diff --git a/lib/ai/vip98k-models.ts b/lib/ai/vip98k-models.ts index 5cf231de7..b267c158e 100644 --- a/lib/ai/vip98k-models.ts +++ b/lib/ai/vip98k-models.ts @@ -199,6 +199,14 @@ const VERIFIED_2026_IMAGE_MODEL_PATTERNS = [ /^youchuan\/v8\.1(?:$|[-/])/, ]; +// These catalog entries currently expose array-shaped request metadata but do +// not provide reliable multi-reference editing. Keep them out of image pickers +// until the provider publishes and verifies a real multi-image contract. +const VIP98K_MULTI_IMAGE_MODEL_EXCLUSIONS = new Set([ + "nano-banana-2-lite", + "nano-banana-fast", +]); + function toRecord(value: unknown): Record | null { if (!value || typeof value !== "object" || Array.isArray(value)) return null; return value as Record; @@ -443,6 +451,11 @@ function hasMultiImageReferenceInput(model: Vip98kCatalogModel) { } export function isVip98kMultiImageEditCatalogModel(model: Vip98kCatalogModel) { + if ( + VIP98K_MULTI_IMAGE_MODEL_EXCLUSIONS.has(getModelId(model).toLowerCase()) + ) { + return false; + } return ( resolvePresetType(model) === "image" && hasMediaReferenceInput(model, "image") && diff --git a/tests/routes/vip98k-reference-routing.test.ts b/tests/routes/vip98k-reference-routing.test.ts index 8b7cb05a0..6ec2d0ae8 100644 --- a/tests/routes/vip98k-reference-routing.test.ts +++ b/tests/routes/vip98k-reference-routing.test.ts @@ -527,6 +527,34 @@ test.describe("VIP98K reference-image routing", () => { expect(presets).toEqual([]); }); + test("excludes Lite and Fast even when catalog metadata claims image arrays", () => { + const presets = buildVip98kModelPresets( + ["nano-banana-2-lite", "nano-banana-fast"].map((modelId) => ({ + id: modelId, + type: "image", + capabilities: ["text_to_image", "image_to_image"], + invocation: { + kind: "task", + method: "POST", + path: "/extensions/v1/tasks", + content_type: "application/json", + request_example: { + file_urls: ["https://api.vip98k.com/logo.png"], + model: modelId, + prompt: "Edit", + }, + input_schema: { + properties: { + file_urls: { type: "array", maxItems: 8 }, + }, + }, + }, + })), + ); + + expect(presets).toEqual([]); + }); + test("maps frontend ratio and resolution to the VIP98K V2 size contract", () => { expect( resolveVip98kImageTaskSize({