Procedural-memory recall (pre-tool-call hook)
Procedural-memory recall for a pre-tool-call hook.
Fires the symbol tripwire on the in-flight action (or explicit entities)
and returns the lesson/procedure insights past sessions recorded about
those symbols — advisory, not a mandate. data: list[Memory] carries the matched
rows (type: "lesson" | "procedure"); mode=compose additionally runs an LLM
relevance gate over task and assembles a markdown block into context, while
mode=retrieve returns the raw matched rows and leaves context null. Scope is
enforced server-side from the request’s scope axes (user_id / group_ids /
agent_id / app_id).
Unlike POST /v1/memories/search, this endpoint is not metered against the
monthly quota — the hook is meant to be called freely before every tool use.
Authorizations
Long-lived org API key. Alternative: Authorization: Bearer <key>.
Body
POST /v1/memories/trigger — procedural-memory recall for a pre-tool-call hook.
An agent calls this right before (or just after) a tool runs to pull the
lesson/procedure insights that past sessions recorded about the symbols
it's touching — what worked, what didn't. Recall fires on the symbol tripwire,
never a semantic query: the server extracts greppable identifiers from action
(tool / args / output) or takes them
straight from entities, and matches them exactly against directives'
trigger_entities.
What comes back is advisory, not a mandate — ranked :class:Memory rows
(type: "lesson" | "procedure") in the shared :class:SearchResponse, with the
assembled markdown in context under mode="compose".
Scope follows "scope by what you pass": every axis you supply ANDs; org_id
is derived server-side from your API key. At least one of user_id / agent_id / app_id /
group_ids is required — an unscoped org-wide recall is rejected.
The in-flight tool call the agent is touching right now — the firing signal for recall. Greppable identifiers are extracted server-side (tool name, args values, optional output) and matched exactly against directives' trigger_entities. Supply this or entities.
Escape hatch: pre-extracted greppable identifiers to fire on, bypassing server-side extraction from action. Use when the client already knows the exact symbols the agent is touching.
["tool_loop.py", "AbortError"]Which procedural corpora to recall. Defaults to both (lesson/procedure); subset to restrict (e.g. ["lesson"]).
lesson, procedure The agent's current goal, in one line. Fed to the relevance gate under mode=compose so it keeps only the insights that help with THIS task.
2000"fix finalize-on-abort in the tool loop"
Pipeline depth selector.
compose(default) — symbol-tripwire recall plus an LLM relevance-gate step that keeps only the insights relevant totask, then assembles a markdown block.datacarries the gated rows;contextcarries the markdown. One LLM call.retrieve— recall only. No LLM, cheaper and faster.datacarries the matched rows;contextis null.
retrieve, compose Scope key. When supplied, applied as an AND pin so reads are tenant-isolated at the storage filter layer. Optional: omit it and pass group_ids to read a shared group across users. At least one of user_id / agent_id / app_id / group_ids is required.
"user-123"
Optional group tags — another AND scope axis. When non-empty, matched rows must be tagged to at least one of the requested group(s). Group ids are server-generated unguessable handles (see POST /v1/groups); knowing the id is the access boundary.
["grp_a1b2c3d4e5f6071829304a5b6c7d8e9f"]Optional agent scope. When set, ANDs onto the active primary scope (whether that's user_id or group_ids): matched rows must also carry this exact agent_id.
"bot-7"
Optional app scope. When set, ANDs onto the active primary scope (like agent_id): matched rows must also carry this exact app_id.
"app-3"
Response
Successful Response
POST /v1/memories/search response.
data is always populated — both modes return the ranked
Memory rows from retrieval. context is populated only when
mode='compose' with the assembled markdown block from the
LLM context-selection step. stage_timings is always present
for per-stage latency attribution.
Note that under mode='compose' the rows in data are the
retrieval candidates — a possibly larger set than the subset
the LLM selected and wove into context. Useful for showing
"everything we found" alongside "what we sent to the model."
Echoes the request's mode. compose ⇒ both data and context populated; retrieve ⇒ data populated and context null.
retrieve, compose Constant discriminator for the resource type.
"search"Ranked Memory rows from retrieval. Populated for both modes. Semantic rows (fact/artifact/episode) are ordered by score desc; when include requests lesson/procedure, those directive rows are precision-gated (not vector-scored, score is null) and lead the list ahead of the semantic rows. For mode=compose, the semantic rows are the candidates considered by the context-selection step — a (possibly larger) superset of what ended up in context.
Assembled markdown context block ready for prompt insertion. Populated only when mode=compose; null otherwise.
Per-stage retrieval-pipeline latencies (seconds). Populated in both modes.
True when the LLM context-selection step ran. False indicates the pipeline fell through (e.g. an empty candidate pool, or context selection disabled by config).