[bot] Anthropic Messages API: `usage.output_tokens_details.thinking_tokens` not captured in span metrics
Nobody has claimed this yet.
Assessment
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Newbie friendliness
- 72/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Quiet
- Tech stack
- ruby
- Domain
- observability
Research direction
Start with Common.parse_usage_tokens in lib/braintrust/contrib/anthropic/instrumentation/common.rb, then trace its callers in messages.rb and beta_messages.rb, including streaming finalization. Confirm how existing usage fields become span metrics and verify that output_tokens_details.thinking_tokens is captured for both stable and beta Messages API instrumentation.
Written by the indexing model from the issue text.
Description
Summary
Anthropic SDK v1.44.0 added usage.output_tokens_details to Messages API responses. This nested object contains thinking_tokens — the number of output tokens consumed by extended thinking/reasoning. The Braintrust Ruby SDK does not capture this field. Users who enable extended thinking via anthropic.messages.create(thinking: {...}, ...) or via the beta messages API have no visibility into their thinking token consumption.
This is distinct from issue #164 (RubyLLM extended thinking), which covers the ruby_llm gem. This issue covers the direct anthropic gem instrumentation.
What is missing
The Anthropic Messages API now returns:
"usage": {
"input_tokens": 2095,
"output_tokens": 503,
"cache_creation_input_tokens": 2051,
"cache_read_input_tokens": 2051,
"output_tokens_details": {
"thinking_tokens": 312
}
}
output_tokens_details.thinking_tokens is the count of tokens the model generated as internal reasoning (always ≤ output_tokens). Capturing it allows users to:
- Attribute cost to extended thinking vs. standard output
- Diagnose cases where reasoning dominates total output tokens
- Compare thinking token spend across requests
Why it is dropped today
Common.parse_usage_tokens in lib/braintrust/contrib/anthropic/instrumentation/common.rb iterates over the top-level usage hash and skips any value that is not Numeric:
usage_hash.each do |key, value|
next unless value.is_a?(Numeric) # ← skips output_tokens_details (a Hash)
...
end
output_tokens_details maps to {thinking_tokens: 312}, which fails the Numeric check and is silently dropped. No field in the existing field_map covers it.
The same gap applies to both the stable Messages API instrumentation (messages.rb) and the beta Messages API instrumentation (beta_messages.rb), since both delegate to Common.parse_usage_tokens.
Braintrust docs status
not_found — The Braintrust Anthropic integration docs at https://www.braintrust.dev/docs/providers/anthropic list prompt_tokens, completion_tokens, and cache metrics as captured but do not mention thinking tokens or output_tokens_details.
Upstream sources
- Anthropic Messages API reference —
usage.output_tokens_details.thinking_tokensfield: https://platform.claude.com/docs/en/api/messages - Anthropic Ruby SDK changelog — v1.44.0 added
output_tokens_detailsand mid-conversation usage details: https://github.com/anthropics/anthropic-sdk-ruby/blob/main/CHANGELOG.md
Local files inspected
lib/braintrust/contrib/anthropic/instrumentation/common.rb—parse_usage_tokensmethod (lines 14–48): 4-fieldfield_map;Numericguard silently drops nested objects likeoutput_tokens_detailslib/braintrust/contrib/anthropic/instrumentation/messages.rb—set_metrics(line 132) callsCommon.parse_usage_tokens; also captures streaming output viafinalize_stream_spanlib/braintrust/contrib/anthropic/instrumentation/beta_messages.rb— sameparse_usage_tokenscall pattern
- Dominant language
- Ruby
- Stars
- 9
- Forks
- 10
- Avg merge
- 22h 10m
- Merged PRs (30d)
- 6
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.
More from braintrustdata/braintrust-sdk-ruby
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
-
Difficulty 3/5 1-2 days Newbie friendliness 65/100
-
Difficulty 5/5 Over a week Newbie friendliness 38/100
All issues in braintrustdata/braintrust-sdk-ruby
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
googleapis/google-api-ruby-client#28001 · 5 reactions ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 70/100