Skip to main content
The Agent class abstracts what an agent does into a small set of behaviors, each suited to a different goal:

Reply

reply and reply_stream drive the same reasoning-acting loop over the same inputs; they differ only in how results are delivered. The inputs parameter accepts:

Basic Reply

One call in, one final Msg out: the simplest way to run the agent, suited for automation where intermediate events don’t matter. reply consumes all events internally and returns the final Msg when the agent finishes. If the reply pauses for outside interaction, it returns a waiting notice whose finished_reason is None, meaning the reply is not finished yet.
Besides the text content, the returned Msg carries the reply’s full outcome. The fields worth checking after each call: See Message & Event for the complete Msg structure and content block types.

Streaming Reply

The agent emits text deltas, tool call progress, and lifecycle events in real time, which is the basis for interactive UIs. reply_stream yields AgentEvent objects as they are produced:
Pass yield_final_msg=True to additionally yield the final Msg as the last item of the stream. This is useful when you need the assembled reply message (e.g. its structured_output attribute) besides the events:

Structured Output

A reply can be required to produce fields conforming to a JSON schema, which is typical for generating reports or emitting control fields that drive a workflow. Pass a Pydantic model class via structured_schema. The agent equips a builtin GenerateStructuredOutput tool whose input schema is your schema: it reasons and calls other tools freely first, then submits the result through this tool. Validation errors are fed back to the model for retry, and the validated result lands on the final message’s structured_output attribute as a plain dict (the message text is only a placeholder).
The requirement is scoped to one reply and survives human-in-the-loop pauses, state persistence, and process restarts, because the schema is stored in the agent state as a plain dict. When resuming a parked reply, do not pass structured_schema again; the reply continues with the schema it was parked with.
  • Validation adapts to how the reply runs. In process, the class itself validates the output: defaults (including default_factory) are filled, extra fields are dropped, and custom validators are executed. After reloading a serialized state, only the JSON schema remains: schema-declared defaults are filled, extra fields are kept, and custom validators are skipped.
  • On reaching max_iters without output, the agent forces the GenerateStructuredOutput call within structured_output_grace_iters extra iterations (default 5). If it still fails, the reply ends with finished_reason=EXCEED_MAX_ITERS and structured_output is None; check for None before use.

Message Observation

Messages can be injected into the agent’s context without triggering a reply. This is useful in multi-agent setups where one agent needs to see another’s output.

Context Compression

Long conversations are kept within the model’s context window by summarizing older messages, triggered automatically or on demand. The agent compresses its context when the token count exceeds context_config.trigger_ratio × model.context_length, and offloads the summarized messages to disk if an offloader is configured. compress_context takes two optional arguments: a context_config that overrides the default thresholds for this call, and an instructions HintBlock that is injected into the compression context to guide the summarization (for example, what must be preserved):
Tool results that exceed tool_result_limit tokens are truncated automatically; with an offloader, the truncated portion is offloaded and the agent receives a path reference it can read on demand. See Context for the full compression pipeline and offloading.
If the system prompt alone exceeds the compression threshold, compress_context raises a RuntimeError. Keep system prompts concise or increase the model’s context length.

State Persistence

The complete agent state serializes to JSON, so a reply can pause in one process and resume in another. This is the basis for multi-session services. AgentState holds everything needed to resume exactly where the agent left off: conversation context, compression summary, permission rules, tool state, and the current reply position. RedisStorage is the built-in storage backend, organising state under a (user_id, agent_id, session_id) key hierarchy:
update_session_state raises KeyError if the session does not exist yet. Use upsert_session to create the session record on the first turn, then switch to update_session_state for subsequent turns.