From dff6274a932e52d980c91a2e812bfe2acae0dda2 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Tue, 23 Dec 2025 02:48:54 +0100 Subject: [PATCH] test: cover models config merge --- src/agents/models-config.test.ts | 131 +++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 src/agents/models-config.test.ts diff --git a/src/agents/models-config.test.ts b/src/agents/models-config.test.ts new file mode 100644 index 000000000..7f2627ee1 --- /dev/null +++ b/src/agents/models-config.test.ts @@ -0,0 +1,131 @@ +import fs from "node:fs/promises"; +import os from "node:os"; +import path from "node:path"; + +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import type { ClawdisConfig } from "../config/config.js"; + +async function withTempHome(fn: (home: string) => Promise): Promise { + const base = await fs.mkdtemp(path.join(os.tmpdir(), "clawdis-models-")); + const previousHome = process.env.HOME; + process.env.HOME = base; + try { + return await fn(base); + } finally { + process.env.HOME = previousHome; + await fs.rm(base, { recursive: true, force: true }); + } +} + +const MODELS_CONFIG: ClawdisConfig = { + models: { + providers: { + "custom-proxy": { + baseUrl: "http://localhost:4000/v1", + apiKey: "TEST_KEY", + api: "openai-completions", + models: [ + { + id: "llama-3.1-8b", + name: "Llama 3.1 8B (Proxy)", + api: "openai-completions", + reasoning: false, + input: ["text"], + cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + contextWindow: 128000, + maxTokens: 32000, + }, + ], + }, + }, + }, +}; + +describe("models config", () => { + let previousHome: string | undefined; + + beforeEach(() => { + previousHome = process.env.HOME; + }); + + afterEach(() => { + process.env.HOME = previousHome; + }); + + it("writes models.json for configured providers", async () => { + await withTempHome(async () => { + vi.resetModules(); + const { ensureClawdisModelsJson } = await import("./models-config.js"); + const { resolveClawdisAgentDir } = await import("./agent-paths.js"); + + await ensureClawdisModelsJson(MODELS_CONFIG); + + const modelPath = path.join( + resolveClawdisAgentDir(), + "models.json", + ); + const raw = await fs.readFile(modelPath, "utf8"); + const parsed = JSON.parse(raw) as { + providers: Record; + }; + + expect(parsed.providers["custom-proxy"]?.baseUrl).toBe( + "http://localhost:4000/v1", + ); + }); + }); + + it("merges providers by default", async () => { + await withTempHome(async () => { + vi.resetModules(); + const { ensureClawdisModelsJson } = await import("./models-config.js"); + const { resolveClawdisAgentDir } = await import("./agent-paths.js"); + + const agentDir = resolveClawdisAgentDir(); + await fs.mkdir(agentDir, { recursive: true }); + await fs.writeFile( + path.join(agentDir, "models.json"), + JSON.stringify( + { + providers: { + existing: { + baseUrl: "http://localhost:1234/v1", + apiKey: "EXISTING_KEY", + api: "openai-completions", + models: [ + { + id: "existing-model", + name: "Existing", + api: "openai-completions", + reasoning: false, + input: ["text"], + cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + contextWindow: 8192, + maxTokens: 2048, + }, + ], + }, + }, + }, + null, + 2, + ), + "utf8", + ); + + await ensureClawdisModelsJson(MODELS_CONFIG); + + const raw = await fs.readFile(path.join(agentDir, "models.json"), "utf8"); + const parsed = JSON.parse(raw) as { + providers: Record; + }; + + expect(parsed.providers.existing?.baseUrl).toBe( + "http://localhost:1234/v1", + ); + expect(parsed.providers["custom-proxy"]?.baseUrl).toBe( + "http://localhost:4000/v1", + ); + }); + }); +});