The per-turn I/O wiring half of ResolvedAgentExecution::resolve’s input:
the borrowed sinks, channels, and policy handles a path holds for the turn.
A grouped input layer (not stored state); resolve spreads it into the bundle.
The resolved model binding: which provider, model, and temperature a turn
uses. The base layer any LLM call needs; ResolvedAgentExecution composes
it. Field names mirror the engine’s former flat fields so the loop body is
unchanged after destructuring.
The resolved per-agent runtime knobs half of ResolvedAgentExecution::resolve’s
input: the values derived from the agent’s resolved config. A grouped input layer
(not stored state); resolve spreads it into the bundle.
The provider/model and resolved limits that actually served the most recent
LLM call in a tool loop. Written every dispatching iteration so the last
value is the FINAL serving route — including a per-call vision switch that
differs from the turn’s selected text route.
Config handle the live SOP driver needs to re-assemble a nested step’s agent
when the step delegates to a different agent than the one running the turn.
Execute a single turn of the agent loop: send messages, parse tool calls,
execute tools, and loop until the LLM produces a final text response.
When silent is true, suppresses stdout (for channel use).
agent_alias, when the caller has resolved one, is threaded onto the
turn’s AgentStart/AgentEnd brackets and onto the inner ToolLoop, so
every lifecycle observer event of the turn (agent_start, llm_request,
llm_response, tool_call_start, tool_call, agent_end) carries the full
(channel, agent_alias, turn_id) correlation triple that observer
consumers (Prometheus, OTel, the gateway /api/events stream) rely on for
per-agent attribution. None opts out for callers without a resolved
alias (tests, benches). turn_id follows the same pattern: Some reuses
a caller-minted id so pre-turn events (the process_message RAG
retrieval) join the bracket; None self-mints.
Whether an MCP tool name is admitted by policy (a None policy admits
everything). The risk-profile denylist always wins; the allowlist
auto-admits <server>__<tool> names so a restrictive allowlist does not
silently drop a configured server’s tools.
Estimate token count for a message history using the ~4 chars/token
heuristic plus ~4 framing tokens per message. Images are charged per
image only where preparation dispatches them: the markers lifted from
user turns and the attachments declared by the tool-result carriers of
the current user turn. Stale tool-result carriers are priced as their
bytes, and system or assistant content is priced
as text. Trim
probes estimate history suffixes that always retain the newest turn, so
the current turn’s tool-result carriers carry the same disposition in
every probe as in the full history.
Load interactive history plus the persisted breadcrumb provenance. Legacy
files without the flag are migrated by inspecting the restored history:
if the first non-system message equals the breadcrumb string, the flag is
recovered as true. v2 records carry an explicit
history_has_trim_breadcrumb (true or false) so a genuine user message
that collides with the breadcrumb text keeps its real turn-boundary role.
Legacy v1 migration is locale-independent: it checks the canonical
English breadcrumb plus the current-locale string, covering both the
stable historical value and any future translated variant. A v1 file whose
first user turn genuinely equals the breadcrumb text cannot be
distinguished from a synthetic marker on its one-time migration; after the
next persist the file becomes v2 with the (mis)classified flag, which is
the documented one-time limitation for unmarked legacy state.
Public helper for other crates (e.g. channels orchestrator) to load
peripheral tools through the registered factory. Returns empty vec
when nothing is registered (hardware feature off or not yet wired).
Build the MCP tool-access policy for an agent from its SecurityPolicy
(allowed_tools + excluded_tools) and an optional caller-supplied
allowlist. Shared by the runtime agent loop and the channels orchestrator
so every MCP registration site gates through identical logic.
Process a single message through the full agent (with tools, peripherals, memory).
Used by channels (Telegram, Discord, etc.) to enable hardware and tool use.
Process a message with a lease admitted by the caller. Detached producers
use this form so the original admission remains owned through delivery and
any caller-side persistence instead of being reacquired from a stale input.
Process a message after admitting its target through the daemon-owned
authority. The plain process-message path remains for callers without
managed lifecycle state.
Record token usage from an accepted LLM response via the task-local cost
tracker. Returns (total_tokens, cost_usd) on success, None when not
scoped or no usage.
Register an eager MCP tool wrapper into tools (and the delegate handle,
when present) only if policy admits it. Returns true when the tool was
registered, false when the policy dropped it.
Run a future with the session key in task-local storage and log attribution.
The scope wraps the entire agent turn, so all tools invoked during
the turn (including nested calls) see the same session key.
SessionsCurrentTool reads this to identify the active session.
Callback type for checking if model has been switched during tool execution.
Returns Some((model_provider, model)) if a switch was requested, None otherwise.