export type Vip98kTaskInvocation = { kind: string; method: string; path: string; contentType: string; requestExample: Record; resultMethod: string; resultPath: string; }; type KnownImageInput = "images" | "video_clips"; const KNOWN_IMAGE_TOOL_INPUTS: Record = { "google/nano-banana-2/reference-to-image": "video_clips", "google/nano-banana-pro/edit": "images", "openai/gpt-image-2/edit": "images", }; function getInvocationToolId(invocation: Vip98kTaskInvocation | null) { if (!invocation || invocation.kind !== "tool") return null; const query = invocation.path.split("?", 2)[1] || ""; return new URLSearchParams(query).get("tool_id"); } function createKnownImageToolInvocation( modelId: string, imageInput: KnownImageInput ): Vip98kTaskInvocation { const encodedModelId = encodeURIComponent(modelId); const requestExample = imageInput === "video_clips" ? { prompt: "", video_clips: [{ fps: 1, url: "", ends: 0, start: 0 }], } : { prompt: "", images: [""] }; return { kind: "tool", method: "POST", path: `/api/external/tools/generate?tool_id=${encodedModelId}`, contentType: "application/json", 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 * and reference-image field belong to the alias rather than the resolved tool. */ export function resolveVip98kTaskInvocation( modelId: string, configuredInvocation: Vip98kTaskInvocation | null ) { const normalizedModelId = modelId.trim().toLowerCase(); const knownImageInput = KNOWN_IMAGE_TOOL_INPUTS[normalizedModelId]; if (!knownImageInput) return configuredInvocation; if (getInvocationToolId(configuredInvocation)?.toLowerCase() === normalizedModelId) { return configuredInvocation; } return createKnownImageToolInvocation(modelId, knownImageInput); }