diff --git a/.changeset/calm-timeline-follow.md b/.changeset/calm-timeline-follow.md deleted file mode 100644 index 77c4d6ca811..00000000000 --- a/.changeset/calm-timeline-follow.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"kilo-code": patch ---- - -Keep task timelines in place while reviewing earlier activity across Kilo chat surfaces, and resume following updates from the latest bar. diff --git a/.changeset/fast-agent-snapshots.md b/.changeset/fast-agent-snapshots.md new file mode 100644 index 00000000000..039e35176a6 --- /dev/null +++ b/.changeset/fast-agent-snapshots.md @@ -0,0 +1,5 @@ +--- +"@kilocode/cli": patch +--- + +Speed up the first Agent Manager prompt in new worktrees by seeding snapshots from the checkout's Git index. diff --git a/.changeset/fresh-provider-models.md b/.changeset/fresh-provider-models.md new file mode 100644 index 00000000000..5919d57f2fc --- /dev/null +++ b/.changeset/fresh-provider-models.md @@ -0,0 +1,5 @@ +--- +"@kilocode/cli": patch +--- + +Refresh connected provider model lists when the models catalog updates. diff --git a/.changeset/restore-scout-codesearch.md b/.changeset/restore-scout-codesearch.md new file mode 100644 index 00000000000..6d83328eda1 --- /dev/null +++ b/.changeset/restore-scout-codesearch.md @@ -0,0 +1,5 @@ +--- +"@kilocode/cli": patch +--- + +Preserve the code search tool and Scout access after the OpenCode provider and agent updates. diff --git a/.changeset/restore-session-export.md b/.changeset/restore-session-export.md deleted file mode 100644 index eea6ce17a8b..00000000000 --- a/.changeset/restore-session-export.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@kilocode/cli": patch ---- - -Re-enable free-model session and Git workspace data export. diff --git a/.changeset/session-patches-stay-whole.md b/.changeset/session-patches-stay-whole.md new file mode 100644 index 00000000000..05f145ceac8 --- /dev/null +++ b/.changeset/session-patches-stay-whole.md @@ -0,0 +1,5 @@ +--- +"kilo-code": patch +--- + +Preserve complete session state when applying partial session updates in VS Code. diff --git a/.changeset/steady-tui-streams.md b/.changeset/steady-tui-streams.md new file mode 100644 index 00000000000..65b122ba078 --- /dev/null +++ b/.changeset/steady-tui-streams.md @@ -0,0 +1,5 @@ +--- +"@kilocode/cli": patch +--- + +Restore streamed responses in the CLI TUI and move code indexing status into the session sidebar. diff --git a/.github/actions/setup-bun/action.yml b/.github/actions/setup-bun/action.yml index 9859174a2e3..5b44517ec51 100644 --- a/.github/actions/setup-bun/action.yml +++ b/.github/actions/setup-bun/action.yml @@ -23,7 +23,7 @@ runs: fi - name: Setup Bun - uses: oven-sh/setup-bun@v2 + uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 with: bun-version-file: ${{ !steps.bun-url.outputs.url && 'package.json' || '' }} bun-download-url: ${{ steps.bun-url.outputs.url }} @@ -33,8 +33,9 @@ runs: shell: bash run: echo "dir=$(bun pm cache)" >> "$GITHUB_OUTPUT" - - name: Cache Bun dependencies - uses: actions/cache@v4 + - name: Restore Bun dependencies + id: bun-cache + uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: path: ${{ steps.cache.outputs.dir }} key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }} @@ -56,3 +57,10 @@ runs: bun install ${{ inputs.install-flags }} fi shell: bash + + - name: Save Bun dependencies + if: steps.bun-cache.outputs.cache-hit != 'true' && github.event_name != 'pull_request' && github.event_name != 'pull_request_target' + uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + with: + path: ${{ steps.cache.outputs.dir }} + key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }} diff --git a/.github/actions/setup-git-committer/action.yml b/.github/actions/setup-git-committer/action.yml index 0474b670a6e..fa00f28b051 100644 --- a/.github/actions/setup-git-committer/action.yml +++ b/.github/actions/setup-git-committer/action.yml @@ -21,7 +21,7 @@ runs: steps: - name: Create app token id: apptoken - uses: actions/create-github-app-token@v2 + uses: actions/create-github-app-token@fee1f7d63c2ff003460e3d139729b119787bc349 # v2.2.2 with: # kilocode_change start app-id: ${{ inputs['kilo-maintainer-app-id'] }} diff --git a/.github/workflows/close-issues.yml b/.github/workflows/close-issues.yml index c6575f750a2..c071fd5bc83 100644 --- a/.github/workflows/close-issues.yml +++ b/.github/workflows/close-issues.yml @@ -15,7 +15,7 @@ jobs: steps: - uses: actions/checkout@v6 # kilocode_change - - uses: oven-sh/setup-bun@v2 + - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 with: bun-version: latest diff --git a/.github/workflows/close-stale-prs.yml b/.github/workflows/close-stale-prs.yml index 13b0cf02197..3e7b1db14b7 100644 --- a/.github/workflows/close-stale-prs.yml +++ b/.github/workflows/close-stale-prs.yml @@ -22,7 +22,7 @@ jobs: timeout-minutes: 15 steps: - name: Close inactive PRs - uses: actions/github-script@v8 + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | diff --git a/.github/workflows/containers.yml b/.github/workflows/containers.yml index a261d6f5b3b..797252b7fd8 100644 --- a/.github/workflows/containers.yml +++ b/.github/workflows/containers.yml @@ -31,13 +31,13 @@ jobs: - uses: ./.github/actions/setup-bun - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 - name: Login to GHCR - uses: docker/login-action@v3 + uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 with: registry: ghcr.io username: ${{ github.repository_owner }} diff --git a/.github/workflows/disabled/compliance-close.yml.disabled b/.github/workflows/disabled/compliance-close.yml.disabled index c3bcf9f686f..14e68701e57 100644 --- a/.github/workflows/disabled/compliance-close.yml.disabled +++ b/.github/workflows/disabled/compliance-close.yml.disabled @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Close non-compliant issues and PRs after 2 hours - uses: actions/github-script@v7 + uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0 with: script: | const { data: items } = await github.rest.issues.listForRepo({ diff --git a/.github/workflows/disabled/notify-discord.yml.disabled b/.github/workflows/disabled/notify-discord.yml.disabled index 6bd1ab67153..1cfb52990ad 100644 --- a/.github/workflows/disabled/notify-discord.yml.disabled +++ b/.github/workflows/disabled/notify-discord.yml.disabled @@ -12,6 +12,6 @@ jobs: runs-on: depot-ubuntu-24.04 steps: - name: Send nicely-formatted embed to Discord - uses: SethCohen/github-releases-to-discord@v1 + uses: SethCohen/github-releases-to-discord@24d166886aee4646d448c8a389ff9e1ebcab3682 # v1.20.0 with: webhook_url: ${{ secrets.DISCORD_WEBHOOK }} diff --git a/.github/workflows/disabled/pr-management.yml.disabled b/.github/workflows/disabled/pr-management.yml.disabled index 1e331bd6f2e..b43c6af9bab 100644 --- a/.github/workflows/disabled/pr-management.yml.disabled +++ b/.github/workflows/disabled/pr-management.yml.disabled @@ -12,7 +12,7 @@ jobs: pull-requests: write steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 with: fetch-depth: 1 @@ -78,7 +78,7 @@ jobs: issues: write steps: - name: Add Contributor Label - uses: actions/github-script@v8 + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 with: script: | const isPR = !!context.payload.pull_request; diff --git a/.github/workflows/disabled/pr-standards.yml.disabled b/.github/workflows/disabled/pr-standards.yml.disabled index 1edbd5d061d..06838089d35 100644 --- a/.github/workflows/disabled/pr-standards.yml.disabled +++ b/.github/workflows/disabled/pr-standards.yml.disabled @@ -12,7 +12,7 @@ jobs: pull-requests: write steps: - name: Check PR standards - uses: actions/github-script@v7 + uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0 with: script: | const pr = context.payload.pull_request; @@ -159,7 +159,7 @@ jobs: pull-requests: write steps: - name: Check PR template compliance - uses: actions/github-script@v7 + uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0 with: script: | const pr = context.payload.pull_request; diff --git a/.github/workflows/disabled/publish-github-action.yml.disabled b/.github/workflows/disabled/publish-github-action.yml.disabled index 3d8426a0dbc..e16d5f7919e 100644 --- a/.github/workflows/disabled/publish-github-action.yml.disabled +++ b/.github/workflows/disabled/publish-github-action.yml.disabled @@ -16,7 +16,7 @@ jobs: publish: runs-on: blacksmith-4vcpu-ubuntu-2404 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 with: fetch-depth: 0 diff --git a/.github/workflows/disabled/release-github-action.yml.disabled b/.github/workflows/disabled/release-github-action.yml.disabled index ddfb7a7fca8..6c2987c8eba 100644 --- a/.github/workflows/disabled/release-github-action.yml.disabled +++ b/.github/workflows/disabled/release-github-action.yml.disabled @@ -16,7 +16,7 @@ jobs: release: runs-on: blacksmith-4vcpu-ubuntu-2404 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 with: fetch-depth: 0 diff --git a/.github/workflows/disabled/review.yml.disabled b/.github/workflows/disabled/review.yml.disabled index b44d262df7c..7f7dc7e8b9b 100644 --- a/.github/workflows/disabled/review.yml.disabled +++ b/.github/workflows/disabled/review.yml.disabled @@ -29,7 +29,7 @@ jobs: fi - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 with: fetch-depth: 1 diff --git a/.github/workflows/disabled/stats.yml.disabled b/.github/workflows/disabled/stats.yml.disabled index 3da92d4691a..b7e1f43b9f4 100644 --- a/.github/workflows/disabled/stats.yml.disabled +++ b/.github/workflows/disabled/stats.yml.disabled @@ -15,7 +15,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - name: Setup Bun uses: ./.github/actions/setup-bun diff --git a/.github/workflows/disabled/storybook.yml.disabled b/.github/workflows/disabled/storybook.yml.disabled index 6d143a8a22f..1e652104d69 100644 --- a/.github/workflows/disabled/storybook.yml.disabled +++ b/.github/workflows/disabled/storybook.yml.disabled @@ -29,7 +29,7 @@ jobs: runs-on: blacksmith-4vcpu-ubuntu-2404 steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - name: Setup Bun uses: ./.github/actions/setup-bun diff --git a/.github/workflows/disabled/sync-zed-extension.yml.disabled b/.github/workflows/disabled/sync-zed-extension.yml.disabled index f14487cde97..6e4b44083c1 100644 --- a/.github/workflows/disabled/sync-zed-extension.yml.disabled +++ b/.github/workflows/disabled/sync-zed-extension.yml.disabled @@ -10,7 +10,7 @@ jobs: name: Release Zed Extension runs-on: blacksmith-4vcpu-ubuntu-2404 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 with: fetch-depth: 0 diff --git a/.github/workflows/nix-eval.yml b/.github/workflows/nix-eval.yml index 51c467e1b24..ff4bc3462a2 100644 --- a/.github/workflows/nix-eval.yml +++ b/.github/workflows/nix-eval.yml @@ -21,10 +21,10 @@ jobs: timeout-minutes: 15 steps: - name: Checkout repository - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Setup Nix - uses: nixbuild/nix-quick-install-action@v34 + uses: nixbuild/nix-quick-install-action@2c9db80fb984ceb1bcaa77cdda3fdf8cfba92035 # v34 - name: Evaluate flake outputs (all systems) run: | diff --git a/.github/workflows/nix-hashes.yml b/.github/workflows/nix-hashes.yml index be48bb895e1..8d9980049f1 100644 --- a/.github/workflows/nix-hashes.yml +++ b/.github/workflows/nix-hashes.yml @@ -42,10 +42,10 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Setup Nix - uses: nixbuild/nix-quick-install-action@v34 + uses: nixbuild/nix-quick-install-action@2c9db80fb984ceb1bcaa77cdda3fdf8cfba92035 # v34 - name: Compute node_modules hash id: hash diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c9301c042d3..76e7f06d2ce 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -46,7 +46,7 @@ jobs: - name: Setup Node id: setup-node continue-on-error: ${{ runner.os == 'Windows' }} - uses: actions/setup-node@v6 + uses: actions/setup-node@v6 # kilocode_change with: node-version: "24" @@ -86,7 +86,7 @@ jobs: - name: Publish unit reports if: always() - uses: mikepenz/action-junit-report@v6 + uses: mikepenz/action-junit-report@bccf2e31636835cf0874589931c4116687171386 # v6.4.0 with: report_paths: packages/*/.artifacts/unit/junit.xml check_name: "unit results (${{ matrix.settings.name }})" diff --git a/.kilo/skills/release-jetbrains/script/dispatch-prepare.ts b/.kilo/skills/release-jetbrains/script/dispatch-prepare.ts index 9589c795416..3fa3411cdcf 100644 --- a/.kilo/skills/release-jetbrains/script/dispatch-prepare.ts +++ b/.kilo/skills/release-jetbrains/script/dispatch-prepare.ts @@ -17,7 +17,9 @@ const { values } = parseArgs({ }) if (values.help) { - console.log(`Usage: bun .kilo/skills/release-jetbrains/script/dispatch-prepare.ts --kind --version [--from-tag ] [--run-id ]`) + console.log( + `Usage: bun .kilo/skills/release-jetbrains/script/dispatch-prepare.ts --kind --version [--from-tag ] [--run-id ]`, + ) process.exit(0) } diff --git a/.kilo/skills/release-jetbrains/script/resolve-version.ts b/.kilo/skills/release-jetbrains/script/resolve-version.ts index 57799b66f65..8245a643619 100644 --- a/.kilo/skills/release-jetbrains/script/resolve-version.ts +++ b/.kilo/skills/release-jetbrains/script/resolve-version.ts @@ -13,7 +13,9 @@ const { values } = parseArgs({ }) if (values.help) { - console.log(`Usage: bun .kilo/skills/release-jetbrains/script/resolve-version.ts --spec `) + console.log( + `Usage: bun .kilo/skills/release-jetbrains/script/resolve-version.ts --spec `, + ) process.exit(0) } diff --git a/.kilo/skills/release-jetbrains/script/update-changelog.ts b/.kilo/skills/release-jetbrains/script/update-changelog.ts index d7dca8b3a75..b6a3ff071fc 100644 --- a/.kilo/skills/release-jetbrains/script/update-changelog.ts +++ b/.kilo/skills/release-jetbrains/script/update-changelog.ts @@ -15,7 +15,9 @@ const { values } = parseArgs({ }) if (values.help) { - console.log(`Usage: bun .kilo/skills/release-jetbrains/script/update-changelog.ts --version --file `) + console.log( + `Usage: bun .kilo/skills/release-jetbrains/script/update-changelog.ts --version --file `, + ) process.exit(0) } @@ -39,7 +41,11 @@ const text = Buffer.from(current.content.replace(/\s/g, ""), "base64").toString( const pattern = regex(ver) if (!pattern.test(text)) throw new Error(`${path} is missing a section for ${ver} on ${branch}`) -const next = text.replace(pattern, `\n${section}\n`).replace(/\n{3,}/g, "\n\n").trimEnd() + "\n" +const next = + text + .replace(pattern, `\n${section}\n`) + .replace(/\n{3,}/g, "\n\n") + .trimEnd() + "\n" if (next === text) { console.log("CHANGELOG.md already contains the provided section") process.exit(0) diff --git a/.kilo/skills/release-jetbrains/script/watch-publish.ts b/.kilo/skills/release-jetbrains/script/watch-publish.ts index 719d46c4c1c..0719bcb2071 100644 --- a/.kilo/skills/release-jetbrains/script/watch-publish.ts +++ b/.kilo/skills/release-jetbrains/script/watch-publish.ts @@ -17,7 +17,9 @@ const { values } = parseArgs({ }) if (values.help) { - console.log(`Usage: bun .kilo/skills/release-jetbrains/script/watch-publish.ts --pr --version [--merge] [--run-id ]`) + console.log( + `Usage: bun .kilo/skills/release-jetbrains/script/watch-publish.ts --pr --version [--merge] [--run-id ]`, + ) process.exit(0) } @@ -70,11 +72,19 @@ async function find() { if (run) return String(run.databaseId) await Bun.sleep(1000) } - throw new Error(`No ${workflow} run found for ${branch}. Merge PR ${pr} first, or pass --merge to merge it automatically.`) + throw new Error( + `No ${workflow} run found for ${branch}. Merge PR ${pr} first, or pass --merge to merge it automatically.`, + ) } function active(status: string) { - return status === "queued" || status === "in_progress" || status === "waiting" || status === "requested" || status === "pending" + return ( + status === "queued" || + status === "in_progress" || + status === "waiting" || + status === "requested" || + status === "pending" + ) } async function runs() { diff --git a/.opencode-version b/.opencode-version index 6ce43629e9b..2bc9bb1ba3e 100644 --- a/.opencode-version +++ b/.opencode-version @@ -1 +1 @@ -v1.14.48 +v1.14.51 diff --git a/.opencode/skills/improve-codebase-architecture/DEEPENING.md b/.opencode/skills/improve-codebase-architecture/DEEPENING.md new file mode 100644 index 00000000000..c52fdfd99f3 --- /dev/null +++ b/.opencode/skills/improve-codebase-architecture/DEEPENING.md @@ -0,0 +1,37 @@ +# Deepening + +How to deepen a cluster of shallow modules safely, given its dependencies. Assumes the vocabulary in [LANGUAGE.md](LANGUAGE.md) — **module**, **interface**, **seam**, **adapter**. + +## Dependency categories + +When assessing a candidate for deepening, classify its dependencies. The category determines how the deepened module is tested across its seam. + +### 1. In-process + +Pure computation, in-memory state, no I/O. Always deepenable — merge the modules and test through the new interface directly. No adapter needed. + +### 2. Local-substitutable + +Dependencies that have local test stand-ins (PGLite for Postgres, in-memory filesystem). Deepenable if the stand-in exists. The deepened module is tested with the stand-in running in the test suite. The seam is internal; no port at the module's external interface. + +### 3. Remote but owned (Ports & Adapters) + +Your own services across a network boundary (microservices, internal APIs). Define a **port** (interface) at the seam. The deep module owns the logic; the transport is injected as an **adapter**. Tests use an in-memory adapter. Production uses an HTTP/gRPC/queue adapter. + +Recommendation shape: _"Define a port at the seam, implement an HTTP adapter for production and an in-memory adapter for testing, so the logic sits in one deep module even though it's deployed across a network."_ + +### 4. True external (Mock) + +Third-party services (Stripe, Twilio, etc.) you don't control. The deepened module takes the external dependency as an injected port; tests provide a mock adapter. + +## Seam discipline + +- **One adapter means a hypothetical seam. Two adapters means a real one.** Don't introduce a port unless at least two adapters are justified (typically production + test). A single-adapter seam is just indirection. +- **Internal seams vs external seams.** A deep module can have internal seams (private to its implementation, used by its own tests) as well as the external seam at its interface. Don't expose internal seams through the interface just because tests use them. + +## Testing strategy: replace, don't layer + +- Old unit tests on shallow modules become waste once tests at the deepened module's interface exist — delete them. +- Write new tests at the deepened module's interface. The **interface is the test surface**. +- Tests assert on observable outcomes through the interface, not internal state. +- Tests should survive internal refactors — they describe behaviour, not implementation. If a test has to change when the implementation changes, it's testing past the interface. diff --git a/.opencode/skills/improve-codebase-architecture/INTERFACE-DESIGN.md b/.opencode/skills/improve-codebase-architecture/INTERFACE-DESIGN.md new file mode 100644 index 00000000000..3197723a0d0 --- /dev/null +++ b/.opencode/skills/improve-codebase-architecture/INTERFACE-DESIGN.md @@ -0,0 +1,44 @@ +# Interface Design + +When the user wants to explore alternative interfaces for a chosen deepening candidate, use this parallel sub-agent pattern. Based on "Design It Twice" (Ousterhout) — your first idea is unlikely to be the best. + +Uses the vocabulary in [LANGUAGE.md](LANGUAGE.md) — **module**, **interface**, **seam**, **adapter**, **leverage**. + +## Process + +### 1. Frame the problem space + +Before spawning sub-agents, write a user-facing explanation of the problem space for the chosen candidate: + +- The constraints any new interface would need to satisfy +- The dependencies it would rely on, and which category they fall into (see [DEEPENING.md](DEEPENING.md)) +- A rough illustrative code sketch to ground the constraints — not a proposal, just a way to make the constraints concrete + +Show this to the user, then immediately proceed to Step 2. The user reads and thinks while the sub-agents work in parallel. + +### 2. Spawn sub-agents + +Spawn 3+ sub-agents in parallel using the Agent tool. Each must produce a **radically different** interface for the deepened module. + +Prompt each sub-agent with a separate technical brief (file paths, coupling details, dependency category from [DEEPENING.md](DEEPENING.md), what sits behind the seam). The brief is independent of the user-facing problem-space explanation in Step 1. Give each agent a different design constraint: + +- Agent 1: "Minimize the interface — aim for 1–3 entry points max. Maximise leverage per entry point." +- Agent 2: "Maximise flexibility — support many use cases and extension." +- Agent 3: "Optimise for the most common caller — make the default case trivial." +- Agent 4 (if applicable): "Design around ports & adapters for cross-seam dependencies." + +Include both [LANGUAGE.md](LANGUAGE.md) vocabulary and CONTEXT.md vocabulary in the brief so each sub-agent names things consistently with the architecture language and the project's domain language. + +Each sub-agent outputs: + +1. Interface (types, methods, params — plus invariants, ordering, error modes) +2. Usage example showing how callers use it +3. What the implementation hides behind the seam +4. Dependency strategy and adapters (see [DEEPENING.md](DEEPENING.md)) +5. Trade-offs — where leverage is high, where it's thin + +### 3. Present and compare + +Present designs sequentially so the user can absorb each one, then compare them in prose. Contrast by **depth** (leverage at the interface), **locality** (where change concentrates), and **seam placement**. + +After comparing, give your own recommendation: which design you think is strongest and why. If elements from different designs would combine well, propose a hybrid. Be opinionated — the user wants a strong read, not a menu. diff --git a/.opencode/skills/improve-codebase-architecture/LANGUAGE.md b/.opencode/skills/improve-codebase-architecture/LANGUAGE.md new file mode 100644 index 00000000000..dd9b60fea07 --- /dev/null +++ b/.opencode/skills/improve-codebase-architecture/LANGUAGE.md @@ -0,0 +1,53 @@ +# Language + +Shared vocabulary for every suggestion this skill makes. Use these terms exactly — don't substitute "component," "service," "API," or "boundary." Consistent language is the whole point. + +## Terms + +**Module** +Anything with an interface and an implementation. Deliberately scale-agnostic — applies equally to a function, class, package, or tier-spanning slice. +_Avoid_: unit, component, service. + +**Interface** +Everything a caller must know to use the module correctly. Includes the type signature, but also invariants, ordering constraints, error modes, required configuration, and performance characteristics. +_Avoid_: API, signature (too narrow — those refer only to the type-level surface). + +**Implementation** +What's inside a module — its body of code. Distinct from **Adapter**: a thing can be a small adapter with a large implementation (a Postgres repo) or a large adapter with a small implementation (an in-memory fake). Reach for "adapter" when the seam is the topic; "implementation" otherwise. + +**Depth** +Leverage at the interface — the amount of behaviour a caller (or test) can exercise per unit of interface they have to learn. A module is **deep** when a large amount of behaviour sits behind a small interface. A module is **shallow** when the interface is nearly as complex as the implementation. + +**Seam** _(from Michael Feathers)_ +A place where you can alter behaviour without editing in that place. The _location_ at which a module's interface lives. Choosing where to put the seam is its own design decision, distinct from what goes behind it. +_Avoid_: boundary (overloaded with DDD's bounded context). + +**Adapter** +A concrete thing that satisfies an interface at a seam. Describes _role_ (what slot it fills), not substance (what's inside). + +**Leverage** +What callers get from depth. More capability per unit of interface they have to learn. One implementation pays back across N call sites and M tests. + +**Locality** +What maintainers get from depth. Change, bugs, knowledge, and verification concentrate at one place rather than spreading across callers. Fix once, fixed everywhere. + +## Principles + +- **Depth is a property of the interface, not the implementation.** A deep module can be internally composed of small, mockable, swappable parts — they just aren't part of the interface. A module can have **internal seams** (private to its implementation, used by its own tests) as well as the **external seam** at its interface. +- **The deletion test.** Imagine deleting the module. If complexity vanishes, the module wasn't hiding anything (it was a pass-through). If complexity reappears across N callers, the module was earning its keep. +- **The interface is the test surface.** Callers and tests cross the same seam. If you want to test _past_ the interface, the module is probably the wrong shape. +- **One adapter means a hypothetical seam. Two adapters means a real one.** Don't introduce a seam unless something actually varies across it. + +## Relationships + +- A **Module** has exactly one **Interface** (the surface it presents to callers and tests). +- **Depth** is a property of a **Module**, measured against its **Interface**. +- A **Seam** is where a **Module**'s **Interface** lives. +- An **Adapter** sits at a **Seam** and satisfies the **Interface**. +- **Depth** produces **Leverage** for callers and **Locality** for maintainers. + +## Rejected framings + +- **Depth as ratio of implementation-lines to interface-lines** (Ousterhout): rewards padding the implementation. We use depth-as-leverage instead. +- **"Interface" as the TypeScript `interface` keyword or a class's public methods**: too narrow — interface here includes every fact a caller must know. +- **"Boundary"**: overloaded with DDD's bounded context. Say **seam** or **interface**. diff --git a/.opencode/skills/improve-codebase-architecture/SKILL.md b/.opencode/skills/improve-codebase-architecture/SKILL.md new file mode 100644 index 00000000000..05984a60968 --- /dev/null +++ b/.opencode/skills/improve-codebase-architecture/SKILL.md @@ -0,0 +1,71 @@ +--- +name: improve-codebase-architecture +description: Find deepening opportunities in a codebase, informed by the domain language in CONTEXT.md and the decisions in docs/adr/. Use when the user wants to improve architecture, find refactoring opportunities, consolidate tightly-coupled modules, or make a codebase more testable and AI-navigable. +--- + +# Improve Codebase Architecture + +Surface architectural friction and propose **deepening opportunities** — refactors that turn shallow modules into deep ones. The aim is testability and AI-navigability. + +## Glossary + +Use these terms exactly in every suggestion. Consistent language is the point — don't drift into "component," "service," "API," or "boundary." Full definitions in [LANGUAGE.md](LANGUAGE.md). + +- **Module** — anything with an interface and an implementation (function, class, package, slice). +- **Interface** — everything a caller must know to use the module: types, invariants, error modes, ordering, config. Not just the type signature. +- **Implementation** — the code inside. +- **Depth** — leverage at the interface: a lot of behaviour behind a small interface. **Deep** = high leverage. **Shallow** = interface nearly as complex as the implementation. +- **Seam** — where an interface lives; a place behaviour can be altered without editing in place. (Use this, not "boundary.") +- **Adapter** — a concrete thing satisfying an interface at a seam. +- **Leverage** — what callers get from depth. +- **Locality** — what maintainers get from depth: change, bugs, knowledge concentrated in one place. + +Key principles (see [LANGUAGE.md](LANGUAGE.md) for the full list): + +- **Deletion test**: imagine deleting the module. If complexity vanishes, it was a pass-through. If complexity reappears across N callers, it was earning its keep. +- **The interface is the test surface.** +- **One adapter = hypothetical seam. Two adapters = real seam.** + +This skill is _informed_ by the project's domain model. The domain language gives names to good seams; ADRs record decisions the skill should not re-litigate. + +## Process + +### 1. Explore + +Read the project's domain glossary and any ADRs in the area you're touching first. + +Then use the Agent tool with `subagent_type=Explore` to walk the codebase. Don't follow rigid heuristics — explore organically and note where you experience friction: + +- Where does understanding one concept require bouncing between many small modules? +- Where are modules **shallow** — interface nearly as complex as the implementation? +- Where have pure functions been extracted just for testability, but the real bugs hide in how they're called (no **locality**)? +- Where do tightly-coupled modules leak across their seams? +- Which parts of the codebase are untested, or hard to test through their current interface? + +Apply the **deletion test** to anything you suspect is shallow: would deleting it concentrate complexity, or just move it? A "yes, concentrates" is the signal you want. + +### 2. Present candidates + +Present a numbered list of deepening opportunities. For each candidate: + +- **Files** — which files/modules are involved +- **Problem** — why the current architecture is causing friction +- **Solution** — plain English description of what would change +- **Benefits** — explained in terms of locality and leverage, and also in how tests would improve + +**Use CONTEXT.md vocabulary for the domain, and [LANGUAGE.md](LANGUAGE.md) vocabulary for the architecture.** If `CONTEXT.md` defines "Order," talk about "the Order intake module" — not "the FooBarHandler," and not "the Order service." + +**ADR conflicts**: if a candidate contradicts an existing ADR, only surface it when the friction is real enough to warrant revisiting the ADR. Mark it clearly (e.g. _"contradicts ADR-0007 — but worth reopening because…"_). Don't list every theoretical refactor an ADR forbids. + +Do NOT propose interfaces yet. Ask the user: "Which of these would you like to explore?" + +### 3. Grilling loop + +Once the user picks a candidate, drop into a grilling conversation. Walk the design tree with them — constraints, dependencies, the shape of the deepened module, what sits behind the seam, what tests survive. + +Side effects happen inline as decisions crystallize: + +- **Naming a deepened module after a concept not in `CONTEXT.md`?** Add the term to `CONTEXT.md` — same discipline as `/grill-with-docs` (see [CONTEXT-FORMAT.md](../grill-with-docs/CONTEXT-FORMAT.md)). Create the file lazily if it doesn't exist. +- **Sharpening a fuzzy term during the conversation?** Update `CONTEXT.md` right there. +- **User rejects the candidate with a load-bearing reason?** Offer an ADR, framed as: _"Want me to record this as an ADR so future architecture reviews don't re-suggest it?"_ Only offer when the reason would actually be needed by a future explorer to avoid re-suggesting the same thing — skip ephemeral reasons ("not worth it right now") and self-evident ones. See [ADR-FORMAT.md](../grill-with-docs/ADR-FORMAT.md). +- **Want to explore alternative interfaces for the deepened module?** See [INTERFACE-DESIGN.md](INTERFACE-DESIGN.md). diff --git a/.opencode/tui.json b/.opencode/tui.json index f52ed17f410..4cd0d06a261 100644 --- a/.opencode/tui.json +++ b/.opencode/tui.json @@ -1,3 +1,3 @@ { "$schema": "https://opencode.ai/tui.json" -} \ No newline at end of file +} diff --git a/bun.lock b/bun.lock index ed235037f24..51ee026f0d1 100644 --- a/bun.lock +++ b/bun.lock @@ -33,27 +33,55 @@ }, "packages/core": { "name": "@opencode-ai/core", - "version": "7.3.41", + "version": "7.3.42", "bin": { "opencode": "./bin/opencode", }, "dependencies": { + "@ai-sdk/alibaba": "1.0.17", + "@ai-sdk/amazon-bedrock": "4.0.96", + "@ai-sdk/anthropic": "3.0.71", + "@ai-sdk/azure": "3.0.49", + "@ai-sdk/cerebras": "2.0.41", + "@ai-sdk/cohere": "3.0.27", + "@ai-sdk/deepinfra": "2.0.41", + "@ai-sdk/gateway": "3.0.104", + "@ai-sdk/google": "3.0.63", + "@ai-sdk/google-vertex": "4.0.112", + "@ai-sdk/groq": "3.0.31", + "@ai-sdk/mistral": "3.0.27", + "@ai-sdk/openai": "3.0.53", + "@ai-sdk/openai-compatible": "2.0.41", + "@ai-sdk/perplexity": "3.0.26", + "@ai-sdk/provider": "3.0.8", + "@ai-sdk/provider-utils": "4.0.23", + "@ai-sdk/togetherai": "2.0.41", + "@ai-sdk/vercel": "2.0.39", + "@ai-sdk/xai": "3.0.82", + "@aws-sdk/credential-providers": "3.993.0", "@effect/opentelemetry": "catalog:", "@effect/platform-node": "catalog:", + "@kilocode/kilo-gateway": "workspace:*", "@npmcli/arborist": "9.4.0", "@npmcli/config": "10.8.1", + "@openrouter/ai-sdk-provider": "2.8.1", "@opentelemetry/api": "1.9.0", "@opentelemetry/context-async-hooks": "2.6.1", "@opentelemetry/exporter-trace-otlp-http": "0.214.0", "@opentelemetry/sdk-trace-base": "2.6.1", + "ai-gateway-provider": "3.1.2", "cross-spawn": "catalog:", "effect": "catalog:", + "gitlab-ai-provider": "6.6.0", "glob": "13.0.5", + "google-auth-library": "10.5.0", + "immer": "11.1.4", "mime-types": "3.0.2", "minimatch": "10.2.5", "npm-package-arg": "13.0.2", "rotating-file-stream": "3.2.9", "semver": "^7.6.3", + "venice-ai-sdk-provider": "2.0.1", "xdg-basedir": "5.1.0", "zod": "catalog:", }, @@ -68,7 +96,7 @@ }, "packages/http-recorder": { "name": "@opencode-ai/http-recorder", - "version": "7.3.41", + "version": "7.3.42", "dependencies": { "@effect/platform-node": "catalog:", "effect": "catalog:", @@ -81,7 +109,7 @@ }, "packages/kilo-console": { "name": "@kilocode/kilo-console", - "version": "7.3.41", + "version": "7.3.42", "dependencies": { "@kilocode/kilo-web-ui": "workspace:*", "@kilocode/sdk": "workspace:*", @@ -103,7 +131,7 @@ }, "packages/kilo-docs": { "name": "@kilocode/kilo-docs", - "version": "7.3.41", + "version": "7.3.42", "dependencies": { "@docsearch/css": "^4", "@docsearch/js": "^4", @@ -133,7 +161,7 @@ }, "packages/kilo-gateway": { "name": "@kilocode/kilo-gateway", - "version": "7.3.41", + "version": "7.3.42", "dependencies": { "@ai-sdk/alibaba": "1.0.17", "@ai-sdk/anthropic": "3.0.71", @@ -170,7 +198,7 @@ }, "packages/kilo-i18n": { "name": "@kilocode/kilo-i18n", - "version": "7.3.41", + "version": "7.3.42", "devDependencies": { "@tsconfig/node22": "catalog:", "@types/bun": "catalog:", @@ -180,7 +208,7 @@ }, "packages/kilo-indexing": { "name": "@kilocode/kilo-indexing", - "version": "7.3.41", + "version": "7.3.42", "dependencies": { "@aws-sdk/client-bedrock-runtime": "3.1005.0", "@aws-sdk/credential-provider-ini": "3.972.31", @@ -212,11 +240,11 @@ }, "packages/kilo-jetbrains": { "name": "@kilocode/kilo-jetbrains", - "version": "7.3.41", + "version": "7.3.42", }, "packages/kilo-telemetry": { "name": "@kilocode/kilo-telemetry", - "version": "7.3.41", + "version": "7.3.42", "dependencies": { "@kilocode/kilo-gateway": "workspace:*", "posthog-node": "4.4.0", @@ -230,7 +258,7 @@ }, "packages/kilo-ui": { "name": "@kilocode/kilo-ui", - "version": "7.3.41", + "version": "7.3.42", "dependencies": { "@kilocode/sdk": "workspace:*", "@kobalte/core": "0.13.11", @@ -267,7 +295,7 @@ }, "packages/kilo-vscode": { "name": "kilo-code", - "version": "7.3.41", + "version": "7.3.42", "dependencies": { "@anthropic-ai/sdk": "^0.39.0", "@kilocode/kilo-gateway": "workspace:*", @@ -333,7 +361,7 @@ }, "packages/kilo-web-ui": { "name": "@kilocode/kilo-web-ui", - "version": "7.3.41", + "version": "7.3.42", "dependencies": { "@kilocode/kilo-ui": "workspace:*", "@kobalte/core": "catalog:", @@ -348,7 +376,7 @@ }, "packages/llm": { "name": "@opencode-ai/llm", - "version": "7.3.41", + "version": "7.3.42", "dependencies": { "@smithy/eventstream-codec": "4.2.14", "@smithy/util-utf8": "4.2.2", @@ -366,7 +394,7 @@ }, "packages/opencode": { "name": "@kilocode/cli", - "version": "7.3.41", + "version": "7.3.42", "bin": { "kilo": "./bin/kilo", "kilocode": "./bin/kilo", @@ -420,6 +448,7 @@ "@octokit/rest": "catalog:", "@openauthjs/openauth": "catalog:", "@opencode-ai/script": "workspace:*", + "@opencode-ai/ui": "workspace:*", "@openrouter/ai-sdk-provider": "2.8.1", "@opentelemetry/api": "1.9.0", "@opentelemetry/context-async-hooks": "2.6.1", @@ -458,6 +487,7 @@ "gray-matter": "4.0.3", "hono": "catalog:", "hono-openapi": "catalog:", + "htmlparser2": "8.0.2", "iconv-lite": "0.7.2", "ignore": "7.0.5", "immer": "11.1.4", @@ -532,7 +562,7 @@ }, "packages/plugin": { "name": "@kilocode/plugin", - "version": "7.3.41", + "version": "7.3.42", "dependencies": { "@kilocode/sdk": "workspace:*", "effect": "catalog:", @@ -548,9 +578,9 @@ "typescript": "catalog:", }, "peerDependencies": { - "@opentui/core": ">=0.2.6", - "@opentui/keymap": ">=0.2.6", - "@opentui/solid": ">=0.2.6", + "@opentui/core": ">=0.2.10", + "@opentui/keymap": ">=0.2.10", + "@opentui/solid": ">=0.2.10", }, "optionalPeers": [ "@opentui/core", @@ -560,7 +590,7 @@ }, "packages/plugin-atomic-chat": { "name": "@kilocode/plugin-atomic-chat", - "version": "7.3.41", + "version": "7.3.42", "dependencies": { "@kilocode/plugin": "workspace:*", }, @@ -574,7 +604,7 @@ }, "packages/script": { "name": "@opencode-ai/script", - "version": "7.3.41", + "version": "7.3.42", "dependencies": { "semver": "^7.6.3", }, @@ -585,7 +615,7 @@ }, "packages/sdk/js": { "name": "@kilocode/sdk", - "version": "7.3.41", + "version": "7.3.42", "dependencies": { "cross-spawn": "catalog:", }, @@ -600,7 +630,7 @@ }, "packages/storybook": { "name": "@opencode-ai/storybook", - "version": "7.3.41", + "version": "7.3.42", "devDependencies": { "@opencode-ai/ui": "workspace:*", "@solidjs/meta": "catalog:", @@ -623,7 +653,7 @@ }, "packages/ui": { "name": "@opencode-ai/ui", - "version": "7.3.41", + "version": "7.3.42", "dependencies": { "@kilocode/sdk": "workspace:*", "@kobalte/core": "catalog:", @@ -689,6 +719,7 @@ "overrides": { "@effect/platform-node-shared": "4.0.0-beta.46", "@opentui/core": "catalog:", + "@opentui/keymap": "catalog:", "@opentui/solid": "catalog:", "@types/bun": "catalog:", "@types/node": "catalog:", @@ -707,17 +738,17 @@ }, "catalog": { "@cloudflare/workers-types": "4.20251008.0", - "@effect/opentelemetry": "4.0.0-beta.57", - "@effect/platform-node": "4.0.0-beta.57", + "@effect/opentelemetry": "4.0.0-beta.65", + "@effect/platform-node": "4.0.0-beta.65", "@hono/zod-validator": "0.4.2", "@kobalte/core": "0.13.11", "@lydell/node-pty": "1.2.0-beta.10", "@npmcli/arborist": "9.4.0", "@octokit/rest": "22.0.0", "@openauthjs/openauth": "0.0.0-20250322224806", - "@opentui/core": "0.2.6", - "@opentui/keymap": "0.2.6", - "@opentui/solid": "0.2.6", + "@opentui/core": "0.2.10", + "@opentui/keymap": "0.2.10", + "@opentui/solid": "0.2.10", "@pierre/diffs": "1.1.22", "@playwright/test": "1.59.1", "@solid-primitives/storage": "4.3.3", @@ -739,7 +770,7 @@ "dompurify": "3.4.2", "drizzle-kit": "1.0.0-beta.19-d95b7a4", "drizzle-orm": "1.0.0-beta.19-d95b7a4", - "effect": "4.0.0-beta.59", + "effect": "4.0.0-beta.65", "fuzzysort": "3.1.0", "hono": "4.12.12", "hono-openapi": "1.1.2", @@ -1098,9 +1129,9 @@ "@effect/language-service": ["@effect/language-service@0.84.2", "", { "bin": { "effect-language-service": "cli.js" } }, "sha512-l04qNxpiA8rY5yXWckRPJ7Mk5MNerXuNymSFf+IdflfI5i8jgL1bpBNLuP6ijg7wgjdHc/KmTnCj2kT0SCntuA=="], - "@effect/opentelemetry": ["@effect/opentelemetry@4.0.0-beta.57", "", { "peerDependencies": { "@opentelemetry/api": "^1.9", "@opentelemetry/resources": "^2.0.0", "@opentelemetry/sdk-logs": ">=0.203.0 <0.300.0", "@opentelemetry/sdk-metrics": "^2.0.0", "@opentelemetry/sdk-trace-base": "^2.0.0", "@opentelemetry/sdk-trace-node": "^2.0.0", "@opentelemetry/sdk-trace-web": "^2.0.0", "@opentelemetry/semantic-conventions": "^1.33.0", "effect": "^4.0.0-beta.57" }, "optionalPeers": ["@opentelemetry/api", "@opentelemetry/resources", "@opentelemetry/sdk-logs", "@opentelemetry/sdk-metrics", "@opentelemetry/sdk-trace-base", "@opentelemetry/sdk-trace-node", "@opentelemetry/sdk-trace-web"] }, "sha512-gdjZPEP0QQg4qmI1vd+443kheeQZKytrjJIzCJncy6ZEpyk/SfrqeStLqLXdTRcms3IB0ls0vOV7KNq7YmBRVA=="], + "@effect/opentelemetry": ["@effect/opentelemetry@4.0.0-beta.65", "", { "peerDependencies": { "@opentelemetry/api": "^1.9", "@opentelemetry/api-logs": ">=0.203.0 <0.300.0", "@opentelemetry/resources": "^2.0.0", "@opentelemetry/sdk-logs": ">=0.203.0 <0.300.0", "@opentelemetry/sdk-metrics": "^2.0.0", "@opentelemetry/sdk-trace-base": "^2.0.0", "@opentelemetry/sdk-trace-node": "^2.0.0", "@opentelemetry/sdk-trace-web": "^2.0.0", "@opentelemetry/semantic-conventions": "^1.33.0", "effect": "^4.0.0-beta.65" }, "optionalPeers": ["@opentelemetry/api", "@opentelemetry/api-logs", "@opentelemetry/resources", "@opentelemetry/sdk-logs", "@opentelemetry/sdk-metrics", "@opentelemetry/sdk-trace-base", "@opentelemetry/sdk-trace-node", "@opentelemetry/sdk-trace-web"] }, "sha512-0CD2fSsXrDM7FP2WFkbGJO1DwMqWR3UKHh6oBDXPHAPA+RsJSKoh3pLQsbQfldLuKnhOy87Bv0v9r9IdrIHCQw=="], - "@effect/platform-node": ["@effect/platform-node@4.0.0-beta.57", "", { "dependencies": { "@effect/platform-node-shared": "^4.0.0-beta.57", "mime": "^4.1.0", "undici": "^8.0.2" }, "peerDependencies": { "effect": "^4.0.0-beta.57", "ioredis": "^5.7.0" } }, "sha512-la0xxPSAYOsY0d+uVxEBxok3jYB31iPQmIaZZRUj2SNWqcGGHJc6KorKtI8guqSLuv9FGZ255kBWXRbG6hMeeg=="], + "@effect/platform-node": ["@effect/platform-node@4.0.0-beta.65", "", { "dependencies": { "@effect/platform-node-shared": "^4.0.0-beta.65", "mime": "^4.1.0", "undici": "^8.0.2" }, "peerDependencies": { "effect": "^4.0.0-beta.65", "ioredis": "^5.7.0" } }, "sha512-QQy3KRcMwP0TngQdfQGl2u1zp03B7k7DuF5SNS8aZhD0dDBpKZpCwFad1ODY5qdY3ycPgMwBwKRRK7y/aw0C9w=="], "@effect/platform-node-shared": ["@effect/platform-node-shared@4.0.0-beta.46", "", { "dependencies": { "@types/ws": "^8.18.1", "ws": "^8.19.0" }, "peerDependencies": { "effect": "^4.0.0-beta.46" } }, "sha512-Yzci82XbZ1W3tuiownsJawrJZTGeTrTZKLD0uxdBWCBzlVyqDwoSwRwO5qh33DurJj9B7iS8MDf14fpGRBPNGQ=="], @@ -1560,23 +1591,23 @@ "@opentelemetry/semantic-conventions": ["@opentelemetry/semantic-conventions@1.40.0", "", {}, "sha512-cifvXDhcqMwwTlTK04GBNeIe7yyo28Mfby85QXFe1Yk8nmi36Ab/5UQwptOx84SsoGNRg+EVSjwzfSZMy6pmlw=="], - "@opentui/core": ["@opentui/core@0.2.6", "", { "dependencies": { "bun-ffi-structs": "0.2.2", "diff": "9.0.0", "marked": "17.0.1", "string-width": "7.2.0", "strip-ansi": "7.1.2", "yoga-layout": "3.2.1" }, "optionalDependencies": { "@opentui/core-darwin-arm64": "0.2.6", "@opentui/core-darwin-x64": "0.2.6", "@opentui/core-linux-arm64": "0.2.6", "@opentui/core-linux-x64": "0.2.6", "@opentui/core-win32-arm64": "0.2.6", "@opentui/core-win32-x64": "0.2.6" }, "peerDependencies": { "web-tree-sitter": "0.25.10" } }, "sha512-dBpMaWVM7wtW2/2TlGPrkPjg6gOL3MVU/5XXk+U1LDJB8L4q4NeYWVdzfAVNcEvgmuuCy/cVqdY2D4ei+e7MMg=="], + "@opentui/core": ["@opentui/core@0.2.10", "", { "dependencies": { "bun-ffi-structs": "0.2.2", "diff": "9.0.0", "marked": "17.0.1", "string-width": "7.2.0", "strip-ansi": "7.1.2", "yoga-layout": "3.2.1" }, "optionalDependencies": { "@opentui/core-darwin-arm64": "0.2.10", "@opentui/core-darwin-x64": "0.2.10", "@opentui/core-linux-arm64": "0.2.10", "@opentui/core-linux-x64": "0.2.10", "@opentui/core-win32-arm64": "0.2.10", "@opentui/core-win32-x64": "0.2.10" }, "peerDependencies": { "web-tree-sitter": "0.25.10" } }, "sha512-oviCtx0jYjc7F8X2b8+0IkQLg6WH47Nwl6CFeZo5dU0k6OpSbTbi07ZleObaiECAp+S1YLhAtVdgzHU7hBZlaw=="], - "@opentui/core-darwin-arm64": ["@opentui/core-darwin-arm64@0.2.6", "", { "os": "darwin", "cpu": "arm64" }, "sha512-hR5nsxNj+059utzenTCF0kealUlibON6fLuebFUCGM/5kJnqa+shIh0XbUDFm0+F47vqVUgZufBdUuieQZIbvQ=="], + "@opentui/core-darwin-arm64": ["@opentui/core-darwin-arm64@0.2.10", "", { "os": "darwin", "cpu": "arm64" }, "sha512-+lbDDj42Og+UtTZEwlHhGXichmOlkxSqn0J+Jqjat5/Tt5oZykj1NZjFIQ7ZSz4Miz7EmZwgYKE2CyOmmm9MoQ=="], - "@opentui/core-darwin-x64": ["@opentui/core-darwin-x64@0.2.6", "", { "os": "darwin", "cpu": "x64" }, "sha512-pJ/bH4WC/mbBaakM1YdH6TVo67jhy0KPd61bCz97w0I/PJGr8fmNKvhmMt/AwyFgOQi3FYZiEKLMpGdvUcSsrQ=="], + "@opentui/core-darwin-x64": ["@opentui/core-darwin-x64@0.2.10", "", { "os": "darwin", "cpu": "x64" }, "sha512-5iAoA0aqMWWAQ93nh8Bb0ipwt9h+tvEFc88+YO9St43uUJ+XrXcmMj3T8wtl6dSu/SN0UoDWNaUMHUmtykiPtg=="], - "@opentui/core-linux-arm64": ["@opentui/core-linux-arm64@0.2.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-9Pnd3kOxig8ii+/IqYheOPEgferylsQA0L6tKBnHQ9jRlCJOcu0Rv65Jepueh212vevdV9DzPURJnhejG06J6g=="], + "@opentui/core-linux-arm64": ["@opentui/core-linux-arm64@0.2.10", "", { "os": "linux", "cpu": "arm64" }, "sha512-EnrkxgH5K76Oi/Br1UHPZblXG5P60snmtySfnxuVaeECNZrbTkV6BV/A0WoBeWshJweGbx1D+eTF+sEEjQCi8w=="], - "@opentui/core-linux-x64": ["@opentui/core-linux-x64@0.2.6", "", { "os": "linux", "cpu": "x64" }, "sha512-458Mx9tBzEPzfft8cSt5ZaIpEepoxBXBOL6AUVmDTKWaZ3uouraPcEKraGAyvOTDQp2XDI3R8c/2GdaR77FaUQ=="], + "@opentui/core-linux-x64": ["@opentui/core-linux-x64@0.2.10", "", { "os": "linux", "cpu": "x64" }, "sha512-fI+r3kCPqIxsWwPVGpKUQy4zHK8y+jkDRCwa3UbaUy48RQ44jMuf2RhVhmi4xmCvSc8UPJBbYsw1tLuh9kmXjg=="], - "@opentui/core-win32-arm64": ["@opentui/core-win32-arm64@0.2.6", "", { "os": "win32", "cpu": "arm64" }, "sha512-BDUrdrT1RCcVnQoHJmUut4y811jDBAEtc6GJFB4Gs265Be8SrTjVCus6p2fSQ7j9sZQ1OcjO+5+4NkheSZICDQ=="], + "@opentui/core-win32-arm64": ["@opentui/core-win32-arm64@0.2.10", "", { "os": "win32", "cpu": "arm64" }, "sha512-8F4z2hIRgkVWcr6CMVeJ9N4+1rmURPt2Pq2GBPko8ch6rxHR+a//KD1MfphyuLTHBS1tJ4vfZSWSoiaESImtrA=="], - "@opentui/core-win32-x64": ["@opentui/core-win32-x64@0.2.6", "", { "os": "win32", "cpu": "x64" }, "sha512-SUYAzRJ9TSoD2Qt8kn6FJz6dbTrFEPVig5mScB4zFGgGQO/Bbod2/Q31vLS/IQrX+FDb67WaErD+kuMCnMPPLA=="], + "@opentui/core-win32-x64": ["@opentui/core-win32-x64@0.2.10", "", { "os": "win32", "cpu": "x64" }, "sha512-Ki+qNBlIFW5K2wcG/RHrlPp7yEQKXeiNX3mlje25iwX62Ac5w391HBpOmUjbPoq20McPyDRnhbLfbXQSPtickg=="], - "@opentui/keymap": ["@opentui/keymap@0.2.6", "", { "dependencies": { "@opentui/core": "0.2.6" }, "peerDependencies": { "@opentui/react": "0.2.6", "@opentui/solid": "0.2.6", "react": ">=19.2.0", "solid-js": "1.9.12" }, "optionalPeers": ["@opentui/react", "@opentui/solid", "react", "solid-js"] }, "sha512-+6OYuedrFCKVo4ryGFNwws++2VOmPcXU3PwpY0mP47gYQY2nvQ+etWIs2Y7r5eMIqUfxVCldkKsrzcEcA4tb/A=="], + "@opentui/keymap": ["@opentui/keymap@0.2.10", "", { "dependencies": { "@opentui/core": "0.2.10" }, "peerDependencies": { "@opentui/react": "0.2.10", "@opentui/solid": "0.2.10", "react": ">=19.2.0", "solid-js": "1.9.12" }, "optionalPeers": ["@opentui/react", "@opentui/solid", "react", "solid-js"] }, "sha512-80fU3Lr/98sNIpVYd8PApAeQw8A8D9BemyOGi6jGvTQCl0rxKgvaVBviDRGKxl1INTVjZy9By8UPncc2KJOuWQ=="], - "@opentui/solid": ["@opentui/solid@0.2.6", "", { "dependencies": { "@babel/core": "7.28.0", "@babel/preset-typescript": "7.27.1", "@opentui/core": "0.2.6", "babel-plugin-module-resolver": "5.0.2", "babel-preset-solid": "1.9.12", "entities": "7.0.1", "s-js": "^0.4.9" }, "peerDependencies": { "solid-js": "1.9.12" } }, "sha512-2y225WlOGi/fCaajkxBmLyVW8Cr+OmhowHdvrYcz5w2kBD15sKbJLIYu1G9DxceirT1uIyasGy2TGzRRcVkTDg=="], + "@opentui/solid": ["@opentui/solid@0.2.10", "", { "dependencies": { "@babel/core": "7.28.0", "@babel/preset-typescript": "7.27.1", "@opentui/core": "0.2.10", "babel-plugin-module-resolver": "5.0.2", "babel-preset-solid": "1.9.12", "entities": "7.0.1", "s-js": "^0.4.9" }, "peerDependencies": { "solid-js": "1.9.12" } }, "sha512-+4/MB90yIQiPwg8Y4wY092yva9BvRTsJeeeEO3e2H7P8k8zxYk4G9bzuhqYLxA9mTVQ+zVDlrmFoPQhT7vpIRw=="], "@oslojs/asn1": ["@oslojs/asn1@1.0.0", "", { "dependencies": { "@oslojs/binary": "1.0.0" } }, "sha512-zw/wn0sj0j0QKbIXfIlnEcTviaCzYOY3V5rAyjR6YtOByFtJiT574+8p9Wlach0lZH9fddD4yb9laEAIl4vXQA=="], @@ -2890,7 +2921,7 @@ "ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="], - "effect": ["effect@4.0.0-beta.59", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "fast-check": "^4.6.0", "find-my-way-ts": "^0.1.6", "ini": "^6.0.0", "kubernetes-types": "^1.30.0", "msgpackr": "^1.11.9", "multipasta": "^0.2.7", "toml": "^4.1.1", "uuid": "^13.0.0", "yaml": "^2.8.3" } }, "sha512-xyUDLeHSe8d6lWGOvR6Fgn2HL6gYeTZ/S4Jzk9uc4ZUxMPPsNZlNXrvk0C7/utQFzeX7uAWcVnG2BjbA0SRoAA=="], + "effect": ["effect@4.0.0-beta.65", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "fast-check": "^4.6.0", "find-my-way-ts": "^0.1.6", "ini": "^6.0.0", "kubernetes-types": "^1.30.0", "msgpackr": "^1.11.9", "multipasta": "^0.2.7", "toml": "^4.1.1", "uuid": "^13.0.0", "yaml": "^2.8.3" } }, "sha512-QYKvQPAj3CmtsvWkHQww15wX4KG2gNsszDWEcOO5sZCMknp66u6Si/Opmt3wwWCwsyvRmDAdIg+JIz5qzbbFIw=="], "electron-to-chromium": ["electron-to-chromium@1.5.340", "", {}, "sha512-908qahOGocRMinT2nM3ajCEM99H4iPdv84eagPP3FfZy/1ZGeOy2CZYzjhms81ckOPCXPlW7LkY4XpxD8r1DrA=="], @@ -3194,7 +3225,7 @@ "html-void-elements": ["html-void-elements@3.0.0", "", {}, "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg=="], - "htmlparser2": ["htmlparser2@10.1.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.2.2", "entities": "^7.0.1" } }, "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ=="], + "htmlparser2": ["htmlparser2@8.0.2", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.0.1", "entities": "^4.4.0" } }, "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA=="], "http-cache-semantics": ["http-cache-semantics@4.2.0", "", {}, "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ=="], @@ -4558,8 +4589,6 @@ "@antfu/install-pkg/package-manager-detector": ["package-manager-detector@1.6.0", "", {}, "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA=="], - "@anthropic-ai/sdk/@types/node": ["@types/node@24.12.2", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g=="], - "@aws-crypto/sha1-browser/@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="], "@aws-crypto/sha256-browser/@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="], @@ -4622,8 +4651,6 @@ "@kilocode/kilo-indexing/glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="], - "@manypkg/find-root/@types/node": ["@types/node@24.12.2", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g=="], - "@manypkg/find-root/find-up": ["find-up@4.1.0", "", { "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" } }, "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw=="], "@manypkg/find-root/fs-extra": ["fs-extra@8.1.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g=="], @@ -4678,6 +4705,8 @@ "@openauthjs/openauth/jose": ["jose@5.9.6", "", {}, "sha512-AMlnetc9+CV9asI19zHmrgS/WYsWUwCn2R7RzlbJWD7F9eWYUTGyBmU9o6PxngtLGOiDGPRu+Uc4fhKzbpteZQ=="], + "@opencode-ai/core/@aws-sdk/credential-providers": ["@aws-sdk/credential-providers@3.993.0", "", { "dependencies": { "@aws-sdk/client-cognito-identity": "3.993.0", "@aws-sdk/core": "^3.973.11", "@aws-sdk/credential-provider-cognito-identity": "^3.972.3", "@aws-sdk/credential-provider-env": "^3.972.9", "@aws-sdk/credential-provider-http": "^3.972.11", "@aws-sdk/credential-provider-ini": "^3.972.9", "@aws-sdk/credential-provider-login": "^3.972.9", "@aws-sdk/credential-provider-node": "^3.972.10", "@aws-sdk/credential-provider-process": "^3.972.9", "@aws-sdk/credential-provider-sso": "^3.972.9", "@aws-sdk/credential-provider-web-identity": "^3.972.9", "@aws-sdk/nested-clients": "3.993.0", "@aws-sdk/types": "^3.973.1", "@smithy/config-resolver": "^4.4.6", "@smithy/core": "^3.23.2", "@smithy/credential-provider-imds": "^4.2.8", "@smithy/node-config-provider": "^4.3.8", "@smithy/property-provider": "^4.2.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-1M/nukgPSLqe9krzOKHnE8OylUaKAiokAV3xRLdeExVHcRE7WG5uzCTKWTj1imKvPjDqXq/FWhlbbdWIn7xIwA=="], + "@opencode-ai/storybook/@storybook/addon-a11y": ["@storybook/addon-a11y@10.3.5", "", { "dependencies": { "@storybook/global": "^5.0.0", "axe-core": "^4.2.0" }, "peerDependencies": { "storybook": "^10.3.5" } }, "sha512-5k6lpgfIeLxvNhE8v3wEzdiu73ONKjF4gmH1AHvfqYd8kIVzQJai0KCDxgvqNncXHQhIWkaf1fg6+9hKaYJyaw=="], "@opencode-ai/storybook/@storybook/addon-docs": ["@storybook/addon-docs@10.3.5", "", { "dependencies": { "@mdx-js/react": "^3.0.0", "@storybook/csf-plugin": "10.3.5", "@storybook/icons": "^2.0.1", "@storybook/react-dom-shim": "10.3.5", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "ts-dedent": "^2.0.0" }, "peerDependencies": { "storybook": "^10.3.5" } }, "sha512-WuHbxia/o5TX4Rg/IFD0641K5qId/Nk0dxhmAUNoFs5L0+yfZUwh65XOBbzXqrkYmYmcVID4v7cgDRmzstQNkA=="], @@ -4764,30 +4793,6 @@ "@textlint/linter-formatter/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - "@types/cacache/@types/node": ["@types/node@24.12.2", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g=="], - - "@types/cross-spawn/@types/node": ["@types/node@24.12.2", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g=="], - - "@types/mssql/@types/node": ["@types/node@24.12.2", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g=="], - - "@types/node-fetch/@types/node": ["@types/node@24.12.2", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g=="], - - "@types/npm-registry-fetch/@types/node": ["@types/node@24.12.2", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g=="], - - "@types/npmcli__arborist/@types/node": ["@types/node@24.12.2", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g=="], - - "@types/npmlog/@types/node": ["@types/node@24.12.2", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g=="], - - "@types/pacote/@types/node": ["@types/node@24.12.2", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g=="], - - "@types/qrcode/@types/node": ["@types/node@24.12.2", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g=="], - - "@types/readable-stream/@types/node": ["@types/node@24.12.2", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g=="], - - "@types/ssri/@types/node": ["@types/node@24.12.2", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g=="], - - "@types/ws/@types/node": ["@types/node@24.12.2", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g=="], - "@typescript-eslint/visitor-keys/eslint-visitor-keys": ["eslint-visitor-keys@5.0.1", "", {}, "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA=="], "@vitest/expect/@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], @@ -4826,8 +4831,6 @@ "ai-gateway-provider/@openrouter/ai-sdk-provider": ["@openrouter/ai-sdk-provider@2.5.1", "", { "peerDependencies": { "ai": "^6.0.0", "zod": "^3.25.0 || ^4.0.0" } }, "sha512-r1fJL1Cb3gQDa2MpWH/sfx1BsEW0uzlRriJM6eihaKqbtKDmZoBisF32VcVaQYassighX7NGCkF68EsrZA43uQ=="], - "apache-arrow/@types/node": ["@types/node@24.12.2", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g=="], - "archiver-utils/glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="], "archiver-utils/is-stream": ["is-stream@2.0.1", "", {}, "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="], @@ -4862,8 +4865,6 @@ "buffer/ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="], - "bun-types/@types/node": ["@types/node@24.12.2", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g=="], - "c12/chokidar": ["chokidar@5.0.0", "", { "dependencies": { "readdirp": "^5.0.0" } }, "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw=="], "c12/dotenv": ["dotenv@17.4.2", "", {}, "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw=="], @@ -4876,6 +4877,8 @@ "chalk-template/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], + "cheerio/htmlparser2": ["htmlparser2@10.1.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.2.2", "entities": "^7.0.1" } }, "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ=="], + "cheerio/undici": ["undici@7.25.0", "", {}, "sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ=="], "clean-stack/escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="], @@ -4956,6 +4959,8 @@ "gray-matter/js-yaml": ["js-yaml@3.14.2", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg=="], + "htmlparser2/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], + "import-fresh/resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="], "isomorphic-git/ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="], @@ -5044,10 +5049,6 @@ "openid-client/lru-cache": ["lru-cache@6.0.0", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="], - "opentui-spinner/@opentui/core": ["@opentui/core@0.2.2", "", { "dependencies": { "bun-ffi-structs": "0.2.2", "diff": "9.0.0", "marked": "17.0.1", "string-width": "7.2.0", "strip-ansi": "7.1.2", "yoga-layout": "3.2.1" }, "optionalDependencies": { "@opentui/core-darwin-arm64": "0.2.2", "@opentui/core-darwin-x64": "0.2.2", "@opentui/core-linux-arm64": "0.2.2", "@opentui/core-linux-x64": "0.2.2", "@opentui/core-win32-arm64": "0.2.2", "@opentui/core-win32-x64": "0.2.2" }, "peerDependencies": { "web-tree-sitter": "0.25.10" } }, "sha512-wxg1CD58SVrowu+WgbhZNi3UP/wWxPio2Kj2IeTjomoIE+6EXLxR8eCCxHYVuQUd9E4fknrKkY5HmiSsp6oPow=="], - - "opentui-spinner/@opentui/solid": ["@opentui/solid@0.2.2", "", { "dependencies": { "@babel/core": "7.28.0", "@babel/preset-typescript": "7.27.1", "@opentui/core": "0.2.2", "babel-plugin-module-resolver": "5.0.2", "babel-preset-solid": "1.9.12", "entities": "7.0.1", "s-js": "^0.4.9" }, "peerDependencies": { "solid-js": "1.9.12" } }, "sha512-ZBVfCoVAhcUGQWPAWOTdzuVldMaRkuPpCu4U1VZCqmIw9DtbCuiVr0WnDocDxKhJLbTu8bl3qEWtVCf6lTSi3w=="], - "ora/cli-spinners": ["cli-spinners@2.9.2", "", {}, "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg=="], "ora/log-symbols": ["log-symbols@6.0.0", "", { "dependencies": { "chalk": "^5.3.0", "is-unicode-supported": "^1.3.0" } }, "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw=="], @@ -5078,8 +5079,6 @@ "pretty-format/ansi-styles": ["ansi-styles@5.2.0", "", {}, "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="], - "protobufjs/@types/node": ["@types/node@24.12.2", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g=="], - "proxy-addr/ipaddr.js": ["ipaddr.js@1.9.1", "", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="], "qrcode/yargs": ["yargs@15.4.1", "", { "dependencies": { "cliui": "^6.0.0", "decamelize": "^1.2.0", "find-up": "^4.1.0", "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", "string-width": "^4.2.0", "which-module": "^2.0.0", "y18n": "^4.0.0", "yargs-parser": "^18.1.2" } }, "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A=="], @@ -5150,8 +5149,6 @@ "tar-fs/tar-stream": ["tar-stream@2.2.0", "", { "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", "fs-constants": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.1.1" } }, "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ=="], - "tedious/@types/node": ["@types/node@24.12.2", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g=="], - "tedious/iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], "tedious/sprintf-js": ["sprintf-js@1.1.3", "", {}, "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA=="], @@ -5234,8 +5231,6 @@ "@morphllm/morphsdk/ai/@ai-sdk/gateway": ["@ai-sdk/gateway@3.0.95", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.23", "@vercel/oidc": "3.1.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-ZmUNNbZl3V42xwQzPaNUi+s8eqR2lnrxf0bvB6YbLXpLjHYv0k2Y78t12cNOfY0bxGeuVVTLyk856uLuQIuXEQ=="], - "@morphllm/morphsdk/openai/@types/node": ["@types/node@24.12.2", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g=="], - "@morphllm/morphsdk/openai/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], "@octokit/core/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@24.2.0", "", {}, "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg=="], @@ -5270,6 +5265,10 @@ "@octokit/rest/@octokit/core/before-after-hook": ["before-after-hook@4.0.0", "", {}, "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ=="], + "@opencode-ai/core/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity": ["@aws-sdk/client-cognito-identity@3.993.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.11", "@aws-sdk/credential-provider-node": "^3.972.10", "@aws-sdk/middleware-host-header": "^3.972.3", "@aws-sdk/middleware-logger": "^3.972.3", "@aws-sdk/middleware-recursion-detection": "^3.972.3", "@aws-sdk/middleware-user-agent": "^3.972.11", "@aws-sdk/region-config-resolver": "^3.972.3", "@aws-sdk/types": "^3.973.1", "@aws-sdk/util-endpoints": "3.993.0", "@aws-sdk/util-user-agent-browser": "^3.972.3", "@aws-sdk/util-user-agent-node": "^3.972.9", "@smithy/config-resolver": "^4.4.6", "@smithy/core": "^3.23.2", "@smithy/fetch-http-handler": "^5.3.9", "@smithy/hash-node": "^4.2.8", "@smithy/invalid-dependency": "^4.2.8", "@smithy/middleware-content-length": "^4.2.8", "@smithy/middleware-endpoint": "^4.4.16", "@smithy/middleware-retry": "^4.4.33", "@smithy/middleware-serde": "^4.2.9", "@smithy/middleware-stack": "^4.2.8", "@smithy/node-config-provider": "^4.3.8", "@smithy/node-http-handler": "^4.4.10", "@smithy/protocol-http": "^5.3.8", "@smithy/smithy-client": "^4.11.5", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.32", "@smithy/util-defaults-mode-node": "^4.2.35", "@smithy/util-endpoints": "^3.2.8", "@smithy/util-middleware": "^4.2.8", "@smithy/util-retry": "^4.2.8", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-7Ne3Yk/bgQPVebAkv7W+RfhiwTRSbfER9BtbhOa2w/+dIr902LrJf6vrZlxiqaJbGj2ALx8M+ZK1YIHVxSwu9A=="], + + "@opencode-ai/core/@aws-sdk/credential-providers/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.993.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.11", "@aws-sdk/middleware-host-header": "^3.972.3", "@aws-sdk/middleware-logger": "^3.972.3", "@aws-sdk/middleware-recursion-detection": "^3.972.3", "@aws-sdk/middleware-user-agent": "^3.972.11", "@aws-sdk/region-config-resolver": "^3.972.3", "@aws-sdk/types": "^3.973.1", "@aws-sdk/util-endpoints": "3.993.0", "@aws-sdk/util-user-agent-browser": "^3.972.3", "@aws-sdk/util-user-agent-node": "^3.972.9", "@smithy/config-resolver": "^4.4.6", "@smithy/core": "^3.23.2", "@smithy/fetch-http-handler": "^5.3.9", "@smithy/hash-node": "^4.2.8", "@smithy/invalid-dependency": "^4.2.8", "@smithy/middleware-content-length": "^4.2.8", "@smithy/middleware-endpoint": "^4.4.16", "@smithy/middleware-retry": "^4.4.33", "@smithy/middleware-serde": "^4.2.9", "@smithy/middleware-stack": "^4.2.8", "@smithy/node-config-provider": "^4.3.8", "@smithy/node-http-handler": "^4.4.10", "@smithy/protocol-http": "^5.3.8", "@smithy/smithy-client": "^4.11.5", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.32", "@smithy/util-defaults-mode-node": "^4.2.35", "@smithy/util-endpoints": "^3.2.8", "@smithy/util-middleware": "^4.2.8", "@smithy/util-retry": "^4.2.8", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-iOq86f2H67924kQUIPOAvlmMaOAvOLoDOIb66I2YqSUpMYB6ufiuJW3RlREgskxv86S5qKzMnfy/X6CqMjK6XQ=="], + "@opencode-ai/storybook/@storybook/addon-docs/@storybook/csf-plugin": ["@storybook/csf-plugin@10.3.5", "", { "dependencies": { "unplugin": "^2.3.5" }, "peerDependencies": { "esbuild": "*", "rollup": "*", "storybook": "^10.3.5", "vite": "*", "webpack": "*" }, "optionalPeers": ["esbuild", "rollup", "vite", "webpack"] }, "sha512-qlEzNKxOjq86pvrbuMwiGD/bylnsXk1dg7ve0j77YFjEEchqtl7qTlrXvFdNaLA89GhW6D/EV6eOCu/eobPDgw=="], "@opencode-ai/storybook/@storybook/addon-docs/@storybook/react-dom-shim": ["@storybook/react-dom-shim@10.3.5", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "storybook": "^10.3.5" } }, "sha512-Gw8R7XZm0zSUH0XAuxlQJhmizsLzyD6x00KOlP6l7oW9eQHXGfxg3seNDG3WrSAcW07iP1/P422kuiriQlOv7g=="], @@ -5528,8 +5527,6 @@ "jszip/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="], - "kilo-code/openai/@types/node": ["@types/node@24.12.2", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g=="], - "lazystream/readable-stream/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="], "lazystream/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="], @@ -5560,20 +5557,6 @@ "opencontrol/@modelcontextprotocol/sdk/zod-to-json-schema": ["zod-to-json-schema@3.25.2", "", { "peerDependencies": { "zod": "^3.25.28 || ^4" } }, "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA=="], - "opentui-spinner/@opentui/core/@opentui/core-darwin-arm64": ["@opentui/core-darwin-arm64@0.2.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-tY5n3ZRQx+b0kyhQJJLsyJMeZ+0w4FV37YZc/Qqv3qvOqE9kZPw/7adR77FYwWDm/7fax94mLMrR8Y5bKUkDmw=="], - - "opentui-spinner/@opentui/core/@opentui/core-darwin-x64": ["@opentui/core-darwin-x64@0.2.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-W/R7OnqY30FXcTG0tiP2JkQFmgtYbIte5afQ5PC12TliRoee1RqG3iCG6kY1jxW+3Vg6jge88uiSjUEDpeV2gA=="], - - "opentui-spinner/@opentui/core/@opentui/core-linux-arm64": ["@opentui/core-linux-arm64@0.2.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-1pzTYFEZauYuw6AGycw2TYGtAlZVGjuUtSdxH1fP51kBPS3oVWduUY2j7GKREz3SU5NulvO2Wc6HWsm3feMqwQ=="], - - "opentui-spinner/@opentui/core/@opentui/core-linux-x64": ["@opentui/core-linux-x64@0.2.2", "", { "os": "linux", "cpu": "x64" }, "sha512-ucVwUtUYeOYGVFPBLbPoxzbrPdhD0PDyKNQ2X4n1AJ9jlQX4gqBZRcXMEF8hiXDjFxsikZwef7De0ciCcWvAMg=="], - - "opentui-spinner/@opentui/core/@opentui/core-win32-arm64": ["@opentui/core-win32-arm64@0.2.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-MPhYdJNdxmC5Bqsq6sis/+VkjRgkEjm+bQ1Tl++NSKLuiTU32Re0ImcZlgHbe+LZtZoGMZHVSgZlkGd3oYXO2g=="], - - "opentui-spinner/@opentui/core/@opentui/core-win32-x64": ["@opentui/core-win32-x64@0.2.2", "", { "os": "win32", "cpu": "x64" }, "sha512-19BroLfn2h0RDYfJS5o96Fc8kYCDhRBcseIXtHIkoKIsKMxx62KiDLo/byVye6rp+yQRRB7Xkd2uWqsbdiWo9w=="], - - "opentui-spinner/@opentui/solid/@babel/core": ["@babel/core@7.28.0", "", { "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.0", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.27.3", "@babel/helpers": "^7.27.6", "@babel/parser": "^7.28.0", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.0", "@babel/types": "^7.28.0", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ=="], - "ora/log-symbols/is-unicode-supported": ["is-unicode-supported@1.3.0", "", {}, "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ=="], "p-locate/p-limit/yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="], @@ -5650,6 +5633,10 @@ "@octokit/rest/@octokit/core/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="], + "@opencode-ai/core/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.993.0", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@smithy/util-endpoints": "^3.2.8", "tslib": "^2.6.2" } }, "sha512-j6vioBeRZ4eHX4SWGvGPpwGg/xSOcK7f1GL0VM+rdf3ZFTIsUEhCFmD78B+5r2PgztcECSzEfvHQX01k8dPQPw=="], + + "@opencode-ai/core/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.993.0", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@smithy/util-endpoints": "^3.2.8", "tslib": "^2.6.2" } }, "sha512-j6vioBeRZ4eHX4SWGvGPpwGg/xSOcK7f1GL0VM+rdf3ZFTIsUEhCFmD78B+5r2PgztcECSzEfvHQX01k8dPQPw=="], + "@opencode-ai/storybook/storybook/@vitest/expect/@vitest/utils": ["@vitest/utils@3.2.4", "", { "dependencies": { "@vitest/pretty-format": "3.2.4", "loupe": "^3.1.4", "tinyrainbow": "^2.0.0" } }, "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA=="], "@opencode-ai/storybook/storybook/@vitest/expect/chai": ["chai@5.3.3", "", { "dependencies": { "assertion-error": "^2.0.1", "check-error": "^2.1.1", "deep-eql": "^5.0.1", "loupe": "^3.1.0", "pathval": "^2.0.0" } }, "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw=="], @@ -5798,8 +5785,6 @@ "mocha/yargs/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - "opentui-spinner/@opentui/solid/@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], - "pkg-conf/find-up/locate-path/p-locate": ["p-locate@6.0.0", "", { "dependencies": { "p-limit": "^4.0.0" } }, "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw=="], "pkg-up/find-up/locate-path/p-locate": ["p-locate@3.0.0", "", { "dependencies": { "p-limit": "^2.0.0" } }, "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ=="], diff --git a/bunfig.toml b/bunfig.toml index 25923129a8c..6b1e40c73f5 100644 --- a/bunfig.toml +++ b/bunfig.toml @@ -1,8 +1,8 @@ [install] exact = true +# Keep Kilo's longer supply-chain quarantine while allowing packages that must track coordinated releases. minimumReleaseAge = 410520 # seconds (~4.75 days / ~114 hours) -minimumReleaseAgeExcludes = ["mermaid", "@mermaid-js/parser"] +minimumReleaseAgeExcludes = ["mermaid", "@mermaid-js/parser", "@opentui/core", "@opentui/core-darwin-arm64", "@opentui/core-darwin-x64", "@opentui/core-linux-arm64", "@opentui/core-linux-x64", "@opentui/core-win32-arm64", "@opentui/core-win32-x64", "@opentui/keymap", "@opentui/solid"] [test] root = "./do-not-run-tests-from-root" - diff --git a/nix/hashes.json b/nix/hashes.json index 0ce17661663..5f626f6f5c6 100644 --- a/nix/hashes.json +++ b/nix/hashes.json @@ -1,8 +1,8 @@ { "nodeModules": { - "x86_64-linux": "sha256-+RfFK1YCo3xeDGebzRXWvXW3cFiyLZUq3VjQTFYYMzc=", - "aarch64-linux": "sha256-uJEMZroamhTbRusWd2+3kqjyYXh50wJLLDFjix1LVNM=", - "aarch64-darwin": "sha256-dnUvPkYYPTxkeKrlW066YJHAMG1HxWxSQV2PpFlBgog=", - "x86_64-darwin": "sha256-nr5xzyjG9kQRhTXjfezqICF7TzBZ6xmhHCcs4DNEVoQ=" + "x86_64-linux": "sha256-j1zK7Z2RIrixppFm67ErQmZ1bpVx8sJ4WHFCMxt4pek=", + "aarch64-linux": "sha256-t+uyV8wFsazjlCD1gDa/R8z7muvTxpdukRy5YVyNABg=", + "aarch64-darwin": "sha256-fmOu2cv1LKx519hWp/8Gk0UHZpY2zHAjOjT2wUOl1uo=", + "x86_64-darwin": "sha256-MT3dQwH+x9iORIejj6h7R/Of1HQpVY7JIVMZocDvw3s=" } } diff --git a/package.json b/package.json index 98da7e85c55..96965ca3635 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "AI-powered development tool", "private": true, "type": "module", - "packageManager": "bun@1.3.14", + "packageManager": "bun@1.3.13", "scripts": { "dev": "bun run --cwd packages/opencode --conditions=browser src/index.ts", "dev:storybook": "bun --cwd packages/storybook storybook", @@ -25,15 +25,15 @@ "packages/sdk/js" ], "catalog": { - "@effect/opentelemetry": "4.0.0-beta.57", - "@effect/platform-node": "4.0.0-beta.57", + "@effect/opentelemetry": "4.0.0-beta.65", + "@effect/platform-node": "4.0.0-beta.65", "@npmcli/arborist": "9.4.0", "@types/bun": "1.3.14", "@types/cross-spawn": "6.0.6", "@octokit/rest": "22.0.0", "@hono/zod-validator": "0.4.2", - "@opentui/core": "0.2.6", - "@opentui/solid": "0.2.6", + "@opentui/core": "0.2.10", + "@opentui/solid": "0.2.10", "ulid": "3.0.1", "@kobalte/core": "0.13.11", "@types/luxon": "3.7.1", @@ -51,7 +51,7 @@ "dompurify": "3.4.2", "drizzle-kit": "1.0.0-beta.19-d95b7a4", "drizzle-orm": "1.0.0-beta.19-d95b7a4", - "effect": "4.0.0-beta.59", + "effect": "4.0.0-beta.65", "ai": "6.0.168", "cross-spawn": "7.0.6", "hono": "4.12.12", @@ -78,7 +78,7 @@ "solid-js": "1.9.12", "vite-plugin-solid": "2.11.10", "@lydell/node-pty": "1.2.0-beta.10", - "@opentui/keymap": "0.2.6" + "@opentui/keymap": "0.2.10" } }, "devDependencies": { @@ -143,7 +143,8 @@ "happy-dom": ">=20.8.9", "@opentui/core": "catalog:", "@opentui/solid": "catalog:", - "solid-js": "catalog:" + "solid-js": "catalog:", + "@opentui/keymap": "catalog:" }, "patchedDependencies": { "@npmcli/agent@4.0.0": "patches/@npmcli%2Fagent@4.0.0.patch", @@ -152,6 +153,6 @@ "solid-js@1.9.10": "patches/solid-js@1.9.10.patch", "mammoth@1.12.0": "patches/mammoth@1.12.0.patch" }, - "version": "7.3.41", + "version": "7.3.42", "peerDependencies": {} } diff --git a/packages/core/package.json b/packages/core/package.json index 2ba968c7496..5c913f0b260 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/package.json", - "version": "7.3.41", + "version": "7.3.42", "name": "@opencode-ai/core", "type": "module", "license": "MIT", @@ -26,6 +26,7 @@ "@types/semver": "catalog:" }, "dependencies": { + "@kilocode/kilo-gateway": "workspace:*", "@effect/opentelemetry": "catalog:", "@effect/platform-node": "catalog:", "@npmcli/arborist": "9.4.0", @@ -43,7 +44,34 @@ "rotating-file-stream": "3.2.9", "semver": "^7.6.3", "xdg-basedir": "5.1.0", - "zod": "catalog:" + "zod": "catalog:", + "@ai-sdk/alibaba": "1.0.17", + "@ai-sdk/amazon-bedrock": "4.0.96", + "@ai-sdk/anthropic": "3.0.71", + "@ai-sdk/azure": "3.0.49", + "@ai-sdk/cerebras": "2.0.41", + "@ai-sdk/cohere": "3.0.27", + "@ai-sdk/deepinfra": "2.0.41", + "@ai-sdk/gateway": "3.0.104", + "@ai-sdk/google": "3.0.63", + "@ai-sdk/google-vertex": "4.0.112", + "@ai-sdk/groq": "3.0.31", + "@ai-sdk/mistral": "3.0.27", + "@ai-sdk/openai": "3.0.53", + "@ai-sdk/openai-compatible": "2.0.41", + "@ai-sdk/perplexity": "3.0.26", + "@ai-sdk/provider": "3.0.8", + "@ai-sdk/provider-utils": "4.0.23", + "@ai-sdk/togetherai": "2.0.41", + "@ai-sdk/vercel": "2.0.39", + "@ai-sdk/xai": "3.0.82", + "@aws-sdk/credential-providers": "3.993.0", + "@openrouter/ai-sdk-provider": "2.8.1", + "ai-gateway-provider": "3.1.2", + "gitlab-ai-provider": "6.6.0", + "google-auth-library": "10.5.0", + "immer": "11.1.4", + "venice-ai-sdk-provider": "2.0.1" }, "overrides": { "drizzle-orm": "catalog:" diff --git a/packages/core/src/aisdk.ts b/packages/core/src/aisdk.ts new file mode 100644 index 00000000000..5fa2294309c --- /dev/null +++ b/packages/core/src/aisdk.ts @@ -0,0 +1,172 @@ +export * as AISDK from "./aisdk" + +import type { LanguageModelV3 } from "@ai-sdk/provider" +import { Cause, Context, Effect, Layer, Schema } from "effect" +import { ModelV2 } from "./model" +import { PluginV2 } from "./plugin" +import { ProviderV2 } from "./provider" + +type SDK = any + +function wrapSSE(res: Response, ms: number, ctl: AbortController) { + if (typeof ms !== "number" || ms <= 0) return res + if (!res.body) return res + if (!res.headers.get("content-type")?.includes("text/event-stream")) return res + + const reader = res.body.getReader() + const body = new ReadableStream({ + async pull(ctrl) { + const part = await new Promise>>((resolve, reject) => { + const id = setTimeout(() => { + const err = new Error("SSE read timed out") + ctl.abort(err) + void reader.cancel(err) + reject(err) + }, ms) + + reader.read().then( + (part) => { + clearTimeout(id) + resolve(part) + }, + (err) => { + clearTimeout(id) + reject(err) + }, + ) + }) + + if (part.done) { + ctrl.close() + return + } + + ctrl.enqueue(part.value) + }, + async cancel(reason) { + ctl.abort(reason) + await reader.cancel(reason) + }, + }) + + return new Response(body, { + headers: new Headers(res.headers), + status: res.status, + statusText: res.statusText, + }) +} + +function prepareOptions(model: ModelV2.Info, pkg: string) { + const options: Record = { name: model.providerID, ...model.options.aisdk.provider } + if (model.endpoint.type === "aisdk" && model.endpoint.url) options.baseURL = model.endpoint.url + + const customFetch = options.fetch + const chunkTimeout = options.chunkTimeout + delete options.chunkTimeout + options.fetch = async (input: Parameters[0], init?: RequestInit) => { + const opts = { ...(init ?? {}) } + const signals = [ + opts.signal, + typeof chunkTimeout === "number" && chunkTimeout > 0 ? new AbortController() : undefined, + options.timeout !== undefined && options.timeout !== null && options.timeout !== false + ? AbortSignal.timeout(options.timeout) + : undefined, + ].filter((item): item is AbortSignal | AbortController => Boolean(item)) + const chunkAbortCtl = signals.find((item): item is AbortController => item instanceof AbortController) + const abortSignals = signals.map((item) => (item instanceof AbortController ? item.signal : item)) + if (abortSignals.length === 1) opts.signal = abortSignals[0] + if (abortSignals.length > 1) opts.signal = AbortSignal.any(abortSignals) + + if ((pkg === "@ai-sdk/openai" || pkg === "@ai-sdk/azure") && opts.body && opts.method === "POST") { + const body = JSON.parse(opts.body as string) + if (body.store !== true && Array.isArray(body.input)) { + for (const item of body.input) { + if ("id" in item) delete item.id + } + opts.body = JSON.stringify(body) + } + } + + const res = await (typeof customFetch === "function" ? customFetch : fetch)(input, { + ...opts, + timeout: false, + }) + if (!chunkAbortCtl || typeof chunkTimeout !== "number") return res + return wrapSSE(res, chunkTimeout, chunkAbortCtl) + } + + return options +} + +export class InitError extends Schema.TaggedErrorClass()("AISDK.InitError", { + providerID: ProviderV2.ID, + cause: Schema.Defect, +}) {} + +function initError(providerID: ProviderV2.ID) { + return Effect.catchCause((cause) => Effect.fail(new InitError({ providerID, cause: Cause.squash(cause) }))) +} + +export interface Interface { + readonly language: (model: ModelV2.Info) => Effect.Effect +} + +export class Service extends Context.Service()("@opencode/v2/AISDK") {} + +export const layer = Layer.effect( + Service, + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const languages = new Map() + const sdks = new Map() + + return Service.of({ + language: Effect.fn("AISDK.language")(function* (model) { + const key = `${model.providerID}/${model.id}/${model.options.variant ?? "default"}` + const existing = languages.get(key) + if (existing) return existing + if (model.endpoint.type !== "aisdk") + return yield* new InitError({ + providerID: model.providerID, + cause: new Error(`Unsupported endpoint ${model.endpoint.type}`), + }) + + const options = prepareOptions(model, model.endpoint.package) + const sdkKey = JSON.stringify({ + providerID: model.providerID, + endpoint: model.endpoint, + options, + }) + const sdk = + sdks.get(sdkKey) ?? + (yield* plugin + .trigger("aisdk.sdk", { model, package: model.endpoint.package, options }, {}) + .pipe(initError(model.providerID))).sdk + if (!sdk) + return yield* new InitError({ + providerID: model.providerID, + cause: new Error("No AISDK provider plugin returned an SDK"), + }) + sdks.set(sdkKey, sdk) + const result = yield* plugin + .trigger( + "aisdk.language", + { + model, + sdk, + options, + }, + {}, + ) + .pipe(initError(model.providerID)) + const language = yield* Effect.sync(() => result.language ?? sdk.languageModel(model.apiID)).pipe( + initError(model.providerID), + ) + languages.set(key, language) + return language + }), + }) + }), +) + +export const defaultLayer = layer.pipe(Layer.provide(PluginV2.defaultLayer)) diff --git a/packages/opencode/src/v2/auth.ts b/packages/core/src/auth.ts similarity index 85% rename from packages/opencode/src/v2/auth.ts rename to packages/core/src/auth.ts index 9ae5ee5a943..971b2320353 100644 --- a/packages/opencode/src/v2/auth.ts +++ b/packages/core/src/auth.ts @@ -1,9 +1,9 @@ import path from "path" import { Effect, Layer, Option, Schema, Context, SynchronizedRef } from "effect" -import { Identifier } from "@opencode-ai/core/util/identifier" -import { NonNegativeInt, withStatics } from "@opencode-ai/core/schema" -import { Global } from "@opencode-ai/core/global" -import { AppFileSystem } from "@opencode-ai/core/filesystem" +import { Identifier } from "./util/identifier" +import { NonNegativeInt, withStatics } from "./schema" +import { Global } from "./global" +import { AppFileSystem } from "./filesystem" export const OAUTH_DUMMY_KEY = "opencode-oauth-dummy-key" @@ -21,6 +21,7 @@ export class OAuthCredential extends Schema.Class("AuthV2.OAuth refresh: Schema.String, access: Schema.String, expires: NonNegativeInt, + accountId: Schema.optional(Schema.String), // kilocode_change - preserve Kilo organization during v1 migration }) {} export class ApiKeyCredential extends Schema.Class("AuthV2.ApiKeyCredential")({ @@ -106,27 +107,45 @@ export const layer = Layer.effect( const fsys = yield* AppFileSystem.Service const global = yield* Global.Service const file = path.join(global.data, "auth-v2.json") + const legacyFile = path.join(global.data, "auth.json") - const load: () => Effect.Effect = Effect.fnUntraced(function* () { - if (process.env.KILO_AUTH_CONTENT) { - try { - return JSON.parse(process.env.KILO_AUTH_CONTENT) - } catch {} - } - - const raw = yield* fsys.readJson(file).pipe(Effect.orElseSucceed(() => null)) - - if (!raw || typeof raw !== "object") return { version: 2, accounts: {}, active: {} } - - if ("version" in raw && raw.version === 2) return raw as Writable - - const migrated = migrate(raw as Record) + const writeMigrated = Effect.fnUntraced(function* (raw: Record) { + const migrated = migrate(raw) yield* fsys .writeJson(file, migrated, 0o600) .pipe(Effect.mapError((cause) => new AuthFileWriteError({ operation: "migrate", cause }))) return migrated }) + const parseAuthContent = () => { + try { + return JSON.parse(process.env.KILO_AUTH_CONTENT ?? "") + } catch {} + } + + const load: () => Effect.Effect = Effect.fnUntraced(function* () { + if (process.env.KILO_AUTH_CONTENT) { + const raw = parseAuthContent() + if (raw && typeof raw === "object") { + if ("version" in raw && raw.version === 2) return raw as Writable + return yield* writeMigrated(raw as Record) + } + return { version: 2, accounts: {}, active: {} } + } + + const legacy = yield* fsys.readJson(legacyFile).pipe(Effect.orElseSucceed(() => null)) + if (legacy && typeof legacy === "object") return yield* writeMigrated(legacy as Record) + + const raw = yield* fsys.readJson(file).pipe(Effect.orElseSucceed(() => null)) + + if (raw && typeof raw === "object") { + if ("version" in raw && raw.version === 2) return raw as Writable + return yield* writeMigrated(raw as Record) + } + + return { version: 2, accounts: {}, active: {} } + }) + const write = (data: Writable) => fsys .writeJson(file, data, 0o600) diff --git a/packages/core/src/catalog.ts b/packages/core/src/catalog.ts new file mode 100644 index 00000000000..70cdba78563 --- /dev/null +++ b/packages/core/src/catalog.ts @@ -0,0 +1,260 @@ +export * as Catalog from "./catalog" + +import { Context, Effect, HashMap, Layer, Option, Order, pipe, Schema, Array } from "effect" +import { produce, type Draft } from "immer" +import { ModelV2 } from "./model" +import { PluginV2 } from "./plugin" +import { ProviderV2 } from "./provider" +import { Instance } from "./instance" + +type ProviderRecord = { + provider: ProviderV2.Info + models: HashMap.HashMap +} + +export class ProviderNotFoundError extends Schema.TaggedErrorClass()( + "CatalogV2.ProviderNotFound", + { + providerID: ProviderV2.ID, + }, +) {} + +export class ModelNotFoundError extends Schema.TaggedErrorClass()("CatalogV2.ModelNotFound", { + providerID: ProviderV2.ID, + modelID: ModelV2.ID, +}) {} + +export interface Interface { + readonly provider: { + readonly get: (providerID: ProviderV2.ID) => Effect.Effect + readonly update: (providerID: ProviderV2.ID, fn: (provider: Draft) => void) => Effect.Effect + readonly all: () => Effect.Effect + readonly available: () => Effect.Effect + } + readonly model: { + readonly get: ( + providerID: ProviderV2.ID, + modelID: ModelV2.ID, + ) => Effect.Effect + readonly update: ( + providerID: ProviderV2.ID, + modelID: ModelV2.ID, + fn: (model: Draft) => void, + ) => Effect.Effect + readonly all: () => Effect.Effect + readonly available: () => Effect.Effect + readonly default: () => Effect.Effect> + readonly setDefault: ( + providerID: ProviderV2.ID, + modelID: ModelV2.ID, + ) => Effect.Effect + readonly small: (providerID: ProviderV2.ID) => Effect.Effect> + } +} + +export class Service extends Context.Service()("@opencode/v2/Catalog") {} + +export const layer = Layer.effect( + Service, + Effect.gen(function* () { + yield* Instance.Service + let records = HashMap.empty() + let defaultModel: { providerID: ProviderV2.ID; modelID: ModelV2.ID } | undefined + const plugin = yield* PluginV2.Service + + const resolve = (model: ModelV2.Info) => { + const provider = Option.getOrThrow(HashMap.get(records, model.providerID)).provider + const endpoint = + model.endpoint.type === "unknown" + ? provider.endpoint + : model.endpoint.type === "aisdk" && provider.endpoint.type === "aisdk" && !model.endpoint.url + ? { ...model.endpoint, url: provider.endpoint.url } + : model.endpoint + const options = { + headers: { + ...provider.options.headers, + ...model.options.headers, + }, + body: { + ...provider.options.body, + ...model.options.body, + }, + aisdk: { + provider: { + ...provider.options.aisdk.provider, + ...model.options.aisdk.provider, + }, + request: model.options.aisdk.request, + }, + variant: model.options.variant, + } + return new ModelV2.Info({ + ...model, + endpoint, + options, + }) + } + + function* getRecord(providerID: ProviderV2.ID) { + const match = HashMap.get(records, providerID) + if (!match.valueOrUndefined) return yield* new ProviderNotFoundError({ providerID }) + return match.value + } + + const result: Interface = { + provider: { + get: Effect.fn("CatalogV2.provider.get")(function* (providerID) { + const record = yield* getRecord(providerID) + return record.provider + }), + + update: Effect.fnUntraced(function* (providerID, fn) { + const current = Option.getOrUndefined(HashMap.get(records, providerID)) + const provider = produce(current?.provider ?? ProviderV2.Info.empty(providerID), (draft) => { + fn(draft) + if (draft.endpoint.type === "aisdk" && typeof draft.options.aisdk.provider.baseURL === "string") { + draft.endpoint.url = draft.options.aisdk.provider.baseURL + delete draft.options.aisdk.provider.baseURL + } + }) + const updated = yield* plugin.trigger("provider.update", {}, { provider, cancel: false }) + records = HashMap.set(records, providerID, { + provider: updated.provider, + models: current?.models ?? HashMap.empty(), + }) + }), + + all: Effect.fn("CatalogV2.provider.all")(function* () { + return globalThis.Array.from(HashMap.values(records)).map((record) => record.provider) + }), + + available: Effect.fn("CatalogV2.provider.available")(function* () { + return globalThis.Array.from(HashMap.values(records)) + .map((record) => record.provider) + .filter((provider) => provider.enabled) + }), + }, + + model: { + get: Effect.fn("CatalogV2.model.get")(function* (providerID, modelID) { + const record = yield* getRecord(providerID) + const model = Option.getOrUndefined(HashMap.get(record.models, modelID)) + if (!model) return yield* new ModelNotFoundError({ providerID, modelID }) + return resolve(model) + }), + + update: Effect.fnUntraced(function* (providerID, modelID, fn) { + const record = yield* getRecord(providerID) + const model = produce( + HashMap.get(record.models, modelID).pipe(Option.getOrElse(() => ModelV2.Info.empty(providerID, modelID))), + (draft) => { + fn(draft) + if (draft.endpoint.type === "aisdk" && typeof draft.options.aisdk.provider.baseURL === "string") { + draft.endpoint.url = draft.options.aisdk.provider.baseURL + delete draft.options.aisdk.provider.baseURL + } + }, + ) + const updated = yield* plugin.trigger("model.update", {}, { model, cancel: false }) + if (updated.cancel) return + records = HashMap.set(records, providerID, { + provider: record.provider, + models: HashMap.set( + record.models, + modelID, + new ModelV2.Info({ ...updated.model, id: modelID, providerID }), + ), + }) + return + }), + + all: Effect.fn("CatalogV2.model.all")(function* () { + return pipe( + records, + HashMap.toValues, + Array.flatMap((record) => HashMap.toValues(record.models)), + Array.map(resolve), + Array.sortWith((item) => item.time.released.epochMilliseconds, Order.flip(Order.Number)), + ) + }), + + available: Effect.fn("CatalogV2.model.available")(function* () { + return (yield* result.model.all()).filter((model) => { + const record = Option.getOrUndefined(HashMap.get(records, model.providerID)) + return record?.provider.enabled !== false && model.enabled + }) + }), + + default: Effect.fn("CatalogV2.model.default")(function* () { + if (defaultModel) { + const model = yield* result.model.get(defaultModel.providerID, defaultModel.modelID).pipe(Effect.option) + if (Option.isSome(model) && model.value.enabled) return model + } + + return pipe( + yield* result.model.available(), + Array.sortWith((item) => item.time.released.epochMilliseconds, Order.flip(Order.Number)), + Array.head, + ) + }), + + setDefault: Effect.fn("CatalogV2.model.setDefault")(function* (providerID, modelID) { + yield* result.model.get(providerID, modelID) + defaultModel = { providerID, modelID } + }), + + small: Effect.fn("CatalogV2.model.small")(function* (providerID) { + const record = Option.getOrUndefined(HashMap.get(records, providerID)) + if (!record) return Option.none() + + if (providerID === ProviderV2.ID.opencode) { + const gpt5Nano = Option.getOrUndefined(HashMap.get(record.models, ModelV2.ID.make("gpt-5-nano"))) + if (gpt5Nano?.enabled && gpt5Nano.status === "active") return Option.some(resolve(gpt5Nano)) + } + + const candidates = pipe( + HashMap.toValues(record.models), + Array.filter( + (model) => + model.providerID === providerID && + model.enabled && + model.status === "active" && + model.capabilities.input.some((item) => item.startsWith("text")) && + model.capabilities.output.some((item) => item.startsWith("text")), + ), + Array.map((model) => ({ + model, + cost: model.cost[0] ? model.cost[0].input + model.cost[0].output : 999, + age: (Date.now() - model.time.released.epochMilliseconds) / (1000 * 60 * 60 * 24 * 30), + small: SMALL_MODEL_RE.test(`${model.id} ${model.family ?? ""} ${model.name}`.toLowerCase()), + })), + Array.filter((item) => item.cost > 0 && item.age <= 18), + ) + + const pick = (items: typeof candidates) => { + const maxCost = Math.max(...items.map((item) => item.cost), 0.01) + const maxAge = Math.max(...items.map((item) => item.age), 0.01) + return pipe( + items, + Array.sortWith((item) => (item.cost / maxCost) * 0.8 + (item.age / maxAge) * 0.2, Order.Number), + Array.map((item) => resolve(item.model)), + Array.head, + ) + } + + return pipe( + candidates, + Array.filter((item) => item.small), + (items) => (items.length > 0 ? pick(items) : pick(candidates)), + ) + }), + }, + } + + return Service.of(result) + }), +) + +const SMALL_MODEL_RE = /\b(nano|flash|lite|mini|haiku|small|fast)\b/ + +export const defaultLayer = layer.pipe(Layer.provide(PluginV2.defaultLayer)) diff --git a/packages/core/src/effect-zod.ts b/packages/core/src/effect-zod.ts index 1c88712d7d1..68395379e3f 100644 --- a/packages/core/src/effect-zod.ts +++ b/packages/core/src/effect-zod.ts @@ -228,7 +228,7 @@ function issueMessage(issue: any): string | undefined { } function body(ast: SchemaAST.AST): z.ZodTypeAny { - if (SchemaAST.isOptional(ast)) return opt(ast) + if (SchemaAST.isOptional(ast) && ast._tag === "Union") return opt(ast) switch (ast._tag) { case "String": diff --git a/packages/core/src/flag/flag.ts b/packages/core/src/flag/flag.ts index 95c8e01634e..ab0647c8af3 100644 --- a/packages/core/src/flag/flag.ts +++ b/packages/core/src/flag/flag.ts @@ -11,8 +11,6 @@ function falsy(key: string) { return value === "false" || value === "0" } -// Channels where new experiments default to ON (unstable / internal users). -// Stable channels (`prod`, `latest`) stay opt-in. const UNSTABLE_CHANNELS = new Set(["dev", "beta", "local"]) function unstableDefault(key: string) { return truthy(key) || (!falsy(key) && UNSTABLE_CHANNELS.has(InstallationChannel)) @@ -54,16 +52,13 @@ export const Flag = { KILO_DISABLE_CLAUDE_CODE, KILO_DISABLE_CLAUDE_CODE_PROMPT: KILO_DISABLE_CLAUDE_CODE || truthy("KILO_DISABLE_CLAUDE_CODE_PROMPT"), KILO_DISABLE_CLAUDE_CODE_SKILLS, - KILO_DISABLE_EXTERNAL_SKILLS: truthy("KILO_DISABLE_EXTERNAL_SKILLS"), // kilocode_change - // Default-on for dev/beta/local; opt-in for stable. Set - // KILO_EXPERIMENTAL_CUSTOMIZE_SKILL=false to force off, =true to force on. + KILO_DISABLE_EXTERNAL_SKILLS: truthy("KILO_DISABLE_EXTERNAL_SKILLS"), KILO_EXPERIMENTAL_CUSTOMIZE_SKILL: unstableDefault("KILO_EXPERIMENTAL_CUSTOMIZE_SKILL"), KILO_FAKE_VCS: process.env["KILO_FAKE_VCS"], KILO_SERVER_PASSWORD: process.env["KILO_SERVER_PASSWORD"], KILO_SERVER_USERNAME: process.env["KILO_SERVER_USERNAME"], KILO_ENABLE_QUESTION_TOOL: truthy("KILO_ENABLE_QUESTION_TOOL"), - // Experimental KILO_EXPERIMENTAL, KILO_EXPERIMENTAL_FILEWATCHER: Config.boolean("KILO_EXPERIMENTAL_FILEWATCHER").pipe(Config.withDefault(false)), KILO_EXPERIMENTAL_DISABLE_FILEWATCHER: Config.boolean("KILO_EXPERIMENTAL_DISABLE_FILEWATCHER").pipe( @@ -93,9 +88,8 @@ export const Flag = { KILO_WORKSPACE_ID: process.env["KILO_WORKSPACE_ID"], KILO_EXPERIMENTAL_WORKSPACES: KILO_EXPERIMENTAL || truthy("KILO_EXPERIMENTAL_WORKSPACES"), KILO_EXPERIMENTAL_EVENT_SYSTEM: KILO_EXPERIMENTAL || truthy("KILO_EXPERIMENTAL_EVENT_SYSTEM"), + KILO_EXPERIMENTAL_SESSION_SWITCHING: KILO_EXPERIMENTAL || truthy("KILO_EXPERIMENTAL_SESSION_SWITCHING"), - // Evaluated at access time (not module load) because tests, the CLI, and - // external tooling set these env vars at runtime. get KILO_DISABLE_PROJECT_CONFIG() { return truthy("KILO_DISABLE_PROJECT_CONFIG") }, @@ -114,9 +108,7 @@ export const Flag = { get KILO_CLIENT() { return process.env["KILO_CLIENT"] ?? "cli" }, - // kilocode_change start get KILO_SESSION_RETRY_LIMIT() { return number("KILO_SESSION_RETRY_LIMIT") }, - // kilocode_change end } diff --git a/packages/opencode/src/provider/sdk/copilot/README.md b/packages/core/src/github-copilot/README.md similarity index 100% rename from packages/opencode/src/provider/sdk/copilot/README.md rename to packages/core/src/github-copilot/README.md diff --git a/packages/opencode/src/provider/sdk/copilot/chat/convert-to-openai-compatible-chat-messages.ts b/packages/core/src/github-copilot/chat/convert-to-openai-compatible-chat-messages.ts similarity index 100% rename from packages/opencode/src/provider/sdk/copilot/chat/convert-to-openai-compatible-chat-messages.ts rename to packages/core/src/github-copilot/chat/convert-to-openai-compatible-chat-messages.ts diff --git a/packages/opencode/src/provider/sdk/copilot/chat/get-response-metadata.ts b/packages/core/src/github-copilot/chat/get-response-metadata.ts similarity index 100% rename from packages/opencode/src/provider/sdk/copilot/chat/get-response-metadata.ts rename to packages/core/src/github-copilot/chat/get-response-metadata.ts diff --git a/packages/opencode/src/provider/sdk/copilot/chat/map-openai-compatible-finish-reason.ts b/packages/core/src/github-copilot/chat/map-openai-compatible-finish-reason.ts similarity index 100% rename from packages/opencode/src/provider/sdk/copilot/chat/map-openai-compatible-finish-reason.ts rename to packages/core/src/github-copilot/chat/map-openai-compatible-finish-reason.ts diff --git a/packages/opencode/src/provider/sdk/copilot/chat/openai-compatible-api-types.ts b/packages/core/src/github-copilot/chat/openai-compatible-api-types.ts similarity index 100% rename from packages/opencode/src/provider/sdk/copilot/chat/openai-compatible-api-types.ts rename to packages/core/src/github-copilot/chat/openai-compatible-api-types.ts diff --git a/packages/opencode/src/provider/sdk/copilot/chat/openai-compatible-chat-language-model.ts b/packages/core/src/github-copilot/chat/openai-compatible-chat-language-model.ts similarity index 100% rename from packages/opencode/src/provider/sdk/copilot/chat/openai-compatible-chat-language-model.ts rename to packages/core/src/github-copilot/chat/openai-compatible-chat-language-model.ts diff --git a/packages/opencode/src/provider/sdk/copilot/chat/openai-compatible-chat-options.ts b/packages/core/src/github-copilot/chat/openai-compatible-chat-options.ts similarity index 100% rename from packages/opencode/src/provider/sdk/copilot/chat/openai-compatible-chat-options.ts rename to packages/core/src/github-copilot/chat/openai-compatible-chat-options.ts diff --git a/packages/opencode/src/provider/sdk/copilot/chat/openai-compatible-metadata-extractor.ts b/packages/core/src/github-copilot/chat/openai-compatible-metadata-extractor.ts similarity index 100% rename from packages/opencode/src/provider/sdk/copilot/chat/openai-compatible-metadata-extractor.ts rename to packages/core/src/github-copilot/chat/openai-compatible-metadata-extractor.ts diff --git a/packages/opencode/src/provider/sdk/copilot/chat/openai-compatible-prepare-tools.ts b/packages/core/src/github-copilot/chat/openai-compatible-prepare-tools.ts similarity index 100% rename from packages/opencode/src/provider/sdk/copilot/chat/openai-compatible-prepare-tools.ts rename to packages/core/src/github-copilot/chat/openai-compatible-prepare-tools.ts diff --git a/packages/opencode/src/provider/sdk/copilot/copilot-provider.ts b/packages/core/src/github-copilot/copilot-provider.ts similarity index 100% rename from packages/opencode/src/provider/sdk/copilot/copilot-provider.ts rename to packages/core/src/github-copilot/copilot-provider.ts diff --git a/packages/opencode/src/provider/sdk/copilot/openai-compatible-error.ts b/packages/core/src/github-copilot/openai-compatible-error.ts similarity index 100% rename from packages/opencode/src/provider/sdk/copilot/openai-compatible-error.ts rename to packages/core/src/github-copilot/openai-compatible-error.ts diff --git a/packages/opencode/src/provider/sdk/copilot/responses/convert-to-openai-responses-input.ts b/packages/core/src/github-copilot/responses/convert-to-openai-responses-input.ts similarity index 100% rename from packages/opencode/src/provider/sdk/copilot/responses/convert-to-openai-responses-input.ts rename to packages/core/src/github-copilot/responses/convert-to-openai-responses-input.ts diff --git a/packages/opencode/src/provider/sdk/copilot/responses/map-openai-responses-finish-reason.ts b/packages/core/src/github-copilot/responses/map-openai-responses-finish-reason.ts similarity index 100% rename from packages/opencode/src/provider/sdk/copilot/responses/map-openai-responses-finish-reason.ts rename to packages/core/src/github-copilot/responses/map-openai-responses-finish-reason.ts diff --git a/packages/opencode/src/provider/sdk/copilot/responses/openai-config.ts b/packages/core/src/github-copilot/responses/openai-config.ts similarity index 100% rename from packages/opencode/src/provider/sdk/copilot/responses/openai-config.ts rename to packages/core/src/github-copilot/responses/openai-config.ts diff --git a/packages/opencode/src/provider/sdk/copilot/responses/openai-error.ts b/packages/core/src/github-copilot/responses/openai-error.ts similarity index 100% rename from packages/opencode/src/provider/sdk/copilot/responses/openai-error.ts rename to packages/core/src/github-copilot/responses/openai-error.ts diff --git a/packages/opencode/src/provider/sdk/copilot/responses/openai-responses-api-types.ts b/packages/core/src/github-copilot/responses/openai-responses-api-types.ts similarity index 100% rename from packages/opencode/src/provider/sdk/copilot/responses/openai-responses-api-types.ts rename to packages/core/src/github-copilot/responses/openai-responses-api-types.ts diff --git a/packages/opencode/src/provider/sdk/copilot/responses/openai-responses-language-model.ts b/packages/core/src/github-copilot/responses/openai-responses-language-model.ts similarity index 100% rename from packages/opencode/src/provider/sdk/copilot/responses/openai-responses-language-model.ts rename to packages/core/src/github-copilot/responses/openai-responses-language-model.ts diff --git a/packages/opencode/src/provider/sdk/copilot/responses/openai-responses-prepare-tools.ts b/packages/core/src/github-copilot/responses/openai-responses-prepare-tools.ts similarity index 100% rename from packages/opencode/src/provider/sdk/copilot/responses/openai-responses-prepare-tools.ts rename to packages/core/src/github-copilot/responses/openai-responses-prepare-tools.ts diff --git a/packages/opencode/src/provider/sdk/copilot/responses/openai-responses-settings.ts b/packages/core/src/github-copilot/responses/openai-responses-settings.ts similarity index 100% rename from packages/opencode/src/provider/sdk/copilot/responses/openai-responses-settings.ts rename to packages/core/src/github-copilot/responses/openai-responses-settings.ts diff --git a/packages/opencode/src/provider/sdk/copilot/responses/tool/code-interpreter.ts b/packages/core/src/github-copilot/responses/tool/code-interpreter.ts similarity index 100% rename from packages/opencode/src/provider/sdk/copilot/responses/tool/code-interpreter.ts rename to packages/core/src/github-copilot/responses/tool/code-interpreter.ts diff --git a/packages/opencode/src/provider/sdk/copilot/responses/tool/file-search.ts b/packages/core/src/github-copilot/responses/tool/file-search.ts similarity index 100% rename from packages/opencode/src/provider/sdk/copilot/responses/tool/file-search.ts rename to packages/core/src/github-copilot/responses/tool/file-search.ts diff --git a/packages/opencode/src/provider/sdk/copilot/responses/tool/image-generation.ts b/packages/core/src/github-copilot/responses/tool/image-generation.ts similarity index 100% rename from packages/opencode/src/provider/sdk/copilot/responses/tool/image-generation.ts rename to packages/core/src/github-copilot/responses/tool/image-generation.ts diff --git a/packages/opencode/src/provider/sdk/copilot/responses/tool/local-shell.ts b/packages/core/src/github-copilot/responses/tool/local-shell.ts similarity index 100% rename from packages/opencode/src/provider/sdk/copilot/responses/tool/local-shell.ts rename to packages/core/src/github-copilot/responses/tool/local-shell.ts diff --git a/packages/opencode/src/provider/sdk/copilot/responses/tool/web-search-preview.ts b/packages/core/src/github-copilot/responses/tool/web-search-preview.ts similarity index 100% rename from packages/opencode/src/provider/sdk/copilot/responses/tool/web-search-preview.ts rename to packages/core/src/github-copilot/responses/tool/web-search-preview.ts diff --git a/packages/opencode/src/provider/sdk/copilot/responses/tool/web-search.ts b/packages/core/src/github-copilot/responses/tool/web-search.ts similarity index 100% rename from packages/opencode/src/provider/sdk/copilot/responses/tool/web-search.ts rename to packages/core/src/github-copilot/responses/tool/web-search.ts diff --git a/packages/core/src/instance-layer.ts b/packages/core/src/instance-layer.ts new file mode 100644 index 00000000000..20e6ac1aceb --- /dev/null +++ b/packages/core/src/instance-layer.ts @@ -0,0 +1,12 @@ +import { Layer, LayerMap } from "effect" +import { Instance } from "./instance" +import { Catalog } from "./catalog" +import { PluginBoot } from "./plugin/boot" + +export class InstanceServiceMap extends LayerMap.Service()("@opencode/example/InstanceServiceMap", { + lookup: (ref: Instance.Ref) => { + const instance = Layer.succeed(Instance.Service, Instance.Service.of(ref)) + return Layer.mergeAll(Catalog.defaultLayer, PluginBoot.defaultLayer).pipe(Layer.provide(instance)) + }, + idleTimeToLive: "5 minutes", +}) {} diff --git a/packages/core/src/instance.ts b/packages/core/src/instance.ts new file mode 100644 index 00000000000..af6de951be4 --- /dev/null +++ b/packages/core/src/instance.ts @@ -0,0 +1,10 @@ +import { Context } from "effect" + +export * as Instance from "./instance" + +export type Ref = { + readonly directory: string + readonly workspaceID?: string +} + +export class Service extends Context.Service()("@opencode/Instance") {} diff --git a/packages/core/src/kilocode/models-refresh.ts b/packages/core/src/kilocode/models-refresh.ts new file mode 100644 index 00000000000..3beeaac69de --- /dev/null +++ b/packages/core/src/kilocode/models-refresh.ts @@ -0,0 +1,15 @@ +import { Effect } from "effect" + +type Listener = () => Effect.Effect + +const listeners = new Set() + +export const notify = Effect.fn("ModelsRefresh.notify")(function* () { + yield* Effect.forEach([...listeners], (listener) => Effect.exit(listener()), { discard: true }) +}) + +export const watch = (listener: Listener) => + Effect.gen(function* () { + listeners.add(listener) + yield* Effect.addFinalizer(() => Effect.sync(() => listeners.delete(listener))) + }) diff --git a/packages/core/src/model.ts b/packages/core/src/model.ts new file mode 100644 index 00000000000..77b8c60ebe7 --- /dev/null +++ b/packages/core/src/model.ts @@ -0,0 +1,116 @@ +import { DateTime, Schema } from "effect" +import { DateTimeUtcFromMillis } from "effect/Schema" +import { ProviderV2 } from "./provider" + +export const ID = Schema.String.pipe(Schema.brand("ModelV2.ID")) +export type ID = typeof ID.Type + +export const VariantID = Schema.String.pipe(Schema.brand("VariantID")) +export type VariantID = typeof VariantID.Type + +// Grouping of models, eg claude opus, claude sonnet +export const Family = Schema.String.pipe(Schema.brand("Family")) +export type Family = typeof Family.Type + +export const Capabilities = Schema.Struct({ + tools: Schema.Boolean, + // mime patterns, image, audio, video/*, text/* + input: Schema.String.pipe(Schema.Array), + output: Schema.String.pipe(Schema.Array), +}) +export type Capabilities = typeof Capabilities.Type + +export const Cost = Schema.Struct({ + tier: Schema.Struct({ + type: Schema.Literal("context"), + size: Schema.Int, + }).pipe(Schema.optional), + input: Schema.Finite, + output: Schema.Finite, + cache: Schema.Struct({ + read: Schema.Finite, + write: Schema.Finite, + }), +}) + +export const Ref = Schema.Struct({ + id: ID, + providerID: ProviderV2.ID, + variant: VariantID, +}) +export type Ref = typeof Ref.Type + +export class Info extends Schema.Class("ModelV2.Info")({ + id: ID, + apiID: ID, + providerID: ProviderV2.ID, + family: Family.pipe(Schema.optional), + name: Schema.String, + endpoint: ProviderV2.Endpoint, + capabilities: Capabilities, + options: Schema.Struct({ + ...ProviderV2.Options.fields, + variant: Schema.String.pipe(Schema.optional), + }), + variants: Schema.Struct({ + id: VariantID, + ...ProviderV2.Options.fields, + }).pipe(Schema.Array), + time: Schema.Struct({ + released: DateTimeUtcFromMillis, + }), + cost: Cost.pipe(Schema.Array), + status: Schema.Literals(["alpha", "beta", "deprecated", "active"]), + enabled: Schema.Boolean, + limit: Schema.Struct({ + context: Schema.Int, + input: Schema.Int.pipe(Schema.optional), + output: Schema.Int, + }), +}) { + static empty(providerID: ProviderV2.ID, modelID: ID) { + return new Info({ + id: modelID, + apiID: modelID, + providerID, + name: modelID, + endpoint: { + type: "unknown", + }, + capabilities: { + tools: false, + input: [], + output: [], + }, + options: { + headers: {}, + body: {}, + aisdk: { + provider: {}, + request: {}, + }, + }, + variants: [], + time: { + released: DateTime.makeUnsafe(0), + }, + cost: [], + status: "active", + enabled: true, + limit: { + context: 0, + output: 0, + }, + }) + } +} + +export function parse(input: string): { providerID: ProviderV2.ID; modelID: ID } { + const [providerID, ...modelID] = input.split("/") + return { + providerID: ProviderV2.ID.make(providerID), + modelID: ID.make(modelID.join("/")), + } +} + +export * as ModelV2 from "./model" diff --git a/packages/core/src/models-snapshot.d.ts b/packages/core/src/models-snapshot.d.ts new file mode 100644 index 00000000000..839eba6b7d5 --- /dev/null +++ b/packages/core/src/models-snapshot.d.ts @@ -0,0 +1,2 @@ +// Auto-generated by build.ts - do not edit +export declare const snapshot: Record diff --git a/packages/core/src/models-snapshot.js b/packages/core/src/models-snapshot.js new file mode 100644 index 00000000000..c582a75bdfd --- /dev/null +++ b/packages/core/src/models-snapshot.js @@ -0,0 +1,71726 @@ +// @ts-nocheck +// Auto-generated by build.ts - do not edit +export const snapshot = { + "302ai": { + id: "302ai", + env: ["302AI_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.302.ai/v1", + name: "302.AI", + doc: "https://doc.302.ai", + models: { + "qwen3-235b-a22b": { + id: "qwen3-235b-a22b", + name: "Qwen3-235B-A22B", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-04-29", + last_updated: "2025-04-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.29, output: 2.86 }, + limit: { context: 128000, output: 16384 }, + }, + "grok-4.1": { + id: "grok-4.1", + name: "grok-4.1", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-06", + release_date: "2025-11-18", + last_updated: "2025-11-18", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 10 }, + limit: { context: 200000, output: 64000 }, + }, + "MiniMax-M2": { + id: "MiniMax-M2", + name: "MiniMax-M2", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-10-26", + last_updated: "2025-10-26", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.33, output: 1.32 }, + limit: { context: 1000000, output: 128000 }, + }, + "grok-4-1-fast-reasoning": { + id: "grok-4-1-fast-reasoning", + name: "grok-4-1-fast-reasoning", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-06", + release_date: "2025-11-20", + last_updated: "2025-11-20", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5 }, + limit: { context: 2000000, output: 30000 }, + }, + "gemini-2.5-flash-nothink": { + id: "gemini-2.5-flash-nothink", + name: "gemini-2.5-flash-nothink", + family: "gemini-flash", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-06-24", + last_updated: "2025-06-24", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 2.5 }, + limit: { context: 1000000, output: 65536 }, + }, + "grok-4.20-multi-agent-beta-0309": { + id: "grok-4.20-multi-agent-beta-0309", + name: "grok-4.20-multi-agent-beta-0309", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-16", + last_updated: "2026-03-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 6 }, + limit: { context: 2000000, output: 30000 }, + }, + "kimi-k2-0905-preview": { + id: "kimi-k2-0905-preview", + name: "kimi-k2-0905-preview", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-06", + release_date: "2025-09-05", + last_updated: "2025-09-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.632, output: 2.53 }, + limit: { context: 262144, output: 262144 }, + }, + "claude-haiku-4-5": { + id: "claude-haiku-4-5", + name: "claude-haiku-4-5", + family: "claude-haiku", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-02-28", + release_date: "2025-10-16", + last_updated: "2025-10-16", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 5 }, + limit: { context: 200000, output: 64000 }, + }, + "claude-opus-4-5-20251101": { + id: "claude-opus-4-5-20251101", + name: "claude-opus-4-5-20251101", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-11-25", + last_updated: "2025-11-25", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25 }, + limit: { context: 200000, output: 64000 }, + }, + "gemini-2.5-flash-lite-preview-09-2025": { + id: "gemini-2.5-flash-lite-preview-09-2025", + name: "gemini-2.5-flash-lite-preview-09-2025", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-09-26", + last_updated: "2025-09-26", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4 }, + limit: { context: 1000000, output: 65536 }, + }, + "qwen3-235b-a22b-instruct-2507": { + id: "qwen3-235b-a22b-instruct-2507", + name: "qwen3-235b-a22b-instruct-2507", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-30", + last_updated: "2025-07-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.29, output: 1.143 }, + limit: { context: 128000, output: 65536 }, + }, + "glm-5v-turbo": { + id: "glm-5v-turbo", + name: "GLM-5V-Turbo", + family: "glm", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-04-02", + last_updated: "2026-04-02", + modalities: { input: ["text", "image", "video", "audio", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.72, output: 3.2 }, + limit: { context: 200000, output: 131072 }, + }, + "mistral-large-2512": { + id: "mistral-large-2512", + name: "mistral-large-2512", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-12", + release_date: "2025-12-16", + last_updated: "2025-12-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 3.3 }, + limit: { context: 128000, output: 262144 }, + }, + "glm-4.7": { + id: "glm-4.7", + name: "glm-4.7", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-04", + release_date: "2025-12-22", + last_updated: "2025-12-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.286, output: 1.142 }, + limit: { context: 204800, output: 131072 }, + }, + "claude-3-5-haiku-20241022": { + id: "claude-3-5-haiku-20241022", + name: "claude-3-5-haiku-20241022", + family: "claude-haiku", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-07-31", + release_date: "2024-10-22", + last_updated: "2024-10-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.8, output: 4 }, + limit: { context: 200000, output: 8192 }, + }, + "doubao-seed-1-8-251215": { + id: "doubao-seed-1-8-251215", + name: "doubao-seed-1-8-251215", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-12-18", + last_updated: "2025-12-18", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.114, output: 0.286 }, + limit: { context: 224000, output: 64000 }, + }, + "chatgpt-4o-latest": { + id: "chatgpt-4o-latest", + name: "chatgpt-4o-latest", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2023-09", + release_date: "2024-08-08", + last_updated: "2024-08-08", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 15 }, + limit: { context: 128000, output: 16384 }, + }, + "glm-5": { + id: "glm-5", + name: "glm-5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.6 }, + limit: { context: 204800, output: 131072 }, + }, + "deepseek-chat": { + id: "deepseek-chat", + name: "Deepseek-Chat", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2024-11-29", + last_updated: "2024-11-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.29, output: 0.43 }, + limit: { context: 128000, output: 8192 }, + }, + "deepseek-v3.2-thinking": { + id: "deepseek-v3.2-thinking", + name: "DeepSeek-V3.2-Thinking", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-12", + release_date: "2025-12-01", + last_updated: "2025-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.29, output: 0.43 }, + limit: { context: 128000, output: 128000 }, + }, + "claude-sonnet-4-6": { + id: "claude-sonnet-4-6", + name: "claude-sonnet-4-6", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-08-31", + release_date: "2026-02-18", + last_updated: "2026-03-13", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15 }, + limit: { context: 1000000, output: 64000 }, + }, + "gpt-5-thinking": { + id: "gpt-5-thinking", + name: "gpt-5-thinking", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-08-08", + last_updated: "2025-08-08", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10 }, + limit: { context: 400000, output: 128000 }, + }, + "glm-4.7-flashx": { + id: "glm-4.7-flashx", + name: "glm-4.7-flashx", + family: "glm-flash", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-01-20", + last_updated: "2026-01-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.0715, output: 0.429 }, + limit: { context: 200000, output: 131072 }, + }, + "gemini-3-flash-preview": { + id: "gemini-3-flash-preview", + name: "gemini-3-flash-preview", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-06", + release_date: "2025-12-18", + last_updated: "2025-12-18", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 3 }, + limit: { context: 1000000, output: 65536 }, + }, + "qwen-plus": { + id: "qwen-plus", + name: "Qwen-Plus", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.12, output: 1.2 }, + limit: { context: 1000000, output: 32768 }, + }, + "grok-4.20-beta-0309-non-reasoning": { + id: "grok-4.20-beta-0309-non-reasoning", + name: "grok-4.20-beta-0309-non-reasoning", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2026-03-16", + last_updated: "2026-03-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 6 }, + limit: { context: 2000000, output: 30000 }, + }, + "claude-opus-4-7": { + id: "claude-opus-4-7", + name: "claude-opus-4-7", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2026-01-31", + release_date: "2026-04-17", + last_updated: "2026-04-17", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 5, + output: 25, + cache_read: 0.5, + cache_write: 6.25, + context_over_200k: { input: 10, output: 37.5, cache_read: 1, cache_write: 12.5 }, + }, + limit: { context: 1000000, output: 128000 }, + }, + "gpt-5-mini": { + id: "gpt-5-mini", + name: "gpt-5-mini", + family: "gpt-mini", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-05-30", + release_date: "2025-08-08", + last_updated: "2025-08-08", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 2 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "gemini-3-pro-preview": { + id: "gemini-3-pro-preview", + name: "gemini-3-pro-preview", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-06", + release_date: "2025-11-19", + last_updated: "2025-11-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 12 }, + limit: { context: 1000000, output: 64000 }, + }, + "MiniMax-M2.7": { + id: "MiniMax-M2.7", + name: "MiniMax-M2.7", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2026-03-19", + last_updated: "2026-03-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 204800, output: 131072 }, + }, + "qwen3-max-2025-09-23": { + id: "qwen3-max-2025-09-23", + name: "qwen3-max-2025-09-23", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-09-24", + last_updated: "2025-09-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.86, output: 3.43 }, + limit: { context: 258048, output: 65536 }, + }, + "claude-sonnet-4-5-20250929": { + id: "claude-sonnet-4-5-20250929", + name: "claude-sonnet-4-5-20250929", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07-31", + release_date: "2025-09-30", + last_updated: "2025-09-30", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15 }, + limit: { context: 200000, output: 64000 }, + }, + "qwen-flash": { + id: "qwen-flash", + name: "Qwen-Flash", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-07-28", + last_updated: "2025-07-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.022, output: 0.22 }, + limit: { context: 1000000, output: 32768 }, + }, + "gemini-2.5-pro": { + id: "gemini-2.5-pro", + name: "gemini-2.5-pro", + family: "gemini-pro", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-06-17", + last_updated: "2025-06-17", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10 }, + limit: { context: 1000000, output: 65536 }, + }, + "grok-4-1-fast-non-reasoning": { + id: "grok-4-1-fast-non-reasoning", + name: "grok-4-1-fast-non-reasoning", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-06", + release_date: "2025-11-20", + last_updated: "2025-11-20", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5 }, + limit: { context: 2000000, output: 30000 }, + }, + "claude-3-5-haiku-latest": { + id: "claude-3-5-haiku-latest", + name: "claude-3-5-haiku-latest", + family: "claude-haiku", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-07-31", + release_date: "2024-10-22", + last_updated: "2024-10-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.8, output: 4 }, + limit: { context: 200000, output: 8192 }, + }, + "claude-opus-4-5-20251101-thinking": { + id: "claude-opus-4-5-20251101-thinking", + name: "claude-opus-4-5-20251101-thinking", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03", + release_date: "2025-11-25", + last_updated: "2025-11-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25 }, + limit: { context: 200000, output: 64000 }, + }, + "gpt-5.2": { + id: "gpt-5.2", + name: "gpt-5.2", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2025-12-12", + last_updated: "2025-12-12", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "gpt-5.4-mini": { + id: "gpt-5.4-mini", + name: "gpt-5.4-mini", + family: "gpt-mini", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-19", + last_updated: "2026-03-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.75, output: 4.5 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "gemini-3-pro-image-preview": { + id: "gemini-3-pro-image-preview", + name: "gemini-3-pro-image-preview", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2025-06", + release_date: "2025-11-20", + last_updated: "2025-11-20", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 120 }, + limit: { context: 32768, output: 64000 }, + }, + "glm-5.1": { + id: "glm-5.1", + name: "glm-5.1", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-04-10", + last_updated: "2026-04-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.86, output: 3.5 }, + limit: { context: 200000, output: 131072 }, + }, + "qwen-max-latest": { + id: "qwen-max-latest", + name: "Qwen-Max-Latest", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-11", + release_date: "2024-04-03", + last_updated: "2025-01-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.343, output: 1.372 }, + limit: { context: 131072, output: 8192 }, + }, + "gpt-5.4-nano": { + id: "gpt-5.4-nano", + name: "gpt-5.4-nano", + family: "gpt-nano", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-19", + last_updated: "2026-03-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 1.25 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "gemini-2.5-flash-image": { + id: "gemini-2.5-flash-image", + name: "gemini-2.5-flash-image", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2025-01", + release_date: "2025-10-08", + last_updated: "2025-10-08", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 30 }, + limit: { context: 32768, output: 32768 }, + }, + "glm-4.5": { + id: "glm-4.5", + name: "GLM-4.5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-29", + last_updated: "2025-07-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.286, output: 1.142 }, + limit: { context: 131072, output: 98304 }, + }, + "gpt-5.4-mini-2026-03-17": { + id: "gpt-5.4-mini-2026-03-17", + name: "gpt-5.4-mini-2026-03-17", + family: "gpt-mini", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-19", + last_updated: "2026-03-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.75, output: 4.5 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "gemini-2.5-flash": { + id: "gemini-2.5-flash", + name: "gemini-2.5-flash", + family: "gemini-flash", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-06-17", + last_updated: "2025-06-17", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 2.5 }, + limit: { context: 1000000, output: 65536 }, + }, + "gpt-5.2-chat-latest": { + id: "gpt-5.2-chat-latest", + name: "gpt-5.2-chat-latest", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2025-12-12", + last_updated: "2025-12-12", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14 }, + limit: { context: 128000, output: 16384 }, + }, + "doubao-seed-1-6-vision-250815": { + id: "doubao-seed-1-6-vision-250815", + name: "doubao-seed-1-6-vision-250815", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-09-30", + last_updated: "2025-09-30", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.114, output: 1.143 }, + limit: { context: 256000, output: 32000 }, + }, + "gemini-3.1-flash-image-preview": { + id: "gemini-3.1-flash-image-preview", + name: "gemini-3.1-flash-image-preview", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2025-01", + release_date: "2026-02-27", + last_updated: "2026-02-27", + modalities: { input: ["text", "image", "pdf"], output: ["text", "image"] }, + open_weights: false, + cost: { input: 0.5, output: 60 }, + limit: { context: 131072, output: 32768 }, + }, + "MiniMax-M2.7-highspeed": { + id: "MiniMax-M2.7-highspeed", + name: "MiniMax-M2.7-highspeed", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2026-03-19", + last_updated: "2026-03-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.6, output: 4.8 }, + limit: { context: 204800, output: 131072 }, + }, + "glm-4.5-x": { + id: "glm-4.5-x", + name: "glm-4.5-x", + family: "glm", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-29", + last_updated: "2025-07-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.143, output: 2.29 }, + limit: { context: 128000, output: 16384 }, + }, + "MiniMax-M2.1": { + id: "MiniMax-M2.1", + name: "MiniMax-M2.1", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-12-19", + last_updated: "2025-12-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 1000000, output: 131072 }, + }, + "gpt-5.1": { + id: "gpt-5.1", + name: "gpt-5.1", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-11-14", + last_updated: "2025-11-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "kimi-k2-thinking-turbo": { + id: "kimi-k2-thinking-turbo", + name: "kimi-k2-thinking-turbo", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-06", + release_date: "2025-09-05", + last_updated: "2025-09-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.265, output: 9.119 }, + limit: { context: 262144, output: 262144 }, + }, + "deepseek-reasoner": { + id: "deepseek-reasoner", + name: "Deepseek-Reasoner", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2025-01-20", + last_updated: "2025-01-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.29, output: 0.43 }, + limit: { context: 128000, output: 128000 }, + }, + "grok-4-fast-reasoning": { + id: "grok-4-fast-reasoning", + name: "grok-4-fast-reasoning", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-06", + release_date: "2025-09-23", + last_updated: "2025-09-23", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5 }, + limit: { context: 2000000, output: 30000 }, + }, + "claude-opus-4-1-20250805-thinking": { + id: "claude-opus-4-1-20250805-thinking", + name: "claude-opus-4-1-20250805-thinking", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03", + release_date: "2025-05-27", + last_updated: "2025-05-27", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75 }, + limit: { context: 200000, output: 32000 }, + }, + "glm-4.5-air": { + id: "glm-4.5-air", + name: "glm-4.5-air", + family: "glm-air", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-29", + last_updated: "2025-07-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1143, output: 0.286 }, + limit: { context: 131072, output: 98304 }, + }, + "gpt-5.4-pro": { + id: "gpt-5.4-pro", + name: "gpt-5.4-pro", + family: "gpt-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-05", + last_updated: "2026-03-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 30, output: 180, cache_read: 0, cache_write: 0, context_over_200k: { input: 60, output: 270 } }, + limit: { context: 1050000, input: 922000, output: 128000 }, + }, + "glm-5-turbo": { + id: "glm-5-turbo", + name: "glm-5-turbo", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-03-16", + last_updated: "2026-03-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.72, output: 3.2 }, + limit: { context: 200000, output: 131072 }, + }, + "qwen3-30b-a3b": { + id: "qwen3-30b-a3b", + name: "Qwen3-30B-A3B", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-04-29", + last_updated: "2025-04-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.11, output: 1.08 }, + limit: { context: 128000, output: 8192 }, + }, + "claude-opus-4-5": { + id: "claude-opus-4-5", + name: "claude-opus-4-5", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-11-25", + last_updated: "2025-11-25", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25 }, + limit: { context: 200000, output: 64000 }, + }, + "glm-4.5v": { + id: "glm-4.5v", + name: "GLM-4.5V", + family: "glm", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-08-12", + last_updated: "2025-08-12", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.29, output: 0.86 }, + limit: { context: 64000, output: 16384 }, + }, + "glm-4.6": { + id: "glm-4.6", + name: "glm-4.6", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-09-30", + last_updated: "2025-09-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.286, output: 1.142 }, + limit: { context: 204800, output: 131072 }, + }, + "claude-opus-4-6-thinking": { + id: "claude-opus-4-6-thinking", + name: "claude-opus-4-6-thinking", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-05", + release_date: "2026-02-06", + last_updated: "2026-03-13", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25 }, + limit: { context: 1000000, output: 128000 }, + }, + "gemini-2.5-flash-preview-09-2025": { + id: "gemini-2.5-flash-preview-09-2025", + name: "gemini-2.5-flash-preview-09-2025", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-09-26", + last_updated: "2025-09-26", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 2.5 }, + limit: { context: 1000000, output: 65536 }, + }, + "claude-sonnet-4-6-thinking": { + id: "claude-sonnet-4-6-thinking", + name: "claude-sonnet-4-6-thinking", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-08", + release_date: "2026-02-18", + last_updated: "2026-03-13", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15 }, + limit: { context: 1000000, output: 64000 }, + }, + "glm-4.6v": { + id: "glm-4.6v", + name: "GLM-4.6V", + family: "glm", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-12-08", + last_updated: "2025-12-08", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.145, output: 0.43 }, + limit: { context: 128000, output: 32768 }, + }, + "claude-opus-4-1-20250805": { + id: "claude-opus-4-1-20250805", + name: "claude-opus-4-1-20250805", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75 }, + limit: { context: 200000, output: 32000 }, + }, + "gpt-5.4": { + id: "gpt-5.4", + name: "gpt-5.4", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-05", + last_updated: "2026-03-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 2.5, + output: 15, + cache_read: 0.25, + cache_write: 0, + context_over_200k: { input: 5, output: 22.5 }, + }, + limit: { context: 1050000, input: 922000, output: 128000 }, + }, + "gpt-5.1-chat-latest": { + id: "gpt-5.1-chat-latest", + name: "gpt-5.1-chat-latest", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-11-14", + last_updated: "2025-11-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10 }, + limit: { context: 128000, output: 16384 }, + }, + "claude-haiku-4-5-20251001": { + id: "claude-haiku-4-5-20251001", + name: "claude-haiku-4-5-20251001", + family: "claude-haiku", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-02-28", + release_date: "2025-10-16", + last_updated: "2025-10-16", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 5 }, + limit: { context: 200000, output: 64000 }, + }, + "MiniMax-M1": { + id: "MiniMax-M1", + name: "MiniMax-M1", + family: "minimax", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-06-16", + last_updated: "2025-06-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.132, output: 1.254 }, + limit: { context: 1000000, output: 128000 }, + }, + "gpt-5.4-nano-2026-03-17": { + id: "gpt-5.4-nano-2026-03-17", + name: "gpt-5.4-nano-2026-03-17", + family: "gpt-nano", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-19", + last_updated: "2026-03-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 1.25 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "claude-sonnet-4-20250514": { + id: "claude-sonnet-4-20250514", + name: "claude-sonnet-4-20250514", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15 }, + limit: { context: 200000, output: 64000 }, + }, + "qwen3-coder-480b-a35b-instruct": { + id: "qwen3-coder-480b-a35b-instruct", + name: "qwen3-coder-480b-a35b-instruct", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-23", + last_updated: "2025-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.86, output: 3.43 }, + limit: { context: 262144, output: 65536 }, + }, + "claude-opus-4-6": { + id: "claude-opus-4-6", + name: "claude-opus-4-6", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-05-31", + release_date: "2026-02-06", + last_updated: "2026-03-13", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25 }, + limit: { context: 1000000, output: 128000 }, + }, + "doubao-seed-code-preview-251028": { + id: "doubao-seed-code-preview-251028", + name: "doubao-seed-code-preview-251028", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-11-11", + last_updated: "2025-11-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.17, output: 1.14 }, + limit: { context: 256000, output: 32000 }, + }, + "gpt-4.1-nano": { + id: "gpt-4.1-nano", + name: "gpt-4.1-nano", + family: "gpt-nano", + 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"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4 }, + limit: { context: 1047576, output: 32768 }, + }, + "deepseek-v3.2": { + id: "deepseek-v3.2", + name: "deepseek-v3.2", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-12", + release_date: "2025-12-01", + last_updated: "2025-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.29, output: 0.43 }, + limit: { context: 128000, output: 8192 }, + }, + "gpt-5-pro": { + id: "gpt-5-pro", + name: "gpt-5-pro", + family: "gpt-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-10-08", + last_updated: "2025-10-08", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 120 }, + limit: { context: 400000, input: 272000, output: 272000 }, + }, + "gpt-4o": { + id: "gpt-4o", + name: "gpt-4o", + 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-05-13", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 10 }, + limit: { context: 128000, output: 16384 }, + }, + "claude-sonnet-4-5": { + id: "claude-sonnet-4-5", + name: "claude-sonnet-4-5", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07-31", + release_date: "2025-09-30", + last_updated: "2025-09-30", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15 }, + limit: { context: 200000, output: 64000 }, + }, + "gpt-5": { + id: "gpt-5", + name: "gpt-5", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-08-08", + last_updated: "2025-08-08", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "grok-4.20-beta-0309-reasoning": { + id: "grok-4.20-beta-0309-reasoning", + name: "grok-4.20-beta-0309-reasoning", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-16", + last_updated: "2026-03-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 6 }, + limit: { context: 2000000, output: 30000 }, + }, + "claude-opus-4-20250514": { + id: "claude-opus-4-20250514", + name: "claude-opus-4-20250514", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75 }, + limit: { context: 200000, output: 32000 }, + }, + "glm-for-coding": { + id: "glm-for-coding", + name: "glm-for-coding", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-09-30", + last_updated: "2025-09-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.086, output: 0.343 }, + limit: { context: 200000, output: 131072 }, + }, + "claude-sonnet-4-5-20250929-thinking": { + id: "claude-sonnet-4-5-20250929-thinking", + name: "claude-sonnet-4-5-20250929-thinking", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03", + release_date: "2025-09-30", + last_updated: "2025-09-30", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15 }, + limit: { context: 200000, output: 64000 }, + }, + "glm-4.5-airx": { + id: "glm-4.5-airx", + name: "glm-4.5-airx", + family: "glm", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-29", + last_updated: "2025-07-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.572, output: 1.714 }, + limit: { context: 128000, output: 16384 }, + }, + "gpt-4.1": { + id: "gpt-4.1", + name: "gpt-4.1", + 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, + cost: { input: 2, output: 8 }, + limit: { context: 1047576, output: 32768 }, + }, + "kimi-k2-thinking": { + id: "kimi-k2-thinking", + name: "kimi-k2-thinking", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-06", + release_date: "2025-09-05", + last_updated: "2025-09-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.575, output: 2.3 }, + limit: { context: 262144, output: 262144 }, + }, + "gemini-2.0-flash-lite": { + id: "gemini-2.0-flash-lite", + name: "gemini-2.0-flash-lite", + family: "gemini-flash-lite", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-11", + release_date: "2025-06-16", + last_updated: "2025-06-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.075, output: 0.3 }, + limit: { context: 2000000, output: 8192 }, + }, + "gpt-4.1-mini": { + id: "gpt-4.1-mini", + name: "gpt-4.1-mini", + family: "gpt-mini", + 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, + cost: { input: 0.4, output: 1.6 }, + limit: { context: 1047576, output: 32768 }, + }, + "grok-4-fast-non-reasoning": { + id: "grok-4-fast-non-reasoning", + name: "grok-4-fast-non-reasoning", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-06", + release_date: "2025-09-23", + last_updated: "2025-09-23", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5 }, + limit: { context: 2000000, output: 30000 }, + }, + "doubao-seed-1-6-thinking-250715": { + id: "doubao-seed-1-6-thinking-250715", + name: "doubao-seed-1-6-thinking-250715", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-07-15", + last_updated: "2025-07-15", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.121, output: 1.21 }, + limit: { context: 256000, output: 16000 }, + }, + "ministral-14b-2512": { + id: "ministral-14b-2512", + name: "ministral-14b-2512", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-12", + release_date: "2025-12-16", + last_updated: "2025-12-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.33, output: 0.33 }, + limit: { context: 128000, output: 128000 }, + }, + }, + }, + alibaba: { + id: "alibaba", + env: ["DASHSCOPE_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1", + name: "Alibaba", + doc: "https://www.alibabacloud.com/help/en/model-studio/models", + models: { + "qwen3-235b-a22b": { + id: "qwen3-235b-a22b", + name: "Qwen3 235B-A22B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-04", + last_updated: "2025-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.7, output: 2.8, reasoning: 8.4 }, + limit: { context: 131072, output: 16384 }, + }, + "qwen3.5-122b-a10b": { + id: "qwen3.5-122b-a10b", + name: "Qwen3.5 122B-A10B", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-02-23", + last_updated: "2026-02-23", + modalities: { input: ["text", "image", "video", "audio"], output: ["text"] }, + open_weights: true, + cost: { input: 0.4, output: 3.2 }, + limit: { context: 262144, output: 65536 }, + }, + "qwen3-coder-plus": { + id: "qwen3-coder-plus", + name: "Qwen3 Coder Plus", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-23", + last_updated: "2025-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 5 }, + limit: { context: 1048576, output: 65536 }, + }, + "qwen3.6-27b": { + id: "qwen3.6-27b", + name: "Qwen3.6 27B", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-04-22", + last_updated: "2026-04-22", + modalities: { input: ["text", "image", "video", "audio"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 3.6 }, + limit: { context: 262144, output: 65536 }, + }, + "qwen3.5-27b": { + id: "qwen3.5-27b", + name: "Qwen3.5 27B", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-02-23", + last_updated: "2026-02-23", + modalities: { input: ["text", "image", "video", "audio"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 2.4 }, + limit: { context: 262144, output: 65536 }, + }, + "qwen-vl-ocr": { + id: "qwen-vl-ocr", + name: "Qwen-VL OCR", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-04", + release_date: "2024-10-28", + last_updated: "2025-04-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.72, output: 0.72 }, + limit: { context: 34096, output: 4096 }, + }, + "qwen-omni-turbo-realtime": { + id: "qwen-omni-turbo-realtime", + name: "Qwen-Omni Turbo Realtime", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-05-08", + last_updated: "2025-05-08", + modalities: { input: ["text", "image", "audio"], output: ["text", "audio"] }, + open_weights: false, + cost: { input: 0.27, output: 1.07, input_audio: 4.44, output_audio: 8.89 }, + limit: { context: 32768, output: 2048 }, + }, + "qwen3-8b": { + id: "qwen3-8b", + name: "Qwen3 8B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-04", + last_updated: "2025-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.18, output: 0.7, reasoning: 2.1 }, + limit: { context: 131072, output: 8192 }, + }, + "qwen3.5-397b-a17b": { + id: "qwen3.5-397b-a17b", + name: "Qwen3.5 397B-A17B", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-02-15", + last_updated: "2026-02-15", + modalities: { input: ["text", "image", "video", "audio"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 3.6 }, + limit: { context: 262144, output: 65536 }, + }, + "qwq-plus": { + id: "qwq-plus", + name: "QwQ Plus", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-03-05", + last_updated: "2025-03-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.8, output: 2.4 }, + limit: { context: 131072, output: 8192 }, + }, + "qwen-vl-plus": { + id: "qwen-vl-plus", + name: "Qwen-VL Plus", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-01-25", + last_updated: "2025-08-15", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.21, output: 0.63 }, + limit: { context: 131072, output: 8192 }, + }, + "qwen3-livetranslate-flash-realtime": { + id: "qwen3-livetranslate-flash-realtime", + name: "Qwen3-LiveTranslate Flash Realtime", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-04", + release_date: "2025-09-22", + last_updated: "2025-09-22", + modalities: { input: ["text", "image", "audio", "video"], output: ["text", "audio"] }, + open_weights: false, + cost: { input: 10, output: 10, input_audio: 10, output_audio: 38 }, + limit: { context: 53248, output: 4096 }, + }, + "qwen3-32b": { + id: "qwen3-32b", + name: "Qwen3 32B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-04", + last_updated: "2025-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.7, output: 2.8, reasoning: 8.4 }, + limit: { context: 131072, output: 16384 }, + }, + "qwen-max": { + id: "qwen-max", + name: "Qwen Max", + 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, + cost: { input: 1.6, output: 6.4 }, + limit: { context: 32768, output: 8192 }, + }, + "qwen-plus": { + id: "qwen-plus", + name: "Qwen Plus", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-01-25", + last_updated: "2025-09-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 1.2, reasoning: 4 }, + limit: { context: 1000000, output: 32768 }, + }, + "qwen3.6-35b-a3b": { + id: "qwen3.6-35b-a3b", + name: "Qwen3.6 35B-A3B", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-04-17", + last_updated: "2026-04-17", + modalities: { input: ["text", "image", "video", "audio"], output: ["text"] }, + open_weights: true, + cost: { input: 0.248, output: 1.485 }, + limit: { context: 262144, output: 65536 }, + }, + "qwen-omni-turbo": { + id: "qwen-omni-turbo", + name: "Qwen-Omni Turbo", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-01-19", + last_updated: "2025-03-26", + modalities: { input: ["text", "image", "audio", "video"], output: ["text", "audio"] }, + open_weights: false, + cost: { input: 0.07, output: 0.27, input_audio: 4.44, output_audio: 8.89 }, + limit: { context: 32768, output: 2048 }, + }, + "qwen-flash": { + id: "qwen-flash", + name: "Qwen Flash", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-07-28", + last_updated: "2025-07-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.05, output: 0.4 }, + limit: { context: 1000000, output: 32768 }, + }, + "qwen2-5-vl-7b-instruct": { + id: "qwen2-5-vl-7b-instruct", + name: "Qwen2.5-VL 7B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-09", + last_updated: "2024-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.35, output: 1.05 }, + limit: { context: 131072, output: 8192 }, + }, + "qwen3.6-plus": { + id: "qwen3.6-plus", + name: "Qwen3.6 Plus", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-04-02", + last_updated: "2026-04-02", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.276, output: 1.651, cache_read: 0.028, cache_write: 0.344 }, + limit: { context: 1000000, output: 65536 }, + }, + "qwen3-max": { + id: "qwen3-max", + name: "Qwen3 Max", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-09-23", + last_updated: "2025-09-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.2, output: 6 }, + limit: { context: 262144, output: 65536 }, + }, + "qwen3-omni-flash": { + id: "qwen3-omni-flash", + name: "Qwen3-Omni Flash", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-09-15", + last_updated: "2025-09-15", + modalities: { input: ["text", "image", "audio", "video"], output: ["text", "audio"] }, + open_weights: false, + cost: { input: 0.43, output: 1.66, input_audio: 3.81, output_audio: 15.11 }, + limit: { context: 65536, output: 16384 }, + }, + "qwen2-5-72b-instruct": { + id: "qwen2-5-72b-instruct", + name: "Qwen2.5 72B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-09", + last_updated: "2024-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.4, output: 5.6 }, + limit: { context: 131072, output: 8192 }, + }, + "qwen3-vl-235b-a22b": { + id: "qwen3-vl-235b-a22b", + name: "Qwen3-VL 235B-A22B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-04", + last_updated: "2025-04", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.7, output: 2.8, reasoning: 8.4 }, + limit: { context: 131072, output: 32768 }, + }, + "qwen3-asr-flash": { + id: "qwen3-asr-flash", + name: "Qwen3-ASR Flash", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + knowledge: "2024-04", + release_date: "2025-09-08", + last_updated: "2025-09-08", + modalities: { input: ["audio"], output: ["text"] }, + open_weights: false, + cost: { input: 0.035, output: 0.035 }, + limit: { context: 53248, output: 4096 }, + }, + "qwen3-next-80b-a3b-thinking": { + id: "qwen3-next-80b-a3b-thinking", + name: "Qwen3-Next 80B-A3B (Thinking)", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-09", + last_updated: "2025-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.5, output: 6 }, + limit: { context: 131072, output: 32768 }, + }, + "qwen-mt-plus": { + id: "qwen-mt-plus", + name: "Qwen-MT Plus", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-04", + release_date: "2025-01", + last_updated: "2025-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2.46, output: 7.37 }, + limit: { context: 16384, output: 8192 }, + }, + "qwen-vl-max": { + id: "qwen-vl-max", + name: "Qwen-VL Max", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-04-08", + last_updated: "2025-08-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.8, output: 3.2 }, + limit: { context: 131072, output: 8192 }, + }, + "qwen3-coder-flash": { + id: "qwen3-coder-flash", + name: "Qwen3 Coder Flash", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-28", + last_updated: "2025-07-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 1.5 }, + limit: { context: 1000000, output: 65536 }, + }, + "qwen2-5-7b-instruct": { + id: "qwen2-5-7b-instruct", + name: "Qwen2.5 7B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-09", + last_updated: "2024-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.175, output: 0.7 }, + limit: { context: 131072, output: 8192 }, + }, + "qwen2-5-14b-instruct": { + id: "qwen2-5-14b-instruct", + name: "Qwen2.5 14B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-09", + last_updated: "2024-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.35, output: 1.4 }, + limit: { context: 131072, output: 8192 }, + }, + "qwen2-5-32b-instruct": { + id: "qwen2-5-32b-instruct", + name: "Qwen2.5 32B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-09", + last_updated: "2024-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.7, output: 2.8 }, + limit: { context: 131072, output: 8192 }, + }, + "qwen3-next-80b-a3b-instruct": { + id: "qwen3-next-80b-a3b-instruct", + name: "Qwen3-Next 80B-A3B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-09", + last_updated: "2025-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.5, output: 2 }, + limit: { context: 131072, output: 32768 }, + }, + "qwen-plus-character-ja": { + id: "qwen-plus-character-ja", + name: "Qwen Plus Character (Japanese)", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-01", + last_updated: "2024-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 1.4 }, + limit: { context: 8192, output: 512 }, + }, + "qwen3-omni-flash-realtime": { + id: "qwen3-omni-flash-realtime", + name: "Qwen3-Omni Flash Realtime", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-09-15", + last_updated: "2025-09-15", + modalities: { input: ["text", "image", "audio", "video"], output: ["text", "audio"] }, + open_weights: false, + cost: { input: 0.52, output: 1.99, input_audio: 4.57, output_audio: 18.13 }, + limit: { context: 65536, output: 16384 }, + }, + "qwen3-vl-30b-a3b": { + id: "qwen3-vl-30b-a3b", + name: "Qwen3-VL 30B-A3B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-04", + last_updated: "2025-04", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.8, reasoning: 2.4 }, + limit: { context: 131072, output: 32768 }, + }, + "qwen3-vl-plus": { + id: "qwen3-vl-plus", + name: "Qwen3-VL Plus", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-09-23", + last_updated: "2025-09-23", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 1.6, reasoning: 4.8 }, + limit: { context: 262144, output: 32768 }, + }, + "qwen3-coder-480b-a35b-instruct": { + id: "qwen3-coder-480b-a35b-instruct", + name: "Qwen3-Coder 480B-A35B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-04", + last_updated: "2025-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.5, output: 7.5 }, + limit: { context: 262144, output: 65536 }, + }, + "qwen3-coder-30b-a3b-instruct": { + id: "qwen3-coder-30b-a3b-instruct", + name: "Qwen3-Coder 30B-A3B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-04", + last_updated: "2025-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.45, output: 2.25 }, + limit: { context: 262144, output: 65536 }, + }, + "qwen-turbo": { + id: "qwen-turbo", + name: "Qwen Turbo", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-11-01", + last_updated: "2025-04-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.05, output: 0.2, reasoning: 0.5 }, + limit: { context: 1000000, output: 16384 }, + }, + "qwen-mt-turbo": { + id: "qwen-mt-turbo", + name: "Qwen-MT Turbo", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-04", + release_date: "2025-01", + last_updated: "2025-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.16, output: 0.49 }, + limit: { context: 16384, output: 8192 }, + }, + "qwen3.6-max-preview": { + id: "qwen3.6-max-preview", + name: "Qwen3.6 Max Preview", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-04-20", + last_updated: "2026-04-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.3, output: 7.8, cache_read: 0.13, cache_write: 1.625 }, + limit: { context: 262144, output: 65536 }, + }, + "qwen2-5-omni-7b": { + id: "qwen2-5-omni-7b", + name: "Qwen2.5-Omni 7B", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-12", + last_updated: "2024-12", + modalities: { input: ["text", "image", "audio", "video"], output: ["text", "audio"] }, + open_weights: true, + cost: { input: 0.1, output: 0.4, input_audio: 6.76 }, + limit: { context: 32768, output: 2048 }, + }, + "qwen3.5-plus": { + id: "qwen3.5-plus", + name: "Qwen3.5 Plus", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-02-16", + last_updated: "2026-02-16", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 2.4, reasoning: 2.4 }, + limit: { context: 1000000, output: 65536 }, + }, + "qwen2-5-vl-72b-instruct": { + id: "qwen2-5-vl-72b-instruct", + name: "Qwen2.5-VL 72B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-09", + last_updated: "2024-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 2.8, output: 8.4 }, + limit: { context: 131072, output: 8192 }, + }, + "qvq-max": { + id: "qvq-max", + name: "QVQ Max", + family: "qvq", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-03-25", + last_updated: "2025-03-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.2, output: 4.8 }, + limit: { context: 131072, output: 8192 }, + }, + "qwen3-14b": { + id: "qwen3-14b", + name: "Qwen3 14B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-04", + last_updated: "2025-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.35, output: 1.4, reasoning: 4.2 }, + limit: { context: 131072, output: 8192 }, + }, + "qwen3.5-35b-a3b": { + id: "qwen3.5-35b-a3b", + name: "Qwen3.5 35B-A3B", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-02-23", + last_updated: "2026-02-23", + modalities: { input: ["text", "image", "video", "audio"], output: ["text"] }, + open_weights: true, + cost: { input: 0.25, output: 2 }, + limit: { context: 262144, output: 65536 }, + }, + }, + }, + scaleway: { + id: "scaleway", + env: ["SCALEWAY_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.scaleway.ai/v1", + name: "Scaleway", + doc: "https://www.scaleway.com/en/docs/generative-apis/", + models: { + "qwen3-embedding-8b": { + id: "qwen3-embedding-8b", + name: "Qwen3 Embedding 8B", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2025-25-11", + last_updated: "2026-03-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0 }, + limit: { context: 32768, output: 4096 }, + }, + "qwen3-235b-a22b-instruct-2507": { + id: "qwen3-235b-a22b-instruct-2507", + name: "Qwen3 235B A22B Instruct 2507", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-07-01", + last_updated: "2026-03-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.75, output: 2.25 }, + limit: { context: 260000, output: 16384 }, + }, + "llama-3.3-70b-instruct": { + id: "llama-3.3-70b-instruct", + name: "Llama-3.3-70B-Instruct", + family: "llama", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-12-06", + last_updated: "2026-03-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.9, output: 0.9 }, + limit: { context: 100000, output: 16384 }, + }, + "qwen3.5-397b-a17b": { + id: "qwen3.5-397b-a17b", + name: "Qwen3.5 397B A17B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-03-17", + last_updated: "2026-03-17", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 3.6 }, + limit: { context: 256000, output: 16384 }, + }, + "devstral-2-123b-instruct-2512": { + id: "devstral-2-123b-instruct-2512", + name: "Devstral 2 123B Instruct (2512)", + family: "devstral", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2026-01-07", + last_updated: "2026-03-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.4, output: 2 }, + limit: { context: 256000, output: 16384 }, + }, + "deepseek-r1-distill-llama-70b": { + id: "deepseek-r1-distill-llama-70b", + name: "DeepSeek R1 Distill Llama 70B", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2025-01-20", + last_updated: "2026-03-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.9, output: 0.9 }, + limit: { context: 32000, output: 8196 }, + }, + "pixtral-12b-2409": { + id: "pixtral-12b-2409", + name: "Pixtral 12B 2409", + family: "pixtral", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-09-25", + last_updated: "2026-03-17", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.2 }, + limit: { context: 128000, output: 4096 }, + }, + "whisper-large-v3": { + id: "whisper-large-v3", + name: "Whisper Large v3", + family: "whisper", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + knowledge: "2023-09", + release_date: "2023-09-01", + last_updated: "2026-03-17", + modalities: { input: ["audio"], output: ["text"] }, + open_weights: true, + cost: { input: 0.003, output: 0 }, + limit: { context: 0, output: 8192 }, + }, + "voxtral-small-24b-2507": { + id: "voxtral-small-24b-2507", + name: "Voxtral Small 24B 2507", + family: "voxtral", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-07-01", + last_updated: "2026-03-17", + modalities: { input: ["text", "audio"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.35 }, + limit: { context: 32000, output: 16384 }, + }, + "gemma-3-27b-it": { + id: "gemma-3-27b-it", + name: "Gemma-3-27B-IT", + family: "gemma", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-12", + release_date: "2024-12-01", + last_updated: "2026-03-17", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 0.5 }, + limit: { context: 40000, output: 8192 }, + }, + "bge-multilingual-gemma2": { + id: "bge-multilingual-gemma2", + name: "BGE Multilingual Gemma2", + family: "gemma", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2024-07-26", + last_updated: "2025-06-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0 }, + limit: { context: 8191, output: 3072 }, + }, + "qwen3-coder-30b-a3b-instruct": { + id: "qwen3-coder-30b-a3b-instruct", + name: "Qwen3-Coder 30B-A3B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-04", + last_updated: "2026-03-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.8 }, + limit: { context: 128000, output: 32768 }, + }, + "mistral-small-3.2-24b-instruct-2506": { + id: "mistral-small-3.2-24b-instruct-2506", + name: "Mistral Small 3.2 24B Instruct (2506)", + family: "mistral-small", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-06-20", + last_updated: "2026-03-17", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.35 }, + limit: { context: 128000, output: 32768 }, + }, + "gpt-oss-120b": { + id: "gpt-oss-120b", + name: "GPT-OSS 120B", + family: "gpt-oss", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-01-01", + last_updated: "2026-03-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 128000, output: 32768 }, + }, + "mistral-nemo-instruct-2407": { + id: "mistral-nemo-instruct-2407", + name: "Mistral Nemo Instruct 2407", + family: "mistral-nemo", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-07-25", + last_updated: "2026-03-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.2 }, + limit: { context: 128000, output: 8192 }, + }, + "llama-3.1-8b-instruct": { + id: "llama-3.1-8b-instruct", + name: "Llama 3.1 8B Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2025-01-01", + last_updated: "2026-03-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.2 }, + limit: { context: 128000, output: 16384 }, + }, + }, + }, + "nano-gpt": { + id: "nano-gpt", + env: ["NANO_GPT_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://nano-gpt.com/api/v1", + name: "NanoGPT", + doc: "https://docs.nano-gpt.com", + models: { + "glm-4-flash": { + id: "glm-4-flash", + name: "GLM-4 Flash", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-08-01", + last_updated: "2024-08-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1003, output: 0.1003 }, + limit: { context: 128000, input: 128000, output: 4096 }, + }, + "Meta-Llama-3-1-8B-Instruct-FP8": { + id: "Meta-Llama-3-1-8B-Instruct-FP8", + name: "Llama 3.1 8B (decentralized)", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.02, output: 0.03 }, + limit: { context: 128000, input: 128000, output: 16384 }, + }, + "claude-opus-4-thinking:32000": { + id: "claude-opus-4-thinking:32000", + name: "Claude 4 Opus Thinking (32K)", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 14.994, output: 75.004 }, + limit: { context: 200000, input: 200000, output: 32000 }, + }, + "gemini-2.5-pro-preview-05-06": { + id: "gemini-2.5-pro-preview-05-06", + name: "Gemini 2.5 Pro Preview 0506", + attachment: true, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-05-06", + last_updated: "2025-05-06", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 10 }, + limit: { context: 1048756, input: 1048756, output: 65536 }, + }, + "grok-3-mini-fast-beta": { + id: "grok-3-mini-fast-beta", + name: "Grok 3 Mini Fast Beta", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-02-17", + last_updated: "2025-02-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.6, output: 4 }, + limit: { context: 131072, input: 131072, output: 131072 }, + }, + "MiniMax-M2": { + id: "MiniMax-M2", + name: "MiniMax M2", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-10-25", + last_updated: "2025-10-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.17, output: 1.53 }, + limit: { context: 200000, input: 200000, output: 131072 }, + }, + "command-a-reasoning-08-2025": { + id: "command-a-reasoning-08-2025", + name: "Cohere Command A (08/2025)", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-08-22", + last_updated: "2025-08-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 10 }, + limit: { context: 256000, input: 256000, output: 8192 }, + }, + brave: { + id: "brave", + name: "Brave (Answers)", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2023-03-02", + last_updated: "2024-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 5 }, + limit: { context: 8192, input: 8192, output: 8192 }, + }, + "exa-research": { + id: "exa-research", + name: "Exa (Research)", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-06-04", + last_updated: "2025-06-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 2.5 }, + limit: { context: 8192, input: 8192, output: 8192 }, + }, + "Llama-3.3-70B-Nova": { + id: "Llama-3.3-70B-Nova", + name: "Llama 3.3 70B Nova", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "gemini-exp-1206": { + id: "gemini-exp-1206", + name: "Gemini 2.0 Pro 1206", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.258, output: 4.998 }, + limit: { context: 2097152, input: 2097152, output: 8192 }, + }, + "claude-opus-4-5-20251101": { + id: "claude-opus-4-5-20251101", + name: "Claude 4.5 Opus", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-11-01", + last_updated: "2025-11-01", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 4.998, output: 25.007 }, + limit: { context: 200000, input: 200000, output: 32000 }, + }, + "auto-model-basic": { + id: "auto-model-basic", + name: "Auto model (Basic)", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-06-01", + last_updated: "2024-06-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 9.996, output: 19.992 }, + limit: { context: 1000000, input: 1000000, output: 1000000 }, + }, + "jamba-mini": { + id: "jamba-mini", + name: "Jamba Mini", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-07-09", + last_updated: "2025-07-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1989, output: 0.408 }, + limit: { context: 256000, input: 256000, output: 4096 }, + }, + "gemini-2.5-flash-lite-preview-09-2025": { + id: "gemini-2.5-flash-lite-preview-09-2025", + name: "Gemini 2.5 Flash Lite Preview (09/2025)", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-09-25", + last_updated: "2025-09-25", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4 }, + limit: { context: 1048756, input: 1048756, output: 65536 }, + }, + "yi-large": { + id: "yi-large", + name: "Yi Large", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-05-13", + last_updated: "2024-05-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 3.196, output: 3.196 }, + limit: { context: 32000, input: 32000, output: 4096 }, + }, + "auto-model-premium": { + id: "auto-model-premium", + name: "Auto model (Premium)", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-06-01", + last_updated: "2024-06-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 9.996, output: 19.992 }, + limit: { context: 1000000, input: 1000000, output: 1000000 }, + }, + "azure-gpt-4o": { + id: "azure-gpt-4o", + name: "Azure gpt-4o", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + release_date: "2024-05-13", + last_updated: "2024-05-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2.499, output: 9.996 }, + limit: { context: 128000, input: 128000, output: 16384 }, + }, + "deepseek-v3-0324": { + id: "deepseek-v3-0324", + name: "DeepSeek Chat 0324", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + release_date: "2025-03-24", + last_updated: "2025-03-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 0.7 }, + limit: { context: 128000, input: 128000, output: 8192 }, + }, + "claude-3-5-haiku-20241022": { + id: "claude-3-5-haiku-20241022", + name: "Claude 3.5 Haiku", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + release_date: "2024-10-22", + last_updated: "2024-10-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.8, output: 4 }, + limit: { context: 200000, input: 200000, output: 8192 }, + }, + "doubao-seed-1-8-251215": { + id: "doubao-seed-1-8-251215", + name: "Doubao Seed 1.8", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-12-15", + last_updated: "2025-12-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.612, output: 6.12 }, + limit: { context: 128000, input: 128000, output: 8192 }, + }, + "doubao-seed-1-6-250615": { + id: "doubao-seed-1-6-250615", + name: "Doubao Seed 1.6", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-06-15", + last_updated: "2025-06-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.204, output: 0.51 }, + limit: { context: 256000, input: 256000, output: 16384 }, + }, + "ernie-x1.1-preview": { + id: "ernie-x1.1-preview", + name: "ERNIE X1.1", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-09-10", + last_updated: "2025-09-10", + modalities: { input: ["text", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 64000, input: 64000, output: 8192 }, + }, + "ernie-5.0-thinking-preview": { + id: "ernie-5.0-thinking-preview", + name: "Ernie 5.0 Thinking Preview", + attachment: true, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-11-18", + last_updated: "2025-11-18", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 2 }, + limit: { context: 128000, input: 128000, output: 16384 }, + }, + "glm-4-air-0111": { + id: "glm-4-air-0111", + name: "GLM 4 Air 0111", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-01-11", + last_updated: "2025-01-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1394, output: 0.1394 }, + limit: { context: 128000, input: 128000, output: 4096 }, + }, + fastgpt: { + id: "fastgpt", + name: "Web Answer", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2023-08-01", + last_updated: "2024-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 7.5, output: 7.5 }, + limit: { context: 32768, input: 32768, output: 32768 }, + }, + "doubao-seed-1-6-thinking-250615": { + id: "doubao-seed-1-6-thinking-250615", + name: "Doubao Seed 1.6 Thinking", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-06-15", + last_updated: "2025-06-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.204, output: 2.04 }, + limit: { context: 256000, input: 256000, output: 16384 }, + }, + "gemini-2.0-flash-001": { + id: "gemini-2.0-flash-001", + name: "Gemini 2.0 Flash", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + release_date: "2024-12-11", + last_updated: "2024-12-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1003, output: 0.408 }, + limit: { context: 1000000, input: 1000000, output: 8192 }, + }, + "claude-opus-4-1-thinking:32000": { + id: "claude-opus-4-1-thinking:32000", + name: "Claude 4.1 Opus Thinking (32K)", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 14.994, output: 75.004 }, + limit: { context: 200000, input: 200000, output: 32000 }, + }, + "Llama-3.3-70B-RAWMAW": { + id: "Llama-3.3-70B-RAWMAW", + name: "Llama 3.3 70B RAWMAW", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "GLM-4.5-Air-Derestricted-Steam": { + id: "GLM-4.5-Air-Derestricted-Steam", + name: "GLM 4.5 Air Derestricted Steam", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-07-28", + last_updated: "2025-07-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 220600, input: 220600, output: 65536 }, + }, + "claude-3-5-sonnet-20241022": { + id: "claude-3-5-sonnet-20241022", + name: "Claude 3.5 Sonnet", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + release_date: "2025-08-26", + last_updated: "2025-08-26", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2.992, output: 14.994 }, + limit: { context: 200000, input: 200000, output: 8192 }, + }, + "yi-medium-200k": { + id: "yi-medium-200k", + name: "Yi Medium 200k", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-03-01", + last_updated: "2024-03-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2.499, output: 2.499 }, + limit: { context: 200000, input: 200000, output: 4096 }, + }, + "Gemma-3-27B-ArliAI-RPMax-v3": { + id: "Gemma-3-27B-ArliAI-RPMax-v3", + name: "Gemma 3 27B RPMax v3", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-07-03", + last_updated: "2025-07-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "phi-4-mini-instruct": { + id: "phi-4-mini-instruct", + name: "Phi 4 Mini", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-07-26", + last_updated: "2025-07-26", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.17, output: 0.68 }, + limit: { context: 128000, input: 128000, output: 16384 }, + }, + "Llama-3.3+(3v3.3)-70B-TenyxChat-DaybreakStorywriter": { + id: "Llama-3.3+(3v3.3)-70B-TenyxChat-DaybreakStorywriter", + name: "Llama 3.3+ 70B TenyxChat DaybreakStorywriter", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "ernie-x1-32k": { + id: "ernie-x1-32k", + name: "Ernie X1 32k", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-05-08", + last_updated: "2025-05-08", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.33, output: 1.32 }, + limit: { context: 32000, input: 32000, output: 16384 }, + }, + "deepseek-chat": { + id: "deepseek-chat", + name: "DeepSeek V3/Deepseek Chat", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + release_date: "2025-02-27", + last_updated: "2025-02-27", + modalities: { input: ["text", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 0.7 }, + limit: { context: 128000, input: 128000, output: 8192 }, + }, + "glm-z1-air": { + id: "glm-z1-air", + name: "GLM Z1 Air", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + release_date: "2025-04-15", + last_updated: "2025-04-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.07, output: 0.07 }, + limit: { context: 32000, input: 32000, output: 16384 }, + }, + "claude-3-7-sonnet-thinking:128000": { + id: "claude-3-7-sonnet-thinking:128000", + name: "Claude 3.7 Sonnet Thinking (128K)", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-02-24", + last_updated: "2025-02-24", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2.992, output: 14.994 }, + limit: { context: 200000, input: 200000, output: 64000 }, + }, + "glm-4-air": { + id: "glm-4-air", + name: "GLM-4 Air", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-06-05", + last_updated: "2024-06-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2006, output: 0.2006 }, + limit: { context: 128000, input: 128000, output: 4096 }, + }, + "Llama-3.3-70B-MiraiFanfare": { + id: "Llama-3.3-70B-MiraiFanfare", + name: "Llama 3.3 70b Mirai Fanfare", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-07-26", + last_updated: "2025-07-26", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.493, output: 0.493 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "gemini-2.0-flash-thinking-exp-01-21": { + id: "gemini-2.0-flash-thinking-exp-01-21", + name: "Gemini 2.0 Flash Thinking 0121", + attachment: true, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-01-21", + last_updated: "2025-01-21", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 1.003 }, + limit: { context: 1000000, input: 1000000, output: 8192 }, + }, + "Magistral-Small-2506": { + id: "Magistral-Small-2506", + name: "Magistral Small 2506", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-09-25", + last_updated: "2025-09-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 1.4 }, + limit: { context: 32768, input: 32768, output: 32768 }, + }, + "doubao-1.5-pro-32k": { + id: "doubao-1.5-pro-32k", + name: "Doubao 1.5 Pro 32k", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-01-22", + last_updated: "2025-01-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1343, output: 0.3349 }, + limit: { context: 32000, input: 32000, output: 8192 }, + }, + "venice-uncensored:web": { + id: "venice-uncensored:web", + name: "Venice Uncensored Web", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-05-01", + last_updated: "2024-05-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 0.4 }, + limit: { context: 80000, input: 80000, output: 16384 }, + }, + "glm-4": { + id: "glm-4", + name: "GLM-4", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-01-16", + last_updated: "2024-01-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 14.994, output: 14.994 }, + limit: { context: 128000, input: 128000, output: 4096 }, + }, + "qwen-max": { + id: "qwen-max", + name: "Qwen 2.5 Max", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-04-03", + last_updated: "2024-04-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.5997, output: 6.392 }, + limit: { context: 32000, input: 32000, output: 8192 }, + }, + "qwen3-vl-235b-a22b-instruct-original": { + id: "qwen3-vl-235b-a22b-instruct-original", + name: "Qwen3 VL 235B A22B Instruct Original", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-09-25", + last_updated: "2025-09-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 1.2 }, + limit: { context: 32768, input: 32768, output: 32768 }, + }, + "jamba-large-1.6": { + id: "jamba-large-1.6", + name: "Jamba Large 1.6", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-03-12", + last_updated: "2025-03-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.989, output: 7.99 }, + limit: { context: 256000, input: 256000, output: 4096 }, + }, + "qwen-plus": { + id: "qwen-plus", + name: "Qwen Plus", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2024-01-25", + last_updated: "2024-01-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3995, output: 1.2002 }, + limit: { context: 995904, input: 995904, output: 32768 }, + }, + "qwen25-vl-72b-instruct": { + id: "qwen25-vl-72b-instruct", + name: "Qwen25 VL 72b", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-05-10", + last_updated: "2025-05-10", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.69989, output: 0.69989 }, + limit: { context: 32000, input: 32000, output: 32768 }, + }, + "claude-sonnet-4-thinking:64000": { + id: "claude-sonnet-4-thinking:64000", + name: "Claude 4 Sonnet Thinking (64K)", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2.992, output: 14.994 }, + limit: { context: 1000000, input: 1000000, output: 64000 }, + }, + "gemini-3-pro-preview": { + id: "gemini-3-pro-preview", + name: "Gemini 3 Pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-11-18", + last_updated: "2025-11-18", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 12 }, + limit: { context: 1048756, input: 1048756, output: 65536 }, + }, + "Llama-3.3+(3.1v3.3)-70B-New-Dawn-v1.1": { + id: "Llama-3.3+(3.1v3.3)-70B-New-Dawn-v1.1", + name: "Llama 3.3+ 70B New Dawn v1.1", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "GLM-4.5-Air-Derestricted-Iceblink-ReExtract": { + id: "GLM-4.5-Air-Derestricted-Iceblink-ReExtract", + name: "GLM 4.5 Air Derestricted Iceblink ReExtract", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-12-12", + last_updated: "2025-12-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 131072, input: 131072, output: 98304 }, + }, + "universal-summarizer": { + id: "universal-summarizer", + name: "Universal Summarizer", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2023-05-01", + last_updated: "2024-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 30, output: 30 }, + limit: { context: 32768, input: 32768, output: 32768 }, + }, + "claude-sonnet-4-thinking:32768": { + id: "claude-sonnet-4-thinking:32768", + name: "Claude 4 Sonnet Thinking (32K)", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2.992, output: 14.994 }, + limit: { context: 1000000, input: 1000000, output: 64000 }, + }, + "sarvan-medium": { + id: "sarvan-medium", + name: "Sarvam Medium", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 0.75 }, + limit: { context: 128000, input: 128000, output: 16384 }, + }, + "claude-3-7-sonnet-thinking:8192": { + id: "claude-3-7-sonnet-thinking:8192", + name: "Claude 3.7 Sonnet Thinking (8K)", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-02-24", + last_updated: "2025-02-24", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2.992, output: 14.994 }, + limit: { context: 200000, input: 200000, output: 64000 }, + }, + "gemini-2.5-flash-preview-05-20": { + id: "gemini-2.5-flash-preview-05-20", + name: "Gemini 2.5 Flash 0520", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-05-20", + last_updated: "2025-05-20", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 1048000, input: 1048000, output: 65536 }, + }, + "GLM-4.5-Air-Derestricted-Iceblink-v2-ReExtract": { + id: "GLM-4.5-Air-Derestricted-Iceblink-v2-ReExtract", + name: "GLM 4.5 Air Derestricted Iceblink v2 ReExtract", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-12-12", + last_updated: "2025-12-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 131072, input: 131072, output: 65536 }, + }, + "Llama-3.3-70B-Fallen-v1": { + id: "Llama-3.3-70B-Fallen-v1", + name: "Llama 3.3 70B Fallen v1", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "qwen3-vl-235b-a22b-thinking": { + id: "qwen3-vl-235b-a22b-thinking", + name: "Qwen3 VL 235B A22B Thinking", + attachment: true, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-08-26", + last_updated: "2025-08-26", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 6 }, + limit: { context: 32768, input: 32768, output: 32768 }, + }, + "claude-3-7-sonnet-thinking:32768": { + id: "claude-3-7-sonnet-thinking:32768", + name: "Claude 3.7 Sonnet Thinking (32K)", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-07-15", + last_updated: "2025-07-15", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2.992, output: 14.994 }, + limit: { context: 200000, input: 200000, output: 64000 }, + }, + "claude-3-7-sonnet-thinking:1024": { + id: "claude-3-7-sonnet-thinking:1024", + name: "Claude 3.7 Sonnet Thinking (1K)", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-02-24", + last_updated: "2025-02-24", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2.992, output: 14.994 }, + limit: { context: 200000, input: 200000, output: 64000 }, + }, + "claude-sonnet-4-5-20250929": { + id: "claude-sonnet-4-5-20250929", + name: "Claude Sonnet 4.5", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2.992, output: 14.994 }, + limit: { context: 1000000, input: 1000000, output: 64000 }, + }, + "Llama-3.3-70B-Vulpecula-R1": { + id: "Llama-3.3-70B-Vulpecula-R1", + name: "Llama 3.3 70B Vulpecula R1", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "claude-sonnet-4-thinking:8192": { + id: "claude-sonnet-4-thinking:8192", + name: "Claude 4 Sonnet Thinking (8K)", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2.992, output: 14.994 }, + limit: { context: 1000000, input: 1000000, output: 64000 }, + }, + "gemini-2.5-pro": { + id: "gemini-2.5-pro", + name: "Gemini 2.5 Pro", + attachment: true, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-06-05", + last_updated: "2025-06-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 10 }, + limit: { context: 1048756, input: 1048756, output: 65536 }, + }, + "Llama-3.3-70B-Ignition-v0.1": { + id: "Llama-3.3-70B-Ignition-v0.1", + name: "Llama 3.3 70B Ignition v0.1", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "glm-4-plus-0111": { + id: "glm-4-plus-0111", + name: "GLM 4 Plus 0111", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-02-19", + last_updated: "2025-02-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 9.996, output: 9.996 }, + limit: { context: 128000, input: 128000, output: 4096 }, + }, + "KAT-Coder-Air-V1": { + id: "KAT-Coder-Air-V1", + name: "KAT Coder Air V1", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-10-28", + last_updated: "2025-10-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.2 }, + limit: { context: 128000, input: 128000, output: 32768 }, + }, + "deepseek-r1-sambanova": { + id: "deepseek-r1-sambanova", + name: "DeepSeek R1 Fast", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-02-20", + last_updated: "2025-02-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 4.998, output: 6.987 }, + limit: { context: 128000, input: 128000, output: 4096 }, + }, + "deepseek-r1": { + id: "deepseek-r1", + name: "DeepSeek R1", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-01-20", + last_updated: "2025-01-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 1.7 }, + limit: { context: 128000, input: 128000, output: 8192 }, + }, + "doubao-1-5-thinking-pro-250415": { + id: "doubao-1-5-thinking-pro-250415", + name: "Doubao 1.5 Thinking Pro", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-04-17", + last_updated: "2025-04-17", + modalities: { input: ["text", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.6, output: 2.4 }, + limit: { context: 128000, input: 128000, output: 16384 }, + }, + "sonar-pro": { + id: "sonar-pro", + name: "Perplexity Pro", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-02-19", + last_updated: "2025-02-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2.992, output: 14.994 }, + limit: { context: 200000, input: 200000, output: 128000 }, + }, + "Gemma-3-27B-it-Abliterated": { + id: "Gemma-3-27B-it-Abliterated", + name: "Gemma 3 27B IT Abliterated", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-07-03", + last_updated: "2025-07-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.42, output: 0.42 }, + limit: { context: 32768, input: 32768, output: 96000 }, + }, + "deepseek-chat-cheaper": { + id: "deepseek-chat-cheaper", + name: "DeepSeek V3/Chat Cheaper", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + release_date: "2025-04-15", + last_updated: "2025-04-15", + modalities: { input: ["text", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 0.7 }, + limit: { context: 128000, input: 128000, output: 8192 }, + }, + "gemini-2.0-pro-exp-02-05": { + id: "gemini-2.0-pro-exp-02-05", + name: "Gemini 2.0 Pro 0205", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-02-05", + last_updated: "2025-02-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.989, output: 7.956 }, + limit: { context: 2097152, input: 2097152, output: 8192 }, + }, + "azure-gpt-4o-mini": { + id: "azure-gpt-4o-mini", + name: "Azure gpt-4o-mini", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + release_date: "2024-07-18", + last_updated: "2024-07-18", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1496, output: 0.595 }, + limit: { context: 128000, input: 128000, output: 16384 }, + }, + "Llama-3.3-70B-MS-Nevoria": { + id: "Llama-3.3-70B-MS-Nevoria", + name: "Llama 3.3 70B MS Nevoria", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "claude-opus-4-thinking": { + id: "claude-opus-4-thinking", + name: "Claude 4 Opus Thinking", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-07-15", + last_updated: "2025-07-15", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 14.994, output: 75.004 }, + limit: { context: 200000, input: 200000, output: 32000 }, + }, + "Llama-3.3-70B-Sapphira-0.1": { + id: "Llama-3.3-70B-Sapphira-0.1", + name: "Llama 3.3 70B Sapphira 0.1", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "doubao-seed-code-preview-latest": { + id: "doubao-seed-code-preview-latest", + name: "Doubao Seed Code Preview", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4 }, + limit: { context: 256000, input: 256000, output: 16384 }, + }, + "qwen-3.6-plus": { + id: "qwen-3.6-plus", + name: "Qwen 3.6 Plus", + family: "qwen3.6", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2026-04-02", + last_updated: "2026-04-02", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.45, output: 2.7 }, + limit: { context: 991800, output: 65536 }, + }, + "Llama-3.3-70B-ArliAI-RPMax-v1.4": { + id: "Llama-3.3-70B-ArliAI-RPMax-v1.4", + name: "Llama 3.3 70B RPMax v1.4", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "mistral-small-31-24b-instruct": { + id: "mistral-small-31-24b-instruct", + name: "Mistral Small 31 24b Instruct", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-04-15", + last_updated: "2025-04-15", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.3 }, + limit: { context: 128000, input: 128000, output: 131072 }, + }, + "glm-4.1v-thinking-flashx": { + id: "glm-4.1v-thinking-flashx", + name: "GLM 4.1V Thinking FlashX", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-07-09", + last_updated: "2025-07-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 0.3 }, + limit: { context: 64000, input: 64000, output: 8192 }, + }, + "hunyuan-t1-latest": { + id: "hunyuan-t1-latest", + name: "Hunyuan T1", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-03-22", + last_updated: "2025-03-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.17, output: 0.66 }, + limit: { context: 256000, input: 256000, output: 16384 }, + }, + "doubao-1-5-thinking-vision-pro-250428": { + id: "doubao-1-5-thinking-vision-pro-250428", + name: "Doubao 1.5 Thinking Vision Pro", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-05-15", + last_updated: "2025-05-15", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.55, output: 1.43 }, + limit: { context: 128000, input: 128000, output: 16384 }, + }, + "asi1-mini": { + id: "asi1-mini", + name: "ASI1 Mini", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-03-25", + last_updated: "2025-03-25", + modalities: { input: ["text", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 1 }, + limit: { context: 128000, input: 128000, output: 16384 }, + }, + "ernie-5.0-thinking-latest": { + id: "ernie-5.0-thinking-latest", + name: "Ernie 5.0 Thinking", + attachment: true, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-11-18", + last_updated: "2025-11-18", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 2 }, + limit: { context: 128000, input: 128000, output: 16384 }, + }, + "Llama-3.3-70B-Incandescent-Malevolence": { + id: "Llama-3.3-70B-Incandescent-Malevolence", + name: "Llama 3.3 70B Incandescent Malevolence", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "Llama-3.3-70B-Damascus-R1": { + id: "Llama-3.3-70B-Damascus-R1", + name: "Damascus R1", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "Gemma-3-27B-Nidum-Uncensored": { + id: "Gemma-3-27B-Nidum-Uncensored", + name: "Gemma 3 27B Nidum Uncensored", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-08-08", + last_updated: "2025-08-08", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 96000 }, + }, + "gemini-2.5-flash-lite-preview-09-2025-thinking": { + id: "gemini-2.5-flash-lite-preview-09-2025-thinking", + name: "Gemini 2.5 Flash Lite Preview (09/2025) – Thinking", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-09-25", + last_updated: "2025-09-25", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4 }, + limit: { context: 1048756, input: 1048756, output: 65536 }, + }, + "doubao-seed-2-0-pro-260215": { + id: "doubao-seed-2-0-pro-260215", + name: "Doubao Seed 2.0 Pro", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2026-02-14", + last_updated: "2026-02-14", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.782, output: 3.876 }, + limit: { context: 256000, input: 256000, output: 128000 }, + }, + "gemini-3-pro-image-preview": { + id: "gemini-3-pro-image-preview", + name: "Gemini 3 Pro Image", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-11-18", + last_updated: "2025-11-18", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 12 }, + limit: { context: 1048756, input: 1048756, output: 65536 }, + }, + "Gemma-3-27B-CardProjector-v4": { + id: "Gemma-3-27B-CardProjector-v4", + name: "Gemma 3 27B CardProjector v4", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-03-10", + last_updated: "2025-03-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "jamba-mini-1.7": { + id: "jamba-mini-1.7", + name: "Jamba Mini 1.7", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-07-09", + last_updated: "2025-07-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1989, output: 0.408 }, + limit: { context: 256000, input: 256000, output: 4096 }, + }, + "Llama-3.3-70B-Forgotten-Safeword-3.6": { + id: "Llama-3.3-70B-Forgotten-Safeword-3.6", + name: "Llama 3.3 70B Forgotten Safeword 3.6", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "doubao-1-5-thinking-pro-vision-250415": { + id: "doubao-1-5-thinking-pro-vision-250415", + name: "Doubao 1.5 Thinking Pro Vision", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-04-15", + last_updated: "2025-04-15", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.6, output: 2.4 }, + limit: { context: 128000, input: 128000, output: 16384 }, + }, + "gemini-2.5-pro-preview-06-05": { + id: "gemini-2.5-pro-preview-06-05", + name: "Gemini 2.5 Pro Preview 0605", + attachment: true, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-06-05", + last_updated: "2025-06-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 10 }, + limit: { context: 1048756, input: 1048756, output: 65536 }, + }, + "gemini-2.0-pro-reasoner": { + id: "gemini-2.0-pro-reasoner", + name: "Gemini 2.0 Pro Reasoner", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-02-05", + last_updated: "2025-02-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.292, output: 4.998 }, + limit: { context: 128000, input: 128000, output: 65536 }, + }, + "doubao-seed-2-0-lite-260215": { + id: "doubao-seed-2-0-lite-260215", + name: "Doubao Seed 2.0 Lite", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2026-02-14", + last_updated: "2026-02-14", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1462, output: 0.8738 }, + limit: { context: 256000, input: 256000, output: 32000 }, + }, + "gemini-2.5-flash-lite-preview-06-17": { + id: "gemini-2.5-flash-lite-preview-06-17", + name: "Gemini 2.5 Flash Lite Preview", + attachment: true, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-06-17", + last_updated: "2025-06-17", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 1048756, input: 1048756, output: 65536 }, + }, + "sonar-deep-research": { + id: "sonar-deep-research", + name: "Perplexity Deep Research", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-02-25", + last_updated: "2025-02-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 3.4, output: 13.6 }, + limit: { context: 60000, input: 60000, output: 128000 }, + }, + "Gemma-3-27B-it": { + id: "Gemma-3-27B-it", + name: "Gemma 3 27B IT", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-03-10", + last_updated: "2025-03-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "Llama-3.3-70B-GeneticLemonade-Unleashed-v3": { + id: "Llama-3.3-70B-GeneticLemonade-Unleashed-v3", + name: "Llama 3.3 70B GeneticLemonade Unleashed v3", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "Gemma-3-27B-Glitter": { + id: "Gemma-3-27B-Glitter", + name: "Gemma 3 27B Glitter", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-03-10", + last_updated: "2025-03-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "Llama-3.3-70B-The-Omega-Directive-Unslop-v2.1": { + id: "Llama-3.3-70B-The-Omega-Directive-Unslop-v2.1", + name: "Llama 3.3 70B Omega Directive Unslop v2.1", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "qwen3-30b-a3b-instruct-2507": { + id: "qwen3-30b-a3b-instruct-2507", + name: "Qwen3 30B A3B Instruct 2507", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-02-20", + last_updated: "2025-02-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5 }, + limit: { context: 256000, input: 256000, output: 32768 }, + }, + "gemini-2.5-flash-preview-09-2025-thinking": { + id: "gemini-2.5-flash-preview-09-2025-thinking", + name: "Gemini 2.5 Flash Preview (09/2025) – Thinking", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-09-25", + last_updated: "2025-09-25", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 2.5 }, + limit: { context: 1048756, input: 1048756, output: 65536 }, + }, + "gemini-2.5-flash": { + id: "gemini-2.5-flash", + name: "Gemini 2.5 Flash", + attachment: true, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-06-05", + last_updated: "2025-06-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 2.5 }, + limit: { context: 1048756, input: 1048756, output: 65536 }, + }, + deepclaude: { + id: "deepclaude", + name: "DeepClaude", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-02-01", + last_updated: "2025-02-01", + modalities: { input: ["text", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15 }, + limit: { context: 128000, input: 128000, output: 8192 }, + }, + "ernie-4.5-8k-preview": { + id: "ernie-4.5-8k-preview", + name: "Ernie 4.5 8k Preview", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-03-25", + last_updated: "2025-03-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.66, output: 2.6 }, + limit: { context: 8000, input: 8000, output: 16384 }, + }, + "doubao-seed-2-0-mini-260215": { + id: "doubao-seed-2-0-mini-260215", + name: "Doubao Seed 2.0 Mini", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2026-02-14", + last_updated: "2026-02-14", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.0493, output: 0.4845 }, + limit: { context: 256000, input: 256000, output: 32000 }, + }, + "gemini-3-pro-preview-thinking": { + id: "gemini-3-pro-preview-thinking", + name: "Gemini 3 Pro Thinking", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-11-18", + last_updated: "2025-11-18", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 12 }, + limit: { context: 1048756, input: 1048756, output: 65536 }, + }, + "Llama-3.3-70B-GeneticLemonade-Opus": { + id: "Llama-3.3-70B-GeneticLemonade-Opus", + name: "Llama 3.3 70B GeneticLemonade Opus", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "v0-1.5-lg": { + id: "v0-1.5-lg", + name: "v0 1.5 LG", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-07-04", + last_updated: "2025-07-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75 }, + limit: { context: 1000000, input: 1000000, output: 64000 }, + }, + "ernie-4.5-turbo-128k": { + id: "ernie-4.5-turbo-128k", + name: "Ernie 4.5 Turbo 128k", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-05-08", + last_updated: "2025-05-08", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.132, output: 0.55 }, + limit: { context: 128000, input: 128000, output: 16384 }, + }, + "KAT-Coder-Pro-V1": { + id: "KAT-Coder-Pro-V1", + name: "KAT Coder Pro V1", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-10-28", + last_updated: "2025-10-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.5, output: 6 }, + limit: { context: 256000, input: 256000, output: 32768 }, + }, + "claude-3-5-sonnet-20240620": { + id: "claude-3-5-sonnet-20240620", + name: "Claude 3.5 Sonnet Old", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + release_date: "2024-06-20", + last_updated: "2024-06-20", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2.992, output: 14.994 }, + limit: { context: 200000, input: 200000, output: 8192 }, + }, + "claude-opus-4-1-thinking:8192": { + id: "claude-opus-4-1-thinking:8192", + name: "Claude 4.1 Opus Thinking (8K)", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 14.994, output: 75.004 }, + limit: { context: 200000, input: 200000, output: 32000 }, + }, + "gemini-2.0-flash-exp-image-generation": { + id: "gemini-2.0-flash-exp-image-generation", + name: "Gemini Text + Image", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-02-19", + last_updated: "2025-02-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.8 }, + limit: { context: 32767, input: 32767, output: 8192 }, + }, + "Llama-3.3-70B-Magnum-v4-SE": { + id: "Llama-3.3-70B-Magnum-v4-SE", + name: "Llama 3.3 70B Magnum v4 SE", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "glm-zero-preview": { + id: "glm-zero-preview", + name: "GLM Zero Preview", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-01", + last_updated: "2024-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.802, output: 1.802 }, + limit: { context: 8000, input: 8000, output: 4096 }, + }, + "study_gpt-chatgpt-4o-latest": { + id: "study_gpt-chatgpt-4o-latest", + name: "Study Mode", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-05-13", + last_updated: "2024-05-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 4.998, output: 14.994 }, + limit: { context: 200000, input: 200000, output: 16384 }, + }, + "glm-4-airx": { + id: "glm-4-airx", + name: "GLM-4 AirX", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-06-05", + last_updated: "2024-06-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2.006, output: 2.006 }, + limit: { context: 8000, input: 8000, output: 4096 }, + }, + "step-2-mini": { + id: "step-2-mini", + name: "Step-2 Mini", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-07-05", + last_updated: "2024-07-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2006, output: 0.408 }, + limit: { context: 8000, input: 8000, output: 4096 }, + }, + "gemini-2.5-flash-preview-04-17:thinking": { + id: "gemini-2.5-flash-preview-04-17:thinking", + name: "Gemini 2.5 Flash Preview Thinking", + attachment: true, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-04-17", + last_updated: "2025-04-17", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 3.5 }, + limit: { context: 1048756, input: 1048756, output: 65536 }, + }, + "Llama-3.3-70B-Mokume-Gane-R1": { + id: "Llama-3.3-70B-Mokume-Gane-R1", + name: "Llama 3.3 70B Mokume Gane R1", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "deepseek-reasoner": { + id: "deepseek-reasoner", + name: "DeepSeek Reasoner", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-01-20", + last_updated: "2025-01-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 1.7 }, + limit: { context: 64000, input: 64000, output: 65536 }, + }, + "glm-z1-airx": { + id: "glm-z1-airx", + name: "GLM Z1 AirX", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + release_date: "2025-04-15", + last_updated: "2025-04-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.7, output: 0.7 }, + limit: { context: 32000, input: 32000, output: 16384 }, + }, + "jamba-mini-1.6": { + id: "jamba-mini-1.6", + name: "Jamba Mini 1.6", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-03-01", + last_updated: "2025-03-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1989, output: 0.408 }, + limit: { context: 256000, input: 256000, output: 4096 }, + }, + "claude-opus-4-1-thinking": { + id: "claude-opus-4-1-thinking", + name: "Claude 4.1 Opus Thinking", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 14.994, output: 75.004 }, + limit: { context: 200000, input: 200000, output: 32000 }, + }, + "grok-3-beta": { + id: "grok-3-beta", + name: "Grok 3 Beta", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15 }, + limit: { context: 131072, input: 131072, output: 131072 }, + }, + "Llama-3.3-70B-Legion-V2.1": { + id: "Llama-3.3-70B-Legion-V2.1", + name: "Llama 3.3 70B Legion V2.1", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + sonar: { + id: "sonar", + name: "Perplexity Simple", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-02-19", + last_updated: "2025-02-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.003, output: 1.003 }, + limit: { context: 127000, input: 127000, output: 128000 }, + }, + "z-image-turbo": { + id: "z-image-turbo", + name: "Z Image Turbo", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2025-11-27", + last_updated: "2025-11-27", + modalities: { input: ["text"], output: ["image"] }, + open_weights: false, + limit: { context: 0, output: 0 }, + }, + "GLM-4.5-Air-Derestricted-Iceblink-v2": { + id: "GLM-4.5-Air-Derestricted-Iceblink-v2", + name: "GLM 4.5 Air Derestricted Iceblink v2", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-07-28", + last_updated: "2025-07-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 158600, input: 158600, output: 65536 }, + }, + "jamba-large": { + id: "jamba-large", + name: "Jamba Large", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-07-09", + last_updated: "2025-07-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.989, output: 7.99 }, + limit: { context: 256000, input: 256000, output: 4096 }, + }, + "claude-3-7-sonnet-reasoner": { + id: "claude-3-7-sonnet-reasoner", + name: "Claude 3.7 Sonnet Reasoner", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-03-29", + last_updated: "2025-03-29", + modalities: { input: ["text", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15 }, + limit: { context: 128000, input: 128000, output: 8192 }, + }, + "ernie-4.5-turbo-vl-32k": { + id: "ernie-4.5-turbo-vl-32k", + name: "Ernie 4.5 Turbo VL 32k", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-05-08", + last_updated: "2025-05-08", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.495, output: 1.43 }, + limit: { context: 32000, input: 32000, output: 16384 }, + }, + "Mistral-Nemo-12B-Instruct-2407": { + id: "Mistral-Nemo-12B-Instruct-2407", + name: "Mistral Nemo 12B Instruct 2407", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-07-18", + last_updated: "2024-07-18", + modalities: { input: ["text", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.01, output: 0.01 }, + limit: { context: 16384, input: 16384, output: 16384 }, + }, + "doubao-seed-1-6-flash-250615": { + id: "doubao-seed-1-6-flash-250615", + name: "Doubao Seed 1.6 Flash", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-06-15", + last_updated: "2025-06-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.0374, output: 0.374 }, + limit: { context: 256000, input: 256000, output: 16384 }, + }, + "qwq-32b": { + id: "qwq-32b", + name: "Qwen: QwQ 32B", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-04-15", + last_updated: "2025-04-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25599999, output: 0.30499999 }, + limit: { context: 128000, input: 128000, output: 32768 }, + }, + "Llama-3.3-70B-Strawberrylemonade-v1.2": { + id: "Llama-3.3-70B-Strawberrylemonade-v1.2", + name: "Llama 3.3 70B StrawberryLemonade v1.2", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "gemini-2.5-flash-preview-04-17": { + id: "gemini-2.5-flash-preview-04-17", + name: "Gemini 2.5 Flash Preview", + attachment: true, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-04-17", + last_updated: "2025-04-17", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 1048756, input: 1048756, output: 65536 }, + }, + "ernie-x1-turbo-32k": { + id: "ernie-x1-turbo-32k", + name: "Ernie X1 Turbo 32k", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-05-08", + last_updated: "2025-05-08", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.165, output: 0.66 }, + limit: { context: 32000, input: 32000, output: 16384 }, + }, + "deepseek-math-v2": { + id: "deepseek-math-v2", + name: "DeepSeek Math V2", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-12-03", + last_updated: "2025-12-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.6, output: 2.2 }, + limit: { context: 128000, input: 128000, output: 65536 }, + }, + "Llama-3.3-70B-Electranova-v1.0": { + id: "Llama-3.3-70B-Electranova-v1.0", + name: "Llama 3.3 70B Electranova v1.0", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "Llama-3.3-70B-ArliAI-RPMax-v2": { + id: "Llama-3.3-70B-ArliAI-RPMax-v2", + name: "Llama 3.3 70B ArliAI RPMax v2", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-08-08", + last_updated: "2025-08-08", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "qwen-image": { + id: "qwen-image", + name: "Qwen Image", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["image"] }, + open_weights: false, + limit: { context: 0, output: 0 }, + }, + "Llama-3.3-70B-Cu-Mai-R1": { + id: "Llama-3.3-70B-Cu-Mai-R1", + name: "Llama 3.3 70B Cu Mai R1", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "GLM-4.5-Air-Derestricted-Iceblink": { + id: "GLM-4.5-Air-Derestricted-Iceblink", + name: "GLM 4.5 Air Derestricted Iceblink", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-07-28", + last_updated: "2025-07-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 131072, input: 131072, output: 98304 }, + }, + "Llama-3.3-70B-Bigger-Body": { + id: "Llama-3.3-70B-Bigger-Body", + name: "Llama 3.3 70B Bigger Body", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "Llama-3.3+(3.1v3.3)-70B-Hanami-x1": { + id: "Llama-3.3+(3.1v3.3)-70B-Hanami-x1", + name: "Llama 3.3+ 70B Hanami x1", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "hunyuan-turbos-20250226": { + id: "hunyuan-turbos-20250226", + name: "Hunyuan Turbo S", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-02-27", + last_updated: "2025-02-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.187, output: 0.374 }, + limit: { context: 24000, input: 24000, output: 8192 }, + }, + "gemini-2.5-flash-preview-09-2025": { + id: "gemini-2.5-flash-preview-09-2025", + name: "Gemini 2.5 Flash Preview (09/2025)", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-09-25", + last_updated: "2025-09-25", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 2.5 }, + limit: { context: 1048756, input: 1048756, output: 65536 }, + }, + "GLM-4.6-Derestricted-v5": { + id: "GLM-4.6-Derestricted-v5", + name: "GLM 4.6 Derestricted v5", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-12-23", + last_updated: "2025-12-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 1.5 }, + limit: { context: 131072, input: 131072, output: 8192 }, + }, + "glm-4-plus": { + id: "glm-4-plus", + name: "GLM-4 Plus", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-08-01", + last_updated: "2024-08-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 7.497, output: 7.497 }, + limit: { context: 128000, input: 128000, output: 4096 }, + }, + "Gemma-3-27B-Big-Tiger-v3": { + id: "Gemma-3-27B-Big-Tiger-v3", + name: "Gemma 3 27B Big Tiger v3", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-08-08", + last_updated: "2025-08-08", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "brave-research": { + id: "brave-research", + name: "Brave (Research)", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2023-03-02", + last_updated: "2024-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 5 }, + limit: { context: 16384, input: 16384, output: 16384 }, + }, + hidream: { + id: "hidream", + name: "Hidream", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2024-01-01", + last_updated: "2024-01-01", + modalities: { input: ["text"], output: ["image"] }, + open_weights: false, + limit: { context: 0, output: 0 }, + }, + "qwen3-max-2026-01-23": { + id: "qwen3-max-2026-01-23", + name: "Qwen3 Max 2026-01-23", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2026-01-26", + last_updated: "2026-01-26", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.2002, output: 6.001 }, + limit: { context: 256000, input: 256000, output: 32768 }, + }, + "claude-opus-4-1-20250805": { + id: "claude-opus-4-1-20250805", + name: "Claude 4.1 Opus", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 14.994, output: 75.004 }, + limit: { context: 200000, input: 200000, output: 32000 }, + }, + "claude-haiku-4-5-20251001": { + id: "claude-haiku-4-5-20251001", + name: "Claude Haiku 4.5", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + release_date: "2025-10-15", + last_updated: "2025-10-15", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 5 }, + limit: { context: 200000, input: 200000, output: 64000 }, + }, + "MiniMax-M1": { + id: "MiniMax-M1", + name: "MiniMax M1", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-06-16", + last_updated: "2025-06-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1394, output: 1.3328 }, + limit: { context: 1000000, input: 1000000, output: 131072 }, + }, + "gemini-2.5-flash-nothinking": { + id: "gemini-2.5-flash-nothinking", + name: "Gemini 2.5 Flash (No Thinking)", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-06-05", + last_updated: "2025-06-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 2.5 }, + limit: { context: 1048756, input: 1048756, output: 65536 }, + }, + "exa-research-pro": { + id: "exa-research-pro", + name: "Exa (Research Pro)", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-06-04", + last_updated: "2025-06-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 2.5 }, + limit: { context: 16384, input: 16384, output: 16384 }, + }, + "grok-3-fast-beta": { + id: "grok-3-fast-beta", + name: "Grok 3 Fast Beta", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-02-17", + last_updated: "2025-02-17", + modalities: { input: ["text", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25 }, + limit: { context: 131072, input: 131072, output: 131072 }, + }, + "claude-opus-4-5-20251101:thinking": { + id: "claude-opus-4-5-20251101:thinking", + name: "Claude 4.5 Opus Thinking", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-11-01", + last_updated: "2025-11-01", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 4.998, output: 25.007 }, + limit: { context: 200000, input: 200000, output: 32000 }, + }, + "gemini-2.5-pro-exp-03-25": { + id: "gemini-2.5-pro-exp-03-25", + name: "Gemini 2.5 Pro Experimental 0325", + attachment: true, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-03-25", + last_updated: "2025-03-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 10 }, + limit: { context: 1048756, input: 1048756, output: 65536 }, + }, + "claude-3-7-sonnet-thinking": { + id: "claude-3-7-sonnet-thinking", + name: "Claude 3.7 Sonnet Thinking", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-02-24", + last_updated: "2025-02-24", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2.992, output: 14.994 }, + limit: { context: 200000, input: 200000, output: 16000 }, + }, + "claude-opus-4-thinking:8192": { + id: "claude-opus-4-thinking:8192", + name: "Claude 4 Opus Thinking (8K)", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 14.994, output: 75.004 }, + limit: { context: 200000, input: 200000, output: 32000 }, + }, + "claude-sonnet-4-thinking:1024": { + id: "claude-sonnet-4-thinking:1024", + name: "Claude 4 Sonnet Thinking (1K)", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2.992, output: 14.994 }, + limit: { context: 1000000, input: 1000000, output: 64000 }, + }, + "Llama-3.3-70B-Magnum-v4-SE-Cirrus-x1-SLERP": { + id: "Llama-3.3-70B-Magnum-v4-SE-Cirrus-x1-SLERP", + name: "Llama 3.3 70B Magnum v4 SE Cirrus x1 SLERP", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-07-26", + last_updated: "2025-07-26", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "step-r1-v-mini": { + id: "step-r1-v-mini", + name: "Step R1 V Mini", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-04-08", + last_updated: "2025-04-08", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 11 }, + limit: { context: 128000, input: 128000, output: 65536 }, + }, + "ernie-x1-32k-preview": { + id: "ernie-x1-32k-preview", + name: "Ernie X1 32k", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-04-03", + last_updated: "2025-04-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.33, output: 1.32 }, + limit: { context: 32000, input: 32000, output: 16384 }, + }, + "Llama-3.3-70B-StrawberryLemonade-v1.0": { + id: "Llama-3.3-70B-StrawberryLemonade-v1.0", + name: "Llama 3.3 70B StrawberryLemonade v1.0", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "KAT-Coder-Exp-72B-1010": { + id: "KAT-Coder-Exp-72B-1010", + name: "KAT Coder Exp 72B 1010", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-10-28", + last_updated: "2025-10-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.2 }, + limit: { context: 128000, input: 128000, output: 32768 }, + }, + "gemini-2.5-pro-preview-03-25": { + id: "gemini-2.5-pro-preview-03-25", + name: "Gemini 2.5 Pro Preview 0325", + attachment: true, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-03-25", + last_updated: "2025-03-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 10 }, + limit: { context: 1048756, input: 1048756, output: 65536 }, + }, + "claude-opus-4-thinking:1024": { + id: "claude-opus-4-thinking:1024", + name: "Claude 4 Opus Thinking (1K)", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 14.994, output: 75.004 }, + limit: { context: 200000, input: 200000, output: 32000 }, + }, + "claude-sonnet-4-20250514": { + id: "claude-sonnet-4-20250514", + name: "Claude 4 Sonnet", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2.992, output: 14.994 }, + limit: { context: 200000, input: 200000, output: 64000 }, + }, + "Llama-3.3-70B-Progenitor-V3.3": { + id: "Llama-3.3-70B-Progenitor-V3.3", + name: "Llama 3.3 70B Progenitor V3.3", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-07-26", + last_updated: "2025-07-26", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "Qwen2.5-32B-EVA-v0.2": { + id: "Qwen2.5-32B-EVA-v0.2", + name: "Qwen 2.5 32b EVA", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-09-01", + last_updated: "2024-09-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.493, output: 0.493 }, + limit: { context: 24576, input: 24576, output: 8192 }, + }, + "brave-pro": { + id: "brave-pro", + name: "Brave (Pro)", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2023-03-02", + last_updated: "2024-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 5 }, + limit: { context: 8192, input: 8192, output: 8192 }, + }, + "step-2-16k-exp": { + id: "step-2-16k-exp", + name: "Step-2 16k Exp", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-07-05", + last_updated: "2024-07-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 7.004, output: 19.992 }, + limit: { context: 16000, input: 16000, output: 8192 }, + }, + "Llama-3.3-70B-Fallen-R1-v1": { + id: "Llama-3.3-70B-Fallen-R1-v1", + name: "Llama 3.3 70B Fallen R1 v1", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "claude-sonnet-4-thinking": { + id: "claude-sonnet-4-thinking", + name: "Claude 4 Sonnet Thinking", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-02-24", + last_updated: "2025-02-24", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2.992, output: 14.994 }, + limit: { context: 1000000, input: 1000000, output: 64000 }, + }, + "doubao-1.5-pro-256k": { + id: "doubao-1.5-pro-256k", + name: "Doubao 1.5 Pro 256k", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-03-12", + last_updated: "2025-03-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.799, output: 1.445 }, + limit: { context: 256000, input: 256000, output: 16384 }, + }, + "claude-3-7-sonnet-20250219": { + id: "claude-3-7-sonnet-20250219", + name: "Claude 3.7 Sonnet", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + release_date: "2025-02-19", + last_updated: "2025-02-19", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2.992, output: 14.994 }, + limit: { context: 200000, input: 200000, output: 16000 }, + }, + "learnlm-1.5-pro-experimental": { + id: "learnlm-1.5-pro-experimental", + name: "Gemini LearnLM Experimental", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-05-14", + last_updated: "2024-05-14", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 3.502, output: 10.506 }, + limit: { context: 32767, input: 32767, output: 8192 }, + }, + "qwen3-coder-30b-a3b-instruct": { + id: "qwen3-coder-30b-a3b-instruct", + name: "Qwen3 Coder 30B A3B Instruct", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4 }, + limit: { context: 128000, input: 128000, output: 65536 }, + }, + chroma: { + id: "chroma", + name: "Chroma", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2025-08-12", + last_updated: "2025-08-12", + modalities: { input: ["text"], output: ["image"] }, + open_weights: false, + limit: { context: 0, output: 0 }, + }, + "Llama-3.3-70B-Predatorial-Extasy": { + id: "Llama-3.3-70B-Predatorial-Extasy", + name: "Llama 3.3 70B Predatorial Extasy", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "Llama-3.3-70B-Aurora-Borealis": { + id: "Llama-3.3-70B-Aurora-Borealis", + name: "Llama 3.3 70B Aurora Borealis", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "Llama-3.3-70B-ArliAI-RPMax-v3": { + id: "Llama-3.3-70B-ArliAI-RPMax-v3", + name: "Llama 3.3 70B ArliAI RPMax v3", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "venice-uncensored": { + id: "venice-uncensored", + name: "Venice Uncensored", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-02-24", + last_updated: "2025-02-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 0.4 }, + limit: { context: 128000, input: 128000, output: 16384 }, + }, + "step-3": { + id: "step-3", + name: "Step-3", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-07-31", + last_updated: "2025-07-31", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2499, output: 0.6494 }, + limit: { context: 65536, input: 65536, output: 8192 }, + }, + "Llama-3.3-70B-The-Omega-Directive-Unslop-v2.0": { + id: "Llama-3.3-70B-The-Omega-Directive-Unslop-v2.0", + name: "Llama 3.3 70B Omega Directive Unslop v2.0", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "auto-model": { + id: "auto-model", + name: "Auto model", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-06-01", + last_updated: "2024-06-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 1000000, input: 1000000, output: 1000000 }, + }, + "claude-opus-4-1-thinking:32768": { + id: "claude-opus-4-1-thinking:32768", + name: "Claude 4.1 Opus Thinking (32K)", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 14.994, output: 75.004 }, + limit: { context: 200000, input: 200000, output: 32000 }, + }, + "Llama-3.3-70B-Shakudo": { + id: "Llama-3.3-70B-Shakudo", + name: "Llama 3.3 70B Shakudo", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "Baichuan4-Air": { + id: "Baichuan4-Air", + name: "Baichuan 4 Air", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-08-19", + last_updated: "2025-08-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.157, output: 0.157 }, + limit: { context: 32768, input: 32768, output: 32768 }, + }, + "kimi-thinking-preview": { + id: "kimi-thinking-preview", + name: "Kimi Thinking Preview", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-05-07", + last_updated: "2025-05-07", + modalities: { input: ["text", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 31.46, output: 31.46 }, + limit: { context: 128000, input: 128000, output: 16384 }, + }, + "qwen-turbo": { + id: "qwen-turbo", + name: "Qwen Turbo", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-11-01", + last_updated: "2024-11-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.04998, output: 0.2006 }, + limit: { context: 1000000, input: 1000000, output: 8192 }, + }, + "Llama-3.3-70B-Mhnnn-x1": { + id: "Llama-3.3-70B-Mhnnn-x1", + name: "Llama 3.3 70B Mhnnn x1", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "claude-opus-4-thinking:32768": { + id: "claude-opus-4-thinking:32768", + name: "Claude 4 Opus Thinking (32K)", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 14.994, output: 75.004 }, + limit: { context: 200000, input: 200000, output: 32000 }, + }, + "Llama-3.3-70B-Argunaut-1-SFT": { + id: "Llama-3.3-70B-Argunaut-1-SFT", + name: "Llama 3.3 70B Argunaut 1 SFT", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "claude-opus-4-1-thinking:1024": { + id: "claude-opus-4-1-thinking:1024", + name: "Claude 4.1 Opus Thinking (1K)", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 14.994, output: 75.004 }, + limit: { context: 200000, input: 200000, output: 32000 }, + }, + "gemini-2.5-flash-lite": { + id: "gemini-2.5-flash-lite", + name: "Gemini 2.5 Flash Lite", + attachment: true, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-06-17", + last_updated: "2025-06-17", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4 }, + limit: { context: 1048756, input: 1048756, output: 65536 }, + }, + "phi-4-multimodal-instruct": { + id: "phi-4-multimodal-instruct", + name: "Phi 4 Multimodal", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-07-26", + last_updated: "2025-07-26", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.07, output: 0.11 }, + limit: { context: 128000, input: 128000, output: 16384 }, + }, + "doubao-seed-2-0-code-preview-260215": { + id: "doubao-seed-2-0-code-preview-260215", + name: "Doubao Seed 2.0 Code Preview", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2026-02-14", + last_updated: "2026-02-14", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.782, output: 3.893 }, + limit: { context: 256000, input: 256000, output: 128000 }, + }, + "deepseek-reasoner-cheaper": { + id: "deepseek-reasoner-cheaper", + name: "Deepseek R1 Cheaper", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-01-20", + last_updated: "2025-01-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 1.7 }, + limit: { context: 128000, input: 128000, output: 65536 }, + }, + "exa-answer": { + id: "exa-answer", + name: "Exa (Answer)", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-06-04", + last_updated: "2025-06-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 2.5 }, + limit: { context: 4096, input: 4096, output: 4096 }, + }, + "v0-1.0-md": { + id: "v0-1.0-md", + name: "v0 1.0 MD", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-07-04", + last_updated: "2025-07-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15 }, + limit: { context: 200000, input: 200000, output: 64000 }, + }, + "glm-4.1v-thinking-flash": { + id: "glm-4.1v-thinking-flash", + name: "GLM 4.1V Thinking Flash", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-07-09", + last_updated: "2025-07-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 0.3 }, + limit: { context: 64000, input: 64000, output: 8192 }, + }, + "azure-o1": { + id: "azure-o1", + name: "Azure o1", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-17", + last_updated: "2024-12-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 14.994, output: 59.993 }, + limit: { context: 200000, input: 200000, output: 100000 }, + }, + "GLM-4.5-Air-Derestricted": { + id: "GLM-4.5-Air-Derestricted", + name: "GLM 4.5 Air Derestricted", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-07-28", + last_updated: "2025-07-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 202600, input: 202600, output: 98304 }, + }, + "azure-o3-mini": { + id: "azure-o3-mini", + name: "Azure o3-mini", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-01-31", + last_updated: "2025-01-31", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.088, output: 4.3996 }, + limit: { context: 200000, input: 200000, output: 65536 }, + }, + "qwen3.6-max-preview": { + id: "qwen3.6-max-preview", + name: "Qwen3.6 Max Preview", + family: "qwen3.6", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2026-04-20", + last_updated: "2026-04-21", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.3, output: 7.8 }, + limit: { context: 245800, output: 65536 }, + }, + "Llama-3.3-70B-Sapphira-0.2": { + id: "Llama-3.3-70B-Sapphira-0.2", + name: "Llama 3.3 70B Sapphira 0.2", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "Llama-3.3-70B-Anthrobomination": { + id: "Llama-3.3-70B-Anthrobomination", + name: "Llama 3.3 70B Anthrobomination", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "QwQ-32B-ArliAI-RpR-v1": { + id: "QwQ-32B-ArliAI-RpR-v1", + name: "QwQ 32b Arli V1", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-02-17", + last_updated: "2025-02-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.2 }, + limit: { context: 32768, input: 32768, output: 32768 }, + }, + "claude-opus-4-20250514": { + id: "claude-opus-4-20250514", + name: "Claude 4 Opus", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + release_date: "2025-05-14", + last_updated: "2025-05-14", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 14.994, output: 75.004 }, + limit: { context: 200000, input: 200000, output: 32000 }, + }, + "yi-lightning": { + id: "yi-lightning", + name: "Yi Lightning", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-10-16", + last_updated: "2024-10-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2006, output: 0.2006 }, + limit: { context: 12000, input: 12000, output: 4096 }, + }, + "Llama-3.3-70B-Electra-R1": { + id: "Llama-3.3-70B-Electra-R1", + name: "Llama 3.3 70B Electra R1", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "Llama-3.3-70B-Forgotten-Abomination-v5.0": { + id: "Llama-3.3-70B-Forgotten-Abomination-v5.0", + name: "Llama 3.3 70B Forgotten Abomination v5.0", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "Llama-3.3-70B-Cirrus-x1": { + id: "Llama-3.3-70B-Cirrus-x1", + name: "Llama 3.3 70B Cirrus x1", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "grok-3-mini-beta": { + id: "grok-3-mini-beta", + name: "Grok 3 Mini Beta", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-02-17", + last_updated: "2025-02-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 0.5 }, + limit: { context: 131072, input: 131072, output: 131072 }, + }, + "auto-model-standard": { + id: "auto-model-standard", + name: "Auto model (Standard)", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-06-01", + last_updated: "2024-06-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 9.996, output: 19.992 }, + limit: { context: 1000000, input: 1000000, output: 1000000 }, + }, + "claude-sonnet-4-5-20250929-thinking": { + id: "claude-sonnet-4-5-20250929-thinking", + name: "Claude Sonnet 4.5 Thinking", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2.992, output: 14.994 }, + limit: { context: 1000000, input: 1000000, output: 64000 }, + }, + "v0-1.5-md": { + id: "v0-1.5-md", + name: "v0 1.5 MD", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-07-04", + last_updated: "2025-07-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15 }, + limit: { context: 200000, input: 200000, output: 64000 }, + }, + "kimi-k2-instruct-fast": { + id: "kimi-k2-instruct-fast", + name: "Kimi K2 0711 Fast", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-07-15", + last_updated: "2025-07-15", + modalities: { input: ["text", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 2 }, + limit: { context: 131072, input: 131072, output: 16384 }, + }, + "glm-4-long": { + id: "glm-4-long", + name: "GLM-4 Long", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-08-01", + last_updated: "2024-08-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2006, output: 0.2006 }, + limit: { context: 1000000, input: 1000000, output: 4096 }, + }, + "jamba-large-1.7": { + id: "jamba-large-1.7", + name: "Jamba Large 1.7", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-07-09", + last_updated: "2025-07-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.989, output: 7.99 }, + limit: { context: 256000, input: 256000, output: 4096 }, + }, + "qvq-max": { + id: "qvq-max", + name: "Qwen: QvQ Max", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-03-28", + last_updated: "2025-03-28", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.4, output: 5.3 }, + limit: { context: 128000, input: 128000, output: 8192 }, + }, + "gemini-2.0-flash-thinking-exp-1219": { + id: "gemini-2.0-flash-thinking-exp-1219", + name: "Gemini 2.0 Flash Thinking 1219", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-19", + last_updated: "2024-12-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1003, output: 0.408 }, + limit: { context: 32767, input: 32767, output: 8192 }, + }, + "gemini-2.0-flash-lite": { + id: "gemini-2.0-flash-lite", + name: "Gemini 2.0 Flash Lite", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-11", + last_updated: "2024-12-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.0748, output: 0.306 }, + limit: { context: 1000000, input: 1000000, output: 8192 }, + }, + "azure-gpt-4-turbo": { + id: "azure-gpt-4-turbo", + name: "Azure gpt-4-turbo", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2023-11-06", + last_updated: "2024-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 9.996, output: 30.005 }, + limit: { context: 128000, input: 128000, output: 4096 }, + }, + "Baichuan-M2": { + id: "Baichuan-M2", + name: "Baichuan M2 32B Medical", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-08-19", + last_updated: "2025-08-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 15.73, output: 15.73 }, + limit: { context: 32768, input: 32768, output: 32768 }, + }, + "qwen-long": { + id: "qwen-long", + name: "Qwen Long 10M", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-01-25", + last_updated: "2025-01-25", + modalities: { input: ["text", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1003, output: 0.408 }, + limit: { context: 10000000, input: 10000000, output: 8192 }, + }, + "sonar-reasoning-pro": { + id: "sonar-reasoning-pro", + name: "Perplexity Reasoning Pro", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-02-19", + last_updated: "2025-02-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2.006, output: 7.9985 }, + limit: { context: 127000, input: 127000, output: 128000 }, + }, + "gemini-2.5-flash-preview-05-20:thinking": { + id: "gemini-2.5-flash-preview-05-20:thinking", + name: "Gemini 2.5 Flash 0520 Thinking", + attachment: true, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-05-20", + last_updated: "2025-05-20", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 3.5 }, + limit: { context: 1048000, input: 1048000, output: 65536 }, + }, + "GLM-4.5-Air-Derestricted-Steam-ReExtract": { + id: "GLM-4.5-Air-Derestricted-Steam-ReExtract", + name: "GLM 4.5 Air Derestricted Steam ReExtract", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-12-12", + last_updated: "2025-12-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 131072, input: 131072, output: 65536 }, + }, + "Llama-3.3-70B-Dark-Ages-v0.1": { + id: "Llama-3.3-70B-Dark-Ages-v0.1", + name: "Llama 3.3 70B Dark Ages v0.1", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "Baichuan4-Turbo": { + id: "Baichuan4-Turbo", + name: "Baichuan 4 Turbo", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-08-19", + last_updated: "2025-08-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2.42, output: 2.42 }, + limit: { context: 128000, input: 128000, output: 32768 }, + }, + "doubao-1.5-vision-pro-32k": { + id: "doubao-1.5-vision-pro-32k", + name: "Doubao 1.5 Vision Pro 32k", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-01-22", + last_updated: "2025-01-22", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.459, output: 1.377 }, + limit: { context: 32000, input: 32000, output: 8192 }, + }, + "alibaba/qwen3.6-flash": { + id: "alibaba/qwen3.6-flash", + name: "Qwen3.6 Flash", + family: "qwen3.6", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2026-04-17", + last_updated: "2026-04-17", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.19, output: 1.16 }, + limit: { context: 991800, output: 65536 }, + }, + "inflection/inflection-3-pi": { + id: "inflection/inflection-3-pi", + name: "Inflection 3 Pi", + family: "gpt", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-10-11", + last_updated: "2024-10-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2.499, output: 9.996 }, + limit: { context: 8000, input: 8000, output: 4096 }, + }, + "inflection/inflection-3-productivity": { + id: "inflection/inflection-3-productivity", + name: "Inflection 3 Productivity", + family: "gpt", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-10-11", + last_updated: "2024-10-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2.499, output: 9.996 }, + limit: { context: 8000, input: 8000, output: 4096 }, + }, + "essentialai/rnj-1-instruct": { + id: "essentialai/rnj-1-instruct", + name: "RNJ-1 Instruct 8B", + family: "rnj", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-12-13", + last_updated: "2025-12-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.15 }, + limit: { context: 128000, input: 128000, output: 8192 }, + }, + "LLM360/K2-Think": { + id: "LLM360/K2-Think", + name: "K2-Think", + family: "kimi-thinking", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-07-26", + last_updated: "2025-07-26", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.17, output: 0.68 }, + limit: { context: 128000, input: 128000, output: 32768 }, + }, + "TEE/kimi-k2.5": { + id: "TEE/kimi-k2.5", + name: "Kimi K2.5 TEE", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2026-01-29", + last_updated: "2026-01-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 1.9 }, + limit: { context: 128000, input: 128000, output: 65535 }, + }, + "TEE/glm-4.7": { + id: "TEE/glm-4.7", + name: "GLM 4.7 TEE", + family: "glm", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2026-01-29", + last_updated: "2026-01-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.85, output: 3.3 }, + limit: { context: 131000, input: 131000, output: 65535 }, + }, + "TEE/qwen3.5-397b-a17b": { + id: "TEE/qwen3.5-397b-a17b", + name: "Qwen3.5 397B A17B TEE", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2026-02-28", + last_updated: "2026-02-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.6, output: 3.6 }, + limit: { context: 258048, input: 258048, output: 65536 }, + }, + "TEE/glm-5": { + id: "TEE/glm-5", + name: "GLM 5 TEE", + family: "glm", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2026-02-11", + last_updated: "2026-02-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.2, output: 3.5 }, + limit: { context: 203000, input: 203000, output: 65535 }, + }, + "TEE/qwen2.5-vl-72b-instruct": { + id: "TEE/qwen2.5-vl-72b-instruct", + name: "Qwen2.5 VL 72B TEE", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-02-01", + last_updated: "2025-02-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.7, output: 0.7 }, + limit: { context: 65536, input: 65536, output: 8192 }, + }, + "TEE/minimax-m2.1": { + id: "TEE/minimax-m2.1", + name: "MiniMax M2.1 TEE", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-12-23", + last_updated: "2025-12-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 200000, input: 200000, output: 131072 }, + }, + "TEE/qwen3-30b-a3b-instruct-2507": { + id: "TEE/qwen3-30b-a3b-instruct-2507", + name: "Qwen3 30B A3B Instruct 2507 TEE", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-07-29", + last_updated: "2025-07-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.44999999999999996 }, + limit: { context: 262000, input: 262000, output: 32768 }, + }, + "TEE/deepseek-v3.1": { + id: "TEE/deepseek-v3.1", + name: "DeepSeek V3.1 TEE", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-08-21", + last_updated: "2025-08-21", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 2.5 }, + limit: { context: 164000, input: 164000, output: 8192 }, + }, + "TEE/llama3-3-70b": { + id: "TEE/llama3-3-70b", + name: "Llama 3.3 70B", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-07-03", + last_updated: "2025-07-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 2 }, + limit: { context: 128000, input: 128000, output: 16384 }, + }, + "TEE/glm-4.6": { + id: "TEE/glm-4.6", + name: "GLM 4.6 TEE", + family: "glm", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-09-30", + last_updated: "2025-09-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.75, output: 2 }, + limit: { context: 203000, input: 203000, output: 65535 }, + }, + "TEE/kimi-k2.5-thinking": { + id: "TEE/kimi-k2.5-thinking", + name: "Kimi K2.5 Thinking TEE", + family: "kimi-thinking", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2026-01-29", + last_updated: "2026-01-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 1.9 }, + limit: { context: 128000, input: 128000, output: 65535 }, + }, + "TEE/gemma-3-27b-it": { + id: "TEE/gemma-3-27b-it", + name: "Gemma 3 27B TEE", + family: "gemma", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-03-10", + last_updated: "2025-03-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.8 }, + limit: { context: 131072, input: 131072, output: 8192 }, + }, + "TEE/deepseek-v3.2": { + id: "TEE/deepseek-v3.2", + name: "DeepSeek V3.2 TEE", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-12-01", + last_updated: "2025-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 1 }, + limit: { context: 164000, input: 164000, output: 65536 }, + }, + "TEE/gpt-oss-20b": { + id: "TEE/gpt-oss-20b", + name: "GPT-OSS 20B TEE", + family: "gpt-oss", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.8 }, + limit: { context: 131072, input: 131072, output: 8192 }, + }, + "TEE/qwen3-coder": { + id: "TEE/qwen3-coder", + name: "Qwen3 Coder 480B TEE", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-07-23", + last_updated: "2025-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.5, output: 2 }, + limit: { context: 128000, input: 128000, output: 32768 }, + }, + "TEE/glm-4.7-flash": { + id: "TEE/glm-4.7-flash", + name: "GLM 4.7 Flash TEE", + family: "glm-flash", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2026-01-19", + last_updated: "2026-01-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.5 }, + limit: { context: 203000, input: 203000, output: 65535 }, + }, + "TEE/gpt-oss-120b": { + id: "TEE/gpt-oss-120b", + name: "GPT-OSS 120B TEE", + family: "gpt-oss", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 2 }, + limit: { context: 131072, input: 131072, output: 16384 }, + }, + "TEE/deepseek-r1-0528": { + id: "TEE/deepseek-r1-0528", + name: "DeepSeek R1 0528 TEE", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-05-28", + last_updated: "2025-05-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 2 }, + limit: { context: 128000, input: 128000, output: 65536 }, + }, + "TEE/kimi-k2-thinking": { + id: "TEE/kimi-k2-thinking", + name: "Kimi K2 Thinking TEE", + family: "kimi-thinking", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-11-06", + last_updated: "2025-11-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 2 }, + limit: { context: 128000, input: 128000, output: 65535 }, + }, + "CrucibleLab/L3.3-70B-Loki-V2.0": { + id: "CrucibleLab/L3.3-70B-Loki-V2.0", + name: "L3.3 70B Loki v2.0", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2026-01-22", + last_updated: "2026-01-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.49299999999999994, output: 0.49299999999999994 }, + limit: { context: 16384, input: 16384, output: 16384 }, + }, + "deepseek/deepseek-v3.2:thinking": { + id: "deepseek/deepseek-v3.2:thinking", + name: "DeepSeek V3.2 Thinking", + family: "deepseek", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-12-01", + last_updated: "2025-12-01", + modalities: { input: ["text", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.27999999999999997, output: 0.42000000000000004 }, + limit: { context: 163000, input: 163000, output: 65536 }, + }, + "deepseek/deepseek-prover-v2-671b": { + id: "deepseek/deepseek-prover-v2-671b", + name: "DeepSeek Prover v2 671B", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-04-30", + last_updated: "2025-04-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 2.5 }, + limit: { context: 160000, input: 160000, output: 16384 }, + }, + "deepseek/deepseek-v3.2-speciale": { + id: "deepseek/deepseek-v3.2-speciale", + name: "DeepSeek V3.2 Speciale", + family: "deepseek", + attachment: true, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-12-02", + last_updated: "2025-12-02", + modalities: { input: ["text", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.27999999999999997, output: 0.42000000000000004 }, + limit: { context: 163000, input: 163000, output: 65536 }, + }, + "deepseek/deepseek-v3.2": { + id: "deepseek/deepseek-v3.2", + name: "DeepSeek V3.2", + family: "deepseek", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + release_date: "2025-12-01", + last_updated: "2025-12-01", + modalities: { input: ["text", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.27999999999999997, output: 0.42000000000000004 }, + limit: { context: 163000, input: 163000, output: 65536 }, + }, + "Doctor-Shotgun/MS3.2-24B-Magnum-Diamond": { + id: "Doctor-Shotgun/MS3.2-24B-Magnum-Diamond", + name: "MS3.2 24B Magnum Diamond", + family: "mistral", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-11-24", + last_updated: "2025-11-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.49299999999999994, output: 0.49299999999999994 }, + limit: { context: 16384, input: 16384, output: 32768 }, + }, + "NeverSleep/Llama-3-Lumimaid-70B-v0.1": { + id: "NeverSleep/Llama-3-Lumimaid-70B-v0.1", + name: "Lumimaid 70b", + family: "llama", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-07-01", + last_updated: "2024-07-01", + modalities: { input: ["text", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2.006, output: 2.006 }, + limit: { context: 16384, input: 16384, output: 8192 }, + }, + "NeverSleep/Lumimaid-v0.2-70B": { + id: "NeverSleep/Lumimaid-v0.2-70B", + name: "Lumimaid v0.2", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-07-01", + last_updated: "2024-07-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 1.5 }, + limit: { context: 16384, input: 16384, output: 8192 }, + }, + "Steelskull/L3.3-Cu-Mai-R1-70b": { + id: "Steelskull/L3.3-Cu-Mai-R1-70b", + name: "Llama 3.3 70B Cu Mai", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.49299999999999994, output: 0.49299999999999994 }, + limit: { context: 16384, input: 16384, output: 16384 }, + }, + "Steelskull/L3.3-Nevoria-R1-70b": { + id: "Steelskull/L3.3-Nevoria-R1-70b", + name: "Steelskull Nevoria R1 70b", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.49299999999999994, output: 0.49299999999999994 }, + limit: { context: 16384, input: 16384, output: 16384 }, + }, + "Steelskull/L3.3-MS-Evayale-70B": { + id: "Steelskull/L3.3-MS-Evayale-70B", + name: "Evayale 70b ", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.49299999999999994, output: 0.49299999999999994 }, + limit: { context: 16384, input: 16384, output: 16384 }, + }, + "Steelskull/L3.3-Electra-R1-70b": { + id: "Steelskull/L3.3-Electra-R1-70b", + name: "Steelskull Electra R1 70b", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.69989, output: 0.69989 }, + limit: { context: 16384, input: 16384, output: 16384 }, + }, + "Steelskull/L3.3-MS-Nevoria-70b": { + id: "Steelskull/L3.3-MS-Nevoria-70b", + name: "Steelskull Nevoria 70b", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.49299999999999994, output: 0.49299999999999994 }, + limit: { context: 16384, input: 16384, output: 16384 }, + }, + "Steelskull/L3.3-MS-Evalebis-70b": { + id: "Steelskull/L3.3-MS-Evalebis-70b", + name: "MS Evalebis 70b", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.49299999999999994, output: 0.49299999999999994 }, + limit: { context: 16384, input: 16384, output: 16384 }, + }, + "miromind-ai/mirothinker-v1.5-235b": { + id: "miromind-ai/mirothinker-v1.5-235b", + name: "MiroThinker v1.5 235B", + family: "gpt", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2026-01-07", + last_updated: "2026-01-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 32768, input: 32768, output: 4000 }, + }, + "pamanseau/OpenReasoning-Nemotron-32B": { + id: "pamanseau/OpenReasoning-Nemotron-32B", + name: "OpenReasoning Nemotron 32B", + family: "nemotron", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-08-21", + last_updated: "2025-08-21", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4 }, + limit: { context: 32768, input: 32768, output: 65536 }, + }, + "arcee-ai/trinity-mini": { + id: "arcee-ai/trinity-mini", + name: "Trinity Mini", + family: "trinity-mini", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-12-01", + last_updated: "2025-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.045000000000000005, output: 0.15 }, + limit: { context: 131072, input: 131072, output: 8192 }, + }, + "arcee-ai/trinity-large": { + id: "arcee-ai/trinity-large", + name: "Trinity Large", + family: "trinity", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-12-01", + last_updated: "2025-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 1 }, + limit: { context: 131072, input: 131072, output: 8192 }, + }, + "cognitivecomputations/dolphin-2.9.2-qwen2-72b": { + id: "cognitivecomputations/dolphin-2.9.2-qwen2-72b", + name: "Dolphin 72b", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-02-27", + last_updated: "2025-02-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.306 }, + limit: { context: 8192, input: 8192, output: 4096 }, + }, + "deepcogito/cogito-v1-preview-qwen-32B": { + id: "deepcogito/cogito-v1-preview-qwen-32B", + name: "Cogito v1 Preview Qwen 32B", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-05-10", + last_updated: "2025-05-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.7999999999999998, output: 1.7999999999999998 }, + limit: { context: 128000, input: 128000, output: 32768 }, + }, + "deepcogito/cogito-v2.1-671b": { + id: "deepcogito/cogito-v2.1-671b", + name: "Cogito v2.1 671B MoE", + family: "cogito", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-11-19", + last_updated: "2025-11-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 1.25 }, + limit: { context: 128000, input: 128000, output: 16384 }, + }, + "Salesforce/Llama-xLAM-2-70b-fc-r": { + id: "Salesforce/Llama-xLAM-2-70b-fc-r", + name: "Llama-xLAM-2 70B fc-r", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-04-13", + last_updated: "2025-04-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 2.5 }, + limit: { context: 128000, input: 128000, output: 16384 }, + }, + "NousResearch 2/hermes-4-405b:thinking": { + id: "NousResearch 2/hermes-4-405b:thinking", + name: "Hermes 4 Large (Thinking)", + family: "nousresearch", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 128000, input: 128000, output: 8192 }, + }, + "NousResearch 2/DeepHermes-3-Mistral-24B-Preview": { + id: "NousResearch 2/DeepHermes-3-Mistral-24B-Preview", + name: "DeepHermes-3 Mistral 24B (Preview)", + family: "nousresearch", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-05-10", + last_updated: "2025-05-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 0.3 }, + limit: { context: 128000, input: 128000, output: 32768 }, + }, + "NousResearch 2/Hermes-4-70B:thinking": { + id: "NousResearch 2/Hermes-4-70B:thinking", + name: "Hermes 4 (Thinking)", + family: "nousresearch", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-09-17", + last_updated: "2025-09-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2006, output: 0.39949999999999997 }, + limit: { context: 128000, input: 128000, output: 8192 }, + }, + "NousResearch 2/hermes-4-405b": { + id: "NousResearch 2/hermes-4-405b", + name: "Hermes 4 Large", + family: "nousresearch", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + release_date: "2025-08-26", + last_updated: "2025-08-26", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 128000, input: 128000, output: 8192 }, + }, + "NousResearch 2/hermes-3-llama-3.1-70b": { + id: "NousResearch 2/hermes-3-llama-3.1-70b", + name: "Hermes 3 70B", + family: "nousresearch", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2026-01-07", + last_updated: "2026-01-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.408, output: 0.408 }, + limit: { context: 65536, input: 65536, output: 8192 }, + }, + "NousResearch 2/hermes-4-70b": { + id: "NousResearch 2/hermes-4-70b", + name: "Hermes 4 Medium", + family: "nousresearch", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-07-03", + last_updated: "2025-07-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2006, output: 0.39949999999999997 }, + limit: { context: 128000, input: 128000, output: 8192 }, + }, + "soob3123/Veiled-Calla-12B": { + id: "soob3123/Veiled-Calla-12B", + name: "Veiled Calla 12B", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-04-13", + last_updated: "2025-04-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 0.3 }, + limit: { context: 32768, input: 32768, output: 8192 }, + }, + "soob3123/GrayLine-Qwen3-8B": { + id: "soob3123/GrayLine-Qwen3-8B", + name: "Grayline Qwen3 8B", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-09-25", + last_updated: "2025-09-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 0.3 }, + limit: { context: 16384, input: 16384, output: 32768 }, + }, + "soob3123/amoral-gemma3-27B-v2": { + id: "soob3123/amoral-gemma3-27B-v2", + name: "Amoral Gemma3 27B v2", + family: "gemma", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-05-23", + last_updated: "2025-05-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 0.3 }, + limit: { context: 32768, input: 32768, output: 8192 }, + }, + "nex-agi/deepseek-v3.1-nex-n1": { + id: "nex-agi/deepseek-v3.1-nex-n1", + name: "DeepSeek V3.1 Nex N1", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-12-10", + last_updated: "2025-12-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.27999999999999997, output: 0.42000000000000004 }, + limit: { context: 128000, input: 128000, output: 8192 }, + }, + "Envoid/Llama-3.05-NT-Storybreaker-Ministral-70B": { + id: "Envoid/Llama-3.05-NT-Storybreaker-Ministral-70B", + name: "Llama 3.05 Storybreaker Ministral 70b", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-01", + last_updated: "2024-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.49299999999999994, output: 0.49299999999999994 }, + limit: { context: 16384, input: 16384, output: 8192 }, + }, + "Envoid/Llama-3.05-Nemotron-Tenyxchat-Storybreaker-70B": { + id: "Envoid/Llama-3.05-Nemotron-Tenyxchat-Storybreaker-70B", + name: "Nemotron Tenyxchat Storybreaker 70b", + family: "nemotron", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-01", + last_updated: "2024-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.49299999999999994, output: 0.49299999999999994 }, + limit: { context: 16384, input: 16384, output: 8192 }, + }, + "anthracite-org/magnum-v4-72b": { + id: "anthracite-org/magnum-v4-72b", + name: "Magnum v4 72B", + family: "llama", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2.006, output: 2.992 }, + limit: { context: 16384, input: 16384, output: 8192 }, + }, + "anthracite-org/magnum-v2-72b": { + id: "anthracite-org/magnum-v2-72b", + name: "Magnum V2 72B", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-07-01", + last_updated: "2024-07-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2.006, output: 2.992 }, + limit: { context: 16384, input: 16384, output: 8192 }, + }, + "ReadyArt/MS3.2-The-Omega-Directive-24B-Unslop-v2.0": { + id: "ReadyArt/MS3.2-The-Omega-Directive-24B-Unslop-v2.0", + name: "Omega Directive 24B Unslop v2.0", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-12-08", + last_updated: "2025-12-08", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 0.5 }, + limit: { context: 16384, input: 16384, output: 32768 }, + }, + "ReadyArt/The-Omega-Abomination-L-70B-v1.0": { + id: "ReadyArt/The-Omega-Abomination-L-70B-v1.0", + name: "The Omega Abomination V1", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-01", + last_updated: "2024-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.7, output: 0.95 }, + limit: { context: 16384, input: 16384, output: 16384 }, + }, + "undi95/remm-slerp-l2-13b": { + id: "undi95/remm-slerp-l2-13b", + name: "ReMM SLERP 13B", + family: "llama", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.7989999999999999, output: 1.2069999999999999 }, + limit: { context: 6144, input: 6144, output: 4096 }, + }, + "MarinaraSpaghetti/NemoMix-Unleashed-12B": { + id: "MarinaraSpaghetti/NemoMix-Unleashed-12B", + name: "NemoMix 12B Unleashed", + family: "mistral-nemo", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-07-01", + last_updated: "2024-07-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.49299999999999994, output: 0.49299999999999994 }, + limit: { context: 32768, input: 32768, output: 8192 }, + }, + "allenai/molmo-2-8b": { + id: "allenai/molmo-2-8b", + name: "Molmo 2 8B", + family: "allenai", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2026-02-14", + last_updated: "2026-02-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.2 }, + limit: { context: 36864, input: 36864, output: 36864 }, + }, + "allenai/olmo-3.1-32b-instruct": { + id: "allenai/olmo-3.1-32b-instruct", + name: "Olmo 3.1 32B Instruct", + family: "allenai", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2026-01-25", + last_updated: "2026-01-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.6 }, + limit: { context: 65536, input: 65536, output: 8192 }, + }, + "allenai/olmo-3.1-32b-think": { + id: "allenai/olmo-3.1-32b-think", + name: "Olmo 3.1 32B Think", + family: "allenai", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2026-01-25", + last_updated: "2026-01-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.5 }, + limit: { context: 65536, input: 65536, output: 8192 }, + }, + "allenai/olmo-3-32b-think": { + id: "allenai/olmo-3-32b-think", + name: "Olmo 3 32B Think", + family: "allenai", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-11-01", + last_updated: "2025-11-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 0.44999999999999996 }, + limit: { context: 128000, input: 128000, output: 8192 }, + }, + "stepfun-ai/step-3.5-flash:thinking": { + id: "stepfun-ai/step-3.5-flash:thinking", + name: "Step 3.5 Flash Thinking", + family: "step", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2026-02-02", + last_updated: "2026-02-02", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5 }, + limit: { context: 256000, input: 256000, output: 256000 }, + }, + "stepfun-ai/step-3.5-flash": { + id: "stepfun-ai/step-3.5-flash", + name: "Step 3.5 Flash", + family: "step", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2026-02-02", + last_updated: "2026-02-02", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5 }, + limit: { context: 256000, input: 256000, output: 256000 }, + }, + "zai-org/glm-4.7": { + id: "zai-org/glm-4.7", + name: "GLM 4.7", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2026-01-29", + last_updated: "2026-01-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.8 }, + limit: { context: 200000, input: 200000, output: 128000 }, + }, + "zai-org/glm-5": { + id: "zai-org/glm-5", + name: "GLM 5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2026-02-11", + last_updated: "2026-02-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 2.55 }, + limit: { context: 200000, input: 200000, output: 128000 }, + }, + "zai-org/glm-5.1": { + id: "zai-org/glm-5.1", + name: "GLM 5.1", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2026-03-27", + last_updated: "2026-03-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 2.55 }, + limit: { context: 200000, input: 200000, output: 131072 }, + }, + "zai-org/glm-5.1:thinking": { + id: "zai-org/glm-5.1:thinking", + name: "GLM 5.1 Thinking", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2026-03-27", + last_updated: "2026-03-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 2.55 }, + limit: { context: 200000, input: 200000, output: 131072 }, + }, + "zai-org/glm-5:thinking": { + id: "zai-org/glm-5:thinking", + name: "GLM 5 Thinking", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2026-02-11", + last_updated: "2026-02-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 2.55 }, + limit: { context: 200000, input: 200000, output: 128000 }, + }, + "zai-org/glm-4.7-flash": { + id: "zai-org/glm-4.7-flash", + name: "GLM 4.7 Flash", + family: "glm-flash", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2026-01-19", + last_updated: "2026-01-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.07, output: 0.4 }, + limit: { context: 200000, input: 200000, output: 128000 }, + }, + "featherless-ai/Qwerky-72B": { + id: "featherless-ai/Qwerky-72B", + name: "Qwerky 72B", + family: "qwerky", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-03-20", + last_updated: "2025-03-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 0.5 }, + limit: { context: 32000, input: 32000, output: 8192 }, + }, + "mlabonne/NeuralDaredevil-8B-abliterated": { + id: "mlabonne/NeuralDaredevil-8B-abliterated", + name: "Neural Daredevil 8B abliterated", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-01", + last_updated: "2024-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.44, output: 0.44 }, + limit: { context: 8192, input: 8192, output: 8192 }, + }, + "raifle/sorcererlm-8x22b": { + id: "raifle/sorcererlm-8x22b", + name: "SorcererLM 8x22B", + family: "mixtral", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 4.505, output: 4.505 }, + limit: { context: 16000, input: 16000, output: 8192 }, + }, + "mistralai/mixtral-8x7b-instruct-v0.1": { + id: "mistralai/mixtral-8x7b-instruct-v0.1", + name: "Mixtral 8x7B", + family: "mixtral", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-12-11", + last_updated: "2025-12-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.27, output: 0.27 }, + limit: { context: 32768, input: 32768, output: 32768 }, + }, + "mistralai/mistral-saba": { + id: "mistralai/mistral-saba", + name: "Mistral Saba", + family: "mistral", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-02-17", + last_updated: "2025-02-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1989, output: 0.595 }, + limit: { context: 32000, input: 32000, output: 32768 }, + }, + "mistralai/mistral-large-3-675b-instruct-2512": { + id: "mistralai/mistral-large-3-675b-instruct-2512", + name: "Mistral Large 3 675B", + family: "mistral-large", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-12-02", + last_updated: "2025-12-02", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 3 }, + limit: { context: 262144, input: 262144, output: 256000 }, + }, + "mistralai/devstral-2-123b-instruct-2512": { + id: "mistralai/devstral-2-123b-instruct-2512", + name: "Devstral 2 123B", + family: "devstral", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-12-09", + last_updated: "2025-12-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 1.4 }, + limit: { context: 262144, input: 262144, output: 65536 }, + }, + "mistralai/codestral-2508": { + id: "mistralai/codestral-2508", + name: "Codestral 2508", + family: "codestral", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-08-01", + last_updated: "2025-08-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 0.8999999999999999 }, + limit: { context: 256000, input: 256000, output: 32768 }, + }, + "mistralai/ministral-14b-instruct-2512": { + id: "mistralai/ministral-14b-instruct-2512", + name: "Ministral 3 14B", + family: "ministral", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-12-02", + last_updated: "2025-12-02", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4 }, + limit: { context: 262144, input: 262144, output: 32768 }, + }, + "mistralai/mistral-tiny": { + id: "mistralai/mistral-tiny", + name: "Mistral Tiny", + family: "mistral", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2023-12-11", + last_updated: "2024-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25499999999999995, output: 0.25499999999999995 }, + limit: { context: 32000, input: 32000, output: 8192 }, + }, + "mistralai/ministral-8b-2512": { + id: "mistralai/ministral-8b-2512", + name: "Ministral 8B", + family: "ministral", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-12-04", + last_updated: "2025-12-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.15 }, + limit: { context: 262144, input: 262144, output: 32768 }, + }, + "mistralai/mixtral-8x22b-instruct-v0.1": { + id: "mistralai/mixtral-8x22b-instruct-v0.1", + name: "Mixtral 8x22B", + family: "mixtral", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-12-11", + last_updated: "2025-12-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.8999999999999999, output: 0.8999999999999999 }, + limit: { context: 65536, input: 65536, output: 32768 }, + }, + "mistralai/mistral-medium-3.1": { + id: "mistralai/mistral-medium-3.1", + name: "Mistral Medium 3.1", + family: "mistral-medium", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-09-05", + last_updated: "2025-09-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 2 }, + limit: { context: 131072, input: 131072, output: 32768 }, + }, + "mistralai/ministral-3b-2512": { + id: "mistralai/ministral-3b-2512", + name: "Ministral 3B", + family: "ministral", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-12-04", + last_updated: "2025-12-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.1 }, + limit: { context: 131072, input: 131072, output: 32768 }, + }, + "mistralai/Mistral-Nemo-Instruct-2407": { + id: "mistralai/Mistral-Nemo-Instruct-2407", + name: "Mistral Nemo", + family: "mistral-nemo", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-07-18", + last_updated: "2024-07-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1003, output: 0.1207 }, + limit: { context: 16384, input: 16384, output: 8192 }, + }, + "mistralai/mistral-medium-3": { + id: "mistralai/mistral-medium-3", + name: "Mistral Medium 3", + family: "mistral-medium", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-09-25", + last_updated: "2025-09-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 2 }, + limit: { context: 131072, input: 131072, output: 32768 }, + }, + "mistralai/mistral-7b-instruct": { + id: "mistralai/mistral-7b-instruct", + name: "Mistral 7B Instruct", + family: "mistral", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-05-27", + last_updated: "2024-05-27", + modalities: { input: ["text", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.0544, output: 0.0544 }, + limit: { context: 32768, input: 32768, output: 8192 }, + }, + "mistralai/Devstral-Small-2505": { + id: "mistralai/Devstral-Small-2505", + name: "Mistral Devstral Small 2505", + family: "devstral", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-08-02", + last_updated: "2025-08-02", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.060000000000000005, output: 0.060000000000000005 }, + limit: { context: 32768, input: 32768, output: 8192 }, + }, + "mistralai/mistral-small-creative": { + id: "mistralai/mistral-small-creative", + name: "Mistral Small Creative", + family: "mistral-small", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + release_date: "2025-12-16", + last_updated: "2025-12-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.3 }, + limit: { context: 32768, input: 32768, output: 32768 }, + }, + "mistralai/mistral-large": { + id: "mistralai/mistral-large", + name: "Mistral Large 2411", + family: "mistral-large", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-02-26", + last_updated: "2024-02-26", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2.006, output: 6.001 }, + limit: { context: 128000, input: 128000, output: 256000 }, + }, + "mistralai/ministral-14b-2512": { + id: "mistralai/ministral-14b-2512", + name: "Ministral 14B", + family: "ministral", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-12-04", + last_updated: "2025-12-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.2 }, + limit: { context: 262144, input: 262144, output: 32768 }, + }, + "shisa-ai/shisa-v2.1-llama3.3-70b": { + id: "shisa-ai/shisa-v2.1-llama3.3-70b", + name: "Shisa V2.1 Llama 3.3 70B", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 0.5 }, + limit: { context: 32768, input: 32768, output: 4096 }, + }, + "shisa-ai/shisa-v2-llama3.3-70b": { + id: "shisa-ai/shisa-v2-llama3.3-70b", + name: "Shisa V2 Llama 3.3 70B", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-07-26", + last_updated: "2025-07-26", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 0.5 }, + limit: { context: 128000, input: 128000, output: 16384 }, + }, + "meta-llama/llama-3.3-70b-instruct": { + id: "meta-llama/llama-3.3-70b-instruct", + name: "Llama 3.3 70b Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + release_date: "2025-02-27", + last_updated: "2025-02-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.05, output: 0.23 }, + limit: { context: 131072, input: 131072, output: 16384 }, + }, + "meta-llama/llama-4-scout": { + id: "meta-llama/llama-4-scout", + name: "Llama 4 Scout", + family: "llama", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + release_date: "2025-09-05", + last_updated: "2025-09-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.085, output: 0.46 }, + limit: { context: 328000, input: 328000, output: 65536 }, + }, + "meta-llama/llama-4-maverick": { + id: "meta-llama/llama-4-maverick", + name: "Llama 4 Maverick", + family: "llama", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + release_date: "2025-09-05", + last_updated: "2025-09-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.18000000000000002, output: 0.8 }, + limit: { context: 1048576, input: 1048576, output: 65536 }, + }, + "meta-llama/llama-3.2-90b-vision-instruct": { + id: "meta-llama/llama-3.2-90b-vision-instruct", + name: "Llama 3.2 Medium", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-09-25", + last_updated: "2025-09-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.9009999999999999, output: 0.9009999999999999 }, + limit: { context: 131072, input: 131072, output: 16384 }, + }, + "meta-llama/llama-3.2-3b-instruct": { + id: "meta-llama/llama-3.2-3b-instruct", + name: "Llama 3.2 3b Instruct", + family: "llama", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-09-25", + last_updated: "2024-09-25", + modalities: { input: ["text", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.0306, output: 0.0493 }, + limit: { context: 131072, input: 131072, output: 8192 }, + }, + "meta-llama/llama-3.1-8b-instruct": { + id: "meta-llama/llama-3.1-8b-instruct", + name: "Llama 3.1 8b Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.0544, output: 0.0544 }, + limit: { context: 131072, input: 131072, output: 16384 }, + }, + "GalrionSoftworks/MN-LooseCannon-12B-v1": { + id: "GalrionSoftworks/MN-LooseCannon-12B-v1", + name: "MN-LooseCannon-12B-v1", + family: "mistral-nemo", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-07-01", + last_updated: "2024-07-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.49299999999999994, output: 0.49299999999999994 }, + limit: { context: 16384, input: 16384, output: 8192 }, + }, + "baseten/Kimi-K2-Instruct-FP4": { + id: "baseten/Kimi-K2-Instruct-FP4", + name: "Kimi K2 0711 Instruct FP4", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-07-11", + last_updated: "2025-07-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 2 }, + limit: { context: 128000, input: 128000, output: 131072 }, + }, + "Gryphe/MythoMax-L2-13b": { + id: "Gryphe/MythoMax-L2-13b", + name: "MythoMax 13B", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-08-08", + last_updated: "2025-08-08", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1003, output: 0.1003 }, + limit: { context: 4000, input: 4000, output: 4096 }, + }, + "x-ai/grok-4-fast:thinking": { + id: "x-ai/grok-4-fast:thinking", + name: "Grok 4 Fast Thinking", + family: "grok", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-07-09", + last_updated: "2025-07-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5 }, + limit: { context: 2000000, input: 2000000, output: 131072 }, + }, + "x-ai/grok-4-07-09": { + id: "x-ai/grok-4-07-09", + name: "Grok 4", + family: "grok", + attachment: true, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-07-09", + last_updated: "2025-07-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15 }, + limit: { context: 256000, input: 256000, output: 131072 }, + }, + "x-ai/grok-4-fast": { + id: "x-ai/grok-4-fast", + name: "Grok 4 Fast", + family: "grok", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-09-20", + last_updated: "2025-09-20", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5 }, + limit: { context: 2000000, input: 2000000, output: 131072 }, + }, + "x-ai/grok-code-fast-1": { + id: "x-ai/grok-code-fast-1", + name: "Grok Code Fast 1", + family: "grok", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-08-28", + last_updated: "2025-08-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 1.5 }, + limit: { context: 256000, input: 256000, output: 131072 }, + }, + "x-ai/grok-4.1-fast": { + id: "x-ai/grok-4.1-fast", + name: "Grok 4.1 Fast", + family: "grok", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-11-20", + last_updated: "2025-11-20", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5 }, + limit: { context: 2000000, input: 2000000, output: 131072 }, + }, + "x-ai/grok-4.1-fast-reasoning": { + id: "x-ai/grok-4.1-fast-reasoning", + name: "Grok 4.1 Fast Reasoning", + family: "grok", + attachment: true, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-11-20", + last_updated: "2025-11-20", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5 }, + limit: { context: 2000000, input: 2000000, output: 131072 }, + }, + "tencent/Hunyuan-MT-7B": { + id: "tencent/Hunyuan-MT-7B", + name: "Hunyuan MT 7B", + family: "hunyuan", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-09-18", + last_updated: "2025-09-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 10, output: 20 }, + limit: { context: 8192, input: 8192, output: 8192 }, + }, + "microsoft/wizardlm-2-8x22b": { + id: "microsoft/wizardlm-2-8x22b", + name: "WizardLM-2 8x22B", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-04-15", + last_updated: "2025-04-15", + modalities: { input: ["text", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.49299999999999994, output: 0.49299999999999994 }, + limit: { context: 65536, input: 65536, output: 8192 }, + }, + "microsoft/MAI-DS-R1-FP8": { + id: "microsoft/MAI-DS-R1-FP8", + name: "Microsoft DeepSeek R1", + family: "deepseek", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-09-25", + last_updated: "2025-09-25", + modalities: { input: ["text", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 0.3 }, + limit: { context: 128000, input: 128000, output: 8192 }, + }, + "cohere/command-r": { + id: "cohere/command-r", + name: "Cohere: Command R", + family: "command-r", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-03-11", + last_updated: "2024-03-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.476, output: 1.428 }, + limit: { context: 128000, input: 128000, output: 4096 }, + }, + "cohere/command-r-plus-08-2024": { + id: "cohere/command-r-plus-08-2024", + name: "Cohere: Command R+", + family: "command-r", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: false, + release_date: "2024-08-30", + last_updated: "2024-08-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2.856, output: 14.246 }, + limit: { context: 128000, input: 128000, output: 4096 }, + }, + "chutesai/Mistral-Small-3.2-24B-Instruct-2506": { + id: "chutesai/Mistral-Small-3.2-24B-Instruct-2506", + name: "Mistral Small 3.2 24b Instruct", + family: "chutesai", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-04-15", + last_updated: "2025-04-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.4 }, + limit: { context: 128000, input: 128000, output: 131072 }, + }, + "nvidia/Llama-3.1-Nemotron-Ultra-253B-v1": { + id: "nvidia/Llama-3.1-Nemotron-Ultra-253B-v1", + name: "Nvidia Nemotron Ultra 253B", + family: "nemotron", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-07-03", + last_updated: "2025-07-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 0.8 }, + limit: { context: 128000, input: 128000, output: 16384 }, + }, + "nvidia/nemotron-3-nano-30b-a3b": { + id: "nvidia/nemotron-3-nano-30b-a3b", + name: "Nvidia Nemotron 3 Nano 30B", + family: "nemotron", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-12-15", + last_updated: "2025-12-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.17, output: 0.68 }, + limit: { context: 256000, input: 256000, output: 262144 }, + }, + "nvidia/nvidia-nemotron-nano-9b-v2": { + id: "nvidia/nvidia-nemotron-nano-9b-v2", + name: "Nvidia Nemotron Nano 9B v2", + family: "nemotron", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-08-18", + last_updated: "2025-08-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.17, output: 0.68 }, + limit: { context: 128000, input: 128000, output: 16384 }, + }, + "nvidia/Llama-3.1-Nemotron-70B-Instruct-HF": { + id: "nvidia/Llama-3.1-Nemotron-70B-Instruct-HF", + name: "Nvidia Nemotron 70b", + family: "nemotron", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-04-15", + last_updated: "2025-04-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.357, output: 0.408 }, + limit: { context: 16384, input: 16384, output: 8192 }, + }, + "nvidia/Llama-3.3-Nemotron-Super-49B-v1": { + id: "nvidia/Llama-3.3-Nemotron-Super-49B-v1", + name: "Nvidia Nemotron Super 49B", + family: "nemotron", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-08-08", + last_updated: "2025-08-08", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.15 }, + limit: { context: 128000, input: 128000, output: 16384 }, + }, + "nvidia/Llama-3_3-Nemotron-Super-49B-v1_5": { + id: "nvidia/Llama-3_3-Nemotron-Super-49B-v1_5", + name: "Nvidia Nemotron Super 49B v1.5", + family: "nemotron", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-08-08", + last_updated: "2025-08-08", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.05, output: 0.25 }, + limit: { context: 128000, input: 128000, output: 16384 }, + }, + "TheDrummer 2/Anubis-70B-v1": { + id: "TheDrummer 2/Anubis-70B-v1", + name: "Anubis 70B v1", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-07-01", + last_updated: "2024-07-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.31, output: 0.31 }, + limit: { context: 65536, input: 65536, output: 16384 }, + }, + "TheDrummer 2/Cydonia-24B-v4.3": { + id: "TheDrummer 2/Cydonia-24B-v4.3", + name: "The Drummer Cydonia 24B v4.3", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-12-25", + last_updated: "2025-12-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1003, output: 0.1207 }, + limit: { context: 32768, input: 32768, output: 32768 }, + }, + "TheDrummer 2/Magidonia-24B-v4.3": { + id: "TheDrummer 2/Magidonia-24B-v4.3", + name: "The Drummer Magidonia 24B v4.3", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-12-25", + last_updated: "2025-12-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1003, output: 0.1207 }, + limit: { context: 32768, input: 32768, output: 32768 }, + }, + "TheDrummer 2/Cydonia-24B-v4": { + id: "TheDrummer 2/Cydonia-24B-v4", + name: "The Drummer Cydonia 24B v4", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-07-22", + last_updated: "2025-07-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2006, output: 0.2414 }, + limit: { context: 16384, input: 16384, output: 32768 }, + }, + "TheDrummer 2/Anubis-70B-v1.1": { + id: "TheDrummer 2/Anubis-70B-v1.1", + name: "Anubis 70B v1.1", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-07-01", + last_updated: "2024-07-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.31, output: 0.31 }, + limit: { context: 131072, input: 131072, output: 16384 }, + }, + "TheDrummer 2/Rocinante-12B-v1.1": { + id: "TheDrummer 2/Rocinante-12B-v1.1", + name: "Rocinante 12b", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-07-01", + last_updated: "2024-07-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.408, output: 0.595 }, + limit: { context: 16384, input: 16384, output: 8192 }, + }, + "TheDrummer 2/Cydonia-24B-v4.1": { + id: "TheDrummer 2/Cydonia-24B-v4.1", + name: "The Drummer Cydonia 24B v4.1", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-08-19", + last_updated: "2025-08-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1003, output: 0.1207 }, + limit: { context: 16384, input: 16384, output: 32768 }, + }, + "TheDrummer 2/UnslopNemo-12B-v4.1": { + id: "TheDrummer 2/UnslopNemo-12B-v4.1", + name: "UnslopNemo 12b v4", + family: "llama", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-07-01", + last_updated: "2024-07-01", + modalities: { input: ["text", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.49299999999999994, output: 0.49299999999999994 }, + limit: { context: 32768, input: 32768, output: 8192 }, + }, + "TheDrummer 2/Cydonia-24B-v2": { + id: "TheDrummer 2/Cydonia-24B-v2", + name: "The Drummer Cydonia 24B v2", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-02-17", + last_updated: "2025-02-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1003, output: 0.1207 }, + limit: { context: 16384, input: 16384, output: 32768 }, + }, + "TheDrummer 2/skyfall-36b-v2": { + id: "TheDrummer 2/skyfall-36b-v2", + name: "TheDrummer Skyfall 36B V2", + family: "llama", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-03-10", + last_updated: "2025-03-10", + modalities: { input: ["text", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.49299999999999994, output: 0.49299999999999994 }, + limit: { context: 64000, input: 64000, output: 32768 }, + }, + "deepseek-ai/DeepSeek-V3.1:thinking": { + id: "deepseek-ai/DeepSeek-V3.1:thinking", + name: "DeepSeek V3.1 Thinking", + family: "deepseek-thinking", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-08-21", + last_updated: "2025-08-21", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.7 }, + limit: { context: 128000, input: 128000, output: 65536 }, + }, + "deepseek-ai/DeepSeek-V3.1": { + id: "deepseek-ai/DeepSeek-V3.1", + name: "DeepSeek V3.1", + family: "deepseek", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-07-26", + last_updated: "2025-07-26", + modalities: { input: ["text", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.7 }, + limit: { context: 128000, input: 128000, output: 65536 }, + }, + "deepseek-ai/DeepSeek-V3.1-Terminus:thinking": { + id: "deepseek-ai/DeepSeek-V3.1-Terminus:thinking", + name: "DeepSeek V3.1 Terminus (Thinking)", + family: "deepseek-thinking", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + release_date: "2025-09-22", + last_updated: "2025-09-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 0.7 }, + limit: { context: 128000, input: 128000, output: 65536 }, + }, + "deepseek-ai/deepseek-v3.2-exp-thinking": { + id: "deepseek-ai/deepseek-v3.2-exp-thinking", + name: "DeepSeek V3.2 Exp Thinking", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.27999999999999997, output: 0.42000000000000004 }, + limit: { context: 163840, input: 163840, output: 65536 }, + }, + "deepseek-ai/deepseek-v3.2-exp": { + id: "deepseek-ai/deepseek-v3.2-exp", + name: "DeepSeek V3.2 Exp", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.27999999999999997, output: 0.42000000000000004 }, + limit: { context: 163840, input: 163840, output: 65536 }, + }, + "deepseek-ai/DeepSeek-R1-0528": { + id: "deepseek-ai/DeepSeek-R1-0528", + name: "DeepSeek R1 0528", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-05-28", + last_updated: "2025-05-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 1.7 }, + limit: { context: 128000, input: 128000, output: 163840 }, + }, + "deepseek-ai/DeepSeek-V3.1-Terminus": { + id: "deepseek-ai/DeepSeek-V3.1-Terminus", + name: "DeepSeek V3.1 Terminus", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + release_date: "2025-08-02", + last_updated: "2025-08-02", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 0.7 }, + limit: { context: 128000, input: 128000, output: 65536 }, + }, + "openai/gpt-5.1-codex-max": { + id: "openai/gpt-5.1-codex-max", + name: "GPT 5.1 Codex Max", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 20 }, + limit: { context: 400000, input: 400000, output: 128000 }, + }, + "openai/gpt-5.2-chat": { + id: "openai/gpt-5.2-chat", + name: "GPT 5.2 Chat", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2026-01-01", + last_updated: "2026-01-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14 }, + limit: { context: 400000, input: 400000, output: 16384 }, + }, + "openai/gpt-4o-mini-search-preview": { + id: "openai/gpt-4o-mini-search-preview", + name: "GPT-4o mini Search Preview", + family: "gpt-mini", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-07-18", + last_updated: "2024-07-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.088, output: 0.35 }, + limit: { context: 128000, input: 128000, output: 16384 }, + }, + "openai/chatgpt-4o-latest": { + id: "openai/chatgpt-4o-latest", + name: "ChatGPT 4o", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + release_date: "2024-05-13", + last_updated: "2024-05-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 4.998, output: 14.993999999999998 }, + limit: { context: 128000, input: 128000, output: 16384 }, + }, + "openai/gpt-5.2-pro": { + id: "openai/gpt-5.2-pro", + name: "GPT 5.2 Pro", + family: "gpt-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2026-01-01", + last_updated: "2026-01-01", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 21, output: 168 }, + limit: { context: 400000, input: 400000, output: 128000 }, + }, + "openai/gpt-5-mini": { + id: "openai/gpt-5-mini", + name: "GPT 5 Mini", + family: "gpt-mini", + attachment: true, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 2 }, + limit: { context: 400000, input: 400000, output: 128000 }, + }, + "openai/gpt-5-nano": { + id: "openai/gpt-5-nano", + name: "GPT 5 Nano", + family: "gpt-nano", + attachment: true, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.05, output: 0.4 }, + limit: { context: 400000, input: 400000, output: 128000 }, + }, + "openai/gpt-4-turbo": { + id: "openai/gpt-4-turbo", + name: "GPT-4 Turbo", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2023-11-06", + last_updated: "2024-01-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 10, output: 30 }, + limit: { context: 128000, input: 128000, output: 4096 }, + }, + "openai/gpt-5.2": { + id: "openai/gpt-5.2", + name: "GPT 5.2", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2026-01-01", + last_updated: "2026-01-01", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14 }, + limit: { context: 400000, input: 400000, output: 128000 }, + }, + "openai/o3-mini-high": { + id: "openai/o3-mini-high", + name: "OpenAI o3-mini (High)", + family: "o-mini", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-01-31", + last_updated: "2025-01-31", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.64, output: 2.588 }, + limit: { context: 200000, input: 200000, output: 100000 }, + }, + "openai/gpt-4o-mini": { + id: "openai/gpt-4o-mini", + name: "GPT-4o mini", + family: "gpt-mini", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-07-18", + last_updated: "2024-07-18", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1496, output: 0.595 }, + limit: { context: 128000, input: 128000, output: 16384 }, + }, + "openai/o4-mini-deep-research": { + id: "openai/o4-mini-deep-research", + name: "OpenAI o4-mini Deep Research", + family: "o-mini", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-04-16", + last_updated: "2025-04-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 9.996, output: 19.992 }, + limit: { context: 200000, input: 200000, output: 100000 }, + }, + "openai/gpt-5.1-chat": { + id: "openai/gpt-5.1-chat", + name: "GPT 5.1 Chat", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10 }, + limit: { context: 400000, input: 400000, output: 128000 }, + }, + "openai/o4-mini": { + id: "openai/o4-mini", + name: "OpenAI o4-mini", + family: "o-mini", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-04-16", + last_updated: "2025-04-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 4.4 }, + limit: { context: 200000, input: 200000, output: 100000 }, + }, + "openai/gpt-5.2-codex": { + id: "openai/gpt-5.2-codex", + name: "GPT 5.2 Codex", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2026-01-14", + last_updated: "2026-01-14", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14 }, + limit: { context: 400000, input: 400000, output: 128000 }, + }, + "openai/gpt-5.1-codex-mini": { + id: "openai/gpt-5.1-codex-mini", + name: "GPT 5.1 Codex Mini", + family: "gpt-codex-mini", + attachment: true, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 2 }, + limit: { context: 400000, input: 400000, output: 128000 }, + }, + "openai/o1-preview": { + id: "openai/o1-preview", + name: "OpenAI o1-preview", + family: "o", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2024-09-12", + last_updated: "2024-09-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 14.993999999999998, output: 59.993 }, + limit: { context: 128000, input: 128000, output: 32768 }, + }, + "openai/gpt-4o-2024-08-06": { + id: "openai/gpt-4o-2024-08-06", + name: "GPT-4o (2024-08-06)", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-08-06", + last_updated: "2024-08-06", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2.499, output: 9.996 }, + limit: { context: 128000, input: 128000, output: 16384 }, + }, + "openai/gpt-5.1": { + id: "openai/gpt-5.1", + name: "GPT 5.1", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10 }, + limit: { context: 400000, input: 400000, output: 128000 }, + }, + "openai/o1": { + id: "openai/o1", + name: "OpenAI o1", + family: "o", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2024-12-17", + last_updated: "2024-12-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 14.993999999999998, output: 59.993 }, + limit: { context: 200000, input: 200000, output: 100000 }, + }, + "openai/gpt-3.5-turbo": { + id: "openai/gpt-3.5-turbo", + name: "GPT-3.5 Turbo", + family: "gpt", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2022-11-30", + last_updated: "2024-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 1.5 }, + limit: { context: 16385, input: 16385, output: 4096 }, + }, + "openai/o3-deep-research": { + id: "openai/o3-deep-research", + name: "OpenAI o3 Deep Research", + family: "o", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-04-16", + last_updated: "2025-04-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 9.996, output: 19.992 }, + limit: { context: 200000, input: 200000, output: 100000 }, + }, + "openai/o3-mini": { + id: "openai/o3-mini", + name: "OpenAI o3-mini", + family: "o-mini", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-01-31", + last_updated: "2025-01-31", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 4.4 }, + limit: { context: 200000, input: 200000, output: 100000 }, + }, + "openai/gpt-4-turbo-preview": { + id: "openai/gpt-4-turbo-preview", + name: "GPT-4 Turbo Preview", + family: "gpt", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2023-11-06", + last_updated: "2024-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 9.996, output: 30.004999999999995 }, + limit: { context: 128000, input: 128000, output: 4096 }, + }, + "openai/o1-pro": { + id: "openai/o1-pro", + name: "OpenAI o1 Pro", + family: "o-pro", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-01-25", + last_updated: "2025-01-25", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 150, output: 600 }, + limit: { context: 200000, input: 200000, output: 100000 }, + }, + "openai/gpt-5-codex": { + id: "openai/gpt-5-codex", + name: "GPT-5 Codex", + family: "gpt-codex", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-09-15", + last_updated: "2025-09-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 9.996, output: 19.992 }, + limit: { context: 256000, input: 256000, output: 32768 }, + }, + "openai/gpt-5.1-chat-latest": { + id: "openai/gpt-5.1-chat-latest", + name: "GPT 5.1 Chat (Latest)", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10 }, + limit: { context: 400000, input: 400000, output: 16384 }, + }, + "openai/gpt-4o-search-preview": { + id: "openai/gpt-4o-search-preview", + name: "GPT-4o Search Preview", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-05-13", + last_updated: "2024-05-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.47, output: 5.88 }, + limit: { context: 128000, input: 128000, output: 16384 }, + }, + "openai/gpt-4.1-nano": { + id: "openai/gpt-4.1-nano", + name: "GPT 4.1 Nano", + family: "gpt-nano", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-04-14", + last_updated: "2025-04-14", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4 }, + limit: { context: 1047576, input: 1047576, output: 32768 }, + }, + "openai/o4-mini-high": { + id: "openai/o4-mini-high", + name: "OpenAI o4-mini high", + family: "o-mini", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-04-16", + last_updated: "2025-04-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 4.4 }, + limit: { context: 200000, input: 200000, output: 100000 }, + }, + "openai/o3": { + id: "openai/o3", + name: "OpenAI o3", + family: "o", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-04-16", + last_updated: "2025-04-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 8 }, + limit: { context: 200000, input: 200000, output: 100000 }, + }, + "openai/gpt-oss-20b": { + id: "openai/gpt-oss-20b", + name: "GPT OSS 20B", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.04, output: 0.15 }, + limit: { context: 128000, input: 128000, output: 16384 }, + }, + "openai/gpt-5-pro": { + id: "openai/gpt-5-pro", + name: "GPT 5 Pro", + family: "gpt-pro", + attachment: true, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 120 }, + limit: { context: 400000, input: 400000, output: 128000 }, + }, + "openai/gpt-5.1-2025-11-13": { + id: "openai/gpt-5.1-2025-11-13", + name: "GPT-5.1 (2025-11-13)", + family: "gpt", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10 }, + limit: { context: 1000000, input: 1000000, output: 32768 }, + }, + "openai/gpt-4o": { + id: "openai/gpt-4o", + name: "GPT-4o", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-05-13", + last_updated: "2024-05-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2.499, output: 9.996 }, + limit: { context: 128000, input: 128000, output: 16384 }, + }, + "openai/o3-mini-low": { + id: "openai/o3-mini-low", + name: "OpenAI o3-mini (Low)", + family: "o-mini", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-01-31", + last_updated: "2025-01-31", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 9.996, output: 19.992 }, + limit: { context: 200000, input: 200000, output: 100000 }, + }, + "openai/gpt-5": { + id: "openai/gpt-5", + name: "GPT 5", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10 }, + limit: { context: 400000, input: 400000, output: 128000 }, + }, + "openai/gpt-oss-safeguard-20b": { + id: "openai/gpt-oss-safeguard-20b", + name: "GPT OSS Safeguard 20B", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-10-29", + last_updated: "2025-10-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.075, output: 0.3 }, + limit: { context: 128000, input: 128000, output: 16384 }, + }, + "openai/o3-pro-2025-06-10": { + id: "openai/o3-pro-2025-06-10", + name: "OpenAI o3-pro (2025-06-10)", + family: "o-pro", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-06-10", + last_updated: "2025-06-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 9.996, output: 19.992 }, + limit: { context: 200000, input: 200000, output: 100000 }, + }, + "openai/gpt-oss-120b": { + id: "openai/gpt-oss-120b", + name: "GPT OSS 120B", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.05, output: 0.25 }, + limit: { context: 128000, input: 128000, output: 16384 }, + }, + "openai/gpt-5-chat-latest": { + id: "openai/gpt-5-chat-latest", + name: "GPT 5 Chat", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10 }, + limit: { context: 400000, input: 400000, output: 128000 }, + }, + "openai/gpt-4.1": { + id: "openai/gpt-4.1", + name: "GPT 4.1", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + release_date: "2025-09-10", + last_updated: "2025-09-10", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 8 }, + limit: { context: 1047576, input: 1047576, output: 32768 }, + }, + "openai/gpt-4.1-mini": { + id: "openai/gpt-4.1-mini", + name: "GPT 4.1 Mini", + family: "gpt-mini", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-04-14", + last_updated: "2025-04-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 1.6 }, + limit: { context: 1047576, input: 1047576, output: 32768 }, + }, + "openai/gpt-5.1-codex": { + id: "openai/gpt-5.1-codex", + name: "GPT 5.1 Codex", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10 }, + limit: { context: 400000, input: 400000, output: 128000 }, + }, + "openai/gpt-4o-2024-11-20": { + id: "openai/gpt-4o-2024-11-20", + name: "GPT-4o (2024-11-20)", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-11-20", + last_updated: "2024-11-20", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 10 }, + limit: { context: 128000, input: 128000, output: 16384 }, + }, + "VongolaChouko/Starcannon-Unleashed-12B-v1.0": { + id: "VongolaChouko/Starcannon-Unleashed-12B-v1.0", + name: "Mistral Nemo Starcannon 12b v1", + family: "mistral-nemo", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-07-01", + last_updated: "2024-07-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.49299999999999994, output: 0.49299999999999994 }, + limit: { context: 16384, input: 16384, output: 8192 }, + }, + "amazon/nova-lite-v1": { + id: "amazon/nova-lite-v1", + name: "Amazon Nova Lite 1.0", + family: "nova-lite", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-03", + last_updated: "2024-12-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.0595, output: 0.238 }, + limit: { context: 300000, input: 300000, output: 5120 }, + }, + "amazon/nova-pro-v1": { + id: "amazon/nova-pro-v1", + name: "Amazon Nova Pro 1.0", + family: "nova-pro", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-03", + last_updated: "2024-12-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.7989999999999999, output: 3.1959999999999997 }, + limit: { context: 300000, input: 300000, output: 32000 }, + }, + "amazon/nova-2-lite-v1": { + id: "amazon/nova-2-lite-v1", + name: "Amazon Nova 2 Lite", + family: "nova", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-03", + last_updated: "2024-12-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5099999999999999, output: 4.25 }, + limit: { context: 1000000, input: 1000000, output: 65535 }, + }, + "amazon/nova-micro-v1": { + id: "amazon/nova-micro-v1", + name: "Amazon Nova Micro 1.0", + family: "nova-micro", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-03", + last_updated: "2024-12-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.0357, output: 0.1394 }, + limit: { context: 128000, input: 128000, output: 5120 }, + }, + "Sao10K/L3.3-70B-Euryale-v2.3": { + id: "Sao10K/L3.3-70B-Euryale-v2.3", + name: "Llama 3.3 70B Euryale", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.49299999999999994, output: 0.49299999999999994 }, + limit: { context: 20480, input: 20480, output: 16384 }, + }, + "Sao10K/L3.1-70B-Euryale-v2.2": { + id: "Sao10K/L3.1-70B-Euryale-v2.2", + name: "Llama 3.1 70B Euryale", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.306, output: 0.357 }, + limit: { context: 20480, input: 20480, output: 16384 }, + }, + "Sao10K/L3.1-70B-Hanami-x1": { + id: "Sao10K/L3.1-70B-Hanami-x1", + name: "Llama 3.1 70B Hanami", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.49299999999999994, output: 0.49299999999999994 }, + limit: { context: 16384, input: 16384, output: 16384 }, + }, + "Sao10K/L3-8B-Stheno-v3.2": { + id: "Sao10K/L3-8B-Stheno-v3.2", + name: "Sao10K Stheno 8b", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-11-29", + last_updated: "2024-11-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2006, output: 0.2006 }, + limit: { context: 16384, input: 16384, output: 8192 }, + }, + "LatitudeGames/Wayfarer-Large-70B-Llama-3.3": { + id: "LatitudeGames/Wayfarer-Large-70B-Llama-3.3", + name: "Llama 3.3 70B Wayfarer", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-02-20", + last_updated: "2025-02-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.700000007, output: 0.700000007 }, + limit: { context: 16384, input: 16384, output: 16384 }, + }, + "z-ai/glm-4.6:thinking": { + id: "z-ai/glm-4.6:thinking", + name: "GLM 4.6 Thinking", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 1.5 }, + limit: { context: 200000, input: 200000, output: 65535 }, + }, + "z-ai/glm-4.5v": { + id: "z-ai/glm-4.5v", + name: "GLM 4.5V", + family: "glmv", + attachment: true, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-11-22", + last_updated: "2025-11-22", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.6, output: 1.7999999999999998 }, + limit: { context: 64000, input: 64000, output: 96000 }, + }, + "z-ai/glm-4.6": { + id: "z-ai/glm-4.6", + name: "GLM 4.6", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-09-30", + last_updated: "2025-09-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 1.5 }, + limit: { context: 200000, input: 200000, output: 65535 }, + }, + "z-ai/glm-4.5v:thinking": { + id: "z-ai/glm-4.5v:thinking", + name: "GLM 4.5V Thinking", + family: "glmv", + attachment: true, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-11-22", + last_updated: "2025-11-22", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.6, output: 1.7999999999999998 }, + limit: { context: 64000, input: 64000, output: 96000 }, + }, + "baidu/ernie-4.5-vl-28b-a3b": { + id: "baidu/ernie-4.5-vl-28b-a3b", + name: "ERNIE 4.5 VL 28B", + family: "ernie", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-06-30", + last_updated: "2025-06-30", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.13999999999999999, output: 0.5599999999999999 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "baidu/ernie-4.5-300b-a47b": { + id: "baidu/ernie-4.5-300b-a47b", + name: "ERNIE 4.5 300B", + family: "ernie", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-06-30", + last_updated: "2025-06-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.35, output: 1.15 }, + limit: { context: 131072, input: 131072, output: 16384 }, + }, + "dmind/dmind-1": { + id: "dmind/dmind-1", + name: "DMind-1", + family: "gpt", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-06-01", + last_updated: "2025-06-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 0.6 }, + limit: { context: 32768, input: 32768, output: 8192 }, + }, + "dmind/dmind-1-mini": { + id: "dmind/dmind-1-mini", + name: "DMind-1-Mini", + family: "gpt", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-06-01", + last_updated: "2025-06-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.4 }, + limit: { context: 32768, input: 32768, output: 8192 }, + }, + "Infermatic/MN-12B-Inferor-v0.0": { + id: "Infermatic/MN-12B-Inferor-v0.0", + name: "Mistral Nemo Inferor 12B", + family: "mistral-nemo", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-07-01", + last_updated: "2024-07-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25499999999999995, output: 0.49299999999999994 }, + limit: { context: 16384, input: 16384, output: 8192 }, + }, + "meituan-longcat/LongCat-Flash-Chat-FP8": { + id: "meituan-longcat/LongCat-Flash-Chat-FP8", + name: "LongCat Flash", + family: "longcat", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + release_date: "2025-08-31", + last_updated: "2025-08-31", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.7 }, + limit: { context: 128000, input: 128000, output: 32768 }, + }, + "meganova-ai/manta-mini-1.0": { + id: "meganova-ai/manta-mini-1.0", + name: "Manta Mini 1.0", + family: "nova", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-12-20", + last_updated: "2025-12-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.02, output: 0.16 }, + limit: { context: 8192, input: 8192, output: 8192 }, + }, + "meganova-ai/manta-pro-1.0": { + id: "meganova-ai/manta-pro-1.0", + name: "Manta Pro 1.0", + family: "nova", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-12-20", + last_updated: "2025-12-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.060000000000000005, output: 0.5 }, + limit: { context: 32768, input: 32768, output: 32768 }, + }, + "meganova-ai/manta-flash-1.0": { + id: "meganova-ai/manta-flash-1.0", + name: "Manta Flash 1.0", + family: "nova", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-12-20", + last_updated: "2025-12-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.02, output: 0.16 }, + limit: { context: 16384, input: 16384, output: 16384 }, + }, + "minimax/minimax-m2.7": { + id: "minimax/minimax-m2.7", + name: "MiniMax M2.7", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 204800, input: 204800, output: 131072 }, + }, + "minimax/minimax-01": { + id: "minimax/minimax-01", + name: "MiniMax 01", + family: "minimax", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-01-15", + last_updated: "2025-01-15", + modalities: { input: ["text", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1394, output: 1.1219999999999999 }, + limit: { context: 1000192, input: 1000192, output: 16384 }, + }, + "minimax/minimax-m2.1": { + id: "minimax/minimax-m2.1", + name: "MiniMax M2.1", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-12-19", + last_updated: "2025-12-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.33, output: 1.32 }, + limit: { context: 200000, input: 200000, output: 131072 }, + }, + "minimax/minimax-m2-her": { + id: "minimax/minimax-m2-her", + name: "MiniMax M2-her", + family: "minimax", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2026-01-24", + last_updated: "2026-01-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.30200000000000005, output: 1.2069999999999999 }, + limit: { context: 65532, input: 65532, output: 2048 }, + }, + "minimax/minimax-m2.5": { + id: "minimax/minimax-m2.5", + name: "MiniMax M2.5", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 204800, input: 204800, output: 131072 }, + }, + "qwen/Qwen3.6-35B-A3B:thinking": { + id: "qwen/Qwen3.6-35B-A3B:thinking", + name: "Qwen3.6 35B A3B Thinking", + family: "qwen3.6", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2026-04-19", + last_updated: "2026-04-21", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.29, output: 1.74 }, + limit: { context: 262144, output: 16384 }, + }, + "qwen/qwen3.5-397b-a17b": { + id: "qwen/qwen3.5-397b-a17b", + name: "Qwen3.5 397B A17B", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2026-02-16", + last_updated: "2026-02-16", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 3.6 }, + limit: { context: 258048, input: 258048, output: 65536 }, + }, + "qwen/Qwen3.6-35B-A3B": { + id: "qwen/Qwen3.6-35B-A3B", + name: "Qwen3.6 35B A3B", + family: "qwen3.6", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2026-04-17", + last_updated: "2026-04-21", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.29, output: 1.74 }, + limit: { context: 262144, output: 16384 }, + }, + "unsloth/gemma-3-1b-it": { + id: "unsloth/gemma-3-1b-it", + name: "Gemma 3 1B IT", + family: "unsloth", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-03-10", + last_updated: "2025-03-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1003, output: 0.1003 }, + limit: { context: 128000, input: 128000, output: 8192 }, + }, + "unsloth/gemma-3-12b-it": { + id: "unsloth/gemma-3-12b-it", + name: "Gemma 3 12B IT", + family: "unsloth", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-03-10", + last_updated: "2025-03-10", + modalities: { input: ["text", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.272, output: 0.272 }, + limit: { context: 128000, input: 128000, output: 131072 }, + }, + "unsloth/gemma-3-4b-it": { + id: "unsloth/gemma-3-4b-it", + name: "Gemma 3 4B IT", + family: "unsloth", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-03-10", + last_updated: "2025-03-10", + modalities: { input: ["text", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2006, output: 0.2006 }, + limit: { context: 128000, input: 128000, output: 8192 }, + }, + "unsloth/gemma-3-27b-it": { + id: "unsloth/gemma-3-27b-it", + name: "Gemma 3 27B IT", + family: "unsloth", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-03-10", + last_updated: "2025-03-10", + modalities: { input: ["text", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2992, output: 0.2992 }, + limit: { context: 128000, input: 128000, output: 96000 }, + }, + "THUDM/GLM-Z1-9B-0414": { + id: "THUDM/GLM-Z1-9B-0414", + name: "GLM Z1 9B 0414", + family: "glm-z", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-04-14", + last_updated: "2025-04-14", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.2 }, + limit: { context: 32000, input: 32000, output: 8000 }, + }, + "THUDM/GLM-4-9B-0414": { + id: "THUDM/GLM-4-9B-0414", + name: "GLM 4 9B 0414", + family: "glm", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-04-14", + last_updated: "2025-04-14", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.2 }, + limit: { context: 32000, input: 32000, output: 8000 }, + }, + "THUDM/GLM-Z1-Rumination-32B-0414": { + id: "THUDM/GLM-Z1-Rumination-32B-0414", + name: "GLM Z1 Rumination 32B 0414", + family: "glm-z", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-04-15", + last_updated: "2025-04-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.2 }, + limit: { context: 32000, input: 32000, output: 65536 }, + }, + "THUDM/GLM-4-32B-0414": { + id: "THUDM/GLM-4-32B-0414", + name: "GLM 4 32B 0414", + family: "glm", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-04-14", + last_updated: "2025-04-14", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.2 }, + limit: { context: 128000, input: 128000, output: 65536 }, + }, + "THUDM/GLM-Z1-32B-0414": { + id: "THUDM/GLM-Z1-32B-0414", + name: "GLM Z1 32B 0414", + family: "glm-z", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-04-15", + last_updated: "2025-04-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.2 }, + limit: { context: 128000, input: 128000, output: 65536 }, + }, + "google/gemini-3-flash-preview": { + id: "google/gemini-3-flash-preview", + name: "Gemini 3 Flash (Preview)", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-12-17", + last_updated: "2025-12-17", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 3 }, + limit: { context: 1048756, input: 1048756, output: 65536 }, + }, + "google/gemini-flash-1.5": { + id: "google/gemini-flash-1.5", + name: "Gemini 1.5 Flash", + family: "gemini-flash", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-05-14", + last_updated: "2024-05-14", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.0748, output: 0.306 }, + limit: { context: 2000000, input: 2000000, output: 8192 }, + }, + "google/gemini-3-flash-preview-thinking": { + id: "google/gemini-3-flash-preview-thinking", + name: "Gemini 3 Flash Thinking", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-12-17", + last_updated: "2025-12-17", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 3 }, + limit: { context: 1048756, input: 1048756, output: 65536 }, + }, + "moonshotai/kimi-k2.5": { + id: "moonshotai/kimi-k2.5", + name: "Kimi K2.5", + family: "kimi", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: false, + release_date: "2026-01-26", + last_updated: "2026-01-26", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 1.9 }, + limit: { context: 256000, input: 256000, output: 65536 }, + }, + "moonshotai/kimi-k2-instruct": { + id: "moonshotai/kimi-k2-instruct", + name: "Kimi K2 Instruct", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + release_date: "2025-07-01", + last_updated: "2025-07-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 2 }, + limit: { context: 256000, input: 256000, output: 8192 }, + }, + "moonshotai/kimi-k2-thinking-original": { + id: "moonshotai/kimi-k2-thinking-original", + name: "Kimi K2 Thinking Original", + family: "kimi-thinking", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-11-06", + last_updated: "2025-11-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.6, output: 2.5 }, + limit: { context: 256000, input: 256000, output: 16384 }, + }, + "moonshotai/kimi-k2-instruct-0711": { + id: "moonshotai/kimi-k2-instruct-0711", + name: "Kimi K2 0711", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + release_date: "2025-07-11", + last_updated: "2025-07-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 2 }, + limit: { context: 128000, input: 128000, output: 8192 }, + }, + "moonshotai/Kimi-Dev-72B": { + id: "moonshotai/Kimi-Dev-72B", + name: "Kimi Dev 72B", + family: "kimi", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-04-15", + last_updated: "2025-04-15", + modalities: { input: ["text", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 0.4 }, + limit: { context: 128000, input: 128000, output: 131072 }, + }, + "moonshotai/kimi-k2-thinking-turbo-original": { + id: "moonshotai/kimi-k2-thinking-turbo-original", + name: "Kimi K2 Thinking Turbo Original", + family: "kimi-thinking", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-11-06", + last_updated: "2025-11-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.15, output: 8 }, + limit: { context: 256000, input: 256000, output: 16384 }, + }, + "moonshotai/kimi-k2.6": { + id: "moonshotai/kimi-k2.6", + name: "Kimi K2.6", + family: "kimi-k2.6", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: false, + release_date: "2026-04-16", + last_updated: "2026-04-21", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.53, output: 2.73 }, + limit: { context: 256000, output: 65536 }, + }, + "moonshotai/kimi-k2.6:thinking": { + id: "moonshotai/kimi-k2.6:thinking", + name: "Kimi K2.6 Thinking", + family: "kimi-thinking", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + release_date: "2026-04-16", + last_updated: "2026-04-21", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.53, output: 2.73 }, + limit: { context: 256000, output: 65536 }, + }, + "moonshotai/Kimi-K2-Instruct-0905": { + id: "moonshotai/Kimi-K2-Instruct-0905", + name: "Kimi K2 0905", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + release_date: "2025-09-25", + last_updated: "2025-09-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 2 }, + limit: { context: 256000, input: 256000, output: 262144 }, + }, + "moonshotai/kimi-k2-thinking": { + id: "moonshotai/kimi-k2-thinking", + name: "Kimi K2 Thinking", + family: "kimi-thinking", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + release_date: "2025-11-06", + last_updated: "2025-11-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 256000, input: 256000, output: 262144 }, + }, + "moonshotai/kimi-k2.5:thinking": { + id: "moonshotai/kimi-k2.5:thinking", + name: "Kimi K2.5 Thinking", + family: "kimi-thinking", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + release_date: "2026-01-26", + last_updated: "2026-01-26", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 1.9 }, + limit: { context: 256000, input: 256000, output: 65536 }, + }, + "Tongyi-Zhiwen/QwenLong-L1-32B": { + id: "Tongyi-Zhiwen/QwenLong-L1-32B", + name: "QwenLong L1 32B", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-01-25", + last_updated: "2025-01-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.13999999999999999, output: 0.6 }, + limit: { context: 128000, input: 128000, output: 40960 }, + }, + "nothingiisreal/L3.1-70B-Celeste-V0.1-BF16": { + id: "nothingiisreal/L3.1-70B-Celeste-V0.1-BF16", + name: "Llama 3.1 70B Celeste v0.1", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.49299999999999994, output: 0.49299999999999994 }, + limit: { context: 16384, input: 16384, output: 16384 }, + }, + "aion-labs/aion-1.0": { + id: "aion-labs/aion-1.0", + name: "Aion 1.0", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-02-01", + last_updated: "2025-02-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 3.995, output: 7.99 }, + limit: { context: 65536, input: 65536, output: 8192 }, + }, + "aion-labs/aion-rp-llama-3.1-8b": { + id: "aion-labs/aion-rp-llama-3.1-8b", + name: "Llama 3.1 8b (uncensored)", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2006, output: 0.2006 }, + limit: { context: 32768, input: 32768, output: 16384 }, + }, + "aion-labs/aion-1.0-mini": { + id: "aion-labs/aion-1.0-mini", + name: "Aion 1.0 mini (DeepSeek)", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-02-20", + last_updated: "2025-02-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.7989999999999999, output: 1.394 }, + limit: { context: 131072, input: 131072, output: 8192 }, + }, + "Alibaba-NLP/Tongyi-DeepResearch-30B-A3B": { + id: "Alibaba-NLP/Tongyi-DeepResearch-30B-A3B", + name: "Tongyi DeepResearch 30B A3B", + family: "yi", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-08-26", + last_updated: "2025-08-26", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.08, output: 0.24000000000000002 }, + limit: { context: 128000, input: 128000, output: 65536 }, + }, + "MiniMaxAI/MiniMax-M1-80k": { + id: "MiniMaxAI/MiniMax-M1-80k", + name: "MiniMax M1 80K", + family: "minimax", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-06-16", + last_updated: "2025-06-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.6052, output: 2.4225000000000003 }, + limit: { context: 1000000, input: 1000000, output: 131072 }, + }, + "anthropic/claude-opus-4.6:thinking:low": { + id: "anthropic/claude-opus-4.6:thinking:low", + name: "Claude 4.6 Opus Thinking Low", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2026-02-05", + last_updated: "2026-02-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 4.998, output: 25.007 }, + limit: { context: 1000000, input: 1000000, output: 128000 }, + }, + "anthropic/claude-opus-4.6": { + id: "anthropic/claude-opus-4.6", + name: "Claude 4.6 Opus", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2026-02-05", + last_updated: "2026-02-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 4.998, output: 25.007 }, + limit: { context: 1000000, input: 1000000, output: 128000 }, + }, + "anthropic/claude-sonnet-4.6:thinking": { + id: "anthropic/claude-sonnet-4.6:thinking", + name: "Claude Sonnet 4.6 Thinking", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + knowledge: "2025-08-31", + release_date: "2026-02-17", + last_updated: "2026-02-17", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2.992, output: 14.993999999999998 }, + limit: { context: 1000000, input: 1000000, output: 128000 }, + }, + "anthropic/claude-opus-4.6:thinking:max": { + id: "anthropic/claude-opus-4.6:thinking:max", + name: "Claude 4.6 Opus Thinking Max", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2026-02-05", + last_updated: "2026-02-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 4.998, output: 25.007 }, + limit: { context: 1000000, input: 1000000, output: 128000 }, + }, + "anthropic/claude-opus-4.6:thinking:medium": { + id: "anthropic/claude-opus-4.6:thinking:medium", + name: "Claude 4.6 Opus Thinking Medium", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2026-02-05", + last_updated: "2026-02-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 4.998, output: 25.007 }, + limit: { context: 1000000, input: 1000000, output: 128000 }, + }, + "anthropic/claude-sonnet-4.6": { + id: "anthropic/claude-sonnet-4.6", + name: "Claude Sonnet 4.6", + family: "claude-sonnet", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + knowledge: "2025-08-31", + release_date: "2026-02-17", + last_updated: "2026-02-17", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2.992, output: 14.993999999999998 }, + limit: { context: 1000000, input: 1000000, output: 128000 }, + }, + "anthropic/claude-opus-4.6:thinking": { + id: "anthropic/claude-opus-4.6:thinking", + name: "Claude 4.6 Opus Thinking", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2026-02-05", + last_updated: "2026-02-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 4.998, output: 25.007 }, + limit: { context: 1000000, input: 1000000, output: 128000 }, + }, + "abacusai/Dracarys-72B-Instruct": { + id: "abacusai/Dracarys-72B-Instruct", + name: "Llama 3.1 70B Dracarys 2", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-08-02", + last_updated: "2025-08-02", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.49299999999999994, output: 0.49299999999999994 }, + limit: { context: 16384, input: 16384, output: 8192 }, + }, + "EVA-UNIT-01/EVA-LLaMA-3.33-70B-v0.0": { + id: "EVA-UNIT-01/EVA-LLaMA-3.33-70B-v0.0", + name: "EVA Llama 3.33 70B", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-07-26", + last_updated: "2025-07-26", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2.006, output: 2.006 }, + limit: { context: 16384, input: 16384, output: 16384 }, + }, + "EVA-UNIT-01/EVA-Qwen2.5-72B-v0.2": { + id: "EVA-UNIT-01/EVA-Qwen2.5-72B-v0.2", + name: "EVA-Qwen2.5-72B-v0.2", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-09-25", + last_updated: "2025-09-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.7989999999999999, output: 0.7989999999999999 }, + limit: { context: 16384, input: 16384, output: 8192 }, + }, + "EVA-UNIT-01/EVA-LLaMA-3.33-70B-v0.1": { + id: "EVA-UNIT-01/EVA-LLaMA-3.33-70B-v0.1", + name: "EVA-LLaMA-3.33-70B-v0.1", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-09-25", + last_updated: "2025-09-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2.006, output: 2.006 }, + limit: { context: 16384, input: 16384, output: 16384 }, + }, + "EVA-UNIT-01/EVA-Qwen2.5-32B-v0.2": { + id: "EVA-UNIT-01/EVA-Qwen2.5-32B-v0.2", + name: "EVA-Qwen2.5-32B-v0.2", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-07-26", + last_updated: "2025-07-26", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.7989999999999999, output: 0.7989999999999999 }, + limit: { context: 16384, input: 16384, output: 8192 }, + }, + "huihui-ai/DeepSeek-R1-Distill-Qwen-32B-abliterated": { + id: "huihui-ai/DeepSeek-R1-Distill-Qwen-32B-abliterated", + name: "DeepSeek R1 Qwen Abliterated", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-01-20", + last_updated: "2025-01-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.4, output: 1.4 }, + limit: { context: 16384, input: 16384, output: 8192 }, + }, + "huihui-ai/DeepSeek-R1-Distill-Llama-70B-abliterated": { + id: "huihui-ai/DeepSeek-R1-Distill-Llama-70B-abliterated", + name: "DeepSeek R1 Llama 70B Abliterated", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: false, + release_date: "2025-01-20", + last_updated: "2025-01-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.7, output: 0.7 }, + limit: { context: 16384, input: 16384, output: 8192 }, + }, + "huihui-ai/Llama-3.3-70B-Instruct-abliterated": { + id: "huihui-ai/Llama-3.3-70B-Instruct-abliterated", + name: "Llama 3.3 70B Instruct abliterated", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-08-08", + last_updated: "2025-08-08", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.7, output: 0.7 }, + limit: { context: 16384, input: 16384, output: 16384 }, + }, + "huihui-ai/Qwen2.5-32B-Instruct-abliterated": { + id: "huihui-ai/Qwen2.5-32B-Instruct-abliterated", + name: "Qwen 2.5 32B Abliterated", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-01-06", + last_updated: "2025-01-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.7, output: 0.7 }, + limit: { context: 32768, input: 32768, output: 8192 }, + }, + "huihui-ai/Llama-3.1-Nemotron-70B-Instruct-HF-abliterated": { + id: "huihui-ai/Llama-3.1-Nemotron-70B-Instruct-HF-abliterated", + name: "Nemotron 3.1 70B abliterated", + family: "nemotron", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.7, output: 0.7 }, + limit: { context: 16384, input: 16384, output: 16384 }, + }, + "xiaomi/mimo-v2-flash-thinking-original": { + id: "xiaomi/mimo-v2-flash-thinking-original", + name: "MiMo V2 Flash (Thinking) Original", + family: "mimo", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-12-17", + last_updated: "2025-12-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.102, output: 0.306 }, + limit: { context: 256000, input: 256000, output: 32768 }, + }, + "xiaomi/mimo-v2-flash-thinking": { + id: "xiaomi/mimo-v2-flash-thinking", + name: "MiMo V2 Flash (Thinking)", + family: "mimo", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-12-17", + last_updated: "2025-12-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.102, output: 0.306 }, + limit: { context: 256000, input: 256000, output: 32768 }, + }, + "xiaomi/mimo-v2-flash": { + id: "xiaomi/mimo-v2-flash", + name: "MiMo V2 Flash", + family: "mimo", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-12-17", + last_updated: "2025-12-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.102, output: 0.306 }, + limit: { context: 256000, input: 256000, output: 32768 }, + }, + "xiaomi/mimo-v2-flash-original": { + id: "xiaomi/mimo-v2-flash-original", + name: "MiMo V2 Flash Original", + family: "mimo", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-12-17", + last_updated: "2025-12-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.102, output: 0.306 }, + limit: { context: 256000, input: 256000, output: 32768 }, + }, + "tngtech/DeepSeek-TNG-R1T2-Chimera": { + id: "tngtech/DeepSeek-TNG-R1T2-Chimera", + name: "DeepSeek TNG R1T2 Chimera", + family: "tngtech", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-09-05", + last_updated: "2025-09-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.31, output: 0.31 }, + limit: { context: 128000, input: 128000, output: 8192 }, + }, + "tngtech/tng-r1t-chimera": { + id: "tngtech/tng-r1t-chimera", + name: "TNG R1T Chimera", + family: "tngtech", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-11-26", + last_updated: "2025-11-26", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 128000, input: 128000, output: 65536 }, + }, + "inflatebot/MN-12B-Mag-Mell-R1": { + id: "inflatebot/MN-12B-Mag-Mell-R1", + name: "Mag Mell R1", + family: "mistral-nemo", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2024-07-01", + last_updated: "2024-07-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.49299999999999994, output: 0.49299999999999994 }, + limit: { context: 16384, input: 16384, output: 8192 }, + }, + "failspy/Meta-Llama-3-70B-Instruct-abliterated-v3.5": { + id: "failspy/Meta-Llama-3-70B-Instruct-abliterated-v3.5", + name: "Llama 3 70B abliterated", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + release_date: "2025-07-26", + last_updated: "2025-07-26", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.7, output: 0.7 }, + limit: { context: 8192, input: 8192, output: 8192 }, + }, + }, + }, + abacus: { + id: "abacus", + env: ["ABACUS_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://routellm.abacus.ai/v1", + name: "Abacus", + doc: "https://abacus.ai/help/api", + models: { + "gpt-5.1-codex-max": { + id: "gpt-5.1-codex-max", + name: "GPT-5.1 Codex Max", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "claude-opus-4-5-20251101": { + id: "claude-opus-4-5-20251101", + name: "Claude Opus 4.5", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-11-01", + last_updated: "2025-11-01", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25 }, + limit: { context: 200000, output: 64000 }, + }, + "kimi-k2.5": { + id: "kimi-k2.5", + name: "Kimi K2.5", + family: "kimi", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 3 }, + limit: { context: 262144, output: 32768 }, + }, + "gemini-3.1-flash-lite-preview": { + id: "gemini-3.1-flash-lite-preview", + name: "Gemini 3.1 Flash Lite Preview", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-03-01", + last_updated: "2026-03-01", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 1.5, cache_read: 0.025, cache_write: 1 }, + limit: { context: 1048576, output: 65536 }, + }, + "claude-sonnet-4-6": { + id: "claude-sonnet-4-6", + name: "Claude Sonnet 4.6", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-08-31", + release_date: "2026-02-17", + last_updated: "2026-02-17", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15 }, + limit: { context: 200000, output: 64000 }, + }, + "gemini-3.1-pro-preview": { + id: "gemini-3.1-pro-preview", + name: "Gemini 3.1 Pro Preview", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-02-19", + last_updated: "2026-02-19", + modalities: { input: ["text", "image", "video", "audio", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 12 }, + limit: { context: 1048576, output: 65536 }, + }, + "gpt-5.3-chat-latest": { + id: "gpt-5.3-chat-latest", + name: "GPT-5.3 Chat Latest", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-01", + last_updated: "2026-03-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14 }, + limit: { context: 400000, output: 128000 }, + }, + "gemini-3-flash-preview": { + id: "gemini-3-flash-preview", + name: "Gemini 3 Flash Preview", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-12-17", + last_updated: "2025-12-17", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 3 }, + limit: { context: 1048576, output: 65536 }, + }, + "llama-3.3-70b-versatile": { + id: "llama-3.3-70b-versatile", + name: "Llama 3.3 70B Versatile", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.59, output: 0.79 }, + limit: { context: 128000, output: 32768 }, + }, + "gpt-5-mini": { + id: "gpt-5-mini", + name: "GPT-5 Mini", + family: "gpt-mini", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-05-30", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 2 }, + limit: { context: 400000, output: 128000 }, + }, + "gpt-5-nano": { + id: "gpt-5-nano", + name: "GPT-5 Nano", + family: "gpt-nano", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-05-30", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.05, output: 0.4 }, + limit: { context: 400000, output: 128000 }, + }, + "gpt-5.3-codex": { + id: "gpt-5.3-codex", + name: "GPT-5.3 Codex", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-02-05", + last_updated: "2026-02-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "claude-sonnet-4-5-20250929": { + id: "claude-sonnet-4-5-20250929", + name: "Claude Sonnet 4.5", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07-31", + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15 }, + limit: { context: 200000, output: 64000 }, + }, + "gemini-2.5-pro": { + id: "gemini-2.5-pro", + name: "Gemini 2.5 Pro", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-03-25", + last_updated: "2025-03-25", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10 }, + limit: { context: 1048576, output: 65536 }, + }, + "grok-4-1-fast-non-reasoning": { + id: "grok-4-1-fast-non-reasoning", + name: "Grok 4.1 Fast (Non-Reasoning)", + family: "grok", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-11-17", + last_updated: "2025-11-17", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5 }, + limit: { context: 2000000, output: 16384 }, + }, + "gpt-5.2": { + id: "gpt-5.2", + name: "GPT-5.2", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2025-12-11", + last_updated: "2025-12-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14 }, + limit: { context: 400000, output: 128000 }, + }, + "o3-pro": { + id: "o3-pro", + name: "o3-pro", + family: "o-pro", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-05", + release_date: "2025-06-10", + last_updated: "2025-06-10", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 20, output: 40 }, + limit: { context: 200000, output: 100000 }, + }, + "gpt-4o-mini": { + id: "gpt-4o-mini", + name: "GPT-4o Mini", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-07-18", + last_updated: "2024-07-18", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 128000, output: 16384 }, + }, + "qwen3-max": { + id: "qwen3-max", + name: "Qwen3 Max", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-05-28", + last_updated: "2025-05-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.2, output: 6 }, + limit: { context: 131072, output: 16384 }, + }, + "o4-mini": { + id: "o4-mini", + name: "o4-mini", + family: "o-mini", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-05", + release_date: "2025-04-16", + last_updated: "2025-04-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 4.4 }, + limit: { context: 200000, output: 100000 }, + }, + "gpt-5.2-codex": { + id: "gpt-5.2-codex", + name: "GPT-5.2 Codex", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2025-12-11", + last_updated: "2025-12-11", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "gemini-2.5-flash": { + id: "gemini-2.5-flash", + name: "Gemini 2.5 Flash", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-03-20", + last_updated: "2025-06-05", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 2.5 }, + limit: { context: 1048576, output: 65536 }, + }, + "gpt-5.2-chat-latest": { + id: "gpt-5.2-chat-latest", + name: "GPT-5.2 Chat Latest", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-09-30", + release_date: "2026-01-01", + last_updated: "2026-01-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14 }, + limit: { context: 400000, output: 128000 }, + }, + "gpt-5.3-codex-xhigh": { + id: "gpt-5.3-codex-xhigh", + name: "GPT-5.3 Codex XHigh", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-02-05", + last_updated: "2026-02-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "grok-code-fast-1": { + id: "grok-code-fast-1", + name: "Grok Code Fast 1", + family: "grok", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-09-01", + last_updated: "2025-09-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 1.5 }, + limit: { context: 256000, output: 16384 }, + }, + "gpt-5.1": { + id: "gpt-5.1", + name: "GPT-5.1", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10 }, + limit: { context: 400000, output: 128000 }, + }, + "o3-mini": { + id: "o3-mini", + name: "o3-mini", + family: "o-mini", + attachment: false, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-05", + release_date: "2024-12-20", + last_updated: "2025-01-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 4.4 }, + limit: { context: 200000, output: 100000 }, + }, + "grok-4-0709": { + id: "grok-4-0709", + name: "Grok 4", + family: "grok", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-07-09", + last_updated: "2025-07-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15 }, + limit: { context: 256000, output: 16384 }, + }, + "route-llm": { + id: "route-llm", + name: "Route LLM", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2024-01-01", + last_updated: "2024-01-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15 }, + limit: { context: 128000, output: 16384 }, + }, + "qwen-2.5-coder-32b": { + id: "qwen-2.5-coder-32b", + name: "Qwen 2.5 Coder 32B", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-11-11", + last_updated: "2024-11-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.79, output: 0.79 }, + limit: { context: 128000, output: 8192 }, + }, + "gpt-5-codex": { + id: "gpt-5-codex", + name: "GPT-5 Codex", + family: "gpt", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-09-15", + last_updated: "2025-09-15", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "claude-opus-4-1-20250805": { + id: "claude-opus-4-1-20250805", + name: "Claude Opus 4.1", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75 }, + limit: { context: 200000, output: 32000 }, + }, + "gpt-5.4": { + id: "gpt-5.4", + name: "GPT-5.4", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-05", + last_updated: "2026-03-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 15 }, + limit: { context: 1050000, input: 922000, output: 128000 }, + }, + "gpt-5.1-chat-latest": { + id: "gpt-5.1-chat-latest", + name: "GPT-5.1 Chat Latest", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10 }, + limit: { context: 400000, output: 128000 }, + }, + "claude-haiku-4-5-20251001": { + id: "claude-haiku-4-5-20251001", + name: "Claude Haiku 4.5", + family: "claude-haiku", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-02-28", + release_date: "2025-10-15", + last_updated: "2025-10-15", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 5 }, + limit: { context: 200000, output: 64000 }, + }, + "claude-sonnet-4-20250514": { + id: "claude-sonnet-4-20250514", + name: "Claude Sonnet 4", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-05-14", + last_updated: "2025-05-14", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15 }, + limit: { context: 200000, output: 64000 }, + }, + "kimi-k2-turbo-preview": { + id: "kimi-k2-turbo-preview", + name: "Kimi K2 Turbo Preview", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-07-08", + last_updated: "2025-07-08", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 8 }, + limit: { context: 256000, output: 8192 }, + }, + "claude-opus-4-6": { + id: "claude-opus-4-6", + name: "Claude Opus 4.6", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-05-31", + release_date: "2026-02-05", + last_updated: "2026-02-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25 }, + limit: { context: 200000, output: 128000 }, + }, + "gpt-4.1-nano": { + id: "gpt-4.1-nano", + name: "GPT-4.1 Nano", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-04-14", + last_updated: "2025-04-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4 }, + limit: { context: 1047576, output: 32768 }, + }, + "claude-3-7-sonnet-20250219": { + id: "claude-3-7-sonnet-20250219", + name: "Claude Sonnet 3.7", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10-31", + release_date: "2025-02-19", + last_updated: "2025-02-19", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15 }, + limit: { context: 200000, output: 64000 }, + }, + o3: { + id: "o3", + name: "o3", + family: "o", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-05", + release_date: "2025-04-16", + last_updated: "2025-04-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 8 }, + limit: { context: 200000, output: 100000 }, + }, + "gpt-5": { + id: "gpt-5", + name: "GPT-5", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10 }, + limit: { context: 400000, output: 128000 }, + }, + "claude-opus-4-20250514": { + id: "claude-opus-4-20250514", + name: "Claude Opus 4", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-05-14", + last_updated: "2025-05-14", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75 }, + limit: { context: 200000, output: 32000 }, + }, + "gpt-4.1": { + id: "gpt-4.1", + name: "GPT-4.1", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-04-14", + last_updated: "2025-04-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 8 }, + limit: { context: 1047576, output: 32768 }, + }, + "gpt-4.1-mini": { + id: "gpt-4.1-mini", + name: "GPT-4.1 Mini", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-04-14", + last_updated: "2025-04-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 1.6 }, + limit: { context: 1047576, output: 32768 }, + }, + "gpt-5.1-codex": { + id: "gpt-5.1-codex", + name: "GPT-5.1 Codex", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "gpt-4o-2024-11-20": { + id: "gpt-4o-2024-11-20", + name: "GPT-4o (2024-11-20)", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2024-11-20", + last_updated: "2024-11-20", + modalities: { input: ["text", "image", "audio"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 10 }, + limit: { context: 128000, output: 16384 }, + }, + "grok-4-fast-non-reasoning": { + id: "grok-4-fast-non-reasoning", + name: "Grok 4 Fast (Non-Reasoning)", + family: "grok", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-07-09", + last_updated: "2025-07-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5 }, + limit: { context: 2000000, output: 16384 }, + }, + "deepseek/deepseek-v3.1": { + id: "deepseek/deepseek-v3.1", + name: "DeepSeek V3.1", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-01-20", + last_updated: "2025-01-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.55, output: 1.66 }, + limit: { context: 128000, output: 8192 }, + }, + "Qwen/QwQ-32B": { + id: "Qwen/QwQ-32B", + name: "QwQ 32B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2024-11-28", + last_updated: "2024-11-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.4, output: 0.4 }, + limit: { context: 32768, output: 32768 }, + }, + "Qwen/Qwen3-235B-A22B-Instruct-2507": { + id: "Qwen/Qwen3-235B-A22B-Instruct-2507", + name: "Qwen3 235B A22B Instruct", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-07-01", + last_updated: "2025-07-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.13, output: 0.6 }, + limit: { context: 262144, output: 8192 }, + }, + "Qwen/Qwen3-32B": { + id: "Qwen/Qwen3-32B", + name: "Qwen3 32B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-04-29", + last_updated: "2025-04-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.09, output: 0.29 }, + limit: { context: 128000, output: 8192 }, + }, + "Qwen/qwen3-coder-480b-a35b-instruct": { + id: "Qwen/qwen3-coder-480b-a35b-instruct", + name: "Qwen3 Coder 480B A35B Instruct", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-07-22", + last_updated: "2025-07-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.29, output: 1.2 }, + limit: { context: 262144, output: 65536 }, + }, + "Qwen/Qwen2.5-72B-Instruct": { + id: "Qwen/Qwen2.5-72B-Instruct", + name: "Qwen 2.5 72B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-09-19", + last_updated: "2024-09-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.11, output: 0.38 }, + limit: { context: 128000, output: 8192 }, + }, + "zai-org/glm-4.7": { + id: "zai-org/glm-4.7", + name: "GLM-4.7", + family: "glm", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-06-01", + last_updated: "2025-06-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.2 }, + limit: { context: 128000, output: 8192 }, + }, + "zai-org/glm-5": { + id: "zai-org/glm-5", + name: "GLM-5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-11", + last_updated: "2026-02-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 3.2 }, + limit: { context: 204800, output: 131072 }, + }, + "zai-org/glm-4.5": { + id: "zai-org/glm-4.5", + name: "GLM-4.5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-07-28", + last_updated: "2025-07-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.2 }, + limit: { context: 128000, output: 8192 }, + }, + "zai-org/glm-4.6": { + id: "zai-org/glm-4.6", + name: "GLM-4.6", + family: "glm", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-03-01", + last_updated: "2025-03-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.2 }, + limit: { context: 128000, output: 8192 }, + }, + "meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo": { + id: "meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo", + name: "Llama 3.1 405B Instruct Turbo", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 3.5, output: 3.5 }, + limit: { context: 128000, output: 4096 }, + }, + "meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8": { + id: "meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8", + name: "Llama 4 Maverick 17B 128E Instruct FP8", + family: "llama", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-08", + release_date: "2025-04-05", + last_updated: "2025-04-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.14, output: 0.59 }, + limit: { context: 1000000, output: 32768 }, + }, + "meta-llama/Meta-Llama-3.1-8B-Instruct": { + id: "meta-llama/Meta-Llama-3.1-8B-Instruct", + name: "Llama 3.1 8B Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.02, output: 0.05 }, + limit: { context: 128000, output: 4096 }, + }, + "deepseek-ai/DeepSeek-R1": { + id: "deepseek-ai/DeepSeek-R1", + name: "DeepSeek R1", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-01-20", + last_updated: "2025-01-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 3, output: 7 }, + limit: { context: 128000, output: 8192 }, + }, + "deepseek-ai/DeepSeek-V3.2": { + id: "deepseek-ai/DeepSeek-V3.2", + name: "DeepSeek V3.2", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-06-15", + last_updated: "2025-06-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.27, output: 0.4 }, + limit: { context: 128000, output: 8192 }, + }, + "deepseek-ai/DeepSeek-V3.1-Terminus": { + id: "deepseek-ai/DeepSeek-V3.1-Terminus", + name: "DeepSeek V3.1 Terminus", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-06-01", + last_updated: "2025-06-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.27, output: 1 }, + limit: { context: 128000, output: 8192 }, + }, + "openai/gpt-oss-120b": { + id: "openai/gpt-oss-120b", + name: "GPT-OSS 120B", + family: "gpt-oss", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.08, output: 0.44 }, + limit: { context: 128000, output: 32768 }, + }, + }, + }, + "perplexity-agent": { + id: "perplexity-agent", + env: ["PERPLEXITY_API_KEY"], + npm: "@ai-sdk/openai", + api: "https://api.perplexity.ai/v1", + name: "Perplexity Agent", + doc: "https://docs.perplexity.ai/docs/agent-api/models", + models: { + "perplexity/sonar": { + id: "perplexity/sonar", + name: "Sonar", + family: "sonar", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-09-01", + release_date: "2024-01-01", + last_updated: "2025-09-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 2.5, cache_read: 0.0625 }, + limit: { context: 128000, output: 8192 }, + }, + "xai/grok-4-1-fast-non-reasoning": { + id: "xai/grok-4-1-fast-non-reasoning", + name: "Grok 4.1 Fast (Non-Reasoning)", + family: "grok", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-11-19", + last_updated: "2025-11-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5, cache_read: 0.05 }, + limit: { context: 2000000, output: 30000 }, + }, + "nvidia/nemotron-3-super-120b-a12b": { + id: "nvidia/nemotron-3-super-120b-a12b", + name: "Nemotron 3 Super 120B", + family: "nemotron", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2026-02", + release_date: "2026-03-11", + last_updated: "2026-03-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.25, output: 2.5 }, + limit: { context: 1000000, output: 32000 }, + }, + "openai/gpt-5.5": { + id: "openai/gpt-5.5", + name: "GPT-5.5", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2025-12-01", + release_date: "2026-04-23", + last_updated: "2026-04-23", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 30, cache_read: 0.5 }, + limit: { context: 1050000, input: 922000, output: 128000 }, + }, + "openai/gpt-5-mini": { + id: "openai/gpt-5-mini", + name: "GPT-5 Mini", + family: "gpt-mini", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-05-30", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 2, cache_read: 0.025 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "openai/gpt-5.2": { + id: "openai/gpt-5.2", + name: "GPT-5.2", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2025-12-11", + last_updated: "2025-12-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "openai/gpt-5.1": { + id: "openai/gpt-5.1", + name: "GPT-5.1", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "openai/gpt-5.4": { + id: "openai/gpt-5.4", + name: "GPT-5.4", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-05", + last_updated: "2026-03-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 15, cache_read: 0.25 }, + limit: { context: 1050000, input: 922000, output: 128000 }, + }, + "google/gemini-3.1-pro-preview": { + id: "google/gemini-3.1-pro-preview", + name: "Gemini 3.1 Pro Preview", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-02-19", + last_updated: "2026-02-19", + modalities: { input: ["text", "image", "video", "audio", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 12, cache_read: 0.2, context_over_200k: { input: 4, output: 18, cache_read: 0.4 } }, + limit: { context: 1048576, output: 65536 }, + }, + "google/gemini-3-flash-preview": { + id: "google/gemini-3-flash-preview", + name: "Gemini 3 Flash Preview", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-12-17", + last_updated: "2025-12-17", + modalities: { input: ["text", "image", "video", "audio", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 0.5, + output: 3, + cache_read: 0.05, + context_over_200k: { input: 0.5, output: 3, cache_read: 0.05 }, + }, + limit: { context: 1048576, output: 65536 }, + }, + "google/gemini-2.5-pro": { + id: "google/gemini-2.5-pro", + name: "Gemini 2.5 Pro", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-03-20", + last_updated: "2025-06-05", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 1.25, + output: 10, + cache_read: 0.125, + context_over_200k: { input: 2.5, output: 15, cache_read: 0.25 }, + }, + limit: { context: 1048576, output: 65536 }, + }, + "google/gemini-2.5-flash": { + id: "google/gemini-2.5-flash", + name: "Gemini 2.5 Flash", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-03-20", + last_updated: "2025-06-05", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 2.5, cache_read: 0.03 }, + limit: { context: 1048576, output: 65536 }, + }, + "anthropic/claude-haiku-4-5": { + id: "anthropic/claude-haiku-4-5", + name: "Claude Haiku 4.5", + family: "claude-haiku", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-02-28", + release_date: "2025-10-15", + last_updated: "2025-10-15", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 5, cache_read: 0.1 }, + limit: { context: 200000, output: 64000 }, + }, + "anthropic/claude-sonnet-4-6": { + id: "anthropic/claude-sonnet-4-6", + name: "Claude Sonnet 4.6", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-08-31", + release_date: "2026-02-17", + last_updated: "2026-02-17", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3 }, + limit: { context: 200000, output: 64000 }, + }, + "anthropic/claude-opus-4-7": { + id: "anthropic/claude-opus-4-7", + name: "Claude Opus 4.7", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2026-01-31", + release_date: "2026-04-16", + last_updated: "2026-04-16", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5 }, + limit: { context: 1000000, output: 128000 }, + }, + "anthropic/claude-opus-4-5": { + id: "anthropic/claude-opus-4-5", + name: "Claude Opus 4.5", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-11-24", + last_updated: "2025-11-24", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5 }, + limit: { context: 200000, output: 64000 }, + }, + "anthropic/claude-opus-4-6": { + id: "anthropic/claude-opus-4-6", + name: "Claude Opus 4.6", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-05-31", + release_date: "2026-02-05", + last_updated: "2026-02-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5 }, + limit: { context: 200000, output: 128000 }, + }, + "anthropic/claude-sonnet-4-5": { + id: "anthropic/claude-sonnet-4-5", + name: "Claude Sonnet 4.5", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07-31", + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3 }, + limit: { context: 200000, output: 64000 }, + }, + }, + }, + "siliconflow-cn": { + id: "siliconflow-cn", + env: ["SILICONFLOW_CN_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.siliconflow.cn/v1", + name: "SiliconFlow (China)", + doc: "https://cloud.siliconflow.com/models", + models: { + "Kwaipilot/KAT-Dev": { + id: "Kwaipilot/KAT-Dev", + name: "Kwaipilot/KAT-Dev", + family: "kat-coder", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-09-27", + last_updated: "2026-01-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.6 }, + limit: { context: 128000, output: 128000 }, + }, + "Qwen/Qwen3.5-397B-A17B": { + id: "Qwen/Qwen3.5-397B-A17B", + name: "Qwen/Qwen3.5-397B-A17B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-02-16", + last_updated: "2026-02-16", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.29, output: 1.74 }, + limit: { context: 262144, output: 65536 }, + }, + "Qwen/Qwen3.5-35B-A3B": { + id: "Qwen/Qwen3.5-35B-A3B", + name: "Qwen/Qwen3.5-35B-A3B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-02-25", + last_updated: "2026-02-25", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.23, output: 1.86 }, + limit: { context: 262144, output: 65536 }, + }, + "Qwen/Qwen3.5-122B-A10B": { + id: "Qwen/Qwen3.5-122B-A10B", + name: "Qwen/Qwen3.5-122B-A10B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-02-26", + last_updated: "2026-02-26", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.29, output: 2.32 }, + limit: { context: 262144, output: 65536 }, + }, + "Qwen/Qwen3.5-9B": { + id: "Qwen/Qwen3.5-9B", + name: "Qwen/Qwen3.5-9B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-03-03", + last_updated: "2026-03-03", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.22, output: 1.74 }, + limit: { context: 262144, output: 65536 }, + }, + "Qwen/Qwen3.5-27B": { + id: "Qwen/Qwen3.5-27B", + name: "Qwen/Qwen3.5-27B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-02-25", + last_updated: "2026-02-25", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.26, output: 2.09 }, + limit: { context: 262144, output: 65536 }, + }, + "Qwen/Qwen3.5-4B": { + id: "Qwen/Qwen3.5-4B", + name: "Qwen/Qwen3.5-4B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-03-03", + last_updated: "2026-03-03", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 262144, output: 65536 }, + }, + "Qwen/Qwen3.6-35B-A3B": { + id: "Qwen/Qwen3.6-35B-A3B", + name: "Qwen/Qwen3.6-35B-A3B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-04-17", + last_updated: "2026-04-17", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.23, output: 1.86 }, + limit: { context: 262144, output: 65536 }, + }, + "Qwen/Qwen2.5-72B-Instruct": { + id: "Qwen/Qwen2.5-72B-Instruct", + name: "Qwen/Qwen2.5-72B-Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-09-18", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.59, output: 0.59 }, + limit: { context: 33000, output: 4000 }, + }, + "Qwen/Qwen3-Coder-480B-A35B-Instruct": { + id: "Qwen/Qwen3-Coder-480B-A35B-Instruct", + name: "Qwen/Qwen3-Coder-480B-A35B-Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-07-31", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 1 }, + limit: { context: 262000, output: 262000 }, + }, + "Qwen/Qwen3-VL-8B-Instruct": { + id: "Qwen/Qwen3-VL-8B-Instruct", + name: "Qwen/Qwen3-VL-8B-Instruct", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-10-15", + last_updated: "2025-11-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.18, output: 0.68 }, + limit: { context: 262000, output: 262000 }, + }, + "Qwen/Qwen3-VL-32B-Instruct": { + id: "Qwen/Qwen3-VL-32B-Instruct", + name: "Qwen/Qwen3-VL-32B-Instruct", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-10-21", + last_updated: "2025-11-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.6 }, + limit: { context: 262000, output: 262000 }, + }, + "Qwen/Qwen3-VL-30B-A3B-Thinking": { + id: "Qwen/Qwen3-VL-30B-A3B-Thinking", + name: "Qwen/Qwen3-VL-30B-A3B-Thinking", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-10-11", + last_updated: "2025-11-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.29, output: 1 }, + limit: { context: 262000, output: 262000 }, + }, + "Qwen/Qwen2.5-14B-Instruct": { + id: "Qwen/Qwen2.5-14B-Instruct", + name: "Qwen/Qwen2.5-14B-Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-09-18", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.1 }, + limit: { context: 33000, output: 4000 }, + }, + "Qwen/Qwen3-VL-235B-A22B-Instruct": { + id: "Qwen/Qwen3-VL-235B-A22B-Instruct", + name: "Qwen/Qwen3-VL-235B-A22B-Instruct", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-10-04", + last_updated: "2025-11-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 1.5 }, + limit: { context: 262000, output: 262000 }, + }, + "Qwen/Qwen3-Next-80B-A3B-Thinking": { + id: "Qwen/Qwen3-Next-80B-A3B-Thinking", + name: "Qwen/Qwen3-Next-80B-A3B-Thinking", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-09-25", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.14, output: 0.57 }, + limit: { context: 262000, output: 262000 }, + }, + "Qwen/Qwen2.5-VL-32B-Instruct": { + id: "Qwen/Qwen2.5-VL-32B-Instruct", + name: "Qwen/Qwen2.5-VL-32B-Instruct", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-03-24", + last_updated: "2025-11-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.27, output: 0.27 }, + limit: { context: 131000, output: 131000 }, + }, + "Qwen/Qwen3-Omni-30B-A3B-Thinking": { + id: "Qwen/Qwen3-Omni-30B-A3B-Thinking", + name: "Qwen/Qwen3-Omni-30B-A3B-Thinking", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-10-04", + last_updated: "2025-11-25", + modalities: { input: ["text", "image", "audio"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4 }, + limit: { context: 66000, output: 66000 }, + }, + "Qwen/Qwen3-235B-A22B-Thinking-2507": { + id: "Qwen/Qwen3-235B-A22B-Thinking-2507", + name: "Qwen/Qwen3-235B-A22B-Thinking-2507", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-07-28", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.13, output: 0.6 }, + limit: { context: 262000, output: 262000 }, + }, + "Qwen/Qwen2.5-32B-Instruct": { + id: "Qwen/Qwen2.5-32B-Instruct", + name: "Qwen/Qwen2.5-32B-Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-09-19", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.18, output: 0.18 }, + limit: { context: 33000, output: 4000 }, + }, + "Qwen/Qwen2.5-72B-Instruct-128K": { + id: "Qwen/Qwen2.5-72B-Instruct-128K", + name: "Qwen/Qwen2.5-72B-Instruct-128K", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-09-18", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.59, output: 0.59 }, + limit: { context: 131000, output: 4000 }, + }, + "Qwen/Qwen3-14B": { + id: "Qwen/Qwen3-14B", + name: "Qwen/Qwen3-14B", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-04-30", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.07, output: 0.28 }, + limit: { context: 131000, output: 131000 }, + }, + "Qwen/Qwen3-Omni-30B-A3B-Instruct": { + id: "Qwen/Qwen3-Omni-30B-A3B-Instruct", + name: "Qwen/Qwen3-Omni-30B-A3B-Instruct", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-10-04", + last_updated: "2025-11-25", + modalities: { input: ["text", "image", "audio"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4 }, + limit: { context: 66000, output: 66000 }, + }, + "Qwen/Qwen3-Coder-30B-A3B-Instruct": { + id: "Qwen/Qwen3-Coder-30B-A3B-Instruct", + name: "Qwen/Qwen3-Coder-30B-A3B-Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-08-01", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.07, output: 0.28 }, + limit: { context: 262000, output: 262000 }, + }, + "Qwen/Qwen3-32B": { + id: "Qwen/Qwen3-32B", + name: "Qwen/Qwen3-32B", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-04-30", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.14, output: 0.57 }, + limit: { context: 131000, output: 131000 }, + }, + "Qwen/Qwen3-235B-A22B-Instruct-2507": { + id: "Qwen/Qwen3-235B-A22B-Instruct-2507", + name: "Qwen/Qwen3-235B-A22B-Instruct-2507", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-07-23", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.09, output: 0.6 }, + limit: { context: 262000, output: 262000 }, + }, + "Qwen/Qwen3-30B-A3B-Instruct-2507": { + id: "Qwen/Qwen3-30B-A3B-Instruct-2507", + name: "Qwen/Qwen3-30B-A3B-Instruct-2507", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-07-30", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.09, output: 0.3 }, + limit: { context: 262000, output: 262000 }, + }, + "Qwen/Qwen3-8B": { + id: "Qwen/Qwen3-8B", + name: "Qwen/Qwen3-8B", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-04-30", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.06, output: 0.06 }, + limit: { context: 131000, output: 131000 }, + }, + "Qwen/Qwen3-Next-80B-A3B-Instruct": { + id: "Qwen/Qwen3-Next-80B-A3B-Instruct", + name: "Qwen/Qwen3-Next-80B-A3B-Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-09-18", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.14, output: 1.4 }, + limit: { context: 262000, output: 262000 }, + }, + "Qwen/Qwen3-VL-8B-Thinking": { + id: "Qwen/Qwen3-VL-8B-Thinking", + name: "Qwen/Qwen3-VL-8B-Thinking", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-10-15", + last_updated: "2025-11-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.18, output: 2 }, + limit: { context: 262000, output: 262000 }, + }, + "Qwen/Qwen3-Omni-30B-A3B-Captioner": { + id: "Qwen/Qwen3-Omni-30B-A3B-Captioner", + name: "Qwen/Qwen3-Omni-30B-A3B-Captioner", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-10-04", + last_updated: "2025-11-25", + modalities: { input: ["audio"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4 }, + limit: { context: 66000, output: 66000 }, + }, + "Qwen/QwQ-32B": { + id: "Qwen/QwQ-32B", + name: "Qwen/QwQ-32B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-03-06", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.58 }, + limit: { context: 131000, output: 131000 }, + }, + "Qwen/Qwen3-VL-30B-A3B-Instruct": { + id: "Qwen/Qwen3-VL-30B-A3B-Instruct", + name: "Qwen/Qwen3-VL-30B-A3B-Instruct", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-10-05", + last_updated: "2025-11-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.29, output: 1 }, + limit: { context: 262000, output: 262000 }, + }, + "Qwen/Qwen2.5-Coder-32B-Instruct": { + id: "Qwen/Qwen2.5-Coder-32B-Instruct", + name: "Qwen/Qwen2.5-Coder-32B-Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-11-11", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.18, output: 0.18 }, + limit: { context: 33000, output: 4000 }, + }, + "Qwen/Qwen2.5-7B-Instruct": { + id: "Qwen/Qwen2.5-7B-Instruct", + name: "Qwen/Qwen2.5-7B-Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-09-18", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.05, output: 0.05 }, + limit: { context: 33000, output: 4000 }, + }, + "Qwen/Qwen3-VL-235B-A22B-Thinking": { + id: "Qwen/Qwen3-VL-235B-A22B-Thinking", + name: "Qwen/Qwen3-VL-235B-A22B-Thinking", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-10-04", + last_updated: "2025-11-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.45, output: 3.5 }, + limit: { context: 262000, output: 262000 }, + }, + "Qwen/Qwen3-30B-A3B-Thinking-2507": { + id: "Qwen/Qwen3-30B-A3B-Thinking-2507", + name: "Qwen/Qwen3-30B-A3B-Thinking-2507", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-07-31", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.09, output: 0.3 }, + limit: { context: 262000, output: 131000 }, + }, + "Qwen/Qwen3-VL-32B-Thinking": { + id: "Qwen/Qwen3-VL-32B-Thinking", + name: "Qwen/Qwen3-VL-32B-Thinking", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-10-21", + last_updated: "2025-11-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 1.5 }, + limit: { context: 262000, output: 262000 }, + }, + "Qwen/Qwen2.5-VL-72B-Instruct": { + id: "Qwen/Qwen2.5-VL-72B-Instruct", + name: "Qwen/Qwen2.5-VL-72B-Instruct", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-01-28", + last_updated: "2025-11-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.59, output: 0.59 }, + limit: { context: 131000, output: 4000 }, + }, + "stepfun-ai/Step-3.5-Flash": { + id: "stepfun-ai/Step-3.5-Flash", + name: "stepfun-ai/Step-3.5-Flash", + family: "step", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-02-11", + last_updated: "2026-02-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.3 }, + limit: { context: 262000, output: 262000 }, + }, + "zai-org/GLM-4.5V": { + id: "zai-org/GLM-4.5V", + name: "zai-org/GLM-4.5V", + family: "glm", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-08-13", + last_updated: "2025-11-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.14, output: 0.86 }, + limit: { context: 66000, output: 66000 }, + }, + "zai-org/GLM-4.6": { + id: "zai-org/GLM-4.6", + name: "zai-org/GLM-4.6", + family: "glm", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-10-04", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 1.9 }, + limit: { context: 205000, output: 205000 }, + }, + "zai-org/GLM-4.6V": { + id: "zai-org/GLM-4.6V", + name: "zai-org/GLM-4.6V", + family: "glm", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-12-07", + last_updated: "2025-12-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 0.9 }, + limit: { context: 131000, output: 131000 }, + }, + "zai-org/GLM-4.5-Air": { + id: "zai-org/GLM-4.5-Air", + name: "zai-org/GLM-4.5-Air", + family: "glm-air", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-07-28", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.14, output: 0.86 }, + limit: { context: 131000, output: 131000 }, + }, + "inclusionAI/Ling-flash-2.0": { + id: "inclusionAI/Ling-flash-2.0", + name: "inclusionAI/Ling-flash-2.0", + family: "ling", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-09-18", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.14, output: 0.57 }, + limit: { context: 131000, output: 131000 }, + }, + "inclusionAI/Ling-mini-2.0": { + id: "inclusionAI/Ling-mini-2.0", + name: "inclusionAI/Ling-mini-2.0", + family: "ling", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-09-10", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.07, output: 0.28 }, + limit: { context: 131000, output: 131000 }, + }, + "inclusionAI/Ring-flash-2.0": { + id: "inclusionAI/Ring-flash-2.0", + name: "inclusionAI/Ring-flash-2.0", + family: "ring", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-09-29", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.14, output: 0.57 }, + limit: { context: 131000, output: 131000 }, + }, + "ascend-tribe/pangu-pro-moe": { + id: "ascend-tribe/pangu-pro-moe", + name: "ascend-tribe/pangu-pro-moe", + family: "pangu", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: true, + temperature: true, + release_date: "2025-07-02", + last_updated: "2026-01-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.6 }, + limit: { context: 128000, output: 128000 }, + }, + "tencent/Hunyuan-MT-7B": { + id: "tencent/Hunyuan-MT-7B", + name: "tencent/Hunyuan-MT-7B", + family: "hunyuan", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-09-18", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 33000, output: 33000 }, + }, + "tencent/Hunyuan-A13B-Instruct": { + id: "tencent/Hunyuan-A13B-Instruct", + name: "tencent/Hunyuan-A13B-Instruct", + family: "hunyuan", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-06-30", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.14, output: 0.57 }, + limit: { context: 131000, output: 131000 }, + }, + "Pro/zai-org/GLM-4.7": { + id: "Pro/zai-org/GLM-4.7", + name: "Pro/zai-org/GLM-4.7", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2025-12-22", + last_updated: "2025-12-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.6, output: 2.2 }, + limit: { context: 205000, output: 205000 }, + }, + "Pro/zai-org/GLM-5.1": { + id: "Pro/zai-org/GLM-5.1", + name: "Pro/zai-org/GLM-5.1", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-04-08", + last_updated: "2026-04-08", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.4, output: 4.4, cache_write: 0 }, + limit: { context: 205000, output: 205000 }, + }, + "Pro/zai-org/GLM-5": { + id: "Pro/zai-org/GLM-5", + name: "Pro/zai-org/GLM-5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 3.2 }, + limit: { context: 205000, output: 205000 }, + }, + "Pro/deepseek-ai/DeepSeek-V3": { + id: "Pro/deepseek-ai/DeepSeek-V3", + name: "Pro/deepseek-ai/DeepSeek-V3", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-12-26", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 1 }, + limit: { context: 164000, output: 164000 }, + }, + "Pro/deepseek-ai/DeepSeek-R1": { + id: "Pro/deepseek-ai/DeepSeek-R1", + name: "Pro/deepseek-ai/DeepSeek-R1", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-05-28", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 2.18 }, + limit: { context: 164000, output: 164000 }, + }, + "Pro/deepseek-ai/DeepSeek-V3.2": { + id: "Pro/deepseek-ai/DeepSeek-V3.2", + name: "Pro/deepseek-ai/DeepSeek-V3.2", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-12-03", + last_updated: "2025-12-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.27, output: 0.42 }, + limit: { context: 164000, output: 164000 }, + }, + "Pro/deepseek-ai/DeepSeek-V3.1-Terminus": { + id: "Pro/deepseek-ai/DeepSeek-V3.1-Terminus", + name: "Pro/deepseek-ai/DeepSeek-V3.1-Terminus", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-09-29", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.27, output: 1 }, + limit: { context: 164000, output: 164000 }, + }, + "Pro/moonshotai/Kimi-K2-Thinking": { + id: "Pro/moonshotai/Kimi-K2-Thinking", + name: "Pro/moonshotai/Kimi-K2-Thinking", + family: "kimi-thinking", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-11-07", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.55, output: 2.5 }, + limit: { context: 262000, output: 262000 }, + }, + "Pro/moonshotai/Kimi-K2.6": { + id: "Pro/moonshotai/Kimi-K2.6", + name: "Pro/moonshotai/Kimi-K2.6", + family: "kimi", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-04-21", + last_updated: "2026-04-21", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.95, output: 4, cache_read: 0.16 }, + limit: { context: 262000, output: 262000 }, + }, + "Pro/moonshotai/Kimi-K2-Instruct-0905": { + id: "Pro/moonshotai/Kimi-K2-Instruct-0905", + name: "Pro/moonshotai/Kimi-K2-Instruct-0905", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-09-08", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 2 }, + limit: { context: 262000, output: 262000 }, + }, + "Pro/moonshotai/Kimi-K2.5": { + id: "Pro/moonshotai/Kimi-K2.5", + name: "Pro/moonshotai/Kimi-K2.5", + family: "kimi", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-01-27", + last_updated: "2026-01-27", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.45, output: 2.25 }, + limit: { context: 262000, output: 262000 }, + }, + "Pro/MiniMaxAI/MiniMax-M2.5": { + id: "Pro/MiniMaxAI/MiniMax-M2.5", + name: "Pro/MiniMaxAI/MiniMax-M2.5", + family: "minimax", + attachment: false, + reasoning: false, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-02-13", + last_updated: "2026-02-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 1.22 }, + limit: { context: 192000, output: 131000 }, + }, + "Pro/MiniMaxAI/MiniMax-M2.1": { + id: "Pro/MiniMaxAI/MiniMax-M2.1", + name: "Pro/MiniMaxAI/MiniMax-M2.1", + family: "minimax", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-12-23", + last_updated: "2025-12-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 197000, output: 131000 }, + }, + "PaddlePaddle/PaddleOCR-VL": { + id: "PaddlePaddle/PaddleOCR-VL", + name: "PaddlePaddle/PaddleOCR-VL", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-10-16", + last_updated: "2025-10-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 16384, output: 16384 }, + }, + "PaddlePaddle/PaddleOCR-VL-1.5": { + id: "PaddlePaddle/PaddleOCR-VL-1.5", + name: "PaddlePaddle/PaddleOCR-VL-1.5", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2026-01-29", + last_updated: "2026-01-29", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 16384, output: 16384 }, + }, + "deepseek-ai/DeepSeek-OCR": { + id: "deepseek-ai/DeepSeek-OCR", + name: "deepseek-ai/DeepSeek-OCR", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-10-20", + last_updated: "2025-10-20", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 8192, output: 8192 }, + }, + "deepseek-ai/DeepSeek-V3.1-Terminus": { + id: "deepseek-ai/DeepSeek-V3.1-Terminus", + name: "deepseek-ai/DeepSeek-V3.1-Terminus", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-09-29", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.27, output: 1 }, + limit: { context: 164000, output: 164000 }, + }, + "deepseek-ai/DeepSeek-V3.2": { + id: "deepseek-ai/DeepSeek-V3.2", + name: "deepseek-ai/DeepSeek-V3.2", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-12-03", + last_updated: "2025-12-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.27, output: 0.42 }, + limit: { context: 164000, output: 164000 }, + }, + "deepseek-ai/DeepSeek-R1-Distill-Qwen-14B": { + id: "deepseek-ai/DeepSeek-R1-Distill-Qwen-14B", + name: "deepseek-ai/DeepSeek-R1-Distill-Qwen-14B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-01-20", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.1 }, + limit: { context: 131000, output: 131000 }, + }, + "deepseek-ai/DeepSeek-R1": { + id: "deepseek-ai/DeepSeek-R1", + name: "deepseek-ai/DeepSeek-R1", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-05-28", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 2.18 }, + limit: { context: 164000, output: 164000 }, + }, + "deepseek-ai/DeepSeek-R1-Distill-Qwen-32B": { + id: "deepseek-ai/DeepSeek-R1-Distill-Qwen-32B", + name: "deepseek-ai/DeepSeek-R1-Distill-Qwen-32B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-01-20", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.18, output: 0.18 }, + limit: { context: 131000, output: 131000 }, + }, + "deepseek-ai/DeepSeek-V3": { + id: "deepseek-ai/DeepSeek-V3", + name: "deepseek-ai/DeepSeek-V3", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-12-26", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 1 }, + limit: { context: 164000, output: 164000 }, + }, + "deepseek-ai/deepseek-vl2": { + id: "deepseek-ai/deepseek-vl2", + name: "deepseek-ai/deepseek-vl2", + family: "deepseek", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-12-13", + last_updated: "2025-11-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.15 }, + limit: { context: 4000, output: 4000 }, + }, + "baidu/ERNIE-4.5-300B-A47B": { + id: "baidu/ERNIE-4.5-300B-A47B", + name: "baidu/ERNIE-4.5-300B-A47B", + family: "ernie", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-07-02", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.28, output: 1.1 }, + limit: { context: 131000, output: 131000 }, + }, + "THUDM/GLM-Z1-32B-0414": { + id: "THUDM/GLM-Z1-32B-0414", + name: "THUDM/GLM-Z1-32B-0414", + family: "glm-z", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-04-18", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.14, output: 0.57 }, + limit: { context: 131000, output: 131000 }, + }, + "THUDM/GLM-4-32B-0414": { + id: "THUDM/GLM-4-32B-0414", + name: "THUDM/GLM-4-32B-0414", + family: "glm", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-04-18", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.27, output: 0.27 }, + limit: { context: 33000, output: 33000 }, + }, + "THUDM/GLM-4-9B-0414": { + id: "THUDM/GLM-4-9B-0414", + name: "THUDM/GLM-4-9B-0414", + family: "glm", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-04-18", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.086, output: 0.086 }, + limit: { context: 33000, output: 33000 }, + }, + "THUDM/GLM-Z1-9B-0414": { + id: "THUDM/GLM-Z1-9B-0414", + name: "THUDM/GLM-Z1-9B-0414", + family: "glm-z", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-04-18", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.086, output: 0.086 }, + limit: { context: 131000, output: 131000 }, + }, + "moonshotai/Kimi-K2-Instruct-0905": { + id: "moonshotai/Kimi-K2-Instruct-0905", + name: "moonshotai/Kimi-K2-Instruct-0905", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-09-08", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 2 }, + limit: { context: 262000, output: 262000 }, + }, + "moonshotai/Kimi-K2-Thinking": { + id: "moonshotai/Kimi-K2-Thinking", + name: "moonshotai/Kimi-K2-Thinking", + family: "kimi-thinking", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-11-07", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.55, output: 2.5 }, + limit: { context: 262000, output: 262000 }, + }, + "ByteDance-Seed/Seed-OSS-36B-Instruct": { + id: "ByteDance-Seed/Seed-OSS-36B-Instruct", + name: "ByteDance-Seed/Seed-OSS-36B-Instruct", + family: "seed", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-09-04", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.21, output: 0.57 }, + limit: { context: 262000, output: 262000 }, + }, + }, + }, + submodel: { + id: "submodel", + env: ["SUBMODEL_INSTAGEN_ACCESS_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://llm.submodel.ai/v1", + name: "submodel", + doc: "https://submodel.gitbook.io", + models: { + "Qwen/Qwen3-235B-A22B-Instruct-2507": { + id: "Qwen/Qwen3-235B-A22B-Instruct-2507", + name: "Qwen3 235B A22B Instruct 2507", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-08-23", + last_updated: "2025-08-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.3 }, + limit: { context: 262144, output: 131072 }, + }, + "Qwen/Qwen3-Coder-480B-A35B-Instruct-FP8": { + id: "Qwen/Qwen3-Coder-480B-A35B-Instruct-FP8", + name: "Qwen3 Coder 480B A35B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-08-23", + last_updated: "2025-08-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.8 }, + limit: { context: 262144, output: 262144 }, + }, + "Qwen/Qwen3-235B-A22B-Thinking-2507": { + id: "Qwen/Qwen3-235B-A22B-Thinking-2507", + name: "Qwen3 235B A22B Thinking 2507", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-23", + last_updated: "2025-08-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.6 }, + limit: { context: 262144, output: 131072 }, + }, + "zai-org/GLM-4.5-Air": { + id: "zai-org/GLM-4.5-Air", + name: "GLM 4.5 Air", + family: "glm-air", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-07-28", + last_updated: "2025-07-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.5 }, + limit: { context: 131072, output: 131072 }, + }, + "zai-org/GLM-4.5-FP8": { + id: "zai-org/GLM-4.5-FP8", + name: "GLM 4.5 FP8", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-07-28", + last_updated: "2025-07-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.8 }, + limit: { context: 131072, output: 131072 }, + }, + "deepseek-ai/DeepSeek-V3.1": { + id: "deepseek-ai/DeepSeek-V3.1", + name: "DeepSeek V3.1", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-23", + last_updated: "2025-08-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.8 }, + limit: { context: 75000, output: 163840 }, + }, + "deepseek-ai/DeepSeek-V3-0324": { + id: "deepseek-ai/DeepSeek-V3-0324", + name: "DeepSeek V3 0324", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-08-23", + last_updated: "2025-08-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.8 }, + limit: { context: 75000, output: 163840 }, + }, + "deepseek-ai/DeepSeek-R1-0528": { + id: "deepseek-ai/DeepSeek-R1-0528", + name: "DeepSeek R1 0528", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-23", + last_updated: "2025-08-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 2.15 }, + limit: { context: 75000, output: 163840 }, + }, + "openai/gpt-oss-120b": { + id: "openai/gpt-oss-120b", + name: "GPT OSS 120B", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-23", + last_updated: "2025-08-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.5 }, + limit: { context: 131072, output: 32768 }, + }, + }, + }, + "minimax-coding-plan": { + id: "minimax-coding-plan", + env: ["MINIMAX_API_KEY"], + npm: "@ai-sdk/anthropic", + api: "https://api.minimax.io/anthropic/v1", + name: "MiniMax Coding Plan (minimax.io)", + doc: "https://platform.minimax.io/docs/coding-plan/intro", + models: { + "MiniMax-M2": { + id: "MiniMax-M2", + name: "MiniMax-M2", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-10-27", + last_updated: "2025-10-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 196608, output: 128000 }, + }, + "MiniMax-M2.5": { + id: "MiniMax-M2.5", + name: "MiniMax-M2.5", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 204800, output: 131072 }, + }, + "MiniMax-M2.7": { + id: "MiniMax-M2.7", + name: "MiniMax-M2.7", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 204800, output: 131072 }, + }, + "MiniMax-M2.7-highspeed": { + id: "MiniMax-M2.7-highspeed", + name: "MiniMax-M2.7-highspeed", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 204800, output: 131072 }, + }, + "MiniMax-M2.1": { + id: "MiniMax-M2.1", + name: "MiniMax-M2.1", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-12-23", + last_updated: "2025-12-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 204800, output: 131072 }, + }, + "MiniMax-M2.5-highspeed": { + id: "MiniMax-M2.5-highspeed", + name: "MiniMax-M2.5-highspeed", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-13", + last_updated: "2026-02-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 204800, output: 131072 }, + }, + }, + }, + perplexity: { + id: "perplexity", + env: ["PERPLEXITY_API_KEY"], + npm: "@ai-sdk/perplexity", + name: "Perplexity", + doc: "https://docs.perplexity.ai", + models: { + "sonar-pro": { + id: "sonar-pro", + name: "Sonar Pro", + family: "sonar-pro", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2025-09-01", + release_date: "2024-01-01", + last_updated: "2025-09-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15 }, + limit: { context: 200000, output: 8192 }, + }, + "sonar-deep-research": { + id: "sonar-deep-research", + name: "Perplexity Sonar Deep Research", + attachment: false, + reasoning: true, + tool_call: false, + temperature: false, + knowledge: "2025-01", + release_date: "2025-02-01", + last_updated: "2025-09-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 8, reasoning: 3 }, + limit: { context: 128000, output: 32768 }, + }, + sonar: { + id: "sonar", + name: "Sonar", + family: "sonar", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2025-09-01", + release_date: "2024-01-01", + last_updated: "2025-09-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 1 }, + limit: { context: 128000, output: 4096 }, + }, + "sonar-reasoning-pro": { + id: "sonar-reasoning-pro", + name: "Sonar Reasoning Pro", + family: "sonar-reasoning", + attachment: true, + reasoning: true, + tool_call: false, + temperature: true, + knowledge: "2025-09-01", + release_date: "2024-01-01", + last_updated: "2025-09-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 8 }, + limit: { context: 128000, output: 4096 }, + }, + }, + }, + deepseek: { + id: "deepseek", + env: ["DEEPSEEK_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.deepseek.com", + name: "DeepSeek", + doc: "https://api-docs.deepseek.com/quick_start/pricing", + models: { + "deepseek-chat": { + id: "deepseek-chat", + name: "DeepSeek Chat", + family: "deepseek", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-09", + release_date: "2025-12-01", + last_updated: "2026-02-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.14, output: 0.28, cache_read: 0.028 }, + limit: { context: 1000000, output: 384000 }, + }, + "deepseek-reasoner": { + id: "deepseek-reasoner", + name: "DeepSeek Reasoner", + family: "deepseek-thinking", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-09", + release_date: "2025-12-01", + last_updated: "2026-02-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.14, output: 0.28, cache_read: 0.028 }, + limit: { context: 1000000, output: 384000 }, + }, + "deepseek-v4-flash": { + id: "deepseek-v4-flash", + name: "DeepSeek V4 Flash", + family: "deepseek-flash", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-05", + release_date: "2026-04-24", + last_updated: "2026-04-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.14, output: 0.28, cache_read: 0.028 }, + limit: { context: 1000000, output: 384000 }, + }, + "deepseek-v4-pro": { + id: "deepseek-v4-pro", + name: "DeepSeek V4 Pro", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-05", + release_date: "2026-04-24", + last_updated: "2026-04-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.74, output: 3.48, cache_read: 0.145 }, + limit: { context: 1000000, output: 384000 }, + }, + }, + }, + llama: { + id: "llama", + env: ["LLAMA_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.llama.com/compat/v1/", + name: "Llama", + doc: "https://llama.developer.meta.com/docs/models", + models: { + "llama-3.3-70b-instruct": { + id: "llama-3.3-70b-instruct", + name: "Llama-3.3-70B-Instruct", + family: "llama", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "cerebras-llama-4-maverick-17b-128e-instruct": { + id: "cerebras-llama-4-maverick-17b-128e-instruct", + name: "Cerebras-Llama-4-Maverick-17B-128E-Instruct", + family: "llama", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-04-05", + last_updated: "2025-04-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "llama-3.3-8b-instruct": { + id: "llama-3.3-8b-instruct", + name: "Llama-3.3-8B-Instruct", + family: "llama", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "cerebras-llama-4-scout-17b-16e-instruct": { + id: "cerebras-llama-4-scout-17b-16e-instruct", + name: "Cerebras-Llama-4-Scout-17B-16E-Instruct", + family: "llama", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-04-05", + last_updated: "2025-04-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "groq-llama-4-maverick-17b-128e-instruct": { + id: "groq-llama-4-maverick-17b-128e-instruct", + name: "Groq-Llama-4-Maverick-17B-128E-Instruct", + family: "llama", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-04-05", + last_updated: "2025-04-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "llama-4-scout-17b-16e-instruct-fp8": { + id: "llama-4-scout-17b-16e-instruct-fp8", + name: "Llama-4-Scout-17B-16E-Instruct-FP8", + family: "llama", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-08", + release_date: "2025-04-05", + last_updated: "2025-04-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "llama-4-maverick-17b-128e-instruct-fp8": { + id: "llama-4-maverick-17b-128e-instruct-fp8", + name: "Llama-4-Maverick-17B-128E-Instruct-FP8", + family: "llama", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-08", + release_date: "2025-04-05", + last_updated: "2025-04-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + }, + }, + openrouter: { + id: "openrouter", + env: ["OPENROUTER_API_KEY"], + npm: "@openrouter/ai-sdk-provider", + api: "https://openrouter.ai/api/v1", + name: "OpenRouter", + doc: "https://openrouter.ai/models", + models: { + "liquid/lfm-2.5-1.2b-instruct:free": { + id: "liquid/lfm-2.5-1.2b-instruct:free", + name: "LFM2.5-1.2B-Instruct (free)", + family: "liquid", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2025-06", + release_date: "2026-01-20", + last_updated: "2026-01-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 131072, output: 32768 }, + }, + "liquid/lfm-2.5-1.2b-thinking:free": { + id: "liquid/lfm-2.5-1.2b-thinking:free", + name: "LFM2.5-1.2B-Thinking (free)", + family: "liquid", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + knowledge: "2025-06", + release_date: "2026-01-20", + last_updated: "2026-01-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 131072, output: 32768 }, + }, + "deepseek/deepseek-chat-v3.1": { + id: "deepseek/deepseek-chat-v3.1", + name: "DeepSeek-V3.1", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-08-21", + last_updated: "2025-08-21", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.8 }, + limit: { context: 163840, output: 163840 }, + }, + "deepseek/deepseek-r1-distill-llama-70b": { + id: "deepseek/deepseek-r1-distill-llama-70b", + name: "DeepSeek R1 Distill Llama 70B", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-01-23", + last_updated: "2025-01-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 8192, output: 8192 }, + }, + "deepseek/deepseek-r1": { + id: "deepseek/deepseek-r1", + name: "DeepSeek: R1", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + knowledge: "2024-07", + release_date: "2025-01-20", + last_updated: "2025-01-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.7, output: 2.5 }, + limit: { context: 64000, output: 16000 }, + }, + "deepseek/deepseek-v3.2-speciale": { + id: "deepseek/deepseek-v3.2-speciale", + name: "DeepSeek V3.2 Speciale", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-07", + release_date: "2025-12-01", + last_updated: "2025-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.27, output: 0.41 }, + limit: { context: 163840, output: 65536 }, + }, + "deepseek/deepseek-v3.2": { + id: "deepseek/deepseek-v3.2", + name: "DeepSeek V3.2", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-07", + release_date: "2025-12-01", + last_updated: "2025-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.28, output: 0.4 }, + limit: { context: 163840, output: 65536 }, + }, + "deepseek/deepseek-v3.1-terminus:exacto": { + id: "deepseek/deepseek-v3.1-terminus:exacto", + name: "DeepSeek V3.1 Terminus (exacto)", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-09-22", + last_updated: "2025-09-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.27, output: 1 }, + limit: { context: 131072, output: 65536 }, + }, + "deepseek/deepseek-chat-v3-0324": { + id: "deepseek/deepseek-chat-v3-0324", + name: "DeepSeek V3 0324", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-03-24", + last_updated: "2025-03-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 16384, output: 8192 }, + }, + "deepseek/deepseek-v3.1-terminus": { + id: "deepseek/deepseek-v3.1-terminus", + name: "DeepSeek V3.1 Terminus", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-09-22", + last_updated: "2025-09-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.27, output: 1 }, + limit: { context: 131072, output: 65536 }, + }, + "openrouter/owl-alpha": { + id: "openrouter/owl-alpha", + name: "Owl Alpha", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-04-28", + last_updated: "2026-04-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 1048756, output: 262144 }, + status: "alpha", + }, + "openrouter/pareto-code": { + id: "openrouter/pareto-code", + name: "Pareto Code Router", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-04-21", + last_updated: "2026-04-21", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 200000, output: 200000 }, + }, + "openrouter/elephant-alpha": { + id: "openrouter/elephant-alpha", + name: "Elephant (free)", + family: "elephant", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-04-13", + last_updated: "2026-04-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 262144, output: 32768 }, + }, + "openrouter/free": { + id: "openrouter/free", + name: "Free Models Router", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-02-01", + last_updated: "2026-02-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 200000, input: 200000, output: 8000 }, + }, + "arcee-ai/trinity-large-thinking": { + id: "arcee-ai/trinity-large-thinking", + name: "Trinity Large Thinking", + family: "trinity", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-01", + last_updated: "2026-04-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.22, output: 0.85 }, + limit: { context: 262144, output: 80000 }, + }, + "arcee-ai/trinity-large-preview:free": { + id: "arcee-ai/trinity-large-preview:free", + name: "Trinity Large Preview", + family: "trinity", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-06", + release_date: "2026-01-28", + last_updated: "2026-01-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 131072, output: 131072 }, + }, + "cognitivecomputations/dolphin-mistral-24b-venice-edition:free": { + id: "cognitivecomputations/dolphin-mistral-24b-venice-edition:free", + name: "Uncensored (free)", + family: "mistral", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: true, + temperature: true, + knowledge: "2025-06", + release_date: "2025-07-09", + last_updated: "2026-01-31", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 32768, output: 32768 }, + }, + "bytedance-seed/seedream-4.5": { + id: "bytedance-seed/seedream-4.5", + name: "Seedream 4.5", + family: "seed", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2025-06", + release_date: "2025-12-23", + last_updated: "2026-01-31", + modalities: { input: ["image", "text"], output: ["image"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 4096, output: 4096 }, + }, + "black-forest-labs/flux.2-max": { + id: "black-forest-labs/flux.2-max", + name: "FLUX.2 Max", + family: "flux", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2025-06", + release_date: "2025-12-16", + last_updated: "2026-01-31", + modalities: { input: ["image", "text"], output: ["image"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 46864, output: 46864 }, + }, + "black-forest-labs/flux.2-flex": { + id: "black-forest-labs/flux.2-flex", + name: "FLUX.2 Flex", + family: "flux", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2025-06", + release_date: "2025-11-25", + last_updated: "2026-01-31", + modalities: { input: ["image", "text"], output: ["image"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 67344, output: 67344 }, + }, + "black-forest-labs/flux.2-pro": { + id: "black-forest-labs/flux.2-pro", + name: "FLUX.2 Pro", + family: "flux", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2025-06", + release_date: "2025-11-25", + last_updated: "2026-01-31", + modalities: { input: ["image", "text"], output: ["image"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 46864, output: 46864 }, + }, + "black-forest-labs/flux.2-klein-4b": { + id: "black-forest-labs/flux.2-klein-4b", + name: "FLUX.2 Klein 4B", + family: "flux", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2025-06", + release_date: "2026-01-14", + last_updated: "2026-01-31", + modalities: { input: ["image", "text"], output: ["image"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 40960, output: 40960 }, + }, + "nousresearch/hermes-3-llama-3.1-405b:free": { + id: "nousresearch/hermes-3-llama-3.1-405b:free", + name: "Hermes 3 405B Instruct (free)", + family: "hermes", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + knowledge: "2023-12", + release_date: "2024-08-16", + last_updated: "2024-08-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 131072, output: 131072 }, + }, + "nousresearch/hermes-4-405b": { + id: "nousresearch/hermes-4-405b", + name: "Hermes 4 405B", + family: "hermes", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2025-08-25", + last_updated: "2025-08-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 3 }, + limit: { context: 131072, output: 131072 }, + }, + "nousresearch/hermes-4-70b": { + id: "nousresearch/hermes-4-70b", + name: "Hermes 4 70B", + family: "hermes", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2023-12", + release_date: "2025-08-25", + last_updated: "2025-08-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.13, output: 0.4 }, + limit: { context: 131072, output: 131072 }, + }, + "stepfun/step-3.5-flash": { + id: "stepfun/step-3.5-flash", + name: "Step 3.5 Flash", + family: "step", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-01-29", + last_updated: "2026-01-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.3, cache_read: 0.02 }, + limit: { context: 256000, output: 256000 }, + }, + "mistralai/mistral-small-3.1-24b-instruct": { + id: "mistralai/mistral-small-3.1-24b-instruct", + name: "Mistral Small 3.1 24B Instruct", + family: "mistral-small", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-03-17", + last_updated: "2025-03-17", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 8192 }, + }, + "mistralai/devstral-2512": { + id: "mistralai/devstral-2512", + name: "Devstral 2 2512", + family: "devstral", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-12", + release_date: "2025-09-12", + last_updated: "2025-09-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 262144, output: 262144 }, + }, + "mistralai/codestral-2508": { + id: "mistralai/codestral-2508", + name: "Codestral 2508", + family: "codestral", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-05", + release_date: "2025-08-01", + last_updated: "2025-08-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 0.9 }, + limit: { context: 256000, output: 256000 }, + }, + "mistralai/mistral-medium-3.1": { + id: "mistralai/mistral-medium-3.1", + name: "Mistral Medium 3.1", + family: "mistral-medium", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-05", + release_date: "2025-08-12", + last_updated: "2025-08-12", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 2 }, + limit: { context: 262144, output: 262144 }, + }, + "mistralai/mistral-small-2603": { + id: "mistralai/mistral-small-2603", + name: "Mistral Small 4", + family: "mistral-small", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-06", + release_date: "2026-03-16", + last_updated: "2026-03-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 262144, output: 262144 }, + }, + "mistralai/mistral-medium-3": { + id: "mistralai/mistral-medium-3", + name: "Mistral Medium 3", + family: "mistral-medium", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-05", + release_date: "2025-05-07", + last_updated: "2025-05-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 2 }, + limit: { context: 131072, output: 131072 }, + }, + "mistralai/devstral-small-2505": { + id: "mistralai/devstral-small-2505", + name: "Devstral Small", + family: "devstral", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-05", + release_date: "2025-05-07", + last_updated: "2025-05-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.06, output: 0.12 }, + limit: { context: 128000, output: 128000 }, + }, + "mistralai/mistral-small-3.2-24b-instruct": { + id: "mistralai/mistral-small-3.2-24b-instruct", + name: "Mistral Small 3.2 24B Instruct", + family: "mistral-small", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-06-20", + last_updated: "2025-06-20", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 96000, output: 8192 }, + }, + "mistralai/devstral-medium-2507": { + id: "mistralai/devstral-medium-2507", + name: "Devstral Medium", + family: "devstral", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-05", + release_date: "2025-07-10", + last_updated: "2025-07-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.4, output: 2 }, + limit: { context: 131072, output: 131072 }, + }, + "mistralai/devstral-small-2507": { + id: "mistralai/devstral-small-2507", + name: "Devstral Small 1.1", + family: "devstral", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-05", + release_date: "2025-07-10", + last_updated: "2025-07-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.3 }, + limit: { context: 131072, output: 131072 }, + }, + "meta-llama/llama-3.2-11b-vision-instruct": { + id: "meta-llama/llama-3.2-11b-vision-instruct", + name: "Llama 3.2 11B Vision Instruct", + family: "llama", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2023-12", + release_date: "2024-09-25", + last_updated: "2024-09-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 131072, output: 8192 }, + }, + "meta-llama/llama-3.2-3b-instruct:free": { + id: "meta-llama/llama-3.2-3b-instruct:free", + name: "Llama 3.2 3B Instruct (free)", + family: "llama", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2023-12", + release_date: "2024-09-25", + last_updated: "2024-09-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 131072, output: 131072 }, + }, + "meta-llama/llama-3.3-70b-instruct:free": { + id: "meta-llama/llama-3.3-70b-instruct:free", + name: "Llama 3.3 70B Instruct (free)", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-12", + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 131072, output: 131072 }, + }, + "x-ai/grok-4.20-multi-agent-beta": { + id: "x-ai/grok-4.20-multi-agent-beta", + name: "Grok 4.20 Multi - Agent Beta", + family: "grok", + attachment: true, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2026-03-12", + last_updated: "2026-03-12", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 6, cache_read: 0.2, context_over_200k: { input: 4, output: 12 } }, + limit: { context: 2000000, output: 30000 }, + status: "beta", + }, + "x-ai/grok-4-fast": { + id: "x-ai/grok-4-fast", + name: "Grok 4 Fast", + family: "grok", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-11", + release_date: "2025-08-19", + last_updated: "2025-08-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5, cache_read: 0.05, cache_write: 0.05 }, + limit: { context: 2000000, output: 30000 }, + }, + "x-ai/grok-code-fast-1": { + id: "x-ai/grok-code-fast-1", + name: "Grok Code Fast 1", + family: "grok", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-08", + release_date: "2025-08-26", + last_updated: "2025-08-26", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 1.5, cache_read: 0.02 }, + limit: { context: 256000, output: 10000 }, + }, + "x-ai/grok-3-beta": { + id: "x-ai/grok-3-beta", + name: "Grok 3 Beta", + family: "grok", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-11", + release_date: "2025-02-17", + last_updated: "2025-02-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.75, cache_write: 15 }, + limit: { context: 131072, output: 8192 }, + }, + "x-ai/grok-4": { + id: "x-ai/grok-4", + name: "Grok 4", + family: "grok", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-07-09", + last_updated: "2025-07-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.75, cache_write: 15 }, + limit: { context: 256000, output: 64000 }, + }, + "x-ai/grok-3-mini": { + id: "x-ai/grok-3-mini", + name: "Grok 3 Mini", + family: "grok", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-11", + release_date: "2025-02-17", + last_updated: "2025-02-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 0.5, cache_read: 0.075, cache_write: 0.5 }, + limit: { context: 131072, output: 8192 }, + }, + "x-ai/grok-4.1-fast": { + id: "x-ai/grok-4.1-fast", + name: "Grok 4.1 Fast", + family: "grok", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-11", + release_date: "2025-11-19", + last_updated: "2025-11-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5, cache_read: 0.05, cache_write: 0.05 }, + limit: { context: 2000000, output: 30000 }, + }, + "x-ai/grok-4.20-beta": { + id: "x-ai/grok-4.20-beta", + name: "Grok 4.20 Beta", + family: "grok", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-12", + last_updated: "2026-03-12", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 6, cache_read: 0.2, context_over_200k: { input: 4, output: 12 } }, + limit: { context: 2000000, output: 30000 }, + status: "beta", + }, + "x-ai/grok-3-mini-beta": { + id: "x-ai/grok-3-mini-beta", + name: "Grok 3 Mini Beta", + family: "grok", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-11", + release_date: "2025-02-17", + last_updated: "2025-02-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 0.5, cache_read: 0.075, cache_write: 0.5 }, + limit: { context: 131072, output: 8192 }, + }, + "x-ai/grok-3": { + id: "x-ai/grok-3", + name: "Grok 3", + family: "grok", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-11", + release_date: "2025-02-17", + last_updated: "2025-02-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.75, cache_write: 15 }, + limit: { context: 131072, output: 8192 }, + }, + "tencent/hy3-preview": { + id: "tencent/hy3-preview", + name: "Hy3 preview", + family: "Hy", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-20", + last_updated: "2026-04-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.066, output: 0.26, cache_read: 0.029, cache_write: 0.029 }, + limit: { context: 256000, output: 64000 }, + }, + "poolside/laguna-m.1:free": { + id: "poolside/laguna-m.1:free", + name: "Laguna M.1", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-04-28", + last_updated: "2026-04-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 131072, output: 8192 }, + }, + "poolside/laguna-xs.2:free": { + id: "poolside/laguna-xs.2:free", + name: "Laguna XS.2", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-04-28", + last_updated: "2026-04-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 131072, output: 8192 }, + }, + "prime-intellect/intellect-3": { + id: "prime-intellect/intellect-3", + name: "Intellect 3", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-01-15", + last_updated: "2025-01-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 1.1 }, + limit: { context: 131072, output: 8192 }, + }, + "nvidia/nemotron-3-super-120b-a12b": { + id: "nvidia/nemotron-3-super-120b-a12b", + name: "Nemotron 3 Super", + family: "nemotron", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2026-03-11", + last_updated: "2026-03-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.5 }, + limit: { context: 262144, output: 262144 }, + }, + "nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free": { + id: "nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free", + name: "Nemotron 3 Nano Omni (free)", + family: "nemotron", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-04-28", + last_updated: "2026-04-28", + modalities: { input: ["text", "image", "video", "audio"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 256000, output: 65536 }, + }, + "nvidia/nemotron-3-nano-30b-a3b:free": { + id: "nvidia/nemotron-3-nano-30b-a3b:free", + name: "Nemotron 3 Nano 30B A3B (free)", + family: "nemotron", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-11", + release_date: "2025-12-14", + last_updated: "2026-01-31", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 256000, output: 256000 }, + }, + "nvidia/nemotron-nano-9b-v2:free": { + id: "nvidia/nemotron-nano-9b-v2:free", + name: "Nemotron Nano 9B V2 (free)", + family: "nemotron", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-09", + release_date: "2025-09-05", + last_updated: "2025-08-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 128000 }, + }, + "nvidia/nemotron-3-super-120b-a12b:free": { + id: "nvidia/nemotron-3-super-120b-a12b:free", + name: "Nemotron 3 Super (free)", + family: "nemotron", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2026-03-11", + last_updated: "2026-03-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 262144, output: 262144 }, + }, + "nvidia/nemotron-nano-9b-v2": { + id: "nvidia/nemotron-nano-9b-v2", + name: "nvidia-nemotron-nano-9b-v2", + family: "nemotron", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-09", + release_date: "2025-08-18", + last_updated: "2025-08-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.04, output: 0.16 }, + limit: { context: 131072, output: 131072 }, + }, + "nvidia/nemotron-nano-12b-v2-vl:free": { + id: "nvidia/nemotron-nano-12b-v2-vl:free", + name: "Nemotron Nano 12B 2 VL (free)", + family: "nemotron", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-11", + release_date: "2025-10-28", + last_updated: "2026-01-31", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 128000 }, + }, + "inception/mercury-edit-2": { + id: "inception/mercury-edit-2", + name: "Mercury Edit 2", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2026-03-30", + last_updated: "2026-03-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 0.75, cache_read: 0.025 }, + limit: { context: 128000, output: 8192 }, + }, + "inception/mercury-2": { + id: "inception/mercury-2", + name: "Mercury 2", + family: "mercury", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-03-04", + last_updated: "2026-03-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 0.75, cache_read: 0.025 }, + limit: { context: 128000, output: 50000 }, + }, + "openai/gpt-5.1-codex-max": { + id: "openai/gpt-5.1-codex-max", + name: "GPT-5.1-Codex-Max", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-09-30", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 9, cache_read: 0.11 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-5.2-chat": { + id: "openai/gpt-5.2-chat", + name: "GPT-5.2 Chat", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2025-12-11", + last_updated: "2025-12-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 128000, output: 16384 }, + }, + "openai/gpt-oss-120b:exacto": { + id: "openai/gpt-oss-120b:exacto", + name: "GPT OSS 120B (exacto)", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.05, output: 0.24 }, + limit: { context: 131072, output: 32768 }, + }, + "openai/gpt-5-chat": { + id: "openai/gpt-5-chat", + name: "GPT-5 Chat (latest)", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: false, + structured_output: true, + temperature: true, + knowledge: "2024-09-30", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-5.2-pro": { + id: "openai/gpt-5.2-pro", + name: "GPT-5.2 Pro", + family: "gpt-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2025-12-11", + last_updated: "2025-12-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 21, output: 168 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-5-mini": { + id: "openai/gpt-5-mini", + name: "GPT-5 Mini", + family: "gpt-mini", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-10-01", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 2 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-5-nano": { + id: "openai/gpt-5-nano", + name: "GPT-5 Nano", + family: "gpt-nano", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-10-01", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.05, output: 0.4 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-5.3-codex": { + id: "openai/gpt-5.3-codex", + name: "GPT-5.3-Codex", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-02-24", + last_updated: "2026-02-24", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-5.2": { + id: "openai/gpt-5.2", + name: "GPT-5.2", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2025-12-11", + last_updated: "2025-12-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-oss-20b:free": { + id: "openai/gpt-oss-20b:free", + name: "gpt-oss-20b (free)", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-05", + last_updated: "2026-01-31", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 131072, output: 32768 }, + }, + "openai/gpt-4o-mini": { + id: "openai/gpt-4o-mini", + name: "GPT-4o-mini", + family: "gpt-mini", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-10", + release_date: "2024-07-18", + last_updated: "2024-07-18", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.6, cache_read: 0.08 }, + limit: { context: 128000, output: 16384 }, + }, + "openai/gpt-5.4-mini": { + id: "openai/gpt-5.4-mini", + name: "GPT-5.4 Mini", + family: "gpt-mini", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-08-31", + release_date: "2026-03-17", + last_updated: "2026-03-17", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.75, output: 4.5, cache_read: 0.075 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-5.1-chat": { + id: "openai/gpt-5.1-chat", + name: "GPT-5.1 Chat", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-09-30", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 128000, output: 16384 }, + }, + "openai/o4-mini": { + id: "openai/o4-mini", + name: "o4 Mini", + family: "o-mini", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-06", + release_date: "2025-04-16", + last_updated: "2025-04-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 4.4, cache_read: 0.28 }, + limit: { context: 200000, output: 100000 }, + }, + "openai/gpt-5.4-nano": { + id: "openai/gpt-5.4-nano", + name: "GPT-5.4 Nano", + family: "gpt-nano", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-08-31", + release_date: "2026-03-17", + last_updated: "2026-03-17", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 1.25, cache_read: 0.02 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-5.2-codex": { + id: "openai/gpt-5.2-codex", + name: "GPT-5.2-Codex", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-08-31", + release_date: "2026-01-14", + last_updated: "2026-01-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-5.1-codex-mini": { + id: "openai/gpt-5.1-codex-mini", + name: "GPT-5.1-Codex-Mini", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-09-30", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 2, cache_read: 0.025 }, + limit: { context: 400000, output: 100000 }, + }, + "openai/gpt-5-image": { + id: "openai/gpt-5-image", + name: "GPT-5 Image", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-10-01", + release_date: "2025-10-14", + last_updated: "2025-10-14", + modalities: { input: ["text", "image", "pdf"], output: ["text", "image"] }, + open_weights: false, + cost: { input: 5, output: 10, cache_read: 1.25 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-5.1": { + id: "openai/gpt-5.1", + name: "GPT-5.1", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-09-30", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-5.4-pro": { + id: "openai/gpt-5.4-pro", + name: "GPT-5.4 Pro", + family: "gpt-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-05", + last_updated: "2026-03-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 30, output: 180, cache_read: 30 }, + limit: { context: 1050000, input: 922000, output: 128000 }, + }, + "openai/gpt-5-codex": { + id: "openai/gpt-5-codex", + name: "GPT-5 Codex", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-10-01", + release_date: "2025-09-15", + last_updated: "2025-09-15", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-oss-20b": { + id: "openai/gpt-oss-20b", + name: "GPT OSS 20B", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.05, output: 0.2 }, + limit: { context: 131072, output: 32768 }, + }, + "openai/gpt-5-pro": { + id: "openai/gpt-5-pro", + name: "GPT-5 Pro", + family: "gpt-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-10-06", + last_updated: "2025-10-06", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 120 }, + limit: { context: 400000, output: 272000 }, + }, + "openai/gpt-oss-120b:free": { + id: "openai/gpt-oss-120b:free", + name: "gpt-oss-120b (free)", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 131072, output: 32768 }, + }, + "openai/gpt-5": { + id: "openai/gpt-5", + name: "GPT-5", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-10-01", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-oss-safeguard-20b": { + id: "openai/gpt-oss-safeguard-20b", + name: "GPT OSS Safeguard 20B", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-10-29", + last_updated: "2025-10-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.075, output: 0.3 }, + limit: { context: 131072, output: 65536 }, + }, + "openai/gpt-oss-120b": { + id: "openai/gpt-oss-120b", + name: "GPT OSS 120B", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.072, output: 0.28 }, + limit: { context: 131072, output: 32768 }, + }, + "openai/gpt-4.1": { + id: "openai/gpt-4.1", + name: "GPT-4.1", + 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"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 8, cache_read: 0.5 }, + limit: { context: 1047576, output: 32768 }, + }, + "openai/gpt-4.1-mini": { + id: "openai/gpt-4.1-mini", + name: "GPT-4.1 Mini", + family: "gpt-mini", + 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"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 1.6, cache_read: 0.1 }, + limit: { context: 1047576, output: 32768 }, + }, + "openai/gpt-5.1-codex": { + id: "openai/gpt-5.1-codex", + name: "GPT-5.1-Codex", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-09-30", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 400000, output: 128000 }, + }, + "z-ai/glm-4.7": { + id: "z-ai/glm-4.7", + name: "GLM-4.7", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_details" }, + structured_output: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-12-22", + last_updated: "2025-12-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.2, cache_read: 0.11 }, + limit: { context: 204800, output: 131072 }, + }, + "z-ai/glm-4.5-air:free": { + id: "z-ai/glm-4.5-air:free", + name: "GLM 4.5 Air (free)", + family: "glm-air", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-28", + last_updated: "2025-07-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 96000 }, + }, + "z-ai/glm-5": { + id: "z-ai/glm-5", + name: "GLM-5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 3.2, cache_read: 0.2 }, + limit: { context: 202752, output: 131000 }, + }, + "z-ai/glm-5.1": { + id: "z-ai/glm-5.1", + name: "GLM-5.1", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-04-07", + last_updated: "2026-04-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.4, output: 4.4, cache_read: 0.26 }, + limit: { context: 202752, output: 131072 }, + }, + "z-ai/glm-4.5": { + id: "z-ai/glm-4.5", + name: "GLM 4.5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-28", + last_updated: "2025-07-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.2 }, + limit: { context: 128000, output: 96000 }, + }, + "z-ai/glm-4.6:exacto": { + id: "z-ai/glm-4.6:exacto", + name: "GLM 4.6 (exacto)", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-09", + release_date: "2025-09-30", + last_updated: "2025-09-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 1.9, cache_read: 0.11 }, + limit: { context: 200000, output: 128000 }, + }, + "z-ai/glm-4.5-air": { + id: "z-ai/glm-4.5-air", + name: "GLM 4.5 Air", + family: "glm-air", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-28", + last_updated: "2025-07-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 1.1 }, + limit: { context: 128000, output: 96000 }, + }, + "z-ai/glm-5-turbo": { + id: "z-ai/glm-5-turbo", + name: "GLM-5-Turbo", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-03-16", + last_updated: "2026-03-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.96, output: 3.2, cache_read: 0.192, cache_write: 0 }, + limit: { context: 202752, output: 131072 }, + }, + "z-ai/glm-4.5v": { + id: "z-ai/glm-4.5v", + name: "GLM 4.5V", + family: "glm", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-08-11", + last_updated: "2025-08-11", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 1.8 }, + limit: { context: 64000, output: 16384 }, + }, + "z-ai/glm-4.6": { + id: "z-ai/glm-4.6", + name: "GLM 4.6", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-09", + release_date: "2025-09-30", + last_updated: "2025-09-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.2, cache_read: 0.11 }, + limit: { context: 200000, output: 128000 }, + }, + "z-ai/glm-4.7-flash": { + id: "z-ai/glm-4.7-flash", + name: "GLM-4.7-Flash", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_details" }, + structured_output: true, + temperature: true, + release_date: "2026-01-19", + last_updated: "2026-01-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.07, output: 0.4 }, + limit: { context: 200000, output: 65535 }, + }, + "sourceful/riverflow-v2-standard-preview": { + id: "sourceful/riverflow-v2-standard-preview", + name: "Riverflow V2 Standard Preview", + family: "sourceful", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2025-06", + release_date: "2025-12-08", + last_updated: "2026-01-28", + modalities: { input: ["text", "image"], output: ["image"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 8192, output: 8192 }, + }, + "sourceful/riverflow-v2-fast-preview": { + id: "sourceful/riverflow-v2-fast-preview", + name: "Riverflow V2 Fast Preview", + family: "sourceful", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2025-06", + release_date: "2025-12-08", + last_updated: "2026-01-28", + modalities: { input: ["text", "image"], output: ["image"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 8192, output: 8192 }, + }, + "sourceful/riverflow-v2-max-preview": { + id: "sourceful/riverflow-v2-max-preview", + name: "Riverflow V2 Max Preview", + family: "sourceful", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2025-06", + release_date: "2025-12-08", + last_updated: "2026-01-28", + modalities: { input: ["text", "image"], output: ["image"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 8192, output: 8192 }, + }, + "minimax/minimax-m2.7": { + id: "minimax/minimax-m2.7", + name: "MiniMax M2.7", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2, cache_read: 0.06, cache_write: 0.375 }, + limit: { context: 204800, output: 131072 }, + }, + "minimax/minimax-m2": { + id: "minimax/minimax-m2", + name: "MiniMax M2", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_details" }, + structured_output: true, + temperature: true, + release_date: "2025-10-23", + last_updated: "2025-10-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.28, output: 1.15, cache_read: 0.28, cache_write: 1.15 }, + limit: { context: 196600, output: 118000 }, + }, + "minimax/minimax-01": { + id: "minimax/minimax-01", + name: "MiniMax-01", + family: "minimax", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-01-15", + last_updated: "2025-01-15", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 1.1 }, + limit: { context: 1000000, output: 1000000 }, + }, + "minimax/minimax-m2.1": { + id: "minimax/minimax-m2.1", + name: "MiniMax M2.1", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_details" }, + structured_output: true, + temperature: true, + release_date: "2025-12-23", + last_updated: "2025-12-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 204800, output: 131072 }, + }, + "minimax/minimax-m2.5:free": { + id: "minimax/minimax-m2.5:free", + name: "MiniMax M2.5 (free)", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_details" }, + structured_output: true, + temperature: true, + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 204800, output: 131072 }, + }, + "minimax/minimax-m1": { + id: "minimax/minimax-m1", + name: "MiniMax M1", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-06-17", + last_updated: "2025-06-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.4, output: 2.2 }, + limit: { context: 1000000, output: 40000 }, + }, + "minimax/minimax-m2.5": { + id: "minimax/minimax-m2.5", + name: "MiniMax M2.5", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_details" }, + structured_output: true, + temperature: true, + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2, cache_read: 0.03 }, + limit: { context: 204800, output: 131072 }, + }, + "qwen/qwen3-coder-plus": { + id: "qwen/qwen3-coder-plus", + name: "Qwen3 Coder Plus", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-09-23", + last_updated: "2025-09-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.65, output: 3.25, cache_read: 0.13, cache_write: 0.8125 }, + limit: { context: 1000000, output: 65536 }, + }, + "qwen/qwen3.5-397b-a17b": { + id: "qwen/qwen3.5-397b-a17b", + name: "Qwen3.5 397B A17B", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-02-16", + last_updated: "2026-02-16", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 3.6 }, + limit: { context: 262144, output: 65536 }, + }, + "qwen/qwen2.5-vl-72b-instruct": { + id: "qwen/qwen2.5-vl-72b-instruct", + name: "Qwen2.5 VL 72B Instruct", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-02-01", + last_updated: "2025-02-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 32768, output: 8192 }, + }, + "qwen/qwen-plus": { + id: "qwen/qwen-plus", + name: "Qwen: Qwen-Plus", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + knowledge: "2024-04", + release_date: "2025-01-25", + last_updated: "2025-01-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.26, output: 0.78, cache_read: 0.052, cache_write: 0.325 }, + limit: { context: 1000000, output: 32768 }, + }, + "qwen/qwen3.5-flash-02-23": { + id: "qwen/qwen3.5-flash-02-23", + name: "Qwen: Qwen3.5-Flash", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-02-25", + last_updated: "2026-02-25", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.065, output: 0.26 }, + limit: { context: 1000000, output: 65536 }, + }, + "qwen/qwen3.6-plus": { + id: "qwen/qwen3.6-plus", + name: "Qwen3.6 Plus", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-04-02", + last_updated: "2026-04-02", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.325, output: 1.95, cache_read: 0.0325, cache_write: 0.40625 }, + limit: { context: 1000000, output: 65536 }, + }, + "qwen/qwen3-max": { + id: "qwen/qwen3-max", + name: "Qwen3 Max", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-09-05", + last_updated: "2025-09-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.2, output: 6, cache_read: 0.156, cache_write: 0.975 }, + limit: { context: 262144, output: 32768 }, + }, + "qwen/qwen3-coder:exacto": { + id: "qwen/qwen3-coder:exacto", + name: "Qwen3 Coder (exacto)", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-23", + last_updated: "2025-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.38, output: 1.53 }, + limit: { context: 131072, output: 32768 }, + }, + "qwen/qwen3-30b-a3b-instruct-2507": { + id: "qwen/qwen3-30b-a3b-instruct-2507", + name: "Qwen3 30B A3B Instruct 2507", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-29", + last_updated: "2025-07-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.8 }, + limit: { context: 262000, output: 262000 }, + }, + "qwen/qwen-3.6-27b": { + id: "qwen/qwen-3.6-27b", + name: "Qwen3.6 27B", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-04-22", + last_updated: "2026-04-22", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.195, output: 1.56 }, + limit: { context: 262144, output: 81920 }, + }, + "qwen/qwen3-235b-a22b-thinking-2507": { + id: "qwen/qwen3-235b-a22b-thinking-2507", + name: "Qwen3 235B A22B Thinking 2507", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-25", + last_updated: "2025-07-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.078, output: 0.312 }, + limit: { context: 262144, output: 81920 }, + }, + "qwen/qwen3-next-80b-a3b-thinking": { + id: "qwen/qwen3-next-80b-a3b-thinking", + name: "Qwen3 Next 80B A3B Thinking", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-09-11", + last_updated: "2025-09-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.14, output: 1.4 }, + limit: { context: 262144, output: 262144 }, + }, + "qwen/qwen3-30b-a3b-thinking-2507": { + id: "qwen/qwen3-30b-a3b-thinking-2507", + name: "Qwen3 30B A3B Thinking 2507", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-29", + last_updated: "2025-07-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.8 }, + limit: { context: 262000, output: 262000 }, + }, + "qwen/qwen3-coder-flash": { + id: "qwen/qwen3-coder-flash", + name: "Qwen3 Coder Flash", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-23", + last_updated: "2025-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 1.5, cache_read: 0.039, cache_write: 0.24375 }, + limit: { context: 128000, output: 66536 }, + }, + "qwen/qwen3-next-80b-a3b-instruct": { + id: "qwen/qwen3-next-80b-a3b-instruct", + name: "Qwen3 Next 80B A3B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-09-11", + last_updated: "2025-09-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.14, output: 1.4 }, + limit: { context: 262144, output: 262144 }, + }, + "qwen/qwen-2.5-coder-32b-instruct": { + id: "qwen/qwen-2.5-coder-32b-instruct", + name: "Qwen2.5 Coder 32B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: true, + temperature: true, + knowledge: "2024-10", + release_date: "2024-11-11", + last_updated: "2024-11-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 32768, output: 8192 }, + }, + "qwen/qwen3-coder-30b-a3b-instruct": { + id: "qwen/qwen3-coder-30b-a3b-instruct", + name: "Qwen3 Coder 30B A3B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-31", + last_updated: "2025-07-31", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.07, output: 0.27 }, + limit: { context: 160000, output: 65536 }, + }, + "qwen/qwen3-coder": { + id: "qwen/qwen3-coder", + name: "Qwen3 Coder", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-23", + last_updated: "2025-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 262144, output: 66536 }, + }, + "qwen/qwen3.5-plus-02-15": { + id: "qwen/qwen3.5-plus-02-15", + name: "Qwen3.5 Plus 2026-02-15", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-02-16", + last_updated: "2026-02-16", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 2.4 }, + limit: { context: 1000000, output: 65536 }, + }, + "qwen/qwen3-235b-a22b-07-25": { + id: "qwen/qwen3-235b-a22b-07-25", + name: "Qwen3 235B A22B Instruct 2507", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-04-28", + last_updated: "2025-07-21", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.85 }, + limit: { context: 262144, output: 131072 }, + }, + "google/gemini-2.5-pro-preview-05-06": { + id: "google/gemini-2.5-pro-preview-05-06", + name: "Gemini 2.5 Pro Preview 05-06", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-05-06", + last_updated: "2025-05-06", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.31 }, + limit: { context: 1048576, output: 65536 }, + }, + "google/gemini-3.1-pro-preview-customtools": { + id: "google/gemini-3.1-pro-preview-customtools", + name: "Gemini 3.1 Pro Preview Custom Tools", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_details" }, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-02-19", + last_updated: "2026-02-19", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 12, reasoning: 12, context_over_200k: { input: 4, output: 18, cache_read: 0.4 } }, + limit: { context: 1048576, output: 65536 }, + }, + "google/gemma-3-4b-it:free": { + id: "google/gemma-3-4b-it:free", + name: "Gemma 3 4B (free)", + family: "gemma", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-10", + release_date: "2025-03-13", + last_updated: "2025-03-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 32768, output: 8192 }, + }, + "google/gemini-2.5-flash-lite-preview-09-2025": { + id: "google/gemini-2.5-flash-lite-preview-09-2025", + name: "Gemini 2.5 Flash Lite Preview 09-25", + family: "gemini-flash-lite", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-09-25", + last_updated: "2025-09-25", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4, cache_read: 0.025 }, + limit: { context: 1048576, output: 65536 }, + }, + "google/gemini-2.0-flash-001": { + id: "google/gemini-2.0-flash-001", + name: "Gemini 2.0 Flash", + family: "gemini-flash", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-06", + release_date: "2024-12-11", + last_updated: "2024-12-11", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4, cache_read: 0.025 }, + limit: { context: 1048576, output: 8192 }, + }, + "google/gemma-3n-e4b-it": { + id: "google/gemma-3n-e4b-it", + name: "Gemma 3n 4B", + family: "gemma", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-06", + release_date: "2025-05-20", + last_updated: "2025-05-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.02, output: 0.04 }, + limit: { context: 32768, output: 32768 }, + }, + "google/gemini-3.1-flash-lite-preview": { + id: "google/gemini-3.1-flash-lite-preview", + name: "Gemini 3.1 Flash Lite Preview", + family: "gemini-flash-lite", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-03-03", + last_updated: "2026-03-03", + modalities: { input: ["text", "image", "video", "pdf", "audio"], output: ["text"] }, + open_weights: false, + cost: { + input: 0.25, + output: 1.5, + reasoning: 1.5, + cache_read: 0.025, + cache_write: 0.083, + input_audio: 0.5, + output_audio: 0.5, + }, + limit: { context: 1048576, output: 65536 }, + }, + "google/gemma-3n-e4b-it:free": { + id: "google/gemma-3n-e4b-it:free", + name: "Gemma 3n 4B (free)", + family: "gemma", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-06", + release_date: "2025-05-20", + last_updated: "2025-05-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 8192, output: 2000 }, + }, + "google/gemini-3.1-pro-preview": { + id: "google/gemini-3.1-pro-preview", + name: "Gemini 3.1 Pro Preview", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_details" }, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-02-19", + last_updated: "2026-02-19", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 12, reasoning: 12, context_over_200k: { input: 4, output: 18, cache_read: 0.4 } }, + limit: { context: 1048576, output: 65536 }, + }, + "google/gemini-3-flash-preview": { + id: "google/gemini-3-flash-preview", + name: "Gemini 3 Flash Preview", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_details" }, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-12-17", + last_updated: "2025-12-17", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 3, cache_read: 0.05 }, + limit: { context: 1048576, output: 65536 }, + }, + "google/gemini-3-pro-preview": { + id: "google/gemini-3-pro-preview", + name: "Gemini 3 Pro Preview", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_details" }, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-11-18", + last_updated: "2025-11", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 12 }, + limit: { context: 1050000, output: 66000 }, + }, + "google/gemma-3n-e2b-it:free": { + id: "google/gemma-3n-e2b-it:free", + name: "Gemma 3n 2B (free)", + family: "gemma", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-06", + release_date: "2025-07-09", + last_updated: "2025-07-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 8192, output: 2000 }, + }, + "google/gemma-2-9b-it": { + id: "google/gemma-2-9b-it", + name: "Gemma 2 9B", + family: "gemma", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-06", + release_date: "2024-06-28", + last_updated: "2024-06-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.03, output: 0.09 }, + limit: { context: 8192, output: 8192 }, + }, + "google/gemma-4-31b-it": { + id: "google/gemma-4-31b-it", + name: "Gemma 4 31B", + family: "gemma", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-04-02", + last_updated: "2026-04-02", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.14, output: 0.4 }, + limit: { context: 262144, output: 262144 }, + }, + "google/gemini-2.5-pro-preview-06-05": { + id: "google/gemini-2.5-pro-preview-06-05", + name: "Gemini 2.5 Pro Preview 06-05", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-06-05", + last_updated: "2025-06-05", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.31 }, + limit: { context: 1048576, output: 65536 }, + }, + "google/gemma-3-12b-it": { + id: "google/gemma-3-12b-it", + name: "Gemma 3 12B", + family: "gemma", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-03-13", + last_updated: "2025-03-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.03, output: 0.1 }, + limit: { context: 131072, output: 131072 }, + }, + "google/gemma-3-27b-it:free": { + id: "google/gemma-3-27b-it:free", + name: "Gemma 3 27B (free)", + family: "gemma", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-03-12", + last_updated: "2025-03-12", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 131072, output: 8192 }, + }, + "google/gemini-2.5-flash": { + id: "google/gemini-2.5-flash", + name: "Gemini 2.5 Flash", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-07-17", + last_updated: "2025-07-17", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 2.5, cache_read: 0.0375 }, + limit: { context: 1048576, output: 65536 }, + }, + "google/gemini-3.1-flash-image-preview": { + id: "google/gemini-3.1-flash-image-preview", + name: "Gemini 3.1 Flash Image Preview (Nano Banana 2)", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: false, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-02-26", + last_updated: "2026-02-26", + modalities: { input: ["text", "image"], output: ["text", "image"] }, + open_weights: false, + cost: { input: 0.5, output: 3 }, + limit: { context: 65536, output: 65536 }, + }, + "google/gemma-4-31b-it:free": { + id: "google/gemma-4-31b-it:free", + name: "Gemma 4 31B (free)", + family: "gemma", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-04-02", + last_updated: "2026-04-02", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 262144, output: 32768 }, + }, + "google/gemma-3-12b-it:free": { + id: "google/gemma-3-12b-it:free", + name: "Gemma 3 12B (free)", + family: "gemma", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-10", + release_date: "2025-03-13", + last_updated: "2025-03-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 32768, output: 8192 }, + }, + "google/gemma-3-4b-it": { + id: "google/gemma-3-4b-it", + name: "Gemma 3 4B", + family: "gemma", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-10", + release_date: "2025-03-13", + last_updated: "2025-03-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.01703, output: 0.06815 }, + limit: { context: 96000, output: 96000 }, + }, + "google/gemini-2.5-flash-preview-09-2025": { + id: "google/gemini-2.5-flash-preview-09-2025", + name: "Gemini 2.5 Flash Preview 09-25", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-09-25", + last_updated: "2025-09-25", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 2.5, cache_read: 0.031 }, + limit: { context: 1048576, output: 65536 }, + }, + "google/gemma-3-27b-it": { + id: "google/gemma-3-27b-it", + name: "Gemma 3 27B", + family: "gemma", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-03-12", + last_updated: "2025-03-12", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.04, output: 0.15 }, + limit: { context: 96000, output: 96000 }, + }, + "google/gemma-4-26b-a4b-it": { + id: "google/gemma-4-26b-a4b-it", + name: "Gemma 4 26B A4B", + family: "gemma", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-04-03", + last_updated: "2026-04-03", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.13, output: 0.4 }, + limit: { context: 262144, output: 262144 }, + }, + "google/gemma-4-26b-a4b-it:free": { + id: "google/gemma-4-26b-a4b-it:free", + name: "Gemma 4 26B A4B (free)", + family: "gemma", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-04-03", + last_updated: "2026-04-03", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 262144, output: 32768 }, + }, + "google/gemini-2.5-flash-lite": { + id: "google/gemini-2.5-flash-lite", + name: "Gemini 2.5 Flash Lite", + family: "gemini-flash-lite", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-06-17", + last_updated: "2025-06-17", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4, cache_read: 0.025 }, + limit: { context: 1048576, output: 65536 }, + }, + "moonshotai/kimi-k2.5": { + id: "moonshotai/kimi-k2.5", + name: "Kimi K2.5", + family: "kimi", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_details" }, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-01-27", + last_updated: "2026-01-27", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 3, cache_read: 0.1 }, + limit: { context: 262144, output: 262144 }, + }, + "moonshotai/kimi-k2-0905": { + id: "moonshotai/kimi-k2-0905", + name: "Kimi K2 Instruct 0905", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-09-05", + last_updated: "2025-09-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.5 }, + limit: { context: 262144, output: 16384 }, + }, + "moonshotai/kimi-k2.6": { + id: "moonshotai/kimi-k2.6", + name: "Kimi K2.6", + family: "kimi", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_details" }, + structured_output: true, + temperature: true, + release_date: "2026-04-20", + last_updated: "2026-04-20", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.95, output: 4, cache_read: 0.16 }, + limit: { context: 262144, output: 262144 }, + }, + "moonshotai/kimi-k2-0905:exacto": { + id: "moonshotai/kimi-k2-0905:exacto", + name: "Kimi K2 Instruct 0905 (exacto)", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-09-05", + last_updated: "2025-09-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.5 }, + limit: { context: 262144, output: 16384 }, + }, + "moonshotai/kimi-k2": { + id: "moonshotai/kimi-k2", + name: "Kimi K2", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-07-11", + last_updated: "2025-07-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.55, output: 2.2 }, + limit: { context: 131072, output: 32768 }, + }, + "moonshotai/kimi-k2-thinking": { + id: "moonshotai/kimi-k2-thinking", + name: "Kimi K2 Thinking", + family: "kimi-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_details" }, + structured_output: true, + temperature: true, + knowledge: "2024-08", + release_date: "2025-11-06", + last_updated: "2025-11-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.5, cache_read: 0.15 }, + limit: { context: 262144, output: 262144 }, + }, + "anthropic/claude-opus-4.1": { + id: "anthropic/claude-opus-4.1", + name: "Claude Opus 4.1", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 32000 }, + }, + "anthropic/claude-3.7-sonnet": { + id: "anthropic/claude-3.7-sonnet", + name: "Claude Sonnet 3.7", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-01", + release_date: "2025-02-19", + last_updated: "2025-02-19", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 128000 }, + }, + "anthropic/claude-opus-4.6": { + id: "anthropic/claude-opus-4.6", + name: "Claude Opus 4.6", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-05-31", + release_date: "2026-02-05", + last_updated: "2026-02-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 5, + output: 25, + cache_read: 0.5, + cache_write: 6.25, + context_over_200k: { input: 10, output: 37.5, cache_read: 1, cache_write: 12.5 }, + }, + limit: { context: 1000000, output: 128000 }, + }, + "anthropic/claude-opus-4.7": { + id: "anthropic/claude-opus-4.7", + name: "Claude Opus 4.7", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2026-01-31", + release_date: "2026-04-16", + last_updated: "2026-04-16", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 5, + output: 25, + cache_read: 0.5, + cache_write: 6.25, + context_over_200k: { input: 10, output: 37.5, cache_read: 1, cache_write: 12.5 }, + }, + limit: { context: 1000000, output: 128000 }, + }, + "anthropic/claude-sonnet-4": { + id: "anthropic/claude-sonnet-4", + name: "Claude Sonnet 4", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 3, + output: 15, + cache_read: 0.3, + cache_write: 3.75, + context_over_200k: { input: 6, output: 22.5, cache_read: 0.6, cache_write: 7.5 }, + }, + limit: { context: 200000, output: 64000 }, + }, + "anthropic/claude-sonnet-4.5": { + id: "anthropic/claude-sonnet-4.5", + name: "Claude Sonnet 4.5", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-07-31", + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 3, + output: 15, + cache_read: 0.3, + cache_write: 3.75, + context_over_200k: { input: 6, output: 22.5, cache_read: 0.6, cache_write: 7.5 }, + }, + limit: { context: 1000000, output: 64000 }, + }, + "anthropic/claude-opus-4.5": { + id: "anthropic/claude-opus-4.5", + name: "Claude Opus 4.5", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-05-30", + release_date: "2025-11-24", + last_updated: "2025-11-24", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 200000, output: 32000 }, + }, + "anthropic/claude-haiku-4.5": { + id: "anthropic/claude-haiku-4.5", + name: "Claude Haiku 4.5", + family: "claude-haiku", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-02-28", + release_date: "2025-10-15", + last_updated: "2025-10-15", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 5, cache_read: 0.1, cache_write: 1.25 }, + limit: { context: 200000, output: 64000 }, + }, + "anthropic/claude-sonnet-4.6": { + id: "anthropic/claude-sonnet-4.6", + name: "Claude Sonnet 4.6", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-08-31", + release_date: "2026-02-17", + last_updated: "2026-02-17", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { + input: 3, + output: 15, + cache_read: 0.3, + cache_write: 3.75, + context_over_200k: { input: 6, output: 22.5, cache_read: 0.6, cache_write: 7.5 }, + }, + limit: { context: 1000000, output: 128000 }, + }, + "deepseek/deepseek-v4-flash": { + id: "deepseek/deepseek-v4-flash", + name: "DeepSeek V4 Flash", + family: "deepseek-flash", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-05", + release_date: "2026-04-24", + last_updated: "2026-04-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.14, output: 0.28, cache_read: 0.028 }, + limit: { context: 1048576, output: 393216 }, + }, + "deepseek/deepseek-v4-pro": { + id: "deepseek/deepseek-v4-pro", + name: "DeepSeek V4 Pro", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-05", + release_date: "2026-04-24", + last_updated: "2026-04-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.74, output: 3.48, cache_read: 0.145 }, + limit: { context: 1048576, output: 393216 }, + }, + "x-ai/grok-4.3": { + id: "x-ai/grok-4.3", + name: "Grok 4.3", + family: "grok", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-05-01", + last_updated: "2026-05-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { + input: 1.25, + output: 2.5, + cache_read: 0.2, + context_over_200k: { input: 2.5, output: 5, cache_read: 0.4 }, + }, + limit: { context: 1000000, output: 1000000 }, + }, + "openai/gpt-5.5": { + id: "openai/gpt-5.5", + name: "GPT-5.5", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-12-01", + release_date: "2026-04-23", + last_updated: "2026-04-23", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 30, cache_read: 0.5, context_over_200k: { input: 10, output: 45, cache_read: 1 } }, + limit: { context: 1050000, input: 922000, output: 128000 }, + }, + "openai/gpt-5.4": { + id: "openai/gpt-5.4", + name: "GPT-5.4", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-05", + last_updated: "2026-03-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 2.5, + output: 15, + cache_read: 0.25, + context_over_200k: { input: 5, output: 22.5, cache_read: 0.5 }, + }, + limit: { context: 1050000, input: 922000, output: 128000 }, + }, + "openai/gpt-5.5-pro": { + id: "openai/gpt-5.5-pro", + name: "GPT-5.5 Pro", + family: "gpt-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-12-01", + release_date: "2026-04-23", + last_updated: "2026-04-23", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 30, output: 180, context_over_200k: { input: 60, output: 270 } }, + limit: { context: 1050000, input: 922000, output: 128000 }, + }, + "google/gemini-2.5-pro": { + id: "google/gemini-2.5-pro", + name: "Gemini 2.5 Pro", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-03-20", + last_updated: "2025-06-05", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 1.25, + output: 10, + cache_read: 0.125, + context_over_200k: { input: 2.5, output: 15, cache_read: 0.25 }, + }, + limit: { context: 1048576, output: 65536 }, + }, + "anthropic/claude-opus-4": { + id: "anthropic/claude-opus-4", + name: "Claude Opus 4", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 32000 }, + }, + "anthropic/claude-3.5-haiku": { + id: "anthropic/claude-3.5-haiku", + name: "Claude Haiku 3.5", + family: "claude-haiku", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-07-31", + release_date: "2024-10-22", + last_updated: "2024-10-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.8, output: 4, cache_read: 0.08, cache_write: 1 }, + limit: { context: 200000, output: 8192 }, + }, + "xiaomi/mimo-v2.5-pro": { + id: "xiaomi/mimo-v2.5-pro", + name: "Xiaomi: MiMo-V2.5-Pro", + family: "mimo", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12", + release_date: "2026-04-22", + last_updated: "2026-04-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 3, cache_read: 0.2, context_over_200k: { input: 2, output: 6, cache_read: 0.4 } }, + limit: { context: 1048576, output: 131072 }, + }, + "xiaomi/mimo-v2-omni": { + id: "xiaomi/mimo-v2-omni", + name: "Xiaomi: MiMo-V2-Omni", + family: "mimo", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_details" }, + temperature: true, + knowledge: "2024-12", + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 2, cache_read: 0.08 }, + limit: { context: 262144, output: 131072 }, + }, + "xiaomi/mimo-v2.5": { + id: "xiaomi/mimo-v2.5", + name: "Xiaomi: MiMo-V2.5", + family: "mimo", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_details" }, + temperature: true, + knowledge: "2024-12", + release_date: "2026-04-22", + last_updated: "2026-04-22", + modalities: { input: ["text", "image", "audio", "video"], output: ["text"] }, + open_weights: true, + cost: { + input: 0.4, + output: 2, + cache_read: 0.08, + context_over_200k: { input: 0.8, output: 4, cache_read: 0.16 }, + }, + limit: { context: 1048576, output: 131072 }, + }, + "xiaomi/mimo-v2-pro": { + id: "xiaomi/mimo-v2-pro", + name: "Xiaomi: MiMo-V2-Pro", + family: "mimo", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_details" }, + temperature: true, + knowledge: "2024-12", + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 3, cache_read: 0.2, context_over_200k: { input: 2, output: 6, cache_read: 0.4 } }, + limit: { context: 1048576, output: 131072 }, + }, + "xiaomi/mimo-v2-flash": { + id: "xiaomi/mimo-v2-flash", + name: "Xiaomi: MiMo-V2-Flash", + family: "mimo", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_details" }, + temperature: true, + knowledge: "2024-12-01", + release_date: "2025-12-16", + last_updated: "2026-02-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.3, cache_read: 0.01 }, + limit: { context: 262144, output: 65536 }, + }, + }, + }, + "fireworks-ai": { + id: "fireworks-ai", + env: ["FIREWORKS_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.fireworks.ai/inference/v1/", + name: "Fireworks AI", + doc: "https://fireworks.ai/docs/", + models: { + "accounts/fireworks/models/glm-5p1": { + id: "accounts/fireworks/models/glm-5p1", + name: "GLM 5.1", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-04-01", + last_updated: "2026-04-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.4, output: 4.4, cache_read: 0.26 }, + limit: { context: 202800, output: 131072 }, + }, + "accounts/fireworks/models/deepseek-v3p2": { + id: "accounts/fireworks/models/deepseek-v3p2", + name: "DeepSeek V3.2", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-09", + release_date: "2025-12-01", + last_updated: "2025-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.56, output: 1.68, cache_read: 0.28 }, + limit: { context: 160000, output: 160000 }, + }, + "accounts/fireworks/models/minimax-m2p5": { + id: "accounts/fireworks/models/minimax-m2p5", + name: "MiniMax-M2.5", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2, cache_read: 0.03 }, + limit: { context: 196608, output: 196608 }, + }, + "accounts/fireworks/models/glm-4p5-air": { + id: "accounts/fireworks/models/glm-4p5-air", + name: "GLM 4.5 Air", + family: "glm-air", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-08-01", + last_updated: "2025-08-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.22, output: 0.88 }, + limit: { context: 131072, output: 131072 }, + }, + "accounts/fireworks/models/glm-5": { + id: "accounts/fireworks/models/glm-5", + name: "GLM 5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-02-11", + last_updated: "2026-02-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 3.2, cache_read: 0.5 }, + limit: { context: 202752, output: 131072 }, + }, + "accounts/fireworks/models/deepseek-v3p1": { + id: "accounts/fireworks/models/deepseek-v3p1", + name: "DeepSeek V3.1", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-08-21", + last_updated: "2025-08-21", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.56, output: 1.68 }, + limit: { context: 163840, output: 163840 }, + }, + "accounts/fireworks/models/kimi-k2p6": { + id: "accounts/fireworks/models/kimi-k2p6", + name: "Kimi K2.6", + family: "kimi-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-04-17", + last_updated: "2026-04-17", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.95, output: 4, cache_read: 0.16 }, + limit: { context: 262000, output: 262000 }, + }, + "accounts/fireworks/models/kimi-k2-instruct": { + id: "accounts/fireworks/models/kimi-k2-instruct", + name: "Kimi K2 Instruct", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-07-11", + last_updated: "2025-07-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 3 }, + limit: { context: 128000, output: 16384 }, + }, + "accounts/fireworks/models/qwen3p6-plus": { + id: "accounts/fireworks/models/qwen3p6-plus", + name: "Qwen 3.6 Plus", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-04", + last_updated: "2026-04-04", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 3, cache_read: 0.1 }, + limit: { context: 128000, output: 8192 }, + }, + "accounts/fireworks/models/minimax-m2p1": { + id: "accounts/fireworks/models/minimax-m2p1", + name: "MiniMax-M2.1", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2025-12-23", + last_updated: "2025-12-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2, cache_read: 0.03 }, + limit: { context: 200000, output: 200000 }, + }, + "accounts/fireworks/models/minimax-m2p7": { + id: "accounts/fireworks/models/minimax-m2p7", + name: "MiniMax-M2.7", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-04-12", + last_updated: "2026-04-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2, cache_read: 0.03 }, + limit: { context: 196608, output: 196608 }, + }, + "accounts/fireworks/models/glm-4p7": { + id: "accounts/fireworks/models/glm-4p7", + name: "GLM 4.7", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-04", + release_date: "2025-12-22", + last_updated: "2025-12-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.2, cache_read: 0.3 }, + limit: { context: 198000, output: 198000 }, + }, + "accounts/fireworks/models/glm-4p5": { + id: "accounts/fireworks/models/glm-4p5", + name: "GLM 4.5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-29", + last_updated: "2025-07-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.55, output: 2.19 }, + limit: { context: 131072, output: 131072 }, + }, + "accounts/fireworks/models/kimi-k2p5": { + id: "accounts/fireworks/models/kimi-k2p5", + name: "Kimi K2.5", + family: "kimi-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-01", + release_date: "2026-01-27", + last_updated: "2026-01-27", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 3, cache_read: 0.1 }, + limit: { context: 256000, output: 256000 }, + }, + "accounts/fireworks/models/gpt-oss-20b": { + id: "accounts/fireworks/models/gpt-oss-20b", + name: "GPT OSS 20B", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.05, output: 0.2 }, + limit: { context: 131072, output: 32768 }, + }, + "accounts/fireworks/models/gpt-oss-120b": { + id: "accounts/fireworks/models/gpt-oss-120b", + name: "GPT OSS 120B", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 131072, output: 32768 }, + }, + "accounts/fireworks/models/kimi-k2-thinking": { + id: "accounts/fireworks/models/kimi-k2-thinking", + name: "Kimi K2 Thinking", + family: "kimi-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2025-11-06", + last_updated: "2025-11-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.5, cache_read: 0.3 }, + limit: { context: 256000, output: 256000 }, + }, + "accounts/fireworks/routers/kimi-k2p5-turbo": { + id: "accounts/fireworks/routers/kimi-k2p5-turbo", + name: "Kimi K2.5 Turbo", + family: "kimi-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-01", + release_date: "2026-01-27", + last_updated: "2026-01-27", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0 }, + limit: { context: 256000, output: 256000 }, + }, + "accounts/fireworks/models/deepseek-v4-pro": { + id: "accounts/fireworks/models/deepseek-v4-pro", + name: "DeepSeek V4 Pro", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-05", + release_date: "2026-04-24", + last_updated: "2026-04-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.74, output: 3.48, cache_read: 0.15 }, + limit: { context: 1000000, output: 384000 }, + }, + }, + }, + "kimi-for-coding": { + id: "kimi-for-coding", + env: ["KIMI_API_KEY"], + npm: "@ai-sdk/anthropic", + api: "https://api.kimi.com/coding/v1", + name: "Kimi For Coding", + doc: "https://www.kimi.com/coding/docs/en/third-party-agents.html", + models: { + k2p6: { + id: "k2p6", + name: "Kimi K2.6", + family: "kimi-thinking", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-04", + last_updated: "2026-04", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 262144, output: 32768 }, + }, + k2p5: { + id: "k2p5", + name: "Kimi K2.5", + family: "kimi-thinking", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 262144, output: 32768 }, + }, + "kimi-k2-thinking": { + id: "kimi-k2-thinking", + name: "Kimi K2 Thinking", + family: "kimi-thinking", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-11", + last_updated: "2025-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 262144, output: 32768 }, + }, + }, + }, + moark: { + id: "moark", + env: ["MOARK_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://moark.com/v1", + name: "Moark", + doc: "https://moark.com/docs/openapi/v1#tag/%E6%96%87%E6%9C%AC%E7%94%9F%E6%88%90", + models: { + "GLM-4.7": { + id: "GLM-4.7", + name: "GLM-4.7", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-04", + release_date: "2025-12-22", + last_updated: "2025-12-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 3.5, output: 14 }, + limit: { context: 204800, output: 131072 }, + }, + "MiniMax-M2.1": { + id: "MiniMax-M2.1", + name: "MiniMax-M2.1", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-12-23", + last_updated: "2025-12-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 2.1, output: 8.4 }, + limit: { context: 204800, output: 131072 }, + }, + }, + }, + "opencode-go": { + id: "opencode-go", + env: ["OPENCODE_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://opencode.ai/zen/go/v1", + name: "OpenCode Go", + doc: "https://opencode.ai/docs/zen", + models: { + "minimax-m2.7": { + id: "minimax-m2.7", + name: "MiniMax M2.7", + family: "minimax-m2.7", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2, cache_read: 0.06 }, + limit: { context: 204800, output: 131072 }, + provider: { npm: "@ai-sdk/anthropic" }, + }, + "kimi-k2.5": { + id: "kimi-k2.5", + name: "Kimi K2.5", + family: "kimi-k2.5", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-10", + release_date: "2026-01-27", + last_updated: "2026-01-27", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 3, cache_read: 0.1 }, + limit: { context: 262144, output: 65536 }, + }, + "mimo-v2.5-pro": { + id: "mimo-v2.5-pro", + name: "MiMo V2.5 Pro", + family: "mimo-v2.5-pro", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12", + release_date: "2026-04-22", + last_updated: "2026-04-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 3, cache_read: 0.2, context_over_200k: { input: 2, output: 6, cache_read: 0.4 } }, + limit: { context: 1048576, output: 128000 }, + }, + "glm-5": { + id: "glm-5", + name: "GLM-5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-04", + release_date: "2026-02-11", + last_updated: "2026-02-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 3.2, cache_read: 0.2 }, + limit: { context: 202752, output: 32768 }, + }, + "mimo-v2-omni": { + id: "mimo-v2-omni", + name: "MiMo V2 Omni", + family: "mimo-v2-omni", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12", + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text", "image", "audio", "pdf"], output: ["text"] }, + open_weights: true, + cost: { input: 0.4, output: 2, cache_read: 0.08 }, + limit: { context: 262144, output: 128000 }, + status: "deprecated", + }, + "mimo-v2.5": { + id: "mimo-v2.5", + name: "MiMo V2.5", + family: "mimo-v2.5", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12", + release_date: "2026-04-22", + last_updated: "2026-04-22", + modalities: { input: ["text", "image", "audio", "video"], output: ["text"] }, + open_weights: true, + cost: { + input: 0.4, + output: 2, + cache_read: 0.08, + context_over_200k: { input: 0.8, output: 4, cache_read: 0.16 }, + }, + limit: { context: 1000000, output: 128000 }, + }, + "qwen3.6-plus": { + id: "qwen3.6-plus", + name: "Qwen3.6 Plus", + family: "qwen3.6", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-04-02", + last_updated: "2026-04-02", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 3, cache_read: 0.05, cache_write: 0.625 }, + limit: { context: 262144, output: 65536 }, + provider: { npm: "@ai-sdk/anthropic" }, + }, + "glm-5.1": { + id: "glm-5.1", + name: "GLM-5.1", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-04", + release_date: "2026-04-07", + last_updated: "2026-04-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.4, output: 4.4, cache_read: 0.26 }, + limit: { context: 202752, output: 32768 }, + }, + "deepseek-v4-flash": { + id: "deepseek-v4-flash", + name: "DeepSeek V4 Flash", + family: "deepseek-flash", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-05", + release_date: "2026-04-24", + last_updated: "2026-04-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.14, output: 0.28, cache_read: 0.0028 }, + limit: { context: 1000000, output: 384000 }, + }, + "kimi-k2.6": { + id: "kimi-k2.6", + name: "Kimi K2.6", + family: "kimi-k2.6", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-10", + release_date: "2026-04-21", + last_updated: "2026-04-21", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.95, output: 4, cache_read: 0.16 }, + limit: { context: 262144, output: 65536 }, + }, + "deepseek-v4-pro": { + id: "deepseek-v4-pro", + name: "DeepSeek V4 Pro", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-05", + release_date: "2026-04-24", + last_updated: "2026-04-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.74, output: 3.48, cache_read: 0.0145 }, + limit: { context: 1000000, output: 384000 }, + }, + "minimax-m2.5": { + id: "minimax-m2.5", + name: "MiniMax M2.5", + family: "minimax-m2.5", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-01", + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2, cache_read: 0.03 }, + limit: { context: 204800, output: 65536 }, + }, + "mimo-v2-pro": { + id: "mimo-v2-pro", + name: "MiMo V2 Pro", + family: "mimo-v2-pro", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12", + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 3, cache_read: 0.2, context_over_200k: { input: 2, output: 6, cache_read: 0.4 } }, + limit: { context: 1048576, output: 128000 }, + status: "deprecated", + }, + "qwen3.5-plus": { + id: "qwen3.5-plus", + name: "Qwen3.5 Plus", + family: "qwen3.5", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-02-16", + last_updated: "2026-02-16", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 1.2, cache_read: 0.02, cache_write: 0.25 }, + limit: { context: 262144, output: 65536 }, + provider: { npm: "@ai-sdk/anthropic" }, + }, + }, + }, + "io-net": { + id: "io-net", + env: ["IOINTELLIGENCE_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.intelligence.io.solutions/api/v1", + name: "IO.NET", + doc: "https://io.net/docs/guides/intelligence/io-intelligence", + models: { + "Intel/Qwen3-Coder-480B-A35B-Instruct-int4-mixed-ar": { + id: "Intel/Qwen3-Coder-480B-A35B-Instruct-int4-mixed-ar", + name: "Qwen 3 Coder 480B", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-12", + release_date: "2025-01-15", + last_updated: "2025-01-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.22, output: 0.95, cache_read: 0.11, cache_write: 0.44 }, + limit: { context: 106000, output: 4096 }, + }, + "Qwen/Qwen3-Next-80B-A3B-Instruct": { + id: "Qwen/Qwen3-Next-80B-A3B-Instruct", + name: "Qwen 3 Next 80B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-12", + release_date: "2025-01-10", + last_updated: "2025-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.8, cache_read: 0.05, cache_write: 0.2 }, + limit: { context: 262144, output: 4096 }, + }, + "Qwen/Qwen3-235B-A22B-Thinking-2507": { + id: "Qwen/Qwen3-235B-A22B-Thinking-2507", + name: "Qwen 3 235B Thinking", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-12", + release_date: "2025-07-01", + last_updated: "2025-07-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.11, output: 0.6, cache_read: 0.055, cache_write: 0.22 }, + limit: { context: 262144, output: 4096 }, + }, + "Qwen/Qwen2.5-VL-32B-Instruct": { + id: "Qwen/Qwen2.5-VL-32B-Instruct", + name: "Qwen 2.5 VL 32B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-09", + release_date: "2024-11-01", + last_updated: "2024-11-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.05, output: 0.22, cache_read: 0.025, cache_write: 0.1 }, + limit: { context: 32000, output: 4096 }, + }, + "zai-org/GLM-4.6": { + id: "zai-org/GLM-4.6", + name: "GLM 4.6", + family: "glm", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2024-11-15", + last_updated: "2024-11-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 1.75, cache_read: 0.2, cache_write: 0.8 }, + limit: { context: 200000, output: 4096 }, + }, + "mistralai/Magistral-Small-2506": { + id: "mistralai/Magistral-Small-2506", + name: "Magistral Small 2506", + family: "magistral-small", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-06-01", + last_updated: "2025-06-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 1.5, cache_read: 0.25, cache_write: 1 }, + limit: { context: 128000, output: 4096 }, + }, + "mistralai/Mistral-Large-Instruct-2411": { + id: "mistralai/Mistral-Large-Instruct-2411", + name: "Mistral Large Instruct 2411", + family: "mistral-large", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2024-11-01", + last_updated: "2024-11-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 6, cache_read: 1, cache_write: 4 }, + limit: { context: 128000, output: 4096 }, + }, + "mistralai/Mistral-Nemo-Instruct-2407": { + id: "mistralai/Mistral-Nemo-Instruct-2407", + name: "Mistral Nemo Instruct 2407", + family: "mistral-nemo", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-05", + release_date: "2024-07-01", + last_updated: "2024-07-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.02, output: 0.04, cache_read: 0.01, cache_write: 0.04 }, + limit: { context: 128000, output: 4096 }, + }, + "mistralai/Devstral-Small-2505": { + id: "mistralai/Devstral-Small-2505", + name: "Devstral Small 2505", + family: "devstral", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-12", + release_date: "2025-05-01", + last_updated: "2025-05-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.05, output: 0.22, cache_read: 0.025, cache_write: 0.1 }, + limit: { context: 128000, output: 4096 }, + }, + "meta-llama/Llama-3.3-70B-Instruct": { + id: "meta-llama/Llama-3.3-70B-Instruct", + name: "Llama 3.3 70B Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.13, output: 0.38, cache_read: 0.065, cache_write: 0.26 }, + limit: { context: 128000, output: 4096 }, + }, + "meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8": { + id: "meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8", + name: "Llama 4 Maverick 17B 128E Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-12", + release_date: "2025-01-15", + last_updated: "2025-01-15", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.6, cache_read: 0.075, cache_write: 0.3 }, + limit: { context: 430000, output: 4096 }, + }, + "meta-llama/Llama-3.2-90B-Vision-Instruct": { + id: "meta-llama/Llama-3.2-90B-Vision-Instruct", + name: "Llama 3.2 90B Vision Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-09-25", + last_updated: "2024-09-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.35, output: 0.4, cache_read: 0.175, cache_write: 0.7 }, + limit: { context: 16000, output: 4096 }, + }, + "deepseek-ai/DeepSeek-R1-0528": { + id: "deepseek-ai/DeepSeek-R1-0528", + name: "DeepSeek R1", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2025-01-20", + last_updated: "2025-05-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 2, output: 8.75, cache_read: 1, cache_write: 4 }, + limit: { context: 128000, output: 4096 }, + }, + "openai/gpt-oss-20b": { + id: "openai/gpt-oss-20b", + name: "GPT-OSS 20B", + family: "gpt-oss", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2024-12-01", + last_updated: "2024-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.03, output: 0.14, cache_read: 0.015, cache_write: 0.06 }, + limit: { context: 64000, output: 4096 }, + }, + "openai/gpt-oss-120b": { + id: "openai/gpt-oss-120b", + name: "GPT-OSS 120B", + family: "gpt-oss", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2024-12-01", + last_updated: "2024-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.04, output: 0.4, cache_read: 0.02, cache_write: 0.08 }, + limit: { context: 131072, output: 4096 }, + }, + "moonshotai/Kimi-K2-Thinking": { + id: "moonshotai/Kimi-K2-Thinking", + name: "Kimi K2 Thinking", + family: "kimi-thinking", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-08", + release_date: "2024-11-01", + last_updated: "2024-11-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.55, output: 2.25, cache_read: 0.275, cache_write: 1.1 }, + limit: { context: 32768, output: 4096 }, + }, + "moonshotai/Kimi-K2-Instruct-0905": { + id: "moonshotai/Kimi-K2-Instruct-0905", + name: "Kimi K2 Instruct", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-08", + release_date: "2024-09-05", + last_updated: "2024-09-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.39, output: 1.9, cache_read: 0.195, cache_write: 0.78 }, + limit: { context: 32768, output: 4096 }, + }, + }, + }, + "alibaba-cn": { + id: "alibaba-cn", + env: ["DASHSCOPE_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://dashscope.aliyuncs.com/compatible-mode/v1", + name: "Alibaba (China)", + doc: "https://www.alibabacloud.com/help/en/model-studio/models", + models: { + "qwen3-235b-a22b": { + id: "qwen3-235b-a22b", + name: "Qwen3 235B-A22B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-04", + last_updated: "2025-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.287, output: 1.147, reasoning: 2.868 }, + limit: { context: 131072, output: 16384 }, + }, + "qwen-plus-character": { + id: "qwen-plus-character", + name: "Qwen Plus Character", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-01", + last_updated: "2024-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.115, output: 0.287 }, + limit: { context: 32768, output: 4096 }, + }, + "qwen2-5-math-7b-instruct": { + id: "qwen2-5-math-7b-instruct", + name: "Qwen2.5-Math 7B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-09", + last_updated: "2024-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.144, output: 0.287 }, + limit: { context: 4096, output: 3072 }, + }, + "kimi-k2.5": { + id: "kimi-k2.5", + name: "Moonshot Kimi K2.5", + family: "kimi", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: false, + temperature: true, + knowledge: "2025-01", + release_date: "2026-01-27", + last_updated: "2026-01-27", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.574, output: 2.411 }, + limit: { context: 262144, output: 32768 }, + }, + "qwen-doc-turbo": { + id: "qwen-doc-turbo", + name: "Qwen Doc Turbo", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-01", + last_updated: "2024-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.087, output: 0.144 }, + limit: { context: 131072, output: 8192 }, + }, + "qwen-vl-ocr": { + id: "qwen-vl-ocr", + name: "Qwen-VL OCR", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-04", + release_date: "2024-10-28", + last_updated: "2025-04-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.717, output: 0.717 }, + limit: { context: 34096, output: 4096 }, + }, + "qwen-omni-turbo-realtime": { + id: "qwen-omni-turbo-realtime", + name: "Qwen-Omni Turbo Realtime", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-05-08", + last_updated: "2025-05-08", + modalities: { input: ["text", "image", "audio"], output: ["text", "audio"] }, + open_weights: false, + cost: { input: 0.23, output: 0.918, input_audio: 3.584, output_audio: 7.168 }, + limit: { context: 32768, output: 2048 }, + }, + "qwen3-8b": { + id: "qwen3-8b", + name: "Qwen3 8B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-04", + last_updated: "2025-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.072, output: 0.287, reasoning: 0.717 }, + limit: { context: 131072, output: 8192 }, + }, + "qwen3.5-397b-a17b": { + id: "qwen3.5-397b-a17b", + name: "Qwen3.5 397B-A17B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-02-16", + last_updated: "2026-02-16", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.43, output: 2.58, reasoning: 2.58 }, + limit: { context: 262144, output: 65536 }, + }, + "qwen-math-turbo": { + id: "qwen-math-turbo", + name: "Qwen Math Turbo", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-09-19", + last_updated: "2024-09-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.287, output: 0.861 }, + limit: { context: 4096, output: 3072 }, + }, + "qwq-plus": { + id: "qwq-plus", + name: "QwQ Plus", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-03-05", + last_updated: "2025-03-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.23, output: 0.574 }, + limit: { context: 131072, output: 8192 }, + }, + "qwen-vl-plus": { + id: "qwen-vl-plus", + name: "Qwen-VL Plus", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-01-25", + last_updated: "2025-08-15", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.115, output: 0.287 }, + limit: { context: 131072, output: 8192 }, + }, + "glm-5": { + id: "glm-5", + name: "GLM-5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-02-11", + last_updated: "2026-02-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.86, output: 3.15 }, + limit: { context: 202752, output: 16384 }, + }, + "deepseek-r1-distill-llama-70b": { + id: "deepseek-r1-distill-llama-70b", + name: "DeepSeek R1 Distill Llama 70B", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.287, output: 0.861 }, + limit: { context: 32768, output: 16384 }, + }, + "qwen3-32b": { + id: "qwen3-32b", + name: "Qwen3 32B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-04", + last_updated: "2025-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.287, output: 1.147, reasoning: 2.868 }, + limit: { context: 131072, output: 16384 }, + }, + "MiniMax-M2.5": { + id: "MiniMax-M2.5", + name: "MiniMax-M2.5", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 204800, output: 131072 }, + }, + "qwen-max": { + id: "qwen-max", + name: "Qwen Max", + 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, + cost: { input: 0.345, output: 1.377 }, + limit: { context: 131072, output: 8192 }, + }, + "qwen-plus": { + id: "qwen-plus", + name: "Qwen Plus", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-01-25", + last_updated: "2025-09-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.115, output: 0.287, reasoning: 1.147 }, + limit: { context: 1000000, output: 32768 }, + }, + "qwen-omni-turbo": { + id: "qwen-omni-turbo", + name: "Qwen-Omni Turbo", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-01-19", + last_updated: "2025-03-26", + modalities: { input: ["text", "image", "audio", "video"], output: ["text", "audio"] }, + open_weights: false, + cost: { input: 0.058, output: 0.23, input_audio: 3.584, output_audio: 7.168 }, + limit: { context: 32768, output: 2048 }, + }, + "qwen-flash": { + id: "qwen-flash", + name: "Qwen Flash", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-07-28", + last_updated: "2025-07-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.022, output: 0.216 }, + limit: { context: 1000000, output: 32768 }, + }, + "qwen2-5-vl-7b-instruct": { + id: "qwen2-5-vl-7b-instruct", + name: "Qwen2.5-VL 7B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-09", + last_updated: "2024-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.287, output: 0.717 }, + limit: { context: 131072, output: 8192 }, + }, + "deepseek-r1": { + id: "deepseek-r1", + name: "DeepSeek R1", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.574, output: 2.294 }, + limit: { context: 131072, output: 16384 }, + }, + "qwen3.5-flash": { + id: "qwen3.5-flash", + name: "Qwen3.5 Flash", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-02-23", + last_updated: "2026-02-23", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.172, output: 1.72, reasoning: 1.72 }, + limit: { context: 1000000, output: 65536 }, + }, + "qwen3.6-plus": { + id: "qwen3.6-plus", + name: "Qwen3.6 Plus", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-04-02", + last_updated: "2026-04-02", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.276, output: 1.651, cache_read: 0.028, cache_write: 0.344 }, + limit: { context: 1000000, output: 65536 }, + }, + "qwen3-max": { + id: "qwen3-max", + name: "Qwen3 Max", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-09-23", + last_updated: "2025-09-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.861, output: 3.441 }, + limit: { context: 262144, output: 65536 }, + }, + "glm-5.1": { + id: "glm-5.1", + name: "GLM-5.1", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-04-14", + last_updated: "2026-04-14", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.87, output: 3.48, cache_read: 0.17 }, + limit: { context: 202752, output: 128000 }, + }, + "qwen3-omni-flash": { + id: "qwen3-omni-flash", + name: "Qwen3-Omni Flash", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-09-15", + last_updated: "2025-09-15", + modalities: { input: ["text", "image", "audio", "video"], output: ["text", "audio"] }, + open_weights: false, + cost: { input: 0.058, output: 0.23, input_audio: 3.584, output_audio: 7.168 }, + limit: { context: 65536, output: 16384 }, + }, + "deepseek-v3-1": { + id: "deepseek-v3-1", + name: "DeepSeek V3.1", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.574, output: 1.721 }, + limit: { context: 131072, output: 65536 }, + }, + "qwen2-5-72b-instruct": { + id: "qwen2-5-72b-instruct", + name: "Qwen2.5 72B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-09", + last_updated: "2024-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.574, output: 1.721 }, + limit: { context: 131072, output: 8192 }, + }, + "qwen3-vl-235b-a22b": { + id: "qwen3-vl-235b-a22b", + name: "Qwen3-VL 235B-A22B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-04", + last_updated: "2025-04", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.286705, output: 1.14682, reasoning: 2.867051 }, + limit: { context: 131072, output: 32768 }, + }, + "qwen-math-plus": { + id: "qwen-math-plus", + name: "Qwen Math Plus", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-08-16", + last_updated: "2024-09-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.574, output: 1.721 }, + limit: { context: 4096, output: 3072 }, + }, + "qwen2-5-coder-32b-instruct": { + id: "qwen2-5-coder-32b-instruct", + name: "Qwen2.5-Coder 32B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-11", + last_updated: "2024-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.287, output: 0.861 }, + limit: { context: 131072, output: 8192 }, + }, + "qwen3-asr-flash": { + id: "qwen3-asr-flash", + name: "Qwen3-ASR Flash", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + knowledge: "2024-04", + release_date: "2025-09-08", + last_updated: "2025-09-08", + modalities: { input: ["audio"], output: ["text"] }, + open_weights: false, + cost: { input: 0.032, output: 0.032 }, + limit: { context: 53248, output: 4096 }, + }, + "qwen-deep-research": { + id: "qwen-deep-research", + name: "Qwen Deep Research", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-01", + last_updated: "2024-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 7.742, output: 23.367 }, + limit: { context: 1000000, output: 32768 }, + }, + "qwen3-next-80b-a3b-thinking": { + id: "qwen3-next-80b-a3b-thinking", + name: "Qwen3-Next 80B-A3B (Thinking)", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-09", + last_updated: "2025-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.144, output: 1.434 }, + limit: { context: 131072, output: 32768 }, + }, + "qwen-mt-plus": { + id: "qwen-mt-plus", + name: "Qwen-MT Plus", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-04", + release_date: "2025-01", + last_updated: "2025-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.259, output: 0.775 }, + limit: { context: 16384, output: 8192 }, + }, + "deepseek-r1-distill-qwen-32b": { + id: "deepseek-r1-distill-qwen-32b", + name: "DeepSeek R1 Distill Qwen 32B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.287, output: 0.861 }, + limit: { context: 32768, output: 16384 }, + }, + "qwen-vl-max": { + id: "qwen-vl-max", + name: "Qwen-VL Max", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-04-08", + last_updated: "2025-08-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.23, output: 0.574 }, + limit: { context: 131072, output: 8192 }, + }, + "qwen3-coder-flash": { + id: "qwen3-coder-flash", + name: "Qwen3 Coder Flash", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-28", + last_updated: "2025-07-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.144, output: 0.574 }, + limit: { context: 1000000, output: 65536 }, + }, + "deepseek-r1-distill-qwen-7b": { + id: "deepseek-r1-distill-qwen-7b", + name: "DeepSeek R1 Distill Qwen 7B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.072, output: 0.144 }, + limit: { context: 32768, output: 16384 }, + }, + "qwen2-5-7b-instruct": { + id: "qwen2-5-7b-instruct", + name: "Qwen2.5 7B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-09", + last_updated: "2024-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.072, output: 0.144 }, + limit: { context: 131072, output: 8192 }, + }, + "qwen2-5-14b-instruct": { + id: "qwen2-5-14b-instruct", + name: "Qwen2.5 14B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-09", + last_updated: "2024-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.144, output: 0.431 }, + limit: { context: 131072, output: 8192 }, + }, + "tongyi-intent-detect-v3": { + id: "tongyi-intent-detect-v3", + name: "Tongyi Intent Detect V3", + family: "yi", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-04", + release_date: "2024-01", + last_updated: "2024-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.058, output: 0.144 }, + limit: { context: 8192, output: 1024 }, + }, + "qwq-32b": { + id: "qwq-32b", + name: "QwQ 32B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-12", + last_updated: "2024-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.287, output: 0.861 }, + limit: { context: 131072, output: 8192 }, + }, + "moonshot-kimi-k2-instruct": { + id: "moonshot-kimi-k2-instruct", + name: "Moonshot Kimi K2 Instruct", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.574, output: 2.294 }, + limit: { context: 131072, output: 8192 }, + }, + "qwen2-5-32b-instruct": { + id: "qwen2-5-32b-instruct", + name: "Qwen2.5 32B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-09", + last_updated: "2024-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.287, output: 0.861 }, + limit: { context: 131072, output: 8192 }, + }, + "qwen3-next-80b-a3b-instruct": { + id: "qwen3-next-80b-a3b-instruct", + name: "Qwen3-Next 80B-A3B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-09", + last_updated: "2025-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.144, output: 0.574 }, + limit: { context: 131072, output: 32768 }, + }, + "qwen3-omni-flash-realtime": { + id: "qwen3-omni-flash-realtime", + name: "Qwen3-Omni Flash Realtime", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-09-15", + last_updated: "2025-09-15", + modalities: { input: ["text", "image", "audio"], output: ["text", "audio"] }, + open_weights: false, + cost: { input: 0.23, output: 0.918, input_audio: 3.584, output_audio: 7.168 }, + limit: { context: 65536, output: 16384 }, + }, + "kimi-k2.6": { + id: "kimi-k2.6", + name: "Moonshot Kimi K2.6", + family: "kimi", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: false, + temperature: true, + knowledge: "2025-01", + release_date: "2026-04-21", + last_updated: "2026-04-21", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.929, output: 3.858 }, + limit: { context: 262144, output: 16384 }, + }, + "qwen3-vl-30b-a3b": { + id: "qwen3-vl-30b-a3b", + name: "Qwen3-VL 30B-A3B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-04", + last_updated: "2025-04", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.108, output: 0.431, reasoning: 1.076 }, + limit: { context: 131072, output: 32768 }, + }, + "qwen3-vl-plus": { + id: "qwen3-vl-plus", + name: "Qwen3-VL Plus", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-09-23", + last_updated: "2025-09-23", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.143353, output: 1.433525, reasoning: 4.300576 }, + limit: { context: 262144, output: 32768 }, + }, + "deepseek-v3-2-exp": { + id: "deepseek-v3-2-exp", + name: "DeepSeek V3.2 Exp", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.287, output: 0.431 }, + limit: { context: 131072, output: 65536 }, + }, + "qwen3-coder-480b-a35b-instruct": { + id: "qwen3-coder-480b-a35b-instruct", + name: "Qwen3-Coder 480B-A35B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-04", + last_updated: "2025-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.861, output: 3.441 }, + limit: { context: 262144, output: 65536 }, + }, + "deepseek-r1-distill-qwen-1-5b": { + id: "deepseek-r1-distill-qwen-1-5b", + name: "DeepSeek R1 Distill Qwen 1.5B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 32768, output: 16384 }, + }, + "qwen3-coder-30b-a3b-instruct": { + id: "qwen3-coder-30b-a3b-instruct", + name: "Qwen3-Coder 30B-A3B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-04", + last_updated: "2025-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.216, output: 0.861 }, + limit: { context: 262144, output: 65536 }, + }, + "qwen2-5-coder-7b-instruct": { + id: "qwen2-5-coder-7b-instruct", + name: "Qwen2.5-Coder 7B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-11", + last_updated: "2024-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.144, output: 0.287 }, + limit: { context: 131072, output: 8192 }, + }, + "qwen-turbo": { + id: "qwen-turbo", + name: "Qwen Turbo", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-11-01", + last_updated: "2025-07-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.044, output: 0.087, reasoning: 0.431 }, + limit: { context: 1000000, output: 16384 }, + }, + "qwen-mt-turbo": { + id: "qwen-mt-turbo", + name: "Qwen-MT Turbo", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-04", + release_date: "2025-01", + last_updated: "2025-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.101, output: 0.28 }, + limit: { context: 16384, output: 8192 }, + }, + "qwen2-5-math-72b-instruct": { + id: "qwen2-5-math-72b-instruct", + name: "Qwen2.5-Math 72B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-09", + last_updated: "2024-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.574, output: 1.721 }, + limit: { context: 4096, output: 3072 }, + }, + "qwen3.6-max-preview": { + id: "qwen3.6-max-preview", + name: "Qwen3.6 Max Preview", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-04-20", + last_updated: "2026-04-21", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.32, output: 7.9, cache_read: 0.132 }, + limit: { context: 245800, output: 65536 }, + }, + "qwen2-5-omni-7b": { + id: "qwen2-5-omni-7b", + name: "Qwen2.5-Omni 7B", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-12", + last_updated: "2024-12", + modalities: { input: ["text", "image", "audio", "video"], output: ["text", "audio"] }, + open_weights: true, + cost: { input: 0.087, output: 0.345, input_audio: 5.448 }, + limit: { context: 32768, output: 2048 }, + }, + "qwen3.5-plus": { + id: "qwen3.5-plus", + name: "Qwen3.5 Plus", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-02-16", + last_updated: "2026-02-16", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.573, output: 3.44, reasoning: 3.44 }, + limit: { context: 1000000, output: 65536 }, + }, + "deepseek-r1-distill-qwen-14b": { + id: "deepseek-r1-distill-qwen-14b", + name: "DeepSeek R1 Distill Qwen 14B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.144, output: 0.431 }, + limit: { context: 32768, output: 16384 }, + }, + "qwen2-5-vl-72b-instruct": { + id: "qwen2-5-vl-72b-instruct", + name: "Qwen2.5-VL 72B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-09", + last_updated: "2024-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 2.294, output: 6.881 }, + limit: { context: 131072, output: 8192 }, + }, + "deepseek-v3": { + id: "deepseek-v3", + name: "DeepSeek V3", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-12-01", + last_updated: "2024-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.287, output: 1.147 }, + limit: { context: 65536, output: 8192 }, + }, + "deepseek-r1-0528": { + id: "deepseek-r1-0528", + name: "DeepSeek R1 0528", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-05-28", + last_updated: "2025-05-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.574, output: 2.294 }, + limit: { context: 131072, output: 16384 }, + }, + "qvq-max": { + id: "qvq-max", + name: "QVQ Max", + family: "qvq", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-03-25", + last_updated: "2025-03-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.147, output: 4.588 }, + limit: { context: 131072, output: 8192 }, + }, + "kimi-k2-thinking": { + id: "kimi-k2-thinking", + name: "Moonshot Kimi K2 Thinking", + family: "kimi", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2025-11-06", + last_updated: "2025-11-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.574, output: 2.294 }, + limit: { context: 262144, output: 16384 }, + }, + "qwen3-14b": { + id: "qwen3-14b", + name: "Qwen3 14B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-04", + last_updated: "2025-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.144, output: 0.574, reasoning: 1.434 }, + limit: { context: 131072, output: 8192 }, + }, + "deepseek-r1-distill-llama-8b": { + id: "deepseek-r1-distill-llama-8b", + name: "DeepSeek R1 Distill Llama 8B", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 32768, output: 16384 }, + }, + "qwen-long": { + id: "qwen-long", + name: "Qwen Long", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-01-25", + last_updated: "2025-01-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.072, output: 0.287 }, + limit: { context: 10000000, output: 8192 }, + }, + "kimi/kimi-k2.5": { + id: "kimi/kimi-k2.5", + name: "kimi/kimi-k2.5", + family: "kimi", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: false, + knowledge: "2025-01", + release_date: "2026-01-27", + last_updated: "2026-01-27", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 3, cache_read: 0.1 }, + limit: { context: 262144, output: 262144 }, + }, + "MiniMax/MiniMax-M2.7": { + id: "MiniMax/MiniMax-M2.7", + name: "MiniMax-M2.7", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2, cache_read: 0.06, cache_write: 0.375 }, + limit: { context: 204800, output: 131072 }, + }, + "siliconflow/deepseek-v3-0324": { + id: "siliconflow/deepseek-v3-0324", + name: "siliconflow/deepseek-v3-0324", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-12-26", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 1 }, + limit: { context: 163840, output: 163840 }, + }, + "siliconflow/deepseek-v3.2": { + id: "siliconflow/deepseek-v3.2", + name: "siliconflow/deepseek-v3.2", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-12-03", + last_updated: "2025-12-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.27, output: 0.42 }, + limit: { context: 163840, output: 65536 }, + }, + "siliconflow/deepseek-r1-0528": { + id: "siliconflow/deepseek-r1-0528", + name: "siliconflow/deepseek-r1-0528", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-05-28", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 2.18 }, + limit: { context: 163840, output: 32768 }, + }, + "siliconflow/deepseek-v3.1-terminus": { + id: "siliconflow/deepseek-v3.1-terminus", + name: "siliconflow/deepseek-v3.1-terminus", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-09-29", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.27, output: 1 }, + limit: { context: 163840, output: 65536 }, + }, + "qwen3-coder-plus": { + id: "qwen3-coder-plus", + name: "Qwen3 Coder Plus", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-23", + last_updated: "2025-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 5 }, + limit: { context: 1048576, output: 65536 }, + }, + "deepseek-v4-flash": { + id: "deepseek-v4-flash", + name: "DeepSeek V4 Flash", + family: "deepseek-flash", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-05", + release_date: "2026-04-24", + last_updated: "2026-04-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.14, output: 0.28, cache_read: 0.028 }, + limit: { context: 1000000, output: 384000 }, + }, + "deepseek-v4-pro": { + id: "deepseek-v4-pro", + name: "DeepSeek V4 Pro", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-05", + release_date: "2026-04-24", + last_updated: "2026-04-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.74, output: 3.48, cache_read: 0.145 }, + limit: { context: 1000000, output: 384000 }, + }, + }, + }, + firepass: { + id: "firepass", + env: ["FIREPASS_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.fireworks.ai/inference/v1/", + name: "Fireworks (Firepass)", + doc: "https://docs.fireworks.ai/firepass", + models: { + "accounts/fireworks/routers/kimi-k2p6-turbo": { + id: "accounts/fireworks/routers/kimi-k2p6-turbo", + name: "Kimi K2.6 Turbo", + family: "kimi-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-04-17", + last_updated: "2026-04-17", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0 }, + limit: { context: 262000, output: 262000 }, + }, + }, + }, + "minimax-cn-coding-plan": { + id: "minimax-cn-coding-plan", + env: ["MINIMAX_API_KEY"], + npm: "@ai-sdk/anthropic", + api: "https://api.minimaxi.com/anthropic/v1", + name: "MiniMax Coding Plan (minimaxi.com)", + doc: "https://platform.minimaxi.com/docs/coding-plan/intro", + models: { + "MiniMax-M2": { + id: "MiniMax-M2", + name: "MiniMax-M2", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-10-27", + last_updated: "2025-10-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 196608, output: 128000 }, + }, + "MiniMax-M2.5": { + id: "MiniMax-M2.5", + name: "MiniMax-M2.5", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 204800, output: 131072 }, + }, + "MiniMax-M2.7": { + id: "MiniMax-M2.7", + name: "MiniMax-M2.7", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 204800, output: 131072 }, + }, + "MiniMax-M2.7-highspeed": { + id: "MiniMax-M2.7-highspeed", + name: "MiniMax-M2.7-highspeed", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 204800, output: 131072 }, + }, + "MiniMax-M2.1": { + id: "MiniMax-M2.1", + name: "MiniMax-M2.1", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-12-23", + last_updated: "2025-12-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 204800, output: 131072 }, + }, + "MiniMax-M2.5-highspeed": { + id: "MiniMax-M2.5-highspeed", + name: "MiniMax-M2.5-highspeed", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-13", + last_updated: "2026-02-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 204800, output: 131072 }, + }, + }, + }, + jiekou: { + id: "jiekou", + env: ["JIEKOU_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.jiekou.ai/openai", + name: "Jiekou.AI", + doc: "https://docs.jiekou.ai/docs/support/quickstart?utm_source=github_models.dev", + models: { + "gpt-5.1-codex-max": { + id: "gpt-5.1-codex-max", + name: "gpt-5.1-codex-max", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.125, output: 9 }, + limit: { context: 400000, output: 128000 }, + }, + "grok-4-1-fast-reasoning": { + id: "grok-4-1-fast-reasoning", + name: "grok-4-1-fast-reasoning", + family: "grok", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.18, output: 0.45 }, + limit: { context: 2000000, output: 2000000 }, + }, + "claude-opus-4-5-20251101": { + id: "claude-opus-4-5-20251101", + name: "claude-opus-4-5-20251101", + family: "claude-opus", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 4.5, output: 22.5 }, + limit: { context: 200000, output: 65536 }, + }, + "gemini-2.5-flash-lite-preview-09-2025": { + id: "gemini-2.5-flash-lite-preview-09-2025", + name: "gemini-2.5-flash-lite-preview-09-2025", + family: "gemini-flash-lite", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image", "video", "audio"], output: ["text"] }, + open_weights: false, + cost: { input: 0.09, output: 0.36 }, + limit: { context: 1048576, output: 65536 }, + }, + "gpt-5.2-pro": { + id: "gpt-5.2-pro", + name: "gpt-5.2-pro", + family: "gpt-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 18.9, output: 151.2 }, + limit: { context: 400000, output: 128000 }, + }, + "gemini-3-flash-preview": { + id: "gemini-3-flash-preview", + name: "gemini-3-flash-preview", + family: "gemini-flash", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image", "video", "audio"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 3 }, + limit: { context: 1048576, output: 65536 }, + }, + "gpt-5-mini": { + id: "gpt-5-mini", + name: "gpt-5-mini", + family: "gpt-mini", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.225, output: 1.8 }, + limit: { context: 400000, output: 128000 }, + }, + "gpt-5-nano": { + id: "gpt-5-nano", + name: "gpt-5-nano", + family: "gpt-nano", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.045, output: 0.36 }, + limit: { context: 400000, output: 128000 }, + }, + "gemini-3-pro-preview": { + id: "gemini-3-pro-preview", + name: "gemini-3-pro-preview", + family: "gemini-pro", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image", "video", "audio"], output: ["text"] }, + open_weights: false, + cost: { input: 1.8, output: 10.8 }, + limit: { context: 1048576, output: 65536 }, + }, + "gemini-2.5-flash-preview-05-20": { + id: "gemini-2.5-flash-preview-05-20", + name: "gemini-2.5-flash-preview-05-20", + family: "gemini-flash", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image", "video", "audio"], output: ["text"] }, + open_weights: false, + cost: { input: 0.135, output: 3.15 }, + limit: { context: 1048576, output: 200000 }, + }, + "claude-sonnet-4-5-20250929": { + id: "claude-sonnet-4-5-20250929", + name: "claude-sonnet-4-5-20250929", + family: "claude-sonnet", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2.7, output: 13.5 }, + limit: { context: 200000, output: 64000 }, + }, + "gemini-2.5-pro": { + id: "gemini-2.5-pro", + name: "gemini-2.5-pro", + family: "gemini-pro", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image", "video", "audio"], output: ["text"] }, + open_weights: false, + cost: { input: 1.125, output: 9 }, + limit: { context: 1048576, output: 65535 }, + }, + "grok-4-1-fast-non-reasoning": { + id: "grok-4-1-fast-non-reasoning", + name: "grok-4-1-fast-non-reasoning", + family: "grok", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.18, output: 0.45 }, + limit: { context: 2000000, output: 2000000 }, + }, + "gpt-5.2": { + id: "gpt-5.2", + name: "gpt-5.2", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.575, output: 12.6 }, + limit: { context: 400000, output: 128000 }, + }, + "o4-mini": { + id: "o4-mini", + name: "o4-mini", + family: "o", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 4.4 }, + limit: { context: 200000, output: 100000 }, + }, + "gemini-2.5-pro-preview-06-05": { + id: "gemini-2.5-pro-preview-06-05", + name: "gemini-2.5-pro-preview-06-05", + family: "gemini-pro", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image", "video", "audio"], output: ["text"] }, + open_weights: false, + cost: { input: 1.125, output: 9 }, + limit: { context: 1048576, output: 200000 }, + }, + "gemini-2.5-flash-lite-preview-06-17": { + id: "gemini-2.5-flash-lite-preview-06-17", + name: "gemini-2.5-flash-lite-preview-06-17", + family: "gemini-flash-lite", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "video", "image", "audio"], output: ["text"] }, + open_weights: false, + cost: { input: 0.09, output: 0.36 }, + limit: { context: 1048576, output: 65535 }, + }, + "gpt-5.2-codex": { + id: "gpt-5.2-codex", + name: "gpt-5.2-codex", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14 }, + limit: { context: 400000, output: 128000 }, + }, + "gemini-2.5-flash": { + id: "gemini-2.5-flash", + name: "gemini-2.5-flash", + family: "gemini-flash", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image", "video", "audio"], output: ["text"] }, + open_weights: false, + cost: { input: 0.27, output: 2.25 }, + limit: { context: 1048576, output: 65535 }, + }, + "gpt-5.1-codex-mini": { + id: "gpt-5.1-codex-mini", + name: "gpt-5.1-codex-mini", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.225, output: 1.8 }, + limit: { context: 400000, output: 128000 }, + }, + "grok-code-fast-1": { + id: "grok-code-fast-1", + name: "grok-code-fast-1", + family: "grok", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.18, output: 1.35 }, + limit: { context: 256000, output: 256000 }, + }, + "gpt-5.1": { + id: "gpt-5.1", + name: "gpt-5.1", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-02", + last_updated: "2026-02", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.125, output: 9 }, + limit: { context: 400000, output: 128000 }, + }, + "grok-4-fast-reasoning": { + id: "grok-4-fast-reasoning", + name: "grok-4-fast-reasoning", + family: "grok", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.18, output: 0.45 }, + limit: { context: 2000000, output: 2000000 }, + }, + "o3-mini": { + id: "o3-mini", + name: "o3-mini", + family: "o", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 4.4 }, + limit: { context: 131072, output: 131072 }, + }, + "grok-4-0709": { + id: "grok-4-0709", + name: "grok-4-0709", + family: "grok", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2.7, output: 13.5 }, + limit: { context: 256000, output: 8192 }, + }, + "gpt-5-codex": { + id: "gpt-5-codex", + name: "gpt-5-codex", + family: "gpt-codex", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.125, output: 9 }, + limit: { context: 400000, output: 128000 }, + }, + "claude-opus-4-1-20250805": { + id: "claude-opus-4-1-20250805", + name: "claude-opus-4-1-20250805", + family: "claude-opus", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 13.5, output: 67.5 }, + limit: { context: 200000, output: 32000 }, + }, + "claude-haiku-4-5-20251001": { + id: "claude-haiku-4-5-20251001", + name: "claude-haiku-4-5-20251001", + family: "claude-haiku", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.9, output: 4.5 }, + limit: { context: 20000, output: 64000 }, + }, + "claude-sonnet-4-20250514": { + id: "claude-sonnet-4-20250514", + name: "claude-sonnet-4-20250514", + family: "claude-sonnet", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2.7, output: 13.5 }, + limit: { context: 200000, output: 64000 }, + }, + "claude-opus-4-6": { + id: "claude-opus-4-6", + name: "claude-opus-4-6", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-05-31", + release_date: "2026-02", + last_updated: "2026-02", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25 }, + limit: { context: 1000000, output: 128000 }, + }, + o3: { + id: "o3", + name: "o3", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 10, output: 40 }, + limit: { context: 131072, output: 131072 }, + }, + "gpt-5-pro": { + id: "gpt-5-pro", + name: "gpt-5-pro", + family: "gpt-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 13.5, output: 108 }, + limit: { context: 400000, output: 272000 }, + }, + "gemini-2.5-flash-lite": { + id: "gemini-2.5-flash-lite", + name: "gemini-2.5-flash-lite", + family: "gemini-flash-lite", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image", "video", "audio"], output: ["text"] }, + open_weights: false, + cost: { input: 0.09, output: 0.36 }, + limit: { context: 1048576, output: 65535 }, + }, + "gpt-5-chat-latest": { + id: "gpt-5-chat-latest", + name: "gpt-5-chat-latest", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.125, output: 9 }, + limit: { context: 400000, output: 128000 }, + }, + "claude-opus-4-20250514": { + id: "claude-opus-4-20250514", + name: "claude-opus-4-20250514", + family: "claude-opus", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 13.5, output: 67.5 }, + limit: { context: 200000, output: 32000 }, + }, + "gpt-5.1-codex": { + id: "gpt-5.1-codex", + name: "gpt-5.1-codex", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.125, output: 9 }, + limit: { context: 400000, output: 128000 }, + }, + "grok-4-fast-non-reasoning": { + id: "grok-4-fast-non-reasoning", + name: "grok-4-fast-non-reasoning", + family: "grok", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.18, output: 0.45 }, + limit: { context: 2000000, output: 2000000 }, + }, + "deepseek/deepseek-v3-0324": { + id: "deepseek/deepseek-v3-0324", + name: "DeepSeek V3 0324", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.28, output: 1.14 }, + limit: { context: 163840, output: 163840 }, + }, + "deepseek/deepseek-v3.1": { + id: "deepseek/deepseek-v3.1", + name: "DeepSeek V3.1", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.27, output: 1 }, + limit: { context: 163840, output: 32768 }, + }, + "deepseek/deepseek-r1-0528": { + id: "deepseek/deepseek-r1-0528", + name: "DeepSeek R1 0528", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.7, output: 2.5 }, + limit: { context: 163840, output: 32768 }, + }, + "zai-org/glm-4.7": { + id: "zai-org/glm-4.7", + name: "GLM-4.7", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.2 }, + limit: { context: 204800, output: 131072 }, + }, + "zai-org/glm-4.5": { + id: "zai-org/glm-4.5", + name: "GLM-4.5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.2 }, + limit: { context: 131072, output: 98304 }, + }, + "zai-org/glm-4.5v": { + id: "zai-org/glm-4.5v", + name: "GLM 4.5V", + family: "glmv", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 1.8 }, + limit: { context: 65536, output: 16384 }, + }, + "zai-org/glm-4.7-flash": { + id: "zai-org/glm-4.7-flash", + name: "GLM-4.7-Flash", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.07, output: 0.4 }, + limit: { context: 200000, output: 128000 }, + }, + "minimaxai/minimax-m1-80k": { + id: "minimaxai/minimax-m1-80k", + name: "MiniMax M1", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.55, output: 2.2 }, + limit: { context: 1000000, output: 40000 }, + }, + "xiaomimimo/mimo-v2-flash": { + id: "xiaomimimo/mimo-v2-flash", + name: "XiaomiMiMo/MiMo-V2-Flash", + family: "mimo", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 262144, output: 131072 }, + }, + "baidu/ernie-4.5-vl-424b-a47b": { + id: "baidu/ernie-4.5-vl-424b-a47b", + name: "ERNIE 4.5 VL 424B A47B", + family: "ernie", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.42, output: 1.25 }, + limit: { context: 123000, output: 16000 }, + }, + "baidu/ernie-4.5-300b-a47b-paddle": { + id: "baidu/ernie-4.5-300b-a47b-paddle", + name: "ERNIE 4.5 300B A47B", + family: "ernie", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.28, output: 1.1 }, + limit: { context: 123000, output: 12000 }, + }, + "minimax/minimax-m2.1": { + id: "minimax/minimax-m2.1", + name: "Minimax M2.1", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 204800, output: 131072 }, + }, + "qwen/qwen3-235b-a22b-instruct-2507": { + id: "qwen/qwen3-235b-a22b-instruct-2507", + name: "Qwen3 235B A22B Instruct 2507", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.8 }, + limit: { context: 131072, output: 16384 }, + }, + "qwen/qwen3-32b-fp8": { + id: "qwen/qwen3-32b-fp8", + name: "Qwen3 32B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.45 }, + limit: { context: 40960, output: 20000 }, + }, + "qwen/qwen3-235b-a22b-thinking-2507": { + id: "qwen/qwen3-235b-a22b-thinking-2507", + name: "Qwen3 235B A22b Thinking 2507", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 3 }, + limit: { context: 131072, output: 131072 }, + }, + "qwen/qwen3-next-80b-a3b-thinking": { + id: "qwen/qwen3-next-80b-a3b-thinking", + name: "Qwen3 Next 80B A3B Thinking", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 1.5 }, + limit: { context: 65536, output: 65536 }, + }, + "qwen/qwen3-next-80b-a3b-instruct": { + id: "qwen/qwen3-next-80b-a3b-instruct", + name: "Qwen3 Next 80B A3B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 1.5 }, + limit: { context: 65536, output: 65536 }, + }, + "qwen/qwen3-30b-a3b-fp8": { + id: "qwen/qwen3-30b-a3b-fp8", + name: "Qwen3 30B A3B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.09, output: 0.45 }, + limit: { context: 40960, output: 20000 }, + }, + "qwen/qwen3-coder-next": { + id: "qwen/qwen3-coder-next", + name: "qwen/qwen3-coder-next", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-02", + last_updated: "2026-02", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 1.5 }, + limit: { context: 262144, output: 65536 }, + }, + "qwen/qwen3-coder-480b-a35b-instruct": { + id: "qwen/qwen3-coder-480b-a35b-instruct", + name: "Qwen3 Coder 480B A35B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.29, output: 1.2 }, + limit: { context: 262144, output: 65536 }, + }, + "qwen/qwen3-235b-a22b-fp8": { + id: "qwen/qwen3-235b-a22b-fp8", + name: "Qwen3 235B A22B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.8 }, + limit: { context: 40960, output: 20000 }, + }, + "moonshotai/kimi-k2.5": { + id: "moonshotai/kimi-k2.5", + name: "Kimi K2.5", + family: "kimi", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 3 }, + limit: { context: 262144, output: 262144 }, + }, + "moonshotai/kimi-k2-instruct": { + id: "moonshotai/kimi-k2-instruct", + name: "Kimi K2 Instruct", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.57, output: 2.3 }, + limit: { context: 131072, output: 131072 }, + }, + "moonshotai/kimi-k2-0905": { + id: "moonshotai/kimi-k2-0905", + name: "Kimi K2 0905", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.5 }, + limit: { context: 262144, output: 262144 }, + }, + }, + }, + bailing: { + id: "bailing", + env: ["BAILING_API_TOKEN"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.tbox.cn/api/llm/v1/chat/completions", + name: "Bailing", + doc: "https://alipaytbox.yuque.com/sxs0ba/ling/intro", + models: { + "Ring-1T": { + id: "Ring-1T", + name: "Ring-1T", + family: "ring", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + knowledge: "2024-06", + release_date: "2025-10", + last_updated: "2025-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.57, output: 2.29 }, + limit: { context: 128000, output: 32000 }, + }, + "Ling-1T": { + id: "Ling-1T", + name: "Ling-1T", + family: "ling", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-06", + release_date: "2025-10", + last_updated: "2025-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.57, output: 2.29 }, + limit: { context: 128000, output: 32000 }, + }, + }, + }, + iflowcn: { + id: "iflowcn", + env: ["IFLOW_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://apis.iflow.cn/v1", + name: "iFlow", + doc: "https://platform.iflow.cn/en/docs", + models: { + "qwen3-coder-plus": { + id: "qwen3-coder-plus", + name: "Qwen3-Coder-Plus", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-01", + last_updated: "2025-07-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 256000, output: 64000 }, + }, + "qwen3-32b": { + id: "qwen3-32b", + name: "Qwen3-32B", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2024-12-01", + last_updated: "2024-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 32000 }, + }, + "deepseek-r1": { + id: "deepseek-r1", + name: "DeepSeek-R1", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-12", + release_date: "2025-01-20", + last_updated: "2025-01-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 32000 }, + }, + "qwen3-max": { + id: "qwen3-max", + name: "Qwen3-Max", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-12", + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 256000, output: 32000 }, + }, + "qwen3-235b-a22b-instruct": { + id: "qwen3-235b-a22b-instruct", + name: "Qwen3-235B-A22B-Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-01", + last_updated: "2025-07-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 256000, output: 64000 }, + }, + "qwen3-235b-a22b-thinking-2507": { + id: "qwen3-235b-a22b-thinking-2507", + name: "Qwen3-235B-A22B-Thinking", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-01", + last_updated: "2025-07-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 256000, output: 64000 }, + }, + "kimi-k2-0905": { + id: "kimi-k2-0905", + name: "Kimi-K2-0905", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-12", + release_date: "2025-09-05", + last_updated: "2025-09-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 256000, output: 64000 }, + }, + "glm-4.6": { + id: "glm-4.6", + name: "GLM-4.6", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2024-12-01", + last_updated: "2025-11-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 200000, output: 128000 }, + }, + "qwen3-vl-plus": { + id: "qwen3-vl-plus", + name: "Qwen3-VL-Plus", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-12", + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 256000, output: 32000 }, + }, + "deepseek-v3.2": { + id: "deepseek-v3.2", + name: "DeepSeek-V3.2-Exp", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-12", + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 64000 }, + }, + "qwen3-235b": { + id: "qwen3-235b", + name: "Qwen3-235B-A22B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2024-12-01", + last_updated: "2024-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 32000 }, + }, + "kimi-k2": { + id: "kimi-k2", + name: "Kimi-K2", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2024-12-01", + last_updated: "2024-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 64000 }, + }, + "qwen3-max-preview": { + id: "qwen3-max-preview", + name: "Qwen3-Max-Preview", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-12", + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 256000, output: 32000 }, + }, + "deepseek-v3": { + id: "deepseek-v3", + name: "DeepSeek-V3", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2024-12-26", + last_updated: "2024-12-26", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 32000 }, + }, + }, + }, + v0: { + id: "v0", + env: ["V0_API_KEY"], + npm: "@ai-sdk/vercel", + name: "v0", + doc: "https://sdk.vercel.ai/providers/ai-sdk-providers/vercel", + models: { + "v0-1.5-lg": { + id: "v0-1.5-lg", + name: "v0-1.5-lg", + family: "v0", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-06-09", + last_updated: "2025-06-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75 }, + limit: { context: 512000, output: 32000 }, + }, + "v0-1.0-md": { + id: "v0-1.0-md", + name: "v0-1.0-md", + family: "v0", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15 }, + limit: { context: 128000, output: 32000 }, + }, + "v0-1.5-md": { + id: "v0-1.5-md", + name: "v0-1.5-md", + family: "v0", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-06-09", + last_updated: "2025-06-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15 }, + limit: { context: 128000, output: 32000 }, + }, + }, + }, + huggingface: { + id: "huggingface", + env: ["HF_TOKEN"], + npm: "@ai-sdk/openai-compatible", + api: "https://router.huggingface.co/v1", + name: "Hugging Face", + doc: "https://huggingface.co/docs/inference-providers", + models: { + "Qwen/Qwen3.5-397B-A17B": { + id: "Qwen/Qwen3.5-397B-A17B", + name: "Qwen3.5-397B-A17B", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-04", + release_date: "2026-02-01", + last_updated: "2026-02-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 3.6 }, + limit: { context: 262144, output: 32768 }, + }, + "Qwen/Qwen3-Coder-Next": { + id: "Qwen/Qwen3-Coder-Next", + name: "Qwen3-Coder-Next", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-02-03", + last_updated: "2026-02-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 1.5 }, + limit: { context: 262144, output: 65536 }, + }, + "Qwen/Qwen3-Next-80B-A3B-Instruct": { + id: "Qwen/Qwen3-Next-80B-A3B-Instruct", + name: "Qwen3-Next-80B-A3B-Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-09-11", + last_updated: "2025-09-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.25, output: 1 }, + limit: { context: 262144, output: 66536 }, + }, + "Qwen/Qwen3-Embedding-8B": { + id: "Qwen/Qwen3-Embedding-8B", + name: "Qwen 3 Embedding 8B", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + knowledge: "2024-12", + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.01, output: 0 }, + limit: { context: 32000, output: 4096 }, + }, + "Qwen/Qwen3-235B-A22B-Thinking-2507": { + id: "Qwen/Qwen3-235B-A22B-Thinking-2507", + name: "Qwen3-235B-A22B-Thinking-2507", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-25", + last_updated: "2025-07-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 3 }, + limit: { context: 262144, output: 131072 }, + }, + "Qwen/Qwen3-Next-80B-A3B-Thinking": { + id: "Qwen/Qwen3-Next-80B-A3B-Thinking", + name: "Qwen3-Next-80B-A3B-Thinking", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-09-11", + last_updated: "2025-09-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 2 }, + limit: { context: 262144, output: 131072 }, + }, + "Qwen/Qwen3-Embedding-4B": { + id: "Qwen/Qwen3-Embedding-4B", + name: "Qwen 3 Embedding 4B", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + knowledge: "2024-12", + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.01, output: 0 }, + limit: { context: 32000, output: 2048 }, + }, + "Qwen/Qwen3-Coder-480B-A35B-Instruct": { + id: "Qwen/Qwen3-Coder-480B-A35B-Instruct", + name: "Qwen3-Coder-480B-A35B-Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-23", + last_updated: "2025-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 2, output: 2 }, + limit: { context: 262144, output: 66536 }, + }, + "zai-org/GLM-4.7-Flash": { + id: "zai-org/GLM-4.7-Flash", + name: "GLM-4.7-Flash", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-04", + release_date: "2025-08-08", + last_updated: "2025-08-08", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 200000, output: 128000 }, + }, + "zai-org/GLM-4.7": { + id: "zai-org/GLM-4.7", + name: "GLM-4.7", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-04", + release_date: "2025-12-22", + last_updated: "2025-12-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.2, cache_read: 0.11 }, + limit: { context: 204800, output: 131072 }, + }, + "zai-org/GLM-5.1": { + id: "zai-org/GLM-5.1", + name: "GLM-5.1", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-04-03", + last_updated: "2026-04-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 3.2, cache_read: 0.2 }, + limit: { context: 202752, output: 131072 }, + }, + "zai-org/GLM-5": { + id: "zai-org/GLM-5", + name: "GLM-5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-02-11", + last_updated: "2026-02-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 3.2, cache_read: 0.2 }, + limit: { context: 202752, output: 131072 }, + }, + "XiaomiMiMo/MiMo-V2-Flash": { + id: "XiaomiMiMo/MiMo-V2-Flash", + name: "MiMo-V2-Flash", + family: "mimo", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-12", + release_date: "2025-12-16", + last_updated: "2025-12-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.3 }, + limit: { context: 262144, output: 4096 }, + }, + "deepseek-ai/DeepSeek-R1-0528": { + id: "deepseek-ai/DeepSeek-R1-0528", + name: "DeepSeek-R1-0528", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-05", + release_date: "2025-05-28", + last_updated: "2025-05-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 3, output: 5 }, + limit: { context: 163840, output: 163840 }, + }, + "deepseek-ai/DeepSeek-V3.2": { + id: "deepseek-ai/DeepSeek-V3.2", + name: "DeepSeek-V3.2", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2025-12-01", + last_updated: "2025-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.28, output: 0.4 }, + limit: { context: 163840, output: 65536 }, + }, + "moonshotai/Kimi-K2-Thinking": { + id: "moonshotai/Kimi-K2-Thinking", + name: "Kimi-K2-Thinking", + family: "kimi-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-08", + release_date: "2025-11-06", + last_updated: "2025-11-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.5, cache_read: 0.15 }, + limit: { context: 262144, output: 262144 }, + }, + "moonshotai/Kimi-K2.6": { + id: "moonshotai/Kimi-K2.6", + name: "Kimi-K2.6", + family: "kimi", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-01", + release_date: "2026-04-20", + last_updated: "2026-04-20", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.95, output: 4, cache_read: 0.16 }, + limit: { context: 262144, output: 262144 }, + }, + "moonshotai/Kimi-K2-Instruct": { + id: "moonshotai/Kimi-K2-Instruct", + name: "Kimi-K2-Instruct", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-07-14", + last_updated: "2025-07-14", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 3 }, + limit: { context: 131072, output: 16384 }, + }, + "moonshotai/Kimi-K2-Instruct-0905": { + id: "moonshotai/Kimi-K2-Instruct-0905", + name: "Kimi-K2-Instruct-0905", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-09-04", + last_updated: "2025-09-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 3 }, + limit: { context: 262144, output: 16384 }, + }, + "moonshotai/Kimi-K2.5": { + id: "moonshotai/Kimi-K2.5", + name: "Kimi-K2.5", + family: "kimi", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-01", + release_date: "2026-01-01", + last_updated: "2026-01-01", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 3, cache_read: 0.1 }, + limit: { context: 262144, output: 262144 }, + }, + "MiniMaxAI/MiniMax-M2.5": { + id: "MiniMaxAI/MiniMax-M2.5", + name: "MiniMax-M2.5", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2, cache_read: 0.03 }, + limit: { context: 204800, output: 131072 }, + }, + "MiniMaxAI/MiniMax-M2.7": { + id: "MiniMaxAI/MiniMax-M2.7", + name: "MiniMax-M2.7", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2, cache_read: 0.06 }, + limit: { context: 204800, output: 131072 }, + }, + "MiniMaxAI/MiniMax-M2.1": { + id: "MiniMaxAI/MiniMax-M2.1", + name: "MiniMax-M2.1", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-10", + release_date: "2025-12-23", + last_updated: "2025-12-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 204800, output: 131072 }, + }, + "deepseek-ai/DeepSeek-V4-Pro": { + id: "deepseek-ai/DeepSeek-V4-Pro", + name: "DeepSeek V4 Pro", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-05", + release_date: "2026-04-24", + last_updated: "2026-04-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.74, output: 3.48, cache_read: 0.145 }, + limit: { context: 1048576, output: 393216 }, + }, + }, + }, + zenmux: { + id: "zenmux", + env: ["ZENMUX_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://zenmux.ai/api/v1", + name: "ZenMux", + doc: "https://docs.zenmux.ai", + models: { + "deepseek/deepseek-chat": { + id: "deepseek/deepseek-chat", + name: "DeepSeek-V3.2 (Non-thinking Mode)", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-12-01", + last_updated: "2025-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.28, output: 0.42, cache_read: 0.03 }, + limit: { context: 128000, output: 64000 }, + }, + "deepseek/deepseek-v3.2-exp": { + id: "deepseek/deepseek-v3.2-exp", + name: "DeepSeek-V3.2-Exp", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.22, output: 0.33 }, + limit: { context: 163000, output: 64000 }, + }, + "deepseek/deepseek-v3.2": { + id: "deepseek/deepseek-v3.2", + name: "DeepSeek V3.2", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-12-05", + last_updated: "2025-12-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.28, output: 0.43 }, + limit: { context: 128000, output: 64000 }, + }, + "inclusionai/ring-1t": { + id: "inclusionai/ring-1t", + name: "Ring-1T", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-10-12", + last_updated: "2025-10-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.56, output: 2.24, cache_read: 0.11 }, + limit: { context: 128000, output: 64000 }, + }, + "inclusionai/ling-1t": { + id: "inclusionai/ling-1t", + name: "Ling-1T", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-10-09", + last_updated: "2025-10-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.56, output: 2.24, cache_read: 0.11 }, + limit: { context: 128000, output: 64000 }, + }, + "stepfun/step-3.5-flash-free": { + id: "stepfun/step-3.5-flash-free", + name: "Step 3.5 Flash (Free)", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2026-02-02", + last_updated: "2026-02-02", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 256000, output: 64000 }, + }, + "stepfun/step-3.5-flash": { + id: "stepfun/step-3.5-flash", + name: "Step 3.5 Flash", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2026-02-02", + last_updated: "2026-02-02", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.3 }, + limit: { context: 256000, output: 64000 }, + }, + "stepfun/step-3": { + id: "stepfun/step-3", + name: "Step-3", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-07-31", + last_updated: "2025-07-31", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.21, output: 0.57 }, + limit: { context: 65536, output: 64000 }, + }, + "kuaishou/kat-coder-pro-v2": { + id: "kuaishou/kat-coder-pro-v2", + name: "KAT-Coder-Pro-V2", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2026-03-30", + last_updated: "2026-03-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 1.2, cache_read: 0.06 }, + limit: { context: 256000, output: 80000 }, + }, + "x-ai/grok-4-fast": { + id: "x-ai/grok-4-fast", + name: "Grok 4 Fast", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-09-19", + last_updated: "2025-09-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5, cache_read: 0.05 }, + limit: { context: 2000000, output: 64000 }, + }, + "x-ai/grok-code-fast-1": { + id: "x-ai/grok-code-fast-1", + name: "Grok Code Fast 1", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-08-26", + last_updated: "2025-08-26", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 1.5, cache_read: 0.02 }, + limit: { context: 256000, output: 64000 }, + }, + "x-ai/grok-4.1-fast-non-reasoning": { + id: "x-ai/grok-4.1-fast-non-reasoning", + name: "Grok 4.1 Fast Non Reasoning", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-11-20", + last_updated: "2025-11-20", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5, cache_read: 0.05 }, + limit: { context: 2000000, output: 64000 }, + }, + "x-ai/grok-4": { + id: "x-ai/grok-4", + name: "Grok 4", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-07-09", + last_updated: "2025-07-09", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.75 }, + limit: { context: 256000, output: 64000 }, + }, + "x-ai/grok-4.1-fast": { + id: "x-ai/grok-4.1-fast", + name: "Grok 4.1 Fast", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-11-20", + last_updated: "2025-11-20", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5, cache_read: 0.05 }, + limit: { context: 2000000, output: 64000 }, + }, + "x-ai/grok-4.2-fast": { + id: "x-ai/grok-4.2-fast", + name: "Grok 4.2 Fast", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-08-31", + release_date: "2026-03-20", + last_updated: "2026-03-20", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 9 }, + limit: { context: 2000000, output: 30000 }, + }, + "x-ai/grok-4.2-fast-non-reasoning": { + id: "x-ai/grok-4.2-fast-non-reasoning", + name: "Grok 4.2 Fast Non Reasoning", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-08-31", + release_date: "2026-03-20", + last_updated: "2026-03-20", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 9 }, + limit: { context: 2000000, output: 30000 }, + }, + "openai/gpt-5.3-chat": { + id: "openai/gpt-5.3-chat", + name: "GPT-5.3 Chat", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-08-31", + release_date: "2026-03-20", + last_updated: "2026-03-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14 }, + limit: { context: 128000, output: 16380 }, + provider: { npm: "@ai-sdk/openai", api: "https://zenmux.ai/api/v1" }, + }, + "openai/gpt-5.2-pro": { + id: "openai/gpt-5.2-pro", + name: "GPT-5.2-Pro", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2025-12-11", + last_updated: "2025-12-11", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 21, output: 168 }, + limit: { context: 400000, output: 128000 }, + provider: { npm: "@ai-sdk/openai", api: "https://zenmux.ai/api/v1" }, + }, + "openai/gpt-5.3-codex": { + id: "openai/gpt-5.3-codex", + name: "GPT-5.3 Codex", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-08-31", + release_date: "2026-03-20", + last_updated: "2026-03-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14 }, + limit: { context: 400000, output: 128000 }, + provider: { npm: "@ai-sdk/openai", api: "https://zenmux.ai/api/v1" }, + }, + "openai/gpt-5.2": { + id: "openai/gpt-5.2", + name: "GPT-5.2", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2025-01-01", + release_date: "2025-12-11", + last_updated: "2025-12-11", + modalities: { input: ["image", "text", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.17 }, + limit: { context: 400000, output: 64000 }, + provider: { npm: "@ai-sdk/openai", api: "https://zenmux.ai/api/v1" }, + }, + "openai/gpt-5.4-mini": { + id: "openai/gpt-5.4-mini", + name: "GPT-5.4 Mini", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-08-31", + release_date: "2026-03-20", + last_updated: "2026-03-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.75, output: 4.5 }, + limit: { context: 400000, output: 128000 }, + provider: { npm: "@ai-sdk/openai", api: "https://zenmux.ai/api/v1" }, + }, + "openai/gpt-5.1-chat": { + id: "openai/gpt-5.1-chat", + name: "GPT-5.1 Chat", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["pdf", "image", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.12 }, + limit: { context: 128000, output: 64000 }, + provider: { npm: "@ai-sdk/openai", api: "https://zenmux.ai/api/v1" }, + }, + "openai/gpt-5.4-nano": { + id: "openai/gpt-5.4-nano", + name: "GPT-5.4 Nano", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-08-31", + release_date: "2026-03-20", + last_updated: "2026-03-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 1.25 }, + limit: { context: 400000, output: 128000 }, + provider: { npm: "@ai-sdk/openai", api: "https://zenmux.ai/api/v1" }, + }, + "openai/gpt-5.2-codex": { + id: "openai/gpt-5.2-codex", + name: "GPT-5.2-Codex", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2025-01-01", + release_date: "2026-01-15", + last_updated: "2026-01-15", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.17 }, + limit: { context: 400000, output: 64000 }, + provider: { npm: "@ai-sdk/openai", api: "https://zenmux.ai/api/v1" }, + }, + "openai/gpt-5.1-codex-mini": { + id: "openai/gpt-5.1-codex-mini", + name: "GPT-5.1-Codex-Mini", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 2, cache_read: 0.03 }, + limit: { context: 400000, output: 64000 }, + provider: { npm: "@ai-sdk/openai", api: "https://zenmux.ai/api/v1" }, + }, + "openai/gpt-5.1": { + id: "openai/gpt-5.1", + name: "GPT-5.1", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["image", "text", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.12 }, + limit: { context: 400000, output: 64000 }, + provider: { npm: "@ai-sdk/openai", api: "https://zenmux.ai/api/v1" }, + }, + "openai/gpt-5.4-pro": { + id: "openai/gpt-5.4-pro", + name: "GPT-5.4 Pro", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-08-31", + release_date: "2026-03-20", + last_updated: "2026-03-20", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 45, output: 225 }, + limit: { context: 1050000, output: 128000 }, + provider: { npm: "@ai-sdk/openai", api: "https://zenmux.ai/api/v1" }, + }, + "openai/gpt-5-codex": { + id: "openai/gpt-5-codex", + name: "GPT-5 Codex", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-09-23", + last_updated: "2025-09-23", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.12 }, + limit: { context: 400000, output: 64000 }, + provider: { npm: "@ai-sdk/openai", api: "https://zenmux.ai/api/v1" }, + }, + "openai/gpt-5.4": { + id: "openai/gpt-5.4", + name: "GPT-5.4", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-08-31", + release_date: "2026-03-20", + last_updated: "2026-03-20", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 3.75, output: 18.75 }, + limit: { context: 1050000, output: 128000 }, + provider: { npm: "@ai-sdk/openai", api: "https://zenmux.ai/api/v1" }, + }, + "openai/gpt-5": { + id: "openai/gpt-5", + name: "GPT-5", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.12 }, + limit: { context: 400000, output: 64000 }, + provider: { npm: "@ai-sdk/openai", api: "https://zenmux.ai/api/v1" }, + }, + "openai/gpt-5.1-codex": { + id: "openai/gpt-5.1-codex", + name: "GPT-5.1-Codex", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.12 }, + limit: { context: 400000, output: 64000 }, + provider: { npm: "@ai-sdk/openai", api: "https://zenmux.ai/api/v1" }, + }, + "z-ai/glm-4.7-flash-free": { + id: "z-ai/glm-4.7-flash-free", + name: "GLM 4.7 Flash (Free)", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-01-01", + release_date: "2026-01-19", + last_updated: "2026-01-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 200000, output: 64000 }, + }, + "z-ai/glm-5v-turbo": { + id: "z-ai/glm-5v-turbo", + name: "GLM 5V Turbo", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-04-01", + last_updated: "2026-04-01", + modalities: { input: ["text", "image", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.726, output: 3.1946, cache_read: 0.1743 }, + limit: { context: 200000, output: 128000 }, + }, + "z-ai/glm-4.7": { + id: "z-ai/glm-4.7", + name: "GLM 4.7", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-12-23", + last_updated: "2025-12-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.28, output: 1.14, cache_read: 0.06 }, + limit: { context: 200000, output: 64000 }, + }, + "z-ai/glm-5": { + id: "z-ai/glm-5", + name: "GLM 5", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-01-01", + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.58, output: 2.6, cache_read: 0.14 }, + limit: { context: 200000, output: 128000 }, + }, + "z-ai/glm-4.7-flashx": { + id: "z-ai/glm-4.7-flashx", + name: "GLM 4.7 FlashX", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-01-01", + release_date: "2026-01-19", + last_updated: "2026-01-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.07, output: 0.42, cache_read: 0.01 }, + limit: { context: 200000, output: 64000 }, + }, + "z-ai/glm-4.6v-flash-free": { + id: "z-ai/glm-4.6v-flash-free", + name: "GLM 4.6V Flash (Free)", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-12-08", + last_updated: "2025-12-08", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 200000, output: 64000 }, + }, + "z-ai/glm-5.1": { + id: "z-ai/glm-5.1", + name: "GLM-5.1", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-04-03", + last_updated: "2026-04-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.8781, output: 3.5126, cache_read: 0.1903 }, + limit: { context: 200000, output: 131072 }, + }, + "z-ai/glm-4.6v-flash": { + id: "z-ai/glm-4.6v-flash", + name: "GLM 4.6V FlashX", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-12-08", + last_updated: "2025-12-08", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.02, output: 0.21, cache_read: 0.0043 }, + limit: { context: 200000, output: 64000 }, + }, + "z-ai/glm-4.5": { + id: "z-ai/glm-4.5", + name: "GLM 4.5", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-07-25", + last_updated: "2025-07-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.35, output: 1.54, cache_read: 0.07 }, + limit: { context: 128000, output: 64000 }, + }, + "z-ai/glm-4.5-air": { + id: "z-ai/glm-4.5-air", + name: "GLM 4.5 Air", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-07-25", + last_updated: "2025-07-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.11, output: 0.56, cache_read: 0.02 }, + limit: { context: 128000, output: 64000 }, + }, + "z-ai/glm-5-turbo": { + id: "z-ai/glm-5-turbo", + name: "GLM 5 Turbo", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2026-03-20", + last_updated: "2026-03-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.88, output: 3.48 }, + limit: { context: 200000, output: 128000 }, + }, + "z-ai/glm-4.6": { + id: "z-ai/glm-4.6", + name: "GLM 4.6", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-09-30", + last_updated: "2025-09-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.35, output: 1.54, cache_read: 0.07 }, + limit: { context: 200000, output: 64000 }, + }, + "z-ai/glm-4.6v": { + id: "z-ai/glm-4.6v", + name: "GLM 4.6V", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-12-08", + last_updated: "2025-12-08", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.14, output: 0.42, cache_read: 0.03 }, + limit: { context: 200000, output: 64000 }, + }, + "volcengine/doubao-seed-2.0-code": { + id: "volcengine/doubao-seed-2.0-code", + name: "Doubao Seed 2.0 Code", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2026-03-20", + last_updated: "2026-03-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.9, output: 4.48 }, + limit: { context: 256000, output: 32000 }, + }, + "volcengine/doubao-seed-code": { + id: "volcengine/doubao-seed-code", + name: "Doubao-Seed-Code", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-11-11", + last_updated: "2025-11-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.17, output: 1.12, cache_read: 0.03 }, + limit: { context: 256000, output: 64000 }, + }, + "volcengine/doubao-seed-2.0-mini": { + id: "volcengine/doubao-seed-2.0-mini", + name: "Doubao-Seed-2.0-mini", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2026-02-14", + release_date: "2026-02-14", + last_updated: "2026-02-14", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.03, output: 0.28, cache_read: 0.01, cache_write: 0.0024 }, + limit: { context: 256000, output: 64000 }, + }, + "volcengine/doubao-seed-2.0-lite": { + id: "volcengine/doubao-seed-2.0-lite", + name: "Doubao-Seed-2.0-lite", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2026-02-14", + release_date: "2026-02-14", + last_updated: "2026-02-14", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.09, output: 0.51, cache_read: 0.02, cache_write: 0.0024 }, + limit: { context: 256000, output: 64000 }, + }, + "volcengine/doubao-seed-1.8": { + id: "volcengine/doubao-seed-1.8", + name: "Doubao-Seed-1.8", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-12-18", + last_updated: "2025-12-18", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.11, output: 0.28, cache_read: 0.02, cache_write: 0.0024 }, + limit: { context: 256000, output: 64000 }, + }, + "volcengine/doubao-seed-2.0-pro": { + id: "volcengine/doubao-seed-2.0-pro", + name: "Doubao-Seed-2.0-pro", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2026-02-14", + release_date: "2026-02-14", + last_updated: "2026-02-14", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.45, output: 2.24, cache_read: 0.09, cache_write: 0.0024 }, + limit: { context: 256000, output: 64000 }, + }, + "baidu/ernie-5.0-thinking-preview": { + id: "baidu/ernie-5.0-thinking-preview", + name: "ERNIE 5.0", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2026-01-22", + last_updated: "2026-01-22", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.84, output: 3.37 }, + limit: { context: 128000, output: 64000 }, + }, + "minimax/minimax-m2.7": { + id: "minimax/minimax-m2.7", + name: "MiniMax M2.7", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2026-03-20", + last_updated: "2026-03-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3055, output: 1.2219 }, + limit: { context: 204800, output: 131070 }, + provider: { npm: "@ai-sdk/anthropic", api: "https://zenmux.ai/api/anthropic/v1" }, + }, + "minimax/minimax-m2.7-highspeed": { + id: "minimax/minimax-m2.7-highspeed", + name: "MiniMax M2.7 highspeed", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2026-03-20", + last_updated: "2026-03-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.611, output: 2.4439 }, + limit: { context: 204800, output: 131070 }, + provider: { npm: "@ai-sdk/anthropic", api: "https://zenmux.ai/api/anthropic/v1" }, + }, + "minimax/minimax-m2": { + id: "minimax/minimax-m2", + name: "MiniMax M2", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-10-27", + last_updated: "2025-10-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 1.2, cache_read: 0.03, cache_write: 0.38 }, + limit: { context: 204000, output: 64000 }, + provider: { npm: "@ai-sdk/anthropic", api: "https://zenmux.ai/api/anthropic/v1" }, + }, + "minimax/minimax-m2.1": { + id: "minimax/minimax-m2.1", + name: "MiniMax M2.1", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-12-22", + last_updated: "2025-12-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 1.2, cache_read: 0.03, cache_write: 0.38 }, + limit: { context: 204000, output: 64000 }, + provider: { npm: "@ai-sdk/anthropic", api: "https://zenmux.ai/api/anthropic/v1" }, + }, + "minimax/minimax-m2.5-lightning": { + id: "minimax/minimax-m2.5-lightning", + name: "MiniMax M2.5 highspeed", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2026-02-13", + last_updated: "2026-02-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.6, output: 4.8, cache_read: 0.06, cache_write: 0.75 }, + limit: { context: 204800, output: 131072 }, + provider: { npm: "@ai-sdk/anthropic", api: "https://zenmux.ai/api/anthropic/v1" }, + }, + "minimax/minimax-m2.5": { + id: "minimax/minimax-m2.5", + name: "MiniMax M2.5", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2026-02-13", + last_updated: "2026-02-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 1.2, cache_read: 0.03, cache_write: 0.375 }, + limit: { context: 204800, output: 131072 }, + provider: { npm: "@ai-sdk/anthropic", api: "https://zenmux.ai/api/anthropic/v1" }, + }, + "qwen/qwen3-coder-plus": { + id: "qwen/qwen3-coder-plus", + name: "Qwen3-Coder-Plus", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-07-23", + last_updated: "2025-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 5, cache_read: 0.1, cache_write: 1.25 }, + limit: { context: 1000000, output: 64000 }, + }, + "qwen/qwen3.5-flash": { + id: "qwen/qwen3.5-flash", + name: "Qwen3.5 Flash", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2026-03-20", + last_updated: "2026-03-20", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4 }, + limit: { context: 1020000, output: 1020000 }, + }, + "qwen/qwen3.6-plus": { + id: "qwen/qwen3.6-plus", + name: "Qwen3.6-Plus", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-30", + last_updated: "2026-03-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { + input: 0.5, + output: 3, + cache_read: 0.05, + cache_write: 0.625, + context_over_200k: { input: 2, output: 6, cache_read: 0.2, cache_write: 2.5 }, + }, + limit: { context: 1000000, output: 64000 }, + }, + "qwen/qwen3-max": { + id: "qwen/qwen3-max", + name: "Qwen3-Max-Thinking", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2026-01-23", + last_updated: "2026-01-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.2, output: 6 }, + limit: { context: 256000, output: 64000 }, + }, + "qwen/qwen3.5-plus": { + id: "qwen/qwen3.5-plus", + name: "Qwen3.5 Plus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2026-03-20", + last_updated: "2026-03-20", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.8, output: 4.8 }, + limit: { context: 1000000, output: 64000 }, + }, + "google/gemini-3.1-flash-lite-preview": { + id: "google/gemini-3.1-flash-lite-preview", + name: "Gemini 3.1 Flash Lite Preview", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-03-20", + last_updated: "2025-03-20", + modalities: { input: ["text", "image", "audio", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 1.5 }, + limit: { context: 1050000, output: 65530 }, + }, + "google/gemini-3.1-pro-preview": { + id: "google/gemini-3.1-pro-preview", + name: "Gemini 3.1 Pro Preview", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2026-02-19", + release_date: "2026-02-19", + last_updated: "2026-02-19", + modalities: { input: ["text", "image", "pdf", "audio", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 12, cache_read: 0.2, cache_write: 4.5 }, + limit: { context: 1048000, output: 64000 }, + }, + "google/gemini-3-flash-preview": { + id: "google/gemini-3-flash-preview", + name: "Gemini 3 Flash Preview", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-12-17", + last_updated: "2025-12-17", + modalities: { input: ["text", "image", "pdf", "audio"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 3, cache_read: 0.05, cache_write: 1 }, + limit: { context: 1048000, output: 64000 }, + }, + "google/gemini-2.5-pro": { + id: "google/gemini-2.5-pro", + name: "Gemini 2.5 Pro", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-06-17", + last_updated: "2025-06-17", + modalities: { input: ["pdf", "image", "text", "audio", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.31, cache_write: 4.5 }, + limit: { context: 1048000, output: 64000 }, + }, + "google/gemini-2.5-flash": { + id: "google/gemini-2.5-flash", + name: "Gemini 2.5 Flash", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-06-17", + last_updated: "2025-06-17", + modalities: { input: ["pdf", "image", "text", "audio"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 2.5, cache_read: 0.07, cache_write: 1 }, + limit: { context: 1048000, output: 64000 }, + }, + "google/gemini-2.5-flash-lite": { + id: "google/gemini-2.5-flash-lite", + name: "Gemini 2.5 Flash Lite", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-07-22", + last_updated: "2025-07-22", + modalities: { input: ["pdf", "image", "text", "audio"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4, cache_read: 0.03, cache_write: 1 }, + limit: { context: 1048000, output: 64000 }, + }, + "sapiens-ai/agnes-1.5-lite": { + id: "sapiens-ai/agnes-1.5-lite", + name: "Agnes 1.5 Lite", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2026-03-26", + last_updated: "2026-03-26", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.12, output: 0.6 }, + limit: { context: 256000, output: 256000 }, + }, + "sapiens-ai/agnes-1.5-pro": { + id: "sapiens-ai/agnes-1.5-pro", + name: "Agnes 1.5 Pro", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-21", + last_updated: "2026-03-21", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.16, output: 0.8 }, + limit: { context: 256000, output: 256000 }, + }, + "moonshotai/kimi-k2.5": { + id: "moonshotai/kimi-k2.5", + name: "Kimi K2.5", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: false, + knowledge: "2025-01-01", + release_date: "2026-01-27", + last_updated: "2026-01-27", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.58, output: 3.02, cache_read: 0.1 }, + limit: { context: 262000, output: 64000 }, + }, + "moonshotai/kimi-k2-thinking-turbo": { + id: "moonshotai/kimi-k2-thinking-turbo", + name: "Kimi K2 Thinking Turbo", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-11-06", + last_updated: "2025-11-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.15, output: 8, cache_read: 0.15 }, + limit: { context: 262000, output: 64000 }, + }, + "moonshotai/kimi-k2-0905": { + id: "moonshotai/kimi-k2-0905", + name: "Kimi K2 0905", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-09-04", + last_updated: "2025-09-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.6, output: 2.5, cache_read: 0.15 }, + limit: { context: 262000, output: 64000 }, + }, + "moonshotai/kimi-k2.6": { + id: "moonshotai/kimi-k2.6", + name: "Kimi K2.6", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: false, + knowledge: "2025-01-01", + release_date: "2026-04-20", + last_updated: "2026-04-20", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.95, output: 4, cache_read: 0.16 }, + limit: { context: 262140, output: 262140 }, + }, + "moonshotai/kimi-k2-thinking": { + id: "moonshotai/kimi-k2-thinking", + name: "Kimi K2 Thinking", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-11-06", + last_updated: "2025-11-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.6, output: 2.5, cache_read: 0.15 }, + limit: { context: 262000, output: 64000 }, + }, + "anthropic/claude-opus-4.1": { + id: "anthropic/claude-opus-4.1", + name: "Claude Opus 4.1", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["image", "text", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 64000 }, + provider: { npm: "@ai-sdk/anthropic", api: "https://zenmux.ai/api/anthropic/v1" }, + }, + "anthropic/claude-3.7-sonnet": { + id: "anthropic/claude-3.7-sonnet", + name: "Claude 3.7 Sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-02-24", + last_updated: "2025-02-24", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + provider: { npm: "@ai-sdk/anthropic", api: "https://zenmux.ai/api/anthropic/v1" }, + }, + "anthropic/claude-opus-4.6": { + id: "anthropic/claude-opus-4.6", + name: "Claude Opus 4.6", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-05-31", + release_date: "2026-02-06", + last_updated: "2026-02-06", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 1000000, output: 128000 }, + provider: { npm: "@ai-sdk/anthropic", api: "https://zenmux.ai/api/anthropic/v1" }, + }, + "anthropic/claude-opus-4.7": { + id: "anthropic/claude-opus-4.7", + name: "Claude Opus 4.7", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2026-01-31", + release_date: "2026-04-16", + last_updated: "2026-04-16", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 1000000, output: 128000 }, + provider: { npm: "@ai-sdk/anthropic", api: "https://zenmux.ai/api/anthropic/v1" }, + }, + "anthropic/claude-sonnet-4": { + id: "anthropic/claude-sonnet-4", + name: "Claude Sonnet 4", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["image", "text", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 1000000, output: 64000 }, + provider: { npm: "@ai-sdk/anthropic", api: "https://zenmux.ai/api/anthropic/v1" }, + }, + "anthropic/claude-sonnet-4.5": { + id: "anthropic/claude-sonnet-4.5", + name: "Claude Sonnet 4.5", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 1000000, output: 64000 }, + provider: { npm: "@ai-sdk/anthropic", api: "https://zenmux.ai/api/anthropic/v1" }, + }, + "anthropic/claude-opus-4.5": { + id: "anthropic/claude-opus-4.5", + name: "Claude Opus 4.5", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-11-24", + last_updated: "2025-11-24", + modalities: { input: ["pdf", "image", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 200000, output: 64000 }, + provider: { npm: "@ai-sdk/anthropic", api: "https://zenmux.ai/api/anthropic/v1" }, + }, + "anthropic/claude-opus-4": { + id: "anthropic/claude-opus-4", + name: "Claude Opus 4", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["image", "text", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 32000 }, + provider: { npm: "@ai-sdk/anthropic", api: "https://zenmux.ai/api/anthropic/v1" }, + }, + "anthropic/claude-3.5-haiku": { + id: "anthropic/claude-3.5-haiku", + name: "Claude 3.5 Haiku", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2024-11-04", + last_updated: "2024-11-04", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.8, output: 4, cache_read: 0.08, cache_write: 1 }, + limit: { context: 200000, output: 64000 }, + provider: { npm: "@ai-sdk/anthropic", api: "https://zenmux.ai/api/anthropic/v1" }, + }, + "anthropic/claude-haiku-4.5": { + id: "anthropic/claude-haiku-4.5", + name: "Claude Haiku 4.5", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2025-10-15", + last_updated: "2025-10-15", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 5, cache_read: 0.1, cache_write: 1.25 }, + limit: { context: 200000, output: 64000 }, + provider: { npm: "@ai-sdk/anthropic", api: "https://zenmux.ai/api/anthropic/v1" }, + }, + "anthropic/claude-sonnet-4.6": { + id: "anthropic/claude-sonnet-4.6", + name: "Claude Sonnet 4.6", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-08-31", + release_date: "2026-02-18", + last_updated: "2026-02-18", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 1000000, output: 64000 }, + provider: { npm: "@ai-sdk/anthropic", api: "https://zenmux.ai/api/anthropic/v1" }, + }, + "deepseek/deepseek-v4-flash": { + id: "deepseek/deepseek-v4-flash", + name: "DeepSeek V4 Flash", + family: "deepseek-flash", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-05", + release_date: "2026-04-24", + last_updated: "2026-04-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.14, output: 0.28, cache_read: 0.028 }, + limit: { context: 1000000, output: 384000 }, + }, + "deepseek/deepseek-v4-pro": { + id: "deepseek/deepseek-v4-pro", + name: "DeepSeek V4 Pro", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-05", + release_date: "2026-04-24", + last_updated: "2026-04-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.74, output: 3.48, cache_read: 0.145 }, + limit: { context: 1000000, output: 384000 }, + }, + "tencent/hy3-preview": { + id: "tencent/hy3-preview", + name: "Hy3 preview", + family: "Hy", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-20", + last_updated: "2026-04-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.172, output: 0.572, cache_read: 0.058, cache_write: 0 }, + limit: { context: 256000, output: 64000 }, + }, + "openai/gpt-5.5": { + id: "openai/gpt-5.5", + name: "GPT-5.5", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-12-01", + release_date: "2026-04-23", + last_updated: "2026-04-23", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 30, cache_read: 0.5, context_over_200k: { input: 10, output: 45, cache_read: 1 } }, + limit: { context: 1050000, input: 922000, output: 128000 }, + experimental: { + modes: { + fast: { + cost: { input: 12.5, output: 75, cache_read: 1.25 }, + provider: { body: { service_tier: "priority" } }, + }, + }, + }, + }, + "openai/gpt-5.5-pro": { + id: "openai/gpt-5.5-pro", + name: "GPT-5.5 Pro", + family: "gpt-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-12-01", + release_date: "2026-04-23", + last_updated: "2026-04-23", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 30, output: 180, context_over_200k: { input: 60, output: 270 } }, + limit: { context: 1050000, input: 922000, output: 128000 }, + }, + "xiaomi/mimo-v2.5-pro": { + id: "xiaomi/mimo-v2.5-pro", + name: "MiMo-V2.5-Pro", + family: "mimo", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12", + release_date: "2026-04-22", + last_updated: "2026-04-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 3, cache_read: 0.2, context_over_200k: { input: 2, output: 6, cache_read: 0.4 } }, + limit: { context: 1048576, output: 131072 }, + }, + "xiaomi/mimo-v2-omni": { + id: "xiaomi/mimo-v2-omni", + name: "MiMo V2 Omni", + family: "mimo", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-12", + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 2, cache_read: 0.08 }, + limit: { context: 265000, output: 265000 }, + }, + "xiaomi/mimo-v2.5": { + id: "xiaomi/mimo-v2.5", + name: "MiMo-V2.5", + family: "mimo", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12", + release_date: "2026-04-22", + last_updated: "2026-04-22", + modalities: { input: ["text", "image", "audio", "video"], output: ["text"] }, + open_weights: true, + cost: { + input: 0.4, + output: 2, + cache_read: 0.08, + context_over_200k: { input: 0.8, output: 4, cache_read: 0.16 }, + }, + limit: { context: 1048576, output: 131072 }, + }, + "xiaomi/mimo-v2-pro": { + id: "xiaomi/mimo-v2-pro", + name: "MiMo V2 Pro", + family: "mimo", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-12", + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 3, cache_read: 0.2, context_over_200k: { input: 2, output: 6, cache_read: 0.4 } }, + limit: { context: 1000000, output: 256000 }, + }, + "xiaomi/mimo-v2-flash": { + id: "xiaomi/mimo-v2-flash", + name: "MiMo-V2-Flash", + family: "mimo", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-12-01", + release_date: "2025-12-16", + last_updated: "2026-02-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.3, cache_read: 0.01 }, + limit: { context: 262144, output: 65536 }, + }, + }, + }, + upstage: { + id: "upstage", + env: ["UPSTAGE_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.upstage.ai/v1/solar", + name: "Upstage", + doc: "https://developers.upstage.ai/docs/apis/chat", + models: { + "solar-pro2": { + id: "solar-pro2", + name: "solar-pro2", + family: "solar-pro", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03", + release_date: "2025-05-20", + last_updated: "2025-05-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 0.25 }, + limit: { context: 65536, output: 8192 }, + }, + "solar-mini": { + id: "solar-mini", + name: "solar-mini", + family: "solar-mini", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-09", + release_date: "2024-06-12", + last_updated: "2025-04-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.15 }, + limit: { context: 32768, output: 4096 }, + }, + "solar-pro3": { + id: "solar-pro3", + name: "solar-pro3", + family: "solar-pro", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03", + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 0.25 }, + limit: { context: 131072, output: 8192 }, + }, + }, + }, + "novita-ai": { + id: "novita-ai", + env: ["NOVITA_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.novita.ai/openai", + name: "NovitaAI", + doc: "https://novita.ai/docs/guides/introduction", + models: { + "deepseek/deepseek-r1-turbo": { + id: "deepseek/deepseek-r1-turbo", + name: "DeepSeek R1 (Turbo)\t", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-03-05", + last_updated: "2025-03-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.7, output: 2.5 }, + limit: { context: 64000, output: 16000 }, + }, + "deepseek/deepseek-v3-0324": { + id: "deepseek/deepseek-v3-0324", + name: "DeepSeek V3 0324", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-07", + release_date: "2025-03-25", + last_updated: "2025-03-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.27, output: 1.12, cache_read: 0.135 }, + limit: { context: 163840, output: 163840 }, + }, + "deepseek/deepseek-ocr-2": { + id: "deepseek/deepseek-ocr-2", + name: "deepseek/deepseek-ocr-2", + attachment: true, + reasoning: false, + tool_call: false, + release_date: "2026-01-27", + last_updated: "2026-01-27", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.03, output: 0.03 }, + limit: { context: 8192, output: 8192 }, + }, + "deepseek/deepseek-ocr": { + id: "deepseek/deepseek-ocr", + name: "DeepSeek-OCR", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: true, + temperature: true, + release_date: "2025-10-24", + last_updated: "2025-10-24", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.03, output: 0.03 }, + limit: { context: 8192, output: 8192 }, + }, + "deepseek/deepseek-r1-distill-llama-70b": { + id: "deepseek/deepseek-r1-distill-llama-70b", + name: "DeepSeek R1 Distill LLama 70B", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: true, + temperature: true, + release_date: "2025-01-27", + last_updated: "2025-01-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.8, output: 0.8 }, + limit: { context: 8192, output: 8192 }, + }, + "deepseek/deepseek-prover-v2-671b": { + id: "deepseek/deepseek-prover-v2-671b", + name: "Deepseek Prover V2 671B", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-04-30", + last_updated: "2025-04-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.7, output: 2.5 }, + limit: { context: 160000, output: 160000 }, + }, + "deepseek/deepseek-r1-0528-qwen3-8b": { + id: "deepseek/deepseek-r1-0528-qwen3-8b", + name: "DeepSeek R1 0528 Qwen3 8B", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2025-05-29", + last_updated: "2025-05-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.06, output: 0.09 }, + limit: { context: 128000, output: 32000 }, + }, + "deepseek/deepseek-r1-distill-qwen-32b": { + id: "deepseek/deepseek-r1-distill-qwen-32b", + name: "DeepSeek R1 Distill Qwen 32B", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: true, + temperature: true, + release_date: "2025-01-20", + last_updated: "2025-01-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 0.3 }, + limit: { context: 64000, output: 32000 }, + }, + "deepseek/deepseek-v3.2-exp": { + id: "deepseek/deepseek-v3.2-exp", + name: "Deepseek V3.2 Exp", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.27, output: 0.41 }, + limit: { context: 163840, output: 65536 }, + }, + "deepseek/deepseek-v3.1": { + id: "deepseek/deepseek-v3.1", + name: "DeepSeek V3.1", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-08-21", + last_updated: "2025-08-21", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.27, output: 1, cache_read: 0.135 }, + limit: { context: 131072, output: 32768 }, + }, + "deepseek/deepseek-v3.2": { + id: "deepseek/deepseek-v3.2", + name: "Deepseek V3.2", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2025-12-01", + last_updated: "2025-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.269, output: 0.4, cache_read: 0.1345 }, + limit: { context: 163840, output: 65536 }, + }, + "deepseek/deepseek-v3-turbo": { + id: "deepseek/deepseek-v3-turbo", + name: "DeepSeek V3 (Turbo)\t", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-03-05", + last_updated: "2025-03-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.4, output: 1.3 }, + limit: { context: 64000, output: 16000 }, + }, + "deepseek/deepseek-r1-distill-qwen-14b": { + id: "deepseek/deepseek-r1-distill-qwen-14b", + name: "DeepSeek R1 Distill Qwen 14B", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: true, + temperature: true, + release_date: "2025-01-20", + last_updated: "2025-01-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.15 }, + limit: { context: 32768, output: 16384 }, + }, + "deepseek/deepseek-r1-0528": { + id: "deepseek/deepseek-r1-0528", + name: "DeepSeek R1 0528", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-07", + release_date: "2025-05-28", + last_updated: "2025-05-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.7, output: 2.5, cache_read: 0.35 }, + limit: { context: 163840, output: 32768 }, + }, + "deepseek/deepseek-v3.1-terminus": { + id: "deepseek/deepseek-v3.1-terminus", + name: "Deepseek V3.1 Terminus", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-09-22", + last_updated: "2025-09-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.27, output: 1, cache_read: 0.135 }, + limit: { context: 131072, output: 32768 }, + }, + "inclusionai/ling-2.6-1t": { + id: "inclusionai/ling-2.6-1t", + name: "Ling-2.6-1T", + family: "ling", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-04-23", + last_updated: "2026-04-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 262144, output: 32768 }, + }, + "paddlepaddle/paddleocr-vl": { + id: "paddlepaddle/paddleocr-vl", + name: "PaddleOCR-VL", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-10-22", + last_updated: "2025-10-22", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.02, output: 0.02 }, + limit: { context: 16384, output: 16384 }, + }, + "nousresearch/hermes-2-pro-llama-3-8b": { + id: "nousresearch/hermes-2-pro-llama-3-8b", + name: "Hermes 2 Pro Llama 3 8B", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: true, + temperature: true, + release_date: "2024-06-27", + last_updated: "2024-06-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.14, output: 0.14 }, + limit: { context: 8192, output: 8192 }, + }, + "zai-org/glm-4.7": { + id: "zai-org/glm-4.7", + name: "GLM-4.7", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2025-12-22", + last_updated: "2025-12-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.2, cache_read: 0.11 }, + limit: { context: 204800, output: 131072 }, + }, + "zai-org/glm-5": { + id: "zai-org/glm-5", + name: "GLM-5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-02-11", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 3.2, cache_read: 0.2 }, + limit: { context: 202800, output: 131072 }, + }, + "zai-org/glm-5.1": { + id: "zai-org/glm-5.1", + name: "GLM-5.1", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-03-27", + last_updated: "2026-03-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.4, output: 4.4, cache_read: 0.26 }, + limit: { context: 204800, output: 131072 }, + }, + "zai-org/glm-4.5": { + id: "zai-org/glm-4.5", + name: "GLM-4.5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2025-07-28", + last_updated: "2025-07-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.2, cache_read: 0.11 }, + limit: { context: 131072, output: 98304 }, + }, + "zai-org/glm-4.5-air": { + id: "zai-org/glm-4.5-air", + name: "GLM 4.5 Air", + family: "glm-air", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-10-13", + last_updated: "2025-10-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.13, output: 0.85 }, + limit: { context: 131072, output: 98304 }, + }, + "zai-org/glm-4.5v": { + id: "zai-org/glm-4.5v", + name: "GLM 4.5V", + family: "glmv", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-08-11", + last_updated: "2025-08-11", + modalities: { input: ["text", "video", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 1.8, cache_read: 0.11 }, + limit: { context: 65536, output: 16384 }, + }, + "zai-org/glm-4.6": { + id: "zai-org/glm-4.6", + name: "GLM 4.6", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2025-09-30", + last_updated: "2025-09-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.55, output: 2.2, cache_read: 0.11 }, + limit: { context: 204800, output: 131072 }, + }, + "zai-org/glm-4.6v": { + id: "zai-org/glm-4.6v", + name: "GLM 4.6V", + family: "glmv", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-12-08", + last_updated: "2025-12-08", + modalities: { input: ["text", "video", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 0.9, cache_read: 0.055 }, + limit: { context: 131072, output: 32768 }, + }, + "zai-org/glm-4.7-flash": { + id: "zai-org/glm-4.7-flash", + name: "GLM-4.7-Flash", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-01-19", + last_updated: "2026-01-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.07, output: 0.4, cache_read: 0.01 }, + limit: { context: 200000, output: 128000 }, + }, + "zai-org/autoglm-phone-9b-multilingual": { + id: "zai-org/autoglm-phone-9b-multilingual", + name: "AutoGLM-Phone-9B-Multilingual", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-12-10", + last_updated: "2025-12-10", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.035, output: 0.138 }, + limit: { context: 65536, output: 65536 }, + }, + "mistralai/mistral-nemo": { + id: "mistralai/mistral-nemo", + name: "Mistral Nemo", + family: "mistral-nemo", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: true, + temperature: true, + release_date: "2024-07-30", + last_updated: "2024-07-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.04, output: 0.17 }, + limit: { context: 60288, output: 16000 }, + }, + "baichuan/baichuan-m2-32b": { + id: "baichuan/baichuan-m2-32b", + name: "baichuan-m2-32b", + family: "baichuan", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + knowledge: "2024-12", + release_date: "2025-08-13", + last_updated: "2025-08-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.07, output: 0.07 }, + limit: { context: 131072, output: 131072 }, + }, + "meta-llama/llama-4-scout-17b-16e-instruct": { + id: "meta-llama/llama-4-scout-17b-16e-instruct", + name: "Llama 4 Scout Instruct", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-04-06", + last_updated: "2025-04-06", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.18, output: 0.59 }, + limit: { context: 131072, output: 131072 }, + }, + "meta-llama/llama-3.3-70b-instruct": { + id: "meta-llama/llama-3.3-70b-instruct", + name: "Llama 3.3 70B Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-12-07", + last_updated: "2024-12-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.135, output: 0.4 }, + limit: { context: 131072, output: 120000 }, + }, + "meta-llama/llama-3.2-3b-instruct": { + id: "meta-llama/llama-3.2-3b-instruct", + name: "Llama 3.2 3B Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: true, + temperature: true, + release_date: "2024-09-18", + last_updated: "2024-09-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.03, output: 0.05 }, + limit: { context: 32768, output: 32000 }, + }, + "meta-llama/llama-3-8b-instruct": { + id: "meta-llama/llama-3-8b-instruct", + name: "Llama 3 8B Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2024-04-25", + last_updated: "2024-04-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.04, output: 0.04 }, + limit: { context: 8192, output: 8192 }, + }, + "meta-llama/llama-3.1-8b-instruct": { + id: "meta-llama/llama-3.1-8b-instruct", + name: "Llama 3.1 8B Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2024-07-24", + last_updated: "2024-07-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.02, output: 0.05 }, + limit: { context: 16384, output: 16384 }, + }, + "meta-llama/llama-3-70b-instruct": { + id: "meta-llama/llama-3-70b-instruct", + name: "Llama3 70B Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: true, + temperature: true, + release_date: "2024-04-25", + last_updated: "2024-04-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.51, output: 0.74 }, + limit: { context: 8192, output: 8000 }, + }, + "meta-llama/llama-4-maverick-17b-128e-instruct-fp8": { + id: "meta-llama/llama-4-maverick-17b-128e-instruct-fp8", + name: "Llama 4 Maverick Instruct", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-04-06", + last_updated: "2025-04-06", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.27, output: 0.85 }, + limit: { context: 1048576, output: 8192 }, + }, + "gryphe/mythomax-l2-13b": { + id: "gryphe/mythomax-l2-13b", + name: "Mythomax L2 13B", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2024-04-25", + last_updated: "2024-04-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.09, output: 0.09 }, + limit: { context: 4096, output: 3200 }, + }, + "sao10k/l31-70b-euryale-v2.2": { + id: "sao10k/l31-70b-euryale-v2.2", + name: "L31 70B Euryale V2.2", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-09-19", + last_updated: "2024-09-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.48, output: 1.48 }, + limit: { context: 8192, output: 8192 }, + }, + "sao10k/l3-70b-euryale-v2.1": { + id: "sao10k/l3-70b-euryale-v2.1", + name: "L3 70B Euryale V2.1\t", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-06-18", + last_updated: "2024-06-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.48, output: 1.48 }, + limit: { context: 8192, output: 8192 }, + }, + "sao10k/L3-8B-Stheno-v3.2": { + id: "sao10k/L3-8B-Stheno-v3.2", + name: "L3 8B Stheno V3.2", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-11-29", + last_updated: "2024-11-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.05, output: 0.05 }, + limit: { context: 8192, output: 32000 }, + }, + "sao10k/l3-8b-lunaris": { + id: "sao10k/l3-8b-lunaris", + name: "Sao10k L3 8B Lunaris\t", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: true, + temperature: true, + release_date: "2024-11-28", + last_updated: "2024-11-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.05, output: 0.05 }, + limit: { context: 8192, output: 8192 }, + }, + "microsoft/wizardlm-2-8x22b": { + id: "microsoft/wizardlm-2-8x22b", + name: "Wizardlm 2 8x22B", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2024-04-24", + last_updated: "2024-04-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.62, output: 0.62 }, + limit: { context: 65535, output: 8000 }, + }, + "openai/gpt-oss-20b": { + id: "openai/gpt-oss-20b", + name: "OpenAI: GPT OSS 20B", + attachment: true, + reasoning: true, + tool_call: false, + structured_output: true, + temperature: true, + release_date: "2025-08-06", + last_updated: "2025-08-06", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.04, output: 0.15 }, + limit: { context: 131072, output: 32768 }, + }, + "openai/gpt-oss-120b": { + id: "openai/gpt-oss-120b", + name: "OpenAI GPT OSS 120B", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-08-06", + last_updated: "2025-08-06", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.05, output: 0.25 }, + limit: { context: 131072, output: 32768 }, + }, + "minimaxai/minimax-m1-80k": { + id: "minimaxai/minimax-m1-80k", + name: "MiniMax M1", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-06-17", + last_updated: "2025-06-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.55, output: 2.2 }, + limit: { context: 1000000, output: 40000 }, + }, + "xiaomimimo/mimo-v2-flash": { + id: "xiaomimimo/mimo-v2-flash", + name: "XiaomiMiMo/MiMo-V2-Flash", + family: "mimo", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-12", + release_date: "2025-12-19", + last_updated: "2025-12-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.3, cache_read: 0.3 }, + limit: { context: 262144, output: 32000 }, + }, + "baidu/ernie-4.5-vl-28b-a3b-thinking": { + id: "baidu/ernie-4.5-vl-28b-a3b-thinking", + name: "ERNIE-4.5-VL-28B-A3B-Thinking", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-11-26", + last_updated: "2025-11-26", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.39, output: 0.39 }, + limit: { context: 131072, output: 65536 }, + }, + "baidu/ernie-4.5-vl-424b-a47b": { + id: "baidu/ernie-4.5-vl-424b-a47b", + name: "ERNIE 4.5 VL 424B A47B", + attachment: true, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2025-06-30", + last_updated: "2025-06-30", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.42, output: 1.25 }, + limit: { context: 123000, output: 16000 }, + }, + "baidu/ernie-4.5-21B-a3b": { + id: "baidu/ernie-4.5-21B-a3b", + name: "ERNIE 4.5 21B A3B", + family: "ernie", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-03", + release_date: "2025-06-30", + last_updated: "2025-06-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.07, output: 0.28 }, + limit: { context: 120000, output: 8000 }, + }, + "baidu/ernie-4.5-300b-a47b-paddle": { + id: "baidu/ernie-4.5-300b-a47b-paddle", + name: "ERNIE 4.5 300B A47B", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: true, + temperature: true, + release_date: "2025-06-30", + last_updated: "2025-06-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.28, output: 1.1 }, + limit: { context: 123000, output: 12000 }, + }, + "baidu/ernie-4.5-21B-a3b-thinking": { + id: "baidu/ernie-4.5-21B-a3b-thinking", + name: "ERNIE-4.5-21B-A3B-Thinking", + family: "ernie", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + knowledge: "2025-03", + release_date: "2025-09-19", + last_updated: "2025-09-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.07, output: 0.28 }, + limit: { context: 131072, output: 65536 }, + }, + "baidu/ernie-4.5-vl-28b-a3b": { + id: "baidu/ernie-4.5-vl-28b-a3b", + name: "ERNIE 4.5 VL 28B A3B", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-06-30", + last_updated: "2025-06-30", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 1.4, output: 5.6 }, + limit: { context: 30000, output: 8000 }, + }, + "minimax/minimax-m2.7": { + id: "minimax/minimax-m2.7", + name: "MiniMax M2.7", + family: "minimax-m2.7", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2, cache_read: 0.06 }, + limit: { context: 204800, output: 131072 }, + }, + "minimax/minimax-m2": { + id: "minimax/minimax-m2", + name: "MiniMax-M2", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2025-10-27", + last_updated: "2025-10-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2, cache_read: 0.03 }, + limit: { context: 204800, output: 131072 }, + }, + "minimax/minimax-m2.1": { + id: "minimax/minimax-m2.1", + name: "Minimax M2.1", + family: "minimax", + attachment: false, + reasoning: false, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2025-12-23", + last_updated: "2025-12-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2, cache_read: 0.03 }, + limit: { context: 204800, output: 131072 }, + }, + "minimax/minimax-m2.5": { + id: "minimax/minimax-m2.5", + name: "MiniMax M2.5", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 1.2, cache_read: 0.03 }, + limit: { context: 204800, output: 131100 }, + }, + "minimax/minimax-m2.5-highspeed": { + id: "minimax/minimax-m2.5-highspeed", + name: "MiniMax M2.5 Highspeed", + family: "minimax-m2.5", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.6, output: 2.4, cache_read: 0.03 }, + limit: { context: 204800, output: 131100 }, + }, + "qwen/qwen2.5-7b-instruct": { + id: "qwen/qwen2.5-7b-instruct", + name: "Qwen2.5 7B Instruct", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-04-16", + last_updated: "2025-04-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.07, output: 0.07 }, + limit: { context: 32000, output: 32000 }, + }, + "qwen/qwen3.5-122b-a10b": { + id: "qwen/qwen3.5-122b-a10b", + name: "Qwen3.5-122B-A10B", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-02-26", + last_updated: "2026-02-26", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.4, output: 3.2 }, + limit: { context: 262144, output: 65536 }, + }, + "qwen/qwen3.6-27b": { + id: "qwen/qwen3.6-27b", + name: "Qwen3.6-27B", + family: "qwen3.6", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-04-02", + last_updated: "2026-04-02", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.6, output: 3.6 }, + limit: { context: 262144, output: 65536 }, + }, + "qwen/qwen3.5-27b": { + id: "qwen/qwen3.5-27b", + name: "Qwen3.5-27B", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-02-26", + last_updated: "2026-02-26", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 2.4 }, + limit: { context: 262144, output: 65536 }, + }, + "qwen/qwen3-235b-a22b-instruct-2507": { + id: "qwen/qwen3-235b-a22b-instruct-2507", + name: "Qwen3 235B A22B Instruct 2507", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-22", + last_updated: "2025-07-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.09, output: 0.58 }, + limit: { context: 131072, output: 16384 }, + }, + "qwen/qwen3-omni-30b-a3b-instruct": { + id: "qwen/qwen3-omni-30b-a3b-instruct", + name: "Qwen3 Omni 30B A3B Instruct", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-09-24", + last_updated: "2025-09-24", + modalities: { input: ["text", "video", "audio", "image"], output: ["text", "audio"] }, + open_weights: true, + cost: { input: 0.25, output: 0.97, input_audio: 2.2, output_audio: 1.788 }, + limit: { context: 65536, output: 16384 }, + }, + "qwen/qwen3.5-397b-a17b": { + id: "qwen/qwen3.5-397b-a17b", + name: "Qwen3.5-397B-A17B", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-02-17", + last_updated: "2026-02-17", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 3.6 }, + limit: { context: 262144, output: 64000 }, + }, + "qwen/qwen2.5-vl-72b-instruct": { + id: "qwen/qwen2.5-vl-72b-instruct", + name: "Qwen2.5 VL 72B Instruct", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-03-25", + last_updated: "2025-03-25", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.8, output: 0.8 }, + limit: { context: 32768, output: 32768 }, + }, + "qwen/qwen3-vl-235b-a22b-thinking": { + id: "qwen/qwen3-vl-235b-a22b-thinking", + name: "Qwen3 VL 235B A22B Thinking", + attachment: true, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2025-09-24", + last_updated: "2025-09-24", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.98, output: 3.95 }, + limit: { context: 131072, output: 32768 }, + }, + "qwen/qwen3-vl-30b-a3b-thinking": { + id: "qwen/qwen3-vl-30b-a3b-thinking", + name: "qwen/qwen3-vl-30b-a3b-thinking", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-10-11", + last_updated: "2025-10-11", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 1 }, + limit: { context: 131072, output: 32768 }, + }, + "qwen/qwen3-omni-30b-a3b-thinking": { + id: "qwen/qwen3-omni-30b-a3b-thinking", + name: "Qwen3 Omni 30B A3B Thinking", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-09-24", + last_updated: "2025-09-24", + modalities: { input: ["text", "audio", "video", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.25, output: 0.97, input_audio: 2.2, output_audio: 1.788 }, + limit: { context: 65536, output: 16384 }, + }, + "qwen/qwen3-vl-8b-instruct": { + id: "qwen/qwen3-vl-8b-instruct", + name: "qwen/qwen3-vl-8b-instruct", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-10-17", + last_updated: "2025-10-17", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.08, output: 0.5 }, + limit: { context: 131072, output: 32768 }, + }, + "qwen/qwen3-max": { + id: "qwen/qwen3-max", + name: "Qwen3 Max", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-09-24", + last_updated: "2025-09-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2.11, output: 8.45 }, + limit: { context: 262144, output: 65536 }, + }, + "qwen/qwen3-32b-fp8": { + id: "qwen/qwen3-32b-fp8", + name: "Qwen3 32B", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2025-04-29", + last_updated: "2025-04-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.45 }, + limit: { context: 40960, output: 20000 }, + }, + "qwen/qwen3-4b-fp8": { + id: "qwen/qwen3-4b-fp8", + name: "Qwen3 4B", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2025-04-29", + last_updated: "2025-04-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.03, output: 0.03 }, + limit: { context: 128000, output: 20000 }, + }, + "qwen/qwen3-235b-a22b-thinking-2507": { + id: "qwen/qwen3-235b-a22b-thinking-2507", + name: "Qwen3 235B A22b Thinking 2507", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-25", + last_updated: "2025-07-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 3 }, + limit: { context: 131072, output: 32768 }, + }, + "qwen/qwen3-next-80b-a3b-thinking": { + id: "qwen/qwen3-next-80b-a3b-thinking", + name: "Qwen3 Next 80B A3B Thinking", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-09-10", + last_updated: "2025-09-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 1.5 }, + limit: { context: 131072, output: 32768 }, + }, + "qwen/qwen-mt-plus": { + id: "qwen/qwen-mt-plus", + name: "Qwen MT Plus", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-09-03", + last_updated: "2025-09-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.25, output: 0.75 }, + limit: { context: 16384, output: 8192 }, + }, + "qwen/qwen3-next-80b-a3b-instruct": { + id: "qwen/qwen3-next-80b-a3b-instruct", + name: "Qwen3 Next 80B A3B Instruct", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-09-10", + last_updated: "2025-09-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 1.5 }, + limit: { context: 131072, output: 32768 }, + }, + "qwen/qwen3-30b-a3b-fp8": { + id: "qwen/qwen3-30b-a3b-fp8", + name: "Qwen3 30B A3B", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2025-04-29", + last_updated: "2025-04-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.09, output: 0.45 }, + limit: { context: 40960, output: 20000 }, + }, + "qwen/qwen3-coder-next": { + id: "qwen/qwen3-coder-next", + name: "Qwen3 Coder Next", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-02-03", + last_updated: "2026-02-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 1.5 }, + limit: { context: 262144, output: 65536 }, + }, + "qwen/qwen3-coder-480b-a35b-instruct": { + id: "qwen/qwen3-coder-480b-a35b-instruct", + name: "Qwen3 Coder 480B A35B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-23", + last_updated: "2025-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.3 }, + limit: { context: 262144, output: 65536 }, + }, + "qwen/qwen3-vl-30b-a3b-instruct": { + id: "qwen/qwen3-vl-30b-a3b-instruct", + name: "qwen/qwen3-vl-30b-a3b-instruct", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-10-11", + last_updated: "2025-10-11", + modalities: { input: ["text", "video", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.7 }, + limit: { context: 131072, output: 32768 }, + }, + "qwen/qwen3-coder-30b-a3b-instruct": { + id: "qwen/qwen3-coder-30b-a3b-instruct", + name: "Qwen3 Coder 30b A3B Instruct", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-10-09", + last_updated: "2025-10-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.07, output: 0.27 }, + limit: { context: 160000, output: 32768 }, + }, + "qwen/qwen3-235b-a22b-fp8": { + id: "qwen/qwen3-235b-a22b-fp8", + name: "Qwen3 235B A22B", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2025-04-29", + last_updated: "2025-04-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.8 }, + limit: { context: 40960, output: 20000 }, + }, + "qwen/qwen3-8b-fp8": { + id: "qwen/qwen3-8b-fp8", + name: "Qwen3 8B", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2025-04-29", + last_updated: "2025-04-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.035, output: 0.138 }, + limit: { context: 128000, output: 20000 }, + }, + "qwen/qwen3-vl-235b-a22b-instruct": { + id: "qwen/qwen3-vl-235b-a22b-instruct", + name: "Qwen3 VL 235B A22B Instruct", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-09-24", + last_updated: "2025-09-24", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.5 }, + limit: { context: 131072, output: 32768 }, + }, + "qwen/qwen-2.5-72b-instruct": { + id: "qwen/qwen-2.5-72b-instruct", + name: "Qwen 2.5 72B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-10-15", + last_updated: "2024-10-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.38, output: 0.4 }, + limit: { context: 32000, output: 8192 }, + }, + "qwen/qwen3.5-35b-a3b": { + id: "qwen/qwen3.5-35b-a3b", + name: "Qwen3.5-35B-A3B", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-02-26", + last_updated: "2026-02-26", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.25, output: 2 }, + limit: { context: 262144, output: 65536 }, + }, + "kwaipilot/kat-coder-pro": { + id: "kwaipilot/kat-coder-pro", + name: "Kat Coder Pro", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01-05", + last_updated: "2026-01-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2, cache_read: 0.06 }, + limit: { context: 256000, output: 128000 }, + }, + "google/gemma-4-31b-it": { + id: "google/gemma-4-31b-it", + name: "Gemma 4 31B", + family: "gemma", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-02", + last_updated: "2026-04-02", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.14, output: 0.4 }, + limit: { context: 262144, output: 131072 }, + }, + "google/gemma-3-12b-it": { + id: "google/gemma-3-12b-it", + name: "Gemma 3 12B", + family: "gemma", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-10", + release_date: "2025-03-13", + last_updated: "2025-03-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.05, output: 0.1 }, + limit: { context: 131072, output: 8192 }, + }, + "google/gemma-3-27b-it": { + id: "google/gemma-3-27b-it", + name: "Gemma 3 27B", + family: "gemma", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-03-25", + last_updated: "2025-03-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.119, output: 0.2 }, + limit: { context: 98304, output: 16384 }, + }, + "google/gemma-4-26b-a4b-it": { + id: "google/gemma-4-26b-a4b-it", + name: "Gemma 4 26B A4B", + family: "gemma", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-02", + last_updated: "2026-04-02", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.13, output: 0.4 }, + limit: { context: 262144, output: 131072 }, + }, + "moonshotai/kimi-k2.5": { + id: "moonshotai/kimi-k2.5", + name: "Kimi K2.5", + family: "kimi", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-01-27", + last_updated: "2026-01-27", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 3, cache_read: 0.1 }, + limit: { context: 262144, output: 262144 }, + }, + "moonshotai/kimi-k2-instruct": { + id: "moonshotai/kimi-k2-instruct", + name: "Kimi K2 Instruct", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-07-11", + last_updated: "2025-07-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.57, output: 2.3 }, + limit: { context: 131072, output: 131072 }, + }, + "moonshotai/kimi-k2-0905": { + id: "moonshotai/kimi-k2-0905", + name: "Kimi K2 0905", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-09-05", + last_updated: "2025-09-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.5 }, + limit: { context: 262144, output: 262144 }, + }, + "moonshotai/kimi-k2.6": { + id: "moonshotai/kimi-k2.6", + name: "Kimi K2.6", + family: "kimi", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-04-21", + last_updated: "2026-04-21", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.95, output: 4, cache_read: 0.16 }, + limit: { context: 262144, output: 262144 }, + }, + "moonshotai/kimi-k2-thinking": { + id: "moonshotai/kimi-k2-thinking", + name: "Kimi K2 Thinking", + family: "kimi", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2025-11-07", + last_updated: "2025-11-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.5 }, + limit: { context: 262144, output: 262144 }, + }, + "deepseek/deepseek-v4-flash": { + id: "deepseek/deepseek-v4-flash", + name: "DeepSeek V4 Flash", + family: "deepseek-flash", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-05", + release_date: "2026-04-24", + last_updated: "2026-04-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.14, output: 0.28, cache_read: 0.028 }, + limit: { context: 1048576, output: 393216 }, + }, + "deepseek/deepseek-v4-pro": { + id: "deepseek/deepseek-v4-pro", + name: "DeepSeek V4 Pro", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-05", + release_date: "2026-04-24", + last_updated: "2026-04-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.69, output: 3.38, cache_read: 0.13 }, + limit: { context: 1048576, output: 393216 }, + }, + }, + }, + "xiaomi-token-plan-cn": { + id: "xiaomi-token-plan-cn", + env: ["XIAOMI_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://token-plan-cn.xiaomimimo.com/v1", + name: "Xiaomi Token Plan (China)", + doc: "https://platform.xiaomimimo.com/#/docs", + models: { + "mimo-v2-tts": { + id: "mimo-v2-tts", + name: "MiMo-V2-TTS", + family: "mimo", + attachment: false, + reasoning: false, + tool_call: false, + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["audio"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 8192, output: 16384 }, + }, + "mimo-v2.5-pro": { + id: "mimo-v2.5-pro", + name: "MiMo-V2.5-Pro", + family: "mimo", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12", + release_date: "2026-04-22", + last_updated: "2026-04-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, context_over_200k: { input: 0, output: 0, cache_read: 0 } }, + limit: { context: 1048576, output: 131072 }, + }, + "mimo-v2-omni": { + id: "mimo-v2-omni", + name: "MiMo-V2-Omni", + family: "mimo", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12", + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0, cache_read: 0 }, + limit: { context: 262144, output: 131072 }, + }, + "mimo-v2.5": { + id: "mimo-v2.5", + name: "MiMo-V2.5", + family: "mimo", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12", + release_date: "2026-04-22", + last_updated: "2026-04-22", + modalities: { input: ["text", "image", "audio", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, context_over_200k: { input: 0, output: 0, cache_read: 0 } }, + limit: { context: 1048576, output: 131072 }, + }, + "mimo-v2-pro": { + id: "mimo-v2-pro", + name: "MiMo-V2-Pro", + family: "mimo", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12", + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0, cache_read: 0, context_over_200k: { input: 2, output: 6, cache_read: 0.4 } }, + limit: { context: 1048576, output: 131072 }, + }, + "mimo-v2-flash": { + id: "mimo-v2-flash", + name: "MiMo-V2-Flash", + family: "mimo", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12-01", + release_date: "2025-12-16", + last_updated: "2026-02-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0 }, + limit: { context: 262144, output: 65536 }, + }, + }, + }, + wandb: { + id: "wandb", + env: ["WANDB_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.inference.wandb.ai/v1", + name: "Weights & Biases", + doc: "https://docs.wandb.ai/guides/integrations/inference/", + models: { + "Qwen/Qwen3-30B-A3B-Instruct-2507": { + id: "Qwen/Qwen3-30B-A3B-Instruct-2507", + name: "Qwen3 30B A3B Instruct 2507", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-07-29", + last_updated: "2026-03-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.3 }, + limit: { context: 262144, output: 262144 }, + }, + "Qwen/Qwen3-235B-A22B-Instruct-2507": { + id: "Qwen/Qwen3-235B-A22B-Instruct-2507", + name: "Qwen3 235B A22B Instruct 2507", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-04-28", + last_updated: "2026-03-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.1 }, + limit: { context: 262144, output: 262144 }, + }, + "Qwen/Qwen3-235B-A22B-Thinking-2507": { + id: "Qwen/Qwen3-235B-A22B-Thinking-2507", + name: "Qwen3-235B-A22B-Thinking-2507", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-25", + last_updated: "2026-03-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.1 }, + limit: { context: 262144, output: 262144 }, + }, + "Qwen/Qwen3-Coder-480B-A35B-Instruct": { + id: "Qwen/Qwen3-Coder-480B-A35B-Instruct", + name: "Qwen3-Coder-480B-A35B-Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-23", + last_updated: "2026-03-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 1.5 }, + limit: { context: 262144, output: 262144 }, + }, + "zai-org/GLM-5-FP8": { + id: "zai-org/GLM-5-FP8", + name: "GLM 5", + family: "glm", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-02-11", + last_updated: "2026-03-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 3.2 }, + limit: { context: 200000, output: 200000 }, + }, + "meta-llama/Llama-4-Scout-17B-16E-Instruct": { + id: "meta-llama/Llama-4-Scout-17B-16E-Instruct", + name: "Llama 4 Scout 17B 16E Instruct", + family: "llama", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-12", + release_date: "2025-01-31", + last_updated: "2026-03-12", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.17, output: 0.66 }, + limit: { context: 64000, output: 64000 }, + }, + "meta-llama/Llama-3.3-70B-Instruct": { + id: "meta-llama/Llama-3.3-70B-Instruct", + name: "Llama-3.3-70B-Instruct", + family: "llama", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-12-06", + last_updated: "2026-03-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.71, output: 0.71 }, + limit: { context: 128000, output: 128000 }, + }, + "meta-llama/Llama-3.1-8B-Instruct": { + id: "meta-llama/Llama-3.1-8B-Instruct", + name: "Meta-Llama-3.1-8B-Instruct", + family: "llama", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-07-23", + last_updated: "2026-03-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.22, output: 0.22 }, + limit: { context: 128000, output: 128000 }, + }, + "meta-llama/Llama-3.1-70B-Instruct": { + id: "meta-llama/Llama-3.1-70B-Instruct", + name: "Llama 3.1 70B", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-07-23", + last_updated: "2026-03-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.8, output: 0.8 }, + limit: { context: 128000, output: 128000 }, + }, + "OpenPipe/Qwen3-14B-Instruct": { + id: "OpenPipe/Qwen3-14B-Instruct", + name: "OpenPipe Qwen3 14B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-04-29", + last_updated: "2026-03-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.05, output: 0.22 }, + limit: { context: 32768, output: 32768 }, + }, + "microsoft/Phi-4-mini-instruct": { + id: "microsoft/Phi-4-mini-instruct", + name: "Phi-4-mini-instruct", + family: "phi", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2023-10", + release_date: "2024-12-11", + last_updated: "2026-03-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.08, output: 0.35 }, + limit: { context: 128000, output: 128000 }, + }, + "nvidia/NVIDIA-Nemotron-3-Super-120B-A12B-FP8": { + id: "nvidia/NVIDIA-Nemotron-3-Super-120B-A12B-FP8", + name: "NVIDIA Nemotron 3 Super 120B", + family: "nemotron", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-03-11", + last_updated: "2026-03-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.8 }, + limit: { context: 262144, output: 262144 }, + }, + "deepseek-ai/DeepSeek-V3.1": { + id: "deepseek-ai/DeepSeek-V3.1", + name: "DeepSeek V3.1", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-08-21", + last_updated: "2026-03-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.55, output: 1.65 }, + limit: { context: 161000, output: 161000 }, + }, + "openai/gpt-oss-20b": { + id: "openai/gpt-oss-20b", + name: "gpt-oss-20b", + family: "gpt-oss", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-08-05", + last_updated: "2026-03-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.05, output: 0.2 }, + limit: { context: 131072, output: 131072 }, + }, + "openai/gpt-oss-120b": { + id: "openai/gpt-oss-120b", + name: "gpt-oss-120b", + family: "gpt-oss", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-08-05", + last_updated: "2026-03-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 131072, output: 131072 }, + }, + "moonshotai/Kimi-K2.5": { + id: "moonshotai/Kimi-K2.5", + name: "Kimi K2.5", + family: "kimi", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-01-27", + last_updated: "2026-03-12", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.5, output: 2.85 }, + limit: { context: 262144, output: 262144 }, + }, + "MiniMaxAI/MiniMax-M2.5": { + id: "MiniMaxAI/MiniMax-M2.5", + name: "MiniMax M2.5", + family: "minimax", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-02-12", + last_updated: "2026-03-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 196608, output: 196608 }, + }, + "zai-org/GLM-5.1": { + id: "zai-org/GLM-5.1", + name: "GLM-5.1", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-03-27", + last_updated: "2026-03-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.4, output: 4.4, cache_read: 0.26, cache_write: 0 }, + limit: { context: 200000, output: 131072 }, + }, + }, + }, + chutes: { + id: "chutes", + env: ["CHUTES_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://llm.chutes.ai/v1", + name: "Chutes", + doc: "https://llm.chutes.ai/v1/models", + models: { + "miromind-ai/MiroThinker-v1.5-235B": { + id: "miromind-ai/MiroThinker-v1.5-235B", + name: "MiroThinker V1.5 235B", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2026-01-10", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2, cache_read: 0.15 }, + limit: { context: 262144, output: 8192 }, + }, + "OpenGVLab/InternVL3-78B-TEE": { + id: "OpenGVLab/InternVL3-78B-TEE", + name: "InternVL3 78B TEE", + family: "opengvlab", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: true, + temperature: true, + release_date: "2025-01-06", + last_updated: "2026-01-10", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.39 }, + limit: { context: 32768, output: 32768 }, + }, + "NousResearch/DeepHermes-3-Mistral-24B-Preview": { + id: "NousResearch/DeepHermes-3-Mistral-24B-Preview", + name: "DeepHermes 3 Mistral 24B Preview", + family: "nousresearch", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.02, output: 0.1 }, + limit: { context: 32768, output: 32768 }, + }, + "NousResearch/Hermes-4-405B-FP8-TEE": { + id: "NousResearch/Hermes-4-405B-FP8-TEE", + name: "Hermes 4 405B FP8 TEE", + family: "nousresearch", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 131072, output: 65536 }, + }, + "NousResearch/Hermes-4.3-36B": { + id: "NousResearch/Hermes-4.3-36B", + name: "Hermes 4.3 36B", + family: "nousresearch", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.39 }, + limit: { context: 32768, output: 8192 }, + }, + "NousResearch/Hermes-4-14B": { + id: "NousResearch/Hermes-4-14B", + name: "Hermes 4 14B", + family: "nousresearch", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.01, output: 0.05 }, + limit: { context: 40960, output: 40960 }, + }, + "NousResearch/Hermes-4-70B": { + id: "NousResearch/Hermes-4-70B", + name: "Hermes 4 70B", + family: "nousresearch", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.11, output: 0.38 }, + limit: { context: 131072, output: 131072 }, + }, + "Qwen/Qwen3-30B-A3B": { + id: "Qwen/Qwen3-30B-A3B", + name: "Qwen3 30B A3B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.06, output: 0.22 }, + limit: { context: 40960, output: 40960 }, + }, + "Qwen/Qwen3-Coder-Next": { + id: "Qwen/Qwen3-Coder-Next", + name: "Qwen3 Coder Next", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-02-05", + last_updated: "2026-02-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.07, output: 0.3 }, + limit: { context: 262144, output: 65536 }, + }, + "Qwen/Qwen2.5-Coder-32B-Instruct": { + id: "Qwen/Qwen2.5-Coder-32B-Instruct", + name: "Qwen2.5 Coder 32B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.03, output: 0.11 }, + limit: { context: 32768, output: 32768 }, + }, + "Qwen/Qwen3-235B-A22B": { + id: "Qwen/Qwen3-235B-A22B", + name: "Qwen3 235B A22B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 40960, output: 40960 }, + }, + "Qwen/Qwen2.5-VL-72B-Instruct-TEE": { + id: "Qwen/Qwen2.5-VL-72B-Instruct-TEE", + name: "Qwen2.5 VL 72B Instruct TEE", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 32768, output: 32768 }, + }, + "Qwen/Qwen3Guard-Gen-0.6B": { + id: "Qwen/Qwen3Guard-Gen-0.6B", + name: "Qwen3Guard Gen 0.6B", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.01, output: 0.01, cache_read: 0.005 }, + limit: { context: 32768, output: 8192 }, + }, + "Qwen/Qwen3-Next-80B-A3B-Instruct": { + id: "Qwen/Qwen3-Next-80B-A3B-Instruct", + name: "Qwen3 Next 80B A3B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.8 }, + limit: { context: 262144, output: 262144 }, + }, + "Qwen/Qwen3-30B-A3B-Instruct-2507": { + id: "Qwen/Qwen3-30B-A3B-Instruct-2507", + name: "Qwen3 30B A3B Instruct 2507", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.08, output: 0.33 }, + limit: { context: 262144, output: 262144 }, + }, + "Qwen/Qwen3-32B": { + id: "Qwen/Qwen3-32B", + name: "Qwen3 32B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.08, output: 0.24, cache_read: 0.04 }, + limit: { context: 40960, output: 40960 }, + }, + "Qwen/Qwen3-14B": { + id: "Qwen/Qwen3-14B", + name: "Qwen3 14B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.05, output: 0.22 }, + limit: { context: 40960, output: 40960 }, + }, + "Qwen/Qwen3-235B-A22B-Instruct-2507-TEE": { + id: "Qwen/Qwen3-235B-A22B-Instruct-2507-TEE", + name: "Qwen3 235B A22B Instruct 2507 TEE", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.08, output: 0.55, cache_read: 0.04 }, + limit: { context: 262144, output: 65536 }, + }, + "Qwen/Qwen3-235B-A22B-Thinking-2507": { + id: "Qwen/Qwen3-235B-A22B-Thinking-2507", + name: "Qwen3 235B A22B Thinking 2507", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.11, output: 0.6 }, + limit: { context: 262144, output: 262144 }, + }, + "Qwen/Qwen2.5-VL-32B-Instruct": { + id: "Qwen/Qwen2.5-VL-32B-Instruct", + name: "Qwen2.5 VL 32B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.05, output: 0.22 }, + limit: { context: 16384, output: 16384 }, + }, + "Qwen/Qwen3.5-397B-A17B-TEE": { + id: "Qwen/Qwen3.5-397B-A17B-TEE", + name: "Qwen3.5 397B A17B TEE", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-02-18", + last_updated: "2026-02-18", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.39, output: 2.34, cache_read: 0.195 }, + limit: { context: 262144, output: 65536 }, + }, + "Qwen/Qwen3-Coder-480B-A35B-Instruct-FP8-TEE": { + id: "Qwen/Qwen3-Coder-480B-A35B-Instruct-FP8-TEE", + name: "Qwen3 Coder 480B A35B Instruct FP8 TEE", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.22, output: 0.95, cache_read: 0.11 }, + limit: { context: 262144, output: 262144 }, + }, + "Qwen/Qwen3-VL-235B-A22B-Instruct": { + id: "Qwen/Qwen3-VL-235B-A22B-Instruct", + name: "Qwen3 VL 235B A22B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 262144, output: 262144 }, + }, + "Qwen/Qwen2.5-72B-Instruct": { + id: "Qwen/Qwen2.5-72B-Instruct", + name: "Qwen2.5 72B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.13, output: 0.52 }, + limit: { context: 32768, output: 32768 }, + }, + "zai-org/GLM-5.1-TEE": { + id: "zai-org/GLM-5.1-TEE", + name: "GLM 5.1 TEE", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-04-08", + last_updated: "2026-04-08", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.95, output: 3.15, cache_read: 0.475 }, + limit: { context: 202752, output: 65535 }, + }, + "zai-org/GLM-4.7-Flash": { + id: "zai-org/GLM-4.7-Flash", + name: "GLM 4.7 Flash", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01-27", + last_updated: "2026-01-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.06, output: 0.35 }, + limit: { context: 202752, output: 65535 }, + }, + "zai-org/GLM-4.5-TEE": { + id: "zai-org/GLM-4.5-TEE", + name: "GLM 4.5 TEE", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.35, output: 1.55 }, + limit: { context: 131072, output: 65536 }, + }, + "zai-org/GLM-4.6-FP8": { + id: "zai-org/GLM-4.6-FP8", + name: "GLM 4.6 FP8", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01-27", + last_updated: "2026-01-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 202752, output: 65535 }, + }, + "zai-org/GLM-4.5-Air": { + id: "zai-org/GLM-4.5-Air", + name: "GLM 4.5 Air", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.05, output: 0.22 }, + limit: { context: 131072, output: 131072 }, + }, + "zai-org/GLM-4.7-FP8": { + id: "zai-org/GLM-4.7-FP8", + name: "GLM 4.7 FP8", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01-27", + last_updated: "2026-01-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 202752, output: 65535 }, + }, + "zai-org/GLM-5-TEE": { + id: "zai-org/GLM-5-TEE", + name: "GLM 5 TEE", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-02-14", + last_updated: "2026-02-14", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.95, output: 3.15, cache_read: 0.475 }, + limit: { context: 202752, output: 65535 }, + }, + "zai-org/GLM-4.5-FP8": { + id: "zai-org/GLM-4.5-FP8", + name: "GLM 4.5 FP8", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01-27", + last_updated: "2026-01-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 131072, output: 65536 }, + }, + "zai-org/GLM-4.7-TEE": { + id: "zai-org/GLM-4.7-TEE", + name: "GLM 4.7 TEE", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.4, output: 1.5 }, + limit: { context: 202752, output: 65535 }, + }, + "zai-org/GLM-4.6V": { + id: "zai-org/GLM-4.6V", + name: "GLM 4.6V", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 0.9, cache_read: 0.15 }, + limit: { context: 131072, output: 65536 }, + }, + "zai-org/GLM-5-Turbo": { + id: "zai-org/GLM-5-Turbo", + name: "GLM 5 Turbo", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-03-11", + last_updated: "2026-03-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.49, output: 1.96, cache_read: 0.245 }, + limit: { context: 202752, output: 65535 }, + }, + "zai-org/GLM-4.6-TEE": { + id: "zai-org/GLM-4.6-TEE", + name: "GLM 4.6 TEE", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.4, output: 1.7, cache_read: 0.2 }, + limit: { context: 202752, output: 65536 }, + }, + "mistralai/Devstral-2-123B-Instruct-2512-TEE": { + id: "mistralai/Devstral-2-123B-Instruct-2512-TEE", + name: "Devstral 2 123B Instruct 2512 TEE", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01-10", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.05, output: 0.22 }, + limit: { context: 262144, output: 65536 }, + }, + "XiaomiMiMo/MiMo-V2-Flash": { + id: "XiaomiMiMo/MiMo-V2-Flash", + name: "MiMo V2 Flash", + family: "mimo", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.09, output: 0.29 }, + limit: { context: 262144, output: 32000 }, + }, + "chutesai/Mistral-Small-3.2-24B-Instruct-2506": { + id: "chutesai/Mistral-Small-3.2-24B-Instruct-2506", + name: "Mistral Small 3.2 24B Instruct 2506", + family: "chutesai", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.06, output: 0.18 }, + limit: { context: 131072, output: 131072 }, + }, + "chutesai/Mistral-Small-3.1-24B-Instruct-2503": { + id: "chutesai/Mistral-Small-3.1-24B-Instruct-2503", + name: "Mistral Small 3.1 24B Instruct 2503", + family: "chutesai", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.03, output: 0.11, cache_read: 0.015 }, + limit: { context: 131072, output: 131072 }, + }, + "nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16": { + id: "nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16", + name: "NVIDIA Nemotron 3 Nano 30B A3B BF16", + family: "nemotron", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.06, output: 0.24 }, + limit: { context: 262144, output: 262144 }, + }, + "deepseek-ai/DeepSeek-R1-TEE": { + id: "deepseek-ai/DeepSeek-R1-TEE", + name: "DeepSeek R1 TEE", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: false, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 163840, output: 163840 }, + }, + "deepseek-ai/DeepSeek-V3": { + id: "deepseek-ai/DeepSeek-V3", + name: "DeepSeek V3", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 163840, output: 163840 }, + }, + "deepseek-ai/DeepSeek-R1-Distill-Llama-70B": { + id: "deepseek-ai/DeepSeek-R1-Distill-Llama-70B", + name: "DeepSeek R1 Distill Llama 70B", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.03, output: 0.11 }, + limit: { context: 131072, output: 131072 }, + }, + "deepseek-ai/DeepSeek-V3.1-TEE": { + id: "deepseek-ai/DeepSeek-V3.1-TEE", + name: "DeepSeek V3.1 TEE", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.8 }, + limit: { context: 163840, output: 65536 }, + }, + "deepseek-ai/DeepSeek-V3-0324-TEE": { + id: "deepseek-ai/DeepSeek-V3-0324-TEE", + name: "DeepSeek V3 0324 TEE", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.19, output: 0.87, cache_read: 0.095 }, + limit: { context: 163840, output: 65536 }, + }, + "deepseek-ai/DeepSeek-V3.2-Speciale-TEE": { + id: "deepseek-ai/DeepSeek-V3.2-Speciale-TEE", + name: "DeepSeek V3.2 Speciale TEE", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: false, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.27, output: 0.41 }, + limit: { context: 163840, output: 65536 }, + }, + "deepseek-ai/DeepSeek-V3.1-Terminus-TEE": { + id: "deepseek-ai/DeepSeek-V3.1-Terminus-TEE", + name: "DeepSeek V3.1 Terminus TEE", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.23, output: 0.9 }, + limit: { context: 163840, output: 65536 }, + }, + "deepseek-ai/DeepSeek-R1-0528-TEE": { + id: "deepseek-ai/DeepSeek-R1-0528-TEE", + name: "DeepSeek R1 0528 TEE", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.4, output: 1.75 }, + limit: { context: 163840, output: 65536 }, + }, + "deepseek-ai/DeepSeek-V3.2-TEE": { + id: "deepseek-ai/DeepSeek-V3.2-TEE", + name: "DeepSeek V3.2 TEE", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.28, output: 0.42, cache_read: 0.14 }, + limit: { context: 131072, output: 65536 }, + }, + "openai/gpt-oss-20b": { + id: "openai/gpt-oss-20b", + name: "gpt oss 20b", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.02, output: 0.1 }, + limit: { context: 131072, output: 131072 }, + }, + "openai/gpt-oss-120b-TEE": { + id: "openai/gpt-oss-120b-TEE", + name: "gpt oss 120b TEE", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.04, output: 0.18 }, + limit: { context: 131072, output: 65536 }, + }, + "unsloth/gemma-3-12b-it": { + id: "unsloth/gemma-3-12b-it", + name: "gemma 3 12b it", + family: "unsloth", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.03, output: 0.1 }, + limit: { context: 131072, output: 131072 }, + }, + "unsloth/Llama-3.2-3B-Instruct": { + id: "unsloth/Llama-3.2-3B-Instruct", + name: "Llama 3.2 3B Instruct", + family: "unsloth", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2025-02-12", + last_updated: "2025-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.01, output: 0.01, cache_read: 0.005 }, + limit: { context: 16384, output: 16384 }, + }, + "unsloth/gemma-3-4b-it": { + id: "unsloth/gemma-3-4b-it", + name: "gemma 3 4b it", + family: "unsloth", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.01, output: 0.03 }, + limit: { context: 96000, output: 96000 }, + }, + "unsloth/Llama-3.2-1B-Instruct": { + id: "unsloth/Llama-3.2-1B-Instruct", + name: "Llama 3.2 1B Instruct", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2026-01-27", + last_updated: "2026-01-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.01, output: 0.01, cache_read: 0.005 }, + limit: { context: 32768, output: 8192 }, + }, + "unsloth/Mistral-Nemo-Instruct-2407": { + id: "unsloth/Mistral-Nemo-Instruct-2407", + name: "Mistral Nemo Instruct 2407", + family: "unsloth", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.02, output: 0.04, cache_read: 0.01 }, + limit: { context: 131072, output: 131072 }, + }, + "unsloth/Mistral-Small-24B-Instruct-2501": { + id: "unsloth/Mistral-Small-24B-Instruct-2501", + name: "Mistral Small 24B Instruct 2501", + family: "unsloth", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.03, output: 0.11 }, + limit: { context: 32768, output: 32768 }, + }, + "unsloth/gemma-3-27b-it": { + id: "unsloth/gemma-3-27b-it", + name: "gemma 3 27b it", + family: "unsloth", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.04, output: 0.15, cache_read: 0.02 }, + limit: { context: 128000, output: 65536 }, + }, + "moonshotai/Kimi-K2-Thinking-TEE": { + id: "moonshotai/Kimi-K2-Thinking-TEE", + name: "Kimi K2 Thinking TEE", + family: "kimi-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.4, output: 1.75 }, + limit: { context: 262144, output: 65535 }, + }, + "moonshotai/Kimi-K2-Instruct-0905": { + id: "moonshotai/Kimi-K2-Instruct-0905", + name: "Kimi K2 Instruct 0905", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.39, output: 1.9, cache_read: 0.195 }, + limit: { context: 262144, output: 262144 }, + }, + "moonshotai/Kimi-K2.6-TEE": { + id: "moonshotai/Kimi-K2.6-TEE", + name: "Kimi K2.6 TEE", + family: "kimi", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-12", + release_date: "2026-04-20", + last_updated: "2026-04-23", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.44, output: 2 }, + limit: { context: 262144, output: 262144 }, + }, + "moonshotai/Kimi-K2.5-TEE": { + id: "moonshotai/Kimi-K2.5-TEE", + name: "Kimi K2.5 TEE", + family: "kimi", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2024-10", + release_date: "2026-01-27", + last_updated: "2026-01-27", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 3 }, + limit: { context: 262144, output: 65535 }, + }, + "MiniMaxAI/MiniMax-M2.1-TEE": { + id: "MiniMaxAI/MiniMax-M2.1-TEE", + name: "MiniMax M2.1 TEE", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.27, output: 1.12 }, + limit: { context: 196608, output: 65536 }, + }, + "MiniMaxAI/MiniMax-M2.5-TEE": { + id: "MiniMaxAI/MiniMax-M2.5-TEE", + name: "MiniMax M2.5 TEE", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-02-15", + last_updated: "2026-02-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.1, cache_read: 0.15 }, + limit: { context: 196608, output: 65536 }, + }, + "rednote-hilab/dots.ocr": { + id: "rednote-hilab/dots.ocr", + name: "dots.ocr", + family: "rednote", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.01, output: 0.01, cache_read: 0.005 }, + limit: { context: 131072, output: 131072 }, + }, + "tngtech/TNG-R1T-Chimera-Turbo": { + id: "tngtech/TNG-R1T-Chimera-Turbo", + name: "TNG R1T Chimera Turbo", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01-27", + last_updated: "2026-01-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.22, output: 0.6 }, + limit: { context: 163840, output: 65536 }, + }, + "tngtech/DeepSeek-TNG-R1T2-Chimera": { + id: "tngtech/DeepSeek-TNG-R1T2-Chimera", + name: "DeepSeek TNG R1T2 Chimera", + family: "tngtech", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.25, output: 0.85 }, + limit: { context: 163840, output: 163840 }, + }, + "tngtech/DeepSeek-R1T-Chimera": { + id: "tngtech/DeepSeek-R1T-Chimera", + name: "DeepSeek R1T Chimera", + family: "tngtech", + attachment: false, + reasoning: true, + tool_call: false, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 163840, output: 163840 }, + }, + "tngtech/TNG-R1T-Chimera-TEE": { + id: "tngtech/TNG-R1T-Chimera-TEE", + name: "TNG R1T Chimera TEE", + family: "tngtech", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.25, output: 0.85 }, + limit: { context: 163840, output: 65536 }, + }, + }, + }, + dinference: { + id: "dinference", + env: ["DINFERENCE_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.dinference.com/v1", + name: "DInference", + doc: "https://dinference.com", + models: { + "gpt-oss-120b": { + id: "gpt-oss-120b", + name: "GPT OSS 120B", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-08", + last_updated: "2025-08", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.0675, output: 0.27 }, + limit: { context: 131072, output: 32768 }, + }, + "glm-4.7": { + id: "glm-4.7", + name: "GLM-4.7", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-04", + release_date: "2025-12-22", + last_updated: "2025-12-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.45, output: 1.65 }, + limit: { context: 200000, output: 128000 }, + }, + "glm-5": { + id: "glm-5", + name: "GLM-5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-02-11", + last_updated: "2026-02-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.75, output: 2.4 }, + limit: { context: 200000, output: 128000 }, + }, + "glm-5.1": { + id: "glm-5.1", + name: "GLM-5.1", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-03-27", + last_updated: "2026-03-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 3.89 }, + limit: { context: 200000, output: 128000 }, + }, + "minimax-m2.5": { + id: "minimax-m2.5", + name: "MiniMax-M2.5", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.22, output: 0.88 }, + limit: { context: 200000, output: 32000 }, + }, + }, + }, + vivgrid: { + id: "vivgrid", + env: ["VIVGRID_API_KEY"], + npm: "@ai-sdk/openai", + api: "https://api.vivgrid.com/v1", + name: "Vivgrid", + doc: "https://docs.vivgrid.com/models", + models: { + "gpt-5.1-codex-max": { + id: "gpt-5.1-codex-max", + name: "GPT-5.1 Codex Max", + family: "gpt-codex", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 400000, output: 128000 }, + }, + "gemini-3.1-flash-lite-preview": { + id: "gemini-3.1-flash-lite-preview", + name: "Gemini 3.1 Flash Lite Preview", + family: "gemini-flash-lite", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-03-03", + last_updated: "2026-03-03", + modalities: { input: ["text", "image", "video", "audio", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 1.5, cache_read: 0.025, cache_write: 1 }, + limit: { context: 1048576, output: 65536 }, + provider: { npm: "@ai-sdk/openai-compatible" }, + }, + "gemini-3.1-pro-preview": { + id: "gemini-3.1-pro-preview", + name: "Gemini 3.1 Pro Preview", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-02-19", + last_updated: "2026-02-19", + modalities: { input: ["text", "image", "video", "audio", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 12, cache_read: 0.2, context_over_200k: { input: 4, output: 18, cache_read: 0.4 } }, + limit: { context: 1048576, output: 65536 }, + provider: { npm: "@ai-sdk/openai-compatible" }, + }, + "gpt-5-mini": { + id: "gpt-5-mini", + name: "GPT-5 Mini", + family: "gpt-mini", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-05-30", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 2, cache_read: 0.03 }, + limit: { context: 272000, output: 128000 }, + provider: { npm: "@ai-sdk/openai-compatible" }, + }, + "gpt-5.3-codex": { + id: "gpt-5.3-codex", + name: "GPT-5.3 Codex", + family: "gpt-codex", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-02-24", + last_updated: "2026-02-24", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 400000, output: 128000 }, + }, + "gpt-5.4-mini": { + id: "gpt-5.4-mini", + name: "GPT-5.4 Mini", + family: "gpt-mini", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-17", + last_updated: "2026-03-17", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.75, output: 4.5, cache_read: 0.075 }, + limit: { context: 400000, input: 272000, output: 128000 }, + provider: { npm: "@ai-sdk/openai-compatible" }, + }, + "gpt-5.4-nano": { + id: "gpt-5.4-nano", + name: "GPT-5.4 Nano", + family: "gpt-nano", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-17", + last_updated: "2026-03-17", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 1.25, cache_read: 0.02 }, + limit: { context: 400000, input: 272000, output: 128000 }, + provider: { npm: "@ai-sdk/openai-compatible" }, + }, + "gpt-5.2-codex": { + id: "gpt-5.2-codex", + name: "GPT-5.2 Codex", + family: "gpt-codex", + attachment: false, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-01-14", + last_updated: "2026-01-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 400000, output: 128000 }, + }, + "gpt-5.4": { + id: "gpt-5.4", + name: "GPT-5.4", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-05", + last_updated: "2026-03-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 15, cache_read: 0.25 }, + limit: { context: 400000, input: 272000, output: 128000 }, + provider: { npm: "@ai-sdk/openai-compatible" }, + }, + "deepseek-v3.2": { + id: "deepseek-v3.2", + name: "DeepSeek-V3.2", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2025-12-01", + last_updated: "2025-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.28, output: 0.42 }, + limit: { context: 128000, output: 128000 }, + provider: { npm: "@ai-sdk/openai-compatible" }, + }, + "gpt-5.1-codex": { + id: "gpt-5.1-codex", + name: "GPT-5.1 Codex", + family: "gpt-codex", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 400000, output: 128000 }, + }, + "gpt-5.5": { + id: "gpt-5.5", + name: "GPT-5.5", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-12-01", + release_date: "2026-04-23", + last_updated: "2026-04-23", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 30, cache_read: 0.5, context_over_200k: { input: 10, output: 45, cache_read: 1 } }, + limit: { context: 1050000, input: 922000, output: 128000 }, + provider: { npm: "@ai-sdk/openai-compatible" }, + }, + "deepseek-v4-pro": { + id: "deepseek-v4-pro", + name: "DeepSeek V4 Pro", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-05", + release_date: "2026-04-24", + last_updated: "2026-04-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.74, output: 3.48, cache_read: 0.145 }, + limit: { context: 1000000, output: 384000 }, + provider: { npm: "@ai-sdk/openai-compatible" }, + }, + }, + }, + deepinfra: { + id: "deepinfra", + env: ["DEEPINFRA_API_KEY"], + npm: "@ai-sdk/deepinfra", + name: "Deep Infra", + doc: "https://deepinfra.com/models", + models: { + "Qwen/Qwen3.5-397B-A17B": { + id: "Qwen/Qwen3.5-397B-A17B", + name: "Qwen 3.5 397B A17B", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-02-01", + last_updated: "2026-04-20", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.54, output: 3.4 }, + limit: { context: 262144, output: 81920 }, + }, + "Qwen/Qwen3.5-35B-A3B": { + id: "Qwen/Qwen3.5-35B-A3B", + name: "Qwen 3.5 35B A3B", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-02-01", + last_updated: "2026-04-20", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.95 }, + limit: { context: 262144, output: 81920 }, + }, + "Qwen/Qwen3-Coder-480B-A35B-Instruct-Turbo": { + id: "Qwen/Qwen3-Coder-480B-A35B-Instruct-Turbo", + name: "Qwen3 Coder 480B A35B Instruct Turbo", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-23", + last_updated: "2025-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 262144, output: 66536 }, + }, + "Qwen/Qwen3-Coder-480B-A35B-Instruct": { + id: "Qwen/Qwen3-Coder-480B-A35B-Instruct", + name: "Qwen3 Coder 480B A35B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-23", + last_updated: "2025-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.4, output: 1.6 }, + limit: { context: 262144, output: 66536 }, + }, + "Qwen/Qwen3.6-35B-A3B": { + id: "Qwen/Qwen3.6-35B-A3B", + name: "Qwen3.6 35B A3B", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-01", + last_updated: "2026-04-01", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 1 }, + limit: { context: 262144, output: 81920 }, + }, + "zai-org/GLM-4.7-Flash": { + id: "zai-org/GLM-4.7-Flash", + name: "GLM-4.7-Flash", + family: "glm-flash", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-04", + release_date: "2026-01-19", + last_updated: "2026-01-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.06, output: 0.4 }, + limit: { context: 202752, output: 16384 }, + }, + "zai-org/GLM-4.5": { + id: "zai-org/GLM-4.5", + name: "GLM-4.5", + family: "glm", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-28", + last_updated: "2025-07-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.2 }, + limit: { context: 131072, output: 98304 }, + status: "deprecated", + }, + "zai-org/GLM-4.7": { + id: "zai-org/GLM-4.7", + name: "GLM-4.7", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-04", + release_date: "2025-12-22", + last_updated: "2025-12-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.43, output: 1.75, cache_read: 0.08 }, + limit: { context: 202752, output: 16384 }, + }, + "zai-org/GLM-5.1": { + id: "zai-org/GLM-5.1", + name: "GLM-5.1", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-04-07", + last_updated: "2026-04-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.4, output: 4.4, cache_read: 0.26 }, + limit: { context: 202752, output: 16384 }, + }, + "zai-org/GLM-5": { + id: "zai-org/GLM-5", + name: "GLM-5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-12", + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.8, output: 2.56, cache_read: 0.16 }, + limit: { context: 202752, output: 16384 }, + }, + "zai-org/GLM-4.6V": { + id: "zai-org/GLM-4.6V", + name: "GLM-4.6V", + family: "glm", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-04", + release_date: "2025-09-30", + last_updated: "2025-09-30", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 0.9 }, + limit: { context: 204800, output: 131072 }, + }, + "zai-org/GLM-4.6": { + id: "zai-org/GLM-4.6", + name: "GLM-4.6", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-04", + release_date: "2025-09-30", + last_updated: "2025-09-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.43, output: 1.74, cache_read: 0.08 }, + limit: { context: 204800, output: 131072 }, + }, + "meta-llama/Llama-4-Scout-17B-16E-Instruct": { + id: "meta-llama/Llama-4-Scout-17B-16E-Instruct", + name: "Llama 4 Scout 17B", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + release_date: "2025-04-05", + last_updated: "2025-04-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.08, output: 0.3 }, + limit: { context: 10000000, output: 16384 }, + }, + "meta-llama/Llama-3.1-8B-Instruct": { + id: "meta-llama/Llama-3.1-8B-Instruct", + name: "Llama 3.1 8B", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.02, output: 0.05 }, + limit: { context: 131072, output: 16384 }, + }, + "meta-llama/Llama-3.1-70B-Instruct": { + id: "meta-llama/Llama-3.1-70B-Instruct", + name: "Llama 3.1 70B", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.4, output: 0.4 }, + limit: { context: 131072, output: 16384 }, + }, + "meta-llama/Llama-3.1-8B-Instruct-Turbo": { + id: "meta-llama/Llama-3.1-8B-Instruct-Turbo", + name: "Llama 3.1 8B Turbo", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.02, output: 0.03 }, + limit: { context: 131072, output: 16384 }, + }, + "meta-llama/Llama-3.3-70B-Instruct-Turbo": { + id: "meta-llama/Llama-3.3-70B-Instruct-Turbo", + name: "Llama 3.3 70B Turbo", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.32 }, + limit: { context: 131072, output: 16384 }, + }, + "meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8": { + id: "meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8", + name: "Llama 4 Maverick 17B FP8", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + release_date: "2025-04-05", + last_updated: "2025-04-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 1000000, output: 16384 }, + }, + "meta-llama/Llama-3.1-70B-Instruct-Turbo": { + id: "meta-llama/Llama-3.1-70B-Instruct-Turbo", + name: "Llama 3.1 70B Turbo", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.4, output: 0.4 }, + limit: { context: 131072, output: 16384 }, + }, + "deepseek-ai/DeepSeek-R1-0528": { + id: "deepseek-ai/DeepSeek-R1-0528", + name: "DeepSeek-R1-0528", + attachment: false, + reasoning: true, + tool_call: false, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-07", + release_date: "2025-05-28", + last_updated: "2025-05-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 2.15, cache_read: 0.35 }, + limit: { context: 163840, output: 64000 }, + }, + "deepseek-ai/DeepSeek-V3.2": { + id: "deepseek-ai/DeepSeek-V3.2", + name: "DeepSeek-V3.2", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12", + release_date: "2025-12-02", + last_updated: "2025-12-02", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.26, output: 0.38, cache_read: 0.13 }, + limit: { context: 163840, output: 64000 }, + }, + "openai/gpt-oss-20b": { + id: "openai/gpt-oss-20b", + name: "GPT OSS 20B", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.03, output: 0.14 }, + limit: { context: 131072, output: 16384 }, + }, + "openai/gpt-oss-120b": { + id: "openai/gpt-oss-120b", + name: "GPT OSS 120B", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.05, output: 0.24 }, + limit: { context: 131072, output: 16384 }, + }, + "moonshotai/Kimi-K2-Thinking": { + id: "moonshotai/Kimi-K2-Thinking", + name: "Kimi K2 Thinking", + family: "kimi-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-10", + release_date: "2025-11-06", + last_updated: "2025-11-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.47, output: 2 }, + limit: { context: 131072, output: 32768 }, + }, + "moonshotai/Kimi-K2.6": { + id: "moonshotai/Kimi-K2.6", + name: "Kimi K2.6", + family: "kimi", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2024-04", + release_date: "2026-04-21", + last_updated: "2026-04-21", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.75, output: 3.5, cache_read: 0.15 }, + limit: { context: 262144, output: 16384 }, + }, + "moonshotai/Kimi-K2-Instruct": { + id: "moonshotai/Kimi-K2-Instruct", + name: "Kimi K2", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-07-11", + last_updated: "2025-07-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.5, output: 2 }, + limit: { context: 131072, output: 32768 }, + }, + "moonshotai/Kimi-K2-Instruct-0905": { + id: "moonshotai/Kimi-K2-Instruct-0905", + name: "Kimi K2 0905", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-09-05", + last_updated: "2025-09-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.4, output: 2, cache_read: 0.15 }, + limit: { context: 262144, output: 262144 }, + }, + "moonshotai/Kimi-K2.5": { + id: "moonshotai/Kimi-K2.5", + name: "Kimi K2.5", + family: "kimi", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-01-27", + last_updated: "2026-01-27", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.5, output: 2.8 }, + limit: { context: 262144, output: 32768 }, + }, + "MiniMaxAI/MiniMax-M2": { + id: "MiniMaxAI/MiniMax-M2", + name: "MiniMax M2", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-10", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.254, output: 1.02 }, + limit: { context: 262144, output: 32768 }, + }, + "MiniMaxAI/MiniMax-M2.5": { + id: "MiniMaxAI/MiniMax-M2.5", + name: "MiniMax M2.5", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-06", + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.27, output: 0.95, cache_read: 0.03, cache_write: 0.375 }, + limit: { context: 204800, output: 131072 }, + }, + "MiniMaxAI/MiniMax-M2.1": { + id: "MiniMaxAI/MiniMax-M2.1", + name: "MiniMax M2.1", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-06", + release_date: "2025-12-23", + last_updated: "2025-12-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.28, output: 1.2 }, + limit: { context: 196608, output: 196608 }, + }, + "anthropic/claude-3-7-sonnet-latest": { + id: "anthropic/claude-3-7-sonnet-latest", + name: "Claude Sonnet 3.7 (Latest)", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10-31", + release_date: "2025-03-13", + last_updated: "2025-03-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 3.3, output: 16.5, cache_read: 0.33 }, + limit: { context: 200000, output: 64000 }, + }, + "anthropic/claude-4-opus": { + id: "anthropic/claude-4-opus", + name: "Claude Opus 4", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-06-12", + last_updated: "2025-06-12", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 16.5, output: 82.5 }, + limit: { context: 200000, output: 32000 }, + }, + "deepseek-ai/DeepSeek-V4-Flash": { + id: "deepseek-ai/DeepSeek-V4-Flash", + name: "DeepSeek V4 Flash", + family: "deepseek-flash", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-05", + release_date: "2026-04-24", + last_updated: "2026-04-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.14, output: 0.28, cache_read: 0.028 }, + limit: { context: 1000000, output: 384000 }, + }, + "deepseek-ai/DeepSeek-V4-Pro": { + id: "deepseek-ai/DeepSeek-V4-Pro", + name: "DeepSeek V4 Pro", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-05", + release_date: "2026-04-24", + last_updated: "2026-04-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.74, output: 3.48, cache_read: 0.145 }, + limit: { context: 65536, output: 65536 }, + }, + "google/gemma-4-26B-A4B-it": { + id: "google/gemma-4-26B-A4B-it", + name: "Gemma 4 26B", + family: "gemma", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-04-02", + last_updated: "2026-04-02", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.07, output: 0.34 }, + limit: { context: 256000, output: 8192 }, + }, + "google/gemma-4-31B-it": { + id: "google/gemma-4-31B-it", + name: "Gemma 4 31B", + family: "gemma", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-04-02", + last_updated: "2026-04-02", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.13, output: 0.38 }, + limit: { context: 256000, output: 8192 }, + }, + }, + }, + "qiniu-ai": { + id: "qiniu-ai", + env: ["QINIU_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.qnaigc.com/v1", + name: "Qiniu", + doc: "https://developer.qiniu.com/aitokenapi", + models: { + "qwen3-235b-a22b": { + id: "qwen3-235b-a22b", + name: "Qwen 3 235B A22B", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 128000, output: 32000 }, + }, + "doubao-seed-1.6-flash": { + id: "doubao-seed-1.6-flash", + name: "Doubao-Seed 1.6 Flash", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-08-15", + last_updated: "2025-08-15", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + limit: { context: 256000, output: 32000 }, + }, + "qwen3-235b-a22b-instruct-2507": { + id: "qwen3-235b-a22b-instruct-2507", + name: "Qwen3 235b A22B Instruct 2507", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-08-12", + last_updated: "2025-08-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 262144, output: 64000 }, + }, + "doubao-seed-2.0-code": { + id: "doubao-seed-2.0-code", + name: "Doubao Seed 2.0 Code", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2026-02-14", + last_updated: "2026-02-14", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + limit: { context: 256000, output: 128000 }, + }, + "deepseek-v3-0324": { + id: "deepseek-v3-0324", + name: "DeepSeek-V3-0324", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 128000, output: 16000 }, + }, + "doubao-1.5-thinking-pro": { + id: "doubao-1.5-thinking-pro", + name: "Doubao 1.5 Thinking Pro", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 128000, output: 16000 }, + }, + "claude-3.7-sonnet": { + id: "claude-3.7-sonnet", + name: "Claude 3.7 Sonnet", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + limit: { context: 200000, output: 128000 }, + }, + "qwen3.5-397b-a17b": { + id: "qwen3.5-397b-a17b", + name: "Qwen3.5 397B A17B", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2026-02-22", + last_updated: "2026-02-22", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + limit: { context: 256000, output: 64000 }, + }, + "qwen-vl-max-2025-01-25": { + id: "qwen-vl-max-2025-01-25", + name: "Qwen VL-MAX-2025-01-25", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text", "image", "audio", "video"], output: ["text"] }, + open_weights: false, + limit: { context: 128000, output: 4096 }, + }, + "qwen3-32b": { + id: "qwen3-32b", + name: "Qwen3 32B", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 40000, output: 4096 }, + }, + "doubao-1.5-pro-32k": { + id: "doubao-1.5-pro-32k", + name: "Doubao 1.5 Pro 32k", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 128000, output: 12000 }, + }, + "qwen2.5-vl-72b-instruct": { + id: "qwen2.5-vl-72b-instruct", + name: "Qwen 2.5 VL 72B Instruct", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text", "image", "audio", "video"], output: ["text"] }, + open_weights: false, + limit: { context: 128000, output: 8192 }, + }, + "gemini-2.0-flash": { + id: "gemini-2.0-flash", + name: "Gemini 2.0 Flash", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text", "image", "audio", "video"], output: ["text"] }, + open_weights: false, + limit: { context: 1048576, output: 8192 }, + }, + "qwen3-vl-30b-a3b-thinking": { + id: "qwen3-vl-30b-a3b-thinking", + name: "Qwen3-Vl 30b A3b Thinking", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2026-02-09", + last_updated: "2026-02-09", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + limit: { context: 128000, output: 32000 }, + }, + "gemini-3.0-pro-image-preview": { + id: "gemini-3.0-pro-image-preview", + name: "Gemini 3.0 Pro Image Preview", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2025-11-20", + last_updated: "2025-11-20", + modalities: { input: ["text", "image"], output: ["text", "image"] }, + open_weights: false, + limit: { context: 32768, output: 8192 }, + }, + "gemini-2.5-pro": { + id: "gemini-2.5-pro", + name: "Gemini 2.5 Pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text", "image", "video", "audio"], output: ["text"] }, + open_weights: false, + limit: { context: 1048576, output: 65536 }, + }, + "claude-4.5-opus": { + id: "claude-4.5-opus", + name: "Claude 4.5 Opus", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-11-25", + last_updated: "2025-11-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + limit: { context: 200000, output: 200000 }, + }, + "deepseek-r1": { + id: "deepseek-r1", + name: "DeepSeek-R1", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 128000, output: 32000 }, + }, + "claude-4.0-opus": { + id: "claude-4.0-opus", + name: "Claude 4.0 Opus", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + limit: { context: 200000, output: 32000 }, + }, + "claude-4.5-haiku": { + id: "claude-4.5-haiku", + name: "Claude 4.5 Haiku", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-10-16", + last_updated: "2025-10-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + limit: { context: 200000, output: 64000 }, + }, + "qwen3-max": { + id: "qwen3-max", + name: "Qwen3 Max", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-09-24", + last_updated: "2025-09-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 262144, output: 65536 }, + }, + "gemini-3.0-flash-preview": { + id: "gemini-3.0-flash-preview", + name: "Gemini 3.0 Flash Preview", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-12-18", + last_updated: "2025-12-18", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + limit: { context: 1000000, output: 64000 }, + }, + "gemini-2.5-flash-image": { + id: "gemini-2.5-flash-image", + name: "Gemini 2.5 Flash Image", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2025-10-22", + last_updated: "2025-10-22", + modalities: { input: ["text", "image"], output: ["image"] }, + open_weights: false, + limit: { context: 32768, output: 8192 }, + }, + "glm-4.5": { + id: "glm-4.5", + name: "GLM 4.5", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 131072, output: 98304 }, + }, + "claude-3.5-sonnet": { + id: "claude-3.5-sonnet", + name: "Claude 3.5 Sonnet", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-09-09", + last_updated: "2025-09-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + limit: { context: 200000, output: 8200 }, + }, + "claude-4.0-sonnet": { + id: "claude-4.0-sonnet", + name: "Claude 4.0 Sonnet", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + limit: { context: 200000, output: 64000 }, + }, + "qwen3-30b-a3b-instruct-2507": { + id: "qwen3-30b-a3b-instruct-2507", + name: "Qwen3 30b A3b Instruct 2507", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2026-02-04", + last_updated: "2026-02-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 128000, output: 32000 }, + }, + "doubao-seed-1.6-thinking": { + id: "doubao-seed-1.6-thinking", + name: "Doubao-Seed 1.6 Thinking", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-08-15", + last_updated: "2025-08-15", + modalities: { input: ["image", "text", "video"], output: ["text"] }, + open_weights: false, + limit: { context: 256000, output: 32000 }, + }, + "gemini-2.5-flash": { + id: "gemini-2.5-flash", + name: "Gemini 2.5 Flash", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text", "image", "audio", "video"], output: ["text"] }, + open_weights: false, + limit: { context: 1048576, output: 64000 }, + }, + "qwen3-235b-a22b-thinking-2507": { + id: "qwen3-235b-a22b-thinking-2507", + name: "Qwen3 235B A22B Thinking 2507", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-08-12", + last_updated: "2025-08-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 262144, output: 4096 }, + }, + "qwen3-next-80b-a3b-thinking": { + id: "qwen3-next-80b-a3b-thinking", + name: "Qwen3 Next 80B A3B Thinking", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-09-12", + last_updated: "2025-09-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 131072, output: 32768 }, + }, + "qwen3-30b-a3b-thinking-2507": { + id: "qwen3-30b-a3b-thinking-2507", + name: "Qwen3 30b A3b Thinking 2507", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2026-02-04", + last_updated: "2026-02-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 126000, output: 32000 }, + }, + "glm-4.5-air": { + id: "glm-4.5-air", + name: "GLM 4.5 Air", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 131000, output: 4096 }, + }, + "deepseek-v3.1": { + id: "deepseek-v3.1", + name: "DeepSeek-V3.1", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-08-19", + last_updated: "2025-08-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 128000, output: 32000 }, + }, + "qwen3-30b-a3b": { + id: "qwen3-30b-a3b", + name: "Qwen3 30B A3B", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 40000, output: 4096 }, + }, + "claude-4.1-opus": { + id: "claude-4.1-opus", + name: "Claude 4.1 Opus", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-08-06", + last_updated: "2025-08-06", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + limit: { context: 200000, output: 32000 }, + }, + "doubao-seed-2.0-mini": { + id: "doubao-seed-2.0-mini", + name: "Doubao Seed 2.0 Mini", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2026-02-14", + last_updated: "2026-02-14", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + limit: { context: 256000, output: 32000 }, + }, + "qwen3-next-80b-a3b-instruct": { + id: "qwen3-next-80b-a3b-instruct", + name: "Qwen3 Next 80B A3B Instruct", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-09-12", + last_updated: "2025-09-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 131072, output: 32768 }, + }, + "doubao-seed-1.6": { + id: "doubao-seed-1.6", + name: "Doubao-Seed 1.6", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-08-15", + last_updated: "2025-08-15", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + limit: { context: 256000, output: 32000 }, + }, + "qwen2.5-vl-7b-instruct": { + id: "qwen2.5-vl-7b-instruct", + name: "Qwen 2.5 VL 7B Instruct", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text", "image", "audio", "video"], output: ["text"] }, + open_weights: false, + limit: { context: 128000, output: 8192 }, + }, + "kling-v2-6": { + id: "kling-v2-6", + name: "Kling-V2 6", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2026-01-13", + last_updated: "2026-01-13", + modalities: { input: ["text", "image", "video"], output: ["video"] }, + open_weights: false, + limit: { context: 99999999, output: 99999999 }, + }, + "MiniMax-M1": { + id: "MiniMax-M1", + name: "MiniMax M1", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 1000000, output: 80000 }, + }, + "gemini-3.0-pro-preview": { + id: "gemini-3.0-pro-preview", + name: "Gemini 3.0 Pro Preview", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-11-19", + last_updated: "2025-11-19", + modalities: { input: ["text", "image", "video", "pdf", "audio"], output: ["text"] }, + open_weights: false, + limit: { context: 1000000, output: 64000 }, + }, + "doubao-seed-2.0-lite": { + id: "doubao-seed-2.0-lite", + name: "Doubao Seed 2.0 Lite", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2026-02-14", + last_updated: "2026-02-14", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + limit: { context: 256000, output: 32000 }, + }, + "qwen3-coder-480b-a35b-instruct": { + id: "qwen3-coder-480b-a35b-instruct", + name: "Qwen3 Coder 480B A35B Instruct", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-08-14", + last_updated: "2025-08-14", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 262000, output: 4096 }, + }, + "claude-3.5-haiku": { + id: "claude-3.5-haiku", + name: "Claude 3.5 Haiku", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-08-26", + last_updated: "2025-08-26", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + limit: { context: 200000, output: 8192 }, + }, + "gpt-oss-20b": { + id: "gpt-oss-20b", + name: "gpt-oss-20b", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-08-06", + last_updated: "2025-08-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 128000, output: 4096 }, + }, + "qwen-turbo": { + id: "qwen-turbo", + name: "Qwen-Turbo", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 1000000, output: 4096 }, + }, + "kimi-k2": { + id: "kimi-k2", + name: "Kimi K2", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 128000, output: 128000 }, + }, + "gemini-2.5-flash-lite": { + id: "gemini-2.5-flash-lite", + name: "Gemini 2.5 Flash Lite", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text", "image", "audio", "video"], output: ["text"] }, + open_weights: false, + limit: { context: 1048576, output: 64000 }, + }, + "qwen3-max-preview": { + id: "qwen3-max-preview", + name: "Qwen3 Max Preview", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-09-06", + last_updated: "2025-09-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 256000, output: 64000 }, + }, + "gpt-oss-120b": { + id: "gpt-oss-120b", + name: "gpt-oss-120b", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-08-06", + last_updated: "2025-08-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 128000, output: 4096 }, + }, + "doubao-1.5-vision-pro": { + id: "doubao-1.5-vision-pro", + name: "Doubao 1.5 Vision Pro", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + limit: { context: 128000, output: 16000 }, + }, + "claude-4.5-sonnet": { + id: "claude-4.5-sonnet", + name: "Claude 4.5 Sonnet", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-09-30", + last_updated: "2025-09-30", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + limit: { context: 200000, output: 64000 }, + }, + "deepseek-v3": { + id: "deepseek-v3", + name: "DeepSeek-V3", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2025-08-13", + last_updated: "2025-08-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 128000, output: 16000 }, + }, + "deepseek-r1-0528": { + id: "deepseek-r1-0528", + name: "DeepSeek-R1-0528", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 128000, output: 32000 }, + }, + "gemini-2.0-flash-lite": { + id: "gemini-2.0-flash-lite", + name: "Gemini 2.0 Flash Lite", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text", "image", "audio", "video"], output: ["text"] }, + open_weights: false, + limit: { context: 1048576, output: 8192 }, + }, + "qwen-max-2025-01-25": { + id: "qwen-max-2025-01-25", + name: "Qwen2.5-Max-2025-01-25", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 128000, output: 4096 }, + }, + "doubao-seed-2.0-pro": { + id: "doubao-seed-2.0-pro", + name: "Doubao Seed 2.0 Pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2026-02-14", + last_updated: "2026-02-14", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + limit: { context: 256000, output: 128000 }, + }, + "deepseek/deepseek-v3.2-exp-thinking": { + id: "deepseek/deepseek-v3.2-exp-thinking", + name: "DeepSeek/DeepSeek-V3.2-Exp-Thinking", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 128000, output: 32000 }, + }, + "deepseek/deepseek-v3.1-terminus-thinking": { + id: "deepseek/deepseek-v3.1-terminus-thinking", + name: "DeepSeek/DeepSeek-V3.1-Terminus-Thinking", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2025-09-22", + last_updated: "2025-09-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 128000, output: 32000 }, + }, + "deepseek/deepseek-v3.2-exp": { + id: "deepseek/deepseek-v3.2-exp", + name: "DeepSeek/DeepSeek-V3.2-Exp", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 128000, output: 32000 }, + }, + "deepseek/deepseek-v3.2-251201": { + id: "deepseek/deepseek-v3.2-251201", + name: "Deepseek/DeepSeek-V3.2", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-12-01", + last_updated: "2025-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 128000, output: 32000 }, + }, + "deepseek/deepseek-math-v2": { + id: "deepseek/deepseek-math-v2", + name: "Deepseek/Deepseek-Math-V2", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2025-12-04", + last_updated: "2025-12-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 160000, output: 160000 }, + }, + "deepseek/deepseek-v3.1-terminus": { + id: "deepseek/deepseek-v3.1-terminus", + name: "DeepSeek/DeepSeek-V3.1-Terminus", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-09-22", + last_updated: "2025-09-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 128000, output: 32000 }, + }, + "stepfun-ai/gelab-zero-4b-preview": { + id: "stepfun-ai/gelab-zero-4b-preview", + name: "Stepfun-Ai/Gelab Zero 4b Preview", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-12-23", + last_updated: "2025-12-23", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + limit: { context: 8192, output: 4096 }, + }, + "stepfun/step-3.5-flash": { + id: "stepfun/step-3.5-flash", + name: "Stepfun/Step-3.5 Flash", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2026-02-02", + last_updated: "2026-02-02", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + limit: { context: 64000, output: 4096 }, + }, + "x-ai/grok-4-fast": { + id: "x-ai/grok-4-fast", + name: "x-AI/Grok-4-Fast", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-09-20", + last_updated: "2025-09-20", + modalities: { input: ["text", "image", "audio", "video"], output: ["text"] }, + open_weights: false, + limit: { context: 2000000, output: 2000000 }, + }, + "x-ai/grok-code-fast-1": { + id: "x-ai/grok-code-fast-1", + name: "x-AI/Grok-Code-Fast 1", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-09-02", + last_updated: "2025-09-02", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 256000, output: 10000 }, + }, + "x-ai/grok-4-fast-reasoning": { + id: "x-ai/grok-4-fast-reasoning", + name: "X-Ai/Grok-4-Fast-Reasoning", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-12-18", + last_updated: "2025-12-18", + modalities: { input: ["text", "image", "audio", "video"], output: ["text"] }, + open_weights: false, + limit: { context: 2000000, output: 2000000 }, + }, + "x-ai/grok-4.1-fast-non-reasoning": { + id: "x-ai/grok-4.1-fast-non-reasoning", + name: "X-Ai/Grok 4.1 Fast Non Reasoning", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-12-19", + last_updated: "2025-12-19", + modalities: { input: ["text", "image", "audio", "video"], output: ["text"] }, + open_weights: false, + limit: { context: 2000000, output: 2000000 }, + }, + "x-ai/grok-4.1-fast": { + id: "x-ai/grok-4.1-fast", + name: "x-AI/Grok-4.1-Fast", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-11-20", + last_updated: "2025-11-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 2000000, output: 2000000 }, + }, + "x-ai/grok-4-fast-non-reasoning": { + id: "x-ai/grok-4-fast-non-reasoning", + name: "X-Ai/Grok-4-Fast-Non-Reasoning", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-12-18", + last_updated: "2025-12-18", + modalities: { input: ["text", "image", "audio", "video"], output: ["text"] }, + open_weights: false, + limit: { context: 2000000, output: 2000000 }, + }, + "x-ai/grok-4.1-fast-reasoning": { + id: "x-ai/grok-4.1-fast-reasoning", + name: "X-Ai/Grok 4.1 Fast Reasoning", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-12-19", + last_updated: "2025-12-19", + modalities: { input: ["text", "image", "audio", "video"], output: ["text"] }, + open_weights: false, + limit: { context: 20000000, output: 2000000 }, + }, + "openai/gpt-5.2": { + id: "openai/gpt-5.2", + name: "OpenAI/GPT-5.2", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-12-11", + last_updated: "2025-12-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-5": { + id: "openai/gpt-5", + name: "OpenAI/GPT-5", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-09-19", + last_updated: "2025-09-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 400000, output: 128000 }, + }, + "z-ai/glm-4.7": { + id: "z-ai/glm-4.7", + name: "Z-Ai/GLM 4.7", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-12-23", + last_updated: "2025-12-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 200000, output: 200000 }, + }, + "z-ai/glm-5": { + id: "z-ai/glm-5", + name: "Z-Ai/GLM 5", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 200000, output: 128000 }, + }, + "z-ai/autoglm-phone-9b": { + id: "z-ai/autoglm-phone-9b", + name: "Z-Ai/Autoglm Phone 9b", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-12-23", + last_updated: "2025-12-23", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + limit: { context: 12800, output: 4096 }, + }, + "z-ai/glm-4.6": { + id: "z-ai/glm-4.6", + name: "Z-AI/GLM 4.6", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-10-11", + last_updated: "2025-10-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 200000, output: 200000 }, + }, + "minimax/minimax-m2": { + id: "minimax/minimax-m2", + name: "Minimax/Minimax-M2", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-10-28", + last_updated: "2025-10-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 200000, output: 128000 }, + }, + "minimax/minimax-m2.1": { + id: "minimax/minimax-m2.1", + name: "Minimax/Minimax-M2.1", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-12-23", + last_updated: "2025-12-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 204800, output: 128000 }, + }, + "minimax/minimax-m2.5": { + id: "minimax/minimax-m2.5", + name: "Minimax/Minimax-M2.5", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 204800, output: 128000 }, + }, + "minimax/minimax-m2.5-highspeed": { + id: "minimax/minimax-m2.5-highspeed", + name: "Minimax/Minimax-M2.5 Highspeed", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2026-02-14", + last_updated: "2026-02-14", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 204800, output: 128000 }, + }, + "moonshotai/kimi-k2.5": { + id: "moonshotai/kimi-k2.5", + name: "Moonshotai/Kimi-K2.5", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2026-01-28", + last_updated: "2026-01-28", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + limit: { context: 256000, output: 256000 }, + }, + "moonshotai/kimi-k2-0905": { + id: "moonshotai/kimi-k2-0905", + name: "Kimi K2 0905", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-09-08", + last_updated: "2025-09-08", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 256000, output: 100000 }, + }, + "moonshotai/kimi-k2-thinking": { + id: "moonshotai/kimi-k2-thinking", + name: "Kimi K2 Thinking", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-11-07", + last_updated: "2025-11-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 256000, output: 100000 }, + }, + "meituan/longcat-flash-chat": { + id: "meituan/longcat-flash-chat", + name: "Meituan/Longcat-Flash-Chat", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2025-11-05", + last_updated: "2025-11-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 131072, output: 131072 }, + }, + "meituan/longcat-flash-lite": { + id: "meituan/longcat-flash-lite", + name: "Meituan/Longcat-Flash-Lite", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2026-02-06", + last_updated: "2026-02-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 256000, output: 320000 }, + }, + "mimo-v2-flash": { + id: "mimo-v2-flash", + name: "Mimo-V2-Flash", + family: "mimo", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-12-01", + release_date: "2025-12-16", + last_updated: "2026-02-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.3, cache_read: 0.01 }, + limit: { context: 256000, output: 256000 }, + }, + "xiaomi/mimo-v2-flash": { + id: "xiaomi/mimo-v2-flash", + name: "Xiaomi/Mimo-V2-Flash", + family: "mimo", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-12-01", + release_date: "2025-12-16", + last_updated: "2026-02-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.3, cache_read: 0.01 }, + limit: { context: 256000, output: 256000 }, + }, + }, + }, + kilo: { + id: "kilo", + env: ["KILO_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.kilo.ai/api/gateway", + name: "Kilo Gateway", + doc: "https://kilo.ai", + models: { + "rekaai/reka-edge": { + id: "rekaai/reka-edge", + name: "Reka Edge", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2026-03-20", + last_updated: "2026-04-11", + modalities: { input: ["image", "text", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.1 }, + limit: { context: 16384, output: 16384 }, + }, + "rekaai/reka-flash-3": { + id: "rekaai/reka-flash-3", + name: "Reka Flash 3", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2025-03-12", + last_updated: "2026-04-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.2 }, + limit: { context: 65536, output: 65536 }, + }, + "ai21/jamba-large-1.7": { + id: "ai21/jamba-large-1.7", + name: "AI21: Jamba Large 1.7", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-08-09", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 8 }, + limit: { context: 256000, output: 4096 }, + }, + "alibaba/tongyi-deepresearch-30b-a3b": { + id: "alibaba/tongyi-deepresearch-30b-a3b", + name: "Tongyi DeepResearch 30B A3B", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-09-18", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.09, output: 0.45 }, + limit: { context: 131072, output: 131072 }, + }, + "inflection/inflection-3-pi": { + id: "inflection/inflection-3-pi", + name: "Inflection: Inflection 3 Pi", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2024-10-11", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 10 }, + limit: { context: 8000, output: 1024 }, + }, + "inflection/inflection-3-productivity": { + id: "inflection/inflection-3-productivity", + name: "Inflection: Inflection 3 Productivity", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2024-10-11", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 10 }, + limit: { context: 8000, output: 1024 }, + }, + "liquid/lfm-2-24b-a2b": { + id: "liquid/lfm-2-24b-a2b", + name: "LiquidAI: LFM2-24B-A2B", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2026-02-26", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.03, output: 0.12 }, + limit: { context: 32768, output: 32768 }, + }, + "writer/palmyra-x5": { + id: "writer/palmyra-x5", + name: "Writer: Palmyra X5", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-04-28", + last_updated: "2025-04-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.6, output: 6 }, + limit: { context: 1040000, output: 8192 }, + }, + "ibm-granite/granite-4.1-8b": { + id: "ibm-granite/granite-4.1-8b", + name: "IBM: Granite 4.1 8B", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2026-04-30", + last_updated: "2026-05-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.05, output: 0.1, cache_read: 0.05 }, + limit: { context: 131072, output: 131072 }, + }, + "ibm-granite/granite-4.0-h-micro": { + id: "ibm-granite/granite-4.0-h-micro", + name: "IBM: Granite 4.0 Micro", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-10-20", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.017, output: 0.11 }, + limit: { context: 131000, output: 32768 }, + }, + "essentialai/rnj-1-instruct": { + id: "essentialai/rnj-1-instruct", + name: "EssentialAI: Rnj 1 Instruct", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-12-05", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.15 }, + limit: { context: 32768, output: 6554 }, + }, + "perplexity/sonar-pro": { + id: "perplexity/sonar-pro", + name: "Perplexity: Sonar Pro", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2024-01-01", + last_updated: "2025-09-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15 }, + limit: { context: 200000, output: 8000 }, + }, + "perplexity/sonar-deep-research": { + id: "perplexity/sonar-deep-research", + name: "Perplexity: Sonar Deep Research", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2025-01-27", + last_updated: "2025-01-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 8 }, + limit: { context: 128000, output: 25600 }, + }, + "perplexity/sonar": { + id: "perplexity/sonar", + name: "Perplexity: Sonar", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2024-01-01", + last_updated: "2025-09-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 1 }, + limit: { context: 127072, output: 25415 }, + }, + "perplexity/sonar-pro-search": { + id: "perplexity/sonar-pro-search", + name: "Perplexity: Sonar Pro Search", + attachment: true, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2025-10-31", + last_updated: "2026-03-15", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15 }, + limit: { context: 200000, output: 8000 }, + }, + "perplexity/sonar-reasoning-pro": { + id: "perplexity/sonar-reasoning-pro", + name: "Perplexity: Sonar Reasoning Pro", + attachment: true, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2024-01-01", + last_updated: "2025-09-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 8 }, + limit: { context: 128000, output: 25600 }, + }, + "deepseek/deepseek-chat-v3.1": { + id: "deepseek/deepseek-chat-v3.1", + name: "DeepSeek: DeepSeek V3.1", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-21", + last_updated: "2025-08-21", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.75 }, + limit: { context: 32768, output: 7168 }, + }, + "deepseek/deepseek-chat": { + id: "deepseek/deepseek-chat", + name: "DeepSeek: DeepSeek V3", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-12-01", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.32, output: 0.89, cache_read: 0.15 }, + limit: { context: 163840, output: 163840 }, + }, + "deepseek/deepseek-r1-distill-llama-70b": { + id: "deepseek/deepseek-r1-distill-llama-70b", + name: "DeepSeek: R1 Distill Llama 70B", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2025-01-23", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.7, output: 0.8, cache_read: 0.015 }, + limit: { context: 131072, output: 16384 }, + }, + "deepseek/deepseek-r1": { + id: "deepseek/deepseek-r1", + name: "DeepSeek: R1", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-01-20", + last_updated: "2025-01-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.7, output: 2.5 }, + limit: { context: 64000, output: 16000 }, + }, + "deepseek/deepseek-v3.2-speciale": { + id: "deepseek/deepseek-v3.2-speciale", + name: "DeepSeek: DeepSeek V3.2 Speciale", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2025-12-01", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.4, output: 1.2, cache_read: 0.135 }, + limit: { context: 163840, output: 163840 }, + }, + "deepseek/deepseek-r1-distill-qwen-32b": { + id: "deepseek/deepseek-r1-distill-qwen-32b", + name: "DeepSeek: R1 Distill Qwen 32B", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2025-01-01", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.29, output: 0.29 }, + limit: { context: 32768, output: 32768 }, + }, + "deepseek/deepseek-v3.2-exp": { + id: "deepseek/deepseek-v3.2-exp", + name: "DeepSeek: DeepSeek V3.2 Exp", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-01-01", + last_updated: "2025-09-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.27, output: 0.41 }, + limit: { context: 163840, output: 65536 }, + }, + "deepseek/deepseek-v4-flash": { + id: "deepseek/deepseek-v4-flash", + name: "DeepSeek: DeepSeek V4 Flash", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-24", + last_updated: "2026-05-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.14, output: 0.28, cache_read: 0.0028 }, + limit: { context: 1048576, output: 384000 }, + }, + "deepseek/deepseek-v4-pro": { + id: "deepseek/deepseek-v4-pro", + name: "DeepSeek: DeepSeek V4 Pro", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-24", + last_updated: "2026-05-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.435, output: 0.87, cache_read: 0.003625 }, + limit: { context: 1048576, output: 384000 }, + }, + "deepseek/deepseek-v3.2": { + id: "deepseek/deepseek-v3.2", + name: "DeepSeek: DeepSeek V3.2", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-12-01", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.26, output: 0.38, cache_read: 0.125 }, + limit: { context: 163840, output: 65536 }, + }, + "deepseek/deepseek-chat-v3-0324": { + id: "deepseek/deepseek-chat-v3-0324", + name: "DeepSeek: DeepSeek V3 0324", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-03-24", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.77, cache_read: 0.095 }, + limit: { context: 163840, output: 65536 }, + }, + "deepseek/deepseek-r1-0528": { + id: "deepseek/deepseek-r1-0528", + name: "DeepSeek: R1 0528", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-05-28", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.45, output: 2.15, cache_read: 0.2 }, + limit: { context: 163840, output: 65536 }, + }, + "deepseek/deepseek-v3.1-terminus": { + id: "deepseek/deepseek-v3.1-terminus", + name: "DeepSeek: DeepSeek V3.1 Terminus", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-09-22", + last_updated: "2025-09-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.21, output: 0.79, cache_read: 0.13 }, + limit: { context: 163840, output: 32768 }, + }, + "openrouter/auto": { + id: "openrouter/auto", + name: "Auto Router", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-15", + last_updated: "2026-03-15", + modalities: { input: ["audio", "image", "pdf", "text", "video"], output: ["image", "text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 2000000, output: 32768 }, + }, + "openrouter/bodybuilder": { + id: "openrouter/bodybuilder", + name: "Body Builder (beta)", + attachment: false, + reasoning: false, + tool_call: false, + release_date: "2026-03-15", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 32768 }, + status: "beta", + }, + "openrouter/owl-alpha": { + id: "openrouter/owl-alpha", + name: "Owl Alpha", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-04-28", + last_updated: "2026-04-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 1048756, output: 262144 }, + status: "alpha", + }, + "openrouter/pareto-code": { + id: "openrouter/pareto-code", + name: "Pareto Code Router", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2026-04-21", + last_updated: "2026-05-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 200000, output: 65536 }, + }, + "openrouter/free": { + id: "openrouter/free", + name: "Free Models Router", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-01", + last_updated: "2026-03-15", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 200000, output: 32768 }, + }, + "inclusionai/ling-2.6-1t:free": { + id: "inclusionai/ling-2.6-1t:free", + name: "inclusionAI: Ling-2.6-1T (free)", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2026-04-23", + last_updated: "2026-05-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 262144, output: 32768 }, + }, + "inclusionai/ling-2.6-flash": { + id: "inclusionai/ling-2.6-flash", + name: "inclusionAI: Ling-2.6 Flash", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2026-04-21", + last_updated: "2026-05-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.08, output: 0.24, cache_read: 0.016 }, + limit: { context: 262144, output: 32768 }, + }, + "arcee-ai/trinity-mini": { + id: "arcee-ai/trinity-mini", + name: "Arcee AI: Trinity Mini", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-12", + last_updated: "2026-01-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.045, output: 0.15 }, + limit: { context: 131072, output: 131072 }, + }, + "arcee-ai/virtuoso-large": { + id: "arcee-ai/virtuoso-large", + name: "Arcee AI: Virtuoso Large", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-05-06", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.75, output: 1.2 }, + limit: { context: 131072, output: 64000 }, + }, + "arcee-ai/trinity-large-thinking": { + id: "arcee-ai/trinity-large-thinking", + name: "Arcee AI: Trinity Large Thinking", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-01", + last_updated: "2026-04-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.22, output: 0.85 }, + limit: { context: 262144, output: 262144 }, + }, + "arcee-ai/spotlight": { + id: "arcee-ai/spotlight", + name: "Arcee AI: Spotlight", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-05-06", + last_updated: "2026-03-15", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.18, output: 0.18 }, + limit: { context: 131072, output: 65537 }, + }, + "arcee-ai/maestro-reasoning": { + id: "arcee-ai/maestro-reasoning", + name: "Arcee AI: Maestro Reasoning", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-05-06", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.9, output: 3.3 }, + limit: { context: 131072, output: 32000 }, + }, + "arcee-ai/coder-large": { + id: "arcee-ai/coder-large", + name: "Arcee AI: Coder Large", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-05-06", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.5, output: 0.8 }, + limit: { context: 32768, output: 32768 }, + }, + "arcee-ai/trinity-large-preview": { + id: "arcee-ai/trinity-large-preview", + name: "Arcee AI: Trinity Large Preview", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2026-01-28", + last_updated: "2026-05-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.45 }, + limit: { context: 131000, output: 32768 }, + }, + "deepcogito/cogito-v2.1-671b": { + id: "deepcogito/cogito-v2.1-671b", + name: "Deep Cogito: Cogito v2.1 671B", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2025-11-14", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.25, output: 1.25 }, + limit: { context: 128000, output: 32768 }, + }, + "upstage/solar-pro-3": { + id: "upstage/solar-pro-3", + name: "Upstage: Solar Pro 3", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-01-27", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 128000, output: 32768 }, + }, + "nex-agi/deepseek-v3.1-nex-n1": { + id: "nex-agi/deepseek-v3.1-nex-n1", + name: "Nex AGI: DeepSeek V3.1 Nex N1", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-01-01", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.27, output: 1 }, + limit: { context: 131072, output: 163840 }, + }, + "bytedance-seed/seed-1.6": { + id: "bytedance-seed/seed-1.6", + name: "ByteDance Seed: Seed 1.6", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-09", + last_updated: "2025-09", + modalities: { input: ["image", "text", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 2 }, + limit: { context: 262144, output: 32768 }, + }, + "bytedance-seed/seed-2.0-lite": { + id: "bytedance-seed/seed-2.0-lite", + name: "ByteDance Seed: Seed-2.0-Lite", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-10", + last_updated: "2026-03-15", + modalities: { input: ["image", "text", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.25, output: 2 }, + limit: { context: 262144, output: 131072 }, + }, + "bytedance-seed/seed-1.6-flash": { + id: "bytedance-seed/seed-1.6-flash", + name: "ByteDance Seed: Seed 1.6 Flash", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-12-23", + last_updated: "2026-03-15", + modalities: { input: ["image", "text", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.075, output: 0.3 }, + limit: { context: 262144, output: 32768 }, + }, + "bytedance-seed/seed-2.0-mini": { + id: "bytedance-seed/seed-2.0-mini", + name: "ByteDance Seed: Seed-2.0-Mini", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-27", + last_updated: "2026-03-15", + modalities: { input: ["image", "text", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.4 }, + limit: { context: 262144, output: 131072 }, + }, + "mancer/weaver": { + id: "mancer/weaver", + name: "Mancer: Weaver (alpha)", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2023-08-02", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.75, output: 1 }, + limit: { context: 8000, output: 2000 }, + }, + "anthracite-org/magnum-v4-72b": { + id: "anthracite-org/magnum-v4-72b", + name: "Magnum v4 72B", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2024-10-22", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 3, output: 5 }, + limit: { context: 16384, output: 2048 }, + }, + "~google/gemini-pro-latest": { + id: "~google/gemini-pro-latest", + name: "Google: Gemini Pro Latest", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-27", + last_updated: "2026-05-01", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 12, cache_read: 0.2, cache_write: 0.375 }, + limit: { context: 1048576, output: 65536 }, + }, + "~google/gemini-flash-latest": { + id: "~google/gemini-flash-latest", + name: "Google: Gemini Flash Latest", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-27", + last_updated: "2026-05-01", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 3, cache_read: 0.05, cache_write: 0.08333333333333334 }, + limit: { context: 1048576, output: 65536 }, + }, + "kilo-auto/balanced": { + id: "kilo-auto/balanced", + name: "Kilo Auto Balanced", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-15", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.6, output: 3 }, + limit: { context: 204800, output: 131072 }, + }, + "kilo-auto/frontier": { + id: "kilo-auto/frontier", + name: "Kilo Auto Frontier", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-15", + last_updated: "2026-03-15", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25 }, + limit: { context: 1000000, output: 128000 }, + }, + "kilo-auto/small": { + id: "kilo-auto/small", + name: "Kilo Auto Small", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-15", + last_updated: "2026-03-15", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.05, output: 0.4 }, + limit: { context: 400000, output: 128000 }, + }, + "kilo-auto/free": { + id: "kilo-auto/free", + name: "Kilo Auto Free", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-15", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 204800, output: 131072 }, + }, + "undi95/remm-slerp-l2-13b": { + id: "undi95/remm-slerp-l2-13b", + name: "ReMM SLERP 13B", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2023-07-22", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.45, output: 0.65 }, + limit: { context: 6144, output: 4096 }, + }, + "allenai/olmo-3-32b-think": { + id: "allenai/olmo-3-32b-think", + name: "AllenAI: Olmo 3 32B Think", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2025-11-22", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.5 }, + limit: { context: 65536, output: 65536 }, + }, + "nousresearch/hermes-2-pro-llama-3-8b": { + id: "nousresearch/hermes-2-pro-llama-3-8b", + name: "NousResearch: Hermes 2 Pro - Llama-3 8B", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2024-05-27", + last_updated: "2024-06-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.14, output: 0.14 }, + limit: { context: 8192, output: 8192 }, + }, + "nousresearch/hermes-4-405b": { + id: "nousresearch/hermes-4-405b", + name: "Nous: Hermes 4 405B", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2025-08-25", + last_updated: "2025-08-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 3 }, + limit: { context: 131072, output: 26215 }, + }, + "nousresearch/hermes-3-llama-3.1-70b": { + id: "nousresearch/hermes-3-llama-3.1-70b", + name: "Nous: Hermes 3 70B Instruct", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2024-08-18", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 0.3 }, + limit: { context: 131072, output: 32768 }, + }, + "nousresearch/hermes-4-70b": { + id: "nousresearch/hermes-4-70b", + name: "Nous: Hermes 4 70B", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2025-08-25", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.13, output: 0.4, cache_read: 0.055 }, + limit: { context: 131072, output: 131072 }, + }, + "nousresearch/hermes-3-llama-3.1-405b": { + id: "nousresearch/hermes-3-llama-3.1-405b", + name: "Nous: Hermes 3 405B Instruct", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2024-08-16", + last_updated: "2024-08-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 1 }, + limit: { context: 131072, output: 16384 }, + }, + "morph/morph-v3-fast": { + id: "morph/morph-v3-fast", + name: "Morph: Morph V3 Fast", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2024-08-15", + last_updated: "2024-08-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.8, output: 1.2 }, + limit: { context: 81920, output: 38000 }, + }, + "morph/morph-v3-large": { + id: "morph/morph-v3-large", + name: "Morph: Morph V3 Large", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2024-08-15", + last_updated: "2024-08-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.9, output: 1.9 }, + limit: { context: 262144, output: 131072 }, + }, + "stepfun/step-3.5-flash:free": { + id: "stepfun/step-3.5-flash:free", + name: "StepFun: Step 3.5 Flash (free)", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-26", + last_updated: "2026-05-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 262144, output: 262144 }, + }, + "stepfun/step-3.5-flash": { + id: "stepfun/step-3.5-flash", + name: "StepFun: Step 3.5 Flash", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-01-29", + last_updated: "2026-01-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.3, cache_read: 0.02 }, + limit: { context: 256000, output: 256000 }, + }, + "alpindale/goliath-120b": { + id: "alpindale/goliath-120b", + name: "Goliath 120B", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2023-11-10", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 3.75, output: 7.5 }, + limit: { context: 6144, output: 1024 }, + }, + "mistralai/mistral-nemo": { + id: "mistralai/mistral-nemo", + name: "Mistral: Mistral Nemo", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-07-01", + last_updated: "2024-07-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.02, output: 0.04 }, + limit: { context: 131072, output: 16384 }, + }, + "mistralai/mistral-saba": { + id: "mistralai/mistral-saba", + name: "Mistral: Saba", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-02-17", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.6 }, + limit: { context: 32768, output: 32768 }, + }, + "mistralai/mistral-large-2512": { + id: "mistralai/mistral-large-2512", + name: "Mistral: Mistral Large 3 2512", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-11-01", + last_updated: "2025-12-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.5, output: 1.5 }, + limit: { context: 262144, output: 52429 }, + }, + "mistralai/devstral-medium": { + id: "mistralai/devstral-medium", + name: "Mistral: Devstral Medium", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-07-10", + last_updated: "2025-07-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.4, output: 2 }, + limit: { context: 131072, output: 26215 }, + }, + "mistralai/mistral-small-3.1-24b-instruct": { + id: "mistralai/mistral-small-3.1-24b-instruct", + name: "Mistral: Mistral Small 3.1 24B", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-03-17", + last_updated: "2026-03-15", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.35, output: 0.56, cache_read: 0.015 }, + limit: { context: 128000, output: 131072 }, + }, + "mistralai/mistral-medium-3-5": { + id: "mistralai/mistral-medium-3-5", + name: "Mistral: Mistral Medium 3.5", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-04-30", + last_updated: "2026-05-07", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.5, output: 7.5 }, + limit: { context: 262144, output: 262144 }, + }, + "mistralai/pixtral-large-2411": { + id: "mistralai/pixtral-large-2411", + name: "Mistral: Pixtral Large 2411", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-11-19", + last_updated: "2026-03-15", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: true, + cost: { input: 2, output: 6 }, + limit: { context: 131072, output: 32768 }, + }, + "mistralai/devstral-2512": { + id: "mistralai/devstral-2512", + name: "Mistral: Devstral 2 2512", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-09-12", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.4, output: 2, cache_read: 0.025 }, + limit: { context: 262144, output: 65536 }, + }, + "mistralai/codestral-2508": { + id: "mistralai/codestral-2508", + name: "Mistral: Codestral 2508", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-08-01", + last_updated: "2025-08-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 0.9 }, + limit: { context: 256000, output: 51200 }, + }, + "mistralai/mistral-small-24b-instruct-2501": { + id: "mistralai/mistral-small-24b-instruct-2501", + name: "Mistral: Mistral Small 3", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-12-29", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.05, output: 0.08 }, + limit: { context: 32768, output: 16384 }, + }, + "mistralai/mistral-large-2411": { + id: "mistralai/mistral-large-2411", + name: "Mistral Large 2411", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-07-24", + last_updated: "2024-11-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 2, output: 6 }, + limit: { context: 131072, output: 26215 }, + }, + "mistralai/mixtral-8x22b-instruct": { + id: "mistralai/mixtral-8x22b-instruct", + name: "Mistral: Mixtral 8x22B Instruct", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-04-17", + last_updated: "2024-04-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 2, output: 6 }, + limit: { context: 65536, output: 13108 }, + }, + "mistralai/mistral-large-2407": { + id: "mistralai/mistral-large-2407", + name: "Mistral Large 2407", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-11-19", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 2, output: 6 }, + limit: { context: 131072, output: 32768 }, + }, + "mistralai/ministral-8b-2512": { + id: "mistralai/ministral-8b-2512", + name: "Mistral: Ministral 3 8B 2512", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-12-02", + last_updated: "2026-03-15", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.15 }, + limit: { context: 262144, output: 32768 }, + }, + "mistralai/mistral-medium-3.1": { + id: "mistralai/mistral-medium-3.1", + name: "Mistral: Mistral Medium 3.1", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-08-12", + last_updated: "2025-08-12", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 2 }, + limit: { context: 131072, output: 26215 }, + }, + "mistralai/mistral-small-2603": { + id: "mistralai/mistral-small-2603", + name: "Mistral: Mistral Small 4", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-16", + last_updated: "2026-04-11", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.6, cache_read: 0.015 }, + limit: { context: 262144, output: 262144 }, + }, + "mistralai/ministral-3b-2512": { + id: "mistralai/ministral-3b-2512", + name: "Mistral: Ministral 3 3B 2512", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-12-02", + last_updated: "2026-03-15", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.1 }, + limit: { context: 131072, output: 32768 }, + }, + "mistralai/voxtral-small-24b-2507": { + id: "mistralai/voxtral-small-24b-2507", + name: "Mistral: Voxtral Small 24B 2507", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-07-01", + last_updated: "2025-07-01", + modalities: { input: ["text", "audio"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.3 }, + limit: { context: 32000, output: 6400 }, + }, + "mistralai/mixtral-8x7b-instruct": { + id: "mistralai/mixtral-8x7b-instruct", + name: "Mistral: Mixtral 8x7B Instruct", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2023-12-10", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.54, output: 0.54 }, + limit: { context: 32768, output: 16384 }, + }, + "mistralai/mistral-medium-3": { + id: "mistralai/mistral-medium-3", + name: "Mistral: Mistral Medium 3", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-05-07", + last_updated: "2025-05-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 2 }, + limit: { context: 131072, output: 26215 }, + }, + "mistralai/mistral-small-3.2-24b-instruct": { + id: "mistralai/mistral-small-3.2-24b-instruct", + name: "Mistral: Mistral Small 3.2 24B", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-06-20", + last_updated: "2025-06-20", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.06, output: 0.18, cache_read: 0.03 }, + limit: { context: 131072, output: 131072 }, + }, + "mistralai/devstral-small": { + id: "mistralai/devstral-small", + name: "Mistral: Devstral Small 1.1", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-05-07", + last_updated: "2025-07-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.3 }, + limit: { context: 131072, output: 26215 }, + }, + "mistralai/mistral-large": { + id: "mistralai/mistral-large", + name: "Mistral Large", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-07-24", + last_updated: "2025-12-02", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 2, output: 6 }, + limit: { context: 128000, output: 25600 }, + }, + "mistralai/mistral-7b-instruct-v0.1": { + id: "mistralai/mistral-7b-instruct-v0.1", + name: "Mistral: Mistral 7B Instruct v0.1", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-04-03", + last_updated: "2025-04-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.11, output: 0.19 }, + limit: { context: 2824, output: 565 }, + }, + "mistralai/ministral-14b-2512": { + id: "mistralai/ministral-14b-2512", + name: "Mistral: Ministral 3 14B 2512", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-12-16", + last_updated: "2025-12-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.2 }, + limit: { context: 262144, output: 52429 }, + }, + "~anthropic/claude-haiku-latest": { + id: "~anthropic/claude-haiku-latest", + name: "Anthropic: Claude Haiku Latest", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-27", + last_updated: "2026-05-01", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 5, cache_read: 0.1, cache_write: 1.25 }, + limit: { context: 200000, output: 64000 }, + }, + "~anthropic/claude-sonnet-latest": { + id: "~anthropic/claude-sonnet-latest", + name: "Anthropic: Claude Sonnet Latest", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-27", + last_updated: "2026-05-01", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 1000000, output: 128000 }, + }, + "~anthropic/claude-opus-latest": { + id: "~anthropic/claude-opus-latest", + name: "Anthropic: Claude Opus Latest", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2026-04-16", + last_updated: "2026-05-01", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 1000000, output: 128000 }, + }, + "meta-llama/llama-3.3-70b-instruct": { + id: "meta-llama/llama-3.3-70b-instruct", + name: "Meta: Llama 3.3 70B Instruct", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-08-01", + last_updated: "2026-02-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.32 }, + limit: { context: 131072, output: 16384 }, + }, + "meta-llama/llama-4-scout": { + id: "meta-llama/llama-4-scout", + name: "Meta: Llama 4 Scout", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-04-05", + last_updated: "2025-04-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.08, output: 0.3 }, + limit: { context: 327680, output: 16384 }, + }, + "meta-llama/llama-guard-3-8b": { + id: "meta-llama/llama-guard-3-8b", + name: "Llama Guard 3 8B", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2024-04-18", + last_updated: "2026-02-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.02, output: 0.06 }, + limit: { context: 131072, output: 26215 }, + }, + "meta-llama/llama-4-maverick": { + id: "meta-llama/llama-4-maverick", + name: "Meta: Llama 4 Maverick", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-04-05", + last_updated: "2025-12-24", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 1048576, output: 16384 }, + }, + "meta-llama/llama-3.2-11b-vision-instruct": { + id: "meta-llama/llama-3.2-11b-vision-instruct", + name: "Meta: Llama 3.2 11B Vision Instruct", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2024-09-25", + last_updated: "2024-09-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.049, output: 0.049 }, + limit: { context: 131072, output: 16384 }, + }, + "meta-llama/llama-guard-4-12b": { + id: "meta-llama/llama-guard-4-12b", + name: "Meta: Llama Guard 4 12B", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-04-05", + last_updated: "2025-04-05", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.18, output: 0.18 }, + limit: { context: 163840, output: 32768 }, + }, + "meta-llama/llama-3.1-70b-instruct": { + id: "meta-llama/llama-3.1-70b-instruct", + name: "Meta: Llama 3.1 70B Instruct", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-07-16", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.4, output: 0.4 }, + limit: { context: 131072, output: 26215 }, + }, + "meta-llama/llama-3.2-1b-instruct": { + id: "meta-llama/llama-3.2-1b-instruct", + name: "Meta: Llama 3.2 1B Instruct", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2024-09-18", + last_updated: "2026-01-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.027, output: 0.2 }, + limit: { context: 60000, output: 12000 }, + }, + "meta-llama/llama-3.2-3b-instruct": { + id: "meta-llama/llama-3.2-3b-instruct", + name: "Meta: Llama 3.2 3B Instruct", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2024-09-18", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.051, output: 0.34 }, + limit: { context: 80000, output: 16384 }, + }, + "meta-llama/llama-3-8b-instruct": { + id: "meta-llama/llama-3-8b-instruct", + name: "Meta: Llama 3 8B Instruct", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-04-25", + last_updated: "2025-04-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.03, output: 0.04 }, + limit: { context: 8192, output: 16384 }, + }, + "meta-llama/llama-3.1-8b-instruct": { + id: "meta-llama/llama-3.1-8b-instruct", + name: "Meta: Llama 3.1 8B Instruct", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-07-23", + last_updated: "2025-12-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.02, output: 0.05 }, + limit: { context: 16384, output: 16384 }, + }, + "meta-llama/llama-3-70b-instruct": { + id: "meta-llama/llama-3-70b-instruct", + name: "Meta: Llama 3 70B Instruct", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.51, output: 0.74 }, + limit: { context: 8192, output: 8000 }, + }, + "x-ai/grok-4.20": { + id: "x-ai/grok-4.20", + name: "xAI: Grok 4.20", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-31", + last_updated: "2026-04-11", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 6, cache_read: 0.2 }, + limit: { context: 2000000, output: 2000000 }, + }, + "x-ai/grok-code-fast-1:optimized:free": { + id: "x-ai/grok-code-fast-1:optimized:free", + name: "xAI: Grok Code Fast 1 Optimized (experimental, free)", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-27", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 256000, output: 10000 }, + }, + "x-ai/grok-4.3": { + id: "x-ai/grok-4.3", + name: "xAI: Grok 4.3", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-05-01", + last_updated: "2026-05-01", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 2.5, cache_read: 0.2 }, + limit: { context: 1000000, output: 4096 }, + }, + "x-ai/grok-4-fast": { + id: "x-ai/grok-4-fast", + name: "xAI: Grok 4 Fast", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-19", + last_updated: "2025-08-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5, cache_read: 0.05 }, + limit: { context: 2000000, output: 30000 }, + }, + "x-ai/grok-code-fast-1": { + id: "x-ai/grok-code-fast-1", + name: "xAI: Grok Code Fast 1", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-26", + last_updated: "2025-08-26", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 1.5, cache_read: 0.02 }, + limit: { context: 256000, output: 10000 }, + }, + "x-ai/grok-3-beta": { + id: "x-ai/grok-3-beta", + name: "xAI: Grok 3 Beta", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-02-17", + last_updated: "2025-02-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.75 }, + limit: { context: 131072, output: 26215 }, + }, + "x-ai/grok-4": { + id: "x-ai/grok-4", + name: "xAI: Grok 4", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-07-09", + last_updated: "2025-07-09", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.75 }, + limit: { context: 256000, output: 51200 }, + }, + "x-ai/grok-3-mini": { + id: "x-ai/grok-3-mini", + name: "xAI: Grok 3 Mini", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-02-17", + last_updated: "2025-02-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 0.5, cache_read: 0.075 }, + limit: { context: 131072, output: 26215 }, + }, + "x-ai/grok-4.1-fast": { + id: "x-ai/grok-4.1-fast", + name: "xAI: Grok 4.1 Fast", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-11-19", + last_updated: "2025-11-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5, cache_read: 0.05 }, + limit: { context: 2000000, output: 30000 }, + }, + "x-ai/grok-3-mini-beta": { + id: "x-ai/grok-3-mini-beta", + name: "xAI: Grok 3 Mini Beta", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-02-17", + last_updated: "2025-02-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 0.5, cache_read: 0.075 }, + limit: { context: 131072, output: 26215 }, + }, + "x-ai/grok-4.20-multi-agent": { + id: "x-ai/grok-4.20-multi-agent", + name: "xAI: Grok 4.20 Multi-Agent", + attachment: true, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2026-03-31", + last_updated: "2026-04-11", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 6, cache_read: 0.2 }, + limit: { context: 2000000, output: 2000000 }, + }, + "x-ai/grok-3": { + id: "x-ai/grok-3", + name: "xAI: Grok 3", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-02-17", + last_updated: "2025-02-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.75 }, + limit: { context: 131072, output: 26215 }, + }, + "tencent/hy3-preview:free": { + id: "tencent/hy3-preview:free", + name: "Tencent: Hy3 Preview (free)", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-22", + last_updated: "2026-05-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 262144, output: 262144 }, + }, + "tencent/hunyuan-a13b-instruct": { + id: "tencent/hunyuan-a13b-instruct", + name: "Tencent: Hunyuan A13B Instruct", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2025-06-30", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.14, output: 0.57 }, + limit: { context: 131072, output: 131072 }, + }, + "gryphe/mythomax-l2-13b": { + id: "gryphe/mythomax-l2-13b", + name: "MythoMax 13B", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2024-04-25", + last_updated: "2024-04-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.06, output: 0.06 }, + limit: { context: 4096, output: 4096 }, + }, + "sao10k/l3-euryale-70b": { + id: "sao10k/l3-euryale-70b", + name: "Sao10k: Llama 3 Euryale 70B v2.1", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-06-18", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.48, output: 1.48 }, + limit: { context: 8192, output: 8192 }, + }, + "sao10k/l3-lunaris-8b": { + id: "sao10k/l3-lunaris-8b", + name: "Sao10K: Llama 3 8B Lunaris", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2024-08-13", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.04, output: 0.05 }, + limit: { context: 8192, output: 8192 }, + }, + "sao10k/l3.3-euryale-70b": { + id: "sao10k/l3.3-euryale-70b", + name: "Sao10K: Llama 3.3 Euryale 70B", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2024-12-18", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.65, output: 0.75 }, + limit: { context: 131072, output: 16384 }, + }, + "sao10k/l3.1-70b-hanami-x1": { + id: "sao10k/l3.1-70b-hanami-x1", + name: "Sao10K: Llama 3.1 70B Hanami x1", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-01-08", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 3, output: 3 }, + limit: { context: 16000, output: 16000 }, + }, + "sao10k/l3.1-euryale-70b": { + id: "sao10k/l3.1-euryale-70b", + name: "Sao10K: Llama 3.1 Euryale 70B v2.2", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-08-28", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.85, output: 0.85 }, + limit: { context: 131072, output: 16384 }, + }, + "microsoft/wizardlm-2-8x22b": { + id: "microsoft/wizardlm-2-8x22b", + name: "WizardLM-2 8x22B", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2024-04-24", + last_updated: "2024-04-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.62, output: 0.62 }, + limit: { context: 65535, output: 8000 }, + }, + "microsoft/phi-4-mini-instruct": { + id: "microsoft/phi-4-mini-instruct", + name: "Microsoft: Phi 4 Mini Instruct", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: true, + temperature: true, + release_date: "2025-10-17", + last_updated: "2026-05-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.08, output: 0.35, cache_read: 0.08 }, + limit: { context: 128000, output: 128000 }, + }, + "microsoft/phi-4": { + id: "microsoft/phi-4", + name: "Microsoft: Phi 4", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2024-12-11", + last_updated: "2024-12-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.06, output: 0.14 }, + limit: { context: 16384, output: 16384 }, + }, + "poolside/laguna-m.1:free": { + id: "poolside/laguna-m.1:free", + name: "Poolside: Laguna M.1 (free)", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-28", + last_updated: "2026-05-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 131072, output: 8192 }, + }, + "poolside/laguna-xs.2:free": { + id: "poolside/laguna-xs.2:free", + name: "Poolside: Laguna XS.2 (free)", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-28", + last_updated: "2026-05-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 131072, output: 8192 }, + }, + "cohere/command-r7b-12-2024": { + id: "cohere/command-r7b-12-2024", + name: "Cohere: Command R7B (12-2024)", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-02-27", + last_updated: "2024-02-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.0375, output: 0.15 }, + limit: { context: 128000, output: 4000 }, + }, + "cohere/command-a": { + id: "cohere/command-a", + name: "Cohere: Command A", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-03-13", + last_updated: "2025-03-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 2.5, output: 10 }, + limit: { context: 256000, output: 8192 }, + }, + "cohere/command-r-plus-08-2024": { + id: "cohere/command-r-plus-08-2024", + name: "Cohere: Command R+ (08-2024)", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-08-30", + last_updated: "2024-08-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 2.5, output: 10 }, + limit: { context: 128000, output: 4000 }, + }, + "cohere/command-r-08-2024": { + id: "cohere/command-r-08-2024", + name: "Cohere: Command R (08-2024)", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-08-30", + last_updated: "2024-08-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 128000, output: 4000 }, + }, + "prime-intellect/intellect-3": { + id: "prime-intellect/intellect-3", + name: "Prime Intellect: INTELLECT-3", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-11-26", + last_updated: "2026-02-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 1.1 }, + limit: { context: 131072, output: 131072 }, + }, + "nvidia/llama-3.3-nemotron-super-49b-v1.5": { + id: "nvidia/llama-3.3-nemotron-super-49b-v1.5", + name: "NVIDIA: Llama 3.3 Nemotron Super 49B V1.5", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-03-16", + last_updated: "2025-03-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4 }, + limit: { context: 131072, output: 26215 }, + }, + "nvidia/nemotron-3-super-120b-a12b": { + id: "nvidia/nemotron-3-super-120b-a12b", + name: "NVIDIA: Nemotron 3 Super", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-11", + last_updated: "2026-04-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.5, cache_read: 0.1 }, + limit: { context: 262144, output: 262144 }, + }, + "nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free": { + id: "nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free", + name: "NVIDIA: Nemotron 3 Nano Omni (free)", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-28", + last_updated: "2026-05-01", + modalities: { input: ["text", "audio", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 256000, output: 65536 }, + }, + "nvidia/nemotron-3-nano-30b-a3b": { + id: "nvidia/nemotron-3-nano-30b-a3b", + name: "NVIDIA: Nemotron 3 Nano 30B A3B", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2024-12", + last_updated: "2026-02-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.05, output: 0.2 }, + limit: { context: 262144, output: 52429 }, + }, + "nvidia/nemotron-3-super-120b-a12b:free": { + id: "nvidia/nemotron-3-super-120b-a12b:free", + name: "NVIDIA: Nemotron 3 Super (free)", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-12", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 262144, output: 262144 }, + }, + "nvidia/nemotron-nano-9b-v2": { + id: "nvidia/nemotron-nano-9b-v2", + name: "NVIDIA: Nemotron Nano 9B V2", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-18", + last_updated: "2025-08-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.04, output: 0.16 }, + limit: { context: 131072, output: 26215 }, + }, + "nvidia/llama-3.1-nemotron-70b-instruct": { + id: "nvidia/llama-3.1-nemotron-70b-instruct", + name: "NVIDIA: Llama 3.1 Nemotron 70B Instruct", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-10-12", + last_updated: "2024-10-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.2, output: 1.2 }, + limit: { context: 131072, output: 16384 }, + }, + "inception/mercury-2": { + id: "inception/mercury-2", + name: "Inception: Mercury 2", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-24", + last_updated: "2026-02-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 0.75, cache_read: 0.025 }, + limit: { context: 128000, output: 50000 }, + }, + "openai/gpt-5.1-codex-max": { + id: "openai/gpt-5.1-codex-max", + name: "OpenAI: GPT-5.1-Codex-Max", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-5.2-chat": { + id: "openai/gpt-5.2-chat", + name: "OpenAI: GPT-5.2 Chat", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2025-12-11", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 128000, output: 16384 }, + }, + "openai/gpt-4o-mini-search-preview": { + id: "openai/gpt-4o-mini-search-preview", + name: "OpenAI: GPT-4o-mini Search Preview", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2025-01", + last_updated: "2025-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 128000, output: 16384 }, + }, + "openai/gpt-5-chat": { + id: "openai/gpt-5-chat", + name: "OpenAI: GPT-5 Chat", + attachment: true, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2025-08-07", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 128000, output: 16384 }, + }, + "openai/gpt-4o-2024-05-13": { + id: "openai/gpt-4o-2024-05-13", + name: "OpenAI: GPT-4o (2024-05-13)", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-05-13", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 15 }, + limit: { context: 128000, output: 4096 }, + }, + "openai/gpt-5.3-chat": { + id: "openai/gpt-5.3-chat", + name: "OpenAI: GPT-5.3 Chat", + attachment: true, + reasoning: false, + tool_call: true, + release_date: "2026-03-04", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14 }, + limit: { context: 128000, output: 16384 }, + }, + "openai/gpt-5.2-pro": { + id: "openai/gpt-5.2-pro", + name: "OpenAI: GPT-5.2 Pro", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-12-11", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 21, output: 168 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-4-1106-preview": { + id: "openai/gpt-4-1106-preview", + name: "OpenAI: GPT-4 Turbo (older v1106)", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2023-11-06", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 10, output: 30 }, + limit: { context: 128000, output: 4096 }, + }, + "openai/gpt-chat-latest": { + id: "openai/gpt-chat-latest", + name: "OpenAI: GPT Chat Latest", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + release_date: "2026-05-05", + last_updated: "2026-05-07", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 30, cache_read: 0.5 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-4o-audio-preview": { + id: "openai/gpt-4o-audio-preview", + name: "OpenAI: GPT-4o Audio", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-08-15", + last_updated: "2026-03-15", + modalities: { input: ["audio", "text"], output: ["audio", "text"] }, + open_weights: false, + cost: { input: 2.5, output: 10 }, + limit: { context: 128000, output: 16384 }, + }, + "openai/gpt-5.5": { + id: "openai/gpt-5.5", + name: "OpenAI: GPT-5.5", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2026-04-24", + last_updated: "2026-05-01", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 30, cache_read: 0.5 }, + limit: { context: 1050000, output: 128000 }, + }, + "openai/gpt-5-mini": { + id: "openai/gpt-5-mini", + name: "OpenAI: GPT-5 Mini", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-08-07", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 2, cache_read: 0.025 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-5-nano": { + id: "openai/gpt-5-nano", + name: "OpenAI: GPT-5 Nano", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-08-07", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.05, output: 0.4, cache_read: 0.005 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-5.3-codex": { + id: "openai/gpt-5.3-codex", + name: "OpenAI: GPT-5.3-Codex", + attachment: true, + reasoning: true, + tool_call: true, + release_date: "2026-02-25", + last_updated: "2026-03-15", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-3.5-turbo-16k": { + id: "openai/gpt-3.5-turbo-16k", + name: "OpenAI: GPT-3.5 Turbo 16k", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2023-08-28", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 4 }, + limit: { context: 16385, output: 4096 }, + }, + "openai/gpt-4-turbo": { + id: "openai/gpt-4-turbo", + name: "OpenAI: GPT-4 Turbo", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2023-09-13", + last_updated: "2024-04-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 10, output: 30 }, + limit: { context: 128000, output: 4096 }, + }, + "openai/gpt-5.2": { + id: "openai/gpt-5.2", + name: "OpenAI: GPT-5.2", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-12-11", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/o3-pro": { + id: "openai/o3-pro", + name: "OpenAI: o3 Pro", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-04-16", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 20, output: 80 }, + limit: { context: 200000, output: 100000 }, + }, + "openai/o3-mini-high": { + id: "openai/o3-mini-high", + name: "OpenAI: o3 Mini High", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2025-01-31", + last_updated: "2026-03-15", + modalities: { input: ["pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 4.4, cache_read: 0.55 }, + limit: { context: 200000, output: 100000 }, + }, + "openai/gpt-4o-mini": { + id: "openai/gpt-4o-mini", + name: "OpenAI: GPT-4o-mini", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-07-18", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.6, cache_read: 0.075 }, + limit: { context: 128000, output: 16384 }, + }, + "openai/o4-mini-deep-research": { + id: "openai/o4-mini-deep-research", + name: "OpenAI: o4 Mini Deep Research", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2024-06-26", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 8, cache_read: 0.5 }, + limit: { context: 200000, output: 100000 }, + }, + "openai/gpt-5.4-mini": { + id: "openai/gpt-5.4-mini", + name: "OpenAI: GPT-5.4 Mini", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2026-03-17", + last_updated: "2026-04-11", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.75, output: 4.5, cache_read: 0.075 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-5.1-chat": { + id: "openai/gpt-5.1-chat", + name: "OpenAI: GPT-5.1 Chat", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2025-11-13", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 128000, output: 16384 }, + }, + "openai/o4-mini": { + id: "openai/o4-mini", + name: "OpenAI: o4 Mini", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-04-16", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 4.4, cache_read: 0.275 }, + limit: { context: 200000, output: 100000 }, + }, + "openai/gpt-5.4-nano": { + id: "openai/gpt-5.4-nano", + name: "OpenAI: GPT-5.4 Nano", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2026-03-17", + last_updated: "2026-04-11", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 1.25, cache_read: 0.02 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-5.2-codex": { + id: "openai/gpt-5.2-codex", + name: "OpenAI: GPT-5.2-Codex", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2026-01-14", + last_updated: "2026-01-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-4o-mini-2024-07-18": { + id: "openai/gpt-4o-mini-2024-07-18", + name: "OpenAI: GPT-4o-mini (2024-07-18)", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-07-18", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 128000, output: 16384 }, + }, + "openai/gpt-5.1-codex-mini": { + id: "openai/gpt-5.1-codex-mini", + name: "OpenAI: GPT-5.1-Codex-Mini", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 2, cache_read: 0.025 }, + limit: { context: 400000, output: 100000 }, + }, + "openai/gpt-4o-2024-08-06": { + id: "openai/gpt-4o-2024-08-06", + name: "OpenAI: GPT-4o (2024-08-06)", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-08-06", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 10, cache_read: 1.25 }, + limit: { context: 128000, output: 16384 }, + }, + "openai/gpt-5-image": { + id: "openai/gpt-5-image", + name: "OpenAI: GPT-5 Image", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-10-14", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text"], output: ["image", "text"] }, + open_weights: false, + cost: { input: 10, output: 10 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-5.1": { + id: "openai/gpt-5.1", + name: "OpenAI: GPT-5.1", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-11-13", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/o1": { + id: "openai/o1", + name: "OpenAI: o1", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2024-12-05", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 60, cache_read: 7.5 }, + limit: { context: 200000, output: 100000 }, + }, + "openai/gpt-5.4-pro": { + id: "openai/gpt-5.4-pro", + name: "OpenAI: GPT-5.4 Pro", + attachment: true, + reasoning: true, + tool_call: true, + release_date: "2026-03-06", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 30, output: 180 }, + limit: { context: 1050000, output: 128000 }, + }, + "openai/gpt-3.5-turbo": { + id: "openai/gpt-3.5-turbo", + name: "OpenAI: GPT-3.5 Turbo", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2023-03-01", + last_updated: "2023-11-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 1.5 }, + limit: { context: 16385, output: 4096 }, + }, + "openai/o3-deep-research": { + id: "openai/o3-deep-research", + name: "OpenAI: o3 Deep Research", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2024-06-26", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 10, output: 40, cache_read: 2.5 }, + limit: { context: 200000, output: 100000 }, + }, + "openai/o3-mini": { + id: "openai/o3-mini", + name: "OpenAI: o3 Mini", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2024-12-20", + last_updated: "2026-03-15", + modalities: { input: ["pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 4.4, cache_read: 0.55 }, + limit: { context: 200000, output: 100000 }, + }, + "openai/gpt-4-turbo-preview": { + id: "openai/gpt-4-turbo-preview", + name: "OpenAI: GPT-4 Turbo Preview", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-01-25", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 10, output: 30 }, + limit: { context: 128000, output: 4096 }, + }, + "openai/o1-pro": { + id: "openai/o1-pro", + name: "OpenAI: o1-pro", + attachment: true, + reasoning: true, + tool_call: false, + temperature: false, + release_date: "2025-03-19", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 150, output: 600 }, + limit: { context: 200000, output: 100000 }, + }, + "openai/gpt-5.4-image-2": { + id: "openai/gpt-5.4-image-2", + name: "OpenAI: GPT-5.4 Image 2", + attachment: true, + reasoning: true, + tool_call: false, + temperature: false, + release_date: "2026-04-21", + last_updated: "2026-05-01", + modalities: { input: ["image", "text", "pdf"], output: ["image", "text"] }, + open_weights: false, + cost: { input: 8, output: 15, cache_read: 2 }, + limit: { context: 272000, output: 128000 }, + }, + "openai/gpt-4": { + id: "openai/gpt-4", + name: "OpenAI: GPT-4", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2023-03-14", + last_updated: "2024-04-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 30, output: 60 }, + limit: { context: 8191, output: 4096 }, + }, + "openai/gpt-4-0314": { + id: "openai/gpt-4-0314", + name: "OpenAI: GPT-4 (older v0314)", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2023-05-28", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 30, output: 60 }, + limit: { context: 8191, output: 4096 }, + }, + "openai/gpt-5-codex": { + id: "openai/gpt-5-codex", + name: "OpenAI: GPT-5 Codex", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-09-15", + last_updated: "2025-09-15", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-5.4": { + id: "openai/gpt-5.4", + name: "OpenAI: GPT-5.4", + attachment: true, + reasoning: true, + tool_call: true, + release_date: "2026-03-06", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 15 }, + limit: { context: 1050000, output: 128000 }, + }, + "openai/gpt-audio": { + id: "openai/gpt-audio", + name: "OpenAI: GPT Audio", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2026-01-20", + last_updated: "2026-03-15", + modalities: { input: ["audio", "text"], output: ["audio", "text"] }, + open_weights: false, + cost: { input: 2.5, output: 10 }, + limit: { context: 128000, output: 16384 }, + }, + "openai/gpt-4o-search-preview": { + id: "openai/gpt-4o-search-preview", + name: "OpenAI: GPT-4o Search Preview", + attachment: false, + reasoning: false, + tool_call: false, + release_date: "2025-03-13", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 10 }, + limit: { context: 128000, output: 16384 }, + }, + "openai/gpt-4.1-nano": { + id: "openai/gpt-4.1-nano", + name: "OpenAI: GPT-4.1 Nano", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-04-14", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4, cache_read: 0.025 }, + limit: { context: 1047576, output: 32768 }, + }, + "openai/o4-mini-high": { + id: "openai/o4-mini-high", + name: "OpenAI: o4 Mini High", + attachment: true, + reasoning: true, + tool_call: true, + release_date: "2025-04-17", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 4.4 }, + limit: { context: 200000, output: 100000 }, + }, + "openai/o3": { + id: "openai/o3", + name: "OpenAI: o3", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-04-16", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 8, cache_read: 0.5 }, + limit: { context: 200000, output: 100000 }, + }, + "openai/gpt-oss-20b": { + id: "openai/gpt-oss-20b", + name: "OpenAI: gpt-oss-20b", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.03, output: 0.14 }, + limit: { context: 131072, output: 26215 }, + }, + "openai/gpt-5-pro": { + id: "openai/gpt-5-pro", + name: "OpenAI: GPT-5 Pro", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-10-06", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 120 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-audio-mini": { + id: "openai/gpt-audio-mini", + name: "OpenAI: GPT Audio Mini", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2026-01-20", + last_updated: "2026-03-15", + modalities: { input: ["audio", "text"], output: ["audio", "text"] }, + open_weights: false, + cost: { input: 0.6, output: 2.4 }, + limit: { context: 128000, output: 16384 }, + }, + "openai/gpt-4o": { + id: "openai/gpt-4o", + name: "OpenAI: GPT-4o", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-05-13", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 10, cache_read: 1.25 }, + limit: { context: 128000, output: 16384 }, + }, + "openai/gpt-3.5-turbo-0613": { + id: "openai/gpt-3.5-turbo-0613", + name: "OpenAI: GPT-3.5 Turbo (older v0613)", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2023-06-13", + last_updated: "2023-06-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 2 }, + limit: { context: 4095, output: 4096 }, + }, + "openai/gpt-5-image-mini": { + id: "openai/gpt-5-image-mini", + name: "OpenAI: GPT-5 Image Mini", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-10-16", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text"], output: ["image", "text"] }, + open_weights: false, + cost: { input: 2.5, output: 2 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-5": { + id: "openai/gpt-5", + name: "OpenAI: GPT-5", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-08-07", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-oss-safeguard-20b": { + id: "openai/gpt-oss-safeguard-20b", + name: "OpenAI: gpt-oss-safeguard-20b", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-10-29", + last_updated: "2025-10-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.075, output: 0.3, cache_read: 0.037 }, + limit: { context: 131072, output: 65536 }, + }, + "openai/gpt-oss-120b": { + id: "openai/gpt-oss-120b", + name: "OpenAI: gpt-oss-120b", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.039, output: 0.19 }, + limit: { context: 131072, output: 26215 }, + }, + "openai/gpt-5.5-pro": { + id: "openai/gpt-5.5-pro", + name: "OpenAI: GPT-5.5 Pro", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2026-04-24", + last_updated: "2026-05-01", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 30, output: 180 }, + limit: { context: 1050000, output: 128000 }, + }, + "openai/gpt-3.5-turbo-instruct": { + id: "openai/gpt-3.5-turbo-instruct", + name: "OpenAI: GPT-3.5 Turbo Instruct", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2023-03-01", + last_updated: "2023-09-21", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.5, output: 2 }, + limit: { context: 4095, output: 4096 }, + }, + "openai/gpt-4.1": { + id: "openai/gpt-4.1", + name: "OpenAI: GPT-4.1", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-04-14", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 8, cache_read: 0.5 }, + limit: { context: 1047576, output: 32768 }, + }, + "openai/gpt-4.1-mini": { + id: "openai/gpt-4.1-mini", + name: "OpenAI: GPT-4.1 Mini", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-04-14", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 1.6, cache_read: 0.1 }, + limit: { context: 1047576, output: 32768 }, + }, + "openai/gpt-5.1-codex": { + id: "openai/gpt-5.1-codex", + name: "OpenAI: GPT-5.1-Codex", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-4o-2024-11-20": { + id: "openai/gpt-4o-2024-11-20", + name: "OpenAI: GPT-4o (2024-11-20)", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-11-20", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 10, cache_read: 1.25 }, + limit: { context: 128000, output: 16384 }, + }, + "amazon/nova-lite-v1": { + id: "amazon/nova-lite-v1", + name: "Amazon: Nova Lite 1.0", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-12-06", + last_updated: "2026-03-15", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.06, output: 0.24 }, + limit: { context: 300000, output: 5120 }, + }, + "amazon/nova-pro-v1": { + id: "amazon/nova-pro-v1", + name: "Amazon: Nova Pro 1.0", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-12-03", + last_updated: "2024-12-03", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.8, output: 3.2 }, + limit: { context: 300000, output: 5120 }, + }, + "amazon/nova-premier-v1": { + id: "amazon/nova-premier-v1", + name: "Amazon: Nova Premier 1.0", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-11-01", + last_updated: "2026-03-15", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 12.5 }, + limit: { context: 1000000, output: 32000 }, + }, + "amazon/nova-2-lite-v1": { + id: "amazon/nova-2-lite-v1", + name: "Amazon: Nova 2 Lite", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2024-12-01", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 2.5 }, + limit: { context: 1000000, output: 65535 }, + }, + "amazon/nova-micro-v1": { + id: "amazon/nova-micro-v1", + name: "Amazon: Nova Micro 1.0", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-12-06", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.035, output: 0.14 }, + limit: { context: 128000, output: 5120 }, + }, + "z-ai/glm-5v-turbo": { + id: "z-ai/glm-5v-turbo", + name: "Z.ai: GLM 5V Turbo", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-01", + last_updated: "2026-04-11", + modalities: { input: ["image", "text", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 1.2, output: 4, cache_read: 0.24 }, + limit: { context: 202752, output: 131072 }, + }, + "z-ai/glm-4.7": { + id: "z-ai/glm-4.7", + name: "Z.ai: GLM 4.7", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-12-22", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.38, output: 1.98, cache_read: 0.2 }, + limit: { context: 202752, output: 65535 }, + }, + "z-ai/glm-5": { + id: "z-ai/glm-5", + name: "Z.ai: GLM 5", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-12", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.72, output: 2.3 }, + limit: { context: 202752, output: 131072 }, + }, + "z-ai/glm-4-32b": { + id: "z-ai/glm-4-32b", + name: "Z.ai: GLM 4 32B ", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-07-25", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.1 }, + limit: { context: 128000, output: 32768 }, + }, + "z-ai/glm-5.1": { + id: "z-ai/glm-5.1", + name: "Z.ai: GLM 5.1", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-27", + last_updated: "2026-03-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.26, output: 3.96 }, + limit: { context: 202752, output: 131072 }, + }, + "z-ai/glm-4.5": { + id: "z-ai/glm-4.5", + name: "Z.ai: GLM 4.5", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-07-28", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.2, cache_read: 0.175 }, + limit: { context: 131072, output: 98304 }, + }, + "z-ai/glm-4.5-air": { + id: "z-ai/glm-4.5-air", + name: "Z.ai: GLM 4.5 Air", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-07-28", + last_updated: "2025-07-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.13, output: 0.85, cache_read: 0.025 }, + limit: { context: 131072, output: 98304 }, + }, + "z-ai/glm-5-turbo": { + id: "z-ai/glm-5-turbo", + name: "Z.ai: GLM 5 Turbo", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-15", + last_updated: "2026-04-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.2, output: 4, cache_read: 0.24 }, + limit: { context: 202752, output: 131072 }, + }, + "z-ai/glm-4.5v": { + id: "z-ai/glm-4.5v", + name: "Z.ai: GLM 4.5V", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-11", + last_updated: "2025-08-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 1.8, cache_read: 0.11 }, + limit: { context: 65536, output: 16384 }, + }, + "z-ai/glm-4.6": { + id: "z-ai/glm-4.6", + name: "Z.ai: GLM 4.6", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-09-30", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.39, output: 1.9, cache_read: 0.175 }, + limit: { context: 204800, output: 204800 }, + }, + "z-ai/glm-4.6v": { + id: "z-ai/glm-4.6v", + name: "Z.ai: GLM 4.6V", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-09-30", + last_updated: "2026-01-10", + modalities: { input: ["image", "text", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 0.9 }, + limit: { context: 131072, output: 131072 }, + }, + "z-ai/glm-4.7-flash": { + id: "z-ai/glm-4.7-flash", + name: "Z.ai: GLM 4.7 Flash", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-01-19", + last_updated: "2026-01-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.06, output: 0.4, cache_read: 0.01 }, + limit: { context: 202752, output: 40551 }, + }, + "baidu/ernie-4.5-vl-424b-a47b": { + id: "baidu/ernie-4.5-vl-424b-a47b", + name: "Baidu: ERNIE 4.5 VL 424B A47B ", + attachment: true, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2025-06-30", + last_updated: "2026-01", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.42, output: 1.25 }, + limit: { context: 123000, output: 16000 }, + }, + "baidu/qianfan-ocr-fast:free": { + id: "baidu/qianfan-ocr-fast:free", + name: "Baidu: Qianfan-OCR-Fast (free)", + attachment: true, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2026-04-20", + last_updated: "2026-05-01", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 65536, output: 28672 }, + }, + "baidu/cobuddy:free": { + id: "baidu/cobuddy:free", + name: "Baidu: CoBuddy (free)", + attachment: false, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2026-05-06", + last_updated: "2026-05-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 131072, output: 65536 }, + }, + "baidu/ernie-4.5-vl-28b-a3b": { + id: "baidu/ernie-4.5-vl-28b-a3b", + name: "Baidu: ERNIE 4.5 VL 28B A3B", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-06-30", + last_updated: "2025-06-30", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.14, output: 0.56 }, + limit: { context: 30000, output: 8000 }, + }, + "baidu/ernie-4.5-21b-a3b": { + id: "baidu/ernie-4.5-21b-a3b", + name: "Baidu: ERNIE 4.5 21B A3B", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-06-30", + last_updated: "2025-06-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.07, output: 0.28 }, + limit: { context: 120000, output: 8000 }, + }, + "baidu/ernie-4.5-300b-a47b": { + id: "baidu/ernie-4.5-300b-a47b", + name: "Baidu: ERNIE 4.5 300B A47B ", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-06-30", + last_updated: "2026-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.28, output: 1.1 }, + limit: { context: 123000, output: 12000 }, + }, + "baidu/ernie-4.5-21b-a3b-thinking": { + id: "baidu/ernie-4.5-21b-a3b-thinking", + name: "Baidu: ERNIE 4.5 21B A3B Thinking", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2025-09-19", + last_updated: "2025-09-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.07, output: 0.28 }, + limit: { context: 131072, output: 65536 }, + }, + "relace/relace-apply-3": { + id: "relace/relace-apply-3", + name: "Relace: Relace Apply 3", + attachment: false, + reasoning: false, + tool_call: false, + release_date: "2025-09-26", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.85, output: 1.25 }, + limit: { context: 256000, output: 128000 }, + }, + "relace/relace-search": { + id: "relace/relace-search", + name: "Relace: Relace Search", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-12-09", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 3 }, + limit: { context: 256000, output: 128000 }, + }, + "minimax/minimax-m2.7": { + id: "minimax/minimax-m2.7", + name: "MiniMax: MiniMax M2.7", + family: "minimax-m2.7", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2, cache_read: 0.06 }, + limit: { context: 204800, output: 131072 }, + }, + "minimax/minimax-m2": { + id: "minimax/minimax-m2", + name: "MiniMax: MiniMax M2", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-10-23", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.255, output: 1, cache_read: 0.03 }, + limit: { context: 196608, output: 196608 }, + }, + "minimax/minimax-01": { + id: "minimax/minimax-01", + name: "MiniMax: MiniMax-01", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-01-15", + last_updated: "2025-01-15", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 1.1 }, + limit: { context: 1000192, output: 1000192 }, + }, + "minimax/minimax-m2.1": { + id: "minimax/minimax-m2.1", + name: "MiniMax: MiniMax M2.1", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-12-23", + last_updated: "2025-12-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.27, output: 0.95, cache_read: 0.03 }, + limit: { context: 196608, output: 39322 }, + }, + "minimax/minimax-m1": { + id: "minimax/minimax-m1", + name: "MiniMax: MiniMax M1", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-06-17", + last_updated: "2025-06-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.4, output: 2.2 }, + limit: { context: 1000000, output: 40000 }, + }, + "minimax/minimax-m2-her": { + id: "minimax/minimax-m2-her", + name: "MiniMax: MiniMax M2-her", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2026-01-23", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 65536, output: 2048 }, + }, + "minimax/minimax-m2.5": { + id: "minimax/minimax-m2.5", + name: "MiniMax: MiniMax M2.5", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-12", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.25, output: 1.2, cache_read: 0.029 }, + limit: { context: 196608, output: 196608 }, + }, + "~openai/gpt-latest": { + id: "~openai/gpt-latest", + name: "OpenAI: GPT Latest", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2026-04-27", + last_updated: "2026-05-01", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 30, cache_read: 0.5 }, + limit: { context: 1050000, output: 128000 }, + }, + "~openai/gpt-mini-latest": { + id: "~openai/gpt-mini-latest", + name: "OpenAI: GPT Mini Latest", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2026-04-27", + last_updated: "2026-05-01", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.75, output: 4.5, cache_read: 0.075 }, + limit: { context: 400000, output: 128000 }, + }, + "qwen/qwen3-235b-a22b": { + id: "qwen/qwen3-235b-a22b", + name: "Qwen: Qwen3 235B A22B", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2024-12-01", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.455, output: 1.82, cache_read: 0.15 }, + limit: { context: 131072, output: 8192 }, + }, + "qwen/qwen3.5-122b-a10b": { + id: "qwen/qwen3.5-122b-a10b", + name: "Qwen: Qwen3.5-122B-A10B", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-26", + last_updated: "2026-03-15", + modalities: { input: ["image", "text", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.26, output: 2.08 }, + limit: { context: 262144, output: 65536 }, + }, + "qwen/qwen3-coder-plus": { + id: "qwen/qwen3-coder-plus", + name: "Qwen: Qwen3 Coder Plus", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-07-01", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.65, output: 3.25, cache_read: 0.2 }, + limit: { context: 1000000, output: 65536 }, + }, + "qwen/qwen3.6-27b": { + id: "qwen/qwen3.6-27b", + name: "Qwen: Qwen3.6 27B", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-27", + last_updated: "2026-05-01", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.325, output: 3.25 }, + limit: { context: 256000, output: 65536 }, + }, + "qwen/qwen3.5-27b": { + id: "qwen/qwen3.5-27b", + name: "Qwen: Qwen3.5-27B", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-26", + last_updated: "2026-03-15", + modalities: { input: ["image", "text", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.195, output: 1.56 }, + limit: { context: 262144, output: 65536 }, + }, + "qwen/qwen3-235b-a22b-2507": { + id: "qwen/qwen3-235b-a22b-2507", + name: "Qwen: Qwen3 235B A22B Instruct 2507", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-04", + last_updated: "2026-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.071, output: 0.1 }, + limit: { context: 262144, output: 52429 }, + }, + "qwen/qwen3-8b": { + id: "qwen/qwen3-8b", + name: "Qwen: Qwen3 8B", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-04", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.05, output: 0.4, cache_read: 0.05 }, + limit: { context: 40960, output: 8192 }, + }, + "qwen/qwen3.5-397b-a17b": { + id: "qwen/qwen3.5-397b-a17b", + name: "Qwen: Qwen3.5 397B A17B", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-15", + last_updated: "2026-03-15", + modalities: { input: ["image", "text", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.39, output: 2.34 }, + limit: { context: 262144, output: 65536 }, + }, + "qwen/qwen-vl-plus": { + id: "qwen/qwen-vl-plus", + name: "Qwen: Qwen VL Plus", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2024-01-25", + last_updated: "2026-03-15", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1365, output: 0.4095, cache_read: 0.042 }, + limit: { context: 131072, output: 8192 }, + }, + "qwen/qwen3-32b": { + id: "qwen/qwen3-32b", + name: "Qwen: Qwen3 32B", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2024-12-01", + last_updated: "2026-02-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.08, output: 0.24, cache_read: 0.04 }, + limit: { context: 40960, output: 40960 }, + }, + "qwen/qwen2.5-vl-72b-instruct": { + id: "qwen/qwen2.5-vl-72b-instruct", + name: "Qwen: Qwen2.5 VL 72B Instruct", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-02-01", + last_updated: "2026-03-15", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.8, output: 0.8, cache_read: 0.075 }, + limit: { context: 32768, output: 32768 }, + }, + "qwen/qwen-max": { + id: "qwen/qwen-max", + name: "Qwen: Qwen-Max ", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-04-03", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.04, output: 4.16, cache_read: 0.32 }, + limit: { context: 32768, output: 8192 }, + }, + "qwen/qwen-plus": { + id: "qwen/qwen-plus", + name: "Qwen: Qwen-Plus", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-01-25", + last_updated: "2025-09-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 1.2, cache_read: 0.08 }, + limit: { context: 1000000, output: 32768 }, + }, + "qwen/qwen3.6-35b-a3b": { + id: "qwen/qwen3.6-35b-a3b", + name: "Qwen: Qwen3.6 35B A3B", + attachment: true, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2026-04-27", + last_updated: "2026-05-01", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1612, output: 0.96525, cache_read: 0.1612 }, + limit: { context: 262144, output: 65536 }, + }, + "qwen/qwen3-vl-235b-a22b-thinking": { + id: "qwen/qwen3-vl-235b-a22b-thinking", + name: "Qwen: Qwen3 VL 235B A22B Thinking", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-09-24", + last_updated: "2026-03-15", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.26, output: 2.6 }, + limit: { context: 131072, output: 32768 }, + }, + "qwen/qwen3-vl-30b-a3b-thinking": { + id: "qwen/qwen3-vl-30b-a3b-thinking", + name: "Qwen: Qwen3 VL 30B A3B Thinking", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-10-11", + last_updated: "2026-03-15", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.13, output: 1.56 }, + limit: { context: 131072, output: 32768 }, + }, + "qwen/qwen3-vl-8b-instruct": { + id: "qwen/qwen3-vl-8b-instruct", + name: "Qwen: Qwen3 VL 8B Instruct", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-10-15", + last_updated: "2025-11-25", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.08, output: 0.5 }, + limit: { context: 131072, output: 32768 }, + }, + "qwen/qwen3.5-flash-02-23": { + id: "qwen/qwen3.5-flash-02-23", + name: "Qwen: Qwen3.5-Flash", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-26", + last_updated: "2026-03-15", + modalities: { input: ["image", "text", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.4 }, + limit: { context: 1000000, output: 65536 }, + }, + "qwen/qwen3.6-plus": { + id: "qwen/qwen3.6-plus", + name: "Qwen: Qwen3.6 Plus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-26", + last_updated: "2026-04-11", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.325, output: 1.95, cache_read: 0.0325, cache_write: 0.40625 }, + limit: { context: 1000000, output: 65536 }, + }, + "qwen/qwen3-max": { + id: "qwen/qwen3-max", + name: "Qwen: Qwen3 Max", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-09-05", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.2, output: 6, cache_read: 0.24 }, + limit: { context: 262144, output: 32768 }, + }, + "qwen/qwen-plus-2025-07-28": { + id: "qwen/qwen-plus-2025-07-28", + name: "Qwen: Qwen Plus 0728", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-09-09", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.26, output: 0.78 }, + limit: { context: 1000000, output: 32768 }, + }, + "qwen/qwen3-30b-a3b-instruct-2507": { + id: "qwen/qwen3-30b-a3b-instruct-2507", + name: "Qwen: Qwen3 30B A3B Instruct 2507", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-07-29", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.09, output: 0.3, cache_read: 0.04 }, + limit: { context: 262144, output: 262144 }, + }, + "qwen/qwen3-vl-32b-instruct": { + id: "qwen/qwen3-vl-32b-instruct", + name: "Qwen: Qwen3 VL 32B Instruct", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-10-21", + last_updated: "2025-11-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.104, output: 0.416 }, + limit: { context: 131072, output: 32768 }, + }, + "qwen/qwen3-235b-a22b-thinking-2507": { + id: "qwen/qwen3-235b-a22b-thinking-2507", + name: "Qwen: Qwen3 235B A22B Thinking 2507", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-07-25", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.11, output: 0.6 }, + limit: { context: 262144, output: 262144 }, + }, + "qwen/qwen3-next-80b-a3b-thinking": { + id: "qwen/qwen3-next-80b-a3b-thinking", + name: "Qwen: Qwen3 Next 80B A3B Thinking", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-09-11", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.0975, output: 0.78 }, + limit: { context: 131072, output: 32768 }, + }, + "qwen/qwen3-30b-a3b-thinking-2507": { + id: "qwen/qwen3-30b-a3b-thinking-2507", + name: "Qwen: Qwen3 30B A3B Thinking 2507", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-07-29", + last_updated: "2025-07-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.051, output: 0.34 }, + limit: { context: 32768, output: 6554 }, + }, + "qwen/qwen-2.5-7b-instruct": { + id: "qwen/qwen-2.5-7b-instruct", + name: "Qwen: Qwen2.5 7B Instruct", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-09", + last_updated: "2025-04-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.04, output: 0.1 }, + limit: { context: 32768, output: 6554 }, + }, + "qwen/qwen-vl-max": { + id: "qwen/qwen-vl-max", + name: "Qwen: Qwen VL Max", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-04-08", + last_updated: "2025-08-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.8, output: 3.2 }, + limit: { context: 131072, output: 32768 }, + }, + "qwen/qwen3-coder-flash": { + id: "qwen/qwen3-coder-flash", + name: "Qwen: Qwen3 Coder Flash", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-07-23", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.195, output: 0.975, cache_read: 0.06 }, + limit: { context: 1000000, output: 65536 }, + }, + "qwen/qwen3-30b-a3b": { + id: "qwen/qwen3-30b-a3b", + name: "Qwen: Qwen3 30B A3B", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-04", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.08, output: 0.28, cache_read: 0.03 }, + limit: { context: 40960, output: 40960 }, + }, + "qwen/qwen3-next-80b-a3b-instruct": { + id: "qwen/qwen3-next-80b-a3b-instruct", + name: "Qwen: Qwen3 Next 80B A3B Instruct", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-09-11", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.09, output: 1.1 }, + limit: { context: 131072, output: 52429 }, + }, + "qwen/qwen3.5-plus-20260420": { + id: "qwen/qwen3.5-plus-20260420", + name: "Qwen: Qwen3.5 Plus 2026-04-20", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-27", + last_updated: "2026-05-01", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 2.4 }, + limit: { context: 1000000, output: 65536 }, + }, + "qwen/qwen3-coder-next": { + id: "qwen/qwen3-coder-next", + name: "Qwen: Qwen3 Coder Next", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2026-02-02", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.12, output: 0.75, cache_read: 0.035 }, + limit: { context: 262144, output: 65536 }, + }, + "qwen/qwen-2.5-coder-32b-instruct": { + id: "qwen/qwen-2.5-coder-32b-instruct", + name: "Qwen2.5 Coder 32B Instruct", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2024-11-11", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.2, cache_read: 0.015 }, + limit: { context: 32768, output: 8192 }, + }, + "qwen/qwen3-vl-30b-a3b-instruct": { + id: "qwen/qwen3-vl-30b-a3b-instruct", + name: "Qwen: Qwen3 VL 30B A3B Instruct", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-10-05", + last_updated: "2025-11-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.13, output: 0.52 }, + limit: { context: 131072, output: 32768 }, + }, + "qwen/qwen3-coder-30b-a3b-instruct": { + id: "qwen/qwen3-coder-30b-a3b-instruct", + name: "Qwen: Qwen3 Coder 30B A3B Instruct", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-07-31", + last_updated: "2025-07-31", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.07, output: 0.27 }, + limit: { context: 160000, output: 32768 }, + }, + "qwen/qwen3-max-thinking": { + id: "qwen/qwen3-max-thinking", + name: "Qwen: Qwen3 Max Thinking", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-01-23", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.78, output: 3.9 }, + limit: { context: 262144, output: 32768 }, + }, + "qwen/qwen-turbo": { + id: "qwen/qwen-turbo", + name: "Qwen: Qwen-Turbo", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-11-01", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.0325, output: 0.13, cache_read: 0.01 }, + limit: { context: 131072, output: 8192 }, + }, + "qwen/qwen3-vl-235b-a22b-instruct": { + id: "qwen/qwen3-vl-235b-a22b-instruct", + name: "Qwen: Qwen3 VL 235B A22B Instruct", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-09-23", + last_updated: "2026-01-10", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.88, cache_read: 0.11 }, + limit: { context: 262144, output: 52429 }, + }, + "qwen/qwen3-coder": { + id: "qwen/qwen3-coder", + name: "Qwen: Qwen3 Coder 480B A35B", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-07-23", + last_updated: "2025-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.22, output: 1, cache_read: 0.022 }, + limit: { context: 262144, output: 52429 }, + }, + "qwen/qwen3.5-9b": { + id: "qwen/qwen3.5-9b", + name: "Qwen: Qwen3.5-9B", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-10", + last_updated: "2026-03-15", + modalities: { input: ["image", "text", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.05, output: 0.15 }, + limit: { context: 256000, output: 32768 }, + }, + "qwen/qwen3-vl-8b-thinking": { + id: "qwen/qwen3-vl-8b-thinking", + name: "Qwen: Qwen3 VL 8B Thinking", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-10-15", + last_updated: "2025-11-25", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.117, output: 1.365 }, + limit: { context: 131072, output: 32768 }, + }, + "qwen/qwen3.6-max-preview": { + id: "qwen/qwen3.6-max-preview", + name: "Qwen: Qwen3.6 Max Preview", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-27", + last_updated: "2026-05-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.04, output: 6.24, cache_write: 1.3 }, + limit: { context: 262144, output: 65536 }, + }, + "qwen/qwen-plus-2025-07-28:thinking": { + id: "qwen/qwen-plus-2025-07-28:thinking", + name: "Qwen: Qwen Plus 0728 (thinking)", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-09-09", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.26, output: 0.78 }, + limit: { context: 1000000, output: 32768 }, + }, + "qwen/qwen-2.5-72b-instruct": { + id: "qwen/qwen-2.5-72b-instruct", + name: "Qwen2.5 72B Instruct", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-09", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.12, output: 0.39 }, + limit: { context: 32768, output: 16384 }, + }, + "qwen/qwen3-14b": { + id: "qwen/qwen3-14b", + name: "Qwen: Qwen3 14B", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-04", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.06, output: 0.24, cache_read: 0.025 }, + limit: { context: 40960, output: 40960 }, + }, + "qwen/qwen3.5-35b-a3b": { + id: "qwen/qwen3.5-35b-a3b", + name: "Qwen: Qwen3.5-35B-A3B", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-26", + last_updated: "2026-03-15", + modalities: { input: ["image", "text", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1625, output: 1.3 }, + limit: { context: 262144, output: 65536 }, + }, + "qwen/qwen3.5-plus-02-15": { + id: "qwen/qwen3.5-plus-02-15", + name: "Qwen: Qwen3.5 Plus 2026-02-15", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-15", + last_updated: "2026-03-15", + modalities: { input: ["image", "text", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.26, output: 1.56 }, + limit: { context: 1000000, output: 65536 }, + }, + "qwen/qwen3.6-flash": { + id: "qwen/qwen3.6-flash", + name: "Qwen: Qwen3.6 Flash", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-27", + last_updated: "2026-05-01", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 1.5, cache_write: 0.3125 }, + limit: { context: 1000000, output: 65536 }, + }, + "alfredpros/codellama-7b-instruct-solidity": { + id: "alfredpros/codellama-7b-instruct-solidity", + name: "AlfredPros: CodeLLaMa 7B Instruct Solidity", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-04-14", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.8, output: 1.2 }, + limit: { context: 4096, output: 4096 }, + }, + "kwaipilot/kat-coder-pro-v2": { + id: "kwaipilot/kat-coder-pro-v2", + name: "Kwaipilot: KAT-Coder-Pro V2", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2026-03-27", + last_updated: "2026-04-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2, cache_read: 0.06 }, + limit: { context: 256000, output: 80000 }, + }, + "google/gemini-2.5-pro-preview-05-06": { + id: "google/gemini-2.5-pro-preview-05-06", + name: "Google: Gemini 2.5 Pro Preview 05-06", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-05-06", + last_updated: "2026-03-15", + modalities: { input: ["audio", "image", "pdf", "text", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, reasoning: 10, cache_read: 0.125, cache_write: 0.375 }, + limit: { context: 1048576, output: 65535 }, + }, + "google/lyria-3-clip-preview": { + id: "google/lyria-3-clip-preview", + name: "Google: Lyria 3 Clip Preview", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2026-03-30", + last_updated: "2026-04-11", + modalities: { input: ["image", "text"], output: ["audio", "text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 1048576, output: 65536 }, + }, + "google/gemini-3.1-pro-preview-customtools": { + id: "google/gemini-3.1-pro-preview-customtools", + name: "Google: Gemini 3.1 Pro Preview Custom Tools", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-26", + last_updated: "2026-03-15", + modalities: { input: ["audio", "image", "pdf", "text", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 12, reasoning: 12 }, + limit: { context: 1048576, output: 65536 }, + }, + "google/gemini-2.5-flash-lite-preview-09-2025": { + id: "google/gemini-2.5-flash-lite-preview-09-2025", + name: "Google: Gemini 2.5 Flash Lite Preview 09-2025", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-09-25", + last_updated: "2026-03-15", + modalities: { input: ["audio", "image", "pdf", "text", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4, reasoning: 0.4, cache_read: 0.01, cache_write: 0.083333 }, + limit: { context: 1048576, output: 65536 }, + }, + "google/gemini-2.0-flash-001": { + id: "google/gemini-2.0-flash-001", + name: "Google: Gemini 2.0 Flash", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-12-11", + last_updated: "2026-03-15", + modalities: { input: ["audio", "image", "pdf", "text", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4, cache_read: 0.025, cache_write: 0.083333 }, + limit: { context: 1048576, output: 8192 }, + }, + "google/lyria-3-pro-preview": { + id: "google/lyria-3-pro-preview", + name: "Google: Lyria 3 Pro Preview", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2026-03-30", + last_updated: "2026-04-11", + modalities: { input: ["image", "text"], output: ["audio", "text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 1048576, output: 65536 }, + }, + "google/gemma-3n-e4b-it": { + id: "google/gemma-3n-e4b-it", + name: "Google: Gemma 3n 4B", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-05-20", + last_updated: "2025-05-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.02, output: 0.04 }, + limit: { context: 32768, output: 6554 }, + }, + "google/gemini-3.1-flash-lite-preview": { + id: "google/gemini-3.1-flash-lite-preview", + name: "Google: Gemini 3.1 Flash Lite Preview", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-03", + last_updated: "2026-03-15", + modalities: { input: ["audio", "image", "pdf", "text", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 1.5, reasoning: 1.5 }, + limit: { context: 1048576, output: 65536 }, + }, + "google/gemini-3.1-pro-preview": { + id: "google/gemini-3.1-pro-preview", + name: "Google: Gemini 3.1 Pro Preview", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-19", + last_updated: "2026-03-15", + modalities: { input: ["audio", "image", "pdf", "text", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 12, reasoning: 12 }, + limit: { context: 1048576, output: 65536 }, + }, + "google/gemini-3-flash-preview": { + id: "google/gemini-3-flash-preview", + name: "Google: Gemini 3 Flash Preview", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-12-17", + last_updated: "2026-03-15", + modalities: { input: ["audio", "image", "pdf", "text", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 3, reasoning: 3, cache_read: 0.05, cache_write: 0.083333 }, + limit: { context: 1048576, output: 65536 }, + }, + "google/gemini-2.5-pro": { + id: "google/gemini-2.5-pro", + name: "Google: Gemini 2.5 Pro", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-03-20", + last_updated: "2026-03-15", + modalities: { input: ["audio", "image", "pdf", "text", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, reasoning: 10, cache_read: 0.125, cache_write: 0.375 }, + limit: { context: 1048576, output: 65536 }, + }, + "google/gemini-3-pro-image-preview": { + id: "google/gemini-3-pro-image-preview", + name: "Google: Nano Banana Pro (Gemini 3 Pro Image Preview)", + attachment: true, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2025-11-20", + last_updated: "2026-03-15", + modalities: { input: ["image", "text"], output: ["image", "text"] }, + open_weights: false, + cost: { input: 2, output: 12, reasoning: 12 }, + limit: { context: 65536, output: 32768 }, + }, + "google/gemma-4-31b-it": { + id: "google/gemma-4-31b-it", + name: "Google: Gemma 4 31B", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-02", + last_updated: "2026-04-11", + modalities: { input: ["image", "text", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.14, output: 0.4 }, + limit: { context: 262144, output: 131072 }, + }, + "google/gemini-2.5-flash-image": { + id: "google/gemini-2.5-flash-image", + name: "Google: Nano Banana (Gemini 2.5 Flash Image)", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-10-08", + last_updated: "2026-03-15", + modalities: { input: ["image", "text"], output: ["image", "text"] }, + open_weights: false, + cost: { input: 0.3, output: 2.5 }, + limit: { context: 32768, output: 32768 }, + }, + "google/gemma-3-12b-it": { + id: "google/gemma-3-12b-it", + name: "Google: Gemma 3 12B", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-03-13", + last_updated: "2026-03-15", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.04, output: 0.13, cache_read: 0.015 }, + limit: { context: 131072, output: 131072 }, + }, + "google/gemini-2.5-flash": { + id: "google/gemini-2.5-flash", + name: "Google: Gemini 2.5 Flash", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-07-17", + last_updated: "2026-03-15", + modalities: { input: ["audio", "image", "pdf", "text", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 2.5, reasoning: 2.5, cache_read: 0.03, cache_write: 0.083333 }, + limit: { context: 1048576, output: 65535 }, + }, + "google/gemini-3.1-flash-image-preview": { + id: "google/gemini-3.1-flash-image-preview", + name: "Google: Nano Banana 2 (Gemini 3.1 Flash Image Preview)", + attachment: true, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2026-02-26", + last_updated: "2026-03-15", + modalities: { input: ["image", "text"], output: ["image", "text"] }, + open_weights: false, + cost: { input: 0.5, output: 3 }, + limit: { context: 65536, output: 65536 }, + }, + "google/gemma-3-4b-it": { + id: "google/gemma-3-4b-it", + name: "Google: Gemma 3 4B", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-03-13", + last_updated: "2026-03-15", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.04, output: 0.08 }, + limit: { context: 131072, output: 19200 }, + }, + "google/gemini-2.5-pro-preview": { + id: "google/gemini-2.5-pro-preview", + name: "Google: Gemini 2.5 Pro Preview 06-05", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-06-05", + last_updated: "2026-03-15", + modalities: { input: ["audio", "image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, reasoning: 10, cache_read: 0.125, cache_write: 0.375 }, + limit: { context: 1048576, output: 65536 }, + }, + "google/gemma-2-27b-it": { + id: "google/gemma-2-27b-it", + name: "Google: Gemma 2 27B", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2024-06-24", + last_updated: "2024-06-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.65, output: 0.65 }, + limit: { context: 8192, output: 2048 }, + }, + "google/gemma-3-27b-it": { + id: "google/gemma-3-27b-it", + name: "Google: Gemma 3 27B", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-03-12", + last_updated: "2026-03-15", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.03, output: 0.11, cache_read: 0.02 }, + limit: { context: 128000, output: 65536 }, + }, + "google/gemma-4-26b-a4b-it": { + id: "google/gemma-4-26b-a4b-it", + name: "Google: Gemma 4 26B A4B", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-03", + last_updated: "2026-04-11", + modalities: { input: ["image", "text", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.12, output: 0.4 }, + limit: { context: 262144, output: 262144 }, + }, + "google/gemini-2.5-flash-lite": { + id: "google/gemini-2.5-flash-lite", + name: "Google: Gemini 2.5 Flash Lite", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-06-17", + last_updated: "2026-03-15", + modalities: { input: ["audio", "image", "pdf", "text", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4, reasoning: 0.4, cache_read: 0.01, cache_write: 0.083333 }, + limit: { context: 1048576, output: 65535 }, + }, + "google/gemini-2.0-flash-lite-001": { + id: "google/gemini-2.0-flash-lite-001", + name: "Google: Gemini 2.0 Flash Lite", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-12-11", + last_updated: "2026-03-15", + modalities: { input: ["audio", "image", "pdf", "text", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.075, output: 0.3 }, + limit: { context: 1048576, output: 8192 }, + }, + "moonshotai/kimi-k2.5": { + id: "moonshotai/kimi-k2.5", + name: "MoonshotAI: Kimi K2.5", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-01-27", + last_updated: "2026-03-15", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.45, output: 2.2 }, + limit: { context: 262144, output: 65535 }, + }, + "moonshotai/kimi-k2-0905": { + id: "moonshotai/kimi-k2-0905", + name: "MoonshotAI: Kimi K2 0905", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-09-05", + last_updated: "2025-09-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.4, output: 2, cache_read: 0.15 }, + limit: { context: 131072, output: 26215 }, + }, + "moonshotai/kimi-k2.6": { + id: "moonshotai/kimi-k2.6", + name: "MoonshotAI: Kimi K2.6", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_details" }, + structured_output: true, + temperature: true, + release_date: "2026-04-20", + last_updated: "2026-04-20", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.95, output: 4, cache_read: 0.16 }, + limit: { context: 262144, output: 262144 }, + }, + "moonshotai/kimi-k2": { + id: "moonshotai/kimi-k2", + name: "MoonshotAI: Kimi K2 0711", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-07-11", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.55, output: 2.2 }, + limit: { context: 131000, output: 26215 }, + }, + "moonshotai/kimi-k2-thinking": { + id: "moonshotai/kimi-k2-thinking", + name: "MoonshotAI: Kimi K2 Thinking", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-11-06", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.47, output: 2, cache_read: 0.2 }, + limit: { context: 131072, output: 65535 }, + }, + "aion-labs/aion-1.0": { + id: "aion-labs/aion-1.0", + name: "AionLabs: Aion-1.0", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2025-02-05", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 4, output: 8 }, + limit: { context: 131072, output: 32768 }, + }, + "aion-labs/aion-rp-llama-3.1-8b": { + id: "aion-labs/aion-rp-llama-3.1-8b", + name: "AionLabs: Aion-RP 1.0 (8B)", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-02-05", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.8, output: 1.6 }, + limit: { context: 32768, output: 32768 }, + }, + "aion-labs/aion-2.0": { + id: "aion-labs/aion-2.0", + name: "AionLabs: Aion-2.0", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2026-02-24", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.8, output: 1.6 }, + limit: { context: 131072, output: 32768 }, + }, + "aion-labs/aion-1.0-mini": { + id: "aion-labs/aion-1.0-mini", + name: "AionLabs: Aion-1.0-Mini", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2025-02-05", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.7, output: 1.4 }, + limit: { context: 131072, output: 32768 }, + }, + "~moonshotai/kimi-latest": { + id: "~moonshotai/kimi-latest", + name: "MoonshotAI: Kimi Latest", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-27", + last_updated: "2026-05-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.74, output: 3.49, cache_read: 0.14 }, + limit: { context: 262142, output: 262142 }, + }, + "thedrummer/unslopnemo-12b": { + id: "thedrummer/unslopnemo-12b", + name: "TheDrummer: UnslopNemo 12B", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-11-09", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.4, output: 0.4 }, + limit: { context: 32768, output: 32768 }, + }, + "thedrummer/cydonia-24b-v4.1": { + id: "thedrummer/cydonia-24b-v4.1", + name: "TheDrummer: Cydonia 24B V4.1", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-09-27", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 0.5 }, + limit: { context: 131072, output: 131072 }, + }, + "thedrummer/skyfall-36b-v2": { + id: "thedrummer/skyfall-36b-v2", + name: "TheDrummer: Skyfall 36B V2", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-03-11", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.55, output: 0.8 }, + limit: { context: 32768, output: 32768 }, + }, + "thedrummer/rocinante-12b": { + id: "thedrummer/rocinante-12b", + name: "TheDrummer: Rocinante 12B", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-09-30", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.17, output: 0.43 }, + limit: { context: 32768, output: 32768 }, + }, + "anthropic/claude-opus-4.1": { + id: "anthropic/claude-opus-4.1", + name: "Anthropic: Claude Opus 4.1", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-05", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 32000 }, + }, + "anthropic/claude-3.7-sonnet:thinking": { + id: "anthropic/claude-3.7-sonnet:thinking", + name: "Anthropic: Claude 3.7 Sonnet (thinking)", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-02-19", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + }, + "anthropic/claude-opus-4.6-fast": { + id: "anthropic/claude-opus-4.6-fast", + name: "Anthropic: Claude Opus 4.6 (Fast)", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-05-31", + release_date: "2026-04-07", + last_updated: "2026-04-11", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 30, output: 150, cache_read: 3, cache_write: 37.5 }, + limit: { context: 1000000, output: 128000 }, + }, + "anthropic/claude-3.7-sonnet": { + id: "anthropic/claude-3.7-sonnet", + name: "Anthropic: Claude 3.7 Sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-02-19", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + }, + "anthropic/claude-opus-4.6": { + id: "anthropic/claude-opus-4.6", + name: "Anthropic: Claude Opus 4.6", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-05-31", + release_date: "2026-02-05", + last_updated: "2026-02-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 1000000, output: 128000 }, + }, + "anthropic/claude-opus-4.7": { + id: "anthropic/claude-opus-4.7", + name: "Anthropic: Claude Opus 4.7", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2026-04-16", + last_updated: "2026-05-01", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 1000000, output: 128000 }, + }, + "anthropic/claude-sonnet-4": { + id: "anthropic/claude-sonnet-4", + name: "Anthropic: Claude Sonnet 4", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-05-22", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + }, + "anthropic/claude-sonnet-4.5": { + id: "anthropic/claude-sonnet-4.5", + name: "Anthropic: Claude Sonnet 4.5", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-09-29", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 1000000, output: 64000 }, + }, + "anthropic/claude-opus-4.5": { + id: "anthropic/claude-opus-4.5", + name: "Anthropic: Claude Opus 4.5", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-11-24", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 200000, output: 64000 }, + }, + "anthropic/claude-3-haiku": { + id: "anthropic/claude-3-haiku", + name: "Anthropic: Claude 3 Haiku", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-03-07", + last_updated: "2024-03-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 1.25, cache_read: 0.03, cache_write: 0.3 }, + limit: { context: 200000, output: 4096 }, + }, + "anthropic/claude-opus-4": { + id: "anthropic/claude-opus-4", + name: "Anthropic: Claude Opus 4", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-05-22", + last_updated: "2026-03-15", + modalities: { input: ["image", "pdf", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 32000 }, + }, + "anthropic/claude-3.5-haiku": { + id: "anthropic/claude-3.5-haiku", + name: "Anthropic: Claude 3.5 Haiku", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-10-22", + last_updated: "2024-10-22", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.8, output: 4, cache_read: 0.08, cache_write: 1 }, + limit: { context: 200000, output: 8192 }, + }, + "anthropic/claude-haiku-4.5": { + id: "anthropic/claude-haiku-4.5", + name: "Anthropic: Claude Haiku 4.5", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-10-15", + last_updated: "2025-10-15", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 5, cache_read: 0.1, cache_write: 1.25 }, + limit: { context: 200000, output: 64000 }, + }, + "anthropic/claude-sonnet-4.6": { + id: "anthropic/claude-sonnet-4.6", + name: "Anthropic: Claude Sonnet 4.6", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-08-31", + release_date: "2026-02-17", + last_updated: "2026-03-15", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15 }, + limit: { context: 1000000, output: 128000 }, + }, + "switchpoint/router": { + id: "switchpoint/router", + name: "Switchpoint Router", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2025-07-12", + last_updated: "2026-03-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.85, output: 3.4 }, + limit: { context: 131072, output: 32768 }, + }, + "bytedance/ui-tars-1.5-7b": { + id: "bytedance/ui-tars-1.5-7b", + name: "ByteDance: UI-TARS 7B ", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-07-23", + last_updated: "2026-03-15", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.2 }, + limit: { context: 128000, output: 2048 }, + }, + "tngtech/deepseek-r1t2-chimera": { + id: "tngtech/deepseek-r1t2-chimera", + name: "TNG: DeepSeek R1T2 Chimera", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-07-08", + last_updated: "2025-07-08", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.25, output: 0.85, cache_read: 0.125 }, + limit: { context: 163840, output: 163840 }, + }, + "xiaomi/mimo-v2.5-pro": { + id: "xiaomi/mimo-v2.5-pro", + name: "Xiaomi: MiMo V2.5 Pro", + family: "mimo", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12", + release_date: "2026-04-22", + last_updated: "2026-04-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 3, cache_read: 0.2, context_over_200k: { input: 2, output: 6, cache_read: 0.4 } }, + limit: { context: 1048576, output: 131072 }, + }, + "xiaomi/mimo-v2-omni": { + id: "xiaomi/mimo-v2-omni", + name: "Xiaomi: MiMo-V2-Omni", + family: "mimo", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-12", + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 2, cache_read: 0.08 }, + limit: { context: 262144, output: 65536 }, + }, + "xiaomi/mimo-v2.5": { + id: "xiaomi/mimo-v2.5", + name: "Xiaomi: MiMo-V2.5", + family: "mimo", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12", + release_date: "2026-04-22", + last_updated: "2026-04-22", + modalities: { input: ["text", "image", "audio", "video"], output: ["text"] }, + open_weights: true, + cost: { + input: 0.4, + output: 2, + cache_read: 0.08, + context_over_200k: { input: 0.8, output: 4, cache_read: 0.16 }, + }, + limit: { context: 1048576, output: 131072 }, + }, + "xiaomi/mimo-v2-pro": { + id: "xiaomi/mimo-v2-pro", + name: "Xiaomi: MiMo-V2-Pro", + family: "mimo", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-12", + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 3, cache_read: 0.2, context_over_200k: { input: 2, output: 6, cache_read: 0.4 } }, + limit: { context: 1048576, output: 131072 }, + }, + "xiaomi/mimo-v2-flash": { + id: "xiaomi/mimo-v2-flash", + name: "Xiaomi: MiMo-V2-Flash", + family: "mimo", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-12-01", + release_date: "2025-12-16", + last_updated: "2026-02-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.09, output: 0.29, cache_read: 0.045 }, + limit: { context: 262144, output: 65536 }, + }, + }, + }, + "sap-ai-core": { + id: "sap-ai-core", + env: ["AICORE_SERVICE_KEY"], + npm: "@jerome-benoit/sap-ai-provider-v2", + name: "SAP AI Core", + doc: "https://help.sap.com/docs/sap-ai-core", + models: { + "anthropic--claude-4.6-opus": { + id: "anthropic--claude-4.6-opus", + name: "anthropic--claude-4.6-opus", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-05", + release_date: "2026-02-05", + last_updated: "2026-03-13", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 1000000, output: 128000 }, + }, + "anthropic--claude-3-haiku": { + id: "anthropic--claude-3-haiku", + name: "anthropic--claude-3-haiku", + family: "claude-haiku", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-08-31", + release_date: "2024-03-13", + last_updated: "2024-03-13", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 1.25, cache_read: 0.03, cache_write: 0.3 }, + limit: { context: 200000, output: 4096 }, + }, + "anthropic--claude-3-opus": { + id: "anthropic--claude-3-opus", + name: "anthropic--claude-3-opus", + family: "claude-opus", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-08-31", + release_date: "2024-02-29", + last_updated: "2024-02-29", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 4096 }, + }, + "gpt-5-mini": { + id: "gpt-5-mini", + name: "gpt-5-mini", + family: "gpt-mini", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-05-30", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 2, cache_read: 0.025 }, + limit: { context: 400000, output: 128000 }, + }, + "gpt-5-nano": { + id: "gpt-5-nano", + name: "gpt-5-nano", + family: "gpt-nano", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-05-30", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.05, output: 0.4, cache_read: 0.005 }, + limit: { context: 400000, output: 128000 }, + }, + "gemini-2.5-pro": { + id: "gemini-2.5-pro", + name: "gemini-2.5-pro", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-03-25", + last_updated: "2025-06-05", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 1048576, output: 65536 }, + }, + "anthropic--claude-3.7-sonnet": { + id: "anthropic--claude-3.7-sonnet", + name: "anthropic--claude-3.7-sonnet", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10-31", + release_date: "2025-02-24", + last_updated: "2025-02-24", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + }, + "sonar-pro": { + id: "sonar-pro", + name: "sonar-pro", + family: "sonar-pro", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2025-09-01", + release_date: "2024-01-01", + last_updated: "2025-09-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15 }, + limit: { context: 200000, output: 8192 }, + }, + "anthropic--claude-4.5-sonnet": { + id: "anthropic--claude-4.5-sonnet", + name: "anthropic--claude-4.5-sonnet", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07-31", + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + }, + "anthropic--claude-4.6-sonnet": { + id: "anthropic--claude-4.6-sonnet", + name: "anthropic--claude-4.6-sonnet", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-08", + release_date: "2026-02-17", + last_updated: "2026-03-13", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 1000000, output: 64000 }, + }, + "sonar-deep-research": { + id: "sonar-deep-research", + name: "sonar-deep-research", + family: "sonar-deep-research", + attachment: false, + reasoning: true, + tool_call: false, + temperature: false, + knowledge: "2025-01", + release_date: "2025-02-01", + last_updated: "2025-09-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 8, reasoning: 3 }, + limit: { context: 128000, output: 32768 }, + }, + "gemini-2.5-flash": { + id: "gemini-2.5-flash", + name: "gemini-2.5-flash", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-03-25", + last_updated: "2025-06-05", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 2.5, cache_read: 0.03, input_audio: 1 }, + limit: { context: 1048576, output: 65536 }, + }, + "anthropic--claude-4.5-opus": { + id: "anthropic--claude-4.5-opus", + name: "anthropic--claude-4.5-opus", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-05", + release_date: "2025-11-24", + last_updated: "2025-11-24", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 200000, output: 64000 }, + }, + sonar: { + id: "sonar", + name: "sonar", + family: "sonar", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2025-09-01", + release_date: "2024-01-01", + last_updated: "2025-09-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 1 }, + limit: { context: 128000, output: 4096 }, + }, + "anthropic--claude-4-opus": { + id: "anthropic--claude-4-opus", + name: "anthropic--claude-4-opus", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 32000 }, + }, + "anthropic--claude-3-sonnet": { + id: "anthropic--claude-3-sonnet", + name: "anthropic--claude-3-sonnet", + family: "claude-sonnet", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-08-31", + release_date: "2024-03-04", + last_updated: "2024-03-04", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 4096 }, + }, + "anthropic--claude-4-sonnet": { + id: "anthropic--claude-4-sonnet", + name: "anthropic--claude-4-sonnet", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + }, + "gemini-2.5-flash-lite": { + id: "gemini-2.5-flash-lite", + name: "gemini-2.5-flash-lite", + family: "gemini-flash-lite", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-06-17", + last_updated: "2025-06-17", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4, cache_read: 0.025 }, + limit: { context: 1048576, output: 65536 }, + }, + "anthropic--claude-4.5-haiku": { + id: "anthropic--claude-4.5-haiku", + name: "anthropic--claude-4.5-haiku", + family: "claude-haiku", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-02-28", + release_date: "2025-10-15", + last_updated: "2025-10-15", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 5, cache_read: 0.1, cache_write: 1.25 }, + limit: { context: 200000, output: 64000 }, + }, + "gpt-5": { + id: "gpt-5", + name: "gpt-5", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 400000, output: 128000 }, + }, + "gpt-4.1": { + id: "gpt-4.1", + name: "gpt-4.1", + 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"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 8, cache_read: 0.5 }, + limit: { context: 1047576, output: 32768 }, + }, + "gpt-4.1-mini": { + id: "gpt-4.1-mini", + name: "gpt-4.1-mini", + family: "gpt-mini", + 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"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 1.6, cache_read: 0.1 }, + limit: { context: 1047576, output: 32768 }, + }, + "anthropic--claude-3.5-sonnet": { + id: "anthropic--claude-3.5-sonnet", + name: "anthropic--claude-3.5-sonnet", + family: "claude-sonnet", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04-30", + release_date: "2024-10-22", + last_updated: "2024-10-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 8192 }, + }, + }, + }, + morph: { + id: "morph", + env: ["MORPH_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.morphllm.com/v1", + name: "Morph", + doc: "https://docs.morphllm.com/api-reference/introduction", + models: { + auto: { + id: "auto", + name: "Auto", + family: "auto", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2024-06-01", + last_updated: "2024-06-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.85, output: 1.55 }, + limit: { context: 32000, output: 32000 }, + }, + "morph-v3-fast": { + id: "morph-v3-fast", + name: "Morph v3 Fast", + family: "morph", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2024-08-15", + last_updated: "2024-08-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.8, output: 1.2 }, + limit: { context: 16000, output: 16000 }, + }, + "morph-v3-large": { + id: "morph-v3-large", + name: "Morph v3 Large", + family: "morph", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2024-08-15", + last_updated: "2024-08-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.9, output: 1.9 }, + limit: { context: 32000, output: 32000 }, + }, + }, + }, + "cloudflare-ai-gateway": { + id: "cloudflare-ai-gateway", + env: ["CLOUDFLARE_API_TOKEN", "CLOUDFLARE_ACCOUNT_ID", "CLOUDFLARE_GATEWAY_ID"], + npm: "ai-gateway-provider", + name: "Cloudflare AI Gateway", + doc: "https://developers.cloudflare.com/ai-gateway/", + models: { + "workers-ai/@cf/myshell-ai/melotts": { + id: "workers-ai/@cf/myshell-ai/melotts", + name: "MyShell MeloTTS", + family: "melotts", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-11-14", + last_updated: "2025-11-14", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 16384 }, + }, + "workers-ai/@cf/ibm-granite/granite-4.0-h-micro": { + id: "workers-ai/@cf/ibm-granite/granite-4.0-h-micro", + name: "IBM Granite 4.0 H Micro", + family: "granite", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-10-15", + last_updated: "2025-10-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.017, output: 0.11 }, + limit: { context: 128000, output: 16384 }, + }, + "workers-ai/@cf/huggingface/distilbert-sst-2-int8": { + id: "workers-ai/@cf/huggingface/distilbert-sst-2-int8", + name: "DistilBERT SST-2 INT8", + family: "distilbert", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-04-03", + last_updated: "2025-04-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.026, output: 0 }, + limit: { context: 128000, output: 16384 }, + }, + "workers-ai/@cf/zai-org/glm-4.7-flash": { + id: "workers-ai/@cf/zai-org/glm-4.7-flash", + name: "GLM-4.7-Flash", + family: "glm-flash", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-01-19", + last_updated: "2026-01-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.06, output: 0.4 }, + limit: { context: 131072, output: 131072 }, + }, + "workers-ai/@cf/pipecat-ai/smart-turn-v2": { + id: "workers-ai/@cf/pipecat-ai/smart-turn-v2", + name: "Pipecat Smart Turn v2", + family: "smart-turn", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-11-14", + last_updated: "2025-11-14", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 16384 }, + }, + "workers-ai/@cf/mistralai/mistral-small-3.1-24b-instruct": { + id: "workers-ai/@cf/mistralai/mistral-small-3.1-24b-instruct", + name: "Mistral Small 3.1 24B Instruct", + family: "mistral-small", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-04-11", + last_updated: "2025-04-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.35, output: 0.56 }, + limit: { context: 128000, output: 16384 }, + }, + "workers-ai/@cf/facebook/bart-large-cnn": { + id: "workers-ai/@cf/facebook/bart-large-cnn", + name: "BART Large CNN", + family: "bart", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-04-09", + last_updated: "2025-04-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 16384 }, + }, + "workers-ai/@cf/aisingapore/gemma-sea-lion-v4-27b-it": { + id: "workers-ai/@cf/aisingapore/gemma-sea-lion-v4-27b-it", + name: "Gemma SEA-LION v4 27B IT", + family: "gemma", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-09-25", + last_updated: "2025-09-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.35, output: 0.56 }, + limit: { context: 128000, output: 16384 }, + }, + "workers-ai/@cf/nvidia/nemotron-3-120b-a12b": { + id: "workers-ai/@cf/nvidia/nemotron-3-120b-a12b", + name: "Nemotron 3 Super 120B", + family: "nemotron", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-03-11", + last_updated: "2026-03-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.5, output: 1.5 }, + limit: { context: 256000, output: 256000 }, + }, + "workers-ai/@cf/deepseek-ai/deepseek-r1-distill-qwen-32b": { + id: "workers-ai/@cf/deepseek-ai/deepseek-r1-distill-qwen-32b", + name: "DeepSeek R1 Distill Qwen 32B", + family: "deepseek-thinking", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-04-03", + last_updated: "2025-04-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 4.88 }, + limit: { context: 128000, output: 16384 }, + }, + "workers-ai/@cf/openai/gpt-oss-20b": { + id: "workers-ai/@cf/openai/gpt-oss-20b", + name: "GPT OSS 20B", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.3 }, + limit: { context: 128000, output: 16384 }, + }, + "workers-ai/@cf/openai/gpt-oss-120b": { + id: "workers-ai/@cf/openai/gpt-oss-120b", + name: "GPT OSS 120B", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.35, output: 0.75 }, + limit: { context: 128000, output: 16384 }, + }, + "workers-ai/@cf/mistral/mistral-7b-instruct-v0.1": { + id: "workers-ai/@cf/mistral/mistral-7b-instruct-v0.1", + name: "Mistral 7B Instruct v0.1", + family: "mistral", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-04-03", + last_updated: "2025-04-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.11, output: 0.19 }, + limit: { context: 128000, output: 16384 }, + }, + "workers-ai/@cf/meta/llama-4-scout-17b-16e-instruct": { + id: "workers-ai/@cf/meta/llama-4-scout-17b-16e-instruct", + name: "Llama 4 Scout 17B 16E Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-04-16", + last_updated: "2025-04-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.27, output: 0.85 }, + limit: { context: 128000, output: 16384 }, + }, + "workers-ai/@cf/meta/llama-3-8b-instruct-awq": { + id: "workers-ai/@cf/meta/llama-3-8b-instruct-awq", + name: "Llama 3 8B Instruct AWQ", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-04-03", + last_updated: "2025-04-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.12, output: 0.27 }, + limit: { context: 128000, output: 16384 }, + }, + "workers-ai/@cf/meta/llama-guard-3-8b": { + id: "workers-ai/@cf/meta/llama-guard-3-8b", + name: "Llama Guard 3 8B", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-04-03", + last_updated: "2025-04-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.48, output: 0.03 }, + limit: { context: 128000, output: 16384 }, + }, + "workers-ai/@cf/meta/m2m100-1.2b": { + id: "workers-ai/@cf/meta/m2m100-1.2b", + name: "M2M100 1.2B", + family: "m2m", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-04-03", + last_updated: "2025-04-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.34, output: 0.34 }, + limit: { context: 128000, output: 16384 }, + }, + "workers-ai/@cf/meta/llama-2-7b-chat-fp16": { + id: "workers-ai/@cf/meta/llama-2-7b-chat-fp16", + name: "Llama 2 7B Chat FP16", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-04-03", + last_updated: "2025-04-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.56, output: 6.67 }, + limit: { context: 128000, output: 16384 }, + }, + "workers-ai/@cf/meta/llama-3.2-11b-vision-instruct": { + id: "workers-ai/@cf/meta/llama-3.2-11b-vision-instruct", + name: "Llama 3.2 11B Vision Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-04-03", + last_updated: "2025-04-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.049, output: 0.68 }, + limit: { context: 128000, output: 16384 }, + }, + "workers-ai/@cf/meta/llama-3.3-70b-instruct-fp8-fast": { + id: "workers-ai/@cf/meta/llama-3.3-70b-instruct-fp8-fast", + name: "Llama 3.3 70B Instruct FP8 Fast", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-04-03", + last_updated: "2025-04-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.29, output: 2.25 }, + limit: { context: 128000, output: 16384 }, + }, + "workers-ai/@cf/meta/llama-3.2-1b-instruct": { + id: "workers-ai/@cf/meta/llama-3.2-1b-instruct", + name: "Llama 3.2 1B Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-04-03", + last_updated: "2025-04-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.027, output: 0.2 }, + limit: { context: 128000, output: 16384 }, + }, + "workers-ai/@cf/meta/llama-3.1-8b-instruct-fp8": { + id: "workers-ai/@cf/meta/llama-3.1-8b-instruct-fp8", + name: "Llama 3.1 8B Instruct FP8", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-04-03", + last_updated: "2025-04-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.29 }, + limit: { context: 128000, output: 16384 }, + }, + "workers-ai/@cf/meta/llama-3.2-3b-instruct": { + id: "workers-ai/@cf/meta/llama-3.2-3b-instruct", + name: "Llama 3.2 3B Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-04-03", + last_updated: "2025-04-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.051, output: 0.34 }, + limit: { context: 128000, output: 16384 }, + }, + "workers-ai/@cf/meta/llama-3.1-8b-instruct-awq": { + id: "workers-ai/@cf/meta/llama-3.1-8b-instruct-awq", + name: "Llama 3.1 8B Instruct AWQ", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-04-03", + last_updated: "2025-04-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.12, output: 0.27 }, + limit: { context: 128000, output: 16384 }, + }, + "workers-ai/@cf/meta/llama-3-8b-instruct": { + id: "workers-ai/@cf/meta/llama-3-8b-instruct", + name: "Llama 3 8B Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-04-03", + last_updated: "2025-04-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.28, output: 0.83 }, + limit: { context: 128000, output: 16384 }, + }, + "workers-ai/@cf/meta/llama-3.1-8b-instruct": { + id: "workers-ai/@cf/meta/llama-3.1-8b-instruct", + name: "Llama 3.1 8B Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-04-03", + last_updated: "2025-04-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.28, output: 0.8299999999999998 }, + limit: { context: 128000, output: 16384 }, + }, + "workers-ai/@cf/qwen/qwen2.5-coder-32b-instruct": { + id: "workers-ai/@cf/qwen/qwen2.5-coder-32b-instruct", + name: "Qwen 2.5 Coder 32B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-04-11", + last_updated: "2025-04-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.66, output: 1 }, + limit: { context: 128000, output: 16384 }, + }, + "workers-ai/@cf/qwen/qwen3-embedding-0.6b": { + id: "workers-ai/@cf/qwen/qwen3-embedding-0.6b", + name: "Qwen3 Embedding 0.6B", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-11-14", + last_updated: "2025-11-14", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.012, output: 0 }, + limit: { context: 128000, output: 16384 }, + }, + "workers-ai/@cf/qwen/qwq-32b": { + id: "workers-ai/@cf/qwen/qwq-32b", + name: "QwQ 32B", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-04-11", + last_updated: "2025-04-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.66, output: 1 }, + limit: { context: 128000, output: 16384 }, + }, + "workers-ai/@cf/qwen/qwen3-30b-a3b-fp8": { + id: "workers-ai/@cf/qwen/qwen3-30b-a3b-fp8", + name: "Qwen3 30B A3B FP8", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-11-14", + last_updated: "2025-11-14", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.051, output: 0.34 }, + limit: { context: 128000, output: 16384 }, + }, + "workers-ai/@cf/google/gemma-3-12b-it": { + id: "workers-ai/@cf/google/gemma-3-12b-it", + name: "Gemma 3 12B IT", + family: "gemma", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-04-11", + last_updated: "2025-04-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.35, output: 0.56 }, + limit: { context: 128000, output: 16384 }, + }, + "workers-ai/@cf/moonshotai/kimi-k2.5": { + id: "workers-ai/@cf/moonshotai/kimi-k2.5", + name: "Kimi K2.5", + family: "kimi", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-01-27", + last_updated: "2026-01-27", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 3, cache_read: 0.1 }, + limit: { context: 256000, output: 256000 }, + }, + "workers-ai/@cf/moonshotai/kimi-k2.6": { + id: "workers-ai/@cf/moonshotai/kimi-k2.6", + name: "Kimi K2.6", + family: "kimi", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-04-20", + last_updated: "2026-04-20", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.95, output: 4, cache_read: 0.16 }, + limit: { context: 256000, output: 256000 }, + }, + "workers-ai/@cf/ai4bharat/indictrans2-en-indic-1B": { + id: "workers-ai/@cf/ai4bharat/indictrans2-en-indic-1B", + name: "IndicTrans2 EN-Indic 1B", + family: "indictrans", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-09-25", + last_updated: "2025-09-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.34, output: 0.34 }, + limit: { context: 128000, output: 16384 }, + }, + "workers-ai/@cf/pfnet/plamo-embedding-1b": { + id: "workers-ai/@cf/pfnet/plamo-embedding-1b", + name: "PLaMo Embedding 1B", + family: "plamo", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-09-25", + last_updated: "2025-09-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.019, output: 0 }, + limit: { context: 128000, output: 16384 }, + }, + "workers-ai/@cf/baai/bge-small-en-v1.5": { + id: "workers-ai/@cf/baai/bge-small-en-v1.5", + name: "BGE Small EN v1.5", + family: "bge", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-04-03", + last_updated: "2025-04-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.02, output: 0 }, + limit: { context: 128000, output: 16384 }, + }, + "workers-ai/@cf/baai/bge-large-en-v1.5": { + id: "workers-ai/@cf/baai/bge-large-en-v1.5", + name: "BGE Large EN v1.5", + family: "bge", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-04-03", + last_updated: "2025-04-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0 }, + limit: { context: 128000, output: 16384 }, + }, + "workers-ai/@cf/baai/bge-reranker-base": { + id: "workers-ai/@cf/baai/bge-reranker-base", + name: "BGE Reranker Base", + family: "bge", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-04-09", + last_updated: "2025-04-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.0031, output: 0 }, + limit: { context: 128000, output: 16384 }, + }, + "workers-ai/@cf/baai/bge-base-en-v1.5": { + id: "workers-ai/@cf/baai/bge-base-en-v1.5", + name: "BGE Base EN v1.5", + family: "bge", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-04-03", + last_updated: "2025-04-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.067, output: 0 }, + limit: { context: 128000, output: 16384 }, + }, + "workers-ai/@cf/baai/bge-m3": { + id: "workers-ai/@cf/baai/bge-m3", + name: "BGE M3", + family: "bge", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-04-03", + last_updated: "2025-04-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.012, output: 0 }, + limit: { context: 128000, output: 16384 }, + }, + "workers-ai/@cf/deepgram/aura-2-en": { + id: "workers-ai/@cf/deepgram/aura-2-en", + name: "Deepgram Aura 2 (EN)", + family: "aura", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-11-14", + last_updated: "2025-11-14", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 16384 }, + }, + "workers-ai/@cf/deepgram/aura-2-es": { + id: "workers-ai/@cf/deepgram/aura-2-es", + name: "Deepgram Aura 2 (ES)", + family: "aura", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-11-14", + last_updated: "2025-11-14", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 16384 }, + }, + "workers-ai/@cf/deepgram/nova-3": { + id: "workers-ai/@cf/deepgram/nova-3", + name: "Deepgram Nova 3", + family: "nova", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-11-14", + last_updated: "2025-11-14", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 16384 }, + }, + "openai/gpt-5.3-codex": { + id: "openai/gpt-5.3-codex", + name: "GPT-5.3 Codex", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-02-05", + last_updated: "2026-02-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 400000, input: 272000, output: 128000 }, + provider: { npm: "ai-gateway-provider" }, + }, + "openai/gpt-4-turbo": { + id: "openai/gpt-4-turbo", + name: "GPT-4 Turbo", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + knowledge: "2023-12", + release_date: "2023-11-06", + last_updated: "2024-04-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 10, output: 30 }, + limit: { context: 128000, output: 4096 }, + }, + "openai/gpt-5.2": { + id: "openai/gpt-5.2", + name: "GPT-5.2", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2025-12-11", + last_updated: "2025-12-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/o3-pro": { + id: "openai/o3-pro", + name: "o3-pro", + family: "o-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-05", + release_date: "2025-06-10", + last_updated: "2025-06-10", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 20, output: 80 }, + limit: { context: 200000, output: 100000 }, + }, + "openai/gpt-4o-mini": { + id: "openai/gpt-4o-mini", + name: "GPT-4o mini", + family: "gpt-mini", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2023-09", + release_date: "2024-07-18", + last_updated: "2024-07-18", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.6, cache_read: 0.08 }, + limit: { context: 128000, output: 16384 }, + }, + "openai/o4-mini": { + id: "openai/o4-mini", + name: "o4-mini", + family: "o-mini", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-05", + release_date: "2025-04-16", + last_updated: "2025-04-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 4.4, cache_read: 0.28 }, + limit: { context: 200000, output: 100000 }, + }, + "openai/gpt-5.2-codex": { + id: "openai/gpt-5.2-codex", + name: "GPT-5.2 Codex", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2025-12-11", + last_updated: "2025-12-11", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 400000, input: 272000, output: 128000 }, + provider: { npm: "ai-gateway-provider" }, + }, + "openai/gpt-5.1": { + id: "openai/gpt-5.1", + name: "GPT-5.1", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.13 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/o1": { + id: "openai/o1", + name: "o1", + family: "o", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2023-09", + release_date: "2024-12-05", + last_updated: "2024-12-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 60, cache_read: 7.5 }, + limit: { context: 200000, output: 100000 }, + }, + "openai/gpt-3.5-turbo": { + id: "openai/gpt-3.5-turbo", + name: "GPT-3.5-turbo", + family: "gpt", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + knowledge: "2021-09-01", + release_date: "2023-03-01", + last_updated: "2023-11-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 1.5, cache_read: 1.25 }, + limit: { context: 16385, output: 4096 }, + }, + "openai/o3-mini": { + id: "openai/o3-mini", + name: "o3-mini", + family: "o-mini", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-05", + release_date: "2024-12-20", + last_updated: "2025-01-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 4.4, cache_read: 0.55 }, + limit: { context: 200000, output: 100000 }, + }, + "openai/gpt-4": { + id: "openai/gpt-4", + name: "GPT-4", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + knowledge: "2023-11", + release_date: "2023-11-06", + last_updated: "2024-04-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 30, output: 60 }, + limit: { context: 8192, output: 8192 }, + }, + "openai/gpt-5.4": { + id: "openai/gpt-5.4", + name: "GPT-5.4", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-05", + last_updated: "2026-03-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 15, cache_read: 0.25 }, + limit: { context: 1050000, input: 922000, output: 128000 }, + provider: { npm: "ai-gateway-provider" }, + }, + "openai/o3": { + id: "openai/o3", + name: "o3", + family: "o", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-05", + release_date: "2025-04-16", + last_updated: "2025-04-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 8, cache_read: 0.5 }, + limit: { context: 200000, output: 100000 }, + }, + "openai/gpt-4o": { + id: "openai/gpt-4o", + name: "GPT-4o", + 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"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 10, cache_read: 1.25 }, + limit: { context: 128000, output: 16384 }, + }, + "openai/gpt-5.1-codex": { + id: "openai/gpt-5.1-codex", + name: "GPT-5.1 Codex", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 400000, output: 128000 }, + }, + "anthropic/claude-haiku-4-5": { + id: "anthropic/claude-haiku-4-5", + name: "Claude Haiku 4.5 (latest)", + family: "claude-haiku", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-02-28", + release_date: "2025-10-15", + last_updated: "2025-10-15", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 5, cache_read: 0.1, cache_write: 1.25 }, + limit: { context: 200000, output: 64000 }, + }, + "anthropic/claude-sonnet-4-6": { + id: "anthropic/claude-sonnet-4-6", + name: "Claude Sonnet 4.6", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: true, + temperature: true, + knowledge: "2025-08-31", + release_date: "2026-02-17", + last_updated: "2026-02-17", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 3, + output: 15, + cache_read: 0.3, + cache_write: 3.75, + context_over_200k: { input: 6, output: 22.5, cache_read: 0.6, cache_write: 7.5 }, + }, + limit: { context: 1000000, output: 64000 }, + provider: { npm: "ai-gateway-provider" }, + }, + "anthropic/claude-opus-4-7": { + id: "anthropic/claude-opus-4-7", + name: "Claude Opus 4.7", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2026-01", + release_date: "2026-04-16", + last_updated: "2026-04-16", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 1000000, output: 128000 }, + provider: { npm: "@ai-sdk/anthropic" }, + }, + "anthropic/claude-opus-4-1": { + id: "anthropic/claude-opus-4-1", + name: "Claude Opus 4.1 (latest)", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 32000 }, + }, + "anthropic/claude-3-5-haiku": { + id: "anthropic/claude-3-5-haiku", + name: "Claude Haiku 3.5 (latest)", + family: "claude-haiku", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-07-31", + release_date: "2024-10-22", + last_updated: "2024-10-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.8, output: 4, cache_read: 0.08, cache_write: 1 }, + limit: { context: 200000, output: 8192 }, + }, + "anthropic/claude-3.5-sonnet": { + id: "anthropic/claude-3.5-sonnet", + name: "Claude Sonnet 3.5 v2", + family: "claude-sonnet", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04-30", + release_date: "2024-10-22", + last_updated: "2024-10-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 8192 }, + }, + "anthropic/claude-sonnet-4": { + id: "anthropic/claude-sonnet-4", + name: "Claude Sonnet 4 (latest)", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + }, + "anthropic/claude-opus-4-5": { + id: "anthropic/claude-opus-4-5", + name: "Claude Opus 4.5 (latest)", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-11-24", + last_updated: "2025-11-24", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 200000, output: 64000 }, + }, + "anthropic/claude-3-haiku": { + id: "anthropic/claude-3-haiku", + name: "Claude Haiku 3", + family: "claude-haiku", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-08-31", + release_date: "2024-03-13", + last_updated: "2024-03-13", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 1.25, cache_read: 0.03, cache_write: 0.3 }, + limit: { context: 200000, output: 4096 }, + }, + "anthropic/claude-opus-4": { + id: "anthropic/claude-opus-4", + name: "Claude Opus 4 (latest)", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 32000 }, + }, + "anthropic/claude-opus-4-6": { + id: "anthropic/claude-opus-4-6", + name: "Claude Opus 4.6 (latest)", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-05-31", + release_date: "2026-02-05", + last_updated: "2026-02-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 5, + output: 25, + cache_read: 0.5, + cache_write: 6.25, + context_over_200k: { input: 10, output: 37.5, cache_read: 1, cache_write: 12.5 }, + }, + limit: { context: 1000000, output: 128000 }, + }, + "anthropic/claude-3.5-haiku": { + id: "anthropic/claude-3.5-haiku", + name: "Claude Haiku 3.5 (latest)", + family: "claude-haiku", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-07-31", + release_date: "2024-10-22", + last_updated: "2024-10-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.8, output: 4, cache_read: 0.08, cache_write: 1 }, + limit: { context: 200000, output: 8192 }, + }, + "anthropic/claude-sonnet-4-5": { + id: "anthropic/claude-sonnet-4-5", + name: "Claude Sonnet 4.5 (latest)", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07-31", + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + }, + "anthropic/claude-3-sonnet": { + id: "anthropic/claude-3-sonnet", + name: "Claude Sonnet 3", + family: "claude-sonnet", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-08-31", + release_date: "2024-03-04", + last_updated: "2024-03-04", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 0.3 }, + limit: { context: 200000, output: 4096 }, + }, + "anthropic/claude-3-opus": { + id: "anthropic/claude-3-opus", + name: "Claude Opus 3", + family: "claude-opus", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-08-31", + release_date: "2024-02-29", + last_updated: "2024-02-29", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 4096 }, + }, + "openai/gpt-5.5": { + id: "openai/gpt-5.5", + name: "GPT-5.5", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-12-01", + release_date: "2026-04-23", + last_updated: "2026-04-23", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 30, cache_read: 0.5, context_over_200k: { input: 10, output: 45, cache_read: 1 } }, + limit: { context: 1050000, input: 922000, output: 128000 }, + }, + }, + }, + "github-copilot": { + id: "github-copilot", + env: ["GITHUB_TOKEN"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.githubcopilot.com", + name: "GitHub Copilot", + doc: "https://docs.github.com/en/copilot", + models: { + "gpt-5.1-codex-max": { + id: "gpt-5.1-codex-max", + name: "GPT-5.1-Codex-max", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-12-04", + last_updated: "2025-12-04", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 400000, input: 128000, output: 128000 }, + status: "deprecated", + }, + "claude-opus-4.6": { + id: "claude-opus-4.6", + name: "Claude Opus 4.6", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-05-31", + release_date: "2026-02-05", + last_updated: "2026-02-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 144000, input: 128000, output: 64000 }, + }, + "gemini-3.1-pro-preview": { + id: "gemini-3.1-pro-preview", + name: "Gemini 3.1 Pro Preview", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-02-19", + last_updated: "2026-02-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, input: 128000, output: 64000 }, + }, + "gemini-3-flash-preview": { + id: "gemini-3-flash-preview", + name: "Gemini 3 Flash", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-12-17", + last_updated: "2025-12-17", + modalities: { input: ["text", "image", "audio", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, input: 128000, output: 64000 }, + }, + "gpt-5.5": { + id: "gpt-5.5", + name: "GPT-5.5", + family: "gpt", + attachment: false, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-04-22", + last_updated: "2026-04-22", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "gpt-5-mini": { + id: "gpt-5-mini", + name: "GPT-5-mini", + family: "gpt-mini", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-06", + release_date: "2025-08-13", + last_updated: "2025-08-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 264000, input: 128000, output: 64000 }, + }, + "gemini-3-pro-preview": { + id: "gemini-3-pro-preview", + name: "Gemini 3 Pro Preview", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-11-18", + last_updated: "2025-11-18", + modalities: { input: ["text", "image", "audio", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, input: 128000, output: 64000 }, + status: "deprecated", + }, + "gpt-5.3-codex": { + id: "gpt-5.3-codex", + name: "GPT-5.3-Codex", + family: "gpt-codex", + attachment: false, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-02-24", + last_updated: "2026-02-24", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "gemini-2.5-pro": { + id: "gemini-2.5-pro", + name: "Gemini 2.5 Pro", + family: "gemini-pro", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-03-20", + last_updated: "2025-06-05", + modalities: { input: ["text", "image", "audio", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, input: 128000, output: 64000 }, + }, + "gpt-5.2": { + id: "gpt-5.2", + name: "GPT-5.2", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2025-12-11", + last_updated: "2025-12-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 264000, input: 128000, output: 64000 }, + }, + "gpt-5.4-mini": { + id: "gpt-5.4-mini", + name: "GPT-5.4 Mini", + family: "gpt-mini", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-17", + last_updated: "2026-03-17", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "claude-opus-4.7": { + id: "claude-opus-4.7", + name: "Claude Opus 4.7", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2026-01-31", + release_date: "2026-04-16", + last_updated: "2026-04-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 144000, input: 128000, output: 64000 }, + }, + "gpt-5.2-codex": { + id: "gpt-5.2-codex", + name: "GPT-5.2-Codex", + family: "gpt-codex", + attachment: false, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2025-12-11", + last_updated: "2025-12-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "gpt-5.1-codex-mini": { + id: "gpt-5.1-codex-mini", + name: "GPT-5.1-Codex-mini", + family: "gpt-codex", + attachment: false, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 400000, input: 128000, output: 128000 }, + status: "deprecated", + }, + "claude-sonnet-4": { + id: "claude-sonnet-4", + name: "Claude Sonnet 4", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 216000, input: 128000, output: 16000 }, + status: "deprecated", + }, + "grok-code-fast-1": { + id: "grok-code-fast-1", + name: "Grok Code Fast 1", + family: "grok", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-08", + release_date: "2025-08-27", + last_updated: "2025-08-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, input: 128000, output: 64000 }, + }, + "gpt-5.1": { + id: "gpt-5.1", + name: "GPT-5.1", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 264000, input: 128000, output: 64000 }, + status: "deprecated", + }, + "claude-sonnet-4.5": { + id: "claude-sonnet-4.5", + name: "Claude Sonnet 4.5", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 144000, input: 128000, output: 32000 }, + }, + "claude-opus-41": { + id: "claude-opus-41", + name: "Claude Opus 4.1", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: false, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 80000, output: 16000 }, + status: "deprecated", + }, + "claude-opus-4.5": { + id: "claude-opus-4.5", + name: "Claude Opus 4.5", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-11-24", + last_updated: "2025-08-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 160000, input: 128000, output: 32000 }, + }, + "gpt-5.4": { + id: "gpt-5.4", + name: "GPT-5.4", + family: "gpt", + attachment: false, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-05", + last_updated: "2026-03-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "gpt-4o": { + id: "gpt-4o", + name: "GPT-4o", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-09", + release_date: "2024-05-13", + last_updated: "2024-05-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, input: 64000, output: 4096 }, + }, + "gpt-5": { + id: "gpt-5", + name: "GPT-5", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 128000 }, + status: "deprecated", + }, + "claude-haiku-4.5": { + id: "claude-haiku-4.5", + name: "Claude Haiku 4.5", + family: "claude-haiku", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-02-28", + release_date: "2025-10-15", + last_updated: "2025-10-15", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 144000, input: 128000, output: 32000 }, + }, + "gpt-4.1": { + id: "gpt-4.1", + name: "GPT-4.1", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-04-14", + last_updated: "2025-04-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, input: 64000, output: 16384 }, + }, + "claude-sonnet-4.6": { + id: "claude-sonnet-4.6", + name: "Claude Sonnet 4.6", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-08-31", + release_date: "2026-02-17", + last_updated: "2026-02-17", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 200000, input: 128000, output: 32000 }, + }, + "gpt-5.1-codex": { + id: "gpt-5.1-codex", + name: "GPT-5.1-Codex", + family: "gpt-codex", + attachment: false, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 400000, input: 128000, output: 128000 }, + status: "deprecated", + }, + }, + }, + mixlayer: { + id: "mixlayer", + env: ["MIXLAYER_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://models.mixlayer.ai/v1", + name: "Mixlayer", + doc: "https://docs.mixlayer.com", + models: { + "qwen/qwen3.5-122b-a10b": { + id: "qwen/qwen3.5-122b-a10b", + name: "Qwen3.5 122B A10B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.4, output: 3.2 }, + limit: { context: 262144, output: 262144 }, + }, + "qwen/qwen3.5-27b": { + id: "qwen/qwen3.5-27b", + name: "Qwen3.5 27B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 2.4 }, + limit: { context: 262144, output: 262144 }, + }, + "qwen/qwen3.5-397b-a17b": { + id: "qwen/qwen3.5-397b-a17b", + name: "Qwen3.5 397B A17B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 3.6 }, + limit: { context: 262144, output: 262144 }, + }, + "qwen/qwen3.5-9b": { + id: "qwen/qwen3.5-9b", + name: "Qwen3.5 9B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.4 }, + limit: { context: 262144, output: 262144 }, + }, + "qwen/qwen3.5-35b-a3b": { + id: "qwen/qwen3.5-35b-a3b", + name: "Qwen3.5 35B A3B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.25, output: 1.3 }, + limit: { context: 262144, output: 262144 }, + }, + }, + }, + "xiaomi-token-plan-sgp": { + id: "xiaomi-token-plan-sgp", + env: ["XIAOMI_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://token-plan-sgp.xiaomimimo.com/v1", + name: "Xiaomi Token Plan (Singapore)", + doc: "https://platform.xiaomimimo.com/#/docs", + models: { + "mimo-v2-tts": { + id: "mimo-v2-tts", + name: "MiMo-V2-TTS", + family: "mimo", + attachment: false, + reasoning: false, + tool_call: false, + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["audio"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 8192, output: 16384 }, + }, + "mimo-v2-flash": { + id: "mimo-v2-flash", + name: "MiMo-V2-Flash", + family: "mimo", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12-01", + release_date: "2025-12-16", + last_updated: "2026-02-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0 }, + limit: { context: 262144, output: 65536 }, + }, + "mimo-v2-pro": { + id: "mimo-v2-pro", + name: "MiMo-V2-Pro", + family: "mimo", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12", + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0, cache_read: 0, context_over_200k: { input: 2, output: 6, cache_read: 0.4 } }, + limit: { context: 1048576, output: 131072 }, + }, + "mimo-v2.5": { + id: "mimo-v2.5", + name: "MiMo-V2.5", + family: "mimo", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12", + release_date: "2026-04-22", + last_updated: "2026-04-22", + modalities: { input: ["text", "image", "audio", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, context_over_200k: { input: 0, output: 0, cache_read: 0 } }, + limit: { context: 1048576, output: 131072 }, + }, + "mimo-v2-omni": { + id: "mimo-v2-omni", + name: "MiMo-V2-Omni", + family: "mimo", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12", + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0, cache_read: 0 }, + limit: { context: 262144, output: 131072 }, + }, + "mimo-v2.5-pro": { + id: "mimo-v2.5-pro", + name: "MiMo-V2.5-Pro", + family: "mimo", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12", + release_date: "2026-04-22", + last_updated: "2026-04-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, context_over_200k: { input: 0, output: 0, cache_read: 0 } }, + limit: { context: 1048576, output: 131072 }, + }, + }, + }, + zai: { + id: "zai", + env: ["ZHIPU_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.z.ai/api/paas/v4", + name: "Z.AI", + doc: "https://docs.z.ai/guides/overview/pricing", + models: { + "glm-5v-turbo": { + id: "glm-5v-turbo", + name: "GLM-5V-Turbo", + family: "glm", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-04-01", + last_updated: "2026-04-01", + modalities: { input: ["text", "image", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.2, output: 4, cache_read: 0.24, cache_write: 0 }, + limit: { context: 200000, output: 131072 }, + }, + "glm-4.7": { + id: "glm-4.7", + name: "GLM-4.7", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-04", + release_date: "2025-12-22", + last_updated: "2025-12-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.2, cache_read: 0.11, cache_write: 0 }, + limit: { context: 204800, output: 131072 }, + }, + "glm-5": { + id: "glm-5", + name: "GLM-5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-02-11", + last_updated: "2026-02-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 3.2, cache_read: 0.2, cache_write: 0 }, + limit: { context: 204800, output: 131072 }, + }, + "glm-4.7-flashx": { + id: "glm-4.7-flashx", + name: "GLM-4.7-FlashX", + family: "glm-flash", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-01-19", + last_updated: "2026-01-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.07, output: 0.4, cache_read: 0.01, cache_write: 0 }, + limit: { context: 200000, output: 131072 }, + }, + "glm-5.1": { + id: "glm-5.1", + name: "GLM-5.1", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-03-27", + last_updated: "2026-03-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.4, output: 4.4, cache_read: 0.26, cache_write: 0 }, + limit: { context: 200000, output: 131072 }, + }, + "glm-4.5": { + id: "glm-4.5", + name: "GLM-4.5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-28", + last_updated: "2025-07-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.2, cache_read: 0.11, cache_write: 0 }, + limit: { context: 131072, output: 98304 }, + }, + "glm-4.5-air": { + id: "glm-4.5-air", + name: "GLM-4.5-Air", + family: "glm-air", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-28", + last_updated: "2025-07-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 1.1, cache_read: 0.03, cache_write: 0 }, + limit: { context: 131072, output: 98304 }, + }, + "glm-5-turbo": { + id: "glm-5-turbo", + name: "GLM-5-Turbo", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-03-16", + last_updated: "2026-03-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.2, output: 4, cache_read: 0.24, cache_write: 0 }, + limit: { context: 200000, output: 131072 }, + }, + "glm-4.5v": { + id: "glm-4.5v", + name: "GLM-4.5V", + family: "glm", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-08-11", + last_updated: "2025-08-11", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 1.8 }, + limit: { context: 64000, output: 16384 }, + }, + "glm-4.6": { + id: "glm-4.6", + name: "GLM-4.6", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-09-30", + last_updated: "2025-09-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.2, cache_read: 0.11, cache_write: 0 }, + limit: { context: 204800, output: 131072 }, + }, + "glm-4.6v": { + id: "glm-4.6v", + name: "GLM-4.6V", + family: "glm", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-12-08", + last_updated: "2025-12-08", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 0.9 }, + limit: { context: 128000, output: 32768 }, + }, + "glm-4.5-flash": { + id: "glm-4.5-flash", + name: "GLM-4.5-Flash", + family: "glm-flash", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-28", + last_updated: "2025-07-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 131072, output: 98304 }, + }, + "glm-4.7-flash": { + id: "glm-4.7-flash", + name: "GLM-4.7-Flash", + family: "glm-flash", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-01-19", + last_updated: "2026-01-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 200000, output: 131072 }, + }, + }, + }, + opencode: { + id: "opencode", + env: ["OPENCODE_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://opencode.ai/zen/v1", + name: "OpenCode Zen", + doc: "https://opencode.ai/docs/zen", + models: { + "minimax-m2.7": { + id: "minimax-m2.7", + name: "MiniMax M2.7", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-01", + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2, cache_read: 0.06 }, + limit: { context: 204800, output: 131072 }, + }, + "gpt-5.1-codex-max": { + id: "gpt-5.1-codex-max", + name: "GPT-5.1 Codex Max", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 400000, input: 272000, output: 128000 }, + provider: { npm: "@ai-sdk/openai" }, + }, + "claude-haiku-4-5": { + id: "claude-haiku-4-5", + name: "Claude Haiku 4.5", + family: "claude-haiku", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-02-28", + release_date: "2025-10-15", + last_updated: "2025-10-15", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 5, cache_read: 0.1, cache_write: 1.25 }, + limit: { context: 200000, output: 64000 }, + provider: { npm: "@ai-sdk/anthropic" }, + }, + "kimi-k2.5": { + id: "kimi-k2.5", + name: "Kimi K2.5", + family: "kimi", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-10", + release_date: "2026-01-27", + last_updated: "2026-01-27", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 3, cache_read: 0.08 }, + limit: { context: 262144, output: 65536 }, + }, + "glm-4.7": { + id: "glm-4.7", + name: "GLM-4.7", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-04", + release_date: "2025-12-22", + last_updated: "2025-12-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.2, cache_read: 0.1 }, + limit: { context: 204800, output: 131072 }, + status: "deprecated", + }, + "glm-5": { + id: "glm-5", + name: "GLM-5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-04", + release_date: "2026-02-11", + last_updated: "2026-02-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 3.2, cache_read: 0.2 }, + limit: { context: 204800, output: 131072 }, + }, + "glm-4.7-free": { + id: "glm-4.7-free", + name: "GLM-4.7 Free", + family: "glm-free", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-04", + release_date: "2025-12-22", + last_updated: "2025-12-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0 }, + limit: { context: 204800, output: 131072 }, + status: "deprecated", + }, + "gemini-3.1-pro": { + id: "gemini-3.1-pro", + name: "Gemini 3.1 Pro Preview", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-02-19", + last_updated: "2026-02-19", + modalities: { input: ["text", "image", "video", "audio", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 12, cache_read: 0.2, context_over_200k: { input: 4, output: 18, cache_read: 0.4 } }, + limit: { context: 1048576, output: 65536 }, + provider: { npm: "@ai-sdk/google" }, + }, + "claude-sonnet-4-6": { + id: "claude-sonnet-4-6", + name: "Claude Sonnet 4.6", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: true, + temperature: true, + knowledge: "2025-08-31", + release_date: "2026-02-17", + last_updated: "2026-02-17", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 1000000, output: 64000 }, + provider: { npm: "@ai-sdk/anthropic" }, + }, + "kimi-k2.5-free": { + id: "kimi-k2.5-free", + name: "Kimi K2.5 Free", + family: "kimi-free", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-10", + release_date: "2026-01-27", + last_updated: "2026-01-27", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0 }, + limit: { context: 262144, output: 262144 }, + status: "deprecated", + }, + "claude-opus-4-7": { + id: "claude-opus-4-7", + name: "Claude Opus 4.7", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2026-01-31", + release_date: "2026-04-16", + last_updated: "2026-04-16", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 1000000, output: 128000 }, + provider: { npm: "@ai-sdk/anthropic" }, + }, + "gpt-5-nano": { + id: "gpt-5-nano", + name: "GPT-5 Nano", + family: "gpt-nano", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-05-30", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.05, output: 0.4, cache_read: 0.005 }, + limit: { context: 400000, input: 272000, output: 128000 }, + provider: { npm: "@ai-sdk/openai" }, + }, + "gpt-5.3-codex": { + id: "gpt-5.3-codex", + name: "GPT-5.3 Codex", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-02-24", + last_updated: "2026-02-24", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 400000, input: 272000, output: 128000 }, + provider: { npm: "@ai-sdk/openai" }, + }, + "minimax-m2.5-free": { + id: "minimax-m2.5-free", + name: "MiniMax M2.5 Free", + family: "minimax-free", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0 }, + limit: { context: 204800, output: 131072 }, + provider: { npm: "@ai-sdk/anthropic" }, + }, + "ring-2.6-1t-free": { + id: "ring-2.6-1t-free", + name: "Ring 2.6 1T Free", + family: "ring-1t-free", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-06", + release_date: "2026-05-08", + last_updated: "2026-05-08", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 262000, output: 66000 }, + }, + "gpt-5.2": { + id: "gpt-5.2", + name: "GPT-5.2", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2025-12-11", + last_updated: "2025-12-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 400000, input: 272000, output: 128000 }, + provider: { npm: "@ai-sdk/openai" }, + }, + "big-pickle": { + id: "big-pickle", + name: "Big Pickle", + family: "big-pickle", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-10-17", + last_updated: "2025-10-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 200000, output: 128000 }, + }, + "claude-opus-4-1": { + id: "claude-opus-4-1", + name: "Claude Opus 4.1", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 32000 }, + provider: { npm: "@ai-sdk/anthropic" }, + }, + "qwen3.6-plus": { + id: "qwen3.6-plus", + name: "Qwen3.6 Plus", + family: "qwen3.6", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-04-02", + last_updated: "2026-04-02", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 3, cache_read: 0.05, cache_write: 0.625 }, + limit: { context: 262144, output: 65536 }, + provider: { npm: "@ai-sdk/anthropic" }, + }, + "gpt-5.4-mini": { + id: "gpt-5.4-mini", + name: "GPT-5.4 Mini", + family: "gpt-mini", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-17", + last_updated: "2026-03-17", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.75, output: 4.5, cache_read: 0.075 }, + limit: { context: 400000, input: 272000, output: 128000 }, + provider: { npm: "@ai-sdk/openai" }, + }, + "claude-3-5-haiku": { + id: "claude-3-5-haiku", + name: "Claude Haiku 3.5", + family: "claude-haiku", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-07-31", + release_date: "2024-10-22", + last_updated: "2024-10-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.8, output: 4, cache_read: 0.08, cache_write: 1 }, + limit: { context: 200000, output: 8192 }, + status: "deprecated", + provider: { npm: "@ai-sdk/anthropic" }, + }, + "minimax-m2.1": { + id: "minimax-m2.1", + name: "MiniMax M2.1", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-01", + release_date: "2025-12-23", + last_updated: "2025-12-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2, cache_read: 0.1 }, + limit: { context: 204800, output: 131072 }, + status: "deprecated", + }, + "glm-5.1": { + id: "glm-5.1", + name: "GLM-5.1", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-04", + release_date: "2026-04-07", + last_updated: "2026-04-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.4, output: 4.4, cache_read: 0.26 }, + limit: { context: 204800, output: 131072 }, + }, + "gpt-5.4-nano": { + id: "gpt-5.4-nano", + name: "GPT-5.4 Nano", + family: "gpt-nano", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-17", + last_updated: "2026-03-17", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 1.25, cache_read: 0.02 }, + limit: { context: 400000, input: 272000, output: 128000 }, + provider: { npm: "@ai-sdk/openai" }, + }, + "gpt-5.2-codex": { + id: "gpt-5.2-codex", + name: "GPT-5.2 Codex", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-01-14", + last_updated: "2026-01-14", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 400000, input: 272000, output: 128000 }, + provider: { npm: "@ai-sdk/openai" }, + }, + "gpt-5.1-codex-mini": { + id: "gpt-5.1-codex-mini", + name: "GPT-5.1 Codex Mini", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 2, cache_read: 0.025 }, + limit: { context: 400000, input: 272000, output: 128000 }, + provider: { npm: "@ai-sdk/openai" }, + }, + "claude-sonnet-4": { + id: "claude-sonnet-4", + name: "Claude Sonnet 4", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 3, + output: 15, + cache_read: 0.3, + cache_write: 3.75, + context_over_200k: { input: 6, output: 22.5, cache_read: 0.6, cache_write: 7.5 }, + }, + limit: { context: 1000000, output: 64000 }, + provider: { npm: "@ai-sdk/anthropic" }, + }, + "gemini-3-flash": { + id: "gemini-3-flash", + name: "Gemini 3 Flash", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-12-17", + last_updated: "2025-12-17", + modalities: { input: ["text", "image", "video", "audio", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 3, cache_read: 0.05 }, + limit: { context: 1048576, output: 65536 }, + provider: { npm: "@ai-sdk/google" }, + }, + "trinity-large-preview-free": { + id: "trinity-large-preview-free", + name: "Trinity Large Preview", + family: "trinity", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-06", + release_date: "2026-01-28", + last_updated: "2026-01-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 131072, output: 131072 }, + status: "deprecated", + }, + "gpt-5.1": { + id: "gpt-5.1", + name: "GPT-5.1", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.07, output: 8.5, cache_read: 0.107 }, + limit: { context: 400000, input: 272000, output: 128000 }, + provider: { npm: "@ai-sdk/openai" }, + }, + "gpt-5.4-pro": { + id: "gpt-5.4-pro", + name: "GPT-5.4 Pro", + family: "gpt-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-05", + last_updated: "2026-03-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 30, output: 180, cache_read: 30 }, + limit: { context: 1050000, input: 922000, output: 128000 }, + provider: { npm: "@ai-sdk/openai" }, + }, + "glm-5-free": { + id: "glm-5-free", + name: "GLM-5 Free", + family: "glm-free", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-04", + release_date: "2026-02-11", + last_updated: "2026-02-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0 }, + limit: { context: 204800, output: 131072 }, + status: "deprecated", + }, + "claude-opus-4-5": { + id: "claude-opus-4-5", + name: "Claude Opus 4.5", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-11-24", + last_updated: "2025-11-24", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 200000, output: 64000 }, + provider: { npm: "@ai-sdk/anthropic" }, + }, + "minimax-m2.1-free": { + id: "minimax-m2.1-free", + name: "MiniMax M2.1 Free", + family: "minimax-free", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-12-23", + last_updated: "2025-12-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0 }, + limit: { context: 204800, output: 131072 }, + status: "deprecated", + provider: { npm: "@ai-sdk/anthropic" }, + }, + "qwen3.6-plus-free": { + id: "qwen3.6-plus-free", + name: "Qwen3.6 Plus Free", + family: "qwen-free", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12", + release_date: "2026-03-30", + last_updated: "2026-03-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0, cache_read: 0 }, + limit: { context: 1048576, output: 64000 }, + status: "deprecated", + }, + "glm-4.6": { + id: "glm-4.6", + name: "GLM-4.6", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-09-30", + last_updated: "2025-09-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.2, cache_read: 0.1 }, + limit: { context: 204800, output: 131072 }, + status: "deprecated", + }, + "ling-2.6-flash-free": { + id: "ling-2.6-flash-free", + name: "Ling 2.6 Flash Free", + family: "ling-flash-free", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-06", + release_date: "2026-04-21", + last_updated: "2026-04-21", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 262100, output: 32800 }, + status: "deprecated", + }, + "gemini-3-pro": { + id: "gemini-3-pro", + name: "Gemini 3 Pro", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-11-18", + last_updated: "2025-11-18", + modalities: { input: ["text", "image", "video", "audio", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 12, cache_read: 0.2, context_over_200k: { input: 4, output: 18, cache_read: 0.4 } }, + limit: { context: 1048576, output: 65536 }, + status: "deprecated", + provider: { npm: "@ai-sdk/google" }, + }, + "kimi-k2.6": { + id: "kimi-k2.6", + name: "Kimi K2.6", + family: "kimi", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-10", + release_date: "2026-04-21", + last_updated: "2026-04-21", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.95, output: 4, cache_read: 0.16 }, + limit: { context: 262144, output: 65536 }, + }, + "gpt-5-codex": { + id: "gpt-5-codex", + name: "GPT-5 Codex", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-09-15", + last_updated: "2025-09-15", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.07, output: 8.5, cache_read: 0.107 }, + limit: { context: 400000, input: 272000, output: 128000 }, + provider: { npm: "@ai-sdk/openai" }, + }, + "grok-code": { + id: "grok-code", + name: "Grok Code Fast 1", + family: "grok", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-20", + last_updated: "2025-08-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 256000, output: 256000 }, + status: "deprecated", + }, + "mimo-v2-flash-free": { + id: "mimo-v2-flash-free", + name: "MiMo V2 Flash Free", + family: "mimo-flash-free", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12", + release_date: "2025-12-16", + last_updated: "2025-12-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0 }, + limit: { context: 262144, output: 65536 }, + status: "deprecated", + }, + "gpt-5.3-codex-spark": { + id: "gpt-5.3-codex-spark", + name: "GPT-5.3 Codex Spark", + family: "gpt-codex-spark", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 128000, input: 128000, output: 128000 }, + provider: { npm: "@ai-sdk/openai" }, + }, + "hy3-preview-free": { + id: "hy3-preview-free", + name: "Hy3 preview Free", + family: "hy3-free", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-06", + release_date: "2026-04-20", + last_updated: "2026-04-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0 }, + limit: { context: 256000, output: 64000 }, + status: "deprecated", + }, + "minimax-m2.5": { + id: "minimax-m2.5", + name: "MiniMax M2.5", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-01", + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2, cache_read: 0.06 }, + limit: { context: 204800, output: 131072 }, + }, + "kimi-k2": { + id: "kimi-k2", + name: "Kimi K2", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-09-05", + last_updated: "2025-09-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.4, output: 2.5, cache_read: 0.4 }, + limit: { context: 262144, output: 262144 }, + status: "deprecated", + }, + "claude-sonnet-4-5": { + id: "claude-sonnet-4-5", + name: "Claude Sonnet 4.5", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: true, + temperature: true, + knowledge: "2025-07-31", + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 3, + output: 15, + cache_read: 0.3, + cache_write: 3.75, + context_over_200k: { input: 6, output: 22.5, cache_read: 0.6, cache_write: 7.5 }, + }, + limit: { context: 1000000, output: 64000 }, + provider: { npm: "@ai-sdk/anthropic" }, + }, + "qwen3-coder": { + id: "qwen3-coder", + name: "Qwen3 Coder", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-23", + last_updated: "2025-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.45, output: 1.8 }, + limit: { context: 262144, output: 65536 }, + status: "deprecated", + }, + "gpt-5": { + id: "gpt-5", + name: "GPT-5", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.07, output: 8.5, cache_read: 0.107 }, + limit: { context: 400000, input: 272000, output: 128000 }, + provider: { npm: "@ai-sdk/openai" }, + }, + "qwen3.5-plus": { + id: "qwen3.5-plus", + name: "Qwen3.5 Plus", + family: "qwen3.5", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-02-16", + last_updated: "2026-02-16", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 1.2, cache_read: 0.02, cache_write: 0.25 }, + limit: { context: 262144, output: 65536 }, + provider: { npm: "@ai-sdk/anthropic" }, + }, + "mimo-v2-pro-free": { + id: "mimo-v2-pro-free", + name: "MiMo V2 Pro Free", + family: "mimo-pro-free", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12", + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0 }, + limit: { context: 1048576, output: 64000 }, + status: "deprecated", + }, + "nemotron-3-super-free": { + id: "nemotron-3-super-free", + name: "Nemotron 3 Super Free", + family: "nemotron-free", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2026-02", + release_date: "2026-03-11", + last_updated: "2026-03-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0 }, + limit: { context: 204800, output: 128000 }, + }, + "gpt-5.5-pro": { + id: "gpt-5.5-pro", + name: "GPT-5.5 Pro", + family: "gpt-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: false, + knowledge: "2025-12-01", + release_date: "2026-04-24", + last_updated: "2026-04-24", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 30, output: 180, cache_read: 30 }, + limit: { context: 1050000, input: 922000, output: 128000 }, + provider: { npm: "@ai-sdk/openai" }, + }, + "kimi-k2-thinking": { + id: "kimi-k2-thinking", + name: "Kimi K2 Thinking", + family: "kimi-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-10", + release_date: "2025-09-05", + last_updated: "2025-09-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.4, output: 2.5, cache_read: 0.4 }, + limit: { context: 262144, output: 262144 }, + status: "deprecated", + }, + "gpt-5.1-codex": { + id: "gpt-5.1-codex", + name: "GPT-5.1 Codex", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.07, output: 8.5, cache_read: 0.107 }, + limit: { context: 400000, input: 272000, output: 128000 }, + provider: { npm: "@ai-sdk/openai" }, + }, + "mimo-v2-omni-free": { + id: "mimo-v2-omni-free", + name: "MiMo V2 Omni Free", + family: "mimo-omni-free", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12", + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text", "image", "audio", "pdf"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0 }, + limit: { context: 262144, output: 64000 }, + status: "deprecated", + }, + "gpt-5.5": { + id: "gpt-5.5", + name: "GPT-5.5", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-12-01", + release_date: "2026-04-23", + last_updated: "2026-04-23", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 30, cache_read: 0.5, context_over_200k: { input: 10, output: 45, cache_read: 1 } }, + limit: { context: 1050000, input: 922000, output: 128000 }, + provider: { npm: "@ai-sdk/openai" }, + }, + "gpt-5.4": { + id: "gpt-5.4", + name: "GPT-5.4", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-05", + last_updated: "2026-03-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 2.5, + output: 15, + cache_read: 0.25, + context_over_200k: { input: 5, output: 22.5, cache_read: 0.5 }, + }, + limit: { context: 1050000, input: 922000, output: 128000 }, + provider: { npm: "@ai-sdk/openai" }, + }, + "claude-opus-4-6": { + id: "claude-opus-4-6", + name: "Claude Opus 4.6", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-05-31", + release_date: "2026-02-05", + last_updated: "2026-03-13", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 1000000, output: 128000 }, + provider: { npm: "@ai-sdk/anthropic" }, + }, + }, + }, + stepfun: { + id: "stepfun", + env: ["STEPFUN_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.stepfun.com/v1", + name: "StepFun", + doc: "https://platform.stepfun.com/docs/zh/overview/concept", + models: { + "step-3.5-flash-2603": { + id: "step-3.5-flash-2603", + name: "Step 3.5 Flash 2603", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-04-02", + last_updated: "2026-04-02", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.3, cache_read: 0.02 }, + limit: { context: 256000, input: 256000, output: 256000 }, + }, + "step-1-32k": { + id: "step-1-32k", + name: "Step 1 (32K)", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-06", + release_date: "2025-01-01", + last_updated: "2026-02-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2.05, output: 9.59, cache_read: 0.41 }, + limit: { context: 32768, input: 32768, output: 32768 }, + }, + "step-3.5-flash": { + id: "step-3.5-flash", + name: "Step 3.5 Flash", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-01-29", + last_updated: "2026-02-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.096, output: 0.288, cache_read: 0.019 }, + limit: { context: 256000, input: 256000, output: 256000 }, + }, + "step-2-16k": { + id: "step-2-16k", + name: "Step 2 (16K)", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-06", + release_date: "2025-01-01", + last_updated: "2026-02-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 5.21, output: 16.44, cache_read: 1.04 }, + limit: { context: 16384, input: 16384, output: 8192 }, + }, + }, + }, + nebius: { + id: "nebius", + env: ["NEBIUS_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.tokenfactory.nebius.com/v1", + name: "Nebius Token Factory", + doc: "https://docs.tokenfactory.nebius.com/", + models: { + "NousResearch/Hermes-4-70B": { + id: "NousResearch/Hermes-4-70B", + name: "Hermes-4-70B", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-11", + release_date: "2026-01-30", + last_updated: "2026-02-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.13, output: 0.4, reasoning: 0.4, cache_read: 0.013, cache_write: 0.16 }, + limit: { context: 128000, input: 120000, output: 8192 }, + }, + "NousResearch/Hermes-4-405B": { + id: "NousResearch/Hermes-4-405B", + name: "Hermes-4-405B", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-11", + release_date: "2026-01-30", + last_updated: "2026-02-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 3, reasoning: 3, cache_read: 0.1, cache_write: 1.25 }, + limit: { context: 128000, input: 120000, output: 8192 }, + }, + "Qwen/Qwen2.5-VL-72B-Instruct": { + id: "Qwen/Qwen2.5-VL-72B-Instruct", + name: "Qwen2.5-VL-72B-Instruct", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-12", + release_date: "2025-01-20", + last_updated: "2026-02-04", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.25, output: 0.75, cache_read: 0.025, cache_write: 0.31 }, + limit: { context: 128000, input: 120000, output: 8192 }, + }, + "Qwen/Qwen3.5-397B-A17B": { + id: "Qwen/Qwen3.5-397B-A17B", + name: "Qwen3.5-397B-A17B", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-07-15", + last_updated: "2026-05-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 3.6, cache_read: 0.06, cache_write: 0.75 }, + limit: { context: 262144, input: 250000, output: 8192 }, + }, + "Qwen/Qwen3-Embedding-8B": { + id: "Qwen/Qwen3-Embedding-8B", + name: "Qwen3-Embedding-8B", + family: "text-embedding", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: false, + knowledge: "2025-10", + release_date: "2026-01-10", + last_updated: "2026-02-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.01, output: 0 }, + limit: { context: 32768, input: 32768, output: 0 }, + }, + "Qwen/Qwen3-30B-A3B-Instruct-2507": { + id: "Qwen/Qwen3-30B-A3B-Instruct-2507", + name: "Qwen3-30B-A3B-Instruct-2507", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-12", + release_date: "2026-01-28", + last_updated: "2026-02-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.3, cache_read: 0.01, cache_write: 0.125 }, + limit: { context: 128000, input: 120000, output: 8192 }, + }, + "Qwen/Qwen3-235B-A22B-Instruct-2507": { + id: "Qwen/Qwen3-235B-A22B-Instruct-2507", + name: "Qwen3 235B A22B Instruct 2507", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-07-25", + last_updated: "2025-10-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.6 }, + limit: { context: 262144, output: 8192 }, + }, + "Qwen/Qwen3-32B": { + id: "Qwen/Qwen3-32B", + name: "Qwen3-32B", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-12", + release_date: "2026-01-28", + last_updated: "2026-02-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.3, cache_read: 0.01, cache_write: 0.125 }, + limit: { context: 128000, input: 120000, output: 8192 }, + }, + "Qwen/Qwen3-235B-A22B-Thinking-2507-fast": { + id: "Qwen/Qwen3-235B-A22B-Thinking-2507-fast", + name: "Qwen3-235B-A22B-Thinking-2507-fast", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-07-25", + last_updated: "2026-05-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.5, output: 2, cache_read: 0.05, cache_write: 0.625 }, + limit: { context: 8000, input: 7000, output: 8192 }, + }, + "Qwen/Qwen3.5-397B-A17B-fast": { + id: "Qwen/Qwen3.5-397B-A17B-fast", + name: "Qwen3.5-397B-A17B-fast", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-07-15", + last_updated: "2026-05-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 3.6, cache_read: 0.06, cache_write: 0.75 }, + limit: { context: 8000, input: 7000, output: 8192 }, + }, + "Qwen/Qwen3-Next-80B-A3B-Thinking-fast": { + id: "Qwen/Qwen3-Next-80B-A3B-Thinking-fast", + name: "Qwen3-Next-80B-A3B-Thinking-fast", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-07-25", + last_updated: "2026-05-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 1.2, cache_read: 0.015, cache_write: 0.1875 }, + limit: { context: 8000, input: 7000, output: 8192 }, + }, + "Qwen/Qwen3-Next-80B-A3B-Thinking": { + id: "Qwen/Qwen3-Next-80B-A3B-Thinking", + name: "Qwen3-Next-80B-A3B-Thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-12", + release_date: "2026-01-28", + last_updated: "2026-02-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 1.2, reasoning: 1.2, cache_read: 0.015, cache_write: 0.18 }, + limit: { context: 128000, input: 120000, output: 16384 }, + }, + "PrimeIntellect/INTELLECT-3": { + id: "PrimeIntellect/INTELLECT-3", + name: "INTELLECT-3", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-10", + release_date: "2026-01-25", + last_updated: "2026-02-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 1.1, cache_read: 0.02, cache_write: 0.25 }, + limit: { context: 128000, input: 120000, output: 8192 }, + }, + "zai-org/GLM-5": { + id: "zai-org/GLM-5", + name: "GLM-5", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2026-01", + release_date: "2026-03-01", + last_updated: "2026-03-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 3.2, cache_read: 0.1, cache_write: 1 }, + limit: { context: 200000, input: 200000, output: 16384 }, + }, + "meta-llama/Llama-3.3-70B-Instruct": { + id: "meta-llama/Llama-3.3-70B-Instruct", + name: "Llama-3.3-70B-Instruct", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-08", + release_date: "2025-12-05", + last_updated: "2026-02-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.13, output: 0.4, cache_read: 0.013, cache_write: 0.16 }, + limit: { context: 128000, input: 120000, output: 8192 }, + }, + "meta-llama/Meta-Llama-3.1-8B-Instruct": { + id: "meta-llama/Meta-Llama-3.1-8B-Instruct", + name: "Meta-Llama-3.1-8B-Instruct", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-12", + release_date: "2024-07-23", + last_updated: "2026-02-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.02, output: 0.06, cache_read: 0.002, cache_write: 0.025 }, + limit: { context: 128000, input: 120000, output: 4096 }, + }, + "nvidia/nemotron-3-super-120b-a12b": { + id: "nvidia/nemotron-3-super-120b-a12b", + name: "Nemotron-3-Super-120B-A12B", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2026-02", + release_date: "2026-03-11", + last_updated: "2026-03-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 0.9 }, + limit: { context: 256000, input: 256000, output: 32768 }, + }, + "nvidia/Llama-3_1-Nemotron-Ultra-253B-v1": { + id: "nvidia/Llama-3_1-Nemotron-Ultra-253B-v1", + name: "Llama-3.1-Nemotron-Ultra-253B-v1", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-12", + release_date: "2025-01-15", + last_updated: "2026-02-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 1.8, cache_read: 0.06, cache_write: 0.75 }, + limit: { context: 128000, input: 120000, output: 4096 }, + }, + "nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B": { + id: "nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B", + name: "Nemotron-3-Nano-30B-A3B", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-05", + release_date: "2025-08-10", + last_updated: "2026-02-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.06, output: 0.24, cache_read: 0.006, cache_write: 0.075 }, + limit: { context: 32000, input: 30000, output: 4096 }, + }, + "nvidia/Nemotron-3-Nano-Omni": { + id: "nvidia/Nemotron-3-Nano-Omni", + name: "Nemotron-3-Nano-Omni", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-01-20", + last_updated: "2026-05-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.06, output: 0.24, cache_read: 0.006, cache_write: 0.075 }, + limit: { context: 65536, input: 60000, output: 8192 }, + }, + "deepseek-ai/DeepSeek-V3.2-fast": { + id: "deepseek-ai/DeepSeek-V3.2-fast", + name: "DeepSeek-V3.2-fast", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-01-27", + last_updated: "2026-05-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.4, output: 2, cache_read: 0.04, cache_write: 0.5 }, + limit: { context: 8000, input: 7000, output: 8192 }, + }, + "deepseek-ai/DeepSeek-V3.2": { + id: "deepseek-ai/DeepSeek-V3.2", + name: "DeepSeek-V3.2", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-11", + release_date: "2026-01-20", + last_updated: "2026-02-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 0.45, reasoning: 0.45, cache_read: 0.03, cache_write: 0.375 }, + limit: { context: 163000, input: 160000, output: 16384 }, + }, + "openai/gpt-oss-120b-fast": { + id: "openai/gpt-oss-120b-fast", + name: "gpt-oss-120b-fast", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-06", + release_date: "2025-06-10", + last_updated: "2026-05-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.5, cache_read: 0.01, cache_write: 0.125 }, + limit: { context: 8000, input: 7000, output: 8192 }, + }, + "openai/gpt-oss-120b": { + id: "openai/gpt-oss-120b", + name: "gpt-oss-120b", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-09", + release_date: "2026-01-10", + last_updated: "2026-02-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.6, reasoning: 0.6, cache_read: 0.015, cache_write: 0.18 }, + limit: { context: 128000, input: 124000, output: 8192 }, + }, + "google/gemma-2-2b-it": { + id: "google/gemma-2-2b-it", + name: "Gemma-2-2b-it", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + knowledge: "2024-06", + release_date: "2024-07-31", + last_updated: "2026-02-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.02, output: 0.06, cache_read: 0.002, cache_write: 0.025 }, + limit: { context: 8192, input: 8000, output: 4096 }, + }, + "google/gemma-3-27b-it": { + id: "google/gemma-3-27b-it", + name: "Gemma-3-27b-it", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-10", + release_date: "2026-01-20", + last_updated: "2026-02-04", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.3, cache_read: 0.01, cache_write: 0.125 }, + limit: { context: 110000, input: 100000, output: 8192 }, + }, + "moonshotai/Kimi-K2.5-fast": { + id: "moonshotai/Kimi-K2.5-fast", + name: "Kimi-K2.5-fast", + family: "kimi", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-06", + release_date: "2025-12-15", + last_updated: "2026-02-04", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.5, output: 2.5, cache_read: 0.05, cache_write: 0.625 }, + limit: { context: 256000, input: 256000, output: 8192 }, + }, + "moonshotai/Kimi-K2.5": { + id: "moonshotai/Kimi-K2.5", + name: "Kimi-K2.5", + family: "kimi", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-06", + release_date: "2025-12-15", + last_updated: "2026-02-04", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.5, output: 2.5, reasoning: 2.5, cache_read: 0.05, cache_write: 0.625 }, + limit: { context: 256000, input: 256000, output: 8192 }, + }, + "MiniMaxAI/MiniMax-M2.5": { + id: "MiniMaxAI/MiniMax-M2.5", + name: "MiniMax-M2.5", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-01-20", + last_updated: "2026-05-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2, cache_read: 0.03, cache_write: 0.375 }, + limit: { context: 196608, input: 190000, output: 8192 }, + }, + "MiniMaxAI/MiniMax-M2.5-fast": { + id: "MiniMaxAI/MiniMax-M2.5-fast", + name: "MiniMax-M2.5-fast", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-01-20", + last_updated: "2026-05-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2, cache_read: 0.03, cache_write: 0.375 }, + limit: { context: 8000, input: 7000, output: 8192 }, + }, + "deepseek-ai/DeepSeek-V4-Pro": { + id: "deepseek-ai/DeepSeek-V4-Pro", + name: "DeepSeek V4 Pro", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-05", + release_date: "2026-04-24", + last_updated: "2026-04-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.75, output: 3.5, cache_read: 0.15 }, + limit: { context: 1000000, output: 384000 }, + }, + }, + }, + poe: { + id: "poe", + env: ["POE_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.poe.com/v1", + name: "Poe", + doc: "https://creator.poe.com/docs/external-applications/openai-compatible-api", + models: { + "topazlabs-co/topazlabs": { + id: "topazlabs-co/topazlabs", + name: "TopazLabs", + family: "topazlabs", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2024-12-03", + last_updated: "2024-12-03", + modalities: { input: ["text"], output: ["image"] }, + open_weights: false, + limit: { context: 204, output: 0 }, + }, + "novita/kimi-k2.5": { + id: "novita/kimi-k2.5", + name: "Kimi-K2.5", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-01-27", + last_updated: "2026-01-27", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.6, output: 3, cache_read: 0.1 }, + limit: { context: 128000, output: 262144 }, + }, + "novita/glm-4.7": { + id: "novita/glm-4.7", + name: "glm-4.7", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-12-22", + last_updated: "2025-12-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 205000, output: 131072 }, + status: "deprecated", + }, + "novita/glm-5": { + id: "novita/glm-5", + name: "GLM-5", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-15", + last_updated: "2026-02-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 3.2, cache_read: 0.2 }, + limit: { context: 205000, output: 131072 }, + }, + "novita/minimax-m2.1": { + id: "novita/minimax-m2.1", + name: "minimax-m2.1", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-12-26", + last_updated: "2025-12-26", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 205000, output: 131072 }, + }, + "novita/glm-4.6": { + id: "novita/glm-4.6", + name: "GLM-4.6", + family: "glm", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2025-09-30", + last_updated: "2025-09-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 0, output: 0 }, + }, + "novita/kimi-k2.6": { + id: "novita/kimi-k2.6", + name: "Kimi-K2.6", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-04-20", + last_updated: "2026-05-02", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.96, output: 4.04, cache_read: 0.16 }, + limit: { context: 262144, input: 262144, output: 262144 }, + }, + "novita/glm-4.6v": { + id: "novita/glm-4.6v", + name: "glm-4.6v", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-12-09", + last_updated: "2025-12-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + limit: { context: 131000, output: 32768 }, + }, + "novita/deepseek-v3.2": { + id: "novita/deepseek-v3.2", + name: "DeepSeek-V3.2", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-12-01", + last_updated: "2025-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.27, output: 0.4, cache_read: 0.13 }, + limit: { context: 128000, output: 0 }, + }, + "novita/glm-4.7-flash": { + id: "novita/glm-4.7-flash", + name: "glm-4.7-flash", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2026-01-19", + last_updated: "2026-01-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 200000, output: 65500 }, + }, + "novita/glm-4.7-n": { + id: "novita/glm-4.7-n", + name: "glm-4.7-n", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-12-22", + last_updated: "2025-12-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 205000, output: 131072 }, + }, + "novita/kimi-k2-thinking": { + id: "novita/kimi-k2-thinking", + name: "kimi-k2-thinking", + family: "kimi", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-11-07", + last_updated: "2025-11-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 256000, output: 0 }, + }, + "fireworks-ai/kimi-k2.5-fw": { + id: "fireworks-ai/kimi-k2.5-fw", + name: "Kimi-K2.5-FW", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2026-01-27", + last_updated: "2026-01-27", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 262144, input: 245760, output: 16384 }, + }, + "empiriolabs/deepseek-v4-pro-el": { + id: "empiriolabs/deepseek-v4-pro-el", + name: "DeepSeek-V4-Pro-EL", + attachment: true, + reasoning: true, + tool_call: true, + release_date: "2026-04-24", + last_updated: "2026-05-02", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.67, output: 3.33 }, + limit: { context: 1000000, input: 1000000, output: 384000 }, + }, + "empiriolabs/deepseek-v4-flash-el": { + id: "empiriolabs/deepseek-v4-flash-el", + name: "DeepSeek-V4-Flash-EL", + attachment: true, + reasoning: true, + tool_call: true, + release_date: "2026-04-24", + last_updated: "2026-05-02", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.14, output: 0.28 }, + limit: { context: 1000000, input: 1000000, output: 384000 }, + }, + "elevenlabs/elevenlabs-v2.5-turbo": { + id: "elevenlabs/elevenlabs-v2.5-turbo", + name: "ElevenLabs-v2.5-Turbo", + family: "elevenlabs", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2024-10-28", + last_updated: "2024-10-28", + modalities: { input: ["text"], output: ["audio"] }, + open_weights: false, + limit: { context: 128000, output: 0 }, + }, + "elevenlabs/elevenlabs-v3": { + id: "elevenlabs/elevenlabs-v3", + name: "ElevenLabs-v3", + family: "elevenlabs", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2025-06-05", + last_updated: "2025-06-05", + modalities: { input: ["text"], output: ["audio"] }, + open_weights: false, + limit: { context: 128000, output: 0 }, + }, + "elevenlabs/elevenlabs-music": { + id: "elevenlabs/elevenlabs-music", + name: "ElevenLabs-Music", + family: "elevenlabs", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2025-08-29", + last_updated: "2025-08-29", + modalities: { input: ["text"], output: ["audio"] }, + open_weights: false, + limit: { context: 2000, output: 0 }, + }, + "cerebras/gpt-oss-120b-cs": { + id: "cerebras/gpt-oss-120b-cs", + name: "GPT-OSS-120B-CS", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-08-06", + last_updated: "2025-08-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.35, output: 0.75 }, + limit: { context: 128000, output: 0 }, + }, + "cerebras/llama-3.1-8b-cs": { + id: "cerebras/llama-3.1-8b-cs", + name: "Llama-3.1-8B-CS", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2025-05-13", + last_updated: "2025-05-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.1 }, + limit: { context: 128000, output: 0 }, + }, + "cerebras/qwen3-32b-cs": { + id: "cerebras/qwen3-32b-cs", + name: "qwen3-32b-cs", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-05-15", + last_updated: "2025-05-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 0, output: 0 }, + status: "deprecated", + }, + "cerebras/qwen3-235b-2507-cs": { + id: "cerebras/qwen3-235b-2507-cs", + name: "qwen3-235b-2507-cs", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-08-06", + last_updated: "2025-08-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 0, output: 0 }, + status: "deprecated", + }, + "cerebras/llama-3.3-70b-cs": { + id: "cerebras/llama-3.3-70b-cs", + name: "llama-3.3-70b-cs", + attachment: true, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2025-05-13", + last_updated: "2025-05-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 0, output: 0 }, + status: "deprecated", + }, + "stabilityai/stablediffusionxl": { + id: "stabilityai/stablediffusionxl", + name: "StableDiffusionXL", + family: "stable-diffusion", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2023-07-09", + last_updated: "2023-07-09", + modalities: { input: ["text", "image"], output: ["image"] }, + open_weights: false, + limit: { context: 200, output: 0 }, + }, + "xai/grok-code-fast-1": { + id: "xai/grok-code-fast-1", + name: "Grok Code Fast 1", + family: "grok", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-08-22", + last_updated: "2025-08-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 1.5, cache_read: 0.02 }, + limit: { context: 256000, output: 128000 }, + }, + "xai/grok-4-fast-reasoning": { + id: "xai/grok-4-fast-reasoning", + name: "Grok-4-Fast-Reasoning", + family: "grok", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-09-16", + last_updated: "2025-09-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5, cache_read: 0.05 }, + limit: { context: 2000000, output: 128000 }, + }, + "xai/grok-4.1-fast-non-reasoning": { + id: "xai/grok-4.1-fast-non-reasoning", + name: "Grok-4.1-Fast-Non-Reasoning", + family: "grok", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2025-11-19", + last_updated: "2025-11-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + limit: { context: 2000000, output: 30000 }, + }, + "xai/grok-4": { + id: "xai/grok-4", + name: "Grok-4", + family: "grok", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-07-10", + last_updated: "2025-07-10", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.75 }, + limit: { context: 256000, output: 128000 }, + }, + "xai/grok-3-mini": { + id: "xai/grok-3-mini", + name: "Grok 3 Mini", + family: "grok", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-04-11", + last_updated: "2025-04-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 0.5, cache_read: 0.075 }, + limit: { context: 131072, output: 8192 }, + }, + "xai/grok-4.20-multi-agent": { + id: "xai/grok-4.20-multi-agent", + name: "Grok-4.20-Multi-Agent", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2026-03-13", + last_updated: "2026-03-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 6, cache_read: 0.2 }, + limit: { context: 128000, output: 0 }, + }, + "xai/grok-3": { + id: "xai/grok-3", + name: "Grok 3", + family: "grok", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2025-04-11", + last_updated: "2025-04-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.75 }, + limit: { context: 131072, output: 8192 }, + }, + "xai/grok-4-fast-non-reasoning": { + id: "xai/grok-4-fast-non-reasoning", + name: "Grok-4-Fast-Non-Reasoning", + family: "grok", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2025-09-16", + last_updated: "2025-09-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5, cache_read: 0.05 }, + limit: { context: 2000000, output: 128000 }, + }, + "xai/grok-4.1-fast-reasoning": { + id: "xai/grok-4.1-fast-reasoning", + name: "Grok-4.1-Fast-Reasoning", + family: "grok", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-11-19", + last_updated: "2025-11-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + limit: { context: 2000000, output: 30000 }, + }, + "runwayml/runway": { + id: "runwayml/runway", + name: "Runway", + family: "runway", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2024-10-11", + last_updated: "2024-10-11", + modalities: { input: ["text", "image"], output: ["video"] }, + open_weights: false, + limit: { context: 256, output: 0 }, + }, + "runwayml/runway-gen-4-turbo": { + id: "runwayml/runway-gen-4-turbo", + name: "Runway-Gen-4-Turbo", + family: "runway", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2025-05-09", + last_updated: "2025-05-09", + modalities: { input: ["text", "image"], output: ["video"] }, + open_weights: false, + limit: { context: 256, output: 0 }, + }, + "openai/gpt-5.1-codex-max": { + id: "openai/gpt-5.1-codex-max", + name: "GPT-5.1-Codex-Max", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-12-08", + last_updated: "2025-12-08", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 9, cache_read: 0.11 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/sora-2-pro": { + id: "openai/sora-2-pro", + name: "Sora-2-Pro", + family: "sora", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2025-10-06", + last_updated: "2025-10-06", + modalities: { input: ["text", "image"], output: ["video"] }, + open_weights: false, + limit: { context: 0, output: 0 }, + }, + "openai/chatgpt-4o-latest": { + id: "openai/chatgpt-4o-latest", + name: "ChatGPT-4o-Latest", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2024-08-14", + last_updated: "2024-08-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 4.5, output: 14 }, + limit: { context: 128000, output: 8192 }, + status: "deprecated", + }, + "openai/gpt-5-chat": { + id: "openai/gpt-5-chat", + name: "GPT-5-Chat", + family: "gpt-codex", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 9, cache_read: 0.11 }, + limit: { context: 128000, output: 16384 }, + }, + "openai/gpt-5.2-pro": { + id: "openai/gpt-5.2-pro", + name: "GPT-5.2-Pro", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-12-11", + last_updated: "2025-12-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 19, output: 150 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-4o-aug": { + id: "openai/gpt-4o-aug", + name: "GPT-4o-Aug", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2024-11-21", + last_updated: "2024-11-21", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2.2, output: 9, cache_read: 1.1 }, + limit: { context: 128000, output: 8192 }, + }, + "openai/gpt-image-2": { + id: "openai/gpt-image-2", + name: "GPT-Image-2", + attachment: true, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2026-04-21", + last_updated: "2026-04-21", + modalities: { input: ["text", "image"], output: ["image"] }, + open_weights: false, + cost: { input: 5.0505, output: 32.3232, cache_read: 1.2626 }, + limit: { context: 0, output: 0 }, + }, + "openai/gpt-4-classic-0314": { + id: "openai/gpt-4-classic-0314", + name: "GPT-4-Classic-0314", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2024-08-26", + last_updated: "2024-08-26", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 27, output: 54 }, + limit: { context: 8192, output: 4096 }, + status: "deprecated", + }, + "openai/gpt-5-mini": { + id: "openai/gpt-5-mini", + name: "GPT-5-mini", + family: "gpt-mini", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-06-25", + last_updated: "2025-06-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.22, output: 1.8, cache_read: 0.022 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-5-nano": { + id: "openai/gpt-5-nano", + name: "GPT-5-nano", + family: "gpt-nano", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.045, output: 0.36, cache_read: 0.0045 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-5.3-codex": { + id: "openai/gpt-5.3-codex", + name: "GPT-5.3-Codex", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2026-02-10", + last_updated: "2026-02-10", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.6, output: 13, cache_read: 0.16 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-4-turbo": { + id: "openai/gpt-4-turbo", + name: "GPT-4-Turbo", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2023-09-13", + last_updated: "2023-09-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 9, output: 27 }, + limit: { context: 128000, output: 4096 }, + }, + "openai/gpt-5.2": { + id: "openai/gpt-5.2", + name: "GPT-5.2", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-12-08", + last_updated: "2025-12-08", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.6, output: 13, cache_read: 0.16 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/o3-pro": { + id: "openai/o3-pro", + name: "o3-pro", + family: "o-pro", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-06-10", + last_updated: "2025-06-10", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 18, output: 72 }, + limit: { context: 200000, output: 100000 }, + }, + "openai/o3-mini-high": { + id: "openai/o3-mini-high", + name: "o3-mini-high", + family: "o-mini", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-01-31", + last_updated: "2025-01-31", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.99, output: 4 }, + limit: { context: 200000, output: 100000 }, + }, + "openai/gpt-4o-mini": { + id: "openai/gpt-4o-mini", + name: "GPT-4o-mini", + family: "gpt-mini", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2024-07-18", + last_updated: "2024-07-18", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.14, output: 0.54, cache_read: 0.068 }, + limit: { context: 124096, output: 4096 }, + }, + "openai/o4-mini-deep-research": { + id: "openai/o4-mini-deep-research", + name: "o4-mini-deep-research", + family: "o-mini", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-06-27", + last_updated: "2025-06-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.8, output: 7.2, cache_read: 0.45 }, + limit: { context: 200000, output: 100000 }, + }, + "openai/gpt-5.4-mini": { + id: "openai/gpt-5.4-mini", + name: "GPT-5.4-Mini", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2026-03-12", + last_updated: "2026-03-12", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.68, output: 4, cache_read: 0.068 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "openai/dall-e-3": { + id: "openai/dall-e-3", + name: "DALL-E-3", + family: "dall-e", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2023-11-06", + last_updated: "2023-11-06", + modalities: { input: ["text"], output: ["image"] }, + open_weights: false, + limit: { context: 800, output: 0 }, + }, + "openai/o4-mini": { + id: "openai/o4-mini", + name: "o4-mini", + family: "o-mini", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-04-16", + last_updated: "2025-04-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.99, output: 4, cache_read: 0.25 }, + limit: { context: 200000, output: 100000 }, + }, + "openai/gpt-5.4-nano": { + id: "openai/gpt-5.4-nano", + name: "GPT-5.4-Nano", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2026-03-11", + last_updated: "2026-03-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.18, output: 1.1, cache_read: 0.018 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "openai/gpt-image-1": { + id: "openai/gpt-image-1", + name: "GPT-Image-1", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2025-03-31", + last_updated: "2025-03-31", + modalities: { input: ["text", "image"], output: ["image"] }, + open_weights: false, + limit: { context: 128000, output: 0 }, + }, + "openai/gpt-5.2-codex": { + id: "openai/gpt-5.2-codex", + name: "GPT-5.2-Codex", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2026-01-14", + last_updated: "2026-01-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.6, output: 13, cache_read: 0.16 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-5.1-codex-mini": { + id: "openai/gpt-5.1-codex-mini", + name: "GPT-5.1-Codex-Mini", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-11-12", + last_updated: "2025-11-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.22, output: 1.8, cache_read: 0.022 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-5.1": { + id: "openai/gpt-5.1", + name: "GPT-5.1", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-11-12", + last_updated: "2025-11-12", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 9, cache_read: 0.11 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-image-1-mini": { + id: "openai/gpt-image-1-mini", + name: "GPT-Image-1-Mini", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2025-08-26", + last_updated: "2025-08-26", + modalities: { input: ["text", "image"], output: ["image"] }, + open_weights: false, + limit: { context: 0, output: 0 }, + }, + "openai/o1": { + id: "openai/o1", + name: "o1", + family: "o", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2024-12-18", + last_updated: "2024-12-18", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 14, output: 54 }, + limit: { context: 200000, output: 100000 }, + }, + "openai/gpt-5.4-pro": { + id: "openai/gpt-5.4-pro", + name: "GPT-5.4-Pro", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2026-03-05", + last_updated: "2026-03-05", + modalities: { input: ["text", "image"], output: ["image"] }, + open_weights: false, + cost: { input: 27, output: 160 }, + limit: { context: 1050000, input: 922000, output: 128000 }, + }, + "openai/gpt-3.5-turbo": { + id: "openai/gpt-3.5-turbo", + name: "GPT-3.5-Turbo", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2023-09-13", + last_updated: "2023-09-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.45, output: 1.4 }, + limit: { context: 16384, output: 2048 }, + }, + "openai/o3-deep-research": { + id: "openai/o3-deep-research", + name: "o3-deep-research", + family: "o", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-06-27", + last_updated: "2025-06-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 9, output: 36, cache_read: 2.2 }, + limit: { context: 200000, output: 100000 }, + }, + "openai/o3-mini": { + id: "openai/o3-mini", + name: "o3-mini", + family: "o-mini", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-01-31", + last_updated: "2025-01-31", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.99, output: 4 }, + limit: { context: 200000, output: 100000 }, + }, + "openai/o1-pro": { + id: "openai/o1-pro", + name: "o1-pro", + family: "o-pro", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-03-19", + last_updated: "2025-03-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 140, output: 540 }, + limit: { context: 200000, output: 100000 }, + }, + "openai/gpt-4o-search": { + id: "openai/gpt-4o-search", + name: "GPT-4o-Search", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2025-03-11", + last_updated: "2025-03-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2.2, output: 9 }, + limit: { context: 128000, output: 8192 }, + }, + "openai/gpt-5-codex": { + id: "openai/gpt-5-codex", + name: "GPT-5-Codex", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-09-23", + last_updated: "2025-09-23", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 9 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-5.4": { + id: "openai/gpt-5.4", + name: "GPT-5.4", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2026-02-26", + last_updated: "2026-02-26", + modalities: { input: ["text", "image", "pdf"], output: ["image"] }, + open_weights: false, + cost: { input: 2.2, output: 14, cache_read: 0.22 }, + limit: { context: 1050000, input: 922000, output: 128000 }, + }, + "openai/gpt-5.3-codex-spark": { + id: "openai/gpt-5.3-codex-spark", + name: "GPT-5.3-Codex-Spark", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2026-03-04", + last_updated: "2026-03-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 16384 }, + }, + "openai/gpt-3.5-turbo-raw": { + id: "openai/gpt-3.5-turbo-raw", + name: "GPT-3.5-Turbo-Raw", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2023-09-27", + last_updated: "2023-09-27", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.45, output: 1.4 }, + limit: { context: 4524, output: 2048 }, + }, + "openai/gpt-4.1-nano": { + id: "openai/gpt-4.1-nano", + name: "GPT-4.1-nano", + family: "gpt-nano", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2025-04-15", + last_updated: "2025-04-15", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.09, output: 0.36, cache_read: 0.022 }, + limit: { context: 1047576, output: 32768 }, + }, + "openai/o3": { + id: "openai/o3", + name: "o3", + family: "o", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-04-16", + last_updated: "2025-04-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.8, output: 7.2, cache_read: 0.45 }, + limit: { context: 200000, output: 100000 }, + }, + "openai/gpt-5-pro": { + id: "openai/gpt-5-pro", + name: "GPT-5-Pro", + family: "gpt-pro", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-10-06", + last_updated: "2025-10-06", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 14, output: 110 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/sora-2": { + id: "openai/sora-2", + name: "Sora-2", + family: "sora", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2025-10-06", + last_updated: "2025-10-06", + modalities: { input: ["text", "image"], output: ["video"] }, + open_weights: false, + limit: { context: 0, output: 0 }, + }, + "openai/gpt-4o": { + id: "openai/gpt-4o", + name: "GPT-4o", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2024-05-13", + last_updated: "2024-05-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + limit: { context: 128000, output: 8192 }, + }, + "openai/gpt-5": { + id: "openai/gpt-5", + name: "GPT-5", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 9, cache_read: 0.11 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-5.2-instant": { + id: "openai/gpt-5.2-instant", + name: "GPT-5.2-Instant", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2025-12-11", + last_updated: "2025-12-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.6, output: 13, cache_read: 0.16 }, + limit: { context: 128000, output: 16384 }, + }, + "openai/gpt-4o-mini-search": { + id: "openai/gpt-4o-mini-search", + name: "GPT-4o-mini-Search", + family: "gpt-mini", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2025-03-11", + last_updated: "2025-03-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.14, output: 0.54 }, + limit: { context: 128000, output: 8192 }, + }, + "openai/gpt-image-1.5": { + id: "openai/gpt-image-1.5", + name: "gpt-image-1.5", + attachment: true, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2025-12-16", + last_updated: "2025-12-16", + modalities: { input: ["text", "image"], output: ["image"] }, + open_weights: false, + limit: { context: 128000, output: 0 }, + }, + "openai/gpt-3.5-turbo-instruct": { + id: "openai/gpt-3.5-turbo-instruct", + name: "GPT-3.5-Turbo-Instruct", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2023-09-20", + last_updated: "2023-09-20", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.4, output: 1.8 }, + limit: { context: 3500, output: 1024 }, + }, + "openai/gpt-4.1": { + id: "openai/gpt-4.1", + name: "GPT-4.1", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2025-04-14", + last_updated: "2025-04-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.8, output: 7.2, cache_read: 0.45 }, + limit: { context: 1047576, output: 32768 }, + }, + "openai/gpt-5.1-instant": { + id: "openai/gpt-5.1-instant", + name: "GPT-5.1-Instant", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-11-12", + last_updated: "2025-11-12", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 9, cache_read: 0.11 }, + limit: { context: 128000, output: 16384 }, + }, + "openai/gpt-4.1-mini": { + id: "openai/gpt-4.1-mini", + name: "GPT-4.1-mini", + family: "gpt-mini", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2025-04-15", + last_updated: "2025-04-15", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.36, output: 1.4, cache_read: 0.09 }, + limit: { context: 1047576, output: 32768 }, + }, + "openai/gpt-4-classic": { + id: "openai/gpt-4-classic", + name: "GPT-4-Classic", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2024-03-25", + last_updated: "2024-03-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 27, output: 54 }, + limit: { context: 8192, output: 4096 }, + status: "deprecated", + }, + "openai/gpt-5.1-codex": { + id: "openai/gpt-5.1-codex", + name: "GPT-5.1-Codex", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-11-12", + last_updated: "2025-11-12", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 9, cache_read: 0.11 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-5.3-instant": { + id: "openai/gpt-5.3-instant", + name: "GPT-5.3-Instant", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2026-03-03", + last_updated: "2026-03-03", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.6, output: 13, cache_read: 0.16 }, + limit: { context: 128000, input: 111616, output: 16384 }, + }, + "google/veo-3-fast": { + id: "google/veo-3-fast", + name: "Veo-3-Fast", + family: "veo", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2025-10-13", + last_updated: "2025-10-13", + modalities: { input: ["text"], output: ["video"] }, + open_weights: false, + limit: { context: 480, output: 0 }, + }, + "google/veo-3.1-fast": { + id: "google/veo-3.1-fast", + name: "Veo-3.1-Fast", + family: "veo", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2025-10-15", + last_updated: "2025-10-15", + modalities: { input: ["text", "image"], output: ["video"] }, + open_weights: false, + limit: { context: 480, output: 0 }, + }, + "google/gemini-3.1-pro": { + id: "google/gemini-3.1-pro", + name: "Gemini-3.1-Pro", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2026-02-19", + last_updated: "2026-02-19", + modalities: { input: ["text", "image", "video", "audio"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 12, cache_read: 0.2 }, + limit: { context: 1048576, output: 65536 }, + }, + "google/imagen-3-fast": { + id: "google/imagen-3-fast", + name: "Imagen-3-Fast", + family: "imagen", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2024-10-17", + last_updated: "2024-10-17", + modalities: { input: ["text"], output: ["image"] }, + open_weights: false, + limit: { context: 480, output: 0 }, + }, + "google/gemini-2.0-flash": { + id: "google/gemini-2.0-flash", + name: "Gemini-2.0-Flash", + family: "gemini-flash", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2024-12-11", + last_updated: "2024-12-11", + modalities: { input: ["text", "image", "video", "audio"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.42 }, + limit: { context: 990000, output: 8192 }, + }, + "google/gemini-deep-research": { + id: "google/gemini-deep-research", + name: "gemini-deep-research", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-12-11", + last_updated: "2025-12-11", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 1.6, output: 9.6 }, + limit: { context: 1048576, output: 0 }, + status: "deprecated", + }, + "google/gemini-2.5-pro": { + id: "google/gemini-2.5-pro", + name: "Gemini-2.5-Pro", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-02-05", + last_updated: "2025-02-05", + modalities: { input: ["text", "image", "video", "audio"], output: ["text"] }, + open_weights: false, + cost: { input: 0.87, output: 7, cache_read: 0.087 }, + limit: { context: 1065535, output: 65535 }, + }, + "google/imagen-3": { + id: "google/imagen-3", + name: "Imagen-3", + family: "imagen", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2024-10-15", + last_updated: "2024-10-15", + modalities: { input: ["text"], output: ["image"] }, + open_weights: false, + limit: { context: 480, output: 0 }, + }, + "google/nano-banana": { + id: "google/nano-banana", + name: "Nano-Banana", + family: "nano-banana", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2025-08-21", + last_updated: "2025-08-21", + modalities: { input: ["text", "image"], output: ["text", "image"] }, + open_weights: false, + cost: { input: 0.21, output: 1.8, cache_read: 0.021 }, + limit: { context: 65536, output: 0 }, + }, + "google/gemini-2.5-flash": { + id: "google/gemini-2.5-flash", + name: "Gemini-2.5-Flash", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-04-26", + last_updated: "2025-04-26", + modalities: { input: ["text", "image", "video", "audio"], output: ["text"] }, + open_weights: false, + cost: { input: 0.21, output: 1.8, cache_read: 0.021 }, + limit: { context: 1065535, output: 65535 }, + }, + "google/gemini-3.1-flash-lite": { + id: "google/gemini-3.1-flash-lite", + name: "Gemini-3.1-Flash-Lite", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2026-02-18", + last_updated: "2026-02-18", + modalities: { input: ["text", "image", "video", "audio"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 1.5 }, + limit: { context: 1048576, output: 65536 }, + }, + "google/gemini-3-flash": { + id: "google/gemini-3-flash", + name: "Gemini-3-Flash", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-10-07", + last_updated: "2025-10-07", + modalities: { input: ["text", "image", "video", "audio"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 2.4, cache_read: 0.04 }, + limit: { context: 1048576, output: 65536 }, + }, + "google/veo-3.1": { + id: "google/veo-3.1", + name: "Veo-3.1", + family: "veo", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2025-10-15", + last_updated: "2025-10-15", + modalities: { input: ["text"], output: ["video"] }, + open_weights: false, + limit: { context: 480, output: 0 }, + }, + "google/lyria": { + id: "google/lyria", + name: "Lyria", + family: "lyria", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2025-06-04", + last_updated: "2025-06-04", + modalities: { input: ["text"], output: ["audio"] }, + open_weights: false, + limit: { context: 0, output: 0 }, + }, + "google/imagen-4-ultra": { + id: "google/imagen-4-ultra", + name: "Imagen-4-Ultra", + family: "imagen", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2025-05-24", + last_updated: "2025-05-24", + modalities: { input: ["text"], output: ["image"] }, + open_weights: false, + limit: { context: 480, output: 0 }, + }, + "google/nano-banana-pro": { + id: "google/nano-banana-pro", + name: "Nano-Banana-Pro", + family: "nano-banana", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2025-11-19", + last_updated: "2025-11-19", + modalities: { input: ["text", "image"], output: ["image"] }, + open_weights: false, + cost: { input: 2, output: 12, cache_read: 0.2 }, + limit: { context: 65536, output: 0 }, + }, + "google/gemini-3-pro": { + id: "google/gemini-3-pro", + name: "Gemini-3-Pro", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-10-22", + last_updated: "2025-10-22", + modalities: { input: ["text", "image", "video", "audio"], output: ["text"] }, + open_weights: false, + cost: { input: 1.6, output: 9.6, cache_read: 0.16 }, + limit: { context: 1048576, output: 65536 }, + status: "deprecated", + }, + "google/imagen-4-fast": { + id: "google/imagen-4-fast", + name: "Imagen-4-Fast", + family: "imagen", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2025-06-25", + last_updated: "2025-06-25", + modalities: { input: ["text"], output: ["image"] }, + open_weights: false, + limit: { context: 480, output: 0 }, + }, + "google/veo-3": { + id: "google/veo-3", + name: "Veo-3", + family: "veo", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2025-05-21", + last_updated: "2025-05-21", + modalities: { input: ["text"], output: ["video"] }, + open_weights: false, + limit: { context: 480, output: 0 }, + }, + "google/gemini-2.5-flash-lite": { + id: "google/gemini-2.5-flash-lite", + name: "Gemini-2.5-Flash-Lite", + family: "gemini-flash-lite", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-06-19", + last_updated: "2025-06-19", + modalities: { input: ["text", "image", "video", "audio"], output: ["text"] }, + open_weights: false, + cost: { input: 0.07, output: 0.28 }, + limit: { context: 1024000, output: 64000 }, + }, + "google/imagen-4": { + id: "google/imagen-4", + name: "Imagen-4", + family: "imagen", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text"], output: ["image"] }, + open_weights: false, + limit: { context: 480, output: 0 }, + }, + "google/gemma-4-31b": { + id: "google/gemma-4-31b", + name: "Gemma-4-31B", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2026-04-02", + last_updated: "2026-04-02", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 262144, output: 8192 }, + }, + "google/gemini-2.0-flash-lite": { + id: "google/gemini-2.0-flash-lite", + name: "Gemini-2.0-Flash-Lite", + family: "gemini-flash-lite", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2025-02-05", + last_updated: "2025-02-05", + modalities: { input: ["text", "image", "video", "audio"], output: ["text"] }, + open_weights: false, + cost: { input: 0.052, output: 0.21 }, + limit: { context: 990000, output: 8192 }, + }, + "google/veo-2": { + id: "google/veo-2", + name: "Veo-2", + family: "veo", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2024-12-02", + last_updated: "2024-12-02", + modalities: { input: ["text"], output: ["video"] }, + open_weights: false, + limit: { context: 480, output: 0 }, + }, + "lumalabs/ray2": { + id: "lumalabs/ray2", + name: "Ray2", + family: "ray", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2025-02-20", + last_updated: "2025-02-20", + modalities: { input: ["text", "image"], output: ["video"] }, + open_weights: false, + limit: { context: 5000, output: 0 }, + }, + "anthropic/claude-opus-4.1": { + id: "anthropic/claude-opus-4.1", + name: "Claude-Opus-4.1", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 13, output: 64, cache_read: 1.3, cache_write: 16 }, + limit: { context: 196608, output: 32000 }, + }, + "anthropic/claude-sonnet-3.5": { + id: "anthropic/claude-sonnet-3.5", + name: "Claude-Sonnet-3.5", + family: "claude-sonnet", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2024-06-05", + last_updated: "2024-06-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2.6, output: 13, cache_read: 0.26, cache_write: 3.2 }, + limit: { context: 189096, output: 8192 }, + status: "deprecated", + }, + "anthropic/claude-haiku-3": { + id: "anthropic/claude-haiku-3", + name: "Claude-Haiku-3", + family: "claude-haiku", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2024-03-09", + last_updated: "2024-03-09", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.21, output: 1.1, cache_read: 0.021, cache_write: 0.26 }, + limit: { context: 189096, output: 8192 }, + }, + "anthropic/claude-opus-4.6": { + id: "anthropic/claude-opus-4.6", + name: "Claude-Opus-4.6", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2026-02-04", + last_updated: "2026-02-04", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 4.3, output: 21, cache_read: 0.43, cache_write: 5.3 }, + limit: { context: 983040, output: 128000 }, + }, + "anthropic/claude-opus-4.7": { + id: "anthropic/claude-opus-4.7", + name: "Claude-Opus-4.7", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2026-04-15", + last_updated: "2026-04-15", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 4.3, output: 21, cache_read: 0.43, cache_write: 5.4 }, + limit: { context: 1048576, output: 128000 }, + }, + "anthropic/claude-sonnet-4": { + id: "anthropic/claude-sonnet-4", + name: "Claude-Sonnet-4", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-05-21", + last_updated: "2025-05-21", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2.6, output: 13, cache_read: 0.26, cache_write: 3.2 }, + limit: { context: 983040, output: 64000 }, + }, + "anthropic/claude-sonnet-4.5": { + id: "anthropic/claude-sonnet-4.5", + name: "Claude-Sonnet-4.5", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-09-26", + last_updated: "2025-09-26", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2.6, output: 13, cache_read: 0.26, cache_write: 3.2 }, + limit: { context: 983040, output: 32768 }, + }, + "anthropic/claude-opus-4.5": { + id: "anthropic/claude-opus-4.5", + name: "Claude-Opus-4.5", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-11-21", + last_updated: "2025-11-21", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 4.3, output: 21, cache_read: 0.43, cache_write: 5.3 }, + limit: { context: 196608, output: 64000 }, + }, + "anthropic/claude-sonnet-3.7": { + id: "anthropic/claude-sonnet-3.7", + name: "Claude-Sonnet-3.7", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-02-19", + last_updated: "2025-02-19", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2.6, output: 13, cache_read: 0.26, cache_write: 3.2 }, + limit: { context: 196608, output: 128000 }, + }, + "anthropic/claude-opus-4": { + id: "anthropic/claude-opus-4", + name: "Claude-Opus-4", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-05-21", + last_updated: "2025-05-21", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 13, output: 64, cache_read: 1.3, cache_write: 16 }, + limit: { context: 192512, output: 28672 }, + }, + "anthropic/claude-haiku-3.5": { + id: "anthropic/claude-haiku-3.5", + name: "Claude-Haiku-3.5", + family: "claude-haiku", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2024-10-01", + last_updated: "2024-10-01", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.68, output: 3.4, cache_read: 0.068, cache_write: 0.85 }, + limit: { context: 189096, output: 8192 }, + }, + "anthropic/claude-haiku-4.5": { + id: "anthropic/claude-haiku-4.5", + name: "Claude-Haiku-4.5", + family: "claude-haiku", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-10-15", + last_updated: "2025-10-15", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.85, output: 4.3, cache_read: 0.085, cache_write: 1.1 }, + limit: { context: 192000, output: 64000 }, + }, + "anthropic/claude-sonnet-3.5-june": { + id: "anthropic/claude-sonnet-3.5-june", + name: "Claude-Sonnet-3.5-June", + family: "claude-sonnet", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2024-11-18", + last_updated: "2024-11-18", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2.6, output: 13, cache_read: 0.26, cache_write: 3.2 }, + limit: { context: 189096, output: 8192 }, + status: "deprecated", + }, + "anthropic/claude-sonnet-4.6": { + id: "anthropic/claude-sonnet-4.6", + name: "Claude-Sonnet-4.6", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2026-02-05", + last_updated: "2026-02-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2.6, output: 13, cache_read: 0.26, cache_write: 3.2 }, + limit: { context: 983040, output: 128000 }, + }, + "ideogramai/ideogram": { + id: "ideogramai/ideogram", + name: "Ideogram", + family: "ideogram", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2024-04-03", + last_updated: "2024-04-03", + modalities: { input: ["text", "image"], output: ["image"] }, + open_weights: false, + limit: { context: 150, output: 0 }, + }, + "ideogramai/ideogram-v2": { + id: "ideogramai/ideogram-v2", + name: "Ideogram-v2", + family: "ideogram", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2024-08-21", + last_updated: "2024-08-21", + modalities: { input: ["text", "image"], output: ["image"] }, + open_weights: false, + limit: { context: 150, output: 0 }, + }, + "ideogramai/ideogram-v2a-turbo": { + id: "ideogramai/ideogram-v2a-turbo", + name: "Ideogram-v2a-Turbo", + family: "ideogram", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2025-02-27", + last_updated: "2025-02-27", + modalities: { input: ["text"], output: ["image"] }, + open_weights: false, + limit: { context: 150, output: 0 }, + }, + "ideogramai/ideogram-v2a": { + id: "ideogramai/ideogram-v2a", + name: "Ideogram-v2a", + family: "ideogram", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2025-02-27", + last_updated: "2025-02-27", + modalities: { input: ["text"], output: ["image"] }, + open_weights: false, + limit: { context: 150, output: 0 }, + }, + "trytako/tako": { + id: "trytako/tako", + name: "Tako", + family: "tako", + attachment: true, + reasoning: false, + tool_call: true, + temperature: false, + release_date: "2024-08-15", + last_updated: "2024-08-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 2048, output: 0 }, + }, + "poetools/claude-code": { + id: "poetools/claude-code", + name: "claude-code", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2025-11-27", + last_updated: "2025-11-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 0, output: 0 }, + }, + "openai/gpt-5.5": { + id: "openai/gpt-5.5", + name: "GPT-5.5", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-12-01", + release_date: "2026-04-08", + last_updated: "2026-04-08", + modalities: { input: ["text", "image"], output: ["text", "image"] }, + open_weights: false, + cost: { input: 4.5455, output: 27.2727, cache_read: 0.4545 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-5.5-pro": { + id: "openai/gpt-5.5-pro", + name: "GPT-5.5-Pro", + family: "gpt-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: false, + knowledge: "2025-12-01", + release_date: "2026-04-08", + last_updated: "2026-04-08", + modalities: { input: ["text", "image"], output: ["text", "image"] }, + open_weights: false, + cost: { input: 27.2727, output: 163.6364 }, + limit: { context: 400000, output: 128000 }, + }, + }, + }, + helicone: { + id: "helicone", + env: ["HELICONE_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://ai-gateway.helicone.ai/v1", + name: "Helicone", + doc: "https://helicone.ai/models", + models: { + "mistral-nemo": { + id: "mistral-nemo", + name: "Mistral Nemo", + family: "mistral-nemo", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-07", + release_date: "2024-07-18", + last_updated: "2024-07-18", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 20, output: 40 }, + limit: { context: 128000, output: 16400 }, + }, + "grok-4-1-fast-reasoning": { + id: "grok-4-1-fast-reasoning", + name: "xAI Grok 4.1 Fast Reasoning", + family: "grok", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-11", + release_date: "2025-11-17", + last_updated: "2025-11-17", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.19999999999999998, output: 0.5, cache_read: 0.049999999999999996 }, + limit: { context: 2000000, output: 2000000 }, + }, + "gemma2-9b-it": { + id: "gemma2-9b-it", + name: "Google Gemma 2", + family: "gemma", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-06", + release_date: "2024-06-25", + last_updated: "2024-06-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.01, output: 0.03 }, + limit: { context: 8192, output: 8192 }, + }, + "llama-3.3-70b-instruct": { + id: "llama-3.3-70b-instruct", + name: "Meta Llama 3.3 70B Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-12", + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.13, output: 0.39 }, + limit: { context: 128000, output: 16400 }, + }, + "llama-4-scout": { + id: "llama-4-scout", + name: "Meta Llama 4 Scout 17B 16E", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.08, output: 0.3 }, + limit: { context: 131072, output: 8192 }, + }, + "chatgpt-4o-latest": { + id: "chatgpt-4o-latest", + name: "OpenAI ChatGPT-4o", + family: "gpt", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-08", + release_date: "2024-08-14", + last_updated: "2024-08-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 20, cache_read: 2.5 }, + limit: { context: 128000, output: 16384 }, + }, + "claude-3.5-sonnet-v2": { + id: "claude-3.5-sonnet-v2", + name: "Anthropic: Claude 3.5 Sonnet v2", + family: "claude-sonnet", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2024-10-22", + last_updated: "2024-10-22", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.30000000000000004, cache_write: 3.75 }, + limit: { context: 200000, output: 8192 }, + }, + "hermes-2-pro-llama-3-8b": { + id: "hermes-2-pro-llama-3-8b", + name: "Hermes 2 Pro Llama 3 8B", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-05", + release_date: "2024-05-27", + last_updated: "2024-05-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.14, output: 0.14 }, + limit: { context: 131072, output: 131072 }, + }, + "claude-3.7-sonnet": { + id: "claude-3.7-sonnet", + name: "Anthropic: Claude 3.7 Sonnet", + family: "claude-sonnet", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-02", + release_date: "2025-02-19", + last_updated: "2025-02-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.30000000000000004, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + }, + "llama-prompt-guard-2-22m": { + id: "llama-prompt-guard-2-22m", + name: "Meta Llama Prompt Guard 2 22M", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-10", + release_date: "2024-10-01", + last_updated: "2024-10-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.01, output: 0.01 }, + limit: { context: 512, output: 2 }, + }, + "o1-mini": { + id: "o1-mini", + name: "OpenAI: o1-mini", + family: "o-mini", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + knowledge: "2025-01", + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 4.4, cache_read: 0.55 }, + limit: { context: 128000, output: 65536 }, + }, + "gpt-4.1-mini-2025-04-14": { + id: "gpt-4.1-mini-2025-04-14", + name: "OpenAI GPT-4.1 Mini", + family: "gpt-mini", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-04-14", + last_updated: "2025-04-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.39999999999999997, output: 1.5999999999999999, cache_read: 0.09999999999999999 }, + limit: { context: 1047576, output: 32768 }, + }, + "deepseek-r1-distill-llama-70b": { + id: "deepseek-r1-distill-llama-70b", + name: "DeepSeek R1 Distill Llama 70B", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-01-20", + last_updated: "2025-01-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.03, output: 0.13 }, + limit: { context: 128000, output: 4096 }, + }, + "qwen3-32b": { + id: "qwen3-32b", + name: "Qwen3 32B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-04-28", + last_updated: "2025-04-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.29, output: 0.59 }, + limit: { context: 131072, output: 40960 }, + }, + "llama-3.3-70b-versatile": { + id: "llama-3.3-70b-versatile", + name: "Meta Llama 3.3 70B Versatile", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-12", + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.59, output: 0.7899999999999999 }, + limit: { context: 131072, output: 32678 }, + }, + "gpt-5-mini": { + id: "gpt-5-mini", + name: "OpenAI GPT-5 Mini", + family: "gpt-mini", + attachment: false, + reasoning: false, + tool_call: true, + temperature: false, + knowledge: "2025-01", + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 2, cache_read: 0.024999999999999998 }, + limit: { context: 400000, output: 128000 }, + }, + "gpt-5-nano": { + id: "gpt-5-nano", + name: "OpenAI GPT-5 Nano", + family: "gpt-nano", + attachment: false, + reasoning: false, + tool_call: true, + temperature: false, + knowledge: "2025-01", + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.049999999999999996, output: 0.39999999999999997, cache_read: 0.005 }, + limit: { context: 400000, output: 128000 }, + }, + "gemini-3-pro-preview": { + id: "gemini-3-pro-preview", + name: "Google Gemini 3 Pro Preview", + family: "gemini-pro", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-11", + release_date: "2025-11-18", + last_updated: "2025-11-18", + modalities: { input: ["text", "image", "audio", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 12, cache_read: 0.19999999999999998 }, + limit: { context: 1048576, output: 65536 }, + }, + "claude-3-haiku-20240307": { + id: "claude-3-haiku-20240307", + name: "Anthropic: Claude 3 Haiku", + family: "claude-haiku", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-03", + release_date: "2024-03-07", + last_updated: "2024-03-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 1.25, cache_read: 0.03, cache_write: 0.3 }, + limit: { context: 200000, output: 4096 }, + }, + "llama-4-maverick": { + id: "llama-4-maverick", + name: "Meta Llama 4 Maverick 17B 128E", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 131072, output: 8192 }, + }, + "claude-sonnet-4-5-20250929": { + id: "claude-sonnet-4-5-20250929", + name: "Anthropic: Claude Sonnet 4.5 (20250929)", + family: "claude-sonnet", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-09", + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.30000000000000004, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + }, + "gemini-2.5-pro": { + id: "gemini-2.5-pro", + name: "Google Gemini 2.5 Pro", + family: "gemini-pro", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-06", + release_date: "2025-06-17", + last_updated: "2025-06-17", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.3125, cache_write: 1.25 }, + limit: { context: 1048576, output: 65536 }, + }, + "claude-4.5-opus": { + id: "claude-4.5-opus", + name: "Anthropic: Claude Opus 4.5", + family: "claude-opus", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-11", + release_date: "2025-11-24", + last_updated: "2025-11-24", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 200000, output: 64000 }, + }, + "grok-4-1-fast-non-reasoning": { + id: "grok-4-1-fast-non-reasoning", + name: "xAI Grok 4.1 Fast Non-Reasoning", + family: "grok", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-11", + release_date: "2025-11-17", + last_updated: "2025-11-17", + modalities: { input: ["text", "image"], output: ["text", "image"] }, + open_weights: false, + cost: { input: 0.19999999999999998, output: 0.5, cache_read: 0.049999999999999996 }, + limit: { context: 2000000, output: 30000 }, + }, + "sonar-pro": { + id: "sonar-pro", + name: "Perplexity Sonar Pro", + family: "sonar-pro", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2025-01", + release_date: "2025-01-27", + last_updated: "2025-01-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15 }, + limit: { context: 200000, output: 4096 }, + }, + "mistral-large-2411": { + id: "mistral-large-2411", + name: "Mistral-Large", + family: "mistral-large", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2024-07-24", + last_updated: "2024-07-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 6 }, + limit: { context: 128000, output: 32768 }, + }, + "o3-pro": { + id: "o3-pro", + name: "OpenAI o3 Pro", + family: "o-pro", + attachment: false, + reasoning: false, + tool_call: true, + temperature: false, + knowledge: "2024-06", + release_date: "2024-06-01", + last_updated: "2024-06-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 20, output: 80 }, + limit: { context: 200000, output: 100000 }, + }, + "claude-opus-4-1": { + id: "claude-opus-4-1", + name: "Anthropic: Claude Opus 4.1", + family: "claude-opus", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-08", + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 32000 }, + }, + "gpt-4o-mini": { + id: "gpt-4o-mini", + name: "OpenAI GPT-4o-mini", + family: "gpt-mini", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2024-07-18", + last_updated: "2024-07-18", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.6, cache_read: 0.075 }, + limit: { context: 128000, output: 16384 }, + }, + "claude-4.5-haiku": { + id: "claude-4.5-haiku", + name: "Anthropic: Claude 4.5 Haiku", + family: "claude-haiku", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-10", + release_date: "2025-10-01", + last_updated: "2025-10-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 5, cache_read: 0.09999999999999999, cache_write: 1.25 }, + limit: { context: 200000, output: 8192 }, + }, + "kimi-k2-0711": { + id: "kimi-k2-0711", + name: "Kimi K2 (07/11)", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5700000000000001, output: 2.3 }, + limit: { context: 131072, output: 16384 }, + }, + "o4-mini": { + id: "o4-mini", + name: "OpenAI o4 Mini", + family: "o-mini", + attachment: false, + reasoning: false, + tool_call: true, + temperature: false, + knowledge: "2024-06", + release_date: "2024-06-01", + last_updated: "2024-06-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 4.4, cache_read: 0.275 }, + limit: { context: 200000, output: 100000 }, + }, + "sonar-deep-research": { + id: "sonar-deep-research", + name: "Perplexity Sonar Deep Research", + family: "sonar-deep-research", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + knowledge: "2025-01", + release_date: "2025-01-27", + last_updated: "2025-01-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 8 }, + limit: { context: 127000, output: 4096 }, + }, + "gemma-3-12b-it": { + id: "gemma-3-12b-it", + name: "Google Gemma 3 12B", + family: "gemma", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-12", + release_date: "2024-12-01", + last_updated: "2024-12-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.049999999999999996, output: 0.09999999999999999 }, + limit: { context: 131072, output: 8192 }, + }, + "gemini-2.5-flash": { + id: "gemini-2.5-flash", + name: "Google Gemini 2.5 Flash", + family: "gemini-flash", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-06", + release_date: "2025-06-17", + last_updated: "2025-06-17", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 2.5, cache_read: 0.075, cache_write: 0.3 }, + limit: { context: 1048576, output: 65535 }, + }, + "deepseek-tng-r1t2-chimera": { + id: "deepseek-tng-r1t2-chimera", + name: "DeepSeek TNG R1T2 Chimera", + family: "deepseek-thinking", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-07-02", + last_updated: "2025-07-02", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 130000, output: 163840 }, + }, + "gpt-5.1-codex-mini": { + id: "gpt-5.1-codex-mini", + name: "OpenAI: GPT-5.1 Codex Mini", + family: "gpt-codex", + attachment: false, + reasoning: false, + tool_call: true, + temperature: false, + knowledge: "2025-01", + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text", "image"], output: ["text", "image"] }, + open_weights: false, + cost: { input: 0.25, output: 2, cache_read: 0.024999999999999998 }, + limit: { context: 400000, output: 128000 }, + }, + "claude-sonnet-4": { + id: "claude-sonnet-4", + name: "Anthropic: Claude Sonnet 4", + family: "claude-sonnet", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-05", + release_date: "2025-05-14", + last_updated: "2025-05-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.30000000000000004, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + }, + "grok-code-fast-1": { + id: "grok-code-fast-1", + name: "xAI Grok Code Fast 1", + family: "grok", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-08", + release_date: "2024-08-25", + last_updated: "2024-08-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.19999999999999998, output: 1.5, cache_read: 0.02 }, + limit: { context: 256000, output: 10000 }, + }, + "gpt-5.1": { + id: "gpt-5.1", + name: "OpenAI GPT-5.1", + family: "gpt", + attachment: false, + reasoning: false, + tool_call: true, + temperature: false, + knowledge: "2025-01", + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text", "image"], output: ["text", "image"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.12500000000000003 }, + limit: { context: 400000, output: 128000 }, + }, + "deepseek-reasoner": { + id: "deepseek-reasoner", + name: "DeepSeek Reasoner", + family: "deepseek-thinking", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2025-01", + release_date: "2025-01-20", + last_updated: "2025-01-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.56, output: 1.68, cache_read: 0.07 }, + limit: { context: 128000, output: 64000 }, + }, + "grok-4-fast-reasoning": { + id: "grok-4-fast-reasoning", + name: "xAI: Grok 4 Fast Reasoning", + family: "grok", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-09", + release_date: "2025-09-01", + last_updated: "2025-09-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.19999999999999998, output: 0.5, cache_read: 0.049999999999999996 }, + limit: { context: 2000000, output: 2000000 }, + }, + o1: { + id: "o1", + name: "OpenAI: o1", + family: "o", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + knowledge: "2025-01", + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 60, cache_read: 7.5 }, + limit: { context: 200000, output: 100000 }, + }, + "llama-3.1-8b-instant": { + id: "llama-3.1-8b-instant", + name: "Meta Llama 3.1 8B Instant", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2024-07-01", + last_updated: "2024-07-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.049999999999999996, output: 0.08 }, + limit: { context: 131072, output: 32678 }, + }, + "o3-mini": { + id: "o3-mini", + name: "OpenAI o3 Mini", + family: "o-mini", + attachment: false, + reasoning: false, + tool_call: true, + temperature: false, + knowledge: "2023-10", + release_date: "2023-10-01", + last_updated: "2023-10-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 4.4, cache_read: 0.55 }, + limit: { context: 200000, output: 100000 }, + }, + sonar: { + id: "sonar", + name: "Perplexity Sonar", + family: "sonar", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2025-01", + release_date: "2025-01-27", + last_updated: "2025-01-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 1 }, + limit: { context: 127000, output: 4096 }, + }, + "kimi-k2-0905": { + id: "kimi-k2-0905", + name: "Kimi K2 (09/05)", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-09", + release_date: "2025-09-05", + last_updated: "2025-09-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 2, cache_read: 0.39999999999999997 }, + limit: { context: 262144, output: 16384 }, + }, + "mistral-small": { + id: "mistral-small", + name: "Mistral Small", + family: "mistral-small", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-02", + release_date: "2024-02-26", + last_updated: "2024-02-26", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 75, output: 200 }, + limit: { context: 128000, output: 128000 }, + }, + "qwen3-30b-a3b": { + id: "qwen3-30b-a3b", + name: "Qwen3 30B A3B", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-06", + release_date: "2025-06-01", + last_updated: "2025-06-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.08, output: 0.29 }, + limit: { context: 41000, output: 41000 }, + }, + "grok-4": { + id: "grok-4", + name: "xAI Grok 4", + family: "grok", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2024-07-09", + last_updated: "2024-07-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.75 }, + limit: { context: 256000, output: 256000 }, + }, + "qwen3-235b-a22b-thinking": { + id: "qwen3-235b-a22b-thinking", + name: "Qwen3 235B A22B Thinking", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + knowledge: "2025-07", + release_date: "2025-07-25", + last_updated: "2025-07-25", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 2.9000000000000004 }, + limit: { context: 262144, output: 81920 }, + }, + "qwen2.5-coder-7b-fast": { + id: "qwen2.5-coder-7b-fast", + name: "Qwen2.5 Coder 7B fast", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-09", + release_date: "2024-09-15", + last_updated: "2024-09-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.03, output: 0.09 }, + limit: { context: 32000, output: 8192 }, + }, + "llama-3.1-8b-instruct-turbo": { + id: "llama-3.1-8b-instruct-turbo", + name: "Meta Llama 3.1 8B Instruct Turbo", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.02, output: 0.03 }, + limit: { context: 128000, output: 128000 }, + }, + "qwen3-next-80b-a3b-instruct": { + id: "qwen3-next-80b-a3b-instruct", + name: "Qwen3 Next 80B A3B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.14, output: 1.4 }, + limit: { context: 262000, output: 16384 }, + }, + "glm-4.6": { + id: "glm-4.6", + name: "Zai GLM-4.6", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2024-07-18", + last_updated: "2024-07-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.44999999999999996, output: 1.5 }, + limit: { context: 204800, output: 131072 }, + }, + "gpt-5-codex": { + id: "gpt-5-codex", + name: "OpenAI: GPT-5 Codex", + family: "gpt-codex", + attachment: false, + reasoning: false, + tool_call: true, + temperature: false, + knowledge: "2025-01", + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.12500000000000003 }, + limit: { context: 400000, output: 128000 }, + }, + "claude-opus-4-1-20250805": { + id: "claude-opus-4-1-20250805", + name: "Anthropic: Claude Opus 4.1 (20250805)", + family: "claude-opus", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-08", + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 32000 }, + }, + "gpt-5.1-chat-latest": { + id: "gpt-5.1-chat-latest", + name: "OpenAI GPT-5.1 Chat", + family: "gpt-codex", + attachment: false, + reasoning: false, + tool_call: true, + temperature: false, + knowledge: "2025-01", + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text", "image"], output: ["text", "image"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.12500000000000003 }, + limit: { context: 128000, output: 16384 }, + }, + "claude-haiku-4-5-20251001": { + id: "claude-haiku-4-5-20251001", + name: "Anthropic: Claude 4.5 Haiku (20251001)", + family: "claude-haiku", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-10", + release_date: "2025-10-01", + last_updated: "2025-10-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 5, cache_read: 0.09999999999999999, cache_write: 1.25 }, + limit: { context: 200000, output: 8192 }, + }, + "sonar-reasoning": { + id: "sonar-reasoning", + name: "Perplexity Sonar Reasoning", + family: "sonar-reasoning", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + knowledge: "2025-01", + release_date: "2025-01-27", + last_updated: "2025-01-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 5 }, + limit: { context: 127000, output: 4096 }, + }, + "claude-opus-4": { + id: "claude-opus-4", + name: "Anthropic: Claude Opus 4", + family: "claude-opus", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-05", + release_date: "2025-05-14", + last_updated: "2025-05-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 32000 }, + }, + "llama-prompt-guard-2-86m": { + id: "llama-prompt-guard-2-86m", + name: "Meta Llama Prompt Guard 2 86M", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-10", + release_date: "2024-10-01", + last_updated: "2024-10-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.01, output: 0.01 }, + limit: { context: 512, output: 2 }, + }, + "gpt-4.1-nano": { + id: "gpt-4.1-nano", + name: "OpenAI GPT-4.1 Nano", + family: "gpt-nano", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-04-14", + last_updated: "2025-04-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.09999999999999999, output: 0.39999999999999997, cache_read: 0.024999999999999998 }, + limit: { context: 1047576, output: 32768 }, + }, + "qwen3-coder-30b-a3b-instruct": { + id: "qwen3-coder-30b-a3b-instruct", + name: "Qwen3 Coder 30B A3B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-07-31", + last_updated: "2025-07-31", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.09999999999999999, output: 0.3 }, + limit: { context: 262144, output: 262144 }, + }, + "claude-3.5-haiku": { + id: "claude-3.5-haiku", + name: "Anthropic: Claude 3.5 Haiku", + family: "claude-haiku", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2024-10-22", + last_updated: "2024-10-22", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.7999999999999999, output: 4, cache_read: 0.08, cache_write: 1 }, + limit: { context: 200000, output: 8192 }, + }, + "grok-3-mini": { + id: "grok-3-mini", + name: "xAI Grok 3 Mini", + family: "grok", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-06", + release_date: "2024-06-01", + last_updated: "2024-06-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 0.5, cache_read: 0.075 }, + limit: { context: 131072, output: 131072 }, + }, + o3: { + id: "o3", + name: "OpenAI o3", + family: "o", + attachment: false, + reasoning: false, + tool_call: true, + temperature: false, + knowledge: "2024-06", + release_date: "2024-06-01", + last_updated: "2024-06-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 8, cache_read: 0.5 }, + limit: { context: 200000, output: 100000 }, + }, + "deepseek-v3.2": { + id: "deepseek-v3.2", + name: "DeepSeek V3.2", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-09", + release_date: "2025-09-22", + last_updated: "2025-09-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.27, output: 0.41 }, + limit: { context: 163840, output: 65536 }, + }, + "gpt-oss-20b": { + id: "gpt-oss-20b", + name: "OpenAI GPT-OSS 20b", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-06", + release_date: "2024-06-01", + last_updated: "2024-06-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.049999999999999996, output: 0.19999999999999998 }, + limit: { context: 131072, output: 131072 }, + }, + "gpt-5-pro": { + id: "gpt-5-pro", + name: "OpenAI: GPT-5 Pro", + family: "gpt-pro", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + knowledge: "2025-01", + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 120 }, + limit: { context: 128000, output: 32768 }, + }, + "llama-guard-4": { + id: "llama-guard-4", + name: "Meta Llama Guard 4 12B", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2025-01", + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.21, output: 0.21 }, + limit: { context: 131072, output: 1024 }, + }, + "gpt-4o": { + id: "gpt-4o", + name: "OpenAI GPT-4o", + family: "gpt", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-05", + release_date: "2024-05-13", + last_updated: "2024-05-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 10, cache_read: 1.25 }, + limit: { context: 128000, output: 16384 }, + }, + "qwen3-vl-235b-a22b-instruct": { + id: "qwen3-vl-235b-a22b-instruct", + name: "Qwen3 VL 235B A22B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-09", + release_date: "2025-09-23", + last_updated: "2025-09-23", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 1.5 }, + limit: { context: 256000, output: 16384 }, + }, + "gemini-2.5-flash-lite": { + id: "gemini-2.5-flash-lite", + name: "Google Gemini 2.5 Flash Lite", + family: "gemini-flash-lite", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-07-22", + last_updated: "2025-07-22", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { + input: 0.09999999999999999, + output: 0.39999999999999997, + cache_read: 0.024999999999999998, + cache_write: 0.09999999999999999, + }, + limit: { context: 1048576, output: 65535 }, + }, + "qwen3-coder": { + id: "qwen3-coder", + name: "Qwen3 Coder 480B A35B Instruct Turbo", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-07-23", + last_updated: "2025-07-23", + modalities: { input: ["text", "image", "audio", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.22, output: 0.95 }, + limit: { context: 262144, output: 16384 }, + }, + "gpt-5": { + id: "gpt-5", + name: "OpenAI GPT-5", + family: "gpt", + attachment: false, + reasoning: false, + tool_call: true, + temperature: false, + knowledge: "2025-01", + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.12500000000000003 }, + limit: { context: 400000, output: 128000 }, + }, + "ernie-4.5-21b-a3b-thinking": { + id: "ernie-4.5-21b-a3b-thinking", + name: "Baidu Ernie 4.5 21B A3B Thinking", + family: "ernie", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + knowledge: "2025-03", + release_date: "2025-03-16", + last_updated: "2025-03-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.07, output: 0.28 }, + limit: { context: 128000, output: 8000 }, + }, + "gpt-oss-120b": { + id: "gpt-oss-120b", + name: "OpenAI GPT-OSS 120b", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-06", + release_date: "2024-06-01", + last_updated: "2024-06-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.04, output: 0.16 }, + limit: { context: 131072, output: 131072 }, + }, + "gpt-5-chat-latest": { + id: "gpt-5-chat-latest", + name: "OpenAI GPT-5 Chat Latest", + family: "gpt-codex", + attachment: false, + reasoning: false, + tool_call: true, + temperature: false, + knowledge: "2024-09", + release_date: "2024-09-30", + last_updated: "2024-09-30", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.12500000000000003 }, + limit: { context: 128000, output: 16384 }, + }, + "claude-4.5-sonnet": { + id: "claude-4.5-sonnet", + name: "Anthropic: Claude Sonnet 4.5", + family: "claude-sonnet", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-09", + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.30000000000000004, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + }, + "deepseek-v3": { + id: "deepseek-v3", + name: "DeepSeek V3", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-12", + release_date: "2024-12-26", + last_updated: "2024-12-26", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.56, output: 1.68, cache_read: 0.07 }, + limit: { context: 128000, output: 8192 }, + }, + "llama-3.1-8b-instruct": { + id: "llama-3.1-8b-instruct", + name: "Meta Llama 3.1 8B Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.02, output: 0.049999999999999996 }, + limit: { context: 16384, output: 16384 }, + }, + "gpt-4.1": { + id: "gpt-4.1", + name: "OpenAI GPT-4.1", + family: "gpt", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-04-14", + last_updated: "2025-04-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 8, cache_read: 0.5 }, + limit: { context: 1047576, output: 32768 }, + }, + "kimi-k2-thinking": { + id: "kimi-k2-thinking", + name: "Kimi K2 Thinking", + family: "kimi-thinking", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-11", + release_date: "2025-11-06", + last_updated: "2025-11-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.48, output: 2 }, + limit: { context: 256000, output: 262144 }, + }, + "gpt-4.1-mini": { + id: "gpt-4.1-mini", + name: "OpenAI GPT-4.1 Mini", + family: "gpt-mini", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-04-14", + last_updated: "2025-04-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.39999999999999997, output: 1.5999999999999999, cache_read: 0.09999999999999999 }, + limit: { context: 1047576, output: 32768 }, + }, + "deepseek-v3.1-terminus": { + id: "deepseek-v3.1-terminus", + name: "DeepSeek V3.1 Terminus", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-09", + release_date: "2025-09-22", + last_updated: "2025-09-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.27, output: 1, cache_read: 0.21600000000000003 }, + limit: { context: 128000, output: 16384 }, + }, + "gpt-5.1-codex": { + id: "gpt-5.1-codex", + name: "OpenAI: GPT-5.1 Codex", + family: "gpt-codex", + attachment: false, + reasoning: false, + tool_call: true, + temperature: false, + knowledge: "2025-01", + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text", "image"], output: ["text", "image"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.12500000000000003 }, + limit: { context: 400000, output: 128000 }, + }, + "grok-3": { + id: "grok-3", + name: "xAI Grok 3", + family: "grok", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-06", + release_date: "2024-06-01", + last_updated: "2024-06-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.75 }, + limit: { context: 131072, output: 131072 }, + }, + "grok-4-fast-non-reasoning": { + id: "grok-4-fast-non-reasoning", + name: "xAI Grok 4 Fast Non-Reasoning", + family: "grok", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-09", + release_date: "2025-09-19", + last_updated: "2025-09-19", + modalities: { input: ["text", "image", "audio"], output: ["text"] }, + open_weights: false, + cost: { input: 0.19999999999999998, output: 0.5, cache_read: 0.049999999999999996 }, + limit: { context: 2000000, output: 2000000 }, + }, + "sonar-reasoning-pro": { + id: "sonar-reasoning-pro", + name: "Perplexity Sonar Reasoning Pro", + family: "sonar-reasoning", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + knowledge: "2025-01", + release_date: "2025-01-27", + last_updated: "2025-01-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 8 }, + limit: { context: 127000, output: 4096 }, + }, + }, + }, + "ollama-cloud": { + id: "ollama-cloud", + env: ["OLLAMA_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://ollama.com/v1", + name: "Ollama Cloud", + doc: "https://docs.ollama.com/cloud", + models: { + "minimax-m2.7": { + id: "minimax-m2.7", + name: "minimax-m2.7", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + limit: { context: 196608, output: 196608 }, + }, + "gpt-oss:20b": { + id: "gpt-oss:20b", + name: "gpt-oss:20b", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + release_date: "2025-08-05", + last_updated: "2026-01-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + limit: { context: 131072, output: 32768 }, + }, + "kimi-k2.5": { + id: "kimi-k2.5", + name: "kimi-k2.5", + family: "kimi", + attachment: true, + reasoning: true, + tool_call: true, + release_date: "2026-01-27", + last_updated: "2026-01-27", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + limit: { context: 262144, output: 262144 }, + }, + "glm-4.7": { + id: "glm-4.7", + name: "glm-4.7", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + release_date: "2025-12-22", + last_updated: "2026-01-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + limit: { context: 202752, output: 131072 }, + }, + "gemma4:31b": { + id: "gemma4:31b", + name: "gemma4:31b", + family: "gemma", + attachment: true, + reasoning: true, + tool_call: true, + knowledge: "2025-01", + release_date: "2026-04-02", + last_updated: "2026-04-08", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + limit: { context: 262144, output: 262144 }, + }, + "gpt-oss:120b": { + id: "gpt-oss:120b", + name: "gpt-oss:120b", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + release_date: "2025-08-05", + last_updated: "2026-01-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + limit: { context: 131072, output: 32768 }, + }, + "qwen3.5:397b": { + id: "qwen3.5:397b", + name: "qwen3.5:397b", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_details" }, + release_date: "2026-02-15", + last_updated: "2026-02-17", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + limit: { context: 262144, output: 65536 }, + }, + "deepseek-v3.1:671b": { + id: "deepseek-v3.1:671b", + name: "deepseek-v3.1:671b", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + release_date: "2025-08-21", + last_updated: "2026-01-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + limit: { context: 163840, output: 163840 }, + }, + "glm-5": { + id: "glm-5", + name: "glm-5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + release_date: "2026-02-11", + last_updated: "2026-02-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + limit: { context: 202752, output: 131072 }, + }, + "qwen3-vl:235b-instruct": { + id: "qwen3-vl:235b-instruct", + name: "qwen3-vl:235b-instruct", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: true, + release_date: "2025-09-22", + last_updated: "2026-01-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + limit: { context: 262144, output: 131072 }, + }, + "gemma3:4b": { + id: "gemma3:4b", + name: "gemma3:4b", + family: "gemma", + attachment: true, + reasoning: false, + tool_call: false, + release_date: "2024-12-01", + last_updated: "2026-01-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + limit: { context: 131072, output: 131072 }, + }, + "gemini-3-flash-preview": { + id: "gemini-3-flash-preview", + name: "gemini-3-flash-preview", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + knowledge: "2025-01", + release_date: "2025-12-17", + last_updated: "2026-04-08", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + limit: { context: 1048576, output: 65536 }, + }, + "ministral-3:14b": { + id: "ministral-3:14b", + name: "ministral-3:14b", + family: "ministral", + attachment: true, + reasoning: false, + tool_call: true, + release_date: "2024-12-01", + last_updated: "2026-01-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + limit: { context: 262144, output: 128000 }, + }, + "minimax-m2": { + id: "minimax-m2", + name: "minimax-m2", + family: "minimax", + attachment: false, + reasoning: false, + tool_call: true, + release_date: "2025-10-23", + last_updated: "2026-01-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + limit: { context: 204800, output: 128000 }, + }, + "qwen3-next:80b": { + id: "qwen3-next:80b", + name: "qwen3-next:80b", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + release_date: "2025-09-15", + last_updated: "2026-01-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + limit: { context: 262144, output: 32768 }, + }, + "qwen3-vl:235b": { + id: "qwen3-vl:235b", + name: "qwen3-vl:235b", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + release_date: "2025-09-22", + last_updated: "2026-01-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + limit: { context: 262144, output: 32768 }, + }, + "rnj-1:8b": { + id: "rnj-1:8b", + name: "rnj-1:8b", + family: "rnj", + attachment: false, + reasoning: false, + tool_call: true, + release_date: "2025-12-06", + last_updated: "2026-01-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + limit: { context: 32768, output: 4096 }, + }, + "minimax-m2.1": { + id: "minimax-m2.1", + name: "minimax-m2.1", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + release_date: "2025-12-23", + last_updated: "2026-01-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + limit: { context: 204800, output: 131072 }, + }, + "glm-5.1": { + id: "glm-5.1", + name: "glm-5.1", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + release_date: "2026-03-27", + last_updated: "2026-04-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + limit: { context: 202752, output: 131072 }, + }, + "mistral-large-3:675b": { + id: "mistral-large-3:675b", + name: "mistral-large-3:675b", + family: "mistral-large", + attachment: true, + reasoning: false, + tool_call: true, + release_date: "2025-12-02", + last_updated: "2026-01-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + limit: { context: 262144, output: 262144 }, + }, + "ministral-3:8b": { + id: "ministral-3:8b", + name: "ministral-3:8b", + family: "ministral", + attachment: true, + reasoning: false, + tool_call: true, + release_date: "2024-12-01", + last_updated: "2026-01-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + limit: { context: 262144, output: 128000 }, + }, + "gemma3:12b": { + id: "gemma3:12b", + name: "gemma3:12b", + family: "gemma", + attachment: true, + reasoning: false, + tool_call: false, + release_date: "2024-12-01", + last_updated: "2026-01-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + limit: { context: 131072, output: 131072 }, + }, + "qwen3-coder:480b": { + id: "qwen3-coder:480b", + name: "qwen3-coder:480b", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + release_date: "2025-07-22", + last_updated: "2026-01-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + limit: { context: 262144, output: 65536 }, + }, + "kimi-k2.6:cloud": { + id: "kimi-k2.6:cloud", + name: "kimi-k2.6:cloud", + family: "kimi", + attachment: true, + reasoning: true, + tool_call: true, + release_date: "2026-04-20", + last_updated: "2026-04-20", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + limit: { context: 262144, output: 262144 }, + }, + "nemotron-3-nano:30b": { + id: "nemotron-3-nano:30b", + name: "nemotron-3-nano:30b", + family: "nemotron", + attachment: false, + reasoning: true, + tool_call: true, + release_date: "2025-12-15", + last_updated: "2026-01-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + limit: { context: 1048576, output: 131072 }, + }, + "deepseek-v4-flash": { + id: "deepseek-v4-flash", + name: "deepseek-v4-flash", + family: "deepseek-flash", + attachment: false, + reasoning: true, + tool_call: true, + release_date: "2026-04-24", + last_updated: "2026-04-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + limit: { context: 1048576, output: 1048576 }, + }, + "glm-4.6": { + id: "glm-4.6", + name: "glm-4.6", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + release_date: "2025-09-29", + last_updated: "2026-01-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + limit: { context: 202752, output: 131072 }, + }, + "ministral-3:3b": { + id: "ministral-3:3b", + name: "ministral-3:3b", + family: "ministral", + attachment: true, + reasoning: false, + tool_call: true, + release_date: "2024-10-22", + last_updated: "2026-01-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + limit: { context: 262144, output: 128000 }, + }, + "gemma3:27b": { + id: "gemma3:27b", + name: "gemma3:27b", + family: "gemma", + attachment: true, + reasoning: false, + tool_call: false, + release_date: "2025-07-27", + last_updated: "2026-01-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + limit: { context: 131072, output: 131072 }, + }, + "devstral-2:123b": { + id: "devstral-2:123b", + name: "devstral-2:123b", + family: "devstral", + attachment: false, + reasoning: false, + tool_call: true, + release_date: "2025-12-09", + last_updated: "2026-01-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + limit: { context: 262144, output: 262144 }, + }, + "cogito-2.1:671b": { + id: "cogito-2.1:671b", + name: "cogito-2.1:671b", + family: "cogito", + attachment: false, + reasoning: true, + tool_call: true, + release_date: "2025-11-19", + last_updated: "2026-01-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + limit: { context: 163840, output: 32000 }, + }, + "qwen3-coder-next": { + id: "qwen3-coder-next", + name: "qwen3-coder-next", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + release_date: "2026-02-02", + last_updated: "2026-02-08", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + limit: { context: 262144, output: 65536 }, + }, + "nemotron-3-super": { + id: "nemotron-3-super", + name: "nemotron-3-super", + family: "nemotron", + attachment: false, + reasoning: true, + tool_call: true, + release_date: "2026-03-11", + last_updated: "2026-03-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + limit: { context: 262144, output: 65536 }, + }, + "deepseek-v4-pro": { + id: "deepseek-v4-pro", + name: "deepseek-v4-pro", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + release_date: "2026-04-24", + last_updated: "2026-04-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + limit: { context: 1048576, output: 1048576 }, + }, + "minimax-m2.5": { + id: "minimax-m2.5", + name: "minimax-m2.5", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + knowledge: "2025-01", + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + limit: { context: 204800, output: 131072 }, + }, + "deepseek-v3.2": { + id: "deepseek-v3.2", + name: "deepseek-v3.2", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + release_date: "2025-06-15", + last_updated: "2026-01-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + limit: { context: 163840, output: 65536 }, + }, + "kimi-k2-thinking": { + id: "kimi-k2-thinking", + name: "kimi-k2-thinking", + family: "kimi-thinking", + attachment: false, + reasoning: true, + tool_call: true, + knowledge: "2024-08", + release_date: "2025-11-06", + last_updated: "2026-01-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + limit: { context: 262144, output: 262144 }, + }, + "devstral-small-2:24b": { + id: "devstral-small-2:24b", + name: "devstral-small-2:24b", + family: "devstral", + attachment: true, + reasoning: false, + tool_call: true, + release_date: "2025-12-09", + last_updated: "2026-01-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + limit: { context: 262144, output: 262144 }, + }, + "kimi-k2:1t": { + id: "kimi-k2:1t", + name: "kimi-k2:1t", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + knowledge: "2024-10", + release_date: "2025-07-11", + last_updated: "2026-01-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + limit: { context: 262144, output: 262144 }, + }, + }, + }, + "zai-coding-plan": { + id: "zai-coding-plan", + env: ["ZHIPU_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.z.ai/api/coding/paas/v4", + name: "Z.AI Coding Plan", + doc: "https://docs.z.ai/devpack/overview", + models: { + "glm-4.7": { + id: "glm-4.7", + name: "GLM-4.7", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-04", + release_date: "2025-12-22", + last_updated: "2025-12-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 204800, output: 131072 }, + }, + "glm-5.1": { + id: "glm-5.1", + name: "GLM-5.1", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-03-27", + last_updated: "2026-03-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 200000, output: 131072 }, + }, + "glm-4.5-air": { + id: "glm-4.5-air", + name: "GLM-4.5-Air", + family: "glm-air", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-28", + last_updated: "2025-07-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 131072, output: 98304 }, + }, + "glm-5-turbo": { + id: "glm-5-turbo", + name: "GLM-5-Turbo", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-03-16", + last_updated: "2026-03-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 200000, output: 131072 }, + }, + "glm-5v-turbo": { + id: "glm-5v-turbo", + name: "GLM-5V-Turbo", + family: "glm", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-04-01", + last_updated: "2026-04-01", + modalities: { input: ["text", "image", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 200000, output: 131072 }, + }, + }, + }, + "amazon-bedrock": { + id: "amazon-bedrock", + env: ["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "AWS_REGION", "AWS_BEARER_TOKEN_BEDROCK"], + npm: "@ai-sdk/amazon-bedrock", + name: "Amazon Bedrock", + doc: "https://docs.aws.amazon.com/bedrock/latest/userguide/models-supported.html", + models: { + "openai.gpt-oss-safeguard-120b": { + id: "openai.gpt-oss-safeguard-120b", + name: "GPT OSS Safeguard 120B", + family: "gpt-oss", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-12-01", + last_updated: "2024-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 128000, output: 4096 }, + }, + "nvidia.nemotron-nano-3-30b": { + id: "nvidia.nemotron-nano-3-30b", + name: "NVIDIA Nemotron Nano 3 30B", + family: "nemotron", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-12-23", + last_updated: "2025-12-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.06, output: 0.24 }, + limit: { context: 128000, output: 4096 }, + }, + "nvidia.nemotron-super-3-120b": { + id: "nvidia.nemotron-super-3-120b", + name: "NVIDIA Nemotron 3 Super 120B A12B", + family: "nemotron", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-11", + last_updated: "2026-03-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.65 }, + limit: { context: 262144, output: 131072 }, + }, + "writer.palmyra-x5-v1:0": { + id: "writer.palmyra-x5-v1:0", + name: "Palmyra X5", + family: "palmyra", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-04-28", + last_updated: "2025-04-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.6, output: 6 }, + limit: { context: 1040000, output: 8192 }, + }, + "mistral.ministral-3-8b-instruct": { + id: "mistral.ministral-3-8b-instruct", + name: "Ministral 3 8B", + family: "ministral", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-12-01", + last_updated: "2024-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.15 }, + limit: { context: 128000, output: 4096 }, + }, + "au.anthropic.claude-opus-4-6-v1": { + id: "au.anthropic.claude-opus-4-6-v1", + name: "AU Anthropic Claude Opus 4.6", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-05", + release_date: "2026-02-05", + last_updated: "2026-02-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 16.5, output: 82.5, cache_read: 1.65, cache_write: 20.625 }, + limit: { context: 1000000, output: 128000 }, + }, + "mistral.ministral-3-3b-instruct": { + id: "mistral.ministral-3-3b-instruct", + name: "Ministral 3 3B", + family: "ministral", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-12-02", + last_updated: "2025-12-02", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.1 }, + limit: { context: 256000, output: 8192 }, + }, + "anthropic.claude-sonnet-4-5-20250929-v1:0": { + id: "anthropic.claude-sonnet-4-5-20250929-v1:0", + name: "Claude Sonnet 4.5", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-07-31", + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + }, + "mistral.devstral-2-123b": { + id: "mistral.devstral-2-123b", + name: "Devstral 2 123B", + family: "devstral", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2026-02-17", + last_updated: "2026-02-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.4, output: 2 }, + limit: { context: 256000, output: 8192 }, + }, + "global.anthropic.claude-opus-4-5-20251101-v1:0": { + id: "global.anthropic.claude-opus-4-5-20251101-v1:0", + name: "Claude Opus 4.5 (Global)", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-11-24", + last_updated: "2025-08-01", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 200000, output: 64000 }, + }, + "mistral.voxtral-small-24b-2507": { + id: "mistral.voxtral-small-24b-2507", + name: "Voxtral Small 24B 2507", + family: "mistral", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-07-01", + last_updated: "2025-07-01", + modalities: { input: ["text", "audio"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.35 }, + limit: { context: 32000, output: 8192 }, + }, + "google.gemma-3-12b-it": { + id: "google.gemma-3-12b-it", + name: "Google Gemma 3 12B", + family: "gemma", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: true, + temperature: true, + knowledge: "2024-12", + release_date: "2024-12-01", + last_updated: "2024-12-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.049999999999999996, output: 0.09999999999999999 }, + limit: { context: 131072, output: 8192 }, + }, + "amazon.nova-pro-v1:0": { + id: "amazon.nova-pro-v1:0", + name: "Nova Pro", + family: "nova-pro", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2024-12-03", + last_updated: "2024-12-03", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.8, output: 3.2, cache_read: 0.2 }, + limit: { context: 300000, output: 8192 }, + }, + "anthropic.claude-haiku-4-5-20251001-v1:0": { + id: "anthropic.claude-haiku-4-5-20251001-v1:0", + name: "Claude Haiku 4.5", + family: "claude-haiku", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-02-28", + release_date: "2025-10-15", + last_updated: "2025-10-15", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 5, cache_read: 0.1, cache_write: 1.25 }, + limit: { context: 200000, output: 64000 }, + }, + "minimax.minimax-m2": { + id: "minimax.minimax-m2", + name: "MiniMax M2", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-10-27", + last_updated: "2025-10-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 204608, output: 128000 }, + }, + "global.anthropic.claude-opus-4-7": { + id: "global.anthropic.claude-opus-4-7", + name: "Claude Opus 4.7 (Global)", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2026-01-31", + release_date: "2026-04-16", + last_updated: "2026-04-16", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 1000000, output: 128000 }, + }, + "mistral.pixtral-large-2502-v1:0": { + id: "mistral.pixtral-large-2502-v1:0", + name: "Pixtral Large (25.02)", + family: "mistral", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-04-08", + last_updated: "2025-04-08", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 6 }, + limit: { context: 128000, output: 8192 }, + }, + "meta.llama4-maverick-17b-instruct-v1:0": { + id: "meta.llama4-maverick-17b-instruct-v1:0", + name: "Llama 4 Maverick 17B Instruct", + family: "llama", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-08", + release_date: "2025-04-05", + last_updated: "2025-04-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.24, output: 0.97 }, + limit: { context: 1000000, output: 16384 }, + }, + "us.anthropic.claude-sonnet-4-5-20250929-v1:0": { + id: "us.anthropic.claude-sonnet-4-5-20250929-v1:0", + name: "Claude Sonnet 4.5 (US)", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-07-31", + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + }, + "us.anthropic.claude-haiku-4-5-20251001-v1:0": { + id: "us.anthropic.claude-haiku-4-5-20251001-v1:0", + name: "Claude Haiku 4.5 (US)", + family: "claude-haiku", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-02-28", + release_date: "2025-10-15", + last_updated: "2025-10-15", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 5, cache_read: 0.1, cache_write: 1.25 }, + limit: { context: 200000, output: 64000 }, + }, + "amazon.nova-micro-v1:0": { + id: "amazon.nova-micro-v1:0", + name: "Nova Micro", + family: "nova-micro", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2024-12-03", + last_updated: "2024-12-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.035, output: 0.14, cache_read: 0.00875 }, + limit: { context: 128000, output: 8192 }, + }, + "global.anthropic.claude-sonnet-4-5-20250929-v1:0": { + id: "global.anthropic.claude-sonnet-4-5-20250929-v1:0", + name: "Claude Sonnet 4.5 (Global)", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-07-31", + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + }, + "openai.gpt-oss-20b-1:0": { + id: "openai.gpt-oss-20b-1:0", + name: "gpt-oss-20b", + family: "gpt-oss", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-12-01", + last_updated: "2024-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.07, output: 0.3 }, + limit: { context: 128000, output: 4096 }, + }, + "zai.glm-5": { + id: "zai.glm-5", + name: "GLM-5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 3.2 }, + limit: { context: 202752, output: 101376 }, + }, + "qwen.qwen3-32b-v1:0": { + id: "qwen.qwen3-32b-v1:0", + name: "Qwen3 32B (dense)", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-09-18", + last_updated: "2025-09-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 16384, output: 16384 }, + }, + "deepseek.v3.2": { + id: "deepseek.v3.2", + name: "DeepSeek-V3.2", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2026-02-06", + last_updated: "2026-02-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.62, output: 1.85 }, + limit: { context: 163840, output: 81920 }, + }, + "eu.anthropic.claude-haiku-4-5-20251001-v1:0": { + id: "eu.anthropic.claude-haiku-4-5-20251001-v1:0", + name: "Claude Haiku 4.5 (EU)", + family: "claude-haiku", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-02-28", + release_date: "2025-10-15", + last_updated: "2025-10-15", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 5, cache_read: 0.1, cache_write: 1.25 }, + limit: { context: 200000, output: 64000 }, + }, + "zai.glm-4.7-flash": { + id: "zai.glm-4.7-flash", + name: "GLM-4.7-Flash", + family: "glm-flash", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-01-19", + last_updated: "2026-01-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.07, output: 0.4 }, + limit: { context: 200000, output: 131072 }, + }, + "us.anthropic.claude-opus-4-7": { + id: "us.anthropic.claude-opus-4-7", + name: "Claude Opus 4.7 (US)", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2026-01-31", + release_date: "2026-04-16", + last_updated: "2026-04-16", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 1000000, output: 128000 }, + }, + "amazon.nova-2-lite-v1:0": { + id: "amazon.nova-2-lite-v1:0", + name: "Nova 2 Lite", + family: "nova", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-12-01", + last_updated: "2024-12-01", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.33, output: 2.75 }, + limit: { context: 128000, output: 4096 }, + }, + "anthropic.claude-opus-4-5-20251101-v1:0": { + id: "anthropic.claude-opus-4-5-20251101-v1:0", + name: "Claude Opus 4.5", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-11-24", + last_updated: "2025-08-01", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 200000, output: 64000 }, + }, + "qwen.qwen3-coder-480b-a35b-v1:0": { + id: "qwen.qwen3-coder-480b-a35b-v1:0", + name: "Qwen3 Coder 480B A35B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-09-18", + last_updated: "2025-09-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.22, output: 1.8 }, + limit: { context: 131072, output: 65536 }, + }, + "amazon.nova-lite-v1:0": { + id: "amazon.nova-lite-v1:0", + name: "Nova Lite", + family: "nova-lite", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2024-12-03", + last_updated: "2024-12-03", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.06, output: 0.24, cache_read: 0.015 }, + limit: { context: 300000, output: 8192 }, + }, + "meta.llama3-1-8b-instruct-v1:0": { + id: "meta.llama3-1-8b-instruct-v1:0", + name: "Llama 3.1 8B Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.22, output: 0.22 }, + limit: { context: 128000, output: 4096 }, + }, + "anthropic.claude-opus-4-7": { + id: "anthropic.claude-opus-4-7", + name: "Claude Opus 4.7", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2026-01-31", + release_date: "2026-04-16", + last_updated: "2026-04-16", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 1000000, output: 128000 }, + }, + "google.gemma-3-27b-it": { + id: "google.gemma-3-27b-it", + name: "Google Gemma 3 27B Instruct", + family: "gemma", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-07-27", + last_updated: "2025-07-27", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.12, output: 0.2 }, + limit: { context: 202752, output: 8192 }, + }, + "global.anthropic.claude-haiku-4-5-20251001-v1:0": { + id: "global.anthropic.claude-haiku-4-5-20251001-v1:0", + name: "Claude Haiku 4.5 (Global)", + family: "claude-haiku", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-02-28", + release_date: "2025-10-15", + last_updated: "2025-10-15", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 5, cache_read: 0.1, cache_write: 1.25 }, + limit: { context: 200000, output: 64000 }, + }, + "google.gemma-3-4b-it": { + id: "google.gemma-3-4b-it", + name: "Gemma 3 4B IT", + family: "gemma", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-12-01", + last_updated: "2024-12-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.04, output: 0.08 }, + limit: { context: 128000, output: 4096 }, + }, + "meta.llama4-scout-17b-instruct-v1:0": { + id: "meta.llama4-scout-17b-instruct-v1:0", + name: "Llama 4 Scout 17B Instruct", + family: "llama", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-08", + release_date: "2025-04-05", + last_updated: "2025-04-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.17, output: 0.66 }, + limit: { context: 3500000, output: 16384 }, + }, + "deepseek.v3-v1:0": { + id: "deepseek.v3-v1:0", + name: "DeepSeek-V3.1", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-07", + release_date: "2025-09-18", + last_updated: "2025-09-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.58, output: 1.68 }, + limit: { context: 163840, output: 81920 }, + }, + "mistral.magistral-small-2509": { + id: "mistral.magistral-small-2509", + name: "Magistral Small 1.2", + family: "magistral", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-12-02", + last_updated: "2025-12-02", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.5, output: 1.5 }, + limit: { context: 128000, output: 40000 }, + }, + "qwen.qwen3-next-80b-a3b": { + id: "qwen.qwen3-next-80b-a3b", + name: "Qwen/Qwen3-Next-80B-A3B-Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-09-18", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.14, output: 1.4 }, + limit: { context: 262000, output: 262000 }, + }, + "zai.glm-4.7": { + id: "zai.glm-4.7", + name: "GLM-4.7", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-04", + release_date: "2025-12-22", + last_updated: "2025-12-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.2 }, + limit: { context: 204800, output: 131072 }, + }, + "moonshot.kimi-k2-thinking": { + id: "moonshot.kimi-k2-thinking", + name: "Kimi K2 Thinking", + family: "kimi-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: true, + structured_output: true, + temperature: true, + release_date: "2025-12-02", + last_updated: "2025-12-02", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.5 }, + limit: { context: 256000, output: 256000 }, + }, + "us.anthropic.claude-opus-4-5-20251101-v1:0": { + id: "us.anthropic.claude-opus-4-5-20251101-v1:0", + name: "Claude Opus 4.5 (US)", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-11-24", + last_updated: "2025-08-01", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 200000, output: 64000 }, + }, + "mistral.ministral-3-14b-instruct": { + id: "mistral.ministral-3-14b-instruct", + name: "Ministral 14B 3.0", + family: "ministral", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-12-01", + last_updated: "2024-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.2 }, + limit: { context: 128000, output: 4096 }, + }, + "deepseek.r1-v1:0": { + id: "deepseek.r1-v1:0", + name: "DeepSeek-R1", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2025-01-20", + last_updated: "2025-05-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.35, output: 5.4 }, + limit: { context: 128000, output: 32768 }, + }, + "mistral.voxtral-mini-3b-2507": { + id: "mistral.voxtral-mini-3b-2507", + name: "Voxtral Mini 3B 2507", + family: "mistral", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-12-01", + last_updated: "2024-12-01", + modalities: { input: ["audio", "text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.04, output: 0.04 }, + limit: { context: 128000, output: 4096 }, + }, + "openai.gpt-oss-120b-1:0": { + id: "openai.gpt-oss-120b-1:0", + name: "gpt-oss-120b", + family: "gpt-oss", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-12-01", + last_updated: "2024-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 128000, output: 4096 }, + }, + "nvidia.nemotron-nano-12b-v2": { + id: "nvidia.nemotron-nano-12b-v2", + name: "NVIDIA Nemotron Nano 12B v2 VL BF16", + family: "nemotron", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-12-01", + last_updated: "2024-12-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.6 }, + limit: { context: 128000, output: 4096 }, + }, + "eu.anthropic.claude-opus-4-7": { + id: "eu.anthropic.claude-opus-4-7", + name: "Claude Opus 4.7 (EU)", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2026-01-31", + release_date: "2026-04-16", + last_updated: "2026-04-16", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 1000000, output: 128000 }, + }, + "minimax.minimax-m2.5": { + id: "minimax.minimax-m2.5", + name: "MiniMax M2.5", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 196608, output: 98304 }, + }, + "meta.llama3-3-70b-instruct-v1:0": { + id: "meta.llama3-3-70b-instruct-v1:0", + name: "Llama 3.3 70B Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.72, output: 0.72 }, + limit: { context: 128000, output: 4096 }, + }, + "meta.llama3-1-70b-instruct-v1:0": { + id: "meta.llama3-1-70b-instruct-v1:0", + name: "Llama 3.1 70B Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.72, output: 0.72 }, + limit: { context: 128000, output: 4096 }, + }, + "eu.anthropic.claude-sonnet-4-5-20250929-v1:0": { + id: "eu.anthropic.claude-sonnet-4-5-20250929-v1:0", + name: "Claude Sonnet 4.5 (EU)", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-07-31", + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + }, + "eu.anthropic.claude-opus-4-5-20251101-v1:0": { + id: "eu.anthropic.claude-opus-4-5-20251101-v1:0", + name: "Claude Opus 4.5 (EU)", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-11-24", + last_updated: "2025-08-01", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 200000, output: 64000 }, + }, + "moonshotai.kimi-k2.5": { + id: "moonshotai.kimi-k2.5", + name: "Kimi K2.5", + family: "kimi", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: true, + temperature: true, + release_date: "2026-02-06", + last_updated: "2026-02-06", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 3 }, + limit: { context: 256000, output: 256000 }, + }, + "au.anthropic.claude-sonnet-4-6": { + id: "au.anthropic.claude-sonnet-4-6", + name: "AU Anthropic Claude Sonnet 4.6", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-08", + release_date: "2026-02-17", + last_updated: "2026-02-17", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3.3, output: 16.5, cache_read: 0.33, cache_write: 4.125 }, + limit: { context: 1000000, output: 128000 }, + }, + "openai.gpt-oss-safeguard-20b": { + id: "openai.gpt-oss-safeguard-20b", + name: "GPT OSS Safeguard 20B", + family: "gpt-oss", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-12-01", + last_updated: "2024-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.07, output: 0.2 }, + limit: { context: 128000, output: 4096 }, + }, + "qwen.qwen3-coder-30b-a3b-v1:0": { + id: "qwen.qwen3-coder-30b-a3b-v1:0", + name: "Qwen3 Coder 30B A3B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-09-18", + last_updated: "2025-09-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 262144, output: 131072 }, + }, + "minimax.minimax-m2.1": { + id: "minimax.minimax-m2.1", + name: "MiniMax M2.1", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-12-23", + last_updated: "2025-12-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 204800, output: 131072 }, + }, + "qwen.qwen3-vl-235b-a22b": { + id: "qwen.qwen3-vl-235b-a22b", + name: "Qwen/Qwen3-VL-235B-A22B-Instruct", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-10-04", + last_updated: "2025-11-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 1.5 }, + limit: { context: 262000, output: 262000 }, + }, + "qwen.qwen3-coder-next": { + id: "qwen.qwen3-coder-next", + name: "Qwen3 Coder Next", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-02-06", + last_updated: "2026-02-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.22, output: 1.8 }, + limit: { context: 131072, output: 65536 }, + }, + "nvidia.nemotron-nano-9b-v2": { + id: "nvidia.nemotron-nano-9b-v2", + name: "NVIDIA Nemotron Nano 9B v2", + family: "nemotron", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-12-01", + last_updated: "2024-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.06, output: 0.23 }, + limit: { context: 128000, output: 4096 }, + }, + "mistral.mistral-large-3-675b-instruct": { + id: "mistral.mistral-large-3-675b-instruct", + name: "Mistral Large 3", + family: "mistral", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-12-02", + last_updated: "2025-12-02", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.5, output: 1.5 }, + limit: { context: 256000, output: 8192 }, + }, + "qwen.qwen3-235b-a22b-2507-v1:0": { + id: "qwen.qwen3-235b-a22b-2507-v1:0", + name: "Qwen3 235B A22B 2507", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-09-18", + last_updated: "2025-09-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.22, output: 0.88 }, + limit: { context: 262144, output: 131072 }, + }, + "writer.palmyra-x4-v1:0": { + id: "writer.palmyra-x4-v1:0", + name: "Palmyra X4", + family: "palmyra", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-04-28", + last_updated: "2025-04-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 10 }, + limit: { context: 122880, output: 8192 }, + }, + "anthropic.claude-opus-4-1-20250805-v1:0": { + id: "anthropic.claude-opus-4-1-20250805-v1:0", + name: "Claude Opus 4.1", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 32000 }, + }, + "us.deepseek.r1-v1:0": { + id: "us.deepseek.r1-v1:0", + name: "DeepSeek-R1 (US)", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2025-01-20", + last_updated: "2025-05-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.35, output: 5.4 }, + limit: { context: 128000, output: 32768 }, + }, + "eu.anthropic.claude-opus-4-6-v1": { + id: "eu.anthropic.claude-opus-4-6-v1", + name: "Claude Opus 4.6 (EU)", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-05-31", + release_date: "2026-02-05", + last_updated: "2026-03-13", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 1000000, output: 128000 }, + }, + "us.meta.llama4-maverick-17b-instruct-v1:0": { + id: "us.meta.llama4-maverick-17b-instruct-v1:0", + name: "Llama 4 Maverick 17B Instruct (US)", + family: "llama", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-08", + release_date: "2025-04-05", + last_updated: "2025-04-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.24, output: 0.97 }, + limit: { context: 1000000, output: 16384 }, + }, + "au.anthropic.claude-haiku-4-5-20251001-v1:0": { + id: "au.anthropic.claude-haiku-4-5-20251001-v1:0", + name: "Claude Haiku 4.5 (AU)", + family: "claude-haiku", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-02-28", + release_date: "2025-10-15", + last_updated: "2025-10-15", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 5, cache_read: 0.1, cache_write: 1.25 }, + limit: { context: 200000, output: 64000 }, + }, + "jp.anthropic.claude-sonnet-4-5-20250929-v1:0": { + id: "jp.anthropic.claude-sonnet-4-5-20250929-v1:0", + name: "Claude Sonnet 4.5 (JP)", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07-31", + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + }, + "anthropic.claude-sonnet-4-6": { + id: "anthropic.claude-sonnet-4-6", + name: "Claude Sonnet 4.6", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: 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, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 1000000, output: 64000 }, + }, + "jp.anthropic.claude-sonnet-4-6": { + id: "jp.anthropic.claude-sonnet-4-6", + name: "Claude Sonnet 4.6 (JP)", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: 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, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 1000000, output: 64000 }, + }, + "global.anthropic.claude-sonnet-4-6": { + id: "global.anthropic.claude-sonnet-4-6", + name: "Claude Sonnet 4.6 (Global)", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: 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, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 1000000, output: 64000 }, + }, + "us.anthropic.claude-sonnet-4-6": { + id: "us.anthropic.claude-sonnet-4-6", + name: "Claude Sonnet 4.6 (US)", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: 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, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 1000000, output: 64000 }, + }, + "global.anthropic.claude-opus-4-6-v1": { + id: "global.anthropic.claude-opus-4-6-v1", + name: "Claude Opus 4.6 (Global)", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-05-31", + release_date: "2026-02-05", + last_updated: "2026-03-13", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 1000000, output: 128000 }, + }, + "us.anthropic.claude-opus-4-6-v1": { + id: "us.anthropic.claude-opus-4-6-v1", + name: "Claude Opus 4.6 (US)", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-05-31", + release_date: "2026-02-05", + last_updated: "2026-03-13", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 1000000, output: 128000 }, + }, + "us.anthropic.claude-opus-4-1-20250805-v1:0": { + id: "us.anthropic.claude-opus-4-1-20250805-v1:0", + name: "Claude Opus 4.1 (US)", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 32000 }, + }, + "au.anthropic.claude-sonnet-4-5-20250929-v1:0": { + id: "au.anthropic.claude-sonnet-4-5-20250929-v1:0", + name: "Claude Sonnet 4.5 (AU)", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07-31", + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + }, + "eu.anthropic.claude-sonnet-4-6": { + id: "eu.anthropic.claude-sonnet-4-6", + name: "Claude Sonnet 4.6 (EU)", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: 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, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 1000000, output: 64000 }, + }, + "us.meta.llama4-scout-17b-instruct-v1:0": { + id: "us.meta.llama4-scout-17b-instruct-v1:0", + name: "Llama 4 Scout 17B Instruct (US)", + family: "llama", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-08", + release_date: "2025-04-05", + last_updated: "2025-04-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.17, output: 0.66 }, + limit: { context: 3500000, output: 16384 }, + }, + "anthropic.claude-opus-4-6-v1": { + id: "anthropic.claude-opus-4-6-v1", + name: "Claude Opus 4.6", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-05-31", + release_date: "2026-02-05", + last_updated: "2026-03-13", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 1000000, output: 128000 }, + }, + "jp.anthropic.claude-opus-4-7": { + id: "jp.anthropic.claude-opus-4-7", + name: "Claude Opus 4.7 (JP)", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2026-01-31", + release_date: "2026-04-16", + last_updated: "2026-04-16", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 1000000, output: 128000 }, + }, + }, + }, + "the-grid-ai": { + id: "the-grid-ai", + env: ["THEGRIDAI_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.thegrid.ai/v1", + name: "The Grid AI", + doc: "https://thegrid.ai/docs", + models: { + "text-prime": { + id: "text-prime", + name: "Text Prime", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-02-26", + last_updated: "2026-02-26", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 128000, output: 30000 }, + status: "beta", + }, + "text-standard": { + id: "text-standard", + name: "Text Standard", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-02-26", + last_updated: "2026-02-26", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 128000, output: 16000 }, + status: "beta", + }, + "text-max": { + id: "text-max", + name: "Text Max", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-03-24", + last_updated: "2026-03-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 1000000, output: 128000 }, + status: "beta", + }, + }, + }, + baseten: { + id: "baseten", + env: ["BASETEN_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://inference.baseten.co/v1", + name: "Baseten", + doc: "https://docs.baseten.co/development/model-apis/overview", + models: { + "zai-org/GLM-4.7": { + id: "zai-org/GLM-4.7", + name: "GLM-4.7", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-04", + release_date: "2025-12-22", + last_updated: "2025-12-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.2 }, + limit: { context: 204800, output: 131072 }, + }, + "zai-org/GLM-5": { + id: "zai-org/GLM-5", + name: "GLM-5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2026-01", + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.95, output: 3.15 }, + limit: { context: 202752, output: 131072 }, + }, + "zai-org/GLM-4.6": { + id: "zai-org/GLM-4.6", + name: "GLM 4.6", + family: "glm", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-08-31", + release_date: "2025-09-16", + last_updated: "2025-09-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.2 }, + limit: { context: 200000, output: 200000 }, + }, + "nvidia/Nemotron-120B-A12B": { + id: "nvidia/Nemotron-120B-A12B", + name: "Nemotron 3 Super", + family: "nemotron", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2026-02", + release_date: "2026-03-11", + last_updated: "2026-03-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 0.75 }, + limit: { context: 262144, output: 32678 }, + }, + "deepseek-ai/DeepSeek-V3.1": { + id: "deepseek-ai/DeepSeek-V3.1", + name: "DeepSeek V3.1", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-25", + last_updated: "2025-08-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.5, output: 1.5 }, + limit: { context: 164000, output: 131000 }, + }, + "deepseek-ai/DeepSeek-V3-0324": { + id: "deepseek-ai/DeepSeek-V3-0324", + name: "DeepSeek V3 0324", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-12", + release_date: "2025-03-24", + last_updated: "2025-03-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.77, output: 0.77 }, + limit: { context: 164000, output: 131000 }, + }, + "deepseek-ai/DeepSeek-V3.2": { + id: "deepseek-ai/DeepSeek-V3.2", + name: "DeepSeek V3.2", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-10", + release_date: "2025-12-01", + last_updated: "2026-03-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 0.45 }, + limit: { context: 163800, output: 131100 }, + status: "deprecated", + }, + "openai/gpt-oss-120b": { + id: "openai/gpt-oss-120b", + name: "GPT OSS 120B", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-08", + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.5 }, + limit: { context: 128000, output: 128000 }, + }, + "moonshotai/Kimi-K2-Thinking": { + id: "moonshotai/Kimi-K2-Thinking", + name: "Kimi K2 Thinking", + family: "kimi-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-08", + release_date: "2025-11-06", + last_updated: "2026-03-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.5 }, + limit: { context: 262144, output: 262144 }, + status: "deprecated", + }, + "moonshotai/Kimi-K2.6": { + id: "moonshotai/Kimi-K2.6", + name: "Kimi K2.6", + family: "kimi-k2.6", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-04-21", + last_updated: "2026-04-21", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.95, output: 4, cache_read: 0.16 }, + limit: { context: 262144, output: 262144 }, + }, + "moonshotai/Kimi-K2-Instruct-0905": { + id: "moonshotai/Kimi-K2-Instruct-0905", + name: "Kimi K2 Instruct 0905", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-08", + release_date: "2025-09-05", + last_updated: "2026-03-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.5 }, + limit: { context: 262144, output: 262144 }, + status: "deprecated", + }, + "moonshotai/Kimi-K2.5": { + id: "moonshotai/Kimi-K2.5", + name: "Kimi K2.5", + family: "kimi", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-12", + release_date: "2026-01-30", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 3 }, + limit: { context: 262144, output: 8192 }, + }, + "MiniMaxAI/MiniMax-M2.5": { + id: "MiniMaxAI/MiniMax-M2.5", + name: "MiniMax-M2.5", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2026-01", + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 204000, output: 204000 }, + }, + "deepseek-ai/DeepSeek-V4-Pro": { + id: "deepseek-ai/DeepSeek-V4-Pro", + name: "DeepSeek V4 Pro", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-05", + release_date: "2026-04-24", + last_updated: "2026-04-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.74, output: 3.48, cache_read: 0.15 }, + limit: { context: 1000000, output: 384000 }, + }, + }, + }, + frogbot: { + id: "frogbot", + env: ["FROGBOT_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://app.frogbot.ai/api/v1", + name: "FrogBot", + doc: "https://docs.frogbot.ai", + models: { + "grok-4-1-fast-reasoning": { + id: "grok-4-1-fast-reasoning", + name: "Grok 4.1 Fast (Reasoning)", + family: "grok", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-11", + release_date: "2025-11-25", + last_updated: "2025-11-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5, cache_read: 0.05 }, + limit: { context: 2000000, output: 128000 }, + }, + "claude-haiku-4-5": { + id: "claude-haiku-4-5", + name: "Claude Haiku 4.5", + family: "claude-haiku", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-02-28", + release_date: "2025-10-15", + last_updated: "2025-10-15", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 5, cache_read: 0.1, cache_write: 1.25 }, + limit: { context: 200000, output: 64000 }, + }, + "kimi-k2.5": { + id: "kimi-k2.5", + name: "Kimi-K2.5", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "1970-01-01", + last_updated: "1970-01-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.6, output: 3, cache_read: 0.1 }, + limit: { context: 256000, output: 128000 }, + }, + "claude-sonnet-4-6": { + id: "claude-sonnet-4-6", + name: "Claude Sonnet 4.6", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-08-31", + release_date: "2026-02-17", + last_updated: "2026-02-17", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + }, + "gemini-3-flash-preview": { + id: "gemini-3-flash-preview", + name: "Gemini 3 Flash Preview", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-12-17", + last_updated: "2025-12-17", + modalities: { input: ["text", "image", "video", "audio", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 3, cache_read: 0.05 }, + limit: { context: 1048576, output: 65536 }, + }, + "claude-opus-4-7": { + id: "claude-opus-4-7", + name: "Claude Opus 4.7", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2026-01-31", + release_date: "2026-04-16", + last_updated: "2026-04-16", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 200000, output: 128000 }, + }, + "zai-glm-5-1": { + id: "zai-glm-5-1", + name: "Z.AI GLM-5.1", + family: "glm", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-01-20", + last_updated: "2025-02-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.4, output: 4.4, cache_read: 0.26 }, + limit: { context: 198000, output: 8192 }, + }, + "gemini-2.5-pro": { + id: "gemini-2.5-pro", + name: "Gemini 2.5 Pro", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-03-20", + last_updated: "2025-06-05", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.31 }, + limit: { context: 1048576, output: 65536 }, + }, + "grok-4-1-fast-non-reasoning": { + id: "grok-4-1-fast-non-reasoning", + name: "Grok 4.1 Fast (Non-Reasoning)", + family: "grok", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-11", + release_date: "2025-11-25", + last_updated: "2025-11-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5, cache_read: 0.05 }, + limit: { context: 2000000, output: 128000 }, + }, + "gpt-5-4-nano": { + id: "gpt-5-4-nano", + name: "GPT-5.4 Nano", + family: "gpt-nano", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-05-30", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 1.25, cache_read: 0.02 }, + limit: { context: 400000, output: 128000 }, + }, + "gemini-2.5-flash": { + id: "gemini-2.5-flash", + name: "Gemini 2.5 Flash", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-07-17", + last_updated: "2025-07-17", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 2.5, cache_read: 0.075 }, + limit: { context: 1048576, output: 65536 }, + }, + "grok-code-fast-1": { + id: "grok-code-fast-1", + name: "Grok 4.1 Fast (Reasoning)", + family: "grok", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2023-10", + release_date: "2025-08-28", + last_updated: "2025-08-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 1.5, cache_read: 0.02 }, + limit: { context: 256000, output: 128000 }, + }, + "gpt-5-5": { + id: "gpt-5-5", + name: "GPT-5.5", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-05", + last_updated: "2026-03-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 15, cache_read: 0.25 }, + limit: { context: 272000, output: 128000 }, + }, + "grok-4-3": { + id: "grok-4-3", + name: "Grok 4.3", + family: "grok", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-11", + release_date: "2026-04-30", + last_updated: "2026-04-30", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 2.5, cache_read: 0.2 }, + limit: { context: 1000000, output: 128000 }, + }, + "gpt-5-4-mini": { + id: "gpt-5-4-mini", + name: "GPT-5.4 Mini", + family: "gpt-mini", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-17", + last_updated: "2026-03-17", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.75, output: 4.5, cache_read: 0.075 }, + limit: { context: 400000, output: 128000 }, + }, + "claude-opus-4-6": { + id: "claude-opus-4-6", + name: "Claude Opus 4.6", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-05-31", + release_date: "2026-02-05", + last_updated: "2026-02-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 200000, output: 128000 }, + }, + "deepseek-v4-pro": { + id: "deepseek-v4-pro", + name: "DeepSeek v4 Pro", + family: "deepseek", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2026-01", + release_date: "2026-04-24", + last_updated: "2026-04-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.74, output: 3.48, cache_read: 0.14 }, + limit: { context: 128000, output: 8192 }, + }, + "gpt-oss-20b": { + id: "gpt-oss-20b", + name: "GPT OSS 20B", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "1970-01-01", + last_updated: "1970-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.07, output: 0.2 }, + limit: { context: 131072, output: 32768 }, + }, + "qwen-3-6-plus": { + id: "qwen-3-6-plus", + name: "Qwen 3.6 Plus", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-02", + last_updated: "2026-04-03", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 3, cache_read: 0.1 }, + limit: { context: 1000000, output: 64000 }, + }, + "minimax-m2-7": { + id: "minimax-m2-7", + name: "MiniMax-M2.7", + family: "minimax", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-09", + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 1.2, cache_read: 0.06 }, + limit: { context: 192000, output: 8192 }, + }, + "minimax-m2-5": { + id: "minimax-m2-5", + name: "MiniMax-M2.5", + family: "minimax", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-09", + release_date: "2025-01-15", + last_updated: "2025-02-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 1.2, cache_read: 0.03 }, + limit: { context: 192000, output: 8192 }, + }, + "gpt-4o": { + id: "gpt-4o", + name: "GPT-4o", + 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"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 10, cache_read: 1.25 }, + limit: { context: 128000, output: 16384 }, + }, + "gpt-oss-120b": { + id: "gpt-oss-120b", + name: "GPT OSS 120B", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "1970-01-01", + last_updated: "1970-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 131072, output: 32768 }, + }, + "gemini-3-1-pro-preview": { + id: "gemini-3-1-pro-preview", + name: "Gemini 3.1 Pro Preview", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2026-01", + release_date: "2026-02-18", + last_updated: "2026-02-18", + modalities: { input: ["text", "image", "video", "audio", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 12, cache_read: 0.2 }, + limit: { context: 1000000, output: 64000 }, + }, + "kimi-k2-6": { + id: "kimi-k2-6", + name: "Kimi-K2.6", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "1970-01-01", + last_updated: "1970-01-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.95, output: 4, cache_read: 0.16 }, + limit: { context: 256000, output: 128000 }, + }, + "gpt-5-3-codex": { + id: "gpt-5-3-codex", + name: "GPT-5.3 Codex", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2026-01-31", + release_date: "2026-02-15", + last_updated: "2026-02-15", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 400000, output: 128000 }, + }, + }, + }, + "zhipuai-coding-plan": { + id: "zhipuai-coding-plan", + env: ["ZHIPU_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://open.bigmodel.cn/api/coding/paas/v4", + name: "Zhipu AI Coding Plan", + doc: "https://docs.bigmodel.cn/cn/coding-plan/overview", + models: { + "glm-5v-turbo": { + id: "glm-5v-turbo", + name: "GLM-5V-Turbo", + family: "glm", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-04-01", + last_updated: "2026-04-01", + modalities: { input: ["text", "image", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 200000, output: 131072 }, + }, + "glm-5.1": { + id: "glm-5.1", + name: "GLM-5.1", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-03-27", + last_updated: "2026-03-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 200000, output: 131072 }, + }, + "glm-5-turbo": { + id: "glm-5-turbo", + name: "GLM-5-Turbo", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-03-16", + last_updated: "2026-03-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 200000, output: 131072 }, + }, + "glm-4.5-air": { + id: "glm-4.5-air", + name: "GLM-4.5-Air", + family: "glm-air", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-28", + last_updated: "2025-07-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 131072, output: 98304 }, + }, + "glm-4.7": { + id: "glm-4.7", + name: "GLM-4.7", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-04", + release_date: "2025-12-22", + last_updated: "2025-12-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 204800, output: 131072 }, + }, + }, + }, + "alibaba-coding-plan": { + id: "alibaba-coding-plan", + env: ["ALIBABA_CODING_PLAN_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://coding-intl.dashscope.aliyuncs.com/v1", + name: "Alibaba Coding Plan", + doc: "https://www.alibabacloud.com/help/en/model-studio/coding-plan", + models: { + "qwen3-coder-plus": { + id: "qwen3-coder-plus", + name: "Qwen3 Coder Plus", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-23", + last_updated: "2025-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 1000000, output: 65536 }, + }, + "kimi-k2.5": { + id: "kimi-k2.5", + name: "Kimi K2.5", + family: "kimi", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-01", + release_date: "2026-01-27", + last_updated: "2026-01-27", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 262144, output: 32768 }, + }, + "glm-4.7": { + id: "glm-4.7", + name: "GLM-4.7", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-04", + release_date: "2025-12-22", + last_updated: "2025-12-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 202752, output: 16384 }, + }, + "glm-5": { + id: "glm-5", + name: "GLM-5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-02-11", + last_updated: "2026-02-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 202752, output: 16384 }, + }, + "MiniMax-M2.5": { + id: "MiniMax-M2.5", + name: "MiniMax-M2.5", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 196608, input: 196601, output: 24576 }, + }, + "qwen3.6-plus": { + id: "qwen3.6-plus", + name: "Qwen3.6 Plus", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-04-02", + last_updated: "2026-04-02", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 1000000, output: 65536 }, + }, + "qwen3-max-2026-01-23": { + id: "qwen3-max-2026-01-23", + name: "Qwen3 Max", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-01-23", + last_updated: "2026-01-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 262144, output: 32768 }, + }, + "qwen3-coder-next": { + id: "qwen3-coder-next", + name: "Qwen3 Coder Next", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-02-03", + last_updated: "2026-02-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 262144, output: 65536 }, + }, + "qwen3.5-plus": { + id: "qwen3.5-plus", + name: "Qwen3.5 Plus", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-02-16", + last_updated: "2026-02-16", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 1000000, output: 65536 }, + }, + }, + }, + venice: { + id: "venice", + env: ["VENICE_API_KEY"], + npm: "venice-ai-sdk-provider", + name: "Venice AI", + doc: "https://docs.venice.ai", + models: { + "openai-gpt-4o-mini-2024-07-18": { + id: "openai-gpt-4o-mini-2024-07-18", + name: "GPT-4o Mini", + family: "gpt-mini", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-02-28", + last_updated: "2026-03-06", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1875, output: 0.75, cache_read: 0.09375 }, + limit: { context: 128000, output: 16384 }, + }, + "qwen3-next-80b": { + id: "qwen3-next-80b", + name: "Qwen 3 Next 80b", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-04-29", + last_updated: "2026-03-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.35, output: 1.9 }, + limit: { context: 256000, output: 16384 }, + }, + "grok-4-20-multi-agent": { + id: "grok-4-20-multi-agent", + name: "Grok 4.20 Multi-Agent", + family: "grok", + attachment: true, + reasoning: true, + tool_call: false, + structured_output: true, + temperature: true, + release_date: "2026-03-12", + last_updated: "2026-05-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { + input: 1.42, + output: 2.83, + cache_read: 0.23, + context_over_200k: { input: 2.83, output: 5.67, cache_read: 0.45 }, + }, + limit: { context: 2000000, output: 128000 }, + }, + "qwen3-235b-a22b-instruct-2507": { + id: "qwen3-235b-a22b-instruct-2507", + name: "Qwen 3 235B A22B Instruct 2507", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-04-29", + last_updated: "2026-03-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.75 }, + limit: { context: 128000, output: 16384 }, + }, + "z-ai-glm-5v-turbo": { + id: "z-ai-glm-5v-turbo", + name: "GLM 5V Turbo", + family: "glmv", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-04-01", + last_updated: "2026-04-12", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.5, output: 5, cache_read: 0.3 }, + limit: { context: 200000, output: 32768 }, + }, + "gemma-4-uncensored": { + id: "gemma-4-uncensored", + name: "Gemma 4 Uncensored", + family: "gemma", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-04-13", + last_updated: "2026-04-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1625, output: 0.5 }, + limit: { context: 256000, output: 8192 }, + }, + "grok-41-fast": { + id: "grok-41-fast", + name: "Grok 4.1 Fast", + family: "grok", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-12-01", + last_updated: "2026-04-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.23, output: 0.57, cache_read: 0.06 }, + limit: { context: 1000000, output: 30000 }, + }, + "claude-sonnet-4-6": { + id: "claude-sonnet-4-6", + name: "Claude Sonnet 4.6", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-08-31", + release_date: "2026-02-17", + last_updated: "2026-03-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 3.6, output: 18, cache_read: 0.36, cache_write: 4.5 }, + limit: { context: 1000000, output: 64000 }, + }, + "nvidia-nemotron-cascade-2-30b-a3b": { + id: "nvidia-nemotron-cascade-2-30b-a3b", + name: "Nemotron Cascade 2 30B A3B", + family: "nemotron", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-03-24", + last_updated: "2026-04-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.14, output: 0.8 }, + limit: { context: 256000, output: 32768 }, + }, + "gemini-3-flash-preview": { + id: "gemini-3-flash-preview", + name: "Gemini 3 Flash Preview", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-12-19", + last_updated: "2026-03-12", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.7, output: 3.75, cache_read: 0.07 }, + limit: { context: 256000, output: 65536 }, + }, + "grok-4-20": { + id: "grok-4-20", + name: "Grok 4.20", + family: "grok", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-03-12", + last_updated: "2026-05-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { + input: 1.42, + output: 2.83, + cache_read: 0.23, + context_over_200k: { input: 2.83, output: 5.67, cache_read: 0.45 }, + }, + limit: { context: 2000000, output: 128000 }, + }, + "google-gemma-4-26b-a4b-it": { + id: "google-gemma-4-26b-a4b-it", + name: "Google Gemma 4 26B A4B Instruct", + family: "gemma", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-04-02", + last_updated: "2026-04-12", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1625, output: 0.5 }, + limit: { context: 256000, output: 8192 }, + }, + "claude-opus-4-7": { + id: "claude-opus-4-7", + name: "Claude Opus 4.7", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + release_date: "2026-04-16", + last_updated: "2026-04-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 6, output: 30, cache_read: 0.6, cache_write: 7.5 }, + limit: { context: 1000000, output: 128000 }, + }, + "qwen3-coder-480b-a35b-instruct-turbo": { + id: "qwen3-coder-480b-a35b-instruct-turbo", + name: "Qwen 3 Coder 480B Turbo", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01-27", + last_updated: "2026-02-26", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.35, output: 1.5, cache_read: 0.04 }, + limit: { context: 256000, output: 65536 }, + }, + "qwen3-5-397b-a17b": { + id: "qwen3-5-397b-a17b", + name: "Qwen 3.5 397B", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-02-16", + last_updated: "2026-04-16", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.75, output: 4.5 }, + limit: { context: 128000, output: 32768 }, + }, + "zai-org-glm-4.7": { + id: "zai-org-glm-4.7", + name: "GLM 4.7", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-12-24", + last_updated: "2026-03-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.55, output: 2.65, cache_read: 0.11 }, + limit: { context: 198000, output: 16384 }, + }, + "openai-gpt-54": { + id: "openai-gpt-54", + name: "GPT-5.4", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-03-05", + last_updated: "2026-03-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 3.13, output: 18.8, cache_read: 0.313 }, + limit: { context: 1000000, output: 131072 }, + }, + "zai-org-glm-4.7-flash": { + id: "zai-org-glm-4.7-flash", + name: "GLM 4.7 Flash", + family: "glm-flash", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01-29", + last_updated: "2026-03-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.125, output: 0.5 }, + limit: { context: 128000, output: 16384 }, + }, + "nvidia-nemotron-3-nano-30b-a3b": { + id: "nvidia-nemotron-3-nano-30b-a3b", + name: "NVIDIA Nemotron 3 Nano 30B", + family: "nemotron", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01-27", + last_updated: "2026-03-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.075, output: 0.3 }, + limit: { context: 128000, output: 16384 }, + }, + "qwen3-vl-235b-a22b": { + id: "qwen3-vl-235b-a22b", + name: "Qwen3 VL 235B", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01-16", + last_updated: "2026-03-12", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.25, output: 1.5 }, + limit: { context: 256000, output: 16384 }, + }, + "openai-gpt-53-codex": { + id: "openai-gpt-53-codex", + name: "GPT-5.3 Codex", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-02-24", + last_updated: "2026-03-12", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2.19, output: 17.5, cache_read: 0.219 }, + limit: { context: 400000, output: 128000 }, + }, + "venice-uncensored-1-2": { + id: "venice-uncensored-1-2", + name: "Venice Uncensored 1.2", + family: "venice", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-04-01", + last_updated: "2026-04-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.9 }, + limit: { context: 128000, output: 8192 }, + }, + "openai-gpt-52": { + id: "openai-gpt-52", + name: "GPT-5.2", + family: "gpt", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-08-31", + release_date: "2025-12-13", + last_updated: "2026-03-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2.19, output: 17.5, cache_read: 0.219 }, + limit: { context: 256000, output: 65536 }, + }, + "mistral-small-3-2-24b-instruct": { + id: "mistral-small-3-2-24b-instruct", + name: "Mistral Small 3.2 24B Instruct", + family: "mistral-small", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01-15", + last_updated: "2026-03-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.09375, output: 0.25 }, + limit: { context: 256000, output: 16384 }, + }, + "minimax-m27": { + id: "minimax-m27", + name: "MiniMax M2.7", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-18", + last_updated: "2026-04-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.375, output: 1.5, cache_read: 0.075 }, + limit: { context: 198000, output: 32768 }, + }, + "qwen3-235b-a22b-thinking-2507": { + id: "qwen3-235b-a22b-thinking-2507", + name: "Qwen 3 235B A22B Thinking 2507", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-04-29", + last_updated: "2026-03-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.45, output: 3.5 }, + limit: { context: 128000, output: 16384 }, + }, + "qwen3-5-35b-a3b": { + id: "qwen3-5-35b-a3b", + name: "Qwen 3.5 35B A3B", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-02-25", + last_updated: "2026-04-16", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3125, output: 1.25, cache_read: 0.15625 }, + limit: { context: 256000, output: 65536 }, + }, + "mercury-2": { + id: "mercury-2", + name: "Mercury 2", + family: "mercury", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-02-20", + last_updated: "2026-04-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3125, output: 0.9375, cache_read: 0.03125 }, + limit: { context: 128000, output: 50000 }, + }, + "google-gemma-3-27b-it": { + id: "google-gemma-3-27b-it", + name: "Google Gemma 3 27B Instruct", + family: "gemma", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-11-04", + last_updated: "2026-03-12", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.12, output: 0.2 }, + limit: { context: 198000, output: 16384 }, + }, + "olafangensan-glm-4.7-flash-heretic": { + id: "olafangensan-glm-4.7-flash-heretic", + name: "GLM 4.7 Flash Heretic", + family: "glm-flash", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-02-04", + last_updated: "2026-03-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.14, output: 0.8 }, + limit: { context: 200000, output: 24000 }, + }, + "openai-gpt-55-pro": { + id: "openai-gpt-55-pro", + name: "GPT-5.5 Pro", + family: "gpt-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-04-24", + last_updated: "2026-04-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 37.5, output: 225 }, + limit: { context: 1000000, output: 128000 }, + }, + "openai-gpt-52-codex": { + id: "openai-gpt-52-codex", + name: "GPT-5.2 Codex", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-08", + release_date: "2025-01-15", + last_updated: "2026-03-12", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2.19, output: 17.5, cache_read: 0.219 }, + limit: { context: 256000, output: 65536 }, + }, + "venice-uncensored-role-play": { + id: "venice-uncensored-role-play", + name: "Venice Role Play Uncensored", + family: "venice", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-02-20", + last_updated: "2026-03-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.5, output: 2 }, + limit: { context: 128000, output: 4096 }, + }, + "zai-org-glm-5": { + id: "zai-org-glm-5", + name: "GLM 5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-02-11", + last_updated: "2026-03-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 3.2, cache_read: 0.2 }, + limit: { context: 198000, output: 32000 }, + }, + "zai-org-glm-4.6": { + id: "zai-org-glm-4.6", + name: "GLM 4.6", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2024-04-01", + last_updated: "2026-04-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.85, output: 2.75, cache_read: 0.3 }, + limit: { context: 198000, output: 16384 }, + }, + "grok-4-3": { + id: "grok-4-3", + name: "Grok 4.3", + family: "grok", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-04-18", + last_updated: "2026-05-04", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { + input: 1.42, + output: 2.83, + cache_read: 0.23, + context_over_200k: { input: 2.83, output: 5.67, cache_read: 0.45 }, + }, + limit: { context: 1000000, output: 32000 }, + }, + "mistral-small-2603": { + id: "mistral-small-2603", + name: "Mistral Small 4", + family: "mistral-small", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-03-16", + last_updated: "2026-04-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1875, output: 0.75 }, + limit: { context: 256000, output: 65536 }, + }, + "openai-gpt-oss-120b": { + id: "openai-gpt-oss-120b", + name: "OpenAI GPT OSS 120B", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-11-06", + last_updated: "2026-05-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.07, output: 0.3 }, + limit: { context: 128000, output: 16384 }, + }, + "claude-opus-4-5": { + id: "claude-opus-4-5", + name: "Claude Opus 4.5", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-12-06", + last_updated: "2026-04-12", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 6, output: 30, cache_read: 0.6, cache_write: 7.5 }, + limit: { context: 198000, output: 32768 }, + }, + "qwen3-5-9b": { + id: "qwen3-5-9b", + name: "Qwen 3.5 9B", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-03-05", + last_updated: "2026-04-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.15 }, + limit: { context: 256000, output: 32768 }, + }, + "deepseek-v4-flash": { + id: "deepseek-v4-flash", + name: "DeepSeek V4 Flash", + family: "deepseek-flash", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-04-24", + last_updated: "2026-04-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.17, output: 0.35, cache_read: 0.028 }, + limit: { context: 1000000, output: 32768 }, + }, + "openai-gpt-54-pro": { + id: "openai-gpt-54-pro", + name: "GPT-5.4 Pro", + family: "gpt-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-03-05", + last_updated: "2026-03-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 37.5, output: 225, context_over_200k: { input: 75, output: 337.5 } }, + limit: { context: 1000000, output: 128000 }, + }, + "openai-gpt-54-mini": { + id: "openai-gpt-54-mini", + name: "GPT-5.4 Mini", + family: "gpt-mini", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-03-27", + last_updated: "2026-03-31", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.9375, output: 5.625, cache_read: 0.09375 }, + limit: { context: 400000, output: 128000 }, + }, + "minimax-m25": { + id: "minimax-m25", + name: "MiniMax M2.5", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-02-12", + last_updated: "2026-04-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.34, output: 1.19, cache_read: 0.04 }, + limit: { context: 198000, output: 32768 }, + }, + "zai-org-glm-5-1": { + id: "zai-org-glm-5-1", + name: "GLM 5.1", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-04-07", + last_updated: "2026-04-08", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.75, output: 5.5, cache_read: 0.325 }, + limit: { context: 200000, output: 24000 }, + }, + "openai-gpt-55": { + id: "openai-gpt-55", + name: "GPT-5.5", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-04-23", + last_updated: "2026-04-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { + input: 6.25, + output: 37.5, + cache_read: 0.625, + context_over_200k: { input: 12.5, output: 56.25, cache_read: 1.25 }, + }, + limit: { context: 1000000, output: 131072 }, + }, + "qwen3-6-27b": { + id: "qwen3-6-27b", + name: "Qwen 3.6 27B", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-04-24", + last_updated: "2026-04-29", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.325, output: 3.25 }, + limit: { context: 256000, output: 65536 }, + }, + "claude-opus-4-6": { + id: "claude-opus-4-6", + name: "Claude Opus 4.6", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-05-31", + release_date: "2026-02-05", + last_updated: "2026-03-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 6, output: 30, cache_read: 0.6, cache_write: 7.5 }, + limit: { context: 1000000, output: 128000 }, + }, + "deepseek-v4-pro": { + id: "deepseek-v4-pro", + name: "DeepSeek V4 Pro", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-04-24", + last_updated: "2026-04-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.73, output: 3.796, cache_read: 0.33 }, + limit: { context: 1000000, output: 32768 }, + }, + "deepseek-v3.2": { + id: "deepseek-v3.2", + name: "DeepSeek V3.2", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-10", + release_date: "2025-12-04", + last_updated: "2026-03-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.33, output: 0.48, cache_read: 0.16 }, + limit: { context: 160000, output: 32768 }, + }, + "qwen-3-6-plus": { + id: "qwen-3-6-plus", + name: "Qwen 3.6 Plus Uncensored", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-04-06", + last_updated: "2026-04-12", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { + input: 0.625, + output: 3.75, + cache_read: 0.0625, + cache_write: 0.78, + context_over_200k: { input: 2.5, output: 7.5, cache_read: 0.0625, cache_write: 0.78 }, + }, + limit: { context: 1000000, output: 65536 }, + }, + "aion-labs-aion-2-0": { + id: "aion-labs-aion-2-0", + name: "Aion 2.0", + family: "o", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2026-03-24", + last_updated: "2026-04-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 2, cache_read: 0.25 }, + limit: { context: 128000, output: 32768 }, + }, + "claude-sonnet-4-5": { + id: "claude-sonnet-4-5", + name: "Claude Sonnet 4.5", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-01-15", + last_updated: "2026-04-12", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 3.75, output: 18.75, cache_read: 0.375, cache_write: 4.69 }, + limit: { context: 198000, output: 64000 }, + }, + "openai-gpt-4o-2024-11-20": { + id: "openai-gpt-4o-2024-11-20", + name: "GPT-4o", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-02-28", + last_updated: "2026-03-06", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 3.125, output: 12.5 }, + limit: { context: 128000, output: 16384 }, + }, + "llama-3.3-70b": { + id: "llama-3.3-70b", + name: "Llama 3.3 70B", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2025-04-06", + last_updated: "2026-03-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.7, output: 2.8 }, + limit: { context: 128000, output: 4096 }, + }, + "kimi-k2-5": { + id: "kimi-k2-5", + name: "Kimi K2.5", + family: "kimi", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2024-04", + release_date: "2026-01-27", + last_updated: "2026-04-30", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.56, output: 3.5, cache_read: 0.22 }, + limit: { context: 256000, output: 65536 }, + }, + "llama-3.2-3b": { + id: "llama-3.2-3b", + name: "Llama 3.2 3B", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-10-03", + last_updated: "2026-03-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 128000, output: 4096 }, + }, + "arcee-trinity-large-thinking": { + id: "arcee-trinity-large-thinking", + name: "Trinity Large Thinking", + family: "trinity", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-04-02", + last_updated: "2026-04-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3125, output: 1.125, cache_read: 0.075 }, + limit: { context: 256000, output: 65536 }, + }, + "hermes-3-llama-3.1-405b": { + id: "hermes-3-llama-3.1-405b", + name: "Hermes 3 Llama 3.1 405b", + family: "hermes", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-04", + release_date: "2025-09-25", + last_updated: "2026-03-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.1, output: 3 }, + limit: { context: 128000, output: 16384 }, + }, + "gemini-3-1-pro-preview": { + id: "gemini-3-1-pro-preview", + name: "Gemini 3.1 Pro Preview", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-02-19", + last_updated: "2026-03-12", + modalities: { input: ["text", "image", "audio", "video"], output: ["text"] }, + open_weights: false, + cost: { + input: 2.5, + output: 15, + cache_read: 0.5, + cache_write: 0.5, + context_over_200k: { input: 5, output: 22.5, cache_read: 0.5 }, + }, + limit: { context: 1000000, output: 32768 }, + }, + "kimi-k2-6": { + id: "kimi-k2-6", + name: "Kimi K2.6", + family: "kimi", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-04-20", + last_updated: "2026-04-30", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.85, output: 4.655, cache_read: 0.22 }, + limit: { context: 256000, output: 65536 }, + }, + "claude-opus-4-6-fast": { + id: "claude-opus-4-6-fast", + name: "Claude Opus 4.6 Fast", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-05-31", + release_date: "2026-04-08", + last_updated: "2026-04-08", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 36, output: 180, cache_read: 3.6, cache_write: 45 }, + limit: { context: 1000000, output: 128000 }, + }, + "z-ai-glm-5-turbo": { + id: "z-ai-glm-5-turbo", + name: "GLM 5 Turbo", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-03-15", + last_updated: "2026-04-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.2, output: 4, cache_read: 0.24 }, + limit: { context: 200000, output: 32768 }, + }, + "google-gemma-4-31b-it": { + id: "google-gemma-4-31b-it", + name: "Google Gemma 4 31B Instruct", + family: "gemma", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-04-03", + last_updated: "2026-04-12", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.175, output: 0.5 }, + limit: { context: 256000, output: 8192 }, + }, + }, + }, + aihubmix: { + id: "aihubmix", + env: ["AIHUBMIX_API_KEY"], + npm: "@aihubmix/ai-sdk-provider", + name: "AIHubMix", + doc: "https://docs.aihubmix.com", + models: { + "minimax-m2.7": { + id: "minimax-m2.7", + name: "MiniMax-M2.7", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2958, output: 1.1832, cache_read: 0.05916 }, + limit: { context: 200000, output: 128000 }, + }, + "coding-glm-5.1-free": { + id: "coding-glm-5.1-free", + name: "Coding GLM 5.1 (free)", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-04-11", + last_updated: "2026-04-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0, cache_read: 0 }, + limit: { context: 204800, output: 128000 }, + }, + "gemini-3.1-pro-preview-customtools": { + id: "gemini-3.1-pro-preview-customtools", + name: "Gemini 3.1 Pro Preview Custom Tools", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-02-19", + last_updated: "2026-02-19", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 12, cache_read: 0.2, context_over_200k: { input: 4, output: 18, cache_read: 0.4 } }, + limit: { context: 1048576, output: 65536 }, + }, + "kimi-k2.5": { + id: "kimi-k2.5", + name: "Kimi K2.5", + family: "kimi-k2.5", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: false, + knowledge: "2025-01", + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 3, cache_read: 0.105 }, + limit: { context: 256000, output: 0 }, + }, + "glm-5v-turbo": { + id: "glm-5v-turbo", + name: "GLM 5 Vision Turbo", + family: "glm", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-05-09", + last_updated: "2026-05-09", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.7042, output: 3.09848, cache_read: 0.169008 }, + limit: { context: 200000, output: 128000 }, + }, + "grok-4.3": { + id: "grok-4.3", + name: "Grok 4.3", + family: "grok", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-05-01", + last_updated: "2026-05-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { + input: 1.25, + output: 2.5, + cache_read: 0.2, + context_over_200k: { input: 2.5, output: 5, cache_read: 0.4 }, + }, + limit: { context: 1000000, output: 1000000 }, + }, + "coding-minimax-m2.7-highspeed": { + id: "coding-minimax-m2.7-highspeed", + name: "Coding MiniMax M2.7 Highspeed", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.2 }, + limit: { context: 204800, output: 13100 }, + }, + "claude-sonnet-4-6": { + id: "claude-sonnet-4-6", + name: "Claude Sonnet 4.6", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-08-31", + release_date: "2026-02-17", + last_updated: "2026-02-17", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 3, + output: 15, + cache_read: 0.3, + cache_write: 3.75, + context_over_200k: { input: 6, output: 22.5, cache_read: 0.6, cache_write: 7.5 }, + }, + limit: { context: 200000, output: 64000 }, + }, + "gemini-3.1-pro-preview": { + id: "gemini-3.1-pro-preview", + name: "Gemini 3.1 Pro Preview", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-02-19", + last_updated: "2026-02-19", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 12, cache_read: 0.2 }, + limit: { context: 1048576, output: 65536 }, + }, + "coding-glm-5.1": { + id: "coding-glm-5.1", + name: "Coding-GLM-5.1", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-04-11", + last_updated: "2026-04-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.06, output: 0.22 }, + limit: { context: 200000, output: 128000 }, + }, + "gemini-3-flash-preview": { + id: "gemini-3-flash-preview", + name: "Gemini 3 Flash Preview", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-12-17", + last_updated: "2025-12-17", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 3, cache_read: 0.05 }, + limit: { context: 1048576, output: 65536 }, + }, + "gpt-5.5": { + id: "gpt-5.5", + name: "GPT-5.5", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-12-01", + release_date: "2026-04-23", + last_updated: "2026-04-23", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 30, cache_read: 0.5 }, + limit: { context: 1050000, output: 128000 }, + }, + "claude-opus-4-7": { + id: "claude-opus-4-7", + name: "Claude Opus 4.7", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2026-01-31", + release_date: "2026-04-16", + last_updated: "2026-04-16", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 1000000, output: 128000 }, + }, + "deepseek-v4-flash-think": { + id: "deepseek-v4-flash-think", + name: "DeepSeek V4 Flash Think", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-05", + release_date: "2026-04-24", + last_updated: "2026-04-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.154, output: 0.308, cache_read: 0.0308 }, + limit: { context: 1000000, output: 384000 }, + }, + "gpt-5.3-codex": { + id: "gpt-5.3-codex", + name: "GPT-5.3 Codex", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-02-05", + last_updated: "2026-02-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "gemini-2.5-pro": { + id: "gemini-2.5-pro", + name: "Gemini 2.5 Pro", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-03-20", + last_updated: "2025-06-05", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 1048576, output: 65536 }, + }, + "gpt-5.2": { + id: "gpt-5.2", + name: "GPT-5.2", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2025-12-11", + last_updated: "2025-12-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 400000, output: 128000 }, + }, + "qwen3.6-plus": { + id: "qwen3.6-plus", + name: "Qwen3.6 Plus", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-05-09", + last_updated: "2026-05-09", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.282, output: 1.692, cache_read: 0.0282, cache_write: 0.3525 }, + limit: { context: 991000, output: 64000 }, + }, + "gpt-5.4-mini": { + id: "gpt-5.4-mini", + name: "GPT-5.4-Mini", + family: "gpt-mini", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: false, + release_date: "2026-03-11", + last_updated: "2026-03-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.75, output: 4.5, cache_read: 0.075 }, + limit: { context: 400000, output: 128000 }, + }, + "glm-5.1": { + id: "glm-5.1", + name: "GLM-5.1", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-03-27", + last_updated: "2026-03-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.845, output: 3.38, cache_read: 0.183112 }, + limit: { context: 200000, output: 128000 }, + }, + "o4-mini": { + id: "o4-mini", + name: "o4-mini", + family: "o-mini", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-05", + release_date: "2025-04-16", + last_updated: "2025-04-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 4.4, cache_read: 0.275 }, + limit: { context: 200000, output: 100000 }, + }, + "gpt-5.2-codex": { + id: "gpt-5.2-codex", + name: "GPT-5.2-Codex", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + knowledge: "2025-08-31", + release_date: "2026-01-14", + last_updated: "2026-01-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 400000, output: 128000 }, + }, + "gemini-2.5-flash": { + id: "gemini-2.5-flash", + name: "Gemini 2.5 Flash", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-03-20", + last_updated: "2025-06-05", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 2.499, cache_read: 0.03 }, + limit: { context: 1048576, output: 65536 }, + }, + "gpt-5.1-codex-mini": { + id: "gpt-5.1-codex-mini", + name: "GPT-5.1 Codex mini", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 2, cache_read: 0.025 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "gemini-3.1-flash-lite": { + id: "gemini-3.1-flash-lite", + name: "Gemini 3.1 Flash Lite", + family: "gemini-flash-lite", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-03-03", + last_updated: "2026-03-03", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 1.5, cache_read: 0.25 }, + limit: { context: 1048576, output: 65536 }, + }, + "gpt-5.1": { + id: "gpt-5.1", + name: "GPT-5.1", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-11", + release_date: "2025-11-15", + last_updated: "2025-11-15", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 400000, output: 128000 }, + }, + "claude-opus-4-6-think": { + id: "claude-opus-4-6-think", + name: "Claude Opus 4.6", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-05-31", + release_date: "2026-02-05", + last_updated: "2026-03-13", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 200000, output: 32000 }, + }, + "coding-minimax-m2.7-free": { + id: "coding-minimax-m2.7-free", + name: "Coding-MiniMax-M2.7-Free", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 204800, output: 13100 }, + }, + "deepseek-v4-flash": { + id: "deepseek-v4-flash", + name: "DeepSeek V4 Flash", + family: "deepseek-flash", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-05", + release_date: "2026-04-24", + last_updated: "2026-04-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.154, output: 0.308, cache_read: 0.0308 }, + limit: { context: 1000000, output: 384000 }, + }, + "kimi-k2.6": { + id: "kimi-k2.6", + name: "Kimi K2.6", + family: "kimi-k2.6", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-04-21", + last_updated: "2026-04-21", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.95, output: 3.9995, cache_read: 0.160835 }, + limit: { context: 262144, output: 262144 }, + }, + "gpt-5.4": { + id: "gpt-5.4", + name: "GPT-5.4", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + release_date: "2026-03-11", + last_updated: "2026-03-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 15, cache_read: 0.25 }, + limit: { context: 400000, output: 128000 }, + }, + "claude-opus-4-6": { + id: "claude-opus-4-6", + name: "Claude Opus 4.6", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-05-31", + release_date: "2026-02-05", + last_updated: "2026-03-13", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 1000000, output: 128000 }, + }, + "deepseek-v4-pro": { + id: "deepseek-v4-pro", + name: "DeepSeek V4 Pro", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-05", + release_date: "2026-04-24", + last_updated: "2026-04-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.478, output: 0.956, cache_read: 0.004302 }, + limit: { context: 1000000, output: 384000 }, + }, + "claude-opus-4-7-think": { + id: "claude-opus-4-7-think", + name: "Claude Opus 4.7 Thinking", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2026-01-31", + release_date: "2026-04-16", + last_updated: "2026-04-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 200000, output: 32000 }, + }, + "coding-minimax-m2.7": { + id: "coding-minimax-m2.7", + name: "Coding MiniMax M2.7", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.2 }, + limit: { context: 204800, output: 13100 }, + }, + "qwen3.6-max-preview": { + id: "qwen3.6-max-preview", + name: "Qwen3.6 Max Preview", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-05-09", + last_updated: "2026-05-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.268, output: 7.608, cache_read: 0.1268, cache_write: 1.585 }, + limit: { context: 240000, output: 64000 }, + }, + "gpt-4.1": { + id: "gpt-4.1", + name: "GPT-4.1", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-04-14", + last_updated: "2025-04-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 8, cache_read: 0.5 }, + limit: { context: 1047576, output: 32768 }, + }, + "gpt-4.1-mini": { + id: "gpt-4.1-mini", + name: "GPT-4.1 mini", + family: "gpt-mini", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-04-14", + last_updated: "2025-04-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 1.6, cache_read: 0.1 }, + limit: { context: 1047576, output: 32768 }, + }, + "gpt-5.1-codex": { + id: "gpt-5.1-codex", + name: "GPT-5.1 Codex", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "claude-sonnet-4-6-think": { + id: "claude-sonnet-4-6-think", + name: "Claude Sonnet 4.6 Think", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-08-31", + release_date: "2026-02-17", + last_updated: "2026-02-17", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 3, + output: 15, + cache_read: 0.3, + cache_write: 3.75, + context_over_200k: { input: 6, output: 22.5, cache_read: 0.6, cache_write: 7.5 }, + }, + limit: { context: 200000, output: 64000 }, + }, + "qwen3.6-flash": { + id: "qwen3.6-flash", + name: "Qwen3.6 Flash", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-04-02", + last_updated: "2026-04-02", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.169, output: 1.014, cache_read: 0.0169, cache_write: 0.21125 }, + limit: { context: 991000, output: 64000 }, + }, + }, + }, + cerebras: { + id: "cerebras", + env: ["CEREBRAS_API_KEY"], + npm: "@ai-sdk/cerebras", + name: "Cerebras", + doc: "https://inference-docs.cerebras.ai/models/overview", + models: { + "llama3.1-8b": { + id: "llama3.1-8b", + name: "Llama 3.1 8B", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.1 }, + limit: { context: 32000, output: 8000 }, + }, + "qwen-3-235b-a22b-instruct-2507": { + id: "qwen-3-235b-a22b-instruct-2507", + name: "Qwen 3 235B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-22", + last_updated: "2025-07-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 1.2 }, + limit: { context: 131000, output: 32000 }, + }, + "zai-glm-4.7": { + id: "zai-glm-4.7", + name: "Z.AI GLM-4.7", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2026-01-10", + last_updated: "2026-01-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 2.25, output: 2.75, cache_read: 0, cache_write: 0 }, + limit: { context: 131072, output: 40000 }, + }, + "gpt-oss-120b": { + id: "gpt-oss-120b", + name: "GPT OSS 120B", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.25, output: 0.69 }, + limit: { context: 131072, output: 32768 }, + }, + }, + }, + lmstudio: { + id: "lmstudio", + env: ["LMSTUDIO_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "http://127.0.0.1:1234/v1", + name: "LMStudio", + doc: "https://lmstudio.ai/models", + models: { + "openai/gpt-oss-20b": { + id: "openai/gpt-oss-20b", + name: "GPT OSS 20B", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 131072, output: 32768 }, + }, + "qwen/qwen3-coder-30b": { + id: "qwen/qwen3-coder-30b", + name: "Qwen3 Coder 30B", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-23", + last_updated: "2025-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 262144, output: 65536 }, + }, + "qwen/qwen3-30b-a3b-2507": { + id: "qwen/qwen3-30b-a3b-2507", + name: "Qwen3 30B A3B 2507", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-30", + last_updated: "2025-07-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 262144, output: 16384 }, + }, + }, + }, + lucidquery: { + id: "lucidquery", + env: ["LUCIDQUERY_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://lucidquery.com/api/v1", + name: "LucidQuery AI", + doc: "https://lucidquery.com/api/docs", + models: { + "lucidnova-rf1-100b": { + id: "lucidnova-rf1-100b", + name: "LucidNova RF1 100B", + family: "nova", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2025-09-16", + release_date: "2024-12-28", + last_updated: "2025-09-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 5 }, + limit: { context: 120000, output: 8000 }, + }, + "lucidquery-nexus-coder": { + id: "lucidquery-nexus-coder", + name: "LucidQuery Nexus Coder", + family: "lucid", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2025-08-01", + release_date: "2025-09-01", + last_updated: "2025-09-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 5 }, + limit: { context: 250000, output: 60000 }, + }, + }, + }, + "moonshotai-cn": { + id: "moonshotai-cn", + env: ["MOONSHOT_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.moonshot.cn/v1", + name: "Moonshot AI (China)", + doc: "https://platform.moonshot.cn/docs/api/chat", + models: { + "kimi-k2-thinking": { + id: "kimi-k2-thinking", + name: "Kimi K2 Thinking", + family: "kimi-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-08", + release_date: "2025-11-06", + last_updated: "2025-11-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.5, cache_read: 0.15 }, + limit: { context: 262144, output: 262144 }, + }, + "kimi-k2-0711-preview": { + id: "kimi-k2-0711-preview", + name: "Kimi K2 0711", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-07-14", + last_updated: "2025-07-14", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.5, cache_read: 0.15 }, + limit: { context: 131072, output: 16384 }, + }, + "kimi-k2-turbo-preview": { + id: "kimi-k2-turbo-preview", + name: "Kimi K2 Turbo", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-09-05", + last_updated: "2025-09-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 2.4, output: 10, cache_read: 0.6 }, + limit: { context: 262144, output: 262144 }, + }, + "kimi-k2.6": { + id: "kimi-k2.6", + name: "Kimi K2.6", + family: "kimi-k2.6", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-04-21", + last_updated: "2026-04-21", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.95, output: 4, cache_read: 0.16 }, + limit: { context: 262144, output: 262144 }, + }, + "kimi-k2-thinking-turbo": { + id: "kimi-k2-thinking-turbo", + name: "Kimi K2 Thinking Turbo", + family: "kimi-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-08", + release_date: "2025-11-06", + last_updated: "2025-11-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.15, output: 8, cache_read: 0.15 }, + limit: { context: 262144, output: 262144 }, + }, + "kimi-k2.5": { + id: "kimi-k2.5", + name: "Kimi K2.5", + family: "kimi-k2.5", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: false, + knowledge: "2025-01", + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 3, cache_read: 0.1 }, + limit: { context: 262144, output: 262144 }, + }, + "kimi-k2-0905-preview": { + id: "kimi-k2-0905-preview", + name: "Kimi K2 0905", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-09-05", + last_updated: "2025-09-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.5, cache_read: 0.15 }, + limit: { context: 262144, output: 262144 }, + }, + }, + }, + "azure-cognitive-services": { + id: "azure-cognitive-services", + env: ["AZURE_COGNITIVE_SERVICES_RESOURCE_NAME", "AZURE_COGNITIVE_SERVICES_API_KEY"], + npm: "@ai-sdk/azure", + name: "Azure Cognitive Services", + doc: "https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/models", + models: { + "claude-haiku-4-5": { + id: "claude-haiku-4-5", + name: "Claude Haiku 4.5", + family: "claude-haiku", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-02-31", + release_date: "2025-11-18", + last_updated: "2025-11-18", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 5, cache_read: 0.1, cache_write: 1.25 }, + limit: { context: 200000, output: 64000 }, + provider: { + npm: "@ai-sdk/anthropic", + api: "https://${AZURE_COGNITIVE_SERVICES_RESOURCE_NAME}.services.ai.azure.com/anthropic/v1", + }, + }, + "claude-opus-4-1": { + id: "claude-opus-4-1", + name: "Claude Opus 4.1", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-11-18", + last_updated: "2025-11-18", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 32000 }, + provider: { + npm: "@ai-sdk/anthropic", + api: "https://${AZURE_COGNITIVE_SERVICES_RESOURCE_NAME}.services.ai.azure.com/anthropic/v1", + }, + }, + "claude-opus-4-5": { + id: "claude-opus-4-5", + name: "Claude Opus 4.5", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-11-24", + last_updated: "2025-08-01", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 200000, output: 64000 }, + provider: { + npm: "@ai-sdk/anthropic", + api: "https://${AZURE_COGNITIVE_SERVICES_RESOURCE_NAME}.services.ai.azure.com/anthropic/v1", + }, + }, + "kimi-k2.6": { + id: "kimi-k2.6", + name: "Kimi K2.6", + family: "kimi", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-04-22", + last_updated: "2026-04-22", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.95, output: 4 }, + limit: { context: 262144, output: 262144 }, + provider: { + npm: "@ai-sdk/openai-compatible", + api: "https://${AZURE_RESOURCE_NAME}.services.ai.azure.com/models", + shape: "completions", + }, + }, + "claude-opus-4-6": { + id: "claude-opus-4-6", + name: "Claude Opus 4.6", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-05-31", + release_date: "2026-02-05", + last_updated: "2026-02-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 5, + output: 25, + cache_read: 0.5, + cache_write: 6.25, + context_over_200k: { input: 10, output: 37.5, cache_read: 1, cache_write: 12.5 }, + }, + limit: { context: 200000, output: 128000 }, + provider: { + npm: "@ai-sdk/anthropic", + api: "https://${AZURE_COGNITIVE_SERVICES_RESOURCE_NAME}.services.ai.azure.com/anthropic/v1", + }, + }, + "claude-sonnet-4-5": { + id: "claude-sonnet-4-5", + name: "Claude Sonnet 4.5", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-07-31", + release_date: "2025-11-18", + last_updated: "2025-11-18", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + provider: { + npm: "@ai-sdk/anthropic", + api: "https://${AZURE_COGNITIVE_SERVICES_RESOURCE_NAME}.services.ai.azure.com/anthropic/v1", + }, + }, + "mai-ds-r1": { + id: "mai-ds-r1", + name: "MAI-DS-R1", + family: "mai", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + knowledge: "2024-06", + release_date: "2025-01-20", + last_updated: "2025-01-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.35, output: 5.4 }, + limit: { context: 128000, output: 8192 }, + }, + "llama-4-maverick-17b-128e-instruct-fp8": { + id: "llama-4-maverick-17b-128e-instruct-fp8", + name: "Llama 4 Maverick 17B 128E Instruct FP8", + family: "llama", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-08", + release_date: "2025-04-05", + last_updated: "2025-04-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.25, output: 1 }, + limit: { context: 128000, output: 8192 }, + }, + "codestral-2501": { + id: "codestral-2501", + name: "Codestral 25.01", + family: "codestral", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-03", + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 0.9 }, + limit: { context: 256000, output: 256000 }, + }, + "gpt-5.1-codex": { + id: "gpt-5.1-codex", + name: "GPT-5.1 Codex", + family: "gpt-codex", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-11-14", + last_updated: "2025-11-14", + modalities: { input: ["text", "image", "audio"], output: ["text", "image", "audio"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 400000, output: 128000 }, + }, + "kimi-k2-thinking": { + id: "kimi-k2-thinking", + name: "Kimi K2 Thinking", + family: "kimi-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: true, + temperature: true, + knowledge: "2024-08", + release_date: "2025-11-06", + last_updated: "2025-12-02", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.5, cache_read: 0.15 }, + limit: { context: 262144, output: 262144 }, + }, + "deepseek-r1-0528": { + id: "deepseek-r1-0528", + name: "DeepSeek-R1-0528", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2025-05-28", + last_updated: "2025-05-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.35, output: 5.4 }, + limit: { context: 163840, output: 163840 }, + }, + "gpt-3.5-turbo-instruct": { + id: "gpt-3.5-turbo-instruct", + name: "GPT-3.5 Turbo Instruct", + family: "gpt", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2021-08", + release_date: "2023-09-21", + last_updated: "2023-09-21", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.5, output: 2 }, + limit: { context: 4096, output: 4096 }, + }, + "mistral-medium-2505": { + id: "mistral-medium-2505", + name: "Mistral Medium 3", + family: "mistral-medium", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-05", + release_date: "2025-05-07", + last_updated: "2025-05-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 2 }, + limit: { context: 128000, output: 128000 }, + }, + "phi-4-reasoning-plus": { + id: "phi-4-reasoning-plus", + name: "Phi-4-reasoning-plus", + family: "phi", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + knowledge: "2023-10", + release_date: "2024-12-11", + last_updated: "2024-12-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.125, output: 0.5 }, + limit: { context: 32000, output: 4096 }, + }, + "cohere-embed-v3-english": { + id: "cohere-embed-v3-english", + name: "Embed v3 English", + family: "cohere-embed", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2023-11-07", + last_updated: "2023-11-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0 }, + limit: { context: 512, output: 1024 }, + }, + "gpt-4-32k": { + id: "gpt-4-32k", + name: "GPT-4 32K", + family: "gpt", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-11", + release_date: "2023-03-14", + last_updated: "2023-03-14", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 60, output: 120 }, + limit: { context: 32768, output: 32768 }, + }, + "gpt-5": { + id: "gpt-5", + name: "GPT-5", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.13 }, + limit: { context: 272000, output: 128000 }, + }, + "phi-4": { + id: "phi-4", + name: "Phi-4", + family: "phi", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2023-10", + release_date: "2024-12-11", + last_updated: "2024-12-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.125, output: 0.5 }, + limit: { context: 128000, output: 4096 }, + }, + "gpt-3.5-turbo-0613": { + id: "gpt-3.5-turbo-0613", + name: "GPT-3.5 Turbo 0613", + family: "gpt", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2021-08", + release_date: "2023-06-13", + last_updated: "2023-06-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 4 }, + limit: { context: 16384, output: 16384 }, + }, + "phi-3-medium-128k-instruct": { + id: "phi-3-medium-128k-instruct", + name: "Phi-3-medium-instruct (128k)", + family: "phi", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2023-10", + release_date: "2024-04-23", + last_updated: "2024-04-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.17, output: 0.68 }, + limit: { context: 128000, output: 4096 }, + }, + "deepseek-v3.2": { + id: "deepseek-v3.2", + name: "DeepSeek-V3.2", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2025-12-01", + last_updated: "2025-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.58, output: 1.68 }, + limit: { context: 128000, output: 128000 }, + }, + "phi-3-small-128k-instruct": { + id: "phi-3-small-128k-instruct", + name: "Phi-3-small-instruct (128k)", + family: "phi", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2023-10", + release_date: "2024-04-23", + last_updated: "2024-04-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 128000, output: 4096 }, + }, + "gpt-3.5-turbo-0301": { + id: "gpt-3.5-turbo-0301", + name: "GPT-3.5 Turbo 0301", + family: "gpt", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2021-08", + release_date: "2023-03-01", + last_updated: "2023-03-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.5, output: 2 }, + limit: { context: 4096, output: 4096 }, + }, + "phi-4-mini": { + id: "phi-4-mini", + name: "Phi-4-mini", + family: "phi", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-10", + release_date: "2024-12-11", + last_updated: "2024-12-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.075, output: 0.3 }, + limit: { context: 128000, output: 4096 }, + }, + "gpt-5-codex": { + id: "gpt-5-codex", + name: "GPT-5-Codex", + family: "gpt-codex", + attachment: false, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-09-15", + last_updated: "2025-09-15", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.13 }, + limit: { context: 400000, output: 128000 }, + }, + "meta-llama-3-8b-instruct": { + id: "meta-llama-3-8b-instruct", + name: "Meta-Llama-3-8B-Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2023-12", + release_date: "2024-04-18", + last_updated: "2024-04-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 0.61 }, + limit: { context: 8192, output: 2048 }, + }, + "gpt-4": { + id: "gpt-4", + name: "GPT-4", + family: "gpt", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-11", + release_date: "2023-03-14", + last_updated: "2023-03-14", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 60, output: 120 }, + limit: { context: 8192, output: 8192 }, + }, + "phi-4-mini-reasoning": { + id: "phi-4-mini-reasoning", + name: "Phi-4-mini-reasoning", + family: "phi", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2023-10", + release_date: "2024-12-11", + last_updated: "2024-12-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.075, output: 0.3 }, + limit: { context: 128000, output: 4096 }, + }, + "meta-llama-3.1-70b-instruct": { + id: "meta-llama-3.1-70b-instruct", + name: "Meta-Llama-3.1-70B-Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 2.68, output: 3.54 }, + limit: { context: 128000, output: 32768 }, + }, + "phi-3-mini-4k-instruct": { + id: "phi-3-mini-4k-instruct", + name: "Phi-3-mini-instruct (4k)", + family: "phi", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2023-10", + release_date: "2024-04-23", + last_updated: "2024-04-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.13, output: 0.52 }, + limit: { context: 4096, output: 1024 }, + }, + "deepseek-v3.1": { + id: "deepseek-v3.1", + name: "DeepSeek-V3.1", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2025-08-21", + last_updated: "2025-08-21", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.56, output: 1.68 }, + limit: { context: 131072, output: 131072 }, + }, + "text-embedding-3-small": { + id: "text-embedding-3-small", + name: "text-embedding-3-small", + family: "text-embedding", + attachment: false, + reasoning: false, + tool_call: false, + release_date: "2024-01-25", + last_updated: "2024-01-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.02, output: 0 }, + limit: { context: 8191, output: 1536 }, + }, + "gpt-3.5-turbo-1106": { + id: "gpt-3.5-turbo-1106", + name: "GPT-3.5 Turbo 1106", + family: "gpt", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2021-08", + release_date: "2023-11-06", + last_updated: "2023-11-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 2 }, + limit: { context: 16384, output: 16384 }, + }, + "model-router": { + id: "model-router", + name: "Model Router", + family: "model-router", + attachment: true, + reasoning: false, + tool_call: true, + release_date: "2025-05-19", + last_updated: "2025-11-18", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.14, output: 0 }, + limit: { context: 128000, output: 16384 }, + }, + "mistral-small-2503": { + id: "mistral-small-2503", + name: "Mistral Small 3.1", + family: "mistral-small", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-09", + release_date: "2025-03-01", + last_updated: "2025-03-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.3 }, + limit: { context: 128000, output: 32768 }, + }, + o1: { + id: "o1", + name: "o1", + family: "o", + attachment: false, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2023-09", + release_date: "2024-12-05", + last_updated: "2024-12-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 60, cache_read: 7.5 }, + limit: { context: 200000, output: 100000 }, + }, + "grok-4-fast-reasoning": { + id: "grok-4-fast-reasoning", + name: "Grok 4 Fast (Reasoning)", + family: "grok", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-09-19", + last_updated: "2025-09-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5, cache_read: 0.05 }, + limit: { context: 2000000, output: 30000 }, + }, + "gpt-5.1": { + id: "gpt-5.1", + name: "GPT-5.1", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-11-14", + last_updated: "2025-11-14", + modalities: { input: ["text", "image", "audio"], output: ["text", "image", "audio"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 272000, output: 128000 }, + }, + "cohere-embed-v3-multilingual": { + id: "cohere-embed-v3-multilingual", + name: "Embed v3 Multilingual", + family: "cohere-embed", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2023-11-07", + last_updated: "2023-11-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0 }, + limit: { context: 512, output: 1024 }, + }, + "o1-preview": { + id: "o1-preview", + name: "o1-preview", + family: "o", + attachment: false, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2023-09", + release_date: "2024-09-12", + last_updated: "2024-09-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 16.5, output: 66, cache_read: 8.25 }, + limit: { context: 128000, output: 32768 }, + }, + "gpt-3.5-turbo-0125": { + id: "gpt-3.5-turbo-0125", + name: "GPT-3.5 Turbo 0125", + family: "gpt", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2021-08", + release_date: "2024-01-25", + last_updated: "2024-01-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 1.5 }, + limit: { context: 16384, output: 16384 }, + }, + "gpt-5.1-codex-mini": { + id: "gpt-5.1-codex-mini", + name: "GPT-5.1 Codex Mini", + family: "gpt-codex", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-11-14", + last_updated: "2025-11-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 2, cache_read: 0.025 }, + limit: { context: 400000, output: 128000 }, + }, + "cohere-embed-v-4-0": { + id: "cohere-embed-v-4-0", + name: "Embed v4", + family: "cohere-embed", + attachment: true, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2025-04-15", + last_updated: "2025-04-15", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.12, output: 0 }, + limit: { context: 128000, output: 1536 }, + }, + "gpt-5.2-codex": { + id: "gpt-5.2-codex", + name: "GPT-5.2 Codex", + family: "gpt-codex", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-01-14", + last_updated: "2026-01-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 400000, output: 128000 }, + }, + "gpt-4-turbo-vision": { + id: "gpt-4-turbo-vision", + name: "GPT-4 Turbo Vision", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-11", + release_date: "2023-11-06", + last_updated: "2024-04-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 10, output: 30 }, + limit: { context: 128000, output: 4096 }, + }, + "gpt-5.1-chat": { + id: "gpt-5.1-chat", + name: "GPT-5.1 Chat", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-11-14", + last_updated: "2025-11-14", + modalities: { input: ["text", "image", "audio"], output: ["text", "image", "audio"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 128000, output: 16384 }, + }, + "meta-llama-3.1-405b-instruct": { + id: "meta-llama-3.1-405b-instruct", + name: "Meta-Llama-3.1-405B-Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 5.33, output: 16 }, + limit: { context: 128000, output: 32768 }, + }, + "llama-3.2-11b-vision-instruct": { + id: "llama-3.2-11b-vision-instruct", + name: "Llama-3.2-11B-Vision-Instruct", + family: "llama", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-09-25", + last_updated: "2024-09-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.37, output: 0.37 }, + limit: { context: 128000, output: 8192 }, + }, + "cohere-command-a": { + id: "cohere-command-a", + name: "Command A", + family: "command-a", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-06-01", + release_date: "2025-03-13", + last_updated: "2025-03-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 2.5, output: 10 }, + limit: { context: 256000, output: 8000 }, + }, + "mistral-large-2411": { + id: "mistral-large-2411", + name: "Mistral Large 24.11", + family: "mistral-large", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-09", + release_date: "2024-11-01", + last_updated: "2024-11-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 6 }, + limit: { context: 128000, output: 32768 }, + }, + "gpt-5.2": { + id: "gpt-5.2", + name: "GPT-5.2", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2025-12-11", + last_updated: "2025-12-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.125 }, + limit: { context: 400000, output: 128000 }, + }, + "deepseek-v3.2-speciale": { + id: "deepseek-v3.2-speciale", + name: "DeepSeek-V3.2-Speciale", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + knowledge: "2024-07", + release_date: "2025-12-01", + last_updated: "2025-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.58, output: 1.68 }, + limit: { context: 128000, output: 128000 }, + }, + "deepseek-r1": { + id: "deepseek-r1", + name: "DeepSeek-R1", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + knowledge: "2024-07", + release_date: "2025-01-20", + last_updated: "2025-01-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.35, output: 5.4 }, + limit: { context: 163840, output: 163840 }, + }, + "llama-3.2-90b-vision-instruct": { + id: "llama-3.2-90b-vision-instruct", + name: "Llama-3.2-90B-Vision-Instruct", + family: "llama", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-09-25", + last_updated: "2024-09-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 2.04, output: 2.04 }, + limit: { context: 128000, output: 8192 }, + }, + "text-embedding-ada-002": { + id: "text-embedding-ada-002", + name: "text-embedding-ada-002", + family: "text-embedding", + attachment: false, + reasoning: false, + tool_call: false, + release_date: "2022-12-15", + last_updated: "2022-12-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0 }, + limit: { context: 8192, output: 1536 }, + }, + "gpt-5.3-codex": { + id: "gpt-5.3-codex", + name: "GPT-5.3 Codex", + family: "gpt-codex", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-02-24", + last_updated: "2026-02-24", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 400000, output: 128000 }, + }, + "phi-3-small-8k-instruct": { + id: "phi-3-small-8k-instruct", + name: "Phi-3-small-instruct (8k)", + family: "phi", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2023-10", + release_date: "2024-04-23", + last_updated: "2024-04-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 8192, output: 2048 }, + }, + "meta-llama-3-70b-instruct": { + id: "meta-llama-3-70b-instruct", + name: "Meta-Llama-3-70B-Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2023-12", + release_date: "2024-04-18", + last_updated: "2024-04-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 2.68, output: 3.54 }, + limit: { context: 8192, output: 2048 }, + }, + "gpt-5-nano": { + id: "gpt-5-nano", + name: "GPT-5 Nano", + family: "gpt-nano", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-05-30", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.05, output: 0.4, cache_read: 0.01 }, + limit: { context: 272000, output: 128000 }, + }, + "gpt-5-mini": { + id: "gpt-5-mini", + name: "GPT-5 Mini", + family: "gpt-mini", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-05-30", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 2, cache_read: 0.03 }, + limit: { context: 272000, output: 128000 }, + }, + "phi-4-reasoning": { + id: "phi-4-reasoning", + name: "Phi-4-reasoning", + family: "phi", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + knowledge: "2023-10", + release_date: "2024-12-11", + last_updated: "2024-12-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.125, output: 0.5 }, + limit: { context: 32000, output: 4096 }, + }, + "phi-3-mini-128k-instruct": { + id: "phi-3-mini-128k-instruct", + name: "Phi-3-mini-instruct (128k)", + family: "phi", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2023-10", + release_date: "2024-04-23", + last_updated: "2024-04-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.13, output: 0.52 }, + limit: { context: 128000, output: 4096 }, + }, + "text-embedding-3-large": { + id: "text-embedding-3-large", + name: "text-embedding-3-large", + family: "text-embedding", + attachment: false, + reasoning: false, + tool_call: false, + release_date: "2024-01-25", + last_updated: "2024-01-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.13, output: 0 }, + limit: { context: 8191, output: 3072 }, + }, + "o1-mini": { + id: "o1-mini", + name: "o1-mini", + family: "o-mini", + attachment: false, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2023-09", + release_date: "2024-09-12", + last_updated: "2024-09-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 4.4, cache_read: 0.55 }, + limit: { context: 128000, output: 65536 }, + }, + "phi-3.5-moe-instruct": { + id: "phi-3.5-moe-instruct", + name: "Phi-3.5-MoE-instruct", + family: "phi", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2023-10", + release_date: "2024-08-20", + last_updated: "2024-08-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.16, output: 0.64 }, + limit: { context: 128000, output: 4096 }, + }, + "gpt-5-chat": { + id: "gpt-5-chat", + name: "GPT-5 Chat", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: false, + temperature: false, + knowledge: "2024-10-24", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.13 }, + limit: { context: 128000, output: 16384 }, + }, + "deepseek-v3-0324": { + id: "deepseek-v3-0324", + name: "DeepSeek-V3-0324", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2025-03-24", + last_updated: "2025-03-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.14, output: 4.56 }, + limit: { context: 131072, output: 131072 }, + }, + "llama-3.3-70b-instruct": { + id: "llama-3.3-70b-instruct", + name: "Llama-3.3-70B-Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.71, output: 0.71 }, + limit: { context: 128000, output: 32768 }, + }, + "kimi-k2.5": { + id: "kimi-k2.5", + name: "Kimi K2.5", + family: "kimi", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-02-06", + last_updated: "2026-02-06", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 3 }, + limit: { context: 262144, output: 262144 }, + provider: { + npm: "@ai-sdk/openai-compatible", + api: "https://${AZURE_RESOURCE_NAME}.services.ai.azure.com/models", + shape: "completions", + }, + }, + "meta-llama-3.1-8b-instruct": { + id: "meta-llama-3.1-8b-instruct", + name: "Meta-Llama-3.1-8B-Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 0.61 }, + limit: { context: 128000, output: 32768 }, + }, + "ministral-3b": { + id: "ministral-3b", + name: "Ministral 3B", + family: "ministral", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-03", + release_date: "2024-10-22", + last_updated: "2024-10-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.04, output: 0.04 }, + limit: { context: 128000, output: 8192 }, + }, + "phi-3-medium-4k-instruct": { + id: "phi-3-medium-4k-instruct", + name: "Phi-3-medium-instruct (4k)", + family: "phi", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2023-10", + release_date: "2024-04-23", + last_updated: "2024-04-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.17, output: 0.68 }, + limit: { context: 4096, output: 1024 }, + }, + "llama-4-scout-17b-16e-instruct": { + id: "llama-4-scout-17b-16e-instruct", + name: "Llama 4 Scout 17B 16E Instruct", + family: "llama", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-08", + release_date: "2025-04-05", + last_updated: "2025-04-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.78 }, + limit: { context: 128000, output: 8192 }, + }, + "phi-3.5-mini-instruct": { + id: "phi-3.5-mini-instruct", + name: "Phi-3.5-mini-instruct", + family: "phi", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2023-10", + release_date: "2024-08-20", + last_updated: "2024-08-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.13, output: 0.52 }, + limit: { context: 128000, output: 4096 }, + }, + "phi-4-multimodal": { + id: "phi-4-multimodal", + name: "Phi-4-multimodal", + family: "phi", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2023-10", + release_date: "2024-12-11", + last_updated: "2024-12-11", + modalities: { input: ["text", "image", "audio"], output: ["text"] }, + open_weights: true, + cost: { input: 0.08, output: 0.32, input_audio: 4 }, + limit: { context: 128000, output: 4096 }, + }, + "codex-mini": { + id: "codex-mini", + name: "Codex Mini", + family: "gpt-codex-mini", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-04", + release_date: "2025-05-16", + last_updated: "2025-05-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.5, output: 6, cache_read: 0.375 }, + limit: { context: 200000, output: 100000 }, + }, + "gpt-5.2-chat": { + id: "gpt-5.2-chat", + name: "GPT-5.2 Chat", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2025-12-11", + last_updated: "2025-12-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 128000, output: 16384 }, + }, + "mistral-nemo": { + id: "mistral-nemo", + name: "Mistral Nemo", + family: "mistral-nemo", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2024-07-18", + last_updated: "2024-07-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.15 }, + limit: { context: 128000, output: 128000 }, + }, + "gpt-5.4-mini": { + id: "gpt-5.4-mini", + name: "GPT-5.4 Mini", + family: "gpt-mini", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-17", + last_updated: "2026-03-17", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.75, output: 4.5, cache_read: 0.075 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "gpt-5.4-nano": { + id: "gpt-5.4-nano", + name: "GPT-5.4 Nano", + family: "gpt-nano", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-17", + last_updated: "2026-03-17", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 1.25, cache_read: 0.02 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "gpt-5.4-pro": { + id: "gpt-5.4-pro", + name: "GPT-5.4 Pro", + family: "gpt-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-05", + last_updated: "2026-03-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 30, output: 180, context_over_200k: { input: 60, output: 270 } }, + limit: { context: 1050000, input: 922000, output: 128000 }, + }, + "gpt-5.4": { + id: "gpt-5.4", + name: "GPT-5.4", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-05", + last_updated: "2026-03-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 2.5, + output: 15, + cache_read: 0.25, + context_over_200k: { input: 5, output: 22.5, cache_read: 0.5 }, + }, + limit: { context: 1050000, input: 922000, output: 128000 }, + }, + "grok-4-fast-non-reasoning": { + id: "grok-4-fast-non-reasoning", + name: "Grok 4 Fast (Non-Reasoning)", + family: "grok", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-09-19", + last_updated: "2025-09-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5, cache_read: 0.05 }, + limit: { context: 2000000, output: 30000 }, + }, + "grok-3": { + id: "grok-3", + name: "Grok 3", + family: "grok", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-11", + release_date: "2025-02-17", + last_updated: "2025-02-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.75 }, + limit: { context: 131072, output: 8192 }, + }, + "gpt-4.1-mini": { + id: "gpt-4.1-mini", + name: "GPT-4.1 mini", + family: "gpt-mini", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-04-14", + last_updated: "2025-04-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 1.6, cache_read: 0.1 }, + limit: { context: 1047576, output: 32768 }, + }, + "gpt-4.1": { + id: "gpt-4.1", + name: "GPT-4.1", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-04-14", + last_updated: "2025-04-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 8, cache_read: 0.5 }, + limit: { context: 1047576, output: 32768 }, + }, + "cohere-command-r-plus-08-2024": { + id: "cohere-command-r-plus-08-2024", + name: "Command R+", + family: "command-r", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-06-01", + release_date: "2024-08-30", + last_updated: "2024-08-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 2.5, output: 10 }, + limit: { context: 128000, output: 4000 }, + }, + "gpt-4o": { + id: "gpt-4o", + name: "GPT-4o", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-09", + release_date: "2024-05-13", + last_updated: "2024-08-06", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 10, cache_read: 1.25 }, + limit: { context: 128000, output: 16384 }, + }, + "gpt-5-pro": { + id: "gpt-5-pro", + name: "GPT-5 Pro", + family: "gpt-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-10-06", + last_updated: "2025-10-06", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 120 }, + limit: { context: 400000, output: 272000 }, + }, + o3: { + id: "o3", + name: "o3", + family: "o", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-05", + release_date: "2025-04-16", + last_updated: "2025-04-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 8, cache_read: 0.5 }, + limit: { context: 200000, output: 100000 }, + }, + "grok-3-mini": { + id: "grok-3-mini", + name: "Grok 3 Mini", + family: "grok", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-11", + release_date: "2025-02-17", + last_updated: "2025-02-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 0.5, reasoning: 0.5, cache_read: 0.075 }, + limit: { context: 131072, output: 8192 }, + }, + "gpt-4.1-nano": { + id: "gpt-4.1-nano", + name: "GPT-4.1 nano", + family: "gpt-nano", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-04-14", + last_updated: "2025-04-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4, cache_read: 0.03 }, + limit: { context: 1047576, output: 32768 }, + }, + "grok-4": { + id: "grok-4", + name: "Grok 4", + family: "grok", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-07-09", + last_updated: "2025-07-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, reasoning: 15, cache_read: 0.75 }, + limit: { context: 256000, output: 64000 }, + }, + "o3-mini": { + id: "o3-mini", + name: "o3-mini", + family: "o-mini", + attachment: false, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-05", + release_date: "2024-12-20", + last_updated: "2025-01-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 4.4, cache_read: 0.55 }, + limit: { context: 200000, output: 100000 }, + }, + "grok-code-fast-1": { + id: "grok-code-fast-1", + name: "Grok Code Fast 1", + family: "grok", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2023-10", + release_date: "2025-08-28", + last_updated: "2025-08-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 1.5, cache_read: 0.02 }, + limit: { context: 256000, output: 10000 }, + }, + "o4-mini": { + id: "o4-mini", + name: "o4-mini", + family: "o-mini", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-05", + release_date: "2025-04-16", + last_updated: "2025-04-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 4.4, cache_read: 0.28 }, + limit: { context: 200000, output: 100000 }, + }, + "cohere-command-r-08-2024": { + id: "cohere-command-r-08-2024", + name: "Command R", + family: "command-r", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-06-01", + release_date: "2024-08-30", + last_updated: "2024-08-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 128000, output: 4000 }, + }, + "gpt-4o-mini": { + id: "gpt-4o-mini", + name: "GPT-4o mini", + family: "gpt-mini", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-09", + release_date: "2024-07-18", + last_updated: "2024-07-18", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.6, cache_read: 0.08 }, + limit: { context: 128000, output: 16384 }, + }, + "gpt-4-turbo": { + id: "gpt-4-turbo", + name: "GPT-4 Turbo", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2023-11-06", + last_updated: "2024-04-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 10, output: 30 }, + limit: { context: 128000, output: 4096 }, + }, + "gpt-5.5": { + id: "gpt-5.5", + name: "GPT-5.5", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-12-01", + release_date: "2026-04-24", + last_updated: "2026-04-24", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 30, cache_read: 0.5, context_over_200k: { input: 10, output: 45, cache_read: 1 } }, + limit: { context: 1050000, input: 922000, output: 128000 }, + }, + }, + }, + "abliteration-ai": { + id: "abliteration-ai", + env: ["ABLIT_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.abliteration.ai/v1", + name: "abliteration.ai", + doc: "https://docs.abliteration.ai/models", + models: { + "abliterated-model": { + id: "abliterated-model", + name: "Abliterated Model", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2026-01-06", + last_updated: "2026-01-06", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 3, output: 3 }, + limit: { context: 150000, input: 150000, output: 8192 }, + }, + }, + }, + "wafer.ai": { + id: "wafer.ai", + env: ["WAFER_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://pass.wafer.ai/v1", + name: "Wafer", + doc: "https://docs.wafer.ai/wafer-pass", + models: { + "Qwen3.5-397B-A17B": { + id: "Qwen3.5-397B-A17B", + name: "Qwen3.5 397B A17B", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-02-16", + last_updated: "2026-02-16", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 262144, output: 65536 }, + }, + "GLM-5.1": { + id: "GLM-5.1", + name: "GLM-5.1", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-04-07", + last_updated: "2026-04-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 202752, output: 131072 }, + }, + "MiniMax-M2.7": { + id: "MiniMax-M2.7", + name: "MiniMax-M2.7", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 204800, output: 131072 }, + }, + "DeepSeek-V4-Pro": { + id: "DeepSeek-V4-Pro", + name: "DeepSeek V4 Pro", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-05", + release_date: "2026-04-24", + last_updated: "2026-04-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 1000000, output: 384000 }, + }, + }, + }, + cohere: { + id: "cohere", + env: ["COHERE_API_KEY"], + npm: "@ai-sdk/cohere", + name: "Cohere", + doc: "https://docs.cohere.com/docs/models", + models: { + "command-a-reasoning-08-2025": { + id: "command-a-reasoning-08-2025", + name: "Command A Reasoning", + family: "command-a", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-06-01", + release_date: "2025-08-21", + last_updated: "2025-08-21", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 2.5, output: 10 }, + limit: { context: 256000, output: 32000 }, + }, + "command-r7b-12-2024": { + id: "command-r7b-12-2024", + name: "Command R7B", + family: "command-r", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-06-01", + release_date: "2024-02-27", + last_updated: "2024-02-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.0375, output: 0.15 }, + limit: { context: 128000, output: 4000 }, + }, + "c4ai-aya-vision-8b": { + id: "c4ai-aya-vision-8b", + name: "Aya Vision 8B", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-03-04", + last_updated: "2025-05-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + limit: { context: 16000, output: 4000 }, + }, + "command-r-plus-08-2024": { + id: "command-r-plus-08-2024", + name: "Command R+", + family: "command-r", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-06-01", + release_date: "2024-08-30", + last_updated: "2024-08-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 2.5, output: 10 }, + limit: { context: 128000, output: 4000 }, + }, + "c4ai-aya-expanse-8b": { + id: "c4ai-aya-expanse-8b", + name: "Aya Expanse 8B", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2024-10-24", + last_updated: "2024-10-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + limit: { context: 8000, output: 4000 }, + }, + "command-r7b-arabic-02-2025": { + id: "command-r7b-arabic-02-2025", + name: "Command R7B Arabic", + family: "command-r", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-06-01", + release_date: "2025-02-27", + last_updated: "2025-02-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.0375, output: 0.15 }, + limit: { context: 128000, output: 4000 }, + }, + "command-a-vision-07-2025": { + id: "command-a-vision-07-2025", + name: "Command A Vision", + family: "command-a", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-06-01", + release_date: "2025-07-31", + last_updated: "2025-07-31", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 2.5, output: 10 }, + limit: { context: 128000, output: 8000 }, + }, + "c4ai-aya-vision-32b": { + id: "c4ai-aya-vision-32b", + name: "Aya Vision 32B", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-03-04", + last_updated: "2025-05-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + limit: { context: 16000, output: 4000 }, + }, + "command-a-translate-08-2025": { + id: "command-a-translate-08-2025", + name: "Command A Translate", + family: "command-a", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-06-01", + release_date: "2025-08-28", + last_updated: "2025-08-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 2.5, output: 10 }, + limit: { context: 8000, output: 8000 }, + }, + "command-r-08-2024": { + id: "command-r-08-2024", + name: "Command R", + family: "command-r", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-06-01", + release_date: "2024-08-30", + last_updated: "2024-08-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 128000, output: 4000 }, + }, + "c4ai-aya-expanse-32b": { + id: "c4ai-aya-expanse-32b", + name: "Aya Expanse 32B", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2024-10-24", + last_updated: "2024-10-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + limit: { context: 128000, output: 4000 }, + }, + "command-a-03-2025": { + id: "command-a-03-2025", + name: "Command A", + family: "command-a", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-06-01", + release_date: "2025-03-13", + last_updated: "2025-03-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 2.5, output: 10 }, + limit: { context: 256000, output: 8000 }, + }, + }, + }, + "cloudferro-sherlock": { + id: "cloudferro-sherlock", + env: ["CLOUDFERRO_SHERLOCK_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api-sherlock.cloudferro.com/openai/v1/", + name: "CloudFerro Sherlock", + doc: "https://docs.sherlock.cloudferro.com/", + models: { + "meta-llama/Llama-3.3-70B-Instruct": { + id: "meta-llama/Llama-3.3-70B-Instruct", + name: "Llama 3.3 70B Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10-09", + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 2.92, output: 2.92 }, + limit: { context: 70000, output: 70000 }, + }, + "openai/gpt-oss-120b": { + id: "openai/gpt-oss-120b", + name: "OpenAI GPT OSS 120B", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-08-28", + last_updated: "2025-08-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 2.92, output: 2.92 }, + limit: { context: 131000, output: 131000 }, + }, + "speakleash/Bielik-11B-v3.0-Instruct": { + id: "speakleash/Bielik-11B-v3.0-Instruct", + name: "Bielik 11B v3.0 Instruct", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-03", + release_date: "2025-03-13", + last_updated: "2025-03-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.67, output: 0.67 }, + limit: { context: 32000, output: 32000 }, + }, + "speakleash/Bielik-11B-v2.6-Instruct": { + id: "speakleash/Bielik-11B-v2.6-Instruct", + name: "Bielik 11B v2.6 Instruct", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-03", + release_date: "2025-03-13", + last_updated: "2025-03-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.67, output: 0.67 }, + limit: { context: 32000, output: 32000 }, + }, + "MiniMaxAI/MiniMax-M2.5": { + id: "MiniMaxAI/MiniMax-M2.5", + name: "MiniMax-M2.5", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2026-01", + release_date: "2026-03-05", + last_updated: "2026-03-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 196000, input: 180000, output: 16000 }, + }, + }, + }, + "kuae-cloud-coding-plan": { + id: "kuae-cloud-coding-plan", + env: ["KUAE_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://coding-plan-endpoint.kuaecloud.net/v1", + name: "KUAE Cloud Coding Plan", + doc: "https://docs.mthreads.com/kuaecloud/kuaecloud-doc-online/coding_plan/", + models: { + "GLM-4.7": { + id: "GLM-4.7", + name: "GLM-4.7", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-04", + release_date: "2025-12-22", + last_updated: "2025-12-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 204800, output: 131072 }, + }, + }, + }, + xai: { + id: "xai", + env: ["XAI_API_KEY"], + npm: "@ai-sdk/xai", + name: "xAI", + doc: "https://docs.x.ai/docs/models", + models: { + "grok-2-1212": { + id: "grok-2-1212", + name: "Grok 2 (1212)", + family: "grok", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-08", + release_date: "2024-12-12", + last_updated: "2024-12-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 10, cache_read: 2 }, + limit: { context: 131072, output: 8192 }, + }, + "grok-vision-beta": { + id: "grok-vision-beta", + name: "Grok Vision Beta", + family: "grok-vision", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-08", + release_date: "2024-11-01", + last_updated: "2024-11-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 15, cache_read: 5 }, + limit: { context: 8192, output: 4096 }, + }, + "grok-4.3": { + id: "grok-4.3", + name: "Grok 4.3", + family: "grok", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-05-01", + last_updated: "2026-05-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { + input: 1.25, + output: 2.5, + cache_read: 0.2, + context_over_200k: { input: 2.5, output: 5, cache_read: 0.4 }, + }, + limit: { context: 1000000, output: 30000 }, + }, + "grok-3-mini-fast": { + id: "grok-3-mini-fast", + name: "Grok 3 Mini Fast", + family: "grok", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-11", + release_date: "2025-02-17", + last_updated: "2025-02-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.6, output: 4, reasoning: 4, cache_read: 0.15 }, + limit: { context: 131072, output: 8192 }, + }, + "grok-3-mini-latest": { + id: "grok-3-mini-latest", + name: "Grok 3 Mini Latest", + family: "grok", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-11", + release_date: "2025-02-17", + last_updated: "2025-02-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 0.5, reasoning: 0.5, cache_read: 0.075 }, + limit: { context: 131072, output: 8192 }, + }, + "grok-3-fast": { + id: "grok-3-fast", + name: "Grok 3 Fast", + family: "grok", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-11", + release_date: "2025-02-17", + last_updated: "2025-02-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 1.25 }, + limit: { context: 131072, output: 8192 }, + }, + "grok-2-vision-latest": { + id: "grok-2-vision-latest", + name: "Grok 2 Vision Latest", + family: "grok", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-08", + release_date: "2024-08-20", + last_updated: "2024-12-12", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 10, cache_read: 2 }, + limit: { context: 8192, output: 4096 }, + }, + "grok-4.20-0309-reasoning": { + id: "grok-4.20-0309-reasoning", + name: "Grok 4.20 (Reasoning)", + family: "grok", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-09", + last_updated: "2026-03-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 6, cache_read: 0.2, context_over_200k: { input: 4, output: 12, cache_read: 0.4 } }, + limit: { context: 2000000, output: 30000 }, + }, + "grok-4-1-fast-non-reasoning": { + id: "grok-4-1-fast-non-reasoning", + name: "Grok 4.1 Fast (Non-Reasoning)", + family: "grok", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-11-19", + last_updated: "2025-11-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5, cache_read: 0.05 }, + limit: { context: 2000000, output: 30000 }, + }, + "grok-3-mini-fast-latest": { + id: "grok-3-mini-fast-latest", + name: "Grok 3 Mini Fast Latest", + family: "grok", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-11", + release_date: "2025-02-17", + last_updated: "2025-02-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.6, output: 4, reasoning: 4, cache_read: 0.15 }, + limit: { context: 131072, output: 8192 }, + }, + "grok-4-fast": { + id: "grok-4-fast", + name: "Grok 4 Fast", + family: "grok", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-09-19", + last_updated: "2025-09-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5, cache_read: 0.05 }, + limit: { context: 2000000, output: 30000 }, + }, + "grok-3-latest": { + id: "grok-3-latest", + name: "Grok 3 Latest", + family: "grok", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-11", + release_date: "2025-02-17", + last_updated: "2025-02-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.75 }, + limit: { context: 131072, output: 8192 }, + }, + "grok-2": { + id: "grok-2", + name: "Grok 2", + family: "grok", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-08", + release_date: "2024-08-20", + last_updated: "2024-08-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 10, cache_read: 2 }, + limit: { context: 131072, output: 8192 }, + }, + "grok-code-fast-1": { + id: "grok-code-fast-1", + name: "Grok Code Fast 1", + family: "grok", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2023-10", + release_date: "2025-08-28", + last_updated: "2025-08-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 1.5, cache_read: 0.02 }, + limit: { context: 256000, output: 10000 }, + }, + "grok-4.20-0309-non-reasoning": { + id: "grok-4.20-0309-non-reasoning", + name: "Grok 4.20 (Non-Reasoning)", + family: "grok", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2026-03-09", + last_updated: "2026-03-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 6, cache_read: 0.2, context_over_200k: { input: 4, output: 12, cache_read: 0.4 } }, + limit: { context: 2000000, output: 30000 }, + }, + "grok-3-fast-latest": { + id: "grok-3-fast-latest", + name: "Grok 3 Fast Latest", + family: "grok", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-11", + release_date: "2025-02-17", + last_updated: "2025-02-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 1.25 }, + limit: { context: 131072, output: 8192 }, + }, + "grok-4.20-multi-agent-0309": { + id: "grok-4.20-multi-agent-0309", + name: "Grok 4.20 Multi-Agent", + family: "grok", + attachment: true, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2026-03-09", + last_updated: "2026-03-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 6, cache_read: 0.2, context_over_200k: { input: 4, output: 12, cache_read: 0.4 } }, + limit: { context: 2000000, output: 30000 }, + }, + "grok-4": { + id: "grok-4", + name: "Grok 4", + family: "grok", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-07-09", + last_updated: "2025-07-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, reasoning: 15, cache_read: 0.75 }, + limit: { context: 256000, output: 64000 }, + }, + "grok-2-latest": { + id: "grok-2-latest", + name: "Grok 2 Latest", + family: "grok", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-08", + release_date: "2024-08-20", + last_updated: "2024-12-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 10, cache_read: 2 }, + limit: { context: 131072, output: 8192 }, + }, + "grok-beta": { + id: "grok-beta", + name: "Grok Beta", + family: "grok-beta", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-08", + release_date: "2024-11-01", + last_updated: "2024-11-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 15, cache_read: 5 }, + limit: { context: 131072, output: 4096 }, + }, + "grok-2-vision": { + id: "grok-2-vision", + name: "Grok 2 Vision", + family: "grok", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-08", + release_date: "2024-08-20", + last_updated: "2024-08-20", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 10, cache_read: 2 }, + limit: { context: 8192, output: 4096 }, + }, + "grok-4-1-fast": { + id: "grok-4-1-fast", + name: "Grok 4.1 Fast", + family: "grok", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-11-19", + last_updated: "2025-11-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5, cache_read: 0.05 }, + limit: { context: 2000000, output: 30000 }, + }, + "grok-3-mini": { + id: "grok-3-mini", + name: "Grok 3 Mini", + family: "grok", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-11", + release_date: "2025-02-17", + last_updated: "2025-02-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 0.5, reasoning: 0.5, cache_read: 0.075 }, + limit: { context: 131072, output: 8192 }, + }, + "grok-2-vision-1212": { + id: "grok-2-vision-1212", + name: "Grok 2 Vision (1212)", + family: "grok", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-08", + release_date: "2024-08-20", + last_updated: "2024-12-12", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 10, cache_read: 2 }, + limit: { context: 8192, output: 4096 }, + }, + "grok-3": { + id: "grok-3", + name: "Grok 3", + family: "grok", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-11", + release_date: "2025-02-17", + last_updated: "2025-02-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.75 }, + limit: { context: 131072, output: 8192 }, + }, + "grok-4-fast-non-reasoning": { + id: "grok-4-fast-non-reasoning", + name: "Grok 4 Fast (Non-Reasoning)", + family: "grok", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-09-19", + last_updated: "2025-09-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5, cache_read: 0.05 }, + limit: { context: 2000000, output: 30000 }, + }, + }, + }, + meganova: { + id: "meganova", + env: ["MEGANOVA_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.meganova.ai/v1", + name: "Meganova", + doc: "https://docs.meganova.ai", + models: { + "Qwen/Qwen3-235B-A22B-Instruct-2507": { + id: "Qwen/Qwen3-235B-A22B-Instruct-2507", + name: "Qwen3 235B A22B Instruct 2507", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-07-23", + last_updated: "2025-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.09, output: 0.6 }, + limit: { context: 262000, output: 262000 }, + }, + "Qwen/Qwen3.5-Plus": { + id: "Qwen/Qwen3.5-Plus", + name: "Qwen3.5 Plus", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-02", + last_updated: "2026-02", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 2.4, reasoning: 2.4 }, + limit: { context: 1000000, output: 65536 }, + }, + "Qwen/Qwen2.5-VL-32B-Instruct": { + id: "Qwen/Qwen2.5-VL-32B-Instruct", + name: "Qwen2.5 VL 32B Instruct", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-03-24", + last_updated: "2025-03-24", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.6 }, + limit: { context: 16384, output: 16384 }, + }, + "zai-org/GLM-4.7": { + id: "zai-org/GLM-4.7", + name: "GLM-4.7", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-04", + release_date: "2025-12-22", + last_updated: "2025-12-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.8 }, + limit: { context: 202752, output: 131072 }, + }, + "zai-org/GLM-5": { + id: "zai-org/GLM-5", + name: "GLM-5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-02-11", + last_updated: "2026-02-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.8, output: 2.56 }, + limit: { context: 202752, output: 131072 }, + }, + "zai-org/GLM-4.6": { + id: "zai-org/GLM-4.6", + name: "GLM-4.6", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-04", + release_date: "2025-09-30", + last_updated: "2025-09-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.45, output: 1.9 }, + limit: { context: 202752, output: 131072 }, + }, + "mistralai/Mistral-Small-3.2-24B-Instruct-2506": { + id: "mistralai/Mistral-Small-3.2-24B-Instruct-2506", + name: "Mistral Small 3.2 24B Instruct", + family: "mistral-small", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-06-20", + last_updated: "2025-06-20", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 32768, output: 8192 }, + }, + "mistralai/Mistral-Nemo-Instruct-2407": { + id: "mistralai/Mistral-Nemo-Instruct-2407", + name: "Mistral Nemo Instruct 2407", + family: "mistral", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-07-18", + last_updated: "2024-07-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.02, output: 0.04 }, + limit: { context: 131072, output: 65536 }, + }, + "XiaomiMiMo/MiMo-V2-Flash": { + id: "XiaomiMiMo/MiMo-V2-Flash", + name: "MiMo V2 Flash", + family: "mimo", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-12-01", + release_date: "2025-12-17", + last_updated: "2025-12-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.3 }, + limit: { context: 262144, output: 32000 }, + }, + "meta-llama/Llama-3.3-70B-Instruct": { + id: "meta-llama/Llama-3.3-70B-Instruct", + name: "Llama 3.3 70B Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.3 }, + limit: { context: 131072, output: 16384 }, + }, + "deepseek-ai/DeepSeek-V3.1": { + id: "deepseek-ai/DeepSeek-V3.1", + name: "DeepSeek V3.1", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-08-25", + last_updated: "2025-08-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.27, output: 1 }, + limit: { context: 164000, output: 164000 }, + }, + "deepseek-ai/DeepSeek-V3-0324": { + id: "deepseek-ai/DeepSeek-V3-0324", + name: "DeepSeek V3 0324", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-03-24", + last_updated: "2025-03-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.25, output: 0.88 }, + limit: { context: 163840, output: 163840 }, + }, + "deepseek-ai/DeepSeek-V3.2-Exp": { + id: "deepseek-ai/DeepSeek-V3.2-Exp", + name: "DeepSeek V3.2 Exp", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-10-10", + last_updated: "2025-10-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.27, output: 0.4 }, + limit: { context: 164000, output: 164000 }, + }, + "deepseek-ai/DeepSeek-R1-0528": { + id: "deepseek-ai/DeepSeek-R1-0528", + name: "DeepSeek R1 0528", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: false, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-07", + release_date: "2025-05-28", + last_updated: "2025-05-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.5, output: 2.15 }, + limit: { context: 163840, output: 64000 }, + }, + "deepseek-ai/DeepSeek-V3.2": { + id: "deepseek-ai/DeepSeek-V3.2", + name: "DeepSeek V3.2", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-12-03", + last_updated: "2025-12-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.26, output: 0.38 }, + limit: { context: 164000, output: 164000 }, + }, + "moonshotai/Kimi-K2-Thinking": { + id: "moonshotai/Kimi-K2-Thinking", + name: "Kimi K2 Thinking", + family: "kimi-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-08", + release_date: "2025-11-06", + last_updated: "2025-11-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.6 }, + limit: { context: 262144, output: 262144 }, + }, + "moonshotai/Kimi-K2.5": { + id: "moonshotai/Kimi-K2.5", + name: "Kimi K2.5", + family: "kimi", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2026-01", + release_date: "2026-01-27", + last_updated: "2026-01-27", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.45, output: 2.8 }, + limit: { context: 262144, output: 262144 }, + }, + "MiniMaxAI/MiniMax-M2.5": { + id: "MiniMaxAI/MiniMax-M2.5", + name: "MiniMax M2.5", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 204800, output: 131072 }, + }, + "MiniMaxAI/MiniMax-M2.1": { + id: "MiniMaxAI/MiniMax-M2.1", + name: "MiniMax M2.1", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2025-12-23", + last_updated: "2025-12-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.28, output: 1.2 }, + limit: { context: 196608, output: 131072 }, + }, + }, + }, + "google-vertex-anthropic": { + id: "google-vertex-anthropic", + env: ["GOOGLE_VERTEX_PROJECT", "GOOGLE_VERTEX_LOCATION", "GOOGLE_APPLICATION_CREDENTIALS"], + npm: "@ai-sdk/google-vertex/anthropic", + name: "Vertex (Anthropic)", + doc: "https://cloud.google.com/vertex-ai/generative-ai/docs/partner-models/claude", + models: { + "claude-haiku-4-5@20251001": { + id: "claude-haiku-4-5@20251001", + name: "Claude Haiku 4.5", + family: "claude-haiku", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-02-28", + release_date: "2025-10-15", + last_updated: "2025-10-15", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 5, cache_read: 0.1, cache_write: 1.25 }, + limit: { context: 200000, output: 64000 }, + }, + "claude-sonnet-4-6@default": { + id: "claude-sonnet-4-6@default", + name: "Claude Sonnet 4.6", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: 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, + cost: { + input: 3, + output: 15, + cache_read: 0.3, + cache_write: 3.75, + context_over_200k: { input: 6, output: 22.5, cache_read: 0.6, cache_write: 7.5 }, + }, + limit: { context: 200000, output: 64000 }, + }, + "claude-3-5-haiku@20241022": { + id: "claude-3-5-haiku@20241022", + name: "Claude Haiku 3.5", + family: "claude-haiku", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-07-31", + release_date: "2024-10-22", + last_updated: "2024-10-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.8, output: 4, cache_read: 0.08, cache_write: 1 }, + limit: { context: 200000, output: 8192 }, + }, + "claude-3-5-sonnet@20241022": { + id: "claude-3-5-sonnet@20241022", + name: "Claude Sonnet 3.5 v2", + family: "claude-sonnet", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04-30", + release_date: "2024-10-22", + last_updated: "2024-10-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 8192 }, + }, + "claude-opus-4-1@20250805": { + id: "claude-opus-4-1@20250805", + name: "Claude Opus 4.1", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 32000 }, + }, + "claude-sonnet-4@20250514": { + id: "claude-sonnet-4@20250514", + name: "Claude Sonnet 4", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + }, + "claude-3-7-sonnet@20250219": { + id: "claude-3-7-sonnet@20250219", + name: "Claude Sonnet 3.7", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10-31", + release_date: "2025-02-19", + last_updated: "2025-02-19", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + }, + "claude-opus-4@20250514": { + id: "claude-opus-4@20250514", + name: "Claude Opus 4", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 32000 }, + }, + "claude-opus-4-5@20251101": { + id: "claude-opus-4-5@20251101", + name: "Claude Opus 4.5", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-11-01", + last_updated: "2025-11-01", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 200000, output: 64000 }, + }, + "claude-sonnet-4-5@20250929": { + id: "claude-sonnet-4-5@20250929", + name: "Claude Sonnet 4.5", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07-31", + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + }, + "claude-opus-4-6@default": { + id: "claude-opus-4-6@default", + name: "Claude Opus 4.6", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-05-31", + release_date: "2026-02-05", + last_updated: "2026-03-13", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 5, + output: 25, + cache_read: 0.5, + cache_write: 6.25, + context_over_200k: { input: 10, output: 37.5, cache_read: 1, cache_write: 12.5 }, + }, + limit: { context: 1000000, output: 128000 }, + }, + "claude-opus-4-7@default": { + id: "claude-opus-4-7@default", + name: "Claude Opus 4.7", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2026-01-31", + release_date: "2026-04-16", + last_updated: "2026-04-16", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 5, + output: 25, + cache_read: 0.5, + cache_write: 6.25, + context_over_200k: { input: 10, output: 37.5, cache_read: 1, cache_write: 12.5 }, + }, + limit: { context: 1000000, output: 128000 }, + }, + }, + }, + evroc: { + id: "evroc", + env: ["EVROC_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://models.think.evroc.com/v1", + name: "evroc", + doc: "https://docs.evroc.com/products/think/overview.html", + models: { + "Qwen/Qwen3-VL-30B-A3B-Instruct": { + id: "Qwen/Qwen3-VL-30B-A3B-Instruct", + name: "Qwen3 VL 30B", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + release_date: "2025-07-30", + last_updated: "2025-07-30", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.24, output: 0.94 }, + limit: { context: 100000, output: 100000 }, + }, + "Qwen/Qwen3-Embedding-8B": { + id: "Qwen/Qwen3-Embedding-8B", + name: "Qwen3 Embedding 8B", + family: "text-embedding", + attachment: false, + reasoning: false, + tool_call: false, + release_date: "2025-07-30", + last_updated: "2025-07-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.12, output: 0.12 }, + limit: { context: 40960, output: 40960 }, + }, + "Qwen/Qwen3-30B-A3B-Instruct-2507-FP8": { + id: "Qwen/Qwen3-30B-A3B-Instruct-2507-FP8", + name: "Qwen3 30B 2507", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + release_date: "2025-07-30", + last_updated: "2025-07-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.35, output: 1.42 }, + limit: { context: 64000, output: 64000 }, + }, + "mistralai/devstral-small-2-24b-instruct-2512": { + id: "mistralai/devstral-small-2-24b-instruct-2512", + name: "Devstral Small 2 24B Instruct 2512", + family: "devstral", + attachment: false, + reasoning: false, + tool_call: true, + release_date: "2025-12-01", + last_updated: "2025-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.12, output: 0.47 }, + limit: { context: 32768, output: 32768 }, + }, + "mistralai/Voxtral-Small-24B-2507": { + id: "mistralai/Voxtral-Small-24B-2507", + name: "Voxtral Small 24B", + family: "voxtral", + attachment: false, + reasoning: false, + tool_call: false, + release_date: "2025-03-01", + last_updated: "2025-03-01", + modalities: { input: ["audio", "text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.00236, output: 0.00236, output_audio: 2.36 }, + limit: { context: 32000, output: 32000 }, + }, + "mistralai/Magistral-Small-2509": { + id: "mistralai/Magistral-Small-2509", + name: "Magistral Small 1.2 24B", + family: "magistral-small", + attachment: false, + reasoning: false, + tool_call: false, + release_date: "2025-06-01", + last_updated: "2025-06-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.59, output: 2.36 }, + limit: { context: 131072, output: 131072 }, + }, + "microsoft/Phi-4-multimodal-instruct": { + id: "microsoft/Phi-4-multimodal-instruct", + name: "Phi-4 15B", + family: "phi", + attachment: false, + reasoning: false, + tool_call: false, + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.24, output: 0.47 }, + limit: { context: 32000, output: 32000 }, + }, + "KBLab/kb-whisper-large": { + id: "KBLab/kb-whisper-large", + name: "KB Whisper", + family: "whisper", + attachment: false, + reasoning: false, + tool_call: false, + release_date: "2024-10-01", + last_updated: "2024-10-01", + modalities: { input: ["audio"], output: ["text"] }, + open_weights: true, + cost: { input: 0.00236, output: 0.00236, output_audio: 2.36 }, + limit: { context: 448, output: 448 }, + }, + "nvidia/Llama-3.3-70B-Instruct-FP8": { + id: "nvidia/Llama-3.3-70B-Instruct-FP8", + name: "Llama 3.3 70B", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + release_date: "2024-12-01", + last_updated: "2024-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.18, output: 1.18 }, + limit: { context: 131072, output: 32768 }, + }, + "openai/whisper-large-v3": { + id: "openai/whisper-large-v3", + name: "Whisper 3 Large", + family: "whisper", + attachment: false, + reasoning: false, + tool_call: false, + release_date: "2024-10-01", + last_updated: "2024-10-01", + modalities: { input: ["audio"], output: ["text"] }, + open_weights: true, + cost: { input: 0.00236, output: 0.00236, output_audio: 2.36 }, + limit: { context: 448, output: 4096 }, + }, + "openai/gpt-oss-120b": { + id: "openai/gpt-oss-120b", + name: "GPT OSS 120B", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.24, output: 0.94 }, + limit: { context: 65536, output: 65536 }, + }, + "moonshotai/Kimi-K2.5": { + id: "moonshotai/Kimi-K2.5", + name: "Kimi K2.5", + family: "kimi", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + release_date: "2026-01-27", + last_updated: "2026-01-27", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 1.47, output: 5.9 }, + limit: { context: 262144, output: 262144 }, + }, + "intfloat/multilingual-e5-large-instruct": { + id: "intfloat/multilingual-e5-large-instruct", + name: "E5 Multi-Lingual Large Embeddings 0.6B", + family: "text-embedding", + attachment: false, + reasoning: false, + tool_call: false, + release_date: "2024-06-01", + last_updated: "2024-06-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.12, output: 0.12 }, + limit: { context: 512, output: 512 }, + }, + }, + }, + synthetic: { + id: "synthetic", + env: ["SYNTHETIC_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.synthetic.new/openai/v1", + name: "Synthetic", + doc: "https://synthetic.new/pricing", + models: { + "hf:meta-llama/Llama-3.1-405B-Instruct": { + id: "hf:meta-llama/Llama-3.1-405B-Instruct", + name: "Llama-3.1-405B-Instruct", + family: "llama", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 3, output: 3 }, + limit: { context: 128000, output: 32768 }, + }, + "hf:meta-llama/Llama-4-Scout-17B-16E-Instruct": { + id: "hf:meta-llama/Llama-4-Scout-17B-16E-Instruct", + name: "Llama-4-Scout-17B-16E-Instruct", + family: "llama", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-08", + release_date: "2025-04-05", + last_updated: "2025-04-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 328000, output: 4096 }, + }, + "hf:meta-llama/Llama-3.3-70B-Instruct": { + id: "hf:meta-llama/Llama-3.3-70B-Instruct", + name: "Llama-3.3-70B-Instruct", + family: "llama", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.9, output: 0.9 }, + limit: { context: 128000, output: 32768 }, + }, + "hf:meta-llama/Llama-3.1-8B-Instruct": { + id: "hf:meta-llama/Llama-3.1-8B-Instruct", + name: "Llama-3.1-8B-Instruct", + family: "llama", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.2 }, + limit: { context: 128000, output: 32768 }, + }, + "hf:meta-llama/Llama-3.1-70B-Instruct": { + id: "hf:meta-llama/Llama-3.1-70B-Instruct", + name: "Llama-3.1-70B-Instruct", + family: "llama", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.9, output: 0.9 }, + limit: { context: 128000, output: 32768 }, + }, + "hf:meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8": { + id: "hf:meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8", + name: "Llama-4-Maverick-17B-128E-Instruct-FP8", + family: "llama", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-08", + release_date: "2025-04-05", + last_updated: "2025-04-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.22, output: 0.88 }, + limit: { context: 524000, output: 4096 }, + }, + "hf:MiniMaxAI/MiniMax-M2": { + id: "hf:MiniMaxAI/MiniMax-M2", + name: "MiniMax-M2", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-10-27", + last_updated: "2025-10-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.55, output: 2.19 }, + limit: { context: 196608, output: 131000 }, + }, + "hf:MiniMaxAI/MiniMax-M2.5": { + id: "hf:MiniMaxAI/MiniMax-M2.5", + name: "MiniMax-M2.5", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-02-07", + last_updated: "2026-02-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 3, cache_read: 0.6 }, + limit: { context: 191488, output: 65536 }, + }, + "hf:MiniMaxAI/MiniMax-M2.1": { + id: "hf:MiniMaxAI/MiniMax-M2.1", + name: "MiniMax-M2.1", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2025-12-23", + last_updated: "2025-12-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.55, output: 2.19 }, + limit: { context: 204800, output: 131072 }, + }, + "hf:Qwen/Qwen3.5-397B-A17B": { + id: "hf:Qwen/Qwen3.5-397B-A17B", + name: "Qwen3.5-97B-A17B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-02-11", + last_updated: "2026-02-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 3, cache_read: 0.6 }, + limit: { context: 262144, output: 65536 }, + status: "beta", + }, + "hf:Qwen/Qwen2.5-Coder-32B-Instruct": { + id: "hf:Qwen/Qwen2.5-Coder-32B-Instruct", + name: "Qwen2.5-Coder-32B-Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-10", + release_date: "2024-11-11", + last_updated: "2024-11-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.8, output: 0.8 }, + limit: { context: 32768, output: 32768 }, + }, + "hf:Qwen/Qwen3-235B-A22B-Instruct-2507": { + id: "hf:Qwen/Qwen3-235B-A22B-Instruct-2507", + name: "Qwen 3 235B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-04-28", + last_updated: "2025-07-21", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.6 }, + limit: { context: 256000, output: 32000 }, + }, + "hf:Qwen/Qwen3-235B-A22B-Thinking-2507": { + id: "hf:Qwen/Qwen3-235B-A22B-Thinking-2507", + name: "Qwen3 235B A22B Thinking 2507", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-25", + last_updated: "2025-07-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.65, output: 3 }, + limit: { context: 256000, output: 32000 }, + }, + "hf:Qwen/Qwen3-Coder-480B-A35B-Instruct": { + id: "hf:Qwen/Qwen3-Coder-480B-A35B-Instruct", + name: "Qwen 3 Coder 480B", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-23", + last_updated: "2025-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 2, output: 2 }, + limit: { context: 256000, output: 32000 }, + }, + "hf:deepseek-ai/DeepSeek-V3.1": { + id: "hf:deepseek-ai/DeepSeek-V3.1", + name: "DeepSeek V3.1", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-21", + last_updated: "2025-08-21", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.56, output: 1.68 }, + limit: { context: 128000, output: 128000 }, + }, + "hf:deepseek-ai/DeepSeek-V3-0324": { + id: "hf:deepseek-ai/DeepSeek-V3-0324", + name: "DeepSeek V3 (0324)", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-08-01", + last_updated: "2025-08-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.2, output: 1.2 }, + limit: { context: 128000, output: 128000 }, + }, + "hf:deepseek-ai/DeepSeek-V3": { + id: "hf:deepseek-ai/DeepSeek-V3", + name: "DeepSeek V3", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2025-01-20", + last_updated: "2025-05-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.25, output: 1.25 }, + limit: { context: 128000, output: 128000 }, + }, + "hf:deepseek-ai/DeepSeek-R1": { + id: "hf:deepseek-ai/DeepSeek-R1", + name: "DeepSeek R1", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-01-20", + last_updated: "2025-01-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.55, output: 2.19 }, + limit: { context: 128000, output: 128000 }, + }, + "hf:deepseek-ai/DeepSeek-R1-0528": { + id: "hf:deepseek-ai/DeepSeek-R1-0528", + name: "DeepSeek R1 (0528)", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-01", + last_updated: "2025-08-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 8 }, + limit: { context: 128000, output: 128000 }, + }, + "hf:deepseek-ai/DeepSeek-V3.2": { + id: "hf:deepseek-ai/DeepSeek-V3.2", + name: "DeepSeek V3.2", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-12-01", + last_updated: "2025-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.27, output: 0.4, cache_read: 0.27, cache_write: 0 }, + limit: { context: 162816, input: 162816, output: 8000 }, + }, + "hf:deepseek-ai/DeepSeek-V3.1-Terminus": { + id: "hf:deepseek-ai/DeepSeek-V3.1-Terminus", + name: "DeepSeek V3.1 Terminus", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-09-22", + last_updated: "2025-09-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.2, output: 1.2 }, + limit: { context: 128000, output: 128000 }, + }, + "hf:openai/gpt-oss-120b": { + id: "hf:openai/gpt-oss-120b", + name: "GPT OSS 120B", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.1 }, + limit: { context: 128000, output: 32768 }, + }, + "hf:moonshotai/Kimi-K2-Thinking": { + id: "hf:moonshotai/Kimi-K2-Thinking", + name: "Kimi K2 Thinking", + family: "kimi-thinking", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-11", + release_date: "2025-11-07", + last_updated: "2025-11-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.55, output: 2.19 }, + limit: { context: 262144, output: 262144 }, + }, + "hf:moonshotai/Kimi-K2-Instruct-0905": { + id: "hf:moonshotai/Kimi-K2-Instruct-0905", + name: "Kimi K2 0905", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-09-05", + last_updated: "2025-09-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.2, output: 1.2 }, + limit: { context: 262144, output: 32768 }, + }, + "hf:moonshotai/Kimi-K2.5": { + id: "hf:moonshotai/Kimi-K2.5", + name: "Kimi K2.5", + family: "kimi", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-01", + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.55, output: 2.19 }, + limit: { context: 262144, output: 65536 }, + }, + "hf:nvidia/NVIDIA-Nemotron-3-Super-120B-A12B-NVFP4": { + id: "hf:nvidia/NVIDIA-Nemotron-3-Super-120B-A12B-NVFP4", + name: "Nemotron 3 Super 120B", + family: "nemotron", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2024-04", + release_date: "2026-03-11", + last_updated: "2026-04-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1, cache_read: 0.3 }, + limit: { context: 262144, output: 65536 }, + }, + "hf:nvidia/Kimi-K2.5-NVFP4": { + id: "hf:nvidia/Kimi-K2.5-NVFP4", + name: "Kimi K2.5 (NVFP4)", + family: "kimi", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-01", + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.55, output: 2.19 }, + limit: { context: 262144, output: 65536 }, + }, + "hf:zai-org/GLM-4.7-Flash": { + id: "hf:zai-org/GLM-4.7-Flash", + name: "GLM-4.7-Flash", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-01-18", + last_updated: "2026-01-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.06, output: 0.4, cache_read: 0.06 }, + limit: { context: 196608, output: 65536 }, + }, + "hf:zai-org/GLM-4.7": { + id: "hf:zai-org/GLM-4.7", + name: "GLM 4.7", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-04", + release_date: "2025-12-22", + last_updated: "2025-12-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.55, output: 2.19 }, + limit: { context: 200000, output: 64000 }, + }, + "hf:zai-org/GLM-5.1": { + id: "hf:zai-org/GLM-5.1", + name: "GLM 5.1", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-03-27", + last_updated: "2026-04-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 3, cache_read: 1 }, + limit: { context: 196608, output: 65536 }, + }, + "hf:zai-org/GLM-5": { + id: "hf:zai-org/GLM-5", + name: "GLM-5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-02-12", + last_updated: "2026-04-08", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 3, cache_read: 1 }, + limit: { context: 196608, output: 65536 }, + }, + "hf:zai-org/GLM-4.6": { + id: "hf:zai-org/GLM-4.6", + name: "GLM 4.6", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-09-30", + last_updated: "2025-09-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.55, output: 2.19 }, + limit: { context: 200000, output: 64000 }, + }, + "hf:moonshotai/Kimi-K2.6": { + id: "hf:moonshotai/Kimi-K2.6", + name: "Kimi K2.6", + family: "kimi-k2.6", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-04-21", + last_updated: "2026-04-21", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.95, output: 4, cache_read: 0.95 }, + limit: { context: 262144, output: 65536 }, + }, + }, + }, + nvidia: { + id: "nvidia", + env: ["NVIDIA_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://integrate.api.nvidia.com/v1", + name: "Nvidia", + doc: "https://docs.api.nvidia.com/nim/", + models: { + "black-forest-labs/flux.1-dev": { + id: "black-forest-labs/flux.1-dev", + name: "FLUX.1-dev", + family: "flux", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-08", + release_date: "2024-08-01", + last_updated: "2025-09-05", + modalities: { input: ["text"], output: ["image"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 4096, output: 0 }, + }, + "stepfun-ai/step-3.5-flash": { + id: "stepfun-ai/step-3.5-flash", + name: "Step 3.5 Flash", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-02", + last_updated: "2026-02-02", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 256000, output: 16384 }, + }, + "mistralai/codestral-22b-instruct-v0.1": { + id: "mistralai/codestral-22b-instruct-v0.1", + name: "Codestral 22b Instruct V0.1", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-05-29", + last_updated: "2024-05-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "mistralai/mistral-large-3-675b-instruct-2512": { + id: "mistralai/mistral-large-3-675b-instruct-2512", + name: "Mistral Large 3 675B Instruct 2512", + family: "mistral-large", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-12-02", + last_updated: "2025-12-02", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 262144, output: 262144 }, + }, + "mistralai/devstral-2-123b-instruct-2512": { + id: "mistralai/devstral-2-123b-instruct-2512", + name: "Devstral-2-123B-Instruct-2512", + family: "devstral", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-12", + release_date: "2025-12-08", + last_updated: "2025-12-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 262144, output: 262144 }, + }, + "mistralai/ministral-14b-instruct-2512": { + id: "mistralai/ministral-14b-instruct-2512", + name: "Ministral 3 14B Instruct 2512", + family: "ministral", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-12", + release_date: "2025-12-01", + last_updated: "2025-12-08", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 262144, output: 262144 }, + }, + "mistralai/mistral-small-3.1-24b-instruct-2503": { + id: "mistralai/mistral-small-3.1-24b-instruct-2503", + name: "Mistral Small 3.1 24b Instruct 2503", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-03-11", + last_updated: "2025-03-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "mistralai/mamba-codestral-7b-v0.1": { + id: "mistralai/mamba-codestral-7b-v0.1", + name: "Mamba Codestral 7b V0.1", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2024-07-16", + last_updated: "2024-07-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "mistralai/mistral-large-2-instruct": { + id: "mistralai/mistral-large-2-instruct", + name: "Mistral Large 2 Instruct", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-07-24", + last_updated: "2024-07-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "microsoft/phi-3-medium-4k-instruct": { + id: "microsoft/phi-3-medium-4k-instruct", + name: "Phi 3 Medium 4k Instruct", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2023-10", + release_date: "2024-05-07", + last_updated: "2024-05-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 4000, output: 4096 }, + }, + "microsoft/phi-3.5-moe-instruct": { + id: "microsoft/phi-3.5-moe-instruct", + name: "Phi 3.5 Moe Instruct", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-08-17", + last_updated: "2024-08-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "microsoft/phi-4-mini-instruct": { + id: "microsoft/phi-4-mini-instruct", + name: "Phi-4-Mini", + family: "phi", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-12", + release_date: "2024-12-01", + last_updated: "2025-09-05", + modalities: { input: ["text", "image", "audio"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 131072, output: 8192 }, + }, + "microsoft/phi-3-small-8k-instruct": { + id: "microsoft/phi-3-small-8k-instruct", + name: "Phi 3 Small 8k Instruct", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2023-10", + release_date: "2024-05-07", + last_updated: "2024-05-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 8000, output: 4096 }, + }, + "microsoft/phi-3-vision-128k-instruct": { + id: "microsoft/phi-3-vision-128k-instruct", + name: "Phi 3 Vision 128k Instruct", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-05-19", + last_updated: "2024-05-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "microsoft/phi-3.5-vision-instruct": { + id: "microsoft/phi-3.5-vision-instruct", + name: "Phi 3.5 Vision Instruct", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-08-16", + last_updated: "2024-08-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "microsoft/phi-3-small-128k-instruct": { + id: "microsoft/phi-3-small-128k-instruct", + name: "Phi 3 Small 128k Instruct", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2023-10", + release_date: "2024-05-07", + last_updated: "2024-05-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "microsoft/phi-3-medium-128k-instruct": { + id: "microsoft/phi-3-medium-128k-instruct", + name: "Phi 3 Medium 128k Instruct", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2023-10", + release_date: "2024-05-07", + last_updated: "2024-05-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "nvidia/nemotron-3-nano-omni-30b-a3b-reasoning": { + id: "nvidia/nemotron-3-nano-omni-30b-a3b-reasoning", + name: "Nemotron 3 Nano Omni", + family: "nemotron", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-04-28", + last_updated: "2026-04-28", + modalities: { input: ["text", "image", "video", "audio"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 256000, output: 65536 }, + }, + "nvidia/llama-3.3-nemotron-super-49b-v1": { + id: "nvidia/llama-3.3-nemotron-super-49b-v1", + name: "Llama 3.3 Nemotron Super 49b V1", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2025-03-16", + last_updated: "2025-03-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "nvidia/nemotron-4-340b-instruct": { + id: "nvidia/nemotron-4-340b-instruct", + name: "Nemotron 4 340b Instruct", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-06-13", + last_updated: "2024-06-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "nvidia/llama3-chatqa-1.5-70b": { + id: "nvidia/llama3-chatqa-1.5-70b", + name: "Llama3 Chatqa 1.5 70b", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-04-28", + last_updated: "2024-04-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "nvidia/llama-3.3-nemotron-super-49b-v1.5": { + id: "nvidia/llama-3.3-nemotron-super-49b-v1.5", + name: "Llama 3.3 Nemotron Super 49b V1.5", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2025-03-16", + last_updated: "2025-03-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "nvidia/nemotron-3-super-120b-a12b": { + id: "nvidia/nemotron-3-super-120b-a12b", + name: "Nemotron 3 Super", + family: "nemotron", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2026-03-11", + last_updated: "2026-03-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.8 }, + limit: { context: 262144, output: 262144 }, + }, + "nvidia/parakeet-tdt-0.6b-v2": { + id: "nvidia/parakeet-tdt-0.6b-v2", + name: "Parakeet TDT 0.6B v2", + family: "parakeet", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + knowledge: "2024-01", + release_date: "2024-01-01", + last_updated: "2025-09-05", + modalities: { input: ["audio"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 0, output: 4096 }, + }, + "nvidia/nemotron-3-nano-30b-a3b": { + id: "nvidia/nemotron-3-nano-30b-a3b", + name: "nemotron-3-nano-30b-a3b", + family: "nemotron", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-09", + release_date: "2024-12", + last_updated: "2024-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 131072, output: 131072 }, + }, + "nvidia/llama-3.1-nemotron-ultra-253b-v1": { + id: "nvidia/llama-3.1-nemotron-ultra-253b-v1", + name: "Llama-3.1-Nemotron-Ultra-253B-v1", + family: "llama", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2024-07-01", + last_updated: "2025-09-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 131072, output: 8192 }, + }, + "nvidia/nvidia-nemotron-nano-9b-v2": { + id: "nvidia/nvidia-nemotron-nano-9b-v2", + name: "nvidia-nemotron-nano-9b-v2", + family: "nemotron", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-09", + release_date: "2025-08-18", + last_updated: "2025-08-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 131072, output: 131072 }, + }, + "nvidia/cosmos-nemotron-34b": { + id: "nvidia/cosmos-nemotron-34b", + name: "Cosmos Nemotron 34B", + family: "nemotron", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + knowledge: "2024-01", + release_date: "2024-01-01", + last_updated: "2025-09-05", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 131072, output: 8192 }, + }, + "nvidia/llama-embed-nemotron-8b": { + id: "nvidia/llama-embed-nemotron-8b", + name: "Llama Embed Nemotron 8B", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + knowledge: "2025-03", + release_date: "2025-03-18", + last_updated: "2025-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 32768, output: 2048 }, + }, + "nvidia/llama-3.1-nemotron-51b-instruct": { + id: "nvidia/llama-3.1-nemotron-51b-instruct", + name: "Llama 3.1 Nemotron 51b Instruct", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-09-22", + last_updated: "2024-09-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "nvidia/llama-3.1-nemotron-70b-instruct": { + id: "nvidia/llama-3.1-nemotron-70b-instruct", + name: "Llama 3.1 Nemotron 70b Instruct", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-10-12", + last_updated: "2024-10-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "nvidia/nemoretriever-ocr-v1": { + id: "nvidia/nemoretriever-ocr-v1", + name: "NeMo Retriever OCR v1", + family: "nemoretriever", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + knowledge: "2024-01", + release_date: "2024-01-01", + last_updated: "2025-09-05", + modalities: { input: ["image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 0, output: 4096 }, + }, + "deepseek-ai/deepseek-r1": { + id: "deepseek-ai/deepseek-r1", + name: "Deepseek R1", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2025-01-20", + last_updated: "2025-01-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "deepseek-ai/deepseek-v3.1": { + id: "deepseek-ai/deepseek-v3.1", + name: "DeepSeek V3.1", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2025-08-20", + last_updated: "2025-08-26", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 8192 }, + }, + "deepseek-ai/deepseek-coder-6.7b-instruct": { + id: "deepseek-ai/deepseek-coder-6.7b-instruct", + name: "Deepseek Coder 6.7b Instruct", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2023-10-29", + last_updated: "2023-10-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "deepseek-ai/deepseek-v3.2": { + id: "deepseek-ai/deepseek-v3.2", + name: "DeepSeek V3.2", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2025-12-01", + last_updated: "2025-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 163840, output: 65536 }, + }, + "deepseek-ai/deepseek-r1-0528": { + id: "deepseek-ai/deepseek-r1-0528", + name: "Deepseek R1 0528", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-05-28", + last_updated: "2025-05-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "deepseek-ai/deepseek-v3.1-terminus": { + id: "deepseek-ai/deepseek-v3.1-terminus", + name: "DeepSeek V3.1 Terminus", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-09-22", + last_updated: "2025-09-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 8192 }, + }, + "openai/whisper-large-v3": { + id: "openai/whisper-large-v3", + name: "Whisper Large v3", + family: "whisper", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + knowledge: "2023-09", + release_date: "2023-09-01", + last_updated: "2025-09-05", + modalities: { input: ["audio"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 0, output: 4096 }, + }, + "openai/gpt-oss-120b": { + id: "openai/gpt-oss-120b", + name: "GPT-OSS-120B", + family: "gpt-oss", + attachment: true, + reasoning: true, + tool_call: false, + temperature: true, + knowledge: "2025-08", + release_date: "2025-08-04", + last_updated: "2025-08-14", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 8192 }, + }, + "minimaxai/minimax-m2.7": { + id: "minimaxai/minimax-m2.7", + name: "MiniMax-M2.7", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-18", + last_updated: "2026-04-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 204800, output: 131072 }, + }, + "minimaxai/minimax-m2.1": { + id: "minimaxai/minimax-m2.1", + name: "MiniMax-M2.1", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-12-23", + last_updated: "2025-12-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 204800, output: 131072 }, + }, + "minimaxai/minimax-m2.5": { + id: "minimaxai/minimax-m2.5", + name: "MiniMax-M2.5", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-08", + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 204800, output: 131072 }, + }, + "z-ai/glm4.7": { + id: "z-ai/glm4.7", + name: "GLM-4.7", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-04", + release_date: "2025-12-22", + last_updated: "2025-12-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 204800, output: 131072 }, + }, + "z-ai/glm5": { + id: "z-ai/glm5", + name: "GLM5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 202752, output: 131000 }, + }, + "z-ai/glm-5.1": { + id: "z-ai/glm-5.1", + name: "GLM-5.1", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-03-27", + last_updated: "2026-03-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 131072, output: 131072 }, + }, + "meta/llama-4-scout-17b-16e-instruct": { + id: "meta/llama-4-scout-17b-16e-instruct", + name: "Llama 4 Scout 17b 16e Instruct", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-02", + release_date: "2025-04-02", + last_updated: "2025-04-02", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "meta/llama-3.3-70b-instruct": { + id: "meta/llama-3.3-70b-instruct", + name: "Llama 3.3 70b Instruct", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-11-26", + last_updated: "2024-11-26", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "meta/llama3-8b-instruct": { + id: "meta/llama3-8b-instruct", + name: "Llama3 8b Instruct", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-04-17", + last_updated: "2024-04-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "meta/llama3-70b-instruct": { + id: "meta/llama3-70b-instruct", + name: "Llama3 70b Instruct", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-04-17", + last_updated: "2024-04-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "meta/codellama-70b": { + id: "meta/codellama-70b", + name: "Codellama 70b", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2024-01-29", + last_updated: "2024-01-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "meta/llama-3.2-11b-vision-instruct": { + id: "meta/llama-3.2-11b-vision-instruct", + name: "Llama 3.2 11b Vision Instruct", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-09-18", + last_updated: "2024-09-18", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "meta/llama-3.1-70b-instruct": { + id: "meta/llama-3.1-70b-instruct", + name: "Llama 3.1 70b Instruct", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-07-16", + last_updated: "2024-07-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "meta/llama-3.2-1b-instruct": { + id: "meta/llama-3.2-1b-instruct", + name: "Llama 3.2 1b Instruct", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-09-18", + last_updated: "2024-09-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "meta/llama-4-maverick-17b-128e-instruct": { + id: "meta/llama-4-maverick-17b-128e-instruct", + name: "Llama 4 Maverick 17b 128e Instruct", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-02", + release_date: "2025-04-01", + last_updated: "2025-04-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "meta/llama-3.1-405b-instruct": { + id: "meta/llama-3.1-405b-instruct", + name: "Llama 3.1 405b Instruct", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-07-16", + last_updated: "2024-07-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "qwen/qwen3-235b-a22b": { + id: "qwen/qwen3-235b-a22b", + name: "Qwen3-235B-A22B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-12", + release_date: "2024-12-01", + last_updated: "2025-09-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 131072, output: 8192 }, + }, + "qwen/qwen2.5-coder-7b-instruct": { + id: "qwen/qwen2.5-coder-7b-instruct", + name: "Qwen2.5 Coder 7b Instruct", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-09-17", + last_updated: "2024-09-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "qwen/qwen2.5-coder-32b-instruct": { + id: "qwen/qwen2.5-coder-32b-instruct", + name: "Qwen2.5 Coder 32b Instruct", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-11-06", + last_updated: "2024-11-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "qwen/qwen3.5-397b-a17b": { + id: "qwen/qwen3.5-397b-a17b", + name: "Qwen3.5-397B-A17B", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2026-01", + release_date: "2026-02-16", + last_updated: "2026-02-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 262144, output: 8192 }, + }, + "qwen/qwen3-next-80b-a3b-thinking": { + id: "qwen/qwen3-next-80b-a3b-thinking", + name: "Qwen3-Next-80B-A3B-Thinking", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-12", + release_date: "2024-12-01", + last_updated: "2025-09-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 262144, output: 16384 }, + }, + "qwen/qwq-32b": { + id: "qwen/qwq-32b", + name: "Qwq 32b", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2025-03-05", + last_updated: "2025-03-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "qwen/qwen3-next-80b-a3b-instruct": { + id: "qwen/qwen3-next-80b-a3b-instruct", + name: "Qwen3-Next-80B-A3B-Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-12", + release_date: "2024-12-01", + last_updated: "2025-09-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 262144, output: 16384 }, + }, + "qwen/qwen3-coder-480b-a35b-instruct": { + id: "qwen/qwen3-coder-480b-a35b-instruct", + name: "Qwen3 Coder 480B A35B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-23", + last_updated: "2025-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 262144, output: 66536 }, + }, + "google/gemma-2-2b-it": { + id: "google/gemma-2-2b-it", + name: "Gemma 2 2b It", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-07-16", + last_updated: "2024-07-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "google/gemma-3n-e4b-it": { + id: "google/gemma-3n-e4b-it", + name: "Gemma 3n E4b It", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-06", + release_date: "2025-06-03", + last_updated: "2025-06-03", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "google/gemma-3-1b-it": { + id: "google/gemma-3-1b-it", + name: "Gemma 3 1b It", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-03-10", + last_updated: "2025-03-10", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "google/codegemma-7b": { + id: "google/codegemma-7b", + name: "Codegemma 7b", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2024-03-21", + last_updated: "2024-03-21", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "google/gemma-4-31b-it": { + id: "google/gemma-4-31b-it", + name: "Gemma-4-31B-IT", + family: "gemma", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-04-02", + last_updated: "2026-04-02", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 256000, output: 16384 }, + }, + "google/gemma-3-12b-it": { + id: "google/gemma-3-12b-it", + name: "Gemma 3 12b It", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-03-01", + last_updated: "2025-03-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "google/codegemma-1.1-7b": { + id: "google/codegemma-1.1-7b", + name: "Codegemma 1.1 7b", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2024-04-30", + last_updated: "2024-04-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "google/gemma-3n-e2b-it": { + id: "google/gemma-3n-e2b-it", + name: "Gemma 3n E2b It", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-06", + release_date: "2025-06-12", + last_updated: "2025-06-12", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "google/gemma-2-27b-it": { + id: "google/gemma-2-27b-it", + name: "Gemma 2 27b It", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-06-24", + last_updated: "2024-06-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "google/gemma-3-27b-it": { + id: "google/gemma-3-27b-it", + name: "Gemma-3-27B-IT", + family: "gemma", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-12", + release_date: "2024-12-01", + last_updated: "2025-09-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 131072, output: 8192 }, + }, + "moonshotai/kimi-k2.5": { + id: "moonshotai/kimi-k2.5", + name: "Kimi K2.5", + family: "kimi", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-07", + release_date: "2026-01-27", + last_updated: "2026-01-27", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 262144, output: 262144 }, + }, + "moonshotai/kimi-k2-instruct": { + id: "moonshotai/kimi-k2-instruct", + name: "Kimi K2 Instruct", + family: "kimi", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-01", + release_date: "2025-01-01", + last_updated: "2025-09-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 8192 }, + }, + "moonshotai/kimi-k2.6": { + id: "moonshotai/kimi-k2.6", + name: "Kimi K2.6", + family: "kimi-k2.6", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-04-21", + last_updated: "2026-04-21", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 262144, output: 262144 }, + }, + "moonshotai/kimi-k2-instruct-0905": { + id: "moonshotai/kimi-k2-instruct-0905", + name: "Kimi K2 0905", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-09-05", + last_updated: "2025-09-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 262144, output: 262144 }, + }, + "moonshotai/kimi-k2-thinking": { + id: "moonshotai/kimi-k2-thinking", + name: "Kimi K2 Thinking", + family: "kimi-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: true, + structured_output: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-11", + last_updated: "2025-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 262144, output: 262144 }, + }, + "mistralai/mistral-medium-3.5-128b": { + id: "mistralai/mistral-medium-3.5-128b", + name: "Mistral Medium 3.5 128B", + family: "mistral-medium", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-04-29", + last_updated: "2026-04-29", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 262144, output: 262144 }, + }, + "deepseek-ai/deepseek-v4-flash": { + id: "deepseek-ai/deepseek-v4-flash", + name: "DeepSeek V4 Flash", + family: "deepseek-flash", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-05", + release_date: "2026-04-24", + last_updated: "2026-04-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.14, output: 0.28, cache_read: 0.028 }, + limit: { context: 1048576, output: 393216 }, + }, + "deepseek-ai/deepseek-v4-pro": { + id: "deepseek-ai/deepseek-v4-pro", + name: "DeepSeek V4 Pro", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-05", + release_date: "2026-04-24", + last_updated: "2026-04-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.74, output: 3.48, cache_read: 0.145 }, + limit: { context: 1048576, output: 393216 }, + }, + }, + }, + inference: { + id: "inference", + env: ["INFERENCE_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://inference.net/v1", + name: "Inference", + doc: "https://inference.net/models", + models: { + "mistral/mistral-nemo-12b-instruct": { + id: "mistral/mistral-nemo-12b-instruct", + name: "Mistral Nemo 12B Instruct", + family: "mistral-nemo", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-12", + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.038, output: 0.1 }, + limit: { context: 16000, output: 4096 }, + }, + "meta/llama-3.2-11b-vision-instruct": { + id: "meta/llama-3.2-11b-vision-instruct", + name: "Llama 3.2 11B Vision Instruct", + family: "llama", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.055, output: 0.055 }, + limit: { context: 16000, output: 4096 }, + }, + "meta/llama-3.2-1b-instruct": { + id: "meta/llama-3.2-1b-instruct", + name: "Llama 3.2 1B Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.01, output: 0.01 }, + limit: { context: 16000, output: 4096 }, + }, + "meta/llama-3.2-3b-instruct": { + id: "meta/llama-3.2-3b-instruct", + name: "Llama 3.2 3B Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.02, output: 0.02 }, + limit: { context: 16000, output: 4096 }, + }, + "meta/llama-3.1-8b-instruct": { + id: "meta/llama-3.1-8b-instruct", + name: "Llama 3.1 8B Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.025, output: 0.025 }, + limit: { context: 16000, output: 4096 }, + }, + "qwen/qwen-2.5-7b-vision-instruct": { + id: "qwen/qwen-2.5-7b-vision-instruct", + name: "Qwen 2.5 7B Vision Instruct", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-12", + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.2 }, + limit: { context: 125000, output: 4096 }, + }, + "qwen/qwen3-embedding-4b": { + id: "qwen/qwen3-embedding-4b", + name: "Qwen 3 Embedding 4B", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + knowledge: "2024-12", + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.01, output: 0 }, + limit: { context: 32000, output: 2048 }, + }, + "google/gemma-3": { + id: "google/gemma-3", + name: "Google Gemma 3", + family: "gemma", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-12", + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.3 }, + limit: { context: 125000, output: 4096 }, + }, + "osmosis/osmosis-structure-0.6b": { + id: "osmosis/osmosis-structure-0.6b", + name: "Osmosis Structure 0.6B", + family: "osmosis", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-12", + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.5 }, + limit: { context: 4000, output: 2048 }, + }, + }, + }, + inception: { + id: "inception", + env: ["INCEPTION_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.inceptionlabs.ai/v1/", + name: "Inception", + doc: "https://platform.inceptionlabs.ai/docs", + models: { + "mercury-edit-2": { + id: "mercury-edit-2", + name: "Mercury Edit 2", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2026-03-30", + last_updated: "2026-03-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 0.75, cache_read: 0.025 }, + limit: { context: 128000, output: 8192 }, + }, + "mercury-2": { + id: "mercury-2", + name: "Mercury 2", + family: "mercury", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01-01", + release_date: "2026-02-24", + last_updated: "2026-02-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 0.75, cache_read: 0.025 }, + limit: { context: 128000, output: 50000 }, + }, + }, + }, + openai: { + id: "openai", + env: ["OPENAI_API_KEY"], + npm: "@ai-sdk/openai", + name: "OpenAI", + doc: "https://platform.openai.com/docs/models", + models: { + "gpt-5.1-codex-max": { + id: "gpt-5.1-codex-max", + name: "GPT-5.1 Codex Max", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "gpt-4o-2024-05-13": { + id: "gpt-4o-2024-05-13", + name: "GPT-4o (2024-05-13)", + 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-05-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 15 }, + limit: { context: 128000, output: 4096 }, + }, + "o1-mini": { + id: "o1-mini", + name: "o1-mini", + family: "o-mini", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: true, + temperature: false, + knowledge: "2023-09", + release_date: "2024-09-12", + last_updated: "2024-09-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 4.4, cache_read: 0.55 }, + limit: { context: 128000, output: 65536 }, + }, + "gpt-5.2-pro": { + id: "gpt-5.2-pro", + name: "GPT-5.2 Pro", + family: "gpt-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: false, + knowledge: "2025-08-31", + release_date: "2025-12-11", + last_updated: "2025-12-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 21, output: 168 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "text-embedding-3-large": { + id: "text-embedding-3-large", + name: "text-embedding-3-large", + family: "text-embedding", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + knowledge: "2024-01", + release_date: "2024-01-25", + last_updated: "2024-01-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.13, output: 0 }, + limit: { context: 8191, output: 3072 }, + }, + "gpt-5.3-chat-latest": { + id: "gpt-5.3-chat-latest", + name: "GPT-5.3 Chat (latest)", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-08-31", + release_date: "2026-03-03", + last_updated: "2026-03-03", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 128000, output: 16384 }, + }, + "gpt-5.5": { + id: "gpt-5.5", + name: "GPT-5.5", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-12-01", + release_date: "2026-04-23", + last_updated: "2026-04-23", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 30, cache_read: 0.5, context_over_200k: { input: 10, output: 45, cache_read: 1 } }, + limit: { context: 1050000, input: 922000, output: 128000 }, + experimental: { + modes: { + fast: { + cost: { input: 12.5, output: 75, cache_read: 1.25 }, + provider: { body: { service_tier: "priority" } }, + }, + }, + }, + }, + "gpt-5-mini": { + id: "gpt-5-mini", + name: "GPT-5 Mini", + family: "gpt-mini", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-05-30", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 2, cache_read: 0.025 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "gpt-5-nano": { + id: "gpt-5-nano", + name: "GPT-5 Nano", + family: "gpt-nano", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-05-30", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.05, output: 0.4, cache_read: 0.005 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "gpt-5.3-codex": { + id: "gpt-5.3-codex", + name: "GPT-5.3 Codex", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-02-05", + last_updated: "2026-02-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "gpt-4-turbo": { + id: "gpt-4-turbo", + name: "GPT-4 Turbo", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + knowledge: "2023-12", + release_date: "2023-11-06", + last_updated: "2024-04-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 10, output: 30 }, + limit: { context: 128000, output: 4096 }, + }, + "text-embedding-ada-002": { + id: "text-embedding-ada-002", + name: "text-embedding-ada-002", + family: "text-embedding", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + knowledge: "2022-12", + release_date: "2022-12-15", + last_updated: "2022-12-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0 }, + limit: { context: 8192, output: 1536 }, + }, + "gpt-5.2": { + id: "gpt-5.2", + name: "GPT-5.2", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2025-12-11", + last_updated: "2025-12-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "o3-pro": { + id: "o3-pro", + name: "o3-pro", + family: "o-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-05", + release_date: "2025-06-10", + last_updated: "2025-06-10", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 20, output: 80 }, + limit: { context: 200000, output: 100000 }, + }, + "gpt-4o-mini": { + id: "gpt-4o-mini", + name: "GPT-4o mini", + family: "gpt-mini", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2023-09", + release_date: "2024-07-18", + last_updated: "2024-07-18", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.6, cache_read: 0.08 }, + limit: { context: 128000, output: 16384 }, + }, + "o4-mini-deep-research": { + id: "o4-mini-deep-research", + name: "o4-mini-deep-research", + family: "o-mini", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-05", + release_date: "2024-06-26", + last_updated: "2024-06-26", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 8, cache_read: 0.5 }, + limit: { context: 200000, output: 100000 }, + }, + "gpt-5.4-mini": { + id: "gpt-5.4-mini", + name: "GPT-5.4 mini", + family: "gpt-mini", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-17", + last_updated: "2026-03-17", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.75, output: 4.5, cache_read: 0.075 }, + limit: { context: 400000, input: 272000, output: 128000 }, + experimental: { + modes: { + fast: { + cost: { input: 1.5, output: 9, cache_read: 0.15 }, + provider: { body: { service_tier: "priority" } }, + }, + }, + }, + }, + "o4-mini": { + id: "o4-mini", + name: "o4-mini", + family: "o-mini", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-05", + release_date: "2025-04-16", + last_updated: "2025-04-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 4.4, cache_read: 0.28 }, + limit: { context: 200000, output: 100000 }, + }, + "gpt-5.4-nano": { + id: "gpt-5.4-nano", + name: "GPT-5.4 nano", + family: "gpt-nano", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-17", + last_updated: "2026-03-17", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 1.25, cache_read: 0.02 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "gpt-image-1": { + id: "gpt-image-1", + name: "gpt-image-1", + family: "gpt-image", + attachment: true, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2025-04-24", + last_updated: "2025-04-24", + modalities: { input: ["text", "image"], output: ["image"] }, + open_weights: false, + limit: { context: 0, input: 0, output: 0 }, + }, + "gpt-5.2-codex": { + id: "gpt-5.2-codex", + name: "GPT-5.2 Codex", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2025-12-11", + last_updated: "2025-12-11", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "gpt-5.2-chat-latest": { + id: "gpt-5.2-chat-latest", + name: "GPT-5.2 Chat", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2025-12-11", + last_updated: "2025-12-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 128000, output: 16384 }, + }, + "gpt-5.1-codex-mini": { + id: "gpt-5.1-codex-mini", + name: "GPT-5.1 Codex mini", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 2, cache_read: 0.025 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "o1-preview": { + id: "o1-preview", + name: "o1-preview", + family: "o", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + knowledge: "2023-09", + release_date: "2024-09-12", + last_updated: "2024-09-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 60, cache_read: 7.5 }, + limit: { context: 128000, output: 32768 }, + }, + "gpt-4o-2024-08-06": { + id: "gpt-4o-2024-08-06", + name: "GPT-4o (2024-08-06)", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2023-09", + release_date: "2024-08-06", + last_updated: "2024-08-06", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 10, cache_read: 1.25 }, + limit: { context: 128000, output: 16384 }, + }, + "gpt-5.1": { + id: "gpt-5.1", + name: "GPT-5.1", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.13 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "gpt-image-1-mini": { + id: "gpt-image-1-mini", + name: "gpt-image-1-mini", + family: "gpt-image", + attachment: true, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2025-09-26", + last_updated: "2025-09-26", + modalities: { input: ["text", "image"], output: ["text", "image"] }, + open_weights: false, + limit: { context: 0, input: 0, output: 0 }, + }, + o1: { + id: "o1", + name: "o1", + family: "o", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2023-09", + release_date: "2024-12-05", + last_updated: "2024-12-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 60, cache_read: 7.5 }, + limit: { context: 200000, output: 100000 }, + }, + "gpt-5.4-pro": { + id: "gpt-5.4-pro", + name: "GPT-5.4 Pro", + family: "gpt-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-05", + last_updated: "2026-03-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 30, output: 180, context_over_200k: { input: 60, output: 270 } }, + limit: { context: 1050000, input: 922000, output: 128000 }, + }, + "gpt-3.5-turbo": { + id: "gpt-3.5-turbo", + name: "GPT-3.5-turbo", + family: "gpt", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + knowledge: "2021-09-01", + release_date: "2023-03-01", + last_updated: "2023-11-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 1.5, cache_read: 1.25 }, + limit: { context: 16385, output: 4096 }, + }, + "o3-deep-research": { + id: "o3-deep-research", + name: "o3-deep-research", + family: "o", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-05", + release_date: "2024-06-26", + last_updated: "2024-06-26", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 10, output: 40, cache_read: 2.5 }, + limit: { context: 200000, output: 100000 }, + }, + "o3-mini": { + id: "o3-mini", + name: "o3-mini", + family: "o-mini", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-05", + release_date: "2024-12-20", + last_updated: "2025-01-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 4.4, cache_read: 0.55 }, + limit: { context: 200000, output: 100000 }, + }, + "text-embedding-3-small": { + id: "text-embedding-3-small", + name: "text-embedding-3-small", + family: "text-embedding", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + knowledge: "2024-01", + release_date: "2024-01-25", + last_updated: "2024-01-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.02, output: 0 }, + limit: { context: 8191, output: 1536 }, + }, + "o1-pro": { + id: "o1-pro", + name: "o1-pro", + family: "o-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2023-09", + release_date: "2025-03-19", + last_updated: "2025-03-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 150, output: 600 }, + limit: { context: 200000, output: 100000 }, + }, + "gpt-4": { + id: "gpt-4", + name: "GPT-4", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + knowledge: "2023-11", + release_date: "2023-11-06", + last_updated: "2024-04-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 30, output: 60 }, + limit: { context: 8192, output: 8192 }, + }, + "gpt-5-codex": { + id: "gpt-5-codex", + name: "GPT-5-Codex", + family: "gpt-codex", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-09-15", + last_updated: "2025-09-15", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "gpt-5.4": { + id: "gpt-5.4", + name: "GPT-5.4", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-05", + last_updated: "2026-03-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 2.5, + output: 15, + cache_read: 0.25, + context_over_200k: { input: 5, output: 22.5, cache_read: 0.5 }, + }, + limit: { context: 1050000, input: 922000, output: 128000 }, + experimental: { + modes: { + fast: { cost: { input: 5, output: 30, cache_read: 0.5 }, provider: { body: { service_tier: "priority" } } }, + }, + }, + }, + "gpt-5.1-chat-latest": { + id: "gpt-5.1-chat-latest", + name: "GPT-5.1 Chat", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 128000, output: 16384 }, + }, + "gpt-5.3-codex-spark": { + id: "gpt-5.3-codex-spark", + name: "GPT-5.3 Codex Spark", + family: "gpt-codex-spark", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-02-05", + last_updated: "2026-02-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 128000, input: 100000, output: 32000 }, + }, + "chatgpt-image-latest": { + id: "chatgpt-image-latest", + name: "chatgpt-image-latest", + family: "gpt-image", + attachment: true, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2025-12-16", + last_updated: "2025-12-16", + modalities: { input: ["text", "image"], output: ["text", "image"] }, + open_weights: false, + limit: { context: 0, input: 0, output: 0 }, + }, + "gpt-4.1-nano": { + id: "gpt-4.1-nano", + name: "GPT-4.1 nano", + family: "gpt-nano", + 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"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4, cache_read: 0.03 }, + limit: { context: 1047576, output: 32768 }, + }, + o3: { + id: "o3", + name: "o3", + family: "o", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-05", + release_date: "2025-04-16", + last_updated: "2025-04-16", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 8, cache_read: 0.5 }, + limit: { context: 200000, output: 100000 }, + }, + "gpt-5-pro": { + id: "gpt-5-pro", + name: "GPT-5 Pro", + family: "gpt-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-10-06", + last_updated: "2025-10-06", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 120 }, + limit: { context: 400000, input: 272000, output: 272000 }, + }, + "gpt-4o": { + id: "gpt-4o", + name: "GPT-4o", + 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, + cost: { input: 2.5, output: 10, cache_read: 1.25 }, + limit: { context: 128000, output: 16384 }, + }, + "gpt-5": { + id: "gpt-5", + name: "GPT-5", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "gpt-5-chat-latest": { + id: "gpt-5-chat-latest", + name: "GPT-5 Chat (latest)", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: false, + structured_output: true, + temperature: true, + knowledge: "2024-09-30", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "gpt-image-1.5": { + id: "gpt-image-1.5", + name: "gpt-image-1.5", + family: "gpt-image", + attachment: true, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2025-11-25", + last_updated: "2025-11-25", + modalities: { input: ["text", "image"], output: ["text", "image"] }, + open_weights: false, + limit: { context: 0, input: 0, output: 0 }, + }, + "gpt-5.5-pro": { + id: "gpt-5.5-pro", + name: "GPT-5.5 Pro", + family: "gpt-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-12-01", + release_date: "2026-04-23", + last_updated: "2026-04-23", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 30, output: 180, context_over_200k: { input: 60, output: 270 } }, + limit: { context: 1050000, input: 922000, output: 128000 }, + }, + "gpt-4.1": { + id: "gpt-4.1", + name: "GPT-4.1", + 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, + cost: { input: 2, output: 8, cache_read: 0.5 }, + limit: { context: 1047576, output: 32768 }, + }, + "gpt-4.1-mini": { + id: "gpt-4.1-mini", + name: "GPT-4.1 mini", + family: "gpt-mini", + 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, + cost: { input: 0.4, output: 1.6, cache_read: 0.1 }, + limit: { context: 1047576, output: 32768 }, + }, + "gpt-5.1-codex": { + id: "gpt-5.1-codex", + name: "GPT-5.1 Codex", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "gpt-4o-2024-11-20": { + id: "gpt-4o-2024-11-20", + name: "GPT-4o (2024-11-20)", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2023-09", + release_date: "2024-11-20", + last_updated: "2024-11-20", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 10, cache_read: 1.25 }, + limit: { context: 128000, output: 16384 }, + }, + }, + }, + requesty: { + id: "requesty", + env: ["REQUESTY_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://router.requesty.ai/v1", + name: "Requesty", + doc: "https://requesty.ai/solution/llm-routing/models", + models: { + "xai/grok-4-fast": { + id: "xai/grok-4-fast", + name: "Grok 4 Fast", + family: "grok", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-09-19", + last_updated: "2025-09-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5, cache_read: 0.05, cache_write: 0.2 }, + limit: { context: 2000000, output: 64000 }, + }, + "xai/grok-4": { + id: "xai/grok-4", + name: "Grok 4", + family: "grok", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-09-09", + last_updated: "2025-09-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.75, cache_write: 3 }, + limit: { context: 256000, output: 64000 }, + }, + "openai/gpt-5.1-codex-max": { + id: "openai/gpt-5.1-codex-max", + name: "GPT-5.1-Codex-Max", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-09-30", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 9, cache_read: 0.11 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-5-chat": { + id: "openai/gpt-5-chat", + name: "GPT-5 Chat (latest)", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: false, + structured_output: true, + temperature: true, + knowledge: "2024-09-30", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-5.2-pro": { + id: "openai/gpt-5.2-pro", + name: "GPT-5.2 Pro", + family: "gpt-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2025-12-11", + last_updated: "2025-12-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 21, output: 168 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-5-mini": { + id: "openai/gpt-5-mini", + name: "GPT-5 Mini", + family: "gpt-mini", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-05-30", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 2, cache_read: 0.03 }, + limit: { context: 128000, output: 32000 }, + }, + "openai/gpt-5-nano": { + id: "openai/gpt-5-nano", + name: "GPT-5 Nano", + family: "gpt-nano", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-05-30", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.05, output: 0.4, cache_read: 0.01 }, + limit: { context: 16000, output: 4000 }, + }, + "openai/gpt-5.3-codex": { + id: "openai/gpt-5.3-codex", + name: "GPT-5.3-Codex", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-02-24", + last_updated: "2026-02-24", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-4o-mini": { + id: "openai/gpt-4o-mini", + name: "GPT-4o Mini", + family: "gpt-mini", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2024-07-18", + last_updated: "2024-07-18", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.6, cache_read: 0.08 }, + limit: { context: 128000, output: 16384 }, + }, + "openai/gpt-5.1-chat": { + id: "openai/gpt-5.1-chat", + name: "GPT-5.1 Chat", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-09-30", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 128000, output: 16384 }, + }, + "openai/o4-mini": { + id: "openai/o4-mini", + name: "o4 Mini", + family: "o-mini", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-06", + release_date: "2025-04-16", + last_updated: "2025-04-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 4.4, cache_read: 0.28 }, + limit: { context: 200000, output: 100000 }, + }, + "openai/gpt-5.2-codex": { + id: "openai/gpt-5.2-codex", + name: "GPT-5.2-Codex", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-08-31", + release_date: "2026-01-14", + last_updated: "2026-01-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-5.1-codex-mini": { + id: "openai/gpt-5.1-codex-mini", + name: "GPT-5.1-Codex-Mini", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-09-30", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 2, cache_read: 0.025 }, + limit: { context: 400000, output: 100000 }, + }, + "openai/gpt-5-image": { + id: "openai/gpt-5-image", + name: "GPT-5 Image", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-10-01", + release_date: "2025-10-14", + last_updated: "2025-10-14", + modalities: { input: ["text", "image", "pdf"], output: ["text", "image"] }, + open_weights: false, + cost: { input: 5, output: 10, cache_read: 1.25 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-5.1": { + id: "openai/gpt-5.1", + name: "GPT-5.1", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-09-30", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-5.4-pro": { + id: "openai/gpt-5.4-pro", + name: "GPT-5.4 Pro", + family: "gpt-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-05", + last_updated: "2026-03-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 30, output: 180, cache_read: 30 }, + limit: { context: 1050000, input: 922000, output: 128000 }, + }, + "openai/gpt-5-codex": { + id: "openai/gpt-5-codex", + name: "GPT-5 Codex", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-10-01", + release_date: "2025-09-15", + last_updated: "2025-09-15", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-5": { + id: "openai/gpt-5", + name: "GPT-5", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "audio", "image", "video"], output: ["text", "audio", "image"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.13 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-4.1-mini": { + id: "openai/gpt-4.1-mini", + name: "GPT-4.1 Mini", + family: "gpt-mini", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-04-14", + last_updated: "2025-04-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 1.6, cache_read: 0.1 }, + limit: { context: 1047576, output: 32768 }, + }, + "openai/gpt-5.1-codex": { + id: "openai/gpt-5.1-codex", + name: "GPT-5.1-Codex", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-09-30", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 400000, output: 128000 }, + }, + "google/gemini-3-flash-preview": { + id: "google/gemini-3-flash-preview", + name: "Gemini 3 Flash", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-12-17", + last_updated: "2025-12-17", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 3, cache_read: 0.05, cache_write: 1 }, + limit: { context: 1048576, output: 65536 }, + }, + "google/gemini-3-pro-preview": { + id: "google/gemini-3-pro-preview", + name: "Gemini 3 Pro", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-11-18", + last_updated: "2025-11-18", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 12, cache_read: 0.2, cache_write: 4.5 }, + limit: { context: 1048576, output: 65536 }, + }, + "google/gemini-2.5-flash": { + id: "google/gemini-2.5-flash", + name: "Gemini 2.5 Flash", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-06-17", + last_updated: "2025-06-17", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 2.5, cache_read: 0.075, cache_write: 0.55 }, + limit: { context: 1048576, output: 65536 }, + }, + "anthropic/claude-haiku-4-5": { + id: "anthropic/claude-haiku-4-5", + name: "Claude Haiku 4.5", + family: "claude-haiku", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-02-01", + release_date: "2025-10-15", + last_updated: "2025-10-15", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 5, cache_read: 0.1, cache_write: 1.25 }, + limit: { context: 200000, output: 62000 }, + }, + "anthropic/claude-sonnet-4-6": { + id: "anthropic/claude-sonnet-4-6", + name: "Claude Sonnet 4.6", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-08-31", + release_date: "2026-02-17", + last_updated: "2026-02-17", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { + input: 3, + output: 15, + cache_read: 0.3, + cache_write: 3.75, + context_over_200k: { input: 6, output: 22.5, cache_read: 0.6, cache_write: 7.5 }, + }, + limit: { context: 1000000, output: 128000 }, + }, + "anthropic/claude-3-7-sonnet": { + id: "anthropic/claude-3-7-sonnet", + name: "Claude Sonnet 3.7", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-01", + release_date: "2025-02-19", + last_updated: "2025-02-19", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + }, + "anthropic/claude-opus-4-5": { + id: "anthropic/claude-opus-4-5", + name: "Claude Opus 4.5", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-11-24", + last_updated: "2025-11-24", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 200000, output: 64000 }, + }, + "anthropic/claude-opus-4": { + id: "anthropic/claude-opus-4", + name: "Claude Opus 4", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 32000 }, + }, + "anthropic/claude-opus-4-6": { + id: "anthropic/claude-opus-4-6", + name: "Claude Opus 4.6", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-05-31", + release_date: "2026-02-05", + last_updated: "2026-02-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 5, + output: 25, + cache_read: 0.5, + cache_write: 6.25, + context_over_200k: { input: 10, output: 37.5, cache_read: 1, cache_write: 12.5 }, + }, + limit: { context: 1000000, output: 128000 }, + }, + "openai/gpt-5.2-chat": { + id: "openai/gpt-5.2-chat", + name: "GPT-5.2 Chat", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2025-12-11", + last_updated: "2025-12-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 128000, output: 16384 }, + }, + "openai/gpt-5.2": { + id: "openai/gpt-5.2", + name: "GPT-5.2", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2025-12-11", + last_updated: "2025-12-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-5.4": { + id: "openai/gpt-5.4", + name: "GPT-5.4", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-05", + last_updated: "2026-03-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 2.5, + output: 15, + cache_read: 0.25, + context_over_200k: { input: 5, output: 22.5, cache_read: 0.5 }, + }, + limit: { context: 1050000, input: 922000, output: 128000 }, + }, + "openai/gpt-5-pro": { + id: "openai/gpt-5-pro", + name: "GPT-5 Pro", + family: "gpt-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-10-06", + last_updated: "2025-10-06", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 120 }, + limit: { context: 400000, output: 272000 }, + }, + "openai/gpt-4.1": { + id: "openai/gpt-4.1", + name: "GPT-4.1", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-04-14", + last_updated: "2025-04-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 8, cache_read: 0.5 }, + limit: { context: 1047576, output: 32768 }, + }, + "google/gemini-2.5-pro": { + id: "google/gemini-2.5-pro", + name: "Gemini 2.5 Pro", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-03-20", + last_updated: "2025-06-05", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 1.25, + output: 10, + cache_read: 0.31, + cache_write: 2.375, + context_over_200k: { input: 2.5, output: 15, cache_read: 0.25 }, + }, + limit: { context: 1048576, output: 65536 }, + }, + "anthropic/claude-opus-4-1": { + id: "anthropic/claude-opus-4-1", + name: "Claude Opus 4.1", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 32000 }, + }, + "anthropic/claude-sonnet-4": { + id: "anthropic/claude-sonnet-4", + name: "Claude Sonnet 4", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + }, + "anthropic/claude-sonnet-4-5": { + id: "anthropic/claude-sonnet-4-5", + name: "Claude Sonnet 4.5", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07-31", + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 1000000, output: 64000 }, + }, + }, + }, + digitalocean: { + id: "digitalocean", + env: ["DIGITALOCEAN_ACCESS_TOKEN"], + npm: "@ai-sdk/openai-compatible", + api: "https://inference.do-ai.run/v1", + name: "DigitalOcean", + doc: "https://docs.digitalocean.com/products/gradient-ai-platform/details/models/", + models: { + "openai-gpt-4o-mini": { + id: "openai-gpt-4o-mini", + name: "GPT-4o mini", + family: "gpt-mini", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2023-09", + release_date: "2024-07-18", + last_updated: "2024-07-18", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.6, cache_read: 0.075 }, + limit: { context: 128000, output: 16384 }, + }, + "multi-qa-mpnet-base-dot-v1": { + id: "multi-qa-mpnet-base-dot-v1", + name: "Multi-QA-mpnet-base-dot-v1", + family: "text-embedding", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2021-08-30", + last_updated: "2026-04-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.009, output: 0 }, + limit: { context: 512, output: 768 }, + }, + "kimi-k2.5": { + id: "kimi-k2.5", + name: "Kimi K2.5", + family: "kimi", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: false, + knowledge: "2025-01", + release_date: "2026-01", + last_updated: "2026-04-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.5, output: 2.7 }, + limit: { context: 262144, output: 32768 }, + }, + "nemotron-3-nano-omni": { + id: "nemotron-3-nano-omni", + name: "Nemotron Nano 3 Omni", + family: "nemotron", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-04-28", + last_updated: "2026-04-30", + modalities: { input: ["text", "image", "video", "audio"], output: ["text"] }, + open_weights: true, + cost: { input: 0.5, output: 0.9 }, + limit: { context: 65536, output: 65536 }, + }, + "llama3-8b-instruct": { + id: "llama3-8b-instruct", + name: "Llama 3.1 Instruct (8B)", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.198, output: 0.198 }, + limit: { context: 131072, output: 131072 }, + }, + "anthropic-claude-opus-4.7": { + id: "anthropic-claude-opus-4.7", + name: "Claude Opus 4.7", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2026-01-31", + release_date: "2026-04-16", + last_updated: "2026-04-16", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 1000000, output: 128000 }, + }, + "anthropic-claude-sonnet-4": { + id: "anthropic-claude-sonnet-4", + name: "Claude Sonnet 4", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 3, + output: 15, + cache_read: 0.3, + cache_write: 3.75, + context_over_200k: { input: 6, output: 22.5, cache_read: 0.3, cache_write: 3.75 }, + }, + limit: { context: 1000000, output: 64000 }, + }, + "wan2-2-t2v-a14b": { + id: "wan2-2-t2v-a14b", + name: "Wan2.2-T2V-A14B", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2025-07-28", + last_updated: "2026-04-30", + modalities: { input: ["text"], output: ["video"] }, + open_weights: true, + cost: { input: 0.6, output: 0 }, + limit: { context: 100, output: 1 }, + }, + "qwen-2.5-14b-instruct": { + id: "qwen-2.5-14b-instruct", + name: "Qwen 2.5 14B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-09", + release_date: "2024-09-19", + last_updated: "2024-09-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + limit: { context: 131072, output: 131072 }, + }, + "openai-gpt-5.4": { + id: "openai-gpt-5.4", + name: "GPT-5.4", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-05", + last_updated: "2026-03-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 15, cache_read: 0.25 }, + limit: { context: 1000000, output: 128000 }, + }, + "qwen3.5-397b-a17b": { + id: "qwen3.5-397b-a17b", + name: "Qwen 3.5 397B A17B", + family: "qwen3.5", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-02-15", + last_updated: "2026-04-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.55, output: 3.5 }, + limit: { context: 262144, output: 81920 }, + }, + "openai-o3": { + id: "openai-o3", + name: "o3", + family: "o", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-05", + release_date: "2025-04-16", + last_updated: "2025-04-16", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 8, cache_read: 0.5 }, + limit: { context: 200000, output: 100000 }, + }, + "e5-large-v2": { + id: "e5-large-v2", + name: "E5 Large v2", + family: "text-embedding", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2023-05-19", + last_updated: "2026-04-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.02, output: 0 }, + limit: { context: 512, output: 1024 }, + }, + "openai-gpt-5.2-pro": { + id: "openai-gpt-5.2-pro", + name: "GPT-5.2 pro", + family: "gpt-pro", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2025-12-11", + last_updated: "2025-12-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 21, output: 168 }, + limit: { context: 400000, output: 128000 }, + }, + "glm-5": { + id: "glm-5", + name: "GLM 5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + release_date: "2026-02-11", + last_updated: "2026-04-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 3.2 }, + limit: { context: 202752, output: 128000 }, + }, + "openai-gpt-5.4-nano": { + id: "openai-gpt-5.4-nano", + name: "GPT-5.4 nano", + family: "gpt-nano", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-17", + last_updated: "2026-03-17", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 1.25, cache_read: 0.02 }, + limit: { context: 400000, output: 128000 }, + }, + "mistral-7b-instruct-v0.3": { + id: "mistral-7b-instruct-v0.3", + name: "Mistral 7B Instruct v0.3", + family: "mistral", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-05-22", + last_updated: "2024-05-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + limit: { context: 32768, output: 32768 }, + }, + "llama3.3-70b-instruct": { + id: "llama3.3-70b-instruct", + name: "Llama 3.3 Instruct 70B", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.65, output: 0.65 }, + limit: { context: 128000, output: 128000 }, + }, + "mistral-3-14B": { + id: "mistral-3-14B", + name: "Ministral 3 14B Instruct", + family: "ministral", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-12-15", + last_updated: "2026-04-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.2 }, + limit: { context: 262144, output: 128000 }, + }, + "deepseek-r1-distill-llama-70b": { + id: "deepseek-r1-distill-llama-70b", + name: "DeepSeek R1 Distill Llama 70B", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-01-30", + last_updated: "2025-01-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.99, output: 0.99 }, + limit: { context: 131072, output: 32768 }, + }, + "alibaba-qwen3-32b": { + id: "alibaba-qwen3-32b", + name: "Qwen3-32B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-04-30", + last_updated: "2026-04-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.25, output: 0.55 }, + limit: { context: 131000, output: 40960 }, + }, + "anthropic-claude-opus-4.5": { + id: "anthropic-claude-opus-4.5", + name: "Claude Opus 4.5", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-11-24", + last_updated: "2025-11-24", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 200000, output: 64000 }, + }, + "openai-o1": { + id: "openai-o1", + name: "o1", + family: "o", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2023-09", + release_date: "2024-12-05", + last_updated: "2024-12-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 60, cache_read: 7.5 }, + limit: { context: 200000, output: 100000 }, + }, + "anthropic-claude-3-opus": { + id: "anthropic-claude-3-opus", + name: "Claude 3 Opus", + family: "claude-opus", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-08", + release_date: "2024-02-29", + last_updated: "2024-02-29", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 4096 }, + status: "deprecated", + }, + "stable-diffusion-3.5-large": { + id: "stable-diffusion-3.5-large", + name: "Stable Diffusion 3.5 Large", + family: "stable-diffusion", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2024-10-22", + last_updated: "2026-04-30", + modalities: { input: ["text"], output: ["image"] }, + open_weights: true, + cost: { input: 0.08, output: 0 }, + limit: { context: 256, output: 1 }, + }, + "openai-gpt-5-nano": { + id: "openai-gpt-5-nano", + name: "GPT-5 nano", + family: "gpt-nano", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-05-30", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.05, output: 0.4, cache_read: 0.005 }, + limit: { context: 400000, output: 128000 }, + }, + "llama-4-maverick": { + id: "llama-4-maverick", + name: "Llama 4 Maverick 17B 128E Instruct", + family: "llama", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-08", + release_date: "2025-04-05", + last_updated: "2026-04-30", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.25, output: 0.87 }, + limit: { context: 1000000, output: 16384 }, + }, + "anthropic-claude-4.5-sonnet": { + id: "anthropic-claude-4.5-sonnet", + name: "Claude Sonnet 4.5", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07-31", + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 3, + output: 15, + cache_read: 0.3, + cache_write: 3.75, + context_over_200k: { input: 6, output: 22.5, cache_read: 0.3, cache_write: 3.75 }, + }, + limit: { context: 1000000, output: 64000 }, + }, + "qwen3-embedding-0.6b": { + id: "qwen3-embedding-0.6b", + name: "Qwen3 Embedding 0.6B", + family: "text-embedding", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2025-06-03", + last_updated: "2026-04-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.04, output: 0 }, + limit: { context: 8000, output: 1024 }, + status: "beta", + }, + "anthropic-claude-4.5-haiku": { + id: "anthropic-claude-4.5-haiku", + name: "Claude Haiku 4.5", + family: "claude-haiku", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-02-28", + release_date: "2025-10-15", + last_updated: "2025-10-15", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 5, cache_read: 1, cache_write: 1.25 }, + limit: { context: 200000, output: 64000 }, + }, + "gte-large-en-v1.5": { + id: "gte-large-en-v1.5", + name: "GTE Large (v1.5)", + family: "text-embedding", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2024-03-27", + last_updated: "2026-04-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.09, output: 0 }, + limit: { context: 8192, output: 1024 }, + }, + "openai-gpt-4.1": { + id: "openai-gpt-4.1", + name: "GPT-4.1", + 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, + cost: { input: 2, output: 8, cache_read: 0.5 }, + limit: { context: 1047576, output: 32768 }, + }, + "anthropic-claude-3.5-haiku": { + id: "anthropic-claude-3.5-haiku", + name: "Claude 3.5 Haiku", + family: "claude-haiku", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2024-11-05", + last_updated: "2024-11-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.8, output: 4, cache_read: 0.08, cache_write: 1 }, + limit: { context: 200000, output: 8192 }, + status: "deprecated", + }, + "openai-gpt-5.2": { + id: "openai-gpt-5.2", + name: "GPT-5.2", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2025-12-11", + last_updated: "2025-12-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 400000, output: 128000 }, + }, + "deepseek-3.2": { + id: "deepseek-3.2", + name: "DeepSeek V3.2", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12", + release_date: "2025-12-02", + last_updated: "2026-04-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.5, output: 1.6 }, + limit: { context: 128000, output: 64000 }, + }, + "nemotron-3-nano-30b": { + id: "nemotron-3-nano-30b", + name: "Nemotron 3 Nano 30B A3B", + family: "nemotron", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-04-14", + last_updated: "2025-04-14", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + limit: { context: 262144, output: 262144 }, + }, + "anthropic-claude-opus-4": { + id: "anthropic-claude-opus-4", + name: "Claude Opus 4", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 32000 }, + }, + "openai-gpt-oss-20b": { + id: "openai-gpt-oss-20b", + name: "gpt-oss-20b", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-06", + release_date: "2025-08-05", + last_updated: "2026-04-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.05, output: 0.45 }, + limit: { context: 131072, output: 131072 }, + }, + "qwen3-coder-flash": { + id: "qwen3-coder-flash", + name: "Qwen3 Coder Flash", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-28", + last_updated: "2026-04-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.45, output: 1.7 }, + limit: { context: 262144, output: 65536 }, + }, + "openai-o3-mini": { + id: "openai-o3-mini", + name: "o3-mini", + family: "o-mini", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-05", + release_date: "2024-12-20", + last_updated: "2025-01-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 4.4, cache_read: 0.55 }, + limit: { context: 200000, output: 100000 }, + }, + "openai-gpt-oss-120b": { + id: "openai-gpt-oss-120b", + name: "gpt-oss-120b", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2024-06", + release_date: "2025-08-05", + last_updated: "2026-04-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.7 }, + limit: { context: 131072, output: 131072 }, + }, + "gemma-4-31B-it": { + id: "gemma-4-31B-it", + name: "Gemma 4 31B", + family: "gemma", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-04-22", + last_updated: "2026-04-30", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.18, output: 0.5 }, + limit: { context: 256000, output: 8192 }, + }, + "nemotron-nano-12b-v2-vl": { + id: "nemotron-nano-12b-v2-vl", + name: "Nemotron Nano 12B v2 VL", + family: "nemotron", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-12-01", + last_updated: "2026-04-30", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.6 }, + limit: { context: 128000, output: 16384 }, + }, + "anthropic-claude-4.1-opus": { + id: "anthropic-claude-4.1-opus", + name: "Claude Opus 4.1", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 32000 }, + }, + "kimi-k2.6": { + id: "kimi-k2.6", + name: "Kimi K2.6", + family: "kimi", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: false, + knowledge: "2025-01", + release_date: "2026-04-21", + last_updated: "2026-04-21", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.95, output: 4 }, + limit: { context: 262144, output: 262144 }, + }, + "openai-gpt-image-2": { + id: "openai-gpt-image-2", + name: "GPT Image 2", + family: "gpt-image", + attachment: true, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2025-04-24", + last_updated: "2025-04-24", + modalities: { input: ["text", "image"], output: ["image"] }, + open_weights: false, + limit: { context: 0, output: 0 }, + }, + "anthropic-claude-4.6-sonnet": { + id: "anthropic-claude-4.6-sonnet", + name: "Claude Sonnet 4.6", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: 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, + cost: { + input: 3, + output: 15, + cache_read: 0.3, + cache_write: 3.75, + context_over_200k: { input: 6, output: 22.5, cache_read: 0.3, cache_write: 3.75 }, + }, + limit: { context: 1000000, output: 64000 }, + }, + "openai-gpt-5-mini": { + id: "openai-gpt-5-mini", + name: "GPT-5 mini", + family: "gpt-mini", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-05-30", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 2, cache_read: 0.025 }, + limit: { context: 400000, output: 128000 }, + }, + "anthropic-claude-haiku-4.5": { + id: "anthropic-claude-haiku-4.5", + name: "Claude Haiku 4.5", + family: "claude-haiku", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-02-28", + release_date: "2025-10-15", + last_updated: "2025-10-15", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 5, cache_read: 1, cache_write: 1.25 }, + limit: { context: 200000, output: 64000 }, + }, + "deepseek-v4-pro": { + id: "deepseek-v4-pro", + name: "DeepSeek V4 Pro", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-05", + release_date: "2026-04-24", + last_updated: "2026-04-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.74, output: 3.48 }, + limit: { context: 1048576, output: 393216 }, + }, + "ministral-3-8b-instruct-2512": { + id: "ministral-3-8b-instruct-2512", + name: "Ministral 3 8B", + family: "ministral", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-12-15", + last_updated: "2025-12-15", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + limit: { context: 262144, output: 262144 }, + }, + "minimax-m2.5": { + id: "minimax-m2.5", + name: "MiniMax M2.5", + family: "minimax-m2.5", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-08", + release_date: "2026-02-12", + last_updated: "2026-04-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 204800, output: 128000 }, + status: "beta", + }, + "openai-gpt-image-1": { + id: "openai-gpt-image-1", + name: "GPT Image 1", + family: "gpt-image", + attachment: true, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2025-04-24", + last_updated: "2025-04-24", + modalities: { input: ["text", "image"], output: ["image"] }, + open_weights: false, + cost: { input: 5, output: 40, cache_read: 1.25 }, + limit: { context: 0, output: 0 }, + }, + "openai-gpt-5.5": { + id: "openai-gpt-5.5", + name: "GPT-5.5", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-12-01", + release_date: "2026-04-23", + last_updated: "2026-04-30", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 30, cache_read: 0.5, context_over_200k: { input: 10, output: 45, cache_read: 1 } }, + limit: { context: 1000000, output: 128000 }, + }, + "nvidia-nemotron-3-super-120b": { + id: "nvidia-nemotron-3-super-120b", + name: "Nemotron-3-Super-120B", + family: "nemotron", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2026-02", + release_date: "2026-03-11", + last_updated: "2026-04-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 0.65 }, + limit: { context: 256000, output: 32768 }, + status: "beta", + }, + "openai-gpt-5.4-pro": { + id: "openai-gpt-5.4-pro", + name: "GPT-5.4 pro", + family: "gpt-pro", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-05", + last_updated: "2026-03-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 30, output: 180 }, + limit: { context: 400000, output: 128000 }, + }, + "all-mini-lm-l6-v2": { + id: "all-mini-lm-l6-v2", + name: "All-MiniLM-L6-v2", + family: "text-embedding", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2021-08-30", + last_updated: "2026-04-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.009, output: 0 }, + limit: { context: 256, output: 384 }, + }, + "bge-m3": { + id: "bge-m3", + name: "BGE M3", + family: "bge", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2024-01-30", + last_updated: "2026-04-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.02, output: 0 }, + limit: { context: 8192, output: 1024 }, + }, + "openai-gpt-5.1-codex-max": { + id: "openai-gpt-5.1-codex-max", + name: "GPT-5.1 Codex Max", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 400000, output: 128000 }, + }, + "anthropic-claude-opus-4.6": { + id: "anthropic-claude-opus-4.6", + name: "Claude Opus 4.6", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-05-31", + release_date: "2026-02-05", + last_updated: "2026-03-13", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 5, + output: 25, + cache_read: 0.5, + cache_write: 6.25, + context_over_200k: { input: 10, output: 37.5, cache_read: 0.5, cache_write: 6.25 }, + }, + limit: { context: 1000000, output: 128000 }, + }, + "openai-gpt-4o": { + id: "openai-gpt-4o", + name: "GPT-4o", + 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, + cost: { input: 2.5, output: 10, cache_read: 1.25 }, + limit: { context: 128000, output: 16384 }, + }, + "openai-gpt-5.4-mini": { + id: "openai-gpt-5.4-mini", + name: "GPT-5.4 mini", + family: "gpt-mini", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-17", + last_updated: "2026-03-17", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.75, output: 4.5, cache_read: 0.075 }, + limit: { context: 400000, output: 128000 }, + }, + "openai-gpt-5": { + id: "openai-gpt-5", + name: "GPT-5", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 400000, output: 128000 }, + }, + "arcee-trinity-large-thinking": { + id: "arcee-trinity-large-thinking", + name: "Trinity Large Thinking", + family: "trinity", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-02", + last_updated: "2026-04-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.25, output: 0.9, cache_read: 0.06 }, + limit: { context: 256000, output: 128000 }, + status: "beta", + }, + "mistral-nemo-instruct-2407": { + id: "mistral-nemo-instruct-2407", + name: "Mistral Nemo Instruct", + family: "mistral", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2024-07-18", + last_updated: "2024-07-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 0.3 }, + limit: { context: 128000, output: 16384 }, + status: "deprecated", + }, + "deepseek-v3": { + id: "deepseek-v3", + name: "DeepSeek V3", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2024-12-26", + last_updated: "2025-03-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + limit: { context: 163840, output: 131072 }, + }, + "bge-reranker-v2-m3": { + id: "bge-reranker-v2-m3", + name: "BGE Reranker v2 M3", + family: "bge", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2024-03-12", + last_updated: "2026-04-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.01, output: 0 }, + limit: { context: 8192, output: 1 }, + }, + "anthropic-claude-3.7-sonnet": { + id: "anthropic-claude-3.7-sonnet", + name: "Claude 3.7 Sonnet", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-11", + release_date: "2025-02-24", + last_updated: "2025-02-24", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + status: "deprecated", + }, + "qwen3-tts-voicedesign": { + id: "qwen3-tts-voicedesign", + name: "Qwen3 TTS VoiceDesign", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2026-04-21", + last_updated: "2026-04-30", + modalities: { input: ["text"], output: ["audio"] }, + open_weights: true, + limit: { context: 32768, output: 1 }, + }, + "openai-gpt-image-1.5": { + id: "openai-gpt-image-1.5", + name: "GPT Image 1.5", + family: "gpt-image", + attachment: true, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2025-11-25", + last_updated: "2025-11-25", + modalities: { input: ["text", "image"], output: ["image"] }, + open_weights: false, + cost: { input: 5, output: 10, cache_read: 1 }, + limit: { context: 0, output: 0 }, + }, + "openai-gpt-5.3-codex": { + id: "openai-gpt-5.3-codex", + name: "GPT-5.3 Codex", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-02-05", + last_updated: "2026-02-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 400000, output: 128000 }, + }, + "anthropic-claude-3.5-sonnet": { + id: "anthropic-claude-3.5-sonnet", + name: "Claude 3.5 Sonnet", + family: "claude-sonnet", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-06-20", + last_updated: "2024-10-22", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 8192 }, + status: "deprecated", + }, + "fal-ai/fast-sdxl": { + id: "fal-ai/fast-sdxl", + name: "Fast SDXL", + family: "stable-diffusion", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2023-07-26", + last_updated: "2026-04-16", + modalities: { input: ["text"], output: ["image"] }, + open_weights: true, + limit: { context: 0, output: 0 }, + }, + "fal-ai/flux/schnell": { + id: "fal-ai/flux/schnell", + name: "FLUX.1 [schnell]", + family: "flux", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2024-08-01", + last_updated: "2026-04-16", + modalities: { input: ["text"], output: ["image"] }, + open_weights: true, + limit: { context: 0, output: 0 }, + }, + "fal-ai/elevenlabs/tts/multilingual-v2": { + id: "fal-ai/elevenlabs/tts/multilingual-v2", + name: "ElevenLabs Multilingual TTS v2", + family: "elevenlabs", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2023-08-22", + last_updated: "2026-04-16", + modalities: { input: ["text"], output: ["audio"] }, + open_weights: false, + limit: { context: 0, output: 0 }, + }, + "fal-ai/stable-audio-25/text-to-audio": { + id: "fal-ai/stable-audio-25/text-to-audio", + name: "Stable Audio 2.5 (Text-to-Audio)", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2025-10-08", + last_updated: "2026-04-16", + modalities: { input: ["text"], output: ["audio"] }, + open_weights: false, + limit: { context: 0, output: 0 }, + }, + }, + }, + vultr: { + id: "vultr", + env: ["VULTR_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.vultrinference.com/v1", + name: "Vultr", + doc: "https://api.vultrinference.com/", + models: { + "MiniMax-M2.5": { + id: "MiniMax-M2.5", + name: "MiniMax M2.5", + family: "minimax", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-09", + release_date: "2025-02-11", + last_updated: "2025-02-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 194000, output: 4096 }, + }, + "GLM-5-FP8": { + id: "GLM-5-FP8", + name: "GLM 5 FP8", + family: "glm", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-05", + release_date: "2026-02-11", + last_updated: "2026-02-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.85, output: 3.1 }, + limit: { context: 200000, output: 131072 }, + }, + "DeepSeek-V3.2": { + id: "DeepSeek-V3.2", + name: "DeepSeek V3.2", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2025-12-01", + last_updated: "2025-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.55, output: 1.65 }, + limit: { context: 127000, output: 4096 }, + }, + "gpt-oss-120b": { + id: "gpt-oss-120b", + name: "GPT OSS 120B", + family: "gpt-oss", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-06", + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 129000, output: 4096 }, + }, + "Kimi-K2.5": { + id: "Kimi-K2.5", + name: "Kimi K2 Instruct", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2026-01-27", + last_updated: "2026-01-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.55, output: 2.75 }, + limit: { context: 254000, output: 32768 }, + }, + }, + }, + "alibaba-coding-plan-cn": { + id: "alibaba-coding-plan-cn", + env: ["ALIBABA_CODING_PLAN_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://coding.dashscope.aliyuncs.com/v1", + name: "Alibaba Coding Plan (China)", + doc: "https://help.aliyun.com/zh/model-studio/coding-plan", + models: { + "qwen3-coder-plus": { + id: "qwen3-coder-plus", + name: "Qwen3 Coder Plus", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-23", + last_updated: "2025-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 1000000, output: 65536 }, + }, + "kimi-k2.5": { + id: "kimi-k2.5", + name: "Kimi K2.5", + family: "kimi", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-01", + release_date: "2026-01-27", + last_updated: "2026-01-27", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 262144, output: 32768 }, + }, + "glm-4.7": { + id: "glm-4.7", + name: "GLM-4.7", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-04", + release_date: "2025-12-22", + last_updated: "2025-12-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 202752, output: 16384 }, + }, + "glm-5": { + id: "glm-5", + name: "GLM-5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-02-11", + last_updated: "2026-02-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 202752, output: 16384 }, + }, + "MiniMax-M2.5": { + id: "MiniMax-M2.5", + name: "MiniMax-M2.5", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 196608, output: 24576 }, + }, + "qwen3.6-plus": { + id: "qwen3.6-plus", + name: "Qwen3.6 Plus", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-04-02", + last_updated: "2026-04-02", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 1000000, output: 65536 }, + }, + "qwen3-max-2026-01-23": { + id: "qwen3-max-2026-01-23", + name: "Qwen3 Max", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-01-23", + last_updated: "2026-01-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 262144, output: 32768 }, + }, + "qwen3-coder-next": { + id: "qwen3-coder-next", + name: "Qwen3 Coder Next", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-02-03", + last_updated: "2026-02-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 262144, output: 65536 }, + }, + "qwen3.5-plus": { + id: "qwen3.5-plus", + name: "Qwen3.5 Plus", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-02-16", + last_updated: "2026-02-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 1000000, output: 65536 }, + }, + }, + }, + mistral: { + id: "mistral", + env: ["MISTRAL_API_KEY"], + npm: "@ai-sdk/mistral", + name: "Mistral", + doc: "https://docs.mistral.ai/getting-started/models/", + models: { + "mistral-small-latest": { + id: "mistral-small-latest", + name: "Mistral Small (latest)", + family: "mistral-small", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-06", + release_date: "2026-03-16", + last_updated: "2026-03-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 256000, output: 256000 }, + }, + "mistral-nemo": { + id: "mistral-nemo", + name: "Mistral Nemo", + family: "mistral-nemo", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2024-07-01", + last_updated: "2024-07-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.15 }, + limit: { context: 128000, output: 128000 }, + }, + "mistral-large-2512": { + id: "mistral-large-2512", + name: "Mistral Large 3", + family: "mistral-large", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-11", + release_date: "2024-11-01", + last_updated: "2025-12-02", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.5, output: 1.5 }, + limit: { context: 262144, output: 262144 }, + }, + "labs-devstral-small-2512": { + id: "labs-devstral-small-2512", + name: "Devstral Small 2", + family: "devstral", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-12", + release_date: "2025-12-09", + last_updated: "2025-12-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 256000, output: 256000 }, + }, + "devstral-2512": { + id: "devstral-2512", + name: "Devstral 2", + family: "devstral", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-12", + release_date: "2025-12-09", + last_updated: "2025-12-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.4, output: 2 }, + limit: { context: 262144, output: 262144 }, + }, + "magistral-medium-latest": { + id: "magistral-medium-latest", + name: "Magistral Medium (latest)", + family: "magistral-medium", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-06", + release_date: "2025-03-17", + last_updated: "2025-03-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 2, output: 5 }, + limit: { context: 128000, output: 16384 }, + }, + "open-mixtral-8x7b": { + id: "open-mixtral-8x7b", + name: "Mixtral 8x7B", + family: "mixtral", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-01", + release_date: "2023-12-11", + last_updated: "2023-12-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.7, output: 0.7 }, + limit: { context: 32000, output: 32000 }, + }, + "pixtral-large-latest": { + id: "pixtral-large-latest", + name: "Pixtral Large (latest)", + family: "pixtral", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-11", + release_date: "2024-11-01", + last_updated: "2024-11-04", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 2, output: 6 }, + limit: { context: 128000, output: 128000 }, + }, + "mistral-large-2411": { + id: "mistral-large-2411", + name: "Mistral Large 2.1", + family: "mistral-large", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-11", + release_date: "2024-11-01", + last_updated: "2024-11-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 2, output: 6 }, + limit: { context: 131072, output: 16384 }, + }, + "codestral-latest": { + id: "codestral-latest", + name: "Codestral (latest)", + family: "codestral", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2024-05-29", + last_updated: "2025-01-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 0.9 }, + limit: { context: 256000, output: 4096 }, + }, + "mistral-large-latest": { + id: "mistral-large-latest", + name: "Mistral Large (latest)", + family: "mistral-large", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-11", + release_date: "2024-11-01", + last_updated: "2025-12-02", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.5, output: 1.5 }, + limit: { context: 262144, output: 262144 }, + }, + "mistral-small-2506": { + id: "mistral-small-2506", + name: "Mistral Small 3.2", + family: "mistral-small", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-03", + release_date: "2025-06-20", + last_updated: "2025-06-20", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.3 }, + limit: { context: 128000, output: 16384 }, + }, + "pixtral-12b": { + id: "pixtral-12b", + name: "Pixtral 12B", + family: "pixtral", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-09", + release_date: "2024-09-01", + last_updated: "2024-09-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.15 }, + limit: { context: 128000, output: 128000 }, + }, + "ministral-8b-latest": { + id: "ministral-8b-latest", + name: "Ministral 8B (latest)", + family: "ministral", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2024-10-01", + last_updated: "2024-10-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.1 }, + limit: { context: 128000, output: 128000 }, + }, + "mistral-embed": { + id: "mistral-embed", + name: "Mistral Embed", + family: "mistral-embed", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2023-12-11", + last_updated: "2023-12-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0 }, + limit: { context: 8000, output: 3072 }, + }, + "magistral-small": { + id: "magistral-small", + name: "Magistral Small", + family: "magistral-small", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-06", + release_date: "2025-03-17", + last_updated: "2025-03-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.5, output: 1.5 }, + limit: { context: 128000, output: 128000 }, + }, + "mistral-small-2603": { + id: "mistral-small-2603", + name: "Mistral Small 4", + family: "mistral-small", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-06", + release_date: "2026-03-16", + last_updated: "2026-03-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 256000, output: 256000 }, + }, + "ministral-3b-latest": { + id: "ministral-3b-latest", + name: "Ministral 3B (latest)", + family: "ministral", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2024-10-01", + last_updated: "2024-10-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.04, output: 0.04 }, + limit: { context: 128000, output: 128000 }, + }, + "open-mixtral-8x22b": { + id: "open-mixtral-8x22b", + name: "Mixtral 8x22B", + family: "mixtral", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-04-17", + last_updated: "2024-04-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 2, output: 6 }, + limit: { context: 64000, output: 64000 }, + }, + "mistral-medium-2604": { + id: "mistral-medium-2604", + name: "Mistral Medium 3.5", + family: "mistral-medium", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-04-29", + last_updated: "2026-04-29", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 1.5, output: 7.5 }, + limit: { context: 262144, output: 262144 }, + }, + "devstral-small-2505": { + id: "devstral-small-2505", + name: "Devstral Small 2505", + family: "devstral", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-05", + release_date: "2025-05-07", + last_updated: "2025-05-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.3 }, + limit: { context: 128000, output: 128000 }, + }, + "devstral-medium-2507": { + id: "devstral-medium-2507", + name: "Devstral Medium", + family: "devstral", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-05", + release_date: "2025-07-10", + last_updated: "2025-07-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.4, output: 2 }, + limit: { context: 128000, output: 128000 }, + }, + "open-mistral-7b": { + id: "open-mistral-7b", + name: "Mistral 7B", + family: "mistral", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2023-09-27", + last_updated: "2023-09-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.25, output: 0.25 }, + limit: { context: 8000, output: 8000 }, + }, + "devstral-medium-latest": { + id: "devstral-medium-latest", + name: "Devstral 2 (latest)", + family: "devstral", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-12", + release_date: "2025-12-02", + last_updated: "2025-12-02", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.4, output: 2 }, + limit: { context: 262144, output: 262144 }, + }, + "mistral-medium-2505": { + id: "mistral-medium-2505", + name: "Mistral Medium 3", + family: "mistral-medium", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-05", + release_date: "2025-05-07", + last_updated: "2025-05-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 2 }, + limit: { context: 131072, output: 131072 }, + }, + "devstral-small-2507": { + id: "devstral-small-2507", + name: "Devstral Small", + family: "devstral", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-05", + release_date: "2025-07-10", + last_updated: "2025-07-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.3 }, + limit: { context: 128000, output: 128000 }, + }, + "mistral-medium-2508": { + id: "mistral-medium-2508", + name: "Mistral Medium 3.1", + family: "mistral-medium", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-05", + release_date: "2025-08-12", + last_updated: "2025-08-12", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 2 }, + limit: { context: 262144, output: 262144 }, + }, + "mistral-medium-latest": { + id: "mistral-medium-latest", + name: "Mistral Medium (latest)", + family: "mistral-medium", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-04-29", + last_updated: "2026-04-29", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 1.5, output: 7.5 }, + limit: { context: 262144, output: 262144 }, + }, + }, + }, + ovhcloud: { + id: "ovhcloud", + env: ["OVHCLOUD_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://oai.endpoints.kepler.ai.cloud.ovh.net/v1", + name: "OVHcloud AI Endpoints", + doc: "https://www.ovhcloud.com/en/public-cloud/ai-endpoints/catalog//", + models: { + "meta-llama-3_3-70b-instruct": { + id: "meta-llama-3_3-70b-instruct", + name: "Meta-Llama-3_3-70B-Instruct", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-04-01", + last_updated: "2025-04-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.74, output: 0.74 }, + limit: { context: 131072, output: 131072 }, + }, + "mistral-7b-instruct-v0.3": { + id: "mistral-7b-instruct-v0.3", + name: "Mistral-7B-Instruct-v0.3", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-04-01", + last_updated: "2025-04-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.11, output: 0.11 }, + limit: { context: 65536, output: 65536 }, + }, + "qwen3-32b": { + id: "qwen3-32b", + name: "Qwen3-32B", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-07-16", + last_updated: "2025-07-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.09, output: 0.25 }, + limit: { context: 32768, output: 32768 }, + }, + "qwen2.5-vl-72b-instruct": { + id: "qwen2.5-vl-72b-instruct", + name: "Qwen2.5-VL-72B-Instruct", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: true, + temperature: true, + release_date: "2025-03-31", + last_updated: "2025-03-31", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 1.01, output: 1.01 }, + limit: { context: 32768, output: 32768 }, + }, + "qwen3-coder-30b-a3b-instruct": { + id: "qwen3-coder-30b-a3b-instruct", + name: "Qwen3-Coder-30B-A3B-Instruct", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-10-28", + last_updated: "2025-10-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.07, output: 0.26 }, + limit: { context: 262144, output: 262144 }, + }, + "gpt-oss-20b": { + id: "gpt-oss-20b", + name: "gpt-oss-20b", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-08-28", + last_updated: "2025-08-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.05, output: 0.18 }, + limit: { context: 131072, output: 131072 }, + }, + "mistral-small-3.2-24b-instruct-2506": { + id: "mistral-small-3.2-24b-instruct-2506", + name: "Mistral-Small-3.2-24B-Instruct-2506", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-07-16", + last_updated: "2025-07-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.31 }, + limit: { context: 131072, output: 131072 }, + }, + "qwen3.5-9b": { + id: "qwen3.5-9b", + name: "Qwen3.5-9B", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-02-15", + last_updated: "2026-02-15", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.15 }, + limit: { context: 262144, output: 262144 }, + }, + "gpt-oss-120b": { + id: "gpt-oss-120b", + name: "gpt-oss-120b", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + release_date: "2025-08-28", + last_updated: "2025-08-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.09, output: 0.47 }, + limit: { context: 131072, output: 131072 }, + }, + "mistral-nemo-instruct-2407": { + id: "mistral-nemo-instruct-2407", + name: "Mistral-Nemo-Instruct-2407", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-11-20", + last_updated: "2024-11-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.14, output: 0.14 }, + limit: { context: 65536, output: 65536 }, + }, + "llama-3.1-8b-instruct": { + id: "llama-3.1-8b-instruct", + name: "Llama-3.1-8B-Instruct", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-06-11", + last_updated: "2025-06-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.11, output: 0.11 }, + limit: { context: 131072, output: 131072 }, + }, + }, + }, + friendli: { + id: "friendli", + env: ["FRIENDLI_TOKEN"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.friendli.ai/serverless/v1", + name: "Friendli", + doc: "https://friendli.ai/docs/guides/serverless_endpoints/introduction", + models: { + "Qwen/Qwen3-235B-A22B-Instruct-2507": { + id: "Qwen/Qwen3-235B-A22B-Instruct-2507", + name: "Qwen3 235B A22B Instruct 2507", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-07-29", + last_updated: "2026-01-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.8 }, + limit: { context: 262144, output: 262144 }, + }, + "zai-org/GLM-5.1": { + id: "zai-org/GLM-5.1", + name: "GLM-5.1", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-04-07", + last_updated: "2026-04-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.4, output: 4.4, cache_read: 0.26 }, + limit: { context: 202752, output: 202752 }, + }, + "zai-org/GLM-5": { + id: "zai-org/GLM-5", + name: "GLM-5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 3.2, cache_read: 0.5 }, + limit: { context: 202752, output: 202752 }, + }, + "meta-llama/Llama-3.3-70B-Instruct": { + id: "meta-llama/Llama-3.3-70B-Instruct", + name: "Llama 3.3 70B Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-08-01", + last_updated: "2025-12-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 0.6 }, + limit: { context: 131072, output: 131072 }, + }, + "meta-llama/Llama-3.1-8B-Instruct": { + id: "meta-llama/Llama-3.1-8B-Instruct", + name: "Llama 3.1 8B Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-08-01", + last_updated: "2025-12-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.1 }, + limit: { context: 131072, output: 8000 }, + }, + "MiniMaxAI/MiniMax-M2.5": { + id: "MiniMaxAI/MiniMax-M2.5", + name: "MiniMax-M2.5", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2, cache_read: 0.06 }, + limit: { context: 196608, output: 196608 }, + }, + }, + }, + cortecs: { + id: "cortecs", + env: ["CORTECS_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.cortecs.ai/v1", + name: "Cortecs", + doc: "https://api.cortecs.ai/v1/models", + models: { + "minimax-m2.7": { + id: "minimax-m2.7", + name: "MiniMax-m2.7", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.47, output: 1.4 }, + limit: { context: 202752, output: 196072 }, + }, + "claude-haiku-4-5": { + id: "claude-haiku-4-5", + name: "Claude Haiku 4.5", + family: "claude-haiku", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-02-28", + release_date: "2025-10-15", + last_updated: "2025-10-15", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.09, output: 5.43 }, + limit: { context: 200000, output: 200000 }, + }, + "qwen3-235b-a22b-instruct-2507": { + id: "qwen3-235b-a22b-instruct-2507", + name: "Qwen3 235B A22B Instruct 2507", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-23", + last_updated: "2025-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.062, output: 0.408 }, + limit: { context: 131000, output: 131000 }, + }, + "kimi-k2.5": { + id: "kimi-k2.5", + name: "Kimi K2.5", + family: "kimi-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-01", + release_date: "2026-01-27", + last_updated: "2026-01-27", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.55, output: 2.76 }, + limit: { context: 256000, output: 256000 }, + }, + "deepseek-v3-0324": { + id: "deepseek-v3-0324", + name: "DeepSeek V3 0324", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2025-03-24", + last_updated: "2025-03-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.551, output: 1.654 }, + limit: { context: 128000, output: 128000 }, + }, + "glm-4.7": { + id: "glm-4.7", + name: "GLM 4.7", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-04", + release_date: "2025-12-22", + last_updated: "2025-12-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.45, output: 2.23 }, + limit: { context: 198000, output: 198000 }, + }, + "claude-opus4-7": { + id: "claude-opus4-7", + name: "Claude Opus 4.7", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2026-01-31", + release_date: "2026-04-16", + last_updated: "2026-04-16", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5.6, output: 27.99, cache_read: 0.56, cache_write: 6.99 }, + limit: { context: 1000000, output: 128000 }, + }, + "glm-5": { + id: "glm-5", + name: "GLM 5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-02-11", + last_updated: "2026-02-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.08, output: 3.44 }, + limit: { context: 202752, output: 202752 }, + }, + "nova-pro-v1": { + id: "nova-pro-v1", + name: "Nova Pro 1.0", + family: "nova-pro", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-12-03", + last_updated: "2024-12-03", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.016, output: 4.061 }, + limit: { context: 300000, output: 5000 }, + }, + "devstral-2512": { + id: "devstral-2512", + name: "Devstral 2 2512", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-12", + release_date: "2025-12-09", + last_updated: "2025-12-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 262000, output: 262000 }, + }, + "qwen3-32b": { + id: "qwen3-32b", + name: "Qwen3 32B", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-12", + release_date: "2025-04-29", + last_updated: "2025-04-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.099, output: 0.33 }, + limit: { context: 16384, output: 16384 }, + }, + "codestral-2508": { + id: "codestral-2508", + name: "Codestral 2508", + family: "mistral", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-03", + release_date: "2025-07-30", + last_updated: "2025-07-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 0.9, cache_read: 0.03 }, + limit: { context: 256000, output: 256000 }, + }, + "claude-4-5-sonnet": { + id: "claude-4-5-sonnet", + name: "Claude 4.5 Sonnet", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07-31", + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3.259, output: 16.296 }, + limit: { context: 200000, output: 200000 }, + }, + "kimi-k2-instruct": { + id: "kimi-k2-instruct", + name: "Kimi K2 Instruct", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2025-07-11", + last_updated: "2025-09-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.551, output: 2.646 }, + limit: { context: 131000, output: 131000 }, + }, + "nemotron-3-super-120b-a12b": { + id: "nemotron-3-super-120b-a12b", + name: "Nemotron 3 Super 120B A12B", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-12", + release_date: "2026-03-11", + last_updated: "2026-03-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.266, output: 0.799 }, + limit: { context: 262144, output: 262144 }, + }, + "minimax-m2": { + id: "minimax-m2", + name: "MiniMax-M2", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-11", + release_date: "2025-10-27", + last_updated: "2025-10-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.39, output: 1.57 }, + limit: { context: 400000, output: 400000 }, + }, + "gemini-2.5-pro": { + id: "gemini-2.5-pro", + name: "Gemini 2.5 Pro", + family: "gemini-pro", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-03-20", + last_updated: "2025-06-17", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.654, output: 11.024 }, + limit: { context: 1048576, output: 65535 }, + }, + "claude-opus4-6": { + id: "claude-opus4-6", + name: "Claude Opus 4.6", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-05-31", + release_date: "2026-02-05", + last_updated: "2026-03-13", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5.98, output: 29.89 }, + limit: { context: 1000000, output: 1000000 }, + }, + "devstral-small-2512": { + id: "devstral-small-2512", + name: "Devstral Small 2 2512", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-12", + release_date: "2025-12-09", + last_updated: "2025-12-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 262000, output: 262000 }, + }, + "minimax-m2.1": { + id: "minimax-m2.1", + name: "MiniMax-M2.1", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2025-12-23", + last_updated: "2025-12-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.34, output: 1.34 }, + limit: { context: 196000, output: 196000 }, + }, + "glm-5.1": { + id: "glm-5.1", + name: "GLM-5.1", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-04-14", + last_updated: "2026-04-14", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.31, output: 4.1, cache_read: 0.24 }, + limit: { context: 204800, output: 131072 }, + }, + "glm-4.5": { + id: "glm-4.5", + name: "GLM 4.5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-29", + last_updated: "2025-07-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.67, output: 2.46 }, + limit: { context: 131072, output: 131072 }, + }, + "claude-opus4-5": { + id: "claude-opus4-5", + name: "Claude Opus 4.5", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-11-24", + last_updated: "2025-11-24", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5.98, output: 29.89 }, + limit: { context: 200000, output: 200000 }, + }, + "claude-sonnet-4": { + id: "claude-sonnet-4", + name: "Claude Sonnet 4", + family: "claude-sonnet", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-03", + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3.307, output: 16.536 }, + limit: { context: 200000, output: 64000 }, + }, + "qwen3-next-80b-a3b-thinking": { + id: "qwen3-next-80b-a3b-thinking", + name: "Qwen3 Next 80B A3B Thinking", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-09-11", + last_updated: "2025-09-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.164, output: 1.311 }, + limit: { context: 128000, output: 128000 }, + }, + "glm-4.5-air": { + id: "glm-4.5-air", + name: "GLM 4.5 Air", + family: "glm-air", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-08-01", + last_updated: "2025-08-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.22, output: 1.34 }, + limit: { context: 131072, output: 131072 }, + }, + "kimi-k2.6": { + id: "kimi-k2.6", + name: "Kimi K2.6", + family: "kimi-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-04-17", + last_updated: "2026-04-17", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.81, output: 3.54, cache_read: 0.2 }, + limit: { context: 256000, output: 256000 }, + }, + "qwen3-coder-next": { + id: "qwen3-coder-next", + name: "Qwen3 Coder Next 80B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-02-04", + last_updated: "2026-02-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.158, output: 0.84 }, + limit: { context: 256000, output: 65536 }, + }, + "claude-4-6-sonnet": { + id: "claude-4-6-sonnet", + name: "Claude Sonnet 4.6", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: 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, + cost: { input: 3.59, output: 17.92 }, + limit: { context: 1000000, output: 1000000 }, + }, + "qwen3-coder-480b-a35b-instruct": { + id: "qwen3-coder-480b-a35b-instruct", + name: "Qwen3 Coder 480B A35B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-07-25", + last_updated: "2025-07-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.441, output: 1.984 }, + limit: { context: 262000, output: 262000 }, + }, + "mixtral-8x7B-instruct-v0.1": { + id: "mixtral-8x7B-instruct-v0.1", + name: "Mixtral 8x7B Instruct v0.1", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + knowledge: "2023-09", + release_date: "2023-12-11", + last_updated: "2023-12-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.438, output: 0.68 }, + limit: { context: 32000, output: 32000 }, + }, + "hermes-4-70b": { + id: "hermes-4-70b", + name: "Hermes 4 70B", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2025-08-26", + last_updated: "2025-08-26", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.116, output: 0.358 }, + limit: { context: 128000, output: 128000 }, + }, + "minimax-m2.5": { + id: "minimax-m2.5", + name: "MiniMax-M2.5", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.32, output: 1.18 }, + limit: { context: 196608, output: 196608 }, + }, + "deepseek-v3.2": { + id: "deepseek-v3.2", + name: "DeepSeek V3.2", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2025-12-01", + last_updated: "2025-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.266, output: 0.444 }, + limit: { context: 163840, output: 163840 }, + }, + "intellect-3": { + id: "intellect-3", + name: "INTELLECT 3", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-11", + release_date: "2025-11-26", + last_updated: "2025-11-26", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.219, output: 1.202 }, + limit: { context: 128000, output: 128000 }, + }, + "glm-4.7-flash": { + id: "glm-4.7-flash", + name: "GLM-4.7-Flash", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-04", + release_date: "2025-08-08", + last_updated: "2025-08-08", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.09, output: 0.53 }, + limit: { context: 203000, output: 203000 }, + }, + "gpt-oss-120b": { + id: "gpt-oss-120b", + name: "GPT Oss 120b", + family: "gpt-oss", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-01", + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 128000 }, + }, + "qwen-2.5-72b-instruct": { + id: "qwen-2.5-72b-instruct", + name: "Qwen2.5 72B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-06", + release_date: "2024-09-19", + last_updated: "2024-09-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.062, output: 0.231 }, + limit: { context: 33000, output: 33000 }, + }, + "deepseek-r1-0528": { + id: "deepseek-r1-0528", + name: "DeepSeek R1 0528", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2025-05-28", + last_updated: "2025-05-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.585, output: 2.307 }, + limit: { context: 164000, output: 164000 }, + }, + "gpt-4.1": { + id: "gpt-4.1", + name: "GPT 4.1", + family: "gpt", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-06", + release_date: "2025-04-14", + last_updated: "2025-04-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2.354, output: 9.417 }, + limit: { context: 1047576, output: 32768 }, + }, + "kimi-k2-thinking": { + id: "kimi-k2-thinking", + name: "Kimi K2 Thinking", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-12", + release_date: "2025-12-08", + last_updated: "2025-12-08", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.656, output: 2.731 }, + limit: { context: 262000, output: 262000 }, + }, + "llama-3.1-405b-instruct": { + id: "llama-3.1-405b-instruct", + name: "Llama 3.1 405B Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 128000 }, + }, + "qwen3.5-122b-a10b": { + id: "qwen3.5-122b-a10b", + name: "Qwen3.5 122B A10B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2026-01", + release_date: "2026-02-24", + last_updated: "2026-02-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.444, output: 3.106 }, + limit: { context: 262144, output: 262144 }, + }, + "llama-3.3-70b-instruct": { + id: "llama-3.3-70b-instruct", + name: "Llama 3.3 70B Instruct", + family: "llama", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.089, output: 0.275 }, + limit: { context: 131000, output: 131000 }, + }, + "mistral-large-2512": { + id: "mistral-large-2512", + name: "Mistral Large 3 2512", + family: "mistral-large", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-12", + release_date: "2025-12-01", + last_updated: "2025-12-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.5, output: 1.5, cache_read: 0.05 }, + limit: { context: 256000, output: 256000 }, + }, + "qwen3.5-397b-a17b": { + id: "qwen3.5-397b-a17b", + name: "Qwen3.5 397B A17B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2026-01", + release_date: "2026-02-16", + last_updated: "2026-02-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 3.6 }, + limit: { context: 250000, output: 250000 }, + }, + "deepseek-v4-flash": { + id: "deepseek-v4-flash", + name: "DeepSeek V4 Flash", + family: "deepseek-flash", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-05", + release_date: "2026-04-24", + last_updated: "2026-04-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.133, output: 0.266, cache_read: 0.028 }, + limit: { context: 1048576, output: 384000 }, + }, + "deepseek-v4-pro": { + id: "deepseek-v4-pro", + name: "DeepSeek V4 Pro", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-05", + release_date: "2026-04-24", + last_updated: "2026-04-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.553, output: 3.106, cache_read: 0.145 }, + limit: { context: 1048576, output: 384000 }, + }, + "qwen3-coder-30b-a3b-instruct": { + id: "qwen3-coder-30b-a3b-instruct", + name: "Qwen3 Coder 30B A3B Instruct", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-31", + last_updated: "2025-07-31", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.053, output: 0.222 }, + limit: { context: 262000, output: 262000 }, + }, + }, + }, + siliconflow: { + id: "siliconflow", + env: ["SILICONFLOW_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.siliconflow.com/v1", + name: "SiliconFlow", + doc: "https://cloud.siliconflow.com/models", + models: { + "nex-agi/DeepSeek-V3.1-Nex-N1": { + id: "nex-agi/DeepSeek-V3.1-Nex-N1", + name: "nex-agi/DeepSeek-V3.1-Nex-N1", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-01-01", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 2 }, + limit: { context: 131000, output: 131000 }, + }, + "Qwen/Qwen2.5-VL-72B-Instruct": { + id: "Qwen/Qwen2.5-VL-72B-Instruct", + name: "Qwen/Qwen2.5-VL-72B-Instruct", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-01-28", + last_updated: "2025-11-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.59, output: 0.59 }, + limit: { context: 131000, output: 4000 }, + }, + "Qwen/Qwen3-VL-32B-Thinking": { + id: "Qwen/Qwen3-VL-32B-Thinking", + name: "Qwen/Qwen3-VL-32B-Thinking", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-10-21", + last_updated: "2025-11-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 1.5 }, + limit: { context: 262000, output: 262000 }, + }, + "Qwen/Qwen3-30B-A3B-Thinking-2507": { + id: "Qwen/Qwen3-30B-A3B-Thinking-2507", + name: "Qwen/Qwen3-30B-A3B-Thinking-2507", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-07-31", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.09, output: 0.3 }, + limit: { context: 262000, output: 131000 }, + }, + "Qwen/Qwen3-VL-235B-A22B-Thinking": { + id: "Qwen/Qwen3-VL-235B-A22B-Thinking", + name: "Qwen/Qwen3-VL-235B-A22B-Thinking", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-10-04", + last_updated: "2025-11-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.45, output: 3.5 }, + limit: { context: 262000, output: 262000 }, + }, + "Qwen/Qwen2.5-7B-Instruct": { + id: "Qwen/Qwen2.5-7B-Instruct", + name: "Qwen/Qwen2.5-7B-Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-09-18", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.05, output: 0.05 }, + limit: { context: 33000, output: 4000 }, + }, + "Qwen/Qwen2.5-Coder-32B-Instruct": { + id: "Qwen/Qwen2.5-Coder-32B-Instruct", + name: "Qwen/Qwen2.5-Coder-32B-Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-11-11", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.18, output: 0.18 }, + limit: { context: 33000, output: 4000 }, + }, + "Qwen/Qwen3-VL-30B-A3B-Instruct": { + id: "Qwen/Qwen3-VL-30B-A3B-Instruct", + name: "Qwen/Qwen3-VL-30B-A3B-Instruct", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-10-05", + last_updated: "2025-11-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.29, output: 1 }, + limit: { context: 262000, output: 262000 }, + }, + "Qwen/QwQ-32B": { + id: "Qwen/QwQ-32B", + name: "Qwen/QwQ-32B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-03-06", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.58 }, + limit: { context: 131000, output: 131000 }, + }, + "Qwen/Qwen3-235B-A22B": { + id: "Qwen/Qwen3-235B-A22B", + name: "Qwen/Qwen3-235B-A22B", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-04-30", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.35, output: 1.42 }, + limit: { context: 131000, output: 131000 }, + }, + "Qwen/Qwen3-Omni-30B-A3B-Captioner": { + id: "Qwen/Qwen3-Omni-30B-A3B-Captioner", + name: "Qwen/Qwen3-Omni-30B-A3B-Captioner", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-10-04", + last_updated: "2025-11-25", + modalities: { input: ["audio"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4 }, + limit: { context: 66000, output: 66000 }, + }, + "Qwen/Qwen3-VL-8B-Thinking": { + id: "Qwen/Qwen3-VL-8B-Thinking", + name: "Qwen/Qwen3-VL-8B-Thinking", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-10-15", + last_updated: "2025-11-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.18, output: 2 }, + limit: { context: 262000, output: 262000 }, + }, + "Qwen/Qwen2.5-VL-7B-Instruct": { + id: "Qwen/Qwen2.5-VL-7B-Instruct", + name: "Qwen/Qwen2.5-VL-7B-Instruct", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-01-28", + last_updated: "2025-11-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.05, output: 0.05 }, + limit: { context: 33000, output: 4000 }, + }, + "Qwen/Qwen3-Next-80B-A3B-Instruct": { + id: "Qwen/Qwen3-Next-80B-A3B-Instruct", + name: "Qwen/Qwen3-Next-80B-A3B-Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-09-18", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.14, output: 1.4 }, + limit: { context: 262000, output: 262000 }, + }, + "Qwen/Qwen3-8B": { + id: "Qwen/Qwen3-8B", + name: "Qwen/Qwen3-8B", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-04-30", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.06, output: 0.06 }, + limit: { context: 131000, output: 131000 }, + }, + "Qwen/Qwen3-30B-A3B-Instruct-2507": { + id: "Qwen/Qwen3-30B-A3B-Instruct-2507", + name: "Qwen/Qwen3-30B-A3B-Instruct-2507", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-07-30", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.09, output: 0.3 }, + limit: { context: 262000, output: 262000 }, + }, + "Qwen/Qwen3-235B-A22B-Instruct-2507": { + id: "Qwen/Qwen3-235B-A22B-Instruct-2507", + name: "Qwen/Qwen3-235B-A22B-Instruct-2507", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-07-23", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.09, output: 0.6 }, + limit: { context: 262000, output: 262000 }, + }, + "Qwen/Qwen3-32B": { + id: "Qwen/Qwen3-32B", + name: "Qwen/Qwen3-32B", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-04-30", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.14, output: 0.57 }, + limit: { context: 131000, output: 131000 }, + }, + "Qwen/Qwen3-Coder-30B-A3B-Instruct": { + id: "Qwen/Qwen3-Coder-30B-A3B-Instruct", + name: "Qwen/Qwen3-Coder-30B-A3B-Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-08-01", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.07, output: 0.28 }, + limit: { context: 262000, output: 262000 }, + }, + "Qwen/Qwen3-Omni-30B-A3B-Instruct": { + id: "Qwen/Qwen3-Omni-30B-A3B-Instruct", + name: "Qwen/Qwen3-Omni-30B-A3B-Instruct", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-10-04", + last_updated: "2025-11-25", + modalities: { input: ["text", "image", "audio"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4 }, + limit: { context: 66000, output: 66000 }, + }, + "Qwen/Qwen3-14B": { + id: "Qwen/Qwen3-14B", + name: "Qwen/Qwen3-14B", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-04-30", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.07, output: 0.28 }, + limit: { context: 131000, output: 131000 }, + }, + "Qwen/Qwen2.5-72B-Instruct-128K": { + id: "Qwen/Qwen2.5-72B-Instruct-128K", + name: "Qwen/Qwen2.5-72B-Instruct-128K", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-09-18", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.59, output: 0.59 }, + limit: { context: 131000, output: 4000 }, + }, + "Qwen/Qwen2.5-32B-Instruct": { + id: "Qwen/Qwen2.5-32B-Instruct", + name: "Qwen/Qwen2.5-32B-Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-09-19", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.18, output: 0.18 }, + limit: { context: 33000, output: 4000 }, + }, + "Qwen/Qwen3-235B-A22B-Thinking-2507": { + id: "Qwen/Qwen3-235B-A22B-Thinking-2507", + name: "Qwen/Qwen3-235B-A22B-Thinking-2507", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-07-28", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.13, output: 0.6 }, + limit: { context: 262000, output: 262000 }, + }, + "Qwen/Qwen3-Omni-30B-A3B-Thinking": { + id: "Qwen/Qwen3-Omni-30B-A3B-Thinking", + name: "Qwen/Qwen3-Omni-30B-A3B-Thinking", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-10-04", + last_updated: "2025-11-25", + modalities: { input: ["text", "image", "audio"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4 }, + limit: { context: 66000, output: 66000 }, + }, + "Qwen/Qwen2.5-VL-32B-Instruct": { + id: "Qwen/Qwen2.5-VL-32B-Instruct", + name: "Qwen/Qwen2.5-VL-32B-Instruct", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-03-24", + last_updated: "2025-11-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.27, output: 0.27 }, + limit: { context: 131000, output: 131000 }, + }, + "Qwen/Qwen3-Next-80B-A3B-Thinking": { + id: "Qwen/Qwen3-Next-80B-A3B-Thinking", + name: "Qwen/Qwen3-Next-80B-A3B-Thinking", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-09-25", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.14, output: 0.57 }, + limit: { context: 262000, output: 262000 }, + }, + "Qwen/Qwen3-VL-235B-A22B-Instruct": { + id: "Qwen/Qwen3-VL-235B-A22B-Instruct", + name: "Qwen/Qwen3-VL-235B-A22B-Instruct", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-10-04", + last_updated: "2025-11-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 1.5 }, + limit: { context: 262000, output: 262000 }, + }, + "Qwen/Qwen2.5-14B-Instruct": { + id: "Qwen/Qwen2.5-14B-Instruct", + name: "Qwen/Qwen2.5-14B-Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-09-18", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.1 }, + limit: { context: 33000, output: 4000 }, + }, + "Qwen/Qwen3-VL-30B-A3B-Thinking": { + id: "Qwen/Qwen3-VL-30B-A3B-Thinking", + name: "Qwen/Qwen3-VL-30B-A3B-Thinking", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-10-11", + last_updated: "2025-11-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.29, output: 1 }, + limit: { context: 262000, output: 262000 }, + }, + "Qwen/Qwen3-VL-32B-Instruct": { + id: "Qwen/Qwen3-VL-32B-Instruct", + name: "Qwen/Qwen3-VL-32B-Instruct", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-10-21", + last_updated: "2025-11-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.6 }, + limit: { context: 262000, output: 262000 }, + }, + "Qwen/Qwen3-VL-8B-Instruct": { + id: "Qwen/Qwen3-VL-8B-Instruct", + name: "Qwen/Qwen3-VL-8B-Instruct", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-10-15", + last_updated: "2025-11-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.18, output: 0.68 }, + limit: { context: 262000, output: 262000 }, + }, + "Qwen/Qwen3-Coder-480B-A35B-Instruct": { + id: "Qwen/Qwen3-Coder-480B-A35B-Instruct", + name: "Qwen/Qwen3-Coder-480B-A35B-Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-07-31", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 1 }, + limit: { context: 262000, output: 262000 }, + }, + "Qwen/Qwen2.5-72B-Instruct": { + id: "Qwen/Qwen2.5-72B-Instruct", + name: "Qwen/Qwen2.5-72B-Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-09-18", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.59, output: 0.59 }, + limit: { context: 33000, output: 4000 }, + }, + "stepfun-ai/Step-3.5-Flash": { + id: "stepfun-ai/Step-3.5-Flash", + name: "stepfun-ai/Step-3.5-Flash", + family: "step", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-02-11", + last_updated: "2026-02-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.3 }, + limit: { context: 262000, output: 262000 }, + }, + "zai-org/GLM-4.5": { + id: "zai-org/GLM-4.5", + name: "zai-org/GLM-4.5", + family: "glm", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-07-28", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 2 }, + limit: { context: 131000, output: 131000 }, + }, + "zai-org/GLM-5V-Turbo": { + id: "zai-org/GLM-5V-Turbo", + name: "zai-org/GLM-5V-Turbo", + family: "glm", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-04-01", + last_updated: "2026-04-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.2, output: 4, cache_write: 0 }, + limit: { context: 200000, output: 131072 }, + }, + "zai-org/GLM-4.7": { + id: "zai-org/GLM-4.7", + name: "zai-org/GLM-4.7", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2025-12-22", + last_updated: "2025-12-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.6, output: 2.2 }, + limit: { context: 205000, output: 205000 }, + }, + "zai-org/GLM-5.1": { + id: "zai-org/GLM-5.1", + name: "zai-org/GLM-5.1", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-04-08", + last_updated: "2026-04-08", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.4, output: 4.4, cache_write: 0 }, + limit: { context: 205000, output: 205000 }, + }, + "zai-org/GLM-4.5-Air": { + id: "zai-org/GLM-4.5-Air", + name: "zai-org/GLM-4.5-Air", + family: "glm-air", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-07-28", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.14, output: 0.86 }, + limit: { context: 131000, output: 131000 }, + }, + "zai-org/GLM-5": { + id: "zai-org/GLM-5", + name: "zai-org/GLM-5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 3.2 }, + limit: { context: 205000, output: 205000 }, + }, + "zai-org/GLM-4.6V": { + id: "zai-org/GLM-4.6V", + name: "zai-org/GLM-4.6V", + family: "glm", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-12-07", + last_updated: "2025-12-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 0.9 }, + limit: { context: 131000, output: 131000 }, + }, + "zai-org/GLM-4.6": { + id: "zai-org/GLM-4.6", + name: "zai-org/GLM-4.6", + family: "glm", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-10-04", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 1.9 }, + limit: { context: 205000, output: 205000 }, + }, + "zai-org/GLM-4.5V": { + id: "zai-org/GLM-4.5V", + name: "zai-org/GLM-4.5V", + family: "glm", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-08-13", + last_updated: "2025-11-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.14, output: 0.86 }, + limit: { context: 66000, output: 66000 }, + }, + "meta-llama/Meta-Llama-3.1-8B-Instruct": { + id: "meta-llama/Meta-Llama-3.1-8B-Instruct", + name: "meta-llama/Meta-Llama-3.1-8B-Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-04-23", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.06, output: 0.06 }, + limit: { context: 33000, output: 4000 }, + }, + "inclusionAI/Ring-flash-2.0": { + id: "inclusionAI/Ring-flash-2.0", + name: "inclusionAI/Ring-flash-2.0", + family: "ring", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-09-29", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.14, output: 0.57 }, + limit: { context: 131000, output: 131000 }, + }, + "inclusionAI/Ling-mini-2.0": { + id: "inclusionAI/Ling-mini-2.0", + name: "inclusionAI/Ling-mini-2.0", + family: "ling", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-09-10", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.07, output: 0.28 }, + limit: { context: 131000, output: 131000 }, + }, + "inclusionAI/Ling-flash-2.0": { + id: "inclusionAI/Ling-flash-2.0", + name: "inclusionAI/Ling-flash-2.0", + family: "ling", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-09-18", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.14, output: 0.57 }, + limit: { context: 131000, output: 131000 }, + }, + "tencent/Hunyuan-A13B-Instruct": { + id: "tencent/Hunyuan-A13B-Instruct", + name: "tencent/Hunyuan-A13B-Instruct", + family: "hunyuan", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-06-30", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.14, output: 0.57 }, + limit: { context: 131000, output: 131000 }, + }, + "tencent/Hunyuan-MT-7B": { + id: "tencent/Hunyuan-MT-7B", + name: "tencent/Hunyuan-MT-7B", + family: "hunyuan", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-09-18", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 33000, output: 33000 }, + }, + "deepseek-ai/DeepSeek-V3.1": { + id: "deepseek-ai/DeepSeek-V3.1", + name: "deepseek-ai/DeepSeek-V3.1", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-08-25", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.27, output: 1 }, + limit: { context: 164000, output: 164000 }, + }, + "deepseek-ai/deepseek-vl2": { + id: "deepseek-ai/deepseek-vl2", + name: "deepseek-ai/deepseek-vl2", + family: "deepseek", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-12-13", + last_updated: "2025-11-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.15 }, + limit: { context: 4000, output: 4000 }, + }, + "deepseek-ai/DeepSeek-V3": { + id: "deepseek-ai/DeepSeek-V3", + name: "deepseek-ai/DeepSeek-V3", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-12-26", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 1 }, + limit: { context: 164000, output: 164000 }, + }, + "deepseek-ai/DeepSeek-R1-Distill-Qwen-32B": { + id: "deepseek-ai/DeepSeek-R1-Distill-Qwen-32B", + name: "deepseek-ai/DeepSeek-R1-Distill-Qwen-32B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-01-20", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.18, output: 0.18 }, + limit: { context: 131000, output: 131000 }, + }, + "deepseek-ai/DeepSeek-R1": { + id: "deepseek-ai/DeepSeek-R1", + name: "deepseek-ai/DeepSeek-R1", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-05-28", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 2.18 }, + limit: { context: 164000, output: 164000 }, + }, + "deepseek-ai/DeepSeek-R1-Distill-Qwen-14B": { + id: "deepseek-ai/DeepSeek-R1-Distill-Qwen-14B", + name: "deepseek-ai/DeepSeek-R1-Distill-Qwen-14B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-01-20", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.1 }, + limit: { context: 131000, output: 131000 }, + }, + "deepseek-ai/DeepSeek-V3.2-Exp": { + id: "deepseek-ai/DeepSeek-V3.2-Exp", + name: "deepseek-ai/DeepSeek-V3.2-Exp", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-10-10", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.27, output: 0.41 }, + limit: { context: 164000, output: 164000 }, + }, + "deepseek-ai/DeepSeek-V3.2": { + id: "deepseek-ai/DeepSeek-V3.2", + name: "deepseek-ai/DeepSeek-V3.2", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-12-03", + last_updated: "2025-12-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.27, output: 0.42 }, + limit: { context: 164000, output: 164000 }, + }, + "deepseek-ai/DeepSeek-V3.1-Terminus": { + id: "deepseek-ai/DeepSeek-V3.1-Terminus", + name: "deepseek-ai/DeepSeek-V3.1-Terminus", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-09-29", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.27, output: 1 }, + limit: { context: 164000, output: 164000 }, + }, + "openai/gpt-oss-20b": { + id: "openai/gpt-oss-20b", + name: "openai/gpt-oss-20b", + family: "gpt-oss", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-08-13", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.04, output: 0.18 }, + limit: { context: 131000, output: 8000 }, + }, + "openai/gpt-oss-120b": { + id: "openai/gpt-oss-120b", + name: "openai/gpt-oss-120b", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-08-13", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.05, output: 0.45 }, + limit: { context: 131000, output: 8000 }, + }, + "baidu/ERNIE-4.5-300B-A47B": { + id: "baidu/ERNIE-4.5-300B-A47B", + name: "baidu/ERNIE-4.5-300B-A47B", + family: "ernie", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-07-02", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.28, output: 1.1 }, + limit: { context: 131000, output: 131000 }, + }, + "THUDM/GLM-Z1-9B-0414": { + id: "THUDM/GLM-Z1-9B-0414", + name: "THUDM/GLM-Z1-9B-0414", + family: "glm-z", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-04-18", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.086, output: 0.086 }, + limit: { context: 131000, output: 131000 }, + }, + "THUDM/GLM-4-9B-0414": { + id: "THUDM/GLM-4-9B-0414", + name: "THUDM/GLM-4-9B-0414", + family: "glm", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-04-18", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.086, output: 0.086 }, + limit: { context: 33000, output: 33000 }, + }, + "THUDM/GLM-4-32B-0414": { + id: "THUDM/GLM-4-32B-0414", + name: "THUDM/GLM-4-32B-0414", + family: "glm", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-04-18", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.27, output: 0.27 }, + limit: { context: 33000, output: 33000 }, + }, + "THUDM/GLM-Z1-32B-0414": { + id: "THUDM/GLM-Z1-32B-0414", + name: "THUDM/GLM-Z1-32B-0414", + family: "glm-z", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-04-18", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.14, output: 0.57 }, + limit: { context: 131000, output: 131000 }, + }, + "moonshotai/Kimi-K2-Thinking": { + id: "moonshotai/Kimi-K2-Thinking", + name: "moonshotai/Kimi-K2-Thinking", + family: "kimi-thinking", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-11-07", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.55, output: 2.5 }, + limit: { context: 262000, output: 262000 }, + }, + "moonshotai/Kimi-K2.6": { + id: "moonshotai/Kimi-K2.6", + name: "moonshotai/Kimi-K2.6", + family: "kimi", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-04-21", + last_updated: "2026-04-21", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.95, output: 4, cache_read: 0.16 }, + limit: { context: 262000, output: 262000 }, + }, + "moonshotai/Kimi-K2-Instruct": { + id: "moonshotai/Kimi-K2-Instruct", + name: "moonshotai/Kimi-K2-Instruct", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-07-13", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.58, output: 2.29 }, + limit: { context: 131000, output: 131000 }, + }, + "moonshotai/Kimi-K2-Instruct-0905": { + id: "moonshotai/Kimi-K2-Instruct-0905", + name: "moonshotai/Kimi-K2-Instruct-0905", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-09-08", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 2 }, + limit: { context: 262000, output: 262000 }, + }, + "moonshotai/Kimi-K2.5": { + id: "moonshotai/Kimi-K2.5", + name: "moonshotai/Kimi-K2.5", + family: "kimi", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-01-27", + last_updated: "2026-01-27", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.45, output: 2.25 }, + limit: { context: 262000, output: 262000 }, + }, + "MiniMaxAI/MiniMax-M2.5": { + id: "MiniMaxAI/MiniMax-M2.5", + name: "MiniMaxAI/MiniMax-M2.5", + family: "minimax", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2026-02-15", + last_updated: "2026-02-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 197000, output: 131000 }, + }, + "MiniMaxAI/MiniMax-M2.1": { + id: "MiniMaxAI/MiniMax-M2.1", + name: "MiniMaxAI/MiniMax-M2.1", + family: "minimax", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-12-23", + last_updated: "2025-12-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 197000, output: 131000 }, + }, + "ByteDance-Seed/Seed-OSS-36B-Instruct": { + id: "ByteDance-Seed/Seed-OSS-36B-Instruct", + name: "ByteDance-Seed/Seed-OSS-36B-Instruct", + family: "seed", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-09-04", + last_updated: "2025-11-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.21, output: 0.57 }, + limit: { context: 262000, output: 262000 }, + }, + }, + }, + vercel: { + id: "vercel", + env: ["AI_GATEWAY_API_KEY"], + npm: "@ai-sdk/gateway", + name: "Vercel AI Gateway", + doc: "https://github.com/vercel/ai/tree/5eb85cc45a259553501f535b8ac79a77d0e79223/packages/gateway", + models: { + "alibaba/qwen3-coder-plus": { + id: "alibaba/qwen3-coder-plus", + name: "Qwen3 Coder Plus", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-23", + last_updated: "2025-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 5 }, + limit: { context: 1000000, output: 1000000 }, + }, + "alibaba/qwen3.6-27b": { + id: "alibaba/qwen3.6-27b", + name: "Qwen 3.6 27B", + family: "qwen3.6", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-22", + last_updated: "2026-05-01", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.6, output: 3.5999999999999996 }, + limit: { context: 256000, output: 256000 }, + }, + "alibaba/qwen3-embedding-8b": { + id: "alibaba/qwen3-embedding-8b", + name: "Qwen3 Embedding 8B", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2025-06-05", + last_updated: "2025-06-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.05, output: 0 }, + limit: { context: 32768, output: 32768 }, + }, + "alibaba/qwen-3-30b": { + id: "alibaba/qwen-3-30b", + name: "Qwen3-30B-A3B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-04", + last_updated: "2025-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.08, output: 0.29 }, + limit: { context: 40960, output: 16384 }, + }, + "alibaba/qwen-3-235b": { + id: "alibaba/qwen-3-235b", + name: "Qwen3 235B A22B Instruct 2507", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-04", + last_updated: "2025-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.13, output: 0.6 }, + limit: { context: 40960, output: 16384 }, + }, + "alibaba/qwen3.5-flash": { + id: "alibaba/qwen3.5-flash", + name: "Qwen 3.5 Flash", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-24", + last_updated: "2026-02-24", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4, cache_read: 0.001, cache_write: 0.125 }, + limit: { context: 1000000, output: 64000 }, + }, + "alibaba/qwen3.6-plus": { + id: "alibaba/qwen3.6-plus", + name: "Qwen 3.6 Plus", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-02", + last_updated: "2026-04-03", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 3, cache_read: 0.09999999999999999, cache_write: 0.625 }, + limit: { context: 1000000, output: 64000 }, + }, + "alibaba/qwen3-max": { + id: "alibaba/qwen3-max", + name: "Qwen3 Max", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-09-23", + last_updated: "2025-09-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.2, output: 6 }, + limit: { context: 262144, output: 32768 }, + }, + "alibaba/qwen3-embedding-0.6b": { + id: "alibaba/qwen3-embedding-0.6b", + name: "Qwen3 Embedding 0.6B", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2025-11-14", + last_updated: "2025-11-14", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.01, output: 0 }, + limit: { context: 32768, output: 32768 }, + }, + "alibaba/qwen-3-32b": { + id: "alibaba/qwen-3-32b", + name: "Qwen 3.32B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-04", + last_updated: "2025-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.3 }, + limit: { context: 40960, output: 16384 }, + }, + "alibaba/qwen-3.6-max-preview": { + id: "alibaba/qwen-3.6-max-preview", + name: "Qwen 3.6 Max Preview", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-20", + last_updated: "2026-04-24", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: true, + cost: { input: 1.3, output: 7.8, cache_read: 0.26, cache_write: 1.625 }, + limit: { context: 240000, output: 64000 }, + }, + "alibaba/qwen3-next-80b-a3b-thinking": { + id: "alibaba/qwen3-next-80b-a3b-thinking", + name: "Qwen3 Next 80B A3B Thinking", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-09", + release_date: "2025-09-12", + last_updated: "2025-09-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 1.5 }, + limit: { context: 131072, output: 65536 }, + }, + "alibaba/qwen3-vl-thinking": { + id: "alibaba/qwen3-vl-thinking", + name: "Qwen3 VL Thinking", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-09", + release_date: "2025-09-24", + last_updated: "2025-09-24", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.7, output: 8.4 }, + limit: { context: 131072, output: 129024 }, + }, + "alibaba/qwen3-235b-a22b-thinking": { + id: "alibaba/qwen3-235b-a22b-thinking", + name: "Qwen3 235B A22B Thinking 2507", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-04", + last_updated: "2025-04", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 2.9 }, + limit: { context: 262114, output: 262114 }, + }, + "alibaba/qwen3-next-80b-a3b-instruct": { + id: "alibaba/qwen3-next-80b-a3b-instruct", + name: "Qwen3 Next 80B A3B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-09-12", + last_updated: "2025-09-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.09, output: 1.1 }, + limit: { context: 262144, output: 32768 }, + }, + "alibaba/qwen3-coder-next": { + id: "alibaba/qwen3-coder-next", + name: "Qwen3 Coder Next", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-07-22", + last_updated: "2026-02-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 1.2 }, + limit: { context: 256000, output: 256000 }, + }, + "alibaba/qwen3-embedding-4b": { + id: "alibaba/qwen3-embedding-4b", + name: "Qwen3 Embedding 4B", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2025-06-05", + last_updated: "2025-06-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.02, output: 0 }, + limit: { context: 32768, output: 32768 }, + }, + "alibaba/qwen3-max-thinking": { + id: "alibaba/qwen3-max-thinking", + name: "Qwen 3 Max Thinking", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-01", + last_updated: "2025-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.2, output: 6, cache_read: 0.24 }, + limit: { context: 256000, output: 65536 }, + }, + "alibaba/qwen3-vl-235b-a22b-instruct": { + id: "alibaba/qwen3-vl-235b-a22b-instruct", + name: "Qwen3 VL 235B A22B Instruct", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-09-24", + last_updated: "2026-05-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.39999999999999997, output: 1.5999999999999999 }, + limit: { context: 131072, output: 129024 }, + }, + "alibaba/qwen3-coder": { + id: "alibaba/qwen3-coder", + name: "Qwen3 Coder 480B A35B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-04", + last_updated: "2025-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.38, output: 1.53 }, + limit: { context: 262144, output: 66536 }, + }, + "alibaba/qwen3-max-preview": { + id: "alibaba/qwen3-max-preview", + name: "Qwen3 Max Preview", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-09-23", + last_updated: "2025-09-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.2, output: 6, cache_read: 0.24 }, + limit: { context: 262144, output: 32768 }, + }, + "alibaba/qwen3.5-plus": { + id: "alibaba/qwen3.5-plus", + name: "Qwen 3.5 Plus", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-16", + last_updated: "2026-02-19", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 2.4, cache_read: 0.04, cache_write: 0.5 }, + limit: { context: 1000000, output: 64000 }, + }, + "alibaba/qwen-3-14b": { + id: "alibaba/qwen-3-14b", + name: "Qwen3-14B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-04", + last_updated: "2025-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.06, output: 0.24 }, + limit: { context: 40960, output: 16384 }, + }, + "alibaba/qwen3-vl-instruct": { + id: "alibaba/qwen3-vl-instruct", + name: "Qwen3 VL Instruct", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-09-24", + last_updated: "2025-09-24", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.7, output: 2.8 }, + limit: { context: 131072, output: 129024 }, + }, + "alibaba/qwen3-coder-30b-a3b": { + id: "alibaba/qwen3-coder-30b-a3b", + name: "Qwen 3 Coder 30B A3B Instruct", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-04", + last_updated: "2025-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.07, output: 0.27 }, + limit: { context: 160000, output: 32768 }, + }, + "perplexity/sonar-pro": { + id: "perplexity/sonar-pro", + name: "Sonar Pro", + family: "sonar-pro", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-09", + release_date: "2025-02-19", + last_updated: "2025-02-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15 }, + limit: { context: 200000, output: 8000 }, + }, + "perplexity/sonar": { + id: "perplexity/sonar", + name: "Sonar", + family: "sonar", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-02", + release_date: "2025-02-19", + last_updated: "2025-02-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 1 }, + limit: { context: 127000, output: 8000 }, + }, + "perplexity/sonar-reasoning": { + id: "perplexity/sonar-reasoning", + name: "Sonar Reasoning", + family: "sonar-reasoning", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + knowledge: "2025-09", + release_date: "2025-02-19", + last_updated: "2025-02-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 5 }, + limit: { context: 127000, output: 8000 }, + }, + "perplexity/sonar-reasoning-pro": { + id: "perplexity/sonar-reasoning-pro", + name: "Sonar Reasoning Pro", + family: "sonar-reasoning", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + knowledge: "2025-09", + release_date: "2025-02-19", + last_updated: "2025-02-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 8 }, + limit: { context: 127000, output: 8000 }, + }, + "deepseek/deepseek-v3.2-thinking": { + id: "deepseek/deepseek-v3.2-thinking", + name: "DeepSeek V3.2 Thinking", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: true, + temperature: true, + knowledge: "2024-07", + release_date: "2025-12-01", + last_updated: "2025-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.28, output: 0.42, cache_read: 0.03 }, + limit: { context: 128000, output: 64000 }, + }, + "deepseek/deepseek-v3.2-exp": { + id: "deepseek/deepseek-v3.2-exp", + name: "DeepSeek V3.2 Exp", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-09", + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.27, output: 0.4 }, + limit: { context: 163840, output: 163840 }, + }, + "deepseek/deepseek-v3.1": { + id: "deepseek/deepseek-v3.1", + name: "DeepSeek-V3.1", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2025-08-21", + last_updated: "2025-08-21", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 1 }, + limit: { context: 163840, output: 128000 }, + }, + "deepseek/deepseek-v4-flash": { + id: "deepseek/deepseek-v4-flash", + name: "DeepSeek V4 Flash", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-23", + last_updated: "2026-04-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.14, output: 0.28, cache_read: 0.028 }, + limit: { context: 1000000, output: 384000 }, + }, + "deepseek/deepseek-v4-pro": { + id: "deepseek/deepseek-v4-pro", + name: "DeepSeek V4 Pro", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-23", + last_updated: "2026-04-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.74, output: 3.48, cache_read: 0.145 }, + limit: { context: 1000000, output: 384000 }, + }, + "deepseek/deepseek-v3.2": { + id: "deepseek/deepseek-v3.2", + name: "DeepSeek V3.2", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-07", + release_date: "2025-12-01", + last_updated: "2025-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.27, output: 0.4, cache_read: 0.22 }, + limit: { context: 163842, output: 8000 }, + }, + "deepseek/deepseek-v3": { + id: "deepseek/deepseek-v3", + name: "DeepSeek V3 0324", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2024-12-26", + last_updated: "2024-12-26", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.77, output: 0.77 }, + limit: { context: 163840, output: 16384 }, + }, + "deepseek/deepseek-v3.1-terminus": { + id: "deepseek/deepseek-v3.1-terminus", + name: "DeepSeek V3.1 Terminus", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-09-22", + last_updated: "2025-09-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.27, output: 1 }, + limit: { context: 131072, output: 65536 }, + }, + "deepseek/deepseek-r1": { + id: "deepseek/deepseek-r1", + name: "DeepSeek-R1", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2025-01-20", + last_updated: "2025-05-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.35, output: 5.4 }, + limit: { context: 128000, output: 32768 }, + }, + "arcee-ai/trinity-mini": { + id: "arcee-ai/trinity-mini", + name: "Trinity Mini", + family: "trinity", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-10", + release_date: "2025-12", + last_updated: "2025-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.05, output: 0.15 }, + limit: { context: 131072, output: 131072 }, + }, + "arcee-ai/trinity-large-thinking": { + id: "arcee-ai/trinity-large-thinking", + name: "Trinity Large Thinking", + family: "trinity", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-01", + last_updated: "2026-04-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.25, output: 0.8999999999999999 }, + limit: { context: 262100, output: 80000 }, + }, + "arcee-ai/trinity-large-preview": { + id: "arcee-ai/trinity-large-preview", + name: "Trinity Large Preview", + family: "trinity", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-01", + last_updated: "2025-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 1 }, + limit: { context: 131000, output: 131000 }, + }, + "recraft/recraft-v3": { + id: "recraft/recraft-v3", + name: "Recraft V3", + family: "recraft", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2024-10", + last_updated: "2024-10", + modalities: { input: ["text"], output: ["image"] }, + open_weights: false, + limit: { context: 512, output: 0 }, + }, + "recraft/recraft-v2": { + id: "recraft/recraft-v2", + name: "Recraft V2", + family: "recraft", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2024-03", + last_updated: "2024-03", + modalities: { input: ["text"], output: ["image"] }, + open_weights: false, + limit: { context: 512, output: 0 }, + }, + "voyage/voyage-3-large": { + id: "voyage/voyage-3-large", + name: "voyage-3-large", + family: "voyage", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2024-09", + last_updated: "2024-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.18, output: 0 }, + limit: { context: 8192, output: 1536 }, + }, + "voyage/voyage-4-large": { + id: "voyage/voyage-4-large", + name: "voyage-4-large", + family: "voyage", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2026-03-06", + last_updated: "2026-03-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 32000, output: 0 }, + }, + "voyage/voyage-3.5-lite": { + id: "voyage/voyage-3.5-lite", + name: "voyage-3.5-lite", + family: "voyage", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2025-05-20", + last_updated: "2025-05-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.02, output: 0 }, + limit: { context: 8192, output: 1536 }, + }, + "voyage/voyage-code-3": { + id: "voyage/voyage-code-3", + name: "voyage-code-3", + family: "voyage", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2024-09", + last_updated: "2024-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.18, output: 0 }, + limit: { context: 8192, output: 1536 }, + }, + "voyage/voyage-finance-2": { + id: "voyage/voyage-finance-2", + name: "voyage-finance-2", + family: "voyage", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2024-03", + last_updated: "2024-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.12, output: 0 }, + limit: { context: 8192, output: 1536 }, + }, + "voyage/voyage-4-lite": { + id: "voyage/voyage-4-lite", + name: "voyage-4-lite", + family: "voyage", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2026-03-06", + last_updated: "2026-03-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 32000, output: 0 }, + }, + "voyage/voyage-4": { + id: "voyage/voyage-4", + name: "voyage-4", + family: "voyage", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2026-03-06", + last_updated: "2026-03-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 32000, output: 0 }, + }, + "voyage/voyage-code-2": { + id: "voyage/voyage-code-2", + name: "voyage-code-2", + family: "voyage", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2024-01", + last_updated: "2024-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.12, output: 0 }, + limit: { context: 8192, output: 1536 }, + }, + "voyage/voyage-law-2": { + id: "voyage/voyage-law-2", + name: "voyage-law-2", + family: "voyage", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2024-03", + last_updated: "2024-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.12, output: 0 }, + limit: { context: 8192, output: 1536 }, + }, + "voyage/voyage-3.5": { + id: "voyage/voyage-3.5", + name: "voyage-3.5", + family: "voyage", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2025-05-20", + last_updated: "2025-05-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.06, output: 0 }, + limit: { context: 8192, output: 1536 }, + }, + "morph/morph-v3-large": { + id: "morph/morph-v3-large", + name: "Morph v3 Large", + family: "morph", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2024-08-15", + last_updated: "2024-08-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.9, output: 1.9 }, + limit: { context: 32000, output: 32000 }, + }, + "morph/morph-v3-fast": { + id: "morph/morph-v3-fast", + name: "Morph v3 Fast", + family: "morph", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2024-08-15", + last_updated: "2024-08-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.8, output: 1.2 }, + limit: { context: 16000, output: 16000 }, + }, + "zai/glm-5v-turbo": { + id: "zai/glm-5v-turbo", + name: "GLM 5V Turbo", + family: "glm", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-01", + last_updated: "2026-04-03", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.2, output: 4, cache_read: 0.24 }, + limit: { context: 200000, output: 128000 }, + }, + "zai/glm-4.7": { + id: "zai/glm-4.7", + name: "GLM 4.7", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-12-22", + last_updated: "2025-12-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.43, output: 1.75, cache_read: 0.08 }, + limit: { context: 202752, output: 120000 }, + }, + "zai/glm-5": { + id: "zai/glm-5", + name: "GLM-5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-12", + last_updated: "2026-02-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 3.2, cache_read: 0.2 }, + limit: { context: 202800, output: 131072 }, + }, + "zai/glm-4.7-flashx": { + id: "zai/glm-4.7-flashx", + name: "GLM 4.7 FlashX", + family: "glm-flash", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-01", + last_updated: "2025-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.06, output: 0.4, cache_read: 0.01 }, + limit: { context: 200000, output: 128000 }, + }, + "zai/glm-5.1": { + id: "zai/glm-5.1", + name: "GLM 5.1", + family: "glm", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-07", + last_updated: "2026-04-16", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.4, output: 4.4, cache_read: 0.26 }, + limit: { context: 202752, output: 202752 }, + }, + "zai/glm-4.6v-flash": { + id: "zai/glm-4.6v-flash", + name: "GLM-4.6V-Flash", + family: "glm", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-09-30", + last_updated: "2025-09-30", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + limit: { context: 128000, output: 24000 }, + }, + "zai/glm-4.5": { + id: "zai/glm-4.5", + name: "GLM 4.5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-07-28", + last_updated: "2025-07-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.2 }, + limit: { context: 131072, output: 131072 }, + }, + "zai/glm-4.5-air": { + id: "zai/glm-4.5-air", + name: "GLM 4.5 Air", + family: "glm-air", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-28", + last_updated: "2025-07-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 1.1 }, + limit: { context: 128000, output: 96000 }, + }, + "zai/glm-5-turbo": { + id: "zai/glm-5-turbo", + name: "GLM 5 Turbo", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-15", + last_updated: "2026-03-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.2, output: 4, cache_read: 0.24 }, + limit: { context: 202800, output: 131100 }, + }, + "zai/glm-4.5v": { + id: "zai/glm-4.5v", + name: "GLM 4.5V", + family: "glm", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-08", + release_date: "2025-08-11", + last_updated: "2025-08-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 1.8 }, + limit: { context: 66000, output: 66000 }, + }, + "zai/glm-4.6": { + id: "zai/glm-4.6", + name: "GLM 4.6", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-09-30", + last_updated: "2025-09-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.45, output: 1.8 }, + limit: { context: 200000, output: 96000 }, + }, + "zai/glm-4.6v": { + id: "zai/glm-4.6v", + name: "GLM-4.6V", + family: "glm", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-09-30", + last_updated: "2025-09-30", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 0.9, cache_read: 0.05 }, + limit: { context: 128000, output: 24000 }, + }, + "zai/glm-4.7-flash": { + id: "zai/glm-4.7-flash", + name: "GLM 4.7 Flash", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-13", + last_updated: "2026-03-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.07, output: 0.39999999999999997 }, + limit: { context: 200000, output: 131000 }, + }, + "cohere/command-a": { + id: "cohere/command-a", + name: "Command A", + family: "command", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-03-13", + last_updated: "2025-03-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 10 }, + limit: { context: 256000, output: 8000 }, + }, + "cohere/embed-v4.0": { + id: "cohere/embed-v4.0", + name: "Embed v4.0", + family: "cohere-embed", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2025-04-15", + last_updated: "2025-04-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.12, output: 0 }, + limit: { context: 8192, output: 1536 }, + }, + "prime-intellect/intellect-3": { + id: "prime-intellect/intellect-3", + name: "INTELLECT 3", + family: "intellect", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-11-26", + last_updated: "2025-11-26", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 1.1 }, + limit: { context: 131072, output: 131072 }, + }, + "xai/grok-4.3": { + id: "xai/grok-4.3", + name: "Grok 4.3", + family: "grok", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-30", + last_updated: "2026-05-01", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 2.5, cache_read: 0.19999999999999998 }, + limit: { context: 1000000, output: 1000000 }, + }, + "xai/grok-4.20-non-reasoning": { + id: "xai/grok-4.20-non-reasoning", + name: "Grok 4.20 Non-Reasoning", + family: "grok", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2026-03-09", + last_updated: "2026-03-23", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 6, cache_read: 0.19999999999999998 }, + limit: { context: 2000000, output: 2000000 }, + }, + "xai/grok-4.20-non-reasoning-beta": { + id: "xai/grok-4.20-non-reasoning-beta", + name: "Grok 4.20 Beta Non-Reasoning", + family: "grok", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2026-03-11", + last_updated: "2026-03-13", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 6, cache_read: 0.19999999999999998 }, + limit: { context: 2000000, output: 2000000 }, + }, + "xai/grok-4.20-reasoning": { + id: "xai/grok-4.20-reasoning", + name: "Grok 4.20 Reasoning", + family: "grok", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-09", + last_updated: "2026-03-23", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 6, cache_read: 0.19999999999999998 }, + limit: { context: 2000000, output: 2000000 }, + }, + "xai/grok-imagine-image": { + id: "xai/grok-imagine-image", + name: "Grok Imagine Image", + family: "grok", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2026-01-28", + last_updated: "2026-02-19", + modalities: { input: ["text"], output: ["text", "image"] }, + open_weights: false, + limit: { context: 0, output: 0 }, + }, + "xai/grok-4.20-multi-agent-beta": { + id: "xai/grok-4.20-multi-agent-beta", + name: "Grok 4.20 Multi Agent Beta", + family: "grok", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-11", + last_updated: "2026-03-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 6, cache_read: 0.19999999999999998 }, + limit: { context: 2000000, output: 2000000 }, + }, + "xai/grok-imagine-image-pro": { + id: "xai/grok-imagine-image-pro", + name: "Grok Imagine Image Pro", + family: "grok", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2026-01-28", + last_updated: "2026-02-19", + modalities: { input: ["text"], output: ["text", "image"] }, + open_weights: false, + limit: { context: 0, output: 0 }, + }, + "xai/grok-4-fast-reasoning": { + id: "xai/grok-4-fast-reasoning", + name: "Grok 4 Fast Reasoning", + family: "grok", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-07-09", + last_updated: "2025-07-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5, cache_read: 0.05 }, + limit: { context: 2000000, output: 256000 }, + }, + "xai/grok-4.1-fast-non-reasoning": { + id: "xai/grok-4.1-fast-non-reasoning", + name: "Grok 4.1 Fast Non-Reasoning", + family: "grok", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-07-09", + last_updated: "2025-07-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5, cache_read: 0.05 }, + limit: { context: 2000000, output: 30000 }, + }, + "xai/grok-4.20-reasoning-beta": { + id: "xai/grok-4.20-reasoning-beta", + name: "Grok 4.20 Beta Reasoning", + family: "grok", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-11", + last_updated: "2026-03-13", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 6, cache_read: 0.19999999999999998 }, + limit: { context: 2000000, output: 2000000 }, + }, + "xai/grok-4.20-multi-agent": { + id: "xai/grok-4.20-multi-agent", + name: "Grok 4.20 Multi-Agent", + family: "grok", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-09", + last_updated: "2026-03-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 6, cache_read: 0.19999999999999998 }, + limit: { context: 2000000, output: 2000000 }, + }, + "xai/grok-4.1-fast-reasoning": { + id: "xai/grok-4.1-fast-reasoning", + name: "Grok 4.1 Fast Reasoning", + family: "grok", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-07-09", + last_updated: "2025-07-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5, cache_read: 0.05 }, + limit: { context: 2000000, output: 30000 }, + }, + "xai/grok-4-fast-non-reasoning": { + id: "xai/grok-4-fast-non-reasoning", + name: "Grok 4 Fast (Non-Reasoning)", + family: "grok", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-09-19", + last_updated: "2025-09-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5, cache_read: 0.05 }, + limit: { context: 2000000, output: 30000 }, + }, + "xai/grok-3": { + id: "xai/grok-3", + name: "Grok 3", + family: "grok", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-11", + release_date: "2025-02-17", + last_updated: "2025-02-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.75 }, + limit: { context: 131072, output: 8192 }, + }, + "xai/grok-3-mini": { + id: "xai/grok-3-mini", + name: "Grok 3 Mini", + family: "grok", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-11", + release_date: "2025-02-17", + last_updated: "2025-02-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 0.5, reasoning: 0.5, cache_read: 0.075 }, + limit: { context: 131072, output: 8192 }, + }, + "xai/grok-2-vision": { + id: "xai/grok-2-vision", + name: "Grok 2 Vision", + family: "grok", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-08", + release_date: "2024-08-20", + last_updated: "2024-08-20", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 10, cache_read: 2 }, + limit: { context: 8192, output: 4096 }, + }, + "xai/grok-4": { + id: "xai/grok-4", + name: "Grok 4", + family: "grok", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-07-09", + last_updated: "2025-07-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, reasoning: 15, cache_read: 0.75 }, + limit: { context: 256000, output: 64000 }, + }, + "xai/grok-code-fast-1": { + id: "xai/grok-code-fast-1", + name: "Grok Code Fast 1", + family: "grok", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2023-10", + release_date: "2025-08-28", + last_updated: "2025-08-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 1.5, cache_read: 0.02 }, + limit: { context: 256000, output: 10000 }, + }, + "xai/grok-3-fast": { + id: "xai/grok-3-fast", + name: "Grok 3 Fast", + family: "grok", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-11", + release_date: "2025-02-17", + last_updated: "2025-02-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 1.25 }, + limit: { context: 131072, output: 8192 }, + }, + "xai/grok-3-mini-fast": { + id: "xai/grok-3-mini-fast", + name: "Grok 3 Mini Fast", + family: "grok", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-11", + release_date: "2025-02-17", + last_updated: "2025-02-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.6, output: 4, reasoning: 4, cache_read: 0.15 }, + limit: { context: 131072, output: 8192 }, + }, + "nvidia/nemotron-3-super-120b-a12b": { + id: "nvidia/nemotron-3-super-120b-a12b", + name: "NVIDIA Nemotron 3 Super 120B A12B", + family: "nemotron", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2026-03-18", + last_updated: "2026-03-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.65 }, + limit: { context: 256000, output: 32000 }, + }, + "nvidia/nemotron-3-nano-30b-a3b": { + id: "nvidia/nemotron-3-nano-30b-a3b", + name: "Nemotron 3 Nano 30B A3B", + family: "nemotron", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + knowledge: "2024-10", + release_date: "2024-12", + last_updated: "2024-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.06, output: 0.24 }, + limit: { context: 262144, output: 262144 }, + }, + "nvidia/nemotron-nano-12b-v2-vl": { + id: "nvidia/nemotron-nano-12b-v2-vl", + name: "Nvidia Nemotron Nano 12B V2 VL", + family: "nemotron", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2024-12", + last_updated: "2024-12", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.6 }, + limit: { context: 131072, output: 131072 }, + }, + "nvidia/nemotron-nano-9b-v2": { + id: "nvidia/nemotron-nano-9b-v2", + name: "Nvidia Nemotron Nano 9B V2", + family: "nemotron", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-08-18", + last_updated: "2025-08-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.04, output: 0.16 }, + limit: { context: 131072, output: 131072 }, + }, + "inception/mercury-edit-2": { + id: "inception/mercury-edit-2", + name: "Mercury Edit 2", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2026-03-30", + last_updated: "2026-03-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 0.75, cache_read: 0.025 }, + limit: { context: 128000, output: 8192 }, + }, + "inception/mercury-2": { + id: "inception/mercury-2", + name: "Mercury 2", + family: "mercury", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-24", + last_updated: "2026-03-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 0.75, cache_read: 0.024999999999999998 }, + limit: { context: 128000, output: 128000 }, + }, + "inception/mercury-coder-small": { + id: "inception/mercury-coder-small", + name: "Mercury Coder Small Beta", + family: "mercury", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-02-26", + last_updated: "2026-05-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 1 }, + limit: { context: 32000, output: 16384 }, + }, + "openai/gpt-5.1-codex-max": { + id: "openai/gpt-5.1-codex-max", + name: "GPT 5.1 Codex Max", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.13 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "openai/gpt-5.2-chat": { + id: "openai/gpt-5.2-chat", + name: "GPT-5.2 Chat", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.18 }, + limit: { context: 128000, input: 111616, output: 16384 }, + }, + "openai/gpt-4o-mini-search-preview": { + id: "openai/gpt-4o-mini-search-preview", + name: "GPT 4o Mini Search Preview", + family: "gpt-mini", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + knowledge: "2023-09", + release_date: "2025-01", + last_updated: "2025-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 128000, input: 111616, output: 16384 }, + }, + "openai/codex-mini": { + id: "openai/codex-mini", + name: "Codex Mini", + family: "gpt-codex-mini", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-05-16", + last_updated: "2025-05-16", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.5, output: 6, cache_read: 0.38 }, + limit: { context: 200000, input: 100000, output: 100000 }, + }, + "openai/gpt-5-chat": { + id: "openai/gpt-5-chat", + name: "GPT-5 Chat", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image", "pdf"], output: ["text", "image"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.13 }, + limit: { context: 128000, input: 111616, output: 16384 }, + }, + "openai/gpt-5.3-chat": { + id: "openai/gpt-5.3-chat", + name: "GPT-5.3 Chat", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-03", + last_updated: "2026-03-06", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 128000, input: 111616, output: 16384 }, + }, + "openai/gpt-5.2-pro": { + id: "openai/gpt-5.2-pro", + name: "GPT 5.2 ", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 21, output: 168 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "openai/text-embedding-3-large": { + id: "openai/text-embedding-3-large", + name: "text-embedding-3-large", + family: "text-embedding", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2024-01-25", + last_updated: "2024-01-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.13, output: 0 }, + limit: { context: 8192, input: 6656, output: 1536 }, + }, + "openai/gpt-5.5": { + id: "openai/gpt-5.5", + name: "GPT 5.5", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-24", + last_updated: "2026-04-24", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 30, cache_read: 0.5 }, + limit: { context: 1000000, input: 872000, output: 128000 }, + }, + "openai/gpt-5.3-codex": { + id: "openai/gpt-5.3-codex", + name: "GPT 5.3 Codex", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-24", + last_updated: "2026-02-24", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "openai/text-embedding-ada-002": { + id: "openai/text-embedding-ada-002", + name: "text-embedding-ada-002", + family: "text-embedding", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2022-12-15", + last_updated: "2022-12-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0 }, + limit: { context: 8192, input: 6656, output: 1536 }, + }, + "openai/gpt-5.2": { + id: "openai/gpt-5.2", + name: "GPT-5.2", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.18 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "openai/o3-pro": { + id: "openai/o3-pro", + name: "o3 Pro", + family: "o-pro", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-10", + release_date: "2025-04-16", + last_updated: "2025-04-16", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 20, output: 80 }, + limit: { context: 200000, input: 100000, output: 100000 }, + }, + "openai/gpt-5.4-mini": { + id: "openai/gpt-5.4-mini", + name: "GPT 5.4 Mini", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-17", + last_updated: "2026-03-17", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.75, output: 4.5, cache_read: 0.075 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "openai/gpt-5.4-nano": { + id: "openai/gpt-5.4-nano", + name: "GPT 5.4 Nano", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-17", + last_updated: "2026-03-17", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.19999999999999998, output: 1.25, cache_read: 0.02 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "openai/gpt-5.2-codex": { + id: "openai/gpt-5.2-codex", + name: "GPT-5.2-Codex", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-12", + last_updated: "2025-12", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "openai/gpt-5.1-codex-mini": { + id: "openai/gpt-5.1-codex-mini", + name: "GPT-5.1 Codex mini", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-05-16", + last_updated: "2025-05-16", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 2, cache_read: 0.03 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "openai/gpt-5.1-thinking": { + id: "openai/gpt-5.1-thinking", + name: "GPT 5.1 Thinking", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-10", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image", "pdf"], output: ["text", "image"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.13 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "openai/gpt-5.4-pro": { + id: "openai/gpt-5.4-pro", + name: "GPT 5.4 Pro", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-05", + last_updated: "2026-03-06", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 30, output: 180 }, + limit: { context: 1050000, input: 922000, output: 128000 }, + }, + "openai/gpt-3.5-turbo": { + id: "openai/gpt-3.5-turbo", + name: "GPT-3.5 Turbo", + family: "gpt", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2021-09", + release_date: "2023-03-01", + last_updated: "2023-03-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 1.5 }, + limit: { context: 16385, input: 12289, output: 4096 }, + }, + "openai/o3-deep-research": { + id: "openai/o3-deep-research", + name: "o3-deep-research", + family: "o", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-10", + release_date: "2024-06-26", + last_updated: "2024-06-26", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 10, output: 40, cache_read: 2.5 }, + limit: { context: 200000, input: 100000, output: 100000 }, + }, + "openai/text-embedding-3-small": { + id: "openai/text-embedding-3-small", + name: "text-embedding-3-small", + family: "text-embedding", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2024-01-25", + last_updated: "2024-01-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.02, output: 0 }, + limit: { context: 8192, input: 6656, output: 1536 }, + }, + "openai/gpt-5.4": { + id: "openai/gpt-5.4", + name: "GPT 5.4", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-05", + last_updated: "2026-03-06", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 15, cache_read: 0.25 }, + limit: { context: 1050000, input: 922000, output: 128000 }, + }, + "openai/gpt-oss-20b": { + id: "openai/gpt-oss-20b", + name: "GPT OSS 20B", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.07, output: 0.3 }, + limit: { context: 131072, input: 98304, output: 32768 }, + }, + "openai/gpt-5-pro": { + id: "openai/gpt-5-pro", + name: "GPT-5 pro", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image", "pdf"], output: ["text", "image"] }, + open_weights: false, + cost: { input: 15, output: 120 }, + limit: { context: 400000, input: 128000, output: 272000 }, + }, + "openai/gpt-oss-safeguard-20b": { + id: "openai/gpt-oss-safeguard-20b", + name: "gpt-oss-safeguard-20b", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2024-12-01", + last_updated: "2024-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.08, output: 0.3, cache_read: 0.04 }, + limit: { context: 131072, input: 65536, output: 65536 }, + }, + "openai/gpt-oss-120b": { + id: "openai/gpt-oss-120b", + name: "GPT OSS 120B", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.5 }, + limit: { context: 131072, output: 131072 }, + }, + "openai/gpt-5.5-pro": { + id: "openai/gpt-5.5-pro", + name: "GPT 5.5 Pro", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-24", + last_updated: "2026-04-24", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 30, output: 180 }, + limit: { context: 1000000, input: 872000, output: 128000 }, + }, + "openai/gpt-3.5-turbo-instruct": { + id: "openai/gpt-3.5-turbo-instruct", + name: "GPT-3.5 Turbo Instruct", + family: "gpt", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2021-09", + release_date: "2023-03-01", + last_updated: "2023-03-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.5, output: 2 }, + limit: { context: 8192, input: 4096, output: 4096 }, + }, + "openai/gpt-5.1-instant": { + id: "openai/gpt-5.1-instant", + name: "GPT-5.1 Instant", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image", "pdf"], output: ["text", "image"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.13 }, + limit: { context: 128000, input: 111616, output: 16384 }, + }, + "openai/gpt-5.1-codex": { + id: "openai/gpt-5.1-codex", + name: "GPT-5.1-Codex", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.13 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "openai/gpt-4.1-mini": { + id: "openai/gpt-4.1-mini", + name: "GPT-4.1 mini", + family: "gpt-mini", + 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, + cost: { input: 0.4, output: 1.6, cache_read: 0.1 }, + limit: { context: 1047576, output: 32768 }, + }, + "openai/gpt-4.1": { + id: "openai/gpt-4.1", + name: "GPT-4.1", + 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, + cost: { input: 2, output: 8, cache_read: 0.5 }, + limit: { context: 1047576, output: 32768 }, + }, + "openai/gpt-5": { + id: "openai/gpt-5", + name: "GPT-5", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "openai/gpt-4o": { + id: "openai/gpt-4o", + name: "GPT-4o", + 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, + cost: { input: 2.5, output: 10, cache_read: 1.25 }, + limit: { context: 128000, output: 16384 }, + }, + "openai/o3": { + id: "openai/o3", + name: "o3", + family: "o", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-05", + release_date: "2025-04-16", + last_updated: "2025-04-16", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 8, cache_read: 0.5 }, + limit: { context: 200000, output: 100000 }, + }, + "openai/gpt-4.1-nano": { + id: "openai/gpt-4.1-nano", + name: "GPT-4.1 nano", + family: "gpt-nano", + 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"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4, cache_read: 0.03 }, + limit: { context: 1047576, output: 32768 }, + }, + "openai/gpt-5-codex": { + id: "openai/gpt-5-codex", + name: "GPT-5-Codex", + family: "gpt-codex", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-09-15", + last_updated: "2025-09-15", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "openai/o3-mini": { + id: "openai/o3-mini", + name: "o3-mini", + family: "o-mini", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-05", + release_date: "2024-12-20", + last_updated: "2025-01-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 4.4, cache_read: 0.55 }, + limit: { context: 200000, output: 100000 }, + }, + "openai/o1": { + id: "openai/o1", + name: "o1", + family: "o", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2023-09", + release_date: "2024-12-05", + last_updated: "2024-12-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 60, cache_read: 7.5 }, + limit: { context: 200000, output: 100000 }, + }, + "openai/o4-mini": { + id: "openai/o4-mini", + name: "o4-mini", + family: "o-mini", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-05", + release_date: "2025-04-16", + last_updated: "2025-04-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 4.4, cache_read: 0.28 }, + limit: { context: 200000, output: 100000 }, + }, + "openai/gpt-4o-mini": { + id: "openai/gpt-4o-mini", + name: "GPT-4o mini", + family: "gpt-mini", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2023-09", + release_date: "2024-07-18", + last_updated: "2024-07-18", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.6, cache_read: 0.08 }, + limit: { context: 128000, output: 16384 }, + }, + "openai/gpt-4-turbo": { + id: "openai/gpt-4-turbo", + name: "GPT-4 Turbo", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + knowledge: "2023-12", + release_date: "2023-11-06", + last_updated: "2024-04-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 10, output: 30 }, + limit: { context: 128000, output: 4096 }, + }, + "openai/gpt-5-nano": { + id: "openai/gpt-5-nano", + name: "GPT-5 Nano", + family: "gpt-nano", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-05-30", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.05, output: 0.4, cache_read: 0.005 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "openai/gpt-5-mini": { + id: "openai/gpt-5-mini", + name: "GPT-5 Mini", + family: "gpt-mini", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-05-30", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 2, cache_read: 0.025 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "amazon/titan-embed-text-v2": { + id: "amazon/titan-embed-text-v2", + name: "Titan Text Embeddings V2", + family: "titan-embed", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2024-04", + last_updated: "2024-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.02, output: 0 }, + limit: { context: 8192, output: 1536 }, + }, + "amazon/nova-2-lite": { + id: "amazon/nova-2-lite", + name: "Nova 2 Lite", + family: "nova", + attachment: true, + reasoning: true, + tool_call: false, + temperature: true, + knowledge: "2024-10", + release_date: "2024-12-01", + last_updated: "2024-12-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 2.5 }, + limit: { context: 1000000, output: 1000000 }, + }, + "amazon/nova-pro": { + id: "amazon/nova-pro", + name: "Nova Pro", + family: "nova-pro", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2024-12-03", + last_updated: "2024-12-03", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.8, output: 3.2, cache_read: 0.2 }, + limit: { context: 300000, output: 8192 }, + }, + "amazon/nova-lite": { + id: "amazon/nova-lite", + name: "Nova Lite", + family: "nova-lite", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2024-12-03", + last_updated: "2024-12-03", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.06, output: 0.24, cache_read: 0.015 }, + limit: { context: 300000, output: 8192 }, + }, + "amazon/nova-micro": { + id: "amazon/nova-micro", + name: "Nova Micro", + family: "nova-micro", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2024-12-03", + last_updated: "2024-12-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.035, output: 0.14, cache_read: 0.00875 }, + limit: { context: 128000, output: 8192 }, + }, + "mistral/mistral-nemo": { + id: "mistral/mistral-nemo", + name: "Mistral Nemo", + family: "mistral-nemo", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-07-01", + last_updated: "2024-07-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.04, output: 0.17 }, + limit: { context: 60288, output: 16000 }, + }, + "mistral/ministral-14b": { + id: "mistral/ministral-14b", + name: "Ministral 14B", + family: "ministral", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-10", + release_date: "2025-12-01", + last_updated: "2025-12-01", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.2 }, + limit: { context: 256000, output: 256000 }, + }, + "mistral/codestral-embed": { + id: "mistral/codestral-embed", + name: "Codestral Embed", + family: "codestral-embed", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2025-05-28", + last_updated: "2025-05-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0 }, + limit: { context: 8192, output: 1536 }, + }, + "mistral/mistral-medium": { + id: "mistral/mistral-medium", + name: "Mistral Medium 3.1", + family: "mistral-medium", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-05-07", + last_updated: "2025-05-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 2 }, + limit: { context: 128000, output: 64000 }, + }, + "mistral/mistral-embed": { + id: "mistral/mistral-embed", + name: "Mistral Embed", + family: "mistral-embed", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2023-12-11", + last_updated: "2023-12-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0 }, + limit: { context: 8192, output: 1536 }, + }, + "mistral/devstral-2": { + id: "mistral/devstral-2", + name: "Devstral 2", + family: "devstral", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-12-09", + last_updated: "2025-12-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 256000, output: 256000 }, + }, + "mistral/mistral-large-3": { + id: "mistral/mistral-large-3", + name: "Mistral Large 3", + family: "mistral-large", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-10", + release_date: "2025-12-02", + last_updated: "2025-12-02", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 1.5 }, + limit: { context: 256000, output: 256000 }, + }, + "mistral/devstral-small-2": { + id: "mistral/devstral-small-2", + name: "Devstral Small 2", + family: "devstral", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-05-07", + last_updated: "2025-05-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 256000, output: 256000 }, + }, + "mistral/devstral-small": { + id: "mistral/devstral-small", + name: "Devstral Small 1.1", + family: "devstral", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-05-07", + last_updated: "2025-05-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.3 }, + limit: { context: 128000, output: 64000 }, + }, + "mistral/ministral-8b": { + id: "mistral/ministral-8b", + name: "Ministral 8B (latest)", + family: "ministral", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2024-10-01", + last_updated: "2024-10-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.1 }, + limit: { context: 128000, output: 128000 }, + }, + "mistral/magistral-medium": { + id: "mistral/magistral-medium", + name: "Magistral Medium (latest)", + family: "magistral-medium", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-06", + release_date: "2025-03-17", + last_updated: "2025-03-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 2, output: 5 }, + limit: { context: 128000, output: 16384 }, + }, + "mistral/mistral-small": { + id: "mistral/mistral-small", + name: "Mistral Small (latest)", + family: "mistral-small", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-06", + release_date: "2026-03-16", + last_updated: "2026-03-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 256000, output: 256000 }, + }, + "mistral/magistral-small": { + id: "mistral/magistral-small", + name: "Magistral Small", + family: "magistral-small", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-06", + release_date: "2025-03-17", + last_updated: "2025-03-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.5, output: 1.5 }, + limit: { context: 128000, output: 128000 }, + }, + "mistral/pixtral-12b": { + id: "mistral/pixtral-12b", + name: "Pixtral 12B", + family: "pixtral", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-09", + release_date: "2024-09-01", + last_updated: "2024-09-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.15 }, + limit: { context: 128000, output: 128000 }, + }, + "mistral/mixtral-8x22b-instruct": { + id: "mistral/mixtral-8x22b-instruct", + name: "Mixtral 8x22B", + family: "mixtral", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-04-17", + last_updated: "2024-04-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 2, output: 6 }, + limit: { context: 64000, output: 64000 }, + }, + "mistral/pixtral-large": { + id: "mistral/pixtral-large", + name: "Pixtral Large (latest)", + family: "pixtral", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-11", + release_date: "2024-11-01", + last_updated: "2024-11-04", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 2, output: 6 }, + limit: { context: 128000, output: 128000 }, + }, + "mistral/ministral-3b": { + id: "mistral/ministral-3b", + name: "Ministral 3B (latest)", + family: "ministral", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2024-10-01", + last_updated: "2024-10-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.04, output: 0.04 }, + limit: { context: 128000, output: 128000 }, + }, + "mistral/codestral": { + id: "mistral/codestral", + name: "Codestral (latest)", + family: "codestral", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2024-05-29", + last_updated: "2025-01-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 0.9 }, + limit: { context: 256000, output: 4096 }, + }, + "meta/llama-3.2-1b": { + id: "meta/llama-3.2-1b", + name: "Llama 3.2 1B Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2023-12", + release_date: "2024-09-18", + last_updated: "2024-09-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.1 }, + limit: { context: 128000, output: 8192 }, + }, + "meta/llama-3.1-8b": { + id: "meta/llama-3.1-8b", + name: "Llama 3.1 8B Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.03, output: 0.05 }, + limit: { context: 131072, output: 16384 }, + }, + "meta/llama-3.2-90b": { + id: "meta/llama-3.2-90b", + name: "Llama 3.2 90B Vision Instruct", + family: "llama", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-09-25", + last_updated: "2024-09-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.72, output: 0.72 }, + limit: { context: 128000, output: 8192 }, + }, + "meta/llama-3.2-3b": { + id: "meta/llama-3.2-3b", + name: "Llama 3.2 3B Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2023-12", + release_date: "2024-09-18", + last_updated: "2024-09-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.15 }, + limit: { context: 128000, output: 8192 }, + }, + "meta/llama-3.2-11b": { + id: "meta/llama-3.2-11b", + name: "Llama 3.2 11B Vision Instruct", + family: "llama", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-09-25", + last_updated: "2024-09-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.16, output: 0.16 }, + limit: { context: 128000, output: 8192 }, + }, + "meta/llama-3.1-70b": { + id: "meta/llama-3.1-70b", + name: "Llama 3.1 70B Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 0.4 }, + limit: { context: 131072, output: 16384 }, + }, + "meta/llama-3.3-70b": { + id: "meta/llama-3.3-70b", + name: "Llama-3.3-70B-Instruct", + family: "llama", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "meta/llama-4-maverick": { + id: "meta/llama-4-maverick", + name: "Llama-4-Maverick-17B-128E-Instruct-FP8", + family: "llama", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-08", + release_date: "2025-04-05", + last_updated: "2025-04-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "meta/llama-4-scout": { + id: "meta/llama-4-scout", + name: "Llama-4-Scout-17B-16E-Instruct-FP8", + family: "llama", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-08", + release_date: "2025-04-05", + last_updated: "2025-04-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "vercel/v0-1.5-md": { + id: "vercel/v0-1.5-md", + name: "v0-1.5-md", + family: "v0", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-06-09", + last_updated: "2025-06-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15 }, + limit: { context: 128000, output: 32000 }, + }, + "vercel/v0-1.0-md": { + id: "vercel/v0-1.0-md", + name: "v0-1.0-md", + family: "v0", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15 }, + limit: { context: 128000, output: 32000 }, + }, + "minimax/minimax-m2.7": { + id: "minimax/minimax-m2.7", + name: "Minimax M2.7", + family: "minimax", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2, cache_read: 0.06, cache_write: 0.375 }, + limit: { context: 204800, output: 131000 }, + }, + "minimax/minimax-m2.7-highspeed": { + id: "minimax/minimax-m2.7-highspeed", + name: "MiniMax M2.7 High Speed", + family: "minimax", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.4, cache_read: 0.06, cache_write: 0.375 }, + limit: { context: 204800, output: 131100 }, + }, + "minimax/minimax-m2": { + id: "minimax/minimax-m2", + name: "MiniMax M2", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-10-27", + last_updated: "2025-10-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.27, output: 1.15, cache_read: 0.03, cache_write: 0.38 }, + limit: { context: 262114, output: 262114 }, + }, + "minimax/minimax-m2.1": { + id: "minimax/minimax-m2.1", + name: "MiniMax M2.1", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-10-27", + last_updated: "2025-10-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 1.2, cache_read: 0.03, cache_write: 0.38 }, + limit: { context: 204800, output: 131072 }, + }, + "minimax/minimax-m2.1-lightning": { + id: "minimax/minimax-m2.1-lightning", + name: "MiniMax M2.1 Lightning", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-10-27", + last_updated: "2025-10-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 2.4, cache_read: 0.03, cache_write: 0.38 }, + limit: { context: 204800, output: 131072 }, + }, + "minimax/minimax-m2.5": { + id: "minimax/minimax-m2.5", + name: "MiniMax M2.5", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-12", + last_updated: "2026-02-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 1.2, cache_read: 0.03, cache_write: 0.375 }, + limit: { context: 204800, output: 131000 }, + }, + "minimax/minimax-m2.5-highspeed": { + id: "minimax/minimax-m2.5-highspeed", + name: "MiniMax M2.5 High Speed", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-12", + last_updated: "2026-03-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.6, output: 2.4, cache_read: 0.03, cache_write: 0.375 }, + limit: { context: 0, output: 0 }, + }, + "kwaipilot/kat-coder-pro-v1": { + id: "kwaipilot/kat-coder-pro-v1", + name: "KAT-Coder-Pro V1", + family: "kat-coder", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + knowledge: "2024-10", + release_date: "2025-10-24", + last_updated: "2025-10-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 256000, output: 32000 }, + }, + "kwaipilot/kat-coder-pro-v2": { + id: "kwaipilot/kat-coder-pro-v2", + name: "Kat Coder Pro V2", + family: "kat-coder", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-27", + last_updated: "2026-03-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 1.2, cache_read: 0.06 }, + limit: { context: 256000, output: 256000 }, + }, + "google/gemini-2.5-flash-lite-preview-09-2025": { + id: "google/gemini-2.5-flash-lite-preview-09-2025", + name: "Gemini 2.5 Flash Lite Preview 09-25", + family: "gemini-flash-lite", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-09-25", + last_updated: "2025-09-25", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4, cache_read: 0.01 }, + limit: { context: 1048576, output: 65536 }, + }, + "google/gemini-3.1-flash-lite-preview": { + id: "google/gemini-3.1-flash-lite-preview", + name: "Gemini 3.1 Flash Lite Preview", + family: "gemini", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-03", + last_updated: "2026-03-06", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 1.5, cache_read: 0.025, cache_write: 1 }, + limit: { context: 1000000, output: 65000 }, + }, + "google/gemini-3-pro-image": { + id: "google/gemini-3-pro-image", + name: "Nano Banana Pro (Gemini 3 Pro Image)", + family: "gemini-pro", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2025-03", + release_date: "2025-09", + last_updated: "2025-09", + modalities: { input: ["text"], output: ["text", "image"] }, + open_weights: false, + cost: { input: 2, output: 120 }, + limit: { context: 65536, output: 32768 }, + }, + "google/gemini-3.1-pro-preview": { + id: "google/gemini-3.1-pro-preview", + name: "Gemini 3.1 Pro Preview", + family: "gemini", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-19", + last_updated: "2026-02-24", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 12, cache_read: 0.2 }, + limit: { context: 1000000, output: 64000 }, + }, + "google/gemini-3-pro-preview": { + id: "google/gemini-3-pro-preview", + name: "Gemini 3 Pro Preview", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-11-18", + last_updated: "2025-11-18", + modalities: { input: ["text", "image", "video", "audio", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 12, cache_read: 0.2, context_over_200k: { input: 4, output: 18, cache_read: 0.4 } }, + limit: { context: 1000000, output: 64000 }, + }, + "google/imagen-4.0-ultra-generate-001": { + id: "google/imagen-4.0-ultra-generate-001", + name: "Imagen 4 Ultra", + family: "imagen", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2025-05-24", + last_updated: "2025-05-24", + modalities: { input: ["text"], output: ["image"] }, + open_weights: false, + limit: { context: 480, output: 0 }, + }, + "google/gemini-embedding-001": { + id: "google/gemini-embedding-001", + name: "Gemini Embedding 001", + family: "gemini-embedding", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2025-05-20", + last_updated: "2025-05-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0 }, + limit: { context: 8192, output: 1536 }, + }, + "google/gemma-4-31b-it": { + id: "google/gemma-4-31b-it", + name: "Gemma 4 31B IT", + family: "gemma", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-02", + last_updated: "2026-04-03", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.14, output: 0.39999999999999997 }, + limit: { context: 262144, output: 131072 }, + }, + "google/gemini-2.5-flash-image": { + id: "google/gemini-2.5-flash-image", + name: "Nano Banana (Gemini 2.5 Flash Image)", + family: "gemini-flash", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2025-01", + release_date: "2025-03-20", + last_updated: "2025-03-20", + modalities: { input: ["text"], output: ["text", "image"] }, + open_weights: false, + cost: { input: 0.3, output: 2.5 }, + limit: { context: 32768, output: 32768 }, + }, + "google/text-embedding-005": { + id: "google/text-embedding-005", + name: "Text Embedding 005", + family: "text-embedding", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2024-08", + last_updated: "2024-08", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.03, output: 0 }, + limit: { context: 8192, output: 1536 }, + }, + "google/text-multilingual-embedding-002": { + id: "google/text-multilingual-embedding-002", + name: "Text Multilingual Embedding 002", + family: "text-embedding", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2024-03", + last_updated: "2024-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.03, output: 0 }, + limit: { context: 8192, output: 1536 }, + }, + "google/gemini-3.1-flash-image-preview": { + id: "google/gemini-3.1-flash-image-preview", + name: "Gemini 3.1 Flash Image Preview (Nano Banana 2)", + family: "gemini", + attachment: true, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2026-02-26", + last_updated: "2026-03-06", + modalities: { input: ["text", "image"], output: ["text", "image"] }, + open_weights: false, + cost: { input: 0.5, output: 3 }, + limit: { context: 131072, output: 32768 }, + }, + "google/gemini-3.1-flash-lite": { + id: "google/gemini-3.1-flash-lite", + name: "Gemini 3.1 Flash Lite", + family: "gemini", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-05-07", + last_updated: "2026-05-08", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 1.5, cache_read: 0.03 }, + limit: { context: 1000000, output: 65000 }, + }, + "google/gemini-3-flash": { + id: "google/gemini-3-flash", + name: "Gemini 3 Flash", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03", + release_date: "2025-12-17", + last_updated: "2025-12-17", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 3, cache_read: 0.05 }, + limit: { context: 1000000, output: 64000 }, + }, + "google/imagen-4.0-generate-001": { + id: "google/imagen-4.0-generate-001", + name: "Imagen 4", + family: "imagen", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text"], output: ["image"] }, + open_weights: false, + limit: { context: 480, output: 0 }, + }, + "google/gemini-2.5-flash-preview-09-2025": { + id: "google/gemini-2.5-flash-preview-09-2025", + name: "Gemini 2.5 Flash Preview 09-25", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-09-25", + last_updated: "2025-09-25", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 2.5, cache_read: 0.03, cache_write: 0.383 }, + limit: { context: 1048576, output: 65536 }, + }, + "google/gemini-embedding-2": { + id: "google/gemini-embedding-2", + name: "Gemini Embedding 2", + family: "gemini-embedding", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2026-03-10", + last_updated: "2026-03-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 0, output: 0 }, + }, + "google/gemma-4-26b-a4b-it": { + id: "google/gemma-4-26b-a4b-it", + name: "Gemma 4 26B A4B IT", + family: "gemma", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-02", + last_updated: "2026-04-03", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.13, output: 0.39999999999999997 }, + limit: { context: 262144, output: 131072 }, + }, + "google/imagen-4.0-fast-generate-001": { + id: "google/imagen-4.0-fast-generate-001", + name: "Imagen 4 Fast", + family: "imagen", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2025-06", + last_updated: "2025-06", + modalities: { input: ["text"], output: ["image"] }, + open_weights: false, + limit: { context: 480, output: 0 }, + }, + "google/gemini-2.5-flash-lite": { + id: "google/gemini-2.5-flash-lite", + name: "Gemini 2.5 Flash Lite", + family: "gemini-flash-lite", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-06-17", + last_updated: "2025-06-17", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4, cache_read: 0.01 }, + limit: { context: 1048576, output: 65536 }, + }, + "google/gemini-2.5-flash-image-preview": { + id: "google/gemini-2.5-flash-image-preview", + name: "Nano Banana Preview (Gemini 2.5 Flash Image Preview)", + family: "gemini-flash", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2025-01", + release_date: "2025-03-20", + last_updated: "2025-03-20", + modalities: { input: ["text"], output: ["text", "image"] }, + open_weights: false, + cost: { input: 0.3, output: 2.5 }, + limit: { context: 32768, output: 32768 }, + }, + "google/gemini-2.0-flash-lite": { + id: "google/gemini-2.0-flash-lite", + name: "Gemini 2.0 Flash Lite", + family: "gemini-flash-lite", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-06", + release_date: "2024-12-11", + last_updated: "2024-12-11", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.075, output: 0.3 }, + limit: { context: 1048576, output: 8192 }, + }, + "google/gemini-2.5-flash": { + id: "google/gemini-2.5-flash", + name: "Gemini 2.5 Flash", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-03-20", + last_updated: "2025-06-05", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 2.5, cache_read: 0.03, input_audio: 1 }, + limit: { context: 1048576, output: 65536 }, + }, + "google/gemini-2.5-pro": { + id: "google/gemini-2.5-pro", + name: "Gemini 2.5 Pro", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-03-20", + last_updated: "2025-06-05", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 1.25, + output: 10, + cache_read: 0.125, + context_over_200k: { input: 2.5, output: 15, cache_read: 0.25 }, + }, + limit: { context: 1048576, output: 65536 }, + }, + "google/gemini-2.0-flash": { + id: "google/gemini-2.0-flash", + name: "Gemini 2.0 Flash", + family: "gemini-flash", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-06", + release_date: "2024-12-11", + last_updated: "2024-12-11", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4, cache_read: 0.025 }, + limit: { context: 1048576, output: 8192 }, + }, + "moonshotai/kimi-k2-turbo": { + id: "moonshotai/kimi-k2-turbo", + name: "Kimi K2 Turbo", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-08", + release_date: "2025-09-05", + last_updated: "2025-09-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2.4, output: 10 }, + limit: { context: 256000, output: 16384 }, + }, + "moonshotai/kimi-k2.5": { + id: "moonshotai/kimi-k2.5", + name: "Kimi K2.5", + family: "kimi", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-01-26", + last_updated: "2026-01-26", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 1.2 }, + limit: { context: 262144, output: 262144 }, + }, + "moonshotai/kimi-k2-thinking-turbo": { + id: "moonshotai/kimi-k2-thinking-turbo", + name: "Kimi K2 Thinking Turbo", + family: "kimi-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: true, + temperature: true, + knowledge: "2024-08", + release_date: "2025-11-06", + last_updated: "2025-11-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.15, output: 8, cache_read: 0.15 }, + limit: { context: 262114, output: 262114 }, + }, + "moonshotai/kimi-k2-0905": { + id: "moonshotai/kimi-k2-0905", + name: "Kimi K2 0905", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-10", + release_date: "2025-09-05", + last_updated: "2025-09-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.6, output: 2.5 }, + limit: { context: 131072, output: 16384 }, + }, + "moonshotai/kimi-k2.6": { + id: "moonshotai/kimi-k2.6", + name: "Kimi K2.6", + family: "kimi-k2.6", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-20", + last_updated: "2026-04-24", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: true, + cost: { input: 0.95, output: 4, cache_read: 0.16 }, + limit: { context: 262000, output: 262000 }, + }, + "moonshotai/kimi-k2-thinking": { + id: "moonshotai/kimi-k2-thinking", + name: "Kimi K2 Thinking", + family: "kimi-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: true, + temperature: true, + knowledge: "2024-08", + release_date: "2025-11-06", + last_updated: "2025-11-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.47, output: 2, cache_read: 0.14 }, + limit: { context: 216144, output: 216144 }, + }, + "moonshotai/kimi-k2": { + id: "moonshotai/kimi-k2", + name: "Kimi K2 Instruct", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-07-14", + last_updated: "2025-07-14", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 3 }, + limit: { context: 131072, output: 16384 }, + status: "deprecated", + }, + "interfaze/interfaze-beta": { + id: "interfaze/interfaze-beta", + name: "Interfaze Beta", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2025-10-07", + last_updated: "2026-04-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.5, output: 3.5 }, + limit: { context: 1000000, output: 32000 }, + }, + "anthropic/claude-3.5-sonnet-20240620": { + id: "anthropic/claude-3.5-sonnet-20240620", + name: "Claude 3.5 Sonnet (2024-06-20)", + family: "claude-sonnet", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-06-20", + last_updated: "2024-06-20", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15 }, + limit: { context: 200000, output: 8192 }, + }, + "anthropic/claude-opus-4.6": { + id: "anthropic/claude-opus-4.6", + name: "Claude Opus 4.6", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: true, + temperature: true, + knowledge: "2025-05-31", + release_date: "2026-02", + last_updated: "2026-02", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 1000000, output: 128000 }, + }, + "anthropic/claude-opus-4.7": { + id: "anthropic/claude-opus-4.7", + name: "Claude Opus 4.7", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + release_date: "2026-04-16", + last_updated: "2026-04-16", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 1000000, output: 128000 }, + }, + "anthropic/claude-opus-4.5": { + id: "anthropic/claude-opus-4.5", + name: "Claude Opus 4.5", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-11-24", + last_updated: "2025-11-24", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 18.75 }, + limit: { context: 200000, output: 64000 }, + }, + "anthropic/claude-haiku-4.5": { + id: "anthropic/claude-haiku-4.5", + name: "Claude Haiku 4.5", + family: "claude-haiku", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: true, + temperature: true, + knowledge: "2025-02-28", + release_date: "2025-10-15", + last_updated: "2025-10-15", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 5, cache_read: 0.1, cache_write: 1.25 }, + limit: { context: 200000, output: 64000 }, + }, + "anthropic/claude-sonnet-4.6": { + id: "anthropic/claude-sonnet-4.6", + name: "Claude Sonnet 4.6", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: true, + temperature: true, + knowledge: "2025-08-31", + release_date: "2026-02-17", + last_updated: "2026-02-17", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 3, + output: 15, + cache_read: 0.3, + cache_write: 3.75, + context_over_200k: { input: 6, output: 22.5, cache_read: 0.6, cache_write: 7.5 }, + }, + limit: { context: 1000000, output: 128000 }, + }, + "anthropic/claude-3-opus": { + id: "anthropic/claude-3-opus", + name: "Claude Opus 3", + family: "claude-opus", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-08-31", + release_date: "2024-02-29", + last_updated: "2024-02-29", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 4096 }, + }, + "anthropic/claude-3.5-haiku": { + id: "anthropic/claude-3.5-haiku", + name: "Claude Haiku 3.5", + family: "claude-haiku", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-07-31", + release_date: "2024-10-22", + last_updated: "2024-10-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.8, output: 4, cache_read: 0.08, cache_write: 1 }, + limit: { context: 200000, output: 8192 }, + }, + "anthropic/claude-opus-4": { + id: "anthropic/claude-opus-4", + name: "Claude Opus 4", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 32000 }, + }, + "anthropic/claude-3-haiku": { + id: "anthropic/claude-3-haiku", + name: "Claude Haiku 3", + family: "claude-haiku", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-08-31", + release_date: "2024-03-13", + last_updated: "2024-03-13", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 1.25, cache_read: 0.03, cache_write: 0.3 }, + limit: { context: 200000, output: 4096 }, + }, + "anthropic/claude-sonnet-4.5": { + id: "anthropic/claude-sonnet-4.5", + name: "Claude Sonnet 4.5", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07-31", + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + }, + "anthropic/claude-sonnet-4": { + id: "anthropic/claude-sonnet-4", + name: "Claude Sonnet 4", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + }, + "anthropic/claude-3.5-sonnet": { + id: "anthropic/claude-3.5-sonnet", + name: "Claude Sonnet 3.5 v2", + family: "claude-sonnet", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04-30", + release_date: "2024-10-22", + last_updated: "2024-10-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 8192 }, + }, + "anthropic/claude-3.7-sonnet": { + id: "anthropic/claude-3.7-sonnet", + name: "Claude Sonnet 3.7", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10-31", + release_date: "2025-02-19", + last_updated: "2025-02-19", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + }, + "anthropic/claude-opus-4.1": { + id: "anthropic/claude-opus-4.1", + name: "Claude Opus 4", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 32000 }, + }, + "xiaomi/mimo-v2.5-pro": { + id: "xiaomi/mimo-v2.5-pro", + name: "MiMo V2.5 Pro", + family: "mimo-v2.5-pro", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-22", + last_updated: "2026-05-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 3, cache_read: 0.19999999999999998 }, + limit: { context: 1050000, output: 131000 }, + }, + "xiaomi/mimo-v2.5": { + id: "xiaomi/mimo-v2.5", + name: "MiMo M2.5", + family: "mimo-v2.5", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-22", + last_updated: "2026-05-01", + modalities: { input: ["text", "image", "audio", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.39999999999999997, output: 2, cache_read: 0.08 }, + limit: { context: 1050000, output: 131100 }, + }, + "xiaomi/mimo-v2-pro": { + id: "xiaomi/mimo-v2-pro", + name: "MiMo V2 Pro", + family: "mimo", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-18", + last_updated: "2026-03-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 3, cache_read: 0.19999999999999998 }, + limit: { context: 1000000, output: 128000 }, + }, + "xiaomi/mimo-v2-flash": { + id: "xiaomi/mimo-v2-flash", + name: "MiMo V2 Flash", + family: "mimo", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-12-17", + last_updated: "2025-12-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.29 }, + limit: { context: 262144, output: 32000 }, + }, + "bytedance/seed-1.6": { + id: "bytedance/seed-1.6", + name: "Seed 1.6", + family: "seed", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-09", + last_updated: "2025-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 2, cache_read: 0.05 }, + limit: { context: 256000, output: 32000 }, + }, + "bytedance/seed-1.8": { + id: "bytedance/seed-1.8", + name: "Seed 1.8", + family: "seed", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-10", + last_updated: "2025-10", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 2, cache_read: 0.05 }, + limit: { context: 256000, output: 64000 }, + }, + "meituan/longcat-flash-chat": { + id: "meituan/longcat-flash-chat", + name: "LongCat Flash Chat", + family: "longcat", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-08-30", + last_updated: "2025-08-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 128000, output: 8192 }, + }, + "meituan/longcat-flash-thinking": { + id: "meituan/longcat-flash-thinking", + name: "LongCat Flash Thinking", + family: "longcat", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-09-23", + last_updated: "2025-09-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 1.5 }, + limit: { context: 128000, output: 8192 }, + }, + "meituan/longcat-flash-thinking-2601": { + id: "meituan/longcat-flash-thinking-2601", + name: "LongCat Flash Thinking 2601", + family: "longcat", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + release_date: "2026-03-13", + last_updated: "2026-03-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + limit: { context: 32768, output: 32768 }, + }, + "bfl/flux-pro-1.0-fill": { + id: "bfl/flux-pro-1.0-fill", + name: "FLUX.1 Fill [pro]", + family: "flux", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2024-10", + last_updated: "2024-10", + modalities: { input: ["text"], output: ["image"] }, + open_weights: false, + limit: { context: 512, output: 0 }, + }, + "bfl/flux-pro-1.1": { + id: "bfl/flux-pro-1.1", + name: "FLUX1.1 [pro]", + family: "flux", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2024-10", + last_updated: "2024-10", + modalities: { input: ["text"], output: ["image"] }, + open_weights: false, + limit: { context: 512, output: 0 }, + }, + "bfl/flux-kontext-pro": { + id: "bfl/flux-kontext-pro", + name: "FLUX.1 Kontext Pro", + family: "flux", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2025-06", + last_updated: "2025-06", + modalities: { input: ["text"], output: ["image"] }, + open_weights: false, + limit: { context: 512, output: 0 }, + }, + "bfl/flux-kontext-max": { + id: "bfl/flux-kontext-max", + name: "FLUX.1 Kontext Max", + family: "flux", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2025-06", + last_updated: "2025-06", + modalities: { input: ["text"], output: ["image"] }, + open_weights: false, + limit: { context: 512, output: 0 }, + }, + "bfl/flux-pro-1.1-ultra": { + id: "bfl/flux-pro-1.1-ultra", + name: "FLUX1.1 [pro] Ultra", + family: "flux", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2024-11", + last_updated: "2024-11", + modalities: { input: ["text"], output: ["image"] }, + open_weights: false, + limit: { context: 512, output: 0 }, + }, + }, + }, + minimax: { + id: "minimax", + env: ["MINIMAX_API_KEY"], + npm: "@ai-sdk/anthropic", + api: "https://api.minimax.io/anthropic/v1", + name: "MiniMax (minimax.io)", + doc: "https://platform.minimax.io/docs/guides/quickstart", + models: { + "MiniMax-M2": { + id: "MiniMax-M2", + name: "MiniMax-M2", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-10-27", + last_updated: "2025-10-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 196608, output: 128000 }, + }, + "MiniMax-M2.5": { + id: "MiniMax-M2.5", + name: "MiniMax-M2.5", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2, cache_read: 0.03, cache_write: 0.375 }, + limit: { context: 204800, output: 131072 }, + }, + "MiniMax-M2.7": { + id: "MiniMax-M2.7", + name: "MiniMax-M2.7", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2, cache_read: 0.06, cache_write: 0.375 }, + limit: { context: 204800, output: 131072 }, + }, + "MiniMax-M2.7-highspeed": { + id: "MiniMax-M2.7-highspeed", + name: "MiniMax-M2.7-highspeed", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.4, cache_read: 0.06, cache_write: 0.375 }, + limit: { context: 204800, output: 131072 }, + }, + "MiniMax-M2.1": { + id: "MiniMax-M2.1", + name: "MiniMax-M2.1", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-12-23", + last_updated: "2025-12-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 204800, output: 131072 }, + }, + "MiniMax-M2.5-highspeed": { + id: "MiniMax-M2.5-highspeed", + name: "MiniMax-M2.5-highspeed", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-13", + last_updated: "2026-02-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.4, cache_read: 0.06, cache_write: 0.375 }, + limit: { context: 204800, output: 131072 }, + }, + }, + }, + llmgateway: { + id: "llmgateway", + env: ["LLMGATEWAY_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.llmgateway.io/v1", + name: "LLM Gateway", + doc: "https://llmgateway.io/docs", + models: { + "gpt-4o-mini-search-preview": { + id: "gpt-4o-mini-search-preview", + name: "GPT-4o Mini Search Preview", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2024-10-01", + last_updated: "2024-10-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 128000, output: 16384 }, + }, + "grok-4-1-fast-reasoning": { + id: "grok-4-1-fast-reasoning", + name: "Grok 4.1 Fast Reasoning", + family: "grok", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-11-19", + last_updated: "2025-11-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5, cache_read: 0.05 }, + limit: { context: 2000000, output: 30000 }, + }, + "qwen3-235b-a22b-instruct-2507": { + id: "qwen3-235b-a22b-instruct-2507", + name: "Qwen3 235B A22B Instruct (2507)", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-07-08", + last_updated: "2025-07-08", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.8, output: 2.4 }, + limit: { context: 131072, output: 8192 }, + }, + "llama-4-scout": { + id: "llama-4-scout", + name: "Llama 4 Scout", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-04-05", + last_updated: "2025-04-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.18, output: 0.59 }, + limit: { context: 32768, output: 16384 }, + status: "beta", + }, + "hermes-2-pro-llama-3-8b": { + id: "hermes-2-pro-llama-3-8b", + name: "Hermes 2 Pro Llama 3 8B", + family: "hermes", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2024-05-27", + last_updated: "2024-05-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.14, output: 0.14 }, + limit: { context: 8192, output: 8192 }, + }, + "qwen-coder-plus": { + id: "qwen-coder-plus", + name: "Qwen Coder Plus", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-09-18", + last_updated: "2024-09-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 1 }, + limit: { context: 131072, output: 8192 }, + }, + auto: { + id: "auto", + name: "Auto Route", + family: "auto", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-01-01", + last_updated: "2024-01-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 16384 }, + }, + "glm-4.6v-flashx": { + id: "glm-4.6v-flashx", + name: "GLM-4.6V FlashX", + family: "glm", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-12-08", + last_updated: "2025-12-08", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.04, output: 0.4, cache_read: 0 }, + limit: { context: 128000, output: 16000 }, + }, + "gemma-2-27b-it-together": { + id: "gemma-2-27b-it-together", + name: "Gemma 2 27B IT", + family: "gemma", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2024-06-27", + last_updated: "2024-06-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.08, output: 0.08 }, + limit: { context: 8192, output: 16384 }, + }, + "codestral-2508": { + id: "codestral-2508", + name: "Codestral", + family: "mistral", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: true, + temperature: true, + release_date: "2025-07-30", + last_updated: "2025-07-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 0.9 }, + limit: { context: 256000, output: 16384 }, + }, + "gemma-3-1b-it": { + id: "gemma-3-1b-it", + name: "Gemma 3 1B IT", + family: "gemma", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2025-03-12", + last_updated: "2025-03-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.08, output: 0.3 }, + limit: { context: 1000000, output: 16384 }, + }, + "glm-4-32b-0414-128k": { + id: "glm-4-32b-0414-128k", + name: "GLM-4 32B (0414-128k)", + family: "glm", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-04-14", + last_updated: "2025-04-14", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.1 }, + limit: { context: 128000, output: 16384 }, + }, + "seed-1-6-flash-250715": { + id: "seed-1-6-flash-250715", + name: "Seed 1.6 Flash (250715)", + family: "seed", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-07-26", + last_updated: "2025-07-26", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.07, output: 0.3, cache_read: 0.01 }, + limit: { context: 256000, output: 8192 }, + }, + "seed-1-6-250615": { + id: "seed-1-6-250615", + name: "Seed 1.6 (250615)", + family: "seed", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-06-25", + last_updated: "2025-06-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.25, output: 2, cache_read: 0.05 }, + limit: { context: 256000, output: 8192 }, + }, + "qwen3-vl-235b-a22b-thinking": { + id: "qwen3-vl-235b-a22b-thinking", + name: "Qwen3 VL 235B A22B Thinking", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-09-15", + last_updated: "2025-09-15", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.8, output: 2.4 }, + limit: { context: 131072, output: 8192 }, + }, + "qwen3-vl-30b-a3b-thinking": { + id: "qwen3-vl-30b-a3b-thinking", + name: "Qwen3 VL 30B A3B Thinking", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-10-02", + last_updated: "2025-10-02", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.1 }, + limit: { context: 131072, output: 8192 }, + }, + "qwen2-5-vl-32b-instruct": { + id: "qwen2-5-vl-32b-instruct", + name: "Qwen2.5 VL 32B Instruct", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-03-15", + last_updated: "2025-03-15", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 0.3 }, + limit: { context: 131072, output: 8192 }, + }, + "qwen3-vl-8b-instruct": { + id: "qwen3-vl-8b-instruct", + name: "Qwen3 VL 8B Instruct", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2025-08-19", + last_updated: "2025-08-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.1 }, + limit: { context: 131072, output: 8192 }, + }, + "claude-3-7-sonnet": { + id: "claude-3-7-sonnet", + name: "Claude 3.7 Sonnet", + family: "claude", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-02-24", + last_updated: "2025-02-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3 }, + limit: { context: 200000, output: 8192 }, + }, + "gemini-pro-latest": { + id: "gemini-pro-latest", + name: "Gemini Pro Latest", + family: "gemini", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-02-27", + last_updated: "2026-02-27", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 12, cache_read: 0.2 }, + limit: { context: 1048576, output: 65536 }, + }, + "claude-3-5-haiku": { + id: "claude-3-5-haiku", + name: "Claude 3.5 Haiku", + family: "claude", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2024-10-22", + last_updated: "2024-10-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.8, output: 4, cache_read: 0.08 }, + limit: { context: 200000, output: 8192 }, + status: "deprecated", + }, + "qwen-max-latest": { + id: "qwen-max-latest", + name: "Qwen Max Latest", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-01-25", + last_updated: "2025-01-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.6, output: 6.4 }, + limit: { context: 32768, output: 8192 }, + }, + "glm-4.6v-flash": { + id: "glm-4.6v-flash", + name: "GLM-4.6V Flash", + family: "glm", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-12-08", + last_updated: "2025-12-08", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 16000 }, + status: "beta", + }, + "qwen3-30b-a3b-instruct-2507": { + id: "qwen3-30b-a3b-instruct-2507", + name: "Qwen3 30B A3B Instruct (2507)", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-07-08", + last_updated: "2025-07-08", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.1 }, + limit: { context: 131072, output: 8192 }, + }, + "minimax-text-01": { + id: "minimax-text-01", + name: "MiniMax Text 01", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2025-01-15", + last_updated: "2025-01-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 1.1 }, + limit: { context: 1000000, output: 131072 }, + }, + "qwen3-32b-fp8": { + id: "qwen3-32b-fp8", + name: "Qwen3 32B FP8", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-04-28", + last_updated: "2025-04-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.1 }, + limit: { context: 131072, output: 8192 }, + }, + "llama-4-scout-17b-instruct": { + id: "llama-4-scout-17b-instruct", + name: "Llama 4 Scout 17B Instruct", + family: "llama", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2025-04-05", + last_updated: "2025-04-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.17, output: 0.66 }, + limit: { context: 8192, output: 2048 }, + }, + "qwen3-4b-fp8": { + id: "qwen3-4b-fp8", + name: "Qwen3 4B FP8", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-04-28", + last_updated: "2025-04-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.03, output: 0.05 }, + limit: { context: 131072, output: 8192 }, + }, + "ministral-8b-2512": { + id: "ministral-8b-2512", + name: "Ministral 8B", + family: "mistral", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: true, + temperature: true, + release_date: "2025-12-02", + last_updated: "2025-12-02", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.15 }, + limit: { context: 262144, output: 8192 }, + }, + "gemma-3-27b": { + id: "gemma-3-27b", + name: "Gemma 3 27B", + family: "gemma", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2025-03-12", + last_updated: "2025-03-12", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.27, output: 0.27 }, + limit: { context: 128000, output: 16384 }, + }, + "qwen3-vl-flash": { + id: "qwen3-vl-flash", + name: "Qwen3 VL Flash", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-10-09", + last_updated: "2025-10-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.05, output: 0.4, cache_read: 0.01 }, + limit: { context: 1000000, output: 32000 }, + }, + "llama-3.1-70b-instruct": { + id: "llama-3.1-70b-instruct", + name: "Llama 3.1 70B Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.72, output: 0.72 }, + limit: { context: 128000, output: 2048 }, + status: "beta", + }, + "seed-1-8-251228": { + id: "seed-1-8-251228", + name: "Seed 1.8 (251228)", + family: "seed", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-12-18", + last_updated: "2025-12-18", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.25, output: 2, cache_read: 0.05 }, + limit: { context: 256000, output: 8192 }, + }, + "qwen3-235b-a22b-thinking-2507": { + id: "qwen3-235b-a22b-thinking-2507", + name: "Qwen3 235B A22B Thinking (2507)", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-07-08", + last_updated: "2025-07-08", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.8, output: 2.4 }, + limit: { context: 131072, output: 8192 }, + }, + "seed-1-6-250915": { + id: "seed-1-6-250915", + name: "Seed 1.6 (250915)", + family: "seed", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-09-15", + last_updated: "2025-09-15", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.25, output: 2, cache_read: 0.05 }, + limit: { context: 256000, output: 8192 }, + }, + "glm-4.5-x": { + id: "glm-4.5-x", + name: "GLM-4.5 X", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-07-28", + last_updated: "2025-07-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2.2, output: 8.9, cache_read: 0.45 }, + limit: { context: 128000, output: 16384 }, + status: "beta", + }, + "qwen3-30b-a3b-thinking-2507": { + id: "qwen3-30b-a3b-thinking-2507", + name: "Qwen3 30B A3B Thinking (2507)", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-07-08", + last_updated: "2025-07-08", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.1 }, + limit: { context: 131072, output: 8192 }, + }, + "grok-4-fast-reasoning": { + id: "grok-4-fast-reasoning", + name: "Grok 4 Fast Reasoning", + family: "grok", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-07-09", + last_updated: "2025-07-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5, cache_read: 0.05 }, + limit: { context: 2000000, output: 30000 }, + }, + "deepseek-v3.1": { + id: "deepseek-v3.1", + name: "DeepSeek V3.1", + family: "deepseek", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-08-21", + last_updated: "2025-08-21", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.56, output: 1.68, cache_read: 0.11 }, + limit: { context: 128000, output: 32768 }, + }, + "ministral-3b-2512": { + id: "ministral-3b-2512", + name: "Ministral 3B", + family: "mistral", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: true, + temperature: true, + release_date: "2025-12-02", + last_updated: "2025-12-02", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.1 }, + limit: { context: 131072, output: 8192 }, + }, + "qwen-plus-latest": { + id: "qwen-plus-latest", + name: "Qwen Plus Latest", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-01-25", + last_updated: "2025-01-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 0.9 }, + limit: { context: 131072, output: 8192 }, + }, + "llama-3.1-nemotron-ultra-253b": { + id: "llama-3.1-nemotron-ultra-253b", + name: "Llama 3.1 Nemotron Ultra 253B", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: true, + temperature: true, + release_date: "2025-04-07", + last_updated: "2025-04-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 1.8 }, + limit: { context: 128000, output: 8192 }, + }, + "llama-4-maverick-17b-instruct": { + id: "llama-4-maverick-17b-instruct", + name: "Llama 4 Maverick 17B Instruct", + family: "llama", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2025-04-05", + last_updated: "2025-04-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.24, output: 0.97 }, + limit: { context: 8192, output: 2048 }, + }, + "grok-4-0709": { + id: "grok-4-0709", + name: "Grok 4 (0709)", + family: "grok", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-07-09", + last_updated: "2025-07-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15 }, + limit: { context: 256000, output: 256000 }, + }, + "qwen3-30b-a3b-fp8": { + id: "qwen3-30b-a3b-fp8", + name: "Qwen3 30B A3B FP8", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-04-28", + last_updated: "2025-04-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.1 }, + limit: { context: 131072, output: 8192 }, + }, + "minimax-m2.1-lightning": { + id: "minimax-m2.1-lightning", + name: "MiniMax M2.1 Lightning", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2025-12-23", + last_updated: "2025-12-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.12, output: 0.48 }, + limit: { context: 196608, output: 131072 }, + }, + "qwen3-max-2026-01-23": { + id: "qwen3-max-2026-01-23", + name: "Qwen3 Max (2026-01-23)", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-01-23", + last_updated: "2026-01-23", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.6 }, + limit: { context: 256000, output: 32800 }, + }, + "llama-3.2-3b-instruct": { + id: "llama-3.2-3b-instruct", + name: "Llama 3.2 3B Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: true, + temperature: true, + release_date: "2024-09-18", + last_updated: "2024-09-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.03, output: 0.05 }, + limit: { context: 32768, output: 32000 }, + }, + "qwen3-coder-next": { + id: "qwen3-coder-next", + name: "Qwen3 Coder Next", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-10-15", + last_updated: "2025-10-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.8, output: 4 }, + limit: { context: 262144, output: 65536 }, + }, + "gpt-4o-search-preview": { + id: "gpt-4o-search-preview", + name: "GPT-4o Search Preview", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2024-10-01", + last_updated: "2024-10-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 10 }, + limit: { context: 128000, output: 16384 }, + }, + custom: { + id: "custom", + name: "Custom Model", + family: "auto", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-01-01", + last_updated: "2024-01-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 16384 }, + }, + "qwen3-vl-30b-a3b-instruct": { + id: "qwen3-vl-30b-a3b-instruct", + name: "Qwen3 VL 30B A3B Instruct", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-10-02", + last_updated: "2025-10-02", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.1 }, + limit: { context: 131072, output: 8192 }, + }, + "deepseek-v3.2": { + id: "deepseek-v3.2", + name: "DeepSeek V3.2", + family: "deepseek", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.28, output: 0.42, cache_read: 0.03 }, + limit: { context: 163840, output: 16384 }, + }, + "qwen3-235b-a22b-fp8": { + id: "qwen3-235b-a22b-fp8", + name: "Qwen3 235B A22B FP8", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-04-28", + last_updated: "2025-04-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.5, output: 2.5 }, + limit: { context: 131072, output: 8192 }, + }, + "gpt-oss-20b": { + id: "gpt-oss-20b", + name: "GPT OSS 20B", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.5 }, + limit: { context: 131072, output: 32766 }, + }, + "kimi-k2": { + id: "kimi-k2", + name: "Kimi K2", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-07-11", + last_updated: "2025-07-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 3, cache_read: 0.5 }, + limit: { context: 131072, output: 16384 }, + }, + "llama-3-8b-instruct": { + id: "llama-3-8b-instruct", + name: "Llama 3 8B Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: true, + temperature: true, + release_date: "2025-04-03", + last_updated: "2025-04-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.04, output: 0.04 }, + limit: { context: 8192, output: 8192 }, + }, + "qwen3-vl-235b-a22b-instruct": { + id: "qwen3-vl-235b-a22b-instruct", + name: "Qwen3 VL 235B A22B Instruct", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-09-15", + last_updated: "2025-09-15", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.8, output: 2.4 }, + limit: { context: 131072, output: 8192 }, + }, + "gpt-oss-120b": { + id: "gpt-oss-120b", + name: "GPT OSS 120B", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.75 }, + limit: { context: 131072, output: 32766 }, + }, + "qwen25-coder-7b": { + id: "qwen25-coder-7b", + name: "Qwen2.5 Coder 7B", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: true, + temperature: true, + release_date: "2024-09-19", + last_updated: "2024-09-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.05, output: 0.05 }, + limit: { context: 131072, output: 8192 }, + }, + "llama-3.1-8b-instruct": { + id: "llama-3.1-8b-instruct", + name: "Llama 3.1 8B Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.22, output: 0.22 }, + limit: { context: 128000, output: 2048 }, + status: "beta", + }, + "llama-3-70b-instruct": { + id: "llama-3-70b-instruct", + name: "Llama 3 70B Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: true, + temperature: true, + release_date: "2024-04-18", + last_updated: "2024-04-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.51, output: 0.74 }, + limit: { context: 8192, output: 8000 }, + }, + "deepseek-r1-0528": { + id: "deepseek-r1-0528", + name: "DeepSeek R1 (0528)", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2025-05-28", + last_updated: "2025-05-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.8, output: 2.4 }, + limit: { context: 64000, output: 16384 }, + status: "beta", + }, + "glm-4.5-airx": { + id: "glm-4.5-airx", + name: "GLM-4.5 AirX", + family: "glm", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-07-28", + last_updated: "2025-07-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 4.5, cache_read: 0.22 }, + limit: { context: 128000, output: 16384 }, + }, + "ministral-14b-2512": { + id: "ministral-14b-2512", + name: "Ministral 14B", + family: "mistral", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: true, + temperature: true, + release_date: "2025-12-02", + last_updated: "2025-12-02", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.2 }, + limit: { context: 262144, output: 8192 }, + }, + "llama-3.2-11b-instruct": { + id: "llama-3.2-11b-instruct", + name: "Llama 3.2 11B Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: true, + temperature: true, + release_date: "2024-09-25", + last_updated: "2024-09-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.07, output: 0.33 }, + limit: { context: 128000, output: 8192 }, + }, + "claude-3-opus": { + id: "claude-3-opus", + name: "Claude 3 Opus", + family: "claude", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2024-03-04", + last_updated: "2024-03-04", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5 }, + limit: { context: 200000, output: 4096 }, + }, + "minimax-m2.7": { + id: "minimax-m2.7", + name: "MiniMax-M2.7", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2, cache_read: 0.06, cache_write: 0.375 }, + limit: { context: 204800, output: 131072 }, + }, + "grok-4-20-beta-0309-non-reasoning": { + id: "grok-4-20-beta-0309-non-reasoning", + name: "Grok 4.20 (Non-Reasoning)", + family: "grok", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2026-03-09", + last_updated: "2026-03-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 6, cache_read: 0.2, context_over_200k: { input: 4, output: 12, cache_read: 0.4 } }, + limit: { context: 2000000, output: 30000 }, + }, + "qwen3-coder-plus": { + id: "qwen3-coder-plus", + name: "Qwen3 Coder Plus", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-23", + last_updated: "2025-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 5 }, + limit: { context: 1048576, output: 65536 }, + }, + "claude-haiku-4-5": { + id: "claude-haiku-4-5", + name: "Claude Haiku 4.5 (latest)", + family: "claude-haiku", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-02-28", + release_date: "2025-10-15", + last_updated: "2025-10-15", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 5, cache_read: 0.1, cache_write: 1.25 }, + limit: { context: 200000, output: 64000 }, + }, + "claude-opus-4-5-20251101": { + id: "claude-opus-4-5-20251101", + name: "Claude Opus 4.5", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-11-01", + last_updated: "2025-11-01", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 200000, output: 64000 }, + }, + "gemini-2.5-flash-lite-preview-09-2025": { + id: "gemini-2.5-flash-lite-preview-09-2025", + name: "Gemini 2.5 Flash Lite Preview 09-25", + family: "gemini-flash-lite", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-09-25", + last_updated: "2025-09-25", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4, cache_read: 0.025 }, + limit: { context: 1048576, output: 65536 }, + }, + "kimi-k2.5": { + id: "kimi-k2.5", + name: "Kimi K2.5", + family: "kimi-k2.5", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: false, + knowledge: "2025-01", + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 3, cache_read: 0.1 }, + limit: { context: 262144, output: 262144 }, + }, + "llama-3.3-70b-instruct": { + id: "llama-3.3-70b-instruct", + name: "Llama-3.3-70B-Instruct", + family: "llama", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "mistral-large-2512": { + id: "mistral-large-2512", + name: "Mistral Large 3", + family: "mistral-large", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-11", + release_date: "2024-11-01", + last_updated: "2025-12-02", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.5, output: 1.5 }, + limit: { context: 262144, output: 262144 }, + }, + "glm-4.7": { + id: "glm-4.7", + name: "GLM-4.7", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-04", + release_date: "2025-12-22", + last_updated: "2025-12-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.2, cache_read: 0.11, cache_write: 0 }, + limit: { context: 204800, output: 131072 }, + }, + "minimax-m2.7-highspeed": { + id: "minimax-m2.7-highspeed", + name: "MiniMax-M2.7-highspeed", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.4, cache_read: 0.06, cache_write: 0.375 }, + limit: { context: 204800, output: 131072 }, + }, + "mimo-v2.5-pro": { + id: "mimo-v2.5-pro", + name: "MiMo-V2.5-Pro", + family: "mimo", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12", + release_date: "2026-04-22", + last_updated: "2026-04-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 3, cache_read: 0.2, context_over_200k: { input: 2, output: 6, cache_read: 0.4 } }, + limit: { context: 1048576, output: 131072 }, + }, + "gemma-3n-e4b-it": { + id: "gemma-3n-e4b-it", + name: "Gemma 3n 4B", + family: "gemma", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-10", + release_date: "2025-05-20", + last_updated: "2025-05-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 8192, output: 2000 }, + }, + "claude-3-5-sonnet-20241022": { + id: "claude-3-5-sonnet-20241022", + name: "Claude Sonnet 3.5 v2", + family: "claude-sonnet", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04-30", + release_date: "2024-10-22", + last_updated: "2024-10-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 8192 }, + }, + "gpt-5.2-pro": { + id: "gpt-5.2-pro", + name: "GPT-5.2 Pro", + family: "gpt-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: false, + knowledge: "2025-08-31", + release_date: "2025-12-11", + last_updated: "2025-12-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 21, output: 168 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "qwq-plus": { + id: "qwq-plus", + name: "QwQ Plus", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-03-05", + last_updated: "2025-03-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.8, output: 2.4 }, + limit: { context: 131072, output: 8192 }, + }, + "gemini-3.1-flash-lite-preview": { + id: "gemini-3.1-flash-lite-preview", + name: "Gemini 3.1 Flash Lite Preview", + family: "gemini-flash-lite", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-03-03", + last_updated: "2026-03-03", + modalities: { input: ["text", "image", "video", "audio", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 1.5, cache_read: 0.025, cache_write: 1 }, + limit: { context: 1048576, output: 65536 }, + }, + "qwen-vl-plus": { + id: "qwen-vl-plus", + name: "Qwen-VL Plus", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-01-25", + last_updated: "2025-08-15", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.21, output: 0.63 }, + limit: { context: 131072, output: 8192 }, + }, + "glm-5": { + id: "glm-5", + name: "GLM-5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-02-11", + last_updated: "2026-02-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 3.2, cache_read: 0.2, cache_write: 0 }, + limit: { context: 204800, output: 131072 }, + }, + "devstral-2512": { + id: "devstral-2512", + name: "Devstral 2", + family: "devstral", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-12", + release_date: "2025-12-09", + last_updated: "2025-12-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.4, output: 2 }, + limit: { context: 262144, output: 262144 }, + }, + "qwen3-32b": { + id: "qwen3-32b", + name: "Qwen3 32B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-04", + last_updated: "2025-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.7, output: 2.8, reasoning: 8.4 }, + limit: { context: 131072, output: 16384 }, + }, + "claude-sonnet-4-6": { + id: "claude-sonnet-4-6", + name: "Claude Sonnet 4.6", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: 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, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 1000000, output: 64000 }, + }, + "glm-4.7-flashx": { + id: "glm-4.7-flashx", + name: "GLM-4.7-FlashX", + family: "glm-flash", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-01-19", + last_updated: "2026-01-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.07, output: 0.4, cache_read: 0.01, cache_write: 0 }, + limit: { context: 200000, output: 131072 }, + }, + "gemini-3.1-pro-preview": { + id: "gemini-3.1-pro-preview", + name: "Gemini 3.1 Pro Preview", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-02-19", + last_updated: "2026-02-19", + modalities: { input: ["text", "image", "video", "audio", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 12, cache_read: 0.2, context_over_200k: { input: 4, output: 18, cache_read: 0.4 } }, + limit: { context: 1048576, output: 65536 }, + }, + "qwen35-397b-a17b": { + id: "qwen35-397b-a17b", + name: "Qwen3.5 397B-A17B", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-02-15", + last_updated: "2026-02-15", + modalities: { input: ["text", "image", "video", "audio"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 3.6 }, + limit: { context: 262144, output: 65536 }, + }, + "qwen-max": { + id: "qwen-max", + name: "Qwen Max", + 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, + cost: { input: 1.6, output: 6.4 }, + limit: { context: 32768, output: 8192 }, + }, + "gpt-5.3-chat-latest": { + id: "gpt-5.3-chat-latest", + name: "GPT-5.3 Chat (latest)", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-08-31", + release_date: "2026-03-03", + last_updated: "2026-03-03", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 128000, output: 16384 }, + }, + "gemini-2.0-flash": { + id: "gemini-2.0-flash", + name: "Gemini 2.0 Flash", + family: "gemini-flash", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-06", + release_date: "2024-12-11", + last_updated: "2024-12-11", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4, cache_read: 0.025 }, + limit: { context: 1048576, output: 8192 }, + }, + "gemini-3-flash-preview": { + id: "gemini-3-flash-preview", + name: "Gemini 3 Flash Preview", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-12-17", + last_updated: "2025-12-17", + modalities: { input: ["text", "image", "video", "audio", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 0.5, + output: 3, + cache_read: 0.05, + context_over_200k: { input: 0.5, output: 3, cache_read: 0.05 }, + }, + limit: { context: 1048576, output: 65536 }, + }, + "qwen-plus": { + id: "qwen-plus", + name: "Qwen Plus", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-01-25", + last_updated: "2025-09-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 1.2, reasoning: 4 }, + limit: { context: 1000000, output: 32768 }, + }, + "gpt-5.5": { + id: "gpt-5.5", + name: "GPT-5.5", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-12-01", + release_date: "2026-04-23", + last_updated: "2026-04-23", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 30, cache_read: 0.5, context_over_200k: { input: 10, output: 45, cache_read: 1 } }, + limit: { context: 1050000, input: 922000, output: 128000 }, + experimental: { + modes: { + fast: { + cost: { input: 12.5, output: 75, cache_read: 1.25 }, + provider: { body: { service_tier: "priority" } }, + }, + }, + }, + }, + "qwen3.6-35b-a3b": { + id: "qwen3.6-35b-a3b", + name: "Qwen3.6 35B-A3B", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-04-17", + last_updated: "2026-04-17", + modalities: { input: ["text", "image", "video", "audio"], output: ["text"] }, + open_weights: true, + cost: { input: 0.248, output: 1.485 }, + limit: { context: 262144, output: 65536 }, + }, + "qwen-omni-turbo": { + id: "qwen-omni-turbo", + name: "Qwen-Omni Turbo", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-01-19", + last_updated: "2025-03-26", + modalities: { input: ["text", "image", "audio", "video"], output: ["text", "audio"] }, + open_weights: false, + cost: { input: 0.07, output: 0.27, input_audio: 4.44, output_audio: 8.89 }, + limit: { context: 32768, output: 2048 }, + }, + "claude-opus-4-7": { + id: "claude-opus-4-7", + name: "Claude Opus 4.7", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2026-01-31", + release_date: "2026-04-16", + last_updated: "2026-04-16", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 1000000, output: 128000 }, + }, + "gpt-5-mini": { + id: "gpt-5-mini", + name: "GPT-5 Mini", + family: "gpt-mini", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-05-30", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 2, cache_read: 0.025 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "gpt-5-nano": { + id: "gpt-5-nano", + name: "GPT-5 Nano", + family: "gpt-nano", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-05-30", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.05, output: 0.4, cache_read: 0.005 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "mimo-v2-omni": { + id: "mimo-v2-omni", + name: "MiMo-V2-Omni", + family: "mimo", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12", + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 2, cache_read: 0.08 }, + limit: { context: 262144, output: 131072 }, + }, + "gpt-5.3-codex": { + id: "gpt-5.3-codex", + name: "GPT-5.3 Codex", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-02-05", + last_updated: "2026-02-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "minimax-m2": { + id: "minimax-m2", + name: "MiniMax-M2", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-10-27", + last_updated: "2025-10-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 196608, output: 128000 }, + }, + "claude-sonnet-4-5-20250929": { + id: "claude-sonnet-4-5-20250929", + name: "Claude Sonnet 4.5", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07-31", + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + }, + "qwen-flash": { + id: "qwen-flash", + name: "Qwen Flash", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-07-28", + last_updated: "2025-07-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.05, output: 0.4 }, + limit: { context: 1000000, output: 32768 }, + }, + "gpt-4-turbo": { + id: "gpt-4-turbo", + name: "GPT-4 Turbo", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + knowledge: "2023-12", + release_date: "2023-11-06", + last_updated: "2024-04-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 10, output: 30 }, + limit: { context: 128000, output: 4096 }, + }, + "gemini-2.5-pro": { + id: "gemini-2.5-pro", + name: "Gemini 2.5 Pro", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-03-20", + last_updated: "2025-06-05", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 1.25, + output: 10, + cache_read: 0.125, + context_over_200k: { input: 2.5, output: 15, cache_read: 0.25 }, + }, + limit: { context: 1048576, output: 65536 }, + }, + "mimo-v2.5": { + id: "mimo-v2.5", + name: "MiMo-V2.5", + family: "mimo", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12", + release_date: "2026-04-22", + last_updated: "2026-04-22", + modalities: { input: ["text", "image", "audio", "video"], output: ["text"] }, + open_weights: true, + cost: { + input: 0.4, + output: 2, + cache_read: 0.08, + context_over_200k: { input: 0.8, output: 4, cache_read: 0.16 }, + }, + limit: { context: 1048576, output: 131072 }, + }, + "grok-4-1-fast-non-reasoning": { + id: "grok-4-1-fast-non-reasoning", + name: "Grok 4.1 Fast (Non-Reasoning)", + family: "grok", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-11-19", + last_updated: "2025-11-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5, cache_read: 0.05 }, + limit: { context: 2000000, output: 30000 }, + }, + "sonar-pro": { + id: "sonar-pro", + name: "Sonar Pro", + family: "sonar-pro", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2025-09-01", + release_date: "2024-01-01", + last_updated: "2025-09-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15 }, + limit: { context: 200000, output: 8192 }, + }, + "pixtral-large-latest": { + id: "pixtral-large-latest", + name: "Pixtral Large (latest)", + family: "pixtral", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-11", + release_date: "2024-11-01", + last_updated: "2024-11-04", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 2, output: 6 }, + limit: { context: 128000, output: 128000 }, + }, + "gpt-5.2": { + id: "gpt-5.2", + name: "GPT-5.2", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2025-12-11", + last_updated: "2025-12-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "grok-4-20-beta-0309-reasoning": { + id: "grok-4-20-beta-0309-reasoning", + name: "Grok 4.20 (Reasoning)", + family: "grok", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-09", + last_updated: "2026-03-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 6, cache_read: 0.2, context_over_200k: { input: 4, output: 12, cache_read: 0.4 } }, + limit: { context: 2000000, output: 30000 }, + }, + "gpt-4o-mini": { + id: "gpt-4o-mini", + name: "GPT-4o mini", + family: "gpt-mini", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2023-09", + release_date: "2024-07-18", + last_updated: "2024-07-18", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.6, cache_read: 0.08 }, + limit: { context: 128000, output: 16384 }, + }, + "qwen3.6-plus": { + id: "qwen3.6-plus", + name: "Qwen3.6 Plus", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-04-02", + last_updated: "2026-04-02", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.276, output: 1.651, cache_read: 0.028, cache_write: 0.344 }, + limit: { context: 1000000, output: 65536 }, + }, + "gpt-5.4-mini": { + id: "gpt-5.4-mini", + name: "GPT-5.4 mini", + family: "gpt-mini", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-17", + last_updated: "2026-03-17", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.75, output: 4.5, cache_read: 0.075 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "qwen3-max": { + id: "qwen3-max", + name: "Qwen3 Max", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-09-23", + last_updated: "2025-09-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.2, output: 6 }, + limit: { context: 262144, output: 65536 }, + }, + "minimax-m2.1": { + id: "minimax-m2.1", + name: "MiniMax-M2.1", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-12-23", + last_updated: "2025-12-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 204800, output: 131072 }, + }, + "glm-5.1": { + id: "glm-5.1", + name: "GLM-5.1", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-03-27", + last_updated: "2026-03-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 6, output: 24, cache_read: 1.3, cache_write: 0 }, + limit: { context: 200000, output: 131072 }, + }, + "o4-mini": { + id: "o4-mini", + name: "o4-mini", + family: "o-mini", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-05", + release_date: "2025-04-16", + last_updated: "2025-04-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 4.4, cache_read: 0.28 }, + limit: { context: 200000, output: 100000 }, + }, + "gpt-5.4-nano": { + id: "gpt-5.4-nano", + name: "GPT-5.4 nano", + family: "gpt-nano", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-17", + last_updated: "2026-03-17", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 1.25, cache_read: 0.02 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "glm-4.5": { + id: "glm-4.5", + name: "GLM-4.5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-28", + last_updated: "2025-07-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.2, cache_read: 0.11, cache_write: 0 }, + limit: { context: 131072, output: 98304 }, + }, + "mistral-large-latest": { + id: "mistral-large-latest", + name: "Mistral Large (latest)", + family: "mistral-large", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-11", + release_date: "2024-11-01", + last_updated: "2025-12-02", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.5, output: 1.5 }, + limit: { context: 262144, output: 262144 }, + }, + "mistral-small-2506": { + id: "mistral-small-2506", + name: "Mistral Small 3.2", + family: "mistral-small", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-03", + release_date: "2025-06-20", + last_updated: "2025-06-20", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.3 }, + limit: { context: 128000, output: 16384 }, + }, + "gemma-3-12b-it": { + id: "gemma-3-12b-it", + name: "Gemma 3 12B", + family: "gemma", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-03-13", + last_updated: "2025-03-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 32768, output: 8192 }, + }, + "gpt-5.2-codex": { + id: "gpt-5.2-codex", + name: "GPT-5.2 Codex", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2025-12-11", + last_updated: "2025-12-11", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "gemini-2.5-flash": { + id: "gemini-2.5-flash", + name: "Gemini 2.5 Flash", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-03-20", + last_updated: "2025-06-05", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 2.5, cache_read: 0.03, input_audio: 1 }, + limit: { context: 1048576, output: 65536 }, + }, + "gpt-5.2-chat-latest": { + id: "gpt-5.2-chat-latest", + name: "GPT-5.2 Chat", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2025-12-11", + last_updated: "2025-12-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 128000, output: 16384 }, + }, + "gemma-3n-e2b-it": { + id: "gemma-3n-e2b-it", + name: "Gemma 3n 2B", + family: "gemma", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-10", + release_date: "2025-07-09", + last_updated: "2025-07-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 8192, output: 2000 }, + }, + "gpt-5.1-codex-mini": { + id: "gpt-5.1-codex-mini", + name: "GPT-5.1 Codex mini", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 2, cache_read: 0.025 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "grok-4-fast": { + id: "grok-4-fast", + name: "Grok 4 Fast", + family: "grok", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-09-19", + last_updated: "2025-09-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5, cache_read: 0.05 }, + limit: { context: 2000000, output: 30000 }, + }, + "gemini-3.1-flash-lite": { + id: "gemini-3.1-flash-lite", + name: "Gemini 3.1 Flash Lite", + family: "gemini-flash-lite", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-05-07", + last_updated: "2026-05-07", + modalities: { input: ["text", "image", "video", "audio", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 1.5, cache_read: 0.025, cache_write: 1 }, + limit: { context: 1048576, output: 65536 }, + }, + "qwen3-next-80b-a3b-thinking": { + id: "qwen3-next-80b-a3b-thinking", + name: "Qwen3-Next 80B-A3B (Thinking)", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-09", + last_updated: "2025-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.5, output: 6 }, + limit: { context: 131072, output: 32768 }, + }, + "grok-code-fast-1": { + id: "grok-code-fast-1", + name: "Grok Code Fast 1", + family: "grok", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2023-10", + release_date: "2025-08-28", + last_updated: "2025-08-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 1.5, cache_read: 0.02 }, + limit: { context: 256000, output: 10000 }, + }, + "gpt-5.1": { + id: "gpt-5.1", + name: "GPT-5.1", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.13 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "gemma-3-4b-it": { + id: "gemma-3-4b-it", + name: "Gemma 3 4B", + family: "gemma", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-10", + release_date: "2025-03-13", + last_updated: "2025-03-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 32768, output: 8192 }, + }, + "kimi-k2-thinking-turbo": { + id: "kimi-k2-thinking-turbo", + name: "Kimi K2 Thinking Turbo", + family: "kimi-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-08", + release_date: "2025-11-06", + last_updated: "2025-11-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.15, output: 8, cache_read: 0.15 }, + limit: { context: 262144, output: 262144 }, + }, + o1: { + id: "o1", + name: "o1", + family: "o", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2023-09", + release_date: "2024-12-05", + last_updated: "2024-12-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 60, cache_read: 7.5 }, + limit: { context: 200000, output: 100000 }, + }, + "glm-4.5-air": { + id: "glm-4.5-air", + name: "GLM-4.5-Air", + family: "glm-air", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-28", + last_updated: "2025-07-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 1.1, cache_read: 0.03, cache_write: 0 }, + limit: { context: 131072, output: 98304 }, + }, + "gpt-5.4-pro": { + id: "gpt-5.4-pro", + name: "GPT-5.4 Pro", + family: "gpt-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-05", + last_updated: "2026-03-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 30, output: 180 }, + limit: { context: 1050000, input: 922000, output: 128000 }, + }, + "gpt-3.5-turbo": { + id: "gpt-3.5-turbo", + name: "GPT-3.5-turbo", + family: "gpt", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + knowledge: "2021-09-01", + release_date: "2023-03-01", + last_updated: "2023-11-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 1.5, cache_read: 1.25 }, + limit: { context: 16385, output: 4096 }, + }, + "o3-mini": { + id: "o3-mini", + name: "o3-mini", + family: "o-mini", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-05", + release_date: "2024-12-20", + last_updated: "2025-01-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 4.4, cache_read: 0.55 }, + limit: { context: 200000, output: 100000 }, + }, + "qwen-vl-max": { + id: "qwen-vl-max", + name: "Qwen-VL Max", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-04-08", + last_updated: "2025-08-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.8, output: 3.2 }, + limit: { context: 131072, output: 8192 }, + }, + sonar: { + id: "sonar", + name: "Sonar", + family: "sonar", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2025-09-01", + release_date: "2024-01-01", + last_updated: "2025-09-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 1 }, + limit: { context: 128000, output: 4096 }, + }, + "qwen3-coder-flash": { + id: "qwen3-coder-flash", + name: "Qwen3 Coder Flash", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-28", + last_updated: "2025-07-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 1.5 }, + limit: { context: 1000000, output: 65536 }, + }, + "grok-4-3": { + id: "grok-4-3", + name: "Grok 4.3", + family: "grok", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-05-01", + last_updated: "2026-05-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { + input: 1.25, + output: 2.5, + cache_read: 0.2, + context_over_200k: { input: 2.5, output: 5, cache_read: 0.4 }, + }, + limit: { context: 1000000, output: 30000 }, + }, + "glm-4.5v": { + id: "glm-4.5v", + name: "GLM-4.5V", + family: "glm", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-08-11", + last_updated: "2025-08-11", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 1.8 }, + limit: { context: 64000, output: 16384 }, + }, + "deepseek-v4-flash": { + id: "deepseek-v4-flash", + name: "DeepSeek V4 Flash", + family: "deepseek-flash", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-05", + release_date: "2026-04-24", + last_updated: "2026-04-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.14, output: 0.28, cache_read: 0.028 }, + limit: { context: 1000000, output: 384000 }, + }, + "grok-4": { + id: "grok-4", + name: "Grok 4", + family: "grok", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-07-09", + last_updated: "2025-07-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, reasoning: 15, cache_read: 0.75 }, + limit: { context: 256000, output: 64000 }, + }, + "qwen3-next-80b-a3b-instruct": { + id: "qwen3-next-80b-a3b-instruct", + name: "Qwen3-Next 80B-A3B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-09", + last_updated: "2025-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.5, output: 2 }, + limit: { context: 131072, output: 32768 }, + }, + "gpt-4": { + id: "gpt-4", + name: "GPT-4", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + knowledge: "2023-11", + release_date: "2023-11-06", + last_updated: "2024-04-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 30, output: 60 }, + limit: { context: 8192, output: 8192 }, + }, + "glm-4.6": { + id: "glm-4.6", + name: "GLM-4.6", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-09-30", + last_updated: "2025-09-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.2, cache_read: 0.11, cache_write: 0 }, + limit: { context: 204800, output: 131072 }, + }, + "kimi-k2.6": { + id: "kimi-k2.6", + name: "Kimi K2.6", + family: "kimi-k2.6", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-04-21", + last_updated: "2026-04-21", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.95, output: 4, cache_read: 0.16 }, + limit: { context: 262144, output: 262144 }, + }, + "glm-4.6v": { + id: "glm-4.6v", + name: "GLM-4.6V", + family: "glm", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-12-08", + last_updated: "2025-12-08", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 0.9 }, + limit: { context: 128000, output: 32768 }, + }, + "claude-opus-4-1-20250805": { + id: "claude-opus-4-1-20250805", + name: "Claude Opus 4.1", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 32000 }, + }, + "gpt-5.4": { + id: "gpt-5.4", + name: "GPT-5.4", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-05", + last_updated: "2026-03-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 15, cache_read: 0.25 }, + limit: { context: 1050000, input: 922000, output: 128000 }, + }, + "claude-haiku-4-5-20251001": { + id: "claude-haiku-4-5-20251001", + name: "Claude Haiku 4.5", + family: "claude-haiku", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-02-28", + release_date: "2025-10-15", + last_updated: "2025-10-15", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 5, cache_read: 0.1, cache_write: 1.25 }, + limit: { context: 200000, output: 64000 }, + }, + "glm-4.5-flash": { + id: "glm-4.5-flash", + name: "GLM-4.5-Flash", + family: "glm-flash", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-28", + last_updated: "2025-07-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 131072, output: 98304 }, + }, + "qwen3-vl-plus": { + id: "qwen3-vl-plus", + name: "Qwen3-VL Plus", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-09-23", + last_updated: "2025-09-23", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 1.6, reasoning: 4.8 }, + limit: { context: 262144, output: 32768 }, + }, + "grok-4-1-fast": { + id: "grok-4-1-fast", + name: "Grok 4.1 Fast", + family: "grok", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-11-19", + last_updated: "2025-11-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5, cache_read: 0.05 }, + limit: { context: 2000000, output: 30000 }, + }, + "claude-sonnet-4-20250514": { + id: "claude-sonnet-4-20250514", + name: "Claude Sonnet 4", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + }, + "qwen3-coder-480b-a35b-instruct": { + id: "qwen3-coder-480b-a35b-instruct", + name: "Qwen3-Coder 480B-A35B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-04", + last_updated: "2025-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.5, output: 7.5 }, + limit: { context: 262144, output: 65536 }, + }, + "claude-opus-4-6": { + id: "claude-opus-4-6", + name: "Claude Opus 4.6", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-05-31", + release_date: "2026-02-05", + last_updated: "2026-03-13", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 1000000, output: 128000 }, + }, + "deepseek-v4-pro": { + id: "deepseek-v4-pro", + name: "DeepSeek V4 Pro", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-05", + release_date: "2026-04-24", + last_updated: "2026-04-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.74, output: 3.48, cache_read: 0.145 }, + limit: { context: 1000000, output: 384000 }, + }, + "gpt-4.1-nano": { + id: "gpt-4.1-nano", + name: "GPT-4.1 nano", + family: "gpt-nano", + 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"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4, cache_read: 0.03 }, + limit: { context: 1047576, output: 32768 }, + }, + "claude-3-7-sonnet-20250219": { + id: "claude-3-7-sonnet-20250219", + name: "Claude Sonnet 3.7", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10-31", + release_date: "2025-02-19", + last_updated: "2025-02-19", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + }, + "qwen3-coder-30b-a3b-instruct": { + id: "qwen3-coder-30b-a3b-instruct", + name: "Qwen3-Coder 30B-A3B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-04", + last_updated: "2025-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.45, output: 2.25 }, + limit: { context: 262144, output: 65536 }, + }, + "minimax-m2.5": { + id: "minimax-m2.5", + name: "MiniMax-M2.5", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2, cache_read: 0.03, cache_write: 0.375 }, + limit: { context: 204800, output: 131072 }, + }, + "mimo-v2-pro": { + id: "mimo-v2-pro", + name: "MiMo-V2-Pro", + family: "mimo", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12", + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 3, cache_read: 0.2, context_over_200k: { input: 2, output: 6, cache_read: 0.4 } }, + limit: { context: 1048576, output: 131072 }, + }, + o3: { + id: "o3", + name: "o3", + family: "o", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-05", + release_date: "2025-04-16", + last_updated: "2025-04-16", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 8, cache_read: 0.5 }, + limit: { context: 200000, output: 100000 }, + }, + "gpt-5-pro": { + id: "gpt-5-pro", + name: "GPT-5 Pro", + family: "gpt-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-10-06", + last_updated: "2025-10-06", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 120 }, + limit: { context: 400000, input: 272000, output: 272000 }, + }, + "gpt-4o": { + id: "gpt-4o", + name: "GPT-4o", + 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, + cost: { input: 2.5, output: 10, cache_read: 1.25 }, + limit: { context: 128000, output: 16384 }, + }, + "minimax-m2.5-highspeed": { + id: "minimax-m2.5-highspeed", + name: "MiniMax-M2.5-highspeed", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-13", + last_updated: "2026-02-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.4, cache_read: 0.06, cache_write: 0.375 }, + limit: { context: 204800, output: 131072 }, + }, + "qwen-turbo": { + id: "qwen-turbo", + name: "Qwen Turbo", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-11-01", + last_updated: "2025-04-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.05, output: 0.2, reasoning: 0.5 }, + limit: { context: 1000000, output: 16384 }, + }, + "claude-sonnet-4-5": { + id: "claude-sonnet-4-5", + name: "Claude Sonnet 4.5 (latest)", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07-31", + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + }, + "gemini-2.5-flash-lite": { + id: "gemini-2.5-flash-lite", + name: "Gemini 2.5 Flash Lite", + family: "gemini-flash-lite", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-06-17", + last_updated: "2025-06-17", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4, cache_read: 0.025 }, + limit: { context: 1048576, output: 65536 }, + }, + "gpt-5": { + id: "gpt-5", + name: "GPT-5", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "glm-4.7-flash": { + id: "glm-4.7-flash", + name: "GLM-4.7-Flash", + family: "glm-flash", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-01-19", + last_updated: "2026-01-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 200000, output: 131072 }, + }, + "mimo-v2-flash": { + id: "mimo-v2-flash", + name: "MiMo-V2-Flash", + family: "mimo", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12-01", + release_date: "2025-12-16", + last_updated: "2026-02-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.3, cache_read: 0.01 }, + limit: { context: 262144, output: 65536 }, + }, + "qwen3.6-max-preview": { + id: "qwen3.6-max-preview", + name: "Qwen3.6 Max Preview", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-04-20", + last_updated: "2026-04-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.3, output: 7.8, cache_read: 0.13, cache_write: 1.625 }, + limit: { context: 262144, output: 65536 }, + }, + "gpt-5-chat-latest": { + id: "gpt-5-chat-latest", + name: "GPT-5 Chat (latest)", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: false, + structured_output: true, + temperature: true, + knowledge: "2024-09-30", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "claude-opus-4-20250514": { + id: "claude-opus-4-20250514", + name: "Claude Opus 4", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 32000 }, + }, + "qwen2-5-vl-72b-instruct": { + id: "qwen2-5-vl-72b-instruct", + name: "Qwen2.5-VL 72B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-09", + last_updated: "2024-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 2.8, output: 8.4 }, + limit: { context: 131072, output: 8192 }, + }, + "gpt-5.5-pro": { + id: "gpt-5.5-pro", + name: "GPT-5.5 Pro", + family: "gpt-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-12-01", + release_date: "2026-04-23", + last_updated: "2026-04-23", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 30, output: 180, context_over_200k: { input: 60, output: 270 } }, + limit: { context: 1050000, input: 922000, output: 128000 }, + }, + "gpt-4.1": { + id: "gpt-4.1", + name: "GPT-4.1", + 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, + cost: { input: 2, output: 8, cache_read: 0.5 }, + limit: { context: 1047576, output: 32768 }, + }, + "devstral-small-2507": { + id: "devstral-small-2507", + name: "Devstral Small", + family: "devstral", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-05", + release_date: "2025-07-10", + last_updated: "2025-07-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.3 }, + limit: { context: 128000, output: 128000 }, + }, + "kimi-k2-thinking": { + id: "kimi-k2-thinking", + name: "Kimi K2 Thinking", + family: "kimi-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-08", + release_date: "2025-11-06", + last_updated: "2025-11-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.5, cache_read: 0.15 }, + limit: { context: 262144, output: 262144 }, + }, + "gemini-2.0-flash-lite": { + id: "gemini-2.0-flash-lite", + name: "Gemini 2.0 Flash Lite", + family: "gemini-flash-lite", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-06", + release_date: "2024-12-11", + last_updated: "2024-12-11", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.075, output: 0.3 }, + limit: { context: 1048576, output: 8192 }, + }, + "gpt-4.1-mini": { + id: "gpt-4.1-mini", + name: "GPT-4.1 mini", + family: "gpt-mini", + 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, + cost: { input: 0.4, output: 1.6, cache_read: 0.1 }, + limit: { context: 1047576, output: 32768 }, + }, + "gpt-5.1-codex": { + id: "gpt-5.1-codex", + name: "GPT-5.1 Codex", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "grok-3": { + id: "grok-3", + name: "Grok 3", + family: "grok", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-11", + release_date: "2025-02-17", + last_updated: "2025-02-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.75 }, + limit: { context: 131072, output: 8192 }, + }, + "grok-4-fast-non-reasoning": { + id: "grok-4-fast-non-reasoning", + name: "Grok 4 Fast (Non-Reasoning)", + family: "grok", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-09-19", + last_updated: "2025-09-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5, cache_read: 0.05 }, + limit: { context: 2000000, output: 30000 }, + }, + "sonar-reasoning-pro": { + id: "sonar-reasoning-pro", + name: "Sonar Reasoning Pro", + family: "sonar-reasoning", + attachment: true, + reasoning: true, + tool_call: false, + temperature: true, + knowledge: "2025-09-01", + release_date: "2024-01-01", + last_updated: "2025-09-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 8 }, + limit: { context: 128000, output: 4096 }, + }, + }, + }, + "google-vertex": { + id: "google-vertex", + env: ["GOOGLE_VERTEX_PROJECT", "GOOGLE_VERTEX_LOCATION", "GOOGLE_APPLICATION_CREDENTIALS"], + npm: "@ai-sdk/google-vertex", + name: "Vertex", + doc: "https://cloud.google.com/vertex-ai/generative-ai/docs/models", + models: { + "gemini-2.0-flash": { + id: "gemini-2.0-flash", + name: "Gemini 2.0 Flash", + family: "gemini-flash", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-06", + release_date: "2024-12-11", + last_updated: "2024-12-11", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.6, cache_read: 0.025 }, + limit: { context: 1048576, output: 8192 }, + }, + "gemini-3-pro-preview": { + id: "gemini-3-pro-preview", + name: "Gemini 3 Pro Preview", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-11-18", + last_updated: "2025-11-18", + modalities: { input: ["text", "image", "video", "audio", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 12, cache_read: 0.2, context_over_200k: { input: 4, output: 18, cache_read: 0.4 } }, + limit: { context: 1048576, output: 65536 }, + }, + "gemini-flash-latest": { + id: "gemini-flash-latest", + name: "Gemini Flash Latest", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-09-25", + last_updated: "2025-09-25", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 2.5, cache_read: 0.075, cache_write: 0.383 }, + limit: { context: 1048576, output: 65536 }, + }, + "gemini-2.5-flash-lite-preview-06-17": { + id: "gemini-2.5-flash-lite-preview-06-17", + name: "Gemini 2.5 Flash Lite Preview 06-17", + family: "gemini-flash-lite", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-06-17", + last_updated: "2025-06-17", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4, cache_read: 0.025 }, + limit: { context: 65536, output: 65536 }, + }, + "gemini-2.5-flash": { + id: "gemini-2.5-flash", + name: "Gemini 2.5 Flash", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-06-17", + last_updated: "2025-06-17", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 2.5, cache_read: 0.075, cache_write: 0.383 }, + limit: { context: 1048576, output: 65536 }, + }, + "gemini-2.5-flash-preview-09-2025": { + id: "gemini-2.5-flash-preview-09-2025", + name: "Gemini 2.5 Flash Preview 09-25", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-09-25", + last_updated: "2025-09-25", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 2.5, cache_read: 0.075, cache_write: 0.383 }, + limit: { context: 1048576, output: 65536 }, + }, + "zai-org/glm-5-maas": { + id: "zai-org/glm-5-maas", + name: "GLM-5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-02-11", + last_updated: "2026-02-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 3.2, cache_read: 0.1 }, + limit: { context: 202752, output: 131072 }, + provider: { + npm: "@ai-sdk/openai-compatible", + api: "https://${GOOGLE_VERTEX_ENDPOINT}/v1/projects/${GOOGLE_VERTEX_PROJECT}/locations/${GOOGLE_VERTEX_LOCATION}/endpoints/openapi", + }, + }, + "zai-org/glm-4.7-maas": { + id: "zai-org/glm-4.7-maas", + name: "GLM-4.7", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-01-06", + last_updated: "2026-01-06", + modalities: { input: ["text", "pdf"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.2 }, + limit: { context: 200000, output: 128000 }, + provider: { + npm: "@ai-sdk/openai-compatible", + api: "https://${GOOGLE_VERTEX_ENDPOINT}/v1/projects/${GOOGLE_VERTEX_PROJECT}/locations/${GOOGLE_VERTEX_LOCATION}/endpoints/openapi", + }, + }, + "deepseek-ai/deepseek-v3.2-maas": { + id: "deepseek-ai/deepseek-v3.2-maas", + name: "DeepSeek V3.2", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-12-17", + last_updated: "2026-04-04", + modalities: { input: ["text", "pdf"], output: ["text"] }, + open_weights: true, + cost: { input: 0.56, output: 1.68, cache_read: 0.056 }, + limit: { context: 163840, output: 65536 }, + provider: { + npm: "@ai-sdk/openai-compatible", + api: "https://${GOOGLE_VERTEX_ENDPOINT}/v1/projects/${GOOGLE_VERTEX_PROJECT}/locations/${GOOGLE_VERTEX_LOCATION}/endpoints/openapi", + }, + }, + "deepseek-ai/deepseek-v3.1-maas": { + id: "deepseek-ai/deepseek-v3.1-maas", + name: "DeepSeek V3.1", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-08-28", + last_updated: "2025-08-28", + modalities: { input: ["text", "pdf"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 1.7 }, + limit: { context: 163840, output: 32768 }, + provider: { + npm: "@ai-sdk/openai-compatible", + api: "https://${GOOGLE_VERTEX_ENDPOINT}/v1/projects/${GOOGLE_VERTEX_PROJECT}/locations/${GOOGLE_VERTEX_LOCATION}/endpoints/openapi", + }, + }, + "openai/gpt-oss-120b-maas": { + id: "openai/gpt-oss-120b-maas", + name: "GPT OSS 120B", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.09, output: 0.36 }, + limit: { context: 131072, output: 32768 }, + }, + "openai/gpt-oss-20b-maas": { + id: "openai/gpt-oss-20b-maas", + name: "GPT OSS 20B", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.07, output: 0.25 }, + limit: { context: 131072, output: 32768 }, + }, + "meta/llama-3.3-70b-instruct-maas": { + id: "meta/llama-3.3-70b-instruct-maas", + name: "Llama 3.3 70B Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2023-12", + release_date: "2025-04-29", + last_updated: "2025-04-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.72, output: 0.72 }, + limit: { context: 128000, output: 8192 }, + provider: { + npm: "@ai-sdk/openai-compatible", + api: "https://${GOOGLE_VERTEX_ENDPOINT}/v1/projects/${GOOGLE_VERTEX_PROJECT}/locations/${GOOGLE_VERTEX_LOCATION}/endpoints/openapi", + }, + }, + "meta/llama-4-maverick-17b-128e-instruct-maas": { + id: "meta/llama-4-maverick-17b-128e-instruct-maas", + name: "Llama 4 Maverick 17B 128E Instruct", + family: "llama", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-08", + release_date: "2025-04-29", + last_updated: "2025-04-29", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.35, output: 1.15 }, + limit: { context: 524288, output: 8192 }, + provider: { + npm: "@ai-sdk/openai-compatible", + api: "https://${GOOGLE_VERTEX_ENDPOINT}/v1/projects/${GOOGLE_VERTEX_PROJECT}/locations/${GOOGLE_VERTEX_LOCATION}/endpoints/openapi", + }, + }, + "qwen/qwen3-235b-a22b-instruct-2507-maas": { + id: "qwen/qwen3-235b-a22b-instruct-2507-maas", + name: "Qwen3 235B A22B Instruct", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-08-13", + last_updated: "2025-08-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.22, output: 0.88 }, + limit: { context: 262144, output: 16384 }, + provider: { + npm: "@ai-sdk/openai-compatible", + api: "https://${GOOGLE_VERTEX_ENDPOINT}/v1/projects/${GOOGLE_VERTEX_PROJECT}/locations/${GOOGLE_VERTEX_LOCATION}/endpoints/openapi", + }, + }, + "moonshotai/kimi-k2-thinking-maas": { + id: "moonshotai/kimi-k2-thinking-maas", + name: "Kimi K2 Thinking", + family: "kimi-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2024-08", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.5 }, + limit: { context: 262144, output: 262144 }, + provider: { + npm: "@ai-sdk/openai-compatible", + api: "https://${GOOGLE_VERTEX_ENDPOINT}/v1/projects/${GOOGLE_VERTEX_PROJECT}/locations/${GOOGLE_VERTEX_LOCATION}/endpoints/openapi", + }, + }, + "gemini-flash-lite-latest": { + id: "gemini-flash-lite-latest", + name: "Gemini Flash-Lite Latest", + family: "gemini-flash-lite", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-09-25", + last_updated: "2025-09-25", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4, cache_read: 0.025 }, + limit: { context: 1048576, output: 65536 }, + }, + "gemini-2.5-pro-preview-05-06": { + id: "gemini-2.5-pro-preview-05-06", + name: "Gemini 2.5 Pro Preview 05-06", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-05-06", + last_updated: "2025-05-06", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.31 }, + limit: { context: 1048576, output: 65536 }, + }, + "claude-haiku-4-5@20251001": { + id: "claude-haiku-4-5@20251001", + name: "Claude Haiku 4.5", + family: "claude-haiku", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-02-28", + release_date: "2025-10-15", + last_updated: "2025-10-15", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 5, cache_read: 0.1, cache_write: 1.25 }, + limit: { context: 200000, output: 64000 }, + provider: { npm: "@ai-sdk/google-vertex/anthropic" }, + }, + "gemini-3.1-pro-preview-customtools": { + id: "gemini-3.1-pro-preview-customtools", + name: "Gemini 3.1 Pro Preview Custom Tools", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-02-19", + last_updated: "2026-02-19", + modalities: { input: ["text", "image", "video", "audio", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 12, cache_read: 0.2, context_over_200k: { input: 4, output: 18, cache_read: 0.4 } }, + limit: { context: 1048576, output: 65536 }, + }, + "claude-sonnet-4-6@default": { + id: "claude-sonnet-4-6@default", + name: "Claude Sonnet 4.6", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: 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, + cost: { + input: 3, + output: 15, + cache_read: 0.3, + cache_write: 3.75, + context_over_200k: { input: 6, output: 22.5, cache_read: 0.6, cache_write: 7.5 }, + }, + limit: { context: 200000, output: 64000 }, + provider: { npm: "@ai-sdk/google-vertex/anthropic" }, + }, + "gemini-2.5-flash-lite-preview-09-2025": { + id: "gemini-2.5-flash-lite-preview-09-2025", + name: "Gemini 2.5 Flash Lite Preview 09-25", + family: "gemini-flash-lite", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-09-25", + last_updated: "2025-09-25", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4, cache_read: 0.025 }, + limit: { context: 1048576, output: 65536 }, + }, + "claude-3-5-haiku@20241022": { + id: "claude-3-5-haiku@20241022", + name: "Claude Haiku 3.5", + family: "claude-haiku", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-07-31", + release_date: "2024-10-22", + last_updated: "2024-10-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.8, output: 4, cache_read: 0.08, cache_write: 1 }, + limit: { context: 200000, output: 8192 }, + provider: { npm: "@ai-sdk/google-vertex/anthropic" }, + }, + "gemini-3.1-flash-lite-preview": { + id: "gemini-3.1-flash-lite-preview", + name: "Gemini 3.1 Flash Lite Preview", + family: "gemini-flash-lite", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-03-03", + last_updated: "2026-03-03", + modalities: { input: ["text", "image", "video", "audio", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 1.5, cache_read: 0.025, cache_write: 1 }, + limit: { context: 1048576, output: 65536 }, + }, + "claude-3-5-sonnet@20241022": { + id: "claude-3-5-sonnet@20241022", + name: "Claude Sonnet 3.5 v2", + family: "claude-sonnet", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04-30", + release_date: "2024-10-22", + last_updated: "2024-10-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 8192 }, + provider: { npm: "@ai-sdk/google-vertex/anthropic" }, + }, + "gemini-3.1-pro-preview": { + id: "gemini-3.1-pro-preview", + name: "Gemini 3.1 Pro Preview", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-02-19", + last_updated: "2026-02-19", + modalities: { input: ["text", "image", "video", "audio", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 12, cache_read: 0.2, context_over_200k: { input: 4, output: 18, cache_read: 0.4 } }, + limit: { context: 1048576, output: 65536 }, + }, + "claude-opus-4-1@20250805": { + id: "claude-opus-4-1@20250805", + name: "Claude Opus 4.1", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 32000 }, + provider: { npm: "@ai-sdk/google-vertex/anthropic" }, + }, + "gemini-3-flash-preview": { + id: "gemini-3-flash-preview", + name: "Gemini 3 Flash Preview", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-12-17", + last_updated: "2025-12-17", + modalities: { input: ["text", "image", "video", "audio", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 0.5, + output: 3, + cache_read: 0.05, + context_over_200k: { input: 0.5, output: 3, cache_read: 0.05 }, + }, + limit: { context: 1048576, output: 65536 }, + }, + "gemini-2.5-flash-preview-05-20": { + id: "gemini-2.5-flash-preview-05-20", + name: "Gemini 2.5 Flash Preview 05-20", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-05-20", + last_updated: "2025-05-20", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.6, cache_read: 0.0375 }, + limit: { context: 1048576, output: 65536 }, + }, + "gemini-embedding-001": { + id: "gemini-embedding-001", + name: "Gemini Embedding 001", + family: "gemini", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + knowledge: "2025-05", + release_date: "2025-05-20", + last_updated: "2025-05-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0 }, + limit: { context: 2048, output: 3072 }, + }, + "gemini-2.5-pro": { + id: "gemini-2.5-pro", + name: "Gemini 2.5 Pro", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-03-20", + last_updated: "2025-06-05", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 1.25, + output: 10, + cache_read: 0.125, + context_over_200k: { input: 2.5, output: 15, cache_read: 0.25 }, + }, + limit: { context: 1048576, output: 65536 }, + }, + "gemini-2.5-pro-preview-06-05": { + id: "gemini-2.5-pro-preview-06-05", + name: "Gemini 2.5 Pro Preview 06-05", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-06-05", + last_updated: "2025-06-05", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.31 }, + limit: { context: 1048576, output: 65536 }, + }, + "claude-sonnet-4@20250514": { + id: "claude-sonnet-4@20250514", + name: "Claude Sonnet 4", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + provider: { npm: "@ai-sdk/google-vertex/anthropic" }, + }, + "gemini-3.1-flash-lite": { + id: "gemini-3.1-flash-lite", + name: "Gemini 3.1 Flash Lite", + family: "gemini-flash-lite", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-05-07", + last_updated: "2026-05-07", + modalities: { input: ["text", "image", "video", "audio", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 1.5, cache_read: 0.025, cache_write: 1 }, + limit: { context: 1048576, output: 65536 }, + }, + "claude-3-7-sonnet@20250219": { + id: "claude-3-7-sonnet@20250219", + name: "Claude Sonnet 3.7", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10-31", + release_date: "2025-02-19", + last_updated: "2025-02-19", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + provider: { npm: "@ai-sdk/google-vertex/anthropic" }, + }, + "claude-opus-4@20250514": { + id: "claude-opus-4@20250514", + name: "Claude Opus 4", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 32000 }, + provider: { npm: "@ai-sdk/google-vertex/anthropic" }, + }, + "claude-opus-4-5@20251101": { + id: "claude-opus-4-5@20251101", + name: "Claude Opus 4.5", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-11-01", + last_updated: "2025-11-01", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 200000, output: 64000 }, + provider: { npm: "@ai-sdk/google-vertex/anthropic" }, + }, + "gemini-2.5-flash-preview-04-17": { + id: "gemini-2.5-flash-preview-04-17", + name: "Gemini 2.5 Flash Preview 04-17", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-04-17", + last_updated: "2025-04-17", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.6, cache_read: 0.0375 }, + limit: { context: 1048576, output: 65536 }, + }, + "claude-sonnet-4-5@20250929": { + id: "claude-sonnet-4-5@20250929", + name: "Claude Sonnet 4.5", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07-31", + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + provider: { npm: "@ai-sdk/google-vertex/anthropic" }, + }, + "gemini-2.5-flash-lite": { + id: "gemini-2.5-flash-lite", + name: "Gemini 2.5 Flash Lite", + family: "gemini-flash-lite", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-06-17", + last_updated: "2025-06-17", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4, cache_read: 0.025 }, + limit: { context: 1048576, output: 65536 }, + }, + "claude-opus-4-6@default": { + id: "claude-opus-4-6@default", + name: "Claude Opus 4.6", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-05-31", + release_date: "2026-02-05", + last_updated: "2026-03-13", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 5, + output: 25, + cache_read: 0.5, + cache_write: 6.25, + context_over_200k: { input: 10, output: 37.5, cache_read: 1, cache_write: 12.5 }, + }, + limit: { context: 1000000, output: 128000 }, + provider: { npm: "@ai-sdk/google-vertex/anthropic" }, + }, + "gemini-2.0-flash-lite": { + id: "gemini-2.0-flash-lite", + name: "Gemini 2.0 Flash Lite", + family: "gemini-flash-lite", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-06", + release_date: "2024-12-11", + last_updated: "2024-12-11", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.075, output: 0.3 }, + limit: { context: 1048576, output: 8192 }, + }, + "claude-opus-4-7@default": { + id: "claude-opus-4-7@default", + name: "Claude Opus 4.7", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2026-01-31", + release_date: "2026-04-16", + last_updated: "2026-04-16", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 5, + output: 25, + cache_read: 0.5, + cache_write: 6.25, + context_over_200k: { input: 10, output: 37.5, cache_read: 1, cache_write: 12.5 }, + }, + limit: { context: 1000000, output: 128000 }, + provider: { npm: "@ai-sdk/google-vertex/anthropic" }, + }, + }, + }, + "cloudflare-workers-ai": { + id: "cloudflare-workers-ai", + env: ["CLOUDFLARE_ACCOUNT_ID", "CLOUDFLARE_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.cloudflare.com/client/v4/accounts/${CLOUDFLARE_ACCOUNT_ID}/ai/v1", + name: "Cloudflare Workers AI", + doc: "https://developers.cloudflare.com/workers-ai/models/", + models: { + "@cf/zai-org/glm-4.7-flash": { + id: "@cf/zai-org/glm-4.7-flash", + name: "GLM-4.7-Flash", + family: "glm-flash", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-01-19", + last_updated: "2026-01-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.06, output: 0.4 }, + limit: { context: 131072, output: 131072 }, + }, + "@cf/nvidia/nemotron-3-120b-a12b": { + id: "@cf/nvidia/nemotron-3-120b-a12b", + name: "Nemotron 3 Super 120B", + family: "nemotron", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-03-11", + last_updated: "2026-03-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.5, output: 1.5 }, + limit: { context: 256000, output: 256000 }, + }, + "@cf/openai/gpt-oss-20b": { + id: "@cf/openai/gpt-oss-20b", + name: "GPT OSS 20B", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.3 }, + limit: { context: 128000, output: 16384 }, + }, + "@cf/openai/gpt-oss-120b": { + id: "@cf/openai/gpt-oss-120b", + name: "GPT OSS 120B", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.35, output: 0.75 }, + limit: { context: 128000, output: 16384 }, + }, + "@cf/meta/llama-4-scout-17b-16e-instruct": { + id: "@cf/meta/llama-4-scout-17b-16e-instruct", + name: "Llama 4 Scout 17B 16E Instruct", + family: "llama", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-04-16", + last_updated: "2025-04-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.27, output: 0.85 }, + limit: { context: 128000, output: 16384 }, + }, + "@cf/google/gemma-4-26b-a4b-it": { + id: "@cf/google/gemma-4-26b-a4b-it", + name: "Gemma 4 26B A4B IT", + family: "gemma", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-12-15", + last_updated: "2025-12-15", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.3 }, + limit: { context: 256000, output: 16384 }, + }, + "@cf/moonshotai/kimi-k2.5": { + id: "@cf/moonshotai/kimi-k2.5", + name: "Kimi K2.5", + family: "kimi", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-01-27", + last_updated: "2026-01-27", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 3, cache_read: 0.1 }, + limit: { context: 256000, output: 256000 }, + }, + "@cf/moonshotai/kimi-k2.6": { + id: "@cf/moonshotai/kimi-k2.6", + name: "Kimi K2.6", + family: "kimi", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-04-20", + last_updated: "2026-04-20", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.95, output: 4, cache_read: 0.16 }, + limit: { context: 256000, output: 256000 }, + }, + }, + }, + groq: { + id: "groq", + env: ["GROQ_API_KEY"], + npm: "@ai-sdk/groq", + name: "Groq", + doc: "https://console.groq.com/docs/models", + models: { + "gemma2-9b-it": { + id: "gemma2-9b-it", + name: "Gemma 2 9B", + family: "gemma", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-06", + release_date: "2024-06-27", + last_updated: "2024-06-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.2 }, + limit: { context: 8192, output: 8192 }, + status: "deprecated", + }, + "mistral-saba-24b": { + id: "mistral-saba-24b", + name: "Mistral Saba 24B", + family: "mistral", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-08", + release_date: "2025-02-06", + last_updated: "2025-02-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.79, output: 0.79 }, + limit: { context: 32768, output: 32768 }, + status: "deprecated", + }, + "deepseek-r1-distill-llama-70b": { + id: "deepseek-r1-distill-llama-70b", + name: "DeepSeek R1 Distill Llama 70B", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2025-01-20", + last_updated: "2025-01-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.75, output: 0.99 }, + limit: { context: 131072, output: 8192 }, + status: "deprecated", + }, + "llama-guard-3-8b": { + id: "llama-guard-3-8b", + name: "Llama Guard 3 8B", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.2 }, + limit: { context: 8192, output: 8192 }, + status: "deprecated", + }, + "llama-3.3-70b-versatile": { + id: "llama-3.3-70b-versatile", + name: "Llama 3.3 70B Versatile", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.59, output: 0.79 }, + limit: { context: 131072, output: 32768 }, + }, + "allam-2-7b": { + id: "allam-2-7b", + name: "ALLaM-2-7b", + family: "allam", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-09", + release_date: "2024-09", + last_updated: "2024-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 4096, output: 4096 }, + }, + "whisper-large-v3": { + id: "whisper-large-v3", + name: "Whisper Large V3", + family: "whisper", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2023-09", + release_date: "2023-09-01", + last_updated: "2025-09-05", + modalities: { input: ["audio"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 448, output: 448 }, + }, + "llama-3.1-8b-instant": { + id: "llama-3.1-8b-instant", + name: "Llama 3.1 8B Instant", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.05, output: 0.08 }, + limit: { context: 131072, output: 131072 }, + }, + "llama3-70b-8192": { + id: "llama3-70b-8192", + name: "Llama 3 70B", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-03", + release_date: "2024-04-18", + last_updated: "2024-04-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.59, output: 0.79 }, + limit: { context: 8192, output: 8192 }, + status: "deprecated", + }, + "qwen-qwq-32b": { + id: "qwen-qwq-32b", + name: "Qwen QwQ 32B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-09", + release_date: "2024-11-27", + last_updated: "2024-11-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.29, output: 0.39 }, + limit: { context: 131072, output: 16384 }, + status: "deprecated", + }, + "whisper-large-v3-turbo": { + id: "whisper-large-v3-turbo", + name: "Whisper Large v3 Turbo", + family: "whisper", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-10", + release_date: "2024-10-01", + last_updated: "2024-10-01", + modalities: { input: ["audio"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 448, output: 448 }, + }, + "llama3-8b-8192": { + id: "llama3-8b-8192", + name: "Llama 3 8B", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-03", + release_date: "2024-04-18", + last_updated: "2024-04-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.05, output: 0.08 }, + limit: { context: 8192, output: 8192 }, + status: "deprecated", + }, + "canopylabs/orpheus-arabic-saudi": { + id: "canopylabs/orpheus-arabic-saudi", + name: "Orpheus Arabic Saudi", + family: "canopylabs", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2025-12-16", + release_date: "2025-12-16", + last_updated: "2025-12-16", + modalities: { input: ["text"], output: ["audio"] }, + open_weights: false, + cost: { input: 40, output: 0 }, + limit: { context: 4000, output: 50000 }, + }, + "canopylabs/orpheus-v1-english": { + id: "canopylabs/orpheus-v1-english", + name: "Orpheus V1 English", + family: "canopylabs", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2025-12-19", + release_date: "2025-12-19", + last_updated: "2025-12-19", + modalities: { input: ["text"], output: ["audio"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 4000, output: 50000 }, + }, + "meta-llama/llama-4-scout-17b-16e-instruct": { + id: "meta-llama/llama-4-scout-17b-16e-instruct", + name: "Llama 4 Scout 17B", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-08", + release_date: "2025-04-05", + last_updated: "2025-04-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.11, output: 0.34 }, + limit: { context: 131072, output: 8192 }, + }, + "meta-llama/llama-prompt-guard-2-22m": { + id: "meta-llama/llama-prompt-guard-2-22m", + name: "Llama Prompt Guard 2 22M", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-10", + release_date: "2024-10-01", + last_updated: "2024-10-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.03, output: 0.03 }, + limit: { context: 512, output: 512 }, + }, + "meta-llama/llama-guard-4-12b": { + id: "meta-llama/llama-guard-4-12b", + name: "Llama Guard 4 12B", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-04-05", + last_updated: "2025-04-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.2 }, + limit: { context: 131072, output: 1024 }, + status: "deprecated", + }, + "meta-llama/llama-4-maverick-17b-128e-instruct": { + id: "meta-llama/llama-4-maverick-17b-128e-instruct", + name: "Llama 4 Maverick 17B", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-08", + release_date: "2025-04-05", + last_updated: "2025-04-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.6 }, + limit: { context: 131072, output: 8192 }, + status: "deprecated", + }, + "meta-llama/llama-prompt-guard-2-86m": { + id: "meta-llama/llama-prompt-guard-2-86m", + name: "Llama Prompt Guard 2 86M", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-10", + release_date: "2024-10-01", + last_updated: "2024-10-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.04, output: 0.04 }, + limit: { context: 512, output: 512 }, + }, + "openai/gpt-oss-20b": { + id: "openai/gpt-oss-20b", + name: "GPT OSS 20B", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.075, output: 0.3 }, + limit: { context: 131072, output: 65536 }, + }, + "openai/gpt-oss-safeguard-20b": { + id: "openai/gpt-oss-safeguard-20b", + name: "Safety GPT OSS 20B", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-03-05", + last_updated: "2025-03-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.075, output: 0.3, cache_read: 0.037 }, + limit: { context: 131072, output: 65536 }, + }, + "openai/gpt-oss-120b": { + id: "openai/gpt-oss-120b", + name: "GPT OSS 120B", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 131072, output: 65536 }, + }, + "qwen/qwen3-32b": { + id: "qwen/qwen3-32b", + name: "Qwen3 32B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-11-08", + release_date: "2024-12-23", + last_updated: "2024-12-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.29, output: 0.59 }, + limit: { context: 131072, output: 40960 }, + }, + "groq/compound": { + id: "groq/compound", + name: "Compound", + family: "groq", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-09-04", + release_date: "2025-09-04", + last_updated: "2025-09-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 131072, output: 8192 }, + }, + "groq/compound-mini": { + id: "groq/compound-mini", + name: "Compound Mini", + family: "groq", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-09-04", + release_date: "2025-09-04", + last_updated: "2025-09-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 131072, output: 8192 }, + }, + "moonshotai/kimi-k2-instruct": { + id: "moonshotai/kimi-k2-instruct", + name: "Kimi K2 Instruct", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-07-14", + last_updated: "2025-07-14", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 3 }, + limit: { context: 131072, output: 16384 }, + status: "deprecated", + }, + "moonshotai/kimi-k2-instruct-0905": { + id: "moonshotai/kimi-k2-instruct-0905", + name: "Kimi K2 Instruct 0905", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-09-05", + last_updated: "2025-09-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 3 }, + limit: { context: 262144, output: 16384 }, + }, + }, + }, + azure: { + id: "azure", + env: ["AZURE_RESOURCE_NAME", "AZURE_API_KEY"], + npm: "@ai-sdk/azure", + name: "Azure", + doc: "https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/models", + models: { + "mistral-nemo": { + id: "mistral-nemo", + name: "Mistral Nemo", + family: "mistral-nemo", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2024-07-18", + last_updated: "2024-07-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.15 }, + limit: { context: 128000, output: 128000 }, + }, + "gpt-5.2-chat": { + id: "gpt-5.2-chat", + name: "GPT-5.2 Chat", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2025-12-11", + last_updated: "2025-12-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 128000, output: 16384 }, + }, + "codex-mini": { + id: "codex-mini", + name: "Codex Mini", + family: "gpt-codex-mini", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-04", + release_date: "2025-05-16", + last_updated: "2025-05-16", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.5, output: 6, cache_read: 0.375 }, + limit: { context: 200000, output: 100000 }, + }, + "phi-4-multimodal": { + id: "phi-4-multimodal", + name: "Phi-4-multimodal", + family: "phi", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2023-10", + release_date: "2024-12-11", + last_updated: "2024-12-11", + modalities: { input: ["text", "image", "audio"], output: ["text"] }, + open_weights: true, + cost: { input: 0.08, output: 0.32, input_audio: 4 }, + limit: { context: 128000, output: 4096 }, + }, + "phi-3.5-mini-instruct": { + id: "phi-3.5-mini-instruct", + name: "Phi-3.5-mini-instruct", + family: "phi", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2023-10", + release_date: "2024-08-20", + last_updated: "2024-08-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.13, output: 0.52 }, + limit: { context: 128000, output: 4096 }, + }, + "llama-4-scout-17b-16e-instruct": { + id: "llama-4-scout-17b-16e-instruct", + name: "Llama 4 Scout 17B 16E Instruct", + family: "llama", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-08", + release_date: "2025-04-05", + last_updated: "2025-04-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.78 }, + limit: { context: 128000, output: 8192 }, + }, + "grok-4-1-fast-reasoning": { + id: "grok-4-1-fast-reasoning", + name: "Grok 4.1 Fast (Reasoning)", + family: "grok", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-06-27", + last_updated: "2025-06-27", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5, cache_read: 0.05 }, + limit: { context: 128000, input: 128000, output: 8192 }, + status: "beta", + }, + "phi-3-medium-4k-instruct": { + id: "phi-3-medium-4k-instruct", + name: "Phi-3-medium-instruct (4k)", + family: "phi", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2023-10", + release_date: "2024-04-23", + last_updated: "2024-04-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.17, output: 0.68 }, + limit: { context: 4096, output: 1024 }, + }, + "ministral-3b": { + id: "ministral-3b", + name: "Ministral 3B", + family: "ministral", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-03", + release_date: "2024-10-22", + last_updated: "2024-10-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.04, output: 0.04 }, + limit: { context: 128000, output: 8192 }, + }, + "claude-haiku-4-5": { + id: "claude-haiku-4-5", + name: "Claude Haiku 4.5", + family: "claude-haiku", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-02-31", + release_date: "2025-11-18", + last_updated: "2025-11-18", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 5, cache_read: 0.1, cache_write: 1.25 }, + limit: { context: 200000, output: 64000 }, + provider: { + npm: "@ai-sdk/anthropic", + api: "https://${AZURE_RESOURCE_NAME}.services.ai.azure.com/anthropic/v1", + }, + }, + "meta-llama-3.1-8b-instruct": { + id: "meta-llama-3.1-8b-instruct", + name: "Meta-Llama-3.1-8B-Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 0.61 }, + limit: { context: 128000, output: 32768 }, + }, + "kimi-k2.5": { + id: "kimi-k2.5", + name: "Kimi K2.5", + family: "kimi", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-02-06", + last_updated: "2026-02-06", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 3 }, + limit: { context: 262144, output: 262144 }, + provider: { + npm: "@ai-sdk/openai-compatible", + api: "https://${AZURE_RESOURCE_NAME}.services.ai.azure.com/models", + shape: "completions", + }, + }, + "llama-3.3-70b-instruct": { + id: "llama-3.3-70b-instruct", + name: "Llama-3.3-70B-Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.71, output: 0.71 }, + limit: { context: 128000, output: 32768 }, + }, + "deepseek-v3-0324": { + id: "deepseek-v3-0324", + name: "DeepSeek-V3-0324", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2025-03-24", + last_updated: "2025-03-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.14, output: 4.56 }, + limit: { context: 131072, output: 131072 }, + }, + "gpt-5-chat": { + id: "gpt-5-chat", + name: "GPT-5 Chat", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: false, + temperature: false, + knowledge: "2024-10-24", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.13 }, + limit: { context: 128000, output: 16384 }, + }, + "phi-3.5-moe-instruct": { + id: "phi-3.5-moe-instruct", + name: "Phi-3.5-MoE-instruct", + family: "phi", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2023-10", + release_date: "2024-08-20", + last_updated: "2024-08-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.16, output: 0.64 }, + limit: { context: 128000, output: 4096 }, + }, + "gpt-5.3-chat": { + id: "gpt-5.3-chat", + name: "GPT-5.3 Chat", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-03", + last_updated: "2026-03-03", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 128000, output: 16384 }, + }, + "o1-mini": { + id: "o1-mini", + name: "o1-mini", + family: "o-mini", + attachment: false, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2023-09", + release_date: "2024-09-12", + last_updated: "2024-09-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 4.4, cache_read: 0.55 }, + limit: { context: 128000, output: 65536 }, + }, + "text-embedding-3-large": { + id: "text-embedding-3-large", + name: "text-embedding-3-large", + family: "text-embedding", + attachment: false, + reasoning: false, + tool_call: false, + release_date: "2024-01-25", + last_updated: "2024-01-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.13, output: 0 }, + limit: { context: 8191, output: 3072 }, + }, + "phi-3-mini-128k-instruct": { + id: "phi-3-mini-128k-instruct", + name: "Phi-3-mini-instruct (128k)", + family: "phi", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2023-10", + release_date: "2024-04-23", + last_updated: "2024-04-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.13, output: 0.52 }, + limit: { context: 128000, output: 4096 }, + }, + "phi-4-reasoning": { + id: "phi-4-reasoning", + name: "Phi-4-reasoning", + family: "phi", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + knowledge: "2023-10", + release_date: "2024-12-11", + last_updated: "2024-12-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.125, output: 0.5 }, + limit: { context: 32000, output: 4096 }, + }, + "gpt-5-mini": { + id: "gpt-5-mini", + name: "GPT-5 Mini", + family: "gpt-mini", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-05-30", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 2, cache_read: 0.03 }, + limit: { context: 272000, output: 128000 }, + }, + "gpt-5-nano": { + id: "gpt-5-nano", + name: "GPT-5 Nano", + family: "gpt-nano", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-05-30", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.05, output: 0.4, cache_read: 0.01 }, + limit: { context: 272000, output: 128000 }, + }, + "meta-llama-3-70b-instruct": { + id: "meta-llama-3-70b-instruct", + name: "Meta-Llama-3-70B-Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2023-12", + release_date: "2024-04-18", + last_updated: "2024-04-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 2.68, output: 3.54 }, + limit: { context: 8192, output: 2048 }, + }, + "phi-3-small-8k-instruct": { + id: "phi-3-small-8k-instruct", + name: "Phi-3-small-instruct (8k)", + family: "phi", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2023-10", + release_date: "2024-04-23", + last_updated: "2024-04-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 8192, output: 2048 }, + }, + "gpt-5.3-codex": { + id: "gpt-5.3-codex", + name: "GPT-5.3 Codex", + family: "gpt-codex", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-02-24", + last_updated: "2026-02-24", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 400000, output: 128000 }, + }, + "text-embedding-ada-002": { + id: "text-embedding-ada-002", + name: "text-embedding-ada-002", + family: "text-embedding", + attachment: false, + reasoning: false, + tool_call: false, + release_date: "2022-12-15", + last_updated: "2022-12-15", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0 }, + limit: { context: 8192, output: 1536 }, + }, + "llama-3.2-90b-vision-instruct": { + id: "llama-3.2-90b-vision-instruct", + name: "Llama-3.2-90B-Vision-Instruct", + family: "llama", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-09-25", + last_updated: "2024-09-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 2.04, output: 2.04 }, + limit: { context: 128000, output: 8192 }, + }, + "deepseek-r1": { + id: "deepseek-r1", + name: "DeepSeek-R1", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + knowledge: "2024-07", + release_date: "2025-01-20", + last_updated: "2025-01-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.35, output: 5.4 }, + limit: { context: 163840, output: 163840 }, + }, + "grok-4-1-fast-non-reasoning": { + id: "grok-4-1-fast-non-reasoning", + name: "Grok 4.1 Fast (Non-Reasoning)", + family: "grok", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-06-27", + last_updated: "2025-06-27", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5, cache_read: 0.05 }, + limit: { context: 128000, input: 128000, output: 8192 }, + status: "beta", + }, + "deepseek-v3.2-speciale": { + id: "deepseek-v3.2-speciale", + name: "DeepSeek-V3.2-Speciale", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + knowledge: "2024-07", + release_date: "2025-12-01", + last_updated: "2025-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.58, output: 1.68 }, + limit: { context: 128000, output: 128000 }, + }, + "gpt-5.2": { + id: "gpt-5.2", + name: "GPT-5.2", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2025-12-11", + last_updated: "2025-12-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.125 }, + limit: { context: 400000, output: 128000 }, + }, + "mistral-large-2411": { + id: "mistral-large-2411", + name: "Mistral Large 24.11", + family: "mistral-large", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-09", + release_date: "2024-11-01", + last_updated: "2024-11-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 6 }, + limit: { context: 128000, output: 32768 }, + }, + "claude-opus-4-1": { + id: "claude-opus-4-1", + name: "Claude Opus 4.1", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-11-18", + last_updated: "2025-11-18", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 32000 }, + provider: { + npm: "@ai-sdk/anthropic", + api: "https://${AZURE_RESOURCE_NAME}.services.ai.azure.com/anthropic/v1", + }, + }, + "cohere-command-a": { + id: "cohere-command-a", + name: "Command A", + family: "command-a", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-06-01", + release_date: "2025-03-13", + last_updated: "2025-03-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 2.5, output: 10 }, + limit: { context: 256000, output: 8000 }, + }, + "llama-3.2-11b-vision-instruct": { + id: "llama-3.2-11b-vision-instruct", + name: "Llama-3.2-11B-Vision-Instruct", + family: "llama", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-09-25", + last_updated: "2024-09-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.37, output: 0.37 }, + limit: { context: 128000, output: 8192 }, + }, + "meta-llama-3.1-405b-instruct": { + id: "meta-llama-3.1-405b-instruct", + name: "Meta-Llama-3.1-405B-Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 5.33, output: 16 }, + limit: { context: 128000, output: 32768 }, + }, + "gpt-5.1-chat": { + id: "gpt-5.1-chat", + name: "GPT-5.1 Chat", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-11-14", + last_updated: "2025-11-14", + modalities: { input: ["text", "image", "audio"], output: ["text", "image", "audio"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 128000, output: 16384 }, + }, + "gpt-4-turbo-vision": { + id: "gpt-4-turbo-vision", + name: "GPT-4 Turbo Vision", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-11", + release_date: "2023-11-06", + last_updated: "2024-04-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 10, output: 30 }, + limit: { context: 128000, output: 4096 }, + }, + "gpt-5.2-codex": { + id: "gpt-5.2-codex", + name: "GPT-5.2 Codex", + family: "gpt-codex", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-01-14", + last_updated: "2026-01-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.75, output: 14, cache_read: 0.175 }, + limit: { context: 400000, output: 128000 }, + }, + "cohere-embed-v-4-0": { + id: "cohere-embed-v-4-0", + name: "Embed v4", + family: "cohere-embed", + attachment: true, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2025-04-15", + last_updated: "2025-04-15", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.12, output: 0 }, + limit: { context: 128000, output: 1536 }, + }, + "gpt-5.1-codex-mini": { + id: "gpt-5.1-codex-mini", + name: "GPT-5.1 Codex Mini", + family: "gpt-codex", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-11-14", + last_updated: "2025-11-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 2, cache_read: 0.025 }, + limit: { context: 400000, output: 128000 }, + }, + "gpt-3.5-turbo-0125": { + id: "gpt-3.5-turbo-0125", + name: "GPT-3.5 Turbo 0125", + family: "gpt", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2021-08", + release_date: "2024-01-25", + last_updated: "2024-01-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 1.5 }, + limit: { context: 16384, output: 16384 }, + }, + "o1-preview": { + id: "o1-preview", + name: "o1-preview", + family: "o", + attachment: false, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2023-09", + release_date: "2024-09-12", + last_updated: "2024-09-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 16.5, output: 66, cache_read: 8.25 }, + limit: { context: 128000, output: 32768 }, + }, + "cohere-embed-v3-multilingual": { + id: "cohere-embed-v3-multilingual", + name: "Embed v3 Multilingual", + family: "cohere-embed", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2023-11-07", + last_updated: "2023-11-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0 }, + limit: { context: 512, output: 1024 }, + }, + "grok-4-20-non-reasoning": { + id: "grok-4-20-non-reasoning", + name: "Grok 4.20 (Non-Reasoning)", + family: "grok", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-09", + release_date: "2026-04-08", + last_updated: "2026-04-08", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 6 }, + limit: { context: 262000, output: 8192 }, + status: "beta", + }, + "gpt-5.1": { + id: "gpt-5.1", + name: "GPT-5.1", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-11-14", + last_updated: "2025-11-14", + modalities: { input: ["text", "image", "audio"], output: ["text", "image", "audio"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 272000, output: 128000 }, + }, + "grok-4-fast-reasoning": { + id: "grok-4-fast-reasoning", + name: "Grok 4 Fast (Reasoning)", + family: "grok", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-09-19", + last_updated: "2025-09-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5, cache_read: 0.05 }, + limit: { context: 2000000, output: 30000 }, + }, + o1: { + id: "o1", + name: "o1", + family: "o", + attachment: false, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2023-09", + release_date: "2024-12-05", + last_updated: "2024-12-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 60, cache_read: 7.5 }, + limit: { context: 200000, output: 100000 }, + }, + "mistral-small-2503": { + id: "mistral-small-2503", + name: "Mistral Small 3.1", + family: "mistral-small", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-09", + release_date: "2025-03-01", + last_updated: "2025-03-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.3 }, + limit: { context: 128000, output: 32768 }, + }, + "model-router": { + id: "model-router", + name: "Model Router", + family: "model-router", + attachment: true, + reasoning: false, + tool_call: true, + release_date: "2025-05-19", + last_updated: "2025-11-18", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.14, output: 0 }, + limit: { context: 128000, output: 16384 }, + }, + "gpt-3.5-turbo-1106": { + id: "gpt-3.5-turbo-1106", + name: "GPT-3.5 Turbo 1106", + family: "gpt", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2021-08", + release_date: "2023-11-06", + last_updated: "2023-11-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 2 }, + limit: { context: 16384, output: 16384 }, + }, + "text-embedding-3-small": { + id: "text-embedding-3-small", + name: "text-embedding-3-small", + family: "text-embedding", + attachment: false, + reasoning: false, + tool_call: false, + release_date: "2024-01-25", + last_updated: "2024-01-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.02, output: 0 }, + limit: { context: 8191, output: 1536 }, + }, + "deepseek-v3.1": { + id: "deepseek-v3.1", + name: "DeepSeek-V3.1", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2025-08-21", + last_updated: "2025-08-21", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.56, output: 1.68 }, + limit: { context: 131072, output: 131072 }, + }, + "claude-opus-4-5": { + id: "claude-opus-4-5", + name: "Claude Opus 4.5", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-11-24", + last_updated: "2025-08-01", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 200000, output: 64000 }, + provider: { + npm: "@ai-sdk/anthropic", + api: "https://${AZURE_RESOURCE_NAME}.services.ai.azure.com/anthropic/v1", + }, + }, + "phi-3-mini-4k-instruct": { + id: "phi-3-mini-4k-instruct", + name: "Phi-3-mini-instruct (4k)", + family: "phi", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2023-10", + release_date: "2024-04-23", + last_updated: "2024-04-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.13, output: 0.52 }, + limit: { context: 4096, output: 1024 }, + }, + "meta-llama-3.1-70b-instruct": { + id: "meta-llama-3.1-70b-instruct", + name: "Meta-Llama-3.1-70B-Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 2.68, output: 3.54 }, + limit: { context: 128000, output: 32768 }, + }, + "phi-4-mini-reasoning": { + id: "phi-4-mini-reasoning", + name: "Phi-4-mini-reasoning", + family: "phi", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2023-10", + release_date: "2024-12-11", + last_updated: "2024-12-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.075, output: 0.3 }, + limit: { context: 128000, output: 4096 }, + }, + "gpt-4": { + id: "gpt-4", + name: "GPT-4", + family: "gpt", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-11", + release_date: "2023-03-14", + last_updated: "2023-03-14", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 60, output: 120 }, + limit: { context: 8192, output: 8192 }, + }, + "meta-llama-3-8b-instruct": { + id: "meta-llama-3-8b-instruct", + name: "Meta-Llama-3-8B-Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2023-12", + release_date: "2024-04-18", + last_updated: "2024-04-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 0.61 }, + limit: { context: 8192, output: 2048 }, + }, + "kimi-k2.6": { + id: "kimi-k2.6", + name: "Kimi K2.6", + family: "kimi", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-04-22", + last_updated: "2026-04-22", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.95, output: 4 }, + limit: { context: 262144, output: 262144 }, + provider: { + npm: "@ai-sdk/openai-compatible", + api: "https://${AZURE_RESOURCE_NAME}.services.ai.azure.com/models", + shape: "completions", + }, + }, + "gpt-5-codex": { + id: "gpt-5-codex", + name: "GPT-5-Codex", + family: "gpt-codex", + attachment: false, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-09-15", + last_updated: "2025-09-15", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.13 }, + limit: { context: 400000, output: 128000 }, + }, + "phi-4-mini": { + id: "phi-4-mini", + name: "Phi-4-mini", + family: "phi", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-10", + release_date: "2024-12-11", + last_updated: "2024-12-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.075, output: 0.3 }, + limit: { context: 128000, output: 4096 }, + }, + "grok-4-20-reasoning": { + id: "grok-4-20-reasoning", + name: "Grok 4.20 (Reasoning)", + family: "grok", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-09", + release_date: "2026-04-08", + last_updated: "2026-04-08", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 6 }, + limit: { context: 262000, output: 8192 }, + status: "beta", + }, + "gpt-3.5-turbo-0301": { + id: "gpt-3.5-turbo-0301", + name: "GPT-3.5 Turbo 0301", + family: "gpt", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2021-08", + release_date: "2023-03-01", + last_updated: "2023-03-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.5, output: 2 }, + limit: { context: 4096, output: 4096 }, + }, + "claude-opus-4-6": { + id: "claude-opus-4-6", + name: "Claude Opus 4.6", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-05-31", + release_date: "2026-02-05", + last_updated: "2026-02-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 5, + output: 25, + cache_read: 0.5, + cache_write: 6.25, + context_over_200k: { input: 10, output: 37.5, cache_read: 1, cache_write: 12.5 }, + }, + limit: { context: 200000, output: 128000 }, + provider: { + npm: "@ai-sdk/anthropic", + api: "https://${AZURE_RESOURCE_NAME}.services.ai.azure.com/anthropic/v1", + }, + }, + "phi-3-small-128k-instruct": { + id: "phi-3-small-128k-instruct", + name: "Phi-3-small-instruct (128k)", + family: "phi", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2023-10", + release_date: "2024-04-23", + last_updated: "2024-04-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 128000, output: 4096 }, + }, + "deepseek-v3.2": { + id: "deepseek-v3.2", + name: "DeepSeek-V3.2", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2025-12-01", + last_updated: "2025-12-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.58, output: 1.68 }, + limit: { context: 128000, output: 128000 }, + }, + "phi-3-medium-128k-instruct": { + id: "phi-3-medium-128k-instruct", + name: "Phi-3-medium-instruct (128k)", + family: "phi", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2023-10", + release_date: "2024-04-23", + last_updated: "2024-04-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.17, output: 0.68 }, + limit: { context: 128000, output: 4096 }, + }, + "gpt-3.5-turbo-0613": { + id: "gpt-3.5-turbo-0613", + name: "GPT-3.5 Turbo 0613", + family: "gpt", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2021-08", + release_date: "2023-06-13", + last_updated: "2023-06-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 4 }, + limit: { context: 16384, output: 16384 }, + }, + "claude-sonnet-4-5": { + id: "claude-sonnet-4-5", + name: "Claude Sonnet 4.5", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-07-31", + release_date: "2025-11-18", + last_updated: "2025-11-18", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + provider: { + npm: "@ai-sdk/anthropic", + api: "https://${AZURE_RESOURCE_NAME}.services.ai.azure.com/anthropic/v1", + }, + }, + "phi-4": { + id: "phi-4", + name: "Phi-4", + family: "phi", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2023-10", + release_date: "2024-12-11", + last_updated: "2024-12-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.125, output: 0.5 }, + limit: { context: 128000, output: 4096 }, + }, + "gpt-5": { + id: "gpt-5", + name: "GPT-5", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.13 }, + limit: { context: 272000, output: 128000 }, + }, + "gpt-4-32k": { + id: "gpt-4-32k", + name: "GPT-4 32K", + family: "gpt", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-11", + release_date: "2023-03-14", + last_updated: "2023-03-14", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 60, output: 120 }, + limit: { context: 32768, output: 32768 }, + }, + "cohere-embed-v3-english": { + id: "cohere-embed-v3-english", + name: "Embed v3 English", + family: "cohere-embed", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2023-11-07", + last_updated: "2023-11-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0 }, + limit: { context: 512, output: 1024 }, + }, + "phi-4-reasoning-plus": { + id: "phi-4-reasoning-plus", + name: "Phi-4-reasoning-plus", + family: "phi", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + knowledge: "2023-10", + release_date: "2024-12-11", + last_updated: "2024-12-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.125, output: 0.5 }, + limit: { context: 32000, output: 4096 }, + }, + "mistral-medium-2505": { + id: "mistral-medium-2505", + name: "Mistral Medium 3", + family: "mistral-medium", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-05", + release_date: "2025-05-07", + last_updated: "2025-05-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 2 }, + limit: { context: 128000, output: 128000 }, + }, + "gpt-3.5-turbo-instruct": { + id: "gpt-3.5-turbo-instruct", + name: "GPT-3.5 Turbo Instruct", + family: "gpt", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2021-08", + release_date: "2023-09-21", + last_updated: "2023-09-21", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.5, output: 2 }, + limit: { context: 4096, output: 4096 }, + }, + "deepseek-r1-0528": { + id: "deepseek-r1-0528", + name: "DeepSeek-R1-0528", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2025-05-28", + last_updated: "2025-05-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.35, output: 5.4 }, + limit: { context: 163840, output: 163840 }, + }, + "kimi-k2-thinking": { + id: "kimi-k2-thinking", + name: "Kimi K2 Thinking", + family: "kimi-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: true, + temperature: true, + knowledge: "2024-08", + release_date: "2025-11-06", + last_updated: "2025-12-02", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.5, cache_read: 0.15 }, + limit: { context: 262144, output: 262144 }, + }, + "gpt-5.1-codex": { + id: "gpt-5.1-codex", + name: "GPT-5.1 Codex", + family: "gpt-codex", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-11-14", + last_updated: "2025-11-14", + modalities: { input: ["text", "image", "audio"], output: ["text", "image", "audio"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 400000, output: 128000 }, + }, + "codestral-2501": { + id: "codestral-2501", + name: "Codestral 25.01", + family: "codestral", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-03", + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 0.9 }, + limit: { context: 256000, output: 256000 }, + }, + "llama-4-maverick-17b-128e-instruct-fp8": { + id: "llama-4-maverick-17b-128e-instruct-fp8", + name: "Llama 4 Maverick 17B 128E Instruct FP8", + family: "llama", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-08", + release_date: "2025-04-05", + last_updated: "2025-04-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.25, output: 1 }, + limit: { context: 128000, output: 8192 }, + }, + "mai-ds-r1": { + id: "mai-ds-r1", + name: "MAI-DS-R1", + family: "mai", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + knowledge: "2024-06", + release_date: "2025-01-20", + last_updated: "2025-01-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.35, output: 5.4 }, + limit: { context: 128000, output: 8192 }, + }, + "gpt-5.1-codex-max": { + id: "gpt-5.1-codex-max", + name: "GPT-5.1 Codex Max", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-11-13", + last_updated: "2025-11-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 400000, output: 128000 }, + }, + "claude-sonnet-4-6": { + id: "claude-sonnet-4-6", + name: "Claude Sonnet 4.6", + family: "claude-sonnet", + attachment: true, + reasoning: true, + 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, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 1000000, output: 64000 }, + provider: { + npm: "@ai-sdk/anthropic", + api: "https://${AZURE_RESOURCE_NAME}.services.ai.azure.com/anthropic/v1", + }, + }, + "gpt-5.5": { + id: "gpt-5.5", + name: "GPT-5.5", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-12-01", + release_date: "2026-04-24", + last_updated: "2026-04-24", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 30, cache_read: 0.5, context_over_200k: { input: 10, output: 45, cache_read: 1 } }, + limit: { context: 1050000, input: 922000, output: 128000 }, + }, + "gpt-4-turbo": { + id: "gpt-4-turbo", + name: "GPT-4 Turbo", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2023-11-06", + last_updated: "2024-04-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 10, output: 30 }, + limit: { context: 128000, output: 4096 }, + }, + "gpt-4o-mini": { + id: "gpt-4o-mini", + name: "GPT-4o mini", + family: "gpt-mini", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-09", + release_date: "2024-07-18", + last_updated: "2024-07-18", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.6, cache_read: 0.08 }, + limit: { context: 128000, output: 16384 }, + }, + "gpt-5.4-mini": { + id: "gpt-5.4-mini", + name: "GPT-5.4 Mini", + family: "gpt-mini", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-17", + last_updated: "2026-03-17", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.75, output: 4.5, cache_read: 0.075 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "cohere-command-r-08-2024": { + id: "cohere-command-r-08-2024", + name: "Command R", + family: "command-r", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-06-01", + release_date: "2024-08-30", + last_updated: "2024-08-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 128000, output: 4000 }, + }, + "o4-mini": { + id: "o4-mini", + name: "o4-mini", + family: "o-mini", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-05", + release_date: "2025-04-16", + last_updated: "2025-04-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 4.4, cache_read: 0.28 }, + limit: { context: 200000, output: 100000 }, + }, + "gpt-5.4-nano": { + id: "gpt-5.4-nano", + name: "GPT-5.4 Nano", + family: "gpt-nano", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-17", + last_updated: "2026-03-17", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 1.25, cache_read: 0.02 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "grok-code-fast-1": { + id: "grok-code-fast-1", + name: "Grok Code Fast 1", + family: "grok", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2023-10", + release_date: "2025-08-28", + last_updated: "2025-08-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 1.5, cache_read: 0.02 }, + limit: { context: 256000, output: 10000 }, + }, + "gpt-5.4-pro": { + id: "gpt-5.4-pro", + name: "GPT-5.4 Pro", + family: "gpt-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-05", + last_updated: "2026-03-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 30, output: 180, context_over_200k: { input: 60, output: 270 } }, + limit: { context: 1050000, input: 922000, output: 128000 }, + }, + "o3-mini": { + id: "o3-mini", + name: "o3-mini", + family: "o-mini", + attachment: false, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-05", + release_date: "2024-12-20", + last_updated: "2025-01-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1.1, output: 4.4, cache_read: 0.55 }, + limit: { context: 200000, output: 100000 }, + }, + "grok-4": { + id: "grok-4", + name: "Grok 4", + family: "grok", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-07-09", + last_updated: "2025-07-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, reasoning: 15, cache_read: 0.75 }, + limit: { context: 256000, output: 64000 }, + }, + "gpt-5.4": { + id: "gpt-5.4", + name: "GPT-5.4", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-05", + last_updated: "2026-03-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 2.5, + output: 15, + cache_read: 0.25, + context_over_200k: { input: 5, output: 22.5, cache_read: 0.5 }, + }, + limit: { context: 1050000, input: 922000, output: 128000 }, + }, + "gpt-4.1-nano": { + id: "gpt-4.1-nano", + name: "GPT-4.1 nano", + family: "gpt-nano", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-04-14", + last_updated: "2025-04-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4, cache_read: 0.03 }, + limit: { context: 1047576, output: 32768 }, + }, + "grok-3-mini": { + id: "grok-3-mini", + name: "Grok 3 Mini", + family: "grok", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-11", + release_date: "2025-02-17", + last_updated: "2025-02-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 0.5, reasoning: 0.5, cache_read: 0.075 }, + limit: { context: 131072, output: 8192 }, + }, + o3: { + id: "o3", + name: "o3", + family: "o", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2024-05", + release_date: "2025-04-16", + last_updated: "2025-04-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 8, cache_read: 0.5 }, + limit: { context: 200000, output: 100000 }, + }, + "gpt-5-pro": { + id: "gpt-5-pro", + name: "GPT-5 Pro", + family: "gpt-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2025-10-06", + last_updated: "2025-10-06", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 120 }, + limit: { context: 400000, output: 272000 }, + }, + "gpt-4o": { + id: "gpt-4o", + name: "GPT-4o", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-09", + release_date: "2024-05-13", + last_updated: "2024-08-06", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2.5, output: 10, cache_read: 1.25 }, + limit: { context: 128000, output: 16384 }, + }, + "cohere-command-r-plus-08-2024": { + id: "cohere-command-r-plus-08-2024", + name: "Command R+", + family: "command-r", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-06-01", + release_date: "2024-08-30", + last_updated: "2024-08-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 2.5, output: 10 }, + limit: { context: 128000, output: 4000 }, + }, + "gpt-4.1": { + id: "gpt-4.1", + name: "GPT-4.1", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-04-14", + last_updated: "2025-04-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 8, cache_read: 0.5 }, + limit: { context: 1047576, output: 32768 }, + }, + "gpt-4.1-mini": { + id: "gpt-4.1-mini", + name: "GPT-4.1 mini", + family: "gpt-mini", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-04-14", + last_updated: "2025-04-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 1.6, cache_read: 0.1 }, + limit: { context: 1047576, output: 32768 }, + }, + "grok-3": { + id: "grok-3", + name: "Grok 3", + family: "grok", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-11", + release_date: "2025-02-17", + last_updated: "2025-02-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.75 }, + limit: { context: 131072, output: 8192 }, + }, + "grok-4-fast-non-reasoning": { + id: "grok-4-fast-non-reasoning", + name: "Grok 4 Fast (Non-Reasoning)", + family: "grok", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-09-19", + last_updated: "2025-09-19", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.2, output: 0.5, cache_read: 0.05 }, + limit: { context: 2000000, output: 30000 }, + }, + }, + }, + fastrouter: { + id: "fastrouter", + env: ["FASTROUTER_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://go.fastrouter.ai/api/v1", + name: "FastRouter", + doc: "https://fastrouter.ai/models", + models: { + "x-ai/grok-4": { + id: "x-ai/grok-4", + name: "Grok 4", + family: "grok", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-07-09", + last_updated: "2025-07-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.75, cache_write: 15 }, + limit: { context: 256000, output: 64000 }, + }, + "deepseek-ai/deepseek-r1-distill-llama-70b": { + id: "deepseek-ai/deepseek-r1-distill-llama-70b", + name: "DeepSeek R1 Distill Llama 70B", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + knowledge: "2024-10", + release_date: "2025-01-23", + last_updated: "2025-01-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.03, output: 0.14 }, + limit: { context: 131072, output: 131072 }, + }, + "openai/gpt-5-mini": { + id: "openai/gpt-5-mini", + name: "GPT-5 Mini", + family: "gpt-mini", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10-01", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 2, cache_read: 0.025 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-5-nano": { + id: "openai/gpt-5-nano", + name: "GPT-5 Nano", + family: "gpt-nano", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10-01", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.05, output: 0.4, cache_read: 0.005 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-oss-20b": { + id: "openai/gpt-oss-20b", + name: "GPT OSS 20B", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.05, output: 0.2 }, + limit: { context: 131072, output: 65536 }, + }, + "openai/gpt-5": { + id: "openai/gpt-5", + name: "GPT-5", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10-01", + release_date: "2025-08-07", + last_updated: "2025-08-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.125 }, + limit: { context: 400000, output: 128000 }, + }, + "openai/gpt-oss-120b": { + id: "openai/gpt-oss-120b", + name: "GPT OSS 120B", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 131072, output: 32768 }, + }, + "z-ai/glm-5": { + id: "z-ai/glm-5", + name: "GLM-5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-02-11", + last_updated: "2026-02-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.95, output: 3.15 }, + limit: { context: 204800, output: 131072 }, + }, + "qwen/qwen3-coder": { + id: "qwen/qwen3-coder", + name: "Qwen3 Coder", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-23", + last_updated: "2025-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 262144, output: 66536 }, + }, + "google/gemini-2.5-pro": { + id: "google/gemini-2.5-pro", + name: "Gemini 2.5 Pro", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-06-17", + last_updated: "2025-06-17", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.31 }, + limit: { context: 1048576, output: 65536 }, + }, + "google/gemini-2.5-flash": { + id: "google/gemini-2.5-flash", + name: "Gemini 2.5 Flash", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-06-17", + last_updated: "2025-06-17", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 2.5, cache_read: 0.0375 }, + limit: { context: 1048576, output: 65536 }, + }, + "moonshotai/kimi-k2": { + id: "moonshotai/kimi-k2", + name: "Kimi K2", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-07-11", + last_updated: "2025-07-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.55, output: 2.2 }, + limit: { context: 131072, output: 32768 }, + }, + "openai/gpt-4.1": { + id: "openai/gpt-4.1", + name: "GPT-4.1", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-04-14", + last_updated: "2025-04-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 8, cache_read: 0.5 }, + limit: { context: 1047576, output: 32768 }, + }, + "anthropic/claude-opus-4.1": { + id: "anthropic/claude-opus-4.1", + name: "Claude Opus 4.1", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 32000 }, + }, + "anthropic/claude-sonnet-4": { + id: "anthropic/claude-sonnet-4", + name: "Claude Sonnet 4", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + }, + }, + }, + stackit: { + id: "stackit", + env: ["STACKIT_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.openai-compat.model-serving.eu01.onstackit.cloud/v1", + name: "STACKIT", + doc: "https://docs.stackit.cloud/products/data-and-ai/ai-model-serving/basics/available-shared-models", + models: { + "Qwen/Qwen3-VL-Embedding-8B": { + id: "Qwen/Qwen3-VL-Embedding-8B", + name: "Qwen3-VL Embedding 8B", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: false, + release_date: "2026-02-05", + last_updated: "2026-02-05", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.09, output: 0.09 }, + limit: { context: 32000, output: 4096 }, + }, + "Qwen/Qwen3-VL-235B-A22B-Instruct-FP8": { + id: "Qwen/Qwen3-VL-235B-A22B-Instruct-FP8", + name: "Qwen3-VL 235B", + family: "qwen", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2024-11-01", + last_updated: "2024-11-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 1.64, output: 1.91 }, + limit: { context: 218000, output: 8192 }, + }, + "neuralmagic/Meta-Llama-3.1-8B-Instruct-FP8": { + id: "neuralmagic/Meta-Llama-3.1-8B-Instruct-FP8", + name: "Llama 3.1 8B", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.16, output: 0.27 }, + limit: { context: 128000, output: 8192 }, + }, + "neuralmagic/Mistral-Nemo-Instruct-2407-FP8": { + id: "neuralmagic/Mistral-Nemo-Instruct-2407-FP8", + name: "Mistral Nemo", + family: "mistral", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2024-07-01", + last_updated: "2024-07-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.49, output: 0.71 }, + limit: { context: 128000, output: 8192 }, + }, + "openai/gpt-oss-120b": { + id: "openai/gpt-oss-120b", + name: "GPT-OSS 120B", + family: "gpt", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.49, output: 0.71 }, + limit: { context: 131000, output: 8192 }, + }, + "cortecs/Llama-3.3-70B-Instruct-FP8-Dynamic": { + id: "cortecs/Llama-3.3-70B-Instruct-FP8-Dynamic", + name: "Llama 3.3 70B", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2024-12-05", + last_updated: "2024-12-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.49, output: 0.71 }, + limit: { context: 128000, output: 8192 }, + }, + "google/gemma-3-27b-it": { + id: "google/gemma-3-27b-it", + name: "Gemma 3 27B", + family: "gemma", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + release_date: "2025-05-17", + last_updated: "2025-05-17", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.49, output: 0.71 }, + limit: { context: 37000, output: 8192 }, + }, + "intfloat/e5-mistral-7b-instruct": { + id: "intfloat/e5-mistral-7b-instruct", + name: "E5 Mistral 7B", + family: "mistral", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: false, + release_date: "2023-12-11", + last_updated: "2023-12-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.02, output: 0.02 }, + limit: { context: 4096, output: 4096 }, + }, + }, + }, + "tencent-coding-plan": { + id: "tencent-coding-plan", + env: ["TENCENT_CODING_PLAN_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.lkeap.cloud.tencent.com/coding/v3", + name: "Tencent Coding Plan (China)", + doc: "https://cloud.tencent.com/document/product/1772/128947", + models: { + "kimi-k2.5": { + id: "kimi-k2.5", + name: "Kimi-K2.5", + family: "kimi", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-01", + release_date: "2026-01-27", + last_updated: "2026-01-27", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 262144, output: 32768 }, + }, + "glm-5": { + id: "glm-5", + name: "GLM-5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-02-11", + last_updated: "2026-02-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 202752, output: 16384 }, + }, + "hunyuan-turbos": { + id: "hunyuan-turbos", + name: "Hunyuan-TurboS", + family: "hunyuan", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2026-03-08", + last_updated: "2026-03-08", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 131072, output: 16384 }, + }, + "hunyuan-t1": { + id: "hunyuan-t1", + name: "Hunyuan-T1", + family: "hunyuan", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-03-08", + last_updated: "2026-03-08", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 131072, output: 16384 }, + }, + "hunyuan-2.0-instruct": { + id: "hunyuan-2.0-instruct", + name: "Tencent HY 2.0 Instruct", + family: "hunyuan", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2026-03-08", + last_updated: "2026-03-08", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 131072, output: 16384 }, + }, + "minimax-m2.5": { + id: "minimax-m2.5", + name: "MiniMax-M2.5", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 204800, output: 32768 }, + }, + "tc-code-latest": { + id: "tc-code-latest", + name: "Auto", + family: "auto", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2026-03-08", + last_updated: "2026-03-08", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 131072, output: 16384 }, + }, + "hunyuan-2.0-thinking": { + id: "hunyuan-2.0-thinking", + name: "Tencent HY 2.0 Think", + family: "hunyuan", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-03-08", + last_updated: "2026-03-08", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 131072, output: 16384 }, + }, + }, + }, + "privatemode-ai": { + id: "privatemode-ai", + env: ["PRIVATEMODE_API_KEY", "PRIVATEMODE_ENDPOINT"], + npm: "@ai-sdk/openai-compatible", + api: "http://localhost:8080/v1", + name: "Privatemode AI", + doc: "https://docs.privatemode.ai/api/overview", + models: { + "gemma-3-27b": { + id: "gemma-3-27b", + name: "Gemma 3 27B", + family: "gemma", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-08", + release_date: "2025-03-12", + last_updated: "2025-03-12", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 8192 }, + }, + "whisper-large-v3": { + id: "whisper-large-v3", + name: "Whisper large-v3", + family: "whisper", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + knowledge: "2023-09", + release_date: "2023-09-01", + last_updated: "2023-09-01", + modalities: { input: ["audio"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 0, output: 4096 }, + }, + "qwen3-embedding-4b": { + id: "qwen3-embedding-4b", + name: "Qwen3-Embedding 4B", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + structured_output: false, + temperature: true, + knowledge: "2025-06", + release_date: "2025-06-06", + last_updated: "2025-06-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 32000, output: 2560 }, + }, + "gpt-oss-120b": { + id: "gpt-oss-120b", + name: "gpt-oss-120b", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-08", + release_date: "2025-08-04", + last_updated: "2025-08-14", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 128000 }, + }, + "qwen3-coder-30b-a3b": { + id: "qwen3-coder-30b-a3b", + name: "Qwen3-Coder 30B-A3B", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-04", + last_updated: "2025-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 32768 }, + }, + }, + }, + google: { + id: "google", + env: ["GOOGLE_GENERATIVE_AI_API_KEY", "GEMINI_API_KEY"], + npm: "@ai-sdk/google", + name: "Google", + doc: "https://ai.google.dev/gemini-api/docs/models", + models: { + "gemini-flash-lite-latest": { + id: "gemini-flash-lite-latest", + name: "Gemini Flash-Lite Latest", + family: "gemini-flash-lite", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-09-25", + last_updated: "2025-09-25", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4, cache_read: 0.025 }, + limit: { context: 1048576, output: 65536 }, + }, + "gemini-2.5-pro-preview-05-06": { + id: "gemini-2.5-pro-preview-05-06", + name: "Gemini 2.5 Pro Preview 05-06", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-05-06", + last_updated: "2025-05-06", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.31 }, + limit: { context: 1048576, output: 65536 }, + }, + "gemini-live-2.5-flash-preview-native-audio": { + id: "gemini-live-2.5-flash-preview-native-audio", + name: "Gemini Live 2.5 Flash Preview Native Audio", + family: "gemini-flash", + attachment: false, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2025-01", + release_date: "2025-06-17", + last_updated: "2025-09-18", + modalities: { input: ["text", "audio", "video"], output: ["text", "audio"] }, + open_weights: false, + cost: { input: 0.5, output: 2, input_audio: 3, output_audio: 12 }, + limit: { context: 131072, output: 65536 }, + }, + "gemini-3.1-pro-preview-customtools": { + id: "gemini-3.1-pro-preview-customtools", + name: "Gemini 3.1 Pro Preview Custom Tools", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-02-19", + last_updated: "2026-02-19", + modalities: { input: ["text", "image", "video", "audio", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 12, cache_read: 0.2, context_over_200k: { input: 4, output: 18, cache_read: 0.4 } }, + limit: { context: 1048576, output: 65536 }, + }, + "gemini-2.5-flash-lite-preview-09-2025": { + id: "gemini-2.5-flash-lite-preview-09-2025", + name: "Gemini 2.5 Flash Lite Preview 09-25", + family: "gemini-flash-lite", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-09-25", + last_updated: "2025-09-25", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4, cache_read: 0.025 }, + limit: { context: 1048576, output: 65536 }, + }, + "gemini-1.5-flash": { + id: "gemini-1.5-flash", + name: "Gemini 1.5 Flash", + family: "gemini-flash", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-05-14", + last_updated: "2024-05-14", + modalities: { input: ["text", "image", "audio", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.075, output: 0.3, cache_read: 0.01875 }, + limit: { context: 1000000, output: 8192 }, + }, + "gemini-1.5-pro": { + id: "gemini-1.5-pro", + name: "Gemini 1.5 Pro", + family: "gemini-pro", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-02-15", + last_updated: "2024-02-15", + modalities: { input: ["text", "image", "audio", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 5, cache_read: 0.3125 }, + limit: { context: 1000000, output: 8192 }, + }, + "gemma-3n-e4b-it": { + id: "gemma-3n-e4b-it", + name: "Gemma 3n 4B", + family: "gemma", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-10", + release_date: "2025-05-20", + last_updated: "2025-05-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 8192, output: 2000 }, + }, + "gemini-3.1-flash-lite-preview": { + id: "gemini-3.1-flash-lite-preview", + name: "Gemini 3.1 Flash Lite Preview", + family: "gemini-flash-lite", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-03-03", + last_updated: "2026-03-03", + modalities: { input: ["text", "image", "video", "audio", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 1.5, cache_read: 0.025, cache_write: 1 }, + limit: { context: 1048576, output: 65536 }, + }, + "gemini-3.1-pro-preview": { + id: "gemini-3.1-pro-preview", + name: "Gemini 3.1 Pro Preview", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-02-19", + last_updated: "2026-02-19", + modalities: { input: ["text", "image", "video", "audio", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 12, cache_read: 0.2, context_over_200k: { input: 4, output: 18, cache_read: 0.4 } }, + limit: { context: 1048576, output: 65536 }, + }, + "gemini-2.0-flash": { + id: "gemini-2.0-flash", + name: "Gemini 2.0 Flash", + family: "gemini-flash", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-06", + release_date: "2024-12-11", + last_updated: "2024-12-11", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4, cache_read: 0.025 }, + limit: { context: 1048576, output: 8192 }, + }, + "gemini-3-flash-preview": { + id: "gemini-3-flash-preview", + name: "Gemini 3 Flash Preview", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-12-17", + last_updated: "2025-12-17", + modalities: { input: ["text", "image", "video", "audio", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 0.5, + output: 3, + cache_read: 0.05, + context_over_200k: { input: 0.5, output: 3, cache_read: 0.05 }, + }, + limit: { context: 1048576, output: 65536 }, + }, + "gemini-2.5-flash-preview-tts": { + id: "gemini-2.5-flash-preview-tts", + name: "Gemini 2.5 Flash Preview TTS", + family: "gemini-flash", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + knowledge: "2025-01", + release_date: "2025-05-01", + last_updated: "2025-05-01", + modalities: { input: ["text"], output: ["audio"] }, + open_weights: false, + cost: { input: 0.5, output: 10 }, + limit: { context: 8000, output: 16000 }, + }, + "gemini-3-pro-preview": { + id: "gemini-3-pro-preview", + name: "Gemini 3 Pro Preview", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-11-18", + last_updated: "2025-11-18", + modalities: { input: ["text", "image", "video", "audio", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 2, output: 12, cache_read: 0.2, context_over_200k: { input: 4, output: 18, cache_read: 0.4 } }, + limit: { context: 1000000, output: 64000 }, + }, + "gemini-2.5-flash-preview-05-20": { + id: "gemini-2.5-flash-preview-05-20", + name: "Gemini 2.5 Flash Preview 05-20", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-05-20", + last_updated: "2025-05-20", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.6, cache_read: 0.0375 }, + limit: { context: 1048576, output: 65536 }, + }, + "gemini-embedding-001": { + id: "gemini-embedding-001", + name: "Gemini Embedding 001", + family: "gemini", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + knowledge: "2025-05", + release_date: "2025-05-20", + last_updated: "2025-05-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0 }, + limit: { context: 2048, output: 3072 }, + }, + "gemini-2.5-pro": { + id: "gemini-2.5-pro", + name: "Gemini 2.5 Pro", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-03-20", + last_updated: "2025-06-05", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { + input: 1.25, + output: 10, + cache_read: 0.125, + context_over_200k: { input: 2.5, output: 15, cache_read: 0.25 }, + }, + limit: { context: 1048576, output: 65536 }, + }, + "gemini-flash-latest": { + id: "gemini-flash-latest", + name: "Gemini Flash Latest", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-09-25", + last_updated: "2025-09-25", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 2.5, cache_read: 0.075, input_audio: 1 }, + limit: { context: 1048576, output: 65536 }, + }, + "gemma-4-31b-it": { + id: "gemma-4-31b-it", + name: "Gemma 4 31B", + family: "gemma", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-04-02", + last_updated: "2026-04-02", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + limit: { context: 256000, output: 8192 }, + }, + "gemini-2.5-pro-preview-06-05": { + id: "gemini-2.5-pro-preview-06-05", + name: "Gemini 2.5 Pro Preview 06-05", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-06-05", + last_updated: "2025-06-05", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1.25, output: 10, cache_read: 0.31 }, + limit: { context: 1048576, output: 65536 }, + }, + "gemini-2.5-flash-image": { + id: "gemini-2.5-flash-image", + name: "Gemini 2.5 Flash Image", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: false, + temperature: true, + knowledge: "2025-06", + release_date: "2025-08-26", + last_updated: "2025-08-26", + modalities: { input: ["text", "image"], output: ["text", "image"] }, + open_weights: false, + cost: { input: 0.3, output: 30, cache_read: 0.075 }, + limit: { context: 32768, output: 32768 }, + }, + "gemini-2.5-flash-lite-preview-06-17": { + id: "gemini-2.5-flash-lite-preview-06-17", + name: "Gemini 2.5 Flash Lite Preview 06-17", + family: "gemini-flash-lite", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-06-17", + last_updated: "2025-06-17", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4, cache_read: 0.025, input_audio: 0.3 }, + limit: { context: 1048576, output: 65536 }, + }, + "gemma-3-12b-it": { + id: "gemma-3-12b-it", + name: "Gemma 3 12B", + family: "gemma", + attachment: true, + reasoning: false, + tool_call: false, + structured_output: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-03-13", + last_updated: "2025-03-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 32768, output: 8192 }, + }, + "gemini-2.5-flash": { + id: "gemini-2.5-flash", + name: "Gemini 2.5 Flash", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-03-20", + last_updated: "2025-06-05", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 2.5, cache_read: 0.03, input_audio: 1 }, + limit: { context: 1048576, output: 65536 }, + }, + "gemma-3n-e2b-it": { + id: "gemma-3n-e2b-it", + name: "Gemma 3n 2B", + family: "gemma", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-10", + release_date: "2025-07-09", + last_updated: "2025-07-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 8192, output: 2000 }, + }, + "gemini-3.1-flash-image-preview": { + id: "gemini-3.1-flash-image-preview", + name: "Gemini 3.1 Flash Image (Preview)", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: false, + temperature: true, + knowledge: "2025-01", + release_date: "2026-02-26", + last_updated: "2026-02-26", + modalities: { input: ["text", "image", "pdf"], output: ["text", "image"] }, + open_weights: false, + cost: { input: 0.25, output: 60 }, + limit: { context: 131072, output: 32768 }, + }, + "gemini-3.1-flash-lite": { + id: "gemini-3.1-flash-lite", + name: "Gemini 3.1 Flash Lite", + family: "gemini-flash-lite", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-05-07", + last_updated: "2026-05-07", + modalities: { input: ["text", "image", "video", "audio", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 1.5, cache_read: 0.025, cache_write: 1 }, + limit: { context: 1048576, output: 65536 }, + }, + "gemma-3-4b-it": { + id: "gemma-3-4b-it", + name: "Gemma 3 4B", + family: "gemma", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + knowledge: "2024-10", + release_date: "2025-03-13", + last_updated: "2025-03-13", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 32768, output: 8192 }, + }, + "gemini-2.5-flash-preview-04-17": { + id: "gemini-2.5-flash-preview-04-17", + name: "Gemini 2.5 Flash Preview 04-17", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-04-17", + last_updated: "2025-04-17", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.15, output: 0.6, cache_read: 0.0375 }, + limit: { context: 1048576, output: 65536 }, + }, + "gemini-2.5-pro-preview-tts": { + id: "gemini-2.5-pro-preview-tts", + name: "Gemini 2.5 Pro Preview TTS", + family: "gemini-flash", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + knowledge: "2025-01", + release_date: "2025-05-01", + last_updated: "2025-05-01", + modalities: { input: ["text"], output: ["audio"] }, + open_weights: false, + cost: { input: 1, output: 20 }, + limit: { context: 8000, output: 16000 }, + }, + "gemini-2.5-flash-preview-09-2025": { + id: "gemini-2.5-flash-preview-09-2025", + name: "Gemini 2.5 Flash Preview 09-25", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-09-25", + last_updated: "2025-09-25", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.3, output: 2.5, cache_read: 0.075, input_audio: 1 }, + limit: { context: 1048576, output: 65536 }, + }, + "gemma-3-27b-it": { + id: "gemma-3-27b-it", + name: "Gemma 3 27B", + family: "gemma", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-03-12", + last_updated: "2025-03-12", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 131072, output: 8192 }, + }, + "gemma-4-26b-a4b-it": { + id: "gemma-4-26b-a4b-it", + name: "Gemma 4 26B", + family: "gemma", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-04-02", + last_updated: "2026-04-02", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + limit: { context: 256000, output: 8192 }, + }, + "gemini-2.5-flash-lite": { + id: "gemini-2.5-flash-lite", + name: "Gemini 2.5 Flash Lite", + family: "gemini-flash-lite", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-06-17", + last_updated: "2025-06-17", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.1, output: 0.4, cache_read: 0.025 }, + limit: { context: 1048576, output: 65536 }, + }, + "gemini-2.5-flash-image-preview": { + id: "gemini-2.5-flash-image-preview", + name: "Gemini 2.5 Flash Image (Preview)", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: false, + temperature: true, + knowledge: "2025-06", + release_date: "2025-08-26", + last_updated: "2025-08-26", + modalities: { input: ["text", "image"], output: ["text", "image"] }, + open_weights: false, + cost: { input: 0.3, output: 30, cache_read: 0.075 }, + limit: { context: 32768, output: 32768 }, + }, + "gemini-1.5-flash-8b": { + id: "gemini-1.5-flash-8b", + name: "Gemini 1.5 Flash-8B", + family: "gemini-flash", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2024-10-03", + last_updated: "2024-10-03", + modalities: { input: ["text", "image", "audio", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.0375, output: 0.15, cache_read: 0.01 }, + limit: { context: 1000000, output: 8192 }, + }, + "gemini-live-2.5-flash": { + id: "gemini-live-2.5-flash", + name: "Gemini Live 2.5 Flash", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-09-01", + last_updated: "2025-09-01", + modalities: { input: ["text", "image", "audio", "video"], output: ["text", "audio"] }, + open_weights: false, + cost: { input: 0.5, output: 2, input_audio: 3, output_audio: 12 }, + limit: { context: 128000, output: 8000 }, + }, + "gemini-2.0-flash-lite": { + id: "gemini-2.0-flash-lite", + name: "Gemini 2.0 Flash Lite", + family: "gemini-flash-lite", + attachment: true, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2024-06", + release_date: "2024-12-11", + last_updated: "2024-12-11", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.075, output: 0.3 }, + limit: { context: 1048576, output: 8192 }, + }, + }, + }, + drun: { + id: "drun", + env: ["DRUN_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://chat.d.run/v1", + name: "D.Run (China)", + doc: "https://www.d.run", + models: { + "public/deepseek-r1": { + id: "public/deepseek-r1", + name: "DeepSeek R1", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12", + release_date: "2025-01-20", + last_updated: "2025-01-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.55, output: 2.2 }, + limit: { context: 131072, output: 32000 }, + }, + "public/minimax-m25": { + id: "public/minimax-m25", + name: "MiniMax M2.5", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_details" }, + temperature: true, + release_date: "2025-03-01", + last_updated: "2025-03-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.29, output: 1.16 }, + limit: { context: 204800, output: 131072 }, + }, + "public/deepseek-v3": { + id: "public/deepseek-v3", + name: "DeepSeek V3", + family: "deepseek", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2024-12-26", + last_updated: "2024-12-26", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.28, output: 1.1 }, + limit: { context: 131072, output: 8192 }, + }, + }, + }, + moonshotai: { + id: "moonshotai", + env: ["MOONSHOT_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.moonshot.ai/v1", + name: "Moonshot AI", + doc: "https://platform.moonshot.ai/docs/api/chat", + models: { + "kimi-k2-0905-preview": { + id: "kimi-k2-0905-preview", + name: "Kimi K2 0905", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-09-05", + last_updated: "2025-09-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.5, cache_read: 0.15 }, + limit: { context: 262144, output: 262144 }, + }, + "kimi-k2.5": { + id: "kimi-k2.5", + name: "Kimi K2.5", + family: "kimi-k2.5", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: false, + knowledge: "2025-01", + release_date: "2026-01", + last_updated: "2026-01", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 3, cache_read: 0.1 }, + limit: { context: 262144, output: 262144 }, + }, + "kimi-k2-thinking-turbo": { + id: "kimi-k2-thinking-turbo", + name: "Kimi K2 Thinking Turbo", + family: "kimi-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-08", + release_date: "2025-11-06", + last_updated: "2025-11-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.15, output: 8, cache_read: 0.15 }, + limit: { context: 262144, output: 262144 }, + }, + "kimi-k2.6": { + id: "kimi-k2.6", + name: "Kimi K2.6", + family: "kimi-k2.6", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-04-21", + last_updated: "2026-04-21", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.95, output: 4, cache_read: 0.16 }, + limit: { context: 262144, output: 262144 }, + }, + "kimi-k2-turbo-preview": { + id: "kimi-k2-turbo-preview", + name: "Kimi K2 Turbo", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-09-05", + last_updated: "2025-09-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 2.4, output: 10, cache_read: 0.6 }, + limit: { context: 262144, output: 262144 }, + }, + "kimi-k2-0711-preview": { + id: "kimi-k2-0711-preview", + name: "Kimi K2 0711", + family: "kimi", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-07-14", + last_updated: "2025-07-14", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.5, cache_read: 0.15 }, + limit: { context: 131072, output: 16384 }, + }, + "kimi-k2-thinking": { + id: "kimi-k2-thinking", + name: "Kimi K2 Thinking", + family: "kimi-thinking", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-08", + release_date: "2025-11-06", + last_updated: "2025-11-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.5, cache_read: 0.15 }, + limit: { context: 262144, output: 262144 }, + }, + }, + }, + berget: { + id: "berget", + env: ["BERGET_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.berget.ai/v1", + name: "Berget.AI", + doc: "https://api.berget.ai", + models: { + "zai-org/GLM-4.7": { + id: "zai-org/GLM-4.7", + name: "GLM 4.7", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-12", + release_date: "2026-01-19", + last_updated: "2026-01-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.77, output: 2.75 }, + limit: { context: 128000, output: 8192 }, + }, + "mistralai/Mistral-Small-3.2-24B-Instruct-2506": { + id: "mistralai/Mistral-Small-3.2-24B-Instruct-2506", + name: "Mistral Small 3.2 24B Instruct 2506", + family: "mistral-small", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-09", + release_date: "2025-10-01", + last_updated: "2025-10-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.33, output: 0.33 }, + limit: { context: 32000, output: 8192 }, + }, + "mistralai/Mistral-Medium-3.5-128B": { + id: "mistralai/Mistral-Medium-3.5-128B", + name: "Mistral Medium 3.5 128B", + family: "mistral-medium", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2026-04", + release_date: "2026-04-29", + last_updated: "2026-04-29", + modalities: { input: ["image", "text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.65, output: 5.5 }, + limit: { context: 262144, output: 131072 }, + }, + "meta-llama/Llama-3.3-70B-Instruct": { + id: "meta-llama/Llama-3.3-70B-Instruct", + name: "Llama 3.3 70B Instruct", + family: "llama", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2023-12", + release_date: "2025-04-27", + last_updated: "2025-04-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.99, output: 0.99 }, + limit: { context: 128000, output: 8192 }, + }, + "openai/gpt-oss-120b": { + id: "openai/gpt-oss-120b", + name: "GPT-OSS-120B", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-08", + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.44, output: 0.99 }, + limit: { context: 128000, output: 8192 }, + }, + "google/gemma-4-31B-it": { + id: "google/gemma-4-31B-it", + name: "Gemma 4 31B Instruct", + family: "gemma", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-12", + release_date: "2026-04-02", + last_updated: "2026-04-02", + modalities: { input: ["audio", "image", "text", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.275, output: 0.55 }, + limit: { context: 128000, output: 8192 }, + }, + }, + }, + "github-models": { + id: "github-models", + env: ["GITHUB_TOKEN"], + npm: "@ai-sdk/openai-compatible", + api: "https://models.github.ai/inference", + name: "GitHub Models", + doc: "https://docs.github.com/en/github-models", + models: { + "deepseek/deepseek-v3-0324": { + id: "deepseek/deepseek-v3-0324", + name: "DeepSeek-V3-0324", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-06", + release_date: "2025-03-24", + last_updated: "2025-03-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 8192 }, + }, + "deepseek/deepseek-r1": { + id: "deepseek/deepseek-r1", + name: "DeepSeek-R1", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-06", + release_date: "2025-01-20", + last_updated: "2025-01-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 65536, output: 8192 }, + }, + "deepseek/deepseek-r1-0528": { + id: "deepseek/deepseek-r1-0528", + name: "DeepSeek-R1-0528", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-06", + release_date: "2025-05-28", + last_updated: "2025-05-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 65536, output: 8192 }, + }, + "ai21-labs/ai21-jamba-1.5-mini": { + id: "ai21-labs/ai21-jamba-1.5-mini", + name: "AI21 Jamba 1.5 Mini", + family: "jamba", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-03", + release_date: "2024-08-29", + last_updated: "2024-08-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 256000, output: 4096 }, + }, + "ai21-labs/ai21-jamba-1.5-large": { + id: "ai21-labs/ai21-jamba-1.5-large", + name: "AI21 Jamba 1.5 Large", + family: "jamba", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-03", + release_date: "2024-08-29", + last_updated: "2024-08-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 256000, output: 4096 }, + }, + "microsoft/phi-3.5-mini-instruct": { + id: "microsoft/phi-3.5-mini-instruct", + name: "Phi-3.5-mini instruct (128k)", + family: "phi", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2023-10", + release_date: "2024-08-20", + last_updated: "2024-08-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "microsoft/phi-3-medium-4k-instruct": { + id: "microsoft/phi-3-medium-4k-instruct", + name: "Phi-3-medium instruct (4k)", + family: "phi", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2023-10", + release_date: "2024-04-23", + last_updated: "2024-04-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 4096, output: 1024 }, + }, + "microsoft/phi-3.5-moe-instruct": { + id: "microsoft/phi-3.5-moe-instruct", + name: "Phi-3.5-MoE instruct (128k)", + family: "phi", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2023-10", + release_date: "2024-08-20", + last_updated: "2024-08-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "microsoft/phi-3-mini-128k-instruct": { + id: "microsoft/phi-3-mini-128k-instruct", + name: "Phi-3-mini instruct (128k)", + family: "phi", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2023-10", + release_date: "2024-04-23", + last_updated: "2024-04-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "microsoft/phi-4-mini-instruct": { + id: "microsoft/phi-4-mini-instruct", + name: "Phi-4-mini-instruct", + family: "phi", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2023-10", + release_date: "2024-12-11", + last_updated: "2024-12-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "microsoft/phi-4-reasoning": { + id: "microsoft/phi-4-reasoning", + name: "Phi-4-Reasoning", + family: "phi", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2023-10", + release_date: "2024-12-11", + last_updated: "2024-12-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "microsoft/phi-3-small-8k-instruct": { + id: "microsoft/phi-3-small-8k-instruct", + name: "Phi-3-small instruct (8k)", + family: "phi", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2023-10", + release_date: "2024-04-23", + last_updated: "2024-04-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 8192, output: 2048 }, + }, + "microsoft/phi-3.5-vision-instruct": { + id: "microsoft/phi-3.5-vision-instruct", + name: "Phi-3.5-vision instruct (128k)", + family: "phi", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2023-10", + release_date: "2024-08-20", + last_updated: "2024-08-20", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "microsoft/phi-3-mini-4k-instruct": { + id: "microsoft/phi-3-mini-4k-instruct", + name: "Phi-3-mini instruct (4k)", + family: "phi", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2023-10", + release_date: "2024-04-23", + last_updated: "2024-04-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 4096, output: 1024 }, + }, + "microsoft/phi-4-mini-reasoning": { + id: "microsoft/phi-4-mini-reasoning", + name: "Phi-4-mini-reasoning", + family: "phi", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2023-10", + release_date: "2024-12-11", + last_updated: "2024-12-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "microsoft/phi-3-small-128k-instruct": { + id: "microsoft/phi-3-small-128k-instruct", + name: "Phi-3-small instruct (128k)", + family: "phi", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2023-10", + release_date: "2024-04-23", + last_updated: "2024-04-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "microsoft/phi-3-medium-128k-instruct": { + id: "microsoft/phi-3-medium-128k-instruct", + name: "Phi-3-medium instruct (128k)", + family: "phi", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2023-10", + release_date: "2024-04-23", + last_updated: "2024-04-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "microsoft/phi-4": { + id: "microsoft/phi-4", + name: "Phi-4", + family: "phi", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2023-10", + release_date: "2024-12-11", + last_updated: "2024-12-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 16000, output: 4096 }, + }, + "microsoft/phi-4-multimodal-instruct": { + id: "microsoft/phi-4-multimodal-instruct", + name: "Phi-4-multimodal-instruct", + family: "phi", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2023-10", + release_date: "2024-12-11", + last_updated: "2024-12-11", + modalities: { input: ["text", "image", "audio"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "microsoft/mai-ds-r1": { + id: "microsoft/mai-ds-r1", + name: "MAI-DS-R1", + family: "mai", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-06", + release_date: "2025-01-20", + last_updated: "2025-01-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 65536, output: 8192 }, + }, + "cohere/cohere-command-r-08-2024": { + id: "cohere/cohere-command-r-08-2024", + name: "Cohere Command R 08-2024", + family: "command-r", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-03", + release_date: "2024-08-01", + last_updated: "2024-08-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "cohere/cohere-command-a": { + id: "cohere/cohere-command-a", + name: "Cohere Command A", + family: "command-a", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-03", + release_date: "2024-11-01", + last_updated: "2024-11-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "cohere/cohere-command-r-plus": { + id: "cohere/cohere-command-r-plus", + name: "Cohere Command R+", + family: "command-r", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-03", + release_date: "2024-04-04", + last_updated: "2024-08-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "cohere/cohere-command-r": { + id: "cohere/cohere-command-r", + name: "Cohere Command R", + family: "command-r", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-03", + release_date: "2024-03-11", + last_updated: "2024-08-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "cohere/cohere-command-r-plus-08-2024": { + id: "cohere/cohere-command-r-plus-08-2024", + name: "Cohere Command R+ 08-2024", + family: "command-r", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-03", + release_date: "2024-08-01", + last_updated: "2024-08-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 4096 }, + }, + "xai/grok-3-mini": { + id: "xai/grok-3-mini", + name: "Grok 3 Mini", + family: "grok", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2024-12-09", + last_updated: "2024-12-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 8192 }, + }, + "xai/grok-3": { + id: "xai/grok-3", + name: "Grok 3", + family: "grok", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2024-12-09", + last_updated: "2024-12-09", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 8192 }, + }, + "openai/o1-mini": { + id: "openai/o1-mini", + name: "OpenAI o1-mini", + family: "o-mini", + attachment: false, + reasoning: true, + tool_call: false, + temperature: false, + knowledge: "2023-10", + release_date: "2024-09-12", + last_updated: "2024-12-17", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 65536 }, + }, + "openai/gpt-4o-mini": { + id: "openai/gpt-4o-mini", + name: "GPT-4o mini", + family: "gpt-mini", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-10", + release_date: "2024-07-18", + last_updated: "2024-07-18", + modalities: { input: ["text", "image", "audio"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 16384 }, + }, + "openai/o4-mini": { + id: "openai/o4-mini", + name: "OpenAI o4-mini", + family: "o-mini", + attachment: false, + reasoning: true, + tool_call: false, + temperature: false, + knowledge: "2024-04", + release_date: "2025-01-31", + last_updated: "2025-01-31", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 200000, output: 100000 }, + }, + "openai/o1-preview": { + id: "openai/o1-preview", + name: "OpenAI o1-preview", + family: "o", + attachment: false, + reasoning: true, + tool_call: false, + temperature: false, + knowledge: "2023-10", + release_date: "2024-09-12", + last_updated: "2024-09-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 32768 }, + }, + "openai/o1": { + id: "openai/o1", + name: "OpenAI o1", + family: "o", + attachment: false, + reasoning: true, + tool_call: false, + temperature: false, + knowledge: "2023-10", + release_date: "2024-09-12", + last_updated: "2024-12-17", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 200000, output: 100000 }, + }, + "openai/o3-mini": { + id: "openai/o3-mini", + name: "OpenAI o3-mini", + family: "o-mini", + attachment: false, + reasoning: true, + tool_call: false, + temperature: false, + knowledge: "2024-04", + release_date: "2025-01-31", + last_updated: "2025-01-31", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 200000, output: 100000 }, + }, + "openai/gpt-4.1-nano": { + id: "openai/gpt-4.1-nano", + name: "GPT-4.1-nano", + family: "gpt-nano", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-04-14", + last_updated: "2025-04-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 16384 }, + }, + "openai/o3": { + id: "openai/o3", + name: "OpenAI o3", + family: "o", + attachment: false, + reasoning: true, + tool_call: false, + temperature: false, + knowledge: "2024-04", + release_date: "2025-01-31", + last_updated: "2025-01-31", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 200000, output: 100000 }, + }, + "openai/gpt-4o": { + id: "openai/gpt-4o", + name: "GPT-4o", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-10", + release_date: "2024-05-13", + last_updated: "2024-05-13", + modalities: { input: ["text", "image", "audio"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 16384 }, + }, + "openai/gpt-4.1": { + id: "openai/gpt-4.1", + name: "GPT-4.1", + family: "gpt", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-04-14", + last_updated: "2025-04-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 16384 }, + }, + "openai/gpt-4.1-mini": { + id: "openai/gpt-4.1-mini", + name: "GPT-4.1-mini", + family: "gpt-mini", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04", + release_date: "2025-04-14", + last_updated: "2025-04-14", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 16384 }, + }, + "meta/llama-4-scout-17b-16e-instruct": { + id: "meta/llama-4-scout-17b-16e-instruct", + name: "Llama 4 Scout 17B 16E Instruct", + family: "llama", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-12", + release_date: "2025-01-31", + last_updated: "2025-01-31", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 8192 }, + }, + "meta/meta-llama-3.1-8b-instruct": { + id: "meta/meta-llama-3.1-8b-instruct", + name: "Meta-Llama-3.1-8B-Instruct", + family: "llama", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 32768 }, + }, + "meta/llama-3.3-70b-instruct": { + id: "meta/llama-3.3-70b-instruct", + name: "Llama-3.3-70B-Instruct", + family: "llama", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 32768 }, + }, + "meta/meta-llama-3-70b-instruct": { + id: "meta/meta-llama-3-70b-instruct", + name: "Meta-Llama-3-70B-Instruct", + family: "llama", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-04-18", + last_updated: "2024-04-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 8192, output: 2048 }, + }, + "meta/llama-3.2-90b-vision-instruct": { + id: "meta/llama-3.2-90b-vision-instruct", + name: "Llama-3.2-90B-Vision-Instruct", + family: "llama", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-09-25", + last_updated: "2024-09-25", + modalities: { input: ["text", "image", "audio"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 8192 }, + }, + "meta/llama-3.2-11b-vision-instruct": { + id: "meta/llama-3.2-11b-vision-instruct", + name: "Llama-3.2-11B-Vision-Instruct", + family: "llama", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-09-25", + last_updated: "2024-09-25", + modalities: { input: ["text", "image", "audio"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 8192 }, + }, + "meta/meta-llama-3.1-405b-instruct": { + id: "meta/meta-llama-3.1-405b-instruct", + name: "Meta-Llama-3.1-405B-Instruct", + family: "llama", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 32768 }, + }, + "meta/meta-llama-3.1-70b-instruct": { + id: "meta/meta-llama-3.1-70b-instruct", + name: "Meta-Llama-3.1-70B-Instruct", + family: "llama", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-07-23", + last_updated: "2024-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 32768 }, + }, + "meta/meta-llama-3-8b-instruct": { + id: "meta/meta-llama-3-8b-instruct", + name: "Meta-Llama-3-8B-Instruct", + family: "llama", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-04-18", + last_updated: "2024-04-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 8192, output: 2048 }, + }, + "meta/llama-4-maverick-17b-128e-instruct-fp8": { + id: "meta/llama-4-maverick-17b-128e-instruct-fp8", + name: "Llama 4 Maverick 17B 128E Instruct FP8", + family: "llama", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-12", + release_date: "2025-01-31", + last_updated: "2025-01-31", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 8192 }, + }, + "core42/jais-30b-chat": { + id: "core42/jais-30b-chat", + name: "JAIS 30b Chat", + family: "jais", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2023-03", + release_date: "2023-08-30", + last_updated: "2023-08-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 8192, output: 2048 }, + }, + "mistral-ai/mistral-nemo": { + id: "mistral-ai/mistral-nemo", + name: "Mistral Nemo", + family: "mistral-nemo", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-03", + release_date: "2024-07-18", + last_updated: "2024-07-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 8192 }, + }, + "mistral-ai/ministral-3b": { + id: "mistral-ai/ministral-3b", + name: "Ministral 3B", + family: "ministral", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-03", + release_date: "2024-10-22", + last_updated: "2024-10-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 8192 }, + }, + "mistral-ai/mistral-large-2411": { + id: "mistral-ai/mistral-large-2411", + name: "Mistral Large 24.11", + family: "mistral-large", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-09", + release_date: "2024-11-01", + last_updated: "2024-11-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 32768 }, + }, + "mistral-ai/mistral-small-2503": { + id: "mistral-ai/mistral-small-2503", + name: "Mistral Small 3.1", + family: "mistral-small", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-09", + release_date: "2025-03-01", + last_updated: "2025-03-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 32768 }, + }, + "mistral-ai/mistral-medium-2505": { + id: "mistral-ai/mistral-medium-2505", + name: "Mistral Medium 3 (25.05)", + family: "mistral-medium", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-09", + release_date: "2025-05-01", + last_updated: "2025-05-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 128000, output: 32768 }, + }, + "mistral-ai/codestral-2501": { + id: "mistral-ai/codestral-2501", + name: "Codestral 25.01", + family: "codestral", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-03", + release_date: "2025-01-01", + last_updated: "2025-01-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 32000, output: 8192 }, + }, + }, + }, + neuralwatt: { + id: "neuralwatt", + env: ["NEURALWATT_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.neuralwatt.com/v1", + name: "Neuralwatt", + doc: "https://portal.neuralwatt.com/docs", + models: { + "glm-5-fast": { + id: "glm-5-fast", + name: "GLM 5 Fast", + family: "glm", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2026-04-07", + last_updated: "2026-04-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.1, output: 3.6 }, + limit: { context: 200000, output: 200000 }, + }, + "kimi-k2.6-fast": { + id: "kimi-k2.6-fast", + name: "Kimi K2.6 Fast", + family: "kimi", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2026-04-21", + last_updated: "2026-04-21", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.69, output: 3.22 }, + limit: { context: 262144, output: 262144 }, + }, + "qwen3.5-397b-fast": { + id: "qwen3.5-397b-fast", + name: "Qwen3.5 397B Fast", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2026-02-01", + last_updated: "2026-02-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.69, output: 4.14 }, + limit: { context: 262144, output: 262144 }, + }, + "glm-5.1-fast": { + id: "glm-5.1-fast", + name: "GLM 5.1 Fast", + family: "glm", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2026-04-07", + last_updated: "2026-04-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.1, output: 3.6 }, + limit: { context: 200000, output: 200000 }, + }, + "qwen3.6-35b-fast": { + id: "qwen3.6-35b-fast", + name: "Qwen3.6 35B Fast", + family: "qwen3.6", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2026-04-01", + last_updated: "2026-04-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.05, output: 0.1 }, + limit: { context: 131072, output: 131072 }, + }, + "kimi-k2.5-fast": { + id: "kimi-k2.5-fast", + name: "Kimi K2.5 Fast", + family: "kimi", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2026-01-27", + last_updated: "2026-01-27", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.52, output: 2.59 }, + limit: { context: 262144, output: 262144 }, + }, + "Qwen/Qwen3.5-397B-A17B-FP8": { + id: "Qwen/Qwen3.5-397B-A17B-FP8", + name: "Qwen3.5 397B A17B FP8", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-02-01", + last_updated: "2026-02-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.69, output: 4.14 }, + limit: { context: 262144, output: 262144 }, + }, + "Qwen/Qwen3.6-35B-A3B": { + id: "Qwen/Qwen3.6-35B-A3B", + name: "Qwen3.6 35B A3B", + family: "qwen3.6", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-04-01", + last_updated: "2026-04-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.05, output: 0.1 }, + limit: { context: 131072, output: 131072 }, + }, + "zai-org/GLM-5.1-FP8": { + id: "zai-org/GLM-5.1-FP8", + name: "GLM 5.1 FP8", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-04-07", + last_updated: "2026-04-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.1, output: 3.6 }, + limit: { context: 200000, output: 200000 }, + }, + "mistralai/Devstral-Small-2-24B-Instruct-2512": { + id: "mistralai/Devstral-Small-2-24B-Instruct-2512", + name: "Devstral Small 2 24B Instruct 2512", + family: "devstral", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-12-09", + last_updated: "2025-12-09", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.12, output: 0.35 }, + limit: { context: 262144, output: 262144 }, + }, + "openai/gpt-oss-20b": { + id: "openai/gpt-oss-20b", + name: "GPT OSS 20B", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.03, output: 0.16 }, + limit: { context: 16384, output: 16384 }, + }, + "moonshotai/Kimi-K2.6": { + id: "moonshotai/Kimi-K2.6", + name: "Kimi K2.6", + family: "kimi", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-04-21", + last_updated: "2026-04-21", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.69, output: 3.22 }, + limit: { context: 262144, output: 262144 }, + }, + "moonshotai/Kimi-K2.5": { + id: "moonshotai/Kimi-K2.5", + name: "Kimi K2.5", + family: "kimi", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-01-27", + last_updated: "2026-01-27", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.52, output: 2.59 }, + limit: { context: 262144, output: 262144 }, + }, + "MiniMaxAI/MiniMax-M2.5": { + id: "MiniMaxAI/MiniMax-M2.5", + name: "MiniMax M2.5", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.35, output: 1.38 }, + limit: { context: 196608, output: 196608 }, + }, + }, + }, + togetherai: { + id: "togetherai", + env: ["TOGETHER_API_KEY"], + npm: "@ai-sdk/togetherai", + name: "Together AI", + doc: "https://docs.together.ai/docs/serverless-models", + models: { + "essentialai/Rnj-1-Instruct": { + id: "essentialai/Rnj-1-Instruct", + name: "Rnj-1 Instruct", + family: "rnj", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-12-05", + last_updated: "2025-12-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.15 }, + limit: { context: 32768, output: 32768 }, + }, + "Qwen/Qwen3.5-397B-A17B": { + id: "Qwen/Qwen3.5-397B-A17B", + name: "Qwen3.5 397B A17B", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-16", + last_updated: "2026-02-16", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 3.6 }, + limit: { context: 262144, output: 130000 }, + }, + "Qwen/Qwen3.6-Plus": { + id: "Qwen/Qwen3.6-Plus", + name: "Qwen3.6 Plus", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-30", + last_updated: "2026-04-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.5, output: 3 }, + limit: { context: 1000000, output: 500000 }, + }, + "Qwen/Qwen3-Coder-Next-FP8": { + id: "Qwen/Qwen3-Coder-Next-FP8", + name: "Qwen3 Coder Next FP8", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2026-02-03", + release_date: "2026-02-03", + last_updated: "2026-02-03", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.5, output: 1.2 }, + limit: { context: 262144, output: 262144 }, + }, + "Qwen/Qwen3-235B-A22B-Instruct-2507-tput": { + id: "Qwen/Qwen3-235B-A22B-Instruct-2507-tput", + name: "Qwen3 235B A22B Instruct 2507 FP8", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-07-25", + last_updated: "2025-07-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.6 }, + limit: { context: 262144, output: 262144 }, + }, + "Qwen/Qwen3-Coder-480B-A35B-Instruct-FP8": { + id: "Qwen/Qwen3-Coder-480B-A35B-Instruct-FP8", + name: "Qwen3 Coder 480B A35B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-23", + last_updated: "2025-07-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 2, output: 2 }, + limit: { context: 262144, output: 262144 }, + }, + "zai-org/GLM-5.1": { + id: "zai-org/GLM-5.1", + name: "GLM-5.1", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-11", + release_date: "2026-04-07", + last_updated: "2026-04-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.4, output: 4.4 }, + limit: { context: 202752, output: 131072 }, + }, + "meta-llama/Llama-3.3-70B-Instruct-Turbo": { + id: "meta-llama/Llama-3.3-70B-Instruct-Turbo", + name: "Llama 3.3 70B", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-12", + release_date: "2024-12-06", + last_updated: "2024-12-06", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.88, output: 0.88 }, + limit: { context: 131072, output: 131072 }, + }, + "deepseek-ai/DeepSeek-V3": { + id: "deepseek-ai/DeepSeek-V3", + name: "DeepSeek V3", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-07", + release_date: "2025-01-20", + last_updated: "2025-05-29", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1.25, output: 1.25 }, + limit: { context: 131072, output: 131072 }, + }, + "deepseek-ai/DeepSeek-R1": { + id: "deepseek-ai/DeepSeek-R1", + name: "DeepSeek R1", + family: "deepseek-thinking", + attachment: false, + reasoning: true, + tool_call: false, + temperature: true, + knowledge: "2024-07", + release_date: "2024-12-26", + last_updated: "2025-03-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 3, output: 7 }, + limit: { context: 163839, output: 163839 }, + }, + "deepseek-ai/DeepSeek-V3-1": { + id: "deepseek-ai/DeepSeek-V3-1", + name: "DeepSeek V3.1", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-08", + release_date: "2025-08-21", + last_updated: "2025-08-21", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 1.7 }, + limit: { context: 131072, output: 131072 }, + }, + "deepseek-ai/DeepSeek-V4-Pro": { + id: "deepseek-ai/DeepSeek-V4-Pro", + name: "DeepSeek V4 Pro", + family: "deepseek", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-04-24", + last_updated: "2026-04-24", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 2.1, output: 4.4, cache_read: 0.2 }, + limit: { context: 512000, output: 384000 }, + }, + "openai/gpt-oss-120b": { + id: "openai/gpt-oss-120b", + name: "GPT OSS 120B", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-08", + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 131072, output: 131072 }, + }, + "google/gemma-4-31B-it": { + id: "google/gemma-4-31B-it", + name: "Gemma 4 31B Instruct", + family: "gemma", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-04-07", + last_updated: "2026-04-07", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.5 }, + limit: { context: 262144, output: 131072 }, + }, + "moonshotai/Kimi-K2.6": { + id: "moonshotai/Kimi-K2.6", + name: "Kimi K2.6", + family: "kimi-k2.6", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-04-21", + last_updated: "2026-04-21", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 1.2, output: 4.5, cache_read: 0.2 }, + limit: { context: 262144, output: 131000 }, + }, + "moonshotai/Kimi-K2.5": { + id: "moonshotai/Kimi-K2.5", + name: "Kimi K2.5", + family: "kimi", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: true, + temperature: true, + knowledge: "2026-01", + release_date: "2026-01-27", + last_updated: "2026-01-27", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.5, output: 2.8 }, + limit: { context: 262144, output: 262144 }, + }, + "MiniMaxAI/MiniMax-M2.5": { + id: "MiniMaxAI/MiniMax-M2.5", + name: "MiniMax-M2.5", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2, cache_read: 0.06 }, + limit: { context: 204800, output: 131072 }, + }, + "MiniMaxAI/MiniMax-M2.7": { + id: "MiniMaxAI/MiniMax-M2.7", + name: "MiniMax-M2.7", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2, cache_read: 0.06 }, + limit: { context: 202752, output: 131072 }, + }, + }, + }, + "qihang-ai": { + id: "qihang-ai", + env: ["QIHANG_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.qhaigc.net/v1", + name: "QiHang", + doc: "https://www.qhaigc.net/docs", + models: { + "claude-opus-4-5-20251101": { + id: "claude-opus-4-5-20251101", + name: "Claude Opus 4.5", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03", + release_date: "2025-11-01", + last_updated: "2025-11-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.71, output: 3.57 }, + limit: { context: 200000, output: 32000 }, + }, + "gemini-3-flash-preview": { + id: "gemini-3-flash-preview", + name: "Gemini 3 Flash Preview", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-12-17", + last_updated: "2025-12-17", + modalities: { input: ["text", "image", "video", "audio", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.07, output: 0.43, context_over_200k: { input: 0.07, output: 0.43 } }, + limit: { context: 1048576, output: 65536 }, + }, + "gpt-5-mini": { + id: "gpt-5-mini", + name: "GPT-5-Mini", + family: "gpt-mini", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-09-30", + release_date: "2025-09-15", + last_updated: "2025-09-15", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.04, output: 0.29 }, + limit: { context: 200000, output: 64000 }, + }, + "gemini-3-pro-preview": { + id: "gemini-3-pro-preview", + name: "Gemini 3 Pro Preview", + family: "gemini-pro", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-11", + release_date: "2025-11-19", + last_updated: "2025-11-19", + modalities: { input: ["text", "image", "audio", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.57, output: 3.43 }, + limit: { context: 1000000, output: 65000 }, + }, + "claude-sonnet-4-5-20250929": { + id: "claude-sonnet-4-5-20250929", + name: "Claude Sonnet 4.5", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07-31", + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.43, output: 2.14 }, + limit: { context: 200000, output: 64000 }, + }, + "gpt-5.2": { + id: "gpt-5.2", + name: "GPT-5.2", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-08-31", + release_date: "2025-12-11", + last_updated: "2025-12-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 2 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "gpt-5.2-codex": { + id: "gpt-5.2-codex", + name: "GPT-5.2 Codex", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2025-12-11", + last_updated: "2025-12-11", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.14, output: 1.14 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "gemini-2.5-flash": { + id: "gemini-2.5-flash", + name: "Gemini 2.5 Flash", + family: "gemini-flash", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2025-12-17", + last_updated: "2025-12-17", + modalities: { input: ["text", "image", "video", "audio", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.09, output: 0.71, context_over_200k: { input: 0.09, output: 0.71 } }, + limit: { context: 1048576, output: 65536 }, + }, + "claude-haiku-4-5-20251001": { + id: "claude-haiku-4-5-20251001", + name: "Claude Haiku 4.5", + family: "claude-haiku", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07-31", + release_date: "2025-10-01", + last_updated: "2025-10-01", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.14, output: 0.71 }, + limit: { context: 200000, output: 64000 }, + }, + }, + }, + "tencent-tokenhub": { + id: "tencent-tokenhub", + env: ["TENCENT_TOKENHUB_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://tokenhub.tencentmaas.com/v1", + name: "Tencent TokenHub", + doc: "https://cloud.tencent.com/document/product/1823/130050", + models: { + "hy3-preview": { + id: "hy3-preview", + name: "Hy3 preview", + family: "Hy", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-04-20", + last_updated: "2026-04-20", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 256000, output: 64000 }, + }, + }, + }, + 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-3-sonnet-20240229": { + id: "claude-3-sonnet-20240229", + name: "Claude Sonnet 3", + family: "claude-sonnet", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-08-31", + release_date: "2024-03-04", + last_updated: "2024-03-04", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 0.3 }, + limit: { context: 200000, output: 4096 }, + }, + "claude-haiku-4-5": { + id: "claude-haiku-4-5", + name: "Claude Haiku 4.5 (latest)", + family: "claude-haiku", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-02-28", + release_date: "2025-10-15", + last_updated: "2025-10-15", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 5, cache_read: 0.1, cache_write: 1.25 }, + limit: { context: 200000, output: 64000 }, + }, + "claude-opus-4-5-20251101": { + id: "claude-opus-4-5-20251101", + name: "Claude Opus 4.5", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-11-01", + last_updated: "2025-11-01", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 200000, output: 64000 }, + }, + "claude-3-opus-20240229": { + id: "claude-3-opus-20240229", + name: "Claude Opus 3", + family: "claude-opus", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-08-31", + release_date: "2024-02-29", + last_updated: "2024-02-29", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 4096 }, + }, + "claude-3-5-haiku-20241022": { + id: "claude-3-5-haiku-20241022", + name: "Claude Haiku 3.5", + family: "claude-haiku", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-07-31", + release_date: "2024-10-22", + last_updated: "2024-10-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.8, output: 4, cache_read: 0.08, cache_write: 1 }, + limit: { context: 200000, output: 8192 }, + }, + "claude-3-5-sonnet-20241022": { + id: "claude-3-5-sonnet-20241022", + name: "Claude Sonnet 3.5 v2", + family: "claude-sonnet", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04-30", + release_date: "2024-10-22", + last_updated: "2024-10-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 8192 }, + }, + "claude-sonnet-4-6": { + id: "claude-sonnet-4-6", + name: "Claude Sonnet 4.6", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: 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, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 1000000, output: 64000 }, + }, + "claude-opus-4-0": { + id: "claude-opus-4-0", + name: "Claude Opus 4 (latest)", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 32000 }, + }, + "claude-opus-4-7": { + id: "claude-opus-4-7", + name: "Claude Opus 4.7", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2026-01-31", + release_date: "2026-04-16", + last_updated: "2026-04-16", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 1000000, output: 128000 }, + }, + "claude-3-haiku-20240307": { + id: "claude-3-haiku-20240307", + name: "Claude Haiku 3", + family: "claude-haiku", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2023-08-31", + release_date: "2024-03-13", + last_updated: "2024-03-13", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.25, output: 1.25, cache_read: 0.03, cache_write: 0.3 }, + limit: { context: 200000, output: 4096 }, + }, + "claude-sonnet-4-5-20250929": { + id: "claude-sonnet-4-5-20250929", + name: "Claude Sonnet 4.5", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07-31", + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + }, + "claude-3-5-haiku-latest": { + id: "claude-3-5-haiku-latest", + name: "Claude Haiku 3.5 (latest)", + family: "claude-haiku", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-07-31", + release_date: "2024-10-22", + last_updated: "2024-10-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.8, output: 4, cache_read: 0.08, cache_write: 1 }, + limit: { context: 200000, output: 8192 }, + }, + "claude-opus-4-1": { + id: "claude-opus-4-1", + name: "Claude Opus 4.1 (latest)", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 32000 }, + }, + "claude-sonnet-4-0": { + id: "claude-sonnet-4-0", + name: "Claude Sonnet 4 (latest)", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + }, + "claude-3-5-sonnet-20240620": { + id: "claude-3-5-sonnet-20240620", + name: "Claude Sonnet 3.5", + family: "claude-sonnet", + attachment: true, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2024-04-30", + release_date: "2024-06-20", + last_updated: "2024-06-20", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 8192 }, + }, + "claude-opus-4-5": { + id: "claude-opus-4-5", + name: "Claude Opus 4.5 (latest)", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-11-24", + last_updated: "2025-11-24", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 200000, output: 64000 }, + }, + "claude-opus-4-1-20250805": { + id: "claude-opus-4-1-20250805", + name: "Claude Opus 4.1", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 32000 }, + }, + "claude-haiku-4-5-20251001": { + id: "claude-haiku-4-5-20251001", + name: "Claude Haiku 4.5", + family: "claude-haiku", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-02-28", + release_date: "2025-10-15", + last_updated: "2025-10-15", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 5, cache_read: 0.1, cache_write: 1.25 }, + limit: { context: 200000, output: 64000 }, + }, + "claude-sonnet-4-20250514": { + id: "claude-sonnet-4-20250514", + name: "Claude Sonnet 4", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + }, + "claude-opus-4-6": { + id: "claude-opus-4-6", + name: "Claude Opus 4.6", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-05-31", + release_date: "2026-02-05", + last_updated: "2026-03-13", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 25, cache_read: 0.5, cache_write: 6.25 }, + limit: { context: 1000000, output: 128000 }, + experimental: { + modes: { + fast: { + cost: { input: 30, output: 150, cache_read: 3, cache_write: 37.5 }, + provider: { body: { speed: "fast" }, headers: { "anthropic-beta": "fast-mode-2026-02-01" } }, + }, + }, + }, + }, + "claude-3-7-sonnet-20250219": { + id: "claude-3-7-sonnet-20250219", + name: "Claude Sonnet 3.7", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10-31", + release_date: "2025-02-19", + last_updated: "2025-02-19", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + }, + "claude-sonnet-4-5": { + id: "claude-sonnet-4-5", + name: "Claude Sonnet 4.5 (latest)", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07-31", + release_date: "2025-09-29", + last_updated: "2025-09-29", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 3, output: 15, cache_read: 0.3, cache_write: 3.75 }, + limit: { context: 200000, output: 64000 }, + }, + "claude-opus-4-20250514": { + id: "claude-opus-4-20250514", + name: "Claude Opus 4", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2025-05-22", + last_updated: "2025-05-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 15, output: 75, cache_read: 1.5, cache_write: 18.75 }, + limit: { context: 200000, output: 32000 }, + }, + }, + }, + modelscope: { + id: "modelscope", + env: ["MODELSCOPE_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api-inference.modelscope.cn/v1", + name: "ModelScope", + doc: "https://modelscope.cn/docs/model-service/API-Inference/intro", + models: { + "Qwen/Qwen3-30B-A3B-Thinking-2507": { + id: "Qwen/Qwen3-30B-A3B-Thinking-2507", + name: "Qwen3 30B A3B Thinking 2507", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-30", + last_updated: "2025-07-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 262144, output: 32768 }, + }, + "Qwen/Qwen3-30B-A3B-Instruct-2507": { + id: "Qwen/Qwen3-30B-A3B-Instruct-2507", + name: "Qwen3 30B A3B Instruct 2507", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-30", + last_updated: "2025-07-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 262144, output: 16384 }, + }, + "Qwen/Qwen3-235B-A22B-Instruct-2507": { + id: "Qwen/Qwen3-235B-A22B-Instruct-2507", + name: "Qwen3 235B A22B Instruct 2507", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-04-28", + last_updated: "2025-07-21", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 262144, output: 131072 }, + }, + "Qwen/Qwen3-Coder-30B-A3B-Instruct": { + id: "Qwen/Qwen3-Coder-30B-A3B-Instruct", + name: "Qwen3 Coder 30B A3B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-31", + last_updated: "2025-07-31", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 262144, output: 65536 }, + }, + "Qwen/Qwen3-235B-A22B-Thinking-2507": { + id: "Qwen/Qwen3-235B-A22B-Thinking-2507", + name: "Qwen3-235B-A22B-Thinking-2507", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-25", + last_updated: "2025-07-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 262144, output: 131072 }, + }, + "ZhipuAI/GLM-4.5": { + id: "ZhipuAI/GLM-4.5", + name: "GLM-4.5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-28", + last_updated: "2025-07-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 131072, output: 98304 }, + }, + "ZhipuAI/GLM-4.6": { + id: "ZhipuAI/GLM-4.6", + name: "GLM-4.6", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07", + release_date: "2025-09-30", + last_updated: "2025-09-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 202752, output: 98304 }, + }, + }, + }, + "hpc-ai": { + id: "hpc-ai", + env: ["HPC_AI_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.hpc-ai.com/inference/v1", + name: "HPC-AI", + doc: "https://www.hpc-ai.com/doc/docs/quickstart/", + models: { + "zai-org/glm-5.1": { + id: "zai-org/glm-5.1", + name: "GLM 5.1", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-04-08", + last_updated: "2026-04-08", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.66, output: 2, cache_read: 0.12 }, + limit: { context: 202000, output: 202000 }, + }, + "minimax/minimax-m2.5": { + id: "minimax/minimax-m2.5", + name: "MiniMax M2.5", + family: "minimax-m2.5", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: false, + temperature: true, + release_date: "2026-02-12", + last_updated: "2026-03-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.14, output: 0.56, cache_read: 0.014 }, + limit: { context: 1000000, output: 131072 }, + }, + "moonshotai/kimi-k2.5": { + id: "moonshotai/kimi-k2.5", + name: "Kimi K2.5", + family: "kimi", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: false, + knowledge: "2025-01-01", + release_date: "2026-01-01", + last_updated: "2026-03-25", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.21, output: 1, cache_read: 0.03 }, + limit: { context: 262144, output: 262144 }, + }, + }, + }, + gitlab: { + id: "gitlab", + env: ["GITLAB_TOKEN"], + npm: "gitlab-ai-provider", + name: "GitLab Duo", + doc: "https://docs.gitlab.com/user/duo_agent_platform/", + models: { + "duo-chat-gpt-5-4-nano": { + id: "duo-chat-gpt-5-4-nano", + name: "Agentic Chat (GPT-5.4 Nano)", + family: "gpt-nano", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-17", + last_updated: "2026-03-17", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "duo-chat-gpt-5-mini": { + id: "duo-chat-gpt-5-mini", + name: "Agentic Chat (GPT-5 Mini)", + family: "gpt-mini", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-05-30", + release_date: "2026-01-22", + last_updated: "2026-01-22", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "duo-chat-sonnet-4-6": { + id: "duo-chat-sonnet-4-6", + name: "Agentic Chat (Claude Sonnet 4.6)", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-08-31", + release_date: "2026-02-17", + last_updated: "2026-02-17", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 1000000, output: 64000 }, + }, + "duo-chat-gpt-5-2": { + id: "duo-chat-gpt-5-2", + name: "Agentic Chat (GPT-5.2)", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-01-23", + last_updated: "2026-01-23", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "duo-chat-gpt-5-codex": { + id: "duo-chat-gpt-5-codex", + name: "Agentic Chat (GPT-5 Codex)", + family: "gpt-codex", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2026-01-22", + last_updated: "2026-01-22", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "duo-chat-gpt-5-1": { + id: "duo-chat-gpt-5-1", + name: "Agentic Chat (GPT-5.1)", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2024-09-30", + release_date: "2026-01-22", + last_updated: "2026-01-22", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "duo-chat-gpt-5-2-codex": { + id: "duo-chat-gpt-5-2-codex", + name: "Agentic Chat (GPT-5.2 Codex)", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-01-22", + last_updated: "2026-01-22", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "duo-chat-sonnet-4-5": { + id: "duo-chat-sonnet-4-5", + name: "Agentic Chat (Claude Sonnet 4.5)", + family: "claude-sonnet", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-07-31", + release_date: "2026-01-08", + last_updated: "2026-01-08", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 200000, output: 64000 }, + }, + "duo-chat-gpt-5-4": { + id: "duo-chat-gpt-5-4", + name: "Agentic Chat (GPT-5.4)", + family: "gpt", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-05", + last_updated: "2026-03-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 1050000, input: 922000, output: 128000 }, + }, + "duo-chat-haiku-4-5": { + id: "duo-chat-haiku-4-5", + name: "Agentic Chat (Claude Haiku 4.5)", + family: "claude-haiku", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-02-28", + release_date: "2026-01-08", + last_updated: "2026-01-08", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 200000, output: 64000 }, + }, + "duo-chat-gpt-5-3-codex": { + id: "duo-chat-gpt-5-3-codex", + name: "Agentic Chat (GPT-5.3 Codex)", + family: "gpt-codex", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-02-05", + last_updated: "2026-02-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "duo-chat-gpt-5-4-mini": { + id: "duo-chat-gpt-5-4-mini", + name: "Agentic Chat (GPT-5.4 Mini)", + family: "gpt-mini", + attachment: true, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: false, + knowledge: "2025-08-31", + release_date: "2026-03-17", + last_updated: "2026-03-17", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0 }, + limit: { context: 400000, input: 272000, output: 128000 }, + }, + "duo-chat-opus-4-7": { + id: "duo-chat-opus-4-7", + name: "Agentic Chat (Claude Opus 4.7)", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: false, + knowledge: "2026-01-31", + release_date: "2026-04-16", + last_updated: "2026-04-16", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 1000000, output: 64000 }, + }, + "duo-chat-opus-4-5": { + id: "duo-chat-opus-4-5", + name: "Agentic Chat (Claude Opus 4.5)", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-03-31", + release_date: "2026-01-08", + last_updated: "2026-01-08", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 200000, output: 64000 }, + }, + "duo-chat-opus-4-6": { + id: "duo-chat-opus-4-6", + name: "Agentic Chat (Claude Opus 4.6)", + family: "claude-opus", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-05-31", + release_date: "2026-02-05", + last_updated: "2026-02-05", + modalities: { input: ["text", "image", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 1000000, output: 64000 }, + }, + }, + }, + xiaomi: { + id: "xiaomi", + env: ["XIAOMI_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.xiaomimimo.com/v1", + name: "Xiaomi", + doc: "https://platform.xiaomimimo.com/#/docs", + models: { + "mimo-v2.5-pro": { + id: "mimo-v2.5-pro", + name: "MiMo-V2.5-Pro", + family: "mimo", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12", + release_date: "2026-04-22", + last_updated: "2026-04-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 3, cache_read: 0.2, context_over_200k: { input: 2, output: 6, cache_read: 0.4 } }, + limit: { context: 1048576, output: 131072 }, + }, + "mimo-v2-omni": { + id: "mimo-v2-omni", + name: "MiMo-V2-Omni", + family: "mimo", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12", + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0.4, output: 2, cache_read: 0.08 }, + limit: { context: 262144, output: 131072 }, + }, + "mimo-v2.5": { + id: "mimo-v2.5", + name: "MiMo-V2.5", + family: "mimo", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12", + release_date: "2026-04-22", + last_updated: "2026-04-22", + modalities: { input: ["text", "image", "audio", "video"], output: ["text"] }, + open_weights: true, + cost: { + input: 0.4, + output: 2, + cache_read: 0.08, + context_over_200k: { input: 0.8, output: 4, cache_read: 0.16 }, + }, + limit: { context: 1048576, output: 131072 }, + }, + "mimo-v2-pro": { + id: "mimo-v2-pro", + name: "MiMo-V2-Pro", + family: "mimo", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12", + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 3, cache_read: 0.2, context_over_200k: { input: 2, output: 6, cache_read: 0.4 } }, + limit: { context: 1048576, output: 131072 }, + }, + "mimo-v2-flash": { + id: "mimo-v2-flash", + name: "MiMo-V2-Flash", + family: "mimo", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12-01", + release_date: "2025-12-16", + last_updated: "2026-02-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.3, cache_read: 0.01 }, + limit: { context: 262144, output: 65536 }, + }, + }, + }, + clarifai: { + id: "clarifai", + env: ["CLARIFAI_PAT"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.clarifai.com/v2/ext/openai/v1", + name: "Clarifai", + doc: "https://docs.clarifai.com/compute/inference/", + models: { + "arcee_ai/AFM/models/trinity-mini": { + id: "arcee_ai/AFM/models/trinity-mini", + name: "Trinity Mini", + family: "trinity-mini", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2024-10", + release_date: "2025-12", + last_updated: "2026-02-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.045, output: 0.15 }, + limit: { context: 131072, output: 131072 }, + }, + "mistralai/completion/models/Ministral-3-14B-Reasoning-2512": { + id: "mistralai/completion/models/Ministral-3-14B-Reasoning-2512", + name: "Ministral 3 14B Reasoning 2512", + family: "ministral", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-12", + release_date: "2025-12-01", + last_updated: "2025-12-12", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 2.5, output: 1.7 }, + limit: { context: 262144, output: 262144 }, + }, + "mistralai/completion/models/Ministral-3-3B-Reasoning-2512": { + id: "mistralai/completion/models/Ministral-3-3B-Reasoning-2512", + name: "Ministral 3 3B Reasoning 2512", + family: "ministral", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-12", + last_updated: "2026-02-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 1.039, output: 0.54825 }, + limit: { context: 262144, output: 262144 }, + }, + "deepseek-ai/deepseek-ocr/models/DeepSeek-OCR": { + id: "deepseek-ai/deepseek-ocr/models/DeepSeek-OCR", + name: "DeepSeek OCR", + family: "deepseek", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-10-20", + last_updated: "2026-02-25", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 0.7 }, + limit: { context: 8192, output: 8192 }, + }, + "openai/chat-completion/models/gpt-oss-20b": { + id: "openai/chat-completion/models/gpt-oss-20b", + name: "GPT OSS 20B", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-12-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.045, output: 0.18 }, + limit: { context: 131072, output: 16384 }, + }, + "openai/chat-completion/models/gpt-oss-120b-high-throughput": { + id: "openai/chat-completion/models/gpt-oss-120b-high-throughput", + name: "GPT OSS 120B High Throughput", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-05", + last_updated: "2026-02-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.09, output: 0.36 }, + limit: { context: 131072, output: 16384 }, + }, + "minimaxai/chat-completion/models/MiniMax-M2_5-high-throughput": { + id: "minimaxai/chat-completion/models/MiniMax-M2_5-high-throughput", + name: "MiniMax-M2.5 High Throughput", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-12", + last_updated: "2026-02-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 204800, output: 131072 }, + }, + "qwen/qwenCoder/models/Qwen3-Coder-30B-A3B-Instruct": { + id: "qwen/qwenCoder/models/Qwen3-Coder-30B-A3B-Instruct", + name: "Qwen3 Coder 30B A3B Instruct", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-31", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.11458, output: 0.74812 }, + limit: { context: 262144, output: 65536 }, + }, + "qwen/qwenLM/models/Qwen3-30B-A3B-Thinking-2507": { + id: "qwen/qwenLM/models/Qwen3-30B-A3B-Thinking-2507", + name: "Qwen3 30B A3B Thinking 2507", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-07-31", + last_updated: "2026-02-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.36, output: 1.3 }, + limit: { context: 262144, output: 131072 }, + }, + "qwen/qwenLM/models/Qwen3-30B-A3B-Instruct-2507": { + id: "qwen/qwenLM/models/Qwen3-30B-A3B-Instruct-2507", + name: "Qwen3 30B A3B Instruct 2507", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: true, + structured_output: true, + temperature: true, + release_date: "2025-07-30", + last_updated: "2026-02-25", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 0.5 }, + limit: { context: 262144, output: 262144 }, + }, + "clarifai/main/models/mm-poly-8b": { + id: "clarifai/main/models/mm-poly-8b", + name: "MM Poly 8B", + family: "mm-poly", + attachment: true, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2025-06", + last_updated: "2026-02-25", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: false, + cost: { input: 0.658, output: 1.11 }, + limit: { context: 32768, output: 4096 }, + }, + "moonshotai/chat-completion/models/Kimi-K2_6": { + id: "moonshotai/chat-completion/models/Kimi-K2_6", + name: "Kimi K2.6", + family: "kimi-k2.6", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + knowledge: "2025-01", + release_date: "2026-04-21", + last_updated: "2026-04-21", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.95, output: 4 }, + limit: { context: 262144, output: 262144 }, + }, + }, + }, + "minimax-cn": { + id: "minimax-cn", + env: ["MINIMAX_API_KEY"], + npm: "@ai-sdk/anthropic", + api: "https://api.minimaxi.com/anthropic/v1", + name: "MiniMax (minimaxi.com)", + doc: "https://platform.minimaxi.com/docs/guides/quickstart", + models: { + "MiniMax-M2": { + id: "MiniMax-M2", + name: "MiniMax-M2", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-10-27", + last_updated: "2025-10-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 196608, output: 128000 }, + }, + "MiniMax-M2.5": { + id: "MiniMax-M2.5", + name: "MiniMax-M2.5", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-12", + last_updated: "2026-02-12", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2, cache_read: 0.03, cache_write: 0.375 }, + limit: { context: 204800, output: 131072 }, + }, + "MiniMax-M2.7": { + id: "MiniMax-M2.7", + name: "MiniMax-M2.7", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2, cache_read: 0.06, cache_write: 0.375 }, + limit: { context: 204800, output: 131072 }, + }, + "MiniMax-M2.7-highspeed": { + id: "MiniMax-M2.7-highspeed", + name: "MiniMax-M2.7-highspeed", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.4, cache_read: 0.06, cache_write: 0.375 }, + limit: { context: 204800, output: 131072 }, + }, + "MiniMax-M2.1": { + id: "MiniMax-M2.1", + name: "MiniMax-M2.1", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-12-23", + last_updated: "2025-12-23", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 204800, output: 131072 }, + }, + "MiniMax-M2.5-highspeed": { + id: "MiniMax-M2.5-highspeed", + name: "MiniMax-M2.5-highspeed", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-13", + last_updated: "2026-02-13", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.4, cache_read: 0.06, cache_write: 0.375 }, + limit: { context: 204800, output: 131072 }, + }, + }, + }, + "regolo-ai": { + id: "regolo-ai", + env: ["REGOLO_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.regolo.ai/v1", + name: "Regolo AI", + doc: "https://docs.regolo.ai/", + models: { + "mistral-small3.2": { + id: "mistral-small3.2", + name: "Mistral Small 3.2", + family: "mistral-small", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-01-31", + last_updated: "2025-01-31", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.5, output: 2.2 }, + limit: { context: 120000, output: 120000 }, + }, + "qwen3-embedding-8b": { + id: "qwen3-embedding-8b", + name: "Qwen3-Embedding-8B", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2026-02-01", + last_updated: "2026-02-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.1, output: 0.1 }, + limit: { context: 32768, output: 8192 }, + }, + "llama-3.3-70b-instruct": { + id: "llama-3.3-70b-instruct", + name: "Llama 3.3 70B Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-04-28", + last_updated: "2025-04-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.6, output: 2.7 }, + limit: { context: 128000, output: 16384 }, + }, + "qwen3-reranker-4b": { + id: "qwen3-reranker-4b", + name: "Qwen3-Reranker-4B", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + temperature: false, + release_date: "2026-02-01", + last_updated: "2026-02-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.12, output: 0.12 }, + limit: { context: 32768, output: 8192 }, + }, + "mistral-small-4-119b": { + id: "mistral-small-4-119b", + name: "Mistral Small 4 119B", + family: "mistral-small", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-15", + last_updated: "2026-03-15", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: false, + cost: { input: 0.75, output: 3 }, + limit: { context: 256000, output: 16384 }, + }, + "qwen3.5-122b": { + id: "qwen3.5-122b", + name: "Qwen3.5-122B", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-01", + last_updated: "2026-02-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.9, output: 3.6 }, + limit: { context: 262144, output: 16384 }, + }, + "qwen-image": { + id: "qwen-image", + name: "Qwen-Image", + family: "qwen", + attachment: false, + reasoning: false, + tool_call: false, + temperature: true, + release_date: "2026-03-01", + last_updated: "2026-03-01", + modalities: { input: ["text"], output: ["image"] }, + open_weights: false, + cost: { input: 0.5, output: 2 }, + limit: { context: 8192, output: 4096 }, + }, + "qwen3-coder-next": { + id: "qwen3-coder-next", + name: "Qwen3-Coder-Next", + family: "qwen", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-01", + last_updated: "2026-03-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 1.2 }, + limit: { context: 262144, output: 16384 }, + }, + "minimax-m2.5": { + id: "minimax-m2.5", + name: "MiniMax 2.5", + family: "minimax", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-10", + last_updated: "2026-03-10", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.8, output: 3.5 }, + limit: { context: 190000, output: 64000 }, + }, + "gpt-oss-20b": { + id: "gpt-oss-20b", + name: "GPT-OSS-20B", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-03-01", + last_updated: "2026-03-01", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.4, output: 1.8 }, + limit: { context: 128000, output: 16384 }, + }, + "qwen3.5-9b": { + id: "qwen3.5-9b", + name: "Qwen3.5-9B", + family: "qwen", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2026-02-01", + last_updated: "2026-02-01", + modalities: { input: ["text", "image"], output: ["text"] }, + open_weights: true, + cost: { input: 0.15, output: 0.6 }, + limit: { context: 262144, output: 8192 }, + }, + "gpt-oss-120b": { + id: "gpt-oss-120b", + name: "GPT-OSS-120B", + family: "gpt-oss", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-08-05", + last_updated: "2025-08-05", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 1, output: 4.2 }, + limit: { context: 128000, output: 16384 }, + }, + "llama-3.1-8b-instruct": { + id: "llama-3.1-8b-instruct", + name: "Llama 3.1 8B Instruct", + family: "llama", + attachment: false, + reasoning: false, + tool_call: true, + temperature: true, + release_date: "2025-04-07", + last_updated: "2025-04-07", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0.05, output: 0.25 }, + limit: { context: 120000, output: 120000 }, + }, + }, + }, + "xiaomi-token-plan-ams": { + id: "xiaomi-token-plan-ams", + env: ["XIAOMI_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://token-plan-ams.xiaomimimo.com/v1", + name: "Xiaomi Token Plan (Europe)", + doc: "https://platform.xiaomimimo.com/#/docs", + models: { + "mimo-v2-tts": { + id: "mimo-v2-tts", + name: "MiMo-V2-TTS", + family: "mimo", + attachment: false, + reasoning: false, + tool_call: false, + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["audio"] }, + open_weights: true, + cost: { input: 0, output: 0 }, + limit: { context: 8192, output: 16384 }, + }, + "mimo-v2-flash": { + id: "mimo-v2-flash", + name: "MiMo-V2-Flash", + family: "mimo", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12-01", + release_date: "2025-12-16", + last_updated: "2026-02-04", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0 }, + limit: { context: 262144, output: 65536 }, + }, + "mimo-v2-pro": { + id: "mimo-v2-pro", + name: "MiMo-V2-Pro", + family: "mimo", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12", + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0, cache_read: 0, context_over_200k: { input: 2, output: 6, cache_read: 0.4 } }, + limit: { context: 1048576, output: 131072 }, + }, + "mimo-v2.5": { + id: "mimo-v2.5", + name: "MiMo-V2.5", + family: "mimo", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12", + release_date: "2026-04-22", + last_updated: "2026-04-22", + modalities: { input: ["text", "image", "audio", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, context_over_200k: { input: 0, output: 0, cache_read: 0 } }, + limit: { context: 1048576, output: 131072 }, + }, + "mimo-v2-omni": { + id: "mimo-v2-omni", + name: "MiMo-V2-Omni", + family: "mimo", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12", + release_date: "2026-03-18", + last_updated: "2026-03-18", + modalities: { input: ["text", "image", "audio", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0, cache_read: 0 }, + limit: { context: 262144, output: 131072 }, + }, + "mimo-v2.5-pro": { + id: "mimo-v2.5-pro", + name: "MiMo-V2.5-Pro", + family: "mimo", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2024-12", + release_date: "2026-04-22", + last_updated: "2026-04-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, context_over_200k: { input: 0, output: 0, cache_read: 0 } }, + limit: { context: 1048576, output: 131072 }, + }, + }, + }, + zhipuai: { + id: "zhipuai", + env: ["ZHIPU_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://open.bigmodel.cn/api/paas/v4", + name: "Zhipu AI", + doc: "https://docs.z.ai/guides/overview/pricing", + models: { + "glm-5v-turbo": { + id: "glm-5v-turbo", + name: "GLM-5V-Turbo", + family: "glm", + attachment: true, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-04-01", + last_updated: "2026-04-01", + modalities: { input: ["text", "image", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 5, output: 22, cache_read: 1.2, cache_write: 0 }, + limit: { context: 200000, output: 131072 }, + }, + "glm-5": { + id: "glm-5", + name: "GLM-5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + release_date: "2026-02-11", + last_updated: "2026-02-11", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 1, output: 3.2, cache_read: 0.2, cache_write: 0 }, + limit: { context: 204800, output: 131072 }, + }, + "glm-5.1": { + id: "glm-5.1", + name: "GLM-5.1", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + structured_output: true, + temperature: true, + release_date: "2026-03-27", + last_updated: "2026-03-27", + modalities: { input: ["text"], output: ["text"] }, + open_weights: false, + cost: { input: 6, output: 24, cache_read: 1.3, cache_write: 0 }, + limit: { context: 200000, output: 131072 }, + }, + "glm-4.7-flash": { + id: "glm-4.7-flash", + name: "GLM-4.7-Flash", + family: "glm-flash", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-01-19", + last_updated: "2026-01-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 200000, output: 131072 }, + }, + "glm-4.5-flash": { + id: "glm-4.5-flash", + name: "GLM-4.5-Flash", + family: "glm-flash", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-28", + last_updated: "2025-07-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 }, + limit: { context: 131072, output: 98304 }, + }, + "glm-4.6v": { + id: "glm-4.6v", + name: "GLM-4.6V", + family: "glm", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-12-08", + last_updated: "2025-12-08", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.3, output: 0.9 }, + limit: { context: 128000, output: 32768 }, + }, + "glm-4.6": { + id: "glm-4.6", + name: "GLM-4.6", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-09-30", + last_updated: "2025-09-30", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.2, cache_read: 0.11, cache_write: 0 }, + limit: { context: 204800, output: 131072 }, + }, + "glm-4.5v": { + id: "glm-4.5v", + name: "GLM-4.5V", + family: "glm", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-08-11", + last_updated: "2025-08-11", + modalities: { input: ["text", "image", "video"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 1.8 }, + limit: { context: 64000, output: 16384 }, + }, + "glm-4.5-air": { + id: "glm-4.5-air", + name: "GLM-4.5-Air", + family: "glm-air", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-28", + last_updated: "2025-07-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.2, output: 1.1, cache_read: 0.03, cache_write: 0 }, + limit: { context: 131072, output: 98304 }, + }, + "glm-4.5": { + id: "glm-4.5", + name: "GLM-4.5", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2025-07-28", + last_updated: "2025-07-28", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.2, cache_read: 0.11, cache_write: 0 }, + limit: { context: 131072, output: 98304 }, + }, + "glm-4.7-flashx": { + id: "glm-4.7-flashx", + name: "GLM-4.7-FlashX", + family: "glm-flash", + attachment: false, + reasoning: true, + tool_call: true, + temperature: true, + knowledge: "2025-04", + release_date: "2026-01-19", + last_updated: "2026-01-19", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.07, output: 0.4, cache_read: 0.01, cache_write: 0 }, + limit: { context: 200000, output: 131072 }, + }, + "glm-4.7": { + id: "glm-4.7", + name: "GLM-4.7", + family: "glm", + attachment: false, + reasoning: true, + tool_call: true, + interleaved: { field: "reasoning_content" }, + temperature: true, + knowledge: "2025-04", + release_date: "2025-12-22", + last_updated: "2025-12-22", + modalities: { input: ["text"], output: ["text"] }, + open_weights: true, + cost: { input: 0.6, output: 2.2, cache_read: 0.11, cache_write: 0 }, + limit: { context: 204800, output: 131072 }, + }, + }, + }, + nova: { + id: "nova", + env: ["NOVA_API_KEY"], + npm: "@ai-sdk/openai-compatible", + api: "https://api.nova.amazon.com/v1", + name: "Nova", + doc: "https://nova.amazon.com/dev/documentation", + models: { + "nova-2-lite-v1": { + id: "nova-2-lite-v1", + name: "Nova 2 Lite", + family: "nova-lite", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-12-01", + last_updated: "2025-12-01", + modalities: { input: ["text", "image", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0, reasoning: 0 }, + limit: { context: 1000000, output: 64000 }, + }, + "nova-2-pro-v1": { + id: "nova-2-pro-v1", + name: "Nova 2 Pro", + family: "nova-pro", + attachment: true, + reasoning: true, + tool_call: true, + temperature: true, + release_date: "2025-12-03", + last_updated: "2026-01-03", + modalities: { input: ["text", "image", "video", "pdf"], output: ["text"] }, + open_weights: false, + cost: { input: 0, output: 0, reasoning: 0 }, + limit: { context: 1000000, output: 64000 }, + }, + }, + }, +} diff --git a/packages/core/src/models.ts b/packages/core/src/models.ts new file mode 100644 index 00000000000..89ec7ead863 --- /dev/null +++ b/packages/core/src/models.ts @@ -0,0 +1,234 @@ +import path from "path" +import { Context, Duration, Effect, Layer, Option, Schedule, Schema } from "effect" +import { FetchHttpClient, HttpClient, HttpClientRequest } from "effect/unstable/http" +import { Global } from "./global" +import { Flag } from "./flag/flag" +import { Flock } from "./util/flock" +import { Hash } from "./util/hash" +import { AppFileSystem } from "./filesystem" +import { InstallationChannel, InstallationVersion } from "./installation/version" +import * as ModelsRefresh from "./kilocode/models-refresh" // kilocode_change + +export const CatalogModelStatus = Schema.Literals(["alpha", "beta", "deprecated"]) +export type CatalogModelStatus = typeof CatalogModelStatus.Type + +const USER_AGENT = `opencode/${InstallationChannel}/${InstallationVersion}/${Flag.KILO_CLIENT}` + +const CostTier = Schema.Struct({ + input: Schema.Finite, + output: Schema.Finite, + cache_read: Schema.optional(Schema.Finite), + cache_write: Schema.optional(Schema.Finite), + tier: Schema.Struct({ + type: Schema.Literal("context"), + size: Schema.Finite, + }), +}) + +const Cost = Schema.Struct({ + input: Schema.Finite, + output: Schema.Finite, + cache_read: Schema.optional(Schema.Finite), + cache_write: Schema.optional(Schema.Finite), + tiers: Schema.optional(Schema.Array(CostTier)), + context_over_200k: Schema.optional( + Schema.Struct({ + input: Schema.Finite, + output: Schema.Finite, + cache_read: Schema.optional(Schema.Finite), + cache_write: Schema.optional(Schema.Finite), + }), + ), +}) + +export const Model = Schema.Struct({ + id: Schema.String, + name: Schema.String, + family: Schema.optional(Schema.String), + release_date: Schema.String, + attachment: Schema.Boolean, + reasoning: Schema.Boolean, + temperature: Schema.Boolean, + tool_call: Schema.Boolean, + interleaved: Schema.optional( + Schema.Union([ + Schema.Literal(true), + Schema.Struct({ + field: Schema.Literals(["reasoning_content", "reasoning_details"]), + }), + ]), + ), + cost: Schema.optional(Cost), + limit: Schema.Struct({ + context: Schema.Finite, + input: Schema.optional(Schema.Finite), + output: Schema.Finite, + }), + modalities: Schema.optional( + Schema.Struct({ + input: Schema.Array(Schema.Literals(["text", "audio", "image", "video", "pdf"])), + output: Schema.Array(Schema.Literals(["text", "audio", "image", "video", "pdf"])), + }), + ), + // kilocode_change start - preserve Kilo catalog metadata + recommendedIndex: Schema.optional(Schema.Finite), + prompt: Schema.optional(Schema.String), + isFree: Schema.optional(Schema.Boolean), + ai_sdk_provider: Schema.optional(Schema.String), + // kilocode_change end + experimental: Schema.optional( + Schema.Struct({ + modes: Schema.optional( + Schema.Record( + Schema.String, + Schema.Struct({ + cost: Schema.optional(Cost), + provider: Schema.optional( + Schema.Struct({ + body: Schema.optional(Schema.Record(Schema.String, Schema.MutableJson)), + headers: Schema.optional(Schema.Record(Schema.String, Schema.String)), + }), + ), + }), + ), + ), + }), + ), + status: Schema.optional(CatalogModelStatus), + provider: Schema.optional( + Schema.Struct({ npm: Schema.optional(Schema.String), api: Schema.optional(Schema.String) }), + ), +}) +export type Model = Schema.Schema.Type + +export const Provider = Schema.Struct({ + api: Schema.optional(Schema.String), + name: Schema.String, + env: Schema.Array(Schema.String), + id: Schema.String, + npm: Schema.optional(Schema.String), + models: Schema.Record(Schema.String, Model), +}) + +export type Provider = Schema.Schema.Type + +export interface Interface { + readonly get: () => Effect.Effect> + readonly refresh: (force?: boolean) => Effect.Effect +} + +export class Service extends Context.Service()("@opencode/ModelsDev") {} + +type Requirements = AppFileSystem.Service | HttpClient.HttpClient + +export const layer: Layer.Layer = Layer.effect( + Service, + Effect.gen(function* () { + const fs = yield* AppFileSystem.Service + const http = HttpClient.filterStatusOk( + (yield* HttpClient.HttpClient).pipe( + HttpClient.retryTransient({ + retryOn: "errors-and-responses", + times: 2, + schedule: Schedule.exponential(200).pipe(Schedule.jittered), + }), + ), + ) + + const source = Flag.KILO_MODELS_URL || "https://models.dev" + const filepath = path.join( + Global.Path.cache, + source === "https://models.dev" ? "models.json" : `models-${Hash.fast(source)}.json`, + ) + const ttl = Duration.minutes(5) + const lockKey = `models-dev:${filepath}` + + const fresh = Effect.fnUntraced(function* () { + const stat = yield* fs.stat(filepath).pipe(Effect.catch(() => Effect.succeed(undefined))) + if (!stat) return false + const mtime = Option.getOrElse(stat.mtime, () => new Date(0)).getTime() + return Date.now() - mtime < Duration.toMillis(ttl) + }) + + const fetchApi = Effect.fn("ModelsDev.fetchApi")(function* () { + return yield* HttpClientRequest.get(`${source}/api.json`).pipe( + HttpClientRequest.setHeader("User-Agent", USER_AGENT), + http.execute, + Effect.flatMap((res) => res.text), + Effect.timeout("10 seconds"), + ) + }) + + const loadFromDisk = fs.readJson(Flag.KILO_MODELS_PATH ?? filepath).pipe( + Effect.catch(() => Effect.succeed(undefined)), + Effect.map((v) => v as Record | undefined), + ) + + // Bundled at build time; absent in dev — `tryPromise` covers both. + const loadSnapshot = Effect.tryPromise({ + // @ts-ignore — generated at build time, may not exist in dev + try: () => import("./models-snapshot.js").then((m) => m.snapshot as Record | undefined), + catch: () => undefined, + }).pipe(Effect.catch(() => Effect.succeed(undefined))) + + const fetchAndWrite = Effect.fn("ModelsDev.fetchAndWrite")(function* () { + const text = yield* fetchApi() + yield* fs.writeWithDirs(filepath, text) + return text + }) + + const populate = Effect.gen(function* () { + const fromDisk = yield* loadFromDisk + if (fromDisk) return fromDisk + const snapshot = yield* loadSnapshot + if (snapshot) return snapshot + if (Flag.KILO_DISABLE_MODELS_FETCH) return {} + // Flock is cross-process: concurrent opencode CLIs can race on this cache file. + const text = yield* Effect.scoped( + Effect.gen(function* () { + yield* Flock.effect(lockKey) + return yield* fetchAndWrite() + }), + ) + return JSON.parse(text) as Record + }).pipe(Effect.withSpan("ModelsDev.populate"), Effect.orDie) + + const [cachedGet, invalidate] = yield* Effect.cachedInvalidateWithTTL(populate, Duration.infinity) + + const get = (): Effect.Effect> => cachedGet + + const refresh = Effect.fn("ModelsDev.refresh")(function* (force = false) { + if (!force && (yield* fresh())) return + yield* Effect.scoped( + Effect.gen(function* () { + yield* Flock.effect(lockKey) + // Re-check under the lock: another process may have refreshed between + // our outer check and lock acquisition. + if (!force && (yield* fresh())) return + yield* fetchAndWrite() + yield* invalidate + yield* ModelsRefresh.notify() // kilocode_change + }), + ).pipe( + Effect.tapCause((cause) => + Effect.logError("Failed to fetch models.dev").pipe(Effect.annotateLogs("cause", cause)), + ), + Effect.ignore, + ) + }) + + if (!Flag.KILO_DISABLE_MODELS_FETCH && !process.argv.includes("--get-yargs-completions")) { + // Schedule.spaced runs the effect once, then waits between completions. + yield* Effect.forkScoped(refresh().pipe(Effect.repeat(Schedule.spaced("60 minutes")), Effect.ignore)) + } + + return Service.of({ get, refresh }) + }), +) + +export const defaultLayer: Layer.Layer = layer.pipe( + Layer.provide(FetchHttpClient.layer), + Layer.provide(AppFileSystem.defaultLayer), +) + +export * as ModelsDev from "./models" diff --git a/packages/core/src/plugin.ts b/packages/core/src/plugin.ts new file mode 100644 index 00000000000..dfcae946859 --- /dev/null +++ b/packages/core/src/plugin.ts @@ -0,0 +1,146 @@ +export * as PluginV2 from "./plugin" + +import { createDraft, finishDraft, type Draft } from "immer" +import type { LanguageModelV3 } from "@ai-sdk/provider" +import { type ProviderV2 } from "./provider" +import { Context, Effect, Layer, Schema } from "effect" +import type { ModelV2 } from "./model" + +export const ID = Schema.String.pipe(Schema.brand("Plugin.ID")) +export type ID = typeof ID.Type + +type HookSpec = { + "provider.update": { + input: {} + output: { + provider: ProviderV2.Info + cancel: boolean + } + } + "model.update": { + input: {} + output: { + model: ModelV2.Info + cancel: boolean + } + } + "aisdk.language": { + input: { + model: ModelV2.Info + sdk: any + options: Record + } + output: { + language?: LanguageModelV3 + } + } + "aisdk.sdk": { + input: { + model: ModelV2.Info + package: string + options: Record + } + output: { + sdk?: any + } + } +} + +export type Hooks = { + [Name in keyof HookSpec]: Readonly & { + -readonly [Field in keyof HookSpec[Name]["output"]]: HookSpec[Name]["output"][Field] extends object + ? Draft + : HookSpec[Name]["output"][Field] + } +} + +export type HookFunctions = { + [key in keyof Hooks]?: (input: Hooks[key]) => Effect.Effect +} + +export type HookInput = HookSpec[Name]["input"] +export type HookOutput = HookSpec[Name]["output"] + +export type Effect = Effect.Effect + +export function define(input: { id: ID; effect: Effect.Effect }) { + return input +} + +export interface Interface { + readonly add: (input: { id: ID; effect: Effect }) => Effect.Effect + readonly remove: (id: ID) => Effect.Effect + readonly trigger: ( + name: Name, + input: HookInput, + output: HookOutput, + ) => Effect.Effect & HookOutput> +} + +export class Service extends Context.Service()("@opencode/v2/Plugin") {} + +export const layer = Layer.effect( + Service, + Effect.gen(function* () { + let hooks: { + id: ID + hooks: HookFunctions + }[] = [] + + const svc = Service.of({ + add: Effect.fn("Plugin.add")(function* (input) { + const result = yield* input.effect + if (!result) return + hooks = [ + ...hooks.filter((item) => item.id !== input.id), + { + id: input.id, + hooks: result, + }, + ] + }), + trigger: Effect.fn("Plugin.trigger")(function* (name, input, output) { + const draftEntries = new Map>() + const event = { + ...input, + ...output, + } as Record + + for (const [field, value] of Object.entries(output)) { + if (value && typeof value === "object") { + draftEntries.set(field, createDraft(value)) + event[field] = draftEntries.get(field) + } + } + + for (const item of hooks) { + const match = item.hooks[name] + if (!match) continue + yield* match(event as any).pipe( + Effect.withSpan(`Plugin.hook.${name}`, { + attributes: { + plugin: item.id, + hook: name, + }, + }), + ) + } + + for (const [field, draft] of draftEntries) { + event[field] = finishDraft(draft) + } + + return event as any + }), + remove: Effect.fn("Plugin.remove")(function* (id) { + hooks = hooks.filter((item) => item.id !== id) + }), + }) + return svc + }), +) + +export const defaultLayer = layer + +// opencode +// sdcok diff --git a/packages/core/src/plugin/auth.ts b/packages/core/src/plugin/auth.ts new file mode 100644 index 00000000000..503d82852cc --- /dev/null +++ b/packages/core/src/plugin/auth.ts @@ -0,0 +1,30 @@ +import { Effect } from "effect" +import { AuthV2 } from "../auth" +import { PluginV2 } from "../plugin" + +export const AuthPlugin = PluginV2.define({ + id: PluginV2.ID.make("auth"), + effect: Effect.gen(function* () { + const auth = yield* AuthV2.Service + return { + "provider.update": Effect.fn(function* (evt) { + const account = yield* auth.active(AuthV2.ServiceID.make(evt.provider.id)).pipe(Effect.orDie) + if (!account) return + evt.provider.enabled = { + via: "auth", + service: account.serviceID, + } + if (account.credential.type === "api") { + evt.provider.options.aisdk.provider.apiKey = account.credential.key + Object.assign(evt.provider.options.aisdk.provider, account.credential.metadata ?? {}) + } + if (account.credential.type === "oauth") { + evt.provider.options.aisdk.provider.apiKey = account.credential.access + if (evt.provider.id === "kilo" && account.credential.accountId) { + evt.provider.options.aisdk.provider.kilocodeOrganizationId = account.credential.accountId // kilocode_change + } + } + }), + } + }), +}) diff --git a/packages/core/src/plugin/boot.ts b/packages/core/src/plugin/boot.ts new file mode 100644 index 00000000000..74560ac85b7 --- /dev/null +++ b/packages/core/src/plugin/boot.ts @@ -0,0 +1,71 @@ +export * as PluginBoot from "./boot" + +import { Context, Deferred, Effect, Layer } from "effect" +import { AuthV2 } from "../auth" +import { Catalog } from "../catalog" +import { Npm } from "../npm" +import { PluginV2 } from "../plugin" +import { AuthPlugin } from "./auth" +import { EnvPlugin } from "./env" +import { ModelsDevPlugin } from "./models-dev" +import { ProviderPlugins } from "./provider" + +type Plugin = { + id: PluginV2.ID + effect: Effect.Effect +} + +export interface Interface { + readonly wait: () => Effect.Effect +} + +export class Service extends Context.Service()("@opencode/v2/PluginBoot") {} + +export const layer: Layer.Layer = + Layer.effect( + Service, + Effect.gen(function* () { + const catalog = yield* Catalog.Service + const plugin = yield* PluginV2.Service + const auth = yield* AuthV2.Service + const npm = yield* Npm.Service + const done = yield* Deferred.make() + + const add = Effect.fn("PluginBoot.add")(function* (input: Plugin) { + yield* plugin.add({ + id: input.id, + effect: input.effect.pipe( + Effect.provideService(Catalog.Service, catalog), + Effect.provideService(AuthV2.Service, auth), + Effect.provideService(Npm.Service, npm), + ), + }) + }) + + const boot = Effect.gen(function* () { + yield* add(EnvPlugin) + yield* add(AuthPlugin) + for (const item of ProviderPlugins) { + yield* add(item) + } + yield* add(ModelsDevPlugin) + }).pipe(Effect.withSpan("PluginBoot.boot")) + + yield* boot.pipe( + Effect.exit, + Effect.flatMap((exit) => Deferred.done(done, exit)), + Effect.forkScoped, + ) + + return Service.of({ + wait: () => Deferred.await(done), + }) + }), + ) + +export const defaultLayer = layer.pipe( + Layer.provide(Catalog.defaultLayer), + Layer.provide(PluginV2.defaultLayer), + Layer.provide(Layer.orDie(AuthV2.defaultLayer)), + Layer.provide(Npm.defaultLayer), +) diff --git a/packages/core/src/plugin/env.ts b/packages/core/src/plugin/env.ts new file mode 100644 index 00000000000..d63936fa13d --- /dev/null +++ b/packages/core/src/plugin/env.ts @@ -0,0 +1,18 @@ +import { Effect } from "effect" +import { PluginV2 } from "../plugin" + +export const EnvPlugin = PluginV2.define({ + id: PluginV2.ID.make("env"), + effect: Effect.gen(function* () { + return { + "provider.update": Effect.fn(function* (evt) { + const key = evt.provider.env.find((item) => process.env[item]) + if (!key) return + evt.provider.enabled = { + via: "env", + name: key, + } + }), + } + }), +}) diff --git a/packages/core/src/plugin/layer-map.example.ts b/packages/core/src/plugin/layer-map.example.ts new file mode 100644 index 00000000000..63e33d3f0c4 --- /dev/null +++ b/packages/core/src/plugin/layer-map.example.ts @@ -0,0 +1,94 @@ +export * as LayerMapExample from "./layer-map.example" + +import { Context, Effect, Layer, LayerMap } from "effect" +import { Npm } from "../npm" + +/** + * Tutorial: split global services from context-specific services. + * + * Use this pattern when part of the app should be constructed once at the app edge, + * while another part should be cached per request/project/workspace key. + * + * In this example: + * - Npm.Service is the global service. It is not keyed by request context and should + * be provided once by the application runtime. + * - ConfigService is context-specific. It is built from a RequestContext key and is + * cached by LayerMap for that key. + * - ConfigServiceMap.layer owns the cache. Provide it once globally, then each + * request can provide ConfigServiceMap.get(context) to select the right instance. + * + * Lifetime model: + * - ConfigServiceMap.layer has the app/global lifetime and depends on Npm.Service. + * - ConfigServiceMap.get(context) has the request/context lifetime and provides + * ConfigService for exactly that context key. + * - The cached ConfigService entry stays alive while something is using it. Once idle, + * it remains cached for idleTimeToLive, then its scope is finalized. + * - invalidate(context) removes the cache entry for future lookups. Active users keep + * running on the old instance; the next lookup can create a fresh instance. + * + * Key model: + * - Keys can be strings, structs, classes, arrays, etc. + * - Prefer primitive or immutable keys. Effect uses Hash / Equal semantics for cache + * lookup, so mutating an object after it has been used as a key is a bug. + */ + +export type RequestContext = { + readonly directory: string + readonly workspace: string +} + +export class RequestContextRef extends Context.Service()( + "@opencode/example/RequestContextRef", +) {} + +export interface ConfigServiceShape { + readonly directory: string + readonly workspace: string + readonly nextUse: () => Effect.Effect + readonly which: Npm.Interface["which"] +} + +export class ConfigService extends Context.Service()( + "@opencode/example/ConfigService", +) {} + +const configServiceLayer = Layer.effect( + ConfigService, + Effect.gen(function* () { + const context = yield* RequestContextRef + const npm = yield* Npm.Service + + let useCount = 0 + + return ConfigService.of({ + directory: context.directory, + workspace: context.workspace, + nextUse: () => Effect.succeed(++useCount), + which: npm.which, + }) + }), +) + +export class ConfigServiceMap extends LayerMap.Service()("@opencode/example/ConfigServiceMap", { + lookup: (context: RequestContext) => + configServiceLayer.pipe(Layer.provide(Layer.succeed(RequestContextRef, RequestContextRef.of(context)))), + idleTimeToLive: "5 minutes", +}) {} + +export const appLayer = ConfigServiceMap.layer + +export const readConfig = Effect.fn("LayerMapExample.readConfig")(function* () { + const config = yield* ConfigService + + return { + directory: config.directory, + workspace: config.workspace, + useCount: yield* config.nextUse(), + } +}) + +export const handleRequest = Effect.fn("LayerMapExample.handleRequest")(function* (context: RequestContext) { + return yield* readConfig().pipe(Effect.provide(ConfigServiceMap.get(context))) +}) + +export const invalidateContext = (context: RequestContext) => ConfigServiceMap.invalidate(context) diff --git a/packages/core/src/plugin/models-dev.ts b/packages/core/src/plugin/models-dev.ts new file mode 100644 index 00000000000..e67c2e75a98 --- /dev/null +++ b/packages/core/src/plugin/models-dev.ts @@ -0,0 +1,108 @@ +import { DateTime, Effect } from "effect" +import { Catalog } from "../catalog" +import { ModelV2 } from "../model" +import { ModelsDev } from "../models" +import { PluginV2 } from "../plugin" +import { ProviderV2 } from "../provider" + +function released(date: string) { + const time = Date.parse(date) + return DateTime.makeUnsafe(Number.isFinite(time) ? time : 0) +} + +function cost(input: ModelsDev.Model["cost"]) { + const base = { + input: input?.input ?? 0, + output: input?.output ?? 0, + cache: { + read: input?.cache_read ?? 0, + write: input?.cache_write ?? 0, + }, + } + if (!input?.context_over_200k) return [base] + return [ + base, + { + tier: { + type: "context" as const, + size: 200_000, + }, + input: input.context_over_200k.input, + output: input.context_over_200k.output, + cache: { + read: input.context_over_200k.cache_read ?? 0, + write: input.context_over_200k.cache_write ?? 0, + }, + }, + ] +} + +function variants(model: ModelsDev.Model) { + return Object.entries(model.experimental?.modes ?? {}).map(([id, item]) => ({ + id: ModelV2.VariantID.make(id), + headers: { ...(item.provider?.headers ?? {}) }, + body: { ...(item.provider?.body ?? {}) }, + aisdk: { + provider: {}, + request: {}, + }, + })) +} + +export const ModelsDevPlugin = PluginV2.define({ + id: PluginV2.ID.make("models-dev"), + effect: Effect.gen(function* () { + const catalog = yield* Catalog.Service + const modelsDev = yield* ModelsDev.Service + for (const item of Object.values(yield* modelsDev.get())) { + const providerID = ProviderV2.ID.make(item.id) + yield* catalog.provider.update(providerID, (provider) => { + provider.name = item.name + provider.env = [...item.env] + provider.endpoint = item.npm + ? { + type: "aisdk", + package: item.npm, + url: item.api, + } + : { + type: "unknown", + } + }) + + for (const model of Object.values(item.models)) { + const modelID = ModelV2.ID.make(model.id) + yield* catalog.model + .update(providerID, modelID, (draft) => { + draft.name = model.name + draft.family = model.family ? ModelV2.Family.make(model.family) : undefined + draft.endpoint = model.provider?.npm + ? { + type: "aisdk", + package: model.provider?.npm, + url: model.provider.api, + } + : { + type: "unknown", + } + draft.capabilities = { + tools: model.tool_call, + input: [...(model.modalities?.input ?? [])], + output: [...(model.modalities?.output ?? [])], + } + draft.variants = variants(model) + draft.time.released = released(model.release_date) + draft.cost = cost(model.cost) + draft.status = model.status ?? "active" + draft.enabled = true + draft.limit = { + context: model.limit.context, + input: model.limit.input, + output: model.limit.output, + } + }) + .pipe(Effect.orDie) + } + } + }).pipe(Effect.provide(ModelsDev.defaultLayer)), +}) diff --git a/packages/core/src/plugin/provider.ts b/packages/core/src/plugin/provider.ts new file mode 100644 index 00000000000..1880787495f --- /dev/null +++ b/packages/core/src/plugin/provider.ts @@ -0,0 +1 @@ +export { ProviderPlugins } from "./provider/index" diff --git a/packages/core/src/plugin/provider/alibaba.ts b/packages/core/src/plugin/provider/alibaba.ts new file mode 100644 index 00000000000..fa5c0a91cfb --- /dev/null +++ b/packages/core/src/plugin/provider/alibaba.ts @@ -0,0 +1,15 @@ +import { Effect } from "effect" +import { PluginV2 } from "../../plugin" + +export const AlibabaPlugin = PluginV2.define({ + id: PluginV2.ID.make("alibaba"), + effect: Effect.gen(function* () { + return { + "aisdk.sdk": Effect.fn(function* (evt) { + if (evt.package !== "@ai-sdk/alibaba") return + const mod = yield* Effect.promise(() => import("@ai-sdk/alibaba")) + evt.sdk = mod.createAlibaba(evt.options) + }), + } + }), +}) diff --git a/packages/core/src/plugin/provider/amazon-bedrock.ts b/packages/core/src/plugin/provider/amazon-bedrock.ts new file mode 100644 index 00000000000..366548a0a32 --- /dev/null +++ b/packages/core/src/plugin/provider/amazon-bedrock.ts @@ -0,0 +1,94 @@ +import { Effect } from "effect" +import { PluginV2 } from "../../plugin" +import { ProviderV2 } from "../../provider" + +// Bedrock cross-region inference profiles require regional prefixes only for +// specific model/region combinations. Keep the mapping narrow and avoid +// double-prefixing model IDs that models.dev already marks as global/us/eu/etc. +function resolveModelID(modelID: string, region: string | undefined) { + const crossRegionPrefixes = ["global.", "us.", "eu.", "jp.", "apac.", "au."] + if (crossRegionPrefixes.some((prefix) => modelID.startsWith(prefix))) return modelID + + const resolvedRegion = region ?? "us-east-1" + const regionPrefix = resolvedRegion.split("-")[0] + if (regionPrefix === "us") { + const requiresPrefix = ["nova-micro", "nova-lite", "nova-pro", "nova-premier", "nova-2", "claude", "deepseek"].some( + (item) => modelID.includes(item), + ) + if (requiresPrefix && !resolvedRegion.startsWith("us-gov")) return `${regionPrefix}.${modelID}` + return modelID + } + if (regionPrefix === "eu") { + const regionRequiresPrefix = [ + "eu-west-1", + "eu-west-2", + "eu-west-3", + "eu-north-1", + "eu-central-1", + "eu-south-1", + "eu-south-2", + ].some((item) => resolvedRegion.includes(item)) + const modelRequiresPrefix = ["claude", "nova-lite", "nova-micro", "llama3", "pixtral"].some((item) => + modelID.includes(item), + ) + return regionRequiresPrefix && modelRequiresPrefix ? `${regionPrefix}.${modelID}` : modelID + } + if (regionPrefix !== "ap") return modelID + + const australia = ["ap-southeast-2", "ap-southeast-4"].includes(resolvedRegion) + if (australia && ["anthropic.claude-sonnet-4-5", "anthropic.claude-haiku"].some((item) => modelID.includes(item))) { + return `au.${modelID}` + } + + const prefix = resolvedRegion === "ap-northeast-1" ? "jp" : "apac" + return ["claude", "nova-lite", "nova-micro", "nova-pro"].some((item) => modelID.includes(item)) + ? `${prefix}.${modelID}` + : modelID +} + +export const AmazonBedrockPlugin = PluginV2.define({ + id: PluginV2.ID.make("amazon-bedrock"), + effect: Effect.gen(function* () { + return { + "provider.update": Effect.fn(function* (evt) { + if (evt.provider.id !== ProviderV2.ID.amazonBedrock) return + if (evt.provider.endpoint.type !== "aisdk") return + if (typeof evt.provider.options.aisdk.provider.endpoint !== "string") return + // The AI SDK expects a base URL, but users configure Bedrock private/VPC + // endpoints as `endpoint`; move it into the catalog endpoint URL once. + evt.provider.endpoint.url = evt.provider.options.aisdk.provider.endpoint + delete evt.provider.options.aisdk.provider.endpoint + }), + "aisdk.sdk": Effect.fn(function* (evt) { + if (evt.package !== "@ai-sdk/amazon-bedrock") return + const options = { ...evt.options } + const profile = typeof options.profile === "string" ? options.profile : process.env.AWS_PROFILE + const region = typeof options.region === "string" ? options.region : (process.env.AWS_REGION ?? "us-east-1") + const bearerToken = + process.env.AWS_BEARER_TOKEN_BEDROCK ?? + (typeof options.bearerToken === "string" ? options.bearerToken : undefined) + if (bearerToken && !process.env.AWS_BEARER_TOKEN_BEDROCK) process.env.AWS_BEARER_TOKEN_BEDROCK = bearerToken + const containerCreds = Boolean( + process.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI || process.env.AWS_CONTAINER_CREDENTIALS_FULL_URI, + ) + + options.region = region + if (typeof options.endpoint === "string") options.baseURL = options.endpoint + if (!bearerToken && options.credentialProvider === undefined) { + // Do not gate SDK creation on explicit AWS env vars. The default chain + // also handles ~/.aws/credentials, SSO, process creds, and instance roles. + const { fromNodeProviderChain } = yield* Effect.promise(() => import("@aws-sdk/credential-providers")) + options.credentialProvider = fromNodeProviderChain(profile ? { profile } : {}) + } + + const mod = yield* Effect.promise(() => import("@ai-sdk/amazon-bedrock")) + evt.sdk = mod.createAmazonBedrock(options) + }), + "aisdk.language": Effect.fn(function* (evt) { + if (evt.model.providerID !== ProviderV2.ID.amazonBedrock) return + const region = typeof evt.options.region === "string" ? evt.options.region : process.env.AWS_REGION + evt.language = evt.sdk.languageModel(resolveModelID(evt.model.apiID, region)) + }), + } + }), +}) diff --git a/packages/core/src/plugin/provider/anthropic.ts b/packages/core/src/plugin/provider/anthropic.ts new file mode 100644 index 00000000000..14851c4a319 --- /dev/null +++ b/packages/core/src/plugin/provider/anthropic.ts @@ -0,0 +1,21 @@ +import { Effect } from "effect" +import { PluginV2 } from "../../plugin" +import { ProviderV2 } from "../../provider" + +export const AnthropicPlugin = PluginV2.define({ + id: PluginV2.ID.make("anthropic"), + effect: Effect.gen(function* () { + return { + "provider.update": Effect.fn(function* (evt) { + if (evt.provider.id !== ProviderV2.ID.anthropic) return + evt.provider.options.headers["anthropic-beta"] = + "interleaved-thinking-2025-05-14,fine-grained-tool-streaming-2025-05-14" + }), + "aisdk.sdk": Effect.fn(function* (evt) { + if (evt.package !== "@ai-sdk/anthropic") return + const mod = yield* Effect.promise(() => import("@ai-sdk/anthropic")) + evt.sdk = mod.createAnthropic(evt.options) + }), + } + }), +}) diff --git a/packages/core/src/plugin/provider/azure.ts b/packages/core/src/plugin/provider/azure.ts new file mode 100644 index 00000000000..6c29a161034 --- /dev/null +++ b/packages/core/src/plugin/provider/azure.ts @@ -0,0 +1,64 @@ +import { Effect } from "effect" +import { PluginV2 } from "../../plugin" +import { ProviderV2 } from "../../provider" + +function selectLanguage(sdk: any, modelID: string, useChat: boolean) { + if (useChat && sdk.chat) return sdk.chat(modelID) + if (sdk.responses) return sdk.responses(modelID) + if (sdk.messages) return sdk.messages(modelID) + if (sdk.chat) return sdk.chat(modelID) + return sdk.languageModel(modelID) +} + +export const AzurePlugin = PluginV2.define({ + id: PluginV2.ID.make("azure"), + effect: Effect.gen(function* () { + return { + "provider.update": Effect.fn(function* (evt) { + if (evt.provider.id !== ProviderV2.ID.azure) return + const configured = evt.provider.options.aisdk.provider.resourceName + const resourceName = + typeof configured === "string" && configured.trim() !== "" ? configured : process.env.AZURE_RESOURCE_NAME + if (resourceName) evt.provider.options.aisdk.provider.resourceName = resourceName + }), + "aisdk.sdk": Effect.fn(function* (evt) { + if (evt.package !== "@ai-sdk/azure") return + if (evt.model.providerID === ProviderV2.ID.azure) { + if ( + !evt.options.resourceName && + !evt.options.baseURL && + (evt.model.endpoint.type !== "aisdk" || !evt.model.endpoint.url) + ) { + throw new Error( + "AZURE_RESOURCE_NAME is missing, set it using env var or reconnecting the azure provider and setting it", + ) + } + } + const mod = yield* Effect.promise(() => import("@ai-sdk/azure")) + evt.sdk = mod.createAzure(evt.options) + }), + "aisdk.language": Effect.fn(function* (evt) { + if (evt.model.providerID !== ProviderV2.ID.azure) return + evt.language = selectLanguage(evt.sdk, evt.model.apiID, Boolean(evt.options.useCompletionUrls)) + }), + } + }), +}) + +export const AzureCognitiveServicesPlugin = PluginV2.define({ + id: PluginV2.ID.make("azure-cognitive-services"), + effect: Effect.gen(function* () { + return { + "provider.update": Effect.fn(function* (evt) { + if (evt.provider.id !== ProviderV2.ID.make("azure-cognitive-services")) return + const resourceName = process.env.AZURE_COGNITIVE_SERVICES_RESOURCE_NAME + if (resourceName) + evt.provider.options.aisdk.provider.baseURL = `https://${resourceName}.cognitiveservices.azure.com/openai` + }), + "aisdk.language": Effect.fn(function* (evt) { + if (evt.model.providerID !== ProviderV2.ID.make("azure-cognitive-services")) return + evt.language = selectLanguage(evt.sdk, evt.model.apiID, Boolean(evt.options.useCompletionUrls)) + }), + } + }), +}) diff --git a/packages/core/src/plugin/provider/cerebras.ts b/packages/core/src/plugin/provider/cerebras.ts new file mode 100644 index 00000000000..b2fadd8bf11 --- /dev/null +++ b/packages/core/src/plugin/provider/cerebras.ts @@ -0,0 +1,20 @@ +import { Effect } from "effect" +import { PluginV2 } from "../../plugin" +import { ProviderV2 } from "../../provider" + +export const CerebrasPlugin = PluginV2.define({ + id: PluginV2.ID.make("cerebras"), + effect: Effect.gen(function* () { + return { + "provider.update": Effect.fn(function* (evt) { + if (evt.provider.id !== ProviderV2.ID.make("cerebras")) return + evt.provider.options.headers["X-Cerebras-3rd-Party-Integration"] = "opencode" + }), + "aisdk.sdk": Effect.fn(function* (evt) { + if (evt.package !== "@ai-sdk/cerebras") return + const mod = yield* Effect.promise(() => import("@ai-sdk/cerebras")) + evt.sdk = mod.createCerebras(evt.options) + }), + } + }), +}) diff --git a/packages/core/src/plugin/provider/cloudflare-ai-gateway.ts b/packages/core/src/plugin/provider/cloudflare-ai-gateway.ts new file mode 100644 index 00000000000..ffcd4adcf46 --- /dev/null +++ b/packages/core/src/plugin/provider/cloudflare-ai-gateway.ts @@ -0,0 +1,81 @@ +import os from "os" +import { InstallationVersion } from "../../installation/version" +import { Effect, Option, Schema } from "effect" +import { PluginV2 } from "../../plugin" + +export const CloudflareAIGatewayPlugin = PluginV2.define({ + id: PluginV2.ID.make("cloudflare-ai-gateway"), + effect: Effect.gen(function* () { + return { + "aisdk.sdk": Effect.fn(function* (evt) { + if (evt.package !== "ai-gateway-provider") return + if (evt.options.baseURL) return + + const config = gatewayConfig(evt.options) + if (!config) return + const metadata = gatewayMetadata(evt.options) + const { createAiGateway } = yield* Effect.promise(() => import("ai-gateway-provider")).pipe(Effect.orDie) + const { createUnified } = yield* Effect.promise(() => import("ai-gateway-provider/providers/unified")).pipe( + Effect.orDie, + ) + const gateway = createAiGateway({ + accountId: config.accountId, + gateway: config.gatewayId, + apiKey: config.apiKey, + options: gatewayOptions(evt.options, metadata), + } as any) + const unified = createUnified() + evt.sdk = { + languageModel(modelID: string) { + return gateway(unified(modelID)) + }, + } + }), + } + }), +}) + +type GatewayConfig = { + accountId: string + gatewayId: string + apiKey: string +} + +const decodeJson = Schema.decodeUnknownOption(Schema.UnknownFromJsonString) + +function gatewayConfig(options: Record): GatewayConfig | undefined { + const accountId = process.env.CLOUDFLARE_ACCOUNT_ID ?? stringOption(options, "accountId") + // AuthPlugin copies CLI prompt metadata into options. The prompt stores the + // gateway as gatewayId, while older config examples may use gateway. + const gatewayId = + process.env.CLOUDFLARE_GATEWAY_ID ?? stringOption(options, "gatewayId") ?? stringOption(options, "gateway") + const apiKey = process.env.CLOUDFLARE_API_TOKEN ?? process.env.CF_AIG_TOKEN ?? stringOption(options, "apiKey") + if (!accountId || !gatewayId || !apiKey) return undefined + + return { accountId, gatewayId, apiKey } +} + +function gatewayMetadata(options: Record) { + // Preserve the legacy cf-aig-metadata header escape hatch for gateway logging + // metadata, but prefer the typed metadata option when present. + if (options.metadata !== undefined) return options.metadata + const raw = (options.headers as Record | undefined)?.["cf-aig-metadata"] + return raw ? Option.getOrUndefined(decodeJson(raw)) : undefined +} + +function gatewayOptions(options: Record, metadata: unknown) { + return { + metadata, + cacheTtl: options.cacheTtl, + cacheKey: options.cacheKey, + skipCache: options.skipCache, + collectLog: options.collectLog, + headers: { + "User-Agent": `opencode/${InstallationVersion} cloudflare-ai-gateway (${os.platform()} ${os.release()}; ${os.arch()})`, + }, + } +} + +function stringOption(options: Record, key: string) { + return typeof options[key] === "string" ? options[key] : undefined +} diff --git a/packages/core/src/plugin/provider/cloudflare-workers-ai.ts b/packages/core/src/plugin/provider/cloudflare-workers-ai.ts new file mode 100644 index 00000000000..f39869b57d7 --- /dev/null +++ b/packages/core/src/plugin/provider/cloudflare-workers-ai.ts @@ -0,0 +1,69 @@ +import os from "os" +import { InstallationVersion } from "../../installation/version" +import { Effect } from "effect" +import { PluginV2 } from "../../plugin" +import { ProviderV2 } from "../../provider" + +const providerID = ProviderV2.ID.make("cloudflare-workers-ai") + +export const CloudflareWorkersAIPlugin = PluginV2.define({ + id: PluginV2.ID.make("cloudflare-workers-ai"), + effect: Effect.gen(function* () { + return { + "provider.update": Effect.fn(function* (evt) { + if (evt.provider.id !== providerID) return + if (evt.provider.endpoint.type !== "aisdk") return + if (evt.provider.endpoint.url) return + + const accountId = resolveAccountId(evt.provider.options.aisdk.provider) + if (accountId) evt.provider.endpoint.url = workersEndpoint(accountId) + }), + "aisdk.sdk": Effect.fn(function* (evt) { + if (evt.model.providerID !== providerID) return + if (evt.package !== "@ai-sdk/openai-compatible") return + + if (!hasWorkersEndpoint(evt.model.endpoint)) return + const mod = yield* Effect.promise(() => import("@ai-sdk/openai-compatible")) + evt.sdk = mod.createOpenAICompatible(sdkOptions(evt.options) as any) + }), + "aisdk.language": Effect.fn(function* (evt) { + if (evt.model.providerID !== providerID) return + evt.language = evt.sdk.languageModel(evt.model.apiID) + }), + } + }), +}) + +function resolveAccountId(options: Record) { + return process.env.CLOUDFLARE_ACCOUNT_ID ?? stringOption(options, "accountId") +} + +function workersEndpoint(accountId: string) { + return `https://api.cloudflare.com/client/v4/accounts/${accountId}/ai/v1` +} + +function hasWorkersEndpoint(endpoint: ProviderV2.Endpoint) { + return endpoint.type === "aisdk" && Boolean(endpoint.url) +} + +function sdkOptions(options: Record) { + return { + ...options, + baseURL: expandAccountId(options.baseURL), + apiKey: process.env.CLOUDFLARE_API_KEY ?? options.apiKey, + headers: { + "User-Agent": `opencode/${InstallationVersion} cloudflare-workers-ai (${os.platform()} ${os.release()}; ${os.arch()})`, + ...options.headers, + }, + name: providerID, + } +} + +function expandAccountId(baseURL: unknown) { + if (typeof baseURL !== "string") return baseURL + return baseURL.replaceAll("${CLOUDFLARE_ACCOUNT_ID}", process.env.CLOUDFLARE_ACCOUNT_ID ?? "${CLOUDFLARE_ACCOUNT_ID}") +} + +function stringOption(options: Record, key: string) { + return typeof options[key] === "string" ? options[key] : undefined +} diff --git a/packages/core/src/plugin/provider/cohere.ts b/packages/core/src/plugin/provider/cohere.ts new file mode 100644 index 00000000000..991c370d175 --- /dev/null +++ b/packages/core/src/plugin/provider/cohere.ts @@ -0,0 +1,15 @@ +import { Effect } from "effect" +import { PluginV2 } from "../../plugin" + +export const CoherePlugin = PluginV2.define({ + id: PluginV2.ID.make("cohere"), + effect: Effect.gen(function* () { + return { + "aisdk.sdk": Effect.fn(function* (evt) { + if (evt.package !== "@ai-sdk/cohere") return + const mod = yield* Effect.promise(() => import("@ai-sdk/cohere")) + evt.sdk = mod.createCohere(evt.options) + }), + } + }), +}) diff --git a/packages/core/src/plugin/provider/deepinfra.ts b/packages/core/src/plugin/provider/deepinfra.ts new file mode 100644 index 00000000000..bbd42f6e283 --- /dev/null +++ b/packages/core/src/plugin/provider/deepinfra.ts @@ -0,0 +1,15 @@ +import { Effect } from "effect" +import { PluginV2 } from "../../plugin" + +export const DeepInfraPlugin = PluginV2.define({ + id: PluginV2.ID.make("deepinfra"), + effect: Effect.gen(function* () { + return { + "aisdk.sdk": Effect.fn(function* (evt) { + if (evt.package !== "@ai-sdk/deepinfra") return + const mod = yield* Effect.promise(() => import("@ai-sdk/deepinfra")) + evt.sdk = mod.createDeepInfra(evt.options) + }), + } + }), +}) diff --git a/packages/core/src/plugin/provider/dynamic.ts b/packages/core/src/plugin/provider/dynamic.ts new file mode 100644 index 00000000000..e5abc7009e3 --- /dev/null +++ b/packages/core/src/plugin/provider/dynamic.ts @@ -0,0 +1,31 @@ +import { Npm } from "../../npm" +import { Effect, Option } from "effect" +import { pathToFileURL } from "url" +import { PluginV2 } from "../../plugin" + +export const DynamicProviderPlugin = PluginV2.define({ + id: PluginV2.ID.make("dynamic-provider"), + effect: Effect.gen(function* () { + const npm = yield* Npm.Service + return { + "aisdk.sdk": Effect.fn(function* (evt) { + if (evt.sdk) return + + const installedPath = evt.package.startsWith("file://") + ? evt.package + : Option.getOrUndefined((yield* npm.add(evt.package).pipe(Effect.orDie)).entrypoint) + if (!installedPath) throw new Error(`Package ${evt.package} has no import entrypoint`) + + const mod = yield* Effect.promise(async () => { + return (await import( + installedPath.startsWith("file://") ? installedPath : pathToFileURL(installedPath).href + )) as Record any> + }).pipe(Effect.orDie) + const match = Object.keys(mod).find((name) => name.startsWith("create")) + if (!match) throw new Error(`Package ${evt.package} has no provider factory export`) + + evt.sdk = mod[match](evt.options) + }), + } + }), +}) diff --git a/packages/core/src/plugin/provider/gateway.ts b/packages/core/src/plugin/provider/gateway.ts new file mode 100644 index 00000000000..5b08ad9ef5e --- /dev/null +++ b/packages/core/src/plugin/provider/gateway.ts @@ -0,0 +1,15 @@ +import { Effect } from "effect" +import { PluginV2 } from "../../plugin" + +export const GatewayPlugin = PluginV2.define({ + id: PluginV2.ID.make("gateway"), + effect: Effect.gen(function* () { + return { + "aisdk.sdk": Effect.fn(function* (evt) { + if (evt.package !== "@ai-sdk/gateway") return + const mod = yield* Effect.promise(() => import("@ai-sdk/gateway")) + evt.sdk = mod.createGateway(evt.options) + }), + } + }), +}) diff --git a/packages/core/src/plugin/provider/github-copilot.ts b/packages/core/src/plugin/provider/github-copilot.ts new file mode 100644 index 00000000000..31e57ba12ab --- /dev/null +++ b/packages/core/src/plugin/provider/github-copilot.ts @@ -0,0 +1,44 @@ +import { Effect } from "effect" +import { ModelV2 } from "../../model" +import { PluginV2 } from "../../plugin" +import { ProviderV2 } from "../../provider" + +function shouldUseResponses(modelID: string) { + // Copilot supports Responses for GPT-5 class models, except mini variants + // which still need the chat-completions endpoint. + const match = /^gpt-(\d+)/.exec(modelID) + if (!match) return false + return Number(match[1]) >= 5 && !modelID.startsWith("gpt-5-mini") +} + +export const GithubCopilotPlugin = PluginV2.define({ + id: PluginV2.ID.make("github-copilot"), + effect: Effect.gen(function* () { + return { + "provider.update": Effect.fn(function* (evt) { + if (evt.provider.id !== ProviderV2.ID.githubCopilot) return + }), + "aisdk.sdk": Effect.fn(function* (evt) { + if (evt.package !== "@ai-sdk/github-copilot") return + const mod = yield* Effect.promise(() => import("../../github-copilot/copilot-provider")) + evt.sdk = mod.createOpenaiCompatible(evt.options) + }), + "aisdk.language": Effect.fn(function* (evt) { + if (evt.model.providerID !== ProviderV2.ID.githubCopilot) return + if (evt.sdk.responses === undefined && evt.sdk.chat === undefined) { + evt.language = evt.sdk.languageModel(evt.model.apiID) + return + } + evt.language = shouldUseResponses(evt.model.apiID) + ? evt.sdk.responses(evt.model.apiID) + : evt.sdk.chat(evt.model.apiID) + }), + "model.update": Effect.fn(function* (evt) { + if (evt.model.providerID !== ProviderV2.ID.githubCopilot) return + // This chat-only alias conflicts with the Copilot GPT-5 Responses route, + // so hide it only for Copilot rather than for every provider catalog. + if (evt.model.id === ModelV2.ID.make("gpt-5-chat-latest")) evt.cancel = true + }), + } + }), +}) diff --git a/packages/core/src/plugin/provider/gitlab.ts b/packages/core/src/plugin/provider/gitlab.ts new file mode 100644 index 00000000000..226f5a45eb4 --- /dev/null +++ b/packages/core/src/plugin/provider/gitlab.ts @@ -0,0 +1,65 @@ +import os from "os" +import { InstallationVersion } from "../../installation/version" +import { Effect } from "effect" +import { PluginV2 } from "../../plugin" +import { ProviderV2 } from "../../provider" + +export const GitLabPlugin = PluginV2.define({ + id: PluginV2.ID.make("gitlab"), + effect: Effect.gen(function* () { + return { + "aisdk.sdk": Effect.fn(function* (evt) { + if (evt.package !== "gitlab-ai-provider") return + const mod = yield* Effect.promise(() => import("gitlab-ai-provider")) + evt.sdk = mod.createGitLab({ + ...evt.options, + instanceUrl: + typeof evt.options.instanceUrl === "string" + ? evt.options.instanceUrl + : (process.env.GITLAB_INSTANCE_URL ?? "https://gitlab.com"), + apiKey: typeof evt.options.apiKey === "string" ? evt.options.apiKey : process.env.GITLAB_TOKEN, + aiGatewayHeaders: { + "User-Agent": `opencode/${InstallationVersion} gitlab-ai-provider/${mod.VERSION} (${os.platform()} ${os.release()}; ${os.arch()})`, + "anthropic-beta": "context-1m-2025-08-07", + ...evt.options.aiGatewayHeaders, + }, + featureFlags: { + duo_agent_platform_agentic_chat: true, + duo_agent_platform: true, + ...evt.options.featureFlags, + }, + }) + }), + "aisdk.language": Effect.fn(function* (evt) { + if (evt.model.providerID !== ProviderV2.ID.gitlab) return + const featureFlags = + typeof evt.options.featureFlags === "object" && evt.options.featureFlags ? evt.options.featureFlags : {} + if (evt.model.apiID.startsWith("duo-workflow-")) { + const gitlab = yield* Effect.promise(() => import("gitlab-ai-provider")).pipe(Effect.orDie) + const workflowRef = + typeof evt.model.options.aisdk.request.workflowRef === "string" + ? evt.model.options.aisdk.request.workflowRef + : undefined + const workflowDefinition = + typeof evt.model.options.aisdk.request.workflowDefinition === "string" + ? evt.model.options.aisdk.request.workflowDefinition + : undefined + const language = evt.sdk.workflowChat( + gitlab.isWorkflowModel(evt.model.apiID) ? evt.model.apiID : "duo-workflow", + { + featureFlags, + workflowDefinition, + }, + ) + if (workflowRef) language.selectedModelRef = workflowRef + evt.language = language + return + } + evt.language = evt.sdk.agenticChat(evt.model.apiID, { + aiGatewayHeaders: evt.options.aiGatewayHeaders, + featureFlags, + }) + }), + } + }), +}) diff --git a/packages/core/src/plugin/provider/google-vertex.ts b/packages/core/src/plugin/provider/google-vertex.ts new file mode 100644 index 00000000000..0c335df9312 --- /dev/null +++ b/packages/core/src/plugin/provider/google-vertex.ts @@ -0,0 +1,141 @@ +import { Effect } from "effect" +import { PluginV2 } from "../../plugin" +import { ProviderV2 } from "../../provider" + +function resolveProject(options: Record) { + // models.dev advertises GOOGLE_VERTEX_PROJECT for Vertex, while Google SDKs + // and ADC examples commonly use the broader Google Cloud project aliases. + return ( + options.project ?? + process.env.GOOGLE_VERTEX_PROJECT ?? + process.env.GOOGLE_CLOUD_PROJECT ?? + process.env.GCP_PROJECT ?? + process.env.GCLOUD_PROJECT + ) +} + +function resolveLocation(options: Record) { + return ( + options.location ?? + process.env.GOOGLE_VERTEX_LOCATION ?? + process.env.GOOGLE_CLOUD_LOCATION ?? + process.env.VERTEX_LOCATION ?? + "us-central1" + ) +} + +function vertexEndpoint(location: string) { + return location === "global" ? "aiplatform.googleapis.com" : `${location}-aiplatform.googleapis.com` +} + +function replaceVertexVars(value: string, project: string | undefined, location: string) { + // Vertex OpenAI-compatible endpoints are stored as templates in the catalog; + // expand them after provider config/env project and location have been resolved. + return value + .replaceAll("${GOOGLE_VERTEX_PROJECT}", project ?? "${GOOGLE_VERTEX_PROJECT}") + .replaceAll("${GOOGLE_VERTEX_LOCATION}", location) + .replaceAll("${GOOGLE_VERTEX_ENDPOINT}", vertexEndpoint(location)) +} + +function authFetch(fetchWithRuntimeOptions?: unknown) { + // Native Vertex SDKs handle ADC internally. OpenAI-compatible Vertex endpoints + // do not, so inject a Google access token into their fetch path. + return async (input: Parameters[0], init?: RequestInit) => { + const { GoogleAuth } = await import("google-auth-library") + const auth = new GoogleAuth() + const client = await auth.getApplicationDefault() + const token = await client.credential.getAccessToken() + const headers = new Headers(init?.headers) + headers.set("Authorization", `Bearer ${token.token}`) + return typeof fetchWithRuntimeOptions === "function" + ? fetchWithRuntimeOptions(input, { ...init, headers }) + : fetch(input, { ...init, headers }) + } +} + +export const GoogleVertexPlugin = PluginV2.define({ + id: PluginV2.ID.make("google-vertex"), + effect: Effect.gen(function* () { + return { + "provider.update": Effect.fn(function* (evt) { + if (evt.provider.id !== ProviderV2.ID.googleVertex) return + const project = resolveProject(evt.provider.options.aisdk.provider) + const location = String(resolveLocation(evt.provider.options.aisdk.provider)) + if (project) evt.provider.options.aisdk.provider.project = project + evt.provider.options.aisdk.provider.location = location + if (evt.provider.endpoint.type === "aisdk" && evt.provider.endpoint.url) { + evt.provider.endpoint.url = replaceVertexVars(evt.provider.endpoint.url, project, location) + } + if ( + evt.provider.endpoint.type === "aisdk" && + evt.provider.endpoint.package.includes("@ai-sdk/openai-compatible") + ) { + evt.provider.options.aisdk.provider.fetch = authFetch(evt.provider.options.aisdk.provider.fetch) + } + }), + "aisdk.sdk": Effect.fn(function* (evt) { + if (evt.model.providerID === ProviderV2.ID.googleVertex && evt.package.includes("@ai-sdk/openai-compatible")) { + evt.options.fetch = authFetch(evt.options.fetch) + return + } + if (evt.package !== "@ai-sdk/google-vertex") return + const mod = yield* Effect.promise(() => import("@ai-sdk/google-vertex")) + const project = resolveProject(evt.options) + const location = resolveLocation(evt.options) + const options = { ...evt.options } + delete options.fetch + evt.sdk = mod.createVertex({ + ...options, + project, + location, + }) + }), + "aisdk.language": Effect.fn(function* (evt) { + if (evt.model.providerID !== ProviderV2.ID.googleVertex) return + evt.language = evt.sdk.languageModel(String(evt.model.apiID).trim()) + }), + } + }), +}) + +export const GoogleVertexAnthropicPlugin = PluginV2.define({ + id: PluginV2.ID.make("google-vertex-anthropic"), + effect: Effect.gen(function* () { + return { + "provider.update": Effect.fn(function* (evt) { + if (evt.provider.id !== ProviderV2.ID.make("google-vertex-anthropic")) return + const project = + evt.provider.options.aisdk.provider.project ?? + process.env.GOOGLE_CLOUD_PROJECT ?? + process.env.GCP_PROJECT ?? + process.env.GCLOUD_PROJECT + const location = + evt.provider.options.aisdk.provider.location ?? + process.env.GOOGLE_CLOUD_LOCATION ?? + process.env.VERTEX_LOCATION ?? + "global" + if (project) evt.provider.options.aisdk.provider.project = project + evt.provider.options.aisdk.provider.location = location + }), + "aisdk.sdk": Effect.fn(function* (evt) { + if (evt.package !== "@ai-sdk/google-vertex/anthropic") return + const mod = yield* Effect.promise(() => import("@ai-sdk/google-vertex/anthropic")) + evt.sdk = mod.createVertexAnthropic({ + ...evt.options, + project: + typeof evt.options.project === "string" + ? evt.options.project + : (process.env.GOOGLE_CLOUD_PROJECT ?? process.env.GCP_PROJECT ?? process.env.GCLOUD_PROJECT), + location: + typeof evt.options.location === "string" + ? evt.options.location + : (process.env.GOOGLE_CLOUD_LOCATION ?? process.env.VERTEX_LOCATION ?? "global"), + }) + }), + "aisdk.language": Effect.fn(function* (evt) { + if (evt.model.providerID !== ProviderV2.ID.make("google-vertex-anthropic")) return + evt.language = evt.sdk.languageModel(String(evt.model.apiID).trim()) + }), + } + }), +}) diff --git a/packages/core/src/plugin/provider/google.ts b/packages/core/src/plugin/provider/google.ts new file mode 100644 index 00000000000..47e29c6b5d5 --- /dev/null +++ b/packages/core/src/plugin/provider/google.ts @@ -0,0 +1,15 @@ +import { Effect } from "effect" +import { PluginV2 } from "../../plugin" + +export const GooglePlugin = PluginV2.define({ + id: PluginV2.ID.make("google"), + effect: Effect.gen(function* () { + return { + "aisdk.sdk": Effect.fn(function* (evt) { + if (evt.package !== "@ai-sdk/google") return + const mod = yield* Effect.promise(() => import("@ai-sdk/google")) + evt.sdk = mod.createGoogleGenerativeAI(evt.options) + }), + } + }), +}) diff --git a/packages/core/src/plugin/provider/groq.ts b/packages/core/src/plugin/provider/groq.ts new file mode 100644 index 00000000000..f2052afd1a8 --- /dev/null +++ b/packages/core/src/plugin/provider/groq.ts @@ -0,0 +1,15 @@ +import { Effect } from "effect" +import { PluginV2 } from "../../plugin" + +export const GroqPlugin = PluginV2.define({ + id: PluginV2.ID.make("groq"), + effect: Effect.gen(function* () { + return { + "aisdk.sdk": Effect.fn(function* (evt) { + if (evt.package !== "@ai-sdk/groq") return + const mod = yield* Effect.promise(() => import("@ai-sdk/groq")) + evt.sdk = mod.createGroq(evt.options) + }), + } + }), +}) diff --git a/packages/core/src/plugin/provider/index.ts b/packages/core/src/plugin/provider/index.ts new file mode 100644 index 00000000000..fd02d322a1f --- /dev/null +++ b/packages/core/src/plugin/provider/index.ts @@ -0,0 +1,67 @@ +import { AlibabaPlugin } from "./alibaba" +import { AmazonBedrockPlugin } from "./amazon-bedrock" +import { AnthropicPlugin } from "./anthropic" +import { AzureCognitiveServicesPlugin, AzurePlugin } from "./azure" +import { CerebrasPlugin } from "./cerebras" +import { CloudflareAIGatewayPlugin } from "./cloudflare-ai-gateway" +import { CloudflareWorkersAIPlugin } from "./cloudflare-workers-ai" +import { CoherePlugin } from "./cohere" +import { DeepInfraPlugin } from "./deepinfra" +import { DynamicProviderPlugin } from "./dynamic" +import { GatewayPlugin } from "./gateway" +import { GithubCopilotPlugin } from "./github-copilot" +import { GitLabPlugin } from "./gitlab" +import { GooglePlugin } from "./google" +import { GoogleVertexAnthropicPlugin, GoogleVertexPlugin } from "./google-vertex" +import { GroqPlugin } from "./groq" +import { KiloPlugin } from "./kilo" +import { LLMGatewayPlugin } from "./llmgateway" +import { MistralPlugin } from "./mistral" +import { NvidiaPlugin } from "./nvidia" +import { OpenAIPlugin } from "./openai" +import { OpenAICompatiblePlugin } from "./openai-compatible" +import { OpencodePlugin } from "./opencode" +import { OpenRouterPlugin } from "./openrouter" +import { PerplexityPlugin } from "./perplexity" +import { SapAICorePlugin } from "./sap-ai-core" +import { TogetherAIPlugin } from "./togetherai" +import { VercelPlugin } from "./vercel" +import { VenicePlugin } from "./venice" +import { XAIPlugin } from "./xai" +import { ZenmuxPlugin } from "./zenmux" + +export const ProviderPlugins = [ + AlibabaPlugin, + AmazonBedrockPlugin, + AnthropicPlugin, + AzureCognitiveServicesPlugin, + AzurePlugin, + CerebrasPlugin, + CloudflareAIGatewayPlugin, + CloudflareWorkersAIPlugin, + CoherePlugin, + DeepInfraPlugin, + GatewayPlugin, + GithubCopilotPlugin, + GitLabPlugin, + GooglePlugin, + GoogleVertexAnthropicPlugin, + GoogleVertexPlugin, + GroqPlugin, + KiloPlugin, + LLMGatewayPlugin, + MistralPlugin, + NvidiaPlugin, + OpencodePlugin, + OpenAICompatiblePlugin, + OpenAIPlugin, + OpenRouterPlugin, + PerplexityPlugin, + SapAICorePlugin, + TogetherAIPlugin, + VercelPlugin, + VenicePlugin, + XAIPlugin, + ZenmuxPlugin, + DynamicProviderPlugin, +] diff --git a/packages/core/src/plugin/provider/kilo.ts b/packages/core/src/plugin/provider/kilo.ts new file mode 100644 index 00000000000..82eca003d10 --- /dev/null +++ b/packages/core/src/plugin/provider/kilo.ts @@ -0,0 +1,37 @@ +// kilocode_change - new file +import { createKilo, KILO_OPENROUTER_BASE } from "@kilocode/kilo-gateway" +import { Effect } from "effect" +import { PluginV2 } from "../../plugin" +import { ProviderV2 } from "../../provider" + +const id = ProviderV2.ID.make("kilo") + +export const KiloPlugin = PluginV2.define({ + id: PluginV2.ID.make("kilo"), + effect: Effect.gen(function* () { + return { + "provider.update": Effect.fn(function* (evt) { + if (evt.provider.id !== id) return + + const options = evt.provider.options.aisdk.provider + const token = options.kilocodeToken ?? options.apiKey ?? process.env.KILO_API_KEY + const org = process.env.KILO_ORG_ID ?? options.kilocodeOrganizationId + + evt.provider.endpoint = { + type: "aisdk", + package: "@kilocode/kilo-gateway", + url: KILO_OPENROUTER_BASE, + } + evt.provider.options.headers["HTTP-Referer"] = "https://kilo.ai/" + evt.provider.options.headers["X-Title"] = "Kilo Code" + options.kilocodeToken = token ?? "anonymous" + if (org) options.kilocodeOrganizationId = org + if (!evt.provider.enabled) evt.provider.enabled = { via: "custom", data: { anonymous: true } } + }), + "aisdk.sdk": Effect.fn(function* (evt) { + if (evt.model.providerID !== id) return + evt.sdk = createKilo(evt.options) + }), + } + }), +}) diff --git a/packages/core/src/plugin/provider/llmgateway.ts b/packages/core/src/plugin/provider/llmgateway.ts new file mode 100644 index 00000000000..dd656dfc59d --- /dev/null +++ b/packages/core/src/plugin/provider/llmgateway.ts @@ -0,0 +1,18 @@ +import { Effect } from "effect" +import { PluginV2 } from "../../plugin" +import { ProviderV2 } from "../../provider" + +export const LLMGatewayPlugin = PluginV2.define({ + id: PluginV2.ID.make("llmgateway"), + effect: Effect.gen(function* () { + return { + "provider.update": Effect.fn(function* (evt) { + if (evt.provider.id !== ProviderV2.ID.make("llmgateway")) return + if (evt.provider.enabled === false) return + evt.provider.options.headers["HTTP-Referer"] = "https://kilo.ai/" // kilocode_change + evt.provider.options.headers["X-Title"] = "Kilo Code" // kilocode_change + evt.provider.options.headers["X-Source"] = "kilo" // kilocode_change + }), + } + }), +}) diff --git a/packages/core/src/plugin/provider/mistral.ts b/packages/core/src/plugin/provider/mistral.ts new file mode 100644 index 00000000000..e7f0decb79e --- /dev/null +++ b/packages/core/src/plugin/provider/mistral.ts @@ -0,0 +1,15 @@ +import { Effect } from "effect" +import { PluginV2 } from "../../plugin" + +export const MistralPlugin = PluginV2.define({ + id: PluginV2.ID.make("mistral"), + effect: Effect.gen(function* () { + return { + "aisdk.sdk": Effect.fn(function* (evt) { + if (evt.package !== "@ai-sdk/mistral") return + const mod = yield* Effect.promise(() => import("@ai-sdk/mistral")) + evt.sdk = mod.createMistral(evt.options) + }), + } + }), +}) diff --git a/packages/core/src/plugin/provider/nvidia.ts b/packages/core/src/plugin/provider/nvidia.ts new file mode 100644 index 00000000000..ebbca16d2af --- /dev/null +++ b/packages/core/src/plugin/provider/nvidia.ts @@ -0,0 +1,17 @@ +import { Effect } from "effect" +import { PluginV2 } from "../../plugin" +import { ProviderV2 } from "../../provider" + +export const NvidiaPlugin = PluginV2.define({ + id: PluginV2.ID.make("nvidia"), + effect: Effect.gen(function* () { + return { + "provider.update": Effect.fn(function* (evt) { + if (evt.provider.id !== ProviderV2.ID.make("nvidia")) return + evt.provider.options.headers["HTTP-Referer"] = "https://kilo.ai/" // kilocode_change + evt.provider.options.headers["X-Title"] = "Kilo Code" // kilocode_change + evt.provider.options.headers["X-BILLING-INVOKE-ORIGIN"] ??= "KiloCode" // kilocode_change + }), + } + }), +}) diff --git a/packages/core/src/plugin/provider/openai-compatible.ts b/packages/core/src/plugin/provider/openai-compatible.ts new file mode 100644 index 00000000000..76c33737066 --- /dev/null +++ b/packages/core/src/plugin/provider/openai-compatible.ts @@ -0,0 +1,17 @@ +import { Effect } from "effect" +import { PluginV2 } from "../../plugin" + +export const OpenAICompatiblePlugin = PluginV2.define({ + id: PluginV2.ID.make("openai-compatible"), + effect: Effect.gen(function* () { + return { + "aisdk.sdk": Effect.fn(function* (evt) { + if (evt.sdk) return + if (!evt.package.includes("@ai-sdk/openai-compatible")) return + if (evt.options.includeUsage !== false) evt.options.includeUsage = true + const mod = yield* Effect.promise(() => import("@ai-sdk/openai-compatible")) + evt.sdk = mod.createOpenAICompatible(evt.options as any) + }), + } + }), +}) diff --git a/packages/core/src/plugin/provider/openai.ts b/packages/core/src/plugin/provider/openai.ts new file mode 100644 index 00000000000..a81455f1985 --- /dev/null +++ b/packages/core/src/plugin/provider/openai.ts @@ -0,0 +1,27 @@ +import { Effect } from "effect" +import { ModelV2 } from "../../model" +import { PluginV2 } from "../../plugin" +import { ProviderV2 } from "../../provider" + +export const OpenAIPlugin = PluginV2.define({ + id: PluginV2.ID.make("openai"), + effect: Effect.gen(function* () { + return { + "aisdk.sdk": Effect.fn(function* (evt) { + if (evt.package !== "@ai-sdk/openai") return + const mod = yield* Effect.promise(() => import("@ai-sdk/openai")) + evt.sdk = mod.createOpenAI(evt.options) + }), + "aisdk.language": Effect.fn(function* (evt) { + if (evt.model.providerID !== ProviderV2.ID.openai) return + evt.language = evt.sdk.responses(evt.model.apiID) + }), + "model.update": Effect.fn(function* (evt) { + if (evt.model.providerID !== ProviderV2.ID.openai) return + // OpenAIPlugin sends OpenAI models through Responses; this alias is a + // chat-completions-only model, so remove it only from OpenAI's catalog. + if (evt.model.id === ModelV2.ID.make("gpt-5-chat-latest")) evt.cancel = true + }), + } + }), +}) diff --git a/packages/core/src/plugin/provider/opencode.ts b/packages/core/src/plugin/provider/opencode.ts new file mode 100644 index 00000000000..10bbb62dadb --- /dev/null +++ b/packages/core/src/plugin/provider/opencode.ts @@ -0,0 +1,27 @@ +import { Effect } from "effect" +import { PluginV2 } from "../../plugin" +import { ProviderV2 } from "../../provider" + +export const OpencodePlugin = PluginV2.define({ + id: PluginV2.ID.make("opencode"), + effect: Effect.gen(function* () { + let hasKey = false + return { + "provider.update": Effect.fn(function* (evt) { + if (evt.provider.id !== ProviderV2.ID.opencode) return + hasKey = Boolean( + process.env.OPENCODE_API_KEY || + evt.provider.env.some((item) => process.env[item]) || + evt.provider.options.aisdk.provider.apiKey || + (evt.provider.enabled && evt.provider.enabled.via === "auth"), + ) + if (!hasKey) evt.provider.options.aisdk.provider.apiKey = "public" + }), + "model.update": Effect.fn(function* (evt) { + if (evt.model.providerID !== ProviderV2.ID.opencode) return + if (hasKey) return + if (evt.model.cost.some((item) => item.input > 0)) evt.cancel = true + }), + } + }), +}) diff --git a/packages/core/src/plugin/provider/openrouter.ts b/packages/core/src/plugin/provider/openrouter.ts new file mode 100644 index 00000000000..b3e926137f7 --- /dev/null +++ b/packages/core/src/plugin/provider/openrouter.ts @@ -0,0 +1,29 @@ +import { Effect } from "effect" +import { ModelV2 } from "../../model" +import { PluginV2 } from "../../plugin" +import { ProviderV2 } from "../../provider" + +export const OpenRouterPlugin = PluginV2.define({ + id: PluginV2.ID.make("openrouter"), + effect: Effect.gen(function* () { + return { + "provider.update": Effect.fn(function* (evt) { + if (evt.provider.id !== ProviderV2.ID.openrouter) return + evt.provider.options.headers["HTTP-Referer"] = "https://kilo.ai/" // kilocode_change + evt.provider.options.headers["X-Title"] = "Kilo Code" // kilocode_change + }), + "aisdk.sdk": Effect.fn(function* (evt) { + if (evt.package !== "@openrouter/ai-sdk-provider") return + const mod = yield* Effect.promise(() => import("@openrouter/ai-sdk-provider")) + evt.sdk = mod.createOpenRouter(evt.options) + }), + "model.update": Effect.fn(function* (evt) { + if (evt.model.providerID !== ProviderV2.ID.openrouter) return + // These are OpenRouter-specific OpenAI chat aliases that do not work on + // the generic path. Keep custom providers with matching IDs untouched. + if (evt.model.id === ModelV2.ID.make("gpt-5-chat-latest")) evt.cancel = true + if (evt.model.id === ModelV2.ID.make("openai/gpt-5-chat")) evt.cancel = true + }), + } + }), +}) diff --git a/packages/core/src/plugin/provider/perplexity.ts b/packages/core/src/plugin/provider/perplexity.ts new file mode 100644 index 00000000000..2415ab7c1a2 --- /dev/null +++ b/packages/core/src/plugin/provider/perplexity.ts @@ -0,0 +1,15 @@ +import { Effect } from "effect" +import { PluginV2 } from "../../plugin" + +export const PerplexityPlugin = PluginV2.define({ + id: PluginV2.ID.make("perplexity"), + effect: Effect.gen(function* () { + return { + "aisdk.sdk": Effect.fn(function* (evt) { + if (evt.package !== "@ai-sdk/perplexity") return + const mod = yield* Effect.promise(() => import("@ai-sdk/perplexity")) + evt.sdk = mod.createPerplexity(evt.options) + }), + } + }), +}) diff --git a/packages/core/src/plugin/provider/sap-ai-core.ts b/packages/core/src/plugin/provider/sap-ai-core.ts new file mode 100644 index 00000000000..7c57b785bff --- /dev/null +++ b/packages/core/src/plugin/provider/sap-ai-core.ts @@ -0,0 +1,44 @@ +import { Npm } from "../../npm" +import { Effect, Option } from "effect" +import { pathToFileURL } from "url" +import { PluginV2 } from "../../plugin" +import { ProviderV2 } from "../../provider" + +export const SapAICorePlugin = PluginV2.define({ + id: PluginV2.ID.make("sap-ai-core"), + effect: Effect.gen(function* () { + const npm = yield* Npm.Service + return { + "aisdk.sdk": Effect.fn(function* (evt) { + if (evt.model.providerID !== ProviderV2.ID.make("sap-ai-core")) return + const serviceKey = + process.env.AICORE_SERVICE_KEY ?? + (typeof evt.options.serviceKey === "string" ? evt.options.serviceKey : undefined) + if (serviceKey && !process.env.AICORE_SERVICE_KEY) process.env.AICORE_SERVICE_KEY = serviceKey + + const installedPath = evt.package.startsWith("file://") + ? evt.package + : Option.getOrUndefined((yield* npm.add(evt.package).pipe(Effect.orDie)).entrypoint) + if (!installedPath) throw new Error(`Package ${evt.package} has no import entrypoint`) + + const mod = yield* Effect.promise(async () => { + return (await import( + installedPath.startsWith("file://") ? installedPath : pathToFileURL(installedPath).href + )) as Record any> + }).pipe(Effect.orDie) + const match = Object.keys(mod).find((name) => name.startsWith("create")) + if (!match) throw new Error(`Package ${evt.package} has no provider factory export`) + + evt.sdk = mod[match]( + serviceKey + ? { deploymentId: process.env.AICORE_DEPLOYMENT_ID, resourceGroup: process.env.AICORE_RESOURCE_GROUP } + : {}, + ) + }), + "aisdk.language": Effect.fn(function* (evt) { + if (evt.model.providerID !== ProviderV2.ID.make("sap-ai-core")) return + evt.language = evt.sdk(evt.model.apiID) + }), + } + }), +}) diff --git a/packages/core/src/plugin/provider/togetherai.ts b/packages/core/src/plugin/provider/togetherai.ts new file mode 100644 index 00000000000..b1870f26625 --- /dev/null +++ b/packages/core/src/plugin/provider/togetherai.ts @@ -0,0 +1,15 @@ +import { Effect } from "effect" +import { PluginV2 } from "../../plugin" + +export const TogetherAIPlugin = PluginV2.define({ + id: PluginV2.ID.make("togetherai"), + effect: Effect.gen(function* () { + return { + "aisdk.sdk": Effect.fn(function* (evt) { + if (evt.package !== "@ai-sdk/togetherai") return + const mod = yield* Effect.promise(() => import("@ai-sdk/togetherai")) + evt.sdk = mod.createTogetherAI(evt.options) + }), + } + }), +}) diff --git a/packages/core/src/plugin/provider/venice.ts b/packages/core/src/plugin/provider/venice.ts new file mode 100644 index 00000000000..8a3b950245c --- /dev/null +++ b/packages/core/src/plugin/provider/venice.ts @@ -0,0 +1,15 @@ +import { Effect } from "effect" +import { PluginV2 } from "../../plugin" + +export const VenicePlugin = PluginV2.define({ + id: PluginV2.ID.make("venice"), + effect: Effect.gen(function* () { + return { + "aisdk.sdk": Effect.fn(function* (evt) { + if (evt.package !== "venice-ai-sdk-provider") return + const mod = yield* Effect.promise(() => import("venice-ai-sdk-provider")) + evt.sdk = mod.createVenice(evt.options) + }), + } + }), +}) diff --git a/packages/core/src/plugin/provider/vercel.ts b/packages/core/src/plugin/provider/vercel.ts new file mode 100644 index 00000000000..2d50e3b0930 --- /dev/null +++ b/packages/core/src/plugin/provider/vercel.ts @@ -0,0 +1,21 @@ +import { Effect } from "effect" +import { PluginV2 } from "../../plugin" +import { ProviderV2 } from "../../provider" + +export const VercelPlugin = PluginV2.define({ + id: PluginV2.ID.make("vercel"), + effect: Effect.gen(function* () { + return { + "provider.update": Effect.fn(function* (evt) { + if (evt.provider.id !== ProviderV2.ID.make("vercel")) return + evt.provider.options.headers["http-referer"] = "https://kilo.ai/" // kilocode_change + evt.provider.options.headers["x-title"] = "Kilo Code" // kilocode_change + }), + "aisdk.sdk": Effect.fn(function* (evt) { + if (evt.package !== "@ai-sdk/vercel") return + const mod = yield* Effect.promise(() => import("@ai-sdk/vercel")) + evt.sdk = mod.createVercel(evt.options) + }), + } + }), +}) diff --git a/packages/core/src/plugin/provider/xai.ts b/packages/core/src/plugin/provider/xai.ts new file mode 100644 index 00000000000..b54aa7374c6 --- /dev/null +++ b/packages/core/src/plugin/provider/xai.ts @@ -0,0 +1,20 @@ +import { Effect } from "effect" +import { PluginV2 } from "../../plugin" +import { ProviderV2 } from "../../provider" + +export const XAIPlugin = PluginV2.define({ + id: PluginV2.ID.make("xai"), + effect: Effect.gen(function* () { + return { + "aisdk.sdk": Effect.fn(function* (evt) { + if (evt.package !== "@ai-sdk/xai") return + const mod = yield* Effect.promise(() => import("@ai-sdk/xai")) + evt.sdk = mod.createXai(evt.options) + }), + "aisdk.language": Effect.fn(function* (evt) { + if (evt.model.providerID !== ProviderV2.ID.make("xai")) return + evt.language = evt.sdk.responses(evt.model.apiID) + }), + } + }), +}) diff --git a/packages/core/src/plugin/provider/zenmux.ts b/packages/core/src/plugin/provider/zenmux.ts new file mode 100644 index 00000000000..be8086f4826 --- /dev/null +++ b/packages/core/src/plugin/provider/zenmux.ts @@ -0,0 +1,16 @@ +import { Effect } from "effect" +import { PluginV2 } from "../../plugin" +import { ProviderV2 } from "../../provider" + +export const ZenmuxPlugin = PluginV2.define({ + id: PluginV2.ID.make("zenmux"), + effect: Effect.gen(function* () { + return { + "provider.update": Effect.fn(function* (evt) { + if (evt.provider.id !== ProviderV2.ID.make("zenmux")) return + evt.provider.options.headers["HTTP-Referer"] ??= "https://kilo.ai/" // kilocode_change + evt.provider.options.headers["X-Title"] ??= "Kilo Code" // kilocode_change + }), + } + }), +}) diff --git a/packages/core/src/process.ts b/packages/core/src/process.ts new file mode 100644 index 00000000000..f076ea4e42c --- /dev/null +++ b/packages/core/src/process.ts @@ -0,0 +1,234 @@ +import { Context, Duration, Effect, Fiber, Layer, Schema, Stream } from "effect" +import type { PlatformError } from "effect/PlatformError" +import { ChildProcess } from "effect/unstable/process" +import { ChildProcessSpawner } from "effect/unstable/process/ChildProcessSpawner" +import { CrossSpawnSpawner } from "./cross-spawn-spawner" + +export class AppProcessError extends Schema.TaggedErrorClass()("AppProcessError", { + command: Schema.String, + exitCode: Schema.optional(Schema.Number), + stderr: Schema.optional(Schema.String), + cause: Schema.optional(Schema.Defect), +}) {} + +export interface RunOptions { + readonly maxOutputBytes?: number + readonly maxErrorBytes?: number + readonly signal?: AbortSignal + readonly timeout?: Duration.Input + readonly stdin?: string | Uint8Array | Stream.Stream +} + +export interface RunStreamOptions { + readonly signal?: AbortSignal + readonly includeStderr?: boolean + readonly okExitCodes?: ReadonlyArray + readonly maxErrorBytes?: number +} + +export interface RunResult { + readonly command: string + readonly exitCode: number + readonly stdout: Buffer + readonly stderr: Buffer + readonly stdoutTruncated: boolean + readonly stderrTruncated: boolean +} + +export type Interface = ChildProcessSpawner["Service"] & { + readonly run: (command: ChildProcess.Command, options?: RunOptions) => Effect.Effect + readonly runStream: ( + command: ChildProcess.Command, + options?: RunStreamOptions, + ) => Stream.Stream +} + +export class Service extends Context.Service()("@opencode/AppProcess") {} + +export const requireSuccess = (result: RunResult): Effect.Effect => + result.exitCode === 0 + ? Effect.succeed(result) + : Effect.fail( + new AppProcessError({ + command: result.command, + exitCode: result.exitCode, + stderr: result.stderr.toString("utf8"), + }), + ) + +export const requireExitIn = + (codes: ReadonlyArray) => + (result: RunResult): Effect.Effect => + codes.includes(result.exitCode) + ? Effect.succeed(result) + : Effect.fail( + new AppProcessError({ + command: result.command, + exitCode: result.exitCode, + stderr: result.stderr.toString("utf8"), + }), + ) + +const describeCommand = (command: ChildProcess.Command): string => { + if (command._tag === "StandardCommand") { + return command.args.length ? `${command.command} ${command.args.join(" ")}` : command.command + } + return `${describeCommand(command.left)} | ${describeCommand(command.right)}` +} + +const wrapError = (description: string, cause: unknown): AppProcessError => + cause instanceof AppProcessError ? cause : new AppProcessError({ command: description, cause }) + +const abortError = (signal: AbortSignal): Error => { + const reason = signal.reason + if (reason instanceof Error) return reason + const err = new Error("Aborted") + err.name = "AbortError" + return err +} + +const waitForAbort = (signal: AbortSignal) => + Effect.callback((resume) => { + if (signal.aborted) { + resume(Effect.fail(abortError(signal))) + return + } + const onabort = () => resume(Effect.fail(abortError(signal))) + signal.addEventListener("abort", onabort, { once: true }) + return Effect.sync(() => signal.removeEventListener("abort", onabort)) + }) + +const normalizeStdin = ( + input: string | Uint8Array | Stream.Stream, +): Stream.Stream => + typeof input === "string" + ? Stream.make(new TextEncoder().encode(input)) + : input instanceof Uint8Array + ? Stream.make(input) + : input + +const collectStream = (stream: Stream.Stream, maxOutputBytes: number | undefined) => + Stream.runFold( + stream, + () => ({ chunks: [] as Uint8Array[], bytes: 0, truncated: false }), + (acc, chunk) => { + if (maxOutputBytes === undefined) { + acc.chunks.push(chunk) + acc.bytes += chunk.length + return acc + } + const remaining = maxOutputBytes - acc.bytes + if (remaining > 0) acc.chunks.push(remaining >= chunk.length ? chunk : chunk.slice(0, remaining)) + acc.bytes += chunk.length + acc.truncated = acc.truncated || acc.bytes > maxOutputBytes + return acc + }, + ).pipe(Effect.map((x) => ({ buffer: Buffer.concat(x.chunks), truncated: x.truncated }))) + +export const layer = Layer.effect( + Service, + Effect.gen(function* () { + const spawner = yield* ChildProcessSpawner + + const runCommand = (command: ChildProcess.Command, options?: RunOptions) => { + const description = describeCommand(command) + const collect = Effect.scoped( + Effect.gen(function* () { + const handle = yield* spawner.spawn(command) + const [stdout, stderr, exitCode] = yield* Effect.all( + [ + collectStream(handle.stdout, options?.maxOutputBytes), + collectStream(handle.stderr, options?.maxErrorBytes), + handle.exitCode, + ], + { concurrency: "unbounded" }, + ) + return { + command: description, + exitCode, + stdout: stdout.buffer, + stderr: stderr.buffer, + stdoutTruncated: stdout.truncated, + stderrTruncated: stderr.truncated, + } satisfies RunResult + }), + ) + const timed = options?.timeout + ? Effect.timeoutOrElse(collect, { + duration: options.timeout, + orElse: () => Effect.fail(new AppProcessError({ command: description, cause: new Error("Timed out") })), + }) + : collect + const aborted = options?.signal + ? timed.pipe( + Effect.raceFirst( + waitForAbort(options.signal).pipe(Effect.mapError((cause) => wrapError(description, cause))), + ), + ) + : timed + return aborted.pipe(Effect.catch((cause) => Effect.fail(wrapError(description, cause)))) + } + + const run = Effect.fn("AppProcess.run")(function* (command: ChildProcess.Command, options?: RunOptions) { + if (options?.stdin === undefined) return yield* runCommand(command, options) + if (command._tag !== "StandardCommand") { + return yield* new AppProcessError({ + command: describeCommand(command), + cause: new Error("stdin option only supports StandardCommand; received PipedCommand"), + }) + } + const next = ChildProcess.make(command.command, command.args, { + ...command.options, + stdin: normalizeStdin(options.stdin), + }) + return yield* runCommand(next, options) + }) + + const runStream = ( + command: ChildProcess.Command, + options?: RunStreamOptions, + ): Stream.Stream => { + const description = describeCommand(command) + const okExitCodes = options?.okExitCodes + const built: Stream.Stream = Stream.unwrap( + Effect.gen(function* () { + const handle = yield* spawner.spawn(command) + const stderrFiber = yield* Effect.forkScoped( + collectStream(handle.stderr, options?.maxErrorBytes).pipe(Effect.map((x) => x.buffer.toString("utf8"))), + ) + const source = options?.includeStderr === true ? handle.all : handle.stdout + const lines = source.pipe( + Stream.decodeText, + Stream.splitLines, + Stream.filter((line) => line.length > 0), + ) + const tail = Stream.unwrap( + Effect.gen(function* () { + const code = yield* handle.exitCode + if (okExitCodes && okExitCodes.length > 0 && !okExitCodes.includes(code)) { + const stderr = yield* Fiber.join(stderrFiber) + return Stream.fail(new AppProcessError({ command: description, exitCode: code, stderr })) + } + return Stream.empty + }), + ) + return Stream.concat(lines, tail) as Stream.Stream + }), + ) + const mapped = built.pipe( + Stream.catch((cause): Stream.Stream => Stream.fail(wrapError(description, cause))), + ) + if (!options?.signal) return mapped + const signal = options.signal + return mapped.pipe( + Stream.interruptWhen(waitForAbort(signal).pipe(Effect.mapError((cause) => wrapError(description, cause)))), + ) + } + + return Service.of({ ...spawner, run, runStream }) + }), +) + +export const defaultLayer = layer.pipe(Layer.provide(CrossSpawnSpawner.defaultLayer)) + +export * as AppProcess from "./process" diff --git a/packages/core/src/provider.ts b/packages/core/src/provider.ts new file mode 100644 index 00000000000..7c1c9666542 --- /dev/null +++ b/packages/core/src/provider.ts @@ -0,0 +1,120 @@ +export * as ProviderV2 from "./provider" + +import { withStatics } from "./schema" +import { Schema } from "effect" + +export const ID = Schema.String.pipe( + Schema.brand("ProviderV2.ID"), + withStatics((schema) => ({ + // Well-known providers + opencode: schema.make("opencode"), + anthropic: schema.make("anthropic"), + openai: schema.make("openai"), + google: schema.make("google"), + googleVertex: schema.make("google-vertex"), + githubCopilot: schema.make("github-copilot"), + amazonBedrock: schema.make("amazon-bedrock"), + azure: schema.make("azure"), + openrouter: schema.make("openrouter"), + mistral: schema.make("mistral"), + gitlab: schema.make("gitlab"), + })), +) +export type ID = typeof ID.Type + +const OpenAIResponses = Schema.Struct({ + type: Schema.Literal("openai/responses"), + url: Schema.String, + websocket: Schema.optional(Schema.Boolean), +}) + +const OpenAICompletions = Schema.Struct({ + type: Schema.Literal("openai/completions"), + url: Schema.String, + reasoning: Schema.Union([ + Schema.Struct({ + type: Schema.Literal("reasoning_content"), + }), + Schema.Struct({ + type: Schema.Literal("reasoning_details"), + }), + ]).pipe(Schema.optional), +}) +export type OpenAICompletions = typeof OpenAICompletions.Type + +const AISDK = Schema.Struct({ + type: Schema.Literal("aisdk"), + package: Schema.String, + url: Schema.String.pipe(Schema.optional), +}) + +const AnthropicMessages = Schema.Struct({ + type: Schema.Literal("anthropic/messages"), + url: Schema.String, +}) + +const UnknownEndpoint = Schema.Struct({ + type: Schema.Literal("unknown"), +}) + +export const Endpoint = Schema.Union([ + UnknownEndpoint, + OpenAIResponses, + OpenAICompletions, + AnthropicMessages, + AISDK, +]).pipe(Schema.toTaggedUnion("type")) +export type Endpoint = typeof Endpoint.Type + +export const Options = Schema.Struct({ + headers: Schema.Record(Schema.String, Schema.String), + body: Schema.Record(Schema.String, Schema.Any), + aisdk: Schema.Struct({ + provider: Schema.Record(Schema.String, Schema.Any), + request: Schema.Record(Schema.String, Schema.Any), + }), +}) +export type Options = typeof Options.Type + +export class Info extends Schema.Class("ProviderV2.Info")({ + id: ID, + name: Schema.String, + enabled: Schema.Union([ + Schema.Literal(false), + Schema.Struct({ + via: Schema.Literal("env"), + name: Schema.String, + }), + Schema.Struct({ + via: Schema.Literal("auth"), + service: Schema.String, + }), + Schema.Struct({ + via: Schema.Literal("custom"), + data: Schema.Record(Schema.String, Schema.Any), + }), + ]), + env: Schema.String.pipe(Schema.Array), + endpoint: Endpoint, + options: Options, +}) { + static empty(providerID: ID) { + return new Info({ + id: providerID, + name: providerID, + enabled: false, + env: [], + endpoint: { + type: "unknown", + }, + options: { + headers: {}, + body: {}, + aisdk: { + provider: {}, + request: {}, + }, + }, + }) + } +} diff --git a/packages/core/src/schema.ts b/packages/core/src/schema.ts index 2a6c02349fb..5b4042c7369 100644 --- a/packages/core/src/schema.ts +++ b/packages/core/src/schema.ts @@ -1,5 +1,4 @@ import { Option, Schema, SchemaGetter } from "effect" -import { zod, ZodOverride } from "./effect-zod" /** * Integer greater than zero. @@ -21,7 +20,6 @@ export const optionalOmitUndefined = (schema: S) => decode: SchemaGetter.passthrough({ strict: false }), encode: SchemaGetter.transformOptional(Option.filter((value) => value !== undefined)), }), - Schema.annotate({ [ZodOverride]: zod(schema).optional() }), ) /** diff --git a/packages/opencode/src/v2/session-prompt.ts b/packages/core/src/session-prompt.ts similarity index 64% rename from packages/opencode/src/v2/session-prompt.ts rename to packages/core/src/session-prompt.ts index 86d8e52eb78..14167fc2889 100644 --- a/packages/opencode/src/v2/session-prompt.ts +++ b/packages/core/src/session-prompt.ts @@ -29,8 +29,21 @@ export class AgentAttachment extends Schema.Class("Prompt.Agent source: Source.pipe(Schema.optional), }) {} +export class ReferenceAttachment extends Schema.Class("Prompt.ReferenceAttachment")({ + name: Schema.String, + kind: Schema.Literals(["local", "git", "invalid"]), + uri: Schema.String.pipe(Schema.optional), + repository: Schema.String.pipe(Schema.optional), + branch: Schema.String.pipe(Schema.optional), + target: Schema.String.pipe(Schema.optional), + targetUri: Schema.String.pipe(Schema.optional), + problem: Schema.String.pipe(Schema.optional), + source: Source.pipe(Schema.optional), +}) {} + export class Prompt extends Schema.Class("Prompt")({ text: Schema.String, files: Schema.Array(FileAttachment).pipe(Schema.optional), agents: Schema.Array(AgentAttachment).pipe(Schema.optional), + references: Schema.Array(ReferenceAttachment).pipe(Schema.optional), }) {} diff --git a/packages/opencode/src/v2/tool-output.ts b/packages/core/src/tool-output.ts similarity index 100% rename from packages/opencode/src/v2/tool-output.ts rename to packages/core/src/tool-output.ts diff --git a/packages/core/src/util/error.ts b/packages/core/src/util/error.ts index 9d3b7c661a3..7338571f298 100644 --- a/packages/core/src/util/error.ts +++ b/packages/core/src/util/error.ts @@ -1,8 +1,8 @@ -import z from "zod" +import { Schema } from "effect" export abstract class NamedError extends Error { - abstract schema(): z.core.$ZodType - abstract toObject(): { name: string; data: any } + abstract schema(): Schema.Top + abstract toObject(): { name: string; data: unknown } static hasName(error: unknown, name: string): boolean { return ( @@ -10,30 +10,42 @@ export abstract class NamedError extends Error { ) } - static create(name: Name, data: Data) { - const schema = z - .object({ - name: z.literal(name), - data, - }) - .meta({ - ref: name, - }) + static create( + name: Name, + fields: Fields, + ): ReturnType>> + static create( + name: Name, + data: DataSchema, + ): ReturnType> + static create(name: Name, data: Schema.Top | Schema.Struct.Fields) { + return NamedError.createSchemaClass(name, Schema.isSchema(data) ? data : Schema.Struct(data)) + } + + private static createSchemaClass(name: Name, data: DataSchema) { + const schema = Schema.Struct({ + name: Schema.Literal(name), + data, + }).annotate({ identifier: name }) + type Data = Schema.Schema.Type + const result = class extends NamedError { public static readonly Schema = schema + public static readonly EffectSchema = schema + public static readonly tag = name - public override readonly name = name as Name + public override readonly name = name constructor( - public readonly data: z.input, + public readonly data: Data, options?: ErrorOptions, ) { super(name, options) this.name = name } - static isInstance(input: any): input is InstanceType { - return typeof input === "object" && "name" in input && input.name === name + static isInstance(input: unknown): input is InstanceType { + return NamedError.hasName(input, name) } schema() { @@ -51,10 +63,7 @@ export abstract class NamedError extends Error { return result } - public static readonly Unknown = NamedError.create( - "UnknownError", - z.object({ - message: z.string(), - }), - ) + public static readonly Unknown = NamedError.create("UnknownError", { + message: Schema.String, + }) } diff --git a/packages/core/src/util/log.ts b/packages/core/src/util/log.ts index 85ffbd915dc..fc341f09c02 100644 --- a/packages/core/src/util/log.ts +++ b/packages/core/src/util/log.ts @@ -4,12 +4,16 @@ import path from "path" import { existsSync, writeFileSync } from "fs" // kilocode_change import fs from "fs/promises" import * as Global from "../global" -import z from "zod" +import { Schema } from "effect" import { Glob } from "./glob" import { createStream } from "rotating-file-stream" // kilocode_change +import { KILO_RUN_ID } from "./opencode-process" // kilocode_change -export const Level = z.enum(["DEBUG", "INFO", "WARN", "ERROR"]).meta({ ref: "LogLevel", description: "Log level" }) -export type Level = z.infer +export const Level = Schema.Literals(["DEBUG", "INFO", "WARN", "ERROR"]).annotate({ + identifier: "LogLevel", + description: "Log level", +}) +export type Level = Schema.Schema.Type const levelPriority: Record = { DEBUG: 0, @@ -18,6 +22,7 @@ const levelPriority: Record = { ERROR: 3, } const keep = 10 +const initializedRunID = "KILO_LOG_INITIALIZED_RUN_ID" let level: Level = "INFO" @@ -55,29 +60,44 @@ let logpath = "" export function file() { return logpath } -let write = (msg: any) => { +const stderr = (msg: any) => { process.stderr.write(msg) return msg.length } +let write = stderr +let stream: ReturnType | undefined // kilocode_change export async function init(options: Options) { if (options.level) level = options.level void cleanup(Global.Path.log) - if (options.print) return + // kilocode_change start - initialize one rotating stream and truncate dev.log once per Kilo run + if (stream) { + const active = stream + stream = undefined + await new Promise((resolve) => active.end(resolve)) + } + if (options.print) { + write = stderr + return + } logpath = path.join( Global.Path.log, options.dev ? "dev.log" : new Date().toISOString().split(".")[0].replace(/:/g, "") + ".log", ) - await fs.truncate(logpath).catch(() => {}) - // kilocode_change start - use rotating-file-stream to cap log files at 50 MB + const run = process.env[KILO_RUN_ID] + if (!options.dev || !run || process.env[initializedRunID] !== run) { + await fs.truncate(logpath).catch(() => {}) + if (options.dev && run) process.env[initializedRunID] = run + } const dir = path.dirname(logpath) - const stream = createStream(path.basename(logpath), { + const active = createStream(path.basename(logpath), { size: "50M", maxFiles: 10, history: ".log-history", path: dir, }) - stream.on("rotation", () => { + stream = active + active.on("rotation", () => { if (!existsSync(dir)) return try { @@ -91,14 +111,14 @@ export async function init(options: Options) { process.stderr.write("log stream warning: " + msg + "\n") } }) - stream.on("error", (err: Error) => { + active.on("error", (err: Error) => { process.stderr.write("log stream error: " + err.message + "\n") }) - stream.on("warning", (err: Error) => { + active.on("warning", (err: Error) => { process.stderr.write("log stream warning: " + err.message + "\n") }) write = (msg: any) => { - stream.write(msg) + active.write(msg) return msg.length } // kilocode_change end diff --git a/packages/opencode/src/v2/schema.ts b/packages/core/src/v2-schema.ts similarity index 88% rename from packages/opencode/src/v2/schema.ts rename to packages/core/src/v2-schema.ts index 44587b838a4..a34b0b15169 100644 --- a/packages/opencode/src/v2/schema.ts +++ b/packages/core/src/v2-schema.ts @@ -7,4 +7,4 @@ export const DateTimeUtcFromMillis = Schema.Finite.pipe( }), ) -export * as V2Schema from "./schema" +export * as V2Schema from "./v2-schema" diff --git a/packages/core/test/catalog.test.ts b/packages/core/test/catalog.test.ts new file mode 100644 index 00000000000..c5ac2c06cc4 --- /dev/null +++ b/packages/core/test/catalog.test.ts @@ -0,0 +1,201 @@ +import { describe, expect } from "bun:test" +import { DateTime, Effect, Layer, Option } from "effect" +import { Catalog } from "@opencode-ai/core/catalog" +import { Instance } from "@opencode-ai/core/instance" +import { ModelV2 } from "@opencode-ai/core/model" +import { PluginV2 } from "@opencode-ai/core/plugin" +import { ProviderV2 } from "@opencode-ai/core/provider" +import { testEffect } from "./lib/effect" + +const instanceLayer = Layer.succeed(Instance.Service, Instance.Service.of({ directory: "test" })) +const it = testEffect(Catalog.layer.pipe(Layer.provideMerge(PluginV2.defaultLayer), Layer.provide(instanceLayer))) + +describe("CatalogV2", () => { + it.effect("normalizes provider baseURL into endpoint url", () => + Effect.gen(function* () { + const catalog = yield* Catalog.Service + const providerID = ProviderV2.ID.make("test") + + yield* catalog.provider.update(providerID, (provider) => { + provider.endpoint = { + type: "aisdk", + package: "@ai-sdk/openai-compatible", + url: "https://default.example.com", + } + provider.options.aisdk.provider.baseURL = "https://override.example.com" + }) + + const provider = yield* catalog.provider.get(providerID) + + expect(provider.endpoint).toEqual({ + type: "aisdk", + package: "@ai-sdk/openai-compatible", + url: "https://override.example.com", + }) + expect(provider.options.aisdk.provider.baseURL).toBeUndefined() + }), + ) + + it.effect("normalizes model baseURL into endpoint url", () => + Effect.gen(function* () { + const catalog = yield* Catalog.Service + const providerID = ProviderV2.ID.make("test") + const modelID = ModelV2.ID.make("model") + + yield* catalog.provider.update(providerID, (provider) => { + provider.endpoint = { + type: "aisdk", + package: "@ai-sdk/openai-compatible", + url: "https://provider.example.com", + } + }) + yield* catalog.model.update(providerID, modelID, (model) => { + model.endpoint = { + type: "aisdk", + package: "@ai-sdk/openai-compatible", + url: "https://model.example.com", + } + model.options.aisdk.provider.baseURL = "https://override.example.com" + }) + + const model = yield* catalog.model.get(providerID, modelID) + + expect(model.endpoint).toEqual({ + type: "aisdk", + package: "@ai-sdk/openai-compatible", + url: "https://override.example.com", + }) + expect(model.options.aisdk.provider.baseURL).toBeUndefined() + }), + ) + + it.effect("resolves unknown model endpoint from provider endpoint", () => + Effect.gen(function* () { + const catalog = yield* Catalog.Service + const providerID = ProviderV2.ID.make("test") + const modelID = ModelV2.ID.make("model") + + yield* catalog.provider.update(providerID, (provider) => { + provider.endpoint = { + type: "aisdk", + package: "@ai-sdk/openai-compatible", + url: "https://provider.example.com", + } + }) + yield* catalog.model.update(providerID, modelID, () => {}) + + const model = yield* catalog.model.get(providerID, modelID) + + expect(model.endpoint).toEqual({ + type: "aisdk", + package: "@ai-sdk/openai-compatible", + url: "https://provider.example.com", + }) + }), + ) + + it.effect("runs provider hooks after baseURL is normalized", () => + Effect.gen(function* () { + const catalog = yield* Catalog.Service + const plugin = yield* PluginV2.Service + const providerID = ProviderV2.ID.make("test") + const seen: unknown[] = [] + + yield* plugin.add({ + id: PluginV2.ID.make("test"), + effect: Effect.succeed({ + "provider.update": (evt) => + Effect.sync(() => { + seen.push(evt.provider.endpoint.type) + if (evt.provider.endpoint.type === "aisdk") seen.push(evt.provider.endpoint.url) + seen.push(evt.provider.options.aisdk.provider.baseURL) + }), + }), + }) + yield* catalog.provider.update(providerID, (provider) => { + provider.endpoint = { + type: "aisdk", + package: "@ai-sdk/openai-compatible", + } + provider.options.aisdk.provider.baseURL = "https://provider.example.com" + }) + + expect(seen).toEqual(["aisdk", "https://provider.example.com", undefined]) + }), + ) + + it.effect("resolves provider and model option merges", () => + Effect.gen(function* () { + const catalog = yield* Catalog.Service + const providerID = ProviderV2.ID.make("test") + const modelID = ModelV2.ID.make("model") + + yield* catalog.provider.update(providerID, (provider) => { + provider.options.headers.provider = "provider" + provider.options.headers.shared = "provider" + provider.options.body.provider = true + provider.options.aisdk.provider.provider = true + }) + yield* catalog.model.update(providerID, modelID, (model) => { + model.options.headers.model = "model" + model.options.headers.shared = "model" + model.options.body.model = true + model.options.aisdk.provider.model = true + model.options.aisdk.request.request = true + }) + + const model = yield* catalog.model.get(providerID, modelID) + + expect(model.options.headers).toEqual({ provider: "provider", shared: "model", model: "model" }) + expect(model.options.body).toEqual({ provider: true, model: true }) + expect(model.options.aisdk.provider).toEqual({ provider: true, model: true }) + expect(model.options.aisdk.request).toEqual({ request: true }) + }), + ) + + it.effect("falls back to newest available model when no default is configured", () => + Effect.gen(function* () { + const catalog = yield* Catalog.Service + const providerID = ProviderV2.ID.make("test") + + yield* catalog.provider.update(providerID, (provider) => { + provider.enabled = { via: "custom", data: {} } + }) + yield* catalog.model.update(providerID, ModelV2.ID.make("old"), (model) => { + model.time.released = DateTime.makeUnsafe(1000) + }) + yield* catalog.model.update(providerID, ModelV2.ID.make("new"), (model) => { + model.time.released = DateTime.makeUnsafe(2000) + }) + + const model = yield* catalog.model.default() + + expect(Option.getOrUndefined(model)?.id).toMatch("new") + }), + ) + + it.effect("small model prefers small keyword candidates before cost scoring", () => + Effect.gen(function* () { + const catalog = yield* Catalog.Service + const providerID = ProviderV2.ID.make("test") + + yield* catalog.provider.update(providerID, () => {}) + yield* catalog.model.update(providerID, ModelV2.ID.make("cheap-large"), (model) => { + model.capabilities.input = ["text"] + model.capabilities.output = ["text"] + model.cost = [{ input: 1, output: 1, cache: { read: 0, write: 0 } }] + model.time.released = DateTime.makeUnsafe(Date.now()) + }) + yield* catalog.model.update(providerID, ModelV2.ID.make("expensive-mini"), (model) => { + model.capabilities.input = ["text"] + model.capabilities.output = ["text"] + model.cost = [{ input: 10, output: 10, cache: { read: 0, write: 0 } }] + model.time.released = DateTime.makeUnsafe(Date.now()) + }) + + const model = yield* catalog.model.small(providerID) + + expect(Option.getOrUndefined(model)?.id).toMatch("expensive-mini") + }), + ) +}) diff --git a/packages/opencode/test/provider/copilot/convert-to-copilot-messages.test.ts b/packages/core/test/github-copilot/convert-to-copilot-messages.test.ts similarity index 99% rename from packages/opencode/test/provider/copilot/convert-to-copilot-messages.test.ts rename to packages/core/test/github-copilot/convert-to-copilot-messages.test.ts index 6f874db6d2e..65f4b6a5369 100644 --- a/packages/opencode/test/provider/copilot/convert-to-copilot-messages.test.ts +++ b/packages/core/test/github-copilot/convert-to-copilot-messages.test.ts @@ -1,4 +1,4 @@ -import { convertToOpenAICompatibleChatMessages as convertToCopilotMessages } from "@/provider/sdk/copilot/chat/convert-to-openai-compatible-chat-messages" +import { convertToOpenAICompatibleChatMessages as convertToCopilotMessages } from "@opencode-ai/core/github-copilot/chat/convert-to-openai-compatible-chat-messages" import { describe, test, expect } from "bun:test" describe("system messages", () => { diff --git a/packages/opencode/test/provider/copilot/copilot-chat-model.test.ts b/packages/core/test/github-copilot/copilot-chat-model.test.ts similarity index 99% rename from packages/opencode/test/provider/copilot/copilot-chat-model.test.ts rename to packages/core/test/github-copilot/copilot-chat-model.test.ts index 389a72bb377..bc1e2ecd956 100644 --- a/packages/opencode/test/provider/copilot/copilot-chat-model.test.ts +++ b/packages/core/test/github-copilot/copilot-chat-model.test.ts @@ -1,4 +1,4 @@ -import { OpenAICompatibleChatLanguageModel } from "@/provider/sdk/copilot/chat/openai-compatible-chat-language-model" +import { OpenAICompatibleChatLanguageModel } from "@opencode-ai/core/github-copilot/chat/openai-compatible-chat-language-model" import { describe, test, expect, mock } from "bun:test" import type { LanguageModelV3Prompt } from "@ai-sdk/provider" diff --git a/packages/opencode/test/util/effect-zod.test.ts b/packages/core/test/kilocode/effect-zod.test.ts similarity index 99% rename from packages/opencode/test/util/effect-zod.test.ts rename to packages/core/test/kilocode/effect-zod.test.ts index ab3923d8e0a..5874aa55a76 100644 --- a/packages/opencode/test/util/effect-zod.test.ts +++ b/packages/core/test/kilocode/effect-zod.test.ts @@ -9,7 +9,7 @@ function json(schema: z.ZodTypeAny) { return rest } -describe("util.effect-zod", () => { +describe("effect-zod", () => { test("converts class schemas for route dto shapes", () => { class Method extends Schema.Class("ProviderAuthMethod")({ type: Schema.Union([Schema.Literal("oauth"), Schema.Literal("api")]), diff --git a/packages/opencode/test/provider/models.test.ts b/packages/core/test/models.test.ts similarity index 88% rename from packages/opencode/test/provider/models.test.ts rename to packages/core/test/models.test.ts index 4336a3786d0..26e254f53e8 100644 --- a/packages/opencode/test/provider/models.test.ts +++ b/packages/core/test/models.test.ts @@ -4,11 +4,8 @@ import { HttpClient, HttpClientResponse } from "effect/unstable/http" import { AppFileSystem } from "@opencode-ai/core/filesystem" import { Flag } from "@opencode-ai/core/flag/flag" import { Global } from "@opencode-ai/core/global" -import { ModelsDev } from "../../src/provider/models" -import { ModelCache } from "../../src/provider/model-cache" // kilocode_change -import { Config } from "../../src/config/config" // kilocode_change -import { Auth } from "../../src/auth" // kilocode_change -import { it } from "../lib/effect" +import { ModelsDev } from "@opencode-ai/core/models" +import { it } from "./lib/effect" import { rm, writeFile, utimes, mkdir } from "fs/promises" import path from "path" @@ -73,13 +70,16 @@ const fixture2: Record = { interface MockState { body: string status: number - calls: Array<{ url: string }> + calls: Array<{ url: string; userAgent: string | null }> } const makeMockClient = (state: Ref.Ref) => HttpClient.make((request) => Effect.gen(function* () { - yield* Ref.update(state, (s) => ({ ...s, calls: [...s.calls, { url: request.url }] })) + yield* Ref.update(state, (s) => ({ + ...s, + calls: [...s.calls, { url: request.url, userAgent: request.headers["user-agent"] ?? null }], + })) const s = yield* Ref.get(state) return HttpClientResponse.fromWeb(request, new Response(s.body, { status: s.status })) }), @@ -92,9 +92,6 @@ const buildLayer = (state: Ref.Ref) => Layer.fresh(ModelsDev.layer).pipe( Layer.provide(Layer.succeed(HttpClient.HttpClient, makeMockClient(state))), Layer.provide(AppFileSystem.defaultLayer), - Layer.provide(Config.defaultLayer), // kilocode_change - Layer.provide(Auth.defaultLayer), // kilocode_change - Layer.provide(ModelCache.defaultLayer), // kilocode_change ) const writeCache = (data: object, mtimeMs?: number) => @@ -124,11 +121,7 @@ const initialState: MockState = { calls: [], } -// kilocode_change start - skip: upstream tests assert raw-fixture passthrough but Kilo's -// ModelsDev.get() filters/injects providers based on effect-native config access (kilo-allowed -// gating, apertis options, and Kilo provider injection). -// kilocode_change end -describe.skip("ModelsDev Service", () => { +describe("ModelsDev Service", () => { it.live("get() returns providers from disk when cache file exists", () => Effect.gen(function* () { yield* writeCache(fixture) @@ -143,14 +136,14 @@ describe.skip("ModelsDev Service", () => { }), ) - it.live("get() returns {} when disk empty and fetch disabled", () => + it.live("get() returns bundled snapshot when disk empty and fetch disabled", () => Effect.gen(function* () { const state = yield* Ref.make(initialState) const result = yield* provided( state, ModelsDev.Service.use((s) => s.get()), ) - expect(result).toEqual({}) + expect(Object.keys(result).length).toBeGreaterThan(0) const final = yield* Ref.get(state) expect(final.calls).toEqual([]) }), @@ -212,6 +205,8 @@ describe.skip("ModelsDev Service", () => { const final = yield* Ref.get(state) expect(final.calls.length).toBe(1) expect(final.calls[0].url).toContain("/api.json") + expect(final.calls[0].userAgent).toStartWith("opencode/") + expect(final.calls[0].userAgent).toEndWith(`/${Flag.KILO_CLIENT}`) }), ) @@ -261,7 +256,7 @@ describe.skip("ModelsDev Service", () => { }), ) expect(result).toEqual(fixture) - // withTransientReadRetry retries 5xx, so calls may be > 1. + // retryTransient retries 5xx, so calls may be > 1. const final = yield* Ref.get(state) expect(final.calls.length).toBeGreaterThanOrEqual(1) }), diff --git a/packages/core/test/plugin/fixtures/provider-factory.ts b/packages/core/test/plugin/fixtures/provider-factory.ts new file mode 100644 index 00000000000..7278c231dd5 --- /dev/null +++ b/packages/core/test/plugin/fixtures/provider-factory.ts @@ -0,0 +1,9 @@ +export function createFixtureProvider(options: Record) { + const captured = Object.fromEntries(Object.entries(options)) + return Object.assign((modelID: string) => ({ modelID, options: captured }), { + options: captured, + languageModel(modelID: string) { + return { modelID, options: captured } + }, + }) +} diff --git a/packages/core/test/plugin/provider-alibaba.test.ts b/packages/core/test/plugin/provider-alibaba.test.ts new file mode 100644 index 00000000000..06e6f969fdc --- /dev/null +++ b/packages/core/test/plugin/provider-alibaba.test.ts @@ -0,0 +1,67 @@ +import { describe, expect } from "bun:test" +import { createAlibaba } from "@ai-sdk/alibaba" +import { Effect } from "effect" +import { ModelV2 } from "@opencode-ai/core/model" +import { PluginV2 } from "@opencode-ai/core/plugin" +import { AlibabaPlugin } from "@opencode-ai/core/plugin/provider/alibaba" +import { it, model } from "./provider-helper" + +describe("AlibabaPlugin", () => { + it.effect("creates an Alibaba SDK for @ai-sdk/alibaba", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(AlibabaPlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { model: model("alibaba", "qwen"), package: "@ai-sdk/alibaba", options: { name: "alibaba" } }, + {}, + ) + expect(result.sdk).toBeDefined() + }), + ) + + it.effect("ignores non-Alibaba SDK packages", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(AlibabaPlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { model: model("alibaba", "qwen"), package: "@ai-sdk/openai-compatible", options: { name: "alibaba" } }, + {}, + ) + expect(result.sdk).toBeUndefined() + }), + ) + + it.effect("matches the old bundled Alibaba SDK provider naming", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(AlibabaPlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("custom-alibaba", "qwen"), + package: "@ai-sdk/alibaba", + options: { name: "custom-alibaba", apiKey: "test" }, + }, + {}, + ) + const expected = createAlibaba({ apiKey: "test", ...{ name: "custom-alibaba" } }).languageModel("qwen") + const actual = result.sdk?.languageModel("qwen") + expect(actual?.provider).toBe(expected.provider) + expect(actual?.modelId).toBe(expected.modelId) + }), + ) + + it.effect("uses the old default languageModel(apiID) behavior", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(AlibabaPlugin) + const item = model("alibaba", "alias", { apiID: ModelV2.ID.make("qwen-plus") }) + const result = yield* plugin.trigger("aisdk.sdk", { model: item, package: "@ai-sdk/alibaba", options: {} }, {}) + const language = result.sdk?.languageModel(item.apiID) + expect(language?.modelId).toBe("qwen-plus") + expect(language?.provider).toBe("alibaba.chat") + }), + ) +}) diff --git a/packages/core/test/plugin/provider-amazon-bedrock.test.ts b/packages/core/test/plugin/provider-amazon-bedrock.test.ts new file mode 100644 index 00000000000..c70ada08d94 --- /dev/null +++ b/packages/core/test/plugin/provider-amazon-bedrock.test.ts @@ -0,0 +1,465 @@ +import { describe, expect } from "bun:test" +import { Effect } from "effect" +import { PluginV2 } from "@opencode-ai/core/plugin" +import { AmazonBedrockPlugin } from "@opencode-ai/core/plugin/provider/amazon-bedrock" +import { fakeSelectorSdk, it, model, provider, withEnv } from "./provider-helper" + +function bedrockBaseURL(sdk: unknown, modelID = "anthropic.claude-sonnet-4-5") { + const language = (sdk as { languageModel: (id: string) => unknown }).languageModel(modelID) + return (language as { config: { baseUrl: () => string } }).config.baseUrl() +} + +function bedrockFetch(sdk: unknown, modelID = "anthropic.claude-sonnet-4-5") { + const language = (sdk as { languageModel: (id: string) => unknown }).languageModel(modelID) + return ( + language as { config: { fetch: (input: Parameters[0], init?: RequestInit) => Promise } } + ).config.fetch +} + +describe("AmazonBedrockPlugin", () => { + it.effect("moves endpoint option to endpoint URL", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(AmazonBedrockPlugin) + const result = yield* plugin.trigger( + "provider.update", + {}, + { + provider: provider("amazon-bedrock", { + options: { + headers: {}, + body: {}, + aisdk: { provider: { endpoint: "https://bedrock.example" }, request: {} }, + }, + }), + cancel: false, + }, + ) + expect(result.provider.endpoint).toEqual({ + type: "aisdk", + package: "test-provider", + url: "https://bedrock.example", + }) + expect(result.provider.options.aisdk.provider.endpoint).toBeUndefined() + }), + ) + + it.effect("prefers endpoint over baseURL for SDK base URL", () => + withEnv({ AWS_BEARER_TOKEN_BEDROCK: undefined, AWS_PROFILE: undefined, AWS_ACCESS_KEY_ID: undefined }, () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(AmazonBedrockPlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("amazon-bedrock", "anthropic.claude-sonnet-4-5"), + package: "@ai-sdk/amazon-bedrock", + options: { + name: "amazon-bedrock", + bearerToken: "token", + baseURL: "https://base.example", + endpoint: "https://endpoint.example", + region: "us-east-1", + }, + }, + {}, + ) + expect(bedrockBaseURL(result.sdk)).toBe("https://endpoint.example") + }), + ), + ) + + it.effect("uses baseURL as SDK base URL", () => + withEnv({ AWS_BEARER_TOKEN_BEDROCK: undefined, AWS_PROFILE: undefined, AWS_ACCESS_KEY_ID: undefined }, () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(AmazonBedrockPlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("amazon-bedrock", "anthropic.claude-sonnet-4-5"), + package: "@ai-sdk/amazon-bedrock", + options: { + name: "amazon-bedrock", + bearerToken: "token", + baseURL: "https://base.example", + region: "us-east-1", + }, + }, + {}, + ) + expect(bedrockBaseURL(result.sdk)).toBe("https://base.example") + }), + ), + ) + + it.effect("creates SDK without explicit credential env so the default AWS chain can resolve credentials", () => + withEnv( + { + AWS_ACCESS_KEY_ID: undefined, + AWS_BEARER_TOKEN_BEDROCK: undefined, + AWS_CONTAINER_CREDENTIALS_FULL_URI: undefined, + AWS_CONTAINER_CREDENTIALS_RELATIVE_URI: undefined, + AWS_PROFILE: undefined, + AWS_REGION: undefined, + AWS_WEB_IDENTITY_TOKEN_FILE: undefined, + }, + () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(AmazonBedrockPlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("amazon-bedrock", "anthropic.claude-sonnet-4-5"), + package: "@ai-sdk/amazon-bedrock", + options: { name: "amazon-bedrock" }, + }, + {}, + ) + expect(result.sdk).toBeDefined() + expect(bedrockBaseURL(result.sdk)).toBe("https://bedrock-runtime.us-east-1.amazonaws.com") + }), + ), + ) + + it.effect("uses config region over AWS_REGION for SDK base URL", () => + withEnv({ AWS_BEARER_TOKEN_BEDROCK: "token", AWS_REGION: "us-east-1" }, () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(AmazonBedrockPlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("amazon-bedrock", "anthropic.claude-sonnet-4-5"), + package: "@ai-sdk/amazon-bedrock", + options: { name: "amazon-bedrock", region: "eu-west-1" }, + }, + {}, + ) + expect(bedrockBaseURL(result.sdk)).toBe("https://bedrock-runtime.eu-west-1.amazonaws.com") + }), + ), + ) + + it.effect("uses AWS_REGION for SDK base URL when config region is absent", () => + withEnv({ AWS_BEARER_TOKEN_BEDROCK: "token", AWS_REGION: "eu-west-1" }, () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(AmazonBedrockPlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("amazon-bedrock", "anthropic.claude-sonnet-4-5"), + package: "@ai-sdk/amazon-bedrock", + options: { name: "amazon-bedrock" }, + }, + {}, + ) + expect(bedrockBaseURL(result.sdk)).toBe("https://bedrock-runtime.eu-west-1.amazonaws.com") + }), + ), + ) + + it.effect("defaults SDK region to us-east-1", () => + withEnv({ AWS_BEARER_TOKEN_BEDROCK: "token", AWS_REGION: undefined }, () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(AmazonBedrockPlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("amazon-bedrock", "anthropic.claude-sonnet-4-5"), + package: "@ai-sdk/amazon-bedrock", + options: { name: "amazon-bedrock" }, + }, + {}, + ) + expect(bedrockBaseURL(result.sdk)).toBe("https://bedrock-runtime.us-east-1.amazonaws.com") + }), + ), + ) + + it.effect("loads bearer token option into env and uses bearer auth", () => + withEnv({ AWS_ACCESS_KEY_ID: undefined, AWS_BEARER_TOKEN_BEDROCK: undefined, AWS_PROFILE: undefined }, () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const headers: Array = [] + yield* plugin.add(AmazonBedrockPlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("amazon-bedrock", "anthropic.claude-sonnet-4-5"), + package: "@ai-sdk/amazon-bedrock", + options: { + name: "amazon-bedrock", + bearerToken: "option-token", + fetch: async (_input: Parameters[0], init?: RequestInit) => { + headers.push(new Headers(init?.headers).get("Authorization")) + return new Response("{}") + }, + }, + }, + {}, + ) + yield* Effect.promise(() => bedrockFetch(result.sdk)("https://bedrock.example", { method: "POST" })) + expect(process.env.AWS_BEARER_TOKEN_BEDROCK).toBe("option-token") + expect(headers).toEqual(["Bearer option-token"]) + }), + ), + ) + + it.effect("prefers bearer token env over bearer token option", () => + withEnv({ AWS_BEARER_TOKEN_BEDROCK: "env-token" }, () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const headers: Array = [] + yield* plugin.add(AmazonBedrockPlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("amazon-bedrock", "anthropic.claude-sonnet-4-5"), + package: "@ai-sdk/amazon-bedrock", + options: { + name: "amazon-bedrock", + bearerToken: "option-token", + fetch: async (_input: Parameters[0], init?: RequestInit) => { + headers.push(new Headers(init?.headers).get("Authorization")) + return new Response("{}") + }, + }, + }, + {}, + ) + yield* Effect.promise(() => bedrockFetch(result.sdk)("https://bedrock.example", { method: "POST" })) + expect(process.env.AWS_BEARER_TOKEN_BEDROCK).toBe("env-token") + expect(headers).toEqual(["Bearer env-token"]) + }), + ), + ) + + it.effect("uses SigV4 credential env when bearer token is absent", () => + withEnv( + { + AWS_ACCESS_KEY_ID: "test-access-key", + AWS_BEARER_TOKEN_BEDROCK: undefined, + AWS_REGION: "us-east-1", + AWS_SECRET_ACCESS_KEY: "test-secret-key", + AWS_SESSION_TOKEN: "test-session-token", + }, + () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const headers: Array = [] + yield* plugin.add(AmazonBedrockPlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("amazon-bedrock", "anthropic.claude-sonnet-4-5"), + package: "@ai-sdk/amazon-bedrock", + options: { + name: "amazon-bedrock", + fetch: async (_input: Parameters[0], init?: RequestInit) => { + headers.push(new Headers(init?.headers).get("Authorization")) + return new Response("{}") + }, + }, + }, + {}, + ) + yield* Effect.promise(() => + bedrockFetch(result.sdk)("https://bedrock-runtime.us-east-1.amazonaws.com/model/test/invoke", { + body: "{}", + method: "POST", + }), + ) + expect(headers[0]?.startsWith("AWS4-HMAC-SHA256 ")).toBe(true) + }), + ), + ) + + it.effect("applies legacy cross-region inference prefixes", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const calls: string[] = [] + yield* plugin.add(AmazonBedrockPlugin) + yield* plugin.trigger( + "aisdk.language", + { + model: model("amazon-bedrock", "anthropic.claude-sonnet-4-5"), + sdk: { languageModel: fakeSelectorSdk(calls).languageModel }, + options: {}, + }, + {}, + ) + yield* plugin.trigger( + "aisdk.language", + { + model: model("amazon-bedrock", "anthropic.claude-sonnet-4-5"), + sdk: { languageModel: fakeSelectorSdk(calls).languageModel }, + options: { region: "eu-west-1" }, + }, + {}, + ) + yield* plugin.trigger( + "aisdk.language", + { + model: model("amazon-bedrock", "global.anthropic.claude-sonnet-4-5"), + sdk: { languageModel: fakeSelectorSdk(calls).languageModel }, + options: { region: "eu-west-1" }, + }, + {}, + ) + yield* plugin.trigger( + "aisdk.language", + { + model: model("amazon-bedrock", "anthropic.claude-sonnet-4-5"), + sdk: { languageModel: fakeSelectorSdk(calls).languageModel }, + options: { region: "ap-northeast-1" }, + }, + {}, + ) + yield* plugin.trigger( + "aisdk.language", + { + model: model("amazon-bedrock", "anthropic.claude-sonnet-4-5"), + sdk: { languageModel: fakeSelectorSdk(calls).languageModel }, + options: { region: "ap-southeast-2" }, + }, + {}, + ) + expect(calls).toEqual([ + "languageModel:us.anthropic.claude-sonnet-4-5", + "languageModel:eu.anthropic.claude-sonnet-4-5", + "languageModel:global.anthropic.claude-sonnet-4-5", + "languageModel:jp.anthropic.claude-sonnet-4-5", + "languageModel:au.anthropic.claude-sonnet-4-5", + ]) + }), + ) + + it.effect("uses AWS_REGION for language prefixes when region option is absent", () => + withEnv({ AWS_REGION: "eu-west-1" }, () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const calls: string[] = [] + yield* plugin.add(AmazonBedrockPlugin) + yield* plugin.trigger( + "aisdk.language", + { + model: model("amazon-bedrock", "anthropic.claude-sonnet-4-5"), + sdk: { languageModel: fakeSelectorSdk(calls).languageModel }, + options: {}, + }, + {}, + ) + expect(calls).toEqual(["languageModel:eu.anthropic.claude-sonnet-4-5"]) + }), + ), + ) + + it.effect("applies the full legacy cross-region prefix matrix", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const calls: string[] = [] + const cases = [ + { region: "us-east-1", modelID: "amazon.nova-micro-v1:0", expected: "us.amazon.nova-micro-v1:0" }, + { region: "us-east-1", modelID: "amazon.nova-lite-v1:0", expected: "us.amazon.nova-lite-v1:0" }, + { region: "us-east-1", modelID: "amazon.nova-pro-v1:0", expected: "us.amazon.nova-pro-v1:0" }, + { region: "us-east-1", modelID: "amazon.nova-premier-v1:0", expected: "us.amazon.nova-premier-v1:0" }, + { region: "us-east-1", modelID: "amazon.nova-2-lite-v1:0", expected: "us.amazon.nova-2-lite-v1:0" }, + { region: "us-east-1", modelID: "anthropic.claude-sonnet-4-5", expected: "us.anthropic.claude-sonnet-4-5" }, + { region: "us-east-1", modelID: "deepseek.r1-v1:0", expected: "us.deepseek.r1-v1:0" }, + { region: "us-gov-west-1", modelID: "anthropic.claude-sonnet-4-5", expected: "anthropic.claude-sonnet-4-5" }, + { region: "us-east-1", modelID: "cohere.command-r-plus-v1:0", expected: "cohere.command-r-plus-v1:0" }, + { region: "eu-west-1", modelID: "anthropic.claude-sonnet-4-5", expected: "eu.anthropic.claude-sonnet-4-5" }, + { region: "eu-west-2", modelID: "amazon.nova-lite-v1:0", expected: "eu.amazon.nova-lite-v1:0" }, + { region: "eu-west-3", modelID: "amazon.nova-micro-v1:0", expected: "eu.amazon.nova-micro-v1:0" }, + { + region: "eu-north-1", + modelID: "meta.llama3-70b-instruct-v1:0", + expected: "eu.meta.llama3-70b-instruct-v1:0", + }, + { region: "eu-central-1", modelID: "mistral.pixtral-large-v1:0", expected: "eu.mistral.pixtral-large-v1:0" }, + { region: "eu-south-1", modelID: "anthropic.claude-sonnet-4-5", expected: "eu.anthropic.claude-sonnet-4-5" }, + { region: "eu-south-2", modelID: "anthropic.claude-sonnet-4-5", expected: "eu.anthropic.claude-sonnet-4-5" }, + { region: "eu-central-2", modelID: "anthropic.claude-sonnet-4-5", expected: "anthropic.claude-sonnet-4-5" }, + { region: "eu-west-1", modelID: "cohere.command-r-plus-v1:0", expected: "cohere.command-r-plus-v1:0" }, + { + region: "ap-southeast-2", + modelID: "anthropic.claude-sonnet-4-5", + expected: "au.anthropic.claude-sonnet-4-5", + }, + { + region: "ap-southeast-4", + modelID: "anthropic.claude-haiku-v1:0", + expected: "au.anthropic.claude-haiku-v1:0", + }, + { region: "ap-southeast-2", modelID: "anthropic.claude-opus-4", expected: "apac.anthropic.claude-opus-4" }, + { + region: "ap-northeast-1", + modelID: "anthropic.claude-sonnet-4-5", + expected: "jp.anthropic.claude-sonnet-4-5", + }, + { region: "ap-northeast-1", modelID: "amazon.nova-pro-v1:0", expected: "jp.amazon.nova-pro-v1:0" }, + { region: "ap-south-1", modelID: "anthropic.claude-sonnet-4-5", expected: "apac.anthropic.claude-sonnet-4-5" }, + { region: "ap-south-1", modelID: "amazon.nova-lite-v1:0", expected: "apac.amazon.nova-lite-v1:0" }, + { region: "ca-central-1", modelID: "anthropic.claude-sonnet-4-5", expected: "anthropic.claude-sonnet-4-5" }, + { + region: "us-east-1", + modelID: "global.anthropic.claude-sonnet-4-5", + expected: "global.anthropic.claude-sonnet-4-5", + }, + { region: "us-east-1", modelID: "us.anthropic.claude-sonnet-4-5", expected: "us.anthropic.claude-sonnet-4-5" }, + { region: "eu-west-1", modelID: "eu.anthropic.claude-sonnet-4-5", expected: "eu.anthropic.claude-sonnet-4-5" }, + { + region: "ap-northeast-1", + modelID: "jp.anthropic.claude-sonnet-4-5", + expected: "jp.anthropic.claude-sonnet-4-5", + }, + { + region: "ap-south-1", + modelID: "apac.anthropic.claude-sonnet-4-5", + expected: "apac.anthropic.claude-sonnet-4-5", + }, + { + region: "ap-southeast-2", + modelID: "au.anthropic.claude-sonnet-4-5", + expected: "au.anthropic.claude-sonnet-4-5", + }, + ] + yield* plugin.add(AmazonBedrockPlugin) + for (const item of cases) { + yield* plugin.trigger( + "aisdk.language", + { + model: model("amazon-bedrock", item.modelID), + sdk: { languageModel: fakeSelectorSdk(calls).languageModel }, + options: { region: item.region }, + }, + {}, + ) + } + expect(calls).toEqual(cases.map((item) => `languageModel:${item.expected}`)) + }), + ) + + it.effect("ignores non-Bedrock providers for language selection", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const calls: string[] = [] + yield* plugin.add(AmazonBedrockPlugin) + const result = yield* plugin.trigger( + "aisdk.language", + { + model: model("openai", "anthropic.claude-sonnet-4-5"), + sdk: { languageModel: fakeSelectorSdk(calls).languageModel }, + options: { region: "eu-west-1" }, + }, + {}, + ) + expect(calls).toEqual([]) + expect(result.language).toBeUndefined() + }), + ) +}) diff --git a/packages/core/test/plugin/provider-anthropic.test.ts b/packages/core/test/plugin/provider-anthropic.test.ts new file mode 100644 index 00000000000..bbea4a37215 --- /dev/null +++ b/packages/core/test/plugin/provider-anthropic.test.ts @@ -0,0 +1,91 @@ +import { describe, expect } from "bun:test" +import { Effect } from "effect" +import { PluginV2 } from "@opencode-ai/core/plugin" +import { AnthropicPlugin } from "@opencode-ai/core/plugin/provider/anthropic" +import { it, model, provider } from "./provider-helper" + +describe("AnthropicPlugin", () => { + it.effect("applies legacy beta headers", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(AnthropicPlugin) + const result = yield* plugin.trigger( + "provider.update", + {}, + { + provider: provider("anthropic", { + options: { headers: { Existing: "1" }, body: {}, aisdk: { provider: {}, request: {} } }, + }), + cancel: false, + }, + ) + expect(result.provider.options.headers["anthropic-beta"]).toBe( + "interleaved-thinking-2025-05-14,fine-grained-tool-streaming-2025-05-14", + ) + expect(result.provider.options.headers.Existing).toBe("1") + }), + ) + + it.effect("ignores non-Anthropic providers", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(AnthropicPlugin) + const result = yield* plugin.trigger("provider.update", {}, { provider: provider("openai"), cancel: false }) + expect(result.provider.options.headers["anthropic-beta"]).toBeUndefined() + }), + ) + + it.effect("creates Anthropic SDKs with the model provider ID as the SDK name", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const providers: string[] = [] + yield* plugin.add(AnthropicPlugin) + yield* plugin.add({ + id: PluginV2.ID.make("anthropic-sdk-inspector"), + effect: Effect.succeed({ + "aisdk.sdk": (evt) => + Effect.sync(() => { + providers.push(evt.sdk.languageModel("claude-sonnet-4-5").provider) + }), + }), + }) + yield* plugin.trigger( + "aisdk.sdk", + { + model: model("custom-anthropic", "claude-sonnet-4-5"), + package: "@ai-sdk/anthropic", + options: { name: "custom-anthropic", apiKey: "test" }, + }, + {}, + ) + expect(providers).toEqual(["custom-anthropic"]) + }), + ) + + it.effect("uses the Anthropic provider ID as the SDK name for the bundled Anthropic provider", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const providers: string[] = [] + yield* plugin.add(AnthropicPlugin) + yield* plugin.add({ + id: PluginV2.ID.make("anthropic-sdk-inspector"), + effect: Effect.succeed({ + "aisdk.sdk": (evt) => + Effect.sync(() => { + providers.push(evt.sdk.languageModel("claude-sonnet-4-5").provider) + }), + }), + }) + yield* plugin.trigger( + "aisdk.sdk", + { + model: model("anthropic", "claude-sonnet-4-5"), + package: "@ai-sdk/anthropic", + options: { name: "anthropic", apiKey: "test" }, + }, + {}, + ) + expect(providers).toEqual(["anthropic"]) + }), + ) +}) diff --git a/packages/core/test/plugin/provider-azure-cognitive-services.test.ts b/packages/core/test/plugin/provider-azure-cognitive-services.test.ts new file mode 100644 index 00000000000..b835cbeeff0 --- /dev/null +++ b/packages/core/test/plugin/provider-azure-cognitive-services.test.ts @@ -0,0 +1,127 @@ +import { describe, expect } from "bun:test" +import { Effect } from "effect" +import { PluginV2 } from "@opencode-ai/core/plugin" +import { AzureCognitiveServicesPlugin } from "@opencode-ai/core/plugin/provider/azure" +import { fakeSelectorSdk, it, model, provider, withEnv } from "./provider-helper" + +describe("AzureCognitiveServicesPlugin", () => { + it.effect("maps the resource env var to the Azure SDK baseURL", () => + withEnv({ AZURE_COGNITIVE_SERVICES_RESOURCE_NAME: "cognitive" }, () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(AzureCognitiveServicesPlugin) + const result = yield* plugin.trigger( + "provider.update", + {}, + { provider: provider("azure-cognitive-services"), cancel: false }, + ) + expect(result.provider.endpoint).toEqual({ + type: "aisdk", + package: "test-provider", + }) + expect(result.provider.options.aisdk.provider.baseURL).toBe( + "https://cognitive.cognitiveservices.azure.com/openai", + ) + expect(result.provider.options.aisdk.provider.resourceName).toBeUndefined() + }), + ), + ) + + it.effect("leaves baseURL unset without resource env and ignores other providers", () => + withEnv({ AZURE_COGNITIVE_SERVICES_RESOURCE_NAME: undefined }, () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(AzureCognitiveServicesPlugin) + const azure = yield* plugin.trigger( + "provider.update", + {}, + { provider: provider("azure-cognitive-services"), cancel: false }, + ) + const other = yield* plugin.trigger("provider.update", {}, { provider: provider("openai"), cancel: false }) + expect(azure.provider.options.aisdk.provider.baseURL).toBeUndefined() + expect(azure.provider.endpoint).toEqual({ type: "aisdk", package: "test-provider" }) + expect(other.provider.options.aisdk.provider.baseURL).toBeUndefined() + expect(other.provider.endpoint).toEqual({ type: "aisdk", package: "test-provider" }) + }), + ), + ) + + it.effect("selects chat only for completion URLs", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const calls: string[] = [] + yield* plugin.add(AzureCognitiveServicesPlugin) + yield* plugin.trigger( + "aisdk.language", + { + model: model("azure-cognitive-services", "deployment"), + sdk: fakeSelectorSdk(calls), + options: { useCompletionUrls: true }, + }, + {}, + ) + expect(calls).toEqual(["chat:deployment"]) + }), + ) + + it.effect("uses the legacy Azure selector order and provider guard", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const calls: string[] = [] + yield* plugin.add(AzureCognitiveServicesPlugin) + yield* plugin.trigger( + "aisdk.language", + { model: model("azure-cognitive-services", "deployment"), sdk: fakeSelectorSdk(calls), options: {} }, + {}, + ) + const ignored = yield* plugin.trigger( + "aisdk.language", + { model: model("openai", "deployment"), sdk: fakeSelectorSdk(calls), options: {} }, + {}, + ) + expect(calls).toEqual(["responses:deployment"]) + expect(ignored.language).toBeUndefined() + }), + ) + + it.effect("falls back from responses to messages, chat, then languageModel", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const calls: string[] = [] + const sdk = fakeSelectorSdk(calls) + yield* plugin.add(AzureCognitiveServicesPlugin) + yield* plugin.trigger( + "aisdk.language", + { + model: model("azure-cognitive-services", "messages-deployment"), + sdk: { messages: sdk.messages, chat: sdk.chat, languageModel: sdk.languageModel }, + options: {}, + }, + {}, + ) + yield* plugin.trigger( + "aisdk.language", + { + model: model("azure-cognitive-services", "chat-deployment"), + sdk: { chat: sdk.chat, languageModel: sdk.languageModel }, + options: {}, + }, + {}, + ) + yield* plugin.trigger( + "aisdk.language", + { + model: model("azure-cognitive-services", "language-deployment"), + sdk: { languageModel: sdk.languageModel }, + options: {}, + }, + {}, + ) + expect(calls).toEqual([ + "messages:messages-deployment", + "chat:chat-deployment", + "languageModel:language-deployment", + ]) + }), + ) +}) diff --git a/packages/core/test/plugin/provider-azure.test.ts b/packages/core/test/plugin/provider-azure.test.ts new file mode 100644 index 00000000000..5121b1eec02 --- /dev/null +++ b/packages/core/test/plugin/provider-azure.test.ts @@ -0,0 +1,245 @@ +import { describe, expect } from "bun:test" +import { Effect, Layer } from "effect" +import { AuthV2 } from "@opencode-ai/core/auth" +import { PluginV2 } from "@opencode-ai/core/plugin" +import { AuthPlugin } from "@opencode-ai/core/plugin/auth" +import { AzurePlugin } from "@opencode-ai/core/plugin/provider/azure" +import { testEffect } from "../lib/effect" +import { fakeSelectorSdk, it, model, npmLayer, provider, withEnv } from "./provider-helper" + +const itWithAuth = testEffect(Layer.mergeAll(PluginV2.defaultLayer, AuthV2.defaultLayer, npmLayer)) + +describe("AzurePlugin", () => { + it.effect("resolves resourceName from env", () => + withEnv({ AZURE_RESOURCE_NAME: "from-env" }, () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(AzurePlugin) + const result = yield* plugin.trigger("provider.update", {}, { provider: provider("azure"), cancel: false }) + expect(result.provider.options.aisdk.provider.resourceName).toBe("from-env") + }), + ), + ) + + it.effect("keeps explicit resourceName over env and ignores other providers", () => + withEnv({ AZURE_RESOURCE_NAME: "from-env" }, () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(AzurePlugin) + const azure = yield* plugin.trigger( + "provider.update", + {}, + { + provider: provider("azure", { + options: { headers: {}, body: {}, aisdk: { provider: { resourceName: "from-config" }, request: {} } }, + }), + cancel: false, + }, + ) + const other = yield* plugin.trigger("provider.update", {}, { provider: provider("openai"), cancel: false }) + expect(azure.provider.options.aisdk.provider.resourceName).toBe("from-config") + expect(other.provider.options.aisdk.provider.resourceName).toBeUndefined() + }), + ), + ) + + itWithAuth.effect("prefers auth resourceName over env", () => + withEnv( + { + AZURE_RESOURCE_NAME: "from-env", + }, + () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const auth = yield* AuthV2.Service + yield* auth.create({ + serviceID: AuthV2.ServiceID.make("azure"), + credential: new AuthV2.ApiKeyCredential({ + type: "api", + key: "key", + metadata: { resourceName: "from-auth" }, + }), + active: true, + }) + yield* plugin.add({ + ...AuthPlugin, + effect: AuthPlugin.effect.pipe(Effect.provideService(AuthV2.Service, auth)), + }) + yield* plugin.add(AzurePlugin) + const result = yield* plugin.trigger("provider.update", {}, { provider: provider("azure"), cancel: false }) + expect(result.provider.options.aisdk.provider.resourceName).toBe("from-auth") + }), + ), + ) + + it.effect("falls back to env when configured resourceName is blank", () => + withEnv({ AZURE_RESOURCE_NAME: "from-env" }, () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(AzurePlugin) + const result = yield* plugin.trigger( + "provider.update", + {}, + { + provider: provider("azure", { + options: { headers: {}, body: {}, aisdk: { provider: { resourceName: "" }, request: {} } }, + }), + cancel: false, + }, + ) + expect(result.provider.options.aisdk.provider.resourceName).toBe("from-env") + }), + ), + ) + + it.effect("falls back to env when configured resourceName is whitespace", () => + withEnv({ AZURE_RESOURCE_NAME: "from-env" }, () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(AzurePlugin) + const result = yield* plugin.trigger( + "provider.update", + {}, + { + provider: provider("azure", { + options: { headers: {}, body: {}, aisdk: { provider: { resourceName: " " }, request: {} } }, + }), + cancel: false, + }, + ) + expect(result.provider.options.aisdk.provider.resourceName).toBe("from-env") + }), + ), + ) + + it.effect("allows configured baseURL without resourceName", () => + withEnv({ AZURE_RESOURCE_NAME: undefined }, () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(AzurePlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("azure", "deployment"), + package: "@ai-sdk/azure", + options: { name: "azure", baseURL: "https://proxy.example.com/openai" }, + }, + {}, + ) + expect(result.sdk).toBeDefined() + }), + ), + ) + + it.effect("rejects missing resourceName when baseURL is not configured", () => + withEnv({ AZURE_RESOURCE_NAME: undefined }, () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(AzurePlugin) + const exit = yield* plugin + .trigger( + "aisdk.sdk", + { model: model("azure", "deployment"), package: "@ai-sdk/azure", options: { name: "azure" } }, + {}, + ) + .pipe(Effect.exit) + expect(exit._tag).toBe("Failure") + }), + ), + ) + + it.effect("selects chat only for completion URLs", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const calls: string[] = [] + yield* plugin.add(AzurePlugin) + yield* plugin.trigger( + "aisdk.language", + { model: model("azure", "deployment"), sdk: fakeSelectorSdk(calls), options: { useCompletionUrls: true } }, + {}, + ) + expect(calls).toEqual(["chat:deployment"]) + }), + ) + + it.effect("selects chat from per-call useCompletionUrls", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const calls: string[] = [] + yield* plugin.add(AzurePlugin) + yield* plugin.trigger( + "aisdk.language", + { model: model("azure", "deployment"), sdk: fakeSelectorSdk(calls), options: { useCompletionUrls: true } }, + {}, + ) + expect(calls).toEqual(["chat:deployment"]) + }), + ) + + it.effect("ignores model useCompletionUrls when per-call option is unset", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const calls: string[] = [] + yield* plugin.add(AzurePlugin) + yield* plugin.trigger( + "aisdk.language", + { + model: model("azure", "deployment", { + options: { headers: {}, body: {}, aisdk: { provider: {}, request: { useCompletionUrls: true } } }, + }), + sdk: fakeSelectorSdk(calls), + options: {}, + }, + {}, + ) + expect(calls).toEqual(["responses:deployment"]) + }), + ) + + it.effect("uses the legacy Azure selector order and provider guard", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const calls: string[] = [] + yield* plugin.add(AzurePlugin) + yield* plugin.trigger( + "aisdk.language", + { model: model("azure", "deployment"), sdk: fakeSelectorSdk(calls), options: {} }, + {}, + ) + const ignored = yield* plugin.trigger( + "aisdk.language", + { model: model("openai", "deployment"), sdk: fakeSelectorSdk(calls), options: {} }, + {}, + ) + expect(calls).toEqual(["responses:deployment"]) + expect(ignored.language).toBeUndefined() + }), + ) + + it.effect("falls back through the legacy Azure selector order", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const calls: string[] = [] + const make = (method: string) => (id: string) => { + calls.push(`${method}:${id}`) + return { modelId: id, provider: method, specificationVersion: "v3" } + } + yield* plugin.add(AzurePlugin) + yield* plugin.trigger( + "aisdk.language", + { + model: model("azure", "messages-deployment"), + sdk: { messages: make("messages"), chat: make("chat"), languageModel: make("languageModel") }, + options: {}, + }, + {}, + ) + yield* plugin.trigger( + "aisdk.language", + { model: model("azure", "language-deployment"), sdk: { languageModel: make("languageModel") }, options: {} }, + {}, + ) + expect(calls).toEqual(["messages:messages-deployment", "languageModel:language-deployment"]) + }), + ) +}) diff --git a/packages/core/test/plugin/provider-cerebras.test.ts b/packages/core/test/plugin/provider-cerebras.test.ts new file mode 100644 index 00000000000..7270d5367ae --- /dev/null +++ b/packages/core/test/plugin/provider-cerebras.test.ts @@ -0,0 +1,102 @@ +import { describe, expect, mock } from "bun:test" +import { Effect } from "effect" +import { PluginV2 } from "@opencode-ai/core/plugin" +import { CerebrasPlugin } from "@opencode-ai/core/plugin/provider/cerebras" +import { it, model, provider } from "./provider-helper" + +const cerebrasOptions: Record[] = [] + +void mock.module("@ai-sdk/cerebras", () => ({ + createCerebras: (options: Record) => { + const snapshot = { ...options } + cerebrasOptions.push(snapshot) + return { + languageModel: (modelID: string) => ({ modelID, provider: snapshot.name, specificationVersion: "v3" }), + } + }, +})) + +describe("CerebrasPlugin", () => { + it.effect("applies the legacy integration header", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(CerebrasPlugin) + const result = yield* plugin.trigger( + "provider.update", + {}, + { + provider: provider("cerebras", { + options: { headers: { Existing: "1" }, body: {}, aisdk: { provider: {}, request: {} } }, + }), + cancel: false, + }, + ) + expect(result.provider.options.headers).toEqual({ Existing: "1", "X-Cerebras-3rd-Party-Integration": "opencode" }) + }), + ) + + it.effect("ignores non-Cerebras providers", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(CerebrasPlugin) + const result = yield* plugin.trigger("provider.update", {}, { provider: provider("groq"), cancel: false }) + expect(result.provider.options.headers).toEqual({}) + }), + ) + + it.effect("creates a bundled Cerebras SDK with the model provider ID as the SDK name", () => + Effect.gen(function* () { + cerebrasOptions.length = 0 + const plugin = yield* PluginV2.Service + yield* plugin.add(CerebrasPlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("custom-cerebras", "llama-4-scout-17b-16e-instruct"), + package: "@ai-sdk/cerebras", + options: { name: "custom-cerebras", apiKey: "test" }, + }, + {}, + ) + expect(cerebrasOptions).toEqual([{ name: "custom-cerebras", apiKey: "test" }]) + expect(result.sdk.languageModel("llama-4-scout-17b-16e-instruct").provider).toBe("custom-cerebras") + }), + ) + + it.effect("preserves an explicit bundled Cerebras SDK name option", () => + Effect.gen(function* () { + cerebrasOptions.length = 0 + const plugin = yield* PluginV2.Service + yield* plugin.add(CerebrasPlugin) + yield* plugin.trigger( + "aisdk.sdk", + { + model: model("custom-cerebras", "llama-4-scout-17b-16e-instruct"), + package: "@ai-sdk/cerebras", + options: { name: "configured-cerebras", apiKey: "test" }, + }, + {}, + ) + expect(cerebrasOptions).toEqual([{ name: "configured-cerebras", apiKey: "test" }]) + }), + ) + + it.effect("ignores non-Cerebras SDK packages", () => + Effect.gen(function* () { + cerebrasOptions.length = 0 + const plugin = yield* PluginV2.Service + yield* plugin.add(CerebrasPlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("custom-cerebras", "llama-4-scout-17b-16e-instruct"), + package: "@ai-sdk/groq", + options: { name: "custom-cerebras", apiKey: "test" }, + }, + {}, + ) + expect(cerebrasOptions).toEqual([]) + expect(result.sdk).toBeUndefined() + }), + ) +}) diff --git a/packages/core/test/plugin/provider-cloudflare-ai-gateway.test.ts b/packages/core/test/plugin/provider-cloudflare-ai-gateway.test.ts new file mode 100644 index 00000000000..72ad5da33f1 --- /dev/null +++ b/packages/core/test/plugin/provider-cloudflare-ai-gateway.test.ts @@ -0,0 +1,384 @@ +import { describe, expect, mock } from "bun:test" +import { Effect } from "effect" +import { PluginV2 } from "@opencode-ai/core/plugin" +import { CloudflareAIGatewayPlugin } from "@opencode-ai/core/plugin/provider/cloudflare-ai-gateway" +import { it, model, withEnv } from "./provider-helper" + +const aiGatewayCalls: Record[] = [] +const unifiedCalls: string[] = [] +const gatewayModelCalls: unknown[] = [] + +function captureAiGatewayOptions(options: Record) { + const nested = + options.options && typeof options.options === "object" ? (options.options as Record) : undefined + return { + ...options, + ...(nested + ? { + options: { + ...nested, + headers: + nested.headers && typeof nested.headers === "object" + ? { ...(nested.headers as Record) } + : nested.headers, + }, + } + : {}), + } +} + +function resetCalls() { + aiGatewayCalls.length = 0 + unifiedCalls.length = 0 + gatewayModelCalls.length = 0 +} + +function cloudflareEnv(overrides: Record = {}) { + return { + CLOUDFLARE_ACCOUNT_ID: "env-account", + CLOUDFLARE_GATEWAY_ID: "env-gateway", + CLOUDFLARE_API_TOKEN: "env-token", + CF_AIG_TOKEN: undefined, + ...overrides, + } +} + +mock.module("ai-gateway-provider", () => ({ + createAiGateway(options: Record) { + aiGatewayCalls.push(captureAiGatewayOptions(options)) + return (input: unknown) => { + gatewayModelCalls.push(input) + return { + modelId: input, + provider: "cloudflare-ai-gateway", + specificationVersion: "v3", + } + } + }, +})) + +mock.module("ai-gateway-provider/providers/unified", () => ({ + createUnified() { + return (modelID: string) => { + unifiedCalls.push(modelID) + return { unifiedModelID: modelID } + } + }, +})) + +describe("CloudflareAIGatewayPlugin", () => { + it.effect("requires account, gateway, and token before creating the unified SDK", () => + withEnv( + { + CLOUDFLARE_ACCOUNT_ID: "acct", + CLOUDFLARE_GATEWAY_ID: "gateway", + CLOUDFLARE_API_TOKEN: "token", + CF_AIG_TOKEN: undefined, + }, + () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(CloudflareAIGatewayPlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("cloudflare-ai-gateway", "openai/gpt-5"), + package: "ai-gateway-provider", + options: { name: "cloudflare-ai-gateway" }, + }, + {}, + ) + expect(result.sdk.languageModel("openai/gpt-5")).toBeDefined() + }), + ), + ) + + it.effect("passes legacy metadata, cache, log, and User-Agent values under the AI Gateway options key", () => + withEnv(cloudflareEnv(), () => + Effect.gen(function* () { + resetCalls() + const plugin = yield* PluginV2.Service + yield* plugin.add(CloudflareAIGatewayPlugin) + + yield* plugin.trigger( + "aisdk.sdk", + { + model: model("cloudflare-ai-gateway", "openai/gpt-5"), + package: "ai-gateway-provider", + options: { + name: "cloudflare-ai-gateway", + metadata: { invoked_by: "test", project: "opencode" }, + cacheTtl: 300, + cacheKey: "cache-key", + skipCache: true, + collectLog: false, + }, + }, + {}, + ) + + expect(aiGatewayCalls).toHaveLength(1) + expect(aiGatewayCalls[0]).toEqual({ + accountId: "env-account", + gateway: "env-gateway", + apiKey: "env-token", + options: { + metadata: { invoked_by: "test", project: "opencode" }, + cacheTtl: 300, + cacheKey: "cache-key", + skipCache: true, + collectLog: false, + headers: { + "User-Agent": expect.stringContaining("opencode/"), + }, + }, + }) + }), + ), + ) + + it.effect("parses legacy cf-aig-metadata header when metadata option is absent", () => + withEnv(cloudflareEnv(), () => + Effect.gen(function* () { + resetCalls() + const plugin = yield* PluginV2.Service + yield* plugin.add(CloudflareAIGatewayPlugin) + + yield* plugin.trigger( + "aisdk.sdk", + { + model: model("cloudflare-ai-gateway", "openai/gpt-5"), + package: "ai-gateway-provider", + options: { + name: "cloudflare-ai-gateway", + headers: { + "cf-aig-metadata": JSON.stringify({ invoked_by: "header", project: "opencode" }), + }, + }, + }, + {}, + ) + + expect(aiGatewayCalls[0]?.options).toMatchObject({ + metadata: { invoked_by: "header", project: "opencode" }, + }) + }), + ), + ) + + it.effect("prefers Cloudflare env values over auth/config-derived options", () => + withEnv(cloudflareEnv(), () => + Effect.gen(function* () { + resetCalls() + const plugin = yield* PluginV2.Service + yield* plugin.add(CloudflareAIGatewayPlugin) + + yield* plugin.trigger( + "aisdk.sdk", + { + model: model("cloudflare-ai-gateway", "openai/gpt-5"), + package: "ai-gateway-provider", + options: { + name: "cloudflare-ai-gateway", + accountId: "auth-account", + gateway: "auth-gateway", + apiKey: "auth-token", + }, + }, + {}, + ) + + expect(aiGatewayCalls[0]).toMatchObject({ + accountId: "env-account", + gateway: "env-gateway", + apiKey: "env-token", + }) + }), + ), + ) + + it.effect("accepts gatewayId metadata copied from auth into provider options", () => + withEnv( + cloudflareEnv({ + CLOUDFLARE_ACCOUNT_ID: undefined, + CLOUDFLARE_GATEWAY_ID: undefined, + CLOUDFLARE_API_TOKEN: undefined, + }), + () => + Effect.gen(function* () { + resetCalls() + const plugin = yield* PluginV2.Service + yield* plugin.add(CloudflareAIGatewayPlugin) + + yield* plugin.trigger( + "aisdk.sdk", + { + model: model("cloudflare-ai-gateway", "openai/gpt-5"), + package: "ai-gateway-provider", + options: { + name: "cloudflare-ai-gateway", + accountId: "auth-account", + gatewayId: "auth-gateway", + apiKey: "auth-token", + }, + }, + {}, + ) + + expect(aiGatewayCalls[0]).toMatchObject({ + accountId: "auth-account", + gateway: "auth-gateway", + apiKey: "auth-token", + }) + }), + ), + ) + + it.effect("falls back to CF_AIG_TOKEN when CLOUDFLARE_API_TOKEN is unset", () => + withEnv(cloudflareEnv({ CLOUDFLARE_API_TOKEN: undefined, CF_AIG_TOKEN: "cf-aig-token" }), () => + Effect.gen(function* () { + resetCalls() + const plugin = yield* PluginV2.Service + yield* plugin.add(CloudflareAIGatewayPlugin) + + yield* plugin.trigger( + "aisdk.sdk", + { + model: model("cloudflare-ai-gateway", "openai/gpt-5"), + package: "ai-gateway-provider", + options: { name: "cloudflare-ai-gateway" }, + }, + {}, + ) + + expect(aiGatewayCalls[0]).toMatchObject({ apiKey: "cf-aig-token" }) + }), + ), + ) + + it.effect("does not create an SDK when account and gateway IDs are missing", () => + withEnv(cloudflareEnv({ CLOUDFLARE_ACCOUNT_ID: undefined, CLOUDFLARE_GATEWAY_ID: undefined }), () => + Effect.gen(function* () { + resetCalls() + const plugin = yield* PluginV2.Service + yield* plugin.add(CloudflareAIGatewayPlugin) + + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("cloudflare-ai-gateway", "openai/gpt-5"), + package: "ai-gateway-provider", + options: { name: "cloudflare-ai-gateway" }, + }, + {}, + ) + + expect(result.sdk).toBeUndefined() + expect(aiGatewayCalls).toHaveLength(0) + }), + ), + ) + + it.effect("does not create an SDK when the token is missing", () => + withEnv(cloudflareEnv({ CLOUDFLARE_API_TOKEN: undefined, CF_AIG_TOKEN: undefined }), () => + Effect.gen(function* () { + resetCalls() + const plugin = yield* PluginV2.Service + yield* plugin.add(CloudflareAIGatewayPlugin) + + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("cloudflare-ai-gateway", "openai/gpt-5"), + package: "ai-gateway-provider", + options: { name: "cloudflare-ai-gateway" }, + }, + {}, + ) + + expect(result.sdk).toBeUndefined() + expect(aiGatewayCalls).toHaveLength(0) + }), + ), + ) + + it.effect("does not replace a configured baseURL with the Cloudflare AI Gateway SDK", () => + withEnv( + cloudflareEnv({ + CLOUDFLARE_ACCOUNT_ID: undefined, + CLOUDFLARE_GATEWAY_ID: undefined, + CLOUDFLARE_API_TOKEN: undefined, + }), + () => + Effect.gen(function* () { + resetCalls() + const plugin = yield* PluginV2.Service + yield* plugin.add(CloudflareAIGatewayPlugin) + + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("cloudflare-ai-gateway", "openai/gpt-5"), + package: "ai-gateway-provider", + options: { name: "cloudflare-ai-gateway", baseURL: "https://proxy.example/v1" }, + }, + {}, + ) + + expect(result.sdk).toBeUndefined() + expect(aiGatewayCalls).toHaveLength(0) + }), + ), + ) + + it.effect("maps provider/model IDs through the unified Cloudflare provider unchanged", () => + withEnv(cloudflareEnv(), () => + Effect.gen(function* () { + resetCalls() + const plugin = yield* PluginV2.Service + yield* plugin.add(CloudflareAIGatewayPlugin) + + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("cloudflare-ai-gateway", "anthropic/claude-sonnet-4-5"), + package: "ai-gateway-provider", + options: { name: "cloudflare-ai-gateway" }, + }, + {}, + ) + + expect(result.sdk.languageModel("anthropic/claude-sonnet-4-5")).toEqual({ + modelId: { unifiedModelID: "anthropic/claude-sonnet-4-5" }, + provider: "cloudflare-ai-gateway", + specificationVersion: "v3", + }) + expect(unifiedCalls).toEqual(["anthropic/claude-sonnet-4-5"]) + expect(gatewayModelCalls).toEqual([{ unifiedModelID: "anthropic/claude-sonnet-4-5" }]) + }), + ), + ) + + it.effect("ignores non Cloudflare AI Gateway packages", () => + withEnv(cloudflareEnv(), () => + Effect.gen(function* () { + resetCalls() + const plugin = yield* PluginV2.Service + yield* plugin.add(CloudflareAIGatewayPlugin) + + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("cloudflare-ai-gateway", "openai/gpt-5"), + package: "@ai-sdk/openai-compatible", + options: { name: "cloudflare-ai-gateway" }, + }, + {}, + ) + + expect(result.sdk).toBeUndefined() + expect(aiGatewayCalls).toHaveLength(0) + }), + ), + ) +}) diff --git a/packages/core/test/plugin/provider-cloudflare-workers-ai.test.ts b/packages/core/test/plugin/provider-cloudflare-workers-ai.test.ts new file mode 100644 index 00000000000..10aba171c33 --- /dev/null +++ b/packages/core/test/plugin/provider-cloudflare-workers-ai.test.ts @@ -0,0 +1,267 @@ +import { describe, expect } from "bun:test" +import { Effect, Layer } from "effect" +import { AuthV2 } from "@opencode-ai/core/auth" +import { ModelV2 } from "@opencode-ai/core/model" +import { PluginV2 } from "@opencode-ai/core/plugin" +import { AuthPlugin } from "@opencode-ai/core/plugin/auth" +import { CloudflareWorkersAIPlugin } from "@opencode-ai/core/plugin/provider/cloudflare-workers-ai" +import { testEffect } from "../lib/effect" +import { fakeSelectorSdk, it, model, npmLayer, provider, withEnv } from "./provider-helper" + +const itWithAuth = testEffect(Layer.mergeAll(PluginV2.defaultLayer, AuthV2.defaultLayer, npmLayer)) + +function cloudflareLanguage(sdk: unknown, modelID = "@cf/model") { + return (sdk as { languageModel: (id: string) => { config: CloudflareConfig; provider: string } }).languageModel( + modelID, + ) +} + +type CloudflareConfig = { + url: (input: { path: string; modelId: string }) => string + headers: () => Record | Promise> +} + +function cloudflareURL(sdk: unknown, modelID = "@cf/model") { + return cloudflareLanguage(sdk, modelID).config.url({ path: "/chat/completions", modelId: modelID }) +} + +function cloudflareHeaders(sdk: unknown, modelID = "@cf/model") { + return cloudflareLanguage(sdk, modelID).config.headers() +} + +describe("CloudflareWorkersAIPlugin", () => { + it.effect("maps account ID to endpoint URL and creates an OpenAI-compatible SDK", () => + withEnv({ CLOUDFLARE_ACCOUNT_ID: "acct", CLOUDFLARE_API_KEY: "key" }, () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(CloudflareWorkersAIPlugin) + const updated = yield* plugin.trigger( + "provider.update", + {}, + { provider: provider("cloudflare-workers-ai"), cancel: false }, + ) + const sdk = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("cloudflare-workers-ai", "@cf/model", { endpoint: updated.provider.endpoint }), + package: "@ai-sdk/openai-compatible", + options: { name: "cloudflare-workers-ai", headers: { custom: "header" } }, + }, + {}, + ) + expect(updated.provider.endpoint).toEqual({ + type: "aisdk", + package: "test-provider", + url: "https://api.cloudflare.com/client/v4/accounts/acct/ai/v1", + }) + expect(sdk.sdk).toBeDefined() + }), + ), + ) + + it.effect("preserves a configured endpoint URL instead of deriving one from account ID", () => + withEnv({ CLOUDFLARE_ACCOUNT_ID: "acct" }, () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(CloudflareWorkersAIPlugin) + const result = yield* plugin.trigger( + "provider.update", + {}, + { + provider: provider("cloudflare-workers-ai", { + endpoint: { type: "aisdk", package: "test-provider", url: "https://proxy.example/v1" }, + }), + cancel: false, + }, + ) + expect(result.provider.endpoint).toEqual({ + type: "aisdk", + package: "test-provider", + url: "https://proxy.example/v1", + }) + }), + ), + ) + + it.effect("allows a configured baseURL without account ID", () => + withEnv({ CLOUDFLARE_ACCOUNT_ID: undefined, CLOUDFLARE_API_KEY: "key" }, () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(CloudflareWorkersAIPlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("cloudflare-workers-ai", "@cf/model", { + endpoint: { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://proxy.example/v1" }, + }), + package: "@ai-sdk/openai-compatible", + options: { name: "cloudflare-workers-ai", baseURL: "https://proxy.example/v1" }, + }, + {}, + ) + expect(cloudflareURL(result.sdk)).toBe("https://proxy.example/v1/chat/completions") + }), + ), + ) + + itWithAuth.effect("falls back to auth account metadata when account env is absent", () => + withEnv( + { + CLOUDFLARE_ACCOUNT_ID: undefined, + CLOUDFLARE_API_KEY: undefined, + }, + () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const auth = yield* AuthV2.Service + yield* auth.create({ + serviceID: AuthV2.ServiceID.make("cloudflare-workers-ai"), + credential: new AuthV2.ApiKeyCredential({ + type: "api", + key: "auth-key", + metadata: { accountId: "auth-acct" }, + }), + active: true, + }) + yield* plugin.add({ + ...AuthPlugin, + effect: AuthPlugin.effect.pipe(Effect.provideService(AuthV2.Service, auth)), + }) + yield* plugin.add(CloudflareWorkersAIPlugin) + const updated = yield* plugin.trigger( + "provider.update", + {}, + { provider: provider("cloudflare-workers-ai"), cancel: false }, + ) + expect(updated.provider.endpoint).toEqual({ + type: "aisdk", + package: "test-provider", + url: "https://api.cloudflare.com/client/v4/accounts/auth-acct/ai/v1", + }) + }), + ), + ) + + it.effect("uses env account ID over configured account ID", () => + withEnv({ CLOUDFLARE_ACCOUNT_ID: "env-acct" }, () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(CloudflareWorkersAIPlugin) + const result = yield* plugin.trigger( + "provider.update", + {}, + { + provider: provider("cloudflare-workers-ai", { + options: { headers: {}, body: {}, aisdk: { provider: { accountId: "configured-acct" }, request: {} } }, + }), + cancel: false, + }, + ) + expect(result.provider.endpoint).toEqual({ + type: "aisdk", + package: "test-provider", + url: "https://api.cloudflare.com/client/v4/accounts/env-acct/ai/v1", + }) + }), + ), + ) + + it.effect("uses env API key over auth or configured API key and keeps the Cloudflare User-Agent", () => + withEnv({ CLOUDFLARE_ACCOUNT_ID: "acct", CLOUDFLARE_API_KEY: "env-key" }, () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(CloudflareWorkersAIPlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("cloudflare-workers-ai", "@cf/model", { + endpoint: { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://proxy.example/v1" }, + }), + package: "@ai-sdk/openai-compatible", + options: { + name: "cloudflare-workers-ai", + apiKey: "auth-key", + baseURL: "https://proxy.example/v1", + headers: { custom: "header" }, + }, + }, + {}, + ) + const headers = yield* Effect.promise(() => Promise.resolve(cloudflareHeaders(result.sdk))) + expect(headers.authorization).toBe("Bearer env-key") + expect(headers.custom).toBe("header") + expect(headers["user-agent"]).toMatch(/^opencode\/.* cloudflare-workers-ai \(.+\) ai-sdk\/openai-compatible\//) + }), + ), + ) + + it.effect("expands account ID vars in endpoint URLs", () => + withEnv({ CLOUDFLARE_ACCOUNT_ID: "acct", CLOUDFLARE_API_KEY: "key" }, () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(CloudflareWorkersAIPlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("cloudflare-workers-ai", "@cf/model", { + endpoint: { + type: "aisdk", + package: "@ai-sdk/openai-compatible", + url: "https://api.cloudflare.com/client/v4/accounts/${CLOUDFLARE_ACCOUNT_ID}/ai/v1", + }, + }), + package: "@ai-sdk/openai-compatible", + options: { + name: "cloudflare-workers-ai", + baseURL: "https://api.cloudflare.com/client/v4/accounts/${CLOUDFLARE_ACCOUNT_ID}/ai/v1", + }, + }, + {}, + ) + expect(cloudflareURL(result.sdk)).toBe( + "https://api.cloudflare.com/client/v4/accounts/acct/ai/v1/chat/completions", + ) + }), + ), + ) + + it.effect("selects languageModel with the API model ID", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const calls: string[] = [] + yield* plugin.add(CloudflareWorkersAIPlugin) + const result = yield* plugin.trigger( + "aisdk.language", + { + model: model("cloudflare-workers-ai", "alias", { apiID: ModelV2.ID.make("@cf/api-model") }), + sdk: fakeSelectorSdk(calls), + options: {}, + }, + {}, + ) + expect(result.language).toBeDefined() + expect(calls).toEqual(["languageModel:@cf/api-model"]) + }), + ) + + it.effect("does not create an SDK for non OpenAI-compatible packages", () => + withEnv({ CLOUDFLARE_ACCOUNT_ID: "acct", CLOUDFLARE_API_KEY: "key" }, () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(CloudflareWorkersAIPlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("cloudflare-workers-ai", "@cf/model", { + endpoint: { type: "aisdk", package: "@ai-sdk/anthropic", url: "https://proxy.example/v1" }, + }), + package: "@ai-sdk/anthropic", + options: { name: "cloudflare-workers-ai" }, + }, + {}, + ) + expect(result.sdk).toBeUndefined() + }), + ), + ) +}) diff --git a/packages/core/test/plugin/provider-cohere.test.ts b/packages/core/test/plugin/provider-cohere.test.ts new file mode 100644 index 00000000000..54bec2cec45 --- /dev/null +++ b/packages/core/test/plugin/provider-cohere.test.ts @@ -0,0 +1,86 @@ +import { describe, expect, mock } from "bun:test" +import { Effect } from "effect" +import { ModelV2 } from "@opencode-ai/core/model" +import { PluginV2 } from "@opencode-ai/core/plugin" +import { CoherePlugin } from "@opencode-ai/core/plugin/provider/cohere" +import { fakeSelectorSdk, it, model } from "./provider-helper" + +const cohereOptions: Record[] = [] + +void mock.module("@ai-sdk/cohere", () => ({ + createCohere: (options: Record) => { + cohereOptions.push({ ...options }) + return { + languageModel: (modelID: string) => ({ + modelID, + provider: `${options.name ?? "cohere"}.chat`, + specificationVersion: "v3", + }), + } + }, +})) + +describe("CoherePlugin", () => { + it.effect("creates a Cohere SDK only for @ai-sdk/cohere", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(CoherePlugin) + + const ignored = yield* plugin.trigger( + "aisdk.sdk", + { model: model("cohere", "command"), package: "@ai-sdk/openai-compatible", options: { name: "cohere" } }, + {}, + ) + expect(ignored.sdk).toBeUndefined() + + const result = yield* plugin.trigger( + "aisdk.sdk", + { model: model("cohere", "command"), package: "@ai-sdk/cohere", options: { name: "cohere" } }, + {}, + ) + expect(result.sdk).toBeDefined() + }), + ) + + it.effect("uses the model provider ID as the bundled SDK name", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(CoherePlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("custom-cohere", "command-r-plus"), + package: "@ai-sdk/cohere", + options: { name: "custom-cohere", apiKey: "test", baseURL: "https://cohere.example" }, + }, + {}, + ) + + expect(cohereOptions.at(-1)).toEqual({ + name: "custom-cohere", + apiKey: "test", + baseURL: "https://cohere.example", + }) + expect(result.sdk?.languageModel("command-r-plus").provider).toBe("custom-cohere.chat") + }), + ) + + it.effect("leaves language selection to the default languageModel fallback", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const calls: string[] = [] + const sdk = fakeSelectorSdk(calls) + yield* plugin.add(CoherePlugin) + const result = yield* plugin.trigger( + "aisdk.language", + { model: model("cohere", "alias", { apiID: ModelV2.ID.make("command-r-plus") }), sdk, options: {} }, + {}, + ) + + expect(result.language).toBeUndefined() + expect(calls).toEqual([]) + expect(result.language ?? sdk.languageModel("command-r-plus")).toBeDefined() + expect(calls).toEqual(["languageModel:command-r-plus"]) + }), + ) +}) diff --git a/packages/core/test/plugin/provider-deepinfra.test.ts b/packages/core/test/plugin/provider-deepinfra.test.ts new file mode 100644 index 00000000000..9a9cb861eaf --- /dev/null +++ b/packages/core/test/plugin/provider-deepinfra.test.ts @@ -0,0 +1,129 @@ +import { describe, expect, mock } from "bun:test" +import { Effect, Layer } from "effect" +import { AISDK } from "@opencode-ai/core/aisdk" +import { PluginV2 } from "@opencode-ai/core/plugin" +import { DeepInfraPlugin } from "@opencode-ai/core/plugin/provider/deepinfra" +import { testEffect } from "../lib/effect" +import { it, model } from "./provider-helper" + +const itAISDK = testEffect(Layer.provideMerge(AISDK.layer, PluginV2.defaultLayer)) +const deepinfraOptions: Record[] = [] +const deepinfraLanguageModels: string[] = [] + +void mock.module("@ai-sdk/deepinfra", () => ({ + createDeepInfra: (options: Record) => { + const captured = { ...options } + deepinfraOptions.push(captured) + return { + languageModel: (modelID: string) => { + deepinfraLanguageModels.push(modelID) + return { modelID, provider: `${captured.name ?? "deepinfra"}.chat`, specificationVersion: "v3" } + }, + } + }, +})) + +function resetDeepInfraMock() { + deepinfraOptions.length = 0 + deepinfraLanguageModels.length = 0 +} + +describe("DeepInfraPlugin", () => { + it.effect("creates a DeepInfra SDK for @ai-sdk/deepinfra", () => + Effect.gen(function* () { + resetDeepInfraMock() + const plugin = yield* PluginV2.Service + yield* plugin.add(DeepInfraPlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { model: model("deepinfra", "model"), package: "@ai-sdk/deepinfra", options: { name: "deepinfra" } }, + {}, + ) + expect(result.sdk).toBeDefined() + }), + ) + + it.effect("passes the model provider ID as the bundled DeepInfra SDK name", () => + Effect.gen(function* () { + resetDeepInfraMock() + const plugin = yield* PluginV2.Service + yield* plugin.add(DeepInfraPlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("custom-deepinfra", "model"), + package: "@ai-sdk/deepinfra", + options: { name: "custom-deepinfra", apiKey: "test" }, + }, + {}, + ) + expect(result.sdk.languageModel("model").provider).toBe("custom-deepinfra.chat") + expect(deepinfraOptions).toEqual([{ name: "custom-deepinfra", apiKey: "test" }]) + }), + ) + + it.effect("uses the canonical provider ID as the bundled DeepInfra SDK name", () => + Effect.gen(function* () { + resetDeepInfraMock() + const plugin = yield* PluginV2.Service + yield* plugin.add(DeepInfraPlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("deepinfra", "model"), + package: "@ai-sdk/deepinfra", + options: { name: "deepinfra", apiKey: "test" }, + }, + {}, + ) + expect(result.sdk.languageModel("model").provider).toBe("deepinfra.chat") + expect(deepinfraOptions).toEqual([{ name: "deepinfra", apiKey: "test" }]) + }), + ) + + it.effect("matches only the exact bundled DeepInfra package", () => + Effect.gen(function* () { + resetDeepInfraMock() + const plugin = yield* PluginV2.Service + yield* plugin.add(DeepInfraPlugin) + const packages = [ + "unmatched-package", + "@ai-sdk/deepinfra-compatible", + "file:///tmp/@ai-sdk/deepinfra-provider.js", + ] + yield* Effect.forEach(packages, (item) => + Effect.gen(function* () { + const ignored = yield* plugin.trigger( + "aisdk.sdk", + { model: model("deepinfra", "model"), package: item, options: { name: "deepinfra" } }, + {}, + ) + expect(ignored.sdk).toBeUndefined() + }), + ) + const result = yield* plugin.trigger( + "aisdk.sdk", + { model: model("deepinfra", "model"), package: "@ai-sdk/deepinfra", options: { name: "deepinfra" } }, + {}, + ) + expect(result.sdk).toBeDefined() + expect(deepinfraOptions).toEqual([{ name: "deepinfra" }]) + }), + ) + + itAISDK.effect("uses the default languageModel selection for DeepInfra models", () => + Effect.gen(function* () { + resetDeepInfraMock() + const plugin = yield* PluginV2.Service + const aisdk = yield* AISDK.Service + yield* plugin.add(DeepInfraPlugin) + const language = yield* aisdk.language( + model("deepinfra", "meta-llama/Llama-3.3-70B-Instruct", { + endpoint: { type: "aisdk", package: "@ai-sdk/deepinfra" }, + }), + ) + expect(language.provider).toBe("deepinfra.chat") + expect(deepinfraLanguageModels).toEqual(["meta-llama/Llama-3.3-70B-Instruct"]) + }), + ) +}) diff --git a/packages/core/test/plugin/provider-dynamic.test.ts b/packages/core/test/plugin/provider-dynamic.test.ts new file mode 100644 index 00000000000..c15568eebd1 --- /dev/null +++ b/packages/core/test/plugin/provider-dynamic.test.ts @@ -0,0 +1,172 @@ +import { Npm } from "@opencode-ai/core/npm" +import { describe, expect } from "bun:test" +import { Cause, Effect, Layer, Option } from "effect" +import fs from "fs/promises" +import os from "os" +import path from "path" +import { fileURLToPath } from "url" +import { AISDK } from "@opencode-ai/core/aisdk" +import { ModelV2 } from "@opencode-ai/core/model" +import { PluginV2 } from "@opencode-ai/core/plugin" +import { DynamicProviderPlugin } from "@opencode-ai/core/plugin/provider/dynamic" +import { testEffect } from "../lib/effect" +import { fixtureProvider, it, model, npmLayer } from "./provider-helper" + +const fixtureProviderPath = fileURLToPath(fixtureProvider) +const itWithAISDK = testEffect(AISDK.layer.pipe(Layer.provideMerge(PluginV2.defaultLayer))) + +function npmEntrypointLayer(entrypoint: Option.Option) { + return Layer.succeed( + Npm.Service, + Npm.Service.of({ + add: () => Effect.succeed({ directory: "", entrypoint }), + install: () => Effect.void, + which: () => Effect.succeed(Option.none()), + }), + ) +} + +function dynamicPlugin(layer = npmLayer) { + return { id: DynamicProviderPlugin.id, effect: DynamicProviderPlugin.effect.pipe(Effect.provide(layer)) } +} + +function tempEntrypoint(source: string) { + return Effect.acquireRelease( + Effect.promise(async () => { + const directory = await fs.mkdtemp(path.join(os.tmpdir(), "opencode-provider-dynamic-")) + const entrypoint = path.join(directory, "provider.mjs") + await Bun.write(entrypoint, source) + return { directory, entrypoint } + }), + (tmp) => Effect.promise(() => fs.rm(tmp.directory, { recursive: true, force: true })), + ) +} + +describe("DynamicProviderPlugin", () => { + it.effect("creates an SDK from a provider factory export", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(dynamicPlugin()) + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("custom", "test-model"), + package: fixtureProvider, + options: { name: "custom", marker: "dynamic" }, + }, + {}, + ) + expect(result.sdk.options).toEqual({ marker: "dynamic", name: "custom" }) + expect(result.sdk.languageModel("x")).toEqual({ modelID: "x", options: { marker: "dynamic", name: "custom" } }) + }), + ) + + it.effect("does not override an SDK already supplied by an earlier plugin", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const sdk = { marker: "existing" } + yield* plugin.add(dynamicPlugin()) + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("custom", "test-model"), + package: fixtureProvider, + options: { name: "custom", marker: "dynamic" }, + }, + { sdk }, + ) + expect(result.sdk).toBe(sdk) + }), + ) + + it.effect("injects the provider ID as the SDK factory name", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(dynamicPlugin()) + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("custom-provider", "test-model"), + package: fixtureProvider, + options: { name: "custom-provider", marker: "dynamic" }, + }, + {}, + ) + expect(result.sdk.options).toEqual({ marker: "dynamic", name: "custom-provider" }) + }), + ) + + it.effect("loads npm packages through their resolved import entrypoint", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(dynamicPlugin(npmEntrypointLayer(Option.some(fixtureProviderPath)))) + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("npm-provider", "test-model"), + package: "fixture-provider", + options: { name: "npm-provider", marker: "npm" }, + }, + {}, + ) + expect(result.sdk.languageModel("x")).toEqual({ modelID: "x", options: { marker: "npm", name: "npm-provider" } }) + }), + ) + + itWithAISDK.effect("wraps missing npm entrypoint failures as AISDK init errors", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const aisdk = yield* AISDK.Service + yield* plugin.add(dynamicPlugin(npmEntrypointLayer(Option.none()))) + const exit = yield* aisdk + .language(model("missing-entrypoint", "alias", { endpoint: { type: "aisdk", package: "fixture-provider" } })) + .pipe(Effect.exit) + expect(exit._tag).toBe("Failure") + if (exit._tag === "Failure") expect(Cause.prettyErrors(exit.cause).join("\n")).toContain("AISDK.InitError") + }), + ) + + itWithAISDK.effect("wraps dynamic import failures as AISDK init errors", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const aisdk = yield* AISDK.Service + yield* plugin.add(dynamicPlugin()) + const exit = yield* aisdk + .language( + model("bad-import", "alias", { endpoint: { type: "aisdk", package: "file:///missing/provider-factory.js" } }), + ) + .pipe(Effect.exit) + expect(exit._tag).toBe("Failure") + if (exit._tag === "Failure") expect(Cause.prettyErrors(exit.cause).join("\n")).toContain("AISDK.InitError") + }), + ) + + itWithAISDK.live("wraps missing provider factory exports as AISDK init errors", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const aisdk = yield* AISDK.Service + const tmp = yield* tempEntrypoint("export const notAProviderFactory = true\n") + yield* plugin.add(dynamicPlugin(npmEntrypointLayer(Option.some(tmp.entrypoint)))) + const exit = yield* aisdk + .language(model("missing-factory", "alias", { endpoint: { type: "aisdk", package: "fixture-provider" } })) + .pipe(Effect.exit) + expect(exit._tag).toBe("Failure") + if (exit._tag === "Failure") expect(Cause.prettyErrors(exit.cause).join("\n")).toContain("AISDK.InitError") + }), + ) + + itWithAISDK.effect("uses the model apiID for the default language model", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const aisdk = yield* AISDK.Service + yield* plugin.add(dynamicPlugin()) + const language = yield* aisdk.language( + model("custom", "alias", { + apiID: ModelV2.ID.make("test-model-api"), + endpoint: { type: "aisdk", package: fixtureProvider }, + }), + ) + expect(language).toMatchObject({ modelID: "test-model-api", options: { name: "custom" } }) + }), + ) +}) diff --git a/packages/core/test/plugin/provider-gateway.test.ts b/packages/core/test/plugin/provider-gateway.test.ts new file mode 100644 index 00000000000..8ee69b7dd49 --- /dev/null +++ b/packages/core/test/plugin/provider-gateway.test.ts @@ -0,0 +1,87 @@ +import { describe, expect, mock } from "bun:test" +import { Effect } from "effect" +import { PluginV2 } from "@opencode-ai/core/plugin" +import { GatewayPlugin } from "@opencode-ai/core/plugin/provider/gateway" +import { it, model } from "./provider-helper" + +const gatewayCalls: Record[] = [] +const vercelGatewayModels = ["anthropic/claude-sonnet-4", "openai/gpt-5", "google/gemini-2.5-pro"] + +mock.module("@ai-sdk/gateway", () => ({ + createGateway(options: Record) { + gatewayCalls.push({ ...options }) + return { + languageModel(modelID: string) { + return { + modelId: modelID, + provider: options.name, + specificationVersion: "v3", + } + }, + } + }, +})) + +describe("GatewayPlugin", () => { + it.effect("creates a Gateway SDK for @ai-sdk/gateway", () => + Effect.gen(function* () { + gatewayCalls.length = 0 + const plugin = yield* PluginV2.Service + yield* plugin.add(GatewayPlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { model: model("gateway", "model"), package: "@ai-sdk/gateway", options: { name: "gateway" } }, + {}, + ) + expect(result.sdk).toBeDefined() + expect(gatewayCalls).toHaveLength(1) + }), + ) + + it.effect("passes the model providerID as the Gateway SDK name", () => + Effect.gen(function* () { + gatewayCalls.length = 0 + const plugin = yield* PluginV2.Service + yield* plugin.add(GatewayPlugin) + + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("vercel", "anthropic/claude-sonnet-4"), + package: "@ai-sdk/gateway", + options: { name: "vercel", apiKey: "test-key" }, + }, + {}, + ) + + expect(gatewayCalls).toEqual([{ name: "vercel", apiKey: "test-key" }]) + expect(result.sdk.languageModel("anthropic/claude-sonnet-4").provider).toBe("vercel") + }), + ) + + it.effect("matches Vercel AI Gateway models by their @ai-sdk/gateway package", () => + Effect.gen(function* () { + gatewayCalls.length = 0 + const plugin = yield* PluginV2.Service + yield* plugin.add(GatewayPlugin) + + for (const modelID of vercelGatewayModels) { + const ignored = yield* plugin.trigger( + "aisdk.sdk", + { model: model("vercel", modelID), package: "@ai-sdk/vercel", options: { name: "vercel" } }, + {}, + ) + expect(ignored.sdk).toBeUndefined() + + const result = yield* plugin.trigger( + "aisdk.sdk", + { model: model("vercel", modelID), package: "@ai-sdk/gateway", options: { name: "vercel" } }, + {}, + ) + expect(result.sdk).toBeDefined() + } + + expect(gatewayCalls).toHaveLength(3) + }), + ) +}) diff --git a/packages/core/test/plugin/provider-github-copilot.test.ts b/packages/core/test/plugin/provider-github-copilot.test.ts new file mode 100644 index 00000000000..e2bd899ff3f --- /dev/null +++ b/packages/core/test/plugin/provider-github-copilot.test.ts @@ -0,0 +1,188 @@ +import { describe, expect } from "bun:test" +import { Effect } from "effect" +import { ModelV2 } from "@opencode-ai/core/model" +import { PluginV2 } from "@opencode-ai/core/plugin" +import { GithubCopilotPlugin } from "@opencode-ai/core/plugin/provider/github-copilot" +import { fakeSelectorSdk, it, model } from "./provider-helper" + +describe("GithubCopilotPlugin", () => { + it.effect("creates the bundled Copilot SDK for the GitHub Copilot package", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(GithubCopilotPlugin) + const ignored = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("github-copilot", "gpt-5"), + package: "@ai-sdk/openai-compatible", + options: { name: "github-copilot" }, + }, + {}, + ) + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("github-copilot", "gpt-5"), + package: "@ai-sdk/github-copilot", + options: { name: "github-copilot" }, + }, + {}, + ) + expect(ignored.sdk).toBeUndefined() + expect(result.sdk).toBeDefined() + }), + ) + + it.effect("selects languageModel when responses and chat are absent", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const calls: string[] = [] + yield* plugin.add(GithubCopilotPlugin) + yield* plugin.trigger( + "aisdk.language", + { + model: model("github-copilot", "claude-sonnet-4"), + sdk: { languageModel: fakeSelectorSdk(calls).languageModel }, + options: {}, + }, + {}, + ) + expect(calls).toEqual(["languageModel:claude-sonnet-4"]) + }), + ) + + it.effect("selects languageModel with the API model ID when responses and chat are absent", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const calls: string[] = [] + yield* plugin.add(GithubCopilotPlugin) + yield* plugin.trigger( + "aisdk.language", + { + model: model("github-copilot", "alias", { apiID: ModelV2.ID.make("claude-sonnet-4") }), + sdk: { languageModel: fakeSelectorSdk(calls).languageModel }, + options: {}, + }, + {}, + ) + expect(calls).toEqual(["languageModel:claude-sonnet-4"]) + }), + ) + + it.effect("uses responses for gpt-5 models except gpt-5-mini", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const calls: string[] = [] + yield* plugin.add(GithubCopilotPlugin) + yield* plugin.trigger( + "aisdk.language", + { model: model("github-copilot", "gpt-5"), sdk: fakeSelectorSdk(calls), options: {} }, + {}, + ) + yield* plugin.trigger( + "aisdk.language", + { model: model("github-copilot", "gpt-5.1-codex"), sdk: fakeSelectorSdk(calls), options: {} }, + {}, + ) + yield* plugin.trigger( + "aisdk.language", + { model: model("github-copilot", "gpt-4o"), sdk: fakeSelectorSdk(calls), options: {} }, + {}, + ) + yield* plugin.trigger( + "aisdk.language", + { model: model("github-copilot", "gpt-5-mini"), sdk: fakeSelectorSdk(calls), options: {} }, + {}, + ) + yield* plugin.trigger( + "aisdk.language", + { model: model("github-copilot", "gpt-5-mini-2025-08-07"), sdk: fakeSelectorSdk(calls), options: {} }, + {}, + ) + expect(calls).toEqual([ + "responses:gpt-5", + "responses:gpt-5.1-codex", + "chat:gpt-4o", + "chat:gpt-5-mini", + "chat:gpt-5-mini-2025-08-07", + ]) + }), + ) + + it.effect("uses the API model ID when selecting responses or chat", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const calls: string[] = [] + yield* plugin.add(GithubCopilotPlugin) + yield* plugin.trigger( + "aisdk.language", + { + model: model("github-copilot", "default", { apiID: ModelV2.ID.make("gpt-5") }), + sdk: fakeSelectorSdk(calls), + options: {}, + }, + {}, + ) + yield* plugin.trigger( + "aisdk.language", + { + model: model("github-copilot", "small", { apiID: ModelV2.ID.make("gpt-5-mini") }), + sdk: fakeSelectorSdk(calls), + options: {}, + }, + {}, + ) + yield* plugin.trigger( + "aisdk.language", + { + model: model("github-copilot", "sonnet", { apiID: ModelV2.ID.make("claude-sonnet-4") }), + sdk: fakeSelectorSdk(calls), + options: {}, + }, + {}, + ) + expect(calls).toEqual(["responses:gpt-5", "chat:gpt-5-mini", "chat:claude-sonnet-4"]) + }), + ) + + it.effect("filters gpt-5-chat-latest before Copilot language selection", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(GithubCopilotPlugin) + const result = yield* plugin.trigger( + "model.update", + {}, + { model: model("github-copilot", "gpt-5-chat-latest"), cancel: false }, + ) + expect(result.cancel).toBe(true) + }), + ) + + it.effect("does not filter gpt-5-chat-latest for non-Copilot providers", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(GithubCopilotPlugin) + const result = yield* plugin.trigger( + "model.update", + {}, + { model: model("custom-copilot", "gpt-5-chat-latest"), cancel: false }, + ) + expect(result.cancel).toBe(false) + }), + ) + + it.effect("ignores non-Copilot providers", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const calls: string[] = [] + yield* plugin.add(GithubCopilotPlugin) + const result = yield* plugin.trigger( + "aisdk.language", + { model: model("openai", "gpt-5"), sdk: fakeSelectorSdk(calls), options: {} }, + {}, + ) + expect(calls).toEqual([]) + expect(result.language).toBeUndefined() + }), + ) +}) diff --git a/packages/core/test/plugin/provider-gitlab.test.ts b/packages/core/test/plugin/provider-gitlab.test.ts new file mode 100644 index 00000000000..56a22649a99 --- /dev/null +++ b/packages/core/test/plugin/provider-gitlab.test.ts @@ -0,0 +1,346 @@ +import { describe, expect, mock } from "bun:test" +import { Effect, Layer } from "effect" +import { AuthV2 } from "@opencode-ai/core/auth" +import { PluginV2 } from "@opencode-ai/core/plugin" +import { AuthPlugin } from "@opencode-ai/core/plugin/auth" +import { GitLabPlugin } from "@opencode-ai/core/plugin/provider/gitlab" +import { testEffect } from "../lib/effect" +import { it, model, npmLayer, provider, withEnv } from "./provider-helper" + +const gitlabSDKOptions: Record[] = [] + +void mock.module("gitlab-ai-provider", () => ({ + VERSION: "test-version", + createGitLab: (options: Record) => { + gitlabSDKOptions.push(options) + return { + agenticChat: (id: string, options: unknown) => ({ id, options, type: "agentic" }), + workflowChat: (id: string, options: unknown) => ({ id, options, type: "workflow" }), + } + }, + discoverWorkflowModels: async () => ({ models: [], project: undefined }), + isWorkflowModel: (id: string) => id === "duo-workflow" || id === "duo-workflow-exact", +})) + +const itWithAuth = testEffect(Layer.mergeAll(PluginV2.defaultLayer, AuthV2.defaultLayer, npmLayer)) + +describe("GitLabPlugin", () => { + it.effect("creates SDKs with legacy default instance URL, token env, headers, and feature flags", () => + withEnv( + { + GITLAB_INSTANCE_URL: undefined, + GITLAB_TOKEN: "env-token", + }, + () => + Effect.gen(function* () { + gitlabSDKOptions.length = 0 + const plugin = yield* PluginV2.Service + yield* plugin.add(GitLabPlugin) + yield* plugin.trigger( + "aisdk.sdk", + { model: model("gitlab", "claude"), package: "gitlab-ai-provider", options: { name: "gitlab" } }, + {}, + ) + expect(gitlabSDKOptions).toHaveLength(1) + expect(gitlabSDKOptions[0].instanceUrl).toBe("https://gitlab.com") + expect(gitlabSDKOptions[0].apiKey).toBe("env-token") + expect(gitlabSDKOptions[0].aiGatewayHeaders).toMatchObject({ + "anthropic-beta": "context-1m-2025-08-07", + }) + expect(String((gitlabSDKOptions[0].aiGatewayHeaders as Record)["User-Agent"])).toContain( + "gitlab-ai-provider/test-version", + ) + expect(gitlabSDKOptions[0].featureFlags).toEqual({ + duo_agent_platform_agentic_chat: true, + duo_agent_platform: true, + }) + }), + ), + ) + + it.effect("uses GITLAB_INSTANCE_URL when instanceUrl is not configured", () => + withEnv( + { + GITLAB_INSTANCE_URL: "https://env.gitlab.example", + GITLAB_TOKEN: undefined, + }, + () => + Effect.gen(function* () { + gitlabSDKOptions.length = 0 + const plugin = yield* PluginV2.Service + yield* plugin.add(GitLabPlugin) + yield* plugin.trigger( + "aisdk.sdk", + { model: model("gitlab", "claude"), package: "gitlab-ai-provider", options: { name: "gitlab" } }, + {}, + ) + expect(gitlabSDKOptions[0].instanceUrl).toBe("https://env.gitlab.example") + }), + ), + ) + + it.effect("keeps configured instance URL, apiKey, aiGatewayHeaders, and featureFlags over env/defaults", () => + withEnv( + { + GITLAB_INSTANCE_URL: "https://env.gitlab.example", + GITLAB_TOKEN: "env-token", + }, + () => + Effect.gen(function* () { + gitlabSDKOptions.length = 0 + const plugin = yield* PluginV2.Service + yield* plugin.add(GitLabPlugin) + yield* plugin.trigger( + "aisdk.sdk", + { + model: model("gitlab", "claude"), + package: "gitlab-ai-provider", + options: { + name: "gitlab", + instanceUrl: "https://configured.gitlab.example", + apiKey: "configured-token", + aiGatewayHeaders: { + "anthropic-beta": "configured-beta", + "x-gitlab-test": "1", + }, + featureFlags: { + duo_agent_platform: false, + custom_flag: true, + }, + }, + }, + {}, + ) + expect(gitlabSDKOptions[0].instanceUrl).toBe("https://configured.gitlab.example") + expect(gitlabSDKOptions[0].apiKey).toBe("configured-token") + expect(gitlabSDKOptions[0].aiGatewayHeaders).toMatchObject({ + "anthropic-beta": "configured-beta", + "x-gitlab-test": "1", + }) + expect(gitlabSDKOptions[0].featureFlags).toEqual({ + duo_agent_platform_agentic_chat: true, + duo_agent_platform: false, + custom_flag: true, + }) + }), + ), + ) + + it.effect("ignores non-GitLab SDK packages", () => + Effect.gen(function* () { + gitlabSDKOptions.length = 0 + const plugin = yield* PluginV2.Service + yield* plugin.add(GitLabPlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { model: model("gitlab", "claude"), package: "@ai-sdk/openai", options: { name: "gitlab" } }, + {}, + ) + expect(result.sdk).toBeUndefined() + expect(gitlabSDKOptions).toHaveLength(0) + }), + ) + + itWithAuth.effect("uses active API auth token over GITLAB_TOKEN", () => + withEnv( + { + GITLAB_TOKEN: "env-token", + }, + () => + Effect.gen(function* () { + gitlabSDKOptions.length = 0 + const plugin = yield* PluginV2.Service + const auth = yield* AuthV2.Service + yield* auth.create({ + serviceID: AuthV2.ServiceID.make("gitlab"), + credential: new AuthV2.ApiKeyCredential({ type: "api", key: "auth-token" }), + active: true, + }) + yield* plugin.add({ + ...AuthPlugin, + effect: AuthPlugin.effect.pipe(Effect.provideService(AuthV2.Service, auth)), + }) + yield* plugin.add(GitLabPlugin) + const updated = yield* plugin.trigger("provider.update", {}, { provider: provider("gitlab"), cancel: false }) + yield* plugin.trigger( + "aisdk.sdk", + { + model: model("gitlab", "claude"), + package: "gitlab-ai-provider", + options: updated.provider.options.aisdk.provider, + }, + {}, + ) + expect(gitlabSDKOptions[0].apiKey).toBe("auth-token") + }), + ), + ) + + itWithAuth.effect("uses active OAuth access token when no API auth exists", () => + withEnv( + { + GITLAB_TOKEN: undefined, + }, + () => + Effect.gen(function* () { + gitlabSDKOptions.length = 0 + const plugin = yield* PluginV2.Service + const auth = yield* AuthV2.Service + yield* auth.create({ + serviceID: AuthV2.ServiceID.make("gitlab"), + credential: new AuthV2.OAuthCredential({ + type: "oauth", + refresh: "refresh-token", + access: "oauth-token", + expires: 9999999999999, + }), + active: true, + }) + yield* plugin.add({ + ...AuthPlugin, + effect: AuthPlugin.effect.pipe(Effect.provideService(AuthV2.Service, auth)), + }) + yield* plugin.add(GitLabPlugin) + const updated = yield* plugin.trigger("provider.update", {}, { provider: provider("gitlab"), cancel: false }) + yield* plugin.trigger( + "aisdk.sdk", + { + model: model("gitlab", "claude"), + package: "gitlab-ai-provider", + options: updated.provider.options.aisdk.provider, + }, + {}, + ) + expect(gitlabSDKOptions[0].apiKey).toBe("oauth-token") + }), + ), + ) + + it.effect("uses workflowChat for duo workflow models and preserves selectedModelRef", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const calls: [string, unknown][] = [] + yield* plugin.add(GitLabPlugin) + const result = yield* plugin.trigger( + "aisdk.language", + { + model: model("gitlab", "duo-workflow-custom", { + options: { + headers: {}, + body: {}, + aisdk: { provider: {}, request: { workflowRef: "ref", workflowDefinition: "definition" } }, + }, + }), + sdk: { + workflowChat: (id: string, options: unknown) => { + calls.push([id, options]) + return { id, options } + }, + agenticChat: () => undefined, + }, + options: { featureFlags: { configured: true } }, + }, + {}, + ) + expect(calls).toEqual([ + ["duo-workflow", { featureFlags: { configured: true }, workflowDefinition: "definition" }], + ]) + expect(result.language as unknown).toEqual({ + id: "duo-workflow", + options: calls[0]?.[1], + selectedModelRef: "ref", + }) + }), + ) + + it.effect("uses exact static workflow model ids when the provider recognizes them", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const calls: [string, unknown][] = [] + yield* plugin.add(GitLabPlugin) + const result = yield* plugin.trigger( + "aisdk.language", + { + model: model("gitlab", "duo-workflow-exact"), + sdk: { + workflowChat: (id: string, options: unknown) => { + calls.push([id, options]) + return { id, options } + }, + agenticChat: () => undefined, + }, + options: { featureFlags: { configured: true } }, + }, + {}, + ) + expect(calls).toEqual([ + ["duo-workflow-exact", { featureFlags: { configured: true }, workflowDefinition: undefined }], + ]) + expect(result.language as unknown).toEqual({ id: "duo-workflow-exact", options: calls[0]?.[1] }) + }), + ) + + it.effect("uses provider feature flags instead of request feature flags", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const calls: [string, unknown][] = [] + yield* plugin.add(GitLabPlugin) + yield* plugin.trigger( + "aisdk.language", + { + model: model("gitlab", "duo-workflow-custom", { + options: { + headers: {}, + body: {}, + aisdk: { provider: {}, request: { featureFlags: { request_flag: true } } }, + }, + }), + sdk: { + workflowChat: (id: string, options: unknown) => { + calls.push([id, options]) + return { id, options } + }, + agenticChat: () => undefined, + }, + options: { featureFlags: { configured: true } }, + }, + {}, + ) + expect(calls).toEqual([["duo-workflow", { featureFlags: { configured: true }, workflowDefinition: undefined }]]) + }), + ) + + it.effect("uses agenticChat with provider aiGatewayHeaders and feature flags for normal models", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const calls: [string, unknown][] = [] + yield* plugin.add(GitLabPlugin) + yield* plugin.trigger( + "aisdk.language", + { + model: model("gitlab", "claude", { + options: { headers: { h: "v" }, body: {}, aisdk: { provider: {}, request: {} } }, + }), + sdk: { + workflowChat: () => undefined, + agenticChat: (id: string, options: unknown) => { + const selected = options as { + aiGatewayHeaders?: Record + featureFlags?: Record + } + calls.push([ + id, + { aiGatewayHeaders: { ...selected.aiGatewayHeaders }, featureFlags: { ...selected.featureFlags } }, + ]) + }, + }, + options: { aiGatewayHeaders: { fallback: "header" }, featureFlags: { duo_agent_platform: true } }, + }, + {}, + ) + expect(calls).toEqual([ + ["claude", { aiGatewayHeaders: { fallback: "header" }, featureFlags: { duo_agent_platform: true } }], + ]) + }), + ) +}) diff --git a/packages/core/test/plugin/provider-google-vertex-anthropic.test.ts b/packages/core/test/plugin/provider-google-vertex-anthropic.test.ts new file mode 100644 index 00000000000..6bcece53c95 --- /dev/null +++ b/packages/core/test/plugin/provider-google-vertex-anthropic.test.ts @@ -0,0 +1,147 @@ +import { describe, expect } from "bun:test" +import { Effect } from "effect" +import { PluginV2 } from "@opencode-ai/core/plugin" +import { GoogleVertexAnthropicPlugin } from "@opencode-ai/core/plugin/provider/google-vertex" +import { fakeSelectorSdk, it, model, provider, withEnv } from "./provider-helper" + +describe("GoogleVertexAnthropicPlugin", () => { + it.effect("resolves legacy project and location env on provider update", () => + withEnv( + { + GOOGLE_CLOUD_PROJECT: "cloud-project", + GCP_PROJECT: "gcp-project", + GCLOUD_PROJECT: "gcloud-project", + GOOGLE_CLOUD_LOCATION: "cloud-location", + VERTEX_LOCATION: "vertex-location", + GOOGLE_VERTEX_LOCATION: "google-vertex-location", + }, + () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(GoogleVertexAnthropicPlugin) + const result = yield* plugin.trigger( + "provider.update", + {}, + { provider: provider("google-vertex-anthropic"), cancel: false }, + ) + expect(result.provider.options.aisdk.provider.project).toBe("cloud-project") + expect(result.provider.options.aisdk.provider.location).toBe("cloud-location") + }), + ), + ) + + it.effect("keeps configured project and location over env fallback", () => + withEnv({ GOOGLE_CLOUD_PROJECT: "env-project", GOOGLE_CLOUD_LOCATION: "env-location" }, () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(GoogleVertexAnthropicPlugin) + const result = yield* plugin.trigger( + "provider.update", + {}, + { + provider: provider("google-vertex-anthropic", { + options: { + headers: {}, + body: {}, + aisdk: { provider: { project: "configured-project", location: "configured-location" }, request: {} }, + }, + }), + cancel: false, + }, + ) + expect(result.provider.options.aisdk.provider.project).toBe("configured-project") + expect(result.provider.options.aisdk.provider.location).toBe("configured-location") + }), + ), + ) + + it.effect("creates SDKs from legacy env fallback and default location", () => + withEnv( + { + GOOGLE_CLOUD_PROJECT: undefined, + GCP_PROJECT: "gcp-project", + GCLOUD_PROJECT: "gcloud-project", + GOOGLE_CLOUD_LOCATION: undefined, + VERTEX_LOCATION: undefined, + GOOGLE_VERTEX_LOCATION: "ignored-location", + }, + () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(GoogleVertexAnthropicPlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("google-vertex-anthropic", "claude-sonnet-4-5"), + package: "@ai-sdk/google-vertex/anthropic", + options: { name: "google-vertex-anthropic" }, + }, + {}, + ) + expect(result.sdk.languageModel("claude-sonnet-4-5").config.baseURL).toBe( + "https://aiplatform.googleapis.com/v1/projects/gcp-project/locations/global/publishers/anthropic/models", + ) + }), + ), + ) + + it.effect("uses GOOGLE_CLOUD_LOCATION before VERTEX_LOCATION when creating SDKs", () => + withEnv( + { GOOGLE_CLOUD_PROJECT: "project", GOOGLE_CLOUD_LOCATION: "cloud-location", VERTEX_LOCATION: "vertex-location" }, + () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(GoogleVertexAnthropicPlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("google-vertex-anthropic", "claude-sonnet-4-5"), + package: "@ai-sdk/google-vertex/anthropic", + options: { name: "google-vertex-anthropic" }, + }, + {}, + ) + expect(result.sdk.languageModel("claude-sonnet-4-5").config.baseURL).toBe( + "https://cloud-location-aiplatform.googleapis.com/v1/projects/project/locations/cloud-location/publishers/anthropic/models", + ) + }), + ), + ) + + it.effect("trims model IDs before selecting language models", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const calls: string[] = [] + yield* plugin.add(GoogleVertexAnthropicPlugin) + yield* plugin.trigger( + "aisdk.language", + { + model: model("google-vertex-anthropic", " claude-sonnet-4-5 "), + sdk: { languageModel: fakeSelectorSdk(calls).languageModel }, + options: {}, + }, + {}, + ) + expect(calls).toEqual(["languageModel:claude-sonnet-4-5"]) + }), + ) + + it.effect("ignores non Vertex Anthropic providers for language selection", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const calls: string[] = [] + yield* plugin.add(GoogleVertexAnthropicPlugin) + const result = yield* plugin.trigger( + "aisdk.language", + { + model: model("google-vertex", "claude-sonnet-4-5"), + sdk: { languageModel: fakeSelectorSdk(calls).languageModel }, + options: {}, + }, + {}, + ) + expect(calls).toEqual([]) + expect(result.language).toBeUndefined() + }), + ) +}) diff --git a/packages/core/test/plugin/provider-google-vertex.test.ts b/packages/core/test/plugin/provider-google-vertex.test.ts new file mode 100644 index 00000000000..3bd60fd7211 --- /dev/null +++ b/packages/core/test/plugin/provider-google-vertex.test.ts @@ -0,0 +1,300 @@ +import { describe, expect, mock } from "bun:test" +import { Effect } from "effect" +import { PluginV2 } from "@opencode-ai/core/plugin" +import { GoogleVertexPlugin } from "@opencode-ai/core/plugin/provider/google-vertex" +import { fakeSelectorSdk, it, model, provider, withEnv } from "./provider-helper" + +const vertexOptions: Record[] = [] + +void mock.module("@ai-sdk/google-vertex", () => ({ + createVertex: (options: Record) => { + vertexOptions.push(options) + return { + languageModel: (modelID: string) => ({ modelID, provider: "google-vertex", specificationVersion: "v3" }), + } + }, +})) + +void mock.module("google-auth-library", () => ({ + GoogleAuth: class { + async getApplicationDefault() { + return { + credential: { + async getAccessToken() { + return { token: "vertex-token" } + }, + }, + } + } + }, +})) + +describe("GoogleVertexPlugin", () => { + it.effect("resolves project and location from env using legacy precedence", () => + withEnv( + { + GOOGLE_CLOUD_PROJECT: "google-cloud-project", + GCP_PROJECT: "gcp-project", + GCLOUD_PROJECT: "gcloud-project", + GOOGLE_VERTEX_LOCATION: "google-vertex-location", + GOOGLE_CLOUD_LOCATION: "google-cloud-location", + VERTEX_LOCATION: "vertex-location", + }, + () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(GoogleVertexPlugin) + const result = yield* plugin.trigger( + "provider.update", + {}, + { + provider: provider("google-vertex", { + endpoint: { + type: "aisdk", + package: "@ai-sdk/openai-compatible", + url: "https://${GOOGLE_VERTEX_ENDPOINT}/v1/projects/${GOOGLE_VERTEX_PROJECT}/locations/${GOOGLE_VERTEX_LOCATION}", + }, + }), + cancel: false, + }, + ) + expect(result.provider.options.aisdk.provider.project).toBe("google-cloud-project") + expect(result.provider.options.aisdk.provider.location).toBe("google-vertex-location") + expect(result.provider.endpoint).toEqual({ + type: "aisdk", + package: "@ai-sdk/openai-compatible", + url: "https://google-vertex-location-aiplatform.googleapis.com/v1/projects/google-cloud-project/locations/google-vertex-location", + }) + }), + ), + ) + + it.effect("resolves the advertised GOOGLE_VERTEX_PROJECT env for provider updates and SDKs", () => + withEnv( + { + GOOGLE_VERTEX_PROJECT: "vertex-project", + GOOGLE_CLOUD_PROJECT: undefined, + GCP_PROJECT: undefined, + GCLOUD_PROJECT: undefined, + GOOGLE_VERTEX_LOCATION: "europe-west4", + GOOGLE_CLOUD_LOCATION: undefined, + VERTEX_LOCATION: undefined, + }, + () => + Effect.gen(function* () { + vertexOptions.length = 0 + const plugin = yield* PluginV2.Service + yield* plugin.add(GoogleVertexPlugin) + const updated = yield* plugin.trigger( + "provider.update", + {}, + { + provider: provider("google-vertex", { + endpoint: { + type: "aisdk", + package: "@ai-sdk/openai-compatible", + url: "https://${GOOGLE_VERTEX_ENDPOINT}/v1/projects/${GOOGLE_VERTEX_PROJECT}/locations/${GOOGLE_VERTEX_LOCATION}", + }, + }), + cancel: false, + }, + ) + yield* plugin.trigger( + "aisdk.sdk", + { + model: model("google-vertex", "gemini", { + endpoint: { type: "aisdk", package: "@ai-sdk/google-vertex" }, + }), + package: "@ai-sdk/google-vertex", + options: { name: "google-vertex" }, + }, + {}, + ) + + expect(updated.provider.options.aisdk.provider.project).toBe("vertex-project") + expect(updated.provider.endpoint).toEqual({ + type: "aisdk", + package: "@ai-sdk/openai-compatible", + url: "https://europe-west4-aiplatform.googleapis.com/v1/projects/vertex-project/locations/europe-west4", + }) + expect(vertexOptions[0].project).toBe("vertex-project") + expect(vertexOptions[0].location).toBe("europe-west4") + }), + ), + ) + + it.effect("keeps configured project and location over env and uses global endpoint", () => + withEnv( + { + GOOGLE_CLOUD_PROJECT: "env-project", + GCP_PROJECT: "env-gcp-project", + GCLOUD_PROJECT: "env-gcloud-project", + GOOGLE_VERTEX_LOCATION: "env-location", + GOOGLE_CLOUD_LOCATION: "env-google-cloud-location", + VERTEX_LOCATION: "env-vertex-location", + }, + () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(GoogleVertexPlugin) + const result = yield* plugin.trigger( + "provider.update", + {}, + { + provider: provider("google-vertex", { + endpoint: { + type: "aisdk", + package: "@ai-sdk/openai-compatible", + url: "https://${GOOGLE_VERTEX_ENDPOINT}/v1/projects/${GOOGLE_VERTEX_PROJECT}/locations/${GOOGLE_VERTEX_LOCATION}", + }, + options: { + headers: {}, + body: {}, + aisdk: { provider: { project: "config-project", location: "global" }, request: {} }, + }, + }), + cancel: false, + }, + ) + expect(result.provider.options.aisdk.provider.project).toBe("config-project") + expect(result.provider.options.aisdk.provider.location).toBe("global") + expect(result.provider.endpoint).toEqual({ + type: "aisdk", + package: "@ai-sdk/openai-compatible", + url: "https://aiplatform.googleapis.com/v1/projects/config-project/locations/global", + }) + }), + ), + ) + + it.effect("defaults location to us-central1 when only project is configured", () => + withEnv( + { + GOOGLE_CLOUD_PROJECT: undefined, + GCP_PROJECT: undefined, + GCLOUD_PROJECT: undefined, + GOOGLE_VERTEX_LOCATION: undefined, + GOOGLE_CLOUD_LOCATION: undefined, + VERTEX_LOCATION: undefined, + }, + () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(GoogleVertexPlugin) + const result = yield* plugin.trigger( + "provider.update", + {}, + { + provider: provider("google-vertex", { + options: { headers: {}, body: {}, aisdk: { provider: { project: "config-project" }, request: {} } }, + }), + cancel: false, + }, + ) + expect(result.provider.options.aisdk.provider.project).toBe("config-project") + expect(result.provider.options.aisdk.provider.location).toBe("us-central1") + }), + ), + ) + + it.effect("does not pass Google auth fetch to the native Vertex SDK", () => + withEnv( + { + GOOGLE_CLOUD_PROJECT: "env-project", + GOOGLE_VERTEX_LOCATION: "env-location", + }, + () => + Effect.gen(function* () { + vertexOptions.length = 0 + const plugin = yield* PluginV2.Service + yield* plugin.add(GoogleVertexPlugin) + yield* plugin.trigger( + "aisdk.sdk", + { + model: model("google-vertex", "gemini", { + endpoint: { type: "aisdk", package: "@ai-sdk/google-vertex" }, + }), + package: "@ai-sdk/google-vertex", + options: { name: "google-vertex" }, + }, + {}, + ) + expect(vertexOptions).toHaveLength(1) + expect(vertexOptions[0].project).toBe("env-project") + expect(vertexOptions[0].location).toBe("env-location") + expect(vertexOptions[0].fetch).toBeUndefined() + }), + ), + ) + + it.effect("keeps Google auth fetch for OpenAI-compatible Vertex endpoints", () => + Effect.gen(function* () { + const fetchCalls: { input: Parameters[0]; init?: RequestInit }[] = [] + const plugin = yield* PluginV2.Service + yield* plugin.add(GoogleVertexPlugin) + yield* plugin.add({ + id: PluginV2.ID.make("capture-openai-compatible"), + effect: Effect.succeed({ + "aisdk.sdk": (evt) => + Effect.promise(async () => { + if (evt.model.providerID !== "google-vertex") return + if (evt.package !== "@ai-sdk/openai-compatible") return + expect(typeof evt.options.fetch).toBe("function") + await evt.options.fetch("https://vertex.example", { + headers: { "x-test": "1" }, + }) + }), + }), + }) + const originalFetch = fetch + ;(globalThis as typeof globalThis & { fetch: typeof fetch }).fetch = (async ( + input: Parameters[0], + init?: RequestInit, + ) => { + fetchCalls.push({ input, init }) + return new Response("ok") + }) as typeof fetch + yield* Effect.acquireUseRelease( + Effect.void, + () => + plugin.trigger( + "aisdk.sdk", + { + model: model("google-vertex", "gemini", { + endpoint: { type: "aisdk", package: "@ai-sdk/openai-compatible" }, + }), + package: "@ai-sdk/openai-compatible", + options: { name: "google-vertex" }, + }, + {}, + ), + () => + Effect.sync(() => { + ;(globalThis as typeof globalThis & { fetch: typeof fetch }).fetch = originalFetch + }), + ) + expect(fetchCalls).toHaveLength(1) + expect(fetchCalls[0].input).toBe("https://vertex.example") + expect(new Headers(fetchCalls[0].init?.headers).get("authorization")).toBe("Bearer vertex-token") + expect(new Headers(fetchCalls[0].init?.headers).get("x-test")).toBe("1") + }), + ) + + it.effect("trims model IDs before selecting language models", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const calls: string[] = [] + yield* plugin.add(GoogleVertexPlugin) + yield* plugin.trigger( + "aisdk.language", + { + model: model("google-vertex", " gemini-2.5-pro "), + sdk: { languageModel: fakeSelectorSdk(calls).languageModel }, + options: {}, + }, + {}, + ) + expect(calls).toEqual(["languageModel:gemini-2.5-pro"]) + }), + ) +}) diff --git a/packages/core/test/plugin/provider-google.test.ts b/packages/core/test/plugin/provider-google.test.ts new file mode 100644 index 00000000000..fdb7bf75eea --- /dev/null +++ b/packages/core/test/plugin/provider-google.test.ts @@ -0,0 +1,70 @@ +import { describe, expect } from "bun:test" +import { Effect, Layer } from "effect" +import { AISDK } from "@opencode-ai/core/aisdk" +import { ModelV2 } from "@opencode-ai/core/model" +import { PluginV2 } from "@opencode-ai/core/plugin" +import { GooglePlugin } from "@opencode-ai/core/plugin/provider/google" +import { testEffect } from "../lib/effect" +import { it, model } from "./provider-helper" + +const itWithAISDK = testEffect(AISDK.layer.pipe(Layer.provideMerge(PluginV2.defaultLayer))) + +describe("GooglePlugin", () => { + it.effect("creates a Google Generative AI SDK for @ai-sdk/google using the provider ID as SDK name", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(GooglePlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("custom-google", "gemini"), + package: "@ai-sdk/google", + options: { name: "custom-google", apiKey: "test" }, + }, + {}, + ) + expect(result.sdk).toBeDefined() + expect(result.sdk?.languageModel("gemini").provider).toBe("custom-google") + }), + ) + + it.effect("ignores non-Google SDK packages", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(GooglePlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { model: model("google", "gemini"), package: "@ai-sdk/google-vertex", options: { name: "google" } }, + {}, + ) + expect(result.sdk).toBeUndefined() + }), + ) + + itWithAISDK.effect("uses default languageModel loading with provider ID parity", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const aisdk = yield* AISDK.Service + yield* plugin.add(GooglePlugin) + const language = yield* aisdk.language( + model("custom-google", "alias", { + apiID: ModelV2.ID.make("gemini-api"), + endpoint: { + type: "aisdk", + package: "@ai-sdk/google", + }, + options: { + headers: {}, + body: {}, + aisdk: { + provider: { apiKey: "test" }, + request: {}, + }, + }, + }), + ) + expect(language.modelId).toBe("gemini-api") + expect(language.provider).toBe("custom-google") + }), + ) +}) diff --git a/packages/core/test/plugin/provider-groq.test.ts b/packages/core/test/plugin/provider-groq.test.ts new file mode 100644 index 00000000000..579d70da59a --- /dev/null +++ b/packages/core/test/plugin/provider-groq.test.ts @@ -0,0 +1,101 @@ +import { describe, expect } from "bun:test" +import { createGroq } from "@ai-sdk/groq" +import { Effect, Layer } from "effect" +import { AISDK } from "@opencode-ai/core/aisdk" +import { ModelV2 } from "@opencode-ai/core/model" +import { PluginV2 } from "@opencode-ai/core/plugin" +import { GroqPlugin } from "@opencode-ai/core/plugin/provider/groq" +import { it, model } from "./provider-helper" +import { testEffect } from "../lib/effect" + +const aisdkIt = testEffect(AISDK.layer.pipe(Layer.provideMerge(PluginV2.defaultLayer))) + +describe("GroqPlugin", () => { + it.effect("creates a Groq SDK for @ai-sdk/groq", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(GroqPlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { model: model("groq", "llama"), package: "@ai-sdk/groq", options: { name: "groq" } }, + {}, + ) + expect(result.sdk).toBeDefined() + }), + ) + + it.effect("ignores non-Groq SDK packages", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(GroqPlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { model: model("groq", "llama"), package: "@ai-sdk/openai-compatible", options: { name: "groq" } }, + {}, + ) + expect(result.sdk).toBeUndefined() + }), + ) + + it.effect("only matches the bundled @ai-sdk/groq package exactly", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(GroqPlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { model: model("groq", "llama"), package: "@ai-sdk/groq/compat", options: { name: "groq" } }, + {}, + ) + expect(result.sdk).toBeUndefined() + }), + ) + + it.effect("matches the old bundled Groq SDK provider naming", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(GroqPlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("custom-groq", "llama"), + package: "@ai-sdk/groq", + options: { name: "custom-groq", apiKey: "test" }, + }, + {}, + ) + const expected = createGroq({ name: "custom-groq", apiKey: "test" } as Parameters[0] & { + name: string + }).languageModel("llama") + const actual = result.sdk?.languageModel("llama") + expect(actual?.provider).toBe(expected.provider) + expect(actual?.modelId).toBe(expected.modelId) + }), + ) + + aisdkIt.effect("uses the default languageModel(apiID) behavior", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const aisdk = yield* AISDK.Service + yield* plugin.add(GroqPlugin) + const result = yield* aisdk.language( + model("groq", "alias", { + apiID: ModelV2.ID.make("llama-api"), + endpoint: { + type: "aisdk", + package: "@ai-sdk/groq", + }, + options: { + headers: {}, + body: {}, + aisdk: { + provider: { apiKey: "test" }, + request: {}, + }, + }, + }), + ) + expect(result.modelId).toBe("llama-api") + expect(result.provider).toBe("groq.chat") + }), + ) +}) diff --git a/packages/core/test/plugin/provider-helper.ts b/packages/core/test/plugin/provider-helper.ts new file mode 100644 index 00000000000..0d67075ac8e --- /dev/null +++ b/packages/core/test/plugin/provider-helper.ts @@ -0,0 +1,100 @@ +import { Npm } from "@opencode-ai/core/npm" +import type { LanguageModelV3 } from "@ai-sdk/provider" +import { expect } from "bun:test" +import { Effect, Layer, Option } from "effect" +import { ModelV2 } from "@opencode-ai/core/model" +import { PluginV2 } from "@opencode-ai/core/plugin" +import { ProviderV2 } from "@opencode-ai/core/provider" +import { testEffect } from "../lib/effect" + +export const fixtureProvider = new URL("./fixtures/provider-factory.ts", import.meta.url).href + +export const npmLayer = Layer.succeed( + Npm.Service, + Npm.Service.of({ + add: () => Effect.succeed({ directory: "", entrypoint: Option.none() }), + install: () => Effect.void, + which: () => Effect.succeed(Option.none()), + }), +) + +export const it = testEffect(Layer.mergeAll(PluginV2.defaultLayer, npmLayer)) + +export function provider(providerID: string, options?: Partial) { + return new ProviderV2.Info({ + ...ProviderV2.Info.empty(ProviderV2.ID.make(providerID)), + endpoint: { + type: "aisdk", + package: "test-provider", + }, + ...options, + options: { + headers: {}, + body: {}, + aisdk: { + provider: {}, + request: {}, + }, + ...options?.options, + }, + }) +} + +export function model(providerID: string, modelID: string, options?: Partial) { + return new ModelV2.Info({ + ...ModelV2.Info.empty(ProviderV2.ID.make(providerID), ModelV2.ID.make(modelID)), + apiID: ModelV2.ID.make(modelID), + endpoint: { + type: "aisdk", + package: "test-provider", + }, + ...options, + options: { + headers: {}, + body: {}, + aisdk: { + provider: {}, + request: {}, + }, + ...options?.options, + }, + }) +} + +export function withEnv(vars: Record, fx: () => Effect.Effect) { + return Effect.acquireUseRelease( + Effect.sync(() => { + const previous = Object.fromEntries(Object.keys(vars).map((key) => [key, process.env[key]])) + for (const [key, value] of Object.entries(vars)) { + if (value === undefined) delete process.env[key] + else process.env[key] = value + } + return previous + }), + () => fx(), + (previous) => + Effect.sync(() => { + for (const [key, value] of Object.entries(previous)) { + if (value === undefined) delete process.env[key] + else process.env[key] = value + } + }), + ) +} + +export function fakeSelectorSdk(calls: string[]) { + const make = (method: string) => (id: string) => { + calls.push(`${method}:${id}`) + return { modelId: id, provider: method, specificationVersion: "v3" } as unknown as LanguageModelV3 + } + return { + responses: make("responses"), + messages: make("messages"), + chat: make("chat"), + languageModel: make("languageModel"), + } +} + +export function expectPluginRegistered(ids: string[], id: string) { + expect(ids).toContain(PluginV2.ID.make(id)) +} diff --git a/packages/core/test/plugin/provider-kilo.test.ts b/packages/core/test/plugin/provider-kilo.test.ts new file mode 100644 index 00000000000..33b2593bf9b --- /dev/null +++ b/packages/core/test/plugin/provider-kilo.test.ts @@ -0,0 +1,178 @@ +import { describe, expect } from "bun:test" +import { Effect } from "effect" +import { PluginV2 } from "@opencode-ai/core/plugin" +import { ProviderPlugins } from "@opencode-ai/core/plugin/provider" +import { KiloPlugin } from "@opencode-ai/core/plugin/provider/kilo" +import { expectPluginRegistered, it, model, provider, withEnv } from "./provider-helper" + +describe("KiloPlugin", () => { + it.effect("is registered so legacy referer headers can be applied", () => + Effect.sync(() => + expectPluginRegistered( + ProviderPlugins.map((item) => item.id), + "kilo", + ), + ), + ) + + it.effect("applies legacy referer headers only to kilo", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(KiloPlugin) + const result = yield* plugin.trigger( + "provider.update", + {}, + { + provider: provider("kilo", { + options: { headers: { Existing: "value" }, body: {}, aisdk: { provider: {}, request: {} } }, + }), + cancel: false, + }, + ) + const ignored = yield* plugin.trigger("provider.update", {}, { provider: provider("openrouter"), cancel: false }) + expect(result.provider.options.headers).toEqual({ + Existing: "value", + "HTTP-Referer": "https://kilo.ai/", + "X-Title": "Kilo Code", + }) + expect(ignored.provider.options.headers).toEqual({}) + }), + ) + + it.effect("uses the exact legacy Kilo header casing and set", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(KiloPlugin) + const result = yield* plugin.trigger("provider.update", {}, { provider: provider("kilo"), cancel: false }) + + expect(result.provider.options.headers).toEqual({ + "HTTP-Referer": "https://kilo.ai/", + "X-Title": "Kilo Code", + }) + expect(result.provider.options.headers).not.toHaveProperty("http-referer") + expect(result.provider.options.headers).not.toHaveProperty("x-title") + expect(result.provider.options.headers).not.toHaveProperty("X-Source") + }), + ) + + it.effect("uses the legacy provider-id guard instead of endpoint package matching", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(KiloPlugin) + const matchingID = yield* plugin.trigger( + "provider.update", + {}, + { + provider: provider("kilo", { + endpoint: { type: "aisdk", package: "not-kilo" }, + }), + cancel: false, + }, + ) + const matchingPackage = yield* plugin.trigger( + "provider.update", + {}, + { + provider: provider("custom-kilo", { + endpoint: { type: "aisdk", package: "kilo" }, + }), + cancel: false, + }, + ) + + expect(matchingID.provider.options.headers).toEqual({ + "HTTP-Referer": "https://kilo.ai/", + "X-Title": "Kilo Code", + }) + expect(matchingPackage.provider.options.headers).toEqual({}) + }), + ) + + it.effect("routes the Kilo catalog through the Kilo Gateway SDK", () => + withEnv({ KILO_API_KEY: undefined, KILO_ORG_ID: undefined }, () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(KiloPlugin) + const updated = yield* plugin.trigger( + "provider.update", + {}, + { + provider: provider("kilo", { + endpoint: { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://api.kilo.ai/api/gateway" }, + options: { + headers: {}, + body: {}, + aisdk: { provider: { apiKey: "stored-token" }, request: {} }, + }, + }), + cancel: false, + }, + ) + + expect(updated.provider.endpoint).toEqual({ + type: "aisdk", + package: "@kilocode/kilo-gateway", + url: "https://api.kilo.ai/api/openrouter", + }) + expect(updated.provider.options.aisdk.provider.kilocodeToken).toBe("stored-token") + + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("kilo", "kilo-auto/free"), + package: "@kilocode/kilo-gateway", + options: updated.provider.options.aisdk.provider, + }, + {}, + ) + expect(result.sdk).toBeDefined() + expect(typeof result.sdk.languageModel).toBe("function") + expect(typeof result.sdk.anthropic).toBe("function") + }), + ), + ) + + it.effect("keeps authenticated credentials ahead of inherited environment keys", () => + withEnv({ KILO_API_KEY: "environment-token", KILO_ORG_ID: "environment-org" }, () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(KiloPlugin) + const result = yield* plugin.trigger( + "provider.update", + {}, + { + provider: provider("kilo", { + enabled: { via: "auth", service: "kilo" }, + options: { + headers: {}, + body: {}, + aisdk: { + provider: { apiKey: "authenticated-token", kilocodeOrganizationId: "authenticated-org" }, + request: {}, + }, + }, + }), + cancel: false, + }, + ) + + expect(result.provider.enabled).toEqual({ via: "auth", service: "kilo" }) + expect(result.provider.options.aisdk.provider.kilocodeToken).toBe("authenticated-token") + expect(result.provider.options.aisdk.provider.kilocodeOrganizationId).toBe("environment-org") + }), + ), + ) + + it.effect("keeps anonymous Kilo models available without credentials", () => + withEnv({ KILO_API_KEY: undefined, KILO_ORG_ID: undefined }, () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(KiloPlugin) + const result = yield* plugin.trigger("provider.update", {}, { provider: provider("kilo"), cancel: false }) + + expect(result.provider.enabled).toEqual({ via: "custom", data: { anonymous: true } }) + expect(result.provider.options.aisdk.provider.kilocodeToken).toBe("anonymous") + }), + ), + ) +}) diff --git a/packages/core/test/plugin/provider-llmgateway.test.ts b/packages/core/test/plugin/provider-llmgateway.test.ts new file mode 100644 index 00000000000..4c69aee7864 --- /dev/null +++ b/packages/core/test/plugin/provider-llmgateway.test.ts @@ -0,0 +1,63 @@ +import { describe, expect } from "bun:test" +import { Effect } from "effect" +import { PluginV2 } from "@opencode-ai/core/plugin" +import { ProviderPlugins } from "@opencode-ai/core/plugin/provider" +import { LLMGatewayPlugin } from "@opencode-ai/core/plugin/provider/llmgateway" +import { expectPluginRegistered, it, provider } from "./provider-helper" + +describe("LLMGatewayPlugin", () => { + it.effect("is registered so legacy referer headers can be applied", () => + Effect.sync(() => + expectPluginRegistered( + ProviderPlugins.map((item) => item.id), + "llmgateway", + ), + ), + ) + + it.effect("applies legacy referer headers only to enabled llmgateway", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(LLMGatewayPlugin) + const result = yield* plugin.trigger( + "provider.update", + {}, + { + provider: provider("llmgateway", { + enabled: { via: "env", name: "LLMGATEWAY_API_KEY" }, + options: { headers: { Existing: "value" }, body: {}, aisdk: { provider: {}, request: {} } }, + }), + cancel: false, + }, + ) + const ignored = yield* plugin.trigger( + "provider.update", + {}, + { + provider: provider("openrouter", { + enabled: { via: "env", name: "OPENROUTER_API_KEY" }, + }), + cancel: false, + }, + ) + expect(result.provider.options.headers).toEqual({ + Existing: "value", + "HTTP-Referer": "https://kilo.ai/", + "X-Title": "Kilo Code", + "X-Source": "kilo", + }) + expect(ignored.provider.options.headers).toEqual({}) + }), + ) + + it.effect("does not apply legacy headers to a disabled llmgateway provider", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(LLMGatewayPlugin) + const result = yield* plugin.trigger("provider.update", {}, { provider: provider("llmgateway"), cancel: false }) + + expect(result.provider.enabled).toBe(false) + expect(result.provider.options.headers).toEqual({}) + }), + ) +}) diff --git a/packages/core/test/plugin/provider-mistral.test.ts b/packages/core/test/plugin/provider-mistral.test.ts new file mode 100644 index 00000000000..f24ff53e5be --- /dev/null +++ b/packages/core/test/plugin/provider-mistral.test.ts @@ -0,0 +1,106 @@ +import { describe, expect } from "bun:test" +import { Effect } from "effect" +import { ModelV2 } from "@opencode-ai/core/model" +import { PluginV2 } from "@opencode-ai/core/plugin" +import { MistralPlugin } from "@opencode-ai/core/plugin/provider/mistral" +import { fakeSelectorSdk, it, model } from "./provider-helper" + +describe("MistralPlugin", () => { + it.effect("creates a Mistral SDK for @ai-sdk/mistral", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(MistralPlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { model: model("mistral", "mistral-large"), package: "@ai-sdk/mistral", options: { name: "mistral" } }, + {}, + ) + expect(result.sdk).toBeDefined() + }), + ) + + it.effect("ignores non-Mistral SDK packages", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(MistralPlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("mistral", "mistral-large"), + package: "@ai-sdk/openai-compatible", + options: { name: "mistral" }, + }, + {}, + ) + expect(result.sdk).toBeUndefined() + }), + ) + + it.effect("matches the old bundled Mistral SDK provider name for the bundled provider ID", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const providers: string[] = [] + yield* plugin.add(MistralPlugin) + yield* plugin.add({ + id: PluginV2.ID.make("mistral-sdk-inspector"), + effect: Effect.succeed({ + "aisdk.sdk": (evt) => + Effect.sync(() => { + providers.push(evt.sdk.languageModel("mistral-large").provider) + }), + }), + }) + const result = yield* plugin.trigger( + "aisdk.sdk", + { model: model("mistral", "mistral-large"), package: "@ai-sdk/mistral", options: { name: "mistral" } }, + {}, + ) + expect(result.sdk).toBeDefined() + expect(providers).toEqual(["mistral.chat"]) + }), + ) + + it.effect("matches the old bundled Mistral SDK provider name for custom provider IDs", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const providers: string[] = [] + yield* plugin.add(MistralPlugin) + yield* plugin.add({ + id: PluginV2.ID.make("mistral-sdk-inspector"), + effect: Effect.succeed({ + "aisdk.sdk": (evt) => + Effect.sync(() => { + providers.push(evt.sdk.languageModel("mistral-large").provider) + }), + }), + }) + yield* plugin.trigger( + "aisdk.sdk", + { + model: model("custom-mistral", "mistral-large"), + package: "@ai-sdk/mistral", + options: { name: "custom-mistral" }, + }, + {}, + ) + expect(providers).toEqual(["mistral.chat"]) + }), + ) + + it.effect("leaves Mistral language selection on the default sdk.languageModel(apiID) path", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const calls: string[] = [] + const sdk = fakeSelectorSdk(calls) + yield* plugin.add(MistralPlugin) + const result = yield* plugin.trigger( + "aisdk.language", + { model: model("mistral", "alias", { apiID: ModelV2.ID.make("mistral-large") }), sdk, options: {} }, + {}, + ) + const language = result.language ?? sdk.languageModel(result.model.apiID) + expect(calls).toEqual(["languageModel:mistral-large"]) + expect(language).toBeDefined() + }), + ) +}) diff --git a/packages/core/test/plugin/provider-nvidia.test.ts b/packages/core/test/plugin/provider-nvidia.test.ts new file mode 100644 index 00000000000..0ce3d370cba --- /dev/null +++ b/packages/core/test/plugin/provider-nvidia.test.ts @@ -0,0 +1,93 @@ +import { describe, expect } from "bun:test" +import { Effect } from "effect" +import { PluginV2 } from "@opencode-ai/core/plugin" +import { ProviderPlugins } from "@opencode-ai/core/plugin/provider" +import { NvidiaPlugin } from "@opencode-ai/core/plugin/provider/nvidia" +import { expectPluginRegistered, it, provider } from "./provider-helper" + +describe("NvidiaPlugin", () => { + it.effect("is registered so legacy referer headers can be applied", () => + Effect.sync(() => + expectPluginRegistered( + ProviderPlugins.map((item) => item.id), + "nvidia", + ), + ), + ) + + it.effect("applies NVIDIA tracking headers only to nvidia", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(NvidiaPlugin) + const result = yield* plugin.trigger( + "provider.update", + {}, + { + provider: provider("nvidia", { + options: { headers: { Existing: "value" }, body: {}, aisdk: { provider: {}, request: {} } }, + }), + cancel: false, + }, + ) + const ignored = yield* plugin.trigger("provider.update", {}, { provider: provider("openrouter"), cancel: false }) + expect(result.provider.options.headers).toEqual({ + Existing: "value", + "HTTP-Referer": "https://kilo.ai/", + "X-Title": "Kilo Code", + "X-BILLING-INVOKE-ORIGIN": "KiloCode", + }) + expect(ignored.provider.options.headers).toEqual({}) + }), + ) + + it.effect("adds billing origin for custom NVIDIA endpoints", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(NvidiaPlugin) + const result = yield* plugin.trigger( + "provider.update", + {}, + { + provider: provider("nvidia", { + endpoint: { type: "aisdk", package: "test-provider", url: "http://localhost:8000/v1" }, + options: { headers: {}, body: {}, aisdk: { provider: {}, request: {} } }, + }), + cancel: false, + }, + ) + + expect(result.provider.options.headers).toEqual({ + "HTTP-Referer": "https://kilo.ai/", + "X-Title": "Kilo Code", + "X-BILLING-INVOKE-ORIGIN": "KiloCode", + }) + }), + ) + + it.effect("preserves an explicit NVIDIA billing origin header", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(NvidiaPlugin) + const result = yield* plugin.trigger( + "provider.update", + {}, + { + provider: provider("nvidia", { + options: { + headers: { "X-BILLING-INVOKE-ORIGIN": "CustomOrigin" }, + body: {}, + aisdk: { provider: { baseURL: "https://integrate.api.nvidia.com/v1" }, request: {} }, + }, + }), + cancel: false, + }, + ) + + expect(result.provider.options.headers).toEqual({ + "HTTP-Referer": "https://kilo.ai/", + "X-Title": "Kilo Code", + "X-BILLING-INVOKE-ORIGIN": "CustomOrigin", + }) + }), + ) +}) diff --git a/packages/core/test/plugin/provider-openai-compatible.test.ts b/packages/core/test/plugin/provider-openai-compatible.test.ts new file mode 100644 index 00000000000..e8bf1f7575f --- /dev/null +++ b/packages/core/test/plugin/provider-openai-compatible.test.ts @@ -0,0 +1,101 @@ +import { describe, expect } from "bun:test" +import { Effect } from "effect" +import { PluginV2 } from "@opencode-ai/core/plugin" +import { OpenAICompatiblePlugin } from "@opencode-ai/core/plugin/provider/openai-compatible" +import { it, model } from "./provider-helper" + +describe("OpenAICompatiblePlugin", () => { + it.effect("preserves explicit includeUsage false and defaults it to true", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(OpenAICompatiblePlugin) + const defaulted = yield* plugin.trigger( + "aisdk.sdk", + { model: model("custom", "model"), package: "@ai-sdk/openai-compatible", options: { name: "custom" } }, + {}, + ) + const disabled = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("custom", "model"), + package: "@ai-sdk/openai-compatible", + options: { name: "custom", includeUsage: false }, + }, + {}, + ) + expect(defaulted.options.includeUsage).toBe(true) + expect(disabled.options.includeUsage).toBe(false) + }), + ) + + it.effect("defaults includeUsage for OpenAI-compatible package matches", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(OpenAICompatiblePlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("custom", "model"), + package: "file:///tmp/@ai-sdk/openai-compatible-provider.js", + options: { name: "custom" }, + }, + {}, + ) + expect(result.options.includeUsage).toBe(true) + }), + ) + + it.effect("uses the provider ID as the OpenAI-compatible provider name", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const observed: string[] = [] + yield* plugin.add(OpenAICompatiblePlugin) + yield* plugin.add({ + id: PluginV2.ID.make("inspector"), + effect: Effect.succeed({ + "aisdk.sdk": (evt) => + Effect.sync(() => { + observed.push(evt.sdk.languageModel("model").provider) + }), + }), + }) + yield* plugin.trigger( + "aisdk.sdk", + { + model: model("custom-provider", "model"), + package: "@ai-sdk/openai-compatible", + options: { name: "custom-provider", baseURL: "https://example.com/v1" }, + }, + {}, + ) + expect(observed).toEqual(["custom-provider.chat"]) + }), + ) + + it.effect("does not overwrite an SDK created by an earlier provider-specific plugin", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const sentinel = { languageModel: (modelID: string) => ({ modelID }) } + yield* plugin.add({ + id: PluginV2.ID.make("sentinel"), + effect: Effect.succeed({ + "aisdk.sdk": (evt) => + Effect.sync(() => { + evt.sdk = sentinel + }), + }), + }) + yield* plugin.add(OpenAICompatiblePlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("cloudflare-workers-ai", "model"), + package: "@ai-sdk/openai-compatible", + options: { name: "cloudflare-workers-ai" }, + }, + {}, + ) + expect(result.sdk).toBe(sentinel) + }), + ) +}) diff --git a/packages/core/test/plugin/provider-openai.test.ts b/packages/core/test/plugin/provider-openai.test.ts new file mode 100644 index 00000000000..31d6dd0b6d1 --- /dev/null +++ b/packages/core/test/plugin/provider-openai.test.ts @@ -0,0 +1,100 @@ +import { describe, expect } from "bun:test" +import { Effect } from "effect" +import { ModelV2 } from "@opencode-ai/core/model" +import { PluginV2 } from "@opencode-ai/core/plugin" +import { OpenAIPlugin } from "@opencode-ai/core/plugin/provider/openai" +import { fakeSelectorSdk, it, model } from "./provider-helper" + +describe("OpenAIPlugin", () => { + it.effect("creates an OpenAI SDK for @ai-sdk/openai using the provider ID as SDK name", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(OpenAIPlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("custom-openai", "gpt-5"), + package: "@ai-sdk/openai", + options: { name: "custom-openai", apiKey: "test" }, + }, + {}, + ) + expect(result.sdk?.responses("gpt-5").provider).toBe("custom-openai.responses") + }), + ) + + it.effect("ignores non-OpenAI SDK packages", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(OpenAIPlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { model: model("openai", "gpt-5"), package: "@ai-sdk/openai-compatible", options: { name: "openai" } }, + {}, + ) + expect(result.sdk).toBeUndefined() + }), + ) + + it.effect("uses the Responses API for language models", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const calls: string[] = [] + yield* plugin.add(OpenAIPlugin) + const result = yield* plugin.trigger( + "aisdk.language", + { + model: model("openai", "alias", { apiID: ModelV2.ID.make("gpt-5") }), + sdk: fakeSelectorSdk(calls), + options: {}, + }, + {}, + ) + expect(calls).toEqual(["responses:gpt-5"]) + expect(result.language).toBeDefined() + }), + ) + + it.effect("ignores non-OpenAI providers", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const calls: string[] = [] + yield* plugin.add(OpenAIPlugin) + const result = yield* plugin.trigger( + "aisdk.language", + { model: model("anthropic", "gpt-5"), sdk: fakeSelectorSdk(calls), options: {} }, + {}, + ) + expect(calls).toEqual([]) + expect(result.language).toBeUndefined() + }), + ) + + it.effect("cancels gpt-5-chat-latest during model updates", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(OpenAIPlugin) + const normal = yield* plugin.trigger("model.update", {}, { model: model("openai", "gpt-5"), cancel: false }) + const filtered = yield* plugin.trigger( + "model.update", + {}, + { model: model("openai", "gpt-5-chat-latest"), cancel: false }, + ) + expect(normal.cancel).toBe(false) + expect(filtered.cancel).toBe(true) + }), + ) + + it.effect("does not cancel gpt-5-chat-latest for non-OpenAI providers", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(OpenAIPlugin) + const result = yield* plugin.trigger( + "model.update", + {}, + { model: model("custom-openai", "gpt-5-chat-latest"), cancel: false }, + ) + expect(result.cancel).toBe(false) + }), + ) +}) diff --git a/packages/core/test/plugin/provider-opencode.test.ts b/packages/core/test/plugin/provider-opencode.test.ts new file mode 100644 index 00000000000..8271a4a5c82 --- /dev/null +++ b/packages/core/test/plugin/provider-opencode.test.ts @@ -0,0 +1,197 @@ +import { describe, expect } from "bun:test" +import { DateTime, Effect, Layer, Option } from "effect" +import { Catalog } from "@opencode-ai/core/catalog" +import { Instance } from "@opencode-ai/core/instance" +import { ModelV2 } from "@opencode-ai/core/model" +import { PluginV2 } from "@opencode-ai/core/plugin" +import { OpencodePlugin } from "@opencode-ai/core/plugin/provider/opencode" +import { ProviderV2 } from "@opencode-ai/core/provider" +import { it, model, provider, withEnv } from "./provider-helper" + +const cost = (input: number, output = 0) => [{ input, output, cache: { read: 0, write: 0 } }] +const instanceLayer = Layer.succeed(Instance.Service, Instance.Service.of({ directory: "test" })) + +describe("OpencodePlugin", () => { + it.effect("uses a public key and cancels paid models without credentials", () => + withEnv({ OPENCODE_API_KEY: undefined }, () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(OpencodePlugin) + const updated = yield* plugin.trigger("provider.update", {}, { provider: provider("opencode"), cancel: false }) + const paid = yield* plugin.trigger( + "model.update", + {}, + { model: model("opencode", "paid", { cost: cost(1) }), cancel: false }, + ) + expect(updated.provider.options.aisdk.provider.apiKey).toBe("public") + expect(paid.cancel).toBe(true) + }), + ), + ) + + it.effect("keeps free models without credentials", () => + withEnv({ OPENCODE_API_KEY: undefined }, () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(OpencodePlugin) + yield* plugin.trigger("provider.update", {}, { provider: provider("opencode"), cancel: false }) + const free = yield* plugin.trigger( + "model.update", + {}, + { model: model("opencode", "free", { cost: cost(0) }), cancel: false }, + ) + expect(free.cancel).toBe(false) + }), + ), + ) + + it.effect("treats output-only cost as free without credentials", () => + withEnv({ OPENCODE_API_KEY: undefined }, () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(OpencodePlugin) + yield* plugin.trigger("provider.update", {}, { provider: provider("opencode"), cancel: false }) + const outputOnly = yield* plugin.trigger( + "model.update", + {}, + { model: model("opencode", "output-only", { cost: cost(0, 1) }), cancel: false }, + ) + expect(outputOnly.cancel).toBe(false) + }), + ), + ) + + it.effect("uses OPENCODE_API_KEY as credentials", () => + withEnv({ OPENCODE_API_KEY: "secret" }, () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(OpencodePlugin) + const updated = yield* plugin.trigger("provider.update", {}, { provider: provider("opencode"), cancel: false }) + const paid = yield* plugin.trigger( + "model.update", + {}, + { model: model("opencode", "paid", { cost: cost(1) }), cancel: false }, + ) + expect(updated.provider.options.aisdk.provider.apiKey).toBeUndefined() + expect(paid.cancel).toBe(false) + }), + ), + ) + + it.effect("uses configured provider env vars as credentials", () => + withEnv({ OPENCODE_API_KEY: undefined, CUSTOM_OPENCODE_API_KEY: "secret" }, () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(OpencodePlugin) + const updated = yield* plugin.trigger( + "provider.update", + {}, + { provider: provider("opencode", { env: ["CUSTOM_OPENCODE_API_KEY"] }), cancel: false }, + ) + const paid = yield* plugin.trigger( + "model.update", + {}, + { model: model("opencode", "paid", { cost: cost(1) }), cancel: false }, + ) + expect(updated.provider.options.aisdk.provider.apiKey).toBeUndefined() + expect(paid.cancel).toBe(false) + }), + ), + ) + + it.effect("uses configured apiKey as credentials", () => + withEnv({ OPENCODE_API_KEY: undefined }, () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(OpencodePlugin) + const updated = yield* plugin.trigger( + "provider.update", + {}, + { + provider: provider("opencode", { + options: { + headers: {}, + body: {}, + aisdk: { + provider: { apiKey: "configured" }, + request: {}, + }, + }, + }), + cancel: false, + }, + ) + const paid = yield* plugin.trigger( + "model.update", + {}, + { model: model("opencode", "paid", { cost: cost(1) }), cancel: false }, + ) + expect(updated.provider.options.aisdk.provider.apiKey).toBe("configured") + expect(paid.cancel).toBe(false) + }), + ), + ) + + it.effect("uses auth-enabled providers as credentials", () => + withEnv({ OPENCODE_API_KEY: undefined }, () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(OpencodePlugin) + const updated = yield* plugin.trigger( + "provider.update", + {}, + { provider: provider("opencode", { enabled: { via: "auth", service: "opencode" } }), cancel: false }, + ) + const paid = yield* plugin.trigger( + "model.update", + {}, + { model: model("opencode", "paid", { cost: cost(1) }), cancel: false }, + ) + expect(updated.provider.options.aisdk.provider.apiKey).toBeUndefined() + expect(paid.cancel).toBe(false) + }), + ), + ) + + it.effect("ignores non-opencode providers and models", () => + withEnv({ OPENCODE_API_KEY: undefined }, () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(OpencodePlugin) + const updated = yield* plugin.trigger("provider.update", {}, { provider: provider("openai"), cancel: false }) + const paid = yield* plugin.trigger( + "model.update", + {}, + { model: model("openai", "paid", { cost: cost(1) }), cancel: false }, + ) + expect(updated.provider.options.aisdk.provider.apiKey).toBeUndefined() + expect(paid.cancel).toBe(false) + }), + ), + ) + + it.effect("prefers gpt-5-nano as the opencode small model", () => + Effect.gen(function* () { + const catalog = yield* Catalog.Service + const providerID = ProviderV2.ID.opencode + + yield* catalog.provider.update(providerID, () => {}) + yield* catalog.model.update(providerID, ModelV2.ID.make("cheap-mini"), (model) => { + model.capabilities.input = ["text"] + model.capabilities.output = ["text"] + model.cost = cost(1, 1) + model.time.released = DateTime.makeUnsafe(Date.now()) + }) + yield* catalog.model.update(providerID, ModelV2.ID.make("gpt-5-nano"), (model) => { + model.capabilities.input = ["text"] + model.capabilities.output = ["text"] + model.cost = cost(10, 10) + model.time.released = DateTime.makeUnsafe(Date.now()) + }) + + const selected = yield* catalog.model.small(providerID) + + expect(Option.getOrUndefined(selected)?.id).toBe(ModelV2.ID.make("gpt-5-nano")) + }).pipe(Effect.provide(Catalog.defaultLayer.pipe(Layer.provide(instanceLayer)))), + ) +}) diff --git a/packages/core/test/plugin/provider-openrouter.test.ts b/packages/core/test/plugin/provider-openrouter.test.ts new file mode 100644 index 00000000000..91db253aa01 --- /dev/null +++ b/packages/core/test/plugin/provider-openrouter.test.ts @@ -0,0 +1,105 @@ +import { describe, expect } from "bun:test" +import { Effect } from "effect" +import { PluginV2 } from "@opencode-ai/core/plugin" +import { ProviderPlugins } from "@opencode-ai/core/plugin/provider" +import { OpenRouterPlugin } from "@opencode-ai/core/plugin/provider/openrouter" +import { expectPluginRegistered, it, model, provider } from "./provider-helper" + +describe("OpenRouterPlugin", () => { + it.effect("is registered so legacy OpenRouter behavior can be applied", () => + Effect.sync(() => + expectPluginRegistered( + ProviderPlugins.map((item) => item.id), + "openrouter", + ), + ), + ) + + it.effect("applies legacy referer headers only to openrouter", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(OpenRouterPlugin) + const result = yield* plugin.trigger( + "provider.update", + {}, + { + provider: provider("openrouter", { + options: { headers: { Existing: "value" }, body: {}, aisdk: { provider: {}, request: {} } }, + }), + cancel: false, + }, + ) + const ignored = yield* plugin.trigger("provider.update", {}, { provider: provider("nvidia"), cancel: false }) + expect(result.provider.options.headers).toEqual({ + Existing: "value", + "HTTP-Referer": "https://kilo.ai/", + "X-Title": "Kilo Code", + }) + expect(ignored.provider.options.headers).toEqual({}) + }), + ) + + it.effect("creates an SDK only for the OpenRouter package", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(OpenRouterPlugin) + + const ignored = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("openrouter", "openai/gpt-5"), + package: "@ai-sdk/openai-compatible", + options: { name: "openrouter" }, + }, + {}, + ) + expect(ignored.sdk).toBeUndefined() + + const result = yield* plugin.trigger( + "aisdk.sdk", + { model: model("custom", "openai/gpt-5"), package: "@openrouter/ai-sdk-provider", options: { name: "custom" } }, + {}, + ) + expect(result.sdk).toBeDefined() + }), + ) + + it.effect("filters OpenRouter's gpt-5 chat alias", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(OpenRouterPlugin) + const result = yield* plugin.trigger( + "model.update", + {}, + { model: model("openrouter", "openai/gpt-5-chat"), cancel: false }, + ) + const regular = yield* plugin.trigger( + "model.update", + {}, + { model: model("openrouter", "openai/gpt-5"), cancel: false }, + ) + const ignored = yield* plugin.trigger( + "model.update", + {}, + { model: model("openai", "openai/gpt-5-chat"), cancel: false }, + ) + + expect(result.cancel).toBe(true) + expect(regular.cancel).toBe(false) + expect(ignored.cancel).toBe(false) + }), + ) + + it.effect("does not filter gpt-5-chat-latest for non-OpenRouter providers", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(OpenRouterPlugin) + const result = yield* plugin.trigger( + "model.update", + {}, + { model: model("custom-openrouter", "gpt-5-chat-latest"), cancel: false }, + ) + expect(result.cancel).toBe(false) + }), + ) +}) diff --git a/packages/core/test/plugin/provider-perplexity.test.ts b/packages/core/test/plugin/provider-perplexity.test.ts new file mode 100644 index 00000000000..d03f583375d --- /dev/null +++ b/packages/core/test/plugin/provider-perplexity.test.ts @@ -0,0 +1,107 @@ +import { describe, expect } from "bun:test" +import { Effect } from "effect" +import { ModelV2 } from "@opencode-ai/core/model" +import { PluginV2 } from "@opencode-ai/core/plugin" +import { PerplexityPlugin } from "@opencode-ai/core/plugin/provider/perplexity" +import { fakeSelectorSdk, it, model } from "./provider-helper" + +describe("PerplexityPlugin", () => { + it.effect("creates a Perplexity SDK for the exact @ai-sdk/perplexity package", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(PerplexityPlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { model: model("perplexity", "sonar"), package: "@ai-sdk/perplexity", options: { name: "perplexity" } }, + {}, + ) + expect(result.sdk).toBeDefined() + }), + ) + + it.effect("ignores packages that are not the bundled Perplexity package", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(PerplexityPlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("perplexity", "sonar"), + package: "@ai-sdk/perplexity-compatible", + options: { name: "perplexity" }, + }, + {}, + ) + expect(result.sdk).toBeUndefined() + }), + ) + + it.effect("uses the Perplexity provider ID as the SDK name for the bundled provider", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const providers: string[] = [] + yield* plugin.add(PerplexityPlugin) + yield* plugin.add({ + id: PluginV2.ID.make("perplexity-sdk-inspector"), + effect: Effect.succeed({ + "aisdk.sdk": (evt) => + Effect.sync(() => { + providers.push(evt.sdk.languageModel("sonar").provider) + }), + }), + }) + yield* plugin.trigger( + "aisdk.sdk", + { model: model("perplexity", "sonar"), package: "@ai-sdk/perplexity", options: { name: "perplexity" } }, + {}, + ) + expect(providers).toEqual(["perplexity"]) + }), + ) + + it.effect("creates bundled Perplexity SDKs for custom provider IDs", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const providers: string[] = [] + yield* plugin.add(PerplexityPlugin) + yield* plugin.add({ + id: PluginV2.ID.make("custom-perplexity-sdk-inspector"), + effect: Effect.succeed({ + "aisdk.sdk": (evt) => + Effect.sync(() => { + providers.push(evt.sdk.languageModel("sonar").provider) + }), + }), + }) + yield* plugin.trigger( + "aisdk.sdk", + { + model: model("custom-perplexity", "sonar"), + package: "@ai-sdk/perplexity", + options: { name: "custom-perplexity" }, + }, + {}, + ) + expect(providers).toEqual(["perplexity"]) + }), + ) + + it.effect("leaves Perplexity language selection to the default languageModel fallback", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const calls: string[] = [] + yield* plugin.add(PerplexityPlugin) + const result = yield* plugin.trigger( + "aisdk.language", + { + model: model("perplexity", "alias", { apiID: ModelV2.ID.make("sonar") }), + sdk: fakeSelectorSdk(calls), + options: {}, + }, + {}, + ) + expect(calls).toEqual([]) + expect(result.language).toBeUndefined() + }), + ) +}) diff --git a/packages/core/test/plugin/provider-sap-ai-core.test.ts b/packages/core/test/plugin/provider-sap-ai-core.test.ts new file mode 100644 index 00000000000..565b9280ab9 --- /dev/null +++ b/packages/core/test/plugin/provider-sap-ai-core.test.ts @@ -0,0 +1,127 @@ +import { describe, expect } from "bun:test" +import { Effect } from "effect" +import { PluginV2 } from "@opencode-ai/core/plugin" +import { SapAICorePlugin } from "@opencode-ai/core/plugin/provider/sap-ai-core" +import { fixtureProvider, it, model, npmLayer, withEnv } from "./provider-helper" + +const pluginWithNpm = { id: SapAICorePlugin.id, effect: SapAICorePlugin.effect.pipe(Effect.provide(npmLayer)) } + +describe("SapAICorePlugin", () => { + it.effect("copies serviceKey option into AICORE_SERVICE_KEY but keeps SDK options to deployment metadata", () => + withEnv( + { AICORE_SERVICE_KEY: undefined, AICORE_DEPLOYMENT_ID: "deployment", AICORE_RESOURCE_GROUP: "resource-group" }, + () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(pluginWithNpm) + const sdk = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("sap-ai-core", "sap-model"), + package: fixtureProvider, + options: { name: "sap-ai-core", serviceKey: "service-key" }, + }, + {}, + ) + expect(process.env.AICORE_SERVICE_KEY).toBe("service-key") + expect(sdk.sdk.options).toEqual({ deploymentId: "deployment", resourceGroup: "resource-group" }) + }), + ), + ) + + it.effect("preserves existing AICORE_SERVICE_KEY over serviceKey option", () => + withEnv( + { + AICORE_SERVICE_KEY: "env-service-key", + AICORE_DEPLOYMENT_ID: "deployment", + AICORE_RESOURCE_GROUP: "resource-group", + }, + () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(pluginWithNpm) + const sdk = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("sap-ai-core", "sap-model"), + package: fixtureProvider, + options: { name: "sap-ai-core", serviceKey: "option-service-key" }, + }, + {}, + ) + expect(process.env.AICORE_SERVICE_KEY).toBe("env-service-key") + expect(sdk.sdk.options).toEqual({ deploymentId: "deployment", resourceGroup: "resource-group" }) + }), + ), + ) + + it.effect("omits deployment and resourceGroup SDK options when no service key is available", () => + withEnv( + { AICORE_SERVICE_KEY: undefined, AICORE_DEPLOYMENT_ID: "deployment", AICORE_RESOURCE_GROUP: "resource-group" }, + () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(pluginWithNpm) + const sdk = yield* plugin.trigger( + "aisdk.sdk", + { model: model("sap-ai-core", "sap-model"), package: fixtureProvider, options: { name: "sap-ai-core" } }, + {}, + ) + expect(process.env.AICORE_SERVICE_KEY).toBeUndefined() + expect(sdk.sdk.options).toEqual({}) + }), + ), + ) + + it.effect("uses the callable SDK for language selection", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(pluginWithNpm) + const sdk = Object.assign((modelID: string) => ({ modelID, provider: "callable" }), { + languageModel() { + throw new Error("SAP AI Core should call the SDK directly") + }, + }) + const language = yield* plugin.trigger( + "aisdk.language", + { model: model("sap-ai-core", "sap-model"), sdk, options: {} }, + {}, + ) + expect(language.language as unknown).toEqual({ modelID: "sap-model", provider: "callable" }) + }), + ) + + it.effect("ignores non-SAP AI Core providers", () => + withEnv( + { AICORE_SERVICE_KEY: undefined, AICORE_DEPLOYMENT_ID: "deployment", AICORE_RESOURCE_GROUP: "resource-group" }, + () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(pluginWithNpm) + const sdk = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("openai", "sap-model"), + package: fixtureProvider, + options: { name: "openai", serviceKey: "service-key" }, + }, + {}, + ) + const language = yield* plugin.trigger( + "aisdk.language", + { + model: model("openai", "sap-model"), + sdk: () => { + throw new Error("SAP AI Core should ignore other providers") + }, + options: {}, + }, + {}, + ) + expect(process.env.AICORE_SERVICE_KEY).toBeUndefined() + expect(sdk.sdk).toBeUndefined() + expect(language.language).toBeUndefined() + }), + ), + ) +}) diff --git a/packages/core/test/plugin/provider-togetherai.test.ts b/packages/core/test/plugin/provider-togetherai.test.ts new file mode 100644 index 00000000000..65090037bef --- /dev/null +++ b/packages/core/test/plugin/provider-togetherai.test.ts @@ -0,0 +1,97 @@ +import { describe, expect } from "bun:test" +import { Effect } from "effect" +import { PluginV2 } from "@opencode-ai/core/plugin" +import { TogetherAIPlugin } from "@opencode-ai/core/plugin/provider/togetherai" +import { fakeSelectorSdk, it, model } from "./provider-helper" + +describe("TogetherAIPlugin", () => { + it.effect("creates a TogetherAI SDK for @ai-sdk/togetherai", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(TogetherAIPlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { model: model("togetherai", "model"), package: "@ai-sdk/togetherai", options: { name: "togetherai" } }, + {}, + ) + expect(result.sdk).toBeDefined() + }), + ) + + it.effect("matches the old bundled provider package exactly", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(TogetherAIPlugin) + + const ignored = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("togetherai", "model"), + package: "file:///tmp/@ai-sdk/togetherai-provider.js", + options: { name: "togetherai" }, + }, + {}, + ) + expect(ignored.sdk).toBeUndefined() + + const result = yield* plugin.trigger( + "aisdk.sdk", + { model: model("togetherai", "model"), package: "@ai-sdk/togetherai", options: { name: "togetherai" } }, + {}, + ) + expect(result.sdk).toBeDefined() + }), + ) + + it.effect("creates bundled TogetherAI SDKs for custom provider IDs", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const observed: string[] = [] + yield* plugin.add(TogetherAIPlugin) + yield* plugin.add({ + id: PluginV2.ID.make("inspector"), + effect: Effect.succeed({ + "aisdk.sdk": (evt) => + Effect.sync(() => { + observed.push(evt.sdk.languageModel("model").provider) + }), + }), + }) + + yield* plugin.trigger( + "aisdk.sdk", + { + model: model("custom-togetherai", "model"), + package: "@ai-sdk/togetherai", + options: { name: "custom-togetherai" }, + }, + {}, + ) + + expect(observed).toEqual(["togetherai.chat"]) + }), + ) + + it.effect("defaults language selection to sdk.languageModel with the model API ID", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const calls: string[] = [] + yield* plugin.add(TogetherAIPlugin) + + const result = yield* plugin.trigger( + "aisdk.language", + { + model: model("togetherai", "meta-llama/Llama-3.3-70B-Instruct-Turbo"), + sdk: { languageModel: fakeSelectorSdk(calls).languageModel }, + options: {}, + }, + {}, + ) + + expect(result.language).toBeUndefined() + expect(calls).toEqual([]) + expect(result.language ?? fakeSelectorSdk(calls).languageModel(result.model.apiID)).toBeDefined() + expect(calls).toEqual(["languageModel:meta-llama/Llama-3.3-70B-Instruct-Turbo"]) + }), + ) +}) diff --git a/packages/core/test/plugin/provider-venice.test.ts b/packages/core/test/plugin/provider-venice.test.ts new file mode 100644 index 00000000000..ff4a922ab1e --- /dev/null +++ b/packages/core/test/plugin/provider-venice.test.ts @@ -0,0 +1,86 @@ +import { describe, expect } from "bun:test" +import { Effect } from "effect" +import { PluginV2 } from "@opencode-ai/core/plugin" +import { VenicePlugin } from "@opencode-ai/core/plugin/provider/venice" +import { fakeSelectorSdk, it, model } from "./provider-helper" + +describe("VenicePlugin", () => { + it.effect("creates a Venice SDK for venice-ai-sdk-provider", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(VenicePlugin) + const result = yield* plugin.trigger( + "aisdk.sdk", + { model: model("venice", "model"), package: "venice-ai-sdk-provider", options: { name: "venice" } }, + {}, + ) + expect(result.sdk).toBeDefined() + }), + ) + + it.effect("uses the model provider ID as the bundled Venice SDK name", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const observed: string[] = [] + yield* plugin.add(VenicePlugin) + yield* plugin.add({ + id: PluginV2.ID.make("inspector"), + effect: Effect.succeed({ + "aisdk.sdk": (evt) => + Effect.sync(() => { + observed.push(evt.sdk.languageModel("model").provider) + }), + }), + }) + const result = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("custom-venice", "model"), + package: "venice-ai-sdk-provider", + options: { name: "custom-venice", apiKey: "test" }, + }, + {}, + ) + expect(result.sdk).toBeDefined() + expect(observed).toEqual(["custom-venice.chat"]) + }), + ) + + it.effect("only handles the bundled venice-ai-sdk-provider package", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(VenicePlugin) + const similar = yield* plugin.trigger( + "aisdk.sdk", + { + model: model("venice", "model"), + package: "file:///tmp/venice-ai-sdk-provider.js", + options: { name: "venice" }, + }, + {}, + ) + const other = yield* plugin.trigger( + "aisdk.sdk", + { model: model("venice", "model"), package: "@ai-sdk/openai-compatible", options: { name: "venice" } }, + {}, + ) + expect(similar.sdk).toBeUndefined() + expect(other.sdk).toBeUndefined() + }), + ) + + it.effect("leaves Venice language selection to the default languageModel fallback", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const calls: string[] = [] + yield* plugin.add(VenicePlugin) + const result = yield* plugin.trigger( + "aisdk.language", + { model: model("venice", "alias"), sdk: fakeSelectorSdk(calls), options: {} }, + {}, + ) + expect(calls).toEqual([]) + expect(result.language).toBeUndefined() + }), + ) +}) diff --git a/packages/core/test/plugin/provider-vercel.test.ts b/packages/core/test/plugin/provider-vercel.test.ts new file mode 100644 index 00000000000..53045ca47f3 --- /dev/null +++ b/packages/core/test/plugin/provider-vercel.test.ts @@ -0,0 +1,62 @@ +import { describe, expect } from "bun:test" +import { Effect } from "effect" +import { PluginV2 } from "@opencode-ai/core/plugin" +import { VercelPlugin } from "@opencode-ai/core/plugin/provider/vercel" +import { it, model, provider } from "./provider-helper" + +describe("VercelPlugin", () => { + it.effect("applies legacy lower-case referer headers", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(VercelPlugin) + const result = yield* plugin.trigger( + "provider.update", + {}, + { + provider: provider("vercel", { + options: { headers: { Existing: "1" }, body: {}, aisdk: { provider: {}, request: {} } }, + }), + cancel: false, + }, + ) + expect(result.provider.options.headers).toEqual({ + Existing: "1", + "http-referer": "https://kilo.ai/", + "x-title": "Kilo Code", + }) + }), + ) + + it.effect("does not add legacy upper-case referer headers", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(VercelPlugin) + const result = yield* plugin.trigger("provider.update", {}, { provider: provider("vercel"), cancel: false }) + expect(result.provider.options.headers).not.toHaveProperty("HTTP-Referer") + expect(result.provider.options.headers).not.toHaveProperty("X-Title") + }), + ) + + it.effect("creates @ai-sdk/vercel SDKs for custom provider IDs", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(VercelPlugin) + const event = yield* plugin.trigger( + "aisdk.sdk", + { model: model("custom-vercel", "v0-1.0-md"), package: "@ai-sdk/vercel", options: { name: "custom-vercel" } }, + {}, + ) + expect(event.sdk).toBeDefined() + expect(event.sdk.languageModel("v0-1.0-md").provider).toBe("vercel.chat") + }), + ) + + it.effect("ignores non-Vercel providers", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(VercelPlugin) + const result = yield* plugin.trigger("provider.update", {}, { provider: provider("gateway"), cancel: false }) + expect(result.provider.options.headers).toEqual({}) + }), + ) +}) diff --git a/packages/core/test/plugin/provider-xai.test.ts b/packages/core/test/plugin/provider-xai.test.ts new file mode 100644 index 00000000000..63af32dae7d --- /dev/null +++ b/packages/core/test/plugin/provider-xai.test.ts @@ -0,0 +1,115 @@ +import { describe, expect } from "bun:test" +import { Effect } from "effect" +import { ModelV2 } from "@opencode-ai/core/model" +import { PluginV2 } from "@opencode-ai/core/plugin" +import { XAIPlugin } from "@opencode-ai/core/plugin/provider/xai" +import { ProviderV2 } from "@opencode-ai/core/provider" +import { testEffect } from "../lib/effect" +import { fakeSelectorSdk } from "./provider-helper" + +const it = testEffect(PluginV2.defaultLayer) + +const model = new ModelV2.Info({ + ...ModelV2.Info.empty(ProviderV2.ID.make("xai"), ModelV2.ID.make("grok-4")), + apiID: ModelV2.ID.make("grok-4"), + endpoint: { + type: "aisdk", + package: "@ai-sdk/xai", + }, +}) + +describe("XAIPlugin", () => { + it.effect("creates an xAI SDK only for @ai-sdk/xai", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(XAIPlugin) + + const ignored = yield* plugin.trigger( + "aisdk.sdk", + { model, package: "@ai-sdk/openai-compatible", options: {} }, + {}, + ) + + const result = yield* plugin.trigger("aisdk.sdk", { model, package: "@ai-sdk/xai", options: {} }, {}) + + expect(ignored.sdk).toBeUndefined() + expect(typeof result.sdk?.responses).toBe("function") + }), + ) + + it.effect("creates xAI SDKs for custom provider IDs", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const providers: string[] = [] + + yield* plugin.add(XAIPlugin) + yield* plugin.add( + PluginV2.define({ + id: PluginV2.ID.make("xai-sdk-name-observer"), + effect: Effect.gen(function* () { + return { + "aisdk.sdk": Effect.fn(function* (evt) { + if (!evt.sdk) return + providers.push(evt.sdk.responses("grok-4").provider) + }), + } + }), + }), + ) + + yield* plugin.trigger( + "aisdk.sdk", + { + model: new ModelV2.Info({ ...model, providerID: ProviderV2.ID.make("custom-xai") }), + package: "@ai-sdk/xai", + options: {}, + }, + {}, + ) + + expect(providers).toEqual(["xai.responses"]) + }), + ) + + it.effect("uses responses with the model apiID for xAI language models", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const calls: string[] = [] + + yield* plugin.add(XAIPlugin) + const result = yield* plugin.trigger( + "aisdk.language", + { + model: new ModelV2.Info({ ...model, id: ModelV2.ID.make("alias"), apiID: ModelV2.ID.make("grok-4") }), + sdk: fakeSelectorSdk(calls), + options: {}, + }, + {}, + ) + + expect(calls).toEqual(["responses:grok-4"]) + expect(result.language).toBeDefined() + }), + ) + + it.effect("ignores non-xAI providers", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + const calls: string[] = [] + + yield* plugin.add(XAIPlugin) + const result = yield* plugin.trigger( + "aisdk.language", + { + model: new ModelV2.Info({ ...model, providerID: ProviderV2.ID.openai }), + sdk: fakeSelectorSdk(calls), + options: {}, + }, + {}, + ) + + expect(calls).toEqual([]) + expect(result.language).toBeUndefined() + }), + ) +}) diff --git a/packages/core/test/plugin/provider-zenmux.test.ts b/packages/core/test/plugin/provider-zenmux.test.ts new file mode 100644 index 00000000000..be90baee926 --- /dev/null +++ b/packages/core/test/plugin/provider-zenmux.test.ts @@ -0,0 +1,103 @@ +import { describe, expect } from "bun:test" +import { Effect } from "effect" +import { PluginV2 } from "@opencode-ai/core/plugin" +import { ProviderPlugins } from "@opencode-ai/core/plugin/provider" +import { ZenmuxPlugin } from "@opencode-ai/core/plugin/provider/zenmux" +import { expectPluginRegistered, it, provider } from "./provider-helper" + +describe("ZenmuxPlugin", () => { + it.effect("is registered so legacy referer headers can be applied", () => + Effect.sync(() => + expectPluginRegistered( + ProviderPlugins.map((item) => item.id), + "zenmux", + ), + ), + ) + + it.effect("applies the exact legacy Zenmux headers", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(ZenmuxPlugin) + const result = yield* plugin.trigger("provider.update", {}, { provider: provider("zenmux"), cancel: false }) + expect(result.provider.options.headers).toEqual({ "HTTP-Referer": "https://kilo.ai/", "X-Title": "Kilo Code" }) + expect(Object.keys(result.provider.options.headers).sort()).toEqual(["HTTP-Referer", "X-Title"]) + expect(result.cancel).toBe(false) + }), + ) + + it.effect("merges legacy Zenmux headers with existing headers", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(ZenmuxPlugin) + const result = yield* plugin.trigger( + "provider.update", + {}, + { + provider: provider("zenmux", { + options: { headers: { Existing: "value" }, body: {}, aisdk: { provider: {}, request: {} } }, + }), + cancel: false, + }, + ) + + expect(result.provider.options.headers).toEqual({ + Existing: "value", + "HTTP-Referer": "https://kilo.ai/", + "X-Title": "Kilo Code", + }) + }), + ) + + it.effect("lets configured Zenmux legacy headers override defaults", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(ZenmuxPlugin) + const result = yield* plugin.trigger( + "provider.update", + {}, + { + provider: provider("zenmux", { + options: { + headers: { "HTTP-Referer": "https://example.com/", "X-Title": "custom-title" }, + body: {}, + aisdk: { provider: {}, request: {} }, + }, + }), + cancel: false, + }, + ) + + expect(result.provider.options.headers).toEqual({ + "HTTP-Referer": "https://example.com/", + "X-Title": "custom-title", + }) + }), + ) + + it.effect("guards legacy Zenmux headers to the exact zenmux provider id", () => + Effect.gen(function* () { + const plugin = yield* PluginV2.Service + yield* plugin.add(ZenmuxPlugin) + const ignored = yield* plugin.trigger( + "provider.update", + {}, + { + provider: provider("openrouter", { + options: { + headers: { "HTTP-Referer": "https://example.com/", "X-Title": "custom-title" }, + body: {}, + aisdk: { provider: {}, request: {} }, + }, + }), + cancel: false, + }, + ) + + expect(ignored.provider.options.headers).toEqual({ + "HTTP-Referer": "https://example.com/", + "X-Title": "custom-title", + }) + }), + ) +}) diff --git a/packages/core/test/process/process.test.ts b/packages/core/test/process/process.test.ts new file mode 100644 index 00000000000..f6a52b7a687 --- /dev/null +++ b/packages/core/test/process/process.test.ts @@ -0,0 +1,292 @@ +import { describe, expect } from "bun:test" +import { realpathSync } from "node:fs" +import { tmpdir } from "node:os" +import { Effect, Exit, Stream } from "effect" +import { ChildProcess } from "effect/unstable/process" +import { AppProcess } from "@opencode-ai/core/process" +import { testEffect } from "../lib/effect" + +const it = testEffect(AppProcess.defaultLayer) + +const NODE = process.execPath +const cmd = (...args: string[]) => ChildProcess.make(NODE, args) + +describe("AppProcess", () => { + describe("run", () => { + it.effect( + "captures stdout and exit code zero", + Effect.gen(function* () { + const svc = yield* AppProcess.Service + const result = yield* svc.run(cmd("-e", "process.stdout.write('hi\\n')")) + expect(result.exitCode).toBe(0) + expect(result.stdout.toString("utf8")).toBe("hi\n") + expect(result.stdoutTruncated).toBe(false) + expect(result.stderrTruncated).toBe(false) + }), + ) + + it.effect( + "non-zero exit returns RunResult; caller can require success", + Effect.gen(function* () { + const svc = yield* AppProcess.Service + const result = yield* svc.run(cmd("-e", "process.exit(1)")) + expect(result.exitCode).toBe(1) + }), + ) + + it.effect( + "requireSuccess fails on non-zero exit", + Effect.gen(function* () { + const svc = yield* AppProcess.Service + const exit = yield* Effect.exit( + svc.run(cmd("-e", "process.exit(1)")).pipe(Effect.flatMap(AppProcess.requireSuccess)), + ) + expect(Exit.isFailure(exit)).toBe(true) + if (Exit.isFailure(exit)) { + const reason = exit.cause.reasons[0] + if (reason && reason._tag === "Fail") { + expect(reason.error).toBeInstanceOf(AppProcess.AppProcessError) + expect((reason.error as AppProcess.AppProcessError).exitCode).toBe(1) + } else { + throw new Error("expected fail reason") + } + } + }), + ) + + it.effect( + "requireSuccess succeeds on exit 0", + Effect.gen(function* () { + const svc = yield* AppProcess.Service + const result = yield* svc.run(cmd("-e", "process.exit(0)")).pipe(Effect.flatMap(AppProcess.requireSuccess)) + expect(result.exitCode).toBe(0) + }), + ) + + it.effect( + "requireExitIn allowlists multiple exit codes", + Effect.gen(function* () { + const svc = yield* AppProcess.Service + const requireZeroOrOne = AppProcess.requireExitIn([0, 1]) + const okZero = yield* svc.run(cmd("-e", "process.exit(0)")).pipe(Effect.flatMap(requireZeroOrOne)) + expect(okZero.exitCode).toBe(0) + const okOne = yield* svc.run(cmd("-e", "process.exit(1)")).pipe(Effect.flatMap(requireZeroOrOne)) + expect(okOne.exitCode).toBe(1) + const exit = yield* Effect.exit(svc.run(cmd("-e", "process.exit(2)")).pipe(Effect.flatMap(requireZeroOrOne))) + expect(Exit.isFailure(exit)).toBe(true) + if (Exit.isFailure(exit)) { + const reason = exit.cause.reasons[0] + if (reason && reason._tag === "Fail") { + expect(reason.error).toBeInstanceOf(AppProcess.AppProcessError) + expect((reason.error as AppProcess.AppProcessError).exitCode).toBe(2) + } + } + }), + ) + + it.effect( + "truncates stdout when maxOutputBytes is set", + Effect.gen(function* () { + const svc = yield* AppProcess.Service + const result = yield* svc.run(cmd("-e", "process.stdout.write('0123456789')"), { maxOutputBytes: 5 }) + expect(result.exitCode).toBe(0) + expect(result.stdoutTruncated).toBe(true) + expect(result.stderrTruncated).toBe(false) + expect(result.stdout.length).toBe(5) + expect(result.stdout.toString("utf8")).toBe("01234") + }), + ) + + it.effect( + "truncates stderr when maxErrorBytes is set", + Effect.gen(function* () { + const svc = yield* AppProcess.Service + const result = yield* svc.run(cmd("-e", "process.stderr.write('0123456789')"), { maxErrorBytes: 5 }) + expect(result.exitCode).toBe(0) + expect(result.stdoutTruncated).toBe(false) + expect(result.stderrTruncated).toBe(true) + expect(result.stderr.length).toBe(5) + expect(result.stderr.toString("utf8")).toBe("01234") + }), + ) + + it.effect( + "result includes command description", + Effect.gen(function* () { + const svc = yield* AppProcess.Service + const result = yield* svc.run(cmd("-e", "process.stdout.write('hi')")) + expect(result.command).toBe(`${NODE} -e process.stdout.write('hi')`) + }), + ) + }) + + describe("inherited platform methods", () => { + it.effect( + "string returns stdout as string", + Effect.gen(function* () { + const svc = yield* AppProcess.Service + const out = yield* svc.string(cmd("-e", "process.stdout.write('hi\\n')")) + expect(out).toBe("hi\n") + }), + ) + + it.effect( + "lines returns the platform's array of lines", + Effect.gen(function* () { + const svc = yield* AppProcess.Service + const out = yield* svc.lines(cmd("-e", "process.stdout.write('a\\nb\\n')")) + expect(Array.from(out)).toEqual(["a", "b"]) + }), + ) + }) + + describe("run with stdin option", () => { + const echoStdin = "process.stdin.on('data', c => process.stdout.write(c))" + + it.effect( + "feeds a string to stdin and returns it on stdout", + Effect.gen(function* () { + const svc = yield* AppProcess.Service + const result = yield* svc.run(cmd("-e", echoStdin), { stdin: "hello" }) + expect(result.exitCode).toBe(0) + expect(result.stdout.toString("utf8")).toBe("hello") + }), + ) + + it.effect( + "feeds a Uint8Array to stdin", + Effect.gen(function* () { + const svc = yield* AppProcess.Service + const bytes = new TextEncoder().encode("bytes") + const result = yield* svc.run(cmd("-e", echoStdin), { stdin: bytes }) + expect(result.exitCode).toBe(0) + expect(result.stdout.toString("utf8")).toBe("bytes") + }), + ) + + it.effect( + "feeds a Stream of Uint8Array chunks to stdin", + Effect.gen(function* () { + const svc = yield* AppProcess.Service + const enc = new TextEncoder() + const stream = Stream.fromIterable([enc.encode("one"), enc.encode("-two"), enc.encode("-three")]) + const result = yield* svc.run(cmd("-e", echoStdin), { stdin: stream }) + expect(result.exitCode).toBe(0) + expect(result.stdout.toString("utf8")).toBe("one-two-three") + }), + ) + + it.effect( + "completes correctly with empty input", + Effect.gen(function* () { + const svc = yield* AppProcess.Service + const result = yield* svc.run(cmd("-e", echoStdin), { stdin: "" }) + expect(result.exitCode).toBe(0) + expect(result.stdout.toString("utf8")).toBe("") + }), + ) + + it.effect( + "carries existing Command options like env", + Effect.gen(function* () { + const svc = yield* AppProcess.Service + const script = + "process.stdout.write(process.env.FEED + ':'); process.stdin.on('data', c => process.stdout.write(c))" + const command = ChildProcess.make(NODE, ["-e", script], { env: { FEED: "envset" }, extendEnv: true }) + const result = yield* svc.run(command, { stdin: "payload" }) + expect(result.exitCode).toBe(0) + expect(result.stdout.toString("utf8")).toBe("envset:payload") + }), + ) + + it.effect( + "carries existing Command options like cwd", + Effect.gen(function* () { + const svc = yield* AppProcess.Service + const dir = realpathSync(tmpdir()) + const script = + "process.stdout.write(process.cwd() + '|'); process.stdin.on('data', c => process.stdout.write(c))" + const command = ChildProcess.make(NODE, ["-e", script], { cwd: dir }) + const result = yield* svc.run(command, { stdin: "ok" }) + expect(result.exitCode).toBe(0) + const [cwd, stdin] = result.stdout.toString("utf8").split("|") + expect(realpathSync(cwd)).toBe(dir) + expect(stdin).toBe("ok") + }), + ) + }) + + describe("runStream", () => { + it.live( + "emits lines incrementally and ends cleanly on exit 0", + Effect.gen(function* () { + const svc = yield* AppProcess.Service + const result = yield* svc + .runStream(cmd("-e", "console.log('one'); console.log('two'); console.log('three')")) + .pipe(Stream.runCollect) + expect(Array.from(result)).toEqual(["one", "two", "three"]) + }), + ) + + it.live( + "okExitCodes determines whether a non-zero exit fails the stream", + Effect.gen(function* () { + const svc = yield* AppProcess.Service + const allowed = yield* svc + .runStream(cmd("-e", "console.log('only'); process.exit(1)"), { okExitCodes: [0, 1] }) + .pipe(Stream.runCollect) + expect(Array.from(allowed)).toEqual(["only"]) + const exit = yield* Effect.exit( + svc + .runStream(cmd("-e", "console.log('a'); process.exit(2)"), { okExitCodes: [0, 1] }) + .pipe(Stream.runCollect), + ) + expect(Exit.isFailure(exit)).toBe(true) + if (Exit.isFailure(exit)) { + const reason = exit.cause.reasons[0] + if (reason && reason._tag === "Fail") { + expect(reason.error).toBeInstanceOf(AppProcess.AppProcessError) + } + } + }), + ) + + it.live( + "without okExitCodes, never fails on exit code", + Effect.gen(function* () { + const svc = yield* AppProcess.Service + const result = yield* svc.runStream(cmd("-e", "console.log('only'); process.exit(7)")).pipe(Stream.runCollect) + expect(Array.from(result)).toEqual(["only"]) + }), + ) + + it.live( + "AbortSignal interrupts the stream", + Effect.gen(function* () { + const svc = yield* AppProcess.Service + const controller = new AbortController() + controller.abort() + const exit = yield* Effect.exit( + svc + .runStream(cmd("-e", "setInterval(() => {}, 60_000)"), { signal: controller.signal }) + .pipe(Stream.runCollect), + ) + expect(Exit.isFailure(exit)).toBe(true) + }), + ) + }) + + describe("spawn (inherited)", () => { + it.live( + "returns the platform ChildProcessHandle for advanced use", + Effect.scoped( + Effect.gen(function* () { + const svc = yield* AppProcess.Service + const handle = yield* svc.spawn(cmd("-e", "setInterval(() => {}, 1_000)")) + expect(yield* handle.isRunning).toBe(true) + yield* handle.kill() + }), + ), + ) + }) +}) diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json index 4bb417f5b41..25530eb0e6f 100644 --- a/packages/core/tsconfig.json +++ b/packages/core/tsconfig.json @@ -3,6 +3,7 @@ "extends": "@tsconfig/bun/tsconfig.json", "compilerOptions": { "noUncheckedIndexedAccess": false, - "types": ["bun"] + "types": ["bun"], + "lib": ["ESNext", "DOM", "DOM.Iterable"] } } diff --git a/packages/extensions/zed/extension.toml b/packages/extensions/zed/extension.toml index 7aefe40497c..c339ebfb6e5 100644 --- a/packages/extensions/zed/extension.toml +++ b/packages/extensions/zed/extension.toml @@ -1,7 +1,7 @@ id = "kilo" name = "Kilo" description = "The open source coding agent." -version = "7.3.41" +version = "7.3.42" schema_version = 1 authors = ["Anomaly"] repository = "https://github.com/Kilo-Org/kilocode" @@ -11,26 +11,26 @@ name = "Kilo" icon = "./icons/opencode.svg" [agent_servers.opencode.targets.darwin-aarch64] -archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.3.41/opencode-darwin-arm64.zip" +archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.3.42/opencode-darwin-arm64.zip" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.darwin-x86_64] -archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.3.41/opencode-darwin-x64.zip" +archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.3.42/opencode-darwin-x64.zip" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.linux-aarch64] -archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.3.41/opencode-linux-arm64.tar.gz" +archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.3.42/opencode-linux-arm64.tar.gz" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.linux-x86_64] -archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.3.41/opencode-linux-x64.tar.gz" +archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.3.42/opencode-linux-x64.tar.gz" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.windows-x86_64] -archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.3.41/opencode-windows-x64.zip" +archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.3.42/opencode-windows-x64.zip" cmd = "./opencode.exe" args = ["acp"] diff --git a/packages/http-recorder/README.md b/packages/http-recorder/README.md index f6aaed4358d..f527dd0cca0 100644 --- a/packages/http-recorder/README.md +++ b/packages/http-recorder/README.md @@ -70,19 +70,15 @@ Cassettes are normal source files — review them, diff them, commit them. ## Request matching -By default, requests match on canonicalized method, URL, headers, and JSON -body (object keys sorted). Two dispatch strategies are available: +Replay walks the cassette in record order via an internal cursor: the Nth +request executed at runtime is served by the Nth recorded interaction, and +each one is validated as the cursor advances. Request equality is computed +on canonicalized method, URL, headers, and JSON body (object keys sorted). -- **`match`** (default) — find the first recorded interaction whose request - matches the incoming request. Same request twice returns the same response. -- **`sequential`** — return interactions in the order they were recorded, - validating each one matches as the cursor advances. Use for ordered flows - where the same URL is hit multiple times with meaningful state changes - (pagination, retries, polling). - -```ts -HttpRecorder.cassetteLayer("flow/poll-until-done", { dispatch: "sequential" }) -``` +This is deliberately strict — content-based dispatch was removed because +it silently returns the first recorded response for repeated identical +requests, masking state changes that retry/polling/cache-hit tests need to +observe. If you reorder requests in a test, re-record the cassette. Supply your own matcher via `match: (incoming, recorded) => boolean` for custom equivalence (e.g. ignoring a timestamp field in the body). @@ -170,11 +166,11 @@ import { Effect } from "effect" const audit = Effect.gen(function* () { const cassettes = yield* HttpRecorder.Cassette.Service - const entries = yield* cassettes.list() - const issues = yield* Effect.forEach(entries, (entry) => + const names = yield* cassettes.list() + const issues = yield* Effect.forEach(names, (name) => cassettes - .read(entry.name) - .pipe(Effect.map((interactions) => ({ name: entry.name, findings: HttpRecorder.secretFindings(interactions) }))), + .read(name) + .pipe(Effect.map((interactions) => ({ name, findings: HttpRecorder.secretFindings(interactions) }))), ) return issues.filter((i) => i.findings.length > 0) }) @@ -194,21 +190,19 @@ type RecordReplayOptions = { directory?: string // default: /test/fixtures/recordings metadata?: Record // merged into cassette.metadata redactor?: Redactor // default: Redactor.defaults() - dispatch?: "match" | "sequential" // default: "match" match?: (incoming, recorded) => boolean // custom matcher } ``` ## Layout -| File | Purpose | -| -------------- | -------------------------------------------------------------------------------- | -| `effect.ts` | `cassetteLayer` / `recordingLayer` — the `HttpClient` adapter. | -| `websocket.ts` | `makeWebSocketExecutor` — WebSocket record/replay. | -| `cassette.ts` | `Cassette.Service` — reads/writes cassette files, accumulates state. | -| `recorder.ts` | Shared transport plumbing: `UnsafeCassetteError`, `appendOrFail`, `ReplayState`. | -| `redactor.ts` | Composable `Redactor` — headers, url, body redaction. | -| `redaction.ts` | Lower-level header/URL primitives + secret pattern detection. | -| `schema.ts` | Effect Schema definitions for the cassette JSON format. | -| `storage.ts` | Path resolution, JSON encode/decode, sync existence check. | -| `matching.ts` | Request matcher, canonicalization, dispatch strategies, mismatch diagnostics. | +| File | Purpose | +| -------------- | --------------------------------------------------------------------------- | +| `effect.ts` | `cassetteLayer` / `recordingLayer` — the `HttpClient` adapter. | +| `websocket.ts` | `makeWebSocketExecutor` — WebSocket record/replay. | +| `cassette.ts` | `Cassette.Service` — `fileSystem` / `memory` adapters, error types. | +| `recorder.ts` | Shared transport plumbing: `resolveAutoMode`, `ReplayState`. | +| `redactor.ts` | Composable `Redactor` — headers, url, body redaction. | +| `redaction.ts` | Lower-level header/URL primitives + secret pattern detection. | +| `schema.ts` | Effect Schema definitions for the cassette JSON format. | +| `matching.ts` | Request matcher, canonicalization, sequential cursor, mismatch diagnostics. | diff --git a/packages/http-recorder/package.json b/packages/http-recorder/package.json index 359c526f2f6..f56ba06f6e0 100644 --- a/packages/http-recorder/package.json +++ b/packages/http-recorder/package.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/package.json", - "version": "7.3.41", + "version": "7.3.42", "name": "@opencode-ai/http-recorder", "type": "module", "license": "MIT", diff --git a/packages/http-recorder/src/cassette.ts b/packages/http-recorder/src/cassette.ts index 3897f0222c4..331f3d4b600 100644 --- a/packages/http-recorder/src/cassette.ts +++ b/packages/http-recorder/src/cassette.ts @@ -1,7 +1,7 @@ import { Context, Effect, FileSystem, Layer, Schema } from "effect" import * as fs from "node:fs" import * as path from "node:path" -import { secretFindings, type SecretFinding } from "./redaction" +import { secretFindings, SecretFindingSchema, type SecretFinding } from "./redaction" import { decodeCassette, encodeCassette, type Cassette, type CassetteMetadata, type Interaction } from "./schema" const DEFAULT_RECORDINGS_DIR = path.resolve(process.cwd(), "test", "fixtures", "recordings") @@ -14,13 +14,24 @@ export class CassetteNotFoundError extends Schema.TaggedErrorClass +export class UnsafeCassetteError extends Schema.TaggedErrorClass()("UnsafeCassetteError", { + cassetteName: Schema.String, + findings: Schema.Array(SecretFindingSchema), +}) { + override get message() { + return `Refusing to write cassette "${this.cassetteName}" because it contains possible secrets: ${this.findings + .map((finding) => `${finding.path} (${finding.reason})`) + .join(", ")}` + } } export interface Interface { readonly read: (name: string) => Effect.Effect, CassetteNotFoundError> - readonly append: (name: string, interaction: Interaction, metadata?: CassetteMetadata) => Effect.Effect + readonly append: ( + name: string, + interaction: Interaction, + metadata?: CassetteMetadata, + ) => Effect.Effect readonly exists: (name: string) => Effect.Effect readonly list: () => Effect.Effect> } @@ -44,6 +55,9 @@ const formatCassette = (cassette: Cassette) => `${JSON.stringify(encodeCassette( const parseCassette = (raw: string) => decodeCassette(JSON.parse(raw)) +const failIfUnsafe = (name: string, findings: ReadonlyArray) => + findings.length === 0 ? Effect.void : Effect.fail(new UnsafeCassetteError({ cassetteName: name, findings })) + export const fileSystem = ( options: { readonly directory?: string } = {}, ): Layer.Layer => @@ -92,11 +106,9 @@ export const fileSystem = ( entry.findings.push(...secretFindings(interaction)) const cassette = buildCassette(name, entry.interactions, metadata) const findings = [...entry.findings, ...secretFindings(cassette.metadata ?? {})] - if (findings.length === 0) { - yield* ensureDirectory(name) - yield* fs.writeFileString(cassettePath(name), formatCassette(cassette)).pipe(Effect.orDie) - } - return { findings } + yield* failIfUnsafe(name, findings) + yield* ensureDirectory(name) + yield* fs.writeFileString(cassettePath(name), formatCassette(cassette)).pipe(Effect.orDie) }), exists: (name) => fs.access(cassettePath(name)).pipe( @@ -133,17 +145,17 @@ export const memory = (initial: Record> = {}) stored.has(name) ? Effect.succeed(stored.get(name) ?? []) : Effect.fail(new CassetteNotFoundError({ cassetteName: name })), - append: (name, interaction, metadata) => - Effect.sync(() => { - const existing = stored.get(name) - if (existing) existing.push(interaction) - else stored.set(name, [interaction]) - const findings = accumulatedFindings.get(name) - if (findings) findings.push(...secretFindings(interaction)) - else accumulatedFindings.set(name, [...secretFindings(interaction)]) - if (metadata) accumulatedFindings.get(name)!.push(...secretFindings({ name, ...metadata })) - return { findings: accumulatedFindings.get(name) ?? [] } - }), + append: (name, interaction, metadata) => { + const existing = stored.get(name) + if (existing) existing.push(interaction) + else stored.set(name, [interaction]) + const existingFindings = accumulatedFindings.get(name) + const findings = existingFindings ?? [] + if (!existingFindings) accumulatedFindings.set(name, findings) + findings.push(...secretFindings(interaction)) + if (metadata) findings.push(...secretFindings({ name, ...metadata })) + return failIfUnsafe(name, findings) + }, exists: (name) => Effect.sync(() => stored.has(name)), list: () => Effect.sync(() => Array.from(stored.keys()).toSorted()), }) diff --git a/packages/http-recorder/src/effect.ts b/packages/http-recorder/src/effect.ts index e6c3ccbc154..e9cb60cc2e2 100644 --- a/packages/http-recorder/src/effect.ts +++ b/packages/http-recorder/src/effect.ts @@ -11,8 +11,8 @@ import { UrlParams, } from "effect/unstable/http" import * as CassetteService from "./cassette" -import { defaultMatcher, selectMatch, selectSequential, type RequestMatcher } from "./matching" -import { appendOrFail, makeReplayState, resolveAutoMode } from "./recorder" +import { defaultMatcher, selectSequential, type RequestMatcher } from "./matching" +import { makeReplayState, resolveAutoMode } from "./recorder" import { defaults, type Redactor } from "./redactor" import { redactUrl } from "./redaction" import { httpInteractions, type CassetteMetadata, type HttpInteraction, type ResponseSnapshot } from "./schema" @@ -24,7 +24,6 @@ export interface RecordReplayOptions { readonly directory?: string readonly metadata?: CassetteMetadata readonly redactor?: Redactor - readonly dispatch?: "match" | "sequential" readonly match?: RequestMatcher } @@ -71,7 +70,6 @@ export const recordingLayer = ( const match = options.match ?? defaultMatcher const requested = options.mode ?? "auto" const mode = requested === "auto" ? yield* resolveAutoMode(cassetteService, name) : requested - const sequential = options.dispatch === "sequential" const replay = yield* makeReplayState(cassetteService, name, httpInteractions) const snapshotRequest = (request: HttpClientRequest.HttpClientRequest) => @@ -102,9 +100,11 @@ export const recordingLayer = ( ...captured, }), } - yield* appendOrFail(cassetteService, name, interaction, options.metadata).pipe( - Effect.catchTag("UnsafeCassetteError", (error) => Effect.fail(transportError(request, error.message))), - ) + yield* cassetteService + .append(name, interaction, options.metadata) + .pipe( + Effect.catchTag("UnsafeCassetteError", (error) => Effect.fail(transportError(request, error.message))), + ) return HttpClientResponse.fromWeb( request, new Response(decodeResponseBody(interaction.response), interaction.response), @@ -119,14 +119,12 @@ export const recordingLayer = ( transportError(request, `Fixture "${name}" not found. Run locally to record it (CI=true forces replay).`), ), ) - const result = sequential - ? selectSequential(interactions, incoming, match, yield* replay.cursor) - : selectMatch(interactions, incoming, match) + const result = selectSequential(interactions, incoming, match, yield* replay.cursor) if (!result.interaction) return yield* Effect.fail( transportError(request, `Fixture "${name}" does not match the current request: ${result.detail}.`), ) - if (sequential) yield* replay.advance + yield* replay.advance return HttpClientResponse.fromWeb( request, new Response(decodeResponseBody(result.interaction.response), result.interaction.response), diff --git a/packages/http-recorder/src/index.ts b/packages/http-recorder/src/index.ts index 4b47e4513d4..d05098996ec 100644 --- a/packages/http-recorder/src/index.ts +++ b/packages/http-recorder/src/index.ts @@ -7,10 +7,9 @@ export type { WebSocketFrame, WebSocketInteraction, } from "./schema" -export { CassetteNotFoundError, hasCassetteSync } from "./cassette" +export { CassetteNotFoundError, hasCassetteSync, UnsafeCassetteError } from "./cassette" export { defaultMatcher, type RequestMatcher } from "./matching" export { redactHeaders, redactUrl, secretFindings, type SecretFinding } from "./redaction" -export { UnsafeCassetteError } from "./recorder" export { cassetteLayer, recordingLayer, type RecordReplayMode, type RecordReplayOptions } from "./effect" export { makeWebSocketExecutor, diff --git a/packages/http-recorder/src/matching.ts b/packages/http-recorder/src/matching.ts index 9af85a2f3ad..1dced17d071 100644 --- a/packages/http-recorder/src/matching.ts +++ b/packages/http-recorder/src/matching.ts @@ -36,7 +36,7 @@ export const canonicalSnapshot = (snapshot: RequestSnapshot): string => export const defaultMatcher: RequestMatcher = (incoming, recorded) => canonicalSnapshot(incoming) === canonicalSnapshot(recorded) -const safeText = (value: unknown) => { +export const safeText = (value: unknown) => { if (value === undefined) return "undefined" if (secretFindings(value).length > 0) return JSON.stringify(REDACTED) const text = JSON.stringify(value) @@ -92,24 +92,6 @@ export const requestDiff = (expected: RequestSnapshot, received: RequestSnapshot return lines } -export const mismatchDetail = (interactions: ReadonlyArray, incoming: RequestSnapshot): string => { - if (interactions.length === 0) return "cassette has no recorded HTTP interactions" - const ranked = interactions - .map((interaction, index) => ({ index, lines: requestDiff(interaction.request, incoming) })) - .toSorted((a, b) => a.lines.length - b.lines.length || a.index - b.index) - const best = ranked[0] - return ["no recorded interaction matched", `closest interaction: #${best.index + 1}`, ...best.lines].join("\n") -} - -export const selectMatch = ( - interactions: ReadonlyArray, - incoming: RequestSnapshot, - match: RequestMatcher, -): { readonly interaction: HttpInteraction | undefined; readonly detail: string } => { - const interaction = interactions.find((candidate) => match(incoming, candidate.request)) - return { interaction, detail: interaction ? "" : mismatchDetail(interactions, incoming) } -} - export const selectSequential = ( interactions: ReadonlyArray, incoming: RequestSnapshot, diff --git a/packages/http-recorder/src/recorder.ts b/packages/http-recorder/src/recorder.ts index 460b427c2a0..0a13282c2d7 100644 --- a/packages/http-recorder/src/recorder.ts +++ b/packages/http-recorder/src/recorder.ts @@ -1,47 +1,22 @@ -import { Effect, Ref, Schema, Scope } from "effect" +import { Effect, Ref, Scope } from "effect" import type * as CassetteService from "./cassette" import type { CassetteNotFoundError } from "./cassette" -import { SecretFindingSchema } from "./redaction" -import type { CassetteMetadata, Interaction } from "./schema" - -export class UnsafeCassetteError extends Schema.TaggedErrorClass()("UnsafeCassetteError", { - cassetteName: Schema.String, - findings: Schema.Array(SecretFindingSchema), -}) { - override get message() { - return `Refusing to write cassette "${this.cassetteName}" because it contains possible secrets: ${this.findings - .map((finding) => `${finding.path} (${finding.reason})`) - .join(", ")}` - } -} - -export type ResolvedMode = "record" | "replay" | "passthrough" +import type { Interaction } from "./schema" const isCI = () => { const value = process.env.CI return value !== undefined && value !== "" && value !== "false" && value !== "0" } -export const resolveAutoMode = (cassette: CassetteService.Interface, name: string): Effect.Effect => +export const resolveAutoMode = ( + cassette: CassetteService.Interface, + name: string, +): Effect.Effect<"record" | "replay" | "passthrough"> => Effect.gen(function* () { if (isCI()) return "replay" return (yield* cassette.exists(name)) ? "replay" : "record" }) -export const appendOrFail = ( - cassette: CassetteService.Interface, - name: string, - interaction: Interaction, - metadata: CassetteMetadata | undefined, -): Effect.Effect => - cassette - .append(name, interaction, metadata) - .pipe( - Effect.flatMap(({ findings }) => - findings.length === 0 ? Effect.void : Effect.fail(new UnsafeCassetteError({ cassetteName: name, findings })), - ), - ) - export interface ReplayState { readonly load: Effect.Effect, CassetteNotFoundError> readonly cursor: Effect.Effect diff --git a/packages/http-recorder/src/redaction.ts b/packages/http-recorder/src/redaction.ts index b6aa8b3b87b..9d89fff2f5f 100644 --- a/packages/http-recorder/src/redaction.ts +++ b/packages/http-recorder/src/redaction.ts @@ -1,3 +1,5 @@ +import { Schema } from "effect" + export const REDACTED = "[REDACTED]" const DEFAULT_REDACT_HEADERS = [ @@ -95,8 +97,6 @@ export const redactHeaders = ( ) } -import { Schema } from "effect" - export const SecretFindingSchema = Schema.Struct({ path: Schema.String, reason: Schema.String, diff --git a/packages/http-recorder/src/websocket.ts b/packages/http-recorder/src/websocket.ts index f7529b48880..2cccc6749c7 100644 --- a/packages/http-recorder/src/websocket.ts +++ b/packages/http-recorder/src/websocket.ts @@ -1,9 +1,10 @@ import { Effect, Option, Ref, Scope, Stream } from "effect" import type { Headers } from "effect/unstable/http" import * as CassetteService from "./cassette" -import { canonicalizeJson, decodeJson } from "./matching" -import { appendOrFail, makeReplayState, resolveAutoMode } from "./recorder" +import { canonicalizeJson, decodeJson, safeText } from "./matching" +import { makeReplayState, resolveAutoMode } from "./recorder" import type { RecordReplayMode } from "./effect" +import { redactUrl } from "./redaction" import { defaults, type Redactor } from "./redactor" import { webSocketInteractions, type CassetteMetadata, type WebSocketFrame } from "./schema" @@ -53,7 +54,7 @@ const decodeFrameText = (frame: WebSocketFrame) => const assertEqual = (message: string, actual: unknown, expected: unknown) => Effect.sync(() => { if (JSON.stringify(actual) === JSON.stringify(expected)) return - throw new Error(`${message}: expected ${JSON.stringify(expected)}, received ${JSON.stringify(actual)}`) + throw new Error(`${message}: expected ${safeText(expected)}, received ${safeText(actual)}`) }) const jsonOrText = (value: string) => Option.match(decodeJson(value), { onNone: () => value, onSome: canonicalizeJson }) @@ -61,7 +62,7 @@ const jsonOrText = (value: string) => Option.match(decodeJson(value), { onNone: const compareClientMessage = (actual: string, expected: WebSocketFrame | undefined, index: number, asJson: boolean) => { if (!expected) return Effect.sync(() => { - throw new Error(`Unexpected WebSocket client frame ${index + 1}: ${actual}`) + throw new Error(`Unexpected WebSocket client frame ${index + 1}: ${safeText(actual)}`) }) const expectedText = decodeFrameText(expected) if (!asJson) return assertEqual(`WebSocket client frame ${index + 1}`, actual, expectedText) @@ -98,12 +99,13 @@ export const makeWebSocketExecutor = ( const closeOnce = Effect.gen(function* () { if (yield* Ref.getAndSet(closed, true)) return yield* connection.close - yield* appendOrFail( - options.cassette, - options.name, - { transport: "websocket", open: openSnapshot(request), client, server }, - options.metadata, - ).pipe(Effect.orDie) + yield* options.cassette + .append( + options.name, + { transport: "websocket", open: openSnapshot(request), client, server }, + options.metadata, + ) + .pipe(Effect.orDie) }) return { sendText: (message) => @@ -111,10 +113,7 @@ export const makeWebSocketExecutor = ( .sendText(message) .pipe(Effect.tap(() => Effect.sync(() => client.push(encodeFrame(message))))), messages: connection.messages.pipe( - Stream.map((message) => { - server.push(encodeFrame(message)) - return message - }), + Stream.tap((message) => Effect.sync(() => server.push(encodeFrame(message)))), ), close: closeOnce, } @@ -130,20 +129,22 @@ export const makeWebSocketExecutor = ( const interactions = yield* replay.load.pipe(Effect.orDie) const index = yield* replay.cursor const interaction = interactions[index] - if (!interaction) return yield* Effect.die(new Error(`No recorded WebSocket interaction for ${request.url}`)) + if (!interaction) + return yield* Effect.die(new Error(`No recorded WebSocket interaction for ${redactUrl(request.url)}`)) yield* replay.advance yield* assertEqual(`WebSocket open frame ${index + 1}`, openSnapshot(request), interaction.open) const messageIndex = yield* Ref.make(0) return { sendText: (message) => Effect.gen(function* () { - const current = yield* Ref.getAndUpdate(messageIndex, (value) => value + 1) + const current = yield* Ref.get(messageIndex) yield* compareClientMessage( message, interaction.client[current], current, options.compareClientMessagesAsJson === true, ) + yield* Ref.update(messageIndex, (value) => value + 1) }), messages: Stream.fromIterable(interaction.server).pipe(Stream.map(decodeFrameMessage)), close: Effect.gen(function* () { diff --git a/packages/http-recorder/sst-env.d.ts b/packages/http-recorder/sst-env.d.ts index 64441936d7a..f25b9714550 100644 --- a/packages/http-recorder/sst-env.d.ts +++ b/packages/http-recorder/sst-env.d.ts @@ -7,4 +7,4 @@ /// import "sst" -export {} \ No newline at end of file +export {} diff --git a/packages/http-recorder/test/record-replay.test.ts b/packages/http-recorder/test/record-replay.test.ts index 7613563fd05..72512868ee6 100644 --- a/packages/http-recorder/test/record-replay.test.ts +++ b/packages/http-recorder/test/record-replay.test.ts @@ -230,19 +230,10 @@ describe("http-recorder", () => { ) }) - test("default matcher dispatches multi-interaction cassettes by request shape", async () => { - await run( - Effect.gen(function* () { - expect(yield* post("https://example.test/echo", { step: 2 })).toBe('{"reply":"second"}') - expect(yield* post("https://example.test/echo", { step: 1 })).toBe('{"reply":"first"}') - }), - ) - }) - - test("sequential dispatch returns recorded responses in order for identical requests", async () => { + test("replay returns recorded responses in order for identical requests", async () => { await runWith( "record-replay/retry", - { dispatch: "sequential" }, + {}, Effect.gen(function* () { expect(yield* post("https://example.test/poll", { id: "job_1" })).toBe('{"status":"pending"}') expect(yield* post("https://example.test/poll", { id: "job_1" })).toBe('{"status":"complete"}') @@ -250,21 +241,8 @@ describe("http-recorder", () => { ) }) - test("default matcher returns the first match for identical requests", async () => { - await runWith( - "record-replay/retry", - {}, - Effect.gen(function* () { - expect(yield* post("https://example.test/poll", { id: "job_1" })).toBe('{"status":"pending"}') - expect(yield* post("https://example.test/poll", { id: "job_1" })).toBe('{"status":"pending"}') - }), - ) - }) - - test("sequential dispatch reports cursor exhaustion when more requests are made than recorded", async () => { - await runWith( - "record-replay/multi-step", - { dispatch: "sequential" }, + test("replay reports cursor exhaustion when more requests are made than recorded", async () => { + await run( Effect.gen(function* () { yield* post("https://example.test/echo", { step: 1 }) yield* post("https://example.test/echo", { step: 2 }) @@ -274,10 +252,8 @@ describe("http-recorder", () => { ) }) - test("sequential dispatch still validates each recorded request", async () => { - await runWith( - "record-replay/multi-step", - { dispatch: "sequential" }, + test("replay validates each recorded request in order", async () => { + await run( Effect.gen(function* () { yield* post("https://example.test/echo", { step: 1 }) const exit = yield* Effect.exit(post("https://example.test/echo", { step: 3 })) @@ -331,14 +307,13 @@ describe("http-recorder", () => { } }) - test("mismatch diagnostics show closest redacted request differences", async () => { + test("mismatch diagnostics show redacted request differences against the expected interaction", async () => { await run( Effect.gen(function* () { const exit = yield* Effect.exit( post("https://example.test/echo?api_key=secret-value", { step: 3, token: "sk-123456789012345678901234" }), ) const message = failureText(exit) - expect(message).toContain("closest interaction: #1") expect(message).toContain("url:") expect(message).toContain("https://example.test/echo?api_key=%5BREDACTED%5D") expect(message).toContain("body:") @@ -348,4 +323,118 @@ describe("http-recorder", () => { }), ) }) + + test("auto mode records to disk when the cassette is missing", async () => { + const directory = fs.mkdtempSync(path.join(os.tmpdir(), "http-recorder-auto-record-")) + using server = Bun.serve({ + port: 0, + fetch: () => new Response('{"reply":"recorded"}', { headers: { "content-type": "application/json" } }), + }) + const url = `http://127.0.0.1:${server.port}/echo` + // CI=true forces replay; clear it so we exercise the local-dev auto-record path. + const previous = process.env.CI + delete process.env.CI + try { + const result = await runWith("auto-record", { directory, mode: "auto" }, post(url, { step: 1 })) + expect(result).toBe('{"reply":"recorded"}') + expect(fs.existsSync(path.join(directory, "auto-record.json"))).toBe(true) + } finally { + if (previous !== undefined) process.env.CI = previous + } + }) + + test("passthrough mode bypasses the recorder entirely", async () => { + using server = Bun.serve({ port: 0, fetch: () => new Response("from-upstream") }) + const url = `http://127.0.0.1:${server.port}/path` + const directory = fs.mkdtempSync(path.join(os.tmpdir(), "http-recorder-passthrough-")) + + const result = await runWith("passthrough-noop", { directory, mode: "passthrough" }, post(url, {})) + expect(result).toBe("from-upstream") + expect(fs.existsSync(path.join(directory, "passthrough-noop.json"))).toBe(false) + }) + + test("UnsafeCassetteError fails the request when a recording would write a known secret", async () => { + using server = Bun.serve({ port: 0, fetch: () => new Response("Bearer abcdefghijklmnopqrstuvwxyz1234") }) + const url = `http://127.0.0.1:${server.port}/leaky` + const directory = fs.mkdtempSync(path.join(os.tmpdir(), "http-recorder-unsafe-")) + + const exit = await Effect.runPromise( + Effect.exit( + post(url, { ok: true }).pipe( + Effect.provide(HttpRecorder.cassetteLayer("unsafe-record", { directory, mode: "record" })), + ), + ), + ) + expect(Exit.isFailure(exit)).toBe(true) + expect(failureText(exit)).toContain("contains possible secrets") + expect(fs.existsSync(path.join(directory, "unsafe-record.json"))).toBe(false) + }) + + test("Cassette.list enumerates recorded cassette names", async () => { + const directory = fs.mkdtempSync(path.join(os.tmpdir(), "http-recorder-list-")) + await seedCassetteDirectory(directory, "alpha/one", [ + { + transport: "http", + request: { method: "GET", url: "https://x.test/a", headers: {}, body: "" }, + response: { status: 200, headers: {}, body: "a" }, + }, + ]) + await seedCassetteDirectory(directory, "beta", [ + { + transport: "http", + request: { method: "GET", url: "https://x.test/b", headers: {}, body: "" }, + response: { status: 200, headers: {}, body: "b" }, + }, + ]) + + const names = await Effect.runPromise( + Effect.gen(function* () { + const cassette = yield* HttpRecorder.Cassette.Service + return yield* cassette.list() + }).pipe(Effect.provide(HttpRecorder.Cassette.fileSystem({ directory })), Effect.provide(NodeFileSystem.layer)), + ) + expect(names).toEqual(["alpha/one", "beta"]) + }) + + test("WebSocket replay decodes binary frames recorded as base64", async () => { + const binaryServer = new Uint8Array([1, 2, 3, 4]) + await Effect.runPromise( + Effect.scoped( + Effect.gen(function* () { + const cassette = yield* HttpRecorder.Cassette.Service + const executor = yield* HttpRecorder.makeWebSocketExecutor({ + name: "ws/binary", + cassette, + live: { open: () => Effect.die(new Error("unexpected live WebSocket open")) }, + }) + const connection = yield* executor.open({ + url: "wss://example.test/binary", + headers: Headers.fromInput({}), + }) + const messages: Array = [] + yield* connection.messages.pipe(Stream.runForEach((m) => Effect.sync(() => messages.push(m)))) + yield* connection.close + + expect(messages).toHaveLength(1) + expect(messages[0]).toBeInstanceOf(Uint8Array) + expect(Array.from(messages[0] as Uint8Array)).toEqual([1, 2, 3, 4]) + }).pipe( + Effect.provide( + HttpRecorder.Cassette.memory({ + "ws/binary": [ + { + transport: "websocket", + open: { url: "wss://example.test/binary", headers: {} }, + client: [], + server: [ + { kind: "binary", body: Buffer.from(binaryServer).toString("base64"), bodyEncoding: "base64" }, + ], + }, + ], + }), + ), + ), + ), + ) + }) }) diff --git a/packages/kilo-console/package.json b/packages/kilo-console/package.json index 459e2e7cbbf..597aa5389f6 100644 --- a/packages/kilo-console/package.json +++ b/packages/kilo-console/package.json @@ -1,6 +1,6 @@ { "name": "@kilocode/kilo-console", - "version": "7.3.41", + "version": "7.3.42", "private": true, "type": "module", "scripts": { diff --git a/packages/kilo-docs/lychee.toml b/packages/kilo-docs/lychee.toml index d10fce303de..fe1be68c3a2 100644 --- a/packages/kilo-docs/lychee.toml +++ b/packages/kilo-docs/lychee.toml @@ -10,6 +10,7 @@ exclude_path = ["node_modules"] accept = [ "200", + "202", "403", "429", "301", @@ -30,6 +31,7 @@ exclude = [ # API endpoint prefixes are valid but return 4xx to plain GET link checks. '^https?://ai-gateway\.vercel\.sh/v1/?$', '^https?://api\.voyageai\.com/v1/embeddings/?$', + '^https?://inference\.do-ai\.run/v1/?$', '^https?://generativelanguage\.googleapis\.com/v1beta/openai/?$', '^https?://search\.parallel\.ai/mcp/?$', # xAI API and OAuth endpoints require request parameters or reject plain link checks. diff --git a/packages/kilo-docs/markdoc/nodes/heading.markdoc.ts b/packages/kilo-docs/markdoc/nodes/heading.markdoc.ts index 3c5741af8d0..ca17196bb5d 100644 --- a/packages/kilo-docs/markdoc/nodes/heading.markdoc.ts +++ b/packages/kilo-docs/markdoc/nodes/heading.markdoc.ts @@ -12,12 +12,7 @@ function generateID(children, attributes) { if (attributes.id && typeof attributes.id === "string") { return attributes.id } - return children - .map(text) - .join(" ") - .replace(/[?/]/g, "") - .replace(/\s+/g, "-") - .toLowerCase() + return children.map(text).join(" ").replace(/[?/]/g, "").replace(/\s+/g, "-").toLowerCase() } export const heading = { diff --git a/packages/kilo-docs/package.json b/packages/kilo-docs/package.json index ebf2d69e4fb..6395895b0a7 100644 --- a/packages/kilo-docs/package.json +++ b/packages/kilo-docs/package.json @@ -1,6 +1,6 @@ { "name": "@kilocode/kilo-docs", - "version": "7.3.41", + "version": "7.3.42", "private": true, "scripts": { "dev": "next dev --webpack --port 3002", diff --git a/packages/kilo-docs/pages/ai-providers/deepseek.md b/packages/kilo-docs/pages/ai-providers/deepseek.md index 3bc77aeda51..8323bc9d0c1 100644 --- a/packages/kilo-docs/pages/ai-providers/deepseek.md +++ b/packages/kilo-docs/pages/ai-providers/deepseek.md @@ -8,11 +8,11 @@ sidebar_label: DeepSeek Kilo Code supports accessing models through the DeepSeek API, including `deepseek-chat` and `deepseek-reasoner`. -**Website:** [DeepSeek API documentation](https://api-docs.deepseek.com/) +**Website:** [https://platform.deepseek.com/](https://platform.deepseek.com/) ## Getting an API Key -1. **Sign Up/Sign In:** Go to the [DeepSeek API keys page](https://platform.deepseek.com/api_keys). Create an account or sign in. +1. **Sign Up/Sign In:** Go to the [DeepSeek Platform](https://platform.deepseek.com/). Create an account or sign in. 2. **Navigate to API Keys:** Find your API keys in the [API keys](https://platform.deepseek.com/api_keys) section of the platform. 3. **Create a Key:** Click "Create new API key". Give your key a descriptive name (e.g., "Kilo Code"). 4. **Copy the Key:** **Important:** Copy the API key _immediately_. You will not be able to see it again. Store it securely. diff --git a/packages/kilo-docs/pages/code-with-ai/platforms/cli-reference.md b/packages/kilo-docs/pages/code-with-ai/platforms/cli-reference.md index 20bde638bfb..67600a5e1e5 100644 --- a/packages/kilo-docs/pages/code-with-ai/platforms/cli-reference.md +++ b/packages/kilo-docs/pages/code-with-ai/platforms/cli-reference.md @@ -207,6 +207,7 @@ Commands: kilo debug snapshot snapshot debugging utilities kilo debug startup print startup timing kilo debug agent show agent configuration details + kilo debug v2 debug v2 catalog and built-in plugins kilo debug info show debug information kilo debug paths show global paths (data, config, cache, state) kilo debug wait wait indefinitely (for debugging) @@ -509,6 +510,16 @@ Options: --params Tool params as JSON or a JS object literal [string] ``` +### kilo debug v2 + +``` +debug v2 catalog and built-in plugins + +Options: + --help Show help [boolean] + --version Show version number [boolean] +``` + ### kilo debug info ``` diff --git a/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/chat/chat-view-agent-manager-completed-chromium-linux.png b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/chat/chat-view-agent-manager-completed-chromium-linux.png new file mode 100644 index 00000000000..0fd5ad4f06d --- /dev/null +++ b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/chat/chat-view-agent-manager-completed-chromium-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ba55764c944231be2cd47c839d3a46c4bbdcb0a3060a1d8aa3ed7d391a34d722 +size 14749 diff --git a/packages/kilo-docs/source-links.md b/packages/kilo-docs/source-links.md index 3704e123e2e..21afcdcab96 100644 --- a/packages/kilo-docs/source-links.md +++ b/packages/kilo-docs/source-links.md @@ -7,6 +7,8 @@ - +- + - - @@ -43,10 +45,10 @@ - +- + - -- - - - @@ -94,6 +96,8 @@ - +- + - - @@ -116,8 +120,6 @@ - -- - - @@ -126,10 +128,6 @@ - -- - -- - - @@ -143,6 +141,8 @@ - +- + - - @@ -151,12 +151,6 @@ - -- - -- - -- - - - diff --git a/packages/kilo-gateway/package.json b/packages/kilo-gateway/package.json index 0a5f2c779f0..ea8736972f7 100644 --- a/packages/kilo-gateway/package.json +++ b/packages/kilo-gateway/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@kilocode/kilo-gateway", - "version": "7.3.41", + "version": "7.3.42", "type": "module", "license": "MIT", "description": "Unified Kilo Gateway package for OpenCode - authentication, provider, and API integration", diff --git a/packages/kilo-i18n/package.json b/packages/kilo-i18n/package.json index 457ca1cb46f..537801dd87e 100644 --- a/packages/kilo-i18n/package.json +++ b/packages/kilo-i18n/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@kilocode/kilo-i18n", - "version": "7.3.41", + "version": "7.3.42", "type": "module", "license": "MIT", "description": "Kilo-specific i18n translations and overrides", diff --git a/packages/kilo-indexing/package.json b/packages/kilo-indexing/package.json index a300f566ca7..387af5a105b 100644 --- a/packages/kilo-indexing/package.json +++ b/packages/kilo-indexing/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@kilocode/kilo-indexing", - "version": "7.3.41", + "version": "7.3.42", "type": "module", "license": "MIT", "description": "Standalone indexing engine and host helpers for Kilo Code", diff --git a/packages/kilo-jetbrains/AGENTS.md b/packages/kilo-jetbrains/AGENTS.md index d9a13a7427e..3bb2c6abab0 100644 --- a/packages/kilo-jetbrains/AGENTS.md +++ b/packages/kilo-jetbrains/AGENTS.md @@ -268,6 +268,22 @@ Tests for retained Swing components should assert: - `update(model)` changes existing labels/body text without duplicating components. - Updates while collapsed do not eagerly create lazy bodies. - No-op updates, empty deltas, repeated hover values, and toggling non-expandable cards do not repaint/revalidate the whole view. +- Streaming/rebuilding surfaces additionally require stress + leak tests (see below). + +### Stress and Leak Tests for Streaming UI + +Session/transcript UI that streams updates or rebuilds its component tree (markdown +views, code blocks, transcript parts, collapsible cards) must ship stress + leak tests in +addition to behavior tests. These tests must: + +- Drive many updates (hundreds of streamed deltas or `set` cycles) through the public API. +- Assert that retained component instances stay identical across updates (`assertSame`). +- Assert the component count stays bounded — no growth per update. +- Assert disposable-backed resources return to baseline after churn + clear/dispose. + For code editors, compare `EditorFactory.getInstance().allEditors.size` against a + baseline captured before the loop. + +See `MdViewHybridStressTest` for the reference pattern. ### Platform Components and Utilities diff --git a/packages/kilo-jetbrains/CHANGELOG.md b/packages/kilo-jetbrains/CHANGELOG.md index c4f0e8224c8..0a86db83022 100644 --- a/packages/kilo-jetbrains/CHANGELOG.md +++ b/packages/kilo-jetbrains/CHANGELOG.md @@ -1,11 +1,51 @@ # Changelog +## 7.3.42 + +### Patch Changes + +- [#11015](https://github.com/Kilo-Org/kilocode/pull/11015) [`c90846a`](https://github.com/Kilo-Org/kilocode/commit/c90846a98938d3cdd666c46294ed4bb4871f7fcd) - Fix JetBrains session scrolling so mouse wheel and keyboard scrolling no longer snap back or bounce near the transcript bottom. + +- [#11015](https://github.com/Kilo-Org/kilocode/pull/11015) [`d505677`](https://github.com/Kilo-Org/kilocode/commit/d505677d88816cf528b64392e23b7ccdddf98a4a) - Prevent the JetBrains session scrollbar from covering transcript content. + +- [#11015](https://github.com/Kilo-Org/kilocode/pull/11015) [`5736a39`](https://github.com/Kilo-Org/kilocode/commit/5736a394597f250f64cf8c684d2426b56ca273ce) - Render glob search results in the JetBrains chat as collapsible tool output with separate directory and pattern rows. + +- [#11015](https://github.com/Kilo-Org/kilocode/pull/11015) [`d1fa450`](https://github.com/Kilo-Org/kilocode/commit/d1fa4506c8b8e65b21cd08e0c6600598366aed0f) - Use matching VS Code-style icons for JetBrains session views. + +- [#11015](https://github.com/Kilo-Org/kilocode/pull/11015) [`952241e`](https://github.com/Kilo-Org/kilocode/commit/952241ee07eebd22717bdf54ce07b3a6c66228af) - Refine JetBrains session card borders so prompt and question surfaces use brighter outlines while reasoning and tool cards use softer default borders. + +- [#11015](https://github.com/Kilo-Org/kilocode/pull/11015) [`b9bff3b`](https://github.com/Kilo-Org/kilocode/commit/b9bff3b69cf27fc7e0d88d411eaa368616fc32d6) - Reset stale hover styling when moving between JetBrains session cards and draw card outlines only while expanded. + +- [#11015](https://github.com/Kilo-Org/kilocode/pull/11015) [`5736a39`](https://github.com/Kilo-Org/kilocode/commit/5736a394597f250f64cf8c684d2426b56ca273ce) - Render grep searches in the JetBrains chat with a dedicated search header that shows stacked, clipped targets. + +- [#11015](https://github.com/Kilo-Org/kilocode/pull/11015) [`01f2886`](https://github.com/Kilo-Org/kilocode/commit/01f28861900d4794d6329821f0c9f5c9efdedae3) - Improve mouse wheel scrolling speed in the JetBrains session view. + ## 7.3.29 ### Patch Changes ## [Unreleased] +## [7.0.1-rc.8] - 2026-06-09 + +### Added + +- Display search results and tool output in clearer, more readable JetBrains session cards. + +### Fixed + +- Improve session transcript scrolling so streaming updates, expanded cards, reasoning blocks, and mouse wheel scrolling preserve the user's position more reliably. +- Make session transcripts easier to scan with tighter spacing, aligned icons, cleaner card outlines, relative search paths, and less visual noise. +- Keep completed reasoning blocks expanded after a response finishes. +- Improve session stability during long-running or cancelled prompts. +- Restore automatic session titles, project skill discovery, and subagent isolation in forked sessions. +- Restore imported cloud session diffs. +- Compact sessions before the configured context limit is exceeded. + +### Changed + +- Update the bundled Kilo CLI runtime with the latest fixes used by the JetBrains plugin. + ## [7.0.1-rc.7] - 2026-06-04 ### Fixed diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/SessionUi.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/SessionUi.kt index 99641c5e599..dd97cbabc9a 100644 --- a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/SessionUi.kt +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/SessionUi.kt @@ -287,7 +287,18 @@ class SessionUi( dismiss = { controller.dismissLoginRequired() }, selection = selection, ) - messageBody = SessionMessageListPanel(controller.model, this, question, permission, login, ::openFile, ::openUrl, selection) + messageBody = SessionMessageListPanel( + controller.model, + this, + question, + permission, + login, + ::openFile, + ::openUrl, + selection, + repo = workspace.directory, + resize = { anchor, fn -> scroll.preserve(anchor, fn) }, + ) header = SessionHeaderPanel(controller, this) scroll = SessionScroll(root, sessionContent, messageBody, blankBody) diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/scroll/SessionScroll.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/scroll/SessionScroll.kt index d320d179b09..018cea2eb0b 100644 --- a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/scroll/SessionScroll.kt +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/scroll/SessionScroll.kt @@ -51,10 +51,10 @@ internal class SessionScroll( private var opening = false private var stable = -1 private var seq = 0 + private var pause = false private var user = false private var value = 0 private var question = false - private var restoring = false init { jump = JBLabel(ScrollButtonIcon.create()).apply { @@ -73,7 +73,6 @@ internal class SessionScroll( user = true } }) - component.viewport.addChangeListener { onViewport() } component.verticalScrollBar.addAdjustmentListener { onScroll() } root.addOverlay(jump) { _, child -> val size = child.preferredSize @@ -98,11 +97,10 @@ internal class SessionScroll( @RequiresEdt fun atBottom(): Boolean { - val bar = component.verticalScrollBar return when { component.viewport.view !== messages -> tail - bar.maximum <= bar.visibleAmount -> true - else -> bar.value + bar.visibleAmount >= bar.maximum - JBUI.scale(THRESHOLD) + !tail -> false + else -> near() } } @@ -114,6 +112,7 @@ internal class SessionScroll( return } user = false + pause = false tail = true stable = -1 auto = true @@ -139,11 +138,44 @@ internal class SessionScroll( return component.viewport.view === messages && tail } + @RequiresEdt + fun preserve(anchor: JComponent, action: () -> Unit) { + if (component.viewport.view !== messages) { + action() + return + } + val pos = SwingUtilities.convertPoint(anchor, Point(0, 0), messages) + val delta = pos.y - component.viewport.viewPosition.y + seq++ + stable = -1 + user = false + pause = false + auto = true + try { + action() + layoutScroll() + val next = SwingUtilities.convertPoint(anchor, Point(0, 0), messages) + val y = (next.y - delta).coerceIn(0, bottom()) + component.viewport.viewPosition = Point(0, y) + bar.value = y + } finally { + auto = false + } + tail = atBottom() + syncValue() + updateJump() + if (tail) { + stable = -1 + seq++ + } + } + @RequiresEdt fun openBottom(done: () -> Unit) { opening = true stable = -1 user = false + pause = false tail = true auto = true show(messages) @@ -169,8 +201,8 @@ internal class SessionScroll( @RequiresEdt fun applyStyle(style: SessionEditorStyle) { this.style = style - component.background = SessionUiStyle.View.transcript() - component.viewport.background = SessionUiStyle.View.transcript() + component.background = SessionUiStyle.Transcript.bgColor() + component.viewport.background = SessionUiStyle.Transcript.bgColor() syncIcon() messages.applyStyle(style) val view = component.viewport.view @@ -189,6 +221,7 @@ internal class SessionScroll( opening = false stable = -1 user = false + pause = false tail = true auto = true show(messages) @@ -271,49 +304,62 @@ internal class SessionScroll( bar.value = bottom() } - @RequiresEdt - private fun onViewport() { - if (restoring || auto || opening || user || tail || component.viewport.view !== messages) return - val y = value.coerceIn(0, bottom()) - if (component.viewport.viewPosition.y == y && bar.value == y) return - restoring = true - try { - component.viewport.viewPosition = Point(0, y) - bar.value = y - } finally { - restoring = false - } - updateJump() - } - @RequiresEdt private fun bottom(): Int { val bar = component.verticalScrollBar return (bar.maximum - bar.visibleAmount).coerceAtLeast(bar.minimum) } + @RequiresEdt + private fun near(): Boolean { + val bar = component.verticalScrollBar + return bar.maximum <= bar.visibleAmount || bar.value + bar.visibleAmount >= bar.maximum - JBUI.scale(THRESHOLD) + } + @RequiresEdt private fun onScroll() { + val prev = value val moved = bar.value != value + val down = bar.value > value syncValue() if (auto || opening) { updateJump() return } if (component.viewport.view === messages) { - val bottom = atBottom() + val bottom = near() if (bottom) { - tail = true + if (user && moved && !down) { + tail = false + pause = true + } else if (!tail && !user) { + if (moved) { + auto = true + try { + bar.value = prev.coerceIn(bar.minimum, bottom()) + } finally { + auto = false + } + syncValue() + } + tail = false + } else if (pause && !user) { + tail = false + } else { + tail = true + pause = false + } user = false updateJump() return } - if (tail && (!user || !moved)) { + if (tail && !user && !moved) { user = false followBottom(true) return } tail = false + pause = false user = false seq++ } diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/ui/ConnectionPanel.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/ui/ConnectionPanel.kt index 9b6beb55e8c..63d42d0cb5e 100644 --- a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/ui/ConnectionPanel.kt +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/ui/ConnectionPanel.kt @@ -94,7 +94,7 @@ class ConnectionPanel( // Keep the banner solid so expanded details cover transcript content beneath it. isOpaque = true background = UiStyle.Colors.bg() - border = JBUI.Borders.customLine(SessionUiStyle.View.line(), 1, 0, 0, 0) + border = JBUI.Borders.customLine(SessionUiStyle.View.Outline.color(), SessionUiStyle.View.Outline.width(), 0, 0, 0) left.add(toggle, BorderLayout.WEST) left.add(label, BorderLayout.CENTER) header.add(left, BorderLayout.CENTER) diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/ui/ProgressPanel.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/ui/ProgressPanel.kt index bb2ed7d8696..5a9d6d757cb 100644 --- a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/ui/ProgressPanel.kt +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/ui/ProgressPanel.kt @@ -5,12 +5,14 @@ import ai.kilocode.client.session.model.SessionModelEvent import ai.kilocode.client.session.model.SessionState import ai.kilocode.client.session.ui.style.SessionEditorStyle import ai.kilocode.client.session.ui.style.SessionEditorStyleTarget +import ai.kilocode.client.session.ui.style.SessionUiStyle import ai.kilocode.client.ui.UiStyle import ai.kilocode.client.ui.layout.Stack import ai.kilocode.client.ui.layout.StackAxis import com.intellij.openapi.Disposable import com.intellij.ui.AnimatedIcon import com.intellij.ui.components.JBLabel +import com.intellij.util.ui.JBUI /** * Progress footer rendered at the bottom of the session transcript while the @@ -35,6 +37,12 @@ class ProgressPanel( init { isOpaque = false isVisible = false + border = JBUI.Borders.empty( + UiStyle.Gap.sm(), + JBUI.scale(SessionUiStyle.View.Layout.HORIZONTAL_PADDING), + 0, + 0, + ) applyStyle(SessionEditorStyle.current()) next(JBLabel(AnimatedIcon.Default())) diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/ui/SessionMessageListPanel.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/ui/SessionMessageListPanel.kt index d2506bb67b0..18c7d7410c9 100644 --- a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/ui/SessionMessageListPanel.kt +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/ui/SessionMessageListPanel.kt @@ -13,9 +13,11 @@ import ai.kilocode.client.session.views.MessageView import ai.kilocode.client.session.views.permission.PermissionView import ai.kilocode.client.session.views.question.QuestionView import ai.kilocode.client.session.views.TurnView +import ai.kilocode.client.session.views.base.PartView import com.intellij.openapi.Disposable import com.intellij.openapi.util.Disposer import com.intellij.util.ui.JBUI +import javax.swing.JComponent /** * Scrollable transcript panel that maps the model's turn grouping to @@ -51,13 +53,15 @@ class SessionMessageListPanel( private val openFile: (String) -> Unit, private val openUrl: (String) -> Unit = {}, private val selection: SessionSelection? = null, + private val repo: String? = null, + private val resize: ((JComponent, () -> Unit) -> Unit)? = null, ) : SessionLayoutPanel( JBUI.scale(SessionUiStyle.SessionLayout.GAP), JBUI.insets( SessionUiStyle.SessionLayout.TRANSCRIPT_PADDING, SessionUiStyle.SessionLayout.TRANSCRIPT_PADDING, SessionUiStyle.SessionLayout.TRANSCRIPT_PADDING, - SessionUiStyle.SessionLayout.TRANSCRIPT_PADDING, + SessionUiStyle.SessionLayout.TRANSCRIPT_PADDING + SessionUiStyle.SessionLayout.TRANSCRIPT_SCROLLBAR_PADDING, ), ), Disposable, SessionEditorStyleTarget { @@ -66,13 +70,14 @@ class SessionMessageListPanel( private val msgToView = HashMap() private var style = SessionEditorStyle.current() private var hiddenTool: ToolCallRef? = null + private var hovered: PartView? = null /** Progress footer — always the last child inside the scroll. */ val progress = ProgressPanel(model, parent) init { isOpaque = true - background = SessionUiStyle.View.transcript() + background = SessionUiStyle.Transcript.bgColor() Disposer.register(parent, this) model.addListener(parent) { event -> @@ -177,7 +182,7 @@ class SessionMessageListPanel( // ------ private event handlers ------ private fun onTurnAdded(turn: ai.kilocode.client.session.model.Turn) { - val tv = TurnView(turn.id, openFile, style, openUrl, selection) + val tv = TurnView(turn.id, openFile, style, openUrl, selection, resize, repo, ::hover) turnViews[turn.id] = tv for (msgId in turn.messageIds) { val msg = model.message(msgId) ?: continue @@ -223,6 +228,7 @@ class SessionMessageListPanel( } private fun rebuild() { + clearHover() turnViews.values.forEach { remove(it) Disposer.dispose(it) @@ -233,7 +239,7 @@ class SessionMessageListPanel( removeAll() for (turn in model.turns()) { - val tv = TurnView(turn.id, openFile, style, openUrl, selection) + val tv = TurnView(turn.id, openFile, style, openUrl, selection, resize, repo, ::hover) turnViews[turn.id] = tv for (msgId in turn.messageIds) { val msg = model.message(msgId) ?: continue @@ -249,6 +255,7 @@ class SessionMessageListPanel( } private fun clear() { + clearHover() turnViews.values.forEach { remove(it) Disposer.dispose(it) @@ -338,9 +345,26 @@ class SessionMessageListPanel( repaint() } + private fun hover(view: PartView, value: Boolean) { + if (value) { + val prev = hovered + if (prev === view) return + hovered = view + prev?.setHovered(false) + return + } + if (hovered === view) hovered = null + } + + private fun clearHover() { + val view = hovered ?: return + hovered = null + view.setHovered(false) + } + override fun applyStyle(style: SessionEditorStyle) { this.style = style - background = SessionUiStyle.View.transcript() + background = SessionUiStyle.Transcript.bgColor() for (view in turnViews.values) view.applyStyle(style) question?.applyStyle(style) permission?.applyStyle(style) @@ -350,6 +374,7 @@ class SessionMessageListPanel( } override fun dispose() { + clearHover() turnViews.values.forEach { remove(it) Disposer.dispose(it) diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/ui/account/SessionAccountOverlay.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/ui/account/SessionAccountOverlay.kt index 4c71a933966..5c4f63dd14b 100644 --- a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/ui/account/SessionAccountOverlay.kt +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/ui/account/SessionAccountOverlay.kt @@ -194,7 +194,7 @@ internal class SessionAccountOverlay( @RequiresEdt private fun showPopup() { - val bg = SessionUiStyle.View.sessionViewBackground() + val bg = SessionUiStyle.AccountPopup.bgColor() val model = CollectionListModel(choices) val list = JBList(model).apply { selectionMode = ListSelectionModel.SINGLE_SELECTION @@ -285,7 +285,7 @@ internal class SessionAccountOverlay( internal fun choiceCount() = choices.size internal fun selectedIndex() = choices.indexOfFirst { it.org == currentOrgId }.takeIf { it >= 0 } ?: 0 internal fun panelBackground() = panel.background - internal fun panelBorderColor() = SessionUiStyle.View.sessionViewOutline() + internal fun panelBorderColor() = SessionUiStyle.AccountPopup.outlineColor() internal fun balanceVisible() = balance.isVisible internal fun balanceIcon() = balance.icon internal fun balanceText() = balanceText diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/ui/prompt/PromptPanel.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/ui/prompt/PromptPanel.kt index 1ebc2c0968a..329c895e4c3 100644 --- a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/ui/prompt/PromptPanel.kt +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/ui/prompt/PromptPanel.kt @@ -491,10 +491,10 @@ class PromptPanel( override fun outlineColor() = if (UIUtil.isFocusAncestor(editor)) { JBUI.CurrentTheme.Focus.focusColor() } else { - SessionUiStyle.View.line() + SessionUiStyle.View.Outline.brightColor() } - override fun outlineWidth() = if (UIUtil.isFocusAncestor(editor)) focus.get() else JBUI.scale(1) + override fun outlineWidth() = if (UIUtil.isFocusAncestor(editor)) focus.get() else SessionUiStyle.View.Outline.width() override fun cornerArc() = JBUI.scale(JBUI.getInt("Button.arc", SessionUiStyle.View.Prompt.CORNER_ARC)) } diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/ui/selection/SessionSelection.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/ui/selection/SessionSelection.kt index 2a52484c25a..0f7fb1a14b0 100644 --- a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/ui/selection/SessionSelection.kt +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/ui/selection/SessionSelection.kt @@ -157,7 +157,7 @@ class SessionSelection : Disposable { override fun clearSelection() { val pos = component.selectionStart.coerceIn(0, component.document.length) - component.select(pos, pos) + component.caretPosition = pos } override fun applyStyle(style: SessionEditorStyle) { diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/ui/style/SessionUiStyle.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/ui/style/SessionUiStyle.kt index 83fc0fa2006..9ffd77482dd 100644 --- a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/ui/style/SessionUiStyle.kt +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/ui/style/SessionUiStyle.kt @@ -9,51 +9,57 @@ import javax.swing.border.Border /** Static style tokens owned by the chat session UI. */ object SessionUiStyle { + object Transcript { + fun bgColor(): Color = UiStyle.Colors.bg() + } + /** Geometry for the transcript list and its scroll behavior. */ object SessionLayout { - const val GAP = 4 + const val GAP = 3 const val TRANSCRIPT_PADDING = 12 + const val TRANSCRIPT_SCROLLBAR_PADDING = 10 const val USER_PROMPT_INDENT = 100 - const val SCROLL_INCREMENT = 16 + const val SCROLL_INCREMENT = 48 } /** Shared tokens for individual transcript views and session views. */ object View { - const val SESSION_VIEW_GAP = 6 - const val SESSION_VIEW_VERTICAL_PADDING = 8 - const val SESSION_VIEW_HORIZONTAL_PADDING = 12 - const val SESSION_VIEW_BODY_EXTRA_HEIGHT = 16 + object Layout { + const val GAP = 5 + const val VERTICAL_PADDING = 7 + const val HORIZONTAL_PADDING = 12 + const val BODY_EXTRA_HEIGHT = 16 + } internal const val BORDER_DELTA = 80 internal const val HOVER_BORDER_ALPHA = 0.18f internal const val HOVER_FILL_ALPHA = 0.10f - /** Creates a visible separator against editor-derived transcript surfaces. */ - fun line(): Color = JBColor.lazy { UiStyle.Colors.contrast(UiStyle.Colors.editorBackground(), BORDER_DELTA) } + object Surface { + fun bgColor(): Color = UiStyle.Colors.editorBackground() - fun transcript(): Color = UiStyle.Colors.bg() + fun headerBgColor(): Color = UiStyle.Colors.editorBackground() - fun sessionViewBackground(): Color = UiStyle.Colors.contentBackground() - - fun sessionViewOutline(): Color = UiStyle.Colors.contentBorder() - - fun surface(): Color = UiStyle.Colors.editorBackground() - - fun header(): Color = UiStyle.Colors.editorBackground() - - /** Subtle hover fill, softer than the session-view outline. */ - fun headerHover(): Color = JBColor.lazy { UiStyle.Colors.blend(header(), hoverLine(), HOVER_FILL_ALPHA) } - - /** Subtle hover outline, stronger than the hover fill. */ - fun hoverLine(): Color = JBColor.lazy { - UiStyle.Colors.blend(line(), JBUI.CurrentTheme.ActionButton.hoverBackground(), HOVER_BORDER_ALPHA) + /** Subtle hover fill, softer than the session-view outline. */ + fun headerHoverBgColor(): Color = JBColor.lazy { + UiStyle.Colors.blend(headerBgColor(), Outline.hoverColor(), HOVER_FILL_ALPHA) + } } - fun sessionView(color: Color = line()): Border = outline(color) + object Outline { + fun color(): Color = UiStyle.Colors.contentBorder() - fun outline(color: Color = line()): Border = JBUI.Borders.customLine(color, 1) + fun brightColor(): Color = JBColor.lazy { + UiStyle.Colors.contrast(UiStyle.Colors.editorBackground(), BORDER_DELTA) + } - fun topOutline(): Border = JBUI.Borders.customLineTop(line()) + /** Subtle hover outline, stronger than the hover fill. */ + fun hoverColor(): Color = JBColor.lazy { + UiStyle.Colors.blend(brightColor(), JBUI.CurrentTheme.ActionButton.hoverBackground(), HOVER_BORDER_ALPHA) + } + + fun width(): Int = JBUI.scale(1) + } /** Prompt input dimensions and chrome inside the session view. */ object Prompt { @@ -74,6 +80,9 @@ object SessionUiStyle { /** Reasoning block preview sizing. */ object Reasoning { const val BODY_LINES = 5 + const val HEADER_VERTICAL_PADDING = 5 + const val BODY_VERTICAL_PADDING = 4 + const val BODY_HORIZONTAL_PADDING = 8 } /** Message container roles and user bubble geometry. */ @@ -119,6 +128,12 @@ object SessionUiStyle { } } + object AccountPopup { + fun bgColor(): Color = UiStyle.Colors.contentBackground() + + fun outlineColor(): Color = UiStyle.Colors.contentBorder() + } + /** Limits for the empty-state recent sessions list. */ object RecentSessions { const val LIMIT = 5 @@ -140,7 +155,13 @@ object SessionUiStyle { /** Border presets for connection dock panel. */ object Dock { fun banner(): Border = JBUI.Borders.compound( - JBUI.Borders.customLineTop(SessionUiStyle.View.line()), + JBUI.Borders.customLine( + SessionUiStyle.View.Outline.color(), + SessionUiStyle.View.Outline.width(), + 0, + 0, + 0, + ), JBUI.Borders.empty(UiStyle.Gap.sm(), UiStyle.Gap.lg(), 0, UiStyle.Gap.lg()), )!! } diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/CompactionView.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/CompactionView.kt index 25435404d9b..ece0854420a 100644 --- a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/CompactionView.kt +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/CompactionView.kt @@ -40,7 +40,7 @@ class CompactionView(@Suppress("UNUSED_PARAMETER") compaction: Compaction) : Par applyStyle(SessionEditorStyle.current()) val line = { JPanel().apply { - background = SessionUiStyle.View.line() + background = SessionUiStyle.View.Outline.color() isOpaque = true preferredSize = JBDimension(0, JBUI.scale(1)) } } diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/MessageView.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/MessageView.kt index 5b71c23b5e6..d0b5e06b445 100644 --- a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/MessageView.kt +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/MessageView.kt @@ -2,6 +2,7 @@ package ai.kilocode.client.session.views import ai.kilocode.client.session.model.Content import ai.kilocode.client.session.model.Message +import ai.kilocode.client.session.model.Reasoning import ai.kilocode.client.session.model.StepFinish import ai.kilocode.client.session.model.Tool import ai.kilocode.client.session.model.ToolCallRef @@ -18,6 +19,7 @@ import com.intellij.util.ui.JBUI import java.awt.Graphics import java.awt.Graphics2D import java.awt.RenderingHints +import javax.swing.JComponent /** * A single message container inside a [TurnView]. @@ -36,6 +38,9 @@ class MessageView( private var style: SessionEditorStyle = SessionEditorStyle.current(), private val openUrl: (String) -> Unit = {}, private val selection: SessionSelection? = null, + private val resize: ((JComponent, () -> Unit) -> Unit)? = null, + private val repo: String? = null, + private val hover: ((PartView, Boolean) -> Unit)? = null, ) : ai.kilocode.client.session.ui.SessionLayoutPanel( JBUI.scale(SessionUiStyle.SessionLayout.GAP), ), Disposable, SessionEditorStyleTarget, SessionView { @@ -48,6 +53,11 @@ class MessageView( get() = if (role == SessionUiStyle.View.Message.USER_ROLE) SessionView.Kind.UserPrompt else SessionView.Kind.Default private val parts = LinkedHashMap() + // Adjacent reasoning parts render through the first ReasoningView. aliases maps each + // merged child id to that owner id, and sources stores the child's latest full text + // so snapshot updates can append only deltas. + private val aliases = LinkedHashMap() + private val sources = LinkedHashMap() private var hidden: ToolCallRef? = null init { @@ -59,10 +69,7 @@ class MessageView( for ((_, content) in msg.parts) { if (content is StepFinish) continue if (isHidden(content)) continue - val view = view(content) - view.applyStyle(style) - parts[content.id] = view - add(view) + addPart(content) } } @@ -81,8 +88,11 @@ class MessageView( if (content is StepFinish) return if (isHidden(content)) { // Remove any stale view for this content so it disappears when suppressed - val stale = parts.remove(content.id) + val id = aliases.remove(content.id) + sources.remove(content.id) + val stale = if (id == null) parts.remove(content.id) else null if (stale != null) { + detach(stale) remove(stale) Disposer.dispose(stale) syncBorder() @@ -90,6 +100,16 @@ class MessageView( } return } + val id = aliases[content.id] + if (id != null && content is Reasoning) { + updateAlias(content, id) + refresh() + return + } + if (id != null) { + aliases.remove(content.id) + sources.remove(content.id) + } val existing = parts[content.id] if (existing != null) { if (ViewFactory.shouldReplace(existing, content)) { @@ -100,20 +120,56 @@ class MessageView( refresh() return } + addPart(content) + syncBorder() + refresh() + } + + private fun addPart(content: Content) { + if (content is Reasoning) { + val previous = parts.values.lastOrNull() + if (previous is ReasoningView) { + aliases[content.id] = previous.contentId + sources[content.id] = content.content.toString() + previous.update(merged(previous, content, content.content.toString())) + return + } + } val view = view(content) + view.resize = resize + view.hover = hover view.applyStyle(style) parts[content.id] = view add(view) - syncBorder() - refresh() + } + + private fun updateAlias(content: Reasoning, id: String) { + val view = parts[id] as? ReasoningView ?: return + val prev = sources[content.id].orEmpty() + val next = content.content.toString() + val delta = if (next.startsWith(prev)) next.removePrefix(prev) else next + sources[content.id] = next + if (delta.isEmpty()) return + view.update(merged(view, content, delta)) + } + + private fun merged(view: ReasoningView, content: Reasoning, delta: String) = Reasoning(view.contentId).also { + it.done = content.done + it.content.append(view.markdown()) + it.content.append(delta) } private fun replacePart(content: Content, existing: PartView) { val at = components.indexOfFirst { it === existing }.takeIf { it >= 0 } ?: componentCount parts.remove(content.id) + aliases.values.removeAll { it == content.id } + sources.keys.removeAll { it !in aliases } + detach(existing) remove(existing) Disposer.dispose(existing) val view = view(content) + view.resize = resize + view.hover = hover view.applyStyle(style) parts[content.id] = view add(view, at) @@ -123,7 +179,14 @@ class MessageView( /** Remove the renderer for [contentId] if present. */ fun removePart(contentId: String) { + if (aliases.remove(contentId) != null) { + sources.remove(contentId) + return + } val view = parts.remove(contentId) ?: return + aliases.values.removeAll { it == contentId } + sources.keys.removeAll { it !in aliases } + detach(view) remove(view) Disposer.dispose(view) syncBorder() @@ -150,17 +213,17 @@ class MessageView( */ private fun rebuildParts() { parts.values.forEach { + detach(it) remove(it) Disposer.dispose(it) } parts.clear() + aliases.clear() + sources.clear() for ((_, content) in msg.parts) { if (content is StepFinish) continue if (isHidden(content)) continue - val view = view(content) - view.applyStyle(style) - parts[content.id] = view - add(view) + addPart(content) } syncBorder() refresh() @@ -172,20 +235,22 @@ class MessageView( } private fun view(content: Content) = if (msg.info.role == SessionUiStyle.View.Message.USER_ROLE) { - ViewFactory.createUser(content, openFile, openUrl, selection) + ViewFactory.createUser(content, openFile, openUrl, selection, repo) } else { - ViewFactory.create(content, openFile, openUrl, selection) + ViewFactory.create(content, openFile, openUrl, selection, repo) } /** Append a streaming delta to the renderer for [contentId]. */ fun appendDelta(contentId: String, delta: String): Boolean { - val part = parts[contentId] ?: return false + val id = aliases[contentId] + if (id != null) sources[contentId] = sources[contentId].orEmpty() + delta + val part = parts[id ?: contentId] ?: return false part.appendDelta(delta) return true } /** Look up a renderer by part id. */ - fun part(id: String): PartView? = parts[id] + fun part(id: String): PartView? = parts[aliases[id] ?: id] /** Ordered part ids — stable for test assertions. */ fun partIds(): List = parts.keys.toList() @@ -202,10 +267,13 @@ class MessageView( override fun dispose() { parts.values.forEach { + detach(it) remove(it) Disposer.dispose(it) } parts.clear() + aliases.clear() + sources.clear() hidden = null } @@ -220,7 +288,7 @@ class MessageView( val arc = JBUI.scale(JBUI.getInt("Button.arc", SessionUiStyle.View.Prompt.CORNER_ARC)) g2.color = style.editorScheme.defaultBackground g2.fillRoundRect(0, 0, width, height, arc, arc) - g2.color = SessionUiStyle.View.line() + g2.color = SessionUiStyle.View.Outline.brightColor() val w = width - 1 val h = height - 1 if (w > 0 && h > 0) g2.drawRoundRect(0, 0, w, h, arc, arc) @@ -235,5 +303,10 @@ class MessageView( repaint() } + private fun detach(view: PartView) { + view.setHovered(false) + view.hover = null + } + private fun assistantBorder() = JBUI.Borders.empty() } diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/ReasoningView.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/ReasoningView.kt index 9907738612f..21afb1fcab7 100644 --- a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/ReasoningView.kt +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/ReasoningView.kt @@ -12,10 +12,10 @@ import ai.kilocode.client.session.views.base.SecondarySessionPartView import ai.kilocode.client.ui.UiStyle import ai.kilocode.client.ui.md.MdView import ai.kilocode.client.ui.md.MdViewFactory -import com.intellij.icons.AllIcons import com.intellij.openapi.util.Disposer import com.intellij.ui.components.JBLabel import com.intellij.ui.components.JBScrollPane +import com.intellij.util.concurrency.annotations.RequiresEdt import com.intellij.util.ui.JBUI import java.awt.BorderLayout import java.awt.Dimension @@ -24,6 +24,7 @@ import java.awt.Rectangle import javax.swing.JPanel import javax.swing.ScrollPaneConstants import javax.swing.Scrollable +import javax.swing.SwingUtilities /** Renders reasoning as a secondary collapsible block. */ class ReasoningView( @@ -32,11 +33,17 @@ class ReasoningView( private val selection: SessionSelection? = null, private val parts: ReasoningParts = reasoningParts(selection), ) : - SecondarySessionPartView(parts.header, { parts.scroll(openUrl) }) { + SecondarySessionPartView( + parts.header, + { parts.scroll(openUrl) }, + expanded = reasoning.content.isNotBlank() && !reasoning.done, + ) { override val contentId: String = reasoning.id + /** Lazily creates, registers, populates, and styles the editor-backed body on first access. */ val md: MdView + @RequiresEdt get() { val fresh = !parts.bodyCreated() val view = parts.md(openUrl) @@ -50,52 +57,97 @@ class ReasoningView( private var style = SessionEditorStyle.current() private var source = reasoning.content.toString() + private var done = reasoning.done private var registered = false + private var following = false init { + row.border = JBUI.Borders.empty( + JBUI.scale(SessionUiStyle.View.Reasoning.HEADER_VERTICAL_PADDING), + JBUI.scale(SessionUiStyle.View.Layout.HORIZONTAL_PADDING), + ) bindHeader(parts.title, parts.icon) applyStyle(style) + if (bodyVisible()) syncBody() + syncBorder() sync() } + @RequiresEdt override fun expand(): Boolean { val changed = super.expand() if (!changed) return false + syncBorder() syncBody() applyBodyStyle() return true } + @RequiresEdt + override fun collapse(): Boolean { + val changed = super.collapse() + if (!changed) return false + syncBorder() + return true + } + + @RequiresEdt override fun update(content: Content) { if (content !is Reasoning) return var changed = false val next = content.content.toString() + val follow = tailVisible() + if (done != content.done) { + done = content.done + changed = true + } if (source != next) { source = next - if (parts.bodyCreated()) md.set(source) + if (parts.bodyCreated()) { + md.set(source) + followTail(follow) + } changed = true } changed = sync() || changed if (changed) refresh() } + @RequiresEdt override fun appendDelta(delta: String) { if (delta.isEmpty()) return + val follow = tailVisible() source += delta - if (parts.bodyCreated()) md.append(delta) + if (parts.bodyCreated()) { + md.append(delta) + followTail(follow) + } val changed = sync() if (changed || bodyVisible()) refresh() } + @RequiresEdt fun markdown(): String = source + @RequiresEdt fun hasToggle(): Boolean = arrow.isVisible + @RequiresEdt fun headerText(): String = parts.title.text + @RequiresEdt internal fun headerFont() = parts.title.font + @RequiresEdt internal fun bodyVisible() = parts.scrollOrNull?.parent === this + @RequiresEdt internal fun horizontalPolicy() = parts.scrollOrNull?.horizontalScrollBarPolicy ?: ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER + @RequiresEdt internal fun bodyMaxRows() = SessionUiStyle.View.Reasoning.BODY_LINES + @RequiresEdt internal fun bodyCreated() = parts.bodyCreated() + @RequiresEdt + internal fun bodyScrollValue() = parts.scrollOrNull?.verticalScrollBar?.value ?: 0 + @RequiresEdt + internal fun bodyScrollBottom() = parts.scrollOrNull?.verticalScrollBar?.let { it.maximum - it.visibleAmount } ?: 0 + @RequiresEdt override fun applyStyle(style: SessionEditorStyle) { this.style = style var changed = false @@ -107,6 +159,7 @@ class ReasoningView( if (changed) refresh() } + @RequiresEdt override fun getPreferredSize(): Dimension { val size = super.getPreferredSize() if (!bodyVisible()) return size @@ -116,7 +169,34 @@ class ReasoningView( private fun canExpand(): Boolean = source.isNotBlank() - private fun sync(): Boolean = syncExpandable(canExpand()) + private fun sync(): Boolean { + var changed = false + val visible = source.isNotBlank() + if (isVisible != visible) { + isVisible = visible + changed = true + } + changed = syncExpandable(canExpand()) || changed + if (visible && !done && !parts.bodyCreated()) { + changed = expand() || changed + changed = syncExpandable(canExpand()) || changed + } + return changed + } + + private fun syncBorder() { + if (isExpanded()) { + border = JBUI.Borders.customLine( + SessionUiStyle.View.Outline.color(), + 0, + SessionUiStyle.View.Outline.width(), + 0, + 0, + ) + return + } + border = JBUI.Borders.empty(0, 1, 0, 0) + } private fun apply(md: MdView): Boolean { var changed = false @@ -130,10 +210,12 @@ class ReasoningView( return changed } + @RequiresEdt private fun syncBody() { val md = md registerBody(md) md.set(source) + followTail(true) } private fun applyBodyStyle(): Boolean { @@ -154,7 +236,28 @@ class ReasoningView( if (!parts.bodyCreated()) return 0 val md = md return md.component.getFontMetrics(md.font).height * bodyMaxRows() + - JBUI.scale(SessionUiStyle.View.SESSION_VIEW_BODY_EXTRA_HEIGHT) + JBUI.scale(SessionUiStyle.View.Layout.BODY_EXTRA_HEIGHT) + } + + @RequiresEdt + private fun tailVisible(): Boolean { + if (!bodyVisible()) return false + val scroll = parts.scrollOrNull ?: return false + val bar = scroll.verticalScrollBar + return bar.value >= bar.maximum - bar.visibleAmount + } + + @RequiresEdt + private fun followTail(follow: Boolean) { + if (!follow || !bodyVisible() || following) return + val scroll = parts.scrollOrNull ?: return + following = true + SwingUtilities.invokeLater { + following = false + if (!bodyVisible()) return@invokeLater + val bar = scroll.verticalScrollBar + bar.value = bar.maximum - bar.visibleAmount + } } override fun dumpLabel(): String { @@ -187,18 +290,18 @@ class ReasoningParts( } val panel = TrackPanel().apply { isOpaque = true - background = SessionUiStyle.View.surface() + background = SessionUiStyle.View.Surface.bgColor() border = JBUI.Borders.empty( - JBUI.scale(SessionUiStyle.View.SESSION_VIEW_VERTICAL_PADDING), - JBUI.scale(SessionUiStyle.View.SESSION_VIEW_HORIZONTAL_PADDING), + JBUI.scale(SessionUiStyle.View.Reasoning.BODY_VERTICAL_PADDING), + JBUI.scale(SessionUiStyle.View.Reasoning.BODY_HORIZONTAL_PADDING), ) add(md.component, BorderLayout.CENTER) } val scroll = JBScrollPane(panel).apply { - border = SessionUiStyle.View.topOutline() + border = JBUI.Borders.empty() isOpaque = true - background = SessionUiStyle.View.surface() - viewport.background = SessionUiStyle.View.surface() + background = SessionUiStyle.View.Surface.bgColor() + viewport.background = SessionUiStyle.View.Surface.bgColor() horizontalScrollBarPolicy = ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER verticalScrollBarPolicy = ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED } @@ -214,8 +317,8 @@ class ReasoningBody( private fun reasoningParts(selection: SessionSelection? = null): ReasoningParts { val title = JBLabel(KiloBundle.message("session.part.reasoning")).apply { foreground = UiStyle.Colors.weak() } - val icon = JBLabel(AllIcons.General.InspectionsEye).apply { foreground = UiStyle.Colors.weak() } - val header = JPanel(BorderLayout(JBUI.scale(SessionUiStyle.View.SESSION_VIEW_GAP), 0)).apply { + val icon = JBLabel(SessionViewIcons.eye).apply { foreground = UiStyle.Colors.weak() } + val header = JPanel(BorderLayout(JBUI.scale(SessionUiStyle.View.Layout.GAP), 0)).apply { isOpaque = false add(icon, BorderLayout.WEST) add(title, BorderLayout.CENTER) diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/SessionViewIcons.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/SessionViewIcons.kt new file mode 100644 index 00000000000..c59f5d371fb --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/SessionViewIcons.kt @@ -0,0 +1,25 @@ +package ai.kilocode.client.session.views + +import com.intellij.openapi.util.IconLoader + +object SessionViewIcons { + val brain = icon("brain") + val bubble = icon("bubble-5") + val bulletList = icon("bullet-list") + val checklist = icon("checklist") + val chevronDown = icon("chevron-down") + val chevronLeft = icon("chevron-left") + val chevronRight = icon("chevron-right") + val code = icon("code") + val codeLines = icon("code-lines") + val console = icon("console") + val eye = icon("eye") + val glasses = icon("glasses") + val mcp = icon("mcp") + val search = icon("magnifying-glass-menu") + val task = icon("task") + val warning = icon("warning") + val windowCursor = icon("window-cursor") + + private fun icon(name: String) = IconLoader.getIcon("/icons/views/$name.svg", SessionViewIcons::class.java) +} diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/TextView.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/TextView.kt index 1e4358415ef..fa56f6466c2 100644 --- a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/TextView.kt +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/TextView.kt @@ -73,7 +73,7 @@ open class TextView( protected open fun styleFont(style: SessionEditorStyle) = style.transcriptFont - protected open fun styleBackground(style: SessionEditorStyle) = SessionUiStyle.View.transcript() + protected open fun styleBackground(style: SessionEditorStyle) = SessionUiStyle.Transcript.bgColor() private fun refresh() { revalidate() diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/ToolView.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/ToolView.kt deleted file mode 100644 index 5951f40ff00..00000000000 --- a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/ToolView.kt +++ /dev/null @@ -1,655 +0,0 @@ -@file:Suppress("TooManyFunctions") - -package ai.kilocode.client.session.views - -import ai.kilocode.client.plugin.KiloBundle -import ai.kilocode.client.session.model.Content -import ai.kilocode.client.session.model.Tool -import ai.kilocode.client.session.model.ToolExecState -import ai.kilocode.client.session.model.ToolKind -import ai.kilocode.client.session.ui.style.SessionEditorStyle -import ai.kilocode.client.session.ui.selection.SessionSelection -import ai.kilocode.client.session.ui.style.SessionUiStyle -import ai.kilocode.client.session.views.base.SecondarySessionPartView -import ai.kilocode.client.ui.UiStyle -import com.intellij.icons.AllIcons -import com.intellij.ui.components.JBLabel -import com.intellij.ui.components.JBScrollPane -import com.intellij.ui.components.JBTextArea -import com.intellij.util.ui.JBUI -import com.intellij.xml.util.XmlStringUtil -import java.awt.BorderLayout -import java.awt.CardLayout -import java.awt.Color -import java.awt.Cursor -import java.awt.Dimension -import java.awt.Font -import java.awt.event.MouseAdapter -import java.awt.event.MouseEvent -import javax.swing.Box -import javax.swing.Icon -import javax.swing.JComponent -import javax.swing.JPanel -import javax.swing.ScrollPaneConstants - -/** Renders non-read tool calls with VS Code-inspired rows/cards. */ -class ToolView( - tool: Tool, - private val selection: SessionSelection? = null, - private val parts: ToolParts = toolParts(tool), -) : - SecondarySessionPartView(parts.header, { parts.scroll(tool) }) { - - override val contentId: String = tool.id - - private var item = tool - private var style = SessionEditorStyle.current() - private var registered = false - - init { - bindHeader(parts.glyph, parts.title, parts.sub, parts.state, parts.center, parts.controls, parts.slot) - applyStyle(style) - sync() - } - - override fun expand(): Boolean { - val changed = super.expand() - if (!changed) return false - syncBody() - applyBodyStyle() - return true - } - - override fun getPreferredSize(): Dimension { - val size = super.getPreferredSize() - if (!bodyVisible()) return size - val height = row.preferredSize.height + bodyMaxHeight() - return Dimension(size.width, minOf(size.height, height)) - } - - override fun update(content: Content) { - if (content !is Tool) return - val was = item.name - item = content - var changed = false - if (was != content.name || !canExpand(content)) changed = collapse() || changed - changed = sync() || changed - changed = syncBody() || changed - if (changed) refresh() - } - - fun labelText(): String = listOf(parts.title.text, subtitleText(parts), parts.state.text) - .filter { it.isNotBlank() } - .joinToString(" ") - - fun commandText(): String = command(item) - - fun outputText(): String = output(item) - fun bodyText(): String = body(item) - internal fun previewText(): String = parts.text?.text ?: preview(item) - fun hasToggle(): Boolean = arrow.isVisible - internal fun bodyFont() = parts.text?.font ?: style.transcriptFont - internal fun titleFont() = parts.title.font - internal fun subtitleFont() = parts.sub.font - internal fun stateFont() = parts.state.font - internal fun bodyEditable() = parts.text?.isEditable ?: false - internal fun bodyCaretVisible() = parts.text?.caret?.isVisible ?: false - internal fun bodyVisible() = parts.scroll?.parent === this - internal fun controlCount() = if (arrow.isVisible) 1 else 0 - internal fun horizontalPolicy() = parts.scroll?.horizontalScrollBarPolicy ?: ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER - internal fun bodyWrap() = parts.text?.lineWrap ?: true - internal fun bodyMaxRows() = SessionUiStyle.View.Tool.BODY_LINES - internal fun bodyCreated() = parts.bodyCreated() - - override fun applyStyle(style: SessionEditorStyle) { - this.style = style - var changed = false - changed = setFont(parts.title, style.boldEditorFont) || changed - changed = setFont(parts.sub, style.smallEditorFont) || changed - changed = setFont(parts.link, style.smallEditorFont) || changed - changed = setFont(parts.state, style.smallEditorFont) || changed - changed = applyBodyStyle() || changed - if (changed) refresh() - } - - private fun sync(): Boolean { - val expand = canExpand(item) - var changed = false - changed = syncExpandable(expand) || changed - changed = setVisible(parts.state, !expand) || changed - changed = syncLabels() || changed - val text = parts.text - if (text != null) changed = setForeground(text, bodyColor()) || changed - return changed - } - - private fun syncLabels(): Boolean { - var changed = false - changed = setIcon(parts.glyph, icon(item)) || changed - changed = setForeground(parts.glyph, color(item)) || changed - changed = setText(parts.title, title(item)) || changed - changed = setText(parts.sub, subtitle(item)) || changed - changed = setForeground(parts.title, titleColor(item)) || changed - changed = setText(parts.state, stateText(item)) || changed - changed = setForeground(parts.state, color(item)) || changed - return changed - } - - private fun syncBody(): Boolean { - var changed = false - val text = parts.text ?: return false - val value = preview(item) - if (text.text != value) { - text.text = value - text.caretPosition = 0 - changed = true - } - changed = setForeground(text, bodyColor()) || changed - return changed - } - - private fun applyBodyStyle(): Boolean { - val text = parts.text ?: return false - if (!registered && selection != null && text.parent != null) { - registered = true - selection.register(text, this) - } - return setFont(text, style.transcriptFont) - } - - private fun bodyColor() = if (item.state == ToolExecState.ERROR) UiStyle.Colors.errorLabelForeground() else UiStyle.Colors.fg() - - private fun bodyMaxHeight(): Int { - val text = parts.text ?: return 0 - return text.getFontMetrics(text.font).height * bodyMaxRows() + - JBUI.scale(SessionUiStyle.View.SESSION_VIEW_BODY_EXTRA_HEIGHT) - } - - override fun dumpLabel() = "ToolView#$contentId(${labelText()})" -} - -/** Renders read calls with secondary, borderless chrome. */ -class ReadToolView( - tool: Tool, - openFile: (String) -> Unit = {}, - private val selection: SessionSelection? = null, - private val parts: ToolParts = toolParts(tool, openFile), -) : SecondarySessionPartView(parts.header, parts.scroll(tool), expandable = false) { - - companion object { - fun canRender(tool: Tool): Boolean = tool.kind == ToolKind.READ - } - - override val contentId: String = tool.id - - private var item = tool - private var style = SessionEditorStyle.current() - - init { - parts.text?.let { selection?.register(it, this) } - bindHeader(parts.glyph, parts.title, parts.sub, parts.state, parts.center, parts.controls, parts.slot) - parts.text?.text = preview(item) - applyStyle(style) - sync() - } - - override fun getPreferredSize(): Dimension { - val size = super.getPreferredSize() - if (!bodyVisible()) return size - val height = row.preferredSize.height + bodyMaxHeight() - return Dimension(size.width, minOf(size.height, height)) - } - - override fun update(content: Content) { - if (content !is Tool) return - item = content - var changed = sync() - changed = syncBody() || changed - if (changed) refresh() - } - - fun labelText(): String = listOf(parts.title.text, subtitleText(parts), parts.state.text) - .filter { it.isNotBlank() } - .joinToString(" ") - fun bodyText(): String = body(item) - internal fun bodyVisible() = parts.scroll?.parent === this - internal fun hasToggle() = arrow.isVisible - internal fun horizontalPolicy() = parts.scroll?.horizontalScrollBarPolicy ?: ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER - internal fun bodyMaxRows() = SessionUiStyle.View.Tool.BODY_LINES - internal fun bodyFont() = parts.text?.font ?: style.transcriptFont - internal fun linkVisible() = parts.link.isVisible - internal fun linkText() = parts.label - internal fun linkMarkup() = parts.link.text ?: "" - internal fun linkForeground() = parts.link.foreground - internal fun linkFont() = parts.link.font - internal fun subtitleForeground() = parts.sub.foreground - internal fun subtitleFont() = parts.sub.font - internal fun linkHref() = parts.href - internal fun openLink() = parts.openLink() - - override fun applyStyle(style: SessionEditorStyle) { - this.style = style - var changed = false - changed = setFont(parts.title, style.boldEditorFont) || changed - changed = setFont(parts.sub, style.transcriptFont) || changed - changed = setFont(parts.link, style.transcriptFont) || changed - changed = setFont(parts.state, style.smallEditorFont) || changed - parts.text?.let { changed = setFont(it, style.transcriptFont) || changed } - if (changed) refresh() - } - - private fun sync(): Boolean { - var changed = false - changed = syncExpandable(false) || changed - changed = setVisible(parts.state, true) || changed - changed = setIcon(parts.glyph, icon(item)) || changed - changed = setForeground(parts.glyph, color(item)) || changed - changed = setText(parts.title, title(item)) || changed - changed = syncSubtitle() || changed - changed = setForeground(parts.title, titleColor(item)) || changed - changed = setForeground(parts.sub, UiStyle.Colors.fg()) || changed - changed = setForeground(parts.link, UiStyle.Colors.fg()) || changed - changed = setText(parts.state, stateText(item)) || changed - changed = setForeground(parts.state, color(item)) || changed - parts.text?.let { changed = setForeground(it, bodyColor()) || changed } - return changed - } - - private fun syncSubtitle(): Boolean { - val target = target(item)?.takeIf { it.type == "file" } - if (target != null) { - var changed = false - if (parts.href != target.path) { - parts.href = target.path - changed = true - } - changed = setLinkText(parts, tail(target.path).ifBlank { target.path }) || changed - changed = show(parts, true) || changed - return changed - } - - var changed = false - if (parts.href != null) { - parts.href = null - changed = true - } - changed = setText(parts.sub, subtitle(item)) || changed - changed = show(parts, false) || changed - return changed - } - - private fun syncBody(): Boolean { - val value = preview(item) - val text = parts.text ?: return false - if (text.text == value) return false - text.text = value - text.caretPosition = 0 - return true - } - - private fun bodyColor() = if (item.state == ToolExecState.ERROR) UiStyle.Colors.errorLabelForeground() else UiStyle.Colors.fg() - - private fun bodyMaxHeight(): Int { - val text = parts.text ?: return 0 - return text.getFontMetrics(text.font).height * bodyMaxRows() + - JBUI.scale(SessionUiStyle.View.SESSION_VIEW_BODY_EXTRA_HEIGHT) - } - - override fun dumpLabel() = "ReadToolView#$contentId(${labelText()})" -} - -class ToolParts( - val header: JPanel, - val glyph: JBLabel, - val title: JBLabel, - val sub: JBLabel, - val link: JBLabel, - val slot: JPanel, - val state: JBLabel, - val center: JPanel, - val controls: JComponent, - private val open: ((String) -> Unit)? = null, -) { - var href: String? = null - var label: String = "" - private var body: ToolBody? = null - - val text: JBTextArea? - get() = body?.text - - val scroll: JBScrollPane? - get() = body?.scroll - - fun scroll(tool: Tool): JBScrollPane = body(tool).scroll - - fun bodyCreated() = body != null - - fun openLink() { - val value = href ?: return - open?.invoke(value) - } - - private fun body(tool: Tool): ToolBody { - val item = body - if (item != null) return item - val text = JBTextArea().apply { - isEditable = false - caret.isVisible = false - caret.isSelectionVisible = true - lineWrap = true - wrapStyleWord = true - foreground = if (tool.state == ToolExecState.ERROR) UiStyle.Colors.errorLabelForeground() else UiStyle.Colors.fg() - background = SessionUiStyle.View.surface() - border = JBUI.Borders.empty( - JBUI.scale(SessionUiStyle.View.SESSION_VIEW_VERTICAL_PADDING), - JBUI.scale(SessionUiStyle.View.SESSION_VIEW_HORIZONTAL_PADDING), - ) - } - val scroll = JBScrollPane(text).apply { - border = SessionUiStyle.View.topOutline() - isOpaque = true - background = SessionUiStyle.View.surface() - viewport.background = SessionUiStyle.View.surface() - horizontalScrollBarPolicy = ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER - verticalScrollBarPolicy = ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED - } - return ToolBody(text, scroll).also { body = it } - } -} - -class ToolBody( - val text: JBTextArea, - val scroll: JBScrollPane, -) - -private const val SUB_CARD = "sub" -private const val LINK_CARD = "link" - -private fun toolParts(tool: Tool, openFile: ((String) -> Unit)? = null): ToolParts { - lateinit var parts: ToolParts - val glyph = JBLabel() - val title = JBLabel() - val sub = JBLabel().apply { foreground = UiStyle.Colors.weak() } - val link = JBLabel().apply { - isVisible = false - isFocusable = false - foreground = UiStyle.Colors.fg() - cursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR) - setRequestFocusEnabled(false) - addMouseListener(object : MouseAdapter() { - override fun mouseClicked(e: MouseEvent) { - parts.openLink() - } - }) - } - val slot = JPanel(CardLayout()).apply { - isOpaque = false - add(sub, SUB_CARD) - add(link, LINK_CARD) - } - val state = JBLabel().apply { foreground = UiStyle.Colors.weak() } - val center = JPanel(BorderLayout(JBUI.scale(SessionUiStyle.View.SESSION_VIEW_GAP), 0)).apply { isOpaque = false } - val controls = Box.createHorizontalBox() - val header = JPanel(BorderLayout(JBUI.scale(SessionUiStyle.View.SESSION_VIEW_GAP), 0)).apply { - isOpaque = false - center.add(title, BorderLayout.WEST) - center.add(slot, BorderLayout.CENTER) - add(glyph, BorderLayout.WEST) - add(center, BorderLayout.CENTER) - add(controls, BorderLayout.EAST) - } - parts = ToolParts(header, glyph, title, sub, link, slot, state, center, controls, openFile) - return parts.also { - controls.add(it.state) - } -} - -private fun icon(tool: Tool) = when (tool.name) { - "read" -> AllIcons.Actions.Preview - "bash" -> AllIcons.Debugger.Console - else -> when (tool.state) { - ToolExecState.PENDING -> AllIcons.Process.Step_1 - ToolExecState.RUNNING -> AllIcons.Process.Step_2 - ToolExecState.COMPLETED -> AllIcons.Actions.Checked - ToolExecState.ERROR -> AllIcons.General.Error - } -} - -private fun title(tool: Tool) = when (tool.name) { - "read" -> KiloBundle.message("session.part.tool.read") - "bash" -> KiloBundle.message("session.part.tool.shell") - else -> toolTitle(tool) -} - -private fun subtitle(tool: Tool) = when (tool.name) { - "read" -> readPath(tool) - "bash" -> shellTitle(tool) - else -> toolSubtitle(tool) -} - -private fun setText(label: JBLabel, text: String): Boolean { - val value = if (text.isBlank()) "" else XmlStringUtil.wrapInHtml(XmlStringUtil.escapeString(text)) - if (label.text == value) return false - label.text = value - return true -} - -private fun setLinkText(parts: ToolParts, text: String): Boolean { - val value = if (text.isBlank()) "" else XmlStringUtil.wrapInHtml("${XmlStringUtil.escapeString(text)}") - if (parts.label == text && parts.link.text == value) return false - parts.label = text - parts.link.text = value - return true -} - -private fun show(parts: ToolParts, link: Boolean): Boolean { - if (parts.link.isVisible == link && parts.sub.isVisible != link) return false - (parts.slot.layout as CardLayout).show(parts.slot, if (link) LINK_CARD else SUB_CARD) - return true -} - -private fun subtitleText(parts: ToolParts): String = if (parts.link.isVisible) parts.label else parts.sub.text - -private fun setIcon(label: JBLabel, icon: Icon): Boolean { - if (label.icon === icon) return false - label.icon = icon - return true -} - -private fun setVisible(component: JComponent, visible: Boolean): Boolean { - if (component.isVisible == visible) return false - component.isVisible = visible - return true -} - -private fun setForeground(component: JComponent, color: Color): Boolean { - if (same(component.foreground, color)) return false - component.foreground = color - return true -} - -private fun setFont(component: JComponent, font: Font): Boolean { - if (component.font == font) return false - component.font = font - return true -} - -private fun same(a: Color?, b: Color): Boolean = a?.rgb == b.rgb - -private fun color(tool: Tool) = when (tool.state) { - ToolExecState.PENDING -> SessionUiStyle.View.Tool.pending() - ToolExecState.RUNNING -> SessionUiStyle.View.Tool.running() - ToolExecState.COMPLETED -> SessionUiStyle.View.Tool.completed() - ToolExecState.ERROR -> SessionUiStyle.View.Tool.error() -} - -private fun titleColor(tool: Tool) = if (tool.state == ToolExecState.ERROR) { - UiStyle.Colors.errorLabelForeground() -} else { - UiStyle.Colors.fg() -} - -private fun stateText(tool: Tool) = when (tool.state) { - ToolExecState.PENDING -> KiloBundle.message("session.part.tool.pending") - ToolExecState.RUNNING -> KiloBundle.message("session.part.tool.running") - ToolExecState.COMPLETED -> "" - ToolExecState.ERROR -> KiloBundle.message("session.part.tool.error") -} - -private fun readPath(tool: Tool): String { - val target = target(tool) - if (target != null) { - if (target.type == "file") return tail(target.path).ifBlank { target.path } - return target.path - } - val path = tool.input["filePath"] ?: tool.input["path"] ?: tool.title ?: return tool.name - return tail(path).ifBlank { path } -} - -private data class Target( - val path: String, - val type: String, -) - -private fun target(tool: Tool): Target? { - val out = output(tool) - if (out.isBlank()) return null - val path = tag(out, "path") ?: return null - val type = tag(out, "type") ?: return null - return Target(path, type.lowercase()) -} - -private fun tag(text: String, name: String): String? = - Regex("<$name>\\s*([\\s\\S]*?)\\s*") - .find(text) - ?.groupValues - ?.getOrNull(1) - ?.trim() - ?.takeIf { it.isNotBlank() } - -private fun shellTitle(tool: Tool): String = - tool.input["description"]?.takeIf { it.isNotBlank() } - ?: tool.metadata["description"]?.takeIf { it.isNotBlank() } - ?: tool.title?.takeIf { it.isNotBlank() } - ?: command(tool).lineSequence().firstOrNull { it.isNotBlank() } - ?: "" - -private fun command(tool: Tool): String = - tool.input["command"]?.takeIf { it.isNotBlank() } - ?: tool.metadata["command"]?.takeIf { it.isNotBlank() } - ?: "" - -private fun output(tool: Tool): String = - tool.output?.takeIf { it.isNotBlank() } - ?: tool.metadata["output"]?.takeIf { it.isNotBlank() } - ?: "" - -private fun preview(tool: Tool): String = if (tool.name == "bash") shellPreview(tool) else plainPreview(tool) - -private fun body(tool: Tool): String = if (tool.name == "bash") shellBody(tool) else plainBody(tool) - -private fun shellPreview(tool: Tool): String { - val cmd = command(tool) - val out = output(tool) - val err = tool.error?.takeIf { it.isNotBlank() } - return Preview().apply { - if (cmd.isNotBlank()) append("$ ").append(cmd) - if (out.isNotBlank()) { - sep() - append(out) - } - if (err != null) { - sep() - append(err) - } - }.build() -} - -private fun shellBody(tool: Tool): String { - val cmd = command(tool) - val out = output(tool) - val err = tool.error?.takeIf { it.isNotBlank() } - return buildString { - if (cmd.isNotBlank()) append("$ ").append(cmd) - if (out.isNotBlank()) { - if (isNotEmpty()) append("\n\n") - append(out) - } - if (err != null) { - if (isNotEmpty()) append("\n\n") - append(err) - } - } -} - -private fun plainPreview(tool: Tool): String { - val out = output(tool) - val err = tool.error?.takeIf { it.isNotBlank() } - return Preview().apply { - if (out.isNotBlank()) append(out) - if (err != null) { - sep() - append(err) - } - }.build() -} - -private fun plainBody(tool: Tool): String { - val out = output(tool) - val err = tool.error?.takeIf { it.isNotBlank() } - return listOf(out, err).filter { !it.isNullOrBlank() }.joinToString("\n\n") -} - -private fun canExpand(tool: Tool): Boolean { - if (tool.name == "bash") return command(tool).isNotBlank() || output(tool).isNotBlank() || !tool.error.isNullOrBlank() - return output(tool).isNotBlank() || !tool.error.isNullOrBlank() -} - -private fun toolTitle(tool: Tool): String = - tool.title?.takeIf { it.isNotBlank() } - ?: tool.name.replace('_', ' ').replaceFirstChar { it.titlecase() } - -private fun toolSubtitle(tool: Tool): String { - val base = listOf("description", "query", "url", "filePath", "path", "name") - .mapNotNull { tool.input[it]?.takeIf { value -> value.isNotBlank() } } - .firstOrNull() - val args = listOf("pattern", "include", "offset", "limit") - .mapNotNull { key -> tool.input[key]?.takeIf { it.isNotBlank() }?.let { "$key=$it" } } - return listOfNotNull(base).plus(args).joinToString(" ") -} - -private fun tail(path: String): String { - val value = path.trimEnd('/', '\\') - val index = maxOf(value.lastIndexOf('/'), value.lastIndexOf('\\')) - if (index < 0) return value - return value.substring(index + 1) -} - -private class Preview { - private val text = StringBuilder() - private var cut = false - - fun append(value: String): Preview { - if (cut) return this - val rem = SessionUiStyle.View.Tool.PREVIEW_LIMIT - text.length - if (value.length <= rem) { - text.append(value) - return this - } - if (rem > 0) text.append(value, 0, rem) - cut = true - return this - } - - fun sep(): Preview { - if (text.isNotEmpty()) append("\n\n") - return this - } - - fun build(): String { - if (!cut) return text.toString() - if (text.isNotEmpty()) text.append("\n\n") - text.append(KiloBundle.message("session.part.tool.truncated")) - return text.toString() - } -} diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/TurnView.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/TurnView.kt index 5320b21dbf0..459509ffc93 100644 --- a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/TurnView.kt +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/TurnView.kt @@ -6,9 +6,11 @@ import ai.kilocode.client.session.ui.style.SessionEditorStyle import ai.kilocode.client.session.ui.selection.SessionSelection import ai.kilocode.client.session.ui.style.SessionEditorStyleTarget import ai.kilocode.client.session.ui.style.SessionUiStyle +import ai.kilocode.client.session.views.base.PartView import com.intellij.openapi.Disposable import com.intellij.openapi.util.Disposer import com.intellij.util.ui.JBUI +import javax.swing.JComponent /** * Top-level transcript item representing one conversational turn. @@ -25,6 +27,9 @@ class TurnView( private var style: SessionEditorStyle = SessionEditorStyle.current(), private val openUrl: (String) -> Unit = {}, private val selection: SessionSelection? = null, + private val resize: ((JComponent, () -> Unit) -> Unit)? = null, + private val repo: String? = null, + private val hover: ((PartView, Boolean) -> Unit)? = null, ) : SessionLayoutPanel(JBUI.scale(SessionUiStyle.SessionLayout.GAP)), Disposable, SessionEditorStyleTarget { constructor(id: String, openFile: (String) -> Unit) : this(id, openFile, SessionEditorStyle.current()) @@ -37,7 +42,7 @@ class TurnView( /** Add a new [MessageView] for [msg] at the end of this turn. */ fun addMessage(msg: Message): MessageView { - val view = MessageView(msg, openFile, style, openUrl, selection) + val view = MessageView(msg, openFile, style, openUrl, selection, resize, repo, hover) messages[msg.info.id] = view add(view) revalidate() diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/ViewFactory.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/ViewFactory.kt index fca054a0c93..a13dde6e1ce 100644 --- a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/ViewFactory.kt +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/ViewFactory.kt @@ -3,6 +3,10 @@ package ai.kilocode.client.session.views import ai.kilocode.client.session.views.base.GenericView import ai.kilocode.client.session.views.base.PartView import ai.kilocode.client.session.views.question.QuestionResultView +import ai.kilocode.client.session.views.tool.GlobToolView +import ai.kilocode.client.session.views.tool.ReadToolView +import ai.kilocode.client.session.views.tool.SearchToolView +import ai.kilocode.client.session.views.tool.ToolView import ai.kilocode.client.session.ui.selection.SessionSelection import ai.kilocode.client.session.model.Compaction import ai.kilocode.client.session.model.Content @@ -25,19 +29,20 @@ object ViewFactory { fun create( content: Content, openFile: (String) -> Unit, - ): PartView = create(content, openFile, openUrl = {}, selection = null) + ): PartView = create(content, openFile, openUrl = {}, selection = null, repo = null) fun create( content: Content, openFile: (String) -> Unit, openUrl: (String) -> Unit, - ): PartView = create(content, openFile, openUrl, selection = null) + ): PartView = create(content, openFile, openUrl, selection = null, repo = null) fun create( content: Content, openFile: (String) -> Unit, openUrl: (String) -> Unit = {}, selection: SessionSelection? = null, + repo: String? = null, ): PartView = when (content) { is Text -> TextView(content, openUrl = openUrl, selection = selection) is Reasoning -> ReasoningView(content, openUrl = openUrl, selection = selection) @@ -45,6 +50,8 @@ object ViewFactory { TodoWriteView.canRender(content) -> TodoWriteView(content) PlanExitView.canRender(content) -> PlanExitView(content, openFile, selection) QuestionResultView.canRender(content) -> QuestionResultView(content, selection) + GlobToolView.canRender(content) -> GlobToolView(content, selection = selection, repo = repo) + SearchToolView.canRender(content) -> SearchToolView(content, selection = selection, repo = repo) ReadToolView.canRender(content) -> ReadToolView(content, openFile, selection = selection) else -> ToolView(content, selection = selection) } @@ -56,22 +63,23 @@ object ViewFactory { fun createUser( content: Content, openFile: (String) -> Unit, - ): PartView = createUser(content, openFile, openUrl = {}, selection = null) + ): PartView = createUser(content, openFile, openUrl = {}, selection = null, repo = null) fun createUser( content: Content, openFile: (String) -> Unit, openUrl: (String) -> Unit, - ): PartView = createUser(content, openFile, openUrl, selection = null) + ): PartView = createUser(content, openFile, openUrl, selection = null, repo = null) fun createUser( content: Content, openFile: (String) -> Unit, openUrl: (String) -> Unit = {}, selection: SessionSelection? = null, + repo: String? = null, ): PartView = when (content) { is Text -> PromptView(content, openUrl = openUrl, selection = selection) - else -> create(content, openFile, openUrl, selection) + else -> create(content, openFile, openUrl, selection, repo) } /** @@ -86,6 +94,10 @@ object ViewFactory { if (view is PlanExitView) return !PlanExitView.canRender(content) if (view !is PlanExitView && PlanExitView.canRender(content)) return true if (view is QuestionResultView) return !QuestionResultView.canRender(content) + if (view is GlobToolView) return !GlobToolView.canRender(content) || QuestionResultView.canRender(content) + if (view !is GlobToolView && GlobToolView.canRender(content)) return true + if (view is SearchToolView) return !SearchToolView.canRender(content) || QuestionResultView.canRender(content) + if (view !is SearchToolView && SearchToolView.canRender(content)) return true if (view is ReadToolView) return !ReadToolView.canRender(content) || QuestionResultView.canRender(content) if (view is ToolView && ReadToolView.canRender(content)) return true if (view is ToolView) return QuestionResultView.canRender(content) diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/base/AbstractSessionPartView.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/base/AbstractSessionPartView.kt index 52942a60677..ac93b08e834 100644 --- a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/base/AbstractSessionPartView.kt +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/base/AbstractSessionPartView.kt @@ -1,7 +1,7 @@ package ai.kilocode.client.session.views.base import ai.kilocode.client.session.ui.style.SessionUiStyle -import com.intellij.icons.AllIcons +import ai.kilocode.client.session.views.SessionViewIcons import com.intellij.ui.components.JBLabel import com.intellij.util.ui.JBUI import java.awt.BorderLayout @@ -29,7 +29,7 @@ abstract class AbstractSessionPartView( ) : this(header, { body }, expanded, expandable) protected val arrow = JBLabel() - protected val row = JPanel(BorderLayout(JBUI.scale(SessionUiStyle.View.SESSION_VIEW_GAP), 0)) + protected val row = JPanel(BorderLayout(JBUI.scale(SessionUiStyle.View.Layout.GAP), 0)) private val bound = linkedSetOf() private var body: JComponent? = null @@ -41,12 +41,12 @@ abstract class AbstractSessionPartView( } private val mouse = object : MouseAdapter() { override fun mouseEntered(e: MouseEvent) { - setHover(true) + setHovered(true) } override fun mouseExited(e: MouseEvent) { if (inside(e)) return - setHover(false) + setHovered(false) } } @@ -65,7 +65,7 @@ abstract class AbstractSessionPartView( fun toggle() { if (!expandable || !arrow.isVisible) return - val changed = if (isExpanded()) collapse() else expand() + val changed = toggleLocal() if (!changed) return syncArrow() refresh() @@ -78,7 +78,7 @@ abstract class AbstractSessionPartView( return true } - fun collapse(): Boolean { + open fun collapse(): Boolean { val item = body ?: return false if (item.parent !== this) return false remove(item) @@ -89,6 +89,15 @@ abstract class AbstractSessionPartView( protected fun bodyComponent(): JComponent = body() + private fun toggleLocal(): Boolean { + val fn = resize ?: return toggleBody() + val expanded = isExpanded() + fn(this) { toggleBody() } + return expanded != isExpanded() + } + + private fun toggleBody(): Boolean = if (isExpanded()) collapse() else expand() + fun syncExpandable(expandable: Boolean): Boolean { val active = this.expandable && expandable val changed = setVisible(arrow, active) @@ -110,13 +119,11 @@ abstract class AbstractSessionPartView( protected open fun hoverColor(value: Boolean): Color? = null - protected open fun applyHover(value: Boolean, color: Color) {} - - private fun setHover(value: Boolean) { + override fun setHovered(value: Boolean) { + hover?.invoke(this, value) val color = hoverColor(value) ?: return if (row.background?.rgb == color.rgb) return row.background = color - applyHover(value, color) row.repaint() } @@ -150,7 +157,7 @@ abstract class AbstractSessionPartView( } private fun syncArrow(): Boolean { - val icon = if (isExpanded()) AllIcons.General.ArrowDown else AllIcons.General.ArrowRight + val icon = if (isExpanded()) SessionViewIcons.chevronDown else SessionViewIcons.chevronRight if (arrow.icon === icon) return false arrow.icon = icon return true diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/base/BaseQuestionView.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/base/BaseQuestionView.kt index 5b14587de93..3a73b355a65 100644 --- a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/base/BaseQuestionView.kt +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/base/BaseQuestionView.kt @@ -41,6 +41,8 @@ import javax.swing.JPanel class BaseQuestionView( private val selection: SessionSelection? = null, ) : RoundedContentPanel( + UiStyle.Gap.pad(), + UiStyle.Gap.pad(), UiStyle.Gap.lg(), UiStyle.Gap.pad(), ), SessionEditorStyleTarget { @@ -95,6 +97,7 @@ class BaseQuestionView( private var top: JComponent? = null private var content: JComponent? = null private var actionLeft: JComponent? = null + private var gap = UiStyle.Gap.lg() // action buttons keyed by id for retained updates private val actionButtons = mutableMapOf() @@ -184,6 +187,15 @@ class BaseQuestionView( repaint() } + @RequiresEdt + fun setSpacing(top: Int, gap: Int) { + this.gap = gap + border = JBUI.Borders.empty(top, UiStyle.Gap.pad(), UiStyle.Gap.lg(), UiStyle.Gap.pad()) + syncNorth() + revalidate() + repaint() + } + /** * Configure the action buttons shown in the card's right-aligned footer. * @@ -275,9 +287,9 @@ class BaseQuestionView( // ---- contentColor override ---- - override fun contentColor(): Color = SessionUiStyle.View.surface() + override fun contentColor(): Color = SessionUiStyle.View.Surface.bgColor() - override fun outlineColor(): Color = SessionUiStyle.View.line() + override fun outlineColor(): Color = SessionUiStyle.View.Outline.brightColor() // ---- private helpers ---- @@ -285,7 +297,7 @@ class BaseQuestionView( north.removeAll() top?.let { north.next(it) } north.next(header) - if (content != null) north.fill(UiStyle.Gap.md()) + if (content != null) north.fill(gap) north.revalidate() north.repaint() } @@ -383,7 +395,7 @@ class BaseQuestionView( } private fun syncBackground() { - background = SessionUiStyle.View.surface() + background = SessionUiStyle.View.Surface.bgColor() } } btn.addActionListener { actionHandlers[id]?.invoke() } diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/base/GenericView.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/base/GenericView.kt index c0973f9d166..7f535048a70 100644 --- a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/base/GenericView.kt +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/base/GenericView.kt @@ -26,6 +26,7 @@ class GenericView private constructor( label.foreground = UiStyle.Colors.weak() applyStyle(SessionEditorStyle.current()) syncExpandable(false) + border = null } override fun update(content: Content) {} // generic content has no updatable state diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/base/PartView.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/base/PartView.kt index 41d4d57853a..b1b0256110f 100644 --- a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/base/PartView.kt +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/base/PartView.kt @@ -4,6 +4,7 @@ import ai.kilocode.client.session.model.Content import ai.kilocode.client.session.ui.style.SessionEditorStyle import ai.kilocode.client.session.ui.style.SessionEditorStyleTarget import com.intellij.openapi.Disposable +import javax.swing.JComponent import javax.swing.JPanel /** @@ -20,6 +21,10 @@ abstract class PartView : JPanel(), Disposable, SessionEditorStyleTarget { /** Stable [Content.id] this renderer was created for. */ abstract val contentId: String + var resize: ((JComponent, () -> Unit) -> Unit)? = null + + var hover: ((PartView, Boolean) -> Unit)? = null + /** * Apply a full content update — replace, not append. * Called when [ai.kilocode.client.session.model.SessionModelEvent.ContentUpdated] fires. @@ -33,6 +38,8 @@ abstract class PartView : JPanel(), Disposable, SessionEditorStyleTarget { */ open fun appendDelta(delta: String) {} + open fun setHovered(value: Boolean) {} + override fun applyStyle(style: SessionEditorStyle) {} override fun dispose() {} diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/base/PrimarySessionPartView.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/base/PrimarySessionPartView.kt index 6a4a1d89f67..d82a3e11628 100644 --- a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/base/PrimarySessionPartView.kt +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/base/PrimarySessionPartView.kt @@ -2,7 +2,6 @@ package ai.kilocode.client.session.views.base import ai.kilocode.client.session.ui.style.SessionUiStyle import com.intellij.util.ui.JBUI -import java.awt.Color import javax.swing.JComponent abstract class PrimarySessionPartView( @@ -13,20 +12,36 @@ abstract class PrimarySessionPartView( ) : AbstractSessionPartView(header, content, expanded, expandable) { init { isOpaque = true - background = SessionUiStyle.View.surface() - border = SessionUiStyle.View.sessionView() + background = SessionUiStyle.View.Surface.bgColor() row.isOpaque = true - row.background = SessionUiStyle.View.header() + row.background = SessionUiStyle.View.Surface.headerBgColor() row.border = JBUI.Borders.empty( - JBUI.scale(SessionUiStyle.View.SESSION_VIEW_VERTICAL_PADDING), - JBUI.scale(SessionUiStyle.View.SESSION_VIEW_HORIZONTAL_PADDING), + JBUI.scale(SessionUiStyle.View.Layout.VERTICAL_PADDING), + JBUI.scale(SessionUiStyle.View.Layout.HORIZONTAL_PADDING), ) + syncBorder() } - override fun hoverColor(value: Boolean) = if (value) SessionUiStyle.View.headerHover() else SessionUiStyle.View.header() + override fun expand(): Boolean { + val changed = super.expand() + if (changed) syncBorder() + return changed + } - override fun applyHover(value: Boolean, color: Color) { - border = if (value) SessionUiStyle.View.sessionView(SessionUiStyle.View.hoverLine()) else SessionUiStyle.View.sessionView() - repaint() + override fun collapse(): Boolean { + val changed = super.collapse() + if (changed) syncBorder() + return changed + } + + override fun hoverColor(value: Boolean) = + if (value) SessionUiStyle.View.Surface.headerHoverBgColor() else SessionUiStyle.View.Surface.headerBgColor() + + private fun syncBorder() { + if (isExpanded()) { + border = JBUI.Borders.customLine(SessionUiStyle.View.Outline.color(), SessionUiStyle.View.Outline.width()) + return + } + border = JBUI.Borders.empty(1) } } diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/base/SecondarySessionPartView.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/base/SecondarySessionPartView.kt index 8951a50d808..d0a0d3808e5 100644 --- a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/base/SecondarySessionPartView.kt +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/base/SecondarySessionPartView.kt @@ -19,12 +19,34 @@ abstract class SecondarySessionPartView( ) : this(header, { content }, expanded, expandable) init { row.isOpaque = true - row.background = SessionUiStyle.View.header() + row.background = SessionUiStyle.View.Surface.headerBgColor() row.border = JBUI.Borders.empty( - JBUI.scale(SessionUiStyle.View.SESSION_VIEW_VERTICAL_PADDING), - JBUI.scale(SessionUiStyle.View.SESSION_VIEW_HORIZONTAL_PADDING), + JBUI.scale(SessionUiStyle.View.Layout.VERTICAL_PADDING), + JBUI.scale(SessionUiStyle.View.Layout.HORIZONTAL_PADDING), ) + syncBorder() } - override fun hoverColor(value: Boolean) = if (value) SessionUiStyle.View.headerHover() else SessionUiStyle.View.header() + override fun expand(): Boolean { + val changed = super.expand() + if (changed) syncBorder() + return changed + } + + override fun collapse(): Boolean { + val changed = super.collapse() + if (changed) syncBorder() + return changed + } + + override fun hoverColor(value: Boolean) = + if (value) SessionUiStyle.View.Surface.headerHoverBgColor() else SessionUiStyle.View.Surface.headerBgColor() + + private fun syncBorder() { + if (isExpanded()) { + border = JBUI.Borders.customLine(SessionUiStyle.View.Outline.color(), SessionUiStyle.View.Outline.width()) + return + } + border = JBUI.Borders.empty(1) + } } diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/permission/PermissionView.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/permission/PermissionView.kt index d6584f0f0ba..e8f52e97dec 100644 --- a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/permission/PermissionView.kt +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/permission/PermissionView.kt @@ -10,14 +10,13 @@ import ai.kilocode.client.session.ui.selection.SessionSelection import ai.kilocode.client.session.ui.style.SessionEditorStyle import ai.kilocode.client.session.ui.style.SessionEditorStyleTarget import ai.kilocode.client.session.ui.style.SessionUiStyle -import ai.kilocode.client.session.ui.style.SessionUiStyle.View.SESSION_VIEW_GAP +import ai.kilocode.client.session.views.SessionViewIcons import ai.kilocode.client.ui.UiStyle import ai.kilocode.client.ui.layout.HAlign import ai.kilocode.client.ui.layout.Stack import ai.kilocode.client.ui.layout.VAlign import ai.kilocode.client.ui.layout.align import ai.kilocode.rpc.dto.PermissionReplyDto -import com.intellij.icons.AllIcons import com.intellij.openapi.Disposable import com.intellij.openapi.util.Disposer import com.intellij.ui.ColorUtil @@ -68,7 +67,7 @@ class PermissionView( isOpaque = false isVisible = false - card.setHeaderIcon(AllIcons.General.Warning, KiloBundle.message("session.permission.title")) + card.setHeaderIcon(SessionViewIcons.warning, KiloBundle.message("session.permission.title")) card.setContent(body) card.setActions(listOf( BaseQuestionView.Action(ID_DENY, KiloBundle.message("session.permission.deny"), primary = false) { decide("reject") }, @@ -128,7 +127,7 @@ class PermissionView( /** Adds a three-column permission detail row: tool, target, and changes. */ private fun addDetailRow(action: String, target: String?, diffs: List) { - val row = JPanel(BorderLayout(SESSION_VIEW_GAP, 0)).apply { + val row = JPanel(BorderLayout(SessionUiStyle.View.Layout.GAP, 0)).apply { isOpaque = false } @@ -174,7 +173,7 @@ class PermissionView( private fun applyTargetPane(pane: JBHtmlPane) { pane.font = style.transcriptFont pane.foreground = style.editorForeground - pane.background = SessionUiStyle.View.headerHover() + pane.background = SessionUiStyle.View.Surface.headerHoverBgColor() pane.reloadCssStylesheets() } @@ -182,7 +181,7 @@ class PermissionView( val sheet = StyleSheet() val font = style.transcriptFont val fg = ColorUtil.toHtmlColor(style.editorForeground) - val bg = ColorUtil.toHtmlColor(SessionUiStyle.View.headerHover()) + val bg = ColorUtil.toHtmlColor(SessionUiStyle.View.Surface.headerHoverBgColor()) val family = font.name.replace("\\", "\\\\").replace("'", "\\'") sheet.addRule("body { margin: 0; padding: 0 ${UiStyle.Gap.xs()}px; color: $fg; background: $bg; font-family: '$family', monospace; font-size: ${font.size}pt }") sheet.addRule("pre { margin: 0; white-space: pre-wrap; font-family: '$family', monospace; font-size: ${font.size}pt }") diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/question/QuestionResultView.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/question/QuestionResultView.kt index 6672c9cf647..f1c241141f8 100644 --- a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/question/QuestionResultView.kt +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/question/QuestionResultView.kt @@ -6,10 +6,10 @@ import ai.kilocode.client.session.model.Tool import ai.kilocode.client.session.ui.selection.SessionSelection import ai.kilocode.client.session.ui.style.SessionEditorStyle import ai.kilocode.client.session.ui.style.SessionUiStyle +import ai.kilocode.client.session.views.SessionViewIcons import ai.kilocode.client.session.views.base.PartView -import ai.kilocode.client.session.views.ToolView +import ai.kilocode.client.session.views.tool.ToolView import ai.kilocode.client.ui.UiStyle -import com.intellij.icons.AllIcons import com.intellij.openapi.Disposable import com.intellij.openapi.util.Disposer import com.intellij.ui.components.JBLabel @@ -41,26 +41,26 @@ class QuestionResultView(tool: Tool, private val selection: SessionSelection? = override fun updateUI() { super.updateUI() isOpaque = true - background = SessionUiStyle.View.surface() - border = SessionUiStyle.View.sessionView() + background = SessionUiStyle.View.Surface.bgColor() + border = JBUI.Borders.empty(1) } } - private val header = object : JPanel(BorderLayout(JBUI.scale(SessionUiStyle.View.SESSION_VIEW_GAP), 0)) { + private val header = object : JPanel(BorderLayout(JBUI.scale(SessionUiStyle.View.Layout.GAP), 0)) { override fun updateUI() { super.updateUI() isOpaque = true - background = SessionUiStyle.View.header() + background = SessionUiStyle.View.Surface.headerBgColor() border = JBUI.Borders.empty( - JBUI.scale(SessionUiStyle.View.SESSION_VIEW_VERTICAL_PADDING), - JBUI.scale(SessionUiStyle.View.SESSION_VIEW_HORIZONTAL_PADDING), + JBUI.scale(SessionUiStyle.View.Layout.VERTICAL_PADDING), + JBUI.scale(SessionUiStyle.View.Layout.HORIZONTAL_PADDING), ) } } - private val glyph = JBLabel(AllIcons.General.Balloon) + private val glyph = JBLabel(SessionViewIcons.bubble) private val title = JBLabel() private val sub = JBLabel().apply { foreground = UiStyle.Colors.weak() } private val arrow = JBLabel() - private val center = JPanel(BorderLayout(JBUI.scale(SessionUiStyle.View.SESSION_VIEW_GAP), 0)).apply { + private val center = JPanel(BorderLayout(JBUI.scale(SessionUiStyle.View.Layout.GAP), 0)).apply { isOpaque = false } private var pane: JPanel? = null @@ -70,10 +70,10 @@ class QuestionResultView(tool: Tool, private val selection: SessionSelection? = } private val mouse = object : MouseAdapter() { - override fun mouseEntered(e: MouseEvent) { setHover(true) } + override fun mouseEntered(e: MouseEvent) { setHovered(true) } override fun mouseExited(e: MouseEvent) { if (inside(e)) return - setHover(false) + setHovered(false) } } @@ -99,6 +99,7 @@ class QuestionResultView(tool: Tool, private val selection: SessionSelection? = add(root, BorderLayout.CENTER) syncLabels() syncArrow() + syncBorder() } override fun update(content: Content) { @@ -122,13 +123,18 @@ class QuestionResultView(tool: Tool, private val selection: SessionSelection? = } fun toggle() { + resize?.invoke(this) { toggleBody() } ?: toggleBody() + syncArrow() + refresh() + } + + private fun toggleBody() { if (isExpanded()) { pane?.let { root.remove(it) } } else { root.add(body(), BorderLayout.CENTER) } - syncArrow() - refresh() + syncBorder() } fun isExpanded(): Boolean = pane?.parent === root @@ -164,10 +170,19 @@ class QuestionResultView(tool: Tool, private val selection: SessionSelection? = override fun updateUI() { super.updateUI() isOpaque = true - background = SessionUiStyle.View.surface() - border = JBUI.Borders.empty( - JBUI.scale(SessionUiStyle.View.SESSION_VIEW_VERTICAL_PADDING), - JBUI.scale(SessionUiStyle.View.SESSION_VIEW_HORIZONTAL_PADDING), + background = SessionUiStyle.View.Surface.bgColor() + border = JBUI.Borders.compound( + JBUI.Borders.customLine( + SessionUiStyle.View.Outline.brightColor(), + SessionUiStyle.View.Outline.width(), + 0, + 0, + 0, + ), + JBUI.Borders.empty( + JBUI.scale(SessionUiStyle.View.Layout.VERTICAL_PADDING), + JBUI.scale(SessionUiStyle.View.Layout.HORIZONTAL_PADDING), + ), ) } }.apply { @@ -270,16 +285,28 @@ class QuestionResultView(tool: Tool, private val selection: SessionSelection? = } private fun syncArrow() { - arrow.icon = if (isExpanded()) AllIcons.General.ArrowDown else AllIcons.General.ArrowRight + arrow.icon = if (isExpanded()) SessionViewIcons.chevronDown else SessionViewIcons.chevronRight } - private fun setHover(value: Boolean) { - val color = if (value) SessionUiStyle.View.headerHover() else SessionUiStyle.View.header() - if (header.background?.rgb == color.rgb) return - header.background = color - root.border = if (value) SessionUiStyle.View.sessionView(SessionUiStyle.View.hoverLine()) else SessionUiStyle.View.sessionView() - header.repaint() - root.repaint() + override fun setHovered(value: Boolean) { + hover?.invoke(this, value) + val color = + if (value) SessionUiStyle.View.Surface.headerHoverBgColor() else SessionUiStyle.View.Surface.headerBgColor() + if (header.background?.rgb != color.rgb) { + header.background = color + header.repaint() + } + } + + private fun syncBorder() { + if (isExpanded()) { + root.border = JBUI.Borders.customLine( + SessionUiStyle.View.Outline.brightColor(), + SessionUiStyle.View.Outline.width(), + ) + return + } + root.border = JBUI.Borders.empty(1) } private fun inside(e: MouseEvent): Boolean { diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/question/QuestionView.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/question/QuestionView.kt index b924a78b30f..42c61bdb25d 100644 --- a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/question/QuestionView.kt +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/question/QuestionView.kt @@ -6,6 +6,7 @@ import ai.kilocode.client.session.model.QuestionItem import ai.kilocode.client.session.model.QuestionOption import ai.kilocode.client.session.ui.SessionView import ai.kilocode.client.session.ui.editor.SessionEditorTextField +import ai.kilocode.client.session.views.SessionViewIcons import ai.kilocode.client.session.views.base.BaseQuestionView import ai.kilocode.client.session.ui.selection.SessionSelection import ai.kilocode.client.session.ui.style.SessionEditorStyle @@ -13,7 +14,6 @@ import ai.kilocode.client.session.ui.style.SessionEditorStyleTarget import ai.kilocode.client.ui.HoverIcon import ai.kilocode.client.ui.UiStyle import ai.kilocode.rpc.dto.QuestionReplyDto -import com.intellij.icons.AllIcons import com.intellij.openapi.Disposable import com.intellij.openapi.editor.EditorFactory import com.intellij.openapi.project.Project @@ -79,14 +79,14 @@ class QuestionView( layout = BoxLayout(this, BoxLayout.X_AXIS) } private val back = HoverIcon().apply { - val ico = AllIcons.Actions.Back + val ico = SessionViewIcons.chevronLeft icon = ico disabledIcon = IconLoader.getDisabledIcon(ico) toolTipText = KiloBundle.message("session.question.back") addActionListener { goBack() } } private val fwd = HoverIcon().apply { - val ico = AllIcons.Actions.Forward + val ico = SessionViewIcons.chevronRight icon = ico disabledIcon = IconLoader.getDisabledIcon(ico) toolTipText = KiloBundle.message("session.question.next") @@ -94,7 +94,7 @@ class QuestionView( } private val topPanel = JPanel(BorderLayout()).apply { isOpaque = false - border = JBUI.Borders.emptyBottom(UiStyle.Gap.lg()) + border = JBUI.Borders.empty() alignmentX = Component.LEFT_ALIGNMENT } private val body = JPanel().apply { @@ -207,6 +207,12 @@ class QuestionView( summary.isVisible = total > 1 nav.isVisible = total > 1 topPanel.isVisible = total > 1 + if (total > 1) { + topPanel.border = JBUI.Borders.empty(0, 0, UiStyle.Gap.sm(), 0) + card.setSpacing(UiStyle.Gap.sm(), UiStyle.Gap.pad()) + return + } + card.setSpacing(UiStyle.Gap.xl(), UiStyle.Gap.pad()) } @RequiresEdt diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/todo/TodoWriteView.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/todo/TodoWriteView.kt index 7dc9cb8a400..a2dcc25d158 100644 --- a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/todo/TodoWriteView.kt +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/todo/TodoWriteView.kt @@ -6,9 +6,9 @@ import ai.kilocode.client.session.model.Tool import ai.kilocode.client.session.model.ToolExecState import ai.kilocode.client.session.ui.style.SessionEditorStyle import ai.kilocode.client.session.ui.style.SessionUiStyle +import ai.kilocode.client.session.views.SessionViewIcons import ai.kilocode.client.session.views.base.PrimarySessionPartView import ai.kilocode.client.ui.UiStyle -import com.intellij.icons.AllIcons import com.intellij.ui.components.JBLabel import com.intellij.util.ui.JBUI import java.awt.BorderLayout @@ -28,7 +28,13 @@ class TodoWriteView(tool: Tool, private val parts: TodoParts = todoParts()) : init { bindHeader(parts.glyph, parts.title, parts.sub, parts.center, parts.controls) parts.list.border = JBUI.Borders.compound( - SessionUiStyle.View.topOutline(), + JBUI.Borders.customLine( + SessionUiStyle.View.Outline.color(), + SessionUiStyle.View.Outline.width(), + 0, + 0, + 0, + ), JBUI.Borders.empty(UiStyle.Gap.sm(), UiStyle.Gap.md()), ) applyStyle(style) @@ -92,16 +98,16 @@ class TodoParts( ) private fun todoParts(): TodoParts { - val glyph = JBLabel(AllIcons.Actions.Checked) + val glyph = JBLabel(SessionViewIcons.checklist) val title = JBLabel(KiloBundle.message("session.part.todo.title")) val sub = JBLabel().apply { foreground = UiStyle.Colors.weak() } - val center = JPanel(BorderLayout(JBUI.scale(SessionUiStyle.View.SESSION_VIEW_GAP), 0)).apply { + val center = JPanel(BorderLayout(JBUI.scale(SessionUiStyle.View.Layout.GAP), 0)).apply { isOpaque = false add(title, BorderLayout.WEST) add(sub, BorderLayout.CENTER) } val controls = Box.createHorizontalBox() - val header = JPanel(BorderLayout(JBUI.scale(SessionUiStyle.View.SESSION_VIEW_GAP), 0)).apply { + val header = JPanel(BorderLayout(JBUI.scale(SessionUiStyle.View.Layout.GAP), 0)).apply { isOpaque = false add(glyph, BorderLayout.WEST) add(center, BorderLayout.CENTER) diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/tool/BaseSearchToolView.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/tool/BaseSearchToolView.kt new file mode 100644 index 00000000000..24d36cff643 --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/tool/BaseSearchToolView.kt @@ -0,0 +1,188 @@ +package ai.kilocode.client.session.views.tool + +import ai.kilocode.client.session.model.Content +import ai.kilocode.client.session.model.Tool +import ai.kilocode.client.session.model.ToolExecState +import ai.kilocode.client.session.ui.selection.SessionSelection +import ai.kilocode.client.session.ui.style.SessionEditorStyle +import ai.kilocode.client.session.ui.style.SessionUiStyle +import ai.kilocode.client.session.views.base.SecondarySessionPartView +import ai.kilocode.client.ui.UiStyle +import com.intellij.openapi.util.Disposer +import com.intellij.util.concurrency.annotations.RequiresEdt +import com.intellij.util.ui.JBUI +import java.awt.Dimension +import javax.swing.Icon + +abstract class BaseSearchToolView( + tool: Tool, + private val selection: SessionSelection? = null, + private val parts: ToolParts, + private val repo: String? = null, +) : SecondarySessionPartView(parts.header, { parts.scroll(tool) }) { + + override val contentId: String = tool.id + + protected var item = tool + private var style = SessionEditorStyle.current() + private var registered = false + private var disposed = false + + protected abstract fun toolIcon(tool: Tool): Icon + protected abstract fun toolTitle(tool: Tool): String + protected abstract fun targets(tool: Tool, repo: String?): List + protected abstract fun viewName(): String + + init { + bindHeader(parts.glyph, parts.title, parts.sub, parts.state, parts.center, parts.controls, parts.slot) + parts.targets.forEach { bindHeader(it) } + applyStyle(style) + sync() + } + + @RequiresEdt + override fun expand(): Boolean { + val changed = super.expand() + if (!changed) return false + syncBody() + applyBodyStyle() + return true + } + + @RequiresEdt + override fun getPreferredSize(): Dimension { + val size = super.getPreferredSize() + if (!bodyVisible()) return size + val height = row.preferredSize.height + bodyMaxHeight() + return Dimension(size.width, minOf(size.height, height)) + } + + @RequiresEdt + override fun update(content: Content) { + if (content !is Tool) return + item = content + var changed = sync() + changed = syncBody() || changed + if (changed) refresh() + } + + @RequiresEdt + fun labelText(): String = listOf(parts.title.text).plus(targetTexts()).plus(parts.state.text) + .filter { it.isNotBlank() } + .joinToString(" ") + + @RequiresEdt + fun bodyText(): String = body(item) + @RequiresEdt + internal fun targetTexts(): List = parts.targets.map { it.text }.filter { it.isNotBlank() } + @RequiresEdt + internal fun targetVisible(index: Int): Boolean = parts.targets.getOrNull(index)?.isVisible ?: false + @RequiresEdt + internal fun bodyVisible() = parts.scroll?.parent === this + @RequiresEdt + internal fun hasToggle() = arrow.isVisible + @RequiresEdt + internal fun bodyFont() = parts.content?.font ?: style.editorFont + @RequiresEdt + internal fun titleFont() = parts.title.font + @RequiresEdt + internal fun targetFont(index: Int) = parts.targets.getOrNull(index)?.font ?: style.regularFont + @RequiresEdt + internal fun stateFont() = parts.state.font + @RequiresEdt + internal fun bodyCreated() = parts.bodyCreated() + @RequiresEdt + internal fun scrollComponent() = parts.scroll + @RequiresEdt + internal fun bodyEditor() = parts.content?.editor + @RequiresEdt + internal fun horizontalPolicy() = parts.scroll?.horizontalScrollBarPolicy + @RequiresEdt + internal fun verticalPolicy() = parts.scroll?.verticalScrollBarPolicy + @RequiresEdt + internal fun bodyWrap() = parts.content?.lineWrap ?: false + @RequiresEdt + internal fun headerComponent() = parts.header + @RequiresEdt + internal fun centerComponent() = parts.center + @RequiresEdt + internal fun targetComponents() = parts.targets + + @RequiresEdt + override fun applyStyle(style: SessionEditorStyle) { + this.style = style + var changed = false + changed = setFont(parts.title, style.boldEditorFont) || changed + changed = setFont(parts.sub, style.smallEditorFont) || changed + parts.targets.forEach { changed = setFont(it, style.regularFont) || changed } + changed = setFont(parts.state, style.smallEditorFont) || changed + changed = applyBodyStyle() || changed + if (changed) refresh() + } + + private fun sync(): Boolean { + val expand = canExpand(item) + var changed = false + changed = syncExpandable(expand) || changed + changed = setVisible(parts.state, item.state != ToolExecState.COMPLETED) || changed + changed = setIcon(parts.glyph, toolIcon(item)) || changed + changed = setForeground(parts.glyph, color(item)) || changed + changed = setText(parts.title, toolTitle(item)) || changed + changed = setForeground(parts.title, titleColor(item)) || changed + changed = setForeground(parts.sub, UiStyle.Colors.weak()) || changed + changed = syncTargets() || changed + changed = setText(parts.state, stateText(item)) || changed + changed = setForeground(parts.state, color(item)) || changed + val body = parts.content + if (body != null && body.foreground != bodyColor()) { + body.foreground = bodyColor() + changed = true + } + return changed + } + + private fun syncTargets(): Boolean { + val values = targets(item, repo) + var changed = false + parts.targets.forEachIndexed { index, label -> + val text = values.getOrNull(index) ?: "" + changed = setVisible(label, text.isNotBlank()) || changed + changed = setTargetText(label, text) || changed + changed = setForeground(label, UiStyle.Colors.fg()) || changed + } + return changed + } + + private fun syncBody(): Boolean { + val body = parts.content ?: return false + val value = plainBody(item) + if (body.text != value) { + body.text = value + return true + } + return false + } + + private fun applyBodyStyle(): Boolean { + val body = parts.content ?: return false + if (!disposed) { + Disposer.register(this, body) + disposed = true + } + if (!registered && selection != null && parts.scroll?.parent != null) { + registered = true + body.register(selection, this) + } + return body.applyStyle(style) + } + + private fun bodyColor() = if (item.state == ToolExecState.ERROR) UiStyle.Colors.errorLabelForeground() else UiStyle.Colors.fg() + + private fun bodyMaxHeight(): Int { + val body = parts.content ?: return 0 + return body.lineHeight() * SessionUiStyle.View.Tool.BODY_LINES + + JBUI.scale(SessionUiStyle.View.Layout.BODY_EXTRA_HEIGHT) + } + + override fun dumpLabel() = "${viewName()}#$contentId(${labelText()})" +} diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/tool/GlobToolView.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/tool/GlobToolView.kt new file mode 100644 index 00000000000..ccb204da04f --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/tool/GlobToolView.kt @@ -0,0 +1,23 @@ +package ai.kilocode.client.session.views.tool + +import ai.kilocode.client.plugin.KiloBundle +import ai.kilocode.client.session.model.Tool +import ai.kilocode.client.session.ui.selection.SessionSelection + +/** Renders glob calls with a stacked, collapsible search-result header. */ +class GlobToolView( + tool: Tool, + selection: SessionSelection? = null, + parts: ToolParts = searchParts(2), + repo: String? = null, +) : BaseSearchToolView(tool, selection, parts, repo) { + + companion object { + fun canRender(tool: Tool): Boolean = tool.name == "glob" + } + + override fun toolIcon(tool: Tool) = icon(tool) + override fun toolTitle(tool: Tool) = KiloBundle.message("session.part.tool.glob") + override fun targets(tool: Tool, repo: String?) = listOf(globDirectory(tool, repo), globPattern(tool)).filter { it.isNotBlank() } + override fun viewName() = "GlobToolView" +} diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/tool/ReadToolView.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/tool/ReadToolView.kt new file mode 100644 index 00000000000..d2c2a623ead --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/tool/ReadToolView.kt @@ -0,0 +1,170 @@ +package ai.kilocode.client.session.views.tool + +import ai.kilocode.client.session.model.Content +import ai.kilocode.client.session.model.Tool +import ai.kilocode.client.session.model.ToolExecState +import ai.kilocode.client.session.model.ToolKind +import ai.kilocode.client.session.ui.selection.SessionSelection +import ai.kilocode.client.session.ui.style.SessionEditorStyle +import ai.kilocode.client.session.ui.style.SessionUiStyle +import ai.kilocode.client.session.views.base.SecondarySessionPartView +import ai.kilocode.client.ui.UiStyle +import com.intellij.util.concurrency.annotations.RequiresEdt +import com.intellij.util.ui.JBUI +import java.awt.Dimension +import javax.swing.ScrollPaneConstants + +/** Renders read calls with secondary, borderless chrome. */ +class ReadToolView( + tool: Tool, + openFile: (String) -> Unit = {}, + private val selection: SessionSelection? = null, + private val parts: ToolParts = toolParts(tool, openFile), +) : SecondarySessionPartView(parts.header, parts.scroll(tool), expandable = false) { + + companion object { + fun canRender(tool: Tool): Boolean = tool.kind == ToolKind.READ + } + + override val contentId: String = tool.id + + private var item = tool + private var style = SessionEditorStyle.current() + + init { + parts.text?.let { selection?.register(it, this) } + bindHeader(parts.glyph, parts.title, parts.sub, parts.state, parts.center, parts.controls, parts.slot) + parts.text?.text = preview(item) + applyStyle(style) + sync() + } + + @RequiresEdt + override fun getPreferredSize(): Dimension { + val size = super.getPreferredSize() + if (!bodyVisible()) return size + val height = row.preferredSize.height + bodyMaxHeight() + return Dimension(size.width, minOf(size.height, height)) + } + + @RequiresEdt + override fun update(content: Content) { + if (content !is Tool) return + item = content + var changed = sync() + changed = syncBody() || changed + if (changed) refresh() + } + + @RequiresEdt + fun labelText(): String = listOf(parts.title.text, subtitleText(parts), parts.state.text) + .filter { it.isNotBlank() } + .joinToString(" ") + @RequiresEdt + fun bodyText(): String = body(item) + @RequiresEdt + internal fun bodyVisible() = parts.scroll?.parent === this + @RequiresEdt + internal fun hasToggle() = arrow.isVisible + @RequiresEdt + internal fun horizontalPolicy() = parts.scroll?.horizontalScrollBarPolicy ?: ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER + @RequiresEdt + internal fun bodyMaxRows() = SessionUiStyle.View.Tool.BODY_LINES + @RequiresEdt + internal fun bodyFont() = parts.text?.font ?: style.transcriptFont + @RequiresEdt + internal fun bodyCreated() = parts.bodyCreated() + @RequiresEdt + internal fun bodyWrap() = parts.text?.lineWrap ?: false + @RequiresEdt + internal fun bodyEditor() = parts.content?.editor + @RequiresEdt + internal fun linkVisible() = parts.link.isVisible + @RequiresEdt + internal fun linkText() = parts.label + @RequiresEdt + internal fun linkMarkup() = parts.link.text ?: "" + @RequiresEdt + internal fun linkForeground() = parts.link.foreground + @RequiresEdt + internal fun linkFont() = parts.link.font + @RequiresEdt + internal fun subtitleForeground() = parts.sub.foreground + @RequiresEdt + internal fun subtitleFont() = parts.sub.font + @RequiresEdt + internal fun linkHref() = parts.href + @RequiresEdt + internal fun openLink() = parts.openLink() + + @RequiresEdt + override fun applyStyle(style: SessionEditorStyle) { + this.style = style + var changed = false + changed = setFont(parts.title, style.boldEditorFont) || changed + changed = setFont(parts.sub, style.transcriptFont) || changed + changed = setFont(parts.link, style.transcriptFont) || changed + changed = setFont(parts.state, style.smallEditorFont) || changed + parts.text?.let { changed = setFont(it, style.transcriptFont) || changed } + if (changed) refresh() + } + + private fun sync(): Boolean { + var changed = false + changed = syncExpandable(false) || changed + changed = setVisible(parts.state, true) || changed + changed = setIcon(parts.glyph, icon(item)) || changed + changed = setForeground(parts.glyph, color(item)) || changed + changed = setText(parts.title, title(item)) || changed + changed = syncSubtitle() || changed + changed = setForeground(parts.title, titleColor(item)) || changed + changed = setForeground(parts.sub, UiStyle.Colors.fg()) || changed + changed = setForeground(parts.link, UiStyle.Colors.fg()) || changed + changed = setText(parts.state, stateText(item)) || changed + changed = setForeground(parts.state, color(item)) || changed + parts.text?.let { changed = setForeground(it, bodyColor()) || changed } + return changed + } + + private fun syncSubtitle(): Boolean { + val target = target(item)?.takeIf { it.type == "file" } + if (target != null) { + var changed = false + if (parts.href != target.path) { + parts.href = target.path + changed = true + } + changed = setLinkText(parts, tail(target.path).ifBlank { target.path }) || changed + changed = show(parts, true) || changed + return changed + } + + var changed = false + if (parts.href != null) { + parts.href = null + changed = true + } + changed = setText(parts.sub, subtitle(item)) || changed + changed = show(parts, false) || changed + return changed + } + + private fun syncBody(): Boolean { + val value = preview(item) + val text = parts.text ?: return false + if (text.text == value) return false + text.text = value + text.caretPosition = 0 + return true + } + + private fun bodyColor() = if (item.state == ToolExecState.ERROR) UiStyle.Colors.errorLabelForeground() else UiStyle.Colors.fg() + + private fun bodyMaxHeight(): Int { + val text = parts.text ?: return 0 + return text.getFontMetrics(text.font).height * bodyMaxRows() + + JBUI.scale(SessionUiStyle.View.Layout.BODY_EXTRA_HEIGHT) + } + + override fun dumpLabel() = "ReadToolView#$contentId(${labelText()})" +} diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/tool/SearchToolView.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/tool/SearchToolView.kt new file mode 100644 index 00000000000..83084495e6b --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/tool/SearchToolView.kt @@ -0,0 +1,24 @@ +package ai.kilocode.client.session.views.tool + +import ai.kilocode.client.plugin.KiloBundle +import ai.kilocode.client.session.model.Tool +import ai.kilocode.client.session.ui.selection.SessionSelection +import ai.kilocode.client.session.views.SessionViewIcons + +/** Renders grep/content-search calls with stacked, clipped search targets. */ +class SearchToolView( + tool: Tool, + selection: SessionSelection? = null, + parts: ToolParts = searchParts(3), + repo: String? = null, +) : BaseSearchToolView(tool, selection, parts, repo) { + + companion object { + fun canRender(tool: Tool): Boolean = tool.name == "grep" + } + + override fun toolIcon(tool: Tool) = SessionViewIcons.search + override fun toolTitle(tool: Tool) = KiloBundle.message("session.part.tool.search") + override fun targets(tool: Tool, repo: String?) = searchTargets(tool, repo) + override fun viewName() = "SearchToolView" +} diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/tool/ToolSupport.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/tool/ToolSupport.kt new file mode 100644 index 00000000000..81744bfb98b --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/tool/ToolSupport.kt @@ -0,0 +1,680 @@ +@file:Suppress("TooManyFunctions") + +package ai.kilocode.client.session.views.tool + +import ai.kilocode.client.plugin.KiloBundle +import ai.kilocode.client.session.model.Tool +import ai.kilocode.client.session.model.ToolExecState +import ai.kilocode.client.session.ui.selection.SessionSelection +import ai.kilocode.client.session.ui.style.SessionEditorStyle +import ai.kilocode.client.session.ui.style.SessionUiStyle +import ai.kilocode.client.session.views.SessionViewIcons +import ai.kilocode.client.ui.UiStyle +import ai.kilocode.client.ui.layout.HAlign +import ai.kilocode.client.ui.layout.Stack +import ai.kilocode.client.ui.layout.VAlign +import ai.kilocode.client.ui.layout.align +import ai.kilocode.log.KiloLog +import com.intellij.openapi.Disposable +import com.intellij.openapi.editor.EditorFactory +import com.intellij.openapi.fileTypes.PlainTextFileType +import com.intellij.openapi.project.ProjectManager +import com.intellij.openapi.util.Disposer +import com.intellij.openapi.util.io.FileUtil +import com.intellij.openapi.util.io.OSAgnosticPathUtil +import com.intellij.ui.EditorTextField +import com.intellij.ui.components.JBLabel +import com.intellij.ui.components.JBScrollPane +import com.intellij.ui.components.JBTextArea +import com.intellij.util.concurrency.annotations.RequiresEdt +import com.intellij.util.ui.JBDimension +import com.intellij.util.ui.JBUI +import com.intellij.xml.util.XmlStringUtil +import java.awt.BorderLayout +import java.awt.CardLayout +import java.awt.Color +import java.awt.Cursor +import java.awt.Font +import java.awt.event.MouseAdapter +import java.awt.event.MouseEvent +import javax.swing.Icon +import javax.swing.JComponent +import javax.swing.JPanel +import javax.swing.ScrollPaneConstants + +private val LOG = KiloLog.create(ToolParts::class.java) + +enum class ToolBodyMode { EDITOR, TEXT } + +class ToolParts( + val header: JPanel, + val glyph: JBLabel, + val title: JBLabel, + val sub: JBLabel, + val link: JBLabel, + val slot: JPanel, + val state: JBLabel, + val center: JPanel, + val controls: JComponent, + private val open: ((String) -> Unit)? = null, + val extra: JBLabel? = null, + val targets: List = emptyList(), + private val mode: ToolBodyMode = ToolBodyMode.EDITOR, +) { + var href: String? = null + var label: String = "" + private var body: ToolBody? = null + + val text: JBTextArea? + @RequiresEdt + get() = body?.area + + val content: ToolBody? + @RequiresEdt + get() = body + + val scroll: JBScrollPane? + @RequiresEdt + get() = body?.scroll + + @RequiresEdt + fun scroll(tool: Tool): JBScrollPane = body(tool).scroll + + @RequiresEdt + fun bodyCreated() = body != null + + @RequiresEdt + fun openLink() { + val value = href ?: return + open?.invoke(value) + } + + @RequiresEdt + private fun body(tool: Tool): ToolBody { + val item = body + if (item != null) return item + val body = when (mode) { + ToolBodyMode.EDITOR -> ToolBody.editor(tool) + ToolBodyMode.TEXT -> ToolBody.text(tool) + } + return body.also { this.body = it } + } +} + +class ToolBody private constructor( + val area: JBTextArea?, + val ed: EditorTextField?, + val scroll: JBScrollPane, + private val disposable: Disposable?, +) : Disposable { + var text: String + @RequiresEdt + get() = area?.text ?: ed?.text ?: "" + @RequiresEdt + set(value) { + if (text == value) return + area?.text = value + ed?.text = value + caretStart() + size() + } + + var font: Font + @RequiresEdt + get() = area?.font ?: ed?.font ?: SessionEditorStyle.current().editorFont + @RequiresEdt + set(value) { + area?.font = value + ed?.font = value + size() + } + + var foreground: Color + @RequiresEdt + get() = area?.foreground ?: ed?.foreground ?: UiStyle.Colors.fg() + @RequiresEdt + set(value) { + area?.foreground = value + ed?.foreground = value + } + + val editable: Boolean get() = area?.isEditable ?: false + val caretVisible: Boolean get() = area?.caret?.isVisible ?: false + val lineWrap: Boolean get() = area?.lineWrap ?: false + val editor: EditorTextField? get() = ed + + @RequiresEdt + fun caretStart() { + area?.caretPosition = 0 + ed?.getEditor(false)?.caretModel?.moveToOffset(0) + } + + @RequiresEdt + fun applyStyle(style: SessionEditorStyle): Boolean { + val before = font + area?.font = style.transcriptFont + ed?.font = style.editorFont + ed?.getEditor(false)?.let(style::applyToEditor) + size() + return before != font + } + + @RequiresEdt + fun register(selection: SessionSelection, parent: Disposable) { + val field = ed + if (field != null) { + selection.register(field, parent) + return + } + area?.let { selection.register(it, parent) } + } + + @RequiresEdt + fun lineHeight(): Int = ed?.getEditor(false)?.lineHeight ?: scroll.viewport.view.getFontMetrics(font).height + + override fun dispose() { + disposable?.let(Disposer::dispose) + } + + private fun size() { + val view = scroll.viewport.view as? JComponent ?: return + val height = height(view) + val width = width(view) + view.preferredSize = JBUI.size(width, height) + view.minimumSize = JBUI.size(0, height) + view.maximumSize = JBDimension(Int.MAX_VALUE, height) + val inset = scroll.viewportBorder?.getBorderInsets(scroll) ?: JBUI.emptyInsets() + val pane = height + scroll.insets.top + scroll.insets.bottom + inset.top + inset.bottom + + scroll.horizontalScrollBar.preferredSize.height + scroll.preferredSize = JBUI.size(0, pane) + scroll.minimumSize = JBUI.size(0, pane) + scroll.maximumSize = JBDimension(Int.MAX_VALUE, pane) + } + + private fun width(view: JComponent): Int { + val metrics = view.getFontMetrics(font) + return (text.lineSequence().maxOfOrNull { metrics.stringWidth(it) } ?: 0) + + JBUI.scale(SessionUiStyle.View.Code.WIDTH_PADDING) + } + + private fun height(view: JComponent): Int { + ed?.ensureWillComputePreferredSize() + val rows = text.lineSequence().count().coerceAtLeast(SessionUiStyle.View.Code.MIN_ROWS) + return maxOf(view.preferredSize.height, lineHeight() * rows) + } + + companion object { + @RequiresEdt + fun editor(tool: Tool): ToolBody { + val disposable = Disposer.newDisposable("Tool body") + val body = runCatching { + val field = ToolField(preview(tool), SessionEditorStyle.current()).also { ed -> + ed.setDisposedWith(disposable) + Disposer.register(disposable) { + ed.getEditor(false)?.let(EditorFactory.getInstance()::releaseEditor) + } + } + ToolBody(null, field, pane(field, true), disposable) + }.getOrElse { err -> + LOG.warn("kind=tool codeEditor=true failed message=${err.message}", err) + val area = area(tool, false) + ToolBody(area, null, pane(area, true), disposable) + } + body.size() + return body + } + + @RequiresEdt + fun text(tool: Tool): ToolBody { + val area = area(tool, true) + val body = ToolBody(area, null, pane(area, false), null) + body.size() + return body + } + + private fun area(tool: Tool, wrap: Boolean) = JBTextArea().apply { + isEditable = false + caret.isVisible = false + caret.isSelectionVisible = true + lineWrap = wrap + wrapStyleWord = wrap + foreground = if (tool.state == ToolExecState.ERROR) UiStyle.Colors.errorLabelForeground() else UiStyle.Colors.fg() + background = SessionUiStyle.View.Surface.bgColor() + border = JBUI.Borders.empty( + JBUI.scale(SessionUiStyle.View.Layout.VERTICAL_PADDING), + JBUI.scale(SessionUiStyle.View.Layout.HORIZONTAL_PADDING), + ) + } + + private fun pane(view: JComponent, scrolls: Boolean) = JBScrollPane(view).apply { + border = JBUI.Borders.customLine( + SessionUiStyle.View.Outline.color(), + SessionUiStyle.View.Outline.width(), + 0, + 0, + 0, + ) + viewportBorder = JBUI.Borders.empty( + JBUI.scale(SessionUiStyle.View.Layout.VERTICAL_PADDING), + JBUI.scale(SessionUiStyle.View.Layout.HORIZONTAL_PADDING), + ).takeIf { scrolls } + isOpaque = true + background = SessionUiStyle.View.Surface.bgColor() + viewport.background = SessionUiStyle.View.Surface.bgColor() + horizontalScrollBarPolicy = if (scrolls) { + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED + } else { + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER + } + verticalScrollBarPolicy = ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED + } + } +} + +private class ToolField(value: String, private var style: SessionEditorStyle) : EditorTextField( + EditorFactory.getInstance().createDocument(value.trimEnd('\n')), + ProjectManager.getInstance().defaultProject, + PlainTextFileType.INSTANCE, + true, + false, +) { + init { + setFontInheritedFromLAF(false) + font = style.editorFont + addSettingsProvider { ed -> + style.applyToEditor(ed) + ed.setBorder(JBUI.Borders.empty()) + ed.scrollPane.border = JBUI.Borders.empty() + ed.scrollPane.viewportBorder = JBUI.Borders.empty() + ed.backgroundColor = SessionUiStyle.View.Surface.bgColor() + ed.scrollPane.background = SessionUiStyle.View.Surface.bgColor() + ed.scrollPane.viewport.background = SessionUiStyle.View.Surface.bgColor() + ed.settings.isUseSoftWraps = false + ed.settings.isAdditionalPageAtBottom = false + ed.scrollPane.horizontalScrollBarPolicy = ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER + ed.scrollPane.verticalScrollBarPolicy = ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER + } + } +} + +private const val SUB_CARD = "sub" +private const val LINK_CARD = "link" + +@RequiresEdt +internal fun toolParts( + tool: Tool, + openFile: ((String) -> Unit)? = null, + mode: ToolBodyMode = ToolBodyMode.TEXT, +): ToolParts { + lateinit var parts: ToolParts + val glyph = JBLabel() + val title = JBLabel() + val sub = JBLabel().apply { foreground = UiStyle.Colors.weak() } + val link = JBLabel().apply { + isVisible = false + isFocusable = false + foreground = UiStyle.Colors.fg() + cursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR) + setRequestFocusEnabled(false) + addMouseListener(object : MouseAdapter() { + override fun mouseClicked(e: MouseEvent) { + parts.openLink() + } + }) + } + val slot = JPanel(CardLayout()).apply { + isOpaque = false + add(sub, SUB_CARD) + add(link, LINK_CARD) + } + val state = JBLabel().apply { foreground = UiStyle.Colors.weak() } + val center = JPanel(BorderLayout(JBUI.scale(SessionUiStyle.View.Layout.GAP), 0)).apply { isOpaque = false } + val controls = Stack.horizontal() + val header = JPanel(BorderLayout(JBUI.scale(SessionUiStyle.View.Layout.GAP), 0)).apply { + isOpaque = false + center.add(title, BorderLayout.WEST) + center.add(slot, BorderLayout.CENTER) + add(glyph, BorderLayout.WEST) + add(center, BorderLayout.CENTER) + add(controls, BorderLayout.EAST) + } + parts = ToolParts(header, glyph, title, sub, link, slot, state, center, controls, openFile, mode = mode) + return parts.also { + controls.add(it.state) + } +} + +@RequiresEdt +internal fun searchParts(count: Int): ToolParts { + val glyph = JBLabel() + val title = JBLabel() + val sub = JBLabel().apply { foreground = UiStyle.Colors.weak() } + val targets = List(count) { + JBLabel().apply { + foreground = UiStyle.Colors.fg() + minimumSize = JBUI.size(0, minimumSize.height) + } + } + val link = JBLabel().apply { isVisible = false } + val slot = JPanel(CardLayout()).apply { + isOpaque = false + add(sub, SUB_CARD) + add(link, LINK_CARD) + } + val state = JBLabel().apply { foreground = UiStyle.Colors.weak() } + val stack = Stack.fitHorizontal(UiStyle.Gap.md()).apply { targets.forEach { next(it) } } + val target = stack.align(HAlign.TRACK, VAlign.CENTER) + val center = JPanel(BorderLayout(JBUI.scale(SessionUiStyle.View.Layout.GAP), 0)).apply { + isOpaque = false + minimumSize = JBUI.size(0, minimumSize.height) + add(title, BorderLayout.WEST) + add(target, BorderLayout.CENTER) + } + val controls = Stack.horizontal() + val header = JPanel(BorderLayout(JBUI.scale(SessionUiStyle.View.Layout.GAP), 0)).apply { + isOpaque = false + add(glyph, BorderLayout.WEST) + add(center, BorderLayout.CENTER) + add(controls, BorderLayout.EAST) + } + return ToolParts(header, glyph, title, sub, link, slot, state, center, controls, targets = targets, mode = ToolBodyMode.EDITOR).also { + controls.add(it.state) + } +} + +internal fun icon(tool: Tool) = when (tool.name) { + "read" -> SessionViewIcons.glasses + "list" -> SessionViewIcons.bulletList + "glob", "grep" -> SessionViewIcons.search + "webfetch", "websearch" -> SessionViewIcons.windowCursor + "codesearch" -> SessionViewIcons.code + "task" -> SessionViewIcons.task + "bash" -> SessionViewIcons.console + "edit", "write", "apply_patch" -> SessionViewIcons.codeLines + "todowrite", "todoread" -> SessionViewIcons.checklist + "question" -> SessionViewIcons.bubble + "skill" -> SessionViewIcons.brain + else -> SessionViewIcons.mcp +} + +internal fun title(tool: Tool) = when (tool.name) { + "read" -> KiloBundle.message("session.part.tool.read") + "bash" -> KiloBundle.message("session.part.tool.shell") + else -> toolTitle(tool) +} + +internal fun subtitle(tool: Tool) = when (tool.name) { + "read" -> readPath(tool) + "bash" -> shellTitle(tool) + else -> toolSubtitle(tool) +} + +@RequiresEdt +internal fun setText(label: JBLabel, text: String): Boolean { + val value = if (text.isBlank()) "" else XmlStringUtil.wrapInHtml(XmlStringUtil.escapeString(text)) + if (label.text == value) return false + label.text = value + return true +} + +@RequiresEdt +internal fun setTargetText(label: JBLabel, text: String): Boolean { + if (label.text == text) return false + label.text = text + return true +} + +@RequiresEdt +internal fun setLinkText(parts: ToolParts, text: String): Boolean { + val value = if (text.isBlank()) "" else XmlStringUtil.wrapInHtml("${XmlStringUtil.escapeString(text)}") + if (parts.label == text && parts.link.text == value) return false + parts.label = text + parts.link.text = value + return true +} + +@RequiresEdt +internal fun show(parts: ToolParts, link: Boolean): Boolean { + if (parts.link.isVisible == link && parts.sub.isVisible != link) return false + (parts.slot.layout as CardLayout).show(parts.slot, if (link) LINK_CARD else SUB_CARD) + return true +} + +internal fun subtitleText(parts: ToolParts): String = if (parts.link.isVisible) parts.label else parts.sub.text + +@RequiresEdt +internal fun setIcon(label: JBLabel, icon: Icon): Boolean { + if (label.icon === icon) return false + label.icon = icon + return true +} + +@RequiresEdt +internal fun setVisible(component: JComponent, visible: Boolean): Boolean { + if (component.isVisible == visible) return false + component.isVisible = visible + return true +} + +@RequiresEdt +internal fun setForeground(component: JComponent, color: Color): Boolean { + if (same(component.foreground, color)) return false + component.foreground = color + return true +} + +@RequiresEdt +internal fun setFont(component: JComponent, font: Font): Boolean { + if (component.font == font) return false + component.font = font + return true +} + +private fun same(a: Color?, b: Color): Boolean = a?.rgb == b.rgb + +internal fun color(tool: Tool) = when (tool.state) { + ToolExecState.PENDING -> SessionUiStyle.View.Tool.pending() + ToolExecState.RUNNING -> SessionUiStyle.View.Tool.running() + ToolExecState.COMPLETED -> SessionUiStyle.View.Tool.completed() + ToolExecState.ERROR -> SessionUiStyle.View.Tool.error() +} + +internal fun titleColor(tool: Tool) = if (tool.state == ToolExecState.ERROR) { + UiStyle.Colors.errorLabelForeground() +} else { + UiStyle.Colors.fg() +} + +internal fun stateText(tool: Tool) = when (tool.state) { + ToolExecState.PENDING -> KiloBundle.message("session.part.tool.pending") + ToolExecState.RUNNING -> KiloBundle.message("session.part.tool.running") + ToolExecState.COMPLETED -> "" + ToolExecState.ERROR -> KiloBundle.message("session.part.tool.error") +} + +private fun readPath(tool: Tool): String { + val target = target(tool) + if (target != null) { + if (target.type == "file") return tail(target.path).ifBlank { target.path } + return target.path + } + val path = tool.input["filePath"] ?: tool.input["path"] ?: tool.title ?: return tool.name + return tail(path).ifBlank { path } +} + +internal fun searchPath(path: String, repo: String?): String { + val text = path.takeIf { it.isNotBlank() } ?: return "" + val root = repo?.takeIf { it.isNotBlank() }?.let(::norm) + if (root == null) return text.takeUnless { it == "." } ?: "" + val full = if (OSAgnosticPathUtil.isAbsolute(text)) norm(text) else norm(FileUtil.join(root, text)) + if (full == root) return "" + if (!OSAgnosticPathUtil.startsWith(full, root)) return full + return FileUtil.getRelativePath(root, full, '/') ?: full +} + +private fun norm(path: String): String = FileUtil.toCanonicalPath(FileUtil.toSystemIndependentName(path), '/', true) + +internal fun globDirectory(tool: Tool, repo: String?): String = + searchPath( + tool.input["path"]?.takeIf { it.isNotBlank() } + ?: tool.title?.takeIf { it.isNotBlank() } + ?: "", + repo, + ) + +internal fun globPattern(tool: Tool): String = + tool.input["pattern"]?.takeIf { it.isNotBlank() }?.let { "pattern=$it" } ?: "" + +internal fun searchTargets(tool: Tool, repo: String?): List = listOfNotNull( + tool.input["path"]?.takeIf { it.isNotBlank() }?.let { searchPath(it, repo) }?.takeIf { it.isNotBlank() }, + tool.input["pattern"]?.takeIf { it.isNotBlank() }?.let { "pattern=$it" }, + tool.input["include"]?.takeIf { it.isNotBlank() }?.let { "include=$it" }, +) + +internal data class Target( + val path: String, + val type: String, +) + +internal fun target(tool: Tool): Target? { + val out = output(tool) + if (out.isBlank()) return null + val path = tag(out, "path") ?: return null + val type = tag(out, "type") ?: return null + return Target(path, type.lowercase()) +} + +private fun tag(text: String, name: String): String? = + Regex("<$name>\\s*([\\s\\S]*?)\\s*") + .find(text) + ?.groupValues + ?.getOrNull(1) + ?.trim() + ?.takeIf { it.isNotBlank() } + +private fun shellTitle(tool: Tool): String = + tool.input["description"]?.takeIf { it.isNotBlank() } + ?: tool.metadata["description"]?.takeIf { it.isNotBlank() } + ?: tool.title?.takeIf { it.isNotBlank() } + ?: command(tool).lineSequence().firstOrNull { it.isNotBlank() } + ?: "" + +internal fun command(tool: Tool): String = + tool.input["command"]?.takeIf { it.isNotBlank() } + ?: tool.metadata["command"]?.takeIf { it.isNotBlank() } + ?: "" + +internal fun output(tool: Tool): String = + tool.output?.takeIf { it.isNotBlank() } + ?: tool.metadata["output"]?.takeIf { it.isNotBlank() } + ?: "" + +internal fun preview(tool: Tool): String = if (tool.name == "bash") shellPreview(tool) else plainPreview(tool) + +internal fun body(tool: Tool): String = if (tool.name == "bash") shellBody(tool) else plainBody(tool) + +private fun shellPreview(tool: Tool): String { + val cmd = command(tool) + val out = output(tool) + val err = tool.error?.takeIf { it.isNotBlank() } + return Preview().apply { + if (cmd.isNotBlank()) append("$ ").append(cmd) + if (out.isNotBlank()) { + sep() + append(out) + } + if (err != null) { + sep() + append(err) + } + }.build() +} + +private fun shellBody(tool: Tool): String { + val cmd = command(tool) + val out = output(tool) + val err = tool.error?.takeIf { it.isNotBlank() } + return buildString { + if (cmd.isNotBlank()) append("$ ").append(cmd) + if (out.isNotBlank()) { + if (isNotEmpty()) append("\n\n") + append(out) + } + if (err != null) { + if (isNotEmpty()) append("\n\n") + append(err) + } + } +} + +private fun plainPreview(tool: Tool): String { + val out = output(tool) + val err = tool.error?.takeIf { it.isNotBlank() } + return Preview().apply { + if (out.isNotBlank()) append(out) + if (err != null) { + sep() + append(err) + } + }.build() +} + +internal fun plainBody(tool: Tool): String { + val out = output(tool) + val err = tool.error?.takeIf { it.isNotBlank() } + return listOf(out, err).filter { !it.isNullOrBlank() }.joinToString("\n\n") +} + +internal fun canExpand(tool: Tool): Boolean { + if (tool.name == "bash") return command(tool).isNotBlank() || output(tool).isNotBlank() || !tool.error.isNullOrBlank() + return output(tool).isNotBlank() || !tool.error.isNullOrBlank() +} + +private fun toolTitle(tool: Tool): String = + tool.title?.takeIf { it.isNotBlank() } + ?: tool.name.replace('_', ' ').replaceFirstChar { it.titlecase() } + +private fun toolSubtitle(tool: Tool): String { + val base = listOf("description", "query", "url", "filePath", "path", "name") + .mapNotNull { tool.input[it]?.takeIf { value -> value.isNotBlank() } } + .firstOrNull() + val args = listOf("pattern", "include", "offset", "limit") + .mapNotNull { key -> tool.input[key]?.takeIf { it.isNotBlank() }?.let { "$key=$it" } } + return listOfNotNull(base).plus(args).joinToString(" ") +} + +internal fun tail(path: String): String { + val value = path.trimEnd('/', '\\') + val index = maxOf(value.lastIndexOf('/'), value.lastIndexOf('\\')) + if (index < 0) return value + return value.substring(index + 1) +} + +private class Preview { + private val text = StringBuilder() + private var cut = false + + fun append(value: String): Preview { + if (cut) return this + val rem = SessionUiStyle.View.Tool.PREVIEW_LIMIT - text.length + if (value.length <= rem) { + text.append(value) + return this + } + if (rem > 0) text.append(value, 0, rem) + cut = true + return this + } + + fun sep(): Preview { + if (text.isNotEmpty()) append("\n\n") + return this + } + + fun build(): String { + if (!cut) return text.toString() + if (text.isNotEmpty()) text.append("\n\n") + text.append(KiloBundle.message("session.part.tool.truncated")) + return text.toString() + } +} diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/tool/ToolView.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/tool/ToolView.kt new file mode 100644 index 00000000000..97324bccd2b --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/views/tool/ToolView.kt @@ -0,0 +1,185 @@ +package ai.kilocode.client.session.views.tool + +import ai.kilocode.client.session.model.Content +import ai.kilocode.client.session.model.Tool +import ai.kilocode.client.session.model.ToolExecState +import ai.kilocode.client.session.ui.selection.SessionSelection +import ai.kilocode.client.session.ui.style.SessionEditorStyle +import ai.kilocode.client.session.ui.style.SessionUiStyle +import ai.kilocode.client.session.views.base.SecondarySessionPartView +import ai.kilocode.client.ui.UiStyle +import com.intellij.openapi.util.Disposer +import com.intellij.util.concurrency.annotations.RequiresEdt +import com.intellij.util.ui.JBUI +import java.awt.Dimension +import javax.swing.ScrollPaneConstants + +/** Renders non-read tool calls with VS Code-inspired rows/cards. */ +class ToolView( + tool: Tool, + private val selection: SessionSelection? = null, + private val parts: ToolParts = toolParts(tool, mode = ToolBodyMode.EDITOR), +) : SecondarySessionPartView(parts.header, { parts.scroll(tool) }) { + + override val contentId: String = tool.id + + private var item = tool + private var style = SessionEditorStyle.current() + private var registered = false + private var disposed = false + + init { + bindHeader(parts.glyph, parts.title, parts.sub, parts.state, parts.center, parts.controls, parts.slot) + applyStyle(style) + sync() + } + + @RequiresEdt + override fun expand(): Boolean { + val changed = super.expand() + if (!changed) return false + syncBody() + applyBodyStyle() + return true + } + + @RequiresEdt + override fun getPreferredSize(): Dimension { + val size = super.getPreferredSize() + if (!bodyVisible()) return size + val height = row.preferredSize.height + bodyMaxHeight() + return Dimension(size.width, minOf(size.height, height)) + } + + @RequiresEdt + override fun update(content: Content) { + if (content !is Tool) return + val was = item.name + item = content + var changed = false + if (was != content.name || !canExpand(content)) changed = collapse() || changed + changed = sync() || changed + changed = syncBody() || changed + if (changed) refresh() + } + + @RequiresEdt + fun labelText(): String = listOf(parts.title.text, subtitleText(parts), parts.state.text) + .filter { it.isNotBlank() } + .joinToString(" ") + + @RequiresEdt + fun commandText(): String = command(item) + @RequiresEdt + fun outputText(): String = output(item) + @RequiresEdt + fun bodyText(): String = body(item) + @RequiresEdt + internal fun previewText(): String = parts.content?.text ?: preview(item) + @RequiresEdt + fun hasToggle(): Boolean = arrow.isVisible + @RequiresEdt + internal fun bodyFont() = parts.content?.font ?: style.editorFont + @RequiresEdt + internal fun titleFont() = parts.title.font + @RequiresEdt + internal fun subtitleFont() = parts.sub.font + @RequiresEdt + internal fun stateFont() = parts.state.font + @RequiresEdt + internal fun bodyEditable() = parts.content?.editable ?: false + @RequiresEdt + internal fun bodyCaretVisible() = parts.content?.caretVisible ?: false + @RequiresEdt + internal fun bodyVisible() = parts.scroll?.parent === this + @RequiresEdt + internal fun controlCount() = if (arrow.isVisible) 1 else 0 + @RequiresEdt + internal fun horizontalPolicy() = parts.scroll?.horizontalScrollBarPolicy ?: ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER + @RequiresEdt + internal fun verticalPolicy() = parts.scroll?.verticalScrollBarPolicy ?: ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER + @RequiresEdt + internal fun bodyWrap() = parts.content?.lineWrap ?: false + @RequiresEdt + internal fun bodyMaxRows() = SessionUiStyle.View.Tool.BODY_LINES + @RequiresEdt + internal fun bodyCreated() = parts.bodyCreated() + @RequiresEdt + internal fun bodyEditor() = parts.content?.editor + + @RequiresEdt + override fun applyStyle(style: SessionEditorStyle) { + this.style = style + var changed = false + changed = setFont(parts.title, style.boldEditorFont) || changed + changed = setFont(parts.sub, style.smallEditorFont) || changed + changed = setFont(parts.link, style.smallEditorFont) || changed + changed = setFont(parts.state, style.smallEditorFont) || changed + changed = applyBodyStyle() || changed + if (changed) refresh() + } + + private fun sync(): Boolean { + val expand = canExpand(item) + var changed = false + changed = syncExpandable(expand) || changed + changed = setVisible(parts.state, !expand) || changed + changed = syncLabels() || changed + val body = parts.content + if (body != null && body.foreground != bodyColor()) { + body.foreground = bodyColor() + changed = true + } + return changed + } + + private fun syncLabels(): Boolean { + var changed = false + changed = setIcon(parts.glyph, icon(item)) || changed + changed = setForeground(parts.glyph, color(item)) || changed + changed = setText(parts.title, title(item)) || changed + changed = setText(parts.sub, subtitle(item)) || changed + changed = setForeground(parts.title, titleColor(item)) || changed + changed = setText(parts.state, stateText(item)) || changed + changed = setForeground(parts.state, color(item)) || changed + return changed + } + + private fun syncBody(): Boolean { + var changed = false + val body = parts.content ?: return false + val value = preview(item) + if (body.text != value) { + body.text = value + changed = true + } + if (body.foreground != bodyColor()) { + body.foreground = bodyColor() + changed = true + } + return changed + } + + private fun applyBodyStyle(): Boolean { + val body = parts.content ?: return false + if (!disposed) { + Disposer.register(this, body) + disposed = true + } + if (!registered && selection != null && parts.scroll?.parent != null) { + registered = true + body.register(selection, this) + } + return body.applyStyle(style) + } + + private fun bodyColor() = if (item.state == ToolExecState.ERROR) UiStyle.Colors.errorLabelForeground() else UiStyle.Colors.fg() + + private fun bodyMaxHeight(): Int { + val body = parts.content ?: return 0 + return body.lineHeight() * bodyMaxRows() + + JBUI.scale(SessionUiStyle.View.Layout.BODY_EXTRA_HEIGHT) + } + + override fun dumpLabel() = "ToolView#$contentId(${labelText()})" +} diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/ui/layout/Stack.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/ui/layout/Stack.kt index bc8385e96b4..e043225c3ce 100644 --- a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/ui/layout/Stack.kt +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/ui/layout/Stack.kt @@ -51,11 +51,19 @@ open class Stack( private val mgr: Layout get() = getLayout() as Layout + internal fun fit(): Stack { + mgr.fit = true + revalidate() + return this + } + private class Layout( private val axis: StackAxis, private val gap: Int, ) : LayoutManager2 { + var fit = false + private val entries = mutableListOf() fun gap(size: Int) { @@ -83,6 +91,10 @@ open class Stack( val ins = parent.insets val w = maxOf(0, parent.width - ins.left - ins.right) val h = maxOf(0, parent.height - ins.top - ins.bottom) + if (axis == StackAxis.HORIZONTAL && fit) { + fit(parent, ins.left, ins.top, w, h) + return + } var x = ins.left var y = ins.top var seen = false @@ -131,6 +143,48 @@ open class Stack( } } + private fun fit(parent: Container, left: Int, top: Int, w: Int, h: Int) { + val items = children(parent, h) + var x = left + var rest = w + items.forEach { item -> + val gap = minOf(item.gap, rest) + x += gap + rest -= gap + val width = minOf(item.width, rest) + item.comp.setBounds(x, top, width, h) + x += width + rest -= width + } + } + + private fun children(parent: Container, h: Int): List { + val items = mutableListOf() + var seen = false + var ready = false + var pending: Int? = null + for (entry in entries) { + when (entry) { + is Entry.Gap -> if (ready) pending = safe(pending ?: 0, entry.size) + is Entry.Child -> { + val space = pending + pending = null + ready = false + if (entry.comp.isVisible) { + entry.comp.setSize(entry.comp.width.coerceAtLeast(1), h) + val pref = entry.comp.preferredSize + val min = entry.comp.minimumSize + val max = entry.comp.maximumSize + items.add(Item(entry.comp, if (seen) space ?: gap else 0, bound(pref.width, min.width, max.width))) + seen = true + ready = true + } + } + } + } + return items + } + override fun minimumLayoutSize(parent: Container) = size(parent, Size.MIN) override fun preferredLayoutSize(parent: Container) = size(parent, Size.PREF) override fun maximumLayoutSize(target: Container) = size(target, Size.MAX) @@ -204,6 +258,8 @@ open class Stack( data class Child(val comp: Component) : Entry data class Gap(val size: Int) : Entry } + + private data class Item(val comp: Component, val gap: Int, val width: Int) } private enum class Size { MIN, PREF, MAX } @@ -211,6 +267,7 @@ open class Stack( companion object { fun vertical(gap: Int = 0) = Stack(StackAxis.VERTICAL, gap) fun horizontal(gap: Int = 0) = Stack(StackAxis.HORIZONTAL, gap) + fun fitHorizontal(gap: Int = 0) = Stack(StackAxis.HORIZONTAL, gap).fit() fun verticalFiller(size: Int): Component = filler(StackAxis.VERTICAL, size) fun horizontalFiller(size: Int): Component = filler(StackAxis.HORIZONTAL, size) } diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/ui/md/MdViewHybrid.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/ui/md/MdViewHybrid.kt index b5579cdd4fe..cd03b91b5c1 100644 --- a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/ui/md/MdViewHybrid.kt +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/ui/md/MdViewHybrid.kt @@ -27,6 +27,7 @@ import org.commonmark.node.Document import org.commonmark.node.FencedCodeBlock import org.commonmark.node.IndentedCodeBlock import org.commonmark.node.Node +import org.commonmark.node.ThematicBreak import org.commonmark.parser.Parser import org.commonmark.renderer.html.HtmlRenderer import java.awt.Color @@ -498,6 +499,9 @@ internal class MdViewHybrid( val field = runCatching { CodeField(file, opts, text).also { ed -> ed.setDisposedWith(disposable) + Disposer.register(disposable) { + ed.getEditor(false)?.let(EditorFactory.getInstance()::releaseEditor) + } selection?.register(ed, disposable) } }.getOrElse { err -> @@ -682,8 +686,14 @@ internal class MdViewHybrid( fun flush() { if (md.isEmpty()) return val doc = parser.parse(md.toString()) - html.append(renderer.render(doc)) - blocks.addAll(collect(doc)) + val descs = collect(doc) + blocks.addAll(descs) + for (desc in descs) { + when (desc) { + is Desc.Html -> html.append(desc.body) + is Desc.Code -> html.append(codeHtml(desc.text)) + } + } md.clear() } @@ -896,27 +906,39 @@ internal class MdViewHybrid( private inner class Visitor : AbstractVisitor() { val blocks = mutableListOf() + private val run = StringBuilder() override fun visit(document: Document) { visitChildren(document) + flush() } override fun visit(code: FencedCodeBlock) { + flush() blocks.add(Desc.Code(code.literal, file(code.info))) } override fun visit(code: IndentedCodeBlock) { + flush() blocks.add(Desc.Code(code.literal, file(null))) } + private fun flush() { + if (run.isEmpty()) return + blocks.add(Desc.Html(run.toString())) + run.clear() + } + public override fun visitChildren(parent: Node) { var child = parent.firstChild while (child != null) { val next = child.next - if (child is FencedCodeBlock || child is IndentedCodeBlock) child.accept(this) - if (child is Block && child !is FencedCodeBlock && child !is IndentedCodeBlock) { - blocks.add(Desc.Html(renderer.render(child))) + if (child is ThematicBreak) { + child = next + continue } + if (child is FencedCodeBlock || child is IndentedCodeBlock) child.accept(this) + if (child is Block && child !is FencedCodeBlock && child !is IndentedCodeBlock) run.append(renderer.render(child)) child = next } } diff --git a/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/brain.svg b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/brain.svg new file mode 100644 index 00000000000..304a93ea9c5 --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/brain.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/brain_dark.svg b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/brain_dark.svg new file mode 100644 index 00000000000..894515662bf --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/brain_dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/bubble-5.svg b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/bubble-5.svg new file mode 100644 index 00000000000..b76605a472d --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/bubble-5.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/bubble-5_dark.svg b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/bubble-5_dark.svg new file mode 100644 index 00000000000..95762858b59 --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/bubble-5_dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/bullet-list.svg b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/bullet-list.svg new file mode 100644 index 00000000000..c15ecbd0e45 --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/bullet-list.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/bullet-list_dark.svg b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/bullet-list_dark.svg new file mode 100644 index 00000000000..bcce4c17aec --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/bullet-list_dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/checklist.svg b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/checklist.svg new file mode 100644 index 00000000000..11b4cac00b4 --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/checklist.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/checklist_dark.svg b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/checklist_dark.svg new file mode 100644 index 00000000000..3997b5ec2ef --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/checklist_dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/chevron-down.svg b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/chevron-down.svg new file mode 100644 index 00000000000..b916dec2a8e --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/chevron-down.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/chevron-down_dark.svg b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/chevron-down_dark.svg new file mode 100644 index 00000000000..9d727eb37c2 --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/chevron-down_dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/chevron-left.svg b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/chevron-left.svg new file mode 100644 index 00000000000..57c07f8de87 --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/chevron-left.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/chevron-left_dark.svg b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/chevron-left_dark.svg new file mode 100644 index 00000000000..0db8b8f5c86 --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/chevron-left_dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/chevron-right.svg b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/chevron-right.svg new file mode 100644 index 00000000000..c4f66e5533a --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/chevron-right.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/chevron-right_dark.svg b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/chevron-right_dark.svg new file mode 100644 index 00000000000..929005b5aaf --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/chevron-right_dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/code-lines.svg b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/code-lines.svg new file mode 100644 index 00000000000..456560f6327 --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/code-lines.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/code-lines_dark.svg b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/code-lines_dark.svg new file mode 100644 index 00000000000..947b66ac25c --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/code-lines_dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/code.svg b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/code.svg new file mode 100644 index 00000000000..554b8656b03 --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/code.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/code_dark.svg b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/code_dark.svg new file mode 100644 index 00000000000..ddfe6242464 --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/code_dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/console.svg b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/console.svg new file mode 100644 index 00000000000..5a27e30208e --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/console.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/console_dark.svg b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/console_dark.svg new file mode 100644 index 00000000000..44f84beaa6d --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/console_dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/eye.svg b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/eye.svg new file mode 100644 index 00000000000..45d7231e5e7 --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/eye.svg @@ -0,0 +1,4 @@ + + + + diff --git a/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/eye_dark.svg b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/eye_dark.svg new file mode 100644 index 00000000000..14983a084f4 --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/eye_dark.svg @@ -0,0 +1,4 @@ + + + + diff --git a/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/glasses.svg b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/glasses.svg new file mode 100644 index 00000000000..1f891fb11d4 --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/glasses.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/glasses_dark.svg b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/glasses_dark.svg new file mode 100644 index 00000000000..769102d69ee --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/glasses_dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/magnifying-glass-menu.svg b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/magnifying-glass-menu.svg new file mode 100644 index 00000000000..3ab3bf728cd --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/magnifying-glass-menu.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/magnifying-glass-menu_dark.svg b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/magnifying-glass-menu_dark.svg new file mode 100644 index 00000000000..a1eff436992 --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/magnifying-glass-menu_dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/mcp.svg b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/mcp.svg new file mode 100644 index 00000000000..cee92d0c0b2 --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/mcp.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/mcp_dark.svg b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/mcp_dark.svg new file mode 100644 index 00000000000..4eb477f0e37 --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/mcp_dark.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/task.svg b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/task.svg new file mode 100644 index 00000000000..17a37afba86 --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/task.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/task_dark.svg b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/task_dark.svg new file mode 100644 index 00000000000..6eaae56d332 --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/task_dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/warning.svg b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/warning.svg new file mode 100644 index 00000000000..802ac7d8554 --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/warning.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/warning_dark.svg b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/warning_dark.svg new file mode 100644 index 00000000000..d9f9e992c55 --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/warning_dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/window-cursor.svg b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/window-cursor.svg new file mode 100644 index 00000000000..b26bac3f715 --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/window-cursor.svg @@ -0,0 +1,4 @@ + + + + diff --git a/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/window-cursor_dark.svg b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/window-cursor_dark.svg new file mode 100644 index 00000000000..80ac013dd3a --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/main/resources/icons/views/window-cursor_dark.svg @@ -0,0 +1,4 @@ + + + + diff --git a/packages/kilo-jetbrains/frontend/src/main/resources/messages/KiloBundle.properties b/packages/kilo-jetbrains/frontend/src/main/resources/messages/KiloBundle.properties index ff2594f38fa..9141c1b9a82 100644 --- a/packages/kilo-jetbrains/frontend/src/main/resources/messages/KiloBundle.properties +++ b/packages/kilo-jetbrains/frontend/src/main/resources/messages/KiloBundle.properties @@ -88,6 +88,8 @@ session.part.tool.copy=Copy session.part.tool.error=Error session.part.tool.pending=Pending session.part.tool.read=Read +session.part.tool.glob=Glob +session.part.tool.search=Search session.part.tool.running=Running session.part.tool.shell=Shell session.part.tool.truncated=Output truncated in preview. Full output remains in session data. diff --git a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/SessionScrollTest.kt b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/SessionScrollTest.kt index a5c6fbcacd3..6aea6cecff2 100644 --- a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/SessionScrollTest.kt +++ b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/SessionScrollTest.kt @@ -1,23 +1,33 @@ package ai.kilocode.client.session import ai.kilocode.client.session.ui.SessionMessageListPanel +import ai.kilocode.client.session.ui.style.SessionUiStyle import ai.kilocode.rpc.dto.ChatEventDto import ai.kilocode.rpc.dto.MessageErrorDto +import ai.kilocode.rpc.dto.MessageWithPartsDto import ai.kilocode.rpc.dto.PermissionRequestDto +import ai.kilocode.rpc.dto.PartDto import ai.kilocode.rpc.dto.QuestionInfoDto import ai.kilocode.rpc.dto.QuestionOptionDto import ai.kilocode.rpc.dto.QuestionRequestDto import ai.kilocode.rpc.dto.SessionStatusDto import ai.kilocode.rpc.dto.ToolRefDto import ai.kilocode.client.session.ui.prompt.PromptPanel +import ai.kilocode.client.session.views.tool.ToolView import ai.kilocode.client.plugin.KiloBundle import com.intellij.ui.EditorTextField +import com.intellij.ui.components.JBScrollPane import com.intellij.ui.components.JBRadioButton import com.intellij.util.ui.JBUI import java.awt.Container +import java.awt.Point import javax.swing.AbstractButton import javax.swing.JButton +import javax.swing.JComponent +import javax.swing.Scrollable +import javax.swing.SwingConstants import javax.swing.JTextArea +import javax.swing.SwingUtilities import kotlinx.coroutines.CompletableDeferred @Suppress("UnstableApiUsage") @@ -43,7 +53,7 @@ class SessionScrollTest : SessionUiTestBase() { if (bottom(bar) <= threshold) { fillTranscript(24, start = 24) } - setValue(bar, bottom(bar) - threshold + 1) + setValuePassive(bar, bottom(bar) - threshold + 1) emit(ChatEventDto.MessageUpdated("ses_test", message("tail"))) drainScroll() @@ -51,6 +61,49 @@ class SessionScrollTest : SessionUiTestBase() { assertBottom(bar) } + fun `test viewport driven scroll can move away from stale saved position`() { + showMessages() + fillTranscript(24) + val bar = scrollBar() + setValue(bar, bottom(bar) / 2) + val value = bar.value + val target = (value + JBUI.scale(96)).coerceAtMost(bottom(bar) - 1) + assertTrue("value=$value target=$target bottom=${bottom(bar)}", target > value) + + (scrollComponent() as JBScrollPane).viewport.viewPosition = Point(0, target) + drainScroll() + + assertEquals(target, bar.value) + assertTrue(jumpButton().isVisible) + } + + fun `test user scroll upward near bottom disables tail follow`() { + showMessages() + fillTranscript(48) + val bar = scrollBar() + val threshold = JBUI.scale(32) + assertTrue("bottom=${bottom(bar)} threshold=$threshold", bottom(bar) > threshold * 2) + val id = "near_bottom_user_tail" + val pid = "near_bottom_user_part" + emit(ChatEventDto.MessageUpdated("ses_test", message(id)), flush = false) + emit(ChatEventDto.PartUpdated("ses_test", part(pid, id, "text", "start\n\n")), flush = false) + forceFlush() + drainScroll() + setBottom(bar) + setValue(bar, bottom(bar) - threshold + 1) + val value = bar.value + assertFalse(ui.scroll.following()) + + repeat(240) { i -> + emit(ChatEventDto.PartDelta("ses_test", id, pid, "text", "tail line $i\n"), flush = false) + } + forceFlush() + drainScroll() + + assertTrue("value=$value actual=${bar.value}", bar.value >= value) + assertFalse(ui.scroll.following()) + } + fun `test session update preserves position outside bottom threshold`() { showMessages() fillTranscript(24) @@ -161,6 +214,22 @@ class SessionScrollTest : SessionUiTestBase() { assertFalse(jumpButton().isVisible) } + fun `test physical mouse wheel uses accelerated transcript unit distance`() { + showMessages() + fillTranscript(48) + val bar = scrollBar() + setValue(bar, 0) + drainScroll() + val amount = 3 + val expected = JBUI.scale(SessionUiStyle.SessionLayout.SCROLL_INCREMENT * amount) + assertTrue("bottom=${bottom(bar)} expected=$expected", bottom(bar) >= expected * 2) + + val view = scrollView() as Scrollable + val unit = view.getScrollableUnitIncrement(scrollComponent().visibleRect, SwingConstants.VERTICAL, 1) + + assertEquals(expected, unit * amount) + } + fun `test part delta follows bottom after height growth`() { showMessages() fillTranscript(24) @@ -181,6 +250,55 @@ class SessionScrollTest : SessionUiTestBase() { assertFalse(jumpButton().isVisible) } + fun `test user scrolling to bottom during massive stream resumes following`() { + showMessages() + fillTranscript(48) + val bar = scrollBar() + val id = "stream_massive_resume" + val pid = "stream_massive_resume_part" + emit(ChatEventDto.MessageUpdated("ses_test", message(id)), flush = false) + emit(ChatEventDto.PartUpdated("ses_test", part(pid, id, "text", "start\n\n")), flush = false) + forceFlush() + drainScroll() + setValue(bar, bottom(bar) / 2) + assertFalse(ui.scroll.following()) + assertTrue(jumpButton().isVisible) + val first = buildString { + repeat(160) { i -> append("line $i\n\n") } + } + + repeat(160) { i -> + emit(ChatEventDto.PartDelta("ses_test", id, pid, "text", "line $i\n\n"), flush = false) + } + emit(ChatEventDto.PartUpdated("ses_test", part(pid, id, "text", "start\n\n${first}snapshot\n\n")), flush = false) + forceFlush() + settleShort(100) + layout() + setBottom(bar) + drainScroll() + setBottom(bar) + drainScroll() + + assertBottom(bar) + assertTrue(ui.scroll.following()) + assertFalse(jumpButton().isVisible) + val second = buildString { + repeat(160) { i -> append("tail line $i\n\n") } + } + + repeat(160) { i -> + emit(ChatEventDto.PartDelta("ses_test", id, pid, "text", "tail line $i\n\n"), flush = false) + } + emit(ChatEventDto.PartUpdated("ses_test", part(pid, id, "text", "start\n\n${first}snapshot\n\n${second}snapshot tail\n\n")), flush = false) + forceFlush() + settleShort(100) + drainScroll() + + assertBottom(bar) + assertTrue(ui.scroll.following()) + assertFalse(jumpButton().isVisible) + } + fun `test part delta preserves middle scroll position`() { showMessages() fillTranscript(24) @@ -201,6 +319,51 @@ class SessionScrollTest : SessionUiTestBase() { assertEquals(value, bar.value) } + fun `test expanding tool at bottom preserves clicked header position`() { + val mid = "tool_expand_bottom" + val pid = "tool_expand_bottom_part" + rpc.history.addAll(history(23) + toolHistory(mid, pid) + historyRange(1, start = 23)) + ui = newUi(id = "ses_test") + settle() + drainScroll() + val bar = scrollBar() + setBottom(bar) + drainScroll() + val view = toolView(mid, pid) + assertFalse(view.bodyVisible()) + val y = visibleY(view) + val value = bar.value + + view.toggle() + drainScroll() + + assertTrue(view.bodyVisible()) + assertEquals(y, visibleY(view)) + assertEquals(value, bar.value) + } + + fun `test expanding tool in middle preserves clicked header position`() { + val mid = "tool_expand_middle" + val pid = "tool_expand_middle_part" + rpc.history.addAll(history(12) + toolHistory(mid, pid) + historyRange(12, start = 12)) + ui = newUi(id = "ses_test") + settle() + drainScroll() + val bar = scrollBar() + val view = toolView(mid, pid) + val top = SwingUtilities.convertPoint(view, Point(0, 0), scrollView()).y + setValue(bar, top - 80) + drainScroll() + val y = visibleY(view) + + view.toggle() + drainScroll() + + assertTrue(view.bodyVisible()) + assertEquals(y, visibleY(view)) + assertTrue(jumpButton().isVisible) + } + fun `test long prompt message follows when transcript is at bottom`() { showMessages() fillTranscript(24) @@ -389,6 +552,56 @@ class SessionScrollTest : SessionUiTestBase() { assertFalse(button.isVisible) } + fun `test scroll button resumes following during massive stream`() { + showMessages() + fillTranscript(48) + val button = jumpButton() + val bar = scrollBar() + val id = "stream_massive_button" + val pid = "stream_massive_button_part" + emit(ChatEventDto.MessageUpdated("ses_test", message(id)), flush = false) + emit(ChatEventDto.PartUpdated("ses_test", part(pid, id, "text", "start\n\n")), flush = false) + forceFlush() + drainScroll() + setValue(bar, bottom(bar) / 2) + val first = buildString { + repeat(160) { i -> append("line $i\n\n") } + } + + repeat(160) { i -> + emit(ChatEventDto.PartDelta("ses_test", id, pid, "text", "line $i\n\n"), flush = false) + } + emit(ChatEventDto.PartUpdated("ses_test", part(pid, id, "text", "start\n\n${first}snapshot\n\n")), flush = false) + forceFlush() + settleShort(100) + drainScroll() + + assertTrue(button.isVisible) + assertFalse(ui.scroll.following()) + + click(button) + drainScroll() + + assertBottom(bar) + assertTrue(ui.scroll.following()) + assertFalse(button.isVisible) + val second = buildString { + repeat(160) { i -> append("tail line $i\n\n") } + } + + repeat(160) { i -> + emit(ChatEventDto.PartDelta("ses_test", id, pid, "text", "tail line $i\n\n"), flush = false) + } + emit(ChatEventDto.PartUpdated("ses_test", part(pid, id, "text", "start\n\n${first}snapshot\n\n${second}snapshot tail\n\n")), flush = false) + forceFlush() + settleShort(100) + drainScroll() + + assertBottom(bar) + assertTrue(ui.scroll.following()) + assertFalse(button.isVisible) + } + fun `test scroll button remains hidden outside transcript body`() { val button = jumpButton() @@ -476,11 +689,12 @@ class SessionScrollTest : SessionUiTestBase() { assertBottom(scrollBar()) } - fun `test scroll owns the session viewport`() { + fun `test scroll owns the session viewport without overlapping content`() { settle() assertSame(scrollComponent(), scrollView()?.parent?.parent) assertFalse(scrollView() is SessionMessageListPanel) + assertFalse((scrollComponent() as JBScrollPane).isOverlappingScrollBar) } // ------ question/login-required autoscroll ------ @@ -853,6 +1067,15 @@ class SessionScrollTest : SessionUiTestBase() { private inline fun option(label: String): T where T : AbstractButton = findAll(ui).first { it.actionCommand == label } + private fun toolView(mid: String, pid: String): ToolView { + val messages = find(ui) + return messages.findMessage(mid)?.part(pid) as? ToolView + ?: error("missing tool $mid/$pid\n${messages.dumpDetailed()}") + } + + private fun visibleY(component: JComponent): Int = + SwingUtilities.convertPoint(component, Point(0, 0), scrollComponent()).y + private inline fun findAll(root: Container = ui): List = findAll(root, T::class.java) private fun findAll(root: Container, cls: Class): List { @@ -949,4 +1172,27 @@ class SessionScrollTest : SessionUiTestBase() { ), tool = ToolRefDto("msg1", "call1"), ) + + private fun toolPart(id: String, mid: String) = PartDto( + id = id, + sessionID = "ses_test", + messageID = mid, + type = "tool", + tool = "bash", + callID = "call_$id", + state = "completed", + title = "print output", + output = "output line\n".repeat(160), + ) + + private fun toolHistory(mid: String, pid: String) = MessageWithPartsDto( + message(mid).copy(role = "assistant"), + listOf(toolPart(pid, mid)), + ) + + private fun historyRange(count: Int, start: Int) = List(count) { offset -> + val i = start + offset + val id = "hist_range_$i" + MessageWithPartsDto(message(id), listOf(part("hist_range_part_$i", id, "text", text(i)))) + } } diff --git a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/SessionUiTestBase.kt b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/SessionUiTestBase.kt index e77fb3d6119..4fe55cf5d26 100644 --- a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/SessionUiTestBase.kt +++ b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/SessionUiTestBase.kt @@ -26,6 +26,7 @@ import ai.kilocode.rpc.dto.PartDto import ai.kilocode.rpc.dto.SessionDto import ai.kilocode.rpc.dto.SessionTimeDto import com.intellij.testFramework.fixtures.BasePlatformTestCase +import com.intellij.openapi.util.Disposer import com.intellij.util.ui.UIUtil import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.SupervisorJob @@ -73,6 +74,7 @@ abstract class SessionUiTestBase : BasePlatformTestCase() { override fun tearDown() { try { + Disposer.dispose(ui) scope.cancel() } finally { super.tearDown() diff --git a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/ui/ProgressPanelTest.kt b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/ui/ProgressPanelTest.kt index 09f1d288f38..7974709b08d 100644 --- a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/ui/ProgressPanelTest.kt +++ b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/ui/ProgressPanelTest.kt @@ -4,9 +4,12 @@ import ai.kilocode.client.session.model.Permission import ai.kilocode.client.session.model.PermissionMeta import ai.kilocode.client.session.model.SessionModel import ai.kilocode.client.session.model.SessionState +import ai.kilocode.client.session.ui.style.SessionUiStyle +import ai.kilocode.client.ui.UiStyle import com.intellij.openapi.Disposable import com.intellij.openapi.util.Disposer import com.intellij.testFramework.fixtures.BasePlatformTestCase +import com.intellij.util.ui.JBUI /** * Verifies [ProgressPanel] show/hide behaviour driven by direct [SessionModel] @@ -45,6 +48,15 @@ class ProgressPanelTest : BasePlatformTestCase() { assertEquals("Thinking\u2026", panel.labelText()) } + fun `test panel uses transcript row padding`() { + val ins = panel.insets + + assertEquals(UiStyle.Gap.sm(), ins.top) + assertEquals(JBUI.scale(SessionUiStyle.View.Layout.HORIZONTAL_PADDING), ins.left) + assertEquals(0, ins.bottom) + assertEquals(0, ins.right) + } + fun `test panel hides on Idle`() { model.setState(SessionState.Busy("Thinking\u2026")) model.setState(SessionState.Idle) diff --git a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/ui/SessionMessageListPanelTest.kt b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/ui/SessionMessageListPanelTest.kt index 7b13b4a5f7d..8a9ae5ccd20 100644 --- a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/ui/SessionMessageListPanelTest.kt +++ b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/ui/SessionMessageListPanelTest.kt @@ -9,13 +9,14 @@ import ai.kilocode.client.session.model.SessionModel import ai.kilocode.client.session.model.SessionState import ai.kilocode.client.session.model.ToolCallRef import ai.kilocode.client.session.ui.style.SessionEditorStyle +import ai.kilocode.client.session.ui.style.SessionUiStyle import ai.kilocode.client.session.views.LoginRequiredView import ai.kilocode.client.session.views.PlanExitView import ai.kilocode.client.session.views.permission.PermissionView import ai.kilocode.client.session.views.question.QuestionResultView import ai.kilocode.client.session.views.question.QuestionView import ai.kilocode.client.session.views.TextView -import ai.kilocode.client.session.views.ToolView +import ai.kilocode.client.session.views.tool.ToolView import ai.kilocode.client.session.views.todo.TodoWriteView import ai.kilocode.rpc.dto.MessageDto import ai.kilocode.rpc.dto.MessageTimeDto @@ -25,8 +26,13 @@ import ai.kilocode.rpc.dto.TodoDto import com.intellij.openapi.Disposable import com.intellij.openapi.util.Disposer import com.intellij.testFramework.fixtures.BasePlatformTestCase +import java.awt.Color +import java.awt.Component import java.awt.Container +import java.awt.event.MouseEvent +import java.awt.image.BufferedImage import javax.swing.JPanel +import javax.swing.border.Border /** * Tests for [SessionMessageListPanel] — structural and index integrity. @@ -537,6 +543,44 @@ class SessionMessageListPanelTest : BasePlatformTestCase() { assertEquals(listOf(".kilo/plans/x.md"), opened) } + fun `test entering a second hoverable part clears stale first hover`() { + model.upsertMessage(msg("a1", "assistant")) + model.updateContent( + "a1", + toolPart( + "tp1", "a1", "question", "call1", state = "completed", + input = mapOf("questions" to """[{"question":"First?"}]"""), + metadata = mapOf("answers" to """[["Yes"]]"""), + ), + ) + model.updateContent( + "a1", + toolPart( + "tp2", "a1", "question", "call2", state = "completed", + input = mapOf("questions" to """[{"question":"Second?"}]"""), + metadata = mapOf("answers" to """[["No"]]"""), + ), + ) + val first = panel.findMessage("a1")!!.part("tp1") as QuestionResultView + val second = panel.findMessage("a1")!!.part("tp2") as QuestionResultView + val firstRoot = root(first) + val secondRoot = root(second) + + first.toggle() + second.toggle() + + enter(header(first)) + assertEquals(SessionUiStyle.View.Surface.headerHoverBgColor().rgb, header(first).background.rgb) + assertLine(firstRoot.border) + + enter(header(second)) + + assertEquals(SessionUiStyle.View.Surface.headerBgColor().rgb, header(first).background.rgb) + assertEquals(SessionUiStyle.View.Surface.headerHoverBgColor().rgb, header(second).background.rgb) + assertLine(firstRoot.border) + assertLine(secondRoot.border) + } + // ------ helpers ------ private fun panelWithPrompts(): SessionMessageListPanel { @@ -610,4 +654,34 @@ class SessionMessageListPanelTest : BasePlatformTestCase() { id = id, sessionID = "ses", messageID = mid, type = "tool", tool = tool, callID = callId, state = state, input = input, metadata = metadata, todos = todos, ) + + private fun root(view: QuestionResultView) = view.components[0] as JPanel + + private fun header(view: QuestionResultView) = root(view).components[0] as JPanel + + private fun enter(component: Component) { + component.dispatchEvent(MouseEvent( + component, + MouseEvent.MOUSE_ENTERED, + System.currentTimeMillis(), + 0, + 1, + 1, + 0, + false, + )) + } + + private fun assertLine(border: Border) { + val image = BufferedImage(5, 5, BufferedImage.TYPE_INT_ARGB) + val item = JPanel() + val graphics = image.createGraphics() + border.paintBorder(item, graphics, 0, 0, image.width, image.height) + graphics.dispose() + val rgb = SessionUiStyle.View.Outline.brightColor().rgb + assertEquals(rgb, Color(image.getRGB(2, 0), true).rgb) + assertEquals(rgb, Color(image.getRGB(0, 2), true).rgb) + assertEquals(rgb, Color(image.getRGB(4, 2), true).rgb) + assertEquals(rgb, Color(image.getRGB(2, 4), true).rgb) + } } diff --git a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/ui/SessionSelectionCopyTest.kt b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/ui/SessionSelectionCopyTest.kt index 0c64f021c9f..a266bc91432 100644 --- a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/ui/SessionSelectionCopyTest.kt +++ b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/ui/SessionSelectionCopyTest.kt @@ -1,7 +1,7 @@ package ai.kilocode.client.session.ui import ai.kilocode.client.session.SessionUiTestBase -import ai.kilocode.client.session.views.ToolView +import ai.kilocode.client.session.views.tool.ToolView import ai.kilocode.rpc.dto.ChatEventDto import ai.kilocode.rpc.dto.PartDto import com.intellij.ide.CopyProvider @@ -47,7 +47,7 @@ class SessionSelectionCopyTest : SessionUiTestBase() { select(two, "bravo") copyProvider()!!.performCopy(DataContext.EMPTY_CONTEXT) - assertNull(one.selectedText) + assertTrue(one.selectedText.isNullOrEmpty()) assertEquals("bravo", CopyPasteManager.getInstance().getContents(DataFlavor.stringFlavor)) } diff --git a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/ui/SessionUiUpdateTest.kt b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/ui/SessionUiUpdateTest.kt index 4d0177f5666..880899b007e 100644 --- a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/ui/SessionUiUpdateTest.kt +++ b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/ui/SessionUiUpdateTest.kt @@ -83,7 +83,7 @@ class SessionUiUpdateTest : BasePlatformTestCase() { model.updateContent("a1", toolPart("t1", "a1", "bash", "running")) model.updateContent("a1", toolPart("t1", "a1", "bash", "completed")) - val tv = panel.findMessage("a1")!!.part("t1") as ai.kilocode.client.session.views.ToolView + val tv = panel.findMessage("a1")!!.part("t1") as ai.kilocode.client.session.views.tool.ToolView assertFalse(tv.labelText().contains("Running")) } @@ -92,7 +92,23 @@ class SessionUiUpdateTest : BasePlatformTestCase() { model.updateContent("a1", toolPart("t1", "a1", "read", "completed")) val tv = panel.findMessage("a1")!!.part("t1") - assertTrue(tv is ai.kilocode.client.session.views.ReadToolView) + assertTrue(tv is ai.kilocode.client.session.views.tool.ReadToolView) + } + + fun `test glob tool renders as GlobToolView`() { + model.upsertMessage(msg("a1", "assistant")) + model.updateContent("a1", toolPart("t1", "a1", "glob", "completed")) + + val tv = panel.findMessage("a1")!!.part("t1") + assertTrue(tv is ai.kilocode.client.session.views.tool.GlobToolView) + } + + fun `test grep tool renders as SearchToolView`() { + model.upsertMessage(msg("a1", "assistant")) + model.updateContent("a1", toolPart("t1", "a1", "grep", "completed")) + + val tv = panel.findMessage("a1")!!.part("t1") + assertTrue(tv is ai.kilocode.client.session.views.tool.SearchToolView) } // ------ multiple turns update correctly ------ diff --git a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/ui/account/SessionAccountOverlayTest.kt b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/ui/account/SessionAccountOverlayTest.kt index ce541a5e719..4aaa851181c 100644 --- a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/ui/account/SessionAccountOverlayTest.kt +++ b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/ui/account/SessionAccountOverlayTest.kt @@ -205,8 +205,8 @@ class SessionAccountOverlayTest : SessionControllerTestBase() { val prof = profile(email = "user@example.com") show(snap(prof)) edt { - assertEquals(SessionUiStyle.View.sessionViewBackground(), panel.panelBackground()) - assertEquals(SessionUiStyle.View.sessionViewOutline(), panel.panelBorderColor()) + assertEquals(SessionUiStyle.AccountPopup.bgColor(), panel.panelBackground()) + assertEquals(SessionUiStyle.AccountPopup.outlineColor(), panel.panelBorderColor()) } } diff --git a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/GlobToolViewTest.kt b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/GlobToolViewTest.kt new file mode 100644 index 00000000000..67c69d9bf8a --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/GlobToolViewTest.kt @@ -0,0 +1,155 @@ +package ai.kilocode.client.session.views + +import ai.kilocode.client.session.model.Tool +import ai.kilocode.client.session.model.ToolExecState +import ai.kilocode.client.session.model.toolKind +import ai.kilocode.client.session.views.base.SecondarySessionPartView +import ai.kilocode.client.session.views.tool.GlobToolView +import ai.kilocode.client.session.views.tool.ReadToolView +import ai.kilocode.client.session.views.tool.ToolView +import ai.kilocode.client.session.ui.style.SessionEditorStyle +import com.intellij.openapi.util.Disposer +import com.intellij.testFramework.fixtures.BasePlatformTestCase +import javax.swing.ScrollPaneConstants + +@Suppress("UnstableApiUsage") +class GlobToolViewTest : BasePlatformTestCase() { + private val views = mutableListOf() + + override fun tearDown() { + try { + views.forEach(Disposer::dispose) + views.clear() + } finally { + super.tearDown() + } + } + + fun `test header renders title directory and pattern rows`() { + val view = GlobToolView(tool().also { + it.input = mapOf("path" to "/repo/src", "pattern" to "**/*.kt") + }) + val base: Any = view + + assertTrue(base is SecondarySessionPartView) + assertTrue(view.labelText().contains("Glob")) + assertEquals(listOf("/repo/src", "pattern=**/*.kt"), view.targetTexts()) + assertTrue(view.targetVisible(1)) + } + + fun `test pattern row hides when pattern is absent`() { + val view = GlobToolView(tool().also { + it.input = mapOf("path" to "/repo/src") + }) + + assertEquals(listOf("/repo/src"), view.targetTexts()) + assertFalse(view.targetVisible(1)) + } + + fun `test repo path displays relative directory`() { + val view = GlobToolView(tool().also { + it.input = mapOf("path" to "/repo/src", "pattern" to "**/*.kt") + }, repo = "/repo") + + assertEquals(listOf("src", "pattern=**/*.kt"), view.targetTexts()) + } + + fun `test repo root directory is hidden`() { + val exact = GlobToolView(tool().also { + it.input = mapOf("path" to "/repo", "pattern" to "**/*.kt") + }, repo = "/repo") + val dot = GlobToolView(tool().also { + it.input = mapOf("path" to ".", "pattern" to "**/*.kt") + }, repo = "/repo") + + assertEquals(listOf("pattern=**/*.kt"), exact.targetTexts()) + assertEquals(listOf("pattern=**/*.kt"), dot.targetTexts()) + assertFalse(exact.targetVisible(1)) + assertFalse(dot.targetVisible(1)) + } + + fun `test outside repo directory stays absolute`() { + val view = GlobToolView(tool().also { + it.input = mapOf("path" to "/other/src", "pattern" to "**/*.kt") + }, repo = "/repo") + + assertEquals(listOf("/other/src", "pattern=**/*.kt"), view.targetTexts()) + } + + fun `test target labels use regular font`() { + val view = GlobToolView(tool().also { + it.input = mapOf("path" to "/repo/src", "pattern" to "**/*.kt") + }) + val style = SessionEditorStyle.current() + + assertEquals(style.regularFont, view.targetFont(0)) + assertEquals(style.regularFont, view.targetFont(1)) + } + + fun `test completed glob starts collapsed and expands output`() { + val view = track(GlobToolView(tool().also { it.output = "/repo/src/A.kt\n/repo/src/B.kt" })) + + assertTrue(view.hasToggle()) + assertFalse(view.isExpanded()) + assertFalse(view.bodyVisible()) + assertEquals("/repo/src/A.kt\n/repo/src/B.kt", view.bodyText()) + + view.toggle() + + assertTrue(view.isExpanded()) + assertTrue(view.bodyVisible()) + assertEquals("/repo/src/A.kt\n/repo/src/B.kt", view.bodyText()) + } + + fun `test glob body is lazy and reused`() { + val view = track(GlobToolView(tool().also { it.output = "/repo/src/A.kt" })) + + assertFalse(view.bodyCreated()) + view.toggle() + val body = view.scrollComponent() + val editor = view.bodyEditor() + assertNotNull(body) + assertNotNull(editor) + assertFalse(view.bodyWrap()) + assertEquals(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED, view.horizontalPolicy()) + assertEquals(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, view.verticalPolicy()) + + view.toggle() + assertFalse(view.bodyVisible()) + view.toggle() + + assertSame(body, view.scrollComponent()) + assertSame(editor, view.bodyEditor()) + assertTrue(view.bodyVisible()) + } + + fun `test collapsed update keeps glob body uncreated`() { + val view = GlobToolView(tool().also { it.output = "/repo/src/A.kt" }) + + view.update(tool().also { it.output = "/repo/src/B.kt" }) + + assertFalse(view.bodyCreated()) + assertEquals("/repo/src/B.kt", view.bodyText()) + } + + fun `test view factory routes glob to glob tool view`() { + assertTrue(ViewFactory.create(tool(), openFile = {}) is GlobToolView) + } + + fun `test should replace when glob renderer changes`() { + val glob = tool() + val read = Tool("p1", "read", toolKind("read")).also { it.state = ToolExecState.COMPLETED } + + assertTrue(ViewFactory.shouldReplace(ReadToolView(read), glob)) + assertTrue(ViewFactory.shouldReplace(ToolView(read), glob)) + assertTrue(ViewFactory.shouldReplace(GlobToolView(glob), read)) + assertFalse(ViewFactory.shouldReplace(GlobToolView(glob), glob)) + } + + private fun tool() = Tool("p1", "glob", toolKind("glob")).also { it.state = ToolExecState.COMPLETED } + + private fun track(view: GlobToolView): GlobToolView { + views.add(view) + return view + } +} diff --git a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/LoginRequiredViewTest.kt b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/LoginRequiredViewTest.kt index 60c65070a37..5f651adcb81 100644 --- a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/LoginRequiredViewTest.kt +++ b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/LoginRequiredViewTest.kt @@ -63,7 +63,7 @@ class LoginRequiredViewTest : BasePlatformTestCase() { val view = LoginRequiredView(openProfile = {}, dismiss = {}) view.show("Sign in required.") val btn = view.openProfileButton() - assertEquals(SessionUiStyle.View.surface(), btn.background) + assertEquals(SessionUiStyle.View.Surface.bgColor(), btn.background) } } diff --git a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/PlanExitViewTest.kt b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/PlanExitViewTest.kt index cc7a2811cf2..93a3d2c173a 100644 --- a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/PlanExitViewTest.kt +++ b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/PlanExitViewTest.kt @@ -3,6 +3,7 @@ package ai.kilocode.client.session.views import ai.kilocode.client.session.model.Tool import ai.kilocode.client.session.model.ToolExecState import ai.kilocode.client.session.model.toolKind +import ai.kilocode.client.session.views.tool.ToolView import com.intellij.testFramework.fixtures.BasePlatformTestCase @Suppress("UnstableApiUsage") diff --git a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/QuestionResultViewTest.kt b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/QuestionResultViewTest.kt index 1d2c8a8e705..5c4bb2947a9 100644 --- a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/QuestionResultViewTest.kt +++ b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/QuestionResultViewTest.kt @@ -6,6 +6,7 @@ import ai.kilocode.client.session.model.toolKind import ai.kilocode.client.session.ui.style.SessionEditorStyle import ai.kilocode.client.session.ui.style.SessionUiStyle import ai.kilocode.client.session.views.question.QuestionResultView +import ai.kilocode.client.session.views.tool.ToolView import com.intellij.testFramework.fixtures.BasePlatformTestCase import java.awt.Color import java.awt.Component @@ -130,7 +131,7 @@ class QuestionResultViewTest : BasePlatformTestCase() { assertFalse("Should be collapsed after second toggle", view.isExpanded()) } - fun `test hover border differs from header fill`() { + fun `test hover only changes header background`() { val view = QuestionResultView(completedTool( input = mapOf("questions" to """[{"question":"Q1"}]"""), metadata = mapOf("answers" to """[["A1"]]"""), @@ -138,12 +139,18 @@ class QuestionResultViewTest : BasePlatformTestCase() { val root = view.node(0) val header = root.node(0) - enter(header) + assertEquals(0, paint(root.border).alpha) + view.toggle() + val body = root.node(1) - assertEquals(SessionUiStyle.View.hoverLine().rgb, paint(root.border).rgb) - assertNotSameColor(SessionUiStyle.View.headerHover(), paint(root.border)) - exit(header) - assertEquals(SessionUiStyle.View.line().rgb, paint(root.border).rgb) + view.setHovered(true) + + assertEquals(SessionUiStyle.View.Surface.headerHoverBgColor().rgb, header.background.rgb) + assertLine(root.border) + assertEquals(SessionUiStyle.View.Outline.brightColor().rgb, paint(body.border).rgb) + view.setHovered(false) + assertEquals(SessionUiStyle.View.Surface.headerBgColor().rgb, header.background.rgb) + assertLine(root.border) } // ------ view factory routing ------ @@ -290,7 +297,17 @@ class QuestionResultViewTest : BasePlatformTestCase() { return Color(image.getRGB(0, 0), true) } - private fun assertNotSameColor(left: Color, right: Color) { - assertFalse("Expected distinct colors but both were ${left.rgb}", left.rgb == right.rgb) + private fun assertLine(border: Border) { + val image = BufferedImage(5, 5, BufferedImage.TYPE_INT_ARGB) + val panel = JPanel() + val graphics = image.createGraphics() + border.paintBorder(panel, graphics, 0, 0, image.width, image.height) + graphics.dispose() + val rgb = SessionUiStyle.View.Outline.brightColor().rgb + assertEquals(rgb, Color(image.getRGB(2, 0), true).rgb) + assertEquals(rgb, Color(image.getRGB(0, 2), true).rgb) + assertEquals(rgb, Color(image.getRGB(4, 2), true).rgb) + assertEquals(rgb, Color(image.getRGB(2, 4), true).rgb) } + } diff --git a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/QuestionViewTest.kt b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/QuestionViewTest.kt index 6efd3d240c1..9305d3114a8 100644 --- a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/QuestionViewTest.kt +++ b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/QuestionViewTest.kt @@ -5,8 +5,10 @@ import ai.kilocode.client.session.model.QuestionItem import ai.kilocode.client.session.model.QuestionOption import ai.kilocode.client.session.ui.style.SessionUiStyle import ai.kilocode.client.session.ui.style.SessionEditorStyle +import ai.kilocode.client.session.views.base.BaseQuestionView import ai.kilocode.client.session.views.question.QuestionView import ai.kilocode.client.ui.HoverIcon +import ai.kilocode.client.ui.UiStyle import ai.kilocode.rpc.dto.QuestionReplyDto import com.intellij.ide.ui.laf.darcula.ui.DarculaButtonUI import com.intellij.testFramework.fixtures.BasePlatformTestCase @@ -15,11 +17,13 @@ import com.intellij.ui.components.JBCheckBox import com.intellij.ui.components.JBLabel import com.intellij.ui.components.JBRadioButton import com.intellij.ui.components.JBTextArea +import java.awt.BorderLayout import java.awt.Component import java.awt.Container import kotlin.math.abs import javax.swing.AbstractButton import javax.swing.JButton +import javax.swing.JComponent import javax.swing.SwingUtilities @Suppress("UnstableApiUsage") @@ -134,6 +138,16 @@ class QuestionViewTest : BasePlatformTestCase() { assertTrue(findAll(view).none { it.text == "1 of 1 questions" && it.isVisible }) } + fun `test single question uses roomy card spacing`() { + view.show(singleSelectQuestion("q_single_spacing")) + + val card = card() + val ins = card.border.getBorderInsets(card) + + assertEquals(UiStyle.Gap.xl(), ins.top) + assertEquals(UiStyle.Gap.pad(), spacer(card).preferredSize.height) + } + fun `test single question submit sends selected answer`() { view.show(singleSelectQuestion("req_2")) @@ -294,6 +308,23 @@ class QuestionViewTest : BasePlatformTestCase() { assertEquals(listOf(listOf("Minimal"), listOf("Unit")), replies.single().second.answers) } + fun `test multi question progress header has top padding`() { + view.show(twoItemQuestion("q_progress_padding")) + + val card = card() + val outer = card.border.getBorderInsets(card) + val summary = findAll(view).first { it.text == "1 of 2 questions" } + val panel = summary.parent as JComponent + val ins = panel.border.getBorderInsets(panel) + + assertEquals(UiStyle.Gap.sm(), outer.top) + assertEquals(0, ins.top) + assertEquals(0, ins.left) + assertEquals(UiStyle.Gap.sm(), ins.bottom) + assertEquals(0, ins.right) + assertEquals(UiStyle.Gap.pad(), spacer(card).preferredSize.height) + } + fun `test multi question uses review before submit`() { view.show(twoItemQuestion("q_review")) @@ -468,8 +499,8 @@ class QuestionViewTest : BasePlatformTestCase() { val dismiss = button(view, "Dismiss") val submit = button(view, "Submit") - assertEquals(SessionUiStyle.View.surface(), dismiss.background) - assertEquals(SessionUiStyle.View.surface(), submit.background) + assertEquals(SessionUiStyle.View.Surface.bgColor(), dismiss.background) + assertEquals(SessionUiStyle.View.Surface.bgColor(), submit.background) } fun `test review submit and back buttons have correct primary state on review page`() { @@ -929,6 +960,13 @@ class QuestionViewTest : BasePlatformTestCase() { private fun text(root: Container, value: String): JBTextArea = findAll(root).first { it.text == value } + private fun card(): BaseQuestionView = findAll(view).distinct().single() + + private fun spacer(card: BaseQuestionView): Component { + val north = (card.layout as BorderLayout).getLayoutComponent(BorderLayout.NORTH) as Container + return north.components.last() + } + private fun layout(root: Container, width: Int = 400) { root.setSize(width, root.preferredSize.height) layoutTree(root) diff --git a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/ReadToolViewTest.kt b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/ReadToolViewTest.kt index a1d27fab1bb..f04fd062a3e 100644 --- a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/ReadToolViewTest.kt +++ b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/ReadToolViewTest.kt @@ -4,6 +4,9 @@ import ai.kilocode.client.session.model.Tool import ai.kilocode.client.session.model.ToolExecState import ai.kilocode.client.session.model.toolKind import ai.kilocode.client.session.views.base.SecondarySessionPartView +import ai.kilocode.client.session.views.tool.GlobToolView +import ai.kilocode.client.session.views.tool.ReadToolView +import ai.kilocode.client.session.views.tool.SearchToolView import ai.kilocode.client.ui.UiStyle import com.intellij.testFramework.fixtures.BasePlatformTestCase import javax.swing.ScrollPaneConstants @@ -85,6 +88,9 @@ class ReadToolViewTest : BasePlatformTestCase() { assertFalse(view.isExpanded()) assertFalse(view.bodyVisible()) assertEquals("file contents", view.bodyText()) + assertTrue(view.bodyCreated()) + assertTrue(view.bodyWrap()) + assertNull(view.bodyEditor()) assertEquals(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER, view.horizontalPolicy()) view.toggle() @@ -95,8 +101,8 @@ class ReadToolViewTest : BasePlatformTestCase() { fun `test view factory routes read kind tools to read tool view`() { assertTrue(ViewFactory.create(tool(), openFile = {}) is ReadToolView) - assertTrue(ViewFactory.create(Tool("p2", "grep", toolKind("grep")), openFile = {}) is ReadToolView) - assertTrue(ViewFactory.create(Tool("p3", "glob", toolKind("glob")), openFile = {}) is ReadToolView) + assertTrue(ViewFactory.create(Tool("p2", "grep", toolKind("grep")), openFile = {}) is SearchToolView) + assertTrue(ViewFactory.create(Tool("p3", "glob", toolKind("glob")), openFile = {}) is GlobToolView) } fun `test canRender matches read kind tools only`() { diff --git a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/ReasoningViewStressTest.kt b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/ReasoningViewStressTest.kt new file mode 100644 index 00000000000..d9f1ac10f19 --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/ReasoningViewStressTest.kt @@ -0,0 +1,63 @@ +package ai.kilocode.client.session.views + +import ai.kilocode.client.session.model.Reasoning +import com.intellij.openapi.editor.EditorFactory +import com.intellij.openapi.util.Disposer +import com.intellij.testFramework.fixtures.BasePlatformTestCase +import com.intellij.ui.EditorTextField +import com.intellij.ui.components.JBHtmlPane +import com.intellij.ui.components.JBScrollPane +import com.intellij.util.ui.UIUtil +import java.awt.Container +import javax.swing.JPanel + +@Suppress("UnstableApiUsage") +class ReasoningViewStressTest : BasePlatformTestCase() { + + fun `test streaming reasoning retains markdown body and disposes editors`() { + val base = EditorFactory.getInstance().allEditors.size + val view = ReasoningView(reasoning("r1", done = false, text = "intro\n\n```kotlin\n")) + val component = view.md.component + val scroll = scrolls(view).first() + val editor = editors(view).single() + val count = panel(view).componentCount + editor.getEditor(true) + + repeat(150) { i -> view.appendDelta("val x$i = $i\n") } + + assertSame(component, view.md.component) + assertSame(scroll, scrolls(view).first()) + assertSame(editor, editors(view).single()) + assertEquals(1, editors(view).size) + assertTrue(htmls(view).size <= 1) + assertEquals(count, panel(view).componentCount) + + view.update(reasoning("r1", done = true, text = view.markdown() + "```")) + assertTrue(view.bodyVisible()) + Disposer.dispose(view) + drainEdt() + + assertEquals(base, EditorFactory.getInstance().allEditors.size) + } + + private fun reasoning(id: String, done: Boolean, text: String) = Reasoning(id).also { + it.done = done + it.content.append(text) + } + + private fun panel(view: ReasoningView): JPanel = view.md.component as JPanel + + private fun scrolls(view: ReasoningView) = descendants(view).filterIsInstance() + + private fun htmls(view: ReasoningView) = descendants(view).filterIsInstance() + + private fun editors(view: ReasoningView) = descendants(view).filterIsInstance() + + private fun descendants(root: Container): List = root.components.flatMap { child -> + listOf(child) + ((child as? Container)?.let(::descendants) ?: emptyList()) + } + + private fun drainEdt() { + UIUtil.dispatchAllInvocationEvents() + } +} diff --git a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/ReasoningViewTest.kt b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/ReasoningViewTest.kt index 2019e30a4e9..c09062ec808 100644 --- a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/ReasoningViewTest.kt +++ b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/ReasoningViewTest.kt @@ -2,8 +2,15 @@ package ai.kilocode.client.session.views import ai.kilocode.client.session.model.Reasoning import ai.kilocode.client.session.ui.style.SessionEditorStyle +import ai.kilocode.client.session.ui.style.SessionUiStyle import ai.kilocode.client.session.views.base.SecondarySessionPartView import com.intellij.testFramework.fixtures.BasePlatformTestCase +import com.intellij.ui.components.JBScrollPane +import com.intellij.util.ui.JBUI +import com.intellij.util.ui.UIUtil +import java.awt.Component +import java.awt.Container +import javax.swing.JPanel import javax.swing.ScrollPaneConstants @Suppress("UnstableApiUsage") @@ -33,15 +40,16 @@ class ReasoningViewTest : BasePlatformTestCase() { assertTrue(view.bodyCreated()) } - fun `test streaming reasoning is collapsed by default`() { + fun `test streaming reasoning is expanded by default`() { val view = ReasoningView(reasoning("p1", done = false, text = "one\ntwo\nthree\nfour")) - assertFalse(view.isExpanded()) + assertTrue(view.isExpanded()) assertTrue(view.hasToggle()) + assertTrue(view.bodyVisible()) } fun `test update to done preserves collapsed reasoning`() { - val view = ReasoningView(reasoning("p1", done = false, text = "one\ntwo\nthree\nfour")) + val view = ReasoningView(reasoning("p1", done = true, text = "one\ntwo\nthree\nfour")) view.update(reasoning("p1", done = true, text = "one\ntwo\nthree\nfour")) @@ -49,6 +57,29 @@ class ReasoningViewTest : BasePlatformTestCase() { assertEquals("one\ntwo\nthree\nfour", view.markdown()) } + fun `test live reasoning stays expanded when marked done`() { + val view = ReasoningView(reasoning("p1", done = false, text = "one\ntwo\nthree\nfour")) + + assertTrue(view.isExpanded()) + + view.update(reasoning("p1", done = true, text = "one\ntwo\nthree\nfour")) + + assertTrue(view.isExpanded()) + assertTrue(view.bodyVisible()) + assertTrue(view.bodyCreated()) + } + + fun `test manually expanded finished reasoning stays open on update`() { + val view = ReasoningView(reasoning("p1", done = true, text = "one\ntwo")) + + view.toggle() + view.update(reasoning("p1", done = true, text = "one\ntwo\nthree")) + + assertTrue(view.isExpanded()) + assertTrue(view.bodyVisible()) + assertEquals("one\ntwo\nthree", view.markdown()) + } + fun `test toggle opens and closes reasoning`() { val view = ReasoningView(reasoning("p1", done = true, text = "one\ntwo\nthree\nfour")) @@ -59,7 +90,7 @@ class ReasoningViewTest : BasePlatformTestCase() { } fun `test collapsed reasoning stays collapsed on update`() { - val view = ReasoningView(reasoning("p1", done = false, text = "one\ntwo")) + val view = ReasoningView(reasoning("p1", done = true, text = "one\ntwo")) view.update(reasoning("p1", done = true, text = "one\ntwo\nthree")) assertFalse(view.isExpanded()) @@ -72,22 +103,24 @@ class ReasoningViewTest : BasePlatformTestCase() { view.appendDelta("b") assertEquals("ab", view.markdown()) - assertFalse(view.isExpanded()) + assertTrue(view.isExpanded()) } - fun `test blank reasoning stays collapsed when delta arrives`() { + fun `test blank streaming reasoning opens when delta arrives`() { val view = ReasoningView(reasoning("p1", done = false, text = "")) + assertFalse(view.isVisible) view.appendDelta("b") assertEquals("b", view.markdown()) - assertFalse(view.bodyCreated()) - assertFalse(view.bodyVisible()) + assertTrue(view.isVisible) + assertTrue(view.bodyCreated()) + assertTrue(view.bodyVisible()) assertTrue(view.hasToggle()) } - fun `test collapsed append keeps lazy reasoning body uncreated`() { - val view = ReasoningView(reasoning("p1", done = false, text = "a")) + fun `test collapsed completed append keeps lazy reasoning body uncreated`() { + val view = ReasoningView(reasoning("p1", done = true, text = "a")) view.appendDelta("b") @@ -96,10 +129,10 @@ class ReasoningViewTest : BasePlatformTestCase() { assertFalse(view.bodyVisible()) } - fun `test collapsed update keeps lazy reasoning body uncreated`() { - val view = ReasoningView(reasoning("p1", done = false, text = "a")) + fun `test collapsed completed update keeps lazy reasoning body uncreated`() { + val view = ReasoningView(reasoning("p1", done = true, text = "a")) - view.update(reasoning("p1", done = false, text = "abc")) + view.update(reasoning("p1", done = true, text = "abc")) assertEquals("abc", view.markdown()) assertFalse(view.bodyCreated()) @@ -107,7 +140,7 @@ class ReasoningViewTest : BasePlatformTestCase() { } fun `test reasoning creates lazy markdown body once`() { - val view = ReasoningView(reasoning("p1", done = false, text = "one")) + val view = ReasoningView(reasoning("p1", done = true, text = "one")) view.toggle() val component = view.md.component @@ -121,6 +154,7 @@ class ReasoningViewTest : BasePlatformTestCase() { fun `test blank reasoning has no toggle`() { val view = ReasoningView(reasoning("p1", done = true, text = "")) + assertFalse(view.isVisible) assertFalse(view.isExpanded()) assertFalse(view.hasToggle()) } @@ -158,10 +192,60 @@ class ReasoningViewTest : BasePlatformTestCase() { fun `test expanded reasoning body is capped to five rows`() { val view = ReasoningView(reasoning("p1", done = false, text = (1..20).joinToString("\n") { "line $it" })) - view.toggle() + val taller = ReasoningView(reasoning("p2", done = false, text = (1..200).joinToString("\n") { "line $it" })) assertEquals(5, view.bodyMaxRows()) assertTrue(view.preferredSize.height > 0) + assertEquals(view.preferredSize.height, taller.preferredSize.height) + } + + fun `test appended reasoning scrolls nested body to bottom`() { + val view = ReasoningView(reasoning("p1", done = false, text = (1..20).joinToString("\n") { "line $it" })) + view.setSize(300, 80) + view.doLayout() + + view.appendDelta("\nline 21\nline 22") + UIUtil.dispatchAllInvocationEvents() + + assertEquals(view.bodyScrollBottom(), view.bodyScrollValue()) + } + + fun `test appended reasoning does not yank user scrolled above tail`() { + val view = ReasoningView(reasoning("p1", done = false, text = (1..40).joinToString("\n") { "line $it" })) + view.setSize(300, 80) + view.doLayout() + UIUtil.dispatchAllInvocationEvents() + val scroll = scroll(view) + scroll.verticalScrollBar.value = 0 + + view.appendDelta("\nline 41\nline 42") + UIUtil.dispatchAllInvocationEvents() + + assertEquals(0, scroll.verticalScrollBar.value) + } + + fun `test reasoning block uses vertical separator`() { + val view = ReasoningView(reasoning("p1", done = true, text = "one")) + + assertEquals(1, view.border!!.getBorderInsets(view).left) + + view.toggle() + + val insets = view.border!!.getBorderInsets(view) + assertEquals(0, insets.top) + assertEquals(1, insets.left) + assertEquals(0, insets.bottom) + assertEquals(0, insets.right) + assertEquals(SessionUiStyle.View.Reasoning.BODY_LINES, view.bodyMaxRows()) + } + + fun `test reasoning toggle uses shared right rail`() { + val view = ReasoningView(reasoning("p1", done = true, text = "one")) + val row = view.components.single() as JPanel + val insets = row.border.getBorderInsets(row) + + assertEquals(JBUI.scale(SessionUiStyle.View.Layout.HORIZONTAL_PADDING), insets.left) + assertEquals(JBUI.scale(SessionUiStyle.View.Layout.HORIZONTAL_PADDING), insets.right) } fun `test link opens url callback`() { @@ -190,4 +274,15 @@ class ReasoningViewTest : BasePlatformTestCase() { it.done = done it.content.append(text) } + + private fun scroll(component: Component): JBScrollPane { + if (component is JBScrollPane) return component + if (component is Container) { + component.components.forEach { child -> + val scroll = runCatching { scroll(child) }.getOrNull() + if (scroll != null) return scroll + } + } + error("scroll not found") + } } diff --git a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/SearchToolViewTest.kt b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/SearchToolViewTest.kt new file mode 100644 index 00000000000..eea06ce279f --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/SearchToolViewTest.kt @@ -0,0 +1,196 @@ +package ai.kilocode.client.session.views + +import ai.kilocode.client.session.model.Tool +import ai.kilocode.client.session.model.ToolExecState +import ai.kilocode.client.session.model.toolKind +import ai.kilocode.client.session.ui.style.SessionEditorStyle +import ai.kilocode.client.session.views.base.SecondarySessionPartView +import ai.kilocode.client.session.views.tool.GlobToolView +import ai.kilocode.client.session.views.tool.ReadToolView +import ai.kilocode.client.session.views.tool.SearchToolView +import ai.kilocode.client.session.views.tool.ToolView +import com.intellij.openapi.util.Disposer +import com.intellij.testFramework.fixtures.BasePlatformTestCase +import java.awt.Container +import java.awt.Dimension +import javax.swing.ScrollPaneConstants + +@Suppress("UnstableApiUsage") +class SearchToolViewTest : BasePlatformTestCase() { + private val views = mutableListOf() + + override fun tearDown() { + try { + views.forEach(Disposer::dispose) + views.clear() + } finally { + super.tearDown() + } + } + + fun `test header renders title pattern and include targets`() { + val view = SearchToolView(tool().also { + it.input = mapOf("pattern" to "class SearchToolView", "include" to "*.{kt,kts}") + }) + val base: Any = view + + assertTrue(base is SecondarySessionPartView) + assertTrue(view.labelText().contains("Search")) + assertEquals(listOf("pattern=class SearchToolView", "include=*.{kt,kts}"), view.targetTexts()) + assertTrue(view.targetVisible(0)) + assertTrue(view.targetVisible(1)) + assertFalse(view.targetVisible(2)) + } + + fun `test header includes optional path target`() { + val view = SearchToolView(tool().also { + it.input = mapOf("path" to "/repo/src", "pattern" to "TODO", "include" to "*.kt") + }) + + assertEquals(listOf("/repo/src", "pattern=TODO", "include=*.kt"), view.targetTexts()) + } + + fun `test repo path displays relative search target`() { + val view = SearchToolView(tool().also { + it.input = mapOf("path" to "/repo/src", "pattern" to "TODO", "include" to "*.kt") + }, repo = "/repo") + + assertEquals(listOf("src", "pattern=TODO", "include=*.kt"), view.targetTexts()) + } + + fun `test repo root search path is hidden`() { + val exact = SearchToolView(tool().also { + it.input = mapOf("path" to "/repo", "pattern" to "TODO", "include" to "*.kt") + }, repo = "/repo") + val dot = SearchToolView(tool().also { + it.input = mapOf("path" to ".", "pattern" to "TODO", "include" to "*.kt") + }, repo = "/repo") + + assertEquals(listOf("pattern=TODO", "include=*.kt"), exact.targetTexts()) + assertEquals(listOf("pattern=TODO", "include=*.kt"), dot.targetTexts()) + assertTrue(exact.targetVisible(0)) + assertFalse(exact.targetVisible(2)) + assertTrue(dot.targetVisible(0)) + assertFalse(dot.targetVisible(2)) + } + + fun `test outside repo search path stays absolute`() { + val view = SearchToolView(tool().also { + it.input = mapOf("path" to "/other/src", "pattern" to "TODO", "include" to "*.kt") + }, repo = "/repo") + + assertEquals(listOf("/other/src", "pattern=TODO", "include=*.kt"), view.targetTexts()) + } + + fun `test target labels use plain text for clipping`() { + val view = SearchToolView(tool().also { + it.input = mapOf("pattern" to "", "include" to "*.kt") + }) + + assertEquals("pattern=", view.targetComponents().first().text) + } + + fun `test target labels use regular font`() { + val view = SearchToolView(tool().also { + it.input = mapOf("pattern" to "TODO", "include" to "*.kt") + }) + val style = SessionEditorStyle.current() + + assertEquals(style.regularFont, view.targetFont(0)) + assertEquals(style.regularFont, view.targetFont(1)) + } + + fun `test completed search starts collapsed and expands output`() { + val view = track(SearchToolView(tool().also { it.output = "src/A.kt:1:class A" })) + + assertTrue(view.hasToggle()) + assertFalse(view.isExpanded()) + assertFalse(view.bodyVisible()) + assertEquals("src/A.kt:1:class A", view.bodyText()) + + view.toggle() + + assertTrue(view.isExpanded()) + assertTrue(view.bodyVisible()) + assertEquals("src/A.kt:1:class A", view.bodyText()) + } + + fun `test search body is lazy and reused`() { + val view = track(SearchToolView(tool().also { it.output = "src/A.kt" })) + + assertFalse(view.bodyCreated()) + view.toggle() + val body = view.scrollComponent() + val editor = view.bodyEditor() + assertNotNull(body) + assertNotNull(editor) + assertFalse(view.bodyWrap()) + assertEquals(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED, view.horizontalPolicy()) + assertEquals(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, view.verticalPolicy()) + + view.toggle() + assertFalse(view.bodyVisible()) + view.toggle() + + assertSame(body, view.scrollComponent()) + assertSame(editor, view.bodyEditor()) + assertTrue(view.bodyVisible()) + } + + fun `test collapsed update keeps search body uncreated`() { + val view = SearchToolView(tool().also { it.output = "src/A.kt" }) + + view.update(tool().also { it.output = "src/B.kt" }) + + assertFalse(view.bodyCreated()) + assertEquals("src/B.kt", view.bodyText()) + } + + fun `test long targets stay horizontal and do not force header wider`() { + val view = SearchToolView(tool().also { + it.input = mapOf( + "pattern" to "a".repeat(200), + "include" to "**/*.${"b".repeat(200)}.kt", + ) + }) + val header = view.headerComponent() + header.setSize(Dimension(240, header.preferredSize.height)) + + layout(header) + + assertTrue(view.centerComponent().width <= header.width) + val labels = view.targetComponents().filter { it.isVisible } + assertEquals(labels.first().y, labels.last().y) + labels.forEach { + assertTrue(it.width <= view.centerComponent().width) + } + } + + fun `test view factory routes grep to search tool view`() { + assertTrue(ViewFactory.create(tool(), openFile = {}) is SearchToolView) + } + + fun `test should replace when search renderer changes`() { + val search = tool() + val read = Tool("p1", "read", toolKind("read")).also { it.state = ToolExecState.COMPLETED } + val glob = Tool("p2", "glob", toolKind("glob")).also { it.state = ToolExecState.COMPLETED } + + assertTrue(ViewFactory.shouldReplace(ReadToolView(read), search)) + assertTrue(ViewFactory.shouldReplace(ToolView(read), search)) + assertTrue(ViewFactory.shouldReplace(SearchToolView(search), read)) + assertTrue(ViewFactory.shouldReplace(GlobToolView(glob, selection = null), search)) + assertFalse(ViewFactory.shouldReplace(SearchToolView(search), search)) + } + + private fun layout(root: Container) { + root.doLayout() + root.components.filterIsInstance().forEach { layout(it) } + } + + private fun tool() = Tool("p1", "grep", toolKind("grep")).also { it.state = ToolExecState.COMPLETED } + + private fun track(view: SearchToolView): SearchToolView { + views.add(view) + return view + } +} diff --git a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/ToolBodyStressTest.kt b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/ToolBodyStressTest.kt new file mode 100644 index 00000000000..3b5171f4f3a --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/ToolBodyStressTest.kt @@ -0,0 +1,71 @@ +package ai.kilocode.client.session.views + +import ai.kilocode.client.session.model.Tool +import ai.kilocode.client.session.model.ToolExecState +import ai.kilocode.client.session.model.toolKind +import ai.kilocode.client.session.views.tool.GlobToolView +import ai.kilocode.client.session.views.tool.SearchToolView +import ai.kilocode.client.session.views.tool.ToolView +import com.intellij.openapi.editor.EditorFactory +import com.intellij.openapi.util.Disposer +import com.intellij.testFramework.fixtures.BasePlatformTestCase +import com.intellij.util.ui.UIUtil + +@Suppress("UnstableApiUsage") +class ToolBodyStressTest : BasePlatformTestCase() { + + fun `test expanded tool body editors are disposed after churn`() { + val base = EditorFactory.getInstance().allEditors.size + + repeat(60) { i -> + val view = ToolView(tool(i)) + view.toggle() + view.bodyEditor()?.getEditor(true) + Disposer.dispose(view) + } + drainEdt() + + assertEquals(base, EditorFactory.getInstance().allEditors.size) + } + + fun `test expanded search tool editors are disposed after churn`() { + val base = EditorFactory.getInstance().allEditors.size + + repeat(60) { i -> + val search = SearchToolView(search(i)) + search.toggle() + search.bodyEditor()?.getEditor(true) + Disposer.dispose(search) + + val glob = GlobToolView(glob(i)) + glob.toggle() + glob.bodyEditor()?.getEditor(true) + Disposer.dispose(glob) + } + drainEdt() + + assertEquals(base, EditorFactory.getInstance().allEditors.size) + } + + private fun tool(index: Int) = Tool("p$index", "bash", toolKind("bash")).also { + it.state = ToolExecState.COMPLETED + it.input = mapOf("command" to "log $index") + it.output = (1..20).joinToString("\n") { line -> "line $index/$line" } + } + + private fun search(index: Int) = Tool("s$index", "grep", toolKind("grep")).also { + it.state = ToolExecState.COMPLETED + it.input = mapOf("path" to "src", "pattern" to "needle$index", "include" to "*.kt") + it.output = (1..20).joinToString("\n") { line -> "src/File$line.kt: needle$index" } + } + + private fun glob(index: Int) = Tool("g$index", "glob", toolKind("glob")).also { + it.state = ToolExecState.COMPLETED + it.input = mapOf("path" to "src", "pattern" to "**/*$index.kt") + it.output = (1..20).joinToString("\n") { line -> "src/File$line.kt" } + } + + private fun drainEdt() { + UIUtil.dispatchAllInvocationEvents() + } +} diff --git a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/ToolViewTest.kt b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/ToolViewTest.kt index 44121d61e17..1de7afe7eeb 100644 --- a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/ToolViewTest.kt +++ b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/ToolViewTest.kt @@ -7,14 +7,30 @@ import ai.kilocode.client.session.model.toolKind import ai.kilocode.client.session.ui.style.SessionEditorStyle import ai.kilocode.client.session.ui.style.SessionUiStyle import ai.kilocode.client.session.views.base.SecondarySessionPartView +import ai.kilocode.client.session.views.tool.ToolView +import com.intellij.openapi.util.Disposer import com.intellij.testFramework.fixtures.BasePlatformTestCase +import java.awt.Color +import java.awt.image.BufferedImage +import javax.swing.JPanel import javax.swing.ScrollPaneConstants +import javax.swing.border.Border /** * Tests for [ToolView]. */ @Suppress("UnstableApiUsage") class ToolViewTest : BasePlatformTestCase() { + private val views = mutableListOf() + + override fun tearDown() { + try { + views.forEach(Disposer::dispose) + views.clear() + } finally { + super.tearDown() + } + } // ---- state icons ------ @@ -47,14 +63,14 @@ class ToolViewTest : BasePlatformTestCase() { fun `test title shown instead of name when title is set`() { val t = Tool("p1", "bash", toolKind("bash")).also { it.state = ToolExecState.RUNNING; it.title = "Install deps" } - val view = ToolView(t) + val view = track(ToolView(t)) assertTrue(view.labelText().contains("Install deps")) assertTrue(view.labelText().contains("Shell")) } fun `test blank title falls back to tool name`() { val t = Tool("p1", "bash", toolKind("bash")).also { it.state = ToolExecState.COMPLETED; it.title = " " } - val view = ToolView(t) + val view = track(ToolView(t)) assertTrue(view.labelText().contains("Shell")) } @@ -64,7 +80,7 @@ class ToolViewTest : BasePlatformTestCase() { it.output = "origin git@example.com:repo.git" } - val view = ToolView(t) + val view = track(ToolView(t)) assertTrue(view.labelText().contains("Shell")) assertTrue(view.labelText().contains("View remotes")) @@ -94,12 +110,25 @@ class ToolViewTest : BasePlatformTestCase() { assertTrue(base is SecondarySessionPartView) } + fun `test tool outline is drawn only while expanded`() { + val view = track(ToolView(tool("p1", "bash", ToolExecState.COMPLETED).also { + it.input = mapOf("command" to "pwd") + it.output = "/tmp" + })) + + assertEquals(0, paint(view.border).alpha) + view.toggle() + assertEquals(SessionUiStyle.View.Outline.color().rgb, paint(view.border).rgb) + view.toggle() + assertEquals(0, paint(view.border).alpha) + } + fun `test bash toggle collapses and expands`() { val t = tool("p1", "bash", ToolExecState.COMPLETED).also { it.input = mapOf("command" to "git log") it.output = "one\ntwo\nthree\nfour" } - val view = ToolView(t) + val view = track(ToolView(t)) assertFalse(view.isExpanded()) view.toggle() @@ -113,7 +142,7 @@ class ToolViewTest : BasePlatformTestCase() { it.input = mapOf("command" to "git log") it.output = "one\ntwo\nthree\nfour" } - val view = ToolView(t) + val view = track(ToolView(t)) assertEquals("$ git log\n\none\ntwo\nthree\nfour", view.bodyText()) assertTrue(view.hasToggle()) @@ -127,23 +156,24 @@ class ToolViewTest : BasePlatformTestCase() { it.input = mapOf("command" to "pwd") it.output = "/tmp" } - val view = ToolView(t) + val view = track(ToolView(t)) assertFalse(view.bodyCreated()) view.toggle() - val font = view.bodyFont() + val body = view.bodyEditor() + assertNotNull(body) view.toggle() view.toggle() - assertSame(font, view.bodyFont()) + assertSame(body, view.bodyEditor()) assertTrue(view.bodyVisible()) } fun `test collapsed update keeps lazy tool body uncreated`() { - val view = ToolView(tool("p1", "bash", ToolExecState.RUNNING).also { + val view = track(ToolView(tool("p1", "bash", ToolExecState.RUNNING).also { it.input = mapOf("command" to "pwd") it.output = "/tmp" - }) + })) view.update(tool("p1", "bash", ToolExecState.COMPLETED).also { it.input = mapOf("command" to "pwd") @@ -155,10 +185,10 @@ class ToolViewTest : BasePlatformTestCase() { } fun `test collapsed update after first expand reuses tool body text`() { - val view = ToolView(tool("p1", "bash", ToolExecState.RUNNING).also { + val view = track(ToolView(tool("p1", "bash", ToolExecState.RUNNING).also { it.input = mapOf("command" to "pwd") it.output = "/tmp" - }) + })) view.toggle() view.toggle() @@ -177,7 +207,7 @@ class ToolViewTest : BasePlatformTestCase() { it.input = mapOf("command" to "pwd") it.output = "/tmp" } - val view = ToolView(t) + val view = track(ToolView(t)) assertFalse(view.isExpanded()) assertTrue(view.hasToggle()) @@ -191,7 +221,7 @@ class ToolViewTest : BasePlatformTestCase() { it.input = mapOf("path" to "/tmp", "pattern" to "**/*.kt") it.output = "/tmp/A.kt" } - val view = ToolView(t) + val view = track(ToolView(t)) assertTrue(view.labelText().contains("Glob")) assertTrue(view.labelText().contains("/tmp")) @@ -205,18 +235,21 @@ class ToolViewTest : BasePlatformTestCase() { fun `test bash output uses editor font settings`() { val style = SessionEditorStyle.current() - val view = ToolView(tool("p1", "bash", ToolExecState.COMPLETED)) + val view = track(ToolView(tool("p1", "bash", ToolExecState.COMPLETED).also { it.output = "done" })) + view.toggle() - assertEditorFont(view.bodyFont(), style) + assertCodeFont(view.bodyFont(), style) assertFalse(view.bodyEditable()) assertFalse(view.bodyCaretVisible()) - assertTrue(view.bodyWrap()) - assertEquals(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER, view.horizontalPolicy()) + assertFalse(view.bodyWrap()) + assertNotNull(view.bodyEditor()) + assertEquals(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED, view.horizontalPolicy()) + assertEquals(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, view.verticalPolicy()) } fun `test tool header uses editor-derived fonts`() { val style = SessionEditorStyle.current() - val view = ToolView(tool("p1", "bash", ToolExecState.COMPLETED)) + val view = track(ToolView(tool("p1", "bash", ToolExecState.COMPLETED).also { it.output = "done" })) assertEditorFont(view.titleFont(), style) assertTrue(view.titleFont().isBold) @@ -227,10 +260,13 @@ class ToolViewTest : BasePlatformTestCase() { fun `test applyStyle updates tool fonts in place`() { val view = ToolView(tool("p1", "bash", ToolExecState.COMPLETED)) val style = SessionEditorStyle.create(family = "Courier New", size = 25) + view.toggle() + val editor = view.bodyEditor() view.applyStyle(style) - assertEditorFont(view.bodyFont(), style) + assertSame(editor, view.bodyEditor()) + assertCodeFont(view.bodyFont(), style) assertEditorFont(view.titleFont(), style) assertTrue(view.titleFont().isBold) assertSmallEditorFont(view.subtitleFont(), style) @@ -243,7 +279,7 @@ class ToolViewTest : BasePlatformTestCase() { it.output = "/tmp" } - val view = ToolView(t) + val view = track(ToolView(t)) assertEquals(1, view.controlCount()) } @@ -253,7 +289,7 @@ class ToolViewTest : BasePlatformTestCase() { it.input = mapOf("command" to "log") it.output = (1..40).joinToString("\n") { line -> "line $line" } } - val view = ToolView(t) + val view = track(ToolView(t)) view.toggle() @@ -268,7 +304,7 @@ class ToolViewTest : BasePlatformTestCase() { it.output = out } - val view = ToolView(t) + val view = track(ToolView(t)) view.toggle() assertEquals("$ log\n\n$out", view.bodyText()) @@ -282,7 +318,7 @@ class ToolViewTest : BasePlatformTestCase() { it.output = out } - val view = ToolView(t) + val view = track(ToolView(t)) view.toggle() assertEquals(out, view.bodyText()) @@ -325,13 +361,32 @@ class ToolViewTest : BasePlatformTestCase() { private fun tool(id: String, name: String, state: ToolExecState, title: String? = null): Tool = Tool(id, name, toolKind(name)).also { it.state = state; it.title = title } + private fun track(view: ToolView): ToolView { + views.add(view) + return view + } + private fun assertEditorFont(font: java.awt.Font, style: SessionEditorStyle) { assertEquals(style.transcriptFont.name, font.name) assertEquals(style.editorSize, font.size) } + private fun assertCodeFont(font: java.awt.Font, style: SessionEditorStyle) { + assertEquals(style.editorFont.name, font.name) + assertEquals(style.editorSize, font.size) + } + private fun assertSmallEditorFont(font: java.awt.Font, style: SessionEditorStyle) { assertEquals(style.smallEditorFont.name, font.name) assertTrue(font.size < style.editorSize) } + + private fun paint(border: Border): Color { + val image = BufferedImage(3, 3, BufferedImage.TYPE_INT_ARGB) + val item = JPanel() + val graphics = image.createGraphics() + border.paintBorder(item, graphics, 0, 0, image.width, image.height) + graphics.dispose() + return Color(image.getRGB(0, 0), true) + } } diff --git a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/TurnViewTest.kt b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/TurnViewTest.kt index 5536843a8a5..7a03cb52083 100644 --- a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/TurnViewTest.kt +++ b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/TurnViewTest.kt @@ -188,6 +188,75 @@ class TurnViewTest : BasePlatformTestCase() { assertEquals("hello world", view.markdown()) } + fun `test consecutive reasoning parts reuse one view`() { + val message = msg("a1", "assistant") + message.parts["r1"] = reasoning("r1", "first ") + message.parts["r2"] = reasoning("r2", "second") + + val mv = MessageView(message, openFile) + + assertEquals(listOf("r1"), mv.partIds()) + assertSame(mv.part("r1"), mv.part("r2")) + assertEquals("first second", (mv.part("r1") as ReasoningView).markdown()) + } + + fun `test delta for aliased reasoning appends to reused view`() { + val message = msg("a1", "assistant") + message.parts["r1"] = reasoning("r1", "first ") + message.parts["r2"] = reasoning("r2", "second") + val mv = MessageView(message, openFile) + + assertTrue(mv.appendDelta("r2", " third")) + + assertEquals("first second third", (mv.part("r1") as ReasoningView).markdown()) + } + + fun `test reasoning alias maps stay bounded across churn`() { + val mv = MessageView(msg("a1", "assistant"), openFile) + + repeat(100) { i -> + mv.upsertPart(reasoning("r${i}a", "first $i ")) + mv.upsertPart(reasoning("r${i}b", "second $i")) + + assertEquals(listOf("r${i}a"), mv.partIds()) + assertSame(mv.part("r${i}a"), mv.part("r${i}b")) + assertEquals(1, aliasSize(mv)) + assertEquals(1, sourceSize(mv)) + assertEquals(1, mv.componentCount) + + mv.removePart("r${i}b") + mv.removePart("r${i}a") + + assertTrue(mv.partIds().isEmpty()) + assertEquals(0, aliasSize(mv)) + assertEquals(0, sourceSize(mv)) + assertEquals(0, mv.componentCount) + } + } + + fun `test text between reasoning parts keeps separate views`() { + val message = msg("a1", "assistant") + message.parts["r1"] = reasoning("r1", "first") + message.parts["t1"] = text("t1", "middle") + message.parts["r2"] = reasoning("r2", "second") + + val mv = MessageView(message, openFile) + + assertEquals(listOf("r1", "t1", "r2"), mv.partIds()) + assertNotSame(mv.part("r1"), mv.part("r2")) + } + + fun `test blank reasoning part is invisible`() { + val message = msg("a1", "assistant") + message.parts["r1"] = reasoning("r1", "") + message.parts["t1"] = text("t1", "middle") + + val mv = MessageView(message, openFile) + + assertFalse(mv.part("r1")!!.isVisible) + assertTrue(mv.part("t1")!!.isVisible) + } + fun `test appendDelta for unknown part id is noop`() { val mv = MessageView(msg("a1", "assistant"), openFile) // Must not throw @@ -226,7 +295,7 @@ class TurnViewTest : BasePlatformTestCase() { fun `test assistant card parts use shared compact gap`() { val message = msg("a1", "assistant") - val reasoning = Reasoning("r1") + val reasoning = reasoning("r1", "thinking") val tool = Tool("t1", "read", toolKind("read")).also { it.state = ToolExecState.COMPLETED } message.parts["r1"] = reasoning message.parts["t1"] = tool @@ -263,6 +332,23 @@ class TurnViewTest : BasePlatformTestCase() { private fun msg(id: String, role: String): Message = Message(MessageDto(id = id, sessionID = "ses", role = role, time = MessageTimeDto(0.0))) + private fun reasoning(id: String, content: String) = Reasoning(id).also { + it.done = false + it.content.append(content) + } + + private fun text(id: String, content: String) = Text(id).also { it.content.append(content) } + + private fun aliasSize(view: MessageView) = mapSize(view, "aliases") + + private fun sourceSize(view: MessageView) = mapSize(view, "sources") + + private fun mapSize(view: MessageView, name: String): Int { + val field = MessageView::class.java.getDeclaredField(name) + field.isAccessible = true + return (field.get(view) as Map<*, *>).size + } + private class TrackingRepaintManager(private val watched: Set) : RepaintManager() { val dirty = mutableListOf() val invalid = mutableListOf() diff --git a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/base/AbstractSessionPartViewTest.kt b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/base/AbstractSessionPartViewTest.kt index 523087c7a22..bc8e1e9ed18 100644 --- a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/base/AbstractSessionPartViewTest.kt +++ b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/base/AbstractSessionPartViewTest.kt @@ -69,21 +69,25 @@ class AbstractSessionPartViewTest : BasePlatformTestCase() { assertNull(content.parent) } - fun `test header hover is subtler than hover outline`() { - assertNotSameColor(SessionUiStyle.View.headerHover(), SessionUiStyle.View.hoverLine()) - assertNotSameColor(SessionUiStyle.View.headerHover(), SessionUiStyle.View.line()) + fun `test header hover fill differs from outline colors`() { + assertNotSameColor(SessionUiStyle.View.Surface.headerHoverBgColor(), SessionUiStyle.View.Outline.hoverColor()) + assertNotSameColor(SessionUiStyle.View.Surface.headerHoverBgColor(), SessionUiStyle.View.Outline.brightColor()) } - fun `test primary card border follows hover color`() { + fun `test primary card hover only changes header background`() { val view = TestView(content = JLabel("body")) - val row = view.component(0) + val row = view.component(0) as JPanel - enter(row) + assertEquals(0, paint(view.border).alpha) + view.expand() - assertEquals(SessionUiStyle.View.hoverLine().rgb, paint(view.border).rgb) - assertNotSameColor(SessionUiStyle.View.headerHover(), paint(view.border)) - exit(row) - assertEquals(SessionUiStyle.View.line().rgb, paint(view.border).rgb) + view.setHovered(true) + + assertEquals(SessionUiStyle.View.Surface.headerHoverBgColor().rgb, row.background.rgb) + assertLine(view.border) + view.setHovered(false) + assertEquals(SessionUiStyle.View.Surface.headerBgColor().rgb, row.background.rgb) + assertLine(view.border) } private class TestView(content: JLabel, expanded: Boolean = false, expandable: Boolean = true) : @@ -122,6 +126,19 @@ class AbstractSessionPartViewTest : BasePlatformTestCase() { return Color(image.getRGB(0, 0), true) } + private fun assertLine(border: Border) { + val image = BufferedImage(5, 5, BufferedImage.TYPE_INT_ARGB) + val panel = JPanel() + val graphics = image.createGraphics() + border.paintBorder(panel, graphics, 0, 0, image.width, image.height) + graphics.dispose() + val rgb = SessionUiStyle.View.Outline.color().rgb + assertEquals(rgb, Color(image.getRGB(2, 0), true).rgb) + assertEquals(rgb, Color(image.getRGB(0, 2), true).rgb) + assertEquals(rgb, Color(image.getRGB(4, 2), true).rgb) + assertEquals(rgb, Color(image.getRGB(2, 4), true).rgb) + } + private fun assertNotSameColor(left: Color, right: Color) { assertFalse("Expected distinct colors but both were ${left.rgb}", left.rgb == right.rgb) } diff --git a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/base/BaseQuestionViewTest.kt b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/base/BaseQuestionViewTest.kt index 41e4229f45d..8136916ef49 100644 --- a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/base/BaseQuestionViewTest.kt +++ b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/base/BaseQuestionViewTest.kt @@ -164,7 +164,7 @@ class BaseQuestionViewTest : BasePlatformTestCase() { val north = region(panel, BorderLayout.NORTH) as Container val filler = north.components.last() - assertEquals(UiStyle.Gap.md(), filler.preferredSize.height) + assertEquals(UiStyle.Gap.lg(), filler.preferredSize.height) assertEquals(0, filler.preferredSize.width) } } @@ -242,8 +242,8 @@ class BaseQuestionViewTest : BasePlatformTestCase() { BaseQuestionView.Action("a", "A", primary = false) {}, BaseQuestionView.Action("b", "B", primary = true) {}, )) - assertEquals(SessionUiStyle.View.surface(), actionButton(panel, "A").background) - assertEquals(SessionUiStyle.View.surface(), actionButton(panel, "B").background) + assertEquals(SessionUiStyle.View.Surface.bgColor(), actionButton(panel, "A").background) + assertEquals(SessionUiStyle.View.Surface.bgColor(), actionButton(panel, "B").background) } } @@ -296,6 +296,18 @@ class BaseQuestionViewTest : BasePlatformTestCase() { } } + fun `test card top padding uses next spacing step`() { + edt { + val panel = BaseQuestionView() + val ins = panel.border.getBorderInsets(panel) + + assertEquals(UiStyle.Gap.pad(), ins.top) + assertEquals(UiStyle.Gap.pad(), ins.left) + assertEquals(UiStyle.Gap.lg(), ins.bottom) + assertEquals(UiStyle.Gap.pad(), ins.right) + } + } + fun `test action left alone attaches footer west`() { edt { val panel = BaseQuestionView() diff --git a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/permission/PermissionViewTest.kt b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/permission/PermissionViewTest.kt index 1e6c3a28150..6b52bef0020 100644 --- a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/permission/PermissionViewTest.kt +++ b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/views/permission/PermissionViewTest.kt @@ -4,12 +4,12 @@ import ai.kilocode.client.session.model.Permission import ai.kilocode.client.session.model.PermissionFileDiff import ai.kilocode.client.session.model.PermissionMeta import ai.kilocode.client.session.model.PermissionRequestState +import ai.kilocode.client.session.views.SessionViewIcons import ai.kilocode.client.session.views.base.BaseQuestionView import ai.kilocode.client.session.ui.style.SessionEditorStyle import ai.kilocode.client.session.ui.style.SessionUiStyle import ai.kilocode.client.ui.UiStyle import ai.kilocode.rpc.dto.PermissionReplyDto -import com.intellij.icons.AllIcons import com.intellij.ide.ui.laf.darcula.ui.DarculaButtonUI import com.intellij.testFramework.fixtures.BasePlatformTestCase import com.intellij.ui.components.JBLabel @@ -410,7 +410,7 @@ class PermissionViewTest : BasePlatformTestCase() { val labels = findAll(view) assertTrue( "Expected permission warning icon in header", - labels.any { it.icon == AllIcons.General.Warning }, + labels.any { it.icon == SessionViewIcons.warning }, ) } @@ -434,8 +434,8 @@ class PermissionViewTest : BasePlatformTestCase() { fun `test session question buttons use question surface background`() { view.show(permission()) - assertEquals(SessionUiStyle.View.surface(), view.runButtonForTest().background) - assertEquals(SessionUiStyle.View.surface(), view.denyButtonForTest().background) + assertEquals(SessionUiStyle.View.Surface.bgColor(), view.runButtonForTest().background) + assertEquals(SessionUiStyle.View.Surface.bgColor(), view.denyButtonForTest().background) } // ------ code labels use transcript style ------ @@ -494,7 +494,7 @@ class PermissionViewTest : BasePlatformTestCase() { val labels = view.codeLabelsForTest() assertFalse("Expected code labels", labels.isEmpty()) - assertEquals(SessionUiStyle.View.headerHover(), labels[0].background) + assertEquals(SessionUiStyle.View.Surface.headerHoverBgColor(), labels[0].background) } private fun permission() = Permission( diff --git a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/ui/UiStyleTest.kt b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/ui/UiStyleTest.kt index 9749a587a94..b3702301c9c 100644 --- a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/ui/UiStyleTest.kt +++ b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/ui/UiStyleTest.kt @@ -39,9 +39,9 @@ class UiStyleTest : BasePlatformTestCase() { fun `test session layout constants provide shared geometry`() { assertTrue(JBUI.scale(SessionUiStyle.SessionLayout.GAP) > 0) - assertTrue(JBUI.scale(SessionUiStyle.View.SESSION_VIEW_GAP) > 0) - assertTrue(JBUI.scale(SessionUiStyle.View.SESSION_VIEW_VERTICAL_PADDING) > 0) - assertTrue(JBUI.scale(SessionUiStyle.View.SESSION_VIEW_HORIZONTAL_PADDING) > 0) + assertTrue(JBUI.scale(SessionUiStyle.View.Layout.GAP) > 0) + assertTrue(JBUI.scale(SessionUiStyle.View.Layout.VERTICAL_PADDING) > 0) + assertTrue(JBUI.scale(SessionUiStyle.View.Layout.HORIZONTAL_PADDING) > 0) assertTrue(SessionUiStyle.View.Tool.BODY_LINES > 0) assertTrue(SessionUiStyle.View.Reasoning.BODY_LINES > 0) } diff --git a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/ui/layout/StackTest.kt b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/ui/layout/StackTest.kt index ec3b1a96a69..887556bfd34 100644 --- a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/ui/layout/StackTest.kt +++ b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/ui/layout/StackTest.kt @@ -313,6 +313,39 @@ class StackTest : BasePlatformTestCase() { assertBounds(3, 2, 10, 44, a) } + fun `test fit horizontal preserves preferred widths when there is space`() { + val a = child(pref = 10 x 5) + val b = child(pref = 20 x 7) + val stack = Stack.fitHorizontal(gap = 3).apply { + next(a) + next(b) + } + + stack.setBounds(0, 0, 100, 50) + stack.doLayout() + + assertBounds(0, 0, 10, 50, a) + assertBounds(13, 0, 20, 50, b) + } + + fun `test fit horizontal allocates tight space from the left`() { + val a = child(pref = 20 x 5) + val b = child(pref = 20 x 7) + val c = child(pref = 20 x 9) + val stack = Stack.fitHorizontal(gap = 3).apply { + next(a) + next(b) + next(c) + } + + stack.setBounds(0, 0, 45, 50) + stack.doLayout() + + assertBounds(0, 0, 20, 50, a) + assertBounds(23, 0, 20, 50, b) + assertBounds(45, 0, 0, 50, c) + } + fun `test vertical measures preferred height after width probe`() { val a = object : JBLabel("x") { override fun getMinimumSize() = Dimension(0, 0) diff --git a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/ui/md/MdViewHybridStressTest.kt b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/ui/md/MdViewHybridStressTest.kt new file mode 100644 index 00000000000..e9d40248cf6 --- /dev/null +++ b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/ui/md/MdViewHybridStressTest.kt @@ -0,0 +1,180 @@ +package ai.kilocode.client.ui.md + +import ai.kilocode.client.session.ui.style.SessionEditorStyle +import com.intellij.openapi.editor.EditorFactory +import com.intellij.openapi.util.Disposer +import com.intellij.testFramework.fixtures.BasePlatformTestCase +import com.intellij.ui.EditorTextField +import com.intellij.ui.components.JBHtmlPane +import com.intellij.ui.components.JBScrollPane +import com.intellij.util.ui.UIUtil +import javax.swing.Box +import javax.swing.JPanel + +/** + * Stress + leak coverage for the hybrid markdown renderer. + * + * These tests drive many updates through the public [MdView] API and inspect the real + * Swing component tree to prove that: + * - retained component instances survive heavy streaming, + * - the component tree stays bounded (no per-update growth), + * - editors created for code blocks are released (no leak) after churn + clear. + */ +@Suppress("UnstableApiUsage") +class MdViewHybridStressTest : BasePlatformTestCase() { + private lateinit var view: MdView + private var disposed = false + + override fun setUp() { + super.setUp() + view = MdViewFactory.hybrid() + disposed = false + } + + override fun tearDown() { + try { + if (this::view.isInitialized && !disposed) Disposer.dispose(view) + } finally { + super.tearDown() + } + } + + fun `test streaming a large mixed document token by token stays consistent`() { + val doc = buildString { + append("# Heading\n\n") + append("Intro paragraph with **bold** text.\n\n") + append("- one\n- two\n- three\n\n") + append("```kotlin\nval x = 1\n```\n\n") + append("middle prose paragraph\n\n") + append("```java\nclass A {}\n```\n\n") + append("closing prose") + } + + for (token in doc.chunked(3)) view.append(token) + + assertEquals(doc, view.markdown()) + assertEquals(3, htmls().size) + assertEquals(2, scrolls().size) + assertEquals(4, struts().size) // blocks - 1 + assertEquals(9, panel().componentCount) // 5 blocks + 4 struts = 2*5 - 1 + + val html = view.html() + assertTrue(html.contains("

")) + assertTrue(html.contains("