pub struct ExecContext {Show 22 fields
pub token: CancellationToken,
pub background: CancellationToken,
pub notify: Option<Sender<Msg>>,
pub progress: Sender<ProgressEvent>,
pub call_id: ToolCallId,
pub turn: TurnId,
pub workdir: PathBuf,
pub config: Arc<Config>,
pub model_id: String,
pub task_id: Option<String>,
pub session_id: Option<String>,
pub message_index: Option<i64>,
pub scratchpad: Option<PathBuf>,
pub safety_mode: SafetyMode,
pub plan_file: Option<PathBuf>,
pub plan_permissions: PlanPermissions,
pub context_percent: Option<u8>,
pub intent: Option<String>,
pub classifier: Option<Arc<dyn AutoClassifier>>,
pub approval: Option<ApprovalBroker>,
pub questions: Option<QuestionBroker>,
pub tasks: Option<TaskBroker>,
}Expand description
What a ToolExecutor::execute() receives.
Fields§
§token: CancellationToken§background: CancellationTokenCtrl+B “background this” signal, parallel to token. Tools that can
detach a running child (execute_command, agent) select on it; the live
path sets it from the turn scope, tests leave it never-fired.
notify: Option<Sender<Msg>>Turn-independent channel back to the main reducer loop. Detached work
(a backgrounded subagent) reports through this after the owning turn
is gone — the per-turn progress channel dies with the turn. None
in tests and contexts that never detach.
progress: Sender<ProgressEvent>§call_id: ToolCallId§turn: TurnId§workdir: PathBuf§config: Arc<Config>Parent session’s app::Config. Needed by SubagentTool so the
child reducer uses the same Ollama host, reasoning prefs, MCP
servers, etc. Other tools don’t consult it — keeping it as a
typed field (rather than a global) means the dependency is
explicit in the signature.
model_id: StringParent session’s active model id (e.g. "anthropic/claude-opus-4-7").
Subagents inherit this so they hit the same provider.
task_id: Option<String>Durable daemon task that owns this tool call, when execution was launched through the runtime task queue.
session_id: Option<String>Conversation id of the interactive session dispatching this call —
stamped by the reducer onto Cmd::ExecuteTool so checkpoints can be
anchored to a conversation position. None on headless/daemon paths.
message_index: Option<i64>Conversation length (messages().len()) at dispatch; pairs with
session_id for checkpoint anchoring (see CheckpointOrigin).
scratchpad: Option<PathBuf>Per-session scratch directory, when the session has one materialized
(Msg::ScratchpadReady). Stamped by the reducer onto
Cmd::ExecuteTool; like background/notify it is field-set after
construction on the live path — None in tests and before the
directory is confirmed on disk.
safety_mode: SafetyModeEffective live safety mode for this call (from the session, not the
static config; floored to ReadOnly while a plan is being drafted).
The policy gate builds its PolicyEngine from this.
plan_file: Option<PathBuf>Some(path) while the session is in plan mode: the one path the
policy gate exempts from the read-only floor, and the flag the plan
carve-outs (memory writes, known-safe builds) and the task tools key
on. Defaults to None in new — the live dispatch path sets it,
like background/notify.
plan_permissions: PlanPermissionsLIVE per-category plan permission levels, threaded from the reducer
(the frozen startup config would go stale under /plan config
edits). Only consulted while plan_file is Some; defaults in new.
context_percent: Option<u8>Context-window fill at dispatch, when known (exit_plan_mode shows
it on the clear-context approval option). Defaults to None in new.
intent: Option<String>The user’s stated intent for the turn (latest user message), passed to the Auto-mode classifier so it can judge whether an action is aligned.
classifier: Option<Arc<dyn AutoClassifier>>LLM classifier for SafetyMode::Auto. Some only when the effective
mode is Auto and a provider is bound; the gate awaits it to resolve a
PolicyDecision::Classify. None ⇒ the gate fails safe (escalate).
approval: Option<ApprovalBroker>Inline-approval back-channel (interactive runs only). Some lets the
gate prompt the user and park until they answer; None (headless) falls
back to the out-of-band DB-approval flow.
questions: Option<QuestionBroker>Inline-question back-channel for ask_user_question (interactive runs
only). Some lets the tool park until the user answers; None
(headless) makes the tool proceed with best judgment instead of blocking.
tasks: Option<TaskBroker>The checklist broker for the task tools (single writer for all task
state). Present on every live path — interactive, headless, and
subagent runners each own one; None only in bare test contexts,
where the tools degrade to a graceful no-op.
Implementations§
Source§impl ExecContext
impl ExecContext
pub fn new( token: CancellationToken, progress: Sender<ProgressEvent>, call_id: ToolCallId, turn: TurnId, workdir: PathBuf, config: Arc<Config>, model_id: String, task_id: Option<String>, session_id: Option<String>, message_index: Option<i64>, safety_mode: SafetyMode, intent: Option<String>, classifier: Option<Arc<dyn AutoClassifier>>, approval: Option<ApprovalBroker>, questions: Option<QuestionBroker>, tasks: Option<TaskBroker>, ) -> Self
Sourcepub fn checkpoint_origin(&self) -> CheckpointOrigin
pub fn checkpoint_origin(&self) -> CheckpointOrigin
Checkpoint provenance for this call — every checkpoint-creating tool passes this so file snapshots anchor to the conversation position that produced them (rewind/fork surfaces them by anchor).
Trait Implementations§
Auto Trait Implementations§
impl !RefUnwindSafe for ExecContext
impl !UnwindSafe for ExecContext
impl Freeze for ExecContext
impl Send for ExecContext
impl Sync for ExecContext
impl Unpin for ExecContext
impl UnsafeUnpin for ExecContext
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> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
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