diff --git a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json index 353507a47..1170b4110 100644 --- a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json +++ b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json @@ -2171,11 +2171,21 @@ "InitializeResponse": { "$schema": "http://json-schema.org/draft-07/schema#", "properties": { + "platformFamily": { + "description": "Platform family for the running app-server target, for example `\"unix\"` or `\"windows\"`.", + "type": "string" + }, + "platformOs": { + "description": "Operating system for the running app-server target, for example `\"macos\"`, `\"linux\"`, or `\"windows\"`.", + "type": "string" + }, "userAgent": { "type": "string" } }, "required": [ + "platformFamily", + "platformOs", "userAgent" ], "title": "InitializeResponse", diff --git a/codex-rs/app-server-protocol/schema/json/v1/InitializeResponse.json b/codex-rs/app-server-protocol/schema/json/v1/InitializeResponse.json index 6ace3177b..ada38a658 100644 --- a/codex-rs/app-server-protocol/schema/json/v1/InitializeResponse.json +++ b/codex-rs/app-server-protocol/schema/json/v1/InitializeResponse.json @@ -1,11 +1,21 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "properties": { + "platformFamily": { + "description": "Platform family for the running app-server target, for example `\"unix\"` or `\"windows\"`.", + "type": "string" + }, + "platformOs": { + "description": "Operating system for the running app-server target, for example `\"macos\"`, `\"linux\"`, or `\"windows\"`.", + "type": "string" + }, "userAgent": { "type": "string" } }, "required": [ + "platformFamily", + "platformOs", "userAgent" ], "title": "InitializeResponse", diff --git a/codex-rs/app-server-protocol/schema/typescript/InitializeResponse.ts b/codex-rs/app-server-protocol/schema/typescript/InitializeResponse.ts index 8a6bec66e..47978fc8d 100644 --- a/codex-rs/app-server-protocol/schema/typescript/InitializeResponse.ts +++ b/codex-rs/app-server-protocol/schema/typescript/InitializeResponse.ts @@ -2,4 +2,14 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -export type InitializeResponse = { userAgent: string, }; +export type InitializeResponse = { userAgent: string, +/** + * Platform family for the running app-server target, for example + * `"unix"` or `"windows"`. + */ +platformFamily: string, +/** + * Operating system for the running app-server target, for example + * `"macos"`, `"linux"`, or `"windows"`. + */ +platformOs: string, }; diff --git a/codex-rs/app-server-protocol/src/protocol/v1.rs b/codex-rs/app-server-protocol/src/protocol/v1.rs index 3ae995323..81f3cc58a 100644 --- a/codex-rs/app-server-protocol/src/protocol/v1.rs +++ b/codex-rs/app-server-protocol/src/protocol/v1.rs @@ -56,6 +56,12 @@ pub struct InitializeCapabilities { #[serde(rename_all = "camelCase")] pub struct InitializeResponse { pub user_agent: String, + /// Platform family for the running app-server target, for example + /// `"unix"` or `"windows"`. + pub platform_family: String, + /// Operating system for the running app-server target, for example + /// `"macos"`, `"linux"`, or `"windows"`. + pub platform_os: String, } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] diff --git a/codex-rs/app-server/README.md b/codex-rs/app-server/README.md index 4a6cd58cc..fca87b692 100644 --- a/codex-rs/app-server/README.md +++ b/codex-rs/app-server/README.md @@ -74,7 +74,7 @@ Use the thread APIs to create, list, or archive conversations. Drive a conversat ## Initialization -Clients must send a single `initialize` request per transport connection before invoking any other method on that connection, then acknowledge with an `initialized` notification. The server returns the user agent string it will present to upstream services; subsequent requests issued before initialization receive a `"Not initialized"` error, and repeated `initialize` calls on the same connection receive an `"Already initialized"` error. +Clients must send a single `initialize` request per transport connection before invoking any other method on that connection, then acknowledge with an `initialized` notification. The server returns the user agent string it will present to upstream services plus `platformFamily` and `platformOs` strings describing the app-server runtime target; subsequent requests issued before initialization receive a `"Not initialized"` error, and repeated `initialize` calls on the same connection receive an `"Already initialized"` error. `initialize.params.capabilities` also supports per-connection notification opt-out via `optOutNotificationMethods`, which is a list of exact method names to suppress for that connection. Matching is exact (no wildcards/prefixes). Unknown method names are accepted and ignored. diff --git a/codex-rs/app-server/src/message_processor.rs b/codex-rs/app-server/src/message_processor.rs index 7571449da..b0b80c7bf 100644 --- a/codex-rs/app-server/src/message_processor.rs +++ b/codex-rs/app-server/src/message_processor.rs @@ -560,7 +560,11 @@ impl MessageProcessor { } let user_agent = get_codex_user_agent(); - let response = InitializeResponse { user_agent }; + let response = InitializeResponse { + user_agent, + platform_family: std::env::consts::FAMILY.to_string(), + platform_os: std::env::consts::OS.to_string(), + }; self.outgoing .send_response(connection_request_id, response) .await; diff --git a/codex-rs/app-server/tests/suite/v2/initialize.rs b/codex-rs/app-server/tests/suite/v2/initialize.rs index 6b5bf1156..9b5f0cacc 100644 --- a/codex-rs/app-server/tests/suite/v2/initialize.rs +++ b/codex-rs/app-server/tests/suite/v2/initialize.rs @@ -46,9 +46,15 @@ async fn initialize_uses_client_info_name_as_originator() -> Result<()> { let JSONRPCMessage::Response(response) = message else { anyhow::bail!("expected initialize response, got {message:?}"); }; - let InitializeResponse { user_agent } = to_response::(response)?; + let InitializeResponse { + user_agent, + platform_family, + platform_os, + } = to_response::(response)?; assert!(user_agent.starts_with("codex_vscode/")); + assert_eq!(platform_family, std::env::consts::FAMILY); + assert_eq!(platform_os, std::env::consts::OS); Ok(()) } @@ -80,9 +86,15 @@ async fn initialize_respects_originator_override_env_var() -> Result<()> { let JSONRPCMessage::Response(response) = message else { anyhow::bail!("expected initialize response, got {message:?}"); }; - let InitializeResponse { user_agent } = to_response::(response)?; + let InitializeResponse { + user_agent, + platform_family, + platform_os, + } = to_response::(response)?; assert!(user_agent.starts_with("codex_originator_via_env_var/")); + assert_eq!(platform_family, std::env::consts::FAMILY); + assert_eq!(platform_os, std::env::consts::OS); Ok(()) } diff --git a/sdk/python/src/codex_app_server/models.py b/sdk/python/src/codex_app_server/models.py index 7c5bb34de..70c61d44c 100644 --- a/sdk/python/src/codex_app_server/models.py +++ b/sdk/python/src/codex_app_server/models.py @@ -95,3 +95,5 @@ class ServerInfo(BaseModel): class InitializeResponse(BaseModel): serverInfo: ServerInfo | None = None userAgent: str | None = None + platformFamily: str | None = None + platformOs: str | None = None