diff --git a/.github/workflows/update-models.yaml b/.github/workflows/update-models.yaml new file mode 100644 index 0000000..99ee468 --- /dev/null +++ b/.github/workflows/update-models.yaml @@ -0,0 +1,95 @@ +name: Update models + +on: + schedule: + - cron: '0 */12 * * *' + workflow_dispatch: + +permissions: + contents: write + +concurrency: + group: update-models + cancel-in-progress: false + +defaults: + run: + shell: bash + +jobs: + update: + name: Update models + + runs-on: ubuntu-latest + + env: + RUSTFLAGS: --deny warnings + + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: true + + - name: Install Rust Toolchain Components + uses: dtolnay/rust-toolchain@stable + + - uses: Swatinem/rust-cache@v2 + + - name: Cache DuckDB Extensions + id: duckdb-extensions + uses: actions/cache@v4 + with: + path: ~/.duckdb/extensions + key: duckdb-ext-ubuntu-latest-${{ hashFiles('Cargo.lock') }} + + - name: Install DuckDB Extensions + if: steps.duckdb-extensions.outputs.cache-hit != 'true' + run: cargo test --all duckdb + + # Coyote loads its config before handling --generate-models/--list-models, and a + # bare non-TTY runner has no config file (and no way to answer the first-run + # prompt), so point COYOTE_CONFIG_DIR at a throwaway dir with a minimal stub. + - name: Write stub config + run: | + COYOTE_CONFIG_DIR="$(mktemp -d)" + printf 'clients:\n - type: openai\n - type: claude\n' > "$COYOTE_CONFIG_DIR/config.yaml" + echo "COYOTE_CONFIG_DIR=$COYOTE_CONFIG_DIR" >> "$GITHUB_ENV" + + - name: Regenerate model catalog + run: cargo run --release -- --generate-models + + - name: Detect catalog changes + id: diff + run: echo "changed=$(git diff --quiet models.yaml && echo false || echo true)" >> "$GITHUB_OUTPUT" + + # The binary built by the regeneration step embedded the OLD models.yaml (the file + # was rewritten after that build), so rebuild before smoke-testing: cargo tracks + # include_str! inputs, making this a cheap incremental rebuild of the final crate. + - name: Rebuild with the refreshed catalog + if: steps.diff.outputs.changed == 'true' + run: cargo build --release + + - name: Test + if: steps.diff.outputs.changed == 'true' + run: cargo test --all + + - name: Smoke test the refreshed catalog + if: steps.diff.outputs.changed == 'true' + run: | + COUNT=$(./target/release/coyote --list-models | wc -l) + echo "Listed $COUNT chat models" + test "$COUNT" -ge 40 + + # Pushes made with the default GITHUB_TOKEN do not trigger other workflows, + # so this push cannot start a workflow loop. The pull --rebase covers a human + # push landing mid-run; if the race is lost anyway, the next cron run retries. + - name: Commit and push + if: steps.diff.outputs.changed == 'true' + run: | + git add models.yaml + git checkout -- . + git config user.name 'github-actions[bot]' + git config user.email '41898282+github-actions[bot]@users.noreply.github.com' + git commit -m 'chore: refresh generated model catalog' + git pull --rebase origin main + git push origin main diff --git a/README.md b/README.md index 4d5030e..f3a39e8 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,7 @@ Coming from [AIChat](https://github.com/sigoden/aichat)? Follow the [migration g * [Client Configurations](https://github.com/Dark-Alex-17/coyote/wiki/Clients): Configuration instructions for various LLM providers. * [Authentication (API Key & OAuth)](https://github.com/Dark-Alex-17/coyote/wiki/Clients#authentication): Authenticate with API keys or OAuth for subscription-based access. * [Patching API Requests](https://github.com/Dark-Alex-17/coyote/wiki/Patches): Learn how to patch API requests for advanced customization. +* [Dynamic Model Catalog](https://github.com/Dark-Alex-17/coyote/wiki/Model-Catalog): Coyote's model catalog (context windows, pricing, capabilities) is generated from live API data, refreshed automatically in the background, and mirrorable for air-gapped setups. New models show up without waiting for a release. * [Custom Themes](https://github.com/Dark-Alex-17/coyote/wiki/Themes): Change the look and feel of Coyote to your preferences with custom themes. * [History](#history): A history of how Coyote came to be. diff --git a/assets/config-template.yaml b/assets/config-template.yaml index 02ca30f..cd18c10 100644 --- a/assets/config-template.yaml +++ b/assets/config-template.yaml @@ -244,8 +244,13 @@ right_prompt: null # If null, uses the built-in default: # ---- Miscellaneous ---- user_agent: null # Set User-Agent HTTP header, use `auto` for coyote/ save_shell_history: true # Whether to save shell execution command to the history file -sync_models_url: null # URL to sync model changes from. If null, uses the built-in default: +sync_models_url: null # Where `--sync-models` and the automatic refresh get model data from. + # If null, fetches fresh model data from models.dev + OpenRouter. + # Set a URL to mirror a full models.yaml instead, e.g.: # https://raw.githubusercontent.com/Dark-Alex-17/coyote/refs/heads/main/models.yaml +sync_models_auto: true # Whether to refresh the model catalog in the background on REPL startup + # once it goes stale +sync_models_ttl_hours: 24 # Hours before the synced model catalog is considered stale # ---- Clients ---- # See the [Clients documentation](https://github.com/Dark-Alex-17/coyote/wiki/Clients) for more details diff --git a/assets/sbx-kit/spec.yaml b/assets/sbx-kit/spec.yaml index 5c972d3..4b17b70 100644 --- a/assets/sbx-kit/spec.yaml +++ b/assets/sbx-kit/spec.yaml @@ -67,6 +67,7 @@ permissions: - 'api.cohere.ai' - 'api.groq.com' - 'openrouter.ai' + - 'models.dev' - 'api.ai21.com' - 'api.cloudflare.com' - 'api.deepinfra.com' diff --git a/config.example.yaml b/config.example.yaml index 2b2a8eb..ebb5d8c 100644 --- a/config.example.yaml +++ b/config.example.yaml @@ -26,8 +26,13 @@ light_theme: false # Activates a light color theme when true. env: # ---- Miscellaneous ---- user_agent: null # Set User-Agent HTTP header, use `auto` for coyote/ save_shell_history: true # Whether to save shell execution command to the history file -sync_models_url: > # URL to sync model changes from - https://raw.githubusercontent.com/Dark-Alex-17/coyote/refs/heads/main/models.yaml +sync_models_url: null # Where `--sync-models` and the automatic refresh get model data from. + # If null, fetches fresh model data from models.dev + OpenRouter. + # Set a URL to mirror a full models.yaml instead, e.g.: + # https://raw.githubusercontent.com/Dark-Alex-17/coyote/refs/heads/main/models.yaml +sync_models_auto: true # Whether to refresh the model catalog in the background on REPL startup + # once it goes stale +sync_models_ttl_hours: 24 # Hours before the synced model catalog is considered stale # ---- REPL Prompt ---- # Custom REPL left/right prompts; see the [REPL Prompt Documentation](https://github.com/Dark-Alex-17/coyote/wiki/REPL-Prompt) for more information diff --git a/models.yaml b/models.yaml index 2502e8c..d302d1c 100644 --- a/models.yaml +++ b/models.yaml @@ -1,2850 +1,9591 @@ -# Links: -# - https://platform.openai.com/docs/models -# - https://platform.openai.com/docs/api-reference/chat +# GENERATED by 'coyote --generate-models' +# DO NOT hand-edit model data. +# Hand-owned behavior lives in quirks.yaml; this file is the embedded offline fallback. - provider: openai models: - - name: gpt-5.6-sol - max_input_tokens: 1050000 - max_output_tokens: 128000 - input_price: 5 - output_price: 30 - supports_vision: true - supports_function_calling: true - reasoning_levels: [none, low, medium, high, xhigh, max] - default_reasoning_effort: medium - - name: gpt-5.6-terra - max_input_tokens: 1050000 - max_output_tokens: 128000 - input_price: 5 - output_price: 30 - supports_vision: true - supports_function_calling: true - reasoning_levels: [none, low, medium, high, xhigh, max] - default_reasoning_effort: medium - - name: gpt-5.6-luna - max_input_tokens: 1050000 - max_output_tokens: 128000 - input_price: 5 - output_price: 30 - supports_vision: true - supports_function_calling: true - reasoning_levels: [none, low, medium, high, xhigh, max] - default_reasoning_effort: medium - - name: gpt-5.5 - max_input_tokens: 1050000 - max_output_tokens: 128000 - input_price: 5 - output_price: 30 - supports_vision: true - supports_function_calling: true - reasoning_levels: [none, low, medium, high, xhigh] - default_reasoning_effort: medium - - name: gpt-5.5-pro - max_input_tokens: 1050000 - max_output_tokens: 128000 - input_price: 30 - output_price: 180 - supports_vision: true - supports_function_calling: true - reasoning_levels: [medium, high, xhigh] - default_reasoning_effort: high - - name: gpt-5.4 - max_input_tokens: 1050000 - max_output_tokens: 128000 - input_price: 2.5 - output_price: 15 - supports_vision: true - supports_function_calling: true - reasoning_levels: [none, low, medium, high, xhigh] - default_reasoning_effort: none - - name: gpt-5.4-pro - max_input_tokens: 1050000 - max_output_tokens: 128000 - input_price: 30 - output_price: 180 - supports_vision: true - supports_function_calling: true - reasoning_levels: [medium, high, xhigh] - default_reasoning_effort: medium - - name: gpt-5.4-mini - max_input_tokens: 400000 - max_output_tokens: 128000 - input_price: 0.75 - output_price: 4.5 - supports_vision: true - supports_function_calling: true - reasoning_levels: [none, low, medium, high, xhigh] - default_reasoning_effort: none - - name: gpt-5.4-nano - max_input_tokens: 400000 - max_output_tokens: 128000 - input_price: 0.2 - output_price: 1.25 - supports_vision: true - supports_function_calling: true - reasoning_levels: [none, low, medium, high, xhigh] - default_reasoning_effort: none - - name: gpt-5.3-codex - max_input_tokens: 400000 - max_output_tokens: 128000 - input_price: 1.75 - output_price: 14 - supports_vision: true - supports_function_calling: true - reasoning_levels: [low, medium, high, xhigh] - default_reasoning_effort: medium - - name: chat-latest - max_input_tokens: 400000 - max_output_tokens: 128000 - input_price: 5 - output_price: 30 - supports_vision: true - supports_function_calling: true - - name: gpt-5.2 - max_input_tokens: 400000 - max_output_tokens: 128000 - input_price: 1.75 - output_price: 14 - supports_vision: true - supports_function_calling: true - reasoning_levels: [none, low, medium, high, xhigh] - default_reasoning_effort: none - - name: gpt-5.2-pro - max_input_tokens: 400000 - max_output_tokens: 128000 - input_price: 21 - output_price: 168 - supports_vision: true - supports_function_calling: true - reasoning_levels: [medium, high, xhigh] - default_reasoning_effort: medium - - name: gpt-5.1 - max_input_tokens: 400000 - max_output_tokens: 128000 - input_price: 1.25 - output_price: 10 - supports_vision: true - supports_function_calling: true - reasoning_levels: [none, low, medium, high] - default_reasoning_effort: none - - name: gpt-5.1-chat-latest - max_input_tokens: 400000 - max_output_tokens: 128000 - input_price: 1.25 - output_price: 10 - supports_vision: true - supports_function_calling: true - reasoning_levels: [none, low, medium, high] - default_reasoning_effort: none - - name: gpt-5 - max_input_tokens: 400000 - max_output_tokens: 128000 - input_price: 1.25 - output_price: 10 - supports_vision: true - supports_function_calling: true - reasoning_levels: [minimal, low, medium, high] - default_reasoning_effort: medium - - name: gpt-5-chat-latest - max_input_tokens: 400000 - max_output_tokens: 128000 - input_price: 1.25 - output_price: 10 - supports_vision: true - supports_function_calling: true - reasoning_levels: [minimal, low, medium, high] - default_reasoning_effort: medium - - name: gpt-5-mini - max_input_tokens: 400000 - max_output_tokens: 128000 - input_price: 0.25 - output_price: 2 - supports_vision: true - supports_function_calling: true - - name: gpt-5-nano - max_input_tokens: 400000 - max_output_tokens: 128000 - input_price: 0.05 - output_price: 0.4 - supports_vision: true - supports_function_calling: true - - name: gpt-4.1 - max_input_tokens: 1047576 - max_output_tokens: 32768 - input_price: 2 - output_price: 8 - supports_vision: true - supports_function_calling: true - - name: gpt-4.1-mini - max_input_tokens: 1047576 - max_output_tokens: 32768 - input_price: 0.4 - output_price: 1.6 - supports_vision: true - supports_function_calling: true - - name: gpt-4.1-nano - max_input_tokens: 1047576 - max_output_tokens: 32768 - input_price: 0.1 - output_price: 0.4 - supports_vision: true - supports_function_calling: true - - name: gpt-4o - max_input_tokens: 128000 - max_output_tokens: 16384 - input_price: 2.5 - output_price: 10 - supports_vision: true - supports_function_calling: true - - name: gpt-4o-mini - max_input_tokens: 128000 - max_output_tokens: 16384 - input_price: 0.15 - output_price: 0.6 - supports_vision: true - supports_function_calling: true - - name: o4-mini - max_output_tokens: 100000 - max_input_tokens: 200000 - input_price: 1.1 - output_price: 4.4 - supports_vision: true - supports_function_calling: true - system_prompt_prefix: Formatting re-enabled - reasoning_levels: [low, medium, high] - default_reasoning_effort: medium - patch: - body: - max_tokens: null - temperature: null - top_p: null - - name: o4-mini-high - max_output_tokens: 100000 - real_name: o4-mini - max_input_tokens: 200000 - input_price: 1.1 - output_price: 4.4 - supports_vision: true - supports_function_calling: true - system_prompt_prefix: Formatting re-enabled - patch: - body: - reasoning_effort: high - max_tokens: null - temperature: null - top_p: null - - name: o3 - max_output_tokens: 100000 - max_input_tokens: 200000 - input_price: 2 - output_price: 8 - supports_vision: true - supports_function_calling: true - system_prompt_prefix: Formatting re-enabled - patch: - body: - max_tokens: null - temperature: null - top_p: null - - name: o3-high - real_name: o3 - max_input_tokens: 200000 - input_price: 2 - output_price: 8 - supports_vision: true - supports_function_calling: true - system_prompt_prefix: Formatting re-enabled - patch: - body: - reasoning_effort: high - max_tokens: null - temperature: null - top_p: null - - name: o3-mini - max_output_tokens: 100000 - max_input_tokens: 200000 - input_price: 1.1 - output_price: 4.4 - supports_vision: true - supports_function_calling: true - system_prompt_prefix: Formatting re-enabled - patch: - body: - max_tokens: null - temperature: null - top_p: null - - name: o3-mini-high - max_output_tokens: 100000 - real_name: o3-mini - max_input_tokens: 200000 - input_price: 1.1 - output_price: 4.4 - supports_vision: true - supports_function_calling: true - system_prompt_prefix: Formatting re-enabled - patch: - body: - reasoning_effort: high - max_tokens: null - temperature: null - top_p: null - - name: gpt-4-turbo - max_input_tokens: 128000 - max_output_tokens: 4096 - input_price: 10 - output_price: 30 - supports_vision: true - supports_function_calling: true - - name: gpt-3.5-turbo - max_input_tokens: 16385 - max_output_tokens: 4096 - input_price: 0.5 - output_price: 1.5 - supports_function_calling: true - - name: text-embedding-3-large - type: embedding - input_price: 0.13 - max_tokens_per_chunk: 8191 - default_chunk_size: 2000 - max_batch_size: 100 - - name: text-embedding-3-small - type: embedding - input_price: 0.02 - max_tokens_per_chunk: 8191 - default_chunk_size: 2000 - max_batch_size: 100 - -# Links: -# - https://ai.google.dev/models/gemini -# - https://ai.google.dev/pricing -# - https://ai.google.dev/api/rest/v1beta/models/streamGenerateContent + - name: text-embedding-3-large + type: embedding + input_price: 0.13 + max_tokens_per_chunk: 8191 + default_chunk_size: 2000 + max_batch_size: 100 + - name: text-embedding-3-small + type: embedding + input_price: 0.02 + max_tokens_per_chunk: 8191 + default_chunk_size: 2000 + max_batch_size: 100 + - name: o4-mini-high + type: chat + real_name: o4-mini + max_input_tokens: 200000 + input_price: 1.1 + output_price: 4.4 + patch: + body: + reasoning_effort: high + max_tokens: null + temperature: null + top_p: null + max_output_tokens: 100000 + supports_vision: true + supports_function_calling: true + system_prompt_prefix: Formatting re-enabled + - name: o3-high + type: chat + real_name: o3 + max_input_tokens: 200000 + input_price: 2.0 + output_price: 8.0 + patch: + body: + reasoning_effort: high + max_tokens: null + temperature: null + top_p: null + supports_vision: true + supports_function_calling: true + system_prompt_prefix: Formatting re-enabled + - name: o3-mini-high + type: chat + real_name: o3-mini + max_input_tokens: 200000 + input_price: 1.1 + output_price: 4.4 + patch: + body: + reasoning_effort: high + max_tokens: null + temperature: null + top_p: null + max_output_tokens: 100000 + supports_vision: true + supports_function_calling: true + system_prompt_prefix: Formatting re-enabled + - name: chat-latest + type: chat + max_input_tokens: 400000 + input_price: 5.0 + output_price: 30.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + - name: gpt-5.1-chat-latest + type: chat + max_input_tokens: 400000 + input_price: 1.25 + output_price: 10.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + default_reasoning_effort: none + - name: gpt-5-chat-latest + type: chat + max_input_tokens: 400000 + input_price: 1.25 + output_price: 10.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - minimal + - low + - medium + - high + default_reasoning_effort: medium + - name: gpt-5.6 + type: chat + max_input_tokens: 1050000 + input_price: 4.0 + output_price: 20.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + - xhigh + - max + - name: gpt-5.6-luna + type: chat + max_input_tokens: 1050000 + input_price: 0.2 + output_price: 1.2 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: medium + - name: gpt-5.6-sol + type: chat + max_input_tokens: 1050000 + input_price: 4.0 + output_price: 20.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: medium + - name: gpt-5.6-terra + type: chat + max_input_tokens: 1050000 + input_price: 2.0 + output_price: 12.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: medium + - name: gpt-5.5 + type: chat + max_input_tokens: 1050000 + input_price: 5.0 + output_price: 30.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + - xhigh + default_reasoning_effort: medium + - name: gpt-5.5-pro + type: chat + max_input_tokens: 1050000 + input_price: 30.0 + output_price: 180.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - medium + - high + - xhigh + default_reasoning_effort: high + - name: gpt-5.4-mini + type: chat + max_input_tokens: 400000 + input_price: 0.75 + output_price: 4.5 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + - xhigh + default_reasoning_effort: none + - name: gpt-5.4-nano + type: chat + max_input_tokens: 400000 + input_price: 0.2 + output_price: 1.25 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + - xhigh + default_reasoning_effort: none + - name: gpt-5.4 + type: chat + max_input_tokens: 1050000 + input_price: 2.5 + output_price: 15.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + - xhigh + default_reasoning_effort: none + - name: gpt-5.4-pro + type: chat + max_input_tokens: 1050000 + input_price: 30.0 + output_price: 180.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - medium + - high + - xhigh + default_reasoning_effort: medium + - name: gpt-5.3-chat-latest + type: chat + max_input_tokens: 128000 + input_price: 1.75 + output_price: 14.0 + max_output_tokens: 16384 + supports_vision: true + supports_function_calling: true + - name: gpt-5.3-codex + type: chat + max_input_tokens: 400000 + input_price: 1.75 + output_price: 14.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + - xhigh + default_reasoning_effort: medium + - name: gpt-5.3-codex-spark + type: chat + max_input_tokens: 128000 + input_price: 1.75 + output_price: 14.0 + max_output_tokens: 32000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + - xhigh + - name: gpt-5.2 + type: chat + max_input_tokens: 400000 + input_price: 1.75 + output_price: 14.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + - xhigh + default_reasoning_effort: none + - name: gpt-5.2-chat-latest + type: chat + max_input_tokens: 128000 + input_price: 1.75 + output_price: 14.0 + max_output_tokens: 16384 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - medium + - name: gpt-5.2-pro + type: chat + max_input_tokens: 400000 + input_price: 21.0 + output_price: 168.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - medium + - high + - xhigh + default_reasoning_effort: medium + - name: gpt-5.1 + type: chat + max_input_tokens: 400000 + input_price: 1.25 + output_price: 10.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + default_reasoning_effort: none + - name: gpt-5-pro + type: chat + max_input_tokens: 400000 + input_price: 15.0 + output_price: 120.0 + max_output_tokens: 272000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - high + - name: gpt-5 + type: chat + max_input_tokens: 400000 + input_price: 1.25 + output_price: 10.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - minimal + - low + - medium + - high + default_reasoning_effort: medium + - name: gpt-5-mini + type: chat + max_input_tokens: 400000 + input_price: 0.25 + output_price: 2.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - minimal + - low + - medium + - high + - name: gpt-5-nano + type: chat + max_input_tokens: 400000 + input_price: 0.05 + output_price: 0.4 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - minimal + - low + - medium + - high + - name: o3-pro + type: chat + max_input_tokens: 200000 + input_price: 20.0 + output_price: 80.0 + max_output_tokens: 100000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - name: o3 + type: chat + max_input_tokens: 200000 + input_price: 2.0 + output_price: 8.0 + patch: + body: + max_tokens: null + temperature: null + top_p: null + max_output_tokens: 100000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + system_prompt_prefix: Formatting re-enabled + - name: o4-mini + type: chat + max_input_tokens: 200000 + input_price: 1.1 + output_price: 4.4 + patch: + body: + max_tokens: null + temperature: null + top_p: null + max_output_tokens: 100000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + default_reasoning_effort: medium + system_prompt_prefix: Formatting re-enabled + - name: gpt-4.1 + type: chat + max_input_tokens: 1047576 + input_price: 2.0 + output_price: 8.0 + max_output_tokens: 32768 + supports_vision: true + supports_function_calling: true + - name: gpt-4.1-mini + type: chat + max_input_tokens: 1047576 + input_price: 0.4 + output_price: 1.6 + max_output_tokens: 32768 + supports_vision: true + supports_function_calling: true + - name: gpt-4.1-nano + type: chat + max_input_tokens: 1047576 + input_price: 0.1 + output_price: 0.4 + max_output_tokens: 32768 + supports_vision: true + supports_function_calling: true + - name: o1-pro + type: chat + max_input_tokens: 200000 + input_price: 150.0 + output_price: 600.0 + max_output_tokens: 100000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - name: o3-mini + type: chat + max_input_tokens: 200000 + input_price: 1.1 + output_price: 4.4 + patch: + body: + max_tokens: null + temperature: null + top_p: null + max_output_tokens: 100000 + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + system_prompt_prefix: Formatting re-enabled + - name: o1 + type: chat + max_input_tokens: 200000 + input_price: 15.0 + output_price: 60.0 + max_output_tokens: 100000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - name: gpt-4o-2024-11-20 + type: chat + max_input_tokens: 128000 + input_price: 2.5 + output_price: 10.0 + max_output_tokens: 16384 + supports_vision: true + supports_function_calling: true + - name: gpt-4o-2024-08-06 + type: chat + max_input_tokens: 128000 + input_price: 2.5 + output_price: 10.0 + max_output_tokens: 16384 + supports_vision: true + supports_function_calling: true + - name: gpt-4o-mini + type: chat + max_input_tokens: 128000 + input_price: 0.15 + output_price: 0.6 + max_output_tokens: 16384 + supports_vision: true + supports_function_calling: true + - name: gpt-4o + type: chat + max_input_tokens: 128000 + input_price: 2.5 + output_price: 10.0 + max_output_tokens: 16384 + supports_vision: true + supports_function_calling: true + - name: gpt-4o-2024-05-13 + type: chat + max_input_tokens: 128000 + input_price: 5.0 + output_price: 15.0 + max_output_tokens: 4096 + supports_vision: true + supports_function_calling: true + - name: gpt-4 + type: chat + max_input_tokens: 8192 + input_price: 30.0 + output_price: 60.0 + max_output_tokens: 8192 + supports_function_calling: true + - name: gpt-4-turbo + type: chat + max_input_tokens: 128000 + input_price: 10.0 + output_price: 30.0 + max_output_tokens: 4096 + supports_vision: true + supports_function_calling: true + - name: gpt-3.5-turbo + type: chat + max_input_tokens: 16385 + input_price: 0.5 + output_price: 1.5 + max_output_tokens: 4096 + supports_function_calling: true - provider: gemini models: - - name: gemini-3.6-flash - max_input_tokens: 1048576 - max_output_tokens: 65536 - input_price: 1.5 - output_price: 7.5 - supports_function_calling: true - reasoning_levels: [minimal, low, medium, high] - default_reasoning_level: medium - - name: gemini-3.5-flash - max_input_tokens: 1048576 - max_output_tokens: 65536 - input_price: 0.2 - output_price: 1.5 - supports_function_calling: true - reasoning_levels: [minimal, low, medium, high] - default_reasoning_effort: medium - - name: gemini-3-flash-preview - max_input_tokens: 1048576 - max_output_tokens: 65536 - input_price: 0.2 - output_price: 1.5 - supports_function_calling: true - reasoning_levels: [minimal, low, medium, high] - default_reasoning_effort: high - - name: gemini-3.1-flash-lite - max_input_tokens: 1048576 - max_output_tokens: 65536 - input_price: 0.2 - output_price: 1.5 - supports_function_calling: true - reasoning_levels: [minimal, low, medium, high] - default_reasoning_effort: minimal - - name: gemini-3.1-pro-preview - max_input_tokens: 1048576 - max_output_tokens: 65535 - input_price: 0.3 - output_price: 2.5 - supports_vision: true - supports_function_calling: true - reasoning_levels: [low, medium, high] - default_reasoning_effort: high - - name: gemini-2.5-flash - max_input_tokens: 1048576 - max_output_tokens: 65536 - input_price: 0 - output_price: 0 - supports_vision: true - supports_function_calling: true - - name: gemini-2.5-pro - max_input_tokens: 1048576 - max_output_tokens: 65536 - input_price: 0 - output_price: 0 - supports_vision: true - supports_function_calling: true - reasoning_levels: [low, medium, high] - default_reasoning_effort: high - - name: gemini-2.5-flash-lite - max_input_tokens: 1000000 - max_output_tokens: 64000 - input_price: 0 - output_price: 0 - supports_vision: true - supports_function_calling: true - - name: gemini-3-pro-preview - max_input_tokens: 1048576 - supports_vision: true - supports_function_calling: true - reasoning_levels: [low, high] - default_reasoning_level: high - - name: gemini-3-flash-preview - max_input_tokens: 1048576 - supports_vision: true - supports_function_calling: true - reasoning_levels: [minimal, low, medium, high] - default_reasoning_level: high - - name: gemma-3-27b-it - max_input_tokens: 131072 - max_output_tokens: 8192 - input_price: 0 - output_price: 0 - - name: text-embedding-004 - type: embedding - input_price: 0 - max_tokens_per_chunk: 2048 - default_chunk_size: 1500 - max_batch_size: 100 - -# Links: -# - https://docs.anthropic.com/en/docs/about-claude/models/all-models -# - https://docs.anthropic.com/en/api/messages + - name: text-embedding-004 + type: embedding + input_price: 0.0 + max_tokens_per_chunk: 2048 + default_chunk_size: 1500 + max_batch_size: 100 + - name: gemini-3-pro-preview + type: chat + max_input_tokens: 1048576 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - high + default_reasoning_effort: high + - name: gemma-3-27b-it + type: chat + max_input_tokens: 131072 + input_price: 0.0 + output_price: 0.0 + max_output_tokens: 8192 + - name: gemini-3.8-flash + type: chat + max_input_tokens: 1048576 + input_price: 0.75 + output_price: 3.75 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - name: gemini-3.7-flash + type: chat + max_input_tokens: 1048576 + input_price: 0.75 + output_price: 3.75 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - name: gemini-flash-latest + type: chat + max_input_tokens: 1048576 + input_price: 0.75 + output_price: 3.75 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - name: gemini-3.5-flash-lite + type: chat + max_input_tokens: 1048576 + input_price: 0.3 + output_price: 2.5 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - minimal + - low + - medium + - high + - name: gemini-3.6-flash + type: chat + max_input_tokens: 1048576 + input_price: 0.75 + output_price: 3.75 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - minimal + - low + - medium + - high + default_reasoning_effort: medium + - name: gemini-flash-lite-latest + type: chat + max_input_tokens: 1048576 + input_price: 0.3 + output_price: 2.5 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - minimal + - low + - medium + - high + - name: gemini-3.1-flash-lite-image + type: chat + max_input_tokens: 65536 + input_price: 0.25 + output_price: 30.0 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - minimal + - high + - name: gemini-omni-flash-preview + type: chat + max_input_tokens: 131072 + input_price: 1.5 + output_price: 17.5 + max_output_tokens: 65536 + supports_vision: true + - name: gemini-3.5-live-translate-preview + type: chat + max_input_tokens: 16384 + input_price: 3.5 + output_price: 21.0 + max_output_tokens: 32768 + - name: gemini-3-pro-image + type: chat + max_input_tokens: 131072 + input_price: 2.0 + output_price: 120.0 + max_output_tokens: 32768 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - high + - name: gemini-3.1-flash-image + type: chat + max_input_tokens: 65536 + input_price: 0.5 + output_price: 60.0 + max_output_tokens: 65536 + supports_vision: true + reasoning_levels: + - minimal + - high + - name: gemini-3.5-flash + type: chat + max_input_tokens: 1048576 + input_price: 1.5 + output_price: 9.0 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - minimal + - low + - medium + - high + default_reasoning_effort: medium + - name: gemini-3.1-flash-lite + type: chat + max_input_tokens: 1048576 + input_price: 0.25 + output_price: 1.5 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - minimal + - low + - medium + - high + default_reasoning_effort: minimal + - name: deep-research-max-preview-04-2026 + type: chat + max_input_tokens: 131072 + input_price: 2.0 + output_price: 12.0 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: deep-research-preview-04-2026 + type: chat + max_input_tokens: 131072 + input_price: 2.0 + output_price: 12.0 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: gemma-4-26b-a4b-it + type: chat + max_input_tokens: 262144 + input_price: 0.07 + output_price: 0.34 + max_output_tokens: 32768 + supports_vision: true + supports_function_calling: true + - name: gemma-4-31b-it + type: chat + max_input_tokens: 262144 + input_price: 0.09 + output_price: 0.34 + max_output_tokens: 32768 + supports_vision: true + supports_function_calling: true + - name: gemini-3.1-flash-live-preview + type: chat + max_input_tokens: 131072 + input_price: 0.75 + output_price: 4.5 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - minimal + - low + - medium + - high + - name: lyria-3-clip-preview + type: chat + max_input_tokens: 1048576 + input_price: 0.0 + output_price: 0.0 + max_output_tokens: 65536 + supports_vision: true + - name: lyria-3-pro-preview + type: chat + max_input_tokens: 1048576 + input_price: 0.0 + output_price: 0.0 + max_output_tokens: 65536 + supports_vision: true + - name: gemini-3.1-flash-lite-preview + type: chat + max_input_tokens: 1048576 + input_price: 0.25 + output_price: 1.5 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - minimal + - low + - medium + - high + - name: gemini-3.1-pro-preview + type: chat + max_input_tokens: 1048576 + input_price: 2.0 + output_price: 12.0 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + default_reasoning_effort: high + - name: gemini-3.1-pro-preview-customtools + type: chat + max_input_tokens: 1048576 + input_price: 2.0 + output_price: 12.0 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - name: gemini-3-flash-preview + type: chat + max_input_tokens: 1048576 + input_price: 0.5 + output_price: 3.0 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - minimal + - low + - medium + - high + default_reasoning_effort: high + - name: gemini-2.5-computer-use-preview-10-2025 + type: chat + max_input_tokens: 131072 + input_price: 1.25 + output_price: 10.0 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: gemini-2.5-flash-image + type: chat + max_input_tokens: 32768 + input_price: 0.3 + output_price: 30.0 + max_output_tokens: 32768 + supports_vision: true + - name: gemini-2.5-flash + type: chat + max_input_tokens: 1048576 + input_price: 0.3 + output_price: 2.5 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: gemini-2.5-flash-lite + type: chat + max_input_tokens: 1048576 + input_price: 0.1 + output_price: 0.4 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: gemini-2.5-pro + type: chat + max_input_tokens: 1048576 + input_price: 1.25 + output_price: 10.0 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + default_reasoning_effort: high - provider: claude models: - - name: claude-opus-5 - max_input_tokens: 1000000 - max_output_tokens: 128000 - require_max_tokens: true - input_price: 5 - output_price: 25 - supports_function_calling: true - supports_vision: true - reasoning_levels: [low, medium, high, xhigh, max] - default_reasoning_effort: high - - name: claude-fable-5-1 - max_input_tokens: 1000000 - max_output_tokens: 128000 - require_max_tokens: true - input_price: 10 - output_price: 50 - supports_function_calling: true - supports_vision: true - reasoning_levels: [low, medium, high, xhigh, max] - default_reasoning_effort: high - - name: claude-fable-5 - max_input_tokens: 1000000 - max_output_tokens: 128000 - require_max_tokens: true - input_price: 10 - output_price: 50 - supports_function_calling: true - supports_vision: true - reasoning_levels: [low, medium, high, xhigh, max] - default_reasoning_effort: high - - name: claude-opus-4-8 - max_input_tokens: 1000000 - max_output_tokens: 128000 - require_max_tokens: true - input_price: 5 - output_price: 25 - supports_vision: true - supports_function_calling: true - reasoning_levels: [low, medium, high, xhigh, max] - default_reasoning_effort: high - - name: claude-opus-4-7 - max_input_tokens: 1000000 - max_output_tokens: 128000 - require_max_tokens: true - input_price: 5 - output_price: 25 - supports_vision: true - supports_function_calling: true - reasoning_levels: [low, medium, high, xhigh, max] - default_reasoning_effort: high - - name: claude-opus-4-6 - max_input_tokens: 200000 - max_output_tokens: 8192 - require_max_tokens: true - input_price: 5 - output_price: 25 - supports_vision: true - supports_function_calling: true - reasoning_levels: [low, medium, high, max] - default_reasoning_effort: high - - name: claude-opus-4-6:thinking - real_name: claude-opus-4-6 - max_input_tokens: 200000 - max_output_tokens: 24000 - require_max_tokens: true - input_price: 5 - output_price: 25 - supports_vision: true - supports_function_calling: true - patch: - body: - temperature: null - top_p: null - thinking: - type: enabled - budget_tokens: 16000 - - name: claude-sonnet-5 - max_input_tokens: 1000000 - max_output_tokens: 128000 - require_max_tokens: true - input_price: 3 - output_price: 15 - supports_vision: true - supports_function_calling: true - reasoning_levels: [low, medium, high, xhigh, max] - default_reasoning_effort: high - - name: claude-sonnet-4-6 - max_input_tokens: 200000 - max_output_tokens: 8192 - require_max_tokens: true - input_price: 3 - output_price: 15 - supports_vision: true - supports_function_calling: true - reasoning_levels: [low, medium, high, max] - default_reasoning_effort: high - - name: claude-sonnet-4-6:thinking - real_name: claude-sonnet-4-6 - max_input_tokens: 200000 - max_output_tokens: 24000 - require_max_tokens: true - input_price: 3 - output_price: 15 - supports_vision: true - supports_function_calling: true - patch: - body: - temperature: null - top_p: null - thinking: - type: enabled - budget_tokens: 16000 - - name: claude-sonnet-4-5-20250929 - max_input_tokens: 200000 - max_output_tokens: 8192 - require_max_tokens: true - input_price: 3 - output_price: 15 - supports_vision: true - supports_function_calling: true - - name: claude-sonnet-4-5-20250929:thinking - real_name: claude-sonnet-4-5-20250929 - max_input_tokens: 200000 - max_output_tokens: 24000 - require_max_tokens: true - input_price: 3 - output_price: 15 - supports_vision: true - supports_function_calling: true - patch: - body: - temperature: null - top_p: null - thinking: - type: enabled - budget_tokens: 16000 - - name: claude-haiku-4-5-20251001 - max_input_tokens: 200000 - max_output_tokens: 8192 - require_max_tokens: true - input_price: 1 - output_price: 5 - supports_vision: true - supports_function_calling: true - - name: claude-haiku-4-5-20251001:thinking - real_name: claude-haiku-4-5-20251001 - max_input_tokens: 200000 - max_output_tokens: 24000 - require_max_tokens: true - input_price: 1 - output_price: 5 - supports_vision: true - supports_function_calling: true - patch: - body: - temperature: null - top_p: null - thinking: - type: enabled - budget_tokens: 16000 - - name: claude-opus-4-5-20251101 - type: chat - max_input_tokens: 200000 - input_price: 15.0 - output_price: 75.0 - max_output_tokens: 8192 - require_max_tokens: true - supports_vision: true - supports_function_calling: true - - name: claude-opus-4-5-20251101:thinking - type: chat - real_name: claude-opus-4-5-20251101 - max_input_tokens: 200000 - input_price: 15.0 - output_price: 75.0 - patch: - body: - temperature: null - top_p: null - thinking: - type: enabled - budget_tokens: 16000 - max_output_tokens: 24000 - require_max_tokens: true - supports_vision: true - supports_function_calling: true - - name: claude-opus-4-1-20250805 - max_input_tokens: 200000 - max_output_tokens: 8192 - require_max_tokens: true - input_price: 15 - output_price: 75 - supports_vision: true - supports_function_calling: true - - name: claude-opus-4-1-20250805:thinking - real_name: claude-opus-4-1-20250805 - max_input_tokens: 200000 - max_output_tokens: 24000 - require_max_tokens: true - input_price: 15 - output_price: 75 - supports_vision: true - supports_function_calling: true - patch: - body: - temperature: null - top_p: null - thinking: - type: enabled - budget_tokens: 16000 - - name: claude-opus-4-20250514 - max_input_tokens: 200000 - max_output_tokens: 8192 - require_max_tokens: true - input_price: 15 - output_price: 75 - supports_vision: true - supports_function_calling: true - - name: claude-opus-4-20250514:thinking - real_name: claude-opus-4-20250514 - max_input_tokens: 200000 - max_output_tokens: 24000 - require_max_tokens: true - input_price: 15 - output_price: 75 - supports_vision: true - supports_function_calling: true - patch: - body: - temperature: null - top_p: null - thinking: - type: enabled - budget_tokens: 16000 - - name: claude-sonnet-4-5-20250929 - max_input_tokens: 200000 - max_output_tokens: 8192 - require_max_tokens: true - input_price: 3 - output_price: 15 - supports_vision: true - supports_function_calling: true - - name: claude-sonnet-4-5-20250929:thinking - real_name: claude-sonnet-4-5-20250929 - max_input_tokens: 200000 - max_output_tokens: 24000 - require_max_tokens: true - input_price: 3 - output_price: 15 - supports_vision: true - supports_function_calling: true - patch: - body: - temperature: null - top_p: null - thinking: - type: enabled - budget_tokens: 16000 - - name: claude-haiku-4-5-20251001 - max_input_tokens: 200000 - max_output_tokens: 8192 - require_max_tokens: true - input_price: 1 - output_price: 5 - supports_vision: true - supports_function_calling: true - - name: claude-haiku-4-5-20251001:thinking - real_name: claude-haiku-4-5-20251001 - max_input_tokens: 200000 - max_output_tokens: 24000 - require_max_tokens: true - input_price: 1 - output_price: 5 - supports_vision: true - supports_function_calling: true - patch: - body: - temperature: null - top_p: null - thinking: - type: enabled - budget_tokens: 16000 - -# Links: -# - https://docs.mistral.ai/getting-started/models/models_overview/ -# - https://mistral.ai/pricing#api-pricing -# - https://docs.mistral.ai/api/ + - name: claude-opus-4-1-20250805 + type: chat + max_input_tokens: 200000 + input_price: 15.0 + output_price: 75.0 + max_output_tokens: 8192 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: claude-opus-4-1-20250805:thinking + type: chat + real_name: claude-opus-4-1-20250805 + max_input_tokens: 200000 + input_price: 15.0 + output_price: 75.0 + patch: + body: + temperature: null + top_p: null + thinking: + type: enabled + budget_tokens: 16000 + max_output_tokens: 24000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: claude-opus-4-20250514 + type: chat + max_input_tokens: 200000 + input_price: 15.0 + output_price: 75.0 + max_output_tokens: 8192 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: claude-opus-4-20250514:thinking + type: chat + real_name: claude-opus-4-20250514 + max_input_tokens: 200000 + input_price: 15.0 + output_price: 75.0 + patch: + body: + temperature: null + top_p: null + thinking: + type: enabled + budget_tokens: 16000 + max_output_tokens: 24000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: claude-fable-5-1 + type: chat + max_input_tokens: 1000000 + input_price: 10.0 + output_price: 50.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: high + - name: claude-opus-5 + type: chat + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: high + - name: claude-sonnet-5 + type: chat + max_input_tokens: 1000000 + input_price: 2.0 + output_price: 10.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: high + - name: claude-fable-5 + type: chat + max_input_tokens: 1000000 + input_price: 10.0 + output_price: 50.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: high + - name: claude-opus-4-8 + type: chat + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: high + - name: claude-opus-4-7 + type: chat + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: high + - name: claude-sonnet-4-6 + type: chat + max_input_tokens: 1000000 + input_price: 3.0 + output_price: 15.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - max + default_reasoning_effort: high + - name: claude-sonnet-4-6:thinking + type: chat + real_name: claude-sonnet-4-6 + max_input_tokens: 1000000 + input_price: 3.0 + output_price: 15.0 + patch: + body: + temperature: null + top_p: null + thinking: + type: enabled + budget_tokens: 16000 + max_output_tokens: 24000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + default_reasoning_effort: high + - name: claude-opus-4-6 + type: chat + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - max + default_reasoning_effort: high + - name: claude-opus-4-6:thinking + type: chat + real_name: claude-opus-4-6 + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 25.0 + patch: + body: + temperature: null + top_p: null + thinking: + type: enabled + budget_tokens: 16000 + max_output_tokens: 24000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + default_reasoning_effort: high + - name: claude-opus-4-5 + type: chat + max_input_tokens: 200000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 64000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - name: claude-opus-4-5-20251101 + type: chat + max_input_tokens: 200000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 64000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - name: claude-opus-4-5-20251101:thinking + type: chat + real_name: claude-opus-4-5-20251101 + max_input_tokens: 200000 + input_price: 5.0 + output_price: 25.0 + patch: + body: + temperature: null + top_p: null + thinking: + type: enabled + budget_tokens: 16000 + max_output_tokens: 24000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: claude-haiku-4-5 + type: chat + max_input_tokens: 200000 + input_price: 1.0 + output_price: 5.0 + max_output_tokens: 64000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: claude-haiku-4-5-20251001 + type: chat + max_input_tokens: 200000 + input_price: 1.0 + output_price: 5.0 + max_output_tokens: 64000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: claude-haiku-4-5-20251001:thinking + type: chat + real_name: claude-haiku-4-5-20251001 + max_input_tokens: 200000 + input_price: 1.0 + output_price: 5.0 + patch: + body: + temperature: null + top_p: null + thinking: + type: enabled + budget_tokens: 16000 + max_output_tokens: 24000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: claude-sonnet-4-5 + type: chat + max_input_tokens: 1000000 + input_price: 3.0 + output_price: 15.0 + max_output_tokens: 64000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: claude-sonnet-4-5-20250929 + type: chat + max_input_tokens: 1000000 + input_price: 3.0 + output_price: 15.0 + max_output_tokens: 64000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: claude-sonnet-4-5-20250929:thinking + type: chat + real_name: claude-sonnet-4-5-20250929 + max_input_tokens: 1000000 + input_price: 3.0 + output_price: 15.0 + patch: + body: + temperature: null + top_p: null + thinking: + type: enabled + budget_tokens: 16000 + max_output_tokens: 24000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true - provider: mistral models: - - name: mistral-large-latest - max_output_tokens: 262144 - input_price: 0.5 - output_price: 1.5 - supports_function_calling: true - supports_vision: true - - name: mistral-medium-latest - max_input_tokens: 131072 - input_price: 0.4 - output_price: 2 - supports_function_calling: true - supports_vision: true - - name: mistral-small-latest - max_input_tokens: 32768 - input_price: 0.1 - output_price: 0.3 - supports_function_calling: true - supports_vision: true - - name: magistral-medium-latest - max_input_tokens: 131072 - input_price: 2 - output_price: 5 - - name: magistral-small-latest - max_input_tokens: 131072 - input_price: 0.5 - output_price: 1.5 - - name: devstral-medium-latest - max_input_tokens: 262144 - input_price: 0.4 - output_price: 2 - supports_function_calling: true - - name: devstral-small-latest - max_input_tokens: 262144 - input_price: 0.1 - output_price: 0.3 - supports_function_calling: true - - name: codestral-latest - max_input_tokens: 262144 - input_price: 0.3 - output_price: 0.9 - supports_function_calling: true - - name: ministral-14b-latest - max_input_tokens: 262144 - input_price: 0.2 - output_price: 0.2 - supports_function_calling: true - - name: mistral-embed - type: embedding - max_input_tokens: 8092 - input_price: 0.1 - max_tokens_per_chunk: 8092 - default_chunk_size: 2000 - -# Links: -# - https://docs.ai21.com/docs/jamba-foundation-models -# - https://www.ai21.com/pricing -# - https://docs.ai21.com/reference/jamba-1-6-api-ref + - name: mistral-embed + type: embedding + max_input_tokens: 8092 + input_price: 0.1 + output_price: 0.0 + max_output_tokens: 3072 + max_tokens_per_chunk: 8092 + default_chunk_size: 2000 + - name: magistral-small-latest + type: chat + max_input_tokens: 131072 + input_price: 0.5 + output_price: 1.5 + - name: devstral-small-latest + type: chat + max_input_tokens: 262144 + input_price: 0.1 + output_price: 0.3 + supports_function_calling: true + - name: ministral-14b-latest + type: chat + max_input_tokens: 262144 + input_price: 0.2 + output_price: 0.2 + supports_function_calling: true + - name: zai-glm-5-2 + type: chat + max_input_tokens: 1000000 + input_price: 1.4 + output_price: 4.4 + max_output_tokens: 131072 + supports_function_calling: true + reasoning_levels: + - high + - max + - name: mistral-medium-2604 + type: chat + max_input_tokens: 262144 + input_price: 1.5 + output_price: 7.5 + max_output_tokens: 262144 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - high + - name: mistral-medium-latest + type: chat + max_input_tokens: 262144 + input_price: 1.5 + output_price: 7.5 + max_output_tokens: 262144 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - high + - name: mistral-small-2603 + type: chat + max_input_tokens: 256000 + input_price: 0.15 + output_price: 0.6 + max_output_tokens: 256000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - high + - name: mistral-small-latest + type: chat + max_input_tokens: 256000 + input_price: 0.15 + output_price: 0.6 + max_output_tokens: 256000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - high + - name: devstral-2512 + type: chat + max_input_tokens: 262144 + input_price: 0.4 + output_price: 2.0 + max_output_tokens: 262144 + supports_function_calling: true + - name: devstral-latest + type: chat + max_input_tokens: 262144 + input_price: 0.4 + output_price: 2.0 + max_output_tokens: 262144 + supports_function_calling: true + - name: labs-devstral-small-2512 + type: chat + max_input_tokens: 256000 + input_price: 0.0 + output_price: 0.0 + max_output_tokens: 256000 + supports_vision: true + supports_function_calling: true + - name: devstral-medium-latest + type: chat + max_input_tokens: 262144 + input_price: 0.4 + output_price: 2.0 + max_output_tokens: 262144 + supports_function_calling: true + - name: mistral-medium-2508 + type: chat + max_input_tokens: 262144 + input_price: 0.4 + output_price: 2.0 + max_output_tokens: 262144 + supports_vision: true + supports_function_calling: true + - name: devstral-medium-2507 + type: chat + max_input_tokens: 128000 + input_price: 0.4 + output_price: 2.0 + max_output_tokens: 128000 + supports_function_calling: true + - name: devstral-small-2507 + type: chat + max_input_tokens: 128000 + input_price: 0.1 + output_price: 0.3 + max_output_tokens: 128000 + supports_function_calling: true + - name: mistral-small-2506 + type: chat + max_input_tokens: 128000 + input_price: 0.1 + output_price: 0.3 + max_output_tokens: 16384 + supports_vision: true + supports_function_calling: true + - name: devstral-small-2505 + type: chat + max_input_tokens: 128000 + input_price: 0.1 + output_price: 0.3 + max_output_tokens: 128000 + supports_function_calling: true + - name: mistral-medium-2505 + type: chat + max_input_tokens: 131072 + input_price: 0.4 + output_price: 2.0 + max_output_tokens: 131072 + supports_vision: true + supports_function_calling: true + - name: magistral-medium-latest + type: chat + max_input_tokens: 128000 + input_price: 2.0 + output_price: 5.0 + max_output_tokens: 16384 + supports_function_calling: true + - name: magistral-small + type: chat + max_input_tokens: 128000 + input_price: 0.5 + output_price: 1.5 + max_output_tokens: 128000 + supports_function_calling: true + - name: mistral-large-2411 + type: chat + max_input_tokens: 131072 + input_price: 2.0 + output_price: 6.0 + max_output_tokens: 16384 + supports_function_calling: true + - name: mistral-large-2512 + type: chat + max_input_tokens: 262144 + input_price: 0.5 + output_price: 1.5 + max_output_tokens: 262144 + supports_vision: true + supports_function_calling: true + - name: mistral-large-latest + type: chat + max_input_tokens: 262144 + input_price: 0.5 + output_price: 1.5 + max_output_tokens: 262144 + supports_vision: true + supports_function_calling: true + - name: pixtral-large-latest + type: chat + max_input_tokens: 128000 + input_price: 2.0 + output_price: 6.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + - name: ministral-3b-latest + type: chat + max_input_tokens: 128000 + input_price: 0.04 + output_price: 0.04 + max_output_tokens: 128000 + supports_function_calling: true + - name: ministral-8b-latest + type: chat + max_input_tokens: 128000 + input_price: 0.1 + output_price: 0.1 + max_output_tokens: 128000 + supports_function_calling: true + - name: pixtral-12b + type: chat + max_input_tokens: 128000 + input_price: 0.15 + output_price: 0.15 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + - name: mistral-nemo + type: chat + max_input_tokens: 128000 + input_price: 0.15 + output_price: 0.15 + max_output_tokens: 128000 + supports_function_calling: true + - name: open-mistral-nemo + type: chat + max_input_tokens: 128000 + input_price: 0.15 + output_price: 0.15 + max_output_tokens: 128000 + supports_function_calling: true + - name: codestral-latest + type: chat + max_input_tokens: 256000 + input_price: 0.3 + output_price: 0.9 + max_output_tokens: 4096 + supports_function_calling: true + - name: open-mixtral-8x22b + type: chat + max_input_tokens: 64000 + input_price: 2.0 + output_price: 6.0 + max_output_tokens: 64000 + supports_function_calling: true + - name: open-mixtral-8x7b + type: chat + max_input_tokens: 32000 + input_price: 0.7 + output_price: 0.7 + max_output_tokens: 32000 + supports_function_calling: true + - name: open-mistral-7b + type: chat + max_input_tokens: 8000 + input_price: 0.25 + output_price: 0.25 + max_output_tokens: 8000 + supports_function_calling: true - provider: ai21 models: - - name: jamba-large - max_input_tokens: 256000 - input_price: 2 - output_price: 8 - supports_function_calling: true - - name: jamba-mini - max_input_tokens: 256000 - input_price: 0.2 - output_price: 0.4 - supports_function_calling: true - -# Links: -# - https://docs.cohere.com/docs/models -# - https://cohere.com/pricing -# - https://docs.cohere.com/reference/chat + - name: jamba-large + type: chat + max_input_tokens: 256000 + input_price: 2.0 + output_price: 8.0 + supports_function_calling: true + - name: jamba-mini + type: chat + max_input_tokens: 256000 + input_price: 0.2 + output_price: 0.4 + supports_function_calling: true - provider: cohere models: - - name: command-a-03-2025 - max_input_tokens: 262144 - max_output_tokens: 8192 - input_price: 2.5 - output_price: 10 - supports_function_calling: true - - name: command-a-reasoning-08-2025 - max_input_tokens: 262144 - max_output_tokens: 32768 - input_price: 2.5 - output_price: 10 - - name: command-a-vision-07-2025 - max_input_tokens: 131072 - max_output_tokens: 8192 - input_price: 2.5 - output_price: 10 - supports_vision: true - - name: command-r7b-12-2024 - max_input_tokens: 131072 - max_output_tokens: 4096 - input_price: 0.0375 - output_price: 0.15 - - name: embed-v4.0 - type: embedding - input_price: 0.12 - max_tokens_per_chunk: 2048 - default_chunk_size: 2000 - max_batch_size: 96 - - name: embed-english-v3.0 - type: embedding - input_price: 0.1 - max_tokens_per_chunk: 512 - default_chunk_size: 1000 - max_batch_size: 96 - - name: embed-multilingual-v3.0 - type: embedding - input_price: 0.1 - max_tokens_per_chunk: 512 - default_chunk_size: 1000 - max_batch_size: 96 - - name: rerank-v3.5 - type: reranker - max_input_tokens: 4096 - - name: rerank-english-v3.0 - type: reranker - max_input_tokens: 4096 - - name: rerank-multilingual-v3.0 - type: reranker - max_input_tokens: 4096 - -# Links: -# - https://docs.x.ai/docs/models -# - https://docs.x.ai/docs/api-reference#chat-completions + - name: embed-v4.0 + type: embedding + input_price: 0.12 + max_tokens_per_chunk: 2048 + default_chunk_size: 2000 + max_batch_size: 96 + - name: embed-english-v3.0 + type: embedding + input_price: 0.1 + max_tokens_per_chunk: 512 + default_chunk_size: 1000 + max_batch_size: 96 + - name: embed-multilingual-v3.0 + type: embedding + input_price: 0.1 + max_tokens_per_chunk: 512 + default_chunk_size: 1000 + max_batch_size: 96 + - name: rerank-v3.5 + type: reranker + max_input_tokens: 4096 + - name: rerank-english-v3.0 + type: reranker + max_input_tokens: 4096 + - name: rerank-multilingual-v3.0 + type: reranker + max_input_tokens: 4096 + - name: north-mini-code-1-0 + type: chat + max_input_tokens: 256000 + input_price: 0.0 + output_price: 0.0 + max_output_tokens: 64000 + supports_function_calling: true + reasoning_levels: + - none + - high + - name: command-a-plus-05-2026 + type: chat + max_input_tokens: 128000 + input_price: 2.5 + output_price: 10.0 + max_output_tokens: 64000 + supports_vision: true + supports_function_calling: true + - name: command-a-translate-08-2025 + type: chat + max_input_tokens: 8000 + input_price: 2.5 + output_price: 10.0 + max_output_tokens: 8000 + supports_function_calling: true + - name: command-a-reasoning-08-2025 + type: chat + max_input_tokens: 256000 + input_price: 2.5 + output_price: 10.0 + max_output_tokens: 32000 + supports_function_calling: true + - name: command-a-vision-07-2025 + type: chat + max_input_tokens: 128000 + input_price: 2.5 + output_price: 10.0 + max_output_tokens: 8000 + supports_vision: true + - name: command-a-03-2025 + type: chat + max_input_tokens: 256000 + input_price: 2.5 + output_price: 10.0 + max_output_tokens: 8000 + supports_function_calling: true + - name: c4ai-aya-vision-32b + type: chat + max_input_tokens: 16000 + max_output_tokens: 4000 + supports_vision: true + - name: c4ai-aya-vision-8b + type: chat + max_input_tokens: 16000 + max_output_tokens: 4000 + supports_vision: true + - name: command-r7b-arabic-02-2025 + type: chat + max_input_tokens: 128000 + input_price: 0.0375 + output_price: 0.15 + max_output_tokens: 4000 + supports_function_calling: true + - name: command-r7b-12-2024 + type: chat + max_input_tokens: 128000 + input_price: 0.0375 + output_price: 0.15 + max_output_tokens: 4000 + supports_function_calling: true + - name: c4ai-aya-expanse-32b + type: chat + max_input_tokens: 128000 + max_output_tokens: 4000 + - name: c4ai-aya-expanse-8b + type: chat + max_input_tokens: 8000 + max_output_tokens: 4000 + - name: command-r-08-2024 + type: chat + max_input_tokens: 128000 + input_price: 0.15 + output_price: 0.6 + max_output_tokens: 4000 + supports_function_calling: true + - name: command-r-plus-08-2024 + type: chat + max_input_tokens: 128000 + input_price: 2.5 + output_price: 10.0 + max_output_tokens: 4000 + supports_function_calling: true - provider: xai oauth: client_id: b1a00492-073a-47ea-816f-4c329264a828 - authorize_url: https://auth.x.ai/oauth2/authorize token_url: https://auth.x.ai/oauth2/token - scopes: - - openid - - profile - - email - - offline_access - - grok-cli:access - - api:access - redirect_port: 56121 flow: pkce + client_secret: null + authorize_url: https://auth.x.ai/oauth2/authorize + redirect_uri: null + redirect_port: 56121 + device_authorization_url: null + scopes: + - openid + - profile + - email + - offline_access + - grok-cli:access + - api:access token_request_format: form_url_encoded extra_authorize_params: plan: generic referrer: coyote + extra_token_headers: {} + extra_request_headers: {} echo_pkce_in_token_exchange: true + use_pkce_in_device_flow: false + include_state_in_token_exchange: true models: - - name: grok-4.6 - input_price: 2 - output_price: 6 - max_input_tokens: 500000 - supports_function_calling: true - - name: grok-4.5 - input_price: 2 - output_price: 6 - max_input_tokens: 256000 - supports_function_calling: true - - name: grok-build-0.1 - input_price: 1 - output_price: 2 - max_input_tokens: 256000 - supports_function_calling: true - - name: grok-4.3 - input_price: 1.25 - output_price: 2.5 - max_input_tokens: 1000000 - supports_function_calling: true - - name: grok-4.20 - real_name: grok-4.20-multi-agent-0309 - input_price: 1.25 - output_price: 2.5 - max_input_tokens: 1000000 - supports_function_calling: true - - name: grok-4.20-reasoning - real_name: grok-4.20-0309-reasoning - input_price: 1.25 - output_price: 2.5 - max_input_tokens: 1000000 - supports_function_calling: true - - name: grok-4.20-non-reasoning - real_name: grok-4.20-0309-non-reasoning - input_price: 1.25 - output_price: 2.5 - max_input_tokens: 1000000 - supports_function_calling: true - - name: grok-4-1-fast-non-reasoning - max_input_tokens: 1000000 - input_price: 0.2 - output_price: 0.5 - supports_function_calling: true - - name: grok-4-1-fast-reasoning - max_input_tokens: 1000000 - input_price: 0.2 - output_price: 0.5 - supports_function_calling: true - - name: grok-code-fast-1 - max_input_tokens: 256000 - input_price: 0.2 - output_price: 1.5 - supports_function_calling: true - - name: grok-3 - max_input_tokens: 131072 - input_price: 3 - output_price: 15 - supports_function_calling: true - - name: grok-3-mini - max_input_tokens: 131072 - input_price: 0.3 - output_price: 0.5 - supports_function_calling: true - -# Links: -# - https://docs.perplexity.ai/getting-started/models -# - https://docs.perplexity.ai/api-reference/chat-completions + - name: grok-4.20 + type: chat + real_name: grok-4.20-multi-agent-0309 + max_input_tokens: 1000000 + input_price: 1.25 + output_price: 2.5 + supports_function_calling: true + - name: grok-4.20-reasoning + type: chat + real_name: grok-4.20-0309-reasoning + max_input_tokens: 1000000 + input_price: 1.25 + output_price: 2.5 + supports_function_calling: true + - name: grok-4.20-non-reasoning + type: chat + real_name: grok-4.20-0309-non-reasoning + max_input_tokens: 1000000 + input_price: 1.25 + output_price: 2.5 + supports_function_calling: true + - name: grok-4-1-fast-non-reasoning + type: chat + max_input_tokens: 1000000 + input_price: 0.2 + output_price: 0.5 + supports_function_calling: true + - name: grok-4-1-fast-reasoning + type: chat + max_input_tokens: 1000000 + input_price: 0.2 + output_price: 0.5 + supports_function_calling: true + - name: grok-code-fast-1 + type: chat + max_input_tokens: 256000 + input_price: 0.2 + output_price: 1.5 + supports_function_calling: true + - name: grok-3 + type: chat + max_input_tokens: 131072 + input_price: 3.0 + output_price: 15.0 + supports_function_calling: true + - name: grok-3-mini + type: chat + max_input_tokens: 131072 + input_price: 0.3 + output_price: 0.5 + supports_function_calling: true + - name: grok-4.6 + type: chat + max_input_tokens: 500000 + input_price: 2.0 + output_price: 6.0 + max_output_tokens: 500000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - name: grok-4.5 + type: chat + max_input_tokens: 500000 + input_price: 2.0 + output_price: 6.0 + max_output_tokens: 500000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - name: grok-4.3 + type: chat + max_input_tokens: 1000000 + input_price: 1.25 + output_price: 2.5 + max_output_tokens: 30000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + - name: grok-build-0.1 + type: chat + max_input_tokens: 256000 + input_price: 1.0 + output_price: 2.0 + max_output_tokens: 256000 + supports_vision: true + supports_function_calling: true + - name: grok-4.20-0309-non-reasoning + type: chat + max_input_tokens: 1000000 + input_price: 1.25 + output_price: 2.5 + max_output_tokens: 30000 + supports_vision: true + supports_function_calling: true + - name: grok-4.20-0309-reasoning + type: chat + max_input_tokens: 1000000 + input_price: 1.25 + output_price: 2.5 + max_output_tokens: 30000 + supports_vision: true + supports_function_calling: true + - name: grok-4.20-multi-agent-0309 + type: chat + max_input_tokens: 1000000 + input_price: 1.25 + output_price: 2.5 + max_output_tokens: 30000 + supports_vision: true + reasoning_levels: + - low + - medium + - high + - xhigh - provider: perplexity models: - - name: sonar-pro - max_output_tokens: 8000 - supports_vision: true - max_input_tokens: 200000 - input_price: 3 - output_price: 15 - - name: sonar - supports_vision: true - max_input_tokens: 127072 - input_price: 1 - output_price: 1 - - name: sonar-reasoning-pro - supports_vision: true - max_input_tokens: 128000 - input_price: 2 - output_price: 8 - - name: sonar-reasoning - max_input_tokens: 128000 - input_price: 1 - output_price: 5 - - name: sonar-deep-research - max_input_tokens: 128000 - input_price: 2 - output_price: 8 - -# Links: -# - https://console.groq.com/docs/models -# - https://console.groq.com/docs/api-reference#chat + - name: sonar-reasoning + type: chat + max_input_tokens: 128000 + input_price: 1.0 + output_price: 5.0 + - name: sonar-deep-research + type: chat + max_input_tokens: 128000 + input_price: 2.0 + output_price: 8.0 + max_output_tokens: 32768 + reasoning_levels: + - minimal + - low + - medium + - high + - name: sonar + type: chat + max_input_tokens: 128000 + input_price: 1.0 + output_price: 1.0 + max_output_tokens: 4096 + supports_vision: true + - name: sonar-pro + type: chat + max_input_tokens: 200000 + input_price: 3.0 + output_price: 15.0 + max_output_tokens: 8192 + supports_vision: true + - name: sonar-reasoning-pro + type: chat + max_input_tokens: 128000 + input_price: 2.0 + output_price: 8.0 + max_output_tokens: 4096 + supports_vision: true + reasoning_levels: + - minimal + - low + - medium + - high - provider: groq models: - - name: openai/gpt-oss-120b - max_input_tokens: 131072 - input_price: 0 - output_price: 0 - supports_function_calling: true - - name: openai/gpt-oss-20b - max_input_tokens: 131072 - input_price: 0 - output_price: 0 - supports_function_calling: true - - name: meta-llama/llama-4-maverick-17b-128e-instruct - max_input_tokens: 131072 - input_price: 0 - output_price: 0 - supports_vision: true - supports_function_calling: true - - name: meta-llama/llama-4-scout-17b-16e-instruct - max_input_tokens: 131072 - input_price: 0 - output_price: 0 - supports_vision: true - supports_function_calling: true - - name: llama-3.3-70b-versatile - max_input_tokens: 131072 - input_price: 0 - output_price: 0 - supports_function_calling: true - - name: moonshotai/kimi-k2-instruct-0905 - max_input_tokens: 262144 - input_price: 0 - output_price: 0 - supports_function_calling: true - - name: qwen/qwen3-32b - max_input_tokens: 131072 - input_price: 0 - output_price: 0 - - name: groq/compound - max_input_tokens: 131072 - input_price: 0 - output_price: 0 - - name: groq/compound-mini - max_input_tokens: 131072 - input_price: 0 - output_price: 0 - -# Links: -# - https://cloud.google.com/vertex-ai/generative-ai/docs/learn/models -# - https://cloud.google.com/vertex-ai/generative-ai/pricing -# - https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/gemini + - name: meta-llama/llama-4-maverick-17b-128e-instruct + type: chat + max_input_tokens: 131072 + input_price: 0.0 + output_price: 0.0 + supports_vision: true + supports_function_calling: true + - name: meta-llama/llama-4-scout-17b-16e-instruct + type: chat + max_input_tokens: 131072 + input_price: 0.0 + output_price: 0.0 + supports_vision: true + supports_function_calling: true + - name: moonshotai/kimi-k2-instruct-0905 + type: chat + max_input_tokens: 262144 + input_price: 0.0 + output_price: 0.0 + supports_function_calling: true + - name: qwen/qwen3-32b + type: chat + max_input_tokens: 131072 + input_price: 0.0 + output_price: 0.0 + - name: qwen/qwen3.8-27b + type: chat + max_input_tokens: 131042 + input_price: 0.8 + output_price: 4.0 + max_output_tokens: 16384 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - default + - low + - medium + - high + - name: qwen/qwen3.6-27b + type: chat + max_input_tokens: 131072 + input_price: 0.6 + output_price: 3.0 + max_output_tokens: 16384 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - default + - name: canopylabs/orpheus-v1-english + type: chat + max_input_tokens: 4000 + max_output_tokens: 50000 + - name: canopylabs/orpheus-arabic-saudi + type: chat + max_input_tokens: 4000 + max_output_tokens: 50000 + - name: openai/gpt-oss-safeguard-20b + type: chat + max_input_tokens: 131072 + input_price: 0.075 + output_price: 0.3 + max_output_tokens: 65536 + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - name: groq/compound + type: chat + max_input_tokens: 131072 + max_output_tokens: 8192 + - name: groq/compound-mini + type: chat + max_input_tokens: 131072 + max_output_tokens: 8192 + - name: openai/gpt-oss-120b + type: chat + max_input_tokens: 131072 + input_price: 0.15 + output_price: 0.6 + max_output_tokens: 65536 + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - name: openai/gpt-oss-20b + type: chat + max_input_tokens: 131072 + input_price: 0.075 + output_price: 0.3 + max_output_tokens: 65536 + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - name: meta-llama/llama-prompt-guard-2-22m + type: chat + max_input_tokens: 512 + input_price: 0.03 + output_price: 0.03 + max_output_tokens: 512 + - name: meta-llama/llama-prompt-guard-2-86m + type: chat + max_input_tokens: 512 + input_price: 0.04 + output_price: 0.04 + max_output_tokens: 512 + - name: allam-2-7b + type: chat + max_input_tokens: 4096 + input_price: 0.0 + output_price: 0.0 + max_output_tokens: 4096 + - name: llama-3.3-70b-versatile + type: chat + max_input_tokens: 131072 + input_price: 0.59 + output_price: 0.79 + max_output_tokens: 32768 + supports_function_calling: true + - name: llama-3.1-8b-instant + type: chat + max_input_tokens: 131072 + input_price: 0.05 + output_price: 0.08 + max_output_tokens: 131072 + supports_function_calling: true - provider: vertexai models: - - name: gemini-3.5-flash - max_input_tokens: 1048576 - max_output_tokens: 65536 - input_price: 0.2 - output_price: 1.5 - supports_function_calling: true - reasoning_levels: [minimal, low, medium, high] - default_reasoning_effort: medium - - name: gemini-3-flash-preview - max_input_tokens: 1048576 - max_output_tokens: 65536 - input_price: 0.2 - output_price: 1.5 - supports_function_calling: true - reasoning_levels: [minimal, low, medium, high] - default_reasoning_effort: high - - name: gemini-3.1-flash-lite - max_input_tokens: 1048576 - max_output_tokens: 65536 - input_price: 0.2 - output_price: 1.5 - supports_function_calling: true - reasoning_levels: [minimal, high] - default_reasoning_effort: minimal - - name: gemini-3.1-pro-preview - max_input_tokens: 1048576 - max_output_tokens: 65536 - input_price: 2 - output_price: 12 - supports_vision: true - supports_function_calling: true - reasoning_levels: [low, medium, high] - default_reasoning_effort: high - - name: gemini-2.5-flash - max_input_tokens: 1048576 - max_output_tokens: 65535 - input_price: 0.3 - output_price: 2.5 - supports_vision: true - supports_function_calling: true - reasoning_levels: [low, medium, high] - default_reasoning_effort: medium - - name: gemini-2.5-pro - max_input_tokens: 1048576 - max_output_tokens: 65536 - input_price: 1.25 - output_price: 10 - supports_vision: true - supports_function_calling: true - reasoning_levels: [low, medium, high] - default_reasoning_effort: high - - name: gemini-2.5-flash-lite - max_input_tokens: 1048576 - max_output_tokens: 65536 - input_price: 0.3 - output_price: 0.4 - supports_vision: true - supports_function_calling: true - - name: gemini-3-pro-preview - max_input_tokens: 1048576 - supports_vision: true - supports_function_calling: true - reasoning_levels: [low, high] - default_reasoning_effort: high - - name: gemini-3-flash-preview - max_input_tokens: 1048576 - supports_vision: true - supports_function_calling: true - reasoning_levels: [minimal, low, medium, high] - default_reasoning_effort: high - - name: claude-opus-5 - max_input_tokens: 1000000 - max_output_tokens: 128000 - require_max_tokens: true - input_price: 5 - output_price: 25 - supports_function_calling: true - supports_vision: true - reasoning_levels: [low, medium, high, xhigh, max] - default_reasoning_effort: high - - name: claude-fable-5-1 - max_input_tokens: 1000000 - max_output_tokens: 128000 - require_max_tokens: true - input_price: 10 - output_price: 50 - supports_function_calling: true - supports_vision: true - reasoning_levels: [low, medium, high, xhigh, max] - default_reasoning_effort: high - - name: claude-fable-5 - max_input_tokens: 1000000 - max_output_tokens: 128000 - require_max_tokens: true - input_price: 10 - output_price: 50 - supports_function_calling: true - supports_vision: true - reasoning_levels: [low, medium, high, xhigh, max] - default_reasoning_effort: high - - name: claude-opus-4-8 - max_input_tokens: 1000000 - max_output_tokens: 128000 - require_max_tokens: true - input_price: 5 - output_price: 25 - supports_vision: true - supports_function_calling: true - reasoning_levels: [low, medium, high, xhigh, max] - default_reasoning_effort: high - - name: claude-opus-4-7 - max_input_tokens: 1000000 - max_output_tokens: 128000 - require_max_tokens: true - input_price: 5 - output_price: 25 - supports_vision: true - supports_function_calling: true - reasoning_levels: [low, medium, high, xhigh, max] - default_reasoning_effort: high - - name: claude-opus-4-6 - max_input_tokens: 200000 - max_output_tokens: 8192 - require_max_tokens: true - input_price: 5 - output_price: 25 - supports_vision: true - supports_function_calling: true - - name: claude-opus-4-6:thinking - real_name: claude-opus-4-6 - max_input_tokens: 200000 - max_output_tokens: 24000 - require_max_tokens: true - input_price: 5 - output_price: 25 - supports_vision: true - patch: - body: - temperature: null - top_p: null - thinking: - type: enabled - budget_tokens: 16000 - - name: claude-sonnet-5 - max_input_tokens: 1000000 - max_output_tokens: 128000 - require_max_tokens: true - input_price: 3 - output_price: 15 - supports_vision: true - supports_function_calling: true - reasoning_levels: [low, medium, high, xhigh, max] - default_reasoning_effort: high - - name: claude-sonnet-4-6 - max_input_tokens: 200000 - max_output_tokens: 8192 - require_max_tokens: true - input_price: 3 - output_price: 15 - supports_vision: true - supports_function_calling: true - reasoning_levels: [low, medium, high, max] - default_reasoning_effort: high - - name: claude-sonnet-4-6:thinking - real_name: claude-sonnet-4-6 - max_input_tokens: 200000 - max_output_tokens: 24000 - require_max_tokens: true - input_price: 3 - output_price: 15 - supports_vision: true - patch: - body: - temperature: null - top_p: null - thinking: - type: enabled - budget_tokens: 16000 - - name: claude-opus-4-5@20251101 - max_input_tokens: 200000 - max_output_tokens: 8192 - require_max_tokens: true - input_price: 5 - output_price: 25 - supports_vision: true - supports_function_calling: true - - name: claude-opus-4-5@20251101:thinking - real_name: claude-opus-4-5@20251101 - max_input_tokens: 200000 - max_output_tokens: 24000 - require_max_tokens: true - input_price: 5 - output_price: 25 - supports_vision: true - patch: - body: - temperature: null - top_p: null - thinking: - type: enabled - budget_tokens: 16000 - - name: claude-sonnet-4-5@20250929 - max_input_tokens: 200000 - max_output_tokens: 8192 - require_max_tokens: true - input_price: 3 - output_price: 15 - supports_vision: true - supports_function_calling: true - - name: claude-sonnet-4-5@20250929:thinking - real_name: claude-sonnet-4-5@20250929 - max_input_tokens: 200000 - max_output_tokens: 24000 - require_max_tokens: true - input_price: 3 - output_price: 15 - supports_vision: true - patch: - body: - temperature: null - top_p: null - thinking: - type: enabled - budget_tokens: 16000 - - name: claude-haiku-4-5@20251001 - max_input_tokens: 200000 - max_output_tokens: 8192 - require_max_tokens: true - input_price: 1 - output_price: 5 - supports_vision: true - supports_function_calling: true - - name: claude-haiku-4-5@20251001:thinking - real_name: claude-haiku-4-5@20251001 - max_input_tokens: 200000 - max_output_tokens: 24000 - require_max_tokens: true - input_price: 1 - output_price: 5 - supports_vision: true - patch: - body: - temperature: null - top_p: null - thinking: - type: enabled - budget_tokens: 16000 - - name: claude-3-5-haiku@20241022 - max_input_tokens: 200000 - max_output_tokens: 8192 - require_max_tokens: true - input_price: 0.8 - output_price: 4 - supports_vision: true - supports_function_calling: true - - name: mistral-small-2503 - max_input_tokens: 32000 - input_price: 0.1 - output_price: 0.3 - supports_function_calling: true - - name: codestral-2501 - max_input_tokens: 256000 - input_price: 0.3 - output_price: 0.9 - supports_function_calling: true - - name: text-embedding-005 - type: embedding - max_input_tokens: 20000 - input_price: 0.025 - max_tokens_per_chunk: 2048 - default_chunk_size: 1500 - max_batch_size: 5 - - name: text-multilingual-embedding-002 - type: embedding - max_input_tokens: 20000 - input_price: 0.2 - max_tokens_per_chunk: 2048 - default_chunk_size: 1500 - max_batch_size: 5 - -# Links: -# - https://docs.aws.amazon.com/bedrock/latest/userguide/model-ids.html#model-ids-arns -# - https://docs.aws.amazon.com/bedrock/latest/userguide/conversation-inference-supported-models-features.html -# - https://aws.amazon.com/bedrock/pricing/ -# - https://docs.aws.amazon.com/bedrock/latest/userguide/conversation-inference-call.html + - name: text-embedding-005 + type: embedding + max_input_tokens: 20000 + input_price: 0.025 + max_tokens_per_chunk: 2048 + default_chunk_size: 1500 + max_batch_size: 5 + - name: text-multilingual-embedding-002 + type: embedding + max_input_tokens: 20000 + input_price: 0.2 + max_tokens_per_chunk: 2048 + default_chunk_size: 1500 + max_batch_size: 5 + - name: gemini-3-pro-preview + type: chat + max_input_tokens: 1048576 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - high + default_reasoning_effort: high + - name: claude-opus-5 + type: chat + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: high + - name: claude-fable-5-1 + type: chat + max_input_tokens: 1000000 + input_price: 10.0 + output_price: 50.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: high + - name: claude-fable-5 + type: chat + max_input_tokens: 1000000 + input_price: 10.0 + output_price: 50.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: high + - name: claude-opus-4-8 + type: chat + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: high + - name: claude-opus-4-7 + type: chat + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: high + - name: claude-opus-4-6 + type: chat + max_input_tokens: 200000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 8192 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: claude-opus-4-6:thinking + type: chat + real_name: claude-opus-4-6 + max_input_tokens: 200000 + input_price: 5.0 + output_price: 25.0 + patch: + body: + temperature: null + top_p: null + thinking: + type: enabled + budget_tokens: 16000 + max_output_tokens: 24000 + require_max_tokens: true + supports_vision: true + - name: claude-sonnet-5 + type: chat + max_input_tokens: 1000000 + input_price: 3.0 + output_price: 15.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: high + - name: claude-sonnet-4-6 + type: chat + max_input_tokens: 200000 + input_price: 3.0 + output_price: 15.0 + max_output_tokens: 8192 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - max + default_reasoning_effort: high + - name: claude-sonnet-4-6:thinking + type: chat + real_name: claude-sonnet-4-6 + max_input_tokens: 200000 + input_price: 3.0 + output_price: 15.0 + patch: + body: + temperature: null + top_p: null + thinking: + type: enabled + budget_tokens: 16000 + max_output_tokens: 24000 + require_max_tokens: true + supports_vision: true + default_reasoning_effort: high + - name: claude-3-5-haiku@20241022 + type: chat + max_input_tokens: 200000 + input_price: 0.8 + output_price: 4.0 + max_output_tokens: 8192 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: mistral-small-2503 + type: chat + max_input_tokens: 32000 + input_price: 0.1 + output_price: 0.3 + supports_function_calling: true + - name: codestral-2501 + type: chat + max_input_tokens: 256000 + input_price: 0.3 + output_price: 0.9 + supports_function_calling: true + - name: gemini-3.8-flash + type: chat + max_input_tokens: 1048576 + input_price: 0.75 + output_price: 3.75 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - name: claude-fable-5-1@default + type: chat + max_input_tokens: 1000000 + input_price: 10.0 + output_price: 50.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: high + - name: gemini-3.7-flash + type: chat + max_input_tokens: 1048576 + input_price: 0.75 + output_price: 3.75 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - name: gemini-flash-latest + type: chat + max_input_tokens: 1048576 + input_price: 1.5 + output_price: 9.0 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - minimal + - low + - medium + - high + - name: claude-opus-5@default + type: chat + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + - name: gemini-3.5-flash-lite + type: chat + max_input_tokens: 1048576 + input_price: 0.3 + output_price: 2.5 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - minimal + - low + - medium + - high + - name: gemini-3.6-flash + type: chat + max_input_tokens: 1048576 + input_price: 0.75 + output_price: 3.75 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - minimal + - low + - medium + - high + - name: gemini-flash-lite-latest + type: chat + max_input_tokens: 1048576 + input_price: 0.25 + output_price: 1.5 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - minimal + - low + - medium + - high + - name: claude-sonnet-5@default + type: chat + max_input_tokens: 1000000 + input_price: 2.0 + output_price: 10.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + - name: claude-fable-5@default + type: chat + max_input_tokens: 1000000 + input_price: 10.0 + output_price: 50.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: high + - name: claude-opus-4-8@default + type: chat + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + - name: gemini-3-pro-image + type: chat + max_input_tokens: 65536 + input_price: 2.0 + output_price: 120.0 + max_output_tokens: 32768 + supports_vision: true + supports_function_calling: true + - name: gemini-3.1-flash-image + type: chat + max_input_tokens: 131072 + input_price: 0.5 + output_price: 60.0 + max_output_tokens: 32768 + supports_vision: true + reasoning_levels: + - minimal + - high + - name: gemini-3.5-flash + type: chat + max_input_tokens: 1048576 + input_price: 1.5 + output_price: 9.0 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - minimal + - low + - medium + - high + default_reasoning_effort: medium + - name: gemini-3.1-flash-lite + type: chat + max_input_tokens: 1048576 + input_price: 0.25 + output_price: 1.5 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - minimal + - low + - medium + - high + default_reasoning_effort: minimal + - name: claude-opus-4-7@default + type: chat + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + - name: gemini-3.1-flash-lite-preview + type: chat + max_input_tokens: 1048576 + input_price: 0.25 + output_price: 1.5 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - minimal + - low + - medium + - high + - name: gemini-3.1-pro-preview + type: chat + max_input_tokens: 1048576 + input_price: 2.0 + output_price: 12.0 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + default_reasoning_effort: high + - name: gemini-3.1-pro-preview-customtools + type: chat + max_input_tokens: 1048576 + input_price: 2.0 + output_price: 12.0 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - name: claude-sonnet-4-6@default + type: chat + max_input_tokens: 1000000 + input_price: 3.0 + output_price: 15.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - max + - name: zai-org/glm-5-maas + type: chat + max_input_tokens: 202752 + input_price: 1.0 + output_price: 3.2 + max_output_tokens: 131072 + supports_function_calling: true + - name: claude-opus-4-6@default + type: chat + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - max + - name: zai-org/glm-4.7-maas + type: chat + max_input_tokens: 200000 + input_price: 0.6 + output_price: 2.2 + max_output_tokens: 128000 + supports_function_calling: true + - name: deepseek-ai/deepseek-v3.2-maas + type: chat + max_input_tokens: 163840 + input_price: 0.56 + output_price: 1.68 + max_output_tokens: 65536 + supports_function_calling: true + - name: gemini-3-flash-preview + type: chat + max_input_tokens: 1048576 + input_price: 0.5 + output_price: 3.0 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - minimal + - low + - medium + - high + default_reasoning_effort: high + - name: moonshotai/kimi-k2-thinking-maas + type: chat + max_input_tokens: 262144 + input_price: 0.6 + output_price: 2.5 + max_output_tokens: 262144 + supports_function_calling: true + - name: claude-opus-4-5@20251101 + type: chat + max_input_tokens: 200000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 64000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - name: claude-opus-4-5@20251101:thinking + type: chat + real_name: claude-opus-4-5@20251101 + max_input_tokens: 200000 + input_price: 5.0 + output_price: 25.0 + patch: + body: + temperature: null + top_p: null + thinking: + type: enabled + budget_tokens: 16000 + max_output_tokens: 24000 + require_max_tokens: true + supports_vision: true + - name: claude-haiku-4-5@20251001 + type: chat + max_input_tokens: 200000 + input_price: 1.0 + output_price: 5.0 + max_output_tokens: 64000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: claude-haiku-4-5@20251001:thinking + type: chat + real_name: claude-haiku-4-5@20251001 + max_input_tokens: 200000 + input_price: 1.0 + output_price: 5.0 + patch: + body: + temperature: null + top_p: null + thinking: + type: enabled + budget_tokens: 16000 + max_output_tokens: 24000 + require_max_tokens: true + supports_vision: true + - name: claude-sonnet-4-5@20250929 + type: chat + max_input_tokens: 200000 + input_price: 3.0 + output_price: 15.0 + max_output_tokens: 64000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: claude-sonnet-4-5@20250929:thinking + type: chat + real_name: claude-sonnet-4-5@20250929 + max_input_tokens: 200000 + input_price: 3.0 + output_price: 15.0 + patch: + body: + temperature: null + top_p: null + thinking: + type: enabled + budget_tokens: 16000 + max_output_tokens: 24000 + require_max_tokens: true + supports_vision: true + - name: deepseek-ai/deepseek-v3.1-maas + type: chat + max_input_tokens: 163840 + input_price: 0.6 + output_price: 1.7 + max_output_tokens: 32768 + supports_function_calling: true + - name: gemini-2.5-flash-image + type: chat + max_input_tokens: 32768 + input_price: 0.3 + output_price: 30.0 + max_output_tokens: 32768 + supports_vision: true + - name: qwen/qwen3-235b-a22b-instruct-2507-maas + type: chat + max_input_tokens: 262144 + input_price: 0.22 + output_price: 0.88 + max_output_tokens: 16384 + supports_function_calling: true + - name: claude-opus-4-1@20250805 + type: chat + max_input_tokens: 200000 + input_price: 15.0 + output_price: 75.0 + max_output_tokens: 32000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: openai/gpt-oss-120b-maas + type: chat + max_input_tokens: 131072 + input_price: 0.09 + output_price: 0.36 + max_output_tokens: 32768 + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - name: openai/gpt-oss-20b-maas + type: chat + max_input_tokens: 131072 + input_price: 0.07 + output_price: 0.25 + max_output_tokens: 32768 + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - name: gemini-2.5-flash + type: chat + max_input_tokens: 1048576 + input_price: 0.3 + output_price: 2.5 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + default_reasoning_effort: medium + - name: gemini-2.5-flash-lite + type: chat + max_input_tokens: 1048576 + input_price: 0.1 + output_price: 0.4 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: gemini-2.5-pro + type: chat + max_input_tokens: 1048576 + input_price: 1.25 + output_price: 10.0 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + default_reasoning_effort: high + - name: claude-opus-4@20250514 + type: chat + max_input_tokens: 200000 + input_price: 15.0 + output_price: 75.0 + max_output_tokens: 32000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: claude-sonnet-4@20250514 + type: chat + max_input_tokens: 200000 + input_price: 3.0 + output_price: 15.0 + max_output_tokens: 64000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: meta/llama-3.3-70b-instruct-maas + type: chat + max_input_tokens: 128000 + input_price: 0.72 + output_price: 0.72 + max_output_tokens: 8192 + supports_function_calling: true + - name: meta/llama-4-maverick-17b-128e-instruct-maas + type: chat + max_input_tokens: 524288 + input_price: 0.35 + output_price: 1.15 + max_output_tokens: 8192 + supports_vision: true + supports_function_calling: true - provider: bedrock models: - - name: us.anthropic.claude-opus-5 - max_input_tokens: 1000000 - max_output_tokens: 128000 - require_max_tokens: true - input_price: 5 - output_price: 25 - supports_function_calling: true - supports_vision: true - reasoning_levels: [low, medium, high, xhigh, max] - default_reasoning_effort: high - - name: us.anthropic.claude-fable-5-1 - max_input_tokens: 1000000 - max_output_tokens: 128000 - require_max_tokens: true - input_price: 10 - output_price: 50 - supports_function_calling: true - supports_vision: true - reasoning_levels: [low, medium, high, xhigh, max] - default_reasoning_effort: high - - name: us.anthropic.claude-fable-5 - max_input_tokens: 1000000 - max_output_tokens: 128000 - require_max_tokens: true - input_price: 10 - output_price: 50 - supports_function_calling: true - supports_vision: true - reasoning_levels: [low, medium, high, xhigh, max] - default_reasoning_effort: high - - name: us.anthropic.claude-opus-4-8 - max_input_tokens: 1000000 - max_output_tokens: 128000 - require_max_tokens: true - input_price: 5 - output_price: 25 - supports_vision: true - supports_function_calling: true - reasoning_levels: [low, medium, high, xhigh, max] - default_reasoning_effort: high - - name: us.anthropic.claude-opus-4-7 - max_input_tokens: 1000000 - max_output_tokens: 128000 - require_max_tokens: true - input_price: 5 - output_price: 25 - supports_vision: true - supports_function_calling: true - reasoning_levels: [low, medium, high, xhigh, max] - default_reasoning_effort: high - - name: us.anthropic.claude-opus-4-6-v1 - max_input_tokens: 200000 - max_output_tokens: 8192 - require_max_tokens: true - input_price: 5 - output_price: 25 - supports_vision: true - supports_function_calling: true - reasoning_levels: [low, medium, high, max] - default_reasoning_effort: high - - name: us.anthropic.claude-opus-4-6-v1:thinking - real_name: us.anthropic.claude-opus-4-6-v1 - max_input_tokens: 200000 - max_output_tokens: 24000 - require_max_tokens: true - input_price: 5 - output_price: 25 - supports_vision: true - patch: - body: - inferenceConfig: - temperature: null - topP: null - additionalModelRequestFields: - thinking: - type: enabled - budget_tokens: 16000 - - name: us.anthropic.claude-sonnet-5 - max_input_tokens: 1000000 - max_output_tokens: 128000 - require_max_tokens: true - input_price: 3 - output_price: 15 - supports_vision: true - supports_function_calling: true - reasoning_levels: [low, medium, high, xhigh, max] - default_reasoning_effort: high - - name: us.anthropic.claude-sonnet-4-6 - max_input_tokens: 200000 - max_output_tokens: 8192 - require_max_tokens: true - input_price: 3 - output_price: 15 - supports_vision: true - supports_function_calling: true - reasoning_levels: [low, medium, high, max] - default_reasoning_effort: high - - name: us.anthropic.claude-sonnet-4-6:thinking - real_name: us.anthropic.claude-sonnet-4-6 - max_input_tokens: 200000 - max_output_tokens: 24000 - require_max_tokens: true - input_price: 3 - output_price: 15 - supports_vision: true - patch: - body: - inferenceConfig: - temperature: null - topP: null - additionalModelRequestFields: - thinking: - type: enabled - budget_tokens: 16000 - - name: us.anthropic.claude-opus-4-5-20251101-v1:0 - max_input_tokens: 200000 - max_output_tokens: 8192 - require_max_tokens: true - input_price: 5 - output_price: 25 - supports_vision: true - supports_function_calling: true - - name: us.anthropic.claude-opus-4-5-20251101-v1:0:thinking - real_name: us.anthropic.claude-opus-4-5-20251101-v1:0 - max_input_tokens: 200000 - max_output_tokens: 24000 - require_max_tokens: true - input_price: 5 - output_price: 25 - supports_vision: true - patch: - body: - inferenceConfig: - temperature: null - topP: null - additionalModelRequestFields: - thinking: - type: enabled - budget_tokens: 16000 - - name: us.anthropic.claude-sonnet-4-5-20250929-v1:0 - max_input_tokens: 200000 - max_output_tokens: 8192 - require_max_tokens: true - input_price: 3 - output_price: 15 - supports_vision: true - supports_function_calling: true - - name: us.anthropic.claude-sonnet-4-5-20250929-v1:0:thinking - real_name: us.anthropic.claude-sonnet-4-5-20250929-v1:0 - max_input_tokens: 200000 - max_output_tokens: 24000 - require_max_tokens: true - input_price: 3 - output_price: 15 - supports_vision: true - patch: - body: - inferenceConfig: - temperature: null - topP: null - additionalModelRequestFields: - thinking: - type: enabled - budget_tokens: 16000 - - name: us.anthropic.claude-haiku-4-5-20251001-v1:0 - max_input_tokens: 200000 - max_output_tokens: 8192 - require_max_tokens: true - input_price: 1 - output_price: 5 - supports_vision: true - supports_function_calling: true - - name: us.anthropic.claude-haiku-4-5-20251001-v1:0:thinking - real_name: us.anthropic.claude-haiku-4-5-20251001-v1:0 - max_input_tokens: 200000 - max_output_tokens: 24000 - require_max_tokens: true - input_price: 1 - output_price: 5 - supports_vision: true - patch: - body: - inferenceConfig: - temperature: null - topP: null - additionalModelRequestFields: - thinking: - type: enabled - budget_tokens: 16000 - - name: us.meta.llama4-maverick-17b-instruct-v1:0 - max_input_tokens: 131072 - max_output_tokens: 8192 - require_max_tokens: true - input_price: 0.24 - output_price: 0.97 - supports_function_calling: true - supports_vision: true - - name: us.meta.llama4-scout-17b-instruct-v1:0 - max_input_tokens: 131072 - max_output_tokens: 8192 - require_max_tokens: true - input_price: 0.17 - output_price: 0.66 - supports_function_calling: true - supports_vision: true - - name: us.meta.llama3-3-70b-instruct-v1:0 - max_input_tokens: 131072 - max_output_tokens: 8192 - require_max_tokens: true - input_price: 0.72 - output_price: 0.72 - supports_function_calling: true - - name: us.amazon.nova-premier-v1:0 - max_input_tokens: 300000 - max_output_tokens: 5120 - input_price: 2.5 - output_price: 12.5 - - name: us.amazon.nova-pro-v1:0 - max_input_tokens: 300000 - max_output_tokens: 5120 - input_price: 0.8 - output_price: 3.2 - supports_vision: true - - name: us.amazon.nova-lite-v1:0 - max_input_tokens: 300000 - max_output_tokens: 5120 - input_price: 0.06 - output_price: 0.24 - supports_vision: true - - name: us.amazon.nova-micro-v1:0 - max_input_tokens: 128000 - max_output_tokens: 5120 - input_price: 0.035 - output_price: 0.14 - - name: cohere.embed-english-v3 - type: embedding - input_price: 0.1 - max_tokens_per_chunk: 512 - default_chunk_size: 1000 - max_batch_size: 96 - - name: cohere.embed-multilingual-v3 - type: embedding - input_price: 0.1 - max_tokens_per_chunk: 512 - default_chunk_size: 1000 - max_batch_size: 96 - - name: us.deepseek.r1-v1:0 - max_input_tokens: 128000 - input_price: 1.35 - output_price: 5.4 - -# Links: -# - https://developers.cloudflare.com/workers-ai/models/ -# - https://developers.cloudflare.com/workers-ai/configuration/open-ai-compatibility/ + - name: cohere.embed-english-v3 + type: embedding + input_price: 0.1 + max_tokens_per_chunk: 512 + default_chunk_size: 1000 + max_batch_size: 96 + - name: cohere.embed-multilingual-v3 + type: embedding + input_price: 0.1 + max_tokens_per_chunk: 512 + default_chunk_size: 1000 + max_batch_size: 96 + - name: us.meta.llama3-3-70b-instruct-v1:0 + type: chat + max_input_tokens: 131072 + input_price: 0.72 + output_price: 0.72 + max_output_tokens: 8192 + require_max_tokens: true + supports_function_calling: true + - name: us.amazon.nova-premier-v1:0 + type: chat + max_input_tokens: 300000 + input_price: 2.5 + output_price: 12.5 + max_output_tokens: 5120 + - name: us.amazon.nova-pro-v1:0 + type: chat + max_input_tokens: 300000 + input_price: 0.8 + output_price: 3.2 + max_output_tokens: 5120 + supports_vision: true + - name: us.amazon.nova-lite-v1:0 + type: chat + max_input_tokens: 300000 + input_price: 0.06 + output_price: 0.24 + max_output_tokens: 5120 + supports_vision: true + - name: us.amazon.nova-micro-v1:0 + type: chat + max_input_tokens: 128000 + input_price: 0.035 + output_price: 0.14 + max_output_tokens: 5120 + - name: anthropic.claude-fable-5-1 + type: chat + max_input_tokens: 1000000 + input_price: 10.0 + output_price: 50.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + - name: global.anthropic.claude-fable-5-1 + type: chat + max_input_tokens: 1000000 + input_price: 10.0 + output_price: 50.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + - name: us.anthropic.claude-fable-5-1 + type: chat + max_input_tokens: 1000000 + input_price: 11.0 + output_price: 55.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: high + - name: xai.grok-4.6 + type: chat + max_input_tokens: 500000 + input_price: 2.2 + output_price: 6.6 + max_output_tokens: 500000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - name: anthropic.claude-opus-5 + type: chat + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + - name: au.anthropic.claude-opus-5 + type: chat + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + - name: eu.anthropic.claude-opus-5 + type: chat + max_input_tokens: 1000000 + input_price: 5.5 + output_price: 27.5 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + - name: global.anthropic.claude-opus-5 + type: chat + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + - name: jp.anthropic.claude-opus-5 + type: chat + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + - name: us.anthropic.claude-opus-5 + type: chat + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: high + - name: global.openai.gpt-5.6-luna + type: chat + max_input_tokens: 1050000 + input_price: 0.2 + output_price: 1.2 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + - xhigh + - max + - name: global.openai.gpt-5.6-sol + type: chat + max_input_tokens: 1050000 + input_price: 4.0 + output_price: 20.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + - xhigh + - max + - name: global.openai.gpt-5.6-terra + type: chat + max_input_tokens: 1050000 + input_price: 2.0 + output_price: 12.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + - xhigh + - max + - name: openai.gpt-5.6-luna + type: chat + max_input_tokens: 1050000 + input_price: 0.22 + output_price: 1.32 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + - xhigh + - max + - name: openai.gpt-5.6-sol + type: chat + max_input_tokens: 1050000 + input_price: 4.4 + output_price: 22.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + - xhigh + - max + - name: openai.gpt-5.6-terra + type: chat + max_input_tokens: 1050000 + input_price: 2.2 + output_price: 13.2 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + - xhigh + - max + - name: anthropic.claude-sonnet-5 + type: chat + max_input_tokens: 1000000 + input_price: 2.0 + output_price: 10.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + - name: au.anthropic.claude-sonnet-5 + type: chat + max_input_tokens: 1000000 + input_price: 2.0 + output_price: 10.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + - name: eu.anthropic.claude-sonnet-5 + type: chat + max_input_tokens: 1000000 + input_price: 2.2 + output_price: 11.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + - name: global.anthropic.claude-sonnet-5 + type: chat + max_input_tokens: 1000000 + input_price: 2.0 + output_price: 10.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + - name: jp.anthropic.claude-sonnet-5 + type: chat + max_input_tokens: 1000000 + input_price: 2.0 + output_price: 10.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + - name: us.anthropic.claude-sonnet-5 + type: chat + max_input_tokens: 1000000 + input_price: 2.0 + output_price: 10.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: high + - name: anthropic.claude-fable-5 + type: chat + max_input_tokens: 1000000 + input_price: 10.0 + output_price: 50.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + - name: eu.anthropic.claude-fable-5 + type: chat + max_input_tokens: 1000000 + input_price: 11.0 + output_price: 55.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + - name: global.anthropic.claude-fable-5 + type: chat + max_input_tokens: 1000000 + input_price: 10.0 + output_price: 50.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + - name: us.anthropic.claude-fable-5 + type: chat + max_input_tokens: 1000000 + input_price: 10.0 + output_price: 50.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: high + - name: anthropic.claude-opus-4-8 + type: chat + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + - name: au.anthropic.claude-opus-4-8 + type: chat + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + - name: eu.anthropic.claude-opus-4-8 + type: chat + max_input_tokens: 1000000 + input_price: 5.5 + output_price: 27.5 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + - name: global.anthropic.claude-opus-4-8 + type: chat + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + - name: jp.anthropic.claude-opus-4-8 + type: chat + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + - name: us.anthropic.claude-opus-4-8 + type: chat + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: high + - name: openai.gpt-5.5 + type: chat + max_input_tokens: 272000 + input_price: 5.5 + output_price: 33.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + - xhigh + - name: xai.grok-4.3 + type: chat + max_input_tokens: 1000000 + input_price: 1.25 + output_price: 2.5 + max_output_tokens: 131072 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + - name: anthropic.claude-opus-4-7 + type: chat + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + - name: eu.anthropic.claude-opus-4-7 + type: chat + max_input_tokens: 1000000 + input_price: 5.5 + output_price: 27.5 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + - name: global.anthropic.claude-opus-4-7 + type: chat + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + - name: jp.anthropic.claude-opus-4-7 + type: chat + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + - name: us.anthropic.claude-opus-4-7 + type: chat + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: high + - name: minimax.minimax-m2.5 + type: chat + max_input_tokens: 196608 + input_price: 0.3 + output_price: 1.2 + max_output_tokens: 98304 + supports_function_calling: true + - name: zai.glm-5 + type: chat + max_input_tokens: 202752 + input_price: 1.0 + output_price: 3.2 + max_output_tokens: 101376 + supports_function_calling: true + - name: nvidia.nemotron-super-3-120b + type: chat + max_input_tokens: 262144 + input_price: 0.15 + output_price: 0.65 + max_output_tokens: 131072 + supports_function_calling: true + - name: openai.gpt-5.4 + type: chat + max_input_tokens: 272000 + input_price: 2.75 + output_price: 16.5 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + - xhigh + - name: anthropic.claude-sonnet-4-6 + type: chat + max_input_tokens: 1000000 + input_price: 3.0 + output_price: 15.0 + max_output_tokens: 64000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - max + - name: au.anthropic.claude-sonnet-4-6 + type: chat + max_input_tokens: 1000000 + input_price: 3.3 + output_price: 16.5 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - max + - name: eu.anthropic.claude-sonnet-4-6 + type: chat + max_input_tokens: 1000000 + input_price: 3.3 + output_price: 16.5 + max_output_tokens: 64000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - max + - name: global.anthropic.claude-sonnet-4-6 + type: chat + max_input_tokens: 1000000 + input_price: 3.0 + output_price: 15.0 + max_output_tokens: 64000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - max + - name: jp.anthropic.claude-sonnet-4-6 + type: chat + max_input_tokens: 1000000 + input_price: 3.0 + output_price: 15.0 + max_output_tokens: 64000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - max + - name: mistral.devstral-2-123b + type: chat + max_input_tokens: 256000 + input_price: 0.4 + output_price: 2.0 + max_output_tokens: 8192 + supports_function_calling: true + - name: us.anthropic.claude-sonnet-4-6 + type: chat + max_input_tokens: 1000000 + input_price: 3.0 + output_price: 15.0 + max_output_tokens: 64000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - max + default_reasoning_effort: high + - name: us.anthropic.claude-sonnet-4-6:thinking + type: chat + real_name: us.anthropic.claude-sonnet-4-6 + max_input_tokens: 1000000 + input_price: 3.0 + output_price: 15.0 + patch: + body: + inferenceConfig: + temperature: null + topP: null + additionalModelRequestFields: + thinking: + type: enabled + budget_tokens: 16000 + max_output_tokens: 24000 + require_max_tokens: true + supports_vision: true + default_reasoning_effort: high + - name: deepseek.v3.2 + type: chat + max_input_tokens: 163840 + input_price: 0.62 + output_price: 1.85 + max_output_tokens: 81920 + supports_function_calling: true + - name: moonshotai.kimi-k2.5 + type: chat + max_input_tokens: 262143 + input_price: 0.6 + output_price: 3.0 + max_output_tokens: 16000 + supports_vision: true + supports_function_calling: true + - name: qwen.qwen3-coder-next + type: chat + max_input_tokens: 131072 + input_price: 0.22 + output_price: 1.8 + max_output_tokens: 65536 + supports_function_calling: true + - name: anthropic.claude-opus-4-6-v1 + type: chat + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - max + - name: au.anthropic.claude-opus-4-6-v1 + type: chat + max_input_tokens: 1000000 + input_price: 16.5 + output_price: 82.5 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - max + - name: eu.anthropic.claude-opus-4-6-v1 + type: chat + max_input_tokens: 1000000 + input_price: 5.5 + output_price: 27.5 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - max + - name: global.anthropic.claude-opus-4-6-v1 + type: chat + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - max + - name: us.anthropic.claude-opus-4-6-v1 + type: chat + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - max + default_reasoning_effort: high + - name: us.anthropic.claude-opus-4-6-v1:thinking + type: chat + real_name: us.anthropic.claude-opus-4-6-v1 + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 25.0 + patch: + body: + inferenceConfig: + temperature: null + topP: null + additionalModelRequestFields: + thinking: + type: enabled + budget_tokens: 16000 + max_output_tokens: 24000 + require_max_tokens: true + supports_vision: true + default_reasoning_effort: high + - name: zai.glm-4.7-flash + type: chat + max_input_tokens: 200000 + input_price: 0.07 + output_price: 0.4 + max_output_tokens: 131072 + supports_function_calling: true + - name: minimax.minimax-m2.1 + type: chat + max_input_tokens: 204800 + input_price: 0.3 + output_price: 1.2 + max_output_tokens: 131072 + supports_function_calling: true + - name: nvidia.nemotron-nano-3-30b + type: chat + max_input_tokens: 128000 + input_price: 0.06 + output_price: 0.24 + max_output_tokens: 4096 + supports_function_calling: true + - name: zai.glm-4.7 + type: chat + max_input_tokens: 204800 + input_price: 0.6 + output_price: 2.2 + max_output_tokens: 131072 + supports_function_calling: true + - name: mistral.magistral-small-2509 + type: chat + max_input_tokens: 128000 + input_price: 0.5 + output_price: 1.5 + max_output_tokens: 40000 + supports_vision: true + supports_function_calling: true + - name: mistral.ministral-3-3b-instruct + type: chat + max_input_tokens: 256000 + input_price: 0.1 + output_price: 0.1 + max_output_tokens: 8192 + supports_vision: true + supports_function_calling: true + - name: mistral.mistral-large-3-675b-instruct + type: chat + max_input_tokens: 256000 + input_price: 0.5 + output_price: 1.5 + max_output_tokens: 8192 + supports_vision: true + supports_function_calling: true + - name: moonshot.kimi-k2-thinking + type: chat + max_input_tokens: 262143 + input_price: 0.6 + output_price: 2.5 + max_output_tokens: 16000 + supports_function_calling: true + - name: anthropic.claude-opus-4-5-20251101-v1:0 + type: chat + max_input_tokens: 200000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 64000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - name: eu.anthropic.claude-opus-4-5-20251101-v1:0 + type: chat + max_input_tokens: 200000 + input_price: 5.5 + output_price: 27.5 + max_output_tokens: 64000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - name: global.anthropic.claude-opus-4-5-20251101-v1:0 + type: chat + max_input_tokens: 200000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 64000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - name: us.anthropic.claude-opus-4-5-20251101-v1:0 + type: chat + max_input_tokens: 200000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 64000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - name: us.anthropic.claude-opus-4-5-20251101-v1:0:thinking + type: chat + real_name: us.anthropic.claude-opus-4-5-20251101-v1:0 + max_input_tokens: 200000 + input_price: 5.0 + output_price: 25.0 + patch: + body: + inferenceConfig: + temperature: null + topP: null + additionalModelRequestFields: + thinking: + type: enabled + budget_tokens: 16000 + max_output_tokens: 24000 + require_max_tokens: true + supports_vision: true + - name: openai.gpt-oss-safeguard-120b + type: chat + max_input_tokens: 128000 + input_price: 0.15 + output_price: 0.6 + max_output_tokens: 16384 + supports_function_calling: true + - name: openai.gpt-oss-safeguard-20b + type: chat + max_input_tokens: 128000 + input_price: 0.07 + output_price: 0.2 + max_output_tokens: 16384 + supports_function_calling: true + - name: minimax.minimax-m2 + type: chat + max_input_tokens: 204608 + input_price: 0.3 + output_price: 1.2 + max_output_tokens: 128000 + supports_function_calling: true + - name: anthropic.claude-haiku-4-5-20251001-v1:0 + type: chat + max_input_tokens: 200000 + input_price: 1.0 + output_price: 5.0 + max_output_tokens: 64000 + supports_vision: true + supports_function_calling: true + - name: au.anthropic.claude-haiku-4-5-20251001-v1:0 + type: chat + max_input_tokens: 200000 + input_price: 1.0 + output_price: 5.0 + max_output_tokens: 64000 + supports_vision: true + supports_function_calling: true + - name: eu.anthropic.claude-haiku-4-5-20251001-v1:0 + type: chat + max_input_tokens: 200000 + input_price: 1.1 + output_price: 5.5 + max_output_tokens: 64000 + supports_vision: true + supports_function_calling: true + - name: global.anthropic.claude-haiku-4-5-20251001-v1:0 + type: chat + max_input_tokens: 200000 + input_price: 1.0 + output_price: 5.0 + max_output_tokens: 64000 + supports_vision: true + supports_function_calling: true + - name: jp.anthropic.claude-haiku-4-5-20251001-v1:0 + type: chat + max_input_tokens: 200000 + input_price: 1.0 + output_price: 5.0 + max_output_tokens: 64000 + supports_vision: true + supports_function_calling: true + - name: us.anthropic.claude-haiku-4-5-20251001-v1:0 + type: chat + max_input_tokens: 200000 + input_price: 1.0 + output_price: 5.0 + max_output_tokens: 64000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: us.anthropic.claude-haiku-4-5-20251001-v1:0:thinking + type: chat + real_name: us.anthropic.claude-haiku-4-5-20251001-v1:0 + max_input_tokens: 200000 + input_price: 1.0 + output_price: 5.0 + patch: + body: + inferenceConfig: + temperature: null + topP: null + additionalModelRequestFields: + thinking: + type: enabled + budget_tokens: 16000 + max_output_tokens: 24000 + require_max_tokens: true + supports_vision: true + - name: qwen.qwen3-vl-235b-a22b + type: chat + max_input_tokens: 262000 + input_price: 0.3 + output_price: 1.5 + max_output_tokens: 262000 + supports_vision: true + supports_function_calling: true + - name: anthropic.claude-sonnet-4-5-20250929-v1:0 + type: chat + max_input_tokens: 200000 + input_price: 3.0 + output_price: 15.0 + max_output_tokens: 64000 + supports_vision: true + supports_function_calling: true + - name: au.anthropic.claude-sonnet-4-5-20250929-v1:0 + type: chat + max_input_tokens: 200000 + input_price: 3.0 + output_price: 15.0 + max_output_tokens: 64000 + supports_vision: true + supports_function_calling: true + - name: eu.anthropic.claude-sonnet-4-5-20250929-v1:0 + type: chat + max_input_tokens: 200000 + input_price: 3.3 + output_price: 16.5 + max_output_tokens: 64000 + supports_vision: true + supports_function_calling: true + - name: global.anthropic.claude-sonnet-4-5-20250929-v1:0 + type: chat + max_input_tokens: 200000 + input_price: 3.0 + output_price: 15.0 + max_output_tokens: 64000 + supports_vision: true + supports_function_calling: true + - name: jp.anthropic.claude-sonnet-4-5-20250929-v1:0 + type: chat + max_input_tokens: 200000 + input_price: 3.0 + output_price: 15.0 + max_output_tokens: 64000 + supports_vision: true + supports_function_calling: true + - name: us.anthropic.claude-sonnet-4-5-20250929-v1:0 + type: chat + max_input_tokens: 200000 + input_price: 3.0 + output_price: 15.0 + max_output_tokens: 64000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: us.anthropic.claude-sonnet-4-5-20250929-v1:0:thinking + type: chat + real_name: us.anthropic.claude-sonnet-4-5-20250929-v1:0 + max_input_tokens: 200000 + input_price: 3.0 + output_price: 15.0 + patch: + body: + inferenceConfig: + temperature: null + topP: null + additionalModelRequestFields: + thinking: + type: enabled + budget_tokens: 16000 + max_output_tokens: 24000 + require_max_tokens: true + supports_vision: true + - name: deepseek.v3-v1:0 + type: chat + max_input_tokens: 163840 + input_price: 0.58 + output_price: 1.68 + max_output_tokens: 81920 + supports_function_calling: true + - name: qwen.qwen3-235b-a22b-2507-v1:0 + type: chat + max_input_tokens: 262144 + input_price: 0.22 + output_price: 0.88 + max_output_tokens: 131072 + supports_function_calling: true + - name: qwen.qwen3-32b-v1:0 + type: chat + max_input_tokens: 16384 + input_price: 0.15 + output_price: 0.6 + max_output_tokens: 16384 + supports_function_calling: true + - name: qwen.qwen3-coder-30b-a3b-v1:0 + type: chat + max_input_tokens: 262144 + input_price: 0.15 + output_price: 0.6 + max_output_tokens: 131072 + supports_function_calling: true + - name: qwen.qwen3-coder-480b-a35b-v1:0 + type: chat + max_input_tokens: 131072 + input_price: 0.22 + output_price: 1.8 + max_output_tokens: 65536 + supports_function_calling: true + - name: qwen.qwen3-next-80b-a3b + type: chat + max_input_tokens: 262000 + input_price: 0.14 + output_price: 1.4 + max_output_tokens: 262000 + supports_function_calling: true + - name: anthropic.claude-opus-4-1-20250805-v1:0 + type: chat + max_input_tokens: 200000 + input_price: 15.0 + output_price: 75.0 + max_output_tokens: 32000 + supports_vision: true + supports_function_calling: true + - name: openai.gpt-oss-120b + type: chat + max_input_tokens: 128000 + input_price: 0.15 + output_price: 0.6 + max_output_tokens: 16384 + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - name: openai.gpt-oss-120b-1:0 + type: chat + max_input_tokens: 128000 + input_price: 0.15 + output_price: 0.6 + max_output_tokens: 16384 + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - name: openai.gpt-oss-20b + type: chat + max_input_tokens: 128000 + input_price: 0.07 + output_price: 0.3 + max_output_tokens: 16384 + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - name: openai.gpt-oss-20b-1:0 + type: chat + max_input_tokens: 128000 + input_price: 0.07 + output_price: 0.3 + max_output_tokens: 16384 + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - name: us.anthropic.claude-opus-4-1-20250805-v1:0 + type: chat + max_input_tokens: 200000 + input_price: 15.0 + output_price: 75.0 + max_output_tokens: 32000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: google.gemma-3-27b-it + type: chat + max_input_tokens: 202752 + input_price: 0.12 + output_price: 0.2 + max_output_tokens: 8192 + supports_vision: true + supports_function_calling: true + - name: mistral.voxtral-small-24b-2507 + type: chat + max_input_tokens: 32000 + input_price: 0.15 + output_price: 0.35 + max_output_tokens: 8192 + supports_function_calling: true + - name: writer.palmyra-x4-v1:0 + type: chat + max_input_tokens: 122880 + input_price: 2.5 + output_price: 10.0 + max_output_tokens: 8192 + supports_function_calling: true + - name: writer.palmyra-x5-v1:0 + type: chat + max_input_tokens: 1040000 + input_price: 0.6 + output_price: 6.0 + max_output_tokens: 8192 + supports_function_calling: true + - name: mistral.pixtral-large-2502-v1:0 + type: chat + max_input_tokens: 128000 + input_price: 2.0 + output_price: 6.0 + max_output_tokens: 8192 + supports_vision: true + supports_function_calling: true + - name: meta.llama4-maverick-17b-instruct-v1:0 + type: chat + max_input_tokens: 1000000 + input_price: 0.24 + output_price: 0.97 + max_output_tokens: 16384 + supports_vision: true + supports_function_calling: true + - name: meta.llama4-scout-17b-instruct-v1:0 + type: chat + max_input_tokens: 3500000 + input_price: 0.17 + output_price: 0.66 + max_output_tokens: 16384 + supports_vision: true + supports_function_calling: true + - name: us.meta.llama4-maverick-17b-instruct-v1:0 + type: chat + max_input_tokens: 1000000 + input_price: 0.24 + output_price: 0.97 + max_output_tokens: 16384 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: us.meta.llama4-scout-17b-instruct-v1:0 + type: chat + max_input_tokens: 3500000 + input_price: 0.17 + output_price: 0.66 + max_output_tokens: 16384 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: deepseek.r1-v1:0 + type: chat + max_input_tokens: 128000 + input_price: 1.35 + output_price: 5.4 + max_output_tokens: 32768 + supports_function_calling: true + - name: us.deepseek.r1-v1:0 + type: chat + max_input_tokens: 128000 + input_price: 1.35 + output_price: 5.4 + max_output_tokens: 32768 + supports_function_calling: true + - name: meta.llama3-3-70b-instruct-v1:0 + type: chat + max_input_tokens: 128000 + input_price: 0.72 + output_price: 0.72 + max_output_tokens: 4096 + supports_function_calling: true + - name: amazon.nova-lite-v1:0 + type: chat + max_input_tokens: 300000 + input_price: 0.06 + output_price: 0.24 + max_output_tokens: 8192 + supports_vision: true + supports_function_calling: true + - name: amazon.nova-micro-v1:0 + type: chat + max_input_tokens: 128000 + input_price: 0.035 + output_price: 0.14 + max_output_tokens: 8192 + supports_function_calling: true + - name: amazon.nova-pro-v1:0 + type: chat + max_input_tokens: 300000 + input_price: 0.8 + output_price: 3.2 + max_output_tokens: 8192 + supports_vision: true + supports_function_calling: true + - name: amazon.nova-2-lite-v1:0 + type: chat + max_input_tokens: 128000 + input_price: 0.33 + output_price: 2.75 + max_output_tokens: 4096 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - name: google.gemma-3-12b-it + type: chat + max_input_tokens: 131072 + input_price: 0.05 + output_price: 0.1 + max_output_tokens: 8192 + supports_vision: true + - name: google.gemma-3-4b-it + type: chat + max_input_tokens: 128000 + input_price: 0.04 + output_price: 0.08 + max_output_tokens: 4096 + supports_vision: true + supports_function_calling: true + - name: mistral.ministral-3-14b-instruct + type: chat + max_input_tokens: 128000 + input_price: 0.2 + output_price: 0.2 + max_output_tokens: 4096 + supports_function_calling: true + - name: mistral.ministral-3-8b-instruct + type: chat + max_input_tokens: 128000 + input_price: 0.15 + output_price: 0.15 + max_output_tokens: 4096 + supports_function_calling: true + - name: mistral.voxtral-mini-3b-2507 + type: chat + max_input_tokens: 128000 + input_price: 0.04 + output_price: 0.04 + max_output_tokens: 4096 + supports_function_calling: true + - name: nvidia.nemotron-nano-12b-v2 + type: chat + max_input_tokens: 128000 + input_price: 0.2 + output_price: 0.6 + max_output_tokens: 4096 + supports_vision: true + supports_function_calling: true + - name: nvidia.nemotron-nano-9b-v2 + type: chat + max_input_tokens: 128000 + input_price: 0.06 + output_price: 0.23 + max_output_tokens: 4096 + supports_function_calling: true + - name: meta.llama3-1-70b-instruct-v1:0 + type: chat + max_input_tokens: 128000 + input_price: 0.72 + output_price: 0.72 + max_output_tokens: 4096 + supports_function_calling: true + - name: meta.llama3-1-8b-instruct-v1:0 + type: chat + max_input_tokens: 128000 + input_price: 0.22 + output_price: 0.22 + max_output_tokens: 4096 + supports_function_calling: true - provider: cloudflare models: - - name: '@cf/meta/llama-4-scout-17b-16e-instruct' - max_input_tokens: 131072 - max_output_tokens: 2048 - require_max_tokens: true - input_price: 0 - output_price: 0 - - name: '@cf/meta/llama-3.3-70b-instruct-fp8-fast' - max_input_tokens: 131072 - max_output_tokens: 2048 - require_max_tokens: true - input_price: 0 - output_price: 0 - - name: '@cf/qwen/qwen3-30b-a3b-fp8' - max_input_tokens: 131072 - max_output_tokens: 2048 - require_max_tokens: true - input_price: 0 - output_price: 0 - - name: '@cf/qwen/qwen2.5-coder-32b-instruct' - max_input_tokens: 131072 - max_output_tokens: 2048 - require_max_tokens: true - input_price: 0 - output_price: 0 - - name: '@cf/zai-org/glm-4.7-flash' - max_input_tokens: 131072 - max_output_tokens: 2048 - require_max_tokens: true - input_price: 0 - output_price: 0 - - name: '@cf/google/gemma-3-12b-it' - max_input_tokens: 131072 - max_output_tokens: 2048 - require_max_tokens: true - input_price: 0 - output_price: 0 - - name: '@cf/mistralai/mistral-small-3.1-24b-instruct' - max_input_tokens: 131072 - max_output_tokens: 2048 - require_max_tokens: true - input_price: 0 - output_price: 0 - - name: '@cf/baai/bge-large-en-v1.5' - type: embedding - input_price: 0 - max_tokens_per_chunk: 512 - default_chunk_size: 1000 - max_batch_size: 100 - -# Links: -# - https://cloud.baidu.com/doc/qianfan/s/rmh4stp0j -# - https://cloud.baidu.com/doc/qianfan/s/wmh4sv6ya + - name: '@cf/baai/bge-large-en-v1.5' + type: embedding + input_price: 0.0 + max_tokens_per_chunk: 512 + default_chunk_size: 1000 + max_batch_size: 100 + - name: '@cf/google/gemma-3-12b-it' + type: chat + max_input_tokens: 131072 + input_price: 0.0 + output_price: 0.0 + max_output_tokens: 2048 + require_max_tokens: true + - name: '@cf/zai-org/glm-5.3-flash' + type: chat + max_input_tokens: 1310720 + input_price: 0.15 + output_price: 0.5 + max_output_tokens: 1048576 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: '@cf/qwen/qwen3.8-27b' + type: chat + max_input_tokens: 262144 + input_price: 0.45 + output_price: 3.2 + max_output_tokens: 262144 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - xhigh + - name: '@cf/zai-org/glm-5.3' + type: chat + max_input_tokens: 1310720 + input_price: 1.4 + output_price: 4.4 + max_output_tokens: 1310720 + require_max_tokens: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - name: '@cf/deepseek-ai/deepseek-v4-pro-0813' + type: chat + max_input_tokens: 1048576 + input_price: 1.32 + output_price: 3.96 + max_output_tokens: 1048576 + require_max_tokens: true + supports_function_calling: true + reasoning_levels: + - high + - max + - name: '@cf/deepseek-ai/deepseek-v4-flash-0731' + type: chat + max_input_tokens: 1310720 + input_price: 0.44 + output_price: 1.32 + max_output_tokens: 1048576 + require_max_tokens: true + supports_function_calling: true + reasoning_levels: + - high + - max + - name: '@cf/zai-org/glm-5.2' + type: chat + max_input_tokens: 262144 + input_price: 1.4 + output_price: 4.4 + max_output_tokens: 256000 + require_max_tokens: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - name: '@cf/moonshotai/kimi-k2.7-code' + type: chat + max_input_tokens: 262144 + input_price: 0.95 + output_price: 4.0 + max_output_tokens: 262144 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - name: '@cf/moonshotai/kimi-k2.6' + type: chat + max_input_tokens: 262144 + input_price: 0.95 + output_price: 4.0 + max_output_tokens: 256000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - name: '@cf/google/gemma-4-26b-a4b-it' + type: chat + max_input_tokens: 256000 + input_price: 0.1 + output_price: 0.3 + max_output_tokens: 16384 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - name: '@cf/nvidia/nemotron-3-120b-a12b' + type: chat + max_input_tokens: 256000 + input_price: 0.5 + output_price: 1.5 + max_output_tokens: 256000 + require_max_tokens: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - name: '@cf/zai-org/glm-4.7-flash' + type: chat + max_input_tokens: 131072 + input_price: 0.0605 + output_price: 0.4 + max_output_tokens: 131072 + require_max_tokens: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - name: '@cf/ibm-granite/granite-4.0-h-micro' + type: chat + max_input_tokens: 131000 + input_price: 0.017 + output_price: 0.112 + max_output_tokens: 131000 + require_max_tokens: true + supports_function_calling: true + - name: '@cf/aisingapore/gemma-sea-lion-v4-27b-it' + type: chat + max_input_tokens: 128000 + input_price: 0.351 + output_price: 0.555 + max_output_tokens: 128000 + require_max_tokens: true + - name: '@cf/openai/gpt-oss-120b' + type: chat + max_input_tokens: 128000 + input_price: 0.35 + output_price: 0.75 + max_output_tokens: 16384 + require_max_tokens: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - name: '@cf/openai/gpt-oss-20b' + type: chat + max_input_tokens: 128000 + input_price: 0.2 + output_price: 0.3 + max_output_tokens: 16384 + require_max_tokens: true + supports_function_calling: true + - name: '@cf/qwen/qwen3-30b-a3b-fp8' + type: chat + max_input_tokens: 32768 + input_price: 0.0509 + output_price: 0.335 + max_output_tokens: 32768 + require_max_tokens: true + supports_function_calling: true + - name: '@cf/meta/llama-4-scout-17b-16e-instruct' + type: chat + max_input_tokens: 131000 + input_price: 0.27 + output_price: 0.85 + max_output_tokens: 16384 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: '@cf/mistralai/mistral-small-3.1-24b-instruct' + type: chat + max_input_tokens: 128000 + input_price: 0.351 + output_price: 0.555 + max_output_tokens: 128000 + require_max_tokens: true + supports_function_calling: true + - name: '@cf/qwen/qwq-32b' + type: chat + max_input_tokens: 24000 + input_price: 0.66 + output_price: 1.0 + max_output_tokens: 24000 + require_max_tokens: true + - name: '@cf/deepseek-ai/deepseek-r1-distill-qwen-32b' + type: chat + max_input_tokens: 80000 + input_price: 0.497 + output_price: 4.881 + max_output_tokens: 80000 + require_max_tokens: true + - name: '@cf/meta/llama-3.3-70b-instruct-fp8-fast' + type: chat + max_input_tokens: 24000 + input_price: 0.293 + output_price: 2.253 + max_output_tokens: 24000 + require_max_tokens: true + supports_function_calling: true + - name: '@cf/qwen/qwen2.5-coder-32b-instruct' + type: chat + max_input_tokens: 32768 + input_price: 0.66 + output_price: 1.0 + max_output_tokens: 32768 + require_max_tokens: true + - name: '@cf/meta/llama-3.2-11b-vision-instruct' + type: chat + max_input_tokens: 128000 + input_price: 0.0485 + output_price: 0.676 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + - name: '@cf/meta/llama-3.2-1b-instruct' + type: chat + max_input_tokens: 60000 + input_price: 0.027 + output_price: 0.201 + max_output_tokens: 60000 + require_max_tokens: true + - name: '@cf/meta/llama-3.2-3b-instruct' + type: chat + max_input_tokens: 80000 + input_price: 0.0509 + output_price: 0.335 + max_output_tokens: 80000 + require_max_tokens: true + - name: '@cf/meta/llama-3.1-8b-instruct-fp8' + type: chat + max_input_tokens: 32000 + input_price: 0.152 + output_price: 0.287 + max_output_tokens: 32000 + require_max_tokens: true + - name: '@cf/meta/llama-guard-3-8b' + type: chat + max_input_tokens: 131072 + input_price: 0.484 + output_price: 0.03 + max_output_tokens: 131072 + require_max_tokens: true - provider: ernie models: - - name: ernie-4.5-turbo-128k - max_input_tokens: 131072 - input_price: 0.112 - output_price: 0.448 - - name: ernie-4.5-turbo-vl-32k - max_input_tokens: 32768 - input_price: 0.42 - output_price: 1.26 - supports_vision: true - - name: ernie-5.0-thinking-preview - max_input_tokens: 131072 - input_price: 1.4 - output_price: 5.6 - - name: ernie-x1.1-preview - max_input_tokens: 65536 - input_price: 0.14 - output_price: 0.56 - - name: bge-large-zh - type: embedding - input_price: 0.07 - max_tokens_per_chunk: 512 - default_chunk_size: 1000 - max_batch_size: 16 - - name: bge-large-en - type: embedding - input_price: 0.07 - max_tokens_per_chunk: 512 - default_chunk_size: 1000 - max_batch_size: 16 - - name: bce-reranker-base - type: reranker - max_input_tokens: 1024 - input_price: 0.07 - -# Links: -# - https://help.aliyun.com/zh/model-studio/getting-started/models -# - https://help.aliyun.com/zh/model-studio/developer-reference/use-qwen-by-calling-api + - name: ernie-4.5-turbo-128k + type: chat + max_input_tokens: 131072 + input_price: 0.112 + output_price: 0.448 + - name: ernie-4.5-turbo-vl-32k + type: chat + max_input_tokens: 32768 + input_price: 0.42 + output_price: 1.26 + supports_vision: true + - name: ernie-5.0-thinking-preview + type: chat + max_input_tokens: 131072 + input_price: 1.4 + output_price: 5.6 + - name: ernie-x1.1-preview + type: chat + max_input_tokens: 65536 + input_price: 0.14 + output_price: 0.56 + - name: bge-large-zh + type: embedding + input_price: 0.07 + max_tokens_per_chunk: 512 + default_chunk_size: 1000 + max_batch_size: 16 + - name: bge-large-en + type: embedding + input_price: 0.07 + max_tokens_per_chunk: 512 + default_chunk_size: 1000 + max_batch_size: 16 + - name: bce-reranker-base + type: reranker + max_input_tokens: 1024 + input_price: 0.07 - provider: qianwen models: - - name: qwen3.5-plus - max_input_tokens: 262144 - supports_function_calling: true - patch: - body: - enable_thinking: false - - name: qwen3.5-plus:thinking - real_name: qwen3.5-plus - max_input_tokens: 262144 - supports_function_calling: true - - name: qwen3-max - max_input_tokens: 262144 - supports_function_calling: true - - name: qwen3-max:thinking - real_name: qwen3-max - max_input_tokens: 262144 - supports_function_calling: true - patch: - body: - enable_thinking: true - - name: qwen3-vl-plus - max_input_tokens: 262144 - supports_vision: true - - name: qwen3-vl-flash - max_input_tokens: 262144 - supports_vision: true - - name: qwen3-coder-plus - max_input_tokens: 1000000 - - name: qwen3-coder-flash - max_input_tokens: 1000000 - - name: qwen3.5-397b-a17b - max_input_tokens: 262144 - supports_function_calling: true - patch: - body: - enable_thinking: false - - name: qwen3.5-397b-a17b:thinking - real_name: qwen3.5-397b-a17b - max_input_tokens: 262144 - supports_function_calling: true - - name: qwen3-next-80b-a3b-instruct - max_input_tokens: 131072 - input_price: 0.14 - output_price: 0.56 - supports_function_calling: true - - name: qwen3-next-80b-a3b-thinking - max_input_tokens: 131072 - input_price: 0.14 - output_price: 1.4 - - name: qwen3-235b-a22b-instruct-2507 - max_input_tokens: 131072 - input_price: 0.28 - output_price: 1.12 - supports_function_calling: true - - name: qwen3-235b-a22b-thinking-2507 - max_input_tokens: 131072 - input_price: 0.28 - output_price: 2.8 - - name: qwen3-30b-a3b-instruct-2507 - max_input_tokens: 131072 - input_price: 0.105 - output_price: 0.42 - supports_function_calling: true - - name: qwen3-30b-a3b-thinking-2507 - max_input_tokens: 131072 - input_price: 0.105 - output_price: 1.05 - - name: qwen3-vl-32b-instruct - max_input_tokens: 131072 - input_price: 0.28 - output_price: 1.12 - supports_vision: true - - name: qwen3-vl-8b-instruct - max_input_tokens: 131072 - input_price: 0.07 - output_price: 0.28 - supports_vision: true - - name: qwen3-coder-next - max_input_tokens: 262144 - - name: qwen3-coder-480b-a35b-instruct - max_input_tokens: 262144 - - name: qwen3-coder-30b-a3b-instruct - max_input_tokens: 262144 - - name: text-embedding-v4 - type: embedding - input_price: 0.1 - max_tokens_per_chunk: 8192 - default_chunk_size: 2000 - max_batch_size: 10 - - name: text-embedding-v3 - type: embedding - input_price: 0.1 - max_tokens_per_chunk: 8192 - default_chunk_size: 2000 - max_batch_size: 10 - -# links: -# - https://cloud.tencent.com/document/product/1729/104753 -# - https://cloud.tencent.com/document/product/1729/97731 -# - https://cloud.tencent.com/document/product/1729/111007 + - name: qwen3.5-plus:thinking + type: chat + real_name: qwen3.5-plus + max_input_tokens: 262144 + supports_function_calling: true + - name: qwen3.5-397b-a17b:thinking + type: chat + real_name: qwen3.5-397b-a17b + max_input_tokens: 262144 + supports_function_calling: true + - name: text-embedding-v4 + type: embedding + input_price: 0.1 + max_tokens_per_chunk: 8192 + default_chunk_size: 2000 + max_batch_size: 10 + - name: text-embedding-v3 + type: embedding + input_price: 0.1 + max_tokens_per_chunk: 8192 + default_chunk_size: 2000 + max_batch_size: 10 + - name: qwen3-vl-flash + type: chat + max_input_tokens: 262144 + supports_vision: true + - name: qwen3-235b-a22b-instruct-2507 + type: chat + max_input_tokens: 131072 + input_price: 0.28 + output_price: 1.12 + supports_function_calling: true + - name: qwen3-235b-a22b-thinking-2507 + type: chat + max_input_tokens: 131072 + input_price: 0.28 + output_price: 2.8 + - name: qwen3-30b-a3b-instruct-2507 + type: chat + max_input_tokens: 131072 + input_price: 0.105 + output_price: 0.42 + supports_function_calling: true + - name: qwen3-30b-a3b-thinking-2507 + type: chat + max_input_tokens: 131072 + input_price: 0.105 + output_price: 1.05 + - name: qwen3-vl-32b-instruct + type: chat + max_input_tokens: 131072 + input_price: 0.28 + output_price: 1.12 + supports_vision: true + - name: qwen3-vl-8b-instruct + type: chat + max_input_tokens: 131072 + input_price: 0.07 + output_price: 0.28 + supports_vision: true + - name: qwen3-coder-next + type: chat + max_input_tokens: 262144 + - name: qwen3.8-flash + type: chat + max_input_tokens: 1000000 + input_price: 0.15 + output_price: 0.47 + max_output_tokens: 131072 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - xhigh + - name: qwen3.8-max + type: chat + max_input_tokens: 1000000 + input_price: 2.0 + output_price: 6.0 + max_output_tokens: 131072 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - xhigh + - name: deepseek-v4-flash-0731 + type: chat + max_input_tokens: 1000000 + input_price: 0.2 + output_price: 0.4 + max_output_tokens: 384000 + supports_function_calling: true + reasoning_levels: + - high + - max + - name: glm-5.2 + type: chat + max_input_tokens: 1000000 + input_price: 1.4 + output_price: 4.4 + max_output_tokens: 131072 + supports_function_calling: true + reasoning_levels: + - none + - minimal + - low + - medium + - high + - xhigh + - max + - name: qwen3.7-plus + type: chat + max_input_tokens: 1000000 + input_price: 0.5 + output_price: 3.0 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: qwen3.7-max + type: chat + max_input_tokens: 1000000 + input_price: 2.5 + output_price: 7.5 + max_output_tokens: 65536 + supports_function_calling: true + - name: qwen3.6-flash + type: chat + max_input_tokens: 1000000 + input_price: 0.1875 + output_price: 1.125 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: qwen3.6-27b + type: chat + max_input_tokens: 262144 + input_price: 0.6 + output_price: 3.6 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: qwen3.6-max-preview + type: chat + max_input_tokens: 262144 + input_price: 1.3 + output_price: 7.8 + max_output_tokens: 65536 + supports_function_calling: true + - name: qwen3.6-35b-a3b + type: chat + max_input_tokens: 262144 + input_price: 0.248 + output_price: 1.485 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: qwen3.6-plus + type: chat + max_input_tokens: 1000000 + input_price: 0.5 + output_price: 3.0 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: qwen3.5-122b-a10b + type: chat + max_input_tokens: 262144 + input_price: 0.4 + output_price: 3.2 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: qwen3.5-27b + type: chat + max_input_tokens: 262144 + input_price: 0.3 + output_price: 2.4 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: qwen3.5-35b-a3b + type: chat + max_input_tokens: 262144 + input_price: 0.25 + output_price: 2.0 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: qwen3.5-plus + type: chat + max_input_tokens: 1000000 + input_price: 0.4 + output_price: 2.4 + patch: + body: + enable_thinking: false + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: qwen3.5-397b-a17b + type: chat + max_input_tokens: 262144 + input_price: 0.6 + output_price: 3.6 + patch: + body: + enable_thinking: false + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: qwen3-max + type: chat + max_input_tokens: 262144 + input_price: 1.2 + output_price: 6.0 + max_output_tokens: 65536 + supports_function_calling: true + - name: qwen3-max:thinking + type: chat + real_name: qwen3-max + max_input_tokens: 262144 + input_price: 1.2 + output_price: 6.0 + patch: + body: + enable_thinking: true + max_output_tokens: 65536 + supports_function_calling: true + - name: qwen3-vl-plus + type: chat + max_input_tokens: 262144 + input_price: 0.2 + output_price: 1.6 + max_output_tokens: 32768 + supports_vision: true + supports_function_calling: true + - name: qwen3-omni-flash + type: chat + max_input_tokens: 65536 + input_price: 0.43 + output_price: 1.66 + max_output_tokens: 16384 + supports_vision: true + supports_function_calling: true + - name: qwen3-asr-flash + type: chat + max_input_tokens: 53248 + input_price: 0.035 + output_price: 0.035 + max_output_tokens: 4096 + - name: qwen3-next-80b-a3b-instruct + type: chat + max_input_tokens: 131072 + input_price: 0.5 + output_price: 2.0 + max_output_tokens: 32768 + supports_function_calling: true + - name: qwen3-next-80b-a3b-thinking + type: chat + max_input_tokens: 131072 + input_price: 0.5 + output_price: 6.0 + max_output_tokens: 32768 + supports_function_calling: true + - name: qwen-flash + type: chat + max_input_tokens: 1000000 + input_price: 0.05 + output_price: 0.4 + max_output_tokens: 32768 + supports_function_calling: true + - name: qwen3-coder-flash + type: chat + max_input_tokens: 1000000 + input_price: 0.3 + output_price: 1.5 + max_output_tokens: 65536 + supports_function_calling: true + - name: qwen3-coder-plus + type: chat + max_input_tokens: 1048576 + input_price: 1.0 + output_price: 5.0 + max_output_tokens: 65536 + supports_function_calling: true + - name: qwen3-14b + type: chat + max_input_tokens: 131072 + input_price: 0.35 + output_price: 1.4 + max_output_tokens: 8192 + supports_function_calling: true + - name: qwen3-235b-a22b + type: chat + max_input_tokens: 131072 + input_price: 0.7 + output_price: 2.8 + max_output_tokens: 16384 + supports_function_calling: true + - name: qwen3-32b + type: chat + max_input_tokens: 131072 + input_price: 0.7 + output_price: 2.8 + max_output_tokens: 16384 + supports_function_calling: true + - name: qwen3-8b + type: chat + max_input_tokens: 131072 + input_price: 0.18 + output_price: 0.7 + max_output_tokens: 8192 + supports_function_calling: true + - name: qwen3-coder-30b-a3b-instruct + type: chat + max_input_tokens: 262144 + input_price: 0.45 + output_price: 2.25 + max_output_tokens: 65536 + supports_function_calling: true + - name: qwen3-coder-480b-a35b-instruct + type: chat + max_input_tokens: 262144 + input_price: 1.5 + output_price: 7.5 + max_output_tokens: 65536 + supports_function_calling: true + - name: qwen3-vl-235b-a22b + type: chat + max_input_tokens: 131072 + input_price: 0.7 + output_price: 2.8 + max_output_tokens: 32768 + supports_vision: true + supports_function_calling: true + - name: qwen3-vl-30b-a3b + type: chat + max_input_tokens: 131072 + input_price: 0.2 + output_price: 0.8 + max_output_tokens: 32768 + supports_vision: true + supports_function_calling: true + - name: qvq-max + type: chat + max_input_tokens: 131072 + input_price: 1.2 + output_price: 4.8 + max_output_tokens: 8192 + supports_vision: true + supports_function_calling: true + - name: qwq-plus + type: chat + max_input_tokens: 131072 + input_price: 0.8 + output_price: 2.4 + max_output_tokens: 8192 + supports_function_calling: true + - name: qwen-omni-turbo + type: chat + max_input_tokens: 32768 + input_price: 0.07 + output_price: 0.27 + max_output_tokens: 2048 + supports_vision: true + supports_function_calling: true + - name: qwen-mt-plus + type: chat + max_input_tokens: 16384 + input_price: 2.46 + output_price: 7.37 + max_output_tokens: 8192 + - name: qwen-mt-turbo + type: chat + max_input_tokens: 16384 + input_price: 0.16 + output_price: 0.49 + max_output_tokens: 8192 + - name: qwen2-5-omni-7b + type: chat + max_input_tokens: 32768 + input_price: 0.1 + output_price: 0.4 + max_output_tokens: 2048 + supports_vision: true + supports_function_calling: true + - name: qwen-turbo + type: chat + max_input_tokens: 1000000 + input_price: 0.05 + output_price: 0.2 + max_output_tokens: 16384 + supports_function_calling: true + - name: qwen-vl-ocr + type: chat + max_input_tokens: 34096 + input_price: 0.72 + output_price: 0.72 + max_output_tokens: 4096 + supports_vision: true + - name: qwen2-5-14b-instruct + type: chat + max_input_tokens: 131072 + input_price: 0.35 + output_price: 1.4 + max_output_tokens: 8192 + supports_function_calling: true + - name: qwen2-5-32b-instruct + type: chat + max_input_tokens: 131072 + input_price: 0.7 + output_price: 2.8 + max_output_tokens: 8192 + supports_function_calling: true + - name: qwen2-5-72b-instruct + type: chat + max_input_tokens: 131072 + input_price: 1.4 + output_price: 5.6 + max_output_tokens: 8192 + supports_function_calling: true + - name: qwen2-5-7b-instruct + type: chat + max_input_tokens: 131072 + input_price: 0.175 + output_price: 0.7 + max_output_tokens: 8192 + supports_function_calling: true + - name: qwen2-5-vl-72b-instruct + type: chat + max_input_tokens: 131072 + input_price: 2.8 + output_price: 8.4 + max_output_tokens: 8192 + supports_vision: true + supports_function_calling: true + - name: qwen2-5-vl-7b-instruct + type: chat + max_input_tokens: 131072 + input_price: 0.35 + output_price: 1.05 + max_output_tokens: 8192 + supports_vision: true + supports_function_calling: true + - name: qwen-vl-max + type: chat + max_input_tokens: 131072 + input_price: 0.8 + output_price: 3.2 + max_output_tokens: 8192 + supports_vision: true + supports_function_calling: true + - name: qwen-max + type: chat + max_input_tokens: 32768 + input_price: 1.6 + output_price: 6.4 + max_output_tokens: 8192 + supports_function_calling: true + - name: qwen-plus + type: chat + max_input_tokens: 1000000 + input_price: 0.4 + output_price: 1.2 + max_output_tokens: 32768 + supports_function_calling: true + - name: qwen-vl-plus + type: chat + max_input_tokens: 131072 + input_price: 0.21 + output_price: 0.63 + max_output_tokens: 8192 + supports_vision: true + supports_function_calling: true + - name: qwen-plus-character-ja + type: chat + max_input_tokens: 8192 + input_price: 0.5 + output_price: 1.4 + max_output_tokens: 512 + supports_function_calling: true - provider: hunyuan models: - - name: hunyuan-2.0-instruct-20251111 - max_input_tokens: 131072 - input_price: 0.112 - output_price: 0.28 - supports_function_calling: true - - name: hunyuan-2.0-thinking-20251109 - max_input_tokens: 131072 - input_price: 0.14 - output_price: 0.56 - supports_function_calling: true - - name: hunyuan-vision-1.5-instruct - max_input_tokens: 24576 - input_price: 0.42 - output_price: 1.26 - supports_vision: true - - name: hunyuan-embedding - type: embedding - input_price: 0.01 - max_tokens_per_chunk: 1024 - default_chunk_size: 1000 - max_batch_size: 100 - -# Links: -# - https://platform.moonshot.cn/docs/pricing/chat#%E8%AE%A1%E8%B4%B9%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5 -# - https://platform.moonshot.cn/docs/api/chat#%E5%85%AC%E5%BC%80%E7%9A%84%E6%9C%8D%E5%8A%A1%E5%9C%B0%E5%9D%80 + - name: hunyuan-2.0-instruct-20251111 + type: chat + max_input_tokens: 131072 + input_price: 0.112 + output_price: 0.28 + supports_function_calling: true + - name: hunyuan-2.0-thinking-20251109 + type: chat + max_input_tokens: 131072 + input_price: 0.14 + output_price: 0.56 + supports_function_calling: true + - name: hunyuan-vision-1.5-instruct + type: chat + max_input_tokens: 24576 + input_price: 0.42 + output_price: 1.26 + supports_vision: true + - name: hunyuan-embedding + type: embedding + input_price: 0.01 + max_tokens_per_chunk: 1024 + default_chunk_size: 1000 + max_batch_size: 100 - provider: moonshot models: - - name: kimi-k3 - max_input_tokens: 1048576 - input_price: 3 - output_price: 15 - supports_vision: true - supports_function_calling: true - - name: kimi-k2.7-code - max_input_tokens: 262144 - input_price: 0.95 - output_price: 4 - supports_vision: true - supports_function_calling: true - - name: kimi-k2.7-code-highspeed - max_input_tokens: 262144 - input_price: 1.9 - output_price: 8 - supports_vision: true - supports_function_calling: true - - name: kimi-k2.6 - max_input_tokens: 262144 - input_price: 0.95 - output_price: 4 - supports_vision: true - supports_function_calling: true - - name: kimi-k2.5 - max_input_tokens: 262144 - input_price: 0.56 - output_price: 2.94 - supports_vision: true - supports_function_calling: true - - name: kimi-k2-turbo-preview - max_input_tokens: 262144 - input_price: 1.12 - output_price: 8.12 - supports_vision: true - supports_function_calling: true - - name: kimi-k2-0905-preview - max_input_tokens: 262144 - input_price: 0.56 - output_price: 2.24 - supports_vision: true - supports_function_calling: true - - name: kimi-k2-thinking-turbo - max_input_tokens: 262144 - input_price: 1.12 - output_price: 8.12 - supports_vision: true - - name: kimi-k2-thinking - max_input_tokens: 262144 - input_price: 0.56 - output_price: 2.24 - supports_vision: true - -# Links: -# - https://api-docs.deepseek.com/quick_start/pricing -# - https://platform.deepseek.com/api-docs/api/create-chat-completion + - name: kimi-k3 + type: chat + max_input_tokens: 1048576 + input_price: 3.0 + output_price: 15.0 + max_output_tokens: 131072 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - high + - max + - name: kimi-k2.7-code + type: chat + max_input_tokens: 262144 + input_price: 0.95 + output_price: 4.0 + max_output_tokens: 262144 + supports_vision: true + supports_function_calling: true + - name: kimi-k2.7-code-highspeed + type: chat + max_input_tokens: 262144 + input_price: 1.9 + output_price: 8.0 + max_output_tokens: 262144 + supports_vision: true + supports_function_calling: true + - name: kimi-k2.6 + type: chat + max_input_tokens: 262144 + input_price: 0.95 + output_price: 4.0 + max_output_tokens: 262144 + supports_vision: true + supports_function_calling: true + - name: kimi-k2.5 + type: chat + max_input_tokens: 262144 + input_price: 0.6 + output_price: 3.0 + max_output_tokens: 262144 + supports_vision: true + supports_function_calling: true + - name: kimi-k2-thinking + type: chat + max_input_tokens: 262144 + input_price: 0.6 + output_price: 2.5 + max_output_tokens: 262144 + supports_function_calling: true + - name: kimi-k2-thinking-turbo + type: chat + max_input_tokens: 262144 + input_price: 1.15 + output_price: 8.0 + max_output_tokens: 262144 + supports_function_calling: true + - name: kimi-k2-0905-preview + type: chat + max_input_tokens: 262144 + input_price: 0.6 + output_price: 2.5 + max_output_tokens: 262144 + supports_function_calling: true + - name: kimi-k2-turbo-preview + type: chat + max_input_tokens: 262144 + input_price: 2.4 + output_price: 10.0 + max_output_tokens: 262144 + supports_function_calling: true + - name: kimi-k2-0711-preview + type: chat + max_input_tokens: 131072 + input_price: 0.6 + output_price: 2.5 + max_output_tokens: 16384 + supports_function_calling: true - provider: deepseek models: - - name: deepseek-v4-pro - max_input_tokens: 1000000 - max_output_tokens: 384000 - input_price: 0.435 - output_price: 0.87 - supports_function_calling: true - - name: deepseek-v4-flash - max_input_tokens: 1000000 - max_output_tokens: 384000 - input_price: 0.14 - output_price: 0.28 - supports_function_calling: true - - name: deepseek-chat - max_input_tokens: 64000 - max_output_tokens: 8192 - input_price: 0.56 - output_price: 1.68 - supports_function_calling: true - - name: deepseek-reasoner - max_input_tokens: 64000 - max_output_tokens: 32768 - input_price: 0.56 - output_price: 1.68 - -# Links: -# - https://open.bigmodel.cn/pricing -# - https://open.bigmodel.cn/dev/api#glm-4 + - name: deepseek-chat + type: chat + max_input_tokens: 64000 + input_price: 0.56 + output_price: 1.68 + max_output_tokens: 8192 + supports_function_calling: true + - name: deepseek-reasoner + type: chat + max_input_tokens: 64000 + input_price: 0.56 + output_price: 1.68 + max_output_tokens: 32768 + - name: deepseek-v4-flash-vision-exp + type: chat + max_input_tokens: 1000000 + input_price: 0.14 + output_price: 0.28 + max_output_tokens: 384000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - high + - max + - name: deepseek-v4-pro + type: chat + max_input_tokens: 1000000 + input_price: 0.435 + output_price: 0.87 + max_output_tokens: 384000 + supports_function_calling: true + reasoning_levels: + - high + - max + - name: deepseek-v4-flash + type: chat + max_input_tokens: 1000000 + input_price: 0.14 + output_price: 0.28 + max_output_tokens: 384000 + supports_function_calling: true + reasoning_levels: + - low + - high + - max - provider: zhipuai models: - - name: glm-5 - max_input_tokens: 202752 - supports_function_calling: true - - name: glm-5:instruct - real_name: glm-5 - max_input_tokens: 202752 - supports_function_calling: true - patch: - body: - thinking: - type: disabled - - name: glm-4.7 - max_input_tokens: 202752 - supports_function_calling: true - - name: glm-4.7:instruct - real_name: glm-4.7 - max_input_tokens: 202752 - supports_function_calling: true - patch: - body: - thinking: - type: disabled - - name: glm-4.7-flash - max_input_tokens: 202752 - input_price: 0 - output_price: 0 - supports_function_calling: true - - name: glm-4.6v - max_input_tokens: 65536 - supports_vision: true - - name: glm-4.6v-flash - max_input_tokens: 65536 - input_price: 0 - output_price: 0 - supports_vision: true - - name: embedding-3 - type: embedding - max_input_tokens: 8192 - input_price: 0.07 - max_tokens_per_chunk: 8192 - default_chunk_size: 2000 - - name: rerank - type: reranker - max_input_tokens: 4096 - input_price: 0.112 - -# Links: -# - https://platform.minimaxi.com/docs/guides/pricing-paygo -# - https://platform.minimaxi.com/document/ChatCompletion%20v2 + - name: embedding-3 + type: embedding + max_input_tokens: 8192 + input_price: 0.07 + max_tokens_per_chunk: 8192 + default_chunk_size: 2000 + - name: rerank + type: reranker + max_input_tokens: 4096 + input_price: 0.112 + - name: glm-4.6v-flash + type: chat + max_input_tokens: 65536 + input_price: 0.0 + output_price: 0.0 + supports_vision: true + - name: glm-5.3-flash + type: chat + max_input_tokens: 1000000 + input_price: 0.075 + output_price: 0.25 + max_output_tokens: 131072 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - high + - max + - name: glm-5.3 + type: chat + max_input_tokens: 1000000 + input_price: 1.4 + output_price: 4.4 + max_output_tokens: 131072 + supports_function_calling: true + reasoning_levels: + - low + - high + - max + - name: glm-5.2 + type: chat + max_input_tokens: 1000000 + input_price: 1.4 + output_price: 4.4 + max_output_tokens: 131072 + supports_function_calling: true + reasoning_levels: + - high + - max + - name: glm-5v-turbo + type: chat + max_input_tokens: 200000 + input_price: 5.0 + output_price: 22.0 + max_output_tokens: 131072 + supports_vision: true + supports_function_calling: true + - name: glm-5.1 + type: chat + max_input_tokens: 200000 + input_price: 1.4 + output_price: 4.4 + max_output_tokens: 131072 + supports_function_calling: true + - name: glm-5 + type: chat + max_input_tokens: 204800 + input_price: 1.0 + output_price: 3.2 + max_output_tokens: 131072 + supports_function_calling: true + - name: glm-5:instruct + type: chat + real_name: glm-5 + max_input_tokens: 204800 + input_price: 1.0 + output_price: 3.2 + patch: + body: + thinking: + type: disabled + max_output_tokens: 131072 + supports_function_calling: true + - name: glm-4.7-flash + type: chat + max_input_tokens: 200000 + input_price: 0.0 + output_price: 0.0 + max_output_tokens: 131072 + supports_function_calling: true + - name: glm-4.7-flashx + type: chat + max_input_tokens: 200000 + input_price: 0.07 + output_price: 0.4 + max_output_tokens: 131072 + supports_function_calling: true + - name: glm-4.7 + type: chat + max_input_tokens: 204800 + input_price: 0.6 + output_price: 2.2 + max_output_tokens: 131072 + supports_function_calling: true + - name: glm-4.7:instruct + type: chat + real_name: glm-4.7 + max_input_tokens: 204800 + input_price: 0.6 + output_price: 2.2 + patch: + body: + thinking: + type: disabled + max_output_tokens: 131072 + supports_function_calling: true + - name: glm-4.6v + type: chat + max_input_tokens: 128000 + input_price: 0.3 + output_price: 0.9 + max_output_tokens: 32768 + supports_vision: true + supports_function_calling: true + - name: glm-4.6 + type: chat + max_input_tokens: 204800 + input_price: 0.6 + output_price: 2.2 + max_output_tokens: 131072 + supports_function_calling: true + - name: glm-4.5v + type: chat + max_input_tokens: 64000 + input_price: 0.6 + output_price: 1.8 + max_output_tokens: 16384 + supports_vision: true + supports_function_calling: true + - name: glm-4.5 + type: chat + max_input_tokens: 131072 + input_price: 0.6 + output_price: 2.2 + max_output_tokens: 98304 + supports_function_calling: true + - name: glm-4.5-air + type: chat + max_input_tokens: 131072 + input_price: 0.2 + output_price: 1.1 + max_output_tokens: 98304 + supports_function_calling: true + - name: glm-4.5-flash + type: chat + max_input_tokens: 131072 + input_price: 0.0 + output_price: 0.0 + max_output_tokens: 98304 + supports_function_calling: true - provider: minimax models: - - name: minimax-m3 - max_input_tokens: 1000000 - input_price: 4.2 - output_price: 16.8 - supports_function_calling: true - - name: minimax-m2.7 - max_input_tokens: 204800 - input_price: 0.294 - output_price: 1.176 - supports_function_calling: true - - name: minimax-m2.5 - max_input_tokens: 204800 - input_price: 0.294 - output_price: 1.176 - supports_function_calling: true - - name: minimax-m2.5-highspeed - max_input_tokens: 204800 - input_price: 0.588 - output_price: 2.352 - supports_function_calling: true - - name: minimax-m2.1 - max_input_tokens: 204800 - input_price: 0.294 - output_price: 1.176 - supports_function_calling: true - - name: minimax-m2.1-highspeed - max_input_tokens: 204800 - input_price: 0.588 - output_price: 2.352 - supports_function_calling: true - -# Links: -# - https://openrouter.ai/models -# - https://openrouter.ai/docs/api-reference/chat-completion + - name: minimax-m3 + type: chat + max_input_tokens: 1000000 + input_price: 4.2 + output_price: 16.8 + supports_function_calling: true + - name: minimax-m2.7 + type: chat + max_input_tokens: 204800 + input_price: 0.294 + output_price: 1.176 + supports_function_calling: true + - name: minimax-m2.5 + type: chat + max_input_tokens: 204800 + input_price: 0.294 + output_price: 1.176 + supports_function_calling: true + - name: minimax-m2.5-highspeed + type: chat + max_input_tokens: 204800 + input_price: 0.588 + output_price: 2.352 + supports_function_calling: true + - name: minimax-m2.1 + type: chat + max_input_tokens: 204800 + input_price: 0.294 + output_price: 1.176 + supports_function_calling: true + - name: minimax-m2.1-highspeed + type: chat + max_input_tokens: 204800 + input_price: 0.588 + output_price: 2.352 + supports_function_calling: true + - name: MiniMax-M3 + type: chat + max_input_tokens: 1048576 + input_price: 0.3 + output_price: 1.2 + max_output_tokens: 512000 + supports_vision: true + supports_function_calling: true + - name: MiniMax-M2.7 + type: chat + max_input_tokens: 204800 + input_price: 0.3 + output_price: 1.2 + max_output_tokens: 131072 + supports_function_calling: true + - name: MiniMax-M2.7-highspeed + type: chat + max_input_tokens: 204800 + input_price: 0.6 + output_price: 2.4 + max_output_tokens: 131072 + supports_function_calling: true + - name: MiniMax-M2.5-highspeed + type: chat + max_input_tokens: 204800 + input_price: 0.6 + output_price: 2.4 + max_output_tokens: 131072 + supports_function_calling: true + - name: MiniMax-M2.5 + type: chat + max_input_tokens: 204800 + input_price: 0.3 + output_price: 1.2 + max_output_tokens: 131072 + supports_function_calling: true + - name: MiniMax-M2.1 + type: chat + max_input_tokens: 204800 + input_price: 0.3 + output_price: 1.2 + max_output_tokens: 131072 + supports_function_calling: true + - name: MiniMax-M2 + type: chat + max_input_tokens: 204800 + input_price: 0.3 + output_price: 1.2 + max_output_tokens: 131072 + supports_function_calling: true - provider: openrouter models: - - name: openai/gpt-5.6-sol - max_input_tokens: 1050000 - max_output_tokens: 128000 - input_price: 5 - output_price: 30 - supports_vision: true - supports_function_calling: true - reasoning_levels: [none, low, medium, high, xhigh, max] - default_reasoning_effort: medium - - name: openai/gpt-5.6-terra - max_input_tokens: 1050000 - max_output_tokens: 128000 - input_price: 5 - output_price: 30 - supports_vision: true - supports_function_calling: true - reasoning_levels: [none, low, medium, high, xhigh, max] - default_reasoning_effort: medium - - name: openai/gpt-5.6-luna - max_input_tokens: 1050000 - max_output_tokens: 128000 - input_price: 5 - output_price: 30 - supports_vision: true - supports_function_calling: true - reasoning_levels: [none, low, medium, high, xhigh, max] - default_reasoning_effort: medium - - name: openai/gpt-5.5 - max_input_tokens: 1050000 - max_output_tokens: 128000 - input_price: 5 - output_price: 30 - supports_vision: true - supports_function_calling: true - reasoning_levels: [none, low, medium, high, xhigh] - default_reasoning_effort: medium - - name: openai/gpt-5.5-pro - max_input_tokens: 1050000 - max_output_tokens: 128000 - input_price: 30 - output_price: 180 - supports_vision: true - supports_function_calling: true - reasoning_levels: [medium, high, xhigh] - default_reasoning_effort: high - - name: openai/gpt-5.4 - max_input_tokens: 1050000 - max_output_tokens: 128000 - input_price: 2.5 - output_price: 15 - supports_vision: true - supports_function_calling: true - reasoning_levels: [none, low, medium, high, xhigh] - default_reasoning_effort: none - - name: openai/gpt-5.4-pro - max_input_tokens: 1050000 - max_output_tokens: 128000 - input_price: 30 - output_price: 180 - supports_vision: true - supports_function_calling: true - reasoning_levels: [medium, high, xhigh] - default_reasoning_effort: medium - - name: openai/gpt-5.4-mini - max_input_tokens: 400000 - max_output_tokens: 128000 - input_price: 0.75 - output_price: 4.5 - supports_vision: true - supports_function_calling: true - reasoning_levels: [none, low, medium, high, xhigh] - default_reasoning_effort: none - - name: openai/gpt-5.4-nano - max_input_tokens: 400000 - max_output_tokens: 128000 - input_price: 0.2 - output_price: 1.25 - supports_vision: true - supports_function_calling: true - reasoning_levels: [none, low, medium, high, xhigh] - default_reasoning_effort: none - - name: openai/gpt-5.3-codex - max_input_tokens: 400000 - max_output_tokens: 128000 - input_price: 1.75 - output_price: 14 - supports_vision: true - supports_function_calling: true - reasoning_levels: [low, medium, high, xhigh] - default_reasoning_effort: medium - - name: openai/gpt-5.2 - max_input_tokens: 400000 - max_output_tokens: 128000 - input_price: 1.75 - output_price: 14 - supports_vision: true - supports_function_calling: true - reasoning_levels: [none, low, medium, high, xhigh] - default_reasoning_effort: none - - name: openai/gpt-5.2-pro - max_input_tokens: 400000 - max_output_tokens: 128000 - input_price: 21 - output_price: 168 - supports_vision: true - supports_function_calling: true - reasoning_levels: [medium, high, xhigh] - default_reasoning_effort: medium - - name: openai/gpt-5 - max_input_tokens: 400000 - max_output_tokens: 128000 - input_price: 1.25 - output_price: 10 - supports_vision: true - supports_function_calling: true - reasoning_levels: [minimal, low, medium, high] - default_reasoning_effort: medium - - name: openai/gpt-5-mini - max_input_tokens: 400000 - max_output_tokens: 128000 - input_price: 0.25 - output_price: 2 - supports_vision: true - supports_function_calling: true - - name: openai/gpt-5-nano - max_input_tokens: 400000 - max_output_tokens: 128000 - input_price: 0.05 - output_price: 0.4 - supports_vision: true - supports_function_calling: true - - name: openai/gpt-4.1 - max_input_tokens: 1047576 - max_output_tokens: 32768 - input_price: 2 - output_price: 8 - supports_vision: true - supports_function_calling: true - - name: openai/gpt-4o - max_input_tokens: 128000 - input_price: 2.5 - output_price: 10 - supports_vision: true - supports_function_calling: true - - name: openai/gpt-oss-120b - max_input_tokens: 131072 - input_price: 0.09 - output_price: 0.45 - supports_function_calling: true - - name: openai/gpt-oss-20b - max_input_tokens: 131072 - input_price: 0.04 - output_price: 0.16 - supports_function_calling: true - - name: google/gemini-3.5-flash - max_input_tokens: 1048576 - max_output_tokens: 65536 - input_price: 0.2 - output_price: 1.5 - supports_function_calling: true - reasoning_levels: [minimal, low, medium, high] - default_reasoning_effort: medium - - name: google/gemini-3-flash-preview - max_input_tokens: 1048576 - max_output_tokens: 65536 - input_price: 0.2 - output_price: 1.5 - supports_function_calling: true - reasoning_levels: [minimal, low, medium, high] - default_reasoning_effort: high - - name: google/gemini-3.1-flash-lite - max_input_tokens: 1048576 - max_output_tokens: 65536 - input_price: 0.2 - output_price: 1.5 - supports_function_calling: true - reasoning_levels: [minimal, low, medium, high] - default_reasoning_effort: minimal - - name: google/gemini-3.1-pro-preview - max_input_tokens: 1048576 - max_output_tokens: 65535 - input_price: 0.3 - output_price: 2.5 - supports_vision: true - supports_function_calling: true - reasoning_levels: [low, medium, high] - default_reasoning_effort: high - - name: google/gemini-3-pro-preview - max_input_tokens: 1048576 - supports_vision: true - supports_function_calling: true - reasoning_levels: [low, high] - default_reasoning_level: high - - name: google/gemini-3-flash-preview - max_input_tokens: 1048576 - supports_vision: true - supports_function_calling: true - reasoning_levels: [minimal, low, medium, high] - default_reasoning_level: high - - name: google/gemini-2.5-flash - max_input_tokens: 1048576 - input_price: 0.3 - output_price: 2.5 - supports_vision: true - supports_function_calling: true - reasoning_levels: [low, medium, high] - default_reasoning_effort: low - - name: google/gemini-2.5-pro - max_input_tokens: 1048576 - input_price: 1.25 - output_price: 10 - supports_vision: true - supports_function_calling: true - reasoning_levels: [low, medium, high] - default_reasoning_effort: high - - name: google/gemini-2.5-flash-lite - max_input_tokens: 1048576 - input_price: 0.3 - output_price: 0.4 - supports_vision: true - - name: google/gemini-2.0-flash-001 - max_input_tokens: 1000000 - input_price: 0.15 - output_price: 0.6 - supports_vision: true - supports_function_calling: true - - name: google/gemini-2.0-flash-lite-001 - max_input_tokens: 1048576 - input_price: 0.075 - output_price: 0.3 - supports_vision: true - supports_function_calling: true - - name: google/gemma-3-27b-it - max_input_tokens: 131072 - input_price: 0.1 - output_price: 0.2 - - name: anthropic/claude-opus-5 - max_input_tokens: 1000000 - max_output_tokens: 128000 - require_max_tokens: true - input_price: 5 - output_price: 25 - supports_function_calling: true - supports_vision: true - reasoning_levels: [low, medium, high, xhigh, max] - default_reasoning_effort: high - - name: anthropic/claude-fable-5-1 - max_input_tokens: 1000000 - max_output_tokens: 128000 - require_max_tokens: true - input_price: 10 - output_price: 50 - supports_function_calling: true - supports_vision: true - reasoning_levels: [low, medium, high, xhigh, max] - default_reasoning_effort: high - - name: anthropic/claude-fable-5 - max_input_tokens: 1000000 - max_output_tokens: 128000 - require_max_tokens: true - input_price: 10 - output_price: 50 - supports_function_calling: true - supports_vision: true - reasoning_levels: [low, medium, high, xhigh, max] - default_reasoning_effort: high - - name: anthropic/claude-opus-4-8 - max_input_tokens: 1000000 - max_output_tokens: 128000 - require_max_tokens: true - input_price: 5 - output_price: 25 - supports_vision: true - supports_function_calling: true - reasoning_levels: [low, medium, high, xhigh, max] - default_reasoning_effort: high - - name: anthropic/claude-opus-4-7 - max_input_tokens: 1000000 - max_output_tokens: 128000 - require_max_tokens: true - input_price: 5 - output_price: 25 - supports_vision: true - supports_function_calling: true - reasoning_levels: [low, medium, high, xhigh, max] - default_reasoning_effort: high - - name: anthropic/claude-opus-4.6 - max_input_tokens: 200000 - max_output_tokens: 8192 - require_max_tokens: true - input_price: 5 - output_price: 25 - supports_vision: true - supports_function_calling: true - reasoning_levels: [low, medium, high, max] - default_reasoning_effort: high - - name: anthropic/claude-sonnet-5 - max_input_tokens: 1000000 - max_output_tokens: 128000 - require_max_tokens: true - input_price: 3 - output_price: 15 - supports_vision: true - supports_function_calling: true - reasoning_levels: [low, medium, high, xhigh, max] - default_reasoning_effort: high - - name: anthropic/claude-sonnet-4.6 - max_input_tokens: 200000 - max_output_tokens: 8192 - require_max_tokens: true - input_price: 3 - output_price: 15 - supports_vision: true - supports_function_calling: true - reasoning_levels: [low, medium, high, max] - default_reasoning_effort: high - - name: anthropic/claude-opus-4.5 - max_input_tokens: 200000 - max_output_tokens: 8192 - require_max_tokens: true - input_price: 5 - output_price: 25 - supports_vision: true - supports_function_calling: true - - name: anthropic/claude-sonnet-4.5 - max_input_tokens: 200000 - max_output_tokens: 8192 - require_max_tokens: true - input_price: 3 - output_price: 15 - supports_vision: true - supports_function_calling: true - - name: anthropic/claude-haiku-4.5 - max_input_tokens: 200000 - max_output_tokens: 8192 - require_max_tokens: true - input_price: 1 - output_price: 5 - supports_vision: true - supports_function_calling: true - - name: meta-llama/llama-4-maverick - max_input_tokens: 1048576 - input_price: 0.18 - output_price: 0.6 - supports_vision: true - supports_function_calling: true - - name: meta-llama/llama-4-scout - max_input_tokens: 327680 - input_price: 0.08 - output_price: 0.3 - supports_vision: true - supports_function_calling: true - - name: meta-llama/llama-3.3-70b-instruct - max_input_tokens: 131072 - input_price: 0.12 - output_price: 0.3 - - name: mistralai/mistral-large-2512 - max_input_tokens: 262144 - input_price: 0.5 - output_price: 1.5 - supports_function_calling: true - - name: mistralai/mistral-medium-3.1 - max_input_tokens: 131072 - input_price: 0.4 - output_price: 2 - supports_function_calling: true - supports_vision: true - - name: mistralai/mistral-small-3.2-24b-instruct - max_input_tokens: 131072 - input_price: 0.1 - output_price: 0.3 - supports_vision: true - - name: mistralai/devstral-2512 - max_input_tokens: 262144 - input_price: 0.5 - output_price: 0.22 - supports_function_calling: true - - name: mistralai/devstral-small - max_input_tokens: 131072 - input_price: 0.07 - output_price: 0.28 - supports_function_calling: true - - name: mistralai/codestral-2508 - max_input_tokens: 256000 - input_price: 0.3 - output_price: 0.9 - supports_function_calling: true - - name: mistralai/ministral-14b-2512 - max_input_tokens: 262144 - input_price: 0.2 - output_price: 0.2 - supports_function_calling: true - - name: ai21/jamba-large-1.7 - max_input_tokens: 256000 - input_price: 2 - output_price: 8 - supports_function_calling: true - - name: cohere/command-a - max_input_tokens: 256000 - input_price: 2.5 - output_price: 10 - supports_function_calling: true - - name: cohere/command-r7b-12-2024 - max_input_tokens: 128000 - max_output_tokens: 4096 - input_price: 0.0375 - output_price: 0.15 - - name: deepseek/deepseek-v3.2 - max_input_tokens: 163840 - input_price: 0.25 - output_price: 0.38 - - name: qwen/qwen3-max - max_input_tokens: 262144 - input_price: 1.2 - output_price: 6 - supports_function_calling: true - - name: qwen/qwen3-max-thinking - max_input_tokens: 262144 - input_price: 1.2 - output_price: 6 - supports_function_calling: true - - name: qwen/qwen3.5-plus-02-15 - max_input_tokens: 1000000 - max_output_tokens: 8192 - input_price: 0.4 - output_price: 2.4 - supports_function_calling: true - - name: qwen/qwen3.5-397b-a17b - max_input_tokens: 262144 - max_output_tokens: 8192 - input_price: 0.15 - output_price: 1 - supports_function_calling: true - - name: qwen/qwen3-next-80b-a3b-instruct - max_input_tokens: 262144 - input_price: 0.1 - output_price: 0.8 - supports_function_calling: true - - name: qwen/qwen3-next-80b-a3b-thinking - max_input_tokens: 262144 - input_price: 0.1 - output_price: 0.8 - - name: qwen/qwen3-235b-a22b-2507 # Qwen3 235B A22B Instruct 2507 - max_input_tokens: 262144 - input_price: 0.12 - output_price: 0.59 - supports_function_calling: true - - name: qwen/qwen3-235b-a22b-thinking-2507 - max_input_tokens: 262144 - input_price: 0.118 - output_price: 0.118 - - name: qwen/qwen3-30b-a3b-instruct-2507 - max_input_tokens: 131072 - input_price: 0.2 - output_price: 0.8 - - name: qwen/qwen3-30b-a3b-thinking-2507 - max_input_tokens: 262144 - input_price: 0.071 - output_price: 0.285 - - name: qwen/qwen3-vl-32b-instruct - max_input_tokens: 262144 - input_price: 0.35 - output_price: 1.1 - supports_vision: true - - name: qwen/qwen3-vl-8b-instruct - max_input_tokens: 262144 - input_price: 0.08 - output_price: 0.50 - supports_vision: true - - name: qwen/qwen3-coder-next - max_input_tokens: 262144 - input_price: 0.12 - output_price: 0.75 - supports_function_calling: true - - name: qwen/qwen3-coder-plus - max_input_tokens: 128000 - input_price: 1 - output_price: 5 - supports_function_calling: true - - name: qwen/qwen3-coder-flash - max_input_tokens: 128000 - input_price: 0.3 - output_price: 1.5 - supports_function_calling: true - - name: qwen/qwen3-coder # Qwen3 Coder 480B A35B - max_input_tokens: 262144 - input_price: 0.22 - output_price: 0.95 - supports_function_calling: true - - name: qwen/qwen3-coder-30b-a3b-instruct - max_input_tokens: 262144 - input_price: 0.052 - output_price: 0.207 - supports_function_calling: true - - name: moonshotai/kimi-k2.5 - max_input_tokens: 262144 - input_price: 0.57 - output_price: 2.85 - supports_vision: true - supports_function_calling: true - - name: moonshotai/kimi-k2-0905 - max_input_tokens: 262144 - input_price: 0.296 - output_price: 1.185 - supports_vision: true - supports_function_calling: true - - name: moonshotai/kimi-k2-thinking - max_input_tokens: 262144 - input_price: 0.45 - output_price: 2.35 - supports_function_calling: true - - name: x-ai/grok-4.1-fast - max_input_tokens: 2000000 - input_price: 0.2 - output_price: 0.5 - supports_function_calling: true - - name: x-ai/grok-code-fast-1 - max_input_tokens: 256000 - input_price: 0.2 - output_price: 1.5 - supports_function_calling: true - - name: amazon/nova-premier-v1 - max_input_tokens: 1000000 - input_price: 2.5 - output_price: 12.5 - supports_vision: true - - name: amazon/nova-pro-v1 - max_input_tokens: 300000 - max_output_tokens: 5120 - input_price: 0.8 - output_price: 3.2 - supports_vision: true - - name: amazon/nova-lite-v1 - max_input_tokens: 300000 - max_output_tokens: 5120 - input_price: 0.06 - output_price: 0.24 - supports_vision: true - - name: amazon/nova-micro-v1 - max_input_tokens: 128000 - max_output_tokens: 5120 - input_price: 0.035 - output_price: 0.14 - - name: perplexity/sonar-pro - max_input_tokens: 200000 - input_price: 3 - output_price: 15 - - name: perplexity/sonar - max_input_tokens: 127072 - input_price: 1 - output_price: 1 - - name: perplexity/sonar-reasoning-pro - max_input_tokens: 128000 - input_price: 2 - output_price: 8 - patch: - body: - include_reasoning: true - - name: perplexity/sonar-deep-research - max_input_tokens: 200000 - input_price: 2 - output_price: 8 - patch: - body: - include_reasoning: true - - name: minimax/minimax-m2.5 - max_input_tokens: 196608 - input_price: 0.3 - output_price: 1.1 - supports_function_calling: true - - name: minimax/minimax-m2.1 - max_input_tokens: 196608 - input_price: 0.12 - output_price: 0.48 - supports_function_calling: true - - name: z-ai/glm-5 - max_input_tokens: 204800 - input_price: 0.95 - output_price: 2.55 - supports_function_calling: true - - name: z-ai/glm-4.7 - max_input_tokens: 202752 - input_price: 0.16 - output_price: 0.80 - supports_function_calling: true - - name: z-ai/glm-4.7-flash - max_input_tokens: 202752 - input_price: 0.07 - output_price: 0.40 - supports_function_calling: true - - name: z-ai/glm-4.6v - max_input_tokens: 131072 - input_price: 0.3 - output_price: 0.9 - supports_vision: true - -# Links: -# - https://github.com/marketplace?type=models + - name: google/gemini-3-pro-preview + type: chat + max_input_tokens: 1048576 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - high + default_reasoning_effort: high + - name: google/gemini-2.0-flash-001 + type: chat + max_input_tokens: 1000000 + input_price: 0.15 + output_price: 0.6 + supports_vision: true + supports_function_calling: true + - name: google/gemini-2.0-flash-lite-001 + type: chat + max_input_tokens: 1048576 + input_price: 0.075 + output_price: 0.3 + supports_vision: true + supports_function_calling: true + - name: anthropic/claude-fable-5-1 + type: chat + max_input_tokens: 1000000 + input_price: 10.0 + output_price: 50.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: high + - name: anthropic/claude-opus-4-8 + type: chat + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: high + - name: anthropic/claude-opus-4-7 + type: chat + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: high + - name: mistralai/devstral-small + type: chat + max_input_tokens: 131072 + input_price: 0.07 + output_price: 0.28 + supports_function_calling: true + - name: ai21/jamba-large-1.7 + type: chat + max_input_tokens: 256000 + input_price: 2.0 + output_price: 8.0 + supports_function_calling: true + - name: x-ai/grok-4.1-fast + type: chat + max_input_tokens: 2000000 + input_price: 0.2 + output_price: 0.5 + supports_function_calling: true + - name: x-ai/grok-code-fast-1 + type: chat + max_input_tokens: 256000 + input_price: 0.2 + output_price: 1.5 + supports_function_calling: true + - name: aion-labs/aion-2.0 + type: chat + max_input_tokens: 131072 + input_price: 0.8 + output_price: 1.6 + max_output_tokens: 32768 + supports_function_calling: true + - name: aion-labs/aion-3.0 + type: chat + max_input_tokens: 131072 + input_price: 3.0 + output_price: 6.0 + max_output_tokens: 32768 + supports_function_calling: true + - name: aion-labs/aion-3.0-mini + type: chat + max_input_tokens: 131072 + input_price: 0.7 + output_price: 1.4 + max_output_tokens: 32768 + supports_function_calling: true + - name: aion-labs/aion-rp-llama-3.1-8b + type: chat + max_input_tokens: 32768 + input_price: 0.8 + output_price: 1.6 + max_output_tokens: 29491 + - name: amazon/nova-2-lite-v1 + type: chat + max_input_tokens: 1000000 + input_price: 0.3 + output_price: 2.5 + max_output_tokens: 65535 + supports_vision: true + supports_function_calling: true + - name: amazon/nova-lite-v1 + type: chat + max_input_tokens: 300000 + input_price: 0.06 + output_price: 0.24 + max_output_tokens: 5120 + supports_vision: true + supports_function_calling: true + - name: amazon/nova-micro-v1 + type: chat + max_input_tokens: 128000 + input_price: 0.035 + output_price: 0.14 + max_output_tokens: 5120 + supports_function_calling: true + - name: amazon/nova-premier-v1 + type: chat + max_input_tokens: 1000000 + input_price: 2.5 + output_price: 12.5 + max_output_tokens: 32000 + supports_vision: true + supports_function_calling: true + - name: amazon/nova-pro-v1 + type: chat + max_input_tokens: 300000 + input_price: 0.8 + output_price: 3.2 + max_output_tokens: 5120 + supports_vision: true + supports_function_calling: true + - name: anthracite-org/magnum-v4-72b + type: chat + max_input_tokens: 32768 + input_price: 2.5 + output_price: 5.0 + max_output_tokens: 4096 + - name: anthropic/claude-3-haiku + type: chat + max_input_tokens: 200000 + input_price: 0.25 + output_price: 1.25 + max_output_tokens: 4096 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: anthropic/claude-fable-5 + type: chat + max_input_tokens: 1000000 + input_price: 10.0 + output_price: 50.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: high + - name: anthropic/claude-fable-5.1 + type: chat + max_input_tokens: 1000000 + input_price: 10.0 + output_price: 50.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: high + - name: anthropic/claude-fable-5.1:batch + type: chat + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: high + - name: anthropic/claude-fable-5:batch + type: chat + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: high + - name: anthropic/claude-haiku-4.5 + type: chat + max_input_tokens: 200000 + input_price: 1.0 + output_price: 5.0 + max_output_tokens: 64000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: anthropic/claude-haiku-4.5:batch + type: chat + max_input_tokens: 200000 + input_price: 0.5 + output_price: 2.5 + max_output_tokens: 64000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: anthropic/claude-opus-4 + type: chat + max_input_tokens: 200000 + input_price: 15.0 + output_price: 75.0 + max_output_tokens: 32000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: anthropic/claude-opus-4.1 + type: chat + max_input_tokens: 200000 + input_price: 15.0 + output_price: 75.0 + max_output_tokens: 32000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: anthropic/claude-opus-4.1:batch + type: chat + max_input_tokens: 200000 + input_price: 7.5 + output_price: 37.5 + max_output_tokens: 32000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: anthropic/claude-opus-4.5 + type: chat + max_input_tokens: 200000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 64000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: anthropic/claude-opus-4.5:batch + type: chat + max_input_tokens: 200000 + input_price: 2.5 + output_price: 12.5 + max_output_tokens: 64000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: anthropic/claude-opus-4.6 + type: chat + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - max + default_reasoning_effort: high + - name: anthropic/claude-opus-4.6:batch + type: chat + max_input_tokens: 1000000 + input_price: 2.5 + output_price: 12.5 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: anthropic/claude-opus-4.7 + type: chat + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: anthropic/claude-opus-4.7:batch + type: chat + max_input_tokens: 1000000 + input_price: 2.5 + output_price: 12.5 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: anthropic/claude-opus-4.8 + type: chat + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: anthropic/claude-opus-4.8:batch + type: chat + max_input_tokens: 1000000 + input_price: 2.5 + output_price: 12.5 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: anthropic/claude-opus-5 + type: chat + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: high + - name: anthropic/claude-opus-5:batch + type: chat + max_input_tokens: 1000000 + input_price: 2.5 + output_price: 12.5 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: anthropic/claude-sonnet-4 + type: chat + max_input_tokens: 1000000 + input_price: 3.0 + output_price: 15.0 + max_output_tokens: 64000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: anthropic/claude-sonnet-4.5 + type: chat + max_input_tokens: 1000000 + input_price: 3.0 + output_price: 15.0 + max_output_tokens: 64000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: anthropic/claude-sonnet-4.5:batch + type: chat + max_input_tokens: 1000000 + input_price: 1.5 + output_price: 7.5 + max_output_tokens: 64000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: anthropic/claude-sonnet-4.6 + type: chat + max_input_tokens: 1000000 + input_price: 3.0 + output_price: 15.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - max + default_reasoning_effort: high + - name: anthropic/claude-sonnet-4.6:batch + type: chat + max_input_tokens: 1000000 + input_price: 1.5 + output_price: 7.5 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: anthropic/claude-sonnet-5 + type: chat + max_input_tokens: 1000000 + input_price: 2.0 + output_price: 10.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: high + - name: anthropic/claude-sonnet-5:batch + type: chat + max_input_tokens: 1000000 + input_price: 1.0 + output_price: 5.0 + max_output_tokens: 128000 + require_max_tokens: true + supports_vision: true + supports_function_calling: true + - name: arcee-ai/trinity-large-thinking + type: chat + max_input_tokens: 262144 + input_price: 0.25 + output_price: 0.8 + max_output_tokens: 80000 + supports_function_calling: true + - name: baidu/ernie-4.5-vl-424b-a47b + type: chat + max_input_tokens: 123000 + input_price: 0.42 + output_price: 1.25 + max_output_tokens: 16000 + supports_vision: true + - name: bytedance-seed/seed-1.6 + type: chat + max_input_tokens: 262144 + input_price: 0.25 + output_price: 2.0 + max_output_tokens: 32768 + supports_vision: true + supports_function_calling: true + - name: bytedance-seed/seed-1.6-flash + type: chat + max_input_tokens: 262144 + input_price: 0.075 + output_price: 0.3 + max_output_tokens: 32768 + supports_vision: true + supports_function_calling: true + - name: bytedance-seed/seed-2-1-turbo + type: chat + max_input_tokens: 262144 + input_price: 0.5 + output_price: 2.5 + max_output_tokens: 235929 + supports_vision: true + supports_function_calling: true + - name: bytedance-seed/seed-2.0-code + type: chat + max_input_tokens: 262144 + input_price: 0.5 + output_price: 3.0 + max_output_tokens: 131072 + supports_vision: true + supports_function_calling: true + - name: bytedance-seed/seed-2.0-lite + type: chat + max_input_tokens: 262144 + input_price: 0.25 + output_price: 2.0 + max_output_tokens: 131072 + supports_vision: true + supports_function_calling: true + - name: bytedance-seed/seed-2.0-mini + type: chat + max_input_tokens: 262144 + input_price: 0.1 + output_price: 0.4 + max_output_tokens: 131072 + supports_vision: true + supports_function_calling: true + - name: bytedance/ui-tars-1.5-7b + type: chat + max_input_tokens: 128000 + input_price: 0.1 + output_price: 0.2 + max_output_tokens: 2048 + supports_vision: true + - name: cognitivecomputations/dolphin-mistral-24b-venice-edition + type: chat + max_input_tokens: 128000 + input_price: 0.2 + output_price: 0.9 + max_output_tokens: 8192 + - name: cohere/command-a + type: chat + max_input_tokens: 256000 + input_price: 2.5 + output_price: 10.0 + max_output_tokens: 8192 + - name: cohere/command-r-08-2024 + type: chat + max_input_tokens: 128000 + input_price: 0.15 + output_price: 0.6 + max_output_tokens: 4000 + supports_function_calling: true + - name: cohere/command-r-plus-08-2024 + type: chat + max_input_tokens: 128000 + input_price: 2.5 + output_price: 10.0 + max_output_tokens: 4000 + supports_function_calling: true + - name: cohere/command-r7b-12-2024 + type: chat + max_input_tokens: 128000 + input_price: 0.0375 + output_price: 0.15 + max_output_tokens: 4000 + - name: cohere/north-mini-code:free + type: chat + max_input_tokens: 256000 + input_price: 0.0 + output_price: 0.0 + max_output_tokens: 64000 + supports_function_calling: true + - name: deepseek/deepseek-chat + type: chat + max_input_tokens: 163840 + input_price: 0.2574 + output_price: 1.0287 + max_output_tokens: 16000 + supports_function_calling: true + - name: deepseek/deepseek-chat-v3-0324 + type: chat + max_input_tokens: 163840 + input_price: 0.25 + output_price: 1.0 + max_output_tokens: 147456 + supports_function_calling: true + - name: deepseek/deepseek-chat-v3.1 + type: chat + max_input_tokens: 163840 + input_price: 0.25 + output_price: 0.95 + max_output_tokens: 32768 + supports_function_calling: true + - name: deepseek/deepseek-r1 + type: chat + max_input_tokens: 64000 + input_price: 0.7 + output_price: 2.5 + max_output_tokens: 16000 + supports_function_calling: true + - name: deepseek/deepseek-r1-0528 + type: chat + max_input_tokens: 163840 + input_price: 0.5 + output_price: 2.15 + max_output_tokens: 32768 + supports_function_calling: true + - name: deepseek/deepseek-r1-distill-llama-70b + type: chat + max_input_tokens: 8192 + input_price: 0.8 + output_price: 0.8 + max_output_tokens: 7372 + - name: deepseek/deepseek-v3.1-terminus + type: chat + max_input_tokens: 163840 + input_price: 0.27 + output_price: 1.0 + max_output_tokens: 32768 + supports_function_calling: true + - name: deepseek/deepseek-v3.2 + type: chat + max_input_tokens: 163840 + input_price: 0.269 + output_price: 0.4 + max_output_tokens: 65536 + supports_function_calling: true + - name: deepseek/deepseek-v3.2-exp + type: chat + max_input_tokens: 163840 + input_price: 0.27 + output_price: 0.41 + max_output_tokens: 65536 + supports_function_calling: true + - name: deepseek/deepseek-v4-flash + type: chat + max_input_tokens: 1048576 + input_price: 0.0825 + output_price: 0.1649 + max_output_tokens: 384000 + supports_function_calling: true + - name: deepseek/deepseek-v4-flash-0731 + type: chat + max_input_tokens: 1310720 + input_price: 0.065 + output_price: 0.18 + max_output_tokens: 943718 + supports_function_calling: true + - name: deepseek/deepseek-v4-flash-0731:batch + type: chat + max_input_tokens: 1048576 + input_price: 0.14 + output_price: 0.28 + max_output_tokens: 943718 + supports_function_calling: true + - name: deepseek/deepseek-v4-flash-vision-exp + type: chat + max_input_tokens: 1048576 + input_price: 0.22 + output_price: 0.66 + max_output_tokens: 384000 + supports_vision: true + supports_function_calling: true + - name: deepseek/deepseek-v4-pro + type: chat + max_input_tokens: 1048576 + input_price: 1.0308 + output_price: 2.0616 + max_output_tokens: 384000 + supports_function_calling: true + - name: deepseek/deepseek-v4-pro-0813 + type: chat + max_input_tokens: 1048576 + input_price: 0.66 + output_price: 1.98 + max_output_tokens: 384000 + supports_function_calling: true + - name: deepseek/deepseek-v4-pro-0813:batch + type: chat + max_input_tokens: 1048576 + input_price: 1.32 + output_price: 3.96 + max_output_tokens: 943718 + supports_function_calling: true + - name: dots-studio/dots-3-note-preview:free + type: chat + max_input_tokens: 512000 + input_price: 0.0 + output_price: 0.0 + max_output_tokens: 460800 + supports_vision: true + supports_function_calling: true + - name: google/gemini-2.5-flash + type: chat + max_input_tokens: 1048576 + input_price: 0.3 + output_price: 2.5 + max_output_tokens: 65535 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + default_reasoning_effort: low + - name: google/gemini-2.5-flash-image + type: chat + max_input_tokens: 32768 + input_price: 0.3 + output_price: 2.5 + max_output_tokens: 8192 + supports_vision: true + - name: google/gemini-2.5-flash-lite + type: chat + max_input_tokens: 1048576 + input_price: 0.1 + output_price: 0.4 + max_output_tokens: 65535 + supports_vision: true + supports_function_calling: true + - name: google/gemini-2.5-flash-lite:batch + type: chat + max_input_tokens: 1048576 + input_price: 0.05 + output_price: 0.2 + max_output_tokens: 65535 + supports_vision: true + supports_function_calling: true + - name: google/gemini-2.5-flash:batch + type: chat + max_input_tokens: 1048576 + input_price: 0.15 + output_price: 1.25 + max_output_tokens: 65535 + supports_vision: true + supports_function_calling: true + - name: google/gemini-2.5-pro + type: chat + max_input_tokens: 1048576 + input_price: 1.25 + output_price: 10.0 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + default_reasoning_effort: high + - name: google/gemini-2.5-pro-preview + type: chat + max_input_tokens: 1048576 + input_price: 1.25 + output_price: 10.0 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: google/gemini-2.5-pro-preview-05-06 + type: chat + max_input_tokens: 1048576 + input_price: 1.25 + output_price: 10.0 + max_output_tokens: 65535 + supports_vision: true + supports_function_calling: true + - name: google/gemini-2.5-pro:batch + type: chat + max_input_tokens: 1048576 + input_price: 0.625 + output_price: 5.0 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: google/gemini-3-flash-preview + type: chat + max_input_tokens: 1048576 + input_price: 0.5 + output_price: 3.0 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - minimal + - low + - medium + - high + default_reasoning_effort: high + - name: google/gemini-3-flash-preview:batch + type: chat + max_input_tokens: 1048576 + input_price: 0.25 + output_price: 1.5 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: google/gemini-3-pro-image + type: chat + max_input_tokens: 131072 + input_price: 2.0 + output_price: 12.0 + max_output_tokens: 32768 + supports_vision: true + supports_function_calling: true + - name: google/gemini-3-pro-image-preview + type: chat + max_input_tokens: 65536 + input_price: 2.0 + output_price: 12.0 + max_output_tokens: 32768 + supports_vision: true + - name: google/gemini-3.1-flash-image + type: chat + max_input_tokens: 131072 + input_price: 0.5 + output_price: 3.0 + max_output_tokens: 32768 + supports_vision: true + - name: google/gemini-3.1-flash-image-preview + type: chat + max_input_tokens: 65536 + input_price: 0.5 + output_price: 3.0 + max_output_tokens: 58982 + supports_vision: true + - name: google/gemini-3.1-flash-lite + type: chat + max_input_tokens: 1048576 + input_price: 0.25 + output_price: 1.5 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - minimal + - low + - medium + - high + default_reasoning_effort: minimal + - name: google/gemini-3.1-flash-lite-image + type: chat + max_input_tokens: 65536 + input_price: 0.25 + output_price: 1.5 + max_output_tokens: 58982 + supports_vision: true + - name: google/gemini-3.1-flash-lite-preview + type: chat + max_input_tokens: 1048576 + input_price: 0.25 + output_price: 1.5 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: google/gemini-3.1-flash-lite:batch + type: chat + max_input_tokens: 1048576 + input_price: 0.125 + output_price: 0.75 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: google/gemini-3.1-pro-preview + type: chat + max_input_tokens: 1048576 + input_price: 2.0 + output_price: 12.0 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + default_reasoning_effort: high + - name: google/gemini-3.1-pro-preview-customtools + type: chat + max_input_tokens: 1048576 + input_price: 2.0 + output_price: 12.0 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: google/gemini-3.1-pro-preview:batch + type: chat + max_input_tokens: 1048576 + input_price: 1.0 + output_price: 6.0 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: google/gemini-3.5-flash + type: chat + max_input_tokens: 1048576 + input_price: 1.5 + output_price: 9.0 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - minimal + - low + - medium + - high + default_reasoning_effort: medium + - name: google/gemini-3.5-flash-lite + type: chat + max_input_tokens: 1048576 + input_price: 0.3 + output_price: 2.5 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: google/gemini-3.5-flash-lite:batch + type: chat + max_input_tokens: 1048576 + input_price: 0.15 + output_price: 1.25 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: google/gemini-3.5-flash:batch + type: chat + max_input_tokens: 1048576 + input_price: 0.75 + output_price: 4.5 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: google/gemini-3.6-flash + type: chat + max_input_tokens: 1048576 + input_price: 0.75 + output_price: 3.75 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: google/gemini-3.6-flash:batch + type: chat + max_input_tokens: 1048576 + input_price: 0.375 + output_price: 1.875 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: google/gemini-3.7-flash + type: chat + max_input_tokens: 1048576 + input_price: 0.75 + output_price: 3.75 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: google/gemini-3.7-flash:batch + type: chat + max_input_tokens: 1048576 + input_price: 0.375 + output_price: 1.875 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: google/gemini-3.8-flash + type: chat + max_input_tokens: 1048576 + input_price: 0.75 + output_price: 3.75 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: google/gemini-3.8-flash:batch + type: chat + max_input_tokens: 1048576 + input_price: 0.375 + output_price: 1.875 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: google/gemma-2-27b-it + type: chat + max_input_tokens: 8192 + input_price: 0.65 + output_price: 0.65 + max_output_tokens: 2048 + - name: google/gemma-3-12b-it + type: chat + max_input_tokens: 131072 + input_price: 0.05 + output_price: 0.15 + max_output_tokens: 16384 + supports_vision: true + supports_function_calling: true + - name: google/gemma-3-27b-it + type: chat + max_input_tokens: 131072 + input_price: 0.08 + output_price: 0.45 + max_output_tokens: 117964 + supports_vision: true + supports_function_calling: true + - name: google/gemma-3-4b-it + type: chat + max_input_tokens: 131072 + input_price: 0.05 + output_price: 0.1 + max_output_tokens: 16384 + supports_vision: true + - name: google/gemma-4-26b-a4b-it + type: chat + max_input_tokens: 262144 + input_price: 0.07 + output_price: 0.34 + max_output_tokens: 16384 + supports_vision: true + supports_function_calling: true + - name: google/gemma-4-26b-a4b-it:free + type: chat + max_input_tokens: 262144 + input_price: 0.0 + output_price: 0.0 + max_output_tokens: 32768 + supports_vision: true + supports_function_calling: true + - name: google/gemma-4-31b-it + type: chat + max_input_tokens: 262144 + input_price: 0.09 + output_price: 0.34 + max_output_tokens: 16384 + supports_vision: true + supports_function_calling: true + - name: google/gemma-4-31b-it:batch + type: chat + max_input_tokens: 262144 + input_price: 0.39 + output_price: 0.97 + max_output_tokens: 235929 + supports_vision: true + supports_function_calling: true + - name: google/gemma-4-31b-it:free + type: chat + max_input_tokens: 262144 + input_price: 0.0 + output_price: 0.0 + max_output_tokens: 32768 + supports_vision: true + supports_function_calling: true + - name: google/lyria-3-clip-preview + type: chat + max_input_tokens: 1048576 + input_price: 0.0 + output_price: 0.0 + max_output_tokens: 65536 + supports_vision: true + - name: google/lyria-3-pro-preview + type: chat + max_input_tokens: 1048576 + input_price: 0.0 + output_price: 0.0 + max_output_tokens: 65536 + supports_vision: true + - name: gryphe/mythomax-l2-13b + type: chat + max_input_tokens: 8192 + input_price: 0.06 + output_price: 0.06 + max_output_tokens: 3686 + - name: ibm-granite/granite-4.0-h-micro + type: chat + max_input_tokens: 131000 + input_price: 0.017 + output_price: 0.112 + max_output_tokens: 117900 + - name: ibm-granite/granite-4.1-8b + type: chat + max_input_tokens: 131072 + input_price: 0.05 + output_price: 0.1 + max_output_tokens: 117964 + supports_function_calling: true + - name: ibm-granite/granite-4.2-8b + type: chat + max_input_tokens: 131072 + input_price: 0.1 + output_price: 0.15 + max_output_tokens: 117964 + supports_function_calling: true + - name: inception/mercury-2 + type: chat + max_input_tokens: 128000 + input_price: 0.25 + output_price: 0.75 + max_output_tokens: 50000 + supports_function_calling: true + - name: inception/mercury-2.5-preview + type: chat + max_input_tokens: 260000 + input_price: 0.04 + output_price: 0.15 + max_output_tokens: 65536 + supports_function_calling: true + - name: inclusionai/ling-3.0-flash + type: chat + max_input_tokens: 262144 + input_price: 0.021 + output_price: 0.063 + max_output_tokens: 32768 + supports_function_calling: true + - name: inclusionai/ling-3.0-flash-fin:free + type: chat + max_input_tokens: 262144 + input_price: 0.0 + output_price: 0.0 + max_output_tokens: 32768 + supports_function_calling: true + - name: kwaipilot/kat-coder-pro-v2 + type: chat + max_input_tokens: 262144 + input_price: 0.3 + output_price: 1.2 + max_output_tokens: 144000 + supports_function_calling: true + - name: kwaipilot/kat-coder-pro-v2.5 + type: chat + max_input_tokens: 262144 + input_price: 0.74 + output_price: 2.96 + max_output_tokens: 235929 + supports_function_calling: true + - name: liquid/lfm-2.5-2.6b:free + type: chat + max_input_tokens: 65536 + input_price: 0.0 + output_price: 0.0 + max_output_tokens: 8192 + supports_function_calling: true + - name: mancer/weaver + type: chat + max_input_tokens: 8000 + input_price: 0.4 + output_price: 0.75 + max_output_tokens: 6000 + - name: meituan/longcat-2.0 + type: chat + max_input_tokens: 1048756 + input_price: 0.3 + output_price: 1.2 + max_output_tokens: 262144 + supports_function_calling: true + - name: meta-llama/llama-3.1-70b-instruct + type: chat + max_input_tokens: 131072 + input_price: 0.4 + output_price: 0.4 + max_output_tokens: 16384 + supports_function_calling: true + - name: meta-llama/llama-3.1-8b-instruct + type: chat + max_input_tokens: 131072 + input_price: 0.05 + output_price: 0.08 + max_output_tokens: 117964 + supports_function_calling: true + - name: meta-llama/llama-3.2-1b-instruct + type: chat + max_input_tokens: 60000 + input_price: 0.027 + output_price: 0.201 + max_output_tokens: 54000 + - name: meta-llama/llama-3.2-3b-instruct + type: chat + max_input_tokens: 131072 + input_price: 0.05 + output_price: 0.33 + max_output_tokens: 117964 + - name: meta-llama/llama-3.3-70b-instruct + type: chat + max_input_tokens: 131072 + input_price: 0.71 + output_price: 0.71 + max_output_tokens: 115200 + supports_function_calling: true + - name: meta-llama/llama-4-maverick + type: chat + max_input_tokens: 1048576 + input_price: 0.2 + output_price: 0.696 + max_output_tokens: 115200 + supports_vision: true + supports_function_calling: true + - name: meta-llama/llama-4-scout + type: chat + max_input_tokens: 1310720 + input_price: 0.1 + output_price: 0.3 + max_output_tokens: 16384 + supports_vision: true + supports_function_calling: true + - name: meta-llama/llama-guard-4-12b + type: chat + max_input_tokens: 163840 + input_price: 0.18 + output_price: 0.18 + max_output_tokens: 16384 + supports_vision: true + - name: meta/muse-glimmer-30b + type: chat + max_input_tokens: 131072 + input_price: 0.3 + output_price: 1.2 + max_output_tokens: 16384 + supports_vision: true + supports_function_calling: true + - name: meta/muse-glimmer-30b:batch + type: chat + max_input_tokens: 131072 + input_price: 0.35 + output_price: 1.5 + max_output_tokens: 117964 + supports_vision: true + supports_function_calling: true + - name: meta/muse-spark-1.1 + type: chat + max_input_tokens: 1048576 + input_price: 1.25 + output_price: 4.25 + max_output_tokens: 943718 + supports_vision: true + supports_function_calling: true + - name: meta/muse-spark-1.2 + type: chat + max_input_tokens: 1048576 + input_price: 1.25 + output_price: 4.25 + max_output_tokens: 943718 + supports_vision: true + supports_function_calling: true + - name: meta/muse-spark-1.2-contributor + type: chat + max_input_tokens: 1048576 + input_price: 0.1 + output_price: 0.2 + max_output_tokens: 943718 + supports_vision: true + supports_function_calling: true + - name: microsoft/phi-4 + type: chat + max_input_tokens: 16384 + input_price: 0.07 + output_price: 0.14 + max_output_tokens: 14745 + - name: microsoft/wizardlm-2-8x22b + type: chat + max_input_tokens: 65535 + input_price: 0.62 + output_price: 0.62 + max_output_tokens: 8000 + - name: minimax/minimax-01 + type: chat + max_input_tokens: 1000192 + input_price: 0.2 + output_price: 1.1 + max_output_tokens: 900172 + supports_vision: true + - name: minimax/minimax-m1 + type: chat + max_input_tokens: 1000000 + input_price: 0.55 + output_price: 2.2 + max_output_tokens: 40000 + supports_function_calling: true + - name: minimax/minimax-m2 + type: chat + max_input_tokens: 204800 + input_price: 0.255 + output_price: 1.02 + max_output_tokens: 131072 + supports_function_calling: true + - name: minimax/minimax-m2-her + type: chat + max_input_tokens: 65536 + input_price: 0.3 + output_price: 1.2 + max_output_tokens: 2048 + - name: minimax/minimax-m2.1 + type: chat + max_input_tokens: 204800 + input_price: 0.3 + output_price: 1.2 + max_output_tokens: 131072 + supports_function_calling: true + - name: minimax/minimax-m2.5 + type: chat + max_input_tokens: 204800 + input_price: 0.27 + output_price: 1.08 + max_output_tokens: 128000 + supports_function_calling: true + - name: minimax/minimax-m2.7 + type: chat + max_input_tokens: 204800 + input_price: 0.3 + output_price: 1.2 + max_output_tokens: 131072 + supports_function_calling: true + - name: minimax/minimax-m2.7:free + type: chat + max_input_tokens: 196608 + input_price: 0.0 + output_price: 0.0 + max_output_tokens: 176947 + supports_function_calling: true + - name: minimax/minimax-m3 + type: chat + max_input_tokens: 1048576 + input_price: 0.3 + output_price: 1.2 + max_output_tokens: 512000 + supports_vision: true + supports_function_calling: true + - name: minimax/minimax-m3:batch + type: chat + max_input_tokens: 524288 + input_price: 0.3 + output_price: 1.2 + max_output_tokens: 471859 + supports_vision: true + supports_function_calling: true + - name: minimax/minimax-m3:free + type: chat + max_input_tokens: 1048576 + input_price: 0.0 + output_price: 0.0 + max_output_tokens: 943718 + supports_vision: true + supports_function_calling: true + - name: mistralai/codestral-2508 + type: chat + max_input_tokens: 256000 + input_price: 0.3 + output_price: 0.9 + max_output_tokens: 204800 + supports_function_calling: true + - name: mistralai/devstral-2512 + type: chat + max_input_tokens: 262144 + input_price: 0.4 + output_price: 2.0 + max_output_tokens: 209715 + supports_function_calling: true + - name: mistralai/ministral-14b-2512 + type: chat + max_input_tokens: 262144 + input_price: 0.2 + output_price: 0.2 + max_output_tokens: 209715 + supports_vision: true + supports_function_calling: true + - name: mistralai/ministral-3b-2512 + type: chat + max_input_tokens: 131072 + input_price: 0.1 + output_price: 0.1 + max_output_tokens: 104857 + supports_vision: true + supports_function_calling: true + - name: mistralai/ministral-8b-2512 + type: chat + max_input_tokens: 262144 + input_price: 0.15 + output_price: 0.15 + max_output_tokens: 209715 + supports_vision: true + supports_function_calling: true + - name: mistralai/mistral-large + type: chat + max_input_tokens: 128000 + input_price: 2.0 + output_price: 6.0 + max_output_tokens: 102400 + supports_function_calling: true + - name: mistralai/mistral-large-2407 + type: chat + max_input_tokens: 131072 + input_price: 2.0 + output_price: 6.0 + max_output_tokens: 104857 + supports_function_calling: true + - name: mistralai/mistral-large-2512 + type: chat + max_input_tokens: 262144 + input_price: 0.5 + output_price: 1.5 + max_output_tokens: 209715 + supports_vision: true + supports_function_calling: true + - name: mistralai/mistral-medium-3 + type: chat + max_input_tokens: 131072 + input_price: 0.4 + output_price: 2.0 + max_output_tokens: 104857 + supports_vision: true + supports_function_calling: true + - name: mistralai/mistral-medium-3-5 + type: chat + max_input_tokens: 262144 + input_price: 1.5 + output_price: 7.5 + max_output_tokens: 209715 + supports_vision: true + supports_function_calling: true + - name: mistralai/mistral-medium-3-5:batch + type: chat + max_input_tokens: 262144 + input_price: 0.75 + output_price: 3.75 + max_output_tokens: 209715 + supports_vision: true + supports_function_calling: true + - name: mistralai/mistral-medium-3.1 + type: chat + max_input_tokens: 131072 + input_price: 0.4 + output_price: 2.0 + max_output_tokens: 104857 + supports_vision: true + supports_function_calling: true + - name: mistralai/mistral-nemo + type: chat + max_input_tokens: 131072 + input_price: 0.019 + output_price: 0.03 + max_output_tokens: 16384 + supports_function_calling: true + - name: mistralai/mistral-saba + type: chat + max_input_tokens: 32768 + input_price: 0.2 + output_price: 0.6 + max_output_tokens: 26214 + supports_function_calling: true + - name: mistralai/mistral-small-24b-instruct-2501 + type: chat + max_input_tokens: 32768 + input_price: 0.05 + output_price: 0.08 + max_output_tokens: 16384 + - name: mistralai/mistral-small-2603 + type: chat + max_input_tokens: 262144 + input_price: 0.15 + output_price: 0.6 + max_output_tokens: 209715 + supports_vision: true + supports_function_calling: true + - name: mistralai/mistral-small-3.1-24b-instruct + type: chat + max_input_tokens: 128000 + input_price: 0.351 + output_price: 0.555 + max_output_tokens: 102400 + supports_vision: true + - name: mistralai/mistral-small-3.2-24b-instruct + type: chat + max_input_tokens: 131072 + input_price: 0.075 + output_price: 0.2 + max_output_tokens: 16384 + supports_vision: true + supports_function_calling: true + - name: mistralai/mixtral-8x22b-instruct + type: chat + max_input_tokens: 65536 + input_price: 2.0 + output_price: 6.0 + max_output_tokens: 52428 + supports_function_calling: true + - name: mistralai/voxtral-small-24b-2507 + type: chat + max_input_tokens: 32768 + input_price: 0.1 + output_price: 0.3 + max_output_tokens: 26214 + supports_function_calling: true + - name: moonshotai/kimi-k2 + type: chat + max_input_tokens: 131072 + input_price: 0.57 + output_price: 2.3 + max_output_tokens: 100352 + supports_function_calling: true + - name: moonshotai/kimi-k2-0905 + type: chat + max_input_tokens: 262144 + input_price: 0.6 + output_price: 2.5 + max_output_tokens: 100352 + supports_function_calling: true + - name: moonshotai/kimi-k2-thinking + type: chat + max_input_tokens: 262144 + input_price: 0.6 + output_price: 2.5 + max_output_tokens: 100352 + supports_function_calling: true + - name: moonshotai/kimi-k2.5 + type: chat + max_input_tokens: 262144 + input_price: 0.45 + output_price: 2.25 + max_output_tokens: 235929 + supports_vision: true + supports_function_calling: true + - name: moonshotai/kimi-k2.6 + type: chat + max_input_tokens: 262144 + input_price: 0.95 + output_price: 4.0 + max_output_tokens: 235929 + supports_vision: true + supports_function_calling: true + - name: moonshotai/kimi-k2.7-code + type: chat + max_input_tokens: 262144 + input_price: 0.66 + output_price: 3.4 + max_output_tokens: 235929 + supports_vision: true + supports_function_calling: true + - name: moonshotai/kimi-k3 + type: chat + max_input_tokens: 1048576 + input_price: 3.0 + output_price: 15.0 + max_output_tokens: 943718 + supports_vision: true + supports_function_calling: true + - name: moonshotai/kimi-k3:batch + type: chat + max_input_tokens: 1048576 + input_price: 3.0 + output_price: 15.0 + max_output_tokens: 943718 + supports_vision: true + supports_function_calling: true + - name: morph/morph-v3-fast + type: chat + max_input_tokens: 81920 + input_price: 0.8 + output_price: 1.2 + max_output_tokens: 38000 + - name: morph/morph-v3-large + type: chat + max_input_tokens: 262144 + input_price: 0.9 + output_price: 1.9 + max_output_tokens: 131072 + - name: nex-agi/nex-n2-mini + type: chat + max_input_tokens: 262144 + input_price: 0.025 + output_price: 0.1 + max_output_tokens: 235929 + supports_vision: true + supports_function_calling: true + - name: nex-agi/nex-n2-pro + type: chat + max_input_tokens: 262144 + input_price: 0.25 + output_price: 1.0 + max_output_tokens: 235929 + supports_vision: true + supports_function_calling: true + - name: nousresearch/hermes-3-llama-3.1-405b + type: chat + max_input_tokens: 131072 + input_price: 1.0 + output_price: 1.0 + max_output_tokens: 16384 + - name: nousresearch/hermes-3-llama-3.1-70b + type: chat + max_input_tokens: 131072 + input_price: 0.7 + output_price: 0.7 + max_output_tokens: 16384 + - name: nousresearch/hermes-4-405b + type: chat + max_input_tokens: 131072 + input_price: 1.0 + output_price: 3.0 + max_output_tokens: 117964 + - name: nousresearch/hermes-4-70b + type: chat + max_input_tokens: 131072 + input_price: 0.13 + output_price: 0.4 + max_output_tokens: 117964 + - name: nvidia/nemotron-3-nano-30b-a3b + type: chat + max_input_tokens: 262144 + input_price: 0.05 + output_price: 0.2 + max_output_tokens: 228000 + supports_function_calling: true + - name: nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free + type: chat + max_input_tokens: 256000 + input_price: 0.0 + output_price: 0.0 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: nvidia/nemotron-3-super-120b-a12b + type: chat + max_input_tokens: 1000000 + input_price: 0.085 + output_price: 0.4 + max_output_tokens: 16384 + supports_function_calling: true + - name: nvidia/nemotron-3-super-120b-a12b:free + type: chat + max_input_tokens: 262144 + input_price: 0.0 + output_price: 0.0 + max_output_tokens: 235929 + supports_function_calling: true + - name: nvidia/nemotron-3-ultra-550b-a55b + type: chat + max_input_tokens: 262144 + input_price: 0.625 + output_price: 3.125 + max_output_tokens: 32768 + supports_function_calling: true + - name: nvidia/nemotron-3-ultra-550b-a55b:batch + type: chat + max_input_tokens: 512288 + input_price: 0.6 + output_price: 3.6 + max_output_tokens: 461059 + supports_function_calling: true + - name: nvidia/nemotron-3-ultra-550b-a55b:free + type: chat + max_input_tokens: 1000000 + input_price: 0.0 + output_price: 0.0 + max_output_tokens: 65536 + supports_function_calling: true + - name: nvidia/nemotron-3.5-content-safety:free + type: chat + max_input_tokens: 128000 + input_price: 0.0 + output_price: 0.0 + max_output_tokens: 8192 + supports_vision: true + - name: nvidia/nemotron-3.5-lightning + type: chat + max_input_tokens: 262144 + input_price: 0.08 + output_price: 0.2 + max_output_tokens: 131072 + supports_function_calling: true + - name: nvidia/nemotron-3.5-lightning:free + type: chat + max_input_tokens: 1000000 + input_price: 0.0 + output_price: 0.0 + max_output_tokens: 65536 + supports_function_calling: true + - name: openai/gpt-3.5-turbo + type: chat + max_input_tokens: 16385 + input_price: 0.5 + output_price: 1.5 + max_output_tokens: 4096 + supports_function_calling: true + - name: openai/gpt-3.5-turbo-0613 + type: chat + max_input_tokens: 4095 + input_price: 1.0 + output_price: 2.0 + max_output_tokens: 3685 + supports_function_calling: true + - name: openai/gpt-3.5-turbo-16k + type: chat + max_input_tokens: 16385 + input_price: 3.0 + output_price: 4.0 + max_output_tokens: 4096 + supports_function_calling: true + - name: openai/gpt-3.5-turbo-instruct + type: chat + max_input_tokens: 4095 + input_price: 1.5 + output_price: 2.0 + max_output_tokens: 3685 + - name: openai/gpt-3.5-turbo:batch + type: chat + max_input_tokens: 16385 + input_price: 0.25 + output_price: 0.75 + max_output_tokens: 4096 + supports_function_calling: true + - name: openai/gpt-4 + type: chat + max_input_tokens: 8191 + input_price: 30.0 + output_price: 60.0 + max_output_tokens: 4096 + supports_function_calling: true + - name: openai/gpt-4-turbo + type: chat + max_input_tokens: 128000 + input_price: 10.0 + output_price: 30.0 + max_output_tokens: 4096 + supports_vision: true + supports_function_calling: true + - name: openai/gpt-4-turbo-preview + type: chat + max_input_tokens: 128000 + input_price: 10.0 + output_price: 30.0 + max_output_tokens: 4096 + supports_function_calling: true + - name: openai/gpt-4-turbo:batch + type: chat + max_input_tokens: 128000 + input_price: 5.0 + output_price: 15.0 + max_output_tokens: 4096 + supports_vision: true + supports_function_calling: true + - name: openai/gpt-4.1 + type: chat + max_input_tokens: 1047576 + input_price: 2.0 + output_price: 8.0 + max_output_tokens: 32768 + supports_vision: true + supports_function_calling: true + - name: openai/gpt-4.1-mini + type: chat + max_input_tokens: 1047576 + input_price: 0.4 + output_price: 1.6 + max_output_tokens: 32768 + supports_vision: true + supports_function_calling: true + - name: openai/gpt-4.1-mini:batch + type: chat + max_input_tokens: 1047576 + input_price: 0.2 + output_price: 0.8 + max_output_tokens: 32768 + supports_vision: true + supports_function_calling: true + - name: openai/gpt-4.1-nano + type: chat + max_input_tokens: 1047576 + input_price: 0.1 + output_price: 0.4 + max_output_tokens: 32768 + supports_vision: true + supports_function_calling: true + - name: openai/gpt-4.1-nano:batch + type: chat + max_input_tokens: 1047576 + input_price: 0.05 + output_price: 0.2 + max_output_tokens: 32768 + supports_vision: true + supports_function_calling: true + - name: openai/gpt-4.1:batch + type: chat + max_input_tokens: 1047576 + input_price: 1.0 + output_price: 4.0 + max_output_tokens: 32768 + supports_vision: true + supports_function_calling: true + - name: openai/gpt-4o + type: chat + max_input_tokens: 128000 + input_price: 2.5 + output_price: 10.0 + max_output_tokens: 16384 + supports_vision: true + supports_function_calling: true + - name: openai/gpt-4o-2024-05-13 + type: chat + max_input_tokens: 128000 + input_price: 5.0 + output_price: 15.0 + max_output_tokens: 4096 + supports_vision: true + supports_function_calling: true + - name: openai/gpt-4o-2024-08-06 + type: chat + max_input_tokens: 128000 + input_price: 2.5 + output_price: 10.0 + max_output_tokens: 16384 + supports_vision: true + supports_function_calling: true + - name: openai/gpt-4o-2024-11-20 + type: chat + max_input_tokens: 128000 + input_price: 2.5 + output_price: 10.0 + max_output_tokens: 16384 + supports_vision: true + supports_function_calling: true + - name: openai/gpt-4o-mini + type: chat + max_input_tokens: 128000 + input_price: 0.15 + output_price: 0.6 + max_output_tokens: 16384 + supports_vision: true + supports_function_calling: true + - name: openai/gpt-4o-mini-2024-07-18 + type: chat + max_input_tokens: 128000 + input_price: 0.15 + output_price: 0.6 + max_output_tokens: 16384 + supports_vision: true + supports_function_calling: true + - name: openai/gpt-4o-mini:batch + type: chat + max_input_tokens: 128000 + input_price: 0.075 + output_price: 0.3 + max_output_tokens: 16384 + supports_vision: true + supports_function_calling: true + - name: openai/gpt-4o:batch + type: chat + max_input_tokens: 128000 + input_price: 1.25 + output_price: 5.0 + max_output_tokens: 16384 + supports_vision: true + supports_function_calling: true + - name: openai/gpt-5 + type: chat + max_input_tokens: 400000 + input_price: 1.25 + output_price: 10.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - minimal + - low + - medium + - high + default_reasoning_effort: medium + - name: openai/gpt-5-image + type: chat + max_input_tokens: 400000 + input_price: 10.0 + output_price: 10.0 + max_output_tokens: 128000 + supports_vision: true + - name: openai/gpt-5-image-mini + type: chat + max_input_tokens: 400000 + input_price: 2.5 + output_price: 2.0 + max_output_tokens: 128000 + supports_vision: true + - name: openai/gpt-5-mini + type: chat + max_input_tokens: 400000 + input_price: 0.25 + output_price: 2.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + - name: openai/gpt-5-mini:batch + type: chat + max_input_tokens: 400000 + input_price: 0.125 + output_price: 1.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + - name: openai/gpt-5-nano + type: chat + max_input_tokens: 400000 + input_price: 0.05 + output_price: 0.4 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + - name: openai/gpt-5-nano:batch + type: chat + max_input_tokens: 400000 + input_price: 0.025 + output_price: 0.2 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + - name: openai/gpt-5-pro + type: chat + max_input_tokens: 400000 + input_price: 15.0 + output_price: 120.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + - name: openai/gpt-5-pro:batch + type: chat + max_input_tokens: 400000 + input_price: 7.5 + output_price: 60.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + - name: openai/gpt-5.1 + type: chat + max_input_tokens: 400000 + input_price: 1.25 + output_price: 10.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + - name: openai/gpt-5.1-codex + type: chat + max_input_tokens: 400000 + input_price: 1.25 + output_price: 10.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + - name: openai/gpt-5.1-codex-max + type: chat + max_input_tokens: 400000 + input_price: 1.25 + output_price: 10.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + - name: openai/gpt-5.1-codex-mini + type: chat + max_input_tokens: 400000 + input_price: 0.25 + output_price: 2.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + - name: openai/gpt-5.1:batch + type: chat + max_input_tokens: 400000 + input_price: 0.625 + output_price: 5.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + - name: openai/gpt-5.2 + type: chat + max_input_tokens: 400000 + input_price: 1.75 + output_price: 14.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + - xhigh + default_reasoning_effort: none + - name: openai/gpt-5.2-chat + type: chat + max_input_tokens: 128000 + input_price: 1.75 + output_price: 14.0 + max_output_tokens: 32000 + supports_vision: true + supports_function_calling: true + - name: openai/gpt-5.2-codex + type: chat + max_input_tokens: 400000 + input_price: 1.75 + output_price: 14.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + - name: openai/gpt-5.2-pro + type: chat + max_input_tokens: 400000 + input_price: 21.0 + output_price: 168.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - medium + - high + - xhigh + default_reasoning_effort: medium + - name: openai/gpt-5.2-pro:batch + type: chat + max_input_tokens: 400000 + input_price: 10.5 + output_price: 84.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + - name: openai/gpt-5.2:batch + type: chat + max_input_tokens: 400000 + input_price: 0.875 + output_price: 7.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + - name: openai/gpt-5.3-codex + type: chat + max_input_tokens: 400000 + input_price: 1.75 + output_price: 14.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + default_reasoning_effort: medium + - name: openai/gpt-5.4 + type: chat + max_input_tokens: 1050000 + input_price: 2.5 + output_price: 15.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + - xhigh + default_reasoning_effort: none + - name: openai/gpt-5.4-image-2 + type: chat + max_input_tokens: 272000 + input_price: 8.0 + output_price: 15.0 + max_output_tokens: 128000 + supports_vision: true + - name: openai/gpt-5.4-mini + type: chat + max_input_tokens: 400000 + input_price: 0.75 + output_price: 4.5 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + - xhigh + default_reasoning_effort: none + - name: openai/gpt-5.4-mini:batch + type: chat + max_input_tokens: 400000 + input_price: 0.375 + output_price: 2.25 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + - name: openai/gpt-5.4-nano + type: chat + max_input_tokens: 400000 + input_price: 0.2 + output_price: 1.25 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + - xhigh + default_reasoning_effort: none + - name: openai/gpt-5.4-nano:batch + type: chat + max_input_tokens: 400000 + input_price: 0.1 + output_price: 0.625 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + - name: openai/gpt-5.4-pro + type: chat + max_input_tokens: 1050000 + input_price: 30.0 + output_price: 180.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - medium + - high + - xhigh + default_reasoning_effort: medium + - name: openai/gpt-5.4-pro:batch + type: chat + max_input_tokens: 1050000 + input_price: 15.0 + output_price: 90.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + - name: openai/gpt-5.4:batch + type: chat + max_input_tokens: 1050000 + input_price: 1.25 + output_price: 7.5 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + - name: openai/gpt-5.5 + type: chat + max_input_tokens: 1050000 + input_price: 5.0 + output_price: 30.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + - xhigh + default_reasoning_effort: medium + - name: openai/gpt-5.5-pro + type: chat + max_input_tokens: 1050000 + input_price: 30.0 + output_price: 180.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - medium + - high + - xhigh + default_reasoning_effort: high + - name: openai/gpt-5.5-pro:batch + type: chat + max_input_tokens: 1050000 + input_price: 15.0 + output_price: 90.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + - name: openai/gpt-5.5:batch + type: chat + max_input_tokens: 1050000 + input_price: 2.5 + output_price: 15.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + - name: openai/gpt-5.6-luna + type: chat + max_input_tokens: 1050000 + input_price: 0.2 + output_price: 1.2 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: medium + - name: openai/gpt-5.6-luna-pro + type: chat + max_input_tokens: 1050000 + input_price: 0.2 + output_price: 1.2 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: medium + - name: openai/gpt-5.6-luna-pro:batch + type: chat + max_input_tokens: 1050000 + input_price: 0.1 + output_price: 0.6 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: medium + - name: openai/gpt-5.6-luna:batch + type: chat + max_input_tokens: 1050000 + input_price: 0.1 + output_price: 0.6 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: medium + - name: openai/gpt-5.6-sol + type: chat + max_input_tokens: 1050000 + input_price: 2.0 + output_price: 10.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: medium + - name: openai/gpt-5.6-sol-pro + type: chat + max_input_tokens: 1050000 + input_price: 2.0 + output_price: 10.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: medium + - name: openai/gpt-5.6-sol-pro:batch + type: chat + max_input_tokens: 1050000 + input_price: 1.0 + output_price: 5.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: medium + - name: openai/gpt-5.6-sol:batch + type: chat + max_input_tokens: 1050000 + input_price: 1.0 + output_price: 5.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: medium + - name: openai/gpt-5.6-terra + type: chat + max_input_tokens: 1050000 + input_price: 2.0 + output_price: 12.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: medium + - name: openai/gpt-5.6-terra-pro + type: chat + max_input_tokens: 1050000 + input_price: 2.0 + output_price: 12.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: medium + - name: openai/gpt-5.6-terra-pro:batch + type: chat + max_input_tokens: 1050000 + input_price: 1.0 + output_price: 6.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: medium + - name: openai/gpt-5.6-terra:batch + type: chat + max_input_tokens: 1050000 + input_price: 1.0 + output_price: 6.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + - xhigh + - max + default_reasoning_effort: medium + - name: openai/gpt-5:batch + type: chat + max_input_tokens: 400000 + input_price: 0.625 + output_price: 5.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + - name: openai/gpt-audio + type: chat + max_input_tokens: 128000 + input_price: 2.5 + output_price: 10.0 + max_output_tokens: 16384 + supports_function_calling: true + - name: openai/gpt-audio-mini + type: chat + max_input_tokens: 128000 + input_price: 0.6 + output_price: 2.4 + max_output_tokens: 16384 + supports_function_calling: true + - name: openai/gpt-chat-latest + type: chat + max_input_tokens: 400000 + input_price: 5.0 + output_price: 30.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + - name: openai/gpt-oss-120b + type: chat + max_input_tokens: 131072 + input_price: 0.037 + output_price: 0.17 + max_output_tokens: 117964 + supports_function_calling: true + - name: openai/gpt-oss-120b:batch + type: chat + max_input_tokens: 131072 + input_price: 0.15 + output_price: 0.6 + max_output_tokens: 117964 + supports_function_calling: true + - name: openai/gpt-oss-20b + type: chat + max_input_tokens: 131072 + input_price: 0.03 + output_price: 0.13 + max_output_tokens: 117964 + supports_function_calling: true + - name: openai/gpt-oss-20b:batch + type: chat + max_input_tokens: 131072 + input_price: 0.05 + output_price: 0.2 + max_output_tokens: 117964 + - name: openai/gpt-oss-safeguard-20b + type: chat + max_input_tokens: 131072 + input_price: 0.075 + output_price: 0.3 + max_output_tokens: 65536 + supports_function_calling: true + - name: openai/o1 + type: chat + max_input_tokens: 200000 + input_price: 15.0 + output_price: 60.0 + max_output_tokens: 100000 + supports_vision: true + supports_function_calling: true + - name: openai/o1-pro + type: chat + max_input_tokens: 200000 + input_price: 150.0 + output_price: 600.0 + max_output_tokens: 100000 + supports_vision: true + - name: openai/o3 + type: chat + max_input_tokens: 200000 + input_price: 2.0 + output_price: 8.0 + max_output_tokens: 100000 + supports_vision: true + supports_function_calling: true + - name: openai/o3-mini + type: chat + max_input_tokens: 200000 + input_price: 1.1 + output_price: 4.4 + max_output_tokens: 100000 + supports_function_calling: true + - name: openai/o3-mini-high + type: chat + max_input_tokens: 200000 + input_price: 1.1 + output_price: 4.4 + max_output_tokens: 100000 + supports_function_calling: true + - name: openai/o3-mini:batch + type: chat + max_input_tokens: 200000 + input_price: 0.55 + output_price: 2.2 + max_output_tokens: 100000 + supports_function_calling: true + - name: openai/o3-pro + type: chat + max_input_tokens: 200000 + input_price: 20.0 + output_price: 80.0 + max_output_tokens: 100000 + supports_vision: true + supports_function_calling: true + - name: openai/o3:batch + type: chat + max_input_tokens: 200000 + input_price: 1.0 + output_price: 4.0 + max_output_tokens: 100000 + supports_vision: true + supports_function_calling: true + - name: openai/o4-mini + type: chat + max_input_tokens: 200000 + input_price: 1.1 + output_price: 4.4 + max_output_tokens: 100000 + supports_vision: true + supports_function_calling: true + - name: openai/o4-mini-high + type: chat + max_input_tokens: 200000 + input_price: 1.1 + output_price: 4.4 + max_output_tokens: 100000 + supports_vision: true + supports_function_calling: true + - name: openai/o4-mini:batch + type: chat + max_input_tokens: 200000 + input_price: 0.55 + output_price: 2.2 + max_output_tokens: 100000 + supports_vision: true + supports_function_calling: true + - name: openrouter/auto + type: chat + max_input_tokens: 2000000 + supports_vision: true + supports_function_calling: true + - name: openrouter/auto-beta + type: chat + max_input_tokens: 2000000 + supports_vision: true + supports_function_calling: true + - name: openrouter/bodybuilder + type: chat + max_input_tokens: 128000 + - name: openrouter/free + type: chat + max_input_tokens: 200000 + input_price: 0.0 + output_price: 0.0 + supports_vision: true + supports_function_calling: true + - name: openrouter/fusion + type: chat + max_input_tokens: 1000000 + - name: openrouter/pareto-code + type: chat + max_input_tokens: 2000000 + - name: perceptron/perceptron-mk1 + type: chat + max_input_tokens: 32768 + input_price: 0.15 + output_price: 1.5 + max_output_tokens: 8192 + supports_vision: true + - name: perplexity/sonar + type: chat + max_input_tokens: 127072 + input_price: 1.0 + output_price: 1.0 + max_output_tokens: 114364 + supports_vision: true + - name: perplexity/sonar-deep-research + type: chat + max_input_tokens: 128000 + input_price: 2.0 + output_price: 8.0 + patch: + body: + include_reasoning: true + max_output_tokens: 115200 + - name: perplexity/sonar-pro + type: chat + max_input_tokens: 200000 + input_price: 3.0 + output_price: 15.0 + max_output_tokens: 8000 + supports_vision: true + - name: perplexity/sonar-pro-search + type: chat + max_input_tokens: 200000 + input_price: 3.0 + output_price: 15.0 + max_output_tokens: 8000 + supports_vision: true + - name: perplexity/sonar-reasoning-pro + type: chat + max_input_tokens: 128000 + input_price: 2.0 + output_price: 8.0 + patch: + body: + include_reasoning: true + max_output_tokens: 115200 + supports_vision: true + - name: poolside/laguna-s-2.1 + type: chat + max_input_tokens: 1048576 + input_price: 0.09 + output_price: 0.18 + max_output_tokens: 131072 + supports_function_calling: true + - name: poolside/laguna-s-2.1:free + type: chat + max_input_tokens: 262144 + input_price: 0.0 + output_price: 0.0 + max_output_tokens: 32768 + supports_function_calling: true + - name: poolside/laguna-xs-2.1 + type: chat + max_input_tokens: 262144 + input_price: 0.06 + output_price: 0.12 + max_output_tokens: 32768 + supports_function_calling: true + - name: poolside/laguna-xs-2.1:free + type: chat + max_input_tokens: 262144 + input_price: 0.0 + output_price: 0.0 + max_output_tokens: 32768 + supports_function_calling: true + - name: qwen/qwen-2.5-72b-instruct + type: chat + max_input_tokens: 32768 + input_price: 0.36 + output_price: 0.4 + max_output_tokens: 16384 + supports_function_calling: true + - name: qwen/qwen-2.5-7b-instruct + type: chat + max_input_tokens: 32768 + input_price: 0.1 + output_price: 0.2 + max_output_tokens: 29491 + supports_function_calling: true + - name: qwen/qwen-2.5-coder-32b-instruct + type: chat + max_input_tokens: 32768 + input_price: 0.66 + output_price: 1.0 + max_output_tokens: 29491 + - name: qwen/qwen-plus + type: chat + max_input_tokens: 1000000 + input_price: 0.26 + output_price: 0.78 + max_output_tokens: 32768 + supports_function_calling: true + - name: qwen/qwen-plus-2025-07-28 + type: chat + max_input_tokens: 1000000 + input_price: 0.26 + output_price: 0.78 + max_output_tokens: 32768 + supports_function_calling: true + - name: qwen/qwen2.5-vl-72b-instruct + type: chat + max_input_tokens: 128000 + input_price: 0.25 + output_price: 0.75 + max_output_tokens: 28800 + supports_vision: true + - name: qwen/qwen3-14b + type: chat + max_input_tokens: 131072 + input_price: 0.12 + output_price: 0.24 + max_output_tokens: 16384 + supports_function_calling: true + - name: qwen/qwen3-235b-a22b + type: chat + max_input_tokens: 131072 + input_price: 0.455 + output_price: 1.82 + max_output_tokens: 8192 + supports_function_calling: true + - name: qwen/qwen3-235b-a22b-2507 + type: chat + max_input_tokens: 262144 + input_price: 0.0875 + output_price: 0.35 + max_output_tokens: 235929 + supports_function_calling: true + - name: qwen/qwen3-235b-a22b-thinking-2507 + type: chat + max_input_tokens: 131072 + input_price: 0.23 + output_price: 2.3 + max_output_tokens: 117964 + supports_function_calling: true + - name: qwen/qwen3-30b-a3b + type: chat + max_input_tokens: 131072 + input_price: 0.12 + output_price: 0.5 + max_output_tokens: 16384 + supports_function_calling: true + - name: qwen/qwen3-30b-a3b-instruct-2507 + type: chat + max_input_tokens: 262144 + input_price: 0.0482 + output_price: 0.1931 + max_output_tokens: 32000 + supports_function_calling: true + - name: qwen/qwen3-30b-a3b-thinking-2507 + type: chat + max_input_tokens: 81920 + input_price: 0.2 + output_price: 2.4 + max_output_tokens: 32768 + supports_function_calling: true + - name: qwen/qwen3-32b + type: chat + max_input_tokens: 131072 + input_price: 0.08 + output_price: 0.28 + max_output_tokens: 16384 + supports_function_calling: true + - name: qwen/qwen3-8b + type: chat + max_input_tokens: 131072 + input_price: 0.117 + output_price: 0.455 + max_output_tokens: 8192 + supports_function_calling: true + - name: qwen/qwen3-coder + type: chat + max_input_tokens: 262144 + input_price: 0.3 + output_price: 1.0 + max_output_tokens: 65536 + supports_function_calling: true + - name: qwen/qwen3-coder-30b-a3b-instruct + type: chat + max_input_tokens: 262144 + input_price: 0.07 + output_price: 0.28 + max_output_tokens: 235929 + supports_function_calling: true + - name: qwen/qwen3-coder-flash + type: chat + max_input_tokens: 1000000 + input_price: 0.195 + output_price: 0.975 + max_output_tokens: 65536 + supports_function_calling: true + - name: qwen/qwen3-coder-next + type: chat + max_input_tokens: 262144 + input_price: 0.12 + output_price: 0.8 + max_output_tokens: 235929 + supports_function_calling: true + - name: qwen/qwen3-coder-plus + type: chat + max_input_tokens: 1000000 + input_price: 0.65 + output_price: 3.25 + max_output_tokens: 65536 + supports_function_calling: true + - name: qwen/qwen3-max + type: chat + max_input_tokens: 262144 + input_price: 0.78 + output_price: 3.9 + max_output_tokens: 65536 + supports_function_calling: true + - name: qwen/qwen3-max-thinking + type: chat + max_input_tokens: 262144 + input_price: 0.78 + output_price: 3.9 + max_output_tokens: 65536 + supports_function_calling: true + - name: qwen/qwen3-next-80b-a3b-instruct + type: chat + max_input_tokens: 262144 + input_price: 0.1 + output_price: 1.1 + max_output_tokens: 235929 + supports_function_calling: true + - name: qwen/qwen3-next-80b-a3b-thinking + type: chat + max_input_tokens: 262144 + input_price: 0.15 + output_price: 1.2 + max_output_tokens: 32768 + supports_function_calling: true + - name: qwen/qwen3-vl-235b-a22b-instruct + type: chat + max_input_tokens: 262144 + input_price: 0.21 + output_price: 1.9 + max_output_tokens: 32768 + supports_vision: true + supports_function_calling: true + - name: qwen/qwen3-vl-235b-a22b-thinking + type: chat + max_input_tokens: 131072 + input_price: 0.4 + output_price: 4.0 + max_output_tokens: 32768 + supports_vision: true + supports_function_calling: true + - name: qwen/qwen3-vl-30b-a3b-instruct + type: chat + max_input_tokens: 262144 + input_price: 0.15 + output_price: 0.6 + max_output_tokens: 16384 + supports_vision: true + supports_function_calling: true + - name: qwen/qwen3-vl-30b-a3b-thinking + type: chat + max_input_tokens: 262144 + input_price: 0.2 + output_price: 2.4 + max_output_tokens: 32768 + supports_vision: true + supports_function_calling: true + - name: qwen/qwen3-vl-32b-instruct + type: chat + max_input_tokens: 131072 + input_price: 0.104 + output_price: 0.416 + max_output_tokens: 32768 + supports_vision: true + supports_function_calling: true + - name: qwen/qwen3-vl-8b-instruct + type: chat + max_input_tokens: 262144 + input_price: 0.117 + output_price: 0.455 + max_output_tokens: 32768 + supports_vision: true + supports_function_calling: true + - name: qwen/qwen3-vl-8b-thinking + type: chat + max_input_tokens: 131072 + input_price: 0.18 + output_price: 2.1 + max_output_tokens: 32768 + supports_vision: true + supports_function_calling: true + - name: qwen/qwen3.5-122b-a10b + type: chat + max_input_tokens: 262144 + input_price: 0.29 + output_price: 2.4 + max_output_tokens: 81920 + supports_vision: true + supports_function_calling: true + - name: qwen/qwen3.5-27b + type: chat + max_input_tokens: 262144 + input_price: 0.195 + output_price: 1.56 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: qwen/qwen3.5-35b-a3b + type: chat + max_input_tokens: 262144 + input_price: 0.25 + output_price: 1.25 + max_output_tokens: 235929 + supports_vision: true + supports_function_calling: true + - name: qwen/qwen3.5-397b-a17b + type: chat + max_input_tokens: 262144 + input_price: 0.39 + output_price: 2.34 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: qwen/qwen3.5-9b + type: chat + max_input_tokens: 262144 + input_price: 0.1 + output_price: 0.15 + max_output_tokens: 235929 + supports_vision: true + supports_function_calling: true + - name: qwen/qwen3.5-9b:batch + type: chat + max_input_tokens: 262144 + input_price: 0.17 + output_price: 0.25 + max_output_tokens: 235929 + supports_vision: true + supports_function_calling: true + - name: qwen/qwen3.5-flash-02-23 + type: chat + max_input_tokens: 1000000 + input_price: 0.065 + output_price: 0.26 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: qwen/qwen3.5-plus-02-15 + type: chat + max_input_tokens: 1000000 + input_price: 0.26 + output_price: 1.56 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: qwen/qwen3.5-plus-20260420 + type: chat + max_input_tokens: 1000000 + input_price: 0.3 + output_price: 1.8 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: qwen/qwen3.6-27b + type: chat + max_input_tokens: 262144 + input_price: 0.6 + output_price: 3.6 + max_output_tokens: 235929 + supports_vision: true + supports_function_calling: true + - name: qwen/qwen3.6-35b-a3b + type: chat + max_input_tokens: 262144 + input_price: 0.1 + output_price: 0.9 + max_output_tokens: 235929 + supports_vision: true + supports_function_calling: true + - name: qwen/qwen3.6-flash + type: chat + max_input_tokens: 1000000 + input_price: 0.1875 + output_price: 1.125 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: qwen/qwen3.6-max-preview + type: chat + max_input_tokens: 262144 + input_price: 1.027 + output_price: 6.162 + max_output_tokens: 65536 + supports_function_calling: true + - name: qwen/qwen3.6-plus + type: chat + max_input_tokens: 1000000 + input_price: 0.325 + output_price: 1.95 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: qwen/qwen3.7-flash + type: chat + max_input_tokens: 1000000 + input_price: 0.03 + output_price: 0.13 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: qwen/qwen3.7-max + type: chat + max_input_tokens: 1000000 + input_price: 1.475 + output_price: 4.425 + max_output_tokens: 131072 + supports_function_calling: true + - name: qwen/qwen3.7-plus + type: chat + max_input_tokens: 1000000 + input_price: 0.32 + output_price: 1.28 + max_output_tokens: 131072 + supports_vision: true + supports_function_calling: true + - name: qwen/qwen3.8-2.4t-a95b + type: chat + max_input_tokens: 1048576 + input_price: 2.0 + output_price: 6.0 + max_output_tokens: 131072 + supports_function_calling: true + - name: qwen/qwen3.8-2.4t-a95b:batch + type: chat + max_input_tokens: 1010000 + input_price: 2.0 + output_price: 6.0 + max_output_tokens: 909000 + supports_function_calling: true + - name: qwen/qwen3.8-27b + type: chat + max_input_tokens: 1000000 + input_price: 0.425 + output_price: 2.55 + max_output_tokens: 131072 + supports_vision: true + supports_function_calling: true + - name: qwen/qwen3.8-flash + type: chat + max_input_tokens: 1000000 + input_price: 0.15 + output_price: 0.47 + max_output_tokens: 131072 + supports_vision: true + supports_function_calling: true + - name: qwen/qwen3.8-max + type: chat + max_input_tokens: 1000000 + input_price: 2.0 + output_price: 6.0 + max_output_tokens: 131072 + supports_vision: true + supports_function_calling: true + - name: rekaai/reka-edge + type: chat + max_input_tokens: 16384 + input_price: 0.1 + output_price: 0.1 + max_output_tokens: 14745 + supports_vision: true + supports_function_calling: true + - name: rekaai/reka-flash-3 + type: chat + max_input_tokens: 65536 + input_price: 0.1 + output_price: 0.2 + max_output_tokens: 58982 + - name: relace/relace-apply-3 + type: chat + max_input_tokens: 256000 + input_price: 0.85 + output_price: 1.25 + max_output_tokens: 128000 + - name: relace/relace-search + type: chat + max_input_tokens: 256000 + input_price: 1.0 + output_price: 3.0 + max_output_tokens: 128000 + supports_function_calling: true + - name: sakana/fugu-ultra + type: chat + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 30.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + - name: sakana/sakana-namazu + type: chat + max_input_tokens: 262144 + input_price: 0.95 + output_price: 4.0 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: sao10k/l3-lunaris-8b + type: chat + max_input_tokens: 8192 + input_price: 0.04 + output_price: 0.05 + max_output_tokens: 7372 + - name: sao10k/l3.1-euryale-70b + type: chat + max_input_tokens: 131072 + input_price: 0.85 + output_price: 0.85 + max_output_tokens: 16384 + supports_function_calling: true + - name: sao10k/l3.3-euryale-70b + type: chat + max_input_tokens: 131072 + input_price: 0.65 + output_price: 0.75 + max_output_tokens: 16384 + - name: stepfun/step-3.5-flash + type: chat + max_input_tokens: 262144 + input_price: 0.1 + output_price: 0.3 + max_output_tokens: 65536 + supports_function_calling: true + - name: stepfun/step-3.7-flash + type: chat + max_input_tokens: 262144 + input_price: 0.2 + output_price: 1.15 + max_output_tokens: 230400 + supports_vision: true + supports_function_calling: true + - name: tencent/hunyuan-a13b-instruct + type: chat + max_input_tokens: 131072 + input_price: 0.14 + output_price: 0.57 + max_output_tokens: 117964 + - name: tencent/hy-mt2-1.8b + type: chat + max_input_tokens: 8192 + input_price: 0.044 + output_price: 0.177 + max_output_tokens: 4096 + - name: tencent/hy-mt2-30b-a3b + type: chat + max_input_tokens: 8192 + input_price: 0.074 + output_price: 0.295 + max_output_tokens: 4096 + - name: tencent/hy-mt2-7b + type: chat + max_input_tokens: 8192 + input_price: 0.074 + output_price: 0.295 + max_output_tokens: 4096 + - name: tencent/hy3 + type: chat + max_input_tokens: 262144 + input_price: 0.0825 + output_price: 0.33 + max_output_tokens: 128000 + supports_function_calling: true + - name: tencent/hy3-preview + type: chat + max_input_tokens: 262144 + input_price: 0.18 + output_price: 0.6 + max_output_tokens: 235929 + supports_function_calling: true + - name: tencent/hy4-preview + type: chat + max_input_tokens: 1048576 + input_price: 0.834 + output_price: 2.501 + max_output_tokens: 64000 + supports_function_calling: true + - name: thedrummer/cydonia-24b-v4.1 + type: chat + max_input_tokens: 131072 + input_price: 0.3 + output_price: 0.5 + max_output_tokens: 117964 + - name: thedrummer/skyfall-36b-v2 + type: chat + max_input_tokens: 32768 + input_price: 0.55 + output_price: 0.8 + max_output_tokens: 29491 + - name: thedrummer/unslopnemo-12b + type: chat + max_input_tokens: 1024000 + input_price: 0.4 + output_price: 0.4 + max_output_tokens: 26214 + supports_function_calling: true + - name: thinkingmachines/inkling + type: chat + max_input_tokens: 1048576 + input_price: 1.0 + output_price: 4.05 + max_output_tokens: 471859 + supports_vision: true + supports_function_calling: true + - name: thinkingmachines/inkling-small + type: chat + max_input_tokens: 1048576 + input_price: 0.45 + output_price: 1.2 + max_output_tokens: 262144 + supports_vision: true + supports_function_calling: true + - name: thinkingmachines/inkling-small:batch + type: chat + max_input_tokens: 524288 + input_price: 0.5 + output_price: 1.2 + max_output_tokens: 471859 + supports_vision: true + supports_function_calling: true + - name: thinkingmachines/inkling-small:free + type: chat + max_input_tokens: 1048576 + input_price: 0.0 + output_price: 0.0 + max_output_tokens: 262144 + supports_vision: true + supports_function_calling: true + - name: thinkingmachines/inkling:batch + type: chat + max_input_tokens: 524288 + input_price: 1.0 + output_price: 4.05 + max_output_tokens: 471859 + supports_vision: true + supports_function_calling: true + - name: thinkingmachines/inkling:free + type: chat + max_input_tokens: 1048576 + input_price: 0.0 + output_price: 0.0 + max_output_tokens: 262144 + supports_vision: true + supports_function_calling: true + - name: undi95/remm-slerp-l2-13b + type: chat + max_input_tokens: 6144 + input_price: 0.45 + output_price: 0.65 + max_output_tokens: 4096 + - name: upstage/solar-pro-3 + type: chat + max_input_tokens: 131072 + input_price: 0.15 + output_price: 0.6 + max_output_tokens: 117964 + supports_function_calling: true + - name: upstage/solar-pro4 + type: chat + max_input_tokens: 524288 + input_price: 0.03 + output_price: 0.12 + max_output_tokens: 131072 + supports_function_calling: true + - name: writer/palmyra-x5 + type: chat + max_input_tokens: 1040000 + input_price: 0.6 + output_price: 6.0 + max_output_tokens: 8192 + - name: x-ai/grok-4.20 + type: chat + max_input_tokens: 2000000 + input_price: 1.25 + output_price: 2.5 + max_output_tokens: 1800000 + supports_vision: true + supports_function_calling: true + - name: x-ai/grok-4.20-multi-agent + type: chat + max_input_tokens: 2000000 + input_price: 1.25 + output_price: 2.5 + max_output_tokens: 1800000 + supports_vision: true + - name: x-ai/grok-4.3 + type: chat + max_input_tokens: 1000000 + input_price: 1.25 + output_price: 2.5 + max_output_tokens: 900000 + supports_vision: true + supports_function_calling: true + - name: x-ai/grok-4.5 + type: chat + max_input_tokens: 500000 + input_price: 2.0 + output_price: 6.0 + max_output_tokens: 450000 + supports_vision: true + supports_function_calling: true + - name: x-ai/grok-4.6 + type: chat + max_input_tokens: 500000 + input_price: 2.0 + output_price: 6.0 + max_output_tokens: 450000 + supports_vision: true + supports_function_calling: true + - name: x-ai/grok-build-0.1 + type: chat + max_input_tokens: 256000 + input_price: 1.0 + output_price: 2.0 + max_output_tokens: 230400 + supports_vision: true + supports_function_calling: true + - name: xiaomi/mimo-v2.5 + type: chat + max_input_tokens: 1050000 + input_price: 0.14 + output_price: 0.28 + max_output_tokens: 131072 + supports_vision: true + supports_function_calling: true + - name: xiaomi/mimo-v2.5-pro + type: chat + max_input_tokens: 1050000 + input_price: 0.435 + output_price: 0.87 + max_output_tokens: 131072 + supports_function_calling: true + - name: z-ai/glm-4.5 + type: chat + max_input_tokens: 131072 + input_price: 0.6 + output_price: 2.2 + max_output_tokens: 98304 + supports_function_calling: true + - name: z-ai/glm-4.5-air + type: chat + max_input_tokens: 131072 + input_price: 0.13 + output_price: 0.85 + max_output_tokens: 98304 + supports_function_calling: true + - name: z-ai/glm-4.5v + type: chat + max_input_tokens: 65536 + input_price: 0.6 + output_price: 1.8 + max_output_tokens: 16384 + supports_vision: true + supports_function_calling: true + - name: z-ai/glm-4.6 + type: chat + max_input_tokens: 204800 + input_price: 0.43 + output_price: 1.75 + max_output_tokens: 16384 + supports_function_calling: true + - name: z-ai/glm-4.6v + type: chat + max_input_tokens: 131072 + input_price: 0.3 + output_price: 0.9 + max_output_tokens: 32768 + supports_vision: true + supports_function_calling: true + - name: z-ai/glm-4.7 + type: chat + max_input_tokens: 204800 + input_price: 0.4 + output_price: 1.75 + max_output_tokens: 131072 + supports_function_calling: true + - name: z-ai/glm-4.7-flash + type: chat + max_input_tokens: 202752 + input_price: 0.06 + output_price: 0.4 + max_output_tokens: 16384 + supports_function_calling: true + - name: z-ai/glm-5 + type: chat + max_input_tokens: 204800 + input_price: 0.6 + output_price: 1.92 + max_output_tokens: 128000 + supports_function_calling: true + - name: z-ai/glm-5-turbo + type: chat + max_input_tokens: 202752 + input_price: 1.2 + output_price: 4.0 + max_output_tokens: 131072 + supports_function_calling: true + - name: z-ai/glm-5.1 + type: chat + max_input_tokens: 204800 + input_price: 0.966 + output_price: 3.036 + max_output_tokens: 128000 + supports_function_calling: true + - name: z-ai/glm-5.2 + type: chat + max_input_tokens: 1048576 + input_price: 0.966 + output_price: 3.036 + max_output_tokens: 131072 + supports_function_calling: true + - name: z-ai/glm-5.2:free + type: chat + max_input_tokens: 256000 + input_price: 0.0 + output_price: 0.0 + max_output_tokens: 230400 + supports_function_calling: true + - name: z-ai/glm-5.3 + type: chat + max_input_tokens: 1310720 + input_price: 1.4 + output_price: 4.4 + max_output_tokens: 131072 + supports_function_calling: true + - name: z-ai/glm-5.3-flash + type: chat + max_input_tokens: 1310720 + input_price: 0.075 + output_price: 0.25 + max_output_tokens: 131072 + supports_vision: true + supports_function_calling: true + - name: z-ai/glm-5.3-flash:batch + type: chat + max_input_tokens: 1048575 + input_price: 0.15 + output_price: 0.5 + max_output_tokens: 943717 + supports_vision: true + supports_function_calling: true + - name: z-ai/glm-5v-turbo + type: chat + max_input_tokens: 202752 + input_price: 1.2 + output_price: 4.0 + max_output_tokens: 131072 + supports_vision: true + supports_function_calling: true + - name: ~anthropic/claude-fable-latest + type: chat + max_input_tokens: 1000000 + input_price: 10.0 + output_price: 50.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + - name: ~anthropic/claude-haiku-latest + type: chat + max_input_tokens: 200000 + input_price: 1.0 + output_price: 5.0 + max_output_tokens: 64000 + supports_vision: true + supports_function_calling: true + - name: ~anthropic/claude-opus-latest + type: chat + max_input_tokens: 1000000 + input_price: 5.0 + output_price: 25.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + - name: ~anthropic/claude-sonnet-latest + type: chat + max_input_tokens: 1000000 + input_price: 2.0 + output_price: 10.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + - name: ~deepseek/deepseek-v4-flash-latest + type: chat + max_input_tokens: 1310720 + input_price: 0.05 + output_price: 0.16 + max_output_tokens: 393216 + supports_function_calling: true + - name: ~google/gemini-flash-latest + type: chat + max_input_tokens: 1048576 + input_price: 0.75 + output_price: 3.75 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: ~google/gemini-pro-latest + type: chat + max_input_tokens: 1048576 + input_price: 2.0 + output_price: 12.0 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: ~moonshotai/kimi-latest + type: chat + max_input_tokens: 1048576 + input_price: 2.55 + output_price: 12.75 + max_output_tokens: 943718 + supports_vision: true + supports_function_calling: true + - name: ~openai/gpt-latest + type: chat + max_input_tokens: 1050000 + input_price: 2.0 + output_price: 10.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + - name: ~openai/gpt-mini-latest + type: chat + max_input_tokens: 400000 + input_price: 0.75 + output_price: 4.5 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + - name: ~x-ai/grok-latest + type: chat + max_input_tokens: 500000 + input_price: 2.0 + output_price: 6.0 + max_output_tokens: 450000 + supports_vision: true + supports_function_calling: true + - name: ~z-ai/glm-flash-latest + type: chat + max_input_tokens: 1310720 + input_price: 0.075 + output_price: 0.25 + max_output_tokens: 131072 + supports_vision: true + supports_function_calling: true + - name: ~z-ai/glm-latest + type: chat + max_input_tokens: 1310720 + input_price: 1.15 + output_price: 3.5 + max_output_tokens: 235929 + supports_function_calling: true - provider: github models: - - name: gpt-5 - max_input_tokens: 400000 - max_output_tokens: 128000 - supports_vision: true - supports_function_calling: true - - name: gpt-5-mini - max_input_tokens: 400000 - max_output_tokens: 128000 - supports_vision: true - supports_function_calling: true - - name: gpt-5-nano - max_input_tokens: 400000 - max_output_tokens: 128000 - supports_vision: true - supports_function_calling: true - - name: gpt-4.1 - max_input_tokens: 1047576 - max_output_tokens: 32768 - supports_vision: true - supports_function_calling: true - - name: gpt-4o - max_input_tokens: 128000 - max_output_tokens: 16384 - supports_function_calling: true - - name: text-embedding-3-large - type: embedding - max_tokens_per_chunk: 8191 - default_chunk_size: 2000 - max_batch_size: 100 - - name: text-embedding-3-small - type: embedding - max_tokens_per_chunk: 8191 - default_chunk_size: 2000 - max_batch_size: 100 - - name: llama-4-maverick-17b-128e-instruct-fp8 - max_input_tokens: 1048576 - supports_vision: true - - name: llama-4-scout-17b-16e-instruct - max_input_tokens: 327680 - supports_vision: true - - name: llama-3.3-70b-instruct - max_input_tokens: 131072 - - name: mistral-medium-2505 - max_input_tokens: 131072 - supports_function_calling: true - - name: mistral-small-2503 - max_input_tokens: 131072 - supports_function_calling: true - - name: codestral-2501 - max_input_tokens: 256000 - supports_function_calling: true - - name: cohere-embed-v3-english - type: embedding - max_tokens_per_chunk: 512 - default_chunk_size: 1000 - max_batch_size: 96 - - name: cohere-embed-v3-multilingual - type: embedding - max_tokens_per_chunk: 512 - default_chunk_size: 1000 - max_batch_size: 96 - - name: deepseek-r1-0528 - max_input_tokens: 163840 - - name: deepseek-v3-0324 - max_input_tokens: 163840 - - name: mai-ds-r1 - max_input_tokens: 163840 - - name: phi-4 - max_input_tokens: 16384 - - name: phi-4-mini-instruct - max_input_tokens: 131072 - - name: phi-4-reasoning - max_input_tokens: 33792 - - name: phi-4-mini-reasoning - max_input_tokens: 131072 - - name: grok-3 - max_input_tokens: 131072 - - name: grok-3-mini - max_input_tokens: 131072 - -# Links: -# - https://deepinfra.com/models -# - https://deepinfra.com/docs/openai_api + - name: gpt-5 + type: chat + max_input_tokens: 400000 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + - name: gpt-5-mini + type: chat + max_input_tokens: 400000 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + - name: gpt-5-nano + type: chat + max_input_tokens: 400000 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + - name: gpt-4.1 + type: chat + max_input_tokens: 1047576 + max_output_tokens: 32768 + supports_vision: true + supports_function_calling: true + - name: gpt-4o + type: chat + max_input_tokens: 128000 + max_output_tokens: 16384 + supports_function_calling: true + - name: text-embedding-3-large + type: embedding + max_tokens_per_chunk: 8191 + default_chunk_size: 2000 + max_batch_size: 100 + - name: text-embedding-3-small + type: embedding + max_tokens_per_chunk: 8191 + default_chunk_size: 2000 + max_batch_size: 100 + - name: llama-4-maverick-17b-128e-instruct-fp8 + type: chat + max_input_tokens: 1048576 + supports_vision: true + - name: llama-4-scout-17b-16e-instruct + type: chat + max_input_tokens: 327680 + supports_vision: true + - name: llama-3.3-70b-instruct + type: chat + max_input_tokens: 131072 + - name: mistral-medium-2505 + type: chat + max_input_tokens: 131072 + supports_function_calling: true + - name: mistral-small-2503 + type: chat + max_input_tokens: 131072 + supports_function_calling: true + - name: codestral-2501 + type: chat + max_input_tokens: 256000 + supports_function_calling: true + - name: cohere-embed-v3-english + type: embedding + max_tokens_per_chunk: 512 + default_chunk_size: 1000 + max_batch_size: 96 + - name: cohere-embed-v3-multilingual + type: embedding + max_tokens_per_chunk: 512 + default_chunk_size: 1000 + max_batch_size: 96 + - name: deepseek-r1-0528 + type: chat + max_input_tokens: 163840 + - name: deepseek-v3-0324 + type: chat + max_input_tokens: 163840 + - name: mai-ds-r1 + type: chat + max_input_tokens: 163840 + - name: phi-4 + type: chat + max_input_tokens: 16384 + - name: phi-4-mini-instruct + type: chat + max_input_tokens: 131072 + - name: phi-4-reasoning + type: chat + max_input_tokens: 33792 + - name: phi-4-mini-reasoning + type: chat + max_input_tokens: 131072 + - name: grok-3 + type: chat + max_input_tokens: 131072 + - name: grok-3-mini + type: chat + max_input_tokens: 131072 - provider: deepinfra models: - - name: openai/gpt-oss-120b - max_input_tokens: 131072 - input_price: 0.09 - output_price: 0.45 - supports_function_calling: true - - name: openai/gpt-oss-20b - max_input_tokens: 131072 - input_price: 0.04 - output_price: 0.16 - supports_function_calling: true - - name: meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8 - max_input_tokens: 1048576 - input_price: 0.18 - output_price: 0.6 - supports_vision: true - - name: meta-llama/Llama-4-Scout-17B-16E-Instruct - max_input_tokens: 327680 - input_price: 0.08 - output_price: 0.3 - supports_vision: true - - name: Qwen/Qwen3-Max - max_input_tokens: 262144 - input_price: 1.2 - output_price: 6 - supports_function_calling: true - - name: Qwen/Qwen3-Max-Thinking - max_input_tokens: 262144 - input_price: 1.2 - output_price: 6 - supports_function_calling: true - - name: Qwen/Qwen3-Next-80B-A3B-Instruct - max_input_tokens: 262144 - input_price: 0.14 - output_price: 1.4 - supports_function_calling: true - - name: Qwen/Qwen3-Next-80B-A3B-Thinking - max_input_tokens: 262144 - input_price: 0.14 - output_price: 1.4 - - name: Qwen/Qwen3-235B-A22B-Instruct-2507 - max_input_tokens: 131072 - input_price: 0.13 - output_price: 0.6 - supports_function_calling: true - - name: Qwen/Qwen3-235B-A22B-Thinking-2507 - max_input_tokens: 131072 - input_price: 0.13 - output_price: 0.6 - - name: Qwen/Qwen3-Coder-480B-A35B-Instruct - max_input_tokens: 131072 - input_price: 0.4 - output_price: 1.6 - supports_function_calling: true - - name: Qwen/Qwen3-Coder-30B-A3B-Instruct - max_input_tokens: 262144 - input_price: 0.07 - output_price: 0.27 - supports_function_calling: true - - name: Qwen/Qwen3-30B-A3B - max_input_tokens: 40960 - input_price: 0.1 - output_price: 0.3 - - name: Qwen/Qwen3-VL-8B-Instruct - max_input_tokens: 262144 - input_price: 0.18 - output_price: 0.69 - supports_vision: true - - name: deepseek-ai/DeepSeek-V3.2 - max_input_tokens: 163840 - input_price: 0.26 - output_price: 0.39 - supports_function_calling: true - - name: google/gemma-3-27b-it - max_input_tokens: 131072 - input_price: 0.1 - output_price: 0.2 - - name: mistralai/Mistral-Small-3.2-24B-Instruct-2506 - max_input_tokens: 32768 - input_price: 0.06 - output_price: 0.12 - - name: moonshotai/Kimi-K2.5 - max_input_tokens: 262144 - input_price: 0.5 - output_price: 2.8 - supports_function_calling: true - - name: moonshotai/Kimi-K2-Instruct-0905 - max_input_tokens: 262144 - input_price: 0.5 - output_price: 2.0 - supports_function_calling: true - - name: moonshotai/Kimi-K2-Thinking - max_input_tokens: 262144 - input_price: 0.55 - output_price: 2.5 - supports_function_calling: true - - name: MiniMaxAI/MiniMax-M2.5 - max_input_tokens: 196608 - input_price: 0.27 - output_price: 0.95 - supports_function_calling: true - - name: MiniMaxAI/MiniMax-M2.1 - max_input_tokens: 196608 - input_price: 0.27 - output_price: 0.95 - supports_function_calling: true - - name: zai-org/GLM-5 - max_input_tokens: 202752 - input_price: 0.8 - output_price: 2.56 - supports_function_calling: true - - name: zai-org/GLM-4.7 - max_input_tokens: 202752 - input_price: 0.43 - output_price: 1.75 - supports_function_calling: true - - name: zai-org/GLM-4.7-Flash - max_input_tokens: 202752 - input_price: 0.06 - output_price: 0.4 - supports_function_calling: true - - name: zai-org/GLM-4.6V - max_input_tokens: 131072 - input_price: 0.3 - output_price: 0.9 - supports_vision: true - - name: BAAI/bge-large-en-v1.5 - type: embedding - input_price: 0.01 - max_tokens_per_chunk: 512 - default_chunk_size: 1000 - max_batch_size: 100 - - name: BAAI/bge-m3 - type: embedding - input_price: 0.01 - max_tokens_per_chunk: 8192 - default_chunk_size: 2000 - max_batch_size: 100 - - name: intfloat/e5-large-v2 - type: embedding - input_price: 0.01 - max_tokens_per_chunk: 512 - default_chunk_size: 1000 - max_batch_size: 100 - - name: intfloat/multilingual-e5-large - type: embedding - input_price: 0.01 - max_tokens_per_chunk: 512 - default_chunk_size: 1000 - max_batch_size: 100 - - name: thenlper/gte-large - type: embedding - input_price: 0.01 - max_tokens_per_chunk: 512 - default_chunk_size: 1000 - max_batch_size: 100 - -# Links: -# - https://jina.ai/models -# - https://api.jina.ai/redoc + - name: BAAI/bge-large-en-v1.5 + type: embedding + input_price: 0.01 + max_tokens_per_chunk: 512 + default_chunk_size: 1000 + max_batch_size: 100 + - name: BAAI/bge-m3 + type: embedding + input_price: 0.01 + max_tokens_per_chunk: 8192 + default_chunk_size: 2000 + max_batch_size: 100 + - name: intfloat/e5-large-v2 + type: embedding + input_price: 0.01 + max_tokens_per_chunk: 512 + default_chunk_size: 1000 + max_batch_size: 100 + - name: intfloat/multilingual-e5-large + type: embedding + input_price: 0.01 + max_tokens_per_chunk: 512 + default_chunk_size: 1000 + max_batch_size: 100 + - name: thenlper/gte-large + type: embedding + input_price: 0.01 + max_tokens_per_chunk: 512 + default_chunk_size: 1000 + max_batch_size: 100 + - name: Qwen/Qwen3-Max-Thinking + type: chat + max_input_tokens: 262144 + input_price: 1.2 + output_price: 6.0 + supports_function_calling: true + - name: Qwen/Qwen3-Next-80B-A3B-Thinking + type: chat + max_input_tokens: 262144 + input_price: 0.14 + output_price: 1.4 + - name: Qwen/Qwen3-235B-A22B-Thinking-2507 + type: chat + max_input_tokens: 131072 + input_price: 0.13 + output_price: 0.6 + - name: Qwen/Qwen3-Coder-480B-A35B-Instruct + type: chat + max_input_tokens: 131072 + input_price: 0.4 + output_price: 1.6 + supports_function_calling: true + - name: Qwen/Qwen3-Coder-30B-A3B-Instruct + type: chat + max_input_tokens: 262144 + input_price: 0.07 + output_price: 0.27 + supports_function_calling: true + - name: Qwen/Qwen3-VL-8B-Instruct + type: chat + max_input_tokens: 262144 + input_price: 0.18 + output_price: 0.69 + supports_vision: true + - name: google/gemma-3-27b-it + type: chat + max_input_tokens: 131072 + input_price: 0.1 + output_price: 0.2 + - name: mistralai/Mistral-Small-3.2-24B-Instruct-2506 + type: chat + max_input_tokens: 32768 + input_price: 0.06 + output_price: 0.12 + - name: moonshotai/Kimi-K2-Instruct-0905 + type: chat + max_input_tokens: 262144 + input_price: 0.5 + output_price: 2.0 + supports_function_calling: true + - name: moonshotai/Kimi-K2-Thinking + type: chat + max_input_tokens: 262144 + input_price: 0.55 + output_price: 2.5 + supports_function_calling: true + - name: MiniMaxAI/MiniMax-M2.1 + type: chat + max_input_tokens: 196608 + input_price: 0.27 + output_price: 0.95 + supports_function_calling: true + - name: zai-org/GLM-4.6V + type: chat + max_input_tokens: 131072 + input_price: 0.3 + output_price: 0.9 + supports_vision: true + - name: zai-org/GLM-5.3-Flash + type: chat + max_input_tokens: 1048576 + input_price: 0.15 + output_price: 0.5 + max_output_tokens: 131072 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - high + - max + - name: Qwen/Qwen3.8-27B + type: chat + max_input_tokens: 262144 + input_price: 0.4 + output_price: 3.0 + max_output_tokens: 32768 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - medium + - xhigh + - name: zai-org/GLM-5.3 + type: chat + max_input_tokens: 1048576 + input_price: 1.2 + output_price: 4.0 + max_output_tokens: 131072 + supports_function_calling: true + reasoning_levels: + - low + - high + - max + - name: Qwen/Qwen3.8-2.4T-A95B + type: chat + max_input_tokens: 262144 + input_price: 2.0 + output_price: 6.0 + max_output_tokens: 131072 + supports_function_calling: true + reasoning_levels: + - low + - medium + - xhigh + - name: deepseek-ai/DeepSeek-V4-Pro-0813 + type: chat + max_input_tokens: 1048576 + input_price: 1.3 + output_price: 2.6 + max_output_tokens: 384000 + supports_function_calling: true + reasoning_levels: + - high + - max + - name: Qwen/Qwen3.8-Max + type: chat + max_input_tokens: 256000 + input_price: 1.65 + output_price: 4.951 + max_output_tokens: 131072 + supports_vision: true + supports_function_calling: true + - name: deepseek-ai/DeepSeek-V4-Flash-0731 + type: chat + max_input_tokens: 1048576 + input_price: 0.08 + output_price: 0.18 + max_output_tokens: 384000 + supports_function_calling: true + - name: thinkingmachines/Inkling-Small + type: chat + max_input_tokens: 524288 + input_price: 0.45 + output_price: 1.2 + max_output_tokens: 1048576 + supports_vision: true + supports_function_calling: true + - name: moonshotai/Kimi-K3 + type: chat + max_input_tokens: 1048576 + input_price: 2.85 + output_price: 14.25 + max_output_tokens: 131072 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - low + - high + - max + - name: thinkingmachines/Inkling + type: chat + max_input_tokens: 524288 + input_price: 0.95 + output_price: 4.05 + max_output_tokens: 1048576 + supports_vision: true + supports_function_calling: true + - name: tencent/Hy3 + type: chat + max_input_tokens: 262144 + input_price: 0.14 + output_price: 0.58 + max_output_tokens: 64000 + supports_function_calling: true + - name: zai-org/GLM-5.2 + type: chat + max_input_tokens: 1048576 + input_price: 0.75 + output_price: 2.4 + max_output_tokens: 32768 + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - name: moonshotai/Kimi-K2.7-Code + type: chat + max_input_tokens: 262144 + input_price: 0.68 + output_price: 3.4 + max_output_tokens: 262144 + supports_vision: true + supports_function_calling: true + - name: MiniMaxAI/MiniMax-M3 + type: chat + max_input_tokens: 524288 + input_price: 0.28 + output_price: 1.1 + max_output_tokens: 512000 + supports_vision: true + supports_function_calling: true + - name: stepfun-ai/Step-3.7-Flash + type: chat + max_input_tokens: 262144 + input_price: 0.2 + output_price: 1.15 + max_output_tokens: 256000 + supports_vision: true + supports_function_calling: true + - name: Qwen/Qwen3.7-Max + type: chat + max_input_tokens: 256000 + input_price: 2.5 + output_price: 7.5 + max_output_tokens: 65536 + supports_function_calling: true + - name: nvidia/Nemotron-3-Nano-Omni-30B-A3B-Reasoning + type: chat + max_input_tokens: 262144 + input_price: 0.2 + output_price: 0.8 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: deepseek-ai/DeepSeek-V4-Flash + type: chat + max_input_tokens: 1048576 + input_price: 0.09 + output_price: 0.18 + max_output_tokens: 16384 + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - name: deepseek-ai/DeepSeek-V4-Pro + type: chat + max_input_tokens: 1048576 + input_price: 1.3 + output_price: 2.6 + max_output_tokens: 16384 + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - xhigh + - name: Qwen/Qwen3.6-27B + type: chat + max_input_tokens: 262144 + input_price: 0.32 + output_price: 3.2 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: XiaomiMiMo/MiMo-V2.5 + type: chat + max_input_tokens: 262144 + input_price: 0.4 + output_price: 2.0 + max_output_tokens: 16384 + supports_vision: true + supports_function_calling: true + - name: XiaomiMiMo/MiMo-V2.5-Pro + type: chat + max_input_tokens: 1048576 + input_price: 1.0 + output_price: 3.0 + max_output_tokens: 16384 + supports_function_calling: true + - name: moonshotai/Kimi-K2.6 + type: chat + max_input_tokens: 262144 + input_price: 0.75 + output_price: 3.5 + max_output_tokens: 16384 + supports_vision: true + supports_function_calling: true + - name: zai-org/GLM-5.1 + type: chat + max_input_tokens: 202752 + input_price: 1.05 + output_price: 3.5 + max_output_tokens: 16384 + supports_function_calling: true + - name: google/gemma-4-26B-A4B-it + type: chat + max_input_tokens: 262144 + input_price: 0.07 + output_price: 0.34 + max_output_tokens: 32768 + supports_vision: true + supports_function_calling: true + - name: google/gemma-4-31B-it + type: chat + max_input_tokens: 262144 + input_price: 0.13 + output_price: 0.38 + max_output_tokens: 32768 + supports_vision: true + supports_function_calling: true + - name: google/gemma-4-E4B-it + type: chat + max_input_tokens: 131072 + input_price: 0.02 + output_price: 0.1 + max_output_tokens: 8192 + supports_vision: true + supports_function_calling: true + - name: Qwen/Qwen3.6-35B-A3B + type: chat + max_input_tokens: 262144 + input_price: 0.1 + output_price: 0.95 + max_output_tokens: 81920 + supports_vision: true + supports_function_calling: true + - name: MiniMaxAI/MiniMax-M2.7 + type: chat + max_input_tokens: 196608 + input_price: 0.25 + output_price: 1.0 + max_output_tokens: 131072 + supports_function_calling: true + - name: Qwen/Qwen3.5-122B-A10B + type: chat + max_input_tokens: 262144 + input_price: 0.29 + output_price: 2.4 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: Qwen/Qwen3.5-27B + type: chat + max_input_tokens: 262144 + input_price: 0.26 + output_price: 2.6 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: Qwen/Qwen3.5-9B + type: chat + max_input_tokens: 262144 + input_price: 0.1 + output_price: 0.15 + max_output_tokens: 65536 + supports_vision: true + supports_function_calling: true + - name: ByteDance/Seed-2.0-code + type: chat + max_input_tokens: 256000 + input_price: 0.5 + output_price: 3.0 + max_output_tokens: 131072 + supports_vision: true + supports_function_calling: true + reasoning_levels: + - none + - low + - medium + - high + - name: ByteDance/Seed-2.0-mini + type: chat + max_input_tokens: 256000 + input_price: 0.1 + output_price: 0.4 + max_output_tokens: 32000 + supports_vision: true + supports_function_calling: true + - name: ByteDance/Seed-2.0-pro + type: chat + max_input_tokens: 256000 + input_price: 0.5 + output_price: 3.0 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + - name: MiniMaxAI/MiniMax-M2.5 + type: chat + max_input_tokens: 196608 + input_price: 0.15 + output_price: 1.15 + max_output_tokens: 131072 + supports_function_calling: true + - name: zai-org/GLM-5 + type: chat + max_input_tokens: 202752 + input_price: 0.6 + output_price: 2.08 + max_output_tokens: 16384 + supports_function_calling: true + - name: Qwen/Qwen3.5-35B-A3B + type: chat + max_input_tokens: 262144 + input_price: 0.14 + output_price: 1.0 + max_output_tokens: 81920 + supports_vision: true + supports_function_calling: true + - name: Qwen/Qwen3.5-397B-A17B + type: chat + max_input_tokens: 262144 + input_price: 0.45 + output_price: 3.0 + max_output_tokens: 81920 + supports_vision: true + supports_function_calling: true + - name: moonshotai/Kimi-K2.5 + type: chat + max_input_tokens: 262144 + input_price: 0.45 + output_price: 2.25 + max_output_tokens: 32768 + supports_vision: true + supports_function_calling: true + - name: zai-org/GLM-4.7-Flash + type: chat + max_input_tokens: 202752 + input_price: 0.06 + output_price: 0.4 + max_output_tokens: 16384 + supports_function_calling: true + - name: zai-org/GLM-4.7 + type: chat + max_input_tokens: 202752 + input_price: 0.4 + output_price: 1.75 + max_output_tokens: 16384 + supports_function_calling: true + - name: nvidia/Nemotron-3-Nano-30B-A3B + type: chat + max_input_tokens: 262144 + input_price: 0.05 + output_price: 0.2 + max_output_tokens: 262144 + supports_function_calling: true + - name: deepseek-ai/DeepSeek-V3.2 + type: chat + max_input_tokens: 163840 + input_price: 0.26 + output_price: 0.38 + max_output_tokens: 64000 + supports_function_calling: true + - name: zai-org/GLM-4.6 + type: chat + max_input_tokens: 202752 + input_price: 0.5 + output_price: 2.0 + max_output_tokens: 131072 + supports_function_calling: true + - name: Qwen/Qwen3-Max + type: chat + max_input_tokens: 256000 + input_price: 1.2 + output_price: 6.0 + max_output_tokens: 65536 + supports_function_calling: true + - name: Qwen/Qwen3-VL-235B-A22B-Instruct + type: chat + max_input_tokens: 262144 + input_price: 0.2 + output_price: 0.88 + max_output_tokens: 32768 + supports_vision: true + supports_function_calling: true + - name: Qwen/Qwen3-Next-80B-A3B-Instruct + type: chat + max_input_tokens: 262144 + input_price: 0.09 + output_price: 1.1 + max_output_tokens: 32768 + supports_function_calling: true + - name: deepseek-ai/DeepSeek-V3.1 + type: chat + max_input_tokens: 163840 + input_price: 0.25 + output_price: 0.95 + max_output_tokens: 8192 + supports_function_calling: true + - name: openai/gpt-oss-120b + type: chat + max_input_tokens: 131072 + input_price: 0.037 + output_price: 0.17 + max_output_tokens: 16384 + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - name: openai/gpt-oss-20b + type: chat + max_input_tokens: 131072 + input_price: 0.03 + output_price: 0.14 + max_output_tokens: 16384 + supports_function_calling: true + reasoning_levels: + - low + - medium + - high + - name: nvidia/Llama-3.3-Nemotron-Super-49B-v1.5 + type: chat + max_input_tokens: 131072 + input_price: 0.4 + output_price: 0.4 + max_output_tokens: 131072 + supports_function_calling: true + - name: Qwen/Qwen3-Coder-480B-A35B-Instruct-Turbo + type: chat + max_input_tokens: 262144 + input_price: 0.3 + output_price: 1.0 + max_output_tokens: 66536 + supports_function_calling: true + - name: Qwen/Qwen3-235B-A22B-Instruct-2507 + type: chat + max_input_tokens: 262144 + input_price: 0.09 + output_price: 0.55 + max_output_tokens: 16384 + supports_function_calling: true + - name: deepseek-ai/DeepSeek-R1-0528 + type: chat + max_input_tokens: 163840 + input_price: 0.5 + output_price: 2.15 + max_output_tokens: 64000 + supports_function_calling: true + - name: Qwen/Qwen3-30B-A3B + type: chat + max_input_tokens: 40960 + input_price: 0.12 + output_price: 0.5 + max_output_tokens: 16384 + supports_function_calling: true + - name: meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8 + type: chat + max_input_tokens: 1048576 + input_price: 0.2 + output_price: 0.8 + max_output_tokens: 16384 + supports_vision: true + - name: meta-llama/Llama-4-Scout-17B-16E-Instruct + type: chat + max_input_tokens: 327680 + input_price: 0.1 + output_price: 0.3 + max_output_tokens: 16384 + supports_vision: true + supports_function_calling: true + - name: Qwen/Qwen3-32B + type: chat + max_input_tokens: 40960 + input_price: 0.08 + output_price: 0.28 + max_output_tokens: 16384 + supports_function_calling: true + - name: deepseek-ai/DeepSeek-V3-0324 + type: chat + max_input_tokens: 163840 + input_price: 0.24 + output_price: 0.9 + max_output_tokens: 163840 + supports_function_calling: true + - name: deepseek-ai/DeepSeek-V3 + type: chat + max_input_tokens: 163840 + input_price: 0.32 + output_price: 0.89 + max_output_tokens: 8192 + supports_function_calling: true + - name: meta-llama/Llama-3.3-70B-Instruct-Turbo + type: chat + max_input_tokens: 131072 + input_price: 0.1 + output_price: 0.32 + max_output_tokens: 16384 + supports_function_calling: true - provider: jina models: - - name: jina-embeddings-v3 - type: embedding - input_price: 0 - max_tokens_per_chunk: 8192 - default_chunk_size: 2000 - max_batch_size: 100 - - name: jina-clip-v2 - type: embedding - input_price: 0 - max_tokens_per_chunk: 8192 - default_chunk_size: 1500 - max_batch_size: 100 - - name: jina-colbert-v2 - type: embedding - input_price: 0 - max_tokens_per_chunk: 8192 - default_chunk_size: 1500 - max_batch_size: 100 - - name: jina-reranker-v2-base-multilingual - type: reranker - max_input_tokens: 8192 - input_price: 0 - - name: jina-colbert-v2 - type: reranker - max_input_tokens: 8192 - input_price: 0 - -# Links: -# - https://docs.voyageai.com/docs/embeddings -# - https://docs.voyageai.com/docs/pricing -# - https://docs.voyageai.com/reference/ + - name: jina-embeddings-v3 + type: embedding + input_price: 0.0 + max_tokens_per_chunk: 8192 + default_chunk_size: 2000 + max_batch_size: 100 + - name: jina-clip-v2 + type: embedding + input_price: 0.0 + max_tokens_per_chunk: 8192 + default_chunk_size: 1500 + max_batch_size: 100 + - name: jina-colbert-v2 + type: embedding + input_price: 0.0 + max_tokens_per_chunk: 8192 + default_chunk_size: 1500 + max_batch_size: 100 + - name: jina-reranker-v2-base-multilingual + type: reranker + max_input_tokens: 8192 + input_price: 0.0 + - name: jina-colbert-v2 + type: reranker + max_input_tokens: 8192 + input_price: 0.0 - provider: voyageai models: - - name: voyage-3-large - type: embedding - max_input_tokens: 120000 - input_price: 0.18 - max_tokens_per_chunk: 32000 - default_chunk_size: 2000 - max_batch_size: 128 - - name: voyage-3 - type: embedding - max_input_tokens: 320000 - input_price: 0.06 - max_tokens_per_chunk: 32000 - default_chunk_size: 2000 - max_batch_size: 128 - - name: voyage-3-lite - type: embedding - max_input_tokens: 1000000 - input_price: 0.02 - max_tokens_per_chunk: 32000 - default_chunk_size: 1000 - max_batch_size: 128 - - name: rerank-2 - type: reranker - max_input_tokens: 16000 - input_price: 0.05 - - name: rerank-2-lite - type: reranker - max_input_tokens: 8000 - input_price: 0.02 + - name: voyage-3-large + type: embedding + max_input_tokens: 120000 + input_price: 0.18 + max_tokens_per_chunk: 32000 + default_chunk_size: 2000 + max_batch_size: 128 + - name: voyage-3 + type: embedding + max_input_tokens: 320000 + input_price: 0.06 + max_tokens_per_chunk: 32000 + default_chunk_size: 2000 + max_batch_size: 128 + - name: voyage-3-lite + type: embedding + max_input_tokens: 1000000 + input_price: 0.02 + max_tokens_per_chunk: 32000 + default_chunk_size: 1000 + max_batch_size: 128 + - name: rerank-2 + type: reranker + max_input_tokens: 16000 + input_price: 0.05 + - name: rerank-2-lite + type: reranker + max_input_tokens: 8000 + input_price: 0.02 diff --git a/quirks.yaml b/quirks.yaml new file mode 100644 index 0000000..3db303c --- /dev/null +++ b/quirks.yaml @@ -0,0 +1,1472 @@ +# Hand-owned model behavior overlay. +# +# Everything in this file is curated by hand and layered on top of API-sourced +# model data: oauth blocks, request patches, wire-name aliases, behavioral +# flags, and models that no public catalog provides. +# +# `models:` entries are self-complete. `rules` apply ONLY to API-sourced +# models, never to hand-owned `models:` entries. Legacy verbatim-preserved +# entries are grouped under a `# legacy -- pruning candidates` comment. + +- provider: openai + exclude: + - "text-embedding-*" + - "gpt-image-*" + - "chatgpt-image-*" + - "gpt-realtime*" + rules: + - match: "gpt-5.6-*" + default_reasoning_effort: medium + - match: "gpt-5.5" + default_reasoning_effort: medium + - match: "gpt-5.5-pro" + default_reasoning_effort: high + - match: "gpt-5.4" + default_reasoning_effort: none + - match: "gpt-5.4-pro" + default_reasoning_effort: medium + - match: "gpt-5.4-mini" + default_reasoning_effort: none + - match: "gpt-5.4-nano" + default_reasoning_effort: none + - match: "gpt-5.3-codex" + default_reasoning_effort: medium + - match: "gpt-5.2" + default_reasoning_effort: none + - match: "gpt-5.2-pro" + default_reasoning_effort: medium + - match: "gpt-5.1" + default_reasoning_effort: none + - match: "gpt-5.1-chat-latest" + default_reasoning_effort: none + - match: "gpt-5" + default_reasoning_effort: medium + - match: "gpt-5-chat-latest" + default_reasoning_effort: medium + - match: "o4-mini" + system_prompt_prefix: Formatting re-enabled + default_reasoning_effort: medium + patch: + body: + max_tokens: null + temperature: null + top_p: null + - match: "o3" + system_prompt_prefix: Formatting re-enabled + patch: + body: + max_tokens: null + temperature: null + top_p: null + - match: "o3-mini" + system_prompt_prefix: Formatting re-enabled + patch: + body: + max_tokens: null + temperature: null + top_p: null + models: + - name: text-embedding-3-large + type: embedding + input_price: 0.13 + max_tokens_per_chunk: 8191 + default_chunk_size: 2000 + max_batch_size: 100 + - name: text-embedding-3-small + type: embedding + input_price: 0.02 + max_tokens_per_chunk: 8191 + default_chunk_size: 2000 + max_batch_size: 100 + # legacy -- pruning candidates + - name: o4-mini-high + max_output_tokens: 100000 + real_name: o4-mini + max_input_tokens: 200000 + input_price: 1.1 + output_price: 4.4 + supports_vision: true + supports_function_calling: true + system_prompt_prefix: Formatting re-enabled + patch: + body: + reasoning_effort: high + max_tokens: null + temperature: null + top_p: null + - name: o3-high + real_name: o3 + max_input_tokens: 200000 + input_price: 2 + output_price: 8 + supports_vision: true + supports_function_calling: true + system_prompt_prefix: Formatting re-enabled + patch: + body: + reasoning_effort: high + max_tokens: null + temperature: null + top_p: null + - name: o3-mini-high + max_output_tokens: 100000 + real_name: o3-mini + max_input_tokens: 200000 + input_price: 1.1 + output_price: 4.4 + supports_vision: true + supports_function_calling: true + system_prompt_prefix: Formatting re-enabled + patch: + body: + reasoning_effort: high + max_tokens: null + temperature: null + top_p: null + - name: chat-latest + max_input_tokens: 400000 + max_output_tokens: 128000 + input_price: 5 + output_price: 30 + supports_vision: true + supports_function_calling: true + - name: gpt-5.1-chat-latest + max_input_tokens: 400000 + max_output_tokens: 128000 + input_price: 1.25 + output_price: 10 + supports_vision: true + supports_function_calling: true + reasoning_levels: [none, low, medium, high] + default_reasoning_effort: none + - name: gpt-5-chat-latest + max_input_tokens: 400000 + max_output_tokens: 128000 + input_price: 1.25 + output_price: 10 + supports_vision: true + supports_function_calling: true + reasoning_levels: [minimal, low, medium, high] + default_reasoning_effort: medium + +- provider: gemini + exclude: + - "gemini-embedding-*" + - "veo-*" + - "*-tts" + - "*-tts-preview" + - "*-image-preview" + rules: + - match: "gemini-3.6-flash" + default_reasoning_effort: medium + - match: "gemini-3.5-flash" + default_reasoning_effort: medium + - match: "gemini-3-flash-preview" + default_reasoning_effort: high + - match: "gemini-3.1-flash-lite" + default_reasoning_effort: minimal + - match: "gemini-3.1-pro-preview" + default_reasoning_effort: high + - match: "gemini-3-pro-preview" + default_reasoning_effort: high + - match: "gemini-2.5-pro" + default_reasoning_effort: high + reasoning_levels: [low, medium, high] + models: + - name: text-embedding-004 + type: embedding + input_price: 0 + max_tokens_per_chunk: 2048 + default_chunk_size: 1500 + max_batch_size: 100 + # legacy -- pruning candidates + - name: gemini-3-pro-preview + max_input_tokens: 1048576 + supports_vision: true + supports_function_calling: true + reasoning_levels: [low, high] + default_reasoning_effort: high + - name: gemma-3-27b-it + max_input_tokens: 131072 + max_output_tokens: 8192 + input_price: 0 + output_price: 0 + +- provider: claude + rules: + - match: "claude-*" + require_max_tokens: true + - match: "claude-opus-5" + default_reasoning_effort: high + - match: "claude-fable-*" + default_reasoning_effort: high + - match: "claude-opus-4-8" + default_reasoning_effort: high + - match: "claude-opus-4-7" + default_reasoning_effort: high + - match: "claude-opus-4-6" + default_reasoning_effort: high + - match: "claude-sonnet-5" + default_reasoning_effort: high + - match: "claude-sonnet-4-6" + default_reasoning_effort: high + variants: + - match: "claude-opus-4-6" + suffix: ":thinking" + real_name: claude-opus-4-6 + max_output_tokens: 24000 + reasoning_levels: [] + patch: + body: + temperature: null + top_p: null + thinking: + type: enabled + budget_tokens: 16000 + - match: "claude-sonnet-4-6" + suffix: ":thinking" + real_name: claude-sonnet-4-6 + max_output_tokens: 24000 + reasoning_levels: [] + patch: + body: + temperature: null + top_p: null + thinking: + type: enabled + budget_tokens: 16000 + - match: "claude-sonnet-4-5-20250929" + suffix: ":thinking" + real_name: claude-sonnet-4-5-20250929 + max_output_tokens: 24000 + reasoning_levels: [] + patch: + body: + temperature: null + top_p: null + thinking: + type: enabled + budget_tokens: 16000 + - match: "claude-haiku-4-5-20251001" + suffix: ":thinking" + real_name: claude-haiku-4-5-20251001 + max_output_tokens: 24000 + reasoning_levels: [] + patch: + body: + temperature: null + top_p: null + thinking: + type: enabled + budget_tokens: 16000 + - match: "claude-opus-4-5-20251101" + suffix: ":thinking" + real_name: claude-opus-4-5-20251101 + max_output_tokens: 24000 + reasoning_levels: [] + patch: + body: + temperature: null + top_p: null + thinking: + type: enabled + budget_tokens: 16000 + - match: "claude-opus-4-1-20250805" + suffix: ":thinking" + real_name: claude-opus-4-1-20250805 + max_output_tokens: 24000 + reasoning_levels: [] + patch: + body: + temperature: null + top_p: null + thinking: + type: enabled + budget_tokens: 16000 + - match: "claude-opus-4-20250514" + suffix: ":thinking" + real_name: claude-opus-4-20250514 + max_output_tokens: 24000 + reasoning_levels: [] + patch: + body: + temperature: null + top_p: null + thinking: + type: enabled + budget_tokens: 16000 + models: + # legacy -- pruning candidates + - name: claude-opus-4-1-20250805 + max_input_tokens: 200000 + max_output_tokens: 8192 + require_max_tokens: true + input_price: 15 + output_price: 75 + supports_vision: true + supports_function_calling: true + - name: claude-opus-4-20250514 + max_input_tokens: 200000 + max_output_tokens: 8192 + require_max_tokens: true + input_price: 15 + output_price: 75 + supports_vision: true + supports_function_calling: true + +- provider: mistral + exclude: + - "voxtral-*" + models: + - name: mistral-embed + type: embedding + max_input_tokens: 8092 + input_price: 0.1 + max_tokens_per_chunk: 8092 + default_chunk_size: 2000 + # legacy -- pruning candidates + - name: magistral-small-latest + max_input_tokens: 131072 + input_price: 0.5 + output_price: 1.5 + - name: devstral-small-latest + max_input_tokens: 262144 + input_price: 0.1 + output_price: 0.3 + supports_function_calling: true + - name: ministral-14b-latest + max_input_tokens: 262144 + input_price: 0.2 + output_price: 0.2 + supports_function_calling: true + +- provider: ai21 + models: + - name: jamba-large + max_input_tokens: 256000 + input_price: 2 + output_price: 8 + supports_function_calling: true + - name: jamba-mini + max_input_tokens: 256000 + input_price: 0.2 + output_price: 0.4 + supports_function_calling: true + +- provider: cohere + models: + - name: embed-v4.0 + type: embedding + input_price: 0.12 + max_tokens_per_chunk: 2048 + default_chunk_size: 2000 + max_batch_size: 96 + - name: embed-english-v3.0 + type: embedding + input_price: 0.1 + max_tokens_per_chunk: 512 + default_chunk_size: 1000 + max_batch_size: 96 + - name: embed-multilingual-v3.0 + type: embedding + input_price: 0.1 + max_tokens_per_chunk: 512 + default_chunk_size: 1000 + max_batch_size: 96 + - name: rerank-v3.5 + type: reranker + max_input_tokens: 4096 + - name: rerank-english-v3.0 + type: reranker + max_input_tokens: 4096 + - name: rerank-multilingual-v3.0 + type: reranker + max_input_tokens: 4096 + +- provider: xai + exclude: + - "grok-imagine-*" + oauth: + client_id: b1a00492-073a-47ea-816f-4c329264a828 + authorize_url: https://auth.x.ai/oauth2/authorize + token_url: https://auth.x.ai/oauth2/token + scopes: + - openid + - profile + - email + - offline_access + - grok-cli:access + - api:access + redirect_port: 56121 + flow: pkce + token_request_format: form_url_encoded + extra_authorize_params: + plan: generic + referrer: coyote + echo_pkce_in_token_exchange: true + models: + - name: grok-4.20 + real_name: grok-4.20-multi-agent-0309 + input_price: 1.25 + output_price: 2.5 + max_input_tokens: 1000000 + supports_function_calling: true + - name: grok-4.20-reasoning + real_name: grok-4.20-0309-reasoning + input_price: 1.25 + output_price: 2.5 + max_input_tokens: 1000000 + supports_function_calling: true + - name: grok-4.20-non-reasoning + real_name: grok-4.20-0309-non-reasoning + input_price: 1.25 + output_price: 2.5 + max_input_tokens: 1000000 + supports_function_calling: true + - name: grok-4-1-fast-non-reasoning + max_input_tokens: 1000000 + input_price: 0.2 + output_price: 0.5 + supports_function_calling: true + - name: grok-4-1-fast-reasoning + max_input_tokens: 1000000 + input_price: 0.2 + output_price: 0.5 + supports_function_calling: true + - name: grok-code-fast-1 + max_input_tokens: 256000 + input_price: 0.2 + output_price: 1.5 + supports_function_calling: true + - name: grok-3 + max_input_tokens: 131072 + input_price: 3 + output_price: 15 + supports_function_calling: true + - name: grok-3-mini + max_input_tokens: 131072 + input_price: 0.3 + output_price: 0.5 + supports_function_calling: true + +- provider: perplexity + models: + # legacy -- pruning candidates + - name: sonar-reasoning + max_input_tokens: 128000 + input_price: 1 + output_price: 5 + +- provider: groq + exclude: + - "whisper-*" + models: + # legacy -- pruning candidates + - name: meta-llama/llama-4-maverick-17b-128e-instruct + max_input_tokens: 131072 + input_price: 0 + output_price: 0 + supports_vision: true + supports_function_calling: true + - name: meta-llama/llama-4-scout-17b-16e-instruct + max_input_tokens: 131072 + input_price: 0 + output_price: 0 + supports_vision: true + supports_function_calling: true + - name: moonshotai/kimi-k2-instruct-0905 + max_input_tokens: 262144 + input_price: 0 + output_price: 0 + supports_function_calling: true + - name: qwen/qwen3-32b + max_input_tokens: 131072 + input_price: 0 + output_price: 0 + +- provider: vertexai + exclude: + - "gemini-embedding-*" + - "*-tts" + rules: + - match: "claude-*" + require_max_tokens: true + - match: "gemini-3.5-flash" + default_reasoning_effort: medium + - match: "gemini-3-flash-preview" + default_reasoning_effort: high + - match: "gemini-3.1-flash-lite" + default_reasoning_effort: minimal + - match: "gemini-3.1-pro-preview" + default_reasoning_effort: high + - match: "gemini-3-pro-preview" + default_reasoning_effort: high + - match: "gemini-2.5-flash" + default_reasoning_effort: medium + reasoning_levels: [low, medium, high] + - match: "gemini-2.5-pro" + default_reasoning_effort: high + reasoning_levels: [low, medium, high] + - match: "claude-opus-5" + default_reasoning_effort: high + - match: "claude-fable-*" + default_reasoning_effort: high + - match: "claude-opus-4-8" + default_reasoning_effort: high + - match: "claude-opus-4-7" + default_reasoning_effort: high + - match: "claude-sonnet-5" + default_reasoning_effort: high + - match: "claude-sonnet-4-6" + default_reasoning_effort: high + variants: + - match: "claude-opus-4-6" + suffix: ":thinking" + real_name: claude-opus-4-6 + max_output_tokens: 24000 + supports_function_calling: false + reasoning_levels: [] + patch: + body: + temperature: null + top_p: null + thinking: + type: enabled + budget_tokens: 16000 + - match: "claude-sonnet-4-6" + suffix: ":thinking" + real_name: claude-sonnet-4-6 + max_output_tokens: 24000 + supports_function_calling: false + reasoning_levels: [] + patch: + body: + temperature: null + top_p: null + thinking: + type: enabled + budget_tokens: 16000 + - match: "claude-opus-4-5@20251101" + suffix: ":thinking" + real_name: claude-opus-4-5@20251101 + max_output_tokens: 24000 + supports_function_calling: false + reasoning_levels: [] + patch: + body: + temperature: null + top_p: null + thinking: + type: enabled + budget_tokens: 16000 + - match: "claude-sonnet-4-5@20250929" + suffix: ":thinking" + real_name: claude-sonnet-4-5@20250929 + max_output_tokens: 24000 + supports_function_calling: false + reasoning_levels: [] + patch: + body: + temperature: null + top_p: null + thinking: + type: enabled + budget_tokens: 16000 + - match: "claude-haiku-4-5@20251001" + suffix: ":thinking" + real_name: claude-haiku-4-5@20251001 + max_output_tokens: 24000 + supports_function_calling: false + reasoning_levels: [] + patch: + body: + temperature: null + top_p: null + thinking: + type: enabled + budget_tokens: 16000 + models: + - name: text-embedding-005 + type: embedding + max_input_tokens: 20000 + input_price: 0.025 + max_tokens_per_chunk: 2048 + default_chunk_size: 1500 + max_batch_size: 5 + - name: text-multilingual-embedding-002 + type: embedding + max_input_tokens: 20000 + input_price: 0.2 + max_tokens_per_chunk: 2048 + default_chunk_size: 1500 + max_batch_size: 5 + # legacy -- pruning candidates + - name: gemini-3-pro-preview + max_input_tokens: 1048576 + supports_vision: true + supports_function_calling: true + reasoning_levels: [low, high] + default_reasoning_effort: high + - name: claude-opus-5 + max_input_tokens: 1000000 + max_output_tokens: 128000 + require_max_tokens: true + input_price: 5 + output_price: 25 + supports_function_calling: true + supports_vision: true + reasoning_levels: [low, medium, high, xhigh, max] + default_reasoning_effort: high + - name: claude-fable-5-1 + max_input_tokens: 1000000 + max_output_tokens: 128000 + require_max_tokens: true + input_price: 10 + output_price: 50 + supports_function_calling: true + supports_vision: true + reasoning_levels: [low, medium, high, xhigh, max] + default_reasoning_effort: high + - name: claude-fable-5 + max_input_tokens: 1000000 + max_output_tokens: 128000 + require_max_tokens: true + input_price: 10 + output_price: 50 + supports_function_calling: true + supports_vision: true + reasoning_levels: [low, medium, high, xhigh, max] + default_reasoning_effort: high + - name: claude-opus-4-8 + max_input_tokens: 1000000 + max_output_tokens: 128000 + require_max_tokens: true + input_price: 5 + output_price: 25 + supports_vision: true + supports_function_calling: true + reasoning_levels: [low, medium, high, xhigh, max] + default_reasoning_effort: high + - name: claude-opus-4-7 + max_input_tokens: 1000000 + max_output_tokens: 128000 + require_max_tokens: true + input_price: 5 + output_price: 25 + supports_vision: true + supports_function_calling: true + reasoning_levels: [low, medium, high, xhigh, max] + default_reasoning_effort: high + - name: claude-opus-4-6 + max_input_tokens: 200000 + max_output_tokens: 8192 + require_max_tokens: true + input_price: 5 + output_price: 25 + supports_vision: true + supports_function_calling: true + - name: claude-sonnet-5 + max_input_tokens: 1000000 + max_output_tokens: 128000 + require_max_tokens: true + input_price: 3 + output_price: 15 + supports_vision: true + supports_function_calling: true + reasoning_levels: [low, medium, high, xhigh, max] + default_reasoning_effort: high + - name: claude-sonnet-4-6 + max_input_tokens: 200000 + max_output_tokens: 8192 + require_max_tokens: true + input_price: 3 + output_price: 15 + supports_vision: true + supports_function_calling: true + reasoning_levels: [low, medium, high, max] + default_reasoning_effort: high + - name: claude-3-5-haiku@20241022 + max_input_tokens: 200000 + max_output_tokens: 8192 + require_max_tokens: true + input_price: 0.8 + output_price: 4 + supports_vision: true + supports_function_calling: true + - name: mistral-small-2503 + max_input_tokens: 32000 + input_price: 0.1 + output_price: 0.3 + supports_function_calling: true + - name: codestral-2501 + max_input_tokens: 256000 + input_price: 0.3 + output_price: 0.9 + supports_function_calling: true + +- provider: bedrock + rules: + - match: "us.anthropic.claude-*" + require_max_tokens: true + - match: "us.meta.llama*" + require_max_tokens: true + - match: "us.anthropic.claude-opus-5" + default_reasoning_effort: high + - match: "us.anthropic.claude-fable-*" + default_reasoning_effort: high + - match: "us.anthropic.claude-opus-4-8" + default_reasoning_effort: high + - match: "us.anthropic.claude-opus-4-7" + default_reasoning_effort: high + - match: "us.anthropic.claude-opus-4-6-v1" + default_reasoning_effort: high + - match: "us.anthropic.claude-sonnet-5" + default_reasoning_effort: high + - match: "us.anthropic.claude-sonnet-4-6" + default_reasoning_effort: high + variants: + - match: "us.anthropic.claude-opus-4-6-v1" + suffix: ":thinking" + real_name: us.anthropic.claude-opus-4-6-v1 + max_output_tokens: 24000 + supports_function_calling: false + reasoning_levels: [] + patch: + body: + inferenceConfig: + temperature: null + topP: null + additionalModelRequestFields: + thinking: + type: enabled + budget_tokens: 16000 + - match: "us.anthropic.claude-sonnet-4-6" + suffix: ":thinking" + real_name: us.anthropic.claude-sonnet-4-6 + max_output_tokens: 24000 + supports_function_calling: false + reasoning_levels: [] + patch: + body: + inferenceConfig: + temperature: null + topP: null + additionalModelRequestFields: + thinking: + type: enabled + budget_tokens: 16000 + - match: "us.anthropic.claude-opus-4-5-20251101-v1:0" + suffix: ":thinking" + real_name: us.anthropic.claude-opus-4-5-20251101-v1:0 + max_output_tokens: 24000 + supports_function_calling: false + reasoning_levels: [] + patch: + body: + inferenceConfig: + temperature: null + topP: null + additionalModelRequestFields: + thinking: + type: enabled + budget_tokens: 16000 + - match: "us.anthropic.claude-sonnet-4-5-20250929-v1:0" + suffix: ":thinking" + real_name: us.anthropic.claude-sonnet-4-5-20250929-v1:0 + max_output_tokens: 24000 + supports_function_calling: false + reasoning_levels: [] + patch: + body: + inferenceConfig: + temperature: null + topP: null + additionalModelRequestFields: + thinking: + type: enabled + budget_tokens: 16000 + - match: "us.anthropic.claude-haiku-4-5-20251001-v1:0" + suffix: ":thinking" + real_name: us.anthropic.claude-haiku-4-5-20251001-v1:0 + max_output_tokens: 24000 + supports_function_calling: false + reasoning_levels: [] + patch: + body: + inferenceConfig: + temperature: null + topP: null + additionalModelRequestFields: + thinking: + type: enabled + budget_tokens: 16000 + models: + - name: cohere.embed-english-v3 + type: embedding + input_price: 0.1 + max_tokens_per_chunk: 512 + default_chunk_size: 1000 + max_batch_size: 96 + - name: cohere.embed-multilingual-v3 + type: embedding + input_price: 0.1 + max_tokens_per_chunk: 512 + default_chunk_size: 1000 + max_batch_size: 96 + # legacy -- pruning candidates + - name: us.meta.llama3-3-70b-instruct-v1:0 + max_input_tokens: 131072 + max_output_tokens: 8192 + require_max_tokens: true + input_price: 0.72 + output_price: 0.72 + supports_function_calling: true + - name: us.amazon.nova-premier-v1:0 + max_input_tokens: 300000 + max_output_tokens: 5120 + input_price: 2.5 + output_price: 12.5 + - name: us.amazon.nova-pro-v1:0 + max_input_tokens: 300000 + max_output_tokens: 5120 + input_price: 0.8 + output_price: 3.2 + supports_vision: true + - name: us.amazon.nova-lite-v1:0 + max_input_tokens: 300000 + max_output_tokens: 5120 + input_price: 0.06 + output_price: 0.24 + supports_vision: true + - name: us.amazon.nova-micro-v1:0 + max_input_tokens: 128000 + max_output_tokens: 5120 + input_price: 0.035 + output_price: 0.14 + +- provider: cloudflare + rules: + - match: "@cf/*" + require_max_tokens: true + models: + - name: '@cf/baai/bge-large-en-v1.5' + type: embedding + input_price: 0 + max_tokens_per_chunk: 512 + default_chunk_size: 1000 + max_batch_size: 100 + # legacy -- pruning candidates + - name: '@cf/google/gemma-3-12b-it' + max_input_tokens: 131072 + max_output_tokens: 2048 + require_max_tokens: true + input_price: 0 + output_price: 0 + +- provider: ernie + models: + - name: ernie-4.5-turbo-128k + max_input_tokens: 131072 + input_price: 0.112 + output_price: 0.448 + - name: ernie-4.5-turbo-vl-32k + max_input_tokens: 32768 + input_price: 0.42 + output_price: 1.26 + supports_vision: true + - name: ernie-5.0-thinking-preview + max_input_tokens: 131072 + input_price: 1.4 + output_price: 5.6 + - name: ernie-x1.1-preview + max_input_tokens: 65536 + input_price: 0.14 + output_price: 0.56 + - name: bge-large-zh + type: embedding + input_price: 0.07 + max_tokens_per_chunk: 512 + default_chunk_size: 1000 + max_batch_size: 16 + - name: bge-large-en + type: embedding + input_price: 0.07 + max_tokens_per_chunk: 512 + default_chunk_size: 1000 + max_batch_size: 16 + - name: bce-reranker-base + type: reranker + max_input_tokens: 1024 + input_price: 0.07 + +- provider: qianwen + exclude: + - "*-realtime" + rules: + - match: "qwen3.5-plus" + patch: + body: + enable_thinking: false + - match: "qwen3.5-397b-a17b" + patch: + body: + enable_thinking: false + variants: + - match: "qwen3-max" + suffix: ":thinking" + real_name: qwen3-max + patch: + body: + enable_thinking: true + models: + - name: qwen3.5-plus:thinking + real_name: qwen3.5-plus + max_input_tokens: 262144 + supports_function_calling: true + - name: qwen3.5-397b-a17b:thinking + real_name: qwen3.5-397b-a17b + max_input_tokens: 262144 + supports_function_calling: true + - name: text-embedding-v4 + type: embedding + input_price: 0.1 + max_tokens_per_chunk: 8192 + default_chunk_size: 2000 + max_batch_size: 10 + - name: text-embedding-v3 + type: embedding + input_price: 0.1 + max_tokens_per_chunk: 8192 + default_chunk_size: 2000 + max_batch_size: 10 + # legacy -- pruning candidates + - name: qwen3-vl-flash + max_input_tokens: 262144 + supports_vision: true + - name: qwen3-235b-a22b-instruct-2507 + max_input_tokens: 131072 + input_price: 0.28 + output_price: 1.12 + supports_function_calling: true + - name: qwen3-235b-a22b-thinking-2507 + max_input_tokens: 131072 + input_price: 0.28 + output_price: 2.8 + - name: qwen3-30b-a3b-instruct-2507 + max_input_tokens: 131072 + input_price: 0.105 + output_price: 0.42 + supports_function_calling: true + - name: qwen3-30b-a3b-thinking-2507 + max_input_tokens: 131072 + input_price: 0.105 + output_price: 1.05 + - name: qwen3-vl-32b-instruct + max_input_tokens: 131072 + input_price: 0.28 + output_price: 1.12 + supports_vision: true + - name: qwen3-vl-8b-instruct + max_input_tokens: 131072 + input_price: 0.07 + output_price: 0.28 + supports_vision: true + - name: qwen3-coder-next + max_input_tokens: 262144 + +- provider: hunyuan + models: + - name: hunyuan-2.0-instruct-20251111 + max_input_tokens: 131072 + input_price: 0.112 + output_price: 0.28 + supports_function_calling: true + - name: hunyuan-2.0-thinking-20251109 + max_input_tokens: 131072 + input_price: 0.14 + output_price: 0.56 + supports_function_calling: true + - name: hunyuan-vision-1.5-instruct + max_input_tokens: 24576 + input_price: 0.42 + output_price: 1.26 + supports_vision: true + - name: hunyuan-embedding + type: embedding + input_price: 0.01 + max_tokens_per_chunk: 1024 + default_chunk_size: 1000 + max_batch_size: 100 + +- provider: deepseek + models: + # legacy -- pruning candidates + - name: deepseek-chat + max_input_tokens: 64000 + max_output_tokens: 8192 + input_price: 0.56 + output_price: 1.68 + supports_function_calling: true + - name: deepseek-reasoner + max_input_tokens: 64000 + max_output_tokens: 32768 + input_price: 0.56 + output_price: 1.68 + +- provider: zhipuai + variants: + - match: "glm-5" + suffix: ":instruct" + real_name: glm-5 + patch: + body: + thinking: + type: disabled + - match: "glm-4.7" + suffix: ":instruct" + real_name: glm-4.7 + patch: + body: + thinking: + type: disabled + models: + - name: embedding-3 + type: embedding + max_input_tokens: 8192 + input_price: 0.07 + max_tokens_per_chunk: 8192 + default_chunk_size: 2000 + - name: rerank + type: reranker + max_input_tokens: 4096 + input_price: 0.112 + # legacy -- pruning candidates + - name: glm-4.6v-flash + max_input_tokens: 65536 + input_price: 0 + output_price: 0 + supports_vision: true + +- provider: minimax + models: + # legacy -- pruning candidates + - name: minimax-m3 + max_input_tokens: 1000000 + input_price: 4.2 + output_price: 16.8 + supports_function_calling: true + - name: minimax-m2.7 + max_input_tokens: 204800 + input_price: 0.294 + output_price: 1.176 + supports_function_calling: true + - name: minimax-m2.5 + max_input_tokens: 204800 + input_price: 0.294 + output_price: 1.176 + supports_function_calling: true + - name: minimax-m2.5-highspeed + max_input_tokens: 204800 + input_price: 0.588 + output_price: 2.352 + supports_function_calling: true + - name: minimax-m2.1 + max_input_tokens: 204800 + input_price: 0.294 + output_price: 1.176 + supports_function_calling: true + - name: minimax-m2.1-highspeed + max_input_tokens: 204800 + input_price: 0.588 + output_price: 2.352 + supports_function_calling: true + +- provider: openrouter + rules: + - match: "anthropic/claude-*" + require_max_tokens: true + - match: "openai/gpt-5.6-*" + default_reasoning_effort: medium + reasoning_levels: [none, low, medium, high, xhigh, max] + - match: "openai/gpt-5.5" + default_reasoning_effort: medium + reasoning_levels: [none, low, medium, high, xhigh] + - match: "openai/gpt-5.5-pro" + default_reasoning_effort: high + reasoning_levels: [medium, high, xhigh] + - match: "openai/gpt-5.4" + default_reasoning_effort: none + reasoning_levels: [none, low, medium, high, xhigh] + - match: "openai/gpt-5.4-pro" + default_reasoning_effort: medium + reasoning_levels: [medium, high, xhigh] + - match: "openai/gpt-5.4-mini" + default_reasoning_effort: none + reasoning_levels: [none, low, medium, high, xhigh] + - match: "openai/gpt-5.4-nano" + default_reasoning_effort: none + reasoning_levels: [none, low, medium, high, xhigh] + - match: "openai/gpt-5.3-codex" + default_reasoning_effort: medium + reasoning_levels: [low, medium, high, xhigh] + - match: "openai/gpt-5.2" + default_reasoning_effort: none + reasoning_levels: [none, low, medium, high, xhigh] + - match: "openai/gpt-5.2-pro" + default_reasoning_effort: medium + reasoning_levels: [medium, high, xhigh] + - match: "openai/gpt-5" + default_reasoning_effort: medium + reasoning_levels: [minimal, low, medium, high] + - match: "google/gemini-3.5-flash" + default_reasoning_effort: medium + reasoning_levels: [minimal, low, medium, high] + - match: "google/gemini-3-flash-preview" + default_reasoning_effort: high + reasoning_levels: [minimal, low, medium, high] + - match: "google/gemini-3.1-flash-lite" + default_reasoning_effort: minimal + reasoning_levels: [minimal, low, medium, high] + - match: "google/gemini-3.1-pro-preview" + default_reasoning_effort: high + reasoning_levels: [low, medium, high] + - match: "google/gemini-3-pro-preview" + default_reasoning_effort: high + - match: "google/gemini-2.5-flash" + default_reasoning_effort: low + reasoning_levels: [low, medium, high] + - match: "google/gemini-2.5-pro" + default_reasoning_effort: high + reasoning_levels: [low, medium, high] + - match: "anthropic/claude-opus-5" + default_reasoning_effort: high + reasoning_levels: [low, medium, high, xhigh, max] + - match: "anthropic/claude-fable-*" + default_reasoning_effort: high + reasoning_levels: [low, medium, high, xhigh, max] + - match: "anthropic/claude-opus-4-8" + default_reasoning_effort: high + - match: "anthropic/claude-opus-4-7" + default_reasoning_effort: high + - match: "anthropic/claude-opus-4.6" + default_reasoning_effort: high + reasoning_levels: [low, medium, high, max] + - match: "anthropic/claude-sonnet-5" + default_reasoning_effort: high + reasoning_levels: [low, medium, high, xhigh, max] + - match: "anthropic/claude-sonnet-4.6" + default_reasoning_effort: high + reasoning_levels: [low, medium, high, max] + - match: "perplexity/sonar-reasoning-pro" + patch: + body: + include_reasoning: true + - match: "perplexity/sonar-deep-research" + patch: + body: + include_reasoning: true + models: + # legacy -- pruning candidates + - name: google/gemini-3-pro-preview + max_input_tokens: 1048576 + supports_vision: true + supports_function_calling: true + reasoning_levels: [low, high] + default_reasoning_effort: high + - name: google/gemini-2.0-flash-001 + max_input_tokens: 1000000 + input_price: 0.15 + output_price: 0.6 + supports_vision: true + supports_function_calling: true + - name: google/gemini-2.0-flash-lite-001 + max_input_tokens: 1048576 + input_price: 0.075 + output_price: 0.3 + supports_vision: true + supports_function_calling: true + - name: anthropic/claude-fable-5-1 + max_input_tokens: 1000000 + max_output_tokens: 128000 + require_max_tokens: true + input_price: 10 + output_price: 50 + supports_function_calling: true + supports_vision: true + reasoning_levels: [low, medium, high, xhigh, max] + default_reasoning_effort: high + - name: anthropic/claude-opus-4-8 + max_input_tokens: 1000000 + max_output_tokens: 128000 + require_max_tokens: true + input_price: 5 + output_price: 25 + supports_vision: true + supports_function_calling: true + reasoning_levels: [low, medium, high, xhigh, max] + default_reasoning_effort: high + - name: anthropic/claude-opus-4-7 + max_input_tokens: 1000000 + max_output_tokens: 128000 + require_max_tokens: true + input_price: 5 + output_price: 25 + supports_vision: true + supports_function_calling: true + reasoning_levels: [low, medium, high, xhigh, max] + default_reasoning_effort: high + - name: mistralai/devstral-small + max_input_tokens: 131072 + input_price: 0.07 + output_price: 0.28 + supports_function_calling: true + - name: ai21/jamba-large-1.7 + max_input_tokens: 256000 + input_price: 2 + output_price: 8 + supports_function_calling: true + - name: x-ai/grok-4.1-fast + max_input_tokens: 2000000 + input_price: 0.2 + output_price: 0.5 + supports_function_calling: true + - name: x-ai/grok-code-fast-1 + max_input_tokens: 256000 + input_price: 0.2 + output_price: 1.5 + supports_function_calling: true + +# Fully hand-owned: upstream catalogs track GitHub Copilot ids, which do not +# match the GitHub Models API ids coyote uses. +- provider: github + models: + - name: gpt-5 + max_input_tokens: 400000 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + - name: gpt-5-mini + max_input_tokens: 400000 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + - name: gpt-5-nano + max_input_tokens: 400000 + max_output_tokens: 128000 + supports_vision: true + supports_function_calling: true + - name: gpt-4.1 + max_input_tokens: 1047576 + max_output_tokens: 32768 + supports_vision: true + supports_function_calling: true + - name: gpt-4o + max_input_tokens: 128000 + max_output_tokens: 16384 + supports_function_calling: true + - name: text-embedding-3-large + type: embedding + max_tokens_per_chunk: 8191 + default_chunk_size: 2000 + max_batch_size: 100 + - name: text-embedding-3-small + type: embedding + max_tokens_per_chunk: 8191 + default_chunk_size: 2000 + max_batch_size: 100 + - name: llama-4-maverick-17b-128e-instruct-fp8 + max_input_tokens: 1048576 + supports_vision: true + - name: llama-4-scout-17b-16e-instruct + max_input_tokens: 327680 + supports_vision: true + - name: llama-3.3-70b-instruct + max_input_tokens: 131072 + - name: mistral-medium-2505 + max_input_tokens: 131072 + supports_function_calling: true + - name: mistral-small-2503 + max_input_tokens: 131072 + supports_function_calling: true + - name: codestral-2501 + max_input_tokens: 256000 + supports_function_calling: true + - name: cohere-embed-v3-english + type: embedding + max_tokens_per_chunk: 512 + default_chunk_size: 1000 + max_batch_size: 96 + - name: cohere-embed-v3-multilingual + type: embedding + max_tokens_per_chunk: 512 + default_chunk_size: 1000 + max_batch_size: 96 + - name: deepseek-r1-0528 + max_input_tokens: 163840 + - name: deepseek-v3-0324 + max_input_tokens: 163840 + - name: mai-ds-r1 + max_input_tokens: 163840 + - name: phi-4 + max_input_tokens: 16384 + - name: phi-4-mini-instruct + max_input_tokens: 131072 + - name: phi-4-reasoning + max_input_tokens: 33792 + - name: phi-4-mini-reasoning + max_input_tokens: 131072 + - name: grok-3 + max_input_tokens: 131072 + - name: grok-3-mini + max_input_tokens: 131072 + +- provider: deepinfra + models: + - name: BAAI/bge-large-en-v1.5 + type: embedding + input_price: 0.01 + max_tokens_per_chunk: 512 + default_chunk_size: 1000 + max_batch_size: 100 + - name: BAAI/bge-m3 + type: embedding + input_price: 0.01 + max_tokens_per_chunk: 8192 + default_chunk_size: 2000 + max_batch_size: 100 + - name: intfloat/e5-large-v2 + type: embedding + input_price: 0.01 + max_tokens_per_chunk: 512 + default_chunk_size: 1000 + max_batch_size: 100 + - name: intfloat/multilingual-e5-large + type: embedding + input_price: 0.01 + max_tokens_per_chunk: 512 + default_chunk_size: 1000 + max_batch_size: 100 + - name: thenlper/gte-large + type: embedding + input_price: 0.01 + max_tokens_per_chunk: 512 + default_chunk_size: 1000 + max_batch_size: 100 + # legacy -- pruning candidates + - name: Qwen/Qwen3-Max-Thinking + max_input_tokens: 262144 + input_price: 1.2 + output_price: 6 + supports_function_calling: true + - name: Qwen/Qwen3-Next-80B-A3B-Thinking + max_input_tokens: 262144 + input_price: 0.14 + output_price: 1.4 + - name: Qwen/Qwen3-235B-A22B-Thinking-2507 + max_input_tokens: 131072 + input_price: 0.13 + output_price: 0.6 + - name: Qwen/Qwen3-Coder-480B-A35B-Instruct + max_input_tokens: 131072 + input_price: 0.4 + output_price: 1.6 + supports_function_calling: true + - name: Qwen/Qwen3-Coder-30B-A3B-Instruct + max_input_tokens: 262144 + input_price: 0.07 + output_price: 0.27 + supports_function_calling: true + - name: Qwen/Qwen3-VL-8B-Instruct + max_input_tokens: 262144 + input_price: 0.18 + output_price: 0.69 + supports_vision: true + - name: google/gemma-3-27b-it + max_input_tokens: 131072 + input_price: 0.1 + output_price: 0.2 + - name: mistralai/Mistral-Small-3.2-24B-Instruct-2506 + max_input_tokens: 32768 + input_price: 0.06 + output_price: 0.12 + - name: moonshotai/Kimi-K2-Instruct-0905 + max_input_tokens: 262144 + input_price: 0.5 + output_price: 2.0 + supports_function_calling: true + - name: moonshotai/Kimi-K2-Thinking + max_input_tokens: 262144 + input_price: 0.55 + output_price: 2.5 + supports_function_calling: true + - name: MiniMaxAI/MiniMax-M2.1 + max_input_tokens: 196608 + input_price: 0.27 + output_price: 0.95 + supports_function_calling: true + - name: zai-org/GLM-4.6V + max_input_tokens: 131072 + input_price: 0.3 + output_price: 0.9 + supports_vision: true + +- provider: jina + models: + - name: jina-embeddings-v3 + type: embedding + input_price: 0 + max_tokens_per_chunk: 8192 + default_chunk_size: 2000 + max_batch_size: 100 + - name: jina-clip-v2 + type: embedding + input_price: 0 + max_tokens_per_chunk: 8192 + default_chunk_size: 1500 + max_batch_size: 100 + - name: jina-colbert-v2 + type: embedding + input_price: 0 + max_tokens_per_chunk: 8192 + default_chunk_size: 1500 + max_batch_size: 100 + - name: jina-reranker-v2-base-multilingual + type: reranker + max_input_tokens: 8192 + input_price: 0 + - name: jina-colbert-v2 + type: reranker + max_input_tokens: 8192 + input_price: 0 + +- provider: voyageai + models: + - name: voyage-3-large + type: embedding + max_input_tokens: 120000 + input_price: 0.18 + max_tokens_per_chunk: 32000 + default_chunk_size: 2000 + max_batch_size: 128 + - name: voyage-3 + type: embedding + max_input_tokens: 320000 + input_price: 0.06 + max_tokens_per_chunk: 32000 + default_chunk_size: 2000 + max_batch_size: 128 + - name: voyage-3-lite + type: embedding + max_input_tokens: 1000000 + input_price: 0.02 + max_tokens_per_chunk: 32000 + default_chunk_size: 1000 + max_batch_size: 128 + - name: rerank-2 + type: reranker + max_input_tokens: 16000 + input_price: 0.05 + - name: rerank-2-lite + type: reranker + max_input_tokens: 8000 + input_price: 0.02 diff --git a/scripts/requirements.txt b/scripts/requirements.txt deleted file mode 100644 index 69a538b..0000000 --- a/scripts/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -requests -ruamel.yaml diff --git a/scripts/update_models.py b/scripts/update_models.py deleted file mode 100644 index fab2014..0000000 --- a/scripts/update_models.py +++ /dev/null @@ -1,255 +0,0 @@ -import requests -import sys -import re -import json - -# Provider mapping from models.yaml to OpenRouter prefixes -PROVIDER_MAPPING = { - "openai": "openai", - "claude": "anthropic", - "gemini": "google", - "mistral": "mistralai", - "cohere": "cohere", - "perplexity": "perplexity", - "xai": "x-ai", - "openrouter": "openrouter", - "ai21": "ai21", - "deepseek": "deepseek", - "moonshot": "moonshotai", - "qianwen": "qwen", - "zhipuai": "zhipuai", - "minimax": "minimax", - "vertexai": "google", - "groq": "groq", - "bedrock": "amazon", - "hunyuan": "tencent", - "ernie": "baidu", - "github": "github", -} - -def fetch_openrouter_models(): - print("Fetching models from OpenRouter...") - try: - response = requests.get("https://openrouter.ai/api/v1/models") - response.raise_for_status() - data = response.json()["data"] - print(f"Fetched {len(data)} models.") - return data - except Exception as e: - print(f"Error fetching models: {e}") - sys.exit(1) - -def get_openrouter_model(models_data, provider_prefix, model_name, is_openrouter_provider=False): - if is_openrouter_provider: - # For openrouter provider, the model_name in yaml is usually the full ID - for model in models_data: - if model["id"] == model_name: - return model - return None - - expected_id = f"{provider_prefix}/{model_name}" - - # 1. Try exact match on ID - for model in models_data: - if model["id"] == expected_id: - return model - - # 2. Try match by suffix - for model in models_data: - if model["id"].split("/")[-1] == model_name: - if model["id"].startswith(f"{provider_prefix}/"): - return model - - return None - -def format_price(price_per_token): - if price_per_token is None: - return None - try: - price_per_1m = float(price_per_token) * 1_000_000 - if price_per_1m.is_integer(): - return str(int(price_per_1m)) - else: - return str(round(price_per_1m, 4)) - except: - return None - -def get_indentation(line): - return len(line) - len(line.lstrip()) - -def process_model_block(block_lines, current_provider, or_models): - if not block_lines: - return [] - - # 1. Identify model name and indentation - name_line = block_lines[0] - name_match = re.match(r"^(\s*)-\s*name:\s*(.+)$", name_line) - if not name_match: - return block_lines - - name_indent_str = name_match.group(1) - model_name = name_match.group(2).strip() - - # 2. Find OpenRouter model - or_prefix = PROVIDER_MAPPING.get(current_provider) - is_openrouter_provider = (current_provider == "openrouter") - - if not or_prefix and not is_openrouter_provider: - return block_lines - - or_model = get_openrouter_model(or_models, or_prefix, model_name, is_openrouter_provider) - if not or_model: - return block_lines - - print(f" Updating {model_name}...") - - # 3. Prepare updates - updates = {} - - # Pricing - pricing = or_model.get("pricing", {}) - p_in = format_price(pricing.get("prompt")) - p_out = format_price(pricing.get("completion")) - if p_in: updates["input_price"] = p_in - if p_out: updates["output_price"] = p_out - - # Context - ctx = or_model.get("context_length") - if ctx: updates["max_input_tokens"] = str(ctx) - - max_out = None - if "top_provider" in or_model and or_model["top_provider"]: - max_out = or_model["top_provider"].get("max_completion_tokens") - if max_out: updates["max_output_tokens"] = str(max_out) - - # Capabilities - arch = or_model.get("architecture", {}) - modality = arch.get("modality", "") - if "image" in modality: - updates["supports_vision"] = "true" - - # 4. Detect field indentation - field_indent_str = None - existing_fields = {} # key -> line_index - - for i, line in enumerate(block_lines): - if i == 0: continue # Skip name line - - # Skip comments - if line.strip().startswith("#"): - continue - - # Look for "key: value" - m = re.match(r"^(\s*)([\w_-]+):", line) - if m: - indent = m.group(1) - key = m.group(2) - # Must be deeper than name line - if len(indent) > len(name_indent_str): - if field_indent_str is None: - field_indent_str = indent - existing_fields[key] = i - - if field_indent_str is None: - field_indent_str = name_indent_str + " " - - # 5. Apply updates - new_block = list(block_lines) - - # Update existing fields - for key, value in updates.items(): - if key in existing_fields: - idx = existing_fields[key] - # Preserve original key indentation exactly - original_line = new_block[idx] - m = re.match(r"^(\s*)([\w_-]+):", original_line) - if m: - current_indent = m.group(1) - new_block[idx] = f"{current_indent}{key}: {value}\n" - - # Insert missing fields - # Insert after the name line - insertion_idx = 1 - - for key, value in updates.items(): - if key not in existing_fields: - new_line = f"{field_indent_str}{key}: {value}\n" - new_block.insert(insertion_idx, new_line) - insertion_idx += 1 - - return new_block - -def main(): - or_models = fetch_openrouter_models() - - print("Reading models.yaml...") - with open("models.yaml", "r") as f: - lines = f.readlines() - - new_lines = [] - current_provider = None - - i = 0 - while i < len(lines): - line = lines[i] - - # Check for provider - # - provider: name - p_match = re.match(r"^\s*-?\s*provider:\s*(.+)$", line) - if p_match: - current_provider = p_match.group(1).strip() - new_lines.append(line) - i += 1 - continue - - # Check for model start - # - name: ... - m_match = re.match(r"^(\s*)-\s*name:\s*.+$", line) - if m_match: - # Start of a model block - start_indent = len(m_match.group(1)) - - # Collect block lines - block_lines = [line] - j = i + 1 - while j < len(lines): - next_line = lines[j] - stripped = next_line.strip() - - # If empty or comment, include it - if not stripped or stripped.startswith("#"): - block_lines.append(next_line) - j += 1 - continue - - # Check indentation - next_indent = get_indentation(next_line) - - # If indentation is greater, it's part of the block (property) - if next_indent > start_indent: - block_lines.append(next_line) - j += 1 - continue - - # If indentation is equal or less, it's the end of the block - break - - # Process the block - processed_block = process_model_block(block_lines, current_provider, or_models) - new_lines.extend(processed_block) - - # Advance i - i = j - continue - - # Otherwise, just a regular line - new_lines.append(line) - i += 1 - - print("Saving models.yaml...") - with open("models.yaml", "w") as f: - f.writelines(new_lines) - print("Done.") - -if __name__ == "__main__": - main() diff --git a/src/cli/mod.rs b/src/cli/mod.rs index fbd3d92..f53658b 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -12,6 +12,7 @@ use clap_complete::ArgValueCompleter; use is_terminal::IsTerminal; use std::collections::HashSet; use std::io::{Read, stdin}; +use std::path::PathBuf; #[derive(clap::ValueEnum, Debug, Clone, Copy, PartialEq, Eq)] pub enum McpTransportArg { @@ -53,7 +54,7 @@ pub enum McpScopeArg { "install_builtins", "sync_models", "list_models", "list_roles", "list_sessions", "list_agents", "list_rags", "list_macros", "list_skills", "list_bundles", "skill", "tail_logs", "completions", - "update", "update_bundle", "uninstall", + "update", "update_bundle", "uninstall", "generate_models", ]) ), group( @@ -253,6 +254,15 @@ pub struct Cli { /// Sync models updates #[arg(long, help_heading = "Installation & Updates")] pub sync_models: bool, + /// Regenerate the models catalog file from live API data + #[arg( + long, + hide = true, + value_name = "PATH", + num_args = 0..=1, + default_missing_value = "models.yaml" + )] + pub generate_models: Option, /// Update Coyote to the latest release, or to a specific version #[arg(long, value_name = "VERSION", help_heading = "Installation & Updates")] pub update: Option>, @@ -810,6 +820,19 @@ mod tests { assert!(cli.sync_models); } + #[test] + fn parse_generate_models_flag() { + assert_eq!(parse(&[]).generate_models, None); + assert_eq!( + parse(&["--generate-models"]).generate_models, + Some(PathBuf::from("models.yaml")) + ); + assert_eq!( + parse(&["--generate-models", "out.yaml"]).generate_models, + Some(PathBuf::from("out.yaml")) + ); + } + #[test] fn parse_model_with_role() { let cli = parse(&["-m", "gpt-4o", "-r", "coder"]); diff --git a/src/client/catalog.rs b/src/client/catalog.rs new file mode 100644 index 0000000..29ac6ed --- /dev/null +++ b/src/client/catalog.rs @@ -0,0 +1,1653 @@ +use super::model::{ModelData, ProviderModels}; +use super::oauth::OAuthConfig; +use std::cmp::Ordering; + +use crate::utils::fetch; + +use anyhow::{Result, bail}; +use fancy_regex::Regex; +use log::warn; +use serde::{Deserialize, Serialize}; +use serde_json::Value; +use std::collections::{HashMap, HashSet}; +use std::fs; +use std::path::Path; +use std::sync::{Arc, LazyLock, Mutex}; + +pub const QUIRKS_YAML: &str = include_str!("../../quirks.yaml"); + +pub static ALL_QUIRKS: LazyLock> = + LazyLock::new(|| serde_yaml::from_str(QUIRKS_YAML).expect("quirks.yaml must be valid")); + +const MODELSDEV_API_URL: &str = "https://models.dev/api.json"; +const OPENROUTER_API_URL: &str = "https://openrouter.ai/api/v1/models"; + +struct SourceIds { + provider: &'static str, + modelsdev: Option<&'static str>, + openrouter: Option<&'static str>, +} + +const PROVIDER_SOURCES: [SourceIds; 24] = [ + SourceIds { + provider: "openai", + modelsdev: Some("openai"), + openrouter: Some("openai"), + }, + SourceIds { + provider: "gemini", + modelsdev: Some("google"), + openrouter: Some("google"), + }, + SourceIds { + provider: "claude", + modelsdev: Some("anthropic"), + openrouter: Some("anthropic"), + }, + SourceIds { + provider: "mistral", + modelsdev: Some("mistral"), + openrouter: Some("mistralai"), + }, + SourceIds { + provider: "ai21", + modelsdev: None, + openrouter: None, + }, + SourceIds { + provider: "cohere", + modelsdev: Some("cohere"), + openrouter: Some("cohere"), + }, + SourceIds { + provider: "xai", + modelsdev: Some("xai"), + openrouter: Some("x-ai"), + }, + SourceIds { + provider: "perplexity", + modelsdev: Some("perplexity"), + openrouter: Some("perplexity"), + }, + SourceIds { + provider: "groq", + modelsdev: Some("groq"), + openrouter: Some("groq"), + }, + SourceIds { + provider: "vertexai", + modelsdev: Some("google-vertex"), + openrouter: Some("google"), + }, + SourceIds { + provider: "bedrock", + modelsdev: Some("amazon-bedrock"), + openrouter: Some("amazon"), + }, + SourceIds { + provider: "cloudflare", + modelsdev: Some("cloudflare-workers-ai"), + openrouter: None, + }, + SourceIds { + provider: "ernie", + modelsdev: None, + openrouter: None, + }, + SourceIds { + provider: "qianwen", + modelsdev: Some("alibaba"), + openrouter: Some("qwen"), + }, + SourceIds { + provider: "hunyuan", + modelsdev: None, + openrouter: None, + }, + SourceIds { + provider: "moonshot", + modelsdev: Some("moonshotai"), + openrouter: Some("moonshotai"), + }, + SourceIds { + provider: "deepseek", + modelsdev: Some("deepseek"), + openrouter: Some("deepseek"), + }, + SourceIds { + provider: "zhipuai", + modelsdev: Some("zhipuai"), + openrouter: Some("zhipuai"), + }, + SourceIds { + provider: "minimax", + modelsdev: Some("minimax"), + openrouter: Some("minimax"), + }, + SourceIds { + provider: "openrouter", + modelsdev: None, + openrouter: None, + }, + SourceIds { + provider: "github", + modelsdev: None, + openrouter: None, + }, + SourceIds { + provider: "deepinfra", + modelsdev: Some("deepinfra"), + openrouter: None, + }, + SourceIds { + provider: "jina", + modelsdev: None, + openrouter: None, + }, + SourceIds { + provider: "voyageai", + modelsdev: None, + openrouter: None, + }, +]; + +pub struct FetchedSources { + pub modelsdev: Option, + pub openrouter: Option, +} + +pub async fn fetch_sources() -> FetchedSources { + let (modelsdev, openrouter) = tokio::join!(fetch(MODELSDEV_API_URL), fetch(OPENROUTER_API_URL)); + FetchedSources { + modelsdev: modelsdev + .inspect_err(|err| warn!("Failed to fetch {MODELSDEV_API_URL}: {err}")) + .ok(), + openrouter: openrouter + .inspect_err(|err| warn!("Failed to fetch {OPENROUTER_API_URL}: {err}")) + .ok(), + } +} + +struct SourcedModel { + data: ModelData, + release_date: Option, +} + +fn clamp_input_tokens(value: u64) -> Option { + (1..=50_000_000).contains(&value).then_some(value as usize) +} + +fn clamp_output_tokens(value: i64) -> Option { + (1..=10_000_000).contains(&value).then_some(value as isize) +} + +fn clamp_price(value: f64) -> Option { + (0.0..=10_000.0).contains(&value).then_some(value) +} + +fn modelsdev_provider_models(api: &Value, provider_id: &str) -> Vec { + let Some(models) = api[provider_id]["models"].as_object() else { + return Vec::new(); + }; + models + .iter() + .map(|(name, entry)| { + let mut data = ModelData::new(name); + data.max_input_tokens = entry["limit"]["context"] + .as_u64() + .and_then(clamp_input_tokens); + data.max_output_tokens = entry["limit"]["output"] + .as_i64() + .and_then(clamp_output_tokens); + data.input_price = entry["cost"]["input"].as_f64().and_then(clamp_price); + data.output_price = entry["cost"]["output"].as_f64().and_then(clamp_price); + data.supports_vision = entry["modalities"]["input"] + .as_array() + .is_some_and(|modes| modes.iter().any(|mode| mode.as_str() == Some("image"))); + data.supports_function_calling = entry["tool_call"].as_bool().unwrap_or(false); + data.reasoning_levels = entry["reasoning_options"] + .as_array() + .and_then(|options| { + options + .iter() + .find(|option| option["type"].as_str() == Some("effort")) + }) + .and_then(|option| option["values"].as_array()) + .map(|values| { + values + .iter() + .filter_map(|value| value.as_str().map(str::to_string)) + .collect() + }) + .unwrap_or_default(); + let release_date = entry["release_date"].as_str().map(str::to_string); + SourcedModel { data, release_date } + }) + .collect() +} + +fn openrouter_price(value: &Value) -> Option { + let per_token: f64 = value.as_str()?.parse().ok()?; + clamp_price((per_token * 1_000_000.0 * 10_000.0).round() / 10_000.0) +} + +fn openrouter_model_data(name: &str, entry: &Value) -> ModelData { + let mut data = ModelData::new(name); + data.max_input_tokens = entry["context_length"] + .as_u64() + .and_then(clamp_input_tokens); + data.max_output_tokens = entry["top_provider"]["max_completion_tokens"] + .as_i64() + .and_then(clamp_output_tokens); + data.input_price = openrouter_price(&entry["pricing"]["prompt"]); + data.output_price = openrouter_price(&entry["pricing"]["completion"]); + data.supports_vision = entry["architecture"]["modality"] + .as_str() + .is_some_and(|modality| modality.contains("image")); + data.supports_function_calling = entry["supported_parameters"] + .as_array() + .is_some_and(|params| params.iter().any(|param| param.as_str() == Some("tools"))); + data +} + +fn openrouter_index(payload: &Value) -> HashMap<&str, &Value> { + payload["data"] + .as_array() + .map(|entries| { + entries + .iter() + .filter_map(|entry| Some((entry["id"].as_str()?, entry))) + .collect() + }) + .unwrap_or_default() +} + +fn openrouter_native_models(payload: &Value) -> Vec { + payload["data"] + .as_array() + .map(|entries| { + entries + .iter() + .filter_map(|entry| { + let id = entry["id"].as_str()?; + Some(SourcedModel { + data: openrouter_model_data(id, entry), + release_date: None, + }) + }) + .collect() + }) + .unwrap_or_default() +} + +fn fill_from_openrouter(data: &mut ModelData, entry: &Value) { + let filler = openrouter_model_data(&data.name, entry); + if data.max_input_tokens.is_none() { + data.max_input_tokens = filler.max_input_tokens; + } + if data.max_output_tokens.is_none() { + data.max_output_tokens = filler.max_output_tokens; + } + if data.input_price.is_none() { + data.input_price = filler.input_price; + } + if data.output_price.is_none() { + data.output_price = filler.output_price; + } + if !data.supports_vision { + data.supports_vision = filler.supports_vision; + } + if !data.supports_function_calling { + data.supports_function_calling = filler.supports_function_calling; + } +} + +/// Outcome of a catalog merge. `degraded` lists API-mapped providers that fell +/// back to their hand-owned quirks models because API data was unavailable or +/// empty; `failed` lists providers that emitted nothing at all. +pub struct CatalogBuild { + pub providers: Vec, + pub degraded: Vec, + pub failed: Vec, +} + +/// Merges API-sourced model data with hand-owned quirks into the full +/// provider catalog, in the fixed provider order of [`PROVIDER_SOURCES`]. +/// +/// Per provider: API models (models.dev primary, OpenRouter gap-fill) are +/// curated by `exclude` globs and `rules`, hand-owned `models:` entries are +/// merged in field-wise (hand-owned wins) and placed first, API models are +/// sorted newest-first by release date (name-ascending tiebreak, undated +/// last), and `variants` clones are inserted immediately after their base +/// model. Providers without usable data are routed to `degraded` or `failed` +/// instead of erroring; a provider never emits zero models. +pub fn build_catalog(sources: &FetchedSources, quirks: &[ProviderQuirks]) -> CatalogBuild { + let modelsdev: Option = sources + .modelsdev + .as_deref() + .and_then(|payload| serde_json::from_str(payload).ok()); + let openrouter: Option = sources + .openrouter + .as_deref() + .and_then(|payload| serde_json::from_str(payload).ok()); + let or_index = openrouter + .as_ref() + .map(openrouter_index) + .unwrap_or_default(); + + let mut providers = Vec::new(); + let mut degraded = Vec::new(); + let mut failed = Vec::new(); + + for source in &PROVIDER_SOURCES { + let provider_quirks = quirks_for(quirks, source.provider); + let api_mapped = source.provider == "openrouter" || source.modelsdev.is_some(); + + let mut api_models: Vec = if source.provider == "openrouter" { + openrouter + .as_ref() + .map(openrouter_native_models) + .unwrap_or_default() + } else if let (Some(id), Some(api)) = (source.modelsdev, modelsdev.as_ref()) { + let mut models = modelsdev_provider_models(api, id); + if let Some(prefix) = source.openrouter { + for model in &mut models { + if let Some(entry) = + or_index.get(format!("{prefix}/{}", model.data.name).as_str()) + { + fill_from_openrouter(&mut model.data, entry); + } + } + } + models + } else { + Vec::new() + }; + + if let Some(provider_quirks) = provider_quirks { + api_models.retain(|model| { + !provider_quirks + .exclude + .iter() + .any(|pattern| glob_matches(pattern, &model.data.name)) + }); + for model in &mut api_models { + apply_rules(provider_quirks, &mut model.data); + } + } + + let hand_owned = provider_quirks + .map(|provider_quirks| provider_quirks.models.clone()) + .unwrap_or_default(); + + if api_models.is_empty() { + if hand_owned.is_empty() { + failed.push(source.provider.to_string()); + continue; + } + if api_mapped { + degraded.push(source.provider.to_string()); + } + } + + let mut merged_hand = Vec::with_capacity(hand_owned.len()); + for hand in hand_owned { + match api_models + .iter() + .position(|model| model.data.name == hand.name) + { + Some(position) => { + let api = api_models.remove(position); + merged_hand.push(overlay_hand_owned(hand, api.data)); + } + None => merged_hand.push(hand), + } + } + + api_models.sort_by(|a, b| match (&a.release_date, &b.release_date) { + (Some(a_date), Some(b_date)) => b_date + .cmp(a_date) + .then_with(|| a.data.name.cmp(&b.data.name)), + (Some(_), None) => Ordering::Less, + (None, Some(_)) => Ordering::Greater, + (None, None) => a.data.name.cmp(&b.data.name), + }); + + let bases = merged_hand + .into_iter() + .chain(api_models.into_iter().map(|model| model.data)); + + let variants = provider_quirks + .map(|provider_quirks| provider_quirks.variants.as_slice()) + .unwrap_or_default(); + let mut models = Vec::new(); + for base in bases { + let mut clones = Vec::new(); + for variant in variants { + if !glob_matches(&variant.r#match, &base.name) { + continue; + } + let mut clone = base.clone(); + clone.name = format!("{}{}", base.name, variant.suffix); + // Without an explicit real_name the clone would send its + // suffixed name on the wire; default to the base's wire name. + if clone.real_name.is_none() { + clone.real_name = Some(base.name.clone()); + } + apply_variant(variant, &mut clone); + clones.push(clone); + } + models.push(base); + models.append(&mut clones); + } + + providers.push(ProviderModels { + provider: source.provider.to_string(), + oauth: provider_quirks.and_then(|provider_quirks| provider_quirks.oauth.clone()), + models, + }); + } + + CatalogBuild { + providers, + degraded, + failed, + } +} + +pub fn build_catalog_strict( + sources: &FetchedSources, + quirks: &[ProviderQuirks], +) -> Result> { + let build = build_catalog(sources, quirks); + if !build.degraded.is_empty() || !build.failed.is_empty() { + bail!( + "model catalog build incomplete: degraded providers [{}], failed providers [{}]", + build.degraded.join(", "), + build.failed.join(", ") + ); + } + + Ok(build.providers) +} + +/// Replaces or inserts the entry of every degraded/failed provider from the +/// embedded catalog, preserving the fixed provider order of +/// [`PROVIDER_SOURCES`]. A synced override must never carry fewer models for a +/// provider than the embedded catalog: an upstream outage would otherwise +/// shrink the model list until the next successful sync. +pub fn backfill_embedded_floor(build: &mut CatalogBuild, embedded: &[ProviderModels]) { + let needs_backfill: HashSet<&str> = build + .degraded + .iter() + .chain(build.failed.iter()) + .map(String::as_str) + .collect(); + if needs_backfill.is_empty() { + return; + } + let mut providers = Vec::with_capacity(PROVIDER_SOURCES.len()); + for source in &PROVIDER_SOURCES { + let built = build + .providers + .iter() + .position(|provider| provider.provider == source.provider) + .map(|position| build.providers.remove(position)); + if needs_backfill.contains(source.provider) + && let Some(entry) = embedded + .iter() + .find(|provider| provider.provider == source.provider) + { + providers.push(entry.clone()); + continue; + } + if let Some(built) = built { + providers.push(built); + } + } + build.providers = providers; +} + +const GENERATED_HEADER: &str = "# GENERATED by 'coyote --generate-models'\n# DO NOT hand-edit model data.\n\ +# Hand-owned behavior lives in quirks.yaml; this file is the embedded offline fallback.\n"; + +pub async fn generate_models_file(path: &Path) -> Result<()> { + let sources = fetch_sources().await; + if sources.modelsdev.is_none() || sources.openrouter.is_none() { + bail!( + "generating the models file requires both catalog sources; see the log for the failed fetch" + ); + } + let providers = build_catalog_strict(&sources, &ALL_QUIRKS)?; + let model_count: usize = providers.iter().map(|provider| provider.models.len()).sum(); + let yaml = serde_yaml::to_string(&providers)?; + + fs::write(path, format!("{GENERATED_HEADER}{yaml}"))?; + println!( + "Wrote {} models across {} providers to {}", + model_count, + providers.len(), + path.display() + ); + + Ok(()) +} + +#[cfg(test)] +pub(crate) fn name_overlap(old: &[String], new: &[String]) -> f64 { + if old.is_empty() { + return 1.0; + } + let new_names: HashSet<&str> = new.iter().map(String::as_str).collect(); + let kept = old + .iter() + .filter(|name| new_names.contains(name.as_str())) + .count(); + kept as f64 / old.len() as f64 +} + +fn overlay_hand_owned(hand: ModelData, api: ModelData) -> ModelData { + ModelData { + name: hand.name, + model_type: hand.model_type, + real_name: hand.real_name.or(api.real_name), + max_input_tokens: hand.max_input_tokens.or(api.max_input_tokens), + input_price: hand.input_price.or(api.input_price), + output_price: hand.output_price.or(api.output_price), + patch: hand.patch.or(api.patch), + max_output_tokens: hand.max_output_tokens.or(api.max_output_tokens), + require_max_tokens: hand.require_max_tokens || api.require_max_tokens, + supports_vision: hand.supports_vision || api.supports_vision, + supports_function_calling: hand.supports_function_calling || api.supports_function_calling, + reasoning_levels: if hand.reasoning_levels.is_empty() { + api.reasoning_levels + } else { + hand.reasoning_levels + }, + default_reasoning_effort: hand + .default_reasoning_effort + .or(api.default_reasoning_effort), + no_stream: hand.no_stream || api.no_stream, + no_system_message: hand.no_system_message || api.no_system_message, + system_prompt_prefix: hand.system_prompt_prefix.or(api.system_prompt_prefix), + max_tokens_per_chunk: hand.max_tokens_per_chunk.or(api.max_tokens_per_chunk), + default_chunk_size: hand.default_chunk_size.or(api.default_chunk_size), + max_batch_size: hand.max_batch_size.or(api.max_batch_size), + } +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct ProviderQuirks { + pub provider: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub oauth: Option, + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub exclude: Vec, + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub rules: Vec, + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub variants: Vec, + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub models: Vec, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct QuirkRule { + pub r#match: String, + #[serde(skip_serializing_if = "Option::is_none")] + pub real_name: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub max_input_tokens: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub max_output_tokens: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub input_price: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub output_price: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub patch: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub require_max_tokens: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub supports_vision: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub supports_function_calling: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub reasoning_levels: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + pub default_reasoning_effort: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub no_stream: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub no_system_message: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub system_prompt_prefix: Option, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct QuirkVariant { + pub r#match: String, + pub suffix: String, + #[serde(skip_serializing_if = "Option::is_none")] + pub real_name: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub max_input_tokens: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub max_output_tokens: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub input_price: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub output_price: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub patch: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub require_max_tokens: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub supports_vision: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub supports_function_calling: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub reasoning_levels: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + pub default_reasoning_effort: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub no_stream: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub no_system_message: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub system_prompt_prefix: Option, +} + +pub fn apply_rules(provider_quirks: &ProviderQuirks, data: &mut ModelData) { + for rule in &provider_quirks.rules { + if !glob_matches(&rule.r#match, &data.name) { + continue; + } + if let Some(real_name) = &rule.real_name { + data.real_name = Some(real_name.clone()); + } + if let Some(max_input_tokens) = rule.max_input_tokens { + data.max_input_tokens = Some(max_input_tokens); + } + if let Some(max_output_tokens) = rule.max_output_tokens { + data.max_output_tokens = Some(max_output_tokens); + } + if let Some(input_price) = rule.input_price { + data.input_price = Some(input_price); + } + if let Some(output_price) = rule.output_price { + data.output_price = Some(output_price); + } + if let Some(patch) = &rule.patch { + data.patch = Some(patch.clone()); + } + if let Some(require_max_tokens) = rule.require_max_tokens { + data.require_max_tokens = require_max_tokens; + } + if let Some(supports_vision) = rule.supports_vision { + data.supports_vision = supports_vision; + } + if let Some(supports_function_calling) = rule.supports_function_calling { + data.supports_function_calling = supports_function_calling; + } + if let Some(reasoning_levels) = &rule.reasoning_levels { + data.reasoning_levels = reasoning_levels.clone(); + } + if let Some(default_reasoning_effort) = &rule.default_reasoning_effort { + data.default_reasoning_effort = Some(default_reasoning_effort.clone()); + } + if let Some(no_stream) = rule.no_stream { + data.no_stream = no_stream; + } + if let Some(no_system_message) = rule.no_system_message { + data.no_system_message = no_system_message; + } + if let Some(system_prompt_prefix) = &rule.system_prompt_prefix { + data.system_prompt_prefix = Some(system_prompt_prefix.clone()); + } + } +} + +fn apply_variant(variant: &QuirkVariant, data: &mut ModelData) { + if let Some(real_name) = &variant.real_name { + data.real_name = Some(real_name.clone()); + } + if let Some(max_input_tokens) = variant.max_input_tokens { + data.max_input_tokens = Some(max_input_tokens); + } + if let Some(max_output_tokens) = variant.max_output_tokens { + data.max_output_tokens = Some(max_output_tokens); + } + if let Some(input_price) = variant.input_price { + data.input_price = Some(input_price); + } + if let Some(output_price) = variant.output_price { + data.output_price = Some(output_price); + } + if let Some(patch) = &variant.patch { + data.patch = Some(patch.clone()); + } + if let Some(require_max_tokens) = variant.require_max_tokens { + data.require_max_tokens = require_max_tokens; + } + if let Some(supports_vision) = variant.supports_vision { + data.supports_vision = supports_vision; + } + if let Some(supports_function_calling) = variant.supports_function_calling { + data.supports_function_calling = supports_function_calling; + } + if let Some(reasoning_levels) = &variant.reasoning_levels { + data.reasoning_levels = reasoning_levels.clone(); + } + if let Some(default_reasoning_effort) = &variant.default_reasoning_effort { + data.default_reasoning_effort = Some(default_reasoning_effort.clone()); + } + if let Some(no_stream) = variant.no_stream { + data.no_stream = no_stream; + } + if let Some(no_system_message) = variant.no_system_message { + data.no_system_message = no_system_message; + } + if let Some(system_prompt_prefix) = &variant.system_prompt_prefix { + data.system_prompt_prefix = Some(system_prompt_prefix.clone()); + } +} + +pub fn quirks_for<'a>( + quirks: &'a [ProviderQuirks], + client_name: &str, +) -> Option<&'a ProviderQuirks> { + quirks + .iter() + .find(|quirks| quirks.provider == client_name) + .or_else(|| { + quirks + .iter() + .find(|quirks| client_name.starts_with(&quirks.provider)) + }) +} + +static GLOB_CACHE: LazyLock>>> = + LazyLock::new(|| Mutex::new(HashMap::new())); + +fn glob_matches(pattern: &str, name: &str) -> bool { + let regex = { + let mut cache = GLOB_CACHE + .lock() + .unwrap_or_else(|poison| poison.into_inner()); + cache + .entry(pattern.to_string()) + .or_insert_with(|| Arc::new(compile_glob(pattern))) + .clone() + }; + regex.is_match(name).unwrap_or(false) +} + +fn compile_glob(pattern: &str) -> Regex { + let translated = format!( + "^{}$", + fancy_regex::escape(pattern) + .replace("\\*", ".*") + .replace("\\?", ".") + ); + Regex::new(&translated).unwrap_or_else(|error| { + warn!("Invalid model quirk pattern '{pattern}': {error}. It will match nothing."); + Regex::new("(?!)").expect("'(?!)' is a valid never-matching regex") + }) +} + +#[cfg(test)] +mod tests { + use super::*; + + use crate::client::MODELS_YAML; + use serde_json::json; + + const KNOWN_PROVIDERS: [&str; 24] = [ + "openai", + "gemini", + "claude", + "mistral", + "ai21", + "cohere", + "xai", + "perplexity", + "groq", + "vertexai", + "bedrock", + "cloudflare", + "ernie", + "qianwen", + "hunyuan", + "moonshot", + "deepseek", + "zhipuai", + "minimax", + "openrouter", + "github", + "deepinfra", + "jina", + "voyageai", + ]; + + const MODELSDEV_FIXTURE: &str = include_str!("testdata/modelsdev_fixture.json"); + const OPENROUTER_FIXTURE: &str = include_str!("testdata/openrouter_fixture.json"); + + fn make_sources(modelsdev: Option<&str>, openrouter: Option<&str>) -> FetchedSources { + FetchedSources { + modelsdev: modelsdev.map(str::to_string), + openrouter: openrouter.map(str::to_string), + } + } + + fn fixture_sources() -> FetchedSources { + make_sources(Some(MODELSDEV_FIXTURE), Some(OPENROUTER_FIXTURE)) + } + + fn parse_quirks(yaml: &str) -> Vec { + serde_yaml::from_str(yaml).unwrap() + } + + fn find_provider<'a>(build: &'a CatalogBuild, provider: &str) -> &'a ProviderModels { + build + .providers + .iter() + .find(|candidate| candidate.provider == provider) + .unwrap_or_else(|| panic!("provider '{provider}' missing")) + } + + fn find_model<'a>(provider: &'a ProviderModels, name: &str) -> &'a ModelData { + provider + .models + .iter() + .find(|model| model.name == name) + .unwrap_or_else(|| panic!("model '{name}' missing")) + } + + #[test] + fn quirks_yaml_parses() { + assert!(!ALL_QUIRKS.is_empty()); + for quirks in ALL_QUIRKS.iter() { + assert!( + KNOWN_PROVIDERS.contains(&quirks.provider.as_str()), + "unknown provider '{}' in quirks.yaml", + quirks.provider + ); + } + } + + #[test] + fn provider_sources_match_known_providers() { + let order: Vec<&str> = PROVIDER_SOURCES + .iter() + .map(|source| source.provider) + .collect(); + + assert_eq!(order, KNOWN_PROVIDERS); + } + + #[test] + fn quirks_models_no_dropped_keys() { + let skipped_when_default = [ + "type", + "require_max_tokens", + "supports_vision", + "supports_function_calling", + "reasoning_levels", + "no_stream", + "no_system_message", + ]; + let raw: serde_yaml::Value = serde_yaml::from_str(QUIRKS_YAML).unwrap(); + for provider in raw.as_sequence().unwrap() { + let Some(models) = provider + .get("models") + .and_then(|models| models.as_sequence()) + else { + continue; + }; + for entry in models { + let parsed: ModelData = serde_yaml::from_value(entry.clone()).unwrap(); + let reserialized = serde_yaml::to_value(&parsed).unwrap(); + let reserialized_keys: Vec<&str> = reserialized + .as_mapping() + .unwrap() + .keys() + .map(|key| key.as_str().unwrap()) + .collect(); + for key in entry.as_mapping().unwrap().keys() { + let key = key.as_str().unwrap(); + assert!( + reserialized_keys.contains(&key) || skipped_when_default.contains(&key), + "key '{key}' on model '{}' was dropped by ModelData", + parsed.name + ); + } + } + } + } + + #[test] + fn rules_apply_in_order() { + let quirks: ProviderQuirks = serde_yaml::from_str( + r#" +provider: openai +rules: + - match: "model-*" + default_reasoning_effort: low + require_max_tokens: true + - match: "model-a" + default_reasoning_effort: high +"#, + ) + .unwrap(); + + let mut matched_by_both = ModelData::new("model-a"); + apply_rules(&quirks, &mut matched_by_both); + assert_eq!( + matched_by_both.default_reasoning_effort.as_deref(), + Some("high") + ); + assert!(matched_by_both.require_max_tokens); + + let mut matched_by_glob = ModelData::new("model-b"); + apply_rules(&quirks, &mut matched_by_glob); + assert_eq!( + matched_by_glob.default_reasoning_effort.as_deref(), + Some("low") + ); + + let mut unmatched = ModelData::new("other"); + apply_rules(&quirks, &mut unmatched); + assert_eq!(unmatched.default_reasoning_effort, None); + assert!(!unmatched.require_max_tokens); + } + + #[test] + fn glob_semantics() { + assert!(glob_matches("claude-*", "claude-opus-4-8")); + assert!(!glob_matches("claude-*", "gpt-4")); + assert!(glob_matches("claude-*", "claude-")); + assert!(glob_matches("gpt-?", "gpt-4")); + assert!(!glob_matches("gpt-?", "gpt-45")); + assert!(!glob_matches("gpt-?", "gpt-")); + assert!(glob_matches("o3", "o3")); + assert!(!glob_matches("o3", "o3-mini")); + } + + #[test] + fn modelsdev_adapter_maps_fields() { + let api: Value = serde_json::from_str(MODELSDEV_FIXTURE).unwrap(); + + let openai = modelsdev_provider_models(&api, "openai"); + let gpt56 = openai + .iter() + .find(|model| model.data.name == "gpt-5.6") + .unwrap(); + assert_eq!(gpt56.data.max_input_tokens, Some(1_050_000)); + assert_eq!(gpt56.data.max_output_tokens, Some(128_000)); + assert_eq!(gpt56.data.input_price, Some(4.0)); + assert_eq!(gpt56.data.output_price, Some(20.0)); + assert!(gpt56.data.supports_vision); + assert!(gpt56.data.supports_function_calling); + assert_eq!( + gpt56.data.reasoning_levels, + ["none", "low", "medium", "high", "xhigh", "max"] + ); + assert_eq!(gpt56.release_date.as_deref(), Some("2026-07-09")); + + let alibaba = modelsdev_provider_models(&api, "alibaba"); + assert_eq!(alibaba.len(), 1); + let qwen = &alibaba[0]; + assert_eq!(qwen.data.name, "qwen-max"); + assert_eq!(qwen.data.max_input_tokens, Some(32_768)); + assert_eq!(qwen.data.max_output_tokens, Some(8_192)); + assert_eq!(qwen.data.input_price, Some(1.6)); + assert_eq!(qwen.data.output_price, Some(6.4)); + assert!(!qwen.data.supports_vision); + assert!(qwen.data.supports_function_calling); + assert!(qwen.data.reasoning_levels.is_empty()); + assert_eq!(qwen.release_date.as_deref(), Some("2024-04-03")); + + assert!(modelsdev_provider_models(&api, "no-such-provider").is_empty()); + } + + #[test] + fn openrouter_adapter_maps_fields() { + let payload: Value = serde_json::from_str(OPENROUTER_FIXTURE).unwrap(); + let index = openrouter_index(&payload); + + let data = openrouter_model_data("gpt-4.1", index["openai/gpt-4.1"]); + assert_eq!(data.max_input_tokens, Some(1_047_576)); + assert_eq!(data.max_output_tokens, Some(32_768)); + assert_eq!(data.input_price, Some(2.0)); + assert_eq!(data.output_price, Some(8.0)); + assert!(data.supports_vision); + assert!(data.supports_function_calling); + + let rounded = openrouter_model_data( + "m", + &json!({"pricing": {"prompt": "0.00000123456789", "completion": "0.0000025"}}), + ); + assert_eq!(rounded.input_price, Some(1.2346)); + assert_eq!(rounded.output_price, Some(2.5)); + } + + #[test] + fn clamps_drop_out_of_range_fields() { + let api = json!({ + "p": {"models": {"m": { + "limit": {"context": 100_000_000, "output": 0}, + "cost": {"input": -1.0, "output": 20_000.0}, + }}} + }); + let models = modelsdev_provider_models(&api, "p"); + assert_eq!(models.len(), 1); + let data = &models[0].data; + assert_eq!(data.name, "m"); + assert_eq!(data.max_input_tokens, None); + assert_eq!(data.max_output_tokens, None); + assert_eq!(data.input_price, None); + assert_eq!(data.output_price, None); + + let data = openrouter_model_data( + "m", + &json!({ + "context_length": 60_000_000, + "top_provider": {"max_completion_tokens": 20_000_000}, + "pricing": {"prompt": "-0.000001", "completion": "999"}, + }), + ); + assert_eq!(data.max_input_tokens, None); + assert_eq!(data.max_output_tokens, None); + assert_eq!(data.input_price, None); + assert_eq!(data.output_price, None); + } + + #[test] + fn adapters_never_set_quirks_owned_fields() { + let api: Value = serde_json::from_str(MODELSDEV_FIXTURE).unwrap(); + let payload: Value = serde_json::from_str(OPENROUTER_FIXTURE).unwrap(); + let mut all: Vec = ["openai", "anthropic", "xai", "alibaba"] + .iter() + .flat_map(|id| modelsdev_provider_models(&api, id)) + .collect(); + + all.extend(openrouter_native_models(&payload)); + + assert!(!all.is_empty()); + for model in &all { + let data = &model.data; + assert_eq!(data.model_type, "chat", "{}", data.name); + assert!(data.patch.is_none(), "{}", data.name); + assert!(data.real_name.is_none(), "{}", data.name); + assert!(data.system_prompt_prefix.is_none(), "{}", data.name); + assert!(data.max_tokens_per_chunk.is_none(), "{}", data.name); + assert!(data.default_chunk_size.is_none(), "{}", data.name); + assert!(data.max_batch_size.is_none(), "{}", data.name); + } + } + + #[test] + fn oauth_comes_only_from_quirks() { + let without_quirks = build_catalog(&fixture_sources(), &[]); + assert!( + without_quirks + .providers + .iter() + .all(|provider| provider.oauth.is_none()) + ); + + let quirks = parse_quirks( + r#" +- provider: xai + oauth: + client_id: id + token_url: https://example.com/token +"#, + ); + + let build = build_catalog(&fixture_sources(), &quirks); + + assert!(find_provider(&build, "xai").oauth.is_some()); + assert!(find_provider(&build, "openai").oauth.is_none()); + } + + #[test] + fn merge_precedence_hand_owned_beats_rule_beats_modelsdev_beats_openrouter() { + let modelsdev = json!({ + "xai": {"models": { + "m-1": {"limit": {"context": 1000}, "cost": {"input": 1.0}}, + "m-2": {"limit": {"context": 1000}}, + }} + }) + .to_string(); + let openrouter = json!({"data": [ + { + "id": "x-ai/m-1", + "context_length": 2000, + "pricing": {"prompt": "0.000003", "completion": "0.000004"}, + "top_provider": {"max_completion_tokens": 512}, + }, + {"id": "x-ai/m-2", "context_length": 2000}, + ]}) + .to_string(); + let quirks = parse_quirks( + r#" +- provider: xai + rules: + - match: "m-1" + input_price: 5 + max_input_tokens: 3000 + models: + - name: m-1 + input_price: 7 +"#, + ); + let build = build_catalog(&make_sources(Some(&modelsdev), Some(&openrouter)), &quirks); + let xai = find_provider(&build, "xai"); + + let merged = find_model(xai, "m-1"); + // hand-owned beats the rule, which beat models.dev, which beat openrouter + assert_eq!(merged.input_price, Some(7.0)); + // rule beats models.dev + assert_eq!(merged.max_input_tokens, Some(3000)); + // openrouter fills fields models.dev left unset + assert_eq!(merged.output_price, Some(4.0)); + assert_eq!(merged.max_output_tokens, Some(512)); + + // models.dev beats openrouter on the same field + assert_eq!(find_model(xai, "m-2").max_input_tokens, Some(1000)); + } + + #[test] + fn excludes_drop_api_models_but_never_hand_owned() { + let quirks = parse_quirks( + r#" +- provider: openai + exclude: + - "gpt-4*" + models: + - name: gpt-4.1 + input_price: 9 +"#, + ); + let build = build_catalog(&fixture_sources(), &quirks); + let openai = find_provider(&build, "openai"); + assert!(openai.models.iter().all(|model| model.name != "gpt-4o")); + find_model(openai, "gpt-5.6"); + let hand = find_model(openai, "gpt-4.1"); + assert_eq!(hand.input_price, Some(9.0)); + // the API copy was excluded before the merge, so nothing leaked in + assert_eq!(hand.max_input_tokens, None); + } + + #[test] + fn variant_expansion() { + let quirks = parse_quirks( + r#" +- provider: xai + variants: + - match: "grok-4.6" + suffix: ":thinking" + max_output_tokens: 24000 + patch: + body: + thinking: true + - match: "grok-4.5" + suffix: ":fast" + real_name: grok-4.5-fast +"#, + ); + let build = build_catalog(&fixture_sources(), &quirks); + let xai = find_provider(&build, "xai"); + let names: Vec<&str> = xai.models.iter().map(|model| model.name.as_str()).collect(); + assert_eq!( + names, + ["grok-4.6", "grok-4.6:thinking", "grok-4.5", "grok-4.5:fast"] + ); + + let thinking = find_model(xai, "grok-4.6:thinking"); + assert_eq!(thinking.real_name.as_deref(), Some("grok-4.6")); + assert_eq!(thinking.max_output_tokens, Some(24_000)); + assert_eq!(thinking.patch, Some(json!({"body": {"thinking": true}}))); + + assert_eq!( + find_model(xai, "grok-4.5:fast").real_name.as_deref(), + Some("grok-4.5-fast") + ); + assert_eq!(find_model(xai, "grok-4.6").real_name, None); + } + + #[test] + fn ordering_hand_owned_first_then_release_date_desc_name_asc() { + let shuffled_payloads = [ + r#"{"openai":{"models":{ + "b":{"release_date":"2026-05-01"}, + "a":{"release_date":"2026-05-01"}, + "c":{"release_date":"2026-06-01"}, + "z":{}, + "y":{} + }}}"#, + r#"{"openai":{"models":{ + "y":{}, + "c":{"release_date":"2026-06-01"}, + "z":{}, + "a":{"release_date":"2026-05-01"}, + "b":{"release_date":"2026-05-01"} + }}}"#, + ]; + let quirks = parse_quirks( + r#" +- provider: openai + models: + - name: n2 + - name: n1 +"#, + ); + for payload in shuffled_payloads { + let build = build_catalog(&make_sources(Some(payload), None), &quirks); + let names: Vec<&str> = find_provider(&build, "openai") + .models + .iter() + .map(|model| model.name.as_str()) + .collect(); + assert_eq!(names, ["n2", "n1", "c", "a", "b", "y", "z"]); + } + } + + #[test] + fn catalog_round_trips_through_yaml() { + let build = build_catalog(&fixture_sources(), &ALL_QUIRKS); + assert!(!build.providers.is_empty()); + let yaml = serde_yaml::to_string(&build.providers).unwrap(); + let parsed: Vec = serde_yaml::from_str(&yaml).unwrap(); + assert_eq!(serde_yaml::to_string(&parsed).unwrap(), yaml); + } + + #[test] + fn openrouter_native_models_use_full_ids() { + let build = build_catalog(&fixture_sources(), &[]); + let openrouter = find_provider(&build, "openrouter"); + assert_eq!(openrouter.models.len(), 8); + + let auto = find_model(openrouter, "openrouter/auto"); + assert_eq!(auto.max_input_tokens, Some(2_000_000)); + // null max_completion_tokens and the "-1" sentinel prices are dropped + assert_eq!(auto.max_output_tokens, None); + assert_eq!(auto.input_price, None); + assert_eq!(auto.output_price, None); + assert!(auto.supports_vision); + assert!(auto.supports_function_calling); + + let free = find_model(openrouter, "openrouter/free"); + assert_eq!(free.max_input_tokens, Some(200_000)); + assert_eq!(free.input_price, Some(0.0)); + assert_eq!(free.output_price, Some(0.0)); + + // no release dates upstream, so full ids sort ascending + let names: Vec<&str> = openrouter + .models + .iter() + .map(|model| model.name.as_str()) + .collect(); + let mut sorted = names.clone(); + sorted.sort_unstable(); + assert_eq!(names, sorted); + } + + #[test] + fn failure_routing_degraded_and_failed() { + let quirks = parse_quirks( + r#" +- provider: gemini + models: [{name: g-1}] +- provider: ai21 + models: [{name: jamba}] +"#, + ); + + let build = build_catalog(&make_sources(None, None), &quirks); + + assert_eq!(build.degraded, ["gemini"]); + assert!(build.failed.contains(&"openai".to_string())); + assert!(build.failed.contains(&"openrouter".to_string())); + assert!(build.failed.contains(&"jina".to_string())); + assert!(!build.failed.contains(&"gemini".to_string())); + assert!(!build.failed.contains(&"ai21".to_string())); + assert!(!build.degraded.contains(&"ai21".to_string())); + + let providers: Vec<&str> = build + .providers + .iter() + .map(|provider| provider.provider.as_str()) + .collect(); + assert_eq!(providers, ["gemini", "ai21"]); + assert!( + build + .providers + .iter() + .all(|provider| !provider.models.is_empty()) + ); + } + + #[test] + fn strict_errors_on_degraded_or_failed() { + let quirks = parse_quirks( + r#" +- provider: gemini + models: [{name: g-1}] +"#, + ); + + let err = build_catalog_strict(&make_sources(None, None), &quirks) + .unwrap_err() + .to_string(); + + assert!(err.contains("gemini"), "{err}"); + assert!(err.contains("openai"), "{err}"); + } + + #[test] + fn strict_succeeds_when_every_provider_resolves() { + let mut api = serde_json::Map::new(); + for source in &PROVIDER_SOURCES { + if let Some(id) = source.modelsdev { + api.insert(id.to_string(), json!({"models": {"m": {}}})); + } + } + let modelsdev = Value::Object(api).to_string(); + let openrouter = json!({"data": [{"id": "openrouter/auto"}]}).to_string(); + let quirks = parse_quirks( + r#" +- provider: ai21 + models: [{name: a}] +- provider: ernie + models: [{name: e}] +- provider: hunyuan + models: [{name: h}] +- provider: github + models: [{name: g}] +- provider: jina + models: [{name: j}] +- provider: voyageai + models: [{name: v}] +"#, + ); + + let providers = + build_catalog_strict(&make_sources(Some(&modelsdev), Some(&openrouter)), &quirks) + .unwrap(); + let order: Vec<&str> = providers + .iter() + .map(|provider| provider.provider.as_str()) + .collect(); + + assert_eq!(order, KNOWN_PROVIDERS); + } + + #[test] + fn name_overlap_fraction_of_old_names_still_present() { + let old: Vec = ["a", "b", "c", "d"].map(str::to_string).into(); + let new: Vec = ["a", "c", "x"].map(str::to_string).into(); + + assert_eq!(name_overlap(&old, &new), 0.5); + assert_eq!(name_overlap(&[], &new), 1.0); + assert_eq!(name_overlap(&old, &[]), 0.0); + } + + fn embedded_catalog() -> Vec { + serde_yaml::from_str(MODELS_YAML).unwrap() + } + + fn embedded_provider<'a>(providers: &'a [ProviderModels], name: &str) -> &'a ProviderModels { + providers + .iter() + .find(|provider| provider.provider == name) + .unwrap_or_else(|| panic!("provider '{name}' missing from models.yaml")) + } + + #[test] + fn embedded_catalog_invariants() { + let providers = embedded_catalog(); + assert!(providers.len() >= 24); + let order: Vec<&str> = providers + .iter() + .map(|provider| provider.provider.as_str()) + .collect(); + assert_eq!(order, KNOWN_PROVIDERS); + + assert!(embedded_provider(&providers, "xai").oauth.is_some()); + for name in ["jina", "voyageai"] { + assert!( + embedded_provider(&providers, name) + .models + .iter() + .any(|model| model.model_type == "embedding"), + "{name} lost its embedding models" + ); + } + assert!( + embedded_provider(&providers, "cohere") + .models + .iter() + .any(|model| model.model_type == "reranker"), + "cohere lost its reranker models" + ); + + for provider in &providers { + for model in &provider.models { + // A :thinking model without a patch must at least alias a real + // wire name (qianwen twins invert a base-model patch instead). + if model.name.ends_with(":thinking") { + assert!( + model.patch.is_some() || model.real_name.is_some(), + "{}:{} has neither patch nor real_name", + provider.provider, + model.name + ); + } + if model.model_type == "chat" { + let serialized = serde_yaml::to_value(model).unwrap(); + assert!( + serialized + .as_mapping() + .unwrap() + .keys() + .any(|key| !matches!(key.as_str(), Some("name" | "type"))), + "{}:{} is an all-default chat entry", + provider.provider, + model.name + ); + } + } + } + + for model in &embedded_provider(&providers, "claude").models { + if model.model_type == "chat" { + assert!( + model.require_max_tokens, + "claude:{} is missing require_max_tokens", + model.name + ); + } + } + } + + #[test] + fn embedded_catalog_roundtrip() { + let providers = embedded_catalog(); + let yaml = serde_yaml::to_string(&providers).unwrap(); + let reparsed: Vec = serde_yaml::from_str(&yaml).unwrap(); + assert_eq!(reparsed.len(), providers.len()); + for (reparsed, original) in reparsed.iter().zip(&providers) { + assert_eq!(reparsed.provider, original.provider); + assert_eq!(reparsed.models.len(), original.models.len()); + } + } + + fn provider_entry(provider: &str, model_names: &[&str]) -> ProviderModels { + ProviderModels { + provider: provider.to_string(), + oauth: None, + models: model_names + .iter() + .map(|name| ModelData::new(name)) + .collect(), + } + } + + #[test] + fn backfill_replaces_degraded_and_inserts_failed_providers() { + let mut build = CatalogBuild { + providers: vec![ + provider_entry("openai", &["gpt-fresh"]), + provider_entry("gemini", &["quirks-only"]), + ], + degraded: vec!["gemini".to_string()], + failed: vec!["claude".to_string()], + }; + let embedded = vec![ + provider_entry("openai", &["gpt-old-1", "gpt-old-2"]), + provider_entry("gemini", &["gem-1", "gem-2", "gem-3"]), + provider_entry("claude", &["claude-1"]), + ]; + + backfill_embedded_floor(&mut build, &embedded); + + let order: Vec<&str> = build + .providers + .iter() + .map(|provider| provider.provider.as_str()) + .collect(); + assert_eq!(order, ["openai", "gemini", "claude"]); + assert_eq!(find_provider(&build, "openai").models.len(), 1); + assert_eq!(find_provider(&build, "gemini").models.len(), 3); + assert_eq!(find_provider(&build, "claude").models.len(), 1); + assert_eq!( + find_provider(&build, "openai").models[0].name, + "gpt-fresh", + "providers with live API data must not be touched" + ); + } + + #[test] + fn backfill_keeps_built_entry_when_embedded_lacks_the_provider() { + let mut build = CatalogBuild { + providers: vec![provider_entry("gemini", &["quirks-only"])], + degraded: vec!["gemini".to_string()], + failed: vec![], + }; + + backfill_embedded_floor(&mut build, &[]); + + assert_eq!(find_provider(&build, "gemini").models.len(), 1); + } + + #[test] + fn backfill_without_degraded_or_failed_is_a_no_op() { + let mut build = CatalogBuild { + providers: vec![provider_entry("openai", &["gpt-fresh"])], + degraded: vec![], + failed: vec![], + }; + + backfill_embedded_floor(&mut build, &[provider_entry("openai", &["a", "b"])]); + + assert_eq!(find_provider(&build, "openai").models.len(), 1); + } + + #[test] + fn backfill_restores_embedded_floor_for_unresolved_providers() { + let embedded: Vec = serde_yaml::from_str(MODELS_YAML).unwrap(); + let mut build = build_catalog(&make_sources(Some(MODELSDEV_FIXTURE), None), &ALL_QUIRKS); + let unresolved: Vec = build + .degraded + .iter() + .chain(build.failed.iter()) + .cloned() + .collect(); + assert!(!unresolved.is_empty()); + + backfill_embedded_floor(&mut build, &embedded); + + for provider in unresolved { + let built = find_provider(&build, &provider); + let floor = embedded + .iter() + .find(|embedded| embedded.provider == provider) + .unwrap(); + assert!( + built.models.len() >= floor.models.len(), + "provider '{provider}' shrank below the embedded floor" + ); + } + } + + /// Guards against upstream id-shape drift by comparing live API model + /// names against the embedded models.yaml. Run manually: + /// `cargo test idshape_guard_live -- --ignored --nocapture` + #[tokio::test] + #[ignore] + async fn idshape_guard_live() { + let sources = fetch_sources().await; + let modelsdev: Value = serde_json::from_str( + sources + .modelsdev + .as_deref() + .expect("models.dev fetch failed"), + ) + .unwrap(); + let openrouter: Value = serde_json::from_str( + sources + .openrouter + .as_deref() + .expect("openrouter fetch failed"), + ) + .unwrap(); + let embedded: Vec = serde_yaml::from_str(MODELS_YAML).unwrap(); + + println!( + "{:<12} {:>7} {:>5} {:>5}", + "provider", "overlap", "old", "new" + ); + for source in &PROVIDER_SOURCES { + let new: Vec = if source.provider == "openrouter" { + openrouter_native_models(&openrouter) + .into_iter() + .map(|model| model.data.name) + .collect() + } else if let Some(id) = source.modelsdev { + modelsdev_provider_models(&modelsdev, id) + .into_iter() + .map(|model| model.data.name) + .collect() + } else { + continue; + }; + let old: Vec = embedded + .iter() + .find(|provider| provider.provider == source.provider) + .map(|provider| { + provider + .models + .iter() + .filter(|model| { + model.model_type == "chat" && !model.name.ends_with(":thinking") + }) + .map(|model| model.name.clone()) + .collect() + }) + .unwrap_or_default(); + println!( + "{:<12} {:>7.2} {:>5} {:>5}", + source.provider, + name_overlap(&old, &new), + old.len(), + new.len() + ); + } + } +} diff --git a/src/client/mod.rs b/src/client/mod.rs index c82c561..54cd832 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -1,4 +1,5 @@ mod access_token; +pub mod catalog; mod claude_oauth; mod common; mod gemini_oauth; diff --git a/src/client/model.rs b/src/client/model.rs index 0137be9..6d9408e 100644 --- a/src/client/model.rs +++ b/src/client/model.rs @@ -1,5 +1,7 @@ use super::{ - ApiPatch, MessageContentToolCalls, RequestPatch, list_all_models, list_client_names, + ApiPatch, MessageContentToolCalls, RequestPatch, + catalog::{ALL_QUIRKS, apply_rules, quirks_for}, + list_all_models, list_client_names, message::{Message, MessageContent, MessageContentPart}, }; @@ -63,12 +65,16 @@ impl Model { }; match model_name { Some(model_name) => { - if let Some(model) = models.iter().find(|v| v.id() == model_id) { - if model.model_type() == model_type { - return Ok((*model).clone()); - } else { - bail!("Model '{model_id}' is not a {model_type} model") - } + // Ids are not unique across types (e.g. a model that is both + // an embedder and a reranker), so match on id AND type. + if let Some(model) = models + .iter() + .find(|v| v.id() == model_id && v.model_type() == model_type) + { + return Ok((*model).clone()); + } + if models.iter().any(|v| v.id() == model_id) { + bail!("Model '{model_id}' is not a {model_type} model") } if list_client_names(config) .into_iter() @@ -77,6 +83,9 @@ impl Model { { let mut new_model = Self::new(client_name, model_name); new_model.data.model_type = model_type.to_string(); + if let Some(quirks) = quirks_for(&ALL_QUIRKS, client_name) { + apply_rules(quirks, &mut new_model.data); + } return Ok(new_model); } } @@ -132,6 +141,7 @@ impl Model { output_price, supports_vision, supports_function_calling, + reasoning_levels, .. } = &self.data; let max_input_tokens = stringify_option_value(max_input_tokens); @@ -145,6 +155,9 @@ impl Model { if *supports_function_calling { capabilities.push('⚒'); }; + if !reasoning_levels.is_empty() { + capabilities.push('🧠'); + }; let capabilities: String = capabilities .into_iter() .map(|v| format!("{v} ")) @@ -330,11 +343,11 @@ pub struct ModelData { #[serde(skip_serializing_if = "Option::is_none")] pub default_reasoning_effort: Option, #[serde(default, skip_serializing_if = "std::ops::Not::not")] - no_stream: bool, + pub(crate) no_stream: bool, #[serde(default, skip_serializing_if = "std::ops::Not::not")] - no_system_message: bool, + pub(crate) no_system_message: bool, #[serde(skip_serializing_if = "Option::is_none")] - system_prompt_prefix: Option, + pub(crate) system_prompt_prefix: Option, // embedding-only properties #[serde(skip_serializing_if = "Option::is_none")] @@ -358,7 +371,7 @@ impl ModelData { #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ProviderModels { pub provider: String, - #[serde(default)] + #[serde(default, skip_serializing_if = "Option::is_none")] pub oauth: Option, pub models: Vec, } @@ -419,3 +432,72 @@ where None => "-".to_string(), } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::client::ClientConfig; + + #[test] + fn created_from_name_inherits_family_rules() { + // The model registries are process-wide caches seeded by a ctor (see + // the request_context tests) that registers a "claude" client; the + // config below documents the shape a real lookup would use. + let claude: ClientConfig = serde_yaml::from_str( + "type: claude\nmodels:\n - name: test-claude-embedder\n type: embedding\n", + ) + .unwrap(); + let config = AppConfig { + clients: vec![claude], + ..AppConfig::default() + }; + let model = Model::retrieve_model( + &config, + "claude:claude-definitely-not-a-real-model", + ModelType::Chat, + ) + .unwrap(); + assert_eq!(model.name(), "claude-definitely-not-a-real-model"); + assert_eq!(model.model_type(), ModelType::Chat); + assert!(model.data.require_max_tokens); + } + + #[test] + fn duplicate_id_across_types_resolves_by_requested_type() { + // Mirrors jina:jina-colbert-v2, which is both an embedder and a + // reranker under the same id. + let claude: ClientConfig = serde_yaml::from_str( + "type: claude\nmodels:\n - name: test-dual-model\n type: embedding\n - name: test-dual-model\n type: reranker\n", + ) + .unwrap(); + let config = AppConfig { + clients: vec![claude], + ..AppConfig::default() + }; + + let embedder = + Model::retrieve_model(&config, "claude:test-dual-model", ModelType::Embedding).unwrap(); + assert_eq!(embedder.model_type(), ModelType::Embedding); + + let reranker = + Model::retrieve_model(&config, "claude:test-dual-model", ModelType::Reranker).unwrap(); + assert_eq!(reranker.model_type(), ModelType::Reranker); + + // An id that exists only under other types still teaches instead of + // silently creating a chat model from the name. + let err = Model::retrieve_model(&config, "claude:test-dual-model", ModelType::Chat) + .unwrap_err() + .to_string(); + assert!(err.contains("is not a chat model"), "got: {err}"); + } + + #[test] + fn description_shows_brain_glyph() { + let mut model = Model::new("claude", "some-model"); + model.data.reasoning_levels = vec!["low".to_string(), "high".to_string()]; + assert!(model.description().contains('🧠')); + + model.data.reasoning_levels.clear(); + assert!(!model.description().contains('🧠')); + } +} diff --git a/src/client/testdata/modelsdev_fixture.json b/src/client/testdata/modelsdev_fixture.json new file mode 100644 index 0000000..d91242a --- /dev/null +++ b/src/client/testdata/modelsdev_fixture.json @@ -0,0 +1,457 @@ +{ + "openai": { + "id": "openai", + "env": [ + "OPENAI_API_KEY" + ], + "npm": "@ai-sdk/openai", + "name": "OpenAI", + "doc": "https://platform.openai.com/docs/models", + "models": { + "gpt-5.6": { + "id": "gpt-5.6", + "name": "GPT-5.6", + "description": "Frontier GPT-5.6 model for complex professional work, coding, and agentic workflows", + "family": "gpt-sol", + "attachment": true, + "reasoning": true, + "reasoning_options": [ + { + "type": "effort", + "values": [ + "none", + "low", + "medium", + "high", + "xhigh", + "max" + ] + } + ], + "tool_call": true, + "structured_output": true, + "temperature": false, + "knowledge": "2026-02-16", + "release_date": "2026-07-09", + "last_updated": "2026-07-09", + "modalities": { + "input": [ + "text", + "image", + "pdf" + ], + "output": [ + "text" + ] + }, + "open_weights": false, + "limit": { + "context": 1050000, + "input": 922000, + "output": 128000 + }, + "experimental": { + "modes": { + "fast": { + "cost": { + "input": 8, + "output": 40, + "cache_read": 0.8, + "cache_write": 10 + }, + "provider": { + "body": { + "service_tier": "priority" + } + } + }, + "pro": { + "provider": { + "body": { + "reasoning": { + "mode": "pro" + } + } + } + } + } + }, + "cost": { + "input": 4, + "output": 20, + "cache_read": 0.4, + "cache_write": 5, + "tiers": [ + { + "input": 8, + "output": 30, + "cache_read": 0.8, + "cache_write": 10, + "tier": { + "type": "context", + "size": 272000 + } + } + ], + "context_over_200k": { + "input": 8, + "output": 30, + "cache_read": 0.8, + "cache_write": 10 + } + } + }, + "gpt-4.1": { + "id": "gpt-4.1", + "name": "GPT-4.1", + "description": "Long-lived GPT workhorse for coding, instruction following, and production apps", + "family": "gpt", + "attachment": true, + "reasoning": false, + "tool_call": true, + "structured_output": true, + "temperature": true, + "knowledge": "2024-04", + "release_date": "2025-04-14", + "last_updated": "2025-04-14", + "modalities": { + "input": [ + "text", + "image", + "pdf" + ], + "output": [ + "text" + ] + }, + "open_weights": false, + "limit": { + "context": 1047576, + "output": 32768 + }, + "cost": { + "input": 2, + "output": 8, + "cache_read": 0.5 + } + }, + "gpt-4o": { + "id": "gpt-4o", + "name": "GPT-4o", + "description": "Omni-era GPT for multimodal chat, practical coding, and general assistants", + "family": "gpt", + "attachment": true, + "reasoning": false, + "tool_call": true, + "structured_output": true, + "temperature": true, + "knowledge": "2023-09", + "release_date": "2024-05-13", + "last_updated": "2024-08-06", + "modalities": { + "input": [ + "text", + "image", + "pdf" + ], + "output": [ + "text" + ] + }, + "open_weights": false, + "limit": { + "context": 128000, + "output": 16384 + }, + "cost": { + "input": 2.5, + "output": 10, + "cache_read": 1.25 + } + } + } + }, + "anthropic": { + "id": "anthropic", + "env": [ + "ANTHROPIC_API_KEY" + ], + "npm": "@ai-sdk/anthropic", + "name": "Anthropic", + "doc": "https://docs.anthropic.com/en/docs/about-claude/models", + "models": { + "claude-sonnet-4-6": { + "id": "claude-sonnet-4-6", + "name": "Claude Sonnet 4.6", + "description": "Claude workhorse for coding agents, careful analysis, and production cost control", + "family": "claude-sonnet", + "attachment": true, + "reasoning": true, + "reasoning_options": [ + { + "type": "effort", + "values": [ + "low", + "medium", + "high", + "max" + ] + }, + { + "type": "budget_tokens", + "min": 1024 + } + ], + "tool_call": true, + "structured_output": true, + "temperature": true, + "knowledge": "2025-08-31", + "release_date": "2026-02-17", + "last_updated": "2026-03-13", + "modalities": { + "input": [ + "text", + "image", + "pdf" + ], + "output": [ + "text" + ] + }, + "open_weights": false, + "limit": { + "context": 1000000, + "output": 128000 + }, + "cost": { + "input": 3, + "output": 15, + "cache_read": 0.3, + "cache_write": 3.75 + } + }, + "claude-opus-4-6": { + "id": "claude-opus-4-6", + "name": "Claude Opus 4.6", + "description": "High-end Claude for difficult coding, planning, and slower expert reasoning", + "family": "claude-opus", + "attachment": true, + "reasoning": true, + "reasoning_options": [ + { + "type": "effort", + "values": [ + "low", + "medium", + "high", + "max" + ] + }, + { + "type": "budget_tokens", + "min": 1024 + } + ], + "tool_call": true, + "structured_output": true, + "temperature": true, + "knowledge": "2025-05-31", + "release_date": "2026-02-04", + "last_updated": "2026-03-13", + "modalities": { + "input": [ + "text", + "image", + "pdf" + ], + "output": [ + "text" + ] + }, + "open_weights": false, + "limit": { + "context": 1000000, + "output": 128000 + }, + "cost": { + "input": 5, + "output": 25, + "cache_read": 0.5, + "cache_write": 6.25 + } + } + } + }, + "xai": { + "id": "xai", + "env": [ + "XAI_API_KEY" + ], + "npm": "@ai-sdk/xai", + "name": "xAI", + "doc": "https://docs.x.ai/docs/models", + "models": { + "grok-4.6": { + "id": "grok-4.6", + "name": "Grok 4.6", + "description": "xAI's frontier model for long-running agents, coding, knowledge work, and visual projects", + "family": "grok", + "attachment": true, + "reasoning": true, + "reasoning_options": [ + { + "type": "effort", + "values": [ + "low", + "medium", + "high", + "xhigh" + ] + } + ], + "tool_call": true, + "structured_output": true, + "temperature": true, + "knowledge": "2026-02-01", + "release_date": "2026-08-12", + "last_updated": "2026-08-12", + "modalities": { + "input": [ + "text", + "image", + "pdf" + ], + "output": [ + "text" + ] + }, + "open_weights": false, + "limit": { + "context": 500000, + "output": 500000 + }, + "cost": { + "input": 2, + "output": 6, + "cache_read": 0.5, + "tiers": [ + { + "input": 4, + "output": 12, + "cache_read": 1, + "tier": { + "type": "context", + "size": 200000 + } + } + ], + "context_over_200k": { + "input": 4, + "output": 12, + "cache_read": 1 + } + } + }, + "grok-4.5": { + "id": "grok-4.5", + "name": "Grok 4.5", + "description": "xAI's Grok model for chat, coding, agentic tools, and lower hallucination risk", + "family": "grok", + "attachment": true, + "reasoning": true, + "reasoning_options": [ + { + "type": "effort", + "values": [ + "low", + "medium", + "high" + ] + } + ], + "tool_call": true, + "structured_output": true, + "temperature": true, + "release_date": "2026-07-08", + "last_updated": "2026-07-08", + "modalities": { + "input": [ + "text", + "image", + "pdf" + ], + "output": [ + "text" + ] + }, + "open_weights": false, + "limit": { + "context": 500000, + "output": 500000 + }, + "cost": { + "input": 2, + "output": 6, + "cache_read": 0.3, + "tiers": [ + { + "input": 4, + "output": 12, + "cache_read": 0.6, + "tier": { + "type": "context", + "size": 200000 + } + } + ], + "context_over_200k": { + "input": 4, + "output": 12, + "cache_read": 0.6 + } + } + } + } + }, + "alibaba": { + "id": "alibaba", + "env": [ + "DASHSCOPE_API_KEY" + ], + "npm": "@ai-sdk/openai-compatible", + "name": "Alibaba", + "doc": "https://www.alibabacloud.com/help/en/model-studio/models", + "models": { + "qwen-max": { + "id": "qwen-max", + "name": "Qwen Max", + "description": "Flagship Qwen model for complex reasoning, coding, and agentic workflows", + "family": "qwen", + "attachment": false, + "reasoning": false, + "tool_call": true, + "temperature": true, + "knowledge": "2024-04", + "release_date": "2024-04-03", + "last_updated": "2025-01-25", + "modalities": { + "input": [ + "text" + ], + "output": [ + "text" + ] + }, + "open_weights": false, + "limit": { + "context": 32768, + "output": 8192 + }, + "cost": { + "input": 1.6, + "output": 6.4 + } + } + } + } +} diff --git a/src/client/testdata/openrouter_fixture.json b/src/client/testdata/openrouter_fixture.json new file mode 100644 index 0000000..956cbdd --- /dev/null +++ b/src/client/testdata/openrouter_fixture.json @@ -0,0 +1,538 @@ +{ + "data": [ + { + "id": "x-ai/grok-4.6", + "canonical_slug": "x-ai/grok-4.6-20260810", + "hugging_face_id": null, + "name": "SpaceXAI: Grok 4.6", + "created": 1786548957, + "description": "Grok 4.6 is SpaceXAI's smartest model with frontier performance on coding, knowledge work, and STEM.", + "context_length": 500000, + "architecture": { + "modality": "text+image+file->text", + "input_modalities": [ + "text", + "image", + "file" + ], + "output_modalities": [ + "text" + ], + "tokenizer": "Grok", + "instruct_type": null + }, + "pricing": { + "prompt": "0.000002", + "completion": "0.000006", + "web_search": "0.005", + "input_cache_read": "0.0000005", + "overrides": [ + { + "min_prompt_tokens": 200000, + "prompt": "0.000004", + "completion": "0.000012", + "input_cache_read": "0.000001" + } + ] + }, + "top_provider": { + "context_length": 500000, + "max_completion_tokens": 450000, + "is_moderated": false + }, + "per_request_limits": null, + "supported_parameters": [ + "include_reasoning", + "logprobs", + "max_tokens", + "reasoning", + "reasoning_effort", + "response_format", + "seed", + "stop", + "structured_outputs", + "temperature", + "tool_choice", + "tools", + "top_k", + "top_logprobs", + "top_p" + ], + "default_parameters": {}, + "supported_voices": null, + "knowledge_cutoff": null, + "expiration_date": null, + "links": { + "details": "/api/v1/models/x-ai/grok-4.6-20260810/endpoints" + }, + "reasoning": { + "mandatory": true, + "default_enabled": true, + "supported_efforts": [ + "xhigh", + "high", + "medium", + "low" + ], + "default_effort": "high" + } + }, + { + "id": "qwen/qwen3.8-max", + "canonical_slug": "qwen/qwen3.8-max-20260803", + "hugging_face_id": null, + "name": "Qwen: Qwen3.8 Max", + "created": 1785731612, + "description": "Qwen3.8 Max is the flagship model in Alibaba's Qwen3.8 series, the general-availability successor to the Qwen3.8 Max Preview. It is a multimodal reasoning model intended for complex reasoning, visual understanding,...", + "context_length": 1000000, + "architecture": { + "modality": "text+image+video->text", + "input_modalities": [ + "text", + "image", + "video" + ], + "output_modalities": [ + "text" + ], + "tokenizer": "Qwen", + "instruct_type": null + }, + "pricing": { + "prompt": "0.000002", + "completion": "0.000006", + "input_cache_read": "0.00000025", + "input_cache_write": "0.0000025" + }, + "top_provider": { + "context_length": 1000000, + "max_completion_tokens": 131072, + "is_moderated": false + }, + "per_request_limits": null, + "supported_parameters": [ + "frequency_penalty", + "include_reasoning", + "logprobs", + "max_tokens", + "presence_penalty", + "reasoning", + "reasoning_effort", + "response_format", + "seed", + "stop", + "structured_outputs", + "temperature", + "tool_choice", + "tools", + "top_k", + "top_logprobs", + "top_p" + ], + "default_parameters": {}, + "supported_voices": null, + "knowledge_cutoff": null, + "expiration_date": null, + "links": { + "details": "/api/v1/models/qwen/qwen3.8-max-20260803/endpoints" + }, + "reasoning": { + "mandatory": true, + "default_enabled": true, + "supported_efforts": [ + "xhigh", + "high", + "medium", + "low", + "minimal" + ], + "default_effort": "xhigh" + } + }, + { + "id": "x-ai/grok-4.5", + "canonical_slug": "x-ai/grok-4.5-20260708", + "hugging_face_id": null, + "name": "SpaceXAI: Grok 4.5", + "created": 1783523154, + "description": "Grok 4.5 is a model from SpaceXAI with frontier performance on coding, knowledge work, and STEM.", + "context_length": 500000, + "architecture": { + "modality": "text+image+file->text", + "input_modalities": [ + "text", + "image", + "file" + ], + "output_modalities": [ + "text" + ], + "tokenizer": "Grok", + "instruct_type": null + }, + "pricing": { + "prompt": "0.000002", + "completion": "0.000006", + "web_search": "0.005", + "input_cache_read": "0.0000003", + "overrides": [ + { + "min_prompt_tokens": 200000, + "prompt": "0.000004", + "completion": "0.000012", + "input_cache_read": "0.0000006" + } + ] + }, + "top_provider": { + "context_length": 500000, + "max_completion_tokens": 450000, + "is_moderated": false + }, + "per_request_limits": null, + "supported_parameters": [ + "include_reasoning", + "logprobs", + "max_tokens", + "reasoning", + "reasoning_effort", + "response_format", + "seed", + "structured_outputs", + "temperature", + "tool_choice", + "tools", + "top_logprobs", + "top_p" + ], + "default_parameters": {}, + "supported_voices": null, + "knowledge_cutoff": null, + "expiration_date": null, + "links": { + "details": "/api/v1/models/x-ai/grok-4.5-20260708/endpoints" + }, + "reasoning": { + "mandatory": true, + "default_enabled": true, + "supported_efforts": [ + "high", + "medium", + "low" + ], + "default_effort": "high" + } + }, + { + "id": "anthropic/claude-sonnet-4.6", + "canonical_slug": "anthropic/claude-4.6-sonnet-20260217", + "hugging_face_id": "", + "name": "Anthropic: Claude Sonnet 4.6", + "created": 1771342990, + "description": "Sonnet 4.6 is Anthropic's most capable Sonnet-class model yet, with frontier performance across coding, agents, and professional work. It excels at iterative development, complex codebase navigation, end-to-end project management with...", + "context_length": 1000000, + "architecture": { + "modality": "text+image+file->text", + "input_modalities": [ + "text", + "image", + "file" + ], + "output_modalities": [ + "text" + ], + "tokenizer": "Claude", + "instruct_type": null + }, + "pricing": { + "prompt": "0.000003", + "completion": "0.000015", + "web_search": "0.01", + "input_cache_read": "0.0000003", + "input_cache_write": "0.00000375", + "input_cache_write_1h": "0.000006" + }, + "top_provider": { + "context_length": 1000000, + "max_completion_tokens": 128000, + "is_moderated": true + }, + "per_request_limits": null, + "supported_parameters": [ + "include_reasoning", + "max_completion_tokens", + "max_tokens", + "reasoning", + "reasoning_effort", + "response_format", + "stop", + "structured_outputs", + "temperature", + "tool_choice", + "tools", + "top_k", + "top_p", + "verbosity" + ], + "default_parameters": {}, + "supported_voices": null, + "knowledge_cutoff": null, + "expiration_date": null, + "links": { + "details": "/api/v1/models/anthropic/claude-4.6-sonnet-20260217/endpoints" + }, + "reasoning": { + "mandatory": false, + "supported_efforts": [ + "max", + "high", + "medium", + "low" + ], + "default_effort": "medium" + } + }, + { + "id": "openrouter/free", + "canonical_slug": "openrouter/free", + "hugging_face_id": "", + "name": "Free Models Router", + "created": 1769917427, + "description": "The simplest way to get free inference. openrouter/free is a router that selects free models at random from the models available on OpenRouter. The router smartly filters for models that...", + "context_length": 200000, + "architecture": { + "modality": "text+image->text", + "input_modalities": [ + "text", + "image" + ], + "output_modalities": [ + "text" + ], + "tokenizer": "Router", + "instruct_type": null + }, + "pricing": { + "prompt": "0", + "completion": "0" + }, + "top_provider": { + "context_length": null, + "max_completion_tokens": null, + "is_moderated": false + }, + "per_request_limits": null, + "supported_parameters": [ + "frequency_penalty", + "include_reasoning", + "logprobs", + "max_completion_tokens", + "max_tokens", + "min_p", + "presence_penalty", + "reasoning", + "reasoning_effort", + "repetition_penalty", + "response_format", + "seed", + "stop", + "structured_outputs", + "temperature", + "tool_choice", + "tools", + "top_k", + "top_logprobs", + "top_p" + ], + "default_parameters": { + "temperature": null, + "top_p": null, + "frequency_penalty": null + }, + "supported_voices": null, + "knowledge_cutoff": null, + "expiration_date": null, + "links": { + "details": "/api/v1/models/openrouter/free/endpoints" + } + }, + { + "id": "openai/gpt-4.1", + "canonical_slug": "openai/gpt-4.1-2025-04-14", + "hugging_face_id": "", + "name": "OpenAI: GPT-4.1", + "created": 1744651385, + "description": "GPT-4.1 is a flagship large language model optimized for advanced instruction following, real-world software engineering, and long-context reasoning. It supports a 1 million token context window and outperforms GPT-4o and...", + "context_length": 1047576, + "architecture": { + "modality": "text+image+file->text", + "input_modalities": [ + "image", + "text", + "file" + ], + "output_modalities": [ + "text" + ], + "tokenizer": "GPT", + "instruct_type": null + }, + "pricing": { + "prompt": "0.000002", + "completion": "0.000008", + "web_search": "0.01", + "input_cache_read": "0.0000005" + }, + "top_provider": { + "context_length": 1047576, + "max_completion_tokens": 32768, + "is_moderated": true + }, + "per_request_limits": null, + "supported_parameters": [ + "max_completion_tokens", + "max_tokens", + "response_format", + "seed", + "structured_outputs", + "temperature", + "tool_choice", + "tools", + "top_p" + ], + "default_parameters": {}, + "supported_voices": null, + "knowledge_cutoff": "2024-06-30", + "expiration_date": null, + "links": { + "details": "/api/v1/models/openai/gpt-4.1-2025-04-14/endpoints" + } + }, + { + "id": "openai/gpt-4o", + "canonical_slug": "openai/gpt-4o", + "hugging_face_id": null, + "name": "OpenAI: GPT-4o", + "created": 1715558400, + "description": "GPT-4o (\"o\" for \"omni\") is OpenAI's latest AI model, supporting both text and image inputs with text outputs. It maintains the intelligence level of [GPT-4 Turbo](/models/openai/gpt-4-turbo) while being twice as...", + "context_length": 128000, + "architecture": { + "modality": "text+image+file->text", + "input_modalities": [ + "text", + "image", + "file" + ], + "output_modalities": [ + "text" + ], + "tokenizer": "GPT", + "instruct_type": null + }, + "pricing": { + "prompt": "0.0000025", + "completion": "0.00001", + "input_cache_read": "0.00000125" + }, + "top_provider": { + "context_length": 128000, + "max_completion_tokens": 16384, + "is_moderated": true + }, + "per_request_limits": null, + "supported_parameters": [ + "frequency_penalty", + "logit_bias", + "logprobs", + "max_completion_tokens", + "max_tokens", + "prediction", + "presence_penalty", + "response_format", + "seed", + "stop", + "structured_outputs", + "temperature", + "tool_choice", + "tools", + "top_logprobs", + "top_p", + "web_search_options" + ], + "default_parameters": {}, + "supported_voices": null, + "knowledge_cutoff": "2023-10-31", + "expiration_date": null, + "links": { + "details": "/api/v1/models/openai/gpt-4o/endpoints" + } + }, + { + "id": "openrouter/auto", + "canonical_slug": "openrouter/auto", + "hugging_face_id": null, + "name": "Auto Router", + "created": 1699401600, + "description": "The Auto Router automatically selects the best model for your prompt, powered by the wisdom of the market. It routes you based on what the OpenRouter community collectively spends on...", + "context_length": 2000000, + "architecture": { + "modality": "text+image+file+audio+video->text+image", + "input_modalities": [ + "text", + "image", + "audio", + "file", + "video" + ], + "output_modalities": [ + "text", + "image" + ], + "tokenizer": "Router", + "instruct_type": null + }, + "pricing": { + "prompt": "-1", + "completion": "-1" + }, + "top_provider": { + "context_length": null, + "max_completion_tokens": null, + "is_moderated": false + }, + "per_request_limits": null, + "supported_parameters": [ + "frequency_penalty", + "include_reasoning", + "logit_bias", + "logprobs", + "max_tokens", + "min_p", + "prediction", + "presence_penalty", + "reasoning", + "reasoning_effort", + "repetition_penalty", + "response_format", + "seed", + "stop", + "structured_outputs", + "temperature", + "tool_choice", + "tools", + "top_a", + "top_k", + "top_logprobs", + "top_p", + "web_search_options" + ], + "default_parameters": {}, + "supported_voices": null, + "knowledge_cutoff": null, + "expiration_date": null, + "links": { + "details": "/api/v1/models/openrouter/auto/endpoints" + } + } + ] +} diff --git a/src/config/app_config.rs b/src/config/app_config.rs index 6235c1d..6bf1576 100644 --- a/src/config/app_config.rs +++ b/src/config/app_config.rs @@ -102,6 +102,8 @@ pub struct AppConfig { pub no_workspace_mcp: bool, pub no_workspace_macros: bool, pub sync_models_url: Option, + pub sync_models_auto: bool, + pub sync_models_ttl_hours: u64, pub clients: Vec, } @@ -188,6 +190,8 @@ impl Default for AppConfig { no_workspace_mcp: false, no_workspace_macros: false, sync_models_url: None, + sync_models_auto: true, + sync_models_ttl_hours: 24, clients: vec![], } @@ -276,6 +280,8 @@ impl AppConfig { no_workspace_mcp: false, no_workspace_macros: false, sync_models_url: config.sync_models_url, + sync_models_auto: config.sync_models_auto, + sync_models_ttl_hours: config.sync_models_ttl_hours, clients: config.clients, }; @@ -388,10 +394,8 @@ impl AppConfig { .ok_or_else(|| anyhow!("Editor not found. Please add the `editor` configuration or set the $EDITOR or $VISUAL environment variable.")) } - pub fn sync_models_url(&self) -> String { - self.sync_models_url - .clone() - .unwrap_or_else(|| super::SYNC_MODELS_URL.into()) + pub fn sync_models_url(&self) -> Option { + self.sync_models_url.clone() } pub fn light_theme(&self) -> bool { @@ -636,7 +640,10 @@ impl AppConfig { if self.highlight && self.theme.is_none() { if let Some(v) = super::read_env_value::(&get_env_name("theme")) { self.theme = v; - } else if *IS_STDOUT_TERMINAL { + } else if !cfg!(test) && *IS_STDOUT_TERMINAL { + // Never query the terminal from test builds: the test harness + // shares the process TTY, so parallel raw-mode color queries + // garble the runner's output and stall on stolen replies. if let Ok(color_scheme) = color_scheme(QueryOptions::default()) { let theme = match color_scheme { ColorScheme::Dark => "dark", @@ -665,6 +672,13 @@ impl AppConfig { if let Some(v) = super::read_env_value::(&get_env_name("sync_models_url")) { self.sync_models_url = v; } + if let Some(Some(v)) = super::read_env_bool(&get_env_name("sync_models_auto")) { + self.sync_models_auto = v; + } + if let Some(Some(v)) = super::read_env_value::(&get_env_name("sync_models_ttl_hours")) + { + self.sync_models_ttl_hours = v; + } } } @@ -951,10 +965,70 @@ mod tests { } #[test] - fn sync_models_url_has_default() { + fn sync_models_url_defaults_to_none() { let app = AppConfig::default(); - let url = app.sync_models_url(); - assert!(!url.is_empty()); + assert!(app.sync_models_url().is_none()); + } + + #[test] + fn sync_models_auto_and_ttl_have_defaults() { + let app = AppConfig::default(); + assert!(app.sync_models_auto); + assert_eq!(app.sync_models_ttl_hours, 24); + } + + #[test] + #[serial_test::serial] + fn load_envs_overrides_sync_models_auto() { + let env_name = get_env_name("sync_models_auto"); + let prev = env::var_os(&env_name); + + let mut app = AppConfig::default(); + + unsafe { env::set_var(&env_name, "false") }; + app.load_envs(); + assert!(!app.sync_models_auto); + + unsafe { env::set_var(&env_name, "true") }; + app.load_envs(); + assert!(app.sync_models_auto); + + unsafe { env::remove_var(&env_name) }; + app.sync_models_auto = false; + app.load_envs(); + assert!(!app.sync_models_auto); + + unsafe { + match prev { + Some(v) => env::set_var(&env_name, v), + None => env::remove_var(&env_name), + } + } + } + + #[test] + #[serial_test::serial] + fn load_envs_overrides_sync_models_ttl_hours() { + let env_name = get_env_name("sync_models_ttl_hours"); + let prev = env::var_os(&env_name); + + let mut app = AppConfig::default(); + + unsafe { env::set_var(&env_name, "6") }; + app.load_envs(); + assert_eq!(app.sync_models_ttl_hours, 6); + + unsafe { env::remove_var(&env_name) }; + app.sync_models_ttl_hours = 48; + app.load_envs(); + assert_eq!(app.sync_models_ttl_hours, 48); + + unsafe { + match prev { + Some(v) => env::set_var(&env_name, v), + None => env::remove_var(&env_name), + } + } } #[test] diff --git a/src/config/mod.rs b/src/config/mod.rs index 0649765..36d16ae 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -69,8 +69,9 @@ pub use self::tool_scope::{ }; pub use self::update::run_self_update; use crate::client::{ - self, ClientConfig, MessageContentToolCalls, Model, ModelType, OPENAI_COMPATIBLE_PROVIDERS, - ProviderModels, create_client_config, list_client_types, oauth, set_client_models_config, + self, ClientConfig, MODELS_YAML, MessageContentToolCalls, Model, ModelType, + OPENAI_COMPATIBLE_PROVIDERS, ProviderModels, catalog, create_client_config, list_client_types, + oauth, set_client_models_config, }; use crate::function::{FunctionDeclaration, Functions}; use crate::rag::Rag; @@ -93,12 +94,13 @@ use serde_json::json; use std::collections::{HashMap, HashSet}; use std::sync::LazyLock; use std::{ - env, + env, fs, fs::{File, create_dir_all, read_dir, read_to_string}, io::Write, path::{Path, PathBuf}, process, sync::{Arc, OnceLock}, + time::SystemTime, }; pub const TEMP_ROLE_NAME: &str = "temp"; @@ -187,9 +189,6 @@ const GITIGNORE_FILE_NAME: &str = ".gitignore"; const CLIENTS_FIELD: &str = "clients"; -const SYNC_MODELS_URL: &str = - "https://raw.githubusercontent.com/Dark-Alex-17/coyote/refs/heads/main/models.yaml"; - const SUMMARIZATION_PROMPT: &str = "Summarize the discussion briefly in 200 words or less to use as a prompt for future context."; const SUMMARY_CONTEXT_PROMPT: &str = "This is a summary of the chat history as a recap: "; @@ -287,6 +286,8 @@ pub struct Config { pub user_agent: Option, pub save_shell_history: bool, pub sync_models_url: Option, + pub sync_models_auto: bool, + pub sync_models_ttl_hours: u64, pub clients: Vec, } @@ -370,6 +371,8 @@ impl Default for Config { user_agent: None, save_shell_history: true, sync_models_url: None, + sync_models_auto: true, + sync_models_ttl_hours: 24, clients: vec![], } @@ -513,26 +516,163 @@ pub fn list_sessions() -> Vec { list_file_names(default_sessions_dir(), ".yaml") } -pub async fn sync_models(url: &str, abort_signal: AbortSignal) -> Result<()> { - let content = abortable_run_with_spinner(fetch(url), "Fetching models.yaml", abort_signal) - .await - .with_context(|| format!("Failed to fetch '{url}'"))?; - println!("✓ Fetched '{url}'"); - let list = serde_yaml::from_str::>(&content) - .with_context(|| "Failed to parse models.yaml")?; +/// Refreshes the models override. With a URL, mirrors a full models.yaml from +/// it; without one, rebuilds the catalog from the live models.dev + OpenRouter +/// APIs merged with the embedded quirks. +pub async fn sync_models(url: Option<&str>, abort_signal: AbortSignal) -> Result<()> { + let list = match url { + Some(url) => { + let content = + abortable_run_with_spinner(fetch(url), "Fetching models.yaml", abort_signal) + .await + .with_context(|| format!("Failed to fetch '{url}'"))?; + println!("✓ Fetched '{url}'"); + parse_mirrored_models(&content)? + } + None => { + let sources = abortable_run_with_spinner( + async { Ok(catalog::fetch_sources().await) }, + "Fetching model data", + abort_signal, + ) + .await?; + let (list, warnings) = build_refreshed_catalog(&sources)?; + for warning in &warnings { + println!("{} {warning}", warning_text("WARNING:")); + } + list + } + }; + let model_override_path = write_models_override(list)?; + println!("✓ Updated '{}'", model_override_path.display()); + Ok(()) +} + +pub async fn sync_models_quiet(url: Option<&str>) -> Result<()> { + let list = match url { + Some(url) => { + let content = fetch(url) + .await + .with_context(|| format!("Failed to fetch '{url}'"))?; + parse_mirrored_models(&content)? + } + None => { + let sources = catalog::fetch_sources().await; + let (list, warnings) = build_refreshed_catalog(&sources)?; + for warning in warnings { + debug!("{warning}"); + } + list + } + }; + write_models_override(list)?; + Ok(()) +} + +fn parse_mirrored_models(content: &str) -> Result> { + serde_yaml::from_str::>(content) + .with_context(|| "Failed to parse models.yaml") +} + +fn build_refreshed_catalog( + sources: &catalog::FetchedSources, +) -> Result<(Vec, Vec)> { + if sources.modelsdev.is_none() && sources.openrouter.is_none() { + bail!("Failed to fetch model data from both models.dev and OpenRouter"); + } + let mut warnings = Vec::new(); + if sources.modelsdev.is_none() { + warnings.push("Failed to fetch models.dev; continuing with OpenRouter data only".into()); + } + if sources.openrouter.is_none() { + warnings.push("Failed to fetch OpenRouter; continuing with models.dev data only".into()); + } + + let mut build = catalog::build_catalog(sources, &catalog::ALL_QUIRKS); + if !build.degraded.is_empty() { + warnings.push(format!( + "No live API data for: {}; keeping their embedded models", + build.degraded.join(", ") + )); + } + if !build.failed.is_empty() { + warnings.push(format!( + "No models resolved for: {}; keeping their embedded models", + build.failed.join(", ") + )); + } + + let embedded = serde_yaml::from_str::>(MODELS_YAML) + .with_context(|| "Failed to parse the embedded models.yaml")?; + catalog::backfill_embedded_floor(&mut build, &embedded); + + if build.providers.is_empty() { + bail!("Model sync produced no providers"); + } + + Ok((build.providers, warnings)) +} + +fn write_models_override(list: Vec) -> Result { let models_override = ModelsOverride { version: env!("CARGO_PKG_VERSION").to_string(), list, }; - let models_override_data = - serde_yaml::to_string(&models_override).with_context(|| "Failed to serde {}")?; + let models_override_data = serde_yaml::to_string(&models_override) + .with_context(|| "Failed to serialize the models override")?; let model_override_path = paths::models_override_file(); ensure_parent_exists(&model_override_path)?; - std::fs::write(&model_override_path, models_override_data) - .with_context(|| format!("Failed to write to '{}'", model_override_path.display()))?; - println!("✓ Updated '{}'", model_override_path.display()); - Ok(()) + // Write through a sibling temp file and rename it over the target so an + // interrupted write can never leave a truncated override behind. The temp + // name embeds the pid so concurrent coyote processes (auto-refresh racing + // a manual --sync-models) never interleave writes into the same file. + let mut tmp_name = model_override_path.as_os_str().to_os_string(); + tmp_name.push(format!(".{}.tmp", process::id())); + let tmp_path = PathBuf::from(tmp_name); + fs::write(&tmp_path, models_override_data) + .with_context(|| format!("Failed to write to '{}'", tmp_path.display()))?; + if let Err(error) = fs::rename(&tmp_path, &model_override_path) { + let _ = fs::remove_file(&tmp_path); + return Err(error) + .with_context(|| format!("Failed to write to '{}'", model_override_path.display())); + } + Ok(model_override_path) +} + +fn models_override_is_stale(loadable: bool, mtime: Option, ttl_hours: u64) -> bool { + if !loadable { + return true; + } + let Some(mtime) = mtime else { + return true; + }; + match SystemTime::now().duration_since(mtime) { + Ok(age) => age.as_secs() > ttl_hours.saturating_mul(3600), + Err(_) => false, + } +} + +pub fn maybe_spawn_models_refresh(app: &AppConfig) { + if !app.sync_models_auto || app.dry_run { + return; + } + let ttl_hours = app.sync_models_ttl_hours; + let url = app.sync_models_url.clone(); + tokio::spawn(async move { + // The loadable probe deserializes the whole override catalog; keep it + // off the startup path. + let loadable = paths::local_models_override().is_ok(); + let mtime = fs::metadata(paths::models_override_file()) + .and_then(|metadata| metadata.modified()) + .ok(); + if !models_override_is_stale(loadable, mtime, ttl_hours) { + return; + } + if let Err(err) = sync_models_quiet(url.as_deref()).await { + debug!("Background models refresh failed: {err}"); + } + }); } impl Config { @@ -890,13 +1030,13 @@ fn render_config_template_from( fn write_config_file(config_path: &Path, config_data: &str) -> Result<()> { ensure_parent_exists(config_path)?; - std::fs::write(config_path, config_data) + fs::write(config_path, config_data) .with_context(|| format!("Failed to write to '{}'", config_path.display()))?; #[cfg(unix)] { use std::os::unix::prelude::PermissionsExt; - let perms = std::fs::Permissions::from_mode(0o600); - std::fs::set_permissions(config_path, perms)?; + let perms = fs::Permissions::from_mode(0o600); + fs::set_permissions(config_path, perms)?; } println!("✓ Saved the config file to '{}'.\n", config_path.display()); @@ -1381,4 +1521,102 @@ clients: "placeholder should be preserved as a literal string in sandbox mode" ); } + + #[test] + fn unloadable_override_is_stale() { + assert!(models_override_is_stale(false, Some(SystemTime::now()), 24)); + assert!(models_override_is_stale(false, None, 24)); + } + + #[test] + fn unreadable_mtime_is_stale() { + assert!(models_override_is_stale(true, None, 24)); + } + + #[test] + fn fresh_loadable_override_is_not_stale() { + assert!(!models_override_is_stale(true, Some(SystemTime::now()), 24)); + } + + #[test] + fn ttl_boundary_controls_staleness() { + let ttl_hours = 24; + let ttl = std::time::Duration::from_secs(ttl_hours * 3600); + let margin = std::time::Duration::from_secs(300); + let just_fresh = SystemTime::now() - (ttl - margin); + let just_stale = SystemTime::now() - (ttl + margin); + + assert!(!models_override_is_stale(true, Some(just_fresh), ttl_hours)); + assert!(models_override_is_stale(true, Some(just_stale), ttl_hours)); + } + + #[test] + fn future_mtime_is_not_stale() { + let future = SystemTime::now() + std::time::Duration::from_secs(3600); + + assert!(!models_override_is_stale(true, Some(future), 24)); + } + + #[test] + #[serial_test::serial] + fn models_override_loading_and_atomic_write() { + use std::fs; + + let unique = SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap() + .as_nanos(); + let tmp_dir = env::temp_dir().join(format!("coyote-models-override-{unique}")); + create_dir_all(&tmp_dir).unwrap(); + + let env_name = get_env_name("config_dir"); + let prev = env::var_os(&env_name); + unsafe { env::set_var(&env_name, &tmp_dir) }; + + let result = std::panic::catch_unwind(|| { + let path = paths::models_override_file(); + let entry = || ProviderModels { + provider: "openai".into(), + oauth: None, + models: vec![client::ModelData::new("gpt-test")], + }; + + // Missing override is unloadable. + assert!(paths::local_models_override().is_err()); + + // Corrupt override is unloadable. + fs::write(&path, "not: [valid").unwrap(); + assert!(paths::local_models_override().is_err()); + + // Version-mismatched override is unloadable. + let mismatched = ModelsOverride { + version: "0.0.0".into(), + list: vec![entry()], + }; + fs::write(&path, serde_yaml::to_string(&mismatched).unwrap()).unwrap(); + assert!(paths::local_models_override().is_err()); + + // write_models_override goes through the sibling temp file and + // leaves a loadable override behind. + let written = write_models_override(vec![entry()]).unwrap(); + assert_eq!(written, path); + let mut tmp_name = path.as_os_str().to_os_string(); + tmp_name.push(format!(".{}.tmp", std::process::id())); + assert!(!PathBuf::from(tmp_name).exists()); + let loaded = paths::local_models_override().unwrap(); + assert_eq!(loaded.len(), 1); + assert_eq!(loaded[0].provider, "openai"); + }); + + unsafe { + match prev { + Some(v) => env::set_var(&env_name, v), + None => env::remove_var(&env_name), + } + } + let _ = fs::remove_dir_all(&tmp_dir); + if let Err(panic) = result { + std::panic::resume_unwind(panic); + } + } } diff --git a/src/config/request_context.rs b/src/config/request_context.rs index f614356..e2f2547 100644 --- a/src/config/request_context.rs +++ b/src/config/request_context.rs @@ -338,6 +338,8 @@ pub struct RequestContext { pub last_continuation_response: Option, pub pending_prefill: Option, + pub session_abort: Option, + pub render_mode: RenderMode, } @@ -375,6 +377,7 @@ impl RequestContext { skill_registry: SkillRegistry::default(), last_continuation_response: None, pending_prefill: None, + session_abort: None, render_mode: RenderMode::default(), } } @@ -439,6 +442,7 @@ impl RequestContext { skill_registry: SkillRegistry::default(), last_continuation_response: None, pending_prefill: None, + session_abort: None, render_mode: RenderMode::default(), }; ctx.refresh_mcp_tool_filters(); @@ -492,6 +496,7 @@ impl RequestContext { skill_registry: self.skill_registry.clone(), last_continuation_response: None, pending_prefill: None, + session_abort: self.session_abort.clone(), render_mode: self.render_mode, } } @@ -541,6 +546,7 @@ impl RequestContext { skill_registry: SkillRegistry::default(), last_continuation_response: None, pending_prefill: None, + session_abort: None, render_mode: parent.render_mode, } } @@ -5232,7 +5238,7 @@ mod tests { // with an empty client list, which would permanently pin every later // model lookup in this process to "unknown model" and make any test that // needs a resolvable model dependent on test ordering. Seed the caches - // before any test runs with one client, "test-seeded", exposing a single + // before any test runs with a client, "test-seeded", exposing a single // embedding model. Deliberately NO chat model: some tests assert that no // chat model is available, and chat lookups don't need one — a // "test-seeded:" chat id resolves through the create-from-name @@ -5252,8 +5258,19 @@ mod tests { embedder.model_type = "embedding".to_string(); config.models = vec![embedder]; } + // A claude client is seeded alongside it so tests can exercise + // provider-quirk inheritance through the create-from-name fallback. + // It deliberately carries one embedding model: an empty `models` list + // would fall back to the full embedded claude catalog and register + // real chat models, breaking the no-chat-model invariant above. + // The test-dual-model pair shares one id across two types, mirroring + // jina:jina-colbert-v2, for the type-aware lookup tests. + let claude: ClientConfig = serde_yaml::from_str( + "type: claude\nmodels:\n - name: test-claude-embedder\n type: embedding\n - name: test-dual-model\n type: embedding\n - name: test-dual-model\n type: reranker\n", + ) + .unwrap(); let config = AppConfig { - clients: vec![client], + clients: vec![client, claude], ..AppConfig::default() }; let _ = list_client_names(&config); diff --git a/src/function/agents.rs b/src/function/agents.rs index 0743611..a03f49a 100644 --- a/src/function/agents.rs +++ b/src/function/agents.rs @@ -7,7 +7,7 @@ use crate::config::{ use crate::supervisor::mailbox::{Envelope, EnvelopePayload, Inbox}; use crate::supervisor::notification::agent_notification; use crate::supervisor::{AgentExitStatus, AgentHandle, AgentResult, Supervisor, TaskKind}; -use crate::utils::{AbortSignal, create_abort_signal, wait_abort_signal}; +use crate::utils::{AbortSignal, create_abort_signal, wait_abort_signal, wait_user_interrupt}; use crate::graph; use anyhow::{Context, Result, anyhow, bail}; @@ -1031,6 +1031,14 @@ async fn handle_collect(ctx: &mut RequestContext, args: &Value) -> Result sup.abort_signal_for(id) }; + let interrupted = || { + json!({ + "status": "interrupted", + "id": id, + "message": format!("agent__collect was interrupted by the user; agent '{id}' is still running in the background. Collect it again later, cancel it with agent__cancel, or continue with other work."), + }) + }; + loop { let is_finished = { let sup = supervisor.read(); @@ -1041,6 +1049,10 @@ async fn handle_collect(ctx: &mut RequestContext, args: &Value) -> Result break; } + if ctx.session_abort.as_ref().is_some_and(|s| s.aborted()) { + return Ok(interrupted()); + } + if let Some(queue) = ctx.root_escalation_queue() && queue.has_pending() { @@ -1068,10 +1080,18 @@ async fn handle_collect(ctx: &mut RequestContext, args: &Value) -> Result tokio::select! { _ = time::sleep(Duration::from_millis(200)) => {} _ = wait_abort_signal(abort) => {} + _ = wait_user_interrupt(ctx.session_abort.as_ref()) => { + return Ok(interrupted()); + } } } None => { - time::sleep(Duration::from_millis(200)).await; + tokio::select! { + _ = time::sleep(Duration::from_millis(200)) => {} + _ = wait_user_interrupt(ctx.session_abort.as_ref()) => { + return Ok(interrupted()); + } + } } } } @@ -2557,6 +2577,72 @@ mod tests { ); } + #[test] + fn handle_collect_session_interrupt_returns_and_keeps_agent() { + run_async(async { + let mut ctx = ctx_with_supervisor(4, 3); + let (tx, rx) = tokio::sync::oneshot::channel::<()>(); + let join_handle = tokio::spawn(async move { + let _ = rx.await; + Ok(AgentResult { + id: "a1".to_string(), + agent_name: "explore".to_string(), + output: "late output".to_string(), + exit_status: AgentExitStatus::Completed, + }) + }); + let handle = AgentHandle { + id: "a1".to_string(), + agent_name: "explore".to_string(), + depth: 1, + inbox: Arc::new(Inbox::new()), + abort_signal: create_abort_signal(), + join_handle, + child_supervisor: None, + }; + ctx.supervisor + .as_ref() + .unwrap() + .write() + .register(handle) + .unwrap(); + + let session = create_abort_signal(); + session.set_ctrlc(); + ctx.session_abort = Some(session.clone()); + + let result = time::timeout( + Duration::from_secs(2), + handle_collect(&mut ctx, &json!({"id": "a1"})), + ) + .await + .expect("interrupted collect must return promptly") + .unwrap(); + + assert_eq!(result["status"], "interrupted"); + assert_eq!(result["id"], "a1"); + assert!( + result["message"] + .as_str() + .unwrap() + .contains("still running") + ); + assert_eq!( + ctx.supervisor.as_ref().unwrap().read().is_finished("a1"), + Some(false) + ); + + session.reset(); + tx.send(()).unwrap(); + + let collected = handle_collect(&mut ctx, &json!({"id": "a1"})) + .await + .unwrap(); + assert_eq!(collected["status"], "completed"); + assert_eq!(collected["output"], "late output"); + }); + } + #[test] fn handle_collect_pending_escalations_early_out_keeps_handle() { let rt = tokio::runtime::Builder::new_current_thread() diff --git a/src/function/jobs.rs b/src/function/jobs.rs index 9e35e80..b191051 100644 --- a/src/function/jobs.rs +++ b/src/function/jobs.rs @@ -16,7 +16,9 @@ use crate::mcp::{ }; use crate::supervisor::notification::job_notification; use crate::supervisor::{JobHandle, JobResult, JobState, JobStatus, Supervisor}; -use crate::utils::{create_abort_signal, muted_warning_text, temp_file, wait_abort_signal}; +use crate::utils::{ + create_abort_signal, muted_warning_text, temp_file, wait_abort_signal, wait_user_interrupt, +}; use anyhow::{Context, Result, anyhow, bail}; use indexmap::IndexMap; @@ -623,6 +625,14 @@ async fn handle_collect(ctx: &RequestContext, args: &Value) -> Result { job.abort_signal.clone() }; + let interrupted = || { + json!({ + "status": "interrupted", + "id": id, + "message": format!("job__collect was interrupted by the user; job '{id}' is still running in the background. Collect it again later, cancel it with job__cancel, or continue with other work."), + }) + }; + loop { let is_finished = { let sup = supervisor.read(); @@ -633,6 +643,10 @@ async fn handle_collect(ctx: &RequestContext, args: &Value) -> Result { break; } + if ctx.session_abort.as_ref().is_some_and(|s| s.aborted()) { + return Ok(interrupted()); + } + if let Some(queue) = ctx.root_escalation_queue() && queue.has_pending() { @@ -666,6 +680,9 @@ async fn handle_collect(ctx: &RequestContext, args: &Value) -> Result { tokio::select! { _ = time::sleep(Duration::from_millis(200)) => {} _ = wait_abort_signal(&target_abort) => {} + _ = wait_user_interrupt(ctx.session_abort.as_ref()) => { + return Ok(interrupted()); + } } } @@ -2140,6 +2157,74 @@ mod tests { }); } + #[test] + fn handle_collect_session_interrupt_returns_and_keeps_job() { + run_async(async { + let mut ctx = ctx_with_job_supervisor(4); + let state = Arc::new(Mutex::new(JobState { + status: JobStatus::Running, + pgid: None, + })); + let (tx, rx) = tokio::sync::oneshot::channel::<()>(); + let task_state = Arc::clone(&state); + let join_handle = tokio::spawn(async move { + let _ = rx.await; + task_state.lock().status = JobStatus::Completed; + Ok(JobResult { + output: json!("late result"), + exit_code: Some(0), + output_bytes_captured: 0, + }) + }); + let handle = JobHandle { + id: "j1".to_string(), + tool: "execute_command".to_string(), + started_at: Instant::now(), + join_handle, + abort_signal: create_abort_signal(), + state, + output_buf: Arc::new(Mutex::new(RingBuf::default())), + no_change_checks: 0, + last_check_state: None, + }; + ctx.supervisor + .as_ref() + .unwrap() + .write() + .register(handle) + .unwrap(); + + let session = create_abort_signal(); + session.set_ctrlc(); + ctx.session_abort = Some(session.clone()); + + let result = time::timeout( + Duration::from_secs(2), + handle_collect(&ctx, &json!({"id": "j1"})), + ) + .await + .expect("interrupted collect must return promptly") + .unwrap(); + + assert_eq!(result["status"], "interrupted"); + assert_eq!(result["id"], "j1"); + assert!( + result["message"] + .as_str() + .unwrap() + .contains("still running") + ); + assert!(ctx.supervisor.as_ref().unwrap().read().has_job("j1")); + + session.reset(); + tx.send(()).unwrap(); + + let collected = handle_collect(&ctx, &json!({"id": "j1"})).await.unwrap(); + assert_eq!(collected["status"], "completed"); + assert_eq!(collected["result"], "late result"); + }); + } + #[test] fn handle_collect_full_result_returns_uncapped() { run_async(async { diff --git a/src/graph/executor.rs b/src/graph/executor.rs index 0d63daf..9a178f9 100644 --- a/src/graph/executor.rs +++ b/src/graph/executor.rs @@ -695,6 +695,7 @@ nodes: type: script script: doubler.py state_updates: {} + timeout: 60 done: type: end output: "{{doubled}}" diff --git a/src/graph/script.rs b/src/graph/script.rs index 9d41c4c..688d6ad 100644 --- a/src/graph/script.rs +++ b/src/graph/script.rs @@ -262,13 +262,16 @@ echo '{"quality": 0.85, "issues": 3, "_next": "approve"}' #[tokio::test] async fn bash_script_can_read_state_from_env() { - if !cmd_available("bash") || !cmd_available("python3") { - eprintln!("skipping: bash or python3 not available"); + if !cmd_available("bash") { + eprintln!("skipping: bash not available"); return; } + // Pure-bash JSON extraction: spawning python3 here blew tight + // timeouts on Windows CI (first-start AV scans of the interpreter). let (dir, path) = write_script( r#"#!/bin/bash -NAME=$(python3 -c 'import json,os; print(json.loads(os.environ["GRAPH_STATE"])["name"])') +t=${GRAPH_STATE#*'"name":"'} +NAME=${t%%'"'*} printf '{"greeting": "hello %s"}' "$NAME" "#, "sh", @@ -280,7 +283,7 @@ printf '{"greeting": "hello %s"}' "$NAME" let _ = executor .execute( - &node_for(path.file_name().unwrap().to_str().unwrap(), 5), + &node_for(path.file_name().unwrap().to_str().unwrap(), 30), &mut state, ) .await @@ -466,7 +469,7 @@ echo '{"ok":true}' #[tokio::test] async fn large_state_is_delivered_via_file_env_var() { - if !cmd_available("bash") || !cmd_available("python3") { + if !cmd_available("bash") { return; } let big = "x".repeat(MAX_STATE_SIZE_BYTES + 1024); @@ -476,7 +479,10 @@ echo '{"ok":true}' let (dir, path) = write_script( r#"#!/bin/bash if [ -n "$GRAPH_STATE_FILE" ]; then - LEN=$(python3 -c 'import json,os; print(len(json.load(open(os.environ["GRAPH_STATE_FILE"]))["blob"]))') + CONTENT=$(cat "$GRAPH_STATE_FILE") + t=${CONTENT#*'"blob":"'} + BLOB=${t%%'"'*} + LEN=${#BLOB} printf '{"blob_len": %s, "via_file": true}' "$LEN" elif [ -n "$GRAPH_STATE" ]; then echo '{"via_file": false}' @@ -489,7 +495,7 @@ fi let executor = ScriptExecutor::new(&dir); executor .execute( - &node_for(path.file_name().unwrap().to_str().unwrap(), 10), + &node_for(path.file_name().unwrap().to_str().unwrap(), 30), &mut state, ) .await @@ -524,7 +530,7 @@ print(json.dumps({ let executor = ScriptExecutor::new(&dir); let next = executor .execute( - &node_for(path.file_name().unwrap().to_str().unwrap(), 5), + &node_for(path.file_name().unwrap().to_str().unwrap(), 60), &mut state, ) .await diff --git a/src/main.rs b/src/main.rs index 9309149..6db2fa9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,13 +20,14 @@ extern crate log; use crate::cli::Cli; use crate::client::{ - ModelType, call_chat_completions, call_chat_completions_streaming, list_models, oauth, + ModelType, call_chat_completions, call_chat_completions_streaming, catalog, list_models, oauth, }; use crate::config::instructions::WORKSPACE_INSTRUCTIONS_FILE_NAME; use crate::config::{ Agent, AppConfig, AppState, CODE_ROLE, Config, EXPLAIN_SHELL_ROLE, Input, MemoryScope, RenderMode, RequestContext, SHELL_ROLE, TEMP_SESSION_NAME, WorkingMode, ensure_parent_exists, - install_builtins, list_agents, load_env_file, macro_execute, sync_models, + install_builtins, list_agents, load_env_file, macro_execute, maybe_spawn_models_refresh, + sync_models, }; use crate::config::{memory, paths}; use crate::function::agents::{GuardrailAction, check_pending_tasks_guardrail}; @@ -101,6 +102,7 @@ async fn main() -> Result<()> { let info_flag = cli.info || cli.sync_models + || cli.generate_models.is_some() || cli.list_models || cli.list_roles || cli.list_agents @@ -292,7 +294,11 @@ async fn run( ) -> Result<()> { if cli.sync_models { let url = ctx.app.config.sync_models_url(); - return sync_models(&url, abort_signal.clone()).await; + return sync_models(url.as_deref(), abort_signal.clone()).await; + } + + if let Some(path) = &cli.generate_models { + return catalog::generate_models_file(path).await; } if cli.list_models { @@ -544,6 +550,7 @@ async fn run( if !*IS_STDOUT_TERMINAL { bail!("No TTY for REPL") } + maybe_spawn_models_refresh(&ctx.app.config); start_interactive(ctx).await } } @@ -557,6 +564,7 @@ async fn start_directive( abort_signal: AbortSignal, ) -> Result<()> { let app: Arc = Arc::clone(&ctx.app.config); + ctx.session_abort = Some(abort_signal.clone()); if graph::active_agent_graph_name(ctx).is_some() { ctx.before_chat_completion(&input)?; diff --git a/src/repl/mod.rs b/src/repl/mod.rs index 847e896..a57efd9 100644 --- a/src/repl/mod.rs +++ b/src/repl/mod.rs @@ -1432,6 +1432,7 @@ async fn ask( if input.is_empty() { return Ok(()); } + ctx.session_abort = Some(abort_signal.clone()); if with_embeddings { input.use_embeddings(abort_signal.clone()).await?; } diff --git a/src/utils/abort_signal.rs b/src/utils/abort_signal.rs index 36f4bf1..eebca96 100644 --- a/src/utils/abort_signal.rs +++ b/src/utils/abort_signal.rs @@ -68,6 +68,29 @@ pub async fn wait_abort_signal(abort_signal: &AbortSignal) { } } +/// Completes when the user interrupts: a SIGINT arrives, or the session's turn +/// signal is (or becomes) aborted. Needed because tools run in cooked mode -- +/// tokio's global SIGINT handler (installed by the first `ctrl_c()` poll) +/// swallows the signal with nobody listening. On SIGINT, sets ctrl-c on the +/// session signal so the surrounding turn aborts too. With `None`, only the +/// SIGINT arm applies. +pub async fn wait_user_interrupt(session: Option<&AbortSignal>) { + let ctrl_c = async { + if tokio::signal::ctrl_c().await.is_err() { + std::future::pending::<()>().await; + } + }; + match session { + Some(signal) => { + tokio::select! { + _ = ctrl_c => signal.set_ctrlc(), + _ = wait_abort_signal(signal) => {} + } + } + None => ctrl_c.await, + } +} + pub fn poll_abort_signal(abort_signal: &AbortSignal) -> Result { if event::poll(Duration::from_millis(25))? && let Event::Key(key) = event::read()? @@ -86,3 +109,18 @@ pub fn poll_abort_signal(abort_signal: &AbortSignal) -> Result { } Ok(false) } + +#[cfg(test)] +mod tests { + use super::*; + + #[tokio::test] + async fn wait_user_interrupt_returns_promptly_on_preset_session_signal() { + let signal = create_abort_signal(); + signal.set_ctrlc(); + + tokio::time::timeout(Duration::from_secs(1), wait_user_interrupt(Some(&signal))) + .await + .expect("must return promptly when the session signal is already set"); + } +}