1use std::collections::HashMap;
2use std::path::PathBuf;
3
4use codex_protocol::ConversationId;
5use codex_protocol::config_types::ForcedLoginMethod;
6use codex_protocol::config_types::ReasoningEffort;
7use codex_protocol::config_types::ReasoningSummary;
8use codex_protocol::config_types::SandboxMode;
9use codex_protocol::config_types::Verbosity;
10use codex_protocol::models::ResponseItem;
11use codex_protocol::parse_command::ParsedCommand;
12use codex_protocol::protocol::AskForApproval;
13use codex_protocol::protocol::EventMsg;
14use codex_protocol::protocol::FileChange;
15use codex_protocol::protocol::ReviewDecision;
16use codex_protocol::protocol::SandboxCommandAssessment;
17use codex_protocol::protocol::SandboxPolicy;
18use codex_protocol::protocol::SessionSource;
19use codex_protocol::protocol::TurnAbortReason;
20use schemars::JsonSchema;
21use serde::Deserialize;
22use serde::Serialize;
23use ts_rs::TS;
24use uuid::Uuid;
25
26use crate::protocol::common::AuthMode;
28use crate::protocol::common::GitSha;
29
30#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default, JsonSchema, TS)]
31#[serde(rename_all = "camelCase")]
32pub struct InitializeParams {
33 pub client_info: ClientInfo,
34}
35
36#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default, JsonSchema, TS)]
37#[serde(rename_all = "camelCase")]
38pub struct ClientInfo {
39 pub name: String,
40 pub title: Option<String>,
41 pub version: String,
42}
43
44#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
45#[serde(rename_all = "camelCase")]
46pub struct InitializeResponse {
47 pub user_agent: String,
48}
49
50#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default, JsonSchema, TS)]
51#[serde(rename_all = "camelCase")]
52pub struct NewConversationParams {
53 pub model: Option<String>,
54 pub model_provider: Option<String>,
55 pub profile: Option<String>,
56 pub cwd: Option<String>,
57 pub approval_policy: Option<AskForApproval>,
58 pub sandbox: Option<SandboxMode>,
59 pub config: Option<HashMap<String, serde_json::Value>>,
60 pub base_instructions: Option<String>,
61 #[serde(skip_serializing_if = "Option::is_none")]
62 pub developer_instructions: Option<String>,
63 #[serde(skip_serializing_if = "Option::is_none")]
64 pub compact_prompt: Option<String>,
65 pub include_apply_patch_tool: Option<bool>,
66}
67
68#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
69#[serde(rename_all = "camelCase")]
70pub struct NewConversationResponse {
71 pub conversation_id: ConversationId,
72 pub model: String,
73 pub reasoning_effort: Option<ReasoningEffort>,
74 pub rollout_path: PathBuf,
75}
76
77#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema, TS)]
78#[serde(rename_all = "camelCase")]
79pub struct ResumeConversationResponse {
80 pub conversation_id: ConversationId,
81 pub model: String,
82 pub initial_messages: Option<Vec<EventMsg>>,
83 pub rollout_path: PathBuf,
84}
85
86#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
87#[serde(untagged)]
88pub enum GetConversationSummaryParams {
89 RolloutPath {
90 #[serde(rename = "rolloutPath")]
91 rollout_path: PathBuf,
92 },
93 ConversationId {
94 #[serde(rename = "conversationId")]
95 conversation_id: ConversationId,
96 },
97}
98
99#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema, TS)]
100#[serde(rename_all = "camelCase")]
101pub struct GetConversationSummaryResponse {
102 pub summary: ConversationSummary,
103}
104
105#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default, JsonSchema, TS)]
106#[serde(rename_all = "camelCase")]
107pub struct ListConversationsParams {
108 pub page_size: Option<usize>,
109 pub cursor: Option<String>,
110 pub model_providers: Option<Vec<String>>,
111}
112
113#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
114#[serde(rename_all = "camelCase")]
115pub struct ConversationSummary {
116 pub conversation_id: ConversationId,
117 pub path: PathBuf,
118 pub preview: String,
119 pub timestamp: Option<String>,
120 pub model_provider: String,
121 pub cwd: PathBuf,
122 pub cli_version: String,
123 pub source: SessionSource,
124 pub git_info: Option<ConversationGitInfo>,
125}
126
127#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
128#[serde(rename_all = "snake_case")]
129pub struct ConversationGitInfo {
130 pub sha: Option<String>,
131 pub branch: Option<String>,
132 pub origin_url: Option<String>,
133}
134
135#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
136#[serde(rename_all = "camelCase")]
137pub struct ListConversationsResponse {
138 pub items: Vec<ConversationSummary>,
139 pub next_cursor: Option<String>,
140}
141
142#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
143#[serde(rename_all = "camelCase")]
144pub struct ResumeConversationParams {
145 pub path: Option<PathBuf>,
146 pub conversation_id: Option<ConversationId>,
147 pub history: Option<Vec<ResponseItem>>,
148 pub overrides: Option<NewConversationParams>,
149}
150
151#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
152#[serde(rename_all = "camelCase")]
153pub struct AddConversationSubscriptionResponse {
154 #[schemars(with = "String")]
155 pub subscription_id: Uuid,
156}
157
158#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
159#[serde(rename_all = "camelCase")]
160pub struct ArchiveConversationParams {
161 pub conversation_id: ConversationId,
162 pub rollout_path: PathBuf,
163}
164
165#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
166#[serde(rename_all = "camelCase")]
167pub struct ArchiveConversationResponse {}
168
169#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
170#[serde(rename_all = "camelCase")]
171pub struct RemoveConversationSubscriptionResponse {}
172
173#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
174#[serde(rename_all = "camelCase")]
175pub struct LoginApiKeyParams {
176 pub api_key: String,
177}
178
179#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
180#[serde(rename_all = "camelCase")]
181pub struct LoginApiKeyResponse {}
182
183#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
184#[serde(rename_all = "camelCase")]
185pub struct LoginChatGptResponse {
186 #[schemars(with = "String")]
187 pub login_id: Uuid,
188 pub auth_url: String,
189}
190
191#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
192#[serde(rename_all = "camelCase")]
193pub struct GitDiffToRemoteResponse {
194 pub sha: GitSha,
195 pub diff: String,
196}
197
198#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
199#[serde(rename_all = "camelCase")]
200pub struct ApplyPatchApprovalParams {
201 pub conversation_id: ConversationId,
202 pub call_id: String,
205 pub file_changes: HashMap<PathBuf, FileChange>,
206 pub reason: Option<String>,
208 pub grant_root: Option<PathBuf>,
211}
212
213#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
214#[serde(rename_all = "camelCase")]
215pub struct ApplyPatchApprovalResponse {
216 pub decision: ReviewDecision,
217}
218
219#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
220#[serde(rename_all = "camelCase")]
221pub struct ExecCommandApprovalParams {
222 pub conversation_id: ConversationId,
223 pub call_id: String,
226 pub command: Vec<String>,
227 pub cwd: PathBuf,
228 pub reason: Option<String>,
229 pub risk: Option<SandboxCommandAssessment>,
230 pub parsed_cmd: Vec<ParsedCommand>,
231}
232
233#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
234pub struct ExecCommandApprovalResponse {
235 pub decision: ReviewDecision,
236}
237
238#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
239#[serde(rename_all = "camelCase")]
240pub struct CancelLoginChatGptParams {
241 #[schemars(with = "String")]
242 pub login_id: Uuid,
243}
244
245#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
246#[serde(rename_all = "camelCase")]
247pub struct GitDiffToRemoteParams {
248 pub cwd: PathBuf,
249}
250
251#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
252#[serde(rename_all = "camelCase")]
253pub struct CancelLoginChatGptResponse {}
254
255#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
256#[serde(rename_all = "camelCase")]
257pub struct LogoutChatGptParams {}
258
259#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
260#[serde(rename_all = "camelCase")]
261pub struct LogoutChatGptResponse {}
262
263#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
264#[serde(rename_all = "camelCase")]
265pub struct GetAuthStatusParams {
266 pub include_token: Option<bool>,
267 pub refresh_token: Option<bool>,
268}
269
270#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
271#[serde(rename_all = "camelCase")]
272pub struct ExecOneOffCommandParams {
273 pub command: Vec<String>,
274 pub timeout_ms: Option<u64>,
275 pub cwd: Option<PathBuf>,
276 pub sandbox_policy: Option<SandboxPolicy>,
277}
278
279#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
280#[serde(rename_all = "camelCase")]
281pub struct ExecOneOffCommandResponse {
282 pub exit_code: i32,
283 pub stdout: String,
284 pub stderr: String,
285}
286
287#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
288#[serde(rename_all = "camelCase")]
289pub struct GetAuthStatusResponse {
290 pub auth_method: Option<AuthMode>,
291 pub auth_token: Option<String>,
292 pub requires_openai_auth: Option<bool>,
293}
294
295#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
296#[serde(rename_all = "camelCase")]
297pub struct GetUserAgentResponse {
298 pub user_agent: String,
299}
300
301#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
302#[serde(rename_all = "camelCase")]
303pub struct UserInfoResponse {
304 pub alleged_user_email: Option<String>,
305}
306
307#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
308#[serde(rename_all = "camelCase")]
309pub struct GetUserSavedConfigResponse {
310 pub config: UserSavedConfig,
311}
312
313#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
314#[serde(rename_all = "camelCase")]
315pub struct SetDefaultModelParams {
316 pub model: Option<String>,
317 pub reasoning_effort: Option<ReasoningEffort>,
318}
319
320#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
321#[serde(rename_all = "camelCase")]
322pub struct SetDefaultModelResponse {}
323
324#[derive(Deserialize, Debug, Clone, PartialEq, Serialize, JsonSchema, TS)]
325#[serde(rename_all = "camelCase")]
326pub struct UserSavedConfig {
327 pub approval_policy: Option<AskForApproval>,
328 pub sandbox_mode: Option<SandboxMode>,
329 pub sandbox_settings: Option<SandboxSettings>,
330 pub forced_chatgpt_workspace_id: Option<String>,
331 pub forced_login_method: Option<ForcedLoginMethod>,
332 pub model: Option<String>,
333 pub model_reasoning_effort: Option<ReasoningEffort>,
334 pub model_reasoning_summary: Option<ReasoningSummary>,
335 pub model_verbosity: Option<Verbosity>,
336 pub tools: Option<Tools>,
337 pub profile: Option<String>,
338 pub profiles: HashMap<String, Profile>,
339}
340
341#[derive(Deserialize, Debug, Clone, PartialEq, Serialize, JsonSchema, TS)]
342#[serde(rename_all = "camelCase")]
343pub struct Profile {
344 pub model: Option<String>,
345 pub model_provider: Option<String>,
346 pub approval_policy: Option<AskForApproval>,
347 pub model_reasoning_effort: Option<ReasoningEffort>,
348 pub model_reasoning_summary: Option<ReasoningSummary>,
349 pub model_verbosity: Option<Verbosity>,
350 pub chatgpt_base_url: Option<String>,
351}
352
353#[derive(Deserialize, Debug, Clone, PartialEq, Serialize, JsonSchema, TS)]
354#[serde(rename_all = "camelCase")]
355pub struct Tools {
356 pub web_search: Option<bool>,
357 pub view_image: Option<bool>,
358}
359
360#[derive(Deserialize, Debug, Clone, PartialEq, Serialize, JsonSchema, TS)]
361#[serde(rename_all = "camelCase")]
362pub struct SandboxSettings {
363 #[serde(default)]
364 pub writable_roots: Vec<PathBuf>,
365 pub network_access: Option<bool>,
366 pub exclude_tmpdir_env_var: Option<bool>,
367 pub exclude_slash_tmp: Option<bool>,
368}
369
370#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
371#[serde(rename_all = "camelCase")]
372pub struct SendUserMessageParams {
373 pub conversation_id: ConversationId,
374 pub items: Vec<InputItem>,
375}
376
377#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
378#[serde(rename_all = "camelCase")]
379pub struct SendUserTurnParams {
380 pub conversation_id: ConversationId,
381 pub items: Vec<InputItem>,
382 pub cwd: PathBuf,
383 pub approval_policy: AskForApproval,
384 pub sandbox_policy: SandboxPolicy,
385 pub model: String,
386 pub effort: Option<ReasoningEffort>,
387 pub summary: ReasoningSummary,
388}
389
390#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
391#[serde(rename_all = "camelCase")]
392pub struct SendUserTurnResponse {}
393
394#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
395#[serde(rename_all = "camelCase")]
396pub struct InterruptConversationParams {
397 pub conversation_id: ConversationId,
398}
399
400#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema, TS)]
401#[serde(rename_all = "camelCase")]
402pub struct InterruptConversationResponse {
403 pub abort_reason: TurnAbortReason,
404}
405
406#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
407#[serde(rename_all = "camelCase")]
408pub struct SendUserMessageResponse {}
409
410#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
411#[serde(rename_all = "camelCase")]
412pub struct AddConversationListenerParams {
413 pub conversation_id: ConversationId,
414 #[serde(default)]
415 pub experimental_raw_events: bool,
416}
417
418#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
419#[serde(rename_all = "camelCase")]
420pub struct RemoveConversationListenerParams {
421 #[schemars(with = "String")]
422 pub subscription_id: Uuid,
423}
424
425#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
426#[serde(rename_all = "camelCase")]
427#[serde(tag = "type", content = "data")]
428pub enum InputItem {
429 Text { text: String },
430 Image { image_url: String },
431 LocalImage { path: PathBuf },
432}
433
434#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
435#[serde(rename_all = "camelCase")]
436pub struct LoginChatGptCompleteNotification {
438 #[schemars(with = "String")]
439 pub login_id: Uuid,
440 pub success: bool,
441 pub error: Option<String>,
442}
443
444#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema, TS)]
445#[serde(rename_all = "camelCase")]
446pub struct SessionConfiguredNotification {
447 pub session_id: ConversationId,
448 pub model: String,
449 pub reasoning_effort: Option<ReasoningEffort>,
450 pub history_log_id: u64,
451 #[ts(type = "number")]
452 pub history_entry_count: usize,
453 pub initial_messages: Option<Vec<EventMsg>>,
454 pub rollout_path: PathBuf,
455}
456
457#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
458#[serde(rename_all = "camelCase")]
459pub struct AuthStatusChangeNotification {
461 pub auth_method: Option<AuthMode>,
462}