Introduction¶
When running long tasks with DeepSeek, the biggest variable on the bill is not the model, but the time period. Weekdays 09:00–12:00 and 14:00–18:00 are at full price, while weekends and statutory holidays are off-peak (50% discount). Manually monitoring the clock to pause is both unrealistic and prone to misses; writing scripts to kill sessions periodically will also lose pending tasks. DSH’s plugin mechanism allows for this at the session controller level. The dsh-offpeak-guard plugin introduced below is a plugin in this direction: it reads DeepSeek’s peak/off-peak rules and the current session’s real model, pauses tasks during peak hours, automatically resumes them during off-peak hours, and schedules requests like “run after 12 o’clock” into the next off-peak window.
What is this¶
dsh-offpeak-guard is maintained by HATO-24, categorized under “Workflow” in the DSH Community Directory, and licensed under MIT. The corresponding package name on npm is dsh-offpeak-guard. It does not replace DSH’s task system but implements a price window scheduling layer at the session level: identifying whether the current time is peak or off-peak and deciding whether to allow currently running and upcoming tasks to proceed.
The core approach relies on two orthogonal judgments:
- Time: Determines peak/off-peak windows based on DeepSeek’s official rules, including handling of statutory holidays;
- Model: Determines if the session’s real
provider / modelis a peak/off-peak priced model based on its name, avoiding false positives on irrelevant models.
The plugin intervenes only when both conditions are met; otherwise, the plugin remains inactive.
Core Features¶
Time Recognition¶
According to DeepSeek’s official rules, Beijing Time weekdays (excluding Chinese statutory holidays) 09:00–12:00 and 14:00–18:00 are peak full-price hours; all other times (including weekends and statutory holidays) are off-peak hours, billed at a 50% discount. Holidays are dynamically synced from public APIs by default, falling back to a built-in 2026 list upon failure.
Model Recognition¶
The plugin precisely determines based on the session’s real provider / model. By default, if the model name (or vendor name) contains deepseek, it is managed; you can also toggle models individually in the settings panel, or use peakPricedModels / exemptModels for precise control. These two lists take precedence over modelPattern when non-empty.
Peak Strategy & Session Exemption¶
- Strategy options are “Pause immediately” or “Pause after current turn”;
- If a session has sub-agents running, the sub-agents are allowed to proceed first, and the parent session is paused after the sub-agents finish, resuming when off-peak begins;
- You can exempt a specific session from pause/resume by using the settings panel or
offpeak_guard exempt/unexempt, which can be canceled at any time.
Workflow Planning¶
- Peak starts → Pause running tasks, retain the pending queue, and do not lose messages;
- New tasks during peak → Stop immediately to avoid spending peak tokens;
- Off-peak starts → Automatically hand the interrupted tasks back to the session to continue execution;
- Provides the
offpeak_plantool to schedule tasks like “run after 12 o’clock” into the next off-peak window.
Interface¶
There is a status bar below the input box displaying the current peak/off-peak status, a countdown to the next switch, the current model, and the count of paused/planned tasks. There is also a permanent timer in the bottom left corner of the sidebar, which flashes colors to warn when switching is imminent: red flash when peak price is about to start, green when off-peak price is about to start. Clicking the timer in the sidebar opens the settings panel, where you can switch peak strategies, manage models individually, exempt sessions, and check holiday sync status.
It also supports on-the-spot exemption: hover over the session row in the sidebar, a shield button appears at the end of the row, click to exempt or cancel; there is also an “Exempt this session” button on the right side of the input box status bar.
Installation & Activation¶
The plugin is published to npm. Search for dsh-offpeak-guard on the DSH plugin page to install, or use the command line:
dsh plugin --profile <profile> add dsh-offpeak-guard
After installation, it is recommended to run offpeak_status once to confirm that the identified period and model match expectations.
Environment requirements (from engines in package.json):
{ "node": ">=22.5", "dsh": ">=0.2.1-rc.2 <0.3.0" }
Typical Usage¶
The plugin provides three tools covering query, planning, and manual control.
| Tool | Purpose |
|---|---|
offpeak_status |
Current period, next switch, whether current model applies, pause and planning lists |
offpeak_plan |
add / list / remove / clear off-peak scheduling |
offpeak_guard |
status / pause_now / resume_now / run_plans_now manual control |
The typical workflow is:
- A long task is running; first check
offpeak_statusto confirm it is off-peak and how long until peak, and decide whether to let it continue; - If peak is about to start, do not send new tasks yet; use
offpeak_plan addto schedule it into the next off-peak window; - After peak starts, the plugin pauses running tasks according to the set strategy, updating the status bar and pause count;
- When off-peak starts, tasks are automatically handed back to the session to run, and you can see recovery records in
offpeak_status; - In cases where immediate execution is required, use
offpeak_guard pause_now/resume_nowto intervene manually;resume_nowgrants these sessions a 10-minute exemption to avoid being paused again immediately after resuming.
Configuration¶
Configuration can be written in the config section of offpeak-guard in cordis.patch.yml, or modified in the plugin configuration on the DSH settings page (the plugin has declared a Config schema). Common keys are listed below, with default values as declared in package.json.
config:
enabled: true
preset: auto
pauseMode: pause-now
timezone: Asia/Shanghai
modelPattern: deepseek
peakPricedModels: []
exemptModels: []
pauseRunningOnPeak: true
deferNewTurnsOnPeak: true
resumeOnOffPeak: true
pollSeconds: 15
resumeDelaySeconds: 3
bypassMinutes: 10
alertMinutes: 10
Key meanings:
enabled: Master switch;preset:autoselects automatically based on provider,workbuddyfor WorkBuddy/CodeBuddy, others usedeepseek-official; can also be fixed todeepseek-official/workbuddy/custom;pauseMode:pause-nowpauses immediately during peak,finish-turnpauses after the current turn finishes;timezone: Pricing timezone, defaultAsia/Shanghai;peakWeekdays/peakWindows/discount: Only used with thecustompreset; modify here for official pricing changes or switching vendors;holidays: Additional statutory holidays,YYYY-MM-DD;holidaySource:autofor dynamic sync,builtinuses only built-in/configured lists;modelPattern/peakPricedModels/exemptModels: Model matching and exemption;pauseRunningOnPeak/deferNewTurnsOnPeak/resumeOnOffPeak: Three main strategy switches;pollSeconds: Check interval, range 5–300;resumeDelaySeconds: Wait a few seconds after off-peak starts before resuming;bypassMinutes: Exemption period after manual resume;alertMinutes: The sidebar timer starts flashing when the switch is within this many minutes,0means no flash.
Environment Variables¶
The deployer can inject configuration uniformly using environment variables. The priority is Environment Variables > Configuration > Default, invalid values are ignored. The naming convention is the DSH_OFFPEAK_ prefix followed by the uppercase underscore version of the config key, for example:
DSH_OFFPEAK_PRESET=custom
DSH_OFFPEAK_PAUSE_MODE=finish-turn
DSH_OFFPEAK_PEAK_WINDOWS=09:00-12:00,14:00-18:00
DSH_OFFPEAK_DISCOUNT=0.5
DSH_OFFPEAK_HOLIDAYS=2026-10-01,2026-10-02
DSH_OFFPEAK_MODEL_PATTERN=deepseek
DSH_OFFPEAK_PEAK_MODELS=deepseek-flash,vendor/model
DSH_OFFPEAK_BYPASS_MINUTES=10
See README for the full list, covering enabled, timezone, peakWeekdays, holidaySource, holidayApi, pollSeconds, and all other configuration items.
Presets¶
deepseek-official(default): Official peak hours on weekdays + built-in 2026 statutory holidays, off-peak for holidays;workbuddy: WorkBuddy credit rules, peak windows are same as official, used to mark source when auto-selecting by provider;custom: UsespeakWeekdays/peakWindows/discount/holidayscompletely, suitable for other vendors or custom pricing.
Data & Recovery Mechanism¶
State and snapshots are located in $DSH_HOME/offpeak-guard/:
state.json: Paused/waiting tasks, off-peak scheduling, session exemptions, precise model rules, peak strategies;status.json: Read-only snapshot for the input box status bar/settings panel, also mirrored to~/.dsh/offpeak-guard/status.json;holidays.json: Cached dynamic holiday sync.
The plugin does not write to the user workspace.
It uses sessionController.cancel for pausing, which ends only the current turn and preserves the pending queue; it uses sessionController.prompt for resuming, delivering a “continue from where it left off” instruction to the original session, automatically waking up cold sessions. The resume text notes the interruption time and the paused model, making it easy to trace in the conversation.
Sub-agents & Waiting¶
- When peak starts and a session has running sub-agents, the parent session and sub-agents are allowed to proceed first;
- After sub-agents finish, the parent session is paused according to the current strategy (recorded as
waiting-children) and automatically resumes when off-peak starts; - In
finish-turnmode, the current turn is allowed to finish; if a subsequent turn is queued, the next turn will be blocked during peak and recorded, resuming when off-peak starts; - When the current turn finishes and there are no subsequent turns, it is marked as
completedand will not start a new turn meaninglessly during off-peak.
Note: The plugin only stops the parent session when sub-agents finish; it cannot intercept messages that have already entered the parent session history at the transport layer. Sub-agent results are consumed by the model after the parent session resumes.
Use Cases & Notes¶
Suitable for these three types of usage:
- People running long or batch tasks who want to minimize token costs during off-peak windows;
- People who need to delegate “run at a certain time” arrangements to the model rather than writing cron jobs manually;
- Operations teams deploying for teams who want to inject peak/off-peak strategies uniformly via environment variables.
Points to note:
- The plugin intervenes in sessions via
sessionController, running with the permissions of the current DSH process. It is recommended to read the source code before installation to confirm behavior matches expectations; the license is MIT; - Built-in statutory holidays currently cover 2026; before the 2027 schedule is announced, use
holidaysorDSH_OFFPEAK_HOLIDAYSto append when dynamic sync fails, otherwise holidays will be treated as regular weekdays; - Dynamic holidays come from a third-party public API (default timor.tech, sends only the year). It falls back to
holidays.jsoncache and built-in list when offline or API fails. SetholidaySource: builtinfor completely offline use; - Only handles root sessions with a working directory and non-sub-agents to avoid interrupting sub-agents and causing the parent session to hang;
- “Session exemption” only affects subsequent pause/resume and does not automatically resume paused tasks immediately; use
resume_nowif needed; - The plugin itself does not actively interrupt running tasks when it restarts; subsequent peak times or new tasks will still be handled according to rules.
Conclusion¶
The value of dsh-offpeak-guard lies in turning peak/off-peak pricing into an automatic strategy at the session layer, rather than relying on memory or one-off scripts. It works with DSH’s existing pause/resume mechanisms, ensuring no queue loss, exemption capability, and traceability, making it suitable as the default first layer of cost control for daily tasks.
Directory: https://www.skillhub.cn/plugins/HATO-24/dsh-offpeak-guard
GitHub: https://github.com/HATO-24/dsh-offpeak-guard