Skip to main content

ToolContext

Struct ToolContext 

Source
#[non_exhaustive]
pub struct ToolContext<'a> {
Show 14 fields pub cwd: &'a Path, pub cancel: CancellationToken, pub fs: Arc<dyn FsBackend>, pub shell: Arc<dyn ShellBackend>, pub http: Arc<dyn HttpClient>, pub current_model: &'a str, pub current_provider: &'a str, pub background: Option<BackgroundTasks>, pub subagent_bridge: Option<SubagentBridge>, pub policy: Option<Arc<dyn SandboxPolicy>>, pub goal: Option<Arc<GoalState>>, pub subagent_depth: u32, pub session_tools: Option<Arc<dyn ToolRegistry>>, pub parent_turn_config: Option<Arc<TurnConfig>>,
}
Expand description

The execution environment injected into Tool::execute.

An explicit struct rather than environment variables or thread-locals, making it easy to construct in tests and avoiding implicit global state. Fields are marked non_exhaustive to allow future additions (sandbox handles, ACP backchannels, etc.) without breaking existing implementations.

Fields (Non-exhaustive)§

This struct is marked as non-exhaustive
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.
§cwd: &'a Path

The default working directory for the tool (typically the ACP session’s cwd).

§cancel: CancellationToken

Cancellation token: triggered by upstream session/cancel, user Ctrl+C, timeout, etc. Tool implementations should check cancel.is_cancelled() at long loops or await points and exit as soon as possible.

§fs: Arc<dyn FsBackend>

Filesystem backend. The fs tool family (read_file / write_file / edit_file) reads and writes files through it. During assembly, defect-acp selects either LocalFsBackend or AcpFsBackend based on the client-negotiated FileSystemCapabilities; tool implementations are completely unaware of this.

Uses Arc instead of a borrow: Tool::execute returns a 'static future / stream, and tools typically clone the fs into async tasks. A borrow cannot survive across .await.

§shell: Arc<dyn ShellBackend>

Shell execution backend. The bash tool uses it to create a terminal and run commands; during assembly, defect-acp selects either LocalShellBackend or AcpShellBackend based on the client-negotiated ClientCapabilities::terminal, and tool implementations are unaware of the choice.

Same Arc trade-off as fsTool::execute returns a 'static future.

§http: Arc<dyn HttpClient>

HTTP fetch backend. The fetch tool uses it to perform network reads; it is set up at the CLI entry point (constructed from HttpClientConfig as a process-level HttpClient instance and reused). Tool implementations receive an Arc clone; Tool::execute is a 'static future, so borrowing cannot survive across await points.

§current_model: &'a str

The model id selected for the current turn. Most tools do not need this; the spawn_agent sub-agent tool uses it to “fall back the model to the parent session’s current selection” — ToolContext does not carry a provider registry, but carrying this string is enough for spawn_agent to call entry_for_model on its own captured registry to resolve the provider the parent is currently using. Populated from config.model by TurnRunner when constructing the context.

§current_provider: &'a str

The provider vendor selected for the current turn. Together with Self::current_model this forms a (vendor, model) selection pair — when a spawn_agent sub-agent falls back to the parent’s choice, it uses this pair to call entry_for on the registry for exact resolution (avoiding provider mis-selection when multiple gateways serve the same model name). An empty string means the value was not injected (legacy/test paths); in that case spawn_agent falls back to looking up the first entry by bare model id. Populated by the turn runner from config.provider when constructing the context.

§background: Option<BackgroundTasks>

Session-level background task handle. When Some, tools can fire-and-forget a task that outlives the current turn (primarily for spawn_agent { run_in_background: true }); None means the context does not support background execution (e.g., nested sub-agent turns or tests), and tools should fall back to synchronous execution.

Uses an owned Arc-backed handle instead of a borrow: Tool::execute returns a 'static future, and a borrow cannot survive across await. Injected by the top-level TurnRunner when constructing the context; not injected for nested sub-agent turns (structurally prevents background tasks from spawning themselves).

§subagent_bridge: Option<SubagentBridge>

Subagent event bridge: when Some, a tool can wrap internally spawned sub-turn events as crate::event::AgentEvent::Subagent and forward them back to the parent session’s event stream for nested observability display. Currently only used by spawn_agent. Injected by the turn runner in session::turn for each tool according to its ToolCallIdinjected for both top-level and nested sub-agent turns (recursive bridging), with the mount point expressed by SubagentBridge::parent_tool_call_id.

§policy: Option<Arc<dyn SandboxPolicy>>

The active sandbox policy for this turn snapshot. spawn_agent uses it to pass the parent’s current real policy to child agents — after a session/set_mode switch, newly created turns propagate the new policy through this field, so child agents never see a stale process-level default. When None, spawn_agent falls back to the policy captured at construction time (testing / uninjected scenarios). Most tools ignore this field.

§goal: Option<Arc<GoalState>>

Shared state for the --goal goal-driven loop. When Some, this session runs in goal mode; the goal_done tool calls crate::session::GoalState::mark_reached to set the flag, and the goal-gate hook uses it to decide whether to release or extend a turn when it voluntarily stops. None means non-goal mode (the default); the goal_done tool is not registered and this field is never read.

§subagent_depth: u32

How many more layers of subagent can be dispatched from the current layer. The top-level turn starts at the configured initial limit; spawn_agent decrements it by one when injecting a nested turn for a child agent. 0 means the child agent cannot obtain the spawn_agent tool (depth exhausted, structurally preventing further recursion) — replacing the old hard-coded “whitelist never contains spawn_agent”. This is a functional gate, unrelated to observability, so it is independent of the optional Self::subagent_bridge and also takes effect in test / no-bridge scenarios. Defaults to 0 (most conservative: no explicit injection means no dispatch; the top-level turn must explicitly use Self::with_subagent_depth).

§session_tools: Option<Arc<dyn ToolRegistry>>

The current session’s fully assembled tool pool — the CompositeRegistry that already merged built-in tools with the per-session MCP tools. spawn_agent uses this (rather than a static, MCP-free tool set captured at construction) to build a child agent’s tool subset, so a subagent profile may allow mcp__* tools. None in legacy / test paths, where spawn_agent falls back to its captured static pool. Injected by the TurnRunner when constructing the context.

§parent_turn_config: Option<Arc<TurnConfig>>

The current turn’s TurnConfig. spawn_agent uses it so a child agent inherits the parent’s turn settings (compaction thresholds, retry/concurrency limits, sampling incl. reasoning_effort, request-limit default) instead of silently falling back to TurnConfig::default(). A profile may still override individual fields. None in legacy / test paths, where spawn_agent uses defaults. Injected by the TurnRunner.

Implementations§

Source§

impl<'a> ToolContext<'a>

Source

pub fn new( cwd: &'a Path, cancel: CancellationToken, fs: Arc<dyn FsBackend>, shell: Arc<dyn ShellBackend>, http: Arc<dyn HttpClient>, current_model: &'a str, ) -> Self

Constructs a minimal ToolContext. The #[non_exhaustive] attribute prevents external crates from constructing the struct directly with a literal — this constructor is the only cross-crate entry point. When adding new fields, add default values to the signature or provide a new constructor to avoid breaking existing call sites.

Source

pub fn with_parent_turn_config(self, config: Arc<TurnConfig>) -> Self

Inject the current turn’s TurnConfig so spawn_agent can build a child config that inherits the parent’s turn settings. If not called, spawn_agent falls back to TurnConfig::default() for non-explicit fields.

Source

pub fn with_session_tools(self, tools: Arc<dyn ToolRegistry>) -> Self

Inject the current session’s fully assembled tool pool (built-in + MCP composite). spawn_agent uses it to build a child agent’s tool subset so subagent profiles can allow mcp__* tools. If not called, session_tools is None and spawn_agent falls back to the static pool captured at construction.

Source

pub fn with_current_provider(self, vendor: &'a str) -> Self

Inject the provider vendor selected for the current turn, forming a selection pair with current_model. If not called, defaults to an empty string (spawn_agent falls back to picking the first entry by bare model id).

Source

pub fn with_subagent_depth(self, depth: u32) -> Self

Inject the remaining subagent dispatch depth from this layer onward. The tool driver for the top-level turn calls with the configured initial cap; spawn_agent injects the decremented value for nested child-agent turns. If not called, defaults to 0 (most conservative: no subagent dispatch allowed).

Source

pub fn with_policy(self, policy: Arc<dyn SandboxPolicy>) -> Self

Inject the active sandbox policy for this turn snapshot. The top-level turn’s tool driver uses this to pass the parent turn’s policy to spawn_agent; if not called, policy is None (child agent nesting / testing), and spawn_agent falls back to the policy captured at construction time.

Source

pub fn with_background(self, background: BackgroundTasks) -> Self

Inject a session-level background task handle. The top-level turn’s tool driver uses this to enable run_in_background; if not called, background is None (the default for sub-agents / tests), and tools fall back to synchronous execution.

Source

pub fn with_goal(self, goal: Arc<GoalState>) -> Self

Inject shared state for the --goal goal-driven loop. The goal_done tool sets reached based on this state; if not called, goal is None (non-goal mode, the default).

Source

pub fn with_subagent_bridge(self, bridge: SubagentBridge) -> Self

Inject a subagent event bridge. The tool driver injects one per tool call in session::turn, keyed by ToolCallId, so that spawn_agent can nest child turn events back into the parent trace.

Auto Trait Implementations§

§

impl<'a> !RefUnwindSafe for ToolContext<'a>

§

impl<'a> !UnwindSafe for ToolContext<'a>

§

impl<'a> Freeze for ToolContext<'a>

§

impl<'a> Send for ToolContext<'a>

§

impl<'a> Sync for ToolContext<'a>

§

impl<'a> Unpin for ToolContext<'a>

§

impl<'a> UnsafeUnpin for ToolContext<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoMaybeUndefined<T> for T

Source§

impl<T> IntoOption<T> for T

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more