Introduction¶
If you have used DeepSeek Harness (dsh) for agent development, you have likely encountered scenarios like this: the model generates an image in the session, exports a CSV, and then tells you “files are in the output/ directory” or pastes a file:///... link. The files have indeed been delivered, but if the user wants to see the content, they still have to navigate directories on the host machine and open a local preview.
dsh-rich-artifacts solves this step. It is a DSH plugin maintained by Inkotake that wraps workspace files into “chat Artifacts”: raster images are rendered inline directly in the session, while other files become file cards with download buttons. When the model creates user-facing delivery files, simply calling the publish_artifact tool completes the publishing.
What is This¶
One-sentence positioning: A DSH dual-face plugin that publishes workspace files as chat Artifacts, featuring inline image previews and download cards.
Basic information:
- Plugin name:
dsh-rich-artifacts, Author: Inkotake, Version: 0.1.0 - License: MIT
- Repository: https://github.com/Inkotake/dsh-rich-artifacts
- Directory page: https://www.skillhub.cn/plugins/Inkotake/dsh-rich-artifacts
The philosophy of DSH is “everything is a plugin”. This plugin follows the standard plugin path: the host side registers tools and session events, and the browser side injects UI. It is worth noting that skillhub.cn is an independent community plugin directory and has no official affiliation with DeepSeek or Fangfang.
Core Features¶
publish_artifact Tool¶
The plugin exposes a publish_artifact tool to the model with three parameters:
path(required): The path to the workspace file to publishtitle(optional): The display titledisplay:auto(default) /inline/download
In auto mode, PNG/JPEG/WebP/GIF are rendered inline, while other files generate download cards; you can also explicitly specify the presentation mode via inline or download.
ArtifactStore: Content-Addressable Storage¶
Published files enter ArtifactStore, adopting SHA-256 content-addressable blob storage, with metadata stored separately in ~/.dsh/artifacts/v1/. The storage root directory and various size limits can be adjusted via configuration, which will be covered later.
Persistent Session Events¶
The plugin registers a persistent session event artifact/published. The design ensures that only artifact metadata enters the session log, not the blob itself. This ensures that historical sessions remain fully displayable after reload/fork.
There is an implementation detail worth noting: artifact/published is a log-only event, and the current harness does not provide a registration entry for session events outside the repository. Therefore, the host adds this event to KNOWN_SESSION_EVENT_TYPES during startup to ensure that sessions that have already been persisted during plugin installation can still be loaded.
HTTP Endpoints¶
The plugin provides two endpoints:
GET /api/artifacts/:id/content— inline-safe previewGET /api/artifacts/:id/download— attachment download
Web UI Rendering¶
The browser renders a gallery at the tail of each turn (turn-tail): PNG/JPEG/WebP/GIF are displayed inline, and other files are displayed as file cards with download buttons.
Security Mechanisms¶
Publishing files involves file system access and network exposure, so the plugin implements several layers of restrictions:
- Workspace restriction: Ensures only files within the workspace can be published via
fs.resolve+fs.contains - Symlink rejection
- Magic number MIME sniffing: MIME types are determined primarily by file content, with the extension serving as a secondary hint. An HTML file disguised as
.pngwill not be rendered inline - In V0.1, SVG/HTML are only supported for download, not inline
- File size, image size, and pixel limits
Installation and Activation¶
Official install command:
dsh plugin --profile web add github:Inkotake/dsh-rich-artifacts
If you need to lock to a specific commit for a reproducible source install:
dsh plugin --profile web add github:Inkotake/dsh-rich-artifacts#<commit>
After installation, restart dsh web (or the profile you used) for it to take effect.
lib/index.js in the repository is the ESM host plugin, and lib/client.js is the browser bundle. Both have been committed, so source install requires no extra build steps. If you wish to build it yourself, the repository has a workflow of pnpm install && pnpm run build, and tests can be run with node tests/artifact-store.test.mjs.
Typical Usage¶
The plugin registers a system-prompt section, so the model will call the tool itself when creating delivery files. You can also directly request in the conversation:
Create a training-loss chart, export it to CSV, and publish both files as artifacts.
The model will then execute:
publish_artifact({ "path": "output/loss.png", "display": "auto" })
publish_artifact({ "path": "output/loss.csv" })
After this round of execution, the loss curve will be displayed inline at the tail of the conversation, accompanied by a CSV download card. You can see both types of deliverables at once without the user having to hunt in the file system.
Configuration¶
The plugin configuration is written in the profile’s cordis.patch.yml:
- id: dsh-rich-artifacts
name: dsh-rich-artifacts
config:
root: ~/.dsh/artifacts
maxFileBytes: 104857600
maxTurnBytes: 524288000
maxImageBytes: 20971520
maxImagePixels: 40000000
inline:
png: true
jpeg: true
webp: true
gif: true
svg: false
Field meanings and defaults:
| Field | Default | Meaning |
|---|---|---|
root |
~/.dsh/artifacts |
Artifact storage root directory |
maxFileBytes |
104857600 |
Single file size limit |
maxTurnBytes |
524288000 |
Per-turn limit (not yet enforced in V0.1, reserved) |
maxImageBytes |
20971520 |
Inline image size limit |
maxImagePixels |
40000000 |
Inline image pixel limit (best-effort parsing) |
inline.* |
png/jpeg/webp/gif: true, svg: false |
Which image types can be rendered inline |
Suitable Scenarios and Notes¶
Suitable scenarios: Workflows where agents need to deliver visualization outputs (training curves, charts, screenshots) or data files (CSV, JSON) to users. Any scenario where “the model produces a file and the user needs to see the content” can have the delivery process brought into the chat interface via this plugin.
Points to note before use:
- The plugin runs with the permissions of the current dsh process and can access the file system resources accessible to that process. It is recommended to check the source code and license before installation to ensure it meets your security requirements. The license is MIT.
maxTurnBytesis a reserved config in V0.1 and not yet enforced; do not rely on it for volume control per turn.- SVG and HTML in V0.1 only provide download, no inline rendering; this is an intentional design choice, and scenarios involving HTML/SVG delivery should be aware of this.
- MIME determination prioritizes magic numbers, with the extension serving as a secondary hint. Inline safety policies take precedence when the file extension does not match the actual content.
Conclusion¶
dsh-rich-artifacts does something simple: turns “files are in the workspace” into “files are in the conversation”. Storage uses content-addressing for traceability, session events store only metadata for replayability, and together with workspace restrictions and magic number sniffing, it tightens the opening for publishing. If your DSH workflow frequently produces charts and data files, it is worth installing and trying.
- Directory page: https://www.skillhub.cn/plugins/Inkotake/dsh-rich-artifacts
- GitHub: https://github.com/Inkotake/dsh-rich-artifacts