import { afterEach, describe, expect, it, vi } from "vitest"; import { buildOpenAIImageGenerationProvider } from "./image-generation-provider.js"; const { resolveApiKeyForProviderMock, postJsonRequestMock, assertOkOrThrowHttpErrorMock, resolveProviderHttpRequestConfigMock, } = vi.hoisted(() => ({ resolveApiKeyForProviderMock: vi.fn(async () => ({ apiKey: "openai-key" })), postJsonRequestMock: vi.fn(), assertOkOrThrowHttpErrorMock: vi.fn(async () => {}), resolveProviderHttpRequestConfigMock: vi.fn((params) => ({ baseUrl: params.baseUrl ?? params.defaultBaseUrl, allowPrivateNetwork: Boolean(params.allowPrivateNetwork), headers: new Headers(params.defaultHeaders), dispatcherPolicy: undefined, })), })); vi.mock("openclaw/plugin-sdk/provider-auth-runtime", () => ({ resolveApiKeyForProvider: resolveApiKeyForProviderMock, })); vi.mock("openclaw/plugin-sdk/provider-http", () => ({ assertOkOrThrowHttpError: assertOkOrThrowHttpErrorMock, postJsonRequest: postJsonRequestMock, resolveProviderHttpRequestConfig: resolveProviderHttpRequestConfigMock, })); describe("openai image generation provider", () => { afterEach(() => { resolveApiKeyForProviderMock.mockClear(); postJsonRequestMock.mockReset(); assertOkOrThrowHttpErrorMock.mockClear(); resolveProviderHttpRequestConfigMock.mockClear(); }); it("does not auto-allow local baseUrl overrides for image requests", async () => { postJsonRequestMock.mockResolvedValue({ response: { json: async () => ({ data: [{ b64_json: Buffer.from("png-bytes").toString("base64") }], }), }, release: vi.fn(async () => {}), }); const provider = buildOpenAIImageGenerationProvider(); const result = await provider.generateImage({ provider: "openai", model: "gpt-image-1", prompt: "Draw a QA lighthouse", cfg: { models: { providers: { openai: { baseUrl: "http://127.0.0.1:44080/v1", models: [], }, }, }, }, }); expect(resolveProviderHttpRequestConfigMock).toHaveBeenCalledWith( expect.objectContaining({ baseUrl: "http://127.0.0.1:44080/v1", }), ); expect(postJsonRequestMock).toHaveBeenCalledWith( expect.objectContaining({ url: "http://127.0.0.1:44080/v1/images/generations", allowPrivateNetwork: false, }), ); expect(result.images).toHaveLength(1); }); it("uses JSON image_url edits for input-image requests", async () => { postJsonRequestMock.mockResolvedValue({ response: { json: async () => ({ data: [{ b64_json: Buffer.from("png-bytes").toString("base64") }], }), }, release: vi.fn(async () => {}), }); const provider = buildOpenAIImageGenerationProvider(); const result = await provider.generateImage({ provider: "openai", model: "gpt-image-1", prompt: "Change only the background to pale blue", cfg: {}, inputImages: [ { buffer: Buffer.from("png-bytes"), mimeType: "image/png", fileName: "reference.png", }, ], }); expect(postJsonRequestMock).toHaveBeenCalledWith( expect.objectContaining({ url: "https://api.openai.com/v1/images/edits", body: expect.objectContaining({ model: "gpt-image-1", prompt: "Change only the background to pale blue", images: [ { image_url: "data:image/png;base64,cG5nLWJ5dGVz", }, ], }), }), ); expect(result.images).toHaveLength(1); }); });