Sources the model catalog from the optional
llm_db package.
Select it globally, per provider, or at a call site:
config :omni, :models, source: Omni.Sources.LLMDB
# keep one provider on the bundled snapshot
config :omni, Omni.Providers.OpenAI, source: Omni.Sources.ModelsDevllm_db must be in your deps — selecting this source without the package raises at boot:
{:llm_db, "~> 2026.7"}Models are read from llm_db's catalog store and transformed at load time: retired models and those without tool use or text modalities are filtered out (deprecated models are kept — they remain callable), aliases are expanded so friendly ids keep resolving (canonical records win on id collisions), and negative cost sentinels are clamped to zero. Models that still fail to build are skipped with a warning.
Model filtering and data freshness are llm_db's own concerns — Omni
deliberately doesn't wrap them. See llm_db's allow:, deny:, and
sources: configuration.
Providers are matched to catalog entries by their canonical id (the
module's id/0) — llm_db uses the same snake_cased ids, so no translation
is applied:
defmodule MyApp.Providers.Mistral do
use Omni.Provider, id: :mistral, dialect: Omni.Dialects.OpenAICompletions
@impl true
def config do
%{base_url: "https://api.mistral.ai", api_key: {:system, "MISTRAL_API_KEY"}}
end
endDialect resolution
Catalog data is the source of truth, resolved per model: the wire
protocol, then npm package metadata, then a per-gateway fallback. When no
signal resolves, Omni.Provider.build_model/2 falls back to the provider
module's declared dialect; a model with no dialect after that is skipped
with a warning. Known upstream data issue: wire_protocol mislabels some
Responses-only OpenAI models as openai_chat — those models load with the
Completions dialect until it's corrected upstream. (A second upstream
issue, capabilities.reasoning.enabled under-reporting reasoning support,
is systematic — a materialized schema default — and is worked around via
extra signals.)