From 745049f267ef9b3264d036b471f6cd4668147a40 Mon Sep 17 00:00:00 2001 From: Yubin Li Date: Mon, 31 Aug 2026 16:49:37 +0800 Subject: [PATCH] =?UTF-8?q?docs(skill):=20=E4=BF=AE=E6=AD=A3=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=20output=20=E5=A5=91=E7=BA=A6=E2=80=94=E2=80=94?= =?UTF-8?q?=E5=BF=85=E9=A1=BB=E5=A3=B0=E6=98=8E=20render?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- skills/make-dsh-plugin/SKILL.md | 9 ++++++++- .../references/entry-contract.md | 15 +++++++++++++-- skills/make-dsh-plugin/references/gotchas.md | 19 +++++++++++++++++++ 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/skills/make-dsh-plugin/SKILL.md b/skills/make-dsh-plugin/SKILL.md index bb9a316..67fcf00 100644 --- a/skills/make-dsh-plugin/SKILL.md +++ b/skills/make-dsh-plugin/SKILL.md @@ -91,7 +91,14 @@ make-skill)见 `references/entry-contract.md` 对应小节——不要发明 运行时的职责(`@deepseek-ai/*`、`cordis`——profile pnpm 闭包注入,勿声明)。 在 `ctx.effect()`/`ctx.on()` 内注册,disable 时清理。 -**检查点**:entry 可解析;工具已注册;inject 声明完整。 +**工具的 `output` 必须声明 `{ schema, render }`**(`presentationMeta` 可选)—— +缺 `render` 在 boot 挂载时抛 `tool ... must declare output { schema, render, presentationMeta? }` +并导致整棵插件树加载失败(web 起不来)。写法: +`output: { schema: {...}, render: (_args, value) => [{ type: 'text', text: JSON.stringify(value, null, 2) }] }`。 +`defineTool` 来自 `@deepseek-ai/dsh-tools`(公共 npm 不存在、仅运行时闭包可解析)——本地独立验证 +用原生 ToolDefinition 对象更稳(`ctx.tools.register` 原生接受,参照 `dsh-chatdata-plugin`)。 + +**检查点**:entry 可解析;工具已注册且 `output` 含 `schema + render`;inject 声明完整。 ## Step 4:Client half(可选)——自渲染 diff --git a/skills/make-dsh-plugin/references/entry-contract.md b/skills/make-dsh-plugin/references/entry-contract.md index eab5572..0ce0870 100644 --- a/skills/make-dsh-plugin/references/entry-contract.md +++ b/skills/make-dsh-plugin/references/entry-contract.md @@ -77,13 +77,24 @@ export function apply(ctx) { name: 'my_tool', description: 'What it does.', parameters: { type: 'object', properties: {} }, - output: { schema: { type: 'string' } }, - execute: async () => 'result', + output: { + schema: { type: 'object' }, + render: (_args, value) => [{ type: 'text', text: JSON.stringify(value, null, 2) }], + }, + execute: async () => ({ ok: true }), })) } ``` - 能力上限是完整 Cordis——事件(`ctx.on`)、服务(`ctx.provide`)、命令、system prompt、TUI,无需声明。 +- **`output` 必须声明 `{ schema, render }`(`presentationMeta` 可选)**:运行时 `ctx.tools.register` + 强制校验,缺 `render` 在 boot 挂载时抛 `tool "" must declare output { schema, render, presentationMeta? }` + 并导致整棵插件树加载失败(`plugin tree failed to load`,web 起不来)。`schema` 须通过官方 + `assertSupportedJsonSchema`(纯 JSON Schema 可用);`render(args, value)` 返回渲染块数组 + (`[{ type: 'text', text: ... }]`)。此坑曾因示例漏写 `render` 真实踩到(见 gotchas §6)。 +- **`defineTool` 仅运行时闭包可解析**:`@deepseek-ai/dsh-tools` 不在公共 npm,本地独立 `import` 失败—— + 本地验证时直接注册原生 ToolDefinition 对象(`ctx.tools.register` 原生接受),参照 `dsh-chatdata-plugin`; + 正式分发仍由运行时经闭包注入解析。 - **依赖解析**:entry 可 import 官方包(`@deepseek-ai/*`、`cordis`),官方运行时经 profile pnpm 闭包注入(`$DSH_HOME/profiles/node_modules` flat fallback);**不要声明这些依赖**(声明了公共 npm 解析不到反而失败)。 - **注册是 effect**:`ctx.tools.register` 返回 disposer,用 `ctx.effect()`/`ctx.on()` 持有生命周期,disable 时清理。 diff --git a/skills/make-dsh-plugin/references/gotchas.md b/skills/make-dsh-plugin/references/gotchas.md index abc2275..2caac51 100644 --- a/skills/make-dsh-plugin/references/gotchas.md +++ b/skills/make-dsh-plugin/references/gotchas.md @@ -86,3 +86,22 @@ bundle 插件的**启停覆盖写 profile 层**,不要写进 bundle 包内层 - **client 经 `__ModuleLoader__.load` 注册**:0811 client-modules 只扫描声明 `dsh.client` 的包,client bundle 必须 `__ModuleLoader__.load({id, factory})`——否则报 `loaded without registering`。 - **严格注入**:`ctx.get` 未在 `inject` 声明的服务 → `cannot get property without inject`,apply 开头即抛、整个 effect 不注册(路由全 fallback 成 SPA 主页)。 - **工具 schema DSL 违规在挂载时暴露**:CLI enable 只校验名称,`defineTool` value-schema 违规在 web boot/面板 enable(reconcile)时暴露——发现后重启 web 确认日志。 + +## 6. 工具 `output` 缺 `render` → boot 硬失败(实测 2026-08-31) + +ToolDefinition 的 `output` 只写 `schema` 不写 `render`(`presentationMeta` 可选)时,boot 挂载即抛: + +``` +TypeError: tool "" must declare output { schema, render, presentationMeta? } +``` + +→ `plugin tree failed to load` → **web 启动失败**。要点: + +- **CLI enable 查不出、mock ctx 独立验证也查不出**(假 ctx 不跑运行时校验)——只有真实挂载 + 冒烟(装 → 挂载 → boot log 干净)能抓到;本地快速自证可用官方 + `assertSupportedJsonSchema`(从已安装 dsh 的 `@deepseek-ai/dsh-tools` import)+ 按 + `register()` 源码复刻 output 条件校验。 +- 正确写法:`output: { schema: {...}, render: (_args, value) => [{ type: 'text', text: JSON.stringify(value, null, 2) }] }` + (对照本部署 `dsh-chatdata-plugin`)。 +- 环境事实:`entry-contract.md` 的示例曾漏写 `render`(已修)——照旧示例原样抄会复现此坑; + 这也是「挂载失败排查顺序」(§3)之外的另一个 boot 失败入口。