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    /// Optional metadata for context trimming state, etc.
95    #[serde(default, skip_serializing_if = "Option::is_none")]
96    pub metadata: Option<serde_json::Value>,
97}
98
99// =============================================================================
100// Request Types
101// =============================================================================
102
103/// Request to create a session (with initial checkpoint state)
104#[derive(Debug, Serialize)]
105pub struct CreateSessionRequest {
106    /// Session title
107    pub title: String,
108    /// Session visibility
109    #[serde(skip_serializing_if = "Option::is_none")]
110    pub visibility: Option<SessionVisibility>,
111    /// Working directory
112    #[serde(skip_serializing_if = "Option::is_none")]
113    pub cwd: Option<String>,
114    /// Initial checkpoint state with messages
115    pub state: CheckpointState,
116}
117
118/// Request to create a checkpoint (for subsequent checkpoints)
119#[derive(Debug, Serialize)]
120pub struct CreateCheckpointRequest {
121    /// Checkpoint state with messages
122    pub state: CheckpointState,
123    /// Parent checkpoint ID (for branching)
124    #[serde(skip_serializing_if = "Option::is_none")]
125    pub parent_id: Option<Uuid>,
126}
127
128/// Query parameters for listing sessions
129#[derive(Debug, Default, Serialize)]
130pub struct ListSessionsQuery {
131    #[serde(skip_serializing_if = "Option::is_none")]
132    pub limit: Option<u32>,
133    #[serde(skip_serializing_if = "Option::is_none")]
134    pub offset: Option<u32>,
135    #[serde(skip_serializing_if = "Option::is_none")]
136    pub search: Option<String>,
137    #[serde(skip_serializing_if = "Option::is_none")]
138    pub status: Option<String>,
139    #[serde(skip_serializing_if = "Option::is_none")]
140    pub visibility: Option<String>,
141}
142
143/// Request to update a session
144#[derive(Debug, Serialize)]
145pub struct UpdateSessionRequest {
146    #[serde(skip_serializing_if = "Option::is_none")]
147    pub title: Option<String>,
148    #[serde(skip_serializing_if = "Option::is_none")]
149    pub visibility: Option<SessionVisibility>,
150}
151
152/// Query parameters for listing checkpoints
153#[derive(Debug, Default, Serialize)]
154pub struct ListCheckpointsQuery {
155    #[serde(skip_serializing_if = "Option::is_none")]
156    pub limit: Option<u32>,
157    #[serde(skip_serializing_if = "Option::is_none")]
158    pub offset: Option<u32>,
159    #[serde(skip_serializing_if = "Option::is_none")]
160    pub include_state: Option<bool>,
161}
162
163// =============================================================================
164// Response Types
165// =============================================================================
166
167/// Response from creating a session
168#[derive(Debug, Deserialize)]
169pub struct CreateSessionResponse {
170    pub session_id: Uuid,
171    pub checkpoint: Checkpoint,
172}
173
174/// Response from creating a checkpoint
175#[derive(Debug, Deserialize)]
176pub struct CreateCheckpointResponse {
177    pub checkpoint: Checkpoint,
178}
179
180/// Response from listing sessions
181#[derive(Debug, Deserialize)]
182pub struct ListSessionsResponse {
183    pub sessions: Vec<SessionSummary>,
184}
185
186/// Response from getting a session
187#[derive(Debug, Deserialize)]
188pub struct GetSessionResponse {
189    pub session: Session,
190}
191
192/// Response from updating a session
193#[derive(Debug, Deserialize)]
194pub struct UpdateSessionResponse {
195    pub session: Session,
196}
197
198/// Response from deleting a session
199#[derive(Debug, Deserialize)]
200pub struct DeleteSessionResponse {
201    pub success: bool,
202    pub deleted_at: DateTime<Utc>,
203}
204
205/// Response from listing checkpoints
206#[derive(Debug, Deserialize)]
207pub struct ListCheckpointsResponse {
208    pub checkpoints: Vec<CheckpointSummary>,
209}
210
211/// Response from getting a checkpoint
212#[derive(Debug, Deserialize)]
213pub struct GetCheckpointResponse {
214    pub checkpoint: Checkpoint,
215}
216
217// =============================================================================
218// MCP Tool Request Types
219// =============================================================================
220
221/// Request for searching documentation
222#[derive(Debug, Serialize)]
223pub struct SearchDocsRequest {
224    pub keywords: String,
225    #[serde(skip_serializing_if = "Option::is_none")]
226    pub exclude_keywords: Option<String>,
227    #[serde(skip_serializing_if = "Option::is_none")]
228    pub limit: Option<u32>,
229}
230
231/// Request for searching memory
232#[derive(Debug, Serialize)]
233pub struct SearchMemoryRequest {
234    pub keywords: Vec<String>,
235    #[serde(skip_serializing_if = "Option::is_none")]
236    pub start_time: Option<DateTime<Utc>>,
237    #[serde(skip_serializing_if = "Option::is_none")]
238    pub end_time: Option<DateTime<Utc>>,
239}
240
241/// Request for reading Slack messages
242#[derive(Debug, Serialize)]
243pub struct SlackReadMessagesRequest {
244    pub channel: String,
245    #[serde(skip_serializing_if = "Option::is_none")]
246    pub limit: Option<u32>,
247}
248
249/// Request for reading Slack thread replies
250#[derive(Debug, Serialize)]
251pub struct SlackReadRepliesRequest {
252    pub channel: String,
253    pub ts: String,
254}
255
256/// Request for sending a Slack message
257#[derive(Debug, Serialize)]
258pub struct SlackSendMessageRequest {
259    pub channel: String,
260    pub markdown_text: String,
261    #[serde(skip_serializing_if = "Option::is_none")]
262    pub thread_ts: Option<String>,
263}
264
265// =============================================================================
266// Internal Types
267// =============================================================================
268
269/// Parameters for calling MCP tools
270#[derive(Debug, Serialize)]
271pub(crate) struct ToolsCallParams {
272    pub name: String,
273    pub arguments: serde_json::Value,
274}