Runtime,
ask it to open a session, and from then on you send commands through
Session and read what the agent does from Events. Everything below is
exported from the crate root; full signatures are on
docs.rs.
Runtime
The entry point. Create one when your app starts and keep it around: it knows the agent catalog, scans the machine for installed agents, and opens sessions on them. It is also where the one-off calls live that don’t need a conversation, like one-shot text generation and reading account quota.AgentInstallation values, and every other Runtime
call takes one. You can also build one by hand: AgentInstallation::at(id, path)
points at a specific binary, and AgentInstallation::acp(name, path, args)
describes an ACP agent that isn’t in the catalog.
SessionOptions
Everythingopen needs to know before the agent starts: where to run, whether
to continue an old conversation, how to handle permissions, which settings to
apply first. Start with in_dir and chain whatever else applies. Anything you
can change later goes through Session::configure instead.
Session
Your handle on one live conversation. Everything you tell the agent goes through it: prompts, answers to its requests, setting changes, cancel, close. It is cheap to clone and every clone talks to the same session, so hand copies to whichever parts of your app need to send commands. Most calls return as soon as the command is accepted; the table says which event confirms the result.prompt never fails for being busy. Instead it returns a Delivery that
says what happened to your text:
A prompt is a plain
&str or an Input, which is text plus file paths:
Input::text("…").attach("shot.png"). On agents with Capability::Images the
image bytes go inline; on the others the attachment becomes a path in the
prompt text that the agent can open with its own tools.
Events
The other half ofopen: a stream of everything the agent does, in order.
Text as it streams, tool calls as they change, requests that need an answer,
usage numbers, and the start and end of every turn. The same EventKinds
arrive for every agent, so one match covers all of them.
It is a Stream<Item = Result<Event, AgentError>>. Read it continuously
from its own task: it buffers 1024 events, and a consumer that falls a full
buffer behind is treated as gone and the session closes.
EventKind is #[non_exhaustive]. Always keep a _ => {} arm so a new
variant does not break your build.
Turn boundaries
A turn is one stretch of agent work. It starts when you prompt (or when the agent wakes itself to finish background work) and ends exactly once. These two events bracket everything else.StopReason:
Content
The agent’s words. Deltas arrive as they stream and are grouped bymessage_id; append them in order.
Tools and plans
What the agent is doing. Each tool call is oneToolUpdate that you replace
whole every time it changes, so there is no delta merging to get wrong.
kind is Subagent, every event the child produces carries that tool’s
id in turn_info.parent_tool_id. That is how you nest it in a UI.
Requests
Moments where the agent stops and waits for a person: permission to run a tool, or a question with choices. The turn does not continue until you answer, and the session’s status isNeedsInput meanwhile.
PermissionChoice is AllowOnce, AllowAlways, DenyOnce, DenyAlways.
QuestionAnswer is Text(String) or Choices(Vec<ChoiceId>).
Session state and usage
Everything about the session that isn’t part of the conversation: its settings, its UI state, how full its context window is, and how much of the account’s quota is used.AgentDetails and capabilities
What the agent told anyagent about itself: its version, whether it is logged in, what it can do, which settings it exposes, and which slash commands it has. You get it fromprobe before opening, and from session.info().details
once a session is live. It is the single source for feature-gating and for
building a settings menu.
Capability is one optional thing this agent can do on this connection.
Check capabilities.supports(..) before offering a feature, and never
special-case an agent by name: the same agent can report different
capabilities over different wires. The full matrix is on the
Agents page.
Errors
Every failure a caller can see is oneAgentError variant, so your app can
match on the cause instead of parsing messages. The two worth handling
specially are AuthRequired, which carries the login steps to show the user,
and ResumeFailed, after which most apps simply open a fresh session. The
enum is #[non_exhaustive].