import { fileRouter } from "../.."; import { requireSession } from "../../lib/RouteAuth"; import { createAgent, deleteAgent, listAgents, regenerateApiKey, setAgentDisabled, updateAgent, } from "../../lib/AgentService"; import { recordAudit } from "../../lib/Audit"; /* eslint-disable @typescript-eslint/no-explicit-any */ function reply(ctr: any, result: { ok: boolean; status?: number; message?: string; data?: unknown }) { if (!result.ok) { return ctr.status(result.status ?? 400).print({ status: "FAILED", message: result.message }); } return ctr.print({ status: "OK", data: (result as any).data }); } export = new fileRouter.Path("/") // List agents .http("GET", "/api/agents", (http) => http.onRequest(async (ctr) => { const session = requireSession(ctr); if (!session) return; const agents = await listAgents(session.user); return ctr.print({ status: "OK", data: agents }); }), ) // Create agent .http("POST", "/api/agents", (http) => http .ratelimit((limit) => limit.hits(10).window(60000).penalty(2000)) .onRequest(async (ctr) => { const session = requireSession(ctr); if (!session) return; const [data, error] = await ctr.bindBody((z) => z.object({ name: z.string().min(1).max(128), description: z.string().max(500).nullable().optional(), website: z.string().max(300).nullable().optional(), icon_url: z.string().max(1000).nullable().optional(), max_pending_requests: z.number().int().min(1).max(10).optional(), }), ); if (!data) return ctr.status(ctr.$status.BAD_REQUEST).print(error.toString()); const result = await createAgent(session.user, data); if (result.ok) { await recordAudit({ actorId: session.user.id, action: "agent_created", targetType: "agent", targetId: String((result.data as any).id), }); } return reply(ctr, result); }), ) // Update agent .http("PATCH", "/api/agents/{id}", (http) => http.onRequest(async (ctr) => { const session = requireSession(ctr); if (!session) return; const id = Number(ctr.params.get("id")); if (Number.isNaN(id)) { return ctr.status(ctr.$status.BAD_REQUEST).print({ status: "FAILED", message: "Invalid agent id" }); } const [data, error] = await ctr.bindBody((z) => z.object({ name: z.string().min(1).max(128).optional(), description: z.string().max(500).nullable().optional(), website: z.string().max(300).nullable().optional(), icon_url: z.string().max(1000).nullable().optional(), max_pending_requests: z.number().int().min(1).max(10).optional(), }), ); if (!data) return ctr.status(ctr.$status.BAD_REQUEST).print(error.toString()); return reply(ctr, await updateAgent(session.user, id, data)); }), ) // Regenerate API key .http("POST", "/api/agents/{id}/regenerate-key", (http) => http .ratelimit((limit) => limit.hits(10).window(60000).penalty(2000)) .onRequest(async (ctr) => { const session = requireSession(ctr); if (!session) return; const id = Number(ctr.params.get("id")); if (Number.isNaN(id)) { return ctr.status(ctr.$status.BAD_REQUEST).print({ status: "FAILED", message: "Invalid agent id" }); } const result = await regenerateApiKey(session.user, id); if (result.ok) { await recordAudit({ actorId: session.user.id, action: "agent_key_regenerated", targetType: "agent", targetId: String(id), }); } return reply(ctr, result); }), ) // Enable / disable agent .http("POST", "/api/agents/{id}/disabled", (http) => http.onRequest(async (ctr) => { const session = requireSession(ctr); if (!session) return; const id = Number(ctr.params.get("id")); if (Number.isNaN(id)) { return ctr.status(ctr.$status.BAD_REQUEST).print({ status: "FAILED", message: "Invalid agent id" }); } const [data, error] = await ctr.bindBody((z) => z.object({ disabled: z.boolean() })); if (!data) return ctr.status(ctr.$status.BAD_REQUEST).print(error.toString()); return reply(ctr, await setAgentDisabled(session.user, id, data.disabled)); }), ) // Delete agent .http("DELETE", "/api/agents/{id}", (http) => http.onRequest(async (ctr) => { const session = requireSession(ctr); if (!session) return; const id = Number(ctr.params.get("id")); if (Number.isNaN(id)) { return ctr.status(ctr.$status.BAD_REQUEST).print({ status: "FAILED", message: "Invalid agent id" }); } const result = await deleteAgent(session.user, id); if (result.ok) { await recordAudit({ actorId: session.user.id, action: "agent_deleted", targetType: "agent", targetId: String(id), }); } return reply(ctr, result); }), );