Spaces:
Sleeping
Sleeping
File size: 1,539 Bytes
5456422 | 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 | import type { Brief, RunResponse, Stats } from "./types";
const API_URL = process.env.NEXT_PUBLIC_API_URL ?? "http://localhost:8000";
/** Raised for any non-OK API response, with a user-friendly message. */
export class ApiError extends Error {
status: number;
constructor(message: string, status: number) {
super(message);
this.name = "ApiError";
this.status = status;
}
}
async function parseError(res: Response): Promise<string> {
if (res.status === 429) {
return "Rate limit reached (10 runs/minute). Give it a minute and try again.";
}
try {
const data = await res.json();
if (data?.detail) return String(data.detail);
} catch {
/* fall through to generic */
}
return `Request failed (${res.status}).`;
}
export async function getStats(): Promise<Stats> {
const res = await fetch(`${API_URL}/stats`, { cache: "no-store" });
if (!res.ok) throw new ApiError(await parseError(res), res.status);
return res.json();
}
export async function runAgent(brief: Brief): Promise<RunResponse> {
let res: Response;
try {
res = await fetch(`${API_URL}/run`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(brief),
});
} catch {
// Network / CORS / backend down.
throw new ApiError(
"Could not reach the backend. Is the API running and NEXT_PUBLIC_API_URL set correctly?",
0,
);
}
if (!res.ok) throw new ApiError(await parseError(res), res.status);
return res.json();
}
export { API_URL };
|