Open saved browser screenshots in image viewer
Route persisted browser screenshot thumbnails to the shared image viewer modal while keeping live Browser previews as Canvas entry points.\n\nAdd regression coverage so static screenshot artifacts do not regress back to opening the Browser surface.
Alessandro committed
May 22, 2026 at 05:03 UTC
26b3ae00d52979ba18d74b71aacf5d333151defa
2 files changed
+19
-1
plugins/_browser/extensions/webui/get_tool_message_handler/browser-tool-handler.js
+14
-1
@@ -2,6 +2,7 @@ import {
2
createActionButton,
3
copyToClipboard,
4
} from "/components/messages/action-buttons/simple-action-buttons.js";
5
+import { store as imageViewerStore } from "/components/modals/image-viewer/image-viewer-store.js";
6
import { store as stepDetailStore } from "/components/modals/process-step-detail/step-detail-store.js";
7
import { ttsService } from "/js/tts-service.js";
8
import { store as browserStore } from "/plugins/_browser/webui/browser-store.js";
@@ -206,6 +207,12 @@ function staticScreenshotSrc(uri = "") {
207
return uri ? uri.replace("img://", "/api/image_get?path=") : "";
208
}
209
210
+function openStaticScreenshot(uri = "") {
211
+ const src = staticScreenshotSrc(uri);
212
+ if (!src) return;
213
+ imageViewerStore.open(src, { name: "Browser screenshot" });
214
+}
215
+
216
function releaseLiveScreenshotFrame(viewerId) {
217
const release = liveScreenshotFrames.get(viewerId);
218
if (!release) return;
@@ -348,6 +355,10 @@ function renderBrowserScreenshotKvp(kvpsTable, resolveBrowserPayload, label, sta
355
button.addEventListener("click", async (event) => {
356
event.preventDefault();
357
event.stopPropagation();
358
+ if (staticUri) {
359
+ openStaticScreenshot(staticUri);
360
+ return;
361
+ }
362
const canvasPayload = resolveBrowserPayload();
363
if (!canvasPayload) return;
364
await openBrowserSurface(canvasPayload);
@@ -477,7 +488,9 @@ function drawBrowserTool({
488
const screenshotUri = staticScreenshotUri(kvps);
489
const browserId = browserIdFromResult(browserResult, kvps);
490
const browserCanvasPayload = buildBrowserCanvasPayload(browserResult, kvps);
480
- const browserPreviewLabel = browserId
491
+ const browserPreviewLabel = screenshotUri
492
+ ? "Open Browser screenshot"
493
+ : browserId
494
? `Open Browser surface for Browser ${browserId}`
495
: "Open Browser surface from screenshot";
496
if (shouldRenderBrowserScreenshotKvp(browserResult, kvps)) {
tests/test_browser_agent_regressions.py
+5
@@ -1122,6 +1122,11 @@ def test_browser_viewer_uses_cdp_screencast_transport():
1122
assert '"snapshot": snapshot' in ws_browser
1123
assert 'const BROWSER_SNAPSHOT_META_KEY = "browser_snapshot";' in browser_tool_handler
1124
assert "staticScreenshotUri(kvps)" in browser_tool_handler
1125
+ assert "/components/modals/image-viewer/image-viewer-store.js" in browser_tool_handler
1126
+ assert "function openStaticScreenshot(uri = \"\")" in browser_tool_handler
1127
+ assert "imageViewerStore.open(src, { name: \"Browser screenshot\" });" in browser_tool_handler
1128
+ assert "if (staticUri) {" in browser_tool_handler
1129
+ assert "openStaticScreenshot(staticUri);" in browser_tool_handler
1130
assert "delete displayKvps[BROWSER_SNAPSHOT_META_KEY];" in browser_tool_handler
1131
assert "startBrowserScreenshotPreview(button, image, resolveBrowserPayload)" in browser_tool_handler
1132
assert "FRAME_FALLBACK_SCREENSHOT_SECONDS" not in ws_browser