Repository navigation
[AISAGE-706] refactor(ai-gateway): derive legacy variants from reasoning_options - #7587
Conversation
E2E:
|
| File | Contents |
|---|---|
gateway-models.json |
Full response, pretty-printed |
summary.tsv |
Per model: id, ai_sdk_provider, variant names, reasoning_options |
reasoning-options-diff-vs-pr7580.json |
Models whose reasoning_options differ from #7580 |
Setup
I ran this branch (5c2fd5d99d) on the local stack (pnpm dev:start nextjs) against a freshly migrated database. Calling GET /api/cron/sync-providers loaded live OpenRouter metadata (669 models) and models.dev data into it. I then fetched /api/gateway/models and /api/openrouter/models through the web app. The two responses are identical, with 397 models. The request was unauthenticated, so the output contains no BYOK models.
Results
variantsare unchanged. For all 394 models that are also in the live production catalog (api.kilo.ai, fetched at the same time), the JSON matches exactly: 0 differences.reasoning_optionsdiffer from [AISAGE-706] feat(ai-gateway): serve models.dev reasoning_options in the model catalog #7580 only for the 28 always-on models, which go fromeffort ["high"]to[]as intended. Production doesn't servereasoning_optionsyet; [AISAGE-706] feat(ai-gateway): serve models.dev reasoning_options in the model catalog #7580 isn't deployed.- Every model with variants has
reasoning_options. The 129 models without either includekilo-auto/*,openrouter/autoandopenrouter/free. - 3 models exist only locally:
fake-deterministicis the local-development fake model.thinkingmachines/inkling:freeandgoogle/gemma-4-31b-it:freecome from the fresher local OpenRouter sync.
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Executive SummaryThis refactor flips Notes
Files Reviewed (19 files)
Reviewed by deepseek-v4.1-flash · Input: 119.2K · Output: 30.9K · Cached: 2.4M Review guidance: REVIEW.md from base branch |
Follow-up to #7580, which has been merged; this PR is based on
main.Summary
#7580 serves
reasoning_optionsby converting them out of the legacyvariants. Direct BYOK models therefore go through a round trip: models.devreasoning_options→ legacy variants (at sync time) →reasoning_optionsagain.This PR turns that around and makes
reasoning_optionsthe source of truth:Changes
getOpenRouterReasoningOptionsreplacesgetOpenRouterDerivedModelVariants:effortentry, sorted from lowest to highest.noneis added when reasoning is optional; Kimi K3 is still the exception.toggle.[].getFallbackReasoningOptionsreplacesgetFallbackModelVariants.variants.tsis nowreasoning-options.ts.toLegacyVariantsandwithLegacyVariants(newlegacy-variants.ts) are the only place OpenRouter-shaped variants are built:togglebecomesinstant/thinking.toggleplus efforts withoutnonegets an extranone.[]becomes a singlethinking.ai_sdk_provider: 'anthropic') get the matchingverbosity.DirectByokModelSchema.variantsis replaced byreasoning_options.reasoning_optionsas they are. It treats[]and options with no usable effort as missing, which was already the effective behaviour.reasoning_options.variantsare served unchanged. If a definition only hasreasoning_options, legacy variants are derived from them.getReasoningOptions/withReasoningOptions(variants →reasoning_options) from [AISAGE-706] feat(ai-gateway): serve models.dev reasoning_options in the model catalog #7580 are removed.main's web-shared typecheck: [AISAGE-706] feat(ai-gateway): serve models.dev reasoning_options in the model catalog #7580 and feat(auto-routing): resolve model aliases before benchmarking #7582 both added the samegetOpenRouterModelsMetadataFromDatabaseimport toopenrouter/index.test.ts.Behaviour changes compared with #7580
liquid/lfm-2.5-24b-a2b,aion-labs/aion-3.0):reasoning_optionschanges fromeffort: ["high"]to[]. This is the models.dev meaning for "always reasons, no caller control". The legacy variant stays a singlethinking.variantsno longer get derivedreasoning_options. An admin can addreasoning_optionsto the definition; legacy variants are then derived from it whenvariantsis absent.noneinstead ofinstant.minimax-m3(toggle, Anthropic API) no longer addsverbosity: highto itsthinkingvariant. Before this PR the sync added it but the gateway path did not; on/off variants now never carry verbosity, so Claude 4.5 and older stay unchanged.variantsuntil the nextsync-providersrun (every 5 minutes) plus the 10-minute list cache. During that window, BYOK reasoning models use the model-name fallback.Verification
main). I ran the local stack, synced providers from live OpenRouter and models.dev, then fetchedGET /api/gateway/models(397 models):variants: identical JSON for every model, compared with both [AISAGE-706] feat(ai-gateway): serve models.dev reasoning_options in the model catalog #7580's local catalog and the live production catalog (0 differences).reasoning_options: only the 28 mandatory-reasoning models above differ from [AISAGE-706] feat(ai-gateway): serve models.dev reasoning_options in the model catalog #7580.pnpm --filter web test -- src/lib/providers ../../packages/web-shared/src/lib/ai-gateway ../../packages/web-shared/src/lib/organizations src/tests/openrouter-models.test.ts src/routers/organizations/organization-settings-router.test.ts src/app/api/cron/sync-providers: 117 suites passed (2293 tests, 2 skipped) after rebasing ontomain.scripts/typecheck-all.sh --changes-onlyandpnpm --filter @kilocode/web-shared --filter web --filter ai-gateway --filter @kilocode/trpc typecheck: pass.oxlint(apps/web/src/lib/providers,packages/web-shared/src/lib/ai-gateway,packages/db/src),oxfmt --checkandgit diff --check: clean.