Module: ActiveHarness::Pricing::ModelsDev

Defined in:
lib/active_harness/pricing/models_dev.rb

Overview

Fallback pricing source — fetches model data from models.dev.

Data source:

{project_root}/tmp/active_harness/pricing_models_dev.json — fetched cache (24h TTL)
Returns nil/empty if cache is missing and network is unavailable.

Usage:

Pricing::ModelsDev.find("gpt-4o")
Pricing::ModelsDev.all
Pricing::ModelsDev.update

Constant Summary collapse

MODELS_DEV_URL =
"https://models.dev/api.json"
MEMORY_TTL =

3 days

3 * 86_400
MODELS_DEV_PROVIDER_MAP =
{
  "openai"         => "openai",
  "anthropic"      => "anthropic",
  "google"         => "gemini",
  "google-vertex"  => "vertexai",
  "amazon-bedrock" => "bedrock",
  "deepseek"       => "deepseek",
  "mistral"        => "mistral",
  "openrouter"     => "openrouter",
  "perplexity"     => "perplexity",
  "xai"            => "xai",
  "groq"           => "groq",
  "azure"          => "azure"
}.freeze

Class Method Summary collapse

Class Method Details

.allObject



39
40
41
42
# File 'lib/active_harness/pricing/models_dev.rb', line 39

def all
  ensure_fresh_registry
  registry.map { |raw| build_cost(raw) }
end

.available_providersObject



100
101
102
103
104
105
106
107
# File 'lib/active_harness/pricing/models_dev.rb', line 100

def available_providers
  @available_providers ||= begin
    providers_dir = File.expand_path("../providers", __dir__)
    Dir.glob("#{providers_dir}/*.rb")
      .map { |f| File.basename(f, ".rb") }
      .reject { |n| %w[base custom].include?(n) }
  end
end

.cache_fileObject



96
97
98
# File 'lib/active_harness/pricing/models_dev.rb', line 96

def cache_file
  File.join(project_root, "tmp", "active_harness", "models_dev_pricing.json")
end

.find(model_id) ⇒ Object



44
45
46
47
48
# File 'lib/active_harness/pricing/models_dev.rb', line 44

def find(model_id)
  ensure_fresh_registry
  raw = registry.find { |m| m[:id] == model_id.to_s }
  raw ? build_cost(raw) : nil
end

.for_provider(name) ⇒ Object



54
55
56
57
58
59
# File 'lib/active_harness/pricing/models_dev.rb', line 54

def for_provider(name)
  ensure_fresh_registry
  registry
    .select { |m| m[:provider] == name.to_s }
    .map { |m| build_cost(m) }
end

.preload!Object

Fetches fresh data from models.dev, writes to cache file, loads into memory. Called automatically when memory is stale. Can also be called explicitly.



70
71
72
73
74
75
76
77
78
# File 'lib/active_harness/pricing/models_dev.rb', line 70

def preload!
  update
rescue StandardError
  nil
ensure
  @registry   = load_registry
  @loaded_at  = @registry.empty? ? nil : Time.now
  @provider_names = nil
end

.provider_namesObject



61
62
63
64
65
66
# File 'lib/active_harness/pricing/models_dev.rb', line 61

def provider_names
  @provider_names ||= begin
    ensure_fresh_registry
    registry.map { |m| m[:provider] }.uniq.sort
  end
end

.providersObject



50
51
52
# File 'lib/active_harness/pricing/models_dev.rb', line 50

def providers
  @providers_proxy ||= Pricing::ProvidersProxy.new(self)
end

.reload!Object



89
90
91
92
93
94
# File 'lib/active_harness/pricing/models_dev.rb', line 89

def reload!
  @registry       = nil
  @loaded_at      = nil
  @provider_names = nil
  nil
end

.updateObject



80
81
82
83
84
85
86
87
# File 'lib/active_harness/pricing/models_dev.rb', line 80

def update
  raw_api = fetch_models_dev
  models  = extract_models(raw_api)

  FileUtils.mkdir_p(File.dirname(cache_file))
  File.write(cache_file, JSON.generate(models))
  models.size
end