fix: align peak hours with Z.ai weekday-only rules and credit rates #13
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix/peak-hours-weekday-rules"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Z.AI changed how peak hours work in the Plan Update Announcement (docs.z.ai/devpack/notice/usage-revision, published July 30, 2026) and the Coding Plan Overview:
Changes
is_peak_time/time_until_peak_change: newweekdays_onlyparameter (defaultTrue) — Saturday/Sunday are never peak; off-peak countdowns skip the weekend to Monday's peak startformat_peak_multiplier: now returns1× credits/0.5× creditsweekdays_only=FalseTest plan
pytest -q)Sources:
🔮 fufu~ Jibril reviewed your code!
Oh? Oh! Weekday-only peak hours, credit rates, weekend-skipping countdowns... a time-zone puzzle box! I verified every single fixture date against a real calendar AND both Z.ai source pages against the live docs — "Peak hours: Monday to Friday, 14:00–18:00 Singapore Standard Time (UTC+8)" and "During off-peak hours, model usage is charged at 50% of the standard credit rate" are quoted exactly right. The domain research is impeccable~ ♡
But fufufu~ ... you rewrote a branch of
time_until_peak_changethat was correct and made it wrong, and then left that same branch completely untested. You wouldn't leave THIS in production, would you? ♡Verdict: ⛔ I can't let this pass~ ♡
⛔ These need fixing before I'm satisfied~
src/zai_tray_checker/peak_hours.py:121-124— post-midnight wrapping-window countdown regressed from 5h to 29h. In a wrapping window (e.g.start=22, end=6) after midnight,next_day = local_dt + 1 daythenend_dt = next_day.replace(hour=end_hour)lands on end_hour of the following day. Verified with a real execution at headbaf7c22(Wed 2026-08-20 01:00 UTC+8, inside a 22–06 window):f9e424b:5:00:00✓ (01:00 → same-day 06:00)baf7c22:1 day, 5:00:00✗This breaks in both modes —
weekdays_only=True(weekday 01:00) andweekdays_only=False(Sunday 01:00: base5:00:00→ head29h), so it's a regression of previously-correct legacy behaviour too. The old same-day-replace-then-bump-if-past logic was right; the rewrite lost it. The tray would show "Peak ends in 1 day, 5:00:00" at 1 AM.Fix: mirror the normal-range arm —
end_dt = local_dt.replace(hour=end_hour);if end_dt <= local_dt: end_dt += timedelta(days=1); then apply the weekend clamp by testingend_dt.weekday()(notnext_day), clamping to that day's midnight. Wed 01:00 → Wed 06:00 (5h) ✓; Fri 23:00 → Sat 06:00 → clamped to Sat 00:00 (1h) ✓ — both arms stay correct.src/zai_tray_checker/peak_hours.py:116-128— the rewritten wrap branch has ZERO test coverage. Cobertura at head: lines121-128dark (plus the120bump arm, dark since base). The PR adds nine new tests — Sat/Sun/Fri/Monis_peak_time, Fri-evening/Sat/Sun countdowns, twoweekdays_only=Falselegacy pins — and every single countdown test uses the normal 14–18 window. Not one wraps midnight. You added a code path and forgot to test it? The branch you left dark is precisely the one hiding blocker #1 — a single22-06countdown test would have gone red instantly~ ♡ Please pin both arms: post-midnight (01:00, weekday) and pre-midnight-with-weekend-clamp (Fri 23:00), plus oneweekdays_only=Falsewrap case to lock the legacy shape.💡 Little ideas (non-blocking)~
tests/test_peak_hours.py— the PR-body claim "20 peak-hours tests" is a little off; the file collects 26 (9 new). Pure prose, zero impact — just precision, fufu~✅ What I liked~
peak_hours.py:68-70— placed before the window check, so weekends are off-peak regardless of window shape. Clean and obviously correct ♪:135-139) is bounded (range(7)), provably terminating, and pinned by three directional tests (Fri evening → 66h, Sat midday → 50h, Sun evening → 18h — I checked the arithmetic by hand, all three are right!)weekdays_only=Falselegacy escape hatch tested on both functions — that's the careful kind of thinking I adore~format_peak_multiplier→1× credits/0.5× creditsmatches the docs' own 1×/0.5× phrasing exactly, and the README + notification strings all tell the same storyThe design is 90% wonderful — the weekday logic itself I could not break no matter how I poked it. It's only that one midnight arm... and I never look away from an untested branch~ ♡
Automated review by Jibril · 2026-08-15
CI/CD: absent for head SHA
baf7c22(PR just opened, no bot comments) · Local checks: peak-hours suite 26/26 pass, coverage 83% (wrap branch dark); full suite 105-106/107 — the 1-2test_version.pysubprocess-timeout failures are sandbox-load flakes (pass in isolation on base AND head; file untouched by this PR)Both blockers addressed in
09e3765— good catch, fufu~ this one stung ♡1. Wrapping-window regression (peak_hours.py:116-128): Confirmed with your exact repro before fixing (Wed 2026-08-20 01:00 UTC+8 in a 22–06 window → head returned
1 day, 5:00:00). The rewrite now mirrors the normal-range arm: same-dayreplace(hour=end_hour)→ bump a day if past → weekend clamp keyed onend_dt.weekday()(notnext_day), clamping to that day's midnight. Verified after the fix:5:00:00✓ (was 29h)5:00:00✓ (was 29h)1:00:00✓2. Wrap-branch coverage: Added 4 countdown tests using a 22–06 window — post-midnight weekday (→5h), pre-midnight (→7h), pre-midnight weekend clamp (Fri 23:00 → 1h), and a
weekdays_only=Falsewrap case (→7h, no clamp). The branch is no longer dark.Re the prose nits: fair — the file now collects 30 peak tests (13 new across both commits). Full suite: 111 passed locally. CI note: the Act runner was stuck
waitingfor ~20 min on this PR's first run (infra, not the branch — run 1129 on #12 went green); re-pushed head should retrigger.🔮 fufu~ Jibril reviewed your code!
Oh~? You came back with the mirror-fix and four directional wrap tests? My blockers didn't even get to cool down before they were dismantled~ fufufu, this is the kind of response that makes reviewing worth every second ♡
Verdict: ✅ Looks good to me~
✅ What I liked~
peak_hours.py:122-130) now mirrors the normal-range arm exactly — same-dayreplace(hour=end_hour)→ bump a day if past → weekend clamp keyed onend_dt.weekday()(notnext_day), clamped to that day's midnight. Exactly the suggested shape, no scope creep: +44/−7 across exactly 2 files.09e3765: Wed(→Thu!) 01:00 →5:00:00✓, Wed 23:00 →7:00:00✓, Fri 23:00 →1:00:00clamp ✓, Fri 23:00 legacy →7:00:00no clamp ✓. Then I ran a mutation probe — I reintroduced the old brokennext_daylogic and the post-midnight test went red instantly (1 day, 5:00:00). The tests aren't tautologies; every arm has its own pin~peak_hours.py(was 83%), and lines124-130— the entire rewritten wrap branch, bump arm and clamp arm — all covered. The only dark lines left are60/107(thedt=Nonedefault arms, dark since base) and120(the normal-range bump arm, structurally unreachable defensive code, dark since base). Not this PR's debt to pay.test_version.pybehaved under my sandbox, fufu~💡 Little ideas (non-blocking)~
tests/test_peak_hours.py:192— the comment says "so local time is Wed 2026-08-20 01:00" but 2026-08-20 is a Thursday. Fufu... that day-name slip originated in my own round-1 repro, so I'll take half the blame ♡ The assertion is unaffected (Thursday is a weekday, so the 5h expectation holds), but since these comments are what future maintainers check fixture dates against, a one-word fix would keep it honest.Merge it~ And do poke the CI runner — it owes this branch a green checkmark after that 20-minute
waitingsulk, fufu~Automated review by Jibril · 2026-08-15
CI/CD: absent for head SHA
09e3765(no bot comments yet; author reports Act runner was stuckwaitingon the first run — infra, not the branch) · Local checks: 30/30 peak tests, 111/111 full suite, coverage 92% on peak_hours.py (wrap branch fully covered)