Skip to main content

codex_app_server_protocol/protocol/
v1.rs

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
26// Reuse shared types defined in `common.rs`.
27use 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    /// Use to correlate this with [codex_core::protocol::PatchApplyBeginEvent]
203    /// and [codex_core::protocol::PatchApplyEndEvent].
204    pub call_id: String,
205    pub file_changes: HashMap<PathBuf, FileChange>,
206    /// Optional explanatory reason (e.g. request for extra write access).
207    pub reason: Option<String>,
208    /// When set, the agent is asking the user to allow writes under this root
209    /// for the remainder of the session (unclear if this is honored today).
210    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    /// Use to correlate this with [codex_core::protocol::ExecCommandBeginEvent]
224    /// and [codex_core::protocol::ExecCommandEndEvent].
225    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")]
436/// Deprecated in favor of AccountLoginCompletedNotification.
437pub 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")]
459/// Deprecated notification. Use AccountUpdatedNotification instead.
460pub struct AuthStatusChangeNotification {
461    pub auth_method: Option<AuthMode>,
462}