1use serde::{Deserialize, Serialize};
4
5pub use crate::storage::SessionMeta;
7
8#[derive(Debug, Deserialize)]
10#[serde(tag = "type")]
11pub enum WsInbound {
12 #[serde(rename = "send_message")]
14 SendMessage { content: String },
15 #[serde(rename = "tool_confirm")]
17 ToolConfirm {
18 action: String,
19 #[serde(default)]
20 reason: Option<String>,
21 },
22 #[serde(rename = "ask_response")]
24 AskResponse {
25 answers: std::collections::HashMap<String, String>,
27 },
28 #[serde(rename = "cancel")]
30 Cancel,
31 #[serde(rename = "sync")]
33 Sync,
34 #[serde(rename = "key_exchange")]
36 KeyExchange { client_pk: String },
37 #[serde(rename = "ping")]
39 Ping,
40 #[serde(rename = "list_sessions")]
42 ListSessions,
43 #[serde(rename = "switch_session")]
45 SwitchSession { session_id: String },
46 #[serde(rename = "new_session")]
48 NewSession,
49 #[serde(rename = "select_model")]
51 SelectModel { index: usize },
52 #[serde(rename = "select_theme")]
54 SelectTheme { index: usize },
55 #[serde(rename = "request_config")]
57 RequestConfig { tab: String },
58 #[serde(rename = "config_edit_submit")]
60 ConfigEditSubmit { value: String },
61 #[serde(rename = "config_toggle")]
63 ConfigToggle { index: usize },
64 #[serde(rename = "start_archive")]
66 StartArchive,
67 #[serde(rename = "archive_with_default")]
69 ArchiveWithDefault,
70 #[serde(rename = "archive_with_custom")]
72 ArchiveWithCustom { name: String },
73 #[serde(rename = "clear_session")]
75 ClearSession,
76 #[serde(rename = "start_archive_list")]
78 StartArchiveList,
79 #[serde(rename = "restore_archive")]
81 RestoreArchive { index: usize },
82 #[serde(rename = "delete_archive")]
84 DeleteArchive { index: usize },
85 #[serde(rename = "delete_session")]
87 DeleteSession { index: usize },
88 #[serde(rename = "agent_perm_confirm")]
90 AgentPermConfirm { approve: bool },
91 #[serde(rename = "plan_approval")]
93 PlanApproval {
94 approve: bool,
95 #[serde(default)]
96 content: Option<String>,
97 },
98 #[serde(rename = "toggle_auto_approve")]
100 ToggleAutoApprove,
101 #[serde(rename = "file_list")]
104 FileList { path: String },
105 #[serde(rename = "file_read")]
107 FileRead { path: String },
108 #[serde(rename = "file_write")]
110 FileWrite { path: String, content: String },
111 #[serde(rename = "terminal_exec")]
114 TerminalExec { command: String },
115 #[serde(rename = "terminal_interrupt")]
117 TerminalInterrupt,
118}
119
120#[derive(Debug, Clone, Serialize)]
122#[serde(tag = "type")]
123#[allow(dead_code)]
124pub enum WsOutbound {
125 #[serde(rename = "stream_chunk")]
127 StreamChunk { content: String },
128 #[serde(rename = "message")]
130 Message { role: String, content: String },
131 #[serde(rename = "tool_confirm_request")]
133 ToolConfirmRequest { tools: Vec<ToolConfirmInfo> },
134 #[serde(rename = "ask_request")]
136 AskRequest { questions: Vec<AskQuestionInfo> },
137 #[serde(rename = "tool_call")]
139 ToolCall {
140 id: String,
141 name: String,
142 arguments: String,
143 },
144 #[serde(rename = "tool_result")]
146 ToolResult {
147 id: String,
148 name: String,
149 output: String,
150 is_error: bool,
151 },
152 #[serde(rename = "status")]
154 Status { state: String },
155 #[serde(rename = "session_sync")]
157 SessionSync {
158 messages: Vec<SyncMessage>,
159 status: String,
160 model: String,
161 #[serde(default)]
162 context_tokens: usize,
163 #[serde(default)]
164 message_count: usize,
165 #[serde(default)]
166 auto_approve: bool,
167 },
168 #[serde(rename = "pong")]
170 Pong,
171 #[serde(rename = "server_hello")]
173 ServerHello { server_pk: String },
174 #[serde(rename = "key_exchange_ok")]
176 KeyExchangeOk,
177 #[serde(rename = "error")]
179 Error { message: String },
180 #[serde(rename = "session_list")]
182 SessionList { sessions: Vec<SessionMeta> },
183 #[serde(rename = "session_switched")]
185 SessionSwitched { session_id: String },
186 #[serde(rename = "model_list")]
188 ModelList {
189 models: Vec<ModelInfo>,
190 active_index: usize,
191 },
192 #[serde(rename = "theme_list")]
194 ThemeList {
195 themes: Vec<ThemeInfo>,
196 active_index: usize,
197 },
198 #[serde(rename = "config_data")]
200 ConfigData {
201 tab: String,
202 fields: Vec<ConfigField>,
203 },
204 #[serde(rename = "archive_list")]
206 ArchiveList { archives: Vec<ArchiveInfo> },
207 #[serde(rename = "agent_perm_request")]
209 AgentPermRequest {
210 agent_name: String,
211 tool_name: String,
212 arguments: String,
213 },
214 #[serde(rename = "plan_approval_request")]
216 PlanApprovalRequest {
217 agent_name: String,
218 plan_summary: String,
219 },
220 #[serde(rename = "file_list_result")]
223 FileListResult {
224 path: String,
225 entries: Vec<FileEntry>,
226 },
227 #[serde(rename = "file_read_result")]
229 FileReadResult {
230 path: String,
231 content: String,
232 #[serde(default)]
233 error: Option<String>,
234 },
235 #[serde(rename = "file_write_result")]
237 FileWriteResult {
238 path: String,
239 success: bool,
240 #[serde(default)]
241 error: Option<String>,
242 },
243 #[serde(rename = "terminal_output")]
246 TerminalOutput {
247 output: String,
248 exit_code: Option<i32>,
249 },
250}
251
252#[derive(Debug, Clone, Serialize)]
254pub struct ToolConfirmInfo {
255 pub id: String,
256 pub name: String,
257 pub arguments: String,
258 pub confirm_message: String,
259}
260
261#[derive(Debug, Clone, Serialize)]
263pub struct AskQuestionInfo {
264 pub question: String,
265 pub header: String,
266 pub options: Vec<AskOptionInfo>,
267 pub multi_select: bool,
268}
269
270#[derive(Debug, Clone, Serialize)]
272pub struct AskOptionInfo {
273 pub label: String,
274 pub description: String,
275}
276
277#[derive(Debug, Clone, Serialize)]
279pub struct SyncToolCall {
280 pub id: String,
281 pub name: String,
282 pub arguments: String,
283}
284
285#[derive(Debug, Clone, Serialize)]
287pub struct SyncMessage {
288 pub role: String,
289 #[serde(default)]
290 pub content: String,
291 #[serde(skip_serializing_if = "Option::is_none")]
292 pub tool_calls: Option<Vec<SyncToolCall>>,
293 #[serde(skip_serializing_if = "Option::is_none")]
294 pub tool_call_id: Option<String>,
295}
296
297#[derive(Debug, Clone, Serialize)]
299pub struct ModelInfo {
300 pub name: String,
301 pub model: String,
302 pub provider: String,
303 pub supports_vision: bool,
304}
305
306#[derive(Debug, Clone, Serialize)]
308pub struct ThemeInfo {
309 pub name: String,
310 pub display_name: String,
311}
312
313#[derive(Debug, Clone, Serialize)]
315pub struct ConfigField {
316 pub key: String,
317 pub label: String,
318 pub value: String,
319 pub field_type: String,
321 pub editable: bool,
322 #[serde(skip_serializing_if = "Option::is_none")]
324 pub options: Option<Vec<String>>,
325}
326
327#[derive(Debug, Clone, Serialize)]
329pub struct ArchiveInfo {
330 pub name: String,
331 pub created_at: String,
332 pub message_count: usize,
333}
334
335#[derive(Debug, Clone, Serialize)]
337pub struct FileEntry {
338 pub name: String,
339 pub is_dir: bool,
340 pub size: u64,
341 pub modified: String,
342}