Discovery
What: find every supported agent on the machine, instantly, without launching anything. Checks env overrides,PATH, the login-shell PATH
(GUI apps often miss it), and known install directories. Agents that are
supported but missing come back with an install hint.
probe
or probe_auth asks the agent.
Gates: none. Call runtime.prewarm() at startup to scan early.
Not found? MissingAgent.searched lists every directory that was checked,
so an app can show it and offer a file picker. A user with an unusual install
sets ANYAGENT_<AGENT>_BIN (see Agents).
An installer that edits the user’s PATH is invisible to an app that is
already running: say “installed? restart the app”, not “not found”.
Some agents have a richer, separately installed runtime (Antigravity’s ACP
server). When only the base CLI is found, agent.upgrade names what to
install for more capabilities.
Probe and auth
What: ask the agent itself what it can do. Opens a throwaway session (about 1 s) and returns version, real login state, capabilities, config options, and slash commands.probe_auth is the cheaper call when you only
need the login state.
AgentDetails. The same struct is available later as
session.info().details.
Gates: none.
anyagent never reads or holds credentials and never drives a login flow. It
tells you the exact command or env var to show the user. Keep several
logins of one agent apart with SessionOptions::config_home(dir).
Sessions
What: one live conversation with one agent process.open spawns the
agent, handshakes, and returns two halves: Session (commands, cheap to
clone) and Events (the stream, one consumer).
open returns. session.info() has the resume token,
capabilities, and config options.
Gates: none. Fails typed: AuthRequired { login } when logged out,
HandshakeTimeout after 30 s, ResumeFailed for a bad token.
Drain Events continuously. It buffers 1024 events; a consumer that falls a
full buffer behind is treated as gone and the session closes. close() ends
the process; dropping Events does the same.
Prompting
What: send text, slash commands, and file attachments. What happens depends on session state, and the returnedDelivery tells you which.
Confirms:
TurnStarted { origin: Prompt(id) } for started and queued
prompts.
Gates: Steer decides steer vs queue. Images decides whether an
attachment goes inline or degrades to a path in the prompt text.
Drop a queued prompt before it starts with session.dequeue(prompt_id).
Slash commands from details.commands are sent as plain text:
session.prompt("/review"). An unknown slash prompt is just text.
Permissions and questions
What: the agent’s “may I run this?” and “which one?” moments, forwarded as typed requests with the choices the agent actually offers. Answer exactly once.RequestClosed. It also arrives when a cancelled turn
withdraws the request, so clear your UI on that event, not on your own
answer. While a request is open, session.status() is NeedsInput.
Gates: Permissions and Questions. An agent without Permissions
runs tools without asking.
For unattended runs, open with
SessionOptions::permission_mode(PermissionMode::AutoApprove): anyagent
allows each request once without forwarding it.
Cancel
What: stop the running turn. The session and its context survive.TurnEnded { stop: Cancelled }, then RequestClosed for any
request the turn had open.
Gates: none.
Configuration
What: models, effort, mode, sandbox, switched without a restart. Agents advertise their settings asConfigOptions with typed choices, so a picker
renders what the agent offers instead of a hardcoded list.
Confirms:
SessionUpdated, carrying the new configuration and the
rebuilt config_options. Wait for it rather than for configure to return.
Gates: the option must be in details.config_options, else
InvalidConfiguration.
Status
What: the one value a thread list needs.Idle, Working, or
NeedsInput, pushed on every change and readable on demand.
StatusChanged is emitted only on change. A turn ending with
another prompt queued stays Working, never flashing Idle.
Gates: none.
One-shot generation
What: prompt in, string out, no session to manage. For thread titles, commit messages, branch names, PR bodies.String.
Gates: Permissions, or a wire that can launch without tools. Requires
a new session: resume and fork_from options are rejected. A tool event or
a question needing a choice cancels generation. Put context inline;
attachments cannot be opened without tools.
Resume
What: continue a conversation from a new process. Every session mints an opaqueresume_token; store it with your transcript.
open returns; the agent has its context back. No old events
are replayed, so keep your own transcript.
Gates: Resume, else ResumeFailed. The token is agent-owned: store it
as-is, never parse it. The session id is not a resume token.
Fork
What: a new session starting from an old one’s history. The original is untouched, which is what “try this a different way” needs.open returns a new session with its own resume token.
Gates: Fork.
Rollback
What: rewind this session in place by whole turns.
Confirms:
SessionUpdated. A refusal comes back as a Diagnostic, not
an error from the call.
Gates: above, plus an idle session (SessionBusy otherwise).
Compact
What: ask the agent to summarize its own context, freeing room in the window without losing the thread.ContextCompacted, then a lower ContextUsage. Compaction
runs as an agent-originated turn: prompts sent meanwhile queue behind it. An
agent that finds nothing to summarize says so as a Diagnostic.
Gates: Compact (claude, codex, opencode, pi) and an idle session.
Subagents
What: agents that spawn agents render as a tree, not interleaved noise.parent_tool_id on the child’s events. A child can never end
the parent’s turn; anyagent consumes the child’s turn bookkeeping.
Gates: Subagents.
Context and plan usage
What: the two gauges apps show. They measure different things.ContextUsage and PlanUsage. Plan usage also needs a
subscription login (AuthKind::Subscription).
MCP servers
What: hand the agent your app’s MCP servers for this session.ToolUpdated with
ToolKind::Mcp { server, tool }.
Gates: the agent’s supported transports. An unsupported transport fails
open typed rather than dropping the server.
Wire recording
What: a bug report that contains the actual bug. Tees every raw protocol frame, both directions, to a JSONL file.Testing without a subprocess
What: run your app over a scripted agent. The engine, turn rules, and event shapes are real; only the agent is fake.Cargo.toml
mock. Script flags (steer, deterministic,
buffer, …) model the wire shapes the engine has to cope with.