feat: pre-tool-call recall (trigger / preToolHook)#12
Open
sgonz-xtrace wants to merge 2 commits into
Open
Conversation
Wrap the new POST /v1/memories/trigger endpoint, which recalls the lesson/procedure insights past sessions recorded about the symbols an in-flight tool call touches. Purpose-built for a pre-tool-call hook: no query, and not metered against the monthly quota, so it's safe to call before every tool use. - `memories.trigger(body)` — thin endpoint wrapper (throws like search). - `memories.preToolHook(signal, opts)` — hot-path sugar that fails soft: a network error / timeout / abort returns an empty, degraded result so a recall hiccup can never stall the agent's tool loop. Throws only on caller misconfiguration (no scope axis / no firing signal), before any network call. `compose` (default) returns the server-assembled block; `retrieve` returns raw rows rendered client-side. Optional `timeoutMs`. - `renderLessonProcedurePrompt(rows)` — deterministic block renderer for retrieve mode. - Types: LessonProcedureType, LessonProcedureDetails, LessonMemory, ProcedureMemory, ActionContext, TriggerRequest, TriggerResponse. Purely additive — no existing types, methods, or behavior change. The lesson/procedure row types reuse the shared memory shape without joining the `Memory` union, so search/list/recall narrowing is untouched. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
When a client-side timeout was combined with a caller-supplied signal,
the `abort` listener added to `opts.signal` was never removed on normal
completion (`{ once: true }` only fires on abort). A long-lived caller
signal reused across a busy tool loop would accumulate one dangling
listener per call. Store the handler and remove it in `finally`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a client for the new
POST /v1/memories/triggerendpoint, which recalls thelesson/procedureinsights past sessions recorded about the symbols an in-flight tool call is touching. It's purpose-built for a pre-tool-call hook: recall fires on the symbols the agent is about to act on (not a semantic query), and the endpoint is not metered against the monthly quota, so it's safe to call before every tool use.This PR is purely additive — no existing type, method, or behavior changes.
What's new
memories.trigger(body, ctx?)— thin wrapper over the endpoint. Throws on HTTP errors, symmetric withsearch().memories.preToolHook(signal, opts)— ergonomic sugar for the hook hot path:{ context: "", memories: [], degraded: true }so a recall hiccup can never stall the agent's tool loop (the endpoint itself also fails soft server-side).mode: "compose"(default) returns the server-assembled, inject-ready block incontext;mode: "retrieve"returns raw matched rows and renders the block client-side.{ tool, args, output? }) or pre-extracted{ entities }.timeoutMsfor a hard client-side cap (opt-in — the server already bounds recall and fails soft).renderLessonProcedurePrompt(rows)— deterministic, no-LLM renderer for the retrieve-mode block.Types —
LessonProcedureType,LessonProcedureDetails,LessonMemory,ProcedureMemory,ActionContext,TriggerRequest,TriggerResponse, all exported.Usage
Design notes
lesson/procedurerow types reuse the shared memory shape but deliberately do not join theMemoryunion — they're only ever returned by this endpoint, so keeping them separate leavessearch/list/recalltype narrowing untouched.preToolHookis the recommended entry point for hooks;triggeris the lower-level escape hatch when you want raw errors and full control over the request.Testing
Adds
src/trigger.test.ts(9 tests) covering both modes, the compose context pass-through, retrieve-mode client rendering, fail-soft on error, the two validation throws, and aborted-signal handling. Full suite (55 tests) andtsc --noEmitpass.