import { describe, expect, it } from "vitest"; import * as harness from "../src/index.js"; type Input = { providerId: string; api: "openai-responses" | "openai-completions" | "anthropic-messages"; apiKey?: string; baseUrl?: string; modelId: string; displayName?: string; supportsImages: boolean; contextWindow?: number; maxTokens?: number; }; type Resolved = { connection: Input; apiKey?: string; source: "session" | "environment" }; type Store = { configure(sessionId: string, input: Input): Promise; getRedacted(sessionId: string): Record; resolveConnection(sessionId: string): Resolved; clearCredentials(sessionId: string): void; }; function input(overrides: Partial = {}): Input { return { providerId: "training-openai", api: "openai-responses", apiKey: "sk-test-secret", baseUrl: "https://api.example.com/v1", modelId: "training-model", displayName: "Training Model", supportsImages: true, contextWindow: 32_000, maxTokens: 4_096, ...overrides, }; } function createStore(environment?: Input): Store { const Constructor = Reflect.get(harness, "InMemoryModelConnectionStore") as unknown as | (new (options?: Record) => Store) | undefined; expect(Constructor, "InMemoryModelConnectionStore must be exported").toBeDefined(); return new Constructor!({ ...(environment === undefined ? {} : { environment }), validateUrl: (url: string) => Promise.resolve({ normalizedUrl: url, addresses: ["93.184.216.34"], redirectPolicy: "same-origin" }), }); } describe("InMemoryModelConnectionStore", () => { it("never returns the raw key", async () => { const store = createStore(); await store.configure("ses_1", input()); const json = JSON.stringify(store.getRedacted("ses_1")); expect(json).not.toContain("sk-test-secret"); expect(store.getRedacted("ses_1").keyHint).toBe("••••cret"); }); it("uses session config before environment and falls back after an idempotent clear", async () => { const store = createStore(input({ providerId: "env-provider", apiKey: "env-secret", modelId: "env-model" })); await store.configure("ses_1", input({ apiKey: "session-secret" })); expect(store.resolveConnection("ses_1")).toMatchObject({ source: "session", apiKey: "session-secret" }); store.clearCredentials("ses_1"); store.clearCredentials("ses_1"); expect(store.resolveConnection("ses_1")).toMatchObject({ source: "environment", apiKey: "env-secret" }); }); it("rotates keys without exposing the old credential", async () => { const store = createStore(); await store.configure("ses_1", input({ apiKey: "first-secret" })); await store.configure("ses_1", input({ apiKey: "second-secret" })); expect(store.resolveConnection("ses_1").apiKey).toBe("second-secret"); expect(JSON.stringify(store.getRedacted("ses_1"))).not.toContain("first-secret"); }); it("fails explicitly when no connection is configured", () => { const store = createStore(); expect(() => store.resolveConnection("ses_missing")).toThrowError( expect.objectContaining({ code: "MODEL_NOT_CONFIGURED" }), ); }); it.each([ input({ providerId: "anthropic", api: "openai-responses" }), input({ providerId: "openai", api: "anthropic-messages" }), ])("rejects a built-in provider/API mismatch", async (invalid) => { await expect(createStore().configure("ses_1", invalid)).rejects.toMatchObject({ code: "MODEL_API_MISMATCH", }); }); it("creates a Pi runtime with only the configured model and in-memory credentials", async () => { const createRuntime = Reflect.get(harness, "createPiModelRuntime") as | ((resolved: Resolved) => Promise<{ getModel(providerId: string, modelId: string): unknown; getAuth(providerId: string): Promise }>) | undefined; expect(createRuntime, "createPiModelRuntime must be exported").toBeDefined(); const resolved = { connection: input(), apiKey: "runtime-secret", source: "session" as const }; const runtime = await createRuntime!(resolved); expect(runtime.getModel("training-openai", "training-model")).toBeDefined(); expect(await runtime.getAuth("training-openai")).toMatchObject({ auth: { apiKey: "runtime-secret" } }); }); });