From 4b309e205e6999fda4243f96359bd76d33814113 Mon Sep 17 00:00:00 2001 From: Jerry-Xin Date: Mon, 16 Mar 2026 16:11:14 +0800 Subject: [PATCH] fix(memory): use offsetLines to report accurate snippet start positions Apply the already-computed offsetLines from extractRelevantSnippet to adjust startLine in all three search mappers (vector, keyword, and hybrid paths). This ensures the reported line range matches the actual snippet content rather than always pointing to the raw chunk start. --- src/memory/manager-search.ts | 46 ++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/src/memory/manager-search.ts b/src/memory/manager-search.ts index a3c8c06146a..4706a42a708 100644 --- a/src/memory/manager-search.ts +++ b/src/memory/manager-search.ts @@ -57,15 +57,18 @@ export async function searchVector(params: { source: SearchSource; dist: number; }>; - return rows.map((row) => ({ - id: row.id, - path: row.path, - startLine: row.start_line, - endLine: row.end_line, - score: 1 - row.dist, - snippet: truncateUtf16Safe(row.text, params.snippetMaxChars), - source: row.source, - })); + return rows.map((row) => { + const { snippet, offsetLines } = extractRelevantSnippet(row.text, params.queryText, params.snippetMaxChars); + return { + id: row.id, + path: row.path, + startLine: row.start_line + offsetLines, + endLine: row.end_line, + score: 1 - row.dist, + snippet, + source: row.source, + }; + }); } const candidates = listChunks({ @@ -82,6 +85,7 @@ export async function searchVector(params: { return scored .toSorted((a, b) => b.score - a.score) .slice(0, params.limit) +<<<<<<< HEAD .map((entry) => ({ id: entry.chunk.id, path: entry.chunk.path, @@ -91,6 +95,24 @@ export async function searchVector(params: { snippet: truncateUtf16Safe(entry.chunk.text, params.snippetMaxChars), source: entry.chunk.source, })); +======= + .map((entry) => { + const { snippet, offsetLines } = extractRelevantSnippet( + entry.chunk.text, + params.queryText, + params.snippetMaxChars, + ); + return { + id: entry.chunk.id, + path: entry.chunk.path, + startLine: entry.chunk.startLine + offsetLines, + endLine: entry.chunk.endLine, + score: entry.score, + snippet, + source: entry.chunk.source, + }; + }); +>>>>>>> 58e5ec73b (fix(memory): use offsetLines to report accurate snippet start positions) } export function listChunks(params: { @@ -177,10 +199,14 @@ export async function searchKeyword(params: { return rows.map((row) => { const textScore = params.bm25RankToScore(row.rank); +<<<<<<< HEAD +======= + const { snippet, offsetLines } = extractRelevantSnippet(row.text, params.query, params.snippetMaxChars); +>>>>>>> 58e5ec73b (fix(memory): use offsetLines to report accurate snippet start positions) return { id: row.id, path: row.path, - startLine: row.start_line, + startLine: row.start_line + offsetLines, endLine: row.end_line, score: textScore, textScore,