From 15388130968b95769ccefe62acbcba2c8ee64ed4 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Tue, 3 Mar 2026 02:49:26 +0000 Subject: [PATCH] refactor(agents): dedupe ollama provider test scaffolding --- .../models-config.providers.ollama.test.ts | 169 +++++++++--------- 1 file changed, 80 insertions(+), 89 deletions(-) diff --git a/src/agents/models-config.providers.ollama.test.ts b/src/agents/models-config.providers.ollama.test.ts index 353819cb3c1..9531e20e7eb 100644 --- a/src/agents/models-config.providers.ollama.test.ts +++ b/src/agents/models-config.providers.ollama.test.ts @@ -31,34 +31,73 @@ describe("resolveOllamaApiBase", () => { }); describe("Ollama provider", () => { + const createAgentDir = () => mkdtempSync(join(tmpdir(), "openclaw-test-")); + + const enableDiscoveryEnv = () => { + vi.stubEnv("VITEST", ""); + vi.stubEnv("NODE_ENV", "development"); + }; + + const fetchCallUrls = (fetchMock: ReturnType): string[] => + fetchMock.mock.calls.map(([input]) => String(input)); + + const expectDiscoveryCallCounts = ( + fetchMock: ReturnType, + params: { tags: number; show: number }, + ) => { + const urls = fetchCallUrls(fetchMock); + expect(urls.filter((url) => url.endsWith("/api/tags"))).toHaveLength(params.tags); + expect(urls.filter((url) => url.endsWith("/api/show"))).toHaveLength(params.show); + }; + + async function withOllamaApiKey(run: () => Promise): Promise { + process.env.OLLAMA_API_KEY = "test-key"; + try { + return await run(); + } finally { + delete process.env.OLLAMA_API_KEY; + } + } + + async function resolveProvidersWithOllamaKey(agentDir: string) { + return await withOllamaApiKey(async () => await resolveImplicitProviders({ agentDir })); + } + + const createTagModel = (name: string) => ({ name, modified_at: "", size: 1, digest: "" }); + + const tagsResponse = (names: string[]) => ({ + ok: true, + json: async () => ({ models: names.map((name) => createTagModel(name)) }), + }); + + const notFoundJsonResponse = () => ({ + ok: false, + status: 404, + json: async () => ({}), + }); + it("should not include ollama when no API key is configured", async () => { - const agentDir = mkdtempSync(join(tmpdir(), "openclaw-test-")); + const agentDir = createAgentDir(); const providers = await resolveImplicitProviders({ agentDir }); expect(providers?.ollama).toBeUndefined(); }); it("should use native ollama api type", async () => { - const agentDir = mkdtempSync(join(tmpdir(), "openclaw-test-")); - process.env.OLLAMA_API_KEY = "test-key"; - - try { + const agentDir = createAgentDir(); + await withOllamaApiKey(async () => { const providers = await resolveImplicitProviders({ agentDir }); expect(providers?.ollama).toBeDefined(); expect(providers?.ollama?.apiKey).toBe("OLLAMA_API_KEY"); expect(providers?.ollama?.api).toBe("ollama"); expect(providers?.ollama?.baseUrl).toBe("http://127.0.0.1:11434"); - } finally { - delete process.env.OLLAMA_API_KEY; - } + }); }); it("should preserve explicit ollama baseUrl on implicit provider injection", async () => { - const agentDir = mkdtempSync(join(tmpdir(), "openclaw-test-")); - process.env.OLLAMA_API_KEY = "test-key"; - - try { + const agentDir = createAgentDir(); + await withOllamaApiKey(async () => { const providers = await resolveImplicitProviders({ agentDir, explicitProviders: { @@ -72,28 +111,16 @@ describe("Ollama provider", () => { // Native API strips /v1 suffix via resolveOllamaApiBase() expect(providers?.ollama?.baseUrl).toBe("http://192.168.20.14:11434"); - } finally { - delete process.env.OLLAMA_API_KEY; - } + }); }); it("discovers per-model context windows from /api/show", async () => { - const agentDir = mkdtempSync(join(tmpdir(), "openclaw-test-")); - process.env.OLLAMA_API_KEY = "test-key"; - vi.stubEnv("VITEST", ""); - vi.stubEnv("NODE_ENV", "development"); + const agentDir = createAgentDir(); + enableDiscoveryEnv(); const fetchMock = vi.fn(async (input: unknown, init?: RequestInit) => { const url = String(input); if (url.endsWith("/api/tags")) { - return { - ok: true, - json: async () => ({ - models: [ - { name: "qwen3:32b", modified_at: "", size: 1, digest: "" }, - { name: "llama3.3:70b", modified_at: "", size: 1, digest: "" }, - ], - }), - }; + return tagsResponse(["qwen3:32b", "llama3.3:70b"]); } if (url.endsWith("/api/show")) { const rawBody = init?.body; @@ -112,43 +139,26 @@ describe("Ollama provider", () => { }; } } - return { - ok: false, - status: 404, - json: async () => ({}), - }; + return notFoundJsonResponse(); }); vi.stubGlobal("fetch", fetchMock); - try { - const providers = await resolveImplicitProviders({ agentDir }); - const models = providers?.ollama?.models ?? []; - const qwen = models.find((model) => model.id === "qwen3:32b"); - const llama = models.find((model) => model.id === "llama3.3:70b"); - expect(qwen?.contextWindow).toBe(131072); - expect(llama?.contextWindow).toBe(65536); - const urls = fetchMock.mock.calls.map(([input]) => String(input)); - expect(urls.filter((url) => url.endsWith("/api/tags"))).toHaveLength(1); - expect(urls.filter((url) => url.endsWith("/api/show"))).toHaveLength(2); - } finally { - delete process.env.OLLAMA_API_KEY; - } + const providers = await resolveProvidersWithOllamaKey(agentDir); + const models = providers?.ollama?.models ?? []; + const qwen = models.find((model) => model.id === "qwen3:32b"); + const llama = models.find((model) => model.id === "llama3.3:70b"); + expect(qwen?.contextWindow).toBe(131072); + expect(llama?.contextWindow).toBe(65536); + expectDiscoveryCallCounts(fetchMock, { tags: 1, show: 2 }); }); it("falls back to default context window when /api/show fails", async () => { - const agentDir = mkdtempSync(join(tmpdir(), "openclaw-test-")); - process.env.OLLAMA_API_KEY = "test-key"; - vi.stubEnv("VITEST", ""); - vi.stubEnv("NODE_ENV", "development"); + const agentDir = createAgentDir(); + enableDiscoveryEnv(); const fetchMock = vi.fn(async (input: unknown) => { const url = String(input); if (url.endsWith("/api/tags")) { - return { - ok: true, - json: async () => ({ - models: [{ name: "qwen3:32b", modified_at: "", size: 1, digest: "" }], - }), - }; + return tagsResponse(["qwen3:32b"]); } if (url.endsWith("/api/show")) { return { @@ -156,31 +166,19 @@ describe("Ollama provider", () => { status: 500, }; } - return { - ok: false, - status: 404, - json: async () => ({}), - }; + return notFoundJsonResponse(); }); vi.stubGlobal("fetch", fetchMock); - try { - const providers = await resolveImplicitProviders({ agentDir }); - const model = providers?.ollama?.models?.find((entry) => entry.id === "qwen3:32b"); - expect(model?.contextWindow).toBe(128000); - const urls = fetchMock.mock.calls.map(([input]) => String(input)); - expect(urls.filter((url) => url.endsWith("/api/tags"))).toHaveLength(1); - expect(urls.filter((url) => url.endsWith("/api/show"))).toHaveLength(1); - } finally { - delete process.env.OLLAMA_API_KEY; - } + const providers = await resolveProvidersWithOllamaKey(agentDir); + const model = providers?.ollama?.models?.find((entry) => entry.id === "qwen3:32b"); + expect(model?.contextWindow).toBe(128000); + expectDiscoveryCallCounts(fetchMock, { tags: 1, show: 1 }); }); it("caps /api/show requests when /api/tags returns a very large model list", async () => { - const agentDir = mkdtempSync(join(tmpdir(), "openclaw-test-")); - process.env.OLLAMA_API_KEY = "test-key"; - vi.stubEnv("VITEST", ""); - vi.stubEnv("NODE_ENV", "development"); + const agentDir = createAgentDir(); + enableDiscoveryEnv(); const manyModels = Array.from({ length: 250 }, (_, idx) => ({ name: `model-${idx}`, modified_at: "", @@ -202,17 +200,11 @@ describe("Ollama provider", () => { }); vi.stubGlobal("fetch", fetchMock); - try { - const providers = await resolveImplicitProviders({ agentDir }); - const models = providers?.ollama?.models ?? []; - const urls = fetchMock.mock.calls.map(([input]) => String(input)); - // 1 call for /api/tags + 200 capped /api/show calls. - expect(urls.filter((url) => url.endsWith("/api/tags"))).toHaveLength(1); - expect(urls.filter((url) => url.endsWith("/api/show"))).toHaveLength(200); - expect(models).toHaveLength(200); - } finally { - delete process.env.OLLAMA_API_KEY; - } + const providers = await resolveProvidersWithOllamaKey(agentDir); + const models = providers?.ollama?.models ?? []; + // 1 call for /api/tags + 200 capped /api/show calls. + expectDiscoveryCallCounts(fetchMock, { tags: 1, show: 200 }); + expect(models).toHaveLength(200); }); it("should have correct model structure without streaming override", () => { @@ -231,9 +223,8 @@ describe("Ollama provider", () => { }); it("should skip discovery fetch when explicit models are configured", async () => { - const agentDir = mkdtempSync(join(tmpdir(), "openclaw-test-")); - vi.stubEnv("VITEST", ""); - vi.stubEnv("NODE_ENV", "development"); + const agentDir = createAgentDir(); + enableDiscoveryEnv(); const fetchMock = vi.fn(); vi.stubGlobal("fetch", fetchMock); const explicitModels: ModelDefinitionConfig[] = [