60 lines
4.0 KiB
TypeScript
60 lines
4.0 KiB
TypeScript
import { expect, test } from "@playwright/test";
|
|
import { serverLoader } from "../helpers/canvas-download-server-loader";
|
|
import sharp from "sharp";
|
|
|
|
test("Alibaba terminal task errors preserve the nested provider reason and do not resubmit", async () => {
|
|
const methods: string[] = [];
|
|
const loader = serverLoader({
|
|
"@/lib/storage/image-archive": {}, "@/lib/storage/service": {},
|
|
setTimeout: (callback: () => void, ms: number) => setTimeout(callback, ms === 5000 ? 0 : ms),
|
|
fetch: async (_url: string, init: RequestInit) => {
|
|
methods.push(init.method || "GET");
|
|
return Response.json(methods.length === 1
|
|
? { output: { task_id: "original-task", task_status: "PENDING" } }
|
|
: { output: { task_id: "original-task", task_status: "FAILED", code: "InvalidParameter", message: "Failed to download image URL after retries." } });
|
|
},
|
|
});
|
|
const provider = loader("lib/ai/providers/alibaba-image.ts").createAlibabaImage({ apiKey: "fixture-key", baseURL: "https://dashscope.example/api/v1/services/aigc/multimodal-generation/generation" });
|
|
let error: unknown;
|
|
try { await provider.chat("qwen-image-3.0").doGenerate({ messages: [{ role: "user", content: "fixture" }], imageParams: { aspectRatio: "1:1" } }); } catch (caught) { error = caught; }
|
|
expect(String(error)).toContain("Failed to download image URL after retries.");
|
|
expect(String(error)).toContain("InvalidParameter");
|
|
expect(String(error)).toContain("original-task");
|
|
expect(methods).toEqual(["POST", "GET"]);
|
|
const failure = loader("lib/request-error.ts").getRequestFailureDetails(error);
|
|
expect(failure).toMatchObject({ code: "PROVIDER_REFERENCE_FETCH_FAILED", message: "模型服务未能读取参考图。" });
|
|
expect(failure.recommendation).toContain("模型取图线路");
|
|
expect(failure.recommendation).not.toContain("稍后重试");
|
|
});
|
|
|
|
test("Qwen 3 sends reference bytes directly with the right MIME and keeps auto resolution", async () => {
|
|
const png = await sharp({ create: { width: 32, height: 64, channels: 3, background: "blue" } }).png().toBuffer();
|
|
const jpeg = await sharp(png).jpeg().toBuffer();
|
|
const webp = await sharp(png).webp().toBuffer();
|
|
const originals = [png, jpeg, webp];
|
|
let submitted: any;
|
|
let posts = 0;
|
|
const loader = serverLoader({
|
|
"@/lib/storage/image-archive": {}, "@/lib/storage/service": { uploadFile() { throw new Error("Reference transport must not upload an intermediate file"); } },
|
|
setTimeout: (callback: () => void, ms: number) => setTimeout(callback, ms === 5000 ? 0 : ms),
|
|
fetch: async (url: string, init: RequestInit = {}) => {
|
|
if (init.method === "POST") { posts++; submitted = JSON.parse(String(init.body)); return Response.json({ output: { task_id: "inline-task", task_status: "PENDING" } }); }
|
|
if (url.includes("/tasks/")) return Response.json({ output: { task_status: "FAILED", message: "transport-inspection-complete" } });
|
|
const index = Number(new URL(url).pathname.slice(1));
|
|
return new Response(originals[index], { headers: { "content-type": ["image/png", "image/jpeg", "image/webp"][index] } });
|
|
},
|
|
});
|
|
const provider = loader("lib/ai/providers/alibaba-image.ts").createAlibabaImage({ apiKey: "fixture-key", baseURL: "https://dashscope.example" });
|
|
await expect(provider.chat("qwen-image-3.0").doGenerate({ messages: [{ role: "user", content: [
|
|
{ type: "text", text: "fixture" }, ...originals.map((_bytes, index) => ({ type: "image", image: `https://source.example/${index}` })),
|
|
] }], imageParams: { aspectRatio: "auto", imageSize: "2K" } })).rejects.toThrow("transport-inspection-complete");
|
|
expect(posts).toBe(1);
|
|
expect(submitted.parameters.size).toBe("1024*2048");
|
|
const images = submitted.input.messages[0].content.filter((part: any) => part.image).map((part: any) => part.image);
|
|
expect(images).toHaveLength(3);
|
|
images.forEach((value: string, index: number) => {
|
|
expect(value.split(";", 1)[0]).toBe(["data:image/png", "data:image/jpeg", "data:image/webp"][index]);
|
|
expect(Buffer.from(value.split(",")[1], "base64").equals(originals[index])).toBe(true);
|
|
});
|
|
});
|