@omnicross/core 0.3.0 → 0.3.1

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.
Files changed (41) hide show
  1. package/dist/auth/GeminiCodeAssistProjectResolver.cjs +3 -3
  2. package/dist/auth/GeminiCodeAssistProjectResolver.js +2 -2
  3. package/dist/{chunk-T6NWPIYZ.cjs → chunk-AKIOOFY3.cjs} +2 -1
  4. package/dist/{chunk-VSYQ6XYN.cjs → chunk-EY3S7NJ3.cjs} +498 -424
  5. package/dist/{chunk-HVBBDBS3.cjs → chunk-FHXDUHVE.cjs} +96 -9
  6. package/dist/{chunk-VL5TUDTM.js → chunk-N5Q5PBV5.js} +6 -1
  7. package/dist/{chunk-MKF46GNZ.js → chunk-NJS2DZE6.js} +91 -4
  8. package/dist/{chunk-U47LQXPB.js → chunk-NRYLPGQB.js} +2 -1
  9. package/dist/{chunk-4Z3ZLLC2.cjs → chunk-RS773ZL3.cjs} +13 -8
  10. package/dist/{chunk-LKDAN4D7.js → chunk-STENJNJU.js} +111 -37
  11. package/dist/{chunk-23S5OPIO.js → chunk-T2VIZQT4.js} +1 -1
  12. package/dist/{chunk-6QQG7YG3.cjs → chunk-T55Z77BR.cjs} +3 -3
  13. package/dist/{chunk-YNJNTCSQ.cjs → chunk-XGVPGH7V.cjs} +2 -2
  14. package/dist/{chunk-OPRS4IQZ.js → chunk-YVBHFVTF.js} +2 -2
  15. package/dist/completion/CompletionService.cjs +7 -7
  16. package/dist/completion/CompletionService.js +6 -6
  17. package/dist/completion.cjs +7 -7
  18. package/dist/completion.js +6 -6
  19. package/dist/index.cjs +7 -7
  20. package/dist/index.js +6 -6
  21. package/dist/outbound-api/routeResolver.cjs +2 -2
  22. package/dist/outbound-api/routeResolver.js +1 -1
  23. package/dist/outbound-api.cjs +7 -7
  24. package/dist/outbound-api.js +6 -6
  25. package/dist/pipeline/AccountAllowanceScheduling.cjs +3 -3
  26. package/dist/pipeline/AccountAllowanceScheduling.js +2 -2
  27. package/dist/pipeline/AccountAllowanceStore.cjs +6 -2
  28. package/dist/pipeline/AccountAllowanceStore.d.cts +41 -1
  29. package/dist/pipeline/AccountAllowanceStore.d.ts +41 -1
  30. package/dist/pipeline/AccountAllowanceStore.js +5 -1
  31. package/dist/pipeline/SubscriptionAuthSource.cjs +4 -4
  32. package/dist/pipeline/SubscriptionAuthSource.js +3 -3
  33. package/dist/pipeline/upstreamFetch.cjs +3 -3
  34. package/dist/pipeline/upstreamFetch.js +2 -2
  35. package/dist/provider-proxy/ProviderProxy.cjs +7 -7
  36. package/dist/provider-proxy/ProviderProxy.js +6 -6
  37. package/dist/provider-proxy/ingress/providerProxyShared.cjs +7 -7
  38. package/dist/provider-proxy/ingress/providerProxyShared.js +6 -6
  39. package/dist/provider-proxy.cjs +7 -7
  40. package/dist/provider-proxy.js +6 -6
  41. package/package.json +2 -2
@@ -1,5 +1,6 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class;// src/pipeline/AccountAllowanceStore.ts
2
2
  var DEFAULT_CODEX_ALLOWANCE_FRESH_MS = 15 * 6e4;
3
+ var CLAUDE_HEADER_FRESH_MS = 5 * 6e4;
3
4
  var DEFAULT_ALLOWANCE_MAX_SNAPSHOTS = 256;
4
5
  var MAX_WINDOWS_PER_SNAPSHOT = 8;
5
6
  var MAX_TEXT_LENGTH = 200;
@@ -55,7 +56,7 @@ function normalizedInstant(value) {
55
56
  return Number.isFinite(parsed) ? new Date(parsed).toISOString() : void 0;
56
57
  }
57
58
  function isAllowanceProvider(value) {
58
- return value === "claude" || value === "codex" || value === "gemini" || value === "opencodego";
59
+ return value === "claude" || value === "codex" || value === "gemini" || value === "opencodego" || value === "kimi";
59
60
  }
60
61
  function isWindowState(value) {
61
62
  return value === "fresh" || value === "stale" || value === "unavailable" || value === "unsupported";
@@ -135,11 +136,15 @@ function parseWindow(headers, prefix) {
135
136
  const resetAfterSeconds = finiteNumber(
136
137
  headerValue(headers, `x-codex-${prefix}-reset-after-seconds`)
137
138
  );
139
+ const resetAtSeconds = finiteNumber(headerValue(headers, `x-codex-${prefix}-reset-at`));
138
140
  const windowMinutes = finiteNumber(headerValue(headers, `x-codex-${prefix}-window-minutes`));
139
- if (usedPercent === void 0 && resetAfterSeconds === void 0 && windowMinutes === void 0) {
141
+ if (usedPercent === void 0 && resetAfterSeconds === void 0 && resetAtSeconds === void 0 && windowMinutes === void 0) {
140
142
  return void 0;
141
143
  }
142
- return { usedPercent, resetAfterSeconds, windowMinutes };
144
+ return { usedPercent, resetAfterSeconds, resetAtSeconds, windowMinutes };
145
+ }
146
+ function epochMsFromMaybeSeconds(value) {
147
+ return value > 1e11 ? value : value * 1e3;
143
148
  }
144
149
  function parseCodexAllowanceHeaders(headers) {
145
150
  const primary = parseWindow(headers, "primary");
@@ -150,6 +155,23 @@ function parseCodexAllowanceHeaders(headers) {
150
155
  if (!primary && !secondary && primaryOverSecondaryLimitPercent === void 0) return null;
151
156
  return { primary, secondary, primaryOverSecondaryLimitPercent };
152
157
  }
158
+ function parseUnifiedWindow(headers, windowId) {
159
+ const prefix = `anthropic-ratelimit-unified-${windowId}-`;
160
+ const fraction = finiteNumber(headerValue(headers, `${prefix}utilization`));
161
+ const resetSeconds = finiteNumber(headerValue(headers, `${prefix}reset`));
162
+ if (fraction === void 0 && resetSeconds === void 0) return void 0;
163
+ return {
164
+ ...fraction !== void 0 ? { usedPercent: Math.round(Math.min(100, Math.max(0, fraction * 100))) } : {},
165
+ ...resetSeconds !== void 0 && resetSeconds > 0 ? { resetAtMs: epochMsFromMaybeSeconds(resetSeconds) } : {}
166
+ };
167
+ }
168
+ function parseClaudeAllowanceHeaders(headers) {
169
+ const fiveHour = parseUnifiedWindow(headers, "5h");
170
+ const sevenDay = parseUnifiedWindow(headers, "7d");
171
+ const scopedSevenDay = parseUnifiedWindow(headers, "7d_oi");
172
+ if (!fiveHour && !sevenDay && !scopedSevenDay) return null;
173
+ return { fiveHour, sevenDay, scopedSevenDay };
174
+ }
153
175
  function durationLabel(minutes) {
154
176
  if (minutes === void 0) return void 0;
155
177
  if (minutes % (7 * 24 * 60) === 0) {
@@ -183,13 +205,13 @@ function remainingSeconds(resetsAt, now) {
183
205
  }
184
206
  function mergeCodexWindow(id, observation, existing, observedMs) {
185
207
  const windowMinutes = _nullishCoalesce(_optionalChain([observation, 'optionalAccess', _ => _.windowMinutes]), () => ( _optionalChain([existing, 'optionalAccess', _2 => _2.windowMinutes])));
186
- const nextResetAt = _optionalChain([observation, 'optionalAccess', _3 => _3.resetAfterSeconds]) !== void 0 ? resetAt(observedMs, observation.resetAfterSeconds) : _optionalChain([existing, 'optionalAccess', _4 => _4.resetsAt]);
208
+ const nextResetAt = _optionalChain([observation, 'optionalAccess', _3 => _3.resetAtSeconds]) !== void 0 ? new Date(epochMsFromMaybeSeconds(observation.resetAtSeconds)).toISOString() : _optionalChain([observation, 'optionalAccess', _4 => _4.resetAfterSeconds]) !== void 0 ? resetAt(observedMs, observation.resetAfterSeconds) : _optionalChain([existing, 'optionalAccess', _5 => _5.resetsAt]);
187
209
  const hasExistingData = !!existing && (existing.usedPercent !== null || existing.windowMinutes !== void 0 || existing.resetsAt !== void 0);
188
210
  return {
189
211
  id,
190
212
  label: codexLabel(id, windowMinutes),
191
213
  scope: "all",
192
- usedPercent: _nullishCoalesce(_nullishCoalesce(_optionalChain([observation, 'optionalAccess', _5 => _5.usedPercent]), () => ( _optionalChain([existing, 'optionalAccess', _6 => _6.usedPercent]))), () => ( null)),
214
+ usedPercent: _nullishCoalesce(_nullishCoalesce(_optionalChain([observation, 'optionalAccess', _6 => _6.usedPercent]), () => ( _optionalChain([existing, 'optionalAccess', _7 => _7.usedPercent]))), () => ( null)),
193
215
  windowMinutes,
194
216
  resetsAt: nextResetAt,
195
217
  remainingSeconds: remainingSeconds(nextResetAt, observedMs),
@@ -279,8 +301,8 @@ var AccountAllowanceStore = (_class = class {
279
301
  const observation = parseCodexAllowanceHeaders(headers);
280
302
  if (!observation) return this.get("codex", accountId, observedMs);
281
303
  const previous = this.snapshots.get(snapshotKey("codex", accountId));
282
- const previousPrimary = _optionalChain([previous, 'optionalAccess', _7 => _7.source]) === "response-headers" ? previous.windows.find((window) => window.id === "primary") : void 0;
283
- const previousSecondary = _optionalChain([previous, 'optionalAccess', _8 => _8.source]) === "response-headers" ? previous.windows.find((window) => window.id === "secondary") : void 0;
304
+ const previousPrimary = _optionalChain([previous, 'optionalAccess', _8 => _8.source]) === "response-headers" ? previous.windows.find((window) => window.id === "primary") : void 0;
305
+ const previousSecondary = _optionalChain([previous, 'optionalAccess', _9 => _9.source]) === "response-headers" ? previous.windows.find((window) => window.id === "secondary") : void 0;
284
306
  const observedAt = new Date(observedMs).toISOString();
285
307
  const snapshot = {
286
308
  providerId: "codex",
@@ -292,11 +314,74 @@ var AccountAllowanceStore = (_class = class {
292
314
  mergeCodexWindow("primary", observation.primary, previousPrimary, observedMs),
293
315
  mergeCodexWindow("secondary", observation.secondary, previousSecondary, observedMs)
294
316
  ],
295
- primaryOverSecondaryLimitPercent: _nullishCoalesce(observation.primaryOverSecondaryLimitPercent, () => ( _optionalChain([previous, 'optionalAccess', _9 => _9.primaryOverSecondaryLimitPercent])))
317
+ primaryOverSecondaryLimitPercent: _nullishCoalesce(observation.primaryOverSecondaryLimitPercent, () => ( _optionalChain([previous, 'optionalAccess', _10 => _10.primaryOverSecondaryLimitPercent])))
296
318
  };
297
319
  this.set(snapshot);
298
320
  return this.get("codex", accountId, observedMs);
299
321
  }
322
+ /**
323
+ * Merge one real Claude upstream response's `anthropic-ratelimit-unified-*`
324
+ * headers into the selected account's snapshot. Live-traffic updates are the
325
+ * passive complement to the daemon's `/api/oauth/usage` poll: they keep the
326
+ * 5h/7d windows fresh between polls WITHOUT an extra request. A response with
327
+ * no recognized headers is a strict no-op; an existing snapshot keeps its
328
+ * provenance (`source`) and any windows the headers did not mention.
329
+ */
330
+ recordClaudeHeaders(accountId, headers, observedMs = this.now()) {
331
+ if (!accountId) return null;
332
+ const observation = parseClaudeAllowanceHeaders(headers);
333
+ if (!observation) return this.get("claude", accountId, observedMs);
334
+ const previous = this.snapshots.get(snapshotKey("claude", accountId));
335
+ const observedAt = new Date(observedMs).toISOString();
336
+ const expiresAt = new Date(observedMs + CLAUDE_HEADER_FRESH_MS).toISOString();
337
+ const mergeWindow = (existing, observed, defaults) => ({
338
+ id: defaults.id,
339
+ label: defaults.label,
340
+ scope: defaults.scope,
341
+ ...defaults.scope === "model-family" && defaults.modelFamily ? { modelFamily: defaults.modelFamily } : {},
342
+ // An unobserved window keeps its last value and merely ages to stale.
343
+ usedPercent: _nullishCoalesce(_nullishCoalesce(_optionalChain([observed, 'optionalAccess', _11 => _11.usedPercent]), () => ( _optionalChain([existing, 'optionalAccess', _12 => _12.usedPercent]))), () => ( null)),
344
+ windowMinutes: defaults.windowMinutes,
345
+ resetsAt: _optionalChain([observed, 'optionalAccess', _13 => _13.resetAtMs]) !== void 0 ? new Date(observed.resetAtMs).toISOString() : _optionalChain([existing, 'optionalAccess', _14 => _14.resetsAt]),
346
+ remainingSeconds: void 0,
347
+ state: observed ? "fresh" : existing && (existing.usedPercent !== null || existing.resetsAt) ? "stale" : "unavailable"
348
+ });
349
+ const previousWindow = (id) => _optionalChain([previous, 'optionalAccess', _15 => _15.windows, 'access', _16 => _16.find, 'call', _17 => _17((window) => window.id === id)]);
350
+ const windows = [
351
+ mergeWindow(previousWindow("five-hour"), observation.fiveHour, {
352
+ id: "five-hour",
353
+ label: "5 hours",
354
+ scope: "all",
355
+ windowMinutes: 5 * 60
356
+ }),
357
+ mergeWindow(previousWindow("seven-day"), observation.sevenDay, {
358
+ id: "seven-day",
359
+ label: "7 days",
360
+ scope: "all",
361
+ windowMinutes: 7 * 24 * 60
362
+ }),
363
+ mergeWindow(previousWindow("seven-day-fable"), observation.scopedSevenDay, {
364
+ id: "seven-day-fable",
365
+ label: "7 days \xB7 Fable",
366
+ scope: "model-family",
367
+ modelFamily: "fable",
368
+ windowMinutes: 7 * 24 * 60
369
+ }),
370
+ ...(_nullishCoalesce(_optionalChain([previous, 'optionalAccess', _18 => _18.windows]), () => ( []))).filter(
371
+ (window) => !["five-hour", "seven-day", "seven-day-fable"].includes(window.id)
372
+ )
373
+ ].slice(0, 8);
374
+ const snapshot = {
375
+ providerId: "claude",
376
+ accountId,
377
+ source: _nullishCoalesce(_optionalChain([previous, 'optionalAccess', _19 => _19.source]), () => ( "response-headers")),
378
+ observedAt,
379
+ expiresAt,
380
+ windows
381
+ };
382
+ this.set(snapshot);
383
+ return this.get("claude", accountId, observedMs);
384
+ }
300
385
  clear() {
301
386
  if (this.snapshots.size === 0) return;
302
387
  this.snapshots.clear();
@@ -347,4 +432,6 @@ function __resetSharedAccountAllowanceStoreForTests() {
347
432
 
348
433
 
349
434
 
350
- exports.DEFAULT_CODEX_ALLOWANCE_FRESH_MS = DEFAULT_CODEX_ALLOWANCE_FRESH_MS; exports.DEFAULT_ALLOWANCE_MAX_SNAPSHOTS = DEFAULT_ALLOWANCE_MAX_SNAPSHOTS; exports.normalizeAccountAllowanceSnapshot = normalizeAccountAllowanceSnapshot; exports.parseCodexAllowanceHeaders = parseCodexAllowanceHeaders; exports.AccountAllowanceStore = AccountAllowanceStore; exports.getSharedAccountAllowanceStore = getSharedAccountAllowanceStore; exports.setSharedAccountAllowanceStore = setSharedAccountAllowanceStore; exports.__resetSharedAccountAllowanceStoreForTests = __resetSharedAccountAllowanceStoreForTests;
435
+
436
+
437
+ exports.DEFAULT_CODEX_ALLOWANCE_FRESH_MS = DEFAULT_CODEX_ALLOWANCE_FRESH_MS; exports.CLAUDE_HEADER_FRESH_MS = CLAUDE_HEADER_FRESH_MS; exports.DEFAULT_ALLOWANCE_MAX_SNAPSHOTS = DEFAULT_ALLOWANCE_MAX_SNAPSHOTS; exports.normalizeAccountAllowanceSnapshot = normalizeAccountAllowanceSnapshot; exports.parseCodexAllowanceHeaders = parseCodexAllowanceHeaders; exports.parseClaudeAllowanceHeaders = parseClaudeAllowanceHeaders; exports.AccountAllowanceStore = AccountAllowanceStore; exports.getSharedAccountAllowanceStore = getSharedAccountAllowanceStore; exports.setSharedAccountAllowanceStore = setSharedAccountAllowanceStore; exports.__resetSharedAccountAllowanceStoreForTests = __resetSharedAccountAllowanceStoreForTests;
@@ -6,7 +6,7 @@ import {
6
6
  } from "./chunk-3WD4HTR2.js";
7
7
  import {
8
8
  getSharedAccountAllowanceStore
9
- } from "./chunk-MKF46GNZ.js";
9
+ } from "./chunk-NJS2DZE6.js";
10
10
  import {
11
11
  getSharedAccountRouteActivity
12
12
  } from "./chunk-GL6XM527.js";
@@ -121,6 +121,11 @@ function fetchUpstream(url, init, ctx) {
121
121
  getSharedAccountAllowanceStore().recordCodexHeaders(ctx.accountId, response.headers);
122
122
  } catch {
123
123
  }
124
+ } else if (ctx?.providerId === "claude" && ctx.accountId) {
125
+ try {
126
+ getSharedAccountAllowanceStore().recordClaudeHeaders(ctx.accountId, response.headers);
127
+ } catch {
128
+ }
124
129
  }
125
130
  return response;
126
131
  });
@@ -1,5 +1,6 @@
1
1
  // src/pipeline/AccountAllowanceStore.ts
2
2
  var DEFAULT_CODEX_ALLOWANCE_FRESH_MS = 15 * 6e4;
3
+ var CLAUDE_HEADER_FRESH_MS = 5 * 6e4;
3
4
  var DEFAULT_ALLOWANCE_MAX_SNAPSHOTS = 256;
4
5
  var MAX_WINDOWS_PER_SNAPSHOT = 8;
5
6
  var MAX_TEXT_LENGTH = 200;
@@ -55,7 +56,7 @@ function normalizedInstant(value) {
55
56
  return Number.isFinite(parsed) ? new Date(parsed).toISOString() : void 0;
56
57
  }
57
58
  function isAllowanceProvider(value) {
58
- return value === "claude" || value === "codex" || value === "gemini" || value === "opencodego";
59
+ return value === "claude" || value === "codex" || value === "gemini" || value === "opencodego" || value === "kimi";
59
60
  }
60
61
  function isWindowState(value) {
61
62
  return value === "fresh" || value === "stale" || value === "unavailable" || value === "unsupported";
@@ -135,11 +136,15 @@ function parseWindow(headers, prefix) {
135
136
  const resetAfterSeconds = finiteNumber(
136
137
  headerValue(headers, `x-codex-${prefix}-reset-after-seconds`)
137
138
  );
139
+ const resetAtSeconds = finiteNumber(headerValue(headers, `x-codex-${prefix}-reset-at`));
138
140
  const windowMinutes = finiteNumber(headerValue(headers, `x-codex-${prefix}-window-minutes`));
139
- if (usedPercent === void 0 && resetAfterSeconds === void 0 && windowMinutes === void 0) {
141
+ if (usedPercent === void 0 && resetAfterSeconds === void 0 && resetAtSeconds === void 0 && windowMinutes === void 0) {
140
142
  return void 0;
141
143
  }
142
- return { usedPercent, resetAfterSeconds, windowMinutes };
144
+ return { usedPercent, resetAfterSeconds, resetAtSeconds, windowMinutes };
145
+ }
146
+ function epochMsFromMaybeSeconds(value) {
147
+ return value > 1e11 ? value : value * 1e3;
143
148
  }
144
149
  function parseCodexAllowanceHeaders(headers) {
145
150
  const primary = parseWindow(headers, "primary");
@@ -150,6 +155,23 @@ function parseCodexAllowanceHeaders(headers) {
150
155
  if (!primary && !secondary && primaryOverSecondaryLimitPercent === void 0) return null;
151
156
  return { primary, secondary, primaryOverSecondaryLimitPercent };
152
157
  }
158
+ function parseUnifiedWindow(headers, windowId) {
159
+ const prefix = `anthropic-ratelimit-unified-${windowId}-`;
160
+ const fraction = finiteNumber(headerValue(headers, `${prefix}utilization`));
161
+ const resetSeconds = finiteNumber(headerValue(headers, `${prefix}reset`));
162
+ if (fraction === void 0 && resetSeconds === void 0) return void 0;
163
+ return {
164
+ ...fraction !== void 0 ? { usedPercent: Math.round(Math.min(100, Math.max(0, fraction * 100))) } : {},
165
+ ...resetSeconds !== void 0 && resetSeconds > 0 ? { resetAtMs: epochMsFromMaybeSeconds(resetSeconds) } : {}
166
+ };
167
+ }
168
+ function parseClaudeAllowanceHeaders(headers) {
169
+ const fiveHour = parseUnifiedWindow(headers, "5h");
170
+ const sevenDay = parseUnifiedWindow(headers, "7d");
171
+ const scopedSevenDay = parseUnifiedWindow(headers, "7d_oi");
172
+ if (!fiveHour && !sevenDay && !scopedSevenDay) return null;
173
+ return { fiveHour, sevenDay, scopedSevenDay };
174
+ }
153
175
  function durationLabel(minutes) {
154
176
  if (minutes === void 0) return void 0;
155
177
  if (minutes % (7 * 24 * 60) === 0) {
@@ -183,7 +205,7 @@ function remainingSeconds(resetsAt, now) {
183
205
  }
184
206
  function mergeCodexWindow(id, observation, existing, observedMs) {
185
207
  const windowMinutes = observation?.windowMinutes ?? existing?.windowMinutes;
186
- const nextResetAt = observation?.resetAfterSeconds !== void 0 ? resetAt(observedMs, observation.resetAfterSeconds) : existing?.resetsAt;
208
+ const nextResetAt = observation?.resetAtSeconds !== void 0 ? new Date(epochMsFromMaybeSeconds(observation.resetAtSeconds)).toISOString() : observation?.resetAfterSeconds !== void 0 ? resetAt(observedMs, observation.resetAfterSeconds) : existing?.resetsAt;
187
209
  const hasExistingData = !!existing && (existing.usedPercent !== null || existing.windowMinutes !== void 0 || existing.resetsAt !== void 0);
188
210
  return {
189
211
  id,
@@ -297,6 +319,69 @@ var AccountAllowanceStore = class {
297
319
  this.set(snapshot);
298
320
  return this.get("codex", accountId, observedMs);
299
321
  }
322
+ /**
323
+ * Merge one real Claude upstream response's `anthropic-ratelimit-unified-*`
324
+ * headers into the selected account's snapshot. Live-traffic updates are the
325
+ * passive complement to the daemon's `/api/oauth/usage` poll: they keep the
326
+ * 5h/7d windows fresh between polls WITHOUT an extra request. A response with
327
+ * no recognized headers is a strict no-op; an existing snapshot keeps its
328
+ * provenance (`source`) and any windows the headers did not mention.
329
+ */
330
+ recordClaudeHeaders(accountId, headers, observedMs = this.now()) {
331
+ if (!accountId) return null;
332
+ const observation = parseClaudeAllowanceHeaders(headers);
333
+ if (!observation) return this.get("claude", accountId, observedMs);
334
+ const previous = this.snapshots.get(snapshotKey("claude", accountId));
335
+ const observedAt = new Date(observedMs).toISOString();
336
+ const expiresAt = new Date(observedMs + CLAUDE_HEADER_FRESH_MS).toISOString();
337
+ const mergeWindow = (existing, observed, defaults) => ({
338
+ id: defaults.id,
339
+ label: defaults.label,
340
+ scope: defaults.scope,
341
+ ...defaults.scope === "model-family" && defaults.modelFamily ? { modelFamily: defaults.modelFamily } : {},
342
+ // An unobserved window keeps its last value and merely ages to stale.
343
+ usedPercent: observed?.usedPercent ?? existing?.usedPercent ?? null,
344
+ windowMinutes: defaults.windowMinutes,
345
+ resetsAt: observed?.resetAtMs !== void 0 ? new Date(observed.resetAtMs).toISOString() : existing?.resetsAt,
346
+ remainingSeconds: void 0,
347
+ state: observed ? "fresh" : existing && (existing.usedPercent !== null || existing.resetsAt) ? "stale" : "unavailable"
348
+ });
349
+ const previousWindow = (id) => previous?.windows.find((window) => window.id === id);
350
+ const windows = [
351
+ mergeWindow(previousWindow("five-hour"), observation.fiveHour, {
352
+ id: "five-hour",
353
+ label: "5 hours",
354
+ scope: "all",
355
+ windowMinutes: 5 * 60
356
+ }),
357
+ mergeWindow(previousWindow("seven-day"), observation.sevenDay, {
358
+ id: "seven-day",
359
+ label: "7 days",
360
+ scope: "all",
361
+ windowMinutes: 7 * 24 * 60
362
+ }),
363
+ mergeWindow(previousWindow("seven-day-fable"), observation.scopedSevenDay, {
364
+ id: "seven-day-fable",
365
+ label: "7 days \xB7 Fable",
366
+ scope: "model-family",
367
+ modelFamily: "fable",
368
+ windowMinutes: 7 * 24 * 60
369
+ }),
370
+ ...(previous?.windows ?? []).filter(
371
+ (window) => !["five-hour", "seven-day", "seven-day-fable"].includes(window.id)
372
+ )
373
+ ].slice(0, 8);
374
+ const snapshot = {
375
+ providerId: "claude",
376
+ accountId,
377
+ source: previous?.source ?? "response-headers",
378
+ observedAt,
379
+ expiresAt,
380
+ windows
381
+ };
382
+ this.set(snapshot);
383
+ return this.get("claude", accountId, observedMs);
384
+ }
300
385
  clear() {
301
386
  if (this.snapshots.size === 0) return;
302
387
  this.snapshots.clear();
@@ -340,9 +425,11 @@ function __resetSharedAccountAllowanceStoreForTests() {
340
425
 
341
426
  export {
342
427
  DEFAULT_CODEX_ALLOWANCE_FRESH_MS,
428
+ CLAUDE_HEADER_FRESH_MS,
343
429
  DEFAULT_ALLOWANCE_MAX_SNAPSHOTS,
344
430
  normalizeAccountAllowanceSnapshot,
345
431
  parseCodexAllowanceHeaders,
432
+ parseClaudeAllowanceHeaders,
346
433
  AccountAllowanceStore,
347
434
  getSharedAccountAllowanceStore,
348
435
  setSharedAccountAllowanceStore,
@@ -119,7 +119,8 @@ var SUBSCRIPTION_PROVIDER_IDS = [
119
119
  "claude",
120
120
  "codex",
121
121
  "gemini",
122
- "opencodego"
122
+ "opencodego",
123
+ "kimi"
123
124
  ];
124
125
  var SUBSCRIPTION_ID_SET = new Set(SUBSCRIPTION_PROVIDER_IDS);
125
126
  function isSubscriptionProviderId(providerId) {
@@ -6,7 +6,7 @@
6
6
  var _chunk235MXAGXcjs = require('./chunk-235MXAGX.cjs');
7
7
 
8
8
 
9
- var _chunkHVBBDBS3cjs = require('./chunk-HVBBDBS3.cjs');
9
+ var _chunkFHXDUHVEcjs = require('./chunk-FHXDUHVE.cjs');
10
10
 
11
11
 
12
12
  var _chunkNKVZ6Z3Ycjs = require('./chunk-NKVZ6Z3Y.cjs');
@@ -118,16 +118,21 @@ function fetchUpstream(url, init, ctx) {
118
118
  const doFetchWithAllowanceTap = () => doFetch().then((response) => {
119
119
  if (_optionalChain([ctx, 'optionalAccess', _4 => _4.providerId]) === "codex" && ctx.accountId) {
120
120
  try {
121
- _chunkHVBBDBS3cjs.getSharedAccountAllowanceStore.call(void 0, ).recordCodexHeaders(ctx.accountId, response.headers);
121
+ _chunkFHXDUHVEcjs.getSharedAccountAllowanceStore.call(void 0, ).recordCodexHeaders(ctx.accountId, response.headers);
122
122
  } catch (e4) {
123
123
  }
124
+ } else if (_optionalChain([ctx, 'optionalAccess', _5 => _5.providerId]) === "claude" && ctx.accountId) {
125
+ try {
126
+ _chunkFHXDUHVEcjs.getSharedAccountAllowanceStore.call(void 0, ).recordClaudeHeaders(ctx.accountId, response.headers);
127
+ } catch (e5) {
128
+ }
124
129
  }
125
130
  return response;
126
131
  });
127
- const activity = _optionalChain([ctx, 'optionalAccess', _5 => _5.routeActivity]);
128
- const activityStartedAt = activity && _optionalChain([ctx, 'optionalAccess', _6 => _6.providerId]) && ctx.accountId ? Date.now() : 0;
132
+ const activity = _optionalChain([ctx, 'optionalAccess', _6 => _6.routeActivity]);
133
+ const activityStartedAt = activity && _optionalChain([ctx, 'optionalAccess', _7 => _7.providerId]) && ctx.accountId ? Date.now() : 0;
129
134
  const recordActivity = (status) => {
130
- if (!activity || !_optionalChain([ctx, 'optionalAccess', _7 => _7.providerId]) || !ctx.accountId) return;
135
+ if (!activity || !_optionalChain([ctx, 'optionalAccess', _8 => _8.providerId]) || !ctx.accountId) return;
131
136
  const record = _chunkNKVZ6Z3Ycjs.getSharedAccountRouteActivity.call(void 0, ).record({
132
137
  providerId: ctx.providerId,
133
138
  accountId: ctx.accountId,
@@ -140,8 +145,8 @@ function fetchUpstream(url, init, ctx) {
140
145
  ts: activityStartedAt
141
146
  });
142
147
  try {
143
- _optionalChain([activity, 'access', _8 => _8.onRecorded, 'optionalCall', _9 => _9(record)]);
144
- } catch (e5) {
148
+ _optionalChain([activity, 'access', _9 => _9.onRecorded, 'optionalCall', _10 => _10(record)]);
149
+ } catch (e6) {
145
150
  }
146
151
  };
147
152
  const doFetchWithActivity = () => doFetchWithAllowanceTap().then(
@@ -155,7 +160,7 @@ function fetchUpstream(url, init, ctx) {
155
160
  }
156
161
  );
157
162
  const tracePath = _chunk235MXAGXcjs.getUpstreamTracePath.call(void 0, );
158
- if (!tracePath || !_optionalChain([ctx, 'optionalAccess', _10 => _10.providerId])) return doFetchWithActivity();
163
+ if (!tracePath || !_optionalChain([ctx, 'optionalAccess', _11 => _11.providerId])) return doFetchWithActivity();
159
164
  const startedAt = Date.now();
160
165
  const method = typeof init.method === "string" ? init.method : "GET";
161
166
  const requestHeaders = _chunk235MXAGXcjs.redactHeaders.call(void 0,
@@ -78,13 +78,13 @@ import {
78
78
  } from "./chunk-V2UKUTJ3.js";
79
79
  import {
80
80
  SubscriptionAuthSource
81
- } from "./chunk-23S5OPIO.js";
81
+ } from "./chunk-T2VIZQT4.js";
82
82
  import {
83
83
  serializeError
84
84
  } from "./chunk-AVYJ4YBN.js";
85
85
  import {
86
86
  isAccountAllowanceExhaustedError
87
- } from "./chunk-OPRS4IQZ.js";
87
+ } from "./chunk-YVBHFVTF.js";
88
88
  import {
89
89
  boundAccountSelectionMessage,
90
90
  isBoundAccountSelectionError
@@ -109,7 +109,7 @@ import {
109
109
  parseModelRef,
110
110
  resolvePrefixTarget,
111
111
  resolveRoute
112
- } from "./chunk-U47LQXPB.js";
112
+ } from "./chunk-NRYLPGQB.js";
113
113
  import {
114
114
  getSubscriptionRegistryForOutbound
115
115
  } from "./chunk-AQ5TNQB7.js";
@@ -137,10 +137,10 @@ import {
137
137
  } from "./chunk-ZLNHPUFA.js";
138
138
  import {
139
139
  fetchUpstream
140
- } from "./chunk-VL5TUDTM.js";
140
+ } from "./chunk-N5Q5PBV5.js";
141
141
  import {
142
142
  getSharedAccountAllowanceStore
143
- } from "./chunk-MKF46GNZ.js";
143
+ } from "./chunk-NJS2DZE6.js";
144
144
  import {
145
145
  getSharedAccountRouteActivity
146
146
  } from "./chunk-GL6XM527.js";
@@ -2297,6 +2297,67 @@ function recordResponsesStreamUsage(recorder, rawUsage, attribution) {
2297
2297
  }
2298
2298
  }
2299
2299
 
2300
+ // src/provider-proxy/ingress/codexUsageLimitDetection.ts
2301
+ var PROVIDER_ID = "codex";
2302
+ var DEFAULT_QUOTA_COOLDOWN_MS = 5 * 6e4;
2303
+ var QUOTA_EXHAUSTED_PERCENT = 90;
2304
+ var BODY_SCAN_LIMIT = 4096;
2305
+ function parseTryAgainDeadline(bodyText) {
2306
+ const match = bodyText.match(/try again (?:at|on)\s+(.+?)(?:[.\n]|$)/i);
2307
+ if (!match) return void 0;
2308
+ const cleaned = match[1].replace(/(\d+)(st|nd|rd|th)/giu, "$1").trim();
2309
+ const ms = Date.parse(cleaned);
2310
+ return Number.isFinite(ms) ? ms : void 0;
2311
+ }
2312
+ var CODEX_USAGE_LIMIT_ERROR_CODES = /* @__PURE__ */ new Set([
2313
+ "usage_limit_reached",
2314
+ "usage_not_included",
2315
+ "rate_limit_exceeded"
2316
+ ]);
2317
+ function parseCodexUsageLimitErrorPayload(bodyText) {
2318
+ const raw = bodyText.slice(0, BODY_SCAN_LIMIT * 4).trim();
2319
+ if (!raw.startsWith("{")) return null;
2320
+ try {
2321
+ const parsed = JSON.parse(raw);
2322
+ const error = parsed?.error;
2323
+ const code = error?.code;
2324
+ if (typeof code !== "string" || !CODEX_USAGE_LIMIT_ERROR_CODES.has(code)) return null;
2325
+ const resetsAt = error?.resets_at;
2326
+ let resetsAtMs;
2327
+ if (typeof resetsAt === "number" && Number.isFinite(resetsAt) && resetsAt > 0) {
2328
+ resetsAtMs = resetsAt > 1e11 ? resetsAt : resetsAt * 1e3;
2329
+ }
2330
+ const planType = error?.plan_type;
2331
+ return {
2332
+ code,
2333
+ ...resetsAtMs !== void 0 ? { resetsAtMs } : {},
2334
+ ...typeof planType === "string" && planType ? { planType } : {}
2335
+ };
2336
+ } catch {
2337
+ return null;
2338
+ }
2339
+ }
2340
+ function deadlineFromAllowanceSnapshot(accountId, now) {
2341
+ const snapshot = getSharedAccountAllowanceStore().get(PROVIDER_ID, accountId, now);
2342
+ if (!snapshot) return void 0;
2343
+ const candidates = snapshot.windows.filter(
2344
+ (w) => typeof w.usedPercent === "number" && w.usedPercent >= QUOTA_EXHAUSTED_PERCENT && typeof w.resetsAt === "string"
2345
+ ).map((w) => ({ ms: Date.parse(w.resetsAt), usedPercent: w.usedPercent })).filter((x) => Number.isFinite(x.ms) && x.ms > now).sort((a, b) => b.usedPercent - a.usedPercent);
2346
+ return candidates[0]?.ms;
2347
+ }
2348
+ function resolveCodexQuotaDeadline(accountId, bodyText, now = Date.now()) {
2349
+ const structured = parseCodexUsageLimitErrorPayload(bodyText);
2350
+ const structuredDeadline = structured?.resetsAtMs !== void 0 && structured.resetsAtMs > now ? structured.resetsAtMs : void 0;
2351
+ const parsed = parseTryAgainDeadline(bodyText);
2352
+ const parsedDeadline = parsed !== void 0 && parsed > now ? parsed : void 0;
2353
+ return deadlineFromAllowanceSnapshot(accountId, now) ?? structuredDeadline ?? parsedDeadline ?? now + DEFAULT_QUOTA_COOLDOWN_MS;
2354
+ }
2355
+ function markCodexUsageLimitExhaustion(accountId, bodyText, now = Date.now()) {
2356
+ if (!accountId) return;
2357
+ const deadline = resolveCodexQuotaDeadline(accountId, bodyText, now);
2358
+ getSharedAccountHealth().markQuotaExhausted(PROVIDER_ID, accountId, deadline, now);
2359
+ }
2360
+
2300
2361
  // src/provider-proxy/responses/responsesAffinity.ts
2301
2362
  function previousResponseNotFound() {
2302
2363
  return new OpenAIOperationError({
@@ -2412,36 +2473,6 @@ function getResponsesAffinityStore(owner) {
2412
2473
  return store;
2413
2474
  }
2414
2475
 
2415
- // src/provider-proxy/ingress/codexUsageLimitDetection.ts
2416
- var PROVIDER_ID = "codex";
2417
- var DEFAULT_QUOTA_COOLDOWN_MS = 5 * 6e4;
2418
- var QUOTA_EXHAUSTED_PERCENT = 90;
2419
- function parseTryAgainDeadline(bodyText) {
2420
- const match = bodyText.match(/try again (?:at|on)\s+(.+?)(?:[.\n]|$)/i);
2421
- if (!match) return void 0;
2422
- const cleaned = match[1].replace(/(\d+)(st|nd|rd|th)/giu, "$1").trim();
2423
- const ms = Date.parse(cleaned);
2424
- return Number.isFinite(ms) ? ms : void 0;
2425
- }
2426
- function deadlineFromAllowanceSnapshot(accountId, now) {
2427
- const snapshot = getSharedAccountAllowanceStore().get(PROVIDER_ID, accountId, now);
2428
- if (!snapshot) return void 0;
2429
- const candidates = snapshot.windows.filter(
2430
- (w) => typeof w.usedPercent === "number" && w.usedPercent >= QUOTA_EXHAUSTED_PERCENT && typeof w.resetsAt === "string"
2431
- ).map((w) => ({ ms: Date.parse(w.resetsAt), usedPercent: w.usedPercent })).filter((x) => Number.isFinite(x.ms) && x.ms > now).sort((a, b) => b.usedPercent - a.usedPercent);
2432
- return candidates[0]?.ms;
2433
- }
2434
- function resolveCodexQuotaDeadline(accountId, bodyText, now = Date.now()) {
2435
- const parsed = parseTryAgainDeadline(bodyText);
2436
- const parsedDeadline = parsed !== void 0 && parsed > now ? parsed : void 0;
2437
- return deadlineFromAllowanceSnapshot(accountId, now) ?? parsedDeadline ?? now + DEFAULT_QUOTA_COOLDOWN_MS;
2438
- }
2439
- function markCodexUsageLimitExhaustion(accountId, bodyText, now = Date.now()) {
2440
- if (!accountId) return;
2441
- const deadline = resolveCodexQuotaDeadline(accountId, bodyText, now);
2442
- getSharedAccountHealth().markQuotaExhausted(PROVIDER_ID, accountId, deadline, now);
2443
- }
2444
-
2445
2476
  // src/provider-proxy/responses/responsesProfile.ts
2446
2477
  function classifyResponsesProfile(declaration) {
2447
2478
  if (declaration.authMode === "byo") {
@@ -3624,11 +3655,25 @@ function responsesSearchDisabledError() {
3624
3655
  // src/provider-proxy/ingress/openaiResponsesIngress.ts
3625
3656
  var SERVER_OVERLOADED_CODES = /* @__PURE__ */ new Set(["server_is_overloaded", "slow_down"]);
3626
3657
  function isCodexServerOverloadEvent(event) {
3627
- if (event["type"] !== "response.failed") return false;
3628
- const error = event["response"]?.["error"];
3658
+ const error = codexResponseFailedError(event);
3629
3659
  const code = error?.["code"];
3630
3660
  return typeof code === "string" && SERVER_OVERLOADED_CODES.has(code);
3631
3661
  }
3662
+ function codexResponseFailedError(event) {
3663
+ if (event["type"] !== "response.failed") return void 0;
3664
+ const error = event["response"]?.["error"];
3665
+ return error && typeof error === "object" ? error : void 0;
3666
+ }
3667
+ var USAGE_LIMIT_CODES = /* @__PURE__ */ new Set(["usage_limit_reached", "usage_not_included"]);
3668
+ function isCodexUsageLimitEvent(event) {
3669
+ const error = codexResponseFailedError(event);
3670
+ const code = error?.["code"];
3671
+ return typeof code === "string" && USAGE_LIMIT_CODES.has(code);
3672
+ }
3673
+ function codexUsageLimitEventBody(event) {
3674
+ const error = codexResponseFailedError(event);
3675
+ return JSON.stringify({ error: error ?? {} });
3676
+ }
3632
3677
  var SAFE_INJECTED_CACHE_KEY_SOURCES = /* @__PURE__ */ new Set([
3633
3678
  "session-header",
3634
3679
  "thread-header",
@@ -3908,10 +3953,21 @@ async function handleResponsesOperation(res, responsesBody, route, deps, request
3908
3953
  };
3909
3954
  }
3910
3955
  let overloadRecorded = false;
3956
+ let usageLimitRecorded = false;
3911
3957
  const observeSse = (event) => {
3912
3958
  if (event.type === "response.completed") {
3913
3959
  recordAffinity(event.response?.id);
3914
3960
  }
3961
+ if (!usageLimitRecorded && isCodexUsageLimitEvent(event)) {
3962
+ usageLimitRecorded = true;
3963
+ if (providerResponse.accountId) {
3964
+ markCodexUsageLimitExhaustion(
3965
+ providerResponse.accountId,
3966
+ codexUsageLimitEventBody(event)
3967
+ );
3968
+ }
3969
+ return;
3970
+ }
3915
3971
  if (overloadRecorded || !isCodexServerOverloadEvent(event)) return;
3916
3972
  overloadRecorded = true;
3917
3973
  if (providerResponse.activityRecordId) {
@@ -4009,7 +4065,25 @@ async function handleAnthropicMessagesByo(res, rawBody, route, deps, options = {
4009
4065
  const overloadActivityId = providerResponse.activityRecordId;
4010
4066
  const overloadAccountId = providerResponse.accountId;
4011
4067
  let overloadRecorded = false;
4068
+ let usageLimitRecorded = false;
4012
4069
  const codexOverloadDetector = plan.isSubscription && !plan.sameFormat && plan.transformerProvider.name === "codex" ? (event) => {
4070
+ if (!usageLimitRecorded) {
4071
+ let limitHit = isCodexUsageLimitEvent(event);
4072
+ if (!limitHit && event["type"] === "error") {
4073
+ const message = event["error"]?.["message"];
4074
+ limitHit = typeof message === "string" && (message.includes("usage_limit_reached") || message.includes("usage_not_included"));
4075
+ }
4076
+ if (limitHit) {
4077
+ usageLimitRecorded = true;
4078
+ if (overloadAccountId) {
4079
+ markCodexUsageLimitExhaustion(
4080
+ overloadAccountId,
4081
+ codexUsageLimitEventBody(event)
4082
+ );
4083
+ }
4084
+ return;
4085
+ }
4086
+ }
4013
4087
  if (overloadRecorded) return;
4014
4088
  let hit = isCodexServerOverloadEvent(event);
4015
4089
  if (!hit && event["type"] === "error") {
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-AVYJ4YBN.js";
4
4
  import {
5
5
  isAccountAllowanceExhaustedError
6
- } from "./chunk-OPRS4IQZ.js";
6
+ } from "./chunk-YVBHFVTF.js";
7
7
  import {
8
8
  isBoundAccountSelectionError
9
9
  } from "./chunk-2JYRIADS.js";
@@ -1,6 +1,6 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } var _class; var _class2;
2
2
 
3
- var _chunkHVBBDBS3cjs = require('./chunk-HVBBDBS3.cjs');
3
+ var _chunkFHXDUHVEcjs = require('./chunk-FHXDUHVE.cjs');
4
4
 
5
5
  // src/pipeline/AccountAllowanceScheduling.ts
6
6
  var DEFAULT_POLICY = {
@@ -34,7 +34,7 @@ function freshWorstWindow(snapshot) {
34
34
  return snapshot.windows.filter((window) => window.state === "fresh" && typeof window.usedPercent === "number").sort((left, right) => (_nullishCoalesce(right.usedPercent, () => ( -1))) - (_nullishCoalesce(left.usedPercent, () => ( -1))))[0];
35
35
  }
36
36
  var AccountAllowanceScheduling = (_class2 = class {
37
- constructor(store = _chunkHVBBDBS3cjs.getSharedAccountAllowanceStore.call(void 0, ), now = Date.now) {;_class2.prototype.__init3.call(this);_class2.prototype.__init4.call(this);_class2.prototype.__init5.call(this);
37
+ constructor(store = _chunkFHXDUHVEcjs.getSharedAccountAllowanceStore.call(void 0, ), now = Date.now) {;_class2.prototype.__init3.call(this);_class2.prototype.__init4.call(this);_class2.prototype.__init5.call(this);
38
38
  this.store = store;
39
39
  this.now = now;
40
40
  }
@@ -73,7 +73,7 @@ var AccountAllowanceScheduling = (_class2 = class {
73
73
  decidedAt
74
74
  };
75
75
  if (!this.config.enabled) return { ...base, action: "ignore", reason: "policy-disabled" };
76
- if (providerId !== "claude" && providerId !== "codex") {
76
+ if (providerId !== "claude" && providerId !== "codex" && providerId !== "kimi" && providerId !== "opencodego") {
77
77
  return { ...base, action: "ignore", reason: "provider-unsupported" };
78
78
  }
79
79
  const snapshot = this.store.get(providerId, accountId, now);