Repository navigation
fix(api): advertise built-in auto/* combos in /v1/models (#4164) - #4170
Conversation
OmniRoute ships a zero-setup auto/* catalog (auto/best-coding, auto/pro- reasoning, …, 16 AUTO_TEMPLATE_VARIANTS) that the dashboard advertises and that resolve on demand via createBuiltinAutoCombo, but the /v1/models listing only emitted persisted DB combos + provider models. Clients that build their model picker from /v1/models (e.g. Hermes Agent) never saw any auto/* option. The catalog now emits every AUTO_TEMPLATE_VARIANTS id (owned_by: combo) at the top of the list, deduped against persisted combos so a user combo can't shadow or double a built-in id. TDD: tests/unit/models-catalog-auto-combos-4164.test.ts asserts every auto/* variant is advertised, they sit at the top, and ids are unique (RED 2/3 -> GREEN 3/3). Aligned the existing 'context_length for individual chat models' test to exclude owned_by:combo entries (combos/routers resolve dynamically and have no fixed context_length — they are not individual chat models).
80005c1 to
457eed5
Compare
There was a problem hiding this comment.
Code Review
This pull request advertises the built-in, zero-setup auto/* combos at the top of the /v1/models endpoint listing to ensure clients can discover them, while also preventing duplicates from shadowing persisted database combos. It includes comprehensive unit tests to verify this behavior and updates existing tests accordingly. The reviewer noted a minor improvement opportunity to remove a redundant check inside the loop that populates the auto/* variants, as the set is empty at initialization and the keys are already unique.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| if (listedIds.has(autoId)) continue; | ||
| listedIds.add(autoId); |
There was a problem hiding this comment.
The check if (listedIds.has(autoId)) continue; is redundant here. listedIds is initialized as an empty Set immediately before this loop, and Object.keys(AUTO_TEMPLATE_VARIANTS) returns unique keys. Therefore, listedIds.has(autoId) will always evaluate to false during this loop. We can safely remove this check to simplify the code.
| if (listedIds.has(autoId)) continue; | |
| listedIds.add(autoId); | |
| listedIds.add(autoId); |
…4180) Integrated into release/v3.8.29 — default includeThoughts for modern Gemini (2.5+) in the openai->gemini translator, so the model's reasoning is marked thought:true and routed to reasoning_content instead of leaking into visible content (#4170). Thanks @dhaern! On review we regenerated the gemini golden snapshots (basic-chat/with-system) and committed the new modern-gemini-default-thinking snapshot. 61/61 translator + golden tests pass; eslint clean. Respects explicit client thinking config (only applies when none is set) and excludes gemini-1.x / non-thinking 2.0.
…njection Merge origin/release/v3.8.47 and resolve conflict in openai-to-gemini.ts: the budget_tokens:0 drop (defect 1) was already fixed on release via cheaper-inference#6821 with a stricter includeThoughts check, so this drops the redundant/inferior duplicate here and keeps the already-merged version (plus the gemma-4 guard from cheaper-inference#6708). Rework the default-thinkingConfig-injection fix (defect 2) so it does not regress the cheaper-inference#4170 golden invariant: modern Gemini 2.5+ models think by default even with no thinkingConfig sent, so the no-knob-at-all case must keep injecting includeThoughts:true (unchanged from release). The real, golden-safe delta for cheaper-inference#6813 defect 2 is an explicit off-switch: reasoning_effort:"none" now maps to thinkingBudget:0/includeThoughts:false in the OpenAI-format branch, giving callers a documented way to opt out without touching the no-knob default path. Also drops the dead `reasoning_effort === "none" ? 0 : defaultBudget` ternary from the default-injection block — unreachable since block 1 already handles every truthy reasoning_effort value, including "none". Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
…erence#4164) (cheaper-inference#4170) OmniRoute ships a zero-setup auto/* catalog (auto/best-coding, auto/pro- reasoning, …, 16 AUTO_TEMPLATE_VARIANTS) that the dashboard advertises and that resolve on demand via createBuiltinAutoCombo, but the /v1/models listing only emitted persisted DB combos + provider models. Clients that build their model picker from /v1/models (e.g. Hermes Agent) never saw any auto/* option. The catalog now emits every AUTO_TEMPLATE_VARIANTS id (owned_by: combo) at the top of the list, deduped against persisted combos so a user combo can't shadow or double a built-in id. TDD: tests/unit/models-catalog-auto-combos-4164.test.ts asserts every auto/* variant is advertised, they sit at the top, and ids are unique (RED 2/3 -> GREEN 3/3). Aligned the existing 'context_length for individual chat models' test to exclude owned_by:combo entries (combos/routers resolve dynamically and have no fixed context_length — they are not individual chat models).
…heaper-inference#4180) Integrated into release/v3.8.29 — default includeThoughts for modern Gemini (2.5+) in the openai->gemini translator, so the model's reasoning is marked thought:true and routed to reasoning_content instead of leaking into visible content (cheaper-inference#4170). Thanks @dhaern! On review we regenerated the gemini golden snapshots (basic-chat/with-system) and committed the new modern-gemini-default-thinking snapshot. 61/61 translator + golden tests pass; eslint clean. Respects explicit client thinking config (only applies when none is set) and excludes gemini-1.x / non-thinking 2.0.
Closes #4164
Problem
OmniRoute ships a zero-setup
auto/*catalog (auto/best-coding,auto/best-reasoning,auto/pro-coding, … — 16AUTO_TEMPLATE_VARIANTSinopen-sse/services/autoCombo/builtinCatalog.ts) that the dashboard advertises and that resolve on demand viacreateBuiltinAutoCombo. But/v1/models(src/app/api/v1/models/catalog.ts) only emitted persisted DB combos + provider models, so clients that build their model picker from/v1/models— e.g. Hermes Agent (hermes model) — never saw anyauto/*option.Fix
The catalog now emits every
AUTO_TEMPLATE_VARIANTSid (asowned_by: "combo") at the top of the list, before persisted combos and provider models. A sharedlistedIdsset dedupes them so a persisted user combo can't shadow or double a built-inauto/*id.Showing each
auto/*'s dynamically-selected members (the reporter's secondary ask) is a separate enhancement — those are resolved per-request by the 9-factor scorer and have no fixed membership to list.Test (TDD, Hard Rule #18)
tests/unit/models-catalog-auto-combos-4164.test.ts:AUTO_TEMPLATE_VARIANTSid is advertised (imports the source-of-truth list, so it can't drift);auto/*entries sit at the top of the list;auto/*ids are unique.RED 2/3 → GREEN 3/3. Catalog route regression 45/45 (aligned the existing 'context_length for individual chat models' test to exclude
owned_by: "combo"entries — combos/routers resolve dynamically and have no fixedcontext_length, so they are categorically not individual chat models; this is alignment, not masking). typecheck:core, eslint, check:file-size clean. The failing vitestecosystem.test.ts › model catalogis environmental (ECONNREFUSED :20128, needs a live server), not from this change.