mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-06 05:51:15 +08:00
fix: validate pixverse video seed metadata
This commit is contained in:
@@ -182,6 +182,48 @@ describe("pixverse video generation provider", () => {
|
||||
expect(firstPostJsonRequest().body).not.toHaveProperty("seed");
|
||||
});
|
||||
|
||||
it("drops malformed response seed metadata", async () => {
|
||||
postJsonRequestMock.mockResolvedValue({
|
||||
response: {
|
||||
json: async () => ({
|
||||
ErrCode: 0,
|
||||
ErrMsg: "success",
|
||||
Resp: { video_id: 123 },
|
||||
}),
|
||||
},
|
||||
release: vi.fn(async () => {}),
|
||||
});
|
||||
fetchWithTimeoutMock.mockResolvedValueOnce({
|
||||
json: async () => ({
|
||||
ErrCode: 0,
|
||||
ErrMsg: "success",
|
||||
Resp: {
|
||||
id: 123,
|
||||
status: 1,
|
||||
url: "https://media.pixverse.ai/out.mp4",
|
||||
seed: 1.5,
|
||||
},
|
||||
}),
|
||||
headers: new Headers(),
|
||||
});
|
||||
|
||||
const provider = buildPixVerseVideoGenerationProvider();
|
||||
const result = await provider.generateVideo({
|
||||
provider: "pixverse",
|
||||
model: "pixverse/v6",
|
||||
prompt: "a quiet city street at sunrise",
|
||||
cfg: {},
|
||||
});
|
||||
|
||||
expect(result.metadata).toEqual({
|
||||
endpoint: "/video/text/generate",
|
||||
videoId: 123,
|
||||
status: 1,
|
||||
seed: undefined,
|
||||
size: undefined,
|
||||
});
|
||||
});
|
||||
|
||||
it("uploads local image input before submitting image-to-video", async () => {
|
||||
postMultipartRequestMock.mockResolvedValue({
|
||||
response: {
|
||||
|
||||
@@ -13,7 +13,11 @@ import {
|
||||
sanitizeConfiguredModelProviderRequest,
|
||||
type ProviderOperationDeadline,
|
||||
} from "openclaw/plugin-sdk/provider-http";
|
||||
import { asFiniteNumber, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import {
|
||||
asFiniteNumber,
|
||||
asSafeIntegerInRange,
|
||||
normalizeOptionalString,
|
||||
} from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import type {
|
||||
GeneratedVideoAsset,
|
||||
VideoGenerationProvider,
|
||||
@@ -34,6 +38,7 @@ const DEFAULT_TIMEOUT_MS = 300_000;
|
||||
const POLL_INTERVAL_MS = 5_000;
|
||||
const MAX_POLL_ATTEMPTS = 180;
|
||||
const MAX_DURATION_SECONDS = 15;
|
||||
const PIXVERSE_SEED_MAX = 2_147_483_647;
|
||||
const PIXVERSE_VIDEO_MODELS = ["v6", "c1"] as const;
|
||||
const PIXVERSE_TEXT_ASPECT_RATIOS = [
|
||||
"16:9",
|
||||
@@ -134,12 +139,16 @@ function appendOptionalNumber(body: Record<string, unknown>, key: string, value:
|
||||
}
|
||||
|
||||
function appendOptionalInt32Seed(body: Record<string, unknown>, value: unknown): void {
|
||||
const seed = asFiniteNumber(value);
|
||||
if (seed != null && Number.isSafeInteger(seed) && seed >= 0 && seed <= 2_147_483_647) {
|
||||
const seed = asSafeIntegerInRange(value, { min: 0, max: PIXVERSE_SEED_MAX });
|
||||
if (seed !== undefined) {
|
||||
body.seed = seed;
|
||||
}
|
||||
}
|
||||
|
||||
function readPixVerseSeed(value: unknown): number | undefined {
|
||||
return asSafeIntegerInRange(value, { min: 0, max: PIXVERSE_SEED_MAX });
|
||||
}
|
||||
|
||||
function appendOptionalString(body: Record<string, unknown>, key: string, value: unknown): void {
|
||||
const stringValue = normalizeOptionalString(value);
|
||||
if (stringValue) {
|
||||
@@ -498,7 +507,7 @@ export function buildPixVerseVideoGenerationProvider(): VideoGenerationProvider
|
||||
endpoint,
|
||||
videoId,
|
||||
status: readPixVerseStatus(completed),
|
||||
seed: asFiniteNumber(completed.seed),
|
||||
seed: readPixVerseSeed(completed.seed),
|
||||
size: asFiniteNumber(completed.size),
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user