mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-26 17:12:27 +03:00
Validated on the combined 12-PR batch board + the resolved merge against the post-#11232 tip: focused suites 73/73 (learned-reasoning-effort-caps, synced-capabilities-learned-effort-override, synced-effort-suffix-learned-validation, effort-tiers-loop-catalog-e2e, reasoning-effort-clamp-and-retry, reasoning-effort-learned-capability) + opencode-plugin effort-tier-variants 4/4, typecheck:core clean, gates within baseline. The stacked-branch conflict after #11232 squash-landed was resolved by hand (the learned-caps module keeps both the Set API and the new model-scoped lookup). The effort_tiers loop is closed end-to-end: catalog advertises exactly what the upstream accepts, and -<tier> suffix variants resolve against the learned set. Thank you @maxmad64bis!
77 lines
3.6 KiB
TypeScript
77 lines
3.6 KiB
TypeScript
/**
|
|
* Synced-model catalog `capabilities` builder (#7694).
|
|
*
|
|
* Extracted from catalog.ts (frozen file-size baseline — `config/quality/file-size-baseline.json`)
|
|
* to keep the vision (#4264) and reasoning-effort-tier (#7694) flags merged into a SINGLE
|
|
* `capabilities` object rather than two separate spreads that would silently overwrite one
|
|
* another via object-spread order. A model can be both vision- and reasoning-capable.
|
|
*
|
|
* effort_tiers loop (2026-08-23): a runtime-learned accepted set (#11232,
|
|
* learnedReasoningEffortCaps) REPLACES the synced `supportedThinkingEfforts`
|
|
* when one exists — the proven contract beats the advertised one. Lookup is
|
|
* model-scoped: executors record under connection ids while this module sees
|
|
* provider ids, so an exact provider:model key would always miss.
|
|
*
|
|
* Exclusion gate: `ownedBy` is REQUIRED and checked against
|
|
* `isSkippedEffortProvider` (codex/glm/kimi — providers that already own a
|
|
* conflicting `-{effort}` suffix mechanism, see syncedEffortVariants.ts, #7694).
|
|
* Without this, the blind opencode-plugin mapping (`capabilities.effort_tiers`
|
|
* -> ModelV2 `variants`) would double-handle those providers' native suffix
|
|
* ids. `shouldExposeSyncedEffortVariants` gates only the *synthetic*
|
|
* `<id>-<tier>` catalog entries (open-sse/utils/syncedEffortVariants.ts) — it
|
|
* never runs over the base entry's `capabilities`, so it cannot substitute
|
|
* for this check. Required (not optional) so no call site can silently skip it.
|
|
*/
|
|
// Use the same canonical alias as catalogModelPolicy.ts (l.1) — a relative path from
|
|
// src/app/api/v1/models/ to open-sse/ would need 5 `../` and silently breaks under
|
|
// refactors. (Confirmed convention: grep "from \"@omniroute/open-sse" src/app/api/v1/models/)
|
|
import { getLearnedReasoningEffortForModel } from "@omniroute/open-sse/services/learnedReasoningEffortCaps.ts";
|
|
import { isSkippedEffortProvider } from "@omniroute/open-sse/utils/syncedEffortVariants.ts";
|
|
|
|
interface SyncedCapabilityFlags {
|
|
id?: string;
|
|
supportsVision?: boolean;
|
|
supportedThinkingEfforts?: string[];
|
|
}
|
|
|
|
function effectiveEffortTiers(sm: SyncedCapabilityFlags, ownedBy: string): string[] | undefined {
|
|
if (isSkippedEffortProvider(ownedBy)) return undefined;
|
|
const learned = sm.id ? getLearnedReasoningEffortForModel(sm.id) : null;
|
|
if (learned) return [...learned];
|
|
return Array.isArray(sm.supportedThinkingEfforts) && sm.supportedThinkingEfforts.length > 0
|
|
? sm.supportedThinkingEfforts
|
|
: undefined;
|
|
}
|
|
|
|
/** Build the `capabilities` object for a fresh synced-model catalog entry, or `undefined` when neither flag applies. */
|
|
export function buildSyncedCapabilities(
|
|
sm: SyncedCapabilityFlags,
|
|
ownedBy: string
|
|
): Record<string, boolean | string[]> | undefined {
|
|
const tiers = effectiveEffortTiers(sm, ownedBy);
|
|
if (!sm.supportsVision && !tiers) return undefined;
|
|
return {
|
|
...(sm.supportsVision ? { vision: true } : {}),
|
|
...(tiers ? { effort_tiers: tiers } : {}),
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Merge (not clobber) capabilities onto an already-catalogued entry so syncing a
|
|
* vision/effort-tier flag onto a registry/combo model that already declares other
|
|
* capabilities keeps both. Returns `undefined` when there is nothing to merge.
|
|
*/
|
|
export function mergeSyncedCapabilities(
|
|
existing: Record<string, unknown> | undefined,
|
|
sm: SyncedCapabilityFlags,
|
|
ownedBy: string
|
|
): Record<string, unknown> | undefined {
|
|
const tiers = effectiveEffortTiers(sm, ownedBy);
|
|
if (!sm.supportsVision && !tiers && !existing) return undefined;
|
|
return {
|
|
...(existing || {}),
|
|
...(sm.supportsVision ? { vision: true } : {}),
|
|
...(tiers ? { effort_tiers: tiers } : {}),
|
|
};
|
|
}
|