dsh-deepseek-offpeak-indicator
Verifieddsh-deepseek-offpeak-indicator · v1.1.0 · MIT · Web UI
DeepSeek Harness plugin: a small dot left of the model name in the composer tool row — yellow for DeepSeek peak hours, green for off-peak (half price). Rendered only when the session's model provider is DeepSeek.
Install
dsh plugin add dsh-deepseek-offpeak-indicator Confirm the layer applied with dsh --profile default --dump-config — see the install guide.
Source
Tags
Creators
Readme
dsh-deepseek-offpeak-indicator
在 DeepSeek Harness(DSH)Web GUI 里一眼看出当前 DeepSeek API 的计费时段。
输入框工具行里、模型名左侧常驻一颗 5px 小圆点(仅当当前会话选中的模型 provider 属于 DeepSeek 时才渲染):
| 颜色 | 时段 | 价格 |
|---|---|---|
🟡 黄 #f2b705 |
高峰时段 | 标准价 |
🟢 绿 #22c55e |
空闲时段 | 半价 |
除颜色外不显示任何文字、图标或占位文案(圆点带 aria-label,屏幕阅读器可读)。
不需要构建步骤,也不依赖任何第三方库;全部逻辑在一个单文件里。
English | 中文
显示条件
只有当前会话选中的模型 provider 属于 DeepSeek 时才渲染;其余情况下彻底不渲染,不占位:
| provider | 显示 |
|---|---|
deepseek-official(DeepSeek 官方 API Key) |
✅ |
deepseek-account(DeepSeek 账号) |
✅ |
| 其他(Anthropic、OpenAI 兼容中转、自建网关……) | ❌ 不渲染 |
| 未知(模型目录尚未加载完) | ❌ 不渲染 |
只看 provider,不看模型名——第三方中转即便转发的是 DeepSeek 模型,也不适用 DeepSeek 的分时计价。
判定逻辑是 isDeepSeekProvider(),想改口径只动这一个函数。
模型目录是在挂载之后延迟解析、失败重试的:刚切换过去的会话还没注册 scope,这一次查找 本来就会失败。因此圆点会在切换会话后的零点几秒内出现,而不是整段会话都不显示。
判定规则
依据 DeepSeek 官方定价说明(模型 & 价格):
- 高峰时段:北京时间周一至周五(不含中国法定节假日)9:00–12:00、14:00–18:00;
- 空闲时段:其余全部时间,包括周末与法定节假日全天(空闲价 = 高峰价的一半)。
边界按左闭右开处理:12:00 与 18:00 整点即进入空闲时段,9:00、14:00 整点即进入高峰时段。
时间一律按 Asia/Shanghai 计算,改本机时区不影响结果。
关于"调休上班的周末":官方原文是"周一至周五……其余时段,包括周末及中国法定节假日 全天均为空闲时段",因此调休上班的周六/周日仍按空闲时段(绿色)处理。若你认为应当算高峰, 改
client.js里的WORKDAYS判定即可。
安装
前置:一个可用的 DSH profile(桌面版或 dsh web 均可),并且已能正常启动会话。
推荐在插件页里填个 GitHub 地址就装好,不用克隆、不用敲命令:
点开侧边栏的**「插件」**页(面板列表里的插件图标)。
点**「添加插件」**。
在输入框里填入下面这个地址(它接受包名、GitHub 仓库地址或本地目录路径):
https://github.com/cumthugo/dsh-deepseek-offpeak-indicator简写
github:cumthugo/dsh-deepseek-offpeak-indicator同样可以;想锁定版本就带上分支或提交号, 例如github:cumthugo/dsh-deepseek-offpeak-indicator#<commit-sha>。装完即生效:结果是
application: applied,当前页面无需刷新;若提示restart-required, 重启 Harness 即可。
安装器会自动把它写进 profile 的 dsh.profile.bundles 与依赖,并按仓库自带的
cordis.patch.yml 插入 Loader 条目——你不需要手工改任何配置文件。
让 Agent 安装(等价做法)
plugin_manager action=install_bundle target=github:cumthugo/dsh-deepseek-offpeak-indicator
安装前安装器会对仓库做一次 git ls-remote 连通性检查(公开仓库无需凭据)。
本地目录安装(要改代码时用)
克隆到本地:
git clone https://github.com/cumthugo/dsh-deepseek-offpeak-indicator.git把克隆下来的绝对路径填进同一个输入框(或交给 Agent):
plugin_manager action=install_bundle target=/绝对路径/dsh-deepseek-offpeak-indicatorprofile 里会记成
link:依赖,改完源文件重装一次即可生效。
更新:重复安装同一个安装源不会生效——依赖串没变化,安装器会报 ambiguous-install。
正确做法是先在插件页卸载,再用同一个地址重装一次:
plugin_manager action=remove_bundle target=dsh-deepseek-offpeak-indicator
plugin_manager action=install_bundle target=github:cumthugo/dsh-deepseek-offpeak-indicator
宿主会重新读取 bundle 并推给已打开的页面,无需重启。(本地目录装法同理,把第二行的 target
换成克隆路径即可;换一个安装源也能绕过,比如从本地目录切到 GitHub 地址。)
停用/卸载:在 GUI 插件页关闭该条目,或让 Agent 执行 plugin_manager 的
remove_bundle(包名 dsh-deepseek-offpeak-indicator)。
包名与仓库同名(
dsh-deepseek-offpeak-indicator),没有发布到 npm,按上面的本地路径或 GitHub 方式安装即可。包名必须与client.js里window.__ModuleLoader__.load({ id })的id、 以及cordis.patch.yml条目的name完全一致——改一处就要三处一起改,并重装。
节假日数据与自动更新
节假日只用于"把放假日从高峰里排除",共三层来源,按优先级取用:
- 本地缓存:
localStorage的dsh-deepseek-offpeak-indicator:holidays:<年>,30 天内视为新鲜; - 联网刷新:holiday-cn(自动抓取国务院办公厅
放假安排)的年份 JSON,依次尝试
raw.githubusercontent.com与cdn.jsdelivr.net,6 秒超时; - 内置兜底:
client.js里的BUILTIN_HOLIDAYS(当前含 2026 年,33 个放假日)。
因此次年安排一公布就会自动生效,无需改代码——前提是机器能访问上述两个地址之一。 完全离线时回落到内置表;若某年既无缓存也无内置数据,则退化为"只按周末判断"(该年节假日的 9:00–12:00 / 14:00–18:00 会被误判为高峰)。
想离线更新内置表:
node tools/update-holidays.mjs # 刷新已有年份 + 今年和明年
node tools/update-holidays.mjs 2027 # 只刷新指定年份
改完按上面的"更新"流程走一趟(remove → install),页面才会用上新的内置表。
文件结构
| 文件 | 作用 |
|---|---|
package.json |
bundle 清单:dsh.bundle.patch 指向补丁,dsh.client 声明浏览器半边 |
cordis.patch.yml |
向 profile 插入一行 deepseek-offpeak-indicator 条目 |
index.js |
Host 半边,空 apply()(仅为让 Loader 有对应条目) |
client.js |
浏览器半边:时段判定 + 圆点组件 + 槽位注册(单文件、无构建) |
tools/update-holidays.mjs |
重新生成内置节假日表 |
tools/test-classify.mjs |
回归测试:时段判定、provider 判定,以及切换会话时的解析重试(31 项断言) |
自定义
都在 client.js 顶部:
PEAK_WINDOWS:高峰区间(当日分钟数);PEAK_COLOR/OFFPEAK_COLOR:两种颜色;DOT_SIZE:圆点直径(默认5);DEEPSEEK_PROVIDER_IDS/isDeepSeekProvider():哪些 provider 算 DeepSeek;- 槽位与位置:默认
conversation.input.right(正好渲染在模型名左侧),nudgeX/nudgeY做像素级横纵微调(当前16/1);想换位置就改ctx.slots.register里的name(例如conversation.input.left、conversation.composer.dock),并把id一并调整。
开发
node tools/test-classify.mjs # 时段判定回归测试,应输出"全部通过"
node --check client.js # 语法检查
client.js 是浏览器半边的完整产物:它用 window.__ModuleLoader__.load({ id, factory })
注册一个惰性工厂,id 必须等于 package.json 的包名。React 由宿主的模块表提供
(require('react')),因此不需要也不应自带 React。改动后按上面的"更新"流程走一趟生效。
兼容性
在 macOS + DSH 桌面版 0.2.0-rc.2 上开发并验证(install_bundle 返回
application: applied,conversation.input.right 槽位占用项 active: true)。
插件只用到槽位注册与 React,理论上兼容同代 DSH;DSH 若调整槽位名或 dsh.client
清单约定,需要跟着改。
免责声明
这是非官方插件,与 DeepSeek 无隶属关系。计费时段与价格以 官方定价页为准;若规则调整, 本项目需要相应更新。节假日数据来自第三方汇总,可能存在延迟或误差。
License
MIT © 2026 ZhangYong (cumthugo)