diff --git a/lib/ai/providers/vip98k.ts b/lib/ai/providers/vip98k.ts index f78a7b915..a7d81a1b6 100644 --- a/lib/ai/providers/vip98k.ts +++ b/lib/ai/providers/vip98k.ts @@ -650,6 +650,15 @@ function buildTaskBody(params: Vip98kTaskParams, invocation: Vip98kInvocation | if ("negativePrompt" in body || !invocation) body.negativePrompt = negativePrompt; if ("negative_prompt" in body || !invocation) body.negative_prompt = negativePrompt; } + const imageToolParamAliases = [ + ["scaleFactor", "scale_factor"], + ["xScale", "x_scale"], + ["yScale", "y_scale"], + ] as const; + for (const [sourceKey, targetKey] of imageToolParamAliases) { + const value = imageParams[sourceKey]; + if (value !== undefined && targetKey in body) body[targetKey] = value; + } if (typeof videoParams.generateAudio === "boolean") { if ("generateAudio" in body || !invocation) body.generateAudio = videoParams.generateAudio; if ("generate_audio" in body || !invocation) body.generate_audio = videoParams.generateAudio; diff --git a/lib/ai/vip98k-task-invocation.ts b/lib/ai/vip98k-task-invocation.ts index 83ebfdfe1..5e5e27aaa 100644 --- a/lib/ai/vip98k-task-invocation.ts +++ b/lib/ai/vip98k-task-invocation.ts @@ -16,6 +16,14 @@ const KNOWN_IMAGE_TOOL_INPUTS: Record = { "openai/gpt-image-2/edit": "images", }; +const KNOWN_IMAGE_PROCESSING_TOOL_REQUESTS: Record< + string, + Record +> = { + "remove-background": { image_url: "" }, + enhance: { image_url: "", scale_factor: 4 }, +}; + function getInvocationToolId(invocation: Vip98kTaskInvocation | null) { if (!invocation || invocation.kind !== "tool") return null; const query = invocation.path.split("?", 2)[1] || ""; @@ -46,6 +54,22 @@ function createKnownImageToolInvocation( }; } +function createKnownProcessingToolInvocation( + modelId: string, + requestExample: Record +): Vip98kTaskInvocation { + const encodedModelId = encodeURIComponent(modelId); + return { + kind: "tool", + method: "POST", + path: `/api/external/tools/generate?tool_id=${encodedModelId}`, + contentType: "application/json", + requestExample: { ...requestExample }, + resultMethod: "GET", + resultPath: `/api/external/tools/result?tool_id=${encodedModelId}&taskId={task_id}`, + }; +} + /** * A frontend alias may resolve to a different VIP98K tool at runtime. In that * case the selected model's invocation cannot be reused because its endpoint @@ -56,6 +80,14 @@ export function resolveVip98kTaskInvocation( configuredInvocation: Vip98kTaskInvocation | null ) { const normalizedModelId = modelId.trim().toLowerCase(); + const processingRequest = KNOWN_IMAGE_PROCESSING_TOOL_REQUESTS[normalizedModelId]; + if (processingRequest) { + if (getInvocationToolId(configuredInvocation)?.toLowerCase() === normalizedModelId) { + return configuredInvocation; + } + return createKnownProcessingToolInvocation(modelId, processingRequest); + } + const knownImageInput = KNOWN_IMAGE_TOOL_INPUTS[normalizedModelId]; if (!knownImageInput) return configuredInvocation; diff --git a/tests/routes/vip98k-reference-routing.test.ts b/tests/routes/vip98k-reference-routing.test.ts index 1cf877f38..818d62706 100644 --- a/tests/routes/vip98k-reference-routing.test.ts +++ b/tests/routes/vip98k-reference-routing.test.ts @@ -59,4 +59,28 @@ test.describe("VIP98K reference-image routing", () => { resolveVip98kTaskInvocation("other/image-model", textToImageInvocation) ).toBe(textToImageInvocation); }); + + test("routes remove-background through the dedicated external tool", () => { + const invocation = resolveVip98kTaskInvocation("remove-background", null); + + expect(invocation?.path).toBe( + "/api/external/tools/generate?tool_id=remove-background" + ); + expect(invocation?.resultPath).toBe( + "/api/external/tools/result?tool_id=remove-background&taskId={task_id}" + ); + expect(invocation?.requestExample).toEqual({ image_url: "" }); + }); + + test("routes enhance through the dedicated external tool", () => { + const invocation = resolveVip98kTaskInvocation("enhance", null); + + expect(invocation?.path).toBe( + "/api/external/tools/generate?tool_id=enhance" + ); + expect(invocation?.requestExample).toEqual({ + image_url: "", + scale_factor: 4, + }); + }); });