@omnicross/core 0.1.5 → 0.1.6

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 (190) hide show
  1. package/dist/ApiConverter.cjs +2 -2
  2. package/dist/ApiConverter.js +1 -1
  3. package/dist/{CompletionService-DdWaAxq0.d.ts → CompletionService-C3BX0Ovy.d.ts} +4 -3
  4. package/dist/{CompletionService-D3a47vdU.d.cts → CompletionService-kNA17cfI.d.cts} +4 -3
  5. package/dist/auth/GeminiCodeAssistProjectResolver.cjs +6 -5
  6. package/dist/auth/GeminiCodeAssistProjectResolver.js +4 -3
  7. package/dist/{chunk-HRRYG2AX.js → chunk-23S5OPIO.js} +10 -1
  8. package/dist/chunk-25GXJCEZ.cjs +40 -0
  9. package/dist/chunk-2JYRIADS.js +40 -0
  10. package/dist/{chunk-4XMYPW46.cjs → chunk-4VLRHHFE.cjs} +75 -33
  11. package/dist/{chunk-VACWOIRE.cjs → chunk-4VZX5F4T.cjs} +39 -15
  12. package/dist/{chunk-C6OV7GCC.js → chunk-6CL5HTPQ.js} +44 -2
  13. package/dist/chunk-6QQG7YG3.cjs +153 -0
  14. package/dist/{chunk-3Q6Z6JTO.cjs → chunk-6VUQPOV3.cjs} +277 -86
  15. package/dist/chunk-7AK7B36B.cjs +44 -0
  16. package/dist/{chunk-5ZQBEOMD.js → chunk-AT7B7SOZ.js} +25 -2
  17. package/dist/{chunk-IK3KE3AU.js → chunk-DE2SRBFZ.js} +1 -1
  18. package/dist/chunk-DLXZEZWO.cjs +285 -0
  19. package/dist/{chunk-UHGVBFU3.js → chunk-EBLFCNPY.js} +38 -14
  20. package/dist/chunk-EJLH6NFT.cjs +166 -0
  21. package/dist/chunk-HVBBDBS3.cjs +350 -0
  22. package/dist/{chunk-46ZIFWYG.cjs → chunk-IIRPUVPH.cjs} +7 -1
  23. package/dist/{chunk-JWVTXXPX.cjs → chunk-KBM2W6UY.cjs} +8 -4
  24. package/dist/{chunk-PG7PS2NN.cjs → chunk-KCVJWJST.cjs} +14 -2
  25. package/dist/chunk-LB6EBS6Y.js +69 -0
  26. package/dist/{chunk-IWQAX3CS.js → chunk-LVUCAWMK.js} +1 -1
  27. package/dist/chunk-MKF46GNZ.js +350 -0
  28. package/dist/{chunk-HYN75H6G.cjs → chunk-MUHWHQVM.cjs} +1 -1
  29. package/dist/{chunk-MFZ5437A.js → chunk-N5T4M4GU.js} +1 -1
  30. package/dist/{chunk-BODMAL6G.js → chunk-OEWZUX4G.js} +262 -71
  31. package/dist/chunk-OF3BECU2.cjs +69 -0
  32. package/dist/{chunk-DDMRUL76.cjs → chunk-OKMJLEXX.cjs} +5 -5
  33. package/dist/chunk-OPRS4IQZ.js +153 -0
  34. package/dist/{chunk-D3TDKWRP.js → chunk-SIZQQD6T.js} +14 -2
  35. package/dist/{chunk-CGKLE6IW.cjs → chunk-SQYVORNP.cjs} +1219 -510
  36. package/dist/{chunk-6QZGDLL4.js → chunk-TOVPMMHM.js} +5 -1
  37. package/dist/{chunk-FH2P4OCD.js → chunk-UDCC7EMR.js} +976 -267
  38. package/dist/{chunk-ZLX3KGXX.js → chunk-UX7VWA46.js} +135 -23
  39. package/dist/{chunk-K52THW2C.cjs → chunk-V4TXMEJS.cjs} +5 -5
  40. package/dist/chunk-VRFBB5DB.js +44 -0
  41. package/dist/chunk-WB6PH56J.js +166 -0
  42. package/dist/{chunk-G2UTNSGU.js → chunk-WNKWAEUR.js} +7 -1
  43. package/dist/{chunk-SUEGJ75D.cjs → chunk-WYTEQ4Q5.cjs} +25 -2
  44. package/dist/{chunk-5ENKBSWO.js → chunk-YJVHCHQX.js} +42 -6
  45. package/dist/{chunk-VQY5W4YW.cjs → chunk-YK57NMIF.cjs} +44 -8
  46. package/dist/{chunk-KFI44N2R.cjs → chunk-YNJNTCSQ.cjs} +10 -1
  47. package/dist/completion/ApiKeyPoolService.cjs +12 -0
  48. package/dist/completion/ApiKeyPoolService.d.cts +6 -0
  49. package/dist/completion/ApiKeyPoolService.d.ts +6 -0
  50. package/dist/completion/ApiKeyPoolService.js +12 -0
  51. package/dist/completion/CompletionService.cjs +25 -23
  52. package/dist/completion/CompletionService.d.cts +2 -1
  53. package/dist/completion/CompletionService.d.ts +2 -1
  54. package/dist/completion/CompletionService.js +24 -22
  55. package/dist/completion.cjs +25 -23
  56. package/dist/completion.d.cts +2 -1
  57. package/dist/completion.d.ts +2 -1
  58. package/dist/completion.js +24 -22
  59. package/dist/index.cjs +49 -26
  60. package/dist/index.d.cts +8 -8
  61. package/dist/index.d.ts +8 -8
  62. package/dist/index.js +52 -29
  63. package/dist/{keyPolicy-Cp0FntZl.d.ts → keyPolicy-zdWTu3CQ.d.cts} +1 -1
  64. package/dist/{keyPolicy-Cp0FntZl.d.cts → keyPolicy-zdWTu3CQ.d.ts} +1 -1
  65. package/dist/outbound-api/quotaWarn.d.cts +1 -1
  66. package/dist/outbound-api/quotaWarn.d.ts +1 -1
  67. package/dist/outbound-api/routeResolver.cjs +2 -2
  68. package/dist/outbound-api/routeResolver.d.cts +4 -3
  69. package/dist/outbound-api/routeResolver.d.ts +4 -3
  70. package/dist/outbound-api/routeResolver.js +1 -1
  71. package/dist/outbound-api/subscriptionRegistryPort.d.cts +1 -0
  72. package/dist/outbound-api/subscriptionRegistryPort.d.ts +1 -0
  73. package/dist/outbound-api/types.d.cts +3 -2
  74. package/dist/outbound-api/types.d.ts +3 -2
  75. package/dist/outbound-api.cjs +47 -24
  76. package/dist/outbound-api.d.cts +127 -85
  77. package/dist/outbound-api.d.ts +127 -85
  78. package/dist/outbound-api.js +50 -27
  79. package/dist/pipeline/AccountAllowanceScheduling.cjs +15 -0
  80. package/dist/pipeline/AccountAllowanceScheduling.d.cts +90 -0
  81. package/dist/pipeline/AccountAllowanceScheduling.d.ts +90 -0
  82. package/dist/pipeline/AccountAllowanceScheduling.js +15 -0
  83. package/dist/pipeline/AccountAllowanceStore.cjs +20 -0
  84. package/dist/pipeline/AccountAllowanceStore.d.cts +77 -0
  85. package/dist/pipeline/AccountAllowanceStore.d.ts +77 -0
  86. package/dist/pipeline/AccountAllowanceStore.js +20 -0
  87. package/dist/pipeline/AuthSource.d.cts +11 -2
  88. package/dist/pipeline/AuthSource.d.ts +11 -2
  89. package/dist/pipeline/BoundAccountSelectionError.cjs +10 -0
  90. package/dist/pipeline/BoundAccountSelectionError.d.cts +28 -0
  91. package/dist/pipeline/BoundAccountSelectionError.d.ts +28 -0
  92. package/dist/pipeline/BoundAccountSelectionError.js +10 -0
  93. package/dist/pipeline/LlmConfigProviderAuth.d.cts +1 -0
  94. package/dist/pipeline/LlmConfigProviderAuth.d.ts +1 -0
  95. package/dist/pipeline/SubscriptionAccountHealth.cjs +4 -2
  96. package/dist/pipeline/SubscriptionAccountHealth.d.cts +34 -6
  97. package/dist/pipeline/SubscriptionAccountHealth.d.ts +34 -6
  98. package/dist/pipeline/SubscriptionAccountHealth.js +3 -1
  99. package/dist/pipeline/SubscriptionAuthSource.cjs +5 -2
  100. package/dist/pipeline/SubscriptionAuthSource.d.cts +1 -0
  101. package/dist/pipeline/SubscriptionAuthSource.d.ts +1 -0
  102. package/dist/pipeline/SubscriptionAuthSource.js +4 -1
  103. package/dist/pipeline/SubscriptionAuthStrategy.d.cts +8 -3
  104. package/dist/pipeline/SubscriptionAuthStrategy.d.ts +8 -3
  105. package/dist/pipeline/executeProviderCall.cjs +2 -2
  106. package/dist/pipeline/executeProviderCall.d.cts +8 -3
  107. package/dist/pipeline/executeProviderCall.d.ts +8 -3
  108. package/dist/pipeline/executeProviderCall.js +1 -1
  109. package/dist/pipeline/resolveProviderChain.d.cts +2 -3
  110. package/dist/pipeline/resolveProviderChain.d.ts +2 -3
  111. package/dist/pipeline/resolveSubscriptionChain.d.cts +1 -0
  112. package/dist/pipeline/resolveSubscriptionChain.d.ts +1 -0
  113. package/dist/pipeline/upstreamFetch.cjs +3 -2
  114. package/dist/pipeline/upstreamFetch.js +2 -1
  115. package/dist/ports/pricing-store.d.cts +4 -3
  116. package/dist/ports/pricing-store.d.ts +4 -3
  117. package/dist/ports.d.cts +4 -3
  118. package/dist/ports.d.ts +4 -3
  119. package/dist/provider-proxy/ProviderProxy.cjs +25 -23
  120. package/dist/provider-proxy/ProviderProxy.d.cts +1 -0
  121. package/dist/provider-proxy/ProviderProxy.d.ts +1 -0
  122. package/dist/provider-proxy/ProviderProxy.js +24 -22
  123. package/dist/provider-proxy/ingress/providerProxyShared.cjs +27 -23
  124. package/dist/provider-proxy/ingress/providerProxyShared.d.cts +34 -5
  125. package/dist/provider-proxy/ingress/providerProxyShared.d.ts +34 -5
  126. package/dist/provider-proxy/ingress/providerProxyShared.js +26 -22
  127. package/dist/provider-proxy/matchText.cjs +4 -2
  128. package/dist/provider-proxy/matchText.d.cts +41 -6
  129. package/dist/provider-proxy/matchText.d.ts +41 -6
  130. package/dist/provider-proxy/matchText.js +3 -1
  131. package/dist/provider-proxy/types.d.cts +30 -2
  132. package/dist/provider-proxy/types.d.ts +30 -2
  133. package/dist/provider-proxy.cjs +25 -23
  134. package/dist/provider-proxy.d.cts +1 -0
  135. package/dist/provider-proxy.d.ts +1 -0
  136. package/dist/provider-proxy.js +24 -22
  137. package/dist/{routeResolver-C4T7yClx.d.ts → routeResolver-CHTv_Bs5.d.ts} +1 -1
  138. package/dist/{routeResolver-CB3tvJKy.d.cts → routeResolver-kepxnfcC.d.cts} +1 -1
  139. package/dist/transformer/TransformerChainExecutor.cjs +2 -2
  140. package/dist/transformer/TransformerChainExecutor.js +1 -1
  141. package/dist/transformer/transformers/AnthropicTransformer.cjs +2 -2
  142. package/dist/transformer/transformers/AnthropicTransformer.js +1 -1
  143. package/dist/transformer/transformers/GeminiCodeAssistTransformer.cjs +3 -3
  144. package/dist/transformer/transformers/GeminiCodeAssistTransformer.js +2 -2
  145. package/dist/transformer/transformers/GeminiTransformer.cjs +3 -3
  146. package/dist/transformer/transformers/GeminiTransformer.js +2 -2
  147. package/dist/transformer/transformers/OpenAIResponseTransformer.cjs +2 -2
  148. package/dist/transformer/transformers/OpenAIResponseTransformer.d.cts +1 -1
  149. package/dist/transformer/transformers/OpenAIResponseTransformer.d.ts +1 -1
  150. package/dist/transformer/transformers/OpenAIResponseTransformer.js +1 -1
  151. package/dist/transformer/transformers/OpenAITransformer.cjs +6 -0
  152. package/dist/transformer/transformers/OpenAITransformer.d.cts +68 -0
  153. package/dist/transformer/transformers/OpenAITransformer.d.ts +68 -0
  154. package/dist/transformer/transformers/OpenAITransformer.js +6 -0
  155. package/dist/transformer/transformers.cjs +8 -14
  156. package/dist/transformer/transformers.d.cts +12 -48
  157. package/dist/transformer/transformers.d.ts +12 -48
  158. package/dist/transformer/transformers.js +12 -18
  159. package/dist/transformer/types.d.cts +17 -0
  160. package/dist/transformer/types.d.ts +17 -0
  161. package/dist/transformer.cjs +10 -11
  162. package/dist/transformer.d.cts +1 -2
  163. package/dist/transformer.d.ts +1 -2
  164. package/dist/transformer.js +9 -10
  165. package/dist/{types-B8Arpxn0.d.cts → types-H3wGZSOo.d.cts} +134 -7
  166. package/dist/{types-lgPYQuZS.d.ts → types-hsoKrVQS.d.ts} +134 -7
  167. package/dist/usage/pricing-engine.cjs +2 -2
  168. package/dist/usage/pricing-engine.d.cts +9 -1
  169. package/dist/usage/pricing-engine.d.ts +9 -1
  170. package/dist/usage/pricing-engine.js +1 -1
  171. package/dist/usage.cjs +2 -2
  172. package/dist/usage.js +1 -1
  173. package/package.json +1 -1
  174. package/dist/chunk-7FEBOPJO.cjs +0 -50
  175. package/dist/chunk-DWKQZ2SK.cjs +0 -254
  176. package/dist/chunk-IAXWICZU.js +0 -69
  177. package/dist/chunk-IB3FDI4O.js +0 -50
  178. package/dist/chunk-OQWKZCXP.js +0 -242
  179. package/dist/chunk-QWBWGODS.cjs +0 -69
  180. package/dist/chunk-YMFAJFQT.cjs +0 -173
  181. package/dist/chunk-ZCIQ3L3R.cjs +0 -242
  182. package/dist/chunk-ZJZAOKI7.js +0 -254
  183. package/dist/transformer/transformers/OpenCodeGoTransformer.cjs +0 -6
  184. package/dist/transformer/transformers/OpenCodeGoTransformer.d.cts +0 -51
  185. package/dist/transformer/transformers/OpenCodeGoTransformer.d.ts +0 -51
  186. package/dist/transformer/transformers/OpenCodeGoTransformer.js +0 -6
  187. package/dist/transformer/transformers/ReasoningTransformer.cjs +0 -6
  188. package/dist/transformer/transformers/ReasoningTransformer.d.cts +0 -47
  189. package/dist/transformer/transformers/ReasoningTransformer.d.ts +0 -47
  190. package/dist/transformer/transformers/ReasoningTransformer.js +0 -6
@@ -1,21 +1,30 @@
1
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;
2
2
 
3
+
4
+
5
+ var _chunkEJLH6NFTcjs = require('./chunk-EJLH6NFT.cjs');
6
+
7
+
3
8
  var _chunkHQP3K7PUcjs = require('./chunk-HQP3K7PU.cjs');
4
9
 
5
10
 
6
- var _chunk46ZIFWYGcjs = require('./chunk-46ZIFWYG.cjs');
11
+ var _chunkIIRPUVPHcjs = require('./chunk-IIRPUVPH.cjs');
12
+
7
13
 
14
+ var _chunkGBHYAGX3cjs = require('./chunk-GBHYAGX3.cjs');
8
15
 
9
- var _chunk4XMYPW46cjs = require('./chunk-4XMYPW46.cjs');
10
16
 
17
+ var _chunkV4TXMEJScjs = require('./chunk-V4TXMEJS.cjs');
11
18
 
12
- var _chunkK52THW2Ccjs = require('./chunk-K52THW2C.cjs');
13
19
 
20
+ var _chunk6VUQPOV3cjs = require('./chunk-6VUQPOV3.cjs');
14
21
 
15
- var _chunk3Q6Z6JTOcjs = require('./chunk-3Q6Z6JTO.cjs');
16
22
 
17
23
 
18
- var _chunkGBHYAGX3cjs = require('./chunk-GBHYAGX3.cjs');
24
+ var _chunk4VLRHHFEcjs = require('./chunk-4VLRHHFE.cjs');
25
+
26
+
27
+ var _chunkR3HK6R4Bcjs = require('./chunk-R3HK6R4B.cjs');
19
28
 
20
29
 
21
30
  var _chunkRPII3E6Zcjs = require('./chunk-RPII3E6Z.cjs');
@@ -25,37 +34,37 @@ var _chunkRPII3E6Zcjs = require('./chunk-RPII3E6Z.cjs');
25
34
  var _chunk6RPZADX3cjs = require('./chunk-6RPZADX3.cjs');
26
35
 
27
36
 
37
+ var _chunkNYUNU75Acjs = require('./chunk-NYUNU75A.cjs');
28
38
 
29
- var _chunkQWBWGODScjs = require('./chunk-QWBWGODS.cjs');
30
39
 
31
40
 
32
- var _chunkUIBD2YY5cjs = require('./chunk-UIBD2YY5.cjs');
41
+ var _chunkYK57NMIFcjs = require('./chunk-YK57NMIF.cjs');
33
42
 
34
43
 
35
- var _chunkR3HK6R4Bcjs = require('./chunk-R3HK6R4B.cjs');
44
+ var _chunkYNJNTCSQcjs = require('./chunk-YNJNTCSQ.cjs');
36
45
 
37
46
 
38
- var _chunkHYN75H6Gcjs = require('./chunk-HYN75H6G.cjs');
47
+ var _chunkSVNDB62Dcjs = require('./chunk-SVNDB62D.cjs');
39
48
 
40
49
 
50
+ var _chunkUIBD2YY5cjs = require('./chunk-UIBD2YY5.cjs');
41
51
 
42
- var _chunkQ27JY5RGcjs = require('./chunk-Q27JY5RG.cjs');
43
52
 
53
+ var _chunk6QQG7YG3cjs = require('./chunk-6QQG7YG3.cjs');
44
54
 
45
- var _chunkQXD4MV2Xcjs = require('./chunk-QXD4MV2X.cjs');
46
55
 
47
56
 
48
- var _chunkNYUNU75Acjs = require('./chunk-NYUNU75A.cjs');
57
+ var _chunk25GXJCEZcjs = require('./chunk-25GXJCEZ.cjs');
49
58
 
50
59
 
60
+ var _chunkMUHWHQVMcjs = require('./chunk-MUHWHQVM.cjs');
51
61
 
52
- var _chunkVQY5W4YWcjs = require('./chunk-VQY5W4YW.cjs');
53
62
 
54
63
 
55
- var _chunkKFI44N2Rcjs = require('./chunk-KFI44N2R.cjs');
64
+ var _chunkQ27JY5RGcjs = require('./chunk-Q27JY5RG.cjs');
56
65
 
57
66
 
58
- var _chunkSVNDB62Dcjs = require('./chunk-SVNDB62D.cjs');
67
+ var _chunkQXD4MV2Xcjs = require('./chunk-QXD4MV2X.cjs');
59
68
 
60
69
 
61
70
  var _chunkAPYG5QD7cjs = require('./chunk-APYG5QD7.cjs');
@@ -72,7 +81,8 @@ var _chunk4YINUUKQcjs = require('./chunk-4YINUUKQ.cjs');
72
81
 
73
82
 
74
83
 
75
- var _chunkVACWOIREcjs = require('./chunk-VACWOIRE.cjs');
84
+
85
+ var _chunk4VZX5F4Tcjs = require('./chunk-4VZX5F4T.cjs');
76
86
 
77
87
 
78
88
 
@@ -84,10 +94,10 @@ var _chunkUNWKG6EIcjs = require('./chunk-UNWKG6EI.cjs');
84
94
 
85
95
 
86
96
 
87
- var _chunkSUEGJ75Dcjs = require('./chunk-SUEGJ75D.cjs');
97
+ var _chunkWYTEQ4Q5cjs = require('./chunk-WYTEQ4Q5.cjs');
88
98
 
89
99
 
90
- var _chunkPG7PS2NNcjs = require('./chunk-PG7PS2NN.cjs');
100
+ var _chunkKCVJWJSTcjs = require('./chunk-KCVJWJST.cjs');
91
101
 
92
102
 
93
103
  var _chunkJMJBSACDcjs = require('./chunk-JMJBSACD.cjs');
@@ -486,48 +496,61 @@ function readAnthropicUsage(usage) {
486
496
  reasoningTokens: 0
487
497
  };
488
498
  }
499
+ function emitAnthropicUsageRecord(recorder, rawUsage, attribution) {
500
+ const tapped = readAnthropicUsage(rawUsage);
501
+ if (!tapped) return;
502
+ recorder.record({
503
+ messageId: null,
504
+ parentMessageId: null,
505
+ sessionId: attribution.sessionId,
506
+ providerId: attribution.providerId,
507
+ model: attribution.model,
508
+ apiKeyId: attribution.apiKeyId,
509
+ auditResponse: attribution.auditResponse,
510
+ engineOrigin: "codex-ingress",
511
+ usage: tapped,
512
+ rawUsage
513
+ });
514
+ }
489
515
  function recordAnthropicNonStreamUsage(recorder, bodyText, attribution) {
490
516
  try {
491
517
  const parsed = JSON.parse(bodyText);
492
- const tapped = readAnthropicUsage(parsed.usage);
493
- if (!tapped) return;
494
- recorder.record({
495
- messageId: null,
496
- parentMessageId: null,
497
- sessionId: attribution.sessionId,
498
- providerId: attribution.providerId,
499
- model: attribution.model,
500
- apiKeyId: attribution.apiKeyId,
501
- engineOrigin: "codex-ingress",
502
- usage: tapped,
503
- rawUsage: parsed.usage,
504
- auditResponse: attribution.auditResponse
505
- });
518
+ emitAnthropicUsageRecord(
519
+ recorder,
520
+ parsed.usage,
521
+ attribution
522
+ );
506
523
  } catch (e4) {
507
524
  }
508
525
  }
526
+ function recordAnthropicStreamUsage(recorder, rawUsage, attribution) {
527
+ try {
528
+ emitAnthropicUsageRecord(recorder, rawUsage, attribution);
529
+ } catch (e5) {
530
+ }
531
+ }
509
532
 
510
533
  // src/provider-proxy/ingress/providerProxyShared.ts
511
534
  var sharedExecutor = null;
512
535
  function getSharedExecutor() {
513
536
  if (!sharedExecutor) {
514
- sharedExecutor = new (0, _chunk46ZIFWYGcjs.TransformerChainExecutor)();
537
+ sharedExecutor = new (0, _chunkIIRPUVPHcjs.TransformerChainExecutor)();
515
538
  }
516
539
  return sharedExecutor;
517
540
  }
518
541
  var sharedResponses = null;
519
542
  function getResponsesEndpointTransformer() {
520
- if (!sharedResponses) sharedResponses = new (0, _chunk3Q6Z6JTOcjs.OpenAIResponseTransformer)();
543
+ if (!sharedResponses) sharedResponses = new (0, _chunk6VUQPOV3cjs.OpenAIResponseTransformer)();
521
544
  return sharedResponses;
522
545
  }
523
546
  var sharedAnthropic = null;
524
547
  function getAnthropicEndpointTransformer() {
525
- if (!sharedAnthropic) sharedAnthropic = new (0, _chunk4XMYPW46cjs.AnthropicTransformer)();
548
+ if (!sharedAnthropic) sharedAnthropic = new (0, _chunk4VLRHHFEcjs.AnthropicTransformer)();
526
549
  return sharedAnthropic;
527
550
  }
528
551
  var sharedGemini = null;
529
552
  function getGeminiEndpointTransformer() {
530
- if (!sharedGemini) sharedGemini = new (0, _chunkK52THW2Ccjs.GeminiTransformer)();
553
+ if (!sharedGemini) sharedGemini = new (0, _chunkV4TXMEJScjs.GeminiTransformer)();
531
554
  return sharedGemini;
532
555
  }
533
556
  function readBody(req) {
@@ -553,7 +576,7 @@ function rewriteJsonModel(bodyText, rewriteModel) {
553
576
  changed = true;
554
577
  }
555
578
  return changed ? JSON.stringify(obj) : bodyText;
556
- } catch (e5) {
579
+ } catch (e6) {
557
580
  return bodyText;
558
581
  }
559
582
  }
@@ -586,11 +609,22 @@ function rewriteSseLine(line, rewriteModel) {
586
609
  }
587
610
  if (!changed) return line;
588
611
  return `data:${leadingSpace}${JSON.stringify(obj)}${newline}`;
589
- } catch (e6) {
612
+ } catch (e7) {
590
613
  return line;
591
614
  }
592
615
  }
593
- async function relayStreamWithModelRewrite(res, body, rewriteModel) {
616
+ function tapSseDataLine(line, onEvent) {
617
+ const leadingStripped = line.replace(/^\s+/, "");
618
+ if (!leadingStripped.startsWith("data:")) return;
619
+ const payload = leadingStripped.slice(5).trim();
620
+ if (!payload || payload === "[DONE]") return;
621
+ try {
622
+ onEvent(JSON.parse(payload));
623
+ } catch (e8) {
624
+ }
625
+ }
626
+ async function relaySseBody(res, body, options) {
627
+ const { rewriteModel, onSseEvent } = options;
594
628
  const reader = body.getReader();
595
629
  const decoder = new TextDecoder();
596
630
  let buffer = "";
@@ -604,21 +638,26 @@ async function relayStreamWithModelRewrite(res, body, rewriteModel) {
604
638
  while ((nlIndex = buffer.indexOf("\n")) !== -1) {
605
639
  const linePart = buffer.slice(0, nlIndex + 1);
606
640
  buffer = buffer.slice(nlIndex + 1);
607
- out += rewriteSseLine(linePart, rewriteModel);
641
+ if (onSseEvent) tapSseDataLine(linePart, onSseEvent);
642
+ out += rewriteModel ? rewriteSseLine(linePart, rewriteModel) : linePart;
608
643
  }
609
644
  if (out) res.write(out);
610
645
  }
611
646
  const tail = buffer + decoder.decode();
612
- if (tail) res.write(rewriteSseLine(tail, rewriteModel));
647
+ if (tail) {
648
+ if (onSseEvent) tapSseDataLine(tail, onSseEvent);
649
+ res.write(rewriteModel ? rewriteSseLine(tail, rewriteModel) : tail);
650
+ }
613
651
  } finally {
614
652
  reader.releaseLock();
615
653
  res.end();
616
654
  }
617
655
  }
618
- async function relayResponse(res, providerResponse, isStream, rewriteModel) {
656
+ async function relayResponse(res, providerResponse, isStream, rewriteModel, usageTap) {
619
657
  const contentType = _nullishCoalesce(providerResponse.headers.get("Content-Type"), () => ( ""));
620
658
  const status = providerResponse.status && providerResponse.status >= 100 ? providerResponse.status : 200;
621
- if (isStream || contentType.includes("text/event-stream")) {
659
+ const upstreamIsSse = contentType.includes("text/event-stream");
660
+ if (upstreamIsSse || isStream && status < 400) {
622
661
  res.writeHead(status, {
623
662
  "Content-Type": "text/event-stream",
624
663
  "Cache-Control": "no-cache",
@@ -628,8 +667,16 @@ async function relayResponse(res, providerResponse, isStream, rewriteModel) {
628
667
  res.end();
629
668
  return null;
630
669
  }
631
- if (rewriteModel) {
632
- await relayStreamWithModelRewrite(res, providerResponse.body, rewriteModel);
670
+ if (rewriteModel || usageTap) {
671
+ let capturedUsage = null;
672
+ await relaySseBody(res, providerResponse.body, {
673
+ rewriteModel,
674
+ onSseEvent: usageTap ? (event) => {
675
+ const raw = usageTap.extractUsage(event);
676
+ if (raw) capturedUsage = raw;
677
+ } : void 0
678
+ });
679
+ if (capturedUsage) usageTap.onUsage(capturedUsage);
633
680
  return null;
634
681
  }
635
682
  const reader = providerResponse.body.getReader();
@@ -670,7 +717,7 @@ async function aggregateAnthropicSseToJsonBody(response, rewriteModel) {
670
717
  let ev;
671
718
  try {
672
719
  ev = JSON.parse(payload);
673
- } catch (e7) {
720
+ } catch (e9) {
674
721
  continue;
675
722
  }
676
723
  switch (ev["type"]) {
@@ -725,7 +772,7 @@ async function aggregateAnthropicSseToJsonBody(response, rewriteModel) {
725
772
  let input = {};
726
773
  try {
727
774
  input = blk.inputJson ? JSON.parse(blk.inputJson) : {};
728
- } catch (e8) {
775
+ } catch (e10) {
729
776
  input = {};
730
777
  }
731
778
  return { type: "tool_use", id: _nullishCoalesce(blk.id, () => ( "")), name: _nullishCoalesce(blk.name, () => ( "")), input };
@@ -745,6 +792,27 @@ function writeError(res, status, message) {
745
792
  res.writeHead(status, { "Content-Type": "application/json" });
746
793
  res.end(JSON.stringify({ error: { type: "provider_proxy_error", message } }));
747
794
  }
795
+ function writeBoundAccountError(res, error) {
796
+ if (res.headersSent) return;
797
+ const headers = { "Content-Type": "application/json" };
798
+ if (error.status === 429 && error.resumeAt) {
799
+ const resumeMs = Date.parse(error.resumeAt);
800
+ if (Number.isFinite(resumeMs)) {
801
+ headers["Retry-After"] = String(Math.max(1, Math.ceil((resumeMs - Date.now()) / 1e3)));
802
+ }
803
+ }
804
+ res.writeHead(error.status, headers);
805
+ res.end(
806
+ JSON.stringify({
807
+ error: {
808
+ type: "provider_proxy_error",
809
+ code: error.code,
810
+ reason: error.reason,
811
+ message: _chunk25GXJCEZcjs.boundAccountSelectionMessage.call(void 0, error.reason)
812
+ }
813
+ })
814
+ );
815
+ }
748
816
  function resolveApiKey(apiKey) {
749
817
  if (!apiKey) return "";
750
818
  if (apiKey.startsWith("$")) {
@@ -752,7 +820,12 @@ function resolveApiKey(apiKey) {
752
820
  }
753
821
  return apiKey;
754
822
  }
755
- async function resolvePoolBoundKey(deps, providerId, provider, sessionId) {
823
+ async function resolvePoolBoundKey(deps, providerId, provider, sessionId, preferredKeyId, boundKeyFallbackPolicy) {
824
+ if (preferredKeyId) {
825
+ const preferred = await _optionalChain([deps, 'access', _8 => _8.apiKeyPool, 'optionalAccess', _9 => _9.getKeyById, 'call', _10 => _10(providerId, preferredKeyId, sessionId)]);
826
+ if (preferred) return preferred;
827
+ if (boundKeyFallbackPolicy !== "pool") return "";
828
+ }
756
829
  if (deps.apiKeyPool && sessionId) {
757
830
  const poolKey = await deps.apiKeyPool.getKeyForSession(providerId, sessionId);
758
831
  if (poolKey) return poolKey;
@@ -775,7 +848,7 @@ async function buildSubscriptionPlan(res, route, deps, anthropicBody, routeModel
775
848
  resolvedModel = mapped.resolvedModel;
776
849
  scenario = mapped.scenario;
777
850
  }
778
- const sessionKey = _chunkQWBWGODScjs.deriveSubscriptionSessionKey.call(void 0, anthropicBody);
851
+ const sessionKey = _chunkEJLH6NFTcjs.deriveSubscriptionSessionKey.call(void 0, anthropicBody);
779
852
  const plan = buildSubscriptionIterationPlan(profile, route, deps, resolvedModel, isStream, scenario, sessionKey);
780
853
  if (!plan) {
781
854
  writeError(res, 502, "Subscription profile is missing resolveUpstreamUrl");
@@ -784,11 +857,11 @@ async function buildSubscriptionPlan(res, route, deps, anthropicBody, routeModel
784
857
  return plan;
785
858
  }
786
859
  function buildSubscriptionIterationPlan(profile, route, deps, resolvedModel, isStream, scenario, sessionKey) {
787
- const upstreamUrl = _optionalChain([profile, 'access', _8 => _8.resolveUpstreamUrl, 'optionalCall', _9 => _9(resolvedModel, route.subscriptionConfig)]);
860
+ const upstreamUrl = _optionalChain([profile, 'access', _11 => _11.resolveUpstreamUrl, 'optionalCall', _12 => _12(resolvedModel, route.subscriptionConfig)]);
788
861
  if (!upstreamUrl) return null;
789
- const auth = _nullishCoalesce(route.auth, () => ( new (0, _chunkKFI44N2Rcjs.SubscriptionAuthSource)(profile)));
862
+ const auth = _nullishCoalesce(route.auth, () => ( new (0, _chunkYNJNTCSQcjs.SubscriptionAuthSource)(profile)));
790
863
  const sameFormat = profile.mode === "pass-through" || upstreamUrl.endsWith("/v1/messages");
791
- const overrideNames = _optionalChain([profile, 'access', _10 => _10.resolveProviderTransformerNames, 'optionalCall', _11 => _11(
864
+ const overrideNames = _optionalChain([profile, 'access', _13 => _13.resolveProviderTransformerNames, 'optionalCall', _14 => _14(
792
865
  resolvedModel,
793
866
  route.subscriptionConfig
794
867
  )]);
@@ -807,6 +880,8 @@ function buildSubscriptionIterationPlan(profile, route, deps, resolvedModel, isS
807
880
  return {
808
881
  auth,
809
882
  preferredAccountId: route.preferredAccountId,
883
+ preferredAccountGroup: route.preferredAccountGroup,
884
+ boundAccountFallbackPolicy: route.boundAccountFallbackPolicy,
810
885
  chain,
811
886
  transformerProvider,
812
887
  resolvedModel,
@@ -851,7 +926,7 @@ function buildSubscriptionRequestSummary(anthropicBody) {
851
926
  estimatedInputTokens: Math.ceil(totalChars / 4),
852
927
  // Single source of truth (shared with the dispatcher builder) so both
853
928
  // ingress paths yield identical `matchText` for the same body.
854
- matchText: _chunkQWBWGODScjs.collectMatchText.call(void 0, anthropicBody)
929
+ matchText: _chunkEJLH6NFTcjs.collectMatchText.call(void 0, anthropicBody)
855
930
  };
856
931
  }
857
932
  function collectText(value) {
@@ -881,13 +956,15 @@ async function runPipeline(anthropicBody, plan, reportSelection) {
881
956
  model: resolvedModel,
882
957
  sessionKey: plan.sessionKey,
883
958
  preferredAccountId: plan.preferredAccountId,
959
+ preferredAccountGroup: plan.preferredAccountGroup,
960
+ boundAccountFallbackPolicy: plan.boundAccountFallbackPolicy,
884
961
  reportSelection: (accountId, isActive) => {
885
962
  proxyAccountId = accountId;
886
- _optionalChain([reportSelection, 'optionalCall', _12 => _12(accountId, isActive)]);
963
+ _optionalChain([reportSelection, 'optionalCall', _15 => _15(accountId, isActive)]);
887
964
  }
888
965
  });
889
966
  let rawStatus = null;
890
- const { response } = await _chunkHYN75H6Gcjs.executeProviderCall.call(void 0, {
967
+ const { response } = await _chunkMUHWHQVMcjs.executeProviderCall.call(void 0, {
891
968
  executor,
892
969
  request: anthropicBody,
893
970
  provider: transformerProvider,
@@ -905,7 +982,7 @@ async function runPipeline(anthropicBody, plan, reportSelection) {
905
982
  },
906
983
  fetchFn: (url, headers, body) => {
907
984
  console.info(`[ProviderProxy:anthropic] -> ${url} model=${resolvedModel} stream=${isStream}`);
908
- return _chunkPG7PS2NNcjs.fetchUpstream.call(void 0,
985
+ return _chunkKCVJWJSTcjs.fetchUpstream.call(void 0,
909
986
  url,
910
987
  { method: "POST", headers, body: JSON.stringify(body) },
911
988
  { providerId: proxyProviderId(plan), accountId: proxyAccountId }
@@ -927,10 +1004,12 @@ async function runSubscriptionSameFormatFetch(rawBody, plan, reportSelection, op
927
1004
  model: plan.resolvedModel,
928
1005
  sessionKey: plan.sessionKey,
929
1006
  preferredAccountId: plan.preferredAccountId,
1007
+ preferredAccountGroup: plan.preferredAccountGroup,
1008
+ boundAccountFallbackPolicy: plan.boundAccountFallbackPolicy,
930
1009
  reportSelection: (accountId, isActive, remapped) => {
931
1010
  proxyAccountId = accountId;
932
1011
  remappedModel = remapped;
933
- _optionalChain([reportSelection, 'optionalCall', _13 => _13(accountId, isActive, remapped)]);
1012
+ _optionalChain([reportSelection, 'optionalCall', _16 => _16(accountId, isActive, remapped)]);
934
1013
  }
935
1014
  });
936
1015
  if (plan.isSubscription && plan.transformerProvider.name === "claude") {
@@ -948,7 +1027,7 @@ async function runSubscriptionSameFormatFetch(rawBody, plan, reportSelection, op
948
1027
  console.info(
949
1028
  `[ProviderProxy:anthropic] (subscription same-format) -> ${plan.upstreamUrl} model=${outboundModel} stream=${plan.isStream}`
950
1029
  );
951
- const response = await _chunkPG7PS2NNcjs.fetchUpstream.call(void 0,
1030
+ const response = await _chunkKCVJWJSTcjs.fetchUpstream.call(void 0,
952
1031
  plan.upstreamUrl,
953
1032
  { method: "POST", headers, body: outboundBody },
954
1033
  { providerId: proxyProviderId(plan), accountId: proxyAccountId }
@@ -964,7 +1043,7 @@ function rewriteBodyModel(rawBody, model) {
964
1043
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return rawBody;
965
1044
  parsed.model = model;
966
1045
  return JSON.stringify(parsed);
967
- } catch (e9) {
1046
+ } catch (e11) {
968
1047
  return rawBody;
969
1048
  }
970
1049
  }
@@ -977,7 +1056,7 @@ async function runSubscriptionAttemptWith401Retry(anthropicBody, relayBody, plan
977
1056
  const first = await runOnce();
978
1057
  let result = first;
979
1058
  if (first.rawStatus === 401) {
980
- const refreshed = await _optionalChain([plan, 'access', _14 => _14.auth, 'access', _15 => _15.onUnauthorized, 'optionalCall', _16 => _16(plan.sessionKey)]);
1059
+ const refreshed = await _optionalChain([plan, 'access', _17 => _17.auth, 'access', _18 => _18.onUnauthorized, 'optionalCall', _19 => _19(plan.sessionKey)]);
981
1060
  if (refreshed) {
982
1061
  console.info("[ProviderProxy:anthropic] 401 \u2192 token refreshed; retrying once");
983
1062
  result = await runOnce();
@@ -992,7 +1071,7 @@ async function readBoundedBody(response, max = 2048) {
992
1071
  try {
993
1072
  const text = await response.clone().text();
994
1073
  return text.slice(0, max);
995
- } catch (e10) {
1074
+ } catch (e12) {
996
1075
  return void 0;
997
1076
  }
998
1077
  }
@@ -1000,9 +1079,9 @@ async function markSubscriptionHealth(plan, selectedAccountId, result) {
1000
1079
  if (!plan.isSubscription || selectedAccountId === void 0) return;
1001
1080
  const providerId = plan.transformerProvider.name;
1002
1081
  const status = result.rawStatus;
1003
- const { resetHeaderSeconds, retryAfterSeconds } = _chunkVQY5W4YWcjs.resolveResetSeconds.call(void 0, providerId, result.response.headers);
1082
+ const { resetHeaderSeconds, retryAfterSeconds } = _chunkYK57NMIFcjs.resolveResetSeconds.call(void 0, providerId, result.response.headers);
1004
1083
  const bodyText = status === 403 ? await readBoundedBody(result.response) : void 0;
1005
- _chunkVQY5W4YWcjs.getSharedAccountHealth.call(void 0, ).recordUpstreamOutcome(providerId, selectedAccountId, {
1084
+ _chunkYK57NMIFcjs.getSharedAccountHealth.call(void 0, ).recordUpstreamOutcome(providerId, selectedAccountId, {
1006
1085
  status,
1007
1086
  resetHeaderSeconds,
1008
1087
  retryAfterSeconds,
@@ -1020,7 +1099,7 @@ function breakerOutcome(rawStatus) {
1020
1099
  function recordBreakerOutcome(profile, modelId, rawStatus) {
1021
1100
  const outcome = breakerOutcome(rawStatus);
1022
1101
  if (outcome === "neutral") return;
1023
- _optionalChain([profile, 'optionalAccess', _17 => _17.recordModelOutcome, 'optionalCall', _18 => _18(modelId, outcome === "success")]);
1102
+ _optionalChain([profile, 'optionalAccess', _20 => _20.recordModelOutcome, 'optionalCall', _21 => _21(modelId, outcome === "success")]);
1024
1103
  }
1025
1104
  async function runSubscriptionAttemptOutcome(anthropicBody, relayBody, plan, options = {}) {
1026
1105
  try {
@@ -1039,7 +1118,7 @@ function settleOutcome(outcome) {
1039
1118
  async function runPipelineWithSubscriptionRetry(anthropicBody, rawBody, initialPlan, route, deps, options = {}) {
1040
1119
  const profile = route.subscriptionProfile;
1041
1120
  const scenario = initialPlan.scenario;
1042
- if (!_optionalChain([profile, 'optionalAccess', _19 => _19.nextFallback]) || scenario === void 0) {
1121
+ if (!_optionalChain([profile, 'optionalAccess', _22 => _22.nextFallback]) || scenario === void 0) {
1043
1122
  const loneOutcome = await runSubscriptionAttemptOutcome(anthropicBody, rawBody, initialPlan, options);
1044
1123
  recordBreakerOutcome(profile, initialPlan.resolvedModel, outcomeStatus(loneOutcome));
1045
1124
  return settleOutcome(loneOutcome);
@@ -1103,7 +1182,7 @@ async function handleAnthropicMessagesByo(res, rawBody, route, deps, options = {
1103
1182
  let anthropicBody;
1104
1183
  try {
1105
1184
  anthropicBody = JSON.parse(rawBody);
1106
- } catch (e11) {
1185
+ } catch (e13) {
1107
1186
  writeError(res, 400, "Invalid JSON in request body");
1108
1187
  return;
1109
1188
  }
@@ -1119,6 +1198,35 @@ async function handleAnthropicMessagesByo(res, rawBody, route, deps, options = {
1119
1198
  const upstreamSse = (_nullishCoalesce(upstreamResponse.headers.get("content-type"), () => ( ""))).includes(
1120
1199
  "text/event-stream"
1121
1200
  );
1201
+ const usageAttribution = {
1202
+ sessionId: route.sessionId,
1203
+ providerId: _nullishCoalesce(route.providerId, () => ( "anthropic")),
1204
+ model: plan.resolvedModel,
1205
+ apiKeyId: _nullishCoalesce(route.apiKeyId, () => ( null)),
1206
+ // request-audit-log: correlate this request's tokens/cost to its audit record.
1207
+ auditResponse: res
1208
+ };
1209
+ const usageRecorder = deps.usageRecorder;
1210
+ let anthropicInputUsage;
1211
+ const usageTap = usageRecorder ? {
1212
+ extractUsage(event) {
1213
+ if (event["type"] === "message_start") {
1214
+ const msg = event["message"];
1215
+ const u = _optionalChain([msg, 'optionalAccess', _23 => _23["usage"]]);
1216
+ if (u) anthropicInputUsage = u;
1217
+ return null;
1218
+ }
1219
+ if (event["type"] === "message_delta") {
1220
+ const outputUsage = event["usage"];
1221
+ if (!outputUsage) return null;
1222
+ return { ...anthropicInputUsage, ...outputUsage };
1223
+ }
1224
+ return null;
1225
+ },
1226
+ onUsage(rawUsage) {
1227
+ recordAnthropicStreamUsage(usageRecorder, rawUsage, usageAttribution);
1228
+ }
1229
+ } : void 0;
1122
1230
  let bodyText;
1123
1231
  if (!isStream && upstreamSse) {
1124
1232
  bodyText = await aggregateAnthropicSseToJsonBody(upstreamResponse, route.requestedModel);
@@ -1128,22 +1236,19 @@ async function handleAnthropicMessagesByo(res, rawBody, route, deps, options = {
1128
1236
  );
1129
1237
  res.end(bodyText);
1130
1238
  } else {
1131
- bodyText = await relayResponse(res, upstreamResponse, isStream, route.requestedModel);
1239
+ bodyText = await relayResponse(res, upstreamResponse, isStream, route.requestedModel, usageTap);
1132
1240
  }
1133
1241
  if (bodyText && deps.usageRecorder) {
1134
- recordAnthropicNonStreamUsage(deps.usageRecorder, bodyText, {
1135
- sessionId: route.sessionId,
1136
- providerId: _nullishCoalesce(route.providerId, () => ( "anthropic")),
1137
- model: plan.resolvedModel,
1138
- apiKeyId: _nullishCoalesce(route.apiKeyId, () => ( null)),
1139
- // request-audit-log: correlate this request's tokens/cost to its audit record.
1140
- auditResponse: res
1141
- });
1242
+ recordAnthropicNonStreamUsage(deps.usageRecorder, bodyText, usageAttribution);
1142
1243
  }
1143
1244
  } catch (err) {
1245
+ if (_chunk25GXJCEZcjs.isBoundAccountSelectionError.call(void 0, err)) {
1246
+ writeBoundAccountError(res, err);
1247
+ return;
1248
+ }
1144
1249
  const errMsg = _chunkSVNDB62Dcjs.serializeError.call(void 0, err);
1145
1250
  console.error("[ProviderProxy:anthropic] Pipeline error:", errMsg);
1146
- writeError(res, 502, errMsg);
1251
+ writeError(res, _chunk6QQG7YG3cjs.isAccountAllowanceExhaustedError.call(void 0, err) ? 429 : 502, errMsg);
1147
1252
  }
1148
1253
  }
1149
1254
  async function buildByoPlan(res, route, deps, resolvedModel, isStream) {
@@ -1157,7 +1262,14 @@ async function buildByoPlan(res, route, deps, resolvedModel, isStream) {
1157
1262
  writeError(res, 502, `Provider not found: ${providerId}`);
1158
1263
  return null;
1159
1264
  }
1160
- const apiKey = await resolvePoolBoundKey(deps, providerId, provider, route.sessionId);
1265
+ const apiKey = await resolvePoolBoundKey(
1266
+ deps,
1267
+ providerId,
1268
+ provider,
1269
+ route.sessionId,
1270
+ route.preferredKeyId,
1271
+ route.boundKeyFallbackPolicy
1272
+ );
1161
1273
  if (!apiKey) {
1162
1274
  writeError(res, 502, "API key not configured");
1163
1275
  return null;
@@ -1190,7 +1302,7 @@ async function buildByoPlan(res, route, deps, resolvedModel, isStream) {
1190
1302
  isSubscription: false,
1191
1303
  provider,
1192
1304
  apiKey,
1193
- extendedContextEnabled: _nullishCoalesce(_optionalChain([route, 'access', _20 => _20.anthropicSdkHints, 'optionalAccess', _21 => _21.extendedContext, 'optionalAccess', _22 => _22.enabled]), () => ( false))
1305
+ extendedContextEnabled: _nullishCoalesce(_optionalChain([route, 'access', _24 => _24.anthropicSdkHints, 'optionalAccess', _25 => _25.extendedContext, 'optionalAccess', _26 => _26.enabled]), () => ( false))
1194
1306
  };
1195
1307
  }
1196
1308
  async function runSameFormatFetch(bodyToSend, plan, options, keyOverride) {
@@ -1200,7 +1312,7 @@ async function runSameFormatFetch(bodyToSend, plan, options, keyOverride) {
1200
1312
  }
1201
1313
  const effectiveKey = _nullishCoalesce(_nullishCoalesce(keyOverride, () => ( apiKey)), () => ( ""));
1202
1314
  const headers = _chunkQ27JY5RGcjs.getProviderHeaders.call(void 0, provider, effectiveKey);
1203
- const callerBeta = _optionalChain([options, 'access', _23 => _23.callerAnthropicBeta, 'optionalAccess', _24 => _24.trim, 'call', _25 => _25()]);
1315
+ const callerBeta = _optionalChain([options, 'access', _27 => _27.callerAnthropicBeta, 'optionalAccess', _28 => _28.trim, 'call', _29 => _29()]);
1204
1316
  if (callerBeta) {
1205
1317
  const existing = _nullishCoalesce(headers["anthropic-beta"], () => ( headers["Anthropic-Beta"]));
1206
1318
  const parts = new Set(
@@ -1214,7 +1326,7 @@ async function runSameFormatFetch(bodyToSend, plan, options, keyOverride) {
1214
1326
  _chunkGBHYAGX3cjs.injectExtendedContextBeta.call(void 0, headers, resolvedModel, _nullishCoalesce(extendedContextEnabled, () => ( false)));
1215
1327
  const url = _chunkA2YMUCBTcjs.buildProviderApiUrl.call(void 0, provider, { model: resolvedModel, stream: isStream });
1216
1328
  console.info(`[ProviderProxy:anthropic] (same-format) -> ${url} model=${resolvedModel} stream=${isStream}`);
1217
- const response = await _chunkPG7PS2NNcjs.fetchUpstream.call(void 0,
1329
+ const response = await _chunkKCVJWJSTcjs.fetchUpstream.call(void 0,
1218
1330
  url,
1219
1331
  { method: "POST", headers, body: bodyToSend },
1220
1332
  { providerId: "byo" }
@@ -1226,7 +1338,7 @@ function resolveSameFormatBody(anthropicBody, rawBody, plan) {
1226
1338
  try {
1227
1339
  const m = JSON.parse(rawBody).model;
1228
1340
  originalModel = typeof m === "string" ? m : void 0;
1229
- } catch (e12) {
1341
+ } catch (e14) {
1230
1342
  originalModel = void 0;
1231
1343
  }
1232
1344
  return plan.resolvedModel !== originalModel ? JSON.stringify(anthropicBody) : rawBody;
@@ -1235,8 +1347,8 @@ async function runPipelineWithPoolReporting(anthropicBody, rawBody, plan, option
1235
1347
  const sameFormatBody = plan.sameFormat ? resolveSameFormatBody(anthropicBody, rawBody, plan) : rawBody;
1236
1348
  const runOnce = (keyOverride) => plan.sameFormat ? runSameFormatFetch(sameFormatBody, plan, options, keyOverride) : runPipeline(anthropicBody, plan);
1237
1349
  const first = await runOnce();
1238
- const outcome = await _optionalChain([plan, 'access', _26 => _26.auth, 'access', _27 => _27.onResult, 'optionalCall', _28 => _28(first.rawStatus)]);
1239
- if (_optionalChain([outcome, 'optionalAccess', _29 => _29.rebound])) {
1350
+ const outcome = await _optionalChain([plan, 'access', _30 => _30.auth, 'access', _31 => _31.onResult, 'optionalCall', _32 => _32(first.rawStatus)]);
1351
+ if (_optionalChain([outcome, 'optionalAccess', _33 => _33.rebound])) {
1240
1352
  console.info(
1241
1353
  "[ProviderProxy:anthropic] pool re-bound key after status",
1242
1354
  first.rawStatus,
@@ -1270,11 +1382,31 @@ async function handleAnthropicMessagesRequest(req, res, route, deps) {
1270
1382
  writeError(res, 502, "Anthropic route is missing a providerId");
1271
1383
  return;
1272
1384
  }
1385
+ let delegatedApiKey = hints.apiKey;
1386
+ if (route.authMode === "byo" && route.providerId) {
1387
+ const provider = await deps.llmConfig.getProvider(route.providerId);
1388
+ if (!provider) {
1389
+ writeError(res, 502, `Provider not found: ${route.providerId}`);
1390
+ return;
1391
+ }
1392
+ delegatedApiKey = await resolvePoolBoundKey(
1393
+ deps,
1394
+ route.providerId,
1395
+ provider,
1396
+ route.sessionId,
1397
+ route.preferredKeyId,
1398
+ route.boundKeyFallbackPolicy
1399
+ );
1400
+ if (!delegatedApiKey) {
1401
+ writeError(res, 502, "API key not configured");
1402
+ return;
1403
+ }
1404
+ }
1273
1405
  const handler = handlerFactory({
1274
1406
  llmConfig: deps.llmConfig,
1275
1407
  providerId: _nullishCoalesce(route.providerId, () => ( "")),
1276
1408
  model: route.model,
1277
- apiKey: hints.apiKey,
1409
+ apiKey: delegatedApiKey,
1278
1410
  backgroundTaskModel: route.backgroundTaskModel,
1279
1411
  isOfficialProvider: hints.isOfficialProvider,
1280
1412
  thinkingLevel: hints.thinkingLevel,
@@ -1283,6 +1415,11 @@ async function handleAnthropicMessagesRequest(req, res, route, deps) {
1283
1415
  passThroughAuthToken: _nullishCoalesce(hints.passThroughAuthToken, () => ( null)),
1284
1416
  resolvePassThroughAuthToken: _nullishCoalesce(hints.resolvePassThroughAuthToken, () => ( null)),
1285
1417
  subscriptionProfile: _nullishCoalesce(hints.subscriptionProfile, () => ( null)),
1418
+ preferredAccountId: hints.preferredAccountId,
1419
+ preferredAccountGroup: hints.preferredAccountGroup,
1420
+ boundAccountFallbackPolicy: hints.boundAccountFallbackPolicy,
1421
+ preferredKeyId: route.preferredKeyId,
1422
+ boundKeyFallbackPolicy: route.boundKeyFallbackPolicy,
1286
1423
  maxConcurrency: hints.maxConcurrency,
1287
1424
  webSearchService: _nullishCoalesce(hints.webSearchService, () => ( null)),
1288
1425
  onRetry: hints.onRetry,
@@ -1309,24 +1446,37 @@ function readGeminiUsage(usage) {
1309
1446
  reasoningTokens
1310
1447
  };
1311
1448
  }
1449
+ function emitGeminiUsageRecord(recorder, rawUsageMetadata, attribution) {
1450
+ const tapped = readGeminiUsage(rawUsageMetadata);
1451
+ if (!tapped) return;
1452
+ recorder.record({
1453
+ messageId: null,
1454
+ parentMessageId: null,
1455
+ sessionId: attribution.sessionId,
1456
+ providerId: attribution.providerId,
1457
+ model: attribution.model,
1458
+ apiKeyId: attribution.apiKeyId,
1459
+ auditResponse: attribution.auditResponse,
1460
+ engineOrigin: "codex-ingress",
1461
+ usage: tapped,
1462
+ rawUsage: rawUsageMetadata
1463
+ });
1464
+ }
1312
1465
  function recordGeminiNonStreamUsage(recorder, bodyText, attribution) {
1313
1466
  try {
1314
1467
  const parsed = JSON.parse(bodyText);
1315
- const tapped = readGeminiUsage(parsed.usageMetadata);
1316
- if (!tapped) return;
1317
- recorder.record({
1318
- messageId: null,
1319
- parentMessageId: null,
1320
- sessionId: attribution.sessionId,
1321
- providerId: attribution.providerId,
1322
- model: attribution.model,
1323
- apiKeyId: attribution.apiKeyId,
1324
- auditResponse: attribution.auditResponse,
1325
- engineOrigin: "codex-ingress",
1326
- usage: tapped,
1327
- rawUsage: parsed.usageMetadata
1328
- });
1329
- } catch (e13) {
1468
+ emitGeminiUsageRecord(
1469
+ recorder,
1470
+ parsed.usageMetadata,
1471
+ attribution
1472
+ );
1473
+ } catch (e15) {
1474
+ }
1475
+ }
1476
+ function recordGeminiStreamUsage(recorder, rawUsageMetadata, attribution) {
1477
+ try {
1478
+ emitGeminiUsageRecord(recorder, rawUsageMetadata, attribution);
1479
+ } catch (e16) {
1330
1480
  }
1331
1481
  }
1332
1482
 
@@ -1335,14 +1485,14 @@ var GENERATE_CONTENT_ACTION = ":generateContent";
1335
1485
  var STREAM_GENERATE_CONTENT_ACTION = ":streamGenerateContent";
1336
1486
  function isGeminiGenerateContentRequest(method, url) {
1337
1487
  if (method !== "POST" || !url) return false;
1338
- const path = _nullishCoalesce(_optionalChain([url, 'access', _30 => _30.split, 'call', _31 => _31("?"), 'access', _32 => _32[0], 'optionalAccess', _33 => _33.replace, 'call', _34 => _34(/\/+$/, "")]), () => ( ""));
1488
+ const path = _nullishCoalesce(_optionalChain([url, 'access', _34 => _34.split, 'call', _35 => _35("?"), 'access', _36 => _36[0], 'optionalAccess', _37 => _37.replace, 'call', _38 => _38(/\/+$/, "")]), () => ( ""));
1339
1489
  const lastSegment = _nullishCoalesce(path.split("/").pop(), () => ( ""));
1340
1490
  return lastSegment.includes(STREAM_GENERATE_CONTENT_ACTION) || lastSegment.includes(GENERATE_CONTENT_ACTION);
1341
1491
  }
1342
1492
  function isGeminiStreamRequest(url) {
1343
1493
  if (!url) return false;
1344
1494
  const [path, query = ""] = url.split("?");
1345
- const lastSegment = _nullishCoalesce((_nullishCoalesce(_optionalChain([path, 'optionalAccess', _35 => _35.replace, 'call', _36 => _36(/\/+$/, "")]), () => ( ""))).split("/").pop(), () => ( ""));
1495
+ const lastSegment = _nullishCoalesce((_nullishCoalesce(_optionalChain([path, 'optionalAccess', _39 => _39.replace, 'call', _40 => _40(/\/+$/, "")]), () => ( ""))).split("/").pop(), () => ( ""));
1346
1496
  if (lastSegment.includes(STREAM_GENERATE_CONTENT_ACTION)) return true;
1347
1497
  return /(^|&)alt=sse(&|$)/.test(query);
1348
1498
  }
@@ -1350,7 +1500,7 @@ async function handleGeminiGenerateContentRequest(res, rawBody, url, route, deps
1350
1500
  let geminiBody;
1351
1501
  try {
1352
1502
  geminiBody = JSON.parse(rawBody);
1353
- } catch (e14) {
1503
+ } catch (e17) {
1354
1504
  writeError(res, 400, "Invalid JSON in request body");
1355
1505
  return;
1356
1506
  }
@@ -1366,16 +1516,32 @@ async function handleGeminiGenerateContentRequest(res, rawBody, url, route, deps
1366
1516
  const plan = await buildByoPlan2(res, route, deps, resolvedModel, isStream);
1367
1517
  if (!plan) return;
1368
1518
  const providerResponse = await runPipelineWithPoolReporting2(geminiBody, plan);
1369
- const bodyText = await relayResponse(res, providerResponse.response, isStream);
1519
+ const usageAttribution = {
1520
+ sessionId: route.sessionId,
1521
+ providerId: _nullishCoalesce(route.providerId, () => ( "gemini")),
1522
+ model: resolvedModel,
1523
+ apiKeyId: _nullishCoalesce(route.apiKeyId, () => ( null)),
1524
+ // request-audit-log: correlate this request's tokens/cost to its audit record.
1525
+ auditResponse: res
1526
+ };
1527
+ const usageRecorder = deps.usageRecorder;
1528
+ const usageTap = usageRecorder ? {
1529
+ extractUsage(event) {
1530
+ return _nullishCoalesce(event["usageMetadata"], () => ( null));
1531
+ },
1532
+ onUsage(rawUsage) {
1533
+ recordGeminiStreamUsage(usageRecorder, rawUsage, usageAttribution);
1534
+ }
1535
+ } : void 0;
1536
+ const bodyText = await relayResponse(
1537
+ res,
1538
+ providerResponse.response,
1539
+ isStream,
1540
+ void 0,
1541
+ usageTap
1542
+ );
1370
1543
  if (bodyText && deps.usageRecorder) {
1371
- recordGeminiNonStreamUsage(deps.usageRecorder, bodyText, {
1372
- sessionId: route.sessionId,
1373
- providerId: _nullishCoalesce(route.providerId, () => ( "gemini")),
1374
- model: resolvedModel,
1375
- apiKeyId: _nullishCoalesce(route.apiKeyId, () => ( null)),
1376
- // request-audit-log: correlate this request's tokens/cost to its audit record.
1377
- auditResponse: res
1378
- });
1544
+ recordGeminiNonStreamUsage(deps.usageRecorder, bodyText, usageAttribution);
1379
1545
  }
1380
1546
  } catch (err) {
1381
1547
  const errMsg = _chunkSVNDB62Dcjs.serializeError.call(void 0, err);
@@ -1394,7 +1560,14 @@ async function buildByoPlan2(res, route, deps, resolvedModel, isStream) {
1394
1560
  writeError(res, 502, `Provider not found: ${providerId}`);
1395
1561
  return null;
1396
1562
  }
1397
- const apiKey = await resolvePoolBoundKey(deps, providerId, provider, route.sessionId);
1563
+ const apiKey = await resolvePoolBoundKey(
1564
+ deps,
1565
+ providerId,
1566
+ provider,
1567
+ route.sessionId,
1568
+ route.preferredKeyId,
1569
+ route.boundKeyFallbackPolicy
1570
+ );
1398
1571
  if (!apiKey) {
1399
1572
  writeError(res, 502, "API key not configured");
1400
1573
  return null;
@@ -1431,7 +1604,7 @@ async function runPipeline2(geminiBody, plan) {
1431
1604
  const authHeaders = {};
1432
1605
  await auth.applyHeaders(authHeaders, { upstreamUrl, model: resolvedModel });
1433
1606
  let rawStatus = null;
1434
- const { response } = await _chunkHYN75H6Gcjs.executeProviderCall.call(void 0, {
1607
+ const { response } = await _chunkMUHWHQVMcjs.executeProviderCall.call(void 0, {
1435
1608
  executor,
1436
1609
  request: geminiBody,
1437
1610
  provider: transformerProvider,
@@ -1449,7 +1622,7 @@ async function runPipeline2(geminiBody, plan) {
1449
1622
  },
1450
1623
  fetchFn: (url, headers, body) => {
1451
1624
  console.log(`[ProviderProxy:gemini] -> ${url} model=${resolvedModel} stream=${isStream}`);
1452
- return _chunkPG7PS2NNcjs.fetchUpstream.call(void 0,
1625
+ return _chunkKCVJWJSTcjs.fetchUpstream.call(void 0,
1453
1626
  url,
1454
1627
  { method: "POST", headers, body: JSON.stringify(body) },
1455
1628
  { providerId: "byo" }
@@ -1464,8 +1637,8 @@ async function runPipeline2(geminiBody, plan) {
1464
1637
  }
1465
1638
  async function runPipelineWithPoolReporting2(geminiBody, plan) {
1466
1639
  const first = await runPipeline2(geminiBody, plan);
1467
- const outcome = await _optionalChain([plan, 'access', _37 => _37.auth, 'access', _38 => _38.onResult, 'optionalCall', _39 => _39(first.rawStatus)]);
1468
- if (_optionalChain([outcome, 'optionalAccess', _40 => _40.rebound])) {
1640
+ const outcome = await _optionalChain([plan, 'access', _41 => _41.auth, 'access', _42 => _42.onResult, 'optionalCall', _43 => _43(first.rawStatus)]);
1641
+ if (_optionalChain([outcome, 'optionalAccess', _44 => _44.rebound])) {
1469
1642
  console.log(
1470
1643
  "[ProviderProxy:gemini] pool re-bound key after status",
1471
1644
  first.rawStatus,
@@ -1494,31 +1667,44 @@ function readChatCompletionsUsage(usage) {
1494
1667
  reasoningTokens
1495
1668
  };
1496
1669
  }
1670
+ function emitChatCompletionsUsageRecord(recorder, rawUsage, attribution) {
1671
+ const tapped = readChatCompletionsUsage(rawUsage);
1672
+ if (!tapped) return;
1673
+ recorder.record({
1674
+ messageId: null,
1675
+ parentMessageId: null,
1676
+ sessionId: attribution.sessionId,
1677
+ providerId: attribution.providerId,
1678
+ model: attribution.model,
1679
+ apiKeyId: attribution.apiKeyId,
1680
+ auditResponse: attribution.auditResponse,
1681
+ engineOrigin: "codex-ingress",
1682
+ usage: tapped,
1683
+ rawUsage
1684
+ });
1685
+ }
1497
1686
  function recordChatCompletionsNonStreamUsage(recorder, bodyText, attribution) {
1498
1687
  try {
1499
1688
  const parsed = JSON.parse(bodyText);
1500
- const tapped = readChatCompletionsUsage(parsed.usage);
1501
- if (!tapped) return;
1502
- recorder.record({
1503
- messageId: null,
1504
- parentMessageId: null,
1505
- sessionId: attribution.sessionId,
1506
- providerId: attribution.providerId,
1507
- model: attribution.model,
1508
- apiKeyId: attribution.apiKeyId,
1509
- auditResponse: attribution.auditResponse,
1510
- engineOrigin: "codex-ingress",
1511
- usage: tapped,
1512
- rawUsage: parsed.usage
1513
- });
1514
- } catch (e15) {
1689
+ emitChatCompletionsUsageRecord(
1690
+ recorder,
1691
+ parsed.usage,
1692
+ attribution
1693
+ );
1694
+ } catch (e18) {
1695
+ }
1696
+ }
1697
+ function recordChatCompletionsStreamUsage(recorder, rawUsage, attribution) {
1698
+ try {
1699
+ emitChatCompletionsUsageRecord(recorder, rawUsage, attribution);
1700
+ } catch (e19) {
1515
1701
  }
1516
1702
  }
1517
1703
 
1518
1704
  // src/provider-proxy/ingress/openaiChatIngress.ts
1519
1705
  function isOpenAIChatRequest(method, url) {
1520
1706
  if (method !== "POST" || !url) return false;
1521
- const path = _nullishCoalesce(_optionalChain([url, 'access', _41 => _41.split, 'call', _42 => _42("?"), 'access', _43 => _43[0], 'optionalAccess', _44 => _44.replace, 'call', _45 => _45(/\/+$/, "")]), () => ( ""));
1707
+ const path = _nullishCoalesce(_optionalChain([url, 'access', _45 => _45.split, 'call', _46 => _46("?"), 'access', _47 => _47[0], 'optionalAccess', _48 => _48.replace, 'call', _49 => _49(/\/+$/, "")]), () => ( ""));
1522
1708
  return path.endsWith("/chat/completions");
1523
1709
  }
1524
1710
  var CHAT_BRIDGE_SUBSCRIPTION_PROVIDERS = /* @__PURE__ */ new Set(["claude"]);
@@ -1527,7 +1713,7 @@ async function handleOpenAIChatRequest(res, rawBody, route, deps) {
1527
1713
  let chatBody;
1528
1714
  try {
1529
1715
  chatBody = JSON.parse(rawBody);
1530
- } catch (e16) {
1716
+ } catch (e20) {
1531
1717
  writeError(res, 400, "Invalid JSON in request body");
1532
1718
  return;
1533
1719
  }
@@ -1538,21 +1724,41 @@ async function handleOpenAIChatRequest(res, rawBody, route, deps) {
1538
1724
  const plan = route.authMode === "subscription" ? await buildSubscriptionPlan2(res, route, deps, resolvedModel, isStream) : await buildByoPlan3(res, route, deps, resolvedModel, isStream);
1539
1725
  if (!plan) return;
1540
1726
  const providerResponse = plan.isSubscription ? await runPipelineWithSubscriptionRetry2(chatBody, plan) : await runPipelineWithPoolReporting3(chatBody, plan);
1541
- const bodyText = await relayResponse(res, providerResponse.response, isStream);
1727
+ const usageAttribution = {
1728
+ sessionId: route.sessionId,
1729
+ providerId: _nullishCoalesce(route.providerId, () => ( "openai")),
1730
+ model: resolvedModel,
1731
+ apiKeyId: _nullishCoalesce(route.apiKeyId, () => ( null)),
1732
+ // request-audit-log: correlate this request's tokens/cost to its audit record.
1733
+ auditResponse: res
1734
+ };
1735
+ const usageRecorder = deps.usageRecorder;
1736
+ const usageTap = usageRecorder ? {
1737
+ extractUsage(event) {
1738
+ return _nullishCoalesce(event["usage"], () => ( null));
1739
+ },
1740
+ onUsage(rawUsage) {
1741
+ recordChatCompletionsStreamUsage(usageRecorder, rawUsage, usageAttribution);
1742
+ }
1743
+ } : void 0;
1744
+ const bodyText = await relayResponse(
1745
+ res,
1746
+ providerResponse.response,
1747
+ isStream,
1748
+ void 0,
1749
+ usageTap
1750
+ );
1542
1751
  if (bodyText && deps.usageRecorder) {
1543
- recordChatCompletionsNonStreamUsage(deps.usageRecorder, bodyText, {
1544
- sessionId: route.sessionId,
1545
- providerId: _nullishCoalesce(route.providerId, () => ( "openai")),
1546
- model: resolvedModel,
1547
- apiKeyId: _nullishCoalesce(route.apiKeyId, () => ( null)),
1548
- // request-audit-log: correlate this request's tokens/cost to its audit record.
1549
- auditResponse: res
1550
- });
1752
+ recordChatCompletionsNonStreamUsage(deps.usageRecorder, bodyText, usageAttribution);
1551
1753
  }
1552
1754
  } catch (err) {
1755
+ if (_chunk25GXJCEZcjs.isBoundAccountSelectionError.call(void 0, err)) {
1756
+ writeBoundAccountError(res, err);
1757
+ return;
1758
+ }
1553
1759
  const errMsg = _chunkSVNDB62Dcjs.serializeError.call(void 0, err);
1554
1760
  console.error("[ProviderProxy:chat] Pipeline error:", errMsg);
1555
- writeError(res, 502, errMsg);
1761
+ writeError(res, _chunk6QQG7YG3cjs.isAccountAllowanceExhaustedError.call(void 0, err) ? 429 : 502, errMsg);
1556
1762
  }
1557
1763
  }
1558
1764
  async function buildByoPlan3(res, route, deps, resolvedModel, isStream) {
@@ -1566,7 +1772,14 @@ async function buildByoPlan3(res, route, deps, resolvedModel, isStream) {
1566
1772
  writeError(res, 502, `Provider not found: ${providerId}`);
1567
1773
  return null;
1568
1774
  }
1569
- const apiKey = await resolvePoolBoundKey(deps, providerId, provider, route.sessionId);
1775
+ const apiKey = await resolvePoolBoundKey(
1776
+ deps,
1777
+ providerId,
1778
+ provider,
1779
+ route.sessionId,
1780
+ route.preferredKeyId,
1781
+ route.boundKeyFallbackPolicy
1782
+ );
1570
1783
  if (!apiKey) {
1571
1784
  writeError(res, 502, "API key not configured");
1572
1785
  return null;
@@ -1613,12 +1826,12 @@ async function buildSubscriptionPlan2(res, route, deps, resolvedModel, isStream)
1613
1826
  );
1614
1827
  return null;
1615
1828
  }
1616
- const upstreamUrl = _optionalChain([profile, 'access', _46 => _46.resolveUpstreamUrl, 'optionalCall', _47 => _47(resolvedModel)]);
1829
+ const upstreamUrl = _optionalChain([profile, 'access', _50 => _50.resolveUpstreamUrl, 'optionalCall', _51 => _51(resolvedModel)]);
1617
1830
  if (!upstreamUrl) {
1618
1831
  writeError(res, 502, "Subscription profile is missing resolveUpstreamUrl");
1619
1832
  return null;
1620
1833
  }
1621
- const auth = _nullishCoalesce(route.auth, () => ( new (0, _chunkKFI44N2Rcjs.SubscriptionAuthSource)(profile)));
1834
+ const auth = _nullishCoalesce(route.auth, () => ( new (0, _chunkYNJNTCSQcjs.SubscriptionAuthSource)(profile)));
1622
1835
  const chain = _chunkNYUNU75Acjs.resolveSubscriptionChain.call(void 0,
1623
1836
  profile,
1624
1837
  deps.llmConfig.getTransformerService(),
@@ -1632,6 +1845,9 @@ async function buildSubscriptionPlan2(res, route, deps, resolvedModel, isStream)
1632
1845
  };
1633
1846
  return {
1634
1847
  auth,
1848
+ preferredAccountId: route.preferredAccountId,
1849
+ preferredAccountGroup: route.preferredAccountGroup,
1850
+ boundAccountFallbackPolicy: route.boundAccountFallbackPolicy,
1635
1851
  chain,
1636
1852
  transformerProvider,
1637
1853
  resolvedModel,
@@ -1650,12 +1866,15 @@ async function runPipeline3(chatBody, plan) {
1650
1866
  await auth.applyHeaders(authHeaders, {
1651
1867
  upstreamUrl,
1652
1868
  model: resolvedModel,
1869
+ preferredAccountId: plan.preferredAccountId,
1870
+ preferredAccountGroup: plan.preferredAccountGroup,
1871
+ boundAccountFallbackPolicy: plan.boundAccountFallbackPolicy,
1653
1872
  reportSelection: (accountId) => {
1654
1873
  proxyAccountId = accountId;
1655
1874
  }
1656
1875
  });
1657
1876
  let rawStatus = null;
1658
- const { response } = await _chunkHYN75H6Gcjs.executeProviderCall.call(void 0, {
1877
+ const { response } = await _chunkMUHWHQVMcjs.executeProviderCall.call(void 0, {
1659
1878
  executor,
1660
1879
  request: chatBody,
1661
1880
  provider: transformerProvider,
@@ -1672,7 +1891,7 @@ async function runPipeline3(chatBody, plan) {
1672
1891
  },
1673
1892
  fetchFn: (url, headers, body) => {
1674
1893
  console.log(`[ProviderProxy:chat] -> ${url} model=${resolvedModel} stream=${isStream}`);
1675
- return _chunkPG7PS2NNcjs.fetchUpstream.call(void 0,
1894
+ return _chunkKCVJWJSTcjs.fetchUpstream.call(void 0,
1676
1895
  url,
1677
1896
  { method: "POST", headers, body: JSON.stringify(body) },
1678
1897
  { providerId: plan.proxyProviderId, accountId: proxyAccountId }
@@ -1687,8 +1906,8 @@ async function runPipeline3(chatBody, plan) {
1687
1906
  }
1688
1907
  async function runPipelineWithPoolReporting3(chatBody, plan) {
1689
1908
  const first = await runPipeline3(chatBody, plan);
1690
- const outcome = await _optionalChain([plan, 'access', _48 => _48.auth, 'access', _49 => _49.onResult, 'optionalCall', _50 => _50(first.rawStatus)]);
1691
- if (_optionalChain([outcome, 'optionalAccess', _51 => _51.rebound])) {
1909
+ const outcome = await _optionalChain([plan, 'access', _52 => _52.auth, 'access', _53 => _53.onResult, 'optionalCall', _54 => _54(first.rawStatus)]);
1910
+ if (_optionalChain([outcome, 'optionalAccess', _55 => _55.rebound])) {
1692
1911
  console.log(
1693
1912
  "[ProviderProxy:chat] pool re-bound key after status",
1694
1913
  first.rawStatus,
@@ -1701,7 +1920,7 @@ async function runPipelineWithPoolReporting3(chatBody, plan) {
1701
1920
  async function runPipelineWithSubscriptionRetry2(chatBody, plan) {
1702
1921
  const first = await runPipeline3(chatBody, plan);
1703
1922
  if (first.rawStatus !== 401) return first;
1704
- const refreshed = await _optionalChain([plan, 'access', _52 => _52.auth, 'access', _53 => _53.onUnauthorized, 'optionalCall', _54 => _54()]);
1923
+ const refreshed = await _optionalChain([plan, 'access', _56 => _56.auth, 'access', _57 => _57.onUnauthorized, 'optionalCall', _58 => _58()]);
1705
1924
  if (!refreshed) {
1706
1925
  console.warn("[ProviderProxy:chat] 401 not recoverable (onUnauthorized returned false)");
1707
1926
  return first;
@@ -1728,63 +1947,107 @@ function readResponsesUsage(usage) {
1728
1947
  reasoningTokens
1729
1948
  };
1730
1949
  }
1950
+ function emitResponsesUsageRecord(recorder, rawUsage, attribution) {
1951
+ const tapped = readResponsesUsage(rawUsage);
1952
+ if (!tapped) return;
1953
+ recorder.record({
1954
+ messageId: null,
1955
+ parentMessageId: null,
1956
+ sessionId: attribution.sessionId,
1957
+ providerId: attribution.providerId,
1958
+ model: attribution.model,
1959
+ apiKeyId: attribution.apiKeyId,
1960
+ auditResponse: attribution.auditResponse,
1961
+ engineOrigin: "codex-ingress",
1962
+ usage: tapped,
1963
+ rawUsage
1964
+ });
1965
+ }
1731
1966
  function recordResponsesNonStreamUsage(recorder, bodyText, attribution) {
1732
1967
  try {
1733
1968
  const parsed = JSON.parse(bodyText);
1734
- const tapped = readResponsesUsage(parsed.usage);
1735
- if (!tapped) return;
1736
- recorder.record({
1737
- messageId: null,
1738
- parentMessageId: null,
1739
- sessionId: attribution.sessionId,
1740
- providerId: attribution.providerId,
1741
- model: attribution.model,
1742
- apiKeyId: attribution.apiKeyId,
1743
- auditResponse: attribution.auditResponse,
1744
- engineOrigin: "codex-ingress",
1745
- usage: tapped,
1746
- rawUsage: parsed.usage
1747
- });
1748
- } catch (e17) {
1969
+ emitResponsesUsageRecord(
1970
+ recorder,
1971
+ parsed.usage,
1972
+ attribution
1973
+ );
1974
+ } catch (e21) {
1975
+ }
1976
+ }
1977
+ function recordResponsesStreamUsage(recorder, rawUsage, attribution) {
1978
+ try {
1979
+ emitResponsesUsageRecord(recorder, rawUsage, attribution);
1980
+ } catch (e22) {
1749
1981
  }
1750
1982
  }
1751
1983
 
1752
1984
  // src/provider-proxy/ingress/openaiResponsesIngress.ts
1753
1985
  function isOpenAIResponsesRequest(method, url) {
1754
1986
  if (method !== "POST" || !url) return false;
1755
- const path = _nullishCoalesce(_optionalChain([url, 'access', _55 => _55.split, 'call', _56 => _56("?"), 'access', _57 => _57[0], 'optionalAccess', _58 => _58.replace, 'call', _59 => _59(/\/+$/, "")]), () => ( ""));
1987
+ const path = _nullishCoalesce(_optionalChain([url, 'access', _59 => _59.split, 'call', _60 => _60("?"), 'access', _61 => _61[0], 'optionalAccess', _62 => _62.replace, 'call', _63 => _63(/\/+$/, "")]), () => ( ""));
1756
1988
  return path.endsWith("/responses");
1757
1989
  }
1758
- async function handleOpenAIResponsesRequest(res, rawBody, route, deps) {
1990
+ async function handleOpenAIResponsesRequest(res, rawBody, route, deps, requestHeaders = {}) {
1759
1991
  let responsesBody;
1760
1992
  try {
1761
1993
  responsesBody = JSON.parse(rawBody);
1762
- } catch (e18) {
1994
+ } catch (e23) {
1763
1995
  writeError(res, 400, "Invalid JSON in request body");
1764
1996
  return;
1765
1997
  }
1766
1998
  const isStream = responsesBody.stream === true;
1999
+ const derivedSession = _chunkEJLH6NFTcjs.deriveGatewaySessionKey.call(void 0, responsesBody, requestHeaders, {
2000
+ endpoint: "responses",
2001
+ // A verified outbound key is the strongest route-local fallback. Resident
2002
+ // proxy callers without one still get a stable run/session bucket; the
2003
+ // final `anonymous` fallback is handled inside the shared utility.
2004
+ fallbackKey: _nullishCoalesce(_nullishCoalesce(route.apiKeyId, () => ( route.sessionId)), () => ( void 0))
2005
+ });
2006
+ const sessionKey = derivedSession.key;
1767
2007
  const resolvedModel = route.model;
1768
2008
  responsesBody.model = resolvedModel;
1769
2009
  try {
1770
- const plan = route.authMode === "subscription" ? await buildSubscriptionPlan3(res, route, deps, resolvedModel, isStream) : await buildByoPlan4(res, route, deps, resolvedModel, isStream);
2010
+ const plan = route.authMode === "subscription" ? await buildSubscriptionPlan3(res, route, deps, resolvedModel, isStream, sessionKey) : await buildByoPlan4(res, route, deps, resolvedModel, isStream);
1771
2011
  if (!plan) return;
1772
2012
  const providerResponse = route.authMode === "subscription" ? await runPipelineWithSubscriptionRetry3(responsesBody, plan) : await runPipelineWithPoolReporting4(responsesBody, plan);
1773
- const bodyText = await relayResponse(res, providerResponse.response, isStream, route.requestedModel);
2013
+ const usageAttribution = {
2014
+ sessionId: route.sessionId,
2015
+ providerId: _nullishCoalesce(route.providerId, () => ( "codex")),
2016
+ model: resolvedModel,
2017
+ apiKeyId: _nullishCoalesce(route.apiKeyId, () => ( null)),
2018
+ // request-audit-log: correlate this request's tokens/cost to its audit record.
2019
+ auditResponse: res
2020
+ };
2021
+ const usageRecorder = deps.usageRecorder;
2022
+ const usageTap = usageRecorder ? {
2023
+ extractUsage(event) {
2024
+ if (event["type"] !== "response.completed") return null;
2025
+ const response = event["response"];
2026
+ const usage = _optionalChain([response, 'optionalAccess', _64 => _64["usage"]]);
2027
+ return _nullishCoalesce(usage, () => ( null));
2028
+ },
2029
+ onUsage(rawUsage) {
2030
+ recordResponsesStreamUsage(usageRecorder, rawUsage, usageAttribution);
2031
+ }
2032
+ } : void 0;
2033
+ const bodyText = await relayResponse(
2034
+ res,
2035
+ providerResponse.response,
2036
+ isStream,
2037
+ route.requestedModel,
2038
+ usageTap
2039
+ );
1774
2040
  if (bodyText && deps.usageRecorder) {
1775
- recordResponsesNonStreamUsage(deps.usageRecorder, bodyText, {
1776
- sessionId: route.sessionId,
1777
- providerId: _nullishCoalesce(route.providerId, () => ( "codex")),
1778
- model: resolvedModel,
1779
- apiKeyId: _nullishCoalesce(route.apiKeyId, () => ( null)),
1780
- // request-audit-log: correlate this request's tokens/cost to its audit record.
1781
- auditResponse: res
1782
- });
2041
+ recordResponsesNonStreamUsage(deps.usageRecorder, bodyText, usageAttribution);
1783
2042
  }
1784
2043
  } catch (err) {
2044
+ if (_chunk25GXJCEZcjs.isBoundAccountSelectionError.call(void 0, err)) {
2045
+ writeBoundAccountError(res, err);
2046
+ return;
2047
+ }
1785
2048
  const errMsg = _chunkSVNDB62Dcjs.serializeError.call(void 0, err);
1786
2049
  console.error("[ProviderProxy:responses] Pipeline error:", errMsg);
1787
- writeError(res, 502, errMsg);
2050
+ writeError(res, _chunk6QQG7YG3cjs.isAccountAllowanceExhaustedError.call(void 0, err) ? 429 : 502, errMsg);
1788
2051
  }
1789
2052
  }
1790
2053
  async function buildByoPlan4(res, route, deps, resolvedModel, isStream) {
@@ -1798,7 +2061,14 @@ async function buildByoPlan4(res, route, deps, resolvedModel, isStream) {
1798
2061
  writeError(res, 502, `Provider not found: ${providerId}`);
1799
2062
  return null;
1800
2063
  }
1801
- const apiKey = await resolvePoolBoundKey(deps, providerId, provider, route.sessionId);
2064
+ const apiKey = await resolvePoolBoundKey(
2065
+ deps,
2066
+ providerId,
2067
+ provider,
2068
+ route.sessionId,
2069
+ route.preferredKeyId,
2070
+ route.boundKeyFallbackPolicy
2071
+ );
1802
2072
  if (!apiKey) {
1803
2073
  writeError(res, 502, "API key not configured");
1804
2074
  return null;
@@ -1829,18 +2099,18 @@ async function buildByoPlan4(res, route, deps, resolvedModel, isStream) {
1829
2099
  proxyProviderId: "byo"
1830
2100
  };
1831
2101
  }
1832
- async function buildSubscriptionPlan3(res, route, deps, resolvedModel, isStream) {
2102
+ async function buildSubscriptionPlan3(res, route, deps, resolvedModel, isStream, sessionKey) {
1833
2103
  const profile = route.subscriptionProfile;
1834
2104
  if (!profile) {
1835
2105
  writeError(res, 502, "Subscription mode requires a codex subscription profile");
1836
2106
  return null;
1837
2107
  }
1838
- const upstreamUrl = _optionalChain([profile, 'access', _60 => _60.resolveUpstreamUrl, 'optionalCall', _61 => _61(resolvedModel)]);
2108
+ const upstreamUrl = _optionalChain([profile, 'access', _65 => _65.resolveUpstreamUrl, 'optionalCall', _66 => _66(resolvedModel)]);
1839
2109
  if (!upstreamUrl) {
1840
2110
  writeError(res, 502, "Subscription profile is missing resolveUpstreamUrl");
1841
2111
  return null;
1842
2112
  }
1843
- const auth = _nullishCoalesce(route.auth, () => ( new (0, _chunkKFI44N2Rcjs.SubscriptionAuthSource)(profile)));
2113
+ const auth = _nullishCoalesce(route.auth, () => ( new (0, _chunkYNJNTCSQcjs.SubscriptionAuthSource)(profile)));
1844
2114
  const chain = _chunkNYUNU75Acjs.resolveSubscriptionChain.call(void 0,
1845
2115
  profile,
1846
2116
  deps.llmConfig.getTransformerService(),
@@ -1854,15 +2124,27 @@ async function buildSubscriptionPlan3(res, route, deps, resolvedModel, isStream)
1854
2124
  };
1855
2125
  if (profile.authStrategy.providerId === "gemini") {
1856
2126
  try {
1857
- transformerProvider.geminiProject = await resolveGeminiCodeAssistProject(profile);
2127
+ transformerProvider.geminiProject = await resolveGeminiCodeAssistProject(profile, {
2128
+ sessionKey,
2129
+ preferredAccountId: route.preferredAccountId,
2130
+ preferredAccountGroup: route.preferredAccountGroup,
2131
+ boundAccountFallbackPolicy: route.boundAccountFallbackPolicy
2132
+ });
1858
2133
  } catch (err) {
2134
+ if (_chunk25GXJCEZcjs.isBoundAccountSelectionError.call(void 0, err)) {
2135
+ writeBoundAccountError(res, err);
2136
+ return null;
2137
+ }
1859
2138
  writeError(res, 502, _chunkSVNDB62Dcjs.serializeError.call(void 0, err));
1860
2139
  return null;
1861
2140
  }
1862
2141
  }
1863
2142
  return {
1864
2143
  auth,
2144
+ sessionKey,
1865
2145
  preferredAccountId: route.preferredAccountId,
2146
+ preferredAccountGroup: route.preferredAccountGroup,
2147
+ boundAccountFallbackPolicy: route.boundAccountFallbackPolicy,
1866
2148
  chain,
1867
2149
  transformerProvider,
1868
2150
  resolvedModel,
@@ -1875,9 +2157,9 @@ async function buildSubscriptionPlan3(res, route, deps, resolvedModel, isStream)
1875
2157
  proxyProviderId: profile.authStrategy.providerId
1876
2158
  };
1877
2159
  }
1878
- async function resolveGeminiCodeAssistProject(profile) {
2160
+ async function resolveGeminiCodeAssistProject(profile, hints) {
1879
2161
  const probe = {};
1880
- await profile.authStrategy.applyHeaders(probe);
2162
+ await profile.authStrategy.applyHeaders(probe, hints);
1881
2163
  const bearer = _nullishCoalesce(_nullishCoalesce(probe.Authorization, () => ( probe.authorization)), () => ( ""));
1882
2164
  const accessToken = bearer.replace(/^Bearer\s+/i, "").trim();
1883
2165
  if (!accessToken) return void 0;
@@ -1888,19 +2170,22 @@ async function resolveGeminiCodeAssistProject(profile) {
1888
2170
  async function runPipeline4(responsesBody, plan) {
1889
2171
  const executor = getSharedExecutor();
1890
2172
  const endpointTransformer = getResponsesEndpointTransformer();
1891
- const { auth, chain, transformerProvider, resolvedModel, isStream, resolveUrl, upstreamUrl } = plan;
2173
+ const { auth, sessionKey, chain, transformerProvider, resolvedModel, isStream, resolveUrl, upstreamUrl } = plan;
1892
2174
  let proxyAccountId;
1893
2175
  const authHeaders = {};
1894
2176
  await auth.applyHeaders(authHeaders, {
1895
2177
  upstreamUrl,
1896
2178
  model: resolvedModel,
2179
+ sessionKey,
1897
2180
  preferredAccountId: plan.preferredAccountId,
2181
+ preferredAccountGroup: plan.preferredAccountGroup,
2182
+ boundAccountFallbackPolicy: plan.boundAccountFallbackPolicy,
1898
2183
  reportSelection: (accountId) => {
1899
2184
  proxyAccountId = accountId;
1900
2185
  }
1901
2186
  });
1902
2187
  let rawStatus = null;
1903
- const { response } = await _chunkHYN75H6Gcjs.executeProviderCall.call(void 0, {
2188
+ const { response } = await _chunkMUHWHQVMcjs.executeProviderCall.call(void 0, {
1904
2189
  executor,
1905
2190
  request: responsesBody,
1906
2191
  provider: transformerProvider,
@@ -1918,7 +2203,7 @@ async function runPipeline4(responsesBody, plan) {
1918
2203
  },
1919
2204
  fetchFn: (url, headers, body) => {
1920
2205
  console.log(`[ProviderProxy:responses] -> ${url} model=${resolvedModel} stream=${isStream}`);
1921
- return _chunkPG7PS2NNcjs.fetchUpstream.call(void 0,
2206
+ return _chunkKCVJWJSTcjs.fetchUpstream.call(void 0,
1922
2207
  url,
1923
2208
  { method: "POST", headers, body: JSON.stringify(body) },
1924
2209
  { providerId: plan.proxyProviderId, accountId: proxyAccountId }
@@ -1933,8 +2218,8 @@ async function runPipeline4(responsesBody, plan) {
1933
2218
  }
1934
2219
  async function runPipelineWithPoolReporting4(responsesBody, plan) {
1935
2220
  const first = await runPipeline4(responsesBody, plan);
1936
- const outcome = await _optionalChain([plan, 'access', _62 => _62.auth, 'access', _63 => _63.onResult, 'optionalCall', _64 => _64(first.rawStatus)]);
1937
- if (_optionalChain([outcome, 'optionalAccess', _65 => _65.rebound])) {
2221
+ const outcome = await _optionalChain([plan, 'access', _67 => _67.auth, 'access', _68 => _68.onResult, 'optionalCall', _69 => _69(first.rawStatus)]);
2222
+ if (_optionalChain([outcome, 'optionalAccess', _70 => _70.rebound])) {
1938
2223
  console.log(
1939
2224
  "[ProviderProxy:responses] pool re-bound key after status",
1940
2225
  first.rawStatus,
@@ -1947,7 +2232,7 @@ async function runPipelineWithPoolReporting4(responsesBody, plan) {
1947
2232
  async function runPipelineWithSubscriptionRetry3(responsesBody, plan) {
1948
2233
  const first = await runPipeline4(responsesBody, plan);
1949
2234
  if (first.rawStatus !== 401) return first;
1950
- const refreshed = await _optionalChain([plan, 'access', _66 => _66.auth, 'access', _67 => _67.onUnauthorized, 'optionalCall', _68 => _68()]);
2235
+ const refreshed = await _optionalChain([plan, 'access', _71 => _71.auth, 'access', _72 => _72.onUnauthorized, 'optionalCall', _73 => _73(plan.sessionKey)]);
1951
2236
  if (!refreshed) {
1952
2237
  console.warn("[ProviderProxy:responses] 401 not recoverable (onUnauthorized returned false)");
1953
2238
  return first;
@@ -1969,7 +2254,7 @@ function resolveRouteToken(req) {
1969
2254
  if (fromAuth) return fromAuth;
1970
2255
  const googKey = req.headers["x-goog-api-key"];
1971
2256
  const value = Array.isArray(googKey) ? googKey[0] : googKey;
1972
- return _optionalChain([value, 'optionalAccess', _69 => _69.trim, 'call', _70 => _70()]) || void 0;
2257
+ return _optionalChain([value, 'optionalAccess', _74 => _74.trim, 'call', _75 => _75()]) || void 0;
1973
2258
  }
1974
2259
  async function routeRequest(req, res, routes, deps) {
1975
2260
  const token = resolveRouteToken(req);
@@ -1986,7 +2271,7 @@ async function routeRequest(req, res, routes, deps) {
1986
2271
  }
1987
2272
  if (isOpenAIResponsesRequest(method, url)) {
1988
2273
  const rawBody = await readBody(req);
1989
- await handleOpenAIResponsesRequest(res, rawBody, route, deps);
2274
+ await handleOpenAIResponsesRequest(res, rawBody, route, deps, req.headers);
1990
2275
  return;
1991
2276
  }
1992
2277
  if (isOpenAIChatRequest(method, url)) {
@@ -2177,11 +2462,11 @@ var DEFAULT_ACCOUNT_HEALTH = {
2177
2462
  overloadCooldownMs: 10 * 6e4
2178
2463
  };
2179
2464
  function normalizeAccountHealth(raw) {
2180
- const ah = _optionalChain([raw, 'optionalAccess', _71 => _71.accountHealth]);
2465
+ const ah = _optionalChain([raw, 'optionalAccess', _76 => _76.accountHealth]);
2181
2466
  return {
2182
- overloadCooldownEnabled: _optionalChain([ah, 'optionalAccess', _72 => _72.overloadCooldownEnabled]) !== false,
2467
+ overloadCooldownEnabled: _optionalChain([ah, 'optionalAccess', _77 => _77.overloadCooldownEnabled]) !== false,
2183
2468
  overloadCooldownMs: clampNumber(
2184
- _optionalChain([ah, 'optionalAccess', _73 => _73.overloadCooldownMs]),
2469
+ _optionalChain([ah, 'optionalAccess', _78 => _78.overloadCooldownMs]),
2185
2470
  6e4,
2186
2471
  36e5,
2187
2472
  DEFAULT_ACCOUNT_HEALTH.overloadCooldownMs
@@ -2196,54 +2481,86 @@ var DEFAULT_ACCOUNT_PROBE = {
2196
2481
  historySize: 10,
2197
2482
  staggerMs: 500
2198
2483
  };
2484
+ var DEFAULT_ALLOWANCE_SCHEDULING = {
2485
+ enabled: false,
2486
+ demoteAtPercent: 80,
2487
+ pauseAtPercent: 98,
2488
+ priorityPenalty: 100
2489
+ };
2490
+ function normalizeAllowanceScheduling(raw) {
2491
+ const value = _optionalChain([raw, 'optionalAccess', _79 => _79.allowanceScheduling]);
2492
+ const demoteAtPercent = clampNumber(
2493
+ _optionalChain([value, 'optionalAccess', _80 => _80.demoteAtPercent]),
2494
+ 0,
2495
+ 100,
2496
+ DEFAULT_ALLOWANCE_SCHEDULING.demoteAtPercent
2497
+ );
2498
+ const requestedPause = clampNumber(
2499
+ _optionalChain([value, 'optionalAccess', _81 => _81.pauseAtPercent]),
2500
+ 0,
2501
+ 100,
2502
+ DEFAULT_ALLOWANCE_SCHEDULING.pauseAtPercent
2503
+ );
2504
+ return {
2505
+ enabled: _optionalChain([value, 'optionalAccess', _82 => _82.enabled]) === true,
2506
+ demoteAtPercent,
2507
+ pauseAtPercent: Math.max(demoteAtPercent, requestedPause),
2508
+ priorityPenalty: Math.trunc(clampNumber(
2509
+ _optionalChain([value, 'optionalAccess', _83 => _83.priorityPenalty]),
2510
+ 1,
2511
+ 1e3,
2512
+ DEFAULT_ALLOWANCE_SCHEDULING.priorityPenalty
2513
+ ))
2514
+ };
2515
+ }
2199
2516
  function normalizeAccountProbe(raw) {
2200
- const ap = _optionalChain([raw, 'optionalAccess', _74 => _74.accountProbe]);
2517
+ const ap = _optionalChain([raw, 'optionalAccess', _84 => _84.accountProbe]);
2201
2518
  return {
2202
- enabled: _optionalChain([ap, 'optionalAccess', _75 => _75.enabled]) === true,
2203
- intervalMs: clampNumber(_optionalChain([ap, 'optionalAccess', _76 => _76.intervalMs]), 6e4, 864e5, DEFAULT_ACCOUNT_PROBE.intervalMs),
2204
- onlyMultiAccount: _optionalChain([ap, 'optionalAccess', _77 => _77.onlyMultiAccount]) !== false,
2205
- timeoutMs: clampNumber(_optionalChain([ap, 'optionalAccess', _78 => _78.timeoutMs]), 1e3, 6e4, DEFAULT_ACCOUNT_PROBE.timeoutMs),
2519
+ enabled: _optionalChain([ap, 'optionalAccess', _85 => _85.enabled]) === true,
2520
+ intervalMs: clampNumber(_optionalChain([ap, 'optionalAccess', _86 => _86.intervalMs]), 6e4, 864e5, DEFAULT_ACCOUNT_PROBE.intervalMs),
2521
+ onlyMultiAccount: _optionalChain([ap, 'optionalAccess', _87 => _87.onlyMultiAccount]) !== false,
2522
+ timeoutMs: clampNumber(_optionalChain([ap, 'optionalAccess', _88 => _88.timeoutMs]), 1e3, 6e4, DEFAULT_ACCOUNT_PROBE.timeoutMs),
2206
2523
  historySize: Math.trunc(
2207
- clampNumber(_optionalChain([ap, 'optionalAccess', _79 => _79.historySize]), 1, 200, DEFAULT_ACCOUNT_PROBE.historySize)
2524
+ clampNumber(_optionalChain([ap, 'optionalAccess', _89 => _89.historySize]), 1, 200, DEFAULT_ACCOUNT_PROBE.historySize)
2208
2525
  ),
2209
- staggerMs: clampNumber(_optionalChain([ap, 'optionalAccess', _80 => _80.staggerMs]), 0, 6e4, DEFAULT_ACCOUNT_PROBE.staggerMs)
2526
+ staggerMs: clampNumber(_optionalChain([ap, 'optionalAccess', _90 => _90.staggerMs]), 0, 6e4, DEFAULT_ACCOUNT_PROBE.staggerMs)
2210
2527
  };
2211
2528
  }
2212
2529
  function normalizeAudit(raw) {
2213
- const a = _optionalChain([raw, 'optionalAccess', _81 => _81.audit]);
2530
+ const a = _optionalChain([raw, 'optionalAccess', _91 => _91.audit]);
2214
2531
  return {
2215
- enabled: _optionalChain([a, 'optionalAccess', _82 => _82.enabled]) === true,
2216
- captureBodies: _optionalChain([a, 'optionalAccess', _83 => _83.captureBodies]) === true,
2532
+ enabled: _optionalChain([a, 'optionalAccess', _92 => _92.enabled]) === true,
2533
+ captureBodies: _optionalChain([a, 'optionalAccess', _93 => _93.captureBodies]) === true,
2217
2534
  maxBodyBytes: Math.trunc(
2218
- clampNumber(_optionalChain([a, 'optionalAccess', _84 => _84.maxBodyBytes]), 256, 1048576, _audittypes.DEFAULT_AUDIT_CONFIG.maxBodyBytes)
2535
+ clampNumber(_optionalChain([a, 'optionalAccess', _94 => _94.maxBodyBytes]), 256, 1048576, _audittypes.DEFAULT_AUDIT_CONFIG.maxBodyBytes)
2219
2536
  ),
2220
2537
  retentionDays: Math.trunc(
2221
- clampNumber(_optionalChain([a, 'optionalAccess', _85 => _85.retentionDays]), 1, 365, _audittypes.DEFAULT_AUDIT_CONFIG.retentionDays)
2538
+ clampNumber(_optionalChain([a, 'optionalAccess', _95 => _95.retentionDays]), 1, 365, _audittypes.DEFAULT_AUDIT_CONFIG.retentionDays)
2222
2539
  ),
2223
- trustForwardedFor: _optionalChain([a, 'optionalAccess', _86 => _86.trustForwardedFor]) === true
2540
+ trustForwardedFor: _optionalChain([a, 'optionalAccess', _96 => _96.trustForwardedFor]) === true
2224
2541
  };
2225
2542
  }
2226
2543
  function normalizeBilling(raw) {
2227
- const b = _optionalChain([raw, 'optionalAccess', _87 => _87.billing]);
2544
+ const b = _optionalChain([raw, 'optionalAccess', _97 => _97.billing]);
2228
2545
  const config = {
2229
- enabled: _optionalChain([b, 'optionalAccess', _88 => _88.enabled]) === true,
2546
+ enabled: _optionalChain([b, 'optionalAccess', _98 => _98.enabled]) === true,
2230
2547
  maxRetryAgeMs: Math.trunc(
2231
- clampNumber(_optionalChain([b, 'optionalAccess', _89 => _89.maxRetryAgeMs]), 6e4, 2592e6, _billingtypes.DEFAULT_BILLING_CONFIG.maxRetryAgeMs)
2548
+ clampNumber(_optionalChain([b, 'optionalAccess', _99 => _99.maxRetryAgeMs]), 6e4, 2592e6, _billingtypes.DEFAULT_BILLING_CONFIG.maxRetryAgeMs)
2232
2549
  )
2233
2550
  };
2234
- if (typeof _optionalChain([b, 'optionalAccess', _90 => _90.endpoint]) === "string" && b.endpoint.trim()) config.endpoint = b.endpoint.trim();
2235
- if (typeof _optionalChain([b, 'optionalAccess', _91 => _91.secret]) === "string" && b.secret.length > 0) config.secret = b.secret;
2551
+ if (typeof _optionalChain([b, 'optionalAccess', _100 => _100.endpoint]) === "string" && b.endpoint.trim()) config.endpoint = b.endpoint.trim();
2552
+ if (typeof _optionalChain([b, 'optionalAccess', _101 => _101.secret]) === "string" && b.secret.length > 0) config.secret = b.secret;
2236
2553
  return config;
2237
2554
  }
2238
2555
  var DEFAULT_FINGERPRINT = { enabled: false };
2239
2556
  function normalizeFingerprint(raw) {
2240
- const f = _optionalChain([raw, 'optionalAccess', _92 => _92.fingerprint]);
2241
- const out = { enabled: _optionalChain([f, 'optionalAccess', _93 => _93.enabled]) === true };
2242
- if (typeof _optionalChain([f, 'optionalAccess', _94 => _94.ua]) === "string" && f.ua.trim().length > 0) out.ua = f.ua.trim();
2557
+ const f = _optionalChain([raw, 'optionalAccess', _102 => _102.fingerprint]);
2558
+ const out = { enabled: _optionalChain([f, 'optionalAccess', _103 => _103.enabled]) === true };
2559
+ if (typeof _optionalChain([f, 'optionalAccess', _104 => _104.ua]) === "string" && f.ua.trim().length > 0) out.ua = f.ua.trim();
2243
2560
  return out;
2244
2561
  }
2245
2562
  function normalizeVoucher(raw) {
2246
- return { enabled: _optionalChain([raw, 'optionalAccess', _95 => _95.voucher, 'optionalAccess', _96 => _96.enabled]) === true };
2563
+ return { enabled: _optionalChain([raw, 'optionalAccess', _105 => _105.voucher, 'optionalAccess', _106 => _106.enabled]) === true };
2247
2564
  }
2248
2565
  var PROXY_TYPES = ["http", "https", "socks5"];
2249
2566
  function normalizeProxyConfig(raw) {
@@ -2327,14 +2644,14 @@ function clampNumber(value, min, max, fallback) {
2327
2644
  return Math.min(max, Math.max(min, n));
2328
2645
  }
2329
2646
  function normalizeQueueSegments(raw) {
2330
- const umq = _optionalChain([raw, 'optionalAccess', _97 => _97.userMessageQueue]);
2331
- const cq = _optionalChain([raw, 'optionalAccess', _98 => _98.concurrencyQueue]);
2647
+ const umq = _optionalChain([raw, 'optionalAccess', _107 => _107.userMessageQueue]);
2648
+ const cq = _optionalChain([raw, 'optionalAccess', _108 => _108.concurrencyQueue]);
2332
2649
  return {
2333
2650
  userMessageQueue: {
2334
- enabled: _optionalChain([umq, 'optionalAccess', _99 => _99.enabled]) === true,
2335
- delayMs: clampNumber(_optionalChain([umq, 'optionalAccess', _100 => _100.delayMs]), 0, 1e4, DEFAULT_USER_MESSAGE_QUEUE.delayMs),
2651
+ enabled: _optionalChain([umq, 'optionalAccess', _109 => _109.enabled]) === true,
2652
+ delayMs: clampNumber(_optionalChain([umq, 'optionalAccess', _110 => _110.delayMs]), 0, 1e4, DEFAULT_USER_MESSAGE_QUEUE.delayMs),
2336
2653
  waitTimeoutMs: clampNumber(
2337
- _optionalChain([umq, 'optionalAccess', _101 => _101.waitTimeoutMs]),
2654
+ _optionalChain([umq, 'optionalAccess', _111 => _111.waitTimeoutMs]),
2338
2655
  1e3,
2339
2656
  3e5,
2340
2657
  DEFAULT_USER_MESSAGE_QUEUE.waitTimeoutMs
@@ -2342,14 +2659,14 @@ function normalizeQueueSegments(raw) {
2342
2659
  },
2343
2660
  concurrencyQueue: {
2344
2661
  maxQueueSizeFactor: clampNumber(
2345
- _optionalChain([cq, 'optionalAccess', _102 => _102.maxQueueSizeFactor]),
2662
+ _optionalChain([cq, 'optionalAccess', _112 => _112.maxQueueSizeFactor]),
2346
2663
  1,
2347
2664
  10,
2348
2665
  DEFAULT_CONCURRENCY_QUEUE.maxQueueSizeFactor
2349
2666
  ),
2350
- minQueueSize: clampNumber(_optionalChain([cq, 'optionalAccess', _103 => _103.minQueueSize]), 1, 100, DEFAULT_CONCURRENCY_QUEUE.minQueueSize),
2667
+ minQueueSize: clampNumber(_optionalChain([cq, 'optionalAccess', _113 => _113.minQueueSize]), 1, 100, DEFAULT_CONCURRENCY_QUEUE.minQueueSize),
2351
2668
  waitTimeoutMs: clampNumber(
2352
- _optionalChain([cq, 'optionalAccess', _104 => _104.waitTimeoutMs]),
2669
+ _optionalChain([cq, 'optionalAccess', _114 => _114.waitTimeoutMs]),
2353
2670
  1e3,
2354
2671
  3e5,
2355
2672
  DEFAULT_CONCURRENCY_QUEUE.waitTimeoutMs
@@ -2360,11 +2677,11 @@ function normalizeQueueSegments(raw) {
2360
2677
  var ALL_ENDPOINTS = ["chat", "responses", "messages", "gemini"];
2361
2678
  function blankModelMap(endpoint) {
2362
2679
  const modelMap = {};
2363
- for (const kind of _chunkVACWOIREcjs.modelKindsForEndpoint.call(void 0, endpoint)) modelMap[kind] = "";
2680
+ for (const kind of _chunk4VZX5F4Tcjs.modelKindsForEndpoint.call(void 0, endpoint)) modelMap[kind] = "";
2364
2681
  return modelMap;
2365
2682
  }
2366
2683
  function defaultEndpointConfig(endpoint) {
2367
- if (_chunkVACWOIREcjs.isKindMappedEndpoint.call(void 0, endpoint)) {
2684
+ if (_chunk4VZX5F4Tcjs.isKindMappedEndpoint.call(void 0, endpoint)) {
2368
2685
  return { endpoint, modelMap: blankModelMap(endpoint), useSubscription: false };
2369
2686
  }
2370
2687
  if (endpoint === "chat") {
@@ -2390,13 +2707,14 @@ function normalizePrefixTargets(raw) {
2390
2707
  function normalizeEndpointConfig(e) {
2391
2708
  const endpoint = e.endpoint;
2392
2709
  const useSubscription = e.useSubscription === true;
2393
- const boundAccountId = typeof e.boundAccountId === "string" && e.boundAccountId.trim() !== "" ? e.boundAccountId : void 0;
2710
+ const boundAccountId = typeof e.boundAccountId === "string" && e.boundAccountId.trim() !== "" ? e.boundAccountId.trim() : void 0;
2711
+ const boundAccountFallbackPolicy = boundAccountId ? e.boundAccountFallbackPolicy === "pool" ? "pool" : "strict" : void 0;
2394
2712
  const boundKeyId = typeof e.boundKeyId === "string" && e.boundKeyId.trim() !== "" ? e.boundKeyId : void 0;
2395
2713
  let config;
2396
- if (_chunkVACWOIREcjs.isKindMappedEndpoint.call(void 0, endpoint)) {
2714
+ if (_chunk4VZX5F4Tcjs.isKindMappedEndpoint.call(void 0, endpoint)) {
2397
2715
  const rawMap = e.modelMap && typeof e.modelMap === "object" ? e.modelMap : {};
2398
2716
  const modelMap = {};
2399
- for (const kind of _chunkVACWOIREcjs.modelKindsForEndpoint.call(void 0, endpoint)) {
2717
+ for (const kind of _chunk4VZX5F4Tcjs.modelKindsForEndpoint.call(void 0, endpoint)) {
2400
2718
  const v = rawMap[kind];
2401
2719
  modelMap[kind] = typeof v === "string" ? v : "";
2402
2720
  }
@@ -2420,21 +2738,186 @@ function normalizeEndpointConfig(e) {
2420
2738
  config.backgroundModelIds = e.backgroundModelIds;
2421
2739
  }
2422
2740
  }
2423
- if (boundAccountId) config.boundAccountId = boundAccountId;
2741
+ if (boundAccountId) {
2742
+ config.boundAccountId = boundAccountId;
2743
+ config.boundAccountFallbackPolicy = boundAccountFallbackPolicy;
2744
+ }
2424
2745
  if (boundKeyId) config.boundKeyId = boundKeyId;
2425
2746
  return config;
2426
2747
  }
2748
+ function normalizeBindingTarget(raw) {
2749
+ if (!raw || typeof raw !== "object") return null;
2750
+ const target = raw;
2751
+ const providerId = typeof target.providerId === "string" ? target.providerId.trim() : "";
2752
+ if (!providerId) return null;
2753
+ if (target.kind === "account") {
2754
+ const accountId = typeof target.accountId === "string" ? target.accountId.trim() : "";
2755
+ return accountId ? { kind: "account", providerId, accountId } : null;
2756
+ }
2757
+ if (target.kind === "account-group") {
2758
+ const group = typeof target.group === "string" ? target.group.trim() : "";
2759
+ return group ? { kind: "account-group", providerId, group } : null;
2760
+ }
2761
+ if (target.kind === "account-pool") return { kind: "account-pool", providerId };
2762
+ if (target.kind === "provider") {
2763
+ const keyId = typeof target.keyId === "string" ? target.keyId.trim() : "";
2764
+ return keyId ? { kind: "provider", providerId, keyId } : { kind: "provider", providerId };
2765
+ }
2766
+ return null;
2767
+ }
2768
+ function normalizeGatewayModelMappings(raw) {
2769
+ if (!Array.isArray(raw)) return [];
2770
+ const mappings = [];
2771
+ for (const entry of raw) {
2772
+ if (!entry || typeof entry !== "object") continue;
2773
+ const value = entry;
2774
+ const source = typeof value.source === "string" ? value.source.trim() : "";
2775
+ const target = typeof value.target === "string" ? value.target.trim() : "";
2776
+ if (!source || !target) continue;
2777
+ mappings.push({ source, target });
2778
+ }
2779
+ return mappings;
2780
+ }
2781
+ function hasConfiguredLegacyModels(config) {
2782
+ return Object.values(_nullishCoalesce(config.modelMap, () => ( {}))).some((value) => typeof value === "string" && value.trim()) || Boolean(_optionalChain([config, 'access', _115 => _115.models, 'optionalAccess', _116 => _116.some, 'call', _117 => _117((value) => typeof value === "string" && value.trim())])) || Boolean(_optionalChain([config, 'access', _118 => _118.defaultModel, 'optionalAccess', _119 => _119.trim, 'call', _120 => _120()])) || Boolean(_optionalChain([config, 'access', _121 => _121.backgroundModel, 'optionalAccess', _122 => _122.trim, 'call', _123 => _123()])) || Boolean(Object.values(_nullishCoalesce(config.prefixTargets, () => ( {}))).some((value) => _optionalChain([value, 'optionalAccess', _124 => _124.trim, 'call', _125 => _125()])));
2783
+ }
2784
+ function splitModelRef(ref) {
2785
+ if (typeof ref !== "string") return null;
2786
+ const idx = ref.indexOf(",");
2787
+ if (idx <= 0) return null;
2788
+ const providerId = ref.slice(0, idx).trim();
2789
+ const modelId = ref.slice(idx + 1).trim();
2790
+ return providerId && modelId ? { providerId, modelId } : null;
2791
+ }
2792
+ function legacyTarget(config, providerId) {
2793
+ if (config.useSubscription) {
2794
+ if (config.boundAccountId) {
2795
+ return { kind: "account", providerId, accountId: config.boundAccountId };
2796
+ }
2797
+ if (config.boundAccountGroup) {
2798
+ return { kind: "account-group", providerId, group: config.boundAccountGroup };
2799
+ }
2800
+ return { kind: "account-pool", providerId };
2801
+ }
2802
+ return config.boundKeyId ? { kind: "provider", providerId, keyId: config.boundKeyId } : { kind: "provider", providerId };
2803
+ }
2804
+ function legacyEndpointToBindings(config) {
2805
+ const fallback = config.boundAccountId && config.boundAccountFallbackPolicy === "strict" ? "fail" : "next";
2806
+ const byProvider = /* @__PURE__ */ new Map();
2807
+ const routeFor = (providerId) => {
2808
+ const existing = byProvider.get(providerId);
2809
+ if (existing) return existing;
2810
+ const created = {
2811
+ id: `legacy-${config.endpoint}-${providerId}`,
2812
+ name: `${config.endpoint} \xB7 ${providerId}`,
2813
+ enabled: true,
2814
+ keyScope: "all",
2815
+ endpoint: config.endpoint,
2816
+ target: legacyTarget(config, providerId),
2817
+ fallback,
2818
+ modelMode: "mapped"
2819
+ };
2820
+ byProvider.set(providerId, created);
2821
+ return created;
2822
+ };
2823
+ for (const [kind, ref] of Object.entries(_nullishCoalesce(config.modelMap, () => ( {})))) {
2824
+ const parsed = splitModelRef(ref);
2825
+ if (!parsed) continue;
2826
+ const route = routeFor(parsed.providerId);
2827
+ route.modelMap = { ...route.modelMap, [kind]: ref };
2828
+ }
2829
+ for (const ref of _nullishCoalesce(config.models, () => ( []))) {
2830
+ const parsed = splitModelRef(ref);
2831
+ if (!parsed) continue;
2832
+ const route = routeFor(parsed.providerId);
2833
+ route.models = [..._nullishCoalesce(route.models, () => ( [])), ref];
2834
+ }
2835
+ for (const [prefix, ref] of Object.entries(_nullishCoalesce(config.prefixTargets, () => ( {})))) {
2836
+ const parsed = splitModelRef(ref);
2837
+ if (!parsed) continue;
2838
+ const route = routeFor(parsed.providerId);
2839
+ route.dispatchMode = "prefix";
2840
+ route.prefixTargets = { ...route.prefixTargets, [prefix]: ref };
2841
+ }
2842
+ for (const [field, ref] of [
2843
+ ["defaultModel", config.defaultModel],
2844
+ ["backgroundModel", config.backgroundModel]
2845
+ ]) {
2846
+ const parsed = splitModelRef(ref);
2847
+ if (!parsed) continue;
2848
+ const route = routeFor(parsed.providerId);
2849
+ route[field] = ref;
2850
+ if (_optionalChain([config, 'access', _126 => _126.backgroundModelIds, 'optionalAccess', _127 => _127.length])) {
2851
+ route.backgroundModelIds = [...config.backgroundModelIds];
2852
+ }
2853
+ }
2854
+ return [...byProvider.values()];
2855
+ }
2856
+ function legacyEndpointsToBindings(endpoints) {
2857
+ return endpoints.filter((endpoint) => hasConfiguredLegacyModels(endpoint)).flatMap((endpoint) => legacyEndpointToBindings(endpoint));
2858
+ }
2859
+ function normalizeGatewayBindings(raw) {
2860
+ if (!Array.isArray(raw)) return [];
2861
+ const seen = /* @__PURE__ */ new Set();
2862
+ const bindings = [];
2863
+ for (const entry of raw) {
2864
+ if (!entry || typeof entry !== "object") continue;
2865
+ const value = entry;
2866
+ const id = typeof value.id === "string" ? value.id.trim() : "";
2867
+ const name = typeof value.name === "string" ? value.name.trim() : "";
2868
+ const endpoint = value.endpoint;
2869
+ const target = normalizeBindingTarget(value.target);
2870
+ if (!id || seen.has(id) || !name || !ALL_ENDPOINTS.includes(endpoint) || !target) continue;
2871
+ seen.add(id);
2872
+ const normalizedRoute = normalizeEndpointConfig({
2873
+ ...value,
2874
+ endpoint,
2875
+ useSubscription: target.kind !== "provider"
2876
+ });
2877
+ const apiKeyIds = Array.isArray(value.apiKeyIds) ? [...new Set(value.apiKeyIds.filter((key) => typeof key === "string" && key.trim() !== "").map((key) => key.trim()))] : [];
2878
+ const keyScope = value.keyScope === "selected" ? "selected" : value.keyScope === "all" ? "all" : apiKeyIds.length > 0 ? "selected" : "all";
2879
+ const modelMappings = normalizeGatewayModelMappings(value.modelMappings);
2880
+ const modelMode = value.modelMode === "passthrough" ? "passthrough" : value.modelMode === "mapped" ? "mapped" : modelMappings.length > 0 || hasConfiguredLegacyModels(normalizedRoute) ? "mapped" : "passthrough";
2881
+ const priority = typeof value.priority === "number" && Number.isFinite(value.priority) ? Math.max(0, Math.min(1e4, Math.round(value.priority))) : void 0;
2882
+ const binding = {
2883
+ id,
2884
+ name,
2885
+ enabled: value.enabled !== false,
2886
+ keyScope,
2887
+ endpoint,
2888
+ target,
2889
+ // Legacy `'global'` meant "yield to the removed global endpoint fallback";
2890
+ // it now yields to the next matching route, which is the same default.
2891
+ fallback: value.fallback === "fail" ? "fail" : "next",
2892
+ modelMode
2893
+ };
2894
+ if (apiKeyIds.length > 0) binding.apiKeyIds = apiKeyIds;
2895
+ if (modelMappings.length > 0) binding.modelMappings = modelMappings;
2896
+ if (priority !== void 0) binding.priority = priority;
2897
+ if (normalizedRoute.modelMap) binding.modelMap = normalizedRoute.modelMap;
2898
+ if (normalizedRoute.models) binding.models = normalizedRoute.models;
2899
+ if (normalizedRoute.dispatchMode) binding.dispatchMode = normalizedRoute.dispatchMode;
2900
+ if (normalizedRoute.prefixTargets) binding.prefixTargets = normalizedRoute.prefixTargets;
2901
+ if (normalizedRoute.defaultModel !== void 0) binding.defaultModel = normalizedRoute.defaultModel;
2902
+ if (normalizedRoute.backgroundModel !== void 0) binding.backgroundModel = normalizedRoute.backgroundModel;
2903
+ if (normalizedRoute.backgroundModelIds) binding.backgroundModelIds = normalizedRoute.backgroundModelIds;
2904
+ bindings.push(binding);
2905
+ }
2906
+ return bindings;
2907
+ }
2427
2908
  function defaultServerConfig() {
2428
2909
  const queues = normalizeQueueSegments(void 0);
2429
2910
  return {
2430
2911
  enabled: false,
2431
2912
  networkBinding: false,
2432
2913
  endpoints: ALL_ENDPOINTS.map(defaultEndpointConfig),
2914
+ bindings: [],
2433
2915
  port: DEFAULT_OUTBOUND_PORT,
2434
2916
  userMessageQueue: queues.userMessageQueue,
2435
2917
  concurrencyQueue: queues.concurrencyQueue,
2436
2918
  accountHealth: normalizeAccountHealth(void 0),
2437
2919
  accountProbe: normalizeAccountProbe(void 0),
2920
+ allowanceScheduling: normalizeAllowanceScheduling(void 0),
2438
2921
  audit: normalizeAudit(void 0),
2439
2922
  billing: normalizeBilling(void 0),
2440
2923
  fingerprint: normalizeFingerprint(void 0),
@@ -2451,17 +2934,20 @@ function normalizeServerConfig(raw) {
2451
2934
  }
2452
2935
  }
2453
2936
  const queues = normalizeQueueSegments(raw);
2937
+ const legacyEndpoints = ALL_ENDPOINTS.map((ep) => _nullishCoalesce(byEndpoint.get(ep), () => ( defaultEndpointConfig(ep))));
2938
+ const persistedBindings = normalizeGatewayBindings(raw.bindings);
2939
+ const bindings = persistedBindings.length > 0 ? persistedBindings : normalizeGatewayBindings(legacyEndpointsToBindings(legacyEndpoints));
2454
2940
  const config = {
2455
2941
  enabled: raw.enabled === true,
2456
2942
  networkBinding: raw.networkBinding === true,
2457
- endpoints: ALL_ENDPOINTS.map(
2458
- (ep) => _nullishCoalesce(byEndpoint.get(ep), () => ( defaultEndpointConfig(ep)))
2459
- ),
2943
+ endpoints: ALL_ENDPOINTS.map(defaultEndpointConfig),
2944
+ bindings,
2460
2945
  port: _nullishCoalesce(raw.port, () => ( base.port)),
2461
2946
  userMessageQueue: queues.userMessageQueue,
2462
2947
  concurrencyQueue: queues.concurrencyQueue,
2463
2948
  accountHealth: normalizeAccountHealth(raw),
2464
2949
  accountProbe: normalizeAccountProbe(raw),
2950
+ allowanceScheduling: normalizeAllowanceScheduling(raw),
2465
2951
  audit: normalizeAudit(raw),
2466
2952
  billing: normalizeBilling(raw),
2467
2953
  fingerprint: normalizeFingerprint(raw),
@@ -2487,11 +2973,13 @@ function mergeServerConfig(current, patch) {
2487
2973
  enabled: _nullishCoalesce(patch.enabled, () => ( current.enabled)),
2488
2974
  networkBinding: _nullishCoalesce(patch.networkBinding, () => ( current.networkBinding)),
2489
2975
  endpoints: _nullishCoalesce(patch.endpoints, () => ( current.endpoints)),
2976
+ bindings: _nullishCoalesce(patch.bindings, () => ( current.bindings)),
2490
2977
  port: _nullishCoalesce(patch.port, () => ( current.port)),
2491
2978
  userMessageQueue: _nullishCoalesce(patch.userMessageQueue, () => ( current.userMessageQueue)),
2492
2979
  concurrencyQueue: _nullishCoalesce(patch.concurrencyQueue, () => ( current.concurrencyQueue)),
2493
2980
  accountHealth: _nullishCoalesce(patch.accountHealth, () => ( current.accountHealth)),
2494
2981
  accountProbe: _nullishCoalesce(patch.accountProbe, () => ( current.accountProbe)),
2982
+ allowanceScheduling: _nullishCoalesce(patch.allowanceScheduling, () => ( current.allowanceScheduling)),
2495
2983
  audit: _nullishCoalesce(patch.audit, () => ( current.audit)),
2496
2984
  billing: _nullishCoalesce(patch.billing, () => ( current.billing)),
2497
2985
  // Proxy is layer-replaced (not deep-merged): a PUT carrying `proxy` swaps the
@@ -2509,6 +2997,167 @@ function mergeServerConfig(current, patch) {
2509
2997
  });
2510
2998
  }
2511
2999
 
3000
+ // src/outbound-api/gatewayBindingResolver.ts
3001
+ var MESSAGE_FALLBACK_KINDS = ["sonnet", "opus", "haiku", "fable"];
3002
+ function nonBlank(value) {
3003
+ return typeof value === "string" && value.trim() !== "";
3004
+ }
3005
+ function gatewayBindingAllowsKey(binding, apiKeyId) {
3006
+ const scope = _nullishCoalesce(binding.keyScope, () => ( (_optionalChain([binding, 'access', _128 => _128.apiKeyIds, 'optionalAccess', _129 => _129.length]) ? "selected" : "all")));
3007
+ return scope === "all" || Boolean(_optionalChain([binding, 'access', _130 => _130.apiKeyIds, 'optionalAccess', _131 => _131.includes, 'call', _132 => _132(apiKeyId)]));
3008
+ }
3009
+ function wildcardMatches(pattern, value) {
3010
+ const escaped = pattern.split("*").map((part) => part.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&")).join(".*");
3011
+ return new RegExp(`^${escaped}$`, "iu").test(value);
3012
+ }
3013
+ function resolveGatewayModelMapping(mappings, requestedModel) {
3014
+ if (!nonBlank(requestedModel)) return void 0;
3015
+ const wanted = requestedModel.trim();
3016
+ const exact = (_nullishCoalesce(mappings, () => ( []))).find(
3017
+ (mapping) => nonBlank(mapping.source) && !mapping.source.includes("*") && mapping.source.trim().toLocaleLowerCase() === wanted.toLocaleLowerCase()
3018
+ );
3019
+ if (exact && nonBlank(exact.target)) return exact.target.trim();
3020
+ const wildcard = (_nullishCoalesce(mappings, () => ( []))).find(
3021
+ (mapping) => nonBlank(mapping.source) && mapping.source.includes("*") && wildcardMatches(mapping.source.trim(), wanted)
3022
+ );
3023
+ return wildcard && nonBlank(wildcard.target) ? wildcard.target.trim() : void 0;
3024
+ }
3025
+ function routeCanServe(binding, requestedModel, role) {
3026
+ if (binding.modelMode === "passthrough") return nonBlank(requestedModel);
3027
+ if (_optionalChain([binding, 'access', _133 => _133.modelMappings, 'optionalAccess', _134 => _134.length])) {
3028
+ return nonBlank(resolveGatewayModelMapping(binding.modelMappings, requestedModel));
3029
+ }
3030
+ if (_chunk4VZX5F4Tcjs.isKindMappedEndpoint.call(void 0, binding.endpoint)) {
3031
+ const map = _nullishCoalesce(binding.modelMap, () => ( {}));
3032
+ const kind = _chunk4VZX5F4Tcjs.detectModelKind.call(void 0, binding.endpoint, requestedModel);
3033
+ if (kind && nonBlank(map[kind])) return true;
3034
+ if (binding.endpoint === "messages") {
3035
+ return MESSAGE_FALLBACK_KINDS.some((candidate) => nonBlank(map[candidate]));
3036
+ }
3037
+ return nonBlank(map.codex);
3038
+ }
3039
+ if (binding.endpoint === "chat" && binding.dispatchMode === "prefix") {
3040
+ return _chunk4VZX5F4Tcjs.resolvePrefixTarget.call(void 0, binding.prefixTargets, requestedModel) !== null;
3041
+ }
3042
+ if (binding.endpoint === "chat") {
3043
+ if (!requestedModel) return false;
3044
+ const wanted = requestedModel.trim().toLowerCase();
3045
+ return (_nullishCoalesce(binding.models, () => ( []))).some((ref) => _optionalChain([modelIdOf, 'call', _135 => _135(ref), 'optionalAccess', _136 => _136.toLowerCase, 'call', _137 => _137()]) === wanted);
3046
+ }
3047
+ return role === "background" ? nonBlank(binding.backgroundModel) : nonBlank(binding.defaultModel);
3048
+ }
3049
+ function modelIdOf(ref) {
3050
+ if (!nonBlank(ref)) return void 0;
3051
+ const trimmed = ref.trim();
3052
+ const comma = trimmed.indexOf(",");
3053
+ const modelId = comma >= 0 ? trimmed.slice(comma + 1).trim() : trimmed;
3054
+ return modelId || void 0;
3055
+ }
3056
+ function targetProviderId(target) {
3057
+ return target.providerId.trim();
3058
+ }
3059
+ function targetRef(target, ref) {
3060
+ const modelId = _nullishCoalesce(modelIdOf(ref), () => ( ""));
3061
+ return modelId ? `${targetProviderId(target)},${modelId}` : "";
3062
+ }
3063
+ function targetRefs(target, refs) {
3064
+ return (_nullishCoalesce(refs, () => ( []))).map((ref) => targetRef(target, ref)).filter(nonBlank);
3065
+ }
3066
+ function targetPrefixRefs(target, refs) {
3067
+ if (!refs) return void 0;
3068
+ const mapped = {};
3069
+ for (const kind of ["claude", "gpt", "gemini"]) {
3070
+ const ref = targetRef(target, refs[kind]);
3071
+ if (ref) mapped[kind] = ref;
3072
+ }
3073
+ return mapped.claude || mapped.gpt || mapped.gemini ? mapped : void 0;
3074
+ }
3075
+ function applySingleModel(config, binding, targetModel) {
3076
+ const ref = targetRef(binding.target, targetModel);
3077
+ if (!ref) return;
3078
+ if (_chunk4VZX5F4Tcjs.isKindMappedEndpoint.call(void 0, binding.endpoint)) {
3079
+ config.modelMap = Object.fromEntries(
3080
+ _chunk4VZX5F4Tcjs.modelKindsForEndpoint.call(void 0, binding.endpoint).map((kind) => [kind, ref])
3081
+ );
3082
+ } else if (binding.endpoint === "chat") {
3083
+ config.models = [ref];
3084
+ config.dispatchMode = "list";
3085
+ } else {
3086
+ config.defaultModel = ref;
3087
+ config.backgroundModel = ref;
3088
+ }
3089
+ }
3090
+ function gatewayBindingToEndpointConfig(binding, requestedModel) {
3091
+ const target = binding.target;
3092
+ const config = {
3093
+ endpoint: binding.endpoint,
3094
+ useSubscription: target.kind !== "provider"
3095
+ };
3096
+ const usesGenericModelHandling = binding.modelMode === "passthrough" || Boolean(_optionalChain([binding, 'access', _138 => _138.modelMappings, 'optionalAccess', _139 => _139.length]));
3097
+ const dynamicModel = binding.modelMode === "passthrough" ? requestedModel : resolveGatewayModelMapping(binding.modelMappings, requestedModel);
3098
+ if (usesGenericModelHandling) {
3099
+ if (nonBlank(dynamicModel)) applySingleModel(config, binding, dynamicModel);
3100
+ } else if (_chunk4VZX5F4Tcjs.isKindMappedEndpoint.call(void 0, binding.endpoint)) {
3101
+ config.modelMap = Object.fromEntries(
3102
+ Object.entries(_nullishCoalesce(binding.modelMap, () => ( {}))).map(([kind, ref]) => [kind, targetRef(target, ref)])
3103
+ );
3104
+ } else if (binding.endpoint === "chat") {
3105
+ config.models = targetRefs(target, binding.models);
3106
+ if (binding.dispatchMode === "prefix") {
3107
+ config.dispatchMode = "prefix";
3108
+ config.prefixTargets = targetPrefixRefs(target, binding.prefixTargets);
3109
+ }
3110
+ } else {
3111
+ config.defaultModel = targetRef(target, binding.defaultModel);
3112
+ config.backgroundModel = targetRef(target, binding.backgroundModel);
3113
+ if (binding.backgroundModelIds) config.backgroundModelIds = [...binding.backgroundModelIds];
3114
+ }
3115
+ if (target.kind === "account") {
3116
+ config.boundAccountId = target.accountId;
3117
+ config.boundAccountFallbackPolicy = binding.fallback === "next" ? "pool" : "strict";
3118
+ } else if (target.kind === "account-group") {
3119
+ config.boundAccountGroup = target.group;
3120
+ config.boundAccountFallbackPolicy = binding.fallback === "next" ? "pool" : "strict";
3121
+ } else if (target.kind === "provider" && target.keyId) {
3122
+ config.boundKeyId = target.keyId;
3123
+ config.boundKeyFallbackPolicy = binding.fallback === "next" ? "pool" : "strict";
3124
+ }
3125
+ return config;
3126
+ }
3127
+ function candidateGatewayBindings(bindings, apiKeyId, endpoint) {
3128
+ const candidates = (_nullishCoalesce(bindings, () => ( []))).filter(
3129
+ (binding) => binding.enabled && binding.endpoint === endpoint && gatewayBindingAllowsKey(binding, apiKeyId)
3130
+ );
3131
+ const scopeOf = (binding) => _nullishCoalesce(binding.keyScope, () => ( (_optionalChain([binding, 'access', _140 => _140.apiKeyIds, 'optionalAccess', _141 => _141.length]) ? "selected" : "all")));
3132
+ const scoped = candidates.filter((binding) => scopeOf(binding) === "selected");
3133
+ const pool = scoped.length > 0 ? scoped : candidates.filter((binding) => scopeOf(binding) === "all");
3134
+ return pool.sort(
3135
+ (left, right) => (_nullishCoalesce(left.priority, () => ( 100))) - (_nullishCoalesce(right.priority, () => ( 100))) || left.id.localeCompare(right.id)
3136
+ );
3137
+ }
3138
+ function candidateBackgroundModelIds(bindings, apiKeyId, endpoint) {
3139
+ const ids = [
3140
+ ...new Set(
3141
+ candidateGatewayBindings(bindings, apiKeyId, endpoint).flatMap(
3142
+ (binding) => _nullishCoalesce(binding.backgroundModelIds, () => ( []))
3143
+ )
3144
+ )
3145
+ ];
3146
+ return ids.length > 0 ? ids : void 0;
3147
+ }
3148
+ function resolveGatewayBinding(input) {
3149
+ const candidates = candidateGatewayBindings(input.bindings, input.apiKeyId, input.endpoint);
3150
+ const binding = _nullishCoalesce(candidates.find(
3151
+ (candidate) => candidate.fallback === "fail" || routeCanServe(candidate, input.requestedModel, input.role)
3152
+ ), () => ( candidates[0]));
3153
+ if (!binding) return { source: "none" };
3154
+ return {
3155
+ source: "binding",
3156
+ binding,
3157
+ config: gatewayBindingToEndpointConfig(binding, input.requestedModel)
3158
+ };
3159
+ }
3160
+
2512
3161
  // src/outbound-api/outboundApiKeyAuth.ts
2513
3162
 
2514
3163
 
@@ -2601,6 +3250,27 @@ async function createNamedKey(db, name) {
2601
3250
  plaintextOnce: secret
2602
3251
  };
2603
3252
  }
3253
+ async function createIntegrationKey(db, name, allowedEndpoints = ["responses", "messages"]) {
3254
+ const secret = generateSecret();
3255
+ const id = newKeyId();
3256
+ const prefix = keyPrefix(secret);
3257
+ const row = await db.outboundApiKeysCreate({
3258
+ id,
3259
+ name,
3260
+ keyHash: hashKey(secret),
3261
+ keyPrefix: prefix,
3262
+ kind: "integration",
3263
+ allowedEndpoints: [...new Set(allowedEndpoints)],
3264
+ loopbackOnly: true
3265
+ });
3266
+ return {
3267
+ id: row.id,
3268
+ name: row.name,
3269
+ keyPrefix: row.keyPrefix,
3270
+ createdAt: row.createdAt,
3271
+ plaintextOnce: secret
3272
+ };
3273
+ }
2604
3274
  function extractCostLimits(row) {
2605
3275
  const limits = {};
2606
3276
  if (row.dailyCostLimitUsd != null) limits.dailyUsd = row.dailyCostLimitUsd;
@@ -2623,7 +3293,12 @@ function extractModelRestriction(row) {
2623
3293
  };
2624
3294
  }
2625
3295
  function toVerifiedKey(row) {
2626
- const key = { id: row.id };
3296
+ const key = {
3297
+ id: row.id,
3298
+ kind: row.kind,
3299
+ allowedEndpoints: row.allowedEndpoints,
3300
+ loopbackOnly: row.loopbackOnly
3301
+ };
2627
3302
  if (row.maxConcurrency !== void 0 && row.maxConcurrency !== null) {
2628
3303
  key.maxConcurrency = row.maxConcurrency;
2629
3304
  }
@@ -2843,8 +3518,8 @@ var OutboundRateLimiter = (_class8 = class {
2843
3518
  * recorded (no bucket growth).
2844
3519
  */
2845
3520
  check(apiKeyId, now = Date.now(), override) {
2846
- const maxRequests = _nullishCoalesce(_optionalChain([override, 'optionalAccess', _105 => _105.maxRequests]), () => ( this.maxRequests));
2847
- const windowMs = _nullishCoalesce(_optionalChain([override, 'optionalAccess', _106 => _106.windowMs]), () => ( this.windowMs));
3521
+ const maxRequests = _nullishCoalesce(_optionalChain([override, 'optionalAccess', _142 => _142.maxRequests]), () => ( this.maxRequests));
3522
+ const windowMs = _nullishCoalesce(_optionalChain([override, 'optionalAccess', _143 => _143.windowMs]), () => ( this.windowMs));
2848
3523
  if (maxRequests === 0) return { allowed: true, retryAfterSeconds: 0 };
2849
3524
  const cutoff = now - windowMs;
2850
3525
  const timestamps = (_nullishCoalesce(this.hits.get(apiKeyId), () => ( []))).filter((ts) => ts > cutoff);
@@ -2889,7 +3564,7 @@ function isUserMessageAnthropic(body) {
2889
3564
  if (typeof content === "string") return true;
2890
3565
  if (Array.isArray(content)) {
2891
3566
  const hasToolResult = content.some(
2892
- (block) => _optionalChain([asObject, 'call', _107 => _107(block), 'optionalAccess', _108 => _108["type"]]) === "tool_result"
3567
+ (block) => _optionalChain([asObject, 'call', _144 => _144(block), 'optionalAccess', _145 => _145["type"]]) === "tool_result"
2893
3568
  );
2894
3569
  return !hasToolResult;
2895
3570
  }
@@ -2918,7 +3593,7 @@ function isUserMessageGemini(body) {
2918
3593
  if (!lastContent || lastContent["role"] !== "user") return false;
2919
3594
  const parts = asArray(lastContent["parts"]);
2920
3595
  const hasFunctionResponse = parts.some(
2921
- (part) => _optionalChain([asObject, 'call', _109 => _109(part), 'optionalAccess', _110 => _110["functionResponse"]]) !== void 0
3596
+ (part) => _optionalChain([asObject, 'call', _146 => _146(part), 'optionalAccess', _147 => _147["functionResponse"]]) !== void 0
2922
3597
  );
2923
3598
  return !hasFunctionResponse;
2924
3599
  }
@@ -3092,14 +3767,14 @@ function newVoucherId() {
3092
3767
  }
3093
3768
  function computeVoucherGrant(voucher, currentKey, now) {
3094
3769
  if (voucher.type === "credit") {
3095
- const current = _nullishCoalesce(_optionalChain([currentKey, 'optionalAccess', _111 => _111.totalCostLimitUsd]), () => ( 0));
3770
+ const current = _nullishCoalesce(_optionalChain([currentKey, 'optionalAccess', _148 => _148.totalCostLimitUsd]), () => ( 0));
3096
3771
  let granted2 = current + (_nullishCoalesce(voucher.creditUsd, () => ( 0)));
3097
3772
  if (voucher.maxTotalCostLimitUsd != null) {
3098
3773
  granted2 = Math.min(granted2, voucher.maxTotalCostLimitUsd);
3099
3774
  }
3100
3775
  return { totalCostLimitUsd: granted2 };
3101
3776
  }
3102
- const currentExpiry = _nullishCoalesce(_optionalChain([currentKey, 'optionalAccess', _112 => _112.expiresAt]), () => ( now));
3777
+ const currentExpiry = _nullishCoalesce(_optionalChain([currentKey, 'optionalAccess', _149 => _149.expiresAt]), () => ( now));
3103
3778
  let granted = currentExpiry + (_nullishCoalesce(voucher.renewalDays, () => ( 0))) * DAY_MS2;
3104
3779
  if (voucher.maxExpiryDays != null) {
3105
3780
  granted = Math.min(granted, now + voucher.maxExpiryDays * DAY_MS2);
@@ -3130,7 +3805,7 @@ function toVoucherInfo(v) {
3130
3805
  // src/outbound-api/voucherRedeem.ts
3131
3806
  function isRedeemRequest(method, url) {
3132
3807
  if (method !== "POST" || !url) return false;
3133
- const path = _nullishCoalesce(_optionalChain([url, 'access', _113 => _113.split, 'call', _114 => _114("?"), 'access', _115 => _115[0], 'optionalAccess', _116 => _116.replace, 'call', _117 => _117(/\/+$/, "")]), () => ( ""));
3808
+ const path = _nullishCoalesce(_optionalChain([url, 'access', _150 => _150.split, 'call', _151 => _151("?"), 'access', _152 => _152[0], 'optionalAccess', _153 => _153.replace, 'call', _154 => _154(/\/+$/, "")]), () => ( ""));
3134
3809
  return path.endsWith("/redeem");
3135
3810
  }
3136
3811
  function writeErr(res, status, message, headers = {}) {
@@ -3160,8 +3835,8 @@ function grantToResult(type, granted) {
3160
3835
  function currentResult(type, keyRow) {
3161
3836
  const result = { type };
3162
3837
  if (type === "credit") {
3163
- if (_optionalChain([keyRow, 'optionalAccess', _118 => _118.totalCostLimitUsd]) != null) result.totalCostLimitUsd = keyRow.totalCostLimitUsd;
3164
- } else if (_optionalChain([keyRow, 'optionalAccess', _119 => _119.expiresAt]) != null) {
3838
+ if (_optionalChain([keyRow, 'optionalAccess', _155 => _155.totalCostLimitUsd]) != null) result.totalCostLimitUsd = keyRow.totalCostLimitUsd;
3839
+ } else if (_optionalChain([keyRow, 'optionalAccess', _156 => _156.expiresAt]) != null) {
3165
3840
  result.expiresAt = keyRow.expiresAt;
3166
3841
  }
3167
3842
  return result;
@@ -3199,7 +3874,7 @@ async function handleVoucherRedeem(req, res, deps, voucherEnabled, redeemLimiter
3199
3874
  let code;
3200
3875
  try {
3201
3876
  code = raw ? JSON.parse(raw)["code"] : void 0;
3202
- } catch (e19) {
3877
+ } catch (e24) {
3203
3878
  writeErr(res, 400, "Invalid JSON in request body");
3204
3879
  return;
3205
3880
  }
@@ -3248,7 +3923,7 @@ async function handleVoucherRedeem(req, res, deps, voucherEnabled, redeemLimiter
3248
3923
  const won = await voucherDb.voucherRedeemCas(voucher.id, verifiedKeyId, absolute, now);
3249
3924
  if (!won) {
3250
3925
  const after = await voucherDb.voucherGetByHash(codeHash);
3251
- if (_optionalChain([after, 'optionalAccess', _120 => _120.status]) === "redeemed" && after.redeemedByKeyId === verifiedKeyId) {
3926
+ if (_optionalChain([after, 'optionalAccess', _157 => _157.status]) === "redeemed" && after.redeemedByKeyId === verifiedKeyId) {
3252
3927
  return after.grantApplied === true ? { ok: true, result: currentResult(after.type, await deps.db.outboundApiKeysGetByHash(keyHash)) } : await applyFirstPass(after, recordedAbsolute(after));
3253
3928
  }
3254
3929
  return { ok: false, status: 409, message: "Code was already redeemed" };
@@ -3267,10 +3942,10 @@ function getFallbackRedeemLimiter() {
3267
3942
  fallbackRedeemLimiter ??= new OutboundRateLimiter({ maxRequests: 10, windowMs: 6e4 });
3268
3943
  return fallbackRedeemLimiter;
3269
3944
  }
3270
- function writeJsonError(res, status, message, headers = {}) {
3945
+ function writeJsonError(res, status, message, headers = {}, details = {}) {
3271
3946
  if (res.headersSent) return;
3272
3947
  res.writeHead(status, { "Content-Type": "application/json", ...headers });
3273
- res.end(JSON.stringify({ error: { type: "outbound_api_error", message } }));
3948
+ res.end(JSON.stringify({ error: { type: "outbound_api_error", message, ...details } }));
3274
3949
  }
3275
3950
  function writeCostLimitError(res, scope, limitUsd, spentUsd) {
3276
3951
  if (res.headersSent) return;
@@ -3309,14 +3984,19 @@ function extractPresentedKey(req) {
3309
3984
  }
3310
3985
  const xApiKey = req.headers["x-api-key"];
3311
3986
  const xApi = Array.isArray(xApiKey) ? xApiKey[0] : xApiKey;
3312
- if (_optionalChain([xApi, 'optionalAccess', _121 => _121.trim, 'call', _122 => _122()])) return xApi.trim();
3987
+ if (_optionalChain([xApi, 'optionalAccess', _158 => _158.trim, 'call', _159 => _159()])) return xApi.trim();
3313
3988
  const goog = req.headers["x-goog-api-key"];
3314
3989
  const g = Array.isArray(goog) ? goog[0] : goog;
3315
- return _optionalChain([g, 'optionalAccess', _123 => _123.trim, 'call', _124 => _124()]) || void 0;
3990
+ return _optionalChain([g, 'optionalAccess', _160 => _160.trim, 'call', _161 => _161()]) || void 0;
3991
+ }
3992
+ function isLoopbackPeer(address) {
3993
+ if (!address) return false;
3994
+ const normalized = address.toLowerCase().split("%")[0];
3995
+ return normalized === "::1" || normalized === "127.0.0.1" || normalized.startsWith("127.") || normalized.startsWith("::ffff:127.");
3316
3996
  }
3317
3997
  function selectEndpoint(method, url) {
3318
3998
  if (method !== "POST" || !url) return null;
3319
- const path = _nullishCoalesce(_optionalChain([url, 'access', _125 => _125.split, 'call', _126 => _126("?"), 'access', _127 => _127[0], 'optionalAccess', _128 => _128.replace, 'call', _129 => _129(/\/+$/, "")]), () => ( ""));
3999
+ const path = _nullishCoalesce(_optionalChain([url, 'access', _162 => _162.split, 'call', _163 => _163("?"), 'access', _164 => _164[0], 'optionalAccess', _165 => _165.replace, 'call', _166 => _166(/\/+$/, "")]), () => ( ""));
3320
4000
  if (path.endsWith("/chat/completions")) return "chat";
3321
4001
  if (path.endsWith("/responses")) return "responses";
3322
4002
  if (path.includes("/v1/messages")) return "messages";
@@ -3334,12 +4014,36 @@ function extractGeminiModelFromUrl(url) {
3334
4014
  }
3335
4015
  function isModelsListRequest(url) {
3336
4016
  if (!url) return false;
3337
- const path = _nullishCoalesce(_optionalChain([url, 'access', _130 => _130.split, 'call', _131 => _131("?"), 'access', _132 => _132[0], 'optionalAccess', _133 => _133.replace, 'call', _134 => _134(/\/+$/, "")]), () => ( ""));
4017
+ const path = _nullishCoalesce(_optionalChain([url, 'access', _167 => _167.split, 'call', _168 => _168("?"), 'access', _169 => _169[0], 'optionalAccess', _170 => _170.replace, 'call', _171 => _171(/\/+$/, "")]), () => ( ""));
3338
4018
  return path.endsWith("/models");
3339
4019
  }
3340
- function writeChatModelsList(res, config) {
3341
- const chat = config.endpoints.find((e) => e.endpoint === "chat");
3342
- const data = (_nullishCoalesce(_optionalChain([chat, 'optionalAccess', _135 => _135.models]), () => ( []))).map((ref) => _chunkVACWOIREcjs.parseModelRef.call(void 0, ref)).filter((p) => p !== null).map((p) => ({ id: p.modelId, object: "model", owned_by: "omnicross" }));
4020
+ function writeModelsList(res, config, apiKeyId, allowedEndpoints) {
4021
+ const refs = [];
4022
+ const endpointConfigs = [];
4023
+ for (const endpoint of ["chat", "responses", "messages", "gemini"]) {
4024
+ if (allowedEndpoints && !allowedEndpoints.includes(endpoint)) continue;
4025
+ endpointConfigs.push(
4026
+ ...candidateGatewayBindings(config.bindings, apiKeyId, endpoint).map(
4027
+ (binding) => gatewayBindingToEndpointConfig(binding)
4028
+ )
4029
+ );
4030
+ }
4031
+ for (const endpoint of endpointConfigs) {
4032
+ if (allowedEndpoints && !allowedEndpoints.includes(endpoint.endpoint)) continue;
4033
+ if (endpoint.endpoint === "chat") refs.push(..._nullishCoalesce(endpoint.models, () => ( [])));
4034
+ else if (endpoint.endpoint === "messages" || endpoint.endpoint === "responses") {
4035
+ refs.push(...Object.values(_nullishCoalesce(endpoint.modelMap, () => ( {}))));
4036
+ } else {
4037
+ if (endpoint.defaultModel) refs.push(endpoint.defaultModel);
4038
+ if (endpoint.backgroundModel) refs.push(endpoint.backgroundModel);
4039
+ }
4040
+ }
4041
+ const seen = /* @__PURE__ */ new Set();
4042
+ const data = refs.map((ref) => _chunk4VZX5F4Tcjs.parseModelRef.call(void 0, ref)).filter((p) => p !== null).filter((p) => {
4043
+ if (seen.has(p.modelId)) return false;
4044
+ seen.add(p.modelId);
4045
+ return true;
4046
+ }).map((p) => ({ id: p.modelId, object: "model", owned_by: "omnicross" }));
3343
4047
  res.writeHead(200, { "Content-Type": "application/json" });
3344
4048
  res.end(JSON.stringify({ object: "list", data }));
3345
4049
  }
@@ -3373,12 +4077,20 @@ async function handleOutboundRequest(req, res, deps, config, rateLimiter, serial
3373
4077
  const verified = verification.key;
3374
4078
  if (audit) audit.keyId = verified.id;
3375
4079
  if (billing) billing.keyId = verified.id;
4080
+ if (verified.loopbackOnly && !isLoopbackPeer(_optionalChain([req, 'access', _172 => _172.socket, 'optionalAccess', _173 => _173.remoteAddress]))) {
4081
+ writeJsonError(res, 403, "This integration key is restricted to loopback clients");
4082
+ return;
4083
+ }
3376
4084
  if (isRedeemRequest(req.method, req.url)) {
4085
+ if (verified.kind === "integration") {
4086
+ writeJsonError(res, 403, "Integration keys cannot redeem vouchers");
4087
+ return;
4088
+ }
3377
4089
  await handleVoucherRedeem(
3378
4090
  req,
3379
4091
  res,
3380
4092
  deps,
3381
- _optionalChain([config, 'access', _136 => _136.voucher, 'optionalAccess', _137 => _137.enabled]) === true,
4093
+ _optionalChain([config, 'access', _174 => _174.voucher, 'optionalAccess', _175 => _175.enabled]) === true,
3382
4094
  _nullishCoalesce(redeemLimiter, () => ( getFallbackRedeemLimiter())),
3383
4095
  verified.id,
3384
4096
  _nullishCoalesce(presented, () => ( "")),
@@ -3395,7 +4107,11 @@ async function handleOutboundRequest(req, res, deps, config, rateLimiter, serial
3395
4107
  return;
3396
4108
  }
3397
4109
  if (req.method === "GET" && isModelsListRequest(req.url)) {
3398
- writeChatModelsList(res, config);
4110
+ if (verified.allowedEndpoints && verified.allowedEndpoints.length === 0) {
4111
+ writeJsonError(res, 403, "API key is not allowed to access this endpoint");
4112
+ return;
4113
+ }
4114
+ writeModelsList(res, config, verified.id, verified.allowedEndpoints);
3399
4115
  return;
3400
4116
  }
3401
4117
  const endpoint = selectEndpoint(req.method, req.url);
@@ -3403,9 +4119,12 @@ async function handleOutboundRequest(req, res, deps, config, rateLimiter, serial
3403
4119
  writeJsonError(res, 404, `Unsupported: ${req.method} ${req.url}`);
3404
4120
  return;
3405
4121
  }
3406
- const endpointConfig = config.endpoints.find((e) => e.endpoint === endpoint);
3407
- if (!endpointConfig) {
3408
- writeJsonError(res, 503, `endpoint '${endpoint}' is not configured`);
4122
+ if (verified.allowedEndpoints && !verified.allowedEndpoints.includes(endpoint)) {
4123
+ writeJsonError(res, 403, "API key is not allowed to access this endpoint");
4124
+ return;
4125
+ }
4126
+ if (candidateGatewayBindings(config.bindings, verified.id, endpoint).length === 0) {
4127
+ writeJsonError(res, 503, `endpoint '${endpoint}' has no downstream route for this key`);
3409
4128
  return;
3410
4129
  }
3411
4130
  if (verified.costLimits && deps.keySpendTracker) {
@@ -3464,12 +4183,12 @@ async function handleOutboundRequest(req, res, deps, config, rateLimiter, serial
3464
4183
  res.once("close", release2);
3465
4184
  }
3466
4185
  try {
3467
- const ingressFormat = _chunkVACWOIREcjs.endpointToIngressFormat.call(void 0, endpoint);
4186
+ const ingressFormat = _chunk4VZX5F4Tcjs.endpointToIngressFormat.call(void 0, endpoint);
3468
4187
  const rawBody = await readBody3(req);
3469
4188
  let parsedBody = {};
3470
4189
  try {
3471
4190
  parsedBody = rawBody ? JSON.parse(rawBody) : {};
3472
- } catch (e20) {
4191
+ } catch (e25) {
3473
4192
  writeJsonError(res, 400, "Invalid JSON in request body");
3474
4193
  return;
3475
4194
  }
@@ -3478,23 +4197,40 @@ async function handleOutboundRequest(req, res, deps, config, rateLimiter, serial
3478
4197
  const urlModel = extractGeminiModelFromUrl(req.url);
3479
4198
  if (urlModel) parsedBody["model"] = urlModel;
3480
4199
  }
3481
- const sessionId = deps.proxyDeps.apiKeyPool ? `outbound:${verified.id}` : null;
3482
- const resolved = _chunkVACWOIREcjs.isKindMappedEndpoint.call(void 0, endpoint) || endpoint === "chat" ? await _chunkVACWOIREcjs.resolveRoute.call(void 0, {
3483
- config: endpointConfig,
4200
+ const requestedModel = _chunk4VZX5F4Tcjs.extractRequestedModel.call(void 0, ingressFormat, parsedBody);
4201
+ const role = _chunk4VZX5F4Tcjs.isKindMappedEndpoint.call(void 0, endpoint) || endpoint === "chat" ? void 0 : _chunk4VZX5F4Tcjs.detectRequestRole.call(void 0, ingressFormat, parsedBody, {
4202
+ // Role detection precedes the route pick (the pick consumes the
4203
+ // role), so the hint is the union across the candidate routes.
4204
+ backgroundModelIds: candidateBackgroundModelIds(config.bindings, verified.id, endpoint)
4205
+ });
4206
+ const bindingResolution = resolveGatewayBinding({
4207
+ bindings: config.bindings,
4208
+ apiKeyId: verified.id,
4209
+ endpoint,
4210
+ requestedModel,
4211
+ role
4212
+ });
4213
+ if (bindingResolution.source === "none") {
4214
+ writeJsonError(res, 503, `endpoint '${endpoint}' has no downstream route for this key`);
4215
+ return;
4216
+ }
4217
+ const effectiveEndpointConfig = bindingResolution.config;
4218
+ const bindingAffinitySuffix = `:${bindingResolution.binding.id}`;
4219
+ const sessionId = deps.proxyDeps.apiKeyPool ? `outbound:${verified.id}${bindingAffinitySuffix}` : null;
4220
+ const resolved = _chunk4VZX5F4Tcjs.isKindMappedEndpoint.call(void 0, endpoint) || endpoint === "chat" ? await _chunk4VZX5F4Tcjs.resolveRoute.call(void 0, {
4221
+ config: effectiveEndpointConfig,
3484
4222
  ingressFormat,
3485
4223
  llmConfig: deps.llmConfig,
3486
4224
  sessionId,
3487
4225
  // Capture the ORIGINAL requested id BEFORE any downstream swap; for
3488
4226
  // kind-mapped endpoints it selects the kind AND is stamped onto
3489
4227
  // `route.requestedModel`; for chat it is matched against the list.
3490
- requestedModel: _chunkVACWOIREcjs.extractRequestedModel.call(void 0, ingressFormat, parsedBody),
4228
+ requestedModel,
3491
4229
  // Attribution: stamp the verified named-key id onto the route.
3492
4230
  apiKeyId: verified.id
3493
- }) : await _chunkVACWOIREcjs.resolveRoute.call(void 0, {
3494
- config: endpointConfig,
3495
- role: _chunkVACWOIREcjs.detectRequestRole.call(void 0, ingressFormat, parsedBody, {
3496
- backgroundModelIds: endpointConfig.backgroundModelIds
3497
- }),
4231
+ }) : await _chunk4VZX5F4Tcjs.resolveRoute.call(void 0, {
4232
+ config: effectiveEndpointConfig,
4233
+ role,
3498
4234
  ingressFormat,
3499
4235
  llmConfig: deps.llmConfig,
3500
4236
  sessionId,
@@ -3523,7 +4259,7 @@ async function handleOutboundRequest(req, res, deps, config, rateLimiter, serial
3523
4259
  }
3524
4260
  let releaseSerial = null;
3525
4261
  const providerKey = resolved.route.providerId;
3526
- if (_optionalChain([config, 'access', _138 => _138.userMessageQueue, 'optionalAccess', _139 => _139.enabled]) && providerKey && isUserMessageRequest(endpoint, parsedBody)) {
4262
+ if (_optionalChain([config, 'access', _176 => _176.userMessageQueue, 'optionalAccess', _177 => _177.enabled]) && providerKey && isUserMessageRequest(endpoint, parsedBody)) {
3527
4263
  const umq = config.userMessageQueue;
3528
4264
  try {
3529
4265
  const serialSlot = await serialQueue.acquire(providerKey, {
@@ -3555,12 +4291,29 @@ async function handleOutboundRequest(req, res, deps, config, rateLimiter, serial
3555
4291
  const replay = makeReplayRequest(req, rawBody);
3556
4292
  await routeRequest(replay, res, routeMap, deps.proxyDeps);
3557
4293
  } catch (err) {
4294
+ if (_chunk25GXJCEZcjs.isBoundAccountSelectionError.call(void 0, err)) {
4295
+ const headers = {};
4296
+ if (err.status === 429 && err.resumeAt) {
4297
+ const resumeMs = Date.parse(err.resumeAt);
4298
+ if (Number.isFinite(resumeMs)) {
4299
+ headers["Retry-After"] = String(Math.max(1, Math.ceil((resumeMs - Date.now()) / 1e3)));
4300
+ }
4301
+ }
4302
+ writeJsonError(
4303
+ res,
4304
+ err.status,
4305
+ _chunk25GXJCEZcjs.boundAccountSelectionMessage.call(void 0, err.reason),
4306
+ headers,
4307
+ { code: err.code, reason: err.reason }
4308
+ );
4309
+ return;
4310
+ }
3558
4311
  const message = _chunkSVNDB62Dcjs.serializeError.call(void 0, err);
3559
4312
  if (deps.logger) deps.logger.error("[OutboundApi] dispatch error:", message);
3560
4313
  else console.error("[OutboundApi] dispatch error:", message);
3561
4314
  _chunkUIBD2YY5cjs.emitWebhookEvent.call(void 0, { kind: "server.error", at: Date.now(), message });
3562
4315
  if (audit) audit.error = message;
3563
- writeJsonError(res, 502, message);
4316
+ writeJsonError(res, _chunk6QQG7YG3cjs.isAccountAllowanceExhaustedError.call(void 0, err) ? 429 : 502, message);
3564
4317
  } finally {
3565
4318
  routeMap.removeRoute(token);
3566
4319
  if (releaseSerial) releaseSerial();
@@ -3584,18 +4337,8 @@ function makeReplayRequest(req, rawBody) {
3584
4337
  var DEFAULT_OUTBOUND_PORT = 8765;
3585
4338
  var LOOPBACK_ADDR = "127.0.0.1";
3586
4339
  var LAN_ADDR = "0.0.0.0";
3587
- var OutboundApiConfigError = class extends Error {
3588
-
3589
- constructor(missing) {
3590
- super(
3591
- "Outbound API server cannot start: incomplete model-kind configuration \u2014 " + missing.map((m) => `${m.endpoint} missing [${m.missingKinds.join(", ")}]`).join("; ")
3592
- );
3593
- this.name = "OutboundApiConfigError";
3594
- this.missing = missing;
3595
- }
3596
- };
3597
4340
  var OutboundApiServer = (_class11 = class {
3598
- 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);
4341
+ 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);_class11.prototype.__init21.call(this);
3599
4342
  this.deps = deps;
3600
4343
  this.onPortChange = onPortChange;
3601
4344
  }
@@ -3605,25 +4348,26 @@ var OutboundApiServer = (_class11 = class {
3605
4348
  __init13() {this.boundPort = 0}
3606
4349
  __init14() {this.boundAddr = LOOPBACK_ADDR}
3607
4350
  __init15() {this.endpoints = []}
4351
+ __init16() {this.bindings = []}
3608
4352
 
3609
4353
 
3610
4354
 
3611
- __init16() {this.rateLimiter = new OutboundRateLimiter()}
4355
+ __init17() {this.rateLimiter = new OutboundRateLimiter()}
3612
4356
  /**
3613
4357
  * Redeem-attempt limiter (voucher-redemption #9, design D6) — a SEPARATE bucket
3614
4358
  * from the traffic `rateLimiter`, keyed by the authenticating key id, so
3615
4359
  * brute-forcing `CC_` codes is throttled (a handful/min) without touching the
3616
4360
  * per-key request rate. Conservative fixed defaults (10 / 60s).
3617
4361
  */
3618
- __init17() {this.redeemLimiter = new OutboundRateLimiter({ maxRequests: 10, windowMs: 6e4 })}
4362
+ __init18() {this.redeemLimiter = new OutboundRateLimiter({ maxRequests: 10, windowMs: 6e4 })}
3619
4363
  /**
3620
4364
  * Per-key redeem mutex (voucher-redemption #9, MJ1 fix). One instance for the
3621
4365
  * server's lifetime so concurrent redeem REQUESTS for the same key serialize
3622
4366
  * (relative grant increments accumulate instead of clobbering a snapshot).
3623
4367
  */
3624
- __init18() {this.redeemMutex = new KeyedMutex()}
3625
- __init19() {this.serialQueue = new UserMessageSerialQueue()}
3626
- __init20() {this.concurrencyGate = new OutboundConcurrencyGate()}
4368
+ __init19() {this.redeemMutex = new KeyedMutex()}
4369
+ __init20() {this.serialQueue = new UserMessageSerialQueue()}
4370
+ __init21() {this.concurrencyGate = new OutboundConcurrencyGate()}
3627
4371
  /**
3628
4372
  * Apply a config. Restarts the listener ONLY when the bind address or port
3629
4373
  * changes (or when toggling enabled); per-endpoint routing config is updated
@@ -3631,6 +4375,7 @@ var OutboundApiServer = (_class11 = class {
3631
4375
  */
3632
4376
  async applyConfig(input) {
3633
4377
  this.endpoints = input.endpoints;
4378
+ this.bindings = _nullishCoalesce(input.bindings, () => ( []));
3634
4379
  this.userMessageQueue = input.userMessageQueue;
3635
4380
  this.concurrencyQueue = input.concurrencyQueue;
3636
4381
  this.voucherConfig = input.voucher;
@@ -3640,16 +4385,6 @@ var OutboundApiServer = (_class11 = class {
3640
4385
  await this.stop();
3641
4386
  return;
3642
4387
  }
3643
- const missing = _chunkVACWOIREcjs.validateServerModelConfig.call(void 0, {
3644
- enabled: true,
3645
- networkBinding: input.networkBinding,
3646
- endpoints: input.endpoints,
3647
- port: input.port
3648
- });
3649
- if (missing.length > 0) {
3650
- await this.stop();
3651
- throw new OutboundApiConfigError(missing);
3652
- }
3653
4388
  const running = this.server !== null;
3654
4389
  const bindChanged = running && (this.boundAddr !== wantAddr || this.boundPort !== wantPort);
3655
4390
  if (running && !bindChanged) {
@@ -3664,7 +4399,7 @@ var OutboundApiServer = (_class11 = class {
3664
4399
  const actualPort = await this.listen(bindAddr, port);
3665
4400
  this.boundAddr = bindAddr;
3666
4401
  this.boundPort = actualPort;
3667
- if (actualPort !== port) _optionalChain([this, 'access', _140 => _140.onPortChange, 'optionalCall', _141 => _141(actualPort)]);
4402
+ if (actualPort !== port) _optionalChain([this, 'access', _178 => _178.onPortChange, 'optionalCall', _179 => _179(actualPort)]);
3668
4403
  this.logInfo(`[OutboundApiServer] Listening on ${bindAddr}:${actualPort}`);
3669
4404
  return actualPort;
3670
4405
  }
@@ -3706,6 +4441,7 @@ var OutboundApiServer = (_class11 = class {
3706
4441
  this.deps,
3707
4442
  {
3708
4443
  endpoints: this.endpoints,
4444
+ bindings: this.bindings,
3709
4445
  userMessageQueue: this.userMessageQueue,
3710
4446
  concurrencyQueue: this.concurrencyQueue,
3711
4447
  voucher: this.voucherConfig
@@ -3732,7 +4468,7 @@ var OutboundApiServer = (_class11 = class {
3732
4468
  const provider = this.deps.healthReportProvider;
3733
4469
  if (!provider) return false;
3734
4470
  if (req.method !== "GET" && req.method !== "HEAD") return false;
3735
- const path = _optionalChain([(_nullishCoalesce(req.url, () => ( "/"))), 'access', _142 => _142.split, 'call', _143 => _143("?"), 'access', _144 => _144[0], 'optionalAccess', _145 => _145.replace, 'call', _146 => _146(/\/+$/, "")]) || "/";
4471
+ const path = _optionalChain([(_nullishCoalesce(req.url, () => ( "/"))), 'access', _180 => _180.split, 'call', _181 => _181("?"), 'access', _182 => _182[0], 'optionalAccess', _183 => _183.replace, 'call', _184 => _184(/\/+$/, "")]) || "/";
3736
4472
  if (path !== "/health" && path !== "/healthz") return false;
3737
4473
  const report = provider();
3738
4474
  res.writeHead(_healthloggingtypes.healthHttpStatus.call(void 0, report.status), { "Content-Type": "application/json" });
@@ -3844,12 +4580,12 @@ function startOfLocalWeek(ts) {
3844
4580
  return day.getTime();
3845
4581
  }
3846
4582
  var KeySpendTracker = (_class12 = class {
3847
- constructor(seeder) {;_class12.prototype.__init21.call(this);
4583
+ constructor(seeder) {;_class12.prototype.__init22.call(this);
3848
4584
  this.seeder = seeder;
3849
4585
  }
3850
4586
 
3851
4587
  /** apiKeyId → live accumulated spend (seeded lazily). */
3852
- __init21() {this.spend = /* @__PURE__ */ new Map()}
4588
+ __init22() {this.spend = /* @__PURE__ */ new Map()}
3853
4589
  /**
3854
4590
  * Read the key's accumulated spend, seeding from the durable store on a cache
3855
4591
  * miss and rolling the daily/weekly windows on a hit.
@@ -3937,7 +4673,7 @@ async function callOpenAICompletion(provider, apiKey, options, logger) {
3937
4673
  model: options.model,
3938
4674
  messages: options.messages.map((m) => convertMessageToOpenAI(m)),
3939
4675
  // Only set max_tokens if explicitly provided, otherwise let API use its default
3940
- ...options.maxTokens ? { max_tokens: options.maxTokens } : {},
4676
+ ...options.maxTokens !== void 0 ? { max_tokens: options.maxTokens } : {},
3941
4677
  temperature: options.temperature,
3942
4678
  stream: false
3943
4679
  // For now, non-streaming only
@@ -3988,7 +4724,7 @@ async function callAnthropicCompletion(provider, apiKey, options, logger) {
3988
4724
  const nonSystemMessages = options.messages.filter((m) => m.role !== "system");
3989
4725
  const anthropicRequest2 = {
3990
4726
  model: options.model,
3991
- max_tokens: options.maxTokens || 16384,
4727
+ max_tokens: _nullishCoalesce(options.maxTokens, () => ( 16384)),
3992
4728
  temperature: options.temperature,
3993
4729
  ...systemMessages.length > 0 ? { system: systemMessages.map((m) => m.content).join("\n\n") } : {},
3994
4730
  messages: nonSystemMessages.map((m) => convertMessageToAnthropic(m)),
@@ -4010,14 +4746,14 @@ async function callAnthropicCompletion(provider, apiKey, options, logger) {
4010
4746
  };
4011
4747
  }
4012
4748
  const anthropicResponse2 = await response2.json();
4013
- const openaiResponse2 = _chunkSUEGJ75Dcjs.convertAnthropicToOpenAI.call(void 0, anthropicResponse2);
4749
+ const openaiResponse2 = _chunkWYTEQ4Q5cjs.convertAnthropicToOpenAI.call(void 0, anthropicResponse2);
4014
4750
  const choice2 = openaiResponse2.choices[0];
4015
4751
  return {
4016
4752
  success: true,
4017
4753
  message: {
4018
4754
  id: `assistant-${Date.now()}`,
4019
4755
  role: "assistant",
4020
- content: _optionalChain([choice2, 'access', _147 => _147.message, 'optionalAccess', _148 => _148.content]) || "",
4756
+ content: _optionalChain([choice2, 'access', _185 => _185.message, 'optionalAccess', _186 => _186.content]) || "",
4021
4757
  timestamp: Date.now()
4022
4758
  },
4023
4759
  usage: openaiResponse2.usage ? {
@@ -4034,14 +4770,14 @@ async function callAnthropicCompletion(provider, apiKey, options, logger) {
4034
4770
  content: m.content
4035
4771
  })),
4036
4772
  // Anthropic requires max_tokens; use 16384 default if not explicitly set
4037
- max_tokens: options.maxTokens || 16384,
4773
+ max_tokens: _nullishCoalesce(options.maxTokens, () => ( 16384)),
4038
4774
  temperature: options.temperature,
4039
4775
  stream: false
4040
4776
  };
4041
4777
  const config = {
4042
4778
  defaultModel: options.model
4043
4779
  };
4044
- const anthropicRequest = _chunkSUEGJ75Dcjs.convertOpenAIToAnthropic.call(void 0, openaiRequest, config);
4780
+ const anthropicRequest = _chunkWYTEQ4Q5cjs.convertOpenAIToAnthropic.call(void 0, openaiRequest, config);
4045
4781
  const apiUrl = _chunkA2YMUCBTcjs.buildProviderApiUrl.call(void 0, provider, { model: options.model, stream: false });
4046
4782
  const headers = _chunkQ27JY5RGcjs.getProviderHeaders.call(void 0, provider, apiKey);
4047
4783
  logger.info("Calling Anthropic completion API", { url: apiUrl, model: options.model });
@@ -4058,7 +4794,7 @@ async function callAnthropicCompletion(provider, apiKey, options, logger) {
4058
4794
  };
4059
4795
  }
4060
4796
  const anthropicResponse = await response.json();
4061
- const openaiResponse = _chunkSUEGJ75Dcjs.convertAnthropicToOpenAI.call(void 0, anthropicResponse);
4797
+ const openaiResponse = _chunkWYTEQ4Q5cjs.convertAnthropicToOpenAI.call(void 0, anthropicResponse);
4062
4798
  const choice = openaiResponse.choices[0];
4063
4799
  return {
4064
4800
  success: true,
@@ -4089,7 +4825,7 @@ async function callGeminiCompletion(provider, apiKey, options, logger) {
4089
4825
  const request = {
4090
4826
  contents,
4091
4827
  generationConfig: {
4092
- ...options.maxTokens ? { maxOutputTokens: options.maxTokens } : {},
4828
+ ...options.maxTokens !== void 0 ? { maxOutputTokens: options.maxTokens } : {},
4093
4829
  ...options.temperature !== void 0 ? { temperature: options.temperature } : {}
4094
4830
  }
4095
4831
  };
@@ -4122,7 +4858,7 @@ async function callGeminiCompletion(provider, apiKey, options, logger) {
4122
4858
  const candidate = candidates[0];
4123
4859
  const content = candidate.content;
4124
4860
  let textContent = "";
4125
- if (_optionalChain([content, 'optionalAccess', _149 => _149.parts])) {
4861
+ if (_optionalChain([content, 'optionalAccess', _187 => _187.parts])) {
4126
4862
  for (const part of content.parts) {
4127
4863
  if (part.text) {
4128
4864
  textContent += part.text;
@@ -4158,7 +4894,7 @@ async function callOpenAIResponseCompletion(provider, apiKey, options, logger) {
4158
4894
  model: options.model,
4159
4895
  input,
4160
4896
  stream: false,
4161
- ...options.maxTokens ? { max_output_tokens: options.maxTokens } : {},
4897
+ ...options.maxTokens !== void 0 ? { max_output_tokens: options.maxTokens } : {},
4162
4898
  ...options.temperature !== void 0 ? { temperature: options.temperature } : {}
4163
4899
  };
4164
4900
  if (options.thinkLevel && options.thinkLevel !== "none") {
@@ -4223,7 +4959,7 @@ async function streamOpenAICompletion(provider, apiKey, options, messageId, call
4223
4959
  model: options.model,
4224
4960
  messages: options.messages.map((m) => convertMessageToOpenAI(m)),
4225
4961
  // Only set max_tokens if explicitly provided, otherwise let API use its default
4226
- ...options.maxTokens ? { max_tokens: options.maxTokens } : {},
4962
+ ...options.maxTokens !== void 0 ? { max_tokens: options.maxTokens } : {},
4227
4963
  temperature: options.temperature,
4228
4964
  stream: true
4229
4965
  };
@@ -4255,7 +4991,7 @@ async function streamOpenAICompletion(provider, apiKey, options, messageId, call
4255
4991
  });
4256
4992
  if (!response.ok) {
4257
4993
  const errorText = await response.text();
4258
- _optionalChain([callbacks, 'access', _150 => _150.onError, 'optionalCall', _151 => _151(`API error (${response.status}): ${errorText}`)]);
4994
+ _optionalChain([callbacks, 'access', _188 => _188.onError, 'optionalCall', _189 => _189(`API error (${response.status}): ${errorText}`)]);
4259
4995
  return;
4260
4996
  }
4261
4997
  const result = await _chunkHQP3K7PUcjs.streamSSEResponse.call(void 0, response, "openai", {
@@ -4265,7 +5001,7 @@ async function streamOpenAICompletion(provider, apiKey, options, messageId, call
4265
5001
  onVideo: callbacks.onVideo,
4266
5002
  onError: callbacks.onError
4267
5003
  });
4268
- _optionalChain([callbacks, 'access', _152 => _152.onDone, 'optionalCall', _153 => _153(
5004
+ _optionalChain([callbacks, 'access', _190 => _190.onDone, 'optionalCall', _191 => _191(
4269
5005
  {
4270
5006
  id: messageId,
4271
5007
  role: "assistant",
@@ -4282,7 +5018,7 @@ async function streamOpenAICompletion(provider, apiKey, options, messageId, call
4282
5018
  async function streamAnthropicCompletion(provider, apiKey, options, messageId, callbacks, logger) {
4283
5019
  const hasImages = options.messages.some((m) => m.images && m.images.length > 0);
4284
5020
  const MAX_TOKENS_FOR_THINKING = 16384;
4285
- let effectiveMaxTokens = options.maxTokens || 16384;
5021
+ let effectiveMaxTokens = _nullishCoalesce(options.maxTokens, () => ( 16384));
4286
5022
  const thinkingMaxTokens = options.thinkLevel && options.thinkLevel !== "none" ? Math.min(effectiveMaxTokens, MAX_TOKENS_FOR_THINKING) : effectiveMaxTokens;
4287
5023
  const thinkingConfig = options.thinkLevel && options.thinkLevel !== "none" ? _thinkingconfig.buildAnthropicThinking.call(void 0, options.model, options.thinkLevel, thinkingMaxTokens) : void 0;
4288
5024
  if (thinkingConfig) {
@@ -4323,7 +5059,7 @@ async function streamAnthropicCompletion(provider, apiKey, options, messageId, c
4323
5059
  temperature: thinkingConfig ? void 0 : options.temperature,
4324
5060
  stream: true
4325
5061
  };
4326
- anthropicRequest = _chunkSUEGJ75Dcjs.convertOpenAIToAnthropic.call(void 0, openaiRequest, config);
5062
+ anthropicRequest = _chunkWYTEQ4Q5cjs.convertOpenAIToAnthropic.call(void 0, openaiRequest, config);
4327
5063
  if (thinkingConfig) {
4328
5064
  anthropicRequest.thinking = thinkingConfig;
4329
5065
  delete anthropicRequest.temperature;
@@ -4337,7 +5073,7 @@ async function streamAnthropicCompletion(provider, apiKey, options, messageId, c
4337
5073
  logger.info("Streaming Anthropic completion request", {
4338
5074
  url: apiUrl,
4339
5075
  model: anthropicRequest.model,
4340
- messagesCount: _optionalChain([anthropicRequest, 'access', _154 => _154.messages, 'optionalAccess', _155 => _155.length]),
5076
+ messagesCount: _optionalChain([anthropicRequest, 'access', _192 => _192.messages, 'optionalAccess', _193 => _193.length]),
4341
5077
  max_tokens: anthropicRequest.max_tokens,
4342
5078
  temperature: anthropicRequest.temperature,
4343
5079
  stream: anthropicRequest.stream,
@@ -4354,7 +5090,7 @@ async function streamAnthropicCompletion(provider, apiKey, options, messageId, c
4354
5090
  if (!response.ok) {
4355
5091
  const errorText = await response.text();
4356
5092
  logger.error("Anthropic API error", void 0, { status: response.status, errorText });
4357
- _optionalChain([callbacks, 'access', _156 => _156.onError, 'optionalCall', _157 => _157(`API error (${response.status}): ${errorText}`)]);
5093
+ _optionalChain([callbacks, 'access', _194 => _194.onError, 'optionalCall', _195 => _195(`API error (${response.status}): ${errorText}`)]);
4358
5094
  return;
4359
5095
  }
4360
5096
  const result = await _chunkHQP3K7PUcjs.streamSSEResponse.call(void 0, response, "anthropic", {
@@ -4365,10 +5101,10 @@ async function streamAnthropicCompletion(provider, apiKey, options, messageId, c
4365
5101
  });
4366
5102
  logger.info("Anthropic stream complete", {
4367
5103
  contentLength: result.content.length,
4368
- reasoningLength: _optionalChain([result, 'access', _158 => _158.reasoning, 'optionalAccess', _159 => _159.length]) || 0,
5104
+ reasoningLength: _optionalChain([result, 'access', _196 => _196.reasoning, 'optionalAccess', _197 => _197.length]) || 0,
4369
5105
  blocksCount: result.blocks.length
4370
5106
  });
4371
- _optionalChain([callbacks, 'access', _160 => _160.onDone, 'optionalCall', _161 => _161(
5107
+ _optionalChain([callbacks, 'access', _198 => _198.onDone, 'optionalCall', _199 => _199(
4372
5108
  {
4373
5109
  id: messageId,
4374
5110
  role: "assistant",
@@ -4394,7 +5130,7 @@ async function streamGeminiCompletion(provider, apiKey, options, messageId, call
4394
5130
  const request = {
4395
5131
  contents,
4396
5132
  generationConfig: {
4397
- ...options.maxTokens ? { maxOutputTokens: options.maxTokens } : {},
5133
+ ...options.maxTokens !== void 0 ? { maxOutputTokens: options.maxTokens } : {},
4398
5134
  ...options.temperature !== void 0 ? { temperature: options.temperature } : {}
4399
5135
  }
4400
5136
  };
@@ -4424,7 +5160,7 @@ async function streamGeminiCompletion(provider, apiKey, options, messageId, call
4424
5160
  if (!response.ok) {
4425
5161
  const errorText = await response.text();
4426
5162
  logger.error("Gemini API error", void 0, { status: response.status, errorText });
4427
- _optionalChain([callbacks, 'access', _162 => _162.onError, 'optionalCall', _163 => _163(`API error (${response.status}): ${errorText}`)]);
5163
+ _optionalChain([callbacks, 'access', _200 => _200.onError, 'optionalCall', _201 => _201(`API error (${response.status}): ${errorText}`)]);
4428
5164
  return;
4429
5165
  }
4430
5166
  const result = await _chunkHQP3K7PUcjs.streamSSEResponse.call(void 0, response, "gemini", {
@@ -4433,7 +5169,7 @@ async function streamGeminiCompletion(provider, apiKey, options, messageId, call
4433
5169
  onError: callbacks.onError
4434
5170
  });
4435
5171
  logger.info("Gemini stream complete", { contentLength: result.content.length });
4436
- _optionalChain([callbacks, 'access', _164 => _164.onDone, 'optionalCall', _165 => _165(
5172
+ _optionalChain([callbacks, 'access', _202 => _202.onDone, 'optionalCall', _203 => _203(
4437
5173
  {
4438
5174
  id: messageId,
4439
5175
  role: "assistant",
@@ -4458,7 +5194,7 @@ async function streamOpenAIResponseCompletion(provider, apiKey, options, message
4458
5194
  model: options.model,
4459
5195
  input,
4460
5196
  stream: true,
4461
- ...options.maxTokens ? { max_output_tokens: options.maxTokens } : {},
5197
+ ...options.maxTokens !== void 0 ? { max_output_tokens: options.maxTokens } : {},
4462
5198
  ...options.temperature !== void 0 ? { temperature: options.temperature } : {}
4463
5199
  };
4464
5200
  if (options.thinkLevel && options.thinkLevel !== "none") {
@@ -4485,7 +5221,7 @@ async function streamOpenAIResponseCompletion(provider, apiKey, options, message
4485
5221
  });
4486
5222
  if (!response.ok) {
4487
5223
  const errorText = await response.text();
4488
- _optionalChain([callbacks, 'access', _166 => _166.onError, 'optionalCall', _167 => _167(`API error (${response.status}): ${errorText}`)]);
5224
+ _optionalChain([callbacks, 'access', _204 => _204.onError, 'optionalCall', _205 => _205(`API error (${response.status}): ${errorText}`)]);
4489
5225
  return;
4490
5226
  }
4491
5227
  const result = await _chunkHQP3K7PUcjs.streamSSEResponse.call(void 0, response, "openai-response", {
@@ -4494,7 +5230,7 @@ async function streamOpenAIResponseCompletion(provider, apiKey, options, message
4494
5230
  onError: callbacks.onError
4495
5231
  });
4496
5232
  logger.info("OpenAI Response API stream complete", { contentLength: result.content.length });
4497
- _optionalChain([callbacks, 'access', _168 => _168.onDone, 'optionalCall', _169 => _169(
5233
+ _optionalChain([callbacks, 'access', _206 => _206.onDone, 'optionalCall', _207 => _207(
4498
5234
  {
4499
5235
  id: messageId,
4500
5236
  role: "assistant",
@@ -4515,59 +5251,20 @@ async function streamOpenAIResponseCompletion(provider, apiKey, options, message
4515
5251
 
4516
5252
 
4517
5253
 
4518
- async function resolveEffectiveMaxTokens(llmConfig, getProvider, logger, providerId, modelId, sessionMaxTokens) {
5254
+ async function resolveEffectiveMaxTokens(llmConfig, _getProvider, logger, _providerId, _modelId, sessionMaxTokens) {
4519
5255
  if (sessionMaxTokens !== void 0 && sessionMaxTokens > 0) {
4520
5256
  logger.debug("Using session maxTokens", { sessionMaxTokens });
4521
5257
  return sessionMaxTokens;
4522
5258
  }
4523
5259
  try {
4524
5260
  const globalParams = await llmConfig.getGlobalModelParameters();
4525
- if (_optionalChain([globalParams, 'optionalAccess', _170 => _170.maxTokens, 'optionalAccess', _171 => _171.enabled]) && globalParams.maxTokens.value > 0) {
5261
+ if (_optionalChain([globalParams, 'optionalAccess', _208 => _208.maxTokens, 'optionalAccess', _209 => _209.enabled]) && globalParams.maxTokens.value > 0) {
4526
5262
  logger.debug("Using global maxTokens", { maxTokens: globalParams.maxTokens.value });
4527
5263
  return globalParams.maxTokens.value;
4528
5264
  }
4529
5265
  } catch (err) {
4530
5266
  logger.warn("Failed to get global params", err instanceof Error ? err : void 0);
4531
5267
  }
4532
- const MAX_TOKENS_CAP = 131072;
4533
- const provider = await getProvider(providerId);
4534
- if (provider) {
4535
- const modelConfig = _optionalChain([provider, 'access', _172 => _172.modelConfigs, 'optionalAccess', _173 => _173.find, 'call', _174 => _174((m) => m.id === modelId)]);
4536
- if (_optionalChain([modelConfig, 'optionalAccess', _175 => _175.maxTokens]) && modelConfig.maxTokens > 0) {
4537
- const cappedMaxTokens = Math.min(modelConfig.maxTokens, MAX_TOKENS_CAP);
4538
- logger.debug("Using model config maxTokens", {
4539
- maxTokens: modelConfig.maxTokens,
4540
- cappedMaxTokens
4541
- });
4542
- return cappedMaxTokens;
4543
- }
4544
- if (provider.modelGroups) {
4545
- for (const group of provider.modelGroups) {
4546
- const model = _optionalChain([group, 'access', _176 => _176.models, 'optionalAccess', _177 => _177.find, 'call', _178 => _178((m) => m.id === modelId)]);
4547
- if (_optionalChain([model, 'optionalAccess', _179 => _179.maxTokens]) && model.maxTokens > 0) {
4548
- const cappedMaxTokens = Math.min(model.maxTokens, MAX_TOKENS_CAP);
4549
- logger.debug("Using modelGroup model maxTokens", {
4550
- maxTokens: model.maxTokens,
4551
- cappedMaxTokens
4552
- });
4553
- return cappedMaxTokens;
4554
- }
4555
- }
4556
- }
4557
- }
4558
- try {
4559
- const discoveredMaxTokens = await llmConfig.getDiscoveredModelMaxTokens(providerId, modelId);
4560
- if (discoveredMaxTokens && discoveredMaxTokens > 0) {
4561
- const cappedMaxTokens = Math.min(discoveredMaxTokens, MAX_TOKENS_CAP);
4562
- logger.debug("Using discovered model maxTokens", {
4563
- discoveredMaxTokens,
4564
- cappedMaxTokens
4565
- });
4566
- return cappedMaxTokens;
4567
- }
4568
- } catch (err) {
4569
- logger.warn("Failed to get discovered model maxTokens", err instanceof Error ? err : void 0);
4570
- }
4571
5268
  logger.debug("No maxTokens configured, returning undefined");
4572
5269
  return void 0;
4573
5270
  }
@@ -4589,7 +5286,7 @@ async function resolveThinkingBudget(getProvider, logger, providerId, modelId, m
4589
5286
  }
4590
5287
  const thinkingBudget = _thinkingconfig.calculateThinkingBudget.call(void 0, modelId, thinkLevel, maxTokens);
4591
5288
  const provider = await getProvider(providerId);
4592
- const providerName = _optionalChain([provider, 'optionalAccess', _180 => _180.name, 'optionalAccess', _181 => _181.toLowerCase, 'call', _182 => _182()]) || "";
5289
+ const providerName = _optionalChain([provider, 'optionalAccess', _210 => _210.name, 'optionalAccess', _211 => _211.toLowerCase, 'call', _212 => _212()]) || "";
4593
5290
  const apiFormat = provider ? _chunkA2YMUCBTcjs.resolveApiFormat.call(void 0, provider) : "openai";
4594
5291
  if (apiFormat === "anthropic" || providerName === "anthropic" || providerName.includes("claude")) {
4595
5292
  const thinkingConfig = _thinkingconfig.buildAnthropicThinking.call(void 0, modelId, thinkLevel, maxTokens);
@@ -4626,7 +5323,7 @@ function logToolFormat(tools, logger) {
4626
5323
  tools: openaiTools.map((t) => t.function.name),
4627
5324
  firstTool: {
4628
5325
  name: firstTool.function.name,
4629
- description: _optionalChain([firstTool, 'access', _183 => _183.function, 'access', _184 => _184.description, 'optionalAccess', _185 => _185.slice, 'call', _186 => _186(0, 100)]),
5326
+ description: _optionalChain([firstTool, 'access', _213 => _213.function, 'access', _214 => _214.description, 'optionalAccess', _215 => _215.slice, 'call', _216 => _216(0, 100)]),
4630
5327
  parameters: firstTool.function.parameters
4631
5328
  }
4632
5329
  });
@@ -4637,7 +5334,7 @@ function logToolFormat(tools, logger) {
4637
5334
  tools: anthropicTools.map((t) => t.name),
4638
5335
  firstTool: {
4639
5336
  name: firstTool.name,
4640
- description: _optionalChain([firstTool, 'access', _187 => _187.description, 'optionalAccess', _188 => _188.slice, 'call', _189 => _189(0, 100)]),
5337
+ description: _optionalChain([firstTool, 'access', _217 => _217.description, 'optionalAccess', _218 => _218.slice, 'call', _219 => _219(0, 100)]),
4641
5338
  input_schema: firstTool.input_schema
4642
5339
  }
4643
5340
  });
@@ -4648,9 +5345,9 @@ function logToolFormat(tools, logger) {
4648
5345
  count: allDeclarations.length,
4649
5346
  tools: allDeclarations.map((t) => t.name),
4650
5347
  firstTool: {
4651
- name: _optionalChain([allDeclarations, 'access', _190 => _190[0], 'optionalAccess', _191 => _191.name]),
4652
- description: _optionalChain([allDeclarations, 'access', _192 => _192[0], 'optionalAccess', _193 => _193.description, 'optionalAccess', _194 => _194.slice, 'call', _195 => _195(0, 100)]),
4653
- parameters: _optionalChain([allDeclarations, 'access', _196 => _196[0], 'optionalAccess', _197 => _197.parameters])
5348
+ name: _optionalChain([allDeclarations, 'access', _220 => _220[0], 'optionalAccess', _221 => _221.name]),
5349
+ description: _optionalChain([allDeclarations, 'access', _222 => _222[0], 'optionalAccess', _223 => _223.description, 'optionalAccess', _224 => _224.slice, 'call', _225 => _225(0, 100)]),
5350
+ parameters: _optionalChain([allDeclarations, 'access', _226 => _226[0], 'optionalAccess', _227 => _227.parameters])
4654
5351
  }
4655
5352
  });
4656
5353
  }
@@ -4670,7 +5367,8 @@ function buildToolRequest(apiFormat, conversationMessages, actualModel, options,
4670
5367
  }
4671
5368
  requestBody = {
4672
5369
  contents,
4673
- tools: options.tools
5370
+ tools: options.tools,
5371
+ ...options.maxTokens !== void 0 ? { generationConfig: { maxOutputTokens: options.maxTokens } } : {}
4674
5372
  };
4675
5373
  url = _chunkA2YMUCBTcjs.buildProviderApiUrl.call(void 0, provider, { model: actualModel, stream: true });
4676
5374
  } else if (apiFormat === "anthropic") {
@@ -4680,7 +5378,10 @@ function buildToolRequest(apiFormat, conversationMessages, actualModel, options,
4680
5378
  role: m.role,
4681
5379
  content: m.content
4682
5380
  })),
4683
- max_tokens: options.maxTokens || 4096,
5381
+ // Native Anthropic Messages requires this field. Resolve an absent
5382
+ // caller cap to the model's real ceiling rather than a small constant —
5383
+ // see `resolveAnthropicMaxTokens`.
5384
+ max_tokens: _chunk4VLRHHFEcjs.resolveAnthropicMaxTokens.call(void 0, actualModel, options.maxTokens),
4684
5385
  temperature: _nullishCoalesce(options.temperature, () => ( 0.7)),
4685
5386
  stream: true,
4686
5387
  tools: options.tools
@@ -4697,7 +5398,7 @@ function buildToolRequest(apiFormat, conversationMessages, actualModel, options,
4697
5398
  role: m.role,
4698
5399
  content: m.content
4699
5400
  })),
4700
- max_tokens: options.maxTokens || 4096,
5401
+ ...options.maxTokens !== void 0 ? { max_tokens: options.maxTokens } : {},
4701
5402
  temperature: _nullishCoalesce(options.temperature, () => ( 0.7)),
4702
5403
  stream: true,
4703
5404
  tools: options.tools
@@ -4709,7 +5410,7 @@ function buildToolRequest(apiFormat, conversationMessages, actualModel, options,
4709
5410
  function extractDeltaContent(rawJson, apiFormat) {
4710
5411
  const json = rawJson;
4711
5412
  if (apiFormat === "google") {
4712
- const parts = _optionalChain([json, 'access', _198 => _198.candidates, 'optionalAccess', _199 => _199[0], 'optionalAccess', _200 => _200.content, 'optionalAccess', _201 => _201.parts]) || [];
5413
+ const parts = _optionalChain([json, 'access', _228 => _228.candidates, 'optionalAccess', _229 => _229[0], 'optionalAccess', _230 => _230.content, 'optionalAccess', _231 => _231.parts]) || [];
4713
5414
  let text = "";
4714
5415
  for (const part of parts) {
4715
5416
  if (part.thought === true) continue;
@@ -4717,15 +5418,15 @@ function extractDeltaContent(rawJson, apiFormat) {
4717
5418
  }
4718
5419
  return text;
4719
5420
  } else if (apiFormat === "anthropic") {
4720
- return _optionalChain([json, 'access', _202 => _202.delta, 'optionalAccess', _203 => _203.text]) || "";
5421
+ return _optionalChain([json, 'access', _232 => _232.delta, 'optionalAccess', _233 => _233.text]) || "";
4721
5422
  } else {
4722
- return _optionalChain([json, 'access', _204 => _204.choices, 'optionalAccess', _205 => _205[0], 'optionalAccess', _206 => _206.delta, 'optionalAccess', _207 => _207.content]) || "";
5423
+ return _optionalChain([json, 'access', _234 => _234.choices, 'optionalAccess', _235 => _235[0], 'optionalAccess', _236 => _236.delta, 'optionalAccess', _237 => _237.content]) || "";
4723
5424
  }
4724
5425
  }
4725
5426
  function extractDeltaReasoning(rawJson, apiFormat) {
4726
5427
  const json = rawJson;
4727
5428
  if (apiFormat === "google") {
4728
- const parts = _optionalChain([json, 'access', _208 => _208.candidates, 'optionalAccess', _209 => _209[0], 'optionalAccess', _210 => _210.content, 'optionalAccess', _211 => _211.parts]) || [];
5429
+ const parts = _optionalChain([json, 'access', _238 => _238.candidates, 'optionalAccess', _239 => _239[0], 'optionalAccess', _240 => _240.content, 'optionalAccess', _241 => _241.parts]) || [];
4729
5430
  let reasoning = "";
4730
5431
  for (const part of parts) {
4731
5432
  if (part.thought === true && part.text) reasoning += part.text;
@@ -4734,14 +5435,14 @@ function extractDeltaReasoning(rawJson, apiFormat) {
4734
5435
  } else if (apiFormat === "anthropic") {
4735
5436
  return "";
4736
5437
  } else {
4737
- const delta = _optionalChain([json, 'access', _212 => _212.choices, 'optionalAccess', _213 => _213[0], 'optionalAccess', _214 => _214.delta]);
4738
- return (_optionalChain([delta, 'optionalAccess', _215 => _215.thinking, 'optionalAccess', _216 => _216.content]) || "") + (_optionalChain([delta, 'optionalAccess', _217 => _217.reasoning_content]) || "");
5438
+ const delta = _optionalChain([json, 'access', _242 => _242.choices, 'optionalAccess', _243 => _243[0], 'optionalAccess', _244 => _244.delta]);
5439
+ return (_optionalChain([delta, 'optionalAccess', _245 => _245.thinking, 'optionalAccess', _246 => _246.content]) || "") + (_optionalChain([delta, 'optionalAccess', _247 => _247.reasoning_content]) || "");
4739
5440
  }
4740
5441
  }
4741
5442
  function extractToolCalls(rawJson, apiFormat, toolCalls, callbacks, logger, pendingOpenAIToolCalls) {
4742
5443
  const json = rawJson;
4743
5444
  if (apiFormat === "google") {
4744
- const parts = _optionalChain([json, 'access', _218 => _218.candidates, 'optionalAccess', _219 => _219[0], 'optionalAccess', _220 => _220.content, 'optionalAccess', _221 => _221.parts]) || [];
5445
+ const parts = _optionalChain([json, 'access', _248 => _248.candidates, 'optionalAccess', _249 => _249[0], 'optionalAccess', _250 => _250.content, 'optionalAccess', _251 => _251.parts]) || [];
4745
5446
  for (const part of parts) {
4746
5447
  if (part.functionCall) {
4747
5448
  logger.info("Function call detected", { functionCall: part.functionCall });
@@ -4751,13 +5452,13 @@ function extractToolCalls(rawJson, apiFormat, toolCalls, callbacks, logger, pend
4751
5452
  args: part.functionCall.args || {}
4752
5453
  };
4753
5454
  toolCalls.push(toolCall);
4754
- _optionalChain([callbacks, 'access', _222 => _222.onToolCall, 'optionalCall', _223 => _223(toolCall)]);
5455
+ _optionalChain([callbacks, 'access', _252 => _252.onToolCall, 'optionalCall', _253 => _253(toolCall)]);
4755
5456
  logger.info("Tool called", { toolName: toolCall.name });
4756
5457
  }
4757
5458
  }
4758
5459
  } else if (apiFormat !== "anthropic") {
4759
- const delta = _optionalChain([json, 'access', _224 => _224.choices, 'optionalAccess', _225 => _225[0], 'optionalAccess', _226 => _226.delta]);
4760
- if (_optionalChain([delta, 'optionalAccess', _227 => _227.tool_calls]) && pendingOpenAIToolCalls) {
5460
+ const delta = _optionalChain([json, 'access', _254 => _254.choices, 'optionalAccess', _255 => _255[0], 'optionalAccess', _256 => _256.delta]);
5461
+ if (_optionalChain([delta, 'optionalAccess', _257 => _257.tool_calls]) && pendingOpenAIToolCalls) {
4761
5462
  for (const tc of delta.tool_calls) {
4762
5463
  const index = _nullishCoalesce(tc.index, () => ( 0));
4763
5464
  let pending = pendingOpenAIToolCalls.get(index);
@@ -4766,8 +5467,8 @@ function extractToolCalls(rawJson, apiFormat, toolCalls, callbacks, logger, pend
4766
5467
  pendingOpenAIToolCalls.set(index, pending);
4767
5468
  }
4768
5469
  if (tc.id) pending.id = tc.id;
4769
- if (_optionalChain([tc, 'access', _228 => _228.function, 'optionalAccess', _229 => _229.name])) pending.name += tc.function.name;
4770
- if (_optionalChain([tc, 'access', _230 => _230.function, 'optionalAccess', _231 => _231.arguments])) pending.arguments += tc.function.arguments;
5470
+ if (_optionalChain([tc, 'access', _258 => _258.function, 'optionalAccess', _259 => _259.name])) pending.name += tc.function.name;
5471
+ if (_optionalChain([tc, 'access', _260 => _260.function, 'optionalAccess', _261 => _261.arguments])) pending.arguments += tc.function.arguments;
4771
5472
  }
4772
5473
  }
4773
5474
  }
@@ -4782,7 +5483,7 @@ function finalizeOpenAIToolCalls(pendingOpenAIToolCalls, toolCalls, callbacks, l
4782
5483
  args: JSON.parse(pending.arguments || "{}")
4783
5484
  };
4784
5485
  toolCalls.push(toolCall);
4785
- _optionalChain([callbacks, 'access', _232 => _232.onToolCall, 'optionalCall', _233 => _233(toolCall)]);
5486
+ _optionalChain([callbacks, 'access', _262 => _262.onToolCall, 'optionalCall', _263 => _263(toolCall)]);
4786
5487
  logger.info("Tool called (OpenAI)", { toolName: toolCall.name, args: toolCall.args });
4787
5488
  } catch (e) {
4788
5489
  logger.error("Failed to parse OpenAI tool call arguments", e instanceof Error ? e : void 0, {
@@ -4796,38 +5497,38 @@ function finalizeOpenAIToolCalls(pendingOpenAIToolCalls, toolCalls, callbacks, l
4796
5497
  function parseStreamChunk(rawJson, apiFormat, callbacks, logger) {
4797
5498
  const json = rawJson;
4798
5499
  if (apiFormat === "google") {
4799
- const candidate = _optionalChain([json, 'access', _234 => _234.candidates, 'optionalAccess', _235 => _235[0]]);
5500
+ const candidate = _optionalChain([json, 'access', _264 => _264.candidates, 'optionalAccess', _265 => _265[0]]);
4800
5501
  if (!candidate) {
4801
5502
  logger.warn("No candidate found in Gemini response");
4802
5503
  return;
4803
5504
  }
4804
- const parts = _optionalChain([candidate, 'access', _236 => _236.content, 'optionalAccess', _237 => _237.parts]) || [];
5505
+ const parts = _optionalChain([candidate, 'access', _266 => _266.content, 'optionalAccess', _267 => _267.parts]) || [];
4805
5506
  for (const part of parts) {
4806
5507
  if (part.thought === true && part.text) {
4807
- _optionalChain([callbacks, 'access', _238 => _238.onReasoning, 'optionalCall', _239 => _239(part.text)]);
5508
+ _optionalChain([callbacks, 'access', _268 => _268.onReasoning, 'optionalCall', _269 => _269(part.text)]);
4808
5509
  continue;
4809
5510
  } else if (part.thoughtSignature && !part.thought) {
4810
5511
  logger.debug("Gemini returned thoughtSignature without thought content");
4811
5512
  }
4812
5513
  if (part.text) {
4813
- _optionalChain([callbacks, 'access', _240 => _240.onDelta, 'optionalCall', _241 => _241(part.text)]);
5514
+ _optionalChain([callbacks, 'access', _270 => _270.onDelta, 'optionalCall', _271 => _271(part.text)]);
4814
5515
  }
4815
5516
  }
4816
5517
  } else if (apiFormat === "anthropic") {
4817
5518
  const delta = json.delta;
4818
- if (_optionalChain([delta, 'optionalAccess', _242 => _242.text])) {
4819
- _optionalChain([callbacks, 'access', _243 => _243.onDelta, 'optionalCall', _244 => _244(delta.text)]);
5519
+ if (_optionalChain([delta, 'optionalAccess', _272 => _272.text])) {
5520
+ _optionalChain([callbacks, 'access', _273 => _273.onDelta, 'optionalCall', _274 => _274(delta.text)]);
4820
5521
  }
4821
5522
  } else {
4822
- const delta = _optionalChain([json, 'access', _245 => _245.choices, 'optionalAccess', _246 => _246[0], 'optionalAccess', _247 => _247.delta]);
4823
- if (_optionalChain([delta, 'optionalAccess', _248 => _248.content])) {
4824
- _optionalChain([callbacks, 'access', _249 => _249.onDelta, 'optionalCall', _250 => _250(delta.content)]);
5523
+ const delta = _optionalChain([json, 'access', _275 => _275.choices, 'optionalAccess', _276 => _276[0], 'optionalAccess', _277 => _277.delta]);
5524
+ if (_optionalChain([delta, 'optionalAccess', _278 => _278.content])) {
5525
+ _optionalChain([callbacks, 'access', _279 => _279.onDelta, 'optionalCall', _280 => _280(delta.content)]);
4825
5526
  }
4826
- if (_optionalChain([delta, 'optionalAccess', _251 => _251.thinking, 'optionalAccess', _252 => _252.content])) {
4827
- _optionalChain([callbacks, 'access', _253 => _253.onReasoning, 'optionalCall', _254 => _254(delta.thinking.content)]);
5527
+ if (_optionalChain([delta, 'optionalAccess', _281 => _281.thinking, 'optionalAccess', _282 => _282.content])) {
5528
+ _optionalChain([callbacks, 'access', _283 => _283.onReasoning, 'optionalCall', _284 => _284(delta.thinking.content)]);
4828
5529
  }
4829
- if (_optionalChain([delta, 'optionalAccess', _255 => _255.reasoning_content])) {
4830
- _optionalChain([callbacks, 'access', _256 => _256.onReasoning, 'optionalCall', _257 => _257(delta.reasoning_content)]);
5530
+ if (_optionalChain([delta, 'optionalAccess', _285 => _285.reasoning_content])) {
5531
+ _optionalChain([callbacks, 'access', _286 => _286.onReasoning, 'optionalCall', _287 => _287(delta.reasoning_content)]);
4831
5532
  }
4832
5533
  }
4833
5534
  }
@@ -4840,7 +5541,7 @@ function buildIterationBlocks(iteration, content, reasoning, blocks, callbacks)
4840
5541
  content: reasoning
4841
5542
  };
4842
5543
  blocks.push(thinkingBlock);
4843
- _optionalChain([callbacks, 'access', _258 => _258.onBlock, 'optionalCall', _259 => _259(thinkingBlock)]);
5544
+ _optionalChain([callbacks, 'access', _288 => _288.onBlock, 'optionalCall', _289 => _289(thinkingBlock)]);
4844
5545
  }
4845
5546
  if (content && content.trim()) {
4846
5547
  const textBlock = {
@@ -4849,7 +5550,7 @@ function buildIterationBlocks(iteration, content, reasoning, blocks, callbacks)
4849
5550
  content
4850
5551
  };
4851
5552
  blocks.push(textBlock);
4852
- _optionalChain([callbacks, 'access', _260 => _260.onBlock, 'optionalCall', _261 => _261(textBlock)]);
5553
+ _optionalChain([callbacks, 'access', _290 => _290.onBlock, 'optionalCall', _291 => _291(textBlock)]);
4853
5554
  }
4854
5555
  }
4855
5556
  async function executeToolCalls(toolCalls, mcpTools, mcpService, blocks, callbacks, logger, builtinExecutor) {
@@ -4864,7 +5565,7 @@ async function executeToolCalls(toolCalls, mcpTools, mcpService, blocks, callbac
4864
5565
  status: "running"
4865
5566
  };
4866
5567
  blocks.push(toolUseBlock);
4867
- _optionalChain([callbacks, 'access', _262 => _262.onBlock, 'optionalCall', _263 => _263(toolUseBlock)]);
5568
+ _optionalChain([callbacks, 'access', _292 => _292.onBlock, 'optionalCall', _293 => _293(toolUseBlock)]);
4868
5569
  try {
4869
5570
  logger.info("Executing tool", { toolName: toolCall.name });
4870
5571
  const mcpTool = mcpTools.find((t) => t.id === toolCall.name);
@@ -4887,8 +5588,8 @@ async function executeToolCalls(toolCalls, mcpTools, mcpService, blocks, callbac
4887
5588
  result = { isError: true, content: [{ type: "text", text: "MCP service not available" }] };
4888
5589
  }
4889
5590
  logger.info("Tool result received", { result });
4890
- _optionalChain([callbacks, 'access', _264 => _264.onToolResult, 'optionalCall', _265 => _265(toolCall.id, result)]);
4891
- const resultText = _optionalChain([result, 'access', _266 => _266.content, 'optionalAccess', _267 => _267[0], 'optionalAccess', _268 => _268.text]) || JSON.stringify(result);
5591
+ _optionalChain([callbacks, 'access', _294 => _294.onToolResult, 'optionalCall', _295 => _295(toolCall.id, result)]);
5592
+ const resultText = _optionalChain([result, 'access', _296 => _296.content, 'optionalAccess', _297 => _297[0], 'optionalAccess', _298 => _298.text]) || JSON.stringify(result);
4892
5593
  const toolResultBlock = {
4893
5594
  id: `${toolCall.id}_result`,
4894
5595
  type: "tool_result",
@@ -4898,11 +5599,11 @@ async function executeToolCalls(toolCalls, mcpTools, mcpService, blocks, callbac
4898
5599
  isError: result.isError
4899
5600
  };
4900
5601
  blocks.push(toolResultBlock);
4901
- _optionalChain([callbacks, 'access', _269 => _269.onBlock, 'optionalCall', _270 => _270(toolResultBlock)]);
5602
+ _optionalChain([callbacks, 'access', _299 => _299.onBlock, 'optionalCall', _300 => _300(toolResultBlock)]);
4902
5603
  const toolUseBlockRef = blocks.find((b) => b.id === `${toolCall.id}_use`);
4903
5604
  if (toolUseBlockRef && toolUseBlockRef.type === "tool_use") {
4904
5605
  toolUseBlockRef.status = result.isError ? "error" : "completed";
4905
- _optionalChain([callbacks, 'access', _271 => _271.onBlock, 'optionalCall', _272 => _272({ ...toolUseBlockRef })]);
5606
+ _optionalChain([callbacks, 'access', _301 => _301.onBlock, 'optionalCall', _302 => _302({ ...toolUseBlockRef })]);
4906
5607
  }
4907
5608
  toolResults.push({ toolCall, result });
4908
5609
  } catch (error) {
@@ -4912,7 +5613,7 @@ async function executeToolCalls(toolCalls, mcpTools, mcpService, blocks, callbac
4912
5613
  isError: true,
4913
5614
  content: [{ type: "text", text: `Error: ${errorMessage}` }]
4914
5615
  };
4915
- _optionalChain([callbacks, 'access', _273 => _273.onToolResult, 'optionalCall', _274 => _274(toolCall.id, errorResult)]);
5616
+ _optionalChain([callbacks, 'access', _303 => _303.onToolResult, 'optionalCall', _304 => _304(toolCall.id, errorResult)]);
4916
5617
  const errorToolResultBlock = {
4917
5618
  id: `${toolCall.id}_result`,
4918
5619
  type: "tool_result",
@@ -4922,11 +5623,11 @@ async function executeToolCalls(toolCalls, mcpTools, mcpService, blocks, callbac
4922
5623
  isError: true
4923
5624
  };
4924
5625
  blocks.push(errorToolResultBlock);
4925
- _optionalChain([callbacks, 'access', _275 => _275.onBlock, 'optionalCall', _276 => _276(errorToolResultBlock)]);
5626
+ _optionalChain([callbacks, 'access', _305 => _305.onBlock, 'optionalCall', _306 => _306(errorToolResultBlock)]);
4926
5627
  const errorToolUseBlockRef = blocks.find((b) => b.id === `${toolCall.id}_use`);
4927
5628
  if (errorToolUseBlockRef && errorToolUseBlockRef.type === "tool_use") {
4928
5629
  errorToolUseBlockRef.status = "error";
4929
- _optionalChain([callbacks, 'access', _277 => _277.onBlock, 'optionalCall', _278 => _278({ ...errorToolUseBlockRef })]);
5630
+ _optionalChain([callbacks, 'access', _307 => _307.onBlock, 'optionalCall', _308 => _308({ ...errorToolUseBlockRef })]);
4930
5631
  }
4931
5632
  toolResults.push({ toolCall, result: errorResult });
4932
5633
  }
@@ -4936,7 +5637,7 @@ async function executeToolCalls(toolCalls, mcpTools, mcpService, blocks, callbac
4936
5637
  function mapToolArguments(args, mcpTool, logger) {
4937
5638
  const mappedArgs = { ...args };
4938
5639
  const toolSchema = mcpTool.inputSchema;
4939
- if (_optionalChain([toolSchema, 'optionalAccess', _279 => _279.properties])) {
5640
+ if (_optionalChain([toolSchema, 'optionalAccess', _309 => _309.properties])) {
4940
5641
  const expectedParams = Object.keys(toolSchema.properties);
4941
5642
  const paramMappings = {
4942
5643
  "search_query": ["query", "q", "searchQuery", "search"],
@@ -4970,25 +5671,25 @@ async function streamWithTools(options, callbacks, mcpService, llmConfig, getPro
4970
5671
  options.providerId,
4971
5672
  options.model
4972
5673
  );
4973
- const actualProviderId = _optionalChain([routedInfo, 'optionalAccess', _280 => _280.actualProviderId]) || options.providerId;
4974
- const actualModel = _optionalChain([routedInfo, 'optionalAccess', _281 => _281.actualModelId]) || options.model;
5674
+ const actualProviderId = _optionalChain([routedInfo, 'optionalAccess', _310 => _310.actualProviderId]) || options.providerId;
5675
+ const actualModel = _optionalChain([routedInfo, 'optionalAccess', _311 => _311.actualModelId]) || options.model;
4975
5676
  const provider = await getProvider(actualProviderId);
4976
5677
  if (!provider) {
4977
- _optionalChain([callbacks, 'access', _282 => _282.onError, 'optionalCall', _283 => _283(`Provider not found: ${actualProviderId}`)]);
5678
+ _optionalChain([callbacks, 'access', _312 => _312.onError, 'optionalCall', _313 => _313(`Provider not found: ${actualProviderId}`)]);
4978
5679
  return;
4979
5680
  }
4980
5681
  if (!provider.enabled) {
4981
- _optionalChain([callbacks, 'access', _284 => _284.onError, 'optionalCall', _285 => _285(`Provider is disabled: ${provider.name}`)]);
5682
+ _optionalChain([callbacks, 'access', _314 => _314.onError, 'optionalCall', _315 => _315(`Provider is disabled: ${provider.name}`)]);
4982
5683
  return;
4983
5684
  }
4984
5685
  const { apiKey: effectiveKey } = _chunkA2YMUCBTcjs.resolveProviderEndpoint.call(void 0, provider);
4985
5686
  const apiKey = resolveApiKey2(effectiveKey);
4986
5687
  if (!apiKey) {
4987
- _optionalChain([callbacks, 'access', _286 => _286.onError, 'optionalCall', _287 => _287("API key not configured")]);
5688
+ _optionalChain([callbacks, 'access', _316 => _316.onError, 'optionalCall', _317 => _317("API key not configured")]);
4988
5689
  return;
4989
5690
  }
4990
5691
  const messageId = `msg_${Date.now()}_${Math.random().toString(36).slice(2)}`;
4991
- _optionalChain([callbacks, 'access', _288 => _288.onStart, 'optionalCall', _289 => _289(messageId)]);
5692
+ _optionalChain([callbacks, 'access', _318 => _318.onStart, 'optionalCall', _319 => _319(messageId)]);
4992
5693
  const globalParams = await llmConfig.getGlobalModelParameters();
4993
5694
  const MAX_ITERATIONS = _nullishCoalesce(globalParams.toolMaxTurns, () => ( 100));
4994
5695
  let iteration = 0;
@@ -5035,12 +5736,12 @@ async function streamWithTools(options, callbacks, mcpService, llmConfig, getPro
5035
5736
  });
5036
5737
  if (!response.ok) {
5037
5738
  const errorText = await response.text();
5038
- _optionalChain([callbacks, 'access', _290 => _290.onError, 'optionalCall', _291 => _291(`API error (${response.status}): ${errorText}`)]);
5739
+ _optionalChain([callbacks, 'access', _320 => _320.onError, 'optionalCall', _321 => _321(`API error (${response.status}): ${errorText}`)]);
5039
5740
  return;
5040
5741
  }
5041
- const reader = _optionalChain([response, 'access', _292 => _292.body, 'optionalAccess', _293 => _293.getReader, 'call', _294 => _294()]);
5742
+ const reader = _optionalChain([response, 'access', _322 => _322.body, 'optionalAccess', _323 => _323.getReader, 'call', _324 => _324()]);
5042
5743
  if (!reader) {
5043
- _optionalChain([callbacks, 'access', _295 => _295.onError, 'optionalCall', _296 => _296("No response body")]);
5744
+ _optionalChain([callbacks, 'access', _325 => _325.onError, 'optionalCall', _326 => _326("No response body")]);
5044
5745
  return;
5045
5746
  }
5046
5747
  const decoder = new TextDecoder();
@@ -5073,7 +5774,7 @@ async function streamWithTools(options, callbacks, mcpService, llmConfig, getPro
5073
5774
  logger.debug("Parsed JSON", { json });
5074
5775
  if (json.error) {
5075
5776
  logger.error("API Error", void 0, { error: json.error });
5076
- _optionalChain([callbacks, 'access', _297 => _297.onError, 'optionalCall', _298 => _298(`API Error: ${json.error.message || JSON.stringify(json.error)}`)]);
5777
+ _optionalChain([callbacks, 'access', _327 => _327.onError, 'optionalCall', _328 => _328(`API Error: ${json.error.message || JSON.stringify(json.error)}`)]);
5077
5778
  return;
5078
5779
  }
5079
5780
  parseStreamChunk(json, apiFormat, callbacks, logger);
@@ -5106,7 +5807,7 @@ async function streamWithTools(options, callbacks, mcpService, llmConfig, getPro
5106
5807
  toolCallsLength: toolCalls.length,
5107
5808
  executableToolCallsLength: executableToolCalls.length,
5108
5809
  hasMcpTools: !!options.mcpTools,
5109
- mcpToolsLength: _optionalChain([options, 'access', _299 => _299.mcpTools, 'optionalAccess', _300 => _300.length]),
5810
+ mcpToolsLength: _optionalChain([options, 'access', _329 => _329.mcpTools, 'optionalAccess', _330 => _330.length]),
5110
5811
  hasMcpService: !!mcpService
5111
5812
  });
5112
5813
  if (executableToolCalls.length > 0 && options.mcpTools && (mcpService || builtinExecutor)) {
@@ -5127,7 +5828,7 @@ async function streamWithTools(options, callbacks, mcpService, llmConfig, getPro
5127
5828
  builtinExecutor
5128
5829
  );
5129
5830
  const toolResultsText = toolResults.map(({ toolCall, result }) => {
5130
- const resultText = typeof result === "string" ? result : _optionalChain([result, 'access', _301 => _301.content, 'optionalAccess', _302 => _302[0], 'optionalAccess', _303 => _303.text]) || JSON.stringify(result);
5831
+ const resultText = typeof result === "string" ? result : _optionalChain([result, 'access', _331 => _331.content, 'optionalAccess', _332 => _332[0], 'optionalAccess', _333 => _333.text]) || JSON.stringify(result);
5131
5832
  return `Tool ${toolCall.name} result:
5132
5833
  ${resultText}`;
5133
5834
  }).join("\n\n");
@@ -5145,12 +5846,12 @@ ${resultText}`;
5145
5846
  }
5146
5847
  } catch (streamError) {
5147
5848
  logger.error("Stream processing error", streamError instanceof Error ? streamError : void 0);
5148
- _optionalChain([callbacks, 'access', _304 => _304.onError, 'optionalCall', _305 => _305(`Stream error: ${streamError instanceof Error ? streamError.message : "Unknown error"}`)]);
5849
+ _optionalChain([callbacks, 'access', _334 => _334.onError, 'optionalCall', _335 => _335(`Stream error: ${streamError instanceof Error ? streamError.message : "Unknown error"}`)]);
5149
5850
  return;
5150
5851
  }
5151
5852
  }
5152
5853
  logger.info("Sending final callback", { blocksCount: blocks.length });
5153
- _optionalChain([callbacks, 'access', _306 => _306.onDone, 'optionalCall', _307 => _307({
5854
+ _optionalChain([callbacks, 'access', _336 => _336.onDone, 'optionalCall', _337 => _337({
5154
5855
  id: messageId,
5155
5856
  role: "assistant",
5156
5857
  content: finalContent,
@@ -5161,7 +5862,7 @@ ${resultText}`;
5161
5862
  } catch (error) {
5162
5863
  logger.error("Error in streamWithTools", error instanceof Error ? error : void 0);
5163
5864
  const message = error instanceof Error ? error.message : "Unknown error";
5164
- _optionalChain([callbacks, 'access', _308 => _308.onError, 'optionalCall', _309 => _309(message)]);
5865
+ _optionalChain([callbacks, 'access', _338 => _338.onError, 'optionalCall', _339 => _339(message)]);
5165
5866
  }
5166
5867
  }
5167
5868
 
@@ -5187,21 +5888,33 @@ function readUsageFromOpenAIResponse(usage) {
5187
5888
  var sharedExecutor2 = null;
5188
5889
  function getSharedExecutor2() {
5189
5890
  if (!sharedExecutor2) {
5190
- sharedExecutor2 = new (0, _chunk46ZIFWYGcjs.TransformerChainExecutor)();
5891
+ sharedExecutor2 = new (0, _chunkIIRPUVPHcjs.TransformerChainExecutor)();
5191
5892
  }
5192
5893
  return sharedExecutor2;
5193
5894
  }
5194
5895
  async function resolveChainWithMain(llmConfig, providerId, model) {
5195
5896
  return _chunkQXD4MV2Xcjs.resolveProviderChain.call(void 0, llmConfig, providerId, model);
5196
5897
  }
5898
+ function buildUnifiedCompletionRequest(actualModel, options, stream) {
5899
+ return {
5900
+ model: actualModel,
5901
+ messages: options.messages.map((m) => ({
5902
+ role: m.role,
5903
+ content: m.content
5904
+ })),
5905
+ ...options.maxTokens !== void 0 ? { max_tokens: options.maxTokens } : {},
5906
+ temperature: options.temperature,
5907
+ stream
5908
+ };
5909
+ }
5197
5910
  async function completeWithTransformers(options, llmConfig, getProvider, resolveApiKey2, completeFallback, logger, recording) {
5198
5911
  try {
5199
5912
  const routedInfo = await llmConfig.resolveRoutedModel(
5200
5913
  options.providerId,
5201
5914
  options.model
5202
5915
  );
5203
- const actualProviderId = _optionalChain([routedInfo, 'optionalAccess', _310 => _310.actualProviderId]) || options.providerId;
5204
- const actualModel = _optionalChain([routedInfo, 'optionalAccess', _311 => _311.actualModelId]) || options.model;
5916
+ const actualProviderId = _optionalChain([routedInfo, 'optionalAccess', _340 => _340.actualProviderId]) || options.providerId;
5917
+ const actualModel = _optionalChain([routedInfo, 'optionalAccess', _341 => _341.actualModelId]) || options.model;
5205
5918
  const provider = await getProvider(actualProviderId);
5206
5919
  if (!provider) {
5207
5920
  return { success: false, error: `Provider not found: ${actualProviderId}` };
@@ -5222,16 +5935,11 @@ async function completeWithTransformers(options, llmConfig, getProvider, resolve
5222
5935
  if (!hasTransformers) {
5223
5936
  return completeFallback(options);
5224
5937
  }
5225
- const unifiedRequest = {
5226
- model: actualModel,
5227
- messages: options.messages.map((m) => ({
5228
- role: m.role,
5229
- content: m.content
5230
- })),
5231
- max_tokens: options.maxTokens || 4096,
5232
- temperature: options.temperature,
5233
- stream: _nullishCoalesce(options.stream, () => ( false))
5234
- };
5938
+ const unifiedRequest = buildUnifiedCompletionRequest(
5939
+ actualModel,
5940
+ options,
5941
+ _nullishCoalesce(options.stream, () => ( false))
5942
+ );
5235
5943
  const transformerProvider = {
5236
5944
  name: provider.name,
5237
5945
  baseUrl: provider.api_base_url,
@@ -5239,7 +5947,7 @@ async function completeWithTransformers(options, llmConfig, getProvider, resolve
5239
5947
  models: provider.models || []
5240
5948
  };
5241
5949
  const executor = getSharedExecutor2();
5242
- const { response } = await _chunkHYN75H6Gcjs.executeProviderCall.call(void 0, {
5950
+ const { response } = await _chunkMUHWHQVMcjs.executeProviderCall.call(void 0, {
5243
5951
  executor,
5244
5952
  request: unifiedRequest,
5245
5953
  provider: transformerProvider,
@@ -5282,18 +5990,18 @@ async function completeWithTransformers(options, llmConfig, getProvider, resolve
5282
5990
  { endpointTransformer: void 0 }
5283
5991
  );
5284
5992
  const data = await transformedResponse.json();
5285
- const choice = _optionalChain([data, 'access', _312 => _312.choices, 'optionalAccess', _313 => _313[0]]);
5993
+ const choice = _optionalChain([data, 'access', _342 => _342.choices, 'optionalAccess', _343 => _343[0]]);
5286
5994
  if (!choice) {
5287
5995
  return { success: false, error: "No choices in response" };
5288
5996
  }
5289
- const rawToolCalls = _optionalChain([choice, 'access', _314 => _314.message, 'optionalAccess', _315 => _315.tool_calls]);
5290
- const toolCalls = _optionalChain([rawToolCalls, 'optionalAccess', _316 => _316.map, 'call', _317 => _317((tc) => ({
5997
+ const rawToolCalls = _optionalChain([choice, 'access', _344 => _344.message, 'optionalAccess', _345 => _345.tool_calls]);
5998
+ const toolCalls = _optionalChain([rawToolCalls, 'optionalAccess', _346 => _346.map, 'call', _347 => _347((tc) => ({
5291
5999
  id: tc.id,
5292
6000
  name: tc.function.name,
5293
6001
  args: typeof tc.function.arguments === "string" ? JSON.parse(tc.function.arguments) : tc.function.arguments
5294
6002
  }))]);
5295
6003
  const tapped = readUsageFromOpenAIResponse(data.usage);
5296
- if (_optionalChain([recording, 'optionalAccess', _318 => _318.recorder]) && tapped) {
6004
+ if (_optionalChain([recording, 'optionalAccess', _348 => _348.recorder]) && tapped) {
5297
6005
  recording.recorder.record({
5298
6006
  messageId: _nullishCoalesce(options.messageId, () => ( null)),
5299
6007
  parentMessageId: _nullishCoalesce(options.parentMessageId, () => ( null)),
@@ -5311,9 +6019,9 @@ async function completeWithTransformers(options, llmConfig, getProvider, resolve
5311
6019
  message: {
5312
6020
  id: `msg_${Date.now()}`,
5313
6021
  role: "assistant",
5314
- content: _optionalChain([choice, 'access', _319 => _319.message, 'optionalAccess', _320 => _320.content]) || "",
6022
+ content: _optionalChain([choice, 'access', _349 => _349.message, 'optionalAccess', _350 => _350.content]) || "",
5315
6023
  timestamp: Date.now(),
5316
- thinking: data.reasoning_content || _optionalChain([choice, 'access', _321 => _321.message, 'optionalAccess', _322 => _322.thinking, 'optionalAccess', _323 => _323.content]) ? { content: data.reasoning_content || _optionalChain([choice, 'access', _324 => _324.message, 'optionalAccess', _325 => _325.thinking, 'optionalAccess', _326 => _326.content]) || "", signature: _optionalChain([choice, 'access', _327 => _327.message, 'optionalAccess', _328 => _328.thinking, 'optionalAccess', _329 => _329.signature]) } : void 0,
6024
+ thinking: data.reasoning_content || _optionalChain([choice, 'access', _351 => _351.message, 'optionalAccess', _352 => _352.thinking, 'optionalAccess', _353 => _353.content]) ? { content: data.reasoning_content || _optionalChain([choice, 'access', _354 => _354.message, 'optionalAccess', _355 => _355.thinking, 'optionalAccess', _356 => _356.content]) || "", signature: _optionalChain([choice, 'access', _357 => _357.message, 'optionalAccess', _358 => _358.thinking, 'optionalAccess', _359 => _359.signature]) } : void 0,
5317
6025
  toolCalls
5318
6026
  },
5319
6027
  usage: data.usage ? {
@@ -5334,21 +6042,21 @@ async function completeStreamWithTransformers(options, callbacks, llmConfig, get
5334
6042
  options.providerId,
5335
6043
  options.model
5336
6044
  );
5337
- const actualProviderId = _optionalChain([routedInfo, 'optionalAccess', _330 => _330.actualProviderId]) || options.providerId;
5338
- const actualModel = _optionalChain([routedInfo, 'optionalAccess', _331 => _331.actualModelId]) || options.model;
6045
+ const actualProviderId = _optionalChain([routedInfo, 'optionalAccess', _360 => _360.actualProviderId]) || options.providerId;
6046
+ const actualModel = _optionalChain([routedInfo, 'optionalAccess', _361 => _361.actualModelId]) || options.model;
5339
6047
  const provider = await getProvider(actualProviderId);
5340
6048
  if (!provider) {
5341
- _optionalChain([callbacks, 'access', _332 => _332.onError, 'optionalCall', _333 => _333(`Provider not found: ${actualProviderId}`)]);
6049
+ _optionalChain([callbacks, 'access', _362 => _362.onError, 'optionalCall', _363 => _363(`Provider not found: ${actualProviderId}`)]);
5342
6050
  return;
5343
6051
  }
5344
6052
  if (!provider.enabled) {
5345
- _optionalChain([callbacks, 'access', _334 => _334.onError, 'optionalCall', _335 => _335(`Provider is disabled: ${provider.name}`)]);
6053
+ _optionalChain([callbacks, 'access', _364 => _364.onError, 'optionalCall', _365 => _365(`Provider is disabled: ${provider.name}`)]);
5346
6054
  return;
5347
6055
  }
5348
6056
  const { apiKey: effectiveKey } = _chunkA2YMUCBTcjs.resolveProviderEndpoint.call(void 0, provider);
5349
6057
  const apiKey = resolveApiKey2(effectiveKey);
5350
6058
  if (!apiKey) {
5351
- _optionalChain([callbacks, 'access', _336 => _336.onError, 'optionalCall', _337 => _337("API key not configured")]);
6059
+ _optionalChain([callbacks, 'access', _366 => _366.onError, 'optionalCall', _367 => _367("API key not configured")]);
5352
6060
  return;
5353
6061
  }
5354
6062
  const { chain, hasTransformers } = await resolveChainWithMain(
@@ -5360,17 +6068,8 @@ async function completeStreamWithTransformers(options, callbacks, llmConfig, get
5360
6068
  return completeStreamFallback(options, callbacks);
5361
6069
  }
5362
6070
  const messageId = `msg_${Date.now()}`;
5363
- _optionalChain([callbacks, 'access', _338 => _338.onStart, 'optionalCall', _339 => _339(messageId)]);
5364
- const unifiedRequest = {
5365
- model: actualModel,
5366
- messages: options.messages.map((m) => ({
5367
- role: m.role,
5368
- content: m.content
5369
- })),
5370
- max_tokens: options.maxTokens || 4096,
5371
- temperature: options.temperature,
5372
- stream: true
5373
- };
6071
+ _optionalChain([callbacks, 'access', _368 => _368.onStart, 'optionalCall', _369 => _369(messageId)]);
6072
+ const unifiedRequest = buildUnifiedCompletionRequest(actualModel, options, true);
5374
6073
  const transformerProvider = {
5375
6074
  name: provider.name,
5376
6075
  baseUrl: provider.api_base_url,
@@ -5378,7 +6077,7 @@ async function completeStreamWithTransformers(options, callbacks, llmConfig, get
5378
6077
  models: provider.models || []
5379
6078
  };
5380
6079
  const executor = getSharedExecutor2();
5381
- const { response } = await _chunkHYN75H6Gcjs.executeProviderCall.call(void 0, {
6080
+ const { response } = await _chunkMUHWHQVMcjs.executeProviderCall.call(void 0, {
5382
6081
  executor,
5383
6082
  request: unifiedRequest,
5384
6083
  provider: transformerProvider,
@@ -5408,7 +6107,7 @@ async function completeStreamWithTransformers(options, callbacks, llmConfig, get
5408
6107
  });
5409
6108
  if (!response.ok) {
5410
6109
  const errorText = await response.text();
5411
- _optionalChain([callbacks, 'access', _340 => _340.onError, 'optionalCall', _341 => _341(`API error (${response.status}): ${errorText}`)]);
6110
+ _optionalChain([callbacks, 'access', _370 => _370.onError, 'optionalCall', _371 => _371(`API error (${response.status}): ${errorText}`)]);
5412
6111
  return;
5413
6112
  }
5414
6113
  const transformedResponse = await executor.executeResponseChain(
@@ -5418,9 +6117,9 @@ async function completeStreamWithTransformers(options, callbacks, llmConfig, get
5418
6117
  chain,
5419
6118
  { endpointTransformer: void 0 }
5420
6119
  );
5421
- const reader = _optionalChain([transformedResponse, 'access', _342 => _342.body, 'optionalAccess', _343 => _343.getReader, 'call', _344 => _344()]);
6120
+ const reader = _optionalChain([transformedResponse, 'access', _372 => _372.body, 'optionalAccess', _373 => _373.getReader, 'call', _374 => _374()]);
5422
6121
  if (!reader) {
5423
- _optionalChain([callbacks, 'access', _345 => _345.onError, 'optionalCall', _346 => _346("No response body")]);
6122
+ _optionalChain([callbacks, 'access', _375 => _375.onError, 'optionalCall', _376 => _376("No response body")]);
5424
6123
  return;
5425
6124
  }
5426
6125
  const decoder = new TextDecoder();
@@ -5438,22 +6137,22 @@ async function completeStreamWithTransformers(options, callbacks, llmConfig, get
5438
6137
  if (data === "[DONE]") continue;
5439
6138
  try {
5440
6139
  const json = JSON.parse(data);
5441
- const delta = _optionalChain([json, 'access', _347 => _347.choices, 'optionalAccess', _348 => _348[0], 'optionalAccess', _349 => _349.delta]);
5442
- if (_optionalChain([delta, 'optionalAccess', _350 => _350.content])) {
6140
+ const delta = _optionalChain([json, 'access', _377 => _377.choices, 'optionalAccess', _378 => _378[0], 'optionalAccess', _379 => _379.delta]);
6141
+ if (_optionalChain([delta, 'optionalAccess', _380 => _380.content])) {
5443
6142
  content += delta.content;
5444
- _optionalChain([callbacks, 'access', _351 => _351.onDelta, 'optionalCall', _352 => _352(delta.content)]);
6143
+ _optionalChain([callbacks, 'access', _381 => _381.onDelta, 'optionalCall', _382 => _382(delta.content)]);
5445
6144
  }
5446
- if (_optionalChain([delta, 'optionalAccess', _353 => _353.thinking, 'optionalAccess', _354 => _354.content])) {
6145
+ if (_optionalChain([delta, 'optionalAccess', _383 => _383.thinking, 'optionalAccess', _384 => _384.content])) {
5447
6146
  reasoning += delta.thinking.content;
5448
- _optionalChain([callbacks, 'access', _355 => _355.onReasoning, 'optionalCall', _356 => _356(delta.thinking.content)]);
6147
+ _optionalChain([callbacks, 'access', _385 => _385.onReasoning, 'optionalCall', _386 => _386(delta.thinking.content)]);
5449
6148
  }
5450
- if (_optionalChain([delta, 'optionalAccess', _357 => _357.reasoning_content])) {
6149
+ if (_optionalChain([delta, 'optionalAccess', _387 => _387.reasoning_content])) {
5451
6150
  reasoning += delta.reasoning_content;
5452
- _optionalChain([callbacks, 'access', _358 => _358.onReasoning, 'optionalCall', _359 => _359(delta.reasoning_content)]);
6151
+ _optionalChain([callbacks, 'access', _388 => _388.onReasoning, 'optionalCall', _389 => _389(delta.reasoning_content)]);
5453
6152
  }
5454
6153
  if (json.usage) {
5455
6154
  const tapped = readUsageFromOpenAIResponse(json.usage);
5456
- if (_optionalChain([recording, 'optionalAccess', _360 => _360.recorder]) && tapped) {
6155
+ if (_optionalChain([recording, 'optionalAccess', _390 => _390.recorder]) && tapped) {
5457
6156
  recording.recorder.record({
5458
6157
  messageId: _nullishCoalesce(options.messageId, () => ( null)),
5459
6158
  parentMessageId: _nullishCoalesce(options.parentMessageId, () => ( null)),
@@ -5466,7 +6165,7 @@ async function completeStreamWithTransformers(options, callbacks, llmConfig, get
5466
6165
  rawUsage: json.usage
5467
6166
  });
5468
6167
  }
5469
- _optionalChain([callbacks, 'access', _361 => _361.onDone, 'optionalCall', _362 => _362(
6168
+ _optionalChain([callbacks, 'access', _391 => _391.onDone, 'optionalCall', _392 => _392(
5470
6169
  {
5471
6170
  id: messageId,
5472
6171
  role: "assistant",
@@ -5487,7 +6186,7 @@ async function completeStreamWithTransformers(options, callbacks, llmConfig, get
5487
6186
  }
5488
6187
  }
5489
6188
  }
5490
- _optionalChain([callbacks, 'access', _363 => _363.onDone, 'optionalCall', _364 => _364({
6189
+ _optionalChain([callbacks, 'access', _393 => _393.onDone, 'optionalCall', _394 => _394({
5491
6190
  id: messageId,
5492
6191
  role: "assistant",
5493
6192
  content,
@@ -5499,13 +6198,13 @@ async function completeStreamWithTransformers(options, callbacks, llmConfig, get
5499
6198
  }
5500
6199
  } catch (error) {
5501
6200
  const message = error instanceof Error ? error.message : "Unknown error";
5502
- _optionalChain([callbacks, 'access', _365 => _365.onError, 'optionalCall', _366 => _366(message)]);
6201
+ _optionalChain([callbacks, 'access', _395 => _395.onError, 'optionalCall', _396 => _396(message)]);
5503
6202
  }
5504
6203
  }
5505
6204
 
5506
6205
  // src/completion/CompletionService.ts
5507
6206
  var CompletionService = (_class13 = class {
5508
- constructor(paths, llmConfig, logger) {;_class13.prototype.__init22.call(this);_class13.prototype.__init23.call(this);_class13.prototype.__init24.call(this);_class13.prototype.__init25.call(this);
6207
+ constructor(paths, llmConfig, logger) {;_class13.prototype.__init23.call(this);_class13.prototype.__init24.call(this);_class13.prototype.__init25.call(this);_class13.prototype.__init26.call(this);
5509
6208
  this.paths = paths;
5510
6209
  this.llmConfig = llmConfig;
5511
6210
  this.logger = logger;
@@ -5513,10 +6212,10 @@ var CompletionService = (_class13 = class {
5513
6212
 
5514
6213
 
5515
6214
 
5516
- __init22() {this.apiKeyPool = null}
5517
- __init23() {this.usageRecorder = null}
5518
- __init24() {this.usageEventSink = null}
5519
- __init25() {this.visionFallbackProvider = null}
6215
+ __init23() {this.apiKeyPool = null}
6216
+ __init24() {this.usageRecorder = null}
6217
+ __init25() {this.usageEventSink = null}
6218
+ __init26() {this.visionFallbackProvider = null}
5520
6219
  /**
5521
6220
  * Set the API key pool service for multi-key load balancing.
5522
6221
  * When set, keys are resolved via the pool instead of directly from the provider.
@@ -5566,8 +6265,8 @@ var CompletionService = (_class13 = class {
5566
6265
  options.providerId,
5567
6266
  options.model
5568
6267
  );
5569
- const actualProviderId = _optionalChain([routedInfo, 'optionalAccess', _367 => _367.actualProviderId]) || options.providerId;
5570
- const actualModel = _optionalChain([routedInfo, 'optionalAccess', _368 => _368.actualModelId]) || options.model;
6268
+ const actualProviderId = _optionalChain([routedInfo, 'optionalAccess', _397 => _397.actualProviderId]) || options.providerId;
6269
+ const actualModel = _optionalChain([routedInfo, 'optionalAccess', _398 => _398.actualModelId]) || options.model;
5571
6270
  const provider = await this.getProvider(actualProviderId);
5572
6271
  if (!provider) {
5573
6272
  return { success: false, error: `Provider not found: ${actualProviderId}` };
@@ -5600,7 +6299,7 @@ var CompletionService = (_class13 = class {
5600
6299
  this.apiKeyPool.reportSuccess(options.sessionId);
5601
6300
  }
5602
6301
  if (result.success && result.usage && options.sessionId) {
5603
- _optionalChain([this, 'access', _369 => _369.usageEventSink, 'optionalAccess', _370 => _370.emit, 'call', _371 => _371({
6302
+ _optionalChain([this, 'access', _399 => _399.usageEventSink, 'optionalAccess', _400 => _400.emit, 'call', _401 => _401({
5604
6303
  sessionId: options.sessionId,
5605
6304
  modelId: actualModel,
5606
6305
  usage: result.usage,
@@ -5629,8 +6328,8 @@ var CompletionService = (_class13 = class {
5629
6328
  options.model
5630
6329
  );
5631
6330
  this.logger.debug("Resolved routed model", { routedInfo });
5632
- const actualProviderId = _optionalChain([routedInfo, 'optionalAccess', _372 => _372.actualProviderId]) || options.providerId;
5633
- const actualModel = _optionalChain([routedInfo, 'optionalAccess', _373 => _373.actualModelId]) || options.model;
6331
+ const actualProviderId = _optionalChain([routedInfo, 'optionalAccess', _402 => _402.actualProviderId]) || options.providerId;
6332
+ const actualModel = _optionalChain([routedInfo, 'optionalAccess', _403 => _403.actualModelId]) || options.model;
5634
6333
  this.logger.debug("Resolved provider and model", { actualProviderId, actualModel });
5635
6334
  const provider = await this.getProvider(actualProviderId);
5636
6335
  this.logger.debug("Retrieved provider", provider ? {
@@ -5642,22 +6341,22 @@ var CompletionService = (_class13 = class {
5642
6341
  enabled: provider.enabled
5643
6342
  } : { error: "Provider not found" });
5644
6343
  if (!provider) {
5645
- _optionalChain([callbacks, 'access', _374 => _374.onError, 'optionalCall', _375 => _375(`Provider not found: ${actualProviderId}`)]);
6344
+ _optionalChain([callbacks, 'access', _404 => _404.onError, 'optionalCall', _405 => _405(`Provider not found: ${actualProviderId}`)]);
5646
6345
  return;
5647
6346
  }
5648
6347
  if (!provider.enabled) {
5649
- _optionalChain([callbacks, 'access', _376 => _376.onError, 'optionalCall', _377 => _377(`Provider is disabled: ${provider.name}`)]);
6348
+ _optionalChain([callbacks, 'access', _406 => _406.onError, 'optionalCall', _407 => _407(`Provider is disabled: ${provider.name}`)]);
5650
6349
  return;
5651
6350
  }
5652
6351
  const apiKey = await this.resolveApiKeyForRequest(provider, actualProviderId, options.sessionId);
5653
6352
  if (!apiKey) {
5654
- _optionalChain([callbacks, 'access', _378 => _378.onError, 'optionalCall', _379 => _379("API key not configured")]);
6353
+ _optionalChain([callbacks, 'access', _408 => _408.onError, 'optionalCall', _409 => _409("API key not configured")]);
5655
6354
  return;
5656
6355
  }
5657
6356
  const apiFormat = _chunkA2YMUCBTcjs.resolveApiFormat.call(void 0, provider);
5658
6357
  this.logger.info("Using API format for stream", { apiFormat });
5659
6358
  const messageId = `msg_${Date.now()}`;
5660
- _optionalChain([callbacks, 'access', _380 => _380.onStart, 'optionalCall', _381 => _381(messageId)]);
6359
+ _optionalChain([callbacks, 'access', _410 => _410.onStart, 'optionalCall', _411 => _411(messageId)]);
5661
6360
  const resolvedOptions = { ...options, model: actualModel };
5662
6361
  if (options.sessionId) {
5663
6362
  const sid = options.sessionId;
@@ -5666,14 +6365,14 @@ var CompletionService = (_class13 = class {
5666
6365
  ...callbacks,
5667
6366
  onDone: (message, usage, metrics) => {
5668
6367
  if (usage) {
5669
- _optionalChain([this, 'access', _382 => _382.usageEventSink, 'optionalAccess', _383 => _383.emit, 'call', _384 => _384({
6368
+ _optionalChain([this, 'access', _412 => _412.usageEventSink, 'optionalAccess', _413 => _413.emit, 'call', _414 => _414({
5670
6369
  sessionId: sid,
5671
6370
  modelId: actualModel,
5672
6371
  usage,
5673
6372
  engineOrigin: "completion"
5674
6373
  })]);
5675
6374
  }
5676
- _optionalChain([userOnDone, 'optionalCall', _385 => _385(message, usage, metrics)]);
6375
+ _optionalChain([userOnDone, 'optionalCall', _415 => _415(message, usage, metrics)]);
5677
6376
  }
5678
6377
  };
5679
6378
  }
@@ -5689,11 +6388,11 @@ var CompletionService = (_class13 = class {
5689
6388
  retryState.error = { status, message: error };
5690
6389
  return;
5691
6390
  }
5692
- _optionalChain([callbacks, 'access', _386 => _386.onError, 'optionalCall', _387 => _387(error)]);
6391
+ _optionalChain([callbacks, 'access', _416 => _416.onError, 'optionalCall', _417 => _417(error)]);
5693
6392
  },
5694
6393
  onDone: (message, usage, metrics) => {
5695
6394
  this.apiKeyPool.reportSuccess(options.sessionId);
5696
- _optionalChain([callbacks, 'access', _388 => _388.onDone, 'optionalCall', _389 => _389(message, usage, metrics)]);
6395
+ _optionalChain([callbacks, 'access', _418 => _418.onDone, 'optionalCall', _419 => _419(message, usage, metrics)]);
5697
6396
  }
5698
6397
  };
5699
6398
  await this.callStreamHandler(apiFormat, provider, apiKey, resolvedOptions, messageId, interceptCallbacks);
@@ -5714,7 +6413,7 @@ var CompletionService = (_class13 = class {
5714
6413
  // don't fire onStart again
5715
6414
  });
5716
6415
  } else {
5717
- _optionalChain([callbacks, 'access', _390 => _390.onError, 'optionalCall', _391 => _391(retryState.error.message)]);
6416
+ _optionalChain([callbacks, 'access', _420 => _420.onError, 'optionalCall', _421 => _421(retryState.error.message)]);
5718
6417
  }
5719
6418
  }
5720
6419
  } else {
@@ -5727,7 +6426,7 @@ var CompletionService = (_class13 = class {
5727
6426
  } catch (error) {
5728
6427
  const message = error instanceof Error ? error.message : "Unknown error";
5729
6428
  this.logger.error("Stream completion error", error instanceof Error ? error : void 0, { message });
5730
- _optionalChain([callbacks, 'access', _392 => _392.onError, 'optionalCall', _393 => _393(message)]);
6429
+ _optionalChain([callbacks, 'access', _422 => _422.onError, 'optionalCall', _423 => _423(message)]);
5731
6430
  }
5732
6431
  }
5733
6432
  /**
@@ -5767,7 +6466,7 @@ var CompletionService = (_class13 = class {
5767
6466
  return {
5768
6467
  success: true,
5769
6468
  message: "Connection successful",
5770
- response: _optionalChain([result, 'access', _394 => _394.message, 'optionalAccess', _395 => _395.content]) || "",
6469
+ response: _optionalChain([result, 'access', _424 => _424.message, 'optionalAccess', _425 => _425.content]) || "",
5771
6470
  model: modelId,
5772
6471
  durationMs
5773
6472
  };
@@ -5832,7 +6531,7 @@ ${description}`;
5832
6531
  * 3. Legacy single key from provider config
5833
6532
  */
5834
6533
  async resolveApiKeyForRequest(provider, providerId, sessionId) {
5835
- if (_optionalChain([provider, 'access', _396 => _396.codingPlan, 'optionalAccess', _397 => _397.enabled]) && provider.codingPlan.apiKey) {
6534
+ if (_optionalChain([provider, 'access', _426 => _426.codingPlan, 'optionalAccess', _427 => _427.enabled]) && provider.codingPlan.apiKey) {
5836
6535
  return this.resolveApiKey(provider.codingPlan.apiKey);
5837
6536
  }
5838
6537
  if (this.apiKeyPool) {
@@ -5905,9 +6604,10 @@ ${description}`;
5905
6604
  * Resolve effective max_tokens value with priority:
5906
6605
  * 1. Session settings (if provided)
5907
6606
  * 2. Global model parameters (if enabled)
5908
- * 3. Model's maxTokens from provider config
5909
- * 4. Discovered models cache (from API)
5910
- * 5. undefined - let API use its default
6607
+ * 3. undefined - let API use its default
6608
+ *
6609
+ * Provider and discovery maxTokens values are capability metadata, not
6610
+ * implicit per-request output limits.
5911
6611
  */
5912
6612
  async resolveEffectiveMaxTokens(providerId, modelId, sessionMaxTokens) {
5913
6613
  return resolveEffectiveMaxTokens(
@@ -6082,4 +6782,13 @@ ${description}`;
6082
6782
 
6083
6783
 
6084
6784
 
6085
- 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.aggregateAnthropicSseToJsonBody = aggregateAnthropicSseToJsonBody; 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.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;
6785
+
6786
+
6787
+
6788
+
6789
+
6790
+
6791
+
6792
+
6793
+
6794
+ 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.aggregateAnthropicSseToJsonBody = aggregateAnthropicSseToJsonBody; exports.writeError = writeError; exports.writeBoundAccountError = writeBoundAccountError; 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.DEFAULT_ALLOWANCE_SCHEDULING = DEFAULT_ALLOWANCE_SCHEDULING; exports.normalizeAllowanceScheduling = normalizeAllowanceScheduling; 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.legacyEndpointsToBindings = legacyEndpointsToBindings; exports.normalizeGatewayBindings = normalizeGatewayBindings; exports.defaultServerConfig = defaultServerConfig; exports.normalizeServerConfig = normalizeServerConfig; exports.loadServerConfig = loadServerConfig; exports.saveServerConfig = saveServerConfig; exports.mergeServerConfig = mergeServerConfig; exports.gatewayBindingToEndpointConfig = gatewayBindingToEndpointConfig; exports.candidateGatewayBindings = candidateGatewayBindings; exports.candidateBackgroundModelIds = candidateBackgroundModelIds; exports.resolveGatewayBinding = resolveGatewayBinding; exports.computeKeyExpiry = computeKeyExpiry; exports.checkKeyQuota = checkKeyQuota; exports.randomBase62 = randomBase62; exports.hashKey = hashKey; exports.createNamedKey = createNamedKey; exports.createIntegrationKey = createIntegrationKey; 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.OutboundApiServer = OutboundApiServer; exports.formatUrls = formatUrls; exports.startOfLocalDay = startOfLocalDay; exports.startOfLocalWeek = startOfLocalWeek; exports.KeySpendTracker = KeySpendTracker; exports.getOutboundApiServer = getOutboundApiServer; exports.__resetOutboundApiServerForTests = __resetOutboundApiServerForTests;