dsh-deepseek-billing-period

toolstested: passnpmMIT

DeepSeek API billing-period chip in the composer dock: shows whether the current time is peak or off-peak with a countdown to the next rate switch, opens the peak/off-peak window rules on click, and during peak hours intercepts sending to ask for confirmation first.

下载量 / Downloads
1,293
依赖体积 / node_modules
0.37 MB
测试时间 / Tested
2026-11-06
DSH 版本 / Version
0.2.2-rc.1

Install

dsh plugin --profile web add dsh-deepseek-billing-period

Sandbox test results

StageResult
1 install✓
2 list✓
3 mount✓
4 boot—

Four stages run in an isolated sandbox: install (network on) → list → mount → boot (last three with no network).

README

dsh-deepseek-billing-period

一个 DeepSeek Harness(dsh)Web 插件:在输入框下方常驻显示当前 DeepSeek API 计费时段 —— 是高峰(全价)还是空闲(半价),以及距离下一次时段切换的倒计时。

  • 药丸实时刷新,倒计时精确到分,每秒更新。
  • 点击药丸会在其正上方弹出浮动的规则说明卡片,不占用输入框布局(展开前后输入区尺寸逐像素不变);点击卡片外部任意位置或按 Esc 关闭。
  • 卡片表面与宿主自带的 composer 浮层(如"上下文已用 …%")保持同一套观感:半透明底、发丝描边、柔和投影、--dsw-radius-lg 圆角。
  • 浅色 / 深色主题自适应:卡片底色、描边、投影全部取自宿主 --dsw-* 令牌(--dsw-specific-menu、--dsw-elevation-prominent 等),不写死任何颜色;确认弹窗直接复用宿主自带的 Modal / Button / Checkbox 组件(宿主未提供时才回退到同套令牌自绘的对话框),观感与主题完全随宿主。
  • 高峰时段发送前确认:高峰(全价)时段按下 Enter 或点击发送按钮时先弹确认框(取消 / 确认发送),并可在弹窗内勾选"以后不再询问",随时用规则卡片底部的开关恢复;新建的空白会话中同样生效。
  • 判定恒按北京时间(UTC+8) 换算,与浏览器所在时区无关;中英文案随界面语言切换,节假日名称也会本地化。
  • 节假日不再硬编码:运行时从免费的在线日历 holiday-cn 获取当年与下一年的法定节假日及调休安排,按年自动更新;数据在本地缓存,离线或数据源不可用时自动回退为"仅按周一至周五判断",并在卡片中注明当前数据状态。

截图

· 浅色 · 深色

规则卡片 · ![计费时段规则卡片 · 浅色](./screenshots/billing-period-light.png) · ![计费时段规则卡片 · 深色](./screenshots/billing-period-dark.png)

高峰发送确认 · ![高峰时段发送确认 · 浅色](./screenshots/peak-confirm-light.png) · ![高峰时段发送确认 · 深色](./screenshots/peak-confirm-dark.png)

计费规则

时段 · 判定 · 价格

高峰 · 北京时间周一至周五 09:00–12:00、14:00–18:00,且当天不是中国法定节假日 · 全价

空闲 · 其余全部时间,包含周末与法定节假日全天 · 高峰价格的一半

  • 两个窗口均为左闭右开:09:00 起进入高峰,12:00 / 18:00 起离开高峰;午休 12:00–14:00 属空闲。
  • 规则与 DeepSeek 官方文档一致:北京时间周一至周五(不含中国法定节假日)的 09:00–12:00、14:00–18:00 为高峰时段,其余时间(含周末与法定节假日全天)为空闲时段,见 DeepSeek 价格页。
  • 只需收录"放假"的日期:周末本身全天空闲,因此调休补班落在周末也不影响高峰判定(这类周末仍按空闲处理)。
  • 未收录年份(例如国务院尚未公布放假安排的年份)自动回退为"仅按周一至周五判断",并在展开卡片中明确写出该提示,不会静默给出错误的"高峰"结论。

节假日数据来源

  • 数据源:NateScarlet/holiday-cn(MIT 许可)。该仓库由 CI 每日抓取国务院办公厅的放假通知,按年生成 JSON,包含全部法定节假日与调休补班安排。
  • 获取方式:浏览器直接 fetch,不需要 API Key,也不经过 dsh 宿主代理。三个可跨域(CORS)的镜像并发竞速,第一个返回合法数据的镜像胜出,其余请求立即中止:

1. https://cdn.jsdelivr.net/gh/NateScarlet/holiday-cn@master/<年份>.json

2. https://fastly.jsdelivr.net/gh/NateScarlet/holiday-cn@master/<年份>.json

3. https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/<年份>.json

单次请求超时 8 秒;某个镜像返回 404、非 JSON 或格式错误时只是输掉竞速,不影响其他镜像。

  • 格式与校验:上游文件形如 { "year": 2026, "papers": ["…"], "days": [{ "name": "元旦", "date": "2026-01-01", "isOffDay": true }] }。插件会校验年份是否与请求一致、days 是否为数组、每个日期是否为真实存在的 YYYY-MM-DD。days: [] 的占位文件视为"当年安排尚未公布",而不是"当年没有节假日"。
  • 本地缓存:保存在 localStorage 的 dsh-deepseek-billing-period.holidays.v1 键中。已公布年份缓存 7 天,未公布占位缓存 6 小时;过期后先展示缓存、再后台刷新(stale-while-revalidate)。只缓存当前年份前 1 年到后 2 年,更早或更晚的年份自动清理。
  • 刷新时机:插件加载、组件挂载以及每 5 分钟检查一次,始终维护当年与下一年的日历;卡片底部的「刷新节假日数据」按钮可强制重新拉取。
  • 失败与回退:全部镜像失败且本地没有可用缓存时,记录一次失败并在 60 秒内不重试,卡片显示"暂时无法访问",此时判定回退为仅按周一至周五;若本地已有缓存,则继续用缓存数据判断(卡片照常显示上次更新时间),并在后台自动重试。数据恢复后自动切回在线日历判定。跨年的 12 月日期可能收录在下一年的通知文件里,插件会合并两年数据;但"该年已收录"仍以该年自己的通知文件为准,未收录时卡片明确提示。
  • 隐私:插件只向上述 jsDelivr / GitHub 地址发起 GET 请求,不发送任何 API Key、会话内容或用户数据;节假日数据也不上报到任何地方。

高峰时段发送前确认

高峰时段(全价)内,Enter 与发送按钮都会先被拦下并弹出确认框:

  • 取消(或 Esc / 点遮罩):不发送,草稿原样保留,光标回到输入框。
  • 确认发送:按原样把消息发出去(复用的是宿主自己的发送逻辑,不绕过任何宿主行为)。
  • 弹窗底部有一个默认不勾选的「以后高峰时段不再询问」。勾选后再点"确认发送",以后高峰时段就直接发送、不再弹窗;偏好存在浏览器 localStorage 的 dsh-deepseek-billing-period.prefs 里。
  • 想重新开启确认:展开计费时段规则卡片,打开底部的「高峰时段发送前确认」开关(点开关或旁边的文字均可)即可,无需刷新页面;开关会实时反映弹窗里或其他标签页中做的修改。
  • 只会拦下"真的要发送消息"的手势:空闲时段、/ 开头的斜杠命令、Shift+Enter 换行、发送按钮处于禁用状态(空草稿、附件仍在上传等)都不受影响;页面上输入框以外的其他文本框(以及其他插件挂在输入框浮层里的编辑器)里按 Enter 也不会被拦截。
  • 拦截逻辑挂在宿主的 conversation.input.dock 上,因此新建的空白会话在第一句话发送前就已经生效;计费药丸本身仍挂在 conversation.composer.dock,宿主只在会话进入正常状态后才渲染它。

安装方法

前置:已安装 dsh 并启用 web profile(本插件在 dsh 0.2.x / Node v26 上验证)。

方式一:从 npm 安装(推荐)

dsh plugin --profile web add dsh-deepseek-billing-period

方式二:从 GitHub 安装

dsh plugin --profile web add github:zi7tian/dsh-deepseek-billing-period

dsh plugin add 会在该 profile 内执行安装,并把声明了 bundle 的包追加到 dsh.profile.bundles。完成后重启 dsh web,刷新页面即可在输入框下方看到计费时段药丸。

方式三:本地克隆后 link(便于改代码)

git clone https://github.com/zi7tian/dsh-deepseek-billing-period.git
dsh plugin --profile web add link:/path/to/dsh-deepseek-billing-period

用 link: 安装时,直接编辑 checkout 里的 client.js 并在浏览器刷新页面即可生效,无需重装或重启 dsh web。

卸载

dsh plugin --profile web remove dsh-deepseek-billing-period

安装成功的标志

打开任意一个已进入正常状态的会话,输入框下方会出现:

● 空闲时段 · 半价 · 距高峰 12 小时 42 分

点击它即可展开上方那张规则说明卡片。

测试

node test/logic.test.mjs

测试不访问网络:2025 / 2026 年的真实日历以 fixture 形式内嵌,镜像竞速与回退、缓存、失败退避、占位年份、跨年日期合并等主要路径通过 mock fetch 覆盖;另有假 DOM 测试覆盖消息手势的编辑器 / composer card 解析,以及 apply() 同时注册 conversation.composer.dock 与 conversation.input.dock 两个 slot。当前共 162 个断言。

更新日志

1.3.0

  • 节假日判定改为运行时从 holiday-cn 在线日历获取,每年自动更新,不再把放假安排硬编码进 client.js。
  • 三镜像并发竞速 + 8 秒超时 + 本地缓存(7 天 / 占位 6 小时)+ 失败退避(60 秒),新增「刷新节假日数据」按钮。
  • 规则卡片新增数据状态行(已收录并显示更新时间 / 正在获取 / 尚未公布 / 暂时无法访问),并保留未收录年份的显式回退提示。

1.3.1

  • 修复:新建的空白会话(hero 输入框)中,高峰时段按 Enter 或点发送按钮不会弹出确认框。拦截逻辑改挂在宿主 conversation.input.dock(空白会话也会渲染),计费药丸仍留在 conversation.composer.dock;手势识别改为从 event.target 反推编辑器与 composer card,不再依赖药丸所在节点。
  • 面板上的「高峰时段发送前确认」开关改为每次发送时读取 localStorage 偏好,切换后立即生效。
  • 测试:新增假 DOM 的手势解析测试与 apply() 双 slot 注册断言(130 → 149)。

1.3.2

  • 修复:高峰时段在页面上任何文本框(输入框以外的编辑框、设置项等)按 Enter 都会被误拦并弹出发送确认。现在只认输入框卡片里唯一的那个草稿编辑器。
  • 修复:在弹窗里勾选"不再询问"后,规则卡片底部的开关仍显示为开启,需要点两次才能真正恢复确认;开关现在会跟随本页和其他标签页的偏好修改实时更新。
  • 修复:弹窗复选框文案与效果相反(写的是"是否需要每次确认",勾选后却是不再询问),改为「以后高峰时段不再询问」。
  • 修复:发送按钮处于禁用状态(空草稿、附件上传中等)时按 Enter 不再弹出确认。
  • 细节:弹窗内按 Esc 不再继续传给宿主;卡片底部开关旁的文字也可点击切换。
  • 测试:149 → 162 个断言。

许可证

[MIT](./LICENSE)

Rendered from the README published on npm. Formatted only, not edited.

Versions

Published on npm::5,最后更新 2026-11-03

Links

GitHub · Homepage · npm

Same category