LemonAi. Models
(lemon_ai v0.1.0)
View Source
Registry of known AI models with their capabilities and pricing.
This module provides access to model metadata including:
- Model identification (id, name, provider)
- API configuration (api type, base_url)
- Capabilities (reasoning support, input types)
- Pricing (cost per million tokens)
- Limits (context window, max tokens)
Usage
# Get a specific model
model = LemonAi.Models.get_model(:anthropic, "claude-sonnet-4-20250514")
# List all models for a provider
models = LemonAi.Models.get_models(:openai)
# Check capabilities
LemonAi.Models.supports_vision?(model)
LemonAi.Models.supports_reasoning?(model)Model data is defined in per-provider submodules under LemonAi.Models.* and
merged into a single compile-time registry here.
Summary
Functions
Adjust max tokens to accommodate a thinking budget for a given reasoning level.
Clamp a reasoning level, mapping :xhigh to :high for providers that
don't support it.
Find a model by ID across all providers.
Get a specific model by provider and model ID.
Get model IDs for a provider.
Get all models for a provider.
List all known providers.
List all known models across all providers.
List all known models with optional runtime discovery.
Check if two models are equal by comparing both their id and provider. Returns false if either model is nil.
Check if a model supports reasoning/thinking.
Check if a model supports vision (image input).
Check if a model supports the xhigh thinking level.
Types
@type list_models_opt() :: {:discover_openai, boolean()} | {:openai_api_key, String.t()} | {:openai_base_url, String.t()} | {:openai_timeout_ms, pos_integer()}
Functions
@spec adjust_max_tokens_for_thinking( non_neg_integer(), non_neg_integer(), atom(), map() ) :: {non_neg_integer(), non_neg_integer()}
Adjust max tokens to accommodate a thinking budget for a given reasoning level.
Computes the thinking token budget for the requested level (clamping xhigh
to high), then increases base_max_tokens by that amount without exceeding
model_max_tokens. If the resulting max is smaller than the budget, the
budget is reduced to leave at least 1024 output tokens.
Ported from Pi's adjustMaxTokensForThinking.
Parameters
base_max_tokens- The base output token limit before thinkingmodel_max_tokens- The model's hard maximum token limitreasoning_level- One of:minimal,:low,:medium,:high,:xhighcustom_budgets- Optional map overriding default budgets per level
Returns
A tuple {max_tokens, thinking_budget}.
Examples
iex> LemonAi.Models.adjust_max_tokens_for_thinking(8192, 200_000, :high)
{24576, 16384}
iex> LemonAi.Models.adjust_max_tokens_for_thinking(8192, 200_000, :medium, %{medium: 4096})
{12288, 4096}
Clamp a reasoning level, mapping :xhigh to :high for providers that
don't support it.
Examples
iex> LemonAi.Models.clamp_reasoning(:xhigh)
:high
iex> LemonAi.Models.clamp_reasoning(:medium)
:medium
iex> LemonAi.Models.clamp_reasoning(nil)
nil
@spec find_by_id(String.t()) :: LemonAi.Types.Model.t() | nil
Find a model by ID across all providers.
Returns the first matching model found, or nil if no match.
Examples
iex> model = LemonAi.Models.find_by_id("gpt-4o")
iex> model.provider
:openai
iex> LemonAi.Models.find_by_id("nonexistent")
nil
@spec get_model(atom(), String.t()) :: LemonAi.Types.Model.t() | nil
Get a specific model by provider and model ID.
Examples
iex> model = LemonAi.Models.get_model(:anthropic, "claude-sonnet-4-20250514")
iex> model.name
"Claude Sonnet 4"
iex> LemonAi.Models.get_model(:anthropic, "nonexistent")
nil
Get model IDs for a provider.
Examples
iex> ids = LemonAi.Models.get_model_ids(:anthropic)
iex> "claude-sonnet-4-20250514" in ids
true
@spec get_models(atom()) :: [LemonAi.Types.Model.t()]
Get all models for a provider.
Examples
iex> models = LemonAi.Models.get_models(:anthropic)
iex> length(models) > 0
true
iex> LemonAi.Models.get_models(:unknown_provider)
[]
@spec get_providers() :: [atom()]
List all known providers.
Examples
iex> providers = LemonAi.Models.get_providers()
iex> :anthropic in providers
true
@spec list_models() :: [LemonAi.Types.Model.t()]
List all known models across all providers.
Examples
iex> models = LemonAi.Models.list_models()
iex> length(models) > 0
true
@spec list_models([list_models_opt()]) :: [LemonAi.Types.Model.t()]
List all known models with optional runtime discovery.
Options
:discover_openai- When true, query OpenAI/v1/modelsand filter the OpenAI model list to IDs reported as available for the configured key. If discovery fails, returns the static model registry.:openai_api_key- Optional API key override for discovery.:openai_base_url- Optional OpenAI-compatible base URL override.:openai_timeout_ms- Optional request timeout in milliseconds.
@spec models_equal?(LemonAi.Types.Model.t() | nil, LemonAi.Types.Model.t() | nil) :: boolean()
Check if two models are equal by comparing both their id and provider. Returns false if either model is nil.
Ported from Pi's modelsAreEqual.
Examples
iex> model1 = LemonAi.Models.get_model(:anthropic, "claude-sonnet-4-20250514")
iex> model2 = LemonAi.Models.get_model(:anthropic, "claude-sonnet-4-20250514")
iex> LemonAi.Models.models_equal?(model1, model2)
true
iex> model1 = LemonAi.Models.get_model(:anthropic, "claude-sonnet-4-20250514")
iex> model2 = LemonAi.Models.get_model(:openai, "gpt-4o")
iex> LemonAi.Models.models_equal?(model1, model2)
false
iex> LemonAi.Models.models_equal?(nil, model1)
false
@spec supports_reasoning?(LemonAi.Types.Model.t()) :: boolean()
Check if a model supports reasoning/thinking.
Examples
iex> model = LemonAi.Models.get_model(:anthropic, "claude-sonnet-4-20250514")
iex> LemonAi.Models.supports_reasoning?(model)
true
iex> model = LemonAi.Models.get_model(:openai, "gpt-4o")
iex> LemonAi.Models.supports_reasoning?(model)
false
@spec supports_vision?(LemonAi.Types.Model.t()) :: boolean()
Check if a model supports vision (image input).
Examples
iex> model = LemonAi.Models.get_model(:anthropic, "claude-sonnet-4-20250514")
iex> LemonAi.Models.supports_vision?(model)
true
iex> model = LemonAi.Models.get_model(:openai, "o3-mini")
iex> LemonAi.Models.supports_vision?(model)
false
@spec supports_xhigh(LemonAi.Types.Model.t()) :: boolean()
Check if a model supports the xhigh thinking level.
Supported models:
- GPT-5.2 / GPT-5.3 model families
- Anthropic Opus 4.6 models (xhigh maps to adaptive effort "max")
Ported from Pi's model-resolver.
Examples
iex> model = LemonAi.Models.get_model(:openai, "gpt-5.2")
iex> LemonAi.Models.supports_xhigh(model)
true
iex> model = LemonAi.Models.get_model(:anthropic, "claude-opus-4-6")
iex> LemonAi.Models.supports_xhigh(model)
true
iex> model = LemonAi.Models.get_model(:anthropic, "claude-sonnet-4-20250514")
iex> LemonAi.Models.supports_xhigh(model)
false