Agent: search_memory missing from preamble — proactive recall dead by discovery gap #14

Closed
opened 2026-05-12 19:03:35 +00:00 by KofTwentyTwo · 1 comment
KofTwentyTwo commented 2026-05-12 19:03:35 +00:00 (Migrated from github.com)

Summary

Agent has no preamble cue to call search_memory — proactive recall is dead by discovery gap. The tool is registered (10 tools probed ok) but the agent never calls it. Today's session reproduced it perfectly: user said "what is my dog's name?", agent answered "I don't have anything in memory about your dog" without calling search_memory. Zero searchFacts: log lines across all sessions.

Evidence

  • File: packages/AgentCore/Sources/AgentCore/ContextBuilder.swift:64-74 (selfAwarePreamble)
  • File: App/AppDelegate.swift:1685 — systemPrompt: ContextBuilder.systemPrompt(for: .empty) — memoryHydration always empty
  • Log: system.2026-05-12.log confirms search_memory registered via BootHealth
  • Log: memory.*log files have zero [memory.search] channel emissions
  • DB: events table shows 19 tool_call_requested rows today — all get_time/get_self_state/etc; zero search_memory

Root cause / hypothesis

The preamble enumerates 7 introspection tools by name (list_audio_devices, get_active_audio_route, get_self_state, list_camera_devices, get_time, get_clipboard, run_applescript) but omits both search_memory and forget_fact. The Anthropic tools array is canonical, but the model's preference is shaped by the preamble's explicit "always prefer calling those tools" rule. Without a name in the preamble, search_memory falls into "tools the agent technically has access to but won't think to use."

The TurnContext.memoryHydration field exists (ContextBuilder.swift:41) but the only production call site passes .empty. No glue pre-populates from a HybridSearch pass before each turn.

Recommended fix

Add search_memory (and arguably forget_fact) to the preamble's named-tool list with a specific cue:

"When the user references something they may have told you before, or asks 'do you remember…', call search_memory FIRST. Never claim to remember without searching."

The SearchMemoryTool.toolDescription already contains that sentence — it's just not in the preamble where the cache-locked early-prompt nudge actually lives. Optionally wire TurnContext.memoryHydration to call HybridSearch.searchFacts(query: input.userText, k: 5) before each turn, but the named-tool fix is much cheaper.

Test

  • Eval scenario: across N=10 trials, agent given a session with prior fact "user's dog name is Toby", when asked "what is my dog's name?" — assert at least one search_memory tool call before assistant text response
  • Behavioral assertion: tool name search_memory appears in compiled preamble text

Source

  • Audit: .planning/audit-2026-05-12/memory-audit.md (2026-05-12) — finding M-3 CRITICAL

Cross-references

  • Related: M-5 (HIGH) — FTS5 query syntax issue will bite the moment search_memory actually fires
  • Related: #8 (M-4 Memory surface migration)
## Summary Agent has no preamble cue to call `search_memory` — proactive recall is dead by discovery gap. The tool is registered (10 tools probed ok) but the agent never calls it. Today's session reproduced it perfectly: user said "what is my dog's name?", agent answered "I don't have anything in memory about your dog" without calling `search_memory`. Zero `searchFacts:` log lines across all sessions. ## Evidence - File: `packages/AgentCore/Sources/AgentCore/ContextBuilder.swift:64-74` (`selfAwarePreamble`) - File: `App/AppDelegate.swift:1685` — `systemPrompt: ContextBuilder.systemPrompt(for: .empty)` — `memoryHydration` always empty - Log: `system.2026-05-12.log` confirms `search_memory` registered via BootHealth - Log: `memory.*log` files have zero `[memory.search]` channel emissions - DB: `events` table shows 19 `tool_call_requested` rows today — all `get_time`/`get_self_state`/etc; zero `search_memory` ## Root cause / hypothesis The preamble enumerates 7 introspection tools by name (`list_audio_devices, get_active_audio_route, get_self_state, list_camera_devices, get_time, get_clipboard, run_applescript`) but **omits both `search_memory` and `forget_fact`**. The Anthropic tools array is canonical, but the model's preference is shaped by the preamble's explicit "always prefer calling those tools" rule. Without a name in the preamble, `search_memory` falls into "tools the agent technically has access to but won't think to use." The `TurnContext.memoryHydration` field exists (`ContextBuilder.swift:41`) but the only production call site passes `.empty`. No glue pre-populates from a `HybridSearch` pass before each turn. ## Recommended fix Add `search_memory` (and arguably `forget_fact`) to the preamble's named-tool list with a specific cue: > "When the user references something they may have told you before, or asks 'do you remember…', call search_memory FIRST. Never claim to remember without searching." The `SearchMemoryTool.toolDescription` already contains that sentence — it's just not in the preamble where the cache-locked early-prompt nudge actually lives. Optionally wire `TurnContext.memoryHydration` to call `HybridSearch.searchFacts(query: input.userText, k: 5)` before each turn, but the named-tool fix is much cheaper. ## Test - Eval scenario: across N=10 trials, agent given a session with prior fact "user's dog name is Toby", when asked "what is my dog's name?" — assert at least one `search_memory` tool call before assistant text response - Behavioral assertion: tool name `search_memory` appears in compiled preamble text ## Source - Audit: `.planning/audit-2026-05-12/memory-audit.md` (2026-05-12) — finding M-3 CRITICAL ## Cross-references - Related: M-5 (HIGH) — FTS5 query syntax issue will bite the moment `search_memory` actually fires - Related: #8 (M-4 Memory surface migration)
KofTwentyTwo commented 2026-05-13 11:51:46 +00:00 (Migrated from github.com)

Closed by v0.1 cluster merges on 2026-05-13. Develop now at a8c7f1a0.

Closed by v0.1 cluster merges on 2026-05-13. Develop now at `a8c7f1a0`.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: KofTwentyTwo/Jarvis#14