import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; const hoisted = vi.hoisted(() => ({ getApiKeyForModel: vi.fn(), resolveApiKeyForProvider: vi.fn(), prepareProviderRuntimeAuth: vi.fn(), })); vi.mock("../../agents/model-auth.js", () => ({ getApiKeyForModel: hoisted.getApiKeyForModel, resolveApiKeyForProvider: hoisted.resolveApiKeyForProvider, })); vi.mock("../provider-runtime.runtime.js", () => ({ prepareProviderRuntimeAuth: hoisted.prepareProviderRuntimeAuth, })); let getRuntimeAuthForModel: typeof import("./runtime-model-auth.runtime.js").getRuntimeAuthForModel; const MODEL = { id: "github-copilot/gpt-4o", provider: "github-copilot", api: "openai-responses", baseUrl: "https://api.githubcopilot.com", }; describe("runtime-model-auth.runtime", () => { beforeAll(async () => { ({ getRuntimeAuthForModel } = await import("./runtime-model-auth.runtime.js")); }); beforeEach(() => { hoisted.getApiKeyForModel.mockReset(); hoisted.resolveApiKeyForProvider.mockReset(); hoisted.prepareProviderRuntimeAuth.mockReset(); }); it("returns provider-prepared runtime auth when the provider transforms credentials", async () => { hoisted.getApiKeyForModel.mockResolvedValue({ apiKey: "github-device-token", source: "profile:github-copilot:github", mode: "token", profileId: "github-copilot:github", }); hoisted.prepareProviderRuntimeAuth.mockResolvedValue({ apiKey: "copilot-bearer-token", baseUrl: "https://api.individual.githubcopilot.com", expiresAt: 123, }); await expect( getRuntimeAuthForModel({ model: MODEL as never, }), ).resolves.toEqual({ apiKey: "copilot-bearer-token", source: "profile:github-copilot:github", mode: "token", profileId: "github-copilot:github", baseUrl: "https://api.individual.githubcopilot.com", expiresAt: 123, }); expect(hoisted.prepareProviderRuntimeAuth).toHaveBeenCalledWith( expect.objectContaining({ provider: "github-copilot", context: expect.objectContaining({ apiKey: "github-device-token", modelId: "github-copilot/gpt-4o", provider: "github-copilot", }), }), ); }); it("falls back to raw auth when the provider has no runtime auth hook", async () => { hoisted.getApiKeyForModel.mockResolvedValue({ apiKey: "plain-api-key", source: "env:OPENAI_API_KEY", mode: "api-key", }); hoisted.prepareProviderRuntimeAuth.mockResolvedValue(undefined); await expect( getRuntimeAuthForModel({ model: { ...MODEL, id: "openai/gpt-5.4", provider: "openai", } as never, }), ).resolves.toEqual({ apiKey: "plain-api-key", source: "env:OPENAI_API_KEY", mode: "api-key", }); }); it("skips provider preparation when raw auth does not expose an apiKey", async () => { hoisted.getApiKeyForModel.mockResolvedValue({ source: "env:AWS_PROFILE", mode: "aws-sdk", }); await expect( getRuntimeAuthForModel({ model: { ...MODEL, id: "bedrock/claude-sonnet", provider: "bedrock", } as never, }), ).resolves.toEqual({ source: "env:AWS_PROFILE", mode: "aws-sdk", }); expect(hoisted.prepareProviderRuntimeAuth).not.toHaveBeenCalled(); }); });