1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3
4macro_rules! opaque_struct {
5 ($name:ident) => {
6 #[derive(Debug, Clone, Serialize, Deserialize, Default)]
7 #[serde(rename_all = "camelCase")]
8 pub struct $name {
9 #[serde(flatten)]
10 pub extra: serde_json::Map<String, Value>,
11 }
12 };
13}
14
15#[derive(Debug, Clone, Serialize, Deserialize)]
16#[serde(rename_all = "camelCase")]
17pub struct ClientInfo {
18 pub name: String,
19 pub title: String,
20 pub version: String,
21}
22
23impl ClientInfo {
24 pub fn new(
25 name: impl Into<String>,
26 title: impl Into<String>,
27 version: impl Into<String>,
28 ) -> Self {
29 Self {
30 name: name.into(),
31 title: title.into(),
32 version: version.into(),
33 }
34 }
35}
36
37#[derive(Debug, Clone, Serialize, Deserialize, Default)]
38#[serde(rename_all = "camelCase")]
39pub struct InitializeCapabilities {
40 #[serde(default, skip_serializing_if = "Option::is_none")]
41 pub experimental_api: Option<bool>,
42 #[serde(flatten)]
43 pub extra: serde_json::Map<String, Value>,
44}
45
46#[derive(Debug, Clone, Serialize, Deserialize)]
47#[serde(rename_all = "camelCase")]
48pub struct InitializeParams {
49 pub client_info: ClientInfo,
50 #[serde(default, skip_serializing_if = "Option::is_none")]
51 pub capabilities: Option<InitializeCapabilities>,
52 #[serde(flatten)]
53 pub extra: serde_json::Map<String, Value>,
54}
55
56impl InitializeParams {
57 pub fn new(client_info: ClientInfo) -> Self {
58 Self {
59 client_info,
60 capabilities: None,
61 extra: serde_json::Map::new(),
62 }
63 }
64}
65
66#[derive(Debug, Clone, Serialize, Deserialize, Default)]
67#[serde(rename_all = "camelCase")]
68pub struct PaginationParams {
69 #[serde(default, skip_serializing_if = "Option::is_none")]
70 pub limit: Option<u32>,
71 #[serde(default, skip_serializing_if = "Option::is_none")]
72 pub cursor: Option<String>,
73 #[serde(flatten)]
74 pub extra: serde_json::Map<String, Value>,
75}
76
77#[derive(Debug, Clone, Serialize, Deserialize, Default)]
78#[serde(rename_all = "camelCase")]
79pub struct ThreadStartParams {
80 #[serde(default, skip_serializing_if = "Option::is_none")]
81 pub model: Option<String>,
82 #[serde(default, skip_serializing_if = "Option::is_none")]
83 pub model_provider: Option<String>,
84 #[serde(default, skip_serializing_if = "Option::is_none")]
85 pub cwd: Option<String>,
86 #[serde(default, skip_serializing_if = "Option::is_none")]
87 pub approval_policy: Option<String>,
88 #[serde(default, skip_serializing_if = "Option::is_none")]
89 pub sandbox: Option<String>,
90 #[serde(default, skip_serializing_if = "Option::is_none")]
91 pub sandbox_policy: Option<Value>,
92 #[serde(default, skip_serializing_if = "Option::is_none")]
93 pub effort: Option<String>,
94 #[serde(default, skip_serializing_if = "Option::is_none")]
95 pub summary: Option<String>,
96 #[serde(default, skip_serializing_if = "Option::is_none")]
97 pub personality: Option<String>,
98 #[serde(default, skip_serializing_if = "Option::is_none")]
99 pub ephemeral: Option<bool>,
100 #[serde(default, skip_serializing_if = "Option::is_none")]
101 pub base_instructions: Option<String>,
102 #[serde(default, skip_serializing_if = "Option::is_none")]
103 pub developer_instructions: Option<String>,
104 #[serde(flatten)]
105 pub extra: serde_json::Map<String, Value>,
106}
107
108#[derive(Debug, Clone, Serialize, Deserialize, Default)]
109#[serde(rename_all = "camelCase")]
110pub struct ThreadResumeParams {
111 pub thread_id: String,
112 #[serde(default, skip_serializing_if = "Option::is_none")]
113 pub history: Option<Vec<Value>>,
114 #[serde(default, skip_serializing_if = "Option::is_none")]
115 pub path: Option<String>,
116 #[serde(default, skip_serializing_if = "Option::is_none")]
117 pub model: Option<String>,
118 #[serde(default, skip_serializing_if = "Option::is_none")]
119 pub model_provider: Option<String>,
120 #[serde(default, skip_serializing_if = "Option::is_none")]
121 pub cwd: Option<String>,
122 #[serde(default, skip_serializing_if = "Option::is_none")]
123 pub approval_policy: Option<String>,
124 #[serde(default, skip_serializing_if = "Option::is_none")]
125 pub sandbox: Option<String>,
126 #[serde(default, skip_serializing_if = "Option::is_none")]
127 pub config: Option<serde_json::Map<String, Value>>,
128 #[serde(default, skip_serializing_if = "Option::is_none")]
129 pub base_instructions: Option<String>,
130 #[serde(default, skip_serializing_if = "Option::is_none")]
131 pub developer_instructions: Option<String>,
132 #[serde(default, skip_serializing_if = "Option::is_none")]
133 pub personality: Option<String>,
134 #[serde(default, skip_serializing_if = "Option::is_none")]
135 pub persist_extended_history: Option<bool>,
136 #[serde(flatten)]
137 pub extra: serde_json::Map<String, Value>,
138}
139
140#[derive(Debug, Clone, Serialize, Deserialize)]
141#[serde(rename_all = "camelCase")]
142pub struct ThreadIdParams {
143 pub thread_id: String,
144 #[serde(flatten)]
145 pub extra: serde_json::Map<String, Value>,
146}
147
148impl ThreadResumeParams {
149 pub fn from_thread_id(thread_id: impl Into<String>) -> Self {
150 Self {
151 thread_id: thread_id.into(),
152 ..Self::default()
153 }
154 }
155}
156
157impl From<ThreadIdParams> for ThreadResumeParams {
158 fn from(value: ThreadIdParams) -> Self {
159 Self {
160 thread_id: value.thread_id,
161 extra: value.extra,
162 ..Self::default()
163 }
164 }
165}
166
167#[derive(Debug, Clone, Serialize, Deserialize)]
168#[serde(rename_all = "camelCase")]
169pub struct ThreadForkParams {
170 pub thread_id: String,
171 #[serde(default, skip_serializing_if = "Option::is_none")]
172 pub from_turn_id: Option<String>,
173 #[serde(flatten)]
174 pub extra: serde_json::Map<String, Value>,
175}
176
177#[derive(Debug, Clone, Serialize, Deserialize)]
178#[serde(rename_all = "camelCase")]
179pub struct ThreadSetNameParams {
180 pub thread_id: String,
181 pub name: String,
182 #[serde(flatten)]
183 pub extra: serde_json::Map<String, Value>,
184}
185
186#[derive(Debug, Clone, Serialize, Deserialize)]
187#[serde(rename_all = "camelCase")]
188pub struct ThreadRollbackParams {
189 pub thread_id: String,
190 pub count: u32,
191 #[serde(flatten)]
192 pub extra: serde_json::Map<String, Value>,
193}
194
195#[derive(Debug, Clone, Serialize, Deserialize)]
196#[serde(rename_all = "camelCase")]
197pub struct ThreadBackgroundTerminalsCleanParams {
198 pub thread_id: String,
199 #[serde(flatten)]
200 pub extra: serde_json::Map<String, Value>,
201}
202
203#[derive(Debug, Clone, Serialize, Deserialize, Default)]
204#[serde(rename_all = "camelCase")]
205pub struct ThreadListParams {
206 #[serde(default, skip_serializing_if = "Option::is_none")]
207 pub limit: Option<u32>,
208 #[serde(default, skip_serializing_if = "Option::is_none")]
209 pub cursor: Option<String>,
210 #[serde(default, skip_serializing_if = "Option::is_none")]
211 pub archived: Option<bool>,
212 #[serde(default, skip_serializing_if = "Option::is_none")]
213 pub source_kinds: Option<Vec<String>>,
214 #[serde(default, skip_serializing_if = "Option::is_none")]
215 pub model_providers: Option<Vec<String>>,
216 #[serde(flatten)]
217 pub extra: serde_json::Map<String, Value>,
218}
219
220#[derive(Debug, Clone, Serialize, Deserialize)]
221#[serde(rename_all = "camelCase")]
222pub struct ThreadReadParams {
223 pub thread_id: String,
224 #[serde(default, skip_serializing_if = "Option::is_none")]
225 pub include_turns: Option<bool>,
226 #[serde(flatten)]
227 pub extra: serde_json::Map<String, Value>,
228}
229
230#[derive(Debug, Clone, Serialize, Deserialize)]
231#[serde(tag = "type", rename_all = "camelCase")]
232pub enum TurnInputItem {
233 Text {
234 text: String,
235 },
236 Image {
237 url: String,
238 },
239 LocalImage {
240 path: String,
241 },
242 Skill {
243 name: String,
244 path: String,
245 },
246 #[serde(other)]
247 Unknown,
248}
249
250impl TurnInputItem {
251 pub fn text(text: impl Into<String>) -> Self {
252 Self::Text { text: text.into() }
253 }
254}
255
256#[derive(Debug, Clone, Serialize, Deserialize)]
257#[serde(rename_all = "camelCase")]
258pub struct TurnStartParams {
259 pub thread_id: String,
260 pub input: Vec<TurnInputItem>,
261 #[serde(default, skip_serializing_if = "Option::is_none")]
262 pub cwd: Option<String>,
263 #[serde(default, skip_serializing_if = "Option::is_none")]
264 pub model: Option<String>,
265 #[serde(default, skip_serializing_if = "Option::is_none")]
266 pub model_provider: Option<String>,
267 #[serde(default, skip_serializing_if = "Option::is_none")]
268 pub effort: Option<String>,
269 #[serde(default, skip_serializing_if = "Option::is_none")]
270 pub summary: Option<String>,
271 #[serde(default, skip_serializing_if = "Option::is_none")]
272 pub personality: Option<String>,
273 #[serde(default, skip_serializing_if = "Option::is_none")]
274 pub output_schema: Option<Value>,
275 #[serde(default, skip_serializing_if = "Option::is_none")]
276 pub approval_policy: Option<String>,
277 #[serde(default, skip_serializing_if = "Option::is_none")]
278 pub sandbox_policy: Option<Value>,
279 #[serde(default, skip_serializing_if = "Option::is_none")]
280 pub collaboration_mode: Option<String>,
281 #[serde(flatten)]
282 pub extra: serde_json::Map<String, Value>,
283}
284
285impl TurnStartParams {
286 pub fn text(thread_id: impl Into<String>, text: impl Into<String>) -> Self {
287 Self {
288 thread_id: thread_id.into(),
289 input: vec![TurnInputItem::text(text)],
290 cwd: None,
291 model: None,
292 model_provider: None,
293 effort: None,
294 summary: None,
295 personality: None,
296 output_schema: None,
297 approval_policy: None,
298 sandbox_policy: None,
299 collaboration_mode: None,
300 extra: serde_json::Map::new(),
301 }
302 }
303}
304
305#[derive(Debug, Clone, Serialize, Deserialize)]
306#[serde(rename_all = "camelCase")]
307pub struct TurnSteerParams {
308 pub thread_id: String,
309 pub input: Vec<TurnInputItem>,
310 #[serde(default, skip_serializing_if = "Option::is_none")]
311 pub expected_turn_id: Option<String>,
312 #[serde(flatten)]
313 pub extra: serde_json::Map<String, Value>,
314}
315
316#[derive(Debug, Clone, Serialize, Deserialize)]
317#[serde(rename_all = "camelCase")]
318pub struct TurnInterruptParams {
319 pub thread_id: String,
320 pub turn_id: String,
321 #[serde(flatten)]
322 pub extra: serde_json::Map<String, Value>,
323}
324
325#[derive(Debug, Clone, Serialize, Deserialize, Default)]
326#[serde(rename_all = "camelCase")]
327pub struct SkillsListParams {
328 #[serde(default, skip_serializing_if = "Option::is_none")]
329 pub cwd: Option<Vec<String>>,
330 #[serde(default, skip_serializing_if = "Option::is_none")]
331 pub force_reload: Option<bool>,
332 #[serde(flatten)]
333 pub extra: serde_json::Map<String, Value>,
334}
335
336opaque_struct!(SkillsRemoteReadParams);
337opaque_struct!(SkillsRemoteWriteParams);
338opaque_struct!(SkillsConfigWriteParams);
339opaque_struct!(AppsListParams);
340opaque_struct!(ReviewStartParams);
341opaque_struct!(ModelListParams);
342opaque_struct!(ExperimentalFeatureListParams);
343opaque_struct!(CollaborationModeListParams);
344opaque_struct!(MockExperimentalMethodParams);
345opaque_struct!(McpServerOauthLoginParams);
346opaque_struct!(ListMcpServerStatusParams);
347opaque_struct!(WindowsSandboxSetupStartParams);
348opaque_struct!(FeedbackUploadParams);
349opaque_struct!(CommandExecParams);
350opaque_struct!(ConfigReadParams);
351opaque_struct!(ConfigValueWriteParams);
352opaque_struct!(ConfigBatchWriteParams);
353opaque_struct!(FuzzyFileSearchSessionStartParams);
354opaque_struct!(FuzzyFileSearchSessionUpdateParams);
355opaque_struct!(FuzzyFileSearchSessionStopParams);
356
357#[derive(Debug, Clone, Serialize, Deserialize)]
358#[serde(rename_all = "camelCase")]
359pub struct LoginAccountParams {
360 #[serde(rename = "type")]
361 pub login_type: String,
362 #[serde(default, skip_serializing_if = "Option::is_none")]
363 pub api_key: Option<String>,
364 #[serde(default, skip_serializing_if = "Option::is_none")]
365 pub id_token: Option<String>,
366 #[serde(default, skip_serializing_if = "Option::is_none")]
367 pub access_token: Option<String>,
368 #[serde(flatten)]
369 pub extra: serde_json::Map<String, Value>,
370}
371
372impl LoginAccountParams {
373 pub fn api_key(key: impl Into<String>) -> Self {
374 Self {
375 login_type: "apiKey".to_string(),
376 api_key: Some(key.into()),
377 id_token: None,
378 access_token: None,
379 extra: serde_json::Map::new(),
380 }
381 }
382
383 pub fn chatgpt(id_token: impl Into<String>, access_token: impl Into<String>) -> Self {
384 Self {
385 login_type: "chatgpt".to_string(),
386 api_key: None,
387 id_token: Some(id_token.into()),
388 access_token: Some(access_token.into()),
389 extra: serde_json::Map::new(),
390 }
391 }
392}
393
394#[derive(Debug, Clone, Serialize, Deserialize)]
395#[serde(rename_all = "camelCase")]
396pub struct CancelLoginAccountParams {
397 pub login_id: String,
398 #[serde(flatten)]
399 pub extra: serde_json::Map<String, Value>,
400}
401
402#[derive(Debug, Clone, Serialize, Deserialize, Default)]
403#[serde(rename_all = "camelCase")]
404pub struct GetAccountParams {
405 #[serde(default, skip_serializing_if = "Option::is_none")]
406 pub refresh_token: Option<bool>,
407 #[serde(flatten)]
408 pub extra: serde_json::Map<String, Value>,
409}
410
411pub type ThreadArchiveParams = ThreadIdParams;
412pub type ThreadUnarchiveParams = ThreadIdParams;
413pub type ThreadCompactStartParams = ThreadIdParams;
414pub type ThreadLoadedListParams = PaginationParams;