Expand description
The assistant agent loop: propose → validate → execute → observe.
One multi-turn tool-use conversation, driven by CAR inference and executed
through a Runtime (validator + policy + permission tiers + event log)
whose tool executor is the GeneralExecutor. The same loop backs the
one-shot CLI, the REPL, and — per turn — the agent.chat surface; streaming
is decoupled through a synchronous emit sink so a caller can forward events
to stdout or to agent.chat.event notifications without the loop knowing.
Structs§
- Assistant
Config - Static configuration for a loop run.
- Assistant
Model Attribution - The terminal result of a loop run.
- Assistant
Outcome - Assistant
Tool Receipt - Delegate
Budget - How much delegating one run may do, whatever each child’s own cap says.
Bounds the model-call amplification a delegating parent can cause: without
it a parent at
max_turns50 could issue 50 children of 60 turns each. - Delegate
Request - A parsed
delegatecall. - Goal
Loop Result - The result of a goal-driven assistant run: the last iteration’s
AssistantOutcomeplus theGoalRunaudit (per-iteration verdicts, grounded flag, halt reason).
Enums§
- Approval
Decision - The outcome of an approval request.
- Assistant
Event - Streamed events from one loop run.
emitis called synchronously as the loop progresses; a chat caller forwards these toagent.chat.event, a CLI caller prints them. - Assistant
Failure Cause - Map a typed generation failure to the terminal
auth_requiredreason, orNonewhen the turn keeps today’serror. - Auth
Required Reason - Why an out-of-the-box turn could not reach Parslee inference.
- Tool
Approval Decision - What the per-agent policy says to do with a tool call before it runs.
Constants§
- AUTH_
REQUIRED_ EXPIRED_ MESSAGE - The wire
messageforauth_required { reason: "expired" }(reserved — seeAuthRequiredReason::Expired). - AUTH_
REQUIRED_ NO_ WORKSPACE_ MESSAGE - The wire
messageforauth_required { reason: "no_workspace" }. - AUTH_
REQUIRED_ SIGNED_ OUT_ MESSAGE - The wire
messageforauth_required { reason: "signed_out" }. - DELEGATE_
DEFAULT_ MAX_ TURNS - Child turn budget when the call names none.
- DELEGATE_
MAX_ TURNS_ CAP - Hard ceiling on a child’s turn budget, whatever the call asks for.
- DELEGATE_
TOOL - The loop-intercepted sub-agent tool. Advertised like any other tool (so a
caller can allowlist or omit it) but never dispatched to the executor: the
loop recognizes the name and runs a child loop in-process — the same shape
as
run_task’s GUI sub-agent, chosen over aToolExecutorbecause an executor is built before theRuntimeandAssistantConfiga child needs. - FORMAT_
REPAIR_ FAILED_ PREFIX - Prefix of the notice emitted when the repair call itself failed (for
example an Anthropic-protocol model rejecting
response_format). The DRAFT answer is returned — a provider that cannot enforce the format is not a reason to throw away the answer the model already gave. - FORMAT_
REPAIR_ NOTICE - Emitted (as
AssistantEvent::Text) when the repair fires, so the run’s event stream records that the final answer was re-asked rather than taken as returned. - FORMAT_
REPAIR_ STILL_ INVALID - Emitted when the single repair also missed. The repaired text is still the answer — the contract is “one repair”, not “retry until valid”.
- OBSERVATION_
CAP - Upper bound (bytes) on a single tool observation fed back into context, so a large read/output can’t blow the request size. Truncates on a char boundary.
- VALUE_
STORE_ PREVIEWS_ DEFAULT - The shipped default for
AssistantConfig::value_store_previews— the one place any production call site reads it from, so “what does CAR do out of the box” is a single greppable fact rather than a literal repeated at the four production construction sites (car dotwice, the MCP assistant, and coder discussions), which can drift apart. The remaining hard-codedfalses in the workspace are deliberate and stay: eight test fixtures inchat.rs, this module’s own off-arm fixture, andHarnessBenchConfig, whosefalsenames the truncating arm of the A/B rather than a product setting.
Traits§
- Approval
Gate - The human-in-the-loop seam. Consulted by the loop before running a
gated_toolsaction. Implementations: a terminal stdin prompt (REPL / one-shot) or the chatapproval_pending→ park → resolve flow. When no gate is wired, a gated action is denied with an actionable message.
Functions§
- annotate_
summary_ with_ claim_ note - Append a non-authoritative claim-check note to a goal-loop reply.
- delegate_
child_ config - Derive the child’s config from the parent’s. Everything is the parent’s
(
clone()) except: - delegate_
tool_ def - Build the
delegatetool def over the parent’s advertised tools. Thetoolsparameter is a JSON-Schemaenumof the parent’s own tool names — the verifiable subset preconditioncar-multi’sspawn_subtaskuses — so the validator rejects an escalation before the loop’s own check does. - extract_
json_ payload - Strip a single surrounding
/json fence, if present. Returns the trimmed input otherwise. - final_
text_ matches_ format - Does a final answer satisfy the requested
car_inference::ResponseFormat? - parse_
delegate_ params - Parse the call’s arguments. Shape errors are the model’s to fix, so they come back as an error result rather than sinking the run.
- resolve_
context_ window - The effective context window for a run: the caller’s override, clamped to the registry window when that is known and smaller. Returns the window plus an advisory when the clamp fired, so the caller can surface it.
- run_
assistant_ goal_ loop - Drive the assistant as a goal loop: keep running iterations (each a full
run_assistant_loop_cancellablepass — the model works until it stops emitting tool calls) until a deterministiccar_verify::goal::GoalConditionholds or acar_verify::goal::GoalGovernorbound is hit. This is CAR’s answer to/goal: the “am I done?” decision is made bycar_verify::goal::evaluate_goalover ground truth gathered from the runtime (gather), never by a model reading its own transcript. - run_
assistant_ goal_ loop_ in_ session - Session-aware variant of
run_assistant_goal_loop. - run_
assistant_ goal_ loop_ in_ session_ durable - run_
assistant_ loop - Run the assistant loop to a terminal outcome, mutating
messages(which must already carry the system + first user turn) and streaming progress viaemit. Reusable across one-shot, REPL, and per-chat-turn. - run_
assistant_ loop_ cancellable - Same as
run_assistant_loop, but checkscancelbefore each turn so theagent.chat.cancelpath can interrupt a running turn between model calls, and consultsapproval(if any) before running agated_toolsaction. - run_
assistant_ loop_ cancellable_ in_ session - Session-aware variant of
run_assistant_loop_cancellable. A caller that multiplexes conversations passes the Runtime session id so stateful tool guards (notably read-before-edit) stay isolated between conversations. - run_
assistant_ loop_ cancellable_ in_ session_ durable - Durable supervised-session variant. The checkpoint sink is invoked after every mutation of the exact model-facing transcript, including compaction, assistant tool calls, refusals, and tool results.
- ungrounded_
summary_ claims - Operational claims the final prose makes that no same-run tool receipt supports — “I ran the tests” with no matching shell call, “I created X” with no matching write.
Type Aliases§
- Approval
Policy Fn - Resolves a per-agent approval decision for a tool call. Built by the caller
(chat.rs) from the loaded
AgentPermissionPolicy+ the session’s agent id + a risk classifier, so the loop stays decoupled from the policy store. - Response
Format Validator - A compiled JSON-Schema check for the final answer —
truewhen the parsed answer conforms. SeeAssistantConfig::response_format_validator.