Class: OmniAI::Chat::Usage
- Inherits:
-
Object
- Object
- OmniAI::Chat::Usage
- Defined in:
- lib/omniai/chat/usage.rb
Overview
The usage of a chat in terms of tokens (input / output / total).
Two invariants hold across every provider:
thinking_tokensis a subset ofoutput_tokens, never an addition to it. Providers either fold reasoning into their output count already (reporting the breakdown separately) or report it separately and have it added in by their own serializer. Addingthinking_tokenstooutput_tokensdouble counts.total_tokensmay exceedinput_tokens + output_tokens. Providers count buckets this class does not model — cached input, tool-use prompts — so the reported total is authoritative and is never recomputed from the parts. It may also benil: some providers report no total at all.
Provider-specific vocabulary is read by that provider's own :usage deserializer, not here. This class reads
only its own keys and the flat OpenAI-compatible aliases the base client speaks.
Instance Attribute Summary collapse
- #input_tokens ⇒ Integer?
- #output_tokens ⇒ Integer?
-
#thinking_tokens ⇒ Integer?
The subset of
output_tokensa provider attributes to internal reasoning ("thinking"). - #total_tokens ⇒ Integer?
Class Method Summary collapse
Instance Method Summary collapse
-
#initialize(input_tokens:, output_tokens:, total_tokens:, thinking_tokens: nil) ⇒ Usage
constructor
A new instance of Usage.
- #inspect ⇒ String
- #serialize(context: nil) ⇒ Hash
Constructor Details
#initialize(input_tokens:, output_tokens:, total_tokens:, thinking_tokens: nil) ⇒ Usage
Returns a new instance of Usage.
39 40 41 42 43 44 |
# File 'lib/omniai/chat/usage.rb', line 39 def initialize(input_tokens:, output_tokens:, total_tokens:, thinking_tokens: nil) @input_tokens = input_tokens @output_tokens = output_tokens @total_tokens = total_tokens @thinking_tokens = thinking_tokens end |
Instance Attribute Details
#input_tokens ⇒ Integer?
20 21 22 |
# File 'lib/omniai/chat/usage.rb', line 20 def input_tokens @input_tokens end |
#output_tokens ⇒ Integer?
23 24 25 |
# File 'lib/omniai/chat/usage.rb', line 23 def output_tokens @output_tokens end |
#thinking_tokens ⇒ Integer?
The subset of output_tokens a provider attributes to internal reasoning ("thinking"). nil when the
provider does not report a breakdown — which is distinct from 0, meaning the provider reported that no
reasoning occurred.
33 34 35 |
# File 'lib/omniai/chat/usage.rb', line 33 def thinking_tokens @thinking_tokens end |
#total_tokens ⇒ Integer?
26 27 28 |
# File 'lib/omniai/chat/usage.rb', line 26 def total_tokens @total_tokens end |
Class Method Details
.deserialize(data, context: nil) ⇒ OmniAI::Chat::Usage
58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/omniai/chat/usage.rb', line 58 def self.deserialize(data, context: nil) deserialize = context&.deserializer(:usage) return deserialize.call(data, context:) if deserialize input_tokens = data["input_tokens"] || data["prompt_tokens"] output_tokens = data["output_tokens"] || data["completion_tokens"] total_tokens = data["total_tokens"] thinking_tokens = data["thinking_tokens"] new(input_tokens:, output_tokens:, total_tokens:, thinking_tokens:) end |
Instance Method Details
#inspect ⇒ String
47 48 49 50 51 52 |
# File 'lib/omniai/chat/usage.rb', line 47 def inspect text = "#<#{self.class.name} input_tokens=#{input_tokens} output_tokens=#{output_tokens} " \ "total_tokens=#{total_tokens}" text += " thinking_tokens=#{thinking_tokens}" unless thinking_tokens.nil? "#{text}>" end |
#serialize(context: nil) ⇒ Hash
73 74 75 76 77 78 79 80 81 82 |
# File 'lib/omniai/chat/usage.rb', line 73 def serialize(context: nil) serialize = context&.serializer(:usage) return serialize.call(self, context:) if serialize { input_tokens:, output_tokens:, total_tokens:, }.tap { |data| data[:thinking_tokens] = thinking_tokens unless thinking_tokens.nil? } end |