pub enum EngineEvent {
Show 26 variants
TextDelta {
text: String,
},
TextDone,
ThinkingStart,
ThinkingDelta {
text: String,
},
ThinkingDone,
ResponseStart,
ToolCallStart {
id: String,
name: String,
args: Value,
is_sub_agent: bool,
},
ToolCallResult {
id: String,
name: String,
output: String,
},
ToolOutputLine {
id: String,
line: String,
is_stderr: bool,
},
SubAgentStart {
agent_name: String,
},
TodoUpdate {
items: Vec<TodoItem>,
diff: TodoDiff,
},
BgTaskUpdate {
task_id: u32,
spawner: Option<u32>,
status: AgentStatus,
},
ApprovalRequest {
id: String,
tool_name: String,
detail: String,
preview: Option<DiffPreview>,
effect: ToolEffect,
},
AskUserRequest {
id: String,
question: String,
options: Vec<String>,
},
ActionBlocked {
tool_name: String,
detail: String,
preview: Option<DiffPreview>,
},
ContextUsage {
used: usize,
max: usize,
},
StatusUpdate {
model: String,
provider: String,
context_pct: f64,
approval_mode: String,
active_tools: usize,
},
Footer {
prompt_tokens: i64,
completion_tokens: i64,
cache_read_tokens: i64,
thinking_tokens: i64,
total_chars: usize,
elapsed_ms: u64,
rate: f64,
context: String,
},
SpinnerStart {
message: String,
},
SpinnerStop,
TurnStart {
turn_id: String,
},
TurnEnd {
turn_id: String,
reason: TurnEndReason,
},
LoopCapReached {
cap: u32,
recent_tools: Vec<String>,
},
Info {
message: String,
},
Warn {
message: String,
},
Error {
message: String,
},
}Expand description
Events emitted by the engine to the client.
The client is responsible for rendering these events appropriately for its medium (terminal, GUI, JSON stream, etc.).
Variants§
TextDelta
A chunk of streaming text from the LLM response.
TextDone
The LLM finished streaming text. Flush any buffered output.
ThinkingStart
The LLM started a thinking/reasoning block.
ThinkingDelta
A chunk of thinking/reasoning content.
ThinkingDone
The thinking/reasoning block finished.
ResponseStart
The LLM response section is starting (shown after thinking ends).
ToolCallStart
A tool call is about to be executed.
Fields
ToolCallResult
A tool call completed with output.
Fields
ToolOutputLine
A line of streaming output from a tool (currently Bash only).
Emitted as each line arrives from stdout/stderr, before ToolCallResult.
Clients can render these in real-time for a “live terminal” feel.
Fields
SubAgentStart
A sub-agent is being invoked.
TodoUpdate
A sub-agent finished.
The model called TodoWrite and the engine accepted the new
list. Emitted exactly once per accepted call (skipped when the
new list is byte-identical to the previous one — the
dedup-nudge path returns the “unchanged” message to the model
without surfacing a transition to clients).
Carries the full new list AND a server-computed diff against the previously persisted list so every client renders the same animation primitives (added / changed / removed) without having to maintain its own previous-list snapshot.
Establishes the principle from DESIGN.md § Progress Tracking: Model-Owned, History-Persisted, Engine-Surfaced — the engine
surfaces transitions, the conversation history persists the
list, the system prompt does not re-inject it.
Fields
BgTaskUpdate
A background sub-agent’s status changed.
Emitted on every transition through crate::bg_agent::AgentStatus
(Pending → Running { iter } → terminal). Drained from the
registry’s status queue inside the inference loop alongside
crate::bg_agent::BgAgentRegistry::drain_completed, so any sink
(CLI / TUI / headless / ACP) sees the same event stream without
having to poll the registry directly.
Closes the engine/UI boundary leak documented in #1076 — prior to
this variant the TUI was the only client that could see live bg
status because it shared the process and grabbed
Arc<BgAgentRegistry> straight out of KodaSession.
Fields
spawner: Option<u32>Sub-agent invocation id of the spawner, or None if the
task was launched from the top-level loop. See
crate::bg_agent::BgTaskSnapshot::spawner.
status: AgentStatusNew status. Includes Running { iter } heartbeats so
clients can render iteration progress without polling.
ApprovalRequest
The engine needs user approval before executing a tool.
The client must respond with EngineCommand::ApprovalResponse
matching the same id.
Fields
preview: Option<DiffPreview>Structured diff preview (rendered by the client).
effect: ToolEffectThe classified effect that triggered confirmation.
AskUserRequest
The model needs a clarifying answer from the user before proceeding.
The client must respond with EngineCommand::AskUserResponse
matching the same id. The answer is returned to the model as the
tool result, so inference can continue.
Fields
ActionBlocked
An action was blocked by safe mode (shown but not executed).
Fields
preview: Option<DiffPreview>Diff preview (if applicable).
ContextUsage
Context window usage updated after assembling messages.
Emitted once per inference turn so the client can display context percentage and trigger auto-compaction without reading engine-internal global state.
Fields
StatusUpdate
Progress/status update for the persistent status bar.
Fields
Inference completion footer with timing and token stats.
SpinnerStart
Spinner/progress indicator (presentational hint).
Clients may render this as a terminal spinner, a status bar update, or ignore it entirely. The ratatui TUI uses the status bar instead.
SpinnerStop
Stop the spinner (presentational hint).
See SpinnerStart — clients may ignore this.
TurnStart
An inference turn is starting.
Emitted at the beginning of inference_loop(). Clients can use this
to lock input, start timers, or update status indicators.
TurnEnd
An inference turn has ended.
Emitted when inference_loop() completes. Clients can use this to
unlock input, drain type-ahead queues, or update status.
LoopCapReached
The engine’s iteration hard cap was reached.
The client must respond with EngineCommand::LoopDecision.
Until the client responds, the inference loop is paused.
Fields
Info
Informational message (not from the LLM).
Warn
Warning message.
Error
Error message.
Trait Implementations§
Source§impl Clone for EngineEvent
impl Clone for EngineEvent
Source§fn clone(&self) -> EngineEvent
fn clone(&self) -> EngineEvent
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for EngineEvent
impl Debug for EngineEvent
Source§impl<'de> Deserialize<'de> for EngineEvent
impl<'de> Deserialize<'de> for EngineEvent
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Auto Trait Implementations§
impl Freeze for EngineEvent
impl RefUnwindSafe for EngineEvent
impl Send for EngineEvent
impl Sync for EngineEvent
impl Unpin for EngineEvent
impl UnsafeUnpin for EngineEvent
impl UnwindSafe for EngineEvent
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