Module: ActiveHarness::Costs
- Defined in:
- lib/active_harness/costs.rb
Overview
Provides access to AI model pricing data, filtered to providers supported by ActiveHarness (files present in lib/active_harness/providers/).
Data source priority:
1. {project_root}/tmp/active_harness/costs.json — fetched cache (refreshed once per day)
2. lib/active_harness/data/models.json — bundled fallback (ships with gem)
Usage:
# Fetch fresh data and save to tmp cache (also called automatically when stale)
ActiveHarness::Costs.update
# All models (auto-updates cache if missing or older than 24h)
ActiveHarness::Costs.all
# Single model by ID
ActiveHarness::Costs.find("gpt-4o")
# By provider — method or bracket syntax
ActiveHarness::Costs.providers.openai
ActiveHarness::Costs.providers[:anthropic]
# List providers that have data
ActiveHarness::Costs.providers.list
Defined Under Namespace
Classes: ModelCost, ProvidersProxy
Constant Summary collapse
- BUNDLED_DATA_FILE =
File.("data/models.json", __dir__).freeze
- MODELS_DEV_URL =
"https://models.dev/api.json"- CACHE_TTL =
24 hours in seconds
86_400- MODELS_DEV_PROVIDER_MAP =
Maps models.dev provider keys → ActiveHarness provider names. Only entries whose value matches a file in providers/ will be kept.
{ "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
-
.all ⇒ Object
Returns pricing data for all models from supported providers.
-
.available_providers ⇒ Object
Names of providers supported by ActiveHarness (derived from providers/ directory).
-
.cache_file ⇒ Object
Path to the per-project cache file.
-
.find(model_id) ⇒ Object
Returns pricing data for a single model by ID, or nil if not found.
-
.for_provider(name) ⇒ Object
Returns pricing data for all models from the given provider.
-
.provider_names ⇒ Object
Returns a sorted list of provider names that have data.
-
.providers ⇒ Object
Returns a ProvidersProxy for provider-scoped access.
-
.reload! ⇒ Object
Reloads registry from disk on next access.
-
.update ⇒ Object
Fetches fresh pricing data from models.dev, filters to supported providers, and writes the result to Costs.project_root/tmp/active_harness/costs.json.
Class Method Details
.all ⇒ Object
Returns pricing data for all models from supported providers. Automatically fetches fresh data if the cache is missing or older than 24h.
102 103 104 105 |
# File 'lib/active_harness/costs.rb', line 102 def all ensure_fresh_registry registry.map { |raw| build_cost(raw) } end |
.available_providers ⇒ Object
Names of providers supported by ActiveHarness (derived from providers/ directory).
162 163 164 165 166 167 168 169 |
# File 'lib/active_harness/costs.rb', line 162 def available_providers @available_providers ||= begin providers_dir = File.("providers", __dir__) Dir.glob("#{providers_dir}/*.rb") .map { |f| File.basename(f, ".rb") } .reject { |n| %w[base custom].include?(n) } end end |
.cache_file ⇒ Object
Path to the per-project cache file.
157 158 159 |
# File 'lib/active_harness/costs.rb', line 157 def cache_file File.join(project_root, "tmp", "active_harness", "costs.json") end |
.find(model_id) ⇒ Object
Returns pricing data for a single model by ID, or nil if not found.
108 109 110 111 112 |
# File 'lib/active_harness/costs.rb', line 108 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
Returns pricing data for all models from the given provider.
120 121 122 123 124 125 |
# File 'lib/active_harness/costs.rb', line 120 def for_provider(name) ensure_fresh_registry registry .select { |m| m[:provider] == name.to_s } .map { |m| build_cost(m) } end |
.provider_names ⇒ Object
Returns a sorted list of provider names that have data.
128 129 130 131 132 133 |
# File 'lib/active_harness/costs.rb', line 128 def provider_names @provider_names ||= begin ensure_fresh_registry registry.map { |m| m[:provider] }.uniq.sort end end |
.providers ⇒ Object
Returns a ProvidersProxy for provider-scoped access.
115 116 117 |
# File 'lib/active_harness/costs.rb', line 115 def providers @providers_proxy ||= ProvidersProxy.new end |
.reload! ⇒ Object
Reloads registry from disk on next access.
150 151 152 153 154 |
# File 'lib/active_harness/costs.rb', line 150 def reload! @registry = nil @provider_names = nil nil end |
.update ⇒ Object
Fetches fresh pricing data from models.dev, filters to supported providers, and writes the result to project_root/tmp/active_harness/costs.json. Returns the number of models saved, or raises on HTTP failure.
138 139 140 141 142 143 144 145 146 147 |
# File 'lib/active_harness/costs.rb', line 138 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)) reload! models.size end |