Expose session analytics state in Responses turn metadata (#44628)

## What changed

Add an optional `analytics_enabled` boolean to `x-codex-turn-metadata`, sourced from the session's selected analytics client. It reports collection state independently of event eligibility or delivery and is omitted without initialized session analytics context.

Reserve `analytics_enabled` so configured or client-supplied metadata cannot override it. Continue accepting existing configurations containing this key while filtering their values from request metadata.

## Testing

Add coverage for the selected analytics client's state taking precedence over turn configuration, reserved-key filtering and compatibility, enabled state in HTTP headers and body metadata, and disabled state in WebSocket prewarm and turn requests.

GitOrigin-RevId: d95375c5ebc27e9d763a7e1a98687a27e4a8d99c
This commit is contained in:
marksteinbrick-oai authored and copyberry committed 2026-09-10 19:41:14 +00:00
1 parent 4150a2c205
commit 9b033b4642
6 files changed
+63 -6

No files matched your search

+1
View File
@@ -647,6 +647,7 @@ impl Session {
CodexResponsesMetadata {
window_number: Some(window_number),
context_window_id: Some(context_window_id),
analytics_enabled: Some(self.services.analytics_events_client.is_enabled()),
history_ingest_requested: turn_context
.config
.token_budget
+18
View File
@@ -97,6 +97,7 @@ use std::collections::BTreeMap;
use tracing::Span;
use crate::connectors::AppInfo;
use crate::responses_metadata::CodexResponsesRequestKind;
use crate::rollout::recorder::RolloutRecorder;
use crate::state::ActiveTurn;
use crate::state::TaskKind;
@@ -6492,6 +6493,23 @@ pub(crate) async fn build_world_state_from_turn_context(
.expect("world state should build")
}
#[tokio::test]
async fn responses_metadata_uses_selected_harness_analytics_client() {
let (mut session, mut turn_context) = make_session_and_context().await;
for enabled in [true, false] {
session.services.analytics_events_client = AnalyticsEventsClient::new(
Arc::clone(&session.services.auth_manager),
turn_context.config.chatgpt_base_url.clone(),
Some(enabled),
);
Arc::make_mut(&mut turn_context.config).analytics_enabled = Some(!enabled);
let metadata = session
.responses_metadata(&turn_context, CodexResponsesRequestKind::Turn)
.await;
assert_eq!(metadata.analytics_enabled, Some(enabled));
}
}
// todo: use online model info
pub(crate) async fn make_session_and_context() -> (Session, TurnContext) {
let (tx_event, _rx_event) = async_channel::unbounded();