use serde_json::Value;
use crate::models::Usage;
use crate::tools::spec::{ToolError, ToolResult};
use crate::tools::subagent::SubAgentResult;
use crate::tools::user_input::UserInputRequest;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TurnOutcomeStatus {
Completed,
Interrupted,
Failed,
}
#[derive(Debug, Clone)]
pub enum Event {
MessageStarted {
#[allow(dead_code)]
index: usize,
},
MessageDelta {
#[allow(dead_code)]
index: usize,
content: String,
},
MessageComplete {
#[allow(dead_code)]
index: usize,
},
ThinkingStarted {
#[allow(dead_code)]
index: usize,
},
ThinkingDelta {
#[allow(dead_code)]
index: usize,
content: String,
},
ThinkingComplete {
#[allow(dead_code)]
index: usize,
},
ToolCallStarted {
id: String,
name: String,
input: Value,
},
#[allow(dead_code)]
ToolCallProgress { id: String, output: String },
ToolCallComplete {
id: String,
name: String,
result: Result<ToolResult, ToolError>,
},
TurnStarted { turn_id: String },
TurnComplete {
usage: Usage,
status: TurnOutcomeStatus,
error: Option<String>,
},
CompactionStarted {
id: String,
auto: bool,
message: String,
},
CompactionCompleted {
id: String,
auto: bool,
message: String,
#[allow(dead_code)]
messages_before: Option<usize>,
#[allow(dead_code)]
messages_after: Option<usize>,
},
CompactionFailed {
id: String,
auto: bool,
message: String,
},
#[allow(dead_code)]
CapacityDecision {
session_id: String,
turn_id: String,
h_hat: f64,
c_hat: f64,
slack: f64,
min_slack: f64,
violation_ratio: f64,
p_fail: f64,
risk_band: String,
action: String,
cooldown_blocked: bool,
reason: String,
},
#[allow(dead_code)]
CapacityIntervention {
session_id: String,
turn_id: String,
action: String,
before_prompt_tokens: usize,
after_prompt_tokens: usize,
compaction_size_reduction: usize,
replay_outcome: Option<String>,
replan_performed: bool,
},
#[allow(dead_code)]
CapacityMemoryPersistFailed {
session_id: String,
turn_id: String,
action: String,
error: String,
},
AgentSpawned { id: String, prompt: String },
AgentProgress { id: String, status: String },
AgentComplete { id: String, result: String },
AgentList { agents: Vec<SubAgentResult> },
Error {
message: String,
#[allow(dead_code)]
recoverable: bool,
},
Status { message: String },
PauseEvents,
ResumeEvents,
ApprovalRequired {
id: String,
tool_name: String,
description: String,
},
UserInputRequired {
id: String,
request: UserInputRequest,
},
#[allow(dead_code)]
ElevationRequired {
tool_id: String,
tool_name: String,
command: Option<String>,
denial_reason: String,
blocked_network: bool,
blocked_write: bool,
},
}
impl Event {
pub fn error(message: impl Into<String>, recoverable: bool) -> Self {
Event::Error {
message: message.into(),
recoverable,
}
}
pub fn status(message: impl Into<String>) -> Self {
Event::Status {
message: message.into(),
}
}
}