Module: Mistri::Models

Defined in:
lib/mistri/models.rb

Overview

The model catalog: capability data for known models, with graceful passthrough for unknown ones. An id missing here still works everywhere; the catalog supplies capability defaults and paid direct-API pricing, so a brand-new model remains usable unless the host requests a cost ceiling.

Defined Under Namespace

Classes: Model, RateCard, Schedule

Constant Summary collapse

EMPTY_PRICING =
[].freeze
EPOCH =
Time.at(0).utc.freeze
CATALOG =
[
  ["claude-fable-5", :anthropic, 128_000, 1_000_000, :adaptive,
   [price(input: 10.0, output: 50.0, cache_read: 1.0, cache_write: 12.5)]],
  ["claude-opus-4-8", :anthropic, 128_000, 1_000_000, :adaptive,
   [price(input: 5.0, output: 25.0, cache_read: 0.5, cache_write: 6.25)]],
  ["claude-opus-4-7", :anthropic, 128_000, 1_000_000, :adaptive,
   [price(input: 5.0, output: 25.0, cache_read: 0.5, cache_write: 6.25)]],
  ["claude-opus-4-6", :anthropic, 128_000, 1_000_000, :adaptive,
   [price(input: 5.0, output: 25.0, cache_read: 0.5, cache_write: 6.25)]],
  ["claude-sonnet-5", :anthropic, 128_000, 1_000_000, :adaptive,
   [price(input: 2.0, output: 10.0, cache_read: 0.2, cache_write: 2.5),
    price({ input: 3.0, output: 15.0, cache_read: 0.3, cache_write: 3.75 },
          from: Time.utc(2026, 9, 1))]],
  ["claude-sonnet-4-6", :anthropic, 128_000, 1_000_000, :adaptive,
   [price(input: 3.0, output: 15.0, cache_read: 0.3, cache_write: 3.75)]],
  ["claude-haiku-4-5", :anthropic, 64_000, 200_000, :budget,
   [price(input: 1.0, output: 5.0, cache_read: 0.1, cache_write: 1.25)]],
  ["gpt-5.6-sol", :openai, 128_000, 1_050_000, :effort,
   [price({ input: 5.0, output: 30.0, cache_read: 0.5, cache_write: 6.25 },
          above: 272_000,
          higher: { input: 10.0, output: 45.0, cache_read: 1.0,
                    cache_write: 12.5 })]],
  ["gpt-5.6-terra", :openai, 128_000, 1_050_000, :effort,
   [price({ input: 2.5, output: 15.0, cache_read: 0.25, cache_write: 3.125 },
          above: 272_000,
          higher: { input: 5.0, output: 22.5, cache_read: 0.5,
                    cache_write: 6.25 })]],
  ["gpt-5.6-luna", :openai, 128_000, 1_050_000, :effort,
   [price({ input: 1.0, output: 6.0, cache_read: 0.1, cache_write: 1.25 },
          above: 272_000,
          higher: { input: 2.0, output: 9.0, cache_read: 0.2,
                    cache_write: 2.5 })]],
  ["gpt-5.5", :openai, 128_000, 1_050_000, :effort,
   [price({ input: 5.0, output: 30.0, cache_read: 0.5 },
          above: 272_000, higher: { input: 10.0, output: 45.0, cache_read: 1.0 })]],
  ["gpt-5.4", :openai, 128_000, 1_050_000, :effort,
   [price({ input: 2.5, output: 15.0, cache_read: 0.25 },
          above: 272_000, higher: { input: 5.0, output: 22.5, cache_read: 0.5 })]],
  ["gpt-5-nano", :openai, 128_000, 400_000, :effort,
   [price(input: 0.05, output: 0.4, cache_read: 0.005)]],
  ["gemini-3.5-flash", :gemini, 65_536, 1_048_576, :level,
   [price(input: 1.5, output: 9.0, cache_read: 0.15)]],
  ["gemini-3.1-pro-preview", :gemini, 65_536, 1_048_576, :level,
   [price({ input: 2.0, output: 12.0, cache_read: 0.2 },
          above: 200_000, higher: { input: 4.0, output: 18.0, cache_read: 0.4 })]],
  ["gemini-2.5-pro", :gemini, 65_536, 1_048_576, :budget,
   [price({ input: 1.25, output: 10.0, cache_read: 0.125 },
          above: 200_000, higher: { input: 2.5, output: 15.0, cache_read: 0.25 })]],
  ["gemini-2.5-flash", :gemini, 65_536, 1_048_576, :budget,
   [price(input: 0.3, output: 2.5, cache_read: 0.03)]]
].to_h do |row|
  id, provider, max_output, context_window, thinking, pricing = row
  [id, Model.new(id:, provider:, max_output:, context_window:, thinking:, pricing:)]
end.freeze
ALIASES =
{ "gpt-5.6" => "gpt-5.6-sol" }.freeze

Class Method Summary collapse

Class Method Details

.find(id) ⇒ Object

Published family aliases and dated ids resolve to their canonical entry.



158
159
160
161
162
163
164
# File 'lib/mistri/models.rb', line 158

def self.find(id)
  exact = CATALOG[id]
  return exact if exact

  base = id.to_s.sub(/-\d{8}\z/, "").sub(/-\d{4}-\d{2}-\d{2}\z/, "")
  CATALOG[ALIASES.fetch(base, base)]
end

.max_output(id) ⇒ Object



166
# File 'lib/mistri/models.rb', line 166

def self.max_output(id) = find(id)&.max_output

.priced?(id) ⇒ Boolean

Returns:

  • (Boolean)


179
# File 'lib/mistri/models.rb', line 179

def self.priced?(id) = find(id)&.priced? || false

.rates(id, usage: nil, at: Time.now) ⇒ Object



177
# File 'lib/mistri/models.rb', line 177

def self.rates(id, usage: nil, at: Time.now) = find(id)&.rates(usage:, at:)

.shared_output(id) ⇒ Object

Output capacity that occupies the published context limit. Gemini's output limit is independent, so its compaction headroom is input-only.



170
171
172
173
# File 'lib/mistri/models.rb', line 170

def self.shared_output(id)
  model = find(id)
  model&.max_output unless model&.provider == :gemini
end

.thinking(id) ⇒ Object



175
# File 'lib/mistri/models.rb', line 175

def self.thinking(id) = find(id)&.thinking