### Setup development environment Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/contributing.mdx Clone the repository and install the 'just' command runner to manage development tasks. ```bash git clone https://github.com/spotta85/anyagent-rs && cd anyagent-rs cargo install just # the dev front door; `just` lists every command just check # fmt, clippy, offline tests ``` -------------------------------- ### Run repository examples Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/quickstart.mdx Commands to run the provided example programs against installed agents. ```bash cargo run --example chat -- claude # prompt, stream, answer, steer cargo run --example sessions -- claude # several sessions at once, then resume cargo run --example probe # what's installed, logged in, and capable ``` -------------------------------- ### Discover and select agents Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/building-an-app.mdx Initializes the runtime, scans for available agents, and displays them in the UI. It distinguishes between installed agents and those requiring installation. ```rust let runtime = Runtime::new(); runtime.prewarm(); // start scanning while the window opens let report = runtime.discover().await; for agent in &report.agents { ui.agent_row(&agent.name, agent.auth.as_ref()); // auth here is a best-effort offline guess } for missing in &report.missing { ui.install_row(&missing.name, &missing.install_hint); } let agent = report.require(&chosen_id)?.clone(); ``` -------------------------------- ### Runtime::discover() Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/core-api.mdx Performs an instant, read-only scan of the machine to identify installed agents and provide installation hints for missing ones. ```APIDOC ## Runtime::discover() ### Description Performs an instant, read-only scan of the machine to identify installed agents and provide installation hints for missing ones. ### Returns - **DiscoveryReport** - A report containing installed agents and missing agents with install hints. ``` -------------------------------- ### Execute a single agent turn in src/main.rs Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/quickstart.mdx A complete example showing how to discover an agent, open a session, prompt it, and stream the response. ```rust use anyagent::{EventKind, Runtime, SessionOptions}; use futures::StreamExt; #[tokio::main] async fn main() -> Result<(), Box> { let runtime = Runtime::new(); // 1. Find what's on this machine, then insist on one of them. let report = runtime.discover().await; let agent = report.require("claude")?; // 2. Open a session: a command handle and an event stream. let (session, mut events) = runtime.open(agent, SessionOptions::in_dir(".")).await?; // 3. Prompt, then drain events until the turn ends. 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?; Ok(()) } ``` -------------------------------- ### Start codex app-server Source: https://github.com/spotta85/anyagent-rs/blob/main/tests/fixtures/codex/README.md The command used to initialize the codex app-server with a specific workspace and temporary home directory. ```bash codex app-server # cwd = workspace, CODEX_HOME = a temp dir ``` -------------------------------- ### SessionOptions Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/core-api.mdx Configuration builder for initializing an agent session. Use these methods to define the environment, permissions, and initial settings before starting the agent. ```APIDOC ## SessionOptions ### Description Builder pattern to configure an agent session before it starts. Start with `in_dir` and chain additional options. ### Methods - **in_dir(path)** - Required - Sets the working directory for the agent. - **configure(id, value)** - Optional - Sets a config option (e.g., "model", "effort", "fast", "mode") before the first turn. - **resume(token)** - Optional - Reopens an earlier session. - **fork_from(token, at)** - Optional - Branches a new session off an old one. - **mcp_server(server)** - Optional - Provides an MCP server (stdio, HTTP, SSE). - **permission_mode(mode)** - Optional - Sets mode to `Ask` or `AutoApprove`. - **config_home(dir)** - Optional - Sets a separate config directory. - **quiet_window(dur)** - Optional - Sets duration of silence before completion is inferred. - **stall_after(dur)** - Optional - Sets silence duration before a stall diagnostic. - **record_wire(path)** - Optional - Dumps raw protocol traffic to a JSONL file. ``` -------------------------------- ### Handling Agent Requests Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/core-api.mdx Example of matching on incoming requests to provide answers for permissions or questions using session.answer. ```rust use anyagent::{Answer, PermissionChoice, QuestionAnswer, Request}; match request { Request::Permission(r) => { // r.options is what this agent actually offers; answers outside it are rejected session.answer(r.id, Answer::Permission(PermissionChoice::AllowOnce)).await?; } Request::Question(r) => { // one QuestionAnswer per question, in order let answers = r.questions.iter().map(|_| QuestionAnswer::Text("yes".into())).collect(); session.answer(r.id, Answer::Question(answers)).await?; } } ``` -------------------------------- ### Manual ACP Agent Installation Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/agents.mdx Build an agent installation manually using AgentInstallation::acp when no catalog entry is available. Note that verified quirks like launch flags and auth hints are not provided. ```rust use anyagent::{AgentInstallation, Runtime, SessionOptions}; let agent = AgentInstallation::acp( "my-agent", // display name "/usr/local/bin/my-agent", // executable vec!["acp".into()], // args that put it in ACP mode ); let (session, events) = Runtime::new().open(&agent, SessionOptions::in_dir(".")).await?; ``` -------------------------------- ### Install ACP agent via AgentInstallation Source: https://github.com/spotta85/anyagent-rs/blob/main/README.md Use this method to register an ACP-compatible agent that is not explicitly listed in the catalog. ```rust AgentInstallation::acp(name, path, args) ``` -------------------------------- ### Retrieve and iterate over plan usage Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/features.mdx Demonstrates how to fetch plan usage for a specific agent and iterate over usage data for all installed agents to populate a dashboard. ```rust let usage = runtime.plan_usage(&agent).await?; // plan name, 5-hour and weekly windows for entry in runtime.plan_usage_all().await { // every installed agent, for a dashboard ui.card(&entry.agent.name, entry.usage); } ``` -------------------------------- ### Discover and validate agents Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/core-api.mdx Use the runtime discovery method to scan for installed agents and handle missing ones using the returned report. ```rust let report = runtime.discover().await; let agent = report.require("codex")?; // AgentError::NotInstalled if absent for missing in &report.missing { // MissingAgent { name, install_hint, .. } println!("{}: {}", missing.name, missing.install_hint); } ``` -------------------------------- ### Install anyagent dependencies Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/quickstart.mdx Add the required dependencies to your Rust project using cargo. ```bash cargo add anyagent futures tokio --features tokio/rt-multi-thread,tokio/macros ``` -------------------------------- ### Antigravity Upgrade UI Offer Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/agents.mdx Rust code snippet used to offer an installation upgrade to the user when only the headless agy wire is detected. ```rust if let Some(upgrade) = &agent.upgrade { ui.offer_install(&upgrade.name, &upgrade.install_hint); } ``` -------------------------------- ### Prompting with text and attachments Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/features.mdx Sends text and file attachments to a session, handling the resulting DeliveryKind to determine if the turn started, was steered, or was queued. ```rust let delivery = session .prompt(Input::text("what's wrong here?").attach("screenshot.png")) .await?; match delivery.kind { DeliveryKind::Started { turn_id } => {} // session was idle; a turn began DeliveryKind::Steered { turn_id } => {} // a turn was running; this went into it DeliveryKind::Queued { position } => {} // a turn was running; this waits its turn } ``` -------------------------------- ### session.prompt(input) Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/features.mdx Sends text, slash commands, or file attachments to the agent session. The returned Delivery object indicates whether the prompt started a new turn, steered an existing one, or was queued. ```APIDOC ## session.prompt(input) ### Description Sends an input (text or file attachment) to the agent. The behavior depends on the current session state. ### Parameters - **input** (Input) - Required - The content to send, which can include text and file attachments. ### Returns - **Delivery** - An object containing the kind of delivery (Started, Steered, or Queued) and the associated turn_id or position. ``` -------------------------------- ### Initialize and interact with an agent Source: https://github.com/spotta85/anyagent-rs/blob/main/README.md Demonstrates the core flow of discovering an agent, opening a session, sending a prompt, and streaming the response events. ```rust 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?; ``` -------------------------------- ### runtime.open(&agent, options) Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/features.mdx Spawns an agent process and establishes a live conversation session. ```APIDOC ## runtime.open(&agent, options) ### Description Spawns the agent process, performs a handshake, and returns a session handle and an event stream for communication. ### Method Async Method ### Parameters - **agent** (Agent) - Required - The agent to open. - **options** (SessionOptions) - Required - Configuration options for the session, such as the config home directory. ### Response - **session** (Session) - Handle for sending commands. - **events** (Events) - Stream for receiving agent events. ``` -------------------------------- ### Run live harness tests with just Source: https://github.com/spotta85/anyagent-rs/blob/main/contributions.md Execute live harness tests for wire or adapter changes, providing the output in the pull request. ```bash just live ``` -------------------------------- ### Runtime::open(&agent, options) Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/core-api.mdx Spawns an agent session and returns the Session and Events handles for communication. ```APIDOC ## Runtime::open(&agent, options) ### Description Spawns the agent and returns the two halves of the communication channel: the Session for sending commands and the Events stream for reading agent output. ### Parameters - **agent** (AgentInstallation) - The agent to spawn. - **options** (SessionOptions) - Configuration options for the session. ### Returns - **(Session, Events)** - A tuple containing the session controller and the event stream. ``` -------------------------------- ### Configure MCP servers with SessionOptions Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/features.mdx Shows how to register stdio, HTTP, and SSE MCP servers within the session options. ```rust let options = SessionOptions::in_dir(".") .mcp_server(McpServer::stdio("local", "/usr/bin/my-server", ["--stdio"])) .mcp_server(McpServer::http("remote", "https://example.com/mcp").with("Authorization", "Bearer …")) .mcp_server(McpServer::sse("stream", "https://example.com/sse")); ``` -------------------------------- ### Monitor usage with runtime.plan_usage_all Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/building-an-app.mdx Iterates through usage entries to update the UI with quota information per agent. ```rust for entry in runtime.plan_usage_all().await { // one call, every installed agent match entry.usage { Ok(usage) => ui.quota_card(&entry.agent.name, usage), // plan name, 5-hour and weekly windows Err(_) => {} // no subscription or no PlanUsage capability } } ``` -------------------------------- ### Runtime and Session Capabilities Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/features.mdx A summary of available methods for runtime management, session control, and event monitoring. ```text Runtime discover · probe · open · generate · plan_usage Session prompt · answer · configure · cancel · rollback · compact · close Events text · tools · plans · requests · status · usage · turn boundaries ``` -------------------------------- ### Fork session from history Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/features.mdx Creates a new session starting from an existing session's history, leaving the original session untouched. Use None for message_id to fork from the end of the history. ```rust let options = SessionOptions::in_dir(".").fork_from(token, Some(message_id)); // None = from the end let (branch, branch_events) = runtime.open(&agent, options).await?; ``` -------------------------------- ### Run project checks with just Source: https://github.com/spotta85/anyagent-rs/blob/main/contributions.md Execute the required project checks before submitting a pull request. ```bash just check ``` -------------------------------- ### Discover Agents with runtime.discover() Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/features.mdx Finds all supported agents on the machine by checking environment variables, PATH, and known directories. Use report.require to select a specific agent or return an AgentError if missing. ```rust let report = runtime.discover().await; for agent in &report.agents { println!("{} at {}", agent.name, agent.executable_path.display()); } for missing in &report.missing { println!("{} not installed: {}", missing.name, missing.install_hint); } let agent = report.require("claude")?; // AgentError::NotInstalled if absent ``` -------------------------------- ### Open a Session with SessionOptions Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/building-an-app.mdx Configures session options based on thread state, including resume tokens, permission modes, and model selection. It handles session opening, including fallback logic for stale tokens and authentication requirements. ```rust let mut options = SessionOptions::in_dir(&thread.repo_dir); if let Some(token) = &thread.resume_token { options = options.resume(token.clone()); // continue an old conversation } if thread.unattended { options = options.permission_mode(PermissionMode::AutoApprove); } if let Some(model) = &thread.model { options = options.configure("model", model.as_str()); } let (session, events) = match runtime.open(&agent, options).await { Ok(pair) => pair, Err(AgentError::ResumeFailed(_)) => { // the token went stale: start fresh, keep your transcript runtime.open(&agent, SessionOptions::in_dir(&thread.repo_dir)).await? } Err(AgentError::AuthRequired { login }) => return ui.show_login(login), Err(e) => return Err(e.into()), }; thread.save_info(session.info()); // resume token, capabilities, options ``` -------------------------------- ### Handle agent permissions and questions Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/building-an-app.mdx Uses open_request to match on Request types, rendering either a permission dialog or a question form based on the agent's request. ```rust fn open_request(ui: &Ui, session: Session, request: Request) { match request { Request::Permission(r) => { // r.tool is the ToolUpdate awaiting approval (title, input, diffs) ui.permission_dialog(r.tool, r.detail, r.options, move |choice| { let session = session.clone(); async move { session.answer(r.id.clone(), Answer::Permission(choice)).await } }); } Request::Question(r) => { // one answer per question, in order; choices or free text per q.allows_free_text ui.question_form(r.questions, move |answers: Vec| { let session = session.clone(); async move { session.answer(r.id.clone(), Answer::Question(answers)).await } }); } } } ``` -------------------------------- ### session.compact Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/features.mdx Triggers the agent to summarize its own context to free up window space. ```APIDOC ## session.compact() ### Description Asks the agent to summarize its own context. This operation confirms with `ContextCompacted` followed by a `ContextUsage` update. ### Usage ```rust session.compact().await?; ``` ``` -------------------------------- ### Configure headless session options Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/building-an-app.mdx Sets up session options for unattended workers by enabling auto-approval and specific agent modes. ```rust let options = SessionOptions::in_dir(&repo) .permission_mode(PermissionMode::AutoApprove) // allow every tool request .configure("mode", "accept-edits"); // if the agent has such a mode ``` -------------------------------- ### Run pi in RPC mode Source: https://github.com/spotta85/anyagent-rs/blob/main/tests/fixtures/pi/README.md Command used to generate the wire recordings with the specified provider and model. ```bash pi --mode rpc --provider openrouter --model nvidia/nemotron-3-super-120b-a12b:free ``` -------------------------------- ### Test with mock agents Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/building-an-app.mdx Initializes a runtime with a scripted agent using the mock feature to test engine logic without external dependencies. ```rust let runtime = Runtime::with_mock(Script::default().turn(vec![ Step::Emit(text("m1", "hi")), Step::Emit(permission("p1")), Step::AwaitAnswer, Step::End(completed()), ])); let agent = runtime.discover().await.require("mock")?.clone(); // steps 3 to 7 run unchanged ``` -------------------------------- ### Open a new agent session Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/features.mdx Spawns an agent process and returns a Session handle and an Events stream. Requires a directory path for session configuration. ```rust let (session, events) = runtime .open(&agent, SessionOptions::in_dir("/path/to/repo")) .await?; ``` -------------------------------- ### Send prompts and cancel sessions Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/building-an-app.mdx Demonstrates sending text and file attachments via session.prompt and handling session cancellation. ```rust async fn send(session: &Session, text: String, files: Vec) -> Result<(), AgentError> { let mut input = Input::text(text); for f in files { input = input.attach(f); } match session.prompt(input).await?.kind { DeliveryKind::Started { .. } | DeliveryKind::Steered { .. } => {} DeliveryKind::Queued { position } => ui.show_queued(position), } Ok(()) } // stop button session.cancel(false).await?; // true also drops queued prompts ``` -------------------------------- ### Runtime::generate(&agent, options, prompt) Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/core-api.mdx Performs a one-shot text generation task by opening a session, prompting the agent, and closing the session. ```APIDOC ## Runtime::generate(&agent, options, prompt) ### Description Performs a one-shot text generation task by opening a session, prompting the agent, and closing the session. ### Parameters - **agent** (AgentInstallation) - The agent to use. - **options** (SessionOptions) - Configuration options. - **prompt** (String) - The text prompt to send. ### Returns - **String** - The generated text response. ``` -------------------------------- ### runtime.probe(&agent) Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/features.mdx Queries the agent for its capabilities, configuration, and authentication status by opening a temporary session. ```APIDOC ## runtime.probe(&agent) ### Description Queries the agent to retrieve its version, real login state, capabilities, and configuration options. This operation opens a temporary session. ### Method Async Method ### Parameters - **agent** (Agent) - Required - The agent instance to probe. ### Response - **details** (AgentDetails) - Contains auth status, capabilities, and config options. ``` -------------------------------- ### Configure session options Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/features.mdx Configures agent settings like model and effort. Options can be set at creation or updated mid-session if marked as live. ```rust // at open: creation-only and live options alike let options = SessionOptions::in_dir(".").configure("model", "sonnet").configure("effort", "low"); // mid-session: options with `live: true` session.configure("fast", true).await?; ``` -------------------------------- ### Add anyagent dependency Source: https://github.com/spotta85/anyagent-rs/blob/main/README.md Add the anyagent crate to your Cargo.toml file. ```toml [dependencies] anyagent = "0.0.1" ``` -------------------------------- ### Persist and resume session Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/building-an-app.mdx Loads session information and uses the resume token to reopen a session. The resume token must be stored as-is. ```rust // tomorrow, after restart let info = store.load_info(thread_id); let token = info.resume_token.clone().ok_or("this agent cannot resume")?; let (session, events) = runtime .open(&info.agent, SessionOptions::in_dir(&repo).resume(token)) .await?; ``` -------------------------------- ### Handling agent permissions and questions Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/features.mdx Responds to permission requests and questions forwarded by the agent. Use RequestClosed to clear UI elements. ```rust EventKind::RequestOpened(Request::Permission(r)) => { // r.tool is the ToolUpdate awaiting approval; r.options is what the agent accepts session.answer(r.id, Answer::Permission(PermissionChoice::AllowOnce)).await?; } EventKind::RequestOpened(Request::Question(r)) => { // one QuestionAnswer per question, in order; Choices(ids) or Text(string) let answers = r.questions.iter().map(|q| QuestionAnswer::Choices(vec![q.choices[0].id.clone()])).collect(); session.answer(r.id, Answer::Question(answers)).await?; } EventKind::RequestClosed { request_id } => ui.clear(request_id), ``` -------------------------------- ### Session Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/core-api.mdx Methods for interacting with a live agent session, including sending prompts, answering requests, and managing session state. ```APIDOC ## Session ### Description Handle for a live conversation. Used to send prompts, answer requests, configure settings, and manage the session lifecycle. ### Methods - **prompt(input)** - Sends text or an `Input` with attachments. Returns a `Delivery`. - **dequeue(prompt_id)** - Drops a queued prompt before it starts. - **answer(request_id, answer)** - Answers a permission or question request. - **configure(id, value)** - Changes a live configuration option. - **rollback(turns, scope)** - Rewinds completed turns. - **compact()** - Requests the agent to summarize its context. - **cancel(clear_queue)** - Stops the running turn. - **close()** - Ends the agent session. - **info()** - Returns a snapshot of agent details and configuration. - **status()** - Returns current status (`Idle`, `Working`, or `NeedsInput`). ``` -------------------------------- ### Configure Cargo.toml dependencies Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/quickstart.mdx The resulting dependencies added to your Cargo.toml file. ```toml [dependencies] anyagent = "0.0.1" futures = "0.3" tokio = { version = "1", features = ["rt-multi-thread", "macros"] } ``` -------------------------------- ### Compact session context Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/features.mdx Summarizes the agent's context to free window space without losing the thread. Compaction runs as an agent-originated turn. ```rust session.compact().await?; ``` -------------------------------- ### Configure Agent Session Isolation Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/agents.mdx Set a custom configuration directory for an agent session using config_home. AnyAgent will set the corresponding environment variable for the process; failure to support this results in an InvalidConfiguration error. ```rust SessionOptions::in_dir(".").config_home("/path/to/work-account") ``` -------------------------------- ### Resume session with resume_token Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/features.mdx Continues a conversation from a new process using a stored resume_token. The agent regains its context, but old events are not replayed. ```rust let token = session.info().resume_token.clone().unwrap(); // grab it while alive // later, any process let (session, events) = runtime .open(&agent, SessionOptions::in_dir(".").resume(token)) .await?; ``` -------------------------------- ### One-shot generation with runtime.generate Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/features.mdx Performs a single prompt-to-string generation without managing a persistent session. It automatically disables tools and rejects permissions, returning a String. ```rust let title = runtime .generate(&agent, SessionOptions::in_dir("."), "a five-word title for: fix the parser") .await?; ``` -------------------------------- ### Runtime::probe(&agent) Source: https://github.com/spotta85/anyagent-rs/blob/main/docs/core-api.mdx Opens a throwaway session to retrieve detailed information about an agent, including version, authentication, capabilities, and configuration options. ```APIDOC ## Runtime::probe(&agent) ### Description Opens a throwaway session to retrieve detailed information about an agent, including version, authentication, capabilities, and configuration options. ### Parameters - **agent** (AgentInstallation) - The agent to probe. ### Returns - **AgentDetails** - Detailed information about the agent. ```