DSH Plugins Marketplace

DSH Plugins

Plugins

/

dsh-peak-gate

C

dsh-peak-gate

Manifest valid

DSH Plugin: Priced according to DeepSeek's peak/off-peak time-of-use rates, puts the brakes on token spending during peak hours (blocks large tasks / compresses output limits / makes the model talk less), and provides a one-click release command

hasBundlePatchMachine translated

dsh-peak-gate · 峰谷守门 / Peak-Gate

按 DeepSeek 的峰谷分时计价,在高峰时段给 token 花销踩刹车:大任务拦下、输出上限压缩、并让模型少说废话,还提供一键放行口令。

English: Based on DeepSeek's peak / off-peak time-of-day pricing, it puts the brakes on token spend during peak hours: big tasks get blocked, output limits get compressed, and the model is told to stop waffling — plus it ships a one-word force-pass token.

⚠️ 非官方插件:与 DeepSeek / DeepSeek Harness 官方无关,是社区自研插件。 通过 web profile 的 link: 依赖挂载(见下方「安装」),不是从插件市场装的。

⚠️ English: Unofficial plugin: unaffiliated with DeepSeek / DeepSeek Harness; built by the community. It is mounted through a web-profile link: dependency (see "安装 / Installation" below) and is not installed from a plugin marketplace.

安装 / Installation

这是 DSH(DeepSeek Harness)host 插件(Node half,跑在宿主侧)—— 通过 web profile 的依赖 + bundle patch 挂载: English: This is a DSH (DeepSeek Harness) host plugin (Node half, running on the host side) — mounted through a web-profile dependency + bundle patch:

  1. 把源码放到 profile 的 vendor 目录:<DSH_HOME>/profiles/web/vendor/dsh-peak-gate-src English: Put the source into the profile's vendor directory: <DSH_HOME>/profiles/web/vendor/dsh-peak-gate-src
  2. 在 profiles/web/package.json 里加两处:dependencies 填 "dsh-peak-gate": "link:vendor/dsh-peak-gate-src"; dsh.profile.bundles 列表里加上 dsh-peak-gate English: Add two things in profiles/web/package.json: set dependencies to "dsh-peak-gate": "link:vendor/dsh-peak-gate-src"; and add dsh-peak-gate to the dsh.profile.bundles list
  3. pnpm install(或按你的 DSH 版本用等价的挂载方式),然后重启 dsh web English: pnpm install (or the equivalent mounting method for your DSH version), then restart dsh web
  4. 配置命名空间 peak-gate;DSH 0.1.7+ 写在 profiles/web/cordis.patch.yml 的 peak-gate: 段,热改即时生效,无需重启 English: The config namespace is peak-gate; on DSH 0.1.7+ write it under the peak-gate: section of profiles/web/cordis.patch.yml — hot edits take effect immediately, no restart needed

运行时依赖 DSH 自带的 schemastery 与 @deepseek-ai/dsh-llm,没有其它第三方包。

English: At runtime it depends on DSH's own schemastery and @deepseek-ai/dsh-llm; there are no other third-party packages.

官方峰谷口径 / The Official Peak/Off-Peak Rules

来自 DeepSeek 官方定价页(核对于 2026-09-11) + 官方峰谷时间说明(2026-09-19 补充): English: Taken from the official DeepSeek pricing page (verified 2026-09-11) plus the official peak/off-peak time note (added 2026-09-19):

时段(北京时间)价格
周一至周五 09:00–12:00、14:00–18:00高峰 ×2
其余时间、周末全天、中国法定节假日全天空闲 ×1

English:

Window (Beijing time)Price
Mon–Fri 09:00–12:00, 14:00–18:00peak ×2
all other times, the whole weekend, all Chinese statutory holidaysoff-peak ×1
  • 空闲价 = 高峰价的一半(flash 输出:谷 $0.6/M vs 峰 $1.2/M) English: the off-peak price = half the peak price (flash output: off-peak $0.6/M vs peak $1.2/M)
  • 判定走「UTC+8 位移后读 UTC 字段」,不依赖本机时区(本机时区/夏令时不可信) English: the decision works by "shifting by UTC+8, then reading the UTC fields" and does not depend on the local machine's time zone (the local time zone / DST are not trustworthy)
  • 🗓️ 调休上班的周末也按空闲计费(官方 2026-09-19 明确)⇒ 只看星期几,没有"补班日恢复高峰"的反向逻辑 English: 🗓️ A weekend worked as a make-up day is billed as off-peak too (stated officially on 2026-09-19) ⇒ only the day of the week is inspected; there is no reverse rule of "make-up workday ⇒ back to peak"

🗓️ 法定节假日日历(2026-09-25 新增)/ 🗓️ Statutory Holiday Calendar (added 2026-09-25)

层说明
① 联网NateScarlet/holiday-cn(按国务院公告生成,含 isOffDay),三源按序:jsDelivr → raw.githubusercontent → gh-proxy;只拉当年,超时 8s,单份响应上限 1 MB
② 磁盘缓存<DSH_HOME>/data/peak-gate/holidays-cn.json,默认 30 天内不重复拉;联网失败仍用旧缓存(并告警)
③ 内置兜底代码里的 DEFAULT_HOLIDAYS(2026 全年),离线/首启可用
④ 自检日级:当年落在日历里的放假日 < 10 天(或日历项写错)⇒ 打日志告警(绝不静默按工作日判峰);每 12 小时自动核对一次

English:

LayerDescription
① OnlineNateScarlet/holiday-cn (generated from State Council announcements, includes isOffDay), three sources in order: jsDelivr → raw.githubusercontent → gh-proxy; it only fetches the current year, with an 8 s timeout and a 1 MB cap per response
② Disk cache<DSH_HOME>/data/peak-gate/holidays-cn.json, not re-fetched within 30 days by default; if networking fails the old cache is still used (with a warning)
③ Built-in fallbackDEFAULT_HOLIDAYS in the code (all of 2026), usable offline / on first start
④ Self-checkdaily: fewer than 10 holidays for that year present in the calendar (or a wrong calendar entry) ⇒ log a warning (never silently fall back to treating it as a workday when judging peak); re-verified automatically every 12 hours

数据质量校验:单年放假日数必须在 15 ~ 45 天之间(防半截响应 / 防"全年都放假"把闸门 fail-open); 文档里不属于该年的日期一律不算数;同年数据合并是取并集(只增不减,半截响应不会覆盖完整数据); 缓存 fetchedAt 落在未来 ⇒ 判损坏并重新拉取(防"永久冻结")。

English: Data-quality validation: the number of holidays in a single year must be between 15 and 45 days (guards against truncated responses / against an "everything is a holiday" response flipping the gate to fail-open); dates in the document that do not belong to that year are never counted; merging data for the same year is a union (add-only, never shrink, so a truncated response cannot overwrite complete data); a cache whose fetchedAt lies in the future ⇒ treated as corrupt and re-fetched (guards against "permanent freeze").

🗓️ 调休上班日也算谷价日:国家标定的补班日(如 2026-10-10 周六)无条件按空闲计费 —— 与 weekendOffPeak 开关无关。缓存里的 workdays 与内置 DEFAULT_MAKEUP_DAYS 都会并进日历。

English: 🗓️ A make-up workday also counts as an off-peak day: a nationally designated make-up workday (e.g. Saturday 2026-10-10) is unconditionally billed as off-peak — independent of the weekendOffPeak switch. Both the workdays in the cache and the built-in DEFAULT_MAKEUP_DAYS are merged into the calendar.

配置项:holidays(追加的日历,默认即内置表)、useBuiltinHolidays(是否并入内置表,收窄时置 false)、 autoHolidayCalendar(关掉联网)、holidayCalendarUrls、holidayCacheMaxAgeDays、holidayFetchTimeoutMs、holidayCachePath。 English: Config options: holidays (a calendar to append, defaulting to the built-in table), useBuiltinHolidays (whether to merge the built-in table in; set it to false when narrowing), autoHolidayCalendar (turn networking off), holidayCalendarUrls, holidayCacheMaxAgeDays, holidayFetchTimeoutMs, holidayCachePath.

⚠️ 想「收窄到只认自己写的几天」:holidays: [] + useBuiltinHolidays: false + autoHolidayCalendar: false 三件一起做。 English: ⚠️ To "narrow it down to only the few days you wrote yourself": do all three together — holidays: [] + useBuiltinHolidays: false + autoHolidayCalendar: false.

⚠️ 该日历同时被右下角的余额挂件(dsh-whale-widget)读取,两边口径必须一致(挂件侧历史分桶有 2026-09-19 生效分界,插件侧没有 —— 这是有意为之)。 English: ⚠️ This calendar is also read by the balance widget in the bottom-right corner (dsh-whale-widget), and the two sides must agree on the rules (the widget's historical bucketing has a 2026-09-19 effective boundary, the plugin side does not — that is intentional).

五个着力点 / Five Levers

#位置干什么
1agent/pre-step峰时拦重活(默认用短提示顶替,见下);判定分三层,见下节
2agent/pre-step(续跑步骤)峰时工具预算:单轮工具步数超限就地停下,不加模型请求
3agent/request峰时把 maxTokens 压到上限
4systemPrompt 段 peak:brevity峰时要求模型精简输出 —— 拦任务是止损,让它少说废话才是从源头省输出 token
5officialProviders 白名单默认全管;填了名单就只对自家官方路由生效,不误伤中转渠道

English:

#HookWhat it does
1agent/pre-stepblocks heavy work during peak (by default replacing it with a short notice, see below); the decision has three layers, see the next section
2agent/pre-step (continuation steps)peak tool budget: stops in place once a single turn exceeds its tool-step budget, without adding a model request
3agent/requestcompresses maxTokens down to the cap during peak
4systemPrompt section peak:brevityasks the model to output concisely during peak — blocking tasks limits the damage, but making it stop waffling is what saves output tokens at the source
5officialProviders allow-listmanages everything by default; once the list is filled in it only applies to your own official routes, so relay channels are not hit by mistake

⚠️ 生死线:pre-step 在每个 step 都会跑,工具循环中间的 step 是 messages.length === 0。 判断「这是不是重活」时只在 messages.length > 0(真正有新输入)时进行,绝不把工具循环当用户输入拦; 续跑步骤只走第 2 条的工具预算,走的是一条独立的、可一键关掉(peakMaxSteps: 0)的规则。

English: ⚠️ Hard line: pre-step runs on every step, and a step in the middle of a tool loop has messages.length === 0. The "is this heavy work?" judgement is only made when messages.length > 0 (there really is new input); a tool loop is never mistaken for user input and blocked. Continuation steps go only through lever 2's tool budget — an independent rule that can be switched off with a single setting (peakMaxSteps: 0).

v2 的三层判定(2026-09-11 新增)/ v2's Three-Layer Decision (added 2026-09-11)

需求:「峰时只能解一些数学题等短的东西,或者只是问一下天气,写程序太伤了」 → 所以峰时按「这活儿重不重」决定拦不拦,而不是只看输入大小。

English: The requirement: "at peak it can only handle short things like math problems, or just asking about the weather, writing programs hurts too much" → so at peak, whether to block is decided by "how heavy is this job", not merely by how big the input is.

层做什么成本兜底
1. 白名单直通命中 lightKeywords 且输入不长 → 直接放行0——
2. 模型分类白名单没命中、输入够长 → 花一次极短调用问「heavy 还是 light」~几十 token超时/报错/认不出 → 按 light 放行
3. 工具预算峰时单轮 step > peakMaxSteps → 就地停下0(不发模型请求)任何异常 → 放行保平安

English:

LayerWhat it doesCostFallback
1. Allow-list pass-throughmatches lightKeywords and the input is short → pass straight through0——
2. Model classificationallow-list missed and the input is long enough → spend one extremely short call asking "heavy or light"~a few dozen tokenstimeout / error / unrecognisable → pass it through as light
3. Tool budgetat peak, a single turn where step > peakMaxSteps → stop in place0 (no model request sent)any exception → pass through and stay safe

第 1 层刻意只判「轻」、不设黑名单:不靠词表猜「这像不像写程序」, 「重不重」交给第 2 层的模型判断,词表只用来省掉那些明显不用分类的短问句。

English: Layer 1 deliberately only recognises "light" and has no blacklist: it does not use a word list to guess "does this look like programming"; "is it heavy" is left to layer 2's model judgement, and the word list only exists to skip short questions that obviously need no classification.

第 2 层怎么调用的:走 ctx.get('llm').prepareCall()(官方公开路径且完全绕开 llm/stream 这个 waterfall),所以既不会把自己再拦一次、也不污染主请求链路。 调用时只带 provider / model / 一条 user 消息 / maxTokens: 6,并用 AbortSignal.timeout 限时;识别 a(light)/ b(heavy)两个字母,认不出就放行。

English: How layer 2 makes the call: it goes through ctx.get('llm').prepareCall() (the official public path, and it bypasses the llm/stream waterfall entirely), so it neither blocks itself a second time nor pollutes the main request chain. The call carries only provider / model / one user message / maxTokens: 6, and is time-limited with AbortSignal.timeout; it recognises the two letters a (light) / b (heavy), and passes through if it cannot tell.

⚠️ 分类调用必须关掉推理(classifierReasoningEffort: 'off',默认值):会话默认 reasoningEffort: high 会开思考,思考 token 会把 maxTokens: 6 吃光 —— 答案一个字母都 吐不出来,于是每次都走「分类未定 → 放行」,看起来像分类器根本没生效 (2026-09-11 真机实测踩到)。若某路由不支持 off,插件会自动退回默认档、并把上限放大到 32 token 重试一次。

English: ⚠️ The classification call must have reasoning turned off (classifierReasoningEffort: 'off', the default): the session default reasoningEffort: high enables thinking, and thinking tokens eat up all of maxTokens: 6 — not a single letter of the answer comes out, so every attempt lands on "classification undecided → pass through", which looks as though the classifier were not working at all (hit in a real-machine test on 2026-09-11). If some route does not support off, the plugin automatically falls back to the default level and retries once with the limit raised to 32 tokens.

第 3 层停下时长什么样:不发任何模型请求,直接把一条提示写进会话 (session.append('user/message', …),与 agent loop 自己落消息同款),界面立刻可见; 然后返回 {kind:'reject'} 结束本轮。

English: What layer 3 stopping looks like: it sends no model request at all; it writes a notice straight into the session (session.append('user/message', …), the same call the agent loop itself uses to record messages), so it is visible in the UI immediately; then it returns {kind:'reject'} to end the turn.

🩸 曾经以为「返回空 messages 就能让本轮自然收尾」—— 真机实测是错的。 dsh-agent-loop 的闸门是 if (turnEnds && decision.messages.length === 0) break, 而工具循环里 turnEnds 始终是 null ⇒ 空 messages 被忽略,照样发一次满历史请求、 模型继续干活(会话记录里可见:提示之后又跑了 22 次工具调用)。 宿主里唯一能真正结束本轮的就是 reject(turnEnds = {kind:'blocked'} + return false)。 代价:本轮不会有 turn/end,界面上本轮也没有模型收尾(提示已把原因写在会话里)。

English: 🩸 It was once assumed "returning empty messages lets the turn wrap up naturally" — a real-machine test proved that wrong. dsh-agent-loop's gate is if (turnEnds && decision.messages.length === 0) break, and inside a tool loop turnEnds is always null ⇒ the empty messages are ignored, a full-history request is still sent, and the model keeps working (visible in the session record: after the notice it ran 22 more tool calls). The only thing in the host that really ends the turn is reject (turnEnds = {kind:'blocked'} + return false). The cost: this turn produces no turn/end, and there is no model sign-off in the UI for that turn either (the notice has already written the reason into the session).

生死线不是 messages.length > 0:宿主会把 source.kind === 'plugin' 的内容注入进 messages(默认启用的 dsh-repeat-tool-reminder 就会这么干),所以判据是 hasUserInput()(只要有「非插件来源」的消息才算用户的新输入),否则工具提醒会被 误当成用户请求去分类、甚至被拦截提示顶替掉。

English: The hard line is not messages.length > 0: the host injects content with source.kind === 'plugin' into messages (the default-enabled dsh-repeat-tool-reminder does exactly this), so the real test is hasUserInput() (only messages from a "non-plugin source" count as new user input); otherwise a tool reminder would be mistaken for a user request, get sent to the classifier, and even be replaced by the block notice.

拦截方式(onBlock)/ How It Blocks (onBlock)

值行为成本体验
replace(默认)用一条短提示顶替掉这次大请求省 95%+用户能立刻看到「被拦了 + 怎么放行」
reject该轮直接 blocked,一个 token 都不发零界面静默,原因只进日志

English:

ValueBehaviourCostExperience
replace (default)replaces this big request with a short noticesaves 95%+the user immediately sees "it was blocked + how to force it through"
rejectblocks the turn outright, not one token is sentzerothe UI stays silent, the reason only goes to the log

一键放行 / One-Word Force Pass

消息里带 !force(可配 forceToken)即无条件放行 —— 急事不用改配置。 注意:!force 整轮生效 —— 既放行这次请求,也关掉本轮的工具预算(这样长任务才跑得完)。 peakMaxSteps: 0 是彻底关掉第 3 层的开关。

English: Putting !force in a message (configurable via forceToken) passes it through unconditionally — no need to edit the config for something urgent. Note: !force applies to the whole turn — it passes this request and also switches off this turn's tool budget (that is what lets a long task finish). peakMaxSteps: 0 is the switch that turns layer 3 off entirely.

配置 / Configuration

命名空间 peak-gate,写在 ~/.dsh/profiles/web/cordis.patch.yml,热改即时生效,无需重启: English: The namespace is peak-gate, written in ~/.dsh/profiles/web/cordis.patch.yml; hot edits take effect immediately, no restart needed:

peak-gate:
  enabled: true
  mode: block                       # block 真拦 | notify 只提醒 | off 关闭
  peakWindows: ['09:00-12:00', '14:00-18:00']   # 北京时间
  beijingOffsetMinutes: 480         # UTC+8
  weekendOffPeak: true
  officialProviders: []             # 空 = 所有 provider 都管;填 ['deepseek-official'] 则只管网关外的官方路由
  brevitySection: true              # 峰时注入「精简输出」提示段
  bigTaskTokens: 6000               # 本次新输入估算超过它 = 大任务(只算新输入,不算会话历史)
  bigTaskChars: 20000               # 字符数兜底
  sessionPressureTokens: 0          # >0 时:会话上下文压力超它也算大任务(默认关)

  # —— 第 1 层:白名单直通(只判轻,没有黑名单) ——
  lightKeywords: [算一下, 计算, 求解, 解方程, 数学, 证明, 天气, 几点, 是什么, 为什么, 解释一下, 翻译, …]
  lightKeywordMaxChars: 120         # 输入超过这么多字符就不认白名单

  # —— 第 2 层:模型分类 ——
  useModelClassifier: true          # 关掉就退回「只看输入大小」
  classifierProvider: ''            # 留空 = 用本会话上一次请求的 provider
  classifierModel: ''               # 留空 = 用本会话上一次请求的 model
  classifierTimeoutMs: 3000         # 超时按轻活放行
  classifierMaxTokens: 6            # 只够吐一个字母
  classifierReasoningEffort: off    # 必须关推理:否则思考会吃光上面那 6 个 token,答案吐不出来
  classifierMinChars: 20            # 短于它就不花这次调用
  classifierMinTokens: 15

  # —— 第 3 层:工具预算 ——
  peakMaxSteps: 12                  # 峰时单轮工具步数预算;0 = 关掉这条

  forceToken: '!force'
  peakMaxTokens: 32768              # 峰时主 agent 输出上限,0 = 不限
  subagentMaxTokens: 16384
  manageSubagents: true             # 是否管子代理(输出上限 + 是否拦)
  blockSubagents: false             # 是否真拦子代理的大任务(默认不拦,免得主任务断掉)
  onBlock: replace                  # replace | reject
  warnOncePerSession: true          # 仅 reject 方式有意义
  dryRun: false                     # 只记日志不真拦

想调「多严」就动这三处:useModelClassifier(要不要模型判)、peakMaxSteps(工具预算)、 classifierMinChars(多长的输入才值得花一次分类)。

English: To tune "how strict" it is, touch these three: useModelClassifier (whether the model judges at all), peakMaxSteps (the tool budget), and classifierMinChars (how long an input must be to be worth one classification).

想看自己的 provider 叫什么?日志里每次拦截都会打印 provider=...,照着填白名单即可。

English: Want to know what your provider is called? Every block prints provider=... in the log; just copy that into the allow-list.

验证 / Verification

先跑离线自测(155 项):/ Run the offline self-test first (155 cases):

# 离线自测(155 项):依赖 DSH 提供的 schemastery / @deepseek-ai/dsh-llm,
# 所以要在 <DSH_HOME>/profiles/web/node_modules 的解析链内运行
cd <DSH_HOME>/profiles/web/vendor/dsh-peak-gate-src
node test/selftest.mjs

真机侧怎么确认插件生效(实测结论):ctx.logger 的输出不落盘(<DSH_HOME>/logs/ 里没有 peak-gate 目录), 所以别去翻插件日志,看这两处即可:

English: How to confirm on a real machine that the plugin is live (a measured conclusion): ctx.logger output is not written to disk (there is no peak-gate directory under <DSH_HOME>/logs/), so do not go digging through plugin logs — just look at these two places:

看哪里期望
GUI「插件」页里 dsh-peak-gate 的开关已启用
宿主启动日志 <DSH_HOME>/dsh-web-launcher.err.log0 字节(无加载报错)

English:

Where to lookWhat to expect
the dsh-peak-gate switch on the GUI "Plugins" pageenabled
the host startup log <DSH_HOME>/dsh-web-launcher.err.log0 bytes (no load errors)

加载成功时宿主控制台会打印 peak-gate: 峰谷守门 v2 已加载(mode=…,峰窗=…,精简段=…,白名单 N 词,模型分类=…,工具预算=… 步,自动日历=…)。

English: On a successful load the host console prints peak-gate: 峰谷守门 v2 已加载(mode=…,峰窗=…,精简段=…,白名单 N 词,模型分类=…,工具预算=… 步,自动日历=…).

卸载 / 回滚 / Uninstall / Rollback

cd ~/.dsh/profiles/web
Copy-Item package.json.bak-peakgate-<timestamp> package.json -Force   # 恢复改动前的 package.json / restore the previous package.json
pnpm install      # 重新解析依赖 / re-resolve dependencies
# 然后重启 dsh web / then restart dsh web

设计参考 / Design References

写这个插件时参考了市场里几个同类插件的做法(awesome-dsh-plugin.com): English: This plugin's design references how a few similar plugins in the marketplace do it (awesome-dsh-plugin.com):

插件借鉴了什么
dsh-peak-cost-mode峰时注入「精简输出」提示段(caveman 模式);systemPrompt.section 的 text 用函数动态求值
dsh-peak-block只精确匹配 deepseek-official 判定官方、避免误伤中转;时区走 UTC+8 数学换算
dsh-peak-indicator按事件时间戳分时段计价的口径意识

English:

PluginWhat was borrowed
dsh-peak-cost-modeinjecting a "be concise" prompt section during peak (caveman mode); evaluating systemPrompt.section's text dynamically with a function
dsh-peak-blockmatching only deepseek-official exactly to identify the official route, avoiding false hits on relays; doing the time zone with UTC+8 arithmetic
dsh-peak-indicatorawareness of pricing windows based on event timestamps

已知限制 / Known Limitations

  • 任务量是估算:按字符类型粗估(ASCII ÷ 3.6,非 ASCII × 0.75)。够分级,不适合对账。 English: Task size is an estimate: a rough estimate by character class (ASCII ÷ 3.6, non-ASCII × 0.75). Good enough for classifying, not for accounting.
  • 模型分类要多花一次调用:每次判定 heavy/light 约几十 token(maxTokens: 6)。相比拦下一次 写程序的工具循环(动辄上万 token)可以忽略,但它确实是「每条够长的输入都问一次」的成本模型; 想省就调高 classifierMinChars / 调低 useModelClassifier。 English: Model classification costs one extra call: each heavy/light decision is about a few dozen tokens (maxTokens: 6). Next to blocking one program-writing tool loop (easily tens of thousands of tokens) that is negligible, but it really is a cost model of "ask once for every input that is long enough"; to save, raise classifierMinChars / turn down useModelClassifier.
  • 停下的那一轮没有模型收尾:第 3 层是「不发请求、直接落提示」,所以用户看到的是进度停住 + 一条说明,而不是模型自己写的总结。要继续就带 !force 重发,或把 peakMaxSteps 调大。 English: The turn that gets stopped has no model sign-off: layer 3 is "send no request, drop a notice instead", so what the user sees is progress halting plus an explanation, not a summary written by the model. To carry on, resend with !force, or raise peakMaxSteps.
  • reject 方式界面静默:被拦的消息不进会话记录,会看到"发出去没反应"。默认的 replace 没这问题。 English: The reject mode is silent in the UI: the blocked message does not enter the session record, so it looks like "sent but nothing happened". The default replace does not have this problem.
  • 不做记账:目前只在日志里记拦截次数,没有「今天省了多少钱」的面板。要做需要订阅 llm/stream 采真实 usage + 落盘 + client 半边(市场里 dsh-peak-cost-mode 是完整形态,可参考)。 English: No accounting: for now it only records the number of blocks in the log; there is no "how much did I save today" panel. Building one would mean subscribing to llm/stream to sample real usage + persisting it + a client half (marketplace plugin dsh-peak-cost-mode is a complete form of this, worth referencing).
  • 精简段会让 KV cache 失效一次:峰谷切换时 system prompt 变化,会丢一次前缀缓存。一天只切 4 次,可接受。 English: The brevity section invalidates the KV cache once: switching between peak and off-peak changes the system prompt, so one prefix cache is lost. It only switches 4 times a day, which is acceptable.
  • 只认 DeepSeek 官方 API 的计价口径;走第三方网关时用 officialProviders 排除,或自己改 peakWindows。 English: It only recognises the pricing rules of the official DeepSeek API; when going through a third-party gateway, exclude it with officialProviders, or change peakWindows yourself.

运行环境 / Requirements

  • DSH(DeepSeek Harness)≥ 0.1.7-rc.2 —— package.json 里 dsh.compatibility.dshReleases 声明为 compatible;本仓在该版本上实测通过。
  • Node.js ≥ 20 —— package.json 的 engines.node;本机在 Node 24 上实测通过。
  • 运行依赖:无。代码用到 schemastery 与 @deepseek-ai/dsh-llm,两者均由 DSH 宿主提供(见 peerDependencies),本仓不随包安装任何第三方运行依赖。
  • 可选联网:默认会去取法定节假日日历(可关,见「配置」里的 autoHolidayCalendar);关掉后走内置兜底表。

English:

  • DSH (DeepSeek Harness) ≥ 0.1.7-rc.2 — declared compatible in package.json's dsh.compatibility.dshReleases; verified on that release.
  • Node.js ≥ 20 — see engines.node in package.json; verified on Node 24 here.
  • Runtime dependencies: none. The code uses schemastery and @deepseek-ai/dsh-llm; both are provided by the DSH host (see peerDependencies).
  • Optional networking: by default it fetches the statutory-holiday calendar (can be turned off via autoHolidayCalendar under "Configuration"); with networking off it falls back to the built-in table.

权限与依赖 / Permissions & Dependencies

本节如实描述本插件对系统的接触面,按「保守」口径写:没查到的地方不写成"不访问"。 English: This section describes, in a deliberately conservative way, what this plugin touches on the system. Where something could not be verified, it is not claimed to be "not accessed".

这是 DSH(DeepSeek Harness)宿主插件:它是 Node half,跑在 dsh web 宿主进程内,通过 profile 的 bundle patch 挂进来,不单独起进程、不开端口、不注册系统服务。因此它与宿主同权限 —— 宿主能读写的,它理论上也能;下面列的是它代码里实际会碰的部分(代码可逐行审计)。

English: This is a DSH (DeepSeek Harness) host plugin: it is a Node half that runs inside the dsh web host process, mounted through a profile bundle patch. It starts no separate process, opens no port and installs no system service. It therefore shares the host's privileges — anything the host can read or write, it could in principle too; listed below is what its code actually touches (the code is short enough to audit line by line).

接触面实际情况
文件(读)读 DSH 的插件配置(由宿主 settings 服务提供,命名空间 peak-gate)与节假日缓存;不主动扫描/读取你的工作文件。
文件(写)只写节假日缓存一个文件:默认 <DSH_HOME>/data/peak-gate/holidays-cn.json(可用 holidayCachePath 改到别处)。
网络默认开启节假日日历更新:只按顺序请求三个源(jsDelivr → raw.githubusercontent → gh-proxy),只拉当年的日历 JSON,单源超时 8 s、响应上限 1 MB。可用 autoHolidayCalendar: false 或 holidayCalendarUrls: [] 完全关掉联网。除此之外不发起任何网络请求。
外部命令不调用任何外部命令 / shell / 子进程;不需要 root / 管理员权限。
凭据不读取、不存储任何凭据(不读环境变量里的 API key、不读凭据文件)。第 2 层的分类调用复用宿主已经配置好的 LLM 路由,鉴权由 DSH 负责;日志里可能打印 provider / model 名,不含密钥。
生命周期脚本无:package.json 没有 scripts,没有 postinstall 之类的安装期脚本。
已知风险① 峰时它会主动改变你的请求(默认用一条短提示顶替大请求)⇒ 先用 dryRun: true 或 mode: notify 观察;② 节假日日历来自第三方镜像源,插件已做质量校验(15~45 天、年份归属、并集合并、1 MB 上限、时间戳未来判损坏),但不能保证第三方源不被篡改;③ 分类与"重活"判定是启发式的,可能误判(设计上宁可放行);④ 它跑在宿主进程内,与宿主同权限。

English:

SurfaceWhat actually happens
Files (read)Reads the DSH plugin config (supplied by the host settings service, namespace peak-gate) and the holiday cache; it does not scan or read your project files.
Files (write)Writes exactly one file: the holiday cache, by default <DSH_HOME>/data/peak-gate/holidays-cn.json (relocatable via holidayCachePath).
NetworkHoliday-calendar updates are on by default: it requests three sources in order (jsDelivr → raw.githubusercontent → gh-proxy), fetching only the current year's calendar JSON, with an 8 s per-source timeout and a 1 MB response cap. Networking can be turned off entirely with autoHolidayCalendar: false or holidayCalendarUrls: []. It makes no other network requests.
External commandsCalls no external command, shell or subprocess; requires no root / administrator privileges.
CredentialsReads and stores no credentials (no API keys from environment variables, no credential files). Layer 2's classification call reuses the LLM route the host is already configured with; authentication is DSH's business. Logs may print provider / model names, never secrets.
Lifecycle scriptsNone: package.json has no scripts field and no postinstall-style install hooks.
Known risks① During peak it actively alters your requests (by default replacing a big request with a short notice) ⇒ observe it first with dryRun: true or mode: notify. ② The holiday calendar comes from third-party mirrors; the plugin validates it (15–45 days, year ownership, union merge, 1 MB cap, future timestamps treated as corrupt) but cannot guarantee a third-party source is untampered. ③ The classifier / "heavy work" decision is heuristic and can misjudge (by design it prefers to let things through). ④ It runs inside the host process and therefore shares the host's privileges.

Comments

Loading…

Similar plugins

dsh-peak-gate

by f20880479-lab

DeepSeek Harness 峰谷计费插件:高峰时段发送前确认(可勾选本次高峰段内不再提示),支持将消息排队到空闲时段(半价)自动发送;可拖拽悬浮队列窗口、调整发送顺序与时间。

Terminal & ClientsManifest valid

★ 3

↓ 98/wk

MIT

JavaScript

Aug 26, 2026

dsh plugin --profile web add dsh-peak-gate

by huanyuLv

DeepSeek Harness (DSH) Web 插件: 余额 + 峰谷计价潮汐提示。显示 DeepSeek 账户余额与本会话花费, 并在余额前提示当前峰/谷价格档位、距切换倒计时与使用建议。

Terminal & ClientsTools & CapabilitiesModels & ProvidersDevelopment & InfrastructureManifest valid

★ 6

MIT

JavaScript

Aug 22, 2026

dsh plugin --profile web add dsh-balance-tide

by Leonx01

省钱闹钟:DeepSeek 峰谷计价低谷/高峰切换时,浏览器通知 + 国风提示音 + 页内 toast(DSH Web 插件 / dsh-plugin)

Manifest valid

★ 0

MIT

JavaScript

Aug 20, 2026

dsh plugin --profile web add peak-valley-alarm

by rinttt233

DSH(DeepSeek Harness)峰谷调度插件:高峰前 N 分钟自动生成仅供 AI 恢复用的简报并停自动续跑,高峰硬挡模型请求(带一键逃生),闲时自动注入简报继续任务。

Manifest valid

★ 0

MIT

JavaScript

Sep 28, 2026

dsh plugin --profile web add dsh-peak-brief

by godpanzz

DSH 插件:统计今日 token 用量与费用(按模型价格与峰谷计费),Web 侧栏面板 + /usage 命令

Manifest valid

★ 0

MIT

JavaScript

Aug 17, 2026

dsh plugin --profile web add dsh-usage

by 2006spy

DSH 实时 token 计费插件:官网人民币价直接计费、高峰/错峰自动切换、价格实时跟随官网、可视化自定义模型价格。Real-time token billing plugin for DeepSeek Harness (dsh web).

Tools & CapabilitiesTerminal & ClientsModels & ProvidersManifest valid

★ 3

MIT

JavaScript

Sep 11, 2026

dsh plugin --profile web add dsh-token-billing