Skip to content

Render file previews via widget-pulled reads; make structuredContent …#536

Open
edgarsskore wants to merge 3 commits into
mainfrom
feature/preview-pull-by-path
Open

Render file previews via widget-pulled reads; make structuredContent …#536
edgarsskore wants to merge 3 commits into
mainfrom
feature/preview-pull-by-path

Conversation

@edgarsskore

@edgarsskore edgarsskore commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator

The preview widget now renders every file type from its own read_file RPC call (origin:'ui'), which the host passes through untouched:

  • Reads pull at tool-input time (tool-result never arrives for images); mutations (write_file/edit_block, inferred from arg shape since the host doesn't send the tool name) pull at tool-result time, after the file changed.
  • Image bytes return as a base64 text block on ui reads - an image content block would make the host inline-render the RPC response and stall it.
  • structuredContent is returned only on origin:'ui' calls and is metadata-only (fileName/filePath/fileType/editor metadata/mimeType): no content duplication, no sourceTool (the widget stamps that client-side for telemetry). LLM-facing responses carry content[] only.
  • An 8s timeout bounds the RPC pull and a 10s watchdog replaces a stuck "Preparing preview..." with a failure row instead of spinning forever.
  • read_file directory listings drop the "use list_directory instead" hint on ui reads so it doesn't render as a notice in the directory preview.

Tests updated to the new contract.

Summary by CodeRabbit

  • New Features
    • File previews now adapt to request origin: the UI view receives metadata-only structured info (file type/name/path, image mimeType), while non-UI responses return content-only payloads.
    • Image and PDF handling is more consistent, separating preview text from metadata across the read/edit flow.
  • Bug Fixes
    • Improved preview rendering to consistently pull and render the latest read result, with more reliable loading recovery and fewer redundant/stale updates.
  • Tests
    • Updated edit/read preview assertions to match the new origin-dependent structured/contents contract.

…widget-only

The host may strip structuredContent from ui/notifications/tool-result and
swallows the notification entirely for image results (it preempts delivery to
inline-render the image), so previews rendered from notification payloads hung
on "Preparing preview..." or fell back to a bare status row.

The preview widget now renders every file type from its own read_file RPC
call (origin:'ui'), which the host passes through untouched:

- Reads pull at tool-input time (tool-result never arrives for images);
  mutations (write_file/edit_block, inferred from arg shape since the host
  doesn't send the tool name) pull at tool-result time, after the file changed.
- Image bytes return as a base64 text block on ui reads - an image content
  block would make the host inline-render the RPC response and stall it.
- structuredContent is returned only on origin:'ui' calls and is metadata-only
  (fileName/filePath/fileType/editor metadata/mimeType): no content
  duplication, no sourceTool (the widget stamps that client-side for
  telemetry). LLM-facing responses carry content[] only.
- An 8s timeout bounds the RPC pull and a 10s watchdog replaces a stuck
  "Preparing preview..." with a failure row instead of spinning forever.
- read_file directory listings drop the "use list_directory instead" hint on
  ui reads so it doesn't render as a notice in the directory preview.

Tests updated to the new contract.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4960dd7a-518c-4481-92f8-d7ff86ea39f3

📥 Commits

Reviewing files that changed from the base of the PR and between 2a62db9 and 0ec015a.

📒 Files selected for processing (2)
  • src/ui/file-preview/src/payload-utils.ts
  • test/test-markdown-preview.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/ui/file-preview/src/payload-utils.ts

📝 Walkthrough

Walkthrough

The PR makes file handlers and edit responses origin-aware for structuredContent, refactors the file-preview app to pull render payloads through RPC with timeout/watchdog handling, changes payload extraction to read joined text blocks from content[], and updates tests for the new preview contract.

Changes

Origin-aware structuredContent and preview pull

Layer / File(s) Summary
Filesystem handlers: origin-dependent responses
src/handlers/filesystem-handlers.ts
handleReadFile changes PDF, image, and text-directory responses to make structuredContent origin-dependent and metadata-only for UI calls; handleWriteFile removes structuredContent from success responses; handleListDirectory limits structuredContent to UI origin and metadata fields.
Edit tool: origin parameter and conditional metadata
src/tools/edit.ts
performSearchReplace accepts an optional origin parameter, and handleEditBlock passes parsed.origin through while making exact-match, range-edit, and text-replacement success responses include structuredContent only for UI origin.
File-preview app: RPC pull-based rendering and payload text
src/ui/file-preview/src/app.ts, src/ui/file-preview/src/payload-utils.ts
app.ts adds constrained read-argument selection, mutation-tool inference, pull-based payload fetching, preview watchdog state, and rewritten input/result handlers; payload-utils.ts now extracts render payload text only from tool content.
Tests updated for origin-aware previews
test/test-edit-block-line-endings.js, test/test-file-handlers.js, test/test-markdown-preview.js
Tests are updated to expect structuredContent to be undefined for LLM-facing calls, metadata-only for UI-origin calls, and raw text to come from content[].

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

Suggested labels: size:XL

Suggested reviewers: dmitry-ottic-ai

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title captures the main change: file previews now use widget-pulled reads, and structuredContent is being restricted to widget/UI use.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/preview-pull-by-path

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.

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/ui/file-preview/src/payload-utils.ts`:
- Around line 68-72: The PDF read payload currently drops the extracted page
text because payload building in payload-utils.ts only uses
extractToolText(value), which returns the first summary/header block. Update the
read path handling in buildRenderPayload so it preserves the later content[]
text blocks for PDF previews, either by concatenating the text blocks or
filtering out the summary header before passing text into the payload.

In `@test/test-markdown-preview.js`:
- Around line 525-540: The current unsupported-content preview test only covers
a single text block, so it misses the multi-block PDF path mentioned in
payload-utils.ts. Update testUnsupportedRawContentPreview to use a content[]
array with multiple blocks and verify extractRenderPayload still selects the
correct raw text while preserving the expected summary-first behavior. Keep the
assertions anchored on extractRenderPayload and payload.content so the test
covers the new contract, not just the simple happy path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 844c3a3b-e2cf-4aaa-9e29-fa2a5032f074

📥 Commits

Reviewing files that changed from the base of the PR and between 0ad919b and f5fa369.

📒 Files selected for processing (7)
  • src/handlers/filesystem-handlers.ts
  • src/tools/edit.ts
  • src/ui/file-preview/src/app.ts
  • src/ui/file-preview/src/payload-utils.ts
  • test/test-edit-block-line-endings.js
  • test/test-file-handlers.js
  • test/test-markdown-preview.js

Comment thread src/ui/file-preview/src/payload-utils.ts Outdated
Comment thread test/test-markdown-preview.js
edgarsskore and others added 2 commits July 3, 2026 11:23
A PDF ui-read returns a summary text block followed by per-page image/text
blocks; assert extractRenderPayload selects the first non-empty text block,
skipping whitespace-only and image blocks.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
extractRenderPayload took only the first content[] text block, which for
multi-block PDF reads is the "PDF file: ... (N pages)" summary — dropping
all extracted page text from the preview (main carried the joined page text
in structuredContent.content). Join all non-empty text blocks instead;
single-block reads are unaffected.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant