DSH Hub

GLFzr/dsh-file-upload

dsh-file-upload

UIWeb UI8 GitHub stars· updated 2026-08-16

dsh-file-upload is a community DeepSeek Harness plugin. Read the repository README before installing.

Install

npx @deepseek-ai/dsh plugin --profile web add ./plugins/file-upload

Restart `dsh web` after install. Bundle APIs can change during the developer preview.

README badge

dsh-file-upload DSH Hub badge
[![DSH Hub](https://dshhub.dev/badge/glfzr-dsh-file-upload.svg)](https://dshhub.dev/plugins/glfzr-dsh-file-upload)

Paste this into your README. The star count updates with every catalog sync.

From the README

Excerpt from GLFzr/dsh-file-upload, cleaned of badges and images.

DSH 文件上传插件(File Upload)v2.1.0

把 DSH Web GUI 原版只支持图片的附件通道,扩展为任意文件上传:拖入任意文件(PDF、3MF、ZIP、Excel、代码、图片……)→ 文件上传/引用到本机中转目录 → 输入框出现一个蓝色文件 chip → agent 可以直接读取该文件。

定位说明(v2.0.0 起):本插件的本质是文件上传功能,不是"路径展示"。路径只是内部机制——agent 读取文件必须依赖磁盘路径,浏览器又拿不到(见下文"为什么必须上传"),所以插件负责把文件物化到本机、并把路径交给 agent。用户界面不再出现任何路径概念:chip 只显示文件名,用户只需知道"文件上传好了,agent 能读了"。

本仓库是持久化 profile 插件dsh.bundle + dsh.client 双声明):按官方方式安装一次,DSH 重启后自动生效

功能特性

  • 🖱️ 页面任意位置拖入任意文件(多文件、图片均可);拖拽时全屏提示"松开以接收文件"
  • 📦 任意文件类型:原版"仅图片"附件通道被完全静默接管,任何文件都可拖入
  • 📍 本机文件零上传直引:Chromium(Edge/Chrome)拖拽会经 entry API 暴露源文件路径——直接引用,零上传、零复制(你电脑里那份文件就是唯一的一份);仅当浏览器拿不到路径(如 Firefox)时才走上传中转
  • 🔵 文件以一个整体 chip 插入输入框:蓝色文字(只显示文件名+格式)、不可被局部删改(Backspace/Delete 一次删除整个引用)
  • 📐 篮筐宽度随文件名自适应:插入时用 composer 真实字体实测文件名宽度,pill 精确贴合(误差 <1 个字符)
  • 🙈 内部细节全部隐藏.b64 后缀、_1/_2 重名序号、中转目录路径——用户界面永远看不到;提交给 agent 的才是完整真实路径
  • ♻️ 两级去重(先查后传,防误复用)begin 快路径命中条件 = 同名 + 同大小 + manifest 登记的源文件修改时间与本次拖入一致——重复拖同一文件仍秒回(零上传);但编辑过且字节数没变的文件绝不误复用(v2.1.0 起,新/旧文件首次拖入都先完整上传,由 end 的 sha256 逐字节比对裁决:内容相同复用旧路径,内容不同落 _1 副本)
  • 📇 中转目录清单(manifest):插件把每个自己写入的文件登记到 ~/.dsh-dropbox/.dsh-manifest.json(原名、源修改时间、sha256、是否自动编号副本)——清理面板的"冗余副本"标记只认清单,不会把 notes_2024.txt 这类自然命名误判为副本(v2.1.0 起)
  • 🧹 失败即清理:上传任一步失败,客户端立即调用 abort 释放宿主会话,不再滞留内存到超时(v2.1.0 起)
  • 🛡️ 完整性校验:每块精确长度校验、分块必须齐全、解码后字节数必须与声明一致——截断/缺块/伪造数据一律拒绝,绝不落盘损坏文件
  • 插入点待机圆环:上传真正需要等待时,在文件将要出现的位置(光标右侧一个字符处)显示 DeepSeek 蓝色转圈环(渐隐拖尾、持续转动);瞬间完成的路径(本机直引、秒回去重、极小文件)不出圈;chip 插入的同一瞬间圆环立即消失
  • 🚀 ~4MB 分块上传,上限 512MB;请求体上限 16MB/次;失败右下角红色提示 4 秒
  • 🗑️ 侧边栏垃圾桶图标(设置图标上方):打开上传目录清理浮层——文件清单、一键清理冗余 _N 副本、按大小清理、清空全部,操作前确认,避免中转目录无限膨胀

为什么必须上传/中转?(浏览器限制)

这是 WebUI 与 Hermes/Codex 之类本地 CLI 的本质区别,不是本插件的缺陷:

  • 浏览器是沙盒:网页里的 JavaScript 拿不到本地文件的磁盘路径(安全模型,防止网页偷读你的磁盘)。Hermes/Codex 直接跑在你的电脑上,可以随便读 C:\...\xxx.pdf;DSH 的 Web GUI 是一个浏览器网页,它手里的文件只是一个内存 File 对象
  • agent 只能读磁盘路径:agent 读取文件靠的是磁盘路径。浏览器无法把一个内存文件"变成"磁盘路径交给 agent,所以插件必须先把文件物化到本机中转目录(默认 ~/.dsh-dropbox),agent 才能访问。
  • 唯一的例外(零上传):Chromium 系浏览器(Edge/Chrome)拖拽本机文件时,DataTransferItem.webkitGetAsEntry() 能探测到源文件路径——此时插件直接引用原路径,零上传、零复制。Firefox、或从非本机来源(网页、压缩包内)拖拽时拿不到路径,才必须走上传兜底。
  • 大文件的代价:新文件第一次拖入必须完整上传(几百 MB 也要传),这是浏览器限制决定的。为了把重复成本降到零,插件做了两级去重(见工作原理)。

上传目录清理

中转目录会随着使用积累文件(尤其大文件)。侧边栏底部、设置图标上方的垃圾桶图标(悬停显示"清理上传目录")打开清理浮层:

  • 文件清单:名称、大小、修改时间;冗余副本自动标注——v2.1.0 起只认插件清单(.dsh-manifest.json)里登记的自动编号副本,自然命名文件(如 notes_2024.txt)绝不会被误标
  • 清理冗余副本:一键删除所有清单登记的 _N 副本(推荐——你的电脑里已有原文件,这些副本是纯浪费)
  • 按大小清理:输入阈值(MB),删除大于该值的文件
  • 清空全部:删除中转目录里所有文件(高危,二次确认)
  • 任何操作前都会显示"将删除 N 个文件、释放 X",并提示历史会话引用的文件会失效——清理前请确认没有正在使用的会话

.b64 是什么?(内部细节,用户无需关心)

浏览器无法保证任意二进制文件的原始字节能无损地穿越 JSON/文本通道,所以回退上传的二进制文件(PDF、3MF、ZIP、图片等)落盘时以 base64 文本保存,文件名追加 .b64 作为标记——agent 看到 .b64 就知道要先解码再使用:

import base64
with open('xxx.pdf.b64') as f: raw = base64.b64decode(f.read())
with open('xxx.pdf', 'wb') as f: f.write(raw)

文本类文件(.md/.txt/.json 等)直接写原文,不会.b64本机文件走原路径引用时不经过中转目录,天然没有 .b64。所有这些都是内部机制——输入框里的 chip 只显示文件名,提交给 agent 的才是完整真实路径。

安装(官方方式,一次永久)

# 在 deepseek-harness 仓库根目录(源码版):
pnpm dsh plugin --profile web add ./plugins/file-upload

# 或任意 dsh 安装(npx 版亦可):
dsh plugin --profile web add <本仓库路径>

dsh plugin 会 pnpm link 本包到 $DSH_HOME/profiles/web 并追加 dsh.profile.bundles。之后无论用 npx 版还是源码版启动 DSH,插件都自动加载

验证:dsh web --dump-config 应出现 # == dsh-file-upload 层。

Related plugins