hf-space-deployer
HF Space deploy from main - 0b1e82967585f1407bf51086f2e5a962f178218a
371efe0
import type {
BenchmarkQuestion,
DeleteModelResultsResponse,
DatasetOption,
DatasetTemplateRow,
OllamaAuthStatus,
ResultsTableKey,
ResultsResponse,
RunStartResponse,
RunStatusResponse,
SloStatus
} from "./types";
const API_BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL ?? "/api";
const OLLAMA_API_KEY_HEADER = "X-Ollama-API-Key";
export class ApiError extends Error {
status: number;
payload: Record<string, unknown>;
constructor(status: number, message: string, payload: Record<string, unknown> = {}) {
super(message);
this.name = "ApiError";
this.status = status;
this.payload = payload;
}
}
async function parseResponse<T>(res: Response): Promise<T> {
if (!res.ok) {
let detail = `Request failed (${res.status})`;
let payload: Record<string, unknown> = {};
try {
payload = (await res.json()) as Record<string, unknown>;
const rawDetail = payload.detail;
if (typeof rawDetail === "string" && rawDetail.trim()) {
detail = rawDetail;
}
} catch {
// keep default detail
}
throw new ApiError(res.status, detail, payload);
}
return (await res.json()) as T;
}
export function apiBaseUrl(): string {
return API_BASE_URL;
}
export function runEventsUrl(runId: number, sessionId: string): string {
return `${API_BASE_URL}/runs/${runId}/events?session_id=${encodeURIComponent(sessionId)}`;
}
export function datasetTemplateUrl(): string {
return `${API_BASE_URL}/datasets/template`;
}
function buildHeaders(contentType?: string, ollamaApiKey?: string): HeadersInit {
const headers: Record<string, string> = {};
if (contentType) {
headers["Content-Type"] = contentType;
}
if (typeof ollamaApiKey === "string" && ollamaApiKey.trim()) {
headers[OLLAMA_API_KEY_HEADER] = ollamaApiKey.trim();
}
return headers;
}
export async function getHealth(): Promise<{ status: string; version: string }> {
return parseResponse(await fetch(`${API_BASE_URL}/health`, { cache: "no-store" }));
}
export async function getOllamaAuthStatus(): Promise<OllamaAuthStatus> {
return parseResponse(await fetch(`${API_BASE_URL}/ollama/auth-status`, { cache: "no-store" }));
}
export async function getModels(ollamaApiKey?: string): Promise<string[]> {
const payload = await parseResponse<{ models: string[] }>(
await fetch(`${API_BASE_URL}/models`, { cache: "no-store", headers: buildHeaders(undefined, ollamaApiKey) })
);
return payload.models;
}
export async function getDatasets(): Promise<DatasetOption[]> {
const payload = await parseResponse<{ datasets: DatasetOption[] }>(
await fetch(`${API_BASE_URL}/datasets`, { cache: "no-store" })
);
return payload.datasets;
}
export async function getQuestions(datasetKey: string): Promise<{ instruction: string; questions: BenchmarkQuestion[] }> {
const payload = await parseResponse<{
dataset_key: string;
instruction: string;
questions: BenchmarkQuestion[];
}>(await fetch(`${API_BASE_URL}/questions?dataset_key=${encodeURIComponent(datasetKey)}`, { cache: "no-store" }));
return { instruction: payload.instruction, questions: payload.questions };
}
export async function getResults(datasetKey: string): Promise<ResultsResponse> {
return parseResponse(
await fetch(`${API_BASE_URL}/results?dataset_key=${encodeURIComponent(datasetKey)}`, { cache: "no-store" })
);
}
export async function startRun(payload: {
session_id: string;
dataset_key: string;
question_id: string;
models: string[];
system_prompt?: string;
}, ollamaApiKey?: string): Promise<RunStartResponse> {
return parseResponse(
await fetch(`${API_BASE_URL}/runs`, {
method: "POST",
headers: buildHeaders("application/json", ollamaApiKey),
body: JSON.stringify(payload)
})
);
}
export async function stopRun(runId: number, sessionId: string): Promise<{ status: string }> {
return parseResponse(
await fetch(`${API_BASE_URL}/runs/${runId}/stop?session_id=${encodeURIComponent(sessionId)}`, {
method: "POST"
})
);
}
export async function getRunStatus(runId: number, sessionId: string): Promise<RunStatusResponse> {
return parseResponse(
await fetch(`${API_BASE_URL}/runs/${runId}/status?session_id=${encodeURIComponent(sessionId)}`, {
cache: "no-store"
})
);
}
export async function applyManualDecision(payload: {
dataset_key: string;
question_id: string;
model: string;
status: "success" | "fail" | "manual_review";
reason?: string;
}): Promise<{ status: string; result: Record<string, unknown> }> {
return parseResponse(
await fetch(`${API_BASE_URL}/results/manual`, {
method: "PATCH",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload)
})
);
}
export async function uploadDataset(file: File): Promise<{ dataset: DatasetOption }> {
const form = new FormData();
form.append("file", file);
return parseResponse(
await fetch(`${API_BASE_URL}/datasets/upload`, {
method: "POST",
body: form
})
);
}
export async function deleteDataset(datasetKey: string): Promise<{ status: string; summary: Record<string, unknown> }> {
return parseResponse(
await fetch(`${API_BASE_URL}/datasets/${encodeURIComponent(datasetKey)}`, {
method: "DELETE"
})
);
}
export async function deleteModelResults(datasetKey: string, model: string): Promise<DeleteModelResultsResponse> {
return parseResponse(
await fetch(
`${API_BASE_URL}/results/model?dataset_key=${encodeURIComponent(datasetKey)}&model=${encodeURIComponent(model)}`,
{
method: "DELETE"
}
)
);
}
export async function getDatasetTemplate(): Promise<DatasetTemplateRow[]> {
return parseResponse(await fetch(`${API_BASE_URL}/datasets/template`, { cache: "no-store" }));
}
export function exportLink(datasetKey: string, format: "json" | "xlsx"): string {
return `${API_BASE_URL}/results/export?dataset_key=${encodeURIComponent(datasetKey)}&format=${format}`;
}
export function tableExportLink(datasetKey: string, table: ResultsTableKey, format: "json" | "xlsx"): string {
return `${API_BASE_URL}/results/table_export?dataset_key=${encodeURIComponent(datasetKey)}&table=${encodeURIComponent(table)}&format=${format}`;
}
export async function getSloStatus(): Promise<SloStatus> {
return parseResponse(await fetch(`${API_BASE_URL}/ops/slo`, { cache: "no-store" }));
}
export async function resetSloStatus(): Promise<{ status: string; slo: SloStatus }> {
return parseResponse(
await fetch(`${API_BASE_URL}/ops/slo/reset`, {
method: "POST"
})
);
}