From 21c82e335c38718039b861f10fd4fe2f8c0228f5 Mon Sep 17 00:00:00 2001 From: Evan Date: Sat, 14 Mar 2026 11:49:17 +0900 Subject: [PATCH] feat: initial model catalog with 196 models across 39 providers Community-maintained TOML catalog for LibreFang. New models can be added via PR without requiring a LibreFang binary release. Includes validation script, bilingual docs, and GitHub templates. --- .github/ISSUE_TEMPLATE/new-model.yml | 68 ++++++++ .github/pull_request_template.md | 14 ++ CONTRIBUTING.md | 108 ++++++++++++ LICENSE | 21 +++ README.md | 188 ++++++++++++++++++++ aliases.toml | 101 +++++++++++ providers/ai21.toml | 48 ++++++ providers/anthropic.toml | 100 +++++++++++ providers/bedrock.toml | 113 ++++++++++++ providers/cerebras.toml | 61 +++++++ providers/chatgpt.toml | 74 ++++++++ providers/chutes.toml | 74 ++++++++ providers/claude-code.toml | 48 ++++++ providers/cohere.toml | 61 +++++++ providers/deepseek.toml | 61 +++++++ providers/fireworks.toml | 74 ++++++++ providers/gemini.toml | 139 +++++++++++++++ providers/github-copilot.toml | 35 ++++ providers/groq.toml | 140 +++++++++++++++ providers/huggingface.toml | 48 ++++++ providers/kimi-coding.toml | 22 +++ providers/lemonade.toml | 9 + providers/lmstudio.toml | 22 +++ providers/minimax-cn.toml | 87 ++++++++++ providers/minimax.toml | 87 ++++++++++ providers/mistral.toml | 87 ++++++++++ providers/moonshot.toml | 74 ++++++++ providers/ollama.toml | 87 ++++++++++ providers/openai.toml | 245 +++++++++++++++++++++++++++ providers/openrouter.toml | 219 ++++++++++++++++++++++++ providers/perplexity.toml | 61 +++++++ providers/qianfan.toml | 48 ++++++ providers/qwen.toml | 152 +++++++++++++++++ providers/replicate.toml | 48 ++++++ providers/sambanova.toml | 48 ++++++ providers/together.toml | 113 ++++++++++++ providers/venice.toml | 48 ++++++ providers/vllm.toml | 22 +++ providers/volcengine-coding.toml | 9 + providers/volcengine.toml | 61 +++++++ providers/xai.toml | 126 ++++++++++++++ providers/zai-coding.toml | 35 ++++ providers/zai.toml | 9 + providers/zhipu-coding.toml | 22 +++ providers/zhipu.toml | 87 ++++++++++ schema.toml | 31 ++++ scripts/validate.py | 233 +++++++++++++++++++++++++ 47 files changed, 3668 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/new-model.yml create mode 100644 .github/pull_request_template.md create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE create mode 100644 README.md create mode 100644 aliases.toml create mode 100644 providers/ai21.toml create mode 100644 providers/anthropic.toml create mode 100644 providers/bedrock.toml create mode 100644 providers/cerebras.toml create mode 100644 providers/chatgpt.toml create mode 100644 providers/chutes.toml create mode 100644 providers/claude-code.toml create mode 100644 providers/cohere.toml create mode 100644 providers/deepseek.toml create mode 100644 providers/fireworks.toml create mode 100644 providers/gemini.toml create mode 100644 providers/github-copilot.toml create mode 100644 providers/groq.toml create mode 100644 providers/huggingface.toml create mode 100644 providers/kimi-coding.toml create mode 100644 providers/lemonade.toml create mode 100644 providers/lmstudio.toml create mode 100644 providers/minimax-cn.toml create mode 100644 providers/minimax.toml create mode 100644 providers/mistral.toml create mode 100644 providers/moonshot.toml create mode 100644 providers/ollama.toml create mode 100644 providers/openai.toml create mode 100644 providers/openrouter.toml create mode 100644 providers/perplexity.toml create mode 100644 providers/qianfan.toml create mode 100644 providers/qwen.toml create mode 100644 providers/replicate.toml create mode 100644 providers/sambanova.toml create mode 100644 providers/together.toml create mode 100644 providers/venice.toml create mode 100644 providers/vllm.toml create mode 100644 providers/volcengine-coding.toml create mode 100644 providers/volcengine.toml create mode 100644 providers/xai.toml create mode 100644 providers/zai-coding.toml create mode 100644 providers/zai.toml create mode 100644 providers/zhipu-coding.toml create mode 100644 providers/zhipu.toml create mode 100644 schema.toml create mode 100755 scripts/validate.py diff --git a/.github/ISSUE_TEMPLATE/new-model.yml b/.github/ISSUE_TEMPLATE/new-model.yml new file mode 100644 index 0000000..0e365b4 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/new-model.yml @@ -0,0 +1,68 @@ +name: New Model Request +description: Request addition of a new AI model to the catalog +labels: ["new-model"] +body: + - type: input + id: model_id + attributes: + label: Model ID + description: The canonical model identifier used by the provider's API. + placeholder: e.g. gpt-5.5 + validations: + required: true + + - type: input + id: provider + attributes: + label: Provider + description: Which provider offers this model? + placeholder: e.g. openai + validations: + required: true + + - type: dropdown + id: tier + attributes: + label: Tier + description: What capability tier does this model belong to? + options: + - frontier + - smart + - balanced + - fast + - local + validations: + required: true + + - type: textarea + id: details + attributes: + label: Model Details + description: | + Please provide the following details: + - Context window (tokens) + - Max output tokens + - Input cost per million tokens (USD) + - Output cost per million tokens (USD) + - Supports tool/function calling? (yes/no) + - Supports vision/image input? (yes/no) + - Supports streaming? (yes/no) + placeholder: | + Context window: 128000 + Max output: 16384 + Input cost: $2.50 / 1M tokens + Output cost: $10.00 / 1M tokens + Tools: yes + Vision: yes + Streaming: yes + validations: + required: true + + - type: input + id: source_url + attributes: + label: Source URL + description: Link to the official pricing or documentation page. + placeholder: e.g. https://openai.com/pricing + validations: + required: false diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..8f90ad8 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,14 @@ +## Model Changes + +### Added/Updated Models +- [ ] Model ID: +- [ ] Provider: +- [ ] Pricing verified from official source: + +### Checklist +- [ ] `python scripts/validate.py` passes +- [ ] No duplicate model IDs +- [ ] Pricing is in USD per million tokens +- [ ] Tier is one of: `frontier`, `smart`, `balanced`, `fast`, `local` +- [ ] `context_window` and `max_output_tokens` are positive integers +- [ ] Boolean fields (`supports_tools`, `supports_vision`, `supports_streaming`) are correct diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..9865eda --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,108 @@ +# Contributing to LibreFang Model Catalog + +Thank you for helping keep the model catalog up to date! This guide explains how to add or update model entries. + +## How to Add a New Model + +### 1. Fork & Clone + +```bash +git clone https://github.com//model-catalog.git +cd model-catalog +``` + +### 2. Find the Right Provider File + +Each provider has its own file in `providers/`. For example: +- OpenAI models go in `providers/openai.toml` +- Anthropic models go in `providers/anthropic.toml` + +If the provider doesn't exist yet, create a new file (e.g. `providers/newprovider.toml`) with the `[provider]` section and your `[[models]]` entries. + +### 3. Add Your Model Entry + +Append a `[[models]]` block to the provider file: + +```toml +[[models]] +id = "new-model-id" # The exact API model ID +display_name = "New Model Name" # Human-readable name +tier = "smart" # frontier | smart | balanced | fast | local +context_window = 128000 +max_output_tokens = 16384 +input_cost_per_m = 2.50 # USD per million input tokens +output_cost_per_m = 10.0 # USD per million output tokens +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] # Optional short names +``` + +### 4. Validate + +```bash +python scripts/validate.py +``` + +This checks: +- All TOML files parse correctly +- Required fields are present +- Tier values are valid +- Costs are non-negative +- No duplicate model IDs + +### 5. Submit a Pull Request + +Push your branch and open a PR. The PR template will guide you through the checklist. + +## Where to Find Model Information + +- **OpenAI**: https://openai.com/pricing +- **Anthropic**: https://docs.anthropic.com/en/docs/about-claude/models +- **Google Gemini**: https://ai.google.dev/pricing +- **DeepSeek**: https://platform.deepseek.com/api-docs/pricing +- **Mistral**: https://mistral.ai/technology/#pricing +- **Groq**: https://wow.groq.com/ +- **xAI**: https://docs.x.ai/docs +- **Cohere**: https://cohere.com/pricing +- **Together**: https://www.together.ai/pricing +- **Fireworks**: https://fireworks.ai/pricing +- **Perplexity**: https://docs.perplexity.ai/guides/pricing + +## Tier Definitions + +| Tier | Description | Examples | +|------|-------------|----------| +| `frontier` | Most capable, cutting-edge | Claude Opus, GPT-4.1, Gemini 2.5 Pro | +| `smart` | Smart and cost-effective | Claude Sonnet, GPT-4o, Gemini 2.5 Flash | +| `balanced` | Balanced speed and cost | GPT-4.1 Mini, Llama 3.3 70B | +| `fast` | Fastest, cheapest | GPT-4o Mini, Claude Haiku, Gemma 2 9B | +| `local` | Local models, zero cost | Ollama, vLLM, LM Studio | + +## Guidelines + +- **Pricing must be in USD per million tokens** -- convert from other units if needed +- **Use the exact model ID** that the provider's API expects +- **Don't guess** -- only add data you can verify from official sources +- **One provider per file** -- don't mix providers in a single TOML file +- **Keep aliases short** -- 1-3 word abbreviations that users would naturally type + +--- + +# 贡献指南 + +感谢您帮助维护模型目录!以下是添加或更新模型条目的方法。 + +## 如何添加新模型 + +1. Fork 并克隆此仓库 +2. 在 `providers/` 目录中找到对应的提供商文件 +3. 添加 `[[models]]` 条目(参考上方英文模板) +4. 运行 `python scripts/validate.py` 验证 +5. 提交 Pull Request + +## 定价说明 + +- 所有价格均以 **美元/百万 tokens** 为单位 +- 免费模型和本地模型的价格为 `0.0` +- 请从官方定价页面获取准确数据 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..fa8195f --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 LibreFang Contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..f87c2a1 --- /dev/null +++ b/README.md @@ -0,0 +1,188 @@ +# LibreFang Model Catalog + +Community-maintained model metadata catalog for [LibreFang](https://github.com/librefang/librefang) -- the open-source Agent Operating System. + +This repository is the source of truth for model metadata (pricing, context windows, capabilities). When new models are released (e.g. GPT-5.5, Claude 5), anyone can submit a PR here without touching the LibreFang binary. + +## Structure + +``` +model-catalog/ +├── providers/ # One TOML file per provider +│ ├── anthropic.toml +│ ├── openai.toml +│ ├── gemini.toml +│ └── ... +├── aliases.toml # Global alias mappings (e.g. "sonnet" -> "claude-sonnet-4-6") +├── schema.toml # Reference schema documenting all fields +├── scripts/ +│ └── validate.py # Validation script +├── CONTRIBUTING.md # How to add a new model +└── LICENSE # MIT +``` + +## How LibreFang Uses This Catalog + +LibreFang ships with a built-in model catalog compiled into the binary. This repository serves as the upstream source. To update your local catalog: + +```bash +librefang catalog update +``` + +This fetches the latest TOML files from this repository and merges them into your local catalog. + +### Custom Local Models + +You can also add custom models locally without submitting a PR: + +```bash +# Add to your personal config +# ~/.librefang/model_catalog.toml + +[[models]] +id = "my-custom-model" +display_name = "My Custom Model" +provider = "ollama" +tier = "local" +context_window = 32768 +max_output_tokens = 4096 +input_cost_per_m = 0.0 +output_cost_per_m = 0.0 +supports_tools = true +supports_vision = false +supports_streaming = true +``` + +## Schema Reference + +Each provider file contains a `[provider]` section and one or more `[[models]]` entries: + +```toml +[provider] +id = "provider-id" # Unique provider identifier +display_name = "Provider Name" # Human-readable name +api_key_env = "PROVIDER_API_KEY" # Environment variable for API key +base_url = "https://api.example.com" # Default API endpoint +key_required = true # Whether an API key is needed + +[[models]] +id = "model-id" # Unique model identifier (API model ID) +display_name = "Human Name" # Human-readable display name +tier = "smart" # frontier | smart | balanced | fast | local +context_window = 128000 # Maximum input tokens +max_output_tokens = 16384 # Maximum output tokens +input_cost_per_m = 2.50 # USD per million input tokens +output_cost_per_m = 10.0 # USD per million output tokens +supports_tools = true # Tool/function calling support +supports_vision = true # Vision/image input support +supports_streaming = true # Streaming response support +aliases = ["alias1", "alias2"] # Short names for this model +``` + +### Tier Definitions + +| Tier | Description | Examples | +|------|-------------|----------| +| `frontier` | Most capable, cutting-edge models | Claude Opus, GPT-4.1, Gemini 2.5 Pro | +| `smart` | Smart, cost-effective models | Claude Sonnet, GPT-4o, Gemini 2.5 Flash | +| `balanced` | Balanced speed/cost | GPT-4.1 Mini, Llama 3.3 70B | +| `fast` | Fastest, cheapest | GPT-4o Mini, Claude Haiku | +| `local` | Local models (zero cost) | Ollama, vLLM, LM Studio | + +## How to Add a New Model + +1. Edit the appropriate provider file in `providers/` +2. Run validation: `python scripts/validate.py` +3. Submit a Pull Request + +See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed instructions. + +## Validation + +```bash +python scripts/validate.py +``` + +This checks all TOML files for correctness: required fields, valid tiers, non-negative costs, no duplicate IDs. + +## Current Stats + +- **30+ providers** including Anthropic, OpenAI, Google, DeepSeek, Groq, Mistral, xAI, and more +- **190+ models** with pricing, context windows, and capability flags +- **80+ aliases** for quick model selection + +## License + +MIT License. See [LICENSE](LICENSE). + +--- + +# LibreFang 模型目录 + +社区维护的 [LibreFang](https://github.com/librefang/librefang) 模型元数据目录 -- 开源 Agent 操作系统。 + +本仓库是模型元数据(定价、上下文窗口、能力标记)的唯一数据源。当新模型发布时(如 GPT-5.5、Claude 5),任何人都可以在这里提交 PR,而无需修改 LibreFang 二进制文件。 + +## 目录结构 + +``` +model-catalog/ +├── providers/ # 每个提供商一个 TOML 文件 +│ ├── anthropic.toml +│ ├── openai.toml +│ ├── gemini.toml +│ └── ... +├── aliases.toml # 全局别名映射(如 "sonnet" -> "claude-sonnet-4-6") +├── schema.toml # 字段定义参考 +├── scripts/ +│ └── validate.py # 验证脚本 +├── CONTRIBUTING.md # 如何添加新模型 +└── LICENSE # MIT 许可证 +``` + +## LibreFang 如何使用此目录 + +LibreFang 内置了编译到二进制文件中的模型目录。本仓库作为上游数据源。更新本地目录: + +```bash +librefang catalog update +``` + +### 本地自定义模型 + +您也可以在本地添加自定义模型,无需提交 PR: + +```bash +# 编辑个人配置文件 +# ~/.librefang/model_catalog.toml + +[[models]] +id = "my-custom-model" +display_name = "我的自定义模型" +provider = "ollama" +tier = "local" +context_window = 32768 +max_output_tokens = 4096 +input_cost_per_m = 0.0 +output_cost_per_m = 0.0 +``` + +## 如何添加新模型 + +1. 编辑 `providers/` 中对应的提供商文件 +2. 运行验证:`python scripts/validate.py` +3. 提交 Pull Request + +详细说明请参考 [CONTRIBUTING.md](CONTRIBUTING.md)。 + +## 验证 + +```bash +python scripts/validate.py +``` + +检查所有 TOML 文件的正确性:必填字段、有效的层级值、非负成本、无重复 ID。 + +## 许可证 + +MIT 许可证。详见 [LICENSE](LICENSE)。 diff --git a/aliases.toml b/aliases.toml new file mode 100644 index 0000000..0fd21a4 --- /dev/null +++ b/aliases.toml @@ -0,0 +1,101 @@ +# Global alias mappings +# Maps short names to canonical model IDs. +# Aliases defined in provider TOML files (via the `aliases` field on each model) +# are auto-registered at load time. This file contains additional global aliases +# that are not tied to a specific model entry. + +[aliases] +# Anthropic +"sonnet" = "claude-sonnet-4-6" +"claude-sonnet" = "claude-sonnet-4-6" +"haiku" = "claude-haiku-4-5-20251001" +"claude-haiku" = "claude-haiku-4-5-20251001" +"opus" = "claude-opus-4-6" +"claude-opus" = "claude-opus-4-6" + +# OpenAI +"gpt4" = "gpt-4o" +"gpt4o" = "gpt-4o" +"gpt4-mini" = "gpt-4o-mini" +"gpt5" = "gpt-5.2" +"gpt5-mini" = "gpt-5-mini" + +# Google Gemini +"flash" = "gemini-2.5-flash" +"gemini-pro" = "gemini-3.1-pro-preview" +"gemini-flash" = "gemini-3-flash-preview" + +# DeepSeek +"deepseek" = "deepseek-chat" +"deepseek-v3" = "deepseek-chat" +"deepseek-r1" = "deepseek-reasoner" + +# Groq +"llama" = "llama-3.3-70b-versatile" +"llama-70b" = "llama-3.3-70b-versatile" +"mixtral" = "mixtral-8x7b-32768" + +# Mistral +"mistral" = "mistral-large-latest" +"codestral" = "codestral-latest" +"mistral-nemo" = "open-mistral-nemo" +"pixtral" = "pixtral-large-latest" + +# xAI +"grok" = "grok-4-0709" +"grok-4" = "grok-4-0709" +"grok-mini" = "grok-2-mini" +"grok3" = "grok-3" +"grok-fast" = "grok-4-1-fast-reasoning" + +# Perplexity +"sonar" = "sonar-pro" + +# AI21 +"jamba" = "jamba-1.5-large" + +# Cohere +"command-r" = "command-r-plus" +"command" = "command-a" + +# GitHub Copilot +"copilot" = "copilot/gpt-4o" +"copilot-4o" = "copilot/gpt-4o" +"copilot-4" = "copilot/gpt-4" +"copilot-gpt4o" = "copilot/gpt-4o" +"copilot-gpt4" = "copilot/gpt-4" + +# Chinese models +"qwen" = "qwen-plus" +"glm" = "glm-5-20250605" +"ernie" = "ernie-4.5-8k" +"kimi" = "kimi-k2" +"moonshot" = "moonshot-v1-128k" +"minimax" = "MiniMax-M2.5" +"minimax-m2.5" = "MiniMax-M2.5" +"minimax-m2.5-highspeed" = "MiniMax-M2.5-highspeed" +"minimax-highspeed" = "MiniMax-M2.5-highspeed" +"minimax-m2.1" = "MiniMax-M2.1" +"codegeex" = "codegeex-4" + +# ChatGPT Session Auth +"chatgpt" = "gpt-5.1-codex-mini" +"chatgpt-mini" = "gpt-5.1-codex-mini" +"chatgpt-5.1" = "gpt-5.1-codex" +"chatgpt-5.2" = "gpt-5.2-codex" +"chatgpt-5.3" = "gpt-5.3-codex" +"chatgpt-5.4" = "gpt-5.4-codex" + +# Codex +"codex" = "codex/gpt-4.1" +"codex-4.1" = "codex/gpt-4.1" +"codex-o4" = "codex/o4-mini" + +# Venice +"venice" = "venice-uncensored" + +# Claude Code +"claude-code" = "claude-code/sonnet" +"claude-code-opus" = "claude-code/opus" +"claude-code-sonnet" = "claude-code/sonnet" +"claude-code-haiku" = "claude-code/haiku" diff --git a/providers/ai21.toml b/providers/ai21.toml new file mode 100644 index 0000000..d451204 --- /dev/null +++ b/providers/ai21.toml @@ -0,0 +1,48 @@ +# AI21 Labs — https://ai21.com +# Models: 3 + +[provider] +id = "ai21" +display_name = "AI21 Labs" +api_key_env = "AI21_API_KEY" +base_url = "https://api.ai21.com/studio/v1" +key_required = true + +[[models]] +id = "jamba-1.5-large" +display_name = "Jamba 1.5 Large" +tier = "smart" +context_window = 256000 +max_output_tokens = 4096 +input_cost_per_m = 2.0 +output_cost_per_m = 8.0 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = ["jamba"] + +[[models]] +id = "jamba-1.5-mini" +display_name = "Jamba 1.5 Mini" +tier = "fast" +context_window = 256000 +max_output_tokens = 4096 +input_cost_per_m = 0.20 +output_cost_per_m = 0.40 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "jamba-instruct" +display_name = "Jamba Instruct" +tier = "balanced" +context_window = 256000 +max_output_tokens = 4096 +input_cost_per_m = 0.50 +output_cost_per_m = 0.70 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] diff --git a/providers/anthropic.toml b/providers/anthropic.toml new file mode 100644 index 0000000..24fd015 --- /dev/null +++ b/providers/anthropic.toml @@ -0,0 +1,100 @@ +# Anthropic — https://anthropic.com +# Models: 7 + +[provider] +id = "anthropic" +display_name = "Anthropic" +api_key_env = "ANTHROPIC_API_KEY" +base_url = "https://api.anthropic.com" +key_required = true + +[[models]] +id = "claude-opus-4-6" +display_name = "Claude Opus 4.6" +tier = "frontier" +context_window = 200000 +max_output_tokens = 128000 +input_cost_per_m = 5.0 +output_cost_per_m = 25.0 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = ["opus", "claude-opus"] + +[[models]] +id = "claude-sonnet-4-6" +display_name = "Claude Sonnet 4.6" +tier = "smart" +context_window = 200000 +max_output_tokens = 64000 +input_cost_per_m = 3.0 +output_cost_per_m = 15.0 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = ["sonnet", "claude-sonnet"] + +[[models]] +id = "claude-opus-4-20250514" +display_name = "Claude Opus 4" +tier = "frontier" +context_window = 200000 +max_output_tokens = 32000 +input_cost_per_m = 15.0 +output_cost_per_m = 75.0 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] + +[[models]] +id = "claude-sonnet-4-20250514" +display_name = "Claude Sonnet 4" +tier = "smart" +context_window = 200000 +max_output_tokens = 64000 +input_cost_per_m = 3.0 +output_cost_per_m = 15.0 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] + +[[models]] +id = "claude-haiku-4-5-20251001" +display_name = "Claude Haiku 4.5" +tier = "fast" +context_window = 200000 +max_output_tokens = 8192 +input_cost_per_m = 0.25 +output_cost_per_m = 1.25 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = ["haiku", "claude-haiku"] + +[[models]] +id = "claude-sonnet-4-5-20250514" +display_name = "Claude Sonnet 4.5" +tier = "smart" +context_window = 200000 +max_output_tokens = 64000 +input_cost_per_m = 3.0 +output_cost_per_m = 15.0 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] + +[[models]] +id = "claude-3-5-sonnet-20241022" +display_name = "Claude 3.5 Sonnet" +tier = "smart" +context_window = 200000 +max_output_tokens = 8192 +input_cost_per_m = 3.0 +output_cost_per_m = 15.0 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] diff --git a/providers/bedrock.toml b/providers/bedrock.toml new file mode 100644 index 0000000..ab27b3d --- /dev/null +++ b/providers/bedrock.toml @@ -0,0 +1,113 @@ +# AWS Bedrock — https://aws.amazon.com/bedrock +# Models: 8 + +[provider] +id = "bedrock" +display_name = "AWS Bedrock" +api_key_env = "AWS_ACCESS_KEY_ID" +base_url = "https://bedrock-runtime.us-east-1.amazonaws.com" +key_required = true + +[[models]] +id = "bedrock/anthropic.claude-opus-4-6" +display_name = "Claude Opus 4.6 (Bedrock)" +tier = "frontier" +context_window = 200000 +max_output_tokens = 128000 +input_cost_per_m = 5.00 +output_cost_per_m = 25.00 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] + +[[models]] +id = "bedrock/anthropic.claude-sonnet-4-6" +display_name = "Claude Sonnet 4.6 (Bedrock)" +tier = "smart" +context_window = 200000 +max_output_tokens = 64000 +input_cost_per_m = 3.00 +output_cost_per_m = 15.00 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] + +[[models]] +id = "bedrock/anthropic.claude-opus-4-20250514" +display_name = "Claude Opus 4 (Bedrock)" +tier = "frontier" +context_window = 200000 +max_output_tokens = 32000 +input_cost_per_m = 15.00 +output_cost_per_m = 75.00 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] + +[[models]] +id = "bedrock/anthropic.claude-sonnet-4-20250514" +display_name = "Claude Sonnet 4 (Bedrock)" +tier = "smart" +context_window = 200000 +max_output_tokens = 64000 +input_cost_per_m = 3.00 +output_cost_per_m = 15.00 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] + +[[models]] +id = "bedrock/anthropic.claude-haiku-4-5-20251001" +display_name = "Claude Haiku 4.5 (Bedrock)" +tier = "fast" +context_window = 200000 +max_output_tokens = 8192 +input_cost_per_m = 0.25 +output_cost_per_m = 1.25 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] + +[[models]] +id = "bedrock/amazon.nova-pro-v1:0" +display_name = "Amazon Nova Pro (Bedrock)" +tier = "smart" +context_window = 300000 +max_output_tokens = 5120 +input_cost_per_m = 0.80 +output_cost_per_m = 3.20 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] + +[[models]] +id = "bedrock/amazon.nova-lite-v1:0" +display_name = "Amazon Nova Lite (Bedrock)" +tier = "fast" +context_window = 300000 +max_output_tokens = 5120 +input_cost_per_m = 0.06 +output_cost_per_m = 0.24 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] + +[[models]] +id = "bedrock/meta.llama3-3-70b-instruct-v1:0" +display_name = "Llama 3.3 70B (Bedrock)" +tier = "balanced" +context_window = 128000 +max_output_tokens = 4096 +input_cost_per_m = 0.72 +output_cost_per_m = 0.72 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] diff --git a/providers/cerebras.toml b/providers/cerebras.toml new file mode 100644 index 0000000..f09df6f --- /dev/null +++ b/providers/cerebras.toml @@ -0,0 +1,61 @@ +# Cerebras — https://cerebras.ai +# Models: 4 + +[provider] +id = "cerebras" +display_name = "Cerebras" +api_key_env = "CEREBRAS_API_KEY" +base_url = "https://api.cerebras.ai/v1" +key_required = true + +[[models]] +id = "cerebras/llama3.3-70b" +display_name = "Llama 3.3 70B (Cerebras)" +tier = "balanced" +context_window = 128000 +max_output_tokens = 8192 +input_cost_per_m = 0.06 +output_cost_per_m = 0.06 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "cerebras/llama3.1-8b" +display_name = "Llama 3.1 8B (Cerebras)" +tier = "fast" +context_window = 128000 +max_output_tokens = 8192 +input_cost_per_m = 0.01 +output_cost_per_m = 0.01 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "cerebras/llama-4-scout-17b" +display_name = "Llama 4 Scout (Cerebras)" +tier = "smart" +context_window = 512000 +max_output_tokens = 8192 +input_cost_per_m = 0.10 +output_cost_per_m = 0.10 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "cerebras/qwen-2.5-32b" +display_name = "Qwen 2.5 32B (Cerebras)" +tier = "balanced" +context_window = 32768 +max_output_tokens = 8192 +input_cost_per_m = 0.06 +output_cost_per_m = 0.06 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] diff --git a/providers/chatgpt.toml b/providers/chatgpt.toml new file mode 100644 index 0000000..cb063df --- /dev/null +++ b/providers/chatgpt.toml @@ -0,0 +1,74 @@ +# ChatGPT (Session Auth / Codex Responses API) — https://chatgpt.com +# Models: 5 (free with ChatGPT subscription via OAuth session) + +[provider] +id = "chatgpt" +display_name = "ChatGPT (Session Auth)" +api_key_env = "CHATGPT_SESSION_TOKEN" +base_url = "https://chatgpt.com/backend-api" +key_required = true + +[[models]] +id = "gpt-5.4-codex" +display_name = "GPT-5.4 Codex" +tier = "frontier" +context_window = 200000 +max_output_tokens = 65536 +input_cost_per_m = 0.0 +output_cost_per_m = 0.0 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = ["chatgpt-5.4"] + +[[models]] +id = "gpt-5.3-codex" +display_name = "GPT-5.3 Codex" +tier = "frontier" +context_window = 200000 +max_output_tokens = 65536 +input_cost_per_m = 0.0 +output_cost_per_m = 0.0 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = ["chatgpt-5.3"] + +[[models]] +id = "gpt-5.2-codex" +display_name = "GPT-5.2 Codex" +tier = "smart" +context_window = 200000 +max_output_tokens = 65536 +input_cost_per_m = 0.0 +output_cost_per_m = 0.0 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = ["chatgpt-5.2"] + +[[models]] +id = "gpt-5.1-codex" +display_name = "GPT-5.1 Codex" +tier = "smart" +context_window = 200000 +max_output_tokens = 65536 +input_cost_per_m = 0.0 +output_cost_per_m = 0.0 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = ["chatgpt-5.1"] + +[[models]] +id = "gpt-5.1-codex-mini" +display_name = "GPT-5.1 Codex Mini" +tier = "balanced" +context_window = 200000 +max_output_tokens = 65536 +input_cost_per_m = 0.0 +output_cost_per_m = 0.0 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = ["chatgpt-mini", "chatgpt"] diff --git a/providers/chutes.toml b/providers/chutes.toml new file mode 100644 index 0000000..b405e3f --- /dev/null +++ b/providers/chutes.toml @@ -0,0 +1,74 @@ +# Chutes.ai — https://chutes.ai +# Models: 5 + +[provider] +id = "chutes" +display_name = "Chutes.ai" +api_key_env = "CHUTES_API_KEY" +base_url = "https://llm.chutes.ai/v1" +key_required = true + +[[models]] +id = "chutes/deepseek-ai/DeepSeek-V3" +display_name = "DeepSeek V3 (Chutes)" +tier = "smart" +context_window = 128000 +max_output_tokens = 8192 +input_cost_per_m = 0.25 +output_cost_per_m = 0.35 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = ["chutes-deepseek-v3"] + +[[models]] +id = "chutes/deepseek-ai/DeepSeek-R1" +display_name = "DeepSeek R1 (Chutes)" +tier = "smart" +context_window = 128000 +max_output_tokens = 8192 +input_cost_per_m = 0.55 +output_cost_per_m = 2.19 +supports_tools = false +supports_vision = false +supports_streaming = true +aliases = ["chutes-deepseek-r1"] + +[[models]] +id = "chutes/meta-llama/Llama-4-Maverick-17B-128E-Instruct" +display_name = "Llama 4 Maverick (Chutes)" +tier = "balanced" +context_window = 128000 +max_output_tokens = 8192 +input_cost_per_m = 0.20 +output_cost_per_m = 0.30 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = ["chutes-llama-maverick"] + +[[models]] +id = "chutes/Qwen/Qwen3-235B-A22B" +display_name = "Qwen3 235B (Chutes)" +tier = "smart" +context_window = 128000 +max_output_tokens = 8192 +input_cost_per_m = 0.25 +output_cost_per_m = 0.35 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = ["chutes-qwen3"] + +[[models]] +id = "chutes/meta-llama/Llama-3.3-70B-Instruct" +display_name = "Llama 3.3 70B (Chutes)" +tier = "balanced" +context_window = 128000 +max_output_tokens = 8192 +input_cost_per_m = 0.10 +output_cost_per_m = 0.15 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = ["chutes-llama-70b"] diff --git a/providers/claude-code.toml b/providers/claude-code.toml new file mode 100644 index 0000000..9061dbd --- /dev/null +++ b/providers/claude-code.toml @@ -0,0 +1,48 @@ +# Claude Code CLI — subprocess-based provider +# Models: 3 (requires `claude` CLI installed) + +[provider] +id = "claude-code" +display_name = "Claude Code" +api_key_env = "" +base_url = "" +key_required = false + +[[models]] +id = "claude-code/opus" +display_name = "Claude Opus (CLI)" +tier = "frontier" +context_window = 200000 +max_output_tokens = 128000 +input_cost_per_m = 5.0 +output_cost_per_m = 25.0 +supports_tools = false +supports_vision = false +supports_streaming = true +aliases = ["claude-code-opus"] + +[[models]] +id = "claude-code/sonnet" +display_name = "Claude Sonnet (CLI)" +tier = "smart" +context_window = 200000 +max_output_tokens = 64000 +input_cost_per_m = 3.0 +output_cost_per_m = 15.0 +supports_tools = false +supports_vision = false +supports_streaming = true +aliases = ["claude-code", "claude-code-sonnet"] + +[[models]] +id = "claude-code/haiku" +display_name = "Claude Haiku (CLI)" +tier = "fast" +context_window = 200000 +max_output_tokens = 8192 +input_cost_per_m = 0.25 +output_cost_per_m = 1.25 +supports_tools = false +supports_vision = false +supports_streaming = true +aliases = ["claude-code-haiku"] diff --git a/providers/cohere.toml b/providers/cohere.toml new file mode 100644 index 0000000..8a4d119 --- /dev/null +++ b/providers/cohere.toml @@ -0,0 +1,61 @@ +# Cohere — https://cohere.com +# Models: 4 + +[provider] +id = "cohere" +display_name = "Cohere" +api_key_env = "COHERE_API_KEY" +base_url = "https://api.cohere.com/v2" +key_required = true + +[[models]] +id = "command-r-plus" +display_name = "Command R+" +tier = "smart" +context_window = 128000 +max_output_tokens = 4096 +input_cost_per_m = 2.50 +output_cost_per_m = 10.0 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = ["command-r"] + +[[models]] +id = "command-r-08-2024" +display_name = "Command R (Aug 2024)" +tier = "balanced" +context_window = 128000 +max_output_tokens = 4096 +input_cost_per_m = 0.15 +output_cost_per_m = 0.60 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "command-a" +display_name = "Command A" +tier = "smart" +context_window = 256000 +max_output_tokens = 8192 +input_cost_per_m = 2.50 +output_cost_per_m = 10.0 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = ["command"] + +[[models]] +id = "command-light" +display_name = "Command Light" +tier = "fast" +context_window = 4096 +max_output_tokens = 4096 +input_cost_per_m = 0.30 +output_cost_per_m = 0.60 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] diff --git a/providers/deepseek.toml b/providers/deepseek.toml new file mode 100644 index 0000000..c5b9735 --- /dev/null +++ b/providers/deepseek.toml @@ -0,0 +1,61 @@ +# DeepSeek — https://deepseek.com +# Models: 4 + +[provider] +id = "deepseek" +display_name = "DeepSeek" +api_key_env = "DEEPSEEK_API_KEY" +base_url = "https://api.deepseek.com/v1" +key_required = true + +[[models]] +id = "deepseek-chat" +display_name = "DeepSeek V3" +tier = "smart" +context_window = 64000 +max_output_tokens = 8192 +input_cost_per_m = 0.27 +output_cost_per_m = 1.10 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = ["deepseek", "deepseek-v3"] + +[[models]] +id = "deepseek-reasoner" +display_name = "DeepSeek R1" +tier = "frontier" +context_window = 64000 +max_output_tokens = 8192 +input_cost_per_m = 0.55 +output_cost_per_m = 2.19 +supports_tools = false +supports_vision = false +supports_streaming = true +aliases = ["deepseek-r1"] + +[[models]] +id = "deepseek-coder" +display_name = "DeepSeek Coder V2" +tier = "balanced" +context_window = 128000 +max_output_tokens = 8192 +input_cost_per_m = 0.14 +output_cost_per_m = 0.28 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "deepseek-chat-v3-0324" +display_name = "DeepSeek V3 0324" +tier = "smart" +context_window = 64000 +max_output_tokens = 8192 +input_cost_per_m = 0.27 +output_cost_per_m = 1.10 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] diff --git a/providers/fireworks.toml b/providers/fireworks.toml new file mode 100644 index 0000000..2f4bc8b --- /dev/null +++ b/providers/fireworks.toml @@ -0,0 +1,74 @@ +# Fireworks AI — https://fireworks.ai +# Models: 5 + +[provider] +id = "fireworks" +display_name = "Fireworks AI" +api_key_env = "FIREWORKS_API_KEY" +base_url = "https://api.fireworks.ai/inference/v1" +key_required = true + +[[models]] +id = "accounts/fireworks/models/llama-v3p1-405b-instruct" +display_name = "Llama 3.1 405B (Fireworks)" +tier = "frontier" +context_window = 131072 +max_output_tokens = 16384 +input_cost_per_m = 3.00 +output_cost_per_m = 3.00 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "accounts/fireworks/models/llama-v3p3-70b-instruct" +display_name = "Llama 3.3 70B (Fireworks)" +tier = "smart" +context_window = 131072 +max_output_tokens = 16384 +input_cost_per_m = 0.90 +output_cost_per_m = 0.90 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "accounts/fireworks/models/deepseek-r1" +display_name = "DeepSeek R1 (Fireworks)" +tier = "frontier" +context_window = 64000 +max_output_tokens = 8192 +input_cost_per_m = 3.00 +output_cost_per_m = 8.00 +supports_tools = false +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "accounts/fireworks/models/deepseek-v3" +display_name = "DeepSeek V3 (Fireworks)" +tier = "smart" +context_window = 64000 +max_output_tokens = 8192 +input_cost_per_m = 0.90 +output_cost_per_m = 0.90 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "accounts/fireworks/models/mixtral-8x22b-instruct" +display_name = "Mixtral 8x22B (Fireworks)" +tier = "balanced" +context_window = 65536 +max_output_tokens = 4096 +input_cost_per_m = 0.90 +output_cost_per_m = 0.90 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] diff --git a/providers/gemini.toml b/providers/gemini.toml new file mode 100644 index 0000000..0c60e4e --- /dev/null +++ b/providers/gemini.toml @@ -0,0 +1,139 @@ +# Google Gemini — https://ai.google.dev +# Models: 10 + +[provider] +id = "gemini" +display_name = "Google Gemini" +api_key_env = "GEMINI_API_KEY" +base_url = "https://generativelanguage.googleapis.com" +key_required = true + +[[models]] +id = "gemini-3.1-pro-preview" +display_name = "Gemini 3.1 Pro Preview" +tier = "frontier" +context_window = 1048576 +max_output_tokens = 65536 +input_cost_per_m = 2.50 +output_cost_per_m = 15.0 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = ["gemini-pro"] + +[[models]] +id = "gemini-3-flash-preview" +display_name = "Gemini 3 Flash Preview" +tier = "smart" +context_window = 1048576 +max_output_tokens = 65536 +input_cost_per_m = 0.15 +output_cost_per_m = 0.60 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = ["gemini-flash"] + +[[models]] +id = "gemini-3.1-flash-lite-preview" +display_name = "Gemini 3.1 Flash Lite Preview" +tier = "fast" +context_window = 1048576 +max_output_tokens = 8192 +input_cost_per_m = 0.04 +output_cost_per_m = 0.15 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] + +[[models]] +id = "gemini-2.5-flash-lite" +display_name = "Gemini 2.5 Flash Lite" +tier = "fast" +context_window = 1048576 +max_output_tokens = 8192 +input_cost_per_m = 0.04 +output_cost_per_m = 0.15 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] + +[[models]] +id = "gemini-2.5-pro" +display_name = "Gemini 2.5 Pro" +tier = "frontier" +context_window = 1048576 +max_output_tokens = 65536 +input_cost_per_m = 1.25 +output_cost_per_m = 10.0 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] + +[[models]] +id = "gemini-2.5-flash" +display_name = "Gemini 2.5 Flash" +tier = "smart" +context_window = 1048576 +max_output_tokens = 65536 +input_cost_per_m = 0.15 +output_cost_per_m = 0.60 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = ["flash"] + +[[models]] +id = "gemini-2.0-flash" +display_name = "Gemini 2.0 Flash" +tier = "fast" +context_window = 1048576 +max_output_tokens = 8192 +input_cost_per_m = 0.10 +output_cost_per_m = 0.40 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] + +[[models]] +id = "gemini-2.0-flash-lite" +display_name = "Gemini 2.0 Flash Lite" +tier = "fast" +context_window = 1048576 +max_output_tokens = 8192 +input_cost_per_m = 0.075 +output_cost_per_m = 0.30 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] + +[[models]] +id = "gemini-1.5-pro" +display_name = "Gemini 1.5 Pro" +tier = "smart" +context_window = 2097152 +max_output_tokens = 8192 +input_cost_per_m = 1.25 +output_cost_per_m = 5.00 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] + +[[models]] +id = "gemini-1.5-flash" +display_name = "Gemini 1.5 Flash" +tier = "fast" +context_window = 1048576 +max_output_tokens = 8192 +input_cost_per_m = 0.075 +output_cost_per_m = 0.30 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] diff --git a/providers/github-copilot.toml b/providers/github-copilot.toml new file mode 100644 index 0000000..1ada7c1 --- /dev/null +++ b/providers/github-copilot.toml @@ -0,0 +1,35 @@ +# GitHub Copilot — https://github.com/features/copilot +# Models: 2 (free for GitHub Copilot subscribers) + +[provider] +id = "github-copilot" +display_name = "GitHub Copilot" +api_key_env = "GITHUB_TOKEN" +base_url = "https://api.githubcopilot.com" +key_required = true + +[[models]] +id = "copilot/gpt-4o" +display_name = "GPT-4o (Copilot)" +tier = "smart" +context_window = 128000 +max_output_tokens = 4096 +input_cost_per_m = 0.0 +output_cost_per_m = 0.0 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = ["copilot-gpt4o"] + +[[models]] +id = "copilot/gpt-4" +display_name = "GPT-4 (Copilot)" +tier = "frontier" +context_window = 128000 +max_output_tokens = 4096 +input_cost_per_m = 0.0 +output_cost_per_m = 0.0 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = ["copilot-gpt4"] diff --git a/providers/groq.toml b/providers/groq.toml new file mode 100644 index 0000000..d38db8b --- /dev/null +++ b/providers/groq.toml @@ -0,0 +1,140 @@ +# Groq — https://groq.com +# Models: 10 + +[provider] +id = "groq" +display_name = "Groq" +api_key_env = "GROQ_API_KEY" +base_url = "https://api.groq.com/openai/v1" +key_required = true + +[[models]] +id = "llama-3.3-70b-versatile" +display_name = "Llama 3.3 70B" +tier = "balanced" +context_window = 128000 +max_output_tokens = 32768 +input_cost_per_m = 0.059 +output_cost_per_m = 0.079 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = ["llama", "llama-70b"] + +[[models]] +id = "llama-3.1-8b-instant" +display_name = "Llama 3.1 8B" +tier = "fast" +context_window = 128000 +max_output_tokens = 8192 +input_cost_per_m = 0.05 +output_cost_per_m = 0.08 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "llama-3.2-90b-vision-preview" +display_name = "Llama 3.2 90B Vision" +tier = "smart" +context_window = 128000 +max_output_tokens = 8192 +input_cost_per_m = 0.90 +output_cost_per_m = 0.90 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] + +[[models]] +id = "llama-3.2-11b-vision-preview" +display_name = "Llama 3.2 11B Vision" +tier = "balanced" +context_window = 128000 +max_output_tokens = 8192 +input_cost_per_m = 0.18 +output_cost_per_m = 0.18 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] + +[[models]] +id = "llama-3.2-3b-preview" +display_name = "Llama 3.2 3B" +tier = "fast" +context_window = 128000 +max_output_tokens = 8192 +input_cost_per_m = 0.06 +output_cost_per_m = 0.06 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "llama-3.2-1b-preview" +display_name = "Llama 3.2 1B" +tier = "fast" +context_window = 128000 +max_output_tokens = 8192 +input_cost_per_m = 0.04 +output_cost_per_m = 0.04 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "mixtral-8x7b-32768" +display_name = "Mixtral 8x7B" +tier = "balanced" +context_window = 32768 +max_output_tokens = 4096 +input_cost_per_m = 0.024 +output_cost_per_m = 0.024 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = ["mixtral"] + +[[models]] +id = "gemma2-9b-it" +display_name = "Gemma 2 9B" +tier = "fast" +context_window = 8192 +max_output_tokens = 4096 +input_cost_per_m = 0.02 +output_cost_per_m = 0.02 +supports_tools = false +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "qwen-qwq-32b" +display_name = "Qwen QWQ 32B" +tier = "balanced" +context_window = 128000 +max_output_tokens = 16384 +input_cost_per_m = 0.20 +output_cost_per_m = 0.20 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "meta-llama/llama-4-scout-17b-16e-instruct" +display_name = "Llama 4 Scout 17B" +tier = "balanced" +context_window = 128000 +max_output_tokens = 8192 +input_cost_per_m = 0.11 +output_cost_per_m = 0.34 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] + diff --git a/providers/huggingface.toml b/providers/huggingface.toml new file mode 100644 index 0000000..a0bad61 --- /dev/null +++ b/providers/huggingface.toml @@ -0,0 +1,48 @@ +# Hugging Face — https://huggingface.co +# Models: 3 (static entries; additional models discovered dynamically at runtime) + +[provider] +id = "huggingface" +display_name = "Hugging Face" +api_key_env = "HF_API_KEY" +base_url = "https://api-inference.huggingface.co/v1" +key_required = true + +[[models]] +id = "hf/meta-llama/Llama-3.3-70B-Instruct" +display_name = "Llama 3.3 70B (HF)" +tier = "balanced" +context_window = 128000 +max_output_tokens = 4096 +input_cost_per_m = 0.30 +output_cost_per_m = 0.30 +supports_tools = false +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "hf/deepseek-ai/DeepSeek-R1" +display_name = "DeepSeek R1 (HF)" +tier = "smart" +context_window = 64000 +max_output_tokens = 4096 +input_cost_per_m = 0.30 +output_cost_per_m = 0.30 +supports_tools = false +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "hf/Qwen/Qwen2.5-72B-Instruct" +display_name = "Qwen 2.5 72B (HF)" +tier = "balanced" +context_window = 32768 +max_output_tokens = 4096 +input_cost_per_m = 0.30 +output_cost_per_m = 0.30 +supports_tools = false +supports_vision = false +supports_streaming = true +aliases = [] diff --git a/providers/kimi-coding.toml b/providers/kimi-coding.toml new file mode 100644 index 0000000..0de163c --- /dev/null +++ b/providers/kimi-coding.toml @@ -0,0 +1,22 @@ +# Kimi for Code — https://api.kimi.com +# Models: 1 + +[provider] +id = "kimi_coding" +display_name = "Kimi for Code" +api_key_env = "KIMI_API_KEY" +base_url = "https://api.kimi.com/coding" +key_required = true + +[[models]] +id = "kimi-for-coding" +display_name = "Kimi For Coding" +tier = "frontier" +context_window = 262144 +max_output_tokens = 32768 +input_cost_per_m = 0.0 +output_cost_per_m = 0.0 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] diff --git a/providers/lemonade.toml b/providers/lemonade.toml new file mode 100644 index 0000000..a8b92e2 --- /dev/null +++ b/providers/lemonade.toml @@ -0,0 +1,9 @@ +# Lemonade — local NPU accelerated inference +# Models: 0 (all models discovered dynamically at runtime) + +[provider] +id = "lemonade" +display_name = "Lemonade" +api_key_env = "LEMONADE_API_KEY" +base_url = "http://localhost:8888/api/v1" +key_required = false diff --git a/providers/lmstudio.toml b/providers/lmstudio.toml new file mode 100644 index 0000000..c1dcf0c --- /dev/null +++ b/providers/lmstudio.toml @@ -0,0 +1,22 @@ +# LM Studio — https://lmstudio.ai +# Models: 1 (generic entry; additional models discovered dynamically at runtime) + +[provider] +id = "lmstudio" +display_name = "LM Studio" +api_key_env = "LMSTUDIO_API_KEY" +base_url = "http://localhost:1234/v1" +key_required = false + +[[models]] +id = "lmstudio-local" +display_name = "LM Studio Local Model" +tier = "local" +context_window = 32768 +max_output_tokens = 4096 +input_cost_per_m = 0.0 +output_cost_per_m = 0.0 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] diff --git a/providers/minimax-cn.toml b/providers/minimax-cn.toml new file mode 100644 index 0000000..b8d6c25 --- /dev/null +++ b/providers/minimax-cn.toml @@ -0,0 +1,87 @@ +# MiniMax (China) — https://minimaxi.com +# Models: 6 (same models as international, different endpoint) + +[provider] +id = "minimax-cn" +display_name = "MiniMax (China)" +api_key_env = "MINIMAX_CN_API_KEY" +base_url = "https://api.minimaxi.com/v1" +key_required = true + +[[models]] +id = "minimax-text-01" +display_name = "MiniMax Text 01" +tier = "smart" +context_window = 1048576 +max_output_tokens = 16384 +input_cost_per_m = 1.00 +output_cost_per_m = 3.00 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "MiniMax-M2.5" +display_name = "MiniMax M2.5" +tier = "frontier" +context_window = 1048576 +max_output_tokens = 16384 +input_cost_per_m = 1.10 +output_cost_per_m = 4.40 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] + +[[models]] +id = "MiniMax-M2.5-highspeed" +display_name = "MiniMax M2.5 Highspeed" +tier = "smart" +context_window = 1048576 +max_output_tokens = 16384 +input_cost_per_m = 0.80 +output_cost_per_m = 3.20 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] + +[[models]] +id = "MiniMax-M2.1" +display_name = "MiniMax M2.1" +tier = "smart" +context_window = 1048576 +max_output_tokens = 16384 +input_cost_per_m = 1.00 +output_cost_per_m = 3.00 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "abab6.5-chat" +display_name = "ABAB 6.5 Chat" +tier = "balanced" +context_window = 245760 +max_output_tokens = 8192 +input_cost_per_m = 0.50 +output_cost_per_m = 1.50 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "abab7-chat" +display_name = "ABAB 7 Chat" +tier = "smart" +context_window = 524288 +max_output_tokens = 16384 +input_cost_per_m = 0.80 +output_cost_per_m = 2.40 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] diff --git a/providers/minimax.toml b/providers/minimax.toml new file mode 100644 index 0000000..609ec1f --- /dev/null +++ b/providers/minimax.toml @@ -0,0 +1,87 @@ +# MiniMax (International) — https://minimax.io +# Models: 6 + +[provider] +id = "minimax" +display_name = "MiniMax (International)" +api_key_env = "MINIMAX_API_KEY" +base_url = "https://api.minimax.io/v1" +key_required = true + +[[models]] +id = "minimax-text-01" +display_name = "MiniMax Text 01" +tier = "smart" +context_window = 1048576 +max_output_tokens = 16384 +input_cost_per_m = 1.00 +output_cost_per_m = 3.00 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = ["minimax"] + +[[models]] +id = "MiniMax-M2.5" +display_name = "MiniMax M2.5" +tier = "frontier" +context_window = 1048576 +max_output_tokens = 16384 +input_cost_per_m = 1.10 +output_cost_per_m = 4.40 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = ["minimax-m2.5"] + +[[models]] +id = "MiniMax-M2.5-highspeed" +display_name = "MiniMax M2.5 Highspeed" +tier = "smart" +context_window = 1048576 +max_output_tokens = 16384 +input_cost_per_m = 0.80 +output_cost_per_m = 3.20 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = ["minimax-m2.5-highspeed", "m2.5-highspeed"] + +[[models]] +id = "MiniMax-M2.1" +display_name = "MiniMax M2.1" +tier = "smart" +context_window = 1048576 +max_output_tokens = 16384 +input_cost_per_m = 1.00 +output_cost_per_m = 3.00 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = ["minimax-m2.1"] + +[[models]] +id = "abab6.5-chat" +display_name = "ABAB 6.5 Chat" +tier = "balanced" +context_window = 245760 +max_output_tokens = 8192 +input_cost_per_m = 0.50 +output_cost_per_m = 1.50 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "abab7-chat" +display_name = "ABAB 7 Chat" +tier = "smart" +context_window = 524288 +max_output_tokens = 16384 +input_cost_per_m = 0.80 +output_cost_per_m = 2.40 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = ["abab7"] diff --git a/providers/mistral.toml b/providers/mistral.toml new file mode 100644 index 0000000..2f3fcf9 --- /dev/null +++ b/providers/mistral.toml @@ -0,0 +1,87 @@ +# Mistral AI — https://mistral.ai +# Models: 6 + +[provider] +id = "mistral" +display_name = "Mistral AI" +api_key_env = "MISTRAL_API_KEY" +base_url = "https://api.mistral.ai/v1" +key_required = true + +[[models]] +id = "mistral-large-latest" +display_name = "Mistral Large" +tier = "smart" +context_window = 128000 +max_output_tokens = 8192 +input_cost_per_m = 2.00 +output_cost_per_m = 6.00 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = ["mistral"] + +[[models]] +id = "mistral-medium-latest" +display_name = "Mistral Medium" +tier = "balanced" +context_window = 128000 +max_output_tokens = 8192 +input_cost_per_m = 2.70 +output_cost_per_m = 8.10 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "mistral-small-latest" +display_name = "Mistral Small" +tier = "fast" +context_window = 128000 +max_output_tokens = 8192 +input_cost_per_m = 0.10 +output_cost_per_m = 0.30 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "codestral-latest" +display_name = "Codestral" +tier = "smart" +context_window = 32000 +max_output_tokens = 8192 +input_cost_per_m = 0.30 +output_cost_per_m = 0.90 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = ["codestral"] + +[[models]] +id = "open-mistral-nemo" +display_name = "Mistral Nemo" +tier = "fast" +context_window = 128000 +max_output_tokens = 8192 +input_cost_per_m = 0.15 +output_cost_per_m = 0.15 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = ["mistral-nemo"] + +[[models]] +id = "pixtral-large-latest" +display_name = "Pixtral Large" +tier = "smart" +context_window = 128000 +max_output_tokens = 8192 +input_cost_per_m = 2.00 +output_cost_per_m = 6.00 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = ["pixtral"] diff --git a/providers/moonshot.toml b/providers/moonshot.toml new file mode 100644 index 0000000..8e8a919 --- /dev/null +++ b/providers/moonshot.toml @@ -0,0 +1,74 @@ +# Moonshot / Kimi — https://moonshot.ai +# Models: 5 + +[provider] +id = "moonshot" +display_name = "Moonshot (Kimi)" +api_key_env = "MOONSHOT_API_KEY" +base_url = "https://api.moonshot.ai/v1" +key_required = true + +[[models]] +id = "moonshot-v1-128k" +display_name = "Moonshot V1 128K" +tier = "smart" +context_window = 131072 +max_output_tokens = 8192 +input_cost_per_m = 0.80 +output_cost_per_m = 0.80 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = ["moonshot"] + +[[models]] +id = "moonshot-v1-32k" +display_name = "Moonshot V1 32K" +tier = "balanced" +context_window = 32768 +max_output_tokens = 8192 +input_cost_per_m = 0.30 +output_cost_per_m = 0.30 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "moonshot-v1-8k" +display_name = "Moonshot V1 8K" +tier = "fast" +context_window = 8192 +max_output_tokens = 4096 +input_cost_per_m = 0.10 +output_cost_per_m = 0.10 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "kimi-k2" +display_name = "Kimi K2" +tier = "frontier" +context_window = 131072 +max_output_tokens = 16384 +input_cost_per_m = 2.00 +output_cost_per_m = 8.00 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = ["kimi"] + +[[models]] +id = "kimi-k2.5" +display_name = "Kimi K2.5" +tier = "frontier" +context_window = 131072 +max_output_tokens = 16384 +input_cost_per_m = 2.00 +output_cost_per_m = 8.00 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = ["kimi-k2.5-0711"] diff --git a/providers/ollama.toml b/providers/ollama.toml new file mode 100644 index 0000000..7d94bdc --- /dev/null +++ b/providers/ollama.toml @@ -0,0 +1,87 @@ +# Ollama — https://ollama.com +# Models: 6 (static entries; additional models discovered dynamically at runtime) + +[provider] +id = "ollama" +display_name = "Ollama" +api_key_env = "OLLAMA_API_KEY" +base_url = "http://localhost:11434/v1" +key_required = false + +[[models]] +id = "llama3.2" +display_name = "Llama 3.2 (Ollama)" +tier = "local" +context_window = 128000 +max_output_tokens = 4096 +input_cost_per_m = 0.0 +output_cost_per_m = 0.0 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "llama3.1" +display_name = "Llama 3.1 (Ollama)" +tier = "local" +context_window = 128000 +max_output_tokens = 4096 +input_cost_per_m = 0.0 +output_cost_per_m = 0.0 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "mistral:latest" +display_name = "Mistral (Ollama)" +tier = "local" +context_window = 32768 +max_output_tokens = 4096 +input_cost_per_m = 0.0 +output_cost_per_m = 0.0 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "qwen2.5" +display_name = "Qwen 2.5 (Ollama)" +tier = "local" +context_window = 32768 +max_output_tokens = 4096 +input_cost_per_m = 0.0 +output_cost_per_m = 0.0 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "phi3" +display_name = "Phi-3 (Ollama)" +tier = "local" +context_window = 128000 +max_output_tokens = 4096 +input_cost_per_m = 0.0 +output_cost_per_m = 0.0 +supports_tools = false +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "deepseek-r1:latest" +display_name = "DeepSeek R1 (Ollama)" +tier = "local" +context_window = 64000 +max_output_tokens = 4096 +input_cost_per_m = 0.0 +output_cost_per_m = 0.0 +supports_tools = false +supports_vision = false +supports_streaming = true +aliases = [] diff --git a/providers/openai.toml b/providers/openai.toml new file mode 100644 index 0000000..2b48a8c --- /dev/null +++ b/providers/openai.toml @@ -0,0 +1,245 @@ +# OpenAI — https://openai.com +# Models: 18 (including 2 Codex variants) + +[provider] +id = "openai" +display_name = "OpenAI" +api_key_env = "OPENAI_API_KEY" +base_url = "https://api.openai.com/v1" +key_required = true + +[[models]] +id = "gpt-4o" +display_name = "GPT-4o" +tier = "smart" +context_window = 128000 +max_output_tokens = 16384 +input_cost_per_m = 2.50 +output_cost_per_m = 10.0 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = ["gpt4", "gpt4o"] + +[[models]] +id = "gpt-4o-mini" +display_name = "GPT-4o Mini" +tier = "fast" +context_window = 128000 +max_output_tokens = 16384 +input_cost_per_m = 0.15 +output_cost_per_m = 0.60 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = ["gpt4-mini"] + +[[models]] +id = "gpt-4.1" +display_name = "GPT-4.1" +tier = "frontier" +context_window = 1047576 +max_output_tokens = 32768 +input_cost_per_m = 2.00 +output_cost_per_m = 8.00 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] + +[[models]] +id = "gpt-4.1-mini" +display_name = "GPT-4.1 Mini" +tier = "balanced" +context_window = 1047576 +max_output_tokens = 32768 +input_cost_per_m = 0.40 +output_cost_per_m = 1.60 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] + +[[models]] +id = "gpt-4.1-nano" +display_name = "GPT-4.1 Nano" +tier = "fast" +context_window = 1047576 +max_output_tokens = 32768 +input_cost_per_m = 0.10 +output_cost_per_m = 0.40 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "o3" +display_name = "o3" +tier = "frontier" +context_window = 200000 +max_output_tokens = 100000 +input_cost_per_m = 2.00 +output_cost_per_m = 8.00 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] + +[[models]] +id = "o3-mini" +display_name = "o3-mini" +tier = "smart" +context_window = 200000 +max_output_tokens = 100000 +input_cost_per_m = 1.10 +output_cost_per_m = 4.40 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "o4-mini" +display_name = "o4-mini" +tier = "smart" +context_window = 200000 +max_output_tokens = 100000 +input_cost_per_m = 1.10 +output_cost_per_m = 4.40 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] + +[[models]] +id = "gpt-4-turbo" +display_name = "GPT-4 Turbo" +tier = "smart" +context_window = 128000 +max_output_tokens = 4096 +input_cost_per_m = 10.00 +output_cost_per_m = 30.00 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] + +[[models]] +id = "gpt-3.5-turbo" +display_name = "GPT-3.5 Turbo" +tier = "fast" +context_window = 16385 +max_output_tokens = 4096 +input_cost_per_m = 0.50 +output_cost_per_m = 1.50 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "gpt-5" +display_name = "GPT-5" +tier = "frontier" +context_window = 400000 +max_output_tokens = 128000 +input_cost_per_m = 1.25 +output_cost_per_m = 10.0 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] + +[[models]] +id = "gpt-5-mini" +display_name = "GPT-5 Mini" +tier = "balanced" +context_window = 400000 +max_output_tokens = 128000 +input_cost_per_m = 0.25 +output_cost_per_m = 2.0 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = ["gpt5-mini"] + +[[models]] +id = "gpt-5-nano" +display_name = "GPT-5 Nano" +tier = "fast" +context_window = 400000 +max_output_tokens = 128000 +input_cost_per_m = 0.05 +output_cost_per_m = 0.40 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "gpt-5.1" +display_name = "GPT-5.1" +tier = "frontier" +context_window = 400000 +max_output_tokens = 128000 +input_cost_per_m = 1.25 +output_cost_per_m = 10.0 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] + +[[models]] +id = "gpt-5.2" +display_name = "GPT-5.2" +tier = "frontier" +context_window = 400000 +max_output_tokens = 128000 +input_cost_per_m = 1.75 +output_cost_per_m = 14.0 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = ["gpt5"] + +[[models]] +id = "gpt-5.2-pro" +display_name = "GPT-5.2 Pro" +tier = "frontier" +context_window = 400000 +max_output_tokens = 128000 +input_cost_per_m = 1.75 +output_cost_per_m = 14.0 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] + +# Codex variants (same OpenAI driver & API key) + +[[models]] +id = "codex/gpt-4.1" +display_name = "GPT-4.1 (Codex)" +tier = "frontier" +context_window = 1047576 +max_output_tokens = 32768 +input_cost_per_m = 2.00 +output_cost_per_m = 8.00 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = ["codex", "codex-4.1"] + +[[models]] +id = "codex/o4-mini" +display_name = "o4-mini (Codex)" +tier = "smart" +context_window = 200000 +max_output_tokens = 100000 +input_cost_per_m = 1.10 +output_cost_per_m = 4.40 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = ["codex-o4"] diff --git a/providers/openrouter.toml b/providers/openrouter.toml new file mode 100644 index 0000000..ad9ce5f --- /dev/null +++ b/providers/openrouter.toml @@ -0,0 +1,219 @@ +# OpenRouter — https://openrouter.ai +# Models: 16 (10 paid + 6 free) + +[provider] +id = "openrouter" +display_name = "OpenRouter" +api_key_env = "OPENROUTER_API_KEY" +base_url = "https://openrouter.ai/api/v1" +key_required = true + +[[models]] +id = "openrouter/google/gemini-2.5-flash" +display_name = "Gemini 2.5 Flash (OpenRouter)" +tier = "smart" +context_window = 1048576 +max_output_tokens = 65536 +input_cost_per_m = 0.15 +output_cost_per_m = 0.60 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] + +[[models]] +id = "openrouter/anthropic/claude-sonnet-4" +display_name = "Claude Sonnet 4 (OpenRouter)" +tier = "smart" +context_window = 200000 +max_output_tokens = 64000 +input_cost_per_m = 3.0 +output_cost_per_m = 15.0 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] + +[[models]] +id = "openrouter/openai/gpt-4o" +display_name = "GPT-4o (OpenRouter)" +tier = "smart" +context_window = 128000 +max_output_tokens = 16384 +input_cost_per_m = 2.5 +output_cost_per_m = 10.0 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] + +[[models]] +id = "openrouter/deepseek/deepseek-chat" +display_name = "DeepSeek V3 (OpenRouter)" +tier = "smart" +context_window = 128000 +max_output_tokens = 32768 +input_cost_per_m = 0.14 +output_cost_per_m = 0.28 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "openrouter/meta-llama/llama-3.3-70b-instruct" +display_name = "Llama 3.3 70B (OpenRouter)" +tier = "balanced" +context_window = 128000 +max_output_tokens = 32768 +input_cost_per_m = 0.39 +output_cost_per_m = 0.39 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "openrouter/qwen/qwen-2.5-72b-instruct" +display_name = "Qwen 2.5 72B (OpenRouter)" +tier = "balanced" +context_window = 128000 +max_output_tokens = 32768 +input_cost_per_m = 0.36 +output_cost_per_m = 0.36 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "openrouter/google/gemini-2.5-pro" +display_name = "Gemini 2.5 Pro (OpenRouter)" +tier = "frontier" +context_window = 1048576 +max_output_tokens = 65536 +input_cost_per_m = 1.25 +output_cost_per_m = 10.0 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] + +[[models]] +id = "openrouter/mistralai/mistral-large-latest" +display_name = "Mistral Large (OpenRouter)" +tier = "smart" +context_window = 128000 +max_output_tokens = 8192 +input_cost_per_m = 2.0 +output_cost_per_m = 6.0 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "openrouter/google/gemma-2-9b-it" +display_name = "Gemma 2 9B (OpenRouter)" +tier = "fast" +context_window = 8192 +max_output_tokens = 4096 +input_cost_per_m = 0.0 +output_cost_per_m = 0.0 +supports_tools = false +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "openrouter/deepseek/deepseek-r1" +display_name = "DeepSeek R1 (OpenRouter)" +tier = "frontier" +context_window = 128000 +max_output_tokens = 32768 +input_cost_per_m = 0.55 +output_cost_per_m = 2.19 +supports_tools = false +supports_vision = false +supports_streaming = true +aliases = [] + +# Free models + +[[models]] +id = "openrouter/google/gemma-2-9b-it:free" +display_name = "Gemma 2 9B Free (OpenRouter)" +tier = "fast" +context_window = 8192 +max_output_tokens = 4096 +input_cost_per_m = 0.0 +output_cost_per_m = 0.0 +supports_tools = false +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "openrouter/meta-llama/llama-3.1-8b-instruct:free" +display_name = "Llama 3.1 8B Free (OpenRouter)" +tier = "fast" +context_window = 131072 +max_output_tokens = 4096 +input_cost_per_m = 0.0 +output_cost_per_m = 0.0 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "openrouter/qwen/qwen-2.5-7b-instruct:free" +display_name = "Qwen 2.5 7B Free (OpenRouter)" +tier = "fast" +context_window = 32768 +max_output_tokens = 4096 +input_cost_per_m = 0.0 +output_cost_per_m = 0.0 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "openrouter/mistralai/mistral-7b-instruct:free" +display_name = "Mistral 7B Free (OpenRouter)" +tier = "fast" +context_window = 32768 +max_output_tokens = 4096 +input_cost_per_m = 0.0 +output_cost_per_m = 0.0 +supports_tools = false +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "openrouter/huggingfaceh4/zephyr-7b-beta:free" +display_name = "Zephyr 7B Free (OpenRouter)" +tier = "fast" +context_window = 4096 +max_output_tokens = 2048 +input_cost_per_m = 0.0 +output_cost_per_m = 0.0 +supports_tools = false +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "openrouter/deepseek/deepseek-r1:free" +display_name = "DeepSeek R1 Free (OpenRouter)" +tier = "smart" +context_window = 128000 +max_output_tokens = 32768 +input_cost_per_m = 0.0 +output_cost_per_m = 0.0 +supports_tools = false +supports_vision = false +supports_streaming = true +aliases = [] diff --git a/providers/perplexity.toml b/providers/perplexity.toml new file mode 100644 index 0000000..c7f7883 --- /dev/null +++ b/providers/perplexity.toml @@ -0,0 +1,61 @@ +# Perplexity AI — https://perplexity.ai +# Models: 4 + +[provider] +id = "perplexity" +display_name = "Perplexity AI" +api_key_env = "PERPLEXITY_API_KEY" +base_url = "https://api.perplexity.ai" +key_required = true + +[[models]] +id = "sonar-pro" +display_name = "Sonar Pro" +tier = "smart" +context_window = 200000 +max_output_tokens = 8192 +input_cost_per_m = 3.0 +output_cost_per_m = 15.0 +supports_tools = false +supports_vision = false +supports_streaming = true +aliases = ["sonar"] + +[[models]] +id = "sonar-reasoning-pro" +display_name = "Sonar Reasoning Pro" +tier = "frontier" +context_window = 200000 +max_output_tokens = 8192 +input_cost_per_m = 2.0 +output_cost_per_m = 8.0 +supports_tools = false +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "sonar-reasoning" +display_name = "Sonar Reasoning" +tier = "balanced" +context_window = 128000 +max_output_tokens = 8192 +input_cost_per_m = 1.0 +output_cost_per_m = 5.0 +supports_tools = false +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "sonar-basic" +display_name = "Sonar" +tier = "fast" +context_window = 128000 +max_output_tokens = 8192 +input_cost_per_m = 1.0 +output_cost_per_m = 5.0 +supports_tools = false +supports_vision = false +supports_streaming = true +aliases = [] diff --git a/providers/qianfan.toml b/providers/qianfan.toml new file mode 100644 index 0000000..47d2d65 --- /dev/null +++ b/providers/qianfan.toml @@ -0,0 +1,48 @@ +# Baidu Qianfan / ERNIE — https://qianfan.baidubce.com +# Models: 3 + +[provider] +id = "qianfan" +display_name = "Baidu Qianfan" +api_key_env = "QIANFAN_API_KEY" +base_url = "https://qianfan.baidubce.com/v2" +key_required = true + +[[models]] +id = "ernie-4.5-8k" +display_name = "ERNIE 4.5 8K" +tier = "smart" +context_window = 8192 +max_output_tokens = 4096 +input_cost_per_m = 2.00 +output_cost_per_m = 6.00 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = ["ernie"] + +[[models]] +id = "ernie-4.0-turbo-8k" +display_name = "ERNIE 4.0 Turbo 8K" +tier = "balanced" +context_window = 8192 +max_output_tokens = 4096 +input_cost_per_m = 1.00 +output_cost_per_m = 3.00 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "ernie-speed-128k" +display_name = "ERNIE Speed 128K" +tier = "fast" +context_window = 131072 +max_output_tokens = 4096 +input_cost_per_m = 0.0 +output_cost_per_m = 0.0 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] diff --git a/providers/qwen.toml b/providers/qwen.toml new file mode 100644 index 0000000..b21b7e5 --- /dev/null +++ b/providers/qwen.toml @@ -0,0 +1,152 @@ +# Qwen / Alibaba — https://dashscope.aliyuncs.com +# Models: 11 + +[provider] +id = "qwen" +display_name = "Qwen (Alibaba)" +api_key_env = "DASHSCOPE_API_KEY" +base_url = "https://dashscope.aliyuncs.com/compatible-mode/v1" +key_required = true + +[[models]] +id = "qwen-max" +display_name = "Qwen Max" +tier = "frontier" +context_window = 32768 +max_output_tokens = 8192 +input_cost_per_m = 4.00 +output_cost_per_m = 12.00 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "qwen-plus" +display_name = "Qwen Plus" +tier = "smart" +context_window = 131072 +max_output_tokens = 8192 +input_cost_per_m = 0.80 +output_cost_per_m = 2.00 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = ["qwen"] + +[[models]] +id = "qwen-turbo" +display_name = "Qwen Turbo" +tier = "fast" +context_window = 131072 +max_output_tokens = 8192 +input_cost_per_m = 0.30 +output_cost_per_m = 0.60 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "qwen-vl-plus" +display_name = "Qwen VL Plus" +tier = "smart" +context_window = 32768 +max_output_tokens = 8192 +input_cost_per_m = 1.50 +output_cost_per_m = 4.50 +supports_tools = false +supports_vision = true +supports_streaming = true +aliases = [] + +[[models]] +id = "qwen-coder-plus" +display_name = "Qwen Coder Plus" +tier = "smart" +context_window = 131072 +max_output_tokens = 8192 +input_cost_per_m = 0.80 +output_cost_per_m = 2.00 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "qwen-long" +display_name = "Qwen Long" +tier = "balanced" +context_window = 1000000 +max_output_tokens = 8192 +input_cost_per_m = 0.50 +output_cost_per_m = 2.00 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "qwen3-235b-a22b" +display_name = "Qwen3 235B" +tier = "frontier" +context_window = 131072 +max_output_tokens = 8192 +input_cost_per_m = 4.00 +output_cost_per_m = 12.00 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = ["qwen3"] + +[[models]] +id = "qwen3-30b-a3b" +display_name = "Qwen3 30B" +tier = "fast" +context_window = 131072 +max_output_tokens = 8192 +input_cost_per_m = 0.30 +output_cost_per_m = 0.60 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "qwen-coder-plus-latest" +display_name = "Qwen Coder Plus (Latest)" +tier = "smart" +context_window = 131072 +max_output_tokens = 8192 +input_cost_per_m = 0.80 +output_cost_per_m = 2.00 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = ["qwen-coder"] + +[[models]] +id = "qwen2.5-coder-32b-instruct" +display_name = "Qwen 2.5 Coder 32B" +tier = "balanced" +context_window = 131072 +max_output_tokens = 8192 +input_cost_per_m = 0.80 +output_cost_per_m = 2.00 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "qwen-vl-max" +display_name = "Qwen VL Max" +tier = "frontier" +context_window = 32768 +max_output_tokens = 8192 +input_cost_per_m = 3.00 +output_cost_per_m = 9.00 +supports_tools = false +supports_vision = true +supports_streaming = true +aliases = [] diff --git a/providers/replicate.toml b/providers/replicate.toml new file mode 100644 index 0000000..3f32b76 --- /dev/null +++ b/providers/replicate.toml @@ -0,0 +1,48 @@ +# Replicate — https://replicate.com +# Models: 3 + +[provider] +id = "replicate" +display_name = "Replicate" +api_key_env = "REPLICATE_API_TOKEN" +base_url = "https://api.replicate.com/v1" +key_required = true + +[[models]] +id = "replicate/meta-llama-3.3-70b-instruct" +display_name = "Llama 3.3 70B (Replicate)" +tier = "balanced" +context_window = 128000 +max_output_tokens = 4096 +input_cost_per_m = 0.40 +output_cost_per_m = 0.40 +supports_tools = false +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "replicate/deepseek-r1" +display_name = "DeepSeek R1 (Replicate)" +tier = "smart" +context_window = 64000 +max_output_tokens = 4096 +input_cost_per_m = 0.40 +output_cost_per_m = 0.40 +supports_tools = false +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "replicate/mistral-7b-instruct" +display_name = "Mistral 7B (Replicate)" +tier = "fast" +context_window = 32768 +max_output_tokens = 4096 +input_cost_per_m = 0.05 +output_cost_per_m = 0.25 +supports_tools = false +supports_vision = false +supports_streaming = true +aliases = [] diff --git a/providers/sambanova.toml b/providers/sambanova.toml new file mode 100644 index 0000000..7e081e3 --- /dev/null +++ b/providers/sambanova.toml @@ -0,0 +1,48 @@ +# SambaNova — https://sambanova.ai +# Models: 3 + +[provider] +id = "sambanova" +display_name = "SambaNova" +api_key_env = "SAMBANOVA_API_KEY" +base_url = "https://api.sambanova.ai/v1" +key_required = true + +[[models]] +id = "sambanova/llama-3.3-70b" +display_name = "Llama 3.3 70B (SambaNova)" +tier = "balanced" +context_window = 128000 +max_output_tokens = 8192 +input_cost_per_m = 0.06 +output_cost_per_m = 0.06 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "sambanova/deepseek-r1" +display_name = "DeepSeek R1 (SambaNova)" +tier = "smart" +context_window = 64000 +max_output_tokens = 8192 +input_cost_per_m = 0.06 +output_cost_per_m = 0.06 +supports_tools = false +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "sambanova/qwen-2.5-72b" +display_name = "Qwen 2.5 72B (SambaNova)" +tier = "smart" +context_window = 32768 +max_output_tokens = 8192 +input_cost_per_m = 0.06 +output_cost_per_m = 0.06 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] diff --git a/providers/together.toml b/providers/together.toml new file mode 100644 index 0000000..069cdb5 --- /dev/null +++ b/providers/together.toml @@ -0,0 +1,113 @@ +# Together AI — https://together.ai +# Models: 8 + +[provider] +id = "together" +display_name = "Together AI" +api_key_env = "TOGETHER_API_KEY" +base_url = "https://api.together.xyz/v1" +key_required = true + +[[models]] +id = "meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo" +display_name = "Llama 3.1 405B (Together)" +tier = "frontier" +context_window = 130000 +max_output_tokens = 4096 +input_cost_per_m = 3.50 +output_cost_per_m = 3.50 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "meta-llama/Llama-3.3-70B-Instruct-Turbo" +display_name = "Llama 3.3 70B (Together)" +tier = "smart" +context_window = 128000 +max_output_tokens = 4096 +input_cost_per_m = 0.88 +output_cost_per_m = 0.88 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8" +display_name = "Llama 4 Maverick (Together)" +tier = "smart" +context_window = 1048576 +max_output_tokens = 8192 +input_cost_per_m = 0.27 +output_cost_per_m = 0.35 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "meta-llama/Llama-4-Scout-17B-16E-Instruct" +display_name = "Llama 4 Scout (Together)" +tier = "balanced" +context_window = 512000 +max_output_tokens = 8192 +input_cost_per_m = 0.18 +output_cost_per_m = 0.30 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "deepseek-ai/DeepSeek-R1" +display_name = "DeepSeek R1 (Together)" +tier = "frontier" +context_window = 64000 +max_output_tokens = 8192 +input_cost_per_m = 3.00 +output_cost_per_m = 7.00 +supports_tools = false +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "deepseek-ai/DeepSeek-V3" +display_name = "DeepSeek V3 (Together)" +tier = "smart" +context_window = 64000 +max_output_tokens = 8192 +input_cost_per_m = 0.90 +output_cost_per_m = 0.90 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "Qwen/Qwen2.5-72B-Instruct-Turbo" +display_name = "Qwen 2.5 72B (Together)" +tier = "smart" +context_window = 32768 +max_output_tokens = 4096 +input_cost_per_m = 0.20 +output_cost_per_m = 0.60 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "mistralai/Mixtral-8x22B-Instruct-v0.1" +display_name = "Mixtral 8x22B (Together)" +tier = "balanced" +context_window = 65536 +max_output_tokens = 4096 +input_cost_per_m = 0.60 +output_cost_per_m = 0.60 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] diff --git a/providers/venice.toml b/providers/venice.toml new file mode 100644 index 0000000..ca9cde6 --- /dev/null +++ b/providers/venice.toml @@ -0,0 +1,48 @@ +# Venice.ai — https://venice.ai +# Models: 3 + +[provider] +id = "venice" +display_name = "Venice.ai" +api_key_env = "VENICE_API_KEY" +base_url = "https://api.venice.ai/api/v1" +key_required = true + +[[models]] +id = "venice-uncensored" +display_name = "Venice Uncensored" +tier = "fast" +context_window = 32000 +max_output_tokens = 8192 +input_cost_per_m = 0.20 +output_cost_per_m = 0.90 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = ["venice"] + +[[models]] +id = "llama-3.3-70b" +display_name = "Llama 3.3 70B (Venice)" +tier = "balanced" +context_window = 128000 +max_output_tokens = 8192 +input_cost_per_m = 0.20 +output_cost_per_m = 0.90 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "qwen3-235b-a22b-instruct-2507" +display_name = "Qwen3 235B A22B (Venice)" +tier = "smart" +context_window = 128000 +max_output_tokens = 8192 +input_cost_per_m = 0.20 +output_cost_per_m = 0.90 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] diff --git a/providers/vllm.toml b/providers/vllm.toml new file mode 100644 index 0000000..36397dc --- /dev/null +++ b/providers/vllm.toml @@ -0,0 +1,22 @@ +# vLLM — https://vllm.ai +# Models: 1 (generic entry; additional models discovered dynamically at runtime) + +[provider] +id = "vllm" +display_name = "vLLM" +api_key_env = "VLLM_API_KEY" +base_url = "http://localhost:8000/v1" +key_required = false + +[[models]] +id = "vllm-local" +display_name = "vLLM Local Model" +tier = "local" +context_window = 32768 +max_output_tokens = 4096 +input_cost_per_m = 0.0 +output_cost_per_m = 0.0 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] diff --git a/providers/volcengine-coding.toml b/providers/volcengine-coding.toml new file mode 100644 index 0000000..c0cda0b --- /dev/null +++ b/providers/volcengine-coding.toml @@ -0,0 +1,9 @@ +# Volcano Engine Coding Plan — https://volcengine.com +# Models: 0 (uses same API, coding-specific endpoint) + +[provider] +id = "volcengine_coding" +display_name = "Volcano Engine Coding Plan" +api_key_env = "VOLCENGINE_API_KEY" +base_url = "https://ark.cn-beijing.volces.com/api/coding/v3" +key_required = true diff --git a/providers/volcengine.toml b/providers/volcengine.toml new file mode 100644 index 0000000..980fcf2 --- /dev/null +++ b/providers/volcengine.toml @@ -0,0 +1,61 @@ +# Volcano Engine / Doubao — https://volcengine.com +# Models: 4 + +[provider] +id = "volcengine" +display_name = "Volcano Engine (Doubao)" +api_key_env = "VOLCENGINE_API_KEY" +base_url = "https://ark.cn-beijing.volces.com/api/v3" +key_required = true + +[[models]] +id = "doubao-seed-1-6-251015" +display_name = "Doubao Seed 1.6 Pro" +tier = "smart" +context_window = 262144 +max_output_tokens = 16384 +input_cost_per_m = 0.80 +output_cost_per_m = 2.00 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = ["doubao", "doubao-pro"] + +[[models]] +id = "doubao-seed-2-0-lite" +display_name = "Doubao Seed 2.0 Lite" +tier = "balanced" +context_window = 131072 +max_output_tokens = 16384 +input_cost_per_m = 0.30 +output_cost_per_m = 0.60 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = ["doubao-lite"] + +[[models]] +id = "doubao-seed-2-0-mini" +display_name = "Doubao Seed 2.0 Mini" +tier = "fast" +context_window = 131072 +max_output_tokens = 16384 +input_cost_per_m = 0.10 +output_cost_per_m = 0.10 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = ["doubao-mini"] + +[[models]] +id = "doubao-seed-code" +display_name = "Doubao Seed Code" +tier = "smart" +context_window = 131072 +max_output_tokens = 16384 +input_cost_per_m = 0.50 +output_cost_per_m = 1.00 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = ["doubao-code"] diff --git a/providers/xai.toml b/providers/xai.toml new file mode 100644 index 0000000..39a1485 --- /dev/null +++ b/providers/xai.toml @@ -0,0 +1,126 @@ +# xAI — https://x.ai +# Models: 9 + +[provider] +id = "xai" +display_name = "xAI" +api_key_env = "XAI_API_KEY" +base_url = "https://api.x.ai/v1" +key_required = true + +[[models]] +id = "grok-4-0709" +display_name = "Grok 4" +tier = "frontier" +context_window = 256000 +max_output_tokens = 32768 +input_cost_per_m = 3.0 +output_cost_per_m = 15.0 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = ["grok", "grok-4"] + +[[models]] +id = "grok-4-fast-reasoning" +display_name = "Grok 4 Fast Reasoning" +tier = "smart" +context_window = 256000 +max_output_tokens = 32768 +input_cost_per_m = 1.0 +output_cost_per_m = 5.0 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "grok-4-fast-non-reasoning" +display_name = "Grok 4 Fast Non-Reasoning" +tier = "smart" +context_window = 256000 +max_output_tokens = 32768 +input_cost_per_m = 1.0 +output_cost_per_m = 5.0 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "grok-4-1-fast-reasoning" +display_name = "Grok 4.1 Fast Reasoning" +tier = "fast" +context_window = 2000000 +max_output_tokens = 32768 +input_cost_per_m = 0.20 +output_cost_per_m = 0.50 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = ["grok-fast"] + +[[models]] +id = "grok-4-1-fast-non-reasoning" +display_name = "Grok 4.1 Fast Non-Reasoning" +tier = "fast" +context_window = 2000000 +max_output_tokens = 32768 +input_cost_per_m = 0.20 +output_cost_per_m = 0.50 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "grok-3" +display_name = "Grok 3" +tier = "frontier" +context_window = 131072 +max_output_tokens = 32768 +input_cost_per_m = 3.0 +output_cost_per_m = 15.0 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = ["grok3"] + +[[models]] +id = "grok-3-mini" +display_name = "Grok 3 Mini" +tier = "balanced" +context_window = 131072 +max_output_tokens = 32768 +input_cost_per_m = 0.30 +output_cost_per_m = 0.50 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "grok-2" +display_name = "Grok 2" +tier = "smart" +context_window = 131072 +max_output_tokens = 32768 +input_cost_per_m = 2.0 +output_cost_per_m = 10.0 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] + +[[models]] +id = "grok-2-mini" +display_name = "Grok 2 Mini" +tier = "fast" +context_window = 131072 +max_output_tokens = 32768 +input_cost_per_m = 0.30 +output_cost_per_m = 0.50 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = ["grok-mini"] diff --git a/providers/zai-coding.toml b/providers/zai-coding.toml new file mode 100644 index 0000000..b7190bc --- /dev/null +++ b/providers/zai-coding.toml @@ -0,0 +1,35 @@ +# Z.AI Coding / GLM Coding Models — https://api.z.ai +# Models: 2 + +[provider] +id = "zai_coding" +display_name = "Z.AI Coding" +api_key_env = "ZHIPU_API_KEY" +base_url = "https://api.z.ai/api/coding/paas/v4" +key_required = true + +[[models]] +id = "glm-5-coding" +display_name = "GLM-5 Coding" +tier = "frontier" +context_window = 131072 +max_output_tokens = 16384 +input_cost_per_m = 2.00 +output_cost_per_m = 8.00 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = ["glm-5-code", "glm-coding"] + +[[models]] +id = "glm-4.7-coding" +display_name = "GLM-4.7 Coding" +tier = "smart" +context_window = 131072 +max_output_tokens = 16384 +input_cost_per_m = 1.50 +output_cost_per_m = 5.00 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = ["glm-4.7-code"] diff --git a/providers/zai.toml b/providers/zai.toml new file mode 100644 index 0000000..3b4f43a --- /dev/null +++ b/providers/zai.toml @@ -0,0 +1,9 @@ +# Z.AI — https://api.z.ai (Zhipu domain alias) +# Models: 0 (uses same models as zhipu, different domain) + +[provider] +id = "zai" +display_name = "Z.AI" +api_key_env = "ZHIPU_API_KEY" +base_url = "https://api.z.ai/api/paas/v4" +key_required = true diff --git a/providers/zhipu-coding.toml b/providers/zhipu-coding.toml new file mode 100644 index 0000000..a9b230f --- /dev/null +++ b/providers/zhipu-coding.toml @@ -0,0 +1,22 @@ +# Zhipu Coding / CodeGeeX — https://open.bigmodel.cn +# Models: 1 + +[provider] +id = "zhipu_coding" +display_name = "Zhipu Coding (CodeGeeX)" +api_key_env = "ZHIPU_API_KEY" +base_url = "https://open.bigmodel.cn/api/coding/paas/v4" +key_required = true + +[[models]] +id = "codegeex-4" +display_name = "CodeGeeX 4" +tier = "smart" +context_window = 131072 +max_output_tokens = 8192 +input_cost_per_m = 0.10 +output_cost_per_m = 0.10 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = ["codegeex"] diff --git a/providers/zhipu.toml b/providers/zhipu.toml new file mode 100644 index 0000000..87e0ad0 --- /dev/null +++ b/providers/zhipu.toml @@ -0,0 +1,87 @@ +# Zhipu AI (GLM) — https://open.bigmodel.cn +# Models: 6 + +[provider] +id = "zhipu" +display_name = "Zhipu AI (GLM)" +api_key_env = "ZHIPU_API_KEY" +base_url = "https://open.bigmodel.cn/api/paas/v4" +key_required = true + +[[models]] +id = "glm-4-plus" +display_name = "GLM-4 Plus" +tier = "smart" +context_window = 131072 +max_output_tokens = 8192 +input_cost_per_m = 0.60 +output_cost_per_m = 2.20 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = ["glm"] + +[[models]] +id = "glm-4-flash" +display_name = "GLM-4 Flash" +tier = "fast" +context_window = 131072 +max_output_tokens = 8192 +input_cost_per_m = 0.0 +output_cost_per_m = 0.0 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "glm-4v-plus" +display_name = "GLM-4V Plus" +tier = "smart" +context_window = 8192 +max_output_tokens = 4096 +input_cost_per_m = 0.60 +output_cost_per_m = 2.20 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] + +[[models]] +id = "glm-4-long" +display_name = "GLM-4 Long" +tier = "balanced" +context_window = 1000000 +max_output_tokens = 8192 +input_cost_per_m = 0.10 +output_cost_per_m = 0.10 +supports_tools = true +supports_vision = false +supports_streaming = true +aliases = [] + +[[models]] +id = "glm-5-20250605" +display_name = "GLM-5" +tier = "frontier" +context_window = 131072 +max_output_tokens = 16384 +input_cost_per_m = 1.00 +output_cost_per_m = 3.20 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = ["glm-5"] + +[[models]] +id = "glm-4.7" +display_name = "GLM-4.7" +tier = "smart" +context_window = 131072 +max_output_tokens = 16384 +input_cost_per_m = 0.60 +output_cost_per_m = 2.20 +supports_tools = true +supports_vision = true +supports_streaming = true +aliases = [] diff --git a/schema.toml b/schema.toml new file mode 100644 index 0000000..d2e0ac0 --- /dev/null +++ b/schema.toml @@ -0,0 +1,31 @@ +# Model Catalog Schema Reference +# ================================ +# This file documents all available fields and their types. +# It is NOT a real provider file — it exists purely as documentation. +# +# Required fields are marked. All other fields are optional. + +[provider] +id = "provider-id" # Required: unique provider identifier (lowercase, hyphenated) +display_name = "Provider Name" # Required: human-readable display name +api_key_env = "PROVIDER_API_KEY" # Required: environment variable name for the API key +base_url = "https://api.example.com" # Required: default API base URL +key_required = true # Required: whether an API key is needed (false for local providers) + +[[models]] +id = "model-id" # Required: unique model identifier +display_name = "Human Name" # Required: human-readable display name +tier = "smart" # Required: one of "frontier", "smart", "balanced", "fast", "local" + # frontier — cutting-edge, most capable (e.g. Claude Opus, GPT-4.1) + # smart — smart, cost-effective (e.g. Claude Sonnet, Gemini 2.5 Flash) + # balanced — balanced speed/cost + # fast — fastest, cheapest for simple tasks + # local — local models (Ollama, vLLM, LM Studio) +context_window = 128000 # Required: maximum input tokens +max_output_tokens = 16384 # Required: maximum output tokens +input_cost_per_m = 2.50 # Required: USD per million input tokens (0.0 for free/local) +output_cost_per_m = 10.0 # Required: USD per million output tokens (0.0 for free/local) +supports_tools = true # Optional: tool/function calling support (default: false) +supports_vision = true # Optional: vision/image input support (default: false) +supports_streaming = true # Optional: streaming response support (default: true) +aliases = ["alias1", "alias2"] # Optional: alternative names for this model diff --git a/scripts/validate.py b/scripts/validate.py new file mode 100755 index 0000000..d835ce8 --- /dev/null +++ b/scripts/validate.py @@ -0,0 +1,233 @@ +#!/usr/bin/env python3 +"""Validate all TOML files in the model catalog against the schema. + +Usage: + python scripts/validate.py + +Checks: + - All provider TOML files parse correctly + - Required provider fields exist + - Required model fields exist for each [[models]] entry + - Tier values are one of: frontier, smart, balanced, fast, local + - Cost values are non-negative + - context_window and max_output_tokens are positive integers + - No duplicate model IDs within the same provider file + - No duplicate model IDs across ALL provider files (same provider) + - aliases.toml parses correctly + +Exit code 0 on success, 1 on any validation error. +""" + +import os +import sys +from pathlib import Path + +try: + import tomllib # Python 3.11+ +except ImportError: + try: + import tomli as tomllib # pip install tomli + except ImportError: + print("ERROR: Python 3.11+ required, or install 'tomli': pip install tomli") + sys.exit(1) + +VALID_TIERS = {"frontier", "smart", "balanced", "fast", "local"} + +REQUIRED_PROVIDER_FIELDS = {"id", "display_name", "api_key_env", "base_url", "key_required"} + +REQUIRED_MODEL_FIELDS = { + "id", + "display_name", + "tier", + "context_window", + "max_output_tokens", + "input_cost_per_m", + "output_cost_per_m", +} + + +def validate_provider_file(filepath: Path) -> list[str]: + """Validate a single provider TOML file. Returns list of error messages.""" + errors = [] + + try: + with open(filepath, "rb") as f: + data = tomllib.load(f) + except Exception as e: + return [f"{filepath.name}: Failed to parse TOML: {e}"] + + # Validate [provider] section + provider = data.get("provider") + if provider is None: + errors.append(f"{filepath.name}: Missing [provider] section") + else: + for field in REQUIRED_PROVIDER_FIELDS: + if field not in provider: + errors.append(f"{filepath.name}: Missing provider field '{field}'") + + # Validate [[models]] entries + models = data.get("models", []) + seen_ids = set() + + for i, model in enumerate(models): + model_label = model.get("id", f"models[{i}]") + + # Check required fields + for field in REQUIRED_MODEL_FIELDS: + if field not in model: + errors.append(f"{filepath.name}: Model '{model_label}' missing field '{field}'") + + # Validate tier + tier = model.get("tier") + if tier is not None and tier not in VALID_TIERS: + errors.append( + f"{filepath.name}: Model '{model_label}' has invalid tier '{tier}' " + f"(must be one of: {', '.join(sorted(VALID_TIERS))})" + ) + + # Validate costs + for cost_field in ("input_cost_per_m", "output_cost_per_m"): + val = model.get(cost_field) + if val is not None and (not isinstance(val, (int, float)) or val < 0): + errors.append( + f"{filepath.name}: Model '{model_label}' has invalid {cost_field}: {val} " + f"(must be >= 0)" + ) + + # Validate context_window and max_output_tokens + for int_field in ("context_window", "max_output_tokens"): + val = model.get(int_field) + if val is not None and (not isinstance(val, int) or val <= 0): + errors.append( + f"{filepath.name}: Model '{model_label}' has invalid {int_field}: {val} " + f"(must be a positive integer)" + ) + + # Check for duplicate IDs within the file + model_id = model.get("id") + if model_id: + if model_id in seen_ids: + errors.append( + f"{filepath.name}: Duplicate model ID '{model_id}' within file" + ) + seen_ids.add(model_id) + + return errors + + +def validate_aliases_file(filepath: Path) -> list[str]: + """Validate aliases.toml. Returns list of error messages.""" + if not filepath.exists(): + return [f"aliases.toml: File not found at {filepath}"] + + try: + with open(filepath, "rb") as f: + data = tomllib.load(f) + except Exception as e: + return [f"aliases.toml: Failed to parse TOML: {e}"] + + errors = [] + aliases = data.get("aliases", {}) + if not isinstance(aliases, dict): + errors.append("aliases.toml: [aliases] must be a table of string -> string mappings") + else: + for alias, target in aliases.items(): + if not isinstance(target, str): + errors.append(f"aliases.toml: Alias '{alias}' must map to a string, got {type(target).__name__}") + + return errors + + +def main(): + # Find the catalog root + script_dir = Path(__file__).resolve().parent + catalog_root = script_dir.parent + providers_dir = catalog_root / "providers" + + if not providers_dir.is_dir(): + print(f"ERROR: providers/ directory not found at {providers_dir}") + sys.exit(1) + + all_errors = [] + total_models = 0 + provider_counts = {} + global_model_ids = {} # model_id -> (provider_id, filename) + + # Validate each provider file + toml_files = sorted(providers_dir.glob("*.toml")) + if not toml_files: + print("ERROR: No .toml files found in providers/") + sys.exit(1) + + for filepath in toml_files: + errors = validate_provider_file(filepath) + all_errors.extend(errors) + + # Count models if file parsed successfully + if not any("Failed to parse" in e for e in errors): + try: + with open(filepath, "rb") as f: + data = tomllib.load(f) + provider_id = data.get("provider", {}).get("id", filepath.stem) + models = data.get("models", []) + count = len(models) + total_models += count + provider_counts[provider_id] = count + + # Track global model IDs for cross-file duplicate detection + for model in models: + mid = model.get("id") + mprov = model.get("provider", provider_id) + if mid: + key = (mid, mprov) + if key in global_model_ids: + prev_file = global_model_ids[key] + # Only flag if same provider in different files + if prev_file != filepath.name: + all_errors.append( + f"Cross-file duplicate: model '{mid}' (provider '{mprov}') " + f"found in both {prev_file} and {filepath.name}" + ) + else: + global_model_ids[key] = filepath.name + except Exception: + pass + + # Validate aliases.toml + aliases_file = catalog_root / "aliases.toml" + all_errors.extend(validate_aliases_file(aliases_file)) + + # Print results + print("=" * 60) + print("LibreFang Model Catalog Validation") + print("=" * 60) + print() + + if all_errors: + print(f"ERRORS ({len(all_errors)}):") + for error in all_errors: + print(f" - {error}") + print() + + print(f"Provider files: {len(toml_files)}") + print(f"Total models: {total_models}") + print() + + print("Per-provider model counts:") + for provider_id in sorted(provider_counts.keys()): + count = provider_counts[provider_id] + if count > 0: + print(f" {provider_id:30s} {count:>3}") + + print() + + if all_errors: + print(f"VALIDATION FAILED with {len(all_errors)} error(s)") + sys.exit(1) + else: + print("VALIDATION PASSED") + sys.exit(0) + + +if __name__ == "__main__": + main()