fix: validate video duration option · openclaw/openclaw@b21b105
steipete
·
2026-05-29
·
via Recent Commits to openclaw:main
| Original file line number | Diff line number | Diff line change |
|---|
@@ -1139,6 +1139,43 @@ describe("createVideoGenerateTool", () => {
|
1139 | 1139 | }); |
1140 | 1140 | }); |
1141 | 1141 | |
| 1142 | +it("rejects fractional duration before calling the provider", async () => { |
| 1143 | +const generateVideo = vi.spyOn(videoGenerationRuntime, "generateVideo").mockResolvedValue({ |
| 1144 | +provider: "google", |
| 1145 | +model: "veo-3.1-fast-generate-preview", |
| 1146 | +attempts: [], |
| 1147 | +ignoredOverrides: [], |
| 1148 | +videos: [ |
| 1149 | +{ |
| 1150 | +buffer: Buffer.from("video-bytes"), |
| 1151 | +mimeType: "video/mp4", |
| 1152 | +fileName: "lobster.mp4", |
| 1153 | +}, |
| 1154 | +], |
| 1155 | +}); |
| 1156 | + |
| 1157 | +const tool = createVideoGenerateTool({ |
| 1158 | +config: asConfig({ |
| 1159 | +agents: { |
| 1160 | +defaults: { |
| 1161 | +videoGenerationModel: { primary: "google/veo-3.1-fast-generate-preview" }, |
| 1162 | +}, |
| 1163 | +}, |
| 1164 | +}), |
| 1165 | +}); |
| 1166 | +if (!tool) { |
| 1167 | +throw new Error("expected video_generate tool"); |
| 1168 | +} |
| 1169 | + |
| 1170 | +await expect( |
| 1171 | +tool.execute("call-1", { |
| 1172 | +prompt: "friendly lobster surfing", |
| 1173 | +durationSeconds: 5.5, |
| 1174 | +}), |
| 1175 | +).rejects.toThrow("durationSeconds must be a positive integer"); |
| 1176 | +expect(generateVideo).not.toHaveBeenCalled(); |
| 1177 | +}); |
| 1178 | + |
1142 | 1179 | it("surfaces normalized video geometry from runtime metadata", async () => { |
1143 | 1180 | vi.spyOn(videoGenerationRuntime, "generateVideo").mockResolvedValue({ |
1144 | 1181 | provider: "runway", |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -181,7 +181,7 @@ const VideoGenerateToolProperties = {
|
181 | 181 | }), |
182 | 182 | ), |
183 | 183 | durationSeconds: Type.Optional( |
184 | | -Type.Number({ |
| 184 | +Type.Integer({ |
185 | 185 | description: "Target seconds; may round to nearest supported duration.", |
186 | 186 | minimum: 1, |
187 | 187 | }), |
@@ -998,9 +998,15 @@ export function createVideoGenerateTool(options?: {
|
998 | 998 | const aspectRatio = normalizeAspectRatio(readStringParam(args, "aspectRatio")); |
999 | 999 | const resolution = normalizeResolution(readStringParam(args, "resolution")); |
1000 | 1000 | const durationSeconds = readNumberParam(args, "durationSeconds", { |
1001 | | -integer: true, |
| 1001 | +positiveInteger: true, |
1002 | 1002 | strict: true, |
1003 | 1003 | }); |
| 1004 | +if ( |
| 1005 | +durationSeconds === undefined && |
| 1006 | +readSnakeCaseParamRaw(args, "durationSeconds") !== undefined |
| 1007 | +) { |
| 1008 | +throw new ToolInputError("durationSeconds must be a positive integer"); |
| 1009 | +} |
1004 | 1010 | const audio = readBooleanToolParam(args, "audio"); |
1005 | 1011 | const watermark = readBooleanToolParam(args, "watermark"); |
1006 | 1012 | const timeoutMs = readGenerationTimeoutMs(args) ?? videoGenerationModelConfig.timeoutMs; |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。