pub struct AgentLoopConfig {Show 32 fields
pub model_config: ModelConfig,
pub provider_override: Option<Arc<dyn StreamProvider>>,
pub thinking_level: ThinkingLevel,
pub max_tokens: Option<u32>,
pub temperature: Option<f32>,
pub convert_to_llm: Option<ConvertToLlmFn>,
pub transform_context: Option<TransformContextFn>,
pub get_steering_messages: Option<GetMessagesFn>,
pub get_follow_up_messages: Option<GetMessagesFn>,
pub context_config: Option<ContextConfig>,
pub execution_limits: Option<ExecutionLimits>,
pub cache_config: CacheConfig,
pub tool_execution: ToolExecutionStrategy,
pub tool_timeout: Option<Duration>,
pub retry_config: RetryConfig,
pub before_turn: Option<BeforeTurnFn>,
pub after_turn: Option<AfterTurnFn>,
pub before_loop: Option<BeforeLoopFn>,
pub after_loop: Option<AfterLoopFn>,
pub before_tool_execution: Option<BeforeToolExecutionFn>,
pub after_tool_execution: Option<AfterToolExecutionFn>,
pub before_tool_execution_update: Option<BeforeToolExecutionUpdateFn>,
pub after_tool_execution_update: Option<AfterToolExecutionUpdateFn>,
pub on_error: Option<OnErrorFn>,
pub before_compaction_start: Option<BeforeCompactionStartFn>,
pub after_compaction_end: Option<AfterCompactionEndFn>,
pub input_filters: Vec<Arc<dyn InputFilter>>,
pub first_turn_trigger: TurnTrigger,
pub config_id: Option<String>,
pub context_translation: Option<Arc<dyn ContextTranslationStrategy>>,
pub prun_pending: Option<Arc<Mutex<Vec<PrunRequest>>>>,
pub response_format: ResponseFormat,
}Expand description
All static settings for a single [agent_loop] / [agent_loop_continue] call.
Build with the public fields directly or via [crate::agent::Agent]’s builder methods.
The config is borrowed (&AgentLoopConfig) throughout the loop — it is never mutated.
§Lifecycle hooks
All hook fields are Option<Arc<dyn Fn(...)>>. None means “no hook” (zero overhead).
See the module-level doc for the guaranteed ordering relative to AgentEvents.
Fields§
§model_config: ModelConfigComplete provider identity: model id, api_key, base_url, protocol, compat flags, cost rates.
The agent loop resolves the concrete StreamProvider from model_config.api via
ProviderRegistry. Set provider_override to bypass the registry for custom providers.
provider_override: Option<Arc<dyn StreamProvider>>Custom provider override. When Some, bypasses ProviderRegistry dispatch and uses
this provider directly. Useful for testing (MockProvider) or custom implementations.
When None (the default), the provider is resolved from model_config.api.
thinking_level: ThinkingLevel§max_tokens: Option<u32>§temperature: Option<f32>§convert_to_llm: Option<ConvertToLlmFn>Convert AgentMessage[] → Message[] before each LLM call. Default: keep only LLM-compatible messages.
transform_context: Option<TransformContextFn>Transform context before convert_to_llm (for pruning, compaction).
get_steering_messages: Option<GetMessagesFn>Get steering messages (user interruptions mid-run).
get_follow_up_messages: Option<GetMessagesFn>Get follow-up messages (queued work after agent finishes).
context_config: Option<ContextConfig>Context window configuration (auto-compaction).
Compaction strategies are now part of ContextConfig.compaction (G5 consolidation).
execution_limits: Option<ExecutionLimits>Execution limits (max turns, tokens, duration, cost).
Cost is tracked automatically using model_config.cost rates after each turn.
ExecutionLimits.max_cost enforcement is active whenever rates are non-zero.
cache_config: CacheConfigPrompt caching configuration.
tool_execution: ToolExecutionStrategyTool execution strategy (sequential, parallel, or batched).
tool_timeout: Option<Duration>Per-tool execution timeout.
When Some(d), each individual AgentTool::execute() call is bounded by d.
On expiry, the tool’s child cancel token is signalled (cooperative cleanup) and a
ToolError::Timeout is synthesised as the tool result — the LLM sees the failure
and the agent loop continues. A per-tool override via AgentTool::timeout() takes
precedence over this field. None (the default) means no per-tool timeout.
retry_config: RetryConfigRetry configuration for transient provider errors.
before_turn: Option<BeforeTurnFn>Called before each LLM turn. Return false to abort the turn.
after_turn: Option<AfterTurnFn>Called after each LLM turn with the current messages and the turn’s usage.
before_loop: Option<BeforeLoopFn>Called before each Agent loop. Return false to abort the loop.
after_loop: Option<AfterLoopFn>Called after each Agent loop with the current messages and the loop’s usage.
before_tool_execution: Option<BeforeToolExecutionFn>Called before each tool execution. Return false to skip the tool call.
after_tool_execution: Option<AfterToolExecutionFn>Called after each tool execution.
before_tool_execution_update: Option<BeforeToolExecutionUpdateFn>Called before each ToolExecutionUpdate event. Return false to suppress the event.
after_tool_execution_update: Option<AfterToolExecutionUpdateFn>Called after each ToolExecutionUpdate event.
on_error: Option<OnErrorFn>Called when the LLM returns a StopReason::Error.
before_compaction_start: Option<BeforeCompactionStartFn>Called before compaction starts. Return false to skip compaction.
after_compaction_end: Option<AfterCompactionEndFn>Called after compaction completes.
input_filters: Vec<Arc<dyn InputFilter>>Input filters applied to user messages before the LLM call.
Filters run in order; first Reject wins and discards any accumulated
warnings. Warn messages accumulate and are appended to the user message.
first_turn_trigger: TurnTriggerThe trigger type for the first TurnStart event in this run.
Defaults to TurnTrigger::User; set to SubAgent by sub-agent callers.
config_id: Option<String>Stable identity for this config, used as the middle segment of loop_id:
loop_id = "{session_id}.{config_id}.{N}"
When None and the Agent wrapper is used, the identity is auto-derived by
Agent::next_loop_id() from the provider, model, and thinking level:
"{provider_id}.{model_slug}[.thinking]"
For direct callers of agent_loop, set context.loop_id explicitly — this field
is only read by Agent::next_loop_id() and has no effect inside agent_loop itself.
Set explicitly for human-readable or deterministic loop IDs, e.g.:
config.config_id = Some("experiment-A".to_string());
→ loop IDs: ses_xyz.experiment-A.1, ses_xyz.experiment-A.2, …
context_translation: Option<Arc<dyn ContextTranslationStrategy>>G8 — Optional context translation strategy for cross-provider compatibility.
When set, messages are translated through this strategy before being sent to
the LLM provider. This allows content types from one provider (e.g.,
Content::Thinking from Anthropic) to be translated or removed when targeting
a different provider. The translation is read-only — originals are never modified.
prun_pending: Option<Arc<Mutex<Vec<PrunRequest>>>>Shared state for PrunTool to communicate pruning requests to the loop.
response_format: ResponseFormatDesired LLM output shape. Default Text preserves the historical free-form
behaviour; JsonObject / JsonSchema request constrained structured output
from providers that support it. See provider::ResponseFormat and the
capability matrix in docs/specs/developer/provider.md.