use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use crate::{
config::BackendType,
ipc::{CliUsageLimitState, ScreenStatus},
session::{AdoptedFrom, PendingResponseCardState, Session, SessionStatus},
};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct ApiHealth {
pub status: String,
pub pid: u32,
pub started_at: DateTime<Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct DaemonRuntimeState {
pub pid: u32,
pub api_addr: String,
pub started_at: DateTime<Utc>,
pub log_path: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct CreateSessionRequest {
pub title: String,
pub cli_id: String,
pub cli_bin: String,
#[serde(default)]
pub cli_args: Vec<String>,
pub working_dir: String,
#[serde(default)]
pub prompt: String,
#[serde(default)]
pub backend_type: Option<BackendType>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct SessionInputRequest {
pub content: String,
#[serde(default)]
pub raw: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct FinalOutputRequest {
pub content: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct RestartSessionRequest {
#[serde(default)]
pub prompt: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct ResumeSessionRequest {
#[serde(default)]
pub prompt: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct AttemptResumeRequest {
#[serde(default)]
pub reason: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct AttemptResumeStartResponse {
pub ok: bool,
pub resume_id: String,
pub run_id: String,
pub activity_id: String,
pub attempt_id: String,
pub session_id: String,
pub original_session_id: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cli_session_id: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub web_port: Option<u16>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub write_token: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub url: Option<String>,
pub already_running: bool,
pub started_at: u64,
pub log_path: String,
pub sidecar_path: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct AttemptResumeEndResponse {
pub ok: bool,
pub resume_id: String,
pub status: String,
pub close_reason: String,
pub closed_at: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct AdoptTmuxSessionRequest {
pub title: Option<String>,
pub tmux_target: String,
pub cli_id: String,
pub cli_bin: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct AdoptCandidate {
pub tmux_target: String,
pub session_name: String,
pub pane_id: String,
pub title: String,
pub cwd: String,
pub pid: i32,
pub cols: Option<u16>,
pub rows: Option<u16>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct TerminalInfo {
pub url: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct SessionSummary {
pub session_id: String,
pub title: String,
pub status: SessionStatus,
pub chat_type: Option<String>,
pub quote_target_id: Option<String>,
pub cli_id: Option<String>,
pub cli_bin: Option<String>,
pub cli_args: Vec<String>,
pub backend_type: BackendType,
pub working_dir: Option<String>,
pub worker_pid: Option<u32>,
pub terminal_url: Option<String>,
pub created_at: DateTime<Utc>,
pub stream_card_nonce: Option<String>,
pub current_screen: Option<String>,
pub last_screen_status: Option<ScreenStatus>,
pub usage_limit: Option<CliUsageLimitState>,
pub current_image_key: Option<String>,
pub tui_prompt_card_id: Option<String>,
pub tui_prompt_options: Vec<crate::ipc::TuiPromptOption>,
pub tui_prompt_multi_select: Option<bool>,
pub tui_toggled_indices: Vec<usize>,
pub pending_response_card_id: Option<String>,
pub pending_response_card_state: Option<PendingResponseCardState>,
pub last_patched_response_card_id: Option<String>,
pub last_final_output_turn_id: Option<String>,
pub last_final_output: Option<String>,
pub adopted_from: Option<AdoptedFrom>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct BotSummary {
pub lark_app_id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
pub cli_id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub model: Option<String>,
pub allowed_users: Vec<String>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub allowed_chat_groups: Vec<String>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub oncall_chats: Vec<String>,
pub private_card: bool,
pub backend_type: BackendType,
pub active_sessions: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct SessionGroup {
pub chat_id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub title: Option<String>,
pub sessions: Vec<SessionSummary>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct DaemonOverview {
pub pid: u32,
pub started_at: DateTime<Utc>,
pub session_count: usize,
pub active_session_count: usize,
pub closed_session_count: usize,
pub bot_count: usize,
pub worker_count: usize,
pub config_path: String,
pub data_dir: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct SessionLocateInfo {
pub session_id: String,
pub terminal_url: Option<String>,
pub web_port: Option<u16>,
pub worker_pid: Option<u32>,
}
impl From<&Session> for SessionSummary {
fn from(value: &Session) -> Self {
Self {
session_id: value.session_id.clone(),
title: value.title.clone(),
status: value.status,
chat_type: value.chat_type.clone(),
quote_target_id: value.quote_target_id.clone(),
cli_id: value.cli_id.clone(),
cli_bin: value.cli_bin.clone(),
cli_args: value.cli_args.clone(),
backend_type: value.backend_type.clone(),
working_dir: value.working_dir.clone(),
worker_pid: value.worker_pid,
terminal_url: value.terminal_url.clone(),
created_at: value.created_at,
stream_card_nonce: value.stream_card_nonce.clone(),
current_screen: value.current_screen.clone(),
last_screen_status: value.last_screen_status,
usage_limit: value.usage_limit.clone(),
current_image_key: value.current_image_key.clone(),
tui_prompt_card_id: value.tui_prompt_card_id.clone(),
tui_prompt_options: value.tui_prompt_options.clone(),
tui_prompt_multi_select: value.tui_prompt_multi_select,
tui_toggled_indices: value.tui_toggled_indices.clone(),
pending_response_card_id: value.pending_response_card_id.clone(),
pending_response_card_state: value.pending_response_card_state,
last_patched_response_card_id: value.last_patched_response_card_id.clone(),
last_final_output_turn_id: value.last_final_output_turn_id.clone(),
last_final_output: value.last_final_output.clone(),
adopted_from: value.adopted_from.clone(),
}
}
}