mirror of
https://github.com/browser-use/browser-use.git
synced 2026-09-14 19:59:47 +08:00
browser-use-js: preserve complete final output
This commit is contained in:
+3
-18
@@ -2,6 +2,7 @@
|
||||
|
||||
import { readFile } from "node:fs/promises";
|
||||
import { Agent } from "./agent.js";
|
||||
import { eventJsonLine, resultJsonLine } from "./event-json.js";
|
||||
|
||||
const args = process.argv.slice(2);
|
||||
const taskFileIndex = args.indexOf("--task-file");
|
||||
@@ -23,11 +24,11 @@ try {
|
||||
reasoningEffort: reasoningEffort(process.env.BROWSER_USE_JS_REASONING_EFFORT),
|
||||
maxSteps: integer(process.env.BROWSER_USE_JS_MAX_STEPS, 100),
|
||||
onEvent: (event) => {
|
||||
process.stdout.write(`${JSON.stringify(sanitize(event))}\n`);
|
||||
process.stdout.write(eventJsonLine(event));
|
||||
},
|
||||
}).run();
|
||||
const { messages: _messages, ...summary } = result;
|
||||
process.stdout.write(`${JSON.stringify({ type: "browser_use_js_result", result: sanitize(summary) })}\n`);
|
||||
process.stdout.write(resultJsonLine(summary));
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? `${error.name}: ${error.message}` : String(error);
|
||||
process.stdout.write(`${JSON.stringify({ type: "browser_use_js_error", error: message })}\n`);
|
||||
@@ -35,22 +36,6 @@ try {
|
||||
process.exitCode = 1;
|
||||
}
|
||||
|
||||
function sanitize(value: unknown): unknown {
|
||||
if (Array.isArray(value)) return value.map(sanitize);
|
||||
if (!value || typeof value !== "object") {
|
||||
return typeof value === "string" && value.length > 30_000
|
||||
? `${value.slice(0, 30_000)}... <${value.length - 30_000} chars omitted>`
|
||||
: value;
|
||||
}
|
||||
const result: Record<string, unknown> = {};
|
||||
for (const [key, item] of Object.entries(value as Record<string, unknown>)) {
|
||||
result[key] = key === "data" && typeof item === "string" && item.length > 10_000
|
||||
? `<image:${item.length} chars>`
|
||||
: sanitize(item);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function integer(value: string | undefined, fallback: number): number {
|
||||
const parsed = Number.parseInt(value ?? "", 10);
|
||||
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
const MAX_EVENT_STRING_CHARS = 30_000;
|
||||
|
||||
/** Encode a bounded Pi event for JSONL logs and telemetry ingestion. */
|
||||
export function eventJsonLine(event: unknown): string {
|
||||
return `${JSON.stringify(sanitizeEvent(event))}\n`;
|
||||
}
|
||||
|
||||
/** Encode the public result without clipping the user's final deliverable. */
|
||||
export function resultJsonLine(result: unknown): string {
|
||||
return `${JSON.stringify({ type: "browser_use_js_result", result })}\n`;
|
||||
}
|
||||
|
||||
function sanitizeEvent(value: unknown): unknown {
|
||||
if (Array.isArray(value)) return value.map(sanitizeEvent);
|
||||
if (!value || typeof value !== "object") {
|
||||
return typeof value === "string" && value.length > MAX_EVENT_STRING_CHARS
|
||||
? `${value.slice(0, MAX_EVENT_STRING_CHARS)}... <${value.length - MAX_EVENT_STRING_CHARS} chars omitted>`
|
||||
: value;
|
||||
}
|
||||
const result: Record<string, unknown> = {};
|
||||
for (const [key, item] of Object.entries(value as Record<string, unknown>)) {
|
||||
result[key] = key === "data" && typeof item === "string" && item.length > 10_000
|
||||
? `<image:${item.length} chars>`
|
||||
: sanitizeEvent(item);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -2,6 +2,15 @@ import assert from "node:assert/strict";
|
||||
import test from "node:test";
|
||||
import { WebSocketServer } from "ws";
|
||||
import { CdpSession, createBrowserSession } from "../dist/cdp.js";
|
||||
import { eventJsonLine, resultJsonLine } from "../dist/event-json.js";
|
||||
|
||||
test("CLI clips trace events without clipping the final deliverable", () => {
|
||||
const output = "x".repeat(40_000);
|
||||
const event = JSON.parse(eventJsonLine({ output }));
|
||||
const result = JSON.parse(resultJsonLine({ output }));
|
||||
assert.match(event.output, /chars omitted/);
|
||||
assert.equal(result.result.output, output);
|
||||
});
|
||||
|
||||
test("CDP session attaches once and routes page calls through the active session", async () => {
|
||||
const requests = [];
|
||||
|
||||
Reference in New Issue
Block a user