claude_agent/session/state/
message.rs1use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5
6use super::ids::MessageId;
7use crate::session::types::EnvironmentContext;
8use crate::types::{ContentBlock, Message, Role, TokenUsage};
9
10#[derive(Clone, Debug, Default, Serialize, Deserialize)]
11pub struct MessageMetadata {
12 pub model: Option<String>,
13 pub request_id: Option<String>,
14 pub tool_results: Option<Vec<ToolResultMeta>>,
15 pub thinking: Option<ThinkingMetadata>,
16}
17
18#[derive(Clone, Debug, Serialize, Deserialize)]
19pub struct ToolResultMeta {
20 pub tool_use_id: String,
21 pub tool_name: String,
22 pub is_error: bool,
23 pub duration_ms: Option<u64>,
24}
25
26#[derive(Clone, Debug, Serialize, Deserialize)]
27pub struct ThinkingMetadata {
28 pub level: String,
29 pub disabled: bool,
30}
31
32#[derive(Clone, Debug, Serialize, Deserialize)]
33pub struct SessionMessage {
34 pub id: MessageId,
35 pub parent_id: Option<MessageId>,
36 pub role: Role,
37 pub content: Vec<ContentBlock>,
38 #[serde(default)]
39 pub is_sidechain: bool,
40 #[serde(default)]
41 pub is_compact_summary: bool,
42 pub usage: Option<TokenUsage>,
43 pub timestamp: DateTime<Utc>,
44 #[serde(default)]
45 pub metadata: MessageMetadata,
46 #[serde(default, skip_serializing_if = "Option::is_none")]
47 pub environment: Option<EnvironmentContext>,
48}
49
50impl SessionMessage {
51 pub fn user(content: Vec<ContentBlock>) -> Self {
52 Self {
53 id: MessageId::new(),
54 parent_id: None,
55 role: Role::User,
56 content,
57 is_sidechain: false,
58 is_compact_summary: false,
59 usage: None,
60 timestamp: Utc::now(),
61 metadata: MessageMetadata::default(),
62 environment: None,
63 }
64 }
65
66 pub fn assistant(content: Vec<ContentBlock>) -> Self {
67 Self {
68 id: MessageId::new(),
69 parent_id: None,
70 role: Role::Assistant,
71 content,
72 is_sidechain: false,
73 is_compact_summary: false,
74 usage: None,
75 timestamp: Utc::now(),
76 metadata: MessageMetadata::default(),
77 environment: None,
78 }
79 }
80
81 pub fn with_parent(mut self, parent_id: MessageId) -> Self {
82 self.parent_id = Some(parent_id);
83 self
84 }
85
86 pub fn with_usage(mut self, usage: TokenUsage) -> Self {
87 self.usage = Some(usage);
88 self
89 }
90
91 pub fn as_sidechain(mut self) -> Self {
92 self.is_sidechain = true;
93 self
94 }
95
96 pub fn as_compact_summary(mut self) -> Self {
97 self.is_compact_summary = true;
98 self
99 }
100
101 pub fn with_environment(mut self, env: EnvironmentContext) -> Self {
102 self.environment = Some(env);
103 self
104 }
105
106 pub fn with_model(mut self, model: impl Into<String>) -> Self {
107 self.metadata.model = Some(model.into());
108 self
109 }
110
111 pub fn with_request_id(mut self, request_id: impl Into<String>) -> Self {
112 self.metadata.request_id = Some(request_id.into());
113 self
114 }
115
116 pub fn to_api_message(&self) -> Message {
117 Message {
118 role: self.role,
119 content: self.content.clone(),
120 }
121 }
122}