Skip to content

fix(smart-search): findObservation returns empty for bare expand obsIds#840

Open
MarvinFS wants to merge 1 commit into
rohitg00:mainfrom
MarvinFS:fix/findobservation-undefined-miss
Open

fix(smart-search): findObservation returns empty for bare expand obsIds#840
MarvinFS wants to merge 1 commit into
rohitg00:mainfrom
MarvinFS:fix/findobservation-undefined-miss

Conversation

@MarvinFS
Copy link
Copy Markdown

@MarvinFS MarvinFS commented Jun 5, 2026

Problem

memory_smart_search with expandIds returns an empty results array for a
bare obsId, even when the observation exists and a session-hinted lookup
resolves it.

Root cause

findObservation scans sessions in batches and selects the hit with
.find((r) => r !== null). But StateKV.get returns the raw state::get
value, which is undefined for a missing key (not null); the surrounding
.catch(() => null) only normalizes rejections. Most sessions don't hold a
given obsId (and some session records are partial, without an id), so each
batch contains undefined before the real observation. Since
undefined !== null is true, .find returns the first undefined, and
if (found) discards it as falsy — so the real observation later in the batch
is never returned. The hint path and the hybrid-search enrich path are
unaffected because they use a truthy if (obs) check.

Separately, findObservation only consults KV.observations(sessionId) and
never KV.memories, so observations saved via mem::remember (stored in
KV.memories under a synthetic session) cannot be resolved by a bare obsId.

Fix

  • Use .find((r) => r != null) so undefined misses are skipped.
  • Resolve saved memories from KV.memories (via memoryToObservation) before
    the session scan. Preserve agentId/imageRef/imageData in
    memoryToObservation so agent-scope filtering stays correct, and route the
    existing BM25 backfill through memoryToObservation for consistency.
  • Add a regression test whose KV mock returns undefined on a miss (mocks that
    coalesce misses to null mask the bug), with a partial session ordered
    before the real one in the same scan batch.

Complements #837, which forwards expandIds from the MCP proxy to the daemon.

Summary by CodeRabbit

  • Bug Fixes

    • Smart search now correctly resolves observations from saved memories.
    • Session-scan matching improved to handle all observation values reliably.
  • Improvements

    • Observation records now retain agent ID and image information from memory data.

findObservation's batched session scan selected hits with
`.find((r) => r !== null)`, but `StateKV.get` returns the raw `state::get`
value, which is `undefined` for a missing key (not null); the `.catch(() =>
null)` only normalizes rejections. Most sessions miss a given obsId (and some
session records are partial without an `id`), so each scan batch contains
`undefined` before the real hit -- `.find` returns the first `undefined` and
`if (found)` discards it as falsy, so the observation is never returned. Bare
`memory_smart_search` expandIds therefore returned empty while the hint path
and hybrid-search enrich (both truthy `if (obs)`) worked.

- Use `.find((r) => r != null)` so undefined misses are skipped.
- Resolve saved memories from KV.memories before the scan, since mem::remember
  stores them outside KV.observations(*); preserve agentId/imageRef/imageData
  in memoryToObservation so agent-scope filtering stays correct, and route the
  legacy BM25 backfill through memoryToObservation too.
- Add a regression test whose KV mock returns undefined on miss (mocks that
  coalesce to null hide the bug) with a partial session ordered before the
  real one in the same scan batch.

Signed-off-by: MarvinFS <7998636+MarvinFS@users.noreply.github.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented Jun 5, 2026

@MarvinFS is attempting to deploy a commit to the rohitg00's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 5, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2fa3340e-b729-4e30-8b6f-8ae2b7171c2a

📥 Commits

Reviewing files that changed from the base of the PR and between a323fb0 and 6b6b7f1.

📒 Files selected for processing (4)
  • src/functions/smart-search.ts
  • src/index.ts
  • src/state/memory-utils.ts
  • test/findobservation-undefined-miss.test.ts

📝 Walkthrough

Walkthrough

This PR enhances observation resolution to support saved memories by enriching the memory-to-observation mapping helper with optional fields, updating smart-search to check saved memories first before falling back to KV scans, centralizing BM25 backfill to use the shared mapping logic, and adding regression tests for the undefined-on-miss failure mode.

Changes

Saved Memories Observation Resolution

Layer / File(s) Summary
Memory field enrichment in observation mapping
src/state/memory-utils.ts, src/functions/smart-search.ts
memoryToObservation now conditionally spreads agentId, imageRef, and imageData from the Memory record into the CompressedObservation. Smart-search imports the Memory type to support memory-based observation resolution.
Smart-search observation resolution with memory lookup
src/functions/smart-search.ts
findObservation gains an early resolution path by attempting to load from KV.memories and converting via memoryToObservation before scanning sessions. Session scan matching is loosened to accept any non-null/non-undefined value instead of filtering only nulls.
BM25 backfill centralized memory mapping
src/index.ts
BM25 backfill imports and uses memoryToObservation helper instead of constructing observation objects inline, centralizing the memory-to-observation mapping logic.
Regression test coverage for undefined-on-miss
test/findobservation-undefined-miss.test.ts
New Vitest suite with test infrastructure, KV mocks, and two regression tests: one verifying observation resolution when partial records precede the real session, and one verifying saved memory resolution preserves agentId.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • rohitg00/agentmemory#654: Both PRs modify the agentId path in smart-search/memory-to-observation resolution, including saved memories behavior.
  • rohitg00/agentmemory#684: Both PRs modify src/state/memory-utils.ts's memoryToObservation function directly at related code paths.

Suggested reviewers

  • rohitg00

Poem

🐰 A memory path emerges swift,
Smart search now checks the saved gift,
With agentId fields in place,
Observations find their grace!
Tests confirm the null won't slip—
Memories and KV skip and skip!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main fix: enabling findObservation to resolve bare expand obsIds that were previously returning empty results.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

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.

1 participant