@@ -34,6 +34,20 @@ export type UsageLimitResolution =
3434 | { readonly type : "finalize" ; readonly resetAt : IsoDateTime | null } ;
3535
3636export const DEFAULT_LIMIT_COOLDOWN_MS = 15 * 60_000 ;
37+ // Per-minute burst limits recover quickly and should not park a healthy account.
38+ export const BURST_LIMIT_COOLDOWN_MS = 60_000 ;
39+
40+ export function limitCooldownUntilMs (
41+ failure : OrchestrationV2ProviderFailure ,
42+ nowMs : number ,
43+ ) : number {
44+ const resetMs = failure . resetAt == null ? Number . NaN : Date . parse ( failure . resetAt ) ;
45+ if ( resetMs > nowMs ) return resetMs ;
46+ return (
47+ nowMs +
48+ ( failure . code === "rateLimitExceeded" ? BURST_LIMIT_COOLDOWN_MS : DEFAULT_LIMIT_COOLDOWN_MS )
49+ ) ;
50+ }
3751
3852/**
3953 * Runs between a usage-limit terminal and the run going terminal. A reference
@@ -59,14 +73,11 @@ const make = Effect.gen(function* () {
5973 input : UsageLimitedAttempt ,
6074 ) {
6175 const nowMs = DateTime . toEpochMillis ( yield * DateTime . now ) ;
62- const resetMs = input . failure . resetAt == null ? Number . NaN : Date . parse ( input . failure . resetAt ) ;
6376 // Every driver cools through this one site, pooled or not, so the
6477 // Providers page shows "Limited until" for any account.
6578 yield * catalog . markLimited ( {
6679 instanceId : input . providerInstanceId ,
67- until : DateTime . formatIso (
68- DateTime . makeUnsafe ( resetMs > nowMs ? resetMs : nowMs + DEFAULT_LIMIT_COOLDOWN_MS ) ,
69- ) ,
80+ until : DateTime . formatIso ( DateTime . makeUnsafe ( limitCooldownUntilMs ( input . failure , nowMs ) ) ) ,
7081 } ) ;
7182 const asToday = { type : "finalize" , resetAt : input . failure . resetAt ?? null } as const ;
7283 const owner = findProviderPool ( yield * catalog . getPublishedProviders , input . providerInstanceId ) ;
0 commit comments