@@ -21,15 +21,45 @@ const MINUTE = 60_000;
2121const HOUR = 60 * MINUTE ;
2222const DAY = 24 * HOUR ;
2323
24- export function exhaustedUsageWindow ( provider : ServerProvider | undefined , now : number ) {
25- return provider ?. usageLimits ?. windows . find (
24+ export function exhaustedUsageWindow (
25+ provider : ServerProvider | undefined ,
26+ now : number ,
27+ model ?: string ,
28+ ) {
29+ const exhausted = ( provider ?. usageLimits ?. windows ?? [ ] ) . filter (
2630 ( window ) =>
2731 window . usedPercent !== undefined &&
2832 window . usedPercent >= 100 &&
2933 ( ! window . resetsAt ||
3034 ! Number . isFinite ( Date . parse ( window . resetsAt ) ) ||
3135 Date . parse ( window . resetsAt ) > now ) ,
3236 ) ;
37+ if ( model === undefined ) return exhausted [ 0 ] ;
38+ // Some drivers report separate allowances per model family; only the ones this model draws from count.
39+ switch ( provider ?. driver ) {
40+ case "cursor" : {
41+ const api = exhausted . find ( ( window ) => window . id === "apiPercentUsed" ) ;
42+ const auto = exhausted . find ( ( window ) => window . id === "autoPercentUsed" ) ;
43+ return / ^ ( a u t o | d e f a u l t | g r o k | c o m p o s e r ) / . test ( model ) ? auto && api : api ;
44+ }
45+ case "antigravity" : {
46+ const family = model . match ( / ^ ( g e m i n i | c l a u d e | g p t ) - / ) ?. [ 1 ] ;
47+ return exhausted . find ( ( window ) => {
48+ const pool = window . id . match ( / ^ ( g e m i n i | c l a u d e | g p t | 3 p ) - / ) ?. [ 1 ] ;
49+ return (
50+ pool === undefined ||
51+ pool === family ||
52+ ( pool === "3p" && ( family === "claude" || family === "gpt" ) )
53+ ) ;
54+ } ) ;
55+ }
56+ case "opencode" :
57+ return exhausted . find (
58+ ( window ) => ! window . id . startsWith ( "go_" ) || model . startsWith ( "opencode-go/" ) ,
59+ ) ;
60+ default :
61+ return exhausted [ 0 ] ;
62+ }
3363}
3464
3565export function resolveNewThreadModelSelection ( input : {
@@ -45,7 +75,7 @@ export function resolveNewThreadModelSelection(input: {
4575 const unchanged = { selection, fallback : null } ;
4676 if ( input . explicitSelection || ! selection || ! input . fallbackSelection ) return unchanged ;
4777 const provider = input . providers . find ( ( entry ) => entry . instanceId === selection . instanceId ) ;
48- const window = exhaustedUsageWindow ( provider , input . now ) ;
78+ const window = exhaustedUsageWindow ( provider , input . now , selection . model ) ;
4979 const fallback = input . providers . find (
5080 ( entry ) => entry . instanceId === input . fallbackSelection ?. instanceId ,
5181 ) ;
@@ -56,7 +86,7 @@ export function resolveNewThreadModelSelection(input: {
5686 ! fallback . installed ||
5787 fallback . auth . status === "unauthenticated" ||
5888 ! isProviderAvailable ( fallback ) ||
59- exhaustedUsageWindow ( fallback , input . now ) ||
89+ exhaustedUsageWindow ( fallback , input . now , input . fallbackSelection . model ) ||
6090 ( input . settings &&
6191 ! resolveProjectProviderInstanceEnabled (
6292 input . settings ,
0 commit comments