pub struct ToolContext {Show 14 fields
pub working_dir: Arc<RwLock<PathBuf>>,
pub semantic: Arc<Mutex<SemanticSearcher>>,
pub file_history: Arc<Mutex<FileHistory>>,
pub graph: Arc<RwLock<CodeGraph>>,
pub ctx_budget_hint: Arc<AtomicUsize>,
pub read_budget_tokens: Arc<AtomicUsize>,
pub read_cache: Arc<RwLock<HashMap<ReadCacheKey, ReadCacheEntry>>>,
pub first_error_signatures: Arc<RwLock<Vec<String>>>,
pub telemetry: Arc<Telemetry>,
pub lsp: Option<Arc<LspManager>>,
pub event_tx: Option<Arc<UnboundedSender<TurnEvent>>>,
pub current_call_id: Option<String>,
pub tool_registry: Option<Arc<ToolRegistry>>,
pub file_store: Arc<RwLock<FileStore>>,
}Expand description
Holds a shared working directory that tools can read (and CdTool can write).
Fields§
§working_dir: Arc<RwLock<PathBuf>>§semantic: Arc<Mutex<SemanticSearcher>>§file_history: Arc<Mutex<FileHistory>>§graph: Arc<RwLock<CodeGraph>>§ctx_budget_hint: Arc<AtomicUsize>Remaining context tokens budget. Set by TurnRunner before each tool batch. read_file uses this to decide full content vs skeleton.
read_budget_tokens: Arc<AtomicUsize>Per-file token budget for read_file. Set by runner.rs Layer B before each
tool batch: ctx_budget / (5 * num_reads). read.rs compares file_tokens
against this to decide full vs skeleton. Defaults to ctx_budget/5 (single file).
read_cache: Arc<RwLock<HashMap<ReadCacheKey, ReadCacheEntry>>>Per-session read-file output cache. Hit is valid only when on-disk mtime still matches. Avoids redoing UTF-8 parsing + semantic skeleton generation when the model re-reads the same file — these are CPU-heavy, not just I/O.
first_error_signatures: Arc<RwLock<Vec<String>>>Top-5 most-distinctive lines captured from the first failed bash call this session. Used for effect-based “error resolved” detection (P0 #5): when a later bash succeeds and ≥3 of these 5 lines no longer appear, the framework appends a hint nudging the model to summarize + stop.
Why 5 lines with a majority threshold instead of 1 line (initial
design from 2026-04-22 morning): cargo / npm / pytest output
interleaves real diagnostics with ambient status (Blocking waiting for file lock, Checking crate v0.1.0). A single-line signature
routinely caught a status line that appears on success too, so the
nudge never fired. Multi-line + majority absent is robust to noise
overlap without per-tool pattern matching.
Stays set once captured — “original failure” anchor, not rolling.
telemetry: Arc<Telemetry>Shared telemetry handle. Always present (possibly in disabled state).
lsp: Option<Arc<LspManager>>Shared LSP manager for diagnostics tool. None when LSP is disabled.
event_tx: Option<Arc<UnboundedSender<TurnEvent>>>Optional event sender for real-time tool output streaming (e.g., bash stdout). When set, tools like bash can send output chunks as they’re produced.
current_call_id: Option<String>Current tool call ID for event correlation.
tool_registry: Option<Arc<ToolRegistry>>Shared registry handle for tools that dispatch fork sub-agents
(currently only parallel_edit_files). Set by AgentLoop::new
after the registry is wrapped in Arc. Reading the registry via
ctx instead of holding it in the tool struct avoids creating a
Tool ↔ Registry Arc cycle that would otherwise leak memory
for the lifetime of the process. None in headless / test
contexts that don’t need fork dispatch.
file_store: Arc<RwLock<FileStore>>D3 file content store. read_file pushes large file content here transparently and consults it on subsequent reads of any range — disk hit only on first read or after edit. Conversation messages carry only the rendered text (with line numbers) for the requested region. edit_file / write_file invalidate entries on success so a stale entry cannot serve outdated bytes.
Implementations§
Source§impl ToolContext
impl ToolContext
Sourcepub fn new(working_dir: PathBuf) -> Self
pub fn new(working_dir: PathBuf) -> Self
Create a ToolContext with a disabled (no-op) telemetry handle.
Prefer with_telemetry in production so real events are emitted.
pub fn with_session(working_dir: PathBuf, session_id: &str) -> Self
pub fn with_telemetry( working_dir: PathBuf, session_id: &str, telemetry: Arc<Telemetry>, ) -> Self
Sourcepub async fn isolate(&self) -> Self
pub async fn isolate(&self) -> Self
Create an isolated copy: same working directory value, independent Arc. Shares the same graph (read-only for tools) but independent working_dir.
Sourcepub async fn notify_lsp_file_changed(&self, path: &Path, content: &str)
pub async fn notify_lsp_file_changed(&self, path: &Path, content: &str)
Notify LSP that a file changed (if LSP is enabled). This is a convenience method for write/edit/search_replace tools.
Trait Implementations§
Source§impl Clone for ToolContext
impl Clone for ToolContext
Source§fn clone(&self) -> ToolContext
fn clone(&self) -> ToolContext
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl Freeze for ToolContext
impl !RefUnwindSafe for ToolContext
impl Send for ToolContext
impl Sync for ToolContext
impl Unpin for ToolContext
impl UnsafeUnpin for ToolContext
impl !UnwindSafe for ToolContext
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
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
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