From 69a0f2d0ff07a571f651732cec7cf8a6a44ee0c7 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Mon, 17 Aug 2026 22:07:17 -0700 Subject: [PATCH] fix(browser): keep screenshot sharing hints capability-neutral (#125597) Browser screenshot results always named the message tool even when policy had removed it from the model's effective tool surface. Report the staged sanitized outbound copy and its path without naming another independently gated tool, so the result remains actionable without becoming hallucination bait. Update the vision, fallback, and raw-image result tests to protect that contract. --- extensions/browser/src/browser-tool.test.ts | 9 ++++++--- extensions/browser/src/browser-tool.ts | 6 +++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/extensions/browser/src/browser-tool.test.ts b/extensions/browser/src/browser-tool.test.ts index b41415ee1bee..d7884751f7a0 100644 --- a/extensions/browser/src/browser-tool.test.ts +++ b/extensions/browser/src/browser-tool.test.ts @@ -1709,7 +1709,8 @@ describe("browser tool snapshot maxChars", () => { expect(imageParams.extraText).toContain( JSON.stringify("/tmp/openclaw-media/outbound/share.png"), ); - expect(imageParams.extraText).toContain("message tool"); + expect(imageParams.extraText).toContain("sanitized outbound copy"); + expect(imageParams.extraText).not.toContain("message tool"); expect(imageParams.details?.media).toEqual({ outbound: false }); expect(toolCommonMocks.stageBrowserScreenshotForSharing).toHaveBeenCalledWith( "/tmp/test.png", @@ -1796,7 +1797,8 @@ describe("browser tool snapshot maxChars", () => { expect(joined).toContain("[neutralized] MEDIA:/tmp/secret.png"); expect(joined).toContain("/tmp/secret.png"); expect(joined).toContain(JSON.stringify("/tmp/openclaw-media/outbound/share.png")); - expect(joined).toContain("message tool"); + expect(joined).toContain("sanitized outbound copy"); + expect(joined).not.toContain("message tool"); // The vision-success path must not surface raw screenshot media via // details.media so channel auto-delivery cannot grab the screenshot. expect((out?.details as Record)?.media).toBeUndefined(); @@ -1851,7 +1853,8 @@ describe("browser tool snapshot maxChars", () => { expect(imageParams.extraText).toContain( JSON.stringify("/tmp/openclaw-media/outbound/share.png"), ); - expect(imageParams.extraText).toContain("message tool"); + expect(imageParams.extraText).toContain("sanitized outbound copy"); + expect(imageParams.extraText).not.toContain("message tool"); expect(imageParams.details?.media).toEqual({ outbound: false }); }); diff --git a/extensions/browser/src/browser-tool.ts b/extensions/browser/src/browser-tool.ts index 025d0535864e..6b8bec2ad91f 100644 --- a/extensions/browser/src/browser-tool.ts +++ b/extensions/browser/src/browser-tool.ts @@ -115,7 +115,7 @@ function readTargetUrlParam(params: Record) { } function formatScreenshotShareHint(filePath: string): string { - return `[Screenshot saved to ${JSON.stringify(filePath)}. Use this path with the message tool to share the screenshot explicitly.]`; + return `[Screenshot saved to ${JSON.stringify(filePath)}. A sanitized outbound copy is ready at this path for explicit sharing.]`; } const SCREENSHOT_SHARE_UNAVAILABLE = @@ -799,7 +799,7 @@ export function createBrowserTool(opts?: { // Screenshot viewing remains useful when optional outbound staging fails. } // Screenshots stay in the tool result for agent vision, but channel - // delivery must remain an explicit message-tool action. + // delivery must remain an explicit outbound-delivery action. const screenshotDetails = { ...(result as Record), media: { outbound: false }, @@ -846,7 +846,7 @@ export function createBrowserTool(opts?: { // a text description as the deliverable output. Exposing the raw // screenshot as media would cause channel delivery to auto-send // potentially sensitive page content. The text block carries the - // staged outbound-copy path for an explicit message-tool send. + // staged outbound-copy path for an explicit outbound-delivery send. vision: { provider: described.provider, model: described.model,