Recall output splits into prependContext (dynamic L1 memories in the user prompt prefix, cached per-turn) and appendSystemContext (stable persona, scene, and tools guide in the system prompt, cached across turns), optimizing provider prompt caching in auto-recall.ts. L1 memories are injected as a <relevant-memories> XML block with truncation limits (maxCharsPerMemory, maxTotalRecallChars) applied in score order, while a static <memory-tools-guide> instructs the agent to call tdai_memory_search and tdai_conversation_search for deeper retrieval. Prompt caching is a provider-side optimization where an unchanged prompt segment is reused across requests without reprocessing, reducing latency and cost.
Recall output is split into two fields on RecallResult (defined in src/core/types.ts): prependContext carries dynamic, per-turn L1 memories prepended to the user prompt, while appendSystemContext carries stable content — persona, scene navigation, and tools guide — appended to the system prompt.[1] This two-field design, implemented in src/core/hooks/auto-recall.ts, optimises provider prompt caching: stable system-prompt content rarely changes across turns, so providers such as Anthropic and OpenAI can cache it, while the dynamic L1 block is kept in the user prompt prefix where per-turn changes do not bust that cache.[2] L1 memories arrived in prependContext (before the user message) starting in v0.3.3, having previously lived in appendSystemContext, where per-turn changes caused system-prompt cache busting.[3]
Recalled L1 memories are injected into the user prompt prefix as a <relevant-memories> XML block containing a Chinese-language disclaimer that the memories are reference context and do not represent the current task state.[2] Memory lines that exceed the per-memory character limit are truncated, and the suffix …(已截断;可用 tdai_memory_search 或 tdai_conversation_search 查看详情) is appended; the minimum retained length before truncation is 40 characters (MIN_TRUNCATED_RECALL_LINE_CHARS).[2] At the end of the stable system context, auto-recall.ts injects a static MEMORY_TOOLS_GUIDE XML block (<memory-tools-guide>) that instructs the agent it may call tdai_memory_search, tdai_conversation_search, and read_file for deeper retrieval, with a combined cap of 3 calls per turn for the first two tools.[2]
RecallConfig in src/config.ts ships with defaults of enabled: true, maxResults: 5, scoreThreshold: 0.3, strategy: "hybrid", and timeoutMs: 5000.[4] The strategy field accepts "embedding", "keyword", or "hybrid" (default); choosing "embedding" or "hybrid" requires a configured embedding provider (see Embedding services).[4] When the recall timeout (recall.timeoutMs, default 5000 ms) is exceeded, memory injection is skipped entirely and a warning is logged rather than failing the request.[5]
recall.maxCharsPerMemory caps the character count of each injected L1 memory, and recall.maxTotalRecallChars caps the total character budget across all recalled L1 memories in a single auto-recall pass; setting either to 0 disables that limit.[4][5] Both options were introduced in v0.3.6 and apply truncation in score order, discarding overflow to prevent long sessions from having their context crowded out by memory bloat.[6]
In src/core/hooks/auto-recall.ts, when userText is empty or undefined, L1 memory search is skipped entirely, but L3 persona and L2 scene navigation are still injected into appendSystemContext.[2] The RecalledMemory interface exported from src/core/hooks/auto-recall.ts holds content (string), score (number), and type (string) — one entry per recalled L1 memory — and is used for metric reporting in the agent_turn event.[2]
Sources