
























@@ -0,0 +1,125 @@
1+import { beforeEach, describe, expect, it, vi } from "vitest";
2+import { describeStickerImage } from "./sticker-cache.js";
3+4+const mocks = vi.hoisted(() => {
5+const describeImageFileWithModel = vi.fn(async () => ({
6+text: "vlm ok",
7+model: "MiniMax-VL-01",
8+}));
9+return {
10+ describeImageFileWithModel,
11+findModelInCatalog: vi.fn((_catalog, provider: string, model: string) => ({
12+ provider,
13+id: model,
14+input: ["text", "image"],
15+})),
16+loadModelCatalog: vi.fn(async () => [
17+{ provider: "minimax-cn", id: "MiniMax-M2.7", input: ["text", "image"] },
18+{ provider: "minimax", id: "MiniMax-M2.7", input: ["text", "image"] },
19+]),
20+modelSupportsVision: vi.fn((entry: { input?: string[] } | undefined) =>
21+Boolean(entry?.input?.includes("image")),
22+),
23+resolveApiKeyForProvider: vi.fn(async () => ({ apiKey: "minimax-test" })),
24+resolveAutoImageModel: vi.fn(async () => ({
25+provider: "minimax-cn",
26+model: "MiniMax-VL-01",
27+})),
28+resolveAutoMediaKeyProviders: vi.fn(() => ["minimax-cn", "minimax"]),
29+resolveDefaultMediaModel: vi.fn(() => "MiniMax-VL-01"),
30+resolveDefaultModelForAgent: vi.fn(() => ({
31+provider: "minimax-cn",
32+model: "MiniMax-M2.7",
33+})),
34+};
35+});
36+37+vi.mock("openclaw/plugin-sdk/agent-runtime", () => ({
38+findModelInCatalog: mocks.findModelInCatalog,
39+loadModelCatalog: mocks.loadModelCatalog,
40+modelSupportsVision: mocks.modelSupportsVision,
41+resolveApiKeyForProvider: mocks.resolveApiKeyForProvider,
42+resolveDefaultModelForAgent: mocks.resolveDefaultModelForAgent,
43+}));
44+45+vi.mock("openclaw/plugin-sdk/media-runtime", () => ({
46+resolveAutoImageModel: mocks.resolveAutoImageModel,
47+resolveAutoMediaKeyProviders: mocks.resolveAutoMediaKeyProviders,
48+resolveDefaultMediaModel: mocks.resolveDefaultMediaModel,
49+}));
50+51+vi.mock("./runtime.js", () => ({
52+getTelegramRuntime: () => ({
53+mediaUnderstanding: {
54+describeImageFileWithModel: mocks.describeImageFileWithModel,
55+},
56+}),
57+}));
58+59+describe("describeStickerImage", () => {
60+beforeEach(() => {
61+mocks.describeImageFileWithModel.mockClear();
62+mocks.findModelInCatalog.mockClear();
63+mocks.loadModelCatalog.mockClear();
64+mocks.modelSupportsVision.mockClear();
65+mocks.resolveApiKeyForProvider.mockClear();
66+mocks.resolveAutoImageModel.mockClear();
67+mocks.resolveAutoMediaKeyProviders.mockClear();
68+mocks.resolveDefaultMediaModel.mockClear();
69+mocks.resolveDefaultModelForAgent.mockClear();
70+});
71+72+it("uses MiniMax VLM auto selection instead of legacy chat vision catalog entries", async () => {
73+await expect(
74+describeStickerImage({
75+imagePath: "/tmp/sticker.webp",
76+cfg: {},
77+agentDir: "/tmp/agent",
78+}),
79+).resolves.toBe("vlm ok");
80+81+expect(mocks.resolveDefaultMediaModel).toHaveBeenCalledWith({
82+cfg: {},
83+providerId: "minimax-cn",
84+capability: "image",
85+includeConfiguredImageModels: false,
86+});
87+expect(mocks.resolveAutoImageModel).not.toHaveBeenCalled();
88+expect(mocks.describeImageFileWithModel).toHaveBeenCalledWith(
89+expect.objectContaining({
90+filePath: "/tmp/sticker.webp",
91+provider: "minimax-cn",
92+model: "MiniMax-VL-01",
93+}),
94+);
95+});
96+97+it("keeps MiniMax chat defaults on MiniMax VLM when other vision providers are configured", async () => {
98+mocks.resolveAutoMediaKeyProviders.mockReturnValue(["openai", "minimax-cn", "minimax"]);
99+mocks.loadModelCatalog.mockResolvedValue([
100+{ provider: "openai", id: "gpt-5.4", input: ["text", "image"] },
101+{ provider: "minimax-cn", id: "MiniMax-M2.7", input: ["text", "image"] },
102+{ provider: "minimax-cn", id: "MiniMax-VL-01", input: ["image"] },
103+]);
104+105+await expect(
106+describeStickerImage({
107+imagePath: "/tmp/sticker.webp",
108+cfg: {},
109+agentDir: "/tmp/agent",
110+}),
111+).resolves.toBe("vlm ok");
112+113+expect(mocks.describeImageFileWithModel).toHaveBeenCalledWith(
114+expect.objectContaining({
115+provider: "minimax-cn",
116+model: "MiniMax-VL-01",
117+}),
118+);
119+expect(mocks.describeImageFileWithModel).not.toHaveBeenCalledWith(
120+expect.objectContaining({
121+provider: "openai",
122+}),
123+);
124+});
125+});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。