feat: add verified VIP98K multi-image models
This commit is contained in:
parent
6f5a444756
commit
821b8658a8
@ -1427,6 +1427,7 @@ function buildTaskBody(params: Vip98kTaskParams, invocation: Vip98kInvocation |
|
||||
videoParams.resolution || imageParams.size || imageParams.imageSize || "",
|
||||
).trim();
|
||||
const negativePrompt = String(videoParams.negativePrompt || imageParams.negativePrompt || "").trim();
|
||||
const quality = String(imageParams.quality || "").trim().toLowerCase();
|
||||
const outputConstraintFallbacks: string[] = [];
|
||||
let hasNativeAspectRatio = false;
|
||||
let hasNativeResolution = false;
|
||||
@ -1481,6 +1482,9 @@ function buildTaskBody(params: Vip98kTaskParams, invocation: Vip98kInvocation |
|
||||
if ("negativePrompt" in body || !invocation) body.negativePrompt = negativePrompt;
|
||||
if ("negative_prompt" in body || !invocation) body.negative_prompt = negativePrompt;
|
||||
}
|
||||
if (quality && invocationSupportsBodyField(invocation, "quality")) {
|
||||
body.quality = quality;
|
||||
}
|
||||
const imageToolParamAliases = [
|
||||
["scaleFactor", "scale_factor"],
|
||||
["xScale", "x_scale"],
|
||||
|
||||
@ -185,6 +185,8 @@ const VERIFIED_2026_IMAGE_MODEL_PATTERNS = [
|
||||
/^nano-banana-fast$/,
|
||||
/^nano-banana-pro$/,
|
||||
/^gpt-image-2(?:$|[-/])/,
|
||||
/^gpt-image-2\.5$/,
|
||||
/^gpt-image-2\.5-flare$/,
|
||||
/^alibaba\/wan-2\.(?:6|7)(?:$|[-/])/,
|
||||
/^black-forest-labs\/flux-2(?:$|[-/])/,
|
||||
/^bytedance\/seedream-v5(?:$|[.\-/])/,
|
||||
@ -689,6 +691,7 @@ function createImagePreset(
|
||||
"ratio",
|
||||
"aspect-ratio",
|
||||
].some((key) => invocationKeys.has(key)) || supportsNativeSize;
|
||||
const supportsQuality = invocationKeys.has("quality");
|
||||
const supportedModes = [
|
||||
...(capabilities.includes("text-to-image") || capabilities.length === 0
|
||||
? ["text-to-image"]
|
||||
@ -738,6 +741,7 @@ function createImagePreset(
|
||||
taskApi: "external-task",
|
||||
supportedModes,
|
||||
...(supportsNativeSize ? { imageSize: defaultImageSize } : {}),
|
||||
...(supportsQuality ? { quality: "auto" } : {}),
|
||||
aspectRatio: "auto",
|
||||
imageCount: 1,
|
||||
},
|
||||
@ -745,6 +749,7 @@ function createImagePreset(
|
||||
maxImages: 1,
|
||||
maxReferenceImages,
|
||||
supportsSize: supportsNativeSize,
|
||||
supportsQuality,
|
||||
supports1K: supportsNativeSize && supportedImageSizes.includes("1K"),
|
||||
supports2K: supportsNativeSize && supportedImageSizes.includes("2K"),
|
||||
supports4K: supportsNativeSize && supportedImageSizes.includes("4K"),
|
||||
|
||||
@ -99,14 +99,15 @@ export function getVip98kSubmissionRetryDelay(params: {
|
||||
maxAttempts: number;
|
||||
retryAfterMs?: number | null;
|
||||
}) {
|
||||
const recoverableGatewayFailure = params.status === 502 || params.status === 504;
|
||||
const recoverableSubmission =
|
||||
/pending\s+safe\s+reconciliation/i.test(params.message) ||
|
||||
/request\s+outcome\s+(?:is\s+)?unknown/i.test(params.message) ||
|
||||
/final\s+outcome\s+could\s+not\s+be\s+confirmed/i.test(params.message);
|
||||
if (
|
||||
params.status !== 503 ||
|
||||
params.attempt >= params.maxAttempts ||
|
||||
!recoverableSubmission
|
||||
(!recoverableGatewayFailure &&
|
||||
(params.status !== 503 || !recoverableSubmission))
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -193,6 +193,23 @@ test.describe("VIP98K reference-image routing", () => {
|
||||
maxAttempts: 3,
|
||||
}),
|
||||
).toBeNull();
|
||||
expect(
|
||||
getVip98kSubmissionRetryDelay({
|
||||
status: 502,
|
||||
message: "Bad Gateway",
|
||||
attempt: 1,
|
||||
maxAttempts: 3,
|
||||
}),
|
||||
).toBe(15_000);
|
||||
expect(
|
||||
getVip98kSubmissionRetryDelay({
|
||||
status: 504,
|
||||
message: "Gateway Timeout",
|
||||
attempt: 2,
|
||||
maxAttempts: 3,
|
||||
retryAfterMs: 6_000,
|
||||
}),
|
||||
).toBe(6_000);
|
||||
});
|
||||
|
||||
test("shows the newly published Nano Banana Pro image editor", () => {
|
||||
@ -523,6 +540,72 @@ test.describe("VIP98K reference-image routing", () => {
|
||||
});
|
||||
});
|
||||
|
||||
test("publishes only the verified GPT Image 2.5 multi-image variants", () => {
|
||||
const models = [
|
||||
"gpt-image-2.5",
|
||||
"gpt-image-2.5-flare",
|
||||
"gpt-image-2.5-sunburst",
|
||||
].map((modelId) => ({
|
||||
id: modelId,
|
||||
type: "image",
|
||||
capabilities: ["image_to_image", "openai.images.generations"],
|
||||
invocation: {
|
||||
kind: "tool",
|
||||
method: "POST",
|
||||
path: "/v1/images/generations",
|
||||
content_type: "application/json",
|
||||
request_example: {
|
||||
image: ["https://api.vip98k.com/logo.png"],
|
||||
model: modelId,
|
||||
n: 1,
|
||||
prompt: "Edit",
|
||||
quality: "auto",
|
||||
stream: false,
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
expect(models.map((model) => isVip98kImageModelVisible(model))).toEqual([
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
]);
|
||||
|
||||
const presets = buildVip98kModelPresets(models);
|
||||
expect(
|
||||
presets.map((preset) => ({
|
||||
modelId: preset.modelId,
|
||||
isHidden: preset.isHidden,
|
||||
supportsQuality: preset.imageGenConfig?.supportsQuality,
|
||||
quality: preset.defaultParams.quality,
|
||||
supportedAspectRatios:
|
||||
preset.imageGenConfig?.supportedAspectRatios,
|
||||
})),
|
||||
).toEqual([
|
||||
{
|
||||
modelId: "gpt-image-2.5",
|
||||
isHidden: false,
|
||||
supportsQuality: true,
|
||||
quality: "auto",
|
||||
supportedAspectRatios: ["auto"],
|
||||
},
|
||||
{
|
||||
modelId: "gpt-image-2.5-flare",
|
||||
isHidden: false,
|
||||
supportsQuality: true,
|
||||
quality: "auto",
|
||||
supportedAspectRatios: ["auto"],
|
||||
},
|
||||
{
|
||||
modelId: "gpt-image-2.5-sunburst",
|
||||
isHidden: true,
|
||||
supportsQuality: true,
|
||||
quality: "auto",
|
||||
supportedAspectRatios: ["auto"],
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
test("does not inherit multi-image support from broad authorized metadata", () => {
|
||||
const presets = buildVip98kModelPresets([
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user