vibeguard/src/inference/model-metadata.ts

36 lines
1.3 KiB
TypeScript

export interface ModelManifest {
source: string;
revision: string;
architecture: string;
labels: {
toxic: number;
nonToxic: number;
names: Record<string, number>;
};
maxLength: number;
quantization: string;
runtime: string;
}
let manifestPromise: Promise<ModelManifest> | undefined;
export function modelBaseUrl(): string {
return chrome.runtime.getURL("models/toxicity/");
}
export function loadModelManifest(): Promise<ModelManifest> {
manifestPromise ??= fetch(`${modelBaseUrl()}model-manifest.json`)
.then((response) => {
if (!response.ok) throw new Error(`VibeGuard model metadata unavailable (${response.status})`);
return response.json() as Promise<ModelManifest>;
})
.then(validateManifest);
return manifestPromise;
}
export function validateManifest(value: ModelManifest): ModelManifest {
if (!value || typeof value.source !== "string" || typeof value.revision !== "string") throw new Error("Invalid VibeGuard model manifest");
if (!Number.isInteger(value.labels?.toxic) || !Number.isInteger(value.labels?.nonToxic) || value.labels.toxic === value.labels.nonToxic || !value.labels?.names) throw new Error("Model manifest has no binary label mapping");
if (!Number.isInteger(value.maxLength) || value.maxLength < 8) throw new Error("Model manifest has an invalid maximum length");
return value;
}