Context
Reference for recall.context() — assemble a Markdown prompt section, structured per-category breakdown, and optional user summary.
The endpoint behind it is POST /v1/build-context. Where recall.search() returns a ranked list for the application to render, recall.context() returns a fully-assembled prompt section, so the only thing your agent has to do is concatenate it into its system message.
Signature
recall.context(input: BuildContextInput, options?: TransportRequestOptions): Promise<BuildContextResult>;BuildContextInput
querystringoptionalNatural-language query or task description. Either query or messages is required (or both). When both are given, query is the canonical signal and messages provides recency.
messagesArray<{ role, content }>optionalRecent conversation turns. When query is omitted, the aggregator derives the effective query from the last two messages — no extra LLM call.
maxTokensnumberoptionalToken budget for the assembled context. Default 4096. The aggregator trims candidates until the rendered Markdown fits — if you set this too low, less-relevant categories are dropped first.
recipe'chat_continuation' | 'task_start' | 'personalization' | 'decision_support' | 'agent_resumption'optionalNamed recipe — controls how the token budget is split across categories. See Recipes below. Default is balanced — slightly favouring preferences and recent events.
includeSummarybooleanoptionalWhen true, prepends a 2–3 sentence LLM-generated narrative about the user. Adds ~1 second of latency on cache miss; cached for 5 minutes per scope. Default false.
BuildContextResult
promptSectionstringalwaysPre-formatted Markdown ready to inject into an LLM system prompt. Has section headers per category and bullet items per memory.
tokenCountnumberalwaysToken count of promptSection, computed server-side. Use to budget the rest of your prompt.
sourcesSourceInfo[]alwaysOne entry per memory cited in the prompt. Carries memoryId, category, content, and confidence. Use to render "click to view source" affordances or to inject <source id="…"> markers into the rendered prompt.
categoryCountsCategoryCountsalways{ activeEntities, preferences, recentEvents, relevantFacts, conventions, constraints } — count of memories included per category.
structuredStructuredContextalwaysMachine-readable per-category breakdown. Each category is a StructuredMemory[] with memoryId, content, confidence, relevanceScore, and eventAt?. Use this when your downstream wants the raw memories instead of (or in addition to) the rendered Markdown.
userSummarystring | nullalwaysThe narrative summary when includeSummary: true. Otherwise null.
traceIdstringalwayslatencyMsnumberalwaysRecipes
The recipe controls how the token budget is divided across categories. All recipes start from the same retrieval pool — they just emphasise different slices when the budget is tight.
| Recipe | Skews toward | Use when |
|---|---|---|
chat_continuation | recent events, recent messages | continuing an in-flight chat |
task_start | facts, conventions | starting a new task ("write a report on …") |
personalization | active entities, preferences | personalising responses for the user |
decision_support | facts, constraints, reranked | the agent needs to make a recommendation |
agent_resumption | a 7-day window of events | resuming an agent after a long pause |
When omitted, the aggregator uses a balanced default that suits chat flows.
Examples
Basic — query only
const ctx = await recall.context({
query: 'help me plan the trip to Lisbon',
maxTokens: 2048,
});
system_prompt += '\n\n' + ctx.promptSection;
console.log(`context tokens: ${ctx.tokenCount}, sources: ${ctx.sources.length}`);Implicit query from recent turns
const ctx = await recall.context({
messages: [
{ role: 'user', content: 'I think I want to switch to a managed Postgres.' },
{ role: 'assistant', content: 'Got it — any preferences on region?' },
],
recipe: 'decision_support',
});The aggregator derives the effective query from the last two turns. No extra LLM call is made for the derivation — it's a deterministic concatenation, then the retrieval pipeline runs against that.
Including a user summary
const ctx = await recall.context({
query: 'design review for the dashboard',
recipe: 'task_start',
includeSummary: true,
});
if (ctx.userSummary) {
system_prompt = `[About the user]\n${ctx.userSummary}\n\n` + ctx.promptSection;
}includeSummary: true adds ~1 second of latency the first time per scope, then is cached for 5 minutes. Cache invalidates when new memories land for the user.
Programmatic per-category access
const ctx = await recall.context({ query: 'what does the user know about Postgres?' });
console.log('preferences:', ctx.structured.preferences.map((m) => m.content));
console.log('facts:', ctx.structured.facts.map((m) => m.content));
console.log('constraints:', ctx.structured.constraints.map((m) => m.content));
for (const fact of ctx.structured.facts) {
if (fact.confidence > 0.8) {
// surface high-confidence facts in their own UI affordance
}
}structured is your escape hatch for applications that want the raw, typed memories without parsing the rendered Markdown.
When to use context vs search
recall.search() returns a ranked list. Use it when your application is rendering match cards, citation lists, or doing custom post-processing.
recall.context() returns a finished prompt section. Use it when the next step is "feed an LLM" — it does the budgeting, the categorical grouping, and the formatting for you. Calling search() then writing your own Markdown templater is duplicative work.
Token budgeting
maxTokens is a soft cap. The aggregator may slightly over-shoot when an item is mid-trim, but in practice tokenCount is within 5% of the cap.
When the budget is too tight to fit any items, the aggregator returns an empty promptSection and tokenCount: 0. The structured breakdown still contains the top per-category candidates so the application can decide what to render.
For chat applications: a typical good budget is maxTokens: 2000 for an 8 K context window, maxTokens: 4000–8000 for 32 K, and maxTokens: 16000 for 200 K windows.
Caching
Context responses are cached server-side for ~30 seconds per (scope, query, recipe, maxTokens, includeSummary) tuple. Repeating the same call within that window is fast and free. The userSummary is cached for a longer 5 minutes inside the same scope.
Caches invalidate eagerly when recall.remember(), recall.correct(), or recall.forget() runs in the same scope.
Common pitfalls
maxTokens includes only the prompt section — your system prompt, instructions, and the user message are separate. Subtract them from your model's context window before picking a value.
structured and promptSection cover the same memories — do not splice both into the prompt or the LLM will see duplicates. Pick one.
messages is for implicit query derivation only. The aggregator does not run extraction on these messages — they're hints, not writes. To persist them, call recall.remember({ messages }) separately.
Was this page helpful?