Add gen_ai.usage.raw attribute to OpenAI spans#1777
Conversation
Serializes the full usage object (including token detail breakdowns like cached_tokens and reasoning_tokens) via model_dump(exclude_none=True). Applied in the shared usage extraction path so all OpenAI response types (chat, completions, embeddings, responses API) get it.
| if usage is not None and hasattr(usage, 'model_dump'): | ||
| span.set_attribute(USAGE_RAW, usage.model_dump(exclude_none=True)) |
There was a problem hiding this comment.
🚩 USAGE_RAW not set for streaming responses
The USAGE_RAW attribute is only set in the non-streaming on_response path (openai.py:621-622). For streaming responses, the flow goes through StreamState.get_attributes() instead (via record_streaming in llm_provider.py:217), and none of the stream state classes (OpenaiChatCompletionStreamState, OpenaiCompletionStreamState, OpenaiResponsesStreamState) set USAGE_RAW. This is consistent with how INPUT_TOKENS and OUTPUT_TOKENS are also not set in stream states — but it means streaming responses won't have the raw usage data. This may be intentional since streaming usage data is often incomplete or unavailable, but worth noting if the goal is comprehensive usage tracking.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Intentional scope limiting — this PR covers OpenAI non-streaming only. Streaming and Anthropic are planned as follow-up work.
| if usage is not None and hasattr(usage, 'model_dump'): | ||
| span.set_attribute(USAGE_RAW, usage.model_dump(exclude_none=True)) |
There was a problem hiding this comment.
🚩 USAGE_RAW not added to Anthropic integration
The USAGE_RAW attribute is only added to the OpenAI integration. The Anthropic integration (anthropic.py:342-344) also has usage data (response.usage) that is a Pydantic model with model_dump, but does not set USAGE_RAW. If the goal is to capture raw usage across all providers, Anthropic should be updated similarly. This may be intentional scope limiting for this PR.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Intentional scope limiting — Anthropic support is planned as follow-up work.
Summary
gen_ai.usage.rawspan attribute containing the full serialized usage object from OpenAI responses (viamodel_dump(exclude_none=True))cached_tokens,reasoning_tokens) that are lost by the existing flatinput_tokens/output_tokensattributesTest plan
🤖 Generated with Claude Code
Summary by cubic
Adds the
gen_ai.usage.rawspan attribute to store the full OpenAI usage object, preserving detailed token metrics. Applies to all non‑streaming responses so spans include rich usage data across chat, completions, embeddings, and the responses API.USAGE_RAWsemconv key (gen_ai.usage.raw) and set it viausage.model_dump(exclude_none=True).Written for commit 5ef3d8b. Summary will update on new commits.