@omnicross/core 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +7 -5
- package/dist/auth/GeminiCodeAssistProjectResolver.js +5 -3
- package/dist/{chunk-HRRYG2AX.js → chunk-23S5OPIO.js} +10 -1
- package/dist/chunk-25GXJCEZ.cjs +40 -0
- package/dist/chunk-2JYRIADS.js +40 -0
- package/dist/chunk-3Z5BQZFM.cjs +52 -0
- package/dist/{chunk-4VAVYUZS.cjs → chunk-4VLRHHFE.cjs} +82 -40
- package/dist/{chunk-VACWOIRE.cjs → chunk-4VZX5F4T.cjs} +39 -15
- package/dist/{chunk-FTQ7IQUC.js → chunk-6CL5HTPQ.js} +52 -10
- package/dist/chunk-6QQG7YG3.cjs +153 -0
- package/dist/{chunk-SU2GCLAC.cjs → chunk-6VUQPOV3.cjs} +359 -60
- package/dist/chunk-7AK7B36B.cjs +44 -0
- package/dist/{chunk-5ZQBEOMD.js → chunk-AT7B7SOZ.js} +25 -2
- package/dist/{chunk-IK3KE3AU.js → chunk-DE2SRBFZ.js} +1 -1
- package/dist/chunk-DLXZEZWO.cjs +285 -0
- package/dist/{chunk-UHGVBFU3.js → chunk-EBLFCNPY.js} +38 -14
- package/dist/chunk-EJLH6NFT.cjs +166 -0
- package/dist/chunk-HVBBDBS3.cjs +350 -0
- package/dist/{chunk-7Y47UCF2.js → chunk-IFXJ2BG7.js} +5 -38
- package/dist/{chunk-46ZIFWYG.cjs → chunk-IIRPUVPH.cjs} +7 -1
- package/dist/{chunk-YGXJGRFI.cjs → chunk-KBM2W6UY.cjs} +111 -24
- package/dist/{chunk-OCEUVQHW.cjs → chunk-KCVJWJST.cjs} +73 -3
- package/dist/chunk-LB6EBS6Y.js +69 -0
- package/dist/{chunk-C7PSERMH.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-Z7Y2NPHY.js → chunk-N5T4M4GU.js} +1 -1
- package/dist/{chunk-TIER4SUC.js → chunk-OEWZUX4G.js} +346 -47
- package/dist/chunk-OF3BECU2.cjs +69 -0
- package/dist/{chunk-RSJ3TWJQ.cjs → chunk-OKMJLEXX.cjs} +5 -5
- package/dist/chunk-OPRS4IQZ.js +153 -0
- package/dist/{chunk-XK5CIRMQ.js → chunk-SIZQQD6T.js} +72 -2
- package/dist/{chunk-DKPXN34V.cjs → chunk-SQYVORNP.cjs} +1334 -510
- package/dist/chunk-SYQF7OIR.js +52 -0
- package/dist/{chunk-S4WBV25P.js → chunk-TOVPMMHM.js} +111 -24
- package/dist/{chunk-QYTT6GE3.js → chunk-UDCC7EMR.js} +1093 -269
- package/dist/{chunk-E3UCVHLP.cjs → chunk-UNWKG6EI.cjs} +5 -38
- package/dist/{chunk-ZLX3KGXX.js → chunk-UX7VWA46.js} +135 -23
- package/dist/{chunk-7YN22L2H.cjs → chunk-V4TXMEJS.cjs} +5 -5
- package/dist/chunk-VRFBB5DB.js +44 -0
- package/dist/chunk-WB6PH56J.js +166 -0
- package/dist/{chunk-G2UTNSGU.js → chunk-WNKWAEUR.js} +7 -1
- package/dist/{chunk-SUEGJ75D.cjs → chunk-WYTEQ4Q5.cjs} +25 -2
- package/dist/{chunk-5ENKBSWO.js → chunk-YJVHCHQX.js} +42 -6
- package/dist/{chunk-VQY5W4YW.cjs → chunk-YK57NMIF.cjs} +44 -8
- package/dist/{chunk-KFI44N2R.cjs → chunk-YNJNTCSQ.cjs} +10 -1
- 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 +27 -24
- package/dist/completion/CompletionService.d.cts +2 -1
- package/dist/completion/CompletionService.d.ts +2 -1
- package/dist/completion/CompletionService.js +26 -23
- package/dist/completion.cjs +27 -24
- package/dist/completion.d.cts +2 -1
- package/dist/completion.d.ts +2 -1
- package/dist/completion.js +26 -23
- package/dist/index.cjs +53 -29
- package/dist/index.d.cts +8 -8
- package/dist/index.d.ts +8 -8
- package/dist/index.js +56 -32
- 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 +5 -3
- package/dist/outbound-api/auditCapture.d.ts +5 -3
- 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 +4 -3
- package/dist/outbound-api/routeResolver.d.ts +4 -3
- package/dist/outbound-api/routeResolver.js +1 -1
- package/dist/outbound-api/subscriptionRegistryPort.d.cts +1 -0
- package/dist/outbound-api/subscriptionRegistryPort.d.ts +1 -0
- package/dist/outbound-api/types.d.cts +3 -2
- package/dist/outbound-api/types.d.ts +3 -2
- package/dist/outbound-api.cjs +49 -25
- package/dist/outbound-api.d.cts +127 -85
- package/dist/outbound-api.d.ts +127 -85
- package/dist/outbound-api.js +52 -28
- package/dist/pipeline/AccountAllowanceScheduling.cjs +15 -0
- package/dist/pipeline/AccountAllowanceScheduling.d.cts +90 -0
- package/dist/pipeline/AccountAllowanceScheduling.d.ts +90 -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/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/SubscriptionAccountHealth.cjs +4 -2
- package/dist/pipeline/SubscriptionAccountHealth.d.cts +34 -6
- package/dist/pipeline/SubscriptionAccountHealth.d.ts +34 -6
- package/dist/pipeline/SubscriptionAccountHealth.js +3 -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 +4 -2
- package/dist/pipeline/upstreamFetch.d.cts +6 -0
- package/dist/pipeline/upstreamFetch.d.ts +6 -0
- package/dist/pipeline/upstreamFetch.js +3 -1
- package/dist/pipeline/upstreamTrace.cjs +14 -0
- package/dist/pipeline/upstreamTrace.d.cts +85 -0
- package/dist/pipeline/upstreamTrace.d.ts +85 -0
- package/dist/pipeline/upstreamTrace.js +14 -0
- 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 +27 -24
- package/dist/provider-proxy/ProviderProxy.d.cts +1 -0
- package/dist/provider-proxy/ProviderProxy.d.ts +1 -0
- package/dist/provider-proxy/ProviderProxy.js +26 -23
- package/dist/provider-proxy/ingress/providerProxyShared.cjs +31 -24
- package/dist/provider-proxy/ingress/providerProxyShared.d.cts +50 -5
- package/dist/provider-proxy/ingress/providerProxyShared.d.ts +50 -5
- package/dist/provider-proxy/ingress/providerProxyShared.js +30 -23
- package/dist/provider-proxy/matchText.cjs +4 -2
- package/dist/provider-proxy/matchText.d.cts +41 -6
- package/dist/provider-proxy/matchText.d.ts +41 -6
- package/dist/provider-proxy/matchText.js +3 -1
- package/dist/provider-proxy/types.d.cts +30 -2
- package/dist/provider-proxy/types.d.ts +30 -2
- package/dist/provider-proxy.cjs +27 -24
- package/dist/provider-proxy.d.cts +1 -0
- package/dist/provider-proxy.d.ts +1 -0
- package/dist/provider-proxy.js +26 -23
- package/dist/{routeResolver-C4T7yClx.d.ts → routeResolver-CHTv_Bs5.d.ts} +1 -1
- package/dist/{routeResolver-CB3tvJKy.d.cts → routeResolver-kepxnfcC.d.cts} +1 -1
- package/dist/transformer/TransformerChainExecutor.cjs +2 -2
- package/dist/transformer/TransformerChainExecutor.js +1 -1
- package/dist/transformer/transformers/AnthropicTransformer.cjs +2 -2
- package/dist/transformer/transformers/AnthropicTransformer.js +1 -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 +2 -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 +1 -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 +8 -14
- package/dist/transformer/transformers.d.cts +12 -48
- package/dist/transformer/transformers.d.ts +12 -48
- package/dist/transformer/transformers.js +11 -17
- package/dist/transformer/types.d.cts +17 -0
- package/dist/transformer/types.d.ts +17 -0
- package/dist/transformer.cjs +11 -12
- package/dist/transformer.d.cts +1 -2
- package/dist/transformer.d.ts +1 -2
- package/dist/transformer.js +11 -12
- package/dist/{types-B8Arpxn0.d.cts → types-H3wGZSOo.d.cts} +134 -7
- package/dist/{types-lgPYQuZS.d.ts → types-hsoKrVQS.d.ts} +134 -7
- package/dist/usage/pricing-engine.cjs +2 -2
- package/dist/usage/pricing-engine.d.cts +9 -1
- package/dist/usage/pricing-engine.d.ts +9 -1
- package/dist/usage/pricing-engine.js +1 -1
- package/dist/usage.cjs +2 -2
- package/dist/usage.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-C72S6TTV.cjs +0 -49
- package/dist/chunk-DWKQZ2SK.cjs +0 -254
- package/dist/chunk-IAXWICZU.js +0 -69
- package/dist/chunk-QWBWGODS.cjs +0 -69
- package/dist/chunk-RGTR7CIO.cjs +0 -235
- package/dist/chunk-VPBAUQ2M.js +0 -235
- package/dist/chunk-YMFAJFQT.cjs +0 -173
- package/dist/chunk-Z7LUNECE.js +0 -49
- package/dist/chunk-ZJZAOKI7.js +0 -254
- 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
|
@@ -1,21 +1,30 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3; var _class4; var _class5; var _class6; var _class7; var _class8; var _class9; var _class10; var _class11; var _class12; var _class13;
|
|
2
2
|
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
var _chunkEJLH6NFTcjs = require('./chunk-EJLH6NFT.cjs');
|
|
6
|
+
|
|
7
|
+
|
|
3
8
|
var _chunkHQP3K7PUcjs = require('./chunk-HQP3K7PU.cjs');
|
|
4
9
|
|
|
5
10
|
|
|
6
|
-
var
|
|
11
|
+
var _chunkIIRPUVPHcjs = require('./chunk-IIRPUVPH.cjs');
|
|
7
12
|
|
|
8
13
|
|
|
9
|
-
var
|
|
14
|
+
var _chunkGBHYAGX3cjs = require('./chunk-GBHYAGX3.cjs');
|
|
10
15
|
|
|
11
16
|
|
|
12
|
-
var
|
|
17
|
+
var _chunkV4TXMEJScjs = require('./chunk-V4TXMEJS.cjs');
|
|
13
18
|
|
|
14
19
|
|
|
15
|
-
var
|
|
20
|
+
var _chunk6VUQPOV3cjs = require('./chunk-6VUQPOV3.cjs');
|
|
16
21
|
|
|
17
22
|
|
|
18
|
-
|
|
23
|
+
|
|
24
|
+
var _chunk4VLRHHFEcjs = require('./chunk-4VLRHHFE.cjs');
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
var _chunkR3HK6R4Bcjs = require('./chunk-R3HK6R4B.cjs');
|
|
19
28
|
|
|
20
29
|
|
|
21
30
|
var _chunkRPII3E6Zcjs = require('./chunk-RPII3E6Z.cjs');
|
|
@@ -25,37 +34,37 @@ var _chunkRPII3E6Zcjs = require('./chunk-RPII3E6Z.cjs');
|
|
|
25
34
|
var _chunk6RPZADX3cjs = require('./chunk-6RPZADX3.cjs');
|
|
26
35
|
|
|
27
36
|
|
|
37
|
+
var _chunkNYUNU75Acjs = require('./chunk-NYUNU75A.cjs');
|
|
28
38
|
|
|
29
|
-
var _chunkQWBWGODScjs = require('./chunk-QWBWGODS.cjs');
|
|
30
39
|
|
|
31
40
|
|
|
32
|
-
var
|
|
41
|
+
var _chunkYK57NMIFcjs = require('./chunk-YK57NMIF.cjs');
|
|
33
42
|
|
|
34
43
|
|
|
35
|
-
var
|
|
44
|
+
var _chunkYNJNTCSQcjs = require('./chunk-YNJNTCSQ.cjs');
|
|
36
45
|
|
|
37
46
|
|
|
38
|
-
var
|
|
47
|
+
var _chunkSVNDB62Dcjs = require('./chunk-SVNDB62D.cjs');
|
|
39
48
|
|
|
40
49
|
|
|
50
|
+
var _chunkUIBD2YY5cjs = require('./chunk-UIBD2YY5.cjs');
|
|
41
51
|
|
|
42
|
-
var _chunkQ27JY5RGcjs = require('./chunk-Q27JY5RG.cjs');
|
|
43
52
|
|
|
53
|
+
var _chunk6QQG7YG3cjs = require('./chunk-6QQG7YG3.cjs');
|
|
44
54
|
|
|
45
|
-
var _chunkQXD4MV2Xcjs = require('./chunk-QXD4MV2X.cjs');
|
|
46
55
|
|
|
47
56
|
|
|
48
|
-
var
|
|
57
|
+
var _chunk25GXJCEZcjs = require('./chunk-25GXJCEZ.cjs');
|
|
49
58
|
|
|
50
59
|
|
|
60
|
+
var _chunkMUHWHQVMcjs = require('./chunk-MUHWHQVM.cjs');
|
|
51
61
|
|
|
52
|
-
var _chunkVQY5W4YWcjs = require('./chunk-VQY5W4YW.cjs');
|
|
53
62
|
|
|
54
63
|
|
|
55
|
-
var
|
|
64
|
+
var _chunkQ27JY5RGcjs = require('./chunk-Q27JY5RG.cjs');
|
|
56
65
|
|
|
57
66
|
|
|
58
|
-
var
|
|
67
|
+
var _chunkQXD4MV2Xcjs = require('./chunk-QXD4MV2X.cjs');
|
|
59
68
|
|
|
60
69
|
|
|
61
70
|
var _chunkAPYG5QD7cjs = require('./chunk-APYG5QD7.cjs');
|
|
@@ -72,7 +81,8 @@ var _chunk4YINUUKQcjs = require('./chunk-4YINUUKQ.cjs');
|
|
|
72
81
|
|
|
73
82
|
|
|
74
83
|
|
|
75
|
-
|
|
84
|
+
|
|
85
|
+
var _chunk4VZX5F4Tcjs = require('./chunk-4VZX5F4T.cjs');
|
|
76
86
|
|
|
77
87
|
|
|
78
88
|
|
|
@@ -80,14 +90,14 @@ var _chunkVACWOIREcjs = require('./chunk-VACWOIRE.cjs');
|
|
|
80
90
|
var _chunkA2YMUCBTcjs = require('./chunk-A2YMUCBT.cjs');
|
|
81
91
|
|
|
82
92
|
|
|
83
|
-
var
|
|
93
|
+
var _chunkUNWKG6EIcjs = require('./chunk-UNWKG6EI.cjs');
|
|
84
94
|
|
|
85
95
|
|
|
86
96
|
|
|
87
|
-
var
|
|
97
|
+
var _chunkWYTEQ4Q5cjs = require('./chunk-WYTEQ4Q5.cjs');
|
|
88
98
|
|
|
89
99
|
|
|
90
|
-
var
|
|
100
|
+
var _chunkKCVJWJSTcjs = require('./chunk-KCVJWJST.cjs');
|
|
91
101
|
|
|
92
102
|
|
|
93
103
|
var _chunkJMJBSACDcjs = require('./chunk-JMJBSACD.cjs');
|
|
@@ -486,48 +496,61 @@ function readAnthropicUsage(usage) {
|
|
|
486
496
|
reasoningTokens: 0
|
|
487
497
|
};
|
|
488
498
|
}
|
|
499
|
+
function emitAnthropicUsageRecord(recorder, rawUsage, attribution) {
|
|
500
|
+
const tapped = readAnthropicUsage(rawUsage);
|
|
501
|
+
if (!tapped) return;
|
|
502
|
+
recorder.record({
|
|
503
|
+
messageId: null,
|
|
504
|
+
parentMessageId: null,
|
|
505
|
+
sessionId: attribution.sessionId,
|
|
506
|
+
providerId: attribution.providerId,
|
|
507
|
+
model: attribution.model,
|
|
508
|
+
apiKeyId: attribution.apiKeyId,
|
|
509
|
+
auditResponse: attribution.auditResponse,
|
|
510
|
+
engineOrigin: "codex-ingress",
|
|
511
|
+
usage: tapped,
|
|
512
|
+
rawUsage
|
|
513
|
+
});
|
|
514
|
+
}
|
|
489
515
|
function recordAnthropicNonStreamUsage(recorder, bodyText, attribution) {
|
|
490
516
|
try {
|
|
491
517
|
const parsed = JSON.parse(bodyText);
|
|
492
|
-
|
|
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
|
-
});
|
|
518
|
+
emitAnthropicUsageRecord(
|
|
519
|
+
recorder,
|
|
520
|
+
parsed.usage,
|
|
521
|
+
attribution
|
|
522
|
+
);
|
|
506
523
|
} catch (e4) {
|
|
507
524
|
}
|
|
508
525
|
}
|
|
526
|
+
function recordAnthropicStreamUsage(recorder, rawUsage, attribution) {
|
|
527
|
+
try {
|
|
528
|
+
emitAnthropicUsageRecord(recorder, rawUsage, attribution);
|
|
529
|
+
} catch (e5) {
|
|
530
|
+
}
|
|
531
|
+
}
|
|
509
532
|
|
|
510
533
|
// src/provider-proxy/ingress/providerProxyShared.ts
|
|
511
534
|
var sharedExecutor = null;
|
|
512
535
|
function getSharedExecutor() {
|
|
513
536
|
if (!sharedExecutor) {
|
|
514
|
-
sharedExecutor = new (0,
|
|
537
|
+
sharedExecutor = new (0, _chunkIIRPUVPHcjs.TransformerChainExecutor)();
|
|
515
538
|
}
|
|
516
539
|
return sharedExecutor;
|
|
517
540
|
}
|
|
518
541
|
var sharedResponses = null;
|
|
519
542
|
function getResponsesEndpointTransformer() {
|
|
520
|
-
if (!sharedResponses) sharedResponses = new (0,
|
|
543
|
+
if (!sharedResponses) sharedResponses = new (0, _chunk6VUQPOV3cjs.OpenAIResponseTransformer)();
|
|
521
544
|
return sharedResponses;
|
|
522
545
|
}
|
|
523
546
|
var sharedAnthropic = null;
|
|
524
547
|
function getAnthropicEndpointTransformer() {
|
|
525
|
-
if (!sharedAnthropic) sharedAnthropic = new (0,
|
|
548
|
+
if (!sharedAnthropic) sharedAnthropic = new (0, _chunk4VLRHHFEcjs.AnthropicTransformer)();
|
|
526
549
|
return sharedAnthropic;
|
|
527
550
|
}
|
|
528
551
|
var sharedGemini = null;
|
|
529
552
|
function getGeminiEndpointTransformer() {
|
|
530
|
-
if (!sharedGemini) sharedGemini = new (0,
|
|
553
|
+
if (!sharedGemini) sharedGemini = new (0, _chunkV4TXMEJScjs.GeminiTransformer)();
|
|
531
554
|
return sharedGemini;
|
|
532
555
|
}
|
|
533
556
|
function readBody(req) {
|
|
@@ -553,7 +576,7 @@ function rewriteJsonModel(bodyText, rewriteModel) {
|
|
|
553
576
|
changed = true;
|
|
554
577
|
}
|
|
555
578
|
return changed ? JSON.stringify(obj) : bodyText;
|
|
556
|
-
} catch (
|
|
579
|
+
} catch (e6) {
|
|
557
580
|
return bodyText;
|
|
558
581
|
}
|
|
559
582
|
}
|
|
@@ -586,11 +609,22 @@ function rewriteSseLine(line, rewriteModel) {
|
|
|
586
609
|
}
|
|
587
610
|
if (!changed) return line;
|
|
588
611
|
return `data:${leadingSpace}${JSON.stringify(obj)}${newline}`;
|
|
589
|
-
} catch (
|
|
612
|
+
} catch (e7) {
|
|
590
613
|
return line;
|
|
591
614
|
}
|
|
592
615
|
}
|
|
593
|
-
|
|
616
|
+
function tapSseDataLine(line, onEvent) {
|
|
617
|
+
const leadingStripped = line.replace(/^\s+/, "");
|
|
618
|
+
if (!leadingStripped.startsWith("data:")) return;
|
|
619
|
+
const payload = leadingStripped.slice(5).trim();
|
|
620
|
+
if (!payload || payload === "[DONE]") return;
|
|
621
|
+
try {
|
|
622
|
+
onEvent(JSON.parse(payload));
|
|
623
|
+
} catch (e8) {
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
async function relaySseBody(res, body, options) {
|
|
627
|
+
const { rewriteModel, onSseEvent } = options;
|
|
594
628
|
const reader = body.getReader();
|
|
595
629
|
const decoder = new TextDecoder();
|
|
596
630
|
let buffer = "";
|
|
@@ -604,21 +638,26 @@ async function relayStreamWithModelRewrite(res, body, rewriteModel) {
|
|
|
604
638
|
while ((nlIndex = buffer.indexOf("\n")) !== -1) {
|
|
605
639
|
const linePart = buffer.slice(0, nlIndex + 1);
|
|
606
640
|
buffer = buffer.slice(nlIndex + 1);
|
|
607
|
-
|
|
641
|
+
if (onSseEvent) tapSseDataLine(linePart, onSseEvent);
|
|
642
|
+
out += rewriteModel ? rewriteSseLine(linePart, rewriteModel) : linePart;
|
|
608
643
|
}
|
|
609
644
|
if (out) res.write(out);
|
|
610
645
|
}
|
|
611
646
|
const tail = buffer + decoder.decode();
|
|
612
|
-
if (tail)
|
|
647
|
+
if (tail) {
|
|
648
|
+
if (onSseEvent) tapSseDataLine(tail, onSseEvent);
|
|
649
|
+
res.write(rewriteModel ? rewriteSseLine(tail, rewriteModel) : tail);
|
|
650
|
+
}
|
|
613
651
|
} finally {
|
|
614
652
|
reader.releaseLock();
|
|
615
653
|
res.end();
|
|
616
654
|
}
|
|
617
655
|
}
|
|
618
|
-
async function relayResponse(res, providerResponse, isStream, rewriteModel) {
|
|
656
|
+
async function relayResponse(res, providerResponse, isStream, rewriteModel, usageTap) {
|
|
619
657
|
const contentType = _nullishCoalesce(providerResponse.headers.get("Content-Type"), () => ( ""));
|
|
620
658
|
const status = providerResponse.status && providerResponse.status >= 100 ? providerResponse.status : 200;
|
|
621
|
-
|
|
659
|
+
const upstreamIsSse = contentType.includes("text/event-stream");
|
|
660
|
+
if (upstreamIsSse || isStream && status < 400) {
|
|
622
661
|
res.writeHead(status, {
|
|
623
662
|
"Content-Type": "text/event-stream",
|
|
624
663
|
"Cache-Control": "no-cache",
|
|
@@ -628,8 +667,16 @@ async function relayResponse(res, providerResponse, isStream, rewriteModel) {
|
|
|
628
667
|
res.end();
|
|
629
668
|
return null;
|
|
630
669
|
}
|
|
631
|
-
if (rewriteModel) {
|
|
632
|
-
|
|
670
|
+
if (rewriteModel || usageTap) {
|
|
671
|
+
let capturedUsage = null;
|
|
672
|
+
await relaySseBody(res, providerResponse.body, {
|
|
673
|
+
rewriteModel,
|
|
674
|
+
onSseEvent: usageTap ? (event) => {
|
|
675
|
+
const raw = usageTap.extractUsage(event);
|
|
676
|
+
if (raw) capturedUsage = raw;
|
|
677
|
+
} : void 0
|
|
678
|
+
});
|
|
679
|
+
if (capturedUsage) usageTap.onUsage(capturedUsage);
|
|
633
680
|
return null;
|
|
634
681
|
}
|
|
635
682
|
const reader = providerResponse.body.getReader();
|
|
@@ -651,11 +698,121 @@ async function relayResponse(res, providerResponse, isStream, rewriteModel) {
|
|
|
651
698
|
res.end(clientText);
|
|
652
699
|
return bodyText;
|
|
653
700
|
}
|
|
701
|
+
async function aggregateAnthropicSseToJsonBody(response, rewriteModel) {
|
|
702
|
+
const text = await response.text();
|
|
703
|
+
const message = {
|
|
704
|
+
type: "message",
|
|
705
|
+
role: "assistant",
|
|
706
|
+
content: [],
|
|
707
|
+
stop_reason: null,
|
|
708
|
+
stop_sequence: null,
|
|
709
|
+
usage: {}
|
|
710
|
+
};
|
|
711
|
+
const blocks = /* @__PURE__ */ new Map();
|
|
712
|
+
for (const raw of text.split("\n")) {
|
|
713
|
+
const line = raw.trim();
|
|
714
|
+
if (!line.startsWith("data:")) continue;
|
|
715
|
+
const payload = line.slice(5).trim();
|
|
716
|
+
if (!payload || payload === "[DONE]") continue;
|
|
717
|
+
let ev;
|
|
718
|
+
try {
|
|
719
|
+
ev = JSON.parse(payload);
|
|
720
|
+
} catch (e9) {
|
|
721
|
+
continue;
|
|
722
|
+
}
|
|
723
|
+
switch (ev["type"]) {
|
|
724
|
+
case "message_start": {
|
|
725
|
+
const m = _nullishCoalesce(ev["message"], () => ( {}));
|
|
726
|
+
if (typeof m["id"] === "string") message["id"] = m["id"];
|
|
727
|
+
if (typeof m["model"] === "string") message["model"] = m["model"];
|
|
728
|
+
if (m["usage"]) message["usage"] = { ...m["usage"] };
|
|
729
|
+
break;
|
|
730
|
+
}
|
|
731
|
+
case "content_block_start": {
|
|
732
|
+
const idx = Number(ev["index"]);
|
|
733
|
+
const cb = _nullishCoalesce(ev["content_block"], () => ( {}));
|
|
734
|
+
blocks.set(idx, {
|
|
735
|
+
type: typeof cb["type"] === "string" ? cb["type"] : "text",
|
|
736
|
+
text: typeof cb["text"] === "string" ? cb["text"] : "",
|
|
737
|
+
id: typeof cb["id"] === "string" ? cb["id"] : void 0,
|
|
738
|
+
name: typeof cb["name"] === "string" ? cb["name"] : void 0,
|
|
739
|
+
inputJson: ""
|
|
740
|
+
});
|
|
741
|
+
break;
|
|
742
|
+
}
|
|
743
|
+
case "content_block_delta": {
|
|
744
|
+
const b = blocks.get(Number(ev["index"]));
|
|
745
|
+
if (!b) break;
|
|
746
|
+
const d = _nullishCoalesce(ev["delta"], () => ( {}));
|
|
747
|
+
if (d["type"] === "text_delta" && typeof d["text"] === "string") b.text += d["text"];
|
|
748
|
+
else if (d["type"] === "input_json_delta" && typeof d["partial_json"] === "string")
|
|
749
|
+
b.inputJson += d["partial_json"];
|
|
750
|
+
else if (d["type"] === "thinking_delta" && typeof d["thinking"] === "string")
|
|
751
|
+
b.text += d["thinking"];
|
|
752
|
+
else if (d["type"] === "signature_delta" && typeof d["signature"] === "string")
|
|
753
|
+
b.signature = (b.signature || "") + d["signature"];
|
|
754
|
+
break;
|
|
755
|
+
}
|
|
756
|
+
case "message_delta": {
|
|
757
|
+
const d = _nullishCoalesce(ev["delta"], () => ( {}));
|
|
758
|
+
if (d["stop_reason"] !== void 0) message["stop_reason"] = d["stop_reason"];
|
|
759
|
+
if (d["stop_sequence"] !== void 0) message["stop_sequence"] = d["stop_sequence"];
|
|
760
|
+
if (ev["usage"])
|
|
761
|
+
message["usage"] = { ...message["usage"], ...ev["usage"] };
|
|
762
|
+
break;
|
|
763
|
+
}
|
|
764
|
+
default:
|
|
765
|
+
break;
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
message["content"] = [...blocks.keys()].sort((a, b) => a - b).map((idx) => {
|
|
769
|
+
const blk = blocks.get(idx);
|
|
770
|
+
if (!blk) return void 0;
|
|
771
|
+
if (blk.type === "tool_use") {
|
|
772
|
+
let input = {};
|
|
773
|
+
try {
|
|
774
|
+
input = blk.inputJson ? JSON.parse(blk.inputJson) : {};
|
|
775
|
+
} catch (e10) {
|
|
776
|
+
input = {};
|
|
777
|
+
}
|
|
778
|
+
return { type: "tool_use", id: _nullishCoalesce(blk.id, () => ( "")), name: _nullishCoalesce(blk.name, () => ( "")), input };
|
|
779
|
+
}
|
|
780
|
+
if (blk.type === "thinking") {
|
|
781
|
+
const out = { type: "thinking", thinking: blk.text };
|
|
782
|
+
if (blk.signature) out.signature = blk.signature;
|
|
783
|
+
return out;
|
|
784
|
+
}
|
|
785
|
+
return { type: blk.type || "text", text: blk.text };
|
|
786
|
+
}).filter((b) => b !== void 0);
|
|
787
|
+
if (rewriteModel) message["model"] = rewriteModel;
|
|
788
|
+
return JSON.stringify(message);
|
|
789
|
+
}
|
|
654
790
|
function writeError(res, status, message) {
|
|
655
791
|
if (res.headersSent) return;
|
|
656
792
|
res.writeHead(status, { "Content-Type": "application/json" });
|
|
657
793
|
res.end(JSON.stringify({ error: { type: "provider_proxy_error", message } }));
|
|
658
794
|
}
|
|
795
|
+
function writeBoundAccountError(res, error) {
|
|
796
|
+
if (res.headersSent) return;
|
|
797
|
+
const headers = { "Content-Type": "application/json" };
|
|
798
|
+
if (error.status === 429 && error.resumeAt) {
|
|
799
|
+
const resumeMs = Date.parse(error.resumeAt);
|
|
800
|
+
if (Number.isFinite(resumeMs)) {
|
|
801
|
+
headers["Retry-After"] = String(Math.max(1, Math.ceil((resumeMs - Date.now()) / 1e3)));
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
res.writeHead(error.status, headers);
|
|
805
|
+
res.end(
|
|
806
|
+
JSON.stringify({
|
|
807
|
+
error: {
|
|
808
|
+
type: "provider_proxy_error",
|
|
809
|
+
code: error.code,
|
|
810
|
+
reason: error.reason,
|
|
811
|
+
message: _chunk25GXJCEZcjs.boundAccountSelectionMessage.call(void 0, error.reason)
|
|
812
|
+
}
|
|
813
|
+
})
|
|
814
|
+
);
|
|
815
|
+
}
|
|
659
816
|
function resolveApiKey(apiKey) {
|
|
660
817
|
if (!apiKey) return "";
|
|
661
818
|
if (apiKey.startsWith("$")) {
|
|
@@ -663,7 +820,12 @@ function resolveApiKey(apiKey) {
|
|
|
663
820
|
}
|
|
664
821
|
return apiKey;
|
|
665
822
|
}
|
|
666
|
-
async function resolvePoolBoundKey(deps, providerId, provider, sessionId) {
|
|
823
|
+
async function resolvePoolBoundKey(deps, providerId, provider, sessionId, preferredKeyId, boundKeyFallbackPolicy) {
|
|
824
|
+
if (preferredKeyId) {
|
|
825
|
+
const preferred = await _optionalChain([deps, 'access', _8 => _8.apiKeyPool, 'optionalAccess', _9 => _9.getKeyById, 'call', _10 => _10(providerId, preferredKeyId, sessionId)]);
|
|
826
|
+
if (preferred) return preferred;
|
|
827
|
+
if (boundKeyFallbackPolicy !== "pool") return "";
|
|
828
|
+
}
|
|
667
829
|
if (deps.apiKeyPool && sessionId) {
|
|
668
830
|
const poolKey = await deps.apiKeyPool.getKeyForSession(providerId, sessionId);
|
|
669
831
|
if (poolKey) return poolKey;
|
|
@@ -686,7 +848,7 @@ async function buildSubscriptionPlan(res, route, deps, anthropicBody, routeModel
|
|
|
686
848
|
resolvedModel = mapped.resolvedModel;
|
|
687
849
|
scenario = mapped.scenario;
|
|
688
850
|
}
|
|
689
|
-
const sessionKey =
|
|
851
|
+
const sessionKey = _chunkEJLH6NFTcjs.deriveSubscriptionSessionKey.call(void 0, anthropicBody);
|
|
690
852
|
const plan = buildSubscriptionIterationPlan(profile, route, deps, resolvedModel, isStream, scenario, sessionKey);
|
|
691
853
|
if (!plan) {
|
|
692
854
|
writeError(res, 502, "Subscription profile is missing resolveUpstreamUrl");
|
|
@@ -695,11 +857,11 @@ async function buildSubscriptionPlan(res, route, deps, anthropicBody, routeModel
|
|
|
695
857
|
return plan;
|
|
696
858
|
}
|
|
697
859
|
function buildSubscriptionIterationPlan(profile, route, deps, resolvedModel, isStream, scenario, sessionKey) {
|
|
698
|
-
const upstreamUrl = _optionalChain([profile, 'access',
|
|
860
|
+
const upstreamUrl = _optionalChain([profile, 'access', _11 => _11.resolveUpstreamUrl, 'optionalCall', _12 => _12(resolvedModel, route.subscriptionConfig)]);
|
|
699
861
|
if (!upstreamUrl) return null;
|
|
700
|
-
const auth = _nullishCoalesce(route.auth, () => ( new (0,
|
|
862
|
+
const auth = _nullishCoalesce(route.auth, () => ( new (0, _chunkYNJNTCSQcjs.SubscriptionAuthSource)(profile)));
|
|
701
863
|
const sameFormat = profile.mode === "pass-through" || upstreamUrl.endsWith("/v1/messages");
|
|
702
|
-
const overrideNames = _optionalChain([profile, 'access',
|
|
864
|
+
const overrideNames = _optionalChain([profile, 'access', _13 => _13.resolveProviderTransformerNames, 'optionalCall', _14 => _14(
|
|
703
865
|
resolvedModel,
|
|
704
866
|
route.subscriptionConfig
|
|
705
867
|
)]);
|
|
@@ -718,6 +880,8 @@ function buildSubscriptionIterationPlan(profile, route, deps, resolvedModel, isS
|
|
|
718
880
|
return {
|
|
719
881
|
auth,
|
|
720
882
|
preferredAccountId: route.preferredAccountId,
|
|
883
|
+
preferredAccountGroup: route.preferredAccountGroup,
|
|
884
|
+
boundAccountFallbackPolicy: route.boundAccountFallbackPolicy,
|
|
721
885
|
chain,
|
|
722
886
|
transformerProvider,
|
|
723
887
|
resolvedModel,
|
|
@@ -762,7 +926,7 @@ function buildSubscriptionRequestSummary(anthropicBody) {
|
|
|
762
926
|
estimatedInputTokens: Math.ceil(totalChars / 4),
|
|
763
927
|
// Single source of truth (shared with the dispatcher builder) so both
|
|
764
928
|
// ingress paths yield identical `matchText` for the same body.
|
|
765
|
-
matchText:
|
|
929
|
+
matchText: _chunkEJLH6NFTcjs.collectMatchText.call(void 0, anthropicBody)
|
|
766
930
|
};
|
|
767
931
|
}
|
|
768
932
|
function collectText(value) {
|
|
@@ -792,13 +956,15 @@ async function runPipeline(anthropicBody, plan, reportSelection) {
|
|
|
792
956
|
model: resolvedModel,
|
|
793
957
|
sessionKey: plan.sessionKey,
|
|
794
958
|
preferredAccountId: plan.preferredAccountId,
|
|
959
|
+
preferredAccountGroup: plan.preferredAccountGroup,
|
|
960
|
+
boundAccountFallbackPolicy: plan.boundAccountFallbackPolicy,
|
|
795
961
|
reportSelection: (accountId, isActive) => {
|
|
796
962
|
proxyAccountId = accountId;
|
|
797
|
-
_optionalChain([reportSelection, 'optionalCall',
|
|
963
|
+
_optionalChain([reportSelection, 'optionalCall', _15 => _15(accountId, isActive)]);
|
|
798
964
|
}
|
|
799
965
|
});
|
|
800
966
|
let rawStatus = null;
|
|
801
|
-
const { response } = await
|
|
967
|
+
const { response } = await _chunkMUHWHQVMcjs.executeProviderCall.call(void 0, {
|
|
802
968
|
executor,
|
|
803
969
|
request: anthropicBody,
|
|
804
970
|
provider: transformerProvider,
|
|
@@ -816,7 +982,7 @@ async function runPipeline(anthropicBody, plan, reportSelection) {
|
|
|
816
982
|
},
|
|
817
983
|
fetchFn: (url, headers, body) => {
|
|
818
984
|
console.info(`[ProviderProxy:anthropic] -> ${url} model=${resolvedModel} stream=${isStream}`);
|
|
819
|
-
return
|
|
985
|
+
return _chunkKCVJWJSTcjs.fetchUpstream.call(void 0,
|
|
820
986
|
url,
|
|
821
987
|
{ method: "POST", headers, body: JSON.stringify(body) },
|
|
822
988
|
{ providerId: proxyProviderId(plan), accountId: proxyAccountId }
|
|
@@ -838,10 +1004,12 @@ async function runSubscriptionSameFormatFetch(rawBody, plan, reportSelection, op
|
|
|
838
1004
|
model: plan.resolvedModel,
|
|
839
1005
|
sessionKey: plan.sessionKey,
|
|
840
1006
|
preferredAccountId: plan.preferredAccountId,
|
|
1007
|
+
preferredAccountGroup: plan.preferredAccountGroup,
|
|
1008
|
+
boundAccountFallbackPolicy: plan.boundAccountFallbackPolicy,
|
|
841
1009
|
reportSelection: (accountId, isActive, remapped) => {
|
|
842
1010
|
proxyAccountId = accountId;
|
|
843
1011
|
remappedModel = remapped;
|
|
844
|
-
_optionalChain([reportSelection, 'optionalCall',
|
|
1012
|
+
_optionalChain([reportSelection, 'optionalCall', _16 => _16(accountId, isActive, remapped)]);
|
|
845
1013
|
}
|
|
846
1014
|
});
|
|
847
1015
|
if (plan.isSubscription && plan.transformerProvider.name === "claude") {
|
|
@@ -859,7 +1027,7 @@ async function runSubscriptionSameFormatFetch(rawBody, plan, reportSelection, op
|
|
|
859
1027
|
console.info(
|
|
860
1028
|
`[ProviderProxy:anthropic] (subscription same-format) -> ${plan.upstreamUrl} model=${outboundModel} stream=${plan.isStream}`
|
|
861
1029
|
);
|
|
862
|
-
const response = await
|
|
1030
|
+
const response = await _chunkKCVJWJSTcjs.fetchUpstream.call(void 0,
|
|
863
1031
|
plan.upstreamUrl,
|
|
864
1032
|
{ method: "POST", headers, body: outboundBody },
|
|
865
1033
|
{ providerId: proxyProviderId(plan), accountId: proxyAccountId }
|
|
@@ -875,7 +1043,7 @@ function rewriteBodyModel(rawBody, model) {
|
|
|
875
1043
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return rawBody;
|
|
876
1044
|
parsed.model = model;
|
|
877
1045
|
return JSON.stringify(parsed);
|
|
878
|
-
} catch (
|
|
1046
|
+
} catch (e11) {
|
|
879
1047
|
return rawBody;
|
|
880
1048
|
}
|
|
881
1049
|
}
|
|
@@ -888,7 +1056,7 @@ async function runSubscriptionAttemptWith401Retry(anthropicBody, relayBody, plan
|
|
|
888
1056
|
const first = await runOnce();
|
|
889
1057
|
let result = first;
|
|
890
1058
|
if (first.rawStatus === 401) {
|
|
891
|
-
const refreshed = await _optionalChain([plan, 'access',
|
|
1059
|
+
const refreshed = await _optionalChain([plan, 'access', _17 => _17.auth, 'access', _18 => _18.onUnauthorized, 'optionalCall', _19 => _19(plan.sessionKey)]);
|
|
892
1060
|
if (refreshed) {
|
|
893
1061
|
console.info("[ProviderProxy:anthropic] 401 \u2192 token refreshed; retrying once");
|
|
894
1062
|
result = await runOnce();
|
|
@@ -903,7 +1071,7 @@ async function readBoundedBody(response, max = 2048) {
|
|
|
903
1071
|
try {
|
|
904
1072
|
const text = await response.clone().text();
|
|
905
1073
|
return text.slice(0, max);
|
|
906
|
-
} catch (
|
|
1074
|
+
} catch (e12) {
|
|
907
1075
|
return void 0;
|
|
908
1076
|
}
|
|
909
1077
|
}
|
|
@@ -911,9 +1079,9 @@ async function markSubscriptionHealth(plan, selectedAccountId, result) {
|
|
|
911
1079
|
if (!plan.isSubscription || selectedAccountId === void 0) return;
|
|
912
1080
|
const providerId = plan.transformerProvider.name;
|
|
913
1081
|
const status = result.rawStatus;
|
|
914
|
-
const { resetHeaderSeconds, retryAfterSeconds } =
|
|
1082
|
+
const { resetHeaderSeconds, retryAfterSeconds } = _chunkYK57NMIFcjs.resolveResetSeconds.call(void 0, providerId, result.response.headers);
|
|
915
1083
|
const bodyText = status === 403 ? await readBoundedBody(result.response) : void 0;
|
|
916
|
-
|
|
1084
|
+
_chunkYK57NMIFcjs.getSharedAccountHealth.call(void 0, ).recordUpstreamOutcome(providerId, selectedAccountId, {
|
|
917
1085
|
status,
|
|
918
1086
|
resetHeaderSeconds,
|
|
919
1087
|
retryAfterSeconds,
|
|
@@ -931,7 +1099,7 @@ function breakerOutcome(rawStatus) {
|
|
|
931
1099
|
function recordBreakerOutcome(profile, modelId, rawStatus) {
|
|
932
1100
|
const outcome = breakerOutcome(rawStatus);
|
|
933
1101
|
if (outcome === "neutral") return;
|
|
934
|
-
_optionalChain([profile, 'optionalAccess',
|
|
1102
|
+
_optionalChain([profile, 'optionalAccess', _20 => _20.recordModelOutcome, 'optionalCall', _21 => _21(modelId, outcome === "success")]);
|
|
935
1103
|
}
|
|
936
1104
|
async function runSubscriptionAttemptOutcome(anthropicBody, relayBody, plan, options = {}) {
|
|
937
1105
|
try {
|
|
@@ -950,7 +1118,7 @@ function settleOutcome(outcome) {
|
|
|
950
1118
|
async function runPipelineWithSubscriptionRetry(anthropicBody, rawBody, initialPlan, route, deps, options = {}) {
|
|
951
1119
|
const profile = route.subscriptionProfile;
|
|
952
1120
|
const scenario = initialPlan.scenario;
|
|
953
|
-
if (!_optionalChain([profile, 'optionalAccess',
|
|
1121
|
+
if (!_optionalChain([profile, 'optionalAccess', _22 => _22.nextFallback]) || scenario === void 0) {
|
|
954
1122
|
const loneOutcome = await runSubscriptionAttemptOutcome(anthropicBody, rawBody, initialPlan, options);
|
|
955
1123
|
recordBreakerOutcome(profile, initialPlan.resolvedModel, outcomeStatus(loneOutcome));
|
|
956
1124
|
return settleOutcome(loneOutcome);
|
|
@@ -1014,7 +1182,7 @@ async function handleAnthropicMessagesByo(res, rawBody, route, deps, options = {
|
|
|
1014
1182
|
let anthropicBody;
|
|
1015
1183
|
try {
|
|
1016
1184
|
anthropicBody = JSON.parse(rawBody);
|
|
1017
|
-
} catch (
|
|
1185
|
+
} catch (e13) {
|
|
1018
1186
|
writeError(res, 400, "Invalid JSON in request body");
|
|
1019
1187
|
return;
|
|
1020
1188
|
}
|
|
@@ -1026,21 +1194,61 @@ async function handleAnthropicMessagesByo(res, rawBody, route, deps, options = {
|
|
|
1026
1194
|
if (!plan) return;
|
|
1027
1195
|
anthropicBody.model = plan.resolvedModel;
|
|
1028
1196
|
const providerResponse = route.authMode === "subscription" ? await runPipelineWithSubscriptionRetry(anthropicBody, rawBody, plan, route, deps, options) : await runPipelineWithPoolReporting(anthropicBody, rawBody, plan, options);
|
|
1029
|
-
const
|
|
1197
|
+
const upstreamResponse = providerResponse.response;
|
|
1198
|
+
const upstreamSse = (_nullishCoalesce(upstreamResponse.headers.get("content-type"), () => ( ""))).includes(
|
|
1199
|
+
"text/event-stream"
|
|
1200
|
+
);
|
|
1201
|
+
const usageAttribution = {
|
|
1202
|
+
sessionId: route.sessionId,
|
|
1203
|
+
providerId: _nullishCoalesce(route.providerId, () => ( "anthropic")),
|
|
1204
|
+
model: plan.resolvedModel,
|
|
1205
|
+
apiKeyId: _nullishCoalesce(route.apiKeyId, () => ( null)),
|
|
1206
|
+
// request-audit-log: correlate this request's tokens/cost to its audit record.
|
|
1207
|
+
auditResponse: res
|
|
1208
|
+
};
|
|
1209
|
+
const usageRecorder = deps.usageRecorder;
|
|
1210
|
+
let anthropicInputUsage;
|
|
1211
|
+
const usageTap = usageRecorder ? {
|
|
1212
|
+
extractUsage(event) {
|
|
1213
|
+
if (event["type"] === "message_start") {
|
|
1214
|
+
const msg = event["message"];
|
|
1215
|
+
const u = _optionalChain([msg, 'optionalAccess', _23 => _23["usage"]]);
|
|
1216
|
+
if (u) anthropicInputUsage = u;
|
|
1217
|
+
return null;
|
|
1218
|
+
}
|
|
1219
|
+
if (event["type"] === "message_delta") {
|
|
1220
|
+
const outputUsage = event["usage"];
|
|
1221
|
+
if (!outputUsage) return null;
|
|
1222
|
+
return { ...anthropicInputUsage, ...outputUsage };
|
|
1223
|
+
}
|
|
1224
|
+
return null;
|
|
1225
|
+
},
|
|
1226
|
+
onUsage(rawUsage) {
|
|
1227
|
+
recordAnthropicStreamUsage(usageRecorder, rawUsage, usageAttribution);
|
|
1228
|
+
}
|
|
1229
|
+
} : void 0;
|
|
1230
|
+
let bodyText;
|
|
1231
|
+
if (!isStream && upstreamSse) {
|
|
1232
|
+
bodyText = await aggregateAnthropicSseToJsonBody(upstreamResponse, route.requestedModel);
|
|
1233
|
+
res.writeHead(
|
|
1234
|
+
upstreamResponse.status && upstreamResponse.status >= 100 ? upstreamResponse.status : 200,
|
|
1235
|
+
{ "Content-Type": "application/json" }
|
|
1236
|
+
);
|
|
1237
|
+
res.end(bodyText);
|
|
1238
|
+
} else {
|
|
1239
|
+
bodyText = await relayResponse(res, upstreamResponse, isStream, route.requestedModel, usageTap);
|
|
1240
|
+
}
|
|
1030
1241
|
if (bodyText && deps.usageRecorder) {
|
|
1031
|
-
recordAnthropicNonStreamUsage(deps.usageRecorder, bodyText,
|
|
1032
|
-
sessionId: route.sessionId,
|
|
1033
|
-
providerId: _nullishCoalesce(route.providerId, () => ( "anthropic")),
|
|
1034
|
-
model: plan.resolvedModel,
|
|
1035
|
-
apiKeyId: _nullishCoalesce(route.apiKeyId, () => ( null)),
|
|
1036
|
-
// request-audit-log: correlate this request's tokens/cost to its audit record.
|
|
1037
|
-
auditResponse: res
|
|
1038
|
-
});
|
|
1242
|
+
recordAnthropicNonStreamUsage(deps.usageRecorder, bodyText, usageAttribution);
|
|
1039
1243
|
}
|
|
1040
1244
|
} catch (err) {
|
|
1245
|
+
if (_chunk25GXJCEZcjs.isBoundAccountSelectionError.call(void 0, err)) {
|
|
1246
|
+
writeBoundAccountError(res, err);
|
|
1247
|
+
return;
|
|
1248
|
+
}
|
|
1041
1249
|
const errMsg = _chunkSVNDB62Dcjs.serializeError.call(void 0, err);
|
|
1042
1250
|
console.error("[ProviderProxy:anthropic] Pipeline error:", errMsg);
|
|
1043
|
-
writeError(res, 502, errMsg);
|
|
1251
|
+
writeError(res, _chunk6QQG7YG3cjs.isAccountAllowanceExhaustedError.call(void 0, err) ? 429 : 502, errMsg);
|
|
1044
1252
|
}
|
|
1045
1253
|
}
|
|
1046
1254
|
async function buildByoPlan(res, route, deps, resolvedModel, isStream) {
|
|
@@ -1054,7 +1262,14 @@ async function buildByoPlan(res, route, deps, resolvedModel, isStream) {
|
|
|
1054
1262
|
writeError(res, 502, `Provider not found: ${providerId}`);
|
|
1055
1263
|
return null;
|
|
1056
1264
|
}
|
|
1057
|
-
const apiKey = await resolvePoolBoundKey(
|
|
1265
|
+
const apiKey = await resolvePoolBoundKey(
|
|
1266
|
+
deps,
|
|
1267
|
+
providerId,
|
|
1268
|
+
provider,
|
|
1269
|
+
route.sessionId,
|
|
1270
|
+
route.preferredKeyId,
|
|
1271
|
+
route.boundKeyFallbackPolicy
|
|
1272
|
+
);
|
|
1058
1273
|
if (!apiKey) {
|
|
1059
1274
|
writeError(res, 502, "API key not configured");
|
|
1060
1275
|
return null;
|
|
@@ -1087,7 +1302,7 @@ async function buildByoPlan(res, route, deps, resolvedModel, isStream) {
|
|
|
1087
1302
|
isSubscription: false,
|
|
1088
1303
|
provider,
|
|
1089
1304
|
apiKey,
|
|
1090
|
-
extendedContextEnabled: _nullishCoalesce(_optionalChain([route, 'access',
|
|
1305
|
+
extendedContextEnabled: _nullishCoalesce(_optionalChain([route, 'access', _24 => _24.anthropicSdkHints, 'optionalAccess', _25 => _25.extendedContext, 'optionalAccess', _26 => _26.enabled]), () => ( false))
|
|
1091
1306
|
};
|
|
1092
1307
|
}
|
|
1093
1308
|
async function runSameFormatFetch(bodyToSend, plan, options, keyOverride) {
|
|
@@ -1097,7 +1312,7 @@ async function runSameFormatFetch(bodyToSend, plan, options, keyOverride) {
|
|
|
1097
1312
|
}
|
|
1098
1313
|
const effectiveKey = _nullishCoalesce(_nullishCoalesce(keyOverride, () => ( apiKey)), () => ( ""));
|
|
1099
1314
|
const headers = _chunkQ27JY5RGcjs.getProviderHeaders.call(void 0, provider, effectiveKey);
|
|
1100
|
-
const callerBeta = _optionalChain([options, 'access',
|
|
1315
|
+
const callerBeta = _optionalChain([options, 'access', _27 => _27.callerAnthropicBeta, 'optionalAccess', _28 => _28.trim, 'call', _29 => _29()]);
|
|
1101
1316
|
if (callerBeta) {
|
|
1102
1317
|
const existing = _nullishCoalesce(headers["anthropic-beta"], () => ( headers["Anthropic-Beta"]));
|
|
1103
1318
|
const parts = new Set(
|
|
@@ -1111,7 +1326,7 @@ async function runSameFormatFetch(bodyToSend, plan, options, keyOverride) {
|
|
|
1111
1326
|
_chunkGBHYAGX3cjs.injectExtendedContextBeta.call(void 0, headers, resolvedModel, _nullishCoalesce(extendedContextEnabled, () => ( false)));
|
|
1112
1327
|
const url = _chunkA2YMUCBTcjs.buildProviderApiUrl.call(void 0, provider, { model: resolvedModel, stream: isStream });
|
|
1113
1328
|
console.info(`[ProviderProxy:anthropic] (same-format) -> ${url} model=${resolvedModel} stream=${isStream}`);
|
|
1114
|
-
const response = await
|
|
1329
|
+
const response = await _chunkKCVJWJSTcjs.fetchUpstream.call(void 0,
|
|
1115
1330
|
url,
|
|
1116
1331
|
{ method: "POST", headers, body: bodyToSend },
|
|
1117
1332
|
{ providerId: "byo" }
|
|
@@ -1123,7 +1338,7 @@ function resolveSameFormatBody(anthropicBody, rawBody, plan) {
|
|
|
1123
1338
|
try {
|
|
1124
1339
|
const m = JSON.parse(rawBody).model;
|
|
1125
1340
|
originalModel = typeof m === "string" ? m : void 0;
|
|
1126
|
-
} catch (
|
|
1341
|
+
} catch (e14) {
|
|
1127
1342
|
originalModel = void 0;
|
|
1128
1343
|
}
|
|
1129
1344
|
return plan.resolvedModel !== originalModel ? JSON.stringify(anthropicBody) : rawBody;
|
|
@@ -1132,8 +1347,8 @@ async function runPipelineWithPoolReporting(anthropicBody, rawBody, plan, option
|
|
|
1132
1347
|
const sameFormatBody = plan.sameFormat ? resolveSameFormatBody(anthropicBody, rawBody, plan) : rawBody;
|
|
1133
1348
|
const runOnce = (keyOverride) => plan.sameFormat ? runSameFormatFetch(sameFormatBody, plan, options, keyOverride) : runPipeline(anthropicBody, plan);
|
|
1134
1349
|
const first = await runOnce();
|
|
1135
|
-
const outcome = await _optionalChain([plan, 'access',
|
|
1136
|
-
if (_optionalChain([outcome, 'optionalAccess',
|
|
1350
|
+
const outcome = await _optionalChain([plan, 'access', _30 => _30.auth, 'access', _31 => _31.onResult, 'optionalCall', _32 => _32(first.rawStatus)]);
|
|
1351
|
+
if (_optionalChain([outcome, 'optionalAccess', _33 => _33.rebound])) {
|
|
1137
1352
|
console.info(
|
|
1138
1353
|
"[ProviderProxy:anthropic] pool re-bound key after status",
|
|
1139
1354
|
first.rawStatus,
|
|
@@ -1167,11 +1382,31 @@ async function handleAnthropicMessagesRequest(req, res, route, deps) {
|
|
|
1167
1382
|
writeError(res, 502, "Anthropic route is missing a providerId");
|
|
1168
1383
|
return;
|
|
1169
1384
|
}
|
|
1385
|
+
let delegatedApiKey = hints.apiKey;
|
|
1386
|
+
if (route.authMode === "byo" && route.providerId) {
|
|
1387
|
+
const provider = await deps.llmConfig.getProvider(route.providerId);
|
|
1388
|
+
if (!provider) {
|
|
1389
|
+
writeError(res, 502, `Provider not found: ${route.providerId}`);
|
|
1390
|
+
return;
|
|
1391
|
+
}
|
|
1392
|
+
delegatedApiKey = await resolvePoolBoundKey(
|
|
1393
|
+
deps,
|
|
1394
|
+
route.providerId,
|
|
1395
|
+
provider,
|
|
1396
|
+
route.sessionId,
|
|
1397
|
+
route.preferredKeyId,
|
|
1398
|
+
route.boundKeyFallbackPolicy
|
|
1399
|
+
);
|
|
1400
|
+
if (!delegatedApiKey) {
|
|
1401
|
+
writeError(res, 502, "API key not configured");
|
|
1402
|
+
return;
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1170
1405
|
const handler = handlerFactory({
|
|
1171
1406
|
llmConfig: deps.llmConfig,
|
|
1172
1407
|
providerId: _nullishCoalesce(route.providerId, () => ( "")),
|
|
1173
1408
|
model: route.model,
|
|
1174
|
-
apiKey:
|
|
1409
|
+
apiKey: delegatedApiKey,
|
|
1175
1410
|
backgroundTaskModel: route.backgroundTaskModel,
|
|
1176
1411
|
isOfficialProvider: hints.isOfficialProvider,
|
|
1177
1412
|
thinkingLevel: hints.thinkingLevel,
|
|
@@ -1180,6 +1415,11 @@ async function handleAnthropicMessagesRequest(req, res, route, deps) {
|
|
|
1180
1415
|
passThroughAuthToken: _nullishCoalesce(hints.passThroughAuthToken, () => ( null)),
|
|
1181
1416
|
resolvePassThroughAuthToken: _nullishCoalesce(hints.resolvePassThroughAuthToken, () => ( null)),
|
|
1182
1417
|
subscriptionProfile: _nullishCoalesce(hints.subscriptionProfile, () => ( null)),
|
|
1418
|
+
preferredAccountId: hints.preferredAccountId,
|
|
1419
|
+
preferredAccountGroup: hints.preferredAccountGroup,
|
|
1420
|
+
boundAccountFallbackPolicy: hints.boundAccountFallbackPolicy,
|
|
1421
|
+
preferredKeyId: route.preferredKeyId,
|
|
1422
|
+
boundKeyFallbackPolicy: route.boundKeyFallbackPolicy,
|
|
1183
1423
|
maxConcurrency: hints.maxConcurrency,
|
|
1184
1424
|
webSearchService: _nullishCoalesce(hints.webSearchService, () => ( null)),
|
|
1185
1425
|
onRetry: hints.onRetry,
|
|
@@ -1206,24 +1446,37 @@ function readGeminiUsage(usage) {
|
|
|
1206
1446
|
reasoningTokens
|
|
1207
1447
|
};
|
|
1208
1448
|
}
|
|
1449
|
+
function emitGeminiUsageRecord(recorder, rawUsageMetadata, attribution) {
|
|
1450
|
+
const tapped = readGeminiUsage(rawUsageMetadata);
|
|
1451
|
+
if (!tapped) return;
|
|
1452
|
+
recorder.record({
|
|
1453
|
+
messageId: null,
|
|
1454
|
+
parentMessageId: null,
|
|
1455
|
+
sessionId: attribution.sessionId,
|
|
1456
|
+
providerId: attribution.providerId,
|
|
1457
|
+
model: attribution.model,
|
|
1458
|
+
apiKeyId: attribution.apiKeyId,
|
|
1459
|
+
auditResponse: attribution.auditResponse,
|
|
1460
|
+
engineOrigin: "codex-ingress",
|
|
1461
|
+
usage: tapped,
|
|
1462
|
+
rawUsage: rawUsageMetadata
|
|
1463
|
+
});
|
|
1464
|
+
}
|
|
1209
1465
|
function recordGeminiNonStreamUsage(recorder, bodyText, attribution) {
|
|
1210
1466
|
try {
|
|
1211
1467
|
const parsed = JSON.parse(bodyText);
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
rawUsage: parsed.usageMetadata
|
|
1225
|
-
});
|
|
1226
|
-
} catch (e11) {
|
|
1468
|
+
emitGeminiUsageRecord(
|
|
1469
|
+
recorder,
|
|
1470
|
+
parsed.usageMetadata,
|
|
1471
|
+
attribution
|
|
1472
|
+
);
|
|
1473
|
+
} catch (e15) {
|
|
1474
|
+
}
|
|
1475
|
+
}
|
|
1476
|
+
function recordGeminiStreamUsage(recorder, rawUsageMetadata, attribution) {
|
|
1477
|
+
try {
|
|
1478
|
+
emitGeminiUsageRecord(recorder, rawUsageMetadata, attribution);
|
|
1479
|
+
} catch (e16) {
|
|
1227
1480
|
}
|
|
1228
1481
|
}
|
|
1229
1482
|
|
|
@@ -1232,14 +1485,14 @@ var GENERATE_CONTENT_ACTION = ":generateContent";
|
|
|
1232
1485
|
var STREAM_GENERATE_CONTENT_ACTION = ":streamGenerateContent";
|
|
1233
1486
|
function isGeminiGenerateContentRequest(method, url) {
|
|
1234
1487
|
if (method !== "POST" || !url) return false;
|
|
1235
|
-
const path = _nullishCoalesce(_optionalChain([url, 'access',
|
|
1488
|
+
const path = _nullishCoalesce(_optionalChain([url, 'access', _34 => _34.split, 'call', _35 => _35("?"), 'access', _36 => _36[0], 'optionalAccess', _37 => _37.replace, 'call', _38 => _38(/\/+$/, "")]), () => ( ""));
|
|
1236
1489
|
const lastSegment = _nullishCoalesce(path.split("/").pop(), () => ( ""));
|
|
1237
1490
|
return lastSegment.includes(STREAM_GENERATE_CONTENT_ACTION) || lastSegment.includes(GENERATE_CONTENT_ACTION);
|
|
1238
1491
|
}
|
|
1239
1492
|
function isGeminiStreamRequest(url) {
|
|
1240
1493
|
if (!url) return false;
|
|
1241
1494
|
const [path, query = ""] = url.split("?");
|
|
1242
|
-
const lastSegment = _nullishCoalesce((_nullishCoalesce(_optionalChain([path, 'optionalAccess',
|
|
1495
|
+
const lastSegment = _nullishCoalesce((_nullishCoalesce(_optionalChain([path, 'optionalAccess', _39 => _39.replace, 'call', _40 => _40(/\/+$/, "")]), () => ( ""))).split("/").pop(), () => ( ""));
|
|
1243
1496
|
if (lastSegment.includes(STREAM_GENERATE_CONTENT_ACTION)) return true;
|
|
1244
1497
|
return /(^|&)alt=sse(&|$)/.test(query);
|
|
1245
1498
|
}
|
|
@@ -1247,7 +1500,7 @@ async function handleGeminiGenerateContentRequest(res, rawBody, url, route, deps
|
|
|
1247
1500
|
let geminiBody;
|
|
1248
1501
|
try {
|
|
1249
1502
|
geminiBody = JSON.parse(rawBody);
|
|
1250
|
-
} catch (
|
|
1503
|
+
} catch (e17) {
|
|
1251
1504
|
writeError(res, 400, "Invalid JSON in request body");
|
|
1252
1505
|
return;
|
|
1253
1506
|
}
|
|
@@ -1263,16 +1516,32 @@ async function handleGeminiGenerateContentRequest(res, rawBody, url, route, deps
|
|
|
1263
1516
|
const plan = await buildByoPlan2(res, route, deps, resolvedModel, isStream);
|
|
1264
1517
|
if (!plan) return;
|
|
1265
1518
|
const providerResponse = await runPipelineWithPoolReporting2(geminiBody, plan);
|
|
1266
|
-
const
|
|
1519
|
+
const usageAttribution = {
|
|
1520
|
+
sessionId: route.sessionId,
|
|
1521
|
+
providerId: _nullishCoalesce(route.providerId, () => ( "gemini")),
|
|
1522
|
+
model: resolvedModel,
|
|
1523
|
+
apiKeyId: _nullishCoalesce(route.apiKeyId, () => ( null)),
|
|
1524
|
+
// request-audit-log: correlate this request's tokens/cost to its audit record.
|
|
1525
|
+
auditResponse: res
|
|
1526
|
+
};
|
|
1527
|
+
const usageRecorder = deps.usageRecorder;
|
|
1528
|
+
const usageTap = usageRecorder ? {
|
|
1529
|
+
extractUsage(event) {
|
|
1530
|
+
return _nullishCoalesce(event["usageMetadata"], () => ( null));
|
|
1531
|
+
},
|
|
1532
|
+
onUsage(rawUsage) {
|
|
1533
|
+
recordGeminiStreamUsage(usageRecorder, rawUsage, usageAttribution);
|
|
1534
|
+
}
|
|
1535
|
+
} : void 0;
|
|
1536
|
+
const bodyText = await relayResponse(
|
|
1537
|
+
res,
|
|
1538
|
+
providerResponse.response,
|
|
1539
|
+
isStream,
|
|
1540
|
+
void 0,
|
|
1541
|
+
usageTap
|
|
1542
|
+
);
|
|
1267
1543
|
if (bodyText && deps.usageRecorder) {
|
|
1268
|
-
recordGeminiNonStreamUsage(deps.usageRecorder, bodyText,
|
|
1269
|
-
sessionId: route.sessionId,
|
|
1270
|
-
providerId: _nullishCoalesce(route.providerId, () => ( "gemini")),
|
|
1271
|
-
model: resolvedModel,
|
|
1272
|
-
apiKeyId: _nullishCoalesce(route.apiKeyId, () => ( null)),
|
|
1273
|
-
// request-audit-log: correlate this request's tokens/cost to its audit record.
|
|
1274
|
-
auditResponse: res
|
|
1275
|
-
});
|
|
1544
|
+
recordGeminiNonStreamUsage(deps.usageRecorder, bodyText, usageAttribution);
|
|
1276
1545
|
}
|
|
1277
1546
|
} catch (err) {
|
|
1278
1547
|
const errMsg = _chunkSVNDB62Dcjs.serializeError.call(void 0, err);
|
|
@@ -1291,7 +1560,14 @@ async function buildByoPlan2(res, route, deps, resolvedModel, isStream) {
|
|
|
1291
1560
|
writeError(res, 502, `Provider not found: ${providerId}`);
|
|
1292
1561
|
return null;
|
|
1293
1562
|
}
|
|
1294
|
-
const apiKey = await resolvePoolBoundKey(
|
|
1563
|
+
const apiKey = await resolvePoolBoundKey(
|
|
1564
|
+
deps,
|
|
1565
|
+
providerId,
|
|
1566
|
+
provider,
|
|
1567
|
+
route.sessionId,
|
|
1568
|
+
route.preferredKeyId,
|
|
1569
|
+
route.boundKeyFallbackPolicy
|
|
1570
|
+
);
|
|
1295
1571
|
if (!apiKey) {
|
|
1296
1572
|
writeError(res, 502, "API key not configured");
|
|
1297
1573
|
return null;
|
|
@@ -1328,7 +1604,7 @@ async function runPipeline2(geminiBody, plan) {
|
|
|
1328
1604
|
const authHeaders = {};
|
|
1329
1605
|
await auth.applyHeaders(authHeaders, { upstreamUrl, model: resolvedModel });
|
|
1330
1606
|
let rawStatus = null;
|
|
1331
|
-
const { response } = await
|
|
1607
|
+
const { response } = await _chunkMUHWHQVMcjs.executeProviderCall.call(void 0, {
|
|
1332
1608
|
executor,
|
|
1333
1609
|
request: geminiBody,
|
|
1334
1610
|
provider: transformerProvider,
|
|
@@ -1346,7 +1622,7 @@ async function runPipeline2(geminiBody, plan) {
|
|
|
1346
1622
|
},
|
|
1347
1623
|
fetchFn: (url, headers, body) => {
|
|
1348
1624
|
console.log(`[ProviderProxy:gemini] -> ${url} model=${resolvedModel} stream=${isStream}`);
|
|
1349
|
-
return
|
|
1625
|
+
return _chunkKCVJWJSTcjs.fetchUpstream.call(void 0,
|
|
1350
1626
|
url,
|
|
1351
1627
|
{ method: "POST", headers, body: JSON.stringify(body) },
|
|
1352
1628
|
{ providerId: "byo" }
|
|
@@ -1361,8 +1637,8 @@ async function runPipeline2(geminiBody, plan) {
|
|
|
1361
1637
|
}
|
|
1362
1638
|
async function runPipelineWithPoolReporting2(geminiBody, plan) {
|
|
1363
1639
|
const first = await runPipeline2(geminiBody, plan);
|
|
1364
|
-
const outcome = await _optionalChain([plan, 'access',
|
|
1365
|
-
if (_optionalChain([outcome, 'optionalAccess',
|
|
1640
|
+
const outcome = await _optionalChain([plan, 'access', _41 => _41.auth, 'access', _42 => _42.onResult, 'optionalCall', _43 => _43(first.rawStatus)]);
|
|
1641
|
+
if (_optionalChain([outcome, 'optionalAccess', _44 => _44.rebound])) {
|
|
1366
1642
|
console.log(
|
|
1367
1643
|
"[ProviderProxy:gemini] pool re-bound key after status",
|
|
1368
1644
|
first.rawStatus,
|
|
@@ -1391,31 +1667,44 @@ function readChatCompletionsUsage(usage) {
|
|
|
1391
1667
|
reasoningTokens
|
|
1392
1668
|
};
|
|
1393
1669
|
}
|
|
1670
|
+
function emitChatCompletionsUsageRecord(recorder, rawUsage, attribution) {
|
|
1671
|
+
const tapped = readChatCompletionsUsage(rawUsage);
|
|
1672
|
+
if (!tapped) return;
|
|
1673
|
+
recorder.record({
|
|
1674
|
+
messageId: null,
|
|
1675
|
+
parentMessageId: null,
|
|
1676
|
+
sessionId: attribution.sessionId,
|
|
1677
|
+
providerId: attribution.providerId,
|
|
1678
|
+
model: attribution.model,
|
|
1679
|
+
apiKeyId: attribution.apiKeyId,
|
|
1680
|
+
auditResponse: attribution.auditResponse,
|
|
1681
|
+
engineOrigin: "codex-ingress",
|
|
1682
|
+
usage: tapped,
|
|
1683
|
+
rawUsage
|
|
1684
|
+
});
|
|
1685
|
+
}
|
|
1394
1686
|
function recordChatCompletionsNonStreamUsage(recorder, bodyText, attribution) {
|
|
1395
1687
|
try {
|
|
1396
1688
|
const parsed = JSON.parse(bodyText);
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
rawUsage: parsed.usage
|
|
1410
|
-
});
|
|
1411
|
-
} catch (e13) {
|
|
1689
|
+
emitChatCompletionsUsageRecord(
|
|
1690
|
+
recorder,
|
|
1691
|
+
parsed.usage,
|
|
1692
|
+
attribution
|
|
1693
|
+
);
|
|
1694
|
+
} catch (e18) {
|
|
1695
|
+
}
|
|
1696
|
+
}
|
|
1697
|
+
function recordChatCompletionsStreamUsage(recorder, rawUsage, attribution) {
|
|
1698
|
+
try {
|
|
1699
|
+
emitChatCompletionsUsageRecord(recorder, rawUsage, attribution);
|
|
1700
|
+
} catch (e19) {
|
|
1412
1701
|
}
|
|
1413
1702
|
}
|
|
1414
1703
|
|
|
1415
1704
|
// src/provider-proxy/ingress/openaiChatIngress.ts
|
|
1416
1705
|
function isOpenAIChatRequest(method, url) {
|
|
1417
1706
|
if (method !== "POST" || !url) return false;
|
|
1418
|
-
const path = _nullishCoalesce(_optionalChain([url, 'access',
|
|
1707
|
+
const path = _nullishCoalesce(_optionalChain([url, 'access', _45 => _45.split, 'call', _46 => _46("?"), 'access', _47 => _47[0], 'optionalAccess', _48 => _48.replace, 'call', _49 => _49(/\/+$/, "")]), () => ( ""));
|
|
1419
1708
|
return path.endsWith("/chat/completions");
|
|
1420
1709
|
}
|
|
1421
1710
|
var CHAT_BRIDGE_SUBSCRIPTION_PROVIDERS = /* @__PURE__ */ new Set(["claude"]);
|
|
@@ -1424,7 +1713,7 @@ async function handleOpenAIChatRequest(res, rawBody, route, deps) {
|
|
|
1424
1713
|
let chatBody;
|
|
1425
1714
|
try {
|
|
1426
1715
|
chatBody = JSON.parse(rawBody);
|
|
1427
|
-
} catch (
|
|
1716
|
+
} catch (e20) {
|
|
1428
1717
|
writeError(res, 400, "Invalid JSON in request body");
|
|
1429
1718
|
return;
|
|
1430
1719
|
}
|
|
@@ -1435,21 +1724,41 @@ async function handleOpenAIChatRequest(res, rawBody, route, deps) {
|
|
|
1435
1724
|
const plan = route.authMode === "subscription" ? await buildSubscriptionPlan2(res, route, deps, resolvedModel, isStream) : await buildByoPlan3(res, route, deps, resolvedModel, isStream);
|
|
1436
1725
|
if (!plan) return;
|
|
1437
1726
|
const providerResponse = plan.isSubscription ? await runPipelineWithSubscriptionRetry2(chatBody, plan) : await runPipelineWithPoolReporting3(chatBody, plan);
|
|
1438
|
-
const
|
|
1727
|
+
const usageAttribution = {
|
|
1728
|
+
sessionId: route.sessionId,
|
|
1729
|
+
providerId: _nullishCoalesce(route.providerId, () => ( "openai")),
|
|
1730
|
+
model: resolvedModel,
|
|
1731
|
+
apiKeyId: _nullishCoalesce(route.apiKeyId, () => ( null)),
|
|
1732
|
+
// request-audit-log: correlate this request's tokens/cost to its audit record.
|
|
1733
|
+
auditResponse: res
|
|
1734
|
+
};
|
|
1735
|
+
const usageRecorder = deps.usageRecorder;
|
|
1736
|
+
const usageTap = usageRecorder ? {
|
|
1737
|
+
extractUsage(event) {
|
|
1738
|
+
return _nullishCoalesce(event["usage"], () => ( null));
|
|
1739
|
+
},
|
|
1740
|
+
onUsage(rawUsage) {
|
|
1741
|
+
recordChatCompletionsStreamUsage(usageRecorder, rawUsage, usageAttribution);
|
|
1742
|
+
}
|
|
1743
|
+
} : void 0;
|
|
1744
|
+
const bodyText = await relayResponse(
|
|
1745
|
+
res,
|
|
1746
|
+
providerResponse.response,
|
|
1747
|
+
isStream,
|
|
1748
|
+
void 0,
|
|
1749
|
+
usageTap
|
|
1750
|
+
);
|
|
1439
1751
|
if (bodyText && deps.usageRecorder) {
|
|
1440
|
-
recordChatCompletionsNonStreamUsage(deps.usageRecorder, bodyText,
|
|
1441
|
-
sessionId: route.sessionId,
|
|
1442
|
-
providerId: _nullishCoalesce(route.providerId, () => ( "openai")),
|
|
1443
|
-
model: resolvedModel,
|
|
1444
|
-
apiKeyId: _nullishCoalesce(route.apiKeyId, () => ( null)),
|
|
1445
|
-
// request-audit-log: correlate this request's tokens/cost to its audit record.
|
|
1446
|
-
auditResponse: res
|
|
1447
|
-
});
|
|
1752
|
+
recordChatCompletionsNonStreamUsage(deps.usageRecorder, bodyText, usageAttribution);
|
|
1448
1753
|
}
|
|
1449
1754
|
} catch (err) {
|
|
1755
|
+
if (_chunk25GXJCEZcjs.isBoundAccountSelectionError.call(void 0, err)) {
|
|
1756
|
+
writeBoundAccountError(res, err);
|
|
1757
|
+
return;
|
|
1758
|
+
}
|
|
1450
1759
|
const errMsg = _chunkSVNDB62Dcjs.serializeError.call(void 0, err);
|
|
1451
1760
|
console.error("[ProviderProxy:chat] Pipeline error:", errMsg);
|
|
1452
|
-
writeError(res, 502, errMsg);
|
|
1761
|
+
writeError(res, _chunk6QQG7YG3cjs.isAccountAllowanceExhaustedError.call(void 0, err) ? 429 : 502, errMsg);
|
|
1453
1762
|
}
|
|
1454
1763
|
}
|
|
1455
1764
|
async function buildByoPlan3(res, route, deps, resolvedModel, isStream) {
|
|
@@ -1463,7 +1772,14 @@ async function buildByoPlan3(res, route, deps, resolvedModel, isStream) {
|
|
|
1463
1772
|
writeError(res, 502, `Provider not found: ${providerId}`);
|
|
1464
1773
|
return null;
|
|
1465
1774
|
}
|
|
1466
|
-
const apiKey = await resolvePoolBoundKey(
|
|
1775
|
+
const apiKey = await resolvePoolBoundKey(
|
|
1776
|
+
deps,
|
|
1777
|
+
providerId,
|
|
1778
|
+
provider,
|
|
1779
|
+
route.sessionId,
|
|
1780
|
+
route.preferredKeyId,
|
|
1781
|
+
route.boundKeyFallbackPolicy
|
|
1782
|
+
);
|
|
1467
1783
|
if (!apiKey) {
|
|
1468
1784
|
writeError(res, 502, "API key not configured");
|
|
1469
1785
|
return null;
|
|
@@ -1510,12 +1826,12 @@ async function buildSubscriptionPlan2(res, route, deps, resolvedModel, isStream)
|
|
|
1510
1826
|
);
|
|
1511
1827
|
return null;
|
|
1512
1828
|
}
|
|
1513
|
-
const upstreamUrl = _optionalChain([profile, 'access',
|
|
1829
|
+
const upstreamUrl = _optionalChain([profile, 'access', _50 => _50.resolveUpstreamUrl, 'optionalCall', _51 => _51(resolvedModel)]);
|
|
1514
1830
|
if (!upstreamUrl) {
|
|
1515
1831
|
writeError(res, 502, "Subscription profile is missing resolveUpstreamUrl");
|
|
1516
1832
|
return null;
|
|
1517
1833
|
}
|
|
1518
|
-
const auth = _nullishCoalesce(route.auth, () => ( new (0,
|
|
1834
|
+
const auth = _nullishCoalesce(route.auth, () => ( new (0, _chunkYNJNTCSQcjs.SubscriptionAuthSource)(profile)));
|
|
1519
1835
|
const chain = _chunkNYUNU75Acjs.resolveSubscriptionChain.call(void 0,
|
|
1520
1836
|
profile,
|
|
1521
1837
|
deps.llmConfig.getTransformerService(),
|
|
@@ -1529,6 +1845,9 @@ async function buildSubscriptionPlan2(res, route, deps, resolvedModel, isStream)
|
|
|
1529
1845
|
};
|
|
1530
1846
|
return {
|
|
1531
1847
|
auth,
|
|
1848
|
+
preferredAccountId: route.preferredAccountId,
|
|
1849
|
+
preferredAccountGroup: route.preferredAccountGroup,
|
|
1850
|
+
boundAccountFallbackPolicy: route.boundAccountFallbackPolicy,
|
|
1532
1851
|
chain,
|
|
1533
1852
|
transformerProvider,
|
|
1534
1853
|
resolvedModel,
|
|
@@ -1547,12 +1866,15 @@ async function runPipeline3(chatBody, plan) {
|
|
|
1547
1866
|
await auth.applyHeaders(authHeaders, {
|
|
1548
1867
|
upstreamUrl,
|
|
1549
1868
|
model: resolvedModel,
|
|
1869
|
+
preferredAccountId: plan.preferredAccountId,
|
|
1870
|
+
preferredAccountGroup: plan.preferredAccountGroup,
|
|
1871
|
+
boundAccountFallbackPolicy: plan.boundAccountFallbackPolicy,
|
|
1550
1872
|
reportSelection: (accountId) => {
|
|
1551
1873
|
proxyAccountId = accountId;
|
|
1552
1874
|
}
|
|
1553
1875
|
});
|
|
1554
1876
|
let rawStatus = null;
|
|
1555
|
-
const { response } = await
|
|
1877
|
+
const { response } = await _chunkMUHWHQVMcjs.executeProviderCall.call(void 0, {
|
|
1556
1878
|
executor,
|
|
1557
1879
|
request: chatBody,
|
|
1558
1880
|
provider: transformerProvider,
|
|
@@ -1569,7 +1891,7 @@ async function runPipeline3(chatBody, plan) {
|
|
|
1569
1891
|
},
|
|
1570
1892
|
fetchFn: (url, headers, body) => {
|
|
1571
1893
|
console.log(`[ProviderProxy:chat] -> ${url} model=${resolvedModel} stream=${isStream}`);
|
|
1572
|
-
return
|
|
1894
|
+
return _chunkKCVJWJSTcjs.fetchUpstream.call(void 0,
|
|
1573
1895
|
url,
|
|
1574
1896
|
{ method: "POST", headers, body: JSON.stringify(body) },
|
|
1575
1897
|
{ providerId: plan.proxyProviderId, accountId: proxyAccountId }
|
|
@@ -1584,8 +1906,8 @@ async function runPipeline3(chatBody, plan) {
|
|
|
1584
1906
|
}
|
|
1585
1907
|
async function runPipelineWithPoolReporting3(chatBody, plan) {
|
|
1586
1908
|
const first = await runPipeline3(chatBody, plan);
|
|
1587
|
-
const outcome = await _optionalChain([plan, 'access',
|
|
1588
|
-
if (_optionalChain([outcome, 'optionalAccess',
|
|
1909
|
+
const outcome = await _optionalChain([plan, 'access', _52 => _52.auth, 'access', _53 => _53.onResult, 'optionalCall', _54 => _54(first.rawStatus)]);
|
|
1910
|
+
if (_optionalChain([outcome, 'optionalAccess', _55 => _55.rebound])) {
|
|
1589
1911
|
console.log(
|
|
1590
1912
|
"[ProviderProxy:chat] pool re-bound key after status",
|
|
1591
1913
|
first.rawStatus,
|
|
@@ -1598,7 +1920,7 @@ async function runPipelineWithPoolReporting3(chatBody, plan) {
|
|
|
1598
1920
|
async function runPipelineWithSubscriptionRetry2(chatBody, plan) {
|
|
1599
1921
|
const first = await runPipeline3(chatBody, plan);
|
|
1600
1922
|
if (first.rawStatus !== 401) return first;
|
|
1601
|
-
const refreshed = await _optionalChain([plan, 'access',
|
|
1923
|
+
const refreshed = await _optionalChain([plan, 'access', _56 => _56.auth, 'access', _57 => _57.onUnauthorized, 'optionalCall', _58 => _58()]);
|
|
1602
1924
|
if (!refreshed) {
|
|
1603
1925
|
console.warn("[ProviderProxy:chat] 401 not recoverable (onUnauthorized returned false)");
|
|
1604
1926
|
return first;
|
|
@@ -1625,63 +1947,107 @@ function readResponsesUsage(usage) {
|
|
|
1625
1947
|
reasoningTokens
|
|
1626
1948
|
};
|
|
1627
1949
|
}
|
|
1950
|
+
function emitResponsesUsageRecord(recorder, rawUsage, attribution) {
|
|
1951
|
+
const tapped = readResponsesUsage(rawUsage);
|
|
1952
|
+
if (!tapped) return;
|
|
1953
|
+
recorder.record({
|
|
1954
|
+
messageId: null,
|
|
1955
|
+
parentMessageId: null,
|
|
1956
|
+
sessionId: attribution.sessionId,
|
|
1957
|
+
providerId: attribution.providerId,
|
|
1958
|
+
model: attribution.model,
|
|
1959
|
+
apiKeyId: attribution.apiKeyId,
|
|
1960
|
+
auditResponse: attribution.auditResponse,
|
|
1961
|
+
engineOrigin: "codex-ingress",
|
|
1962
|
+
usage: tapped,
|
|
1963
|
+
rawUsage
|
|
1964
|
+
});
|
|
1965
|
+
}
|
|
1628
1966
|
function recordResponsesNonStreamUsage(recorder, bodyText, attribution) {
|
|
1629
1967
|
try {
|
|
1630
1968
|
const parsed = JSON.parse(bodyText);
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
rawUsage: parsed.usage
|
|
1644
|
-
});
|
|
1645
|
-
} catch (e15) {
|
|
1969
|
+
emitResponsesUsageRecord(
|
|
1970
|
+
recorder,
|
|
1971
|
+
parsed.usage,
|
|
1972
|
+
attribution
|
|
1973
|
+
);
|
|
1974
|
+
} catch (e21) {
|
|
1975
|
+
}
|
|
1976
|
+
}
|
|
1977
|
+
function recordResponsesStreamUsage(recorder, rawUsage, attribution) {
|
|
1978
|
+
try {
|
|
1979
|
+
emitResponsesUsageRecord(recorder, rawUsage, attribution);
|
|
1980
|
+
} catch (e22) {
|
|
1646
1981
|
}
|
|
1647
1982
|
}
|
|
1648
1983
|
|
|
1649
1984
|
// src/provider-proxy/ingress/openaiResponsesIngress.ts
|
|
1650
1985
|
function isOpenAIResponsesRequest(method, url) {
|
|
1651
1986
|
if (method !== "POST" || !url) return false;
|
|
1652
|
-
const path = _nullishCoalesce(_optionalChain([url, 'access',
|
|
1987
|
+
const path = _nullishCoalesce(_optionalChain([url, 'access', _59 => _59.split, 'call', _60 => _60("?"), 'access', _61 => _61[0], 'optionalAccess', _62 => _62.replace, 'call', _63 => _63(/\/+$/, "")]), () => ( ""));
|
|
1653
1988
|
return path.endsWith("/responses");
|
|
1654
1989
|
}
|
|
1655
|
-
async function handleOpenAIResponsesRequest(res, rawBody, route, deps) {
|
|
1990
|
+
async function handleOpenAIResponsesRequest(res, rawBody, route, deps, requestHeaders = {}) {
|
|
1656
1991
|
let responsesBody;
|
|
1657
1992
|
try {
|
|
1658
1993
|
responsesBody = JSON.parse(rawBody);
|
|
1659
|
-
} catch (
|
|
1994
|
+
} catch (e23) {
|
|
1660
1995
|
writeError(res, 400, "Invalid JSON in request body");
|
|
1661
1996
|
return;
|
|
1662
1997
|
}
|
|
1663
1998
|
const isStream = responsesBody.stream === true;
|
|
1999
|
+
const derivedSession = _chunkEJLH6NFTcjs.deriveGatewaySessionKey.call(void 0, responsesBody, requestHeaders, {
|
|
2000
|
+
endpoint: "responses",
|
|
2001
|
+
// A verified outbound key is the strongest route-local fallback. Resident
|
|
2002
|
+
// proxy callers without one still get a stable run/session bucket; the
|
|
2003
|
+
// final `anonymous` fallback is handled inside the shared utility.
|
|
2004
|
+
fallbackKey: _nullishCoalesce(_nullishCoalesce(route.apiKeyId, () => ( route.sessionId)), () => ( void 0))
|
|
2005
|
+
});
|
|
2006
|
+
const sessionKey = derivedSession.key;
|
|
1664
2007
|
const resolvedModel = route.model;
|
|
1665
2008
|
responsesBody.model = resolvedModel;
|
|
1666
2009
|
try {
|
|
1667
|
-
const plan = route.authMode === "subscription" ? await buildSubscriptionPlan3(res, route, deps, resolvedModel, isStream) : await buildByoPlan4(res, route, deps, resolvedModel, isStream);
|
|
2010
|
+
const plan = route.authMode === "subscription" ? await buildSubscriptionPlan3(res, route, deps, resolvedModel, isStream, sessionKey) : await buildByoPlan4(res, route, deps, resolvedModel, isStream);
|
|
1668
2011
|
if (!plan) return;
|
|
1669
2012
|
const providerResponse = route.authMode === "subscription" ? await runPipelineWithSubscriptionRetry3(responsesBody, plan) : await runPipelineWithPoolReporting4(responsesBody, plan);
|
|
1670
|
-
const
|
|
2013
|
+
const usageAttribution = {
|
|
2014
|
+
sessionId: route.sessionId,
|
|
2015
|
+
providerId: _nullishCoalesce(route.providerId, () => ( "codex")),
|
|
2016
|
+
model: resolvedModel,
|
|
2017
|
+
apiKeyId: _nullishCoalesce(route.apiKeyId, () => ( null)),
|
|
2018
|
+
// request-audit-log: correlate this request's tokens/cost to its audit record.
|
|
2019
|
+
auditResponse: res
|
|
2020
|
+
};
|
|
2021
|
+
const usageRecorder = deps.usageRecorder;
|
|
2022
|
+
const usageTap = usageRecorder ? {
|
|
2023
|
+
extractUsage(event) {
|
|
2024
|
+
if (event["type"] !== "response.completed") return null;
|
|
2025
|
+
const response = event["response"];
|
|
2026
|
+
const usage = _optionalChain([response, 'optionalAccess', _64 => _64["usage"]]);
|
|
2027
|
+
return _nullishCoalesce(usage, () => ( null));
|
|
2028
|
+
},
|
|
2029
|
+
onUsage(rawUsage) {
|
|
2030
|
+
recordResponsesStreamUsage(usageRecorder, rawUsage, usageAttribution);
|
|
2031
|
+
}
|
|
2032
|
+
} : void 0;
|
|
2033
|
+
const bodyText = await relayResponse(
|
|
2034
|
+
res,
|
|
2035
|
+
providerResponse.response,
|
|
2036
|
+
isStream,
|
|
2037
|
+
route.requestedModel,
|
|
2038
|
+
usageTap
|
|
2039
|
+
);
|
|
1671
2040
|
if (bodyText && deps.usageRecorder) {
|
|
1672
|
-
recordResponsesNonStreamUsage(deps.usageRecorder, bodyText,
|
|
1673
|
-
sessionId: route.sessionId,
|
|
1674
|
-
providerId: _nullishCoalesce(route.providerId, () => ( "codex")),
|
|
1675
|
-
model: resolvedModel,
|
|
1676
|
-
apiKeyId: _nullishCoalesce(route.apiKeyId, () => ( null)),
|
|
1677
|
-
// request-audit-log: correlate this request's tokens/cost to its audit record.
|
|
1678
|
-
auditResponse: res
|
|
1679
|
-
});
|
|
2041
|
+
recordResponsesNonStreamUsage(deps.usageRecorder, bodyText, usageAttribution);
|
|
1680
2042
|
}
|
|
1681
2043
|
} catch (err) {
|
|
2044
|
+
if (_chunk25GXJCEZcjs.isBoundAccountSelectionError.call(void 0, err)) {
|
|
2045
|
+
writeBoundAccountError(res, err);
|
|
2046
|
+
return;
|
|
2047
|
+
}
|
|
1682
2048
|
const errMsg = _chunkSVNDB62Dcjs.serializeError.call(void 0, err);
|
|
1683
2049
|
console.error("[ProviderProxy:responses] Pipeline error:", errMsg);
|
|
1684
|
-
writeError(res, 502, errMsg);
|
|
2050
|
+
writeError(res, _chunk6QQG7YG3cjs.isAccountAllowanceExhaustedError.call(void 0, err) ? 429 : 502, errMsg);
|
|
1685
2051
|
}
|
|
1686
2052
|
}
|
|
1687
2053
|
async function buildByoPlan4(res, route, deps, resolvedModel, isStream) {
|
|
@@ -1695,7 +2061,14 @@ async function buildByoPlan4(res, route, deps, resolvedModel, isStream) {
|
|
|
1695
2061
|
writeError(res, 502, `Provider not found: ${providerId}`);
|
|
1696
2062
|
return null;
|
|
1697
2063
|
}
|
|
1698
|
-
const apiKey = await resolvePoolBoundKey(
|
|
2064
|
+
const apiKey = await resolvePoolBoundKey(
|
|
2065
|
+
deps,
|
|
2066
|
+
providerId,
|
|
2067
|
+
provider,
|
|
2068
|
+
route.sessionId,
|
|
2069
|
+
route.preferredKeyId,
|
|
2070
|
+
route.boundKeyFallbackPolicy
|
|
2071
|
+
);
|
|
1699
2072
|
if (!apiKey) {
|
|
1700
2073
|
writeError(res, 502, "API key not configured");
|
|
1701
2074
|
return null;
|
|
@@ -1726,18 +2099,18 @@ async function buildByoPlan4(res, route, deps, resolvedModel, isStream) {
|
|
|
1726
2099
|
proxyProviderId: "byo"
|
|
1727
2100
|
};
|
|
1728
2101
|
}
|
|
1729
|
-
async function buildSubscriptionPlan3(res, route, deps, resolvedModel, isStream) {
|
|
2102
|
+
async function buildSubscriptionPlan3(res, route, deps, resolvedModel, isStream, sessionKey) {
|
|
1730
2103
|
const profile = route.subscriptionProfile;
|
|
1731
2104
|
if (!profile) {
|
|
1732
2105
|
writeError(res, 502, "Subscription mode requires a codex subscription profile");
|
|
1733
2106
|
return null;
|
|
1734
2107
|
}
|
|
1735
|
-
const upstreamUrl = _optionalChain([profile, 'access',
|
|
2108
|
+
const upstreamUrl = _optionalChain([profile, 'access', _65 => _65.resolveUpstreamUrl, 'optionalCall', _66 => _66(resolvedModel)]);
|
|
1736
2109
|
if (!upstreamUrl) {
|
|
1737
2110
|
writeError(res, 502, "Subscription profile is missing resolveUpstreamUrl");
|
|
1738
2111
|
return null;
|
|
1739
2112
|
}
|
|
1740
|
-
const auth = _nullishCoalesce(route.auth, () => ( new (0,
|
|
2113
|
+
const auth = _nullishCoalesce(route.auth, () => ( new (0, _chunkYNJNTCSQcjs.SubscriptionAuthSource)(profile)));
|
|
1741
2114
|
const chain = _chunkNYUNU75Acjs.resolveSubscriptionChain.call(void 0,
|
|
1742
2115
|
profile,
|
|
1743
2116
|
deps.llmConfig.getTransformerService(),
|
|
@@ -1751,15 +2124,27 @@ async function buildSubscriptionPlan3(res, route, deps, resolvedModel, isStream)
|
|
|
1751
2124
|
};
|
|
1752
2125
|
if (profile.authStrategy.providerId === "gemini") {
|
|
1753
2126
|
try {
|
|
1754
|
-
transformerProvider.geminiProject = await resolveGeminiCodeAssistProject(profile
|
|
2127
|
+
transformerProvider.geminiProject = await resolveGeminiCodeAssistProject(profile, {
|
|
2128
|
+
sessionKey,
|
|
2129
|
+
preferredAccountId: route.preferredAccountId,
|
|
2130
|
+
preferredAccountGroup: route.preferredAccountGroup,
|
|
2131
|
+
boundAccountFallbackPolicy: route.boundAccountFallbackPolicy
|
|
2132
|
+
});
|
|
1755
2133
|
} catch (err) {
|
|
2134
|
+
if (_chunk25GXJCEZcjs.isBoundAccountSelectionError.call(void 0, err)) {
|
|
2135
|
+
writeBoundAccountError(res, err);
|
|
2136
|
+
return null;
|
|
2137
|
+
}
|
|
1756
2138
|
writeError(res, 502, _chunkSVNDB62Dcjs.serializeError.call(void 0, err));
|
|
1757
2139
|
return null;
|
|
1758
2140
|
}
|
|
1759
2141
|
}
|
|
1760
2142
|
return {
|
|
1761
2143
|
auth,
|
|
2144
|
+
sessionKey,
|
|
1762
2145
|
preferredAccountId: route.preferredAccountId,
|
|
2146
|
+
preferredAccountGroup: route.preferredAccountGroup,
|
|
2147
|
+
boundAccountFallbackPolicy: route.boundAccountFallbackPolicy,
|
|
1763
2148
|
chain,
|
|
1764
2149
|
transformerProvider,
|
|
1765
2150
|
resolvedModel,
|
|
@@ -1772,9 +2157,9 @@ async function buildSubscriptionPlan3(res, route, deps, resolvedModel, isStream)
|
|
|
1772
2157
|
proxyProviderId: profile.authStrategy.providerId
|
|
1773
2158
|
};
|
|
1774
2159
|
}
|
|
1775
|
-
async function resolveGeminiCodeAssistProject(profile) {
|
|
2160
|
+
async function resolveGeminiCodeAssistProject(profile, hints) {
|
|
1776
2161
|
const probe = {};
|
|
1777
|
-
await profile.authStrategy.applyHeaders(probe);
|
|
2162
|
+
await profile.authStrategy.applyHeaders(probe, hints);
|
|
1778
2163
|
const bearer = _nullishCoalesce(_nullishCoalesce(probe.Authorization, () => ( probe.authorization)), () => ( ""));
|
|
1779
2164
|
const accessToken = bearer.replace(/^Bearer\s+/i, "").trim();
|
|
1780
2165
|
if (!accessToken) return void 0;
|
|
@@ -1785,19 +2170,22 @@ async function resolveGeminiCodeAssistProject(profile) {
|
|
|
1785
2170
|
async function runPipeline4(responsesBody, plan) {
|
|
1786
2171
|
const executor = getSharedExecutor();
|
|
1787
2172
|
const endpointTransformer = getResponsesEndpointTransformer();
|
|
1788
|
-
const { auth, chain, transformerProvider, resolvedModel, isStream, resolveUrl, upstreamUrl } = plan;
|
|
2173
|
+
const { auth, sessionKey, chain, transformerProvider, resolvedModel, isStream, resolveUrl, upstreamUrl } = plan;
|
|
1789
2174
|
let proxyAccountId;
|
|
1790
2175
|
const authHeaders = {};
|
|
1791
2176
|
await auth.applyHeaders(authHeaders, {
|
|
1792
2177
|
upstreamUrl,
|
|
1793
2178
|
model: resolvedModel,
|
|
2179
|
+
sessionKey,
|
|
1794
2180
|
preferredAccountId: plan.preferredAccountId,
|
|
2181
|
+
preferredAccountGroup: plan.preferredAccountGroup,
|
|
2182
|
+
boundAccountFallbackPolicy: plan.boundAccountFallbackPolicy,
|
|
1795
2183
|
reportSelection: (accountId) => {
|
|
1796
2184
|
proxyAccountId = accountId;
|
|
1797
2185
|
}
|
|
1798
2186
|
});
|
|
1799
2187
|
let rawStatus = null;
|
|
1800
|
-
const { response } = await
|
|
2188
|
+
const { response } = await _chunkMUHWHQVMcjs.executeProviderCall.call(void 0, {
|
|
1801
2189
|
executor,
|
|
1802
2190
|
request: responsesBody,
|
|
1803
2191
|
provider: transformerProvider,
|
|
@@ -1815,7 +2203,7 @@ async function runPipeline4(responsesBody, plan) {
|
|
|
1815
2203
|
},
|
|
1816
2204
|
fetchFn: (url, headers, body) => {
|
|
1817
2205
|
console.log(`[ProviderProxy:responses] -> ${url} model=${resolvedModel} stream=${isStream}`);
|
|
1818
|
-
return
|
|
2206
|
+
return _chunkKCVJWJSTcjs.fetchUpstream.call(void 0,
|
|
1819
2207
|
url,
|
|
1820
2208
|
{ method: "POST", headers, body: JSON.stringify(body) },
|
|
1821
2209
|
{ providerId: plan.proxyProviderId, accountId: proxyAccountId }
|
|
@@ -1830,8 +2218,8 @@ async function runPipeline4(responsesBody, plan) {
|
|
|
1830
2218
|
}
|
|
1831
2219
|
async function runPipelineWithPoolReporting4(responsesBody, plan) {
|
|
1832
2220
|
const first = await runPipeline4(responsesBody, plan);
|
|
1833
|
-
const outcome = await _optionalChain([plan, 'access',
|
|
1834
|
-
if (_optionalChain([outcome, 'optionalAccess',
|
|
2221
|
+
const outcome = await _optionalChain([plan, 'access', _67 => _67.auth, 'access', _68 => _68.onResult, 'optionalCall', _69 => _69(first.rawStatus)]);
|
|
2222
|
+
if (_optionalChain([outcome, 'optionalAccess', _70 => _70.rebound])) {
|
|
1835
2223
|
console.log(
|
|
1836
2224
|
"[ProviderProxy:responses] pool re-bound key after status",
|
|
1837
2225
|
first.rawStatus,
|
|
@@ -1844,7 +2232,7 @@ async function runPipelineWithPoolReporting4(responsesBody, plan) {
|
|
|
1844
2232
|
async function runPipelineWithSubscriptionRetry3(responsesBody, plan) {
|
|
1845
2233
|
const first = await runPipeline4(responsesBody, plan);
|
|
1846
2234
|
if (first.rawStatus !== 401) return first;
|
|
1847
|
-
const refreshed = await _optionalChain([plan, 'access',
|
|
2235
|
+
const refreshed = await _optionalChain([plan, 'access', _71 => _71.auth, 'access', _72 => _72.onUnauthorized, 'optionalCall', _73 => _73(plan.sessionKey)]);
|
|
1848
2236
|
if (!refreshed) {
|
|
1849
2237
|
console.warn("[ProviderProxy:responses] 401 not recoverable (onUnauthorized returned false)");
|
|
1850
2238
|
return first;
|
|
@@ -1866,7 +2254,7 @@ function resolveRouteToken(req) {
|
|
|
1866
2254
|
if (fromAuth) return fromAuth;
|
|
1867
2255
|
const googKey = req.headers["x-goog-api-key"];
|
|
1868
2256
|
const value = Array.isArray(googKey) ? googKey[0] : googKey;
|
|
1869
|
-
return _optionalChain([value, 'optionalAccess',
|
|
2257
|
+
return _optionalChain([value, 'optionalAccess', _74 => _74.trim, 'call', _75 => _75()]) || void 0;
|
|
1870
2258
|
}
|
|
1871
2259
|
async function routeRequest(req, res, routes, deps) {
|
|
1872
2260
|
const token = resolveRouteToken(req);
|
|
@@ -1883,7 +2271,7 @@ async function routeRequest(req, res, routes, deps) {
|
|
|
1883
2271
|
}
|
|
1884
2272
|
if (isOpenAIResponsesRequest(method, url)) {
|
|
1885
2273
|
const rawBody = await readBody(req);
|
|
1886
|
-
await handleOpenAIResponsesRequest(res, rawBody, route, deps);
|
|
2274
|
+
await handleOpenAIResponsesRequest(res, rawBody, route, deps, req.headers);
|
|
1887
2275
|
return;
|
|
1888
2276
|
}
|
|
1889
2277
|
if (isOpenAIChatRequest(method, url)) {
|
|
@@ -2074,11 +2462,11 @@ var DEFAULT_ACCOUNT_HEALTH = {
|
|
|
2074
2462
|
overloadCooldownMs: 10 * 6e4
|
|
2075
2463
|
};
|
|
2076
2464
|
function normalizeAccountHealth(raw) {
|
|
2077
|
-
const ah = _optionalChain([raw, 'optionalAccess',
|
|
2465
|
+
const ah = _optionalChain([raw, 'optionalAccess', _76 => _76.accountHealth]);
|
|
2078
2466
|
return {
|
|
2079
|
-
overloadCooldownEnabled: _optionalChain([ah, 'optionalAccess',
|
|
2467
|
+
overloadCooldownEnabled: _optionalChain([ah, 'optionalAccess', _77 => _77.overloadCooldownEnabled]) !== false,
|
|
2080
2468
|
overloadCooldownMs: clampNumber(
|
|
2081
|
-
_optionalChain([ah, 'optionalAccess',
|
|
2469
|
+
_optionalChain([ah, 'optionalAccess', _78 => _78.overloadCooldownMs]),
|
|
2082
2470
|
6e4,
|
|
2083
2471
|
36e5,
|
|
2084
2472
|
DEFAULT_ACCOUNT_HEALTH.overloadCooldownMs
|
|
@@ -2093,54 +2481,86 @@ var DEFAULT_ACCOUNT_PROBE = {
|
|
|
2093
2481
|
historySize: 10,
|
|
2094
2482
|
staggerMs: 500
|
|
2095
2483
|
};
|
|
2484
|
+
var DEFAULT_ALLOWANCE_SCHEDULING = {
|
|
2485
|
+
enabled: false,
|
|
2486
|
+
demoteAtPercent: 80,
|
|
2487
|
+
pauseAtPercent: 98,
|
|
2488
|
+
priorityPenalty: 100
|
|
2489
|
+
};
|
|
2490
|
+
function normalizeAllowanceScheduling(raw) {
|
|
2491
|
+
const value = _optionalChain([raw, 'optionalAccess', _79 => _79.allowanceScheduling]);
|
|
2492
|
+
const demoteAtPercent = clampNumber(
|
|
2493
|
+
_optionalChain([value, 'optionalAccess', _80 => _80.demoteAtPercent]),
|
|
2494
|
+
0,
|
|
2495
|
+
100,
|
|
2496
|
+
DEFAULT_ALLOWANCE_SCHEDULING.demoteAtPercent
|
|
2497
|
+
);
|
|
2498
|
+
const requestedPause = clampNumber(
|
|
2499
|
+
_optionalChain([value, 'optionalAccess', _81 => _81.pauseAtPercent]),
|
|
2500
|
+
0,
|
|
2501
|
+
100,
|
|
2502
|
+
DEFAULT_ALLOWANCE_SCHEDULING.pauseAtPercent
|
|
2503
|
+
);
|
|
2504
|
+
return {
|
|
2505
|
+
enabled: _optionalChain([value, 'optionalAccess', _82 => _82.enabled]) === true,
|
|
2506
|
+
demoteAtPercent,
|
|
2507
|
+
pauseAtPercent: Math.max(demoteAtPercent, requestedPause),
|
|
2508
|
+
priorityPenalty: Math.trunc(clampNumber(
|
|
2509
|
+
_optionalChain([value, 'optionalAccess', _83 => _83.priorityPenalty]),
|
|
2510
|
+
1,
|
|
2511
|
+
1e3,
|
|
2512
|
+
DEFAULT_ALLOWANCE_SCHEDULING.priorityPenalty
|
|
2513
|
+
))
|
|
2514
|
+
};
|
|
2515
|
+
}
|
|
2096
2516
|
function normalizeAccountProbe(raw) {
|
|
2097
|
-
const ap = _optionalChain([raw, 'optionalAccess',
|
|
2517
|
+
const ap = _optionalChain([raw, 'optionalAccess', _84 => _84.accountProbe]);
|
|
2098
2518
|
return {
|
|
2099
|
-
enabled: _optionalChain([ap, 'optionalAccess',
|
|
2100
|
-
intervalMs: clampNumber(_optionalChain([ap, 'optionalAccess',
|
|
2101
|
-
onlyMultiAccount: _optionalChain([ap, 'optionalAccess',
|
|
2102
|
-
timeoutMs: clampNumber(_optionalChain([ap, 'optionalAccess',
|
|
2519
|
+
enabled: _optionalChain([ap, 'optionalAccess', _85 => _85.enabled]) === true,
|
|
2520
|
+
intervalMs: clampNumber(_optionalChain([ap, 'optionalAccess', _86 => _86.intervalMs]), 6e4, 864e5, DEFAULT_ACCOUNT_PROBE.intervalMs),
|
|
2521
|
+
onlyMultiAccount: _optionalChain([ap, 'optionalAccess', _87 => _87.onlyMultiAccount]) !== false,
|
|
2522
|
+
timeoutMs: clampNumber(_optionalChain([ap, 'optionalAccess', _88 => _88.timeoutMs]), 1e3, 6e4, DEFAULT_ACCOUNT_PROBE.timeoutMs),
|
|
2103
2523
|
historySize: Math.trunc(
|
|
2104
|
-
clampNumber(_optionalChain([ap, 'optionalAccess',
|
|
2524
|
+
clampNumber(_optionalChain([ap, 'optionalAccess', _89 => _89.historySize]), 1, 200, DEFAULT_ACCOUNT_PROBE.historySize)
|
|
2105
2525
|
),
|
|
2106
|
-
staggerMs: clampNumber(_optionalChain([ap, 'optionalAccess',
|
|
2526
|
+
staggerMs: clampNumber(_optionalChain([ap, 'optionalAccess', _90 => _90.staggerMs]), 0, 6e4, DEFAULT_ACCOUNT_PROBE.staggerMs)
|
|
2107
2527
|
};
|
|
2108
2528
|
}
|
|
2109
2529
|
function normalizeAudit(raw) {
|
|
2110
|
-
const a = _optionalChain([raw, 'optionalAccess',
|
|
2530
|
+
const a = _optionalChain([raw, 'optionalAccess', _91 => _91.audit]);
|
|
2111
2531
|
return {
|
|
2112
|
-
enabled: _optionalChain([a, 'optionalAccess',
|
|
2113
|
-
captureBodies: _optionalChain([a, 'optionalAccess',
|
|
2532
|
+
enabled: _optionalChain([a, 'optionalAccess', _92 => _92.enabled]) === true,
|
|
2533
|
+
captureBodies: _optionalChain([a, 'optionalAccess', _93 => _93.captureBodies]) === true,
|
|
2114
2534
|
maxBodyBytes: Math.trunc(
|
|
2115
|
-
clampNumber(_optionalChain([a, 'optionalAccess',
|
|
2535
|
+
clampNumber(_optionalChain([a, 'optionalAccess', _94 => _94.maxBodyBytes]), 256, 1048576, _audittypes.DEFAULT_AUDIT_CONFIG.maxBodyBytes)
|
|
2116
2536
|
),
|
|
2117
2537
|
retentionDays: Math.trunc(
|
|
2118
|
-
clampNumber(_optionalChain([a, 'optionalAccess',
|
|
2538
|
+
clampNumber(_optionalChain([a, 'optionalAccess', _95 => _95.retentionDays]), 1, 365, _audittypes.DEFAULT_AUDIT_CONFIG.retentionDays)
|
|
2119
2539
|
),
|
|
2120
|
-
trustForwardedFor: _optionalChain([a, 'optionalAccess',
|
|
2540
|
+
trustForwardedFor: _optionalChain([a, 'optionalAccess', _96 => _96.trustForwardedFor]) === true
|
|
2121
2541
|
};
|
|
2122
2542
|
}
|
|
2123
2543
|
function normalizeBilling(raw) {
|
|
2124
|
-
const b = _optionalChain([raw, 'optionalAccess',
|
|
2544
|
+
const b = _optionalChain([raw, 'optionalAccess', _97 => _97.billing]);
|
|
2125
2545
|
const config = {
|
|
2126
|
-
enabled: _optionalChain([b, 'optionalAccess',
|
|
2546
|
+
enabled: _optionalChain([b, 'optionalAccess', _98 => _98.enabled]) === true,
|
|
2127
2547
|
maxRetryAgeMs: Math.trunc(
|
|
2128
|
-
clampNumber(_optionalChain([b, 'optionalAccess',
|
|
2548
|
+
clampNumber(_optionalChain([b, 'optionalAccess', _99 => _99.maxRetryAgeMs]), 6e4, 2592e6, _billingtypes.DEFAULT_BILLING_CONFIG.maxRetryAgeMs)
|
|
2129
2549
|
)
|
|
2130
2550
|
};
|
|
2131
|
-
if (typeof _optionalChain([b, 'optionalAccess',
|
|
2132
|
-
if (typeof _optionalChain([b, 'optionalAccess',
|
|
2551
|
+
if (typeof _optionalChain([b, 'optionalAccess', _100 => _100.endpoint]) === "string" && b.endpoint.trim()) config.endpoint = b.endpoint.trim();
|
|
2552
|
+
if (typeof _optionalChain([b, 'optionalAccess', _101 => _101.secret]) === "string" && b.secret.length > 0) config.secret = b.secret;
|
|
2133
2553
|
return config;
|
|
2134
2554
|
}
|
|
2135
2555
|
var DEFAULT_FINGERPRINT = { enabled: false };
|
|
2136
2556
|
function normalizeFingerprint(raw) {
|
|
2137
|
-
const f = _optionalChain([raw, 'optionalAccess',
|
|
2138
|
-
const out = { enabled: _optionalChain([f, 'optionalAccess',
|
|
2139
|
-
if (typeof _optionalChain([f, 'optionalAccess',
|
|
2557
|
+
const f = _optionalChain([raw, 'optionalAccess', _102 => _102.fingerprint]);
|
|
2558
|
+
const out = { enabled: _optionalChain([f, 'optionalAccess', _103 => _103.enabled]) === true };
|
|
2559
|
+
if (typeof _optionalChain([f, 'optionalAccess', _104 => _104.ua]) === "string" && f.ua.trim().length > 0) out.ua = f.ua.trim();
|
|
2140
2560
|
return out;
|
|
2141
2561
|
}
|
|
2142
2562
|
function normalizeVoucher(raw) {
|
|
2143
|
-
return { enabled: _optionalChain([raw, 'optionalAccess',
|
|
2563
|
+
return { enabled: _optionalChain([raw, 'optionalAccess', _105 => _105.voucher, 'optionalAccess', _106 => _106.enabled]) === true };
|
|
2144
2564
|
}
|
|
2145
2565
|
var PROXY_TYPES = ["http", "https", "socks5"];
|
|
2146
2566
|
function normalizeProxyConfig(raw) {
|
|
@@ -2224,14 +2644,14 @@ function clampNumber(value, min, max, fallback) {
|
|
|
2224
2644
|
return Math.min(max, Math.max(min, n));
|
|
2225
2645
|
}
|
|
2226
2646
|
function normalizeQueueSegments(raw) {
|
|
2227
|
-
const umq = _optionalChain([raw, 'optionalAccess',
|
|
2228
|
-
const cq = _optionalChain([raw, 'optionalAccess',
|
|
2647
|
+
const umq = _optionalChain([raw, 'optionalAccess', _107 => _107.userMessageQueue]);
|
|
2648
|
+
const cq = _optionalChain([raw, 'optionalAccess', _108 => _108.concurrencyQueue]);
|
|
2229
2649
|
return {
|
|
2230
2650
|
userMessageQueue: {
|
|
2231
|
-
enabled: _optionalChain([umq, 'optionalAccess',
|
|
2232
|
-
delayMs: clampNumber(_optionalChain([umq, 'optionalAccess',
|
|
2651
|
+
enabled: _optionalChain([umq, 'optionalAccess', _109 => _109.enabled]) === true,
|
|
2652
|
+
delayMs: clampNumber(_optionalChain([umq, 'optionalAccess', _110 => _110.delayMs]), 0, 1e4, DEFAULT_USER_MESSAGE_QUEUE.delayMs),
|
|
2233
2653
|
waitTimeoutMs: clampNumber(
|
|
2234
|
-
_optionalChain([umq, 'optionalAccess',
|
|
2654
|
+
_optionalChain([umq, 'optionalAccess', _111 => _111.waitTimeoutMs]),
|
|
2235
2655
|
1e3,
|
|
2236
2656
|
3e5,
|
|
2237
2657
|
DEFAULT_USER_MESSAGE_QUEUE.waitTimeoutMs
|
|
@@ -2239,14 +2659,14 @@ function normalizeQueueSegments(raw) {
|
|
|
2239
2659
|
},
|
|
2240
2660
|
concurrencyQueue: {
|
|
2241
2661
|
maxQueueSizeFactor: clampNumber(
|
|
2242
|
-
_optionalChain([cq, 'optionalAccess',
|
|
2662
|
+
_optionalChain([cq, 'optionalAccess', _112 => _112.maxQueueSizeFactor]),
|
|
2243
2663
|
1,
|
|
2244
2664
|
10,
|
|
2245
2665
|
DEFAULT_CONCURRENCY_QUEUE.maxQueueSizeFactor
|
|
2246
2666
|
),
|
|
2247
|
-
minQueueSize: clampNumber(_optionalChain([cq, 'optionalAccess',
|
|
2667
|
+
minQueueSize: clampNumber(_optionalChain([cq, 'optionalAccess', _113 => _113.minQueueSize]), 1, 100, DEFAULT_CONCURRENCY_QUEUE.minQueueSize),
|
|
2248
2668
|
waitTimeoutMs: clampNumber(
|
|
2249
|
-
_optionalChain([cq, 'optionalAccess',
|
|
2669
|
+
_optionalChain([cq, 'optionalAccess', _114 => _114.waitTimeoutMs]),
|
|
2250
2670
|
1e3,
|
|
2251
2671
|
3e5,
|
|
2252
2672
|
DEFAULT_CONCURRENCY_QUEUE.waitTimeoutMs
|
|
@@ -2257,11 +2677,11 @@ function normalizeQueueSegments(raw) {
|
|
|
2257
2677
|
var ALL_ENDPOINTS = ["chat", "responses", "messages", "gemini"];
|
|
2258
2678
|
function blankModelMap(endpoint) {
|
|
2259
2679
|
const modelMap = {};
|
|
2260
|
-
for (const kind of
|
|
2680
|
+
for (const kind of _chunk4VZX5F4Tcjs.modelKindsForEndpoint.call(void 0, endpoint)) modelMap[kind] = "";
|
|
2261
2681
|
return modelMap;
|
|
2262
2682
|
}
|
|
2263
2683
|
function defaultEndpointConfig(endpoint) {
|
|
2264
|
-
if (
|
|
2684
|
+
if (_chunk4VZX5F4Tcjs.isKindMappedEndpoint.call(void 0, endpoint)) {
|
|
2265
2685
|
return { endpoint, modelMap: blankModelMap(endpoint), useSubscription: false };
|
|
2266
2686
|
}
|
|
2267
2687
|
if (endpoint === "chat") {
|
|
@@ -2287,13 +2707,14 @@ function normalizePrefixTargets(raw) {
|
|
|
2287
2707
|
function normalizeEndpointConfig(e) {
|
|
2288
2708
|
const endpoint = e.endpoint;
|
|
2289
2709
|
const useSubscription = e.useSubscription === true;
|
|
2290
|
-
const boundAccountId = typeof e.boundAccountId === "string" && e.boundAccountId.trim() !== "" ? e.boundAccountId : void 0;
|
|
2710
|
+
const boundAccountId = typeof e.boundAccountId === "string" && e.boundAccountId.trim() !== "" ? e.boundAccountId.trim() : void 0;
|
|
2711
|
+
const boundAccountFallbackPolicy = boundAccountId ? e.boundAccountFallbackPolicy === "pool" ? "pool" : "strict" : void 0;
|
|
2291
2712
|
const boundKeyId = typeof e.boundKeyId === "string" && e.boundKeyId.trim() !== "" ? e.boundKeyId : void 0;
|
|
2292
2713
|
let config;
|
|
2293
|
-
if (
|
|
2714
|
+
if (_chunk4VZX5F4Tcjs.isKindMappedEndpoint.call(void 0, endpoint)) {
|
|
2294
2715
|
const rawMap = e.modelMap && typeof e.modelMap === "object" ? e.modelMap : {};
|
|
2295
2716
|
const modelMap = {};
|
|
2296
|
-
for (const kind of
|
|
2717
|
+
for (const kind of _chunk4VZX5F4Tcjs.modelKindsForEndpoint.call(void 0, endpoint)) {
|
|
2297
2718
|
const v = rawMap[kind];
|
|
2298
2719
|
modelMap[kind] = typeof v === "string" ? v : "";
|
|
2299
2720
|
}
|
|
@@ -2317,21 +2738,186 @@ function normalizeEndpointConfig(e) {
|
|
|
2317
2738
|
config.backgroundModelIds = e.backgroundModelIds;
|
|
2318
2739
|
}
|
|
2319
2740
|
}
|
|
2320
|
-
if (boundAccountId)
|
|
2741
|
+
if (boundAccountId) {
|
|
2742
|
+
config.boundAccountId = boundAccountId;
|
|
2743
|
+
config.boundAccountFallbackPolicy = boundAccountFallbackPolicy;
|
|
2744
|
+
}
|
|
2321
2745
|
if (boundKeyId) config.boundKeyId = boundKeyId;
|
|
2322
2746
|
return config;
|
|
2323
2747
|
}
|
|
2748
|
+
function normalizeBindingTarget(raw) {
|
|
2749
|
+
if (!raw || typeof raw !== "object") return null;
|
|
2750
|
+
const target = raw;
|
|
2751
|
+
const providerId = typeof target.providerId === "string" ? target.providerId.trim() : "";
|
|
2752
|
+
if (!providerId) return null;
|
|
2753
|
+
if (target.kind === "account") {
|
|
2754
|
+
const accountId = typeof target.accountId === "string" ? target.accountId.trim() : "";
|
|
2755
|
+
return accountId ? { kind: "account", providerId, accountId } : null;
|
|
2756
|
+
}
|
|
2757
|
+
if (target.kind === "account-group") {
|
|
2758
|
+
const group = typeof target.group === "string" ? target.group.trim() : "";
|
|
2759
|
+
return group ? { kind: "account-group", providerId, group } : null;
|
|
2760
|
+
}
|
|
2761
|
+
if (target.kind === "account-pool") return { kind: "account-pool", providerId };
|
|
2762
|
+
if (target.kind === "provider") {
|
|
2763
|
+
const keyId = typeof target.keyId === "string" ? target.keyId.trim() : "";
|
|
2764
|
+
return keyId ? { kind: "provider", providerId, keyId } : { kind: "provider", providerId };
|
|
2765
|
+
}
|
|
2766
|
+
return null;
|
|
2767
|
+
}
|
|
2768
|
+
function normalizeGatewayModelMappings(raw) {
|
|
2769
|
+
if (!Array.isArray(raw)) return [];
|
|
2770
|
+
const mappings = [];
|
|
2771
|
+
for (const entry of raw) {
|
|
2772
|
+
if (!entry || typeof entry !== "object") continue;
|
|
2773
|
+
const value = entry;
|
|
2774
|
+
const source = typeof value.source === "string" ? value.source.trim() : "";
|
|
2775
|
+
const target = typeof value.target === "string" ? value.target.trim() : "";
|
|
2776
|
+
if (!source || !target) continue;
|
|
2777
|
+
mappings.push({ source, target });
|
|
2778
|
+
}
|
|
2779
|
+
return mappings;
|
|
2780
|
+
}
|
|
2781
|
+
function hasConfiguredLegacyModels(config) {
|
|
2782
|
+
return Object.values(_nullishCoalesce(config.modelMap, () => ( {}))).some((value) => typeof value === "string" && value.trim()) || Boolean(_optionalChain([config, 'access', _115 => _115.models, 'optionalAccess', _116 => _116.some, 'call', _117 => _117((value) => typeof value === "string" && value.trim())])) || Boolean(_optionalChain([config, 'access', _118 => _118.defaultModel, 'optionalAccess', _119 => _119.trim, 'call', _120 => _120()])) || Boolean(_optionalChain([config, 'access', _121 => _121.backgroundModel, 'optionalAccess', _122 => _122.trim, 'call', _123 => _123()])) || Boolean(Object.values(_nullishCoalesce(config.prefixTargets, () => ( {}))).some((value) => _optionalChain([value, 'optionalAccess', _124 => _124.trim, 'call', _125 => _125()])));
|
|
2783
|
+
}
|
|
2784
|
+
function splitModelRef(ref) {
|
|
2785
|
+
if (typeof ref !== "string") return null;
|
|
2786
|
+
const idx = ref.indexOf(",");
|
|
2787
|
+
if (idx <= 0) return null;
|
|
2788
|
+
const providerId = ref.slice(0, idx).trim();
|
|
2789
|
+
const modelId = ref.slice(idx + 1).trim();
|
|
2790
|
+
return providerId && modelId ? { providerId, modelId } : null;
|
|
2791
|
+
}
|
|
2792
|
+
function legacyTarget(config, providerId) {
|
|
2793
|
+
if (config.useSubscription) {
|
|
2794
|
+
if (config.boundAccountId) {
|
|
2795
|
+
return { kind: "account", providerId, accountId: config.boundAccountId };
|
|
2796
|
+
}
|
|
2797
|
+
if (config.boundAccountGroup) {
|
|
2798
|
+
return { kind: "account-group", providerId, group: config.boundAccountGroup };
|
|
2799
|
+
}
|
|
2800
|
+
return { kind: "account-pool", providerId };
|
|
2801
|
+
}
|
|
2802
|
+
return config.boundKeyId ? { kind: "provider", providerId, keyId: config.boundKeyId } : { kind: "provider", providerId };
|
|
2803
|
+
}
|
|
2804
|
+
function legacyEndpointToBindings(config) {
|
|
2805
|
+
const fallback = config.boundAccountId && config.boundAccountFallbackPolicy === "strict" ? "fail" : "next";
|
|
2806
|
+
const byProvider = /* @__PURE__ */ new Map();
|
|
2807
|
+
const routeFor = (providerId) => {
|
|
2808
|
+
const existing = byProvider.get(providerId);
|
|
2809
|
+
if (existing) return existing;
|
|
2810
|
+
const created = {
|
|
2811
|
+
id: `legacy-${config.endpoint}-${providerId}`,
|
|
2812
|
+
name: `${config.endpoint} \xB7 ${providerId}`,
|
|
2813
|
+
enabled: true,
|
|
2814
|
+
keyScope: "all",
|
|
2815
|
+
endpoint: config.endpoint,
|
|
2816
|
+
target: legacyTarget(config, providerId),
|
|
2817
|
+
fallback,
|
|
2818
|
+
modelMode: "mapped"
|
|
2819
|
+
};
|
|
2820
|
+
byProvider.set(providerId, created);
|
|
2821
|
+
return created;
|
|
2822
|
+
};
|
|
2823
|
+
for (const [kind, ref] of Object.entries(_nullishCoalesce(config.modelMap, () => ( {})))) {
|
|
2824
|
+
const parsed = splitModelRef(ref);
|
|
2825
|
+
if (!parsed) continue;
|
|
2826
|
+
const route = routeFor(parsed.providerId);
|
|
2827
|
+
route.modelMap = { ...route.modelMap, [kind]: ref };
|
|
2828
|
+
}
|
|
2829
|
+
for (const ref of _nullishCoalesce(config.models, () => ( []))) {
|
|
2830
|
+
const parsed = splitModelRef(ref);
|
|
2831
|
+
if (!parsed) continue;
|
|
2832
|
+
const route = routeFor(parsed.providerId);
|
|
2833
|
+
route.models = [..._nullishCoalesce(route.models, () => ( [])), ref];
|
|
2834
|
+
}
|
|
2835
|
+
for (const [prefix, ref] of Object.entries(_nullishCoalesce(config.prefixTargets, () => ( {})))) {
|
|
2836
|
+
const parsed = splitModelRef(ref);
|
|
2837
|
+
if (!parsed) continue;
|
|
2838
|
+
const route = routeFor(parsed.providerId);
|
|
2839
|
+
route.dispatchMode = "prefix";
|
|
2840
|
+
route.prefixTargets = { ...route.prefixTargets, [prefix]: ref };
|
|
2841
|
+
}
|
|
2842
|
+
for (const [field, ref] of [
|
|
2843
|
+
["defaultModel", config.defaultModel],
|
|
2844
|
+
["backgroundModel", config.backgroundModel]
|
|
2845
|
+
]) {
|
|
2846
|
+
const parsed = splitModelRef(ref);
|
|
2847
|
+
if (!parsed) continue;
|
|
2848
|
+
const route = routeFor(parsed.providerId);
|
|
2849
|
+
route[field] = ref;
|
|
2850
|
+
if (_optionalChain([config, 'access', _126 => _126.backgroundModelIds, 'optionalAccess', _127 => _127.length])) {
|
|
2851
|
+
route.backgroundModelIds = [...config.backgroundModelIds];
|
|
2852
|
+
}
|
|
2853
|
+
}
|
|
2854
|
+
return [...byProvider.values()];
|
|
2855
|
+
}
|
|
2856
|
+
function legacyEndpointsToBindings(endpoints) {
|
|
2857
|
+
return endpoints.filter((endpoint) => hasConfiguredLegacyModels(endpoint)).flatMap((endpoint) => legacyEndpointToBindings(endpoint));
|
|
2858
|
+
}
|
|
2859
|
+
function normalizeGatewayBindings(raw) {
|
|
2860
|
+
if (!Array.isArray(raw)) return [];
|
|
2861
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2862
|
+
const bindings = [];
|
|
2863
|
+
for (const entry of raw) {
|
|
2864
|
+
if (!entry || typeof entry !== "object") continue;
|
|
2865
|
+
const value = entry;
|
|
2866
|
+
const id = typeof value.id === "string" ? value.id.trim() : "";
|
|
2867
|
+
const name = typeof value.name === "string" ? value.name.trim() : "";
|
|
2868
|
+
const endpoint = value.endpoint;
|
|
2869
|
+
const target = normalizeBindingTarget(value.target);
|
|
2870
|
+
if (!id || seen.has(id) || !name || !ALL_ENDPOINTS.includes(endpoint) || !target) continue;
|
|
2871
|
+
seen.add(id);
|
|
2872
|
+
const normalizedRoute = normalizeEndpointConfig({
|
|
2873
|
+
...value,
|
|
2874
|
+
endpoint,
|
|
2875
|
+
useSubscription: target.kind !== "provider"
|
|
2876
|
+
});
|
|
2877
|
+
const apiKeyIds = Array.isArray(value.apiKeyIds) ? [...new Set(value.apiKeyIds.filter((key) => typeof key === "string" && key.trim() !== "").map((key) => key.trim()))] : [];
|
|
2878
|
+
const keyScope = value.keyScope === "selected" ? "selected" : value.keyScope === "all" ? "all" : apiKeyIds.length > 0 ? "selected" : "all";
|
|
2879
|
+
const modelMappings = normalizeGatewayModelMappings(value.modelMappings);
|
|
2880
|
+
const modelMode = value.modelMode === "passthrough" ? "passthrough" : value.modelMode === "mapped" ? "mapped" : modelMappings.length > 0 || hasConfiguredLegacyModels(normalizedRoute) ? "mapped" : "passthrough";
|
|
2881
|
+
const priority = typeof value.priority === "number" && Number.isFinite(value.priority) ? Math.max(0, Math.min(1e4, Math.round(value.priority))) : void 0;
|
|
2882
|
+
const binding = {
|
|
2883
|
+
id,
|
|
2884
|
+
name,
|
|
2885
|
+
enabled: value.enabled !== false,
|
|
2886
|
+
keyScope,
|
|
2887
|
+
endpoint,
|
|
2888
|
+
target,
|
|
2889
|
+
// Legacy `'global'` meant "yield to the removed global endpoint fallback";
|
|
2890
|
+
// it now yields to the next matching route, which is the same default.
|
|
2891
|
+
fallback: value.fallback === "fail" ? "fail" : "next",
|
|
2892
|
+
modelMode
|
|
2893
|
+
};
|
|
2894
|
+
if (apiKeyIds.length > 0) binding.apiKeyIds = apiKeyIds;
|
|
2895
|
+
if (modelMappings.length > 0) binding.modelMappings = modelMappings;
|
|
2896
|
+
if (priority !== void 0) binding.priority = priority;
|
|
2897
|
+
if (normalizedRoute.modelMap) binding.modelMap = normalizedRoute.modelMap;
|
|
2898
|
+
if (normalizedRoute.models) binding.models = normalizedRoute.models;
|
|
2899
|
+
if (normalizedRoute.dispatchMode) binding.dispatchMode = normalizedRoute.dispatchMode;
|
|
2900
|
+
if (normalizedRoute.prefixTargets) binding.prefixTargets = normalizedRoute.prefixTargets;
|
|
2901
|
+
if (normalizedRoute.defaultModel !== void 0) binding.defaultModel = normalizedRoute.defaultModel;
|
|
2902
|
+
if (normalizedRoute.backgroundModel !== void 0) binding.backgroundModel = normalizedRoute.backgroundModel;
|
|
2903
|
+
if (normalizedRoute.backgroundModelIds) binding.backgroundModelIds = normalizedRoute.backgroundModelIds;
|
|
2904
|
+
bindings.push(binding);
|
|
2905
|
+
}
|
|
2906
|
+
return bindings;
|
|
2907
|
+
}
|
|
2324
2908
|
function defaultServerConfig() {
|
|
2325
2909
|
const queues = normalizeQueueSegments(void 0);
|
|
2326
2910
|
return {
|
|
2327
2911
|
enabled: false,
|
|
2328
2912
|
networkBinding: false,
|
|
2329
2913
|
endpoints: ALL_ENDPOINTS.map(defaultEndpointConfig),
|
|
2914
|
+
bindings: [],
|
|
2330
2915
|
port: DEFAULT_OUTBOUND_PORT,
|
|
2331
2916
|
userMessageQueue: queues.userMessageQueue,
|
|
2332
2917
|
concurrencyQueue: queues.concurrencyQueue,
|
|
2333
2918
|
accountHealth: normalizeAccountHealth(void 0),
|
|
2334
2919
|
accountProbe: normalizeAccountProbe(void 0),
|
|
2920
|
+
allowanceScheduling: normalizeAllowanceScheduling(void 0),
|
|
2335
2921
|
audit: normalizeAudit(void 0),
|
|
2336
2922
|
billing: normalizeBilling(void 0),
|
|
2337
2923
|
fingerprint: normalizeFingerprint(void 0),
|
|
@@ -2348,17 +2934,20 @@ function normalizeServerConfig(raw) {
|
|
|
2348
2934
|
}
|
|
2349
2935
|
}
|
|
2350
2936
|
const queues = normalizeQueueSegments(raw);
|
|
2937
|
+
const legacyEndpoints = ALL_ENDPOINTS.map((ep) => _nullishCoalesce(byEndpoint.get(ep), () => ( defaultEndpointConfig(ep))));
|
|
2938
|
+
const persistedBindings = normalizeGatewayBindings(raw.bindings);
|
|
2939
|
+
const bindings = persistedBindings.length > 0 ? persistedBindings : normalizeGatewayBindings(legacyEndpointsToBindings(legacyEndpoints));
|
|
2351
2940
|
const config = {
|
|
2352
2941
|
enabled: raw.enabled === true,
|
|
2353
2942
|
networkBinding: raw.networkBinding === true,
|
|
2354
|
-
endpoints: ALL_ENDPOINTS.map(
|
|
2355
|
-
|
|
2356
|
-
),
|
|
2943
|
+
endpoints: ALL_ENDPOINTS.map(defaultEndpointConfig),
|
|
2944
|
+
bindings,
|
|
2357
2945
|
port: _nullishCoalesce(raw.port, () => ( base.port)),
|
|
2358
2946
|
userMessageQueue: queues.userMessageQueue,
|
|
2359
2947
|
concurrencyQueue: queues.concurrencyQueue,
|
|
2360
2948
|
accountHealth: normalizeAccountHealth(raw),
|
|
2361
2949
|
accountProbe: normalizeAccountProbe(raw),
|
|
2950
|
+
allowanceScheduling: normalizeAllowanceScheduling(raw),
|
|
2362
2951
|
audit: normalizeAudit(raw),
|
|
2363
2952
|
billing: normalizeBilling(raw),
|
|
2364
2953
|
fingerprint: normalizeFingerprint(raw),
|
|
@@ -2384,11 +2973,13 @@ function mergeServerConfig(current, patch) {
|
|
|
2384
2973
|
enabled: _nullishCoalesce(patch.enabled, () => ( current.enabled)),
|
|
2385
2974
|
networkBinding: _nullishCoalesce(patch.networkBinding, () => ( current.networkBinding)),
|
|
2386
2975
|
endpoints: _nullishCoalesce(patch.endpoints, () => ( current.endpoints)),
|
|
2976
|
+
bindings: _nullishCoalesce(patch.bindings, () => ( current.bindings)),
|
|
2387
2977
|
port: _nullishCoalesce(patch.port, () => ( current.port)),
|
|
2388
2978
|
userMessageQueue: _nullishCoalesce(patch.userMessageQueue, () => ( current.userMessageQueue)),
|
|
2389
2979
|
concurrencyQueue: _nullishCoalesce(patch.concurrencyQueue, () => ( current.concurrencyQueue)),
|
|
2390
2980
|
accountHealth: _nullishCoalesce(patch.accountHealth, () => ( current.accountHealth)),
|
|
2391
2981
|
accountProbe: _nullishCoalesce(patch.accountProbe, () => ( current.accountProbe)),
|
|
2982
|
+
allowanceScheduling: _nullishCoalesce(patch.allowanceScheduling, () => ( current.allowanceScheduling)),
|
|
2392
2983
|
audit: _nullishCoalesce(patch.audit, () => ( current.audit)),
|
|
2393
2984
|
billing: _nullishCoalesce(patch.billing, () => ( current.billing)),
|
|
2394
2985
|
// Proxy is layer-replaced (not deep-merged): a PUT carrying `proxy` swaps the
|
|
@@ -2406,6 +2997,167 @@ function mergeServerConfig(current, patch) {
|
|
|
2406
2997
|
});
|
|
2407
2998
|
}
|
|
2408
2999
|
|
|
3000
|
+
// src/outbound-api/gatewayBindingResolver.ts
|
|
3001
|
+
var MESSAGE_FALLBACK_KINDS = ["sonnet", "opus", "haiku", "fable"];
|
|
3002
|
+
function nonBlank(value) {
|
|
3003
|
+
return typeof value === "string" && value.trim() !== "";
|
|
3004
|
+
}
|
|
3005
|
+
function gatewayBindingAllowsKey(binding, apiKeyId) {
|
|
3006
|
+
const scope = _nullishCoalesce(binding.keyScope, () => ( (_optionalChain([binding, 'access', _128 => _128.apiKeyIds, 'optionalAccess', _129 => _129.length]) ? "selected" : "all")));
|
|
3007
|
+
return scope === "all" || Boolean(_optionalChain([binding, 'access', _130 => _130.apiKeyIds, 'optionalAccess', _131 => _131.includes, 'call', _132 => _132(apiKeyId)]));
|
|
3008
|
+
}
|
|
3009
|
+
function wildcardMatches(pattern, value) {
|
|
3010
|
+
const escaped = pattern.split("*").map((part) => part.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&")).join(".*");
|
|
3011
|
+
return new RegExp(`^${escaped}$`, "iu").test(value);
|
|
3012
|
+
}
|
|
3013
|
+
function resolveGatewayModelMapping(mappings, requestedModel) {
|
|
3014
|
+
if (!nonBlank(requestedModel)) return void 0;
|
|
3015
|
+
const wanted = requestedModel.trim();
|
|
3016
|
+
const exact = (_nullishCoalesce(mappings, () => ( []))).find(
|
|
3017
|
+
(mapping) => nonBlank(mapping.source) && !mapping.source.includes("*") && mapping.source.trim().toLocaleLowerCase() === wanted.toLocaleLowerCase()
|
|
3018
|
+
);
|
|
3019
|
+
if (exact && nonBlank(exact.target)) return exact.target.trim();
|
|
3020
|
+
const wildcard = (_nullishCoalesce(mappings, () => ( []))).find(
|
|
3021
|
+
(mapping) => nonBlank(mapping.source) && mapping.source.includes("*") && wildcardMatches(mapping.source.trim(), wanted)
|
|
3022
|
+
);
|
|
3023
|
+
return wildcard && nonBlank(wildcard.target) ? wildcard.target.trim() : void 0;
|
|
3024
|
+
}
|
|
3025
|
+
function routeCanServe(binding, requestedModel, role) {
|
|
3026
|
+
if (binding.modelMode === "passthrough") return nonBlank(requestedModel);
|
|
3027
|
+
if (_optionalChain([binding, 'access', _133 => _133.modelMappings, 'optionalAccess', _134 => _134.length])) {
|
|
3028
|
+
return nonBlank(resolveGatewayModelMapping(binding.modelMappings, requestedModel));
|
|
3029
|
+
}
|
|
3030
|
+
if (_chunk4VZX5F4Tcjs.isKindMappedEndpoint.call(void 0, binding.endpoint)) {
|
|
3031
|
+
const map = _nullishCoalesce(binding.modelMap, () => ( {}));
|
|
3032
|
+
const kind = _chunk4VZX5F4Tcjs.detectModelKind.call(void 0, binding.endpoint, requestedModel);
|
|
3033
|
+
if (kind && nonBlank(map[kind])) return true;
|
|
3034
|
+
if (binding.endpoint === "messages") {
|
|
3035
|
+
return MESSAGE_FALLBACK_KINDS.some((candidate) => nonBlank(map[candidate]));
|
|
3036
|
+
}
|
|
3037
|
+
return nonBlank(map.codex);
|
|
3038
|
+
}
|
|
3039
|
+
if (binding.endpoint === "chat" && binding.dispatchMode === "prefix") {
|
|
3040
|
+
return _chunk4VZX5F4Tcjs.resolvePrefixTarget.call(void 0, binding.prefixTargets, requestedModel) !== null;
|
|
3041
|
+
}
|
|
3042
|
+
if (binding.endpoint === "chat") {
|
|
3043
|
+
if (!requestedModel) return false;
|
|
3044
|
+
const wanted = requestedModel.trim().toLowerCase();
|
|
3045
|
+
return (_nullishCoalesce(binding.models, () => ( []))).some((ref) => _optionalChain([modelIdOf, 'call', _135 => _135(ref), 'optionalAccess', _136 => _136.toLowerCase, 'call', _137 => _137()]) === wanted);
|
|
3046
|
+
}
|
|
3047
|
+
return role === "background" ? nonBlank(binding.backgroundModel) : nonBlank(binding.defaultModel);
|
|
3048
|
+
}
|
|
3049
|
+
function modelIdOf(ref) {
|
|
3050
|
+
if (!nonBlank(ref)) return void 0;
|
|
3051
|
+
const trimmed = ref.trim();
|
|
3052
|
+
const comma = trimmed.indexOf(",");
|
|
3053
|
+
const modelId = comma >= 0 ? trimmed.slice(comma + 1).trim() : trimmed;
|
|
3054
|
+
return modelId || void 0;
|
|
3055
|
+
}
|
|
3056
|
+
function targetProviderId(target) {
|
|
3057
|
+
return target.providerId.trim();
|
|
3058
|
+
}
|
|
3059
|
+
function targetRef(target, ref) {
|
|
3060
|
+
const modelId = _nullishCoalesce(modelIdOf(ref), () => ( ""));
|
|
3061
|
+
return modelId ? `${targetProviderId(target)},${modelId}` : "";
|
|
3062
|
+
}
|
|
3063
|
+
function targetRefs(target, refs) {
|
|
3064
|
+
return (_nullishCoalesce(refs, () => ( []))).map((ref) => targetRef(target, ref)).filter(nonBlank);
|
|
3065
|
+
}
|
|
3066
|
+
function targetPrefixRefs(target, refs) {
|
|
3067
|
+
if (!refs) return void 0;
|
|
3068
|
+
const mapped = {};
|
|
3069
|
+
for (const kind of ["claude", "gpt", "gemini"]) {
|
|
3070
|
+
const ref = targetRef(target, refs[kind]);
|
|
3071
|
+
if (ref) mapped[kind] = ref;
|
|
3072
|
+
}
|
|
3073
|
+
return mapped.claude || mapped.gpt || mapped.gemini ? mapped : void 0;
|
|
3074
|
+
}
|
|
3075
|
+
function applySingleModel(config, binding, targetModel) {
|
|
3076
|
+
const ref = targetRef(binding.target, targetModel);
|
|
3077
|
+
if (!ref) return;
|
|
3078
|
+
if (_chunk4VZX5F4Tcjs.isKindMappedEndpoint.call(void 0, binding.endpoint)) {
|
|
3079
|
+
config.modelMap = Object.fromEntries(
|
|
3080
|
+
_chunk4VZX5F4Tcjs.modelKindsForEndpoint.call(void 0, binding.endpoint).map((kind) => [kind, ref])
|
|
3081
|
+
);
|
|
3082
|
+
} else if (binding.endpoint === "chat") {
|
|
3083
|
+
config.models = [ref];
|
|
3084
|
+
config.dispatchMode = "list";
|
|
3085
|
+
} else {
|
|
3086
|
+
config.defaultModel = ref;
|
|
3087
|
+
config.backgroundModel = ref;
|
|
3088
|
+
}
|
|
3089
|
+
}
|
|
3090
|
+
function gatewayBindingToEndpointConfig(binding, requestedModel) {
|
|
3091
|
+
const target = binding.target;
|
|
3092
|
+
const config = {
|
|
3093
|
+
endpoint: binding.endpoint,
|
|
3094
|
+
useSubscription: target.kind !== "provider"
|
|
3095
|
+
};
|
|
3096
|
+
const usesGenericModelHandling = binding.modelMode === "passthrough" || Boolean(_optionalChain([binding, 'access', _138 => _138.modelMappings, 'optionalAccess', _139 => _139.length]));
|
|
3097
|
+
const dynamicModel = binding.modelMode === "passthrough" ? requestedModel : resolveGatewayModelMapping(binding.modelMappings, requestedModel);
|
|
3098
|
+
if (usesGenericModelHandling) {
|
|
3099
|
+
if (nonBlank(dynamicModel)) applySingleModel(config, binding, dynamicModel);
|
|
3100
|
+
} else if (_chunk4VZX5F4Tcjs.isKindMappedEndpoint.call(void 0, binding.endpoint)) {
|
|
3101
|
+
config.modelMap = Object.fromEntries(
|
|
3102
|
+
Object.entries(_nullishCoalesce(binding.modelMap, () => ( {}))).map(([kind, ref]) => [kind, targetRef(target, ref)])
|
|
3103
|
+
);
|
|
3104
|
+
} else if (binding.endpoint === "chat") {
|
|
3105
|
+
config.models = targetRefs(target, binding.models);
|
|
3106
|
+
if (binding.dispatchMode === "prefix") {
|
|
3107
|
+
config.dispatchMode = "prefix";
|
|
3108
|
+
config.prefixTargets = targetPrefixRefs(target, binding.prefixTargets);
|
|
3109
|
+
}
|
|
3110
|
+
} else {
|
|
3111
|
+
config.defaultModel = targetRef(target, binding.defaultModel);
|
|
3112
|
+
config.backgroundModel = targetRef(target, binding.backgroundModel);
|
|
3113
|
+
if (binding.backgroundModelIds) config.backgroundModelIds = [...binding.backgroundModelIds];
|
|
3114
|
+
}
|
|
3115
|
+
if (target.kind === "account") {
|
|
3116
|
+
config.boundAccountId = target.accountId;
|
|
3117
|
+
config.boundAccountFallbackPolicy = binding.fallback === "next" ? "pool" : "strict";
|
|
3118
|
+
} else if (target.kind === "account-group") {
|
|
3119
|
+
config.boundAccountGroup = target.group;
|
|
3120
|
+
config.boundAccountFallbackPolicy = binding.fallback === "next" ? "pool" : "strict";
|
|
3121
|
+
} else if (target.kind === "provider" && target.keyId) {
|
|
3122
|
+
config.boundKeyId = target.keyId;
|
|
3123
|
+
config.boundKeyFallbackPolicy = binding.fallback === "next" ? "pool" : "strict";
|
|
3124
|
+
}
|
|
3125
|
+
return config;
|
|
3126
|
+
}
|
|
3127
|
+
function candidateGatewayBindings(bindings, apiKeyId, endpoint) {
|
|
3128
|
+
const candidates = (_nullishCoalesce(bindings, () => ( []))).filter(
|
|
3129
|
+
(binding) => binding.enabled && binding.endpoint === endpoint && gatewayBindingAllowsKey(binding, apiKeyId)
|
|
3130
|
+
);
|
|
3131
|
+
const scopeOf = (binding) => _nullishCoalesce(binding.keyScope, () => ( (_optionalChain([binding, 'access', _140 => _140.apiKeyIds, 'optionalAccess', _141 => _141.length]) ? "selected" : "all")));
|
|
3132
|
+
const scoped = candidates.filter((binding) => scopeOf(binding) === "selected");
|
|
3133
|
+
const pool = scoped.length > 0 ? scoped : candidates.filter((binding) => scopeOf(binding) === "all");
|
|
3134
|
+
return pool.sort(
|
|
3135
|
+
(left, right) => (_nullishCoalesce(left.priority, () => ( 100))) - (_nullishCoalesce(right.priority, () => ( 100))) || left.id.localeCompare(right.id)
|
|
3136
|
+
);
|
|
3137
|
+
}
|
|
3138
|
+
function candidateBackgroundModelIds(bindings, apiKeyId, endpoint) {
|
|
3139
|
+
const ids = [
|
|
3140
|
+
...new Set(
|
|
3141
|
+
candidateGatewayBindings(bindings, apiKeyId, endpoint).flatMap(
|
|
3142
|
+
(binding) => _nullishCoalesce(binding.backgroundModelIds, () => ( []))
|
|
3143
|
+
)
|
|
3144
|
+
)
|
|
3145
|
+
];
|
|
3146
|
+
return ids.length > 0 ? ids : void 0;
|
|
3147
|
+
}
|
|
3148
|
+
function resolveGatewayBinding(input) {
|
|
3149
|
+
const candidates = candidateGatewayBindings(input.bindings, input.apiKeyId, input.endpoint);
|
|
3150
|
+
const binding = _nullishCoalesce(candidates.find(
|
|
3151
|
+
(candidate) => candidate.fallback === "fail" || routeCanServe(candidate, input.requestedModel, input.role)
|
|
3152
|
+
), () => ( candidates[0]));
|
|
3153
|
+
if (!binding) return { source: "none" };
|
|
3154
|
+
return {
|
|
3155
|
+
source: "binding",
|
|
3156
|
+
binding,
|
|
3157
|
+
config: gatewayBindingToEndpointConfig(binding, input.requestedModel)
|
|
3158
|
+
};
|
|
3159
|
+
}
|
|
3160
|
+
|
|
2409
3161
|
// src/outbound-api/outboundApiKeyAuth.ts
|
|
2410
3162
|
|
|
2411
3163
|
|
|
@@ -2498,6 +3250,27 @@ async function createNamedKey(db, name) {
|
|
|
2498
3250
|
plaintextOnce: secret
|
|
2499
3251
|
};
|
|
2500
3252
|
}
|
|
3253
|
+
async function createIntegrationKey(db, name, allowedEndpoints = ["responses", "messages"]) {
|
|
3254
|
+
const secret = generateSecret();
|
|
3255
|
+
const id = newKeyId();
|
|
3256
|
+
const prefix = keyPrefix(secret);
|
|
3257
|
+
const row = await db.outboundApiKeysCreate({
|
|
3258
|
+
id,
|
|
3259
|
+
name,
|
|
3260
|
+
keyHash: hashKey(secret),
|
|
3261
|
+
keyPrefix: prefix,
|
|
3262
|
+
kind: "integration",
|
|
3263
|
+
allowedEndpoints: [...new Set(allowedEndpoints)],
|
|
3264
|
+
loopbackOnly: true
|
|
3265
|
+
});
|
|
3266
|
+
return {
|
|
3267
|
+
id: row.id,
|
|
3268
|
+
name: row.name,
|
|
3269
|
+
keyPrefix: row.keyPrefix,
|
|
3270
|
+
createdAt: row.createdAt,
|
|
3271
|
+
plaintextOnce: secret
|
|
3272
|
+
};
|
|
3273
|
+
}
|
|
2501
3274
|
function extractCostLimits(row) {
|
|
2502
3275
|
const limits = {};
|
|
2503
3276
|
if (row.dailyCostLimitUsd != null) limits.dailyUsd = row.dailyCostLimitUsd;
|
|
@@ -2520,7 +3293,12 @@ function extractModelRestriction(row) {
|
|
|
2520
3293
|
};
|
|
2521
3294
|
}
|
|
2522
3295
|
function toVerifiedKey(row) {
|
|
2523
|
-
const key = {
|
|
3296
|
+
const key = {
|
|
3297
|
+
id: row.id,
|
|
3298
|
+
kind: row.kind,
|
|
3299
|
+
allowedEndpoints: row.allowedEndpoints,
|
|
3300
|
+
loopbackOnly: row.loopbackOnly
|
|
3301
|
+
};
|
|
2524
3302
|
if (row.maxConcurrency !== void 0 && row.maxConcurrency !== null) {
|
|
2525
3303
|
key.maxConcurrency = row.maxConcurrency;
|
|
2526
3304
|
}
|
|
@@ -2740,8 +3518,8 @@ var OutboundRateLimiter = (_class8 = class {
|
|
|
2740
3518
|
* recorded (no bucket growth).
|
|
2741
3519
|
*/
|
|
2742
3520
|
check(apiKeyId, now = Date.now(), override) {
|
|
2743
|
-
const maxRequests = _nullishCoalesce(_optionalChain([override, 'optionalAccess',
|
|
2744
|
-
const windowMs = _nullishCoalesce(_optionalChain([override, 'optionalAccess',
|
|
3521
|
+
const maxRequests = _nullishCoalesce(_optionalChain([override, 'optionalAccess', _142 => _142.maxRequests]), () => ( this.maxRequests));
|
|
3522
|
+
const windowMs = _nullishCoalesce(_optionalChain([override, 'optionalAccess', _143 => _143.windowMs]), () => ( this.windowMs));
|
|
2745
3523
|
if (maxRequests === 0) return { allowed: true, retryAfterSeconds: 0 };
|
|
2746
3524
|
const cutoff = now - windowMs;
|
|
2747
3525
|
const timestamps = (_nullishCoalesce(this.hits.get(apiKeyId), () => ( []))).filter((ts) => ts > cutoff);
|
|
@@ -2786,7 +3564,7 @@ function isUserMessageAnthropic(body) {
|
|
|
2786
3564
|
if (typeof content === "string") return true;
|
|
2787
3565
|
if (Array.isArray(content)) {
|
|
2788
3566
|
const hasToolResult = content.some(
|
|
2789
|
-
(block) => _optionalChain([asObject, 'call',
|
|
3567
|
+
(block) => _optionalChain([asObject, 'call', _144 => _144(block), 'optionalAccess', _145 => _145["type"]]) === "tool_result"
|
|
2790
3568
|
);
|
|
2791
3569
|
return !hasToolResult;
|
|
2792
3570
|
}
|
|
@@ -2815,7 +3593,7 @@ function isUserMessageGemini(body) {
|
|
|
2815
3593
|
if (!lastContent || lastContent["role"] !== "user") return false;
|
|
2816
3594
|
const parts = asArray(lastContent["parts"]);
|
|
2817
3595
|
const hasFunctionResponse = parts.some(
|
|
2818
|
-
(part) => _optionalChain([asObject, 'call',
|
|
3596
|
+
(part) => _optionalChain([asObject, 'call', _146 => _146(part), 'optionalAccess', _147 => _147["functionResponse"]]) !== void 0
|
|
2819
3597
|
);
|
|
2820
3598
|
return !hasFunctionResponse;
|
|
2821
3599
|
}
|
|
@@ -2989,14 +3767,14 @@ function newVoucherId() {
|
|
|
2989
3767
|
}
|
|
2990
3768
|
function computeVoucherGrant(voucher, currentKey, now) {
|
|
2991
3769
|
if (voucher.type === "credit") {
|
|
2992
|
-
const current = _nullishCoalesce(_optionalChain([currentKey, 'optionalAccess',
|
|
3770
|
+
const current = _nullishCoalesce(_optionalChain([currentKey, 'optionalAccess', _148 => _148.totalCostLimitUsd]), () => ( 0));
|
|
2993
3771
|
let granted2 = current + (_nullishCoalesce(voucher.creditUsd, () => ( 0)));
|
|
2994
3772
|
if (voucher.maxTotalCostLimitUsd != null) {
|
|
2995
3773
|
granted2 = Math.min(granted2, voucher.maxTotalCostLimitUsd);
|
|
2996
3774
|
}
|
|
2997
3775
|
return { totalCostLimitUsd: granted2 };
|
|
2998
3776
|
}
|
|
2999
|
-
const currentExpiry = _nullishCoalesce(_optionalChain([currentKey, 'optionalAccess',
|
|
3777
|
+
const currentExpiry = _nullishCoalesce(_optionalChain([currentKey, 'optionalAccess', _149 => _149.expiresAt]), () => ( now));
|
|
3000
3778
|
let granted = currentExpiry + (_nullishCoalesce(voucher.renewalDays, () => ( 0))) * DAY_MS2;
|
|
3001
3779
|
if (voucher.maxExpiryDays != null) {
|
|
3002
3780
|
granted = Math.min(granted, now + voucher.maxExpiryDays * DAY_MS2);
|
|
@@ -3027,7 +3805,7 @@ function toVoucherInfo(v) {
|
|
|
3027
3805
|
// src/outbound-api/voucherRedeem.ts
|
|
3028
3806
|
function isRedeemRequest(method, url) {
|
|
3029
3807
|
if (method !== "POST" || !url) return false;
|
|
3030
|
-
const path = _nullishCoalesce(_optionalChain([url, 'access',
|
|
3808
|
+
const path = _nullishCoalesce(_optionalChain([url, 'access', _150 => _150.split, 'call', _151 => _151("?"), 'access', _152 => _152[0], 'optionalAccess', _153 => _153.replace, 'call', _154 => _154(/\/+$/, "")]), () => ( ""));
|
|
3031
3809
|
return path.endsWith("/redeem");
|
|
3032
3810
|
}
|
|
3033
3811
|
function writeErr(res, status, message, headers = {}) {
|
|
@@ -3057,8 +3835,8 @@ function grantToResult(type, granted) {
|
|
|
3057
3835
|
function currentResult(type, keyRow) {
|
|
3058
3836
|
const result = { type };
|
|
3059
3837
|
if (type === "credit") {
|
|
3060
|
-
if (_optionalChain([keyRow, 'optionalAccess',
|
|
3061
|
-
} else if (_optionalChain([keyRow, 'optionalAccess',
|
|
3838
|
+
if (_optionalChain([keyRow, 'optionalAccess', _155 => _155.totalCostLimitUsd]) != null) result.totalCostLimitUsd = keyRow.totalCostLimitUsd;
|
|
3839
|
+
} else if (_optionalChain([keyRow, 'optionalAccess', _156 => _156.expiresAt]) != null) {
|
|
3062
3840
|
result.expiresAt = keyRow.expiresAt;
|
|
3063
3841
|
}
|
|
3064
3842
|
return result;
|
|
@@ -3096,7 +3874,7 @@ async function handleVoucherRedeem(req, res, deps, voucherEnabled, redeemLimiter
|
|
|
3096
3874
|
let code;
|
|
3097
3875
|
try {
|
|
3098
3876
|
code = raw ? JSON.parse(raw)["code"] : void 0;
|
|
3099
|
-
} catch (
|
|
3877
|
+
} catch (e24) {
|
|
3100
3878
|
writeErr(res, 400, "Invalid JSON in request body");
|
|
3101
3879
|
return;
|
|
3102
3880
|
}
|
|
@@ -3145,7 +3923,7 @@ async function handleVoucherRedeem(req, res, deps, voucherEnabled, redeemLimiter
|
|
|
3145
3923
|
const won = await voucherDb.voucherRedeemCas(voucher.id, verifiedKeyId, absolute, now);
|
|
3146
3924
|
if (!won) {
|
|
3147
3925
|
const after = await voucherDb.voucherGetByHash(codeHash);
|
|
3148
|
-
if (_optionalChain([after, 'optionalAccess',
|
|
3926
|
+
if (_optionalChain([after, 'optionalAccess', _157 => _157.status]) === "redeemed" && after.redeemedByKeyId === verifiedKeyId) {
|
|
3149
3927
|
return after.grantApplied === true ? { ok: true, result: currentResult(after.type, await deps.db.outboundApiKeysGetByHash(keyHash)) } : await applyFirstPass(after, recordedAbsolute(after));
|
|
3150
3928
|
}
|
|
3151
3929
|
return { ok: false, status: 409, message: "Code was already redeemed" };
|
|
@@ -3164,10 +3942,10 @@ function getFallbackRedeemLimiter() {
|
|
|
3164
3942
|
fallbackRedeemLimiter ??= new OutboundRateLimiter({ maxRequests: 10, windowMs: 6e4 });
|
|
3165
3943
|
return fallbackRedeemLimiter;
|
|
3166
3944
|
}
|
|
3167
|
-
function writeJsonError(res, status, message, headers = {}) {
|
|
3945
|
+
function writeJsonError(res, status, message, headers = {}, details = {}) {
|
|
3168
3946
|
if (res.headersSent) return;
|
|
3169
3947
|
res.writeHead(status, { "Content-Type": "application/json", ...headers });
|
|
3170
|
-
res.end(JSON.stringify({ error: { type: "outbound_api_error", message } }));
|
|
3948
|
+
res.end(JSON.stringify({ error: { type: "outbound_api_error", message, ...details } }));
|
|
3171
3949
|
}
|
|
3172
3950
|
function writeCostLimitError(res, scope, limitUsd, spentUsd) {
|
|
3173
3951
|
if (res.headersSent) return;
|
|
@@ -3206,14 +3984,19 @@ function extractPresentedKey(req) {
|
|
|
3206
3984
|
}
|
|
3207
3985
|
const xApiKey = req.headers["x-api-key"];
|
|
3208
3986
|
const xApi = Array.isArray(xApiKey) ? xApiKey[0] : xApiKey;
|
|
3209
|
-
if (_optionalChain([xApi, 'optionalAccess',
|
|
3987
|
+
if (_optionalChain([xApi, 'optionalAccess', _158 => _158.trim, 'call', _159 => _159()])) return xApi.trim();
|
|
3210
3988
|
const goog = req.headers["x-goog-api-key"];
|
|
3211
3989
|
const g = Array.isArray(goog) ? goog[0] : goog;
|
|
3212
|
-
return _optionalChain([g, 'optionalAccess',
|
|
3990
|
+
return _optionalChain([g, 'optionalAccess', _160 => _160.trim, 'call', _161 => _161()]) || void 0;
|
|
3991
|
+
}
|
|
3992
|
+
function isLoopbackPeer(address) {
|
|
3993
|
+
if (!address) return false;
|
|
3994
|
+
const normalized = address.toLowerCase().split("%")[0];
|
|
3995
|
+
return normalized === "::1" || normalized === "127.0.0.1" || normalized.startsWith("127.") || normalized.startsWith("::ffff:127.");
|
|
3213
3996
|
}
|
|
3214
3997
|
function selectEndpoint(method, url) {
|
|
3215
3998
|
if (method !== "POST" || !url) return null;
|
|
3216
|
-
const path = _nullishCoalesce(_optionalChain([url, 'access',
|
|
3999
|
+
const path = _nullishCoalesce(_optionalChain([url, 'access', _162 => _162.split, 'call', _163 => _163("?"), 'access', _164 => _164[0], 'optionalAccess', _165 => _165.replace, 'call', _166 => _166(/\/+$/, "")]), () => ( ""));
|
|
3217
4000
|
if (path.endsWith("/chat/completions")) return "chat";
|
|
3218
4001
|
if (path.endsWith("/responses")) return "responses";
|
|
3219
4002
|
if (path.includes("/v1/messages")) return "messages";
|
|
@@ -3231,12 +4014,36 @@ function extractGeminiModelFromUrl(url) {
|
|
|
3231
4014
|
}
|
|
3232
4015
|
function isModelsListRequest(url) {
|
|
3233
4016
|
if (!url) return false;
|
|
3234
|
-
const path = _nullishCoalesce(_optionalChain([url, 'access',
|
|
4017
|
+
const path = _nullishCoalesce(_optionalChain([url, 'access', _167 => _167.split, 'call', _168 => _168("?"), 'access', _169 => _169[0], 'optionalAccess', _170 => _170.replace, 'call', _171 => _171(/\/+$/, "")]), () => ( ""));
|
|
3235
4018
|
return path.endsWith("/models");
|
|
3236
4019
|
}
|
|
3237
|
-
function
|
|
3238
|
-
const
|
|
3239
|
-
const
|
|
4020
|
+
function writeModelsList(res, config, apiKeyId, allowedEndpoints) {
|
|
4021
|
+
const refs = [];
|
|
4022
|
+
const endpointConfigs = [];
|
|
4023
|
+
for (const endpoint of ["chat", "responses", "messages", "gemini"]) {
|
|
4024
|
+
if (allowedEndpoints && !allowedEndpoints.includes(endpoint)) continue;
|
|
4025
|
+
endpointConfigs.push(
|
|
4026
|
+
...candidateGatewayBindings(config.bindings, apiKeyId, endpoint).map(
|
|
4027
|
+
(binding) => gatewayBindingToEndpointConfig(binding)
|
|
4028
|
+
)
|
|
4029
|
+
);
|
|
4030
|
+
}
|
|
4031
|
+
for (const endpoint of endpointConfigs) {
|
|
4032
|
+
if (allowedEndpoints && !allowedEndpoints.includes(endpoint.endpoint)) continue;
|
|
4033
|
+
if (endpoint.endpoint === "chat") refs.push(..._nullishCoalesce(endpoint.models, () => ( [])));
|
|
4034
|
+
else if (endpoint.endpoint === "messages" || endpoint.endpoint === "responses") {
|
|
4035
|
+
refs.push(...Object.values(_nullishCoalesce(endpoint.modelMap, () => ( {}))));
|
|
4036
|
+
} else {
|
|
4037
|
+
if (endpoint.defaultModel) refs.push(endpoint.defaultModel);
|
|
4038
|
+
if (endpoint.backgroundModel) refs.push(endpoint.backgroundModel);
|
|
4039
|
+
}
|
|
4040
|
+
}
|
|
4041
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4042
|
+
const data = refs.map((ref) => _chunk4VZX5F4Tcjs.parseModelRef.call(void 0, ref)).filter((p) => p !== null).filter((p) => {
|
|
4043
|
+
if (seen.has(p.modelId)) return false;
|
|
4044
|
+
seen.add(p.modelId);
|
|
4045
|
+
return true;
|
|
4046
|
+
}).map((p) => ({ id: p.modelId, object: "model", owned_by: "omnicross" }));
|
|
3240
4047
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
3241
4048
|
res.end(JSON.stringify({ object: "list", data }));
|
|
3242
4049
|
}
|
|
@@ -3255,7 +4062,7 @@ function shimAuthHeader(req, routeToken) {
|
|
|
3255
4062
|
}
|
|
3256
4063
|
async function handleOutboundRequest(req, res, deps, config, rateLimiter, serialQueue, concurrencyGate, redeemLimiter, redeemMutex) {
|
|
3257
4064
|
const now = Date.now();
|
|
3258
|
-
const audit =
|
|
4065
|
+
const audit = _chunkUNWKG6EIcjs.beginAuditCapture.call(void 0, req, res, now);
|
|
3259
4066
|
const billing = _chunkAPYG5QD7cjs.beginBillingCapture.call(void 0, req, res, now);
|
|
3260
4067
|
const presented = extractPresentedKey(req);
|
|
3261
4068
|
const verification = await verifyKey(deps.db, presented, now);
|
|
@@ -3270,12 +4077,20 @@ async function handleOutboundRequest(req, res, deps, config, rateLimiter, serial
|
|
|
3270
4077
|
const verified = verification.key;
|
|
3271
4078
|
if (audit) audit.keyId = verified.id;
|
|
3272
4079
|
if (billing) billing.keyId = verified.id;
|
|
4080
|
+
if (verified.loopbackOnly && !isLoopbackPeer(_optionalChain([req, 'access', _172 => _172.socket, 'optionalAccess', _173 => _173.remoteAddress]))) {
|
|
4081
|
+
writeJsonError(res, 403, "This integration key is restricted to loopback clients");
|
|
4082
|
+
return;
|
|
4083
|
+
}
|
|
3273
4084
|
if (isRedeemRequest(req.method, req.url)) {
|
|
4085
|
+
if (verified.kind === "integration") {
|
|
4086
|
+
writeJsonError(res, 403, "Integration keys cannot redeem vouchers");
|
|
4087
|
+
return;
|
|
4088
|
+
}
|
|
3274
4089
|
await handleVoucherRedeem(
|
|
3275
4090
|
req,
|
|
3276
4091
|
res,
|
|
3277
4092
|
deps,
|
|
3278
|
-
_optionalChain([config, 'access',
|
|
4093
|
+
_optionalChain([config, 'access', _174 => _174.voucher, 'optionalAccess', _175 => _175.enabled]) === true,
|
|
3279
4094
|
_nullishCoalesce(redeemLimiter, () => ( getFallbackRedeemLimiter())),
|
|
3280
4095
|
verified.id,
|
|
3281
4096
|
_nullishCoalesce(presented, () => ( "")),
|
|
@@ -3292,7 +4107,11 @@ async function handleOutboundRequest(req, res, deps, config, rateLimiter, serial
|
|
|
3292
4107
|
return;
|
|
3293
4108
|
}
|
|
3294
4109
|
if (req.method === "GET" && isModelsListRequest(req.url)) {
|
|
3295
|
-
|
|
4110
|
+
if (verified.allowedEndpoints && verified.allowedEndpoints.length === 0) {
|
|
4111
|
+
writeJsonError(res, 403, "API key is not allowed to access this endpoint");
|
|
4112
|
+
return;
|
|
4113
|
+
}
|
|
4114
|
+
writeModelsList(res, config, verified.id, verified.allowedEndpoints);
|
|
3296
4115
|
return;
|
|
3297
4116
|
}
|
|
3298
4117
|
const endpoint = selectEndpoint(req.method, req.url);
|
|
@@ -3300,9 +4119,12 @@ async function handleOutboundRequest(req, res, deps, config, rateLimiter, serial
|
|
|
3300
4119
|
writeJsonError(res, 404, `Unsupported: ${req.method} ${req.url}`);
|
|
3301
4120
|
return;
|
|
3302
4121
|
}
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
4122
|
+
if (verified.allowedEndpoints && !verified.allowedEndpoints.includes(endpoint)) {
|
|
4123
|
+
writeJsonError(res, 403, "API key is not allowed to access this endpoint");
|
|
4124
|
+
return;
|
|
4125
|
+
}
|
|
4126
|
+
if (candidateGatewayBindings(config.bindings, verified.id, endpoint).length === 0) {
|
|
4127
|
+
writeJsonError(res, 503, `endpoint '${endpoint}' has no downstream route for this key`);
|
|
3306
4128
|
return;
|
|
3307
4129
|
}
|
|
3308
4130
|
if (verified.costLimits && deps.keySpendTracker) {
|
|
@@ -3361,12 +4183,12 @@ async function handleOutboundRequest(req, res, deps, config, rateLimiter, serial
|
|
|
3361
4183
|
res.once("close", release2);
|
|
3362
4184
|
}
|
|
3363
4185
|
try {
|
|
3364
|
-
const ingressFormat =
|
|
4186
|
+
const ingressFormat = _chunk4VZX5F4Tcjs.endpointToIngressFormat.call(void 0, endpoint);
|
|
3365
4187
|
const rawBody = await readBody3(req);
|
|
3366
4188
|
let parsedBody = {};
|
|
3367
4189
|
try {
|
|
3368
4190
|
parsedBody = rawBody ? JSON.parse(rawBody) : {};
|
|
3369
|
-
} catch (
|
|
4191
|
+
} catch (e25) {
|
|
3370
4192
|
writeJsonError(res, 400, "Invalid JSON in request body");
|
|
3371
4193
|
return;
|
|
3372
4194
|
}
|
|
@@ -3375,23 +4197,40 @@ async function handleOutboundRequest(req, res, deps, config, rateLimiter, serial
|
|
|
3375
4197
|
const urlModel = extractGeminiModelFromUrl(req.url);
|
|
3376
4198
|
if (urlModel) parsedBody["model"] = urlModel;
|
|
3377
4199
|
}
|
|
3378
|
-
const
|
|
3379
|
-
const
|
|
3380
|
-
|
|
4200
|
+
const requestedModel = _chunk4VZX5F4Tcjs.extractRequestedModel.call(void 0, ingressFormat, parsedBody);
|
|
4201
|
+
const role = _chunk4VZX5F4Tcjs.isKindMappedEndpoint.call(void 0, endpoint) || endpoint === "chat" ? void 0 : _chunk4VZX5F4Tcjs.detectRequestRole.call(void 0, ingressFormat, parsedBody, {
|
|
4202
|
+
// Role detection precedes the route pick (the pick consumes the
|
|
4203
|
+
// role), so the hint is the union across the candidate routes.
|
|
4204
|
+
backgroundModelIds: candidateBackgroundModelIds(config.bindings, verified.id, endpoint)
|
|
4205
|
+
});
|
|
4206
|
+
const bindingResolution = resolveGatewayBinding({
|
|
4207
|
+
bindings: config.bindings,
|
|
4208
|
+
apiKeyId: verified.id,
|
|
4209
|
+
endpoint,
|
|
4210
|
+
requestedModel,
|
|
4211
|
+
role
|
|
4212
|
+
});
|
|
4213
|
+
if (bindingResolution.source === "none") {
|
|
4214
|
+
writeJsonError(res, 503, `endpoint '${endpoint}' has no downstream route for this key`);
|
|
4215
|
+
return;
|
|
4216
|
+
}
|
|
4217
|
+
const effectiveEndpointConfig = bindingResolution.config;
|
|
4218
|
+
const bindingAffinitySuffix = `:${bindingResolution.binding.id}`;
|
|
4219
|
+
const sessionId = deps.proxyDeps.apiKeyPool ? `outbound:${verified.id}${bindingAffinitySuffix}` : null;
|
|
4220
|
+
const resolved = _chunk4VZX5F4Tcjs.isKindMappedEndpoint.call(void 0, endpoint) || endpoint === "chat" ? await _chunk4VZX5F4Tcjs.resolveRoute.call(void 0, {
|
|
4221
|
+
config: effectiveEndpointConfig,
|
|
3381
4222
|
ingressFormat,
|
|
3382
4223
|
llmConfig: deps.llmConfig,
|
|
3383
4224
|
sessionId,
|
|
3384
4225
|
// Capture the ORIGINAL requested id BEFORE any downstream swap; for
|
|
3385
4226
|
// kind-mapped endpoints it selects the kind AND is stamped onto
|
|
3386
4227
|
// `route.requestedModel`; for chat it is matched against the list.
|
|
3387
|
-
requestedModel
|
|
4228
|
+
requestedModel,
|
|
3388
4229
|
// Attribution: stamp the verified named-key id onto the route.
|
|
3389
4230
|
apiKeyId: verified.id
|
|
3390
|
-
}) : await
|
|
3391
|
-
config:
|
|
3392
|
-
role
|
|
3393
|
-
backgroundModelIds: endpointConfig.backgroundModelIds
|
|
3394
|
-
}),
|
|
4231
|
+
}) : await _chunk4VZX5F4Tcjs.resolveRoute.call(void 0, {
|
|
4232
|
+
config: effectiveEndpointConfig,
|
|
4233
|
+
role,
|
|
3395
4234
|
ingressFormat,
|
|
3396
4235
|
llmConfig: deps.llmConfig,
|
|
3397
4236
|
sessionId,
|
|
@@ -3420,7 +4259,7 @@ async function handleOutboundRequest(req, res, deps, config, rateLimiter, serial
|
|
|
3420
4259
|
}
|
|
3421
4260
|
let releaseSerial = null;
|
|
3422
4261
|
const providerKey = resolved.route.providerId;
|
|
3423
|
-
if (_optionalChain([config, 'access',
|
|
4262
|
+
if (_optionalChain([config, 'access', _176 => _176.userMessageQueue, 'optionalAccess', _177 => _177.enabled]) && providerKey && isUserMessageRequest(endpoint, parsedBody)) {
|
|
3424
4263
|
const umq = config.userMessageQueue;
|
|
3425
4264
|
try {
|
|
3426
4265
|
const serialSlot = await serialQueue.acquire(providerKey, {
|
|
@@ -3452,12 +4291,29 @@ async function handleOutboundRequest(req, res, deps, config, rateLimiter, serial
|
|
|
3452
4291
|
const replay = makeReplayRequest(req, rawBody);
|
|
3453
4292
|
await routeRequest(replay, res, routeMap, deps.proxyDeps);
|
|
3454
4293
|
} catch (err) {
|
|
4294
|
+
if (_chunk25GXJCEZcjs.isBoundAccountSelectionError.call(void 0, err)) {
|
|
4295
|
+
const headers = {};
|
|
4296
|
+
if (err.status === 429 && err.resumeAt) {
|
|
4297
|
+
const resumeMs = Date.parse(err.resumeAt);
|
|
4298
|
+
if (Number.isFinite(resumeMs)) {
|
|
4299
|
+
headers["Retry-After"] = String(Math.max(1, Math.ceil((resumeMs - Date.now()) / 1e3)));
|
|
4300
|
+
}
|
|
4301
|
+
}
|
|
4302
|
+
writeJsonError(
|
|
4303
|
+
res,
|
|
4304
|
+
err.status,
|
|
4305
|
+
_chunk25GXJCEZcjs.boundAccountSelectionMessage.call(void 0, err.reason),
|
|
4306
|
+
headers,
|
|
4307
|
+
{ code: err.code, reason: err.reason }
|
|
4308
|
+
);
|
|
4309
|
+
return;
|
|
4310
|
+
}
|
|
3455
4311
|
const message = _chunkSVNDB62Dcjs.serializeError.call(void 0, err);
|
|
3456
4312
|
if (deps.logger) deps.logger.error("[OutboundApi] dispatch error:", message);
|
|
3457
4313
|
else console.error("[OutboundApi] dispatch error:", message);
|
|
3458
4314
|
_chunkUIBD2YY5cjs.emitWebhookEvent.call(void 0, { kind: "server.error", at: Date.now(), message });
|
|
3459
4315
|
if (audit) audit.error = message;
|
|
3460
|
-
writeJsonError(res, 502, message);
|
|
4316
|
+
writeJsonError(res, _chunk6QQG7YG3cjs.isAccountAllowanceExhaustedError.call(void 0, err) ? 429 : 502, message);
|
|
3461
4317
|
} finally {
|
|
3462
4318
|
routeMap.removeRoute(token);
|
|
3463
4319
|
if (releaseSerial) releaseSerial();
|
|
@@ -3481,18 +4337,8 @@ function makeReplayRequest(req, rawBody) {
|
|
|
3481
4337
|
var DEFAULT_OUTBOUND_PORT = 8765;
|
|
3482
4338
|
var LOOPBACK_ADDR = "127.0.0.1";
|
|
3483
4339
|
var LAN_ADDR = "0.0.0.0";
|
|
3484
|
-
var OutboundApiConfigError = class extends Error {
|
|
3485
|
-
|
|
3486
|
-
constructor(missing) {
|
|
3487
|
-
super(
|
|
3488
|
-
"Outbound API server cannot start: incomplete model-kind configuration \u2014 " + missing.map((m) => `${m.endpoint} missing [${m.missingKinds.join(", ")}]`).join("; ")
|
|
3489
|
-
);
|
|
3490
|
-
this.name = "OutboundApiConfigError";
|
|
3491
|
-
this.missing = missing;
|
|
3492
|
-
}
|
|
3493
|
-
};
|
|
3494
4340
|
var OutboundApiServer = (_class11 = class {
|
|
3495
|
-
constructor(deps, onPortChange) {;_class11.prototype.__init12.call(this);_class11.prototype.__init13.call(this);_class11.prototype.__init14.call(this);_class11.prototype.__init15.call(this);_class11.prototype.__init16.call(this);_class11.prototype.__init17.call(this);_class11.prototype.__init18.call(this);_class11.prototype.__init19.call(this);_class11.prototype.__init20.call(this);
|
|
4341
|
+
constructor(deps, onPortChange) {;_class11.prototype.__init12.call(this);_class11.prototype.__init13.call(this);_class11.prototype.__init14.call(this);_class11.prototype.__init15.call(this);_class11.prototype.__init16.call(this);_class11.prototype.__init17.call(this);_class11.prototype.__init18.call(this);_class11.prototype.__init19.call(this);_class11.prototype.__init20.call(this);_class11.prototype.__init21.call(this);
|
|
3496
4342
|
this.deps = deps;
|
|
3497
4343
|
this.onPortChange = onPortChange;
|
|
3498
4344
|
}
|
|
@@ -3502,25 +4348,26 @@ var OutboundApiServer = (_class11 = class {
|
|
|
3502
4348
|
__init13() {this.boundPort = 0}
|
|
3503
4349
|
__init14() {this.boundAddr = LOOPBACK_ADDR}
|
|
3504
4350
|
__init15() {this.endpoints = []}
|
|
4351
|
+
__init16() {this.bindings = []}
|
|
3505
4352
|
|
|
3506
4353
|
|
|
3507
4354
|
|
|
3508
|
-
|
|
4355
|
+
__init17() {this.rateLimiter = new OutboundRateLimiter()}
|
|
3509
4356
|
/**
|
|
3510
4357
|
* Redeem-attempt limiter (voucher-redemption #9, design D6) — a SEPARATE bucket
|
|
3511
4358
|
* from the traffic `rateLimiter`, keyed by the authenticating key id, so
|
|
3512
4359
|
* brute-forcing `CC_` codes is throttled (a handful/min) without touching the
|
|
3513
4360
|
* per-key request rate. Conservative fixed defaults (10 / 60s).
|
|
3514
4361
|
*/
|
|
3515
|
-
|
|
4362
|
+
__init18() {this.redeemLimiter = new OutboundRateLimiter({ maxRequests: 10, windowMs: 6e4 })}
|
|
3516
4363
|
/**
|
|
3517
4364
|
* Per-key redeem mutex (voucher-redemption #9, MJ1 fix). One instance for the
|
|
3518
4365
|
* server's lifetime so concurrent redeem REQUESTS for the same key serialize
|
|
3519
4366
|
* (relative grant increments accumulate instead of clobbering a snapshot).
|
|
3520
4367
|
*/
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
|
|
4368
|
+
__init19() {this.redeemMutex = new KeyedMutex()}
|
|
4369
|
+
__init20() {this.serialQueue = new UserMessageSerialQueue()}
|
|
4370
|
+
__init21() {this.concurrencyGate = new OutboundConcurrencyGate()}
|
|
3524
4371
|
/**
|
|
3525
4372
|
* Apply a config. Restarts the listener ONLY when the bind address or port
|
|
3526
4373
|
* changes (or when toggling enabled); per-endpoint routing config is updated
|
|
@@ -3528,6 +4375,7 @@ var OutboundApiServer = (_class11 = class {
|
|
|
3528
4375
|
*/
|
|
3529
4376
|
async applyConfig(input) {
|
|
3530
4377
|
this.endpoints = input.endpoints;
|
|
4378
|
+
this.bindings = _nullishCoalesce(input.bindings, () => ( []));
|
|
3531
4379
|
this.userMessageQueue = input.userMessageQueue;
|
|
3532
4380
|
this.concurrencyQueue = input.concurrencyQueue;
|
|
3533
4381
|
this.voucherConfig = input.voucher;
|
|
@@ -3537,16 +4385,6 @@ var OutboundApiServer = (_class11 = class {
|
|
|
3537
4385
|
await this.stop();
|
|
3538
4386
|
return;
|
|
3539
4387
|
}
|
|
3540
|
-
const missing = _chunkVACWOIREcjs.validateServerModelConfig.call(void 0, {
|
|
3541
|
-
enabled: true,
|
|
3542
|
-
networkBinding: input.networkBinding,
|
|
3543
|
-
endpoints: input.endpoints,
|
|
3544
|
-
port: input.port
|
|
3545
|
-
});
|
|
3546
|
-
if (missing.length > 0) {
|
|
3547
|
-
await this.stop();
|
|
3548
|
-
throw new OutboundApiConfigError(missing);
|
|
3549
|
-
}
|
|
3550
4388
|
const running = this.server !== null;
|
|
3551
4389
|
const bindChanged = running && (this.boundAddr !== wantAddr || this.boundPort !== wantPort);
|
|
3552
4390
|
if (running && !bindChanged) {
|
|
@@ -3561,7 +4399,7 @@ var OutboundApiServer = (_class11 = class {
|
|
|
3561
4399
|
const actualPort = await this.listen(bindAddr, port);
|
|
3562
4400
|
this.boundAddr = bindAddr;
|
|
3563
4401
|
this.boundPort = actualPort;
|
|
3564
|
-
if (actualPort !== port) _optionalChain([this, 'access',
|
|
4402
|
+
if (actualPort !== port) _optionalChain([this, 'access', _178 => _178.onPortChange, 'optionalCall', _179 => _179(actualPort)]);
|
|
3565
4403
|
this.logInfo(`[OutboundApiServer] Listening on ${bindAddr}:${actualPort}`);
|
|
3566
4404
|
return actualPort;
|
|
3567
4405
|
}
|
|
@@ -3595,6 +4433,7 @@ var OutboundApiServer = (_class11 = class {
|
|
|
3595
4433
|
}
|
|
3596
4434
|
/** Per-request handler. Auth is enforced on EVERY request (incl. loopback). */
|
|
3597
4435
|
onRequest(req, res) {
|
|
4436
|
+
if (req.url) req.url = normalizeDoubledEndpointPath(req.url);
|
|
3598
4437
|
if (this.deps.healthReportProvider && this.tryServeHealth(req, res)) return;
|
|
3599
4438
|
handleOutboundRequest(
|
|
3600
4439
|
req,
|
|
@@ -3602,6 +4441,7 @@ var OutboundApiServer = (_class11 = class {
|
|
|
3602
4441
|
this.deps,
|
|
3603
4442
|
{
|
|
3604
4443
|
endpoints: this.endpoints,
|
|
4444
|
+
bindings: this.bindings,
|
|
3605
4445
|
userMessageQueue: this.userMessageQueue,
|
|
3606
4446
|
concurrencyQueue: this.concurrencyQueue,
|
|
3607
4447
|
voucher: this.voucherConfig
|
|
@@ -3628,7 +4468,7 @@ var OutboundApiServer = (_class11 = class {
|
|
|
3628
4468
|
const provider = this.deps.healthReportProvider;
|
|
3629
4469
|
if (!provider) return false;
|
|
3630
4470
|
if (req.method !== "GET" && req.method !== "HEAD") return false;
|
|
3631
|
-
const path = _optionalChain([(_nullishCoalesce(req.url, () => ( "/"))), 'access',
|
|
4471
|
+
const path = _optionalChain([(_nullishCoalesce(req.url, () => ( "/"))), 'access', _180 => _180.split, 'call', _181 => _181("?"), 'access', _182 => _182[0], 'optionalAccess', _183 => _183.replace, 'call', _184 => _184(/\/+$/, "")]) || "/";
|
|
3632
4472
|
if (path !== "/health" && path !== "/healthz") return false;
|
|
3633
4473
|
const report = provider();
|
|
3634
4474
|
res.writeHead(_healthloggingtypes.healthHttpStatus.call(void 0, report.status), { "Content-Type": "application/json" });
|
|
@@ -3717,6 +4557,16 @@ function firstLanIPv4() {
|
|
|
3717
4557
|
}
|
|
3718
4558
|
return null;
|
|
3719
4559
|
}
|
|
4560
|
+
function normalizeDoubledEndpointPath(url) {
|
|
4561
|
+
const queryIdx = url.indexOf("?");
|
|
4562
|
+
const path = queryIdx === -1 ? url : url.slice(0, queryIdx);
|
|
4563
|
+
const query = queryIdx === -1 ? "" : url.slice(queryIdx);
|
|
4564
|
+
const collapsed = path.replace(
|
|
4565
|
+
/^(.*?)(\/v1\/(?:messages|responses|chat\/completions))\2$/,
|
|
4566
|
+
"$1$2"
|
|
4567
|
+
);
|
|
4568
|
+
return collapsed + query;
|
|
4569
|
+
}
|
|
3720
4570
|
|
|
3721
4571
|
// src/outbound-api/keySpendTracker.ts
|
|
3722
4572
|
function startOfLocalDay(ts) {
|
|
@@ -3730,12 +4580,12 @@ function startOfLocalWeek(ts) {
|
|
|
3730
4580
|
return day.getTime();
|
|
3731
4581
|
}
|
|
3732
4582
|
var KeySpendTracker = (_class12 = class {
|
|
3733
|
-
constructor(seeder) {;_class12.prototype.
|
|
4583
|
+
constructor(seeder) {;_class12.prototype.__init22.call(this);
|
|
3734
4584
|
this.seeder = seeder;
|
|
3735
4585
|
}
|
|
3736
4586
|
|
|
3737
4587
|
/** apiKeyId → live accumulated spend (seeded lazily). */
|
|
3738
|
-
|
|
4588
|
+
__init22() {this.spend = /* @__PURE__ */ new Map()}
|
|
3739
4589
|
/**
|
|
3740
4590
|
* Read the key's accumulated spend, seeding from the durable store on a cache
|
|
3741
4591
|
* miss and rolling the daily/weekly windows on a hit.
|
|
@@ -3823,7 +4673,7 @@ async function callOpenAICompletion(provider, apiKey, options, logger) {
|
|
|
3823
4673
|
model: options.model,
|
|
3824
4674
|
messages: options.messages.map((m) => convertMessageToOpenAI(m)),
|
|
3825
4675
|
// Only set max_tokens if explicitly provided, otherwise let API use its default
|
|
3826
|
-
...options.maxTokens ? { max_tokens: options.maxTokens } : {},
|
|
4676
|
+
...options.maxTokens !== void 0 ? { max_tokens: options.maxTokens } : {},
|
|
3827
4677
|
temperature: options.temperature,
|
|
3828
4678
|
stream: false
|
|
3829
4679
|
// For now, non-streaming only
|
|
@@ -3874,7 +4724,7 @@ async function callAnthropicCompletion(provider, apiKey, options, logger) {
|
|
|
3874
4724
|
const nonSystemMessages = options.messages.filter((m) => m.role !== "system");
|
|
3875
4725
|
const anthropicRequest2 = {
|
|
3876
4726
|
model: options.model,
|
|
3877
|
-
max_tokens: options.maxTokens
|
|
4727
|
+
max_tokens: _nullishCoalesce(options.maxTokens, () => ( 16384)),
|
|
3878
4728
|
temperature: options.temperature,
|
|
3879
4729
|
...systemMessages.length > 0 ? { system: systemMessages.map((m) => m.content).join("\n\n") } : {},
|
|
3880
4730
|
messages: nonSystemMessages.map((m) => convertMessageToAnthropic(m)),
|
|
@@ -3896,14 +4746,14 @@ async function callAnthropicCompletion(provider, apiKey, options, logger) {
|
|
|
3896
4746
|
};
|
|
3897
4747
|
}
|
|
3898
4748
|
const anthropicResponse2 = await response2.json();
|
|
3899
|
-
const openaiResponse2 =
|
|
4749
|
+
const openaiResponse2 = _chunkWYTEQ4Q5cjs.convertAnthropicToOpenAI.call(void 0, anthropicResponse2);
|
|
3900
4750
|
const choice2 = openaiResponse2.choices[0];
|
|
3901
4751
|
return {
|
|
3902
4752
|
success: true,
|
|
3903
4753
|
message: {
|
|
3904
4754
|
id: `assistant-${Date.now()}`,
|
|
3905
4755
|
role: "assistant",
|
|
3906
|
-
content: _optionalChain([choice2, 'access',
|
|
4756
|
+
content: _optionalChain([choice2, 'access', _185 => _185.message, 'optionalAccess', _186 => _186.content]) || "",
|
|
3907
4757
|
timestamp: Date.now()
|
|
3908
4758
|
},
|
|
3909
4759
|
usage: openaiResponse2.usage ? {
|
|
@@ -3920,14 +4770,14 @@ async function callAnthropicCompletion(provider, apiKey, options, logger) {
|
|
|
3920
4770
|
content: m.content
|
|
3921
4771
|
})),
|
|
3922
4772
|
// Anthropic requires max_tokens; use 16384 default if not explicitly set
|
|
3923
|
-
max_tokens: options.maxTokens
|
|
4773
|
+
max_tokens: _nullishCoalesce(options.maxTokens, () => ( 16384)),
|
|
3924
4774
|
temperature: options.temperature,
|
|
3925
4775
|
stream: false
|
|
3926
4776
|
};
|
|
3927
4777
|
const config = {
|
|
3928
4778
|
defaultModel: options.model
|
|
3929
4779
|
};
|
|
3930
|
-
const anthropicRequest =
|
|
4780
|
+
const anthropicRequest = _chunkWYTEQ4Q5cjs.convertOpenAIToAnthropic.call(void 0, openaiRequest, config);
|
|
3931
4781
|
const apiUrl = _chunkA2YMUCBTcjs.buildProviderApiUrl.call(void 0, provider, { model: options.model, stream: false });
|
|
3932
4782
|
const headers = _chunkQ27JY5RGcjs.getProviderHeaders.call(void 0, provider, apiKey);
|
|
3933
4783
|
logger.info("Calling Anthropic completion API", { url: apiUrl, model: options.model });
|
|
@@ -3944,7 +4794,7 @@ async function callAnthropicCompletion(provider, apiKey, options, logger) {
|
|
|
3944
4794
|
};
|
|
3945
4795
|
}
|
|
3946
4796
|
const anthropicResponse = await response.json();
|
|
3947
|
-
const openaiResponse =
|
|
4797
|
+
const openaiResponse = _chunkWYTEQ4Q5cjs.convertAnthropicToOpenAI.call(void 0, anthropicResponse);
|
|
3948
4798
|
const choice = openaiResponse.choices[0];
|
|
3949
4799
|
return {
|
|
3950
4800
|
success: true,
|
|
@@ -3975,7 +4825,7 @@ async function callGeminiCompletion(provider, apiKey, options, logger) {
|
|
|
3975
4825
|
const request = {
|
|
3976
4826
|
contents,
|
|
3977
4827
|
generationConfig: {
|
|
3978
|
-
...options.maxTokens ? { maxOutputTokens: options.maxTokens } : {},
|
|
4828
|
+
...options.maxTokens !== void 0 ? { maxOutputTokens: options.maxTokens } : {},
|
|
3979
4829
|
...options.temperature !== void 0 ? { temperature: options.temperature } : {}
|
|
3980
4830
|
}
|
|
3981
4831
|
};
|
|
@@ -4008,7 +4858,7 @@ async function callGeminiCompletion(provider, apiKey, options, logger) {
|
|
|
4008
4858
|
const candidate = candidates[0];
|
|
4009
4859
|
const content = candidate.content;
|
|
4010
4860
|
let textContent = "";
|
|
4011
|
-
if (_optionalChain([content, 'optionalAccess',
|
|
4861
|
+
if (_optionalChain([content, 'optionalAccess', _187 => _187.parts])) {
|
|
4012
4862
|
for (const part of content.parts) {
|
|
4013
4863
|
if (part.text) {
|
|
4014
4864
|
textContent += part.text;
|
|
@@ -4044,7 +4894,7 @@ async function callOpenAIResponseCompletion(provider, apiKey, options, logger) {
|
|
|
4044
4894
|
model: options.model,
|
|
4045
4895
|
input,
|
|
4046
4896
|
stream: false,
|
|
4047
|
-
...options.maxTokens ? { max_output_tokens: options.maxTokens } : {},
|
|
4897
|
+
...options.maxTokens !== void 0 ? { max_output_tokens: options.maxTokens } : {},
|
|
4048
4898
|
...options.temperature !== void 0 ? { temperature: options.temperature } : {}
|
|
4049
4899
|
};
|
|
4050
4900
|
if (options.thinkLevel && options.thinkLevel !== "none") {
|
|
@@ -4109,7 +4959,7 @@ async function streamOpenAICompletion(provider, apiKey, options, messageId, call
|
|
|
4109
4959
|
model: options.model,
|
|
4110
4960
|
messages: options.messages.map((m) => convertMessageToOpenAI(m)),
|
|
4111
4961
|
// Only set max_tokens if explicitly provided, otherwise let API use its default
|
|
4112
|
-
...options.maxTokens ? { max_tokens: options.maxTokens } : {},
|
|
4962
|
+
...options.maxTokens !== void 0 ? { max_tokens: options.maxTokens } : {},
|
|
4113
4963
|
temperature: options.temperature,
|
|
4114
4964
|
stream: true
|
|
4115
4965
|
};
|
|
@@ -4141,7 +4991,7 @@ async function streamOpenAICompletion(provider, apiKey, options, messageId, call
|
|
|
4141
4991
|
});
|
|
4142
4992
|
if (!response.ok) {
|
|
4143
4993
|
const errorText = await response.text();
|
|
4144
|
-
_optionalChain([callbacks, 'access',
|
|
4994
|
+
_optionalChain([callbacks, 'access', _188 => _188.onError, 'optionalCall', _189 => _189(`API error (${response.status}): ${errorText}`)]);
|
|
4145
4995
|
return;
|
|
4146
4996
|
}
|
|
4147
4997
|
const result = await _chunkHQP3K7PUcjs.streamSSEResponse.call(void 0, response, "openai", {
|
|
@@ -4151,7 +5001,7 @@ async function streamOpenAICompletion(provider, apiKey, options, messageId, call
|
|
|
4151
5001
|
onVideo: callbacks.onVideo,
|
|
4152
5002
|
onError: callbacks.onError
|
|
4153
5003
|
});
|
|
4154
|
-
_optionalChain([callbacks, 'access',
|
|
5004
|
+
_optionalChain([callbacks, 'access', _190 => _190.onDone, 'optionalCall', _191 => _191(
|
|
4155
5005
|
{
|
|
4156
5006
|
id: messageId,
|
|
4157
5007
|
role: "assistant",
|
|
@@ -4168,7 +5018,7 @@ async function streamOpenAICompletion(provider, apiKey, options, messageId, call
|
|
|
4168
5018
|
async function streamAnthropicCompletion(provider, apiKey, options, messageId, callbacks, logger) {
|
|
4169
5019
|
const hasImages = options.messages.some((m) => m.images && m.images.length > 0);
|
|
4170
5020
|
const MAX_TOKENS_FOR_THINKING = 16384;
|
|
4171
|
-
let effectiveMaxTokens = options.maxTokens
|
|
5021
|
+
let effectiveMaxTokens = _nullishCoalesce(options.maxTokens, () => ( 16384));
|
|
4172
5022
|
const thinkingMaxTokens = options.thinkLevel && options.thinkLevel !== "none" ? Math.min(effectiveMaxTokens, MAX_TOKENS_FOR_THINKING) : effectiveMaxTokens;
|
|
4173
5023
|
const thinkingConfig = options.thinkLevel && options.thinkLevel !== "none" ? _thinkingconfig.buildAnthropicThinking.call(void 0, options.model, options.thinkLevel, thinkingMaxTokens) : void 0;
|
|
4174
5024
|
if (thinkingConfig) {
|
|
@@ -4209,7 +5059,7 @@ async function streamAnthropicCompletion(provider, apiKey, options, messageId, c
|
|
|
4209
5059
|
temperature: thinkingConfig ? void 0 : options.temperature,
|
|
4210
5060
|
stream: true
|
|
4211
5061
|
};
|
|
4212
|
-
anthropicRequest =
|
|
5062
|
+
anthropicRequest = _chunkWYTEQ4Q5cjs.convertOpenAIToAnthropic.call(void 0, openaiRequest, config);
|
|
4213
5063
|
if (thinkingConfig) {
|
|
4214
5064
|
anthropicRequest.thinking = thinkingConfig;
|
|
4215
5065
|
delete anthropicRequest.temperature;
|
|
@@ -4223,7 +5073,7 @@ async function streamAnthropicCompletion(provider, apiKey, options, messageId, c
|
|
|
4223
5073
|
logger.info("Streaming Anthropic completion request", {
|
|
4224
5074
|
url: apiUrl,
|
|
4225
5075
|
model: anthropicRequest.model,
|
|
4226
|
-
messagesCount: _optionalChain([anthropicRequest, 'access',
|
|
5076
|
+
messagesCount: _optionalChain([anthropicRequest, 'access', _192 => _192.messages, 'optionalAccess', _193 => _193.length]),
|
|
4227
5077
|
max_tokens: anthropicRequest.max_tokens,
|
|
4228
5078
|
temperature: anthropicRequest.temperature,
|
|
4229
5079
|
stream: anthropicRequest.stream,
|
|
@@ -4240,7 +5090,7 @@ async function streamAnthropicCompletion(provider, apiKey, options, messageId, c
|
|
|
4240
5090
|
if (!response.ok) {
|
|
4241
5091
|
const errorText = await response.text();
|
|
4242
5092
|
logger.error("Anthropic API error", void 0, { status: response.status, errorText });
|
|
4243
|
-
_optionalChain([callbacks, 'access',
|
|
5093
|
+
_optionalChain([callbacks, 'access', _194 => _194.onError, 'optionalCall', _195 => _195(`API error (${response.status}): ${errorText}`)]);
|
|
4244
5094
|
return;
|
|
4245
5095
|
}
|
|
4246
5096
|
const result = await _chunkHQP3K7PUcjs.streamSSEResponse.call(void 0, response, "anthropic", {
|
|
@@ -4251,10 +5101,10 @@ async function streamAnthropicCompletion(provider, apiKey, options, messageId, c
|
|
|
4251
5101
|
});
|
|
4252
5102
|
logger.info("Anthropic stream complete", {
|
|
4253
5103
|
contentLength: result.content.length,
|
|
4254
|
-
reasoningLength: _optionalChain([result, 'access',
|
|
5104
|
+
reasoningLength: _optionalChain([result, 'access', _196 => _196.reasoning, 'optionalAccess', _197 => _197.length]) || 0,
|
|
4255
5105
|
blocksCount: result.blocks.length
|
|
4256
5106
|
});
|
|
4257
|
-
_optionalChain([callbacks, 'access',
|
|
5107
|
+
_optionalChain([callbacks, 'access', _198 => _198.onDone, 'optionalCall', _199 => _199(
|
|
4258
5108
|
{
|
|
4259
5109
|
id: messageId,
|
|
4260
5110
|
role: "assistant",
|
|
@@ -4280,7 +5130,7 @@ async function streamGeminiCompletion(provider, apiKey, options, messageId, call
|
|
|
4280
5130
|
const request = {
|
|
4281
5131
|
contents,
|
|
4282
5132
|
generationConfig: {
|
|
4283
|
-
...options.maxTokens ? { maxOutputTokens: options.maxTokens } : {},
|
|
5133
|
+
...options.maxTokens !== void 0 ? { maxOutputTokens: options.maxTokens } : {},
|
|
4284
5134
|
...options.temperature !== void 0 ? { temperature: options.temperature } : {}
|
|
4285
5135
|
}
|
|
4286
5136
|
};
|
|
@@ -4310,7 +5160,7 @@ async function streamGeminiCompletion(provider, apiKey, options, messageId, call
|
|
|
4310
5160
|
if (!response.ok) {
|
|
4311
5161
|
const errorText = await response.text();
|
|
4312
5162
|
logger.error("Gemini API error", void 0, { status: response.status, errorText });
|
|
4313
|
-
_optionalChain([callbacks, 'access',
|
|
5163
|
+
_optionalChain([callbacks, 'access', _200 => _200.onError, 'optionalCall', _201 => _201(`API error (${response.status}): ${errorText}`)]);
|
|
4314
5164
|
return;
|
|
4315
5165
|
}
|
|
4316
5166
|
const result = await _chunkHQP3K7PUcjs.streamSSEResponse.call(void 0, response, "gemini", {
|
|
@@ -4319,7 +5169,7 @@ async function streamGeminiCompletion(provider, apiKey, options, messageId, call
|
|
|
4319
5169
|
onError: callbacks.onError
|
|
4320
5170
|
});
|
|
4321
5171
|
logger.info("Gemini stream complete", { contentLength: result.content.length });
|
|
4322
|
-
_optionalChain([callbacks, 'access',
|
|
5172
|
+
_optionalChain([callbacks, 'access', _202 => _202.onDone, 'optionalCall', _203 => _203(
|
|
4323
5173
|
{
|
|
4324
5174
|
id: messageId,
|
|
4325
5175
|
role: "assistant",
|
|
@@ -4344,7 +5194,7 @@ async function streamOpenAIResponseCompletion(provider, apiKey, options, message
|
|
|
4344
5194
|
model: options.model,
|
|
4345
5195
|
input,
|
|
4346
5196
|
stream: true,
|
|
4347
|
-
...options.maxTokens ? { max_output_tokens: options.maxTokens } : {},
|
|
5197
|
+
...options.maxTokens !== void 0 ? { max_output_tokens: options.maxTokens } : {},
|
|
4348
5198
|
...options.temperature !== void 0 ? { temperature: options.temperature } : {}
|
|
4349
5199
|
};
|
|
4350
5200
|
if (options.thinkLevel && options.thinkLevel !== "none") {
|
|
@@ -4371,7 +5221,7 @@ async function streamOpenAIResponseCompletion(provider, apiKey, options, message
|
|
|
4371
5221
|
});
|
|
4372
5222
|
if (!response.ok) {
|
|
4373
5223
|
const errorText = await response.text();
|
|
4374
|
-
_optionalChain([callbacks, 'access',
|
|
5224
|
+
_optionalChain([callbacks, 'access', _204 => _204.onError, 'optionalCall', _205 => _205(`API error (${response.status}): ${errorText}`)]);
|
|
4375
5225
|
return;
|
|
4376
5226
|
}
|
|
4377
5227
|
const result = await _chunkHQP3K7PUcjs.streamSSEResponse.call(void 0, response, "openai-response", {
|
|
@@ -4380,7 +5230,7 @@ async function streamOpenAIResponseCompletion(provider, apiKey, options, message
|
|
|
4380
5230
|
onError: callbacks.onError
|
|
4381
5231
|
});
|
|
4382
5232
|
logger.info("OpenAI Response API stream complete", { contentLength: result.content.length });
|
|
4383
|
-
_optionalChain([callbacks, 'access',
|
|
5233
|
+
_optionalChain([callbacks, 'access', _206 => _206.onDone, 'optionalCall', _207 => _207(
|
|
4384
5234
|
{
|
|
4385
5235
|
id: messageId,
|
|
4386
5236
|
role: "assistant",
|
|
@@ -4401,59 +5251,20 @@ async function streamOpenAIResponseCompletion(provider, apiKey, options, message
|
|
|
4401
5251
|
|
|
4402
5252
|
|
|
4403
5253
|
|
|
4404
|
-
async function resolveEffectiveMaxTokens(llmConfig,
|
|
5254
|
+
async function resolveEffectiveMaxTokens(llmConfig, _getProvider, logger, _providerId, _modelId, sessionMaxTokens) {
|
|
4405
5255
|
if (sessionMaxTokens !== void 0 && sessionMaxTokens > 0) {
|
|
4406
5256
|
logger.debug("Using session maxTokens", { sessionMaxTokens });
|
|
4407
5257
|
return sessionMaxTokens;
|
|
4408
5258
|
}
|
|
4409
5259
|
try {
|
|
4410
5260
|
const globalParams = await llmConfig.getGlobalModelParameters();
|
|
4411
|
-
if (_optionalChain([globalParams, 'optionalAccess',
|
|
5261
|
+
if (_optionalChain([globalParams, 'optionalAccess', _208 => _208.maxTokens, 'optionalAccess', _209 => _209.enabled]) && globalParams.maxTokens.value > 0) {
|
|
4412
5262
|
logger.debug("Using global maxTokens", { maxTokens: globalParams.maxTokens.value });
|
|
4413
5263
|
return globalParams.maxTokens.value;
|
|
4414
5264
|
}
|
|
4415
5265
|
} catch (err) {
|
|
4416
5266
|
logger.warn("Failed to get global params", err instanceof Error ? err : void 0);
|
|
4417
5267
|
}
|
|
4418
|
-
const MAX_TOKENS_CAP = 131072;
|
|
4419
|
-
const provider = await getProvider(providerId);
|
|
4420
|
-
if (provider) {
|
|
4421
|
-
const modelConfig = _optionalChain([provider, 'access', _172 => _172.modelConfigs, 'optionalAccess', _173 => _173.find, 'call', _174 => _174((m) => m.id === modelId)]);
|
|
4422
|
-
if (_optionalChain([modelConfig, 'optionalAccess', _175 => _175.maxTokens]) && modelConfig.maxTokens > 0) {
|
|
4423
|
-
const cappedMaxTokens = Math.min(modelConfig.maxTokens, MAX_TOKENS_CAP);
|
|
4424
|
-
logger.debug("Using model config maxTokens", {
|
|
4425
|
-
maxTokens: modelConfig.maxTokens,
|
|
4426
|
-
cappedMaxTokens
|
|
4427
|
-
});
|
|
4428
|
-
return cappedMaxTokens;
|
|
4429
|
-
}
|
|
4430
|
-
if (provider.modelGroups) {
|
|
4431
|
-
for (const group of provider.modelGroups) {
|
|
4432
|
-
const model = _optionalChain([group, 'access', _176 => _176.models, 'optionalAccess', _177 => _177.find, 'call', _178 => _178((m) => m.id === modelId)]);
|
|
4433
|
-
if (_optionalChain([model, 'optionalAccess', _179 => _179.maxTokens]) && model.maxTokens > 0) {
|
|
4434
|
-
const cappedMaxTokens = Math.min(model.maxTokens, MAX_TOKENS_CAP);
|
|
4435
|
-
logger.debug("Using modelGroup model maxTokens", {
|
|
4436
|
-
maxTokens: model.maxTokens,
|
|
4437
|
-
cappedMaxTokens
|
|
4438
|
-
});
|
|
4439
|
-
return cappedMaxTokens;
|
|
4440
|
-
}
|
|
4441
|
-
}
|
|
4442
|
-
}
|
|
4443
|
-
}
|
|
4444
|
-
try {
|
|
4445
|
-
const discoveredMaxTokens = await llmConfig.getDiscoveredModelMaxTokens(providerId, modelId);
|
|
4446
|
-
if (discoveredMaxTokens && discoveredMaxTokens > 0) {
|
|
4447
|
-
const cappedMaxTokens = Math.min(discoveredMaxTokens, MAX_TOKENS_CAP);
|
|
4448
|
-
logger.debug("Using discovered model maxTokens", {
|
|
4449
|
-
discoveredMaxTokens,
|
|
4450
|
-
cappedMaxTokens
|
|
4451
|
-
});
|
|
4452
|
-
return cappedMaxTokens;
|
|
4453
|
-
}
|
|
4454
|
-
} catch (err) {
|
|
4455
|
-
logger.warn("Failed to get discovered model maxTokens", err instanceof Error ? err : void 0);
|
|
4456
|
-
}
|
|
4457
5268
|
logger.debug("No maxTokens configured, returning undefined");
|
|
4458
5269
|
return void 0;
|
|
4459
5270
|
}
|
|
@@ -4475,7 +5286,7 @@ async function resolveThinkingBudget(getProvider, logger, providerId, modelId, m
|
|
|
4475
5286
|
}
|
|
4476
5287
|
const thinkingBudget = _thinkingconfig.calculateThinkingBudget.call(void 0, modelId, thinkLevel, maxTokens);
|
|
4477
5288
|
const provider = await getProvider(providerId);
|
|
4478
|
-
const providerName = _optionalChain([provider, 'optionalAccess',
|
|
5289
|
+
const providerName = _optionalChain([provider, 'optionalAccess', _210 => _210.name, 'optionalAccess', _211 => _211.toLowerCase, 'call', _212 => _212()]) || "";
|
|
4479
5290
|
const apiFormat = provider ? _chunkA2YMUCBTcjs.resolveApiFormat.call(void 0, provider) : "openai";
|
|
4480
5291
|
if (apiFormat === "anthropic" || providerName === "anthropic" || providerName.includes("claude")) {
|
|
4481
5292
|
const thinkingConfig = _thinkingconfig.buildAnthropicThinking.call(void 0, modelId, thinkLevel, maxTokens);
|
|
@@ -4512,7 +5323,7 @@ function logToolFormat(tools, logger) {
|
|
|
4512
5323
|
tools: openaiTools.map((t) => t.function.name),
|
|
4513
5324
|
firstTool: {
|
|
4514
5325
|
name: firstTool.function.name,
|
|
4515
|
-
description: _optionalChain([firstTool, 'access',
|
|
5326
|
+
description: _optionalChain([firstTool, 'access', _213 => _213.function, 'access', _214 => _214.description, 'optionalAccess', _215 => _215.slice, 'call', _216 => _216(0, 100)]),
|
|
4516
5327
|
parameters: firstTool.function.parameters
|
|
4517
5328
|
}
|
|
4518
5329
|
});
|
|
@@ -4523,7 +5334,7 @@ function logToolFormat(tools, logger) {
|
|
|
4523
5334
|
tools: anthropicTools.map((t) => t.name),
|
|
4524
5335
|
firstTool: {
|
|
4525
5336
|
name: firstTool.name,
|
|
4526
|
-
description: _optionalChain([firstTool, 'access',
|
|
5337
|
+
description: _optionalChain([firstTool, 'access', _217 => _217.description, 'optionalAccess', _218 => _218.slice, 'call', _219 => _219(0, 100)]),
|
|
4527
5338
|
input_schema: firstTool.input_schema
|
|
4528
5339
|
}
|
|
4529
5340
|
});
|
|
@@ -4534,9 +5345,9 @@ function logToolFormat(tools, logger) {
|
|
|
4534
5345
|
count: allDeclarations.length,
|
|
4535
5346
|
tools: allDeclarations.map((t) => t.name),
|
|
4536
5347
|
firstTool: {
|
|
4537
|
-
name: _optionalChain([allDeclarations, 'access',
|
|
4538
|
-
description: _optionalChain([allDeclarations, 'access',
|
|
4539
|
-
parameters: _optionalChain([allDeclarations, 'access',
|
|
5348
|
+
name: _optionalChain([allDeclarations, 'access', _220 => _220[0], 'optionalAccess', _221 => _221.name]),
|
|
5349
|
+
description: _optionalChain([allDeclarations, 'access', _222 => _222[0], 'optionalAccess', _223 => _223.description, 'optionalAccess', _224 => _224.slice, 'call', _225 => _225(0, 100)]),
|
|
5350
|
+
parameters: _optionalChain([allDeclarations, 'access', _226 => _226[0], 'optionalAccess', _227 => _227.parameters])
|
|
4540
5351
|
}
|
|
4541
5352
|
});
|
|
4542
5353
|
}
|
|
@@ -4556,7 +5367,8 @@ function buildToolRequest(apiFormat, conversationMessages, actualModel, options,
|
|
|
4556
5367
|
}
|
|
4557
5368
|
requestBody = {
|
|
4558
5369
|
contents,
|
|
4559
|
-
tools: options.tools
|
|
5370
|
+
tools: options.tools,
|
|
5371
|
+
...options.maxTokens !== void 0 ? { generationConfig: { maxOutputTokens: options.maxTokens } } : {}
|
|
4560
5372
|
};
|
|
4561
5373
|
url = _chunkA2YMUCBTcjs.buildProviderApiUrl.call(void 0, provider, { model: actualModel, stream: true });
|
|
4562
5374
|
} else if (apiFormat === "anthropic") {
|
|
@@ -4566,7 +5378,10 @@ function buildToolRequest(apiFormat, conversationMessages, actualModel, options,
|
|
|
4566
5378
|
role: m.role,
|
|
4567
5379
|
content: m.content
|
|
4568
5380
|
})),
|
|
4569
|
-
|
|
5381
|
+
// Native Anthropic Messages requires this field. Resolve an absent
|
|
5382
|
+
// caller cap to the model's real ceiling rather than a small constant —
|
|
5383
|
+
// see `resolveAnthropicMaxTokens`.
|
|
5384
|
+
max_tokens: _chunk4VLRHHFEcjs.resolveAnthropicMaxTokens.call(void 0, actualModel, options.maxTokens),
|
|
4570
5385
|
temperature: _nullishCoalesce(options.temperature, () => ( 0.7)),
|
|
4571
5386
|
stream: true,
|
|
4572
5387
|
tools: options.tools
|
|
@@ -4583,7 +5398,7 @@ function buildToolRequest(apiFormat, conversationMessages, actualModel, options,
|
|
|
4583
5398
|
role: m.role,
|
|
4584
5399
|
content: m.content
|
|
4585
5400
|
})),
|
|
4586
|
-
max_tokens: options.maxTokens
|
|
5401
|
+
...options.maxTokens !== void 0 ? { max_tokens: options.maxTokens } : {},
|
|
4587
5402
|
temperature: _nullishCoalesce(options.temperature, () => ( 0.7)),
|
|
4588
5403
|
stream: true,
|
|
4589
5404
|
tools: options.tools
|
|
@@ -4595,7 +5410,7 @@ function buildToolRequest(apiFormat, conversationMessages, actualModel, options,
|
|
|
4595
5410
|
function extractDeltaContent(rawJson, apiFormat) {
|
|
4596
5411
|
const json = rawJson;
|
|
4597
5412
|
if (apiFormat === "google") {
|
|
4598
|
-
const parts = _optionalChain([json, 'access',
|
|
5413
|
+
const parts = _optionalChain([json, 'access', _228 => _228.candidates, 'optionalAccess', _229 => _229[0], 'optionalAccess', _230 => _230.content, 'optionalAccess', _231 => _231.parts]) || [];
|
|
4599
5414
|
let text = "";
|
|
4600
5415
|
for (const part of parts) {
|
|
4601
5416
|
if (part.thought === true) continue;
|
|
@@ -4603,15 +5418,15 @@ function extractDeltaContent(rawJson, apiFormat) {
|
|
|
4603
5418
|
}
|
|
4604
5419
|
return text;
|
|
4605
5420
|
} else if (apiFormat === "anthropic") {
|
|
4606
|
-
return _optionalChain([json, 'access',
|
|
5421
|
+
return _optionalChain([json, 'access', _232 => _232.delta, 'optionalAccess', _233 => _233.text]) || "";
|
|
4607
5422
|
} else {
|
|
4608
|
-
return _optionalChain([json, 'access',
|
|
5423
|
+
return _optionalChain([json, 'access', _234 => _234.choices, 'optionalAccess', _235 => _235[0], 'optionalAccess', _236 => _236.delta, 'optionalAccess', _237 => _237.content]) || "";
|
|
4609
5424
|
}
|
|
4610
5425
|
}
|
|
4611
5426
|
function extractDeltaReasoning(rawJson, apiFormat) {
|
|
4612
5427
|
const json = rawJson;
|
|
4613
5428
|
if (apiFormat === "google") {
|
|
4614
|
-
const parts = _optionalChain([json, 'access',
|
|
5429
|
+
const parts = _optionalChain([json, 'access', _238 => _238.candidates, 'optionalAccess', _239 => _239[0], 'optionalAccess', _240 => _240.content, 'optionalAccess', _241 => _241.parts]) || [];
|
|
4615
5430
|
let reasoning = "";
|
|
4616
5431
|
for (const part of parts) {
|
|
4617
5432
|
if (part.thought === true && part.text) reasoning += part.text;
|
|
@@ -4620,14 +5435,14 @@ function extractDeltaReasoning(rawJson, apiFormat) {
|
|
|
4620
5435
|
} else if (apiFormat === "anthropic") {
|
|
4621
5436
|
return "";
|
|
4622
5437
|
} else {
|
|
4623
|
-
const delta = _optionalChain([json, 'access',
|
|
4624
|
-
return (_optionalChain([delta, 'optionalAccess',
|
|
5438
|
+
const delta = _optionalChain([json, 'access', _242 => _242.choices, 'optionalAccess', _243 => _243[0], 'optionalAccess', _244 => _244.delta]);
|
|
5439
|
+
return (_optionalChain([delta, 'optionalAccess', _245 => _245.thinking, 'optionalAccess', _246 => _246.content]) || "") + (_optionalChain([delta, 'optionalAccess', _247 => _247.reasoning_content]) || "");
|
|
4625
5440
|
}
|
|
4626
5441
|
}
|
|
4627
5442
|
function extractToolCalls(rawJson, apiFormat, toolCalls, callbacks, logger, pendingOpenAIToolCalls) {
|
|
4628
5443
|
const json = rawJson;
|
|
4629
5444
|
if (apiFormat === "google") {
|
|
4630
|
-
const parts = _optionalChain([json, 'access',
|
|
5445
|
+
const parts = _optionalChain([json, 'access', _248 => _248.candidates, 'optionalAccess', _249 => _249[0], 'optionalAccess', _250 => _250.content, 'optionalAccess', _251 => _251.parts]) || [];
|
|
4631
5446
|
for (const part of parts) {
|
|
4632
5447
|
if (part.functionCall) {
|
|
4633
5448
|
logger.info("Function call detected", { functionCall: part.functionCall });
|
|
@@ -4637,13 +5452,13 @@ function extractToolCalls(rawJson, apiFormat, toolCalls, callbacks, logger, pend
|
|
|
4637
5452
|
args: part.functionCall.args || {}
|
|
4638
5453
|
};
|
|
4639
5454
|
toolCalls.push(toolCall);
|
|
4640
|
-
_optionalChain([callbacks, 'access',
|
|
5455
|
+
_optionalChain([callbacks, 'access', _252 => _252.onToolCall, 'optionalCall', _253 => _253(toolCall)]);
|
|
4641
5456
|
logger.info("Tool called", { toolName: toolCall.name });
|
|
4642
5457
|
}
|
|
4643
5458
|
}
|
|
4644
5459
|
} else if (apiFormat !== "anthropic") {
|
|
4645
|
-
const delta = _optionalChain([json, 'access',
|
|
4646
|
-
if (_optionalChain([delta, 'optionalAccess',
|
|
5460
|
+
const delta = _optionalChain([json, 'access', _254 => _254.choices, 'optionalAccess', _255 => _255[0], 'optionalAccess', _256 => _256.delta]);
|
|
5461
|
+
if (_optionalChain([delta, 'optionalAccess', _257 => _257.tool_calls]) && pendingOpenAIToolCalls) {
|
|
4647
5462
|
for (const tc of delta.tool_calls) {
|
|
4648
5463
|
const index = _nullishCoalesce(tc.index, () => ( 0));
|
|
4649
5464
|
let pending = pendingOpenAIToolCalls.get(index);
|
|
@@ -4652,8 +5467,8 @@ function extractToolCalls(rawJson, apiFormat, toolCalls, callbacks, logger, pend
|
|
|
4652
5467
|
pendingOpenAIToolCalls.set(index, pending);
|
|
4653
5468
|
}
|
|
4654
5469
|
if (tc.id) pending.id = tc.id;
|
|
4655
|
-
if (_optionalChain([tc, 'access',
|
|
4656
|
-
if (_optionalChain([tc, 'access',
|
|
5470
|
+
if (_optionalChain([tc, 'access', _258 => _258.function, 'optionalAccess', _259 => _259.name])) pending.name += tc.function.name;
|
|
5471
|
+
if (_optionalChain([tc, 'access', _260 => _260.function, 'optionalAccess', _261 => _261.arguments])) pending.arguments += tc.function.arguments;
|
|
4657
5472
|
}
|
|
4658
5473
|
}
|
|
4659
5474
|
}
|
|
@@ -4668,7 +5483,7 @@ function finalizeOpenAIToolCalls(pendingOpenAIToolCalls, toolCalls, callbacks, l
|
|
|
4668
5483
|
args: JSON.parse(pending.arguments || "{}")
|
|
4669
5484
|
};
|
|
4670
5485
|
toolCalls.push(toolCall);
|
|
4671
|
-
_optionalChain([callbacks, 'access',
|
|
5486
|
+
_optionalChain([callbacks, 'access', _262 => _262.onToolCall, 'optionalCall', _263 => _263(toolCall)]);
|
|
4672
5487
|
logger.info("Tool called (OpenAI)", { toolName: toolCall.name, args: toolCall.args });
|
|
4673
5488
|
} catch (e) {
|
|
4674
5489
|
logger.error("Failed to parse OpenAI tool call arguments", e instanceof Error ? e : void 0, {
|
|
@@ -4682,38 +5497,38 @@ function finalizeOpenAIToolCalls(pendingOpenAIToolCalls, toolCalls, callbacks, l
|
|
|
4682
5497
|
function parseStreamChunk(rawJson, apiFormat, callbacks, logger) {
|
|
4683
5498
|
const json = rawJson;
|
|
4684
5499
|
if (apiFormat === "google") {
|
|
4685
|
-
const candidate = _optionalChain([json, 'access',
|
|
5500
|
+
const candidate = _optionalChain([json, 'access', _264 => _264.candidates, 'optionalAccess', _265 => _265[0]]);
|
|
4686
5501
|
if (!candidate) {
|
|
4687
5502
|
logger.warn("No candidate found in Gemini response");
|
|
4688
5503
|
return;
|
|
4689
5504
|
}
|
|
4690
|
-
const parts = _optionalChain([candidate, 'access',
|
|
5505
|
+
const parts = _optionalChain([candidate, 'access', _266 => _266.content, 'optionalAccess', _267 => _267.parts]) || [];
|
|
4691
5506
|
for (const part of parts) {
|
|
4692
5507
|
if (part.thought === true && part.text) {
|
|
4693
|
-
_optionalChain([callbacks, 'access',
|
|
5508
|
+
_optionalChain([callbacks, 'access', _268 => _268.onReasoning, 'optionalCall', _269 => _269(part.text)]);
|
|
4694
5509
|
continue;
|
|
4695
5510
|
} else if (part.thoughtSignature && !part.thought) {
|
|
4696
5511
|
logger.debug("Gemini returned thoughtSignature without thought content");
|
|
4697
5512
|
}
|
|
4698
5513
|
if (part.text) {
|
|
4699
|
-
_optionalChain([callbacks, 'access',
|
|
5514
|
+
_optionalChain([callbacks, 'access', _270 => _270.onDelta, 'optionalCall', _271 => _271(part.text)]);
|
|
4700
5515
|
}
|
|
4701
5516
|
}
|
|
4702
5517
|
} else if (apiFormat === "anthropic") {
|
|
4703
5518
|
const delta = json.delta;
|
|
4704
|
-
if (_optionalChain([delta, 'optionalAccess',
|
|
4705
|
-
_optionalChain([callbacks, 'access',
|
|
5519
|
+
if (_optionalChain([delta, 'optionalAccess', _272 => _272.text])) {
|
|
5520
|
+
_optionalChain([callbacks, 'access', _273 => _273.onDelta, 'optionalCall', _274 => _274(delta.text)]);
|
|
4706
5521
|
}
|
|
4707
5522
|
} else {
|
|
4708
|
-
const delta = _optionalChain([json, 'access',
|
|
4709
|
-
if (_optionalChain([delta, 'optionalAccess',
|
|
4710
|
-
_optionalChain([callbacks, 'access',
|
|
5523
|
+
const delta = _optionalChain([json, 'access', _275 => _275.choices, 'optionalAccess', _276 => _276[0], 'optionalAccess', _277 => _277.delta]);
|
|
5524
|
+
if (_optionalChain([delta, 'optionalAccess', _278 => _278.content])) {
|
|
5525
|
+
_optionalChain([callbacks, 'access', _279 => _279.onDelta, 'optionalCall', _280 => _280(delta.content)]);
|
|
4711
5526
|
}
|
|
4712
|
-
if (_optionalChain([delta, 'optionalAccess',
|
|
4713
|
-
_optionalChain([callbacks, 'access',
|
|
5527
|
+
if (_optionalChain([delta, 'optionalAccess', _281 => _281.thinking, 'optionalAccess', _282 => _282.content])) {
|
|
5528
|
+
_optionalChain([callbacks, 'access', _283 => _283.onReasoning, 'optionalCall', _284 => _284(delta.thinking.content)]);
|
|
4714
5529
|
}
|
|
4715
|
-
if (_optionalChain([delta, 'optionalAccess',
|
|
4716
|
-
_optionalChain([callbacks, 'access',
|
|
5530
|
+
if (_optionalChain([delta, 'optionalAccess', _285 => _285.reasoning_content])) {
|
|
5531
|
+
_optionalChain([callbacks, 'access', _286 => _286.onReasoning, 'optionalCall', _287 => _287(delta.reasoning_content)]);
|
|
4717
5532
|
}
|
|
4718
5533
|
}
|
|
4719
5534
|
}
|
|
@@ -4726,7 +5541,7 @@ function buildIterationBlocks(iteration, content, reasoning, blocks, callbacks)
|
|
|
4726
5541
|
content: reasoning
|
|
4727
5542
|
};
|
|
4728
5543
|
blocks.push(thinkingBlock);
|
|
4729
|
-
_optionalChain([callbacks, 'access',
|
|
5544
|
+
_optionalChain([callbacks, 'access', _288 => _288.onBlock, 'optionalCall', _289 => _289(thinkingBlock)]);
|
|
4730
5545
|
}
|
|
4731
5546
|
if (content && content.trim()) {
|
|
4732
5547
|
const textBlock = {
|
|
@@ -4735,7 +5550,7 @@ function buildIterationBlocks(iteration, content, reasoning, blocks, callbacks)
|
|
|
4735
5550
|
content
|
|
4736
5551
|
};
|
|
4737
5552
|
blocks.push(textBlock);
|
|
4738
|
-
_optionalChain([callbacks, 'access',
|
|
5553
|
+
_optionalChain([callbacks, 'access', _290 => _290.onBlock, 'optionalCall', _291 => _291(textBlock)]);
|
|
4739
5554
|
}
|
|
4740
5555
|
}
|
|
4741
5556
|
async function executeToolCalls(toolCalls, mcpTools, mcpService, blocks, callbacks, logger, builtinExecutor) {
|
|
@@ -4750,7 +5565,7 @@ async function executeToolCalls(toolCalls, mcpTools, mcpService, blocks, callbac
|
|
|
4750
5565
|
status: "running"
|
|
4751
5566
|
};
|
|
4752
5567
|
blocks.push(toolUseBlock);
|
|
4753
|
-
_optionalChain([callbacks, 'access',
|
|
5568
|
+
_optionalChain([callbacks, 'access', _292 => _292.onBlock, 'optionalCall', _293 => _293(toolUseBlock)]);
|
|
4754
5569
|
try {
|
|
4755
5570
|
logger.info("Executing tool", { toolName: toolCall.name });
|
|
4756
5571
|
const mcpTool = mcpTools.find((t) => t.id === toolCall.name);
|
|
@@ -4773,8 +5588,8 @@ async function executeToolCalls(toolCalls, mcpTools, mcpService, blocks, callbac
|
|
|
4773
5588
|
result = { isError: true, content: [{ type: "text", text: "MCP service not available" }] };
|
|
4774
5589
|
}
|
|
4775
5590
|
logger.info("Tool result received", { result });
|
|
4776
|
-
_optionalChain([callbacks, 'access',
|
|
4777
|
-
const resultText = _optionalChain([result, 'access',
|
|
5591
|
+
_optionalChain([callbacks, 'access', _294 => _294.onToolResult, 'optionalCall', _295 => _295(toolCall.id, result)]);
|
|
5592
|
+
const resultText = _optionalChain([result, 'access', _296 => _296.content, 'optionalAccess', _297 => _297[0], 'optionalAccess', _298 => _298.text]) || JSON.stringify(result);
|
|
4778
5593
|
const toolResultBlock = {
|
|
4779
5594
|
id: `${toolCall.id}_result`,
|
|
4780
5595
|
type: "tool_result",
|
|
@@ -4784,11 +5599,11 @@ async function executeToolCalls(toolCalls, mcpTools, mcpService, blocks, callbac
|
|
|
4784
5599
|
isError: result.isError
|
|
4785
5600
|
};
|
|
4786
5601
|
blocks.push(toolResultBlock);
|
|
4787
|
-
_optionalChain([callbacks, 'access',
|
|
5602
|
+
_optionalChain([callbacks, 'access', _299 => _299.onBlock, 'optionalCall', _300 => _300(toolResultBlock)]);
|
|
4788
5603
|
const toolUseBlockRef = blocks.find((b) => b.id === `${toolCall.id}_use`);
|
|
4789
5604
|
if (toolUseBlockRef && toolUseBlockRef.type === "tool_use") {
|
|
4790
5605
|
toolUseBlockRef.status = result.isError ? "error" : "completed";
|
|
4791
|
-
_optionalChain([callbacks, 'access',
|
|
5606
|
+
_optionalChain([callbacks, 'access', _301 => _301.onBlock, 'optionalCall', _302 => _302({ ...toolUseBlockRef })]);
|
|
4792
5607
|
}
|
|
4793
5608
|
toolResults.push({ toolCall, result });
|
|
4794
5609
|
} catch (error) {
|
|
@@ -4798,7 +5613,7 @@ async function executeToolCalls(toolCalls, mcpTools, mcpService, blocks, callbac
|
|
|
4798
5613
|
isError: true,
|
|
4799
5614
|
content: [{ type: "text", text: `Error: ${errorMessage}` }]
|
|
4800
5615
|
};
|
|
4801
|
-
_optionalChain([callbacks, 'access',
|
|
5616
|
+
_optionalChain([callbacks, 'access', _303 => _303.onToolResult, 'optionalCall', _304 => _304(toolCall.id, errorResult)]);
|
|
4802
5617
|
const errorToolResultBlock = {
|
|
4803
5618
|
id: `${toolCall.id}_result`,
|
|
4804
5619
|
type: "tool_result",
|
|
@@ -4808,11 +5623,11 @@ async function executeToolCalls(toolCalls, mcpTools, mcpService, blocks, callbac
|
|
|
4808
5623
|
isError: true
|
|
4809
5624
|
};
|
|
4810
5625
|
blocks.push(errorToolResultBlock);
|
|
4811
|
-
_optionalChain([callbacks, 'access',
|
|
5626
|
+
_optionalChain([callbacks, 'access', _305 => _305.onBlock, 'optionalCall', _306 => _306(errorToolResultBlock)]);
|
|
4812
5627
|
const errorToolUseBlockRef = blocks.find((b) => b.id === `${toolCall.id}_use`);
|
|
4813
5628
|
if (errorToolUseBlockRef && errorToolUseBlockRef.type === "tool_use") {
|
|
4814
5629
|
errorToolUseBlockRef.status = "error";
|
|
4815
|
-
_optionalChain([callbacks, 'access',
|
|
5630
|
+
_optionalChain([callbacks, 'access', _307 => _307.onBlock, 'optionalCall', _308 => _308({ ...errorToolUseBlockRef })]);
|
|
4816
5631
|
}
|
|
4817
5632
|
toolResults.push({ toolCall, result: errorResult });
|
|
4818
5633
|
}
|
|
@@ -4822,7 +5637,7 @@ async function executeToolCalls(toolCalls, mcpTools, mcpService, blocks, callbac
|
|
|
4822
5637
|
function mapToolArguments(args, mcpTool, logger) {
|
|
4823
5638
|
const mappedArgs = { ...args };
|
|
4824
5639
|
const toolSchema = mcpTool.inputSchema;
|
|
4825
|
-
if (_optionalChain([toolSchema, 'optionalAccess',
|
|
5640
|
+
if (_optionalChain([toolSchema, 'optionalAccess', _309 => _309.properties])) {
|
|
4826
5641
|
const expectedParams = Object.keys(toolSchema.properties);
|
|
4827
5642
|
const paramMappings = {
|
|
4828
5643
|
"search_query": ["query", "q", "searchQuery", "search"],
|
|
@@ -4856,25 +5671,25 @@ async function streamWithTools(options, callbacks, mcpService, llmConfig, getPro
|
|
|
4856
5671
|
options.providerId,
|
|
4857
5672
|
options.model
|
|
4858
5673
|
);
|
|
4859
|
-
const actualProviderId = _optionalChain([routedInfo, 'optionalAccess',
|
|
4860
|
-
const actualModel = _optionalChain([routedInfo, 'optionalAccess',
|
|
5674
|
+
const actualProviderId = _optionalChain([routedInfo, 'optionalAccess', _310 => _310.actualProviderId]) || options.providerId;
|
|
5675
|
+
const actualModel = _optionalChain([routedInfo, 'optionalAccess', _311 => _311.actualModelId]) || options.model;
|
|
4861
5676
|
const provider = await getProvider(actualProviderId);
|
|
4862
5677
|
if (!provider) {
|
|
4863
|
-
_optionalChain([callbacks, 'access',
|
|
5678
|
+
_optionalChain([callbacks, 'access', _312 => _312.onError, 'optionalCall', _313 => _313(`Provider not found: ${actualProviderId}`)]);
|
|
4864
5679
|
return;
|
|
4865
5680
|
}
|
|
4866
5681
|
if (!provider.enabled) {
|
|
4867
|
-
_optionalChain([callbacks, 'access',
|
|
5682
|
+
_optionalChain([callbacks, 'access', _314 => _314.onError, 'optionalCall', _315 => _315(`Provider is disabled: ${provider.name}`)]);
|
|
4868
5683
|
return;
|
|
4869
5684
|
}
|
|
4870
5685
|
const { apiKey: effectiveKey } = _chunkA2YMUCBTcjs.resolveProviderEndpoint.call(void 0, provider);
|
|
4871
5686
|
const apiKey = resolveApiKey2(effectiveKey);
|
|
4872
5687
|
if (!apiKey) {
|
|
4873
|
-
_optionalChain([callbacks, 'access',
|
|
5688
|
+
_optionalChain([callbacks, 'access', _316 => _316.onError, 'optionalCall', _317 => _317("API key not configured")]);
|
|
4874
5689
|
return;
|
|
4875
5690
|
}
|
|
4876
5691
|
const messageId = `msg_${Date.now()}_${Math.random().toString(36).slice(2)}`;
|
|
4877
|
-
_optionalChain([callbacks, 'access',
|
|
5692
|
+
_optionalChain([callbacks, 'access', _318 => _318.onStart, 'optionalCall', _319 => _319(messageId)]);
|
|
4878
5693
|
const globalParams = await llmConfig.getGlobalModelParameters();
|
|
4879
5694
|
const MAX_ITERATIONS = _nullishCoalesce(globalParams.toolMaxTurns, () => ( 100));
|
|
4880
5695
|
let iteration = 0;
|
|
@@ -4921,12 +5736,12 @@ async function streamWithTools(options, callbacks, mcpService, llmConfig, getPro
|
|
|
4921
5736
|
});
|
|
4922
5737
|
if (!response.ok) {
|
|
4923
5738
|
const errorText = await response.text();
|
|
4924
|
-
_optionalChain([callbacks, 'access',
|
|
5739
|
+
_optionalChain([callbacks, 'access', _320 => _320.onError, 'optionalCall', _321 => _321(`API error (${response.status}): ${errorText}`)]);
|
|
4925
5740
|
return;
|
|
4926
5741
|
}
|
|
4927
|
-
const reader = _optionalChain([response, 'access',
|
|
5742
|
+
const reader = _optionalChain([response, 'access', _322 => _322.body, 'optionalAccess', _323 => _323.getReader, 'call', _324 => _324()]);
|
|
4928
5743
|
if (!reader) {
|
|
4929
|
-
_optionalChain([callbacks, 'access',
|
|
5744
|
+
_optionalChain([callbacks, 'access', _325 => _325.onError, 'optionalCall', _326 => _326("No response body")]);
|
|
4930
5745
|
return;
|
|
4931
5746
|
}
|
|
4932
5747
|
const decoder = new TextDecoder();
|
|
@@ -4959,7 +5774,7 @@ async function streamWithTools(options, callbacks, mcpService, llmConfig, getPro
|
|
|
4959
5774
|
logger.debug("Parsed JSON", { json });
|
|
4960
5775
|
if (json.error) {
|
|
4961
5776
|
logger.error("API Error", void 0, { error: json.error });
|
|
4962
|
-
_optionalChain([callbacks, 'access',
|
|
5777
|
+
_optionalChain([callbacks, 'access', _327 => _327.onError, 'optionalCall', _328 => _328(`API Error: ${json.error.message || JSON.stringify(json.error)}`)]);
|
|
4963
5778
|
return;
|
|
4964
5779
|
}
|
|
4965
5780
|
parseStreamChunk(json, apiFormat, callbacks, logger);
|
|
@@ -4992,7 +5807,7 @@ async function streamWithTools(options, callbacks, mcpService, llmConfig, getPro
|
|
|
4992
5807
|
toolCallsLength: toolCalls.length,
|
|
4993
5808
|
executableToolCallsLength: executableToolCalls.length,
|
|
4994
5809
|
hasMcpTools: !!options.mcpTools,
|
|
4995
|
-
mcpToolsLength: _optionalChain([options, 'access',
|
|
5810
|
+
mcpToolsLength: _optionalChain([options, 'access', _329 => _329.mcpTools, 'optionalAccess', _330 => _330.length]),
|
|
4996
5811
|
hasMcpService: !!mcpService
|
|
4997
5812
|
});
|
|
4998
5813
|
if (executableToolCalls.length > 0 && options.mcpTools && (mcpService || builtinExecutor)) {
|
|
@@ -5013,7 +5828,7 @@ async function streamWithTools(options, callbacks, mcpService, llmConfig, getPro
|
|
|
5013
5828
|
builtinExecutor
|
|
5014
5829
|
);
|
|
5015
5830
|
const toolResultsText = toolResults.map(({ toolCall, result }) => {
|
|
5016
|
-
const resultText = typeof result === "string" ? result : _optionalChain([result, 'access',
|
|
5831
|
+
const resultText = typeof result === "string" ? result : _optionalChain([result, 'access', _331 => _331.content, 'optionalAccess', _332 => _332[0], 'optionalAccess', _333 => _333.text]) || JSON.stringify(result);
|
|
5017
5832
|
return `Tool ${toolCall.name} result:
|
|
5018
5833
|
${resultText}`;
|
|
5019
5834
|
}).join("\n\n");
|
|
@@ -5031,12 +5846,12 @@ ${resultText}`;
|
|
|
5031
5846
|
}
|
|
5032
5847
|
} catch (streamError) {
|
|
5033
5848
|
logger.error("Stream processing error", streamError instanceof Error ? streamError : void 0);
|
|
5034
|
-
_optionalChain([callbacks, 'access',
|
|
5849
|
+
_optionalChain([callbacks, 'access', _334 => _334.onError, 'optionalCall', _335 => _335(`Stream error: ${streamError instanceof Error ? streamError.message : "Unknown error"}`)]);
|
|
5035
5850
|
return;
|
|
5036
5851
|
}
|
|
5037
5852
|
}
|
|
5038
5853
|
logger.info("Sending final callback", { blocksCount: blocks.length });
|
|
5039
|
-
_optionalChain([callbacks, 'access',
|
|
5854
|
+
_optionalChain([callbacks, 'access', _336 => _336.onDone, 'optionalCall', _337 => _337({
|
|
5040
5855
|
id: messageId,
|
|
5041
5856
|
role: "assistant",
|
|
5042
5857
|
content: finalContent,
|
|
@@ -5047,7 +5862,7 @@ ${resultText}`;
|
|
|
5047
5862
|
} catch (error) {
|
|
5048
5863
|
logger.error("Error in streamWithTools", error instanceof Error ? error : void 0);
|
|
5049
5864
|
const message = error instanceof Error ? error.message : "Unknown error";
|
|
5050
|
-
_optionalChain([callbacks, 'access',
|
|
5865
|
+
_optionalChain([callbacks, 'access', _338 => _338.onError, 'optionalCall', _339 => _339(message)]);
|
|
5051
5866
|
}
|
|
5052
5867
|
}
|
|
5053
5868
|
|
|
@@ -5073,21 +5888,33 @@ function readUsageFromOpenAIResponse(usage) {
|
|
|
5073
5888
|
var sharedExecutor2 = null;
|
|
5074
5889
|
function getSharedExecutor2() {
|
|
5075
5890
|
if (!sharedExecutor2) {
|
|
5076
|
-
sharedExecutor2 = new (0,
|
|
5891
|
+
sharedExecutor2 = new (0, _chunkIIRPUVPHcjs.TransformerChainExecutor)();
|
|
5077
5892
|
}
|
|
5078
5893
|
return sharedExecutor2;
|
|
5079
5894
|
}
|
|
5080
5895
|
async function resolveChainWithMain(llmConfig, providerId, model) {
|
|
5081
5896
|
return _chunkQXD4MV2Xcjs.resolveProviderChain.call(void 0, llmConfig, providerId, model);
|
|
5082
5897
|
}
|
|
5898
|
+
function buildUnifiedCompletionRequest(actualModel, options, stream) {
|
|
5899
|
+
return {
|
|
5900
|
+
model: actualModel,
|
|
5901
|
+
messages: options.messages.map((m) => ({
|
|
5902
|
+
role: m.role,
|
|
5903
|
+
content: m.content
|
|
5904
|
+
})),
|
|
5905
|
+
...options.maxTokens !== void 0 ? { max_tokens: options.maxTokens } : {},
|
|
5906
|
+
temperature: options.temperature,
|
|
5907
|
+
stream
|
|
5908
|
+
};
|
|
5909
|
+
}
|
|
5083
5910
|
async function completeWithTransformers(options, llmConfig, getProvider, resolveApiKey2, completeFallback, logger, recording) {
|
|
5084
5911
|
try {
|
|
5085
5912
|
const routedInfo = await llmConfig.resolveRoutedModel(
|
|
5086
5913
|
options.providerId,
|
|
5087
5914
|
options.model
|
|
5088
5915
|
);
|
|
5089
|
-
const actualProviderId = _optionalChain([routedInfo, 'optionalAccess',
|
|
5090
|
-
const actualModel = _optionalChain([routedInfo, 'optionalAccess',
|
|
5916
|
+
const actualProviderId = _optionalChain([routedInfo, 'optionalAccess', _340 => _340.actualProviderId]) || options.providerId;
|
|
5917
|
+
const actualModel = _optionalChain([routedInfo, 'optionalAccess', _341 => _341.actualModelId]) || options.model;
|
|
5091
5918
|
const provider = await getProvider(actualProviderId);
|
|
5092
5919
|
if (!provider) {
|
|
5093
5920
|
return { success: false, error: `Provider not found: ${actualProviderId}` };
|
|
@@ -5108,16 +5935,11 @@ async function completeWithTransformers(options, llmConfig, getProvider, resolve
|
|
|
5108
5935
|
if (!hasTransformers) {
|
|
5109
5936
|
return completeFallback(options);
|
|
5110
5937
|
}
|
|
5111
|
-
const unifiedRequest =
|
|
5112
|
-
|
|
5113
|
-
|
|
5114
|
-
|
|
5115
|
-
|
|
5116
|
-
})),
|
|
5117
|
-
max_tokens: options.maxTokens || 4096,
|
|
5118
|
-
temperature: options.temperature,
|
|
5119
|
-
stream: _nullishCoalesce(options.stream, () => ( false))
|
|
5120
|
-
};
|
|
5938
|
+
const unifiedRequest = buildUnifiedCompletionRequest(
|
|
5939
|
+
actualModel,
|
|
5940
|
+
options,
|
|
5941
|
+
_nullishCoalesce(options.stream, () => ( false))
|
|
5942
|
+
);
|
|
5121
5943
|
const transformerProvider = {
|
|
5122
5944
|
name: provider.name,
|
|
5123
5945
|
baseUrl: provider.api_base_url,
|
|
@@ -5125,7 +5947,7 @@ async function completeWithTransformers(options, llmConfig, getProvider, resolve
|
|
|
5125
5947
|
models: provider.models || []
|
|
5126
5948
|
};
|
|
5127
5949
|
const executor = getSharedExecutor2();
|
|
5128
|
-
const { response } = await
|
|
5950
|
+
const { response } = await _chunkMUHWHQVMcjs.executeProviderCall.call(void 0, {
|
|
5129
5951
|
executor,
|
|
5130
5952
|
request: unifiedRequest,
|
|
5131
5953
|
provider: transformerProvider,
|
|
@@ -5168,18 +5990,18 @@ async function completeWithTransformers(options, llmConfig, getProvider, resolve
|
|
|
5168
5990
|
{ endpointTransformer: void 0 }
|
|
5169
5991
|
);
|
|
5170
5992
|
const data = await transformedResponse.json();
|
|
5171
|
-
const choice = _optionalChain([data, 'access',
|
|
5993
|
+
const choice = _optionalChain([data, 'access', _342 => _342.choices, 'optionalAccess', _343 => _343[0]]);
|
|
5172
5994
|
if (!choice) {
|
|
5173
5995
|
return { success: false, error: "No choices in response" };
|
|
5174
5996
|
}
|
|
5175
|
-
const rawToolCalls = _optionalChain([choice, 'access',
|
|
5176
|
-
const toolCalls = _optionalChain([rawToolCalls, 'optionalAccess',
|
|
5997
|
+
const rawToolCalls = _optionalChain([choice, 'access', _344 => _344.message, 'optionalAccess', _345 => _345.tool_calls]);
|
|
5998
|
+
const toolCalls = _optionalChain([rawToolCalls, 'optionalAccess', _346 => _346.map, 'call', _347 => _347((tc) => ({
|
|
5177
5999
|
id: tc.id,
|
|
5178
6000
|
name: tc.function.name,
|
|
5179
6001
|
args: typeof tc.function.arguments === "string" ? JSON.parse(tc.function.arguments) : tc.function.arguments
|
|
5180
6002
|
}))]);
|
|
5181
6003
|
const tapped = readUsageFromOpenAIResponse(data.usage);
|
|
5182
|
-
if (_optionalChain([recording, 'optionalAccess',
|
|
6004
|
+
if (_optionalChain([recording, 'optionalAccess', _348 => _348.recorder]) && tapped) {
|
|
5183
6005
|
recording.recorder.record({
|
|
5184
6006
|
messageId: _nullishCoalesce(options.messageId, () => ( null)),
|
|
5185
6007
|
parentMessageId: _nullishCoalesce(options.parentMessageId, () => ( null)),
|
|
@@ -5197,9 +6019,9 @@ async function completeWithTransformers(options, llmConfig, getProvider, resolve
|
|
|
5197
6019
|
message: {
|
|
5198
6020
|
id: `msg_${Date.now()}`,
|
|
5199
6021
|
role: "assistant",
|
|
5200
|
-
content: _optionalChain([choice, 'access',
|
|
6022
|
+
content: _optionalChain([choice, 'access', _349 => _349.message, 'optionalAccess', _350 => _350.content]) || "",
|
|
5201
6023
|
timestamp: Date.now(),
|
|
5202
|
-
thinking: data.reasoning_content || _optionalChain([choice, 'access',
|
|
6024
|
+
thinking: data.reasoning_content || _optionalChain([choice, 'access', _351 => _351.message, 'optionalAccess', _352 => _352.thinking, 'optionalAccess', _353 => _353.content]) ? { content: data.reasoning_content || _optionalChain([choice, 'access', _354 => _354.message, 'optionalAccess', _355 => _355.thinking, 'optionalAccess', _356 => _356.content]) || "", signature: _optionalChain([choice, 'access', _357 => _357.message, 'optionalAccess', _358 => _358.thinking, 'optionalAccess', _359 => _359.signature]) } : void 0,
|
|
5203
6025
|
toolCalls
|
|
5204
6026
|
},
|
|
5205
6027
|
usage: data.usage ? {
|
|
@@ -5220,21 +6042,21 @@ async function completeStreamWithTransformers(options, callbacks, llmConfig, get
|
|
|
5220
6042
|
options.providerId,
|
|
5221
6043
|
options.model
|
|
5222
6044
|
);
|
|
5223
|
-
const actualProviderId = _optionalChain([routedInfo, 'optionalAccess',
|
|
5224
|
-
const actualModel = _optionalChain([routedInfo, 'optionalAccess',
|
|
6045
|
+
const actualProviderId = _optionalChain([routedInfo, 'optionalAccess', _360 => _360.actualProviderId]) || options.providerId;
|
|
6046
|
+
const actualModel = _optionalChain([routedInfo, 'optionalAccess', _361 => _361.actualModelId]) || options.model;
|
|
5225
6047
|
const provider = await getProvider(actualProviderId);
|
|
5226
6048
|
if (!provider) {
|
|
5227
|
-
_optionalChain([callbacks, 'access',
|
|
6049
|
+
_optionalChain([callbacks, 'access', _362 => _362.onError, 'optionalCall', _363 => _363(`Provider not found: ${actualProviderId}`)]);
|
|
5228
6050
|
return;
|
|
5229
6051
|
}
|
|
5230
6052
|
if (!provider.enabled) {
|
|
5231
|
-
_optionalChain([callbacks, 'access',
|
|
6053
|
+
_optionalChain([callbacks, 'access', _364 => _364.onError, 'optionalCall', _365 => _365(`Provider is disabled: ${provider.name}`)]);
|
|
5232
6054
|
return;
|
|
5233
6055
|
}
|
|
5234
6056
|
const { apiKey: effectiveKey } = _chunkA2YMUCBTcjs.resolveProviderEndpoint.call(void 0, provider);
|
|
5235
6057
|
const apiKey = resolveApiKey2(effectiveKey);
|
|
5236
6058
|
if (!apiKey) {
|
|
5237
|
-
_optionalChain([callbacks, 'access',
|
|
6059
|
+
_optionalChain([callbacks, 'access', _366 => _366.onError, 'optionalCall', _367 => _367("API key not configured")]);
|
|
5238
6060
|
return;
|
|
5239
6061
|
}
|
|
5240
6062
|
const { chain, hasTransformers } = await resolveChainWithMain(
|
|
@@ -5246,17 +6068,8 @@ async function completeStreamWithTransformers(options, callbacks, llmConfig, get
|
|
|
5246
6068
|
return completeStreamFallback(options, callbacks);
|
|
5247
6069
|
}
|
|
5248
6070
|
const messageId = `msg_${Date.now()}`;
|
|
5249
|
-
_optionalChain([callbacks, 'access',
|
|
5250
|
-
const unifiedRequest =
|
|
5251
|
-
model: actualModel,
|
|
5252
|
-
messages: options.messages.map((m) => ({
|
|
5253
|
-
role: m.role,
|
|
5254
|
-
content: m.content
|
|
5255
|
-
})),
|
|
5256
|
-
max_tokens: options.maxTokens || 4096,
|
|
5257
|
-
temperature: options.temperature,
|
|
5258
|
-
stream: true
|
|
5259
|
-
};
|
|
6071
|
+
_optionalChain([callbacks, 'access', _368 => _368.onStart, 'optionalCall', _369 => _369(messageId)]);
|
|
6072
|
+
const unifiedRequest = buildUnifiedCompletionRequest(actualModel, options, true);
|
|
5260
6073
|
const transformerProvider = {
|
|
5261
6074
|
name: provider.name,
|
|
5262
6075
|
baseUrl: provider.api_base_url,
|
|
@@ -5264,7 +6077,7 @@ async function completeStreamWithTransformers(options, callbacks, llmConfig, get
|
|
|
5264
6077
|
models: provider.models || []
|
|
5265
6078
|
};
|
|
5266
6079
|
const executor = getSharedExecutor2();
|
|
5267
|
-
const { response } = await
|
|
6080
|
+
const { response } = await _chunkMUHWHQVMcjs.executeProviderCall.call(void 0, {
|
|
5268
6081
|
executor,
|
|
5269
6082
|
request: unifiedRequest,
|
|
5270
6083
|
provider: transformerProvider,
|
|
@@ -5294,7 +6107,7 @@ async function completeStreamWithTransformers(options, callbacks, llmConfig, get
|
|
|
5294
6107
|
});
|
|
5295
6108
|
if (!response.ok) {
|
|
5296
6109
|
const errorText = await response.text();
|
|
5297
|
-
_optionalChain([callbacks, 'access',
|
|
6110
|
+
_optionalChain([callbacks, 'access', _370 => _370.onError, 'optionalCall', _371 => _371(`API error (${response.status}): ${errorText}`)]);
|
|
5298
6111
|
return;
|
|
5299
6112
|
}
|
|
5300
6113
|
const transformedResponse = await executor.executeResponseChain(
|
|
@@ -5304,9 +6117,9 @@ async function completeStreamWithTransformers(options, callbacks, llmConfig, get
|
|
|
5304
6117
|
chain,
|
|
5305
6118
|
{ endpointTransformer: void 0 }
|
|
5306
6119
|
);
|
|
5307
|
-
const reader = _optionalChain([transformedResponse, 'access',
|
|
6120
|
+
const reader = _optionalChain([transformedResponse, 'access', _372 => _372.body, 'optionalAccess', _373 => _373.getReader, 'call', _374 => _374()]);
|
|
5308
6121
|
if (!reader) {
|
|
5309
|
-
_optionalChain([callbacks, 'access',
|
|
6122
|
+
_optionalChain([callbacks, 'access', _375 => _375.onError, 'optionalCall', _376 => _376("No response body")]);
|
|
5310
6123
|
return;
|
|
5311
6124
|
}
|
|
5312
6125
|
const decoder = new TextDecoder();
|
|
@@ -5324,22 +6137,22 @@ async function completeStreamWithTransformers(options, callbacks, llmConfig, get
|
|
|
5324
6137
|
if (data === "[DONE]") continue;
|
|
5325
6138
|
try {
|
|
5326
6139
|
const json = JSON.parse(data);
|
|
5327
|
-
const delta = _optionalChain([json, 'access',
|
|
5328
|
-
if (_optionalChain([delta, 'optionalAccess',
|
|
6140
|
+
const delta = _optionalChain([json, 'access', _377 => _377.choices, 'optionalAccess', _378 => _378[0], 'optionalAccess', _379 => _379.delta]);
|
|
6141
|
+
if (_optionalChain([delta, 'optionalAccess', _380 => _380.content])) {
|
|
5329
6142
|
content += delta.content;
|
|
5330
|
-
_optionalChain([callbacks, 'access',
|
|
6143
|
+
_optionalChain([callbacks, 'access', _381 => _381.onDelta, 'optionalCall', _382 => _382(delta.content)]);
|
|
5331
6144
|
}
|
|
5332
|
-
if (_optionalChain([delta, 'optionalAccess',
|
|
6145
|
+
if (_optionalChain([delta, 'optionalAccess', _383 => _383.thinking, 'optionalAccess', _384 => _384.content])) {
|
|
5333
6146
|
reasoning += delta.thinking.content;
|
|
5334
|
-
_optionalChain([callbacks, 'access',
|
|
6147
|
+
_optionalChain([callbacks, 'access', _385 => _385.onReasoning, 'optionalCall', _386 => _386(delta.thinking.content)]);
|
|
5335
6148
|
}
|
|
5336
|
-
if (_optionalChain([delta, 'optionalAccess',
|
|
6149
|
+
if (_optionalChain([delta, 'optionalAccess', _387 => _387.reasoning_content])) {
|
|
5337
6150
|
reasoning += delta.reasoning_content;
|
|
5338
|
-
_optionalChain([callbacks, 'access',
|
|
6151
|
+
_optionalChain([callbacks, 'access', _388 => _388.onReasoning, 'optionalCall', _389 => _389(delta.reasoning_content)]);
|
|
5339
6152
|
}
|
|
5340
6153
|
if (json.usage) {
|
|
5341
6154
|
const tapped = readUsageFromOpenAIResponse(json.usage);
|
|
5342
|
-
if (_optionalChain([recording, 'optionalAccess',
|
|
6155
|
+
if (_optionalChain([recording, 'optionalAccess', _390 => _390.recorder]) && tapped) {
|
|
5343
6156
|
recording.recorder.record({
|
|
5344
6157
|
messageId: _nullishCoalesce(options.messageId, () => ( null)),
|
|
5345
6158
|
parentMessageId: _nullishCoalesce(options.parentMessageId, () => ( null)),
|
|
@@ -5352,7 +6165,7 @@ async function completeStreamWithTransformers(options, callbacks, llmConfig, get
|
|
|
5352
6165
|
rawUsage: json.usage
|
|
5353
6166
|
});
|
|
5354
6167
|
}
|
|
5355
|
-
_optionalChain([callbacks, 'access',
|
|
6168
|
+
_optionalChain([callbacks, 'access', _391 => _391.onDone, 'optionalCall', _392 => _392(
|
|
5356
6169
|
{
|
|
5357
6170
|
id: messageId,
|
|
5358
6171
|
role: "assistant",
|
|
@@ -5373,7 +6186,7 @@ async function completeStreamWithTransformers(options, callbacks, llmConfig, get
|
|
|
5373
6186
|
}
|
|
5374
6187
|
}
|
|
5375
6188
|
}
|
|
5376
|
-
_optionalChain([callbacks, 'access',
|
|
6189
|
+
_optionalChain([callbacks, 'access', _393 => _393.onDone, 'optionalCall', _394 => _394({
|
|
5377
6190
|
id: messageId,
|
|
5378
6191
|
role: "assistant",
|
|
5379
6192
|
content,
|
|
@@ -5385,13 +6198,13 @@ async function completeStreamWithTransformers(options, callbacks, llmConfig, get
|
|
|
5385
6198
|
}
|
|
5386
6199
|
} catch (error) {
|
|
5387
6200
|
const message = error instanceof Error ? error.message : "Unknown error";
|
|
5388
|
-
_optionalChain([callbacks, 'access',
|
|
6201
|
+
_optionalChain([callbacks, 'access', _395 => _395.onError, 'optionalCall', _396 => _396(message)]);
|
|
5389
6202
|
}
|
|
5390
6203
|
}
|
|
5391
6204
|
|
|
5392
6205
|
// src/completion/CompletionService.ts
|
|
5393
6206
|
var CompletionService = (_class13 = class {
|
|
5394
|
-
constructor(paths, llmConfig, logger) {;_class13.prototype.
|
|
6207
|
+
constructor(paths, llmConfig, logger) {;_class13.prototype.__init23.call(this);_class13.prototype.__init24.call(this);_class13.prototype.__init25.call(this);_class13.prototype.__init26.call(this);
|
|
5395
6208
|
this.paths = paths;
|
|
5396
6209
|
this.llmConfig = llmConfig;
|
|
5397
6210
|
this.logger = logger;
|
|
@@ -5399,10 +6212,10 @@ var CompletionService = (_class13 = class {
|
|
|
5399
6212
|
|
|
5400
6213
|
|
|
5401
6214
|
|
|
5402
|
-
|
|
5403
|
-
|
|
5404
|
-
|
|
5405
|
-
|
|
6215
|
+
__init23() {this.apiKeyPool = null}
|
|
6216
|
+
__init24() {this.usageRecorder = null}
|
|
6217
|
+
__init25() {this.usageEventSink = null}
|
|
6218
|
+
__init26() {this.visionFallbackProvider = null}
|
|
5406
6219
|
/**
|
|
5407
6220
|
* Set the API key pool service for multi-key load balancing.
|
|
5408
6221
|
* When set, keys are resolved via the pool instead of directly from the provider.
|
|
@@ -5452,8 +6265,8 @@ var CompletionService = (_class13 = class {
|
|
|
5452
6265
|
options.providerId,
|
|
5453
6266
|
options.model
|
|
5454
6267
|
);
|
|
5455
|
-
const actualProviderId = _optionalChain([routedInfo, 'optionalAccess',
|
|
5456
|
-
const actualModel = _optionalChain([routedInfo, 'optionalAccess',
|
|
6268
|
+
const actualProviderId = _optionalChain([routedInfo, 'optionalAccess', _397 => _397.actualProviderId]) || options.providerId;
|
|
6269
|
+
const actualModel = _optionalChain([routedInfo, 'optionalAccess', _398 => _398.actualModelId]) || options.model;
|
|
5457
6270
|
const provider = await this.getProvider(actualProviderId);
|
|
5458
6271
|
if (!provider) {
|
|
5459
6272
|
return { success: false, error: `Provider not found: ${actualProviderId}` };
|
|
@@ -5486,7 +6299,7 @@ var CompletionService = (_class13 = class {
|
|
|
5486
6299
|
this.apiKeyPool.reportSuccess(options.sessionId);
|
|
5487
6300
|
}
|
|
5488
6301
|
if (result.success && result.usage && options.sessionId) {
|
|
5489
|
-
_optionalChain([this, 'access',
|
|
6302
|
+
_optionalChain([this, 'access', _399 => _399.usageEventSink, 'optionalAccess', _400 => _400.emit, 'call', _401 => _401({
|
|
5490
6303
|
sessionId: options.sessionId,
|
|
5491
6304
|
modelId: actualModel,
|
|
5492
6305
|
usage: result.usage,
|
|
@@ -5515,8 +6328,8 @@ var CompletionService = (_class13 = class {
|
|
|
5515
6328
|
options.model
|
|
5516
6329
|
);
|
|
5517
6330
|
this.logger.debug("Resolved routed model", { routedInfo });
|
|
5518
|
-
const actualProviderId = _optionalChain([routedInfo, 'optionalAccess',
|
|
5519
|
-
const actualModel = _optionalChain([routedInfo, 'optionalAccess',
|
|
6331
|
+
const actualProviderId = _optionalChain([routedInfo, 'optionalAccess', _402 => _402.actualProviderId]) || options.providerId;
|
|
6332
|
+
const actualModel = _optionalChain([routedInfo, 'optionalAccess', _403 => _403.actualModelId]) || options.model;
|
|
5520
6333
|
this.logger.debug("Resolved provider and model", { actualProviderId, actualModel });
|
|
5521
6334
|
const provider = await this.getProvider(actualProviderId);
|
|
5522
6335
|
this.logger.debug("Retrieved provider", provider ? {
|
|
@@ -5528,22 +6341,22 @@ var CompletionService = (_class13 = class {
|
|
|
5528
6341
|
enabled: provider.enabled
|
|
5529
6342
|
} : { error: "Provider not found" });
|
|
5530
6343
|
if (!provider) {
|
|
5531
|
-
_optionalChain([callbacks, 'access',
|
|
6344
|
+
_optionalChain([callbacks, 'access', _404 => _404.onError, 'optionalCall', _405 => _405(`Provider not found: ${actualProviderId}`)]);
|
|
5532
6345
|
return;
|
|
5533
6346
|
}
|
|
5534
6347
|
if (!provider.enabled) {
|
|
5535
|
-
_optionalChain([callbacks, 'access',
|
|
6348
|
+
_optionalChain([callbacks, 'access', _406 => _406.onError, 'optionalCall', _407 => _407(`Provider is disabled: ${provider.name}`)]);
|
|
5536
6349
|
return;
|
|
5537
6350
|
}
|
|
5538
6351
|
const apiKey = await this.resolveApiKeyForRequest(provider, actualProviderId, options.sessionId);
|
|
5539
6352
|
if (!apiKey) {
|
|
5540
|
-
_optionalChain([callbacks, 'access',
|
|
6353
|
+
_optionalChain([callbacks, 'access', _408 => _408.onError, 'optionalCall', _409 => _409("API key not configured")]);
|
|
5541
6354
|
return;
|
|
5542
6355
|
}
|
|
5543
6356
|
const apiFormat = _chunkA2YMUCBTcjs.resolveApiFormat.call(void 0, provider);
|
|
5544
6357
|
this.logger.info("Using API format for stream", { apiFormat });
|
|
5545
6358
|
const messageId = `msg_${Date.now()}`;
|
|
5546
|
-
_optionalChain([callbacks, 'access',
|
|
6359
|
+
_optionalChain([callbacks, 'access', _410 => _410.onStart, 'optionalCall', _411 => _411(messageId)]);
|
|
5547
6360
|
const resolvedOptions = { ...options, model: actualModel };
|
|
5548
6361
|
if (options.sessionId) {
|
|
5549
6362
|
const sid = options.sessionId;
|
|
@@ -5552,14 +6365,14 @@ var CompletionService = (_class13 = class {
|
|
|
5552
6365
|
...callbacks,
|
|
5553
6366
|
onDone: (message, usage, metrics) => {
|
|
5554
6367
|
if (usage) {
|
|
5555
|
-
_optionalChain([this, 'access',
|
|
6368
|
+
_optionalChain([this, 'access', _412 => _412.usageEventSink, 'optionalAccess', _413 => _413.emit, 'call', _414 => _414({
|
|
5556
6369
|
sessionId: sid,
|
|
5557
6370
|
modelId: actualModel,
|
|
5558
6371
|
usage,
|
|
5559
6372
|
engineOrigin: "completion"
|
|
5560
6373
|
})]);
|
|
5561
6374
|
}
|
|
5562
|
-
_optionalChain([userOnDone, 'optionalCall',
|
|
6375
|
+
_optionalChain([userOnDone, 'optionalCall', _415 => _415(message, usage, metrics)]);
|
|
5563
6376
|
}
|
|
5564
6377
|
};
|
|
5565
6378
|
}
|
|
@@ -5575,11 +6388,11 @@ var CompletionService = (_class13 = class {
|
|
|
5575
6388
|
retryState.error = { status, message: error };
|
|
5576
6389
|
return;
|
|
5577
6390
|
}
|
|
5578
|
-
_optionalChain([callbacks, 'access',
|
|
6391
|
+
_optionalChain([callbacks, 'access', _416 => _416.onError, 'optionalCall', _417 => _417(error)]);
|
|
5579
6392
|
},
|
|
5580
6393
|
onDone: (message, usage, metrics) => {
|
|
5581
6394
|
this.apiKeyPool.reportSuccess(options.sessionId);
|
|
5582
|
-
_optionalChain([callbacks, 'access',
|
|
6395
|
+
_optionalChain([callbacks, 'access', _418 => _418.onDone, 'optionalCall', _419 => _419(message, usage, metrics)]);
|
|
5583
6396
|
}
|
|
5584
6397
|
};
|
|
5585
6398
|
await this.callStreamHandler(apiFormat, provider, apiKey, resolvedOptions, messageId, interceptCallbacks);
|
|
@@ -5600,7 +6413,7 @@ var CompletionService = (_class13 = class {
|
|
|
5600
6413
|
// don't fire onStart again
|
|
5601
6414
|
});
|
|
5602
6415
|
} else {
|
|
5603
|
-
_optionalChain([callbacks, 'access',
|
|
6416
|
+
_optionalChain([callbacks, 'access', _420 => _420.onError, 'optionalCall', _421 => _421(retryState.error.message)]);
|
|
5604
6417
|
}
|
|
5605
6418
|
}
|
|
5606
6419
|
} else {
|
|
@@ -5613,7 +6426,7 @@ var CompletionService = (_class13 = class {
|
|
|
5613
6426
|
} catch (error) {
|
|
5614
6427
|
const message = error instanceof Error ? error.message : "Unknown error";
|
|
5615
6428
|
this.logger.error("Stream completion error", error instanceof Error ? error : void 0, { message });
|
|
5616
|
-
_optionalChain([callbacks, 'access',
|
|
6429
|
+
_optionalChain([callbacks, 'access', _422 => _422.onError, 'optionalCall', _423 => _423(message)]);
|
|
5617
6430
|
}
|
|
5618
6431
|
}
|
|
5619
6432
|
/**
|
|
@@ -5653,7 +6466,7 @@ var CompletionService = (_class13 = class {
|
|
|
5653
6466
|
return {
|
|
5654
6467
|
success: true,
|
|
5655
6468
|
message: "Connection successful",
|
|
5656
|
-
response: _optionalChain([result, 'access',
|
|
6469
|
+
response: _optionalChain([result, 'access', _424 => _424.message, 'optionalAccess', _425 => _425.content]) || "",
|
|
5657
6470
|
model: modelId,
|
|
5658
6471
|
durationMs
|
|
5659
6472
|
};
|
|
@@ -5718,7 +6531,7 @@ ${description}`;
|
|
|
5718
6531
|
* 3. Legacy single key from provider config
|
|
5719
6532
|
*/
|
|
5720
6533
|
async resolveApiKeyForRequest(provider, providerId, sessionId) {
|
|
5721
|
-
if (_optionalChain([provider, 'access',
|
|
6534
|
+
if (_optionalChain([provider, 'access', _426 => _426.codingPlan, 'optionalAccess', _427 => _427.enabled]) && provider.codingPlan.apiKey) {
|
|
5722
6535
|
return this.resolveApiKey(provider.codingPlan.apiKey);
|
|
5723
6536
|
}
|
|
5724
6537
|
if (this.apiKeyPool) {
|
|
@@ -5791,9 +6604,10 @@ ${description}`;
|
|
|
5791
6604
|
* Resolve effective max_tokens value with priority:
|
|
5792
6605
|
* 1. Session settings (if provided)
|
|
5793
6606
|
* 2. Global model parameters (if enabled)
|
|
5794
|
-
* 3.
|
|
5795
|
-
*
|
|
5796
|
-
*
|
|
6607
|
+
* 3. undefined - let API use its default
|
|
6608
|
+
*
|
|
6609
|
+
* Provider and discovery maxTokens values are capability metadata, not
|
|
6610
|
+
* implicit per-request output limits.
|
|
5797
6611
|
*/
|
|
5798
6612
|
async resolveEffectiveMaxTokens(providerId, modelId, sessionMaxTokens) {
|
|
5799
6613
|
return resolveEffectiveMaxTokens(
|
|
@@ -5967,4 +6781,14 @@ ${description}`;
|
|
|
5967
6781
|
|
|
5968
6782
|
|
|
5969
6783
|
|
|
5970
|
-
|
|
6784
|
+
|
|
6785
|
+
|
|
6786
|
+
|
|
6787
|
+
|
|
6788
|
+
|
|
6789
|
+
|
|
6790
|
+
|
|
6791
|
+
|
|
6792
|
+
|
|
6793
|
+
|
|
6794
|
+
exports.CompletionService = CompletionService; exports.register = register; exports.emit = emit; exports.attach = attach; exports.release = release; exports.convertMessageToOpenAI = convertMessageToOpenAI; exports.convertMessageToAnthropic = convertMessageToAnthropic; exports.convertMessageToGemini = convertMessageToGemini; exports.getOpenRouterProviderConfig = getOpenRouterProviderConfig; exports.addOpenRouterProviderToRequest = addOpenRouterProviderToRequest; exports.DEFAULT_ROUTE_IDLE_MS = DEFAULT_ROUTE_IDLE_MS; exports.ProviderProxyRouteMap = ProviderProxyRouteMap; exports.getSharedExecutor = getSharedExecutor; exports.getResponsesEndpointTransformer = getResponsesEndpointTransformer; exports.getAnthropicEndpointTransformer = getAnthropicEndpointTransformer; exports.getGeminiEndpointTransformer = getGeminiEndpointTransformer; exports.readBody = readBody; exports.relayResponse = relayResponse; exports.aggregateAnthropicSseToJsonBody = aggregateAnthropicSseToJsonBody; exports.writeError = writeError; exports.writeBoundAccountError = writeBoundAccountError; exports.resolvePoolBoundKey = resolvePoolBoundKey; exports.extractRouteToken = extractRouteToken; exports.isLoopbackAddress = isLoopbackAddress; exports.ProviderProxy = ProviderProxy; exports.getProviderProxy = getProviderProxy; exports.__resetProviderProxyForTests = __resetProviderProxyForTests; exports.KeyedMutex = KeyedMutex; exports.OUTBOUND_API_SERVER_CONFIG_KEY = OUTBOUND_API_SERVER_CONFIG_KEY; exports.DEFAULT_USER_MESSAGE_QUEUE = DEFAULT_USER_MESSAGE_QUEUE; exports.DEFAULT_CONCURRENCY_QUEUE = DEFAULT_CONCURRENCY_QUEUE; exports.DEFAULT_ACCOUNT_PROBE = DEFAULT_ACCOUNT_PROBE; exports.DEFAULT_ALLOWANCE_SCHEDULING = DEFAULT_ALLOWANCE_SCHEDULING; exports.normalizeAllowanceScheduling = normalizeAllowanceScheduling; exports.normalizeAccountProbe = normalizeAccountProbe; exports.normalizeAudit = normalizeAudit; exports.normalizeBilling = normalizeBilling; exports.DEFAULT_FINGERPRINT = DEFAULT_FINGERPRINT; exports.normalizeFingerprint = normalizeFingerprint; exports.normalizeVoucher = normalizeVoucher; exports.normalizeProxyConfig = normalizeProxyConfig; exports.normalizeProxySegment = normalizeProxySegment; exports.normalizeWebhookDestination = normalizeWebhookDestination; exports.normalizeWebhookSegment = normalizeWebhookSegment; exports.normalizeQueueSegments = normalizeQueueSegments; exports.normalizePrefixTargets = normalizePrefixTargets; exports.legacyEndpointsToBindings = legacyEndpointsToBindings; exports.normalizeGatewayBindings = normalizeGatewayBindings; exports.defaultServerConfig = defaultServerConfig; exports.normalizeServerConfig = normalizeServerConfig; exports.loadServerConfig = loadServerConfig; exports.saveServerConfig = saveServerConfig; exports.mergeServerConfig = mergeServerConfig; exports.gatewayBindingToEndpointConfig = gatewayBindingToEndpointConfig; exports.candidateGatewayBindings = candidateGatewayBindings; exports.candidateBackgroundModelIds = candidateBackgroundModelIds; exports.resolveGatewayBinding = resolveGatewayBinding; exports.computeKeyExpiry = computeKeyExpiry; exports.checkKeyQuota = checkKeyQuota; exports.randomBase62 = randomBase62; exports.hashKey = hashKey; exports.createNamedKey = createNamedKey; exports.createIntegrationKey = createIntegrationKey; exports.verifyKey = verifyKey; exports.verifyPresentedKey = verifyPresentedKey; exports.ConcurrencyQueueFullError = ConcurrencyQueueFullError; exports.ConcurrencyWaitTimeoutError = ConcurrencyWaitTimeoutError; exports.ConcurrencyWaitCancelledError = ConcurrencyWaitCancelledError; exports.isConcurrencyRejection = isConcurrencyRejection; exports.OutboundConcurrencyGate = OutboundConcurrencyGate; exports.OutboundRateLimiter = OutboundRateLimiter; exports.isUserMessageRequest = isUserMessageRequest; exports.SerialQueueTimeoutError = SerialQueueTimeoutError; exports.isSerialQueueTimeout = isSerialQueueTimeout; exports.UserMessageSerialQueue = UserMessageSerialQueue; exports.generateVoucherCode = generateVoucherCode; exports.hashVoucherCode = hashVoucherCode; exports.voucherCodePrefix = voucherCodePrefix; exports.newVoucherId = newVoucherId; exports.computeVoucherGrant = computeVoucherGrant; exports.toVoucherInfo = toVoucherInfo; exports.isRedeemRequest = isRedeemRequest; exports.handleVoucherRedeem = handleVoucherRedeem; exports.DEFAULT_OUTBOUND_PORT = DEFAULT_OUTBOUND_PORT; exports.OutboundApiServer = OutboundApiServer; exports.formatUrls = formatUrls; exports.startOfLocalDay = startOfLocalDay; exports.startOfLocalWeek = startOfLocalWeek; exports.KeySpendTracker = KeySpendTracker; exports.getOutboundApiServer = getOutboundApiServer; exports.__resetOutboundApiServerForTests = __resetOutboundApiServerForTests;
|