From 1ac788d012bd6a2ddbd1a49be978132b568321a8 Mon Sep 17 00:00:00 2001 From: Roy Han Date: Tue, 7 Apr 2026 14:28:40 -0700 Subject: [PATCH] add server response --- .../src/protocol/common.rs | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/codex-rs/app-server-protocol/src/protocol/common.rs b/codex-rs/app-server-protocol/src/protocol/common.rs index 3ac96fa0eb4..b0a20544c78 100644 --- a/codex-rs/app-server-protocol/src/protocol/common.rs +++ b/codex-rs/app-server-protocol/src/protocol/common.rs @@ -620,6 +620,41 @@ macro_rules! server_request_definitions { } } + /// Typed response from the client to the server. + #[derive(Serialize, Deserialize, Debug, Clone)] + #[serde(tag = "method", rename_all = "camelCase")] + pub enum ServerResponse { + $( + $(#[$variant_meta])* + $(#[serde(rename = $wire)])? + $variant { + #[serde(rename = "id")] + request_id: RequestId, + response: $response, + }, + )* + } + + impl ServerResponse { + pub fn id(&self) -> &RequestId { + match self { + $(Self::$variant { request_id, .. } => request_id,)* + } + } + + pub fn method(&self) -> String { + serde_json::to_value(self) + .ok() + .and_then(|value| { + value + .get("method") + .and_then(serde_json::Value::as_str) + .map(str::to_owned) + }) + .unwrap_or_else(|| "".to_string()) + } + } + #[derive(Debug, Clone, PartialEq, JsonSchema)] #[allow(clippy::large_enum_variant)] pub enum ServerRequestPayload { @@ -1230,6 +1265,30 @@ mod tests { Ok(()) } + #[test] + fn serialize_server_response() -> Result<()> { + let response = ServerResponse::CommandExecutionRequestApproval { + request_id: RequestId::Integer(8), + response: v2::CommandExecutionRequestApprovalResponse { + decision: v2::CommandExecutionApprovalDecision::AcceptForSession, + }, + }; + + assert_eq!(response.id(), &RequestId::Integer(8)); + assert_eq!(response.method(), "item/commandExecution/requestApproval"); + assert_eq!( + json!({ + "method": "item/commandExecution/requestApproval", + "id": 8, + "response": { + "decision": "acceptForSession" + } + }), + serde_json::to_value(&response)?, + ); + Ok(()) + } + #[test] fn serialize_mcp_server_elicitation_request() -> Result<()> { let requested_schema: v2::McpElicitationSchema = serde_json::from_value(json!({