CXk253-chenxing/dsh-chunk-download

dsh-chunk-download

给 AI Agent 用的 HTTP Range 分片下载器(DeepSeek Harness 插件):多连接并发、断点续传、暂停/恢复、限速与队列,比 curl 单连接快数倍;Linux / macOS / Windows 通用,Android 可一键存进 Download。

Uncategorizedagent-toolsai-agentdeepseek-harness

分片高速下载 · dsh-chunk-download

手机上的 Agent 下载助手:多连接分片、断了能续、下完直接进「下载」目录

功能 · 为什么快 · 安装 · 用法 · 配置 · 实测 · 原理

在手机上的 DEEPSEEK_HARNESS 里让 Agent 下大文件:Range 分片并发 + 断点续传,断了接着下, 下完直接落在 Download/DeepSeekHarness;桌面端有侧边栏进度与会话标题栏胶囊。 纯 Node 实现,不用装 aria2 / curl 二进制。

适合谁

· 情况 · 说明 ✅ · 手机上让 Agent 下安装包 / 模型 / 视频 / 网盘直链 · 下完一键进「下载」,推送通知栏 ✅ · 服务端对单连接限速(网盘直链、部分 CDN、GitHub Releases) · 多连接聚合,实测约 ×2.4 ✅ · 不想装 aria2 / curl 二进制(macOS、ARM 服务器、手机容器) · 纯 Node,无原生依赖 ❌ · HLS(m3u8) / 磁力 / BT · 不支持 ❌ · 单连接已经跑满带宽 · 并行不会更快,与单线程持平(见实测) ❌ · 想要网盘分享链接解析 · 那是另一类插件,需要各平台登录态

功能

· 能力 · 说明 🚀 · Range 分片并发 · 1~64 条连接按 bytes=x-y 并行拉取,片数与分片策略见原理 ⏯ · 断点续传 · 已完成分片位图 + 分片计划签名落盘,进程重启后能接着下 ⏸ · 暂停 / 恢复 / 取消 · 运行中随时干预,暂停保留 .part,取消可连文件一起删 🧮 · 任务队列 · 同时跑 N 个任务(默认 2),其余排队;FIFO 调度 🐢 · 全局限速 + 单任务限速 · 令牌桶实现,所有连接合计不超设定速率 🛡 · 严格校验 · Content-Range 与请求必须匹配、实收字节数必须等于区间、文件大小变化即报错 🔀 · 自动回退单流 · 服务端忽略 Range(返回 200)或响应被 gzip 压缩时,自动退回单流下载,绝不写花文件 🕵️ · 停滞看门狗 · 单请求 30s 没数据即掐断重试,慢连接不拖死整个任务 📊 · 实时进度 · 桌面侧边栏 + 会话标题栏胶囊 + 浮动面板;工具侧也有进度条 / 速度 / ETA / 分片数 ✅ · SHA-256 校验 · 传 sha256,下完逐字节核对;不匹配置为失败,可选删坏文件 🗂 · 同名策略 · ifExists: overwrite / skip / rename(另存为 name (1).ext) 💽 · 磁盘预检 · 远端给了大小、本地空间不足时,开下前就拒绝 📦 · 批量下载 · 一次 urls 提交多条,逐条给出结果,一条失败不影响其余 🔔 · 完成通知 · 手机端走 3090 设备桥发通知栏消息;桌面端自动跳过 📱 · 送进手机 Download · 完成后通过 DSH 设备桥导出到 Download/DeepSeekHarness 🔁 · 同链接去重 · 同一 URL + 同一目标文件已有任务时直接复用,不重复下载 🖥 · 跨平台 · Linux / macOS / Windows,Node ≥20;纯 Node 实现,无原生依赖 🧩 · 零依赖 · 只用 Node 内置模块,不需要 npm install 任何东西

为什么快

curl 单连接      ────────────── 48MB / 380KB/s / 130s ──────────────►
chunk-download   ──┬── 1/8 ──┬── 2/8 ──┬── 3/8 ──┬ ... 8 路并行,聚合带宽
                   └─────────┴─────────┴─────────┘  同一个文件,数倍的速度
  • 分片数远多于连接数:按「每连接 8 片」给盈余片,worker 领完一片再领下一片(工作窃取),

避免某一片慢导致其他连接空转的“尾部塌缩”。

  • 单片大小自适应:按文件大小档位规划(<5MB 不分片、<50MB 8 片、<500MB 32 片、更大 64 片),

单片不小于 256KB、总数封顶 512 片 —— 既不产生海量 Range 请求,也不会因为片太大而失去并行度。

  • 失败只重试那一片:指数退避,已完成的片不重下。

安装

方式一:npm(发布后)

dsh plugin add dsh-chunk-download

方式二:本地目录 link(当前使用,推荐开发用)

DSH_HOME=/root/.dsh dsh plugin --profile web add /root/dsh-chunk-download

装完 dependencies 里是 link:/root/dsh-chunk-download、dsh.profile.bundles 自动带上包名; 改完源码重启会话即生效,不用重打包。

来源形式:本地目录 link:(与 dsh-image-gen 等社区插件的安装形态一致)。
升级只需 git pull(或改文件)后重启;要分发时再用下面的 tgz。

方式三:本地 bundle 包(tgz,适合分发)

  1. 打成 npm 风格 tgz(package/ 前缀):
npm run pack:plugin      # 生成 dsh-chunk-download-$(version).tgz
  1. 在 DEEPSEEK_HARNESS 的插件管理里安装这个 tgz,启用 chunk-download,然后开新会话。
  2. 工具列表里出现 chunk_download / chunk_download_status / chunk_download_control / chunk_download_wait 即成功。

分发流程(npm 发布 / 插件目录 PR / Release)见 docs/publishing.md。

插件会往系统提示词注入一段“下载文件优先用 chunk_download”,让 Agent 自动走这条路而不是 curl。

本地开发

git clone https://github.com/CXk253-chenxing/dsh-chunk-download.git
cd dsh-chunk-download
node --test                # 24 个用例,全部用本地 HTTP 服务器,无需外网
npm i -D react react-dom && node --test test/render.test.mjs   # 可选:把 UI 组件真渲染一遍
node bench/speedup.mjs 2   # 加速比演示

跨平台

平台 · 下载 · 导出到手机 Linux / macOS / Windows · ✅ 纯 Node,路径用 path 处理;Windows 覆盖同名文件前会先删目标 · —(无设备桥,自动跳过) Android(DEEPSEEK_HARNESS) · ✅ · ✅ 走 3090 设备桥,落 Download/DeepSeekHarness

桌面端没有设备桥时,export: true 会被跳过并在任务里记 exportError("已跳过导出;文件已保存在本地"),下载不受影响。 CI 在 Ubuntu × Node 20/22/24、macOS × 22、Windows × 22 上跑同一套测试。

界面

示意图,不是截图;深色主题下取色,浅色主题自动跟随 DSH 令牌。

装好后 DSH Web GUI 里会多出三处「安静但看得见」的进度,不用打开设置:

位置 · 表现 输入框上方整条(手机 + 桌面) · 文件名 / 进度条 / 百分比 / 速度 + 暂停、取消;点开是完整面板(手机端主要入口) 会话标题栏(手机 + 桌面) · 进度胶囊:环形进度 + 百分比 + 实时速度;多任务时显示「N 个」 桌面侧边栏底部 · 一行摘要「下载 · N 个任务」+ 迷你进度条 + 百分比 点任意一处 · 桌面右下角浮动卡片 / 手机底部抽屉:任务列表、速度、剩余时间、暂停 / 继续 / 取消 / 导出到手机、全部暂停、清理已完成

数据来自宿主注册的同源接口(GET /chunk-download/tasks,有任务时 1s 轮询、空闲降到 4s、页面隐藏时暂停; 操作走 POST /chunk-download/control)。所有颜色取 DSH 主题令牌,明暗主题自动适配;图标为内联 SVG。

用法

1. 下载一个文件

// chunk_download
{
  "url": "https://example.com/big.iso",
  "dir": "/root/Downloads",   // 可选,默认 ~/Downloads
  "filename": "big.iso",      // 可选,默认取 Content-Disposition / URL 末段
  "connections": 16,          // 可选,1~64,默认 8
  "sha256": "74bb0f3a…",      // 可选,下完校验摘要
  "ifExists": "rename",       // 可选,同名文件:overwrite / skip / rename
  "export": true,             // 可选,下完送进手机 Download/DeepSeekHarness
  "waitMs": 60000             // 可选,阻塞等它下完(否则立即返回任务 id)
}

2. 跟进进度

// chunk_download_status(给 id 看单个,不给看全部 + 汇总)
{ "id": "dl_mvm1kptj_281a40" }

返回里带进度条、速度、ETA、分片完成数:

任务 dl_xxx  ▶ 下载中
  文件   /root/Downloads/node.tar.gz
  进度   93.2% ███████████████████░  45.0 MB / 48.3 MB
  速度   6.4 MB/s · 剩余 10s
  分片   111/128 片完成 · 16 连接并发

3. 干预与收尾

{ "id": "dl_xxx", "action": "pause" }                        // 暂停(保留 .part)
{ "id": "dl_xxx", "action": "resume" }                       // 恢复续传
{ "id": "dl_xxx", "action": "cancel", "deleteFile": true }    // 取消并删 .part
{ "id": "dl_xxx", "action": "export" }                        // 完成后送进手机
{ "id": "dl_xxx", "action": "remove", "deleteFile": true }    // 删任务记录(可连文件)

4. 阻塞等待

// chunk_download_wait
{ "id": "dl_xxx", "timeoutMs": 120000 }

5. 批量下载

// chunk_download
{
  "urls": [
    "https://example.com/a.zip",
    "https://example.com/b.zip"
  ],
  "dir": "/root/Downloads",
  "connections": 8
}

一次最多 20 条;逐条返回结果,某条失败不影响其余。

网盘直链(需要带识别头)

{
  "url": "https://cdn.example.com/file.zip",
  "headers": {
    "referer": "https://pan.quark.cn/",
    "cookie": "你的登录态"
  },
  "connections": 16
}
直链通常对 Referer / Cookie / UA 敏感,缺了会 403;本插件只负责“更快地下”,不负责解析分享链接。

配置

cordis.patch.yml 里的 config(也可在插件管理里改):

键 · 默认 · 说明 dir · ~/Downloads · 默认下载目录 connections · 8 · 单任务默认并发连接数(1~64) maxConcurrentTasks · 2 · 同时运行的任务数,其余排队 speedLimit · 0 · 全局限速(字节/秒),0 = 不限 exportToPhone · false · true 时所有任务完成后自动导出到手机(桌面端自动跳过) autoResume · true · 进程重启后自动续传未完成任务 retries · 4 · 单分片重试次数 requestTimeoutMs · 20000 · 探测 / 建连超时 stallTimeoutMs · 30000 · 单请求停滞多久判定死连接 notifyOnComplete · true · 下载完成后发手机通知(桌面端自动跳过) stateDir · $DSH_HOME/chunk-download · 任务状态目录(续传依赖它) promptSection · true · 是否注入“下载优先用本插件”的系统提示

实测

2026-10-25 实测,家庭宽带 + 境内 CDN,同一文件、同一时段逐项对比。
之后没有复测(作者换了限速流量卡,再测没有参考价值)——把这张表当历史数据,不要当承诺。

场景 · 单连接 · 本插件 · 差距 2MB,本地服务器把单连接限速 256KB/s,8 连接(node bench/speedup.mjs 2,可复现) · 8.34s(0.24 MB/s) · 1.32s(1.51 MB/s) · 6.3× 44.98MB 真实 CDN(npmmirror),8 连接,CDN 不限流时 · 4.5–5.8s(7.4–9.5 MB/s) · 2.1–2.3s(18–21 MB/s) · 约 2.4× 同上,CDN 进入按 IP 限流时段 · 8–9s(≈5 MB/s) · 8–9s · ≈1×(限流按 IP 算,加连接无效)

怎么读这张表:加速比只由服务端决定 ——

  • 单连接被限速(网盘直链、部分 CDN、GitHub Releases)⇒ 收益最大,数倍;
  • 单连接已经跑满线路带宽,或 CDN 按 IP 限流 ⇒ 并行不会更快,此时与单线程打平,不会更慢。

其它实测结论:

  • 16 连接在 npmmirror 上反而容易触发限流(复测中出现过一次 31s 才下完,8 连接同文件 2.1s),这类 CDN 建议 8 连接;
  • 内容校验:下载 48.3MB 的 Node 发行包,SHA-256 与官方 SHASUMS256.txt 完全一致;
  • export: true 时手机 Download/DeepSeekHarness 里能直接看到成品。

工作原理

完整细节见 docs/how-it-works.md,要点:

  1. Range: bytes=0-0 探测总长度(校验 Content-Range),拿不到就 HEAD 兜底;
  2. 按文件大小与连接数规划分片数,单片 ≥256KB、总数 ≤512 片;
  3. N 个 worker 从共享队列领取分片,定位写入同一个文件(fs.write(buffer, pos));
  4. 每片严格校验 Content-Range 与实收字节数,不符即重试;
  5. 已完成分片索引 + 计划签名落盘,续传时跳过已完成片;
  6. 服务端返回 200 或响应被压缩 ⇒ 放弃分片,回退单流。

同类项目

同类插件已经存在,按需选择:

项目 · 特点 · 什么时候选它 @leisureyu/dsh-smart-dl · 内置 aria2,校验 / 批量 / 磁盘预检 / 进度面板,下载量最大 · 桌面端,想直接复用 aria2 引擎 dlx-downloader · 分片 curl 引擎 + 侧栏面板 + 镜像故障转移 · 需要镜像自动重试 dsh-downloader · 下载代理(自带节点),解决「连不上」 · 境外链路被墙 本项目 · 纯 Node 无二进制、1–64 连接、手机导出 + 通知、严格校验 · 手机端 / ARM / 不想装外部依赖

与 YunX 的关系

分片策略、校验规则、限速与测速思路参考了开源项目 YunX(云析) 的 Android 下载内核(Kotlin):片数 = max(档位, 连接数×8)、 单片 ≥256KB、封顶 512 片、Content-Range 严格匹配、忽略 Range 时回退单流等。

本仓库是 Node 版本的重新实现:把「part_N 临时分片 + 合并」换成「直接定位写最终文件」,省掉一次全量磁盘合并; 语言、运行时、并发模型都不同。但实现思路与分片参数来自 YunX,因此本项目同样以 AGPL-3.0-or-later 发布, 与上游保持一致;二次分发或提供网络服务时请遵守同一协议。感谢原项目的开源。

目录结构

dsh-chunk-download/
├── index.js                 # 插件入口:注册 4 个工具 + 系统提示 + 进度接口
├── client.js                # 浏览器半身:侧边栏 / 标题栏 / 浮动面板
├── assets/ui-mock.svg       # 界面示意图(README 用)
├── lib/engine.js            # 下载内核(探测/分片/并发/续传/限速/队列/持久化)
├── lib/format.js            # 进度条与人类可读文案
├── cordis.patch.yml         # 插件层挂载配置
├── locale/{zh,en}.json      # 插件管理里显示的名称与简介
├── icon.svg
├── docs/how-it-works.md     # 原理、分片规划、协议校验细节
├── docs/publishing.md       # npm 发布 / 插件目录 PR / Release 流程
├── docs/catalog-entry.yml   # awesome-dsh-plugin 目录条目(可直接提 PR)
├── test/                    # node --test:引擎 + 插件层端到端
├── bench/speedup.mjs        # 加速比演示
└── .github/workflows/ci.yml # CI:node 20 / 22 / 24 跑测试

已知限制

  • 只做直链下载,不解析网盘分享链接(那需要各平台登录态与逆向,风险与合规成本都不适合放进插件);
  • 不支持 HLS(m3u8) / DASH / 磁力 / BT;
  • 服务端不支持 Range 时只能单流(无法续传);
  • 连接数过高可能撞上 CDN 对单 IP 的连接数限制(429 / 连接重置),此时调低 connections。