From a0a144f506c7c18f39b48558c1c505dbf8907004 Mon Sep 17 00:00:00 2001 From: 134 Date: Sat, 8 Aug 2026 17:18:43 +0800 Subject: [PATCH] fix(ai): route VIP98K reference edits through task API --- lib/ai/providers/vip98k.ts | 36 ++++++++++++++++++++++++++----- scripts/test-vip98k-capability.ts | 25 +++++++++++++++------ 2 files changed, 50 insertions(+), 11 deletions(-) diff --git a/lib/ai/providers/vip98k.ts b/lib/ai/providers/vip98k.ts index 674dbc577..424bef452 100644 --- a/lib/ai/providers/vip98k.ts +++ b/lib/ai/providers/vip98k.ts @@ -108,6 +108,25 @@ function inferKind(modelId: string, config: Vip98kModelRuntimeConfig) { return "chat"; } +const VIP98K_OPENAI_IMAGE_ALIASES = new Set([ + "nano-banana-2", + "nano-banana-pro", + "gpt-image-2-vip", +]); + +function resolveVip98kReferenceModelId(modelId: string) { + switch (modelId.trim().toLowerCase()) { + case "nano-banana-2": + return "google/nano-banana-2/reference-to-image"; + case "nano-banana-pro": + return "google/nano-banana-pro/edit"; + case "gpt-image-2-vip": + return "openai/gpt-image-2/edit"; + default: + return modelId; + } +} + function delay(ms: number) { return new Promise((resolve) => setTimeout(resolve, ms)); } @@ -746,10 +765,6 @@ export function createVip98k({ apiKey, baseURL }: Vip98kConfig) { const modelConfig = parseRuntimeConfig(defaultModelConfig); const kind = inferKind(modelId, modelConfig); - if (kind === "image") { - return openAIImageProvider.chat(modelId) as any; - } - if (kind === "chat") { return openAITextProvider.chat(modelId) as any; } @@ -774,14 +789,25 @@ export function createVip98k({ apiKey, baseURL }: Vip98kConfig) { if (!activeModelId) throw new Error("VIP98K model ID is not configured"); const activeKind = inferKind(activeModelId, runtimeConfig); const { prompt, imageUrls, videoUrls } = extractPromptAndMedia(options.messages); + if ( + activeKind === "image" && + imageUrls.length === 0 && + VIP98K_OPENAI_IMAGE_ALIASES.has(activeModelId.toLowerCase()) + ) { + return openAIImageProvider.chat(activeModelId).doGenerate(options as any); + } const [publicImageUrls, publicVideoUrls] = await Promise.all([ Promise.all(imageUrls.map(ensurePublicMediaUrl)), Promise.all(videoUrls.map(ensurePublicMediaUrl)), ]); + const taskModelId = + activeKind === "image" && publicImageUrls.length > 0 + ? resolveVip98kReferenceModelId(activeModelId) + : activeModelId; const text = await runTask({ apiKey, baseURL: rootBaseURL, - modelId: activeModelId, + modelId: taskModelId, kind: activeKind, prompt, imageUrls: publicImageUrls, diff --git a/scripts/test-vip98k-capability.ts b/scripts/test-vip98k-capability.ts index 4504cc575..b553b309d 100644 --- a/scripts/test-vip98k-capability.ts +++ b/scripts/test-vip98k-capability.ts @@ -49,7 +49,11 @@ const DEFAULT_MODEL_IDS: Record = { chat: ["gpt-5.4-mini", "gpt-5.4", "claude-sonnet-4-6"], multimodal: ["gpt-5.4-mini", "gpt-5.4", "claude-sonnet-4-6"], image: ["nano-banana-2", "nano-banana-pro", "gpt-image-2-vip"], - "multi-image-edit": ["nano-banana-2", "nano-banana-pro", "gpt-image-2-vip"], + "multi-image-edit": [ + "google/nano-banana-2/reference-to-image", + "google/nano-banana-pro/edit", + "openai/gpt-image-2/edit", + ], rmbg: ["remove-background"], enhance: ["enhance", "image-upscaler"], extend: ["image-expansion"], @@ -302,18 +306,27 @@ async function runExternalTask(params: { capability: Capability; }) { const imageUrl = "https://dummyimage.com/512x512/2563eb/ffffff.png&text=VIP98K"; + const secondImageUrl = "https://dummyimage.com/512x512/dc2626/ffffff.png&text=REFERENCE"; const body: Record = { model: params.modelId, displayName: `provider-smoke-${params.capability}`, prompt: "Create a minimal test result with one simple object", }; - if (["rmbg", "enhance", "extend", "image-to-3d"].includes(params.capability)) { + if ( + ["multi-image-edit", "rmbg", "enhance", "extend", "image-to-3d"].includes( + params.capability, + ) + ) { + const images = + params.capability === "multi-image-edit" ? [imageUrl, secondImageUrl] : [imageUrl]; Object.assign(body, { image: imageUrl, imageUrl, image_url: imageUrl, - images: [imageUrl], - imageUrls: [imageUrl], + images, + imageUrls: images, + referenceImages: images, + reference_images: images, }); } if (params.capability === "extend") { @@ -424,12 +437,12 @@ async function main() { modelId, multimodal: capability === "multimodal", }); - } else if (capability === "image" || capability === "multi-image-edit") { + } else if (capability === "image") { outputs = await runOpenAIImage({ baseUrl, apiKey, modelId, - multiImage: capability === "multi-image-edit", + multiImage: false, }); } else { outputs = await runExternalTask({ baseUrl, apiKey, modelId, capability });