description: "面向工具作者与维护者的工具注册表与执行流水线说明,用于注册、限制、呈现或调试面向模型的工具。"
English | 中文
使用 dsh-tools 可向模型公开类型化能力、校验调用、执行允许/拒绝/询问策略,并在普通工具失败时返回最终结果而不中止当前轮次。通过 mode 选择原生 Function Calling(函数调用)、PTC mode 或两者;单个 agent(智能体)可用 presentAs 覆盖默认值。工具作者使用 defineTool 声明类型化参数与输出、协作式超时、并行安全属性和可选 UI 展示。模型会看到每个获准工具声明的名称、描述与参数 schema;按 agent 设置的限制可缩小该可见集合。
在任何 agent 调用工具的地方挂载 dsh-tools:它提供 ctx.tools,即每个工具插件注册进去、循环分发所经过的注册表。注册一个工具就足以让它可见——注册表会自动把其 schema 送入系统提示词组装。
defineTool 构建类型化工具定义:面向模型的名称、描述与参数 schema、规范输出声明,以及只返回所声明 JSON 值的 execute 主体。模型参数在执行前被校验;无效输入变成普通错误结果。
import { readFile } from 'node:fs/promises'
import type { Context } from '@deepseek-ai/cordis'
import { defineTool } from '@deepseek-ai/dsh-tools'
declare const ctx: Context
ctx.tools.register(defineTool({
name: 'read_file',
description: 'Read a file from disk.',
parameters: {
path: { type: 'string', required: true, description: 'Absolute file path' },
offset: { type: 'number' },
limit: { type: 'number' },
},
output: {
schema: { type: 'string' },
render: (_args, value) => [{ type: 'text', text: value }],
},
async execute(args, exec) {
// args is typed: { path: string; offset?: number; limit?: number }
return readFile(args.path, { encoding: 'utf8', signal: exec.signal })
},
}))
统一 schema DSL 支持 string、number、integer、boolean、null、array、object、仅供作者使用的 json 与恰好匹配一个分支的 oneOf;InferValue 在 16 层容器内保留精确类型,之后加宽为 JsonValue。原始 JSON Schema(JsonSchemaNode)是与 subagent、工作流和 MCP 共享的协议级对应类型。
mode 配置决定模型看到什么:native(每个可见 schema)、ptc(只有 run_code 加一份生成 SDK)或 both。
- name: '@deepseek-ai/dsh-tools'
config:
mode: native
| 字段 | 默认值 | 含义 |
|---|---|---|
mode |
native |
可见工具向模型呈现的方式:native、ptc 或 both |
maxParallelSubCalls |
10 |
run_code 程序重叠子调用的并发上限;1 恢复严格串行分发 |
生成的配置目录是每个受支持字段的穷尽式真源。非原生模式要求已组合的 ctx.codeRuntime 且其语言有已注册的 SDK 渲染器;agent preset 通过 dsh-agent-tool-presentation 自行选择呈现方式,单个 agent 可用 presentAs(mode) 遮蔽默认值。
ctx.tools.restrict(filter) 对单个 agent 继承的全局工具应用允许或拒绝掩码;掩码取交集,作用域注册保持可见,限制在 dispose(资源释放)时解除。ctx.tools.get(name, scope) 按一个作用域的视角解析工具。使用 Host 本地展示转换器的消费方如需匹配实际执行的定义,会传入发起调用的 agent。ctx.tools.schemas(scope) 返回可见 schema(不含 execute 函数)。
ctx.tools.guard(guard) 在可扩展的 tools/pre-execute waterfall(瀑布式事件)之后注册单调同步守卫:返回的理由会拒绝调用,后续监听器无法把该拒绝重新变为允许。流水线事件给插件更多控制——tools/pre-execute 决定允许/拒绝/询问,tools/execute 为超时或重试包装分发,tools/post-execute 检查或替换结果,tools/result 观测冻结的最终结果。
工具可以为 Host 本地消费方保留纯函数 presentCall() 与 presentResult() 方法。内置 Web Client 不消费这些值,而是通过 tool.call.toolview 选择 renderer,并从原始调用参数、结果内容、失败状态与持久 metadata 派生 card props。Client 派生展示决策负责该 transport 拆分。
包级约定对大多数消费方已经足够;需要周边领域时再阅读以下页面。
在普通模式下,模型会看到每个可见定义的确切名称、描述与 JSON Schema;已交付定义记录在生成的工具目录中。agent 作用域的限制、遮蔽与扩展注册会改变该 agent 的最终工具集合。
每次请求的固定成本与可见定义成正比。隐藏工具的限制会为该 agent 移除其全部 schema 成本。
只要可见定义及其顺序不变,前缀就保持稳定。注册、dispose 或作用域限制可能从第一个改变的 schema token 起使复用失效。
PTC mode 会公开生成的 run_code schema、下方 SDK 说明,以及按所加载运行时语言生成的精确 SDK 块。TypeScript 说明会把生成声明明确标为只能在程序内使用的绑定。当当前 bash 参数 schema 接受示例参数时,说明还会给出以 run_code 包住 tools.bash(...) 的完整调用。tools:sdk 段使用 first-party 顺序 5000。both 会同时公开普通 schema 与此 PTC mode API;在 ptc 下,提示词还会带上处于更早 first-party 顺序的 tools:ptc-only 规则,让模型先读到「可以调用哪些工具」再读「每个工具做什么」。
## Writing code for run_code
`run_code` takes two required arguments: `code` — the body of an async TypeScript function (erasable syntax only — no `enum` or namespaces; type annotations are advisory, the code runs type-stripped) — and `description`, a short summary of what the program does. The declarations below are SDK bindings for this program. A declaration does not make its name a directly callable tool; only names supplied as separate tool schemas may be called directly. When no separate `bash` schema is supplied, invoke a declared `bash` binding inside `run_code`:
`run_code({ code: "return await tools.bash({ command: 'pwd', description: 'Show current directory' })", description: "Show current directory" })`
Inside the program:
- Call tools as `await tools.name(args)` — quoted access for exotic names: `tools["my-tool"](args)`. Every call resolves to the tool's typed canonical JSON value. Tool arguments must be lossless JSON.
- A FAILED tool call rejects with `ToolCallError`, whose `toolName` identifies the failed tool and whose `message` is human-readable — `try/catch` it to handle and continue.
- Independent read-only calls MAY overlap under `Promise.all` (safe calls run concurrently; mutating calls run alone, in submission order). Sequence dependent work with `await`.
- Emit results with `return` and/or `console.log(...)`. Only what you print or return is program output. A successful tool result containing an image is attached after the run so you can inspect it on the next step; every other intermediate result stays out of the conversation, so extract just what you need.
Program-only SDK bindings:
每次请求的固定成本与可见定义成正比。PTC mode 使用生成的 SDK 文本加一个传输 schema 取代最终工具 schema,但不承诺普遍减少成本。
只要 PTC mode 选择、生成的 SDK、传输 schema 与可见工具集合不变,前缀就保持稳定。模式或筛选器变更可能从第一个改变的提示词或 schema token 起使复用失效。
循环会保留模型发出的参数与注册表的最终内容。任何抛出异常或遭到拒绝的调用,都会转换为确切的 Error: <message>。PTC mode 只返回外层程序打印的行与呈现后的返回值;两者都为空时返回 (run_code completed with no output);失败时返回 Error: code run failed (<kind>): <message>,并根据是否存在已捕获内容,在其后附加 Captured output: 与捕获的行。内部分发事件只保留在日志中;成功且含图片的子结果会在外层结果之后作为带来源归属的上下文追加。
参数、结果与附加上下文取决于数据,并会重复发送直至压缩(compaction)。隐藏工具的限制还会在模型可以调用这些工具之前移除其 schema。
仅追加;新的可见内容位于可复用请求前缀之后,不会使现有 KV Cache 条目失效。
这些限制说明注册表何时需要特别留意。它们是当前包约束,不是任务积压。
executionMode() 直接读取已解析的工具定义;插件只能在自身拥有的定义上声明分类器。tools/pre-execute 有意不允许改写 exec.arguments:否则日志记录与呈现的参数会与实际运行内容失去同步;改写设计记录在拟议的 Agent Note中。timeoutMs 仅作声明之用:注册表绝不会强制执行截止时间;要强制执行,必须使用 @deepseek-ai/dsh-tool-call-timeout-policy 包装层。mode: ptc/both 会拒绝组装提示词,除非 ctx.codeRuntime.language 有已注册的 SDK 渲染器;同一个 agent 内不能让一个工具仅使用 Native,而另一个仅使用 PTC。run_code 输出受 worker 可配置的硬上限约束。run_code 状态:MVP 不采用持久 REPL 风格内核,因为跨调用状态不会出现在日志中。