Skip to content

feat(artifacts): render agent HTML files inline in the session chat - #420

Merged
chriswritescode-dev merged 2 commits into
mainfrom
feat/sandboxed-html-artifacts
Oct 13, 2026
Merged

chriswritescode-dev merged 2 commits into
mainfrom
feat/sandboxed-html-artifacts

Conversation

@chriswritescode-dev

@chriswritescode-dev chriswritescode-dev commented Oct 12, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Add a show_artifact action to the ocm manager tool: the agent writes a self-contained HTML file and passes its path instead of resending the document on every fix.
  • Validate the path through a new internal resolve route scoped to the session directory (realpath containment, .html/.htm only, 5 MB cap) so a bad path fails the tool call immediately.
  • Render the artifact inline in the session chat in a sandboxed iframe through the existing raw file route, with the file path, a reload button, and an open-in-new-tab link; artifacts stay visible in simple chat mode.
  • Serve raw file responses with Cache-Control: no-cache and X-Content-Type-Options: nosniff so previews and artifacts reload the current file.

Validation

  • Backend tests: 64 passed across 3 files (files, internal-session-artifacts, opencode-manager-tool-plugin).
  • Frontend tests: 170 passed across 11 files (message components).
  • pnpm lint passed with 41 existing backend warnings.
  • Typecheck passed for shared, backend, and frontend.
  • git diff --check passed.

Summary by CodeRabbit

  • New Features
    • Added the ability to display HTML artifacts in chat, with reload and open-in-new-tab controls.
    • Added artifact path validation and file-size limits.
  • Bug Fixes
    • Improved raw file responses with content metadata, security headers, and conditional caching.
    • Corrected workspace file paths when the working directory ends with a slash.

@coderabbitai

coderabbitai Bot commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Important

Review skipped

Review was skipped as selected files did not have any reviewable changes.

⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Essentials
  • Run ID: e5e2a332-067f-4ea4-9a04-f176fcbc7fed

📥 Commits

Reviewing files that changed from the base of the PR and between 2d26338 and 5e24521.


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

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Essentials
  • Run ID: 7a5799d3-e94e-4d65-8bf4-6ba34f856f27

📥 Commits

Reviewing files that changed from the base of the PR and between fe49878 and 2d26338.


📒 Files selected for processing (24)
  • backend/src/routes/files.ts
  • backend/src/routes/opencode-proxy.ts
  • backend/src/services/files.ts
  • backend/src/services/opencode-manager-tool-plugin.ts
  • backend/src/services/sandbox/command.ts
  • backend/src/services/sandbox/shell-shim.ts
  • backend/src/services/session-artifacts.ts
  • backend/src/utils/fs-safe.ts
  • backend/test/routes/files.test.ts
  • backend/test/routes/internal-session-artifacts.test.ts
  • backend/test/services/files.test.ts
  • backend/test/services/opencode-manager-tool-plugin.test.ts
  • backend/test/services/sandbox/command.test.ts
  • frontend/src/components/message/ExplorationGroup.tsx
  • frontend/src/components/message/MessagePart.test.tsx
  • frontend/src/components/message/MessagePart.tsx
  • frontend/src/components/message/MessageThread.tsx
  • frontend/src/components/message/ToolCallPart.test.tsx
  • frontend/src/components/message/ToolCallPart.tsx
  • frontend/src/lib/artifactTool.test.ts
  • frontend/src/lib/artifactTool.ts
  • frontend/src/lib/markdownLinks.test.ts
  • frontend/src/lib/markdownLinks.ts
  • frontend/src/pages/SessionDetail.tsx

Included review availability: This review used your included allowance. 2 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 5 reviews per hour.



📝 Walkthrough
📝 Walkthrough

Walkthrough

The change adds a show_artifact manager tool action, backend path resolution for session HTML files, and frontend rendering in a sandboxed iframe. Raw-file responses now include metadata-based headers and conditional request handling.

Changes

Session artifact display

Layer / File(s) Summary
Artifact contract and path resolution
shared/src/schemas/internal-assistant.ts, backend/src/services/session-artifacts.ts, backend/src/utils/fs-safe.ts, backend/src/services/sandbox/command.ts, backend/src/services/sandbox/shell-shim.ts, backend/src/routes/internal/*, backend/src/routes/opencode-proxy.ts, backend/test/routes/internal-session-artifacts.test.ts, backend/test/services/sandbox/command.test.ts
The shared schema defines artifact parameters and limits. The internal route resolves session artifact paths, while the resolver checks path containment, file type, and size. Path-containment imports now use the shared filesystem utility.
Manager tool action
backend/src/services/opencode-manager-tool-plugin.ts, backend/test/services/opencode-manager-tool-plugin.test.ts
The manager tool adds show_artifact, sends the current session ID and path to the resolution route, and returns the resolved path in metadata. Tests cover the action schema and resolution responses.
Raw-file response metadata
backend/src/services/files.ts, backend/src/routes/files.ts, backend/test/services/files.test.ts, backend/test/routes/files.test.ts
Raw-file responses use file metadata for MIME type, content length, ETag, and Last-Modified headers. Matching If-None-Match values return 304 responses. The MIME map recognizes .htm files as HTML.
Frontend artifact rendering
frontend/src/lib/artifactTool.ts, frontend/src/components/message/ArtifactPart.tsx, frontend/src/components/message/ToolCallPart.tsx, frontend/src/components/message/MessagePart.tsx, frontend/src/components/message/MessageThread.tsx, frontend/src/components/message/ExplorationGroup.tsx, frontend/src/lib/markdownLinks.ts, frontend/src/pages/SessionDetail.tsx, frontend/src/lib/*test.ts, frontend/src/components/message/*test.tsx
The frontend recognizes completed show_artifact calls, resolves artifact URLs using session and repository paths, and displays eligible artifacts in a sandboxed iframe with reload and open-in-new-tab controls.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant ManagerTool as OpenCode manager tool
  participant InternalSessionArtifactRoute
  participant resolveSessionArtifactFile
  participant ToolCallPart
  participant ArtifactPart
  participant FilesRoute
  ManagerTool->>InternalSessionArtifactRoute: POST session ID and artifact path
  InternalSessionArtifactRoute->>resolveSessionArtifactFile: Resolve artifact file
  resolveSessionArtifactFile-->>InternalSessionArtifactRoute: Return resolved path
  InternalSessionArtifactRoute-->>ManagerTool: Return resolved path
  ManagerTool-->>ToolCallPart: Completed tool call with resolved-path metadata
  ToolCallPart->>ArtifactPart: Render artifact with raw-file URL
  ArtifactPart->>FilesRoute: Request raw file
Loading

Merge Risk: ⚪ Minimal · up to 2d263

This change adds inline rendering of agent-produced HTML artifacts in the session chat. Path scoping, the file type and size limits, and the sandboxed iframe are in place, and no actionable merge-blocking issue remains.

Pre-merge checks | Passed 4 | Failed 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 32 functions across 30 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check Passed The title clearly summarizes the main change: rendering agent HTML artifacts inline in session chat.
Description check Passed The description explains the feature and validation results. It omits the template’s “Type of Change” and “Checklist” sections, but it provides most of the required information, including tests, lint,…
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 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR

🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

@chriswritescode-dev
chriswritescode-dev force-pushed the feat/sandboxed-html-artifacts branch from fe49878 to 2d26338 Compare October 12, 2026 14:24
Chris Scott and others added 2 commits October 12, 2026 16:43
…files once

- show_artifact returns the validated path as tool metadata; the chat card
  renders from it and maps repo paths with getWorkspaceFilePath, so local
  repos and moved sessions load the right file
- serve .htm as text/html
- raw file route stats and reads once and adds ETag/Last-Modified with 304
- reuse isPathWithinRoot from utils/fs-safe
- move readShowArtifactCall to frontend/src/lib/artifactTool
@chriswritescode-dev
chriswritescode-dev force-pushed the feat/sandboxed-html-artifacts branch from 2d26338 to 5e24521 Compare October 12, 2026 20:45
@chriswritescode-dev
chriswritescode-dev merged commit 59ffe6c into main Oct 13, 2026
2 checks passed
@chriswritescode-dev
chriswritescode-dev deleted the feat/sandboxed-html-artifacts branch October 13, 2026 13:31
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