pub struct Agent { /* private fields */ }Expand description
Subscriber info for fan-out event delivery
Thread-safe, Clone-able agent handle for tokio async usage.
All internal state is held behind a single Arc<Mutex<>> — cloning Agent
just increments the reference count. All public methods take &self.
§Sharing across tasks
let agent = Agent::new("claude-sonnet-4-6");
// Clone into another task
let agent2 = agent.clone();
let handle = tokio::spawn(async move {
agent2.query("do work").await
});
// Subscribe from the original
let (mut sub, _guard) = agent.subscribe();Implementations§
Source§impl Agent
impl Agent
Sourcepub fn new(model: &str) -> Self
pub fn new(model: &str) -> Self
Create a new agent with the given model name.
The model defaults to the AI_MODEL environment variable, then
"claude-sonnet-4-6". All other config (API key, base URL, max turns,
thinking) also defaults from environment.
Chain builder methods to customize:
let agent = Agent::new("claude-sonnet-4-6")
.max_turns(20)
.system_prompt("You are a code reviewer.")
.thinking(ThinkingConfig::Enabled { budget_tokens: 4096 });Returns a Cloneable handle — all internal state uses interior
mutability, so Agent::query takes &self and the agent can be
shared across async tasks via Arc<Agent>.
Sourcepub fn model(self, model: &str) -> Self
pub fn model(self, model: &str) -> Self
Configure the model name.
Triggers engine recreation if the engine is already initialized.
Sourcepub fn api_key(self, api_key: &str) -> Self
pub fn api_key(self, api_key: &str) -> Self
Set the API key.
Triggers engine recreation if the engine is already initialized.
Sourcepub fn base_url(self, base_url: &str) -> Self
pub fn base_url(self, base_url: &str) -> Self
Set a custom base URL for the API.
Triggers engine recreation if the engine is already initialized.
Sourcepub fn cwd(self, cwd: &str) -> Self
pub fn cwd(self, cwd: &str) -> Self
Set the working directory.
Triggers engine recreation if the engine is already initialized.
Sourcepub fn system_prompt(self, prompt: &str) -> Self
pub fn system_prompt(self, prompt: &str) -> Self
Set a custom system prompt.
Sourcepub fn max_turns(self, max_turns: u32) -> Self
pub fn max_turns(self, max_turns: u32) -> Self
Set the maximum number of turns.
Triggers engine recreation if the engine is already initialized.
Sourcepub fn max_budget_usd(self, budget: f64) -> Self
pub fn max_budget_usd(self, budget: f64) -> Self
Set the maximum budget in USD.
Sourcepub fn max_tokens(self, max_tokens: u32) -> Self
pub fn max_tokens(self, max_tokens: u32) -> Self
Set the maximum tokens for a single response.
Sourcepub fn fallback_model(self, model: &str) -> Self
pub fn fallback_model(self, model: &str) -> Self
Set the fallback model.
Sourcepub fn thinking(self, thinking: ThinkingConfig) -> Self
pub fn thinking(self, thinking: ThinkingConfig) -> Self
Set thinking configuration for extended thinking.
Sourcepub fn tools(self, tools: Vec<ToolDefinition>) -> Self
pub fn tools(self, tools: Vec<ToolDefinition>) -> Self
Set tool definitions.
Sourcepub fn allowed_tools(self, tools: Vec<String>) -> Self
pub fn allowed_tools(self, tools: Vec<String>) -> Self
Only allow specific tools by name.
Sourcepub fn disallowed_tools(self, tools: Vec<String>) -> Self
pub fn disallowed_tools(self, tools: Vec<String>) -> Self
Explicitly disallow specific tools by name.
Sourcepub fn mcp_servers(self, servers: HashMap<String, McpServerConfig>) -> Self
pub fn mcp_servers(self, servers: HashMap<String, McpServerConfig>) -> Self
Set MCP server configurations.
Sourcepub fn on_event<F>(self, callback: F) -> Self
pub fn on_event<F>(self, callback: F) -> Self
Set an event callback for streaming agent events.
Can be called at any time (before or after query()). Takes self
so it can be updated between queries for dynamic event handling.
For fully async event handling, prefer Agent::subscribe() with
the EventSubscriber stream instead.
Sourcepub async fn prompt(model: &str, prompt: &str) -> Result<String, AgentError>
pub async fn prompt(model: &str, prompt: &str) -> Result<String, AgentError>
One-shot query — creates an agent, sends the prompt, and returns the text.
Use this for single-turn interactions where you don’t need conversation history
or multi-turn reuse. For persistent agents, use Agent::new() + .query().
§Example
let answer = Agent::prompt("claude-sonnet-4-6", "Explain quantum computing")
.await?;
println!("{answer}");Sourcepub fn get_session_id(&self) -> String
pub fn get_session_id(&self) -> String
Get the session ID.
Sourcepub fn get_messages(&self) -> Vec<Message>
pub fn get_messages(&self) -> Vec<Message>
Get all messages in the conversation history. Delegates to the persisted QueryEngine which owns the message state (matches TypeScript: engine.mutableMessages).
Sourcepub fn get_tools(&self) -> Vec<ToolDefinition>
pub fn get_tools(&self) -> Vec<ToolDefinition>
Get all tools available to the agent
Sourcepub fn set_system_prompt(&self, prompt: &str)
pub fn set_system_prompt(&self, prompt: &str)
Set system prompt for the agent (interior mutability).
Sourcepub fn set_cwd(&self, cwd: &str)
pub fn set_cwd(&self, cwd: &str)
Set the working directory for the agent (interior mutability).
Sourcepub fn set_thinking(&self, thinking: Option<ThinkingConfig>)
pub fn set_thinking(&self, thinking: Option<ThinkingConfig>)
Set thinking configuration for the agent (interior mutability).
Sourcepub fn set_model(&self, model: &str)
pub fn set_model(&self, model: &str)
Set the model name at runtime (interior mutability).
Changes the model for subsequent query() calls, matching TypeScript’s
QueryEngine.setModel().
Sourcepub async fn query(&self, prompt: &str) -> Result<QueryResult, AgentError>
pub async fn query(&self, prompt: &str) -> Result<QueryResult, AgentError>
Main query method - handles the full agent loop including tool use, streaming responses, and multi-turn interaction with the LLM.
Reuses a persisted QueryEngine across calls so that conversation history, usage tracking, and tool state accumulate naturally (matches TypeScript pattern).
Takes &self (interior mutability) — the agent can be shared across tasks.
Sourcepub fn reset(&self)
pub fn reset(&self)
Reset the agent’s conversation history, keeping configuration intact.
Clears all messages, usage tracking, and turn count. This starts a fresh conversation while preserving model, API key, tools, and other settings.
Sourcepub fn subscribe(&self) -> (EventSubscriber, CancelGuard)
pub fn subscribe(&self) -> (EventSubscriber, CancelGuard)
Subscribe to agent events for the current and subsequent queries.
Returns an EventSubscriber (implements futures_util::Stream) and a
CancelGuard. Events flow to the subscriber until the guard is dropped.
Takes &self (not &mut self) — you can subscribe from a shared reference,
enabling decoupled TUI architectures where the subscriber is owned by a
separate task from the agent.
§Example
let (mut sub, _guard) = agent.subscribe();
tokio::pin!(sub);
// Run query asynchronously
tokio::spawn(async move {
agent.query("hello").await;
});
// Consume events
while let Some(ev) = sub.next().await {
// render in TUI
}Sourcepub fn interrupt(&self)
pub fn interrupt(&self)
Interrupt the agent loop. This aborts the current query() call,
cancelling any in-flight API requests and tool execution.
§Example
let agent = Agent::new("claude-sonnet-4-6");
tokio::spawn(async move {
agent.query("Do a lot of work").await.unwrap();
});
tokio::time::sleep(Duration::from_secs(5)).await;
agent.interrupt(); // Cancel the running promptSourcepub async fn recap(&self) -> AwaySummaryResult
pub async fn recap(&self) -> AwaySummaryResult
Generate a short session recap summarizing the conversation so far.
Produces a 1-3 sentence summary suitable for a “while you were away” card or CLI status display. Uses the small/fast model (Haiku) with the last 30 messages and optional session memory context.
Returns AwaySummaryResult which indicates whether the LLM produced
a summary, was aborted, or returned empty (no conversation history).
§Example
let agent = Agent::new("claude-sonnet-4-6")
.api_key("sk-ant-...");
agent.query("build a REST API").await.ok();
// ... user steps away ...
let recap = agent.recap().await;
if let Some(summary) = recap.summary {
println!("※ {}", summary);
}