From 30b5e29849b3f13887e9ab1f69ed1b94126a1dec Mon Sep 17 00:00:00 2001 From: zhuchi Date: Wed, 16 Sep 2026 20:03:46 +0800 Subject: [PATCH] =?UTF-8?q?feat(web):=20=E6=A8=A1=E5=9E=8B=E8=83=BD?= =?UTF-8?q?=E5=8A=9B=20-=20Agnes=20=E5=9B=BE=E5=83=8F=E5=8D=8F=E8=AE=AE?= =?UTF-8?q?=E8=A1=A5=E5=85=85=E6=AF=94=E4=BE=8B=E6=A1=A3=E4=BD=8D=E4=B8=8E?= =?UTF-8?q?=E5=8D=95=E6=AC=A1=E5=BC=A0=E6=95=B0=E9=BB=98=E8=AE=A4=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/src/lib/model-capabilities.ts | 20 ++++++++++++++++++++ web/test/image-resolution-tiers.test.ts | 19 ++++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/web/src/lib/model-capabilities.ts b/web/src/lib/model-capabilities.ts index 60958bba3..5f32a27ed 100644 --- a/web/src/lib/model-capabilities.ts +++ b/web/src/lib/model-capabilities.ts @@ -236,6 +236,26 @@ export function defaultImageCapabilityConfig(protocol?: ModelProtocol, model = " image.outputFormat = { supported: false }; image.maxOutputs = 4; } + if (protocol === "agnes-image") { + // Agnes 图像:size 必填,取 1K/2K/3K/4K 档位或 WxH 精确尺寸,画面比例走独立的 ratio 字段; + // 参考图放 extra_body.image,支持多图合成,但没有蒙版端点。 + image.references.maxImages = 9; + image.references.maskSupported = false; + image.size = { + parameter: "aspect_ratio", + values: ["1:1", "3:4", "4:3", "16:9", "9:16", "2:3", "3:2", "21:9"], + default: "1:1", + allowCustom: false, + }; + // 官方档位是 1K/2K/3K/4K,统一层只提供 1k/2k/4k 三档;3K 保留在协议映射里但不在界面露出。 + image.quality = { supported: true, values: ["1k", "2k", "4k"], default: "2k" }; + image.transparentBackground = { supported: false, default: false }; + // 顶层 response_format 是官方明确的错误写法,输出格式只能在 extra_body 内声明。 + image.responseFormat = { supported: false }; + image.outputFormat = { supported: false }; + // 该端点不接受 n,单次请求固定返回一张图片。 + image.maxOutputs = 1; + } if (protocol !== "grok-image" && model.trim().toLowerCase().startsWith("grok-imagine-image")) { image.references.maxImages = 0; image.references.maskSupported = false; diff --git a/web/test/image-resolution-tiers.test.ts b/web/test/image-resolution-tiers.test.ts index 30f8a23b8..5f1e1a3da 100644 --- a/web/test/image-resolution-tiers.test.ts +++ b/web/test/image-resolution-tiers.test.ts @@ -8,7 +8,7 @@ import { imageSizeForResolution, supportsImageResolutionPresets, } from "../src/lib/image-resolution-tiers"; -import { defaultImageCapabilityConfig } from "../src/lib/model-capabilities"; +import { defaultImageCapabilityConfig, normalizeImageValue } from "../src/lib/model-capabilities"; import { resolveImageRequestSize } from "../src/services/api/image-validation"; const sizes = [ @@ -65,6 +65,23 @@ describe("image resolution tiers", () => { expect(buildImageResolutionOptions(profile.size.values)).toHaveLength(30); }); + // Agnes 图像的 size 是官方必填项,但取分辨率档位,画面比例走独立的 ratio 字段, + // 所以界面必须同时保留比例和档位两个选择器,不能退化成 OpenAI 的像素尺寸。 + test("Agnes 图像按比例加档位选择尺寸,并关闭上游不支持的输出开关", () => { + const profile = defaultImageCapabilityConfig("agnes-image", "agnes-image-2.1-flash"); + + expect(profile.size.parameter).toBe("aspect_ratio"); + expect(profile.size.values).toEqual(["1:1", "3:4", "4:3", "16:9", "9:16", "2:3", "3:2", "21:9"]); + expect(profile.quality.values).toEqual(["1k", "2k", "4k"]); + expect(normalizeImageValue(profile, { size: "3:4", quality: "4k", count: "4" })).toMatchObject({ size: "3:4", quality: "4k", count: "1" }); + + // 顶层 response_format 是官方明确列出的错误写法,output_format 会被上游直接拒绝。 + expect(profile.responseFormat.supported).toBe(false); + expect(profile.outputFormat.supported).toBe(false); + expect(profile.transparentBackground.supported).toBe(false); + expect(profile.references.maskSupported).toBe(false); + }); + test("识别适合全景图的 2:1 自定义尺寸", () => { const options = buildImageResolutionOptions(["1440x720", "2048x1024", "3840x1920"]);