|
1 | 1 | import { |
2 | | -normalizeOptionalString, |
3 | | -readStringValue, |
4 | | -} from "openclaw/plugin-sdk/string-coerce-runtime"; |
| 2 | +parseStrictNonNegativeInteger, |
| 3 | +parseStrictPositiveInteger, |
| 4 | +} from "openclaw/plugin-sdk/number-runtime"; |
| 5 | +import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime"; |
5 | 6 | import type { ResolvedBrowserProfile } from "../config.js"; |
6 | 7 | import { |
7 | 8 | DEFAULT_AI_SNAPSHOT_EFFICIENT_DEPTH, |
@@ -14,7 +15,7 @@ import {
|
14 | 15 | shouldUsePlaywrightForScreenshot, |
15 | 16 | } from "../profile-capabilities.js"; |
16 | 17 | import { normalizeBrowserTimerDelayMs } from "../timer-delay.js"; |
17 | | -import { toBoolean, toNumber, toStringOrEmpty } from "./utils.js"; |
| 18 | +import { toBoolean, toStringOrEmpty } from "./utils.js"; |
18 | 19 | |
19 | 20 | type BrowserSnapshotPlan = { |
20 | 21 | format: "ai" | "aria"; |
@@ -49,25 +50,25 @@ export function resolveSnapshotPlan(params: {
|
49 | 50 | explicitFormat, |
50 | 51 | mode, |
51 | 52 | }); |
52 | | -const limitRaw = readStringValue(params.query.limit); |
| 53 | +const limit = parseStrictPositiveInteger(params.query.limit); |
53 | 54 | const hasMaxChars = Object.hasOwn(params.query, "maxChars"); |
54 | | -const maxCharsRaw = readStringValue(params.query.maxChars); |
55 | | -const limit = Number.isFinite(Number(limitRaw)) ? Number(limitRaw) : undefined; |
56 | | -const maxChars = |
57 | | -Number.isFinite(Number(maxCharsRaw)) && Number(maxCharsRaw) > 0 |
58 | | - ? Math.floor(Number(maxCharsRaw)) |
59 | | - : undefined; |
| 55 | +const maxCharsRaw = parseStrictNonNegativeInteger(params.query.maxChars); |
| 56 | +const maxChars = maxCharsRaw !== undefined && maxCharsRaw > 0 ? maxCharsRaw : undefined; |
60 | 57 | const resolvedMaxChars = |
61 | 58 | format === "ai" |
62 | 59 | ? hasMaxChars |
63 | | - ? maxChars |
| 60 | + ? maxCharsRaw === undefined |
| 61 | + ? mode === "efficient" |
| 62 | + ? DEFAULT_AI_SNAPSHOT_EFFICIENT_MAX_CHARS |
| 63 | + : DEFAULT_AI_SNAPSHOT_MAX_CHARS |
| 64 | + : maxChars |
64 | 65 | : mode === "efficient" |
65 | 66 | ? DEFAULT_AI_SNAPSHOT_EFFICIENT_MAX_CHARS |
66 | 67 | : DEFAULT_AI_SNAPSHOT_MAX_CHARS |
67 | 68 | : undefined; |
68 | 69 | const interactiveRaw = toBoolean(params.query.interactive); |
69 | 70 | const compactRaw = toBoolean(params.query.compact); |
70 | | -const depthRaw = toNumber(params.query.depth); |
| 71 | +const depthRaw = parseStrictNonNegativeInteger(params.query.depth); |
71 | 72 | const refsModeRaw = toStringOrEmpty(params.query.refs).trim(); |
72 | 73 | const refsMode: "aria" | "role" | undefined = |
73 | 74 | refsModeRaw === "aria" ? "aria" : refsModeRaw === "role" ? "role" : undefined; |
@@ -77,11 +78,9 @@ export function resolveSnapshotPlan(params: {
|
77 | 78 | depthRaw ?? (mode === "efficient" ? DEFAULT_AI_SNAPSHOT_EFFICIENT_DEPTH : undefined); |
78 | 79 | const selectorValue = normalizeOptionalString(toStringOrEmpty(params.query.selector)); |
79 | 80 | const frameSelectorValue = normalizeOptionalString(toStringOrEmpty(params.query.frame)); |
80 | | -const timeoutMsRaw = toNumber(params.query.timeoutMs); |
| 81 | +const timeoutMsRaw = parseStrictPositiveInteger(params.query.timeoutMs); |
81 | 82 | const timeoutMs = |
82 | | -timeoutMsRaw !== undefined && Number.isFinite(timeoutMsRaw) && timeoutMsRaw > 0 |
83 | | - ? normalizeBrowserTimerDelayMs(timeoutMsRaw) |
84 | | - : undefined; |
| 83 | +timeoutMsRaw !== undefined ? normalizeBrowserTimerDelayMs(timeoutMsRaw) : undefined; |
85 | 84 | |
86 | 85 | return { |
87 | 86 | format, |
|