From 41e2e552dd96036c80479dc43f64c002b1281e8e Mon Sep 17 00:00:00 2001 From: Logan Yang Date: Fri, 6 Mar 2026 17:21:27 -0800 Subject: [PATCH] fix: pass timeRange to Miyo search path (#2267) (#2269) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: pass timeRange to Miyo search path (#2267) When Miyo is active, localSearchTool called performMiyoSearch without the timeRange parameter, causing time-based queries like "what did I do this week" to ignore date filters and return wrong results. Thread timeRange through to performMiyoSearch, FilterRetriever, and MiyoSemanticRetriever — all of which already support it. Co-Authored-By: Claude Opus 4.6 * chore: gitignore .claude/worktrees/ Co-Authored-By: Claude Opus 4.6 --------- Co-authored-by: Claude Opus 4.6 --- .gitignore | 1 + src/tools/SearchTools.ts | 40 ++++++++++++++++++++++++++-------------- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index 2a9d1973..75d21f2a 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,7 @@ data.json # Claude configuration .claude/settings.local.json +.claude/worktrees/ # Development session tracking TODO.md diff --git a/src/tools/SearchTools.ts b/src/tools/SearchTools.ts index c2d18666..db33dd4b 100644 --- a/src/tools/SearchTools.ts +++ b/src/tools/SearchTools.ts @@ -388,34 +388,41 @@ async function performMiyoSearch({ query, salientTerms, returnAll = false, + timeRange, }: { query: string; salientTerms: string[]; returnAll?: boolean; + timeRange?: { startTime: number; endTime: number }; }) { const tagTerms = salientTerms.filter((term) => term.startsWith("#")); - const useExpandedLimits = returnAll || tagTerms.length > 0; + const useExpandedLimits = returnAll || timeRange !== undefined || tagTerms.length > 0; const effectiveMaxK = useExpandedLimits ? RETURN_ALL_LIMIT : DEFAULT_MAX_SOURCE_CHUNKS; - // FilterRetriever for local tag/title matches + // FilterRetriever for local tag/title/time-range matches const filterRetriever = new FilterRetriever(app, { salientTerms, + timeRange, maxK: effectiveMaxK, returnAll: useExpandedLimits, }); const filterDocs = await filterRetriever.getRelevantDocuments(query); - // Miyo retriever for server-side semantic search (no local lexical merge) - const miyoRetriever = RetrieverFactory.createMiyoRetriever(app, { - minSimilarityScore: useExpandedLimits ? 0.0 : 0.1, - maxK: effectiveMaxK, - salientTerms, - textWeight: TEXT_WEIGHT, - returnAll: useExpandedLimits, - useRerankerThreshold: 0.5, - tagTerms, - }); - const miyoDocs = await miyoRetriever.getRelevantDocuments(query); + // When timeRange is set, filter results are the complete set — skip Miyo search + // (mirrors the non-Miyo path where main retriever is skipped for time-range queries) + let miyoDocs: import("@langchain/core/documents").Document[] = []; + if (!filterRetriever.hasTimeRange()) { + const miyoRetriever = RetrieverFactory.createMiyoRetriever(app, { + minSimilarityScore: useExpandedLimits ? 0.0 : 0.1, + maxK: effectiveMaxK, + salientTerms, + textWeight: TEXT_WEIGHT, + returnAll: useExpandedLimits, + useRerankerThreshold: 0.5, + tagTerms, + }); + miyoDocs = await miyoRetriever.getRelevantDocuments(query); + } logInfo( `miyoSearch: ${filterDocs.length} filter + ${miyoDocs.length} miyo docs for query: "${query}"` @@ -462,7 +469,12 @@ const localSearchTool = createLangChainTool({ // Miyo handles search server-side — use separate path (no local lexical search) if (RetrieverFactory.isMiyoActive()) { logInfo("localSearch: Using Miyo search path"); - return await performMiyoSearch({ query, salientTerms, returnAll: returnAll === true }); + return await performMiyoSearch({ + query, + salientTerms, + returnAll: returnAll === true, + timeRange, + }); } const tagTerms = salientTerms.filter((term) => term.startsWith("#"));