Skip to content

feat(ai-openrouter): update model catalog from OpenRouter API#400

Merged
AlemTuzlak merged 7 commits intoTanStack:mainfrom
SutuSebastian:feat/update-openrouter-models
Mar 30, 2026
Merged

feat(ai-openrouter): update model catalog from OpenRouter API#400
AlemTuzlak merged 7 commits intoTanStack:mainfrom
SutuSebastian:feat/update-openrouter-models

Conversation

@SutuSebastian
Copy link
Copy Markdown
Contributor

@SutuSebastian SutuSebastian commented Mar 26, 2026

🎯 Changes

Regenerates model-meta.ts from the current OpenRouter /api/v1/models endpoint, bringing the type system up to date with all models available on the platform.

  • 346 models total (+57 new, -59 deprecated/removed by OpenRouter)
  • Fixes snake_case → camelCase mapping bug in the conversion script
  • Adds parallelToolCalls to OpenRouterBaseOptions

Notable new models

Provider Models
OpenAI gpt-5.4, gpt-5.4-mini, gpt-5.4-nano, gpt-5.4-pro, gpt-5.3-chat, gpt-5.3-codex, gpt-5.2-codex
Anthropic claude-sonnet-4.6, claude-opus-4.6
Z.ai glm-5-turbo, glm-5, glm-4.7-flash
Xiaomi mimo-v2-pro, mimo-v2-omni
MiniMax minimax-m2.7, minimax-m2.5
Google gemini-3.1-flash-lite-preview, gemini-3.1-pro-preview, gemini-3.1-flash-image-preview
Mistral mistral-small-2603
Qwen qwen3.5-* series (9b, 27b, 35b, 122b, 397b, plus, flash)
Others kimi-k2.5, mercury-2, solar-pro-3, palmyra-x5, grok-4.20-*

Conversion script fixes

The OpenRouter API now returns supported_parameters in snake_case (e.g. frequency_penalty) whereas the previous data used camelCase. The conversion script only mapped max_tokensmax_completion_tokens but missed all other params, causing Pick<OpenRouterBaseOptions, 'frequency_penalty'> type errors on build.

Fix: Added a complete paramNameMap that converts all snake_case API params to their camelCase OpenRouterBaseOptions equivalents (frequency_penaltyfrequencyPenalty, presence_penaltypresencePenalty, logit_biaslogitBias, etc.).

Also fixed duplicate openrouter/auto entries — the model is now returned by the API directly, so the hardcoded manual additions are skipped when already present.

Other changes

  • Added parallelToolCalls?: boolean to OpenRouterBaseOptions (2 models use it)
  • Updated image-adapter.test.ts to use google/gemini-2.5-flash-image (the -preview variant was removed from the catalog)

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested this code locally with pnpm run test:pr.

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

Summary by CodeRabbit

  • New Features

    • Added an optional parallel tool-calls configuration for OpenRouter text models.
  • Tests

    • Updated OpenRouter image model identifier used in image adapter tests.
  • Chores

    • Prevented duplicate model entries and normalized parameter names in model-generation tooling.
    • Added a changeset recording model catalog updates (57 added, 59 removed) and the new option.

Regenerate model-meta.ts from the current OpenRouter /api/v1/models
endpoint (346 models total, +57 new, -59 deprecated).

Notable additions:
- openai/gpt-5.4, gpt-5.4-mini, gpt-5.4-nano, gpt-5.4-pro
- anthropic/claude-sonnet-4.6, claude-opus-4.6
- z-ai/glm-5-turbo, glm-5, glm-4.7-flash
- xiaomi/mimo-v2-pro, mimo-v2-omni
- minimax/minimax-m2.7, minimax-m2.5
- google/gemini-3.1-flash-lite-preview, gemini-3.1-pro-preview
- mistralai/mistral-small-2603
- moonshotai/kimi-k2.5
- qwen/qwen3.5-* series

Fixes in conversion script:
- Map snake_case supported_parameters from the API to camelCase
  keys matching OpenRouterBaseOptions (frequency_penalty →
  frequencyPenalty, etc.)
- Skip duplicate openrouter/auto entries when the model is already
  in the API catalog

Other changes:
- Add parallelToolCalls to OpenRouterBaseOptions
- Update image-adapter test to use non-deprecated model ID
@SutuSebastian SutuSebastian requested a review from a team March 26, 2026 10:32
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 26, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Added parallelToolCalls?: boolean to OpenRouter base options, updated image adapter tests to use google/gemini-2.5-flash-image, and changed the model conversion script to avoid duplicate openrouter/auto entries and to map/filter parameter names when generating model metadata.

Changes

Cohort / File(s) Summary
Text Provider Configuration
packages/typescript/ai-openrouter/src/text/text-provider-options.ts
Added optional parallelToolCalls?: boolean to OpenRouterBaseOptions.
Image Adapter Tests
packages/typescript/ai-openrouter/tests/image-adapter.test.ts
Replaced google/gemini-2.5-flash-image-preview with google/gemini-2.5-flash-image across mocks, inputs, adapter factory config, and assertions.
Model Conversion Script
scripts/convert-openrouter-models.ts
Prevent duplicate "openrouter/auto" entries when keys already exist; introduced paramNameMap to map snake_case → camelCase and excludedParams to filter out tools, reasoning_effort, structured_outputs when producing model metadata and supported params.
Changeset
.changeset/update-openrouter-models.md
Added changeset documenting model catalog updates, the parameter-mapping fix, and addition of parallelToolCalls.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 I hopped through options, tidy and small,
Tests swapped a model and I fixed them all,
Scripts trim duplicates, rename with delight,
Params now camel-cased and shining bright,
I munch a carrot and bound out of sight. 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and accurately summarizes the main change: regenerating the OpenRouter model catalog from the API with updated models and type system.
Description check ✅ Passed The PR description is comprehensive, covering all required sections with detailed explanations of changes, fixes, checklist completion, and release impact including changeset generation.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

- Add minor changeset for @tanstack/ai-openrouter
- Apply prettier formatting to model-meta.ts and scripts
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
packages/typescript/ai-openrouter/src/text/text-provider-options.ts (1)

308-311: Duplicate property definition with inconsistent JSDoc.

parallelToolCalls is already defined in OpenRouterCommonOptions (lines 197-200) with @default true in its JSDoc. This duplicate in OpenRouterBaseOptions lacks the default value annotation.

If both definitions are intentional (to enable per-model Pick<> typing), consider aligning the JSDoc or adding a comment explaining why it's defined in both interfaces.

♻️ Suggested JSDoc alignment
   /**
    * Whether to allow the model to make multiple tool calls in parallel.
+   * `@default` true
    */
   parallelToolCalls?: boolean
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/typescript/ai-openrouter/src/text/text-provider-options.ts` around
lines 308 - 311, The property parallelToolCalls is duplicated between
OpenRouterCommonOptions and OpenRouterBaseOptions with inconsistent JSDoc;
either remove the duplicate from OpenRouterBaseOptions if redundant, or align
the documentation by adding the same JSDoc (e.g., `@default` true) to the
OpenRouterBaseOptions declaration and include a short comment explaining the
duplication is intentional to support per-model Pick<> typing (referencing
OpenRouterCommonOptions, OpenRouterBaseOptions, and parallelToolCalls to locate
the declarations).
scripts/convert-openrouter-models.ts (1)

168-172: Consider adding a TODO for future type coverage.

Excluding tools, reasoning_effort, and structured_outputs is pragmatic since they're either handled elsewhere (tools in InternalTextProviderOptions) or have no corresponding OpenRouterBaseOptions fields. However, this means models supporting these features won't have type-checked access via per-model types.

📝 Optional: Add TODO comment for future enhancement
   const excludedParams = new Set([
     'tools',
     'reasoning_effort',
     'structured_outputs',
   ])
+  // TODO: Consider adding reasoning_effort and structured_outputs to OpenRouterBaseOptions
+  // to enable per-model type safety for these capabilities
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/convert-openrouter-models.ts` around lines 168 - 172, Add a TODO
comment above the excludedParams Set declaration (the excludedParams variable
that contains 'tools', 'reasoning_effort', and 'structured_outputs') noting that
these keys are intentionally excluded for now and that future work should extend
per-model types to cover tools, reasoning_effort, and structured_outputs (or map
them from InternalTextProviderOptions/OpenRouterBaseOptions) so models
supporting these features get proper type-checked access. Keep the TODO concise
and reference the three excluded keys and the excludedParams identifier so it's
easy to find later.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@scripts/convert-openrouter-models.ts`:
- Around line 186-188: The runtime "supports" array construction currently uses
model.supported_parameters directly and maps with paramNameMap, which causes
excludedParams (tools, reasoning_effort, structured_outputs) to appear at
runtime even though they're filtered from the generated TypeScript types; update
the supports push to filter model.supported_parameters through the same
excludedParams set before mapping (e.g., model.supported_parameters?.filter(p =>
!excludedParams.has(p)).map(p => paramNameMap[p] ?? p)...) and preserve the
existing join/empty-string behavior so runtime metadata matches the Pick<> type
filtering.

---

Nitpick comments:
In `@packages/typescript/ai-openrouter/src/text/text-provider-options.ts`:
- Around line 308-311: The property parallelToolCalls is duplicated between
OpenRouterCommonOptions and OpenRouterBaseOptions with inconsistent JSDoc;
either remove the duplicate from OpenRouterBaseOptions if redundant, or align
the documentation by adding the same JSDoc (e.g., `@default` true) to the
OpenRouterBaseOptions declaration and include a short comment explaining the
duplication is intentional to support per-model Pick<> typing (referencing
OpenRouterCommonOptions, OpenRouterBaseOptions, and parallelToolCalls to locate
the declarations).

In `@scripts/convert-openrouter-models.ts`:
- Around line 168-172: Add a TODO comment above the excludedParams Set
declaration (the excludedParams variable that contains 'tools',
'reasoning_effort', and 'structured_outputs') noting that these keys are
intentionally excluded for now and that future work should extend per-model
types to cover tools, reasoning_effort, and structured_outputs (or map them from
InternalTextProviderOptions/OpenRouterBaseOptions) so models supporting these
features get proper type-checked access. Keep the TODO concise and reference the
three excluded keys and the excludedParams identifier so it's easy to find
later.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 441907d0-726c-4955-b967-915e4e8075cf

📥 Commits

Reviewing files that changed from the base of the PR and between c3583e3 and 4dad9ca.

📒 Files selected for processing (5)
  • packages/typescript/ai-openrouter/src/model-meta.ts
  • packages/typescript/ai-openrouter/src/text/text-provider-options.ts
  • packages/typescript/ai-openrouter/tests/image-adapter.test.ts
  • scripts/convert-openrouter-models.ts
  • scripts/openrouter.models.ts

@SutuSebastian
Copy link
Copy Markdown
Contributor Author

SutuSebastian commented Mar 26, 2026

Went through the review comments:

  1. supports array mismatch — good catch, fixed. The runtime supports array wasn't filtering excludedParams but the Pick<> types were, so they were out of sync. Added the same filter.

  2. parallelToolCalls JSDoc — the duplication is intentional (needed for Pick<> to compile), but the missing @default true was a fair point. Aligned it.

  3. TODO for excluded params — skipping this, no need for speculative TODOs.

The supports array in generated model metadata included tools,
reasoning_effort, and structured_outputs which were already filtered
from the TypeScript Pick<> types, creating a runtime/type mismatch.
Add missing @default true annotation to OpenRouterBaseOptions to
match OpenRouterCommonOptions.
@SutuSebastian
Copy link
Copy Markdown
Contributor Author

related to #312, but fresher? maybe we can join/consolidate changes?

@nx-cloud
Copy link
Copy Markdown

nx-cloud bot commented Mar 27, 2026

View your CI Pipeline Execution ↗ for commit 3b8e074

Command Status Duration Result
nx affected --targets=test:sherif,test:knip,tes... ✅ Succeeded 1m 4s View ↗
nx run-many --targets=build --exclude=examples/** ✅ Succeeded 44s View ↗

☁️ Nx Cloud last updated this comment at 2026-03-30 13:30:52 UTC

SutuSebastian and others added 2 commits March 29, 2026 12:29
+1 new model (kwaipilot/kat-coder-pro-v2), -2 removed free variants
(mistralai/mistral-small-3.1-24b-instruct:free, qwen/qwen3-4b:free),
plus pricing/parameter updates across existing models.
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Mar 30, 2026

Open in StackBlitz

@tanstack/ai

npm i https://pkg.pr.new/@tanstack/ai@400

@tanstack/ai-anthropic

npm i https://pkg.pr.new/@tanstack/ai-anthropic@400

@tanstack/ai-client

npm i https://pkg.pr.new/@tanstack/ai-client@400

@tanstack/ai-devtools-core

npm i https://pkg.pr.new/@tanstack/ai-devtools-core@400

@tanstack/ai-elevenlabs

npm i https://pkg.pr.new/@tanstack/ai-elevenlabs@400

@tanstack/ai-event-client

npm i https://pkg.pr.new/@tanstack/ai-event-client@400

@tanstack/ai-fal

npm i https://pkg.pr.new/@tanstack/ai-fal@400

@tanstack/ai-gemini

npm i https://pkg.pr.new/@tanstack/ai-gemini@400

@tanstack/ai-grok

npm i https://pkg.pr.new/@tanstack/ai-grok@400

@tanstack/ai-groq

npm i https://pkg.pr.new/@tanstack/ai-groq@400

@tanstack/ai-ollama

npm i https://pkg.pr.new/@tanstack/ai-ollama@400

@tanstack/ai-openai

npm i https://pkg.pr.new/@tanstack/ai-openai@400

@tanstack/ai-openrouter

npm i https://pkg.pr.new/@tanstack/ai-openrouter@400

@tanstack/ai-preact

npm i https://pkg.pr.new/@tanstack/ai-preact@400

@tanstack/ai-react

npm i https://pkg.pr.new/@tanstack/ai-react@400

@tanstack/ai-react-ui

npm i https://pkg.pr.new/@tanstack/ai-react-ui@400

@tanstack/ai-solid

npm i https://pkg.pr.new/@tanstack/ai-solid@400

@tanstack/ai-solid-ui

npm i https://pkg.pr.new/@tanstack/ai-solid-ui@400

@tanstack/ai-svelte

npm i https://pkg.pr.new/@tanstack/ai-svelte@400

@tanstack/ai-vue

npm i https://pkg.pr.new/@tanstack/ai-vue@400

@tanstack/ai-vue-ui

npm i https://pkg.pr.new/@tanstack/ai-vue-ui@400

@tanstack/preact-ai-devtools

npm i https://pkg.pr.new/@tanstack/preact-ai-devtools@400

@tanstack/react-ai-devtools

npm i https://pkg.pr.new/@tanstack/react-ai-devtools@400

@tanstack/solid-ai-devtools

npm i https://pkg.pr.new/@tanstack/solid-ai-devtools@400

commit: 3b8e074

@AlemTuzlak AlemTuzlak merged commit e36f2af into TanStack:main Mar 30, 2026
7 checks passed
@SutuSebastian SutuSebastian deleted the feat/update-openrouter-models branch March 30, 2026 13:33
@github-actions github-actions bot mentioned this pull request Mar 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants