Skip to content

feat(pricing): weekends bill off-peak, and the vision model is on the card - #23

Merged
lroolle merged 1 commit into
mainfrom
pricing-weekend-vision
Aug 24, 2026
Merged

feat(pricing): weekends bill off-peak, and the vision model is on the card#23
lroolle merged 1 commit into
mainfrom
pricing-weekend-vision

Conversation

@lroolle

@lroolle lroolle commented Aug 24, 2026

Copy link
Copy Markdown
Member

Two upstream changes since 2026-08-17, neither of which reached us through a changelog.

Weekends are off-peak

From 16:00 UTC on 2026-08-22 (00:00 Beijing, Sun 23 Aug), a Saturday or Sunday bills off-peak for all 24 hours. Peak is 35 hours a week, not 49 — so anything reading the hour alone reports peak for 14 hours a week the account is charged half for.

DeepSeek published no changelog entry. The announcement sat in the pricing-page footnote for a few days before it took effect, and the live page now carries only the settled rule, so it exists nowhere on api-docs.deepseek.com today. The citable source is the archived copy, recorded next to the constant in all three places that hold it:

Effective 00:00 (Beijing Time) on Sunday, August 23, 2026, we will adjust our peak/off-peak billing rules, with off-peak rates applying throughout the day on weekends (Saturdays and Sundays, Beijing Time).

The weekday is read on the vendor's clock, because that last parenthesis is the rule as written — which puts the turnover at 16:00 UTC, not midnight UTC. A Friday evening in Europe is already Saturday upstream.

That choice is untestable by ordinary means and worth being explicit about. Both windows close at 10:00 UTC, well before the 16:00 UTC point where a UTC date and a Beijing date diverge, so the two readings label all 168 hours of the week identically and any test written against the published windows passes with the shift deleted. The tests therefore pin the instants that do discriminate. Verified by mutation, per copy:

copy mutation result
internal/deepseek weekday read in UTC 1 failed — TestWeekendTurnsOverOnTheVendorClock
internal/deepseek boundary gate removed 1 failed — TestWeekendRuleDoesNotRepriceHistory
gateway/…/meter weekday read in UTC 1 failed — TestWeekendIsReadOnTheVendorClock
site/pricing.js BEIJING_OFFSET_MS = 0 2 failed — the two onDay vectors

Each dies to a targeted test and nothing else, which is the point: without those vectors every mutant passes the whole suite.

The boundary is kept, not backdated

Gated on its own instant rather than folded into RepriceAt. Working it through, exactly one weekend day ever billed peak under time-of-use:

Sun 2026-08-16   windows had already passed when time-of-use began  -> flat
Sat 2026-08-22   time-of-use live, weekend rule not yet             -> PEAK
Sun 2026-08-23   weekend rule live from 00:00 Beijing               -> off-peak

A ledger that refunds that Saturday is inventing money the account never got back. TestWeekendRuleDoesNotRepriceHistory pins all three rows.

The vision model was metering at zero

deepseek-v4-flash-vision-exp shipped 2026-08-21, priced exactly as flash on every bucket in both currencies, and was absent from the card — so a call to it cost nothing, in the CLI's estimates and in the gateway's budget.

Added, plus a single deepseek.Models list, because it was missing from three separate hardcoded []string{ModelFlash, ModelPro} iterations. The next model reaches every table at once.

It lands in three copies, on purpose

copy why it is separate
internal/deepseek the CLI's card and clock
gateway/…/meter separate Go module, no shared import. make price-check guarded the numbers; nothing guarded the clock, so it now has tests that do
site/build.py the schedule gained a days axis; pricing.js reads it, pricing.test.js pins it

The gateway's drift ran the safe direction — over-charging our own budget rather than under — but it still made /economics report a cost-per-task nobody paid.

One process note worth keeping: I first edited the generated site/pricing/index.html directly. make site-check caught it and I redid the work in build.py. That check earned its keep.

Also in here

Verified

  • make check — green end to end: fmt, vet, go test ./..., corpus-check, price-check (5 matching rate-card rows across both modules), build, gateway-check, site-check, bans.
  • ds pricing prints the vision row and peak hours … Mon-Fri; all other hours, and all weekend, off-peak.
  • The pricing page rendered headless on a faked Beijing Saturday: off-peak, next peak in 46h59m. dsh-meter, written independently, gives the same answer for the same instant.

🤖 Generated with Claude Code

… card

Two upstream changes, neither of which reached us through a changelog.

WEEKENDS. From 16:00 UTC on 2026-08-22 (00:00 Beijing, Sun 23 Aug) a
Saturday or Sunday bills off-peak for all 24 hours. Peak is 35 hours a
week, not 49, so anything reading the hour alone was reporting peak for
14 hours a week the account was being charged half for.

The weekday is read on the vendor's clock, because that is how DeepSeek
wrote it -- "Saturdays and Sundays, Beijing Time" -- which puts the
turnover at 16:00 UTC, not midnight UTC. With today's windows the UTC and
Beijing readings label all 168 hours identically (both windows close at
10:00 UTC, before the dates diverge), so the tests pin the two instants
that do discriminate; deleting the shift fails exactly one test in each
of the three copies.

Gated on its own instant rather than folded into RepriceAt. Exactly one
weekend day ever billed peak under time-of-use -- Saturday 2026-08-22,
since Sunday 08-16's windows had passed before the switchover -- and a
ledger that refunds it is inventing money.

DeepSeek published no changelog entry. The announcement sat in the
pricing-page footnote for a few days and the live page now carries only
the settled rule, so the citable source is the archived copy, recorded
next to the constant in all three places that hold it.

VISION. deepseek-v4-flash-vision-exp shipped 2026-08-21, priced exactly
as flash in both currencies, and was absent from the card -- which meters
it at zero. Added, along with a single deepseek.Models list so the next
model reaches every table at once rather than three of them.

Landing in three copies, because the gateway is a separate module and the
site is generated:

- internal/deepseek  the CLI's card and clock
- gateway/…/meter    its own copy; `make price-check` guards the numbers,
                     and it now has tests guarding the clock too. Its drift
                     ran the safe way (over-charging our own budget) but it
                     still made /economics report a cost nobody paid.
- site/build.py      the schedule gained a `days` axis; pricing.js reads it,
                     pricing.test.js pins it. Editing the generated HTML is
                     what `site-check` exists to catch, and it caught me.

Also: the embedded docs corpus is repacked from the mirror, so `ds docs
show quick_start/pricing` carries the Monday-through-Friday footnote and
the third pricing column; two news entries; llms.txt.

Verified: `make check` green, and the pricing page rendered headless on a
faked Beijing Saturday reads off-peak with the next peak 46h59m out --
the same answer dsh-meter gives.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@lroolle
lroolle merged commit 5a415a2 into main Aug 24, 2026
8 checks passed
@lroolle
lroolle deleted the pricing-weekend-vision branch August 24, 2026 03:48
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