Skip to content

Open generated images from tool activity#4427

Open
colonelpanic8 wants to merge 3 commits into
pingdotgg:mainfrom
colonelpanic8:t3code/inline-image-support
Open

Open generated images from tool activity#4427
colonelpanic8 wants to merge 3 commits into
pingdotgg:mainfrom
colonelpanic8:t3code/inline-image-support

Conversation

@colonelpanic8

@colonelpanic8 colonelpanic8 commented Jul 24, 2026

Copy link
Copy Markdown

What Changed

  • Recognize completed imageGeneration activities and expose only their activity ID and filename to the client timeline.
  • Resolve the provider-saved image path server-side and serve it through a signed, exact-file asset capability.
  • Render generated images as compact evidence links in the work log instead of automatically expanding thumbnails.
  • Open selected generated images in a dedicated right-panel tab alongside files, diffs, terminals, and browser previews.
  • Keep generated-image links visible across turn/work-log folding and preserve open image tabs across reloads.
  • Retry the short projection race when an image link is opened immediately after completion, while failing non-transient asset errors immediately.

Why

Generated images already arrive with a provider-saved path in completed tool activity, but that activity was rendered only as a text work-log row. The image should remain viewable after streaming finishes and after a thread is reloaded, without depending on the assistant to repeat a filename.

The interaction follows the Codex desktop pattern: images remain compact, link-like evidence in the transcript and open on demand in the existing right-side workspace. This avoids large automatic thumbnails and avoids requesting image assets until the user selects one.

This builds on the direction explored by #3984, which promotes image filenames explicitly mentioned in assistant Markdown, and #4321, which covers broader workspace/browser media references. Neither PR is included as a dependency here.

UI Changes

  • Completed image-generation activity shows an image icon and filename link under the work-log row.
  • Selecting the link opens or activates a named generated-image tab in the right panel.
  • The panel shows the full image with contained sizing, loading state, and load-error state.
  • Multiple generated images remain separate compact transcript links and separate reusable panel tabs.

Current browser evidence

Captured from the exact current PR head 9939cc9a46e6a33dbbca4961b1c755f9ed6fae21 in the combined package 0.0.29-patched-main-20260724 (integration 4dd4cef4039303179929a1dbdbf0c9b358c076f9). The fixture uses a real provider imageGeneration event in a disposable repository.

Compact work-log link Generated-image right panel
Generated-image work-log link Generated image opened in the right panel

Opening a generated image in the right panel

MP4 version of the interaction

Checklist

  • pnpm exec vp test run apps/web/src/rightPanelStore.test.ts apps/web/src/components/chat/MessagesTimeline.test.tsx apps/web/src/components/chat/GeneratedImagePanel.test.tsx apps/server/src/assets/GeneratedImageResolver.test.ts (48 tests)
  • Targeted pnpm exec vp check for all changed server/web files
  • pnpm --filter t3 run typecheck
  • React best-practices review: no asset request before selection, no render-time store subscription, keyboard events isolated from the collapsible parent row
  • Integrated browser verification in an isolated authenticated environment against the exact combined package: real generated-image activity rendered a compact work-log link and opened the signed image in a reusable right-panel tab
  • pnpm --filter @t3tools/web run typecheck currently reports only existing unrelated errors in BranchToolbarBranchSelector.tsx, ModelPickerContent.tsx, PreviewAutomationHosts.tsx, and the atom query hooks

Note

Medium Risk
Touches signed asset issuance and filesystem path validation for provider-saved files; scope is bounded by image-preview checks and exact basename matching, with retries limited to not-found races.

Overview
Provider-generated images can be opened on demand from completed imageGeneration tool activity instead of only showing as plain work-log text.

The server adds a generated-image asset resource: assetsCreateUrl looks up the saved path from thread projection via findGeneratedImagePath, retries briefly when the file is not ready yet, and AssetAccess issues exact-path signed tokens (image preview paths only) with basename-locked resolution.

The client exposes only activity id and filename in work-log entries (not the provider path), renders a compact filename link in the timeline, and opens a dedicated generated-image right-panel tab (GeneratedImagePanel + useAssetUrlState). Timeline folding and work-log grouping skip generated-image rows so links stay visible when turns or tool groups collapse.

Right-panel persistence bumps to v8 with migration validation for generated-image surfaces.

Reviewed by Cursor Bugbot for commit 9939cc9. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add generated image viewer panel accessible from tool activity work log

  • Adds a GeneratedImagePanel right-panel surface that fetches and displays provider-generated images via a signed asset URL, with loading and error states.
  • Clicking a completed image generation entry in the messages timeline opens the panel; the entry renders as a standalone link (not collapsed into grouped work-log rows).
  • Extends the asset token system with a generated-image claim kind, strict canonical path validation, and two new error types (AssetGeneratedImageNotFoundError, AssetGeneratedImageInspectionError).
  • The assetsCreateUrl RPC polls orchestration state with retry until the generated file is available before issuing a signed URL.
  • Bumps RIGHT_PANEL_STORAGE_VERSION to 8; persisted generated-image surfaces are validated on migration and dropped if malformed.

Macroscope summarized 9939cc9.

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c8426607-5a04-4a6c-9881-83fc9c223542

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Jul 24, 2026
Comment thread apps/web/src/components/chat/MessagesTimeline.tsx
Comment thread apps/web/src/components/chat/MessagesTimeline.tsx Outdated
@macroscopeapp

macroscopeapp Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new feature for displaying generated images from tool activity, adding new UI components, server-side asset handling, and state management across multiple packages. New features of this scope warrant human review to validate the integration and user experience.

You can customize Macroscope's approvability policy. Learn more.

@colonelpanic8
colonelpanic8 force-pushed the t3code/inline-image-support branch from b923a8c to 3cc953f Compare July 24, 2026 05:28
@colonelpanic8 colonelpanic8 changed the title Render generated images from tool activity Open generated images from tool activity Jul 24, 2026
@colonelpanic8
colonelpanic8 force-pushed the t3code/inline-image-support branch from 3cc953f to f20908f Compare July 24, 2026 05:30
Comment thread apps/server/src/assets/GeneratedImageResolver.ts
Comment thread apps/web/src/components/chat/GeneratedImagePanel.tsx
@colonelpanic8
colonelpanic8 force-pushed the t3code/inline-image-support branch from f20908f to c0a41f8 Compare July 24, 2026 05:41
Comment thread apps/server/src/ws.ts Outdated
Comment thread apps/server/src/ws.ts
@colonelpanic8
colonelpanic8 force-pushed the t3code/inline-image-support branch from 77a0abd to 2422be0 Compare July 24, 2026 17:01
Comment thread apps/web/src/rightPanelStore.ts

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 9939cc9. Configure here.

kind: "generated-image";
activityId: EventId;
name: string;
loadRequestId: number;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

v8 persist skips loadRequestId

Low Severity

This change makes loadRequestId part of the persisted generated-image surface and uses it in the GeneratedImagePanel React key, but RIGHT_PANEL_STORAGE_VERSION stays at 8. Clients that already saved v8 generated-image tabs without that field will rehydrate without running migration, so loadRequestId can be missing and the panel key becomes unstable until the user opens the image again.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 9939cc9. Configure here.

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

Labels

size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant