diff --git a/src/lib/rateLimits.ts b/src/lib/rateLimits.ts index 95359a2..21ad93e 100644 --- a/src/lib/rateLimits.ts +++ b/src/lib/rateLimits.ts @@ -65,10 +65,18 @@ export const DEFAULT_RATE_LIMITS: RateLimitsConfig = { // mirror the backend policy (cloud-api modelRateLimits + the token cap for // glm5.3) and the usage hook's window budget, which is the same set of // numbers the member portal publishes. + // + // contextTokens mirrors the backend EXACTLY: 1,048,576, raised from 500,000 + // on 2026-09-10 and exactly what the Novita primary serves. It renders as + // "1M" because formatTokens rounds the display, which is the layer that + // should do it — publishing a rounded 1,000,000 here would leave the site + // 4.8% below the source it claims to mirror, and would turn the test below + // from an equality into a floor. The equality is the mechanism: it is what + // makes a backend change fail here instead of shipping quietly. windowedModels: [ { model: 'glm5.3', - contextTokens: 1_000_000, + contextTokens: 1_048_576, maxParallel: 5, windowHours: 4, windowTokens: 400_000_000, @@ -89,7 +97,16 @@ export function formatTokens(tokens: number, lang: DocsLocale = 'en'): string { // cannot read "3,000M" next to a model card that says "3.000M". // `useGrouping: 'always'` because es-ES leaves four-digit numbers ungrouped, // which would print 3000M beside a model card that already says 3.000M. - const fmt = new Intl.NumberFormat(lang === 'es' ? 'es-ES' : 'en-US', { useGrouping: 'always' }); + // `maximumFractionDigits: 0` so a window of 1,048,576 prints "1M" and not + // "1,049M". Without it the page shows a decimal comma (1,049M) next to a + // thousands dot (3.000M) in es-ES — both correct, and confusing side by + // side. Rounding the DISPLAY is the right layer: the published constant + // stays equal to the backend, so the test below can keep asserting + // equality rather than a floor. + const fmt = new Intl.NumberFormat(lang === 'es' ? 'es-ES' : 'en-US', { + useGrouping: 'always', + maximumFractionDigits: 0, + }); if (tokens >= 1_000_000) return `${fmt.format(tokens / 1_000_000)}M`; if (tokens >= 1_000) return `${fmt.format(tokens / 1_000)}K`; return String(tokens); diff --git a/src/tests/lib/rateLimits.test.ts b/src/tests/lib/rateLimits.test.ts index 13cf237..3bc56ea 100644 --- a/src/tests/lib/rateLimits.test.ts +++ b/src/tests/lib/rateLimits.test.ts @@ -16,7 +16,7 @@ import { * were the ones that do not apply to them. These asserts pin the four numbers * to what the platform actually enforces: * - * context 1,000,000 cloud-api usage_quota.go modelRateLimits + * context 1,048,576 cloud-api usage_quota.go modelRateLimits * concurrency 5 idem, and the ratelimit hook * 400M per rolling 4h ratelimit hook ROLLING_WINDOW_S / rolling budget * 3,000M per period cloud-api usage_quota.go monthlyTokenCaps @@ -25,7 +25,7 @@ import { * change: the failure is the point. */ const GLM = { - contextTokens: 1_000_000, + contextTokens: 1_048_576, maxParallel: 5, windowHours: 4, windowTokens: 400_000_000,