From 4dbe2a3d2bcb497b39487e8db8ada381a96d66ff Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Thu, 28 May 2026 17:48:09 -0400 Subject: [PATCH] fix: validate deepinfra video seed metadata --- .../video-generation-provider.test.ts | 28 +++++++++++++++++++ .../deepinfra/video-generation-provider.ts | 13 ++++----- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/extensions/deepinfra/video-generation-provider.test.ts b/extensions/deepinfra/video-generation-provider.test.ts index ff151708729..72a8f4c571d 100644 --- a/extensions/deepinfra/video-generation-provider.test.ts +++ b/extensions/deepinfra/video-generation-provider.test.ts @@ -151,6 +151,34 @@ describe("deepinfra video generation provider", () => { expect(Reflect.get(Reflect.get(postRequest ?? {}, "body") ?? {}, "seed")).toBeUndefined(); }); + it("drops malformed response seed metadata", async () => { + postJsonRequestMock.mockResolvedValue({ + response: { + json: async () => ({ + video_url: "/generated/video.mp4", + request_id: "req_bad_seed", + seed: 1.5, + inference_status: { status: "succeeded" }, + }), + }, + release: vi.fn(async () => {}), + }); + + const provider = buildDeepInfraVideoGenerationProvider(); + const result = await provider.generateVideo({ + provider: "deepinfra", + model: "deepinfra/Pixverse/Pixverse-T2V", + prompt: "A bicycle weaving through a rainy neon street", + cfg: {}, + }); + + expect(result.metadata).toEqual({ + requestId: "req_bad_seed", + seed: undefined, + status: "succeeded", + }); + }); + it("reports malformed native video JSON as a provider error", async () => { const release = vi.fn(async () => {}); postJsonRequestMock.mockResolvedValue({ diff --git a/extensions/deepinfra/video-generation-provider.ts b/extensions/deepinfra/video-generation-provider.ts index cac81dc69da..b4d067987b5 100644 --- a/extensions/deepinfra/video-generation-provider.ts +++ b/extensions/deepinfra/video-generation-provider.ts @@ -8,7 +8,8 @@ import { resolveProviderHttpRequestConfig, } from "openclaw/plugin-sdk/provider-http"; import { - asFiniteNumber as coerceProviderNumber, + asFiniteNumber, + asSafeIntegerInRange, normalizeOptionalString, } from "openclaw/plugin-sdk/string-coerce-runtime"; import type { @@ -94,11 +95,7 @@ function resolveDurationSeconds(value: number | undefined): number | undefined { } function resolveSeed(value: unknown): number | undefined { - const seed = coerceProviderNumber(value); - if (seed == null || !Number.isSafeInteger(seed) || seed < 0 || seed > 4_294_967_295) { - return undefined; - } - return seed; + return asSafeIntegerInRange(value, { min: 0, max: 4_294_967_295 }); } function buildDeepInfraVideoBody( @@ -132,7 +129,7 @@ function buildDeepInfraVideoBody( body.style = style; } const guidanceScale = - coerceProviderNumber(options.guidance_scale) ?? coerceProviderNumber(options.guidanceScale); + asFiniteNumber(options.guidance_scale) ?? asFiniteNumber(options.guidanceScale); if (guidanceScale != null && model.startsWith("Wan-AI/")) { body.guidance_scale = guidanceScale; } @@ -288,7 +285,7 @@ export function buildDeepInfraVideoGenerationProvider(options?: { model, metadata: { requestId: normalizeOptionalString(payload.request_id), - seed: payload.seed, + seed: resolveSeed(payload.seed), status: payload.inference_status?.status ?? payload.status, }, };