pub struct AssistantConfig {Show 16 fields
pub model: Option<String>,
pub strict_model: bool,
pub max_turns: u32,
pub tools: Vec<Value>,
pub gated_tools: Vec<String>,
pub approval_policy: Option<ApprovalPolicyFn>,
pub proactive_memory: Option<Arc<MemoryTools>>,
pub tool_memory: Option<Arc<ToolMemory>>,
pub tool_labels: Option<HashMap<String, ToolLabels>>,
pub todos: Option<Arc<Mutex<TodoList>>>,
pub value_store_previews: bool,
pub response_format: Option<ResponseFormat>,
pub context_window_override: Option<usize>,
pub refuse_unadvertised_tools: bool,
pub response_format_validator: Option<ResponseFormatValidator>,
pub delegate_budget: Option<DelegateBudget>,
}Expand description
Static configuration for a loop run.
Fields§
§model: Option<String>Model id, or None to let the router choose (pin a tool-capable model
for real tool use — the local completion path ignores tools).
strict_model: boolFail on the selected model rather than silently substituting another. Native chat enables this only for an explicit per-turn selection.
max_turns: u32Hard cap on loop turns.
tools: Vec<Value>The model-visible tool list (from GeneralExecutor::all_tool_defs()).
gated_tools: Vec<String>Tool names that require human approval before running (the standing tier
doesn’t auto-allow them, e.g. writes/shell on the local host without
--full-access). Empty when the tier auto-allows everything.
approval_policy: Option<ApprovalPolicyFn>Optional per-agent approval policy. Given a tool name + params, returns
whether to allow, require approval, or deny — the runtime enforcement of
the agent_permissions.* posture for the running agent. When set it
takes precedence over gated_tools; when None, gated_tools (the
standing-tier list) applies, so existing callers are unchanged.
proactive_memory: Option<Arc<MemoryTools>>Host-side proactive memory bank for the assistant loop. When present, CAR
runs a deterministic memory-maintenance + selective-intervention pass
before each model turn, so long-running agents do not depend on the model
remembering to call recall at the right time.
tool_memory: Option<Arc<ToolMemory>>Durable learned tool repairs. When present, the loop recalls what
recovered this kind of tool failure last time, and records what recovers
one this time — the difference between an agent that remembers and one
that gets better (see super::tool_memory).
None disables both halves. A surface that must be reproducible — the
benchmark harness above all — leaves it unset deliberately: a run whose
prompt depends on what the operator’s assistant learned last Tuesday is
not a measurement.
tool_labels: Option<HashMap<String, ToolLabels>>Information-flow tool labels used to classify whether a tool result came from outside the trust boundary (car#723).
None falls back to car_engine::builtin_tool_labels, so the
network-reaching commodity tools are always classified even when a caller
supplies nothing. Deliberately Option<_> rather than a plain map with a
Default: an empty map would silently classify everything as internal,
and a security marking that a forgotten field can switch off is not one.
Callers that load .car/tool-labels.json should pass the merged map so a
project’s own trust: untrusted declarations are honoured here too.
todos: Option<Arc<Mutex<TodoList>>>The run’s task list, rendered into a per-turn state block at the tail of
the request (Parslee-ai/car#814 items 2-3). None renders no block.
value_store_previews: boolRetain tool results for the run and put a typed bounded preview in the transcript, instead of destructively truncating (Parslee-ai/car#813).
Production call sites pass VALUE_STORE_PREVIEWS_DEFAULT, which is
false because the measured A/B did not meet #813’s fewer-model-calls
criterion. See that constant for the results and caveats.
Still a field rather than a constant read inside the loop, because the
bench needs both arms in one binary and a caller may want the old shape.
With this false the observation path is byte-for-byte what it was:
cap(), same cap, same notice.
Below OBSERVATION_CAP the two arms render identically — the flag
can only change an observation that crosses the cap. Note the flag also
gates SessionValues::resolve_refs on every tool call, so once a handle
exists a later below-cap call whose argument is a $rN reference is
rewritten on the on arm only. That is a no-op until something over the
cap has been retained; it is not the same statement as “nothing below
the cap can ever differ”.
response_format: Option<ResponseFormat>Constrain the run’s FINAL answer to JSON. Applies to the answer, not
to the work: it is NOT sent on any turn that offers tools, because a
JSON-constrained request suppresses tool use on real providers (GLM
5.3 Flash answered in one turn without a single tool call under
json_object; the same goal unconstrained ran two delegations and two
reads and got it right). The loop instead checks the final
no-tool-call answer itself and, only if it is not the requested shape,
re-asks ONCE with no tools and response_format set — see
final_text_matches_format and the repair branch. A run that offers
no tools at all has nothing to suppress and carries the format on
every turn. A final answer that already parses costs no extra call.
None is the correct default for every caller that does not consume
the answer as data. A knob that tightens the output contract, never a
toggle between implementations (CLAUDE.md rule 1a). Provider-dependent:
the Anthropic protocol rejects it up front (UnsupportedMode).
context_window_override: Option<usize>Override the context window (tokens) that bounds the running history
each turn. None uses the registry’s window for model (0 when
unknown, which disables compaction). Resolved through
resolve_context_window, which clamps a value ABOVE a known registry
window back down to it: compaction exists to stop provider-side
truncation of the original task (see compact_history_to_window), and
a window larger than the real one would recreate exactly that. A value
below the registry window is honored as-is — it only tightens.
refuse_unadvertised_tools: boolRefuse any tool call whose name is not among tools with an error
result, before approval or dispatch. Set on a delegate child so the
tool subset it was granted holds at EXECUTION, not just advertisement:
every tool is registered with the runtime, so a hallucinated call to an
ungranted one would otherwise run (the same reason run_task’s GUI
sub-agent enforces its restriction on the call, not the def).
false everywhere else, so existing callers whose advertised list is
deliberately narrower than the registry keep today’s behavior.
response_format_validator: Option<ResponseFormatValidator>Validates a parsed final answer against the caller’s JSON Schema.
Carried as a closure so car-server-core needs no schema-validation
dependency: car-cli compiles the --json-schema file with the
jsonschema crate it already has and passes Validator::is_valid
here. Without it a JsonSchema format is parse-only in the loop — and
since tool turns never carry the format on the wire, NOBODY would
enforce the schema on a tool-bearing run. Ignored for JsonObject.
delegate_budget: Option<DelegateBudget>Run-level ceiling on delegate use. None applies
DelegateBudget::default (20 delegations, 300 child turns); a call
past either limit is an error result, never a spawn. Per parent run —
children cannot delegate, so nothing nests under it.
Trait Implementations§
Auto Trait Implementations§
impl !RefUnwindSafe for AssistantConfig
impl !UnwindSafe for AssistantConfig
impl Freeze for AssistantConfig
impl Send for AssistantConfig
impl Sync for AssistantConfig
impl Unpin for AssistantConfig
impl UnsafeUnpin for AssistantConfig
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<S, T> Duplex<S> for Twhere
T: FromSample<S> + ToSample<S>,
impl<T> ErasedDestructor for Twhere
T: 'static,
Source§impl<S> FromSample<S> for S
impl<S> FromSample<S> for S
fn from_sample_(s: S) -> S
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more