use serde::{Deserialize, Serialize};
use serde_json::Value;
use crate::types::UsageInfo;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ContentBlock {
Text { text: String },
ToolUse {
id: String,
name: String,
input: Value,
},
ToolResult {
tool_use_id: String,
content: String,
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
is_error: bool,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum SystemSubtype {
Init,
Compact,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ResultSubtype {
Success,
ErrorMaxTurns,
ErrorMaxBudgetUsd,
ErrorDuringExecution,
}
impl ResultSubtype {
pub fn is_success(self) -> bool {
matches!(self, Self::Success)
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum SdkMessage {
System {
subtype: SystemSubtype,
session_id: String,
#[serde(default, skip_serializing_if = "Value::is_null")]
data: Value,
},
Assistant {
content: Vec<ContentBlock>,
#[serde(skip_serializing_if = "Option::is_none")]
stop_reason: Option<String>,
},
User { content: Vec<ContentBlock> },
Result {
subtype: ResultSubtype,
#[serde(skip_serializing_if = "Option::is_none")]
result: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
total_cost_usd: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
usage: Option<UsageInfo>,
num_turns: u32,
session_id: String,
#[serde(skip_serializing_if = "Option::is_none")]
stop_reason: Option<String>,
},
}
impl SdkMessage {
pub fn is_terminal(&self) -> bool {
matches!(self, SdkMessage::Result { .. })
}
}