Skip to main content

AgentRunnerBuilder

Struct AgentRunnerBuilder 

Source
pub struct AgentRunnerBuilder<P: LlmProvider> { /* private fields */ }
Expand description

Builder for AgentRunner.

Construct via AgentRunner::builder, configure the agent with chainable setter methods, then call build to produce the runner. Build validates several invariants: on_input and structured_schema are mutually exclusive, max_tool_calls_per_turn = 0 is rejected, and turn/token limits must be non-zero. For multi-agent scenarios use OrchestratorBuilder instead, which internally wraps an AgentRunner with sub-agent delegation.

Implementations§

Source§

impl<P: LlmProvider> AgentRunnerBuilder<P>

Source

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

Source

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

Source

pub fn tool(self, tool: Arc<dyn Tool>) -> Self

Source

pub fn tools(self, tools: Vec<Arc<dyn Tool>>) -> Self

Register a batch of tools.

SECURITY (F-MCP-2): when MCP-discovered tools and builtins coexist, register the trusted builtins first. The runner deduplicates by name with first-wins semantics, so a hostile MCP server that exports a tool named bash will be shadowed by the local bash builtin only if the builtin was added before. The collision is logged at error! and emits a tool_name_collision audit signal.

Source

pub fn max_turns(self, max_turns: usize) -> Self

Source

pub fn max_tokens(self, max_tokens: u32) -> Self

Source

pub fn context_strategy(self, strategy: ContextStrategy) -> Self

Source

pub fn summarize_threshold(self, threshold: u32) -> Self

Set the token threshold at which to trigger automatic summarization.

Source

pub fn memory(self, memory: Arc<dyn Memory>) -> Self

Attach a memory store to the agent. Memory tools (store, recall, update, forget, consolidate) are created at build() time using the builder’s name.

Call .name() before or after .memory() — the agent name is resolved at build.

Source

pub fn knowledge(self, kb: Arc<dyn KnowledgeBase>) -> Self

Attach a knowledge base to the agent. The knowledge_search tool is added at build() time.

Source

pub fn on_text(self, callback: Arc<OnText>) -> Self

Set a callback for streaming text output. When set, the agent uses stream_complete instead of complete, calling the callback for each text delta as it arrives from the LLM.

The callback must not panic. A panic inside the callback will propagate through the agent loop and abort the run.

Source

pub fn on_approval(self, callback: Arc<OnApproval>) -> Self

Set a callback for human-in-the-loop approval before tool execution.

When set, the callback is invoked with the list of tool calls before each execution round. If it returns false, tool execution is denied and the agent receives error results, allowing the LLM to adjust.

Source

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

Set a timeout for individual tool executions. If a tool does not complete within this duration, the execution is cancelled and an error result is returned to the LLM.

Default: None (no timeout).

Source

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

Set a maximum byte size for individual tool output content.

Tool results exceeding this limit are truncated with a [truncated: N bytes omitted] suffix, preventing oversized results from blowing out the context window.

Default: None (no truncation).

Source

pub fn structured_schema(self, schema: Value) -> Self

Set a JSON Schema for structured output. The agent will receive a synthetic __respond__ tool with this schema. When the LLM calls __respond__, its input is extracted as AgentOutput::structured.

The agent can still use regular tools before producing output.

Source

pub fn on_event(self, callback: Arc<OnEvent>) -> Self

Set a callback for structured agent events. Events are emitted at key points in the agent loop: run start/end, turn transitions, LLM responses, tool call start/completion, approval decisions, and context summarization.

Source

pub fn guardrail(self, guardrail: Arc<dyn Guardrail>) -> Self

Add a single guardrail. Multiple guardrails are evaluated in order; first Deny wins.

Source

pub fn guardrails(self, guardrails: Vec<Arc<dyn Guardrail>>) -> Self

Add multiple guardrails at once.

Source

pub fn on_question(self, callback: Arc<OnQuestion>) -> Self

Set a callback for structured questions to the user. When set, a question tool is added at build() time allowing the agent to ask the user structured questions with predefined options.

Source

pub fn on_input(self, callback: Arc<OnInput>) -> Self

Set a callback for interactive mode. When set and the LLM returns text without tool calls, the callback is invoked to get the next user message. Return Some(message) to continue the conversation or None to end the session.

Source

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

Set a wall-clock deadline for the entire run. If the agent does not complete within this duration, Error::RunTimeout is returned.

Default: None (no deadline).

Source

pub fn reasoning_effort(self, effort: ReasoningEffort) -> Self

Set the reasoning/thinking effort level. Enables extended thinking on models that support it (e.g., Qwen3 via OpenRouter, Claude).

Default: None (no reasoning).

Source

pub fn enable_reflection(self, enabled: bool) -> Self

Source

pub fn tool_output_compression_threshold(self, threshold: usize) -> Self

Source

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

Source

pub fn tool_profile(self, profile: ToolProfile) -> Self

Set a static tool profile to pre-filter tools before dynamic selection.

When set, tool definitions are filtered to the profile’s subset before max_tools_per_turn scoring applies. Use ToolProfile::Conversational for chat-only agents, Standard for code agents, Full for all tools.

Source

pub fn max_identical_tool_calls(self, max: u32) -> Self

Set the maximum number of consecutive identical tool-call turns before the agent receives an error result instead of executing the tools.

This detects “doom loops” where the LLM keeps repeating the exact same tool calls. After max consecutive identical turns, all tool calls in the turn receive an error result asking the LLM to try a different approach.

Default: None (no detection).

Source

pub fn max_fuzzy_identical_tool_calls(self, max: u32) -> Self

Set the maximum number of consecutive fuzzy-identical tool-call turns before the agent receives an error result. Fuzzy matching compares sorted tool names (ignoring inputs), catching loops where the agent retries the same tools with different arguments.

Default: None (no fuzzy detection).

Source

pub fn max_tool_calls_per_turn(self, cap: u32) -> Self

Cap the number of tool invocations the LLM may emit per turn. When the LLM returns more tool_use blocks than cap, the run returns Error::Agent (wrapped in Error::WithPartialUsage) and no tools are dispatched.

Distinct from max_tools_per_turn: that one limits the tool definitions offered to the LLM before it responds (pre-filter). This one caps the invocations in the LLM’s actual response (post-response). Both can be set independently.

Default: None (unlimited). Recommended for production: 8. Zero is rejected at build time.

Source

pub fn permission_rules(self, rules: PermissionRuleset) -> Self

Set declarative permission rules for tool calls.

Rules are evaluated per tool call before the on_approval callback. Allow executes without asking, Deny returns an error result, Ask falls through to the on_approval callback.

Source

pub fn learned_permissions( self, learned: Arc<Mutex<LearnedPermissions>>, ) -> Self

Set learned permissions for persisting AlwaysAllow/AlwaysDeny decisions.

When set, approval decisions with AlwaysAllow or AlwaysDeny are saved to disk and injected into the live permission ruleset.

Source

pub fn lsp_manager(self, manager: Arc<LspManager>) -> Self

Set an LSP manager for collecting diagnostics after file-modifying tools.

When set, after any tool named write, edit, or patch completes, the manager reads the modified file and collects diagnostics from the language server. Diagnostics are appended to the tool result so the LLM sees compilation errors immediately.

Source

pub fn session_prune_config(self, config: SessionPruneConfig) -> Self

Enable session pruning to reduce token usage by truncating old tool results.

Source

pub fn enable_recursive_summarization(self, enable: bool) -> Self

Enable recursive (cluster-then-summarize) summarization for long conversations.

Source

pub fn reflection_threshold(self, threshold: u32) -> Self

Set cumulative importance threshold for memory reflection triggers. When the sum of stored memory importance values exceeds this threshold, the store tool appends a reflection hint to guide the agent.

Source

pub fn consolidate_on_exit(self, enable: bool) -> Self

Enable automatic memory consolidation at session end.

When enabled, clusters related episodic memories by keyword overlap and merges them into semantic summaries. Requires memory to be configured. Adds LLM calls at session end (one per cluster).

Source

pub fn observability_mode(self, mode: ObservabilityMode) -> Self

Set the observability verbosity mode for this agent.

Controls how much detail is recorded in tracing spans:

  • Production: span names + durations only (near-zero overhead)
  • Analysis: + metrics (tokens, latencies, costs)
  • Debug: + full payloads (truncated to 4KB)

When not set, resolved via HEARTBIT_OBSERVABILITY env var or default (Production).

Source

pub fn instruction_text(self, text: impl Into<String>) -> Self

Provide pre-loaded instruction text to prepend to the system prompt.

Use instructions::load_instructions to load from file paths, or instructions::discover_instruction_files to auto-discover them.

Source

pub fn max_total_tokens(self, max: u64) -> Self

Set a hard limit on cumulative tokens (input + output) across all turns.

When the total tokens consumed exceed this limit, the agent returns Error::BudgetExceeded with partial usage data.

Default: None (no budget).

Source

pub fn audit_mode(self, mode: AuditMode) -> Self

Set the audit mode controlling what data is stored in audit records.

  • Full (default): all content is recorded.
  • MetadataOnly: user content fields are replaced with [stripped].
Source

pub fn audit_trail(self, trail: Arc<dyn AuditTrail>) -> Self

Attach an audit trail for recording untruncated agent decisions.

When set, every LLM response, tool call, tool result, run completion, run failure, and guardrail denial is recorded with full payloads. Recording is best-effort: failures are logged, never abort the agent.

Source

pub fn audit_user_context( self, user_id: impl Into<String>, tenant_id: impl Into<String>, ) -> Self

Set user context for multi-tenant audit enrichment. When set, all AuditRecord entries include the user and tenant IDs.

Source

pub fn audit_delegation_chain(self, chain: Vec<String>) -> Self

Set the delegation chain for audit records.

Populated when the daemon acts on behalf of a user via RFC 8693 token exchange. The chain records which agent(s) are in the delegation path.

Source

pub fn response_cache_size(self, size: usize) -> Self

Enable an LRU response cache with the given maximum number of entries. Identical requests (same system prompt, messages, and tool names) return cached responses without calling the LLM. Only non-streaming calls are cached. Size must be at least 1.

Source

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

Set the agent’s workspace directory. When set, file tools resolve relative paths against this directory, BashTool starts here, and a workspace hint is appended to the system prompt.

Source

pub fn tenant_tracker(self, tracker: Arc<TenantTokenTracker>) -> Self

Optional per-tenant in-flight token tracker. When set, the runner calls tracker.adjust(&scope, delta) after each LLM response, reconciling the per-tenant in_flight counter against the estimated reservation made at submit time. Has no effect when audit_tenant_id is unset.

Source

pub fn build(self) -> Result<AgentRunner<P>, Error>

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> 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: 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: 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> 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<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