-
Notifications
You must be signed in to change notification settings - Fork 374
feat(memory): Design and implement inject_memories retrieval strategy #3013
Copy link
Copy link
Open
Labels
area/agentFor work that has to do with the general agent loop/agentic features of the appFor work that has to do with the general agent loop/agentic features of the apparea/configFor configuration parsing, YAML, environment variablesFor configuration parsing, YAML, environment variablesarea/ragFor work/issues that have to do with the RAG featuresFor work/issues that have to do with the RAG featuresarea/toolsFor features/issues/fixes related to the usage of built-in and MCP toolsFor features/issues/fixes related to the usage of built-in and MCP tools
Metadata
Metadata
Assignees
Labels
area/agentFor work that has to do with the general agent loop/agentic features of the appFor work that has to do with the general agent loop/agentic features of the apparea/configFor configuration parsing, YAML, environment variablesFor configuration parsing, YAML, environment variablesarea/ragFor work/issues that have to do with the RAG featuresFor work/issues that have to do with the RAG featuresarea/toolsFor features/issues/fixes related to the usage of built-in and MCP toolsFor features/issues/fixes related to the usage of built-in and MCP tools
Type
Fields
Give feedbackNo fields configured for Enhancement.
Background
Part of #3011 — the
inject_memoriesturn_startbuiltin proactively retrieves relevant memories before every model call. This issue is scoped specifically to the retrieval strategy: how keywords are extracted from the user prompt, howSearchMemoriesis called, and what the end-to-end retrieval pipeline looks like.Confirmed Design Decisions
1. Prompt availability in
turn_startexecuteTurnStartHooksmust be updated to populatehooks.Input.LastUserMessagewithsess.GetLastUserMessageContent(). This follows the exact pattern already used inexecuteStopHooksand makes the user's current prompt available to the builtin without breaking the stateless-builtin contract:2. Configurable keyword extraction strategy
The builtin supports two strategies, selected via YAML config:
local(default)pkg/rag/strategy/bm25.go: lowercase → strip punctuation → split on whitespace → drop tokens ≤ 2 chars → filter stopwords (the existing 20-word list). No external calls.llmSearchMemories. Costs one extra inference call per turn; useful for complex/multi-topic prompts.YAML example:
3. Retrieval pipeline (end-to-end)
4. Fallback behaviour
No fallback to
GetMemories.SearchMemoriesis always used. When the prompt is short or empty, no keywords are extracted andSearchMemories("")returns all memories (since an empty query returns everything in the SQLite layer). Themax_inject_memoriescap prevents context bloat.5. Output format
Memories are injected as an XML-wrapped block:
Implementation Checklist
pkg/runtime/hooks.go— populateInput.LastUserMessageinexecuteTurnStartHookspkg/hooks/builtins/inject_memories.go— newturn_startbuiltin; implementlocalandllmstrategiespkg/hooks/builtins/builtins.go— registerInjectMemoriesconstant + handler; addInjectMemoriesStrategytoAgentDefaultspkg/config/latest/types.go— addInjectMemoriesStrategy stringtoAgentConfigpkg/agent/agent.go— addInjectMemoriesStrategy() stringaccessorturn_startinjects relevant memories, empty-prompt returns all memories up to capAcceptance Criteria
inject_memories: trueandinject_memories_strategy: local, relevant memories (matching BM25-extracted keywords) appear as a transient system message before every LLM callinject_memories_strategy: llm, an LLM call extracts keywords beforeSearchMemoriesis invokedSearchMemories("")to return all memories (capped atmax_inject_memories)inject_memories: false(default) produces no change in behaviour for existing agents<memories>XML block is correctly formatted withidandcategoryattributes