@llmops/app 0.3.2-beta.3 → 0.3.3
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/index.cjs +95 -33
- package/dist/index.mjs +95 -33
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -16613,12 +16613,45 @@ const createGatewayAdapterMiddleware = () => {
|
|
|
16613
16613
|
*/
|
|
16614
16614
|
function createStreamingCostExtractor() {
|
|
16615
16615
|
let extractedUsage = null;
|
|
16616
|
+
let extractedHookResults = void 0;
|
|
16616
16617
|
let buffer = "";
|
|
16617
16618
|
let resolveUsage;
|
|
16618
16619
|
const usagePromise = new Promise((resolve) => {
|
|
16619
16620
|
resolveUsage = resolve;
|
|
16620
16621
|
});
|
|
16621
16622
|
const decoder = new TextDecoder();
|
|
16623
|
+
/**
|
|
16624
|
+
* Parse an SSE message and extract usage/hook_results
|
|
16625
|
+
*/
|
|
16626
|
+
function parseSSEMessage(message) {
|
|
16627
|
+
const trimmed = message.trim();
|
|
16628
|
+
if (!trimmed) return;
|
|
16629
|
+
const lines = trimmed.split("\n");
|
|
16630
|
+
let eventType = null;
|
|
16631
|
+
let dataLine = null;
|
|
16632
|
+
for (const line of lines) if (line.startsWith("event:")) eventType = line.slice(6).trim();
|
|
16633
|
+
else if (line.startsWith("data:")) dataLine = line.slice(5).trim();
|
|
16634
|
+
if (dataLine === "[DONE]") return;
|
|
16635
|
+
if (!dataLine) return;
|
|
16636
|
+
try {
|
|
16637
|
+
const parsed = JSON.parse(dataLine);
|
|
16638
|
+
if (eventType === "hook_results" || parsed.hook_results) {
|
|
16639
|
+
const hookData = parsed.hook_results || parsed;
|
|
16640
|
+
if (hookData.before_request_hooks || hookData.after_request_hooks) extractedHookResults = {
|
|
16641
|
+
before_request_hooks: hookData.before_request_hooks,
|
|
16642
|
+
after_request_hooks: hookData.after_request_hooks
|
|
16643
|
+
};
|
|
16644
|
+
}
|
|
16645
|
+
const usageData = parsed;
|
|
16646
|
+
if (usageData.usage) extractedUsage = {
|
|
16647
|
+
promptTokens: usageData.usage.prompt_tokens ?? 0,
|
|
16648
|
+
completionTokens: usageData.usage.completion_tokens ?? 0,
|
|
16649
|
+
totalTokens: usageData.usage.total_tokens ?? 0,
|
|
16650
|
+
cachedTokens: usageData.usage.prompt_tokens_details?.cached_tokens,
|
|
16651
|
+
hookResults: extractedHookResults
|
|
16652
|
+
};
|
|
16653
|
+
} catch {}
|
|
16654
|
+
}
|
|
16622
16655
|
return {
|
|
16623
16656
|
stream: new TransformStream({
|
|
16624
16657
|
transform(chunk, controller) {
|
|
@@ -16627,39 +16660,17 @@ function createStreamingCostExtractor() {
|
|
|
16627
16660
|
buffer += text;
|
|
16628
16661
|
const messages = buffer.split("\n\n");
|
|
16629
16662
|
buffer = messages.pop() || "";
|
|
16630
|
-
for (const message of messages)
|
|
16631
|
-
const trimmed = message.trim();
|
|
16632
|
-
if (!trimmed) continue;
|
|
16633
|
-
if (!trimmed.startsWith("data:")) continue;
|
|
16634
|
-
const jsonPart = trimmed.slice(5).trim();
|
|
16635
|
-
if (jsonPart === "[DONE]") continue;
|
|
16636
|
-
try {
|
|
16637
|
-
const parsed = JSON.parse(jsonPart);
|
|
16638
|
-
if (parsed.usage) extractedUsage = {
|
|
16639
|
-
promptTokens: parsed.usage.prompt_tokens ?? 0,
|
|
16640
|
-
completionTokens: parsed.usage.completion_tokens ?? 0,
|
|
16641
|
-
totalTokens: parsed.usage.total_tokens ?? 0,
|
|
16642
|
-
cachedTokens: parsed.usage.prompt_tokens_details?.cached_tokens
|
|
16643
|
-
};
|
|
16644
|
-
} catch {}
|
|
16645
|
-
}
|
|
16663
|
+
for (const message of messages) parseSSEMessage(message);
|
|
16646
16664
|
},
|
|
16647
16665
|
flush(controller) {
|
|
16648
|
-
if (buffer.trim())
|
|
16649
|
-
|
|
16650
|
-
|
|
16651
|
-
|
|
16652
|
-
|
|
16653
|
-
|
|
16654
|
-
|
|
16655
|
-
|
|
16656
|
-
completionTokens: parsed.usage.completion_tokens ?? 0,
|
|
16657
|
-
totalTokens: parsed.usage.total_tokens ?? 0,
|
|
16658
|
-
cachedTokens: parsed.usage.prompt_tokens_details?.cached_tokens
|
|
16659
|
-
};
|
|
16660
|
-
} catch {}
|
|
16661
|
-
}
|
|
16662
|
-
}
|
|
16666
|
+
if (buffer.trim()) parseSSEMessage(buffer);
|
|
16667
|
+
if (extractedUsage && extractedHookResults) extractedUsage.hookResults = extractedHookResults;
|
|
16668
|
+
else if (!extractedUsage && extractedHookResults) extractedUsage = {
|
|
16669
|
+
promptTokens: 0,
|
|
16670
|
+
completionTokens: 0,
|
|
16671
|
+
totalTokens: 0,
|
|
16672
|
+
hookResults: extractedHookResults
|
|
16673
|
+
};
|
|
16663
16674
|
resolveUsage(extractedUsage);
|
|
16664
16675
|
}
|
|
16665
16676
|
}),
|
|
@@ -16899,6 +16910,47 @@ var PricingProvider = class {
|
|
|
16899
16910
|
};
|
|
16900
16911
|
const pricingProvider = new PricingProvider();
|
|
16901
16912
|
/**
|
|
16913
|
+
* Transform gateway hook results to our schema format for telemetry
|
|
16914
|
+
*/
|
|
16915
|
+
function transformHookResultsToGuardrailResults(hookResults, wasBlocked) {
|
|
16916
|
+
if (!hookResults) return null;
|
|
16917
|
+
const beforeHooks = hookResults.before_request_hooks || [];
|
|
16918
|
+
const afterHooks = hookResults.after_request_hooks || [];
|
|
16919
|
+
if (beforeHooks.length === 0 && afterHooks.length === 0) return null;
|
|
16920
|
+
const results = [];
|
|
16921
|
+
let totalLatencyMs = 0;
|
|
16922
|
+
for (const hook of beforeHooks) {
|
|
16923
|
+
totalLatencyMs += hook.execution_time;
|
|
16924
|
+
for (const check$1 of hook.checks) results.push({
|
|
16925
|
+
checkId: check$1.id,
|
|
16926
|
+
functionId: check$1.id.split(".")[1] || check$1.id,
|
|
16927
|
+
hookType: "beforeRequestHook",
|
|
16928
|
+
verdict: check$1.verdict,
|
|
16929
|
+
latencyMs: check$1.execution_time
|
|
16930
|
+
});
|
|
16931
|
+
}
|
|
16932
|
+
for (const hook of afterHooks) {
|
|
16933
|
+
totalLatencyMs += hook.execution_time;
|
|
16934
|
+
for (const check$1 of hook.checks) results.push({
|
|
16935
|
+
checkId: check$1.id,
|
|
16936
|
+
functionId: check$1.id.split(".")[1] || check$1.id,
|
|
16937
|
+
hookType: "afterRequestHook",
|
|
16938
|
+
verdict: check$1.verdict,
|
|
16939
|
+
latencyMs: check$1.execution_time
|
|
16940
|
+
});
|
|
16941
|
+
}
|
|
16942
|
+
const anyFailed = results.some((r) => !r.verdict);
|
|
16943
|
+
let action;
|
|
16944
|
+
if (wasBlocked) action = "blocked";
|
|
16945
|
+
else if (anyFailed) action = "logged";
|
|
16946
|
+
else action = "allowed";
|
|
16947
|
+
return {
|
|
16948
|
+
results,
|
|
16949
|
+
action,
|
|
16950
|
+
totalLatencyMs
|
|
16951
|
+
};
|
|
16952
|
+
}
|
|
16953
|
+
/**
|
|
16902
16954
|
* Creates cost tracking middleware that logs LLM requests with usage and cost data.
|
|
16903
16955
|
*
|
|
16904
16956
|
* Features:
|
|
@@ -16976,6 +17028,7 @@ function createCostTrackingMiddleware(config$1 = {}) {
|
|
|
16976
17028
|
const { response: wrappedResponse, usagePromise } = wrapStreamingResponse(response);
|
|
16977
17029
|
c.res = wrappedResponse;
|
|
16978
17030
|
usagePromise.then(async (usage) => {
|
|
17031
|
+
const guardrailResults = usage?.hookResults ? transformHookResultsToGuardrailResults(usage.hookResults, statusCode === 446) : null;
|
|
16979
17032
|
await processUsageAndLog({
|
|
16980
17033
|
requestId,
|
|
16981
17034
|
provider,
|
|
@@ -16994,6 +17047,7 @@ function createCostTrackingMiddleware(config$1 = {}) {
|
|
|
16994
17047
|
totalTokens: usage.totalTokens,
|
|
16995
17048
|
cachedTokens: usage.cachedTokens
|
|
16996
17049
|
} : null,
|
|
17050
|
+
guardrailResults,
|
|
16997
17051
|
tags: customTags,
|
|
16998
17052
|
batchWriter,
|
|
16999
17053
|
trackErrors,
|
|
@@ -17004,6 +17058,7 @@ function createCostTrackingMiddleware(config$1 = {}) {
|
|
|
17004
17058
|
});
|
|
17005
17059
|
} else {
|
|
17006
17060
|
let usage = null;
|
|
17061
|
+
let guardrailResults = null;
|
|
17007
17062
|
try {
|
|
17008
17063
|
const responseBody = await response.clone().json();
|
|
17009
17064
|
if (responseBody.usage) usage = {
|
|
@@ -17012,6 +17067,11 @@ function createCostTrackingMiddleware(config$1 = {}) {
|
|
|
17012
17067
|
totalTokens: responseBody.usage.total_tokens || 0,
|
|
17013
17068
|
cachedTokens: responseBody.usage.prompt_tokens_details?.cached_tokens
|
|
17014
17069
|
};
|
|
17070
|
+
if (responseBody.hook_results) {
|
|
17071
|
+
const wasBlocked = statusCode === 446;
|
|
17072
|
+
guardrailResults = transformHookResultsToGuardrailResults(responseBody.hook_results, wasBlocked);
|
|
17073
|
+
if (guardrailResults) log(`Extracted guardrail results: ${guardrailResults.results.length} checks, action=${guardrailResults.action}`);
|
|
17074
|
+
}
|
|
17015
17075
|
} catch {
|
|
17016
17076
|
log("Failed to parse response body for usage");
|
|
17017
17077
|
}
|
|
@@ -17028,6 +17088,7 @@ function createCostTrackingMiddleware(config$1 = {}) {
|
|
|
17028
17088
|
latencyMs,
|
|
17029
17089
|
isStreaming: false,
|
|
17030
17090
|
usage,
|
|
17091
|
+
guardrailResults,
|
|
17031
17092
|
tags: customTags,
|
|
17032
17093
|
batchWriter,
|
|
17033
17094
|
trackErrors,
|
|
@@ -17040,7 +17101,7 @@ function createCostTrackingMiddleware(config$1 = {}) {
|
|
|
17040
17101
|
* Process usage data and log to batch writer
|
|
17041
17102
|
*/
|
|
17042
17103
|
async function processUsageAndLog(params) {
|
|
17043
|
-
const { requestId, provider, model, configId, variantId, environmentId, providerConfigId, endpoint, statusCode, latencyMs, isStreaming, usage, tags = {}, batchWriter, trackErrors, log } = params;
|
|
17104
|
+
const { requestId, provider, model, configId, variantId, environmentId, providerConfigId, endpoint, statusCode, latencyMs, isStreaming, usage, guardrailResults, tags = {}, batchWriter, trackErrors, log } = params;
|
|
17044
17105
|
if (!trackErrors && statusCode >= 400) {
|
|
17045
17106
|
log(`Skipping error response (${statusCode})`);
|
|
17046
17107
|
return;
|
|
@@ -17091,7 +17152,8 @@ async function processUsageAndLog(params) {
|
|
|
17091
17152
|
statusCode,
|
|
17092
17153
|
latencyMs,
|
|
17093
17154
|
isStreaming,
|
|
17094
|
-
tags
|
|
17155
|
+
tags,
|
|
17156
|
+
guardrailResults: guardrailResults || null
|
|
17095
17157
|
};
|
|
17096
17158
|
batchWriter.enqueue(requestData);
|
|
17097
17159
|
log(`Enqueued request ${requestId} for logging`);
|
package/dist/index.mjs
CHANGED
|
@@ -16585,12 +16585,45 @@ const createGatewayAdapterMiddleware = () => {
|
|
|
16585
16585
|
*/
|
|
16586
16586
|
function createStreamingCostExtractor() {
|
|
16587
16587
|
let extractedUsage = null;
|
|
16588
|
+
let extractedHookResults = void 0;
|
|
16588
16589
|
let buffer = "";
|
|
16589
16590
|
let resolveUsage;
|
|
16590
16591
|
const usagePromise = new Promise((resolve) => {
|
|
16591
16592
|
resolveUsage = resolve;
|
|
16592
16593
|
});
|
|
16593
16594
|
const decoder = new TextDecoder();
|
|
16595
|
+
/**
|
|
16596
|
+
* Parse an SSE message and extract usage/hook_results
|
|
16597
|
+
*/
|
|
16598
|
+
function parseSSEMessage(message) {
|
|
16599
|
+
const trimmed = message.trim();
|
|
16600
|
+
if (!trimmed) return;
|
|
16601
|
+
const lines = trimmed.split("\n");
|
|
16602
|
+
let eventType = null;
|
|
16603
|
+
let dataLine = null;
|
|
16604
|
+
for (const line of lines) if (line.startsWith("event:")) eventType = line.slice(6).trim();
|
|
16605
|
+
else if (line.startsWith("data:")) dataLine = line.slice(5).trim();
|
|
16606
|
+
if (dataLine === "[DONE]") return;
|
|
16607
|
+
if (!dataLine) return;
|
|
16608
|
+
try {
|
|
16609
|
+
const parsed = JSON.parse(dataLine);
|
|
16610
|
+
if (eventType === "hook_results" || parsed.hook_results) {
|
|
16611
|
+
const hookData = parsed.hook_results || parsed;
|
|
16612
|
+
if (hookData.before_request_hooks || hookData.after_request_hooks) extractedHookResults = {
|
|
16613
|
+
before_request_hooks: hookData.before_request_hooks,
|
|
16614
|
+
after_request_hooks: hookData.after_request_hooks
|
|
16615
|
+
};
|
|
16616
|
+
}
|
|
16617
|
+
const usageData = parsed;
|
|
16618
|
+
if (usageData.usage) extractedUsage = {
|
|
16619
|
+
promptTokens: usageData.usage.prompt_tokens ?? 0,
|
|
16620
|
+
completionTokens: usageData.usage.completion_tokens ?? 0,
|
|
16621
|
+
totalTokens: usageData.usage.total_tokens ?? 0,
|
|
16622
|
+
cachedTokens: usageData.usage.prompt_tokens_details?.cached_tokens,
|
|
16623
|
+
hookResults: extractedHookResults
|
|
16624
|
+
};
|
|
16625
|
+
} catch {}
|
|
16626
|
+
}
|
|
16594
16627
|
return {
|
|
16595
16628
|
stream: new TransformStream({
|
|
16596
16629
|
transform(chunk, controller) {
|
|
@@ -16599,39 +16632,17 @@ function createStreamingCostExtractor() {
|
|
|
16599
16632
|
buffer += text;
|
|
16600
16633
|
const messages = buffer.split("\n\n");
|
|
16601
16634
|
buffer = messages.pop() || "";
|
|
16602
|
-
for (const message of messages)
|
|
16603
|
-
const trimmed = message.trim();
|
|
16604
|
-
if (!trimmed) continue;
|
|
16605
|
-
if (!trimmed.startsWith("data:")) continue;
|
|
16606
|
-
const jsonPart = trimmed.slice(5).trim();
|
|
16607
|
-
if (jsonPart === "[DONE]") continue;
|
|
16608
|
-
try {
|
|
16609
|
-
const parsed = JSON.parse(jsonPart);
|
|
16610
|
-
if (parsed.usage) extractedUsage = {
|
|
16611
|
-
promptTokens: parsed.usage.prompt_tokens ?? 0,
|
|
16612
|
-
completionTokens: parsed.usage.completion_tokens ?? 0,
|
|
16613
|
-
totalTokens: parsed.usage.total_tokens ?? 0,
|
|
16614
|
-
cachedTokens: parsed.usage.prompt_tokens_details?.cached_tokens
|
|
16615
|
-
};
|
|
16616
|
-
} catch {}
|
|
16617
|
-
}
|
|
16635
|
+
for (const message of messages) parseSSEMessage(message);
|
|
16618
16636
|
},
|
|
16619
16637
|
flush(controller) {
|
|
16620
|
-
if (buffer.trim())
|
|
16621
|
-
|
|
16622
|
-
|
|
16623
|
-
|
|
16624
|
-
|
|
16625
|
-
|
|
16626
|
-
|
|
16627
|
-
|
|
16628
|
-
completionTokens: parsed.usage.completion_tokens ?? 0,
|
|
16629
|
-
totalTokens: parsed.usage.total_tokens ?? 0,
|
|
16630
|
-
cachedTokens: parsed.usage.prompt_tokens_details?.cached_tokens
|
|
16631
|
-
};
|
|
16632
|
-
} catch {}
|
|
16633
|
-
}
|
|
16634
|
-
}
|
|
16638
|
+
if (buffer.trim()) parseSSEMessage(buffer);
|
|
16639
|
+
if (extractedUsage && extractedHookResults) extractedUsage.hookResults = extractedHookResults;
|
|
16640
|
+
else if (!extractedUsage && extractedHookResults) extractedUsage = {
|
|
16641
|
+
promptTokens: 0,
|
|
16642
|
+
completionTokens: 0,
|
|
16643
|
+
totalTokens: 0,
|
|
16644
|
+
hookResults: extractedHookResults
|
|
16645
|
+
};
|
|
16635
16646
|
resolveUsage(extractedUsage);
|
|
16636
16647
|
}
|
|
16637
16648
|
}),
|
|
@@ -16871,6 +16882,47 @@ var PricingProvider = class {
|
|
|
16871
16882
|
};
|
|
16872
16883
|
const pricingProvider = new PricingProvider();
|
|
16873
16884
|
/**
|
|
16885
|
+
* Transform gateway hook results to our schema format for telemetry
|
|
16886
|
+
*/
|
|
16887
|
+
function transformHookResultsToGuardrailResults(hookResults, wasBlocked) {
|
|
16888
|
+
if (!hookResults) return null;
|
|
16889
|
+
const beforeHooks = hookResults.before_request_hooks || [];
|
|
16890
|
+
const afterHooks = hookResults.after_request_hooks || [];
|
|
16891
|
+
if (beforeHooks.length === 0 && afterHooks.length === 0) return null;
|
|
16892
|
+
const results = [];
|
|
16893
|
+
let totalLatencyMs = 0;
|
|
16894
|
+
for (const hook of beforeHooks) {
|
|
16895
|
+
totalLatencyMs += hook.execution_time;
|
|
16896
|
+
for (const check$1 of hook.checks) results.push({
|
|
16897
|
+
checkId: check$1.id,
|
|
16898
|
+
functionId: check$1.id.split(".")[1] || check$1.id,
|
|
16899
|
+
hookType: "beforeRequestHook",
|
|
16900
|
+
verdict: check$1.verdict,
|
|
16901
|
+
latencyMs: check$1.execution_time
|
|
16902
|
+
});
|
|
16903
|
+
}
|
|
16904
|
+
for (const hook of afterHooks) {
|
|
16905
|
+
totalLatencyMs += hook.execution_time;
|
|
16906
|
+
for (const check$1 of hook.checks) results.push({
|
|
16907
|
+
checkId: check$1.id,
|
|
16908
|
+
functionId: check$1.id.split(".")[1] || check$1.id,
|
|
16909
|
+
hookType: "afterRequestHook",
|
|
16910
|
+
verdict: check$1.verdict,
|
|
16911
|
+
latencyMs: check$1.execution_time
|
|
16912
|
+
});
|
|
16913
|
+
}
|
|
16914
|
+
const anyFailed = results.some((r) => !r.verdict);
|
|
16915
|
+
let action;
|
|
16916
|
+
if (wasBlocked) action = "blocked";
|
|
16917
|
+
else if (anyFailed) action = "logged";
|
|
16918
|
+
else action = "allowed";
|
|
16919
|
+
return {
|
|
16920
|
+
results,
|
|
16921
|
+
action,
|
|
16922
|
+
totalLatencyMs
|
|
16923
|
+
};
|
|
16924
|
+
}
|
|
16925
|
+
/**
|
|
16874
16926
|
* Creates cost tracking middleware that logs LLM requests with usage and cost data.
|
|
16875
16927
|
*
|
|
16876
16928
|
* Features:
|
|
@@ -16948,6 +17000,7 @@ function createCostTrackingMiddleware(config$1 = {}) {
|
|
|
16948
17000
|
const { response: wrappedResponse, usagePromise } = wrapStreamingResponse(response);
|
|
16949
17001
|
c.res = wrappedResponse;
|
|
16950
17002
|
usagePromise.then(async (usage) => {
|
|
17003
|
+
const guardrailResults = usage?.hookResults ? transformHookResultsToGuardrailResults(usage.hookResults, statusCode === 446) : null;
|
|
16951
17004
|
await processUsageAndLog({
|
|
16952
17005
|
requestId,
|
|
16953
17006
|
provider,
|
|
@@ -16966,6 +17019,7 @@ function createCostTrackingMiddleware(config$1 = {}) {
|
|
|
16966
17019
|
totalTokens: usage.totalTokens,
|
|
16967
17020
|
cachedTokens: usage.cachedTokens
|
|
16968
17021
|
} : null,
|
|
17022
|
+
guardrailResults,
|
|
16969
17023
|
tags: customTags,
|
|
16970
17024
|
batchWriter,
|
|
16971
17025
|
trackErrors,
|
|
@@ -16976,6 +17030,7 @@ function createCostTrackingMiddleware(config$1 = {}) {
|
|
|
16976
17030
|
});
|
|
16977
17031
|
} else {
|
|
16978
17032
|
let usage = null;
|
|
17033
|
+
let guardrailResults = null;
|
|
16979
17034
|
try {
|
|
16980
17035
|
const responseBody = await response.clone().json();
|
|
16981
17036
|
if (responseBody.usage) usage = {
|
|
@@ -16984,6 +17039,11 @@ function createCostTrackingMiddleware(config$1 = {}) {
|
|
|
16984
17039
|
totalTokens: responseBody.usage.total_tokens || 0,
|
|
16985
17040
|
cachedTokens: responseBody.usage.prompt_tokens_details?.cached_tokens
|
|
16986
17041
|
};
|
|
17042
|
+
if (responseBody.hook_results) {
|
|
17043
|
+
const wasBlocked = statusCode === 446;
|
|
17044
|
+
guardrailResults = transformHookResultsToGuardrailResults(responseBody.hook_results, wasBlocked);
|
|
17045
|
+
if (guardrailResults) log(`Extracted guardrail results: ${guardrailResults.results.length} checks, action=${guardrailResults.action}`);
|
|
17046
|
+
}
|
|
16987
17047
|
} catch {
|
|
16988
17048
|
log("Failed to parse response body for usage");
|
|
16989
17049
|
}
|
|
@@ -17000,6 +17060,7 @@ function createCostTrackingMiddleware(config$1 = {}) {
|
|
|
17000
17060
|
latencyMs,
|
|
17001
17061
|
isStreaming: false,
|
|
17002
17062
|
usage,
|
|
17063
|
+
guardrailResults,
|
|
17003
17064
|
tags: customTags,
|
|
17004
17065
|
batchWriter,
|
|
17005
17066
|
trackErrors,
|
|
@@ -17012,7 +17073,7 @@ function createCostTrackingMiddleware(config$1 = {}) {
|
|
|
17012
17073
|
* Process usage data and log to batch writer
|
|
17013
17074
|
*/
|
|
17014
17075
|
async function processUsageAndLog(params) {
|
|
17015
|
-
const { requestId, provider, model, configId, variantId, environmentId, providerConfigId, endpoint, statusCode, latencyMs, isStreaming, usage, tags = {}, batchWriter, trackErrors, log } = params;
|
|
17076
|
+
const { requestId, provider, model, configId, variantId, environmentId, providerConfigId, endpoint, statusCode, latencyMs, isStreaming, usage, guardrailResults, tags = {}, batchWriter, trackErrors, log } = params;
|
|
17016
17077
|
if (!trackErrors && statusCode >= 400) {
|
|
17017
17078
|
log(`Skipping error response (${statusCode})`);
|
|
17018
17079
|
return;
|
|
@@ -17063,7 +17124,8 @@ async function processUsageAndLog(params) {
|
|
|
17063
17124
|
statusCode,
|
|
17064
17125
|
latencyMs,
|
|
17065
17126
|
isStreaming,
|
|
17066
|
-
tags
|
|
17127
|
+
tags,
|
|
17128
|
+
guardrailResults: guardrailResults || null
|
|
17067
17129
|
};
|
|
17068
17130
|
batchWriter.enqueue(requestData);
|
|
17069
17131
|
log(`Enqueued request ${requestId} for logging`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@llmops/app",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"description": "LLMOps application with server and client",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -67,8 +67,8 @@
|
|
|
67
67
|
"react-aria-components": "^1.13.0",
|
|
68
68
|
"react-hook-form": "^7.68.0",
|
|
69
69
|
"recharts": "^3.6.0",
|
|
70
|
-
"@llmops/
|
|
71
|
-
"@llmops/
|
|
70
|
+
"@llmops/core": "^0.3.3",
|
|
71
|
+
"@llmops/gateway": "^0.3.3"
|
|
72
72
|
},
|
|
73
73
|
"peerDependencies": {
|
|
74
74
|
"react": "^19.2.1",
|