🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

模型故障转移层 SISCHOI/daruma

DeepSeek Harnessv0.2.1
SISCHOI12 天前有提交已提供中文文档扫描:含敏感能力

Daruma 是 DeepSeek HarnessDSH的一个韧性层。它只为一件事存在:第三方订阅 API…

51.1/100
综合分
61
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/30 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

自动兼容检查未通过:缺少 main/exports/bin 入口声明;仓库 package.json 标记 private,未发布到 npm,需从源码安装。以下命令仍可尝试,但可能失败。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add SISCHOI/daruma
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
dsh 原生插件 · other
装得上吗
本站已在 dsh 0.2.1-rc.5 下真实安装成功
非静态推断
L5 · 运行时冒烟等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 12 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查需源码安装

缺少 main/exports/bin 入口声明;仓库 package.json 标记 private,未发布到 npm,需从源码安装

展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✓npm 包daruma @ 0.2.1
✓Node 引擎要求 >=22.0.0 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✗入口文件缺少入口声明

源码安装时若 pnpm 拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑。

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/30 09:04:48

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件发起外部网络请求
查看扫描证据(共 41 处,展示前 41 条)
  • 删除本地文件递归
    packages/dsh-daruma/src/failover-log.test.ts:17
    rmSync(dir, { recursive: true, force: true })
  • 读取本地文件
    packages/dsh-daruma/src/failover-log.test.ts:42
    const lines = readFileSync(file, 'utf8').trim().split('\n')
  • 写入本地文件
    packages/dsh-daruma/src/failover-log.test.ts:63
    writeFileSync(file, 'x'.repeat(FAILOVER_LOG_ROTATE_BYTES), 'utf8')
  • 读取本地文件
    packages/dsh-daruma/src/failover-log.test.ts:69
    expect(readFileSync(`${file}.1`, 'utf8')).toBe('x'.repeat(FAILOVER_LOG_ROTATE_BYTES))
  • 读取本地文件
    packages/dsh-daruma/src/failover-log.test.ts:70
    const lines = readFileSync(file, 'utf8').trim().split('\n')
  • 写入本地文件
    packages/dsh-daruma/src/failover-log.test.ts:78
    writeFileSync(file, 'x'.repeat(10), 'utf8')
  • 读取本地文件
    packages/dsh-daruma/src/failover-log.test.ts:83
    expect(statSync(file).size).toBeGreaterThan(10)
  • 写入本地文件
    packages/dsh-daruma/src/failover-log.test.ts:90
    writeFileSync(blocker, 'not a dir', 'utf8')
  • 写入本地文件
    packages/dsh-daruma/src/failover-log.ts:82
    mkdirSync(dirname(this.file), { recursive: true })
  • 写入本地文件
    packages/dsh-daruma/src/failover-log.ts:83
    appendFileSync(this.file, `${JSON.stringify(record)}\n`, 'utf8')
  • 读取本地文件
    packages/dsh-daruma/src/failover-log.ts:91
    if (statSync(this.file).size < FAILOVER_LOG_ROTATE_BYTES) return
  • 写入本地文件
    packages/dsh-daruma/src/failover-log.ts:92
    renameSync(this.file, `${this.file}.1`)
  • 发起网络请求
    packages/dsh-daruma/src/http-transport.test.ts:42
    fetch(request: unknown): Promise<unknown>
  • 发起网络请求
    packages/dsh-daruma/src/http-transport.test.ts:140
    const response = await firstRoute(routes).fetch(
  • 发起网络请求
    packages/dsh-daruma/src/http-transport.test.ts:165
    const response = await firstRoute(routes).fetch(
  • 发起网络请求
    packages/dsh-daruma/src/http-transport.test.ts:184
    const response = await firstRoute(routes).fetch(
  • 发起网络请求
    packages/dsh-daruma/src/http-transport.test.ts:260
    const response = await firstRoute(routes).fetch(
  • 发起网络请求
    packages/dsh-daruma/src/http-transport.ts:37
    fetch(request: unknown): Promise<unknown>
  • 发起网络请求
    packages/dsh-daruma/src/http-transport.ts:150
    async fetch(request: unknown) {
  • 删除本地文件递归
    packages/dsh-daruma/src/index.test.ts:131
    for (const dir of dirs) rmSync(dir, { recursive: true, force: true })
  • 读取本地文件
    packages/dsh-daruma/src/index.test.ts:237
    const lines = readFileSync(join(h.dir, 'failover-log.jsonl'), 'utf8').trim().split('\n')
  • 读取本地文件
    packages/dsh-daruma/src/status.ts:113
    if (!existsSync(file) || !statSync(file).isFile()) return
  • 读取本地文件
    packages/dsh-daruma/src/status.ts:113
    if (!existsSync(file) || !statSync(file).isFile()) return
  • 读取本地文件
    packages/dsh-daruma/src/status.ts:114
    const raw = JSON.parse(readFileSync(file, 'utf8')) as { backup?: unknown }
  • 写入本地文件
    packages/dsh-daruma/src/status.ts:122
    mkdirSync(dirname(file), { recursive: true })
  • 写入本地文件
    packages/dsh-daruma/src/status.ts:125
    writeFileSync(temporary, serialized, { mode: 0o600 })
  • 写入本地文件
    packages/dsh-daruma/src/status.ts:127
    renameSync(temporary, file)
  • 写入本地文件
    packages/dsh-daruma/src/status.ts:129
    writeFileSync(file, serialized, { mode: 0o600 })
  • 删除本地文件
    packages/dsh-daruma/src/status.ts:130
    try { unlinkSync(temporary) } catch { }
  • 写入本地文件
    packages/dsh-daruma/src/status.ts:132
    try { chmodSync(file, 0o600) } catch { }
  • 删除本地文件递归
    packages/dsh-daruma/src/store.test.ts:10
    for (const dir of tempDirs.splice(0)) rmSync(dir, { recursive: true, force: true })
  • 写入本地文件
    packages/dsh-daruma/src/store.test.ts:18
    writeFileSync(file, JSON.stringify({
  • 读取本地文件
    packages/dsh-daruma/src/store.ts:36
    if (!existsSync(this.file)) return
  • 读取本地文件
    packages/dsh-daruma/src/store.ts:37
    if (!statSync(this.file).isFile()) return
  • 读取本地文件
    packages/dsh-daruma/src/store.ts:38
    const raw = JSON.parse(readFileSync(this.file, 'utf8')) as StoredState
  • 写入本地文件
    packages/dsh-daruma/src/store.ts:60
    mkdirSync(dirname(this.file), { recursive: true })
  • 写入本地文件
    packages/dsh-daruma/src/store.ts:65
    writeFileSync(temporary, serialized, { mode: 0o600 })
  • 写入本地文件
    packages/dsh-daruma/src/store.ts:67
    renameSync(temporary, this.file)
  • 写入本地文件
    packages/dsh-daruma/src/store.ts:71
    writeFileSync(this.file, serialized, { mode: 0o600 })
  • 删除本地文件
    packages/dsh-daruma/src/store.ts:72
    try { unlinkSync(temporary) } catch { }
  • 写入本地文件
    packages/dsh-daruma/src/store.ts:74
    chmodSync(this.file, 0o600)
扫描于 2026/11/2(1 天前) · 范围 全包扫描 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

README

由 DeepSeek 最新模型翻译生成
daruma 七転八起,跌而不倒。 Daruma 是 DeepSeek Harness(DSH)的一个韧性层。它只为一件事存在:第三方订阅 API 会抽风。限流(429)、服务端错误(500)、网络抖动、模型抽风、风控拦截——其中任何一个都能把长任务掐断在半路。Daruma 捕捉到失败,切换到另一个模型/渠道,让会话替你继续跑下去。 工作原理 Daruma 落在 DSH 的两个原生扩展点上: | 机制 | 负责方 | 作用 | | 重试 | 内建 dsh-llm-retry | 同渠道,有界的指数退避 | | 换渠道 | dsh-daruma | 重试放弃后,或遇到终态错误(QUOTA / INVALID_CREDENTIAL / CONTEXT_WINDOW_EXCEEDED)时,切到下一个渠道 | 决策引擎是纯函数:同样的失败历史 + 同样的渠道状态 → 同样的恢复计划。确定性、可测试、无 I/O。
展开完整文档(README 剩余 1 节)
daruma

七転八起,跌而不倒。

Daruma 是 DeepSeek Harness(DSH)的一个韧性层。它只为一件事存在:第三方订阅 API 会抽风。限流(429)、服务端错误(500)、网络抖动、模型抽风、风控拦截——其中任何一个都能把长任务掐断在半路。Daruma 捕捉到失败,切换到另一个模型/渠道,让会话替你继续跑下去。

工作原理

Daruma 落在 DSH 的两个原生扩展点上:

| 机制 | 负责方 | 作用 |
| 重试 | 内建 dsh-llm-retry | 同渠道,有界的指数退避 |
| 换渠道 | dsh-daruma | 重试放弃后,或遇到终态错误(QUOTA / INVALID_CREDENTIAL / CONTEXT_WINDOW_EXCEEDED)时,切到下一个渠道 |

决策引擎是纯函数:同样的失败历史 + 同样的渠道状态 → 同样的恢复计划。确定性、可测试、无 I/O。

包结构

| 包 | 职责 |
| dsh-daruma | DSH 插件——挂 agent/request-error + agent/request,进程内换渠道 |
| daruma-core | 纯域层——故障分类、熔断状态机、恢复决策引擎 |

快速开始

本地开发(link 工作区里的包)
dsh plugin --profile web add link:./packages/daruma-core link:./packages/dsh-daruma

发布之后:
dsh plugin --profile web add dsh-daruma

在 profile 的 cordis.patch.yml 里配置渠道链:

- id: dsh-daruma
name: dsh-daruma
config:
channels:
- { provider: mt, model: deepseek-v4-pro }
- { provider: mt, model: glm-5.2 }
failureBudget: 3
cooldownMs: 30000
giveUpBudget: 8 # 每个 agent 的故障转移预算

当 deepseek-v4-pro 开始回 429,daruma 熔断它、改用 glm-5.2 继续。渠道健康状态落到 ~/.dsh/daruma/channel-health.json,被熔断的渠道在重启后依然保持冷却;成功请求会自动闭合断路器(由下一个 agent/pre-step 推断)。每次切换/放弃决策同时追加到 ~/.dsh/daruma/failover-log.jsonl,可事后审计。

为什么叫 daruma

达摩不倒翁 源自一句谚语——七転八起(跌七次,起八次)。你的长任务也一样:被 429 击中,再爬起来。

当前状态

支持 DSH 0.2.1 版本线,已在 0.2.1-rc.2 上实测。 2026-10-20 使用 dsh-daruma 0.1.9 验证:自动切换 7/7、指定备用渠道 7/7、备用管理 RPC 12/12;139 项单测、类型检查与构建通过。验证时尚无 0.2.1 正式版。浏览器渲染未检查;会话内切换/放弃提示仍使用旧聊天事件注册入口,在该版本上可能缺失,不影响已实测的故障转移与备用管理接口。见 0.2.1 验证报告。

已实现并测试:139 个单测(daruma-core 35 + dsh-daruma 104),外加端到端换渠道实测(主渠道 mock 429 → 自动切换 → 任务完成)。见 docs/e2e-test.md 与 docs/research.md。

跨平台:Windows / Linux / macOS 均支持;CI 在三个系统上跑 typecheck、lint、单测、构建与 BOM 守卫,故障转移 e2e 在 Linux 与 macOS 实跑;本机 WSL 2(Ubuntu 24.04)另做了一遍全流程实测。

WSL 提醒:WSL 会追加 Windows 的 PATH,裸 dsh 可能命中 /mnt/c/... 下的 Windows 安装(用 Linux 的 node 加载它的 sharp/koffi 必然失败)。e2e:failover 会在启动前拒绝 /mnt/ 宿主并给出修复命令;请在发行版内装宿主:npm install --global @deepseek-ai/dsh@0.1.0-rc.7 && export PATH="$(npm prefix --global)/bin:$PATH"。

已发布到 npm:dsh-daruma / daruma-core。

开发

pnpm install
pnpm build
pnpm test
pnpm run start:test # mock LLM + daruma-test web profile(任何系统,Ctrl+C 一起停)
pnpm run e2e:failover # headless 故障转移验证(临时 DSH home,不碰 ~/.dsh)

License

MIT © 2026 SISCHOI
预览分享卡片长什么样 ↓SISCHOI/daruma
分享 · DeepSeek Harness Hub
SISCHOI/daruma

Daruma 是 DeepSeek HarnessDSH的一个韧性层。它只为一件事存在:第三方订阅 API…

回到顶部