mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-20 22:22:57 +03:00
Merged via merge-train (release/v3.8.50, batch1 2026-08-20) — static gates (typecheck/file-size/complexity/cognitive/changelog) green on the combined tree; test:unit reds observed in the boarded run were verified pre-existing on the pure release tip (unrelated flake), not caused by this PR. Thanks for the contribution!
This commit is contained in:
1
changelog.d/fixes/10734-combo-context-generic-default.md
Normal file
1
changelog.d/fixes/10734-combo-context-generic-default.md
Normal file
@@ -0,0 +1 @@
|
||||
- **fix(catalog):** stop counting `getTokenLimit()`'s generic 128k catch-all as a known combo window, so `/v1/models` advertises the min of sourced member contexts instead of collapsing a 500k combo to 128k ([#10734](https://github.com/diegosouzapw/OmniRoute/issues/10734))
|
||||
@@ -281,6 +281,29 @@ export function getTokenLimit(
|
||||
return resolveTokenLimit(provider, model, snapshot).limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Context window from a known source only: an explicit canonical window, or a
|
||||
* provider/model-specific `resolveTokenLimit` result. The generic 128000
|
||||
* catch-all (`specific: false`) is treated as unknown so combo `min()` does
|
||||
* not advertise 128k when every real member is larger (#10734).
|
||||
*/
|
||||
export function getSourcedTokenLimit(
|
||||
provider: string,
|
||||
model: string | null = null,
|
||||
canonicalWindow?: unknown,
|
||||
snapshot?: ModelCapabilityResolutionSnapshot | null
|
||||
): number | undefined {
|
||||
if (
|
||||
typeof canonicalWindow === "number" &&
|
||||
Number.isFinite(canonicalWindow) &&
|
||||
canonicalWindow > 0
|
||||
) {
|
||||
return canonicalWindow;
|
||||
}
|
||||
const resolved = resolveTokenLimit(provider, model, snapshot);
|
||||
return resolved.specific ? resolved.limit : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a combo target's token limit without crashing when `parseModel(modelStr)`
|
||||
* returns `provider: null` (model id with no `provider/` prefix).
|
||||
@@ -315,7 +338,7 @@ export function getComboTargetTokenLimit(options: {
|
||||
* name heuristic, curated per-provider default) or only from the generic
|
||||
* catch-all default.
|
||||
*/
|
||||
function resolveTokenLimit(
|
||||
export function resolveTokenLimit(
|
||||
provider: string,
|
||||
model: string | null = null,
|
||||
snapshot?: ModelCapabilityResolutionSnapshot | null
|
||||
|
||||
@@ -68,7 +68,7 @@ import {
|
||||
isNoAuthRawProviderPrefix,
|
||||
normalizeBlockedProviderSet,
|
||||
} from "@/shared/utils/noAuthProviders";
|
||||
import { getTokenLimit } from "@omniroute/open-sse/services/contextManager";
|
||||
import { getSourcedTokenLimit, getTokenLimit } from "@omniroute/open-sse/services/contextManager";
|
||||
import { extractApiKey } from "@/sse/services/auth";
|
||||
import type { ComboModelStep } from "@/lib/combos/steps";
|
||||
import {
|
||||
@@ -396,7 +396,10 @@ async function buildUnifiedModelsResponseCore(
|
||||
// single-stretch event-loop budget this file's own yield mechanism is meant to protect.
|
||||
const connectionsForProviderCache = new Map<string, typeof connections>();
|
||||
const getConnectionsForProvider = (...keys: Array<string | null | undefined>) => {
|
||||
const cacheKey = keys.filter((k): k is string => Boolean(k)).sort().join(" | ||||