Skip to content

feat(core): honor per-model provider overrides in the models.dev gateway#18928

Merged
abhiaiyer91 merged 1 commit into
mastra-ai:mainfrom
andrelandgraf:feat/models-dev-per-model-provider-overrides
Jul 6, 2026
Merged

feat(core): honor per-model provider overrides in the models.dev gateway#18928
abhiaiyer91 merged 1 commit into
mastra-ai:mainfrom
andrelandgraf:feat/models-dev-per-model-provider-overrides

Conversation

@andrelandgraf

@andrelandgraf andrelandgraf commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Summary

The models.dev gateway currently resolves every model of a provider through a single provider-level URL + request shape, chosen by provider id (resolveLanguageModel switches on providerId; buildUrl uses the provider-level url). This ignores models.dev's per-model provider block, which lets a provider serve individual models over a different endpoint / request shape / SDK than the provider default.

A concrete case: a provider whose default is OpenAI-compatible chat-completions, but whose GPT‑5 models are served over the OpenAI Responses API (shape: "responses") at a different path. Today Mastra sends those to chat-completions and they 404 / can't use Responses-only features (e.g. the image_generation built-in tool).

This PR makes the models.dev gateway honor per-model overrides generically (not tied to any specific provider):

  • fetchProviders captures each model's provider block (api, shape, npm) into a new optional ProviderConfig.modelOverrides map. It serializes into the generated registry like any other field, so it flows through the existing sync pipeline.
  • buildUrl prefers a per-model api over the provider-level url (explicit *_BASE_URL env override still wins).
  • resolveLanguageModel routes a model with shape: "responses" via createOpenAI(...).responses(modelId) (for any provider), and prefers a per-model npm over the provider default in the openai-compatible dispatch.

Providers without per-model overrides are completely unaffected.

Why

models.dev already supports per-model provider overrides in its schema (shape: "responses" | "completions", api, npm) and providers use them (e.g. Amazon Bedrock points openai.gpt-5.5 at a /openai/v1 Responses endpoint). Mastra was the one consumer dropping them on the floor. This came up while modeling the Neon AI Gateway, which serves its GPT‑5 models over the OpenAI Responses route while the rest of the catalog uses a chat-completions endpoint — companion models.dev change for context: anomalyco/models.dev#3021.

Test plan

  • packages/core unit tests pass (vitest run src/llm/model/gateways/models-dev.test.ts — 40/40), including 3 new tests: fetchProviders captures modelOverrides; a shape: "responses" model resolves via createOpenAI().responses() on a chat-completions provider; buildUrl prefers the per-model endpoint.
  • Full model unit suite green (vitest run src/llm/model --exclude '**/*.e2e.test.ts' — 318/318, no type errors).
  • Changeset added (@mastra/core minor).

Notes

  • The committed provider-registry.json picks up per-model overrides on the next registry sync (or live fetch); the field is optional, so existing cached registries and providers without overrides behave exactly as before.

ELI5

This change lets each model choose its own “instructions” instead of forcing every model from the same provider to use the same setup. That means the gateway can now send some models to a different URL, use a different request style, or pick a different SDK when needed.

Summary

  • Added per-model provider overrides to models.dev support, including api, shape, and npm.
  • Stored model-specific overrides in ProviderConfig.modelOverrides while fetching providers.
  • Updated URL building to prefer a model-level API override before falling back to provider defaults and environment overrides.
  • Updated model resolution so shape: "responses" routes through the OpenAI Responses API for any provider.
  • Updated SDK selection to prefer a model-specific npm package over the provider default.
  • Added tests covering override parsing, Responses API routing, and URL fallback behavior.
  • Added a changeset for a minor @mastra/core release.

The models.dev gateway resolved every model of a provider through a single
provider-level url + request shape (chosen by provider id). This ignores
models.dev's per-model `provider` block, which lets a provider serve
individual models over a different endpoint/shape/SDK (e.g. a model on the
OpenAI Responses API while the provider default is chat-completions).

Capture per-model `provider` overrides (api/shape/npm) in fetchProviders,
prefer a per-model `api` in buildUrl, and route `shape: "responses"` models
via the OpenAI Responses API in resolveLanguageModel. Providers without
overrides are unchanged.
@changeset-bot

changeset-bot Bot commented Jul 3, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 07b1067

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 22 packages
Name Type
@mastra/core Minor
mastracode Patch
@mastra/mcp-docs-server Patch
@internal/playground Patch
@mastra/client-js Patch
@mastra/opencode Patch
@mastra/longmemeval Patch
mastra Patch
@mastra/deployer-cloud Minor
@mastra/react Patch
@mastra/playground-ui Patch
@mastra/server Minor
@mastra/deployer Minor
create-mastra Patch
@mastra/express Patch
@mastra/fastify Patch
@mastra/hono Patch
@mastra/koa Patch
@mastra/nestjs Patch
@mastra/next Patch
@mastra/tanstack-start Patch
@mastra/temporal Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel

vercel Bot commented Jul 3, 2026

Copy link
Copy Markdown

@andrelandgraf is attempting to deploy a commit to the Mastra Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Adds per-model provider override support to the models.dev gateway in @mastra/core. A new ModelProviderOverride type allows specifying alternate api, shape, or npm per model. Parsing, URL building, and model resolution logic are updated accordingly, with corresponding tests and a changeset.

Changes

Per-model provider overrides

Layer / File(s) Summary
Override type contract
packages/core/src/llm/model/gateways/base.ts
Adds exported ModelProviderOverride interface (api, shape, npm) and ProviderConfig.modelOverrides map.
Parsing overrides from models.dev
packages/core/src/llm/model/gateways/models-dev.ts
ModelsDevModelInfo gains a provider override block; fetchProviders() collects per-model overrides into modelOverrides and stores them on provider configs.
URL building and model resolution
packages/core/src/llm/model/gateways/models-dev.ts
buildUrl() prefers per-model api override before provider default; resolveLanguageModel() routes shape: 'responses' models through OpenAI Responses API and prefers override npm package.
Tests and changeset
packages/core/src/llm/model/gateways/models-dev.test.ts, .changeset/models-dev-per-model-provider-overrides.md
Adds tests for override parsing, responses-API routing, and URL fallback; adds a minor changeset documenting the feature.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Suggested labels: complexity: medium

Suggested reviewers: abhiaiyer91, TylerBarnes, wardpeet, TheIsrael1, NikAiyer

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: honoring per-model provider overrides in the models.dev gateway.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ 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.

@dane-ai-mastra dane-ai-mastra Bot added the needs-issue PR is missing a linked issue label Jul 3, 2026
@dane-ai-mastra

dane-ai-mastra Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

PR triage

This PR needs to fix an existing issue. Please link an issue in the PR description, for example with Fixes #1234 or Closes #1234.

Applied label: needs-issue

PRs without a linked issue will automatically close after 1 day(s) with the label.


Changed test gate

Changed Test Gate is pending. The Changed Test Gate / changed-tests check will update the test label when it completes.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.changeset/models-dev-per-model-provider-overrides.md (1)

1-8: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Missing code example for a new feature (potential_issue).

As per path instructions, "If the change is a breaking change or is adding a new feature, ensure that a short code example is provided. This code example should show the public API usage." This changeset documents a new feature (per-model routing overrides) but includes no code example.

Consider adding a short snippet showing the (unchanged) model string usage that now benefits from correct routing, e.g.:

const agent = new Agent({
  model: 'neon/gpt-5-mini', // now routed via the OpenAI Responses API per models.dev override
});
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.changeset/models-dev-per-model-provider-overrides.md around lines 1 - 8,
The changeset for the new models.dev per-model provider override feature is
missing a public API usage example. Add a short code example to the document,
near the description of the feature, showing the unchanged model string usage
through Agent or the relevant public entry point so readers can see how a model
like neon/gpt-5-mini is now routed via the per-model provider override. Refer to
the models.dev gateway behavior and the resolveLanguageModel/buildUrl routing
changes in the text so the example clearly matches the new feature.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In @.changeset/models-dev-per-model-provider-overrides.md:
- Around line 1-8: The changeset for the new models.dev per-model provider
override feature is missing a public API usage example. Add a short code example
to the document, near the description of the feature, showing the unchanged
model string usage through Agent or the relevant public entry point so readers
can see how a model like neon/gpt-5-mini is now routed via the per-model
provider override. Refer to the models.dev gateway behavior and the
resolveLanguageModel/buildUrl routing changes in the text so the example clearly
matches the new feature.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 49d417a7-6995-4b0c-9148-dba62eba8b37

📥 Commits

Reviewing files that changed from the base of the PR and between bed7a5e and 07b1067.

📒 Files selected for processing (4)
  • .changeset/models-dev-per-model-provider-overrides.md
  • packages/core/src/llm/model/gateways/base.ts
  • packages/core/src/llm/model/gateways/models-dev.test.ts
  • packages/core/src/llm/model/gateways/models-dev.ts

@dane-ai-mastra

dane-ai-mastra Bot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Closing this PR because it has had the needs-issue label for at least 1 days without a linked issue. Please open or link an issue first, then reopen this PR when it is ready.

@dane-ai-mastra dane-ai-mastra Bot closed this Jul 5, 2026
@abhiaiyer91 abhiaiyer91 reopened this Jul 6, 2026
@abhiaiyer91 abhiaiyer91 merged commit 10959d5 into mastra-ai:main Jul 6, 2026
43 of 48 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-issue PR is missing a linked issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants