test(agents): share video tool plugin fixtures

This commit is contained in:
Vincent Koc
2026-04-12 10:10:26 +01:00
parent 493288bf2e
commit 2393065a54

View File

@@ -23,6 +23,53 @@ function asConfig(value: unknown): OpenClawConfig {
return value as OpenClawConfig;
}
function mockVideoPluginProvider(capabilities: Record<string, unknown> = {}) {
vi.spyOn(videoGenerationRuntime, "listRuntimeVideoGenerationProviders").mockReturnValue([
{
id: "video-plugin",
defaultModel: "vid-v1",
models: ["vid-v1"],
capabilities,
generateVideo: vi.fn(async () => ({
videos: [{ buffer: Buffer.from("x"), mimeType: "video/mp4" }],
})),
},
]);
}
function createVideoPluginTool() {
const tool = createVideoGenerateTool({
config: asConfig({
agents: {
defaults: {
videoGenerationModel: { primary: "video-plugin/vid-v1" },
},
},
}),
});
if (!tool) {
throw new Error("expected video_generate tool");
}
return tool;
}
function mockSavedVideoResult(fileName = "out.mp4") {
const generateSpy = vi.spyOn(videoGenerationRuntime, "generateVideo").mockResolvedValue({
provider: "video-plugin",
model: "vid-v1",
attempts: [],
ignoredOverrides: [],
videos: [{ buffer: Buffer.from("video-bytes"), mimeType: "video/mp4", fileName }],
});
vi.spyOn(mediaStore, "saveMediaBuffer").mockResolvedValueOnce({
path: `/tmp/${fileName}`,
id: fileName,
size: 11,
contentType: "video/mp4",
});
return generateSpy;
}
describe("createVideoGenerateTool", () => {
beforeEach(() => {
vi.restoreAllMocks();
@@ -597,31 +644,9 @@ describe("createVideoGenerateTool", () => {
});
it("rejects providerOptions that is not a plain JSON object", async () => {
vi.spyOn(videoGenerationRuntime, "listRuntimeVideoGenerationProviders").mockReturnValue([
{
id: "video-plugin",
defaultModel: "vid-v1",
models: ["vid-v1"],
capabilities: {},
generateVideo: vi.fn(async () => ({
videos: [{ buffer: Buffer.from("x"), mimeType: "video/mp4" }],
})),
},
]);
mockVideoPluginProvider();
const generateSpy = vi.spyOn(videoGenerationRuntime, "generateVideo");
const tool = createVideoGenerateTool({
config: asConfig({
agents: {
defaults: {
videoGenerationModel: { primary: "video-plugin/vid-v1" },
},
},
}),
});
if (!tool) {
throw new Error("expected video_generate tool");
}
const tool = createVideoPluginTool();
// Array-shaped providerOptions should be rejected up front, not cast to a
// Record with numeric-string keys and silently forwarded.
@@ -646,45 +671,11 @@ describe("createVideoGenerateTool", () => {
});
it("forwards providerOptions to the runtime for valid JSON-object payloads", async () => {
vi.spyOn(videoGenerationRuntime, "listRuntimeVideoGenerationProviders").mockReturnValue([
{
id: "video-plugin",
defaultModel: "vid-v1",
models: ["vid-v1"],
capabilities: {
providerOptions: { seed: "number", draft: "boolean" },
},
generateVideo: vi.fn(async () => ({
videos: [{ buffer: Buffer.from("x"), mimeType: "video/mp4" }],
})),
},
]);
const generateSpy = vi.spyOn(videoGenerationRuntime, "generateVideo").mockResolvedValue({
provider: "video-plugin",
model: "vid-v1",
attempts: [],
ignoredOverrides: [],
videos: [{ buffer: Buffer.from("video-bytes"), mimeType: "video/mp4", fileName: "out.mp4" }],
mockVideoPluginProvider({
providerOptions: { seed: "number", draft: "boolean" },
});
vi.spyOn(mediaStore, "saveMediaBuffer").mockResolvedValueOnce({
path: "/tmp/out.mp4",
id: "out.mp4",
size: 11,
contentType: "video/mp4",
});
const tool = createVideoGenerateTool({
config: asConfig({
agents: {
defaults: {
videoGenerationModel: { primary: "video-plugin/vid-v1" },
},
},
}),
});
if (!tool) {
throw new Error("expected video_generate tool");
}
const generateSpy = mockSavedVideoResult();
const tool = createVideoPluginTool();
await tool.execute("call-1", {
prompt: "lobster",
@@ -699,33 +690,11 @@ describe("createVideoGenerateTool", () => {
});
it("rejects *Roles arrays that are longer than the asset list", async () => {
vi.spyOn(videoGenerationRuntime, "listRuntimeVideoGenerationProviders").mockReturnValue([
{
id: "video-plugin",
defaultModel: "vid-v1",
models: ["vid-v1"],
capabilities: {
imageToVideo: { enabled: true, maxInputImages: 2 },
},
generateVideo: vi.fn(async () => ({
videos: [{ buffer: Buffer.from("x"), mimeType: "video/mp4" }],
})),
},
]);
const generateSpy = vi.spyOn(videoGenerationRuntime, "generateVideo");
const tool = createVideoGenerateTool({
config: asConfig({
agents: {
defaults: {
videoGenerationModel: { primary: "video-plugin/vid-v1" },
},
},
}),
mockVideoPluginProvider({
imageToVideo: { enabled: true, maxInputImages: 2 },
});
if (!tool) {
throw new Error("expected video_generate tool");
}
const generateSpy = vi.spyOn(videoGenerationRuntime, "generateVideo");
const tool = createVideoPluginTool();
await expect(
tool.execute("call-1", {
@@ -739,30 +708,9 @@ describe("createVideoGenerateTool", () => {
});
it("rejects *Roles that are not arrays", async () => {
vi.spyOn(videoGenerationRuntime, "listRuntimeVideoGenerationProviders").mockReturnValue([
{
id: "video-plugin",
defaultModel: "vid-v1",
models: ["vid-v1"],
capabilities: {},
generateVideo: vi.fn(async () => ({
videos: [{ buffer: Buffer.from("x"), mimeType: "video/mp4" }],
})),
},
]);
mockVideoPluginProvider();
const generateSpy = vi.spyOn(videoGenerationRuntime, "generateVideo");
const tool = createVideoGenerateTool({
config: asConfig({
agents: {
defaults: {
videoGenerationModel: { primary: "video-plugin/vid-v1" },
},
},
}),
});
if (!tool) {
throw new Error("expected video_generate tool");
}
const tool = createVideoPluginTool();
await expect(
tool.execute("call-1", {
@@ -776,45 +724,11 @@ describe("createVideoGenerateTool", () => {
});
it("attaches positional role hints to loaded reference assets", async () => {
vi.spyOn(videoGenerationRuntime, "listRuntimeVideoGenerationProviders").mockReturnValue([
{
id: "video-plugin",
defaultModel: "vid-v1",
models: ["vid-v1"],
capabilities: {
imageToVideo: { enabled: true, maxInputImages: 2 },
},
generateVideo: vi.fn(async () => ({
videos: [{ buffer: Buffer.from("x"), mimeType: "video/mp4" }],
})),
},
]);
const generateSpy = vi.spyOn(videoGenerationRuntime, "generateVideo").mockResolvedValue({
provider: "video-plugin",
model: "vid-v1",
attempts: [],
ignoredOverrides: [],
videos: [{ buffer: Buffer.from("video-bytes"), mimeType: "video/mp4", fileName: "out.mp4" }],
mockVideoPluginProvider({
imageToVideo: { enabled: true, maxInputImages: 2 },
});
vi.spyOn(mediaStore, "saveMediaBuffer").mockResolvedValueOnce({
path: "/tmp/out.mp4",
id: "out.mp4",
size: 11,
contentType: "video/mp4",
});
const tool = createVideoGenerateTool({
config: asConfig({
agents: {
defaults: {
videoGenerationModel: { primary: "video-plugin/vid-v1" },
},
},
}),
});
if (!tool) {
throw new Error("expected video_generate tool");
}
const generateSpy = mockSavedVideoResult();
const tool = createVideoPluginTool();
await tool.execute("call-1", {
prompt: "lobster",
@@ -832,33 +746,11 @@ describe("createVideoGenerateTool", () => {
});
it("rejects audio data: URLs via the templated rejection branch", async () => {
vi.spyOn(videoGenerationRuntime, "listRuntimeVideoGenerationProviders").mockReturnValue([
{
id: "video-plugin",
defaultModel: "vid-v1",
models: ["vid-v1"],
capabilities: {
maxInputAudios: 1,
},
generateVideo: vi.fn(async () => ({
videos: [{ buffer: Buffer.from("x"), mimeType: "video/mp4" }],
})),
},
]);
const generateSpy = vi.spyOn(videoGenerationRuntime, "generateVideo");
const tool = createVideoGenerateTool({
config: asConfig({
agents: {
defaults: {
videoGenerationModel: { primary: "video-plugin/vid-v1" },
},
},
}),
mockVideoPluginProvider({
maxInputAudios: 1,
});
if (!tool) {
throw new Error("expected video_generate tool");
}
const generateSpy = vi.spyOn(videoGenerationRuntime, "generateVideo");
const tool = createVideoPluginTool();
await expect(
tool.execute("call-1", {
@@ -870,43 +762,9 @@ describe("createVideoGenerateTool", () => {
});
it("accepts aspectRatio=adaptive and forwards it to the runtime", async () => {
vi.spyOn(videoGenerationRuntime, "listRuntimeVideoGenerationProviders").mockReturnValue([
{
id: "video-plugin",
defaultModel: "vid-v1",
models: ["vid-v1"],
capabilities: {},
generateVideo: vi.fn(async () => ({
videos: [{ buffer: Buffer.from("x"), mimeType: "video/mp4" }],
})),
},
]);
const generateSpy = vi.spyOn(videoGenerationRuntime, "generateVideo").mockResolvedValue({
provider: "video-plugin",
model: "vid-v1",
attempts: [],
ignoredOverrides: [],
videos: [{ buffer: Buffer.from("video-bytes"), mimeType: "video/mp4", fileName: "out.mp4" }],
});
vi.spyOn(mediaStore, "saveMediaBuffer").mockResolvedValueOnce({
path: "/tmp/out.mp4",
id: "out.mp4",
size: 11,
contentType: "video/mp4",
});
const tool = createVideoGenerateTool({
config: asConfig({
agents: {
defaults: {
videoGenerationModel: { primary: "video-plugin/vid-v1" },
},
},
}),
});
if (!tool) {
throw new Error("expected video_generate tool");
}
mockVideoPluginProvider();
const generateSpy = mockSavedVideoResult();
const tool = createVideoPluginTool();
await tool.execute("call-1", {
prompt: "lobster",
@@ -917,29 +775,8 @@ describe("createVideoGenerateTool", () => {
});
it("rejects unsupported aspectRatio values", async () => {
vi.spyOn(videoGenerationRuntime, "listRuntimeVideoGenerationProviders").mockReturnValue([
{
id: "video-plugin",
defaultModel: "vid-v1",
models: ["vid-v1"],
capabilities: {},
generateVideo: vi.fn(async () => ({
videos: [{ buffer: Buffer.from("x"), mimeType: "video/mp4" }],
})),
},
]);
const tool = createVideoGenerateTool({
config: asConfig({
agents: {
defaults: {
videoGenerationModel: { primary: "video-plugin/vid-v1" },
},
},
}),
});
if (!tool) {
throw new Error("expected video_generate tool");
}
mockVideoPluginProvider();
const tool = createVideoPluginTool();
await expect(
tool.execute("call-1", {