Skip to content

feat(ui): display image attachments from tool results - #38846

Closed
johnwmail wants to merge 2 commits into
anomalyco:devfrom
johnwmail:feat/tool-result-image-display
Closed

johnwmail wants to merge 2 commits into
anomalyco:devfrom
johnwmail:feat/tool-result-image-display

Conversation

@johnwmail

@johnwmail johnwmail commented Jul 25, 2026 •

Copy link
Copy Markdown

Issue for this PR

Closes #21227

Type of change

  • New feature

What does this PR do?

Tool results can carry image attachments (state.attachments with an image mime type) — e.g. MCP ImageCo ntent blocks from browser/screenshot tools, or images returned by the built-in read tool. They are forw
arded to the model, but the web UI never renders them.

This PR renders image attachments as clickable thumbnails below completed tool calls; clicking a thumbnail
opens the existing ImagePreview dialog.

A small shared ToolImageAttachments component is used in both tool rendering paths:

  • ToolPartDisplay — MCP tools and other non-grouped tools
  • ContextToolGroup — the read/grep/glob group row, so images produced by the read tool are visible wit
    hout expanding the group

Non-image attachments and non-completed tool states render nothing, as before.

How did you verify your code works?

Ran the backend (bun run --conditions=browser ./src/index.ts serve --port 4096) and the app dev server (
bun dev -- --port 4444) locally, then drove the UI headlessly with Playwright:

  1. Asked the agent to read a PNG file → thumbnail strip appears below the "Exploring · 1 read" group row
    ; clicking it opens the full-size preview dialog.
  2. Registered a mock MCP server whose tool returns an ImageContent block → thumbnail appears directly un
    der the Called mock-img_take_screenshot row.

Also ran tsgo --noEmit (clean), prettier --check, oxlint (no new issues), and the existing message- part.test.ts (6 pass).

Screenshots / recordings

MCP tool returning an image:

MCP tool call with image thumbnail

read tool on an image file (context group row):

read tool group with image thumbnail

Clicking a thumbnail opens the full-size preview:

image preview dialog

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

Tool results can include image attachments (e.g. MCP ImageContent blocks
from browser/screenshot tools, or images returned by the read tool), but
the web UI never rendered them - they were only forwarded to the model.

Show clickable image thumbnails below completed tool calls, for both
rendering paths:
- ToolPartDisplay (MCP and other non-grouped tools)
- ContextToolGroup (read/grep/glob group row)

Clicking a thumbnail opens the existing ImagePreview dialog.

Closes anomalyco#21227
@github-actions github-actions Bot added the needs:compliance This means the issue will auto-close after 2 hours. label Jul 25, 2026
@github-actions github-actions Bot removed the needs:compliance This means the issue will auto-close after 2 hours. label Jul 25, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Thanks for updating your PR! It now meets our contributing guidelines. 👍

@cheezfish

Copy link
Copy Markdown

Validated this fix against a shipped OpenCode Desktop build. I ported the exact change (ToolImageAttachments in ContextToolGroup + ToolPartDisplay) onto the Electron renderer bundle and tested it live:

  • Custom plugin tool returning {type:"file", mime:"image/png"} attachments → 48px thumbnail renders in the tool row, click opens the fullscreen ImagePreview. Works in both the plain tool row and the context (read/search) tool group.
  • Model-side media forwarding is unaffected; attachments still reach the provider as before.
  • Confirmed the failure mode this fixes: tool-result images were previously invisible in the UI even though stored correctly in part.state.attachments.

One observation from testing (not a blocker): the server's tool-result image normalization (image.normalize) upscales small images to ~1200px before storing, so tiny source images look soft at fullscreen preview. Native-resolution photos render crisp.

Thanks for the fix — looking forward to it landing so I can drop my local patch.

@github-actions

Copy link
Copy Markdown
Contributor

Automated PR Cleanup

Thank you for contributing to opencode.

Due to the high volume of PRs from users and AI agents, we periodically close older PRs using automated criteria so maintainers can focus review time on the most active and community-supported contributions.

This PR was closed because it matched the following cleanup criteria:

  • The PR was created more than 1 month ago
  • The PR had fewer than 2 positive reactions
  • Positive reactions are counted as thumbs-up, heart, celebration, or rocket reactions on the PR

PRs created within the last month are not affected by this cleanup.

If you believe this PR was closed incorrectly, or if you are still actively working on it, please leave a comment explaining why it should be reopened. A maintainer can review and reopen it if appropriate.

Thanks again for taking the time to contribute.

@TheOriginal92

Copy link
Copy Markdown

Also hitting this on opencode web (1.18.5, Docker). Images returned by MCP tools are converted to data: URIs in session/tools.ts and stored in part.state.attachments; they reach the model correctly, but the chat UI never renders them, so the only way to look at a screenshot a tool just produced is to open the file outside opencode.

This PR was closed by the automated cleanup rather than on review, and it already carries an independent verification against a Desktop build in the thread above. Could a maintainer either reopen it, or point at #39817 as the preferred direction so the effort isn't split across two patches?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE(app)]: display image attachments from tool results in chat UI

3 participants