1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3
4use crate::{
5 ipc::{CliUsageLimitState, ScreenStatus},
6 session::{AdoptedFrom, 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)]
44pub struct FinalOutputRequest {
45 pub content: String,
46}
47
48#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
49pub struct RestartSessionRequest {
50 #[serde(default)]
51 pub prompt: String,
52}
53
54#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
55pub struct ResumeSessionRequest {
56 #[serde(default)]
57 pub prompt: String,
58}
59
60#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
61pub struct AttemptResumeRequest {
62 #[serde(default)]
63 pub reason: Option<String>,
64}
65
66#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
67pub struct AttemptResumeStartResponse {
68 pub ok: bool,
69 pub resume_id: String,
70 pub run_id: String,
71 pub activity_id: String,
72 pub attempt_id: String,
73 pub session_id: String,
74 pub original_session_id: String,
75 #[serde(default, skip_serializing_if = "Option::is_none")]
76 pub cli_session_id: Option<String>,
77 #[serde(default, skip_serializing_if = "Option::is_none")]
78 pub web_port: Option<u16>,
79 #[serde(default, skip_serializing_if = "Option::is_none")]
80 pub write_token: Option<String>,
81 #[serde(default, skip_serializing_if = "Option::is_none")]
82 pub url: Option<String>,
83 pub already_running: bool,
84 pub started_at: u64,
85 pub log_path: String,
86 pub sidecar_path: String,
87}
88
89#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
90pub struct AttemptResumeEndResponse {
91 pub ok: bool,
92 pub resume_id: String,
93 pub status: String,
94 pub close_reason: String,
95 pub closed_at: u64,
96}
97
98#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
99pub struct TerminalInfo {
100 pub url: String,
101 #[serde(default, skip_serializing_if = "Option::is_none")]
102 pub read_only_token: Option<String>,
103 #[serde(default, skip_serializing_if = "Option::is_none")]
104 pub write_token: Option<String>,
105}
106
107#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
108pub struct SessionSummary {
109 pub session_id: String,
110 pub title: String,
111 pub status: SessionStatus,
112 pub chat_type: Option<String>,
113 pub quote_target_id: Option<String>,
114 pub cli_id: Option<String>,
115 pub cli_bin: Option<String>,
116 pub cli_args: Vec<String>,
117 pub working_dir: Option<String>,
118 pub worker_pid: Option<u32>,
119 pub terminal_url: Option<String>,
120 #[serde(default, skip_serializing_if = "Option::is_none")]
121 pub read_only_token: Option<String>,
122 #[serde(default, skip_serializing_if = "Option::is_none")]
123 pub write_token: Option<String>,
124 pub created_at: DateTime<Utc>,
125 pub stream_card_nonce: Option<String>,
126 pub current_screen: Option<String>,
127 pub last_screen_status: Option<ScreenStatus>,
128 pub usage_limit: Option<CliUsageLimitState>,
129 pub current_image_key: Option<String>,
130 pub tui_prompt_card_id: Option<String>,
131 pub tui_prompt_options: Vec<crate::ipc::TuiPromptOption>,
132 pub tui_prompt_multi_select: Option<bool>,
133 pub tui_toggled_indices: Vec<usize>,
134 pub pending_response_card_id: Option<String>,
135 pub pending_response_card_state: Option<PendingResponseCardState>,
136 pub last_patched_response_card_id: Option<String>,
137 pub last_final_output_turn_id: Option<String>,
138 pub last_final_output: Option<String>,
139 pub adopted_from: Option<AdoptedFrom>,
140}
141
142#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
143pub struct BotSummary {
144 pub lark_app_id: String,
145 #[serde(skip_serializing_if = "Option::is_none")]
146 pub name: Option<String>,
147 pub cli_id: String,
148 #[serde(skip_serializing_if = "Option::is_none")]
149 pub model: Option<String>,
150 pub allowed_users: Vec<String>,
151 #[serde(skip_serializing_if = "Vec::is_empty")]
152 pub allowed_chat_groups: Vec<String>,
153 #[serde(skip_serializing_if = "Vec::is_empty")]
154 pub oncall_chats: Vec<String>,
155 pub private_card: bool,
156 pub active_sessions: usize,
157}
158
159#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
160pub struct SessionGroup {
161 pub chat_id: String,
162 #[serde(skip_serializing_if = "Option::is_none")]
163 pub title: Option<String>,
164 pub sessions: Vec<SessionSummary>,
165}
166
167#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
168pub struct DaemonOverview {
169 pub pid: u32,
170 pub started_at: DateTime<Utc>,
171 pub session_count: usize,
172 pub active_session_count: usize,
173 pub closed_session_count: usize,
174 pub bot_count: usize,
175 pub worker_count: usize,
176 pub config_path: String,
177 pub data_dir: String,
178}
179
180#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
181pub struct SessionLocateInfo {
182 pub session_id: String,
183 pub terminal_url: Option<String>,
184 pub worker_pid: Option<u32>,
185}
186
187impl From<&Session> for SessionSummary {
188 fn from(value: &Session) -> Self {
189 Self {
190 session_id: value.session_id.clone(),
191 title: value.title.clone(),
192 status: value.status,
193 chat_type: value.chat_type.clone(),
194 quote_target_id: value.quote_target_id.clone(),
195 cli_id: value.cli_id.clone(),
196 cli_bin: value.cli_bin.clone(),
197 cli_args: value.cli_args.clone(),
198 working_dir: value.working_dir.clone(),
199 worker_pid: value.worker_pid,
200 terminal_url: value.terminal_url.clone(),
201 read_only_token: None,
202 write_token: None,
203 created_at: value.created_at,
204 stream_card_nonce: value.stream_card_nonce.clone(),
205 current_screen: value.current_screen.clone(),
206 last_screen_status: value.last_screen_status,
207 usage_limit: value.usage_limit.clone(),
208 current_image_key: value.current_image_key.clone(),
209 tui_prompt_card_id: value.tui_prompt_card_id.clone(),
210 tui_prompt_options: value.tui_prompt_options.clone(),
211 tui_prompt_multi_select: value.tui_prompt_multi_select,
212 tui_toggled_indices: value.tui_toggled_indices.clone(),
213 pending_response_card_id: value.pending_response_card_id.clone(),
214 pending_response_card_state: value.pending_response_card_state,
215 last_patched_response_card_id: value.last_patched_response_card_id.clone(),
216 last_final_output_turn_id: value.last_final_output_turn_id.clone(),
217 last_final_output: value.last_final_output.clone(),
218 adopted_from: value.adopted_from.clone(),
219 }
220 }
221}