1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use uuid::Uuid;
4
5use crate::{HostRuntimeContext, Message, ModelSpec};
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct SessionTime {
9 pub created: DateTime<Utc>,
10 pub updated: DateTime<Utc>,
11}
12
13#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct Session {
15 pub id: String,
16 pub slug: Option<String>,
17 pub version: Option<String>,
18 pub project_id: Option<String>,
19 pub title: String,
20 pub directory: String,
21 #[serde(default, skip_serializing_if = "Option::is_none")]
22 pub workspace_root: Option<String>,
23 #[serde(default, skip_serializing_if = "Option::is_none")]
24 pub origin_workspace_root: Option<String>,
25 #[serde(default, skip_serializing_if = "Option::is_none")]
26 pub attached_from_workspace: Option<String>,
27 #[serde(default, skip_serializing_if = "Option::is_none")]
28 pub attached_to_workspace: Option<String>,
29 #[serde(default, skip_serializing_if = "Option::is_none")]
30 pub attach_timestamp_ms: Option<u64>,
31 #[serde(default, skip_serializing_if = "Option::is_none")]
32 pub attach_reason: Option<String>,
33 pub time: SessionTime,
34 pub model: Option<ModelSpec>,
35 pub provider: Option<String>,
36 #[serde(default, skip_serializing_if = "Option::is_none")]
37 pub environment: Option<HostRuntimeContext>,
38 #[serde(default)]
39 pub messages: Vec<Message>,
40}
41
42impl Session {
43 pub fn new(title: Option<String>, directory: Option<String>) -> Self {
44 let now = Utc::now();
45 Self {
46 id: Uuid::new_v4().to_string(),
47 slug: None,
48 version: Some("v1".to_string()),
49 project_id: None,
50 title: title.unwrap_or_else(|| "New session".to_string()),
51 directory: directory.unwrap_or_else(|| ".".to_string()),
52 workspace_root: None,
53 origin_workspace_root: None,
54 attached_from_workspace: None,
55 attached_to_workspace: None,
56 attach_timestamp_ms: None,
57 attach_reason: None,
58 time: SessionTime {
59 created: now,
60 updated: now,
61 },
62 model: None,
63 provider: None,
64 environment: None,
65 messages: Vec::new(),
66 }
67 }
68}
69
70#[derive(Debug, Clone, Serialize, Deserialize)]
71pub struct CreateSessionRequest {
72 pub parent_id: Option<String>,
73 pub title: Option<String>,
74 pub directory: Option<String>,
75 pub workspace_root: Option<String>,
76 pub model: Option<ModelSpec>,
77 pub provider: Option<String>,
78 pub permission: Option<Vec<serde_json::Value>>,
79}
80
81#[derive(Debug, Clone, Serialize, Deserialize)]
82pub struct SendMessageRequest {
83 #[serde(default)]
84 pub parts: Vec<crate::MessagePartInput>,
85 pub model: Option<ModelSpec>,
86 pub agent: Option<String>,
87}
88
89#[derive(Debug, Clone, Serialize, Deserialize)]
90pub struct TodoItem {
91 pub id: String,
92 pub content: String,
93 pub status: String,
94}