1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
7#[serde(rename_all = "snake_case")]
8pub enum SessionStatus {
9 Idle,
10 Working,
11 WaitingApproval,
12 Error,
13}
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
22#[serde(rename_all = "kebab-case")]
23pub enum SessionMode {
24 Interactive,
25 #[serde(alias = "auto-allow")]
28 Guarded,
29 Autonomous,
30}
31
32impl Default for SessionMode {
33 fn default() -> Self {
34 Self::Interactive
35 }
36}
37
38#[derive(Debug, Clone, Serialize, Deserialize)]
41#[serde(rename_all = "camelCase")]
42pub struct SessionInfo {
43 pub id: String,
44 pub name: String,
45 pub workdir: String,
46 pub status: SessionStatus,
47 pub created_by: String,
48 pub created_at: String,
49 pub attached_clients: u32,
50
51 #[serde(default, skip_serializing_if = "Option::is_none")]
52 pub mode: Option<SessionMode>,
53
54 #[serde(default, skip_serializing_if = "Option::is_none")]
56 pub turns_remaining: Option<u32>,
57
58 #[serde(default, skip_serializing_if = "Option::is_none")]
59 pub pinned_files: Option<Vec<String>>,
60
61 #[serde(default, skip_serializing_if = "Option::is_none")]
62 pub agent_uri: Option<String>,
63
64 #[serde(default, skip_serializing_if = "Option::is_none")]
65 pub subagents: Option<Vec<Subagent>>,
66
67 #[serde(default, skip_serializing_if = "Option::is_none")]
68 pub usage: Option<SessionUsage>,
69
70 #[serde(default, skip_serializing_if = "Option::is_none")]
71 pub rotation: Option<RotationInfo>,
72
73 #[serde(default, skip_serializing_if = "Option::is_none")]
74 pub queued_messages: Option<u32>,
75
76 #[serde(default, skip_serializing_if = "Option::is_none")]
77 pub model: Option<String>,
78
79 #[serde(default, skip_serializing_if = "Option::is_none")]
80 pub fallback_model: Option<String>,
81
82 #[serde(default, skip_serializing_if = "Option::is_none")]
85 pub provider_id: Option<String>,
86
87 #[serde(default, skip_serializing_if = "Option::is_none")]
90 pub forked_from: Option<ForkedFrom>,
91
92 #[serde(default, skip_serializing_if = "Option::is_none")]
96 pub worktree: Option<SessionWorktree>,
97}
98
99#[derive(Debug, Clone, Serialize, Deserialize)]
103#[serde(rename_all = "camelCase")]
104pub struct ForkedFrom {
105 pub session_id: String,
106 pub name: String,
107 pub at_turn: u32,
108}
109
110#[derive(Debug, Clone, Serialize, Deserialize)]
114#[serde(rename_all = "camelCase")]
115pub struct SessionWorktree {
116 pub path: String,
117 pub branch: String,
118 pub created_by_codeoid: bool,
119}
120
121#[derive(Debug, Clone, Serialize, Deserialize)]
124#[serde(rename_all = "camelCase")]
125pub struct RotationInfo {
126 pub count: u32,
127 pub last_rotated_at: Option<i64>,
129 #[serde(default, skip_serializing_if = "Option::is_none")]
130 pub claude_code_session_id: Option<String>,
131}
132
133#[derive(Debug, Clone, Default, Serialize, Deserialize)]
135#[serde(rename_all = "camelCase")]
136pub struct SessionUsage {
137 pub input_tokens: u64,
138 pub output_tokens: u64,
139 pub cache_read_tokens: u64,
140 pub cache_creation_tokens: u64,
141 pub total_cost_usd: f64,
142 pub num_turns: u32,
143 pub duration_ms: u64,
144
145 #[serde(default, skip_serializing_if = "Option::is_none")]
146 pub recent_turns: Option<Vec<TurnUsage>>,
147
148 #[serde(default, skip_serializing_if = "Option::is_none")]
150 pub peak_input_tokens: Option<u64>,
151
152 #[serde(default, skip_serializing_if = "Option::is_none")]
154 pub last_turn_input_tokens: Option<u64>,
155
156 #[serde(default, skip_serializing_if = "Option::is_none")]
157 pub last_turn_output_tokens: Option<u64>,
158
159 #[serde(default, skip_serializing_if = "Option::is_none")]
160 pub last_turn_cost_usd: Option<f64>,
161
162 #[serde(default, skip_serializing_if = "Option::is_none")]
163 pub last_turn_cache_hit_rate: Option<f64>,
164}
165
166#[derive(Debug, Clone, Serialize, Deserialize)]
168#[serde(rename_all = "camelCase")]
169pub struct TurnUsage {
170 pub turn_number: u32,
171 pub created_at: i64,
172 pub input_tokens: u64,
173 pub output_tokens: u64,
174 pub cache_read_tokens: u64,
175 pub cache_creation_tokens: u64,
176 pub total_cost_usd: f64,
177 pub duration_ms: u64,
178
179 #[serde(default, skip_serializing_if = "Option::is_none")]
180 pub stop_reason: Option<String>,
181
182 pub total_input_tokens: u64,
183 pub billable_input_tokens: u64,
184 pub cache_hit_rate: f64,
185}
186
187#[derive(Debug, Clone, Serialize, Deserialize)]
189#[serde(rename_all = "camelCase")]
190pub struct Subagent {
191 pub agent_id: String,
192 #[serde(default, skip_serializing_if = "Option::is_none")]
193 pub wimse_uri: Option<String>,
194 pub agent_type: String,
195 pub spawned_at: i64,
196 pub active: bool,
197}