pub struct Agent {
pub history: Box<dyn History>,
/* private fields */
}Expand description
Agent loop that coordinates LLM calls and tool execution.
Uses ParallelExecutor by default.
Fields§
§history: Box<dyn History>Implementations§
Source§impl Agent
impl Agent
Sourcepub fn new(llm: impl LLMProvider + 'static) -> Self
pub fn new(llm: impl LLMProvider + 'static) -> Self
Create a new agent loop
Sourcepub fn history(self, history: impl History + 'static) -> Self
pub fn history(self, history: impl History + 'static) -> Self
Set custom history manager (default: InfiniteHistory)
§Example
use tiny_loop::{Agent, history::InfiniteHistory, llm::OpenAIProvider};
let agent = Agent::new(OpenAIProvider::new())
.history(InfiniteHistory::new());Sourcepub fn system(self, content: impl Into<String>) -> Self
pub fn system(self, content: impl Into<String>) -> Self
Append a system message
§Example
use tiny_loop::{Agent, llm::OpenAIProvider};
let agent = Agent::new(OpenAIProvider::new())
.system("You are a helpful assistant");Sourcepub fn tools(&self) -> &[ToolDefinition]
pub fn tools(&self) -> &[ToolDefinition]
Get reference to registered tool definitions
Sourcepub fn executor(self, executor: impl ToolExecutor + 'static) -> Self
pub fn executor(self, executor: impl ToolExecutor + 'static) -> Self
Set a custom tool executor (default: ParallelExecutor)
§Example
use tiny_loop::{Agent, tool::SequentialExecutor, llm::OpenAIProvider};
let agent = Agent::new(OpenAIProvider::new())
.executor(SequentialExecutor::new());Sourcepub fn tool<Args, Fut>(self, tool: fn(Args) -> Fut) -> Self
pub fn tool<Args, Fut>(self, tool: fn(Args) -> Fut) -> Self
Register a tool function created by #[tool]
To register a tool method with an instance, use Self::bind.
To register external tools (e.g. from MCP servers) use Self::external
§Example
use tiny_loop::{Agent, tool::tool, llm::OpenAIProvider};
#[tool]
async fn fetch(
/// URL to fetch
url: String,
) -> String {
todo!()
}
let agent = Agent::new(OpenAIProvider::new())
.tool(fetch);Sourcepub fn bind<T, Args, Fut>(self, ins: T, tool: fn(T, Args) -> Fut) -> Self
pub fn bind<T, Args, Fut>(self, ins: T, tool: fn(T, Args) -> Fut) -> Self
Bind an instance to a tool method created by #[tool]
To register a standalone tool function, use Self::tool.
To register external tools (e.g. from MCP servers) use Self::external
§Example
use tiny_loop::{Agent, tool::tool, llm::OpenAIProvider};
use std::sync::Arc;
#[derive(Clone)]
struct Database {
data: Arc<String>,
}
#[tool]
impl Database {
/// Fetch data from database
async fn fetch(
self,
/// Data key
key: String,
) -> String {
todo!()
}
}
let db = Database { data: Arc::new("data".into()) };
let agent = Agent::new(OpenAIProvider::new())
.bind(db, Database::fetch);Sourcepub fn external<Fut>(
self,
defs: Vec<ToolDefinition>,
exec: impl Fn(String, String) -> Fut + Clone + Send + Sync + 'static,
) -> Self
pub fn external<Fut>( self, defs: Vec<ToolDefinition>, exec: impl Fn(String, String) -> Fut + Clone + Send + Sync + 'static, ) -> Self
Register external tools (e.g. from MCP servers)
To register a standalone tool function, use tool.
To register a tool method with an instance, use bind.
§Example
use tiny_loop::{Agent, llm::OpenAIProvider, types::{Parameters, ToolDefinition, ToolFunction}};
use serde_json::{json, Value};
let defs = vec![ToolDefinition {
tool_type: "function".into(),
function: ToolFunction {
name: "get_weather".into(),
description: "Get weather information".into(),
parameters: Parameters::from_object(
json!({
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "City name"
}
},
"required": ["city"]
}).as_object().unwrap().clone()
),
},
}];
let external_executor = move |name: String, args: String| {
async move {
let _args = serde_json::from_str::<Value>(&args).unwrap();
"result".into()
}
};
let agent = Agent::new(OpenAIProvider::new())
.external(defs, external_executor);Sourcepub async fn step(&mut self) -> Result<Option<String>>
pub async fn step(&mut self) -> Result<Option<String>>
Execute one iteration of the agent loop.
Returns Ok(Some(content)) if loop should terminate, Ok(None) to continue
This is usually used to customize the agent loop.
§Example
use tiny_loop::{Agent, llm::OpenAIProvider};
let mut agent = Agent::new(OpenAIProvider::new())
.system("You are a helpful assistant");
// Custom loop with early break
let mut iterations = 0;
loop {
println!("Before step {}", iterations);
if let Some(content) = agent.step().await? {
println!("Completed: {}", content);
break;
}
iterations += 1;
if iterations > 10 {
println!("Max iterations reached");
break;
}
}