Skip to main content

tandem_types/
session.rs

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 project_id: Option<String>,
77    pub model: Option<ModelSpec>,
78    pub provider: Option<String>,
79    pub permission: Option<Vec<serde_json::Value>>,
80}
81
82#[derive(Debug, Clone, Serialize, Deserialize)]
83pub struct SendMessageRequest {
84    #[serde(default)]
85    pub parts: Vec<crate::MessagePartInput>,
86    pub model: Option<ModelSpec>,
87    pub agent: Option<String>,
88    #[serde(default, alias = "toolMode", alias = "tool_mode")]
89    pub tool_mode: Option<ToolMode>,
90    #[serde(default, alias = "toolAllowlist", alias = "tool_allowlist")]
91    pub tool_allowlist: Option<Vec<String>>,
92    #[serde(default, alias = "contextMode", alias = "context_mode")]
93    pub context_mode: Option<ContextMode>,
94    #[serde(default, alias = "writeRequired", alias = "write_required")]
95    pub write_required: Option<bool>,
96    #[serde(
97        default,
98        alias = "prewriteRequirements",
99        alias = "prewrite_requirements"
100    )]
101    pub prewrite_requirements: Option<PrewriteRequirements>,
102}
103
104#[derive(Debug, Clone, Serialize, Deserialize, Default)]
105pub struct PrewriteRequirements {
106    #[serde(
107        default,
108        alias = "workspaceInspectionRequired",
109        alias = "workspace_inspection_required"
110    )]
111    pub workspace_inspection_required: bool,
112    #[serde(
113        default,
114        alias = "webResearchRequired",
115        alias = "web_research_required"
116    )]
117    pub web_research_required: bool,
118    #[serde(
119        default,
120        alias = "concreteReadRequired",
121        alias = "concrete_read_required"
122    )]
123    pub concrete_read_required: bool,
124    #[serde(
125        default,
126        alias = "successfulWebResearchRequired",
127        alias = "successful_web_research_required"
128    )]
129    pub successful_web_research_required: bool,
130    #[serde(
131        default,
132        alias = "repairOnUnmetRequirements",
133        alias = "repair_on_unmet_requirements"
134    )]
135    pub repair_on_unmet_requirements: bool,
136    #[serde(default, alias = "coverageMode", alias = "coverage_mode")]
137    pub coverage_mode: PrewriteCoverageMode,
138}
139
140#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
141#[serde(rename_all = "snake_case")]
142pub enum PrewriteCoverageMode {
143    #[default]
144    None,
145    FilesReviewedBacked,
146    ResearchCorpus,
147}
148
149#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
150#[serde(rename_all = "snake_case")]
151pub enum ToolMode {
152    Auto,
153    None,
154    Required,
155}
156
157#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
158#[serde(rename_all = "snake_case")]
159pub enum ContextMode {
160    Auto,
161    Compact,
162    Full,
163}
164
165#[derive(Debug, Clone, Serialize, Deserialize)]
166pub struct TodoItem {
167    pub id: String,
168    pub content: String,
169    pub status: String,
170}