Skip to main content

Crate open_agent

Crate open_agent 

Source
Expand description

§Open Agent SDK - Rust Implementation

A streaming Rust SDK for building AI agents over two wire protocols: OpenAI chat completions and Anthropic messages.

§Overview

The protocol is a property of the endpoint. Select it with AgentOptions::builder().protocol(..); it defaults to ApiProtocol::OpenAiChat.

ApiProtocol::OpenAiChat posts to {base_url}/chat/completions with bearer auth:

  • LM Studio, Ollama, llama.cpp, vLLM, and other local servers
  • OpenAI, OpenRouter, z.ai, and other hosted OpenAI-compatible endpoints

ApiProtocol::Anthropic posts to {base_url}/messages with x-api-key and anthropic-version:

  • Anthropic
  • Moonshot Kimi for Coding, MiniMax, and other Anthropic-shaped endpoints

§Two Interaction Modes

§1. Simple Query Function (query())

For single-turn interactions without conversation state:

use open_agent::{query, AgentOptions, ContentBlock, FinishReason, StreamEvent};
use futures::StreamExt;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Configure the agent with required settings
    let options = AgentOptions::builder()
        .system_prompt("You are a helpful assistant")
        .model("qwen2.5-32b-instruct")
        .base_url("http://localhost:1234/v1")
        .build()?;

    // Send a single query and stream the response
    let mut stream = query("What's the capital of France?", &options).await?;

    // Process each event as it arrives; the stream always ends with one Finish
    while let Some(event) = stream.next().await {
        match event? {
            StreamEvent::Block(ContentBlock::Text(text_block)) => {
                print!("{}", text_block.text);
            }
            StreamEvent::Block(ContentBlock::ToolUse(tool_block)) => {
                println!("Tool called: {}", tool_block.name());
            }
            StreamEvent::Finish(FinishReason::Length) => {
                eprintln!("response was truncated at the token cap");
            }
            _ => {}
        }
    }

    Ok(())
}

§2. Client Object (Client)

For multi-turn conversations with persistent state:

use open_agent::{Client, AgentOptions, ContentBlock};
use futures::StreamExt;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let options = AgentOptions::builder()
        .system_prompt("You are a helpful assistant")
        .model("qwen2.5-32b-instruct")
        .base_url("http://localhost:1234/v1")
        .build()?;

    // Create a stateful client that maintains conversation history
    let mut client = Client::new(options)?;

    // First turn
    client.send("What's 2+2?").await?;
    while let Some(block) = client.receive().await? {
        match block {
            ContentBlock::Text(text) => print!("{}", text.text),
            ContentBlock::ToolUse(_) | ContentBlock::ToolResult(_) | ContentBlock::Image(_) => {}
        }
    }

    // Second turn - client remembers previous context
    client.send("What about if we multiply that by 3?").await?;
    while let Some(block) = client.receive().await? {
        match block {
            ContentBlock::Text(text) => print!("{}", text.text),
            ContentBlock::ToolUse(_) | ContentBlock::ToolResult(_) | ContentBlock::Image(_) => {}
        }
    }

    Ok(())
}

Modules§

prelude
Convenience module containing the most commonly used types and functions. Import with use open_agent::prelude::*; to get everything you need for typical usage.
retry
Retry utilities with exponential backoff and jitter. Made public as a module so users can access retry configuration and functions for their own operations that need retry logic. Retry utilities with exponential backoff

Structs§

AgentOptions
Configuration for model requests, tool execution, and hooks.
AgentOptionsBuilder
Builds AgentOptions with runtime validation.
AnthropicErrorBody
The body of a mid-stream error event.
AnthropicMessage
One conversation turn.
AnthropicMessageDelta
Top-level message changes, carrying the reason generation stopped.
AnthropicRequest
Request payload for POST {base_url}/messages.
BaseUrl
A base URL validated at construction time.
Client
A reusable conversation client with optional automatic tool execution.
HookDecision
A hook decision to continue, block, or replace input.
Hooks
An ordered registry of asynchronous lifecycle hooks.
ImageBlock
Image content block for vision-capable models.
Message
A complete message in a conversation.
ModelName
A model name validated at construction time.
OpenAIFunction
Function name and JSON-encoded arguments for an OpenAI tool call.
OpenAIMessage
OpenAIRequest
An OpenAI chat-completions request.
OpenAIToolCall
An OpenAI tool call, including the call ID used to pair its result.
PostToolUseEvent
Snapshot passed to an automatic post-tool hook.
PreToolUseEvent
Snapshot passed to an automatic pre-tool hook.
Temperature
A temperature validated at construction time.
TextBlock
A text block in a message or an incremental streamed text fragment.
Tool
A named asynchronous function with a JSON input schema.
ToolBuilder
Builds a Tool by adding parameters or supplying a complete schema.
ToolResultBlock
A JSON tool result paired with the originating ToolUseBlock ID.
ToolUseBlock
A model-requested tool call with an ID, name, and assembled JSON input.
UserPromptSubmitEvent
Snapshot passed to a prompt hook before the user message is added to history.

Enums§

AnthropicBlockStart
The declaration that opens a content block.
AnthropicDelta
One fragment appended to an open block.
AnthropicEvent
One event from an Anthropic streaming response.
ApiProtocol
The wire protocol an endpoint exposes.
ContentBlock
A text, image, tool-call, or tool-result block.
Error
Errors from configuration, transport, stream decoding, and tool execution.
FinishReason
Why the model stopped generating.
ImageDetail
Image detail level for vision API calls.
MessageRole
Identifies the sender of a conversation message. Serializes as a lowercase string.
OpenAIContent
OpenAI message content, serialized as either a string or a list of parts.
OpenAIContentPart
A single content part in an OpenAI message.
Provider
Local inference providers with conventional OpenAI-compatible endpoint URLs.
StreamEvent
One item in the stream returned by query().

Constants§

HOOK_POST_TOOL_USE
String constant for the PostToolUse hook event name.
HOOK_PRE_TOOL_USE
String constant for the PreToolUse hook event name.
HOOK_USER_PROMPT_SUBMIT
String constant for the UserPromptSubmit hook event name.

Functions§

anthropic_finish_reason
Maps an Anthropic stop_reason onto the SDK’s protocol-neutral FinishReason.
coalesce_text_blocks
Joins runs of adjacent ContentBlock::Text, leaving every other block untouched.
estimate_tokens
Estimates tokens using UTF-8 byte lengths and fixed image allowances.
get_base_url
Resolves a base URL in this order:
get_model
Resolves a model name with optional environment lookup.
is_approaching_limit
Returns whether estimate_tokens is strictly greater than limit * margin.
query
Starts a single-turn streaming query using the configured protocol.
tool
Starts a ToolBuilder.
truncate_messages
Clones the most recent keep messages, optionally preserving the first system message.

Type Aliases§

EventStream
A stream of content, optional reasoning, and one final finish event.
Result
A result using the SDK Error type.