From ac2c2e96812461c32053767697f3e6f81481f592 Mon Sep 17 00:00:00 2001 From: Robinnnnn <12162433+Robinnnnn@users.noreply.github.com> Date: Mon, 6 Jul 2026 21:53:04 -0700 Subject: [PATCH] provider: add image generation support for OpenRouter --- src/providers/openrouter/api.ts | 2 + src/providers/openrouter/imageGenerate.ts | 54 +++++++++++++++++++++++ src/providers/openrouter/index.ts | 6 +++ 3 files changed, 62 insertions(+) create mode 100644 src/providers/openrouter/imageGenerate.ts diff --git a/src/providers/openrouter/api.ts b/src/providers/openrouter/api.ts index 7f868c092..6ef1e7223 100644 --- a/src/providers/openrouter/api.ts +++ b/src/providers/openrouter/api.ts @@ -14,6 +14,8 @@ const OpenrouterAPIConfig: ProviderAPIConfig = { switch (fn) { case 'chatComplete': return '/v1/chat/completions'; + case 'imageGenerate': + return '/v1/images'; default: return ''; } diff --git a/src/providers/openrouter/imageGenerate.ts b/src/providers/openrouter/imageGenerate.ts new file mode 100644 index 000000000..83cb62af8 --- /dev/null +++ b/src/providers/openrouter/imageGenerate.ts @@ -0,0 +1,54 @@ +import { OPENROUTER } from '../../globals'; +import { ErrorResponse, ImageGenerateResponse, ProviderConfig } from '../types'; +import { OpenAIErrorResponseTransform } from '../openai/utils'; + +export const OpenrouterImageGenerateConfig: ProviderConfig = { + prompt: { + param: 'prompt', + required: true, + }, + model: { + param: 'model', + required: true, + }, + n: { + param: 'n', + min: 1, + max: 10, + }, + size: { + param: 'size', + }, + seed: { + param: 'seed', + }, + aspect_ratio: { + param: 'aspect_ratio', + }, + resolution: { + param: 'resolution', + }, + input_references: { + param: 'input_references', + }, +}; + +interface OpenrouterImageObject { + b64_json?: string; // The base64-encoded image. OpenRouter always returns base64 (no URL support). + media_type?: string; // The image MIME type, only present for non-PNG images. +} + +interface OpenrouterImageGenerateResponse extends ImageGenerateResponse { + data: OpenrouterImageObject[]; +} + +export const OpenrouterImageGenerateResponseTransform: ( + response: OpenrouterImageGenerateResponse | ErrorResponse, + responseStatus: number +) => ImageGenerateResponse | ErrorResponse = (response, responseStatus) => { + if (responseStatus !== 200 && 'error' in response) { + return OpenAIErrorResponseTransform(response, OPENROUTER); + } + + return response; +}; diff --git a/src/providers/openrouter/index.ts b/src/providers/openrouter/index.ts index 78ff0bcf9..9ae27398c 100644 --- a/src/providers/openrouter/index.ts +++ b/src/providers/openrouter/index.ts @@ -5,13 +5,19 @@ import { OpenrouterChatCompleteResponseTransform, OpenrouterChatCompleteStreamChunkTransform, } from './chatComplete'; +import { + OpenrouterImageGenerateConfig, + OpenrouterImageGenerateResponseTransform, +} from './imageGenerate'; const OpenrouterConfig: ProviderConfigs = { chatComplete: OpenrouterChatCompleteConfig, + imageGenerate: OpenrouterImageGenerateConfig, api: OpenrouterAPIConfig, responseTransforms: { chatComplete: OpenrouterChatCompleteResponseTransform, 'stream-chatComplete': OpenrouterChatCompleteStreamChunkTransform, + imageGenerate: OpenrouterImageGenerateResponseTransform, }, };