Files
omniai-web/src/api/modelCapabilitiesClient.ts
T

96 lines
3.2 KiB
TypeScript
Raw Normal View History

2026-06-02 12:38:01 +08:00
import { isOptionalApiRouteMissing } from "./apiErrorUtils";
import { isRecord, serverRequest } from "./serverConnection";
export interface ModelCapabilityOption {
value: string;
label: string;
description?: string;
badge?: string;
enabled?: boolean;
status?: "available" | "maintenance" | "disabled" | string;
}
export interface WebModelCapabilities {
source: "server" | "fallback";
imageModels: ModelCapabilityOption[];
videoModels: ModelCapabilityOption[];
chatModels: ModelCapabilityOption[];
updatedAt?: string;
}
function toStringValue(value: unknown, fallback = ""): string {
if (typeof value === "string") return value.trim() || fallback;
if (typeof value === "number" && Number.isFinite(value)) return String(value);
return fallback;
}
function normalizeModelOption(raw: unknown): ModelCapabilityOption | null {
if (typeof raw === "string") {
const value = raw.trim();
return value ? { value, label: value } : null;
}
if (!isRecord(raw)) return null;
const value = toStringValue(raw.value ?? raw.id ?? raw.model ?? raw.modelKey ?? raw.model_key);
if (!value) return null;
const status = toStringValue(raw.status);
const enabled = raw.enabled === undefined ? status !== "maintenance" && status !== "disabled" : Boolean(raw.enabled);
if (!enabled) return null;
return {
value,
label: toStringValue(raw.label ?? raw.displayName ?? raw.display_name ?? raw.name, value),
description: toStringValue(raw.description) || undefined,
badge: toStringValue(raw.badge) || undefined,
enabled,
status: status || "available",
};
}
function normalizeModelList(value: unknown): ModelCapabilityOption[] {
return Array.isArray(value)
? value.map(normalizeModelOption).filter((item): item is ModelCapabilityOption => Boolean(item))
: [];
}
function createFallbackCapabilities(): WebModelCapabilities {
return {
source: "fallback",
imageModels: [],
videoModels: [],
chatModels: [],
};
}
let modelCapabilitiesRouteMissing = false;
export const modelCapabilitiesClient = {
async get(name = "web-model-capabilities"): Promise<WebModelCapabilities> {
if (modelCapabilitiesRouteMissing) return createFallbackCapabilities();
let payload: unknown;
try {
payload = await serverRequest<unknown>(`config/profile?name=${encodeURIComponent(name)}`);
} catch (error) {
if (isOptionalApiRouteMissing(error)) {
modelCapabilitiesRouteMissing = true;
return createFallbackCapabilities();
}
throw error;
}
const raw = isRecord(payload) && isRecord(payload.config) ? payload.config : payload;
const config = isRecord(raw) ? raw : {};
const models = isRecord(config.models) ? config.models : {};
return {
source: "server",
imageModels: normalizeModelList(config.imageModels ?? config.image_models ?? models.image),
videoModels: normalizeModelList(config.videoModels ?? config.video_models ?? models.video),
chatModels: normalizeModelList(config.chatModels ?? config.chat_models ?? models.chat ?? models.agent ?? models.text),
updatedAt: toStringValue((payload as { updatedAt?: unknown; updated_at?: unknown })?.updatedAt ?? (payload as { updated_at?: unknown })?.updated_at),
};
},
};