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