Class: Mistri::Usage
- Inherits:
-
Object
- Object
- Mistri::Usage
- Defined in:
- lib/mistri/usage.rb
Overview
Token accounting for an assistant turn, and the dollar cost of those tokens.
input counts only prompt tokens billed at the full rate: cache reads and
writes are separate fields, so a cached token is never double-billed.
reasoning is the thinking slice of output. cache_write_1h is the slice
of cache_write held for an hour, which bills at twice the input rate.
Defined Under Namespace
Classes: Cost
Class Method Summary collapse
Instance Method Summary collapse
- #+(other) ⇒ Object
-
#initialize(input: 0, output: 0, cache_read: 0, cache_write: 0, cache_write_1h: 0, reasoning: 0, cost: Cost.zero) ⇒ Usage
constructor
A new instance of Usage.
- #to_h ⇒ Object
- #total_tokens ⇒ Object
-
#with_cost(rates) ⇒ Object
A copy with cost computed from per-million-token rates.
Constructor Details
#initialize(input: 0, output: 0, cache_read: 0, cache_write: 0, cache_write_1h: 0, reasoning: 0, cost: Cost.zero) ⇒ Usage
Returns a new instance of Usage.
23 24 25 26 |
# File 'lib/mistri/usage.rb', line 23 def initialize(input: 0, output: 0, cache_read: 0, cache_write: 0, cache_write_1h: 0, reasoning: 0, cost: Cost.zero) super end |
Class Method Details
.from_h(hash) ⇒ Object
30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/mistri/usage.rb', line 30 def self.from_h(hash) h = (hash || {}).transform_keys(&:to_s) c = (h["cost"] || {}).transform_keys(&:to_s) new(input: h.fetch("input", 0).to_i, output: h.fetch("output", 0).to_i, cache_read: h.fetch("cache_read", 0).to_i, cache_write: h.fetch("cache_write", 0).to_i, cache_write_1h: h.fetch("cache_write_1h", 0).to_i, reasoning: h.fetch("reasoning", 0).to_i, cost: Cost.new(input: c.fetch("input", 0).to_f, output: c.fetch("output", 0).to_f, cache_read: c.fetch("cache_read", 0).to_f, cache_write: c.fetch("cache_write", 0).to_f, total: c.fetch("total", 0).to_f)) end |
.zero ⇒ Object
28 |
# File 'lib/mistri/usage.rb', line 28 def self.zero = new |
Instance Method Details
#+(other) ⇒ Object
60 61 62 63 64 65 66 67 |
# File 'lib/mistri/usage.rb', line 60 def +(other) self.class.new(input: input + other.input, output: output + other.output, cache_read: cache_read + other.cache_read, cache_write: cache_write + other.cache_write, cache_write_1h: cache_write_1h + other.cache_write_1h, reasoning: reasoning + other.reasoning, cost: cost + other.cost) end |
#to_h ⇒ Object
69 |
# File 'lib/mistri/usage.rb', line 69 def to_h = super.merge(cost: cost.to_h) |
#total_tokens ⇒ Object
43 |
# File 'lib/mistri/usage.rb', line 43 def total_tokens = input + output + cache_read + cache_write |
#with_cost(rates) ⇒ Object
A copy with cost computed from per-million-token rates. The 1h cache-write slice bills at the :cache_write_1h rate when given, else at twice the input rate, matching extended-retention pricing.
48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/mistri/usage.rb', line 48 def with_cost(rates) long = [cache_write_1h, cache_write].min short = cache_write - long computed = { input: rate(rates, :input) * input, output: rate(rates, :output) * output, cache_read: rate(rates, :cache_read) * cache_read, cache_write: (rate(rates, :cache_write) * short) + (long_write_rate(rates) * long) } with(cost: Cost.new(**computed, total: computed.values.sum)) end |