
DSH Tool Calculator
☆ 1DSH 计算器工具插件:安全的数学表达式求值器,零依赖递归下降解析器
Get this plugin
Review the source, then continue to the publisher.
dsh plugin add @deepseek-ai/dsh-tool-calculator@latestAbout this plugin
Source snapshot 8/13/2026dsh-tool-calculator
English
DSH 计算器工具插件 —— 安全的数学表达式求值器。零依赖、零进程、纯函数。
动机
Agent 做算术不稳定是 LLM 的通病。DSH 内置的 bash 工具可以调用 echo $((15 + 27 * 3)) 完成计算,但有两个问题:
- 每次算术都起一个 bash 进程——Windows 上尤其昂贵(创建进程、加载 shell、执行、收集输出),高频调用时累积延迟显著
- bash 算术语法有限——不支持
sqrt、sin、cos、log、pow等数学函数,agent 在这些场景下只能猜答案或写脚本
本插件提供零依赖、零进程、纯函数的计算器——一次函数调用,毫秒级得出结果,覆盖常用初等数学函数。
安全模型
无 eval、无 new Function。 使用手写递归下降解析器(词法层 + 语法层),只求值白名单节点:
- 词法层只识别数字字面量、白名单标识符、运算符;引号、分号、反引号、
{}[]直接报错 - 标识符按名查白名单表(15 个函数 + 2 个常量),查不到即抛
Unknown identifier - 求值结果必须是有限数字,
NaN/Infinity(除零、负数开方等)统一拒绝
new Function + 正则白名单是不安全的——constructor.constructor(...) 可直达 Function 构造器执行任意代码,process.exit(0) 可直接杀死宿主进程(均已实测复现)。本实现不使用任何代码求值捷径。
架构
┌──────────────────────────────┐
│ DSH Agent │
│ tool call: calculator { ... }│
└──────────┬───────────────────┘
│ ctx.tools.register()
┌──────────▼───────────────────┐
│ src/index.ts │
│ Cordis 插件入口 │
└──────────┬───────────────────┘
│
┌──────────▼───────────────────┐
│ src/evaluate.ts │
│ tokenize() → parse() │
│ 递归下降解析器 │
└──────────────────────────────┘
src/index.ts:Cordis 插件入口(name/inject/apply),注册calculator工具src/evaluate.ts:evaluate(expression: unknown): number——入口独立校验类型(非字符串抛calculator: expression must be a string),返回有限数字,非法输入全部抛错
工具声明
import type { Context } from '@deepseek-ai/cordis'
import { defineTool } from '@deepseek-ai/dsh-tools'
import { evaluate } from './evaluate.ts'
export const name = '@deepseek-ai/dsh-tool-calculator'
export const inject = ['tools']
export function apply(ctx: Context): void {
ctx.tools.register(defineTool({
name: 'calculator',
description:
'Evaluate a mathematical expression safely. ' +
'Supports +, -, *, /, %, **, parentheses, and functions: ' +
'abs, ceil, floor, round, max, min, sqrt, pow, log, log2, log10, exp, sin, cos, tan, PI, E.',
parameters: {
expression: {
type: 'string',
required: true,
description: 'Mathematical expression, e.g. "15 + 27 * sqrt(9)"',
},
},
output: {
schema: { type: 'number' },
render: (_args, value) => [{ type: 'text', text: String(value) }],
},
execute: async (args) => evaluate(args.expression),
timeoutMs: 1000,
}))
}
支持的操作
| 类别 | 项目 |
|---|---|
| 算术 | + - * / % **(幂,右结合:2 ** 3 ** 2 = 512) |
| 函数(单参) | abs ceil floor round sqrt log log2 log10 exp sin cos tan |
| 函数(多参) | pow(x, y) max(a, b, ...) min(a, b, ...) |
| 常量 | PI E |
| 分组 | ( ),一元正负 +5 -5 |
优先级:**(右结合)> 一元 ± > * / % > + -。
npm rc.1 兼容(已验证)
本插件已迁移到 npm rc.1 依赖线,并在 @deepseek-ai/dsh@0.0.1-rc.1 的隔离 consumer 中完成全链路验证:
- 类型/运行时:
@deepseek-ai/cordis@^4.0.1-rc.1+@deepseek-ai/dsh-tools@^0.0.1-rc.1+@deepseek-ai/dsh-invariants@^0.0.1-rc.1(peer);不再依赖 unscopedcordis - 独立构建:
npm install(devDependencies 自包含 typescript/vitest/@types/node)→npm run typecheck→npm test→npm run build→npm pack - 消费验证:tarball 装入 rc.1 consumer →
dsh --profile compat --dump-config出现本插件 row → 工具真实注册与执行通过 - 启动方式:
npx -p @deepseek-ai/dsh@0.0.1-rc.1 dsh web(lib 生产模式;勿install -g全局安装)
版本适配
- 适配 DSH snapshot:
20260806T160212Z-279244acb0(0806 迁移:profile/bundle 插件系统) - bundle 声明:
package.json的dsh.bundle(patch 指向cordis.patch.yml)+exports导出 - patch 格式:
cordis.patch.yml使用- insert:列表(0806 的 patch 是 id-targeted 语义,裸- id:条目会报entry not found) - files: 发布 tarball 含
lib/、src/、cordis.patch.yml
安装
Profile Bundle(推荐)
将本插件作为独立 bundle 安装到 profile(0806+):
# 交互式(web)profile
dsh plugin --profile web add "C:/path/to/dsh-tool-calculator"
# 一次性任务(headless)profile —— dsh run 默认使用 headless
dsh plugin --profile headless add "C:/path/to/dsh-tool-calculator"
包内 dsh.bundle.patch(指向 cordis.patch.yml)会在安装后自动把插件加入 profile 的 layer stack;插件的 cordis.patch.yml 以 - insert: 插入 tool-calculator 条目。插件缺失的 peer 依赖(cordis、@deepseek-ai/dsh-tools)由 profile 的 healed profiles/node_modules 回退安装提供。
⚠️ web 与 headless 是不同 profile:web 安装不会自动覆盖 headless;
dsh run默认使用 headless profile。Windows 路径使用正斜杠(C:/...)。
验证安装
dsh --profile web --dump-config | grep tool-calculator
运行验证
dsh run "使用 calculator 工具计算 1+2*3"
手动安装与旧版本兼容
仅适用于不支持 Profile Bundle 的旧快照或插件开发调试环境:
- 放入 monorepo:
cp -r calculator ~/.dsh/source/master/packages/tools/calculator(开发调试) apps/cli/package.json加"@deepseek-ai/dsh-tool-calculator": "workspace:^";tsconfig.host.jsonreferences 加{ "path": "./packages/tools/calculator" }pnpm install && pnpm run build- 在 profile 用户层 patch 插入插件(
~/.dsh/profiles/<name>/cordis.patch.yml):
- insert:
- id: tool-calculator
name: '@deepseek-ai/dsh-tool-calculator'
- 验证:
dsh --profile <name> --dump-config | grep tool-calculator
0806 注意:patch 是 id-targeted 语义——裸
- id:条目会报entry "xxx" not found,必须用- insert:列表包裹。
用法
安装后,agent 自动获得 calculator 工具:
calculator { expression: "15 + 27 * sqrt(9)" } → 96
工具名满足 DeepSeek 函数名约束(≤64 字符,[A-Za-z0-9_-])。注册后自动进入 Code Mode SDK(await tools.calculator(...)),canonical 返回值为数字。
已知限制
- 分发链路:
@deepseek-ai/dsh-tools是 DSH monorepo 私有包(未发布 npm),本插件需放入 monorepo 走 workspace 解析 - 三角函数使用弧度:与
Math.sin/Math.cos一致;需要角度时写sin(30 * PI / 180) - 不支持大整数:JS
number是 IEEE 754 double,安全整数范围 ±9e15,超出有精度损失 - 不支持科学计数法:
1e5会被词法层拒绝
测试
pnpm test
包含功能用例与攻击载荷用例(constructor.constructor 链、process.exit(0)、globalThis、引号注入、分号语句等)。完整用例清单见本地维护的设计文档。
许可
MIT