← 返回列表
未验证
dsh-peakrate ⛰️
尚未跑自动兼容性验证,可查看页面内的依赖与入口分析。 · 最近上游提交 2026/9/12 · 已提供中文文档
DeepSeek Harness 的峰谷费率徽章——按提供商、按模型,显示在模型选择器和编辑器工具行中。根据各提供商自己的时区和时间表进行判断,而不是仅限 DeepSeek 的时段。
综合分
30.3
GitHub 分
30.3
用户评分
—
★ Stars
1
周下载量
—
兼容 / 相关生态插件(非 dsh 原生,请按其对应运行时安装)
git clone https://github.com/log-li/dsh-peakrate.git数据截至 2026/9/16(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/schemastery用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动
README
dsh-peakrate ⛰️ 给 DeepSeek Harness 的峰谷倍率徽章 —— 切过去之前,先看清每个模型此刻到底什么价。按 provider、按模型。 🌐 简体中文: README.zh.md · English: README.md npm npm downloads license GitHub stars GitHub last commit TypeScript DSH plugin CI 每家 provider 都按自己的钟计费。DeepSeek 按北京时区分峰谷;Ollama 的窗口是 UTC;Z.ai 还有带日期区间的限时活动。同一个模型经不同 provider 路由,此刻的价可能完全不同。 dsh-peakrate 读出每个 provider 各自适用的时段规则,算出此刻落在哪一态,然后把它放到你本来就在看的地方 —— 模型选择器的每一行,以及 composer 旁边。 三种时段态,不是两种。 峰与谷是熟悉的那一对;第三种 campaign 是带日期区间与星期过滤的限时活动窗口,在有效期内优先级高于常规峰谷。 一条最要紧的规则:所有窗口都按真实时间戳判定,所以 DST 切换与跨午夜的窗口是正确的,而不是近似正确。 ✨ 主要特性 - ⛰️ 按 provider 分别判定 —— 每个 provider 用自己的 IANA 时区与自己的时段规则,不套用 DeepSeek 的时段。 - 🌗 三种时段态 —— peak / offPeak / campaign(限时活动,优先级高于常规峰谷)。 - ⏱️ 切换倒计时 —— 不只当前倍率,还有何时结束、会变成什么:1× · 2d 7h、2d 6h → 2×。 - 💬 跟随主题的悬停浮层 —— 详情由页面自己绘制而非系统 tooltip,风格与 harness 一致,键盘聚焦也能唤出。 - 📋 模型选择器每一行 —— 切换之前就能比价。选型只在这个面板里发生,信息正好落在决策点。 - 📌 composer 工具行徽章 —— 当前模型的倍率与倒计时,抬眼可见,不用开菜单。 - 🔄 目录实时更新 —— host 半边每 24 小时刷新共享目录,并经带信任围栏的路由下发到页面,数据更新无需重新构建即可上屏;覆盖面板里一键「立即刷新」。 - 🔍 覆盖面板 —— 设置 → 插件里,逐 provider 列出「命中 / 总数 / 未收录的模型」,并对整组零命中的 provider 告警。那正是静默漏配的形态,也是本插件最不愿意隐藏的东西。 - 🧭 npm run audit —— 离线覆盖穷举:枚举运行时的 provider × model,挑出需要人工决策的 provider。 - 🪶 零运行时依赖 —— 时间计算只用 Intl.DateTimeFormat 与 Date,不引入日期库。 - 🎨 只用设计 token —— 颜色来自 harness 自己的 --dsw-,跟随明暗主题。 - 🌐 中英双语 —— 全部文案经 harness 的 locale 服务,内置完整的中文与英文两本字典,跟随你的 harness 语言设置。 📚 目录 - 安装 - 你会看到什么 - 工作原理 - 覆盖面板 - 配置 - 数据来源与新鲜度 - 架构 - 兼容性与贡献 - 许可 安装 是你的 DSH profile —— 通常就是 web。--profile 是必填: dsh plugin 会在该 profile 目录里把参数转发给 pnpm。 dsh plugin --profile web add dsh-peakrate 从本地检出安装: dsh plugin --profile web add ./path/to/dsh-peakrate 前置依赖:dsh plugin 只是一个转发器,它把参数交给 profile 目录里的 pnpm 执行, 所以 pnpm 必须在 PATH 上(否则会报 pnpm not found on PATH — install pnpm to manage profile plugins)。 请注意:本插件会替换官方的模型选择器。 它接管了 conversation.input.model 槽位 —— 你从 composer 打开的选择器将变成本插件自己的组件, 而不再是内置的那个。这个接管是有意为之,且是功能超集:键盘导航、aria 接线、portal 定位、 加载 / 空 / 错误 / 重试状态、以及推理等级子菜单全部保留,倍率是按行加在上面的。 上游组件为 MIT,移植所依据的版本记录在 src/client/index.tsx。由于是替换而非扩展, 将来 DSH 若重构该选择器,可能需要重新移植 —— 见兼容性与贡献。 装完请重启 dsh web。 本插件在 host 半边声明了 settings 命名空间,而 host 代码只在启动时读取。重启后覆盖卡片会出现在 设置 → 插件 → 插件配置。 你会看到什么 模型选择器里 —— 打开你本来就在用的选择器(即顶部那张图),每一行都带该模型此刻适用的倍率。 同一个倍率同时常驻在下方 composer 工具行,你付的什么价一直看得见。 上图里四种倍率形态同时在场:2× 峰时、1× 与 0.5× 谷时、0.8× credits 套餐、以及限时的 Campaign 活动。 没有时段计价的模型就是不带徽章 —— 那是诚实的状态,不是漏查。 悬停徽章看详情:此刻什么态、多久之后变成什么。浮层由插件自己绘制(非系统 tooltip), 跟随明暗主题,键盘聚焦同样能唤出: 三种时段态 | 态 | 含义 | 颜色 | 图标 | |---|---|---|---| | peak | 标准价 | 警示(橙) | 双峰山 | | offPeak | 折扣价 | 成功(绿) | 双谷 | | campaign | 限时活动 | 成功(绿) | 星芒 | 颜色表达「贵/便宜」,图标表达「是哪个时段态」。 图标刻意用地貌形状而不是涨跌箭头 —— 箭头会被读成「它要涨/要跌了」,而山峰只是「一个高点」。方向与形状不是同一个断言。 某个模型没有匹配到任何 profile 时,那一行什么都不显示。这是有意的:没有时段计价的模型,不该被贴上一个它并不拥有的倍率。 工作原理 provider id ──┐ ├─► 别名 ──┐ model id ─────┘ ├─► profile ─► schedule ─► 此刻状态 ─► 徽章 + 倒计时 │ 目录(实时或内置)────────┘ 1. 匹配:provider id 经过别名表(ollama → Ollama)。provider id 是你自己起的本地标签;别名表就是「标签 → 真实计费主体」的翻译。模型 id 随后被归一化(剥掉 :tag 后缀、统一大小写与分隔符),再按 provider 专属的模型模式匹配。 2. 判定:用匹配到的 profile 自己的时区求值。峰时窗口、星期过滤、以及任何生效中的 override 一起考虑,override 在日期区间与星期条件允许时优先。 3. 呈现:结果与倒计时渲染到模型选择器、composer 工具行与覆盖面板。 时间正确性 时间计算刻意避开了「墙钟分钟数 + 1440」这类捷径 —— 那会让倒计时在 DST 边界差一小时、在窗口边缘差一整天。这里的做法是把墙钟候选点换算回真实时间戳再与 now 比较。 跨午夜窗口(23:00–09:00)归属它开始的那一天,所以凌晨那半段按开始日的日期与星期判定。这对活动 override 与常规峰时窗口完全一致。 扩展覆盖范围 判定基于一份精选目录,因此一个 provider 要么被映射,要么被明确记录为「有意不映射」。不存在第三种静默结局 —— 覆盖面板与测试套件都在强制这一点: - endpoint 转售别家计费的(网关)继承上游时段 —— 目录收录的是直连厂商,不是转售方; - 确实没有时段计价的 provider,会得到一条写明理由的显式记录; - 其余情况一律在覆盖面板里冒出告警。 覆盖面板 设置 → 插件 → 插件配置。它承担三件事:看清覆盖、发现漏配、刷新目录。 | 列 | 含义 | |---|---| | Provider | harness 所知的 provider | | 覆盖 | 该 provider 下命中 profile 的模型数 | | 未收录的模型 | 没有命中任何 profile 的模型 | 整组零命中的 provider 会被顶到前面并告警。部分未命中刻意不告警:同一个 provider 下常混有「有/无时段计价」两类模型(比如一个 Ollama 分组里既有 DeepSeek 又有 GLM),每行都提示等于没提示。 面板顶部的数据来源行(如上图的「目录来源:远端 · 更新于 …」)说明当前用的是远端目录还是内置快照; 右侧「立即刷新」强制重新拉取一次。enabled 与 refreshIntervalHours 也在这里编辑,即时生效。 配置 配置写在 profile 的 cordis.patch.yml 里: - id: peakrate config: provider id → 目录里的 provider 名 providerAliases: my-gateway: DeepSeek 按 provider 限定模型模式;先匹配者胜 modelMappings: - provider: my-gateway match: "^deepseek-v4" profile: deepseek-v4 - provider: my-gateway match: "glm-5\\.3-flash" matchIsRegex: true profile: zai-glm-5-3-flash 拉取间隔;0 表示关闭后台刷新 refreshIntervalHours: 24 catalogUrl: https://offpeakclock.com/pricing.json cachePath: ~/.dsh/peakrate/pricing.json | 选项 | 默认 | 说明 | |---|---|---| | enabled | true | 后台刷新开关。也可在覆盖面板里改。 | | refreshIntervalHours | 24 | 目录刷新间隔(小时)。0 关闭。也可在面板里改。 | | catalogUrl | 公共目录 | 远端目录地址。 | | cachePath | ~/.dsh/peakrate/pricing.json | 最近一次成功拉取的磁盘缓存。 | | providerAliases | 内置表 | 额外的 provider id → 目录 provider 映射,覆盖内置。 | | modelMappings | 内置表 | 额外的 provider + 模型模式 → profile 映射,先于内置尝试。 | | customProfiles | [] | 额外 profile:按 id 覆盖内置条目或新增;同样参与徽章判定。 | modelMappings 默认是前缀匹配;写 matchIsRegex: true 则按正则。非法正则不抛错,只是永不命中。 customProfiles 完全生效(含徽章)。host 会把合并后的目录经 /peakrate/catalog 下发给页面, 所以自定义 profile 与内置条目一样参与徽章判定 —— 按 id 覆盖内置条目,或追加新条目。 实测:给 deepseek-v4 写一条 peak: 9× 的自定义 profile,下发的目录与徽章都变成 9×。 数据来源与新鲜度 目录来自 offpeakclock.com/pricing.json(schemaVersion: 1),一份社区维护的各 provider 峰谷时段快照。 一次更新如何到达你的屏幕: 1. host 在启动时以及每 refreshIntervalHours(默认 24 小时)拉取目录,校验后写入磁盘缓存。 2. host 通过 GET /peakrate/catalog 下发当前目录,并在 POST /peakrate/catalog(即「立即刷新」按钮)时按需重新拉取。 3. client 启动时请求一次,拿到即重渲染。若请求失败 —— 离线、首次运行、被围栏拒绝 —— 会静默回退到构建期内置快照,所以徽章绝不会因为网络问题而消失。 因为页面读的是 host 的实时目录,数据更新无需重新构建或重装插件即可上屏。内置快照作为离线兜底始终保留。 路由带信任围栏 /peakrate/catalog 不是开放端点。它施加与 harness 自身 /api 相同的 browser-trust fence,防的是浏览器针对本地 HTTP 服务打开的两条 confused-deputy 通道: - DNS rebinding —— Host 头(rebinding 无法伪造它)必须是回环或 trustedHosts 里的 authority,否则 403。 - 跨站请求 —— Sec-Fetch-Site: cross-site 直接拒绝;带 Origin 时要求它与 Host 同源。 它是信任围栏,不是认证层 —— 网络可达性仍归 webserver 管。该端点提供的是公开的定价数据。 拉取到的目录会被严格校验:未知 schema 版本、非法时钟值、零长度窗口、非 YYYY-MM-DD 日期、重复 profile id,都在解析期就被拒绝,而不是在之后产生一个错误判定。 架构 | 模块 | 职责 | |---|---| | index.ts | host:目录拉取/缓存、用户配置、settings 命名空间、下发路由 | | catalog.ts | 解析并校验目录文档 | | catalog-route.ts | 带信任围栏的 /peakrate/catalog 路由 | | schedule.ts · matching.ts · coverage.ts | 纯函数:时段判定与倒计时 / provider+模型匹配 / 覆盖报告 | | client/ | 三处呈现、运行时目录拉取与回退、选择器 fork、图标与样式 | schedule.ts、matching.ts、coverage.ts 不依赖 DSH 运行时,所有时间边界与匹配规则都由单测覆盖。 三处呈现 | 位置 | 槽位 | 类型 | |---|---|---| | composer 工具行 | conversation.input.left | 追加 | | 模型选择器 | conversation.input.model | 有意接管(功能超集) | | 覆盖面板 | settings.plugin.item | 追加,以本插件的 settings 命名空间为 key | 模型选择器的接管是官方组件的完整超集 —— 键盘导航、aria 接线、portal 定位、加载/空/错误/重试态、推理等级二级菜单,一个都不少。上游包是 MIT,移植版本记录在 src/client/index.tsx 中;test/bundle-contract.test.ts 的守卫测试会在任何其他自带 UI 槽位被遮蔽时让构建失败。 兼容性与贡献 已实测范围 | | | |---|---| | DeepSeek Harness | macOS 上的 0.1.5-rc.1 | | 安装路径 | 用已发布的 npm 包在一个新建 profile 上做过端到端验证(dsh plugin --profile … add dsh-peakrate)—— bundle 注册、目录路由、三处呈现、控制台零错误 | | 尚未验证 | 其他 DSH 版本;Linux 与 Windows;已经自定义过模型选择器的 profile | 最可能出问题的是选择器接管:它替换的是一个 shipped-UI 槽位,因此上游一旦改动选择器结构, 就需要刷新移植。移植所依据的版本记录在 src/client/index.tsx。 - 需要提供 conversation.input.model 与 settings.plugin.item 槽位的 DeepSeek Harness 构建。选择器移植自 @deepseek-ai/dsh-client-ui-model-selection@0.1.5-rc.1。 - peer 依赖:@deepseek-ai/cordis、@deepseek-ai/schemastery。 - 提交遵循 Conventional Commits;变更日志遵循 Keep a Changelog。 - 发版:推一个 v tag 即触发 release workflow —— 跑 typecheck 与测试、构建、带 provenance 发布到 npm,并从 CHANGELOG.md 生成 GitHub Release。 - 欢迎在 github.com/log-li/dsh-peakrate 提 issue 与 PR。 贡献者 | 贡献者 | 角色 | |---|---| | @log-li | 作者与维护者 | 许可 MIT © Logan Lin
扫码进群