前言¶
在 DeepSeek Harness(DSH)里用 PTC 的 run_code 写一小段 TypeScript,再调用宿主暴露的工具,是常见工作流。不少工具的首参是可选对象:模型往往会写成 await tools.job_list() 或 await tools.job_list(undefined),而不是显式传 {}。PTC worker 在把调用交给宿主前,会对绑定参数做 lossless JSON 快照;undefined 没有可序列化表示,调用会在 worker 侧被拒绝,宿主收不到请求,报错通常是 binding arguments must be lossless JSON。手动改成 await tools.job_list({}) 可以绕过,但很难保证模型每次都写对。下面介绍 Cordis 插件 dsh-ptc-noargs(维护者 TLEWA,分类:工作流):在不大改 runtime 的前提下,对 run_code 里 TypeScript function-body 的执行副本注入一行 prelude,把「省略首参」和「显式 undefined」归一成 {}。
这是什么¶
dsh-ptc-noargs 是一个最小的 Cordis 插件,面向 DSH PTC 的 run_code 绑定场景。它监听共享工具流水线的 tools/execute waterfall;仅当工具是 run_code、程序为 TypeScript function-body、且参数里含 code 时,在实际执行的 code 前追加 prelude,用包装后的 tools 命名空间拦截无参或首参为 undefined 的调用。
- 仓库:TLEWA/dsh-ptc-noargs
- 插件目录页:skillhub.cn/plugins/TLEWA/dsh-ptc-noargs
- 当前包版本(package.json):
0.1.0 - 许可证:MIT
- peer:
@deepseek-ai/cordis >=4.0.0-rc <5;引擎要求node >=20、dsh >=0.2.2-rc.1(README 写明在 DSH 0.2.2-rc.1 验证)
插件不修改 PTC runtime、不修改工具定义,也不改模型与日志里的原始 code;只有执行副本带 prelude。
问题与原理¶
报错从哪来¶
在 run_code 中若写成:
await tools.job_list()
await tools.job_list(undefined)
PTC worker 会因 binding 参数无法做 lossless JSON 序列化而失败,典型错误为:
binding arguments must be lossless JSON
显式传对象可以绕过,例如 await tools.job_list({}),但这依赖模型习惯,不稳定。
插件怎么做¶
prelude 会克隆 tools,对每个函数做薄包装:首参省略或为 undefined 时改为 {},其余参数原样传递;用户代码仍使用名字 tools。null 不会被改写。插件只处理 run_code 的 PTC 绑定,不适用于原生工具执行器下的普通工具调用。
支持范围与限制¶
安装前建议通读 README 中的限制,避免误判「没生效」:
- 仅支持 TypeScript function-body(PTC 默认模式);Python、REPL、script 模式会跳过。
- prelude 占一行,用户代码行号整体后移 1 行;报错栈中的行号也会偏移。
- 依赖
tools/execute上可替换arguments的执行对象;上游若收紧行为,插件会安全跳过(warn,不阻断调用)。 - 已在 DSH 0.2.2-rc.1 验证;更低版本需自行核对
engines。
安装与启用¶
插件应放在稳定目录,不要只留在临时工作区。DSH 社区插件目录(SkillHub)与 GitHub 仓库相互独立,并非 DeepSeek / 幻方官方应用商店;安装方式以仓库 README 为准。
方式一:桌面端插件页(推荐,通常无需重启)¶
- 打开 插件 → 添加插件,输入插件的本地目录路径(需先自行将仓库放到稳定位置,README 示例使用
git clone到固定路径,此处不重复克隆命令)。 - 安装后点 立即启用;管理器显示「运行中」即已生效。
方式二:CLI(link: 或 .tgz)¶
若 dsh 不在 PATH,可改用 DSH 安装目录下的 resources\runtime\cli\bin\dsh.cmd(Windows 路径以 README 为准)。
dsh plugin --profile desktop add "link:C:\Users\<you>\.dsh\local-plugins\dsh-ptc-noargs"
也可在插件目录执行 npm pack,用生成的包安装(不依赖源码目录继续存在):
dsh plugin --profile desktop add "C:\path\to\dsh-ptc-noargs-0.1.0.tgz"
CLI 安装后需重启 DSH;插件页热加载通常不用重启。
卸载¶
dsh plugin --profile desktop remove dsh-ptc-noargs
从插件管理器卸载后立即恢复行为;CLI 卸载后需重启。插件不写入 DSH 安装目录;link: 安装主要在 profile 的 package.json / Cordis 组合中增加一项,卸载后应恢复原状。
安全提示:插件随当前 DSH 进程权限运行。安装前应阅读 lib/ 与 cordis.patch.yml、确认 MIT 许可证与来源归属,再启用。
典型用法与验证¶
启用后,在 run_code 的 TypeScript function-body 中可继续使用模型常用的无参写法:
await tools.job_list()
await tools.list_agents()
预期返回正常结果,而不是 binding arguments must be lossless JSON。README 中的对照还包括 await tools.job_list(undefined)、await tools.get_goal() 等;未启用时同一 await tools.job_list() 会恢复该报错。
开发者在插件仓库内可跑单元测试:
node test/prelude.test.mjs
README 说明 12 项测试覆盖省略首参、undefined、null、非 TS runtime 跳过等情形。
适用场景¶
- 经常在
run_code里编排 DSH 工具、且模型爱写tools.foo()/tools.foo(undefined)的开发者。 - 希望少改提示词、少教模型「空对象也要写
{}」的工作流场景。 - 不需要 Python / REPL / script 模式下的同类修补(本插件会跳过)。
若你关心 PTC 以外的体验,同一维护者还在 README 中列出其他 DSH 项目(如 dsh-better-choice、dsh-fastload 等),可按需从 GitHub 查阅,与本插件无安装依赖。
结尾¶
dsh-ptc-noargs 用一行 prelude 在 run_code 执行路径上归一化首参,专门对付 binding arguments must be lossless JSON,改动面刻意保持很小。查阅说明与源码:GitHub;在 DSH 里从社区目录进入:SkillHub 插件页。