Skip to content

Commit 94d51cc

Browse files
committed
[app-server] define new v2 approval request
1 parent 3838d67 commit 94d51cc

File tree

6 files changed

+302
-88
lines changed

6 files changed

+302
-88
lines changed

codex-rs/Cargo.lock

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

codex-rs/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,6 @@ opentelemetry-semantic-conventions = "0.30.0"
148148
opentelemetry_sdk = "0.30.0"
149149
os_info = "3.12.0"
150150
owo-colors = "4.2.0"
151-
paste = "1.0.15"
152151
path-absolutize = "3.1.1"
153152
pathdiff = "0.2"
154153
portable-pty = "0.9.0"

codex-rs/app-server-protocol/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ anyhow = { workspace = true }
1515
clap = { workspace = true, features = ["derive"] }
1616
codex-protocol = { workspace = true }
1717
mcp-types = { workspace = true }
18-
paste = { workspace = true }
1918
schemars = { workspace = true }
2019
serde = { workspace = true, features = ["derive"] }
2120
serde_json = { workspace = true }

codex-rs/app-server-protocol/src/protocol/common.rs

Lines changed: 61 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
use std::collections::HashMap;
21
use std::path::Path;
3-
use std::path::PathBuf;
42

53
use crate::JSONRPCNotification;
64
use crate::JSONRPCRequest;
@@ -9,12 +7,6 @@ use crate::export::GeneratedSchema;
97
use crate::export::write_json_schema;
108
use crate::protocol::v1;
119
use crate::protocol::v2;
12-
use codex_protocol::ConversationId;
13-
use codex_protocol::parse_command::ParsedCommand;
14-
use codex_protocol::protocol::FileChange;
15-
use codex_protocol::protocol::ReviewDecision;
16-
use codex_protocol::protocol::SandboxCommandAssessment;
17-
use paste::paste;
1810
use schemars::JsonSchema;
1911
use serde::Deserialize;
2012
use serde::Serialize;
@@ -277,44 +269,46 @@ macro_rules! server_request_definitions {
277269
(
278270
$(
279271
$(#[$variant_meta:meta])*
280-
$variant:ident
272+
$variant:ident $(=> $wire:literal)? {
273+
params: $params:ty,
274+
response: $response:ty,
275+
}
281276
),* $(,)?
282277
) => {
283-
paste! {
284-
/// Request initiated from the server and sent to the client.
285-
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
286-
#[serde(tag = "method", rename_all = "camelCase")]
287-
pub enum ServerRequest {
288-
$(
289-
$(#[$variant_meta])*
290-
$variant {
291-
#[serde(rename = "id")]
292-
request_id: RequestId,
293-
params: [<$variant Params>],
294-
},
295-
)*
296-
}
278+
/// Request initiated from the server and sent to the client.
279+
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
280+
#[serde(tag = "method", rename_all = "camelCase")]
281+
pub enum ServerRequest {
282+
$(
283+
$(#[$variant_meta])*
284+
$(#[serde(rename = $wire)] #[ts(rename = $wire)])?
285+
$variant {
286+
#[serde(rename = "id")]
287+
request_id: RequestId,
288+
params: $params,
289+
},
290+
)*
291+
}
297292

298-
#[derive(Debug, Clone, PartialEq, JsonSchema)]
299-
pub enum ServerRequestPayload {
300-
$( $variant([<$variant Params>]), )*
301-
}
293+
#[derive(Debug, Clone, PartialEq, JsonSchema)]
294+
pub enum ServerRequestPayload {
295+
$( $variant($params), )*
296+
}
302297

303-
impl ServerRequestPayload {
304-
pub fn request_with_id(self, request_id: RequestId) -> ServerRequest {
305-
match self {
306-
$(Self::$variant(params) => ServerRequest::$variant { request_id, params },)*
307-
}
298+
impl ServerRequestPayload {
299+
pub fn request_with_id(self, request_id: RequestId) -> ServerRequest {
300+
match self {
301+
$(Self::$variant(params) => ServerRequest::$variant { request_id, params },)*
308302
}
309303
}
310304
}
311305

312306
pub fn export_server_responses(
313307
out_dir: &::std::path::Path,
314308
) -> ::std::result::Result<(), ::ts_rs::ExportError> {
315-
paste! {
316-
$(<[<$variant Response>] as ::ts_rs::TS>::export_all_to(out_dir)?;)*
317-
}
309+
$(
310+
<$response as ::ts_rs::TS>::export_all_to(out_dir)?;
311+
)*
318312
Ok(())
319313
}
320314

@@ -323,9 +317,12 @@ macro_rules! server_request_definitions {
323317
out_dir: &Path,
324318
) -> ::anyhow::Result<Vec<GeneratedSchema>> {
325319
let mut schemas = Vec::new();
326-
paste! {
327-
$(schemas.push(crate::export::write_json_schema::<[<$variant Response>]>(out_dir, stringify!([<$variant Response>]))?);)*
328-
}
320+
$(
321+
schemas.push(crate::export::write_json_schema::<$response>(
322+
out_dir,
323+
concat!(stringify!($variant), "Response"),
324+
)?);
325+
)*
329326
Ok(schemas)
330327
}
331328

@@ -334,9 +331,12 @@ macro_rules! server_request_definitions {
334331
out_dir: &Path,
335332
) -> ::anyhow::Result<Vec<GeneratedSchema>> {
336333
let mut schemas = Vec::new();
337-
paste! {
338-
$(schemas.push(crate::export::write_json_schema::<[<$variant Params>]>(out_dir, stringify!([<$variant Params>]))?);)*
339-
}
334+
$(
335+
schemas.push(crate::export::write_json_schema::<$params>(
336+
out_dir,
337+
concat!(stringify!($variant), "Params"),
338+
)?);
339+
)*
340340
Ok(schemas)
341341
}
342342
};
@@ -426,49 +426,24 @@ impl TryFrom<JSONRPCRequest> for ServerRequest {
426426
}
427427

428428
server_request_definitions! {
429+
/// NEW APIs
430+
/// Sent when approval is requested for a specific item (e.g. file edit, command execution).
431+
ItemRequestApproval => "item/requestApproval" {
432+
params: v2::ItemRequestApprovalParams,
433+
response: v2::ItemRequestApprovalResponse,
434+
},
435+
436+
/// DEPRECATED APIs below
429437
/// Request to approve a patch.
430-
ApplyPatchApproval,
438+
ApplyPatchApproval {
439+
params: v1::ApplyPatchApprovalParams,
440+
response: v1::ApplyPatchApprovalResponse,
441+
},
431442
/// Request to exec a command.
432-
ExecCommandApproval,
433-
}
434-
435-
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
436-
#[serde(rename_all = "camelCase")]
437-
pub struct ApplyPatchApprovalParams {
438-
pub conversation_id: ConversationId,
439-
/// Use to correlate this with [codex_core::protocol::PatchApplyBeginEvent]
440-
/// and [codex_core::protocol::PatchApplyEndEvent].
441-
pub call_id: String,
442-
pub file_changes: HashMap<PathBuf, FileChange>,
443-
/// Optional explanatory reason (e.g. request for extra write access).
444-
pub reason: Option<String>,
445-
/// When set, the agent is asking the user to allow writes under this root
446-
/// for the remainder of the session (unclear if this is honored today).
447-
pub grant_root: Option<PathBuf>,
448-
}
449-
450-
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
451-
#[serde(rename_all = "camelCase")]
452-
pub struct ExecCommandApprovalParams {
453-
pub conversation_id: ConversationId,
454-
/// Use to correlate this with [codex_core::protocol::ExecCommandBeginEvent]
455-
/// and [codex_core::protocol::ExecCommandEndEvent].
456-
pub call_id: String,
457-
pub command: Vec<String>,
458-
pub cwd: PathBuf,
459-
pub reason: Option<String>,
460-
pub risk: Option<SandboxCommandAssessment>,
461-
pub parsed_cmd: Vec<ParsedCommand>,
462-
}
463-
464-
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
465-
pub struct ExecCommandApprovalResponse {
466-
pub decision: ReviewDecision,
467-
}
468-
469-
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
470-
pub struct ApplyPatchApprovalResponse {
471-
pub decision: ReviewDecision,
443+
ExecCommandApproval {
444+
params: v1::ExecCommandApprovalParams,
445+
response: v1::ExecCommandApprovalResponse,
446+
},
472447
}
473448

474449
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
@@ -530,10 +505,13 @@ client_notification_definitions! {
530505
mod tests {
531506
use super::*;
532507
use anyhow::Result;
508+
use codex_protocol::ConversationId;
533509
use codex_protocol::account::PlanType;
510+
use codex_protocol::parse_command::ParsedCommand;
534511
use codex_protocol::protocol::AskForApproval;
535512
use pretty_assertions::assert_eq;
536513
use serde_json::json;
514+
use std::path::PathBuf;
537515

538516
#[test]
539517
fn serialize_new_conversation() -> Result<()> {
@@ -613,7 +591,7 @@ mod tests {
613591
#[test]
614592
fn serialize_server_request() -> Result<()> {
615593
let conversation_id = ConversationId::from_string("67e55044-10b1-426f-9247-bb680e5fe0c8")?;
616-
let params = ExecCommandApprovalParams {
594+
let params = v1::ExecCommandApprovalParams {
617595
conversation_id,
618596
call_id: "call-42".to_string(),
619597
command: vec!["echo".to_string(), "hello".to_string()],

codex-rs/app-server-protocol/src/protocol/v1.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,12 @@ use codex_protocol::config_types::ReasoningSummary;
88
use codex_protocol::config_types::SandboxMode;
99
use codex_protocol::config_types::Verbosity;
1010
use codex_protocol::models::ResponseItem;
11+
use codex_protocol::parse_command::ParsedCommand;
1112
use codex_protocol::protocol::AskForApproval;
1213
use codex_protocol::protocol::EventMsg;
14+
use codex_protocol::protocol::FileChange;
15+
use codex_protocol::protocol::ReviewDecision;
16+
use codex_protocol::protocol::SandboxCommandAssessment;
1317
use codex_protocol::protocol::SandboxPolicy;
1418
use codex_protocol::protocol::SessionSource;
1519
use codex_protocol::protocol::TurnAbortReason;
@@ -191,6 +195,46 @@ pub struct GitDiffToRemoteResponse {
191195
pub diff: String,
192196
}
193197

198+
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
199+
#[serde(rename_all = "camelCase")]
200+
pub 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")]
215+
pub struct ApplyPatchApprovalResponse {
216+
pub decision: ReviewDecision,
217+
}
218+
219+
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
220+
#[serde(rename_all = "camelCase")]
221+
pub 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)]
234+
pub struct ExecCommandApprovalResponse {
235+
pub decision: ReviewDecision,
236+
}
237+
194238
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
195239
#[serde(rename_all = "camelCase")]
196240
pub struct CancelLoginChatGptParams {

0 commit comments

Comments
 (0)