Repository navigation
release: v0.1.4 — pre-model peak deferral and Chinese holiday-aware pricing - #9
Merged
Merged
Conversation
…oliday-aware pricing Move the peak hold to OpenCode v2's `model.request` hook, which runs while the model request is prepared and before the provider attempt (and its 300s response-header timeout) exists. A request submitted during peak no longer holds a provider attempt open or surfaces "Timed out waiting for response headers"; the same session continues the same turn at the scheduled off-peak boundary. The HTTP/WebSocket transport guard stays as the final hard barrier and the v0.1.3 retry recovery stays for requests that cross into peak in flight. Primary interactive holds persist a deferral while they wait and remove it on normal release, so a plugin reload or server restart during peak delivers exactly one same-session continuation. session.execution.interrupted events are handled by reason: inactivity keeps the deferral and continues the session; user clears it; superseded/shutdown abort the hold and leave recovery to OpenCode's own execution claim. The built-in deepseek-opencode-go policy now treats Chinese statutory public holidays as full-day OFF_PEAK through explicit holiday exception calendars evaluated on Asia/Shanghai, with the official 2026 State Council calendar in src/holidays.ts. Weekend make-up working days stay OFF_PEAK, nextTransition skips holiday windows (14-day scan), unknown years keep the deterministic weekly schedule, and a stored unmodified copy of the built-in policy adopts the built-in calendar so yearly updates apply without editing the config.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two user-reported issues, fixed on the supported OpenCode v2 lifecycle hooks.
1.
Timed out waiting for response headersduring PEAK. OpenCode 2.0.27 starts an attempt's response-header timeout (default 300s) at attempt start, before thehttp.requesthook chain completes. The v0.1.2–v0.1.3 guard held interactive peak requests insidehttp.request, so a peak-submitted request could sit in a transport attempt until the timeout fired. Verified from the 2.0.27 sources (packages/ai/src/route/transport/http.tswrapsruntime.http.executein the timeout;packages/core/src/session/model-request.tstriggershttp.requestinside it) and reproduced with the real binary against a local fixture.The deferral now happens at the supported
model.requesthook, which runs while the model request is prepared and before the provider attempt exists. The same session continues the same turn at the scheduled boundary, with zero provider traffic while pricing is blocked and no header-timeout wait. The transport guard remains unchanged as the final hard barrier.session.execution.interruptedevents are handled by reason:inactivitykeeps the deferral (OpenCode's 60-minute location-activity sweep),userclears it,superseded/shutdownabort the hold.2. Chinese public holidays are full-day OFF_PEAK. The policy model gains explicit full-day OFF_PEAK exception calendars (
year,dates,timeZone,source,verifiedAt,description) evaluated on the calendar's own time zone, overriding every weekly peak window.src/holidays.tsships the official 2026 State Council calendar (国办发明电〔2025〕7号): Jan 1–3, Feb 15–23, Apr 4–6, May 1–5, Jun 19–21, Sep 25–27, Oct 1–7. Weekend make-up workdays stay OFF_PEAK;nextTransitionskips holiday windows (14-day scan); unknown years keep the deterministic weekly schedule. A stored unmodified copy of the built-in policy adopts the built-in calendar so yearly updates apply without editing the config.The rule source is the DeepSeek pricing documentation ("…excluding Chinese public holidays. All other hours are off-peak, including weekends and Chinese public holidays in full."). Upstream open report anomalyco/opencode#53071 is recorded as the annual re-check cue (Go per-request billing is not observable).
Checks
npm run lint,npm run typecheck,npm test— 71 tests pass (new deferral, deferral-persistence, interrupt, and full 2026 holiday coverage).npm pack+ artifact validation.