mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-16 03:42:21 +03:00
Validated in local merge-train (devbox-vm-06-dev002) @ combined-tip (FAST gates: typecheck/complexity/cognitive/changelog/vitest — only pre-existing audit.test.ts flake). Evidence: /home/diegosouzapw/dev/proxys/OmniRoute/.claude/worktrees/merge-train-20260805-222248-suite.log
107 lines
3.8 KiB
TypeScript
107 lines
3.8 KiB
TypeScript
import { isRetiredGitHubCopilotModelId } from "@omniroute/open-sse/config/providers/registry/github/retiredModels.ts";
|
|
|
|
import { asRecord, toNonEmptyString } from "./shared";
|
|
|
|
export interface SyncedAvailableModel {
|
|
id: string;
|
|
name: string;
|
|
source: "imported";
|
|
apiFormat?: string;
|
|
targetFormat?: string;
|
|
upstreamProtocol?: string;
|
|
supportedEndpoints?: string[];
|
|
supportedThinkingEfforts?: string[];
|
|
defaultThinkingEffort?: string;
|
|
inputTokenLimit?: number;
|
|
outputTokenLimit?: number;
|
|
description?: string;
|
|
supportsThinking?: boolean;
|
|
alwaysThinking?: boolean;
|
|
supportsTools?: boolean;
|
|
supportsVideo?: boolean;
|
|
// #4264: image-input capability captured at sync time (e.g. OpenRouter
|
|
// `architecture.input_modalities`/`modality`) so the catalog can surface vision.
|
|
supportsVision?: boolean;
|
|
}
|
|
|
|
export type SyncedAvailableModelInput = Omit<SyncedAvailableModel, "source"> & {
|
|
source?: string;
|
|
};
|
|
|
|
function normalizeSyncedAvailableModel(model: unknown): SyncedAvailableModel | null {
|
|
const record = asRecord(model);
|
|
const id =
|
|
toNonEmptyString(record.id) || toNonEmptyString(record.name) || toNonEmptyString(record.model);
|
|
if (!id) return null;
|
|
|
|
const name =
|
|
toNonEmptyString(record.name) ||
|
|
toNonEmptyString(record.displayName) ||
|
|
toNonEmptyString(record.model) ||
|
|
id;
|
|
const supportedEndpoints = Array.isArray(record.supportedEndpoints)
|
|
? Array.from(
|
|
new Set(
|
|
record.supportedEndpoints
|
|
.map((endpoint) => toNonEmptyString(endpoint))
|
|
.filter((endpoint): endpoint is string => Boolean(endpoint))
|
|
)
|
|
).sort()
|
|
: undefined;
|
|
|
|
return {
|
|
id,
|
|
name,
|
|
source: "imported",
|
|
...(toNonEmptyString(record.apiFormat)
|
|
? { apiFormat: toNonEmptyString(record.apiFormat)! }
|
|
: {}),
|
|
...(toNonEmptyString(record.targetFormat)
|
|
? { targetFormat: toNonEmptyString(record.targetFormat)! }
|
|
: {}),
|
|
...(toNonEmptyString(record.upstreamProtocol)
|
|
? { upstreamProtocol: toNonEmptyString(record.upstreamProtocol)! }
|
|
: {}),
|
|
...(supportedEndpoints && supportedEndpoints.length > 0 ? { supportedEndpoints } : {}),
|
|
...(Array.isArray(record.supportedThinkingEfforts)
|
|
? {
|
|
supportedThinkingEfforts: record.supportedThinkingEfforts.filter(
|
|
(effort): effort is string => typeof effort === "string" && effort.length > 0
|
|
),
|
|
}
|
|
: {}),
|
|
...(toNonEmptyString(record.defaultThinkingEffort)
|
|
? { defaultThinkingEffort: toNonEmptyString(record.defaultThinkingEffort)! }
|
|
: {}),
|
|
...(typeof record.inputTokenLimit === "number"
|
|
? { inputTokenLimit: record.inputTokenLimit }
|
|
: {}),
|
|
...(typeof record.outputTokenLimit === "number"
|
|
? { outputTokenLimit: record.outputTokenLimit }
|
|
: {}),
|
|
...(typeof record.description === "string" ? { description: record.description } : {}),
|
|
...(typeof record.supportsThinking === "boolean"
|
|
? { supportsThinking: record.supportsThinking }
|
|
: {}),
|
|
...(record.alwaysThinking === true ? { alwaysThinking: true } : {}),
|
|
...(typeof record.supportsTools === "boolean" ? { supportsTools: record.supportsTools } : {}),
|
|
...(typeof record.supportsVideo === "boolean" ? { supportsVideo: record.supportsVideo } : {}),
|
|
...(record.supportsVision === true ? { supportsVision: true } : {}),
|
|
};
|
|
}
|
|
|
|
export function normalizeSyncedAvailableModels(
|
|
models: unknown,
|
|
providerId?: string
|
|
): SyncedAvailableModel[] {
|
|
if (!Array.isArray(models)) return [];
|
|
const deduped = new Map<string, SyncedAvailableModel>();
|
|
for (const model of models) {
|
|
const normalized = normalizeSyncedAvailableModel(model);
|
|
if (normalized && !isRetiredGitHubCopilotModelId(providerId, normalized.id)) {
|
|
deduped.set(normalized.id, normalized);
|
|
}
|
|
}
|
|
return Array.from(deduped.values());
|
|
}
|