Skip to content

Commit 4829146

Browse files
committed
fix: validate runway video durations
1 parent ccf3476 commit 4829146

2 files changed

Lines changed: 39 additions & 1 deletion

File tree

extensions/runway/video-generation-provider.test.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,41 @@ describe("runway video generation provider", () => {
115115
expect(metadata.endpoint).toBe("/v1/text_to_video");
116116
});
117117

118+
it("does not round malformed duration values into create requests", async () => {
119+
postJsonRequestMock.mockResolvedValue({
120+
response: {
121+
json: async () => ({ id: "task-duration" }),
122+
},
123+
release: vi.fn(async () => {}),
124+
});
125+
fetchWithTimeoutMock
126+
.mockResolvedValueOnce({
127+
json: async () => ({
128+
id: "task-duration",
129+
status: "SUCCEEDED",
130+
output: ["https://example.com/out.mp4"],
131+
}),
132+
headers: new Headers(),
133+
})
134+
.mockResolvedValueOnce({
135+
arrayBuffer: async () => Buffer.from("mp4-bytes"),
136+
headers: new Headers({ "content-type": "video/mp4" }),
137+
});
138+
139+
const provider = buildRunwayVideoGenerationProvider();
140+
await provider.generateVideo({
141+
provider: "runway",
142+
model: "gen4.5",
143+
prompt: "a tiny lobster DJ under neon lights",
144+
cfg: {},
145+
durationSeconds: 4.5,
146+
aspectRatio: "16:9",
147+
});
148+
149+
expect(postJsonRequestMock).toHaveBeenCalledTimes(1);
150+
expect(firstPostJsonRequest().body?.duration).toBe(5);
151+
});
152+
118153
it("accepts local image buffers by converting them into data URIs", async () => {
119154
postJsonRequestMock.mockResolvedValue({
120155
response: {

extensions/runway/video-generation-provider.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,10 @@ function resolveDurationSeconds(value: number | undefined): number {
149149
if (typeof value !== "number" || !Number.isFinite(value)) {
150150
return 5;
151151
}
152-
return Math.max(2, Math.min(MAX_DURATION_SECONDS, Math.round(value)));
152+
if (!Number.isSafeInteger(value)) {
153+
return 5;
154+
}
155+
return Math.max(2, Math.min(MAX_DURATION_SECONDS, value));
153156
}
154157

155158
function resolveRunwayRatio(req: VideoGenerationRequest): string {

0 commit comments

Comments
 (0)