From b769b65b485d26a87a77842ef1ab9c24d1fc351a Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 14 Feb 2026 13:35:11 +0000 Subject: [PATCH] refactor(browser): share proxy file helpers --- src/agents/tools/browser-tool.ts | 31 ++------------------- src/browser/proxy-files.ts | 40 +++++++++++++++++++++++++++ src/gateway/server-methods/browser.ts | 31 ++------------------- 3 files changed, 46 insertions(+), 56 deletions(-) create mode 100644 src/browser/proxy-files.ts diff --git a/src/agents/tools/browser-tool.ts b/src/agents/tools/browser-tool.ts index 7065ae99336..e7fb904b2be 100644 --- a/src/agents/tools/browser-tool.ts +++ b/src/agents/tools/browser-tool.ts @@ -22,8 +22,8 @@ import { import { resolveBrowserConfig } from "../../browser/config.js"; import { DEFAULT_AI_SNAPSHOT_MAX_CHARS } from "../../browser/constants.js"; import { DEFAULT_UPLOAD_DIR, resolvePathsWithinRoot } from "../../browser/paths.js"; +import { applyBrowserProxyPaths, persistBrowserProxyFiles } from "../../browser/proxy-files.js"; import { loadConfig } from "../../config/config.js"; -import { saveMediaBuffer } from "../../media/store.js"; import { wrapExternalContent } from "../../security/external-content.js"; import { BrowserToolSchema } from "./browser-tool.schema.js"; import { type AnyAgentTool, imageResultFromFile, jsonResult, readStringParam } from "./common.js"; @@ -181,36 +181,11 @@ async function callBrowserProxy(params: { } async function persistProxyFiles(files: BrowserProxyFile[] | undefined) { - if (!files || files.length === 0) { - return new Map(); - } - const mapping = new Map(); - for (const file of files) { - const buffer = Buffer.from(file.base64, "base64"); - const saved = await saveMediaBuffer(buffer, file.mimeType, "browser", buffer.byteLength); - mapping.set(file.path, saved.path); - } - return mapping; + return await persistBrowserProxyFiles(files); } function applyProxyPaths(result: unknown, mapping: Map) { - if (!result || typeof result !== "object") { - return; - } - const obj = result as Record; - if (typeof obj.path === "string" && mapping.has(obj.path)) { - obj.path = mapping.get(obj.path); - } - if (typeof obj.imagePath === "string" && mapping.has(obj.imagePath)) { - obj.imagePath = mapping.get(obj.imagePath); - } - const download = obj.download; - if (download && typeof download === "object") { - const d = download as Record; - if (typeof d.path === "string" && mapping.has(d.path)) { - d.path = mapping.get(d.path); - } - } + applyBrowserProxyPaths(result, mapping); } function resolveBrowserBaseUrl(params: { diff --git a/src/browser/proxy-files.ts b/src/browser/proxy-files.ts new file mode 100644 index 00000000000..b18820a4594 --- /dev/null +++ b/src/browser/proxy-files.ts @@ -0,0 +1,40 @@ +import { saveMediaBuffer } from "../media/store.js"; + +export type BrowserProxyFile = { + path: string; + base64: string; + mimeType?: string; +}; + +export async function persistBrowserProxyFiles(files: BrowserProxyFile[] | undefined) { + if (!files || files.length === 0) { + return new Map(); + } + const mapping = new Map(); + for (const file of files) { + const buffer = Buffer.from(file.base64, "base64"); + const saved = await saveMediaBuffer(buffer, file.mimeType, "browser", buffer.byteLength); + mapping.set(file.path, saved.path); + } + return mapping; +} + +export function applyBrowserProxyPaths(result: unknown, mapping: Map) { + if (!result || typeof result !== "object") { + return; + } + const obj = result as Record; + if (typeof obj.path === "string" && mapping.has(obj.path)) { + obj.path = mapping.get(obj.path); + } + if (typeof obj.imagePath === "string" && mapping.has(obj.imagePath)) { + obj.imagePath = mapping.get(obj.imagePath); + } + const download = obj.download; + if (download && typeof download === "object") { + const d = download as Record; + if (typeof d.path === "string" && mapping.has(d.path)) { + d.path = mapping.get(d.path); + } + } +} diff --git a/src/gateway/server-methods/browser.ts b/src/gateway/server-methods/browser.ts index 42e53e85983..80e13e7ec00 100644 --- a/src/gateway/server-methods/browser.ts +++ b/src/gateway/server-methods/browser.ts @@ -5,9 +5,9 @@ import { createBrowserControlContext, startBrowserControlServiceFromConfig, } from "../../browser/control-service.js"; +import { applyBrowserProxyPaths, persistBrowserProxyFiles } from "../../browser/proxy-files.js"; import { createBrowserRouteDispatcher } from "../../browser/routes/dispatcher.js"; import { loadConfig } from "../../config/config.js"; -import { saveMediaBuffer } from "../../media/store.js"; import { isNodeCommandAllowed, resolveNodeCommandAllowlist } from "../node-command-policy.js"; import { ErrorCodes, errorShape } from "../protocol/index.js"; import { safeParseJson } from "./nodes.helpers.js"; @@ -113,36 +113,11 @@ function resolveBrowserNodeTarget(params: { } async function persistProxyFiles(files: BrowserProxyFile[] | undefined) { - if (!files || files.length === 0) { - return new Map(); - } - const mapping = new Map(); - for (const file of files) { - const buffer = Buffer.from(file.base64, "base64"); - const saved = await saveMediaBuffer(buffer, file.mimeType, "browser", buffer.byteLength); - mapping.set(file.path, saved.path); - } - return mapping; + return await persistBrowserProxyFiles(files); } function applyProxyPaths(result: unknown, mapping: Map) { - if (!result || typeof result !== "object") { - return; - } - const obj = result as Record; - if (typeof obj.path === "string" && mapping.has(obj.path)) { - obj.path = mapping.get(obj.path); - } - if (typeof obj.imagePath === "string" && mapping.has(obj.imagePath)) { - obj.imagePath = mapping.get(obj.imagePath); - } - const download = obj.download; - if (download && typeof download === "object") { - const d = download as Record; - if (typeof d.path === "string" && mapping.has(d.path)) { - d.path = mapping.get(d.path); - } - } + applyBrowserProxyPaths(result, mapping); } export const browserHandlers: GatewayRequestHandlers = {