import { type AgentResponse, type AgentStatusResponse, type AgentWebhookConfig } from "../types"; import { HttpClient } from "../utils/httpClient"; import { normalizeAxiosError, throwForBadResponse } from "../utils/errorHandler"; import { isZodSchema, zodSchemaToJsonSchema } from "../../utils/zodSchemaToJson"; import type { ZodTypeAny } from "zod"; function prepareAgentPayload(args: { urls?: string[]; prompt: string; schema?: Record | ZodTypeAny; integration?: string; origin?: string; maxCredits?: number; strictConstrainToURLs?: boolean; model?: "spark-1-pro" | "spark-1-mini"; webhook?: string | AgentWebhookConfig; }): Record { const body: Record = {}; if (args.urls) body.urls = args.urls; body.prompt = args.prompt; if (args.schema != null) { body.schema = isZodSchema(args.schema) ? zodSchemaToJsonSchema(args.schema) : args.schema; } if (args.integration && args.integration.trim()) body.integration = args.integration.trim(); if (args.origin) body.origin = args.origin; if (args.maxCredits !== null && args.maxCredits !== undefined) body.maxCredits = args.maxCredits; if (args.strictConstrainToURLs !== null && args.strictConstrainToURLs !== undefined) body.strictConstrainToURLs = args.strictConstrainToURLs; if (args.model !== null && args.model !== undefined) body.model = args.model; if (args.webhook != null) body.webhook = args.webhook; return body; } export async function startAgent(http: HttpClient, args: Parameters[0]): Promise { const payload = prepareAgentPayload(args); try { const res = await http.post("/v2/agent", payload); if (res.status !== 200) throwForBadResponse(res, "agent"); return res.data; } catch (err: any) { if (err?.isAxiosError) return normalizeAxiosError(err, "agent"); throw err; } } export async function getAgentStatus(http: HttpClient, jobId: string): Promise { try { const res = await http.get(`/v2/agent/${jobId}`); if (res.status !== 200) throwForBadResponse(res, "agent status"); return res.data; } catch (err: any) { if (err?.isAxiosError) return normalizeAxiosError(err, "agent status"); throw err; } } export async function waitAgent( http: HttpClient, jobId: string, pollInterval = 2, timeout?: number ): Promise { const start = Date.now(); while (true) { const status = await getAgentStatus(http, jobId); if (["completed", "failed", "cancelled"].includes(status.status || "")) return status; if (timeout != null && Date.now() - start > timeout * 1000) return status; await new Promise((r) => setTimeout(r, Math.max(1000, pollInterval * 1000))); } } export async function agent( http: HttpClient, args: Parameters[0] & { pollInterval?: number; timeout?: number } ): Promise { const started = await startAgent(http, args); const jobId = started.id; if (!jobId) return started as unknown as AgentStatusResponse; return waitAgent(http, jobId, args.pollInterval ?? 2, args.timeout); } export async function cancelAgent(http: HttpClient, jobId: string): Promise { try { const res = await http.delete<{ success: boolean }>(`/v2/agent/${jobId}`); if (res.status !== 200) throwForBadResponse(res, "cancel agent"); return res.data?.success === true; } catch (err: any) { if (err?.isAxiosError) return normalizeAxiosError(err, "cancel agent"); throw err; } }