92b90447e8
internal/config,server: implement model capabilities - define the capabilities of a model using a simple config block on the model - v1/models renders out capabilities to be compatible with openrouter, huggingface chat, and mistral formats for broader compatibility - add support for capabilities in UI Fixes #734
51 lines
1.4 KiB
TypeScript
51 lines
1.4 KiB
TypeScript
import type { Model } from "./types";
|
|
|
|
export interface GroupedModels {
|
|
local: Model[];
|
|
localMatching: Model[];
|
|
peersByProvider: Record<string, Model[]>;
|
|
}
|
|
|
|
export function matchesCapabilities(model: Model, required: string[], matchAny = false): boolean {
|
|
if (!required.length) return true;
|
|
if (!model.capabilities) return false;
|
|
const caps = model.capabilities as Record<string, boolean>;
|
|
if (matchAny) {
|
|
return required.some((cap) => caps[cap] === true);
|
|
}
|
|
return required.every((cap) => caps[cap] === true);
|
|
}
|
|
|
|
export function groupModels(models: Model[], capabilities?: string[], matchAny = false): GroupedModels {
|
|
const available = models.filter((m) => !m.unlisted);
|
|
const local = available.filter((m) => !m.peerID);
|
|
const peerModels = available.filter((m) => m.peerID);
|
|
|
|
let localMatching: Model[] = [];
|
|
let localRest: Model[] = [];
|
|
|
|
if (capabilities && capabilities.length > 0) {
|
|
for (const model of local) {
|
|
if (matchesCapabilities(model, capabilities, matchAny)) {
|
|
localMatching.push(model);
|
|
} else {
|
|
localRest.push(model);
|
|
}
|
|
}
|
|
} else {
|
|
localRest = local;
|
|
}
|
|
|
|
const peersByProvider = peerModels.reduce(
|
|
(acc, model) => {
|
|
const peerId = model.peerID || "unknown";
|
|
if (!acc[peerId]) acc[peerId] = [];
|
|
acc[peerId].push(model);
|
|
return acc;
|
|
},
|
|
{} as Record<string, Model[]>
|
|
);
|
|
|
|
return { local: localRest, localMatching, peersByProvider };
|
|
}
|