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