mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 16:58:25 +00:00
fix: cap ai snapshots for tool calls (#763) (thanks @thesash)
This commit is contained in:
@@ -44,6 +44,8 @@ const BROWSER_ACT_KINDS = [
|
||||
|
||||
type BrowserActKind = (typeof BROWSER_ACT_KINDS)[number];
|
||||
|
||||
const DEFAULT_AI_SNAPSHOT_MAX_CHARS = 80_000;
|
||||
|
||||
// NOTE: Using a flattened object schema instead of Type.Union([Type.Object(...), ...])
|
||||
// because Claude API on Vertex AI rejects nested anyOf schemas as invalid JSON Schema.
|
||||
// The discriminator (kind) determines which properties are relevant; runtime validates.
|
||||
@@ -326,14 +328,19 @@ export function createBrowserTool(opts?: {
|
||||
: undefined;
|
||||
const maxChars =
|
||||
typeof params.maxChars === "number" &&
|
||||
Number.isFinite(params.maxChars)
|
||||
? params.maxChars
|
||||
Number.isFinite(params.maxChars) &&
|
||||
params.maxChars > 0
|
||||
? Math.floor(params.maxChars)
|
||||
: undefined;
|
||||
const resolvedMaxChars =
|
||||
format === "ai"
|
||||
? (maxChars ?? DEFAULT_AI_SNAPSHOT_MAX_CHARS)
|
||||
: undefined;
|
||||
const snapshot = await browserSnapshot(baseUrl, {
|
||||
format,
|
||||
targetId,
|
||||
limit,
|
||||
maxChars,
|
||||
...(resolvedMaxChars ? { maxChars: resolvedMaxChars } : {}),
|
||||
profile,
|
||||
});
|
||||
if (snapshot.format === "ai") {
|
||||
|
||||
@@ -10,8 +10,6 @@ import {
|
||||
let nextUploadArmId = 0;
|
||||
let nextDialogArmId = 0;
|
||||
|
||||
const MAX_SNAPSHOT_CHARS = 80_000;
|
||||
|
||||
function requireRef(value: unknown): string {
|
||||
const ref = typeof value === "string" ? value.trim() : "";
|
||||
if (!ref) throw new Error("ref is required");
|
||||
@@ -44,18 +42,17 @@ export async function snapshotAiViaPlaywright(opts: {
|
||||
),
|
||||
track: "response",
|
||||
});
|
||||
let snapshot = String(result?.full ?? "");
|
||||
const maxChars = opts.maxChars;
|
||||
const limit =
|
||||
typeof maxChars === "number" && Number.isFinite(maxChars) && maxChars > 0
|
||||
? Math.floor(maxChars)
|
||||
: MAX_SNAPSHOT_CHARS;
|
||||
let snapshot = String(result?.full ?? "");
|
||||
let truncated = false;
|
||||
if (snapshot.length > limit) {
|
||||
: undefined;
|
||||
if (limit && snapshot.length > limit) {
|
||||
snapshot = `${snapshot.slice(0, limit)}\n\n[...TRUNCATED - page too large]`;
|
||||
truncated = true;
|
||||
return { snapshot, truncated: true };
|
||||
}
|
||||
return truncated ? { snapshot, truncated } : { snapshot };
|
||||
return { snapshot };
|
||||
}
|
||||
|
||||
export async function clickViaPlaywright(opts: {
|
||||
|
||||
@@ -567,23 +567,22 @@ export function registerBrowserAgentRoutes(
|
||||
? Number(req.query.maxChars)
|
||||
: undefined;
|
||||
const limit = Number.isFinite(limitRaw) ? limitRaw : undefined;
|
||||
const maxChars = Number.isFinite(maxCharsRaw) ? maxCharsRaw : undefined;
|
||||
const maxChars =
|
||||
typeof maxCharsRaw === "number" &&
|
||||
Number.isFinite(maxCharsRaw) &&
|
||||
maxCharsRaw > 0
|
||||
? Math.floor(maxCharsRaw)
|
||||
: undefined;
|
||||
|
||||
try {
|
||||
const tab = await profileCtx.ensureTabAvailable(targetId || undefined);
|
||||
if (format === "ai") {
|
||||
const pw = await requirePwAi(res, "ai snapshot");
|
||||
if (!pw) return;
|
||||
const resolvedMaxChars =
|
||||
typeof maxChars === "number" && maxChars > 0
|
||||
? maxChars
|
||||
: typeof limit === "number" && limit > 0
|
||||
? limit
|
||||
: undefined;
|
||||
const snap = await pw.snapshotAiViaPlaywright({
|
||||
cdpUrl: profileCtx.profile.cdpUrl,
|
||||
targetId: tab.targetId,
|
||||
...(resolvedMaxChars ? { maxChars: resolvedMaxChars } : {}),
|
||||
...(maxChars ? { maxChars } : {}),
|
||||
});
|
||||
return res.json({
|
||||
ok: true,
|
||||
|
||||
Reference in New Issue
Block a user