From 6557aea0bcb0d9adf777600d661cfc5162b2f364 Mon Sep 17 00:00:00 2001 From: Paco POR-CORREO Date: Mon, 6 Apr 2026 16:31:01 +0200 Subject: [PATCH] Improve isolated scope bootstrap and upload ingest --- RAG/src/modules/retrieve/service.ts | 7 +++++++ RAG/src/modules/vectorstore/client.ts | 29 +++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/RAG/src/modules/retrieve/service.ts b/RAG/src/modules/retrieve/service.ts index e6407cd..af8c452 100644 --- a/RAG/src/modules/retrieve/service.ts +++ b/RAG/src/modules/retrieve/service.ts @@ -233,6 +233,13 @@ export class RetrieveService { } } + if (merged.size === 0 && scope && (scope.sourceId || scope.sourceRef || (scope.tags && scope.tags.length > 0))) { + const explored = await this.vectorStore.browseScope(12, mode, scope); + for (const item of explored) { + merged.set(item.chunkId, item); + } + } + return rankItems(query, [...merged.values()]).slice(0, 12); } } diff --git a/RAG/src/modules/vectorstore/client.ts b/RAG/src/modules/vectorstore/client.ts index 7bb962a..558b80d 100644 --- a/RAG/src/modules/vectorstore/client.ts +++ b/RAG/src/modules/vectorstore/client.ts @@ -20,6 +20,7 @@ export interface VectorStoreClient { upsert(chunks: IngestedChunk[]): Promise; search(queryVector: number[], limit: number, mode?: string, scope?: RetrieveScope): Promise; listScopes(): Promise; + browseScope(limit: number, mode?: string, scope?: RetrieveScope): Promise; } function buildSearchFilter(mode?: string, scope?: RetrieveScope) { @@ -189,4 +190,32 @@ export class QdrantVectorStoreClient implements VectorStoreClient { return [...scopeMap.values()].sort((left, right) => left.sourceRef.localeCompare(right.sourceRef)); } + + async browseScope(limit: number, mode?: string, scope?: RetrieveScope): Promise { + const collections = await this.client.getCollections(); + const exists = collections.collections.some((collection) => collection.name === env.qdrantCollection); + + if (!exists) { + return []; + } + + const response = await this.client.scroll(env.qdrantCollection, { + limit, + with_payload: true, + filter: buildSearchFilter(mode, scope) + }); + + return response.points.map((point) => ({ + chunkId: String(point.payload?.chunk_id ?? point.id), + documentId: String(point.payload?.document_id ?? ""), + sourceId: String(point.payload?.source_id ?? ""), + title: String(point.payload?.title ?? ""), + sectionTitle: point.payload?.section_title ? String(point.payload.section_title) : undefined, + content: String(point.payload?.content ?? ""), + score: 0, + chunkMode: point.payload?.chunk_mode ? String(point.payload.chunk_mode) as "documental" | "codigo" : undefined, + startLine: point.payload?.start_line ? Number(point.payload.start_line) : undefined, + endLine: point.payload?.end_line ? Number(point.payload.end_line) : undefined + })); + } }