From 52e19fe678e440dc596e8b8ecb47600179d9b606 Mon Sep 17 00:00:00 2001 From: vvzvlad Date: Thu, 18 Jun 2026 02:15:18 +0300 Subject: [PATCH] feat(ai): wire up workspace RAG bulk reindex + manual "Reindex now" The WORKSPACE_CREATE_EMBEDDINGS / WORKSPACE_DELETE_EMBEDDINGS jobs were enqueued (on AI Search enable/disable) but had no AI_QUEUE handler, so existing pages were never indexed ("Indexed 0 of N pages") and disabling never purged embeddings. - EmbeddingProcessor: handle WORKSPACE_CREATE_EMBEDDINGS (bulk reindex all live pages) and WORKSPACE_DELETE_EMBEDDINGS (purge workspace embeddings) - EmbeddingIndexerService: add reindexWorkspace() (skips when embeddings unconfigured; per-page error isolation) and removeWorkspace() - PageRepo.getIdsByWorkspace(), PageEmbeddingRepo.deleteByWorkspace() - AiSettingsService.reindex() + admin-only POST /workspace/ai-settings/reindex - Frontend: "Reindex now" button, service call and mutation - Stable per-workspace jobId with remove-before-add so a stale job can't block future reindexes; cancel the delayed purge on enable/reindex so it can't wipe freshly-built embeddings --- .../components/ai-provider-settings.tsx | 26 +++++++-- .../workspace/queries/ai-settings-query.ts | 21 +++++++ .../workspace/services/ai-settings-service.ts | 5 ++ .../embedding/embedding-indexer.service.ts | 55 +++++++++++++++++++ .../ai-chat/embedding/embedding.processor.ts | 41 ++++++++++++-- .../workspace/services/workspace.service.ts | 21 ++++++- .../repos/ai-chat/page-embedding.repo.ts | 15 +++++ .../src/database/repos/page/page.repo.ts | 14 +++++ .../integrations/ai/ai-settings.controller.ts | 12 ++++ .../integrations/ai/ai-settings.service.ts | 44 +++++++++++++++ apps/server/src/integrations/ai/ai.module.ts | 7 ++- .../queue/constants/queue.interface.ts | 8 +++ 12 files changed, 253 insertions(+), 16 deletions(-) diff --git a/apps/client/src/features/workspace/components/settings/components/ai-provider-settings.tsx b/apps/client/src/features/workspace/components/settings/components/ai-provider-settings.tsx index 4fe6d671..dc3a1fb7 100644 --- a/apps/client/src/features/workspace/components/settings/components/ai-provider-settings.tsx +++ b/apps/client/src/features/workspace/components/settings/components/ai-provider-settings.tsx @@ -18,6 +18,7 @@ import { useTranslation } from "react-i18next"; import useUserRole from "@/hooks/use-user-role.tsx"; import { useAiSettingsQuery, + useReindexAiEmbeddingsMutation, useTestAiConnectionMutation, useUpdateAiSettingsMutation, } from "@/features/workspace/queries/ai-settings-query.ts"; @@ -50,6 +51,7 @@ export default function AiProviderSettings() { const { data: settings, isLoading } = useAiSettingsQuery(isAdmin); const updateMutation = useUpdateAiSettingsMutation(); const testMutation = useTestAiConnectionMutation(); + const reindexMutation = useReindexAiEmbeddingsMutation(); // Whether a key is currently stored server-side (drives the placeholder). const [hasApiKey, setHasApiKey] = useState(false); @@ -258,12 +260,24 @@ export default function AiProviderSettings() { )} {settings && ( - - {t("Indexed {{indexed}} of {{total}} pages", { - indexed: settings.indexedPages ?? 0, - total: settings.totalPages ?? 0, - })} - + + + {t("Indexed {{indexed}} of {{total}} pages", { + indexed: settings.indexedPages ?? 0, + total: settings.totalPages ?? 0, + })} + + {isAdmin && ( + + )} + )}