import fs from "node:fs/promises"; import path from "node:path"; import { describe, expect, it, vi } from "vitest"; import { installModelsConfigTestHooks, withModelsTempHome as withTempHome, } from "./models-config.e2e-harness.js"; import { ensureOpenClawModelsJson } from "./models-config.js"; installModelsConfigTestHooks({ restoreFetch: true }); describe("models-config", () => { it("auto-injects github-copilot provider when token is present", async () => { await withTempHome(async (home) => { const previous = process.env.COPILOT_GITHUB_TOKEN; process.env.COPILOT_GITHUB_TOKEN = "gh-token"; const fetchMock = vi.fn().mockResolvedValue({ ok: true, status: 200, json: async () => ({ token: "copilot-token;proxy-ep=proxy.copilot.example", expires_at: Math.floor(Date.now() / 1000) + 3600, }), }); globalThis.fetch = fetchMock as unknown as typeof fetch; try { const agentDir = path.join(home, "agent-default-base-url"); await ensureOpenClawModelsJson({ models: { providers: {} } }, agentDir); const raw = await fs.readFile(path.join(agentDir, "models.json"), "utf8"); const parsed = JSON.parse(raw) as { providers: Record; }; expect(parsed.providers["github-copilot"]?.baseUrl).toBe("https://api.copilot.example"); expect(parsed.providers["github-copilot"]?.models?.length ?? 0).toBe(0); } finally { if (previous === undefined) { delete process.env.COPILOT_GITHUB_TOKEN; } else { process.env.COPILOT_GITHUB_TOKEN = previous; } } }); }); it("prefers COPILOT_GITHUB_TOKEN over GH_TOKEN and GITHUB_TOKEN", async () => { await withTempHome(async () => { const previous = process.env.COPILOT_GITHUB_TOKEN; const previousGh = process.env.GH_TOKEN; const previousGithub = process.env.GITHUB_TOKEN; process.env.COPILOT_GITHUB_TOKEN = "copilot-token"; process.env.GH_TOKEN = "gh-token"; process.env.GITHUB_TOKEN = "github-token"; const fetchMock = vi.fn().mockResolvedValue({ ok: true, status: 200, json: async () => ({ token: "copilot-token;proxy-ep=proxy.copilot.example", expires_at: Math.floor(Date.now() / 1000) + 3600, }), }); globalThis.fetch = fetchMock as unknown as typeof fetch; try { await ensureOpenClawModelsJson({ models: { providers: {} } }); const [, opts] = fetchMock.mock.calls[0] as [string, { headers?: Record }]; expect(opts?.headers?.Authorization).toBe("Bearer copilot-token"); } finally { process.env.COPILOT_GITHUB_TOKEN = previous; process.env.GH_TOKEN = previousGh; process.env.GITHUB_TOKEN = previousGithub; } }); }); });