@omnicross/core 0.1.2 → 0.1.3

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 (131) hide show
  1. package/dist/auth/GeminiCodeAssistProjectResolver.cjs +6 -1
  2. package/dist/auth/GeminiCodeAssistProjectResolver.js +6 -1
  3. package/dist/{chunk-SN3YWBX7.cjs → chunk-2FMI2B6V.cjs} +2329 -533
  4. package/dist/{chunk-XBSYYZIY.cjs → chunk-3QOSDDNI.cjs} +39 -3
  5. package/dist/{chunk-2FEVTJWG.js → chunk-4DECIFU7.js} +2162 -366
  6. package/dist/chunk-4IH4EL7M.cjs +9 -0
  7. package/dist/chunk-5ENKBSWO.js +311 -0
  8. package/dist/chunk-6RPZADX3.cjs +92 -0
  9. package/dist/chunk-AEOZIDEB.cjs +32 -0
  10. package/dist/chunk-BO4RFWBR.js +89 -0
  11. package/dist/{chunk-MNYKI4CI.js → chunk-CWM2ZDU5.js} +36 -0
  12. package/dist/chunk-CZHZGRU7.js +383 -0
  13. package/dist/{chunk-4NBS6KPV.cjs → chunk-DQ5VAYZ6.cjs} +7 -8
  14. package/dist/chunk-HUZZZ3JL.js +32 -0
  15. package/dist/{chunk-QOCNX236.js → chunk-IAXWICZU.js} +24 -1
  16. package/dist/{chunk-V5KPWNYX.cjs → chunk-JMJBSACD.cjs} +3 -3
  17. package/dist/chunk-L74VDN4A.cjs +32 -0
  18. package/dist/{chunk-74TMJA7Z.js → chunk-N5QFKSDO.js} +7 -4
  19. package/dist/{chunk-LKZJEL6E.cjs → chunk-Q27JY5RG.cjs} +6 -4
  20. package/dist/{chunk-SPVWWUHX.cjs → chunk-QWBWGODS.cjs} +24 -1
  21. package/dist/chunk-RPII3E6Z.cjs +145 -0
  22. package/dist/chunk-S6JGLF3G.cjs +89 -0
  23. package/dist/chunk-SVXC36MU.cjs +383 -0
  24. package/dist/chunk-TKJMZBAH.js +32 -0
  25. package/dist/{chunk-ZSVQT3PW.js → chunk-UBWEBKRC.js} +5 -6
  26. package/dist/chunk-UNEFIWXI.cjs +32 -0
  27. package/dist/chunk-VQY5W4YW.cjs +311 -0
  28. package/dist/chunk-WNY4WMRF.js +32 -0
  29. package/dist/chunk-XEKD23J5.js +9 -0
  30. package/dist/chunk-XTEI64OU.js +145 -0
  31. package/dist/chunk-XX6NQJMA.js +92 -0
  32. package/dist/{chunk-N3V2J5ZO.cjs → chunk-Y6OM7EV7.cjs} +7 -4
  33. package/dist/{chunk-745DV5FL.js → chunk-Y7FO65VT.js} +3 -3
  34. package/dist/{chunk-PXUJF5HS.js → chunk-ZY6KU6P3.js} +4 -2
  35. package/dist/completion/CompletionService.cjs +22 -15
  36. package/dist/completion/CompletionService.js +21 -14
  37. package/dist/completion/NativeSearchInjector.cjs +3 -3
  38. package/dist/completion/NativeSearchInjector.js +2 -2
  39. package/dist/completion/openrouter-headers.cjs +3 -6
  40. package/dist/completion/openrouter-headers.d.cts +9 -12
  41. package/dist/completion/openrouter-headers.d.ts +9 -12
  42. package/dist/completion/openrouter-headers.js +2 -5
  43. package/dist/completion/openrouter-models.cjs +4 -3
  44. package/dist/completion/openrouter-models.js +2 -1
  45. package/dist/completion.cjs +22 -15
  46. package/dist/completion.js +21 -14
  47. package/dist/index.cjs +139 -17
  48. package/dist/index.d.cts +40 -10
  49. package/dist/index.d.ts +40 -10
  50. package/dist/index.js +146 -24
  51. package/dist/outbound-api/routeResolver.cjs +5 -2
  52. package/dist/outbound-api/routeResolver.d.cts +8 -2
  53. package/dist/outbound-api/routeResolver.d.ts +8 -2
  54. package/dist/outbound-api/routeResolver.js +4 -1
  55. package/dist/outbound-api/types.cjs +6 -1
  56. package/dist/outbound-api/types.d.cts +11 -144
  57. package/dist/outbound-api/types.d.ts +11 -144
  58. package/dist/outbound-api/types.js +6 -0
  59. package/dist/outbound-api.cjs +133 -15
  60. package/dist/outbound-api.d.cts +786 -25
  61. package/dist/outbound-api.d.ts +786 -25
  62. package/dist/outbound-api.js +137 -19
  63. package/dist/pipeline/AuthSource.d.cts +23 -1
  64. package/dist/pipeline/AuthSource.d.ts +23 -1
  65. package/dist/pipeline/LlmConfigProviderAuth.cjs +3 -3
  66. package/dist/pipeline/LlmConfigProviderAuth.js +2 -2
  67. package/dist/pipeline/SubscriptionAccountHealth.cjs +22 -0
  68. package/dist/pipeline/SubscriptionAccountHealth.d.cts +235 -0
  69. package/dist/pipeline/SubscriptionAccountHealth.d.ts +235 -0
  70. package/dist/pipeline/SubscriptionAccountHealth.js +22 -0
  71. package/dist/pipeline/SubscriptionAuthSource.cjs +2 -2
  72. package/dist/pipeline/SubscriptionAuthSource.d.cts +3 -2
  73. package/dist/pipeline/SubscriptionAuthSource.d.ts +3 -2
  74. package/dist/pipeline/SubscriptionAuthSource.js +1 -1
  75. package/dist/pipeline/SubscriptionAuthStrategy.d.cts +24 -1
  76. package/dist/pipeline/SubscriptionAuthStrategy.d.ts +24 -1
  77. package/dist/pipeline/auditSink.cjs +14 -0
  78. package/dist/pipeline/auditSink.d.cts +48 -0
  79. package/dist/pipeline/auditSink.d.ts +48 -0
  80. package/dist/pipeline/auditSink.js +14 -0
  81. package/dist/pipeline/billingEmit.cjs +14 -0
  82. package/dist/pipeline/billingEmit.d.cts +49 -0
  83. package/dist/pipeline/billingEmit.d.ts +49 -0
  84. package/dist/pipeline/billingEmit.js +14 -0
  85. package/dist/ports/usage-event-store.d.cts +26 -1
  86. package/dist/ports/usage-event-store.d.ts +26 -1
  87. package/dist/ports.d.cts +7 -1
  88. package/dist/ports.d.ts +7 -1
  89. package/dist/provider-proxy/ProviderProxy.cjs +22 -15
  90. package/dist/provider-proxy/ProviderProxy.js +21 -14
  91. package/dist/provider-proxy/identity/SubscriptionIdentityStore.cjs +15 -0
  92. package/dist/provider-proxy/identity/SubscriptionIdentityStore.d.cts +121 -0
  93. package/dist/provider-proxy/identity/SubscriptionIdentityStore.d.ts +121 -0
  94. package/dist/provider-proxy/identity/SubscriptionIdentityStore.js +15 -0
  95. package/dist/provider-proxy/identity/fingerprintHeaders.cjs +20 -0
  96. package/dist/provider-proxy/identity/fingerprintHeaders.d.cts +89 -0
  97. package/dist/provider-proxy/identity/fingerprintHeaders.d.ts +89 -0
  98. package/dist/provider-proxy/identity/fingerprintHeaders.js +20 -0
  99. package/dist/provider-proxy/ingress/providerProxyShared.cjs +22 -15
  100. package/dist/provider-proxy/ingress/providerProxyShared.d.cts +11 -2
  101. package/dist/provider-proxy/ingress/providerProxyShared.d.ts +11 -2
  102. package/dist/provider-proxy/ingress/providerProxyShared.js +21 -14
  103. package/dist/provider-proxy/matchText.cjs +4 -2
  104. package/dist/provider-proxy/matchText.d.cts +14 -1
  105. package/dist/provider-proxy/matchText.d.ts +14 -1
  106. package/dist/provider-proxy/matchText.js +3 -1
  107. package/dist/provider-proxy/types.d.cts +23 -0
  108. package/dist/provider-proxy/types.d.ts +23 -0
  109. package/dist/provider-proxy.cjs +22 -15
  110. package/dist/provider-proxy.js +21 -14
  111. package/dist/{routeResolver-HE-ZO0fO.d.ts → routeResolver-B1NglTfe.d.ts} +36 -10
  112. package/dist/{routeResolver-BrbK6ja9.d.cts → routeResolver-CbG5uBgm.d.cts} +36 -10
  113. package/dist/transformer/transformers.cjs +7 -7
  114. package/dist/transformer/transformers.js +7 -7
  115. package/dist/transformer.cjs +5 -5
  116. package/dist/transformer.js +4 -4
  117. package/dist/types-6OUY_xfA.d.ts +830 -0
  118. package/dist/types-aBFFXoBz.d.cts +830 -0
  119. package/dist/usage/usage-recorder.cjs +2 -2
  120. package/dist/usage/usage-recorder.d.cts +19 -1
  121. package/dist/usage/usage-recorder.d.ts +19 -1
  122. package/dist/usage/usage-recorder.js +1 -1
  123. package/dist/usage.cjs +2 -2
  124. package/dist/usage.js +1 -1
  125. package/package.json +4 -2
  126. package/dist/chunk-3MEACFK3.js +0 -193
  127. package/dist/chunk-6VIXXLMX.cjs +0 -14
  128. package/dist/chunk-E3WHL7CO.js +0 -14
  129. package/dist/chunk-G2FUJNA2.cjs +0 -193
  130. package/dist/{chunk-UYPEN5XE.cjs → chunk-FFALUUZZ.cjs} +5 -5
  131. package/dist/{chunk-O466Y272.js → chunk-MQNDWYPN.js} +6 -6
@@ -1,7 +1,4 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 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; var _class2; var _class3; var _class4; var _class5;
2
-
3
- var _chunkSPVWWUHXcjs = require('./chunk-SPVWWUHX.cjs');
4
-
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 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; var _class2; var _class3; var _class4; var _class5; var _class6; var _class7; var _class8; var _class9; var _class10; var _class11; var _class12; var _class13;
5
2
 
6
3
  var _chunkHQP3K7PUcjs = require('./chunk-HQP3K7PU.cjs');
7
4
 
@@ -9,7 +6,7 @@ var _chunkHQP3K7PUcjs = require('./chunk-HQP3K7PU.cjs');
9
6
  var _chunk46ZIFWYGcjs = require('./chunk-46ZIFWYG.cjs');
10
7
 
11
8
 
12
- var _chunkGBHYAGX3cjs = require('./chunk-GBHYAGX3.cjs');
9
+ var _chunk4VAVYUZScjs = require('./chunk-4VAVYUZS.cjs');
13
10
 
14
11
 
15
12
  var _chunk7YN22L2Hcjs = require('./chunk-7YN22L2H.cjs');
@@ -18,52 +15,88 @@ var _chunk7YN22L2Hcjs = require('./chunk-7YN22L2H.cjs');
18
15
  var _chunk2DCNB7DFcjs = require('./chunk-2DCNB7DF.cjs');
19
16
 
20
17
 
21
- var _chunk4VAVYUZScjs = require('./chunk-4VAVYUZS.cjs');
18
+ var _chunk3QOSDDNIcjs = require('./chunk-3QOSDDNI.cjs');
22
19
 
23
20
 
24
- var _chunkR3HK6R4Bcjs = require('./chunk-R3HK6R4B.cjs');
21
+ var _chunkGBHYAGX3cjs = require('./chunk-GBHYAGX3.cjs');
25
22
 
26
23
 
27
- var _chunkKUU2RNG6cjs = require('./chunk-KUU2RNG6.cjs');
24
+ var _chunkRPII3E6Zcjs = require('./chunk-RPII3E6Z.cjs');
28
25
 
29
26
 
30
27
 
31
- var _chunkLKZJEL6Ecjs = require('./chunk-LKZJEL6E.cjs');
28
+ var _chunk6RPZADX3cjs = require('./chunk-6RPZADX3.cjs');
32
29
 
33
30
 
34
- var _chunkQXD4MV2Xcjs = require('./chunk-QXD4MV2X.cjs');
31
+
32
+ var _chunkQWBWGODScjs = require('./chunk-QWBWGODS.cjs');
35
33
 
36
34
 
37
35
  var _chunkNYUNU75Acjs = require('./chunk-NYUNU75A.cjs');
38
36
 
39
37
 
40
- var _chunkN3V2J5ZOcjs = require('./chunk-N3V2J5ZO.cjs');
38
+
39
+ var _chunkVQY5W4YWcjs = require('./chunk-VQY5W4YW.cjs');
40
+
41
+
42
+ var _chunkY6OM7EV7cjs = require('./chunk-Y6OM7EV7.cjs');
41
43
 
42
44
 
43
45
  var _chunkSVNDB62Dcjs = require('./chunk-SVNDB62D.cjs');
44
46
 
45
47
 
48
+ var _chunkR3HK6R4Bcjs = require('./chunk-R3HK6R4B.cjs');
49
+
50
+
51
+
52
+ var _chunkAEOZIDEBcjs = require('./chunk-AEOZIDEB.cjs');
53
+
54
+
55
+
56
+ var _chunkL74VDN4Acjs = require('./chunk-L74VDN4A.cjs');
57
+
58
+
59
+ var _chunkKUU2RNG6cjs = require('./chunk-KUU2RNG6.cjs');
60
+
61
+
62
+
63
+ var _chunkQ27JY5RGcjs = require('./chunk-Q27JY5RG.cjs');
64
+
65
+
66
+ var _chunkQXD4MV2Xcjs = require('./chunk-QXD4MV2X.cjs');
67
+
68
+
46
69
 
47
70
 
48
71
  var _chunkA2YMUCBTcjs = require('./chunk-A2YMUCBT.cjs');
49
72
 
50
73
 
51
- var _chunkG2FUJNA2cjs = require('./chunk-G2FUJNA2.cjs');
52
74
 
53
75
 
54
76
 
55
- var _chunkSUEGJ75Dcjs = require('./chunk-SUEGJ75D.cjs');
56
77
 
57
78
 
58
- var _chunkV5KPWNYXcjs = require('./chunk-V5KPWNYX.cjs');
59
79
 
60
80
 
81
+ var _chunkSVXC36MUcjs = require('./chunk-SVXC36MU.cjs');
82
+
83
+
84
+
85
+ var _chunkSUEGJ75Dcjs = require('./chunk-SUEGJ75D.cjs');
86
+
87
+
88
+ var _chunkS6JGLF3Gcjs = require('./chunk-S6JGLF3G.cjs');
89
+
61
90
 
62
- var _chunk6VIXXLMXcjs = require('./chunk-6VIXXLMX.cjs');
91
+ var _chunkJMJBSACDcjs = require('./chunk-JMJBSACD.cjs');
63
92
 
64
93
 
65
94
  var _chunkGMMT7RVNcjs = require('./chunk-GMMT7RVN.cjs');
66
95
 
96
+
97
+
98
+ var _chunkUNEFIWXIcjs = require('./chunk-UNEFIWXI.cjs');
99
+
67
100
  // src/completion/StreamEventBuffer.ts
68
101
  var TERMINAL_TYPES = /* @__PURE__ */ new Set(["done", "error", "abort"]);
69
102
  var QUEUE_CAP = 200;
@@ -325,7 +358,7 @@ function convertMessageToGemini(msg) {
325
358
 
326
359
  // src/completion/openrouter-utils.ts
327
360
  function getOpenRouterProviderConfig(provider, modelId) {
328
- if (!_chunk6VIXXLMXcjs.isOpenRouterProvider.call(void 0, provider)) {
361
+ if (!_chunkUNEFIWXIcjs.isOpenRouterProvider.call(void 0, provider)) {
329
362
  return void 0;
330
363
  }
331
364
  const modelConfig = _optionalChain([provider, 'access', _ => _.modelConfigs, 'optionalAccess', _2 => _2.find, 'call', _3 => _3((m) => m.id === modelId)]);
@@ -462,10 +495,11 @@ function recordAnthropicNonStreamUsage(recorder, bodyText, attribution) {
462
495
  sessionId: attribution.sessionId,
463
496
  providerId: attribution.providerId,
464
497
  model: attribution.model,
465
- apiKeyId: null,
498
+ apiKeyId: attribution.apiKeyId,
466
499
  engineOrigin: "codex-ingress",
467
500
  usage: tapped,
468
- rawUsage: parsed.usage
501
+ rawUsage: parsed.usage,
502
+ auditResponse: attribution.auditResponse
469
503
  });
470
504
  } catch (e4) {
471
505
  }
@@ -502,7 +536,84 @@ function readBody(req) {
502
536
  req.on("error", reject);
503
537
  });
504
538
  }
505
- async function relayResponse(res, providerResponse, isStream) {
539
+ function rewriteJsonModel(bodyText, rewriteModel) {
540
+ try {
541
+ const obj = JSON.parse(bodyText);
542
+ if (!obj || typeof obj !== "object") return bodyText;
543
+ let changed = false;
544
+ if (typeof obj.model === "string") {
545
+ obj.model = rewriteModel;
546
+ changed = true;
547
+ }
548
+ const nested = obj.response;
549
+ if (nested && typeof nested === "object" && typeof nested.model === "string") {
550
+ nested.model = rewriteModel;
551
+ changed = true;
552
+ }
553
+ return changed ? JSON.stringify(obj) : bodyText;
554
+ } catch (e5) {
555
+ return bodyText;
556
+ }
557
+ }
558
+ function rewriteSseLine(line, rewriteModel) {
559
+ if (!line.startsWith("data:") || !line.includes('"model"')) return line;
560
+ const nl = /\r?\n$/.exec(line);
561
+ const newline = nl ? nl[0] : "";
562
+ const withoutNl = newline ? line.slice(0, line.length - newline.length) : line;
563
+ const afterData = withoutNl.slice("data:".length);
564
+ const leadingSpace = afterData.startsWith(" ") ? " " : "";
565
+ const payload = afterData.slice(leadingSpace.length);
566
+ if (payload === "" || payload === "[DONE]") return line;
567
+ try {
568
+ const obj = JSON.parse(payload);
569
+ if (!obj || typeof obj !== "object") return line;
570
+ const type = typeof obj.type === "string" ? obj.type : "";
571
+ let changed = false;
572
+ if (type === "message_start") {
573
+ const message = obj.message;
574
+ if (message && typeof message === "object" && typeof message.model === "string") {
575
+ message.model = rewriteModel;
576
+ changed = true;
577
+ }
578
+ } else if (type === "response.created" || type === "response.in_progress" || type === "response.completed" || type === "response.failed" || type === "response.incomplete") {
579
+ const response = obj.response;
580
+ if (response && typeof response === "object" && typeof response.model === "string") {
581
+ response.model = rewriteModel;
582
+ changed = true;
583
+ }
584
+ }
585
+ if (!changed) return line;
586
+ return `data:${leadingSpace}${JSON.stringify(obj)}${newline}`;
587
+ } catch (e6) {
588
+ return line;
589
+ }
590
+ }
591
+ async function relayStreamWithModelRewrite(res, body, rewriteModel) {
592
+ const reader = body.getReader();
593
+ const decoder = new TextDecoder();
594
+ let buffer = "";
595
+ try {
596
+ for (; ; ) {
597
+ const { done, value } = await reader.read();
598
+ if (done) break;
599
+ buffer += decoder.decode(value, { stream: true });
600
+ let out = "";
601
+ let nlIndex;
602
+ while ((nlIndex = buffer.indexOf("\n")) !== -1) {
603
+ const linePart = buffer.slice(0, nlIndex + 1);
604
+ buffer = buffer.slice(nlIndex + 1);
605
+ out += rewriteSseLine(linePart, rewriteModel);
606
+ }
607
+ if (out) res.write(out);
608
+ }
609
+ const tail = buffer + decoder.decode();
610
+ if (tail) res.write(rewriteSseLine(tail, rewriteModel));
611
+ } finally {
612
+ reader.releaseLock();
613
+ res.end();
614
+ }
615
+ }
616
+ async function relayResponse(res, providerResponse, isStream, rewriteModel) {
506
617
  const contentType = _nullishCoalesce(providerResponse.headers.get("Content-Type"), () => ( ""));
507
618
  const status = providerResponse.status && providerResponse.status >= 100 ? providerResponse.status : 200;
508
619
  if (isStream || contentType.includes("text/event-stream")) {
@@ -515,6 +626,10 @@ async function relayResponse(res, providerResponse, isStream) {
515
626
  res.end();
516
627
  return null;
517
628
  }
629
+ if (rewriteModel) {
630
+ await relayStreamWithModelRewrite(res, providerResponse.body, rewriteModel);
631
+ return null;
632
+ }
518
633
  const reader = providerResponse.body.getReader();
519
634
  try {
520
635
  for (; ; ) {
@@ -529,8 +644,9 @@ async function relayResponse(res, providerResponse, isStream) {
529
644
  return null;
530
645
  }
531
646
  const bodyText = await providerResponse.text();
647
+ const clientText = rewriteModel ? rewriteJsonModel(bodyText, rewriteModel) : bodyText;
532
648
  res.writeHead(status, { "Content-Type": contentType.includes("json") ? contentType : "application/json" });
533
- res.end(bodyText);
649
+ res.end(clientText);
534
650
  return bodyText;
535
651
  }
536
652
  function writeError(res, status, message) {
@@ -568,17 +684,18 @@ async function buildSubscriptionPlan(res, route, deps, anthropicBody, routeModel
568
684
  resolvedModel = mapped.resolvedModel;
569
685
  scenario = mapped.scenario;
570
686
  }
571
- const plan = buildSubscriptionIterationPlan(profile, route, deps, resolvedModel, isStream, scenario);
687
+ const sessionKey = _chunkQWBWGODScjs.deriveSubscriptionSessionKey.call(void 0, anthropicBody);
688
+ const plan = buildSubscriptionIterationPlan(profile, route, deps, resolvedModel, isStream, scenario, sessionKey);
572
689
  if (!plan) {
573
690
  writeError(res, 502, "Subscription profile is missing resolveUpstreamUrl");
574
691
  return null;
575
692
  }
576
693
  return plan;
577
694
  }
578
- function buildSubscriptionIterationPlan(profile, route, deps, resolvedModel, isStream, scenario) {
695
+ function buildSubscriptionIterationPlan(profile, route, deps, resolvedModel, isStream, scenario, sessionKey) {
579
696
  const upstreamUrl = _optionalChain([profile, 'access', _8 => _8.resolveUpstreamUrl, 'optionalCall', _9 => _9(resolvedModel, route.subscriptionConfig)]);
580
697
  if (!upstreamUrl) return null;
581
- const auth = _nullishCoalesce(route.auth, () => ( new (0, _chunkN3V2J5ZOcjs.SubscriptionAuthSource)(profile)));
698
+ const auth = _nullishCoalesce(route.auth, () => ( new (0, _chunkY6OM7EV7cjs.SubscriptionAuthSource)(profile)));
582
699
  const sameFormat = profile.mode === "pass-through" || upstreamUrl.endsWith("/v1/messages");
583
700
  const overrideNames = _optionalChain([profile, 'access', _10 => _10.resolveProviderTransformerNames, 'optionalCall', _11 => _11(
584
701
  resolvedModel,
@@ -622,7 +739,8 @@ function buildSubscriptionIterationPlan(profile, route, deps, resolvedModel, isS
622
739
  upstreamUrl,
623
740
  sameFormat,
624
741
  isSubscription: true,
625
- scenario
742
+ scenario,
743
+ sessionKey
626
744
  };
627
745
  }
628
746
  function usesResponsesChain(names) {
@@ -641,7 +759,7 @@ function buildSubscriptionRequestSummary(anthropicBody) {
641
759
  estimatedInputTokens: Math.ceil(totalChars / 4),
642
760
  // Single source of truth (shared with the dispatcher builder) so both
643
761
  // ingress paths yield identical `matchText` for the same body.
644
- matchText: _chunkSPVWWUHXcjs.collectMatchText.call(void 0, anthropicBody)
762
+ matchText: _chunkQWBWGODScjs.collectMatchText.call(void 0, anthropicBody)
645
763
  };
646
764
  }
647
765
  function collectText(value) {
@@ -657,12 +775,24 @@ function collectText(value) {
657
775
  }
658
776
  return 0;
659
777
  }
660
- async function runPipeline(anthropicBody, plan) {
778
+ function proxyProviderId(plan) {
779
+ return plan.isSubscription ? plan.transformerProvider.name : "byo";
780
+ }
781
+ async function runPipeline(anthropicBody, plan, reportSelection) {
661
782
  const executor = getSharedExecutor();
662
783
  const endpointTransformer = getAnthropicEndpointTransformer();
663
784
  const { auth, chain, transformerProvider, resolvedModel, isStream, resolveUrl, upstreamUrl } = plan;
785
+ let proxyAccountId;
664
786
  const authHeaders = {};
665
- await auth.applyHeaders(authHeaders, { upstreamUrl, model: resolvedModel });
787
+ await auth.applyHeaders(authHeaders, {
788
+ upstreamUrl,
789
+ model: resolvedModel,
790
+ sessionKey: plan.sessionKey,
791
+ reportSelection: (accountId, isActive) => {
792
+ proxyAccountId = accountId;
793
+ _optionalChain([reportSelection, 'optionalCall', _12 => _12(accountId, isActive)]);
794
+ }
795
+ });
666
796
  let rawStatus = null;
667
797
  const { response } = await _chunkKUU2RNG6cjs.executeProviderCall.call(void 0, {
668
798
  executor,
@@ -682,7 +812,11 @@ async function runPipeline(anthropicBody, plan) {
682
812
  },
683
813
  fetchFn: (url, headers, body) => {
684
814
  console.info(`[ProviderProxy:anthropic] -> ${url} model=${resolvedModel} stream=${isStream}`);
685
- return fetch(url, { method: "POST", headers, body: JSON.stringify(body) }).then((r) => {
815
+ return _chunkS6JGLF3Gcjs.fetchUpstream.call(void 0,
816
+ url,
817
+ { method: "POST", headers, body: JSON.stringify(body) },
818
+ { providerId: proxyProviderId(plan), accountId: proxyAccountId }
819
+ ).then((r) => {
686
820
  rawStatus = r.status;
687
821
  return r;
688
822
  });
@@ -691,29 +825,95 @@ async function runPipeline(anthropicBody, plan) {
691
825
  });
692
826
  return { response, rawStatus };
693
827
  }
694
- async function runSubscriptionSameFormatFetch(rawBody, plan) {
828
+ async function runSubscriptionSameFormatFetch(rawBody, plan, reportSelection, options = {}) {
829
+ let proxyAccountId;
830
+ let remappedModel;
695
831
  const headers = { "content-type": "application/json" };
696
832
  await plan.auth.applyHeaders(headers, {
697
833
  upstreamUrl: plan.upstreamUrl,
698
- model: plan.resolvedModel
834
+ model: plan.resolvedModel,
835
+ sessionKey: plan.sessionKey,
836
+ reportSelection: (accountId, isActive, remapped) => {
837
+ proxyAccountId = accountId;
838
+ remappedModel = remapped;
839
+ _optionalChain([reportSelection, 'optionalCall', _13 => _13(accountId, isActive, remapped)]);
840
+ }
699
841
  });
842
+ if (plan.isSubscription && plan.transformerProvider.name === "claude") {
843
+ _chunk6RPZADX3cjs.applyFingerprint.call(void 0,
844
+ _chunkRPII3E6Zcjs.getSharedIdentityStore.call(void 0, ),
845
+ headers,
846
+ plan.transformerProvider.name,
847
+ proxyAccountId,
848
+ options.callerIdentity
849
+ );
850
+ }
851
+ const applyRemap = remappedModel !== void 0 && outboundRemapApplies(plan);
852
+ const outboundBody = applyRemap ? rewriteBodyModel(rawBody, remappedModel) : rawBody;
853
+ const outboundModel = applyRemap ? remappedModel : plan.resolvedModel;
700
854
  console.info(
701
- `[ProviderProxy:anthropic] (subscription same-format) -> ${plan.upstreamUrl} model=${plan.resolvedModel} stream=${plan.isStream}`
855
+ `[ProviderProxy:anthropic] (subscription same-format) -> ${plan.upstreamUrl} model=${outboundModel} stream=${plan.isStream}`
856
+ );
857
+ const response = await _chunkS6JGLF3Gcjs.fetchUpstream.call(void 0,
858
+ plan.upstreamUrl,
859
+ { method: "POST", headers, body: outboundBody },
860
+ { providerId: proxyProviderId(plan), accountId: proxyAccountId }
702
861
  );
703
- const response = await fetch(plan.upstreamUrl, { method: "POST", headers, body: rawBody });
704
862
  return { response, rawStatus: response.status };
705
863
  }
706
- async function runSubscriptionAttemptWith401Retry(anthropicBody, relayBody, plan) {
707
- const runOnce = () => plan.sameFormat ? runSubscriptionSameFormatFetch(relayBody, plan) : runPipeline(anthropicBody, plan);
864
+ function outboundRemapApplies(plan) {
865
+ return plan.isSubscription && plan.transformerProvider.name === "claude";
866
+ }
867
+ function rewriteBodyModel(rawBody, model) {
868
+ try {
869
+ const parsed = JSON.parse(rawBody);
870
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return rawBody;
871
+ parsed.model = model;
872
+ return JSON.stringify(parsed);
873
+ } catch (e7) {
874
+ return rawBody;
875
+ }
876
+ }
877
+ async function runSubscriptionAttemptWith401Retry(anthropicBody, relayBody, plan, options = {}) {
878
+ let selectedAccountId;
879
+ const reportSelection = (accountId) => {
880
+ selectedAccountId = accountId;
881
+ };
882
+ const runOnce = () => plan.sameFormat ? runSubscriptionSameFormatFetch(relayBody, plan, reportSelection, options) : runPipeline(anthropicBody, plan, reportSelection);
708
883
  const first = await runOnce();
709
- if (first.rawStatus !== 401) return first;
710
- const refreshed = await _optionalChain([plan, 'access', _12 => _12.auth, 'access', _13 => _13.onUnauthorized, 'optionalCall', _14 => _14()]);
711
- if (!refreshed) {
712
- console.warn("[ProviderProxy:anthropic] 401 not recoverable (onUnauthorized returned false)");
713
- return first;
884
+ let result = first;
885
+ if (first.rawStatus === 401) {
886
+ const refreshed = await _optionalChain([plan, 'access', _14 => _14.auth, 'access', _15 => _15.onUnauthorized, 'optionalCall', _16 => _16(plan.sessionKey)]);
887
+ if (refreshed) {
888
+ console.info("[ProviderProxy:anthropic] 401 \u2192 token refreshed; retrying once");
889
+ result = await runOnce();
890
+ } else {
891
+ console.warn("[ProviderProxy:anthropic] 401 not recoverable (onUnauthorized returned false)");
892
+ }
714
893
  }
715
- console.info("[ProviderProxy:anthropic] 401 \u2192 token refreshed; retrying once");
716
- return runOnce();
894
+ await markSubscriptionHealth(plan, selectedAccountId, result);
895
+ return result;
896
+ }
897
+ async function readBoundedBody(response, max = 2048) {
898
+ try {
899
+ const text = await response.clone().text();
900
+ return text.slice(0, max);
901
+ } catch (e8) {
902
+ return void 0;
903
+ }
904
+ }
905
+ async function markSubscriptionHealth(plan, selectedAccountId, result) {
906
+ if (!plan.isSubscription || selectedAccountId === void 0) return;
907
+ const providerId = plan.transformerProvider.name;
908
+ const status = result.rawStatus;
909
+ const { resetHeaderSeconds, retryAfterSeconds } = _chunkVQY5W4YWcjs.resolveResetSeconds.call(void 0, providerId, result.response.headers);
910
+ const bodyText = status === 403 ? await readBoundedBody(result.response) : void 0;
911
+ _chunkVQY5W4YWcjs.getSharedAccountHealth.call(void 0, ).recordUpstreamOutcome(providerId, selectedAccountId, {
912
+ status,
913
+ resetHeaderSeconds,
914
+ retryAfterSeconds,
915
+ bodyText
916
+ });
717
917
  }
718
918
  function isFallbackEligibleStatus(rawStatus) {
719
919
  return rawStatus === null || rawStatus >= 500 || rawStatus === 429;
@@ -726,11 +926,11 @@ function breakerOutcome(rawStatus) {
726
926
  function recordBreakerOutcome(profile, modelId, rawStatus) {
727
927
  const outcome = breakerOutcome(rawStatus);
728
928
  if (outcome === "neutral") return;
729
- _optionalChain([profile, 'optionalAccess', _15 => _15.recordModelOutcome, 'optionalCall', _16 => _16(modelId, outcome === "success")]);
929
+ _optionalChain([profile, 'optionalAccess', _17 => _17.recordModelOutcome, 'optionalCall', _18 => _18(modelId, outcome === "success")]);
730
930
  }
731
- async function runSubscriptionAttemptOutcome(anthropicBody, relayBody, plan) {
931
+ async function runSubscriptionAttemptOutcome(anthropicBody, relayBody, plan, options = {}) {
732
932
  try {
733
- return { kind: "result", result: await runSubscriptionAttemptWith401Retry(anthropicBody, relayBody, plan) };
933
+ return { kind: "result", result: await runSubscriptionAttemptWith401Retry(anthropicBody, relayBody, plan, options) };
734
934
  } catch (error) {
735
935
  return { kind: "thrown", error };
736
936
  }
@@ -742,11 +942,11 @@ function settleOutcome(outcome) {
742
942
  if (outcome.kind === "thrown") throw outcome.error;
743
943
  return outcome.result;
744
944
  }
745
- async function runPipelineWithSubscriptionRetry(anthropicBody, rawBody, initialPlan, route, deps) {
945
+ async function runPipelineWithSubscriptionRetry(anthropicBody, rawBody, initialPlan, route, deps, options = {}) {
746
946
  const profile = route.subscriptionProfile;
747
947
  const scenario = initialPlan.scenario;
748
- if (!_optionalChain([profile, 'optionalAccess', _17 => _17.nextFallback]) || scenario === void 0) {
749
- const loneOutcome = await runSubscriptionAttemptOutcome(anthropicBody, rawBody, initialPlan);
948
+ if (!_optionalChain([profile, 'optionalAccess', _19 => _19.nextFallback]) || scenario === void 0) {
949
+ const loneOutcome = await runSubscriptionAttemptOutcome(anthropicBody, rawBody, initialPlan, options);
750
950
  recordBreakerOutcome(profile, initialPlan.resolvedModel, outcomeStatus(loneOutcome));
751
951
  return settleOutcome(loneOutcome);
752
952
  }
@@ -757,7 +957,7 @@ async function runPipelineWithSubscriptionRetry(anthropicBody, rawBody, initialP
757
957
  if (profile.allowModel && !profile.allowModel(initialPlan.resolvedModel)) {
758
958
  attempted.push(initialPlan.resolvedModel);
759
959
  const firstAdmitting = profile.nextFallback(scenario, attempted, route.subscriptionConfig);
760
- const gatedPlan = firstAdmitting ? buildSubscriptionIterationPlan(profile, route, deps, firstAdmitting.modelId, initialPlan.isStream, scenario) : null;
960
+ const gatedPlan = firstAdmitting ? buildSubscriptionIterationPlan(profile, route, deps, firstAdmitting.modelId, initialPlan.isStream, scenario, initialPlan.sessionKey) : null;
761
961
  if (firstAdmitting && gatedPlan) {
762
962
  console.warn(
763
963
  `[ProviderProxy:anthropic] subscription primary ${initialPlan.resolvedModel} circuit open -> first admitting fallback ${firstAdmitting.modelId}`
@@ -772,7 +972,7 @@ async function runPipelineWithSubscriptionRetry(anthropicBody, rawBody, initialP
772
972
  );
773
973
  }
774
974
  }
775
- let outcome = await runSubscriptionAttemptOutcome(firstBodyObj, firstRelayBody, plan);
975
+ let outcome = await runSubscriptionAttemptOutcome(firstBodyObj, firstRelayBody, plan, options);
776
976
  recordBreakerOutcome(profile, plan.resolvedModel, outcomeStatus(outcome));
777
977
  if (!attempted.includes(plan.resolvedModel)) attempted.push(plan.resolvedModel);
778
978
  while (attempted.length < MAX_FALLBACK_ATTEMPTS) {
@@ -785,7 +985,8 @@ async function runPipelineWithSubscriptionRetry(anthropicBody, rawBody, initialP
785
985
  deps,
786
986
  next.modelId,
787
987
  plan.isStream,
788
- scenario
988
+ scenario,
989
+ initialPlan.sessionKey
789
990
  );
790
991
  if (!nextPlan) return settleOutcome(outcome);
791
992
  const sinceLabel = outcome.kind === "thrown" ? "thrown error" : `status ${String(outcome.result.rawStatus)}`;
@@ -796,7 +997,7 @@ async function runPipelineWithSubscriptionRetry(anthropicBody, rawBody, initialP
796
997
  const fallbackRelayBody = nextPlan.sameFormat ? JSON.stringify(fallbackBodyObj) : rawBody;
797
998
  plan = nextPlan;
798
999
  attempted.push(next.modelId);
799
- outcome = await runSubscriptionAttemptOutcome(fallbackBodyObj, fallbackRelayBody, plan);
1000
+ outcome = await runSubscriptionAttemptOutcome(fallbackBodyObj, fallbackRelayBody, plan, options);
800
1001
  recordBreakerOutcome(profile, plan.resolvedModel, outcomeStatus(outcome));
801
1002
  }
802
1003
  return settleOutcome(outcome);
@@ -808,7 +1009,7 @@ async function handleAnthropicMessagesByo(res, rawBody, route, deps, options = {
808
1009
  let anthropicBody;
809
1010
  try {
810
1011
  anthropicBody = JSON.parse(rawBody);
811
- } catch (e5) {
1012
+ } catch (e9) {
812
1013
  writeError(res, 400, "Invalid JSON in request body");
813
1014
  return;
814
1015
  }
@@ -819,13 +1020,16 @@ async function handleAnthropicMessagesByo(res, rawBody, route, deps, options = {
819
1020
  const plan = route.authMode === "subscription" ? await buildSubscriptionPlan(res, route, deps, anthropicBody, resolvedModel, isStream) : await buildByoPlan(res, route, deps, resolvedModel, isStream);
820
1021
  if (!plan) return;
821
1022
  anthropicBody.model = plan.resolvedModel;
822
- const providerResponse = route.authMode === "subscription" ? await runPipelineWithSubscriptionRetry(anthropicBody, rawBody, plan, route, deps) : await runPipelineWithPoolReporting(anthropicBody, rawBody, plan, options);
823
- const bodyText = await relayResponse(res, providerResponse.response, isStream);
1023
+ const providerResponse = route.authMode === "subscription" ? await runPipelineWithSubscriptionRetry(anthropicBody, rawBody, plan, route, deps, options) : await runPipelineWithPoolReporting(anthropicBody, rawBody, plan, options);
1024
+ const bodyText = await relayResponse(res, providerResponse.response, isStream, route.requestedModel);
824
1025
  if (bodyText && deps.usageRecorder) {
825
1026
  recordAnthropicNonStreamUsage(deps.usageRecorder, bodyText, {
826
1027
  sessionId: route.sessionId,
827
1028
  providerId: _nullishCoalesce(route.providerId, () => ( "anthropic")),
828
- model: plan.resolvedModel
1029
+ model: plan.resolvedModel,
1030
+ apiKeyId: _nullishCoalesce(route.apiKeyId, () => ( null)),
1031
+ // request-audit-log: correlate this request's tokens/cost to its audit record.
1032
+ auditResponse: res
829
1033
  });
830
1034
  }
831
1035
  } catch (err) {
@@ -850,7 +1054,7 @@ async function buildByoPlan(res, route, deps, resolvedModel, isStream) {
850
1054
  writeError(res, 502, "API key not configured");
851
1055
  return null;
852
1056
  }
853
- const auth = _nullishCoalesce(route.auth, () => ( new (0, _chunkLKZJEL6Ecjs.LlmConfigProviderAuth)({
1057
+ const auth = _nullishCoalesce(route.auth, () => ( new (0, _chunkQ27JY5RGcjs.LlmConfigProviderAuth)({
854
1058
  provider,
855
1059
  apiKey,
856
1060
  apiKeyPool: _nullishCoalesce(deps.apiKeyPool, () => ( null)),
@@ -878,17 +1082,17 @@ async function buildByoPlan(res, route, deps, resolvedModel, isStream) {
878
1082
  isSubscription: false,
879
1083
  provider,
880
1084
  apiKey,
881
- extendedContextEnabled: _nullishCoalesce(_optionalChain([route, 'access', _18 => _18.anthropicSdkHints, 'optionalAccess', _19 => _19.extendedContext, 'optionalAccess', _20 => _20.enabled]), () => ( false))
1085
+ extendedContextEnabled: _nullishCoalesce(_optionalChain([route, 'access', _20 => _20.anthropicSdkHints, 'optionalAccess', _21 => _21.extendedContext, 'optionalAccess', _22 => _22.enabled]), () => ( false))
882
1086
  };
883
1087
  }
884
- async function runSameFormatFetch(rawBody, plan, options, keyOverride) {
1088
+ async function runSameFormatFetch(bodyToSend, plan, options, keyOverride) {
885
1089
  const { provider, apiKey, resolvedModel, isStream, extendedContextEnabled } = plan;
886
1090
  if (!provider) {
887
1091
  throw new Error("[ProviderProxy:anthropic] same-format BYO path requires a provider row");
888
1092
  }
889
1093
  const effectiveKey = _nullishCoalesce(_nullishCoalesce(keyOverride, () => ( apiKey)), () => ( ""));
890
- const headers = _chunkLKZJEL6Ecjs.getProviderHeaders.call(void 0, provider, effectiveKey);
891
- const callerBeta = _optionalChain([options, 'access', _21 => _21.callerAnthropicBeta, 'optionalAccess', _22 => _22.trim, 'call', _23 => _23()]);
1094
+ const headers = _chunkQ27JY5RGcjs.getProviderHeaders.call(void 0, provider, effectiveKey);
1095
+ const callerBeta = _optionalChain([options, 'access', _23 => _23.callerAnthropicBeta, 'optionalAccess', _24 => _24.trim, 'call', _25 => _25()]);
892
1096
  if (callerBeta) {
893
1097
  const existing = _nullishCoalesce(headers["anthropic-beta"], () => ( headers["Anthropic-Beta"]));
894
1098
  const parts = new Set(
@@ -902,14 +1106,29 @@ async function runSameFormatFetch(rawBody, plan, options, keyOverride) {
902
1106
  _chunkGBHYAGX3cjs.injectExtendedContextBeta.call(void 0, headers, resolvedModel, _nullishCoalesce(extendedContextEnabled, () => ( false)));
903
1107
  const url = _chunkA2YMUCBTcjs.buildProviderApiUrl.call(void 0, provider, { model: resolvedModel, stream: isStream });
904
1108
  console.info(`[ProviderProxy:anthropic] (same-format) -> ${url} model=${resolvedModel} stream=${isStream}`);
905
- const response = await fetch(url, { method: "POST", headers, body: rawBody });
1109
+ const response = await _chunkS6JGLF3Gcjs.fetchUpstream.call(void 0,
1110
+ url,
1111
+ { method: "POST", headers, body: bodyToSend },
1112
+ { providerId: "byo" }
1113
+ );
906
1114
  return { response, rawStatus: response.status };
907
1115
  }
1116
+ function resolveSameFormatBody(anthropicBody, rawBody, plan) {
1117
+ let originalModel;
1118
+ try {
1119
+ const m = JSON.parse(rawBody).model;
1120
+ originalModel = typeof m === "string" ? m : void 0;
1121
+ } catch (e10) {
1122
+ originalModel = void 0;
1123
+ }
1124
+ return plan.resolvedModel !== originalModel ? JSON.stringify(anthropicBody) : rawBody;
1125
+ }
908
1126
  async function runPipelineWithPoolReporting(anthropicBody, rawBody, plan, options) {
909
- const runOnce = (keyOverride) => plan.sameFormat ? runSameFormatFetch(rawBody, plan, options, keyOverride) : runPipeline(anthropicBody, plan);
1127
+ const sameFormatBody = plan.sameFormat ? resolveSameFormatBody(anthropicBody, rawBody, plan) : rawBody;
1128
+ const runOnce = (keyOverride) => plan.sameFormat ? runSameFormatFetch(sameFormatBody, plan, options, keyOverride) : runPipeline(anthropicBody, plan);
910
1129
  const first = await runOnce();
911
- const outcome = await _optionalChain([plan, 'access', _24 => _24.auth, 'access', _25 => _25.onResult, 'optionalCall', _26 => _26(first.rawStatus)]);
912
- if (_optionalChain([outcome, 'optionalAccess', _27 => _27.rebound])) {
1130
+ const outcome = await _optionalChain([plan, 'access', _26 => _26.auth, 'access', _27 => _27.onResult, 'optionalCall', _28 => _28(first.rawStatus)]);
1131
+ if (_optionalChain([outcome, 'optionalAccess', _29 => _29.rebound])) {
913
1132
  console.info(
914
1133
  "[ProviderProxy:anthropic] pool re-bound key after status",
915
1134
  first.rawStatus,
@@ -930,7 +1149,8 @@ async function handleAnthropicMessagesRequest(req, res, route, deps) {
930
1149
  const rawBody = await readBody(req);
931
1150
  const callerBetaRaw = req.headers["anthropic-beta"];
932
1151
  const callerAnthropicBeta = Array.isArray(callerBetaRaw) ? callerBetaRaw.join(",") : callerBetaRaw;
933
- await handleAnthropicMessagesByo(res, rawBody, route, deps, { callerAnthropicBeta });
1152
+ const callerIdentity = _chunk6RPZADX3cjs.captureCallerIdentity.call(void 0, _chunkRPII3E6Zcjs.getSharedIdentityStore.call(void 0, ), req.headers);
1153
+ await handleAnthropicMessagesByo(res, rawBody, route, deps, { callerAnthropicBeta, callerIdentity });
934
1154
  return;
935
1155
  }
936
1156
  const hints = route.anthropicSdkHints;
@@ -992,12 +1212,13 @@ function recordGeminiNonStreamUsage(recorder, bodyText, attribution) {
992
1212
  sessionId: attribution.sessionId,
993
1213
  providerId: attribution.providerId,
994
1214
  model: attribution.model,
995
- apiKeyId: null,
1215
+ apiKeyId: attribution.apiKeyId,
1216
+ auditResponse: attribution.auditResponse,
996
1217
  engineOrigin: "codex-ingress",
997
1218
  usage: tapped,
998
1219
  rawUsage: parsed.usageMetadata
999
1220
  });
1000
- } catch (e6) {
1221
+ } catch (e11) {
1001
1222
  }
1002
1223
  }
1003
1224
 
@@ -1006,14 +1227,14 @@ var GENERATE_CONTENT_ACTION = ":generateContent";
1006
1227
  var STREAM_GENERATE_CONTENT_ACTION = ":streamGenerateContent";
1007
1228
  function isGeminiGenerateContentRequest(method, url) {
1008
1229
  if (method !== "POST" || !url) return false;
1009
- const path = _nullishCoalesce(_optionalChain([url, 'access', _28 => _28.split, 'call', _29 => _29("?"), 'access', _30 => _30[0], 'optionalAccess', _31 => _31.replace, 'call', _32 => _32(/\/+$/, "")]), () => ( ""));
1230
+ const path = _nullishCoalesce(_optionalChain([url, 'access', _30 => _30.split, 'call', _31 => _31("?"), 'access', _32 => _32[0], 'optionalAccess', _33 => _33.replace, 'call', _34 => _34(/\/+$/, "")]), () => ( ""));
1010
1231
  const lastSegment = _nullishCoalesce(path.split("/").pop(), () => ( ""));
1011
1232
  return lastSegment.includes(STREAM_GENERATE_CONTENT_ACTION) || lastSegment.includes(GENERATE_CONTENT_ACTION);
1012
1233
  }
1013
1234
  function isGeminiStreamRequest(url) {
1014
1235
  if (!url) return false;
1015
1236
  const [path, query = ""] = url.split("?");
1016
- const lastSegment = _nullishCoalesce((_nullishCoalesce(_optionalChain([path, 'optionalAccess', _33 => _33.replace, 'call', _34 => _34(/\/+$/, "")]), () => ( ""))).split("/").pop(), () => ( ""));
1237
+ const lastSegment = _nullishCoalesce((_nullishCoalesce(_optionalChain([path, 'optionalAccess', _35 => _35.replace, 'call', _36 => _36(/\/+$/, "")]), () => ( ""))).split("/").pop(), () => ( ""));
1017
1238
  if (lastSegment.includes(STREAM_GENERATE_CONTENT_ACTION)) return true;
1018
1239
  return /(^|&)alt=sse(&|$)/.test(query);
1019
1240
  }
@@ -1021,7 +1242,7 @@ async function handleGeminiGenerateContentRequest(res, rawBody, url, route, deps
1021
1242
  let geminiBody;
1022
1243
  try {
1023
1244
  geminiBody = JSON.parse(rawBody);
1024
- } catch (e7) {
1245
+ } catch (e12) {
1025
1246
  writeError(res, 400, "Invalid JSON in request body");
1026
1247
  return;
1027
1248
  }
@@ -1042,7 +1263,10 @@ async function handleGeminiGenerateContentRequest(res, rawBody, url, route, deps
1042
1263
  recordGeminiNonStreamUsage(deps.usageRecorder, bodyText, {
1043
1264
  sessionId: route.sessionId,
1044
1265
  providerId: _nullishCoalesce(route.providerId, () => ( "gemini")),
1045
- model: resolvedModel
1266
+ model: resolvedModel,
1267
+ apiKeyId: _nullishCoalesce(route.apiKeyId, () => ( null)),
1268
+ // request-audit-log: correlate this request's tokens/cost to its audit record.
1269
+ auditResponse: res
1046
1270
  });
1047
1271
  }
1048
1272
  } catch (err) {
@@ -1067,7 +1291,7 @@ async function buildByoPlan2(res, route, deps, resolvedModel, isStream) {
1067
1291
  writeError(res, 502, "API key not configured");
1068
1292
  return null;
1069
1293
  }
1070
- const auth = _nullishCoalesce(route.auth, () => ( new (0, _chunkLKZJEL6Ecjs.LlmConfigProviderAuth)({
1294
+ const auth = _nullishCoalesce(route.auth, () => ( new (0, _chunkQ27JY5RGcjs.LlmConfigProviderAuth)({
1071
1295
  provider,
1072
1296
  apiKey,
1073
1297
  apiKeyPool: _nullishCoalesce(deps.apiKeyPool, () => ( null)),
@@ -1117,7 +1341,11 @@ async function runPipeline2(geminiBody, plan) {
1117
1341
  },
1118
1342
  fetchFn: (url, headers, body) => {
1119
1343
  console.log(`[ProviderProxy:gemini] -> ${url} model=${resolvedModel} stream=${isStream}`);
1120
- return fetch(url, { method: "POST", headers, body: JSON.stringify(body) }).then((r) => {
1344
+ return _chunkS6JGLF3Gcjs.fetchUpstream.call(void 0,
1345
+ url,
1346
+ { method: "POST", headers, body: JSON.stringify(body) },
1347
+ { providerId: "byo" }
1348
+ ).then((r) => {
1121
1349
  rawStatus = r.status;
1122
1350
  return r;
1123
1351
  });
@@ -1128,8 +1356,8 @@ async function runPipeline2(geminiBody, plan) {
1128
1356
  }
1129
1357
  async function runPipelineWithPoolReporting2(geminiBody, plan) {
1130
1358
  const first = await runPipeline2(geminiBody, plan);
1131
- const outcome = await _optionalChain([plan, 'access', _35 => _35.auth, 'access', _36 => _36.onResult, 'optionalCall', _37 => _37(first.rawStatus)]);
1132
- if (_optionalChain([outcome, 'optionalAccess', _38 => _38.rebound])) {
1359
+ const outcome = await _optionalChain([plan, 'access', _37 => _37.auth, 'access', _38 => _38.onResult, 'optionalCall', _39 => _39(first.rawStatus)]);
1360
+ if (_optionalChain([outcome, 'optionalAccess', _40 => _40.rebound])) {
1133
1361
  console.log(
1134
1362
  "[ProviderProxy:gemini] pool re-bound key after status",
1135
1363
  first.rawStatus,
@@ -1169,46 +1397,48 @@ function recordChatCompletionsNonStreamUsage(recorder, bodyText, attribution) {
1169
1397
  sessionId: attribution.sessionId,
1170
1398
  providerId: attribution.providerId,
1171
1399
  model: attribution.model,
1172
- apiKeyId: null,
1400
+ apiKeyId: attribution.apiKeyId,
1401
+ auditResponse: attribution.auditResponse,
1173
1402
  engineOrigin: "codex-ingress",
1174
1403
  usage: tapped,
1175
1404
  rawUsage: parsed.usage
1176
1405
  });
1177
- } catch (e8) {
1406
+ } catch (e13) {
1178
1407
  }
1179
1408
  }
1180
1409
 
1181
1410
  // src/provider-proxy/ingress/openaiChatIngress.ts
1182
1411
  function isOpenAIChatRequest(method, url) {
1183
1412
  if (method !== "POST" || !url) return false;
1184
- const path = _nullishCoalesce(_optionalChain([url, 'access', _39 => _39.split, 'call', _40 => _40("?"), 'access', _41 => _41[0], 'optionalAccess', _42 => _42.replace, 'call', _43 => _43(/\/+$/, "")]), () => ( ""));
1413
+ const path = _nullishCoalesce(_optionalChain([url, 'access', _41 => _41.split, 'call', _42 => _42("?"), 'access', _43 => _43[0], 'optionalAccess', _44 => _44.replace, 'call', _45 => _45(/\/+$/, "")]), () => ( ""));
1185
1414
  return path.endsWith("/chat/completions");
1186
1415
  }
1416
+ var CHAT_BRIDGE_SUBSCRIPTION_PROVIDERS = /* @__PURE__ */ new Set(["claude"]);
1417
+ var IDENTITY_ENDPOINT_TRANSFORMER = { name: "identity-openai-chat" };
1187
1418
  async function handleOpenAIChatRequest(res, rawBody, route, deps) {
1188
1419
  let chatBody;
1189
1420
  try {
1190
1421
  chatBody = JSON.parse(rawBody);
1191
- } catch (e9) {
1422
+ } catch (e14) {
1192
1423
  writeError(res, 400, "Invalid JSON in request body");
1193
1424
  return;
1194
1425
  }
1195
- if (route.authMode === "subscription") {
1196
- writeError(res, 502, "OpenAI Chat Completions ingress does not support subscription auth");
1197
- return;
1198
- }
1199
1426
  const isStream = chatBody.stream === true;
1200
1427
  const resolvedModel = route.model;
1201
1428
  chatBody.model = resolvedModel;
1202
1429
  try {
1203
- const plan = await buildByoPlan3(res, route, deps, resolvedModel, isStream);
1430
+ const plan = route.authMode === "subscription" ? await buildSubscriptionPlan2(res, route, deps, resolvedModel, isStream) : await buildByoPlan3(res, route, deps, resolvedModel, isStream);
1204
1431
  if (!plan) return;
1205
- const providerResponse = await runPipelineWithPoolReporting3(chatBody, plan);
1432
+ const providerResponse = plan.isSubscription ? await runPipelineWithSubscriptionRetry2(chatBody, plan) : await runPipelineWithPoolReporting3(chatBody, plan);
1206
1433
  const bodyText = await relayResponse(res, providerResponse.response, isStream);
1207
1434
  if (bodyText && deps.usageRecorder) {
1208
1435
  recordChatCompletionsNonStreamUsage(deps.usageRecorder, bodyText, {
1209
1436
  sessionId: route.sessionId,
1210
1437
  providerId: _nullishCoalesce(route.providerId, () => ( "openai")),
1211
- model: resolvedModel
1438
+ model: resolvedModel,
1439
+ apiKeyId: _nullishCoalesce(route.apiKeyId, () => ( null)),
1440
+ // request-audit-log: correlate this request's tokens/cost to its audit record.
1441
+ auditResponse: res
1212
1442
  });
1213
1443
  }
1214
1444
  } catch (err) {
@@ -1233,7 +1463,7 @@ async function buildByoPlan3(res, route, deps, resolvedModel, isStream) {
1233
1463
  writeError(res, 502, "API key not configured");
1234
1464
  return null;
1235
1465
  }
1236
- const auth = _nullishCoalesce(route.auth, () => ( new (0, _chunkLKZJEL6Ecjs.LlmConfigProviderAuth)({
1466
+ const auth = _nullishCoalesce(route.auth, () => ( new (0, _chunkQ27JY5RGcjs.LlmConfigProviderAuth)({
1237
1467
  provider,
1238
1468
  apiKey,
1239
1469
  apiKeyPool: _nullishCoalesce(deps.apiKeyPool, () => ( null)),
@@ -1255,14 +1485,67 @@ async function buildByoPlan3(res, route, deps, resolvedModel, isStream) {
1255
1485
  resolvedModel,
1256
1486
  isStream,
1257
1487
  resolveUrl: (config) => config.url instanceof URL ? config.url.toString() : byoUrl,
1258
- upstreamUrl: byoUrl
1488
+ upstreamUrl: byoUrl,
1489
+ proxyProviderId: "byo",
1490
+ isSubscription: false
1491
+ };
1492
+ }
1493
+ async function buildSubscriptionPlan2(res, route, deps, resolvedModel, isStream) {
1494
+ const profile = route.subscriptionProfile;
1495
+ if (!profile) {
1496
+ writeError(res, 502, "Subscription mode requires a subscription profile");
1497
+ return null;
1498
+ }
1499
+ const providerId = profile.authStrategy.providerId;
1500
+ if (!CHAT_BRIDGE_SUBSCRIPTION_PROVIDERS.has(providerId)) {
1501
+ writeError(
1502
+ res,
1503
+ 501,
1504
+ `the OpenAI-chat\u2192subscription bridge currently supports claude only; subscription provider '${providerId}' is not implemented on this endpoint yet (use the /v1/responses endpoint, a Claude subscription, or a BYO provider)`
1505
+ );
1506
+ return null;
1507
+ }
1508
+ const upstreamUrl = _optionalChain([profile, 'access', _46 => _46.resolveUpstreamUrl, 'optionalCall', _47 => _47(resolvedModel)]);
1509
+ if (!upstreamUrl) {
1510
+ writeError(res, 502, "Subscription profile is missing resolveUpstreamUrl");
1511
+ return null;
1512
+ }
1513
+ const auth = _nullishCoalesce(route.auth, () => ( new (0, _chunkY6OM7EV7cjs.SubscriptionAuthSource)(profile)));
1514
+ const chain = _chunkNYUNU75Acjs.resolveSubscriptionChain.call(void 0,
1515
+ profile,
1516
+ deps.llmConfig.getTransformerService(),
1517
+ IDENTITY_ENDPOINT_TRANSFORMER
1518
+ );
1519
+ const transformerProvider = {
1520
+ name: providerId,
1521
+ baseUrl: upstreamUrl,
1522
+ apiKey: "",
1523
+ models: [resolvedModel]
1524
+ };
1525
+ return {
1526
+ auth,
1527
+ chain,
1528
+ transformerProvider,
1529
+ resolvedModel,
1530
+ isStream,
1531
+ resolveUrl: (config) => config.url instanceof URL ? config.url.toString() : typeof config.url === "string" ? config.url : upstreamUrl,
1532
+ upstreamUrl,
1533
+ proxyProviderId: providerId,
1534
+ isSubscription: true
1259
1535
  };
1260
1536
  }
1261
1537
  async function runPipeline3(chatBody, plan) {
1262
1538
  const executor = getSharedExecutor();
1263
1539
  const { auth, chain, transformerProvider, resolvedModel, isStream, resolveUrl, upstreamUrl } = plan;
1540
+ let proxyAccountId;
1264
1541
  const authHeaders = {};
1265
- await auth.applyHeaders(authHeaders, { upstreamUrl, model: resolvedModel });
1542
+ await auth.applyHeaders(authHeaders, {
1543
+ upstreamUrl,
1544
+ model: resolvedModel,
1545
+ reportSelection: (accountId) => {
1546
+ proxyAccountId = accountId;
1547
+ }
1548
+ });
1266
1549
  let rawStatus = null;
1267
1550
  const { response } = await _chunkKUU2RNG6cjs.executeProviderCall.call(void 0, {
1268
1551
  executor,
@@ -1281,7 +1564,11 @@ async function runPipeline3(chatBody, plan) {
1281
1564
  },
1282
1565
  fetchFn: (url, headers, body) => {
1283
1566
  console.log(`[ProviderProxy:chat] -> ${url} model=${resolvedModel} stream=${isStream}`);
1284
- return fetch(url, { method: "POST", headers, body: JSON.stringify(body) }).then((r) => {
1567
+ return _chunkS6JGLF3Gcjs.fetchUpstream.call(void 0,
1568
+ url,
1569
+ { method: "POST", headers, body: JSON.stringify(body) },
1570
+ { providerId: plan.proxyProviderId, accountId: proxyAccountId }
1571
+ ).then((r) => {
1285
1572
  rawStatus = r.status;
1286
1573
  return r;
1287
1574
  });
@@ -1292,8 +1579,8 @@ async function runPipeline3(chatBody, plan) {
1292
1579
  }
1293
1580
  async function runPipelineWithPoolReporting3(chatBody, plan) {
1294
1581
  const first = await runPipeline3(chatBody, plan);
1295
- const outcome = await _optionalChain([plan, 'access', _44 => _44.auth, 'access', _45 => _45.onResult, 'optionalCall', _46 => _46(first.rawStatus)]);
1296
- if (_optionalChain([outcome, 'optionalAccess', _47 => _47.rebound])) {
1582
+ const outcome = await _optionalChain([plan, 'access', _48 => _48.auth, 'access', _49 => _49.onResult, 'optionalCall', _50 => _50(first.rawStatus)]);
1583
+ if (_optionalChain([outcome, 'optionalAccess', _51 => _51.rebound])) {
1297
1584
  console.log(
1298
1585
  "[ProviderProxy:chat] pool re-bound key after status",
1299
1586
  first.rawStatus,
@@ -1303,6 +1590,17 @@ async function runPipelineWithPoolReporting3(chatBody, plan) {
1303
1590
  }
1304
1591
  return first;
1305
1592
  }
1593
+ async function runPipelineWithSubscriptionRetry2(chatBody, plan) {
1594
+ const first = await runPipeline3(chatBody, plan);
1595
+ if (first.rawStatus !== 401) return first;
1596
+ const refreshed = await _optionalChain([plan, 'access', _52 => _52.auth, 'access', _53 => _53.onUnauthorized, 'optionalCall', _54 => _54()]);
1597
+ if (!refreshed) {
1598
+ console.warn("[ProviderProxy:chat] 401 not recoverable (onUnauthorized returned false)");
1599
+ return first;
1600
+ }
1601
+ console.log("[ProviderProxy:chat] 401 \u2192 token refreshed; retrying once");
1602
+ return runPipeline3(chatBody, plan);
1603
+ }
1306
1604
 
1307
1605
  // src/provider-proxy/usage/recordResponsesUsage.ts
1308
1606
  function readResponsesUsage(usage) {
@@ -1333,26 +1631,27 @@ function recordResponsesNonStreamUsage(recorder, bodyText, attribution) {
1333
1631
  sessionId: attribution.sessionId,
1334
1632
  providerId: attribution.providerId,
1335
1633
  model: attribution.model,
1336
- apiKeyId: null,
1634
+ apiKeyId: attribution.apiKeyId,
1635
+ auditResponse: attribution.auditResponse,
1337
1636
  engineOrigin: "codex-ingress",
1338
1637
  usage: tapped,
1339
1638
  rawUsage: parsed.usage
1340
1639
  });
1341
- } catch (e10) {
1640
+ } catch (e15) {
1342
1641
  }
1343
1642
  }
1344
1643
 
1345
1644
  // src/provider-proxy/ingress/openaiResponsesIngress.ts
1346
1645
  function isOpenAIResponsesRequest(method, url) {
1347
1646
  if (method !== "POST" || !url) return false;
1348
- const path = _nullishCoalesce(_optionalChain([url, 'access', _48 => _48.split, 'call', _49 => _49("?"), 'access', _50 => _50[0], 'optionalAccess', _51 => _51.replace, 'call', _52 => _52(/\/+$/, "")]), () => ( ""));
1647
+ const path = _nullishCoalesce(_optionalChain([url, 'access', _55 => _55.split, 'call', _56 => _56("?"), 'access', _57 => _57[0], 'optionalAccess', _58 => _58.replace, 'call', _59 => _59(/\/+$/, "")]), () => ( ""));
1349
1648
  return path.endsWith("/responses");
1350
1649
  }
1351
1650
  async function handleOpenAIResponsesRequest(res, rawBody, route, deps) {
1352
1651
  let responsesBody;
1353
1652
  try {
1354
1653
  responsesBody = JSON.parse(rawBody);
1355
- } catch (e11) {
1654
+ } catch (e16) {
1356
1655
  writeError(res, 400, "Invalid JSON in request body");
1357
1656
  return;
1358
1657
  }
@@ -1360,15 +1659,18 @@ async function handleOpenAIResponsesRequest(res, rawBody, route, deps) {
1360
1659
  const resolvedModel = route.model;
1361
1660
  responsesBody.model = resolvedModel;
1362
1661
  try {
1363
- const plan = route.authMode === "subscription" ? await buildSubscriptionPlan2(res, route, deps, resolvedModel, isStream) : await buildByoPlan4(res, route, deps, resolvedModel, isStream);
1662
+ const plan = route.authMode === "subscription" ? await buildSubscriptionPlan3(res, route, deps, resolvedModel, isStream) : await buildByoPlan4(res, route, deps, resolvedModel, isStream);
1364
1663
  if (!plan) return;
1365
- const providerResponse = route.authMode === "subscription" ? await runPipelineWithSubscriptionRetry2(responsesBody, plan) : await runPipelineWithPoolReporting4(responsesBody, plan);
1366
- const bodyText = await relayResponse(res, providerResponse.response, isStream);
1664
+ const providerResponse = route.authMode === "subscription" ? await runPipelineWithSubscriptionRetry3(responsesBody, plan) : await runPipelineWithPoolReporting4(responsesBody, plan);
1665
+ const bodyText = await relayResponse(res, providerResponse.response, isStream, route.requestedModel);
1367
1666
  if (bodyText && deps.usageRecorder) {
1368
1667
  recordResponsesNonStreamUsage(deps.usageRecorder, bodyText, {
1369
1668
  sessionId: route.sessionId,
1370
1669
  providerId: _nullishCoalesce(route.providerId, () => ( "codex")),
1371
- model: resolvedModel
1670
+ model: resolvedModel,
1671
+ apiKeyId: _nullishCoalesce(route.apiKeyId, () => ( null)),
1672
+ // request-audit-log: correlate this request's tokens/cost to its audit record.
1673
+ auditResponse: res
1372
1674
  });
1373
1675
  }
1374
1676
  } catch (err) {
@@ -1393,7 +1695,7 @@ async function buildByoPlan4(res, route, deps, resolvedModel, isStream) {
1393
1695
  writeError(res, 502, "API key not configured");
1394
1696
  return null;
1395
1697
  }
1396
- const auth = _nullishCoalesce(route.auth, () => ( new (0, _chunkLKZJEL6Ecjs.LlmConfigProviderAuth)({
1698
+ const auth = _nullishCoalesce(route.auth, () => ( new (0, _chunkQ27JY5RGcjs.LlmConfigProviderAuth)({
1397
1699
  provider,
1398
1700
  apiKey,
1399
1701
  apiKeyPool: _nullishCoalesce(deps.apiKeyPool, () => ( null)),
@@ -1415,21 +1717,22 @@ async function buildByoPlan4(res, route, deps, resolvedModel, isStream) {
1415
1717
  resolvedModel,
1416
1718
  isStream,
1417
1719
  resolveUrl: (config) => config.url instanceof URL ? config.url.toString() : byoUrl,
1418
- upstreamUrl: byoUrl
1720
+ upstreamUrl: byoUrl,
1721
+ proxyProviderId: "byo"
1419
1722
  };
1420
1723
  }
1421
- async function buildSubscriptionPlan2(res, route, deps, resolvedModel, isStream) {
1724
+ async function buildSubscriptionPlan3(res, route, deps, resolvedModel, isStream) {
1422
1725
  const profile = route.subscriptionProfile;
1423
1726
  if (!profile) {
1424
1727
  writeError(res, 502, "Subscription mode requires a codex subscription profile");
1425
1728
  return null;
1426
1729
  }
1427
- const upstreamUrl = _optionalChain([profile, 'access', _53 => _53.resolveUpstreamUrl, 'optionalCall', _54 => _54(resolvedModel)]);
1730
+ const upstreamUrl = _optionalChain([profile, 'access', _60 => _60.resolveUpstreamUrl, 'optionalCall', _61 => _61(resolvedModel)]);
1428
1731
  if (!upstreamUrl) {
1429
1732
  writeError(res, 502, "Subscription profile is missing resolveUpstreamUrl");
1430
1733
  return null;
1431
1734
  }
1432
- const auth = _nullishCoalesce(route.auth, () => ( new (0, _chunkN3V2J5ZOcjs.SubscriptionAuthSource)(profile)));
1735
+ const auth = _nullishCoalesce(route.auth, () => ( new (0, _chunkY6OM7EV7cjs.SubscriptionAuthSource)(profile)));
1433
1736
  const chain = _chunkNYUNU75Acjs.resolveSubscriptionChain.call(void 0,
1434
1737
  profile,
1435
1738
  deps.llmConfig.getTransformerService(),
@@ -1459,7 +1762,8 @@ async function buildSubscriptionPlan2(res, route, deps, resolvedModel, isStream)
1459
1762
  // stream vs non-stream colon-method URL in `config.url`); fall back to the
1460
1763
  // profile's `resolveUpstreamUrl` for non-Code-Assist subscriptions.
1461
1764
  resolveUrl: (config) => config.url instanceof URL ? config.url.toString() : typeof config.url === "string" ? config.url : upstreamUrl,
1462
- upstreamUrl
1765
+ upstreamUrl,
1766
+ proxyProviderId: profile.authStrategy.providerId
1463
1767
  };
1464
1768
  }
1465
1769
  async function resolveGeminiCodeAssistProject(profile) {
@@ -1476,8 +1780,15 @@ async function runPipeline4(responsesBody, plan) {
1476
1780
  const executor = getSharedExecutor();
1477
1781
  const endpointTransformer = getResponsesEndpointTransformer();
1478
1782
  const { auth, chain, transformerProvider, resolvedModel, isStream, resolveUrl, upstreamUrl } = plan;
1783
+ let proxyAccountId;
1479
1784
  const authHeaders = {};
1480
- await auth.applyHeaders(authHeaders, { upstreamUrl, model: resolvedModel });
1785
+ await auth.applyHeaders(authHeaders, {
1786
+ upstreamUrl,
1787
+ model: resolvedModel,
1788
+ reportSelection: (accountId) => {
1789
+ proxyAccountId = accountId;
1790
+ }
1791
+ });
1481
1792
  let rawStatus = null;
1482
1793
  const { response } = await _chunkKUU2RNG6cjs.executeProviderCall.call(void 0, {
1483
1794
  executor,
@@ -1497,7 +1808,11 @@ async function runPipeline4(responsesBody, plan) {
1497
1808
  },
1498
1809
  fetchFn: (url, headers, body) => {
1499
1810
  console.log(`[ProviderProxy:responses] -> ${url} model=${resolvedModel} stream=${isStream}`);
1500
- return fetch(url, { method: "POST", headers, body: JSON.stringify(body) }).then((r) => {
1811
+ return _chunkS6JGLF3Gcjs.fetchUpstream.call(void 0,
1812
+ url,
1813
+ { method: "POST", headers, body: JSON.stringify(body) },
1814
+ { providerId: plan.proxyProviderId, accountId: proxyAccountId }
1815
+ ).then((r) => {
1501
1816
  rawStatus = r.status;
1502
1817
  return r;
1503
1818
  });
@@ -1508,8 +1823,8 @@ async function runPipeline4(responsesBody, plan) {
1508
1823
  }
1509
1824
  async function runPipelineWithPoolReporting4(responsesBody, plan) {
1510
1825
  const first = await runPipeline4(responsesBody, plan);
1511
- const outcome = await _optionalChain([plan, 'access', _55 => _55.auth, 'access', _56 => _56.onResult, 'optionalCall', _57 => _57(first.rawStatus)]);
1512
- if (_optionalChain([outcome, 'optionalAccess', _58 => _58.rebound])) {
1826
+ const outcome = await _optionalChain([plan, 'access', _62 => _62.auth, 'access', _63 => _63.onResult, 'optionalCall', _64 => _64(first.rawStatus)]);
1827
+ if (_optionalChain([outcome, 'optionalAccess', _65 => _65.rebound])) {
1513
1828
  console.log(
1514
1829
  "[ProviderProxy:responses] pool re-bound key after status",
1515
1830
  first.rawStatus,
@@ -1519,10 +1834,10 @@ async function runPipelineWithPoolReporting4(responsesBody, plan) {
1519
1834
  }
1520
1835
  return first;
1521
1836
  }
1522
- async function runPipelineWithSubscriptionRetry2(responsesBody, plan) {
1837
+ async function runPipelineWithSubscriptionRetry3(responsesBody, plan) {
1523
1838
  const first = await runPipeline4(responsesBody, plan);
1524
1839
  if (first.rawStatus !== 401) return first;
1525
- const refreshed = await _optionalChain([plan, 'access', _59 => _59.auth, 'access', _60 => _60.onUnauthorized, 'optionalCall', _61 => _61()]);
1840
+ const refreshed = await _optionalChain([plan, 'access', _66 => _66.auth, 'access', _67 => _67.onUnauthorized, 'optionalCall', _68 => _68()]);
1526
1841
  if (!refreshed) {
1527
1842
  console.warn("[ProviderProxy:responses] 401 not recoverable (onUnauthorized returned false)");
1528
1843
  return first;
@@ -1544,7 +1859,7 @@ function resolveRouteToken(req) {
1544
1859
  if (fromAuth) return fromAuth;
1545
1860
  const googKey = req.headers["x-goog-api-key"];
1546
1861
  const value = Array.isArray(googKey) ? googKey[0] : googKey;
1547
- return _optionalChain([value, 'optionalAccess', _62 => _62.trim, 'call', _63 => _63()]) || void 0;
1862
+ return _optionalChain([value, 'optionalAccess', _69 => _69.trim, 'call', _70 => _70()]) || void 0;
1548
1863
  }
1549
1864
  async function routeRequest(req, res, routes, deps) {
1550
1865
  const token = resolveRouteToken(req);
@@ -1696,12 +2011,644 @@ function __resetProviderProxyForTests() {
1696
2011
  // src/outbound-api/OutboundApiServer.ts
1697
2012
 
1698
2013
  var _os = require('os');
2014
+ var _healthloggingtypes = require('@omnicross/contracts/health-logging-types');
2015
+
2016
+ // src/outbound-api/keyedMutex.ts
2017
+ var KeyedMutex = (_class3 = class {constructor() { _class3.prototype.__init4.call(this); }
2018
+ /** key → the tail of the pending-op chain (resolves when the last op frees). */
2019
+ __init4() {this.tails = /* @__PURE__ */ new Map()}
2020
+ /**
2021
+ * Run `fn` exclusively for `key`: it starts only after every previously
2022
+ * enqueued op for the SAME key has settled, and the next waiter starts only
2023
+ * after `fn` settles. Returns `fn`'s result (or rejection). Never lets one op's
2024
+ * failure wedge the queue (waiters proceed regardless).
2025
+ */
2026
+ async runExclusive(key, fn) {
2027
+ const prev = _nullishCoalesce(this.tails.get(key), () => ( Promise.resolve()));
2028
+ let release2;
2029
+ const gate = new Promise((resolve) => {
2030
+ release2 = resolve;
2031
+ });
2032
+ const chain = prev.then(() => gate);
2033
+ this.tails.set(key, chain);
2034
+ await prev.catch(() => void 0);
2035
+ try {
2036
+ return await fn();
2037
+ } finally {
2038
+ release2();
2039
+ if (this.tails.get(key) === chain) this.tails.delete(key);
2040
+ }
2041
+ }
2042
+ }, _class3);
1699
2043
 
1700
2044
  // src/outbound-api/outboundApiRouter.ts
1701
2045
  var _stream = require('stream');
1702
2046
 
2047
+ // src/pipeline/webhookEmit.ts
2048
+ var sink = null;
2049
+ function emitWebhookEvent(event) {
2050
+ const active = sink;
2051
+ if (!active) return;
2052
+ try {
2053
+ active(event);
2054
+ } catch (e17) {
2055
+ }
2056
+ }
2057
+
2058
+ // src/outbound-api/apiServerConfig.ts
2059
+ var _audittypes = require('@omnicross/contracts/audit-types');
2060
+ var _billingtypes = require('@omnicross/contracts/billing-types');
2061
+
2062
+
2063
+
2064
+ var _webhooktypes = require('@omnicross/contracts/webhook-types');
2065
+ var OUTBOUND_API_SERVER_CONFIG_KEY = "outboundApiServer.config";
2066
+ var DEFAULT_USER_MESSAGE_QUEUE = {
2067
+ enabled: false,
2068
+ delayMs: 200,
2069
+ waitTimeoutMs: 6e4
2070
+ };
2071
+ var DEFAULT_CONCURRENCY_QUEUE = {
2072
+ maxQueueSizeFactor: 2,
2073
+ minQueueSize: 4,
2074
+ waitTimeoutMs: 6e4
2075
+ };
2076
+ var DEFAULT_ACCOUNT_HEALTH = {
2077
+ overloadCooldownEnabled: true,
2078
+ overloadCooldownMs: 10 * 6e4
2079
+ };
2080
+ function normalizeAccountHealth(raw) {
2081
+ const ah = _optionalChain([raw, 'optionalAccess', _71 => _71.accountHealth]);
2082
+ return {
2083
+ overloadCooldownEnabled: _optionalChain([ah, 'optionalAccess', _72 => _72.overloadCooldownEnabled]) !== false,
2084
+ overloadCooldownMs: clampNumber(
2085
+ _optionalChain([ah, 'optionalAccess', _73 => _73.overloadCooldownMs]),
2086
+ 6e4,
2087
+ 36e5,
2088
+ DEFAULT_ACCOUNT_HEALTH.overloadCooldownMs
2089
+ )
2090
+ };
2091
+ }
2092
+ var DEFAULT_ACCOUNT_PROBE = {
2093
+ enabled: false,
2094
+ intervalMs: 15 * 6e4,
2095
+ onlyMultiAccount: true,
2096
+ timeoutMs: 5e3,
2097
+ historySize: 10,
2098
+ staggerMs: 500
2099
+ };
2100
+ function normalizeAccountProbe(raw) {
2101
+ const ap = _optionalChain([raw, 'optionalAccess', _74 => _74.accountProbe]);
2102
+ return {
2103
+ enabled: _optionalChain([ap, 'optionalAccess', _75 => _75.enabled]) === true,
2104
+ intervalMs: clampNumber(_optionalChain([ap, 'optionalAccess', _76 => _76.intervalMs]), 6e4, 864e5, DEFAULT_ACCOUNT_PROBE.intervalMs),
2105
+ onlyMultiAccount: _optionalChain([ap, 'optionalAccess', _77 => _77.onlyMultiAccount]) !== false,
2106
+ timeoutMs: clampNumber(_optionalChain([ap, 'optionalAccess', _78 => _78.timeoutMs]), 1e3, 6e4, DEFAULT_ACCOUNT_PROBE.timeoutMs),
2107
+ historySize: Math.trunc(
2108
+ clampNumber(_optionalChain([ap, 'optionalAccess', _79 => _79.historySize]), 1, 200, DEFAULT_ACCOUNT_PROBE.historySize)
2109
+ ),
2110
+ staggerMs: clampNumber(_optionalChain([ap, 'optionalAccess', _80 => _80.staggerMs]), 0, 6e4, DEFAULT_ACCOUNT_PROBE.staggerMs)
2111
+ };
2112
+ }
2113
+ function normalizeAudit(raw) {
2114
+ const a = _optionalChain([raw, 'optionalAccess', _81 => _81.audit]);
2115
+ return {
2116
+ enabled: _optionalChain([a, 'optionalAccess', _82 => _82.enabled]) === true,
2117
+ captureBodies: _optionalChain([a, 'optionalAccess', _83 => _83.captureBodies]) === true,
2118
+ maxBodyBytes: Math.trunc(
2119
+ clampNumber(_optionalChain([a, 'optionalAccess', _84 => _84.maxBodyBytes]), 256, 1048576, _audittypes.DEFAULT_AUDIT_CONFIG.maxBodyBytes)
2120
+ ),
2121
+ retentionDays: Math.trunc(
2122
+ clampNumber(_optionalChain([a, 'optionalAccess', _85 => _85.retentionDays]), 1, 365, _audittypes.DEFAULT_AUDIT_CONFIG.retentionDays)
2123
+ ),
2124
+ trustForwardedFor: _optionalChain([a, 'optionalAccess', _86 => _86.trustForwardedFor]) === true
2125
+ };
2126
+ }
2127
+ function normalizeBilling(raw) {
2128
+ const b = _optionalChain([raw, 'optionalAccess', _87 => _87.billing]);
2129
+ const config = {
2130
+ enabled: _optionalChain([b, 'optionalAccess', _88 => _88.enabled]) === true,
2131
+ maxRetryAgeMs: Math.trunc(
2132
+ clampNumber(_optionalChain([b, 'optionalAccess', _89 => _89.maxRetryAgeMs]), 6e4, 2592e6, _billingtypes.DEFAULT_BILLING_CONFIG.maxRetryAgeMs)
2133
+ )
2134
+ };
2135
+ if (typeof _optionalChain([b, 'optionalAccess', _90 => _90.endpoint]) === "string" && b.endpoint.trim()) config.endpoint = b.endpoint.trim();
2136
+ if (typeof _optionalChain([b, 'optionalAccess', _91 => _91.secret]) === "string" && b.secret.length > 0) config.secret = b.secret;
2137
+ return config;
2138
+ }
2139
+ var DEFAULT_FINGERPRINT = { enabled: false };
2140
+ function normalizeFingerprint(raw) {
2141
+ const f = _optionalChain([raw, 'optionalAccess', _92 => _92.fingerprint]);
2142
+ const out = { enabled: _optionalChain([f, 'optionalAccess', _93 => _93.enabled]) === true };
2143
+ if (typeof _optionalChain([f, 'optionalAccess', _94 => _94.ua]) === "string" && f.ua.trim().length > 0) out.ua = f.ua.trim();
2144
+ return out;
2145
+ }
2146
+ function normalizeVoucher(raw) {
2147
+ return { enabled: _optionalChain([raw, 'optionalAccess', _95 => _95.voucher, 'optionalAccess', _96 => _96.enabled]) === true };
2148
+ }
2149
+ var PROXY_TYPES = ["http", "https", "socks5"];
2150
+ function normalizeProxyConfig(raw) {
2151
+ if (!raw || typeof raw !== "object") return void 0;
2152
+ const r = raw;
2153
+ if (typeof r["url"] === "string" && r["url"].trim().length > 0) {
2154
+ return { url: r["url"].trim() };
2155
+ }
2156
+ const type = r["type"];
2157
+ const host = r["host"];
2158
+ const port = r["port"];
2159
+ if (typeof type === "string" && PROXY_TYPES.includes(type) && typeof host === "string" && host.trim().length > 0 && typeof port === "number" && Number.isFinite(port) && port >= 1 && port <= 65535) {
2160
+ const out = {
2161
+ type,
2162
+ host: host.trim(),
2163
+ port: Math.trunc(port)
2164
+ };
2165
+ if (typeof r["username"] === "string" && r["username"].length > 0) out.username = r["username"];
2166
+ if (typeof r["password"] === "string" && r["password"].length > 0) out.password = r["password"];
2167
+ return out;
2168
+ }
2169
+ return void 0;
2170
+ }
2171
+ function normalizeProxySegment(raw) {
2172
+ if (!raw || typeof raw !== "object") return void 0;
2173
+ const r = raw;
2174
+ const out = {};
2175
+ const global = normalizeProxyConfig(r["global"]);
2176
+ if (global) out.global = global;
2177
+ if (r["byProvider"] && typeof r["byProvider"] === "object") {
2178
+ const byProvider = {};
2179
+ for (const [key, value] of Object.entries(r["byProvider"])) {
2180
+ if (!key.trim()) continue;
2181
+ const cfg = normalizeProxyConfig(value);
2182
+ if (cfg) byProvider[key] = cfg;
2183
+ }
2184
+ if (Object.keys(byProvider).length > 0) out.byProvider = byProvider;
2185
+ }
2186
+ return out.global || out.byProvider ? out : void 0;
2187
+ }
2188
+ function normalizeWebhookDestination(raw) {
2189
+ if (!raw || typeof raw !== "object") return void 0;
2190
+ const r = raw;
2191
+ const id = typeof r["id"] === "string" ? r["id"].trim() : "";
2192
+ const url = typeof r["url"] === "string" ? r["url"].trim() : "";
2193
+ const type = r["type"];
2194
+ if (!id || !url || typeof type !== "string" || !_webhooktypes.WEBHOOK_DESTINATION_TYPES.includes(type)) {
2195
+ return void 0;
2196
+ }
2197
+ const out = {
2198
+ id,
2199
+ type,
2200
+ url,
2201
+ enabled: r["enabled"] !== false
2202
+ };
2203
+ if (typeof r["secret"] === "string" && r["secret"].length > 0) out.secret = r["secret"];
2204
+ if (Array.isArray(r["events"])) {
2205
+ const events = r["events"].filter(
2206
+ (e) => typeof e === "string" && _webhooktypes.WEBHOOK_EVENT_KINDS.includes(e)
2207
+ );
2208
+ if (events.length > 0) out.events = events;
2209
+ }
2210
+ return out;
2211
+ }
2212
+ function normalizeWebhookSegment(raw) {
2213
+ if (!raw || typeof raw !== "object") return void 0;
2214
+ const r = raw;
2215
+ const destinations = [];
2216
+ if (Array.isArray(r["destinations"])) {
2217
+ for (const entry of r["destinations"]) {
2218
+ const d = normalizeWebhookDestination(entry);
2219
+ if (d) destinations.push(d);
2220
+ }
2221
+ }
2222
+ const enabled = r["enabled"] === true;
2223
+ if (!enabled && destinations.length === 0) return void 0;
2224
+ return { enabled, destinations };
2225
+ }
2226
+ function clampNumber(value, min, max, fallback) {
2227
+ const n = typeof value === "number" && Number.isFinite(value) ? value : fallback;
2228
+ return Math.min(max, Math.max(min, n));
2229
+ }
2230
+ function normalizeQueueSegments(raw) {
2231
+ const umq = _optionalChain([raw, 'optionalAccess', _97 => _97.userMessageQueue]);
2232
+ const cq = _optionalChain([raw, 'optionalAccess', _98 => _98.concurrencyQueue]);
2233
+ return {
2234
+ userMessageQueue: {
2235
+ enabled: _optionalChain([umq, 'optionalAccess', _99 => _99.enabled]) === true,
2236
+ delayMs: clampNumber(_optionalChain([umq, 'optionalAccess', _100 => _100.delayMs]), 0, 1e4, DEFAULT_USER_MESSAGE_QUEUE.delayMs),
2237
+ waitTimeoutMs: clampNumber(
2238
+ _optionalChain([umq, 'optionalAccess', _101 => _101.waitTimeoutMs]),
2239
+ 1e3,
2240
+ 3e5,
2241
+ DEFAULT_USER_MESSAGE_QUEUE.waitTimeoutMs
2242
+ )
2243
+ },
2244
+ concurrencyQueue: {
2245
+ maxQueueSizeFactor: clampNumber(
2246
+ _optionalChain([cq, 'optionalAccess', _102 => _102.maxQueueSizeFactor]),
2247
+ 1,
2248
+ 10,
2249
+ DEFAULT_CONCURRENCY_QUEUE.maxQueueSizeFactor
2250
+ ),
2251
+ minQueueSize: clampNumber(_optionalChain([cq, 'optionalAccess', _103 => _103.minQueueSize]), 1, 100, DEFAULT_CONCURRENCY_QUEUE.minQueueSize),
2252
+ waitTimeoutMs: clampNumber(
2253
+ _optionalChain([cq, 'optionalAccess', _104 => _104.waitTimeoutMs]),
2254
+ 1e3,
2255
+ 3e5,
2256
+ DEFAULT_CONCURRENCY_QUEUE.waitTimeoutMs
2257
+ )
2258
+ }
2259
+ };
2260
+ }
2261
+ var ALL_ENDPOINTS = ["chat", "responses", "messages", "gemini"];
2262
+ function blankModelMap(endpoint) {
2263
+ const modelMap = {};
2264
+ for (const kind of _chunkSVXC36MUcjs.modelKindsForEndpoint.call(void 0, endpoint)) modelMap[kind] = "";
2265
+ return modelMap;
2266
+ }
2267
+ function defaultEndpointConfig(endpoint) {
2268
+ if (_chunkSVXC36MUcjs.isKindMappedEndpoint.call(void 0, endpoint)) {
2269
+ return { endpoint, modelMap: blankModelMap(endpoint), useSubscription: false };
2270
+ }
2271
+ if (endpoint === "chat") {
2272
+ return { endpoint, models: [], useSubscription: false };
2273
+ }
2274
+ return {
2275
+ endpoint,
2276
+ defaultModel: "",
2277
+ backgroundModel: "",
2278
+ useSubscription: false
2279
+ };
2280
+ }
2281
+ function normalizePrefixTargets(raw) {
2282
+ if (!raw || typeof raw !== "object") return void 0;
2283
+ const r = raw;
2284
+ const out = {};
2285
+ for (const key of ["claude", "gpt", "gemini"]) {
2286
+ const v = r[key];
2287
+ if (typeof v === "string" && v.trim() !== "") out[key] = v.trim();
2288
+ }
2289
+ return out.claude || out.gpt || out.gemini ? out : void 0;
2290
+ }
2291
+ function normalizeEndpointConfig(e) {
2292
+ const endpoint = e.endpoint;
2293
+ const useSubscription = e.useSubscription === true;
2294
+ if (_chunkSVXC36MUcjs.isKindMappedEndpoint.call(void 0, endpoint)) {
2295
+ const rawMap = e.modelMap && typeof e.modelMap === "object" ? e.modelMap : {};
2296
+ const modelMap = {};
2297
+ for (const kind of _chunkSVXC36MUcjs.modelKindsForEndpoint.call(void 0, endpoint)) {
2298
+ const v = rawMap[kind];
2299
+ modelMap[kind] = typeof v === "string" ? v : "";
2300
+ }
2301
+ return { endpoint, modelMap, useSubscription };
2302
+ }
2303
+ if (endpoint === "chat") {
2304
+ const models = Array.isArray(e.models) ? e.models.filter((m) => typeof m === "string" && m.trim() !== "") : [];
2305
+ const config2 = { endpoint, models, useSubscription };
2306
+ if (e.dispatchMode === "prefix") {
2307
+ config2.dispatchMode = "prefix";
2308
+ const targets = normalizePrefixTargets(e.prefixTargets);
2309
+ if (targets) config2.prefixTargets = targets;
2310
+ }
2311
+ return config2;
2312
+ }
2313
+ const config = {
2314
+ endpoint,
2315
+ defaultModel: typeof e.defaultModel === "string" ? e.defaultModel : "",
2316
+ backgroundModel: typeof e.backgroundModel === "string" ? e.backgroundModel : "",
2317
+ useSubscription
2318
+ };
2319
+ if (Array.isArray(e.backgroundModelIds)) {
2320
+ config.backgroundModelIds = e.backgroundModelIds;
2321
+ }
2322
+ return config;
2323
+ }
2324
+ function defaultServerConfig() {
2325
+ const queues = normalizeQueueSegments(void 0);
2326
+ return {
2327
+ enabled: false,
2328
+ networkBinding: false,
2329
+ endpoints: ALL_ENDPOINTS.map(defaultEndpointConfig),
2330
+ port: DEFAULT_OUTBOUND_PORT,
2331
+ userMessageQueue: queues.userMessageQueue,
2332
+ concurrencyQueue: queues.concurrencyQueue,
2333
+ accountHealth: normalizeAccountHealth(void 0),
2334
+ accountProbe: normalizeAccountProbe(void 0),
2335
+ audit: normalizeAudit(void 0),
2336
+ billing: normalizeBilling(void 0),
2337
+ fingerprint: normalizeFingerprint(void 0),
2338
+ voucher: normalizeVoucher(void 0)
2339
+ };
2340
+ }
2341
+ function normalizeServerConfig(raw) {
2342
+ const base = defaultServerConfig();
2343
+ if (!raw) return base;
2344
+ const byEndpoint = /* @__PURE__ */ new Map();
2345
+ for (const e of _nullishCoalesce(raw.endpoints, () => ( []))) {
2346
+ if (e && ALL_ENDPOINTS.includes(e.endpoint)) {
2347
+ byEndpoint.set(e.endpoint, normalizeEndpointConfig(e));
2348
+ }
2349
+ }
2350
+ const queues = normalizeQueueSegments(raw);
2351
+ const config = {
2352
+ enabled: raw.enabled === true,
2353
+ networkBinding: raw.networkBinding === true,
2354
+ endpoints: ALL_ENDPOINTS.map(
2355
+ (ep) => _nullishCoalesce(byEndpoint.get(ep), () => ( defaultEndpointConfig(ep)))
2356
+ ),
2357
+ port: _nullishCoalesce(raw.port, () => ( base.port)),
2358
+ userMessageQueue: queues.userMessageQueue,
2359
+ concurrencyQueue: queues.concurrencyQueue,
2360
+ accountHealth: normalizeAccountHealth(raw),
2361
+ accountProbe: normalizeAccountProbe(raw),
2362
+ audit: normalizeAudit(raw),
2363
+ billing: normalizeBilling(raw),
2364
+ fingerprint: normalizeFingerprint(raw),
2365
+ voucher: normalizeVoucher(raw)
2366
+ };
2367
+ const proxy = normalizeProxySegment(raw.proxy);
2368
+ if (proxy) config.proxy = proxy;
2369
+ const webhook = normalizeWebhookSegment(raw.webhook);
2370
+ if (webhook) config.webhook = webhook;
2371
+ return config;
2372
+ }
2373
+ async function loadServerConfig(store) {
2374
+ const raw = await store.get(
2375
+ OUTBOUND_API_SERVER_CONFIG_KEY
2376
+ );
2377
+ return normalizeServerConfig(raw);
2378
+ }
2379
+ async function saveServerConfig(store, config) {
2380
+ await store.set(OUTBOUND_API_SERVER_CONFIG_KEY, config);
2381
+ }
2382
+ function mergeServerConfig(current, patch) {
2383
+ return normalizeServerConfig({
2384
+ enabled: _nullishCoalesce(patch.enabled, () => ( current.enabled)),
2385
+ networkBinding: _nullishCoalesce(patch.networkBinding, () => ( current.networkBinding)),
2386
+ endpoints: _nullishCoalesce(patch.endpoints, () => ( current.endpoints)),
2387
+ port: _nullishCoalesce(patch.port, () => ( current.port)),
2388
+ userMessageQueue: _nullishCoalesce(patch.userMessageQueue, () => ( current.userMessageQueue)),
2389
+ concurrencyQueue: _nullishCoalesce(patch.concurrencyQueue, () => ( current.concurrencyQueue)),
2390
+ accountHealth: _nullishCoalesce(patch.accountHealth, () => ( current.accountHealth)),
2391
+ accountProbe: _nullishCoalesce(patch.accountProbe, () => ( current.accountProbe)),
2392
+ audit: _nullishCoalesce(patch.audit, () => ( current.audit)),
2393
+ billing: _nullishCoalesce(patch.billing, () => ( current.billing)),
2394
+ // Proxy is layer-replaced (not deep-merged): a PUT carrying `proxy` swaps the
2395
+ // whole segment; omitting it keeps the current one. `undefined` on both ⇒ absent.
2396
+ proxy: _nullishCoalesce(patch.proxy, () => ( current.proxy)),
2397
+ // Webhook is layer-replaced too (a PUT carrying `webhook` swaps the whole
2398
+ // segment; omitting it keeps the current one). `undefined` on both ⇒ absent.
2399
+ webhook: _nullishCoalesce(patch.webhook, () => ( current.webhook)),
2400
+ // Fingerprint is always-filled (normalizeFingerprint synthesizes a default);
2401
+ // a PUT carrying it replaces the segment, else the current one is kept.
2402
+ fingerprint: _nullishCoalesce(patch.fingerprint, () => ( current.fingerprint)),
2403
+ // Voucher is always-filled (normalizeVoucher synthesizes a default); a PUT
2404
+ // carrying it replaces the segment, else the current one is kept.
2405
+ voucher: _nullishCoalesce(patch.voucher, () => ( current.voucher))
2406
+ });
2407
+ }
2408
+
2409
+ // src/outbound-api/auditCapture.ts
2410
+
2411
+
2412
+ // src/outbound-api/auditRedact.ts
2413
+ var AUDIT_REDACTED = "***REDACTED***";
2414
+ var RULES = [
2415
+ // `sk-…` family (Anthropic sk-ant-, omnicross sk-omnicross-, OpenAI sk-proj-/sk-).
2416
+ { re: /\bsk-[A-Za-z0-9_-]{6,}/g, replace: AUDIT_REDACTED },
2417
+ // Google API keys.
2418
+ { re: /\bAIza[A-Za-z0-9_-]{10,}/g, replace: AUDIT_REDACTED },
2419
+ // `Bearer <token>` (auth headers echoed into a body / SSE error).
2420
+ { re: /\bBearer\s+[A-Za-z0-9._~+/=-]{6,}/gi, replace: `Bearer ${AUDIT_REDACTED}` },
2421
+ // Inline `x-api-key` / `api-key` / `authorization` label followed by a value.
2422
+ {
2423
+ re: /\b(x-api-key|api[_-]?key|authorization)(["']?\s*[:=]\s*["']?)[A-Za-z0-9._~+/=-]{6,}/gi,
2424
+ replace: `$1$2${AUDIT_REDACTED}`
2425
+ },
2426
+ // `x-goog-api-key` header echoed inline.
2427
+ {
2428
+ re: /\b(x-goog-api-key)(["']?\s*[:=]\s*["']?)[A-Za-z0-9._~+/=-]{6,}/gi,
2429
+ replace: `$1$2${AUDIT_REDACTED}`
2430
+ }
2431
+ ];
2432
+ function redactAuditText(text) {
2433
+ if (typeof text !== "string" || text.length === 0) return _nullishCoalesce(text, () => ( ""));
2434
+ let out = text;
2435
+ for (const { re, replace } of RULES) {
2436
+ out = out.replace(re, replace);
2437
+ }
2438
+ return out;
2439
+ }
2440
+
2441
+ // src/outbound-api/auditCapture.ts
2442
+ function isStreamingContentType(res) {
2443
+ const ct = res.getHeader("content-type");
2444
+ const value = Array.isArray(ct) ? ct.join(";") : String(_nullishCoalesce(ct, () => ( "")));
2445
+ return value.toLowerCase().includes("text/event-stream");
2446
+ }
2447
+ function resolveClientIp(req, trustForwardedFor) {
2448
+ if (trustForwardedFor) {
2449
+ const xff = req.headers["x-forwarded-for"];
2450
+ const raw = Array.isArray(xff) ? xff[0] : xff;
2451
+ if (typeof raw === "string" && raw.trim()) {
2452
+ const first = _optionalChain([raw, 'access', _105 => _105.split, 'call', _106 => _106(","), 'access', _107 => _107[0], 'optionalAccess', _108 => _108.trim, 'call', _109 => _109()]);
2453
+ if (first) return first;
2454
+ }
2455
+ }
2456
+ return _nullishCoalesce(_optionalChain([req, 'access', _110 => _110.socket, 'optionalAccess', _111 => _111.remoteAddress]), () => ( void 0));
2457
+ }
2458
+ function truncateToBytes(text, maxBytes) {
2459
+ const buf = Buffer.from(text, "utf8");
2460
+ if (buf.length <= maxBytes) return text;
2461
+ return buf.subarray(0, maxBytes).toString("utf8");
2462
+ }
2463
+ function beginAuditCapture(req, res, now) {
2464
+ const config = _chunkAEOZIDEBcjs.getAuditCaptureConfig.call(void 0, );
2465
+ if (!config) return null;
2466
+ let rawRequestBody;
2467
+ const responseChunks = [];
2468
+ let responseBytes = 0;
2469
+ let streamDetected = false;
2470
+ let finished = false;
2471
+ const ctx = {
2472
+ setRequestBody(raw) {
2473
+ if (config.captureBodies) rawRequestBody = raw;
2474
+ }
2475
+ };
2476
+ if (config.captureBodies) {
2477
+ installResponseCapture(res, config.maxBodyBytes, {
2478
+ push(chunk) {
2479
+ responseBytes += chunk.length;
2480
+ responseChunks.push(chunk);
2481
+ },
2482
+ get bytes() {
2483
+ return responseBytes;
2484
+ },
2485
+ markStream() {
2486
+ streamDetected = true;
2487
+ },
2488
+ get isStream() {
2489
+ return streamDetected;
2490
+ }
2491
+ });
2492
+ }
2493
+ const finalize = () => {
2494
+ if (finished) return;
2495
+ finished = true;
2496
+ try {
2497
+ const record = {
2498
+ id: _crypto.randomUUID.call(void 0, ),
2499
+ ts: now,
2500
+ method: _nullishCoalesce(req.method, () => ( "")),
2501
+ path: _nullishCoalesce((_nullishCoalesce(req.url, () => ( ""))).split("?")[0], () => ( "")),
2502
+ status: res.statusCode,
2503
+ latencyMs: Math.max(0, Date.now() - now)
2504
+ };
2505
+ if (ctx.keyId != null) record.keyId = ctx.keyId;
2506
+ const ip = resolveClientIp(req, config.trustForwardedFor);
2507
+ if (ip) record.ip = ip;
2508
+ const ua = req.headers["user-agent"];
2509
+ if (typeof ua === "string" && ua) record.ua = ua;
2510
+ if (ctx.model) record.model = ctx.model;
2511
+ if (ctx.provider) record.provider = ctx.provider;
2512
+ const usage = _chunk3QOSDDNIcjs.readAuditUsage.call(void 0, res);
2513
+ if (usage) {
2514
+ if (typeof usage.inputTokens === "number") record.inputTokens = usage.inputTokens;
2515
+ if (typeof usage.outputTokens === "number") record.outputTokens = usage.outputTokens;
2516
+ if (typeof usage.costUsd === "number") record.costUsd = usage.costUsd;
2517
+ if (!record.model && usage.model) record.model = usage.model;
2518
+ if (!record.provider && usage.provider) record.provider = usage.provider;
2519
+ }
2520
+ if (ctx.error) record.error = redactAuditText(ctx.error);
2521
+ if (config.captureBodies) {
2522
+ if (rawRequestBody != null && rawRequestBody.length > 0) {
2523
+ record.requestBody = redactAuditText(truncateToBytes(rawRequestBody, config.maxBodyBytes));
2524
+ }
2525
+ if (!streamDetected && responseChunks.length > 0) {
2526
+ const body = Buffer.concat(responseChunks).toString("utf8");
2527
+ record.responseBody = redactAuditText(body);
2528
+ }
2529
+ }
2530
+ _chunkAEOZIDEBcjs.recordAudit.call(void 0, record);
2531
+ } catch (e18) {
2532
+ }
2533
+ };
2534
+ res.once("close", finalize);
2535
+ return ctx;
2536
+ }
2537
+ function installResponseCapture(res, maxBodyBytes, sink2) {
2538
+ let contentTypeChecked = false;
2539
+ const capture = (chunk) => {
2540
+ if (sink2.isStream) return;
2541
+ if (!contentTypeChecked) {
2542
+ contentTypeChecked = true;
2543
+ if (isStreamingContentType(res)) {
2544
+ sink2.markStream();
2545
+ return;
2546
+ }
2547
+ }
2548
+ if (sink2.bytes >= maxBodyBytes) return;
2549
+ let buf = null;
2550
+ if (Buffer.isBuffer(chunk)) buf = chunk;
2551
+ else if (typeof chunk === "string") buf = Buffer.from(chunk, "utf8");
2552
+ if (!buf || buf.length === 0) return;
2553
+ const remaining = maxBodyBytes - sink2.bytes;
2554
+ sink2.push(buf.length > remaining ? buf.subarray(0, remaining) : buf);
2555
+ };
2556
+ const originalWrite = res.write.bind(res);
2557
+ const originalEnd = res.end.bind(res);
2558
+ res.write = ((chunk, ...args) => {
2559
+ if (chunk != null) capture(chunk);
2560
+ return originalWrite(chunk, ...args);
2561
+ });
2562
+ res.end = ((chunk, ...args) => {
2563
+ if (chunk != null && typeof chunk !== "function") capture(chunk);
2564
+ return originalEnd(chunk, ...args);
2565
+ });
2566
+ }
2567
+
2568
+ // src/outbound-api/billingCapture.ts
2569
+
2570
+ var defaultDefer = (fn) => {
2571
+ setTimeout(fn, 0);
2572
+ };
2573
+ function beginBillingCapture(_req, res, now, defer = defaultDefer) {
2574
+ if (!_chunkL74VDN4Acjs.getBillingCaptureConfig.call(void 0, )) return null;
2575
+ const ctx = {};
2576
+ let finished = false;
2577
+ const finalize = () => {
2578
+ if (finished) return;
2579
+ finished = true;
2580
+ const status = res.statusCode;
2581
+ defer(() => {
2582
+ try {
2583
+ const usage = _chunk3QOSDDNIcjs.readAuditUsage.call(void 0, res);
2584
+ if (!usage) return;
2585
+ const event = {
2586
+ id: _crypto.randomUUID.call(void 0, ),
2587
+ ts: now,
2588
+ model: _nullishCoalesce(_nullishCoalesce(ctx.model, () => ( usage.model)), () => ( "")),
2589
+ authMode: _nullishCoalesce(ctx.authMode, () => ( "byo")),
2590
+ inputTokens: _nullishCoalesce(usage.inputTokens, () => ( 0)),
2591
+ outputTokens: _nullishCoalesce(usage.outputTokens, () => ( 0)),
2592
+ costUsd: _nullishCoalesce(usage.costUsd, () => ( 0)),
2593
+ status
2594
+ };
2595
+ if (ctx.keyId != null) event.keyId = ctx.keyId;
2596
+ const provider = _nullishCoalesce(ctx.provider, () => ( usage.provider));
2597
+ if (provider) event.provider = provider;
2598
+ _chunkL74VDN4Acjs.publishBillingEvent.call(void 0, event);
2599
+ } catch (e19) {
2600
+ }
2601
+ });
2602
+ };
2603
+ res.once("close", finalize);
2604
+ return ctx;
2605
+ }
2606
+
1703
2607
  // src/outbound-api/outboundApiKeyAuth.ts
1704
2608
 
2609
+
2610
+ // src/outbound-api/keyPolicy.ts
2611
+ var DAY_MS = 864e5;
2612
+ function computeKeyExpiry(row, now) {
2613
+ const mode = _nullishCoalesce(row.activationMode, () => ( "fixed"));
2614
+ if (mode === "activation") {
2615
+ if (row.activatedAt == null) return { expired: false, needsActivation: true };
2616
+ if (row.activationDays == null) return { expired: false };
2617
+ const effectiveExpiresAt = row.activatedAt + row.activationDays * DAY_MS;
2618
+ return { expired: now >= effectiveExpiresAt, effectiveExpiresAt };
2619
+ }
2620
+ if (row.expiresAt == null) return { expired: false };
2621
+ return { expired: now >= row.expiresAt, effectiveExpiresAt: row.expiresAt };
2622
+ }
2623
+ function checkKeyQuota(limits, spend) {
2624
+ if (!limits) return { allowed: true };
2625
+ if (limits.dailyUsd != null && spend.dailyUsd >= limits.dailyUsd) {
2626
+ return { allowed: false, scope: "daily", limitUsd: limits.dailyUsd, spentUsd: spend.dailyUsd };
2627
+ }
2628
+ if (limits.weeklyUsd != null && spend.weeklyUsd >= limits.weeklyUsd) {
2629
+ return { allowed: false, scope: "weekly", limitUsd: limits.weeklyUsd, spentUsd: spend.weeklyUsd };
2630
+ }
2631
+ if (limits.totalUsd != null && spend.totalUsd >= limits.totalUsd) {
2632
+ return { allowed: false, scope: "total", limitUsd: limits.totalUsd, spentUsd: spend.totalUsd };
2633
+ }
2634
+ return { allowed: true };
2635
+ }
2636
+ function canonicalModelId(value) {
2637
+ const idx = value.indexOf(",");
2638
+ const bare = idx >= 0 ? value.slice(idx + 1) : value;
2639
+ return bare.trim().toLowerCase();
2640
+ }
2641
+ function checkModelAllowed(restriction, resolvedModelId) {
2642
+ if (!restriction) return { allowed: true };
2643
+ const target = canonicalModelId(resolvedModelId);
2644
+ const listed = restriction.models.some((m) => canonicalModelId(m) === target);
2645
+ if (restriction.mode === "allowlist") {
2646
+ return listed ? { allowed: true } : { allowed: false, model: resolvedModelId };
2647
+ }
2648
+ return listed ? { allowed: false, model: resolvedModelId } : { allowed: true };
2649
+ }
2650
+
2651
+ // src/outbound-api/outboundApiKeyAuth.ts
1705
2652
  var SECRET_BYTES = 32;
1706
2653
  var PREFIX_LEN = 14;
1707
2654
  var KEY_PREFIX = "sk-omnicross-";
@@ -1749,143 +2696,730 @@ async function createNamedKey(db, name) {
1749
2696
  plaintextOnce: secret
1750
2697
  };
1751
2698
  }
1752
- async function verifyPresentedKey(db, presentedKey) {
1753
- if (!presentedKey) return null;
2699
+ function extractCostLimits(row) {
2700
+ const limits = {};
2701
+ if (row.dailyCostLimitUsd != null) limits.dailyUsd = row.dailyCostLimitUsd;
2702
+ if (row.totalCostLimitUsd != null) limits.totalUsd = row.totalCostLimitUsd;
2703
+ if (row.weeklyCostLimitUsd != null) limits.weeklyUsd = row.weeklyCostLimitUsd;
2704
+ return limits.dailyUsd != null || limits.totalUsd != null || limits.weeklyUsd != null ? limits : void 0;
2705
+ }
2706
+ function extractRateLimit(row) {
2707
+ if (row.rateLimitMaxRequests == null && row.rateLimitWindowMs == null) return void 0;
2708
+ const override = {};
2709
+ if (row.rateLimitMaxRequests != null) override.maxRequests = row.rateLimitMaxRequests;
2710
+ if (row.rateLimitWindowMs != null) override.windowMs = row.rateLimitWindowMs;
2711
+ return override;
2712
+ }
2713
+ function extractModelRestriction(row) {
2714
+ if (row.enableModelRestriction !== true) return void 0;
2715
+ return {
2716
+ mode: _nullishCoalesce(row.restrictionMode, () => ( "blacklist")),
2717
+ models: _nullishCoalesce(row.restrictedModels, () => ( []))
2718
+ };
2719
+ }
2720
+ function toVerifiedKey(row) {
2721
+ const key = { id: row.id };
2722
+ if (row.maxConcurrency !== void 0 && row.maxConcurrency !== null) {
2723
+ key.maxConcurrency = row.maxConcurrency;
2724
+ }
2725
+ const costLimits = extractCostLimits(row);
2726
+ if (costLimits) key.costLimits = costLimits;
2727
+ const rateLimit = extractRateLimit(row);
2728
+ if (rateLimit) key.rateLimit = rateLimit;
2729
+ const modelRestriction = extractModelRestriction(row);
2730
+ if (modelRestriction) key.modelRestriction = modelRestriction;
2731
+ return key;
2732
+ }
2733
+ async function verifyKey(db, presentedKey, now = Date.now()) {
2734
+ if (!presentedKey) return { status: "invalid" };
1754
2735
  const trimmed = presentedKey.trim();
1755
- if (!trimmed) return null;
2736
+ if (!trimmed) return { status: "invalid" };
1756
2737
  const row = await db.outboundApiKeysGetByHash(hashKey(trimmed));
1757
- if (!row) return null;
1758
- if (!row.enabled || row.revokedAt !== null) return null;
2738
+ if (!row) return { status: "invalid" };
2739
+ if (!row.enabled || row.revokedAt !== null) return { status: "invalid" };
2740
+ const expiry = computeKeyExpiry(row, now);
2741
+ if (expiry.expired) return { status: "expired" };
1759
2742
  void db.outboundApiKeysTouchLastUsed(row.id).catch(() => {
1760
2743
  });
1761
- return { id: row.id };
1762
- }
1763
-
1764
- // src/outbound-api/roleDetection.ts
1765
- var _canonicalmodels = require('@omnicross/contracts/canonical-models');
1766
- var BACKGROUND_TIER_TOKENS = /* @__PURE__ */ new Set([
1767
- "haiku",
1768
- "mini",
1769
- "flash",
1770
- "small",
1771
- "lite",
1772
- "nano",
1773
- "8b"
1774
- ]);
1775
- function modelTokens(normalizedId) {
1776
- return normalizedId.split(/[-._:/\s]+/).filter(Boolean);
1777
- }
1778
- function isBackgroundTierModel(rawModelId) {
1779
- if (!rawModelId) return false;
1780
- const tokens = modelTokens(_canonicalmodels.normalizeModelId.call(void 0, rawModelId));
1781
- return tokens.some((tok) => BACKGROUND_TIER_TOKENS.has(tok));
1782
- }
1783
- function extractRequestedModel(ingressFormat, body) {
1784
- const model = body["model"];
1785
- return typeof model === "string" && model ? model : void 0;
1786
- }
1787
- function anthropicHasVision(body) {
1788
- const messages = body["messages"];
1789
- if (!Array.isArray(messages)) return false;
1790
- for (const msg of messages) {
1791
- const content = _optionalChain([msg, 'optionalAccess', _64 => _64.content]);
1792
- if (!Array.isArray(content)) continue;
1793
- for (const part of content) {
1794
- if (_optionalChain([part, 'optionalAccess', _65 => _65.type]) === "image") return true;
1795
- }
2744
+ if (expiry.needsActivation) {
2745
+ void db.outboundApiKeysMarkActivated(row.id, now).catch(() => {
2746
+ });
1796
2747
  }
1797
- return false;
2748
+ return { status: "ok", key: toVerifiedKey(row) };
2749
+ }
2750
+ async function verifyPresentedKey(db, presentedKey) {
2751
+ const result = await verifyKey(db, presentedKey);
2752
+ return result.status === "ok" ? result.key : null;
2753
+ }
2754
+
2755
+ // src/outbound-api/quotaWarn.ts
2756
+ var WEBHOOK_QUOTA_WARN_RATIO = 0.8;
2757
+ function computeQuotaWarnings(limits, spend, ratio = WEBHOOK_QUOTA_WARN_RATIO) {
2758
+ const out = [];
2759
+ const consider = (scope, limit, spent, windowStart) => {
2760
+ if (limit == null || limit <= 0) return;
2761
+ if (spent >= limit) return;
2762
+ if (spent >= ratio * limit) out.push({ scope, limitUsd: limit, spentUsd: spent, windowStart });
2763
+ };
2764
+ consider("daily", limits.dailyUsd, spend.dailyUsd, spend.dailyWindowStart);
2765
+ consider("weekly", limits.weeklyUsd, spend.weeklyUsd, spend.weeklyWindowStart);
2766
+ consider("total", limits.totalUsd, spend.totalUsd, 0);
2767
+ return out;
2768
+ }
2769
+ var WARN_GUARD_MAX = 1e4;
2770
+ var warned = /* @__PURE__ */ new Set();
2771
+ function markQuotaWarnedOnce(keyId, scope, windowStart) {
2772
+ const key = `${keyId}\0${scope}\0${windowStart}`;
2773
+ if (warned.has(key)) return false;
2774
+ if (warned.size >= WARN_GUARD_MAX) warned.clear();
2775
+ warned.add(key);
2776
+ return true;
1798
2777
  }
1799
- function openaiChatHasVision(body) {
1800
- const messages = body["messages"];
1801
- if (!Array.isArray(messages)) return false;
1802
- for (const msg of messages) {
1803
- const content = _optionalChain([msg, 'optionalAccess', _66 => _66.content]);
1804
- if (!Array.isArray(content)) continue;
1805
- for (const part of content) {
1806
- if (_optionalChain([part, 'optionalAccess', _67 => _67.type]) === "image_url") return true;
2778
+
2779
+ // src/outbound-api/outboundConcurrencyGate.ts
2780
+ var ConcurrencyQueueFullError = (_class4 = class extends Error {
2781
+ constructor(apiKeyId, maxQueueSize) {
2782
+ super(`concurrency queue full (max ${maxQueueSize}) for key '${apiKeyId}'`);_class4.prototype.__init5.call(this);;
2783
+ this.apiKeyId = apiKeyId;
2784
+ this.maxQueueSize = maxQueueSize;
2785
+ this.name = "ConcurrencyQueueFullError";
2786
+ }
2787
+
2788
+
2789
+ __init5() {this.code = "concurrency_queue_full"}
2790
+ }, _class4);
2791
+ var ConcurrencyWaitTimeoutError = (_class5 = class extends Error {
2792
+ constructor(apiKeyId, waitTimeoutMs) {
2793
+ super(`concurrency wait timed out after ${waitTimeoutMs}ms for key '${apiKeyId}'`);_class5.prototype.__init6.call(this);;
2794
+ this.apiKeyId = apiKeyId;
2795
+ this.waitTimeoutMs = waitTimeoutMs;
2796
+ this.name = "ConcurrencyWaitTimeoutError";
2797
+ }
2798
+
2799
+
2800
+ __init6() {this.code = "concurrency_wait_timeout"}
2801
+ }, _class5);
2802
+ var ConcurrencyWaitCancelledError = (_class6 = class extends Error {
2803
+ constructor(apiKeyId) {
2804
+ super(`concurrency wait cancelled for key '${apiKeyId}'`);_class6.prototype.__init7.call(this);;
2805
+ this.apiKeyId = apiKeyId;
2806
+ this.name = "ConcurrencyWaitCancelledError";
2807
+ }
2808
+
2809
+ __init7() {this.code = "concurrency_wait_cancelled"}
2810
+ }, _class6);
2811
+ function isConcurrencyRejection(err) {
2812
+ return err instanceof ConcurrencyQueueFullError || err instanceof ConcurrencyWaitTimeoutError || err instanceof ConcurrencyWaitCancelledError;
2813
+ }
2814
+ var OutboundConcurrencyGate = (_class7 = class {constructor() { _class7.prototype.__init8.call(this); }
2815
+ __init8() {this.states = /* @__PURE__ */ new Map()}
2816
+ ensure(apiKeyId) {
2817
+ let state = this.states.get(apiKeyId);
2818
+ if (!state) {
2819
+ state = { active: 0, waiters: [] };
2820
+ this.states.set(apiKeyId, state);
1807
2821
  }
2822
+ return state;
1808
2823
  }
1809
- return false;
1810
- }
1811
- function openaiResponsesHasVision(body) {
1812
- const input = body["input"];
1813
- if (!Array.isArray(input)) return false;
1814
- for (const item of input) {
1815
- const content = _optionalChain([item, 'optionalAccess', _68 => _68.content]);
1816
- if (Array.isArray(content)) {
1817
- for (const part of content) {
1818
- if (_optionalChain([part, 'optionalAccess', _69 => _69.type]) === "input_image") return true;
2824
+ /** Delete a key's state once it is fully idle (no active, no waiters). */
2825
+ gc(apiKeyId) {
2826
+ const state = this.states.get(apiKeyId);
2827
+ if (state && state.active === 0 && state.waiters.length === 0) {
2828
+ this.states.delete(apiKeyId);
2829
+ }
2830
+ }
2831
+ /**
2832
+ * Acquire a concurrency slot for `apiKeyId` under `limit`. Grants immediately
2833
+ * when `active < limit`; else enqueues FIFO while under the per-key queue cap;
2834
+ * else rejects queue-full. `limit <= 0` = unlimited (always granted).
2835
+ */
2836
+ acquire(apiKeyId, limit, options) {
2837
+ const state = this.ensure(apiKeyId);
2838
+ const cap = limit > 0 ? limit : Infinity;
2839
+ if (state.active < cap) {
2840
+ state.active += 1;
2841
+ const slot = this.makeSlot(apiKeyId);
2842
+ return { granted: Promise.resolve(slot), cancel: slot.cancel };
2843
+ }
2844
+ const maxQueueSize = Math.max(
2845
+ Number.isFinite(cap) ? cap * options.maxQueueSizeFactor : Infinity,
2846
+ options.minQueueSize
2847
+ );
2848
+ if (state.waiters.length >= maxQueueSize) {
2849
+ const err = new ConcurrencyQueueFullError(apiKeyId, maxQueueSize);
2850
+ return { granted: Promise.reject(err), cancel: () => {
2851
+ } };
2852
+ }
2853
+ let settled = false;
2854
+ let granted = false;
2855
+ let resolveGrant;
2856
+ let rejectGrant;
2857
+ const grantedPromise = new Promise((resolve, reject) => {
2858
+ resolveGrant = resolve;
2859
+ rejectGrant = reject;
2860
+ });
2861
+ const waiter = {
2862
+ cap,
2863
+ settled: false,
2864
+ timeoutHandle: null,
2865
+ grant: () => {
2866
+ if (settled) return;
2867
+ settled = true;
2868
+ granted = true;
2869
+ waiter.settled = true;
2870
+ if (waiter.timeoutHandle) clearTimeout(waiter.timeoutHandle);
2871
+ state.active += 1;
2872
+ resolveGrant(this.makeSlot(apiKeyId));
2873
+ },
2874
+ fail: (err) => {
2875
+ if (settled) return;
2876
+ settled = true;
2877
+ waiter.settled = true;
2878
+ if (waiter.timeoutHandle) clearTimeout(waiter.timeoutHandle);
2879
+ const idx = state.waiters.indexOf(waiter);
2880
+ if (idx >= 0) state.waiters.splice(idx, 1);
2881
+ rejectGrant(err);
2882
+ this.gc(apiKeyId);
2883
+ }
2884
+ };
2885
+ waiter.timeoutHandle = setTimeout(() => {
2886
+ waiter.fail(new ConcurrencyWaitTimeoutError(apiKeyId, options.waitTimeoutMs));
2887
+ }, options.waitTimeoutMs);
2888
+ state.waiters.push(waiter);
2889
+ const cancel = () => {
2890
+ if (settled || granted) return;
2891
+ waiter.fail(new ConcurrencyWaitCancelledError(apiKeyId));
2892
+ };
2893
+ return { granted: grantedPromise, cancel };
2894
+ }
2895
+ /** Build an idempotent granted slot (`release` decrements; `cancel` is a no-op). */
2896
+ makeSlot(apiKeyId) {
2897
+ let released = false;
2898
+ const release2 = () => {
2899
+ if (released) return;
2900
+ released = true;
2901
+ const state = this.states.get(apiKeyId);
2902
+ if (!state) return;
2903
+ state.active = Math.max(0, state.active - 1);
2904
+ this.dispatchNext(apiKeyId);
2905
+ this.gc(apiKeyId);
2906
+ };
2907
+ return { release: release2, cancel: () => {
2908
+ } };
2909
+ }
2910
+ /** After a release freed a slot, grant the FIFO head if it fits under its cap. */
2911
+ dispatchNext(apiKeyId) {
2912
+ const state = this.states.get(apiKeyId);
2913
+ if (!state || state.waiters.length === 0) return;
2914
+ const head = state.waiters[0];
2915
+ if (state.active < head.cap) {
2916
+ state.waiters.shift();
2917
+ head.grant();
2918
+ }
2919
+ }
2920
+ /** Snapshot for observability — only keys with active slots or waiters. */
2921
+ getStatus() {
2922
+ const out = [];
2923
+ for (const [apiKeyId, state] of this.states) {
2924
+ if (state.active > 0 || state.waiters.length > 0) {
2925
+ out.push({ apiKeyId, active: state.active, waiting: state.waiters.length });
2926
+ }
2927
+ }
2928
+ return out;
2929
+ }
2930
+ /** Drop all state + pending timers (tests / teardown). */
2931
+ reset() {
2932
+ for (const state of this.states.values()) {
2933
+ for (const w of state.waiters) {
2934
+ if (w.timeoutHandle) clearTimeout(w.timeoutHandle);
2935
+ }
2936
+ }
2937
+ this.states.clear();
2938
+ }
2939
+ }, _class7);
2940
+
2941
+ // src/outbound-api/outboundRateLimiter.ts
2942
+ var DEFAULT_WINDOW_MS = 6e4;
2943
+ var DEFAULT_MAX_REQUESTS = 60;
2944
+ var OutboundRateLimiter = (_class8 = class {
2945
+
2946
+
2947
+ /** apiKeyId → ascending request timestamps within the current window. */
2948
+ __init9() {this.hits = /* @__PURE__ */ new Map()}
2949
+ constructor(options = {}) {;_class8.prototype.__init9.call(this);
2950
+ this.windowMs = _nullishCoalesce(options.windowMs, () => ( DEFAULT_WINDOW_MS));
2951
+ this.maxRequests = _nullishCoalesce(options.maxRequests, () => ( DEFAULT_MAX_REQUESTS));
2952
+ }
2953
+ /**
2954
+ * Record a request for `apiKeyId` and decide whether it is allowed. Prunes
2955
+ * timestamps older than the window first; when allowed, the request's
2956
+ * timestamp is appended.
2957
+ *
2958
+ * `override` (outbound-key-policy) supplies a PER-KEY window/max for this
2959
+ * bucket, superseding the instance defaults for THAT key. Absent ⇒ the
2960
+ * instance default 60/60s (byte-identical to before this change). An effective
2961
+ * `maxRequests` of `0` means UNLIMITED — the request is allowed and NOT
2962
+ * recorded (no bucket growth).
2963
+ */
2964
+ check(apiKeyId, now = Date.now(), override) {
2965
+ const maxRequests = _nullishCoalesce(_optionalChain([override, 'optionalAccess', _112 => _112.maxRequests]), () => ( this.maxRequests));
2966
+ const windowMs = _nullishCoalesce(_optionalChain([override, 'optionalAccess', _113 => _113.windowMs]), () => ( this.windowMs));
2967
+ if (maxRequests === 0) return { allowed: true, retryAfterSeconds: 0 };
2968
+ const cutoff = now - windowMs;
2969
+ const timestamps = (_nullishCoalesce(this.hits.get(apiKeyId), () => ( []))).filter((ts) => ts > cutoff);
2970
+ if (timestamps.length >= maxRequests) {
2971
+ if (timestamps.length === 0) {
2972
+ this.hits.delete(apiKeyId);
2973
+ return { allowed: false, retryAfterSeconds: Math.max(1, Math.ceil(windowMs / 1e3)) };
1819
2974
  }
2975
+ const oldest = timestamps[0];
2976
+ const retryAfterMs = Math.max(0, oldest + windowMs - now);
2977
+ this.hits.set(apiKeyId, timestamps);
2978
+ return {
2979
+ allowed: false,
2980
+ retryAfterSeconds: Math.max(1, Math.ceil(retryAfterMs / 1e3))
2981
+ };
1820
2982
  }
1821
- if (_optionalChain([item, 'optionalAccess', _70 => _70.type]) === "input_image") return true;
2983
+ timestamps.push(now);
2984
+ this.hits.set(apiKeyId, timestamps);
2985
+ return { allowed: true, retryAfterSeconds: 0 };
2986
+ }
2987
+ /** Drop all recorded state (tests / teardown). */
2988
+ reset() {
2989
+ this.hits.clear();
2990
+ }
2991
+ }, _class8);
2992
+
2993
+ // src/outbound-api/userMessageDetection.ts
2994
+ function asArray(v) {
2995
+ return Array.isArray(v) ? v : [];
2996
+ }
2997
+ function asObject(v) {
2998
+ return v !== null && typeof v === "object" && !Array.isArray(v) ? v : null;
2999
+ }
3000
+ function last(arr) {
3001
+ return arr.length > 0 ? arr[arr.length - 1] : void 0;
3002
+ }
3003
+ function isUserMessageAnthropic(body) {
3004
+ const messages = asArray(body["messages"]);
3005
+ const lastMsg = asObject(last(messages));
3006
+ if (!lastMsg || lastMsg["role"] !== "user") return false;
3007
+ const content = lastMsg["content"];
3008
+ if (typeof content === "string") return true;
3009
+ if (Array.isArray(content)) {
3010
+ const hasToolResult = content.some(
3011
+ (block) => _optionalChain([asObject, 'call', _114 => _114(block), 'optionalAccess', _115 => _115["type"]]) === "tool_result"
3012
+ );
3013
+ return !hasToolResult;
1822
3014
  }
1823
3015
  return false;
1824
3016
  }
1825
- function geminiHasVision(body) {
1826
- const contents = body["contents"];
1827
- if (!Array.isArray(contents)) return false;
1828
- for (const content of contents) {
1829
- const parts = _optionalChain([content, 'optionalAccess', _71 => _71.parts]);
1830
- if (!Array.isArray(parts)) continue;
1831
- for (const part of parts) {
1832
- const p = part;
1833
- if (_optionalChain([p, 'optionalAccess', _72 => _72.inline_data]) || _optionalChain([p, 'optionalAccess', _73 => _73.inlineData]) || _optionalChain([p, 'optionalAccess', _74 => _74.file_data]) || _optionalChain([p, 'optionalAccess', _75 => _75.fileData])) return true;
1834
- }
3017
+ function isUserMessageResponses(body) {
3018
+ const input = body["input"];
3019
+ if (typeof input === "string") return input.length > 0;
3020
+ if (Array.isArray(input)) {
3021
+ const lastItem = asObject(last(input));
3022
+ if (!lastItem) return false;
3023
+ if (lastItem["type"] === "function_call_output") return false;
3024
+ return lastItem["role"] === "user";
1835
3025
  }
1836
3026
  return false;
1837
3027
  }
1838
- function hasVisionContent(ingressFormat, body) {
1839
- switch (ingressFormat) {
1840
- case "anthropic-messages":
1841
- return anthropicHasVision(body);
1842
- case "openai-chat":
1843
- return openaiChatHasVision(body);
1844
- case "openai-responses":
1845
- return openaiResponsesHasVision(body);
1846
- case "gemini-generatecontent":
1847
- return geminiHasVision(body);
3028
+ function isUserMessageChat(body) {
3029
+ const messages = asArray(body["messages"]);
3030
+ const lastMsg = asObject(last(messages));
3031
+ if (!lastMsg) return false;
3032
+ return lastMsg["role"] === "user";
3033
+ }
3034
+ function isUserMessageGemini(body) {
3035
+ const contents = asArray(body["contents"]);
3036
+ const lastContent = asObject(last(contents));
3037
+ if (!lastContent || lastContent["role"] !== "user") return false;
3038
+ const parts = asArray(lastContent["parts"]);
3039
+ const hasFunctionResponse = parts.some(
3040
+ (part) => _optionalChain([asObject, 'call', _116 => _116(part), 'optionalAccess', _117 => _117["functionResponse"]]) !== void 0
3041
+ );
3042
+ return !hasFunctionResponse;
3043
+ }
3044
+ function isUserMessageRequest(endpoint, parsedBody) {
3045
+ const body = asObject(parsedBody);
3046
+ if (!body) return false;
3047
+ switch (endpoint) {
3048
+ case "messages":
3049
+ return isUserMessageAnthropic(body);
3050
+ case "responses":
3051
+ return isUserMessageResponses(body);
3052
+ case "chat":
3053
+ return isUserMessageChat(body);
3054
+ case "gemini":
3055
+ return isUserMessageGemini(body);
1848
3056
  default:
1849
3057
  return false;
1850
3058
  }
1851
3059
  }
1852
- function detectRequestRole(ingressFormat, body, options) {
1853
- if (hasVisionContent(ingressFormat, body)) return "vision";
1854
- const requestedModel = extractRequestedModel(ingressFormat, body);
1855
- if (requestedModel) {
1856
- const overrides = _optionalChain([options, 'optionalAccess', _76 => _76.backgroundModelIds]);
1857
- if (overrides && overrides.length > 0) {
1858
- const reqNorm = _canonicalmodels.normalizeModelId.call(void 0, requestedModel);
1859
- const inOverride = overrides.some((id) => {
1860
- if (!id) return false;
1861
- const candidate = id.includes(",") ? id.slice(id.indexOf(",") + 1) : id;
1862
- return _canonicalmodels.normalizeModelId.call(void 0, candidate) === reqNorm || candidate === requestedModel;
1863
- });
1864
- if (inOverride) return "background";
3060
+
3061
+ // src/outbound-api/userMessageSerialQueue.ts
3062
+ var SerialQueueTimeoutError = (_class9 = class extends Error {
3063
+ constructor(providerId, waitTimeoutMs) {
3064
+ super(`user-message serial queue wait timed out after ${waitTimeoutMs}ms for '${providerId}'`);_class9.prototype.__init10.call(this);;
3065
+ this.providerId = providerId;
3066
+ this.waitTimeoutMs = waitTimeoutMs;
3067
+ this.name = "SerialQueueTimeoutError";
3068
+ }
3069
+
3070
+
3071
+ __init10() {this.code = "serial_queue_timeout"}
3072
+ }, _class9);
3073
+ function isSerialQueueTimeout(err) {
3074
+ return err instanceof SerialQueueTimeoutError;
3075
+ }
3076
+ var UserMessageSerialQueue = (_class10 = class {constructor() { _class10.prototype.__init11.call(this); }
3077
+ __init11() {this.states = /* @__PURE__ */ new Map()}
3078
+ ensure(providerId) {
3079
+ let state = this.states.get(providerId);
3080
+ if (!state) {
3081
+ state = { holding: false, lastReleaseTs: null, waiters: [], dispatchHandle: null };
3082
+ this.states.set(providerId, state);
3083
+ }
3084
+ return state;
3085
+ }
3086
+ /**
3087
+ * Acquire the serial slot for `providerId`. Resolves immediately when the slot
3088
+ * is free, no one is queued, and the `delayMs` gap since the last release has
3089
+ * elapsed; otherwise enqueues FIFO and resolves in order (or rejects with a
3090
+ * {@link SerialQueueTimeoutError} after `waitTimeoutMs`).
3091
+ */
3092
+ acquire(providerId, options) {
3093
+ const { waitTimeoutMs, delayMs } = options;
3094
+ const now = _nullishCoalesce(options.now, () => ( Date.now()));
3095
+ const state = this.ensure(providerId);
3096
+ const spacingElapsed = state.lastReleaseTs === null || now - state.lastReleaseTs >= delayMs;
3097
+ if (!state.holding && state.waiters.length === 0 && spacingElapsed) {
3098
+ state.holding = true;
3099
+ return Promise.resolve(this.makeSlot(providerId));
1865
3100
  }
1866
- if (isBackgroundTierModel(requestedModel)) return "background";
3101
+ return new Promise((resolve, reject) => {
3102
+ const waiter = {
3103
+ delayMs,
3104
+ resolve,
3105
+ reject,
3106
+ timeoutHandle: null,
3107
+ done: false
3108
+ };
3109
+ waiter.timeoutHandle = setTimeout(() => {
3110
+ if (waiter.done) return;
3111
+ waiter.done = true;
3112
+ const idx = state.waiters.indexOf(waiter);
3113
+ if (idx >= 0) state.waiters.splice(idx, 1);
3114
+ reject(new SerialQueueTimeoutError(providerId, waitTimeoutMs));
3115
+ }, waitTimeoutMs);
3116
+ state.waiters.push(waiter);
3117
+ this.maybeDispatch(providerId);
3118
+ });
3119
+ }
3120
+ /** Build an idempotent release for a granted slot. */
3121
+ makeSlot(providerId) {
3122
+ let released = false;
3123
+ return {
3124
+ release: () => {
3125
+ if (released) return;
3126
+ released = true;
3127
+ const state = this.states.get(providerId);
3128
+ if (!state) return;
3129
+ state.holding = false;
3130
+ state.lastReleaseTs = Date.now();
3131
+ this.maybeDispatch(providerId);
3132
+ }
3133
+ };
3134
+ }
3135
+ /**
3136
+ * Grant the head waiter when the slot is free and the head's `delayMs` gap has
3137
+ * elapsed; otherwise schedule a dispatch for the residual gap. No-op while the
3138
+ * slot is held (release re-invokes this) or the queue is empty.
3139
+ */
3140
+ maybeDispatch(providerId) {
3141
+ const state = this.states.get(providerId);
3142
+ if (!state || state.holding || state.waiters.length === 0) return;
3143
+ const head = state.waiters[0];
3144
+ const now = Date.now();
3145
+ const elapsed = state.lastReleaseTs === null ? Infinity : now - state.lastReleaseTs;
3146
+ const residual = Math.max(0, head.delayMs - elapsed);
3147
+ if (residual <= 0) {
3148
+ this.grantHead(providerId);
3149
+ return;
3150
+ }
3151
+ if (state.dispatchHandle !== null) return;
3152
+ state.dispatchHandle = setTimeout(() => {
3153
+ state.dispatchHandle = null;
3154
+ this.grantHead(providerId);
3155
+ }, residual);
3156
+ }
3157
+ /** Hand the slot to the FIFO head (if free and someone is waiting). */
3158
+ grantHead(providerId) {
3159
+ const state = this.states.get(providerId);
3160
+ if (!state || state.holding || state.waiters.length === 0) return;
3161
+ if (state.dispatchHandle !== null) {
3162
+ clearTimeout(state.dispatchHandle);
3163
+ state.dispatchHandle = null;
3164
+ }
3165
+ const head = state.waiters.shift();
3166
+ if (!head) return;
3167
+ if (head.timeoutHandle) clearTimeout(head.timeoutHandle);
3168
+ head.done = true;
3169
+ state.holding = true;
3170
+ head.resolve(this.makeSlot(providerId));
3171
+ }
3172
+ /** Snapshot for observability — only keys holding a slot or with waiters. */
3173
+ getStatus() {
3174
+ const out = [];
3175
+ for (const [providerId, state] of this.states) {
3176
+ if (state.holding || state.waiters.length > 0) {
3177
+ out.push({ providerId, holding: state.holding, waiting: state.waiters.length });
3178
+ }
3179
+ }
3180
+ return out;
3181
+ }
3182
+ /** Drop all state + pending timers (tests / teardown). */
3183
+ reset() {
3184
+ for (const state of this.states.values()) {
3185
+ if (state.dispatchHandle) clearTimeout(state.dispatchHandle);
3186
+ for (const w of state.waiters) {
3187
+ if (w.timeoutHandle) clearTimeout(w.timeoutHandle);
3188
+ }
3189
+ }
3190
+ this.states.clear();
3191
+ }
3192
+ }, _class10);
3193
+
3194
+ // src/outbound-api/voucher.ts
3195
+
3196
+ var CODE_ENTROPY_CHARS = 32;
3197
+ var CODE_PREFIX = "CC_";
3198
+ var DISPLAY_PREFIX_LEN = 8;
3199
+ var DAY_MS2 = 864e5;
3200
+ function generateVoucherCode() {
3201
+ return CODE_PREFIX + randomBase62(CODE_ENTROPY_CHARS);
3202
+ }
3203
+ function hashVoucherCode(code) {
3204
+ return _crypto.createHash.call(void 0, "sha256").update(code, "utf8").digest("hex");
3205
+ }
3206
+ function voucherCodePrefix(code) {
3207
+ return code.slice(0, DISPLAY_PREFIX_LEN);
3208
+ }
3209
+ function newVoucherId() {
3210
+ return `vch_${Date.now()}_${randomBase62(8)}`;
3211
+ }
3212
+ function computeVoucherGrant(voucher, currentKey, now) {
3213
+ if (voucher.type === "credit") {
3214
+ const current = _nullishCoalesce(_optionalChain([currentKey, 'optionalAccess', _118 => _118.totalCostLimitUsd]), () => ( 0));
3215
+ let granted2 = current + (_nullishCoalesce(voucher.creditUsd, () => ( 0)));
3216
+ if (voucher.maxTotalCostLimitUsd != null) {
3217
+ granted2 = Math.min(granted2, voucher.maxTotalCostLimitUsd);
3218
+ }
3219
+ return { totalCostLimitUsd: granted2 };
3220
+ }
3221
+ const currentExpiry = _nullishCoalesce(_optionalChain([currentKey, 'optionalAccess', _119 => _119.expiresAt]), () => ( now));
3222
+ let granted = currentExpiry + (_nullishCoalesce(voucher.renewalDays, () => ( 0))) * DAY_MS2;
3223
+ if (voucher.maxExpiryDays != null) {
3224
+ granted = Math.min(granted, now + voucher.maxExpiryDays * DAY_MS2);
3225
+ }
3226
+ return { expiresAt: granted };
3227
+ }
3228
+ function toVoucherInfo(v) {
3229
+ const info = {
3230
+ id: v.id,
3231
+ codePrefix: v.codePrefix,
3232
+ type: v.type,
3233
+ status: v.status,
3234
+ createdAt: v.createdAt
3235
+ };
3236
+ if (v.creditUsd != null) info.creditUsd = v.creditUsd;
3237
+ if (v.renewalDays != null) info.renewalDays = v.renewalDays;
3238
+ if (v.maxTotalCostLimitUsd != null) info.maxTotalCostLimitUsd = v.maxTotalCostLimitUsd;
3239
+ if (v.maxExpiryDays != null) info.maxExpiryDays = v.maxExpiryDays;
3240
+ if (v.redeemedAt != null) info.redeemedAt = v.redeemedAt;
3241
+ if (v.redeemedByKeyId != null) info.redeemedByKeyId = v.redeemedByKeyId;
3242
+ if (v.grantApplied != null) info.grantApplied = v.grantApplied;
3243
+ if (v.grantedTotalCostLimitUsd != null) info.grantedTotalCostLimitUsd = v.grantedTotalCostLimitUsd;
3244
+ if (v.grantedExpiresAt != null) info.grantedExpiresAt = v.grantedExpiresAt;
3245
+ if (v.revokedAt != null) info.revokedAt = v.revokedAt;
3246
+ return info;
3247
+ }
3248
+
3249
+ // src/outbound-api/voucherRedeem.ts
3250
+ function isRedeemRequest(method, url) {
3251
+ if (method !== "POST" || !url) return false;
3252
+ const path = _nullishCoalesce(_optionalChain([url, 'access', _120 => _120.split, 'call', _121 => _121("?"), 'access', _122 => _122[0], 'optionalAccess', _123 => _123.replace, 'call', _124 => _124(/\/+$/, "")]), () => ( ""));
3253
+ return path.endsWith("/redeem");
3254
+ }
3255
+ function writeErr(res, status, message, headers = {}) {
3256
+ if (res.headersSent) return;
3257
+ res.writeHead(status, { "Content-Type": "application/json", ...headers });
3258
+ res.end(JSON.stringify({ error: { type: "voucher_error", message } }));
3259
+ }
3260
+ function writeResult(res, result) {
3261
+ if (res.headersSent) return;
3262
+ res.writeHead(200, { "Content-Type": "application/json" });
3263
+ res.end(JSON.stringify({ ok: true, ...result }));
3264
+ }
3265
+ function readBody2(req) {
3266
+ return new Promise((resolve, reject) => {
3267
+ const chunks = [];
3268
+ req.on("data", (c) => chunks.push(c));
3269
+ req.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")));
3270
+ req.on("error", reject);
3271
+ });
3272
+ }
3273
+ function grantToResult(type, granted) {
3274
+ const result = { type };
3275
+ if (granted.totalCostLimitUsd != null) result.totalCostLimitUsd = granted.totalCostLimitUsd;
3276
+ if (granted.expiresAt != null) result.expiresAt = granted.expiresAt;
3277
+ return result;
3278
+ }
3279
+ function currentResult(type, keyRow) {
3280
+ const result = { type };
3281
+ if (type === "credit") {
3282
+ if (_optionalChain([keyRow, 'optionalAccess', _125 => _125.totalCostLimitUsd]) != null) result.totalCostLimitUsd = keyRow.totalCostLimitUsd;
3283
+ } else if (_optionalChain([keyRow, 'optionalAccess', _126 => _126.expiresAt]) != null) {
3284
+ result.expiresAt = keyRow.expiresAt;
3285
+ }
3286
+ return result;
3287
+ }
3288
+ function recordedAbsolute(v) {
3289
+ const granted = {};
3290
+ if (v.grantedTotalCostLimitUsd != null) granted.totalCostLimitUsd = v.grantedTotalCostLimitUsd;
3291
+ if (v.grantedExpiresAt != null) granted.expiresAt = v.grantedExpiresAt;
3292
+ return granted;
3293
+ }
3294
+ function policyFrom(granted) {
3295
+ const policy = {};
3296
+ if (granted.totalCostLimitUsd != null) policy.totalCostLimitUsd = granted.totalCostLimitUsd;
3297
+ if (granted.expiresAt != null) policy.expiresAt = granted.expiresAt;
3298
+ return policy;
3299
+ }
3300
+ var NOT_REDEEMABLE = "Invalid or non-redeemable code";
3301
+ var fallbackMutex = null;
3302
+ function getFallbackMutex() {
3303
+ fallbackMutex ??= new KeyedMutex();
3304
+ return fallbackMutex;
3305
+ }
3306
+ async function handleVoucherRedeem(req, res, deps, voucherEnabled, redeemLimiter, verifiedKeyId, presentedKey, now, redeemMutex) {
3307
+ if (!voucherEnabled || !deps.voucherDb) {
3308
+ writeErr(res, 403, "Voucher redemption is not enabled");
3309
+ return;
3310
+ }
3311
+ const voucherDb = deps.voucherDb;
3312
+ const rl = redeemLimiter.check(verifiedKeyId, now);
3313
+ if (!rl.allowed) {
3314
+ writeErr(res, 429, "Too many redeem attempts", { "Retry-After": String(rl.retryAfterSeconds) });
3315
+ return;
3316
+ }
3317
+ const raw = await readBody2(req);
3318
+ let code;
3319
+ try {
3320
+ code = raw ? JSON.parse(raw)["code"] : void 0;
3321
+ } catch (e20) {
3322
+ writeErr(res, 400, "Invalid JSON in request body");
3323
+ return;
1867
3324
  }
1868
- return "default";
1869
- }
1870
- function endpointToIngressFormat(endpoint) {
1871
- switch (endpoint) {
1872
- case "chat":
1873
- return "openai-chat";
1874
- case "responses":
1875
- return "openai-responses";
1876
- case "messages":
1877
- return "anthropic-messages";
1878
- case "gemini":
1879
- return "gemini-generatecontent";
3325
+ if (typeof code !== "string" || !code.trim()) {
3326
+ writeErr(res, 400, "Missing redemption code");
3327
+ return;
1880
3328
  }
3329
+ const codeHash = hashVoucherCode(code.trim());
3330
+ const keyHash = hashKey(presentedKey.trim());
3331
+ const applyFirstPass = async (voucher, absolute) => {
3332
+ const ok = await deps.db.outboundApiKeysSetPolicy(verifiedKeyId, policyFrom(absolute));
3333
+ if (!ok) {
3334
+ await voucherDb.voucherRevertRedeem(voucher.id, verifiedKeyId);
3335
+ return { ok: false, status: 409, message: "Could not apply the grant \u2014 please retry" };
3336
+ }
3337
+ await voucherDb.voucherMarkGrantApplied(voucher.id);
3338
+ return { ok: true, result: grantToResult(voucher.type, absolute) };
3339
+ };
3340
+ const reconcileOne = async (voucher) => {
3341
+ const ok = await deps.db.outboundApiKeysSetPolicy(verifiedKeyId, policyFrom(recordedAbsolute(voucher)));
3342
+ if (ok) await voucherDb.voucherMarkGrantApplied(voucher.id);
3343
+ };
3344
+ const reconcileStranded = async () => {
3345
+ const all = await voucherDb.voucherList();
3346
+ const stranded = all.filter((v) => v.status === "redeemed" && v.grantApplied !== true && v.redeemedByKeyId === verifiedKeyId).sort((a, b) => (_nullishCoalesce(a.redeemedAt, () => ( 0))) - (_nullishCoalesce(b.redeemedAt, () => ( 0))));
3347
+ for (const v of stranded) await reconcileOne(v);
3348
+ };
3349
+ const runCritical = async () => {
3350
+ await reconcileStranded();
3351
+ const voucher = await voucherDb.voucherGetByHash(codeHash);
3352
+ if (!voucher || voucher.status === "revoked") {
3353
+ return { ok: false, status: 400, message: NOT_REDEEMABLE };
3354
+ }
3355
+ if (voucher.status === "redeemed") {
3356
+ if (voucher.redeemedByKeyId !== verifiedKeyId) {
3357
+ return { ok: false, status: 400, message: NOT_REDEEMABLE };
3358
+ }
3359
+ if (voucher.grantApplied === true) {
3360
+ const keyRow2 = await deps.db.outboundApiKeysGetByHash(keyHash);
3361
+ return { ok: true, result: currentResult(voucher.type, keyRow2) };
3362
+ }
3363
+ return await applyFirstPass(voucher, recordedAbsolute(voucher));
3364
+ }
3365
+ const keyRow = await deps.db.outboundApiKeysGetByHash(keyHash);
3366
+ const absolute = computeVoucherGrant(voucher, keyRow, now);
3367
+ const won = await voucherDb.voucherRedeemCas(voucher.id, verifiedKeyId, absolute, now);
3368
+ if (!won) {
3369
+ const after = await voucherDb.voucherGetByHash(codeHash);
3370
+ if (_optionalChain([after, 'optionalAccess', _127 => _127.status]) === "redeemed" && after.redeemedByKeyId === verifiedKeyId) {
3371
+ return after.grantApplied === true ? { ok: true, result: currentResult(after.type, await deps.db.outboundApiKeysGetByHash(keyHash)) } : await applyFirstPass(after, recordedAbsolute(after));
3372
+ }
3373
+ return { ok: false, status: 409, message: "Code was already redeemed" };
3374
+ }
3375
+ return await applyFirstPass(voucher, absolute);
3376
+ };
3377
+ const mutex = _nullishCoalesce(redeemMutex, () => ( getFallbackMutex()));
3378
+ const outcome = await mutex.runExclusive(verifiedKeyId, runCritical);
3379
+ if (outcome.ok) writeResult(res, outcome.result);
3380
+ else writeErr(res, outcome.status, outcome.message);
1881
3381
  }
1882
3382
 
1883
3383
  // src/outbound-api/outboundApiRouter.ts
3384
+ var fallbackRedeemLimiter = null;
3385
+ function getFallbackRedeemLimiter() {
3386
+ fallbackRedeemLimiter ??= new OutboundRateLimiter({ maxRequests: 10, windowMs: 6e4 });
3387
+ return fallbackRedeemLimiter;
3388
+ }
1884
3389
  function writeJsonError(res, status, message, headers = {}) {
1885
3390
  if (res.headersSent) return;
1886
3391
  res.writeHead(status, { "Content-Type": "application/json", ...headers });
1887
3392
  res.end(JSON.stringify({ error: { type: "outbound_api_error", message } }));
1888
3393
  }
3394
+ function writeCostLimitError(res, scope, limitUsd, spentUsd) {
3395
+ if (res.headersSent) return;
3396
+ res.writeHead(402, { "Content-Type": "application/json" });
3397
+ res.end(
3398
+ JSON.stringify({
3399
+ error: {
3400
+ type: "outbound_api_error",
3401
+ message: `Cost limit reached for this key (${scope}): $${spentUsd.toFixed(4)} of $${limitUsd.toFixed(4)}`
3402
+ },
3403
+ scope,
3404
+ limitUsd,
3405
+ spentUsd
3406
+ })
3407
+ );
3408
+ }
3409
+ function writeModelNotAllowedError(res, model, mode) {
3410
+ if (res.headersSent) return;
3411
+ res.writeHead(403, { "Content-Type": "application/json" });
3412
+ res.end(
3413
+ JSON.stringify({
3414
+ error: {
3415
+ type: "outbound_api_error",
3416
+ message: `Model '${model}' is not permitted for this key (${mode})`
3417
+ },
3418
+ model,
3419
+ mode
3420
+ })
3421
+ );
3422
+ }
1889
3423
  function extractPresentedKey(req) {
1890
3424
  const auth = req.headers["authorization"];
1891
3425
  if (typeof auth === "string" && auth.trim()) {
@@ -1894,14 +3428,14 @@ function extractPresentedKey(req) {
1894
3428
  }
1895
3429
  const xApiKey = req.headers["x-api-key"];
1896
3430
  const xApi = Array.isArray(xApiKey) ? xApiKey[0] : xApiKey;
1897
- if (_optionalChain([xApi, 'optionalAccess', _77 => _77.trim, 'call', _78 => _78()])) return xApi.trim();
3431
+ if (_optionalChain([xApi, 'optionalAccess', _128 => _128.trim, 'call', _129 => _129()])) return xApi.trim();
1898
3432
  const goog = req.headers["x-goog-api-key"];
1899
3433
  const g = Array.isArray(goog) ? goog[0] : goog;
1900
- return _optionalChain([g, 'optionalAccess', _79 => _79.trim, 'call', _80 => _80()]) || void 0;
3434
+ return _optionalChain([g, 'optionalAccess', _130 => _130.trim, 'call', _131 => _131()]) || void 0;
1901
3435
  }
1902
3436
  function selectEndpoint(method, url) {
1903
3437
  if (method !== "POST" || !url) return null;
1904
- const path = _nullishCoalesce(_optionalChain([url, 'access', _81 => _81.split, 'call', _82 => _82("?"), 'access', _83 => _83[0], 'optionalAccess', _84 => _84.replace, 'call', _85 => _85(/\/+$/, "")]), () => ( ""));
3438
+ const path = _nullishCoalesce(_optionalChain([url, 'access', _132 => _132.split, 'call', _133 => _133("?"), 'access', _134 => _134[0], 'optionalAccess', _135 => _135.replace, 'call', _136 => _136(/\/+$/, "")]), () => ( ""));
1905
3439
  if (path.endsWith("/chat/completions")) return "chat";
1906
3440
  if (path.endsWith("/responses")) return "responses";
1907
3441
  if (path.includes("/v1/messages")) return "messages";
@@ -1917,7 +3451,18 @@ function extractGeminiModelFromUrl(url) {
1917
3451
  const m = /\/models\/([^/:]+):(?:stream)?[gG]enerateContent$/.exec(path.replace(/\/+$/, ""));
1918
3452
  return m ? decodeURIComponent(m[1]) : void 0;
1919
3453
  }
1920
- function readBody2(req) {
3454
+ function isModelsListRequest(url) {
3455
+ if (!url) return false;
3456
+ const path = _nullishCoalesce(_optionalChain([url, 'access', _137 => _137.split, 'call', _138 => _138("?"), 'access', _139 => _139[0], 'optionalAccess', _140 => _140.replace, 'call', _141 => _141(/\/+$/, "")]), () => ( ""));
3457
+ return path.endsWith("/models");
3458
+ }
3459
+ function writeChatModelsList(res, config) {
3460
+ const chat = config.endpoints.find((e) => e.endpoint === "chat");
3461
+ const data = (_nullishCoalesce(_optionalChain([chat, 'optionalAccess', _142 => _142.models]), () => ( []))).map((ref) => _chunkSVXC36MUcjs.parseModelRef.call(void 0, ref)).filter((p) => p !== null).map((p) => ({ id: p.modelId, object: "model", owned_by: "omnicross" }));
3462
+ res.writeHead(200, { "Content-Type": "application/json" });
3463
+ res.end(JSON.stringify({ object: "list", data }));
3464
+ }
3465
+ function readBody3(req) {
1921
3466
  return new Promise((resolve, reject) => {
1922
3467
  const chunks = [];
1923
3468
  req.on("data", (chunk) => chunks.push(chunk));
@@ -1930,20 +3475,48 @@ function shimAuthHeader(req, routeToken) {
1930
3475
  delete req.headers["x-goog-api-key"];
1931
3476
  delete req.headers["x-api-key"];
1932
3477
  }
1933
- async function handleOutboundRequest(req, res, deps, config, rateLimiter) {
3478
+ async function handleOutboundRequest(req, res, deps, config, rateLimiter, serialQueue, concurrencyGate, redeemLimiter, redeemMutex) {
3479
+ const now = Date.now();
3480
+ const audit = beginAuditCapture(req, res, now);
3481
+ const billing = beginBillingCapture(req, res, now);
1934
3482
  const presented = extractPresentedKey(req);
1935
- const verified = await verifyPresentedKey(deps.db, presented);
1936
- if (!verified) {
1937
- writeJsonError(res, 401, "Invalid or missing API key");
3483
+ const verification = await verifyKey(deps.db, presented, now);
3484
+ if (verification.status !== "ok") {
3485
+ writeJsonError(
3486
+ res,
3487
+ 401,
3488
+ verification.status === "expired" ? "API key has expired" : "Invalid or missing API key"
3489
+ );
3490
+ return;
3491
+ }
3492
+ const verified = verification.key;
3493
+ if (audit) audit.keyId = verified.id;
3494
+ if (billing) billing.keyId = verified.id;
3495
+ if (isRedeemRequest(req.method, req.url)) {
3496
+ await handleVoucherRedeem(
3497
+ req,
3498
+ res,
3499
+ deps,
3500
+ _optionalChain([config, 'access', _143 => _143.voucher, 'optionalAccess', _144 => _144.enabled]) === true,
3501
+ _nullishCoalesce(redeemLimiter, () => ( getFallbackRedeemLimiter())),
3502
+ verified.id,
3503
+ _nullishCoalesce(presented, () => ( "")),
3504
+ now,
3505
+ redeemMutex
3506
+ );
1938
3507
  return;
1939
3508
  }
1940
- const decision = rateLimiter.check(verified.id);
3509
+ const decision = rateLimiter.check(verified.id, now, verified.rateLimit);
1941
3510
  if (!decision.allowed) {
1942
3511
  writeJsonError(res, 429, "Rate limit exceeded", {
1943
3512
  "Retry-After": String(decision.retryAfterSeconds)
1944
3513
  });
1945
3514
  return;
1946
3515
  }
3516
+ if (req.method === "GET" && isModelsListRequest(req.url)) {
3517
+ writeChatModelsList(res, config);
3518
+ return;
3519
+ }
1947
3520
  const endpoint = selectEndpoint(req.method, req.url);
1948
3521
  if (!endpoint) {
1949
3522
  writeJsonError(res, 404, `Unsupported: ${req.method} ${req.url}`);
@@ -1954,53 +3527,165 @@ async function handleOutboundRequest(req, res, deps, config, rateLimiter) {
1954
3527
  writeJsonError(res, 503, `endpoint '${endpoint}' is not configured`);
1955
3528
  return;
1956
3529
  }
1957
- const ingressFormat = endpointToIngressFormat(endpoint);
1958
- const rawBody = await readBody2(req);
1959
- let parsedBody = {};
1960
- try {
1961
- parsedBody = rawBody ? JSON.parse(rawBody) : {};
1962
- } catch (e12) {
1963
- writeJsonError(res, 400, "Invalid JSON in request body");
1964
- return;
1965
- }
1966
- if (endpoint === "gemini" && typeof parsedBody["model"] !== "string") {
1967
- const urlModel = extractGeminiModelFromUrl(req.url);
1968
- if (urlModel) parsedBody["model"] = urlModel;
3530
+ if (verified.costLimits && deps.keySpendTracker) {
3531
+ const spend = await deps.keySpendTracker.getSpend(verified.id, now);
3532
+ const quota = checkKeyQuota(verified.costLimits, spend);
3533
+ if (!quota.allowed) {
3534
+ emitWebhookEvent({
3535
+ kind: "key.quotaExceeded",
3536
+ at: now,
3537
+ keyId: verified.id,
3538
+ scope: quota.scope,
3539
+ limitUsd: quota.limitUsd,
3540
+ spentUsd: quota.spentUsd
3541
+ });
3542
+ writeCostLimitError(res, quota.scope, quota.limitUsd, quota.spentUsd);
3543
+ return;
3544
+ }
3545
+ for (const warn of computeQuotaWarnings(verified.costLimits, spend)) {
3546
+ if (markQuotaWarnedOnce(verified.id, warn.scope, warn.windowStart)) {
3547
+ emitWebhookEvent({
3548
+ kind: "key.quotaWarning",
3549
+ at: now,
3550
+ keyId: verified.id,
3551
+ scope: warn.scope,
3552
+ limitUsd: warn.limitUsd,
3553
+ spentUsd: warn.spentUsd
3554
+ });
3555
+ }
3556
+ }
1969
3557
  }
1970
- const role = detectRequestRole(ingressFormat, parsedBody, {
1971
- backgroundModelIds: endpointConfig.backgroundModelIds
1972
- });
1973
- const resolved = await _chunkG2FUJNA2cjs.resolveRoute.call(void 0, {
1974
- config: endpointConfig,
1975
- role,
1976
- ingressFormat,
1977
- llmConfig: deps.llmConfig,
1978
- // pool-seam (omnicross-daemon-parity-poolseam, design D1/D2(a)): synthesize a
1979
- // STABLE per-verified-key sessionId so the BYO ingress can seed a pool session
1980
- // binding and 429/529/401/403 failover actually fires. Synthesize ONLY when
1981
- // the pool is wired — pool-null embedders/tests keep `route.sessionId === null`
1982
- // (byte-identical to pre-seam). The `outbound:` prefix is namespace-isolated
1983
- // from real chat-session ids; `verified.id` is a small operator-controlled set,
1984
- // so `sessionBindings` stays bounded (one binding per named key, not per
1985
- // request — `sessionBindings` has no TTL).
1986
- sessionId: deps.proxyDeps.apiKeyPool ? `outbound:${verified.id}` : null
1987
- });
1988
- if (!resolved.ok) {
1989
- writeJsonError(res, resolved.error.status, resolved.error.message);
1990
- return;
3558
+ const concurrencyLimit = verified.maxConcurrency;
3559
+ let releaseConcurrency = null;
3560
+ if (typeof concurrencyLimit === "number" && concurrencyLimit > 0) {
3561
+ const cq = _nullishCoalesce(config.concurrencyQueue, () => ( DEFAULT_CONCURRENCY_QUEUE));
3562
+ const acquisition = concurrencyGate.acquire(verified.id, concurrencyLimit, {
3563
+ maxQueueSizeFactor: cq.maxQueueSizeFactor,
3564
+ minQueueSize: cq.minQueueSize,
3565
+ waitTimeoutMs: cq.waitTimeoutMs
3566
+ });
3567
+ const cancelOnClose = () => acquisition.cancel();
3568
+ res.once("close", cancelOnClose);
3569
+ let slot;
3570
+ try {
3571
+ slot = await acquisition.granted;
3572
+ } catch (err) {
3573
+ res.removeListener("close", cancelOnClose);
3574
+ if (isConcurrencyRejection(err)) {
3575
+ writeJsonError(res, 429, "Concurrency limit exceeded", { "Retry-After": "5" });
3576
+ return;
3577
+ }
3578
+ throw err;
3579
+ }
3580
+ res.removeListener("close", cancelOnClose);
3581
+ const release2 = () => slot.release();
3582
+ releaseConcurrency = release2;
3583
+ res.once("close", release2);
1991
3584
  }
1992
- const routeMap = deps.providerProxy.getRouteMap();
1993
- const token = routeMap.addRoute(resolved.route);
1994
3585
  try {
1995
- shimAuthHeader(req, token);
1996
- const replay = makeReplayRequest(req, rawBody);
1997
- await routeRequest(replay, res, routeMap, deps.proxyDeps);
1998
- } catch (err) {
1999
- const message = _chunkSVNDB62Dcjs.serializeError.call(void 0, err);
2000
- console.error("[OutboundApi] dispatch error:", message);
2001
- writeJsonError(res, 502, message);
3586
+ const ingressFormat = _chunkSVXC36MUcjs.endpointToIngressFormat.call(void 0, endpoint);
3587
+ const rawBody = await readBody3(req);
3588
+ let parsedBody = {};
3589
+ try {
3590
+ parsedBody = rawBody ? JSON.parse(rawBody) : {};
3591
+ } catch (e21) {
3592
+ writeJsonError(res, 400, "Invalid JSON in request body");
3593
+ return;
3594
+ }
3595
+ if (audit) audit.setRequestBody(rawBody);
3596
+ if (endpoint === "gemini" && typeof parsedBody["model"] !== "string") {
3597
+ const urlModel = extractGeminiModelFromUrl(req.url);
3598
+ if (urlModel) parsedBody["model"] = urlModel;
3599
+ }
3600
+ const sessionId = deps.proxyDeps.apiKeyPool ? `outbound:${verified.id}` : null;
3601
+ const resolved = _chunkSVXC36MUcjs.isKindMappedEndpoint.call(void 0, endpoint) || endpoint === "chat" ? await _chunkSVXC36MUcjs.resolveRoute.call(void 0, {
3602
+ config: endpointConfig,
3603
+ ingressFormat,
3604
+ llmConfig: deps.llmConfig,
3605
+ sessionId,
3606
+ // Capture the ORIGINAL requested id BEFORE any downstream swap; for
3607
+ // kind-mapped endpoints it selects the kind AND is stamped onto
3608
+ // `route.requestedModel`; for chat it is matched against the list.
3609
+ requestedModel: _chunkSVXC36MUcjs.extractRequestedModel.call(void 0, ingressFormat, parsedBody),
3610
+ // Attribution: stamp the verified named-key id onto the route.
3611
+ apiKeyId: verified.id
3612
+ }) : await _chunkSVXC36MUcjs.resolveRoute.call(void 0, {
3613
+ config: endpointConfig,
3614
+ role: _chunkSVXC36MUcjs.detectRequestRole.call(void 0, ingressFormat, parsedBody, {
3615
+ backgroundModelIds: endpointConfig.backgroundModelIds
3616
+ }),
3617
+ ingressFormat,
3618
+ llmConfig: deps.llmConfig,
3619
+ sessionId,
3620
+ // Attribution: stamp the verified named-key id onto the route.
3621
+ apiKeyId: verified.id
3622
+ });
3623
+ if (!resolved.ok) {
3624
+ writeJsonError(res, resolved.error.status, resolved.error.message);
3625
+ return;
3626
+ }
3627
+ if (audit) {
3628
+ audit.model = resolved.route.model;
3629
+ audit.provider = resolved.route.providerId;
3630
+ }
3631
+ if (billing) {
3632
+ billing.model = resolved.route.model;
3633
+ billing.provider = resolved.route.providerId;
3634
+ billing.authMode = resolved.route.authMode;
3635
+ }
3636
+ if (verified.modelRestriction) {
3637
+ const modelDecision = checkModelAllowed(verified.modelRestriction, resolved.route.model);
3638
+ if (!modelDecision.allowed) {
3639
+ writeModelNotAllowedError(res, modelDecision.model, verified.modelRestriction.mode);
3640
+ return;
3641
+ }
3642
+ }
3643
+ let releaseSerial = null;
3644
+ const providerKey = resolved.route.providerId;
3645
+ if (_optionalChain([config, 'access', _145 => _145.userMessageQueue, 'optionalAccess', _146 => _146.enabled]) && providerKey && isUserMessageRequest(endpoint, parsedBody)) {
3646
+ const umq = config.userMessageQueue;
3647
+ try {
3648
+ const serialSlot = await serialQueue.acquire(providerKey, {
3649
+ waitTimeoutMs: umq.waitTimeoutMs,
3650
+ delayMs: umq.delayMs
3651
+ });
3652
+ releaseSerial = () => serialSlot.release();
3653
+ } catch (err) {
3654
+ if (isSerialQueueTimeout(err)) {
3655
+ writeJsonError(res, 503, "User-message serial queue wait timed out");
3656
+ return;
3657
+ }
3658
+ throw err;
3659
+ }
3660
+ }
3661
+ if (releaseSerial) {
3662
+ const original = res.writeHead.bind(res);
3663
+ const releaseOnce = releaseSerial;
3664
+ res.writeHead = ((...args) => {
3665
+ res.writeHead = original;
3666
+ releaseOnce();
3667
+ return original(...args);
3668
+ });
3669
+ }
3670
+ const routeMap = deps.providerProxy.getRouteMap();
3671
+ const token = routeMap.addRoute(resolved.route);
3672
+ try {
3673
+ shimAuthHeader(req, token);
3674
+ const replay = makeReplayRequest(req, rawBody);
3675
+ await routeRequest(replay, res, routeMap, deps.proxyDeps);
3676
+ } catch (err) {
3677
+ const message = _chunkSVNDB62Dcjs.serializeError.call(void 0, err);
3678
+ if (deps.logger) deps.logger.error("[OutboundApi] dispatch error:", message);
3679
+ else console.error("[OutboundApi] dispatch error:", message);
3680
+ emitWebhookEvent({ kind: "server.error", at: Date.now(), message });
3681
+ if (audit) audit.error = message;
3682
+ writeJsonError(res, 502, message);
3683
+ } finally {
3684
+ routeMap.removeRoute(token);
3685
+ if (releaseSerial) releaseSerial();
3686
+ }
2002
3687
  } finally {
2003
- routeMap.removeRoute(token);
3688
+ if (releaseConcurrency) releaseConcurrency();
2004
3689
  }
2005
3690
  }
2006
3691
  function makeReplayRequest(req, rawBody) {
@@ -2014,65 +3699,50 @@ function makeReplayRequest(req, rawBody) {
2014
3699
  return readable;
2015
3700
  }
2016
3701
 
2017
- // src/outbound-api/outboundRateLimiter.ts
2018
- var DEFAULT_WINDOW_MS = 6e4;
2019
- var DEFAULT_MAX_REQUESTS = 60;
2020
- var OutboundRateLimiter = (_class3 = class {
2021
-
2022
-
2023
- /** apiKeyId → ascending request timestamps within the current window. */
2024
- __init4() {this.hits = /* @__PURE__ */ new Map()}
2025
- constructor(options = {}) {;_class3.prototype.__init4.call(this);
2026
- this.windowMs = _nullishCoalesce(options.windowMs, () => ( DEFAULT_WINDOW_MS));
2027
- this.maxRequests = _nullishCoalesce(options.maxRequests, () => ( DEFAULT_MAX_REQUESTS));
2028
- }
2029
- /**
2030
- * Record a request for `apiKeyId` and decide whether it is allowed. Prunes
2031
- * timestamps older than the window first; when allowed, the request's
2032
- * timestamp is appended.
2033
- */
2034
- check(apiKeyId, now = Date.now()) {
2035
- const cutoff = now - this.windowMs;
2036
- const timestamps = (_nullishCoalesce(this.hits.get(apiKeyId), () => ( []))).filter((ts) => ts > cutoff);
2037
- if (timestamps.length >= this.maxRequests) {
2038
- if (timestamps.length === 0) {
2039
- this.hits.delete(apiKeyId);
2040
- return { allowed: false, retryAfterSeconds: Math.max(1, Math.ceil(this.windowMs / 1e3)) };
2041
- }
2042
- const oldest = timestamps[0];
2043
- const retryAfterMs = Math.max(0, oldest + this.windowMs - now);
2044
- this.hits.set(apiKeyId, timestamps);
2045
- return {
2046
- allowed: false,
2047
- retryAfterSeconds: Math.max(1, Math.ceil(retryAfterMs / 1e3))
2048
- };
2049
- }
2050
- timestamps.push(now);
2051
- this.hits.set(apiKeyId, timestamps);
2052
- return { allowed: true, retryAfterSeconds: 0 };
2053
- }
2054
- /** Drop all recorded state (tests / teardown). */
2055
- reset() {
2056
- this.hits.clear();
2057
- }
2058
- }, _class3);
2059
-
2060
3702
  // src/outbound-api/OutboundApiServer.ts
2061
3703
  var DEFAULT_OUTBOUND_PORT = 8765;
2062
3704
  var LOOPBACK_ADDR = "127.0.0.1";
2063
3705
  var LAN_ADDR = "0.0.0.0";
2064
- var OutboundApiServer = (_class4 = class {
2065
- constructor(deps, onPortChange) {;_class4.prototype.__init5.call(this);_class4.prototype.__init6.call(this);_class4.prototype.__init7.call(this);_class4.prototype.__init8.call(this);_class4.prototype.__init9.call(this);
3706
+ var OutboundApiConfigError = class extends Error {
3707
+
3708
+ constructor(missing) {
3709
+ super(
3710
+ "Outbound API server cannot start: incomplete model-kind configuration \u2014 " + missing.map((m) => `${m.endpoint} missing [${m.missingKinds.join(", ")}]`).join("; ")
3711
+ );
3712
+ this.name = "OutboundApiConfigError";
3713
+ this.missing = missing;
3714
+ }
3715
+ };
3716
+ var OutboundApiServer = (_class11 = class {
3717
+ constructor(deps, onPortChange) {;_class11.prototype.__init12.call(this);_class11.prototype.__init13.call(this);_class11.prototype.__init14.call(this);_class11.prototype.__init15.call(this);_class11.prototype.__init16.call(this);_class11.prototype.__init17.call(this);_class11.prototype.__init18.call(this);_class11.prototype.__init19.call(this);_class11.prototype.__init20.call(this);
2066
3718
  this.deps = deps;
2067
3719
  this.onPortChange = onPortChange;
2068
3720
  }
2069
3721
 
2070
3722
 
2071
- __init5() {this.server = null}
2072
- __init6() {this.boundPort = 0}
2073
- __init7() {this.boundAddr = LOOPBACK_ADDR}
2074
- __init8() {this.endpoints = []}
2075
- __init9() {this.rateLimiter = new OutboundRateLimiter()}
3723
+ __init12() {this.server = null}
3724
+ __init13() {this.boundPort = 0}
3725
+ __init14() {this.boundAddr = LOOPBACK_ADDR}
3726
+ __init15() {this.endpoints = []}
3727
+
3728
+
3729
+
3730
+ __init16() {this.rateLimiter = new OutboundRateLimiter()}
3731
+ /**
3732
+ * Redeem-attempt limiter (voucher-redemption #9, design D6) — a SEPARATE bucket
3733
+ * from the traffic `rateLimiter`, keyed by the authenticating key id, so
3734
+ * brute-forcing `CC_` codes is throttled (a handful/min) without touching the
3735
+ * per-key request rate. Conservative fixed defaults (10 / 60s).
3736
+ */
3737
+ __init17() {this.redeemLimiter = new OutboundRateLimiter({ maxRequests: 10, windowMs: 6e4 })}
3738
+ /**
3739
+ * Per-key redeem mutex (voucher-redemption #9, MJ1 fix). One instance for the
3740
+ * server's lifetime so concurrent redeem REQUESTS for the same key serialize
3741
+ * (relative grant increments accumulate instead of clobbering a snapshot).
3742
+ */
3743
+ __init18() {this.redeemMutex = new KeyedMutex()}
3744
+ __init19() {this.serialQueue = new UserMessageSerialQueue()}
3745
+ __init20() {this.concurrencyGate = new OutboundConcurrencyGate()}
2076
3746
  /**
2077
3747
  * Apply a config. Restarts the listener ONLY when the bind address or port
2078
3748
  * changes (or when toggling enabled); per-endpoint routing config is updated
@@ -2080,12 +3750,25 @@ var OutboundApiServer = (_class4 = class {
2080
3750
  */
2081
3751
  async applyConfig(input) {
2082
3752
  this.endpoints = input.endpoints;
3753
+ this.userMessageQueue = input.userMessageQueue;
3754
+ this.concurrencyQueue = input.concurrencyQueue;
3755
+ this.voucherConfig = input.voucher;
2083
3756
  const wantAddr = input.networkBinding ? LAN_ADDR : LOOPBACK_ADDR;
2084
3757
  const wantPort = _nullishCoalesce(input.port, () => ( DEFAULT_OUTBOUND_PORT));
2085
3758
  if (!input.enabled) {
2086
3759
  await this.stop();
2087
3760
  return;
2088
3761
  }
3762
+ const missing = _chunkSVXC36MUcjs.validateServerModelConfig.call(void 0, {
3763
+ enabled: true,
3764
+ networkBinding: input.networkBinding,
3765
+ endpoints: input.endpoints,
3766
+ port: input.port
3767
+ });
3768
+ if (missing.length > 0) {
3769
+ await this.stop();
3770
+ throw new OutboundApiConfigError(missing);
3771
+ }
2089
3772
  const running = this.server !== null;
2090
3773
  const bindChanged = running && (this.boundAddr !== wantAddr || this.boundPort !== wantPort);
2091
3774
  if (running && !bindChanged) {
@@ -2100,8 +3783,8 @@ var OutboundApiServer = (_class4 = class {
2100
3783
  const actualPort = await this.listen(bindAddr, port);
2101
3784
  this.boundAddr = bindAddr;
2102
3785
  this.boundPort = actualPort;
2103
- if (actualPort !== port) _optionalChain([this, 'access', _86 => _86.onPortChange, 'optionalCall', _87 => _87(actualPort)]);
2104
- console.log(`[OutboundApiServer] Listening on ${bindAddr}:${actualPort}`);
3786
+ if (actualPort !== port) _optionalChain([this, 'access', _147 => _147.onPortChange, 'optionalCall', _148 => _148(actualPort)]);
3787
+ this.logInfo(`[OutboundApiServer] Listening on ${bindAddr}:${actualPort}`);
2105
3788
  return actualPort;
2106
3789
  }
2107
3790
  /** Bind once; on EADDRINUSE retry with an ephemeral port (port 0). */
@@ -2123,7 +3806,7 @@ var OutboundApiServer = (_class4 = class {
2123
3806
  const addr = server.address();
2124
3807
  if (addr && typeof addr === "object") {
2125
3808
  server.removeListener("error", onError);
2126
- server.on("error", (e) => console.error("[OutboundApiServer] server error", _chunkSVNDB62Dcjs.serializeError.call(void 0, e)));
3809
+ server.on("error", (e) => this.logError("[OutboundApiServer] server error", _chunkSVNDB62Dcjs.serializeError.call(void 0, e)));
2127
3810
  this.server = server;
2128
3811
  resolve(addr.port);
2129
3812
  } else {
@@ -2134,21 +3817,58 @@ var OutboundApiServer = (_class4 = class {
2134
3817
  }
2135
3818
  /** Per-request handler. Auth is enforced on EVERY request (incl. loopback). */
2136
3819
  onRequest(req, res) {
3820
+ if (this.deps.healthReportProvider && this.tryServeHealth(req, res)) return;
2137
3821
  handleOutboundRequest(
2138
3822
  req,
2139
3823
  res,
2140
3824
  this.deps,
2141
- { endpoints: this.endpoints },
2142
- this.rateLimiter
3825
+ {
3826
+ endpoints: this.endpoints,
3827
+ userMessageQueue: this.userMessageQueue,
3828
+ concurrencyQueue: this.concurrencyQueue,
3829
+ voucher: this.voucherConfig
3830
+ },
3831
+ this.rateLimiter,
3832
+ this.serialQueue,
3833
+ this.concurrencyGate,
3834
+ this.redeemLimiter,
3835
+ this.redeemMutex
2143
3836
  ).catch((err) => {
2144
3837
  const message = _chunkSVNDB62Dcjs.serializeError.call(void 0, err);
2145
- console.error("[OutboundApiServer] unhandled error:", message);
3838
+ this.logError("[OutboundApiServer] unhandled error:", message);
2146
3839
  if (!res.headersSent) {
2147
3840
  res.writeHead(500, { "Content-Type": "application/json" });
2148
3841
  res.end(JSON.stringify({ error: { type: "outbound_api_error", message } }));
2149
3842
  }
2150
3843
  });
2151
3844
  }
3845
+ /**
3846
+ * Serve `GET|HEAD /health` (+ `/healthz`) from the injected provider, returning
3847
+ * true when it handled the request. 200 when `ok`, else 503; secret-free body.
3848
+ */
3849
+ tryServeHealth(req, res) {
3850
+ const provider = this.deps.healthReportProvider;
3851
+ if (!provider) return false;
3852
+ if (req.method !== "GET" && req.method !== "HEAD") return false;
3853
+ const path = _optionalChain([(_nullishCoalesce(req.url, () => ( "/"))), 'access', _149 => _149.split, 'call', _150 => _150("?"), 'access', _151 => _151[0], 'optionalAccess', _152 => _152.replace, 'call', _153 => _153(/\/+$/, "")]) || "/";
3854
+ if (path !== "/health" && path !== "/healthz") return false;
3855
+ const report = provider();
3856
+ res.writeHead(_healthloggingtypes.healthHttpStatus.call(void 0, report.status), { "Content-Type": "application/json" });
3857
+ res.end(req.method === "HEAD" ? void 0 : JSON.stringify(report));
3858
+ return true;
3859
+ }
3860
+ /** Route an info lifecycle line through the injected logger, else `console.log`
3861
+ * (byte-identical legacy fallback when no logger is wired). */
3862
+ logInfo(message) {
3863
+ if (this.deps.logger) this.deps.logger.info(message);
3864
+ else console.log(message);
3865
+ }
3866
+ /** Route an error lifecycle line through the injected logger, else `console.error`. */
3867
+ logError(message, detail) {
3868
+ if (this.deps.logger) this.deps.logger.error(message, detail);
3869
+ else if (detail === void 0) console.error(message);
3870
+ else console.error(message, detail);
3871
+ }
2152
3872
  /** Stop the listener and release the port. */
2153
3873
  async stop() {
2154
3874
  const server = this.server;
@@ -2157,7 +3877,7 @@ var OutboundApiServer = (_class4 = class {
2157
3877
  this.boundPort = 0;
2158
3878
  return new Promise((resolve) => {
2159
3879
  server.close(() => {
2160
- console.log("[OutboundApiServer] Stopped");
3880
+ this.logInfo("[OutboundApiServer] Stopped");
2161
3881
  resolve();
2162
3882
  });
2163
3883
  });
@@ -2189,7 +3909,18 @@ var OutboundApiServer = (_class4 = class {
2189
3909
  lanFormats: lanBase ? formatUrls(lanBase) : null
2190
3910
  };
2191
3911
  }
2192
- }, _class4);
3912
+ /**
3913
+ * Live queue-occupancy snapshot (only active entries). This getter's name +
3914
+ * shape are FROZEN — `omnicross-uqc-daemon` spreads it into its `/status`
3915
+ * response; the existing {@link getStatus} shape is deliberately NOT changed.
3916
+ */
3917
+ getQueueStatus() {
3918
+ return {
3919
+ serial: this.serialQueue.getStatus(),
3920
+ concurrency: this.concurrencyGate.getStatus()
3921
+ };
3922
+ }
3923
+ }, _class11);
2193
3924
  function formatUrls(base) {
2194
3925
  return {
2195
3926
  chat: `${base}/v1/chat/completions`,
@@ -2209,66 +3940,88 @@ function firstLanIPv4() {
2209
3940
  return null;
2210
3941
  }
2211
3942
 
2212
- // src/outbound-api/apiServerConfig.ts
2213
- var OUTBOUND_API_SERVER_CONFIG_KEY = "outboundApiServer.config";
2214
- var ALL_ENDPOINTS = ["chat", "responses", "messages", "gemini"];
2215
- function defaultEndpointConfig(endpoint) {
2216
- return {
2217
- endpoint,
2218
- defaultModel: "",
2219
- backgroundModel: "",
2220
- useSubscription: false
2221
- };
3943
+ // src/outbound-api/keySpendTracker.ts
3944
+ function startOfLocalDay(ts) {
3945
+ const d = new Date(ts);
3946
+ return new Date(d.getFullYear(), d.getMonth(), d.getDate()).getTime();
2222
3947
  }
2223
- function defaultServerConfig() {
2224
- return {
2225
- enabled: false,
2226
- networkBinding: false,
2227
- endpoints: ALL_ENDPOINTS.map(defaultEndpointConfig),
2228
- port: DEFAULT_OUTBOUND_PORT
2229
- };
3948
+ function startOfLocalWeek(ts) {
3949
+ const d = new Date(ts);
3950
+ const day = new Date(d.getFullYear(), d.getMonth(), d.getDate());
3951
+ day.setDate(day.getDate() - day.getDay());
3952
+ return day.getTime();
2230
3953
  }
2231
- function normalizeServerConfig(raw) {
2232
- const base = defaultServerConfig();
2233
- if (!raw) return base;
2234
- const byEndpoint = /* @__PURE__ */ new Map();
2235
- for (const e of _nullishCoalesce(raw.endpoints, () => ( []))) {
2236
- if (e && ALL_ENDPOINTS.includes(e.endpoint)) {
2237
- byEndpoint.set(e.endpoint, {
2238
- endpoint: e.endpoint,
2239
- defaultModel: _nullishCoalesce(e.defaultModel, () => ( "")),
2240
- backgroundModel: _nullishCoalesce(e.backgroundModel, () => ( "")),
2241
- visionModel: e.visionModel,
2242
- useSubscription: e.useSubscription === true,
2243
- backgroundModelIds: e.backgroundModelIds
2244
- });
3954
+ var KeySpendTracker = (_class12 = class {
3955
+ constructor(seeder) {;_class12.prototype.__init21.call(this);
3956
+ this.seeder = seeder;
3957
+ }
3958
+
3959
+ /** apiKeyId live accumulated spend (seeded lazily). */
3960
+ __init21() {this.spend = /* @__PURE__ */ new Map()}
3961
+ /**
3962
+ * Read the key's accumulated spend, seeding from the durable store on a cache
3963
+ * miss and rolling the daily/weekly windows on a hit.
3964
+ */
3965
+ async getSpend(apiKeyId, now) {
3966
+ const existing = this.spend.get(apiKeyId);
3967
+ if (existing) {
3968
+ rollWindows(existing, now);
3969
+ return existing;
2245
3970
  }
3971
+ const seeded = await this.seed(apiKeyId, now);
3972
+ const existingAfterSeed = this.spend.get(apiKeyId);
3973
+ if (existingAfterSeed) {
3974
+ rollWindows(existingAfterSeed, now);
3975
+ return existingAfterSeed;
3976
+ }
3977
+ this.spend.set(apiKeyId, seeded);
3978
+ return seeded;
3979
+ }
3980
+ /**
3981
+ * Increment the aggregate for one recorded request. No-op when the key has not
3982
+ * been seeded yet — a later `getSpend` will lazy-seed from the durable store,
3983
+ * which already includes this record, so it is neither lost nor double-counted.
3984
+ */
3985
+ add(apiKeyId, costUsd, now) {
3986
+ const s = this.spend.get(apiKeyId);
3987
+ if (!s) return;
3988
+ rollWindows(s, now);
3989
+ s.dailyUsd += costUsd;
3990
+ s.weeklyUsd += costUsd;
3991
+ s.totalUsd += costUsd;
3992
+ }
3993
+ /** Drop all cached spend (tests / teardown). */
3994
+ reset() {
3995
+ this.spend.clear();
3996
+ }
3997
+ /**
3998
+ * Derive a fresh spend snapshot for `apiKeyId` from the durable store in a
3999
+ * SINGLE scan (all three windows at once). `endTs` is EXCLUSIVE, so `now + 1`
4000
+ * includes a record stamped at exactly `now`.
4001
+ */
4002
+ async seed(apiKeyId, now) {
4003
+ const dailyWindowStart = startOfLocalDay(now);
4004
+ const weeklyWindowStart = startOfLocalWeek(now);
4005
+ const { totalUsd, dailyUsd, weeklyUsd } = await this.seeder.getSpendByKey({
4006
+ apiKeyId,
4007
+ dayStartTs: dailyWindowStart,
4008
+ weekStartTs: weeklyWindowStart,
4009
+ endTs: now + 1
4010
+ });
4011
+ return { dailyUsd, dailyWindowStart, weeklyUsd, weeklyWindowStart, totalUsd };
4012
+ }
4013
+ }, _class12);
4014
+ function rollWindows(s, now) {
4015
+ const day = startOfLocalDay(now);
4016
+ if (s.dailyWindowStart !== day) {
4017
+ s.dailyUsd = 0;
4018
+ s.dailyWindowStart = day;
4019
+ }
4020
+ const week = startOfLocalWeek(now);
4021
+ if (s.weeklyWindowStart !== week) {
4022
+ s.weeklyUsd = 0;
4023
+ s.weeklyWindowStart = week;
2246
4024
  }
2247
- return {
2248
- enabled: raw.enabled === true,
2249
- networkBinding: raw.networkBinding === true,
2250
- endpoints: ALL_ENDPOINTS.map(
2251
- (ep) => _nullishCoalesce(byEndpoint.get(ep), () => ( defaultEndpointConfig(ep)))
2252
- ),
2253
- port: _nullishCoalesce(raw.port, () => ( base.port))
2254
- };
2255
- }
2256
- async function loadServerConfig(store) {
2257
- const raw = await store.get(
2258
- OUTBOUND_API_SERVER_CONFIG_KEY
2259
- );
2260
- return normalizeServerConfig(raw);
2261
- }
2262
- async function saveServerConfig(store, config) {
2263
- await store.set(OUTBOUND_API_SERVER_CONFIG_KEY, config);
2264
- }
2265
- function mergeServerConfig(current, patch) {
2266
- return normalizeServerConfig({
2267
- enabled: _nullishCoalesce(patch.enabled, () => ( current.enabled)),
2268
- networkBinding: _nullishCoalesce(patch.networkBinding, () => ( current.networkBinding)),
2269
- endpoints: _nullishCoalesce(patch.endpoints, () => ( current.endpoints)),
2270
- port: _nullishCoalesce(patch.port, () => ( current.port))
2271
- });
2272
4025
  }
2273
4026
 
2274
4027
  // src/outbound-api/index.ts
@@ -2304,7 +4057,7 @@ async function callOpenAICompletion(provider, apiKey, options, logger) {
2304
4057
  }
2305
4058
  }
2306
4059
  const apiUrl = _chunkA2YMUCBTcjs.buildProviderApiUrl.call(void 0, provider, { model: options.model, stream: false });
2307
- const headers = _chunkLKZJEL6Ecjs.getProviderHeaders.call(void 0, provider, apiKey);
4060
+ const headers = _chunkQ27JY5RGcjs.getProviderHeaders.call(void 0, provider, apiKey);
2308
4061
  logger.info("Calling OpenAI completion API", { url: apiUrl, model: options.model });
2309
4062
  const response = await fetch(apiUrl, {
2310
4063
  method: "POST",
@@ -2350,7 +4103,7 @@ async function callAnthropicCompletion(provider, apiKey, options, logger) {
2350
4103
  stream: false
2351
4104
  };
2352
4105
  const apiUrl2 = _chunkA2YMUCBTcjs.buildProviderApiUrl.call(void 0, provider, { model: options.model, stream: false });
2353
- const headers2 = _chunkLKZJEL6Ecjs.getProviderHeaders.call(void 0, provider, apiKey);
4106
+ const headers2 = _chunkQ27JY5RGcjs.getProviderHeaders.call(void 0, provider, apiKey);
2354
4107
  logger.info("Calling Anthropic completion API with images", { url: apiUrl2, model: options.model });
2355
4108
  const response2 = await fetch(apiUrl2, {
2356
4109
  method: "POST",
@@ -2372,7 +4125,7 @@ async function callAnthropicCompletion(provider, apiKey, options, logger) {
2372
4125
  message: {
2373
4126
  id: `assistant-${Date.now()}`,
2374
4127
  role: "assistant",
2375
- content: _optionalChain([choice2, 'access', _88 => _88.message, 'optionalAccess', _89 => _89.content]) || "",
4128
+ content: _optionalChain([choice2, 'access', _154 => _154.message, 'optionalAccess', _155 => _155.content]) || "",
2376
4129
  timestamp: Date.now()
2377
4130
  },
2378
4131
  usage: openaiResponse2.usage ? {
@@ -2398,7 +4151,7 @@ async function callAnthropicCompletion(provider, apiKey, options, logger) {
2398
4151
  };
2399
4152
  const anthropicRequest = _chunkSUEGJ75Dcjs.convertOpenAIToAnthropic.call(void 0, openaiRequest, config);
2400
4153
  const apiUrl = _chunkA2YMUCBTcjs.buildProviderApiUrl.call(void 0, provider, { model: options.model, stream: false });
2401
- const headers = _chunkLKZJEL6Ecjs.getProviderHeaders.call(void 0, provider, apiKey);
4154
+ const headers = _chunkQ27JY5RGcjs.getProviderHeaders.call(void 0, provider, apiKey);
2402
4155
  logger.info("Calling Anthropic completion API", { url: apiUrl, model: options.model });
2403
4156
  const response = await fetch(apiUrl, {
2404
4157
  method: "POST",
@@ -2452,7 +4205,7 @@ async function callGeminiCompletion(provider, apiKey, options, logger) {
2452
4205
  request.systemInstruction = systemInstruction;
2453
4206
  }
2454
4207
  const apiUrl = _chunkA2YMUCBTcjs.buildProviderApiUrl.call(void 0, provider, { model: options.model, stream: false });
2455
- const headers = _chunkLKZJEL6Ecjs.getProviderHeaders.call(void 0, provider, apiKey);
4208
+ const headers = _chunkQ27JY5RGcjs.getProviderHeaders.call(void 0, provider, apiKey);
2456
4209
  logger.info("Calling Gemini completion API", { url: apiUrl, model: options.model });
2457
4210
  const response = await fetch(apiUrl, {
2458
4211
  method: "POST",
@@ -2477,7 +4230,7 @@ async function callGeminiCompletion(provider, apiKey, options, logger) {
2477
4230
  const candidate = candidates[0];
2478
4231
  const content = candidate.content;
2479
4232
  let textContent = "";
2480
- if (_optionalChain([content, 'optionalAccess', _90 => _90.parts])) {
4233
+ if (_optionalChain([content, 'optionalAccess', _156 => _156.parts])) {
2481
4234
  for (const part of content.parts) {
2482
4235
  if (part.text) {
2483
4236
  textContent += part.text;
@@ -2523,7 +4276,7 @@ async function callOpenAIResponseCompletion(provider, apiKey, options, logger) {
2523
4276
  }
2524
4277
  }
2525
4278
  const apiUrl = _chunkA2YMUCBTcjs.buildProviderApiUrl.call(void 0, provider, { model: options.model, stream: false });
2526
- const headers = _chunkLKZJEL6Ecjs.getProviderHeaders.call(void 0, provider, apiKey);
4279
+ const headers = _chunkQ27JY5RGcjs.getProviderHeaders.call(void 0, provider, apiKey);
2527
4280
  logger.info("Calling OpenAI Response API", { url: apiUrl, model: options.model });
2528
4281
  const response = await fetch(apiUrl, {
2529
4282
  method: "POST",
@@ -2589,9 +4342,9 @@ async function streamOpenAICompletion(provider, apiKey, options, messageId, call
2589
4342
  }
2590
4343
  }
2591
4344
  const apiUrl = _chunkA2YMUCBTcjs.buildProviderApiUrl.call(void 0, provider, { model: options.model, stream: true });
2592
- const headers = _chunkLKZJEL6Ecjs.getProviderHeaders.call(void 0, provider, apiKey);
4345
+ const headers = _chunkQ27JY5RGcjs.getProviderHeaders.call(void 0, provider, apiKey);
2593
4346
  if (options.nativeSearchAugmentation) {
2594
- _chunkV5KPWNYXcjs.applyAugmentation.call(void 0, request, options.nativeSearchAugmentation);
4347
+ _chunkJMJBSACDcjs.applyAugmentation.call(void 0, request, options.nativeSearchAugmentation);
2595
4348
  }
2596
4349
  logger.info("Streaming OpenAI completion request", {
2597
4350
  url: apiUrl,
@@ -2610,7 +4363,7 @@ async function streamOpenAICompletion(provider, apiKey, options, messageId, call
2610
4363
  });
2611
4364
  if (!response.ok) {
2612
4365
  const errorText = await response.text();
2613
- _optionalChain([callbacks, 'access', _91 => _91.onError, 'optionalCall', _92 => _92(`API error (${response.status}): ${errorText}`)]);
4366
+ _optionalChain([callbacks, 'access', _157 => _157.onError, 'optionalCall', _158 => _158(`API error (${response.status}): ${errorText}`)]);
2614
4367
  return;
2615
4368
  }
2616
4369
  const result = await _chunkHQP3K7PUcjs.streamSSEResponse.call(void 0, response, "openai", {
@@ -2620,7 +4373,7 @@ async function streamOpenAICompletion(provider, apiKey, options, messageId, call
2620
4373
  onVideo: callbacks.onVideo,
2621
4374
  onError: callbacks.onError
2622
4375
  });
2623
- _optionalChain([callbacks, 'access', _93 => _93.onDone, 'optionalCall', _94 => _94(
4376
+ _optionalChain([callbacks, 'access', _159 => _159.onDone, 'optionalCall', _160 => _160(
2624
4377
  {
2625
4378
  id: messageId,
2626
4379
  role: "assistant",
@@ -2685,14 +4438,14 @@ async function streamAnthropicCompletion(provider, apiKey, options, messageId, c
2685
4438
  }
2686
4439
  }
2687
4440
  const apiUrl = _chunkA2YMUCBTcjs.buildProviderApiUrl.call(void 0, provider, { model: options.model, stream: true });
2688
- const headers = _chunkLKZJEL6Ecjs.getProviderHeaders.call(void 0, provider, apiKey);
4441
+ const headers = _chunkQ27JY5RGcjs.getProviderHeaders.call(void 0, provider, apiKey);
2689
4442
  if (options.nativeSearchAugmentation) {
2690
- _chunkV5KPWNYXcjs.applyAugmentation.call(void 0, anthropicRequest, options.nativeSearchAugmentation);
4443
+ _chunkJMJBSACDcjs.applyAugmentation.call(void 0, anthropicRequest, options.nativeSearchAugmentation);
2691
4444
  }
2692
4445
  logger.info("Streaming Anthropic completion request", {
2693
4446
  url: apiUrl,
2694
4447
  model: anthropicRequest.model,
2695
- messagesCount: _optionalChain([anthropicRequest, 'access', _95 => _95.messages, 'optionalAccess', _96 => _96.length]),
4448
+ messagesCount: _optionalChain([anthropicRequest, 'access', _161 => _161.messages, 'optionalAccess', _162 => _162.length]),
2696
4449
  max_tokens: anthropicRequest.max_tokens,
2697
4450
  temperature: anthropicRequest.temperature,
2698
4451
  stream: anthropicRequest.stream,
@@ -2709,7 +4462,7 @@ async function streamAnthropicCompletion(provider, apiKey, options, messageId, c
2709
4462
  if (!response.ok) {
2710
4463
  const errorText = await response.text();
2711
4464
  logger.error("Anthropic API error", void 0, { status: response.status, errorText });
2712
- _optionalChain([callbacks, 'access', _97 => _97.onError, 'optionalCall', _98 => _98(`API error (${response.status}): ${errorText}`)]);
4465
+ _optionalChain([callbacks, 'access', _163 => _163.onError, 'optionalCall', _164 => _164(`API error (${response.status}): ${errorText}`)]);
2713
4466
  return;
2714
4467
  }
2715
4468
  const result = await _chunkHQP3K7PUcjs.streamSSEResponse.call(void 0, response, "anthropic", {
@@ -2720,10 +4473,10 @@ async function streamAnthropicCompletion(provider, apiKey, options, messageId, c
2720
4473
  });
2721
4474
  logger.info("Anthropic stream complete", {
2722
4475
  contentLength: result.content.length,
2723
- reasoningLength: _optionalChain([result, 'access', _99 => _99.reasoning, 'optionalAccess', _100 => _100.length]) || 0,
4476
+ reasoningLength: _optionalChain([result, 'access', _165 => _165.reasoning, 'optionalAccess', _166 => _166.length]) || 0,
2724
4477
  blocksCount: result.blocks.length
2725
4478
  });
2726
- _optionalChain([callbacks, 'access', _101 => _101.onDone, 'optionalCall', _102 => _102(
4479
+ _optionalChain([callbacks, 'access', _167 => _167.onDone, 'optionalCall', _168 => _168(
2727
4480
  {
2728
4481
  id: messageId,
2729
4482
  role: "assistant",
@@ -2757,9 +4510,9 @@ async function streamGeminiCompletion(provider, apiKey, options, messageId, call
2757
4510
  request.systemInstruction = systemInstruction;
2758
4511
  }
2759
4512
  const apiUrl = _chunkA2YMUCBTcjs.buildProviderApiUrl.call(void 0, provider, { model: options.model, stream: true });
2760
- const headers = _chunkLKZJEL6Ecjs.getProviderHeaders.call(void 0, provider, apiKey);
4513
+ const headers = _chunkQ27JY5RGcjs.getProviderHeaders.call(void 0, provider, apiKey);
2761
4514
  if (options.nativeSearchAugmentation) {
2762
- _chunkV5KPWNYXcjs.applyAugmentation.call(void 0, request, options.nativeSearchAugmentation);
4515
+ _chunkJMJBSACDcjs.applyAugmentation.call(void 0, request, options.nativeSearchAugmentation);
2763
4516
  }
2764
4517
  logger.info("Streaming Gemini completion request", {
2765
4518
  url: apiUrl,
@@ -2779,7 +4532,7 @@ async function streamGeminiCompletion(provider, apiKey, options, messageId, call
2779
4532
  if (!response.ok) {
2780
4533
  const errorText = await response.text();
2781
4534
  logger.error("Gemini API error", void 0, { status: response.status, errorText });
2782
- _optionalChain([callbacks, 'access', _103 => _103.onError, 'optionalCall', _104 => _104(`API error (${response.status}): ${errorText}`)]);
4535
+ _optionalChain([callbacks, 'access', _169 => _169.onError, 'optionalCall', _170 => _170(`API error (${response.status}): ${errorText}`)]);
2783
4536
  return;
2784
4537
  }
2785
4538
  const result = await _chunkHQP3K7PUcjs.streamSSEResponse.call(void 0, response, "gemini", {
@@ -2788,7 +4541,7 @@ async function streamGeminiCompletion(provider, apiKey, options, messageId, call
2788
4541
  onError: callbacks.onError
2789
4542
  });
2790
4543
  logger.info("Gemini stream complete", { contentLength: result.content.length });
2791
- _optionalChain([callbacks, 'access', _105 => _105.onDone, 'optionalCall', _106 => _106(
4544
+ _optionalChain([callbacks, 'access', _171 => _171.onDone, 'optionalCall', _172 => _172(
2792
4545
  {
2793
4546
  id: messageId,
2794
4547
  role: "assistant",
@@ -2823,7 +4576,7 @@ async function streamOpenAIResponseCompletion(provider, apiKey, options, message
2823
4576
  }
2824
4577
  }
2825
4578
  const apiUrl = _chunkA2YMUCBTcjs.buildProviderApiUrl.call(void 0, provider, { model: options.model, stream: true });
2826
- const headers = _chunkLKZJEL6Ecjs.getProviderHeaders.call(void 0, provider, apiKey);
4579
+ const headers = _chunkQ27JY5RGcjs.getProviderHeaders.call(void 0, provider, apiKey);
2827
4580
  logger.info("Streaming OpenAI Response API request", {
2828
4581
  url: apiUrl,
2829
4582
  providerId: options.providerId,
@@ -2840,7 +4593,7 @@ async function streamOpenAIResponseCompletion(provider, apiKey, options, message
2840
4593
  });
2841
4594
  if (!response.ok) {
2842
4595
  const errorText = await response.text();
2843
- _optionalChain([callbacks, 'access', _107 => _107.onError, 'optionalCall', _108 => _108(`API error (${response.status}): ${errorText}`)]);
4596
+ _optionalChain([callbacks, 'access', _173 => _173.onError, 'optionalCall', _174 => _174(`API error (${response.status}): ${errorText}`)]);
2844
4597
  return;
2845
4598
  }
2846
4599
  const result = await _chunkHQP3K7PUcjs.streamSSEResponse.call(void 0, response, "openai-response", {
@@ -2849,7 +4602,7 @@ async function streamOpenAIResponseCompletion(provider, apiKey, options, message
2849
4602
  onError: callbacks.onError
2850
4603
  });
2851
4604
  logger.info("OpenAI Response API stream complete", { contentLength: result.content.length });
2852
- _optionalChain([callbacks, 'access', _109 => _109.onDone, 'optionalCall', _110 => _110(
4605
+ _optionalChain([callbacks, 'access', _175 => _175.onDone, 'optionalCall', _176 => _176(
2853
4606
  {
2854
4607
  id: messageId,
2855
4608
  role: "assistant",
@@ -2877,7 +4630,7 @@ async function resolveEffectiveMaxTokens(llmConfig, getProvider, logger, provide
2877
4630
  }
2878
4631
  try {
2879
4632
  const globalParams = await llmConfig.getGlobalModelParameters();
2880
- if (_optionalChain([globalParams, 'optionalAccess', _111 => _111.maxTokens, 'optionalAccess', _112 => _112.enabled]) && globalParams.maxTokens.value > 0) {
4633
+ if (_optionalChain([globalParams, 'optionalAccess', _177 => _177.maxTokens, 'optionalAccess', _178 => _178.enabled]) && globalParams.maxTokens.value > 0) {
2881
4634
  logger.debug("Using global maxTokens", { maxTokens: globalParams.maxTokens.value });
2882
4635
  return globalParams.maxTokens.value;
2883
4636
  }
@@ -2887,8 +4640,8 @@ async function resolveEffectiveMaxTokens(llmConfig, getProvider, logger, provide
2887
4640
  const MAX_TOKENS_CAP = 131072;
2888
4641
  const provider = await getProvider(providerId);
2889
4642
  if (provider) {
2890
- const modelConfig = _optionalChain([provider, 'access', _113 => _113.modelConfigs, 'optionalAccess', _114 => _114.find, 'call', _115 => _115((m) => m.id === modelId)]);
2891
- if (_optionalChain([modelConfig, 'optionalAccess', _116 => _116.maxTokens]) && modelConfig.maxTokens > 0) {
4643
+ const modelConfig = _optionalChain([provider, 'access', _179 => _179.modelConfigs, 'optionalAccess', _180 => _180.find, 'call', _181 => _181((m) => m.id === modelId)]);
4644
+ if (_optionalChain([modelConfig, 'optionalAccess', _182 => _182.maxTokens]) && modelConfig.maxTokens > 0) {
2892
4645
  const cappedMaxTokens = Math.min(modelConfig.maxTokens, MAX_TOKENS_CAP);
2893
4646
  logger.debug("Using model config maxTokens", {
2894
4647
  maxTokens: modelConfig.maxTokens,
@@ -2898,8 +4651,8 @@ async function resolveEffectiveMaxTokens(llmConfig, getProvider, logger, provide
2898
4651
  }
2899
4652
  if (provider.modelGroups) {
2900
4653
  for (const group of provider.modelGroups) {
2901
- const model = _optionalChain([group, 'access', _117 => _117.models, 'optionalAccess', _118 => _118.find, 'call', _119 => _119((m) => m.id === modelId)]);
2902
- if (_optionalChain([model, 'optionalAccess', _120 => _120.maxTokens]) && model.maxTokens > 0) {
4654
+ const model = _optionalChain([group, 'access', _183 => _183.models, 'optionalAccess', _184 => _184.find, 'call', _185 => _185((m) => m.id === modelId)]);
4655
+ if (_optionalChain([model, 'optionalAccess', _186 => _186.maxTokens]) && model.maxTokens > 0) {
2903
4656
  const cappedMaxTokens = Math.min(model.maxTokens, MAX_TOKENS_CAP);
2904
4657
  logger.debug("Using modelGroup model maxTokens", {
2905
4658
  maxTokens: model.maxTokens,
@@ -2944,7 +4697,7 @@ async function resolveThinkingBudget(getProvider, logger, providerId, modelId, m
2944
4697
  }
2945
4698
  const thinkingBudget = _thinkingconfig.calculateThinkingBudget.call(void 0, modelId, thinkLevel, maxTokens);
2946
4699
  const provider = await getProvider(providerId);
2947
- const providerName = _optionalChain([provider, 'optionalAccess', _121 => _121.name, 'optionalAccess', _122 => _122.toLowerCase, 'call', _123 => _123()]) || "";
4700
+ const providerName = _optionalChain([provider, 'optionalAccess', _187 => _187.name, 'optionalAccess', _188 => _188.toLowerCase, 'call', _189 => _189()]) || "";
2948
4701
  const apiFormat = provider ? _chunkA2YMUCBTcjs.resolveApiFormat.call(void 0, provider) : "openai";
2949
4702
  if (apiFormat === "anthropic" || providerName === "anthropic" || providerName.includes("claude")) {
2950
4703
  const thinkingConfig = _thinkingconfig.buildAnthropicThinking.call(void 0, modelId, thinkLevel, maxTokens);
@@ -2981,7 +4734,7 @@ function logToolFormat(tools, logger) {
2981
4734
  tools: openaiTools.map((t) => t.function.name),
2982
4735
  firstTool: {
2983
4736
  name: firstTool.function.name,
2984
- description: _optionalChain([firstTool, 'access', _124 => _124.function, 'access', _125 => _125.description, 'optionalAccess', _126 => _126.slice, 'call', _127 => _127(0, 100)]),
4737
+ description: _optionalChain([firstTool, 'access', _190 => _190.function, 'access', _191 => _191.description, 'optionalAccess', _192 => _192.slice, 'call', _193 => _193(0, 100)]),
2985
4738
  parameters: firstTool.function.parameters
2986
4739
  }
2987
4740
  });
@@ -2992,7 +4745,7 @@ function logToolFormat(tools, logger) {
2992
4745
  tools: anthropicTools.map((t) => t.name),
2993
4746
  firstTool: {
2994
4747
  name: firstTool.name,
2995
- description: _optionalChain([firstTool, 'access', _128 => _128.description, 'optionalAccess', _129 => _129.slice, 'call', _130 => _130(0, 100)]),
4748
+ description: _optionalChain([firstTool, 'access', _194 => _194.description, 'optionalAccess', _195 => _195.slice, 'call', _196 => _196(0, 100)]),
2996
4749
  input_schema: firstTool.input_schema
2997
4750
  }
2998
4751
  });
@@ -3003,9 +4756,9 @@ function logToolFormat(tools, logger) {
3003
4756
  count: allDeclarations.length,
3004
4757
  tools: allDeclarations.map((t) => t.name),
3005
4758
  firstTool: {
3006
- name: _optionalChain([allDeclarations, 'access', _131 => _131[0], 'optionalAccess', _132 => _132.name]),
3007
- description: _optionalChain([allDeclarations, 'access', _133 => _133[0], 'optionalAccess', _134 => _134.description, 'optionalAccess', _135 => _135.slice, 'call', _136 => _136(0, 100)]),
3008
- parameters: _optionalChain([allDeclarations, 'access', _137 => _137[0], 'optionalAccess', _138 => _138.parameters])
4759
+ name: _optionalChain([allDeclarations, 'access', _197 => _197[0], 'optionalAccess', _198 => _198.name]),
4760
+ description: _optionalChain([allDeclarations, 'access', _199 => _199[0], 'optionalAccess', _200 => _200.description, 'optionalAccess', _201 => _201.slice, 'call', _202 => _202(0, 100)]),
4761
+ parameters: _optionalChain([allDeclarations, 'access', _203 => _203[0], 'optionalAccess', _204 => _204.parameters])
3009
4762
  }
3010
4763
  });
3011
4764
  }
@@ -3064,7 +4817,7 @@ function buildToolRequest(apiFormat, conversationMessages, actualModel, options,
3064
4817
  function extractDeltaContent(rawJson, apiFormat) {
3065
4818
  const json = rawJson;
3066
4819
  if (apiFormat === "google") {
3067
- const parts = _optionalChain([json, 'access', _139 => _139.candidates, 'optionalAccess', _140 => _140[0], 'optionalAccess', _141 => _141.content, 'optionalAccess', _142 => _142.parts]) || [];
4820
+ const parts = _optionalChain([json, 'access', _205 => _205.candidates, 'optionalAccess', _206 => _206[0], 'optionalAccess', _207 => _207.content, 'optionalAccess', _208 => _208.parts]) || [];
3068
4821
  let text = "";
3069
4822
  for (const part of parts) {
3070
4823
  if (part.thought === true) continue;
@@ -3072,15 +4825,15 @@ function extractDeltaContent(rawJson, apiFormat) {
3072
4825
  }
3073
4826
  return text;
3074
4827
  } else if (apiFormat === "anthropic") {
3075
- return _optionalChain([json, 'access', _143 => _143.delta, 'optionalAccess', _144 => _144.text]) || "";
4828
+ return _optionalChain([json, 'access', _209 => _209.delta, 'optionalAccess', _210 => _210.text]) || "";
3076
4829
  } else {
3077
- return _optionalChain([json, 'access', _145 => _145.choices, 'optionalAccess', _146 => _146[0], 'optionalAccess', _147 => _147.delta, 'optionalAccess', _148 => _148.content]) || "";
4830
+ return _optionalChain([json, 'access', _211 => _211.choices, 'optionalAccess', _212 => _212[0], 'optionalAccess', _213 => _213.delta, 'optionalAccess', _214 => _214.content]) || "";
3078
4831
  }
3079
4832
  }
3080
4833
  function extractDeltaReasoning(rawJson, apiFormat) {
3081
4834
  const json = rawJson;
3082
4835
  if (apiFormat === "google") {
3083
- const parts = _optionalChain([json, 'access', _149 => _149.candidates, 'optionalAccess', _150 => _150[0], 'optionalAccess', _151 => _151.content, 'optionalAccess', _152 => _152.parts]) || [];
4836
+ const parts = _optionalChain([json, 'access', _215 => _215.candidates, 'optionalAccess', _216 => _216[0], 'optionalAccess', _217 => _217.content, 'optionalAccess', _218 => _218.parts]) || [];
3084
4837
  let reasoning = "";
3085
4838
  for (const part of parts) {
3086
4839
  if (part.thought === true && part.text) reasoning += part.text;
@@ -3089,14 +4842,14 @@ function extractDeltaReasoning(rawJson, apiFormat) {
3089
4842
  } else if (apiFormat === "anthropic") {
3090
4843
  return "";
3091
4844
  } else {
3092
- const delta = _optionalChain([json, 'access', _153 => _153.choices, 'optionalAccess', _154 => _154[0], 'optionalAccess', _155 => _155.delta]);
3093
- return (_optionalChain([delta, 'optionalAccess', _156 => _156.thinking, 'optionalAccess', _157 => _157.content]) || "") + (_optionalChain([delta, 'optionalAccess', _158 => _158.reasoning_content]) || "");
4845
+ const delta = _optionalChain([json, 'access', _219 => _219.choices, 'optionalAccess', _220 => _220[0], 'optionalAccess', _221 => _221.delta]);
4846
+ return (_optionalChain([delta, 'optionalAccess', _222 => _222.thinking, 'optionalAccess', _223 => _223.content]) || "") + (_optionalChain([delta, 'optionalAccess', _224 => _224.reasoning_content]) || "");
3094
4847
  }
3095
4848
  }
3096
4849
  function extractToolCalls(rawJson, apiFormat, toolCalls, callbacks, logger, pendingOpenAIToolCalls) {
3097
4850
  const json = rawJson;
3098
4851
  if (apiFormat === "google") {
3099
- const parts = _optionalChain([json, 'access', _159 => _159.candidates, 'optionalAccess', _160 => _160[0], 'optionalAccess', _161 => _161.content, 'optionalAccess', _162 => _162.parts]) || [];
4852
+ const parts = _optionalChain([json, 'access', _225 => _225.candidates, 'optionalAccess', _226 => _226[0], 'optionalAccess', _227 => _227.content, 'optionalAccess', _228 => _228.parts]) || [];
3100
4853
  for (const part of parts) {
3101
4854
  if (part.functionCall) {
3102
4855
  logger.info("Function call detected", { functionCall: part.functionCall });
@@ -3106,13 +4859,13 @@ function extractToolCalls(rawJson, apiFormat, toolCalls, callbacks, logger, pend
3106
4859
  args: part.functionCall.args || {}
3107
4860
  };
3108
4861
  toolCalls.push(toolCall);
3109
- _optionalChain([callbacks, 'access', _163 => _163.onToolCall, 'optionalCall', _164 => _164(toolCall)]);
4862
+ _optionalChain([callbacks, 'access', _229 => _229.onToolCall, 'optionalCall', _230 => _230(toolCall)]);
3110
4863
  logger.info("Tool called", { toolName: toolCall.name });
3111
4864
  }
3112
4865
  }
3113
4866
  } else if (apiFormat !== "anthropic") {
3114
- const delta = _optionalChain([json, 'access', _165 => _165.choices, 'optionalAccess', _166 => _166[0], 'optionalAccess', _167 => _167.delta]);
3115
- if (_optionalChain([delta, 'optionalAccess', _168 => _168.tool_calls]) && pendingOpenAIToolCalls) {
4867
+ const delta = _optionalChain([json, 'access', _231 => _231.choices, 'optionalAccess', _232 => _232[0], 'optionalAccess', _233 => _233.delta]);
4868
+ if (_optionalChain([delta, 'optionalAccess', _234 => _234.tool_calls]) && pendingOpenAIToolCalls) {
3116
4869
  for (const tc of delta.tool_calls) {
3117
4870
  const index = _nullishCoalesce(tc.index, () => ( 0));
3118
4871
  let pending = pendingOpenAIToolCalls.get(index);
@@ -3121,8 +4874,8 @@ function extractToolCalls(rawJson, apiFormat, toolCalls, callbacks, logger, pend
3121
4874
  pendingOpenAIToolCalls.set(index, pending);
3122
4875
  }
3123
4876
  if (tc.id) pending.id = tc.id;
3124
- if (_optionalChain([tc, 'access', _169 => _169.function, 'optionalAccess', _170 => _170.name])) pending.name += tc.function.name;
3125
- if (_optionalChain([tc, 'access', _171 => _171.function, 'optionalAccess', _172 => _172.arguments])) pending.arguments += tc.function.arguments;
4877
+ if (_optionalChain([tc, 'access', _235 => _235.function, 'optionalAccess', _236 => _236.name])) pending.name += tc.function.name;
4878
+ if (_optionalChain([tc, 'access', _237 => _237.function, 'optionalAccess', _238 => _238.arguments])) pending.arguments += tc.function.arguments;
3126
4879
  }
3127
4880
  }
3128
4881
  }
@@ -3137,7 +4890,7 @@ function finalizeOpenAIToolCalls(pendingOpenAIToolCalls, toolCalls, callbacks, l
3137
4890
  args: JSON.parse(pending.arguments || "{}")
3138
4891
  };
3139
4892
  toolCalls.push(toolCall);
3140
- _optionalChain([callbacks, 'access', _173 => _173.onToolCall, 'optionalCall', _174 => _174(toolCall)]);
4893
+ _optionalChain([callbacks, 'access', _239 => _239.onToolCall, 'optionalCall', _240 => _240(toolCall)]);
3141
4894
  logger.info("Tool called (OpenAI)", { toolName: toolCall.name, args: toolCall.args });
3142
4895
  } catch (e) {
3143
4896
  logger.error("Failed to parse OpenAI tool call arguments", e instanceof Error ? e : void 0, {
@@ -3151,38 +4904,38 @@ function finalizeOpenAIToolCalls(pendingOpenAIToolCalls, toolCalls, callbacks, l
3151
4904
  function parseStreamChunk(rawJson, apiFormat, callbacks, logger) {
3152
4905
  const json = rawJson;
3153
4906
  if (apiFormat === "google") {
3154
- const candidate = _optionalChain([json, 'access', _175 => _175.candidates, 'optionalAccess', _176 => _176[0]]);
4907
+ const candidate = _optionalChain([json, 'access', _241 => _241.candidates, 'optionalAccess', _242 => _242[0]]);
3155
4908
  if (!candidate) {
3156
4909
  logger.warn("No candidate found in Gemini response");
3157
4910
  return;
3158
4911
  }
3159
- const parts = _optionalChain([candidate, 'access', _177 => _177.content, 'optionalAccess', _178 => _178.parts]) || [];
4912
+ const parts = _optionalChain([candidate, 'access', _243 => _243.content, 'optionalAccess', _244 => _244.parts]) || [];
3160
4913
  for (const part of parts) {
3161
4914
  if (part.thought === true && part.text) {
3162
- _optionalChain([callbacks, 'access', _179 => _179.onReasoning, 'optionalCall', _180 => _180(part.text)]);
4915
+ _optionalChain([callbacks, 'access', _245 => _245.onReasoning, 'optionalCall', _246 => _246(part.text)]);
3163
4916
  continue;
3164
4917
  } else if (part.thoughtSignature && !part.thought) {
3165
4918
  logger.debug("Gemini returned thoughtSignature without thought content");
3166
4919
  }
3167
4920
  if (part.text) {
3168
- _optionalChain([callbacks, 'access', _181 => _181.onDelta, 'optionalCall', _182 => _182(part.text)]);
4921
+ _optionalChain([callbacks, 'access', _247 => _247.onDelta, 'optionalCall', _248 => _248(part.text)]);
3169
4922
  }
3170
4923
  }
3171
4924
  } else if (apiFormat === "anthropic") {
3172
4925
  const delta = json.delta;
3173
- if (_optionalChain([delta, 'optionalAccess', _183 => _183.text])) {
3174
- _optionalChain([callbacks, 'access', _184 => _184.onDelta, 'optionalCall', _185 => _185(delta.text)]);
4926
+ if (_optionalChain([delta, 'optionalAccess', _249 => _249.text])) {
4927
+ _optionalChain([callbacks, 'access', _250 => _250.onDelta, 'optionalCall', _251 => _251(delta.text)]);
3175
4928
  }
3176
4929
  } else {
3177
- const delta = _optionalChain([json, 'access', _186 => _186.choices, 'optionalAccess', _187 => _187[0], 'optionalAccess', _188 => _188.delta]);
3178
- if (_optionalChain([delta, 'optionalAccess', _189 => _189.content])) {
3179
- _optionalChain([callbacks, 'access', _190 => _190.onDelta, 'optionalCall', _191 => _191(delta.content)]);
4930
+ const delta = _optionalChain([json, 'access', _252 => _252.choices, 'optionalAccess', _253 => _253[0], 'optionalAccess', _254 => _254.delta]);
4931
+ if (_optionalChain([delta, 'optionalAccess', _255 => _255.content])) {
4932
+ _optionalChain([callbacks, 'access', _256 => _256.onDelta, 'optionalCall', _257 => _257(delta.content)]);
3180
4933
  }
3181
- if (_optionalChain([delta, 'optionalAccess', _192 => _192.thinking, 'optionalAccess', _193 => _193.content])) {
3182
- _optionalChain([callbacks, 'access', _194 => _194.onReasoning, 'optionalCall', _195 => _195(delta.thinking.content)]);
4934
+ if (_optionalChain([delta, 'optionalAccess', _258 => _258.thinking, 'optionalAccess', _259 => _259.content])) {
4935
+ _optionalChain([callbacks, 'access', _260 => _260.onReasoning, 'optionalCall', _261 => _261(delta.thinking.content)]);
3183
4936
  }
3184
- if (_optionalChain([delta, 'optionalAccess', _196 => _196.reasoning_content])) {
3185
- _optionalChain([callbacks, 'access', _197 => _197.onReasoning, 'optionalCall', _198 => _198(delta.reasoning_content)]);
4937
+ if (_optionalChain([delta, 'optionalAccess', _262 => _262.reasoning_content])) {
4938
+ _optionalChain([callbacks, 'access', _263 => _263.onReasoning, 'optionalCall', _264 => _264(delta.reasoning_content)]);
3186
4939
  }
3187
4940
  }
3188
4941
  }
@@ -3195,7 +4948,7 @@ function buildIterationBlocks(iteration, content, reasoning, blocks, callbacks)
3195
4948
  content: reasoning
3196
4949
  };
3197
4950
  blocks.push(thinkingBlock);
3198
- _optionalChain([callbacks, 'access', _199 => _199.onBlock, 'optionalCall', _200 => _200(thinkingBlock)]);
4951
+ _optionalChain([callbacks, 'access', _265 => _265.onBlock, 'optionalCall', _266 => _266(thinkingBlock)]);
3199
4952
  }
3200
4953
  if (content && content.trim()) {
3201
4954
  const textBlock = {
@@ -3204,7 +4957,7 @@ function buildIterationBlocks(iteration, content, reasoning, blocks, callbacks)
3204
4957
  content
3205
4958
  };
3206
4959
  blocks.push(textBlock);
3207
- _optionalChain([callbacks, 'access', _201 => _201.onBlock, 'optionalCall', _202 => _202(textBlock)]);
4960
+ _optionalChain([callbacks, 'access', _267 => _267.onBlock, 'optionalCall', _268 => _268(textBlock)]);
3208
4961
  }
3209
4962
  }
3210
4963
  async function executeToolCalls(toolCalls, mcpTools, mcpService, blocks, callbacks, logger, builtinExecutor) {
@@ -3219,7 +4972,7 @@ async function executeToolCalls(toolCalls, mcpTools, mcpService, blocks, callbac
3219
4972
  status: "running"
3220
4973
  };
3221
4974
  blocks.push(toolUseBlock);
3222
- _optionalChain([callbacks, 'access', _203 => _203.onBlock, 'optionalCall', _204 => _204(toolUseBlock)]);
4975
+ _optionalChain([callbacks, 'access', _269 => _269.onBlock, 'optionalCall', _270 => _270(toolUseBlock)]);
3223
4976
  try {
3224
4977
  logger.info("Executing tool", { toolName: toolCall.name });
3225
4978
  const mcpTool = mcpTools.find((t) => t.id === toolCall.name);
@@ -3242,8 +4995,8 @@ async function executeToolCalls(toolCalls, mcpTools, mcpService, blocks, callbac
3242
4995
  result = { isError: true, content: [{ type: "text", text: "MCP service not available" }] };
3243
4996
  }
3244
4997
  logger.info("Tool result received", { result });
3245
- _optionalChain([callbacks, 'access', _205 => _205.onToolResult, 'optionalCall', _206 => _206(toolCall.id, result)]);
3246
- const resultText = _optionalChain([result, 'access', _207 => _207.content, 'optionalAccess', _208 => _208[0], 'optionalAccess', _209 => _209.text]) || JSON.stringify(result);
4998
+ _optionalChain([callbacks, 'access', _271 => _271.onToolResult, 'optionalCall', _272 => _272(toolCall.id, result)]);
4999
+ const resultText = _optionalChain([result, 'access', _273 => _273.content, 'optionalAccess', _274 => _274[0], 'optionalAccess', _275 => _275.text]) || JSON.stringify(result);
3247
5000
  const toolResultBlock = {
3248
5001
  id: `${toolCall.id}_result`,
3249
5002
  type: "tool_result",
@@ -3253,11 +5006,11 @@ async function executeToolCalls(toolCalls, mcpTools, mcpService, blocks, callbac
3253
5006
  isError: result.isError
3254
5007
  };
3255
5008
  blocks.push(toolResultBlock);
3256
- _optionalChain([callbacks, 'access', _210 => _210.onBlock, 'optionalCall', _211 => _211(toolResultBlock)]);
5009
+ _optionalChain([callbacks, 'access', _276 => _276.onBlock, 'optionalCall', _277 => _277(toolResultBlock)]);
3257
5010
  const toolUseBlockRef = blocks.find((b) => b.id === `${toolCall.id}_use`);
3258
5011
  if (toolUseBlockRef && toolUseBlockRef.type === "tool_use") {
3259
5012
  toolUseBlockRef.status = result.isError ? "error" : "completed";
3260
- _optionalChain([callbacks, 'access', _212 => _212.onBlock, 'optionalCall', _213 => _213({ ...toolUseBlockRef })]);
5013
+ _optionalChain([callbacks, 'access', _278 => _278.onBlock, 'optionalCall', _279 => _279({ ...toolUseBlockRef })]);
3261
5014
  }
3262
5015
  toolResults.push({ toolCall, result });
3263
5016
  } catch (error) {
@@ -3267,7 +5020,7 @@ async function executeToolCalls(toolCalls, mcpTools, mcpService, blocks, callbac
3267
5020
  isError: true,
3268
5021
  content: [{ type: "text", text: `Error: ${errorMessage}` }]
3269
5022
  };
3270
- _optionalChain([callbacks, 'access', _214 => _214.onToolResult, 'optionalCall', _215 => _215(toolCall.id, errorResult)]);
5023
+ _optionalChain([callbacks, 'access', _280 => _280.onToolResult, 'optionalCall', _281 => _281(toolCall.id, errorResult)]);
3271
5024
  const errorToolResultBlock = {
3272
5025
  id: `${toolCall.id}_result`,
3273
5026
  type: "tool_result",
@@ -3277,11 +5030,11 @@ async function executeToolCalls(toolCalls, mcpTools, mcpService, blocks, callbac
3277
5030
  isError: true
3278
5031
  };
3279
5032
  blocks.push(errorToolResultBlock);
3280
- _optionalChain([callbacks, 'access', _216 => _216.onBlock, 'optionalCall', _217 => _217(errorToolResultBlock)]);
5033
+ _optionalChain([callbacks, 'access', _282 => _282.onBlock, 'optionalCall', _283 => _283(errorToolResultBlock)]);
3281
5034
  const errorToolUseBlockRef = blocks.find((b) => b.id === `${toolCall.id}_use`);
3282
5035
  if (errorToolUseBlockRef && errorToolUseBlockRef.type === "tool_use") {
3283
5036
  errorToolUseBlockRef.status = "error";
3284
- _optionalChain([callbacks, 'access', _218 => _218.onBlock, 'optionalCall', _219 => _219({ ...errorToolUseBlockRef })]);
5037
+ _optionalChain([callbacks, 'access', _284 => _284.onBlock, 'optionalCall', _285 => _285({ ...errorToolUseBlockRef })]);
3285
5038
  }
3286
5039
  toolResults.push({ toolCall, result: errorResult });
3287
5040
  }
@@ -3291,7 +5044,7 @@ async function executeToolCalls(toolCalls, mcpTools, mcpService, blocks, callbac
3291
5044
  function mapToolArguments(args, mcpTool, logger) {
3292
5045
  const mappedArgs = { ...args };
3293
5046
  const toolSchema = mcpTool.inputSchema;
3294
- if (_optionalChain([toolSchema, 'optionalAccess', _220 => _220.properties])) {
5047
+ if (_optionalChain([toolSchema, 'optionalAccess', _286 => _286.properties])) {
3295
5048
  const expectedParams = Object.keys(toolSchema.properties);
3296
5049
  const paramMappings = {
3297
5050
  "search_query": ["query", "q", "searchQuery", "search"],
@@ -3325,25 +5078,25 @@ async function streamWithTools(options, callbacks, mcpService, llmConfig, getPro
3325
5078
  options.providerId,
3326
5079
  options.model
3327
5080
  );
3328
- const actualProviderId = _optionalChain([routedInfo, 'optionalAccess', _221 => _221.actualProviderId]) || options.providerId;
3329
- const actualModel = _optionalChain([routedInfo, 'optionalAccess', _222 => _222.actualModelId]) || options.model;
5081
+ const actualProviderId = _optionalChain([routedInfo, 'optionalAccess', _287 => _287.actualProviderId]) || options.providerId;
5082
+ const actualModel = _optionalChain([routedInfo, 'optionalAccess', _288 => _288.actualModelId]) || options.model;
3330
5083
  const provider = await getProvider(actualProviderId);
3331
5084
  if (!provider) {
3332
- _optionalChain([callbacks, 'access', _223 => _223.onError, 'optionalCall', _224 => _224(`Provider not found: ${actualProviderId}`)]);
5085
+ _optionalChain([callbacks, 'access', _289 => _289.onError, 'optionalCall', _290 => _290(`Provider not found: ${actualProviderId}`)]);
3333
5086
  return;
3334
5087
  }
3335
5088
  if (!provider.enabled) {
3336
- _optionalChain([callbacks, 'access', _225 => _225.onError, 'optionalCall', _226 => _226(`Provider is disabled: ${provider.name}`)]);
5089
+ _optionalChain([callbacks, 'access', _291 => _291.onError, 'optionalCall', _292 => _292(`Provider is disabled: ${provider.name}`)]);
3337
5090
  return;
3338
5091
  }
3339
5092
  const { apiKey: effectiveKey } = _chunkA2YMUCBTcjs.resolveProviderEndpoint.call(void 0, provider);
3340
5093
  const apiKey = resolveApiKey2(effectiveKey);
3341
5094
  if (!apiKey) {
3342
- _optionalChain([callbacks, 'access', _227 => _227.onError, 'optionalCall', _228 => _228("API key not configured")]);
5095
+ _optionalChain([callbacks, 'access', _293 => _293.onError, 'optionalCall', _294 => _294("API key not configured")]);
3343
5096
  return;
3344
5097
  }
3345
5098
  const messageId = `msg_${Date.now()}_${Math.random().toString(36).slice(2)}`;
3346
- _optionalChain([callbacks, 'access', _229 => _229.onStart, 'optionalCall', _230 => _230(messageId)]);
5099
+ _optionalChain([callbacks, 'access', _295 => _295.onStart, 'optionalCall', _296 => _296(messageId)]);
3347
5100
  const globalParams = await llmConfig.getGlobalModelParameters();
3348
5101
  const MAX_ITERATIONS = _nullishCoalesce(globalParams.toolMaxTurns, () => ( 100));
3349
5102
  let iteration = 0;
@@ -3375,9 +5128,9 @@ async function streamWithTools(options, callbacks, mcpService, llmConfig, getPro
3375
5128
  provider
3376
5129
  );
3377
5130
  if (options.nativeSearchAugmentation) {
3378
- _chunkV5KPWNYXcjs.applyAugmentation.call(void 0, requestBody, options.nativeSearchAugmentation);
5131
+ _chunkJMJBSACDcjs.applyAugmentation.call(void 0, requestBody, options.nativeSearchAugmentation);
3379
5132
  }
3380
- const headers = _chunkLKZJEL6Ecjs.getProviderHeaders.call(void 0, provider, apiKey);
5133
+ const headers = _chunkQ27JY5RGcjs.getProviderHeaders.call(void 0, provider, apiKey);
3381
5134
  logger.info("Sending tool call request", {
3382
5135
  url,
3383
5136
  headers,
@@ -3390,12 +5143,12 @@ async function streamWithTools(options, callbacks, mcpService, llmConfig, getPro
3390
5143
  });
3391
5144
  if (!response.ok) {
3392
5145
  const errorText = await response.text();
3393
- _optionalChain([callbacks, 'access', _231 => _231.onError, 'optionalCall', _232 => _232(`API error (${response.status}): ${errorText}`)]);
5146
+ _optionalChain([callbacks, 'access', _297 => _297.onError, 'optionalCall', _298 => _298(`API error (${response.status}): ${errorText}`)]);
3394
5147
  return;
3395
5148
  }
3396
- const reader = _optionalChain([response, 'access', _233 => _233.body, 'optionalAccess', _234 => _234.getReader, 'call', _235 => _235()]);
5149
+ const reader = _optionalChain([response, 'access', _299 => _299.body, 'optionalAccess', _300 => _300.getReader, 'call', _301 => _301()]);
3397
5150
  if (!reader) {
3398
- _optionalChain([callbacks, 'access', _236 => _236.onError, 'optionalCall', _237 => _237("No response body")]);
5151
+ _optionalChain([callbacks, 'access', _302 => _302.onError, 'optionalCall', _303 => _303("No response body")]);
3399
5152
  return;
3400
5153
  }
3401
5154
  const decoder = new TextDecoder();
@@ -3428,7 +5181,7 @@ async function streamWithTools(options, callbacks, mcpService, llmConfig, getPro
3428
5181
  logger.debug("Parsed JSON", { json });
3429
5182
  if (json.error) {
3430
5183
  logger.error("API Error", void 0, { error: json.error });
3431
- _optionalChain([callbacks, 'access', _238 => _238.onError, 'optionalCall', _239 => _239(`API Error: ${json.error.message || JSON.stringify(json.error)}`)]);
5184
+ _optionalChain([callbacks, 'access', _304 => _304.onError, 'optionalCall', _305 => _305(`API Error: ${json.error.message || JSON.stringify(json.error)}`)]);
3432
5185
  return;
3433
5186
  }
3434
5187
  parseStreamChunk(json, apiFormat, callbacks, logger);
@@ -3461,7 +5214,7 @@ async function streamWithTools(options, callbacks, mcpService, llmConfig, getPro
3461
5214
  toolCallsLength: toolCalls.length,
3462
5215
  executableToolCallsLength: executableToolCalls.length,
3463
5216
  hasMcpTools: !!options.mcpTools,
3464
- mcpToolsLength: _optionalChain([options, 'access', _240 => _240.mcpTools, 'optionalAccess', _241 => _241.length]),
5217
+ mcpToolsLength: _optionalChain([options, 'access', _306 => _306.mcpTools, 'optionalAccess', _307 => _307.length]),
3465
5218
  hasMcpService: !!mcpService
3466
5219
  });
3467
5220
  if (executableToolCalls.length > 0 && options.mcpTools && (mcpService || builtinExecutor)) {
@@ -3482,7 +5235,7 @@ async function streamWithTools(options, callbacks, mcpService, llmConfig, getPro
3482
5235
  builtinExecutor
3483
5236
  );
3484
5237
  const toolResultsText = toolResults.map(({ toolCall, result }) => {
3485
- const resultText = typeof result === "string" ? result : _optionalChain([result, 'access', _242 => _242.content, 'optionalAccess', _243 => _243[0], 'optionalAccess', _244 => _244.text]) || JSON.stringify(result);
5238
+ const resultText = typeof result === "string" ? result : _optionalChain([result, 'access', _308 => _308.content, 'optionalAccess', _309 => _309[0], 'optionalAccess', _310 => _310.text]) || JSON.stringify(result);
3486
5239
  return `Tool ${toolCall.name} result:
3487
5240
  ${resultText}`;
3488
5241
  }).join("\n\n");
@@ -3500,12 +5253,12 @@ ${resultText}`;
3500
5253
  }
3501
5254
  } catch (streamError) {
3502
5255
  logger.error("Stream processing error", streamError instanceof Error ? streamError : void 0);
3503
- _optionalChain([callbacks, 'access', _245 => _245.onError, 'optionalCall', _246 => _246(`Stream error: ${streamError instanceof Error ? streamError.message : "Unknown error"}`)]);
5256
+ _optionalChain([callbacks, 'access', _311 => _311.onError, 'optionalCall', _312 => _312(`Stream error: ${streamError instanceof Error ? streamError.message : "Unknown error"}`)]);
3504
5257
  return;
3505
5258
  }
3506
5259
  }
3507
5260
  logger.info("Sending final callback", { blocksCount: blocks.length });
3508
- _optionalChain([callbacks, 'access', _247 => _247.onDone, 'optionalCall', _248 => _248({
5261
+ _optionalChain([callbacks, 'access', _313 => _313.onDone, 'optionalCall', _314 => _314({
3509
5262
  id: messageId,
3510
5263
  role: "assistant",
3511
5264
  content: finalContent,
@@ -3516,7 +5269,7 @@ ${resultText}`;
3516
5269
  } catch (error) {
3517
5270
  logger.error("Error in streamWithTools", error instanceof Error ? error : void 0);
3518
5271
  const message = error instanceof Error ? error.message : "Unknown error";
3519
- _optionalChain([callbacks, 'access', _249 => _249.onError, 'optionalCall', _250 => _250(message)]);
5272
+ _optionalChain([callbacks, 'access', _315 => _315.onError, 'optionalCall', _316 => _316(message)]);
3520
5273
  }
3521
5274
  }
3522
5275
 
@@ -3555,8 +5308,8 @@ async function completeWithTransformers(options, llmConfig, getProvider, resolve
3555
5308
  options.providerId,
3556
5309
  options.model
3557
5310
  );
3558
- const actualProviderId = _optionalChain([routedInfo, 'optionalAccess', _251 => _251.actualProviderId]) || options.providerId;
3559
- const actualModel = _optionalChain([routedInfo, 'optionalAccess', _252 => _252.actualModelId]) || options.model;
5311
+ const actualProviderId = _optionalChain([routedInfo, 'optionalAccess', _317 => _317.actualProviderId]) || options.providerId;
5312
+ const actualModel = _optionalChain([routedInfo, 'optionalAccess', _318 => _318.actualModelId]) || options.model;
3560
5313
  const provider = await getProvider(actualProviderId);
3561
5314
  if (!provider) {
3562
5315
  return { success: false, error: `Provider not found: ${actualProviderId}` };
@@ -3603,9 +5356,9 @@ async function completeWithTransformers(options, llmConfig, getProvider, resolve
3603
5356
  extendedContext: options.useExtendedContext ? { enabled: true, model: actualModel } : void 0,
3604
5357
  resolveUrl: (config) => config.url instanceof URL ? config.url.toString() : _chunkA2YMUCBTcjs.buildProviderApiUrl.call(void 0, provider, { model: actualModel, stream: false }),
3605
5358
  buildHeaders: (config) => ({
3606
- ..._chunkLKZJEL6Ecjs.getProviderHeaders.call(void 0, provider, apiKey),
5359
+ ..._chunkQ27JY5RGcjs.getProviderHeaders.call(void 0, provider, apiKey),
3607
5360
  ...config.headers,
3608
- ..._chunk6VIXXLMXcjs.isOpenRouterProvider.call(void 0, provider) ? _chunk6VIXXLMXcjs.OPENROUTER_APP_HEADERS : {}
5361
+ ..._chunkUNEFIWXIcjs.isOpenRouterProvider.call(void 0, provider) ? _chunkUNEFIWXIcjs.OPENROUTER_APP_HEADERS : {}
3609
5362
  }),
3610
5363
  // Add OpenRouter provider routing config if applicable
3611
5364
  prepareBody: (requestBody) => addOpenRouterProviderToRequest(
@@ -3637,18 +5390,18 @@ async function completeWithTransformers(options, llmConfig, getProvider, resolve
3637
5390
  { endpointTransformer: void 0 }
3638
5391
  );
3639
5392
  const data = await transformedResponse.json();
3640
- const choice = _optionalChain([data, 'access', _253 => _253.choices, 'optionalAccess', _254 => _254[0]]);
5393
+ const choice = _optionalChain([data, 'access', _319 => _319.choices, 'optionalAccess', _320 => _320[0]]);
3641
5394
  if (!choice) {
3642
5395
  return { success: false, error: "No choices in response" };
3643
5396
  }
3644
- const rawToolCalls = _optionalChain([choice, 'access', _255 => _255.message, 'optionalAccess', _256 => _256.tool_calls]);
3645
- const toolCalls = _optionalChain([rawToolCalls, 'optionalAccess', _257 => _257.map, 'call', _258 => _258((tc) => ({
5397
+ const rawToolCalls = _optionalChain([choice, 'access', _321 => _321.message, 'optionalAccess', _322 => _322.tool_calls]);
5398
+ const toolCalls = _optionalChain([rawToolCalls, 'optionalAccess', _323 => _323.map, 'call', _324 => _324((tc) => ({
3646
5399
  id: tc.id,
3647
5400
  name: tc.function.name,
3648
5401
  args: typeof tc.function.arguments === "string" ? JSON.parse(tc.function.arguments) : tc.function.arguments
3649
5402
  }))]);
3650
5403
  const tapped = readUsageFromOpenAIResponse(data.usage);
3651
- if (_optionalChain([recording, 'optionalAccess', _259 => _259.recorder]) && tapped) {
5404
+ if (_optionalChain([recording, 'optionalAccess', _325 => _325.recorder]) && tapped) {
3652
5405
  recording.recorder.record({
3653
5406
  messageId: _nullishCoalesce(options.messageId, () => ( null)),
3654
5407
  parentMessageId: _nullishCoalesce(options.parentMessageId, () => ( null)),
@@ -3666,9 +5419,9 @@ async function completeWithTransformers(options, llmConfig, getProvider, resolve
3666
5419
  message: {
3667
5420
  id: `msg_${Date.now()}`,
3668
5421
  role: "assistant",
3669
- content: _optionalChain([choice, 'access', _260 => _260.message, 'optionalAccess', _261 => _261.content]) || "",
5422
+ content: _optionalChain([choice, 'access', _326 => _326.message, 'optionalAccess', _327 => _327.content]) || "",
3670
5423
  timestamp: Date.now(),
3671
- thinking: data.reasoning_content || _optionalChain([choice, 'access', _262 => _262.message, 'optionalAccess', _263 => _263.thinking, 'optionalAccess', _264 => _264.content]) ? { content: data.reasoning_content || _optionalChain([choice, 'access', _265 => _265.message, 'optionalAccess', _266 => _266.thinking, 'optionalAccess', _267 => _267.content]) || "", signature: _optionalChain([choice, 'access', _268 => _268.message, 'optionalAccess', _269 => _269.thinking, 'optionalAccess', _270 => _270.signature]) } : void 0,
5424
+ thinking: data.reasoning_content || _optionalChain([choice, 'access', _328 => _328.message, 'optionalAccess', _329 => _329.thinking, 'optionalAccess', _330 => _330.content]) ? { content: data.reasoning_content || _optionalChain([choice, 'access', _331 => _331.message, 'optionalAccess', _332 => _332.thinking, 'optionalAccess', _333 => _333.content]) || "", signature: _optionalChain([choice, 'access', _334 => _334.message, 'optionalAccess', _335 => _335.thinking, 'optionalAccess', _336 => _336.signature]) } : void 0,
3672
5425
  toolCalls
3673
5426
  },
3674
5427
  usage: data.usage ? {
@@ -3689,21 +5442,21 @@ async function completeStreamWithTransformers(options, callbacks, llmConfig, get
3689
5442
  options.providerId,
3690
5443
  options.model
3691
5444
  );
3692
- const actualProviderId = _optionalChain([routedInfo, 'optionalAccess', _271 => _271.actualProviderId]) || options.providerId;
3693
- const actualModel = _optionalChain([routedInfo, 'optionalAccess', _272 => _272.actualModelId]) || options.model;
5445
+ const actualProviderId = _optionalChain([routedInfo, 'optionalAccess', _337 => _337.actualProviderId]) || options.providerId;
5446
+ const actualModel = _optionalChain([routedInfo, 'optionalAccess', _338 => _338.actualModelId]) || options.model;
3694
5447
  const provider = await getProvider(actualProviderId);
3695
5448
  if (!provider) {
3696
- _optionalChain([callbacks, 'access', _273 => _273.onError, 'optionalCall', _274 => _274(`Provider not found: ${actualProviderId}`)]);
5449
+ _optionalChain([callbacks, 'access', _339 => _339.onError, 'optionalCall', _340 => _340(`Provider not found: ${actualProviderId}`)]);
3697
5450
  return;
3698
5451
  }
3699
5452
  if (!provider.enabled) {
3700
- _optionalChain([callbacks, 'access', _275 => _275.onError, 'optionalCall', _276 => _276(`Provider is disabled: ${provider.name}`)]);
5453
+ _optionalChain([callbacks, 'access', _341 => _341.onError, 'optionalCall', _342 => _342(`Provider is disabled: ${provider.name}`)]);
3701
5454
  return;
3702
5455
  }
3703
5456
  const { apiKey: effectiveKey } = _chunkA2YMUCBTcjs.resolveProviderEndpoint.call(void 0, provider);
3704
5457
  const apiKey = resolveApiKey2(effectiveKey);
3705
5458
  if (!apiKey) {
3706
- _optionalChain([callbacks, 'access', _277 => _277.onError, 'optionalCall', _278 => _278("API key not configured")]);
5459
+ _optionalChain([callbacks, 'access', _343 => _343.onError, 'optionalCall', _344 => _344("API key not configured")]);
3707
5460
  return;
3708
5461
  }
3709
5462
  const { chain, hasTransformers } = await resolveChainWithMain(
@@ -3715,7 +5468,7 @@ async function completeStreamWithTransformers(options, callbacks, llmConfig, get
3715
5468
  return completeStreamFallback(options, callbacks);
3716
5469
  }
3717
5470
  const messageId = `msg_${Date.now()}`;
3718
- _optionalChain([callbacks, 'access', _279 => _279.onStart, 'optionalCall', _280 => _280(messageId)]);
5471
+ _optionalChain([callbacks, 'access', _345 => _345.onStart, 'optionalCall', _346 => _346(messageId)]);
3719
5472
  const unifiedRequest = {
3720
5473
  model: actualModel,
3721
5474
  messages: options.messages.map((m) => ({
@@ -3742,9 +5495,9 @@ async function completeStreamWithTransformers(options, callbacks, llmConfig, get
3742
5495
  extendedContext: options.useExtendedContext ? { enabled: true, model: actualModel } : void 0,
3743
5496
  resolveUrl: (config) => config.url instanceof URL ? config.url.toString() : _chunkA2YMUCBTcjs.buildProviderApiUrl.call(void 0, provider, { model: actualModel, stream: true }),
3744
5497
  buildHeaders: (config) => ({
3745
- ..._chunkLKZJEL6Ecjs.getProviderHeaders.call(void 0, provider, apiKey),
5498
+ ..._chunkQ27JY5RGcjs.getProviderHeaders.call(void 0, provider, apiKey),
3746
5499
  ...config.headers,
3747
- ..._chunk6VIXXLMXcjs.isOpenRouterProvider.call(void 0, provider) ? _chunk6VIXXLMXcjs.OPENROUTER_APP_HEADERS : {}
5500
+ ..._chunkUNEFIWXIcjs.isOpenRouterProvider.call(void 0, provider) ? _chunkUNEFIWXIcjs.OPENROUTER_APP_HEADERS : {}
3748
5501
  }),
3749
5502
  // Add OpenRouter provider routing config if applicable
3750
5503
  prepareBody: (requestBody) => addOpenRouterProviderToRequest(
@@ -3763,7 +5516,7 @@ async function completeStreamWithTransformers(options, callbacks, llmConfig, get
3763
5516
  });
3764
5517
  if (!response.ok) {
3765
5518
  const errorText = await response.text();
3766
- _optionalChain([callbacks, 'access', _281 => _281.onError, 'optionalCall', _282 => _282(`API error (${response.status}): ${errorText}`)]);
5519
+ _optionalChain([callbacks, 'access', _347 => _347.onError, 'optionalCall', _348 => _348(`API error (${response.status}): ${errorText}`)]);
3767
5520
  return;
3768
5521
  }
3769
5522
  const transformedResponse = await executor.executeResponseChain(
@@ -3773,9 +5526,9 @@ async function completeStreamWithTransformers(options, callbacks, llmConfig, get
3773
5526
  chain,
3774
5527
  { endpointTransformer: void 0 }
3775
5528
  );
3776
- const reader = _optionalChain([transformedResponse, 'access', _283 => _283.body, 'optionalAccess', _284 => _284.getReader, 'call', _285 => _285()]);
5529
+ const reader = _optionalChain([transformedResponse, 'access', _349 => _349.body, 'optionalAccess', _350 => _350.getReader, 'call', _351 => _351()]);
3777
5530
  if (!reader) {
3778
- _optionalChain([callbacks, 'access', _286 => _286.onError, 'optionalCall', _287 => _287("No response body")]);
5531
+ _optionalChain([callbacks, 'access', _352 => _352.onError, 'optionalCall', _353 => _353("No response body")]);
3779
5532
  return;
3780
5533
  }
3781
5534
  const decoder = new TextDecoder();
@@ -3793,22 +5546,22 @@ async function completeStreamWithTransformers(options, callbacks, llmConfig, get
3793
5546
  if (data === "[DONE]") continue;
3794
5547
  try {
3795
5548
  const json = JSON.parse(data);
3796
- const delta = _optionalChain([json, 'access', _288 => _288.choices, 'optionalAccess', _289 => _289[0], 'optionalAccess', _290 => _290.delta]);
3797
- if (_optionalChain([delta, 'optionalAccess', _291 => _291.content])) {
5549
+ const delta = _optionalChain([json, 'access', _354 => _354.choices, 'optionalAccess', _355 => _355[0], 'optionalAccess', _356 => _356.delta]);
5550
+ if (_optionalChain([delta, 'optionalAccess', _357 => _357.content])) {
3798
5551
  content += delta.content;
3799
- _optionalChain([callbacks, 'access', _292 => _292.onDelta, 'optionalCall', _293 => _293(delta.content)]);
5552
+ _optionalChain([callbacks, 'access', _358 => _358.onDelta, 'optionalCall', _359 => _359(delta.content)]);
3800
5553
  }
3801
- if (_optionalChain([delta, 'optionalAccess', _294 => _294.thinking, 'optionalAccess', _295 => _295.content])) {
5554
+ if (_optionalChain([delta, 'optionalAccess', _360 => _360.thinking, 'optionalAccess', _361 => _361.content])) {
3802
5555
  reasoning += delta.thinking.content;
3803
- _optionalChain([callbacks, 'access', _296 => _296.onReasoning, 'optionalCall', _297 => _297(delta.thinking.content)]);
5556
+ _optionalChain([callbacks, 'access', _362 => _362.onReasoning, 'optionalCall', _363 => _363(delta.thinking.content)]);
3804
5557
  }
3805
- if (_optionalChain([delta, 'optionalAccess', _298 => _298.reasoning_content])) {
5558
+ if (_optionalChain([delta, 'optionalAccess', _364 => _364.reasoning_content])) {
3806
5559
  reasoning += delta.reasoning_content;
3807
- _optionalChain([callbacks, 'access', _299 => _299.onReasoning, 'optionalCall', _300 => _300(delta.reasoning_content)]);
5560
+ _optionalChain([callbacks, 'access', _365 => _365.onReasoning, 'optionalCall', _366 => _366(delta.reasoning_content)]);
3808
5561
  }
3809
5562
  if (json.usage) {
3810
5563
  const tapped = readUsageFromOpenAIResponse(json.usage);
3811
- if (_optionalChain([recording, 'optionalAccess', _301 => _301.recorder]) && tapped) {
5564
+ if (_optionalChain([recording, 'optionalAccess', _367 => _367.recorder]) && tapped) {
3812
5565
  recording.recorder.record({
3813
5566
  messageId: _nullishCoalesce(options.messageId, () => ( null)),
3814
5567
  parentMessageId: _nullishCoalesce(options.parentMessageId, () => ( null)),
@@ -3821,7 +5574,7 @@ async function completeStreamWithTransformers(options, callbacks, llmConfig, get
3821
5574
  rawUsage: json.usage
3822
5575
  });
3823
5576
  }
3824
- _optionalChain([callbacks, 'access', _302 => _302.onDone, 'optionalCall', _303 => _303(
5577
+ _optionalChain([callbacks, 'access', _368 => _368.onDone, 'optionalCall', _369 => _369(
3825
5578
  {
3826
5579
  id: messageId,
3827
5580
  role: "assistant",
@@ -3842,7 +5595,7 @@ async function completeStreamWithTransformers(options, callbacks, llmConfig, get
3842
5595
  }
3843
5596
  }
3844
5597
  }
3845
- _optionalChain([callbacks, 'access', _304 => _304.onDone, 'optionalCall', _305 => _305({
5598
+ _optionalChain([callbacks, 'access', _370 => _370.onDone, 'optionalCall', _371 => _371({
3846
5599
  id: messageId,
3847
5600
  role: "assistant",
3848
5601
  content,
@@ -3854,13 +5607,13 @@ async function completeStreamWithTransformers(options, callbacks, llmConfig, get
3854
5607
  }
3855
5608
  } catch (error) {
3856
5609
  const message = error instanceof Error ? error.message : "Unknown error";
3857
- _optionalChain([callbacks, 'access', _306 => _306.onError, 'optionalCall', _307 => _307(message)]);
5610
+ _optionalChain([callbacks, 'access', _372 => _372.onError, 'optionalCall', _373 => _373(message)]);
3858
5611
  }
3859
5612
  }
3860
5613
 
3861
5614
  // src/completion/CompletionService.ts
3862
- var CompletionService = (_class5 = class {
3863
- constructor(paths, llmConfig, logger) {;_class5.prototype.__init10.call(this);_class5.prototype.__init11.call(this);_class5.prototype.__init12.call(this);_class5.prototype.__init13.call(this);
5615
+ var CompletionService = (_class13 = class {
5616
+ constructor(paths, llmConfig, logger) {;_class13.prototype.__init22.call(this);_class13.prototype.__init23.call(this);_class13.prototype.__init24.call(this);_class13.prototype.__init25.call(this);
3864
5617
  this.paths = paths;
3865
5618
  this.llmConfig = llmConfig;
3866
5619
  this.logger = logger;
@@ -3868,10 +5621,10 @@ var CompletionService = (_class5 = class {
3868
5621
 
3869
5622
 
3870
5623
 
3871
- __init10() {this.apiKeyPool = null}
3872
- __init11() {this.usageRecorder = null}
3873
- __init12() {this.usageEventSink = null}
3874
- __init13() {this.visionFallbackProvider = null}
5624
+ __init22() {this.apiKeyPool = null}
5625
+ __init23() {this.usageRecorder = null}
5626
+ __init24() {this.usageEventSink = null}
5627
+ __init25() {this.visionFallbackProvider = null}
3875
5628
  /**
3876
5629
  * Set the API key pool service for multi-key load balancing.
3877
5630
  * When set, keys are resolved via the pool instead of directly from the provider.
@@ -3893,8 +5646,8 @@ var CompletionService = (_class5 = class {
3893
5646
  * emission is unconditional in production. Optional — when unset (unit-test
3894
5647
  * constructors), the emit calls no-op, identical to `usageRecorder`.
3895
5648
  */
3896
- setUsageEventSink(sink) {
3897
- this.usageEventSink = sink;
5649
+ setUsageEventSink(sink2) {
5650
+ this.usageEventSink = sink2;
3898
5651
  }
3899
5652
  /**
3900
5653
  * Set the vision-fallback provider used by `applyVisionFallback` to describe
@@ -3921,8 +5674,8 @@ var CompletionService = (_class5 = class {
3921
5674
  options.providerId,
3922
5675
  options.model
3923
5676
  );
3924
- const actualProviderId = _optionalChain([routedInfo, 'optionalAccess', _308 => _308.actualProviderId]) || options.providerId;
3925
- const actualModel = _optionalChain([routedInfo, 'optionalAccess', _309 => _309.actualModelId]) || options.model;
5677
+ const actualProviderId = _optionalChain([routedInfo, 'optionalAccess', _374 => _374.actualProviderId]) || options.providerId;
5678
+ const actualModel = _optionalChain([routedInfo, 'optionalAccess', _375 => _375.actualModelId]) || options.model;
3926
5679
  const provider = await this.getProvider(actualProviderId);
3927
5680
  if (!provider) {
3928
5681
  return { success: false, error: `Provider not found: ${actualProviderId}` };
@@ -3955,7 +5708,7 @@ var CompletionService = (_class5 = class {
3955
5708
  this.apiKeyPool.reportSuccess(options.sessionId);
3956
5709
  }
3957
5710
  if (result.success && result.usage && options.sessionId) {
3958
- _optionalChain([this, 'access', _310 => _310.usageEventSink, 'optionalAccess', _311 => _311.emit, 'call', _312 => _312({
5711
+ _optionalChain([this, 'access', _376 => _376.usageEventSink, 'optionalAccess', _377 => _377.emit, 'call', _378 => _378({
3959
5712
  sessionId: options.sessionId,
3960
5713
  modelId: actualModel,
3961
5714
  usage: result.usage,
@@ -3984,8 +5737,8 @@ var CompletionService = (_class5 = class {
3984
5737
  options.model
3985
5738
  );
3986
5739
  this.logger.debug("Resolved routed model", { routedInfo });
3987
- const actualProviderId = _optionalChain([routedInfo, 'optionalAccess', _313 => _313.actualProviderId]) || options.providerId;
3988
- const actualModel = _optionalChain([routedInfo, 'optionalAccess', _314 => _314.actualModelId]) || options.model;
5740
+ const actualProviderId = _optionalChain([routedInfo, 'optionalAccess', _379 => _379.actualProviderId]) || options.providerId;
5741
+ const actualModel = _optionalChain([routedInfo, 'optionalAccess', _380 => _380.actualModelId]) || options.model;
3989
5742
  this.logger.debug("Resolved provider and model", { actualProviderId, actualModel });
3990
5743
  const provider = await this.getProvider(actualProviderId);
3991
5744
  this.logger.debug("Retrieved provider", provider ? {
@@ -3997,22 +5750,22 @@ var CompletionService = (_class5 = class {
3997
5750
  enabled: provider.enabled
3998
5751
  } : { error: "Provider not found" });
3999
5752
  if (!provider) {
4000
- _optionalChain([callbacks, 'access', _315 => _315.onError, 'optionalCall', _316 => _316(`Provider not found: ${actualProviderId}`)]);
5753
+ _optionalChain([callbacks, 'access', _381 => _381.onError, 'optionalCall', _382 => _382(`Provider not found: ${actualProviderId}`)]);
4001
5754
  return;
4002
5755
  }
4003
5756
  if (!provider.enabled) {
4004
- _optionalChain([callbacks, 'access', _317 => _317.onError, 'optionalCall', _318 => _318(`Provider is disabled: ${provider.name}`)]);
5757
+ _optionalChain([callbacks, 'access', _383 => _383.onError, 'optionalCall', _384 => _384(`Provider is disabled: ${provider.name}`)]);
4005
5758
  return;
4006
5759
  }
4007
5760
  const apiKey = await this.resolveApiKeyForRequest(provider, actualProviderId, options.sessionId);
4008
5761
  if (!apiKey) {
4009
- _optionalChain([callbacks, 'access', _319 => _319.onError, 'optionalCall', _320 => _320("API key not configured")]);
5762
+ _optionalChain([callbacks, 'access', _385 => _385.onError, 'optionalCall', _386 => _386("API key not configured")]);
4010
5763
  return;
4011
5764
  }
4012
5765
  const apiFormat = _chunkA2YMUCBTcjs.resolveApiFormat.call(void 0, provider);
4013
5766
  this.logger.info("Using API format for stream", { apiFormat });
4014
5767
  const messageId = `msg_${Date.now()}`;
4015
- _optionalChain([callbacks, 'access', _321 => _321.onStart, 'optionalCall', _322 => _322(messageId)]);
5768
+ _optionalChain([callbacks, 'access', _387 => _387.onStart, 'optionalCall', _388 => _388(messageId)]);
4016
5769
  const resolvedOptions = { ...options, model: actualModel };
4017
5770
  if (options.sessionId) {
4018
5771
  const sid = options.sessionId;
@@ -4021,14 +5774,14 @@ var CompletionService = (_class5 = class {
4021
5774
  ...callbacks,
4022
5775
  onDone: (message, usage, metrics) => {
4023
5776
  if (usage) {
4024
- _optionalChain([this, 'access', _323 => _323.usageEventSink, 'optionalAccess', _324 => _324.emit, 'call', _325 => _325({
5777
+ _optionalChain([this, 'access', _389 => _389.usageEventSink, 'optionalAccess', _390 => _390.emit, 'call', _391 => _391({
4025
5778
  sessionId: sid,
4026
5779
  modelId: actualModel,
4027
5780
  usage,
4028
5781
  engineOrigin: "completion"
4029
5782
  })]);
4030
5783
  }
4031
- _optionalChain([userOnDone, 'optionalCall', _326 => _326(message, usage, metrics)]);
5784
+ _optionalChain([userOnDone, 'optionalCall', _392 => _392(message, usage, metrics)]);
4032
5785
  }
4033
5786
  };
4034
5787
  }
@@ -4044,11 +5797,11 @@ var CompletionService = (_class5 = class {
4044
5797
  retryState.error = { status, message: error };
4045
5798
  return;
4046
5799
  }
4047
- _optionalChain([callbacks, 'access', _327 => _327.onError, 'optionalCall', _328 => _328(error)]);
5800
+ _optionalChain([callbacks, 'access', _393 => _393.onError, 'optionalCall', _394 => _394(error)]);
4048
5801
  },
4049
5802
  onDone: (message, usage, metrics) => {
4050
5803
  this.apiKeyPool.reportSuccess(options.sessionId);
4051
- _optionalChain([callbacks, 'access', _329 => _329.onDone, 'optionalCall', _330 => _330(message, usage, metrics)]);
5804
+ _optionalChain([callbacks, 'access', _395 => _395.onDone, 'optionalCall', _396 => _396(message, usage, metrics)]);
4052
5805
  }
4053
5806
  };
4054
5807
  await this.callStreamHandler(apiFormat, provider, apiKey, resolvedOptions, messageId, interceptCallbacks);
@@ -4069,7 +5822,7 @@ var CompletionService = (_class5 = class {
4069
5822
  // don't fire onStart again
4070
5823
  });
4071
5824
  } else {
4072
- _optionalChain([callbacks, 'access', _331 => _331.onError, 'optionalCall', _332 => _332(retryState.error.message)]);
5825
+ _optionalChain([callbacks, 'access', _397 => _397.onError, 'optionalCall', _398 => _398(retryState.error.message)]);
4073
5826
  }
4074
5827
  }
4075
5828
  } else {
@@ -4082,7 +5835,7 @@ var CompletionService = (_class5 = class {
4082
5835
  } catch (error) {
4083
5836
  const message = error instanceof Error ? error.message : "Unknown error";
4084
5837
  this.logger.error("Stream completion error", error instanceof Error ? error : void 0, { message });
4085
- _optionalChain([callbacks, 'access', _333 => _333.onError, 'optionalCall', _334 => _334(message)]);
5838
+ _optionalChain([callbacks, 'access', _399 => _399.onError, 'optionalCall', _400 => _400(message)]);
4086
5839
  }
4087
5840
  }
4088
5841
  /**
@@ -4122,7 +5875,7 @@ var CompletionService = (_class5 = class {
4122
5875
  return {
4123
5876
  success: true,
4124
5877
  message: "Connection successful",
4125
- response: _optionalChain([result, 'access', _335 => _335.message, 'optionalAccess', _336 => _336.content]) || "",
5878
+ response: _optionalChain([result, 'access', _401 => _401.message, 'optionalAccess', _402 => _402.content]) || "",
4126
5879
  model: modelId,
4127
5880
  durationMs
4128
5881
  };
@@ -4187,7 +5940,7 @@ ${description}`;
4187
5940
  * 3. Legacy single key from provider config
4188
5941
  */
4189
5942
  async resolveApiKeyForRequest(provider, providerId, sessionId) {
4190
- if (_optionalChain([provider, 'access', _337 => _337.codingPlan, 'optionalAccess', _338 => _338.enabled]) && provider.codingPlan.apiKey) {
5943
+ if (_optionalChain([provider, 'access', _403 => _403.codingPlan, 'optionalAccess', _404 => _404.enabled]) && provider.codingPlan.apiKey) {
4191
5944
  return this.resolveApiKey(provider.codingPlan.apiKey);
4192
5945
  }
4193
5946
  if (this.apiKeyPool) {
@@ -4352,7 +6105,50 @@ ${description}`;
4352
6105
  builtinExecutor
4353
6106
  );
4354
6107
  }
4355
- }, _class5);
6108
+ }, _class13);
6109
+
6110
+
6111
+
6112
+
6113
+
6114
+
6115
+
6116
+
6117
+
6118
+
6119
+
6120
+
6121
+
6122
+
6123
+
6124
+
6125
+
6126
+
6127
+
6128
+
6129
+
6130
+
6131
+
6132
+
6133
+
6134
+
6135
+
6136
+
6137
+
6138
+
6139
+
6140
+
6141
+
6142
+
6143
+
6144
+
6145
+
6146
+
6147
+
6148
+
6149
+
6150
+
6151
+
4356
6152
 
4357
6153
 
4358
6154
 
@@ -4397,4 +6193,4 @@ ${description}`;
4397
6193
 
4398
6194
 
4399
6195
 
4400
- exports.CompletionService = CompletionService; exports.register = register; exports.emit = emit; exports.attach = attach; exports.release = release; exports.convertMessageToOpenAI = convertMessageToOpenAI; exports.convertMessageToAnthropic = convertMessageToAnthropic; exports.convertMessageToGemini = convertMessageToGemini; exports.getOpenRouterProviderConfig = getOpenRouterProviderConfig; exports.addOpenRouterProviderToRequest = addOpenRouterProviderToRequest; exports.DEFAULT_ROUTE_IDLE_MS = DEFAULT_ROUTE_IDLE_MS; exports.ProviderProxyRouteMap = ProviderProxyRouteMap; exports.getSharedExecutor = getSharedExecutor; exports.getResponsesEndpointTransformer = getResponsesEndpointTransformer; exports.getAnthropicEndpointTransformer = getAnthropicEndpointTransformer; exports.getGeminiEndpointTransformer = getGeminiEndpointTransformer; exports.readBody = readBody; exports.relayResponse = relayResponse; exports.writeError = writeError; exports.resolvePoolBoundKey = resolvePoolBoundKey; exports.extractRouteToken = extractRouteToken; exports.isLoopbackAddress = isLoopbackAddress; exports.ProviderProxy = ProviderProxy; exports.getProviderProxy = getProviderProxy; exports.__resetProviderProxyForTests = __resetProviderProxyForTests; exports.hashKey = hashKey; exports.createNamedKey = createNamedKey; exports.verifyPresentedKey = verifyPresentedKey; exports.detectRequestRole = detectRequestRole; exports.endpointToIngressFormat = endpointToIngressFormat; exports.OutboundRateLimiter = OutboundRateLimiter; exports.DEFAULT_OUTBOUND_PORT = DEFAULT_OUTBOUND_PORT; exports.OutboundApiServer = OutboundApiServer; exports.formatUrls = formatUrls; exports.OUTBOUND_API_SERVER_CONFIG_KEY = OUTBOUND_API_SERVER_CONFIG_KEY; exports.defaultServerConfig = defaultServerConfig; exports.normalizeServerConfig = normalizeServerConfig; exports.loadServerConfig = loadServerConfig; exports.saveServerConfig = saveServerConfig; exports.mergeServerConfig = mergeServerConfig; exports.getOutboundApiServer = getOutboundApiServer; exports.__resetOutboundApiServerForTests = __resetOutboundApiServerForTests;
6196
+ exports.CompletionService = CompletionService; exports.register = register; exports.emit = emit; exports.attach = attach; exports.release = release; exports.convertMessageToOpenAI = convertMessageToOpenAI; exports.convertMessageToAnthropic = convertMessageToAnthropic; exports.convertMessageToGemini = convertMessageToGemini; exports.getOpenRouterProviderConfig = getOpenRouterProviderConfig; exports.addOpenRouterProviderToRequest = addOpenRouterProviderToRequest; exports.DEFAULT_ROUTE_IDLE_MS = DEFAULT_ROUTE_IDLE_MS; exports.ProviderProxyRouteMap = ProviderProxyRouteMap; exports.getSharedExecutor = getSharedExecutor; exports.getResponsesEndpointTransformer = getResponsesEndpointTransformer; exports.getAnthropicEndpointTransformer = getAnthropicEndpointTransformer; exports.getGeminiEndpointTransformer = getGeminiEndpointTransformer; exports.readBody = readBody; exports.relayResponse = relayResponse; exports.writeError = writeError; exports.resolvePoolBoundKey = resolvePoolBoundKey; exports.extractRouteToken = extractRouteToken; exports.isLoopbackAddress = isLoopbackAddress; exports.ProviderProxy = ProviderProxy; exports.getProviderProxy = getProviderProxy; exports.__resetProviderProxyForTests = __resetProviderProxyForTests; exports.KeyedMutex = KeyedMutex; exports.OUTBOUND_API_SERVER_CONFIG_KEY = OUTBOUND_API_SERVER_CONFIG_KEY; exports.DEFAULT_USER_MESSAGE_QUEUE = DEFAULT_USER_MESSAGE_QUEUE; exports.DEFAULT_CONCURRENCY_QUEUE = DEFAULT_CONCURRENCY_QUEUE; exports.DEFAULT_ACCOUNT_PROBE = DEFAULT_ACCOUNT_PROBE; exports.normalizeAccountProbe = normalizeAccountProbe; exports.normalizeAudit = normalizeAudit; exports.normalizeBilling = normalizeBilling; exports.DEFAULT_FINGERPRINT = DEFAULT_FINGERPRINT; exports.normalizeFingerprint = normalizeFingerprint; exports.normalizeVoucher = normalizeVoucher; exports.normalizeProxyConfig = normalizeProxyConfig; exports.normalizeProxySegment = normalizeProxySegment; exports.normalizeWebhookDestination = normalizeWebhookDestination; exports.normalizeWebhookSegment = normalizeWebhookSegment; exports.normalizeQueueSegments = normalizeQueueSegments; exports.normalizePrefixTargets = normalizePrefixTargets; exports.defaultServerConfig = defaultServerConfig; exports.normalizeServerConfig = normalizeServerConfig; exports.loadServerConfig = loadServerConfig; exports.saveServerConfig = saveServerConfig; exports.mergeServerConfig = mergeServerConfig; exports.AUDIT_REDACTED = AUDIT_REDACTED; exports.redactAuditText = redactAuditText; exports.beginAuditCapture = beginAuditCapture; exports.beginBillingCapture = beginBillingCapture; exports.computeKeyExpiry = computeKeyExpiry; exports.checkKeyQuota = checkKeyQuota; exports.randomBase62 = randomBase62; exports.hashKey = hashKey; exports.createNamedKey = createNamedKey; exports.verifyKey = verifyKey; exports.verifyPresentedKey = verifyPresentedKey; exports.ConcurrencyQueueFullError = ConcurrencyQueueFullError; exports.ConcurrencyWaitTimeoutError = ConcurrencyWaitTimeoutError; exports.ConcurrencyWaitCancelledError = ConcurrencyWaitCancelledError; exports.isConcurrencyRejection = isConcurrencyRejection; exports.OutboundConcurrencyGate = OutboundConcurrencyGate; exports.OutboundRateLimiter = OutboundRateLimiter; exports.isUserMessageRequest = isUserMessageRequest; exports.SerialQueueTimeoutError = SerialQueueTimeoutError; exports.isSerialQueueTimeout = isSerialQueueTimeout; exports.UserMessageSerialQueue = UserMessageSerialQueue; exports.generateVoucherCode = generateVoucherCode; exports.hashVoucherCode = hashVoucherCode; exports.voucherCodePrefix = voucherCodePrefix; exports.newVoucherId = newVoucherId; exports.computeVoucherGrant = computeVoucherGrant; exports.toVoucherInfo = toVoucherInfo; exports.isRedeemRequest = isRedeemRequest; exports.handleVoucherRedeem = handleVoucherRedeem; exports.DEFAULT_OUTBOUND_PORT = DEFAULT_OUTBOUND_PORT; exports.OutboundApiConfigError = OutboundApiConfigError; exports.OutboundApiServer = OutboundApiServer; exports.formatUrls = formatUrls; exports.startOfLocalDay = startOfLocalDay; exports.startOfLocalWeek = startOfLocalWeek; exports.KeySpendTracker = KeySpendTracker; exports.getOutboundApiServer = getOutboundApiServer; exports.__resetOutboundApiServerForTests = __resetOutboundApiServerForTests;