Class: Agent::Sessions::Usage

Inherits:
Data
  • Object
show all
Defined in:
lib/agent/sessions/usage.rb

Overview

Token counts an agent reported, for one message or one whole session, normalized to five DISJOINT buckets: input never includes what was read from or written to cache, and output never includes reasoning. Agents disagree here — Codex's input_tokens includes its cached_input_tokens, Claude's does not (both verified against real stores on this machine, 2026-08-24) — and a caller summing across agents needs one rule, not one per agent. Readers do the subtraction; this object only holds the result.

nil means "this format does not record that dimension", and it is load- bearing: absence must never read as zero, for the same reason Agent::Sessions.read raises on a format with no reader. cost is reported by the agent or absent — never derived from a pricing table, which would go stale in a gem and is a consumer's decision anyway.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(input: nil, output: nil, cache_read: nil, cache_creation: nil, reasoning: nil, cost: nil) ⇒ Usage

Returns a new instance of Usage.



19
20
21
# File 'lib/agent/sessions/usage.rb', line 19

def initialize(input: nil, output: nil, cache_read: nil, cache_creation: nil, reasoning: nil, cost: nil)
  super
end

Instance Attribute Details

#cache_creationObject (readonly)

Returns the value of attribute cache_creation

Returns:

  • (Object)

    the current value of cache_creation



18
19
20
# File 'lib/agent/sessions/usage.rb', line 18

def cache_creation
  @cache_creation
end

#cache_readObject (readonly)

Returns the value of attribute cache_read

Returns:

  • (Object)

    the current value of cache_read



18
19
20
# File 'lib/agent/sessions/usage.rb', line 18

def cache_read
  @cache_read
end

#costObject (readonly)

Returns the value of attribute cost

Returns:

  • (Object)

    the current value of cost



18
19
20
# File 'lib/agent/sessions/usage.rb', line 18

def cost
  @cost
end

#inputObject (readonly)

Returns the value of attribute input

Returns:

  • (Object)

    the current value of input



18
19
20
# File 'lib/agent/sessions/usage.rb', line 18

def input
  @input
end

#outputObject (readonly)

Returns the value of attribute output

Returns:

  • (Object)

    the current value of output



18
19
20
# File 'lib/agent/sessions/usage.rb', line 18

def output
  @output
end

#reasoningObject (readonly)

Returns the value of attribute reasoning

Returns:

  • (Object)

    the current value of reasoning



18
19
20
# File 'lib/agent/sessions/usage.rb', line 18

def reasoning
  @reasoning
end

Instance Method Details

#+(other) ⇒ Object

Sums dimension-wise, keeping the nil/zero distinction: nil + nil stays nil ("neither side records this"), nil + n is n — one recorded value is a real value, not a value plus an unknown, because per-message absence under a format that does record the dimension means "none reported for this message", the one place absence and zero do coincide.



28
29
30
31
32
33
# File 'lib/agent/sessions/usage.rb', line 28

def +(other)
  self.class.new(input: sum(input, other.input), output: sum(output, other.output),
                 cache_read: sum(cache_read, other.cache_read),
                 cache_creation: sum(cache_creation, other.cache_creation),
                 reasoning: sum(reasoning, other.reasoning), cost: sum(cost, other.cost))
end