use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct MiddlewareDecisionEvidence {
pub middleware_id: String,
pub title: String,
pub phase: String,
pub effect: String,
pub decision: String,
pub reason: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct VerificationIssue {
#[serde(default)]
pub tool: String,
#[serde(default)]
pub file_path: String,
pub line: Option<i32>,
pub column: Option<i32>,
#[serde(default)]
pub message: String,
#[serde(default)]
pub repair_suggestion: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct OrchestrationObservation {
pub id: String,
#[serde(default)]
pub kind: String,
#[serde(default)]
pub subject: String,
#[serde(default)]
pub summary: String,
#[serde(default)]
pub fields: std::collections::HashMap<String, String>,
pub created_at: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct UserQuestionOption {
pub label: String,
#[serde(default)]
pub description: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct UserQuestion {
pub question: String,
#[serde(default)]
pub header: String,
pub options: Vec<UserQuestionOption>,
#[serde(default)]
pub multi_select: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct AgentRosterRow {
pub sub_session_id: String,
pub role: String,
pub status: String,
#[serde(default, skip_serializing_if = "String::is_empty")]
pub model: String,
pub tokens_in: u64,
pub tokens_out: u64,
pub cache_read: u64,
pub tool_uses: u32,
pub elapsed_ms: u64,
pub last_tools: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct SessionUsageRollup {
pub session_id: String,
pub tokens_in: u64,
pub tokens_out: u64,
pub cache_read: u64,
pub cache_creation: u64,
pub cost_usd: f64,
pub updated_at: String,
}
impl SessionUsageRollup {
pub fn from_rows(session_id: &str, rows: &[AgentRosterRow], updated_at: &str) -> Self {
let mut r = SessionUsageRollup {
session_id: session_id.to_string(),
tokens_in: 0,
tokens_out: 0,
cache_read: 0,
cache_creation: 0,
cost_usd: 0.0,
updated_at: updated_at.to_string(),
};
for a in rows {
r.tokens_in += a.tokens_in;
r.tokens_out += a.tokens_out;
r.cache_read += a.cache_read;
}
r
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum SelfReviewProposalKind {
Memory,
HarnessRule,
Workflow,
SkillTweak,
Skill,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SelfReviewProposalDraft {
pub id: String,
pub kind: SelfReviewProposalKind,
pub summary: String,
pub evidence: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ProtocolEventMeta {
pub session_id: String,
pub seq: i64,
pub created_at: String,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PriceSnapshot {
pub prompt_per_m: f64,
pub completion_per_m: f64,
pub source: String,
pub fetched_at: String,
pub hash: String,
}
fn default_route_decision_schema_version() -> u32 {
1
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum RunFailureKind {
BudgetExceeded,
OwnershipMismatch,
OriginMissing,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RunBudgetExhausted {
pub run_id: String,
pub tool_call_id: String,
pub concurrent_limit: u32,
pub concurrent_in_flight: u32,
pub cumulative_limit: u32,
pub cumulative_used: u32,
pub exceeded_kind: RunBudgetKind,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum RunBudgetKind {
Concurrent,
Cumulative,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RunOwnershipFailure {
pub caller_run_id: String,
pub target_run_id: String,
pub action: RunOwnershipAction,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum RunOwnershipAction {
MutateAgent,
CancelAgent,
ReadState,
DispatchTool,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RunOriginFailure {
pub run_id: String,
pub tool_call_id: String,
pub reason: String,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ModelRouteDecisionPayload {
pub agent_role: String,
pub model_id: String,
pub tier: String,
pub reason: String,
pub signals_digest: String,
pub price_snapshot: PriceSnapshot,
pub est_cost_usd: f64,
#[serde(default = "default_route_decision_schema_version")]
pub schema_version: u32,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "state", rename_all = "camelCase")]
pub enum ShellExitStatus {
#[serde(rename = "exited")]
Exited { code: i32 },
#[serde(rename = "signaled")]
Signaled {
#[serde(default)]
signal: Option<i32>,
},
#[serde(rename = "killedByTimeout", rename_all = "camelCase")]
KilledByTimeout { timeout_ms: u64 },
#[serde(rename = "killedByCancel")]
KilledByCancel,
#[serde(rename = "spawnFailed")]
SpawnFailed { reason: String },
}
impl ShellExitStatus {
pub fn label(&self) -> String {
match self {
Self::Exited { code } => format!("exited (code {code})"),
Self::Signaled { signal: Some(s) } => format!("signaled (signal {s})"),
Self::Signaled { signal: None } => "signaled".to_string(),
Self::KilledByTimeout { timeout_ms } => {
format!("killed by timeout after {timeout_ms}ms")
}
Self::KilledByCancel => "killed by cancel".to_string(),
Self::SpawnFailed { reason } => format!("spawn failed: {reason}"),
}
}
}