From 80ae0af8f9bc99a138299957ef597385dbb7da98 Mon Sep 17 00:00:00 2001 From: 4 Bytes Robby Date: Mon, 29 Jun 2026 23:34:31 +0200 Subject: [PATCH 1/3] fix: resolve vec0 chunk excerpts via batch content lookup #192 --- package.json | 2 +- src/search/unified.ts | 68 ++++++++++++++++++++++++++++++++++++++----- 2 files changed, 62 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 0fcea59..90a9de0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@four-bytes/four-opencode-brain", - "version": "1.8.1", + "version": "1.8.2", "description": "Unified brain plugin — single SQLite DB for RAG search, memory, and knowledge base", "license": "Apache-2.0", "type": "module", diff --git a/src/search/unified.ts b/src/search/unified.ts index 4e715db..6decc35 100644 --- a/src/search/unified.ts +++ b/src/search/unified.ts @@ -328,13 +328,67 @@ async function searchVec0( ) .all(queryBlob, maxResults); - return rows.map((row) => ({ - id: row.chunk_id, - title: `vec0:${row.chunk_id.slice(0, 8)}`, - excerpt: `[vec0 chunk] distance=${row.distance.toFixed(4)}`, - score: Math.max(0, 1 - row.distance), - content_type: "chunk" as const, - })); + if (rows.length === 0) return []; + + // Batch-lookup real content from chunks table for all vec0 results + const chunkIds = rows.map((r) => r.chunk_id); + const placeholders = chunkIds.map(() => "?").join(","); + const chunkRows = db + .query( + `SELECT c.id, c.content, c.symbol, c.chunk_type, c.start_line, c.end_line, + c.chunk_index, c.kind, d.path AS source_path, d.title AS doc_title + FROM chunks c + JOIN documents d ON d.id = c.document_id + WHERE c.id IN (${placeholders})`, + ) + .all(...chunkIds) as Array<{ + id: string; + content: string; + symbol: string | null; + chunk_type: string; + start_line: number | null; + end_line: number | null; + chunk_index: number; + kind: string | null; + source_path: string; + doc_title: string; + }>; + + const chunkMap = new Map(chunkRows.map((r) => [r.id, r])); + + return rows.map((row) => { + const chunk = chunkMap.get(row.chunk_id); + if (!chunk) { + // Fallback: chunk not found in chunks table (shouldn't happen, but be safe) + return { + id: row.chunk_id, + title: `vec0:${row.chunk_id.slice(0, 8)}`, + excerpt: `[vec0 chunk] distance=${row.distance.toFixed(4)}`, + score: Math.max(0, 1 - row.distance), + content_type: "chunk" as const, + }; + } + const excerpt = + chunk.content.length > 80 + ? chunk.content.slice(0, 80) + "..." + : chunk.content; + return { + id: chunk.id, + title: + chunk.symbol ?? + `${chunk.doc_title}:${chunk.chunk_type}#${chunk.chunk_index}`, + excerpt, + score: Math.max(0, 1 - row.distance), + content_type: "chunk" as const, + source_path: chunk.source_path ?? undefined, + metadata: { + kind: chunk.kind ?? undefined, + chunk_type: chunk.chunk_type, + start_line: chunk.start_line ?? undefined, + end_line: chunk.end_line ?? undefined, + }, + }; + }); } catch { return []; } From 550e96da66de789af59441dfe522f632e8594093 Mon Sep 17 00:00:00 2001 From: 4 Bytes Robby Date: Mon, 29 Jun 2026 23:40:11 +0200 Subject: [PATCH 2/3] fix: cap excerpt length and clamp chunk ID batch size #192 --- package.json | 2 +- src/search/unified.ts | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 90a9de0..3272f1f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@four-bytes/four-opencode-brain", - "version": "1.8.2", + "version": "1.8.3", "description": "Unified brain plugin — single SQLite DB for RAG search, memory, and knowledge base", "license": "Apache-2.0", "type": "module", diff --git a/src/search/unified.ts b/src/search/unified.ts index 6decc35..7f0930e 100644 --- a/src/search/unified.ts +++ b/src/search/unified.ts @@ -331,7 +331,8 @@ async function searchVec0( if (rows.length === 0) return []; // Batch-lookup real content from chunks table for all vec0 results - const chunkIds = rows.map((r) => r.chunk_id); + const MAX_BATCH_IDS = 500; // SQLite host-parameter safety ceiling + const chunkIds = rows.slice(0, MAX_BATCH_IDS).map((r) => r.chunk_id); const placeholders = chunkIds.map(() => "?").join(","); const chunkRows = db .query( @@ -370,7 +371,7 @@ async function searchVec0( } const excerpt = chunk.content.length > 80 - ? chunk.content.slice(0, 80) + "..." + ? chunk.content.slice(0, 77) + "..." : chunk.content; return { id: chunk.id, From a5faf9ed234671ec06f53d97b806d6239a9e09ad Mon Sep 17 00:00:00 2001 From: 4 Bytes Robby Date: Mon, 29 Jun 2026 23:52:06 +0200 Subject: [PATCH 3/3] fix: clamp row iteration to match batch fetch window #192 --- package.json | 2 +- src/search/unified.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 3272f1f..0b07641 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@four-bytes/four-opencode-brain", - "version": "1.8.3", + "version": "1.8.4", "description": "Unified brain plugin — single SQLite DB for RAG search, memory, and knowledge base", "license": "Apache-2.0", "type": "module", diff --git a/src/search/unified.ts b/src/search/unified.ts index 7f0930e..b435555 100644 --- a/src/search/unified.ts +++ b/src/search/unified.ts @@ -357,7 +357,7 @@ async function searchVec0( const chunkMap = new Map(chunkRows.map((r) => [r.id, r])); - return rows.map((row) => { + return rows.slice(0, MAX_BATCH_IDS).map((row) => { const chunk = chunkMap.get(row.chunk_id); if (!chunk) { // Fallback: chunk not found in chunks table (shouldn't happen, but be safe)