1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3
4use crate::{
5 ipc::{CliUsageLimitState, ScreenStatus},
6 session::{AdoptedFrom, AgentAttention, PendingResponseCardState, Session, SessionStatus},
7};
8
9#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
10pub struct ApiHealth {
11 pub status: String,
12 pub pid: u32,
13 pub started_at: DateTime<Utc>,
14}
15
16#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
17pub struct DaemonRuntimeState {
18 pub pid: u32,
19 pub api_addr: String,
20 pub started_at: DateTime<Utc>,
21 pub log_path: String,
22}
23
24#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
25pub struct CreateSessionRequest {
26 pub title: String,
27 pub cli_id: String,
28 pub cli_bin: String,
29 #[serde(default)]
30 pub cli_args: Vec<String>,
31 pub working_dir: String,
32 #[serde(default)]
33 pub prompt: String,
34}
35
36#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
37pub struct SessionInputRequest {
38 pub content: String,
39 #[serde(default)]
40 pub raw: bool,
41}
42
43#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
45pub struct MentionTarget {
46 pub open_id: String,
47 #[serde(default)]
48 pub name: Option<String>,
49}
50
51#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
56pub struct FinalOutputRequest {
57 pub content: String,
58
59 #[serde(default)]
62 pub mentions: Vec<MentionTarget>,
63 #[serde(default)]
65 pub mention_back: bool,
66 #[serde(default)]
68 pub no_mention: bool,
69
70 #[serde(default)]
73 pub files: Vec<String>,
74 #[serde(default)]
76 pub images: Vec<String>,
77
78 #[serde(default)]
81 pub top_level: bool,
82 #[serde(default)]
84 pub chat_id: Option<String>,
85 #[serde(default)]
87 pub into: Option<String>,
88 #[serde(default)]
90 pub quote: Option<String>,
91 #[serde(default)]
93 pub no_quote: bool,
94
95 #[serde(default)]
98 pub voice: bool,
99
100 #[serde(default)]
104 pub attention: Option<String>,
105
106 #[serde(default)]
109 pub card: bool,
110 #[serde(default)]
112 pub text: bool,
113 #[serde(default)]
115 pub anyway: bool,
116}
117
118#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
119pub struct RestartSessionRequest {
120 #[serde(default)]
121 pub prompt: String,
122}
123
124#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
125pub struct ResumeSessionRequest {
126 #[serde(default)]
127 pub prompt: String,
128}
129
130#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
131pub struct AttemptResumeRequest {
132 #[serde(default)]
133 pub reason: Option<String>,
134}
135
136#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
137pub struct AttemptResumeStartResponse {
138 pub ok: bool,
139 pub resume_id: String,
140 pub run_id: String,
141 pub activity_id: String,
142 pub attempt_id: String,
143 pub session_id: String,
144 pub original_session_id: String,
145 #[serde(default, skip_serializing_if = "Option::is_none")]
146 pub cli_session_id: Option<String>,
147 #[serde(default, skip_serializing_if = "Option::is_none")]
148 pub web_port: Option<u16>,
149 #[serde(default, skip_serializing_if = "Option::is_none")]
150 pub write_token: Option<String>,
151 #[serde(default, skip_serializing_if = "Option::is_none")]
152 pub url: Option<String>,
153 pub already_running: bool,
154 pub started_at: u64,
155 pub log_path: String,
156 pub sidecar_path: String,
157}
158
159#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
160pub struct AttemptResumeEndResponse {
161 pub ok: bool,
162 pub resume_id: String,
163 pub status: String,
164 pub close_reason: String,
165 pub closed_at: u64,
166}
167
168#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
169pub struct TerminalInfo {
170 pub url: String,
171 #[serde(default, skip_serializing_if = "Option::is_none")]
172 pub read_only_token: Option<String>,
173 #[serde(default, skip_serializing_if = "Option::is_none")]
174 pub write_token: Option<String>,
175}
176
177#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
178pub struct SessionSummary {
179 pub session_id: String,
180 pub title: String,
181 pub status: SessionStatus,
182 pub chat_type: Option<String>,
183 pub quote_target_id: Option<String>,
184 pub cli_id: Option<String>,
185 pub cli_bin: Option<String>,
186 pub cli_args: Vec<String>,
187 pub working_dir: Option<String>,
188 pub worker_pid: Option<u32>,
189 pub terminal_url: Option<String>,
190 #[serde(default, skip_serializing_if = "Option::is_none")]
191 pub read_only_token: Option<String>,
192 #[serde(default, skip_serializing_if = "Option::is_none")]
193 pub write_token: Option<String>,
194 pub created_at: DateTime<Utc>,
195 pub stream_card_nonce: Option<String>,
196 pub current_screen: Option<String>,
197 pub last_screen_status: Option<ScreenStatus>,
198 pub usage_limit: Option<CliUsageLimitState>,
199 pub current_image_key: Option<String>,
200 pub tui_prompt_card_id: Option<String>,
201 pub tui_prompt_options: Vec<crate::ipc::TuiPromptOption>,
202 pub tui_prompt_multi_select: Option<bool>,
203 pub tui_toggled_indices: Vec<usize>,
204 pub pending_response_card_id: Option<String>,
205 pub pending_response_card_state: Option<PendingResponseCardState>,
206 pub last_patched_response_card_id: Option<String>,
207 pub last_final_output_turn_id: Option<String>,
208 pub last_final_output: Option<String>,
209 pub adopted_from: Option<AdoptedFrom>,
210 #[serde(default, skip_serializing_if = "Option::is_none")]
211 pub agent_attention: Option<AgentAttention>,
212}
213
214#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
215pub struct BotSummary {
216 pub lark_app_id: String,
217 #[serde(skip_serializing_if = "Option::is_none")]
218 pub name: Option<String>,
219 pub cli_id: String,
220 #[serde(skip_serializing_if = "Option::is_none")]
221 pub model: Option<String>,
222 pub allowed_users: Vec<String>,
223 #[serde(skip_serializing_if = "Vec::is_empty")]
224 pub allowed_chat_groups: Vec<String>,
225 #[serde(skip_serializing_if = "Vec::is_empty")]
226 pub oncall_chats: Vec<String>,
227 pub private_card: bool,
228 pub active_sessions: usize,
229}
230
231#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
232pub struct SessionGroup {
233 pub chat_id: String,
234 #[serde(skip_serializing_if = "Option::is_none")]
235 pub title: Option<String>,
236 pub sessions: Vec<SessionSummary>,
237}
238
239#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
240pub struct DaemonOverview {
241 pub pid: u32,
242 pub started_at: DateTime<Utc>,
243 pub session_count: usize,
244 pub active_session_count: usize,
245 pub closed_session_count: usize,
246 pub bot_count: usize,
247 pub worker_count: usize,
248 pub config_path: String,
249 pub data_dir: String,
250}
251
252#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
253pub struct SessionLocateInfo {
254 pub session_id: String,
255 pub terminal_url: Option<String>,
256 pub worker_pid: Option<u32>,
257}
258
259impl From<&Session> for SessionSummary {
260 fn from(value: &Session) -> Self {
261 Self {
262 session_id: value.session_id.clone(),
263 title: value.title.clone(),
264 status: value.status,
265 chat_type: value.chat_type.clone(),
266 quote_target_id: value.quote_target_id.clone(),
267 cli_id: value.cli_id.clone(),
268 cli_bin: value.cli_bin.clone(),
269 cli_args: value.cli_args.clone(),
270 working_dir: value.working_dir.clone(),
271 worker_pid: value.worker_pid,
272 terminal_url: value.terminal_url.clone(),
273 read_only_token: None,
274 write_token: None,
275 created_at: value.created_at,
276 stream_card_nonce: value.stream_card_nonce.clone(),
277 current_screen: value.current_screen.clone(),
278 last_screen_status: value.last_screen_status,
279 usage_limit: value.usage_limit.clone(),
280 current_image_key: value.current_image_key.clone(),
281 tui_prompt_card_id: value.tui_prompt_card_id.clone(),
282 tui_prompt_options: value.tui_prompt_options.clone(),
283 tui_prompt_multi_select: value.tui_prompt_multi_select,
284 tui_toggled_indices: value.tui_toggled_indices.clone(),
285 pending_response_card_id: value.pending_response_card_id.clone(),
286 pending_response_card_state: value.pending_response_card_state,
287 last_patched_response_card_id: value.last_patched_response_card_id.clone(),
288 last_final_output_turn_id: value.last_final_output_turn_id.clone(),
289 last_final_output: value.last_final_output.clone(),
290 adopted_from: value.adopted_from.clone(),
291 agent_attention: value.agent_attention.clone(),
292 }
293 }
294}
295
296#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
299pub struct AttentionRequest {
300 #[serde(alias = "sessionId")]
301 pub session_id: String,
302 pub kind: String,
303 pub reason: String,
304}