Skip to main content

stakpak_api/stakpak/
models.rs

1//! Stakpak API models for sessions and checkpoints
2//!
3//! These types match the new `/v1/sessions` API endpoints.
4
5use chrono::{DateTime, Utc};
6use serde::{Deserialize, Serialize};
7use stakpak_shared::models::integrations::openai::ChatMessage;
8use uuid::Uuid;
9
10// =============================================================================
11// Session Types
12// =============================================================================
13
14/// Session visibility
15#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
16#[serde(rename_all = "UPPERCASE")]
17pub enum SessionVisibility {
18    Private,
19    Public,
20}
21
22impl Default for SessionVisibility {
23    fn default() -> Self {
24        Self::Private
25    }
26}
27
28/// Session status
29#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
30#[serde(rename_all = "UPPERCASE")]
31pub enum SessionStatus {
32    Active,
33    Deleted,
34}
35
36impl Default for SessionStatus {
37    fn default() -> Self {
38        Self::Active
39    }
40}
41
42/// Full session with active checkpoint
43#[derive(Debug, Clone, Deserialize)]
44pub struct Session {
45    pub id: Uuid,
46    pub title: String,
47    pub visibility: SessionVisibility,
48    pub status: SessionStatus,
49    pub cwd: Option<String>,
50    pub created_at: DateTime<Utc>,
51    pub updated_at: DateTime<Utc>,
52    pub deleted_at: Option<DateTime<Utc>>,
53    pub active_checkpoint: Option<Checkpoint>,
54}
55
56/// Session summary for list responses
57#[derive(Debug, Clone, Deserialize)]
58pub struct SessionSummary {
59    pub id: Uuid,
60    pub title: String,
61    pub visibility: SessionVisibility,
62    pub status: SessionStatus,
63    pub cwd: Option<String>,
64    pub created_at: DateTime<Utc>,
65    pub updated_at: DateTime<Utc>,
66    pub message_count: u32,
67    pub active_checkpoint_id: Uuid,
68    pub last_message_at: Option<DateTime<Utc>>,
69}
70
71// =============================================================================
72// Checkpoint Types
73// =============================================================================
74
75/// Full checkpoint with state
76#[derive(Debug, Clone, Serialize, Deserialize)]
77pub struct Checkpoint {
78    pub id: Uuid,
79    pub session_id: Uuid,
80    pub parent_id: Option<Uuid>,
81    pub state: CheckpointState,
82    pub created_at: DateTime<Utc>,
83    pub updated_at: DateTime<Utc>,
84}
85
86/// Checkpoint summary for list responses
87#[derive(Debug, Clone, Deserialize)]
88pub struct CheckpointSummary {
89    pub id: Uuid,
90    pub session_id: Uuid,
91    pub parent_id: Option<Uuid>,
92    pub message_count: u32,
93    pub created_at: DateTime<Utc>,
94    pub updated_at: DateTime<Utc>,
95    /// State is optionally included based on `include_state` query param
96    pub state: Option<CheckpointState>,
97}
98
99/// Checkpoint state containing messages
100#[derive(Debug, Clone, Default, Serialize, Deserialize)]
101pub struct CheckpointState {
102    #[serde(default)]
103    pub messages: Vec<ChatMessage>,
104}
105
106// =============================================================================
107// Request Types
108// =============================================================================
109
110/// Request to create a session (with initial checkpoint state)
111#[derive(Debug, Serialize)]
112pub struct CreateSessionRequest {
113    /// Session title
114    pub title: String,
115    /// Session visibility
116    #[serde(skip_serializing_if = "Option::is_none")]
117    pub visibility: Option<SessionVisibility>,
118    /// Working directory
119    #[serde(skip_serializing_if = "Option::is_none")]
120    pub cwd: Option<String>,
121    /// Initial checkpoint state with messages
122    pub state: CheckpointState,
123}
124
125/// Request to create a checkpoint (for subsequent checkpoints)
126#[derive(Debug, Serialize)]
127pub struct CreateCheckpointRequest {
128    /// Checkpoint state with messages
129    pub state: CheckpointState,
130    /// Parent checkpoint ID (for branching)
131    #[serde(skip_serializing_if = "Option::is_none")]
132    pub parent_id: Option<Uuid>,
133}
134
135/// Query parameters for listing sessions
136#[derive(Debug, Default, Serialize)]
137pub struct ListSessionsQuery {
138    #[serde(skip_serializing_if = "Option::is_none")]
139    pub limit: Option<u32>,
140    #[serde(skip_serializing_if = "Option::is_none")]
141    pub offset: Option<u32>,
142    #[serde(skip_serializing_if = "Option::is_none")]
143    pub search: Option<String>,
144    #[serde(skip_serializing_if = "Option::is_none")]
145    pub status: Option<String>,
146    #[serde(skip_serializing_if = "Option::is_none")]
147    pub visibility: Option<String>,
148}
149
150/// Request to update a session
151#[derive(Debug, Serialize)]
152pub struct UpdateSessionRequest {
153    #[serde(skip_serializing_if = "Option::is_none")]
154    pub title: Option<String>,
155    #[serde(skip_serializing_if = "Option::is_none")]
156    pub visibility: Option<SessionVisibility>,
157}
158
159/// Query parameters for listing checkpoints
160#[derive(Debug, Default, Serialize)]
161pub struct ListCheckpointsQuery {
162    #[serde(skip_serializing_if = "Option::is_none")]
163    pub limit: Option<u32>,
164    #[serde(skip_serializing_if = "Option::is_none")]
165    pub offset: Option<u32>,
166    #[serde(skip_serializing_if = "Option::is_none")]
167    pub include_state: Option<bool>,
168}
169
170// =============================================================================
171// Response Types
172// =============================================================================
173
174/// Response from creating a session
175#[derive(Debug, Deserialize)]
176pub struct CreateSessionResponse {
177    pub session_id: Uuid,
178    pub checkpoint: Checkpoint,
179}
180
181/// Response from creating a checkpoint
182#[derive(Debug, Deserialize)]
183pub struct CreateCheckpointResponse {
184    pub checkpoint: Checkpoint,
185}
186
187/// Response from listing sessions
188#[derive(Debug, Deserialize)]
189pub struct ListSessionsResponse {
190    pub sessions: Vec<SessionSummary>,
191}
192
193/// Response from getting a session
194#[derive(Debug, Deserialize)]
195pub struct GetSessionResponse {
196    pub session: Session,
197}
198
199/// Response from updating a session
200#[derive(Debug, Deserialize)]
201pub struct UpdateSessionResponse {
202    pub session: Session,
203}
204
205/// Response from deleting a session
206#[derive(Debug, Deserialize)]
207pub struct DeleteSessionResponse {
208    pub success: bool,
209    pub deleted_at: DateTime<Utc>,
210}
211
212/// Response from listing checkpoints
213#[derive(Debug, Deserialize)]
214pub struct ListCheckpointsResponse {
215    pub checkpoints: Vec<CheckpointSummary>,
216}
217
218/// Response from getting a checkpoint
219#[derive(Debug, Deserialize)]
220pub struct GetCheckpointResponse {
221    pub checkpoint: Checkpoint,
222}
223
224// =============================================================================
225// MCP Tool Request Types
226// =============================================================================
227
228/// Request for searching documentation
229#[derive(Debug, Serialize)]
230pub struct SearchDocsRequest {
231    pub keywords: String,
232    #[serde(skip_serializing_if = "Option::is_none")]
233    pub exclude_keywords: Option<String>,
234    #[serde(skip_serializing_if = "Option::is_none")]
235    pub limit: Option<u32>,
236}
237
238/// Request for searching memory
239#[derive(Debug, Serialize)]
240pub struct SearchMemoryRequest {
241    pub keywords: Vec<String>,
242    #[serde(skip_serializing_if = "Option::is_none")]
243    pub start_time: Option<DateTime<Utc>>,
244    #[serde(skip_serializing_if = "Option::is_none")]
245    pub end_time: Option<DateTime<Utc>>,
246}
247
248/// Request for reading Slack messages
249#[derive(Debug, Serialize)]
250pub struct SlackReadMessagesRequest {
251    pub channel: String,
252    #[serde(skip_serializing_if = "Option::is_none")]
253    pub limit: Option<u32>,
254}
255
256/// Request for reading Slack thread replies
257#[derive(Debug, Serialize)]
258pub struct SlackReadRepliesRequest {
259    pub channel: String,
260    pub ts: String,
261}
262
263/// Request for sending a Slack message
264#[derive(Debug, Serialize)]
265pub struct SlackSendMessageRequest {
266    pub channel: String,
267    pub mrkdwn_text: String,
268    #[serde(skip_serializing_if = "Option::is_none")]
269    pub thread_ts: Option<String>,
270}
271
272// =============================================================================
273// Internal Types
274// =============================================================================
275
276/// Parameters for calling MCP tools
277#[derive(Debug, Serialize)]
278pub(crate) struct ToolsCallParams {
279    pub name: String,
280    pub arguments: serde_json::Value,
281}