mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-15 19:32:20 +03:00
Validated in a combined 4-PR batch worktree off release/v3.8.51 tip. This PR's diff overlapped taskFitness.ts and autoCombo.test.ts with the already-merged #11492/#11506 — git's merge auto-resolved both hunks cleanly (non-overlapping layers: #11492/#11506 touch layer 2 arena lookup, this PR touches layer 4 static-table hygiene); verified no conflict markers remained and re-ran the full suite after boarding. - npm run check:model-lifecycle — PASS, 68 retired ids, 1327 catalog ids, 0 violations (re-ran with the correct `node --import tsx/esm` loader after an initial bare-node invocation mistakenly failed on path-alias resolution — that was my invocation error, not the gate) - Focused tests: fitness-table-hygiene-11503.test.ts, taskFitness-pattern-order-8603.test.ts, model-deprecation-aliases-11503.test.ts, check-model-lifecycle-gate.test.ts, model-deprecation.test.ts, autoCombo.test.ts — part of batch's 126/126 vitest + 246/246 node:test runs - typecheck:core, file-size, changelog-integrity, complexity, cognitive-complexity, check:cycles — all OK - Full-repo lint: 228 problems remaining, all pre-existing dashboard react-hooks/* findings unrelated to this diff (zero errors in any file this PR touches) Thanks for this — genuinely thorough methodology (segment-boundary matching, provider-scoped alias guard, offline lifecycle gate with a documented burn-down list for the 6 remaining catalog offenders).
63 lines
1.9 KiB
TypeScript
63 lines
1.9 KiB
TypeScript
import { HTTP_STATUS } from "../../config/constants.ts";
|
|
import {
|
|
formatModelLifecycleMessage,
|
|
getModelLifecycleDecision,
|
|
} from "../../services/modelLifecycle.ts";
|
|
import { resolveModelAlias } from "../../services/modelDeprecation.ts";
|
|
import { createErrorResult } from "../../utils/error.ts";
|
|
|
|
type LifecycleLogger = {
|
|
info?: (tag: string, message: string) => unknown;
|
|
warn?: (tag: string, message: string) => unknown;
|
|
} | null;
|
|
|
|
function getModelLifecycleError({
|
|
provider,
|
|
model,
|
|
log,
|
|
warnOnDeprecation = false,
|
|
}: {
|
|
provider: string;
|
|
model: string;
|
|
log?: LifecycleLogger;
|
|
warnOnDeprecation?: boolean;
|
|
}): ReturnType<typeof createErrorResult> | null {
|
|
const decision = getModelLifecycleDecision(provider, model);
|
|
const message = formatModelLifecycleMessage(decision);
|
|
if (message && (decision.action === "reject" || warnOnDeprecation)) {
|
|
log?.warn?.("MODEL_LIFECYCLE", message);
|
|
}
|
|
if (decision.action !== "reject" || !message) return null;
|
|
return createErrorResult(
|
|
HTTP_STATUS.GONE,
|
|
message,
|
|
null,
|
|
"model_shutdown",
|
|
"invalid_request_error"
|
|
);
|
|
}
|
|
|
|
export function checkLifecycle(provider: string, model: string, log?: LifecycleLogger) {
|
|
return getModelLifecycleError({
|
|
provider,
|
|
// #11503: pass the provider so a globally deprecated id this provider still serves
|
|
// under its original name is left alone instead of rewritten into a 404.
|
|
model: resolveModelAlias(model, provider),
|
|
log,
|
|
});
|
|
}
|
|
|
|
export function resolveLifecycle(provider: string, model: string, log?: LifecycleLogger) {
|
|
const resolvedModel = resolveModelAlias(model, provider);
|
|
if (resolvedModel !== model) {
|
|
log?.info?.("ALIAS", `Model alias applied: ${model} → ${resolvedModel}`);
|
|
}
|
|
const lifecycleError = getModelLifecycleError({
|
|
provider,
|
|
model: resolvedModel,
|
|
log,
|
|
warnOnDeprecation: true,
|
|
});
|
|
return [resolvedModel, resolvedModel === model ? model : resolvedModel, lifecycleError] as const;
|
|
}
|