Skip to content

fix(memory): use per-keyword FTS search in hybrid mode #39484#120

Open
BingqingLyu wants to merge 5 commits into
mainfrom
fork-pr-39555-yangzi33-memory_search-0hit-fix
Open

fix(memory): use per-keyword FTS search in hybrid mode #39484#120
BingqingLyu wants to merge 5 commits into
mainfrom
fork-pr-39555-yangzi33-memory_search-0hit-fix

Conversation

@BingqingLyu

@BingqingLyu BingqingLyu commented Apr 27, 2026

Copy link
Copy Markdown
Owner

Summary

  • Problem: memory_search returns 0 hits for multi-word queries (e.g. Rocky Point bagging, retail garden products) in hybrid mode, even when the terms appear 17+ times across indexed files.
  • Why it matters: Users relying on memory search for domain-specific multi-word terms get silently empty results with no indication of why, making the feature appear broken.
  • What changed: Hybrid mode now searches each extracted keyword individually and merges results by highest score (OR-style recall), matching the strategy already used by FTS-only mode.
  • What did NOT change (scope boundary): buildFtsQuery, searchKeyword, the FTS-only code path, vector search, scoring weights, and all other memory subsystems are untouched.
  • Note that test cases were written with assists of AI.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

User-visible / Behavior Changes

Multi-word memory_search queries in hybrid mode now return results when the query terms span separate chunks. Previously these returned 0 hits. Single-word queries and FTS-only mode behavior are unchanged.

Security Impact (required)

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No
  • New/changed network calls? No
  • Command/tool execution surface changed? No
  • Data access scope changed? No

Repro + Verification

Environment

  • OS: Linux (WSL2 / native)
  • Runtime/container: Node 22+
  • Model/provider: any (bug is in FTS path, provider-independent)
  • Integration/channel (if any): N/A
  • Relevant config (redacted): memorySearch.query.hybrid.enabled: true (default)

Steps

  1. Index a document where query terms appear in separate sections (e.g. "Rocky Point" in one paragraph, "bagging" in another).
  2. Run memory_search with query Rocky Point bagging.
  3. Observe result count.

Expected

  • At least one result returned referencing the indexed document.

Actual

  • Before fix: 0 results returned despite 17+ term instances across indexed files.
  • After fix: results returned correctly.

Evidence

  • Failing test/log before + passing after

src/memory/manager.hybrid-keyword-multi.test.ts — 2 tests fail against the reverted manager.ts (0 results asserted > 0), both pass with the fix applied.

Human Verification (required)

  • Verified scenarios: Multi-word cross-chunk query (Rocky Point bagging); two-word queries (bagging operations, retail garden products); single-word queries unaffected; FTS-only mode unaffected.
  • Edge cases checked: Reverted manager.ts confirms tests correctly catch the regression; restored fix confirms green.
  • What you did not verify: Live index with real embedding provider; very large documents with hundreds of chunks; non-English keyword extraction paths.

Compatibility / Migration

  • Backward compatible? Yes
  • Config/env changes? No
  • Migration needed? No

Failure Recovery (if this breaks)

  • How to disable/revert this change quickly: revert src/memory/manager.ts to parent commit (3eec79bd6).
  • Files/config to restore: src/memory/manager.ts only.
  • Known bad symptoms reviewers should watch for: hybrid keyword search returning unexpected results for single-word queries (should not occur — single-keyword path is identical before and after).

Risks and Mitigations

  • Risk: per-keyword FTS searches increase the number of SQLite MATCH queries from 1 to N per hybrid search call.
  • Mitigation: extractKeywords already strips stop words and short tokens, keeping N small for typical queries (2–5 terms). The candidates multiplier already caps each individual lookup at 200 rows. No change for single-word queries.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

memory_search returns 0 hits for specific terms despite indexed content

2 participants