use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MessageOrigin {
#[serde(rename = "kind", skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(flatten)]
pub extra: HashMap<String, serde_json::Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct MessageBase {
#[serde(skip_serializing_if = "Option::is_none")]
pub uuid: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "parentUuid")]
pub parent_uuid: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub timestamp: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "createdAt")]
pub created_at: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "isMeta")]
pub is_meta: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "isVirtual")]
pub is_virtual: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "isCompactSummary")]
pub is_compact_summary: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "toolUseResult")]
pub tool_use_result: Option<serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub origin: Option<MessageOrigin>,
#[serde(flatten)]
pub extra: HashMap<String, serde_json::Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AttachmentMessage {
#[serde(flatten)]
pub base: MessageBase,
#[serde(rename = "type")]
pub message_type: String, #[serde(skip_serializing_if = "Option::is_none")]
pub path: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UserMessage {
#[serde(flatten)]
pub base: MessageBase,
#[serde(rename = "type")]
pub message_type: String, pub message: UserMessageContent,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UserMessageContent {
pub content: UserContent,
#[serde(flatten)]
pub extra: HashMap<String, serde_json::Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum UserContent {
Text(String),
Blocks(Vec<UserContentBlock>),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UserContentBlock {
#[serde(rename = "type")]
pub block_type: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub text: Option<String>,
#[serde(flatten)]
pub extra: HashMap<String, serde_json::Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AssistantMessage {
#[serde(flatten)]
pub base: MessageBase,
#[serde(rename = "type")]
pub message_type: String, #[serde(skip_serializing_if = "Option::is_none")]
pub message: Option<AssistantMessageContent>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AssistantMessageContent {
#[serde(skip_serializing_if = "Option::is_none")]
pub content: Option<serde_json::Value>,
#[serde(flatten)]
pub extra: HashMap<String, serde_json::Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ProgressMessage {
#[serde(flatten)]
pub base: MessageBase,
#[serde(rename = "type")]
pub message_type: String, #[serde(skip_serializing_if = "Option::is_none")]
pub progress: Option<serde_json::Value>,
}
pub type SystemMessageLevel = String;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SystemMessage {
#[serde(flatten)]
pub base: MessageBase,
#[serde(rename = "type")]
pub message_type: String, #[serde(skip_serializing_if = "Option::is_none")]
pub subtype: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub level: Option<SystemMessageLevel>,
#[serde(skip_serializing_if = "Option::is_none")]
pub message: Option<String>,
}
pub type SystemLocalCommandMessage = SystemMessage;
pub type SystemBridgeStatusMessage = SystemMessage;
pub type SystemTurnDurationMessage = SystemMessage;
pub type SystemThinkingMessage = SystemMessage;
pub type SystemMemorySavedMessage = SystemMessage;
pub type SystemStopHookSummaryMessage = SystemMessage;
pub type SystemInformationalMessage = SystemMessage;
pub type SystemCompactBoundaryMessage = SystemMessage;
pub type SystemMicrocompactBoundaryMessage = SystemMessage;
pub type SystemPermissionRetryMessage = SystemMessage;
pub type SystemScheduledTaskFireMessage = SystemMessage;
pub type SystemAwaySummaryMessage = SystemMessage;
pub type SystemAgentsKilledMessage = SystemMessage;
pub type SystemApiMetricsMessage = SystemMessage;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SystemApiErrorMessage {
#[serde(flatten)]
pub base: MessageBase,
#[serde(rename = "type")]
pub message_type: String, #[serde(skip_serializing_if = "Option::is_none")]
pub subtype: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub level: Option<SystemMessageLevel>,
#[serde(skip_serializing_if = "Option::is_none")]
pub message: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub error: Option<String>,
}
pub type SystemFileSnapshotMessage = SystemMessage;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HookResultMessage {
#[serde(flatten)]
pub base: MessageBase,
#[serde(rename = "type")]
pub message_type: String, }
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ToolUseSummaryMessage {
#[serde(flatten)]
pub base: MessageBase,
#[serde(rename = "type")]
pub message_type: String, }
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TombstoneMessage {
#[serde(flatten)]
pub base: MessageBase,
#[serde(rename = "type")]
pub message_type: String, }
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StreamEvent {
#[serde(rename = "type", skip_serializing_if = "Option::is_none")]
pub event_type: Option<String>,
#[serde(flatten)]
pub extra: HashMap<String, serde_json::Value>,
}
pub type RequestStartEvent = StreamEvent;
pub type StopHookInfo = HashMap<String, serde_json::Value>;
pub type CompactMetadata = HashMap<String, serde_json::Value>;
pub type PartialCompactDirection = String;
pub type CollapsedReadSearchGroup = HashMap<String, serde_json::Value>;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GroupedToolUseMessage {
#[serde(flatten)]
pub base: MessageBase,
#[serde(rename = "type")]
pub message_type: String, }
pub type CollapsibleMessage = MessageBase;
pub type NormalizedAssistantMessage = AssistantMessage;
pub type NormalizedUserMessage = UserMessage;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum NormalizedMessage {
#[serde(rename = "assistant")]
Assistant(AssistantMessage),
#[serde(rename = "user")]
User(UserMessage),
#[serde(rename = "progress")]
Progress(ProgressMessage),
#[serde(rename = "system")]
System(SystemMessage),
#[serde(rename = "attachment")]
Attachment(AttachmentMessage),
}
pub type RenderableMessage = Message;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum Message {
#[serde(rename = "user")]
User(UserMessage),
#[serde(rename = "assistant")]
Assistant(AssistantMessage),
#[serde(rename = "progress")]
Progress(ProgressMessage),
#[serde(rename = "system")]
System(SystemMessage),
#[serde(rename = "attachment")]
Attachment(AttachmentMessage),
#[serde(rename = "hook_result")]
HookResult(HookResultMessage),
#[serde(rename = "tool_use_summary")]
ToolUseSummary(ToolUseSummaryMessage),
#[serde(rename = "tombstone")]
Tombstone(TombstoneMessage),
#[serde(rename = "grouped_tool_use")]
GroupedToolUse(GroupedToolUseMessage),
}
pub fn create_away_summary_message(content: &str) -> Message {
Message::System(SystemMessage {
base: MessageBase {
uuid: Some(uuid::Uuid::new_v4().to_string()),
timestamp: Some(chrono::Utc::now().to_rfc3339()),
created_at: Some(chrono::Utc::now().to_rfc3339()),
is_meta: Some(false),
..Default::default()
},
message_type: "system".to_string(),
subtype: Some("away_summary".to_string()),
level: None,
message: Some(content.to_string()),
})
}