Brainby arc-labs/docs
Sdk pythonContext build
Python SDK

Context build

Assemble prompt-ready context from the memory store with recall.context.build — recipes, token budgets, and structured output.

build()

POST/v1/build-contextAPI keystable
def build(
    self,
    query: Optional[str] = None,
    max_tokens: Optional[int] = None,
    recipe: Optional[str] = None,
    messages: Optional[list[dict[str, str]]] = None,
    include_summary: bool = False,
) -> Any: ...

Build a prompt-ready context block from the agent's memory store. Returns a structured response with the formatted prompt section, the token count, the source memories, and an optional user summary.

Parameters

ParameterTypeRequired
querystroptional

Natural-language query that drives memory retrieval. The server uses it to seed the read pipeline. Either query or messages must be supplied.

max_tokensintoptional

Soft token budget for the assembled context. The server packs as many memories as fit, prioritising by relevance. Default depends on the recipe.

recipestroptional

Formatting recipe. Supported: 'default', 'summary', 'bullet_points'. Each emits a different promptSection shape.

messageslist[dict[str, str]]optional

Conversation history. When supplied, the server uses the latest turn as the implicit query and weights against the full thread.

include_summarybooloptional

When true, the response includes a userSummary field with an LLM-generated profile assembled from the user's typed memories.

Wire-shape

The Python SDK passes snake_case fields through to the server, which returns camelCase fields. The SDK does not translate field names — you get the camelCase shape directly.

Request:

{
  "query": "What does the user think about the UI?",
  "max_tokens": 800,
  "recipe": "bullet_points",
  "include_summary": true
}

Response:

{
  "promptSection": "- User prefers dark mode.\n- User wants larger fonts.",
  "tokenCount": 47,
  "sources": [
    { "id": "m_01HEX…", "content": "…", "score": 0.81 }
  ],
  "structured": { "preferences": [...] },
  "userSummary": "User on the Pro plan; prefers dark mode and larger fonts."
}

Examples

from recall import Recall

recall = Recall(url='https://api.recall.arc-labs.ai', api_key='rcall_…')

ctx = recall.context.build(
    query='What does the user think about the UI?',
    max_tokens=800,
    recipe='bullet_points',
    include_summary=True,
)
prompt = (
    "Background:\n"
    f"{ctx['promptSection']}\n\n"
    "User question: ..."
)
print(prompt)
print('Tokens used:', ctx['tokenCount'])
import asyncio
from recall import AsyncRecall

async def main():
    async with AsyncRecall(
        url='https://api.recall.arc-labs.ai',
        api_key='rcall_…',
    ) as recall:
        ctx = await recall.context.build(
            query='What does the user think about the UI?',
            max_tokens=800,
            recipe='bullet_points',
            include_summary=True,
        )
        print(ctx['promptSection'])

asyncio.run(main())

Recipes

OptionTypeDefault / Env
defaultstr

Bare list of memories formatted as [type] content per line. Best when your prompt has its own header and you just need raw evidence.

summarystr

LLM-condensed paragraph summarising the matched memories. Best for short context windows where token budget is tight.

bullet_pointsstr

Markdown bullet list, one memory per bullet. Best for chat-style LLMs that respond well to structured input.

The recipe choice affects the promptSection shape but not the sources array — the source memories are returned regardless, so you can always post-process or display them as evidence.

Token budget

max_tokens is a soft budget. The server uses a tokenizer-aware packer that fits the highest-scoring memories first. If a single memory exceeds the budget, it's truncated rather than dropped — but truncation is unusual since memories are typically short.

The returned tokenCount is the actual count of the assembled promptSection, measured by the same tokenizer the server uses for LLM calls. This lets you reason precisely about your remaining context budget.

query vs messages

You can drive the build with either a single query string or a full message history:

recall.context.build(query='current pain points')

# Conversation-driven — server uses the latest turn
recall.context.build(messages=[
    {'role': 'user', 'content': 'How do I export my data?'},
    {'role': 'assistant', 'content': 'You can use the export menu.'},
    {'role': 'user', 'content': 'What about my old data?'},
])

When you pass messages, the server's read pipeline weights against the recent conversation context, which often produces better retrieval than a bare query string.

include_summary

include_summary=True instructs the server to also assemble a profile-style summary from the user's typed memories — preferences, recurring entities, recent events. The summary lives at userSummary in the response and is independent of the query-driven promptSection.

This is useful for system prompts that want both:

  • Static user context (userSummary) — "who is this user?"
  • Query-relevant memory (promptSection) — "what does this user know about this question?"

structured output

The structured field carries a typed projection of the source memories, keyed by memory type. The exact shape depends on the recipe and the deployment's prompt schema — see the REST API reference for the full schema.

Errors

CodeStatusRetry
RecallAuthError401/403fatal
Auth failed.
RecallValidationError422fatal

Neither query nor messages provided; invalid recipe value; max_tokens outside the server's accepted range.

RecallRateLimitError429fatal
Rate limit exceeded.
RecallServerError5xxfatal

LLM upstream failure (when the recipe requires LLM-generated output).

context.build() makes an LLM call when the recipe is summary or when include_summary=True. Latency is correspondingly higher than search() — typically 1-3s vs 100-300ms. Cache the result for the conversation's duration if it doesn't depend on the latest turn.

Was this page helpful?

On this page