File size: 2,350 Bytes
96f2542 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | export type Lang = { code: string; label: string };
export type ParamSpec = {
name: string;
label: string;
type: "float" | "int" | "bool" | "enum";
default: number | string | boolean;
min?: number;
max?: number;
step?: number;
choices?: string[];
help?: string;
};
export type ModelInfo = {
id: string;
label: string;
description: string;
languages: Lang[];
paralinguistic_tags: string[];
supports_voice_clone: boolean;
params: ParamSpec[];
};
export type ActiveStatus = {
id: string | null;
status: "idle" | "loading" | "loaded" | "error";
last_error: string | null;
};
export async function listModels(): Promise<ModelInfo[]> {
const r = await fetch("/api/models");
if (!r.ok) throw new Error(`listModels: ${r.status}`);
return r.json();
}
export async function getActiveModel(): Promise<ActiveStatus> {
const r = await fetch("/api/models/active");
if (!r.ok) throw new Error(`getActiveModel: ${r.status}`);
return r.json();
}
export async function activateModel(id: string): Promise<void> {
const r = await fetch(`/api/models/${encodeURIComponent(id)}/activate`, { method: "POST" });
if (!r.ok) {
const err = await r.json().catch(() => ({}));
throw new Error(err?.error?.code ?? `activateModel: ${r.status}`);
}
}
export type GenerateInput = {
modelId: string;
text: string;
language?: string;
params: Record<string, unknown>;
reference?: Blob;
};
export async function generate(input: GenerateInput): Promise<Blob> {
const fd = new FormData();
fd.set("text", input.text);
fd.set("model_id", input.modelId);
fd.set("params", JSON.stringify(input.params ?? {}));
if (input.language) fd.set("language", input.language);
if (input.reference) fd.set("reference_wav", input.reference, "ref.wav");
const r = await fetch("/api/generate", { method: "POST", body: fd });
if (!r.ok) {
const err = await r.json().catch(() => ({}));
throw new Error(err?.error?.code ?? `generate: ${r.status}`);
}
return r.blob();
}
export function streamActiveEvents(
onEvent: (e: { id: string | null; status: string; error?: string }) => void,
) {
const es = new EventSource("/api/models/active/events");
es.onmessage = (m) => {
try {
onEvent(JSON.parse(m.data));
} catch {
/* ignore malformed */
}
};
return () => es.close();
}
|