import { describe, it, expect } from "vitest"; import type { AbstractAgent } from "@ag-ui/client"; import { createCopilotEndpointSingleRoute } from "../endpoints"; import { CopilotRuntime } from "../core/runtime"; describe("CopilotEndpointSingleRoute routing", () => { const createMockRuntime = () => { const createMockAgent = () => { const agent: unknown = { execute: async () => ({ events: [] }), }; (agent as { clone: () => unknown }).clone = () => createMockAgent(); return agent as AbstractAgent; }; return new CopilotRuntime({ agents: { default: createMockAgent(), myAgent: createMockAgent(), agent123: createMockAgent(), "my-agent": createMockAgent(), my_agent: createMockAgent(), testAgent: createMockAgent(), test: createMockAgent(), "test%20agent": createMockAgent(), "test agent": createMockAgent(), }, }); }; const callEndpoint = async (body: Record) => { const runtime = createMockRuntime(); const endpoint = createCopilotEndpointSingleRoute({ runtime, basePath: "/rpc", }); const request = new Request("https://example.com/rpc", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify(body), }); return endpoint.fetch(request); }; describe("agent/run method", () => { it("accepts simple agent names", async () => { const response = await callEndpoint({ method: "agent/run", params: { agentId: "myAgent" }, body: {}, }); expect(response.status).not.toBe(404); }); it("accepts hyphenated agent names", async () => { const response = await callEndpoint({ method: "agent/run", params: { agentId: "my-agent" }, body: {}, }); expect(response.status).not.toBe(404); }); it("accepts underscored agent names", async () => { const response = await callEndpoint({ method: "agent/run", params: { agentId: "my_agent" }, body: {}, }); expect(response.status).not.toBe(404); }); it("returns 400 when agentId missing", async () => { const response = await callEndpoint({ method: "agent/run", body: {}, }); expect(response.status).toBe(400); }); }); describe("agent/connect method", () => { it("accepts standard agent id", async () => { const response = await callEndpoint({ method: "agent/connect", params: { agentId: "agent123" }, body: {}, }); expect(response.status).not.toBe(404); }); }); describe("agent/stop method", () => { it("requires threadId", async () => { const response = await callEndpoint({ method: "agent/stop", params: { agentId: "agent123" }, }); expect(response.status).toBe(400); }); it("returns response when params provided", async () => { const response = await callEndpoint({ method: "agent/stop", params: { agentId: "agent123", threadId: "thread-1" }, }); expect(response.status).not.toBe(404); }); }); describe("info method", () => { it("returns runtime info for base path", async () => { const response = await callEndpoint({ method: "info" }); expect(response.status).toBe(200); const body = await response.json(); expect(body).toHaveProperty("version"); }); it("handles query parameters", async () => { const runtime = createMockRuntime(); const endpoint = createCopilotEndpointSingleRoute({ runtime, basePath: "/rpc", }); const request = new Request("https://example.com/rpc?foo=bar", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ method: "info" }), }); const response = await endpoint.fetch(request); expect(response.status).toBe(200); }); }); describe("transcribe method", () => { it("returns non-404 even without multipart body", async () => { const response = await callEndpoint({ method: "transcribe" }); expect(response.status).not.toBe(404); }); }); describe("invalid inputs", () => { it("returns 415 for non-JSON content", async () => { const runtime = createMockRuntime(); const endpoint = createCopilotEndpointSingleRoute({ runtime, basePath: "/rpc", }); const request = new Request("https://example.com/rpc", { method: "POST", headers: { "content-type": "text/plain" }, body: "method=info", }); const response = await endpoint.fetch(request); expect(response.status).toBe(415); }); it("returns 400 for unsupported method", async () => { const response = await callEndpoint({ method: "unknown" }); expect(response.status).toBe(400); }); it("returns 404 for unmatched path", async () => { const runtime = createMockRuntime(); const endpoint = createCopilotEndpointSingleRoute({ runtime, basePath: "/rpc", }); const request = new Request("https://example.com/other", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ method: "info" }), }); const response = await endpoint.fetch(request); expect(response.status).toBe(404); }); }); });