[codex-analytics] add session source to client metadata (#17374)

## Summary

Adds `thread_source` field to the existing Codex turn metadata sent to
Responses API
- Sends `thread_source: "user"` for user-initiated sessions: CLI, VS
Code, and Exec
- Sends `thread_source: "subagent"` for subagent sessions
- Omits `thread_source` for MCP, custom, and unknown session sources
- Uses the existing turn metadata transport:
  - HTTP requests send through the `x-codex-turn-metadata` header
- WebSocket `response.create` requests send through
`client_metadata["x-codex-turn-metadata"]`

## Testing
- `cargo test -p codex-protocol
session_source_thread_source_name_classifies_user_and_subagent_sources`
- `cargo test -p codex-core turn_metadata_state`
- `cargo test -p codex-core --test responses_headers
responses_stream_includes_turn_metadata_header_for_git_workspace_e2e --
--nocapture`
This commit is contained in:
marksteinbrick-oai
2026-04-14 08:55:12 -07:00
committed by GitHub
parent f030ab62eb
commit 61fe23159e
8 changed files with 94 additions and 13 deletions

View File

@@ -1209,8 +1209,9 @@ async fn responses_websocket_forwards_turn_metadata_on_initial_and_incremental_c
let harness = websocket_harness(&server).await;
let mut client_session = harness.client.new_session();
let first_turn_metadata = r#"{"turn_id":"turn-123","sandbox":"workspace-write"}"#;
let enriched_turn_metadata = r#"{"turn_id":"turn-123","sandbox":"workspace-write","workspaces":[{"root_path":"/tmp/repo","latest_git_commit_hash":"abc123","associated_remote_urls":["git@github.com:openai/codex.git"],"has_changes":true}]}"#;
let first_turn_metadata =
r#"{"turn_id":"turn-123","thread_source":"user","sandbox":"workspace-write"}"#;
let enriched_turn_metadata = r#"{"turn_id":"turn-123","thread_source":"user","sandbox":"workspace-write","workspaces":[{"root_path":"/tmp/repo","latest_git_commit_hash":"abc123","associated_remote_urls":["git@github.com:openai/codex.git"],"has_changes":true}]}"#;
let prompt_one = prompt_with_input(vec![message_item("hello")]);
let prompt_two = prompt_with_input(vec![
message_item("hello"),
@@ -1259,6 +1260,8 @@ async fn responses_websocket_forwards_turn_metadata_on_initial_and_incremental_c
assert_eq!(first_metadata["turn_id"].as_str(), Some("turn-123"));
assert_eq!(second_metadata["turn_id"].as_str(), Some("turn-123"));
assert_eq!(first_metadata["thread_source"].as_str(), Some("user"));
assert_eq!(second_metadata["thread_source"].as_str(), Some("user"));
assert_eq!(
second_metadata["workspaces"][0]["has_changes"].as_bool(),
Some(true)