Skip to main content

Crate anyagent

Crate anyagent 

Source
Expand description

One Rust interface to the coding agents installed on a machine.

anyagent finds the agent CLIs a user already has — Claude Code, Codex, Grok, Hermes, OpenCode, Kiro, Qwen — speaks each one’s protocol (native or ACP), and exposes them all through three objects:

The examples/ directory shows the patterns; chat.rs is the core loop:

use anyagent::{EventKind, Runtime, SessionOptions};
use futures::StreamExt;

let runtime = Runtime::new();
let report = runtime.discover().await;
let agent = report.require("claude")?;
let (session, mut events) = runtime.open(agent, SessionOptions::in_dir(".")).await?;

session.prompt("explain this repo").await?;
while let Some(event) = events.next().await {
    match event?.kind {
        EventKind::TextDelta { text, .. } => print!("{text}"),
        EventKind::TurnEnded { .. } => break,
        _ => {}
    }
}
session.close().await?;

§Features

Discovery. Runtime::discover is read-only and instant: it finds executables (env overrides, PATH, the login-shell PATH, known install dirs) and lists supported-but-missing agents with install hints. It never launches anything; login state comes from Runtime::probe.

Probe. Runtime::probe opens a throwaway session (~1 s) to learn what only the agent can tell you, returned as AgentDetails: version, real login state (AuthStatus — who is logged in, or runnable LoginMethods if not), capabilities, config options, and slash commands.

Sessions and events. Runtime::open spawns the agent and returns a Session handle plus one Events stream. Every agent produces the same events — streamed text and reasoning, typed tool calls with diffs (ToolUpdate), plan updates, context usage, turn boundaries — so your app is written once. Turn rules are enforced by anyagent, not trusted from the provider: exactly one TurnEnded per turn, no phantom turns. Anything provider-specific rides in Event::extensions instead of leaking into the types. The UI state — SessionStatus: working, needing input, idle — is pushed as StatusChanged on every flip and read on demand with Session::status, so thread lists and “needs you” badges need no event reducer.

One-shot generation. Runtime::generate is prompt in, string out: it opens a throwaway session, declines every tool request, and returns the reply text. Thread titles, commit messages, branch names, and PR bodies need this, not a conversation.

Prompting. Session::prompt takes text or an Input with file attachments (images inline when the wire supports them). A prompt sent mid-turn steers the running turn on agents that support it, and queues otherwise — the returned Delivery says which happened. Slash commands from AgentDetails::commands are sent as plain text.

Permissions and questions. When the agent wants to run a tool or ask the user something, a Request arrives on the stream; answer it with Session::answer. Or set PermissionMode::AutoApprove at open for unattended runs.

Configuration. Agents advertise their settings — model, effort, mode, sandbox — as ConfigOptions with typed choices; your picker reads them instead of hardcoding a catalog. Set creation-only options through SessionOptions::configure, switch live ones with Session::configure; the applied change comes back as SessionUpdated.

Resume, fork, rollback. Every session mints a ResumeToken at open: store it and continue the conversation from any process with SessionOptions::resume. SessionOptions::fork_from branches a conversation; Session::rollback rewinds it, optionally restoring the files the dropped turns changed. All gated by Capability, so unsupported agents refuse with a typed error instead of misbehaving.

Auth. Runtime::probe_auth answers the real login state cheaply — from the agent itself, not just credential-file guesses. A logged-out agent reports AuthStatus::Unauthenticated with runnable LoginMethods (the exact terminal command, or the env var to set) for your app to surface.

Plan usage. Runtime::plan_usage reads the logged-in account’s quota windows (session/week, plan name) from the agent itself — no HTTP endpoints, no token handling.

MCP forwarding. Hand the agent your app’s MCP servers at open with SessionOptions::mcp_server (stdio, HTTP, or SSE, checked against the agent’s transports).

Capabilities. AgentDetails::capabilities says what each agent supports — Capability::Steer, Fork, Rollback, Subagents, PlanUsage, … — so the UI can gate features per agent instead of special-casing agent names.

Testing your app. With the mock feature, [Runtime::with_mock] runs the real engine over a scripted agent ([mock::Script]): your UI and routing tests need no subprocess.

Your application keeps what is rightfully its own: the transcript store, titles, worktrees, and UI. anyagent owns the processes, the wires, and the turn rules.

Modules§

sidecar
The public API over a pair of byte streams, one JSON object per line. This is what the anyagent serve binary runs and what every language wrapper talks to, so the crate stays the only place with logic.

Structs§

AccountInfo
AgentDetails
What probe and open learn about an agent.
AgentId
AgentInstallation
One installed agent, as returned by Runtime::discover.
AgentPlanUsage
One row of a usage page: the agent and its quota, or why it has none.
Capabilities
Effective caller actions for one agent or session.
Choice
ChoiceId
ConfigChoice
ConfigId
ConfigOption
A session setting the agent advertises. Well-known ids: model, effort, mode, sandbox, fast (boolean, lower latency with increased usage).
Delivery
Immediate result of submitting a prompt.
Diagnostic
DiscoveryReport
What discover found and what it could not read.
Event
One normalized event produced by anyagent.
Events
Ordered event stream, buffering up to 1024 undrained events.
FileDiff
Input
One prompt: text plus optional attachments.
McpServer
A client-owned MCP server the agent should connect to, forwarded at open.
MessageId
MissingAgent
PermissionRequest
PlanEntry
PlanUsage
Plan quota windows for the logged-in account.
PromptId
Question
QuestionId
QuestionRequest
RawTool
RequestId
ResumeToken
Runtime
The one object an application creates. Holds the adapter registry.
Session
Command handle. Cheap to clone; every clone talks to the same engine task.
SessionConfiguration
SessionId
SessionInfo
Snapshot of a live session. Also carried by EventKind::SessionUpdated.
SessionOptions
Creation-time settings for Runtime::open.
SlashCommand
ToolId
ToolUpdate
Cumulative snapshot of one tool call.
TurnContext
TurnId
UsageWindow

Enums§

AgentError
Every failure a caller can see. Non-exhaustive so new cases do not break consumers.
Answer
AuthKind
The login kind decides which features exist (plan usage needs a subscription).
AuthStatus
Whether, and how, an agent is logged in.
Capability
Optional actions supported by an agent or session.
CompletionSource
ConfigKind
ConfigValue
DeliveryKind
DiagnosticLevel
EventKind
InstallationSource
Where discovery found an executable.
LoginMethod
A login method the application can show to the user.
McpTransport
PermissionChoice
PermissionMode
How anyagent handles tool permission requests.
PlanStatus
QuestionAnswer
Request
Something the agent is waiting on the caller for. Answer once with Session::answer.
RollbackScope
What rollback rewinds: conversation context only, or also the files the agent changed in the dropped turns (requires RollbackFiles).
SessionStatus
What a UI should show for the session right now. Changes arrive as EventKind::StatusChanged; Session::status reads it without the stream.
StopReason
ToolInput
ToolKind
ToolStatus
TurnOrigin

Type Aliases§

Extensions
Namespaced provider data Anyagent has not normalized yet. Keys use provider/name, for example codex/thread_status.