@@ -2,6 +2,7 @@ import { beforeEach, describe, expect, test } from 'bun:test'
22
33import {
44 FREEBUFF_GEMINI_PRO_MODEL_ID ,
5+ FREEBUFF_GLM_MODEL_ID ,
56 FREEBUFF_KIMI_MODEL_ID ,
67} from '@codebuff/common/constants/freebuff-models'
78
@@ -223,6 +224,54 @@ describe('requestSession', () => {
223224 expect ( deps . rows . size ) . toBe ( 0 )
224225 } )
225226
227+ test ( 'legacy GLM 5.1 model is still accepted for old clients during deployment hours' , async ( ) => {
228+ deps . _tick ( new Date ( '2026-04-17T16:00:00Z' ) )
229+ const state = await requestSession ( {
230+ userId : 'u1' ,
231+ model : FREEBUFF_GLM_MODEL_ID ,
232+ deps,
233+ } )
234+ expect ( state . status ) . toBe ( 'queued' )
235+ if ( state . status !== 'queued' ) throw new Error ( 'unreachable' )
236+ expect ( deps . rows . get ( 'u1' ) ?. model ) . toBe ( FREEBUFF_GLM_MODEL_ID )
237+ expect ( state . rateLimit ) . toEqual ( {
238+ model : FREEBUFF_GLM_MODEL_ID ,
239+ limit : 5 ,
240+ windowHours : 12 ,
241+ recentCount : 0 ,
242+ } )
243+ } )
244+
245+ test ( 'legacy GLM 5.1 active session can be reclaimed outside deployment hours' , async ( ) => {
246+ const admittedAt = new Date ( deps . _now ( ) . getTime ( ) - 10 * 60 * 1000 )
247+ deps . rows . set ( 'u1' , {
248+ user_id : 'u1' ,
249+ status : 'active' ,
250+ active_instance_id : 'inst-pre' ,
251+ model : FREEBUFF_GLM_MODEL_ID ,
252+ queued_at : admittedAt ,
253+ admitted_at : admittedAt ,
254+ expires_at : new Date ( deps . _now ( ) . getTime ( ) + SESSION_LEN ) ,
255+ created_at : admittedAt ,
256+ updated_at : admittedAt ,
257+ } )
258+
259+ const state = await requestSession ( {
260+ userId : 'u1' ,
261+ model : FREEBUFF_GLM_MODEL_ID ,
262+ deps,
263+ } )
264+ expect ( state . status ) . toBe ( 'active' )
265+ if ( state . status !== 'active' ) throw new Error ( 'unreachable' )
266+ expect ( state . instanceId ) . not . toBe ( 'inst-pre' )
267+ expect ( state . rateLimit ) . toEqual ( {
268+ model : FREEBUFF_GLM_MODEL_ID ,
269+ limit : 5 ,
270+ windowHours : 12 ,
271+ recentCount : 0 ,
272+ } )
273+ } )
274+
226275 test ( 'queued response includes a per-model depth snapshot for the selector' , async ( ) => {
227276 deps . _tick ( new Date ( '2026-04-17T16:00:00Z' ) )
228277 // Seed 2 users in MiniMax + 1 in Kimi so the returned map captures both.
@@ -436,6 +485,29 @@ describe('requestSession', () => {
436485 expect ( deps . rows . has ( 'u1' ) ) . toBe ( false )
437486 } )
438487
488+ test ( 'rate_limited: legacy GLM 5.1 keeps the deployment-hours quota' , async ( ) => {
489+ deps . _tick ( KIMI_OPEN_TIME )
490+ const now = deps . _now ( )
491+ for ( let i = 0 ; i < KIMI_LIMIT ; i ++ ) {
492+ deps . admits . push ( {
493+ user_id : 'u1' ,
494+ model : FREEBUFF_GLM_MODEL_ID ,
495+ admitted_at : new Date ( now . getTime ( ) - ( i + 1 ) * 60 * 60 * 1000 ) ,
496+ } )
497+ }
498+
499+ const state = await requestSession ( {
500+ userId : 'u1' ,
501+ model : FREEBUFF_GLM_MODEL_ID ,
502+ deps,
503+ } )
504+ expect ( state . status ) . toBe ( 'rate_limited' )
505+ if ( state . status !== 'rate_limited' ) throw new Error ( 'unreachable' )
506+ expect ( state . model ) . toBe ( FREEBUFF_GLM_MODEL_ID )
507+ expect ( state . limit ) . toBe ( KIMI_LIMIT )
508+ expect ( state . windowHours ) . toBe ( KIMI_WINDOW_HOURS )
509+ } )
510+
439511 test ( 'rate_limited: admits outside the 12h window do not count' , async ( ) => {
440512 deps . _tick ( KIMI_OPEN_TIME )
441513 // 5 admits, each just over 12h old → all fall off the window.
0 commit comments