agent-shim 9.1.0 → 9.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.cjs CHANGED
@@ -31107,6 +31107,18 @@ function parseDuration(value2) {
31107
31107
  }
31108
31108
  return Number(count) * multiplier;
31109
31109
  }
31110
+ function windowValues(prefix, windows) {
31111
+ const values = {};
31112
+ for (const name of ["fiveHour", "sevenDay", "extraUsage"]) {
31113
+ const facts = windows?.[name];
31114
+ if (facts !== void 0) {
31115
+ values[`${prefix}.${name}.remaining`] = facts.remaining;
31116
+ values[`${prefix}.${name}.utilization`] = facts.utilization;
31117
+ values[`${prefix}.${name}.hoursUntilReset`] = facts.hoursUntilReset;
31118
+ }
31119
+ }
31120
+ return values;
31121
+ }
31110
31122
  function resolversOf(context) {
31111
31123
  const pool = context.pool;
31112
31124
  const values = {
@@ -31115,8 +31127,7 @@ function resolversOf(context) {
31115
31127
  ...context.fact?.totalSizeBytes === void 0 ? {} : { "entry.totalSizeBytes": context.fact.totalSizeBytes },
31116
31128
  ...context.branch === void 0 ? {} : { "repo.branch": context.branch },
31117
31129
  "repo.detached": context.branchDetached ?? false,
31118
- ...pool?.fiveHour === void 0 ? {} : { "quota.fiveHour.remaining": pool.fiveHour.remaining, "quota.fiveHour.utilization": pool.fiveHour.utilization, "quota.fiveHour.hoursUntilReset": pool.fiveHour.hoursUntilReset },
31119
- ...pool?.sevenDay === void 0 ? {} : { "quota.sevenDay.remaining": pool.sevenDay.remaining, "quota.sevenDay.utilization": pool.sevenDay.utilization, "quota.sevenDay.hoursUntilReset": pool.sevenDay.hoursUntilReset },
31130
+ ...windowValues("quota", pool),
31120
31131
  ...pool?.burnPerHour === void 0 ? {} : { "quota.burnPerHour": pool.burnPerHour },
31121
31132
  ...pool?.resuming === void 0 ? {} : { "session.resuming": pool.resuming },
31122
31133
  ...pool?.lastPickHoursAgo === void 0 ? {} : { "session.lastPickHoursAgo": pool.lastPickHoursAgo },
@@ -31127,12 +31138,7 @@ function resolversOf(context) {
31127
31138
  ...context.request?.maxTokens === void 0 ? {} : { "request.maxTokens": context.request.maxTokens },
31128
31139
  ...context.request?.isCountTokens === void 0 ? {} : { "request.isCountTokens": context.request.isCountTokens },
31129
31140
  ...context.providerQuota === void 0 ? {} : Object.fromEntries(
31130
- Object.entries(context.providerQuota).flatMap(
31131
- ([name, windows]) => [
31132
- ...windows.fiveHour === void 0 ? [] : [["provider." + name + ".fiveHour.remaining", windows.fiveHour.remaining], ["provider." + name + ".fiveHour.utilization", windows.fiveHour.utilization], ["provider." + name + ".fiveHour.hoursUntilReset", windows.fiveHour.hoursUntilReset]],
31133
- ...windows.sevenDay === void 0 ? [] : [["provider." + name + ".sevenDay.remaining", windows.sevenDay.remaining], ["provider." + name + ".sevenDay.utilization", windows.sevenDay.utilization], ["provider." + name + ".sevenDay.hoursUntilReset", windows.sevenDay.hoursUntilReset]]
31134
- ]
31135
- )
31141
+ Object.entries(context.providerQuota).flatMap(([name, windows]) => Object.entries(windowValues("provider." + name, windows)))
31136
31142
  )
31137
31143
  };
31138
31144
  return {
@@ -32529,9 +32535,313 @@ var init_paths = __esm({
32529
32535
  }
32530
32536
  });
32531
32537
 
32538
+ // src/usage/schema.ts
32539
+ function isRateLimitHeader(name) {
32540
+ const lower = name.toLowerCase();
32541
+ return lower === "retry-after" || lower.startsWith("anthropic-ratelimit-") || lower.startsWith("x-ratelimit-") || lower.startsWith("ratelimit") || lower.startsWith("x-codex-");
32542
+ }
32543
+ var USAGE_SCHEMA_VERSION, VersionSchema, InstantSchema, TokenCountSchema, TokenUsageSchema, LIMIT_KINDS, LimitClassificationSchema, UsageRecordSchema, QuotaWindowSchema, UnifiedRateLimitSchema, RateLimitStateSchema, LimitEventSchema, ProviderQuotaWindowSchema, ProviderQuotaSchema, ProviderUsageStateSchema, AccountMetadataSchema, UsageSnapshotSchema;
32544
+ var init_schema2 = __esm({
32545
+ "src/usage/schema.ts"() {
32546
+ "use strict";
32547
+ init_zod();
32548
+ USAGE_SCHEMA_VERSION = 1;
32549
+ VersionSchema = external_exports.literal(USAGE_SCHEMA_VERSION);
32550
+ InstantSchema = external_exports.iso.datetime();
32551
+ TokenCountSchema = external_exports.number().int().nonnegative();
32552
+ TokenUsageSchema = external_exports.strictObject({
32553
+ inputTokens: TokenCountSchema.optional(),
32554
+ outputTokens: TokenCountSchema.optional(),
32555
+ cacheCreationInputTokens: TokenCountSchema.optional(),
32556
+ cacheReadInputTokens: TokenCountSchema.optional()
32557
+ });
32558
+ LIMIT_KINDS = ["rate-limited", "quota-exhausted"];
32559
+ LimitClassificationSchema = external_exports.strictObject({
32560
+ kind: external_exports.enum(LIMIT_KINDS),
32561
+ /** Seconds to wait before retrying, from the response's `retry-after`. */
32562
+ retryAfterSeconds: external_exports.number().nonnegative().optional(),
32563
+ /** When the limiting window resets, from the upstream's own reset header. */
32564
+ resetAt: InstantSchema.optional(),
32565
+ /** The window the upstream named as the binding one (`anthropic-ratelimit-unified-representative-claim`), such as `five_hour` or `seven_day`. */
32566
+ window: external_exports.string().optional(),
32567
+ /** The signals the classification rests on, each `<name>=<value>` from a response header or the error body's `type` or `code`. Never the error message. */
32568
+ evidence: external_exports.array(external_exports.string())
32569
+ });
32570
+ UsageRecordSchema = external_exports.strictObject({
32571
+ schemaVersion: VersionSchema,
32572
+ /** When the front door received the request. */
32573
+ at: InstantSchema,
32574
+ /** The launching identity, when the launch resolved one. */
32575
+ identity: external_exports.string().optional(),
32576
+ /** `anthropic` for an OAuth session's request to Claude Code's own API, otherwise the provider's name. */
32577
+ provider: external_exports.string(),
32578
+ /** The launch's session id, generated per launch. */
32579
+ sessionId: external_exports.string().optional(),
32580
+ /** The project the launch ran in (its git repository root), when the launch sent one: headroom launches do. */
32581
+ project: external_exports.string().optional(),
32582
+ /** The front-door route that served the request. */
32583
+ route: external_exports.string(),
32584
+ method: external_exports.string(),
32585
+ /** The API path as the upstream sees it (`/v1/messages`), without the provider prefix or a query string. */
32586
+ endpoint: external_exports.string(),
32587
+ /** The model the response named. */
32588
+ model: external_exports.string().optional(),
32589
+ status: external_exports.number().int(),
32590
+ /** Milliseconds from the request's arrival to its response head. */
32591
+ latencyMs: external_exports.number().int().nonnegative(),
32592
+ /** Milliseconds from the request's arrival to the end of its response body. */
32593
+ durationMs: external_exports.number().int().nonnegative(),
32594
+ /** Whether the client received the whole body. */
32595
+ outcome: external_exports.enum(["completed", "aborted"]),
32596
+ usage: TokenUsageSchema.optional(),
32597
+ /** The response's quota and rate-limit headers, by name (see `isRateLimitHeader`). */
32598
+ rateLimitHeaders: external_exports.record(external_exports.string(), external_exports.string()).optional(),
32599
+ limit: LimitClassificationSchema.optional(),
32600
+ /** The upstream's request id (`request-id`), for matching a record to the provider's own logs. */
32601
+ requestId: external_exports.string().optional()
32602
+ });
32603
+ QuotaWindowSchema = external_exports.strictObject({
32604
+ /** The fraction of the window used, as the upstream reports it (0 to 1). */
32605
+ utilization: external_exports.number().nonnegative().optional(),
32606
+ resetsAt: InstantSchema.optional(),
32607
+ /** The window's own status (`allowed`, `allowed_warning`, `rejected`). */
32608
+ status: external_exports.string().optional()
32609
+ });
32610
+ UnifiedRateLimitSchema = external_exports.strictObject({
32611
+ /** The overall status: `allowed`, `allowed_warning` or `rejected`. */
32612
+ status: external_exports.string().optional(),
32613
+ fiveHour: QuotaWindowSchema.optional(),
32614
+ sevenDay: QuotaWindowSchema.optional(),
32615
+ /** The window that currently binds. */
32616
+ representativeClaim: external_exports.string().optional(),
32617
+ /** When the binding window resets. */
32618
+ resetAt: InstantSchema.optional(),
32619
+ /** Whether usage beyond the plan (extra usage) is available: `allowed` or `rejected`. */
32620
+ overageStatus: external_exports.string().optional(),
32621
+ /** The fraction of the extra-usage allowance used, as the upstream reports it (0 to 1). An account with no plan windows, such as an Enterprise one, is metered by this alone. */
32622
+ overageUtilization: external_exports.number().nonnegative().optional(),
32623
+ /** When the extra-usage allowance resets. */
32624
+ overageResetsAt: InstantSchema.optional(),
32625
+ /** Why extra usage is unavailable, as the upstream names it (`out_of_credits`, for one). */
32626
+ overageDisabledReason: external_exports.string().optional()
32627
+ });
32628
+ RateLimitStateSchema = external_exports.strictObject({
32629
+ observedAt: InstantSchema,
32630
+ /** Every quota and rate-limit header on that response, by name. */
32631
+ headers: external_exports.record(external_exports.string(), external_exports.string()),
32632
+ unified: UnifiedRateLimitSchema.optional()
32633
+ });
32634
+ LimitEventSchema = LimitClassificationSchema.extend({
32635
+ observedAt: InstantSchema,
32636
+ status: external_exports.number().int()
32637
+ });
32638
+ ProviderQuotaWindowSchema = external_exports.strictObject({
32639
+ /** What the window measures, in the provider's terms (`tokens`, `tool-calls`). */
32640
+ measures: external_exports.string(),
32641
+ /** The window's length in milliseconds, when the provider's unit is one this project knows; absent for an unrecognised unit, with `period` carrying the raw code. */
32642
+ periodMs: external_exports.number().int().positive().optional(),
32643
+ /** The provider's own description of the period when `periodMs` could not be derived, such as `unit 4 x 1`. */
32644
+ period: external_exports.string().optional(),
32645
+ /** The fraction of the window used (0 to 1). */
32646
+ utilization: external_exports.number().nonnegative(),
32647
+ resetsAt: InstantSchema.optional(),
32648
+ /** Absolute counts, when the provider reports them for this window. */
32649
+ limit: external_exports.number().nonnegative().optional(),
32650
+ used: external_exports.number().nonnegative().optional(),
32651
+ remaining: external_exports.number().nonnegative().optional()
32652
+ });
32653
+ ProviderQuotaSchema = external_exports.strictObject({
32654
+ observedAt: InstantSchema,
32655
+ /** Which usage endpoint produced it (`z.ai`). */
32656
+ source: external_exports.string(),
32657
+ /** The subscription level the endpoint reports, when it does. */
32658
+ level: external_exports.string().optional(),
32659
+ windows: external_exports.array(ProviderQuotaWindowSchema)
32660
+ });
32661
+ ProviderUsageStateSchema = external_exports.strictObject({
32662
+ /** When the provider last served a request for the identity through the front door. Absent while the state holds only a rate-limit state fetched from the provider's usage endpoint, for an identity that has made no request. */
32663
+ lastRequestAt: InstantSchema.optional(),
32664
+ lastStatus: external_exports.number().int().optional(),
32665
+ lastModel: external_exports.string().optional(),
32666
+ /** The latest rate-limit state, from the last response that carried any rate-limit header. */
32667
+ rateLimit: RateLimitStateSchema.optional(),
32668
+ /** The latest classified refusal. It stays after later successes, so a reader compares its `resetAt` (or `observedAt` plus `retryAfterSeconds`) with the current time. */
32669
+ lastLimit: LimitEventSchema.optional(),
32670
+ /** The latest quota the provider's usage endpoint reported, for providers whose quota is not visible in response headers. */
32671
+ quota: ProviderQuotaSchema.optional()
32672
+ });
32673
+ AccountMetadataSchema = external_exports.strictObject({
32674
+ accountUuid: external_exports.string().optional(),
32675
+ emailAddress: external_exports.string().optional(),
32676
+ displayName: external_exports.string().optional(),
32677
+ organizationUuid: external_exports.string().optional(),
32678
+ organizationName: external_exports.string().optional(),
32679
+ organizationType: external_exports.string().optional(),
32680
+ organizationRole: external_exports.string().optional(),
32681
+ workspaceRole: external_exports.string().optional(),
32682
+ billingType: external_exports.string().optional(),
32683
+ seatTier: external_exports.string().optional(),
32684
+ organizationRateLimitTier: external_exports.string().optional(),
32685
+ userRateLimitTier: external_exports.string().optional(),
32686
+ hasExtraUsageEnabled: external_exports.boolean().optional(),
32687
+ subscriptionCreatedAt: external_exports.string().optional(),
32688
+ accountCreatedAt: external_exports.string().optional()
32689
+ });
32690
+ UsageSnapshotSchema = external_exports.strictObject({
32691
+ schemaVersion: VersionSchema,
32692
+ identity: external_exports.string(),
32693
+ updatedAt: InstantSchema,
32694
+ /** The identity's account metadata as of `updatedAt`. */
32695
+ account: AccountMetadataSchema.optional(),
32696
+ /** Latest state per provider, keyed by provider name (`anthropic` for OAuth sessions). */
32697
+ providers: external_exports.record(external_exports.string(), ProviderUsageStateSchema)
32698
+ });
32699
+ }
32700
+ });
32701
+
32702
+ // src/usage/rateLimit.ts
32703
+ function rateLimitHeadersOf(headers) {
32704
+ const kept = {};
32705
+ for (const [name, value2] of Object.entries(headers)) {
32706
+ if (isRateLimitHeader(name)) {
32707
+ kept[name.toLowerCase()] = value2;
32708
+ }
32709
+ }
32710
+ return Object.keys(kept).length === 0 ? void 0 : kept;
32711
+ }
32712
+ function epochSecondsToIso(value2) {
32713
+ if (value2 === void 0) {
32714
+ return void 0;
32715
+ }
32716
+ const seconds = Number(value2);
32717
+ return Number.isFinite(seconds) && seconds > 0 ? new Date(seconds * MS_PER_SECOND).toISOString() : void 0;
32718
+ }
32719
+ function nonNegativeNumber(value2) {
32720
+ if (value2 === void 0 || value2.trim() === "") {
32721
+ return void 0;
32722
+ }
32723
+ const parsed = Number(value2);
32724
+ return Number.isFinite(parsed) && parsed >= 0 ? parsed : void 0;
32725
+ }
32726
+ function unifiedWindow(headers, window) {
32727
+ const utilization = nonNegativeNumber(headers[`${UNIFIED_PREFIX}${window}-utilization`]);
32728
+ const resetsAt = epochSecondsToIso(headers[`${UNIFIED_PREFIX}${window}-reset`]);
32729
+ const status = headers[`${UNIFIED_PREFIX}${window}-status`];
32730
+ if (utilization === void 0 && resetsAt === void 0 && status === void 0) {
32731
+ return void 0;
32732
+ }
32733
+ return { ...utilization === void 0 ? {} : { utilization }, ...resetsAt === void 0 ? {} : { resetsAt }, ...status === void 0 ? {} : { status } };
32734
+ }
32735
+ function parseUnifiedRateLimit(headers) {
32736
+ if (!Object.keys(headers).some((name) => name.startsWith(UNIFIED_PREFIX))) {
32737
+ return void 0;
32738
+ }
32739
+ const status = headers[`${UNIFIED_PREFIX}status`];
32740
+ const fiveHour = unifiedWindow(headers, "5h");
32741
+ const sevenDay = unifiedWindow(headers, "7d");
32742
+ const representativeClaim = headers[`${UNIFIED_PREFIX}representative-claim`];
32743
+ const resetAt = epochSecondsToIso(headers[`${UNIFIED_PREFIX}reset`]);
32744
+ const overageStatus = headers[`${UNIFIED_PREFIX}overage-status`];
32745
+ const overageUtilization = nonNegativeNumber(headers[`${UNIFIED_PREFIX}overage-utilization`]);
32746
+ const overageResetsAt = epochSecondsToIso(headers[`${UNIFIED_PREFIX}overage-reset`]);
32747
+ const overageDisabledReason = headers[`${UNIFIED_PREFIX}overage-disabled-reason`];
32748
+ return {
32749
+ ...status === void 0 ? {} : { status },
32750
+ ...fiveHour === void 0 ? {} : { fiveHour },
32751
+ ...sevenDay === void 0 ? {} : { sevenDay },
32752
+ ...representativeClaim === void 0 ? {} : { representativeClaim },
32753
+ ...resetAt === void 0 ? {} : { resetAt },
32754
+ ...overageStatus === void 0 ? {} : { overageStatus },
32755
+ ...overageUtilization === void 0 ? {} : { overageUtilization },
32756
+ ...overageResetsAt === void 0 ? {} : { overageResetsAt },
32757
+ ...overageDisabledReason === void 0 ? {} : { overageDisabledReason }
32758
+ };
32759
+ }
32760
+ function overageFactsOf(unified) {
32761
+ const { overageStatus, overageUtilization, overageResetsAt, overageDisabledReason } = unified;
32762
+ return {
32763
+ ...overageStatus === void 0 ? {} : { overageStatus },
32764
+ ...overageUtilization === void 0 ? {} : { overageUtilization },
32765
+ ...overageResetsAt === void 0 ? {} : { overageResetsAt },
32766
+ ...overageDisabledReason === void 0 ? {} : { overageDisabledReason }
32767
+ };
32768
+ }
32769
+ function overageWindowOf(unified) {
32770
+ const { overageUtilization: utilization, overageResetsAt: resetsAt, overageStatus: status } = unified;
32771
+ if (utilization === void 0 && resetsAt === void 0 && status === void 0) {
32772
+ return void 0;
32773
+ }
32774
+ return { ...utilization === void 0 ? {} : { utilization }, ...resetsAt === void 0 ? {} : { resetsAt }, ...status === void 0 ? {} : { status } };
32775
+ }
32776
+ function soleOverageWindow(unified) {
32777
+ return unified.fiveHour === void 0 && unified.sevenDay === void 0 ? overageWindowOf(unified) : void 0;
32778
+ }
32779
+ function retryAfterSeconds(value2, nowMs) {
32780
+ if (value2 === void 0) {
32781
+ return void 0;
32782
+ }
32783
+ const seconds = nonNegativeNumber(value2);
32784
+ if (seconds !== void 0) {
32785
+ return seconds;
32786
+ }
32787
+ const date5 = Date.parse(value2);
32788
+ return Number.isNaN(date5) ? void 0 : Math.max(0, Math.ceil((date5 - nowMs) / MS_PER_SECOND));
32789
+ }
32790
+ function classifyLimit(params) {
32791
+ const { status, headers, error: error62 } = params;
32792
+ if (status !== TOO_MANY_REQUESTS && status !== PAYMENT_REQUIRED) {
32793
+ return void 0;
32794
+ }
32795
+ const evidence = [`status=${String(status)}`];
32796
+ const unified = parseUnifiedRateLimit(headers);
32797
+ const unifiedRejected = unified?.status === "rejected" && (unified.overageStatus === void 0 || unified.overageStatus === "rejected");
32798
+ if (unified?.status !== void 0) {
32799
+ evidence.push(`${UNIFIED_PREFIX}status=${unified.status}`);
32800
+ }
32801
+ if (unified?.overageStatus !== void 0) {
32802
+ evidence.push(`${UNIFIED_PREFIX}overage-status=${unified.overageStatus}`);
32803
+ }
32804
+ for (const [name, value2] of [
32805
+ ["error.type", error62?.type],
32806
+ ["error.code", error62?.code]
32807
+ ]) {
32808
+ if (value2 !== void 0 && EVIDENCE_TOKEN.test(value2)) {
32809
+ evidence.push(`${name}=${value2}`);
32810
+ }
32811
+ }
32812
+ const errorExhausted = [error62?.type, error62?.code].some((value2) => value2 !== void 0 && QUOTA_EXHAUSTED_ERRORS.has(value2));
32813
+ const messageExhausted = error62?.message !== void 0 && QUOTA_EXHAUSTED_MESSAGE.test(error62.message);
32814
+ if (messageExhausted) {
32815
+ evidence.push("error.message=names a usage limit");
32816
+ }
32817
+ const exhausted = status === PAYMENT_REQUIRED || unifiedRejected || errorExhausted || messageExhausted;
32818
+ const retryAfter = retryAfterSeconds(headers["retry-after"], params.nowMs);
32819
+ return {
32820
+ kind: exhausted ? "quota-exhausted" : "rate-limited",
32821
+ ...retryAfter === void 0 ? {} : { retryAfterSeconds: retryAfter },
32822
+ ...unified?.resetAt === void 0 ? {} : { resetAt: unified.resetAt },
32823
+ ...unified?.representativeClaim === void 0 ? {} : { window: unified.representativeClaim },
32824
+ evidence
32825
+ };
32826
+ }
32827
+ var TOO_MANY_REQUESTS, PAYMENT_REQUIRED, MS_PER_SECOND, UNIFIED_PREFIX, QUOTA_EXHAUSTED_ERRORS, QUOTA_EXHAUSTED_MESSAGE, EVIDENCE_TOKEN;
32828
+ var init_rateLimit = __esm({
32829
+ "src/usage/rateLimit.ts"() {
32830
+ "use strict";
32831
+ init_schema2();
32832
+ TOO_MANY_REQUESTS = 429;
32833
+ PAYMENT_REQUIRED = 402;
32834
+ MS_PER_SECOND = 1e3;
32835
+ UNIFIED_PREFIX = "anthropic-ratelimit-unified-";
32836
+ QUOTA_EXHAUSTED_ERRORS = /* @__PURE__ */ new Set(["usage_limit_reached", "insufficient_quota", "1308", "1309", "1310", "1316", "1317", "1318", "1319", "1320", "1321"]);
32837
+ QUOTA_EXHAUSTED_MESSAGE = /usage limit|quota (?:exceeded|exhausted)|limit exhausted|insufficient (?:balance|credits|quota)/i;
32838
+ EVIDENCE_TOKEN = /^[\w.-]{1,64}$/;
32839
+ }
32840
+ });
32841
+
32532
32842
  // src/usage/preflight.ts
32533
32843
  function formatAge(ms2) {
32534
- const minutes = Math.floor(ms2 / (MS_PER_SECOND * SECONDS_PER_MINUTE));
32844
+ const minutes = Math.floor(ms2 / (MS_PER_SECOND2 * SECONDS_PER_MINUTE));
32535
32845
  if (minutes < MINUTES_PER_HOUR) {
32536
32846
  return `${String(Math.max(minutes, 0))}m`;
32537
32847
  }
@@ -32559,7 +32869,8 @@ function quotaWarnings(snapshot, provider, nowMs) {
32559
32869
  const age2 = formatAge(nowMs - Date.parse(rateLimit.observedAt));
32560
32870
  const windows = [
32561
32871
  { name: "five-hour", window: unified.fiveHour },
32562
- { name: "seven-day", window: unified.sevenDay }
32872
+ { name: "seven-day", window: unified.sevenDay },
32873
+ { name: "extra-usage", window: soleOverageWindow(unified) }
32563
32874
  ];
32564
32875
  return windows.flatMap(({ name, window }) => {
32565
32876
  const effective = window === void 0 ? void 0 : effectiveWindow(window, nowMs);
@@ -32571,11 +32882,12 @@ function quotaWarnings(snapshot, provider, nowMs) {
32571
32882
  return [`agent-shim: identity ${snapshot.identity}: the ${name} quota is ${verdict}${reset} (last seen ${age2} ago)`];
32572
32883
  });
32573
32884
  }
32574
- var MS_PER_SECOND, SECONDS_PER_MINUTE, MINUTES_PER_HOUR, HOURS_PER_DAY, WARNING_STATUSES;
32885
+ var MS_PER_SECOND2, SECONDS_PER_MINUTE, MINUTES_PER_HOUR, HOURS_PER_DAY, WARNING_STATUSES;
32575
32886
  var init_preflight = __esm({
32576
32887
  "src/usage/preflight.ts"() {
32577
32888
  "use strict";
32578
- MS_PER_SECOND = 1e3;
32889
+ init_rateLimit();
32890
+ MS_PER_SECOND2 = 1e3;
32579
32891
  SECONDS_PER_MINUTE = 60;
32580
32892
  MINUTES_PER_HOUR = 60;
32581
32893
  HOURS_PER_DAY = 24;
@@ -32879,7 +33191,7 @@ var init_package = __esm({
32879
33191
  "package.json"() {
32880
33192
  package_default = {
32881
33193
  name: "agent-shim",
32882
- version: "9.1.0",
33194
+ version: "9.2.0",
32883
33195
  description: "A profile manager and launcher for Claude Code that lets one person run multiple logins from one machine while controlling what gets shared between them.",
32884
33196
  license: "MIT",
32885
33197
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -32981,164 +33293,6 @@ var init_package = __esm({
32981
33293
  }
32982
33294
  });
32983
33295
 
32984
- // src/usage/schema.ts
32985
- function isRateLimitHeader(name) {
32986
- const lower = name.toLowerCase();
32987
- return lower === "retry-after" || lower.startsWith("anthropic-ratelimit-") || lower.startsWith("x-ratelimit-") || lower.startsWith("ratelimit") || lower.startsWith("x-codex-");
32988
- }
32989
- var USAGE_SCHEMA_VERSION, VersionSchema, InstantSchema, TokenCountSchema, TokenUsageSchema, LIMIT_KINDS, LimitClassificationSchema, UsageRecordSchema, QuotaWindowSchema, UnifiedRateLimitSchema, RateLimitStateSchema, LimitEventSchema, ProviderQuotaWindowSchema, ProviderQuotaSchema, ProviderUsageStateSchema, AccountMetadataSchema, UsageSnapshotSchema;
32990
- var init_schema2 = __esm({
32991
- "src/usage/schema.ts"() {
32992
- "use strict";
32993
- init_zod();
32994
- USAGE_SCHEMA_VERSION = 1;
32995
- VersionSchema = external_exports.literal(USAGE_SCHEMA_VERSION);
32996
- InstantSchema = external_exports.iso.datetime();
32997
- TokenCountSchema = external_exports.number().int().nonnegative();
32998
- TokenUsageSchema = external_exports.strictObject({
32999
- inputTokens: TokenCountSchema.optional(),
33000
- outputTokens: TokenCountSchema.optional(),
33001
- cacheCreationInputTokens: TokenCountSchema.optional(),
33002
- cacheReadInputTokens: TokenCountSchema.optional()
33003
- });
33004
- LIMIT_KINDS = ["rate-limited", "quota-exhausted"];
33005
- LimitClassificationSchema = external_exports.strictObject({
33006
- kind: external_exports.enum(LIMIT_KINDS),
33007
- /** Seconds to wait before retrying, from the response's `retry-after`. */
33008
- retryAfterSeconds: external_exports.number().nonnegative().optional(),
33009
- /** When the limiting window resets, from the upstream's own reset header. */
33010
- resetAt: InstantSchema.optional(),
33011
- /** The window the upstream named as the binding one (`anthropic-ratelimit-unified-representative-claim`), such as `five_hour` or `seven_day`. */
33012
- window: external_exports.string().optional(),
33013
- /** The signals the classification rests on, each `<name>=<value>` from a response header or the error body's `type` or `code`. Never the error message. */
33014
- evidence: external_exports.array(external_exports.string())
33015
- });
33016
- UsageRecordSchema = external_exports.strictObject({
33017
- schemaVersion: VersionSchema,
33018
- /** When the front door received the request. */
33019
- at: InstantSchema,
33020
- /** The launching identity, when the launch resolved one. */
33021
- identity: external_exports.string().optional(),
33022
- /** `anthropic` for an OAuth session's request to Claude Code's own API, otherwise the provider's name. */
33023
- provider: external_exports.string(),
33024
- /** The launch's session id, generated per launch. */
33025
- sessionId: external_exports.string().optional(),
33026
- /** The project the launch ran in (its git repository root), when the launch sent one: headroom launches do. */
33027
- project: external_exports.string().optional(),
33028
- /** The front-door route that served the request. */
33029
- route: external_exports.string(),
33030
- method: external_exports.string(),
33031
- /** The API path as the upstream sees it (`/v1/messages`), without the provider prefix or a query string. */
33032
- endpoint: external_exports.string(),
33033
- /** The model the response named. */
33034
- model: external_exports.string().optional(),
33035
- status: external_exports.number().int(),
33036
- /** Milliseconds from the request's arrival to its response head. */
33037
- latencyMs: external_exports.number().int().nonnegative(),
33038
- /** Milliseconds from the request's arrival to the end of its response body. */
33039
- durationMs: external_exports.number().int().nonnegative(),
33040
- /** Whether the client received the whole body. */
33041
- outcome: external_exports.enum(["completed", "aborted"]),
33042
- usage: TokenUsageSchema.optional(),
33043
- /** The response's quota and rate-limit headers, by name (see `isRateLimitHeader`). */
33044
- rateLimitHeaders: external_exports.record(external_exports.string(), external_exports.string()).optional(),
33045
- limit: LimitClassificationSchema.optional(),
33046
- /** The upstream's request id (`request-id`), for matching a record to the provider's own logs. */
33047
- requestId: external_exports.string().optional()
33048
- });
33049
- QuotaWindowSchema = external_exports.strictObject({
33050
- /** The fraction of the window used, as the upstream reports it (0 to 1). */
33051
- utilization: external_exports.number().nonnegative().optional(),
33052
- resetsAt: InstantSchema.optional(),
33053
- /** The window's own status (`allowed`, `allowed_warning`, `rejected`). */
33054
- status: external_exports.string().optional()
33055
- });
33056
- UnifiedRateLimitSchema = external_exports.strictObject({
33057
- /** The overall status: `allowed`, `allowed_warning` or `rejected`. */
33058
- status: external_exports.string().optional(),
33059
- fiveHour: QuotaWindowSchema.optional(),
33060
- sevenDay: QuotaWindowSchema.optional(),
33061
- /** The window that currently binds. */
33062
- representativeClaim: external_exports.string().optional(),
33063
- /** When the binding window resets. */
33064
- resetAt: InstantSchema.optional(),
33065
- /** Whether usage beyond the plan (extra usage) is available: `allowed` or `rejected`. */
33066
- overageStatus: external_exports.string().optional()
33067
- });
33068
- RateLimitStateSchema = external_exports.strictObject({
33069
- observedAt: InstantSchema,
33070
- /** Every quota and rate-limit header on that response, by name. */
33071
- headers: external_exports.record(external_exports.string(), external_exports.string()),
33072
- unified: UnifiedRateLimitSchema.optional()
33073
- });
33074
- LimitEventSchema = LimitClassificationSchema.extend({
33075
- observedAt: InstantSchema,
33076
- status: external_exports.number().int()
33077
- });
33078
- ProviderQuotaWindowSchema = external_exports.strictObject({
33079
- /** What the window measures, in the provider's terms (`tokens`, `tool-calls`). */
33080
- measures: external_exports.string(),
33081
- /** The window's length in milliseconds, when the provider's unit is one this project knows; absent for an unrecognised unit, with `period` carrying the raw code. */
33082
- periodMs: external_exports.number().int().positive().optional(),
33083
- /** The provider's own description of the period when `periodMs` could not be derived, such as `unit 4 x 1`. */
33084
- period: external_exports.string().optional(),
33085
- /** The fraction of the window used (0 to 1). */
33086
- utilization: external_exports.number().nonnegative(),
33087
- resetsAt: InstantSchema.optional(),
33088
- /** Absolute counts, when the provider reports them for this window. */
33089
- limit: external_exports.number().nonnegative().optional(),
33090
- used: external_exports.number().nonnegative().optional(),
33091
- remaining: external_exports.number().nonnegative().optional()
33092
- });
33093
- ProviderQuotaSchema = external_exports.strictObject({
33094
- observedAt: InstantSchema,
33095
- /** Which usage endpoint produced it (`z.ai`). */
33096
- source: external_exports.string(),
33097
- /** The subscription level the endpoint reports, when it does. */
33098
- level: external_exports.string().optional(),
33099
- windows: external_exports.array(ProviderQuotaWindowSchema)
33100
- });
33101
- ProviderUsageStateSchema = external_exports.strictObject({
33102
- /** When the provider last served a request for the identity through the front door. Absent while the state holds only a rate-limit state fetched from the provider's usage endpoint, for an identity that has made no request. */
33103
- lastRequestAt: InstantSchema.optional(),
33104
- lastStatus: external_exports.number().int().optional(),
33105
- lastModel: external_exports.string().optional(),
33106
- /** The latest rate-limit state, from the last response that carried any rate-limit header. */
33107
- rateLimit: RateLimitStateSchema.optional(),
33108
- /** The latest classified refusal. It stays after later successes, so a reader compares its `resetAt` (or `observedAt` plus `retryAfterSeconds`) with the current time. */
33109
- lastLimit: LimitEventSchema.optional(),
33110
- /** The latest quota the provider's usage endpoint reported, for providers whose quota is not visible in response headers. */
33111
- quota: ProviderQuotaSchema.optional()
33112
- });
33113
- AccountMetadataSchema = external_exports.strictObject({
33114
- accountUuid: external_exports.string().optional(),
33115
- emailAddress: external_exports.string().optional(),
33116
- displayName: external_exports.string().optional(),
33117
- organizationUuid: external_exports.string().optional(),
33118
- organizationName: external_exports.string().optional(),
33119
- organizationType: external_exports.string().optional(),
33120
- organizationRole: external_exports.string().optional(),
33121
- workspaceRole: external_exports.string().optional(),
33122
- billingType: external_exports.string().optional(),
33123
- seatTier: external_exports.string().optional(),
33124
- organizationRateLimitTier: external_exports.string().optional(),
33125
- userRateLimitTier: external_exports.string().optional(),
33126
- hasExtraUsageEnabled: external_exports.boolean().optional(),
33127
- subscriptionCreatedAt: external_exports.string().optional(),
33128
- accountCreatedAt: external_exports.string().optional()
33129
- });
33130
- UsageSnapshotSchema = external_exports.strictObject({
33131
- schemaVersion: VersionSchema,
33132
- identity: external_exports.string(),
33133
- updatedAt: InstantSchema,
33134
- /** The identity's account metadata as of `updatedAt`. */
33135
- account: AccountMetadataSchema.optional(),
33136
- /** Latest state per provider, keyed by provider name (`anthropic` for OAuth sessions). */
33137
- providers: external_exports.record(external_exports.string(), ProviderUsageStateSchema)
33138
- });
33139
- }
33140
- });
33141
-
33142
33296
  // src/usage/account.ts
33143
33297
  function isObject2(value2) {
33144
33298
  return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
@@ -33344,121 +33498,6 @@ var init_route = __esm({
33344
33498
  }
33345
33499
  });
33346
33500
 
33347
- // src/usage/rateLimit.ts
33348
- function rateLimitHeadersOf(headers) {
33349
- const kept = {};
33350
- for (const [name, value2] of Object.entries(headers)) {
33351
- if (isRateLimitHeader(name)) {
33352
- kept[name.toLowerCase()] = value2;
33353
- }
33354
- }
33355
- return Object.keys(kept).length === 0 ? void 0 : kept;
33356
- }
33357
- function epochSecondsToIso(value2) {
33358
- if (value2 === void 0) {
33359
- return void 0;
33360
- }
33361
- const seconds = Number(value2);
33362
- return Number.isFinite(seconds) && seconds > 0 ? new Date(seconds * MS_PER_SECOND2).toISOString() : void 0;
33363
- }
33364
- function nonNegativeNumber(value2) {
33365
- if (value2 === void 0 || value2.trim() === "") {
33366
- return void 0;
33367
- }
33368
- const parsed = Number(value2);
33369
- return Number.isFinite(parsed) && parsed >= 0 ? parsed : void 0;
33370
- }
33371
- function unifiedWindow(headers, window) {
33372
- const utilization = nonNegativeNumber(headers[`${UNIFIED_PREFIX}${window}-utilization`]);
33373
- const resetsAt = epochSecondsToIso(headers[`${UNIFIED_PREFIX}${window}-reset`]);
33374
- const status = headers[`${UNIFIED_PREFIX}${window}-status`];
33375
- if (utilization === void 0 && resetsAt === void 0 && status === void 0) {
33376
- return void 0;
33377
- }
33378
- return { ...utilization === void 0 ? {} : { utilization }, ...resetsAt === void 0 ? {} : { resetsAt }, ...status === void 0 ? {} : { status } };
33379
- }
33380
- function parseUnifiedRateLimit(headers) {
33381
- if (!Object.keys(headers).some((name) => name.startsWith(UNIFIED_PREFIX))) {
33382
- return void 0;
33383
- }
33384
- const status = headers[`${UNIFIED_PREFIX}status`];
33385
- const fiveHour = unifiedWindow(headers, "5h");
33386
- const sevenDay = unifiedWindow(headers, "7d");
33387
- const representativeClaim = headers[`${UNIFIED_PREFIX}representative-claim`];
33388
- const resetAt = epochSecondsToIso(headers[`${UNIFIED_PREFIX}reset`]);
33389
- const overageStatus = headers[`${UNIFIED_PREFIX}overage-status`];
33390
- return {
33391
- ...status === void 0 ? {} : { status },
33392
- ...fiveHour === void 0 ? {} : { fiveHour },
33393
- ...sevenDay === void 0 ? {} : { sevenDay },
33394
- ...representativeClaim === void 0 ? {} : { representativeClaim },
33395
- ...resetAt === void 0 ? {} : { resetAt },
33396
- ...overageStatus === void 0 ? {} : { overageStatus }
33397
- };
33398
- }
33399
- function retryAfterSeconds(value2, nowMs) {
33400
- if (value2 === void 0) {
33401
- return void 0;
33402
- }
33403
- const seconds = nonNegativeNumber(value2);
33404
- if (seconds !== void 0) {
33405
- return seconds;
33406
- }
33407
- const date5 = Date.parse(value2);
33408
- return Number.isNaN(date5) ? void 0 : Math.max(0, Math.ceil((date5 - nowMs) / MS_PER_SECOND2));
33409
- }
33410
- function classifyLimit(params) {
33411
- const { status, headers, error: error62 } = params;
33412
- if (status !== TOO_MANY_REQUESTS && status !== PAYMENT_REQUIRED) {
33413
- return void 0;
33414
- }
33415
- const evidence = [`status=${String(status)}`];
33416
- const unified = parseUnifiedRateLimit(headers);
33417
- const unifiedRejected = unified?.status === "rejected" && (unified.overageStatus === void 0 || unified.overageStatus === "rejected");
33418
- if (unified?.status !== void 0) {
33419
- evidence.push(`${UNIFIED_PREFIX}status=${unified.status}`);
33420
- }
33421
- if (unified?.overageStatus !== void 0) {
33422
- evidence.push(`${UNIFIED_PREFIX}overage-status=${unified.overageStatus}`);
33423
- }
33424
- for (const [name, value2] of [
33425
- ["error.type", error62?.type],
33426
- ["error.code", error62?.code]
33427
- ]) {
33428
- if (value2 !== void 0 && EVIDENCE_TOKEN.test(value2)) {
33429
- evidence.push(`${name}=${value2}`);
33430
- }
33431
- }
33432
- const errorExhausted = [error62?.type, error62?.code].some((value2) => value2 !== void 0 && QUOTA_EXHAUSTED_ERRORS.has(value2));
33433
- const messageExhausted = error62?.message !== void 0 && QUOTA_EXHAUSTED_MESSAGE.test(error62.message);
33434
- if (messageExhausted) {
33435
- evidence.push("error.message=names a usage limit");
33436
- }
33437
- const exhausted = status === PAYMENT_REQUIRED || unifiedRejected || errorExhausted || messageExhausted;
33438
- const retryAfter = retryAfterSeconds(headers["retry-after"], params.nowMs);
33439
- return {
33440
- kind: exhausted ? "quota-exhausted" : "rate-limited",
33441
- ...retryAfter === void 0 ? {} : { retryAfterSeconds: retryAfter },
33442
- ...unified?.resetAt === void 0 ? {} : { resetAt: unified.resetAt },
33443
- ...unified?.representativeClaim === void 0 ? {} : { window: unified.representativeClaim },
33444
- evidence
33445
- };
33446
- }
33447
- var TOO_MANY_REQUESTS, PAYMENT_REQUIRED, MS_PER_SECOND2, UNIFIED_PREFIX, QUOTA_EXHAUSTED_ERRORS, QUOTA_EXHAUSTED_MESSAGE, EVIDENCE_TOKEN;
33448
- var init_rateLimit = __esm({
33449
- "src/usage/rateLimit.ts"() {
33450
- "use strict";
33451
- init_schema2();
33452
- TOO_MANY_REQUESTS = 429;
33453
- PAYMENT_REQUIRED = 402;
33454
- MS_PER_SECOND2 = 1e3;
33455
- UNIFIED_PREFIX = "anthropic-ratelimit-unified-";
33456
- QUOTA_EXHAUSTED_ERRORS = /* @__PURE__ */ new Set(["usage_limit_reached", "insufficient_quota", "1308", "1309", "1310", "1316", "1317", "1318", "1319", "1320", "1321"]);
33457
- QUOTA_EXHAUSTED_MESSAGE = /usage limit|quota (?:exceeded|exhausted)|limit exhausted|insufficient (?:balance|credits|quota)/i;
33458
- EVIDENCE_TOKEN = /^[\w.-]{1,64}$/;
33459
- }
33460
- });
33461
-
33462
33501
  // src/usage/scan.ts
33463
33502
  function mergeUsage(current, raw) {
33464
33503
  const parsed = AnthropicUsageSchema.safeParse(raw);
@@ -33873,6 +33912,28 @@ var init_middleware = __esm({
33873
33912
  }
33874
33913
  });
33875
33914
 
33915
+ // src/usage/quotaFacts.ts
33916
+ function windowFacts(window, nowMs) {
33917
+ if (window?.utilization === void 0 || window.resetsAt === void 0) {
33918
+ return void 0;
33919
+ }
33920
+ return { remaining: Math.max(0, 1 - window.utilization), utilization: window.utilization, hoursUntilReset: Math.max(0, (Date.parse(window.resetsAt) - nowMs) / MS_PER_HOUR) };
33921
+ }
33922
+ function quotaFactsOf(unified, nowMs) {
33923
+ const fiveHour = windowFacts(unified?.fiveHour, nowMs);
33924
+ const sevenDay = windowFacts(unified?.sevenDay, nowMs);
33925
+ const extraUsage = windowFacts(unified === void 0 ? void 0 : soleOverageWindow(unified), nowMs);
33926
+ return { ...fiveHour === void 0 ? {} : { fiveHour }, ...sevenDay === void 0 ? {} : { sevenDay }, ...extraUsage === void 0 ? {} : { extraUsage } };
33927
+ }
33928
+ var MS_PER_HOUR;
33929
+ var init_quotaFacts = __esm({
33930
+ "src/usage/quotaFacts.ts"() {
33931
+ "use strict";
33932
+ init_rateLimit();
33933
+ MS_PER_HOUR = 36e5;
33934
+ }
33935
+ });
33936
+
33876
33937
  // src/usage/pick.ts
33877
33938
  function unifiedOf(state) {
33878
33939
  return state?.rateLimit?.unified;
@@ -33967,18 +34028,22 @@ function assessIdentity(member, nowMs) {
33967
34028
  ...fiveHourWindow === void 0 || five === void 0 ? [] : [describeWindow("5h", fiveHourWindow, five, nowMs)],
33968
34029
  ...sevenDayWindow === void 0 || seven === void 0 ? [] : [describeWindow("7d", sevenDayWindow, seven, nowMs)]
33969
34030
  ];
34031
+ const overageWindow = soleOverageWindow(unified);
34032
+ const overage = overageWindow === void 0 ? void 0 : effectiveWindow(overageWindow, nowMs);
34033
+ const overageReasons = overageWindow === void 0 || overage === void 0 ? [] : [describeWindow("extra usage", overageWindow, overage, nowMs)];
33970
34034
  const blockedUntil = Math.max(
33971
- windowBlockedUntil([five, seven].flatMap((window) => window === void 0 ? [] : [window])) ?? 0,
34035
+ windowBlockedUntil([five, seven, overage].flatMap((window) => window === void 0 ? [] : [window])) ?? 0,
33972
34036
  limitBlockedUntil(state, nowMs) ?? 0
33973
34037
  );
33974
34038
  if (blockedUntil > nowMs) {
33975
34039
  if (unified.overageStatus === "allowed") {
33976
34040
  return { candidate: { ...base, class: "pay-per-use", reasons: [`plan exhausted until ${new Date(blockedUntil).toISOString()}, continues as extra usage`, ...windowReasons, ...planReasons] } };
33977
34041
  }
33978
- return { candidate: { ...base, class: "ineligible", blockedUntilMs: blockedUntil, reasons: [`refused until ${new Date(blockedUntil).toISOString()} (in ${formatAge(blockedUntil - nowMs)})`, ...windowReasons, ...planReasons] } };
34042
+ return { candidate: { ...base, class: "ineligible", blockedUntilMs: blockedUntil, reasons: [`refused until ${new Date(blockedUntil).toISOString()} (in ${formatAge(blockedUntil - nowMs)})`, ...windowReasons, ...overageReasons, ...planReasons] } };
33979
34043
  }
33980
34044
  if (plan.kind === "pay-per-use" || fiveHourWindow === void 0 && sevenDayWindow === void 0) {
33981
- return { candidate: { ...base, class: "pay-per-use", reasons: [...plan.kind === "pay-per-use" ? planReasons : ["no plan windows reported, so usage bills as extra usage"]] } };
34045
+ const headroom = overage?.utilization === void 0 ? void 0 : Math.max(0, 1 - overage.utilization);
34046
+ return { candidate: { ...base, class: "pay-per-use", ...headroom === void 0 ? {} : { headroom }, reasons: [...plan.kind === "pay-per-use" ? planReasons : ["no plan windows reported, so usage bills as extra usage"], ...overageReasons] } };
33982
34047
  }
33983
34048
  const basis = seven?.utilization !== void 0 ? { window: seven, windowMs: SEVEN_DAY_WINDOW_MS } : five?.utilization !== void 0 ? { window: five, windowMs: FIVE_HOUR_WINDOW_MS } : void 0;
33984
34049
  if (basis?.window.utilization === void 0) {
@@ -33986,7 +34051,7 @@ function assessIdentity(member, nowMs) {
33986
34051
  }
33987
34052
  const remaining = Math.max(0, 1 - basis.window.utilization);
33988
34053
  const untilResetMs = basis.window.resetsAtMs === void 0 ? basis.windowMs : Math.max(basis.window.resetsAtMs - nowMs, MS_PER_SECOND3);
33989
- const score = remaining * plan.capacity / (untilResetMs / MS_PER_HOUR);
34054
+ const score = remaining * plan.capacity / (untilResetMs / MS_PER_HOUR2);
33990
34055
  const fiveRemaining = five?.utilization === void 0 ? void 0 : Math.max(0, 1 - five.utilization);
33991
34056
  const fiveUntil = five?.resetsAtMs === void 0 ? FIVE_HOUR_WINDOW_MS : Math.max(five.resetsAtMs - nowMs, MS_PER_SECOND3);
33992
34057
  const burn = windowBurn(member.records, "fiveHour");
@@ -34002,24 +34067,15 @@ function assessIdentity(member, nowMs) {
34002
34067
  };
34003
34068
  }
34004
34069
  function poolFactsOf(member, nowMs, resuming, sticky) {
34005
- const unified = member.snapshot?.providers[ANTHROPIC_PROVIDER]?.rateLimit?.unified;
34006
- const window = (which) => {
34007
- const raw = unified?.[which];
34008
- if (raw?.utilization === void 0) {
34009
- return void 0;
34010
- }
34011
- if (raw.resetsAt === void 0) {
34012
- return void 0;
34013
- }
34014
- return { remaining: Math.max(0, 1 - raw.utilization), utilization: raw.utilization, hoursUntilReset: Math.max(0, (Date.parse(raw.resetsAt) - nowMs) / MS_PER_HOUR) };
34015
- };
34070
+ const { fiveHour, sevenDay, extraUsage } = quotaFactsOf(member.snapshot?.providers[ANTHROPIC_PROVIDER]?.rateLimit?.unified, nowMs);
34016
34071
  const burn = windowBurn(member.records, "fiveHour");
34017
34072
  return {
34018
- ...window("fiveHour") === void 0 ? {} : { fiveHour: window("fiveHour") },
34019
- ...window("sevenDay") === void 0 ? {} : { sevenDay: window("sevenDay") },
34020
- ...burn === void 0 ? {} : { burnPerHour: burn * MS_PER_HOUR },
34073
+ ...fiveHour === void 0 ? {} : { fiveHour },
34074
+ ...sevenDay === void 0 ? {} : { sevenDay },
34075
+ ...extraUsage === void 0 ? {} : { extraUsage },
34076
+ ...burn === void 0 ? {} : { burnPerHour: burn * MS_PER_HOUR2 },
34021
34077
  resuming,
34022
- ...sticky?.identity === member.identity ? { lastPickHoursAgo: Math.max(0, (nowMs - Date.parse(sticky.at)) / MS_PER_HOUR) } : {}
34078
+ ...sticky?.identity === member.identity ? { lastPickHoursAgo: Math.max(0, (nowMs - Date.parse(sticky.at)) / MS_PER_HOUR2) } : {}
34023
34079
  };
34024
34080
  }
34025
34081
  function rankPool(input2) {
@@ -34068,7 +34124,7 @@ function rankPool(input2) {
34068
34124
  return { ...candidate, feasible: false, reasons: [...drySpots, ...candidate.reasons] };
34069
34125
  });
34070
34126
  const ordered = input2.preference === "listed" ? [...candidates] : [...candidates].sort(
34071
- (left, right) => CLASS_ORDER[left.class] - CLASS_ORDER[right.class] || Number(left.policyDemoted ?? false) - Number(right.policyDemoted ?? false) || Number(right.feasible) - Number(left.feasible) || (right.score ?? 0) - (left.score ?? 0) || left.identity.localeCompare(right.identity)
34127
+ (left, right) => CLASS_ORDER[left.class] - CLASS_ORDER[right.class] || Number(left.policyDemoted ?? false) - Number(right.policyDemoted ?? false) || Number(right.feasible) - Number(left.feasible) || (right.headroom ?? 1) - (left.headroom ?? 1) || (right.score ?? 0) - (left.score ?? 0) || left.identity.localeCompare(right.identity)
34072
34128
  );
34073
34129
  const sticky = input2.sticky;
34074
34130
  const stickyIndex = sticky === void 0 ? -1 : ordered.findIndex((candidate) => candidate.identity === sticky.identity);
@@ -34093,7 +34149,7 @@ function rankPool(input2) {
34093
34149
  ...movedOff === void 0 || pick2 === void 0 ? {} : { movedOff }
34094
34150
  };
34095
34151
  }
34096
- var MS_PER_SECOND3, MS_PER_HOUR, HOURS_PER_DAY2, FIVE_HOURS, PROMPT_CACHE_TTL_HOURS, PERCENT, SEVEN_DAYS, FIVE_HOUR_WINDOW_MS, SEVEN_DAY_WINDOW_MS, PROMPT_CACHE_TTL_MS, CLASS_ORDER;
34152
+ var MS_PER_SECOND3, MS_PER_HOUR2, HOURS_PER_DAY2, FIVE_HOURS, PROMPT_CACHE_TTL_HOURS, PERCENT, SEVEN_DAYS, FIVE_HOUR_WINDOW_MS, SEVEN_DAY_WINDOW_MS, PROMPT_CACHE_TTL_MS, CLASS_ORDER;
34097
34153
  var init_pick = __esm({
34098
34154
  "src/usage/pick.ts"() {
34099
34155
  "use strict";
@@ -34101,17 +34157,18 @@ var init_pick = __esm({
34101
34157
  init_plan2();
34102
34158
  init_middleware();
34103
34159
  init_preflight();
34160
+ init_quotaFacts();
34104
34161
  init_rateLimit();
34105
34162
  MS_PER_SECOND3 = 1e3;
34106
- MS_PER_HOUR = 36e5;
34163
+ MS_PER_HOUR2 = 36e5;
34107
34164
  HOURS_PER_DAY2 = 24;
34108
34165
  FIVE_HOURS = 5;
34109
34166
  PROMPT_CACHE_TTL_HOURS = 1;
34110
34167
  PERCENT = 100;
34111
34168
  SEVEN_DAYS = 7;
34112
- FIVE_HOUR_WINDOW_MS = FIVE_HOURS * MS_PER_HOUR;
34113
- SEVEN_DAY_WINDOW_MS = SEVEN_DAYS * HOURS_PER_DAY2 * MS_PER_HOUR;
34114
- PROMPT_CACHE_TTL_MS = PROMPT_CACHE_TTL_HOURS * MS_PER_HOUR;
34169
+ FIVE_HOUR_WINDOW_MS = FIVE_HOURS * MS_PER_HOUR2;
34170
+ SEVEN_DAY_WINDOW_MS = SEVEN_DAYS * HOURS_PER_DAY2 * MS_PER_HOUR2;
34171
+ PROMPT_CACHE_TTL_MS = PROMPT_CACHE_TTL_HOURS * MS_PER_HOUR2;
34115
34172
  CLASS_ORDER = { scored: 0, unknown: 1, "pay-per-use": 2, ineligible: 3 };
34116
34173
  }
34117
34174
  });
@@ -34381,8 +34438,9 @@ function createUsageStore(deps) {
34381
34438
  recordRateLimit: (identity, provider, rateLimit) => rewriteSnapshot(identity, (current) => {
34382
34439
  const state = current?.providers[provider] ?? {};
34383
34440
  const keep = state.rateLimit !== void 0 && state.rateLimit.observedAt.localeCompare(rateLimit.observedAt) > 0;
34384
- const overageStatus = rateLimit.unified?.overageStatus ?? state.rateLimit?.unified?.overageStatus;
34385
- const merged = overageStatus === void 0 || rateLimit.unified === void 0 ? rateLimit : { ...rateLimit, unified: { ...rateLimit.unified, overageStatus } };
34441
+ const earlier = state.rateLimit?.unified;
34442
+ const carried = rateLimit.unified === void 0 || rateLimit.unified.overageStatus !== void 0 || earlier === void 0 ? void 0 : overageFactsOf(earlier);
34443
+ const merged = carried === void 0 || rateLimit.unified === void 0 ? rateLimit : { ...rateLimit, unified: { ...rateLimit.unified, ...carried } };
34386
34444
  return { ...current?.providers, [provider]: { ...state, rateLimit: keep ? state.rateLimit : merged } };
34387
34445
  })
34388
34446
  };
@@ -60908,7 +60966,8 @@ function unifiedFromReportedLimits(reported) {
60908
60966
  return { ...fiveHour === void 0 ? {} : { fiveHour }, ...sevenDay === void 0 ? {} : { sevenDay } };
60909
60967
  }
60910
60968
  function isAnthropicUsageProbeable(member) {
60911
- return planOf(member.account ?? member.snapshot?.account).kind === "subscription";
60969
+ const unified = member.snapshot?.providers[ANTHROPIC_PROVIDER]?.rateLimit?.unified;
60970
+ return planOf(member.account ?? member.snapshot?.account).kind === "subscription" && (unified === void 0 || soleOverageWindow(unified) === void 0);
60912
60971
  }
60913
60972
  function isAnthropicUsageStale(member, nowMs) {
60914
60973
  const rateLimit = member.snapshot?.providers[ANTHROPIC_PROVIDER]?.rateLimit;
@@ -60994,6 +61053,7 @@ var init_anthropicUsageRefresh = __esm({
60994
61053
  init_middleware();
60995
61054
  init_pick();
60996
61055
  init_plan2();
61056
+ init_rateLimit();
60997
61057
  PERCENT2 = 100;
60998
61058
  ANTHROPIC_USAGE_FRESHNESS_MS = FIVE_HOUR_WINDOW_MS / PERCENT2;
60999
61059
  NO_PLAN_WINDOWS_FRESHNESS_MS = SEVEN_DAY_WINDOW_MS / PERCENT2;
@@ -113105,11 +113165,11 @@ function rcFanoutOnDoorHub(fanout, hub) {
113105
113165
 
113106
113166
  // src/frontdoor/quotaExpiringEvents.ts
113107
113167
  init_schema2();
113108
- var MS_PER_HOUR2 = 36e5;
113168
+ var MS_PER_HOUR3 = 36e5;
113109
113169
  var MS_PER_DAY3 = 864e5;
113110
113170
  var FIVE_HOUR_WINDOW_HOURS = 5;
113111
113171
  var SEVEN_DAY_WINDOW_DAYS = 7;
113112
- var FIVE_HOUR_WINDOW_MS2 = FIVE_HOUR_WINDOW_HOURS * MS_PER_HOUR2;
113172
+ var FIVE_HOUR_WINDOW_MS2 = FIVE_HOUR_WINDOW_HOURS * MS_PER_HOUR3;
113113
113173
  var SEVEN_DAY_WINDOW_MS2 = SEVEN_DAY_WINDOW_DAYS * MS_PER_DAY3;
113114
113174
  var FINAL_SPAN_DENOMINATOR = 30;
113115
113175
  var QUOTA_EXPIRING_WINDOW_FRACTION = 1 / FINAL_SPAN_DENOMINATOR;
@@ -114393,6 +114453,7 @@ function createPassthroughRoute(name, target) {
114393
114453
 
114394
114454
  // src/frontdoor/providerRoute.ts
114395
114455
  init_conditions();
114456
+ init_quotaFacts();
114396
114457
  init_route();
114397
114458
  var import_node_stream3 = require("node:stream");
114398
114459
 
@@ -114475,7 +114536,6 @@ async function scanRequestHead(request7, wholeBody = false) {
114475
114536
  }
114476
114537
 
114477
114538
  // src/frontdoor/providerRoute.ts
114478
- var MS_PER_HOUR3 = 36e5;
114479
114539
  function createProviderRouteResolver(deps) {
114480
114540
  const isRcSelfHostPath = (path47) => path47 === "/v1/code/sessions" || path47.startsWith("/v1/code/sessions/") || path47 === "/v1/sessions" || path47.startsWith("/v1/sessions/");
114481
114541
  const oauthRoute = createPassthroughRoute("anthropic", { baseUrl: `https://${CONNECT_INTERCEPT_HOST}:${String(HTTPS_PORT)}`, stripPrefix: void 0, headroomUpstream: void 0 });
@@ -114575,16 +114635,9 @@ function createProviderRouteResolver(deps) {
114575
114635
  }
114576
114636
  const whole = routes.some((entry) => entry.model !== void 0 || referencesFact(entry.when, "request.hasImage"));
114577
114637
  const snapshot = deps.usageSnapshotOf?.(current.session.identity);
114578
- const windowFacts = (raw) => {
114579
- if (raw?.utilization === void 0 || raw.resetsAt === void 0) {
114580
- return void 0;
114581
- }
114582
- return { remaining: Math.max(0, 1 - raw.utilization), utilization: raw.utilization, hoursUntilReset: Math.max(0, (Date.parse(raw.resetsAt) - Date.now()) / MS_PER_HOUR3) };
114583
- };
114584
114638
  const providerQuota = Object.fromEntries(
114585
114639
  routes.flatMap((entry) => {
114586
- const unified = snapshot?.providers[entry.provider]?.rateLimit?.unified;
114587
- return [[entry.provider, { fiveHour: windowFacts(unified?.fiveHour), sevenDay: windowFacts(unified?.sevenDay) }]];
114640
+ return [[entry.provider, quotaFactsOf(snapshot?.providers[entry.provider]?.rateLimit?.unified, Date.now())]];
114588
114641
  })
114589
114642
  );
114590
114643
  const scan = await scanRequestHead(current, whole);
@@ -119020,6 +119073,7 @@ init_account();
119020
119073
  init_read();
119021
119074
  init_anthropicUsageRefresh();
119022
119075
  init_middleware();
119076
+ init_rateLimit();
119023
119077
  init_realAnthropicUsageProbe();
119024
119078
  init_store2();
119025
119079
  var DAY_MS3 = 864e5;
@@ -119052,13 +119106,19 @@ function formatWindow(label, window) {
119052
119106
  const used = window.utilization === void 0 ? "usage unknown" : `${String(Math.round(window.utilization * PERCENT4))}% used`;
119053
119107
  return `${label} ${used}${window.resetsAt === void 0 ? "" : `, resets ${window.resetsAt}`}${window.status === void 0 ? "" : ` (${window.status})`}`;
119054
119108
  }
119109
+ function extraUsageParts(unified) {
119110
+ const window = overageWindowOf(unified);
119111
+ const measured = window?.utilization !== void 0 || window?.resetsAt !== void 0;
119112
+ const fact = window === void 0 ? void 0 : measured ? formatWindow("extra usage", window) : `extra usage ${window.status ?? "unknown"}`;
119113
+ return [...fact === void 0 ? [] : [fact], ...unified.overageDisabledReason === void 0 ? [] : [`extra usage disabled: ${unified.overageDisabledReason}`]];
119114
+ }
119055
119115
  function formatRateLimit(state) {
119056
119116
  const { unified } = state;
119057
119117
  if (unified === void 0) {
119058
119118
  return `rate-limit headers (as of ${state.observedAt}): ${Object.entries(state.headers).map(([name, value2]) => `${name}=${value2}`).join(", ")}`;
119059
119119
  }
119060
119120
  const parts = [formatWindow("5h", unified.fiveHour), formatWindow("7d", unified.sevenDay)].filter((part) => part !== void 0);
119061
- return `quota (as of ${state.observedAt}): ${[...parts, `status ${unified.status ?? "unknown"}`, ...unified.overageStatus === void 0 ? [] : [`extra usage ${unified.overageStatus}`]].join("; ")}`;
119121
+ return `quota (as of ${state.observedAt}): ${[...parts, `status ${unified.status ?? "unknown"}`, ...extraUsageParts(unified)].join("; ")}`;
119062
119122
  }
119063
119123
  function formatLimit(limit) {
119064
119124
  const wait2 = [