Repository navigation
feat(cost): add override_dates to off_peak_pricing windows for holidays and make-up workdays - #42880
devin-ai-integration[bot] wants to merge 11 commits into
Conversation
|
I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
…icing windows A window rule can now list override_dates: YYYY-MM-DD dates read on the block's weekday_timezone calendar. On a listed date only the matching rules decide (weekdays ignored, flat hours_utc and other rules skipped); on any other date a rule carrying override_dates never applies. The DeepSeek rows model the 2026 PRC public holidays (off-peak all day) and make-up workdays (weekday off-peak hours) this way.
A rule carrying the override_dates key now never participates in the normal weekday path, even when its entries cannot be parsed, matching how a rule with fully malformed weekdays never matches. Previously a malformed override_dates was treated as absent, which let a whole-day rule silently widen the off-peak hours.
The shipped DeepSeek rows model PRC public holidays and make-up workdays, which the State Council notice declares on China Standard Time, so the rows now set weekday_timezone: Asia/Shanghai and their override_dates follow the Shanghai calendar instead of UTC.
There was a problem hiding this comment.
Devin Review found 2 potential issues.
2 flags not posted on this PR by your GitHub settings — view them in Devin Review. (Configure)
A window rule's override_dates now applies only when the value is a non-empty sequence of strings that all parse as YYYY-MM-DD. One malformed entry disables the whole list, matching how the rule already disappears when override_dates itself is malformed. Also updates the hand-written schema in test_utils for the new windows key.
Every direct DeepSeek row carrying off_peak_pricing now shares the same windows, weekday_timezone Asia/Shanghai, and override_dates for the 2026 public holidays and make-up workdays; each row keeps its own halved off-peak rates. A unit test moment that pinned 2026-09-25 (now a modeled holiday) moves to 2026-09-18.
…id hours override_dates entries are parsed as date objects with an exact YYYY-MM-DD shape, so week-date, ordinal, and whitespace-padded strings can never select a rule. An override rule also needs a parseable hours_utc, matching how ordinary rules without windows are skipped; previously a rule with broken hours won its date and billed peak all day.
cost-map-guard runs the base branch's generator, so a diff that edits ci_cd/generate_model_prices_schema.py makes its schema sync and validation checks stale by definition. The parse and backup checks still run, and the head generator is covered by the schema unit tests.
|
| }, | ||
| { | ||
| "hours_utc": "00:00-00:00", | ||
| "override_dates": [ |
There was a problem hiding this comment.
The shipped DeepSeek holiday and make-up-workday overrides contain only 2026 dates, with no renewal check or reminder in the changed tests. Without a refresh, later dates fall back to the ordinary weekday rules, silently bringing back the pricing errors this change addresses. An annual refresh safeguard would make that maintenance visible.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
…n the shipped dates
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 2c24623. Configure here.
what to review
DeepSeek bills off-peak all day on Chinese public holidays and peak on weekend make-up workdays; we priced both wrong. A window rule can now carry
override_dates, and the eight direct DeepSeek rows list the 2026 datessummary
override_datesbehave differently; every otheroff_peak_pricingblock prices as beforeweekdays, the flathours_utcand other rules are skippedoverride_dateshas any entry that is not aYYYY-MM-DDstring, or whosehours_utcdoes not parse, is disabled, not widened to every daycost_map_guard.pyskips its schema sync and validation steps when the PR also changes the generator, since it runs main's copy of the generator onpull_request_targetdecisions
hours_utc: "00:00-00:00"and a make-up day is a copy of the weekday hoursTLDR
Problem this solves:
How it solves it:
override_dateson a window rule: on those dates it alone decidesUser Flow
Before: a team routing to
deepseek/deepseek-flashis overcharged on holidays"model": "deepseek/deepseek-flash"x-litellm-response-costshows the peak rate, twice what DeepSeek charges that dayAfter: the same calls price the way DeepSeek bills them
"model": "deepseek/deepseek-flash"x-litellm-response-costshows the off-peak rate all dayoverride_datesin their ownmodel_infoRelevant issues
Follow-up of #41960
Linear ticket
Resolves LIT-8177
Follow-up of LIT-7469
How it works
_is_off_peaktakes the request's date on theweekday_timezonecalendar (UTC when unset). If a window rule lists that date inoverride_dates, the answer is whether the current time falls in that rule'shours_utc. Otherwise the flathours_utcand the weekday rules run as before, with rules that carryoverride_datesleft outThe DeepSeek rows set
weekday_timezone: Asia/Shanghaibecause the State Council declares the dates on China time. With DeepSeek's hours it changes no price: the two calendars only disagree 16:00 to 00:00 UTC, which DeepSeek bills off-peak on any day, and a 15 minute sweep of 2026 found zero differing instantsThe Rust catalog round-trips the cost map with
deny_unknown_fields, so it gets the key asOption<Vec<String>>. The JSON schema types it as a non-empty array ofYYYY-MM-DDstrings, so a typo in the shipped map fails schema CI.OffPeakPricingis not in the proxy OpenAPI spec, soschema.d.tsis unchangedDates and sources
Dates come from the State Council notice on the 2026 holiday arrangement, https://www.gov.cn/zhengce/zhengceku/202511/content_7047091.htm, read from the raw HTML on 2026-09-24. Holidays: 01-01 to 01-03, 02-15 to 02-23, 04-04 to 04-06, 05-01 to 05-05, 06-19 to 06-21, 09-25 to 09-27, 10-01 to 10-07. Make-up workdays: 01-04, 02-14, 02-28, 05-09, 09-20, 10-10
DeepSeek's pricing footnote, https://api-docs.deepseek.com/quick_start/pricing, states the policy: peak is 01:00 to 04:00 and 06:00 to 10:00 UTC, Monday to Friday, excluding Chinese public holidays. DeepSeek does not publish the date list. Weekend holiday dates are listed too so the list can be checked line by line against the notice
Pre-Submission checklist
Please complete all items before asking a LiteLLM maintainer to review your PR
uv run pytest tests/test_litellm/<your_test_file>.py -v. Leave the suites (make test-unit-*,make test-unit) to CI: it finishes in ~15 minutes where a laptop takes an hour or more@greptileaito re-request a review after pushing changes)Delays in PR merge?
If you're seeing a delay in your PR being merged, ping the LiteLLM Team on Slack (#pr-review).
Screenshots / Proof of Fix
Two proxies, base at the merge base and head at 09746bf (the later commit only adds
weekday_timezoneto the shipped rows), each with its own Postgres andLITELLM_LOCAL_MODEL_COST_MAP=True, both calling the real DeepSeek API on Thursday 2026-09-24 between 06:00 and 06:07 UTC, a peak window. Every call returned 200 with 36 prompt and 5 completion tokensds-stockis the shippeddeepseek/deepseek-flashrow.ds-holiday-weekend-ruleadds one rule to it:{"hours_utc": "00:00-00:00", "weekdays": [6, 7], "override_dates": ["2026-09-24"]}, which marks today as a holiday; theweekdayson it is what separates the two sides on a Thursday.ds-bad-overrideandds-bad-override-2put"2026-09-24"(bare string) and[20260924, null]on a00:00-00:00ruleBefore (port 4817)
ds-stock:x-litellm-response-cost: 1.6800000000000002e-05, peakds-holiday-weekend-rule:1.6800000000000002e-05, the key is unknown and Thursday is not in[6, 7]deepseek/deepseek-flash | 1.68e-05 | 36 | 5for bothAfter (port 4818)
ds-stock:1.6800000000000002e-05, same as base since today is not a holidayds-holiday-weekend-rule:8.400000000000001e-06, the override date selects that rule and itsweekdaysare ignoredds-bad-override,ds-bad-override-2:1.6800000000000002e-05on both, 200, no proxy error1.68e-05,8.400000000000001e-06,1.68e-05,1.68e-05, matching the headersGET /model/infofords-stockreturns 2 rules inoff_peak_pricing.windowson base and 4 on headMutation checks: reverting the override early return, the skip of nonmatching override rules, or the all-entries-parse rule each turns its test red
Type
New Feature
Caveats (if any)
Medium
Low
openrouter/deepseek/...rows keep their own schedule; OpenRouter's holiday policy is not documentedcost-map-guardis red on this PR and cannot go green from it: the check runs main's schema generator, which does not knowoverride_dates. The guard change here fixes that for the next generator PR but only once it is on main, so this one merges over the red required check (test_committed_schema_matches_generator_outputin the misc shard proves the schema is in sync with this PR's generator)Final Attestation
Link to Devin session: https://app.devin.ai/sessions/3e4563b49e964e089f8abcee782456ec
Open in Devin Desktop: https://app.devin.ai/desktop/session/3e4563b49e964e089f8abcee782456ec?variant=devin
Requested by: @shreshth-berri
Note
Medium Risk
Changes token billing logic in
_is_off_peakand ships date-specific rates for DeepSeek; incorrect dates or precedence would mischarge customers, though the PR adds broad tests and schema validation.Overview
Adds
override_dateson off-peak window rules so billing can follow calendar exceptions (e.g. all-day off-peak on holidays, weekday hours on weekend make-up days). On a listed date, only rules that include that date apply—theirhours_utcwins andweekdays, flathours_utc, and other windows are skipped; malformedoverride_datesor unparseablehours_utcdisable that rule instead of widening off-peak._is_off_peakinutils.pyimplements the precedence (dates read onweekday_timezone). The schema generator, committed schema, RustOffPeakWindow, andOffPeakWindowTypedDict document and validate the field. Direct DeepSeek entries in the cost map gain 2026 PRC holiday and make-up rules plusweekday_timezone: Asia/Shanghai.cost_map_guard.pyskips schema sync/validation when the PR also editsci_cd/generate_model_prices_schema.py, while still enforcing backup parity. Tests cover override behavior end-to-end and guard/schema drift checks.Reviewed by Cursor Bugbot for commit 2c24623. Bugbot is set up for automated code reviews on this repo. Configure here.