npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

dsh-tool-normalizer

v0.5.2

Published

Auto-healing, argument normalization, Code-Mode bridging and execution diagnostics for DeepSeek Harness

Readme

dsh-tool-normalizer (中文文档)

dsh-plugin License: MIT npm version

模型工具调用自愈层:把过去每次都要完整重试一轮的调用失败静默修好,并给你看修复的证据。

English Documentation (README.md)

工具自愈看板:自愈成功率 97.7%、自愈 837 次、节省 Token 153.3M

为什么开发这个插件

每次工具调用失败都要完整重试一轮:报错返回、模型把整段对话上下文重读一遍、再试一次。在大工作区里,一次重试就要重传约 18 万 input token —— 约 5% 的工具失败率,会让相关轮次的 token 开销悄悄翻倍还多,Agent 每隔几分钟就 visible 地卡一下。

本插件挂在 tools/execute 流水线上,在失败到达模型之前把它修好:缺 description 就补上,忘读文件就代读一次并重试编辑,相对路径就解析,修不好的错误就追加一条可操作的提示。在 192 个真实会话(15,460 次工具调用)中实测:

  • 表面错误率从 7.95% 降到 2.20%(可见失败减少约 72%)。
  • 本会发生的错误中约 82% 被自动修复(837 次自愈 vs 182 次残留)。
  • 每次自愈省掉一次全量上下文重传(中位数约 16 万 input token),累计节省 约 153M token —— 约为同期模型实际消耗(133M)的 115%,即没有自愈的话 token 开销约为现在的 2.2 倍(估算口径:token-meter 实测请求压力 × 跳过回环数)。

你得到的是一个不再被自己的工具调用绊倒的 Agent —— 外加一个能证明这一点的看板:

一次文件编辑自愈的前后参数对比

它为你做什么

  1. 在失败前修好调用 —— 参数错位(command → code、缺 description、Markdown 围栏)、Code-Mode 内层调用描述、相对路径与视图范围。
  2. 只重试该重试的 —— 文件门禁失败做一次作用域内的读取后重试,范围越界做一次有界重试;锚点丢失类错误绝不盲目重试。
  3. 一切可见 —— KPI 卡片、工具/类别排行、可筛选的前后对比流水,在设置面板一键直达:

| 根因排行 | 自愈规则 | | --- | --- | | 工具与类别排行 | 六条自愈规则全部生效中 |


📖 前因后果与数据驱动背景

在 DeepSeek Harness 的自主 Agent 循环中,工具调用的鲁棒性直接决定了任务的成功率与流畅度。通过对 111 个真实持久化会话(共包含 11,176 次工具调用)进行全量统计与诊断,发现共有 543 次 Tool Call 错误(整体错误率 4.86%,影响了 53.2% 的会话)。

深层归因分析揭示了 四大结构性错误根因:

  1. INVALID_ARGS 参数契约错位 (13.6%, 74 次):
    • 模型在调用 run_code 时常套用 bash 惯性,传递 {"command": "..."} 而非 {"description": "...", "code": "..."}。
    • 模型常漏传 description 必填字段。
  2. UNKNOWN_TOOL Code-Mode 认知惯性冲突 (12.3%, 67 次):
    • 当配置启用 Code-Mode 时,系统仅向模型暴露 run_code 单一入口。但模型常习惯性直接发起 read、bash、write、grep 等独立工具调用,导致直接报 UNKNOWN_TOOL 失败。
  3. CODE_RUN_FAILED 沙箱内执行异常 (46.8%, 254 次):
    • 模型在 JS 模板字符串中嵌套生成复杂多行 shell 脚本或 Python 脚本时,因反引号未转义或换行破裂导致 JS 语法解析失败。
  4. 文件系统安全策略门禁 (5.5%, 30 次):
    • 未遵循先读后改策略(FS_NOT_OBSERVED)、编辑器 view_range 行号超界、或者使用了相对路径。

线上实际效果(v0.4.0 · 192 会话 / 15,460 次调用)

插件首次生效前(7,182 次调用,错误率 7.95%)与生效后(8,289 次调用,错误率 2.20%)对比:

  • INVALID_ARGS 缺描述失败从 74 降到 2(外层 RUN_CODE_DESC + 前置 INNER_DESC 修复)。
  • 以 CODE_RUN_FAILED 形式暴露的内层缺 description 从 45 降到 0(插件日志中 598 次前置 INNER_DESC 成功)。
  • FS_NOT_OBSERVED 从 10 降到 0(169 次观察后重试成功)。
  • UNKNOWN_TOOL 减半(71 → 35)但未消除:PTC 折叠调用在 waterfall 之前即被拒绝,任何插件都观测不到;v0.4.0 改为向这类错误追加可直接改写的提示,而不是静默丢弃。
  • 残留 CODE_RUN_FAILED 语法失败多为安全改写无法猜测的语义错误(把 Python 当 JS 粘贴、调错 API);v0.4.0 对其追加解析失败提示。

反事实上界:若没有 837 次成功自愈,生效后窗口错误率约为 12.3% 而非 2.20%。节省 Token 累计的是实测避免的重传(token-meter 压力量 × 跳过回环数),非硬编码常量。v0.4.0 起插件自身的嵌套恢复调用不再计入拦截总数,分母仅为面向用户的调用。


🎯 dsh-tool-normalizer 想解决的问题

本插件基于 Cordis 的 tools/execute 瀑布流扩展点构建,作为低开销、确定性的前置中间件对模型生成的工具调用进行自动纠偏与自愈,并配套提供 Web UI 诊断与统计看板:

       模型发起的 Tool Call
              │
              ▼
   ┌────────────────────────────────────────────────────────┐
   │             dsh-tool-normalizer 插件                   │
   │                                                        │
   │  1. run_code 自动归一化 (command ➔ code, 补全描述)       │
   │  2. 直接调用安全恢复 (保留上下文的嵌套派发)              │
   │  3. 编辑器路径与范围修正 (相对路径、倒置/越界范围)       │
   │  4. 动态精简提示词注入 (按需挂载, 零冗余 Token)          │
   │  5. 实时运行遥测与统计分析追踪器 (Tracker)              │
   └────────────────────────────────────────────────────────┘
              │
              ▼
       尽量恢复可修复错误
              │
              ▼
    [Web UI] 设置面板 ➔ 工具自愈与统计 (实时图表与日志)

核心功能

  • 🛠️ run_code 参数智能自愈:
    • 自动识别并转换 {"command": "git status"} / {"cmd": "..."} 为标准的 run_code JavaScript 调用。空或非字符串 command 不再自愈为空程序(会静默成功),而是留给宿主大声拒绝。
    • 自动补全缺失或为空的 description 字段。
    • 自动剥离误包含的 Markdown 代码块标记(如 typescript ... )。
    • 仅当内层目标工具的当前 schema 将 description 标记为必填时才补全;read、glob、grep 等开放参数工具保持原始参数不变。
  • 🌉 Code-Mode 透明工具桥接:
    • 当 UNKNOWN_TOOL 已经进入 tools/execute 且目标工具在当前 Agent 作用域中可见时,插件通过宿主的 tools.execute() 重新以嵌套调用派发,保留 Agent、会话、取消信号、上下文和终结状态。可桥接名单覆盖 bash/read/write/grep/edit/glob/str_replace_editor/job_output/job_kill 及 web_fetch/web_search/todo_write/skill/ask_user_question。
    • 适用范围说明:在 PTC(code)折叠模式下,宿主在任何监听器之前拒绝直调,这条路径插件无法仅靠自身拦截;v0.4.0 对这类错误在保留原文的基础上追加一条可直接粘贴的 run_code 改写提示。插件也不会直接调用工具定义的 execute() 方法。
  • 💡 失败即时提示(errorHints,默认开启):
    • 对无法恢复的 PTC 直调错误与不可修复的 run_code 解析失败,在保留原报错文本的前提下追加一条可操作提示,模型当轮即可纠正。设为 false 可保持宿主报错逐字节不变。
  • 📐 编辑器参数与边界纠偏:
    • 仅对 str_replace_editor(拒收相对路径)将相对路径转换为当前会话工作目录下的绝对路径;edit/read/write 族自己会解析,插件不碰。
    • 先做结构性范围修正;当 str_replace_editor 返回包含文件行数的越界错误时,按真实行数嵌套重试,并保留 -1 到文件末尾的语义。
  • 🩹 文件观察后重试:
    • 在编辑/写入返回 FS_NOT_OBSERVED 或 FS_STALE_VERSION 后读取目标文件,再通过宿主标准派发重试一次;锚点丢失类错误(FS_EDIT_NOT_FOUND、FS_AMBIGUOUS_EDIT)绝不盲目重试,仅预读刷新观察态以便模型下次重试不再被额外拦截;正常调用不会预先增加一次读取。
  • 📊 可视化运行与诊断面板 (Web UI):
    • 无缝挂载至 DSH 的 设置面板(settings.section)。
    • 实时呈现核心 KPI 指标:拦截总数、成功纠正数、纠正尝试成功率 %、未恢复错误数。
    • 工具维度与问题类别的可视化分布进度条。
    • 支持按状态(全部 / 仅看纠偏 / 仅看失败)筛选的实时运行流水明细表,直观对比纠偏前后的输入差异。
    • v0.4.1 界面修复:深色主题下选中的筛选 pill 与页签不再是黑底黑字(改为 tint 底 + 品牌色文字);未修改的正常放行行改用中性色而非成功绿;规则页新增第 6 张卡片说明失败提示。本文截图均取自真实运行的部署(首图深色、明细浅色)。

🧭 UI 页面放置位置与设计考量

挂载位置:DeepSeek Harness 设置导航页(settings.section,ID 为 tool-normalizer,序号 25)。

选址考量:

  1. 符合 DSH 官方架构规范:在 DeepSeek Harness 的 Web UI 规范中,所有系统监控、用量统计(如 dsh-usage-atlas)、模型配置与插件管理均统一收纳于设置抽屉(Settings Panel)内。
  2. 保持主对话界面纯净:将诊断与统计收纳于设置页,既不干扰 Agent 主对话流与工作区画布,又可通过侧边栏左下角齿轮图标一键直达。
  3. 运维与排障一体化:开发者可在同一设置视窗内完成模型切换、插件开关以及工具自愈率观察。

🚀 安装与快速上手

在 DeepSeek Harness 中,插件是按 组合 Profile(如 web, headless, tui 等)进行隔离与依赖管理的。

第一步:安装插件至目标 Profile

使用全局 dsh 命令(或在源码仓库下使用 pnpm dsh):

# 1. 安装至 Web UI 模式(含设置面板可视化看板)
dsh plugin --profile web add dsh-tool-normalizer
# (若在 deepseek-harness 源码仓库下开发调试)
pnpm dsh plugin --profile web add dsh-tool-normalizer

# 2. 安装至 Headless 自动化模式
dsh plugin --profile headless add dsh-tool-normalizer

# 3. 安装至 TUI 终端交互模式
dsh plugin --profile tui add dsh-tool-normalizer

本地开发模式链接(可选)

如果你正在本地修改或测试插件源码:

pnpm dsh plugin --profile web add ./plugins/dsh-tool-normalizer

第二步:启动并查看效果

# 启动 Web 界面
dsh web
# (或源码启动)
pnpm dsh web

打开浏览器进入 Harness 界面,点击左下角 设置 (⚙️) ➔ 「工具自愈与统计」,即可实时查看所有工具调用拦截流水、纠偏统计与成功率图表!


⚙️ 配置项说明

你可以在工作区的 cordis.patch.yml 中自定义插件的运行参数:

- insert:
    - id: tool-normalizer
      name: dsh-tool-normalizer
      config:
        autoWrapRunCode: true
        autoBridgeDirectTools: true
        autoObserveFiles: true
        autoClampRanges: true
        injectPrompt: true
        errorHints: true
        persistPassthrough: false

| 配置字段 | 类型 | 默认值 | 作用说明 | | :--- | :---: | :---: | :--- | | autoWrapRunCode | boolean | true | 自动转换 command 属性为 code,自动补全描述,剥离 Markdown 标记 | | autoBridgeDirectTools | boolean | true | 仅对已进入 tools/execute 的 UNKNOWN_TOOL 结果尝试安全嵌套恢复;宿主提前拒绝的调用插件无法拦截 | | autoObserveFiles | boolean | true | 仅在收到 FS_NOT_OBSERVED 后读取目标并重试一次编辑/写入 | | autoClampRanges | boolean | true | 修正编辑器范围;仅对 str_replace_editor 解析相对路径 | | injectPrompt | boolean | true | 动态向 systemPrompt 注册极简工具最佳实践提示词(静态文本,不影响前缀缓存命中) | | errorHints | boolean | true | 对不可恢复的 PTC/语法错误追加一条可操作提示,原报错文本完整保留 | | persistPassthrough | boolean | false | 是否将未修改且成功的正常放行调用逐条写入 JSONL;默认仅保留聚合计数,失败和自愈事件仍保留明细 |

成功率只计算实际发生修复/恢复尝试的调用:healedSuccess / (healedSuccess + healedFailed)。前置规范化改对、但终错属于另一失败类别时,记为无关的未修复失败而非修复失败,成功率才反映真实修复能力。预检/守卫拒绝等未修复失败计入总数但不进入成功率分母。正常成功放行不会进入详细 JSONL,以避免日志被高频健康调用淹没;其计数写入同目录的 tool-normalizer-summary.json(最多每秒落盘一次)。明细日志超 2 MB 自动轮转(保留最新约 1 MB),debug 日志仅记录失败与自愈。

"预估节省 Token"KPI 为每次成功自愈累计的实测输入 token:每次修复记为「跳过的模型回环数 × token-meter 请求压力量」(即再多一次请求需重新提交的整段提示词)。它依赖组合中的 @deepseek-ai/dsh-token-meter;未挂载时该统计保持为 0,不再使用硬编码的单次重试成本。

流水明细对长参数只保留首尾预览,并额外显示实际修改的字段或恢复路径,避免新增字段位于截断区域时看起来没有变化。


📦 发版与发布指南 (Release & Publishing)

方式一:基于 GitHub Actions 自动化发版(推荐)

  1. 在 GitHub 仓库设置中配置 npm Token:
    • 进入 GitHub 仓库 Settings ➔ Secrets and variables ➔ Actions ➔ New repository secret。
    • Secret 名称:NPM_TOKEN,值为开启了 2FA Bypass 权限的 npm Token。
  2. 升级版本号并推送 Tag:
    # 升级小版本(patch / minor / major)
    npm version patch
    
    # 推送分支与 Tags 到 GitHub
    git push origin main --tags
  3. 在 GitHub 页面基于新推送的 Tag 发布 Release,GitHub Actions 流程(.github/workflows/publish.yml)将自动运行全套测试、打包并将新版本发布至 npm 官方镜像源!

方式二:本地手动发布到 npm

# 1. 执行全量测试与打包编译检查
npm run check

# 2. 登录 npm 账号(若未登录)
npm login

# 3. 执行发布
npm publish --access public

已知局限

  • 不对 read/write 做路径归一化。 read/write/edit 工具族自己就会按会话工作目录解析相对路径,只有 str_replace_editor 会拒收。给前者"治病"会把本来就能成功的调用计入自愈,污染成功率,因此插件有意不碰。

🧪 单元测试与验证

# 运行单元测试
pnpm test

# 运行测试并打包产物
pnpm run check

📄 开源许可

MIT © merenguesL