From 7dfa2b6e6cb30d544ebd2df867a0d385f1bf9a1d Mon Sep 17 00:00:00 2001 From: "jeff.zhao" Date: Sat, 28 Feb 2026 14:27:51 +0800 Subject: [PATCH] feat(baoyu-image-gen): support OpenAI chat completions endpoint for image generation Add OPENAI_IMAGE_USE_CHAT env var (true|false) to route image generation through /chat/completions instead of /images/generations. Extracts base64 image data URLs from the chat response, enabling compatibility with OpenAI-compatible providers that return images via chat API. --- skills/baoyu-image-gen/scripts/main.ts | 1 + .../scripts/providers/openai.ts | 38 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/skills/baoyu-image-gen/scripts/main.ts b/skills/baoyu-image-gen/scripts/main.ts index 82274b2..85b940f 100644 --- a/skills/baoyu-image-gen/scripts/main.ts +++ b/skills/baoyu-image-gen/scripts/main.ts @@ -36,6 +36,7 @@ Environment variables: DASHSCOPE_IMAGE_MODEL Default DashScope model (z-image-turbo) REPLICATE_IMAGE_MODEL Default Replicate model (google/nano-banana-pro) OPENAI_BASE_URL Custom OpenAI endpoint + OPENAI_IMAGE_USE_CHAT Use /chat/completions instead of /images/generations (true|false) GOOGLE_BASE_URL Custom Google endpoint DASHSCOPE_BASE_URL Custom DashScope endpoint REPLICATE_BASE_URL Custom Replicate endpoint diff --git a/skills/baoyu-image-gen/scripts/providers/openai.ts b/skills/baoyu-image-gen/scripts/providers/openai.ts index a721318..b9a41ca 100644 --- a/skills/baoyu-image-gen/scripts/providers/openai.ts +++ b/skills/baoyu-image-gen/scripts/providers/openai.ts @@ -70,6 +70,10 @@ export async function generateImage( if (!apiKey) throw new Error("OPENAI_API_KEY is required"); + if (process.env.OPENAI_IMAGE_USE_CHAT === "true") { + return generateWithChatCompletions(baseURL, apiKey, prompt, model); + } + const size = args.size || getOpenAISize(model, args.aspectRatio, args.quality); if (args.referenceImages.length > 0) { @@ -84,6 +88,40 @@ export async function generateImage( return generateWithOpenAIGenerations(baseURL, apiKey, prompt, model, size, args.quality); } +async function generateWithChatCompletions( + baseURL: string, + apiKey: string, + prompt: string, + model: string +): Promise { + const res = await fetch(`${baseURL}/chat/completions`, { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${apiKey}`, + }, + body: JSON.stringify({ + model, + messages: [{ role: "user", content: prompt }], + }), + }); + + if (!res.ok) { + const err = await res.text(); + throw new Error(`OpenAI API error: ${err}`); + } + + const result = (await res.json()) as { choices: Array<{ message: { content: string } }> }; + const content = result.choices[0]?.message?.content ?? ""; + + const match = content.match(/data:image\/[^;]+;base64,([A-Za-z0-9+/=]+)/); + if (match) { + return Uint8Array.from(Buffer.from(match[1]!, "base64")); + } + + throw new Error("No image found in chat completions response"); +} + async function generateWithOpenAIGenerations( baseURL: string, apiKey: string,