@omnicross/core 0.3.0 → 0.4.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.
Files changed (49) hide show
  1. package/dist/auth/GeminiCodeAssistProjectResolver.cjs +3 -3
  2. package/dist/auth/GeminiCodeAssistProjectResolver.js +2 -2
  3. package/dist/{chunk-HVBBDBS3.cjs → chunk-2T6D7LWE.cjs} +96 -9
  4. package/dist/{chunk-VL5TUDTM.js → chunk-5DJSOFEP.js} +6 -1
  5. package/dist/{chunk-LKDAN4D7.js → chunk-5TEWZN5J.js} +112 -38
  6. package/dist/{chunk-6QQG7YG3.cjs → chunk-BKXC4XM6.cjs} +3 -3
  7. package/dist/{chunk-OPRS4IQZ.js → chunk-C3NPMQTK.js} +2 -2
  8. package/dist/{chunk-HOMUGKHR.js → chunk-GTDQCW3H.js} +29 -2
  9. package/dist/{chunk-23S5OPIO.js → chunk-HDXSPXIN.js} +1 -1
  10. package/dist/{chunk-MKF46GNZ.js → chunk-PF7YQBKX.js} +91 -4
  11. package/dist/{chunk-VSYQ6XYN.cjs → chunk-QEOV6Y4E.cjs} +516 -442
  12. package/dist/{chunk-U47LQXPB.js → chunk-QRXOLINS.js} +4 -1
  13. package/dist/{chunk-YNJNTCSQ.cjs → chunk-TX3AEV6H.cjs} +2 -2
  14. package/dist/{chunk-OIKREZVQ.cjs → chunk-TX4UCSOP.cjs} +30 -3
  15. package/dist/{chunk-T6NWPIYZ.cjs → chunk-YEVWA4C7.cjs} +4 -1
  16. package/dist/{chunk-4Z3ZLLC2.cjs → chunk-ZSA44G7J.cjs} +13 -8
  17. package/dist/completion/CompletionService.cjs +8 -8
  18. package/dist/completion/CompletionService.js +7 -7
  19. package/dist/completion.cjs +14 -8
  20. package/dist/completion.d.cts +22 -1
  21. package/dist/completion.d.ts +22 -1
  22. package/dist/completion.js +14 -8
  23. package/dist/index.cjs +14 -8
  24. package/dist/index.d.cts +1 -1
  25. package/dist/index.d.ts +1 -1
  26. package/dist/index.js +14 -8
  27. package/dist/outbound-api/routeResolver.cjs +2 -2
  28. package/dist/outbound-api/routeResolver.js +1 -1
  29. package/dist/outbound-api.cjs +8 -8
  30. package/dist/outbound-api.js +7 -7
  31. package/dist/pipeline/AccountAllowanceScheduling.cjs +3 -3
  32. package/dist/pipeline/AccountAllowanceScheduling.js +2 -2
  33. package/dist/pipeline/AccountAllowanceStore.cjs +6 -2
  34. package/dist/pipeline/AccountAllowanceStore.d.cts +41 -1
  35. package/dist/pipeline/AccountAllowanceStore.d.ts +41 -1
  36. package/dist/pipeline/AccountAllowanceStore.js +5 -1
  37. package/dist/pipeline/LlmConfigProviderAuth.cjs +2 -2
  38. package/dist/pipeline/LlmConfigProviderAuth.js +1 -1
  39. package/dist/pipeline/SubscriptionAuthSource.cjs +4 -4
  40. package/dist/pipeline/SubscriptionAuthSource.js +3 -3
  41. package/dist/pipeline/upstreamFetch.cjs +3 -3
  42. package/dist/pipeline/upstreamFetch.js +2 -2
  43. package/dist/provider-proxy/ProviderProxy.cjs +8 -8
  44. package/dist/provider-proxy/ProviderProxy.js +7 -7
  45. package/dist/provider-proxy/ingress/providerProxyShared.cjs +8 -8
  46. package/dist/provider-proxy/ingress/providerProxyShared.js +7 -7
  47. package/dist/provider-proxy.cjs +8 -8
  48. package/dist/provider-proxy.js +7 -7
  49. package/package.json +2 -2
@@ -7,9 +7,9 @@ require('../chunk-77USGNRW.cjs');
7
7
  require('../chunk-IUL4VWNU.cjs');
8
8
 
9
9
 
10
- var _chunk4Z3ZLLC2cjs = require('../chunk-4Z3ZLLC2.cjs');
10
+ var _chunkZSA44G7Jcjs = require('../chunk-ZSA44G7J.cjs');
11
11
  require('../chunk-235MXAGX.cjs');
12
- require('../chunk-HVBBDBS3.cjs');
12
+ require('../chunk-2T6D7LWE.cjs');
13
13
  require('../chunk-NKVZ6Z3Y.cjs');
14
14
 
15
15
  // src/auth/GeminiCodeAssistProjectResolver.ts
@@ -30,7 +30,7 @@ var GeminiCodeAssistHandshakeError = class extends Error {
30
30
  var GeminiCodeAssistProjectResolver = (_class = class {
31
31
  // upstream-proxy: the Code Assist handshake is upstream egress → honor the
32
32
  // gemini proxy by default (still injectable for tests).
33
- constructor(fetchImpl = (url, init) => _chunk4Z3ZLLC2cjs.fetchUpstream.call(void 0, url, init, { providerId: "gemini" })) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);
33
+ constructor(fetchImpl = (url, init) => _chunkZSA44G7Jcjs.fetchUpstream.call(void 0, url, init, { providerId: "gemini" })) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);
34
34
  this.fetchImpl = fetchImpl;
35
35
  }
36
36
 
@@ -7,9 +7,9 @@ import "../chunk-WYVGULTQ.js";
7
7
  import "../chunk-ZLNHPUFA.js";
8
8
  import {
9
9
  fetchUpstream
10
- } from "../chunk-VL5TUDTM.js";
10
+ } from "../chunk-5DJSOFEP.js";
11
11
  import "../chunk-3WD4HTR2.js";
12
- import "../chunk-MKF46GNZ.js";
12
+ import "../chunk-PF7YQBKX.js";
13
13
  import "../chunk-GL6XM527.js";
14
14
 
15
15
  // src/auth/GeminiCodeAssistProjectResolver.ts
@@ -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" || value === "grok" || value === "copilot";
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-PF7YQBKX.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
  });
@@ -62,7 +62,7 @@ import {
62
62
  import {
63
63
  LlmConfigProviderAuth,
64
64
  getProviderHeaders
65
- } from "./chunk-HOMUGKHR.js";
65
+ } from "./chunk-GTDQCW3H.js";
66
66
  import {
67
67
  resolveProviderChain
68
68
  } from "./chunk-JWC6APFQ.js";
@@ -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-HDXSPXIN.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-C3NPMQTK.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-QRXOLINS.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-5DJSOFEP.js";
141
141
  import {
142
142
  getSharedAccountAllowanceStore
143
- } from "./chunk-MKF46GNZ.js";
143
+ } from "./chunk-PF7YQBKX.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") {
@@ -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 _chunk2T6D7LWEcjs = require('./chunk-2T6D7LWE.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 = _chunk2T6D7LWEcjs.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" && providerId !== "grok" && providerId !== "copilot") {
77
77
  return { ...base, action: "ignore", reason: "provider-unsupported" };
78
78
  }
79
79
  const snapshot = this.store.get(providerId, accountId, now);
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getSharedAccountAllowanceStore
3
- } from "./chunk-MKF46GNZ.js";
3
+ } from "./chunk-PF7YQBKX.js";
4
4
 
5
5
  // src/pipeline/AccountAllowanceScheduling.ts
6
6
  var DEFAULT_POLICY = {
@@ -73,7 +73,7 @@ var AccountAllowanceScheduling = 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" && providerId !== "grok" && providerId !== "copilot") {
77
77
  return { ...base, action: "ignore", reason: "provider-unsupported" };
78
78
  }
79
79
  const snapshot = this.store.get(providerId, accountId, now);
@@ -45,10 +45,34 @@ function getProviderHeaders(provider, apiKey) {
45
45
  };
46
46
  break;
47
47
  }
48
+ const withExtra = mergeExtraHeaders(headers, provider.extraHeaders);
48
49
  if (isOpenRouterProvider(provider)) {
49
- return { ...headers, ...OPENROUTER_APP_HEADERS };
50
+ return { ...withExtra, ...OPENROUTER_APP_HEADERS };
50
51
  }
51
- return headers;
52
+ return withExtra;
53
+ }
54
+ function expandHeaderPlaceholder(value) {
55
+ return value.includes("{{platform}}") ? value.replaceAll("{{platform}}", process.platform) : value;
56
+ }
57
+ var EXTRA_HEADER_RESERVED_NAMES = /* @__PURE__ */ new Set([
58
+ "authorization",
59
+ "x-api-key",
60
+ "x-goog-api-key",
61
+ "api-key",
62
+ "cookie",
63
+ "content-type",
64
+ "content-length"
65
+ ]);
66
+ function mergeExtraHeaders(base, extra) {
67
+ if (!extra) return base;
68
+ const entries = Object.entries(extra);
69
+ if (entries.length === 0) return base;
70
+ const merged = { ...base };
71
+ for (const [name, value] of entries) {
72
+ if (EXTRA_HEADER_RESERVED_NAMES.has(name.toLowerCase())) continue;
73
+ merged[name] = expandHeaderPlaceholder(value);
74
+ }
75
+ return merged;
52
76
  }
53
77
 
54
78
  // src/pipeline/LlmConfigProviderAuth.ts
@@ -125,5 +149,8 @@ var LlmConfigProviderAuth = class {
125
149
 
126
150
  export {
127
151
  getProviderHeaders,
152
+ expandHeaderPlaceholder,
153
+ EXTRA_HEADER_RESERVED_NAMES,
154
+ mergeExtraHeaders,
128
155
  LlmConfigProviderAuth
129
156
  };
@@ -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-C3NPMQTK.js";
7
7
  import {
8
8
  isBoundAccountSelectionError
9
9
  } from "./chunk-2JYRIADS.js";