@omnicross/core 0.1.5 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ApiConverter.cjs +2 -2
- package/dist/ApiConverter.js +1 -1
- package/dist/{CompletionService-DdWaAxq0.d.ts → CompletionService-C3BX0Ovy.d.ts} +4 -3
- package/dist/{CompletionService-D3a47vdU.d.cts → CompletionService-kNA17cfI.d.cts} +4 -3
- package/dist/auth/GeminiCodeAssistProjectResolver.cjs +8 -6
- package/dist/auth/GeminiCodeAssistProjectResolver.js +6 -4
- package/dist/{chunk-3Z5BQZFM.cjs → chunk-235MXAGX.cjs} +3 -1
- package/dist/{chunk-HRRYG2AX.js → chunk-23S5OPIO.js} +10 -1
- package/dist/chunk-25GXJCEZ.cjs +40 -0
- package/dist/chunk-2E42SAW3.cjs +323 -0
- package/dist/chunk-2JYRIADS.js +40 -0
- package/dist/chunk-2Z4XM3H5.cjs +44 -0
- package/dist/{chunk-BODMAL6G.js → chunk-32O35CIF.js} +271 -91
- package/dist/chunk-3SCOLIPT.cjs +63 -0
- package/dist/{chunk-SYQF7OIR.js → chunk-3WD4HTR2.js} +2 -0
- package/dist/{chunk-CGKLE6IW.cjs → chunk-4BB343BI.cjs} +1489 -520
- package/dist/{chunk-VACWOIRE.cjs → chunk-4VZX5F4T.cjs} +39 -15
- package/dist/{chunk-5ZQBEOMD.js → chunk-5NJLQ6T6.js} +46 -12
- package/dist/chunk-5RSZYQJH.cjs +62 -0
- package/dist/chunk-6QQG7YG3.cjs +153 -0
- package/dist/{chunk-IFXJ2BG7.js → chunk-7C7DET6S.js} +51 -6
- package/dist/{chunk-IK3KE3AU.js → chunk-DE2SRBFZ.js} +1 -1
- package/dist/{chunk-FH2P4OCD.js → chunk-E3COOKUP.js} +1240 -271
- package/dist/{chunk-UHGVBFU3.js → chunk-EBLFCNPY.js} +38 -14
- package/dist/chunk-FU7EAR73.js +62 -0
- package/dist/chunk-FXR6N3SR.js +323 -0
- package/dist/{chunk-SUEGJ75D.cjs → chunk-GDIXXKF2.cjs} +46 -12
- package/dist/chunk-GFIZ6LQI.js +170 -0
- package/dist/chunk-GL6XM527.js +61 -0
- package/dist/chunk-HVBBDBS3.cjs +350 -0
- package/dist/{chunk-46ZIFWYG.cjs → chunk-IIRPUVPH.cjs} +7 -1
- package/dist/chunk-J3QQ6JS5.cjs +170 -0
- package/dist/{chunk-JWVTXXPX.cjs → chunk-KBM2W6UY.cjs} +8 -4
- package/dist/chunk-LB6EBS6Y.js +69 -0
- package/dist/{chunk-IWQAX3CS.js → chunk-LVUCAWMK.js} +1 -1
- package/dist/chunk-MKF46GNZ.js +350 -0
- package/dist/{chunk-HYN75H6G.cjs → chunk-MUHWHQVM.cjs} +1 -1
- package/dist/chunk-MYYR3HZL.js +44 -0
- package/dist/{chunk-MFZ5437A.js → chunk-N5T4M4GU.js} +1 -1
- package/dist/{chunk-5ENKBSWO.js → chunk-N7OOJI5V.js} +88 -8
- package/dist/chunk-NKVZ6Z3Y.cjs +61 -0
- package/dist/chunk-OF3BECU2.cjs +69 -0
- package/dist/{chunk-SNYBEXLB.cjs → chunk-OJGQKHN5.cjs} +3 -1
- package/dist/{chunk-DDMRUL76.cjs → chunk-OKMJLEXX.cjs} +5 -5
- package/dist/chunk-OPRS4IQZ.js +153 -0
- package/dist/chunk-OTZC4TNH.cjs +79 -0
- package/dist/{chunk-3Q6Z6JTO.cjs → chunk-OVQBNVSV.cjs} +287 -107
- package/dist/{chunk-4XMYPW46.cjs → chunk-OXHNSZ53.cjs} +84 -44
- package/dist/{chunk-C6OV7GCC.js → chunk-PEGTIPB3.js} +52 -12
- package/dist/chunk-PO3XB56Z.js +79 -0
- package/dist/{chunk-D3TDKWRP.js → chunk-RJ5ZGNI3.js} +54 -5
- package/dist/{chunk-PG7PS2NN.cjs → chunk-RJUONLUQ.cjs} +59 -10
- package/dist/{chunk-BPKCU575.js → chunk-SOO562NM.js} +3 -1
- package/dist/{chunk-6QZGDLL4.js → chunk-TOVPMMHM.js} +5 -1
- package/dist/{chunk-K52THW2C.cjs → chunk-V4TXMEJS.cjs} +5 -5
- package/dist/{chunk-G2UTNSGU.js → chunk-WNKWAEUR.js} +7 -1
- package/dist/{chunk-UNWKG6EI.cjs → chunk-XPIOJQS2.cjs} +51 -6
- package/dist/chunk-XXFYLL7R.js +63 -0
- package/dist/{chunk-KFI44N2R.cjs → chunk-YNJNTCSQ.cjs} +10 -1
- package/dist/{chunk-VQY5W4YW.cjs → chunk-YWL7YZWS.cjs} +90 -10
- package/dist/completion/ApiKeyPoolService.cjs +12 -0
- package/dist/completion/ApiKeyPoolService.d.cts +6 -0
- package/dist/completion/ApiKeyPoolService.d.ts +6 -0
- package/dist/completion/ApiKeyPoolService.js +12 -0
- package/dist/completion/CompletionService.cjs +30 -24
- package/dist/completion/CompletionService.d.cts +3 -1
- package/dist/completion/CompletionService.d.ts +3 -1
- package/dist/completion/CompletionService.js +29 -23
- package/dist/completion.cjs +32 -26
- package/dist/completion.d.cts +3 -1
- package/dist/completion.d.ts +3 -1
- package/dist/completion.js +31 -25
- package/dist/index.cjs +56 -29
- package/dist/index.d.cts +8 -8
- package/dist/index.d.ts +8 -8
- package/dist/index.js +61 -34
- package/dist/{keyPolicy-Cp0FntZl.d.cts → keyPolicy-zdWTu3CQ.d.cts} +1 -1
- package/dist/{keyPolicy-Cp0FntZl.d.ts → keyPolicy-zdWTu3CQ.d.ts} +1 -1
- package/dist/outbound-api/auditCapture.cjs +2 -2
- package/dist/outbound-api/auditCapture.d.cts +3 -4
- package/dist/outbound-api/auditCapture.d.ts +3 -4
- package/dist/outbound-api/auditCapture.js +1 -1
- package/dist/outbound-api/quotaWarn.d.cts +1 -1
- package/dist/outbound-api/quotaWarn.d.ts +1 -1
- package/dist/outbound-api/routeResolver.cjs +2 -2
- package/dist/outbound-api/routeResolver.d.cts +5 -3
- package/dist/outbound-api/routeResolver.d.ts +5 -3
- package/dist/outbound-api/routeResolver.js +1 -1
- package/dist/outbound-api/subscriptionRegistryPort.d.cts +2 -0
- package/dist/outbound-api/subscriptionRegistryPort.d.ts +2 -0
- package/dist/outbound-api/types.d.cts +4 -2
- package/dist/outbound-api/types.d.ts +4 -2
- package/dist/outbound-api.cjs +52 -25
- package/dist/outbound-api.d.cts +131 -87
- package/dist/outbound-api.d.ts +131 -87
- package/dist/outbound-api.js +55 -28
- package/dist/pipeline/AccountAllowanceScheduling.cjs +15 -0
- package/dist/pipeline/AccountAllowanceScheduling.d.cts +91 -0
- package/dist/pipeline/AccountAllowanceScheduling.d.ts +91 -0
- package/dist/pipeline/AccountAllowanceScheduling.js +15 -0
- package/dist/pipeline/AccountAllowanceStore.cjs +20 -0
- package/dist/pipeline/AccountAllowanceStore.d.cts +77 -0
- package/dist/pipeline/AccountAllowanceStore.d.ts +77 -0
- package/dist/pipeline/AccountAllowanceStore.js +20 -0
- package/dist/pipeline/AccountRouteActivity.cjs +10 -0
- package/dist/pipeline/AccountRouteActivity.d.cts +61 -0
- package/dist/pipeline/AccountRouteActivity.d.ts +61 -0
- package/dist/pipeline/AccountRouteActivity.js +10 -0
- package/dist/pipeline/AuthSource.d.cts +11 -2
- package/dist/pipeline/AuthSource.d.ts +11 -2
- package/dist/pipeline/BoundAccountSelectionError.cjs +10 -0
- package/dist/pipeline/BoundAccountSelectionError.d.cts +28 -0
- package/dist/pipeline/BoundAccountSelectionError.d.ts +28 -0
- package/dist/pipeline/BoundAccountSelectionError.js +10 -0
- package/dist/pipeline/LlmConfigProviderAuth.d.cts +1 -0
- package/dist/pipeline/LlmConfigProviderAuth.d.ts +1 -0
- package/dist/pipeline/ServerOverloadCounter.cjs +16 -0
- package/dist/pipeline/ServerOverloadCounter.d.cts +77 -0
- package/dist/pipeline/ServerOverloadCounter.d.ts +77 -0
- package/dist/pipeline/ServerOverloadCounter.js +16 -0
- package/dist/pipeline/SubscriptionAccountHealth.cjs +6 -2
- package/dist/pipeline/SubscriptionAccountHealth.d.cts +65 -8
- package/dist/pipeline/SubscriptionAccountHealth.d.ts +65 -8
- package/dist/pipeline/SubscriptionAccountHealth.js +5 -1
- package/dist/pipeline/SubscriptionAuthSource.cjs +5 -2
- package/dist/pipeline/SubscriptionAuthSource.d.cts +1 -0
- package/dist/pipeline/SubscriptionAuthSource.d.ts +1 -0
- package/dist/pipeline/SubscriptionAuthSource.js +4 -1
- package/dist/pipeline/SubscriptionAuthStrategy.d.cts +8 -3
- package/dist/pipeline/SubscriptionAuthStrategy.d.ts +8 -3
- package/dist/pipeline/executeProviderCall.cjs +2 -2
- package/dist/pipeline/executeProviderCall.d.cts +8 -3
- package/dist/pipeline/executeProviderCall.d.ts +8 -3
- package/dist/pipeline/executeProviderCall.js +1 -1
- package/dist/pipeline/resolveProviderChain.d.cts +2 -3
- package/dist/pipeline/resolveProviderChain.d.ts +2 -3
- package/dist/pipeline/resolveSubscriptionChain.d.cts +1 -0
- package/dist/pipeline/resolveSubscriptionChain.d.ts +1 -0
- package/dist/pipeline/upstreamFetch.cjs +5 -3
- package/dist/pipeline/upstreamFetch.d.cts +35 -6
- package/dist/pipeline/upstreamFetch.d.ts +35 -6
- package/dist/pipeline/upstreamFetch.js +4 -2
- package/dist/pipeline/upstreamTrace.cjs +4 -2
- package/dist/pipeline/upstreamTrace.d.cts +22 -8
- package/dist/pipeline/upstreamTrace.d.ts +22 -8
- package/dist/pipeline/upstreamTrace.js +3 -1
- package/dist/ports/pricing-store.d.cts +4 -3
- package/dist/ports/pricing-store.d.ts +4 -3
- package/dist/ports.d.cts +4 -3
- package/dist/ports.d.ts +4 -3
- package/dist/provider-proxy/ProviderProxy.cjs +30 -24
- package/dist/provider-proxy/ProviderProxy.d.cts +2 -0
- package/dist/provider-proxy/ProviderProxy.d.ts +2 -0
- package/dist/provider-proxy/ProviderProxy.js +29 -23
- package/dist/provider-proxy/identity/codexCliHeaders.cjs +10 -0
- package/dist/provider-proxy/identity/codexCliHeaders.d.cts +45 -0
- package/dist/provider-proxy/identity/codexCliHeaders.d.ts +45 -0
- package/dist/provider-proxy/identity/codexCliHeaders.js +10 -0
- package/dist/provider-proxy/ingress/providerProxyShared.cjs +32 -24
- package/dist/provider-proxy/ingress/providerProxyShared.d.cts +44 -5
- package/dist/provider-proxy/ingress/providerProxyShared.d.ts +44 -5
- package/dist/provider-proxy/ingress/providerProxyShared.js +31 -23
- package/dist/provider-proxy/matchText.cjs +4 -2
- package/dist/provider-proxy/matchText.d.cts +39 -6
- package/dist/provider-proxy/matchText.d.ts +39 -6
- package/dist/provider-proxy/matchText.js +3 -1
- package/dist/provider-proxy/types.d.cts +35 -2
- package/dist/provider-proxy/types.d.ts +35 -2
- package/dist/provider-proxy.cjs +30 -24
- package/dist/provider-proxy.d.cts +2 -0
- package/dist/provider-proxy.d.ts +2 -0
- package/dist/provider-proxy.js +29 -23
- package/dist/{routeResolver-C4T7yClx.d.ts → routeResolver-BxOfunbm.d.ts} +1 -1
- package/dist/{routeResolver-CB3tvJKy.d.cts → routeResolver-D5OzD0iM.d.cts} +1 -1
- package/dist/transformer/TransformerChainExecutor.cjs +2 -2
- package/dist/transformer/TransformerChainExecutor.js +1 -1
- package/dist/transformer/transformers/AnthropicTransformer.cjs +3 -2
- package/dist/transformer/transformers/AnthropicTransformer.js +2 -1
- package/dist/transformer/transformers/GeminiCodeAssistTransformer.cjs +3 -3
- package/dist/transformer/transformers/GeminiCodeAssistTransformer.js +2 -2
- package/dist/transformer/transformers/GeminiTransformer.cjs +3 -3
- package/dist/transformer/transformers/GeminiTransformer.js +2 -2
- package/dist/transformer/transformers/OpenAIResponseTransformer.cjs +3 -2
- package/dist/transformer/transformers/OpenAIResponseTransformer.d.cts +1 -1
- package/dist/transformer/transformers/OpenAIResponseTransformer.d.ts +1 -1
- package/dist/transformer/transformers/OpenAIResponseTransformer.js +2 -1
- package/dist/transformer/transformers/OpenAITransformer.cjs +6 -0
- package/dist/transformer/transformers/OpenAITransformer.d.cts +68 -0
- package/dist/transformer/transformers/OpenAITransformer.d.ts +68 -0
- package/dist/transformer/transformers/OpenAITransformer.js +6 -0
- package/dist/transformer/transformers.cjs +9 -14
- package/dist/transformer/transformers.d.cts +12 -48
- package/dist/transformer/transformers.d.ts +12 -48
- package/dist/transformer/transformers.js +11 -16
- package/dist/transformer/types.d.cts +17 -0
- package/dist/transformer/types.d.ts +17 -0
- package/dist/transformer.cjs +12 -12
- package/dist/transformer.d.cts +1 -2
- package/dist/transformer.d.ts +1 -2
- package/dist/transformer.js +12 -12
- package/dist/{types-lgPYQuZS.d.ts → types-CqZD77rS.d.ts} +173 -7
- package/dist/{types-B8Arpxn0.d.cts → types-gjJ5lJ5n.d.cts} +173 -7
- package/dist/usage/pricing-engine.cjs +2 -2
- package/dist/usage/pricing-engine.d.cts +29 -1
- package/dist/usage/pricing-engine.d.ts +29 -1
- package/dist/usage/pricing-engine.js +1 -1
- package/dist/usage/usage-recorder.cjs +2 -2
- package/dist/usage/usage-recorder.d.cts +5 -1
- package/dist/usage/usage-recorder.d.ts +5 -1
- package/dist/usage/usage-recorder.js +1 -1
- package/dist/usage.cjs +3 -3
- package/dist/usage.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-7FEBOPJO.cjs +0 -50
- package/dist/chunk-DWKQZ2SK.cjs +0 -254
- package/dist/chunk-IAXWICZU.js +0 -69
- package/dist/chunk-IB3FDI4O.js +0 -50
- package/dist/chunk-OQWKZCXP.js +0 -242
- package/dist/chunk-QWBWGODS.cjs +0 -69
- package/dist/chunk-YMFAJFQT.cjs +0 -173
- package/dist/chunk-ZCIQ3L3R.cjs +0 -242
- package/dist/chunk-ZJZAOKI7.js +0 -254
- package/dist/chunk-ZLX3KGXX.js +0 -173
- package/dist/transformer/transformers/OpenCodeGoTransformer.cjs +0 -6
- package/dist/transformer/transformers/OpenCodeGoTransformer.d.cts +0 -51
- package/dist/transformer/transformers/OpenCodeGoTransformer.d.ts +0 -51
- package/dist/transformer/transformers/OpenCodeGoTransformer.js +0 -6
- package/dist/transformer/transformers/ReasoningTransformer.cjs +0 -6
- package/dist/transformer/transformers/ReasoningTransformer.d.cts +0 -47
- package/dist/transformer/transformers/ReasoningTransformer.d.ts +0 -47
- package/dist/transformer/transformers/ReasoningTransformer.js +0 -6
|
@@ -3,21 +3,30 @@
|
|
|
3
3
|
var _chunkHQP3K7PUcjs = require('./chunk-HQP3K7PU.cjs');
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
var _chunk46ZIFWYGcjs = require('./chunk-46ZIFWYG.cjs');
|
|
7
6
|
|
|
7
|
+
var _chunkOXHNSZ53cjs = require('./chunk-OXHNSZ53.cjs');
|
|
8
8
|
|
|
9
|
-
var _chunk4XMYPW46cjs = require('./chunk-4XMYPW46.cjs');
|
|
10
9
|
|
|
10
|
+
var _chunkV4TXMEJScjs = require('./chunk-V4TXMEJS.cjs');
|
|
11
11
|
|
|
12
|
-
var _chunkK52THW2Ccjs = require('./chunk-K52THW2C.cjs');
|
|
13
12
|
|
|
13
|
+
var _chunkOVQBNVSVcjs = require('./chunk-OVQBNVSV.cjs');
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
|
|
16
|
+
var _chunkIIRPUVPHcjs = require('./chunk-IIRPUVPH.cjs');
|
|
16
17
|
|
|
17
18
|
|
|
18
19
|
var _chunkGBHYAGX3cjs = require('./chunk-GBHYAGX3.cjs');
|
|
19
20
|
|
|
20
21
|
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
var _chunk3SCOLIPTcjs = require('./chunk-3SCOLIPT.cjs');
|
|
28
|
+
|
|
29
|
+
|
|
21
30
|
var _chunkRPII3E6Zcjs = require('./chunk-RPII3E6Z.cjs');
|
|
22
31
|
|
|
23
32
|
|
|
@@ -26,7 +35,8 @@ var _chunk6RPZADX3cjs = require('./chunk-6RPZADX3.cjs');
|
|
|
26
35
|
|
|
27
36
|
|
|
28
37
|
|
|
29
|
-
|
|
38
|
+
|
|
39
|
+
var _chunkJ3QQ6JS5cjs = require('./chunk-J3QQ6JS5.cjs');
|
|
30
40
|
|
|
31
41
|
|
|
32
42
|
var _chunkUIBD2YY5cjs = require('./chunk-UIBD2YY5.cjs');
|
|
@@ -35,27 +45,37 @@ var _chunkUIBD2YY5cjs = require('./chunk-UIBD2YY5.cjs');
|
|
|
35
45
|
var _chunkR3HK6R4Bcjs = require('./chunk-R3HK6R4B.cjs');
|
|
36
46
|
|
|
37
47
|
|
|
38
|
-
var
|
|
48
|
+
var _chunkQXD4MV2Xcjs = require('./chunk-QXD4MV2X.cjs');
|
|
39
49
|
|
|
40
50
|
|
|
51
|
+
var _chunkNYUNU75Acjs = require('./chunk-NYUNU75A.cjs');
|
|
41
52
|
|
|
42
|
-
var _chunkQ27JY5RGcjs = require('./chunk-Q27JY5RG.cjs');
|
|
43
53
|
|
|
54
|
+
var _chunkOTZC4TNHcjs = require('./chunk-OTZC4TNH.cjs');
|
|
44
55
|
|
|
45
|
-
var _chunkQXD4MV2Xcjs = require('./chunk-QXD4MV2X.cjs');
|
|
46
56
|
|
|
47
57
|
|
|
48
|
-
var
|
|
58
|
+
var _chunkYWL7YZWScjs = require('./chunk-YWL7YZWS.cjs');
|
|
59
|
+
|
|
49
60
|
|
|
61
|
+
var _chunkYNJNTCSQcjs = require('./chunk-YNJNTCSQ.cjs');
|
|
50
62
|
|
|
51
63
|
|
|
52
|
-
var
|
|
64
|
+
var _chunkSVNDB62Dcjs = require('./chunk-SVNDB62D.cjs');
|
|
53
65
|
|
|
54
66
|
|
|
55
|
-
var
|
|
67
|
+
var _chunk6QQG7YG3cjs = require('./chunk-6QQG7YG3.cjs');
|
|
56
68
|
|
|
57
69
|
|
|
58
|
-
|
|
70
|
+
|
|
71
|
+
var _chunk25GXJCEZcjs = require('./chunk-25GXJCEZ.cjs');
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
var _chunkMUHWHQVMcjs = require('./chunk-MUHWHQVM.cjs');
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
var _chunkQ27JY5RGcjs = require('./chunk-Q27JY5RG.cjs');
|
|
59
79
|
|
|
60
80
|
|
|
61
81
|
var _chunkAPYG5QD7cjs = require('./chunk-APYG5QD7.cjs');
|
|
@@ -72,7 +92,8 @@ var _chunk4YINUUKQcjs = require('./chunk-4YINUUKQ.cjs');
|
|
|
72
92
|
|
|
73
93
|
|
|
74
94
|
|
|
75
|
-
|
|
95
|
+
|
|
96
|
+
var _chunk4VZX5F4Tcjs = require('./chunk-4VZX5F4T.cjs');
|
|
76
97
|
|
|
77
98
|
|
|
78
99
|
|
|
@@ -80,14 +101,20 @@ var _chunkVACWOIREcjs = require('./chunk-VACWOIRE.cjs');
|
|
|
80
101
|
var _chunkA2YMUCBTcjs = require('./chunk-A2YMUCBT.cjs');
|
|
81
102
|
|
|
82
103
|
|
|
83
|
-
var
|
|
104
|
+
var _chunkXPIOJQS2cjs = require('./chunk-XPIOJQS2.cjs');
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
var _chunkGDIXXKF2cjs = require('./chunk-GDIXXKF2.cjs');
|
|
109
|
+
|
|
84
110
|
|
|
111
|
+
var _chunkRJUONLUQcjs = require('./chunk-RJUONLUQ.cjs');
|
|
85
112
|
|
|
86
113
|
|
|
87
|
-
var
|
|
114
|
+
var _chunkHVBBDBS3cjs = require('./chunk-HVBBDBS3.cjs');
|
|
88
115
|
|
|
89
116
|
|
|
90
|
-
var
|
|
117
|
+
var _chunkNKVZ6Z3Ycjs = require('./chunk-NKVZ6Z3Y.cjs');
|
|
91
118
|
|
|
92
119
|
|
|
93
120
|
var _chunkJMJBSACDcjs = require('./chunk-JMJBSACD.cjs');
|
|
@@ -469,6 +496,66 @@ var ProviderProxyRouteMap = (_class = class {
|
|
|
469
496
|
}
|
|
470
497
|
}, _class);
|
|
471
498
|
|
|
499
|
+
// src/provider-proxy/identity/claudeCodeHeaders.ts
|
|
500
|
+
var DEFAULT_ANTHROPIC_VERSION = "2023-06-01";
|
|
501
|
+
var OAUTH_BETA = "oauth-2025-04-20";
|
|
502
|
+
var CLAUDE_CODE_BETA = "claude-code-20250219";
|
|
503
|
+
var INTERLEAVED_THINKING_BETA = "interleaved-thinking-2025-05-14";
|
|
504
|
+
var TOOL_STREAMING_BETA = "fine-grained-tool-streaming-2025-05-14";
|
|
505
|
+
var DEFAULT_CLAUDE_CODE_HEADERS = Object.freeze({
|
|
506
|
+
"user-agent": "claude-cli/1.0.119 (external, cli)",
|
|
507
|
+
"x-app": "cli",
|
|
508
|
+
accept: "application/json",
|
|
509
|
+
"accept-language": "*",
|
|
510
|
+
"sec-fetch-mode": "cors",
|
|
511
|
+
"anthropic-dangerous-direct-browser-access": "true",
|
|
512
|
+
"x-stainless-lang": "js",
|
|
513
|
+
"x-stainless-package-version": "0.55.1",
|
|
514
|
+
"x-stainless-os": "Windows",
|
|
515
|
+
"x-stainless-arch": "x64",
|
|
516
|
+
"x-stainless-runtime": "node",
|
|
517
|
+
"x-stainless-runtime-version": "v20.19.2",
|
|
518
|
+
"x-stainless-retry-count": "0",
|
|
519
|
+
"x-stainless-timeout": "60"
|
|
520
|
+
});
|
|
521
|
+
var FORCED_ACCEPT_ENCODING = "identity";
|
|
522
|
+
var CLAUDE_FORWARD_ALLOWLIST = /* @__PURE__ */ new Set([
|
|
523
|
+
"accept",
|
|
524
|
+
"accept-language",
|
|
525
|
+
"sec-fetch-mode",
|
|
526
|
+
"user-agent",
|
|
527
|
+
"x-app",
|
|
528
|
+
"anthropic-dangerous-direct-browser-access",
|
|
529
|
+
"anthropic-version"
|
|
530
|
+
]);
|
|
531
|
+
var STAINLESS_PREFIX = "x-stainless-";
|
|
532
|
+
function extractClaudeClientHeaders(reqHeaders) {
|
|
533
|
+
const out = {};
|
|
534
|
+
for (const [rawKey, rawVal] of Object.entries(reqHeaders)) {
|
|
535
|
+
const key = rawKey.toLowerCase();
|
|
536
|
+
if (_chunk3SCOLIPTcjs.NEVER_FORWARD_HEADERS.has(key)) continue;
|
|
537
|
+
if (!CLAUDE_FORWARD_ALLOWLIST.has(key) && !key.startsWith(STAINLESS_PREFIX)) continue;
|
|
538
|
+
const value = _chunk3SCOLIPTcjs.flattenHeaderValue.call(void 0, rawVal);
|
|
539
|
+
if (value !== void 0) out[key] = value;
|
|
540
|
+
}
|
|
541
|
+
return out;
|
|
542
|
+
}
|
|
543
|
+
function buildAnthropicBeta(model, callerBeta) {
|
|
544
|
+
const isHaiku = typeof model === "string" && model.toLowerCase().includes("haiku");
|
|
545
|
+
const baseline = isHaiku ? [OAUTH_BETA, INTERLEAVED_THINKING_BETA] : [CLAUDE_CODE_BETA, OAUTH_BETA, INTERLEAVED_THINKING_BETA, TOOL_STREAMING_BETA];
|
|
546
|
+
const seen = /* @__PURE__ */ new Set();
|
|
547
|
+
const out = [];
|
|
548
|
+
const add = (flag) => {
|
|
549
|
+
const trimmed = flag.trim();
|
|
550
|
+
if (!trimmed || seen.has(trimmed)) return;
|
|
551
|
+
seen.add(trimmed);
|
|
552
|
+
out.push(trimmed);
|
|
553
|
+
};
|
|
554
|
+
baseline.forEach(add);
|
|
555
|
+
if (callerBeta) callerBeta.split(",").forEach(add);
|
|
556
|
+
return out.join(",");
|
|
557
|
+
}
|
|
558
|
+
|
|
472
559
|
// src/provider-proxy/usage/recordAnthropicUsage.ts
|
|
473
560
|
function readAnthropicUsage(usage) {
|
|
474
561
|
if (!usage) return null;
|
|
@@ -486,48 +573,61 @@ function readAnthropicUsage(usage) {
|
|
|
486
573
|
reasoningTokens: 0
|
|
487
574
|
};
|
|
488
575
|
}
|
|
576
|
+
function emitAnthropicUsageRecord(recorder, rawUsage, attribution) {
|
|
577
|
+
const tapped = readAnthropicUsage(rawUsage);
|
|
578
|
+
if (!tapped) return;
|
|
579
|
+
recorder.record({
|
|
580
|
+
messageId: null,
|
|
581
|
+
parentMessageId: null,
|
|
582
|
+
sessionId: attribution.sessionId,
|
|
583
|
+
providerId: attribution.providerId,
|
|
584
|
+
model: attribution.model,
|
|
585
|
+
apiKeyId: attribution.apiKeyId,
|
|
586
|
+
auditResponse: attribution.auditResponse,
|
|
587
|
+
engineOrigin: "codex-ingress",
|
|
588
|
+
usage: tapped,
|
|
589
|
+
rawUsage
|
|
590
|
+
});
|
|
591
|
+
}
|
|
489
592
|
function recordAnthropicNonStreamUsage(recorder, bodyText, attribution) {
|
|
490
593
|
try {
|
|
491
594
|
const parsed = JSON.parse(bodyText);
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
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
|
-
});
|
|
595
|
+
emitAnthropicUsageRecord(
|
|
596
|
+
recorder,
|
|
597
|
+
parsed.usage,
|
|
598
|
+
attribution
|
|
599
|
+
);
|
|
506
600
|
} catch (e4) {
|
|
507
601
|
}
|
|
508
602
|
}
|
|
603
|
+
function recordAnthropicStreamUsage(recorder, rawUsage, attribution) {
|
|
604
|
+
try {
|
|
605
|
+
emitAnthropicUsageRecord(recorder, rawUsage, attribution);
|
|
606
|
+
} catch (e5) {
|
|
607
|
+
}
|
|
608
|
+
}
|
|
509
609
|
|
|
510
610
|
// src/provider-proxy/ingress/providerProxyShared.ts
|
|
511
611
|
var sharedExecutor = null;
|
|
512
612
|
function getSharedExecutor() {
|
|
513
613
|
if (!sharedExecutor) {
|
|
514
|
-
sharedExecutor = new (0,
|
|
614
|
+
sharedExecutor = new (0, _chunkIIRPUVPHcjs.TransformerChainExecutor)();
|
|
515
615
|
}
|
|
516
616
|
return sharedExecutor;
|
|
517
617
|
}
|
|
518
618
|
var sharedResponses = null;
|
|
519
619
|
function getResponsesEndpointTransformer() {
|
|
520
|
-
if (!sharedResponses) sharedResponses = new (0,
|
|
620
|
+
if (!sharedResponses) sharedResponses = new (0, _chunkOVQBNVSVcjs.OpenAIResponseTransformer)();
|
|
521
621
|
return sharedResponses;
|
|
522
622
|
}
|
|
523
623
|
var sharedAnthropic = null;
|
|
524
624
|
function getAnthropicEndpointTransformer() {
|
|
525
|
-
if (!sharedAnthropic) sharedAnthropic = new (0,
|
|
625
|
+
if (!sharedAnthropic) sharedAnthropic = new (0, _chunkOXHNSZ53cjs.AnthropicTransformer)();
|
|
526
626
|
return sharedAnthropic;
|
|
527
627
|
}
|
|
528
628
|
var sharedGemini = null;
|
|
529
629
|
function getGeminiEndpointTransformer() {
|
|
530
|
-
if (!sharedGemini) sharedGemini = new (0,
|
|
630
|
+
if (!sharedGemini) sharedGemini = new (0, _chunkV4TXMEJScjs.GeminiTransformer)();
|
|
531
631
|
return sharedGemini;
|
|
532
632
|
}
|
|
533
633
|
function readBody(req) {
|
|
@@ -553,7 +653,7 @@ function rewriteJsonModel(bodyText, rewriteModel) {
|
|
|
553
653
|
changed = true;
|
|
554
654
|
}
|
|
555
655
|
return changed ? JSON.stringify(obj) : bodyText;
|
|
556
|
-
} catch (
|
|
656
|
+
} catch (e6) {
|
|
557
657
|
return bodyText;
|
|
558
658
|
}
|
|
559
659
|
}
|
|
@@ -586,11 +686,22 @@ function rewriteSseLine(line, rewriteModel) {
|
|
|
586
686
|
}
|
|
587
687
|
if (!changed) return line;
|
|
588
688
|
return `data:${leadingSpace}${JSON.stringify(obj)}${newline}`;
|
|
589
|
-
} catch (
|
|
689
|
+
} catch (e7) {
|
|
590
690
|
return line;
|
|
591
691
|
}
|
|
592
692
|
}
|
|
593
|
-
|
|
693
|
+
function tapSseDataLine(line, onEvent) {
|
|
694
|
+
const leadingStripped = line.replace(/^\s+/, "");
|
|
695
|
+
if (!leadingStripped.startsWith("data:")) return;
|
|
696
|
+
const payload = leadingStripped.slice(5).trim();
|
|
697
|
+
if (!payload || payload === "[DONE]") return;
|
|
698
|
+
try {
|
|
699
|
+
onEvent(JSON.parse(payload));
|
|
700
|
+
} catch (e8) {
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
async function relaySseBody(res, body, options) {
|
|
704
|
+
const { rewriteModel, onSseEvent } = options;
|
|
594
705
|
const reader = body.getReader();
|
|
595
706
|
const decoder = new TextDecoder();
|
|
596
707
|
let buffer = "";
|
|
@@ -604,21 +715,26 @@ async function relayStreamWithModelRewrite(res, body, rewriteModel) {
|
|
|
604
715
|
while ((nlIndex = buffer.indexOf("\n")) !== -1) {
|
|
605
716
|
const linePart = buffer.slice(0, nlIndex + 1);
|
|
606
717
|
buffer = buffer.slice(nlIndex + 1);
|
|
607
|
-
|
|
718
|
+
if (onSseEvent) tapSseDataLine(linePart, onSseEvent);
|
|
719
|
+
out += rewriteModel ? rewriteSseLine(linePart, rewriteModel) : linePart;
|
|
608
720
|
}
|
|
609
721
|
if (out) res.write(out);
|
|
610
722
|
}
|
|
611
723
|
const tail = buffer + decoder.decode();
|
|
612
|
-
if (tail)
|
|
724
|
+
if (tail) {
|
|
725
|
+
if (onSseEvent) tapSseDataLine(tail, onSseEvent);
|
|
726
|
+
res.write(rewriteModel ? rewriteSseLine(tail, rewriteModel) : tail);
|
|
727
|
+
}
|
|
613
728
|
} finally {
|
|
614
729
|
reader.releaseLock();
|
|
615
730
|
res.end();
|
|
616
731
|
}
|
|
617
732
|
}
|
|
618
|
-
async function relayResponse(res, providerResponse, isStream, rewriteModel) {
|
|
733
|
+
async function relayResponse(res, providerResponse, isStream, rewriteModel, usageTap, onSseEvent) {
|
|
619
734
|
const contentType = _nullishCoalesce(providerResponse.headers.get("Content-Type"), () => ( ""));
|
|
620
735
|
const status = providerResponse.status && providerResponse.status >= 100 ? providerResponse.status : 200;
|
|
621
|
-
|
|
736
|
+
const upstreamIsSse = contentType.includes("text/event-stream");
|
|
737
|
+
if (upstreamIsSse || isStream && status < 400) {
|
|
622
738
|
res.writeHead(status, {
|
|
623
739
|
"Content-Type": "text/event-stream",
|
|
624
740
|
"Cache-Control": "no-cache",
|
|
@@ -628,8 +744,19 @@ async function relayResponse(res, providerResponse, isStream, rewriteModel) {
|
|
|
628
744
|
res.end();
|
|
629
745
|
return null;
|
|
630
746
|
}
|
|
631
|
-
if (rewriteModel) {
|
|
632
|
-
|
|
747
|
+
if (rewriteModel || usageTap || onSseEvent) {
|
|
748
|
+
let capturedUsage = null;
|
|
749
|
+
await relaySseBody(res, providerResponse.body, {
|
|
750
|
+
rewriteModel,
|
|
751
|
+
onSseEvent: onSseEvent || usageTap ? (event) => {
|
|
752
|
+
_optionalChain([onSseEvent, 'optionalCall', _8 => _8(event)]);
|
|
753
|
+
if (usageTap) {
|
|
754
|
+
const raw = usageTap.extractUsage(event);
|
|
755
|
+
if (raw) capturedUsage = raw;
|
|
756
|
+
}
|
|
757
|
+
} : void 0
|
|
758
|
+
});
|
|
759
|
+
if (capturedUsage) usageTap.onUsage(capturedUsage);
|
|
633
760
|
return null;
|
|
634
761
|
}
|
|
635
762
|
const reader = providerResponse.body.getReader();
|
|
@@ -670,7 +797,7 @@ async function aggregateAnthropicSseToJsonBody(response, rewriteModel) {
|
|
|
670
797
|
let ev;
|
|
671
798
|
try {
|
|
672
799
|
ev = JSON.parse(payload);
|
|
673
|
-
} catch (
|
|
800
|
+
} catch (e9) {
|
|
674
801
|
continue;
|
|
675
802
|
}
|
|
676
803
|
switch (ev["type"]) {
|
|
@@ -725,7 +852,7 @@ async function aggregateAnthropicSseToJsonBody(response, rewriteModel) {
|
|
|
725
852
|
let input = {};
|
|
726
853
|
try {
|
|
727
854
|
input = blk.inputJson ? JSON.parse(blk.inputJson) : {};
|
|
728
|
-
} catch (
|
|
855
|
+
} catch (e10) {
|
|
729
856
|
input = {};
|
|
730
857
|
}
|
|
731
858
|
return { type: "tool_use", id: _nullishCoalesce(blk.id, () => ( "")), name: _nullishCoalesce(blk.name, () => ( "")), input };
|
|
@@ -745,6 +872,27 @@ function writeError(res, status, message) {
|
|
|
745
872
|
res.writeHead(status, { "Content-Type": "application/json" });
|
|
746
873
|
res.end(JSON.stringify({ error: { type: "provider_proxy_error", message } }));
|
|
747
874
|
}
|
|
875
|
+
function writeBoundAccountError(res, error) {
|
|
876
|
+
if (res.headersSent) return;
|
|
877
|
+
const headers = { "Content-Type": "application/json" };
|
|
878
|
+
if (error.status === 429 && error.resumeAt) {
|
|
879
|
+
const resumeMs = Date.parse(error.resumeAt);
|
|
880
|
+
if (Number.isFinite(resumeMs)) {
|
|
881
|
+
headers["Retry-After"] = String(Math.max(1, Math.ceil((resumeMs - Date.now()) / 1e3)));
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
res.writeHead(error.status, headers);
|
|
885
|
+
res.end(
|
|
886
|
+
JSON.stringify({
|
|
887
|
+
error: {
|
|
888
|
+
type: "provider_proxy_error",
|
|
889
|
+
code: error.code,
|
|
890
|
+
reason: error.reason,
|
|
891
|
+
message: _chunk25GXJCEZcjs.boundAccountSelectionMessage.call(void 0, error.reason)
|
|
892
|
+
}
|
|
893
|
+
})
|
|
894
|
+
);
|
|
895
|
+
}
|
|
748
896
|
function resolveApiKey(apiKey) {
|
|
749
897
|
if (!apiKey) return "";
|
|
750
898
|
if (apiKey.startsWith("$")) {
|
|
@@ -752,7 +900,12 @@ function resolveApiKey(apiKey) {
|
|
|
752
900
|
}
|
|
753
901
|
return apiKey;
|
|
754
902
|
}
|
|
755
|
-
async function resolvePoolBoundKey(deps, providerId, provider, sessionId) {
|
|
903
|
+
async function resolvePoolBoundKey(deps, providerId, provider, sessionId, preferredKeyId, boundKeyFallbackPolicy) {
|
|
904
|
+
if (preferredKeyId) {
|
|
905
|
+
const preferred = await _optionalChain([deps, 'access', _9 => _9.apiKeyPool, 'optionalAccess', _10 => _10.getKeyById, 'call', _11 => _11(providerId, preferredKeyId, sessionId)]);
|
|
906
|
+
if (preferred) return preferred;
|
|
907
|
+
if (boundKeyFallbackPolicy !== "pool") return "";
|
|
908
|
+
}
|
|
756
909
|
if (deps.apiKeyPool && sessionId) {
|
|
757
910
|
const poolKey = await deps.apiKeyPool.getKeyForSession(providerId, sessionId);
|
|
758
911
|
if (poolKey) return poolKey;
|
|
@@ -775,7 +928,7 @@ async function buildSubscriptionPlan(res, route, deps, anthropicBody, routeModel
|
|
|
775
928
|
resolvedModel = mapped.resolvedModel;
|
|
776
929
|
scenario = mapped.scenario;
|
|
777
930
|
}
|
|
778
|
-
const sessionKey =
|
|
931
|
+
const sessionKey = _chunkJ3QQ6JS5cjs.deriveSubscriptionSessionKey.call(void 0, anthropicBody);
|
|
779
932
|
const plan = buildSubscriptionIterationPlan(profile, route, deps, resolvedModel, isStream, scenario, sessionKey);
|
|
780
933
|
if (!plan) {
|
|
781
934
|
writeError(res, 502, "Subscription profile is missing resolveUpstreamUrl");
|
|
@@ -784,11 +937,11 @@ async function buildSubscriptionPlan(res, route, deps, anthropicBody, routeModel
|
|
|
784
937
|
return plan;
|
|
785
938
|
}
|
|
786
939
|
function buildSubscriptionIterationPlan(profile, route, deps, resolvedModel, isStream, scenario, sessionKey) {
|
|
787
|
-
const upstreamUrl = _optionalChain([profile, 'access',
|
|
940
|
+
const upstreamUrl = _optionalChain([profile, 'access', _12 => _12.resolveUpstreamUrl, 'optionalCall', _13 => _13(resolvedModel, route.subscriptionConfig)]);
|
|
788
941
|
if (!upstreamUrl) return null;
|
|
789
|
-
const auth = _nullishCoalesce(route.auth, () => ( new (0,
|
|
942
|
+
const auth = _nullishCoalesce(route.auth, () => ( new (0, _chunkYNJNTCSQcjs.SubscriptionAuthSource)(profile)));
|
|
790
943
|
const sameFormat = profile.mode === "pass-through" || upstreamUrl.endsWith("/v1/messages");
|
|
791
|
-
const overrideNames = _optionalChain([profile, 'access',
|
|
944
|
+
const overrideNames = _optionalChain([profile, 'access', _14 => _14.resolveProviderTransformerNames, 'optionalCall', _15 => _15(
|
|
792
945
|
resolvedModel,
|
|
793
946
|
route.subscriptionConfig
|
|
794
947
|
)]);
|
|
@@ -807,6 +960,8 @@ function buildSubscriptionIterationPlan(profile, route, deps, resolvedModel, isS
|
|
|
807
960
|
return {
|
|
808
961
|
auth,
|
|
809
962
|
preferredAccountId: route.preferredAccountId,
|
|
963
|
+
preferredAccountGroup: route.preferredAccountGroup,
|
|
964
|
+
boundAccountFallbackPolicy: route.boundAccountFallbackPolicy,
|
|
810
965
|
chain,
|
|
811
966
|
transformerProvider,
|
|
812
967
|
resolvedModel,
|
|
@@ -851,7 +1006,7 @@ function buildSubscriptionRequestSummary(anthropicBody) {
|
|
|
851
1006
|
estimatedInputTokens: Math.ceil(totalChars / 4),
|
|
852
1007
|
// Single source of truth (shared with the dispatcher builder) so both
|
|
853
1008
|
// ingress paths yield identical `matchText` for the same body.
|
|
854
|
-
matchText:
|
|
1009
|
+
matchText: _chunkJ3QQ6JS5cjs.collectMatchText.call(void 0, anthropicBody)
|
|
855
1010
|
};
|
|
856
1011
|
}
|
|
857
1012
|
function collectText(value) {
|
|
@@ -881,13 +1036,15 @@ async function runPipeline(anthropicBody, plan, reportSelection) {
|
|
|
881
1036
|
model: resolvedModel,
|
|
882
1037
|
sessionKey: plan.sessionKey,
|
|
883
1038
|
preferredAccountId: plan.preferredAccountId,
|
|
1039
|
+
preferredAccountGroup: plan.preferredAccountGroup,
|
|
1040
|
+
boundAccountFallbackPolicy: plan.boundAccountFallbackPolicy,
|
|
884
1041
|
reportSelection: (accountId, isActive) => {
|
|
885
1042
|
proxyAccountId = accountId;
|
|
886
|
-
_optionalChain([reportSelection, 'optionalCall',
|
|
1043
|
+
_optionalChain([reportSelection, 'optionalCall', _16 => _16(accountId, isActive)]);
|
|
887
1044
|
}
|
|
888
1045
|
});
|
|
889
1046
|
let rawStatus = null;
|
|
890
|
-
const { response } = await
|
|
1047
|
+
const { response } = await _chunkMUHWHQVMcjs.executeProviderCall.call(void 0, {
|
|
891
1048
|
executor,
|
|
892
1049
|
request: anthropicBody,
|
|
893
1050
|
provider: transformerProvider,
|
|
@@ -905,10 +1062,19 @@ async function runPipeline(anthropicBody, plan, reportSelection) {
|
|
|
905
1062
|
},
|
|
906
1063
|
fetchFn: (url, headers, body) => {
|
|
907
1064
|
console.info(`[ProviderProxy:anthropic] -> ${url} model=${resolvedModel} stream=${isStream}`);
|
|
908
|
-
return
|
|
1065
|
+
return _chunkRJUONLUQcjs.fetchUpstream.call(void 0,
|
|
909
1066
|
url,
|
|
910
1067
|
{ method: "POST", headers, body: JSON.stringify(body) },
|
|
911
|
-
{
|
|
1068
|
+
{
|
|
1069
|
+
providerId: proxyProviderId(plan),
|
|
1070
|
+
accountId: proxyAccountId,
|
|
1071
|
+
routeActivity: plan.isSubscription ? {
|
|
1072
|
+
endpoint: "messages",
|
|
1073
|
+
sessionKey: plan.sessionKey,
|
|
1074
|
+
sessionSource: plan.sessionKey ? "content-fingerprint" : "none",
|
|
1075
|
+
model: resolvedModel
|
|
1076
|
+
} : void 0
|
|
1077
|
+
}
|
|
912
1078
|
).then((r) => {
|
|
913
1079
|
rawStatus = r.status;
|
|
914
1080
|
return r;
|
|
@@ -927,13 +1093,16 @@ async function runSubscriptionSameFormatFetch(rawBody, plan, reportSelection, op
|
|
|
927
1093
|
model: plan.resolvedModel,
|
|
928
1094
|
sessionKey: plan.sessionKey,
|
|
929
1095
|
preferredAccountId: plan.preferredAccountId,
|
|
1096
|
+
preferredAccountGroup: plan.preferredAccountGroup,
|
|
1097
|
+
boundAccountFallbackPolicy: plan.boundAccountFallbackPolicy,
|
|
930
1098
|
reportSelection: (accountId, isActive, remapped) => {
|
|
931
1099
|
proxyAccountId = accountId;
|
|
932
1100
|
remappedModel = remapped;
|
|
933
|
-
_optionalChain([reportSelection, 'optionalCall',
|
|
1101
|
+
_optionalChain([reportSelection, 'optionalCall', _17 => _17(accountId, isActive, remapped)]);
|
|
934
1102
|
}
|
|
935
1103
|
});
|
|
936
|
-
|
|
1104
|
+
const isClaudeSubscription = plan.isSubscription && plan.transformerProvider.name === "claude";
|
|
1105
|
+
if (isClaudeSubscription) {
|
|
937
1106
|
_chunk6RPZADX3cjs.applyFingerprint.call(void 0,
|
|
938
1107
|
_chunkRPII3E6Zcjs.getSharedIdentityStore.call(void 0, ),
|
|
939
1108
|
headers,
|
|
@@ -942,16 +1111,36 @@ async function runSubscriptionSameFormatFetch(rawBody, plan, reportSelection, op
|
|
|
942
1111
|
options.callerIdentity
|
|
943
1112
|
);
|
|
944
1113
|
}
|
|
1114
|
+
if (isClaudeSubscription) {
|
|
1115
|
+
_chunk3SCOLIPTcjs.fillMissingHeaders.call(void 0, headers, _nullishCoalesce(options.callerClientHeaders, () => ( {})));
|
|
1116
|
+
_chunk3SCOLIPTcjs.fillMissingHeaders.call(void 0, headers, DEFAULT_CLAUDE_CODE_HEADERS);
|
|
1117
|
+
}
|
|
1118
|
+
_chunk3SCOLIPTcjs.fillMissingHeaders.call(void 0, headers, { "anthropic-version": DEFAULT_ANTHROPIC_VERSION });
|
|
1119
|
+
headers["accept-encoding"] = FORCED_ACCEPT_ENCODING;
|
|
945
1120
|
const applyRemap = remappedModel !== void 0 && outboundRemapApplies(plan);
|
|
946
1121
|
const outboundBody = applyRemap ? rewriteBodyModel(rawBody, remappedModel) : rawBody;
|
|
947
1122
|
const outboundModel = applyRemap ? remappedModel : plan.resolvedModel;
|
|
1123
|
+
if (isClaudeSubscription) {
|
|
1124
|
+
headers["anthropic-beta"] = buildAnthropicBeta(outboundModel, options.callerAnthropicBeta);
|
|
1125
|
+
} else if (options.callerAnthropicBeta) {
|
|
1126
|
+
_chunk3SCOLIPTcjs.fillMissingHeaders.call(void 0, headers, { "anthropic-beta": options.callerAnthropicBeta });
|
|
1127
|
+
}
|
|
948
1128
|
console.info(
|
|
949
1129
|
`[ProviderProxy:anthropic] (subscription same-format) -> ${plan.upstreamUrl} model=${outboundModel} stream=${plan.isStream}`
|
|
950
1130
|
);
|
|
951
|
-
const response = await
|
|
1131
|
+
const response = await _chunkRJUONLUQcjs.fetchUpstream.call(void 0,
|
|
952
1132
|
plan.upstreamUrl,
|
|
953
1133
|
{ method: "POST", headers, body: outboundBody },
|
|
954
|
-
{
|
|
1134
|
+
{
|
|
1135
|
+
providerId: proxyProviderId(plan),
|
|
1136
|
+
accountId: proxyAccountId,
|
|
1137
|
+
routeActivity: plan.isSubscription ? {
|
|
1138
|
+
endpoint: "messages",
|
|
1139
|
+
sessionKey: plan.sessionKey,
|
|
1140
|
+
sessionSource: plan.sessionKey ? "content-fingerprint" : "none",
|
|
1141
|
+
model: outboundModel
|
|
1142
|
+
} : void 0
|
|
1143
|
+
}
|
|
955
1144
|
);
|
|
956
1145
|
return { response, rawStatus: response.status };
|
|
957
1146
|
}
|
|
@@ -964,7 +1153,7 @@ function rewriteBodyModel(rawBody, model) {
|
|
|
964
1153
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return rawBody;
|
|
965
1154
|
parsed.model = model;
|
|
966
1155
|
return JSON.stringify(parsed);
|
|
967
|
-
} catch (
|
|
1156
|
+
} catch (e11) {
|
|
968
1157
|
return rawBody;
|
|
969
1158
|
}
|
|
970
1159
|
}
|
|
@@ -977,7 +1166,7 @@ async function runSubscriptionAttemptWith401Retry(anthropicBody, relayBody, plan
|
|
|
977
1166
|
const first = await runOnce();
|
|
978
1167
|
let result = first;
|
|
979
1168
|
if (first.rawStatus === 401) {
|
|
980
|
-
const refreshed = await _optionalChain([plan, 'access',
|
|
1169
|
+
const refreshed = await _optionalChain([plan, 'access', _18 => _18.auth, 'access', _19 => _19.onUnauthorized, 'optionalCall', _20 => _20(plan.sessionKey)]);
|
|
981
1170
|
if (refreshed) {
|
|
982
1171
|
console.info("[ProviderProxy:anthropic] 401 \u2192 token refreshed; retrying once");
|
|
983
1172
|
result = await runOnce();
|
|
@@ -992,7 +1181,7 @@ async function readBoundedBody(response, max = 2048) {
|
|
|
992
1181
|
try {
|
|
993
1182
|
const text = await response.clone().text();
|
|
994
1183
|
return text.slice(0, max);
|
|
995
|
-
} catch (
|
|
1184
|
+
} catch (e12) {
|
|
996
1185
|
return void 0;
|
|
997
1186
|
}
|
|
998
1187
|
}
|
|
@@ -1000,9 +1189,9 @@ async function markSubscriptionHealth(plan, selectedAccountId, result) {
|
|
|
1000
1189
|
if (!plan.isSubscription || selectedAccountId === void 0) return;
|
|
1001
1190
|
const providerId = plan.transformerProvider.name;
|
|
1002
1191
|
const status = result.rawStatus;
|
|
1003
|
-
const { resetHeaderSeconds, retryAfterSeconds } =
|
|
1192
|
+
const { resetHeaderSeconds, retryAfterSeconds } = _chunkYWL7YZWScjs.resolveResetSeconds.call(void 0, providerId, result.response.headers);
|
|
1004
1193
|
const bodyText = status === 403 ? await readBoundedBody(result.response) : void 0;
|
|
1005
|
-
|
|
1194
|
+
_chunkYWL7YZWScjs.getSharedAccountHealth.call(void 0, ).recordUpstreamOutcome(providerId, selectedAccountId, {
|
|
1006
1195
|
status,
|
|
1007
1196
|
resetHeaderSeconds,
|
|
1008
1197
|
retryAfterSeconds,
|
|
@@ -1020,7 +1209,7 @@ function breakerOutcome(rawStatus) {
|
|
|
1020
1209
|
function recordBreakerOutcome(profile, modelId, rawStatus) {
|
|
1021
1210
|
const outcome = breakerOutcome(rawStatus);
|
|
1022
1211
|
if (outcome === "neutral") return;
|
|
1023
|
-
_optionalChain([profile, 'optionalAccess',
|
|
1212
|
+
_optionalChain([profile, 'optionalAccess', _21 => _21.recordModelOutcome, 'optionalCall', _22 => _22(modelId, outcome === "success")]);
|
|
1024
1213
|
}
|
|
1025
1214
|
async function runSubscriptionAttemptOutcome(anthropicBody, relayBody, plan, options = {}) {
|
|
1026
1215
|
try {
|
|
@@ -1039,7 +1228,7 @@ function settleOutcome(outcome) {
|
|
|
1039
1228
|
async function runPipelineWithSubscriptionRetry(anthropicBody, rawBody, initialPlan, route, deps, options = {}) {
|
|
1040
1229
|
const profile = route.subscriptionProfile;
|
|
1041
1230
|
const scenario = initialPlan.scenario;
|
|
1042
|
-
if (!_optionalChain([profile, 'optionalAccess',
|
|
1231
|
+
if (!_optionalChain([profile, 'optionalAccess', _23 => _23.nextFallback]) || scenario === void 0) {
|
|
1043
1232
|
const loneOutcome = await runSubscriptionAttemptOutcome(anthropicBody, rawBody, initialPlan, options);
|
|
1044
1233
|
recordBreakerOutcome(profile, initialPlan.resolvedModel, outcomeStatus(loneOutcome));
|
|
1045
1234
|
return settleOutcome(loneOutcome);
|
|
@@ -1103,7 +1292,7 @@ async function handleAnthropicMessagesByo(res, rawBody, route, deps, options = {
|
|
|
1103
1292
|
let anthropicBody;
|
|
1104
1293
|
try {
|
|
1105
1294
|
anthropicBody = JSON.parse(rawBody);
|
|
1106
|
-
} catch (
|
|
1295
|
+
} catch (e13) {
|
|
1107
1296
|
writeError(res, 400, "Invalid JSON in request body");
|
|
1108
1297
|
return;
|
|
1109
1298
|
}
|
|
@@ -1119,6 +1308,35 @@ async function handleAnthropicMessagesByo(res, rawBody, route, deps, options = {
|
|
|
1119
1308
|
const upstreamSse = (_nullishCoalesce(upstreamResponse.headers.get("content-type"), () => ( ""))).includes(
|
|
1120
1309
|
"text/event-stream"
|
|
1121
1310
|
);
|
|
1311
|
+
const usageAttribution = {
|
|
1312
|
+
sessionId: route.sessionId,
|
|
1313
|
+
providerId: _nullishCoalesce(route.providerId, () => ( "anthropic")),
|
|
1314
|
+
model: plan.resolvedModel,
|
|
1315
|
+
apiKeyId: _nullishCoalesce(route.apiKeyId, () => ( null)),
|
|
1316
|
+
// request-audit-log: correlate this request's tokens/cost to its audit record.
|
|
1317
|
+
auditResponse: res
|
|
1318
|
+
};
|
|
1319
|
+
const usageRecorder = deps.usageRecorder;
|
|
1320
|
+
let anthropicInputUsage;
|
|
1321
|
+
const usageTap = usageRecorder ? {
|
|
1322
|
+
extractUsage(event) {
|
|
1323
|
+
if (event["type"] === "message_start") {
|
|
1324
|
+
const msg = event["message"];
|
|
1325
|
+
const u = _optionalChain([msg, 'optionalAccess', _24 => _24["usage"]]);
|
|
1326
|
+
if (u) anthropicInputUsage = u;
|
|
1327
|
+
return null;
|
|
1328
|
+
}
|
|
1329
|
+
if (event["type"] === "message_delta") {
|
|
1330
|
+
const outputUsage = event["usage"];
|
|
1331
|
+
if (!outputUsage) return null;
|
|
1332
|
+
return { ...anthropicInputUsage, ...outputUsage };
|
|
1333
|
+
}
|
|
1334
|
+
return null;
|
|
1335
|
+
},
|
|
1336
|
+
onUsage(rawUsage) {
|
|
1337
|
+
recordAnthropicStreamUsage(usageRecorder, rawUsage, usageAttribution);
|
|
1338
|
+
}
|
|
1339
|
+
} : void 0;
|
|
1122
1340
|
let bodyText;
|
|
1123
1341
|
if (!isStream && upstreamSse) {
|
|
1124
1342
|
bodyText = await aggregateAnthropicSseToJsonBody(upstreamResponse, route.requestedModel);
|
|
@@ -1128,22 +1346,19 @@ async function handleAnthropicMessagesByo(res, rawBody, route, deps, options = {
|
|
|
1128
1346
|
);
|
|
1129
1347
|
res.end(bodyText);
|
|
1130
1348
|
} else {
|
|
1131
|
-
bodyText = await relayResponse(res, upstreamResponse, isStream, route.requestedModel);
|
|
1349
|
+
bodyText = await relayResponse(res, upstreamResponse, isStream, route.requestedModel, usageTap);
|
|
1132
1350
|
}
|
|
1133
1351
|
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
|
-
});
|
|
1352
|
+
recordAnthropicNonStreamUsage(deps.usageRecorder, bodyText, usageAttribution);
|
|
1142
1353
|
}
|
|
1143
1354
|
} catch (err) {
|
|
1355
|
+
if (_chunk25GXJCEZcjs.isBoundAccountSelectionError.call(void 0, err)) {
|
|
1356
|
+
writeBoundAccountError(res, err);
|
|
1357
|
+
return;
|
|
1358
|
+
}
|
|
1144
1359
|
const errMsg = _chunkSVNDB62Dcjs.serializeError.call(void 0, err);
|
|
1145
1360
|
console.error("[ProviderProxy:anthropic] Pipeline error:", errMsg);
|
|
1146
|
-
writeError(res, 502, errMsg);
|
|
1361
|
+
writeError(res, _chunk6QQG7YG3cjs.isAccountAllowanceExhaustedError.call(void 0, err) ? 429 : 502, errMsg);
|
|
1147
1362
|
}
|
|
1148
1363
|
}
|
|
1149
1364
|
async function buildByoPlan(res, route, deps, resolvedModel, isStream) {
|
|
@@ -1157,7 +1372,14 @@ async function buildByoPlan(res, route, deps, resolvedModel, isStream) {
|
|
|
1157
1372
|
writeError(res, 502, `Provider not found: ${providerId}`);
|
|
1158
1373
|
return null;
|
|
1159
1374
|
}
|
|
1160
|
-
const apiKey = await resolvePoolBoundKey(
|
|
1375
|
+
const apiKey = await resolvePoolBoundKey(
|
|
1376
|
+
deps,
|
|
1377
|
+
providerId,
|
|
1378
|
+
provider,
|
|
1379
|
+
route.sessionId,
|
|
1380
|
+
route.preferredKeyId,
|
|
1381
|
+
route.boundKeyFallbackPolicy
|
|
1382
|
+
);
|
|
1161
1383
|
if (!apiKey) {
|
|
1162
1384
|
writeError(res, 502, "API key not configured");
|
|
1163
1385
|
return null;
|
|
@@ -1190,7 +1412,7 @@ async function buildByoPlan(res, route, deps, resolvedModel, isStream) {
|
|
|
1190
1412
|
isSubscription: false,
|
|
1191
1413
|
provider,
|
|
1192
1414
|
apiKey,
|
|
1193
|
-
extendedContextEnabled: _nullishCoalesce(_optionalChain([route, 'access',
|
|
1415
|
+
extendedContextEnabled: _nullishCoalesce(_optionalChain([route, 'access', _25 => _25.anthropicSdkHints, 'optionalAccess', _26 => _26.extendedContext, 'optionalAccess', _27 => _27.enabled]), () => ( false))
|
|
1194
1416
|
};
|
|
1195
1417
|
}
|
|
1196
1418
|
async function runSameFormatFetch(bodyToSend, plan, options, keyOverride) {
|
|
@@ -1200,7 +1422,7 @@ async function runSameFormatFetch(bodyToSend, plan, options, keyOverride) {
|
|
|
1200
1422
|
}
|
|
1201
1423
|
const effectiveKey = _nullishCoalesce(_nullishCoalesce(keyOverride, () => ( apiKey)), () => ( ""));
|
|
1202
1424
|
const headers = _chunkQ27JY5RGcjs.getProviderHeaders.call(void 0, provider, effectiveKey);
|
|
1203
|
-
const callerBeta = _optionalChain([options, 'access',
|
|
1425
|
+
const callerBeta = _optionalChain([options, 'access', _28 => _28.callerAnthropicBeta, 'optionalAccess', _29 => _29.trim, 'call', _30 => _30()]);
|
|
1204
1426
|
if (callerBeta) {
|
|
1205
1427
|
const existing = _nullishCoalesce(headers["anthropic-beta"], () => ( headers["Anthropic-Beta"]));
|
|
1206
1428
|
const parts = new Set(
|
|
@@ -1214,7 +1436,7 @@ async function runSameFormatFetch(bodyToSend, plan, options, keyOverride) {
|
|
|
1214
1436
|
_chunkGBHYAGX3cjs.injectExtendedContextBeta.call(void 0, headers, resolvedModel, _nullishCoalesce(extendedContextEnabled, () => ( false)));
|
|
1215
1437
|
const url = _chunkA2YMUCBTcjs.buildProviderApiUrl.call(void 0, provider, { model: resolvedModel, stream: isStream });
|
|
1216
1438
|
console.info(`[ProviderProxy:anthropic] (same-format) -> ${url} model=${resolvedModel} stream=${isStream}`);
|
|
1217
|
-
const response = await
|
|
1439
|
+
const response = await _chunkRJUONLUQcjs.fetchUpstream.call(void 0,
|
|
1218
1440
|
url,
|
|
1219
1441
|
{ method: "POST", headers, body: bodyToSend },
|
|
1220
1442
|
{ providerId: "byo" }
|
|
@@ -1226,7 +1448,7 @@ function resolveSameFormatBody(anthropicBody, rawBody, plan) {
|
|
|
1226
1448
|
try {
|
|
1227
1449
|
const m = JSON.parse(rawBody).model;
|
|
1228
1450
|
originalModel = typeof m === "string" ? m : void 0;
|
|
1229
|
-
} catch (
|
|
1451
|
+
} catch (e14) {
|
|
1230
1452
|
originalModel = void 0;
|
|
1231
1453
|
}
|
|
1232
1454
|
return plan.resolvedModel !== originalModel ? JSON.stringify(anthropicBody) : rawBody;
|
|
@@ -1235,8 +1457,8 @@ async function runPipelineWithPoolReporting(anthropicBody, rawBody, plan, option
|
|
|
1235
1457
|
const sameFormatBody = plan.sameFormat ? resolveSameFormatBody(anthropicBody, rawBody, plan) : rawBody;
|
|
1236
1458
|
const runOnce = (keyOverride) => plan.sameFormat ? runSameFormatFetch(sameFormatBody, plan, options, keyOverride) : runPipeline(anthropicBody, plan);
|
|
1237
1459
|
const first = await runOnce();
|
|
1238
|
-
const outcome = await _optionalChain([plan, 'access',
|
|
1239
|
-
if (_optionalChain([outcome, 'optionalAccess',
|
|
1460
|
+
const outcome = await _optionalChain([plan, 'access', _31 => _31.auth, 'access', _32 => _32.onResult, 'optionalCall', _33 => _33(first.rawStatus)]);
|
|
1461
|
+
if (_optionalChain([outcome, 'optionalAccess', _34 => _34.rebound])) {
|
|
1240
1462
|
console.info(
|
|
1241
1463
|
"[ProviderProxy:anthropic] pool re-bound key after status",
|
|
1242
1464
|
first.rawStatus,
|
|
@@ -1258,7 +1480,12 @@ async function handleAnthropicMessagesRequest(req, res, route, deps) {
|
|
|
1258
1480
|
const callerBetaRaw = req.headers["anthropic-beta"];
|
|
1259
1481
|
const callerAnthropicBeta = Array.isArray(callerBetaRaw) ? callerBetaRaw.join(",") : callerBetaRaw;
|
|
1260
1482
|
const callerIdentity = _chunk6RPZADX3cjs.captureCallerIdentity.call(void 0, _chunkRPII3E6Zcjs.getSharedIdentityStore.call(void 0, ), req.headers);
|
|
1261
|
-
|
|
1483
|
+
const callerClientHeaders = extractClaudeClientHeaders(req.headers);
|
|
1484
|
+
await handleAnthropicMessagesByo(res, rawBody, route, deps, {
|
|
1485
|
+
callerAnthropicBeta,
|
|
1486
|
+
callerIdentity,
|
|
1487
|
+
callerClientHeaders
|
|
1488
|
+
});
|
|
1262
1489
|
return;
|
|
1263
1490
|
}
|
|
1264
1491
|
const hints = route.anthropicSdkHints;
|
|
@@ -1270,11 +1497,31 @@ async function handleAnthropicMessagesRequest(req, res, route, deps) {
|
|
|
1270
1497
|
writeError(res, 502, "Anthropic route is missing a providerId");
|
|
1271
1498
|
return;
|
|
1272
1499
|
}
|
|
1500
|
+
let delegatedApiKey = hints.apiKey;
|
|
1501
|
+
if (route.authMode === "byo" && route.providerId) {
|
|
1502
|
+
const provider = await deps.llmConfig.getProvider(route.providerId);
|
|
1503
|
+
if (!provider) {
|
|
1504
|
+
writeError(res, 502, `Provider not found: ${route.providerId}`);
|
|
1505
|
+
return;
|
|
1506
|
+
}
|
|
1507
|
+
delegatedApiKey = await resolvePoolBoundKey(
|
|
1508
|
+
deps,
|
|
1509
|
+
route.providerId,
|
|
1510
|
+
provider,
|
|
1511
|
+
route.sessionId,
|
|
1512
|
+
route.preferredKeyId,
|
|
1513
|
+
route.boundKeyFallbackPolicy
|
|
1514
|
+
);
|
|
1515
|
+
if (!delegatedApiKey) {
|
|
1516
|
+
writeError(res, 502, "API key not configured");
|
|
1517
|
+
return;
|
|
1518
|
+
}
|
|
1519
|
+
}
|
|
1273
1520
|
const handler = handlerFactory({
|
|
1274
1521
|
llmConfig: deps.llmConfig,
|
|
1275
1522
|
providerId: _nullishCoalesce(route.providerId, () => ( "")),
|
|
1276
1523
|
model: route.model,
|
|
1277
|
-
apiKey:
|
|
1524
|
+
apiKey: delegatedApiKey,
|
|
1278
1525
|
backgroundTaskModel: route.backgroundTaskModel,
|
|
1279
1526
|
isOfficialProvider: hints.isOfficialProvider,
|
|
1280
1527
|
thinkingLevel: hints.thinkingLevel,
|
|
@@ -1283,6 +1530,11 @@ async function handleAnthropicMessagesRequest(req, res, route, deps) {
|
|
|
1283
1530
|
passThroughAuthToken: _nullishCoalesce(hints.passThroughAuthToken, () => ( null)),
|
|
1284
1531
|
resolvePassThroughAuthToken: _nullishCoalesce(hints.resolvePassThroughAuthToken, () => ( null)),
|
|
1285
1532
|
subscriptionProfile: _nullishCoalesce(hints.subscriptionProfile, () => ( null)),
|
|
1533
|
+
preferredAccountId: hints.preferredAccountId,
|
|
1534
|
+
preferredAccountGroup: hints.preferredAccountGroup,
|
|
1535
|
+
boundAccountFallbackPolicy: hints.boundAccountFallbackPolicy,
|
|
1536
|
+
preferredKeyId: route.preferredKeyId,
|
|
1537
|
+
boundKeyFallbackPolicy: route.boundKeyFallbackPolicy,
|
|
1286
1538
|
maxConcurrency: hints.maxConcurrency,
|
|
1287
1539
|
webSearchService: _nullishCoalesce(hints.webSearchService, () => ( null)),
|
|
1288
1540
|
onRetry: hints.onRetry,
|
|
@@ -1309,24 +1561,37 @@ function readGeminiUsage(usage) {
|
|
|
1309
1561
|
reasoningTokens
|
|
1310
1562
|
};
|
|
1311
1563
|
}
|
|
1564
|
+
function emitGeminiUsageRecord(recorder, rawUsageMetadata, attribution) {
|
|
1565
|
+
const tapped = readGeminiUsage(rawUsageMetadata);
|
|
1566
|
+
if (!tapped) return;
|
|
1567
|
+
recorder.record({
|
|
1568
|
+
messageId: null,
|
|
1569
|
+
parentMessageId: null,
|
|
1570
|
+
sessionId: attribution.sessionId,
|
|
1571
|
+
providerId: attribution.providerId,
|
|
1572
|
+
model: attribution.model,
|
|
1573
|
+
apiKeyId: attribution.apiKeyId,
|
|
1574
|
+
auditResponse: attribution.auditResponse,
|
|
1575
|
+
engineOrigin: "codex-ingress",
|
|
1576
|
+
usage: tapped,
|
|
1577
|
+
rawUsage: rawUsageMetadata
|
|
1578
|
+
});
|
|
1579
|
+
}
|
|
1312
1580
|
function recordGeminiNonStreamUsage(recorder, bodyText, attribution) {
|
|
1313
1581
|
try {
|
|
1314
1582
|
const parsed = JSON.parse(bodyText);
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
rawUsage: parsed.usageMetadata
|
|
1328
|
-
});
|
|
1329
|
-
} catch (e13) {
|
|
1583
|
+
emitGeminiUsageRecord(
|
|
1584
|
+
recorder,
|
|
1585
|
+
parsed.usageMetadata,
|
|
1586
|
+
attribution
|
|
1587
|
+
);
|
|
1588
|
+
} catch (e15) {
|
|
1589
|
+
}
|
|
1590
|
+
}
|
|
1591
|
+
function recordGeminiStreamUsage(recorder, rawUsageMetadata, attribution) {
|
|
1592
|
+
try {
|
|
1593
|
+
emitGeminiUsageRecord(recorder, rawUsageMetadata, attribution);
|
|
1594
|
+
} catch (e16) {
|
|
1330
1595
|
}
|
|
1331
1596
|
}
|
|
1332
1597
|
|
|
@@ -1335,14 +1600,14 @@ var GENERATE_CONTENT_ACTION = ":generateContent";
|
|
|
1335
1600
|
var STREAM_GENERATE_CONTENT_ACTION = ":streamGenerateContent";
|
|
1336
1601
|
function isGeminiGenerateContentRequest(method, url) {
|
|
1337
1602
|
if (method !== "POST" || !url) return false;
|
|
1338
|
-
const path = _nullishCoalesce(_optionalChain([url, 'access',
|
|
1603
|
+
const path = _nullishCoalesce(_optionalChain([url, 'access', _35 => _35.split, 'call', _36 => _36("?"), 'access', _37 => _37[0], 'optionalAccess', _38 => _38.replace, 'call', _39 => _39(/\/+$/, "")]), () => ( ""));
|
|
1339
1604
|
const lastSegment = _nullishCoalesce(path.split("/").pop(), () => ( ""));
|
|
1340
1605
|
return lastSegment.includes(STREAM_GENERATE_CONTENT_ACTION) || lastSegment.includes(GENERATE_CONTENT_ACTION);
|
|
1341
1606
|
}
|
|
1342
1607
|
function isGeminiStreamRequest(url) {
|
|
1343
1608
|
if (!url) return false;
|
|
1344
1609
|
const [path, query = ""] = url.split("?");
|
|
1345
|
-
const lastSegment = _nullishCoalesce((_nullishCoalesce(_optionalChain([path, 'optionalAccess',
|
|
1610
|
+
const lastSegment = _nullishCoalesce((_nullishCoalesce(_optionalChain([path, 'optionalAccess', _40 => _40.replace, 'call', _41 => _41(/\/+$/, "")]), () => ( ""))).split("/").pop(), () => ( ""));
|
|
1346
1611
|
if (lastSegment.includes(STREAM_GENERATE_CONTENT_ACTION)) return true;
|
|
1347
1612
|
return /(^|&)alt=sse(&|$)/.test(query);
|
|
1348
1613
|
}
|
|
@@ -1350,7 +1615,7 @@ async function handleGeminiGenerateContentRequest(res, rawBody, url, route, deps
|
|
|
1350
1615
|
let geminiBody;
|
|
1351
1616
|
try {
|
|
1352
1617
|
geminiBody = JSON.parse(rawBody);
|
|
1353
|
-
} catch (
|
|
1618
|
+
} catch (e17) {
|
|
1354
1619
|
writeError(res, 400, "Invalid JSON in request body");
|
|
1355
1620
|
return;
|
|
1356
1621
|
}
|
|
@@ -1366,16 +1631,32 @@ async function handleGeminiGenerateContentRequest(res, rawBody, url, route, deps
|
|
|
1366
1631
|
const plan = await buildByoPlan2(res, route, deps, resolvedModel, isStream);
|
|
1367
1632
|
if (!plan) return;
|
|
1368
1633
|
const providerResponse = await runPipelineWithPoolReporting2(geminiBody, plan);
|
|
1369
|
-
const
|
|
1634
|
+
const usageAttribution = {
|
|
1635
|
+
sessionId: route.sessionId,
|
|
1636
|
+
providerId: _nullishCoalesce(route.providerId, () => ( "gemini")),
|
|
1637
|
+
model: resolvedModel,
|
|
1638
|
+
apiKeyId: _nullishCoalesce(route.apiKeyId, () => ( null)),
|
|
1639
|
+
// request-audit-log: correlate this request's tokens/cost to its audit record.
|
|
1640
|
+
auditResponse: res
|
|
1641
|
+
};
|
|
1642
|
+
const usageRecorder = deps.usageRecorder;
|
|
1643
|
+
const usageTap = usageRecorder ? {
|
|
1644
|
+
extractUsage(event) {
|
|
1645
|
+
return _nullishCoalesce(event["usageMetadata"], () => ( null));
|
|
1646
|
+
},
|
|
1647
|
+
onUsage(rawUsage) {
|
|
1648
|
+
recordGeminiStreamUsage(usageRecorder, rawUsage, usageAttribution);
|
|
1649
|
+
}
|
|
1650
|
+
} : void 0;
|
|
1651
|
+
const bodyText = await relayResponse(
|
|
1652
|
+
res,
|
|
1653
|
+
providerResponse.response,
|
|
1654
|
+
isStream,
|
|
1655
|
+
void 0,
|
|
1656
|
+
usageTap
|
|
1657
|
+
);
|
|
1370
1658
|
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
|
-
});
|
|
1659
|
+
recordGeminiNonStreamUsage(deps.usageRecorder, bodyText, usageAttribution);
|
|
1379
1660
|
}
|
|
1380
1661
|
} catch (err) {
|
|
1381
1662
|
const errMsg = _chunkSVNDB62Dcjs.serializeError.call(void 0, err);
|
|
@@ -1394,7 +1675,14 @@ async function buildByoPlan2(res, route, deps, resolvedModel, isStream) {
|
|
|
1394
1675
|
writeError(res, 502, `Provider not found: ${providerId}`);
|
|
1395
1676
|
return null;
|
|
1396
1677
|
}
|
|
1397
|
-
const apiKey = await resolvePoolBoundKey(
|
|
1678
|
+
const apiKey = await resolvePoolBoundKey(
|
|
1679
|
+
deps,
|
|
1680
|
+
providerId,
|
|
1681
|
+
provider,
|
|
1682
|
+
route.sessionId,
|
|
1683
|
+
route.preferredKeyId,
|
|
1684
|
+
route.boundKeyFallbackPolicy
|
|
1685
|
+
);
|
|
1398
1686
|
if (!apiKey) {
|
|
1399
1687
|
writeError(res, 502, "API key not configured");
|
|
1400
1688
|
return null;
|
|
@@ -1431,7 +1719,7 @@ async function runPipeline2(geminiBody, plan) {
|
|
|
1431
1719
|
const authHeaders = {};
|
|
1432
1720
|
await auth.applyHeaders(authHeaders, { upstreamUrl, model: resolvedModel });
|
|
1433
1721
|
let rawStatus = null;
|
|
1434
|
-
const { response } = await
|
|
1722
|
+
const { response } = await _chunkMUHWHQVMcjs.executeProviderCall.call(void 0, {
|
|
1435
1723
|
executor,
|
|
1436
1724
|
request: geminiBody,
|
|
1437
1725
|
provider: transformerProvider,
|
|
@@ -1449,7 +1737,7 @@ async function runPipeline2(geminiBody, plan) {
|
|
|
1449
1737
|
},
|
|
1450
1738
|
fetchFn: (url, headers, body) => {
|
|
1451
1739
|
console.log(`[ProviderProxy:gemini] -> ${url} model=${resolvedModel} stream=${isStream}`);
|
|
1452
|
-
return
|
|
1740
|
+
return _chunkRJUONLUQcjs.fetchUpstream.call(void 0,
|
|
1453
1741
|
url,
|
|
1454
1742
|
{ method: "POST", headers, body: JSON.stringify(body) },
|
|
1455
1743
|
{ providerId: "byo" }
|
|
@@ -1464,8 +1752,8 @@ async function runPipeline2(geminiBody, plan) {
|
|
|
1464
1752
|
}
|
|
1465
1753
|
async function runPipelineWithPoolReporting2(geminiBody, plan) {
|
|
1466
1754
|
const first = await runPipeline2(geminiBody, plan);
|
|
1467
|
-
const outcome = await _optionalChain([plan, 'access',
|
|
1468
|
-
if (_optionalChain([outcome, 'optionalAccess',
|
|
1755
|
+
const outcome = await _optionalChain([plan, 'access', _42 => _42.auth, 'access', _43 => _43.onResult, 'optionalCall', _44 => _44(first.rawStatus)]);
|
|
1756
|
+
if (_optionalChain([outcome, 'optionalAccess', _45 => _45.rebound])) {
|
|
1469
1757
|
console.log(
|
|
1470
1758
|
"[ProviderProxy:gemini] pool re-bound key after status",
|
|
1471
1759
|
first.rawStatus,
|
|
@@ -1494,31 +1782,44 @@ function readChatCompletionsUsage(usage) {
|
|
|
1494
1782
|
reasoningTokens
|
|
1495
1783
|
};
|
|
1496
1784
|
}
|
|
1785
|
+
function emitChatCompletionsUsageRecord(recorder, rawUsage, attribution) {
|
|
1786
|
+
const tapped = readChatCompletionsUsage(rawUsage);
|
|
1787
|
+
if (!tapped) return;
|
|
1788
|
+
recorder.record({
|
|
1789
|
+
messageId: null,
|
|
1790
|
+
parentMessageId: null,
|
|
1791
|
+
sessionId: attribution.sessionId,
|
|
1792
|
+
providerId: attribution.providerId,
|
|
1793
|
+
model: attribution.model,
|
|
1794
|
+
apiKeyId: attribution.apiKeyId,
|
|
1795
|
+
auditResponse: attribution.auditResponse,
|
|
1796
|
+
engineOrigin: "codex-ingress",
|
|
1797
|
+
usage: tapped,
|
|
1798
|
+
rawUsage
|
|
1799
|
+
});
|
|
1800
|
+
}
|
|
1497
1801
|
function recordChatCompletionsNonStreamUsage(recorder, bodyText, attribution) {
|
|
1498
1802
|
try {
|
|
1499
1803
|
const parsed = JSON.parse(bodyText);
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
rawUsage: parsed.usage
|
|
1513
|
-
});
|
|
1514
|
-
} catch (e15) {
|
|
1804
|
+
emitChatCompletionsUsageRecord(
|
|
1805
|
+
recorder,
|
|
1806
|
+
parsed.usage,
|
|
1807
|
+
attribution
|
|
1808
|
+
);
|
|
1809
|
+
} catch (e18) {
|
|
1810
|
+
}
|
|
1811
|
+
}
|
|
1812
|
+
function recordChatCompletionsStreamUsage(recorder, rawUsage, attribution) {
|
|
1813
|
+
try {
|
|
1814
|
+
emitChatCompletionsUsageRecord(recorder, rawUsage, attribution);
|
|
1815
|
+
} catch (e19) {
|
|
1515
1816
|
}
|
|
1516
1817
|
}
|
|
1517
1818
|
|
|
1518
1819
|
// src/provider-proxy/ingress/openaiChatIngress.ts
|
|
1519
1820
|
function isOpenAIChatRequest(method, url) {
|
|
1520
1821
|
if (method !== "POST" || !url) return false;
|
|
1521
|
-
const path = _nullishCoalesce(_optionalChain([url, 'access',
|
|
1822
|
+
const path = _nullishCoalesce(_optionalChain([url, 'access', _46 => _46.split, 'call', _47 => _47("?"), 'access', _48 => _48[0], 'optionalAccess', _49 => _49.replace, 'call', _50 => _50(/\/+$/, "")]), () => ( ""));
|
|
1522
1823
|
return path.endsWith("/chat/completions");
|
|
1523
1824
|
}
|
|
1524
1825
|
var CHAT_BRIDGE_SUBSCRIPTION_PROVIDERS = /* @__PURE__ */ new Set(["claude"]);
|
|
@@ -1527,7 +1828,7 @@ async function handleOpenAIChatRequest(res, rawBody, route, deps) {
|
|
|
1527
1828
|
let chatBody;
|
|
1528
1829
|
try {
|
|
1529
1830
|
chatBody = JSON.parse(rawBody);
|
|
1530
|
-
} catch (
|
|
1831
|
+
} catch (e20) {
|
|
1531
1832
|
writeError(res, 400, "Invalid JSON in request body");
|
|
1532
1833
|
return;
|
|
1533
1834
|
}
|
|
@@ -1538,21 +1839,41 @@ async function handleOpenAIChatRequest(res, rawBody, route, deps) {
|
|
|
1538
1839
|
const plan = route.authMode === "subscription" ? await buildSubscriptionPlan2(res, route, deps, resolvedModel, isStream) : await buildByoPlan3(res, route, deps, resolvedModel, isStream);
|
|
1539
1840
|
if (!plan) return;
|
|
1540
1841
|
const providerResponse = plan.isSubscription ? await runPipelineWithSubscriptionRetry2(chatBody, plan) : await runPipelineWithPoolReporting3(chatBody, plan);
|
|
1541
|
-
const
|
|
1842
|
+
const usageAttribution = {
|
|
1843
|
+
sessionId: route.sessionId,
|
|
1844
|
+
providerId: _nullishCoalesce(route.providerId, () => ( "openai")),
|
|
1845
|
+
model: resolvedModel,
|
|
1846
|
+
apiKeyId: _nullishCoalesce(route.apiKeyId, () => ( null)),
|
|
1847
|
+
// request-audit-log: correlate this request's tokens/cost to its audit record.
|
|
1848
|
+
auditResponse: res
|
|
1849
|
+
};
|
|
1850
|
+
const usageRecorder = deps.usageRecorder;
|
|
1851
|
+
const usageTap = usageRecorder ? {
|
|
1852
|
+
extractUsage(event) {
|
|
1853
|
+
return _nullishCoalesce(event["usage"], () => ( null));
|
|
1854
|
+
},
|
|
1855
|
+
onUsage(rawUsage) {
|
|
1856
|
+
recordChatCompletionsStreamUsage(usageRecorder, rawUsage, usageAttribution);
|
|
1857
|
+
}
|
|
1858
|
+
} : void 0;
|
|
1859
|
+
const bodyText = await relayResponse(
|
|
1860
|
+
res,
|
|
1861
|
+
providerResponse.response,
|
|
1862
|
+
isStream,
|
|
1863
|
+
void 0,
|
|
1864
|
+
usageTap
|
|
1865
|
+
);
|
|
1542
1866
|
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
|
-
});
|
|
1867
|
+
recordChatCompletionsNonStreamUsage(deps.usageRecorder, bodyText, usageAttribution);
|
|
1551
1868
|
}
|
|
1552
1869
|
} catch (err) {
|
|
1870
|
+
if (_chunk25GXJCEZcjs.isBoundAccountSelectionError.call(void 0, err)) {
|
|
1871
|
+
writeBoundAccountError(res, err);
|
|
1872
|
+
return;
|
|
1873
|
+
}
|
|
1553
1874
|
const errMsg = _chunkSVNDB62Dcjs.serializeError.call(void 0, err);
|
|
1554
1875
|
console.error("[ProviderProxy:chat] Pipeline error:", errMsg);
|
|
1555
|
-
writeError(res, 502, errMsg);
|
|
1876
|
+
writeError(res, _chunk6QQG7YG3cjs.isAccountAllowanceExhaustedError.call(void 0, err) ? 429 : 502, errMsg);
|
|
1556
1877
|
}
|
|
1557
1878
|
}
|
|
1558
1879
|
async function buildByoPlan3(res, route, deps, resolvedModel, isStream) {
|
|
@@ -1566,7 +1887,14 @@ async function buildByoPlan3(res, route, deps, resolvedModel, isStream) {
|
|
|
1566
1887
|
writeError(res, 502, `Provider not found: ${providerId}`);
|
|
1567
1888
|
return null;
|
|
1568
1889
|
}
|
|
1569
|
-
const apiKey = await resolvePoolBoundKey(
|
|
1890
|
+
const apiKey = await resolvePoolBoundKey(
|
|
1891
|
+
deps,
|
|
1892
|
+
providerId,
|
|
1893
|
+
provider,
|
|
1894
|
+
route.sessionId,
|
|
1895
|
+
route.preferredKeyId,
|
|
1896
|
+
route.boundKeyFallbackPolicy
|
|
1897
|
+
);
|
|
1570
1898
|
if (!apiKey) {
|
|
1571
1899
|
writeError(res, 502, "API key not configured");
|
|
1572
1900
|
return null;
|
|
@@ -1613,12 +1941,12 @@ async function buildSubscriptionPlan2(res, route, deps, resolvedModel, isStream)
|
|
|
1613
1941
|
);
|
|
1614
1942
|
return null;
|
|
1615
1943
|
}
|
|
1616
|
-
const upstreamUrl = _optionalChain([profile, 'access',
|
|
1944
|
+
const upstreamUrl = _optionalChain([profile, 'access', _51 => _51.resolveUpstreamUrl, 'optionalCall', _52 => _52(resolvedModel)]);
|
|
1617
1945
|
if (!upstreamUrl) {
|
|
1618
1946
|
writeError(res, 502, "Subscription profile is missing resolveUpstreamUrl");
|
|
1619
1947
|
return null;
|
|
1620
1948
|
}
|
|
1621
|
-
const auth = _nullishCoalesce(route.auth, () => ( new (0,
|
|
1949
|
+
const auth = _nullishCoalesce(route.auth, () => ( new (0, _chunkYNJNTCSQcjs.SubscriptionAuthSource)(profile)));
|
|
1622
1950
|
const chain = _chunkNYUNU75Acjs.resolveSubscriptionChain.call(void 0,
|
|
1623
1951
|
profile,
|
|
1624
1952
|
deps.llmConfig.getTransformerService(),
|
|
@@ -1632,6 +1960,9 @@ async function buildSubscriptionPlan2(res, route, deps, resolvedModel, isStream)
|
|
|
1632
1960
|
};
|
|
1633
1961
|
return {
|
|
1634
1962
|
auth,
|
|
1963
|
+
preferredAccountId: route.preferredAccountId,
|
|
1964
|
+
preferredAccountGroup: route.preferredAccountGroup,
|
|
1965
|
+
boundAccountFallbackPolicy: route.boundAccountFallbackPolicy,
|
|
1635
1966
|
chain,
|
|
1636
1967
|
transformerProvider,
|
|
1637
1968
|
resolvedModel,
|
|
@@ -1650,12 +1981,15 @@ async function runPipeline3(chatBody, plan) {
|
|
|
1650
1981
|
await auth.applyHeaders(authHeaders, {
|
|
1651
1982
|
upstreamUrl,
|
|
1652
1983
|
model: resolvedModel,
|
|
1984
|
+
preferredAccountId: plan.preferredAccountId,
|
|
1985
|
+
preferredAccountGroup: plan.preferredAccountGroup,
|
|
1986
|
+
boundAccountFallbackPolicy: plan.boundAccountFallbackPolicy,
|
|
1653
1987
|
reportSelection: (accountId) => {
|
|
1654
1988
|
proxyAccountId = accountId;
|
|
1655
1989
|
}
|
|
1656
1990
|
});
|
|
1657
1991
|
let rawStatus = null;
|
|
1658
|
-
const { response } = await
|
|
1992
|
+
const { response } = await _chunkMUHWHQVMcjs.executeProviderCall.call(void 0, {
|
|
1659
1993
|
executor,
|
|
1660
1994
|
request: chatBody,
|
|
1661
1995
|
provider: transformerProvider,
|
|
@@ -1672,7 +2006,7 @@ async function runPipeline3(chatBody, plan) {
|
|
|
1672
2006
|
},
|
|
1673
2007
|
fetchFn: (url, headers, body) => {
|
|
1674
2008
|
console.log(`[ProviderProxy:chat] -> ${url} model=${resolvedModel} stream=${isStream}`);
|
|
1675
|
-
return
|
|
2009
|
+
return _chunkRJUONLUQcjs.fetchUpstream.call(void 0,
|
|
1676
2010
|
url,
|
|
1677
2011
|
{ method: "POST", headers, body: JSON.stringify(body) },
|
|
1678
2012
|
{ providerId: plan.proxyProviderId, accountId: proxyAccountId }
|
|
@@ -1687,8 +2021,8 @@ async function runPipeline3(chatBody, plan) {
|
|
|
1687
2021
|
}
|
|
1688
2022
|
async function runPipelineWithPoolReporting3(chatBody, plan) {
|
|
1689
2023
|
const first = await runPipeline3(chatBody, plan);
|
|
1690
|
-
const outcome = await _optionalChain([plan, 'access',
|
|
1691
|
-
if (_optionalChain([outcome, 'optionalAccess',
|
|
2024
|
+
const outcome = await _optionalChain([plan, 'access', _53 => _53.auth, 'access', _54 => _54.onResult, 'optionalCall', _55 => _55(first.rawStatus)]);
|
|
2025
|
+
if (_optionalChain([outcome, 'optionalAccess', _56 => _56.rebound])) {
|
|
1692
2026
|
console.log(
|
|
1693
2027
|
"[ProviderProxy:chat] pool re-bound key after status",
|
|
1694
2028
|
first.rawStatus,
|
|
@@ -1701,7 +2035,7 @@ async function runPipelineWithPoolReporting3(chatBody, plan) {
|
|
|
1701
2035
|
async function runPipelineWithSubscriptionRetry2(chatBody, plan) {
|
|
1702
2036
|
const first = await runPipeline3(chatBody, plan);
|
|
1703
2037
|
if (first.rawStatus !== 401) return first;
|
|
1704
|
-
const refreshed = await _optionalChain([plan, 'access',
|
|
2038
|
+
const refreshed = await _optionalChain([plan, 'access', _57 => _57.auth, 'access', _58 => _58.onUnauthorized, 'optionalCall', _59 => _59()]);
|
|
1705
2039
|
if (!refreshed) {
|
|
1706
2040
|
console.warn("[ProviderProxy:chat] 401 not recoverable (onUnauthorized returned false)");
|
|
1707
2041
|
return first;
|
|
@@ -1728,63 +2062,207 @@ function readResponsesUsage(usage) {
|
|
|
1728
2062
|
reasoningTokens
|
|
1729
2063
|
};
|
|
1730
2064
|
}
|
|
2065
|
+
function emitResponsesUsageRecord(recorder, rawUsage, attribution) {
|
|
2066
|
+
const tapped = readResponsesUsage(rawUsage);
|
|
2067
|
+
if (!tapped) return;
|
|
2068
|
+
recorder.record({
|
|
2069
|
+
messageId: null,
|
|
2070
|
+
parentMessageId: null,
|
|
2071
|
+
sessionId: attribution.sessionId,
|
|
2072
|
+
providerId: attribution.providerId,
|
|
2073
|
+
model: attribution.model,
|
|
2074
|
+
apiKeyId: attribution.apiKeyId,
|
|
2075
|
+
cacheKeySource: attribution.cacheKeySource,
|
|
2076
|
+
cacheKeyInjected: attribution.cacheKeyInjected,
|
|
2077
|
+
auditResponse: attribution.auditResponse,
|
|
2078
|
+
engineOrigin: "codex-ingress",
|
|
2079
|
+
usage: tapped,
|
|
2080
|
+
rawUsage
|
|
2081
|
+
});
|
|
2082
|
+
}
|
|
1731
2083
|
function recordResponsesNonStreamUsage(recorder, bodyText, attribution) {
|
|
1732
2084
|
try {
|
|
1733
2085
|
const parsed = JSON.parse(bodyText);
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
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) {
|
|
2086
|
+
emitResponsesUsageRecord(
|
|
2087
|
+
recorder,
|
|
2088
|
+
parsed.usage,
|
|
2089
|
+
attribution
|
|
2090
|
+
);
|
|
2091
|
+
} catch (e21) {
|
|
1749
2092
|
}
|
|
1750
2093
|
}
|
|
2094
|
+
function recordResponsesStreamUsage(recorder, rawUsage, attribution) {
|
|
2095
|
+
try {
|
|
2096
|
+
emitResponsesUsageRecord(recorder, rawUsage, attribution);
|
|
2097
|
+
} catch (e22) {
|
|
2098
|
+
}
|
|
2099
|
+
}
|
|
2100
|
+
|
|
2101
|
+
// src/provider-proxy/ingress/codexUsageLimitDetection.ts
|
|
2102
|
+
var PROVIDER_ID = "codex";
|
|
2103
|
+
var DEFAULT_QUOTA_COOLDOWN_MS = 5 * 6e4;
|
|
2104
|
+
var QUOTA_EXHAUSTED_PERCENT = 90;
|
|
2105
|
+
function parseTryAgainDeadline(bodyText) {
|
|
2106
|
+
const match = bodyText.match(/try again (?:at|on)\s+(.+?)(?:[.\n]|$)/i);
|
|
2107
|
+
if (!match) return void 0;
|
|
2108
|
+
const cleaned = match[1].replace(/(\d+)(st|nd|rd|th)/giu, "$1").trim();
|
|
2109
|
+
const ms = Date.parse(cleaned);
|
|
2110
|
+
return Number.isFinite(ms) ? ms : void 0;
|
|
2111
|
+
}
|
|
2112
|
+
function deadlineFromAllowanceSnapshot(accountId, now) {
|
|
2113
|
+
const snapshot = _chunkHVBBDBS3cjs.getSharedAccountAllowanceStore.call(void 0, ).get(PROVIDER_ID, accountId, now);
|
|
2114
|
+
if (!snapshot) return void 0;
|
|
2115
|
+
const candidates = snapshot.windows.filter(
|
|
2116
|
+
(w) => typeof w.usedPercent === "number" && w.usedPercent >= QUOTA_EXHAUSTED_PERCENT && typeof w.resetsAt === "string"
|
|
2117
|
+
).map((w) => ({ ms: Date.parse(w.resetsAt), usedPercent: w.usedPercent })).filter((x) => Number.isFinite(x.ms) && x.ms > now).sort((a, b) => b.usedPercent - a.usedPercent);
|
|
2118
|
+
return _optionalChain([candidates, 'access', _60 => _60[0], 'optionalAccess', _61 => _61.ms]);
|
|
2119
|
+
}
|
|
2120
|
+
function resolveCodexQuotaDeadline(accountId, bodyText, now = Date.now()) {
|
|
2121
|
+
const parsed = parseTryAgainDeadline(bodyText);
|
|
2122
|
+
const parsedDeadline = parsed !== void 0 && parsed > now ? parsed : void 0;
|
|
2123
|
+
return _nullishCoalesce(_nullishCoalesce(deadlineFromAllowanceSnapshot(accountId, now), () => ( parsedDeadline)), () => ( now + DEFAULT_QUOTA_COOLDOWN_MS));
|
|
2124
|
+
}
|
|
2125
|
+
function markCodexUsageLimitExhaustion(accountId, bodyText, now = Date.now()) {
|
|
2126
|
+
if (!accountId) return;
|
|
2127
|
+
const deadline = resolveCodexQuotaDeadline(accountId, bodyText, now);
|
|
2128
|
+
_chunkYWL7YZWScjs.getSharedAccountHealth.call(void 0, ).markQuotaExhausted(PROVIDER_ID, accountId, deadline, now);
|
|
2129
|
+
}
|
|
1751
2130
|
|
|
1752
2131
|
// src/provider-proxy/ingress/openaiResponsesIngress.ts
|
|
2132
|
+
var SERVER_OVERLOADED_CODES = /* @__PURE__ */ new Set(["server_is_overloaded", "slow_down"]);
|
|
2133
|
+
function isCodexServerOverloadEvent(event) {
|
|
2134
|
+
if (event["type"] !== "response.failed") return false;
|
|
2135
|
+
const error = _optionalChain([event, 'access', _62 => _62["response"], 'optionalAccess', _63 => _63["error"]]);
|
|
2136
|
+
const code = _optionalChain([error, 'optionalAccess', _64 => _64["code"]]);
|
|
2137
|
+
return typeof code === "string" && SERVER_OVERLOADED_CODES.has(code);
|
|
2138
|
+
}
|
|
1753
2139
|
function isOpenAIResponsesRequest(method, url) {
|
|
1754
2140
|
if (method !== "POST" || !url) return false;
|
|
1755
|
-
const path = _nullishCoalesce(_optionalChain([url, 'access',
|
|
2141
|
+
const path = _nullishCoalesce(_optionalChain([url, 'access', _65 => _65.split, 'call', _66 => _66("?"), 'access', _67 => _67[0], 'optionalAccess', _68 => _68.replace, 'call', _69 => _69(/\/+$/, "")]), () => ( ""));
|
|
1756
2142
|
return path.endsWith("/responses");
|
|
1757
2143
|
}
|
|
1758
|
-
|
|
2144
|
+
var SAFE_INJECTED_CACHE_KEY_SOURCES = /* @__PURE__ */ new Set([
|
|
2145
|
+
"session-header",
|
|
2146
|
+
"thread-header",
|
|
2147
|
+
"body-session-id",
|
|
2148
|
+
"body-thread-id",
|
|
2149
|
+
"content-fingerprint"
|
|
2150
|
+
]);
|
|
2151
|
+
function isSafeInjectedCacheKeySource(source) {
|
|
2152
|
+
return SAFE_INJECTED_CACHE_KEY_SOURCES.has(source);
|
|
2153
|
+
}
|
|
2154
|
+
function ensureCodexPromptCacheKey(body, proxyProviderId2, derivedSession) {
|
|
2155
|
+
if (typeof body.prompt_cache_key === "string" && body.prompt_cache_key.trim()) {
|
|
2156
|
+
return { cacheKeySource: "client", cacheKeyInjected: false };
|
|
2157
|
+
}
|
|
2158
|
+
if (proxyProviderId2 !== "codex" || !isSafeInjectedCacheKeySource(derivedSession.source)) {
|
|
2159
|
+
return { cacheKeySource: "none", cacheKeyInjected: false };
|
|
2160
|
+
}
|
|
2161
|
+
body.prompt_cache_key = `omnicross:${derivedSession.source}:${derivedSession.key}`;
|
|
2162
|
+
return {
|
|
2163
|
+
cacheKeySource: derivedSession.source,
|
|
2164
|
+
cacheKeyInjected: true
|
|
2165
|
+
};
|
|
2166
|
+
}
|
|
2167
|
+
async function handleOpenAIResponsesRequest(res, rawBody, route, deps, requestHeaders = {}) {
|
|
1759
2168
|
let responsesBody;
|
|
1760
2169
|
try {
|
|
1761
2170
|
responsesBody = JSON.parse(rawBody);
|
|
1762
|
-
} catch (
|
|
2171
|
+
} catch (e23) {
|
|
1763
2172
|
writeError(res, 400, "Invalid JSON in request body");
|
|
1764
2173
|
return;
|
|
1765
2174
|
}
|
|
1766
2175
|
const isStream = responsesBody.stream === true;
|
|
2176
|
+
const derivedSession = _chunkJ3QQ6JS5cjs.deriveGatewaySessionKey.call(void 0, responsesBody, requestHeaders, {
|
|
2177
|
+
endpoint: "responses",
|
|
2178
|
+
// A verified outbound key is the strongest route-local fallback. Resident
|
|
2179
|
+
// proxy callers without one still get a stable run/session bucket; the
|
|
2180
|
+
// final `anonymous` fallback is handled inside the shared utility.
|
|
2181
|
+
fallbackKey: _nullishCoalesce(_nullishCoalesce(route.apiKeyId, () => ( route.sessionId)), () => ( void 0))
|
|
2182
|
+
});
|
|
2183
|
+
const sessionKey = derivedSession.key;
|
|
1767
2184
|
const resolvedModel = route.model;
|
|
1768
2185
|
responsesBody.model = resolvedModel;
|
|
1769
2186
|
try {
|
|
1770
|
-
const plan = route.authMode === "subscription" ? await buildSubscriptionPlan3(
|
|
2187
|
+
const plan = route.authMode === "subscription" ? await buildSubscriptionPlan3(
|
|
2188
|
+
res,
|
|
2189
|
+
route,
|
|
2190
|
+
deps,
|
|
2191
|
+
resolvedModel,
|
|
2192
|
+
isStream,
|
|
2193
|
+
sessionKey,
|
|
2194
|
+
derivedSession.source,
|
|
2195
|
+
requestHeaders
|
|
2196
|
+
) : await buildByoPlan4(res, route, deps, resolvedModel, isStream);
|
|
1771
2197
|
if (!plan) return;
|
|
1772
|
-
const
|
|
1773
|
-
|
|
2198
|
+
const cacheKeyAttribution = ensureCodexPromptCacheKey(
|
|
2199
|
+
responsesBody,
|
|
2200
|
+
plan.proxyProviderId,
|
|
2201
|
+
derivedSession
|
|
2202
|
+
);
|
|
2203
|
+
let providerResponse = route.authMode === "subscription" ? await runPipelineWithSubscriptionRetry3(responsesBody, plan) : await runPipelineWithPoolReporting4(responsesBody, plan);
|
|
2204
|
+
providerResponse = await retryAroundCodexUsageLimit(responsesBody, plan, providerResponse);
|
|
2205
|
+
const usageAttribution = {
|
|
2206
|
+
sessionId: route.sessionId,
|
|
2207
|
+
providerId: _nullishCoalesce(route.providerId, () => ( "codex")),
|
|
2208
|
+
model: resolvedModel,
|
|
2209
|
+
apiKeyId: _nullishCoalesce(route.apiKeyId, () => ( null)),
|
|
2210
|
+
cacheKeySource: cacheKeyAttribution.cacheKeySource,
|
|
2211
|
+
cacheKeyInjected: cacheKeyAttribution.cacheKeyInjected,
|
|
2212
|
+
// request-audit-log: correlate this request's tokens/cost to its audit record.
|
|
2213
|
+
auditResponse: res
|
|
2214
|
+
};
|
|
2215
|
+
const usageRecorder = deps.usageRecorder;
|
|
2216
|
+
const usageTap = usageRecorder ? {
|
|
2217
|
+
extractUsage(event) {
|
|
2218
|
+
if (event["type"] !== "response.completed") return null;
|
|
2219
|
+
const response = event["response"];
|
|
2220
|
+
const usage = _optionalChain([response, 'optionalAccess', _70 => _70["usage"]]);
|
|
2221
|
+
return _nullishCoalesce(usage, () => ( null));
|
|
2222
|
+
},
|
|
2223
|
+
onUsage(rawUsage) {
|
|
2224
|
+
recordResponsesStreamUsage(usageRecorder, rawUsage, usageAttribution);
|
|
2225
|
+
}
|
|
2226
|
+
} : void 0;
|
|
2227
|
+
const overloadActivityId = providerResponse.activityRecordId;
|
|
2228
|
+
const overloadAccountId = providerResponse.accountId;
|
|
2229
|
+
const overloadProviderId = plan.proxyProviderId;
|
|
2230
|
+
let overloadRecorded = false;
|
|
2231
|
+
const overloadDetector = (event) => {
|
|
2232
|
+
if (overloadRecorded || !isCodexServerOverloadEvent(event)) return;
|
|
2233
|
+
overloadRecorded = true;
|
|
2234
|
+
if (overloadActivityId) {
|
|
2235
|
+
_chunkNKVZ6Z3Ycjs.getSharedAccountRouteActivity.call(void 0, ).amend(overloadActivityId, {
|
|
2236
|
+
streamError: "server_overloaded"
|
|
2237
|
+
});
|
|
2238
|
+
}
|
|
2239
|
+
if (overloadAccountId) {
|
|
2240
|
+
_chunkOTZC4TNHcjs.getSharedOverloadCounter.call(void 0, ).recordOverload({
|
|
2241
|
+
providerId: overloadProviderId,
|
|
2242
|
+
accountId: overloadAccountId,
|
|
2243
|
+
endpoint: "responses"
|
|
2244
|
+
});
|
|
2245
|
+
}
|
|
2246
|
+
};
|
|
2247
|
+
const bodyText = await relayResponse(
|
|
2248
|
+
res,
|
|
2249
|
+
providerResponse.response,
|
|
2250
|
+
isStream,
|
|
2251
|
+
route.requestedModel,
|
|
2252
|
+
usageTap,
|
|
2253
|
+
overloadDetector
|
|
2254
|
+
);
|
|
1774
2255
|
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
|
-
});
|
|
2256
|
+
recordResponsesNonStreamUsage(deps.usageRecorder, bodyText, usageAttribution);
|
|
1783
2257
|
}
|
|
1784
2258
|
} catch (err) {
|
|
2259
|
+
if (_chunk25GXJCEZcjs.isBoundAccountSelectionError.call(void 0, err)) {
|
|
2260
|
+
writeBoundAccountError(res, err);
|
|
2261
|
+
return;
|
|
2262
|
+
}
|
|
1785
2263
|
const errMsg = _chunkSVNDB62Dcjs.serializeError.call(void 0, err);
|
|
1786
2264
|
console.error("[ProviderProxy:responses] Pipeline error:", errMsg);
|
|
1787
|
-
writeError(res, 502, errMsg);
|
|
2265
|
+
writeError(res, _chunk6QQG7YG3cjs.isAccountAllowanceExhaustedError.call(void 0, err) ? 429 : 502, errMsg);
|
|
1788
2266
|
}
|
|
1789
2267
|
}
|
|
1790
2268
|
async function buildByoPlan4(res, route, deps, resolvedModel, isStream) {
|
|
@@ -1798,7 +2276,14 @@ async function buildByoPlan4(res, route, deps, resolvedModel, isStream) {
|
|
|
1798
2276
|
writeError(res, 502, `Provider not found: ${providerId}`);
|
|
1799
2277
|
return null;
|
|
1800
2278
|
}
|
|
1801
|
-
const apiKey = await resolvePoolBoundKey(
|
|
2279
|
+
const apiKey = await resolvePoolBoundKey(
|
|
2280
|
+
deps,
|
|
2281
|
+
providerId,
|
|
2282
|
+
provider,
|
|
2283
|
+
route.sessionId,
|
|
2284
|
+
route.preferredKeyId,
|
|
2285
|
+
route.boundKeyFallbackPolicy
|
|
2286
|
+
);
|
|
1802
2287
|
if (!apiKey) {
|
|
1803
2288
|
writeError(res, 502, "API key not configured");
|
|
1804
2289
|
return null;
|
|
@@ -1829,18 +2314,18 @@ async function buildByoPlan4(res, route, deps, resolvedModel, isStream) {
|
|
|
1829
2314
|
proxyProviderId: "byo"
|
|
1830
2315
|
};
|
|
1831
2316
|
}
|
|
1832
|
-
async function buildSubscriptionPlan3(res, route, deps, resolvedModel, isStream) {
|
|
2317
|
+
async function buildSubscriptionPlan3(res, route, deps, resolvedModel, isStream, sessionKey, sessionSource, requestHeaders) {
|
|
1833
2318
|
const profile = route.subscriptionProfile;
|
|
1834
2319
|
if (!profile) {
|
|
1835
2320
|
writeError(res, 502, "Subscription mode requires a codex subscription profile");
|
|
1836
2321
|
return null;
|
|
1837
2322
|
}
|
|
1838
|
-
const upstreamUrl = _optionalChain([profile, 'access',
|
|
2323
|
+
const upstreamUrl = _optionalChain([profile, 'access', _71 => _71.resolveUpstreamUrl, 'optionalCall', _72 => _72(resolvedModel)]);
|
|
1839
2324
|
if (!upstreamUrl) {
|
|
1840
2325
|
writeError(res, 502, "Subscription profile is missing resolveUpstreamUrl");
|
|
1841
2326
|
return null;
|
|
1842
2327
|
}
|
|
1843
|
-
const auth = _nullishCoalesce(route.auth, () => ( new (0,
|
|
2328
|
+
const auth = _nullishCoalesce(route.auth, () => ( new (0, _chunkYNJNTCSQcjs.SubscriptionAuthSource)(profile)));
|
|
1844
2329
|
const chain = _chunkNYUNU75Acjs.resolveSubscriptionChain.call(void 0,
|
|
1845
2330
|
profile,
|
|
1846
2331
|
deps.llmConfig.getTransformerService(),
|
|
@@ -1854,15 +2339,28 @@ async function buildSubscriptionPlan3(res, route, deps, resolvedModel, isStream)
|
|
|
1854
2339
|
};
|
|
1855
2340
|
if (profile.authStrategy.providerId === "gemini") {
|
|
1856
2341
|
try {
|
|
1857
|
-
transformerProvider.geminiProject = await resolveGeminiCodeAssistProject(profile
|
|
2342
|
+
transformerProvider.geminiProject = await resolveGeminiCodeAssistProject(profile, {
|
|
2343
|
+
sessionKey,
|
|
2344
|
+
preferredAccountId: route.preferredAccountId,
|
|
2345
|
+
preferredAccountGroup: route.preferredAccountGroup,
|
|
2346
|
+
boundAccountFallbackPolicy: route.boundAccountFallbackPolicy
|
|
2347
|
+
});
|
|
1858
2348
|
} catch (err) {
|
|
2349
|
+
if (_chunk25GXJCEZcjs.isBoundAccountSelectionError.call(void 0, err)) {
|
|
2350
|
+
writeBoundAccountError(res, err);
|
|
2351
|
+
return null;
|
|
2352
|
+
}
|
|
1859
2353
|
writeError(res, 502, _chunkSVNDB62Dcjs.serializeError.call(void 0, err));
|
|
1860
2354
|
return null;
|
|
1861
2355
|
}
|
|
1862
2356
|
}
|
|
1863
2357
|
return {
|
|
1864
2358
|
auth,
|
|
2359
|
+
sessionKey,
|
|
2360
|
+
sessionSource,
|
|
1865
2361
|
preferredAccountId: route.preferredAccountId,
|
|
2362
|
+
preferredAccountGroup: route.preferredAccountGroup,
|
|
2363
|
+
boundAccountFallbackPolicy: route.boundAccountFallbackPolicy,
|
|
1866
2364
|
chain,
|
|
1867
2365
|
transformerProvider,
|
|
1868
2366
|
resolvedModel,
|
|
@@ -1872,12 +2370,15 @@ async function buildSubscriptionPlan3(res, route, deps, resolvedModel, isStream)
|
|
|
1872
2370
|
// profile's `resolveUpstreamUrl` for non-Code-Assist subscriptions.
|
|
1873
2371
|
resolveUrl: (config) => config.url instanceof URL ? config.url.toString() : typeof config.url === "string" ? config.url : upstreamUrl,
|
|
1874
2372
|
upstreamUrl,
|
|
1875
|
-
proxyProviderId: profile.authStrategy.providerId
|
|
2373
|
+
proxyProviderId: profile.authStrategy.providerId,
|
|
2374
|
+
// Only the codex backend understands these; other subscription providers
|
|
2375
|
+
// (gemini Code Assist) share this relay and must not receive them.
|
|
2376
|
+
callerClientHeaders: profile.authStrategy.providerId === "codex" ? _chunk3SCOLIPTcjs.extractCodexClientHeaders.call(void 0, requestHeaders) : void 0
|
|
1876
2377
|
};
|
|
1877
2378
|
}
|
|
1878
|
-
async function resolveGeminiCodeAssistProject(profile) {
|
|
2379
|
+
async function resolveGeminiCodeAssistProject(profile, hints) {
|
|
1879
2380
|
const probe = {};
|
|
1880
|
-
await profile.authStrategy.applyHeaders(probe);
|
|
2381
|
+
await profile.authStrategy.applyHeaders(probe, hints);
|
|
1881
2382
|
const bearer = _nullishCoalesce(_nullishCoalesce(probe.Authorization, () => ( probe.authorization)), () => ( ""));
|
|
1882
2383
|
const accessToken = bearer.replace(/^Bearer\s+/i, "").trim();
|
|
1883
2384
|
if (!accessToken) return void 0;
|
|
@@ -1888,19 +2389,23 @@ async function resolveGeminiCodeAssistProject(profile) {
|
|
|
1888
2389
|
async function runPipeline4(responsesBody, plan) {
|
|
1889
2390
|
const executor = getSharedExecutor();
|
|
1890
2391
|
const endpointTransformer = getResponsesEndpointTransformer();
|
|
1891
|
-
const { auth, chain, transformerProvider, resolvedModel, isStream, resolveUrl, upstreamUrl } = plan;
|
|
2392
|
+
const { auth, sessionKey, chain, transformerProvider, resolvedModel, isStream, resolveUrl, upstreamUrl } = plan;
|
|
1892
2393
|
let proxyAccountId;
|
|
2394
|
+
let activityRecordId;
|
|
1893
2395
|
const authHeaders = {};
|
|
1894
2396
|
await auth.applyHeaders(authHeaders, {
|
|
1895
2397
|
upstreamUrl,
|
|
1896
2398
|
model: resolvedModel,
|
|
2399
|
+
sessionKey,
|
|
1897
2400
|
preferredAccountId: plan.preferredAccountId,
|
|
2401
|
+
preferredAccountGroup: plan.preferredAccountGroup,
|
|
2402
|
+
boundAccountFallbackPolicy: plan.boundAccountFallbackPolicy,
|
|
1898
2403
|
reportSelection: (accountId) => {
|
|
1899
2404
|
proxyAccountId = accountId;
|
|
1900
2405
|
}
|
|
1901
2406
|
});
|
|
1902
2407
|
let rawStatus = null;
|
|
1903
|
-
const { response } = await
|
|
2408
|
+
const { response } = await _chunkMUHWHQVMcjs.executeProviderCall.call(void 0, {
|
|
1904
2409
|
executor,
|
|
1905
2410
|
request: responsesBody,
|
|
1906
2411
|
provider: transformerProvider,
|
|
@@ -1914,14 +2419,31 @@ async function runPipeline4(responsesBody, plan) {
|
|
|
1914
2419
|
if (value !== void 0 && !(key in headers)) headers[key] = value;
|
|
1915
2420
|
}
|
|
1916
2421
|
}
|
|
2422
|
+
if (plan.proxyProviderId === "codex") {
|
|
2423
|
+
_chunk3SCOLIPTcjs.fillMissingHeaders.call(void 0, headers, _nullishCoalesce(plan.callerClientHeaders, () => ( {})));
|
|
2424
|
+
_chunk3SCOLIPTcjs.fillMissingHeaders.call(void 0, headers, _chunk3SCOLIPTcjs.DEFAULT_CODEX_CLI_HEADERS);
|
|
2425
|
+
_chunk3SCOLIPTcjs.fillMissingHeaders.call(void 0, headers, { accept: _chunk3SCOLIPTcjs.codexAcceptHeader.call(void 0, isStream) });
|
|
2426
|
+
}
|
|
1917
2427
|
return headers;
|
|
1918
2428
|
},
|
|
1919
2429
|
fetchFn: (url, headers, body) => {
|
|
1920
2430
|
console.log(`[ProviderProxy:responses] -> ${url} model=${resolvedModel} stream=${isStream}`);
|
|
1921
|
-
return
|
|
2431
|
+
return _chunkRJUONLUQcjs.fetchUpstream.call(void 0,
|
|
1922
2432
|
url,
|
|
1923
2433
|
{ method: "POST", headers, body: JSON.stringify(body) },
|
|
1924
|
-
{
|
|
2434
|
+
{
|
|
2435
|
+
providerId: plan.proxyProviderId,
|
|
2436
|
+
accountId: proxyAccountId,
|
|
2437
|
+
routeActivity: plan.proxyProviderId === "byo" ? void 0 : {
|
|
2438
|
+
endpoint: "responses",
|
|
2439
|
+
sessionKey,
|
|
2440
|
+
sessionSource: _nullishCoalesce(plan.sessionSource, () => ( "none")),
|
|
2441
|
+
model: resolvedModel,
|
|
2442
|
+
onRecorded: (record) => {
|
|
2443
|
+
activityRecordId = record.id;
|
|
2444
|
+
}
|
|
2445
|
+
}
|
|
2446
|
+
}
|
|
1925
2447
|
).then((r) => {
|
|
1926
2448
|
rawStatus = r.status;
|
|
1927
2449
|
return r;
|
|
@@ -1929,12 +2451,12 @@ async function runPipeline4(responsesBody, plan) {
|
|
|
1929
2451
|
},
|
|
1930
2452
|
runResponseChain: true
|
|
1931
2453
|
});
|
|
1932
|
-
return { response, rawStatus };
|
|
2454
|
+
return { response, rawStatus, accountId: proxyAccountId, activityRecordId };
|
|
1933
2455
|
}
|
|
1934
2456
|
async function runPipelineWithPoolReporting4(responsesBody, plan) {
|
|
1935
2457
|
const first = await runPipeline4(responsesBody, plan);
|
|
1936
|
-
const outcome = await _optionalChain([plan, 'access',
|
|
1937
|
-
if (_optionalChain([outcome, 'optionalAccess',
|
|
2458
|
+
const outcome = await _optionalChain([plan, 'access', _73 => _73.auth, 'access', _74 => _74.onResult, 'optionalCall', _75 => _75(first.rawStatus)]);
|
|
2459
|
+
if (_optionalChain([outcome, 'optionalAccess', _76 => _76.rebound])) {
|
|
1938
2460
|
console.log(
|
|
1939
2461
|
"[ProviderProxy:responses] pool re-bound key after status",
|
|
1940
2462
|
first.rawStatus,
|
|
@@ -1947,7 +2469,7 @@ async function runPipelineWithPoolReporting4(responsesBody, plan) {
|
|
|
1947
2469
|
async function runPipelineWithSubscriptionRetry3(responsesBody, plan) {
|
|
1948
2470
|
const first = await runPipeline4(responsesBody, plan);
|
|
1949
2471
|
if (first.rawStatus !== 401) return first;
|
|
1950
|
-
const refreshed = await _optionalChain([plan, 'access',
|
|
2472
|
+
const refreshed = await _optionalChain([plan, 'access', _77 => _77.auth, 'access', _78 => _78.onUnauthorized, 'optionalCall', _79 => _79(plan.sessionKey)]);
|
|
1951
2473
|
if (!refreshed) {
|
|
1952
2474
|
console.warn("[ProviderProxy:responses] 401 not recoverable (onUnauthorized returned false)");
|
|
1953
2475
|
return first;
|
|
@@ -1955,6 +2477,22 @@ async function runPipelineWithSubscriptionRetry3(responsesBody, plan) {
|
|
|
1955
2477
|
console.log("[ProviderProxy:responses] 401 \u2192 token refreshed; retrying once");
|
|
1956
2478
|
return runPipeline4(responsesBody, plan);
|
|
1957
2479
|
}
|
|
2480
|
+
var MAX_QUOTA_RETRIES = 3;
|
|
2481
|
+
function isCodexAccountQuota429(plan, result) {
|
|
2482
|
+
return plan.proxyProviderId === "codex" && !!result.accountId && result.rawStatus === 429;
|
|
2483
|
+
}
|
|
2484
|
+
async function retryAroundCodexUsageLimit(responsesBody, plan, first, runAttempt = runPipelineWithSubscriptionRetry3) {
|
|
2485
|
+
if (!isCodexAccountQuota429(plan, first)) return first;
|
|
2486
|
+
let current = first;
|
|
2487
|
+
for (let attempt = 0; attempt < MAX_QUOTA_RETRIES; attempt++) {
|
|
2488
|
+
const errorBody = await current.response.text().catch(() => "");
|
|
2489
|
+
markCodexUsageLimitExhaustion(current.accountId, errorBody);
|
|
2490
|
+
const next = await runAttempt(responsesBody, plan);
|
|
2491
|
+
if (!isCodexAccountQuota429(plan, next)) return next;
|
|
2492
|
+
current = next;
|
|
2493
|
+
}
|
|
2494
|
+
return current;
|
|
2495
|
+
}
|
|
1958
2496
|
|
|
1959
2497
|
// src/provider-proxy/providerProxyRouter.ts
|
|
1960
2498
|
function extractRouteToken(authHeader) {
|
|
@@ -1969,7 +2507,7 @@ function resolveRouteToken(req) {
|
|
|
1969
2507
|
if (fromAuth) return fromAuth;
|
|
1970
2508
|
const googKey = req.headers["x-goog-api-key"];
|
|
1971
2509
|
const value = Array.isArray(googKey) ? googKey[0] : googKey;
|
|
1972
|
-
return _optionalChain([value, 'optionalAccess',
|
|
2510
|
+
return _optionalChain([value, 'optionalAccess', _80 => _80.trim, 'call', _81 => _81()]) || void 0;
|
|
1973
2511
|
}
|
|
1974
2512
|
async function routeRequest(req, res, routes, deps) {
|
|
1975
2513
|
const token = resolveRouteToken(req);
|
|
@@ -1986,7 +2524,7 @@ async function routeRequest(req, res, routes, deps) {
|
|
|
1986
2524
|
}
|
|
1987
2525
|
if (isOpenAIResponsesRequest(method, url)) {
|
|
1988
2526
|
const rawBody = await readBody(req);
|
|
1989
|
-
await handleOpenAIResponsesRequest(res, rawBody, route, deps);
|
|
2527
|
+
await handleOpenAIResponsesRequest(res, rawBody, route, deps, req.headers);
|
|
1990
2528
|
return;
|
|
1991
2529
|
}
|
|
1992
2530
|
if (isOpenAIChatRequest(method, url)) {
|
|
@@ -2177,11 +2715,11 @@ var DEFAULT_ACCOUNT_HEALTH = {
|
|
|
2177
2715
|
overloadCooldownMs: 10 * 6e4
|
|
2178
2716
|
};
|
|
2179
2717
|
function normalizeAccountHealth(raw) {
|
|
2180
|
-
const ah = _optionalChain([raw, 'optionalAccess',
|
|
2718
|
+
const ah = _optionalChain([raw, 'optionalAccess', _82 => _82.accountHealth]);
|
|
2181
2719
|
return {
|
|
2182
|
-
overloadCooldownEnabled: _optionalChain([ah, 'optionalAccess',
|
|
2720
|
+
overloadCooldownEnabled: _optionalChain([ah, 'optionalAccess', _83 => _83.overloadCooldownEnabled]) !== false,
|
|
2183
2721
|
overloadCooldownMs: clampNumber(
|
|
2184
|
-
_optionalChain([ah, 'optionalAccess',
|
|
2722
|
+
_optionalChain([ah, 'optionalAccess', _84 => _84.overloadCooldownMs]),
|
|
2185
2723
|
6e4,
|
|
2186
2724
|
36e5,
|
|
2187
2725
|
DEFAULT_ACCOUNT_HEALTH.overloadCooldownMs
|
|
@@ -2196,54 +2734,91 @@ var DEFAULT_ACCOUNT_PROBE = {
|
|
|
2196
2734
|
historySize: 10,
|
|
2197
2735
|
staggerMs: 500
|
|
2198
2736
|
};
|
|
2737
|
+
var DEFAULT_ALLOWANCE_SCHEDULING = {
|
|
2738
|
+
enabled: false,
|
|
2739
|
+
demoteAtPercent: 80,
|
|
2740
|
+
pauseAtPercent: 98,
|
|
2741
|
+
priorityPenalty: 100
|
|
2742
|
+
};
|
|
2743
|
+
function normalizeAllowanceScheduling(raw) {
|
|
2744
|
+
const value = _optionalChain([raw, 'optionalAccess', _85 => _85.allowanceScheduling]);
|
|
2745
|
+
const demoteAtPercent = clampNumber(
|
|
2746
|
+
_optionalChain([value, 'optionalAccess', _86 => _86.demoteAtPercent]),
|
|
2747
|
+
0,
|
|
2748
|
+
100,
|
|
2749
|
+
DEFAULT_ALLOWANCE_SCHEDULING.demoteAtPercent
|
|
2750
|
+
);
|
|
2751
|
+
const requestedPause = clampNumber(
|
|
2752
|
+
_optionalChain([value, 'optionalAccess', _87 => _87.pauseAtPercent]),
|
|
2753
|
+
0,
|
|
2754
|
+
100,
|
|
2755
|
+
DEFAULT_ALLOWANCE_SCHEDULING.pauseAtPercent
|
|
2756
|
+
);
|
|
2757
|
+
return {
|
|
2758
|
+
enabled: _optionalChain([value, 'optionalAccess', _88 => _88.enabled]) === true,
|
|
2759
|
+
demoteAtPercent,
|
|
2760
|
+
pauseAtPercent: Math.max(demoteAtPercent, requestedPause),
|
|
2761
|
+
priorityPenalty: Math.trunc(clampNumber(
|
|
2762
|
+
_optionalChain([value, 'optionalAccess', _89 => _89.priorityPenalty]),
|
|
2763
|
+
1,
|
|
2764
|
+
1e3,
|
|
2765
|
+
DEFAULT_ALLOWANCE_SCHEDULING.priorityPenalty
|
|
2766
|
+
))
|
|
2767
|
+
};
|
|
2768
|
+
}
|
|
2199
2769
|
function normalizeAccountProbe(raw) {
|
|
2200
|
-
const ap = _optionalChain([raw, 'optionalAccess',
|
|
2770
|
+
const ap = _optionalChain([raw, 'optionalAccess', _90 => _90.accountProbe]);
|
|
2201
2771
|
return {
|
|
2202
|
-
enabled: _optionalChain([ap, 'optionalAccess',
|
|
2203
|
-
intervalMs: clampNumber(_optionalChain([ap, 'optionalAccess',
|
|
2204
|
-
onlyMultiAccount: _optionalChain([ap, 'optionalAccess',
|
|
2205
|
-
timeoutMs: clampNumber(_optionalChain([ap, 'optionalAccess',
|
|
2772
|
+
enabled: _optionalChain([ap, 'optionalAccess', _91 => _91.enabled]) === true,
|
|
2773
|
+
intervalMs: clampNumber(_optionalChain([ap, 'optionalAccess', _92 => _92.intervalMs]), 6e4, 864e5, DEFAULT_ACCOUNT_PROBE.intervalMs),
|
|
2774
|
+
onlyMultiAccount: _optionalChain([ap, 'optionalAccess', _93 => _93.onlyMultiAccount]) !== false,
|
|
2775
|
+
timeoutMs: clampNumber(_optionalChain([ap, 'optionalAccess', _94 => _94.timeoutMs]), 1e3, 6e4, DEFAULT_ACCOUNT_PROBE.timeoutMs),
|
|
2206
2776
|
historySize: Math.trunc(
|
|
2207
|
-
clampNumber(_optionalChain([ap, 'optionalAccess',
|
|
2777
|
+
clampNumber(_optionalChain([ap, 'optionalAccess', _95 => _95.historySize]), 1, 200, DEFAULT_ACCOUNT_PROBE.historySize)
|
|
2208
2778
|
),
|
|
2209
|
-
staggerMs: clampNumber(_optionalChain([ap, 'optionalAccess',
|
|
2779
|
+
staggerMs: clampNumber(_optionalChain([ap, 'optionalAccess', _96 => _96.staggerMs]), 0, 6e4, DEFAULT_ACCOUNT_PROBE.staggerMs)
|
|
2210
2780
|
};
|
|
2211
2781
|
}
|
|
2212
2782
|
function normalizeAudit(raw) {
|
|
2213
|
-
const a = _optionalChain([raw, 'optionalAccess',
|
|
2783
|
+
const a = _optionalChain([raw, 'optionalAccess', _97 => _97.audit]);
|
|
2214
2784
|
return {
|
|
2215
|
-
enabled: _optionalChain([a, 'optionalAccess',
|
|
2216
|
-
captureBodies: _optionalChain([a, 'optionalAccess',
|
|
2217
|
-
maxBodyBytes:
|
|
2218
|
-
clampNumber(_optionalChain([a, 'optionalAccess', _84 => _84.maxBodyBytes]), 256, 1048576, _audittypes.DEFAULT_AUDIT_CONFIG.maxBodyBytes)
|
|
2219
|
-
),
|
|
2785
|
+
enabled: _optionalChain([a, 'optionalAccess', _98 => _98.enabled]) === true,
|
|
2786
|
+
captureBodies: _optionalChain([a, 'optionalAccess', _99 => _99.captureBodies]) === true,
|
|
2787
|
+
maxBodyBytes: normalizeMaxBodyBytes(_optionalChain([a, 'optionalAccess', _100 => _100.maxBodyBytes])),
|
|
2220
2788
|
retentionDays: Math.trunc(
|
|
2221
|
-
clampNumber(_optionalChain([a, 'optionalAccess',
|
|
2789
|
+
clampNumber(_optionalChain([a, 'optionalAccess', _101 => _101.retentionDays]), 1, 365, _audittypes.DEFAULT_AUDIT_CONFIG.retentionDays)
|
|
2222
2790
|
),
|
|
2223
|
-
trustForwardedFor: _optionalChain([a, 'optionalAccess',
|
|
2791
|
+
trustForwardedFor: _optionalChain([a, 'optionalAccess', _102 => _102.trustForwardedFor]) === true
|
|
2224
2792
|
};
|
|
2225
2793
|
}
|
|
2794
|
+
function normalizeMaxBodyBytes(value) {
|
|
2795
|
+
if (value === -1) return -1;
|
|
2796
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
|
|
2797
|
+
return _audittypes.DEFAULT_AUDIT_CONFIG.maxBodyBytes;
|
|
2798
|
+
}
|
|
2799
|
+
return Math.trunc(Math.min(1048576, value));
|
|
2800
|
+
}
|
|
2226
2801
|
function normalizeBilling(raw) {
|
|
2227
|
-
const b = _optionalChain([raw, 'optionalAccess',
|
|
2802
|
+
const b = _optionalChain([raw, 'optionalAccess', _103 => _103.billing]);
|
|
2228
2803
|
const config = {
|
|
2229
|
-
enabled: _optionalChain([b, 'optionalAccess',
|
|
2804
|
+
enabled: _optionalChain([b, 'optionalAccess', _104 => _104.enabled]) === true,
|
|
2230
2805
|
maxRetryAgeMs: Math.trunc(
|
|
2231
|
-
clampNumber(_optionalChain([b, 'optionalAccess',
|
|
2806
|
+
clampNumber(_optionalChain([b, 'optionalAccess', _105 => _105.maxRetryAgeMs]), 6e4, 2592e6, _billingtypes.DEFAULT_BILLING_CONFIG.maxRetryAgeMs)
|
|
2232
2807
|
)
|
|
2233
2808
|
};
|
|
2234
|
-
if (typeof _optionalChain([b, 'optionalAccess',
|
|
2235
|
-
if (typeof _optionalChain([b, 'optionalAccess',
|
|
2809
|
+
if (typeof _optionalChain([b, 'optionalAccess', _106 => _106.endpoint]) === "string" && b.endpoint.trim()) config.endpoint = b.endpoint.trim();
|
|
2810
|
+
if (typeof _optionalChain([b, 'optionalAccess', _107 => _107.secret]) === "string" && b.secret.length > 0) config.secret = b.secret;
|
|
2236
2811
|
return config;
|
|
2237
2812
|
}
|
|
2238
2813
|
var DEFAULT_FINGERPRINT = { enabled: false };
|
|
2239
2814
|
function normalizeFingerprint(raw) {
|
|
2240
|
-
const f = _optionalChain([raw, 'optionalAccess',
|
|
2241
|
-
const out = { enabled: _optionalChain([f, 'optionalAccess',
|
|
2242
|
-
if (typeof _optionalChain([f, 'optionalAccess',
|
|
2815
|
+
const f = _optionalChain([raw, 'optionalAccess', _108 => _108.fingerprint]);
|
|
2816
|
+
const out = { enabled: _optionalChain([f, 'optionalAccess', _109 => _109.enabled]) === true };
|
|
2817
|
+
if (typeof _optionalChain([f, 'optionalAccess', _110 => _110.ua]) === "string" && f.ua.trim().length > 0) out.ua = f.ua.trim();
|
|
2243
2818
|
return out;
|
|
2244
2819
|
}
|
|
2245
2820
|
function normalizeVoucher(raw) {
|
|
2246
|
-
return { enabled: _optionalChain([raw, 'optionalAccess',
|
|
2821
|
+
return { enabled: _optionalChain([raw, 'optionalAccess', _111 => _111.voucher, 'optionalAccess', _112 => _112.enabled]) === true };
|
|
2247
2822
|
}
|
|
2248
2823
|
var PROXY_TYPES = ["http", "https", "socks5"];
|
|
2249
2824
|
function normalizeProxyConfig(raw) {
|
|
@@ -2327,14 +2902,14 @@ function clampNumber(value, min, max, fallback) {
|
|
|
2327
2902
|
return Math.min(max, Math.max(min, n));
|
|
2328
2903
|
}
|
|
2329
2904
|
function normalizeQueueSegments(raw) {
|
|
2330
|
-
const umq = _optionalChain([raw, 'optionalAccess',
|
|
2331
|
-
const cq = _optionalChain([raw, 'optionalAccess',
|
|
2905
|
+
const umq = _optionalChain([raw, 'optionalAccess', _113 => _113.userMessageQueue]);
|
|
2906
|
+
const cq = _optionalChain([raw, 'optionalAccess', _114 => _114.concurrencyQueue]);
|
|
2332
2907
|
return {
|
|
2333
2908
|
userMessageQueue: {
|
|
2334
|
-
enabled: _optionalChain([umq, 'optionalAccess',
|
|
2335
|
-
delayMs: clampNumber(_optionalChain([umq, 'optionalAccess',
|
|
2909
|
+
enabled: _optionalChain([umq, 'optionalAccess', _115 => _115.enabled]) === true,
|
|
2910
|
+
delayMs: clampNumber(_optionalChain([umq, 'optionalAccess', _116 => _116.delayMs]), 0, 1e4, DEFAULT_USER_MESSAGE_QUEUE.delayMs),
|
|
2336
2911
|
waitTimeoutMs: clampNumber(
|
|
2337
|
-
_optionalChain([umq, 'optionalAccess',
|
|
2912
|
+
_optionalChain([umq, 'optionalAccess', _117 => _117.waitTimeoutMs]),
|
|
2338
2913
|
1e3,
|
|
2339
2914
|
3e5,
|
|
2340
2915
|
DEFAULT_USER_MESSAGE_QUEUE.waitTimeoutMs
|
|
@@ -2342,14 +2917,14 @@ function normalizeQueueSegments(raw) {
|
|
|
2342
2917
|
},
|
|
2343
2918
|
concurrencyQueue: {
|
|
2344
2919
|
maxQueueSizeFactor: clampNumber(
|
|
2345
|
-
_optionalChain([cq, 'optionalAccess',
|
|
2920
|
+
_optionalChain([cq, 'optionalAccess', _118 => _118.maxQueueSizeFactor]),
|
|
2346
2921
|
1,
|
|
2347
2922
|
10,
|
|
2348
2923
|
DEFAULT_CONCURRENCY_QUEUE.maxQueueSizeFactor
|
|
2349
2924
|
),
|
|
2350
|
-
minQueueSize: clampNumber(_optionalChain([cq, 'optionalAccess',
|
|
2925
|
+
minQueueSize: clampNumber(_optionalChain([cq, 'optionalAccess', _119 => _119.minQueueSize]), 1, 100, DEFAULT_CONCURRENCY_QUEUE.minQueueSize),
|
|
2351
2926
|
waitTimeoutMs: clampNumber(
|
|
2352
|
-
_optionalChain([cq, 'optionalAccess',
|
|
2927
|
+
_optionalChain([cq, 'optionalAccess', _120 => _120.waitTimeoutMs]),
|
|
2353
2928
|
1e3,
|
|
2354
2929
|
3e5,
|
|
2355
2930
|
DEFAULT_CONCURRENCY_QUEUE.waitTimeoutMs
|
|
@@ -2360,11 +2935,11 @@ function normalizeQueueSegments(raw) {
|
|
|
2360
2935
|
var ALL_ENDPOINTS = ["chat", "responses", "messages", "gemini"];
|
|
2361
2936
|
function blankModelMap(endpoint) {
|
|
2362
2937
|
const modelMap = {};
|
|
2363
|
-
for (const kind of
|
|
2938
|
+
for (const kind of _chunk4VZX5F4Tcjs.modelKindsForEndpoint.call(void 0, endpoint)) modelMap[kind] = "";
|
|
2364
2939
|
return modelMap;
|
|
2365
2940
|
}
|
|
2366
2941
|
function defaultEndpointConfig(endpoint) {
|
|
2367
|
-
if (
|
|
2942
|
+
if (_chunk4VZX5F4Tcjs.isKindMappedEndpoint.call(void 0, endpoint)) {
|
|
2368
2943
|
return { endpoint, modelMap: blankModelMap(endpoint), useSubscription: false };
|
|
2369
2944
|
}
|
|
2370
2945
|
if (endpoint === "chat") {
|
|
@@ -2390,13 +2965,14 @@ function normalizePrefixTargets(raw) {
|
|
|
2390
2965
|
function normalizeEndpointConfig(e) {
|
|
2391
2966
|
const endpoint = e.endpoint;
|
|
2392
2967
|
const useSubscription = e.useSubscription === true;
|
|
2393
|
-
const boundAccountId = typeof e.boundAccountId === "string" && e.boundAccountId.trim() !== "" ? e.boundAccountId : void 0;
|
|
2968
|
+
const boundAccountId = typeof e.boundAccountId === "string" && e.boundAccountId.trim() !== "" ? e.boundAccountId.trim() : void 0;
|
|
2969
|
+
const boundAccountFallbackPolicy = boundAccountId ? e.boundAccountFallbackPolicy === "pool" ? "pool" : "strict" : void 0;
|
|
2394
2970
|
const boundKeyId = typeof e.boundKeyId === "string" && e.boundKeyId.trim() !== "" ? e.boundKeyId : void 0;
|
|
2395
2971
|
let config;
|
|
2396
|
-
if (
|
|
2972
|
+
if (_chunk4VZX5F4Tcjs.isKindMappedEndpoint.call(void 0, endpoint)) {
|
|
2397
2973
|
const rawMap = e.modelMap && typeof e.modelMap === "object" ? e.modelMap : {};
|
|
2398
2974
|
const modelMap = {};
|
|
2399
|
-
for (const kind of
|
|
2975
|
+
for (const kind of _chunk4VZX5F4Tcjs.modelKindsForEndpoint.call(void 0, endpoint)) {
|
|
2400
2976
|
const v = rawMap[kind];
|
|
2401
2977
|
modelMap[kind] = typeof v === "string" ? v : "";
|
|
2402
2978
|
}
|
|
@@ -2420,21 +2996,186 @@ function normalizeEndpointConfig(e) {
|
|
|
2420
2996
|
config.backgroundModelIds = e.backgroundModelIds;
|
|
2421
2997
|
}
|
|
2422
2998
|
}
|
|
2423
|
-
if (boundAccountId)
|
|
2999
|
+
if (boundAccountId) {
|
|
3000
|
+
config.boundAccountId = boundAccountId;
|
|
3001
|
+
config.boundAccountFallbackPolicy = boundAccountFallbackPolicy;
|
|
3002
|
+
}
|
|
2424
3003
|
if (boundKeyId) config.boundKeyId = boundKeyId;
|
|
2425
3004
|
return config;
|
|
2426
3005
|
}
|
|
3006
|
+
function normalizeBindingTarget(raw) {
|
|
3007
|
+
if (!raw || typeof raw !== "object") return null;
|
|
3008
|
+
const target = raw;
|
|
3009
|
+
const providerId = typeof target.providerId === "string" ? target.providerId.trim() : "";
|
|
3010
|
+
if (!providerId) return null;
|
|
3011
|
+
if (target.kind === "account") {
|
|
3012
|
+
const accountId = typeof target.accountId === "string" ? target.accountId.trim() : "";
|
|
3013
|
+
return accountId ? { kind: "account", providerId, accountId } : null;
|
|
3014
|
+
}
|
|
3015
|
+
if (target.kind === "account-group") {
|
|
3016
|
+
const group = typeof target.group === "string" ? target.group.trim() : "";
|
|
3017
|
+
return group ? { kind: "account-group", providerId, group } : null;
|
|
3018
|
+
}
|
|
3019
|
+
if (target.kind === "account-pool") return { kind: "account-pool", providerId };
|
|
3020
|
+
if (target.kind === "provider") {
|
|
3021
|
+
const keyId = typeof target.keyId === "string" ? target.keyId.trim() : "";
|
|
3022
|
+
return keyId ? { kind: "provider", providerId, keyId } : { kind: "provider", providerId };
|
|
3023
|
+
}
|
|
3024
|
+
return null;
|
|
3025
|
+
}
|
|
3026
|
+
function normalizeGatewayModelMappings(raw) {
|
|
3027
|
+
if (!Array.isArray(raw)) return [];
|
|
3028
|
+
const mappings = [];
|
|
3029
|
+
for (const entry of raw) {
|
|
3030
|
+
if (!entry || typeof entry !== "object") continue;
|
|
3031
|
+
const value = entry;
|
|
3032
|
+
const source = typeof value.source === "string" ? value.source.trim() : "";
|
|
3033
|
+
const target = typeof value.target === "string" ? value.target.trim() : "";
|
|
3034
|
+
if (!source || !target) continue;
|
|
3035
|
+
mappings.push({ source, target });
|
|
3036
|
+
}
|
|
3037
|
+
return mappings;
|
|
3038
|
+
}
|
|
3039
|
+
function hasConfiguredLegacyModels(config) {
|
|
3040
|
+
return Object.values(_nullishCoalesce(config.modelMap, () => ( {}))).some((value) => typeof value === "string" && value.trim()) || Boolean(_optionalChain([config, 'access', _121 => _121.models, 'optionalAccess', _122 => _122.some, 'call', _123 => _123((value) => typeof value === "string" && value.trim())])) || Boolean(_optionalChain([config, 'access', _124 => _124.defaultModel, 'optionalAccess', _125 => _125.trim, 'call', _126 => _126()])) || Boolean(_optionalChain([config, 'access', _127 => _127.backgroundModel, 'optionalAccess', _128 => _128.trim, 'call', _129 => _129()])) || Boolean(Object.values(_nullishCoalesce(config.prefixTargets, () => ( {}))).some((value) => _optionalChain([value, 'optionalAccess', _130 => _130.trim, 'call', _131 => _131()])));
|
|
3041
|
+
}
|
|
3042
|
+
function splitModelRef(ref) {
|
|
3043
|
+
if (typeof ref !== "string") return null;
|
|
3044
|
+
const idx = ref.indexOf(",");
|
|
3045
|
+
if (idx <= 0) return null;
|
|
3046
|
+
const providerId = ref.slice(0, idx).trim();
|
|
3047
|
+
const modelId = ref.slice(idx + 1).trim();
|
|
3048
|
+
return providerId && modelId ? { providerId, modelId } : null;
|
|
3049
|
+
}
|
|
3050
|
+
function legacyTarget(config, providerId) {
|
|
3051
|
+
if (config.useSubscription) {
|
|
3052
|
+
if (config.boundAccountId) {
|
|
3053
|
+
return { kind: "account", providerId, accountId: config.boundAccountId };
|
|
3054
|
+
}
|
|
3055
|
+
if (config.boundAccountGroup) {
|
|
3056
|
+
return { kind: "account-group", providerId, group: config.boundAccountGroup };
|
|
3057
|
+
}
|
|
3058
|
+
return { kind: "account-pool", providerId };
|
|
3059
|
+
}
|
|
3060
|
+
return config.boundKeyId ? { kind: "provider", providerId, keyId: config.boundKeyId } : { kind: "provider", providerId };
|
|
3061
|
+
}
|
|
3062
|
+
function legacyEndpointToBindings(config) {
|
|
3063
|
+
const fallback = config.boundAccountId && config.boundAccountFallbackPolicy === "strict" ? "fail" : "next";
|
|
3064
|
+
const byProvider = /* @__PURE__ */ new Map();
|
|
3065
|
+
const routeFor = (providerId) => {
|
|
3066
|
+
const existing = byProvider.get(providerId);
|
|
3067
|
+
if (existing) return existing;
|
|
3068
|
+
const created = {
|
|
3069
|
+
id: `legacy-${config.endpoint}-${providerId}`,
|
|
3070
|
+
name: `${config.endpoint} \xB7 ${providerId}`,
|
|
3071
|
+
enabled: true,
|
|
3072
|
+
keyScope: "all",
|
|
3073
|
+
endpoint: config.endpoint,
|
|
3074
|
+
target: legacyTarget(config, providerId),
|
|
3075
|
+
fallback,
|
|
3076
|
+
modelMode: "mapped"
|
|
3077
|
+
};
|
|
3078
|
+
byProvider.set(providerId, created);
|
|
3079
|
+
return created;
|
|
3080
|
+
};
|
|
3081
|
+
for (const [kind, ref] of Object.entries(_nullishCoalesce(config.modelMap, () => ( {})))) {
|
|
3082
|
+
const parsed = splitModelRef(ref);
|
|
3083
|
+
if (!parsed) continue;
|
|
3084
|
+
const route = routeFor(parsed.providerId);
|
|
3085
|
+
route.modelMap = { ...route.modelMap, [kind]: ref };
|
|
3086
|
+
}
|
|
3087
|
+
for (const ref of _nullishCoalesce(config.models, () => ( []))) {
|
|
3088
|
+
const parsed = splitModelRef(ref);
|
|
3089
|
+
if (!parsed) continue;
|
|
3090
|
+
const route = routeFor(parsed.providerId);
|
|
3091
|
+
route.models = [..._nullishCoalesce(route.models, () => ( [])), ref];
|
|
3092
|
+
}
|
|
3093
|
+
for (const [prefix, ref] of Object.entries(_nullishCoalesce(config.prefixTargets, () => ( {})))) {
|
|
3094
|
+
const parsed = splitModelRef(ref);
|
|
3095
|
+
if (!parsed) continue;
|
|
3096
|
+
const route = routeFor(parsed.providerId);
|
|
3097
|
+
route.dispatchMode = "prefix";
|
|
3098
|
+
route.prefixTargets = { ...route.prefixTargets, [prefix]: ref };
|
|
3099
|
+
}
|
|
3100
|
+
for (const [field, ref] of [
|
|
3101
|
+
["defaultModel", config.defaultModel],
|
|
3102
|
+
["backgroundModel", config.backgroundModel]
|
|
3103
|
+
]) {
|
|
3104
|
+
const parsed = splitModelRef(ref);
|
|
3105
|
+
if (!parsed) continue;
|
|
3106
|
+
const route = routeFor(parsed.providerId);
|
|
3107
|
+
route[field] = ref;
|
|
3108
|
+
if (_optionalChain([config, 'access', _132 => _132.backgroundModelIds, 'optionalAccess', _133 => _133.length])) {
|
|
3109
|
+
route.backgroundModelIds = [...config.backgroundModelIds];
|
|
3110
|
+
}
|
|
3111
|
+
}
|
|
3112
|
+
return [...byProvider.values()];
|
|
3113
|
+
}
|
|
3114
|
+
function legacyEndpointsToBindings(endpoints) {
|
|
3115
|
+
return endpoints.filter((endpoint) => hasConfiguredLegacyModels(endpoint)).flatMap((endpoint) => legacyEndpointToBindings(endpoint));
|
|
3116
|
+
}
|
|
3117
|
+
function normalizeGatewayBindings(raw) {
|
|
3118
|
+
if (!Array.isArray(raw)) return [];
|
|
3119
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3120
|
+
const bindings = [];
|
|
3121
|
+
for (const entry of raw) {
|
|
3122
|
+
if (!entry || typeof entry !== "object") continue;
|
|
3123
|
+
const value = entry;
|
|
3124
|
+
const id = typeof value.id === "string" ? value.id.trim() : "";
|
|
3125
|
+
const name = typeof value.name === "string" ? value.name.trim() : "";
|
|
3126
|
+
const endpoint = value.endpoint;
|
|
3127
|
+
const target = normalizeBindingTarget(value.target);
|
|
3128
|
+
if (!id || seen.has(id) || !name || !ALL_ENDPOINTS.includes(endpoint) || !target) continue;
|
|
3129
|
+
seen.add(id);
|
|
3130
|
+
const normalizedRoute = normalizeEndpointConfig({
|
|
3131
|
+
...value,
|
|
3132
|
+
endpoint,
|
|
3133
|
+
useSubscription: target.kind !== "provider"
|
|
3134
|
+
});
|
|
3135
|
+
const apiKeyIds = Array.isArray(value.apiKeyIds) ? [...new Set(value.apiKeyIds.filter((key) => typeof key === "string" && key.trim() !== "").map((key) => key.trim()))] : [];
|
|
3136
|
+
const keyScope = value.keyScope === "selected" ? "selected" : value.keyScope === "all" ? "all" : apiKeyIds.length > 0 ? "selected" : "all";
|
|
3137
|
+
const modelMappings = normalizeGatewayModelMappings(value.modelMappings);
|
|
3138
|
+
const modelMode = value.modelMode === "passthrough" ? "passthrough" : value.modelMode === "mapped" ? "mapped" : modelMappings.length > 0 || hasConfiguredLegacyModels(normalizedRoute) ? "mapped" : "passthrough";
|
|
3139
|
+
const priority = typeof value.priority === "number" && Number.isFinite(value.priority) ? Math.max(0, Math.min(1e4, Math.round(value.priority))) : void 0;
|
|
3140
|
+
const binding = {
|
|
3141
|
+
id,
|
|
3142
|
+
name,
|
|
3143
|
+
enabled: value.enabled !== false,
|
|
3144
|
+
keyScope,
|
|
3145
|
+
endpoint,
|
|
3146
|
+
target,
|
|
3147
|
+
// Legacy `'global'` meant "yield to the removed global endpoint fallback";
|
|
3148
|
+
// it now yields to the next matching route, which is the same default.
|
|
3149
|
+
fallback: value.fallback === "fail" ? "fail" : "next",
|
|
3150
|
+
modelMode
|
|
3151
|
+
};
|
|
3152
|
+
if (apiKeyIds.length > 0) binding.apiKeyIds = apiKeyIds;
|
|
3153
|
+
if (modelMappings.length > 0) binding.modelMappings = modelMappings;
|
|
3154
|
+
if (priority !== void 0) binding.priority = priority;
|
|
3155
|
+
if (normalizedRoute.modelMap) binding.modelMap = normalizedRoute.modelMap;
|
|
3156
|
+
if (normalizedRoute.models) binding.models = normalizedRoute.models;
|
|
3157
|
+
if (normalizedRoute.dispatchMode) binding.dispatchMode = normalizedRoute.dispatchMode;
|
|
3158
|
+
if (normalizedRoute.prefixTargets) binding.prefixTargets = normalizedRoute.prefixTargets;
|
|
3159
|
+
if (normalizedRoute.defaultModel !== void 0) binding.defaultModel = normalizedRoute.defaultModel;
|
|
3160
|
+
if (normalizedRoute.backgroundModel !== void 0) binding.backgroundModel = normalizedRoute.backgroundModel;
|
|
3161
|
+
if (normalizedRoute.backgroundModelIds) binding.backgroundModelIds = normalizedRoute.backgroundModelIds;
|
|
3162
|
+
bindings.push(binding);
|
|
3163
|
+
}
|
|
3164
|
+
return bindings;
|
|
3165
|
+
}
|
|
2427
3166
|
function defaultServerConfig() {
|
|
2428
3167
|
const queues = normalizeQueueSegments(void 0);
|
|
2429
3168
|
return {
|
|
2430
3169
|
enabled: false,
|
|
2431
3170
|
networkBinding: false,
|
|
2432
3171
|
endpoints: ALL_ENDPOINTS.map(defaultEndpointConfig),
|
|
3172
|
+
bindings: [],
|
|
2433
3173
|
port: DEFAULT_OUTBOUND_PORT,
|
|
2434
3174
|
userMessageQueue: queues.userMessageQueue,
|
|
2435
3175
|
concurrencyQueue: queues.concurrencyQueue,
|
|
2436
3176
|
accountHealth: normalizeAccountHealth(void 0),
|
|
2437
3177
|
accountProbe: normalizeAccountProbe(void 0),
|
|
3178
|
+
allowanceScheduling: normalizeAllowanceScheduling(void 0),
|
|
2438
3179
|
audit: normalizeAudit(void 0),
|
|
2439
3180
|
billing: normalizeBilling(void 0),
|
|
2440
3181
|
fingerprint: normalizeFingerprint(void 0),
|
|
@@ -2451,17 +3192,20 @@ function normalizeServerConfig(raw) {
|
|
|
2451
3192
|
}
|
|
2452
3193
|
}
|
|
2453
3194
|
const queues = normalizeQueueSegments(raw);
|
|
3195
|
+
const legacyEndpoints = ALL_ENDPOINTS.map((ep) => _nullishCoalesce(byEndpoint.get(ep), () => ( defaultEndpointConfig(ep))));
|
|
3196
|
+
const persistedBindings = normalizeGatewayBindings(raw.bindings);
|
|
3197
|
+
const bindings = persistedBindings.length > 0 ? persistedBindings : normalizeGatewayBindings(legacyEndpointsToBindings(legacyEndpoints));
|
|
2454
3198
|
const config = {
|
|
2455
3199
|
enabled: raw.enabled === true,
|
|
2456
3200
|
networkBinding: raw.networkBinding === true,
|
|
2457
|
-
endpoints: ALL_ENDPOINTS.map(
|
|
2458
|
-
|
|
2459
|
-
),
|
|
3201
|
+
endpoints: ALL_ENDPOINTS.map(defaultEndpointConfig),
|
|
3202
|
+
bindings,
|
|
2460
3203
|
port: _nullishCoalesce(raw.port, () => ( base.port)),
|
|
2461
3204
|
userMessageQueue: queues.userMessageQueue,
|
|
2462
3205
|
concurrencyQueue: queues.concurrencyQueue,
|
|
2463
3206
|
accountHealth: normalizeAccountHealth(raw),
|
|
2464
3207
|
accountProbe: normalizeAccountProbe(raw),
|
|
3208
|
+
allowanceScheduling: normalizeAllowanceScheduling(raw),
|
|
2465
3209
|
audit: normalizeAudit(raw),
|
|
2466
3210
|
billing: normalizeBilling(raw),
|
|
2467
3211
|
fingerprint: normalizeFingerprint(raw),
|
|
@@ -2487,11 +3231,13 @@ function mergeServerConfig(current, patch) {
|
|
|
2487
3231
|
enabled: _nullishCoalesce(patch.enabled, () => ( current.enabled)),
|
|
2488
3232
|
networkBinding: _nullishCoalesce(patch.networkBinding, () => ( current.networkBinding)),
|
|
2489
3233
|
endpoints: _nullishCoalesce(patch.endpoints, () => ( current.endpoints)),
|
|
3234
|
+
bindings: _nullishCoalesce(patch.bindings, () => ( current.bindings)),
|
|
2490
3235
|
port: _nullishCoalesce(patch.port, () => ( current.port)),
|
|
2491
3236
|
userMessageQueue: _nullishCoalesce(patch.userMessageQueue, () => ( current.userMessageQueue)),
|
|
2492
3237
|
concurrencyQueue: _nullishCoalesce(patch.concurrencyQueue, () => ( current.concurrencyQueue)),
|
|
2493
3238
|
accountHealth: _nullishCoalesce(patch.accountHealth, () => ( current.accountHealth)),
|
|
2494
3239
|
accountProbe: _nullishCoalesce(patch.accountProbe, () => ( current.accountProbe)),
|
|
3240
|
+
allowanceScheduling: _nullishCoalesce(patch.allowanceScheduling, () => ( current.allowanceScheduling)),
|
|
2495
3241
|
audit: _nullishCoalesce(patch.audit, () => ( current.audit)),
|
|
2496
3242
|
billing: _nullishCoalesce(patch.billing, () => ( current.billing)),
|
|
2497
3243
|
// Proxy is layer-replaced (not deep-merged): a PUT carrying `proxy` swaps the
|
|
@@ -2509,6 +3255,167 @@ function mergeServerConfig(current, patch) {
|
|
|
2509
3255
|
});
|
|
2510
3256
|
}
|
|
2511
3257
|
|
|
3258
|
+
// src/outbound-api/gatewayBindingResolver.ts
|
|
3259
|
+
var MESSAGE_FALLBACK_KINDS = ["sonnet", "opus", "haiku", "fable"];
|
|
3260
|
+
function nonBlank(value) {
|
|
3261
|
+
return typeof value === "string" && value.trim() !== "";
|
|
3262
|
+
}
|
|
3263
|
+
function gatewayBindingAllowsKey(binding, apiKeyId) {
|
|
3264
|
+
const scope = _nullishCoalesce(binding.keyScope, () => ( (_optionalChain([binding, 'access', _134 => _134.apiKeyIds, 'optionalAccess', _135 => _135.length]) ? "selected" : "all")));
|
|
3265
|
+
return scope === "all" || Boolean(_optionalChain([binding, 'access', _136 => _136.apiKeyIds, 'optionalAccess', _137 => _137.includes, 'call', _138 => _138(apiKeyId)]));
|
|
3266
|
+
}
|
|
3267
|
+
function wildcardMatches(pattern, value) {
|
|
3268
|
+
const escaped = pattern.split("*").map((part) => part.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&")).join(".*");
|
|
3269
|
+
return new RegExp(`^${escaped}$`, "iu").test(value);
|
|
3270
|
+
}
|
|
3271
|
+
function resolveGatewayModelMapping(mappings, requestedModel) {
|
|
3272
|
+
if (!nonBlank(requestedModel)) return void 0;
|
|
3273
|
+
const wanted = requestedModel.trim();
|
|
3274
|
+
const exact = (_nullishCoalesce(mappings, () => ( []))).find(
|
|
3275
|
+
(mapping) => nonBlank(mapping.source) && !mapping.source.includes("*") && mapping.source.trim().toLocaleLowerCase() === wanted.toLocaleLowerCase()
|
|
3276
|
+
);
|
|
3277
|
+
if (exact && nonBlank(exact.target)) return exact.target.trim();
|
|
3278
|
+
const wildcard = (_nullishCoalesce(mappings, () => ( []))).find(
|
|
3279
|
+
(mapping) => nonBlank(mapping.source) && mapping.source.includes("*") && wildcardMatches(mapping.source.trim(), wanted)
|
|
3280
|
+
);
|
|
3281
|
+
return wildcard && nonBlank(wildcard.target) ? wildcard.target.trim() : void 0;
|
|
3282
|
+
}
|
|
3283
|
+
function routeCanServe(binding, requestedModel, role) {
|
|
3284
|
+
if (binding.modelMode === "passthrough") return nonBlank(requestedModel);
|
|
3285
|
+
if (_optionalChain([binding, 'access', _139 => _139.modelMappings, 'optionalAccess', _140 => _140.length])) {
|
|
3286
|
+
return nonBlank(resolveGatewayModelMapping(binding.modelMappings, requestedModel));
|
|
3287
|
+
}
|
|
3288
|
+
if (_chunk4VZX5F4Tcjs.isKindMappedEndpoint.call(void 0, binding.endpoint)) {
|
|
3289
|
+
const map = _nullishCoalesce(binding.modelMap, () => ( {}));
|
|
3290
|
+
const kind = _chunk4VZX5F4Tcjs.detectModelKind.call(void 0, binding.endpoint, requestedModel);
|
|
3291
|
+
if (kind && nonBlank(map[kind])) return true;
|
|
3292
|
+
if (binding.endpoint === "messages") {
|
|
3293
|
+
return MESSAGE_FALLBACK_KINDS.some((candidate) => nonBlank(map[candidate]));
|
|
3294
|
+
}
|
|
3295
|
+
return nonBlank(map.codex);
|
|
3296
|
+
}
|
|
3297
|
+
if (binding.endpoint === "chat" && binding.dispatchMode === "prefix") {
|
|
3298
|
+
return _chunk4VZX5F4Tcjs.resolvePrefixTarget.call(void 0, binding.prefixTargets, requestedModel) !== null;
|
|
3299
|
+
}
|
|
3300
|
+
if (binding.endpoint === "chat") {
|
|
3301
|
+
if (!requestedModel) return false;
|
|
3302
|
+
const wanted = requestedModel.trim().toLowerCase();
|
|
3303
|
+
return (_nullishCoalesce(binding.models, () => ( []))).some((ref) => _optionalChain([modelIdOf, 'call', _141 => _141(ref), 'optionalAccess', _142 => _142.toLowerCase, 'call', _143 => _143()]) === wanted);
|
|
3304
|
+
}
|
|
3305
|
+
return role === "background" ? nonBlank(binding.backgroundModel) : nonBlank(binding.defaultModel);
|
|
3306
|
+
}
|
|
3307
|
+
function modelIdOf(ref) {
|
|
3308
|
+
if (!nonBlank(ref)) return void 0;
|
|
3309
|
+
const trimmed = ref.trim();
|
|
3310
|
+
const comma = trimmed.indexOf(",");
|
|
3311
|
+
const modelId = comma >= 0 ? trimmed.slice(comma + 1).trim() : trimmed;
|
|
3312
|
+
return modelId || void 0;
|
|
3313
|
+
}
|
|
3314
|
+
function targetProviderId(target) {
|
|
3315
|
+
return target.providerId.trim();
|
|
3316
|
+
}
|
|
3317
|
+
function targetRef(target, ref) {
|
|
3318
|
+
const modelId = _nullishCoalesce(modelIdOf(ref), () => ( ""));
|
|
3319
|
+
return modelId ? `${targetProviderId(target)},${modelId}` : "";
|
|
3320
|
+
}
|
|
3321
|
+
function targetRefs(target, refs) {
|
|
3322
|
+
return (_nullishCoalesce(refs, () => ( []))).map((ref) => targetRef(target, ref)).filter(nonBlank);
|
|
3323
|
+
}
|
|
3324
|
+
function targetPrefixRefs(target, refs) {
|
|
3325
|
+
if (!refs) return void 0;
|
|
3326
|
+
const mapped = {};
|
|
3327
|
+
for (const kind of ["claude", "gpt", "gemini"]) {
|
|
3328
|
+
const ref = targetRef(target, refs[kind]);
|
|
3329
|
+
if (ref) mapped[kind] = ref;
|
|
3330
|
+
}
|
|
3331
|
+
return mapped.claude || mapped.gpt || mapped.gemini ? mapped : void 0;
|
|
3332
|
+
}
|
|
3333
|
+
function applySingleModel(config, binding, targetModel) {
|
|
3334
|
+
const ref = targetRef(binding.target, targetModel);
|
|
3335
|
+
if (!ref) return;
|
|
3336
|
+
if (_chunk4VZX5F4Tcjs.isKindMappedEndpoint.call(void 0, binding.endpoint)) {
|
|
3337
|
+
config.modelMap = Object.fromEntries(
|
|
3338
|
+
_chunk4VZX5F4Tcjs.modelKindsForEndpoint.call(void 0, binding.endpoint).map((kind) => [kind, ref])
|
|
3339
|
+
);
|
|
3340
|
+
} else if (binding.endpoint === "chat") {
|
|
3341
|
+
config.models = [ref];
|
|
3342
|
+
config.dispatchMode = "list";
|
|
3343
|
+
} else {
|
|
3344
|
+
config.defaultModel = ref;
|
|
3345
|
+
config.backgroundModel = ref;
|
|
3346
|
+
}
|
|
3347
|
+
}
|
|
3348
|
+
function gatewayBindingToEndpointConfig(binding, requestedModel) {
|
|
3349
|
+
const target = binding.target;
|
|
3350
|
+
const config = {
|
|
3351
|
+
endpoint: binding.endpoint,
|
|
3352
|
+
useSubscription: target.kind !== "provider"
|
|
3353
|
+
};
|
|
3354
|
+
const usesGenericModelHandling = binding.modelMode === "passthrough" || Boolean(_optionalChain([binding, 'access', _144 => _144.modelMappings, 'optionalAccess', _145 => _145.length]));
|
|
3355
|
+
const dynamicModel = binding.modelMode === "passthrough" ? requestedModel : resolveGatewayModelMapping(binding.modelMappings, requestedModel);
|
|
3356
|
+
if (usesGenericModelHandling) {
|
|
3357
|
+
if (nonBlank(dynamicModel)) applySingleModel(config, binding, dynamicModel);
|
|
3358
|
+
} else if (_chunk4VZX5F4Tcjs.isKindMappedEndpoint.call(void 0, binding.endpoint)) {
|
|
3359
|
+
config.modelMap = Object.fromEntries(
|
|
3360
|
+
Object.entries(_nullishCoalesce(binding.modelMap, () => ( {}))).map(([kind, ref]) => [kind, targetRef(target, ref)])
|
|
3361
|
+
);
|
|
3362
|
+
} else if (binding.endpoint === "chat") {
|
|
3363
|
+
config.models = targetRefs(target, binding.models);
|
|
3364
|
+
if (binding.dispatchMode === "prefix") {
|
|
3365
|
+
config.dispatchMode = "prefix";
|
|
3366
|
+
config.prefixTargets = targetPrefixRefs(target, binding.prefixTargets);
|
|
3367
|
+
}
|
|
3368
|
+
} else {
|
|
3369
|
+
config.defaultModel = targetRef(target, binding.defaultModel);
|
|
3370
|
+
config.backgroundModel = targetRef(target, binding.backgroundModel);
|
|
3371
|
+
if (binding.backgroundModelIds) config.backgroundModelIds = [...binding.backgroundModelIds];
|
|
3372
|
+
}
|
|
3373
|
+
if (target.kind === "account") {
|
|
3374
|
+
config.boundAccountId = target.accountId;
|
|
3375
|
+
config.boundAccountFallbackPolicy = binding.fallback === "next" ? "pool" : "strict";
|
|
3376
|
+
} else if (target.kind === "account-group") {
|
|
3377
|
+
config.boundAccountGroup = target.group;
|
|
3378
|
+
config.boundAccountFallbackPolicy = binding.fallback === "next" ? "pool" : "strict";
|
|
3379
|
+
} else if (target.kind === "provider" && target.keyId) {
|
|
3380
|
+
config.boundKeyId = target.keyId;
|
|
3381
|
+
config.boundKeyFallbackPolicy = binding.fallback === "next" ? "pool" : "strict";
|
|
3382
|
+
}
|
|
3383
|
+
return config;
|
|
3384
|
+
}
|
|
3385
|
+
function candidateGatewayBindings(bindings, apiKeyId, endpoint) {
|
|
3386
|
+
const candidates = (_nullishCoalesce(bindings, () => ( []))).filter(
|
|
3387
|
+
(binding) => binding.enabled && binding.endpoint === endpoint && gatewayBindingAllowsKey(binding, apiKeyId)
|
|
3388
|
+
);
|
|
3389
|
+
const scopeOf = (binding) => _nullishCoalesce(binding.keyScope, () => ( (_optionalChain([binding, 'access', _146 => _146.apiKeyIds, 'optionalAccess', _147 => _147.length]) ? "selected" : "all")));
|
|
3390
|
+
const scoped = candidates.filter((binding) => scopeOf(binding) === "selected");
|
|
3391
|
+
const pool = scoped.length > 0 ? scoped : candidates.filter((binding) => scopeOf(binding) === "all");
|
|
3392
|
+
return pool.sort(
|
|
3393
|
+
(left, right) => (_nullishCoalesce(left.priority, () => ( 100))) - (_nullishCoalesce(right.priority, () => ( 100))) || left.id.localeCompare(right.id)
|
|
3394
|
+
);
|
|
3395
|
+
}
|
|
3396
|
+
function candidateBackgroundModelIds(bindings, apiKeyId, endpoint) {
|
|
3397
|
+
const ids = [
|
|
3398
|
+
...new Set(
|
|
3399
|
+
candidateGatewayBindings(bindings, apiKeyId, endpoint).flatMap(
|
|
3400
|
+
(binding) => _nullishCoalesce(binding.backgroundModelIds, () => ( []))
|
|
3401
|
+
)
|
|
3402
|
+
)
|
|
3403
|
+
];
|
|
3404
|
+
return ids.length > 0 ? ids : void 0;
|
|
3405
|
+
}
|
|
3406
|
+
function resolveGatewayBinding(input) {
|
|
3407
|
+
const candidates = candidateGatewayBindings(input.bindings, input.apiKeyId, input.endpoint);
|
|
3408
|
+
const binding = _nullishCoalesce(candidates.find(
|
|
3409
|
+
(candidate) => candidate.fallback === "fail" || routeCanServe(candidate, input.requestedModel, input.role)
|
|
3410
|
+
), () => ( candidates[0]));
|
|
3411
|
+
if (!binding) return { source: "none" };
|
|
3412
|
+
return {
|
|
3413
|
+
source: "binding",
|
|
3414
|
+
binding,
|
|
3415
|
+
config: gatewayBindingToEndpointConfig(binding, input.requestedModel)
|
|
3416
|
+
};
|
|
3417
|
+
}
|
|
3418
|
+
|
|
2512
3419
|
// src/outbound-api/outboundApiKeyAuth.ts
|
|
2513
3420
|
|
|
2514
3421
|
|
|
@@ -2591,7 +3498,30 @@ async function createNamedKey(db, name) {
|
|
|
2591
3498
|
id,
|
|
2592
3499
|
name,
|
|
2593
3500
|
keyHash: hashKey(secret),
|
|
2594
|
-
keyPrefix: prefix
|
|
3501
|
+
keyPrefix: prefix,
|
|
3502
|
+
plaintext: secret
|
|
3503
|
+
});
|
|
3504
|
+
return {
|
|
3505
|
+
id: row.id,
|
|
3506
|
+
name: row.name,
|
|
3507
|
+
keyPrefix: row.keyPrefix,
|
|
3508
|
+
createdAt: row.createdAt,
|
|
3509
|
+
plaintextOnce: secret
|
|
3510
|
+
};
|
|
3511
|
+
}
|
|
3512
|
+
async function createIntegrationKey(db, name, allowedEndpoints = ["responses", "messages"]) {
|
|
3513
|
+
const secret = generateSecret();
|
|
3514
|
+
const id = newKeyId();
|
|
3515
|
+
const prefix = keyPrefix(secret);
|
|
3516
|
+
const row = await db.outboundApiKeysCreate({
|
|
3517
|
+
id,
|
|
3518
|
+
name,
|
|
3519
|
+
keyHash: hashKey(secret),
|
|
3520
|
+
keyPrefix: prefix,
|
|
3521
|
+
kind: "integration",
|
|
3522
|
+
allowedEndpoints: [...new Set(allowedEndpoints)],
|
|
3523
|
+
loopbackOnly: true,
|
|
3524
|
+
plaintext: secret
|
|
2595
3525
|
});
|
|
2596
3526
|
return {
|
|
2597
3527
|
id: row.id,
|
|
@@ -2623,7 +3553,12 @@ function extractModelRestriction(row) {
|
|
|
2623
3553
|
};
|
|
2624
3554
|
}
|
|
2625
3555
|
function toVerifiedKey(row) {
|
|
2626
|
-
const key = {
|
|
3556
|
+
const key = {
|
|
3557
|
+
id: row.id,
|
|
3558
|
+
kind: row.kind,
|
|
3559
|
+
allowedEndpoints: row.allowedEndpoints,
|
|
3560
|
+
loopbackOnly: row.loopbackOnly
|
|
3561
|
+
};
|
|
2627
3562
|
if (row.maxConcurrency !== void 0 && row.maxConcurrency !== null) {
|
|
2628
3563
|
key.maxConcurrency = row.maxConcurrency;
|
|
2629
3564
|
}
|
|
@@ -2843,8 +3778,8 @@ var OutboundRateLimiter = (_class8 = class {
|
|
|
2843
3778
|
* recorded (no bucket growth).
|
|
2844
3779
|
*/
|
|
2845
3780
|
check(apiKeyId, now = Date.now(), override) {
|
|
2846
|
-
const maxRequests = _nullishCoalesce(_optionalChain([override, 'optionalAccess',
|
|
2847
|
-
const windowMs = _nullishCoalesce(_optionalChain([override, 'optionalAccess',
|
|
3781
|
+
const maxRequests = _nullishCoalesce(_optionalChain([override, 'optionalAccess', _148 => _148.maxRequests]), () => ( this.maxRequests));
|
|
3782
|
+
const windowMs = _nullishCoalesce(_optionalChain([override, 'optionalAccess', _149 => _149.windowMs]), () => ( this.windowMs));
|
|
2848
3783
|
if (maxRequests === 0) return { allowed: true, retryAfterSeconds: 0 };
|
|
2849
3784
|
const cutoff = now - windowMs;
|
|
2850
3785
|
const timestamps = (_nullishCoalesce(this.hits.get(apiKeyId), () => ( []))).filter((ts) => ts > cutoff);
|
|
@@ -2889,7 +3824,7 @@ function isUserMessageAnthropic(body) {
|
|
|
2889
3824
|
if (typeof content === "string") return true;
|
|
2890
3825
|
if (Array.isArray(content)) {
|
|
2891
3826
|
const hasToolResult = content.some(
|
|
2892
|
-
(block) => _optionalChain([asObject, 'call',
|
|
3827
|
+
(block) => _optionalChain([asObject, 'call', _150 => _150(block), 'optionalAccess', _151 => _151["type"]]) === "tool_result"
|
|
2893
3828
|
);
|
|
2894
3829
|
return !hasToolResult;
|
|
2895
3830
|
}
|
|
@@ -2918,7 +3853,7 @@ function isUserMessageGemini(body) {
|
|
|
2918
3853
|
if (!lastContent || lastContent["role"] !== "user") return false;
|
|
2919
3854
|
const parts = asArray(lastContent["parts"]);
|
|
2920
3855
|
const hasFunctionResponse = parts.some(
|
|
2921
|
-
(part) => _optionalChain([asObject, 'call',
|
|
3856
|
+
(part) => _optionalChain([asObject, 'call', _152 => _152(part), 'optionalAccess', _153 => _153["functionResponse"]]) !== void 0
|
|
2922
3857
|
);
|
|
2923
3858
|
return !hasFunctionResponse;
|
|
2924
3859
|
}
|
|
@@ -3092,14 +4027,14 @@ function newVoucherId() {
|
|
|
3092
4027
|
}
|
|
3093
4028
|
function computeVoucherGrant(voucher, currentKey, now) {
|
|
3094
4029
|
if (voucher.type === "credit") {
|
|
3095
|
-
const current = _nullishCoalesce(_optionalChain([currentKey, 'optionalAccess',
|
|
4030
|
+
const current = _nullishCoalesce(_optionalChain([currentKey, 'optionalAccess', _154 => _154.totalCostLimitUsd]), () => ( 0));
|
|
3096
4031
|
let granted2 = current + (_nullishCoalesce(voucher.creditUsd, () => ( 0)));
|
|
3097
4032
|
if (voucher.maxTotalCostLimitUsd != null) {
|
|
3098
4033
|
granted2 = Math.min(granted2, voucher.maxTotalCostLimitUsd);
|
|
3099
4034
|
}
|
|
3100
4035
|
return { totalCostLimitUsd: granted2 };
|
|
3101
4036
|
}
|
|
3102
|
-
const currentExpiry = _nullishCoalesce(_optionalChain([currentKey, 'optionalAccess',
|
|
4037
|
+
const currentExpiry = _nullishCoalesce(_optionalChain([currentKey, 'optionalAccess', _155 => _155.expiresAt]), () => ( now));
|
|
3103
4038
|
let granted = currentExpiry + (_nullishCoalesce(voucher.renewalDays, () => ( 0))) * DAY_MS2;
|
|
3104
4039
|
if (voucher.maxExpiryDays != null) {
|
|
3105
4040
|
granted = Math.min(granted, now + voucher.maxExpiryDays * DAY_MS2);
|
|
@@ -3130,7 +4065,7 @@ function toVoucherInfo(v) {
|
|
|
3130
4065
|
// src/outbound-api/voucherRedeem.ts
|
|
3131
4066
|
function isRedeemRequest(method, url) {
|
|
3132
4067
|
if (method !== "POST" || !url) return false;
|
|
3133
|
-
const path = _nullishCoalesce(_optionalChain([url, 'access',
|
|
4068
|
+
const path = _nullishCoalesce(_optionalChain([url, 'access', _156 => _156.split, 'call', _157 => _157("?"), 'access', _158 => _158[0], 'optionalAccess', _159 => _159.replace, 'call', _160 => _160(/\/+$/, "")]), () => ( ""));
|
|
3134
4069
|
return path.endsWith("/redeem");
|
|
3135
4070
|
}
|
|
3136
4071
|
function writeErr(res, status, message, headers = {}) {
|
|
@@ -3160,8 +4095,8 @@ function grantToResult(type, granted) {
|
|
|
3160
4095
|
function currentResult(type, keyRow) {
|
|
3161
4096
|
const result = { type };
|
|
3162
4097
|
if (type === "credit") {
|
|
3163
|
-
if (_optionalChain([keyRow, 'optionalAccess',
|
|
3164
|
-
} else if (_optionalChain([keyRow, 'optionalAccess',
|
|
4098
|
+
if (_optionalChain([keyRow, 'optionalAccess', _161 => _161.totalCostLimitUsd]) != null) result.totalCostLimitUsd = keyRow.totalCostLimitUsd;
|
|
4099
|
+
} else if (_optionalChain([keyRow, 'optionalAccess', _162 => _162.expiresAt]) != null) {
|
|
3165
4100
|
result.expiresAt = keyRow.expiresAt;
|
|
3166
4101
|
}
|
|
3167
4102
|
return result;
|
|
@@ -3199,7 +4134,7 @@ async function handleVoucherRedeem(req, res, deps, voucherEnabled, redeemLimiter
|
|
|
3199
4134
|
let code;
|
|
3200
4135
|
try {
|
|
3201
4136
|
code = raw ? JSON.parse(raw)["code"] : void 0;
|
|
3202
|
-
} catch (
|
|
4137
|
+
} catch (e24) {
|
|
3203
4138
|
writeErr(res, 400, "Invalid JSON in request body");
|
|
3204
4139
|
return;
|
|
3205
4140
|
}
|
|
@@ -3248,7 +4183,7 @@ async function handleVoucherRedeem(req, res, deps, voucherEnabled, redeemLimiter
|
|
|
3248
4183
|
const won = await voucherDb.voucherRedeemCas(voucher.id, verifiedKeyId, absolute, now);
|
|
3249
4184
|
if (!won) {
|
|
3250
4185
|
const after = await voucherDb.voucherGetByHash(codeHash);
|
|
3251
|
-
if (_optionalChain([after, 'optionalAccess',
|
|
4186
|
+
if (_optionalChain([after, 'optionalAccess', _163 => _163.status]) === "redeemed" && after.redeemedByKeyId === verifiedKeyId) {
|
|
3252
4187
|
return after.grantApplied === true ? { ok: true, result: currentResult(after.type, await deps.db.outboundApiKeysGetByHash(keyHash)) } : await applyFirstPass(after, recordedAbsolute(after));
|
|
3253
4188
|
}
|
|
3254
4189
|
return { ok: false, status: 409, message: "Code was already redeemed" };
|
|
@@ -3267,10 +4202,10 @@ function getFallbackRedeemLimiter() {
|
|
|
3267
4202
|
fallbackRedeemLimiter ??= new OutboundRateLimiter({ maxRequests: 10, windowMs: 6e4 });
|
|
3268
4203
|
return fallbackRedeemLimiter;
|
|
3269
4204
|
}
|
|
3270
|
-
function writeJsonError(res, status, message, headers = {}) {
|
|
4205
|
+
function writeJsonError(res, status, message, headers = {}, details = {}) {
|
|
3271
4206
|
if (res.headersSent) return;
|
|
3272
4207
|
res.writeHead(status, { "Content-Type": "application/json", ...headers });
|
|
3273
|
-
res.end(JSON.stringify({ error: { type: "outbound_api_error", message } }));
|
|
4208
|
+
res.end(JSON.stringify({ error: { type: "outbound_api_error", message, ...details } }));
|
|
3274
4209
|
}
|
|
3275
4210
|
function writeCostLimitError(res, scope, limitUsd, spentUsd) {
|
|
3276
4211
|
if (res.headersSent) return;
|
|
@@ -3309,14 +4244,19 @@ function extractPresentedKey(req) {
|
|
|
3309
4244
|
}
|
|
3310
4245
|
const xApiKey = req.headers["x-api-key"];
|
|
3311
4246
|
const xApi = Array.isArray(xApiKey) ? xApiKey[0] : xApiKey;
|
|
3312
|
-
if (_optionalChain([xApi, 'optionalAccess',
|
|
4247
|
+
if (_optionalChain([xApi, 'optionalAccess', _164 => _164.trim, 'call', _165 => _165()])) return xApi.trim();
|
|
3313
4248
|
const goog = req.headers["x-goog-api-key"];
|
|
3314
4249
|
const g = Array.isArray(goog) ? goog[0] : goog;
|
|
3315
|
-
return _optionalChain([g, 'optionalAccess',
|
|
4250
|
+
return _optionalChain([g, 'optionalAccess', _166 => _166.trim, 'call', _167 => _167()]) || void 0;
|
|
4251
|
+
}
|
|
4252
|
+
function isLoopbackPeer(address) {
|
|
4253
|
+
if (!address) return false;
|
|
4254
|
+
const normalized = address.toLowerCase().split("%")[0];
|
|
4255
|
+
return normalized === "::1" || normalized === "127.0.0.1" || normalized.startsWith("127.") || normalized.startsWith("::ffff:127.");
|
|
3316
4256
|
}
|
|
3317
4257
|
function selectEndpoint(method, url) {
|
|
3318
4258
|
if (method !== "POST" || !url) return null;
|
|
3319
|
-
const path = _nullishCoalesce(_optionalChain([url, 'access',
|
|
4259
|
+
const path = _nullishCoalesce(_optionalChain([url, 'access', _168 => _168.split, 'call', _169 => _169("?"), 'access', _170 => _170[0], 'optionalAccess', _171 => _171.replace, 'call', _172 => _172(/\/+$/, "")]), () => ( ""));
|
|
3320
4260
|
if (path.endsWith("/chat/completions")) return "chat";
|
|
3321
4261
|
if (path.endsWith("/responses")) return "responses";
|
|
3322
4262
|
if (path.includes("/v1/messages")) return "messages";
|
|
@@ -3334,12 +4274,36 @@ function extractGeminiModelFromUrl(url) {
|
|
|
3334
4274
|
}
|
|
3335
4275
|
function isModelsListRequest(url) {
|
|
3336
4276
|
if (!url) return false;
|
|
3337
|
-
const path = _nullishCoalesce(_optionalChain([url, 'access',
|
|
4277
|
+
const path = _nullishCoalesce(_optionalChain([url, 'access', _173 => _173.split, 'call', _174 => _174("?"), 'access', _175 => _175[0], 'optionalAccess', _176 => _176.replace, 'call', _177 => _177(/\/+$/, "")]), () => ( ""));
|
|
3338
4278
|
return path.endsWith("/models");
|
|
3339
4279
|
}
|
|
3340
|
-
function
|
|
3341
|
-
const
|
|
3342
|
-
const
|
|
4280
|
+
function writeModelsList(res, config, apiKeyId, allowedEndpoints) {
|
|
4281
|
+
const refs = [];
|
|
4282
|
+
const endpointConfigs = [];
|
|
4283
|
+
for (const endpoint of ["chat", "responses", "messages", "gemini"]) {
|
|
4284
|
+
if (allowedEndpoints && !allowedEndpoints.includes(endpoint)) continue;
|
|
4285
|
+
endpointConfigs.push(
|
|
4286
|
+
...candidateGatewayBindings(config.bindings, apiKeyId, endpoint).map(
|
|
4287
|
+
(binding) => gatewayBindingToEndpointConfig(binding)
|
|
4288
|
+
)
|
|
4289
|
+
);
|
|
4290
|
+
}
|
|
4291
|
+
for (const endpoint of endpointConfigs) {
|
|
4292
|
+
if (allowedEndpoints && !allowedEndpoints.includes(endpoint.endpoint)) continue;
|
|
4293
|
+
if (endpoint.endpoint === "chat") refs.push(..._nullishCoalesce(endpoint.models, () => ( [])));
|
|
4294
|
+
else if (endpoint.endpoint === "messages" || endpoint.endpoint === "responses") {
|
|
4295
|
+
refs.push(...Object.values(_nullishCoalesce(endpoint.modelMap, () => ( {}))));
|
|
4296
|
+
} else {
|
|
4297
|
+
if (endpoint.defaultModel) refs.push(endpoint.defaultModel);
|
|
4298
|
+
if (endpoint.backgroundModel) refs.push(endpoint.backgroundModel);
|
|
4299
|
+
}
|
|
4300
|
+
}
|
|
4301
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4302
|
+
const data = refs.map((ref) => _chunk4VZX5F4Tcjs.parseModelRef.call(void 0, ref)).filter((p) => p !== null).filter((p) => {
|
|
4303
|
+
if (seen.has(p.modelId)) return false;
|
|
4304
|
+
seen.add(p.modelId);
|
|
4305
|
+
return true;
|
|
4306
|
+
}).map((p) => ({ id: p.modelId, object: "model", owned_by: "omnicross" }));
|
|
3343
4307
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
3344
4308
|
res.end(JSON.stringify({ object: "list", data }));
|
|
3345
4309
|
}
|
|
@@ -3358,7 +4322,7 @@ function shimAuthHeader(req, routeToken) {
|
|
|
3358
4322
|
}
|
|
3359
4323
|
async function handleOutboundRequest(req, res, deps, config, rateLimiter, serialQueue, concurrencyGate, redeemLimiter, redeemMutex) {
|
|
3360
4324
|
const now = Date.now();
|
|
3361
|
-
const audit =
|
|
4325
|
+
const audit = _chunkXPIOJQS2cjs.beginAuditCapture.call(void 0, req, res, now);
|
|
3362
4326
|
const billing = _chunkAPYG5QD7cjs.beginBillingCapture.call(void 0, req, res, now);
|
|
3363
4327
|
const presented = extractPresentedKey(req);
|
|
3364
4328
|
const verification = await verifyKey(deps.db, presented, now);
|
|
@@ -3373,12 +4337,20 @@ async function handleOutboundRequest(req, res, deps, config, rateLimiter, serial
|
|
|
3373
4337
|
const verified = verification.key;
|
|
3374
4338
|
if (audit) audit.keyId = verified.id;
|
|
3375
4339
|
if (billing) billing.keyId = verified.id;
|
|
4340
|
+
if (verified.loopbackOnly && !isLoopbackPeer(_optionalChain([req, 'access', _178 => _178.socket, 'optionalAccess', _179 => _179.remoteAddress]))) {
|
|
4341
|
+
writeJsonError(res, 403, "This integration key is restricted to loopback clients");
|
|
4342
|
+
return;
|
|
4343
|
+
}
|
|
3376
4344
|
if (isRedeemRequest(req.method, req.url)) {
|
|
4345
|
+
if (verified.kind === "integration") {
|
|
4346
|
+
writeJsonError(res, 403, "Integration keys cannot redeem vouchers");
|
|
4347
|
+
return;
|
|
4348
|
+
}
|
|
3377
4349
|
await handleVoucherRedeem(
|
|
3378
4350
|
req,
|
|
3379
4351
|
res,
|
|
3380
4352
|
deps,
|
|
3381
|
-
_optionalChain([config, 'access',
|
|
4353
|
+
_optionalChain([config, 'access', _180 => _180.voucher, 'optionalAccess', _181 => _181.enabled]) === true,
|
|
3382
4354
|
_nullishCoalesce(redeemLimiter, () => ( getFallbackRedeemLimiter())),
|
|
3383
4355
|
verified.id,
|
|
3384
4356
|
_nullishCoalesce(presented, () => ( "")),
|
|
@@ -3395,7 +4367,11 @@ async function handleOutboundRequest(req, res, deps, config, rateLimiter, serial
|
|
|
3395
4367
|
return;
|
|
3396
4368
|
}
|
|
3397
4369
|
if (req.method === "GET" && isModelsListRequest(req.url)) {
|
|
3398
|
-
|
|
4370
|
+
if (verified.allowedEndpoints && verified.allowedEndpoints.length === 0) {
|
|
4371
|
+
writeJsonError(res, 403, "API key is not allowed to access this endpoint");
|
|
4372
|
+
return;
|
|
4373
|
+
}
|
|
4374
|
+
writeModelsList(res, config, verified.id, verified.allowedEndpoints);
|
|
3399
4375
|
return;
|
|
3400
4376
|
}
|
|
3401
4377
|
const endpoint = selectEndpoint(req.method, req.url);
|
|
@@ -3403,9 +4379,12 @@ async function handleOutboundRequest(req, res, deps, config, rateLimiter, serial
|
|
|
3403
4379
|
writeJsonError(res, 404, `Unsupported: ${req.method} ${req.url}`);
|
|
3404
4380
|
return;
|
|
3405
4381
|
}
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
|
|
4382
|
+
if (verified.allowedEndpoints && !verified.allowedEndpoints.includes(endpoint)) {
|
|
4383
|
+
writeJsonError(res, 403, "API key is not allowed to access this endpoint");
|
|
4384
|
+
return;
|
|
4385
|
+
}
|
|
4386
|
+
if (candidateGatewayBindings(config.bindings, verified.id, endpoint).length === 0) {
|
|
4387
|
+
writeJsonError(res, 503, `endpoint '${endpoint}' has no downstream route for this key`);
|
|
3409
4388
|
return;
|
|
3410
4389
|
}
|
|
3411
4390
|
if (verified.costLimits && deps.keySpendTracker) {
|
|
@@ -3464,12 +4443,12 @@ async function handleOutboundRequest(req, res, deps, config, rateLimiter, serial
|
|
|
3464
4443
|
res.once("close", release2);
|
|
3465
4444
|
}
|
|
3466
4445
|
try {
|
|
3467
|
-
const ingressFormat =
|
|
4446
|
+
const ingressFormat = _chunk4VZX5F4Tcjs.endpointToIngressFormat.call(void 0, endpoint);
|
|
3468
4447
|
const rawBody = await readBody3(req);
|
|
3469
4448
|
let parsedBody = {};
|
|
3470
4449
|
try {
|
|
3471
4450
|
parsedBody = rawBody ? JSON.parse(rawBody) : {};
|
|
3472
|
-
} catch (
|
|
4451
|
+
} catch (e25) {
|
|
3473
4452
|
writeJsonError(res, 400, "Invalid JSON in request body");
|
|
3474
4453
|
return;
|
|
3475
4454
|
}
|
|
@@ -3478,23 +4457,40 @@ async function handleOutboundRequest(req, res, deps, config, rateLimiter, serial
|
|
|
3478
4457
|
const urlModel = extractGeminiModelFromUrl(req.url);
|
|
3479
4458
|
if (urlModel) parsedBody["model"] = urlModel;
|
|
3480
4459
|
}
|
|
3481
|
-
const
|
|
3482
|
-
const
|
|
3483
|
-
|
|
4460
|
+
const requestedModel = _chunk4VZX5F4Tcjs.extractRequestedModel.call(void 0, ingressFormat, parsedBody);
|
|
4461
|
+
const role = _chunk4VZX5F4Tcjs.isKindMappedEndpoint.call(void 0, endpoint) || endpoint === "chat" ? void 0 : _chunk4VZX5F4Tcjs.detectRequestRole.call(void 0, ingressFormat, parsedBody, {
|
|
4462
|
+
// Role detection precedes the route pick (the pick consumes the
|
|
4463
|
+
// role), so the hint is the union across the candidate routes.
|
|
4464
|
+
backgroundModelIds: candidateBackgroundModelIds(config.bindings, verified.id, endpoint)
|
|
4465
|
+
});
|
|
4466
|
+
const bindingResolution = resolveGatewayBinding({
|
|
4467
|
+
bindings: config.bindings,
|
|
4468
|
+
apiKeyId: verified.id,
|
|
4469
|
+
endpoint,
|
|
4470
|
+
requestedModel,
|
|
4471
|
+
role
|
|
4472
|
+
});
|
|
4473
|
+
if (bindingResolution.source === "none") {
|
|
4474
|
+
writeJsonError(res, 503, `endpoint '${endpoint}' has no downstream route for this key`);
|
|
4475
|
+
return;
|
|
4476
|
+
}
|
|
4477
|
+
const effectiveEndpointConfig = bindingResolution.config;
|
|
4478
|
+
const bindingAffinitySuffix = `:${bindingResolution.binding.id}`;
|
|
4479
|
+
const sessionId = deps.proxyDeps.apiKeyPool ? `outbound:${verified.id}${bindingAffinitySuffix}` : null;
|
|
4480
|
+
const resolved = _chunk4VZX5F4Tcjs.isKindMappedEndpoint.call(void 0, endpoint) || endpoint === "chat" ? await _chunk4VZX5F4Tcjs.resolveRoute.call(void 0, {
|
|
4481
|
+
config: effectiveEndpointConfig,
|
|
3484
4482
|
ingressFormat,
|
|
3485
4483
|
llmConfig: deps.llmConfig,
|
|
3486
4484
|
sessionId,
|
|
3487
4485
|
// Capture the ORIGINAL requested id BEFORE any downstream swap; for
|
|
3488
4486
|
// kind-mapped endpoints it selects the kind AND is stamped onto
|
|
3489
4487
|
// `route.requestedModel`; for chat it is matched against the list.
|
|
3490
|
-
requestedModel
|
|
4488
|
+
requestedModel,
|
|
3491
4489
|
// Attribution: stamp the verified named-key id onto the route.
|
|
3492
4490
|
apiKeyId: verified.id
|
|
3493
|
-
}) : await
|
|
3494
|
-
config:
|
|
3495
|
-
role
|
|
3496
|
-
backgroundModelIds: endpointConfig.backgroundModelIds
|
|
3497
|
-
}),
|
|
4491
|
+
}) : await _chunk4VZX5F4Tcjs.resolveRoute.call(void 0, {
|
|
4492
|
+
config: effectiveEndpointConfig,
|
|
4493
|
+
role,
|
|
3498
4494
|
ingressFormat,
|
|
3499
4495
|
llmConfig: deps.llmConfig,
|
|
3500
4496
|
sessionId,
|
|
@@ -3523,7 +4519,7 @@ async function handleOutboundRequest(req, res, deps, config, rateLimiter, serial
|
|
|
3523
4519
|
}
|
|
3524
4520
|
let releaseSerial = null;
|
|
3525
4521
|
const providerKey = resolved.route.providerId;
|
|
3526
|
-
if (_optionalChain([config, 'access',
|
|
4522
|
+
if (_optionalChain([config, 'access', _182 => _182.userMessageQueue, 'optionalAccess', _183 => _183.enabled]) && providerKey && isUserMessageRequest(endpoint, parsedBody)) {
|
|
3527
4523
|
const umq = config.userMessageQueue;
|
|
3528
4524
|
try {
|
|
3529
4525
|
const serialSlot = await serialQueue.acquire(providerKey, {
|
|
@@ -3555,12 +4551,29 @@ async function handleOutboundRequest(req, res, deps, config, rateLimiter, serial
|
|
|
3555
4551
|
const replay = makeReplayRequest(req, rawBody);
|
|
3556
4552
|
await routeRequest(replay, res, routeMap, deps.proxyDeps);
|
|
3557
4553
|
} catch (err) {
|
|
4554
|
+
if (_chunk25GXJCEZcjs.isBoundAccountSelectionError.call(void 0, err)) {
|
|
4555
|
+
const headers = {};
|
|
4556
|
+
if (err.status === 429 && err.resumeAt) {
|
|
4557
|
+
const resumeMs = Date.parse(err.resumeAt);
|
|
4558
|
+
if (Number.isFinite(resumeMs)) {
|
|
4559
|
+
headers["Retry-After"] = String(Math.max(1, Math.ceil((resumeMs - Date.now()) / 1e3)));
|
|
4560
|
+
}
|
|
4561
|
+
}
|
|
4562
|
+
writeJsonError(
|
|
4563
|
+
res,
|
|
4564
|
+
err.status,
|
|
4565
|
+
_chunk25GXJCEZcjs.boundAccountSelectionMessage.call(void 0, err.reason),
|
|
4566
|
+
headers,
|
|
4567
|
+
{ code: err.code, reason: err.reason }
|
|
4568
|
+
);
|
|
4569
|
+
return;
|
|
4570
|
+
}
|
|
3558
4571
|
const message = _chunkSVNDB62Dcjs.serializeError.call(void 0, err);
|
|
3559
4572
|
if (deps.logger) deps.logger.error("[OutboundApi] dispatch error:", message);
|
|
3560
4573
|
else console.error("[OutboundApi] dispatch error:", message);
|
|
3561
4574
|
_chunkUIBD2YY5cjs.emitWebhookEvent.call(void 0, { kind: "server.error", at: Date.now(), message });
|
|
3562
4575
|
if (audit) audit.error = message;
|
|
3563
|
-
writeJsonError(res, 502, message);
|
|
4576
|
+
writeJsonError(res, _chunk6QQG7YG3cjs.isAccountAllowanceExhaustedError.call(void 0, err) ? 429 : 502, message);
|
|
3564
4577
|
} finally {
|
|
3565
4578
|
routeMap.removeRoute(token);
|
|
3566
4579
|
if (releaseSerial) releaseSerial();
|
|
@@ -3584,18 +4597,8 @@ function makeReplayRequest(req, rawBody) {
|
|
|
3584
4597
|
var DEFAULT_OUTBOUND_PORT = 8765;
|
|
3585
4598
|
var LOOPBACK_ADDR = "127.0.0.1";
|
|
3586
4599
|
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
4600
|
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);
|
|
4601
|
+
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
4602
|
this.deps = deps;
|
|
3600
4603
|
this.onPortChange = onPortChange;
|
|
3601
4604
|
}
|
|
@@ -3605,25 +4608,26 @@ var OutboundApiServer = (_class11 = class {
|
|
|
3605
4608
|
__init13() {this.boundPort = 0}
|
|
3606
4609
|
__init14() {this.boundAddr = LOOPBACK_ADDR}
|
|
3607
4610
|
__init15() {this.endpoints = []}
|
|
4611
|
+
__init16() {this.bindings = []}
|
|
3608
4612
|
|
|
3609
4613
|
|
|
3610
4614
|
|
|
3611
|
-
|
|
4615
|
+
__init17() {this.rateLimiter = new OutboundRateLimiter()}
|
|
3612
4616
|
/**
|
|
3613
4617
|
* Redeem-attempt limiter (voucher-redemption #9, design D6) — a SEPARATE bucket
|
|
3614
4618
|
* from the traffic `rateLimiter`, keyed by the authenticating key id, so
|
|
3615
4619
|
* brute-forcing `CC_` codes is throttled (a handful/min) without touching the
|
|
3616
4620
|
* per-key request rate. Conservative fixed defaults (10 / 60s).
|
|
3617
4621
|
*/
|
|
3618
|
-
|
|
4622
|
+
__init18() {this.redeemLimiter = new OutboundRateLimiter({ maxRequests: 10, windowMs: 6e4 })}
|
|
3619
4623
|
/**
|
|
3620
4624
|
* Per-key redeem mutex (voucher-redemption #9, MJ1 fix). One instance for the
|
|
3621
4625
|
* server's lifetime so concurrent redeem REQUESTS for the same key serialize
|
|
3622
4626
|
* (relative grant increments accumulate instead of clobbering a snapshot).
|
|
3623
4627
|
*/
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
4628
|
+
__init19() {this.redeemMutex = new KeyedMutex()}
|
|
4629
|
+
__init20() {this.serialQueue = new UserMessageSerialQueue()}
|
|
4630
|
+
__init21() {this.concurrencyGate = new OutboundConcurrencyGate()}
|
|
3627
4631
|
/**
|
|
3628
4632
|
* Apply a config. Restarts the listener ONLY when the bind address or port
|
|
3629
4633
|
* changes (or when toggling enabled); per-endpoint routing config is updated
|
|
@@ -3631,6 +4635,7 @@ var OutboundApiServer = (_class11 = class {
|
|
|
3631
4635
|
*/
|
|
3632
4636
|
async applyConfig(input) {
|
|
3633
4637
|
this.endpoints = input.endpoints;
|
|
4638
|
+
this.bindings = _nullishCoalesce(input.bindings, () => ( []));
|
|
3634
4639
|
this.userMessageQueue = input.userMessageQueue;
|
|
3635
4640
|
this.concurrencyQueue = input.concurrencyQueue;
|
|
3636
4641
|
this.voucherConfig = input.voucher;
|
|
@@ -3640,16 +4645,6 @@ var OutboundApiServer = (_class11 = class {
|
|
|
3640
4645
|
await this.stop();
|
|
3641
4646
|
return;
|
|
3642
4647
|
}
|
|
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
4648
|
const running = this.server !== null;
|
|
3654
4649
|
const bindChanged = running && (this.boundAddr !== wantAddr || this.boundPort !== wantPort);
|
|
3655
4650
|
if (running && !bindChanged) {
|
|
@@ -3664,7 +4659,7 @@ var OutboundApiServer = (_class11 = class {
|
|
|
3664
4659
|
const actualPort = await this.listen(bindAddr, port);
|
|
3665
4660
|
this.boundAddr = bindAddr;
|
|
3666
4661
|
this.boundPort = actualPort;
|
|
3667
|
-
if (actualPort !== port) _optionalChain([this, 'access',
|
|
4662
|
+
if (actualPort !== port) _optionalChain([this, 'access', _184 => _184.onPortChange, 'optionalCall', _185 => _185(actualPort)]);
|
|
3668
4663
|
this.logInfo(`[OutboundApiServer] Listening on ${bindAddr}:${actualPort}`);
|
|
3669
4664
|
return actualPort;
|
|
3670
4665
|
}
|
|
@@ -3706,6 +4701,7 @@ var OutboundApiServer = (_class11 = class {
|
|
|
3706
4701
|
this.deps,
|
|
3707
4702
|
{
|
|
3708
4703
|
endpoints: this.endpoints,
|
|
4704
|
+
bindings: this.bindings,
|
|
3709
4705
|
userMessageQueue: this.userMessageQueue,
|
|
3710
4706
|
concurrencyQueue: this.concurrencyQueue,
|
|
3711
4707
|
voucher: this.voucherConfig
|
|
@@ -3732,7 +4728,7 @@ var OutboundApiServer = (_class11 = class {
|
|
|
3732
4728
|
const provider = this.deps.healthReportProvider;
|
|
3733
4729
|
if (!provider) return false;
|
|
3734
4730
|
if (req.method !== "GET" && req.method !== "HEAD") return false;
|
|
3735
|
-
const path = _optionalChain([(_nullishCoalesce(req.url, () => ( "/"))), 'access',
|
|
4731
|
+
const path = _optionalChain([(_nullishCoalesce(req.url, () => ( "/"))), 'access', _186 => _186.split, 'call', _187 => _187("?"), 'access', _188 => _188[0], 'optionalAccess', _189 => _189.replace, 'call', _190 => _190(/\/+$/, "")]) || "/";
|
|
3736
4732
|
if (path !== "/health" && path !== "/healthz") return false;
|
|
3737
4733
|
const report = provider();
|
|
3738
4734
|
res.writeHead(_healthloggingtypes.healthHttpStatus.call(void 0, report.status), { "Content-Type": "application/json" });
|
|
@@ -3844,12 +4840,12 @@ function startOfLocalWeek(ts) {
|
|
|
3844
4840
|
return day.getTime();
|
|
3845
4841
|
}
|
|
3846
4842
|
var KeySpendTracker = (_class12 = class {
|
|
3847
|
-
constructor(seeder) {;_class12.prototype.
|
|
4843
|
+
constructor(seeder) {;_class12.prototype.__init22.call(this);
|
|
3848
4844
|
this.seeder = seeder;
|
|
3849
4845
|
}
|
|
3850
4846
|
|
|
3851
4847
|
/** apiKeyId → live accumulated spend (seeded lazily). */
|
|
3852
|
-
|
|
4848
|
+
__init22() {this.spend = /* @__PURE__ */ new Map()}
|
|
3853
4849
|
/**
|
|
3854
4850
|
* Read the key's accumulated spend, seeding from the durable store on a cache
|
|
3855
4851
|
* miss and rolling the daily/weekly windows on a hit.
|
|
@@ -3937,7 +4933,7 @@ async function callOpenAICompletion(provider, apiKey, options, logger) {
|
|
|
3937
4933
|
model: options.model,
|
|
3938
4934
|
messages: options.messages.map((m) => convertMessageToOpenAI(m)),
|
|
3939
4935
|
// Only set max_tokens if explicitly provided, otherwise let API use its default
|
|
3940
|
-
...options.maxTokens ? { max_tokens: options.maxTokens } : {},
|
|
4936
|
+
...options.maxTokens !== void 0 ? { max_tokens: options.maxTokens } : {},
|
|
3941
4937
|
temperature: options.temperature,
|
|
3942
4938
|
stream: false
|
|
3943
4939
|
// For now, non-streaming only
|
|
@@ -3988,7 +4984,7 @@ async function callAnthropicCompletion(provider, apiKey, options, logger) {
|
|
|
3988
4984
|
const nonSystemMessages = options.messages.filter((m) => m.role !== "system");
|
|
3989
4985
|
const anthropicRequest2 = {
|
|
3990
4986
|
model: options.model,
|
|
3991
|
-
max_tokens: options.maxTokens
|
|
4987
|
+
max_tokens: _nullishCoalesce(options.maxTokens, () => ( 16384)),
|
|
3992
4988
|
temperature: options.temperature,
|
|
3993
4989
|
...systemMessages.length > 0 ? { system: systemMessages.map((m) => m.content).join("\n\n") } : {},
|
|
3994
4990
|
messages: nonSystemMessages.map((m) => convertMessageToAnthropic(m)),
|
|
@@ -4010,14 +5006,14 @@ async function callAnthropicCompletion(provider, apiKey, options, logger) {
|
|
|
4010
5006
|
};
|
|
4011
5007
|
}
|
|
4012
5008
|
const anthropicResponse2 = await response2.json();
|
|
4013
|
-
const openaiResponse2 =
|
|
5009
|
+
const openaiResponse2 = _chunkGDIXXKF2cjs.convertAnthropicToOpenAI.call(void 0, anthropicResponse2);
|
|
4014
5010
|
const choice2 = openaiResponse2.choices[0];
|
|
4015
5011
|
return {
|
|
4016
5012
|
success: true,
|
|
4017
5013
|
message: {
|
|
4018
5014
|
id: `assistant-${Date.now()}`,
|
|
4019
5015
|
role: "assistant",
|
|
4020
|
-
content: _optionalChain([choice2, 'access',
|
|
5016
|
+
content: _optionalChain([choice2, 'access', _191 => _191.message, 'optionalAccess', _192 => _192.content]) || "",
|
|
4021
5017
|
timestamp: Date.now()
|
|
4022
5018
|
},
|
|
4023
5019
|
usage: openaiResponse2.usage ? {
|
|
@@ -4034,14 +5030,14 @@ async function callAnthropicCompletion(provider, apiKey, options, logger) {
|
|
|
4034
5030
|
content: m.content
|
|
4035
5031
|
})),
|
|
4036
5032
|
// Anthropic requires max_tokens; use 16384 default if not explicitly set
|
|
4037
|
-
max_tokens: options.maxTokens
|
|
5033
|
+
max_tokens: _nullishCoalesce(options.maxTokens, () => ( 16384)),
|
|
4038
5034
|
temperature: options.temperature,
|
|
4039
5035
|
stream: false
|
|
4040
5036
|
};
|
|
4041
5037
|
const config = {
|
|
4042
5038
|
defaultModel: options.model
|
|
4043
5039
|
};
|
|
4044
|
-
const anthropicRequest =
|
|
5040
|
+
const anthropicRequest = _chunkGDIXXKF2cjs.convertOpenAIToAnthropic.call(void 0, openaiRequest, config);
|
|
4045
5041
|
const apiUrl = _chunkA2YMUCBTcjs.buildProviderApiUrl.call(void 0, provider, { model: options.model, stream: false });
|
|
4046
5042
|
const headers = _chunkQ27JY5RGcjs.getProviderHeaders.call(void 0, provider, apiKey);
|
|
4047
5043
|
logger.info("Calling Anthropic completion API", { url: apiUrl, model: options.model });
|
|
@@ -4058,7 +5054,7 @@ async function callAnthropicCompletion(provider, apiKey, options, logger) {
|
|
|
4058
5054
|
};
|
|
4059
5055
|
}
|
|
4060
5056
|
const anthropicResponse = await response.json();
|
|
4061
|
-
const openaiResponse =
|
|
5057
|
+
const openaiResponse = _chunkGDIXXKF2cjs.convertAnthropicToOpenAI.call(void 0, anthropicResponse);
|
|
4062
5058
|
const choice = openaiResponse.choices[0];
|
|
4063
5059
|
return {
|
|
4064
5060
|
success: true,
|
|
@@ -4089,7 +5085,7 @@ async function callGeminiCompletion(provider, apiKey, options, logger) {
|
|
|
4089
5085
|
const request = {
|
|
4090
5086
|
contents,
|
|
4091
5087
|
generationConfig: {
|
|
4092
|
-
...options.maxTokens ? { maxOutputTokens: options.maxTokens } : {},
|
|
5088
|
+
...options.maxTokens !== void 0 ? { maxOutputTokens: options.maxTokens } : {},
|
|
4093
5089
|
...options.temperature !== void 0 ? { temperature: options.temperature } : {}
|
|
4094
5090
|
}
|
|
4095
5091
|
};
|
|
@@ -4122,7 +5118,7 @@ async function callGeminiCompletion(provider, apiKey, options, logger) {
|
|
|
4122
5118
|
const candidate = candidates[0];
|
|
4123
5119
|
const content = candidate.content;
|
|
4124
5120
|
let textContent = "";
|
|
4125
|
-
if (_optionalChain([content, 'optionalAccess',
|
|
5121
|
+
if (_optionalChain([content, 'optionalAccess', _193 => _193.parts])) {
|
|
4126
5122
|
for (const part of content.parts) {
|
|
4127
5123
|
if (part.text) {
|
|
4128
5124
|
textContent += part.text;
|
|
@@ -4158,7 +5154,7 @@ async function callOpenAIResponseCompletion(provider, apiKey, options, logger) {
|
|
|
4158
5154
|
model: options.model,
|
|
4159
5155
|
input,
|
|
4160
5156
|
stream: false,
|
|
4161
|
-
...options.maxTokens ? { max_output_tokens: options.maxTokens } : {},
|
|
5157
|
+
...options.maxTokens !== void 0 ? { max_output_tokens: options.maxTokens } : {},
|
|
4162
5158
|
...options.temperature !== void 0 ? { temperature: options.temperature } : {}
|
|
4163
5159
|
};
|
|
4164
5160
|
if (options.thinkLevel && options.thinkLevel !== "none") {
|
|
@@ -4223,7 +5219,7 @@ async function streamOpenAICompletion(provider, apiKey, options, messageId, call
|
|
|
4223
5219
|
model: options.model,
|
|
4224
5220
|
messages: options.messages.map((m) => convertMessageToOpenAI(m)),
|
|
4225
5221
|
// Only set max_tokens if explicitly provided, otherwise let API use its default
|
|
4226
|
-
...options.maxTokens ? { max_tokens: options.maxTokens } : {},
|
|
5222
|
+
...options.maxTokens !== void 0 ? { max_tokens: options.maxTokens } : {},
|
|
4227
5223
|
temperature: options.temperature,
|
|
4228
5224
|
stream: true
|
|
4229
5225
|
};
|
|
@@ -4255,7 +5251,7 @@ async function streamOpenAICompletion(provider, apiKey, options, messageId, call
|
|
|
4255
5251
|
});
|
|
4256
5252
|
if (!response.ok) {
|
|
4257
5253
|
const errorText = await response.text();
|
|
4258
|
-
_optionalChain([callbacks, 'access',
|
|
5254
|
+
_optionalChain([callbacks, 'access', _194 => _194.onError, 'optionalCall', _195 => _195(`API error (${response.status}): ${errorText}`)]);
|
|
4259
5255
|
return;
|
|
4260
5256
|
}
|
|
4261
5257
|
const result = await _chunkHQP3K7PUcjs.streamSSEResponse.call(void 0, response, "openai", {
|
|
@@ -4265,7 +5261,7 @@ async function streamOpenAICompletion(provider, apiKey, options, messageId, call
|
|
|
4265
5261
|
onVideo: callbacks.onVideo,
|
|
4266
5262
|
onError: callbacks.onError
|
|
4267
5263
|
});
|
|
4268
|
-
_optionalChain([callbacks, 'access',
|
|
5264
|
+
_optionalChain([callbacks, 'access', _196 => _196.onDone, 'optionalCall', _197 => _197(
|
|
4269
5265
|
{
|
|
4270
5266
|
id: messageId,
|
|
4271
5267
|
role: "assistant",
|
|
@@ -4282,7 +5278,7 @@ async function streamOpenAICompletion(provider, apiKey, options, messageId, call
|
|
|
4282
5278
|
async function streamAnthropicCompletion(provider, apiKey, options, messageId, callbacks, logger) {
|
|
4283
5279
|
const hasImages = options.messages.some((m) => m.images && m.images.length > 0);
|
|
4284
5280
|
const MAX_TOKENS_FOR_THINKING = 16384;
|
|
4285
|
-
let effectiveMaxTokens = options.maxTokens
|
|
5281
|
+
let effectiveMaxTokens = _nullishCoalesce(options.maxTokens, () => ( 16384));
|
|
4286
5282
|
const thinkingMaxTokens = options.thinkLevel && options.thinkLevel !== "none" ? Math.min(effectiveMaxTokens, MAX_TOKENS_FOR_THINKING) : effectiveMaxTokens;
|
|
4287
5283
|
const thinkingConfig = options.thinkLevel && options.thinkLevel !== "none" ? _thinkingconfig.buildAnthropicThinking.call(void 0, options.model, options.thinkLevel, thinkingMaxTokens) : void 0;
|
|
4288
5284
|
if (thinkingConfig) {
|
|
@@ -4323,7 +5319,7 @@ async function streamAnthropicCompletion(provider, apiKey, options, messageId, c
|
|
|
4323
5319
|
temperature: thinkingConfig ? void 0 : options.temperature,
|
|
4324
5320
|
stream: true
|
|
4325
5321
|
};
|
|
4326
|
-
anthropicRequest =
|
|
5322
|
+
anthropicRequest = _chunkGDIXXKF2cjs.convertOpenAIToAnthropic.call(void 0, openaiRequest, config);
|
|
4327
5323
|
if (thinkingConfig) {
|
|
4328
5324
|
anthropicRequest.thinking = thinkingConfig;
|
|
4329
5325
|
delete anthropicRequest.temperature;
|
|
@@ -4337,7 +5333,7 @@ async function streamAnthropicCompletion(provider, apiKey, options, messageId, c
|
|
|
4337
5333
|
logger.info("Streaming Anthropic completion request", {
|
|
4338
5334
|
url: apiUrl,
|
|
4339
5335
|
model: anthropicRequest.model,
|
|
4340
|
-
messagesCount: _optionalChain([anthropicRequest, 'access',
|
|
5336
|
+
messagesCount: _optionalChain([anthropicRequest, 'access', _198 => _198.messages, 'optionalAccess', _199 => _199.length]),
|
|
4341
5337
|
max_tokens: anthropicRequest.max_tokens,
|
|
4342
5338
|
temperature: anthropicRequest.temperature,
|
|
4343
5339
|
stream: anthropicRequest.stream,
|
|
@@ -4354,7 +5350,7 @@ async function streamAnthropicCompletion(provider, apiKey, options, messageId, c
|
|
|
4354
5350
|
if (!response.ok) {
|
|
4355
5351
|
const errorText = await response.text();
|
|
4356
5352
|
logger.error("Anthropic API error", void 0, { status: response.status, errorText });
|
|
4357
|
-
_optionalChain([callbacks, 'access',
|
|
5353
|
+
_optionalChain([callbacks, 'access', _200 => _200.onError, 'optionalCall', _201 => _201(`API error (${response.status}): ${errorText}`)]);
|
|
4358
5354
|
return;
|
|
4359
5355
|
}
|
|
4360
5356
|
const result = await _chunkHQP3K7PUcjs.streamSSEResponse.call(void 0, response, "anthropic", {
|
|
@@ -4365,10 +5361,10 @@ async function streamAnthropicCompletion(provider, apiKey, options, messageId, c
|
|
|
4365
5361
|
});
|
|
4366
5362
|
logger.info("Anthropic stream complete", {
|
|
4367
5363
|
contentLength: result.content.length,
|
|
4368
|
-
reasoningLength: _optionalChain([result, 'access',
|
|
5364
|
+
reasoningLength: _optionalChain([result, 'access', _202 => _202.reasoning, 'optionalAccess', _203 => _203.length]) || 0,
|
|
4369
5365
|
blocksCount: result.blocks.length
|
|
4370
5366
|
});
|
|
4371
|
-
_optionalChain([callbacks, 'access',
|
|
5367
|
+
_optionalChain([callbacks, 'access', _204 => _204.onDone, 'optionalCall', _205 => _205(
|
|
4372
5368
|
{
|
|
4373
5369
|
id: messageId,
|
|
4374
5370
|
role: "assistant",
|
|
@@ -4394,7 +5390,7 @@ async function streamGeminiCompletion(provider, apiKey, options, messageId, call
|
|
|
4394
5390
|
const request = {
|
|
4395
5391
|
contents,
|
|
4396
5392
|
generationConfig: {
|
|
4397
|
-
...options.maxTokens ? { maxOutputTokens: options.maxTokens } : {},
|
|
5393
|
+
...options.maxTokens !== void 0 ? { maxOutputTokens: options.maxTokens } : {},
|
|
4398
5394
|
...options.temperature !== void 0 ? { temperature: options.temperature } : {}
|
|
4399
5395
|
}
|
|
4400
5396
|
};
|
|
@@ -4424,7 +5420,7 @@ async function streamGeminiCompletion(provider, apiKey, options, messageId, call
|
|
|
4424
5420
|
if (!response.ok) {
|
|
4425
5421
|
const errorText = await response.text();
|
|
4426
5422
|
logger.error("Gemini API error", void 0, { status: response.status, errorText });
|
|
4427
|
-
_optionalChain([callbacks, 'access',
|
|
5423
|
+
_optionalChain([callbacks, 'access', _206 => _206.onError, 'optionalCall', _207 => _207(`API error (${response.status}): ${errorText}`)]);
|
|
4428
5424
|
return;
|
|
4429
5425
|
}
|
|
4430
5426
|
const result = await _chunkHQP3K7PUcjs.streamSSEResponse.call(void 0, response, "gemini", {
|
|
@@ -4433,7 +5429,7 @@ async function streamGeminiCompletion(provider, apiKey, options, messageId, call
|
|
|
4433
5429
|
onError: callbacks.onError
|
|
4434
5430
|
});
|
|
4435
5431
|
logger.info("Gemini stream complete", { contentLength: result.content.length });
|
|
4436
|
-
_optionalChain([callbacks, 'access',
|
|
5432
|
+
_optionalChain([callbacks, 'access', _208 => _208.onDone, 'optionalCall', _209 => _209(
|
|
4437
5433
|
{
|
|
4438
5434
|
id: messageId,
|
|
4439
5435
|
role: "assistant",
|
|
@@ -4458,7 +5454,7 @@ async function streamOpenAIResponseCompletion(provider, apiKey, options, message
|
|
|
4458
5454
|
model: options.model,
|
|
4459
5455
|
input,
|
|
4460
5456
|
stream: true,
|
|
4461
|
-
...options.maxTokens ? { max_output_tokens: options.maxTokens } : {},
|
|
5457
|
+
...options.maxTokens !== void 0 ? { max_output_tokens: options.maxTokens } : {},
|
|
4462
5458
|
...options.temperature !== void 0 ? { temperature: options.temperature } : {}
|
|
4463
5459
|
};
|
|
4464
5460
|
if (options.thinkLevel && options.thinkLevel !== "none") {
|
|
@@ -4485,7 +5481,7 @@ async function streamOpenAIResponseCompletion(provider, apiKey, options, message
|
|
|
4485
5481
|
});
|
|
4486
5482
|
if (!response.ok) {
|
|
4487
5483
|
const errorText = await response.text();
|
|
4488
|
-
_optionalChain([callbacks, 'access',
|
|
5484
|
+
_optionalChain([callbacks, 'access', _210 => _210.onError, 'optionalCall', _211 => _211(`API error (${response.status}): ${errorText}`)]);
|
|
4489
5485
|
return;
|
|
4490
5486
|
}
|
|
4491
5487
|
const result = await _chunkHQP3K7PUcjs.streamSSEResponse.call(void 0, response, "openai-response", {
|
|
@@ -4494,7 +5490,7 @@ async function streamOpenAIResponseCompletion(provider, apiKey, options, message
|
|
|
4494
5490
|
onError: callbacks.onError
|
|
4495
5491
|
});
|
|
4496
5492
|
logger.info("OpenAI Response API stream complete", { contentLength: result.content.length });
|
|
4497
|
-
_optionalChain([callbacks, 'access',
|
|
5493
|
+
_optionalChain([callbacks, 'access', _212 => _212.onDone, 'optionalCall', _213 => _213(
|
|
4498
5494
|
{
|
|
4499
5495
|
id: messageId,
|
|
4500
5496
|
role: "assistant",
|
|
@@ -4515,59 +5511,20 @@ async function streamOpenAIResponseCompletion(provider, apiKey, options, message
|
|
|
4515
5511
|
|
|
4516
5512
|
|
|
4517
5513
|
|
|
4518
|
-
async function resolveEffectiveMaxTokens(llmConfig,
|
|
5514
|
+
async function resolveEffectiveMaxTokens(llmConfig, _getProvider, logger, _providerId, _modelId, sessionMaxTokens) {
|
|
4519
5515
|
if (sessionMaxTokens !== void 0 && sessionMaxTokens > 0) {
|
|
4520
5516
|
logger.debug("Using session maxTokens", { sessionMaxTokens });
|
|
4521
5517
|
return sessionMaxTokens;
|
|
4522
5518
|
}
|
|
4523
5519
|
try {
|
|
4524
5520
|
const globalParams = await llmConfig.getGlobalModelParameters();
|
|
4525
|
-
if (_optionalChain([globalParams, 'optionalAccess',
|
|
5521
|
+
if (_optionalChain([globalParams, 'optionalAccess', _214 => _214.maxTokens, 'optionalAccess', _215 => _215.enabled]) && globalParams.maxTokens.value > 0) {
|
|
4526
5522
|
logger.debug("Using global maxTokens", { maxTokens: globalParams.maxTokens.value });
|
|
4527
5523
|
return globalParams.maxTokens.value;
|
|
4528
5524
|
}
|
|
4529
5525
|
} catch (err) {
|
|
4530
5526
|
logger.warn("Failed to get global params", err instanceof Error ? err : void 0);
|
|
4531
5527
|
}
|
|
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
5528
|
logger.debug("No maxTokens configured, returning undefined");
|
|
4572
5529
|
return void 0;
|
|
4573
5530
|
}
|
|
@@ -4589,7 +5546,7 @@ async function resolveThinkingBudget(getProvider, logger, providerId, modelId, m
|
|
|
4589
5546
|
}
|
|
4590
5547
|
const thinkingBudget = _thinkingconfig.calculateThinkingBudget.call(void 0, modelId, thinkLevel, maxTokens);
|
|
4591
5548
|
const provider = await getProvider(providerId);
|
|
4592
|
-
const providerName = _optionalChain([provider, 'optionalAccess',
|
|
5549
|
+
const providerName = _optionalChain([provider, 'optionalAccess', _216 => _216.name, 'optionalAccess', _217 => _217.toLowerCase, 'call', _218 => _218()]) || "";
|
|
4593
5550
|
const apiFormat = provider ? _chunkA2YMUCBTcjs.resolveApiFormat.call(void 0, provider) : "openai";
|
|
4594
5551
|
if (apiFormat === "anthropic" || providerName === "anthropic" || providerName.includes("claude")) {
|
|
4595
5552
|
const thinkingConfig = _thinkingconfig.buildAnthropicThinking.call(void 0, modelId, thinkLevel, maxTokens);
|
|
@@ -4626,7 +5583,7 @@ function logToolFormat(tools, logger) {
|
|
|
4626
5583
|
tools: openaiTools.map((t) => t.function.name),
|
|
4627
5584
|
firstTool: {
|
|
4628
5585
|
name: firstTool.function.name,
|
|
4629
|
-
description: _optionalChain([firstTool, 'access',
|
|
5586
|
+
description: _optionalChain([firstTool, 'access', _219 => _219.function, 'access', _220 => _220.description, 'optionalAccess', _221 => _221.slice, 'call', _222 => _222(0, 100)]),
|
|
4630
5587
|
parameters: firstTool.function.parameters
|
|
4631
5588
|
}
|
|
4632
5589
|
});
|
|
@@ -4637,7 +5594,7 @@ function logToolFormat(tools, logger) {
|
|
|
4637
5594
|
tools: anthropicTools.map((t) => t.name),
|
|
4638
5595
|
firstTool: {
|
|
4639
5596
|
name: firstTool.name,
|
|
4640
|
-
description: _optionalChain([firstTool, 'access',
|
|
5597
|
+
description: _optionalChain([firstTool, 'access', _223 => _223.description, 'optionalAccess', _224 => _224.slice, 'call', _225 => _225(0, 100)]),
|
|
4641
5598
|
input_schema: firstTool.input_schema
|
|
4642
5599
|
}
|
|
4643
5600
|
});
|
|
@@ -4648,9 +5605,9 @@ function logToolFormat(tools, logger) {
|
|
|
4648
5605
|
count: allDeclarations.length,
|
|
4649
5606
|
tools: allDeclarations.map((t) => t.name),
|
|
4650
5607
|
firstTool: {
|
|
4651
|
-
name: _optionalChain([allDeclarations, 'access',
|
|
4652
|
-
description: _optionalChain([allDeclarations, 'access',
|
|
4653
|
-
parameters: _optionalChain([allDeclarations, 'access',
|
|
5608
|
+
name: _optionalChain([allDeclarations, 'access', _226 => _226[0], 'optionalAccess', _227 => _227.name]),
|
|
5609
|
+
description: _optionalChain([allDeclarations, 'access', _228 => _228[0], 'optionalAccess', _229 => _229.description, 'optionalAccess', _230 => _230.slice, 'call', _231 => _231(0, 100)]),
|
|
5610
|
+
parameters: _optionalChain([allDeclarations, 'access', _232 => _232[0], 'optionalAccess', _233 => _233.parameters])
|
|
4654
5611
|
}
|
|
4655
5612
|
});
|
|
4656
5613
|
}
|
|
@@ -4670,7 +5627,8 @@ function buildToolRequest(apiFormat, conversationMessages, actualModel, options,
|
|
|
4670
5627
|
}
|
|
4671
5628
|
requestBody = {
|
|
4672
5629
|
contents,
|
|
4673
|
-
tools: options.tools
|
|
5630
|
+
tools: options.tools,
|
|
5631
|
+
...options.maxTokens !== void 0 ? { generationConfig: { maxOutputTokens: options.maxTokens } } : {}
|
|
4674
5632
|
};
|
|
4675
5633
|
url = _chunkA2YMUCBTcjs.buildProviderApiUrl.call(void 0, provider, { model: actualModel, stream: true });
|
|
4676
5634
|
} else if (apiFormat === "anthropic") {
|
|
@@ -4680,7 +5638,10 @@ function buildToolRequest(apiFormat, conversationMessages, actualModel, options,
|
|
|
4680
5638
|
role: m.role,
|
|
4681
5639
|
content: m.content
|
|
4682
5640
|
})),
|
|
4683
|
-
|
|
5641
|
+
// Native Anthropic Messages requires this field. Resolve an absent
|
|
5642
|
+
// caller cap to the model's real ceiling rather than a small constant —
|
|
5643
|
+
// see `resolveAnthropicMaxTokens`.
|
|
5644
|
+
max_tokens: _chunkOXHNSZ53cjs.resolveAnthropicMaxTokens.call(void 0, actualModel, options.maxTokens),
|
|
4684
5645
|
temperature: _nullishCoalesce(options.temperature, () => ( 0.7)),
|
|
4685
5646
|
stream: true,
|
|
4686
5647
|
tools: options.tools
|
|
@@ -4697,7 +5658,7 @@ function buildToolRequest(apiFormat, conversationMessages, actualModel, options,
|
|
|
4697
5658
|
role: m.role,
|
|
4698
5659
|
content: m.content
|
|
4699
5660
|
})),
|
|
4700
|
-
max_tokens: options.maxTokens
|
|
5661
|
+
...options.maxTokens !== void 0 ? { max_tokens: options.maxTokens } : {},
|
|
4701
5662
|
temperature: _nullishCoalesce(options.temperature, () => ( 0.7)),
|
|
4702
5663
|
stream: true,
|
|
4703
5664
|
tools: options.tools
|
|
@@ -4709,7 +5670,7 @@ function buildToolRequest(apiFormat, conversationMessages, actualModel, options,
|
|
|
4709
5670
|
function extractDeltaContent(rawJson, apiFormat) {
|
|
4710
5671
|
const json = rawJson;
|
|
4711
5672
|
if (apiFormat === "google") {
|
|
4712
|
-
const parts = _optionalChain([json, 'access',
|
|
5673
|
+
const parts = _optionalChain([json, 'access', _234 => _234.candidates, 'optionalAccess', _235 => _235[0], 'optionalAccess', _236 => _236.content, 'optionalAccess', _237 => _237.parts]) || [];
|
|
4713
5674
|
let text = "";
|
|
4714
5675
|
for (const part of parts) {
|
|
4715
5676
|
if (part.thought === true) continue;
|
|
@@ -4717,15 +5678,15 @@ function extractDeltaContent(rawJson, apiFormat) {
|
|
|
4717
5678
|
}
|
|
4718
5679
|
return text;
|
|
4719
5680
|
} else if (apiFormat === "anthropic") {
|
|
4720
|
-
return _optionalChain([json, 'access',
|
|
5681
|
+
return _optionalChain([json, 'access', _238 => _238.delta, 'optionalAccess', _239 => _239.text]) || "";
|
|
4721
5682
|
} else {
|
|
4722
|
-
return _optionalChain([json, 'access',
|
|
5683
|
+
return _optionalChain([json, 'access', _240 => _240.choices, 'optionalAccess', _241 => _241[0], 'optionalAccess', _242 => _242.delta, 'optionalAccess', _243 => _243.content]) || "";
|
|
4723
5684
|
}
|
|
4724
5685
|
}
|
|
4725
5686
|
function extractDeltaReasoning(rawJson, apiFormat) {
|
|
4726
5687
|
const json = rawJson;
|
|
4727
5688
|
if (apiFormat === "google") {
|
|
4728
|
-
const parts = _optionalChain([json, 'access',
|
|
5689
|
+
const parts = _optionalChain([json, 'access', _244 => _244.candidates, 'optionalAccess', _245 => _245[0], 'optionalAccess', _246 => _246.content, 'optionalAccess', _247 => _247.parts]) || [];
|
|
4729
5690
|
let reasoning = "";
|
|
4730
5691
|
for (const part of parts) {
|
|
4731
5692
|
if (part.thought === true && part.text) reasoning += part.text;
|
|
@@ -4734,14 +5695,14 @@ function extractDeltaReasoning(rawJson, apiFormat) {
|
|
|
4734
5695
|
} else if (apiFormat === "anthropic") {
|
|
4735
5696
|
return "";
|
|
4736
5697
|
} else {
|
|
4737
|
-
const delta = _optionalChain([json, 'access',
|
|
4738
|
-
return (_optionalChain([delta, 'optionalAccess',
|
|
5698
|
+
const delta = _optionalChain([json, 'access', _248 => _248.choices, 'optionalAccess', _249 => _249[0], 'optionalAccess', _250 => _250.delta]);
|
|
5699
|
+
return (_optionalChain([delta, 'optionalAccess', _251 => _251.thinking, 'optionalAccess', _252 => _252.content]) || "") + (_optionalChain([delta, 'optionalAccess', _253 => _253.reasoning_content]) || "");
|
|
4739
5700
|
}
|
|
4740
5701
|
}
|
|
4741
5702
|
function extractToolCalls(rawJson, apiFormat, toolCalls, callbacks, logger, pendingOpenAIToolCalls) {
|
|
4742
5703
|
const json = rawJson;
|
|
4743
5704
|
if (apiFormat === "google") {
|
|
4744
|
-
const parts = _optionalChain([json, 'access',
|
|
5705
|
+
const parts = _optionalChain([json, 'access', _254 => _254.candidates, 'optionalAccess', _255 => _255[0], 'optionalAccess', _256 => _256.content, 'optionalAccess', _257 => _257.parts]) || [];
|
|
4745
5706
|
for (const part of parts) {
|
|
4746
5707
|
if (part.functionCall) {
|
|
4747
5708
|
logger.info("Function call detected", { functionCall: part.functionCall });
|
|
@@ -4751,13 +5712,13 @@ function extractToolCalls(rawJson, apiFormat, toolCalls, callbacks, logger, pend
|
|
|
4751
5712
|
args: part.functionCall.args || {}
|
|
4752
5713
|
};
|
|
4753
5714
|
toolCalls.push(toolCall);
|
|
4754
|
-
_optionalChain([callbacks, 'access',
|
|
5715
|
+
_optionalChain([callbacks, 'access', _258 => _258.onToolCall, 'optionalCall', _259 => _259(toolCall)]);
|
|
4755
5716
|
logger.info("Tool called", { toolName: toolCall.name });
|
|
4756
5717
|
}
|
|
4757
5718
|
}
|
|
4758
5719
|
} else if (apiFormat !== "anthropic") {
|
|
4759
|
-
const delta = _optionalChain([json, 'access',
|
|
4760
|
-
if (_optionalChain([delta, 'optionalAccess',
|
|
5720
|
+
const delta = _optionalChain([json, 'access', _260 => _260.choices, 'optionalAccess', _261 => _261[0], 'optionalAccess', _262 => _262.delta]);
|
|
5721
|
+
if (_optionalChain([delta, 'optionalAccess', _263 => _263.tool_calls]) && pendingOpenAIToolCalls) {
|
|
4761
5722
|
for (const tc of delta.tool_calls) {
|
|
4762
5723
|
const index = _nullishCoalesce(tc.index, () => ( 0));
|
|
4763
5724
|
let pending = pendingOpenAIToolCalls.get(index);
|
|
@@ -4766,8 +5727,8 @@ function extractToolCalls(rawJson, apiFormat, toolCalls, callbacks, logger, pend
|
|
|
4766
5727
|
pendingOpenAIToolCalls.set(index, pending);
|
|
4767
5728
|
}
|
|
4768
5729
|
if (tc.id) pending.id = tc.id;
|
|
4769
|
-
if (_optionalChain([tc, 'access',
|
|
4770
|
-
if (_optionalChain([tc, 'access',
|
|
5730
|
+
if (_optionalChain([tc, 'access', _264 => _264.function, 'optionalAccess', _265 => _265.name])) pending.name += tc.function.name;
|
|
5731
|
+
if (_optionalChain([tc, 'access', _266 => _266.function, 'optionalAccess', _267 => _267.arguments])) pending.arguments += tc.function.arguments;
|
|
4771
5732
|
}
|
|
4772
5733
|
}
|
|
4773
5734
|
}
|
|
@@ -4782,7 +5743,7 @@ function finalizeOpenAIToolCalls(pendingOpenAIToolCalls, toolCalls, callbacks, l
|
|
|
4782
5743
|
args: JSON.parse(pending.arguments || "{}")
|
|
4783
5744
|
};
|
|
4784
5745
|
toolCalls.push(toolCall);
|
|
4785
|
-
_optionalChain([callbacks, 'access',
|
|
5746
|
+
_optionalChain([callbacks, 'access', _268 => _268.onToolCall, 'optionalCall', _269 => _269(toolCall)]);
|
|
4786
5747
|
logger.info("Tool called (OpenAI)", { toolName: toolCall.name, args: toolCall.args });
|
|
4787
5748
|
} catch (e) {
|
|
4788
5749
|
logger.error("Failed to parse OpenAI tool call arguments", e instanceof Error ? e : void 0, {
|
|
@@ -4796,38 +5757,38 @@ function finalizeOpenAIToolCalls(pendingOpenAIToolCalls, toolCalls, callbacks, l
|
|
|
4796
5757
|
function parseStreamChunk(rawJson, apiFormat, callbacks, logger) {
|
|
4797
5758
|
const json = rawJson;
|
|
4798
5759
|
if (apiFormat === "google") {
|
|
4799
|
-
const candidate = _optionalChain([json, 'access',
|
|
5760
|
+
const candidate = _optionalChain([json, 'access', _270 => _270.candidates, 'optionalAccess', _271 => _271[0]]);
|
|
4800
5761
|
if (!candidate) {
|
|
4801
5762
|
logger.warn("No candidate found in Gemini response");
|
|
4802
5763
|
return;
|
|
4803
5764
|
}
|
|
4804
|
-
const parts = _optionalChain([candidate, 'access',
|
|
5765
|
+
const parts = _optionalChain([candidate, 'access', _272 => _272.content, 'optionalAccess', _273 => _273.parts]) || [];
|
|
4805
5766
|
for (const part of parts) {
|
|
4806
5767
|
if (part.thought === true && part.text) {
|
|
4807
|
-
_optionalChain([callbacks, 'access',
|
|
5768
|
+
_optionalChain([callbacks, 'access', _274 => _274.onReasoning, 'optionalCall', _275 => _275(part.text)]);
|
|
4808
5769
|
continue;
|
|
4809
5770
|
} else if (part.thoughtSignature && !part.thought) {
|
|
4810
5771
|
logger.debug("Gemini returned thoughtSignature without thought content");
|
|
4811
5772
|
}
|
|
4812
5773
|
if (part.text) {
|
|
4813
|
-
_optionalChain([callbacks, 'access',
|
|
5774
|
+
_optionalChain([callbacks, 'access', _276 => _276.onDelta, 'optionalCall', _277 => _277(part.text)]);
|
|
4814
5775
|
}
|
|
4815
5776
|
}
|
|
4816
5777
|
} else if (apiFormat === "anthropic") {
|
|
4817
5778
|
const delta = json.delta;
|
|
4818
|
-
if (_optionalChain([delta, 'optionalAccess',
|
|
4819
|
-
_optionalChain([callbacks, 'access',
|
|
5779
|
+
if (_optionalChain([delta, 'optionalAccess', _278 => _278.text])) {
|
|
5780
|
+
_optionalChain([callbacks, 'access', _279 => _279.onDelta, 'optionalCall', _280 => _280(delta.text)]);
|
|
4820
5781
|
}
|
|
4821
5782
|
} else {
|
|
4822
|
-
const delta = _optionalChain([json, 'access',
|
|
4823
|
-
if (_optionalChain([delta, 'optionalAccess',
|
|
4824
|
-
_optionalChain([callbacks, 'access',
|
|
5783
|
+
const delta = _optionalChain([json, 'access', _281 => _281.choices, 'optionalAccess', _282 => _282[0], 'optionalAccess', _283 => _283.delta]);
|
|
5784
|
+
if (_optionalChain([delta, 'optionalAccess', _284 => _284.content])) {
|
|
5785
|
+
_optionalChain([callbacks, 'access', _285 => _285.onDelta, 'optionalCall', _286 => _286(delta.content)]);
|
|
4825
5786
|
}
|
|
4826
|
-
if (_optionalChain([delta, 'optionalAccess',
|
|
4827
|
-
_optionalChain([callbacks, 'access',
|
|
5787
|
+
if (_optionalChain([delta, 'optionalAccess', _287 => _287.thinking, 'optionalAccess', _288 => _288.content])) {
|
|
5788
|
+
_optionalChain([callbacks, 'access', _289 => _289.onReasoning, 'optionalCall', _290 => _290(delta.thinking.content)]);
|
|
4828
5789
|
}
|
|
4829
|
-
if (_optionalChain([delta, 'optionalAccess',
|
|
4830
|
-
_optionalChain([callbacks, 'access',
|
|
5790
|
+
if (_optionalChain([delta, 'optionalAccess', _291 => _291.reasoning_content])) {
|
|
5791
|
+
_optionalChain([callbacks, 'access', _292 => _292.onReasoning, 'optionalCall', _293 => _293(delta.reasoning_content)]);
|
|
4831
5792
|
}
|
|
4832
5793
|
}
|
|
4833
5794
|
}
|
|
@@ -4840,7 +5801,7 @@ function buildIterationBlocks(iteration, content, reasoning, blocks, callbacks)
|
|
|
4840
5801
|
content: reasoning
|
|
4841
5802
|
};
|
|
4842
5803
|
blocks.push(thinkingBlock);
|
|
4843
|
-
_optionalChain([callbacks, 'access',
|
|
5804
|
+
_optionalChain([callbacks, 'access', _294 => _294.onBlock, 'optionalCall', _295 => _295(thinkingBlock)]);
|
|
4844
5805
|
}
|
|
4845
5806
|
if (content && content.trim()) {
|
|
4846
5807
|
const textBlock = {
|
|
@@ -4849,7 +5810,7 @@ function buildIterationBlocks(iteration, content, reasoning, blocks, callbacks)
|
|
|
4849
5810
|
content
|
|
4850
5811
|
};
|
|
4851
5812
|
blocks.push(textBlock);
|
|
4852
|
-
_optionalChain([callbacks, 'access',
|
|
5813
|
+
_optionalChain([callbacks, 'access', _296 => _296.onBlock, 'optionalCall', _297 => _297(textBlock)]);
|
|
4853
5814
|
}
|
|
4854
5815
|
}
|
|
4855
5816
|
async function executeToolCalls(toolCalls, mcpTools, mcpService, blocks, callbacks, logger, builtinExecutor) {
|
|
@@ -4864,7 +5825,7 @@ async function executeToolCalls(toolCalls, mcpTools, mcpService, blocks, callbac
|
|
|
4864
5825
|
status: "running"
|
|
4865
5826
|
};
|
|
4866
5827
|
blocks.push(toolUseBlock);
|
|
4867
|
-
_optionalChain([callbacks, 'access',
|
|
5828
|
+
_optionalChain([callbacks, 'access', _298 => _298.onBlock, 'optionalCall', _299 => _299(toolUseBlock)]);
|
|
4868
5829
|
try {
|
|
4869
5830
|
logger.info("Executing tool", { toolName: toolCall.name });
|
|
4870
5831
|
const mcpTool = mcpTools.find((t) => t.id === toolCall.name);
|
|
@@ -4887,8 +5848,8 @@ async function executeToolCalls(toolCalls, mcpTools, mcpService, blocks, callbac
|
|
|
4887
5848
|
result = { isError: true, content: [{ type: "text", text: "MCP service not available" }] };
|
|
4888
5849
|
}
|
|
4889
5850
|
logger.info("Tool result received", { result });
|
|
4890
|
-
_optionalChain([callbacks, 'access',
|
|
4891
|
-
const resultText = _optionalChain([result, 'access',
|
|
5851
|
+
_optionalChain([callbacks, 'access', _300 => _300.onToolResult, 'optionalCall', _301 => _301(toolCall.id, result)]);
|
|
5852
|
+
const resultText = _optionalChain([result, 'access', _302 => _302.content, 'optionalAccess', _303 => _303[0], 'optionalAccess', _304 => _304.text]) || JSON.stringify(result);
|
|
4892
5853
|
const toolResultBlock = {
|
|
4893
5854
|
id: `${toolCall.id}_result`,
|
|
4894
5855
|
type: "tool_result",
|
|
@@ -4898,11 +5859,11 @@ async function executeToolCalls(toolCalls, mcpTools, mcpService, blocks, callbac
|
|
|
4898
5859
|
isError: result.isError
|
|
4899
5860
|
};
|
|
4900
5861
|
blocks.push(toolResultBlock);
|
|
4901
|
-
_optionalChain([callbacks, 'access',
|
|
5862
|
+
_optionalChain([callbacks, 'access', _305 => _305.onBlock, 'optionalCall', _306 => _306(toolResultBlock)]);
|
|
4902
5863
|
const toolUseBlockRef = blocks.find((b) => b.id === `${toolCall.id}_use`);
|
|
4903
5864
|
if (toolUseBlockRef && toolUseBlockRef.type === "tool_use") {
|
|
4904
5865
|
toolUseBlockRef.status = result.isError ? "error" : "completed";
|
|
4905
|
-
_optionalChain([callbacks, 'access',
|
|
5866
|
+
_optionalChain([callbacks, 'access', _307 => _307.onBlock, 'optionalCall', _308 => _308({ ...toolUseBlockRef })]);
|
|
4906
5867
|
}
|
|
4907
5868
|
toolResults.push({ toolCall, result });
|
|
4908
5869
|
} catch (error) {
|
|
@@ -4912,7 +5873,7 @@ async function executeToolCalls(toolCalls, mcpTools, mcpService, blocks, callbac
|
|
|
4912
5873
|
isError: true,
|
|
4913
5874
|
content: [{ type: "text", text: `Error: ${errorMessage}` }]
|
|
4914
5875
|
};
|
|
4915
|
-
_optionalChain([callbacks, 'access',
|
|
5876
|
+
_optionalChain([callbacks, 'access', _309 => _309.onToolResult, 'optionalCall', _310 => _310(toolCall.id, errorResult)]);
|
|
4916
5877
|
const errorToolResultBlock = {
|
|
4917
5878
|
id: `${toolCall.id}_result`,
|
|
4918
5879
|
type: "tool_result",
|
|
@@ -4922,11 +5883,11 @@ async function executeToolCalls(toolCalls, mcpTools, mcpService, blocks, callbac
|
|
|
4922
5883
|
isError: true
|
|
4923
5884
|
};
|
|
4924
5885
|
blocks.push(errorToolResultBlock);
|
|
4925
|
-
_optionalChain([callbacks, 'access',
|
|
5886
|
+
_optionalChain([callbacks, 'access', _311 => _311.onBlock, 'optionalCall', _312 => _312(errorToolResultBlock)]);
|
|
4926
5887
|
const errorToolUseBlockRef = blocks.find((b) => b.id === `${toolCall.id}_use`);
|
|
4927
5888
|
if (errorToolUseBlockRef && errorToolUseBlockRef.type === "tool_use") {
|
|
4928
5889
|
errorToolUseBlockRef.status = "error";
|
|
4929
|
-
_optionalChain([callbacks, 'access',
|
|
5890
|
+
_optionalChain([callbacks, 'access', _313 => _313.onBlock, 'optionalCall', _314 => _314({ ...errorToolUseBlockRef })]);
|
|
4930
5891
|
}
|
|
4931
5892
|
toolResults.push({ toolCall, result: errorResult });
|
|
4932
5893
|
}
|
|
@@ -4936,7 +5897,7 @@ async function executeToolCalls(toolCalls, mcpTools, mcpService, blocks, callbac
|
|
|
4936
5897
|
function mapToolArguments(args, mcpTool, logger) {
|
|
4937
5898
|
const mappedArgs = { ...args };
|
|
4938
5899
|
const toolSchema = mcpTool.inputSchema;
|
|
4939
|
-
if (_optionalChain([toolSchema, 'optionalAccess',
|
|
5900
|
+
if (_optionalChain([toolSchema, 'optionalAccess', _315 => _315.properties])) {
|
|
4940
5901
|
const expectedParams = Object.keys(toolSchema.properties);
|
|
4941
5902
|
const paramMappings = {
|
|
4942
5903
|
"search_query": ["query", "q", "searchQuery", "search"],
|
|
@@ -4970,25 +5931,25 @@ async function streamWithTools(options, callbacks, mcpService, llmConfig, getPro
|
|
|
4970
5931
|
options.providerId,
|
|
4971
5932
|
options.model
|
|
4972
5933
|
);
|
|
4973
|
-
const actualProviderId = _optionalChain([routedInfo, 'optionalAccess',
|
|
4974
|
-
const actualModel = _optionalChain([routedInfo, 'optionalAccess',
|
|
5934
|
+
const actualProviderId = _optionalChain([routedInfo, 'optionalAccess', _316 => _316.actualProviderId]) || options.providerId;
|
|
5935
|
+
const actualModel = _optionalChain([routedInfo, 'optionalAccess', _317 => _317.actualModelId]) || options.model;
|
|
4975
5936
|
const provider = await getProvider(actualProviderId);
|
|
4976
5937
|
if (!provider) {
|
|
4977
|
-
_optionalChain([callbacks, 'access',
|
|
5938
|
+
_optionalChain([callbacks, 'access', _318 => _318.onError, 'optionalCall', _319 => _319(`Provider not found: ${actualProviderId}`)]);
|
|
4978
5939
|
return;
|
|
4979
5940
|
}
|
|
4980
5941
|
if (!provider.enabled) {
|
|
4981
|
-
_optionalChain([callbacks, 'access',
|
|
5942
|
+
_optionalChain([callbacks, 'access', _320 => _320.onError, 'optionalCall', _321 => _321(`Provider is disabled: ${provider.name}`)]);
|
|
4982
5943
|
return;
|
|
4983
5944
|
}
|
|
4984
5945
|
const { apiKey: effectiveKey } = _chunkA2YMUCBTcjs.resolveProviderEndpoint.call(void 0, provider);
|
|
4985
5946
|
const apiKey = resolveApiKey2(effectiveKey);
|
|
4986
5947
|
if (!apiKey) {
|
|
4987
|
-
_optionalChain([callbacks, 'access',
|
|
5948
|
+
_optionalChain([callbacks, 'access', _322 => _322.onError, 'optionalCall', _323 => _323("API key not configured")]);
|
|
4988
5949
|
return;
|
|
4989
5950
|
}
|
|
4990
5951
|
const messageId = `msg_${Date.now()}_${Math.random().toString(36).slice(2)}`;
|
|
4991
|
-
_optionalChain([callbacks, 'access',
|
|
5952
|
+
_optionalChain([callbacks, 'access', _324 => _324.onStart, 'optionalCall', _325 => _325(messageId)]);
|
|
4992
5953
|
const globalParams = await llmConfig.getGlobalModelParameters();
|
|
4993
5954
|
const MAX_ITERATIONS = _nullishCoalesce(globalParams.toolMaxTurns, () => ( 100));
|
|
4994
5955
|
let iteration = 0;
|
|
@@ -5035,12 +5996,12 @@ async function streamWithTools(options, callbacks, mcpService, llmConfig, getPro
|
|
|
5035
5996
|
});
|
|
5036
5997
|
if (!response.ok) {
|
|
5037
5998
|
const errorText = await response.text();
|
|
5038
|
-
_optionalChain([callbacks, 'access',
|
|
5999
|
+
_optionalChain([callbacks, 'access', _326 => _326.onError, 'optionalCall', _327 => _327(`API error (${response.status}): ${errorText}`)]);
|
|
5039
6000
|
return;
|
|
5040
6001
|
}
|
|
5041
|
-
const reader = _optionalChain([response, 'access',
|
|
6002
|
+
const reader = _optionalChain([response, 'access', _328 => _328.body, 'optionalAccess', _329 => _329.getReader, 'call', _330 => _330()]);
|
|
5042
6003
|
if (!reader) {
|
|
5043
|
-
_optionalChain([callbacks, 'access',
|
|
6004
|
+
_optionalChain([callbacks, 'access', _331 => _331.onError, 'optionalCall', _332 => _332("No response body")]);
|
|
5044
6005
|
return;
|
|
5045
6006
|
}
|
|
5046
6007
|
const decoder = new TextDecoder();
|
|
@@ -5073,7 +6034,7 @@ async function streamWithTools(options, callbacks, mcpService, llmConfig, getPro
|
|
|
5073
6034
|
logger.debug("Parsed JSON", { json });
|
|
5074
6035
|
if (json.error) {
|
|
5075
6036
|
logger.error("API Error", void 0, { error: json.error });
|
|
5076
|
-
_optionalChain([callbacks, 'access',
|
|
6037
|
+
_optionalChain([callbacks, 'access', _333 => _333.onError, 'optionalCall', _334 => _334(`API Error: ${json.error.message || JSON.stringify(json.error)}`)]);
|
|
5077
6038
|
return;
|
|
5078
6039
|
}
|
|
5079
6040
|
parseStreamChunk(json, apiFormat, callbacks, logger);
|
|
@@ -5106,7 +6067,7 @@ async function streamWithTools(options, callbacks, mcpService, llmConfig, getPro
|
|
|
5106
6067
|
toolCallsLength: toolCalls.length,
|
|
5107
6068
|
executableToolCallsLength: executableToolCalls.length,
|
|
5108
6069
|
hasMcpTools: !!options.mcpTools,
|
|
5109
|
-
mcpToolsLength: _optionalChain([options, 'access',
|
|
6070
|
+
mcpToolsLength: _optionalChain([options, 'access', _335 => _335.mcpTools, 'optionalAccess', _336 => _336.length]),
|
|
5110
6071
|
hasMcpService: !!mcpService
|
|
5111
6072
|
});
|
|
5112
6073
|
if (executableToolCalls.length > 0 && options.mcpTools && (mcpService || builtinExecutor)) {
|
|
@@ -5127,7 +6088,7 @@ async function streamWithTools(options, callbacks, mcpService, llmConfig, getPro
|
|
|
5127
6088
|
builtinExecutor
|
|
5128
6089
|
);
|
|
5129
6090
|
const toolResultsText = toolResults.map(({ toolCall, result }) => {
|
|
5130
|
-
const resultText = typeof result === "string" ? result : _optionalChain([result, 'access',
|
|
6091
|
+
const resultText = typeof result === "string" ? result : _optionalChain([result, 'access', _337 => _337.content, 'optionalAccess', _338 => _338[0], 'optionalAccess', _339 => _339.text]) || JSON.stringify(result);
|
|
5131
6092
|
return `Tool ${toolCall.name} result:
|
|
5132
6093
|
${resultText}`;
|
|
5133
6094
|
}).join("\n\n");
|
|
@@ -5145,12 +6106,12 @@ ${resultText}`;
|
|
|
5145
6106
|
}
|
|
5146
6107
|
} catch (streamError) {
|
|
5147
6108
|
logger.error("Stream processing error", streamError instanceof Error ? streamError : void 0);
|
|
5148
|
-
_optionalChain([callbacks, 'access',
|
|
6109
|
+
_optionalChain([callbacks, 'access', _340 => _340.onError, 'optionalCall', _341 => _341(`Stream error: ${streamError instanceof Error ? streamError.message : "Unknown error"}`)]);
|
|
5149
6110
|
return;
|
|
5150
6111
|
}
|
|
5151
6112
|
}
|
|
5152
6113
|
logger.info("Sending final callback", { blocksCount: blocks.length });
|
|
5153
|
-
_optionalChain([callbacks, 'access',
|
|
6114
|
+
_optionalChain([callbacks, 'access', _342 => _342.onDone, 'optionalCall', _343 => _343({
|
|
5154
6115
|
id: messageId,
|
|
5155
6116
|
role: "assistant",
|
|
5156
6117
|
content: finalContent,
|
|
@@ -5161,7 +6122,7 @@ ${resultText}`;
|
|
|
5161
6122
|
} catch (error) {
|
|
5162
6123
|
logger.error("Error in streamWithTools", error instanceof Error ? error : void 0);
|
|
5163
6124
|
const message = error instanceof Error ? error.message : "Unknown error";
|
|
5164
|
-
_optionalChain([callbacks, 'access',
|
|
6125
|
+
_optionalChain([callbacks, 'access', _344 => _344.onError, 'optionalCall', _345 => _345(message)]);
|
|
5165
6126
|
}
|
|
5166
6127
|
}
|
|
5167
6128
|
|
|
@@ -5187,21 +6148,33 @@ function readUsageFromOpenAIResponse(usage) {
|
|
|
5187
6148
|
var sharedExecutor2 = null;
|
|
5188
6149
|
function getSharedExecutor2() {
|
|
5189
6150
|
if (!sharedExecutor2) {
|
|
5190
|
-
sharedExecutor2 = new (0,
|
|
6151
|
+
sharedExecutor2 = new (0, _chunkIIRPUVPHcjs.TransformerChainExecutor)();
|
|
5191
6152
|
}
|
|
5192
6153
|
return sharedExecutor2;
|
|
5193
6154
|
}
|
|
5194
6155
|
async function resolveChainWithMain(llmConfig, providerId, model) {
|
|
5195
6156
|
return _chunkQXD4MV2Xcjs.resolveProviderChain.call(void 0, llmConfig, providerId, model);
|
|
5196
6157
|
}
|
|
6158
|
+
function buildUnifiedCompletionRequest(actualModel, options, stream) {
|
|
6159
|
+
return {
|
|
6160
|
+
model: actualModel,
|
|
6161
|
+
messages: options.messages.map((m) => ({
|
|
6162
|
+
role: m.role,
|
|
6163
|
+
content: m.content
|
|
6164
|
+
})),
|
|
6165
|
+
...options.maxTokens !== void 0 ? { max_tokens: options.maxTokens } : {},
|
|
6166
|
+
temperature: options.temperature,
|
|
6167
|
+
stream
|
|
6168
|
+
};
|
|
6169
|
+
}
|
|
5197
6170
|
async function completeWithTransformers(options, llmConfig, getProvider, resolveApiKey2, completeFallback, logger, recording) {
|
|
5198
6171
|
try {
|
|
5199
6172
|
const routedInfo = await llmConfig.resolveRoutedModel(
|
|
5200
6173
|
options.providerId,
|
|
5201
6174
|
options.model
|
|
5202
6175
|
);
|
|
5203
|
-
const actualProviderId = _optionalChain([routedInfo, 'optionalAccess',
|
|
5204
|
-
const actualModel = _optionalChain([routedInfo, 'optionalAccess',
|
|
6176
|
+
const actualProviderId = _optionalChain([routedInfo, 'optionalAccess', _346 => _346.actualProviderId]) || options.providerId;
|
|
6177
|
+
const actualModel = _optionalChain([routedInfo, 'optionalAccess', _347 => _347.actualModelId]) || options.model;
|
|
5205
6178
|
const provider = await getProvider(actualProviderId);
|
|
5206
6179
|
if (!provider) {
|
|
5207
6180
|
return { success: false, error: `Provider not found: ${actualProviderId}` };
|
|
@@ -5222,16 +6195,11 @@ async function completeWithTransformers(options, llmConfig, getProvider, resolve
|
|
|
5222
6195
|
if (!hasTransformers) {
|
|
5223
6196
|
return completeFallback(options);
|
|
5224
6197
|
}
|
|
5225
|
-
const unifiedRequest =
|
|
5226
|
-
|
|
5227
|
-
|
|
5228
|
-
|
|
5229
|
-
|
|
5230
|
-
})),
|
|
5231
|
-
max_tokens: options.maxTokens || 4096,
|
|
5232
|
-
temperature: options.temperature,
|
|
5233
|
-
stream: _nullishCoalesce(options.stream, () => ( false))
|
|
5234
|
-
};
|
|
6198
|
+
const unifiedRequest = buildUnifiedCompletionRequest(
|
|
6199
|
+
actualModel,
|
|
6200
|
+
options,
|
|
6201
|
+
_nullishCoalesce(options.stream, () => ( false))
|
|
6202
|
+
);
|
|
5235
6203
|
const transformerProvider = {
|
|
5236
6204
|
name: provider.name,
|
|
5237
6205
|
baseUrl: provider.api_base_url,
|
|
@@ -5239,7 +6207,7 @@ async function completeWithTransformers(options, llmConfig, getProvider, resolve
|
|
|
5239
6207
|
models: provider.models || []
|
|
5240
6208
|
};
|
|
5241
6209
|
const executor = getSharedExecutor2();
|
|
5242
|
-
const { response } = await
|
|
6210
|
+
const { response } = await _chunkMUHWHQVMcjs.executeProviderCall.call(void 0, {
|
|
5243
6211
|
executor,
|
|
5244
6212
|
request: unifiedRequest,
|
|
5245
6213
|
provider: transformerProvider,
|
|
@@ -5282,18 +6250,18 @@ async function completeWithTransformers(options, llmConfig, getProvider, resolve
|
|
|
5282
6250
|
{ endpointTransformer: void 0 }
|
|
5283
6251
|
);
|
|
5284
6252
|
const data = await transformedResponse.json();
|
|
5285
|
-
const choice = _optionalChain([data, 'access',
|
|
6253
|
+
const choice = _optionalChain([data, 'access', _348 => _348.choices, 'optionalAccess', _349 => _349[0]]);
|
|
5286
6254
|
if (!choice) {
|
|
5287
6255
|
return { success: false, error: "No choices in response" };
|
|
5288
6256
|
}
|
|
5289
|
-
const rawToolCalls = _optionalChain([choice, 'access',
|
|
5290
|
-
const toolCalls = _optionalChain([rawToolCalls, 'optionalAccess',
|
|
6257
|
+
const rawToolCalls = _optionalChain([choice, 'access', _350 => _350.message, 'optionalAccess', _351 => _351.tool_calls]);
|
|
6258
|
+
const toolCalls = _optionalChain([rawToolCalls, 'optionalAccess', _352 => _352.map, 'call', _353 => _353((tc) => ({
|
|
5291
6259
|
id: tc.id,
|
|
5292
6260
|
name: tc.function.name,
|
|
5293
6261
|
args: typeof tc.function.arguments === "string" ? JSON.parse(tc.function.arguments) : tc.function.arguments
|
|
5294
6262
|
}))]);
|
|
5295
6263
|
const tapped = readUsageFromOpenAIResponse(data.usage);
|
|
5296
|
-
if (_optionalChain([recording, 'optionalAccess',
|
|
6264
|
+
if (_optionalChain([recording, 'optionalAccess', _354 => _354.recorder]) && tapped) {
|
|
5297
6265
|
recording.recorder.record({
|
|
5298
6266
|
messageId: _nullishCoalesce(options.messageId, () => ( null)),
|
|
5299
6267
|
parentMessageId: _nullishCoalesce(options.parentMessageId, () => ( null)),
|
|
@@ -5311,9 +6279,9 @@ async function completeWithTransformers(options, llmConfig, getProvider, resolve
|
|
|
5311
6279
|
message: {
|
|
5312
6280
|
id: `msg_${Date.now()}`,
|
|
5313
6281
|
role: "assistant",
|
|
5314
|
-
content: _optionalChain([choice, 'access',
|
|
6282
|
+
content: _optionalChain([choice, 'access', _355 => _355.message, 'optionalAccess', _356 => _356.content]) || "",
|
|
5315
6283
|
timestamp: Date.now(),
|
|
5316
|
-
thinking: data.reasoning_content || _optionalChain([choice, 'access',
|
|
6284
|
+
thinking: data.reasoning_content || _optionalChain([choice, 'access', _357 => _357.message, 'optionalAccess', _358 => _358.thinking, 'optionalAccess', _359 => _359.content]) ? { content: data.reasoning_content || _optionalChain([choice, 'access', _360 => _360.message, 'optionalAccess', _361 => _361.thinking, 'optionalAccess', _362 => _362.content]) || "", signature: _optionalChain([choice, 'access', _363 => _363.message, 'optionalAccess', _364 => _364.thinking, 'optionalAccess', _365 => _365.signature]) } : void 0,
|
|
5317
6285
|
toolCalls
|
|
5318
6286
|
},
|
|
5319
6287
|
usage: data.usage ? {
|
|
@@ -5334,21 +6302,21 @@ async function completeStreamWithTransformers(options, callbacks, llmConfig, get
|
|
|
5334
6302
|
options.providerId,
|
|
5335
6303
|
options.model
|
|
5336
6304
|
);
|
|
5337
|
-
const actualProviderId = _optionalChain([routedInfo, 'optionalAccess',
|
|
5338
|
-
const actualModel = _optionalChain([routedInfo, 'optionalAccess',
|
|
6305
|
+
const actualProviderId = _optionalChain([routedInfo, 'optionalAccess', _366 => _366.actualProviderId]) || options.providerId;
|
|
6306
|
+
const actualModel = _optionalChain([routedInfo, 'optionalAccess', _367 => _367.actualModelId]) || options.model;
|
|
5339
6307
|
const provider = await getProvider(actualProviderId);
|
|
5340
6308
|
if (!provider) {
|
|
5341
|
-
_optionalChain([callbacks, 'access',
|
|
6309
|
+
_optionalChain([callbacks, 'access', _368 => _368.onError, 'optionalCall', _369 => _369(`Provider not found: ${actualProviderId}`)]);
|
|
5342
6310
|
return;
|
|
5343
6311
|
}
|
|
5344
6312
|
if (!provider.enabled) {
|
|
5345
|
-
_optionalChain([callbacks, 'access',
|
|
6313
|
+
_optionalChain([callbacks, 'access', _370 => _370.onError, 'optionalCall', _371 => _371(`Provider is disabled: ${provider.name}`)]);
|
|
5346
6314
|
return;
|
|
5347
6315
|
}
|
|
5348
6316
|
const { apiKey: effectiveKey } = _chunkA2YMUCBTcjs.resolveProviderEndpoint.call(void 0, provider);
|
|
5349
6317
|
const apiKey = resolveApiKey2(effectiveKey);
|
|
5350
6318
|
if (!apiKey) {
|
|
5351
|
-
_optionalChain([callbacks, 'access',
|
|
6319
|
+
_optionalChain([callbacks, 'access', _372 => _372.onError, 'optionalCall', _373 => _373("API key not configured")]);
|
|
5352
6320
|
return;
|
|
5353
6321
|
}
|
|
5354
6322
|
const { chain, hasTransformers } = await resolveChainWithMain(
|
|
@@ -5360,17 +6328,8 @@ async function completeStreamWithTransformers(options, callbacks, llmConfig, get
|
|
|
5360
6328
|
return completeStreamFallback(options, callbacks);
|
|
5361
6329
|
}
|
|
5362
6330
|
const messageId = `msg_${Date.now()}`;
|
|
5363
|
-
_optionalChain([callbacks, 'access',
|
|
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
|
-
};
|
|
6331
|
+
_optionalChain([callbacks, 'access', _374 => _374.onStart, 'optionalCall', _375 => _375(messageId)]);
|
|
6332
|
+
const unifiedRequest = buildUnifiedCompletionRequest(actualModel, options, true);
|
|
5374
6333
|
const transformerProvider = {
|
|
5375
6334
|
name: provider.name,
|
|
5376
6335
|
baseUrl: provider.api_base_url,
|
|
@@ -5378,7 +6337,7 @@ async function completeStreamWithTransformers(options, callbacks, llmConfig, get
|
|
|
5378
6337
|
models: provider.models || []
|
|
5379
6338
|
};
|
|
5380
6339
|
const executor = getSharedExecutor2();
|
|
5381
|
-
const { response } = await
|
|
6340
|
+
const { response } = await _chunkMUHWHQVMcjs.executeProviderCall.call(void 0, {
|
|
5382
6341
|
executor,
|
|
5383
6342
|
request: unifiedRequest,
|
|
5384
6343
|
provider: transformerProvider,
|
|
@@ -5408,7 +6367,7 @@ async function completeStreamWithTransformers(options, callbacks, llmConfig, get
|
|
|
5408
6367
|
});
|
|
5409
6368
|
if (!response.ok) {
|
|
5410
6369
|
const errorText = await response.text();
|
|
5411
|
-
_optionalChain([callbacks, 'access',
|
|
6370
|
+
_optionalChain([callbacks, 'access', _376 => _376.onError, 'optionalCall', _377 => _377(`API error (${response.status}): ${errorText}`)]);
|
|
5412
6371
|
return;
|
|
5413
6372
|
}
|
|
5414
6373
|
const transformedResponse = await executor.executeResponseChain(
|
|
@@ -5418,9 +6377,9 @@ async function completeStreamWithTransformers(options, callbacks, llmConfig, get
|
|
|
5418
6377
|
chain,
|
|
5419
6378
|
{ endpointTransformer: void 0 }
|
|
5420
6379
|
);
|
|
5421
|
-
const reader = _optionalChain([transformedResponse, 'access',
|
|
6380
|
+
const reader = _optionalChain([transformedResponse, 'access', _378 => _378.body, 'optionalAccess', _379 => _379.getReader, 'call', _380 => _380()]);
|
|
5422
6381
|
if (!reader) {
|
|
5423
|
-
_optionalChain([callbacks, 'access',
|
|
6382
|
+
_optionalChain([callbacks, 'access', _381 => _381.onError, 'optionalCall', _382 => _382("No response body")]);
|
|
5424
6383
|
return;
|
|
5425
6384
|
}
|
|
5426
6385
|
const decoder = new TextDecoder();
|
|
@@ -5438,22 +6397,22 @@ async function completeStreamWithTransformers(options, callbacks, llmConfig, get
|
|
|
5438
6397
|
if (data === "[DONE]") continue;
|
|
5439
6398
|
try {
|
|
5440
6399
|
const json = JSON.parse(data);
|
|
5441
|
-
const delta = _optionalChain([json, 'access',
|
|
5442
|
-
if (_optionalChain([delta, 'optionalAccess',
|
|
6400
|
+
const delta = _optionalChain([json, 'access', _383 => _383.choices, 'optionalAccess', _384 => _384[0], 'optionalAccess', _385 => _385.delta]);
|
|
6401
|
+
if (_optionalChain([delta, 'optionalAccess', _386 => _386.content])) {
|
|
5443
6402
|
content += delta.content;
|
|
5444
|
-
_optionalChain([callbacks, 'access',
|
|
6403
|
+
_optionalChain([callbacks, 'access', _387 => _387.onDelta, 'optionalCall', _388 => _388(delta.content)]);
|
|
5445
6404
|
}
|
|
5446
|
-
if (_optionalChain([delta, 'optionalAccess',
|
|
6405
|
+
if (_optionalChain([delta, 'optionalAccess', _389 => _389.thinking, 'optionalAccess', _390 => _390.content])) {
|
|
5447
6406
|
reasoning += delta.thinking.content;
|
|
5448
|
-
_optionalChain([callbacks, 'access',
|
|
6407
|
+
_optionalChain([callbacks, 'access', _391 => _391.onReasoning, 'optionalCall', _392 => _392(delta.thinking.content)]);
|
|
5449
6408
|
}
|
|
5450
|
-
if (_optionalChain([delta, 'optionalAccess',
|
|
6409
|
+
if (_optionalChain([delta, 'optionalAccess', _393 => _393.reasoning_content])) {
|
|
5451
6410
|
reasoning += delta.reasoning_content;
|
|
5452
|
-
_optionalChain([callbacks, 'access',
|
|
6411
|
+
_optionalChain([callbacks, 'access', _394 => _394.onReasoning, 'optionalCall', _395 => _395(delta.reasoning_content)]);
|
|
5453
6412
|
}
|
|
5454
6413
|
if (json.usage) {
|
|
5455
6414
|
const tapped = readUsageFromOpenAIResponse(json.usage);
|
|
5456
|
-
if (_optionalChain([recording, 'optionalAccess',
|
|
6415
|
+
if (_optionalChain([recording, 'optionalAccess', _396 => _396.recorder]) && tapped) {
|
|
5457
6416
|
recording.recorder.record({
|
|
5458
6417
|
messageId: _nullishCoalesce(options.messageId, () => ( null)),
|
|
5459
6418
|
parentMessageId: _nullishCoalesce(options.parentMessageId, () => ( null)),
|
|
@@ -5466,7 +6425,7 @@ async function completeStreamWithTransformers(options, callbacks, llmConfig, get
|
|
|
5466
6425
|
rawUsage: json.usage
|
|
5467
6426
|
});
|
|
5468
6427
|
}
|
|
5469
|
-
_optionalChain([callbacks, 'access',
|
|
6428
|
+
_optionalChain([callbacks, 'access', _397 => _397.onDone, 'optionalCall', _398 => _398(
|
|
5470
6429
|
{
|
|
5471
6430
|
id: messageId,
|
|
5472
6431
|
role: "assistant",
|
|
@@ -5487,7 +6446,7 @@ async function completeStreamWithTransformers(options, callbacks, llmConfig, get
|
|
|
5487
6446
|
}
|
|
5488
6447
|
}
|
|
5489
6448
|
}
|
|
5490
|
-
_optionalChain([callbacks, 'access',
|
|
6449
|
+
_optionalChain([callbacks, 'access', _399 => _399.onDone, 'optionalCall', _400 => _400({
|
|
5491
6450
|
id: messageId,
|
|
5492
6451
|
role: "assistant",
|
|
5493
6452
|
content,
|
|
@@ -5499,13 +6458,13 @@ async function completeStreamWithTransformers(options, callbacks, llmConfig, get
|
|
|
5499
6458
|
}
|
|
5500
6459
|
} catch (error) {
|
|
5501
6460
|
const message = error instanceof Error ? error.message : "Unknown error";
|
|
5502
|
-
_optionalChain([callbacks, 'access',
|
|
6461
|
+
_optionalChain([callbacks, 'access', _401 => _401.onError, 'optionalCall', _402 => _402(message)]);
|
|
5503
6462
|
}
|
|
5504
6463
|
}
|
|
5505
6464
|
|
|
5506
6465
|
// src/completion/CompletionService.ts
|
|
5507
6466
|
var CompletionService = (_class13 = class {
|
|
5508
|
-
constructor(paths, llmConfig, logger) {;_class13.prototype.
|
|
6467
|
+
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
6468
|
this.paths = paths;
|
|
5510
6469
|
this.llmConfig = llmConfig;
|
|
5511
6470
|
this.logger = logger;
|
|
@@ -5513,10 +6472,10 @@ var CompletionService = (_class13 = class {
|
|
|
5513
6472
|
|
|
5514
6473
|
|
|
5515
6474
|
|
|
5516
|
-
|
|
5517
|
-
|
|
5518
|
-
|
|
5519
|
-
|
|
6475
|
+
__init23() {this.apiKeyPool = null}
|
|
6476
|
+
__init24() {this.usageRecorder = null}
|
|
6477
|
+
__init25() {this.usageEventSink = null}
|
|
6478
|
+
__init26() {this.visionFallbackProvider = null}
|
|
5520
6479
|
/**
|
|
5521
6480
|
* Set the API key pool service for multi-key load balancing.
|
|
5522
6481
|
* When set, keys are resolved via the pool instead of directly from the provider.
|
|
@@ -5566,8 +6525,8 @@ var CompletionService = (_class13 = class {
|
|
|
5566
6525
|
options.providerId,
|
|
5567
6526
|
options.model
|
|
5568
6527
|
);
|
|
5569
|
-
const actualProviderId = _optionalChain([routedInfo, 'optionalAccess',
|
|
5570
|
-
const actualModel = _optionalChain([routedInfo, 'optionalAccess',
|
|
6528
|
+
const actualProviderId = _optionalChain([routedInfo, 'optionalAccess', _403 => _403.actualProviderId]) || options.providerId;
|
|
6529
|
+
const actualModel = _optionalChain([routedInfo, 'optionalAccess', _404 => _404.actualModelId]) || options.model;
|
|
5571
6530
|
const provider = await this.getProvider(actualProviderId);
|
|
5572
6531
|
if (!provider) {
|
|
5573
6532
|
return { success: false, error: `Provider not found: ${actualProviderId}` };
|
|
@@ -5600,7 +6559,7 @@ var CompletionService = (_class13 = class {
|
|
|
5600
6559
|
this.apiKeyPool.reportSuccess(options.sessionId);
|
|
5601
6560
|
}
|
|
5602
6561
|
if (result.success && result.usage && options.sessionId) {
|
|
5603
|
-
_optionalChain([this, 'access',
|
|
6562
|
+
_optionalChain([this, 'access', _405 => _405.usageEventSink, 'optionalAccess', _406 => _406.emit, 'call', _407 => _407({
|
|
5604
6563
|
sessionId: options.sessionId,
|
|
5605
6564
|
modelId: actualModel,
|
|
5606
6565
|
usage: result.usage,
|
|
@@ -5629,8 +6588,8 @@ var CompletionService = (_class13 = class {
|
|
|
5629
6588
|
options.model
|
|
5630
6589
|
);
|
|
5631
6590
|
this.logger.debug("Resolved routed model", { routedInfo });
|
|
5632
|
-
const actualProviderId = _optionalChain([routedInfo, 'optionalAccess',
|
|
5633
|
-
const actualModel = _optionalChain([routedInfo, 'optionalAccess',
|
|
6591
|
+
const actualProviderId = _optionalChain([routedInfo, 'optionalAccess', _408 => _408.actualProviderId]) || options.providerId;
|
|
6592
|
+
const actualModel = _optionalChain([routedInfo, 'optionalAccess', _409 => _409.actualModelId]) || options.model;
|
|
5634
6593
|
this.logger.debug("Resolved provider and model", { actualProviderId, actualModel });
|
|
5635
6594
|
const provider = await this.getProvider(actualProviderId);
|
|
5636
6595
|
this.logger.debug("Retrieved provider", provider ? {
|
|
@@ -5642,22 +6601,22 @@ var CompletionService = (_class13 = class {
|
|
|
5642
6601
|
enabled: provider.enabled
|
|
5643
6602
|
} : { error: "Provider not found" });
|
|
5644
6603
|
if (!provider) {
|
|
5645
|
-
_optionalChain([callbacks, 'access',
|
|
6604
|
+
_optionalChain([callbacks, 'access', _410 => _410.onError, 'optionalCall', _411 => _411(`Provider not found: ${actualProviderId}`)]);
|
|
5646
6605
|
return;
|
|
5647
6606
|
}
|
|
5648
6607
|
if (!provider.enabled) {
|
|
5649
|
-
_optionalChain([callbacks, 'access',
|
|
6608
|
+
_optionalChain([callbacks, 'access', _412 => _412.onError, 'optionalCall', _413 => _413(`Provider is disabled: ${provider.name}`)]);
|
|
5650
6609
|
return;
|
|
5651
6610
|
}
|
|
5652
6611
|
const apiKey = await this.resolveApiKeyForRequest(provider, actualProviderId, options.sessionId);
|
|
5653
6612
|
if (!apiKey) {
|
|
5654
|
-
_optionalChain([callbacks, 'access',
|
|
6613
|
+
_optionalChain([callbacks, 'access', _414 => _414.onError, 'optionalCall', _415 => _415("API key not configured")]);
|
|
5655
6614
|
return;
|
|
5656
6615
|
}
|
|
5657
6616
|
const apiFormat = _chunkA2YMUCBTcjs.resolveApiFormat.call(void 0, provider);
|
|
5658
6617
|
this.logger.info("Using API format for stream", { apiFormat });
|
|
5659
6618
|
const messageId = `msg_${Date.now()}`;
|
|
5660
|
-
_optionalChain([callbacks, 'access',
|
|
6619
|
+
_optionalChain([callbacks, 'access', _416 => _416.onStart, 'optionalCall', _417 => _417(messageId)]);
|
|
5661
6620
|
const resolvedOptions = { ...options, model: actualModel };
|
|
5662
6621
|
if (options.sessionId) {
|
|
5663
6622
|
const sid = options.sessionId;
|
|
@@ -5666,14 +6625,14 @@ var CompletionService = (_class13 = class {
|
|
|
5666
6625
|
...callbacks,
|
|
5667
6626
|
onDone: (message, usage, metrics) => {
|
|
5668
6627
|
if (usage) {
|
|
5669
|
-
_optionalChain([this, 'access',
|
|
6628
|
+
_optionalChain([this, 'access', _418 => _418.usageEventSink, 'optionalAccess', _419 => _419.emit, 'call', _420 => _420({
|
|
5670
6629
|
sessionId: sid,
|
|
5671
6630
|
modelId: actualModel,
|
|
5672
6631
|
usage,
|
|
5673
6632
|
engineOrigin: "completion"
|
|
5674
6633
|
})]);
|
|
5675
6634
|
}
|
|
5676
|
-
_optionalChain([userOnDone, 'optionalCall',
|
|
6635
|
+
_optionalChain([userOnDone, 'optionalCall', _421 => _421(message, usage, metrics)]);
|
|
5677
6636
|
}
|
|
5678
6637
|
};
|
|
5679
6638
|
}
|
|
@@ -5689,11 +6648,11 @@ var CompletionService = (_class13 = class {
|
|
|
5689
6648
|
retryState.error = { status, message: error };
|
|
5690
6649
|
return;
|
|
5691
6650
|
}
|
|
5692
|
-
_optionalChain([callbacks, 'access',
|
|
6651
|
+
_optionalChain([callbacks, 'access', _422 => _422.onError, 'optionalCall', _423 => _423(error)]);
|
|
5693
6652
|
},
|
|
5694
6653
|
onDone: (message, usage, metrics) => {
|
|
5695
6654
|
this.apiKeyPool.reportSuccess(options.sessionId);
|
|
5696
|
-
_optionalChain([callbacks, 'access',
|
|
6655
|
+
_optionalChain([callbacks, 'access', _424 => _424.onDone, 'optionalCall', _425 => _425(message, usage, metrics)]);
|
|
5697
6656
|
}
|
|
5698
6657
|
};
|
|
5699
6658
|
await this.callStreamHandler(apiFormat, provider, apiKey, resolvedOptions, messageId, interceptCallbacks);
|
|
@@ -5714,7 +6673,7 @@ var CompletionService = (_class13 = class {
|
|
|
5714
6673
|
// don't fire onStart again
|
|
5715
6674
|
});
|
|
5716
6675
|
} else {
|
|
5717
|
-
_optionalChain([callbacks, 'access',
|
|
6676
|
+
_optionalChain([callbacks, 'access', _426 => _426.onError, 'optionalCall', _427 => _427(retryState.error.message)]);
|
|
5718
6677
|
}
|
|
5719
6678
|
}
|
|
5720
6679
|
} else {
|
|
@@ -5727,7 +6686,7 @@ var CompletionService = (_class13 = class {
|
|
|
5727
6686
|
} catch (error) {
|
|
5728
6687
|
const message = error instanceof Error ? error.message : "Unknown error";
|
|
5729
6688
|
this.logger.error("Stream completion error", error instanceof Error ? error : void 0, { message });
|
|
5730
|
-
_optionalChain([callbacks, 'access',
|
|
6689
|
+
_optionalChain([callbacks, 'access', _428 => _428.onError, 'optionalCall', _429 => _429(message)]);
|
|
5731
6690
|
}
|
|
5732
6691
|
}
|
|
5733
6692
|
/**
|
|
@@ -5767,7 +6726,7 @@ var CompletionService = (_class13 = class {
|
|
|
5767
6726
|
return {
|
|
5768
6727
|
success: true,
|
|
5769
6728
|
message: "Connection successful",
|
|
5770
|
-
response: _optionalChain([result, 'access',
|
|
6729
|
+
response: _optionalChain([result, 'access', _430 => _430.message, 'optionalAccess', _431 => _431.content]) || "",
|
|
5771
6730
|
model: modelId,
|
|
5772
6731
|
durationMs
|
|
5773
6732
|
};
|
|
@@ -5832,7 +6791,7 @@ ${description}`;
|
|
|
5832
6791
|
* 3. Legacy single key from provider config
|
|
5833
6792
|
*/
|
|
5834
6793
|
async resolveApiKeyForRequest(provider, providerId, sessionId) {
|
|
5835
|
-
if (_optionalChain([provider, 'access',
|
|
6794
|
+
if (_optionalChain([provider, 'access', _432 => _432.codingPlan, 'optionalAccess', _433 => _433.enabled]) && provider.codingPlan.apiKey) {
|
|
5836
6795
|
return this.resolveApiKey(provider.codingPlan.apiKey);
|
|
5837
6796
|
}
|
|
5838
6797
|
if (this.apiKeyPool) {
|
|
@@ -5905,9 +6864,10 @@ ${description}`;
|
|
|
5905
6864
|
* Resolve effective max_tokens value with priority:
|
|
5906
6865
|
* 1. Session settings (if provided)
|
|
5907
6866
|
* 2. Global model parameters (if enabled)
|
|
5908
|
-
* 3.
|
|
5909
|
-
*
|
|
5910
|
-
*
|
|
6867
|
+
* 3. undefined - let API use its default
|
|
6868
|
+
*
|
|
6869
|
+
* Provider and discovery maxTokens values are capability metadata, not
|
|
6870
|
+
* implicit per-request output limits.
|
|
5911
6871
|
*/
|
|
5912
6872
|
async resolveEffectiveMaxTokens(providerId, modelId, sessionMaxTokens) {
|
|
5913
6873
|
return resolveEffectiveMaxTokens(
|
|
@@ -6082,4 +7042,13 @@ ${description}`;
|
|
|
6082
7042
|
|
|
6083
7043
|
|
|
6084
7044
|
|
|
6085
|
-
|
|
7045
|
+
|
|
7046
|
+
|
|
7047
|
+
|
|
7048
|
+
|
|
7049
|
+
|
|
7050
|
+
|
|
7051
|
+
|
|
7052
|
+
|
|
7053
|
+
|
|
7054
|
+
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;
|