@@ -18,6 +18,7 @@ import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js";
|
18 | 18 | import type { ImageSanitizationLimits } from "../image-sanitization.js"; |
19 | 19 | import type { AgentToolResult } from "../runtime/index.js"; |
20 | 20 | import { sanitizeToolResultImages } from "../tool-images.js"; |
| 21 | +import { readPositiveIntegerParam } from "./common.js"; |
21 | 22 | import type { GatewayCallOptions } from "./gateway.js"; |
22 | 23 | import { callGatewayTool } from "./gateway.js"; |
23 | 24 | import { resolveNode, resolveNodeId } from "./nodes-utils.js"; |
@@ -46,6 +47,7 @@ export const POLICY_REDIRECT_INVOKE_COMMANDS: ReadonlySet<string> = new Set([
|
46 | 47 | ]); |
47 | 48 | |
48 | 49 | export type NodeMediaAction = "camera_snap" | "photos_latest" | "camera_clip" | "screen_record"; |
| 50 | +const MAX_RECORDING_DURATION_MS = 300_000; |
49 | 51 | |
50 | 52 | type ExecuteNodeMediaActionParams = { |
51 | 53 | action: NodeMediaAction; |
@@ -294,12 +296,11 @@ async function executeCameraClip({
|
294 | 296 | if (facing !== "front" && facing !== "back") { |
295 | 297 | throw new Error("invalid facing (front|back)"); |
296 | 298 | } |
297 | | -const durationMs = |
298 | | -typeof params.durationMs === "number" && Number.isFinite(params.durationMs) |
299 | | - ? params.durationMs |
300 | | - : typeof params.duration === "string" |
301 | | - ? parseDurationMs(params.duration) |
302 | | - : 3000; |
| 299 | +const durationMs = Math.min( |
| 300 | +readPositiveIntegerParam(params, "durationMs") ?? |
| 301 | +(typeof params.duration === "string" ? parseDurationMs(params.duration) : 3000), |
| 302 | +MAX_RECORDING_DURATION_MS, |
| 303 | +); |
303 | 304 | const includeAudio = typeof params.includeAudio === "boolean" ? params.includeAudio : true; |
304 | 305 | const deviceId = |
305 | 306 | typeof params.deviceId === "string" && params.deviceId.trim() |
@@ -341,12 +342,9 @@ async function executeScreenRecord({
|
341 | 342 | const node = requireString(params, "node"); |
342 | 343 | const nodeId = await resolveNodeId(gatewayOpts, node); |
343 | 344 | const durationMs = Math.min( |
344 | | -typeof params.durationMs === "number" && Number.isFinite(params.durationMs) |
345 | | - ? params.durationMs |
346 | | - : typeof params.duration === "string" |
347 | | - ? parseDurationMs(params.duration) |
348 | | - : 10_000, |
349 | | -300_000, |
| 345 | +readPositiveIntegerParam(params, "durationMs") ?? |
| 346 | +(typeof params.duration === "string" ? parseDurationMs(params.duration) : 10_000), |
| 347 | +MAX_RECORDING_DURATION_MS, |
350 | 348 | ); |
351 | 349 | const fps = typeof params.fps === "number" && Number.isFinite(params.fps) ? params.fps : 10; |
352 | 350 | const screenIndex = |
|