import { describe, expect, it } from "vitest"; import { discoverLocalProviders } from "./index.js"; /** Build a mock fetch that returns a models catalog for a given URL. */ function mockFetch( catalog: Record, ): typeof fetch { return ((url: string) => { if (catalog[url]) { return Promise.resolve( new Response(JSON.stringify(catalog[url]), { status: 200, headers: { "content-type": "application/json" }, }), ); } return Promise.reject(new Error("not found")); }) as unknown as typeof fetch; } describe("discoverLocalProviders", () => { it("detects a running Ollama server", async () => { const results = await discoverLocalProviders({ timeoutMs: 200, fetchImpl: mockFetch({ "http://localhost:11434/v1/models": { object: "list", data: [ { id: "llama3.1", owned_by: "ollama" }, { id: "mistral", owned_by: "ollama" }, ], }, }), }); expect(results).toHaveLength(1); expect(results[0]!.endpoint).toBe("http://localhost:11434/v1/models"); expect(results[0]!.kind).toBe("openai-compatible"); expect(results[0]!.models.map((m) => m.id)).toEqual(["llama3.1", "mistral"]); }); it("returns an empty array when no endpoints respond", async () => { const results = await discoverLocalProviders({ timeoutMs: 100, fetchImpl: mockFetch({}), }); expect(results).toEqual([]); }); it("ignores endpoints that return no models", async () => { const results = await discoverLocalProviders({ timeoutMs: 200, fetchImpl: mockFetch({ "http://localhost:1234/v1/models": { object: "list", data: [] }, }), }); expect(results).toEqual([]); }); it("probes multiple endpoints and collects all responders", async () => { const results = await discoverLocalProviders({ timeoutMs: 200, fetchImpl: mockFetch({ "http://localhost:11434/v1/models": { object: "list", data: [{ id: "llama3.1" }], }, "http://localhost:1234/v1/models": { object: "list", data: [{ id: "qwen2.5" }], }, }), }); expect(results).toHaveLength(2); const ids = results.flatMap((r) => r.models.map((m) => m.id)); expect(ids).toContain("llama3.1"); expect(ids).toContain("qwen2.5"); }); });