Module: OmniAI::OpenAI::Chat::UsageSerializer

Defined in:
lib/omniai/openai/chat/usage_serializer.rb

Overview

Overrides usage deserialize to read OpenAI's reasoning breakdown.

Class Method Summary collapse

Class Method Details

.deserialize(data) ⇒ OmniAI::Chat::Usage

OpenAI already counts reasoning inside output_tokens and reports the breakdown alongside it, so the breakdown is read into thinking_tokens and the output count is left exactly as reported. Adding the two together would double count.

This gem targets the Responses API (/responses), whose usage object reports the breakdown at output_tokens_details.reasoning_tokens. The Chat Completions vocabulary from the previous API generation (completion_tokens_details) is deliberately not read — this gem never receives it.

Parameters:

  • data (Hash)

Returns:

  • (OmniAI::Chat::Usage)


18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/omniai/openai/chat/usage_serializer.rb', line 18

def self.deserialize(data, *)
  # Deserialize without a context so the generic flat parse runs rather than recursing into this method.
  usage = OmniAI::Chat::Usage.deserialize(data)

  # Only overwrite when the vendor container is actually present. A payload produced by `Usage#serialize`
  # carries base's own `thinking_tokens` key and no `output_tokens_details`, so assigning unconditionally
  # would clobber a correctly-parsed value with nil and break the round-trip. `unless nil?` rather than
  # `||=`, so a reported zero from the wire still wins over base's nil.
  reasoning_tokens = data.dig("output_tokens_details", "reasoning_tokens")
  usage.thinking_tokens = reasoning_tokens unless reasoning_tokens.nil?

  usage
end