fix(qwen): place DashScope image prompts in user content (#93649)

Co-authored-by: openclaw-clownfish[bot] <280122609+openclaw-clownfish[bot]@users.noreply.github.com>
This commit is contained in:
Vincent Koc
2026-06-16 21:42:59 +08:00
committed by GitHub
parent 5cebe96667
commit 998445ea20
2 changed files with 54 additions and 0 deletions

View File

@@ -884,6 +884,59 @@ describe("describeImageWithModel", () => {
]);
});
it("places DashScope image prompts in user content before images", async () => {
discoverModelsMock.mockReturnValue({
find: vi.fn(() => ({
api: "openai-completions",
provider: "qwen",
id: "qwen-vl-max-latest",
input: ["text", "image"],
baseUrl: "https://dashscope.aliyuncs.com/compatible-mode/v1",
})),
});
completeMock.mockResolvedValue({
role: "assistant",
api: "openai-completions",
provider: "qwen",
model: "qwen-vl-max-latest",
stopReason: "stop",
timestamp: Date.now(),
content: [{ type: "text", text: "dashscope ok" }],
});
const result = await describeImageWithModel({
cfg: {},
agentDir: "/tmp/openclaw-agent",
provider: "qwen",
model: "qwen-vl-max-latest",
buffer: Buffer.from("png-bytes"),
fileName: "image.png",
mime: "image/png",
prompt: "Describe the image.",
timeoutMs: 1000,
});
expect(result).toEqual({
text: "dashscope ok",
model: "qwen-vl-max-latest",
});
const firstCall = requireFirstMockCall(completeMock, "DashScope image completion");
const [, context] = firstCall;
expect(context.systemPrompt).toBeUndefined();
const userMessage = context.messages[0];
if (!userMessage) {
throw new Error("expected DashScope image completion user message");
}
expect(userMessage.content).toEqual([
{ type: "text", text: "Describe the image." },
{
type: "image",
data: Buffer.from("png-bytes").toString("base64"),
mimeType: "image/png",
},
]);
});
it.each([
{
name: "direct OpenAI Responses baseUrl",

View File

@@ -298,6 +298,7 @@ function shouldPlaceImagePromptInUserContent(model: Model): boolean {
});
return (
capabilities.endpointClass === "openrouter" ||
capabilities.endpointClass === "modelstudio-native" ||
(model.provider.toLowerCase() === "openrouter" && capabilities.endpointClass === "default")
);
}