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.
This commit is contained in:
Peter Steinberger
2026-08-17 22:07:17 -07:00
committed by GitHub
parent e6a427c493
commit 69a0f2d0ff
2 changed files with 9 additions and 6 deletions
+6 -3
View File
@@ -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<string, unknown>)?.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 });
});
+3 -3
View File
@@ -115,7 +115,7 @@ function readTargetUrlParam(params: Record<string, unknown>) {
}
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<string, unknown>),
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,