From bde9db1375667c50dcc0c2b52532a4e2672571c2 Mon Sep 17 00:00:00 2001 From: jif Date: Wed, 26 Aug 2026 15:09:15 +0000 Subject: [PATCH] Record actual Responses endpoints in tracing spans (#40906) ## Why Responses-compatible requests can use routes other than `/responses`, but their tracing spans reported the default route regardless of the selected endpoint. ## What changed - Populate `api.path` from the selected `ResponsesEndpoint` for HTTP and WebSocket requests. - Retain the endpoint on WebSocket connections so stream-request spans report the same route as connection spans. GitOrigin-RevId: 349eca94b27d4cc3a1adde8b257313506bdaf0f4 --- codex-rs/codex-api/src/endpoint/responses.rs | 4 ++-- codex-rs/codex-api/src/endpoint/responses_websocket.rs | 9 +++++++-- codex-rs/core/src/client.rs | 8 +++++--- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/codex-rs/codex-api/src/endpoint/responses.rs b/codex-rs/codex-api/src/endpoint/responses.rs index 21d3deb928..69a8c686d1 100644 --- a/codex-rs/codex-api/src/endpoint/responses.rs +++ b/codex-rs/codex-api/src/endpoint/responses.rs @@ -96,7 +96,7 @@ impl ResponsesClient { fields( transport = "responses_http", http.method = "POST", - api.path = "responses" + api.path = self.endpoint.path() ) )] pub async fn stream_request( @@ -136,7 +136,7 @@ impl ResponsesClient { fields( transport = "responses_http", http.method = "POST", - api.path = "responses", + api.path = self.endpoint.path(), turn.has_state = turn_state.is_some() ) )] diff --git a/codex-rs/codex-api/src/endpoint/responses_websocket.rs b/codex-rs/codex-api/src/endpoint/responses_websocket.rs index b1e009f908..95d41e0d91 100644 --- a/codex-rs/codex-api/src/endpoint/responses_websocket.rs +++ b/codex-rs/codex-api/src/endpoint/responses_websocket.rs @@ -182,6 +182,7 @@ struct ResponsesWebsocketTimingLogContext { pub struct ResponsesWebsocketConnection { stream: Arc>>, + endpoint: ResponsesEndpoint, // TODO (pakrym): is this the right place for timeout? idle_timeout: Duration, server_reasoning_included: bool, @@ -193,6 +194,7 @@ impl std::fmt::Debug for ResponsesWebsocketConnection { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("ResponsesWebsocketConnection") .field("stream", &"") + .field("endpoint", &self.endpoint) .field("idle_timeout", &self.idle_timeout) .field("server_reasoning_included", &self.server_reasoning_included) .field("server_model", &self.server_model) @@ -208,9 +210,11 @@ impl ResponsesWebsocketConnection { server_reasoning_included: bool, server_model: Option, telemetry: Option>, + endpoint: ResponsesEndpoint, ) -> Self { Self { stream: Arc::new(Mutex::new(Some(stream))), + endpoint, idle_timeout, server_reasoning_included, server_model, @@ -226,7 +230,7 @@ impl ResponsesWebsocketConnection { name = "responses_websocket.stream_request", level = "info", skip_all, - fields(transport = "responses_websocket", api.path = "responses") + fields(transport = "responses_websocket", api.path = self.endpoint.path()) )] pub async fn stream_request( &self, @@ -388,7 +392,7 @@ impl ResponsesWebsocketClient { name = "responses_websocket.connect", level = "info", skip_all, - fields(transport = "responses_websocket", api.path = "responses") + fields(transport = "responses_websocket", api.path = self.endpoint.path()) )] pub async fn connect( &self, @@ -415,6 +419,7 @@ impl ResponsesWebsocketClient { server_reasoning_included, server_model, telemetry, + self.endpoint, )) } diff --git a/codex-rs/core/src/client.rs b/codex-rs/core/src/client.rs index c1768066d4..90b095aa39 100644 --- a/codex-rs/core/src/client.rs +++ b/codex-rs/core/src/client.rs @@ -1416,7 +1416,7 @@ impl ModelClientSession { provider = %self.client.state.provider.info().name, wire_api = %self.client.state.provider.info().wire_api, transport = "responses_websocket", - api.path = "responses", + api.path = params.endpoint.path(), turn.has_metadata_header = params.responses_metadata.has_turn_metadata() ) )] @@ -1504,7 +1504,7 @@ impl ModelClientSession { wire_api = %self.client.state.provider.info().wire_api, transport = "responses_http", http.method = "POST", - api.path = "responses", + api.path = tracing::field::Empty, turn.has_metadata_header = responses_metadata.has_turn_metadata() ) )] @@ -1530,6 +1530,7 @@ impl ModelClientSession { let endpoint = self .client .responses_endpoint(client_setup.auth.as_ref(), &model_info.slug); + tracing::Span::current().record("api.path", endpoint.path()); let transport = self .client .build_api_transport(&client_setup.api_provider, endpoint.path())?; @@ -1657,7 +1658,7 @@ impl ModelClientSession { model = %model_info.slug, wire_api = %self.client.state.provider.info().wire_api, transport = "responses_websocket", - api.path = "responses", + api.path = tracing::field::Empty, turn.has_metadata_header = responses_metadata.has_turn_metadata(), websocket.warmup = warmup ) @@ -1688,6 +1689,7 @@ impl ModelClientSession { let endpoint = self .client .responses_endpoint(client_setup.auth.as_ref(), &model_info.slug); + tracing::Span::current().record("api.path", endpoint.path()); let request_auth_context = AuthRequestTelemetryContext::new( client_setup.auth.as_ref().map(CodexAuth::auth_mode), client_setup.api_auth.as_ref(),