Packages
llm_composer
0.19.3
0.20.2
0.20.1
0.20.0
0.19.6
0.19.5
0.19.4
0.19.3
0.19.2
0.19.1
0.19.0
0.18.2
0.18.1
0.18.0
0.17.1
0.17.0
0.16.2
0.16.1
0.16.0
0.15.0
0.14.2
0.14.1
0.14.0
0.13.1
0.13.0
0.12.3
0.12.2
0.12.0
0.11.2
0.11.1
0.11.0
0.10.0
0.8.0
0.7.0
0.6.0
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.0
0.3.6
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.0
0.1.0
LlmComposer is an Elixir library that facilitates chat interactions with language models, providing tools to handle user messages, generate responses, and execute functions automatically based on model outputs.
Current section
Files
Jump to
Current section
Files
lib/llm_composer/cost/pricing.ex
defmodule LlmComposer.Cost.Pricing do
@moduledoc """
Centralized pricing retrieval and calculation module.
Orchestrates pricing retrieval from multiple sources with priority chain:
1. Explicit pricing from provider options (input_price_per_million, output_price_per_million)
2. Provider-specific APIs:
- OpenRouter API for :open_router provider
- models.dev API for :open_ai, :open_ai_responses, and :google providers
3. Fallback to nil if no pricing source available
"""
alias LlmComposer.Cost.Fetchers.ModelsDev
alias LlmComposer.Cost.Fetchers.OpenRouter
require Logger
@spec fetch_pricing(atom(), keyword()) :: keyword() | nil
def fetch_pricing(provider, opts) do
# Priority chain: explicit opts -> provider-specific API
if explicit_pricing?(opts) do
extract_explicit_pricing(opts)
else
case provider do
:open_router ->
fetch_openrouter_pricing(opts)
provider when provider in [:open_ai, :open_ai_responses, :google, :bedrock] ->
fetch_models_dev_pricing(provider, opts)
_ ->
nil
end
end
end
# Check if explicit pricing is provided in opts
defp explicit_pricing?(opts) do
not is_nil(opts[:input_price_per_million]) and not is_nil(opts[:output_price_per_million])
end
# Extract explicit pricing from opts
defp extract_explicit_pricing(opts) do
pricing = [
input_price_per_million: Decimal.new(opts[:input_price_per_million]),
output_price_per_million: Decimal.new(opts[:output_price_per_million]),
currency: "USD"
]
case opts[:cache_read_price_per_million] do
nil -> pricing
price -> Keyword.put(pricing, :cache_read_price_per_million, Decimal.new(price))
end
end
defp fetch_openrouter_pricing(opts) do
body = Keyword.get(opts, :body)
if is_nil(body) do
nil
else
transform_fetcher_response(OpenRouter.fetch_pricing(body))
end
end
defp fetch_models_dev_pricing(provider, opts)
when provider in [:open_ai, :open_ai_responses, :google, :bedrock] do
model = Keyword.get(opts, :model)
if is_nil(model) do
Logger.warning("No model specified for models.dev pricing fetch")
nil
else
transform_fetcher_response(ModelsDev.fetch_pricing(provider, model))
end
end
defp transform_fetcher_response(
%{
input_price_per_million: input,
output_price_per_million: output
} = pricing
) do
result = [
input_price_per_million: input,
output_price_per_million: output,
currency: "USD"
]
case Map.get(pricing, :cache_read_price_per_million) do
nil -> result
cache_read -> Keyword.put(result, :cache_read_price_per_million, cache_read)
end
end
defp transform_fetcher_response(nil), do: nil
end