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", ); }); }); });