npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

dsh-auto-thinking-levels

v0.1.2

Published

DSH Host plugin: keep every llm-pi-ai provider route offering the full thinking-level set by writing the missing reasoningEfforts tables into that namespace's settings.

Readme

dsh-auto-thinking-levels

DeepSeek Harness (dsh) 的 Host 插件: 自动给每个提供商、每个模型补上完整的思考等级表(reasoningEfforts),不用再逐模型手写。

English TL;DR — A dsh Host plugin that keeps every llm-pi-ai provider route offering the full thinking-level set. It writes the missing reasoningEfforts tables into that namespace's settings layer, so both the model selector and the request path agree on which levels exist. Add-only and idempotent: it never rewrites a level you already spelled, never removes an entry, and never touches a model that declares reasoningEfforts: false.

reasoningEfforts:
  { off: null, minimal: minimal, low: low, medium: medium, high: high, xhigh: xhigh, max: max }

为什么写配置层,而不是去 patch adapter

llm-pi-ai 在物化模型时读一次 reasoningEfforts,把它翻译成 pi-ai 描述符上的 thinkingLevelMap(resolveModelReasoning)。之后所有判断都只从这张 map 出发:

  • getSupportedThinkingLevels() 决定选择器显示哪些档位;
  • 同一个函数守着请求路径,map 里没有的档位在发出任何 I/O 之前就以 UNSUPPORTED_REASONING_EFFORT 被拒。

所以只包一层 adapter 的 resolveModel 只能改到第一个答案、改不到第二个 —— 用户会选到 一个真正发请求时被拒的档位。把表写进配置层,是让配置本身正确,两个答案都从它推导, 且任何一次重载后依然成立,不需要重新打补丁。

写入走 settings.update:候选值会先过该命名空间自己的 schema 与 assertServiceable 校验,注入不合法时什么都不落盘。

安装

dsh plugin --profile <name> add dsh-auto-thinking-levels

插件自带 dsh.bundle.patch,安装后自动挂一行,不需要手改 cordis.patch.yml。

想改配置的话,在 profile 的 cordis.patch.yml 里用 id 定向 patch 覆盖那一行即可; 改完用 set_bundle 关掉再打开,这一行就会用新配置重新挂载。

配置

全部字段可选,默认值见下表。

| 字段 | 默认 | 含义 | | --- | --- | --- | | namespace | llm-pi-ai | 要配置的 settings 命名空间(dsh-llm-pi-ai 的 NS) | | fill | complete | complete 把档位不足的模型补齐(已写过的档位保留你的原值);missing 只补完全没有表的模型,尊重刻意的子集 | | levels | 七档全表 | 要写入的表;值是发给网关的线材拼写,off: null 表示「支持,但不发送该参数」 | | providers | [] | 路由白名单,空 = 全部已注册路由 | | enabled | true | false 时挂载但不动配置 |

行为

只做新增,绝不覆盖:

  • 已有部分档位的模型(fill: complete):补齐缺失的档位,已写过的档位保留你的原值;
  • 声明 reasoningEfforts: false 的模型:false 是「此模型不推理」的明确答复,永不填充;
  • 其余任何字段、任何条目都不会被删改。

因此是幂等的:第二遍扫描找不到要补的,就不写、不发事件,自然收敛。

插件会监听该命名空间的变更与 adapter 拓扑变化,所以在 GUI 新增模型,或修改 profile 的 cordis.patch.yml 后,它会自动补齐。

DSH 0.1.7 的配置通知可能从 HMR 事务内发出。插件会退出该事务的异步上下文, 再通过 settings.update 正常排队写入,避免 HMR transactions cannot be nested。 单纯加 setTimeout 或微任务不能解决此问题,因为它们会继承原事务上下文。 连续保存造成 revision 冲突时,已收到的新变更通知不会丢弃:下一遍重新读取最新配置, 不会用旧模型列表覆盖新模型。已有档位、自定义值和显式 false 仍按上述规则保留。

两种路由

  • 声明了 models 的路由:逐条 entry 补表。
  • 没有 models 的路由(catalog 路由):只能通过 modelOverrides 表达,因此按 ctx.llm.listModels(route) 实际服务的模型逐个补 —— adapter 会拒绝命名 catalog 里不存在的模型,所以这里用真实服务列表而不是去猜 catalog。 两种方式互斥:models 旁边放 modelOverrides 会被 adapter 拒绝。

已知边界

HMR 事务兼容已在 DSH 0.1.7-rc.1 验证,目前需要访问该版本的内部 hmr.executing(AsyncLocalStorage);不是稳定公开的跨版本接口,升级 DSH 后需重新验证。 卸载后不会再提交新的补全写入;已交给 settings.update 的写入由宿主完成,插件不会在卸载时等待它, 避免和 HMR 的串行队列互相等待。

本插件只配置 llm-pi-ai 命名空间。其它 adapter 不在作用域内,且有些无法被配置:

deepseek-official(llm-deepseek adapter)拿不到七档 —— 它的档位写死在 adapter 里 (off/low/high/max),线材校验函数 reasoningEffort() 对其余值直接抛 UNSUPPORTED_REASONING_EFFORT;它的 settings schema 也只有 provider 级 reasoningEffort, 没有 per-model 表。这是官方 API 自己的线材词汇(medium 会收敛到 high),不是配置能改的。 强行为它注入 minimal/medium/xhigh 只会把请求打成必然失败。

验证

verification/probe-result.json 是一次性探针在运行中的 harness 上抓的实测结果:对每个 已注册路由/模型调用 llm.resolveModelInfo(选择器看到的档位)与 llm.resolveCallConfig(请求路径是否接受该档位)。

## provider: cpa
   deepseek-v4-flash-0731   efforts: off/minimal/low/medium/high/xhigh/max   rejected: none
   glm-5.3-flash            efforts: off/minimal/low/medium/high/xhigh/max   rejected: none
   deepseek-flash           efforts: off/minimal/low/medium/high/xhigh/max   rejected: none
   gpt-6-astra              efforts: off/minimal/low/medium/high/xhigh/max   rejected: none
   claude-fable-5-1         efforts: off/minimal/low/medium/high/xhigh/max   rejected: none
   glm-5.3-flashx           efforts: off/minimal/low/medium/high/xhigh/max   rejected: none

## provider: deepseek-official
   deepseek-flash           efforts: off/low/high/max   rejected: minimal,medium,xhigh
   deepseek-v4-pro          efforts: off/low/high/max   rejected: minimal,medium,xhigh

(resolveModelInfo 里的 auto 由另一个插件注入,不属于本插件。)

开发

npm test          # node:test,零依赖;含 HMR 事务及连续保存回归
npm run check:pack   # 断言 npm publish 会打包哪些文件

lib/plan.js 是纯决策逻辑(可测、无 I/O),index.js 只负责读写 settings 与事件触发。

发布

发布走 tag:

npm version patch        # 0.1.1-rc.1 -> 0.1.1,或 npm version prerelease --preid rc
git push --follow-tags

.github/workflows/publish.yml 会校验 tag 与 package.json 版本一致、跑测试、断言打包内容、 以 provenance 发布到 npm,并开一个 GitHub Release。只由 tag 触发,从分支上发不出任何东西。

dist-tag 由版本号推导,不写死

| package.json 版本 | dist-tag | npm i dsh-auto-thinking-levels 会拿到它吗 | | --- | --- | --- | | 0.1.1 | latest | 会 | | 0.1.1-rc.1 | rc | 不会 | | 1.0.0-beta.2 | beta | 不会 | | 2.0.0-next | next | 不会 | | 3.0.0-preview.1 | next(并告警) | 不会 |

这一步是必需的,不是风格问题:npm 拒绝在没有显式 --tag 时发布 prerelease (You must specify a tag using --tag when publishing a prerelease version.), 所以 0.1.1-rc.1 走裸的 npm publish 必然失败;同时这条规则保证了 rc 永远顶不掉 latest。 推导逻辑由 test/release-dist-tag.test.js 直接抽出 workflow 里的脚本执行验证。

想先看不发,或者想确认 OIDC 登记好了没有:在 Actions 页面手动 dispatch Release, dry_run 默认为 true —— 测试、tarball 断言、OIDC 换取都会真跑,只有 npm publish 带 --dry-run。 所以一次 dry run 就能回答"这个仓库现在能不能发布"。

注意 npm 的重复版本检查在 --dry-run 下同样生效:如果 package.json 的版本已经发布过 (比如刚发完 0.1.1,而工作区版本号还是 0.1.1),dry run 会在 Publish 步骤报 You cannot publish over the previously published versions: 0.1.1. —— 这是预期行为, 不是流水线坏了;要 dry run 一个已发布的版本,先升版本号。

发布后的回读是轮询的:npm 会对 publish 回一句 "Your package is being processed and may take a few minutes to become available",读副本滞后(实测 0.1.1 是 131 秒)。轮询 5 分钟仍没等到时只 ::warning:: 而不失败,因为发布是否成功以 Publish 步骤的输出(registry 接受 + provenance 签名)为准, 把已发布的版本标成红会误导人。

凭据:npm Trusted Publishing(OIDC),没有 secret

发布不用任何长期 token。job 里的 id-token: write 让 npm 用这次运行的 OIDC 身份换取一个 短时效发布令牌(trusted publishing), 公开仓库 + 公开包还会自动开启 provenance。仓库里不存在 NPM_TOKEN, test/release-dist-tag.test.js 会断言工作流里不出现任何 token 注入。

代价是必须先登记一次信任关系——在 npmjs.com 的包设置里填(workflow 文件名必须仍是 publish.yml):

| 字段 | 值 | | --- | --- | | Organization or user | lolkda | | Repository | dsh-auto-thinking-levels | | Workflow filename | publish.yml | | Environment | 留空 |

这一步必须走网页:命令行配不了。npm trust github 会被 npm 拒绝, 因为能发布包 ≠ 能改包的安全设置:

$ npm trust list dsh-auto-thinking-levels
npm error 401 Unauthorized - GET https://registry.npmjs.org/-/package/dsh-auto-thinking-levels/trust
$ npm trust github dsh-auto-thinking-levels --file publish.yml --repo lolkda/dsh-auto-thinking-levels --allow-publish
npm error 401 Unauthorized - POST https://registry.npmjs.org/-/package/dsh-auto-thinking-levels/trust

(上面两条都是用一个 granular token 跑的,npm whoami 正常但改安全设置就是 401。)

没登记之前,发布会被 workflow 里那道 preflight 明确拦下,而不是给一个看不懂的 ENEEDAUTH:

::error::npm refused the OIDC token exchange (HTTP 404)
Register the trusted publisher at https://www.npmjs.com/package/dsh-auto-thinking-levels/access

这道 preflight 就是 npm publish 内部会做的同一次 OIDC 换取,只是提前跑、并且自己解释失败原因; 它成功打印 npm accepted the OIDC token exchange for dsh-auto-thinking-levels 才继续发布。

License

MIT