Add response and conversation IDs to completed-response OTLP usage spans
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.5k
- PR merge metrics
- PR metrics pending
Description
What variant of Codex are you using?
CLI.
What feature would you like to see?
Include two existing IDs on completed-response spans that contain token usage:
gen_ai.response.id: the ID supplied by the provider in the completed response.gen_ai.conversation.id: the existing CodexThreadId.
We collect Codex usage through OTLP. These attributes would let us associate usage with a provider response and group usage by thread across turns and resume. Codex already has both IDs, but the usage spans do not export them.
Example of the requested span attributes, shown as a decoded map:
{
"gen_ai.usage.input_tokens": 30,
"gen_ai.usage.output_tokens": 7,
"gen_ai.response.id": "resp-example",
"gen_ai.conversation.id": "<existing Codex ThreadId>"
}
Expected behavior:
- Export the response ID with the usage from the same completion.
- Omit the response ID attribute when the ID is empty. Do not generate a replacement.
- Keep the conversation ID consistent across turns and resume.
- Use different conversation IDs for separate threads.
- Preserve token values, existing event fields, parser behavior, and exporter settings.
- Add no metric dimensions.
Additional information
The relevant code is the handle_responses span declaration and SessionTelemetry::record_responses. I also checked the completion-recording code at upstream commit 5c5308fc9a9ee789049d646ef11e5400384b9c6f; it still omits both attributes.
A reference implementation and OTLP export test are available in my fork (download patch). The patch applies to 0f7c8608bdce4874acba3f3a4467f1bf8275fecc. Please use or adapt it if helpful. This is a feature request, in line with the contribution policy; no upstream PR is open.
The test sends synthetic responses through Codex and checks the actual OTLP HTTP payload. It covers repeated response IDs, different response IDs with equal usage, empty IDs, existing missing-ID parser behavior, multiple turns, resume, and separate threads.
Validation and known test gaps
Tested on macOS arm64 with Rust 1.95.0. The test is included in the reference commit. From codex-rs:
just test -p codex-core --test all completed_response_identity_reaches_otlp_exporter
The identity test and all telemetry tests passed. The affected-crate run (just test -p codex-core -p codex-otel) had 4,562 passes, one failure, one timeout, and 28 skips. The failure and timeout also occurred without the production fix:
suite::user_shell_cmd::user_shell_command_does_not_set_network_sandbox_env_varshell_snapshot::tests::snapshot_discovers_and_redacts_shell_initialized_credentials
Scoped Clippy passed with an existing unused-import warning. The CLI build and formatting passed. The full workspace was not rerun for this final revision. Linux and Windows were not tested.
Related: #43078 asks about correlation for reasoning-effort completion logs. This request is limited to two existing IDs on completed-response usage spans.
Would the team consider implementing this behavior? We can provide further reproduction details.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the handle_responses span declaration in codex-rs/core/src/session/turn.rs and SessionTelemetry::record_responses in codex-rs/otel/src/events/session_telemetry.rs. Review the linked reference implementation and run just test -p codex-core --test all completed_response_identity_reaches_otlp_exporter. Done means completed-response usage spans export the existing response and thread IDs with the specified empty-ID, resume, and separate-thread behavior while preserving existing telemetry.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- observability-sre
- Issue type
- Feature
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 84/100