Skip to content

fix(providers): support OpenRouter virtual model IDs#344

Merged
SantiagoDePolonia merged 3 commits into
mainfrom
fix/openrouter-aliases
May 21, 2026
Merged

fix(providers): support OpenRouter virtual model IDs#344
SantiagoDePolonia merged 3 commits into
mainfrom
fix/openrouter-aliases

Conversation

@SantiagoDePolonia
Copy link
Copy Markdown
Contributor

@SantiagoDePolonia SantiagoDePolonia commented May 21, 2026

Summary

  • Support provider-owned raw slash model IDs such as openrouter/free and openrouter/auto.
  • Keep exact provider/model selector precedence before falling back to raw provider-owned IDs.
  • Add router and registry coverage for OpenRouter virtual model selectors.

Tests

  • go test ./...
  • pre-commit hook: make test-race, go mod tidy, dashboard JS check, hot-path performance guard, make lint

Fixes #342

Summary by CodeRabbit

  • Bug Fixes
    • Improved resolution for models containing raw slashes (e.g., provider/model) across lookup, routing, pricing and metadata so the correct provider/type/name and pricing are selected.
  • Tests
    • Added tests validating routing, model lookup, metadata selection, and pricing behavior for provider-owned raw-slash model identifiers.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 21, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 54b5a03e-449c-4b31-baa7-0e9f523817cc

📥 Commits

Reviewing files that changed from the base of the PR and between 5fb3079 and 00c0b47.

📒 Files selected for processing (2)
  • internal/providers/registry_metadata.go
  • internal/providers/registry_metadata_override_test.go

📝 Walkthrough

Walkthrough

Registry, router, and pricing resolution now accept raw slash-containing model selectors (e.g., openrouter/free) by matching both the normalized model ID and the raw selector against provider-scoped entries, and tests were added to verify registry lookups, routing, and pricing fallbacks.

Changes

Provider-Owned Raw Model Selector Matching

Layer / File(s) Summary
Registry model-info lookup helper and integration
internal/providers/registry.go
Registry query methods (GetProvider, GetModel, LookupModel, Supports, GetProviderType, GetProviderName) now use providerModelInfo which trims inputs, matches by parsed modelID, and falls back to the raw selector when different.
Router provider-owned raw selector resolution
internal/providers/router.go
resolveQualifiedSelector adds resolveProviderOwnedRawSelector to scan provider models and match when provider name or type equals the provider segment and the model ID equals the raw requested model.
Provider-scoped metadata lookup enhancements
internal/providers/registry_metadata.go
getProviderModelMetadata/metadataFromProviderModel/metadataModelID updated to accept alternate model tokens, trim candidates, and return the first matching provider-scoped metadata key.
Pricing resolve fallback to raw provider-owned model
internal/pricingoverrides/resolver.go, internal/pricingoverrides/service_test.go
ResolvePricing trims the raw selector, normalizes for base lookup, and if no base pricing is found retries using the raw selector to honor provider-owned pricing entries; tests added for fallback behavior.
Tests: registry, router, and metadata overrides
internal/providers/registry_test.go, internal/providers/router_test.go, internal/providers/registry_metadata_override_test.go
Added tests verifying provider-owned slash model registration and lookup, router routing for slash models (provider stripping, upstream model), and metadata/pricing selection for provider-specific overrides.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • ENTERPILOT/GoModel#327: Refactors router/provider resolution paths; related changes to provider/type/name resolution and raw-slash selector handling.
  • ENTERPILOT/GoModel#176: Adjusts model-selector parsing and preservation for slash-containing model IDs; related alternative approach.

Poem

🐰 A slash in the name, a route that's awry,
I trimmed and I matched till the lookup said "hi" —
From registry to router, pricing finds home,
Openrouter/free now travels and roams 🥕✨

🚥 Pre-merge checks | ✅ 4 | ❌ 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 (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(providers): support OpenRouter virtual model IDs' accurately summarizes the main change—adding support for provider-owned raw slash model IDs like openrouter/free and openrouter/auto.
Linked Issues check ✅ Passed The PR directly addresses issue #342 by implementing support for OpenRouter virtual model IDs (e.g., openrouter/auto, openrouter/free) through provider-owned raw selector handling in registry, router, and pricing override resolution.
Out of Scope Changes check ✅ Passed All changes are scoped to supporting provider-owned raw slash model IDs: registry lookup logic, router resolution, pricing overrides, and metadata handling. No unrelated modifications detected.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/openrouter-aliases

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.

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 21, 2026

Greptile Summary

This PR extends model resolution for OpenRouter virtual model IDs that contain raw slashes. It changes:

  • Registry lookups to fall back from stripped provider/model selectors to raw provider-owned IDs.
  • Router resolution to route virtual IDs such as openrouter/free and openrouter/auto.
  • Pricing and metadata lookup to try raw provider-owned IDs after stripped selectors.
  • Tests covering routing, registry lookup, and pricing for raw slash model IDs.

Confidence Score: 3/5

This is close, but the pricing fallback should be fixed before merging.

  • The raw virtual model path can still miss pricing when a stripped sibling has metadata without pricing.

  • The remaining issue affects the main OpenRouter usage-pricing path this PR is meant to repair.

  • Routing and registry selector precedence otherwise appear consistent with the intended behavior.

  • internal/providers/registry_metadata.go needs pricing-aware candidate fallback.

Important Files Changed

Filename Overview
internal/providers/registry_metadata.go Updates metadata lookup for provider-owned raw slash IDs, but pricing fallback can still stop on a non-pricing stripped sibling.
internal/providers/router.go Adds raw provider-owned selector routing while preserving exact provider/model precedence.
internal/providers/registry.go Adds raw provider-owned fallback for registry model and provider lookups.

Reviews (3): Last reviewed commit: "fix(providers): skip empty metadata cand..." | Re-trigger Greptile

Comment on lines +532 to +543
func providerModelInfo(providerModels map[string]*ModelInfo, modelID, rawModel string) (*ModelInfo, bool) {
modelID = strings.TrimSpace(modelID)
rawModel = strings.TrimSpace(rawModel)
if info, exists := providerModels[modelID]; exists {
return info, true
}
if rawModel != "" && rawModel != modelID {
if info, exists := providerModels[rawModel]; exists {
return info, true
}
}
return nil, false
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Metadata lookup still strips raw IDs

This PR teaches the main registry lookup to find provider-owned raw slash IDs by trying the full raw model after the split model ID. The pricing and metadata path in registry_metadata.go still uses the old split-only lookup. When OpenRouter is configured as provider name openrouter and the model is openrouter/free, ResolvePricing("openrouter/free", "openrouter") looks for model free under provider openrouter, then returns nil because openrouter is a configured provider name. The chat request routes successfully, but usage logging cannot find the attached pricing/metadata for the actual registered model key openrouter/free.

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented May 21, 2026

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 81.13208% with 10 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
internal/providers/registry_metadata.go 57.14% 6 Missing ⚠️
internal/providers/router.go 80.00% 2 Missing and 2 partials ⚠️

📢 Thoughts on this report? Let us know!

Comment thread internal/providers/registry_metadata.go
Comment on lines +153 to +156
if info == nil || info.Model.Metadata == nil {
continue
}
return info.Model.Metadata
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Keep scanning for pricing

This helper now skips models with nil metadata, but ResolvePricing still accepts the first non-nil metadata even when it has no pricing. If OpenRouter exposes both free with metadata but no Pricing and openrouter/free with pricing, ResolvePricing("openrouter/free", "openrouter") returns the stripped free metadata here, drops it because Pricing is nil, and later metadataModelID keeps resolving the selector back to free. The raw virtual model pricing is never tried, so usage for openrouter/free remains unpriced even though the raw model has pricing metadata.

@SantiagoDePolonia SantiagoDePolonia merged commit 72a0e68 into main May 21, 2026
19 checks passed
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 virtual models not supported?

2 participants