Skip to content

fix(provider): resolve OpenRouter route-modifier suffixes in model IDs - #48117

Open
xiaoguomeiyitian wants to merge 1 commit into
anomalyco:devfrom
xiaoguomeiyitian:openrouter-route-modifiers
Open

xiaoguomeiyitian wants to merge 1 commit into
anomalyco:devfrom
xiaoguomeiyitian:openrouter-route-modifiers

Conversation

@xiaoguomeiyitian

Copy link
Copy Markdown

Issue for this PR

Closes #48016

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

OpenRouter exposes request-time route modifiers as : suffixes on a model slug — :floor, :nitro, :exacto, :online (and others like :free that do appear as catalog keys). These modifiers are not separate model SKUs, so they never appear as keys in the models.dev catalog. As a result, a reference like openrouter/openai/gpt-5.6-luna:floor fails lookup in Provider.getModel with ModelNotFoundError, even though OpenRouter routes that exact identifier fine when it is passed straight through.

The fix is scoped to the lookup step. When the exact provider.models[modelID] lookup misses and the provider is openrouter, strip a known route-modifier suffix and resolve against the base catalog model. The returned model keeps the suffixed ID in both model.id and model.api.id, so downstream request paths (getLanguagesdk.languageModel(model.api.id) in the AI SDK path, and LLMNativeRuntime in the native path) still send the modifier to OpenRouter.

Why it works: the base model entry carries everything the resolver needs (capabilities, cost, request config, npm/package), and the only thing that differs is the identifier OpenRouter should receive, which is exactly what the suffix expresses. Keeping the suffixed ID on api.id means the modifier is preserved end-to-end without touching any other provider path.

The fallback is deliberately narrow: only for openrouter, only for the four documented route-modifier suffixes, and only when the base model is present in the catalog. Unknown suffixes and missing bases keep the existing ModelNotFoundError + suggestions behavior.

How did you verify your code works?

  • Added two tests in packages/opencode/test/provider/provider.test.ts:
    • getModel resolves OpenRouter route-modifier suffixes against the base model — asserts openai/gpt-5.6-luna:floor resolves and that both model.id and model.api.id carry the suffixed value with the openrouter npm package.
    • getModel throws ModelNotFoundError for unknown route-modifier base — asserts openai/nonexistent-model:floor still fails.
  • bun run typecheck in packages/opencode passes.
  • Full packages/opencode provider suite passes (bun test test/provider/ — 715 passing; one header-timeout test is a pre-existing timing flake that also fails on the unmodified baseline when run in parallel).

Screenshots / recordings

If this is a UI change, please include a screenshot or recording.

N/A — backend model-resolution change, no UI.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

@xiaoguomeiyitian
xiaoguomeiyitian force-pushed the openrouter-route-modifiers branch 4 times, most recently from dc50a95 to ce657da Compare September 12, 2026 00:30
OpenRouter route modifiers (:floor, :nitro, :exacto, :online) are
request-time routing suffixes, not catalog model keys, so references
like openrouter/openai/gpt-5.6-luna:floor always failed model lookup
with ModelNotFoundError even though OpenRouter accepts the identifier.

When exact model-ID lookup fails, strip a known route-modifier suffix
and resolve against the base catalog model, keeping the suffixed ID for
provider requests so the routing modifier still applies.

Fixes anomalyco#48016
@xiaoguomeiyitian
xiaoguomeiyitian force-pushed the openrouter-route-modifiers branch from ce657da to 81ec2ec Compare September 16, 2026 04:15
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.

OpenRouter route-modifier suffixes (:floor, :nitro, :exacto) can't be referenced in model IDs

1 participant