[providers.openrouter]
display_name = "OpenRouter"
adapter = "openai_compatible"
api_key_url = "https://openrouter.ai/keys"
base_url = "https://openrouter.ai/api/v1"
priority = 25
enabled = false

[providers.openrouter.auth]
credentials = ["env:OPENROUTER_API_KEY", "vault:OPENROUTER_API_KEY"]

# Attribution headers (HTTP-Referer, X-Title) are NOT sent by default.
# Self-hosted Fabro installations stay anonymous on OpenRouter's public
# leaderboard unless the operator opts in. To advertise, add to
# settings.toml:
#
#   [llm.providers.openrouter.extra_headers]
#   "HTTP-Referer" = "https://your-site.example"
#   "X-Title" = "Your App"
#
# To enable OpenRouter, add the following to ~/.fabro/settings.toml:
#
# [llm.providers.openrouter]
# enabled = true
#
# Then run `fabro provider login openrouter` to store the API key,
# or set the OPENROUTER_API_KEY environment variable.

# ---------- Anthropic via OpenRouter ----------
#
# Claude models bill Anthropic-style (cache read/write pricing), so these
# rows override the provider's OpenAI-default billing_policy. Costs are
# best-effort estimates; OpenRouter returns the authoritative usage.cost
# in-band on every response.

[providers.openrouter.models."claude-fable-5"]
api_id = "anthropic/claude-fable-5"
display_name = "Claude Fable 5 (via OpenRouter)"
family = "claude-5"
billing_policy = "anthropic"
aliases = ["fable", "claude-fable"]
agent_profile = "claude-5"

[providers.openrouter.models."claude-fable-5".limits]
context_window = 1000000
max_output = 128000

[providers.openrouter.models."claude-fable-5".features]
tools = true
vision = true
reasoning = true
reasoning_effort = "always_adaptive"
prompt_cache = true
cache_control_breakpoints = true
sampling_params = false

[providers.openrouter.models."claude-fable-5".costs]
input_cost_per_mtok = 10.0
output_cost_per_mtok = 50.0
cache_input_cost_per_mtok = 1.0

[providers.openrouter.models."claude-opus-5"]
api_id = "anthropic/claude-opus-5"
display_name = "Claude Opus 5 (via OpenRouter)"
family = "claude-5"
billing_policy = "anthropic"
training = "2026-05-01"
knowledge_cutoff = "May 2026"
aliases = ["opus", "claude-opus"]
agent_profile = "claude-5"

[providers.openrouter.models."claude-opus-5".limits]
context_window = 1000000
max_output = 128000

[providers.openrouter.models."claude-opus-5".features]
tools = true
vision = true
reasoning = true
reasoning_effort = "levels"
prompt_cache = true
cache_control_breakpoints = true
sampling_params = false

[providers.openrouter.models."claude-opus-5".costs]
input_cost_per_mtok = 5.0
output_cost_per_mtok = 25.0
cache_input_cost_per_mtok = 0.5

[providers.openrouter.models."claude-sonnet-5"]
api_id = "anthropic/claude-sonnet-5"
display_name = "Claude Sonnet 5 (via OpenRouter)"
family = "claude-5"
billing_policy = "anthropic"
training = "2026-01-01"
knowledge_cutoff = "Jan 2026"
default = true
aliases = ["sonnet", "claude-sonnet"]
agent_profile = "claude-5"

[providers.openrouter.models."claude-sonnet-5".limits]
context_window = 1000000
max_output = 128000

[providers.openrouter.models."claude-sonnet-5".features]
tools = true
vision = true
reasoning = true
reasoning_effort = "levels"
prompt_cache = true
cache_control_breakpoints = true
sampling_params = false

# Current introductory rate. OpenRouter's authoritative in-band usage.cost
# supersedes this estimate on completed responses.
[providers.openrouter.models."claude-sonnet-5".costs]
input_cost_per_mtok = 2.0
output_cost_per_mtok = 10.0
cache_input_cost_per_mtok = 0.2

[providers.openrouter.models."claude-opus-4-8"]
api_id = "anthropic/claude-opus-4.8"
display_name = "Claude Opus 4.8 (via OpenRouter)"
family = "claude-4"
billing_policy = "anthropic"
training = "2026-01-01"
knowledge_cutoff = "Jan 2026"

[providers.openrouter.models."claude-opus-4-8".limits]
context_window = 1000000
max_output = 128000

[providers.openrouter.models."claude-opus-4-8".features]
tools = true
vision = true
reasoning = true
reasoning_effort = "levels"
prompt_cache = true
cache_control_breakpoints = true
sampling_params = false

[providers.openrouter.models."claude-opus-4-8".costs]
input_cost_per_mtok = 5.0
output_cost_per_mtok = 25.0
cache_input_cost_per_mtok = 0.5

[providers.openrouter.models."claude-opus-4-7"]
api_id = "anthropic/claude-opus-4.7"
display_name = "Claude Opus 4.7 (via OpenRouter)"
family = "claude-4"
billing_policy = "anthropic"

[providers.openrouter.models."claude-opus-4-7".limits]
context_window = 1000000
max_output = 128000

[providers.openrouter.models."claude-opus-4-7".features]
tools = true
vision = true
reasoning = true
prompt_cache = true
cache_control_breakpoints = true

[providers.openrouter.models."claude-opus-4-7".costs]
input_cost_per_mtok = 5.0
output_cost_per_mtok = 25.0
cache_input_cost_per_mtok = 0.5

[providers.openrouter.models."claude-sonnet-4-6"]
api_id = "anthropic/claude-sonnet-4.6"
display_name = "Claude Sonnet 4.6 (via OpenRouter)"
family = "claude-4"
billing_policy = "anthropic"

[providers.openrouter.models."claude-sonnet-4-6".limits]
context_window = 1000000
max_output = 64000

[providers.openrouter.models."claude-sonnet-4-6".features]
tools = true
vision = true
reasoning = true
prompt_cache = true
cache_control_breakpoints = true

[providers.openrouter.models."claude-sonnet-4-6".costs]
input_cost_per_mtok = 3.0
output_cost_per_mtok = 15.0
cache_input_cost_per_mtok = 0.3

[providers.openrouter.models."claude-haiku-4-5"]
api_id = "anthropic/claude-haiku-4.5"
display_name = "Claude Haiku 4.5 (via OpenRouter)"
family = "claude-4"
billing_policy = "anthropic"
small_default = true
aliases = ["haiku", "claude-haiku"]

[providers.openrouter.models."claude-haiku-4-5".limits]
context_window = 200000
max_output = 8192

[providers.openrouter.models."claude-haiku-4-5".features]
tools = true
vision = true
reasoning = false
prompt_cache = true
cache_control_breakpoints = true

[providers.openrouter.models."claude-haiku-4-5".costs]
input_cost_per_mtok = 1.0
output_cost_per_mtok = 5.0
cache_input_cost_per_mtok = 0.1

# ---------- OpenAI via OpenRouter ----------

# GPT-5.6 entries use OpenRouter's base rates below the 272k-token
# long-context threshold. Authoritative in-band usage.cost covers
# long-context and cache-write pricing.

[providers.openrouter.models."gpt-5.6-sol"]
api_id = "openai/gpt-5.6-sol"
display_name = "GPT-5.6 Sol (via OpenRouter)"
family = "gpt-5"
training = "2026-02-16"
knowledge_cutoff = "February 16, 2026"
aliases = ["sol", "gpt-sol", "gpt56-sol", "gpt-56-sol", "gpt-5.6", "gpt56", "gpt-56"]
# Same narrow Codex tool set as on the openai provider; the gateway does not
# change what the model was trained against.
agent_profile = "gpt56"

[providers.openrouter.models."gpt-5.6-sol".limits]
context_window = 1050000
max_output = 128000

[providers.openrouter.models."gpt-5.6-sol".features]
tools = true
vision = true
reasoning = true
reasoning_effort = "levels"
prompt_cache = true
sampling_params = false

[providers.openrouter.models."gpt-5.6-sol".costs]
input_cost_per_mtok = 5.0
output_cost_per_mtok = 30.0
cache_input_cost_per_mtok = 0.5

[providers.openrouter.models."gpt-5.6-terra"]
api_id = "openai/gpt-5.6-terra"
display_name = "GPT-5.6 Terra (via OpenRouter)"
family = "gpt-5"
training = "2026-02-16"
knowledge_cutoff = "February 16, 2026"
aliases = ["terra", "gpt-terra", "gpt56-terra", "gpt-56-terra"]
agent_profile = "gpt56"

[providers.openrouter.models."gpt-5.6-terra".limits]
context_window = 1050000
max_output = 128000

[providers.openrouter.models."gpt-5.6-terra".features]
tools = true
vision = true
reasoning = true
reasoning_effort = "levels"
prompt_cache = true
sampling_params = false

[providers.openrouter.models."gpt-5.6-terra".costs]
input_cost_per_mtok = 2.5
output_cost_per_mtok = 15.0
cache_input_cost_per_mtok = 0.25

[providers.openrouter.models."gpt-5.6-luna"]
api_id = "openai/gpt-5.6-luna"
display_name = "GPT-5.6 Luna (via OpenRouter)"
family = "gpt-5"
training = "2026-02-16"
knowledge_cutoff = "February 16, 2026"
aliases = ["luna", "gpt-luna", "gpt56-luna", "gpt-56-luna"]
agent_profile = "gpt56"

[providers.openrouter.models."gpt-5.6-luna".limits]
context_window = 1050000
max_output = 128000

[providers.openrouter.models."gpt-5.6-luna".features]
tools = true
vision = true
reasoning = true
reasoning_effort = "levels"
prompt_cache = true
sampling_params = false

[providers.openrouter.models."gpt-5.6-luna".costs]
input_cost_per_mtok = 1.0
output_cost_per_mtok = 6.0
cache_input_cost_per_mtok = 0.1

[providers.openrouter.models."gpt-5.4"]
api_id = "openai/gpt-5.4"
display_name = "GPT-5.4 (via OpenRouter)"
family = "gpt-5"
aliases = ["gpt54", "gpt-54", "gpt-5.2", "gpt5", "gpt-5.3-codex", "codex"]

[providers.openrouter.models."gpt-5.4".limits]
context_window = 1050000
max_output = 32768

[providers.openrouter.models."gpt-5.4".features]
tools = true
vision = true
reasoning = true

[providers.openrouter.models."gpt-5.4".costs]
input_cost_per_mtok = 2.5
output_cost_per_mtok = 15.0

[providers.openrouter.models."gpt-5.5"]
api_id = "openai/gpt-5.5"
display_name = "GPT-5.5 (via OpenRouter)"
family = "gpt-5"
aliases = ["gpt55", "gpt-55"]

[providers.openrouter.models."gpt-5.5".limits]
context_window = 1050000
max_output = 32768

[providers.openrouter.models."gpt-5.5".features]
tools = true
vision = true
reasoning = true

[providers.openrouter.models."gpt-5.5".costs]
input_cost_per_mtok = 5.0
output_cost_per_mtok = 30.0

# ---------- Google Gemini via OpenRouter ----------

[providers.openrouter.models."gemini-3.1-pro-preview"]
api_id = "google/gemini-3.1-pro-preview"
display_name = "Gemini 3.1 Pro Preview (via OpenRouter)"
family = "gemini-3"

[providers.openrouter.models."gemini-3.1-pro-preview".limits]
context_window = 1048576
max_output = 65536

[providers.openrouter.models."gemini-3.1-pro-preview".features]
tools = true
vision = true
reasoning = true

[providers.openrouter.models."gemini-3.1-pro-preview".costs]
input_cost_per_mtok = 2.0
output_cost_per_mtok = 12.0

[providers.openrouter.models."gemini-3.5-flash"]
api_id = "google/gemini-3.5-flash"
display_name = "Gemini 3.5 Flash (via OpenRouter)"
family = "gemini-3"

[providers.openrouter.models."gemini-3.5-flash".limits]
context_window = 1048576
max_output = 65536

[providers.openrouter.models."gemini-3.5-flash".features]
tools = true
vision = true
reasoning = false

[providers.openrouter.models."gemini-3.5-flash".costs]
input_cost_per_mtok = 1.5
output_cost_per_mtok = 9.0

# ---------- Open-weights models ----------

[providers.openrouter.models."mimo-v2.5-pro"]
api_id = "xiaomi/mimo-v2.5-pro"
display_name = "Xiaomi MiMo v2.5 Pro"
family = "mimo-v2"

[providers.openrouter.models."mimo-v2.5-pro".limits]
context_window = 1050000
max_output = 16384

[providers.openrouter.models."mimo-v2.5-pro".features]
tools = true
vision = false
reasoning = false

[providers.openrouter.models."mimo-v2.5-pro".costs]
input_cost_per_mtok = 0.435
output_cost_per_mtok = 0.87

[providers.openrouter.models."minimax-m2.7"]
api_id = "minimax/minimax-m2.7"
display_name = "MiniMax M2.7"
family = "minimax-m2"

[providers.openrouter.models."minimax-m2.7".limits]
context_window = 200000
max_output = 16384

[providers.openrouter.models."minimax-m2.7".features]
tools = true
vision = false
reasoning = false

[providers.openrouter.models."minimax-m2.7".costs]
input_cost_per_mtok = 0.28
output_cost_per_mtok = 1.20

[providers.openrouter.models."deepseek-v4-pro"]
api_id = "deepseek/deepseek-v4-pro"
display_name = "DeepSeek V4 Pro"
family = "deepseek-v4"
agent_profile = "openai"

[providers.openrouter.models."deepseek-v4-pro".limits]
context_window = 1048576
max_output = 384000

[providers.openrouter.models."deepseek-v4-pro".features]
tools = true
vision = false
reasoning = true
reasoning_effort = "levels"
reasoning_by_default = true
prompt_cache = true
sampling_params = false

[providers.openrouter.models."deepseek-v4-pro".controls]
# OpenRouter names DeepSeek's max tier xhigh on this route.
reasoning_effort = ["high", "xhigh"]

[providers.openrouter.models."deepseek-v4-pro".costs]
input_cost_per_mtok = 0.435
output_cost_per_mtok = 0.87
cache_input_cost_per_mtok = 0.003625

[providers.openrouter.models."deepseek-v4-flash"]
api_id = "deepseek/deepseek-v4-flash-0731"
display_name = "DeepSeek V4 Flash"
family = "deepseek-v4"
aliases = ["deepseek-v4", "deepseek", "deepseek-flash"]
agent_profile = "openai"

[providers.openrouter.models."deepseek-v4-flash".limits]
context_window = 1048576
max_output = 384000

[providers.openrouter.models."deepseek-v4-flash".features]
tools = true
vision = false
reasoning = true
reasoning_effort = "levels"
reasoning_by_default = true
prompt_cache = true
sampling_params = false

[providers.openrouter.models."deepseek-v4-flash".controls]
reasoning_effort = ["low", "high", "max"]

[providers.openrouter.models."deepseek-v4-flash".costs]
input_cost_per_mtok = 0.14
output_cost_per_mtok = 0.28
cache_input_cost_per_mtok = 0.0028

[providers.openrouter.models."kimi-k2.6"]
api_id = "moonshotai/kimi-k2.6"
display_name = "Kimi K2.6"
family = "kimi-k2"
# Kimi models get the Kimi agent profile wherever they are served from, so a
# gateway route behaves like the direct Moonshot one.
agent_profile = "kimi"

[providers.openrouter.models."kimi-k2.6".limits]
context_window = 262144
max_output = 16384

[providers.openrouter.models."kimi-k2.6".features]
tools = true
vision = false
reasoning = false

[providers.openrouter.models."kimi-k2.6".costs]
input_cost_per_mtok = 0.73
output_cost_per_mtok = 3.49

[providers.openrouter.models."kimi-k3"]
api_id = "moonshotai/kimi-k3"
display_name = "Kimi K3 (via OpenRouter)"
family = "kimi-k3"
agent_profile = "kimi"

[providers.openrouter.models."kimi-k3".limits]
context_window = 1048576
max_output = 131072

[providers.openrouter.models."kimi-k3".features]
tools = true
vision = true
reasoning = true
reasoning_effort = "always_adaptive"
prompt_cache = true
sampling_params = false

[providers.openrouter.models."kimi-k3".controls]
reasoning_effort = ["low", "high", "max"]

[providers.openrouter.models."kimi-k3".costs]
input_cost_per_mtok = 3.0
output_cost_per_mtok = 15.0
cache_input_cost_per_mtok = 0.3

[providers.openrouter.models."laguna-s-2.1"]
api_id = "poolside/laguna-s-2.1"
display_name = "Laguna S 2.1 (via OpenRouter)"
family = "laguna-2"

[providers.openrouter.models."laguna-s-2.1".limits]
context_window = 1048576
max_output = 131072

[providers.openrouter.models."laguna-s-2.1".features]
tools = true
vision = false
reasoning = true
prompt_cache = true
sampling_params = true

[providers.openrouter.models."laguna-s-2.1".costs]
input_cost_per_mtok = 0.10
output_cost_per_mtok = 0.20
cache_input_cost_per_mtok = 0.01

[providers.openrouter.models."laguna-xs-2.1"]
api_id = "poolside/laguna-xs-2.1"
display_name = "Laguna XS 2.1 (via OpenRouter)"
family = "laguna-2"

[providers.openrouter.models."laguna-xs-2.1".limits]
context_window = 262144
max_output = 32768

[providers.openrouter.models."laguna-xs-2.1".features]
tools = true
vision = false
reasoning = true
prompt_cache = true
sampling_params = true

# Current promotional rate. OpenRouter's authoritative in-band usage.cost
# supersedes this estimate on completed responses.
[providers.openrouter.models."laguna-xs-2.1".costs]
input_cost_per_mtok = 0.06
output_cost_per_mtok = 0.12
cache_input_cost_per_mtok = 0.03

[providers.openrouter.models."qwen3-coder"]
api_id = "qwen/qwen3-coder"
display_name = "Qwen3 Coder"
family = "qwen3"

[providers.openrouter.models."qwen3-coder".limits]
context_window = 1050000
max_output = 16384

[providers.openrouter.models."qwen3-coder".features]
tools = true
vision = false
reasoning = false

[providers.openrouter.models."qwen3-coder".costs]
input_cost_per_mtok = 0.22
output_cost_per_mtok = 1.80

[providers.openrouter.models."qwen3.6-flash"]
api_id = "qwen/qwen3.6-flash"
display_name = "Qwen3.6 Flash"
family = "qwen3"

[providers.openrouter.models."qwen3.6-flash".limits]
context_window = 1000000
max_output = 16384

[providers.openrouter.models."qwen3.6-flash".features]
tools = true
vision = false
reasoning = false

[providers.openrouter.models."qwen3.6-flash".costs]
input_cost_per_mtok = 0.1875
output_cost_per_mtok = 1.125

[providers.openrouter.models."qwen3.8-max"]
api_id = "qwen/qwen3.8-max"
display_name = "Qwen3.8 Max"
family = "qwen3"

[providers.openrouter.models."qwen3.8-max".limits]
context_window = 1000000
max_output = 131072

[providers.openrouter.models."qwen3.8-max".features]
tools = true
vision = true
reasoning = true
reasoning_effort = "levels"
prompt_cache = true

[providers.openrouter.models."qwen3.8-max".controls]
reasoning_effort = ["low", "medium", "high", "xhigh"]

[providers.openrouter.models."qwen3.8-max".costs]
input_cost_per_mtok = 2.0
output_cost_per_mtok = 6.0
cache_input_cost_per_mtok = 0.25

[providers.openrouter.models."glm-5.2"]
api_id = "z-ai/glm-5.2"
display_name = "GLM 5.2 (via OpenRouter)"
family = "glm-5"
aliases = ["glm", "glm5", "glm52", "glm5.2"]

[providers.openrouter.models."glm-5.2".limits]
context_window = 1048576
max_output = 131072

[providers.openrouter.models."glm-5.2".features]
tools = true
vision = false
reasoning = true
reasoning_effort = "levels"
prompt_cache = true

[providers.openrouter.models."glm-5.2".controls]
reasoning_effort = ["high", "xhigh"]

[providers.openrouter.models."glm-5.2".costs]
input_cost_per_mtok = 0.784
output_cost_per_mtok = 2.464
cache_input_cost_per_mtok = 0.1456

[providers.openrouter.models."glm-4.6"]
api_id = "z-ai/glm-4.6"
display_name = "GLM 4.6"
family = "glm-4"

[providers.openrouter.models."glm-4.6".limits]
context_window = 203000
max_output = 16384

[providers.openrouter.models."glm-4.6".features]
tools = true
vision = false
reasoning = false

[providers.openrouter.models."glm-4.6".costs]
input_cost_per_mtok = 0.43
output_cost_per_mtok = 1.74

[providers.openrouter.models."nemotron-3-super-120b-a12b"]
api_id = "nvidia/nemotron-3-super-120b-a12b"
display_name = "NVIDIA Nemotron 3 Super 120B"
family = "nemotron-3"

[providers.openrouter.models."nemotron-3-super-120b-a12b".limits]
context_window = 1000000
max_output = 16384

[providers.openrouter.models."nemotron-3-super-120b-a12b".features]
tools = true
vision = false
reasoning = false

[providers.openrouter.models."nemotron-3-super-120b-a12b".costs]
input_cost_per_mtok = 0.09
output_cost_per_mtok = 0.45

[providers.openrouter.models."devstral-2512"]
api_id = "mistralai/devstral-2512"
display_name = "Devstral 2512"
family = "devstral"

[providers.openrouter.models."devstral-2512".limits]
context_window = 262144
max_output = 16384

[providers.openrouter.models."devstral-2512".features]
tools = true
vision = false
reasoning = false

[providers.openrouter.models."devstral-2512".costs]
input_cost_per_mtok = 0.40
output_cost_per_mtok = 2.00
