app-server: Add platform os and family to init response (#14527)

This allows the client to pick os-specific behavior while interacting
with the app server, e.g. to use proper path separators.
This commit is contained in:
Ruslan Nigmatullin
2026-03-13 12:07:54 -07:00
committed by GitHub
parent 3aabce9e0a
commit 50558e6507
8 changed files with 59 additions and 5 deletions

View File

@@ -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.

View File

@@ -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;

View File

@@ -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::<InitializeResponse>(response)?;
let InitializeResponse {
user_agent,
platform_family,
platform_os,
} = to_response::<InitializeResponse>(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::<InitializeResponse>(response)?;
let InitializeResponse {
user_agent,
platform_family,
platform_os,
} = to_response::<InitializeResponse>(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(())
}