1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
//! # Open Agent SDK - Rust Implementation
//!
//! A production-ready, streaming-first Rust SDK for building AI agents with local OpenAI-compatible servers.
//!
//! ## Overview
//!
//! This SDK provides a clean, ergonomic API for working with local LLM servers such as:
//! - LM Studio
//! - Ollama
//! - llama.cpp
//! - vLLM
//!
//! ## Key Features
//!
//! - **Zero API Costs**: Run models on your own hardware
//! - **Privacy-First**: All data stays local on your machine
//! - **High Performance**: Native async/await with Tokio runtime
//! - **Streaming Responses**: Real-time token-by-token streaming
//! - **Tool Calling**: Define and execute tools with automatic schema generation
//! - **Lifecycle Hooks**: Intercept and control execution at key points
//! - **Interrupts**: Gracefully cancel long-running operations
//! - **Context Management**: Manual token estimation and history truncation
//! - **Retry Logic**: Exponential backoff with jitter for reliability
//!
//! ## Two Interaction Modes
//!
//! ### 1. Simple Query Function (`query()`)
//! For single-turn interactions without conversation state:
//!
//! ```rust,no_run
//! use open_agent::{query, AgentOptions, ContentBlock};
//! 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 content block as it arrives
//! while let Some(block) = stream.next().await {
//! match block? {
//! ContentBlock::Text(text_block) => {
//! print!("{}", text_block.text);
//! }
//! ContentBlock::ToolUse(tool_block) => {
//! println!("Tool called: {}", tool_block.name());
//! }
//! ContentBlock::ToolResult(_) => {
//! // Tool results can be ignored in simple queries
//! }
//! ContentBlock::Image(_) => {
//! // Images not expected in this example
//! }
//! }
//! }
//!
//! Ok(())
//! }
//! ```
//!
//! ### 2. Client Object (`Client`)
//! For multi-turn conversations with persistent state:
//!
//! ```rust,no_run
//! 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(())
//! }
//! ```
//!
//! ## Architecture
//!
//! The SDK is organized into several modules, each with a specific responsibility:
//!
//! - **client**: Core streaming query engine and multi-turn client
//! - **types**: Data structures for messages, content blocks, and configuration
//! - **tools**: Tool definition system with automatic JSON schema generation
//! - **hooks**: Lifecycle event system for intercepting execution
//! - **config**: Provider-specific configuration helpers
//! - **error**: Comprehensive error types and conversions
//! - **context**: Token estimation and message truncation utilities
//! - **retry**: Exponential backoff retry logic with jitter
//! - **utils**: Internal utilities for SSE parsing and tool aggregation
// ============================================================================
// MODULE DECLARATIONS
// ============================================================================
// These modules are private (internal implementation details) unless explicitly
// re-exported through `pub use` statements below.
/// Core client implementation providing streaming queries and stateful conversations.
/// Contains the `query()` function for single-turn queries and `Client` struct
/// for multi-turn conversations with automatic state management.
/// Provider configuration helpers for LM Studio, Ollama, llama.cpp, and vLLM.
/// Simplifies endpoint and model name resolution with environment variable support.
/// Context window management utilities for token estimation and history truncation.
/// Provides manual control over conversation memory to prevent context overflow.
/// Error types and conversions for comprehensive error handling throughout the SDK.
/// Defines the `Error` enum and `Result<T>` type alias used across all public APIs.
/// Lifecycle hooks system for intercepting and controlling execution at key points.
/// Enables security gates, audit logging, input/output modification, and compliance checks.
/// Tool definition and execution system with automatic JSON schema generation.
/// Allows LLMs to call Rust functions with type-safe parameter handling.
/// Core type definitions for messages, content blocks, and agent configuration.
/// Includes builder patterns for ergonomic configuration and OpenAI API serialization.
/// Internal utilities for Server-Sent Events (SSE) parsing and tool call aggregation.
/// Handles the low-level details of streaming response parsing.
// ============================================================================
// PUBLIC EXPORTS
// ============================================================================
// These items form the public API of the SDK. Everything else is internal.
/// 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.
// --- Core Client API ---
pub use ;
// --- Provider Configuration ---
pub use ;
// --- Context Management ---
pub use ;
// --- Error Handling ---
pub use ;
// --- Lifecycle Hooks ---
pub use ;
// --- Tool System ---
pub use ;
// --- Core Types ---
pub use ;
// ============================================================================
// CONVENIENCE 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.
///
/// This includes:
/// - Configuration: AgentOptions, AgentOptionsBuilder
/// - Client: Client, query()
/// - Content: ContentBlock, TextBlock, ToolUseBlock
/// - Tools: Tool, tool()
/// - Hooks: Hooks, HookDecision, hook event types
/// - Errors: Error, Result