import { createCopilotEndpoint } from "../endpoints"; import { CopilotRuntime } from "../core/runtime"; import { describe, it, expect } from "vitest"; import type { AbstractAgent } from "@ag-ui/client"; describe("CopilotEndpoint routing", () => { // Helper function to create a Request object with a given URL const createRequest = (url: string, method: string = "GET"): Request => { return new Request(url, { method }); }; // Create a mock runtime with a basic agent 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(), }, }); }; // Helper to test routing const testRoute = async ( url: string, method: string = "GET", body?: unknown, ) => { const runtime = createMockRuntime(); const endpoint = createCopilotEndpoint({ runtime, basePath: "/" }); const requestInit: RequestInit = { method }; if (body) { requestInit.body = JSON.stringify(body); requestInit.headers = { "Content-Type": "application/json" }; } const request = createRequest(url, method); const response = await endpoint.fetch(request); return response; }; describe("RunAgent route pattern", () => { it("should match agent run URL with simple agent name", async () => { const response = await testRoute( "https://example.com/agent/myAgent/run", "POST", { agentId: "myAgent", }, ); // Should not be 404 expect(response.status).not.toBe(404); }); it("should match agent run URL with alphanumeric agent name", async () => { const response = await testRoute( "https://example.com/agent/agent123/run", "POST", { agentId: "agent123", }, ); expect(response.status).not.toBe(404); }); it("should match agent run URL with hyphenated agent name", async () => { const response = await testRoute( "https://example.com/agent/my-agent/run", "POST", { agentId: "my-agent", }, ); expect(response.status).not.toBe(404); }); it("should match agent run URL with underscored agent name", async () => { const response = await testRoute( "https://example.com/agent/my_agent/run", "POST", { agentId: "my_agent", }, ); expect(response.status).not.toBe(404); }); it("should not match agent run URL with empty agent name", async () => { const response = await testRoute( "https://example.com/agent//run", "POST", ); expect(response.status).toBe(404); const body = await response.json(); expect(body).toEqual({ error: "Not found" }); }); it("should not match partial agent run URL", async () => { const response = await testRoute( "https://example.com/agent/myAgent", "POST", ); expect(response.status).toBe(404); }); it("should not match agent run URL with extra path segments", async () => { const response = await testRoute( "https://example.com/agent/myAgent/run/extra", "POST", ); expect(response.status).toBe(404); }); }); describe("GetRuntimeInfo route pattern (/info endpoint)", () => { it("should match simple info URL", async () => { const response = await testRoute("https://example.com/info"); expect(response.status).toBe(200); const body = await response.json(); expect(body).toHaveProperty("version"); }); it("should match info URL with query parameters", async () => { const response = await testRoute("https://example.com/info?param=value"); expect(response.status).toBe(200); }); it("should not match non-info URLs", async () => { const response = await testRoute("https://example.com/agents"); expect(response.status).toBe(404); }); }); describe("Transcribe route pattern (/transcribe endpoint)", () => { it("should match simple transcribe URL", async () => { // Transcribe expects POST method and audio data const response = await testRoute( "https://example.com/transcribe", "POST", {}, ); // It might return an error since we're not providing audio, but it shouldn't be 404 expect(response.status).not.toBe(404); }); it("should match transcribe URL with query parameters", async () => { const response = await testRoute( "https://example.com/transcribe?format=json", "POST", {}, ); expect(response.status).not.toBe(404); }); it("should not match transcribe URLs with extra path segments", async () => { const response = await testRoute( "https://example.com/transcribe/extra", "POST", ); expect(response.status).toBe(404); }); }); describe("Unmatched routes (404 behavior)", () => { it("should return 404 for root path", async () => { const response = await testRoute("https://example.com/"); expect(response.status).toBe(404); const body = await response.json(); expect(body).toEqual({ error: "Not found" }); }); it("should return 404 for unknown paths", async () => { const response = await testRoute("https://example.com/unknown/path"); expect(response.status).toBe(404); }); it("should return 404 for malformed agent paths", async () => { const response = await testRoute("https://example.com/agent/run", "POST"); expect(response.status).toBe(404); }); it("should return 404 for agents path", async () => { const response = await testRoute("https://example.com/agents"); expect(response.status).toBe(404); }); }); describe("Edge cases", () => { it("should handle URLs with different domains", async () => { const response = await testRoute( "http://localhost:3000/agent/test/run", "POST", { agentId: "test", }, ); expect(response.status).not.toBe(404); }); it("should handle URLs with ports for info endpoint", async () => { const response = await testRoute("https://api.example.com:8080/info"); expect(response.status).toBe(200); }); it("should handle URLs with ports for transcribe endpoint", async () => { const response = await testRoute( "https://api.example.com:8080/transcribe", "POST", {}, ); expect(response.status).not.toBe(404); }); it("should handle URLs with special characters in agent names", async () => { const response = await testRoute( "https://example.com/agent/test%20agent/run", "POST", { agentId: "test%20agent" }, ); expect(response.status).not.toBe(404); }); }); });