Preface

Running agents in DeepSeek Harness (DSH) typically involves two common file-related requirements: one is users providing local files to models via web chat, and the other is models needing to read PDFs, Office documents, or text files in the workspace rather than just guessing formats based on extensions. Built-in capabilities often only cover one part, requiring separate integrations for upload paths, visual images, and document parsing.

Below introduces the community plugin dsh-files. It connects the upload UI, read_document tool, and native image attachments into a single line of cordis configuration, tailored for the dsh web scenario.

What is this

dsh-files is a dual-face plugin for DeepSeek Harness maintained by taxueseek: it injects a composer upload entry on the frontend and registers the read_document tool on the backend. The current version is v0.4.0, licensed under MIT, with approximately 22 stars on GitHub.

In one sentence: this package provides session-isolated file uploads, colorful file cards, and content-sniffing reads with LRU caching for text/PDF/DOCX/XLSX files; while JPEG/PNG/WebP/GIF images are routed through the harness core attachment pipeline to models with vision capabilities.

Core Features

Upload: Three Entry Points and Session-Isolated Storage

  1. Paperclip Button: Multi-select files from the composer toolbar.
  2. Folder Button: Recursively flattens directories, preserving relative subdirectory paths.
  3. Drag-and-Drop: Drop files or folders anywhere on the page, with an overlay hint on hover.

Batch uploads default to 4 concurrent operations, and a single file failure doesn’t block other tasks. Files are written to <session-workdir>/.dsh-filess/<sessionId>/, and the agent’s fs backend can resolve them by path.

When typing @, the candidate list includes both files uploaded in the current session (absolute paths) and workspace files (relative paths), allowing references to existing workspace files without re-uploading.

Colorful cards are colored based on the real format detected by byte sniffing (PDF red / DOC blue / XLS green / TXT gray), so extension disguises won’t mislead the display. Upload responses include readHint (cost / estimatedChars), facilitating pre-read cost estimation.

For lifecycle: empty session directories are cleaned up with a default TTL of 7 days; an optional maxUploadBytesPerSession quota is available; sha256 content deduplication ensures same-named but different-content files are stored only once.

Native Images: Via the Harness Attachment Pipeline

Raster images are no longer saved as local paths for read_document to process. Instead, they go through createDraftImagesaddImagesserializeDraftImages, converting to base64 image_url at request time. Any model declaring inputModalities: [text, image] (DeepSeek Vision, Dots3, Longcat, OpenRouter Vision models, etc.) can receive them. The UI renders thumbnails and previews via the official conversation.input.attachments rail.

Document Reading: read_document Tool

Supports text, PDF, DOCX, and XLSX. Format detection is based on content sniffing, not trusting file extensions; encoding chains cover UTF-16 BOM, UTF-8, GB18030, and BOM-less UTF-16.

Long documents are paginated via offset / limit, with character budgets tiered by format (full for text, 3/4 for xlsx, 1/2 for pdf/docx, see maxOutputChars). XLSX supports a sheet parameter for reading specific sheets, and list_sheets only lists sheet names. PDFs without a text layer (scans) return a clear hint rather than an empty string.

Parsing uses an LRU cache (dual budget for entry count + bytes), with keys including content sha256, invalidating when content changes. Reading uses ctx.fs, inheriting the session sandbox; parsing relies on pdfjs-dist, mammoth, and read-excel-file, with ZIP detection without expanding members.

Security Guardrails

Upload-side validation includes loopback host + same-origin + sec-fetch-site triple checks; public or reverse-tunnel deployments can be allowed via trustedHosts (semantics align with dsh web --trusted-host). Filename sanitization, 403 for unknown sessions, 429 for concurrency limits, and early rejection of oversized request bodies.

Installation and Activation

In an environment with DSH installed, run:

dsh plugin --profile web add dsh-files
# Restart dsh web

After installation, the plugin entry must be retained in the cordis configuration (default id is upload-toolkit). When accessing via a public domain, if uploads don’t respond, check whether the deployment domain needs to be added to trustedHosts.

Common configuration example:

- id: upload-toolkit
  name: 'dsh-files'
  config:
    maxFileBytes: 25165824        # Maximum bytes per document read
    readLimit: 800                # Maximum lines returned per read
    sheetRowLimit: 200            # Rows retained per sheet
    maxSheets: 5                  # Sheets read per workbook
    cacheEntries: 16              # Parse cache entry count
    cacheMaxBytes: 67108864       # Parse cache byte budget
    maxOutputChars: 24000         # Character budget per output window
    readTimeoutMs: 120000         # read_document single execution timeout
    uploadMaxBytes: 25165824      # Maximum bytes per upload
    allowedExtensions: []         # Upload extension whitelist (empty = all allowed)
    uploadTtlMs: 604800000        # Upload file retention duration (7 days)
    maxConcurrentUploads: 4       # Concurrent upload count
    maxUploadBytesPerSession: 0   # Per-session storage quota (0 = unlimited)
    trustedHosts: []              # Additional trusted upload hosts

Typical Usage

Upload and chat: Use the paperclip, folder button, or drag-and-drop in the Web UI to add files. Once colorful cards are mounted, paths are automatically injected into the input box and sent with the message. Images are presented as native attachments, and documents are read on-demand by the model via read_document with pagination.

Reference workspace files: Type @, and select from the dual-source candidates: session-uploaded files or workspace relative paths, without re-uploading.

Read Excel: First use list_sheets to explore structure, then use the sheet parameter to read specific sheets; merged reads default to covering the first 5 sheets.

Public deployment: If the paperclip click doesn’t respond, add the actual access domain (e.g., dsh.example.com) to trustedHosts, used in conjunction with dsh web --trusted-host.

Use Cases and Considerations

Suitable for agent scenarios under dsh web that require integrated capabilities of “user upload + model document reading + visual images,” such as reviewing PDF/Word/Excel files, referencing local code or configurations, or submitting screenshots to vision models.

A few notes:

  • The plugin runs with the current dsh process permissions; before installation, it’s recommended to review the source code and MIT license to ensure the upload directory and sandbox policies align with your deployment environment.
  • Uploads do not enforce an extension whitelist by default; allowedExtensions being empty means all are allowed, with security boundaries relying on the session sandbox.
  • Large PDF parsing may be time-consuming; increase readTimeoutMs if needed; for scans without a text layer, OCR or other solutions are required, as the plugin only returns a clear hint.
  • SkillHub is an independent community directory, with no official affiliation to DeepSeek or幻方; the plugin is categorized under “Model Inference” as part of the community-maintained ecosystem.

Conclusion

dsh-files consolidates the upload, document reading, and native image pipelines into a single DSH plugin, reducing the cost of assembling UI and parsers manually. Directory page and source code:

  • SkillHub: https://www.skillhub.cn/plugins/taxueseek/dsh-files
  • GitHub: https://github.com/taxueseek/dsh-files