import { getBackendBaseURL } from "@/core/config"; import type { Agent, CreateAgentRequest, UpdateAgentRequest } from "./types"; const BACKEND_UNAVAILABLE_STATUSES = new Set([502, 503, 504]); export class AgentNameCheckError extends Error { constructor( message: string, public readonly reason: "backend_unreachable" | "request_failed", ) { super(message); this.name = "AgentNameCheckError"; } } export async function listAgents(): Promise { const res = await fetch(`${getBackendBaseURL()}/api/agents`); if (!res.ok) throw new Error(`Failed to load agents: ${res.statusText}`); const data = (await res.json()) as { agents: Agent[] }; return data.agents; } export async function getAgent(name: string): Promise { const res = await fetch(`${getBackendBaseURL()}/api/agents/${name}`); if (!res.ok) throw new Error(`Agent '${name}' not found`); return res.json() as Promise; } export async function createAgent(request: CreateAgentRequest): Promise { const res = await fetch(`${getBackendBaseURL()}/api/agents`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(request), }); if (!res.ok) { const err = (await res.json().catch(() => ({}))) as { detail?: string }; throw new Error(err.detail ?? `Failed to create agent: ${res.statusText}`); } return res.json() as Promise; } export async function updateAgent( name: string, request: UpdateAgentRequest, ): Promise { const res = await fetch(`${getBackendBaseURL()}/api/agents/${name}`, { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify(request), }); if (!res.ok) { const err = (await res.json().catch(() => ({}))) as { detail?: string }; throw new Error(err.detail ?? `Failed to update agent: ${res.statusText}`); } return res.json() as Promise; } export async function deleteAgent(name: string): Promise { const res = await fetch(`${getBackendBaseURL()}/api/agents/${name}`, { method: "DELETE", }); if (!res.ok) throw new Error(`Failed to delete agent: ${res.statusText}`); } export async function checkAgentName( name: string, ): Promise<{ available: boolean; name: string }> { let res: Response; try { res = await fetch( `${getBackendBaseURL()}/api/agents/check?name=${encodeURIComponent(name)}`, ); } catch { throw new AgentNameCheckError( "Could not reach the DeerFlow backend.", "backend_unreachable", ); } if (!res.ok) { const err = (await res.json().catch(() => ({}))) as { detail?: string }; if (BACKEND_UNAVAILABLE_STATUSES.has(res.status)) { throw new AgentNameCheckError( "Could not reach the DeerFlow backend.", "backend_unreachable", ); } throw new AgentNameCheckError( err.detail ?? `Failed to check agent name: ${res.statusText}`, "request_failed", ); } return res.json() as Promise<{ available: boolean; name: string }>; }