* feat(image): 图片参数 - 统一插件声明配置与生成合同 * docs(image): 图片参数 - 说明声明合同与验证边界 * fix(plugins): 图片声明 - 保留内联素材支持并同步制品文档 * fix(image): 参数合同 - 对齐审批意图和尺寸预检调用方 * fix(image): 调用链 - 保留公开意图并接通独立分辨率 * fix(image): 图片参数 - 补齐分辨率接线与目录价格投影
93 lines
5.3 KiB
TypeScript
93 lines
5.3 KiB
TypeScript
import { describe, expect, test } from "bun:test";
|
||
|
||
import {
|
||
buildImageResolutionOptions,
|
||
formatImageResolutionSize,
|
||
imageResolutionChoices,
|
||
imageResolutionOption,
|
||
imageSizeForResolution,
|
||
supportsImageResolutionPresets,
|
||
} from "../src/lib/image-resolution-tiers";
|
||
import { defaultImageCapabilityConfig, normalizeImageValue } from "../src/lib/model-capabilities";
|
||
import { resolveImageRequestSize } from "../src/services/api/image-validation";
|
||
|
||
const sizes = [
|
||
"1024x1024", "1360x1024", "1024x1360", "1536x1024", "1024x1536", "1024x1280", "1280x1024", "2048x878", "1824x1024", "1024x1824",
|
||
"2048x2048", "2304x1728", "1728x2304", "2496x1664", "1664x2496", "1792x2240", "2240x1792", "3136x1344", "2752x1536", "1536x2752",
|
||
"2880x2880", "3264x2448", "2448x3264", "3504x2336", "2336x3504", "2560x3200", "3200x2560", "3808x1632", "3840x2160", "2160x3840",
|
||
];
|
||
|
||
describe("image resolution tiers", () => {
|
||
test("精确像素预设保持请求原值,比例协议发送比例", () => {
|
||
const profile = defaultImageCapabilityConfig("openai-image", "test");
|
||
profile.size = { parameter: "size", values: ["1920x1080", "3840x2160", "2160x3840", "1824x1024"], default: "1920x1080", allowCustom: false };
|
||
expect(imageResolutionChoices(profile.size.values)).toEqual(["1k", "2k", "4k"]);
|
||
expect(imageSizeForResolution(buildImageResolutionOptions(profile.size.values), "1k", "16:9")).toBe("1824x1024");
|
||
expect(resolveImageRequestSize(profile, undefined, "1920x1080")).toEqual({ parameter: "size", value: "1920x1080" });
|
||
profile.size = { parameter: "aspect_ratio", values: ["16:9"], default: "16:9", allowCustom: false };
|
||
expect(resolveImageRequestSize(profile, undefined, "16:9")).toEqual({ parameter: "aspect_ratio", value: "16:9" });
|
||
profile.size = { parameter: "size", values: [], default: "auto", allowCustom: true };
|
||
expect(() => resolveImageRequestSize(profile, undefined, "1920x1080")).toThrow("16 的倍数");
|
||
});
|
||
test("将 Xiaobaishu 的精确尺寸整理为 1K、2K、4K 各十种比例", () => {
|
||
const options = buildImageResolutionOptions(sizes);
|
||
|
||
expect(options.filter((item) => item.tier === "1k")).toHaveLength(10);
|
||
expect(options.filter((item) => item.tier === "2k")).toHaveLength(10);
|
||
expect(options.filter((item) => item.tier === "4k")).toHaveLength(10);
|
||
expect(imageResolutionOption(options, "1536x2752")).toMatchObject({ tier: "2k", ratio: "9:16" });
|
||
});
|
||
|
||
test("切换档位时按相同比例还原精确像素并显示比例与档位", () => {
|
||
const options = buildImageResolutionOptions(sizes);
|
||
|
||
expect(imageSizeForResolution(options, "4k", "9:16")).toBe("2160x3840");
|
||
expect(formatImageResolutionSize("1536x2752", options)).toBe("9:16 · 2K");
|
||
});
|
||
|
||
test("保留自动尺寸并在摘要中显示中文标签", () => {
|
||
const values = ["auto", ...sizes];
|
||
|
||
expect(imageResolutionChoices(values)).toEqual(["auto", "1k", "2k", "4k"]);
|
||
expect(buildImageResolutionOptions(values)).toHaveLength(30);
|
||
expect(formatImageResolutionSize("auto", [])).toBe("自动");
|
||
});
|
||
|
||
test("允许自定义尺寸时仍保留自动与分辨率预设", () => {
|
||
expect(supportsImageResolutionPresets({ parameter: "size", values: ["auto", ...sizes], allowCustom: true })).toBe(true);
|
||
});
|
||
|
||
test("默认图片能力为 OpenAI 兼容模型提供完整 1K、2K、4K 档位", () => {
|
||
const profile = defaultImageCapabilityConfig("openai-image", "gpt-image-2-4K");
|
||
|
||
expect(supportsImageResolutionPresets(profile.size)).toBe(true);
|
||
expect(imageResolutionChoices(profile.size.values)).toEqual(["auto", "1k", "2k", "4k"]);
|
||
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.resolution.values).toEqual(["1k", "2k", "4k"]);
|
||
expect(profile.quality.supported).toBe(false);
|
||
expect(normalizeImageValue(profile, { size: "3:4", imageResolution: "4k", count: "4" })).toMatchObject({ size: "3:4", imageResolution: "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"]);
|
||
|
||
expect(options.map((item) => item.tier)).toEqual(["1k", "2k", "4k"]);
|
||
expect(imageResolutionOption(options, "3840x1920")).toMatchObject({ tier: "4k", ratio: "2:1" });
|
||
});
|
||
});
|