Skip to main content

ChatCtx

Struct ChatCtx 

Source
pub struct ChatCtx<'a> {
Show 50 fields pub url: &'a str, pub model: &'a str, pub kind: BackendKind, pub api_key: Option<&'a str>, pub messages: &'a [MemMessage], pub task: &'a str, pub workspace: &'a str, pub color: bool, pub markdown: bool, pub tool_offload: bool, pub spill_store: Option<&'a dyn SpillStore>, pub compaction_store: Option<&'a dyn SpillStore>, pub scratchpad: bool, pub scratchpad_store: Option<&'a dyn ScratchpadStore>, pub code_search: Option<CodeSearch<'a>>, pub experience_store: Option<&'a dyn ExperienceStore>, pub step_ledger: Option<&'a dyn StepLedger>, pub caveats: &'a Caveats, pub max_tool_rounds: usize, pub workflow_grace_rounds: usize, pub tool_output_lines: usize, pub debug: bool, pub trace: bool, pub num_ctx: Option<u32>, pub connect_timeout_secs: u64, pub inference_timeout_secs: u64, pub mid_loop_trim_threshold: usize, pub mid_loop_trim_tokens: Option<usize>, pub max_ok_input: Option<u32>, pub build_check_cmd: Option<String>, pub safe_context: Option<u32>, pub recover_cw_400: Option<RecoverCw400>, pub note_sink: Option<&'a mut dyn NoteSink>, pub note_nudge: Option<&'a mut NoteNudge>, pub recall_source: Option<&'a dyn RecallSource>, pub memory_source: Option<&'a dyn MemorySource>, pub summarizer: Option<&'a SummarizeFn>, pub compress_state: Option<&'a mut CompressState>, pub tool_events: Option<&'a mut Vec<ToolEvent>>, pub phantom_reaches: Option<&'a mut Vec<PhantomReach>>, pub permission_gate: Option<&'a mut dyn PermissionGate>, pub on_round_usage: Option<&'a mut dyn FnMut(RoundObservation)>, pub estimate_ratio: Option<f32>, pub estimation: TokenEstimation, pub summary_input_cap_floor_chars: usize, pub exec_floor: Option<&'a Scope<String>>, pub write_ledger: Option<&'a RefCell<WriteLedger>>, pub cancel: Option<&'a AtomicBool>, pub git_tool: Option<&'a dyn GitTool>, pub crew_runner: Option<&'a dyn CrewRunner>,
}
Expand description

Everything one agentic turn needs, resolved once by the caller (the TUI resolves config + capability cache + caveats per turn and threads them in here, so the loop itself never re-reads config from disk).

Fields§

§url: &'a str§model: &'a str§kind: BackendKind

Wire protocol of the active backend (Ollama vs OpenAI-compatible).

§api_key: Option<&'a str>

Bearer token for authenticated OpenAI-compatible endpoints.

§messages: &'a [MemMessage]

Full message list already assembled by MemoryManager::build_messages.

§task: &'a str§workspace: &'a str§color: bool§markdown: bool

Render assistant Markdown as ANSI in the live stream (Step 25.4, #568). Resolved by the caller as [tui].markdown (∧ /markdown override) ∧ color. The loop only renders when this is true.

§tool_offload: bool

Offload oversized tool results to the session spill store (Step 26.3, #584). The resolved tool_offload composable feature (Step 26.1); false for headless/eval callers (bit-for-bit unchanged when off).

§spill_store: Option<&'a dyn SpillStore>

Session spill store for tool_offload (Step 26.3). None = no offload (and spill: re-reads resolve to a labelled absence). Shared &dyn (interior mutability) so it serves both the write path and memory_fetch.

§compaction_store: Option<&'a dyn SpillStore>

Session compaction store (#661 group B): the compressor stores each evicted (redacted) middle span here and names a compaction:<id> handle in the marker, so the model can losslessly recover a detail the summary dropped. SEPARATE store from spill_store (own id space). None = lossy-only compaction (headless / progressive disclosure off).

§scratchpad: bool

Inject the <state> scratchpad block + advertise the state tools (Step 26.4, #583). The resolved scratchpad feature; false for headless/eval.

§scratchpad_store: Option<&'a dyn ScratchpadStore>

Session scratchpad store (Step 26.4). None = state tools not advertised and no <state> injected. Shared &dyn (interior mutability).

§code_search: Option<CodeSearch<'a>>

Semantic searcher for the code_search tool (Step 26.5.5). None = the tool is not advertised (semantic off / no index). Bundles embedder+index.

§experience_store: Option<&'a dyn ExperienceStore>

Experiential store for the record/recall tools (Step 26.6a). None = the tools are not advertised (experiential off). Shared &dyn (interior mut).

§step_ledger: Option<&'a dyn StepLedger>

Plan ledger for the update_plan tool (Step 26.6b). None = the tool is not advertised (scheduled off). Shared &dyn (interior mut).

§caveats: &'a Caveats§max_tool_rounds: usize

Maximum tool-call rounds before forcing a final tools-disabled completion (from [tui].max_tool_rounds, default 40).

§workflow_grace_rounds: usize

Additional progress-aware rounds available after max_tool_rounds when the active workflow still has incomplete work and the recent rounds show repair evidence or concrete progress. 0 makes the normal cap hard.

§tool_output_lines: usize

Max lines of tool output shown inline (from [tui].tool_output_lines, default 20). Resolved once per turn and threaded to execute_tool so the tool loop never re-reads config from disk.

§debug: bool

Enable per-round diagnostic output. Set via NEWT_DEBUG=1 or the [tui] debug = true config key.

§trace: bool

Enable deeper backend compatibility traces. Set via NEWT_TRACE=1 or the [tui] trace = true config key.

§num_ctx: Option<u32>

Ollama options.num_ctx — caps KV-cache allocation to prevent VRAM exhaustion on large models. None → model default (often 131k). Also feeds the pre-send budget as a hard input ceiling for this turn’s requests (issue #282): Ollama silently evaluates only the window’s tail, so anything newt sends must already fit inside the num_ctx it sends it with. Ignored on the OpenAI path (no such request field).

§connect_timeout_secs: u64

TCP connect timeout. Short (5 s default) so a down endpoint fails fast rather than blocking the full inference_timeout_secs.

§inference_timeout_secs: u64

Total inference timeout. Must be long enough for the model to generate a complete response (120 s default).

§mid_loop_trim_threshold: usize

Message list size at which the agent trims the middle of the in-flight conversation to prevent context overflow mid-turn.

§mid_loop_trim_tokens: Option<usize>

Estimated-token threshold that also triggers a mid-loop trim, regardless of message count. Guards against a single huge tool result blowing past the context window in one round (from [tui].mid_loop_trim_tokens). None disables token-based trimming. See issue #223.

§max_ok_input: Option<u32>

Highest input-token count this model has accepted without a 400, from model-capabilities.json. Used as the pre-send budget gate: requests estimated to exceed it are trimmed before dispatch. None falls back to safe_context. See issue #223.

§build_check_cmd: Option<String>

Shell command run after every successful file write to give the model immediate ground-truth feedback (e.g. “cargo check -q –workspace”). None disables auto-checking. Set per-workspace in .newt/config.toml.

§safe_context: Option<u32>

Empirically derived safe context size for this model (input tokens). Used to detect likely overflow when the model returns an empty response. Sourced from model-capabilities.json via ensure_context_window. None disables overflow detection.

§recover_cw_400: Option<RecoverCw400>

Hook invoked when a dispatch fails, to recover a hard context-window 400: (error, model, today) → new input-token cap. The TUI wires its recover_context_window_400 (which parses the endpoint’s real limit and persists it to model-capabilities.json — that cache stays TUI-side with the probe module). None disables recovery: the error propagates exactly as it did when no limit could be parsed. See #223.

§note_sink: Option<&'a mut dyn NoteSink>

Model-writable note store behind the save_note tool (Step 19.3, #248). None ⇒ the tool is not advertised and the loop never writes memory (eval / headless callers unaffected). The TUI passes a sink over its session MemoryManager, so save_note and /remember share one store, one security scan, one char budget.

§note_nudge: Option<&'a mut NoteNudge>

Turn-counted memory-nudge state (NoteNudge), owned by the caller across user turns and lent to the loop per call. Consulted only when note_sink is present; None disables the nudge.

§recall_source: Option<&'a dyn RecallSource>

Read-only search over PAST conversations behind the recall tool (Step 17.5, #246). None ⇒ the tool is not advertised and the loop never searches (eval / headless callers unaffected). The TUI passes a StoreRecallSource over its session ConversationStore — workspace-fenced, current conversation excluded.

§memory_source: Option<&'a dyn MemorySource>

Read-only pull of an ADDRESSED memory item behind the memory_fetch tool (progressive-disclosure memory, Workstream A MVP, #319). None ⇒ the tool is not advertised and the loop never fetches — eval / headless / ACP callers (which pass memory_source: None) are unaffected, bit-for-bit. The TUI passes a StoreMemorySource over its session NoteStore + ConversationStore (workspace-fenced), so note: and turn: addresses resolve against the same surfaces /remember and recall use. Gated exactly like recall_source.

§summarizer: Option<&'a SummarizeFn>

Compression summarizer (Step 18.4, #247): given the redacted summary request, returns the summary text — typically one tools-disabled completion against the same backend (the TUI wires this, mirroring the Summarizing provider’s with_summarizer injection). None (eval / headless) ⇒ the compression pipeline degrades to the static “Summary generation was unavailable” marker instead of an LLM summary.

§compress_state: Option<&'a mut CompressState>

Session-scoped compression anti-thrash state (CompressState), owned by the caller across user turns and lent per call (the note_nudge pattern). None ⇒ a fresh per-turn state.

§tool_events: Option<&'a mut Vec<ToolEvent>>

Per-turn tool-event recorder (Step 17.6, #246): when present, the loop pushes one crate::ToolEvent per executed tool call — name, privacy-preserving args digest (never raw args), outcome, duration claim — at the same site that renders tool activity live. The TUI lends a fresh Vec per turn (the note_nudge pattern) and persists it into the turn’s events column. None (eval / headless) ⇒ nothing is recorded.

§phantom_reaches: Option<&'a mut Vec<PhantomReach>>

Per-turn phantom-reach recorder (#717): when present, the loop pushes one crate::PhantomReach for each phantom tool/capability reach (alias resolve, hallucination, or a real-tool empty-by-design miss). Lent fresh per turn like tool_events; persisted into the turn’s phantom_reaches. None (eval / headless) ⇒ nothing recorded.

§permission_gate: Option<&'a mut dyn PermissionGate>

Prompted ocap grants (issue #263): when present, a capability denial inside execute_tool consults the human — allow once / session allow / deny — instead of failing outright; the loop blocks like a long tool call while the prompt is pending. None (the default — every headless caller: ACP worker, newt-eval) keeps each denial exactly as before, so nothing non-interactive can ever hang on a prompt.

§on_round_usage: Option<&'a mut dyn FnMut(RoundObservation)>

Per-round capability observation hook (Phase 20, docs/design/model-self-tuning.md §2.2): the loop reports each round’s evidence — accepted prompt sizes (with the matching chars/4 estimate for calibration), persistent-empty suspected overflows, the thinking-only response quirk — at the moment of observation, so the caller can persist it even when the turn later bails or errors (the motivating failure discarded an accepted 8,734-token prompt because the only write-back lived in the TUI’s Ok-arm epilogue). None (ACP worker, eval, cowork driver) preserves today’s behavior exactly (spec §5).

§estimate_ratio: Option<f32>

Learned observed/estimated prompt-token ratio for this model (Phase 20 §2.3), applied wherever chars/4 estimates meet backend-reported token budgets — compression triggers, targets, and the tool-schema overhead. None or out-of-clamp values degrade to 1.0 (no calibration; pre-Phase-20 behavior).

§estimation: TokenEstimation

[context.estimation] token-estimation heuristic (chars-per-token), extracted from config so the loop never re-reads it — drives every chars→token estimate and the budget→chars summary-cap conversion.

§summary_input_cap_floor_chars: usize

[context] summary_input_cap_floor_chars — floor for the summarizer input cap so a tight budget never starves the summarizer of material.

§exec_floor: Option<&'a Scope<String>>

#307 named-permission-preset exec FLOOR. When a /mode preset is active its exec clamp is threaded here so the --disable-ocap / --yolo bypass in execute_tool cannot raise exec authority above the preset: an out-of-floor command falls through to the confined shell and is denied. None (no active preset, and every headless caller) leaves the bypass bit-for-bit. The floor is also already meet-ed into caveats, so the confined-shell and gate paths enforce it too; this field is the one extra place the otherwise caveats-blind bypass must consult.

§write_ledger: Option<&'a RefCell<WriteLedger>>

retry technique (R2 action arm): a turn-scoped copy-on-first-write ledger (crate::verify_gate::WriteLedger) the file-write tools record into before each write_file / edit_file, so the caller can revert exactly the files newt wrote this turn (and only those) after the gate runs. Shared via RefCell so the loop records while the caller reads. None (every headless caller, and any profile without retry) ⇒ nothing is recorded and no file is ever reverted — bit-for-bit today’s behavior.

§cancel: Option<&'a AtomicBool>

User-interrupt flag (Esc / Ctrl-C during a turn). When set mid-turn the loop abandons at its next checkpoint — the round-loop top, and the two model awaits (the non-streaming probe and the token stream) — and returns early. None (every headless / eval caller) ⇒ no interrupt path, bit-for-bit today’s behavior. The caller owns the AtomicBool, trips it from a keyboard watcher, and inspects it after the call to tell an interrupted turn from a genuinely empty reply.

§git_tool: Option<&'a dyn GitTool>

The injected embedded-git capability (PR4, #461). Some ⇒ the git tool is advertised and dispatches through it (LocalGitTool in newt-git, injected by the binary). None (every headless / eval caller, and any session not in a git repo) ⇒ the tool is never advertised — bit-for-bit today’s behavior. The trait-injection seam, not a direct dep, because newt-git depends on newt-core (circular).

§crew_runner: Option<&'a dyn CrewRunner>

The injected crew/team orchestration capability (#479). Some ⇒ the compose_roster + crew tools are advertised and dispatch through it (LocalCrewRunner in newt-cli, injected by the /team toggle). None ⇒ never advertised. Trait-injection seam like git_tool (newt-scheduler depends on newt-core, so the dep can’t be direct).

Auto Trait Implementations§

§

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

§

impl<'a> !Send for ChatCtx<'a>

§

impl<'a> !Sync for ChatCtx<'a>

§

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

§

impl<'a> Freeze for ChatCtx<'a>

§

impl<'a> Unpin for ChatCtx<'a>

§

impl<'a> UnsafeUnpin for ChatCtx<'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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> ErasedDestructor for T
where T: 'static,

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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

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

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
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<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

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