Skip to content
Pyrula

Context

AgentContext is the ctx passed to every agent. It extends the workflow context, so all the durable primitives are there, plus a few things specific to agents.

These behave exactly as they do in a workflow. Use them for anything non-deterministic or side-effecting:

ctx.step, ctx.now, ctx.uuid, ctx.random, ctx.emit, ctx.emit_status, ctx.sleep, ctx.sleep_until, ctx.wait_for_signal, ctx.interrupt, ctx.checkpoint.

See Timers, Signals, and Human-in-the-Loop.

call_agent runs another agent and returns its result. It records like any other step, so the child isn’t re-run on replay.

summary = await ctx.call_agent(summarizer, text=document, id="summarize")

gather runs several calls concurrently and waits for all of them:

results = await ctx.gather(
(classifier, {"text": a}),
(classifier, {"text": b}),
id="classify-batch",
)

AgentLimits on the parent caps depth and parallelism so a fan-out can’t run away.

An agent can hand off to the durable engine directly. spawn_workflow starts a workflow run; wait_for_workflow blocks on its result.

run_id = await ctx.spawn_workflow("nightly_report", params={"date": today})
result = await ctx.wait_for_workflow("nightly_report", run_id)

ctx.memory is cross-turn state for an agent. ctx.thread is the conversation thread the turn belongs to, when there is one. Both let an agent carry context across separate turns without you wiring up storage by hand.

ctx.turn_id is the id of the current turn, handy for logging and idempotency keys.