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 publish
  • title (optional): The display title
  • display: 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 preview
  • GET /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 .png will 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.
  • maxTurnBytes is 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