Skip to content

release: v0.1.4 — pre-model peak deferral and Chinese holiday-aware pricing - #9

Merged
lutzkind merged 1 commit into
mainfrom
release/v0.1.4
Oct 14, 2026
Merged

lutzkind merged 1 commit into
mainfrom
release/v0.1.4

Conversation

@lutzkind

Copy link
Copy Markdown
Owner

Summary

Two user-reported issues, fixed on the supported OpenCode v2 lifecycle hooks.

1. Timed out waiting for response headers during PEAK. OpenCode 2.0.27 starts an attempt's response-header timeout (default 300s) at attempt start, before the http.request hook chain completes. The v0.1.2–v0.1.3 guard held interactive peak requests inside http.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.ts wraps runtime.http.execute in the timeout; packages/core/src/session/model-request.ts triggers http.request inside it) and reproduced with the real binary against a local fixture.

The deferral now happens at the supported model.request hook, 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.

  • Primary interactive holds persist a deferral while they wait and remove it on normal release → plugin reload / server restart during peak still delivers exactly one same-session continuation.
  • session.execution.interrupted events are handled by reason: inactivity keeps the deferral (OpenCode's 60-minute location-activity sweep), user clears it, superseded/shutdown abort the hold.
  • v0.1.3 retry-veto recovery stays for requests that cross into peak in flight. No new runtime, database, daemon, scheduler, or polling loop.

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.ts ships 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; nextTransition skips 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.
  • Real OpenCode 2.0.27 + local fixture validation: peak-submitted interactive request deferred past a 5s provider header timeout with zero fixture traffic, released at the boundary in the same session (1 user / 1 assistant, no duplicates); queue task auto-started at the boundary; OFF_PEAK→PEAK retry recovery preserved; plugin reload and server restart keep exactly one continuation; v0.1.3 under the same harness still fails at 5s with the reported error.

…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.
@lutzkind
lutzkind merged commit 60f13ec into main Oct 14, 2026
2 checks passed
@lutzkind
lutzkind deleted the release/v0.1.4 branch October 14, 2026 11:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant