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