DSH 安全数学计算工具,用零依赖纯函数求值替代每次起 bash 进程做算术
ⓘ 此插件是大仓库 omdsh-dev/dsh-toolkit 的子包,星数与活跃度统计的是整个仓库。
- 语言
- TypeScript
- License
- MIT
- 分支
- main
安装
$ dsh plugin --profile web add github:omdsh-dev/dsh-toolkit#path:packages/dsh-tool-calculator在终端中运行以上命令,通过 dsh CLI 安装此插件。可在右上角切换 Profile。 第一次用 dsh?看这篇新手教程
对话式安装
帮我安装 DeepSeek Harness 插件 omdsh-dev/dsh-toolkit/packages/dsh-tool-calculator:先查看仓库 https://github.com/omdsh-dev/dsh-toolkit 确认安全性,然后执行安装命令并验证插件加载成功。
把这段指令粘贴给 DSH Web GUI 里的助手,由它代你完成安装与验证。
一句话定位
DSH 的安全数学计算工具,让 AI 在做算术时不必每次都起一个 bash 进程,覆盖四则运算与常用初等数学函数,纯函数毫秒级返回结果。
核心能力
- 让 AI 调用
calculator工具直接对数学表达式求值,避免用 bash 算术每次起子进程 - 支持四则运算
+ - * / %、幂运算**(右结合)、一元正负、括号分组 - 提供 13 个单参函数(
absceilfloorroundsqrtloglog2log10expsincostan)和 2 个变参函数(pow(x, y)max/min) - 内置两个数学常量
PI和E - 严格安全模型:不使用
eval与new Function,手写递归下降解析器只接受白名单标识符与运算符 - 错误输入全部抛错:未知标识符、参数个数错误、非有限结果(NaN/Infinity)、非法字符、超长表达式都会失败而非静默返回
技术实现
- 语言: TypeScript(ESM 模式,tsc 编译到
lib/) - 关键依赖:
@deepseek-ai/cordis、@deepseek-ai/dsh-tools、@deepseek-ai/dsh-invariants - 架构模式: Cordis 插件模型(
name+inject: ['tools']+apply(ctx)),在apply中通过ctx.tools.register(defineTool(...))注册名为calculator的工具;插件安装由cordis.patch.yml用- insert:列表把tool-calculator条目插入目标 profile 的 layer 栈 - 入口文件:
src/index.ts(Cordis 插件入口与工具声明)/src/evaluate.ts(手写词法+递归下降求值器)/src/invariant.ts(包级 invariant companion)
适用场景
AI 频繁做算术、对一组数取最大/最小、或者需要做开方、对数、三角函数等超出 bash 算术能力的计算时,本工具以纯函数方式毫秒级返回结果,避免每个调用都付一次进程启动开销;尤其在 Windows 上替代 bash 算术收益明显。返回结果必须是有理意义的数字(NaN/Infinity 会被拒绝),适合做确定性计算的中间环节。
前置依赖与兼容性
| 依赖 | 最低版本 | 说明 |
|---|---|---|
| DSH | 0.1.0-rc.8+ | peerDependencies 要求 @deepseek-ai/dsh-tools 与 @deepseek-ai/dsh-invariants 在 [0.0.1-rc.1, 0.2.0),@deepseek-ai/cordis ^4.0.1;README 明确在 @deepseek-ai/[email protected] 隔离 consumer 完成全链路验证 |
| Node.js | >=22.19.0 | package.json#engines 声明 ^22.19.0 || >=24.0.0 |
| 平台 | macOS / Windows / Linux | 纯 TypeScript 实现,未声明任何原生模块;README 提示 Windows 路径使用正斜杠 |
| 原生模块 | 无 | 仅依赖运行时 JS 包,不引入 node-pty、node:sqlite 等原生模块 |
安装方式
dsh plugin --profile web add github:omdsh-dev/dsh-toolkit/packages/dsh-tool-calculator
配置项
本插件无需额外配置。calculator 工具的唯一输入是单次调用的 expression 字符串,源码中没有读取 config、process.env、options 等外部配置。
| 配置 | 类型 | 说明 | 默认值 |
|---|---|---|---|
| expression | string | 待求值的数学表达式,例如 "15 + 27 * sqrt(9)" | (每次调用必填,无默认值) |
常见问题
Q: 这个计算器安全吗?会不会执行用户输入的代码?
A: 安全。src/evaluate.ts 自带手写递归下降解析器(词法层+语法层),完全不使用 eval 也不使用 new Function。所有标识符通过 Object.hasOwn 查白名单(13 个单参函数 + 2 个变参函数 + 2 个常量),不在白名单的立即抛 Unknown identifier。词法层对引号、分号、反引号、{}、[]、.(独立形式)均直接报错;constructor.constructor(...)、process.exit(0)、globalThis、__proto__ 等攻击载荷在测试用例中被实测拒绝。
Q: 支持哪些运算和函数?
A: 算术:+ - * / % 和幂 **(右结合,例如 2 ** 3 ** 2 = 512);一元正负与括号分组;单参函数 abs ceil floor round sqrt log log2 log10 exp sin cos tan;多参函数 pow(x, y) 与 max/min(可变参数);常量 PI 与 E。
Q: 三角函数用的是角度还是弧度?
A: 弧度,与 Math.sin/Math.cos 行为一致;需要角度时写 sin(30 * PI / 180) 自行换算。
Q: 表达式长度有上限吗?
A: 有。evaluate() 入口处对 expression 长度做硬限制(MAX_EXPRESSION_LENGTH = 500),超过直接抛 Expression too long,避免被恶意大输入阻塞。
Q: 哪些输入会失败?会返回 NaN 吗?
A: 不会。parse() 求值后,若结果不是有限数字(NaN、Infinity,例如除零、sqrt(-1)、log(0)),evaluate() 会抛 Expression did not evaluate to a finite number;未知标识符、参数个数错误(sqrt(9, 1) / pow(2))、非法字符、引号/分号、科学计数法(1e5、6.02e23)、超长表达式也都会抛错,工具不会静默返回垃圾数字。
Q: 需要写配置吗?需要联网或读文件吗?
A: 不需要任何配置,所有逻辑都基于单次工具调用传入的 expression 字符串;实现是纯函数,不读文件、不写文件、不联网、不调子进程。也不依赖任何外部配置或环境变量。
Q: 跟 DSH 内置的 bash 算术(echo $((1+2)))比有什么差别?
A: bash 算术每次都要起一个 shell 进程,Windows 上进程创建+shell 加载代价明显,且 bash 算术不支持 sqrt sin cos log pow 等函数;本工具是纯函数毫秒级调用,覆盖常用初等数学函数,AI 不必为求一个开方再写脚本。
Q: 装到 web profile 后,dsh run 能直接用到吗?
A: 不能。web 与 headless 是两个独立的 profile,本插件需要单独装到 headless(dsh run 默认使用),或者用集合仓库自带的批量脚本一次性同时装到两边。
上手难度
入门 — 安装一行命令即生效,AI 在对话里按需调用 calculator 工具并传入表达式即可,无需写配置或脚本;理解白名单运算与三角函数用弧度即可避免踩坑。
已知问题与限制
- 表达式长度上限 500 字符,超出直接拒绝(
src/evaluate.ts:42、src/evaluate.ts:168-170) - 数字结果受 IEEE 754 双精度浮点限制,安全整数范围约 ±9e15,超出会有精度损失,不适合做大整数运算(
README.md:185) - 不支持科学计数法,
1e5、6.02e23会被词法层专门拒绝并提示'Scientific notation is not supported'(src/evaluate.ts:53-56、tests/evaluate.spec.ts:140-146) - 三角函数使用弧度而非角度,需要角度需自行乘
PI/180换算(README.md:184) - 工具调用超时
timeoutMs: 1000(src/index.ts:36),单次求值超过 1 秒会被宿主中断 - 函数参数个数由白名单严格约束,
pow必须恰好 2 个、sqrt必须 1 个,max/min至少 1 个,否则抛Invalid argument count(src/evaluate.ts:142-147) - 仓库内未发现 TODO/FIXME/HACK/XXX 注释
DSH 零依赖工具包 collection —— time / encoding / json / calculator / csv / regex / markdown / diff / stat / schema 十个确定性工具,统一入口一键安装。
为什么
DSH 生态仓库持续增长,单插件在 hub 中容易被淹没;collection 分类是辨识度最高的形态。本仓库把 10 个工具插件 vendored 冻结为 pack artifact 快照(各子仓库独立演进,当前源位于 omdsh-dev 组织下),统一工程、统一测试、统一维护。
定位(官方 Profile Bundle 生态方向):本仓库是 collection 与安装辅助仓库——每个子包都是可独立安装/启用/禁用/卸载的 bundle(dsh plugin --profile <p> add <子包>);collection 提供目录、清单与批量安装脚本。meta 包 @deepseek-ai/dsh-toolkit 保留为可选的原子挂载模型(见下文两种运行模型)。
分发边界:根 meta 包保持 private: true,用于 Git/collection 分发,不代表会发布到 npm registry。根目录已提交由当前 src 构建出的 lib/index.js 与 lib/types/index.d.ts,因此从 Git 安装时不依赖消费端 lifecycle;prepack 仍会在生成 pack artifact 前执行完整构建。
工具一览
| 工具 | 能力 | 用例数 |
|---|---|---|
time | ISO 8601 / 时区 / 日历运算 / 时长差 | 65 |
encoding | base64 / url / hex / hash / UUID | 46 |
json | JMESPath 子集查询 | 66 |
calculator | 安全数学表达式求值(无 eval) | 31 |
csv | RFC 4180 解析 / 查询 / 统计(严格引号) | 50 |
regex | 测试 / 提取 / 替换 / 静态解释(worker 硬超时) | 63 |
markdown | HTML↔Markdown / GFM 表格 / 目录生成(白名单安全) | 71 |
diff | 文本/JSON/CSV/Markdown 结构化比较与 unified diff(只读) | 124 |
stat | 描述统计 / 百分位数 / 频数分布 / 相关性(零依赖确定性) | 82 |
schema | JSON Schema 验证 / 路径 / 解释 / 安全 default(零网络零动态) | 125 |
| 合计 | 723 |
架构
dsh-toolkit/
├── src/index.ts # meta 包:相对路径动态导入 10 个子包 apply(),聚合注册
├── packages/dsh-tool-* # vendored 子包(pack artifact 快照,name 保持 @deepseek-ai/dsh-tool-*)
├── scripts/
│ ├── link-deps.sh # 构建期 junction(cordis → vendor/cordis,dsh-tools → packages/core/tools)
│ ├── build-all.sh # 一键构建 10 子包 + meta 包(tsc)
│ ├── test-all.sh # 一键跑 10 子包 vitest(合计用例数)
│ ├── install.sh # meta / 逐包两种挂载模式(含 dry-run)
│ ├── install-web.sh # 独立 bundle 批量安装 → web profile
│ ├── install-headless.sh # 独立 bundle 批量安装 → headless profile
│ └── install-all.sh # web + headless 都装
├── catalog.json # collection 清单(hub collection 分类识别依据)
└── tsconfig.base.json # 共享编译配置(固化踩坑经验)
与实施文档方案 A 的工程化适配:子包为私有 Git/collection 包,peer 名解析在 profile 内不可行, 故 meta 包采用相对路径动态导入(零解析魔法、打包自足);子包 runtime 依赖 (
@deepseek-ai/dsh-tools)在 npm 独立模式(默认)下不依赖 DSH monorepo,monorepo 模式经子包构建期 junction 解析。
安装
仓库位于 omdsh-dev/dsh-toolkit(public)。
独立 bundle 模型(推荐)
每个子包独立安装、启用、禁用、卸载:
# 安装单个工具到 web profile
dsh plugin --profile web add github:omdsh-dev/dsh-tool-csv
# 一次性任务(headless)profile
dsh plugin --profile headless add github:omdsh-dev/dsh-tool-diff
批量安装(collection 辅助脚本,幂等——重复执行不会重复添加):
./scripts/install-web.sh # 全部 10 工具 → web profile
./scripts/install-headless.sh # 全部 10 工具 → headless profile(dsh run 使用面)
./scripts/install-all.sh # 两个 profile 都装
验证与运行:
dsh --profile web --dump-config | grep tool-csv # 行存在即安装成功
dsh run "使用 csv 工具解析 'a,b\n1,2'" # headless 端到端
⚠️ web 与 headless 是不同 profile:web 安装不会自动覆盖 headless;
dsh run默认使用 headless。 Windows 路径使用正斜杠(C:/...)。
npm pack tarball 安装
本地构建后用 tarball 路径安装(不依赖 GitHub):
# tarball 方式(web 为例;headless 同)
npm pack
dsh plugin --profile web add <npm pack 产物 tarball 路径>
meta bundle 模型(可选)
需要一次原子挂载全部工具时,挂载根 meta 包:
dsh plugin --profile web add github:omdsh-dev/dsh-toolkit
dsh --profile web --dump-config | grep tool-kit
⚠️ 若 profile 已单独挂载过同名插件(tool-time/.../tool-diff/tool-stat/tool-schema),挂 meta 包会注册重名报错—— 此时先移除旧插件,或用独立 bundle 模型。meta apply 具备原子性(任一子插件失败时 逆序回滚已注册工具,不残留部分状态)。
手动安装与旧版本兼容
旧场景(monorepo 集成、不支持 Profile Bundle 的旧快照或插件开发调试环境——本地 junction/symlink、手动编辑 profile 层)。
构建与测试
npm 独立模式(默认,推荐):无需 DSH monorepo;npm install(devDependencies 自包含)后即可:
npm run build:all # 10 子包 + meta 包 tsc + 产物完整性验证(无 .ts 残留导入、10+1 个 lib/index.js)
bash scripts/test-all.sh # 10 子包 vitest 全量(723 用例);任一失败整体非零退出
npm pack # prepack 自包含(build:all),tarball 含 lib + 10 个子包
monorepo 模式(可选:源码贡献/旧 snapshot):显式提供 DSH monorepo 根:
export DSH_MONOREPO=<DSH 0.1.0-rc.8(npm)安装路径> # 或作为第一个参数
bash scripts/build-all.sh # link-deps + 10 子包 + meta 包 tsc + 产物完整性验证
bash scripts/test-all.sh
prepack已指向build:all(完整构建 10 子包 + meta),保证 pack artifact 含全部运行入口;根 Git 入口由当前src预构建并提交。 本仓库只在本地验证构建、测试与 pack artifact;不要将这些结果解读为 npm registry 发布或未实际执行的 consumer/profile 验证。
同步 vendored(子仓库有更新时)
把 packages/<name> 与源仓库重新同步(src/tests/package.json/tsconfig/cordis.patch.yml/LICENSE/README.md),并在 README 标注子包版本。
新增工具
见 docs/CONTRIBUTING.md:复制模板子包 → 实现 → 测试 → build-all 验证 → 更新 catalog.json。
许可
MIT
查看使用指南 →
该插件的安装步骤、关键要点、FAQ 与兼容性说明(基于已收录字段派生)。
收录徽章
[](https://deepseek-plugin.org/plugins/omdsh-dev/dsh-toolkit/packages/dsh-tool-calculator)把这段 markdown 粘贴到你的 GitHub README,链接回本插件详情页。徽章只声明已被本站收录,不代表安全认证。