@infersec/conduit 1.98.0 → 1.98.2
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/cli.js +54 -108
- package/dist/cli.sea.cjs +54 -108
- package/dist/sse/handler.d.ts +2 -5
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -122307,16 +122307,17 @@ const DOWNLOAD_PROGRESS_TIMEOUT = 60000;
|
|
|
122307
122307
|
const DOWNLOAD_RETRY_ATTEMPTS_FULL = 3;
|
|
122308
122308
|
const DOWNLOAD_RETRY_ATTEMPTS_RANGE = 10;
|
|
122309
122309
|
const ALLOWED_EXTENSIONS = new Set([
|
|
122310
|
+
".bin",
|
|
122311
|
+
".gguf",
|
|
122310
122312
|
".gitattributes",
|
|
122313
|
+
".jinja",
|
|
122311
122314
|
".json",
|
|
122312
122315
|
".merges",
|
|
122313
122316
|
".model",
|
|
122314
122317
|
".py",
|
|
122315
122318
|
".safetensors",
|
|
122316
122319
|
".tiktoken",
|
|
122317
|
-
".txt"
|
|
122318
|
-
".bin",
|
|
122319
|
-
".gguf"
|
|
122320
|
+
".txt"
|
|
122320
122321
|
]);
|
|
122321
122322
|
function isAllowedFile(filePath) {
|
|
122322
122323
|
const lower = filePath.toLowerCase();
|
|
@@ -124186,12 +124187,17 @@ function serializeRequestBody$1(body) {
|
|
|
124186
124187
|
};
|
|
124187
124188
|
}
|
|
124188
124189
|
const requestPayload = { ...body };
|
|
124189
|
-
|
|
124190
|
-
|
|
124191
|
-
|
|
124192
|
-
|
|
124193
|
-
|
|
124194
|
-
|
|
124190
|
+
if (requestPayload.stream === true) {
|
|
124191
|
+
const streamOptions = requestPayload.stream_options;
|
|
124192
|
+
const normalizedStreamOptions = isPlainObject$3(streamOptions)
|
|
124193
|
+
? { ...streamOptions }
|
|
124194
|
+
: {};
|
|
124195
|
+
normalizedStreamOptions.include_usage = true;
|
|
124196
|
+
requestPayload.stream_options = normalizedStreamOptions;
|
|
124197
|
+
}
|
|
124198
|
+
else {
|
|
124199
|
+
delete requestPayload.stream_options;
|
|
124200
|
+
}
|
|
124195
124201
|
if (requestPayload.repetition_penalty === undefined) {
|
|
124196
124202
|
requestPayload.repetition_penalty = 1.1;
|
|
124197
124203
|
}
|
|
@@ -124201,11 +124207,17 @@ function serializeRequestBody$1(body) {
|
|
|
124201
124207
|
payload
|
|
124202
124208
|
};
|
|
124203
124209
|
}
|
|
124204
|
-
function calculateTokensPerSecond$
|
|
124205
|
-
if (durationMs <= 0) {
|
|
124210
|
+
function calculateTokensPerSecond$1({ completionTokens, durationMs, streamRequested, timeToFirstTokenMs }) {
|
|
124211
|
+
if (completionTokens <= 0 || durationMs <= 0) {
|
|
124212
|
+
return 0;
|
|
124213
|
+
}
|
|
124214
|
+
const decodeMs = streamRequested && timeToFirstTokenMs !== null && timeToFirstTokenMs > 0
|
|
124215
|
+
? Math.max(0, durationMs - timeToFirstTokenMs)
|
|
124216
|
+
: durationMs;
|
|
124217
|
+
if (decodeMs <= 0) {
|
|
124206
124218
|
return 0;
|
|
124207
124219
|
}
|
|
124208
|
-
const tokensPerSecond =
|
|
124220
|
+
const tokensPerSecond = completionTokens / (decodeMs / 1000);
|
|
124209
124221
|
if (!Number.isFinite(tokensPerSecond) || tokensPerSecond <= 0) {
|
|
124210
124222
|
return 0;
|
|
124211
124223
|
}
|
|
@@ -124255,10 +124267,7 @@ async function proxyEmbeddingsRoute({ body, conduitConfiguration, endpointId, lo
|
|
|
124255
124267
|
responseBytes,
|
|
124256
124268
|
successful: upstreamResponseOk && !error,
|
|
124257
124269
|
timeToFirstTokenMs: null,
|
|
124258
|
-
tokensPerSecond:
|
|
124259
|
-
durationMs: latencyMs,
|
|
124260
|
-
totalTokens
|
|
124261
|
-
}),
|
|
124270
|
+
tokensPerSecond: 0,
|
|
124262
124271
|
totalTokens
|
|
124263
124272
|
});
|
|
124264
124273
|
};
|
|
@@ -124401,9 +124410,11 @@ async function proxyOpenAIStreamingRoute({ body, conduitConfiguration, endpointI
|
|
|
124401
124410
|
responseBytes,
|
|
124402
124411
|
successful: upstreamResponseOk && !error,
|
|
124403
124412
|
timeToFirstTokenMs,
|
|
124404
|
-
tokensPerSecond: calculateTokensPerSecond$
|
|
124413
|
+
tokensPerSecond: calculateTokensPerSecond$1({
|
|
124414
|
+
completionTokens,
|
|
124405
124415
|
durationMs: latencyMs,
|
|
124406
|
-
|
|
124416
|
+
streamRequested,
|
|
124417
|
+
timeToFirstTokenMs
|
|
124407
124418
|
}),
|
|
124408
124419
|
totalTokens
|
|
124409
124420
|
});
|
|
@@ -124851,10 +124862,15 @@ function serializeRequestBody(body) {
|
|
|
124851
124862
|
payload
|
|
124852
124863
|
};
|
|
124853
124864
|
}
|
|
124854
|
-
function calculateTokensPerSecond
|
|
124855
|
-
if (durationMs <= 0)
|
|
124865
|
+
function calculateTokensPerSecond({ completionTokens, durationMs, streamRequested, timeToFirstTokenMs }) {
|
|
124866
|
+
if (completionTokens <= 0 || durationMs <= 0)
|
|
124867
|
+
return 0;
|
|
124868
|
+
const decodeMs = streamRequested && timeToFirstTokenMs !== null && timeToFirstTokenMs > 0
|
|
124869
|
+
? Math.max(0, durationMs - timeToFirstTokenMs)
|
|
124870
|
+
: durationMs;
|
|
124871
|
+
if (decodeMs <= 0)
|
|
124856
124872
|
return 0;
|
|
124857
|
-
const tokensPerSecond =
|
|
124873
|
+
const tokensPerSecond = completionTokens / (decodeMs / 1000);
|
|
124858
124874
|
if (!Number.isFinite(tokensPerSecond) || tokensPerSecond <= 0)
|
|
124859
124875
|
return 0;
|
|
124860
124876
|
return Math.round(tokensPerSecond);
|
|
@@ -125032,7 +125048,7 @@ async function proxyAnthropicStreamingRoute({ body, conduitConfiguration, endpoi
|
|
|
125032
125048
|
const targetBody = needsTranslation
|
|
125033
125049
|
? translateAnthropicRequestToOpenAI(serializedBody).body
|
|
125034
125050
|
: serializedBody;
|
|
125035
|
-
const onMonitoringComplete = ({ durationMs, error, responseBytes, usage }) => {
|
|
125051
|
+
const onMonitoringComplete = ({ durationMs, error, responseBytes, timeToFirstTokenMs, usage }) => {
|
|
125036
125052
|
const promptTokens = normalizeTokenCount(usage?.inputTokens);
|
|
125037
125053
|
const completionTokens = normalizeTokenCount(usage?.outputTokens);
|
|
125038
125054
|
const totalTokens = promptTokens + completionTokens;
|
|
@@ -125051,10 +125067,12 @@ async function proxyAnthropicStreamingRoute({ body, conduitConfiguration, endpoi
|
|
|
125051
125067
|
requestPath: "/v1/messages",
|
|
125052
125068
|
responseBytes,
|
|
125053
125069
|
successful: !error,
|
|
125054
|
-
timeToFirstTokenMs
|
|
125055
|
-
tokensPerSecond: calculateTokensPerSecond
|
|
125070
|
+
timeToFirstTokenMs,
|
|
125071
|
+
tokensPerSecond: calculateTokensPerSecond({
|
|
125072
|
+
completionTokens,
|
|
125056
125073
|
durationMs: latencyMs,
|
|
125057
|
-
|
|
125074
|
+
streamRequested,
|
|
125075
|
+
timeToFirstTokenMs
|
|
125058
125076
|
}),
|
|
125059
125077
|
totalTokens
|
|
125060
125078
|
});
|
|
@@ -125151,6 +125169,7 @@ async function proxyAnthropicStreamingRoute({ body, conduitConfiguration, endpoi
|
|
|
125151
125169
|
const passThrough = new PassThrough();
|
|
125152
125170
|
let responseBytes = 0;
|
|
125153
125171
|
let completed = false;
|
|
125172
|
+
let firstChunkAt = null;
|
|
125154
125173
|
const usage = { inputTokens: null, outputTokens: null };
|
|
125155
125174
|
const upstreamError = response.ok
|
|
125156
125175
|
? null
|
|
@@ -125163,6 +125182,7 @@ async function proxyAnthropicStreamingRoute({ body, conduitConfiguration, endpoi
|
|
|
125163
125182
|
durationMs: Math.max(0, Date.now() - requestStartedAt),
|
|
125164
125183
|
error,
|
|
125165
125184
|
responseBytes,
|
|
125185
|
+
timeToFirstTokenMs: firstChunkAt === null ? null : Math.max(0, firstChunkAt - requestStartedAt),
|
|
125166
125186
|
usage
|
|
125167
125187
|
});
|
|
125168
125188
|
}
|
|
@@ -125172,6 +125192,8 @@ async function proxyAnthropicStreamingRoute({ body, conduitConfiguration, endpoi
|
|
|
125172
125192
|
const chunks = [];
|
|
125173
125193
|
rawBody.on("data", (chunk) => {
|
|
125174
125194
|
const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
125195
|
+
if (firstChunkAt === null)
|
|
125196
|
+
firstChunkAt = Date.now();
|
|
125175
125197
|
responseBytes += chunkBuffer.length;
|
|
125176
125198
|
chunks.push(chunkBuffer);
|
|
125177
125199
|
});
|
|
@@ -125254,6 +125276,8 @@ async function proxyAnthropicStreamingRoute({ body, conduitConfiguration, endpoi
|
|
|
125254
125276
|
let buffer = "";
|
|
125255
125277
|
rawBody.on("data", (chunk) => {
|
|
125256
125278
|
const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
125279
|
+
if (firstChunkAt === null)
|
|
125280
|
+
firstChunkAt = Date.now();
|
|
125257
125281
|
responseBytes += chunkBuffer.length;
|
|
125258
125282
|
buffer += chunkBuffer.toString("utf8");
|
|
125259
125283
|
const lines = buffer.split("\n");
|
|
@@ -125324,6 +125348,8 @@ async function proxyAnthropicStreamingRoute({ body, conduitConfiguration, endpoi
|
|
|
125324
125348
|
const chunks = [];
|
|
125325
125349
|
rawBody.on("data", (chunk) => {
|
|
125326
125350
|
const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
125351
|
+
if (firstChunkAt === null)
|
|
125352
|
+
firstChunkAt = Date.now();
|
|
125327
125353
|
responseBytes += chunkBuffer.length;
|
|
125328
125354
|
chunks.push(chunkBuffer);
|
|
125329
125355
|
});
|
|
@@ -125474,7 +125500,7 @@ function createHealthHandler() {
|
|
|
125474
125500
|
};
|
|
125475
125501
|
}
|
|
125476
125502
|
|
|
125477
|
-
async function handleSSERequests({ apiURL,
|
|
125503
|
+
async function handleSSERequests({ apiURL, configuration, logger, onRequest, onRequestEnd, onRequestStart, signal }) {
|
|
125478
125504
|
const streamURL = `${apiURL}/conduit/api/v1/source/${configuration.inferenceSourceID}/requests/stream`;
|
|
125479
125505
|
const maxReconnectDelayMs = 30000;
|
|
125480
125506
|
let reconnectAttempt = 0;
|
|
@@ -125516,14 +125542,11 @@ async function handleSSERequests({ apiURL, conduitConfiguration, configuration,
|
|
|
125516
125542
|
handleRequest({
|
|
125517
125543
|
activeRequests,
|
|
125518
125544
|
apiURL,
|
|
125519
|
-
conduitConfiguration,
|
|
125520
125545
|
configuration,
|
|
125521
125546
|
logger,
|
|
125522
|
-
modelID,
|
|
125523
125547
|
onRequest,
|
|
125524
125548
|
onRequestEnd,
|
|
125525
125549
|
onRequestStart,
|
|
125526
|
-
reportMetrics,
|
|
125527
125550
|
request: payload,
|
|
125528
125551
|
signal: effectiveSignal
|
|
125529
125552
|
}).catch(error => {
|
|
@@ -125560,23 +125583,12 @@ async function handleSSERequests({ apiURL, conduitConfiguration, configuration,
|
|
|
125560
125583
|
}
|
|
125561
125584
|
}
|
|
125562
125585
|
}
|
|
125563
|
-
async function handleRequest({ activeRequests, apiURL,
|
|
125564
|
-
function reportMetricsSafe(payload) {
|
|
125565
|
-
reportMetrics(payload).catch(error => {
|
|
125566
|
-
logger.warn("Failed to upload LLM prompt metrics", {
|
|
125567
|
-
error: asError(error),
|
|
125568
|
-
requestUrl: request.path
|
|
125569
|
-
});
|
|
125570
|
-
});
|
|
125571
|
-
}
|
|
125572
|
-
const engineType = conduitConfiguration().engineConfig?.type ?? null;
|
|
125573
|
-
const endpointId = request.parameters?.endpointID ?? null;
|
|
125586
|
+
async function handleRequest({ activeRequests, apiURL, configuration, logger, onRequest, onRequestEnd, onRequestStart, request, signal }) {
|
|
125574
125587
|
const requestStartedAt = Date.now();
|
|
125575
|
-
const requestBytes = calculateRequestBytes(request.body ?? null);
|
|
125576
125588
|
try {
|
|
125577
125589
|
await onRequestStart?.(request);
|
|
125578
125590
|
const response = await onRequest({ request, signal });
|
|
125579
|
-
|
|
125591
|
+
await streamResponse({
|
|
125580
125592
|
apiURL,
|
|
125581
125593
|
configuration,
|
|
125582
125594
|
logger,
|
|
@@ -125585,30 +125597,6 @@ async function handleRequest({ activeRequests, apiURL, conduitConfiguration, con
|
|
|
125585
125597
|
response,
|
|
125586
125598
|
signal
|
|
125587
125599
|
});
|
|
125588
|
-
const latencyMs = Math.max(0, Date.now() - requestStartedAt);
|
|
125589
|
-
const totalTokens = 0;
|
|
125590
|
-
const tokensPerSecond = calculateTokensPerSecond({
|
|
125591
|
-
durationMs: latencyMs,
|
|
125592
|
-
totalTokens
|
|
125593
|
-
});
|
|
125594
|
-
reportMetricsSafe({
|
|
125595
|
-
bytes: requestBytes + responseMetrics.responseBytes,
|
|
125596
|
-
completionTokens: 0,
|
|
125597
|
-
engine: engineType,
|
|
125598
|
-
endpointId,
|
|
125599
|
-
latencyMs,
|
|
125600
|
-
modelId: modelID,
|
|
125601
|
-
promptTokens: 0,
|
|
125602
|
-
requestBytes,
|
|
125603
|
-
requestId: request.requestID,
|
|
125604
|
-
requestMethod: request.method,
|
|
125605
|
-
requestPath: request.path,
|
|
125606
|
-
responseBytes: responseMetrics.responseBytes,
|
|
125607
|
-
successful: responseMetrics.status < 400,
|
|
125608
|
-
timeToFirstTokenMs: responseMetrics.timeToFirstTokenMs,
|
|
125609
|
-
tokensPerSecond,
|
|
125610
|
-
totalTokens
|
|
125611
|
-
});
|
|
125612
125600
|
}
|
|
125613
125601
|
catch (error) {
|
|
125614
125602
|
const isCancelled = signal?.aborted;
|
|
@@ -125624,8 +125612,6 @@ async function handleRequest({ activeRequests, apiURL, conduitConfiguration, con
|
|
|
125624
125612
|
});
|
|
125625
125613
|
}
|
|
125626
125614
|
const failureMessage = "Bad gateway\n\nProxying failed";
|
|
125627
|
-
const failureBytes = Buffer.byteLength(failureMessage, "utf8");
|
|
125628
|
-
const latencyMs = Math.max(0, Date.now() - requestStartedAt);
|
|
125629
125615
|
if (!isCancelled) {
|
|
125630
125616
|
const streamHandler = await sendChunkStream({
|
|
125631
125617
|
apiURL,
|
|
@@ -125645,24 +125631,6 @@ async function handleRequest({ activeRequests, apiURL, conduitConfiguration, con
|
|
|
125645
125631
|
});
|
|
125646
125632
|
await streamHandler.end();
|
|
125647
125633
|
}
|
|
125648
|
-
reportMetricsSafe({
|
|
125649
|
-
bytes: isCancelled ? requestBytes : requestBytes + failureBytes,
|
|
125650
|
-
completionTokens: 0,
|
|
125651
|
-
engine: engineType,
|
|
125652
|
-
endpointId,
|
|
125653
|
-
latencyMs,
|
|
125654
|
-
modelId: modelID,
|
|
125655
|
-
promptTokens: 0,
|
|
125656
|
-
requestBytes,
|
|
125657
|
-
requestId: request.requestID,
|
|
125658
|
-
requestMethod: request.method,
|
|
125659
|
-
requestPath: request.path,
|
|
125660
|
-
responseBytes: isCancelled ? 0 : failureBytes,
|
|
125661
|
-
successful: false,
|
|
125662
|
-
timeToFirstTokenMs: isCancelled ? null : latencyMs,
|
|
125663
|
-
tokensPerSecond: 0,
|
|
125664
|
-
totalTokens: 0
|
|
125665
|
-
});
|
|
125666
125634
|
}
|
|
125667
125635
|
finally {
|
|
125668
125636
|
activeRequests.delete(request.requestID);
|
|
@@ -125850,25 +125818,6 @@ async function sendChunkStream({ apiURL, configuration, requestID, logger }) {
|
|
|
125850
125818
|
abort
|
|
125851
125819
|
};
|
|
125852
125820
|
}
|
|
125853
|
-
function calculateRequestBytes(body) {
|
|
125854
|
-
if (body === null || body === undefined) {
|
|
125855
|
-
return 0;
|
|
125856
|
-
}
|
|
125857
|
-
if (typeof body === "string") {
|
|
125858
|
-
return Buffer.byteLength(body, "utf8");
|
|
125859
|
-
}
|
|
125860
|
-
return Buffer.byteLength(JSON.stringify(body), "utf8");
|
|
125861
|
-
}
|
|
125862
|
-
function calculateTokensPerSecond({ durationMs, totalTokens }) {
|
|
125863
|
-
if (durationMs <= 0) {
|
|
125864
|
-
return 0;
|
|
125865
|
-
}
|
|
125866
|
-
const tokensPerSecond = totalTokens / (durationMs / 1000);
|
|
125867
|
-
if (!Number.isFinite(tokensPerSecond) || tokensPerSecond <= 0) {
|
|
125868
|
-
return 0;
|
|
125869
|
-
}
|
|
125870
|
-
return Math.round(tokensPerSecond);
|
|
125871
|
-
}
|
|
125872
125821
|
|
|
125873
125822
|
const ENGINE_FETCH_TIMEOUT_MS = 7_200_000;
|
|
125874
125823
|
const LOOPBACK_AGENT = new undiciExports.Agent({
|
|
@@ -136041,10 +135990,8 @@ async function createApplication({ abortController, apiClient, configuration, lo
|
|
|
136041
135990
|
});
|
|
136042
135991
|
handleSSERequests({
|
|
136043
135992
|
apiURL: configuration.apiURL,
|
|
136044
|
-
conduitConfiguration: () => conduitConfiguration,
|
|
136045
135993
|
configuration,
|
|
136046
135994
|
logger,
|
|
136047
|
-
modelID: conduitConfiguration.targetModel.id,
|
|
136048
135995
|
onRequest: async ({ request, signal }) => {
|
|
136049
135996
|
return proxyRequest({
|
|
136050
135997
|
configuration,
|
|
@@ -136061,7 +136008,6 @@ async function createApplication({ abortController, apiClient, configuration, lo
|
|
|
136061
136008
|
conduitStateManager.incrementActiveRequestCount();
|
|
136062
136009
|
conduitStateReportManager.reportStateChange();
|
|
136063
136010
|
},
|
|
136064
|
-
reportMetrics: apiClient.reportPromptMetrics,
|
|
136065
136011
|
signal: abortController.signal
|
|
136066
136012
|
}).catch(error => {
|
|
136067
136013
|
logger.error("SSE handler failed", {
|
package/dist/cli.sea.cjs
CHANGED
|
@@ -122322,16 +122322,17 @@ const DOWNLOAD_PROGRESS_TIMEOUT = 60000;
|
|
|
122322
122322
|
const DOWNLOAD_RETRY_ATTEMPTS_FULL = 3;
|
|
122323
122323
|
const DOWNLOAD_RETRY_ATTEMPTS_RANGE = 10;
|
|
122324
122324
|
const ALLOWED_EXTENSIONS = new Set([
|
|
122325
|
+
".bin",
|
|
122326
|
+
".gguf",
|
|
122325
122327
|
".gitattributes",
|
|
122328
|
+
".jinja",
|
|
122326
122329
|
".json",
|
|
122327
122330
|
".merges",
|
|
122328
122331
|
".model",
|
|
122329
122332
|
".py",
|
|
122330
122333
|
".safetensors",
|
|
122331
122334
|
".tiktoken",
|
|
122332
|
-
".txt"
|
|
122333
|
-
".bin",
|
|
122334
|
-
".gguf"
|
|
122335
|
+
".txt"
|
|
122335
122336
|
]);
|
|
122336
122337
|
function isAllowedFile(filePath) {
|
|
122337
122338
|
const lower = filePath.toLowerCase();
|
|
@@ -124201,12 +124202,17 @@ function serializeRequestBody$1(body) {
|
|
|
124201
124202
|
};
|
|
124202
124203
|
}
|
|
124203
124204
|
const requestPayload = { ...body };
|
|
124204
|
-
|
|
124205
|
-
|
|
124206
|
-
|
|
124207
|
-
|
|
124208
|
-
|
|
124209
|
-
|
|
124205
|
+
if (requestPayload.stream === true) {
|
|
124206
|
+
const streamOptions = requestPayload.stream_options;
|
|
124207
|
+
const normalizedStreamOptions = isPlainObject$3(streamOptions)
|
|
124208
|
+
? { ...streamOptions }
|
|
124209
|
+
: {};
|
|
124210
|
+
normalizedStreamOptions.include_usage = true;
|
|
124211
|
+
requestPayload.stream_options = normalizedStreamOptions;
|
|
124212
|
+
}
|
|
124213
|
+
else {
|
|
124214
|
+
delete requestPayload.stream_options;
|
|
124215
|
+
}
|
|
124210
124216
|
if (requestPayload.repetition_penalty === undefined) {
|
|
124211
124217
|
requestPayload.repetition_penalty = 1.1;
|
|
124212
124218
|
}
|
|
@@ -124216,11 +124222,17 @@ function serializeRequestBody$1(body) {
|
|
|
124216
124222
|
payload
|
|
124217
124223
|
};
|
|
124218
124224
|
}
|
|
124219
|
-
function calculateTokensPerSecond$
|
|
124220
|
-
if (durationMs <= 0) {
|
|
124225
|
+
function calculateTokensPerSecond$1({ completionTokens, durationMs, streamRequested, timeToFirstTokenMs }) {
|
|
124226
|
+
if (completionTokens <= 0 || durationMs <= 0) {
|
|
124227
|
+
return 0;
|
|
124228
|
+
}
|
|
124229
|
+
const decodeMs = streamRequested && timeToFirstTokenMs !== null && timeToFirstTokenMs > 0
|
|
124230
|
+
? Math.max(0, durationMs - timeToFirstTokenMs)
|
|
124231
|
+
: durationMs;
|
|
124232
|
+
if (decodeMs <= 0) {
|
|
124221
124233
|
return 0;
|
|
124222
124234
|
}
|
|
124223
|
-
const tokensPerSecond =
|
|
124235
|
+
const tokensPerSecond = completionTokens / (decodeMs / 1000);
|
|
124224
124236
|
if (!Number.isFinite(tokensPerSecond) || tokensPerSecond <= 0) {
|
|
124225
124237
|
return 0;
|
|
124226
124238
|
}
|
|
@@ -124270,10 +124282,7 @@ async function proxyEmbeddingsRoute({ body, conduitConfiguration, endpointId, lo
|
|
|
124270
124282
|
responseBytes,
|
|
124271
124283
|
successful: upstreamResponseOk && !error,
|
|
124272
124284
|
timeToFirstTokenMs: null,
|
|
124273
|
-
tokensPerSecond:
|
|
124274
|
-
durationMs: latencyMs,
|
|
124275
|
-
totalTokens
|
|
124276
|
-
}),
|
|
124285
|
+
tokensPerSecond: 0,
|
|
124277
124286
|
totalTokens
|
|
124278
124287
|
});
|
|
124279
124288
|
};
|
|
@@ -124416,9 +124425,11 @@ async function proxyOpenAIStreamingRoute({ body, conduitConfiguration, endpointI
|
|
|
124416
124425
|
responseBytes,
|
|
124417
124426
|
successful: upstreamResponseOk && !error,
|
|
124418
124427
|
timeToFirstTokenMs,
|
|
124419
|
-
tokensPerSecond: calculateTokensPerSecond$
|
|
124428
|
+
tokensPerSecond: calculateTokensPerSecond$1({
|
|
124429
|
+
completionTokens,
|
|
124420
124430
|
durationMs: latencyMs,
|
|
124421
|
-
|
|
124431
|
+
streamRequested,
|
|
124432
|
+
timeToFirstTokenMs
|
|
124422
124433
|
}),
|
|
124423
124434
|
totalTokens
|
|
124424
124435
|
});
|
|
@@ -124866,10 +124877,15 @@ function serializeRequestBody(body) {
|
|
|
124866
124877
|
payload
|
|
124867
124878
|
};
|
|
124868
124879
|
}
|
|
124869
|
-
function calculateTokensPerSecond
|
|
124870
|
-
if (durationMs <= 0)
|
|
124880
|
+
function calculateTokensPerSecond({ completionTokens, durationMs, streamRequested, timeToFirstTokenMs }) {
|
|
124881
|
+
if (completionTokens <= 0 || durationMs <= 0)
|
|
124882
|
+
return 0;
|
|
124883
|
+
const decodeMs = streamRequested && timeToFirstTokenMs !== null && timeToFirstTokenMs > 0
|
|
124884
|
+
? Math.max(0, durationMs - timeToFirstTokenMs)
|
|
124885
|
+
: durationMs;
|
|
124886
|
+
if (decodeMs <= 0)
|
|
124871
124887
|
return 0;
|
|
124872
|
-
const tokensPerSecond =
|
|
124888
|
+
const tokensPerSecond = completionTokens / (decodeMs / 1000);
|
|
124873
124889
|
if (!Number.isFinite(tokensPerSecond) || tokensPerSecond <= 0)
|
|
124874
124890
|
return 0;
|
|
124875
124891
|
return Math.round(tokensPerSecond);
|
|
@@ -125047,7 +125063,7 @@ async function proxyAnthropicStreamingRoute({ body, conduitConfiguration, endpoi
|
|
|
125047
125063
|
const targetBody = needsTranslation
|
|
125048
125064
|
? translateAnthropicRequestToOpenAI(serializedBody).body
|
|
125049
125065
|
: serializedBody;
|
|
125050
|
-
const onMonitoringComplete = ({ durationMs, error, responseBytes, usage }) => {
|
|
125066
|
+
const onMonitoringComplete = ({ durationMs, error, responseBytes, timeToFirstTokenMs, usage }) => {
|
|
125051
125067
|
const promptTokens = normalizeTokenCount(usage?.inputTokens);
|
|
125052
125068
|
const completionTokens = normalizeTokenCount(usage?.outputTokens);
|
|
125053
125069
|
const totalTokens = promptTokens + completionTokens;
|
|
@@ -125066,10 +125082,12 @@ async function proxyAnthropicStreamingRoute({ body, conduitConfiguration, endpoi
|
|
|
125066
125082
|
requestPath: "/v1/messages",
|
|
125067
125083
|
responseBytes,
|
|
125068
125084
|
successful: !error,
|
|
125069
|
-
timeToFirstTokenMs
|
|
125070
|
-
tokensPerSecond: calculateTokensPerSecond
|
|
125085
|
+
timeToFirstTokenMs,
|
|
125086
|
+
tokensPerSecond: calculateTokensPerSecond({
|
|
125087
|
+
completionTokens,
|
|
125071
125088
|
durationMs: latencyMs,
|
|
125072
|
-
|
|
125089
|
+
streamRequested,
|
|
125090
|
+
timeToFirstTokenMs
|
|
125073
125091
|
}),
|
|
125074
125092
|
totalTokens
|
|
125075
125093
|
});
|
|
@@ -125166,6 +125184,7 @@ async function proxyAnthropicStreamingRoute({ body, conduitConfiguration, endpoi
|
|
|
125166
125184
|
const passThrough = new require$$0$8.PassThrough();
|
|
125167
125185
|
let responseBytes = 0;
|
|
125168
125186
|
let completed = false;
|
|
125187
|
+
let firstChunkAt = null;
|
|
125169
125188
|
const usage = { inputTokens: null, outputTokens: null };
|
|
125170
125189
|
const upstreamError = response.ok
|
|
125171
125190
|
? null
|
|
@@ -125178,6 +125197,7 @@ async function proxyAnthropicStreamingRoute({ body, conduitConfiguration, endpoi
|
|
|
125178
125197
|
durationMs: Math.max(0, Date.now() - requestStartedAt),
|
|
125179
125198
|
error,
|
|
125180
125199
|
responseBytes,
|
|
125200
|
+
timeToFirstTokenMs: firstChunkAt === null ? null : Math.max(0, firstChunkAt - requestStartedAt),
|
|
125181
125201
|
usage
|
|
125182
125202
|
});
|
|
125183
125203
|
}
|
|
@@ -125187,6 +125207,8 @@ async function proxyAnthropicStreamingRoute({ body, conduitConfiguration, endpoi
|
|
|
125187
125207
|
const chunks = [];
|
|
125188
125208
|
rawBody.on("data", (chunk) => {
|
|
125189
125209
|
const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
125210
|
+
if (firstChunkAt === null)
|
|
125211
|
+
firstChunkAt = Date.now();
|
|
125190
125212
|
responseBytes += chunkBuffer.length;
|
|
125191
125213
|
chunks.push(chunkBuffer);
|
|
125192
125214
|
});
|
|
@@ -125269,6 +125291,8 @@ async function proxyAnthropicStreamingRoute({ body, conduitConfiguration, endpoi
|
|
|
125269
125291
|
let buffer = "";
|
|
125270
125292
|
rawBody.on("data", (chunk) => {
|
|
125271
125293
|
const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
125294
|
+
if (firstChunkAt === null)
|
|
125295
|
+
firstChunkAt = Date.now();
|
|
125272
125296
|
responseBytes += chunkBuffer.length;
|
|
125273
125297
|
buffer += chunkBuffer.toString("utf8");
|
|
125274
125298
|
const lines = buffer.split("\n");
|
|
@@ -125339,6 +125363,8 @@ async function proxyAnthropicStreamingRoute({ body, conduitConfiguration, endpoi
|
|
|
125339
125363
|
const chunks = [];
|
|
125340
125364
|
rawBody.on("data", (chunk) => {
|
|
125341
125365
|
const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
125366
|
+
if (firstChunkAt === null)
|
|
125367
|
+
firstChunkAt = Date.now();
|
|
125342
125368
|
responseBytes += chunkBuffer.length;
|
|
125343
125369
|
chunks.push(chunkBuffer);
|
|
125344
125370
|
});
|
|
@@ -125489,7 +125515,7 @@ function createHealthHandler() {
|
|
|
125489
125515
|
};
|
|
125490
125516
|
}
|
|
125491
125517
|
|
|
125492
|
-
async function handleSSERequests({ apiURL,
|
|
125518
|
+
async function handleSSERequests({ apiURL, configuration, logger, onRequest, onRequestEnd, onRequestStart, signal }) {
|
|
125493
125519
|
const streamURL = `${apiURL}/conduit/api/v1/source/${configuration.inferenceSourceID}/requests/stream`;
|
|
125494
125520
|
const maxReconnectDelayMs = 30000;
|
|
125495
125521
|
let reconnectAttempt = 0;
|
|
@@ -125531,14 +125557,11 @@ async function handleSSERequests({ apiURL, conduitConfiguration, configuration,
|
|
|
125531
125557
|
handleRequest({
|
|
125532
125558
|
activeRequests,
|
|
125533
125559
|
apiURL,
|
|
125534
|
-
conduitConfiguration,
|
|
125535
125560
|
configuration,
|
|
125536
125561
|
logger,
|
|
125537
|
-
modelID,
|
|
125538
125562
|
onRequest,
|
|
125539
125563
|
onRequestEnd,
|
|
125540
125564
|
onRequestStart,
|
|
125541
|
-
reportMetrics,
|
|
125542
125565
|
request: payload,
|
|
125543
125566
|
signal: effectiveSignal
|
|
125544
125567
|
}).catch(error => {
|
|
@@ -125575,23 +125598,12 @@ async function handleSSERequests({ apiURL, conduitConfiguration, configuration,
|
|
|
125575
125598
|
}
|
|
125576
125599
|
}
|
|
125577
125600
|
}
|
|
125578
|
-
async function handleRequest({ activeRequests, apiURL,
|
|
125579
|
-
function reportMetricsSafe(payload) {
|
|
125580
|
-
reportMetrics(payload).catch(error => {
|
|
125581
|
-
logger.warn("Failed to upload LLM prompt metrics", {
|
|
125582
|
-
error: asError(error),
|
|
125583
|
-
requestUrl: request.path
|
|
125584
|
-
});
|
|
125585
|
-
});
|
|
125586
|
-
}
|
|
125587
|
-
const engineType = conduitConfiguration().engineConfig?.type ?? null;
|
|
125588
|
-
const endpointId = request.parameters?.endpointID ?? null;
|
|
125601
|
+
async function handleRequest({ activeRequests, apiURL, configuration, logger, onRequest, onRequestEnd, onRequestStart, request, signal }) {
|
|
125589
125602
|
const requestStartedAt = Date.now();
|
|
125590
|
-
const requestBytes = calculateRequestBytes(request.body ?? null);
|
|
125591
125603
|
try {
|
|
125592
125604
|
await onRequestStart?.(request);
|
|
125593
125605
|
const response = await onRequest({ request, signal });
|
|
125594
|
-
|
|
125606
|
+
await streamResponse({
|
|
125595
125607
|
apiURL,
|
|
125596
125608
|
configuration,
|
|
125597
125609
|
logger,
|
|
@@ -125600,30 +125612,6 @@ async function handleRequest({ activeRequests, apiURL, conduitConfiguration, con
|
|
|
125600
125612
|
response,
|
|
125601
125613
|
signal
|
|
125602
125614
|
});
|
|
125603
|
-
const latencyMs = Math.max(0, Date.now() - requestStartedAt);
|
|
125604
|
-
const totalTokens = 0;
|
|
125605
|
-
const tokensPerSecond = calculateTokensPerSecond({
|
|
125606
|
-
durationMs: latencyMs,
|
|
125607
|
-
totalTokens
|
|
125608
|
-
});
|
|
125609
|
-
reportMetricsSafe({
|
|
125610
|
-
bytes: requestBytes + responseMetrics.responseBytes,
|
|
125611
|
-
completionTokens: 0,
|
|
125612
|
-
engine: engineType,
|
|
125613
|
-
endpointId,
|
|
125614
|
-
latencyMs,
|
|
125615
|
-
modelId: modelID,
|
|
125616
|
-
promptTokens: 0,
|
|
125617
|
-
requestBytes,
|
|
125618
|
-
requestId: request.requestID,
|
|
125619
|
-
requestMethod: request.method,
|
|
125620
|
-
requestPath: request.path,
|
|
125621
|
-
responseBytes: responseMetrics.responseBytes,
|
|
125622
|
-
successful: responseMetrics.status < 400,
|
|
125623
|
-
timeToFirstTokenMs: responseMetrics.timeToFirstTokenMs,
|
|
125624
|
-
tokensPerSecond,
|
|
125625
|
-
totalTokens
|
|
125626
|
-
});
|
|
125627
125615
|
}
|
|
125628
125616
|
catch (error) {
|
|
125629
125617
|
const isCancelled = signal?.aborted;
|
|
@@ -125639,8 +125627,6 @@ async function handleRequest({ activeRequests, apiURL, conduitConfiguration, con
|
|
|
125639
125627
|
});
|
|
125640
125628
|
}
|
|
125641
125629
|
const failureMessage = "Bad gateway\n\nProxying failed";
|
|
125642
|
-
const failureBytes = Buffer.byteLength(failureMessage, "utf8");
|
|
125643
|
-
const latencyMs = Math.max(0, Date.now() - requestStartedAt);
|
|
125644
125630
|
if (!isCancelled) {
|
|
125645
125631
|
const streamHandler = await sendChunkStream({
|
|
125646
125632
|
apiURL,
|
|
@@ -125660,24 +125646,6 @@ async function handleRequest({ activeRequests, apiURL, conduitConfiguration, con
|
|
|
125660
125646
|
});
|
|
125661
125647
|
await streamHandler.end();
|
|
125662
125648
|
}
|
|
125663
|
-
reportMetricsSafe({
|
|
125664
|
-
bytes: isCancelled ? requestBytes : requestBytes + failureBytes,
|
|
125665
|
-
completionTokens: 0,
|
|
125666
|
-
engine: engineType,
|
|
125667
|
-
endpointId,
|
|
125668
|
-
latencyMs,
|
|
125669
|
-
modelId: modelID,
|
|
125670
|
-
promptTokens: 0,
|
|
125671
|
-
requestBytes,
|
|
125672
|
-
requestId: request.requestID,
|
|
125673
|
-
requestMethod: request.method,
|
|
125674
|
-
requestPath: request.path,
|
|
125675
|
-
responseBytes: isCancelled ? 0 : failureBytes,
|
|
125676
|
-
successful: false,
|
|
125677
|
-
timeToFirstTokenMs: isCancelled ? null : latencyMs,
|
|
125678
|
-
tokensPerSecond: 0,
|
|
125679
|
-
totalTokens: 0
|
|
125680
|
-
});
|
|
125681
125649
|
}
|
|
125682
125650
|
finally {
|
|
125683
125651
|
activeRequests.delete(request.requestID);
|
|
@@ -125865,25 +125833,6 @@ async function sendChunkStream({ apiURL, configuration, requestID, logger }) {
|
|
|
125865
125833
|
abort
|
|
125866
125834
|
};
|
|
125867
125835
|
}
|
|
125868
|
-
function calculateRequestBytes(body) {
|
|
125869
|
-
if (body === null || body === undefined) {
|
|
125870
|
-
return 0;
|
|
125871
|
-
}
|
|
125872
|
-
if (typeof body === "string") {
|
|
125873
|
-
return Buffer.byteLength(body, "utf8");
|
|
125874
|
-
}
|
|
125875
|
-
return Buffer.byteLength(JSON.stringify(body), "utf8");
|
|
125876
|
-
}
|
|
125877
|
-
function calculateTokensPerSecond({ durationMs, totalTokens }) {
|
|
125878
|
-
if (durationMs <= 0) {
|
|
125879
|
-
return 0;
|
|
125880
|
-
}
|
|
125881
|
-
const tokensPerSecond = totalTokens / (durationMs / 1000);
|
|
125882
|
-
if (!Number.isFinite(tokensPerSecond) || tokensPerSecond <= 0) {
|
|
125883
|
-
return 0;
|
|
125884
|
-
}
|
|
125885
|
-
return Math.round(tokensPerSecond);
|
|
125886
|
-
}
|
|
125887
125836
|
|
|
125888
125837
|
const ENGINE_FETCH_TIMEOUT_MS = 7_200_000;
|
|
125889
125838
|
const LOOPBACK_AGENT = new undiciExports.Agent({
|
|
@@ -156271,10 +156220,8 @@ async function createApplication({ abortController, apiClient, configuration, lo
|
|
|
156271
156220
|
});
|
|
156272
156221
|
handleSSERequests({
|
|
156273
156222
|
apiURL: configuration.apiURL,
|
|
156274
|
-
conduitConfiguration: () => conduitConfiguration,
|
|
156275
156223
|
configuration,
|
|
156276
156224
|
logger,
|
|
156277
|
-
modelID: conduitConfiguration.targetModel.id,
|
|
156278
156225
|
onRequest: async ({ request, signal }) => {
|
|
156279
156226
|
return proxyRequest({
|
|
156280
156227
|
configuration,
|
|
@@ -156291,7 +156238,6 @@ async function createApplication({ abortController, apiClient, configuration, lo
|
|
|
156291
156238
|
conduitStateManager.incrementActiveRequestCount();
|
|
156292
156239
|
conduitStateReportManager.reportStateChange();
|
|
156293
156240
|
},
|
|
156294
|
-
reportMetrics: apiClient.reportPromptMetrics,
|
|
156295
156241
|
signal: abortController.signal
|
|
156296
156242
|
}).catch(error => {
|
|
156297
156243
|
logger.error("SSE handler failed", {
|
package/dist/sse/handler.d.ts
CHANGED
|
@@ -1,18 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { type APIResponse, type ServerToClientAPIRequest } from "@infersec/definitions";
|
|
2
2
|
import { Logger } from "@infersec/logger";
|
|
3
3
|
import { Configuration } from "../configuration.js";
|
|
4
|
-
export declare function handleSSERequests({ apiURL,
|
|
4
|
+
export declare function handleSSERequests({ apiURL, configuration, logger, onRequest, onRequestEnd, onRequestStart, signal }: {
|
|
5
5
|
apiURL: string;
|
|
6
|
-
conduitConfiguration: () => InferenceAgentConfiguration;
|
|
7
6
|
configuration: Configuration;
|
|
8
7
|
logger: Logger;
|
|
9
|
-
modelID: ULID;
|
|
10
8
|
onRequest: ({ request, signal }: {
|
|
11
9
|
request: ServerToClientAPIRequest;
|
|
12
10
|
signal?: AbortSignal;
|
|
13
11
|
}) => Promise<APIResponse>;
|
|
14
12
|
onRequestEnd?: (request: ServerToClientAPIRequest) => Promise<void> | void;
|
|
15
13
|
onRequestStart?: (request: ServerToClientAPIRequest) => Promise<void> | void;
|
|
16
|
-
reportMetrics: (payload: InferenceAgentLLMMetricsPayload) => Promise<void>;
|
|
17
14
|
signal?: AbortSignal;
|
|
18
15
|
}): Promise<void>;
|