Skip to main content

AgentBuilder

Struct AgentBuilder 

Source
pub struct AgentBuilder<'a> { /* private fields */ }
Expand description

Builder for creating an agent with custom configuration.

Implementations§

Source§

impl<'a> AgentBuilder<'a>

Source

pub fn new(oxicode: &'a Oxicode, config: AgentConfig) -> Self

Create a new builder bound to the given Oxicode instance with the provided agent config.

Source

pub fn workspace(self, dir: impl Into<PathBuf>) -> Self

Set the working directory for file tools.

Source

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

Set a custom system prompt.

Source

pub fn with_mode(self, mode: Mode) -> Self

Set the agent’s autonomy Mode.

In Mode::Auto the agent runs to completion without asking the user questions (the ask tool is short-circuited). Default: Mode::Default.

Source

pub fn with_todo(self, todo: Arc<dyn TodoStateProvider>) -> Self

Register a TodoStateProvider so the agent’s todo tool works.

The provider is shared between the agent (writer) and the host application (reader), so you can observe phase changes in real time by calling TodoStateProvider::get_phases() periodically.

Use InMemoryTodoState for a ready-to-go in-memory implementation:

use std::sync::Arc;
use oxicode_sdk::{AgentConfig, OxicodeBuilder, inmem::InMemoryTodoState};

let todo = Arc::new(InMemoryTodoState::new());
let oxicode = OxicodeBuilder::new().with_builtins().build();
let agent = oxicode.agent(AgentConfig {
    model_id: "anthropic/claude-sonnet-4-20250514".into(),
    ..Default::default()
})
.with_todo(todo.clone())
.build()
.unwrap();

// Observe later:
let phases = todo.get_phases();
Source

pub fn with_memory_backend(self, backend: Arc<dyn MemoryBackend>) -> Self

Register a MemoryBackend and the four memory_* tools (memory_recall, memory_reflect, memory_retain, memory_edit).

Generic entry point: pass any MemoryBackend. For the common case of bridging the engine’s registered MemoryStore port, use Self::with_port_memory instead.

Source

pub fn with_port_memory(self) -> Self

Bridge the engine’s registered MemoryStore (+ EmbeddingProvider) ports into this agent’s memory_* tools via PortMemoryBackend.

This is how a pure-SDK consumer makes memory functional end-to-end: register the ports on OxicodeBuilder (with_memory / with_embeddings), then call this on the agent. Without an EmbeddingProvider, put / list / delete work but semantic search returns an error.

Without this call (or Self::with_memory_backend), the memory_* tools are absent and ToolContext.memory stays None — the registered MemoryStore port is unused by the agent loop.

use std::sync::Arc;
use oxicode_sdk::{OxicodeBuilder, inmem::InMemoryMemoryStore};

let oxicode = OxicodeBuilder::new()
    .with_builtins()
    .with_memory(Arc::new(InMemoryMemoryStore::new()))
    .build();
let agent = oxicode.agent(oxicode_agent::AgentConfig {
    model_id: "anthropic/claude-sonnet-4-20250514".into(),
    ..Default::default()
})
.with_port_memory()
.build()
.unwrap();
Source

pub fn with_url_resolver(self, resolver: Arc<dyn UrlResolver>) -> Self

Set the URL resolver — enables internal-URL dispatch (issue://, skill://, memory://, …) in the read/grep/find tools.

Source

pub fn with_port_url_resolver(self) -> Self

Bridge the engine’s registered InternalUrlRouter port into this agent’s read/grep/find tools via SdkUrlResolver.

This is how a pure-SDK consumer enables protocol-scheme URL resolution: register scheme handlers on the router port, then call this. Without it (or Self::with_url_resolver), URL-prefixed paths are treated as regular file paths.

Source

pub fn with_snapshot_store(self, store: Arc<dyn SnapshotStore>) -> Self

Set the hashline snapshot store — enables line-anchored edit mode (read emits [path#TAG] headers, edit validates against them).

Without this, the edit tool falls back to plain text replacement. Use oxicode_hashline::InMemorySnapshotStore for an ephemeral store, or implement oxicode_hashline::SnapshotStore for persistence.

Source

pub fn with_port_subagent(self) -> Self

Bridge the engine into an in-process subagent runner and register the subagent tool.

Uses SdkSubagentRunner so the subagent tool runs isolated agents in-process (no CLI binary). Without this, the subagent tool is absent from the agent’s toolset.

Source

pub fn with_port_hooks(self) -> Self

Add the HookMiddleware backed by the engine’s registered HookRunner port (see crate::OxicodeBuilder::with_hooks).

When the port is NoopHookRunner (the default), this is a no-op. The middleware composes into the existing pipeline at the audit → authorizer → hooks → user position. set_hooks is called exactly once in build() — see the single-set_hooks invariant.

Source

pub fn with_session_hooks(self, closures: SessionHookClosures) -> Self

Install session-level closures (stop flag + steering/follow_up queues). These are composed into the same AgentHooks that the middleware pipeline produces, so set_hooks is called exactly once. This is the only way to install session hooks — never call agent.set_hooks(...) elsewhere (it would wipe the middleware pipeline’s before/after_tool_call slots).

Source

pub fn with_compactor(self, compactor: Arc<dyn Compactor>) -> Self

Replace the default LLM compactor with a custom one.

The compactor is threaded into every agent run (via AgentLoopConfig::compactor) and replaces the default LlmCompactor — the CompactionManager has a single compactor slot. None (default) preserves the existing LLM-compactor behavior.

The SDK ships crate::snapcompact_compactor::SnapcompactCompactor — a PNG-frame compactor that makes no LLM call:

AgentBuilder::new(oxicode, config)
    .with_compactor(std::sync::Arc::new(SnapcompactCompactor::new()))
    .build()
Source

pub fn coding_tools(self) -> Self

Register the standard coding tools (read, write, edit, bash, grep, find, ls, …).

Source

pub fn readonly_tools(self) -> Self

Register read-only tools (read, ls).

Source

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

Register a tool.

Source

pub fn custom_tool( self, name: impl Into<String>, description: impl Into<String>, schema: Value, handler: impl Fn(Value, &ToolContext) -> Result<AgentToolResult, ToolError> + Send + Sync + 'static, ) -> Self

Register a custom tool from a closure (synchronous handler).

Creates a ClosureTool internally.

§Example
use oxicode_sdk::{ClosureTool, AgentToolResult};

// custom_tool creates a tool from a closure
let tool = ClosureTool::new_sync(
    "memory_recall",
    "Search long-term memory",
    serde_json::json!({"type": "object", "properties": {"query": {"type": "string"}}}),
    |params, _ctx| {
        let query = params["query"].as_str().unwrap();
        Ok(AgentToolResult::success(format!("Recalled: {}", query)))
    },
);
Source

pub fn tools( self, tools: impl IntoIterator<Item = impl AgentTool + 'static>, ) -> Self

Register multiple tools.

Source

pub fn kernel_tools( self, provider: &dyn KernelToolProvider, context: &KernelToolContext, ) -> Self

Register kernel tools from a KernelToolProvider.

This is the bridge for oxios kernel tools (exec, memory, browser, etc.). The kernel implements KernelToolProvider and registers its tools into the agent’s tool registry.

Source

pub fn capabilities(self, caps: CapabilitySet) -> Self

Set the capability set for this agent.

Source

pub fn coding_capabilities(self) -> Self

Use standard coding capabilities.

Source

pub fn readonly_capabilities(self) -> Self

Use read-only capabilities.

Source

pub fn authorizer(self, authorizer: Arc<Authorizer>) -> Self

Attach an authorizer for capability enforcement.

Source

pub fn tracer(self, tracer: Arc<Tracer>) -> Self

Attach a tracer for distributed tracing.

Source

pub fn audit_log(self, audit: Arc<AuditLog>) -> Self

Attach an audit log for security and tool audit trail.

Source

pub fn cost_tracker(self, tracker: Arc<CostTracker>) -> Self

Attach a cost tracker for token and cost monitoring.

Source

pub fn middleware(self, mw: impl Middleware + 'static) -> Self

Add a middleware to the pipeline.

Source

pub fn with_rate_limit(self, max_per_minute: usize) -> Self

Add a rate limit middleware (convenience shortcut).

Source

pub fn with_token_budget(self, max_tokens: usize) -> Self

Add a token budget middleware (convenience shortcut).

Source

pub fn with_logging(self) -> Self

Add a logging middleware (convenience shortcut).

Source

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

Build the agent.

Uses the Oxicode engine’s ProviderResolver for isolated provider/model lookups, so switch_model() and compaction stay within the engine’s registry — no global state pollution.

Auto Trait Implementations§

§

impl<'a> !RefUnwindSafe for AgentBuilder<'a>

§

impl<'a> !UnwindSafe for AgentBuilder<'a>

§

impl<'a> Freeze for AgentBuilder<'a>

§

impl<'a> Send for AgentBuilder<'a>

§

impl<'a> Sync for AgentBuilder<'a>

§

impl<'a> Unpin for AgentBuilder<'a>

§

impl<'a> UnsafeUnpin for AgentBuilder<'a>

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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

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.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more