AgentBuilder

Struct AgentBuilder 

Source
pub struct AgentBuilder { /* private fields */ }
Expand description

Builder for creating an Agent with fluent configuration

Use Agent::builder() to create a new builder, configure it with the various with_* methods, and call .build().await to create the agent.

§Example

use mixtape_core::{Agent, ClaudeHaiku4_5, Result};

#[tokio::main]
async fn main() -> Result<()> {
    let agent = Agent::builder()
        .bedrock(ClaudeHaiku4_5)
        .with_system_prompt("You are a helpful assistant")
        .add_tool(Calculator)
        .build()
        .await?;

    let response = agent.run("What's 2 + 2?").await?;
    println!("{}", response);
    Ok(())
}

Implementations§

Source§

impl AgentBuilder

Source

pub fn new() -> Self

Create a new AgentBuilder with default settings

Source

pub fn provider(self, provider: impl ModelProvider + 'static) -> Self

Use a pre-configured provider

Use this when you need custom provider configuration (e.g., custom retry settings, inference profiles) or a custom provider implementation.

§Example
let provider = BedrockProvider::new(ClaudeSonnet4_5).await
    .with_max_retries(5)
    .with_inference_profile(InferenceProfile::US);

let agent = Agent::builder()
    .provider(provider)
    .build()
    .await?;
Source

pub fn add_tool(self, tool: impl Tool + 'static) -> Self

Add a tool to the agent

§Example
let agent = Agent::builder()
    .bedrock(ClaudeHaiku4_5)
    .add_tool(Calculator)
    .add_tool(WeatherLookup)
    .build()
    .await?;
Source

pub fn add_trusted_tool(self, tool: impl Tool + 'static) -> Self

Add a trusted tool to the agent with automatic permission grant

This is a convenience method that adds the tool and automatically grants permission for it to execute. Use this for tools you trust completely.

§Example
let agent = Agent::builder()
    .bedrock(ClaudeHaiku4_5)
    .add_trusted_tool(Calculator)
    .add_trusted_tool(WeatherLookup)
    .build()
    .await?;
Source

pub fn add_tools( self, tools: impl IntoIterator<Item = Box<dyn DynTool>>, ) -> Self

Add multiple tools to the agent

Accepts pre-boxed dynamic tools, typically from tool group helper functions.

§Example
use mixtape_tools::sqlite;

// Add all read-only SQLite tools
let agent = Agent::builder()
    .bedrock(ClaudeHaiku4_5)
    .add_tools(sqlite::read_only_tools())
    .build()
    .await?;

// Or add all SQLite tools
let agent = Agent::builder()
    .bedrock(ClaudeHaiku4_5)
    .add_tools(sqlite::all_tools())
    .build()
    .await?;
Source

pub fn add_trusted_tools( self, tools: impl IntoIterator<Item = Box<dyn DynTool>>, ) -> Self

Add multiple trusted tools to the agent with automatic permission grants

This is a convenience method that adds the tools and automatically grants permission for them to execute. Use this for tools you trust completely.

§Example
use mixtape_tools::sqlite;

// Add all read-only SQLite tools as trusted
let agent = Agent::builder()
    .bedrock(ClaudeHaiku4_5)
    .add_trusted_tools(sqlite::read_only_tools())
    .build()
    .await?;
Source

pub fn with_system_prompt(self, prompt: impl Into<String>) -> Self

Set the system prompt

Source

pub fn with_max_concurrent_tools(self, max: usize) -> Self

Set the maximum number of tools that can execute concurrently

Source

pub fn with_conversation_manager( self, manager: impl ConversationManager + 'static, ) -> Self

Set a custom conversation manager

Source

pub fn add_context(self, content: impl Into<String>) -> Self

Add literal string content as context

The content will be included directly in the system prompt. Use this for dynamic context that doesn’t come from a file.

§Example
let agent = Agent::builder()
    .bedrock(ClaudeSonnet4_5)
    .add_context("# Project Rules\nAlways use async/await.")
    .build()
    .await?;
Source

pub fn add_context_file(self, path: impl Into<String>) -> Self

Add a required context file

The path supports variable substitution:

  • $CWD - current working directory at resolution time
  • $HOME or ~ - user’s home directory

Relative paths are resolved against the current working directory. The file must exist or an error is returned at runtime.

Context files are resolved at runtime (each run() call), allowing files to change between runs.

§Example
let agent = Agent::builder()
    .bedrock(ClaudeSonnet4_5)
    .add_context_file("~/.config/myagent/rules.md")
    .build()
    .await?;
Source

pub fn add_optional_context_file(self, path: impl Into<String>) -> Self

Add an optional context file

Same as add_context_file() but the file is optional. If the file doesn’t exist, it will be silently skipped.

§Example
let agent = Agent::builder()
    .bedrock(ClaudeSonnet4_5)
    .add_optional_context_file("AGENTS.md")
    .build()
    .await?;
Source

pub fn add_context_files( self, paths: impl IntoIterator<Item = impl Into<String>>, ) -> Self

Add multiple required context files

All files must exist or an error is returned at runtime. Files are loaded in the order provided.

§Example
let agent = Agent::builder()
    .bedrock(ClaudeSonnet4_5)
    .add_context_files(["rules.md", "examples.md"])
    .build()
    .await?;
Source

pub fn add_optional_context_files( self, paths: impl IntoIterator<Item = impl Into<String>>, ) -> Self

Add multiple optional context files

Files that exist are loaded; missing files are skipped. Files are loaded in the order provided.

§Example
let agent = Agent::builder()
    .bedrock(ClaudeSonnet4_5)
    .add_optional_context_files(["AGENTS.md", "agents.md", "CLAUDE.md"])
    .build()
    .await?;
Source

pub fn add_context_files_glob(self, pattern: impl Into<String>) -> Self

Add context files matching a glob pattern

The pattern supports variable substitution (same as add_context_file()). Files matching the pattern are sorted alphabetically and loaded in order.

Glob patterns are inherently optional - zero matches is acceptable.

§Example
let agent = Agent::builder()
    .bedrock(ClaudeSonnet4_5)
    .add_context_files_glob("$CWD/.context/*.md")
    .build()
    .await?;
Source

pub fn with_context_config(self, config: ContextConfig) -> Self

Configure context file size limits

§Example
use mixtape_core::ContextConfig;

let agent = Agent::builder()
    .bedrock(ClaudeSonnet4_5)
    .with_context_config(ContextConfig {
        max_file_size: 512 * 1024,       // 512KB per file
        max_total_size: 2 * 1024 * 1024, // 2MB total
    })
    .with_context_pattern("$CWD/docs/*.md")
    .build()
    .await?;
Source

pub async fn build(self) -> Result<Agent>

Build the agent

This is where the async provider creation happens. For Bedrock, this loads AWS credentials from the environment.

§Errors

Returns an error if no provider was configured (call .bedrock(), .anthropic(), or .provider() first).

§Example
let agent = Agent::builder()
    .bedrock(ClaudeHaiku4_5)
    .build()
    .await?;
Source§

impl AgentBuilder

Source

pub fn with_grant_store(self, store: impl GrantStore + 'static) -> Self

Set a custom grant store for tool authorization.

By default, the agent uses an in-memory store. Use this to provide a persistent store (e.g., crate::FileGrantStore).

§Example
use mixtape_core::{Agent, FileGrantStore};

let agent = Agent::builder()
    .bedrock(ClaudeSonnet4_5)
    .with_grant_store(FileGrantStore::new("./grants.json"))
    .build()
    .await?;
Source

pub fn with_authorization_timeout(self, timeout: Duration) -> Self

Set the timeout for authorization requests.

If an authorization request is not responded to within this duration, it will be automatically denied.

Default: 5 minutes

Source

pub fn interactive(self) -> Self

Enable interactive authorization prompts.

By default, tools without grants are denied immediately. This is secure for non-interactive environments (scripts, CI/CD, automated agents).

Call .interactive() to enable prompting users for authorization when a tool has no matching grant. The agent will emit crate::AgentEvent::PermissionRequired events that can be handled to approve or deny tool calls.

§Example
use mixtape_core::Agent;

// Interactive mode: prompts user for tools without grants
let agent = Agent::builder()
    .bedrock(ClaudeSonnet4_5)
    .interactive()
    .build()
    .await?;

This can be combined with a grant store for hybrid behavior:

use mixtape_core::{Agent, FileGrantStore};

// Pre-approved tools run immediately, others prompt user
let agent = Agent::builder()
    .bedrock(ClaudeSonnet4_5)
    .interactive()
    .with_grant_store(FileGrantStore::new("./grants.json"))
    .build()
    .await?;

Trait Implementations§

Source§

impl Default for AgentBuilder

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.