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>
impl<P: LlmProvider> AgentRunnerBuilder<P>
pub fn name(self, name: impl Into<String>) -> Self
pub fn system_prompt(self, prompt: impl Into<String>) -> Self
pub fn tool(self, tool: Arc<dyn Tool>) -> Self
Sourcepub fn tools(self, tools: Vec<Arc<dyn Tool>>) -> Self
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.
pub fn max_turns(self, max_turns: usize) -> Self
pub fn max_tokens(self, max_tokens: u32) -> Self
pub fn context_strategy(self, strategy: ContextStrategy) -> Self
Sourcepub fn summarize_threshold(self, threshold: u32) -> Self
pub fn summarize_threshold(self, threshold: u32) -> Self
Set the token threshold at which to trigger automatic summarization.
Sourcepub fn memory(self, memory: Arc<dyn Memory>) -> Self
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.
Sourcepub fn knowledge(self, kb: Arc<dyn KnowledgeBase>) -> Self
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.
Sourcepub fn on_text(self, callback: Arc<OnText>) -> Self
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.
Sourcepub fn on_approval(self, callback: Arc<OnApproval>) -> Self
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.
Sourcepub fn tool_timeout(self, timeout: Duration) -> Self
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).
Sourcepub fn max_tool_output_bytes(self, max: usize) -> Self
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).
Sourcepub fn structured_schema(self, schema: Value) -> Self
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.
Sourcepub fn on_event(self, callback: Arc<OnEvent>) -> Self
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.
Sourcepub fn guardrail(self, guardrail: Arc<dyn Guardrail>) -> Self
pub fn guardrail(self, guardrail: Arc<dyn Guardrail>) -> Self
Add a single guardrail. Multiple guardrails are evaluated in order;
first Deny wins.
Sourcepub fn guardrails(self, guardrails: Vec<Arc<dyn Guardrail>>) -> Self
pub fn guardrails(self, guardrails: Vec<Arc<dyn Guardrail>>) -> Self
Add multiple guardrails at once.
Sourcepub fn on_question(self, callback: Arc<OnQuestion>) -> Self
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.
Sourcepub fn on_input(self, callback: Arc<OnInput>) -> Self
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.
Sourcepub fn run_timeout(self, timeout: Duration) -> Self
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).
Sourcepub fn reasoning_effort(self, effort: ReasoningEffort) -> Self
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).
pub fn enable_reflection(self, enabled: bool) -> Self
pub fn tool_output_compression_threshold(self, threshold: usize) -> Self
pub fn max_tools_per_turn(self, max: usize) -> Self
Sourcepub fn tool_profile(self, profile: ToolProfile) -> Self
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.
Sourcepub fn max_identical_tool_calls(self, max: u32) -> Self
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).
Sourcepub fn max_fuzzy_identical_tool_calls(self, max: u32) -> Self
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).
Sourcepub fn max_tool_calls_per_turn(self, cap: u32) -> Self
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.
Sourcepub fn permission_rules(self, rules: PermissionRuleset) -> Self
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.
Sourcepub fn learned_permissions(
self,
learned: Arc<Mutex<LearnedPermissions>>,
) -> Self
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.
Sourcepub fn lsp_manager(self, manager: Arc<LspManager>) -> Self
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.
Sourcepub fn session_prune_config(self, config: SessionPruneConfig) -> Self
pub fn session_prune_config(self, config: SessionPruneConfig) -> Self
Enable session pruning to reduce token usage by truncating old tool results.
Sourcepub fn enable_recursive_summarization(self, enable: bool) -> Self
pub fn enable_recursive_summarization(self, enable: bool) -> Self
Enable recursive (cluster-then-summarize) summarization for long conversations.
Sourcepub fn reflection_threshold(self, threshold: u32) -> Self
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.
Sourcepub fn consolidate_on_exit(self, enable: bool) -> Self
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).
Sourcepub fn observability_mode(self, mode: ObservabilityMode) -> Self
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).
Sourcepub fn instruction_text(self, text: impl Into<String>) -> Self
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.
Sourcepub fn max_total_tokens(self, max: u64) -> Self
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).
Sourcepub fn audit_mode(self, mode: AuditMode) -> Self
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].
Sourcepub fn audit_trail(self, trail: Arc<dyn AuditTrail>) -> Self
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.
Sourcepub fn audit_user_context(
self,
user_id: impl Into<String>,
tenant_id: impl Into<String>,
) -> Self
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.
Sourcepub fn audit_delegation_chain(self, chain: Vec<String>) -> Self
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.
Sourcepub fn response_cache_size(self, size: usize) -> Self
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.
Sourcepub fn workspace(self, path: impl Into<PathBuf>) -> Self
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.
Sourcepub fn tenant_tracker(self, tracker: Arc<TenantTokenTracker>) -> Self
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.