Skip to content

fix: read search hit text from chunk — search() currently drops 100% of results - #83

Open
fabio-bergmann wants to merge 1 commit into
supermemoryai:mainfrom
fabio-bergmann:fix/search-maps-chunk-field
Open

fix: read search hit text from chunk — search() currently drops 100% of results#83
fabio-bergmann wants to merge 1 commit into
supermemoryai:mainfrom
fabio-bergmann:fix/search-maps-chunk-field

Conversation

@fabio-bergmann

Copy link
Copy Markdown

Fixes #81.

/v4/search returns the text of a hit in chunk. SupermemoryClient.search() mapped it as r.content || r.memory || r.context || '', so memory came back empty and the dedupe(mapped, (r) => r.memory) on the next line dropped every entry with an empty key. total reported the true count while results was always [].

Writes are unaffected, so the plugin looks healthy while accumulating memories it can never retrieve — and /supermemory:status still says "connected", since it only checks that a key is present. getProfile() mapped searchResults identically, which took the SessionStart context hook down too.

Changes

  • searchResultText() in result-merge.js holds the fallback chain, now including chunk. The two call sites had drifted apart — only one listed memory — and now share one definition.
  • The search dedupe keys on the existing searchResultKey(), which falls back to id:. A future field rename then costs formatting, not every result. The profile dedupe keeps raw text as its key so hits still dedupe against profile facts through the shared seen set, plus the same id fallback.
  • Three unit tests, built on a verbatim /v4/search hit. npm test 5 → 8, npm run lint clean.
  • plugin/scripts/*.cjs rebuilt via npm run build (5 bundles carry the mapper).

Note on testability

The mapper had no test coverage because src/lib/supermemory-client.js can't be required — src/lib/validate.js is committed as minified ESM while package.json is "type": "commonjs", so requiring it throws Cannot use import statement outside a module. Extracting the chain into result-merge.js is what makes this regression testable at all. That packaging issue seems worth fixing separately.

Two of the three tests genuinely require the new helper; the third passes on main already — searchResultKey had the id fallback and mergeSearchResponses used it. It guards that property rather than proving the bug.

Left out

The other hardening idea from #81 — warning when total > 0 && results.length === 0 — adds console output to a module the hooks parse, so I kept it out of this PR. Happy to add it if you want it.

Verified against a live container: the same query that returned nothing now returns the memory at ~70% relevance.

`/v4/search` and `/v4/profile` return the text of a hit in `chunk`, but
`SupermemoryClient.search()` mapped it as
`r.content || r.memory || r.context || ''`. `memory` therefore came back
empty, and the `dedupe(mapped, (r) => r.memory)` on the next line dropped
every entry whose key was empty — so `total` reported the true hit count
while `results` was always `[]`, and every consumer printed
"No memories found".

Writes were unaffected, so the plugin looked healthy while silently
accumulating memories it could never retrieve. `getProfile()` mapped
`searchResults` the same way, which took the SessionStart context hook
down with it.

- extract the fallback chain into `searchResultText()` and add `chunk`.
  The two call sites had drifted apart (only one listed `memory`); they
  now share one definition.
- key the search dedupe on the existing `searchResultKey()`, which falls
  back to `id:` — so a hit with no recognised text field is returned
  rather than discarded. The profile dedupe keeps the raw text as its key
  to stay deduped against profile facts via the shared `seen` set, with
  the same id fallback.
- cover both with unit tests, using a verbatim `/v4/search` hit.

Fixes supermemoryai#81

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.

search() drops 100% of results — /v4/search returns hit text in chunk, mapper reads content/memory/context

1 participant