feat: FTS fallback + query expansion for memory search#18304
Merged
steipete merged 4 commits intoopenclaw:mainfrom Feb 16, 2026
Merged
feat: FTS fallback + query expansion for memory search#18304steipete merged 4 commits intoopenclaw:mainfrom
steipete merged 4 commits intoopenclaw:mainfrom
Conversation
added 4 commits
February 16, 2026 18:16
Add parseGeminiAuth() to detect OAuth JSON format ({"token": "...", "projectId": "..."})
and use Bearer token authentication instead of x-goog-api-key header.
This allows OAuth users (using gemini-cli-auth extension) to use memory_search
with Gemini embedding API.
Extract parseGeminiAuth() to shared infra module and use it in both embeddings-gemini.ts and inline-data.ts. Previously, inline-data.ts directly set x-goog-api-key header without handling OAuth JSON format. Now it properly supports both traditional API keys and OAuth tokens.
…aw#17725) When no embedding provider is available (e.g., OAuth mode without API keys), memory_search now falls back to FTS-only mode instead of returning disabled: true. Changes: - embeddings.ts: return null provider with reason instead of throwing - manager.ts: handle null provider, use FTS-only search mode - manager-search.ts: allow searching all models when provider is undefined - memory-tool.ts: expose search mode in results The search results now include a 'mode' field indicating 'hybrid' or 'fts-only'.
When searching in FTS-only mode (no embedding provider), extract meaningful keywords from conversational queries using LLM to improve search results. Changes: - New query-expansion module with keyword extraction - Supports English and Chinese stop word filtering - Null safety guards for FTS-only mode (provider can be null) - Lint compliance fixes for string iteration This helps users find relevant memory entries even with vague queries.
Comment on lines
+244
to
+246
| const resultSets = await Promise.all( | ||
| searchTerms.map((term) => this.searchKeyword(term, candidates).catch(() => [])), | ||
| ); |
Contributor
There was a problem hiding this comment.
each keyword search uses candidates limit, but merging happens after - total results fetched could be searchTerms.length * candidates
if user searches "API discussion design" and it extracts 3 keywords, this fetches up to 600 results (3 * 200) before merging
Suggested change
| const resultSets = await Promise.all( | |
| searchTerms.map((term) => this.searchKeyword(term, candidates).catch(() => [])), | |
| ); | |
| // Search with each keyword and merge results (limit per-keyword to avoid over-fetching) | |
| const perTermLimit = Math.min(candidates, Math.ceil(candidates / searchTerms.length)); | |
| const resultSets = await Promise.all( | |
| searchTerms.map((term) => this.searchKeyword(term, perTermLimit).catch(() => [])), | |
| ); |
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/memory/manager.ts
Line: 244:246
Comment:
each keyword search uses `candidates` limit, but merging happens after - total results fetched could be `searchTerms.length * candidates`
if user searches "API discussion design" and it extracts 3 keywords, this fetches up to 600 results (3 * 200) before merging
```suggestion
// Search with each keyword and merge results (limit per-keyword to avoid over-fetching)
const perTermLimit = Math.min(candidates, Math.ceil(candidates / searchTerms.length));
const resultSets = await Promise.all(
searchTerms.map((term) => this.searchKeyword(term, perTermLimit).catch(() => [])),
);
```
How can I resolve this? If you propose a fix, please make it concise.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Depends on #17800 (OAuth support).
Summary
When no embedding provider is configured, fall back to full-text search instead of disabling memory search. Includes LLM-based query expansion for better FTS results.
Changes
Depends on #17800
Greptile Summary
Adds FTS-only fallback mode when no embedding provider is configured, with LLM-based query expansion to improve keyword extraction from conversational queries. Also includes OAuth support for Gemini API.
Key changes:
provider: EmbeddingProvider | nullwith guards in all embedding operationsparseGeminiAuthhelper (JSON format with token/projectId)Issues found:
Confidence Score: 4/5
src/memory/manager.ts:244-246for the keyword search batching issueLast reviewed commit: de98782