braintrust 3.7.0 → 3.8.0
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/LICENSE +201 -0
- package/dev/dist/index.d.mts +144 -2
- package/dev/dist/index.d.ts +144 -2
- package/dev/dist/index.js +3322 -799
- package/dev/dist/index.mjs +3214 -691
- package/dist/auto-instrumentations/bundler/esbuild.cjs +377 -13
- package/dist/auto-instrumentations/bundler/esbuild.mjs +2 -2
- package/dist/auto-instrumentations/bundler/rollup.cjs +377 -13
- package/dist/auto-instrumentations/bundler/rollup.mjs +2 -2
- package/dist/auto-instrumentations/bundler/vite.cjs +377 -13
- package/dist/auto-instrumentations/bundler/vite.mjs +2 -2
- package/dist/auto-instrumentations/bundler/webpack-loader.cjs +377 -13
- package/dist/auto-instrumentations/bundler/webpack-loader.d.ts +11 -9
- package/dist/auto-instrumentations/bundler/webpack.cjs +377 -13
- package/dist/auto-instrumentations/bundler/webpack.mjs +2 -2
- package/dist/auto-instrumentations/{chunk-EVUKFMHG.mjs → chunk-ITP7RAUY.mjs} +21 -3
- package/dist/auto-instrumentations/{chunk-ZK2IYER2.mjs → chunk-MD7W27YH.mjs} +5 -1
- package/dist/auto-instrumentations/{chunk-AKEXR4AL.mjs → chunk-OLBMPZXE.mjs} +378 -14
- package/dist/auto-instrumentations/{chunk-VLEJ5AEK.mjs → chunk-P5YLNB2A.mjs} +21 -3
- package/dist/auto-instrumentations/hook.mjs +393 -19
- package/dist/auto-instrumentations/index.cjs +379 -13
- package/dist/auto-instrumentations/index.d.mts +5 -1
- package/dist/auto-instrumentations/index.d.ts +5 -1
- package/dist/auto-instrumentations/index.mjs +5 -1
- package/dist/auto-instrumentations/loader/cjs-patch.cjs +34 -6
- package/dist/auto-instrumentations/loader/cjs-patch.d.mts +1 -0
- package/dist/auto-instrumentations/loader/cjs-patch.d.ts +1 -0
- package/dist/auto-instrumentations/loader/cjs-patch.mjs +15 -5
- package/dist/auto-instrumentations/loader/esm-hook.mjs +8 -3
- package/dist/auto-instrumentations/loader/get-package-version.cjs +20 -2
- package/dist/auto-instrumentations/loader/get-package-version.mjs +1 -1
- package/dist/browser.d.mts +199 -44
- package/dist/browser.d.ts +199 -44
- package/dist/browser.js +7086 -6747
- package/dist/browser.mjs +7086 -6747
- package/dist/cli.js +3200 -677
- package/dist/edge-light.d.mts +1 -1
- package/dist/edge-light.d.ts +1 -1
- package/dist/edge-light.js +12645 -12215
- package/dist/edge-light.mjs +12645 -12215
- package/dist/index.d.mts +199 -44
- package/dist/index.d.ts +199 -44
- package/dist/index.js +7173 -6834
- package/dist/index.mjs +7022 -6683
- package/dist/instrumentation/index.d.mts +7 -0
- package/dist/instrumentation/index.d.ts +7 -0
- package/dist/instrumentation/index.js +3170 -669
- package/dist/instrumentation/index.mjs +3170 -669
- package/dist/workerd.d.mts +1 -1
- package/dist/workerd.d.ts +1 -1
- package/dist/workerd.js +12645 -12215
- package/dist/workerd.mjs +12645 -12215
- package/package.json +45 -45
package/dev/dist/index.mjs
CHANGED
|
@@ -165,7 +165,7 @@ var DefaultTracingChannel = class {
|
|
|
165
165
|
}
|
|
166
166
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
167
167
|
tracePromise(fn, _message, thisArg, ...args) {
|
|
168
|
-
return
|
|
168
|
+
return fn.apply(thisArg, args);
|
|
169
169
|
}
|
|
170
170
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
171
171
|
traceCallback(fn, _position, _message, thisArg, ...args) {
|
|
@@ -185,6 +185,7 @@ var iso = {
|
|
|
185
185
|
processOn: (_0, _1) => {
|
|
186
186
|
},
|
|
187
187
|
basename: (filepath) => filepath.split(/[\\/]/).pop() || filepath,
|
|
188
|
+
// eslint-disable-next-line no-restricted-properties -- preserving intentional console usage.
|
|
188
189
|
writeln: (text) => console.log(text)
|
|
189
190
|
};
|
|
190
191
|
var isomorph_default = iso;
|
|
@@ -1881,6 +1882,15 @@ var InternalAbortError = class extends Error {
|
|
|
1881
1882
|
this.name = "InternalAbortError";
|
|
1882
1883
|
}
|
|
1883
1884
|
};
|
|
1885
|
+
function filterFrom(record, keys) {
|
|
1886
|
+
const out = {};
|
|
1887
|
+
for (const k of Object.keys(record)) {
|
|
1888
|
+
if (!keys.includes(k)) {
|
|
1889
|
+
out[k] = record[k];
|
|
1890
|
+
}
|
|
1891
|
+
}
|
|
1892
|
+
return out;
|
|
1893
|
+
}
|
|
1884
1894
|
|
|
1885
1895
|
// src/generated_types.ts
|
|
1886
1896
|
import { z as z6 } from "zod/v3";
|
|
@@ -2092,6 +2102,16 @@ var NullableSavedFunctionId = z6.union([
|
|
|
2092
2102
|
}),
|
|
2093
2103
|
z6.null()
|
|
2094
2104
|
]);
|
|
2105
|
+
var TopicMapGenerationSettings = z6.object({
|
|
2106
|
+
algorithm: z6.enum(["hdbscan", "kmeans"]),
|
|
2107
|
+
dimension_reduction: z6.enum(["umap", "pca", "none"]),
|
|
2108
|
+
sample_size: z6.number().int().gt(0).optional(),
|
|
2109
|
+
n_clusters: z6.number().int().gt(0).optional(),
|
|
2110
|
+
min_cluster_size: z6.number().int().gt(0).optional(),
|
|
2111
|
+
min_samples: z6.number().int().gt(0).optional(),
|
|
2112
|
+
hierarchy_threshold: z6.number().int().gt(0).optional(),
|
|
2113
|
+
naming_model: z6.string().optional()
|
|
2114
|
+
});
|
|
2095
2115
|
var TopicMapData = z6.object({
|
|
2096
2116
|
type: z6.literal("topic_map"),
|
|
2097
2117
|
source_facet: z6.string(),
|
|
@@ -2099,6 +2119,7 @@ var TopicMapData = z6.object({
|
|
|
2099
2119
|
bundle_key: z6.string().optional(),
|
|
2100
2120
|
report_key: z6.string().optional(),
|
|
2101
2121
|
topic_names: z6.record(z6.string()).optional(),
|
|
2122
|
+
generation_settings: TopicMapGenerationSettings.optional(),
|
|
2102
2123
|
distance_threshold: z6.number().optional()
|
|
2103
2124
|
});
|
|
2104
2125
|
var BatchedFacetData = z6.object({
|
|
@@ -2323,6 +2344,7 @@ var Dataset = z6.object({
|
|
|
2323
2344
|
created: z6.union([z6.string(), z6.null()]).optional(),
|
|
2324
2345
|
deleted_at: z6.union([z6.string(), z6.null()]).optional(),
|
|
2325
2346
|
user_id: z6.union([z6.string(), z6.null()]).optional(),
|
|
2347
|
+
tags: z6.union([z6.array(z6.string()), z6.null()]).optional(),
|
|
2326
2348
|
metadata: z6.union([z6.object({}).partial().passthrough(), z6.null()]).optional(),
|
|
2327
2349
|
url_slug: z6.string()
|
|
2328
2350
|
});
|
|
@@ -2405,6 +2427,14 @@ var DatasetEvent = z6.object({
|
|
|
2405
2427
|
z6.null()
|
|
2406
2428
|
]).optional()
|
|
2407
2429
|
});
|
|
2430
|
+
var DatasetSnapshot = z6.object({
|
|
2431
|
+
id: z6.string().uuid(),
|
|
2432
|
+
dataset_id: z6.string().uuid(),
|
|
2433
|
+
name: z6.string(),
|
|
2434
|
+
description: z6.union([z6.string(), z6.null()]),
|
|
2435
|
+
xact_id: z6.string(),
|
|
2436
|
+
created: z6.union([z6.string(), z6.null()])
|
|
2437
|
+
});
|
|
2408
2438
|
var EnvVar = z6.object({
|
|
2409
2439
|
id: z6.string().uuid(),
|
|
2410
2440
|
object_type: z6.enum(["organization", "project", "function"]),
|
|
@@ -3163,6 +3193,8 @@ var TopicAutomationConfig = z6.object({
|
|
|
3163
3193
|
scope: z6.union([SpanScope, TraceScope, GroupScope, z6.null()]).optional(),
|
|
3164
3194
|
data_scope: TopicAutomationDataScope.optional(),
|
|
3165
3195
|
btql_filter: z6.union([z6.string(), z6.null()]).optional(),
|
|
3196
|
+
rerun_seconds: z6.union([z6.number(), z6.null()]).optional(),
|
|
3197
|
+
relabel_overlap_seconds: z6.union([z6.number(), z6.null()]).optional(),
|
|
3166
3198
|
backfill_time_range: z6.union([
|
|
3167
3199
|
z6.string(),
|
|
3168
3200
|
z6.object({ from: z6.string(), to: z6.string() }),
|
|
@@ -3499,7 +3531,8 @@ var User = z6.object({
|
|
|
3499
3531
|
family_name: z6.union([z6.string(), z6.null()]).optional(),
|
|
3500
3532
|
email: z6.union([z6.string(), z6.null()]).optional(),
|
|
3501
3533
|
avatar_url: z6.union([z6.string(), z6.null()]).optional(),
|
|
3502
|
-
created: z6.union([z6.string(), z6.null()]).optional()
|
|
3534
|
+
created: z6.union([z6.string(), z6.null()]).optional(),
|
|
3535
|
+
last_active_at: z6.union([z6.number(), z6.null()]).optional()
|
|
3503
3536
|
});
|
|
3504
3537
|
var ViewDataSearch = z6.union([
|
|
3505
3538
|
z6.object({
|
|
@@ -4659,6 +4692,15 @@ var BRAINTRUST_CURRENT_SPAN_STORE = Symbol.for(
|
|
|
4659
4692
|
"braintrust.currentSpanStore"
|
|
4660
4693
|
);
|
|
4661
4694
|
var ContextManager = class {
|
|
4695
|
+
/**
|
|
4696
|
+
* Returns the value to store in the ALS bound to a TracingChannel's start event.
|
|
4697
|
+
* In default mode this is the Span itself; in OTEL mode it is the OTEL Context
|
|
4698
|
+
* containing the span so that OTEL's own ALS stores a proper Context object.
|
|
4699
|
+
*/
|
|
4700
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4701
|
+
wrapSpanForStore(span) {
|
|
4702
|
+
return span;
|
|
4703
|
+
}
|
|
4662
4704
|
};
|
|
4663
4705
|
var BraintrustContextManager = class extends ContextManager {
|
|
4664
4706
|
_currentSpan;
|
|
@@ -8874,7 +8916,7 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
8874
8916
|
if (!completed) {
|
|
8875
8917
|
completed = true;
|
|
8876
8918
|
try {
|
|
8877
|
-
options.onComplete(chunks);
|
|
8919
|
+
await options.onComplete(chunks);
|
|
8878
8920
|
} catch (error) {
|
|
8879
8921
|
console.error("Error in stream onComplete handler:", error);
|
|
8880
8922
|
}
|
|
@@ -8886,7 +8928,7 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
8886
8928
|
chunks.push(chunk);
|
|
8887
8929
|
if (options.onChunk) {
|
|
8888
8930
|
try {
|
|
8889
|
-
options.onChunk(chunk);
|
|
8931
|
+
await options.onChunk(chunk);
|
|
8890
8932
|
} catch (error) {
|
|
8891
8933
|
console.error("Error in stream onChunk handler:", error);
|
|
8892
8934
|
}
|
|
@@ -8899,7 +8941,7 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
8899
8941
|
completed = true;
|
|
8900
8942
|
if (options.onError) {
|
|
8901
8943
|
try {
|
|
8902
|
-
options.onError(
|
|
8944
|
+
await options.onError(
|
|
8903
8945
|
error instanceof Error ? error : new Error(String(error)),
|
|
8904
8946
|
chunks
|
|
8905
8947
|
);
|
|
@@ -8917,7 +8959,7 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
8917
8959
|
if (!completed) {
|
|
8918
8960
|
completed = true;
|
|
8919
8961
|
try {
|
|
8920
|
-
options.onComplete(chunks);
|
|
8962
|
+
await options.onComplete(chunks);
|
|
8921
8963
|
} catch (error) {
|
|
8922
8964
|
console.error("Error in stream onComplete handler:", error);
|
|
8923
8965
|
}
|
|
@@ -8934,7 +8976,7 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
8934
8976
|
const error = rawError instanceof Error ? rawError : new Error(String(rawError));
|
|
8935
8977
|
if (options.onError) {
|
|
8936
8978
|
try {
|
|
8937
|
-
options.onError(error, chunks);
|
|
8979
|
+
await options.onError(error, chunks);
|
|
8938
8980
|
} catch (handlerError) {
|
|
8939
8981
|
console.error("Error in stream onError handler:", handlerError);
|
|
8940
8982
|
}
|
|
@@ -9391,18 +9433,22 @@ function ensureSpanStateForEvent(states, config, event, channelName) {
|
|
|
9391
9433
|
function bindCurrentSpanStoreToStart(tracingChannel2, states, config, channelName) {
|
|
9392
9434
|
const state = _internalGetGlobalState();
|
|
9393
9435
|
const startChannel = tracingChannel2.start;
|
|
9394
|
-
const
|
|
9436
|
+
const contextManager = state?.contextManager;
|
|
9437
|
+
const currentSpanStore = contextManager ? contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
|
|
9395
9438
|
if (!currentSpanStore || !startChannel) {
|
|
9396
9439
|
return void 0;
|
|
9397
9440
|
}
|
|
9398
9441
|
startChannel.bindStore(
|
|
9399
9442
|
currentSpanStore,
|
|
9400
|
-
(event) =>
|
|
9401
|
-
|
|
9402
|
-
|
|
9403
|
-
|
|
9404
|
-
|
|
9405
|
-
|
|
9443
|
+
(event) => {
|
|
9444
|
+
const span = ensureSpanStateForEvent(
|
|
9445
|
+
states,
|
|
9446
|
+
config,
|
|
9447
|
+
event,
|
|
9448
|
+
channelName
|
|
9449
|
+
).span;
|
|
9450
|
+
return contextManager.wrapSpanForStore(span);
|
|
9451
|
+
}
|
|
9406
9452
|
);
|
|
9407
9453
|
return () => {
|
|
9408
9454
|
startChannel.unbindStore(currentSpanStore);
|
|
@@ -9419,6 +9465,26 @@ function logErrorAndEnd(states, event) {
|
|
|
9419
9465
|
spanData.span.end();
|
|
9420
9466
|
states.delete(event);
|
|
9421
9467
|
}
|
|
9468
|
+
function runStreamingCompletionHook(args) {
|
|
9469
|
+
if (!args.config.onComplete) {
|
|
9470
|
+
return;
|
|
9471
|
+
}
|
|
9472
|
+
try {
|
|
9473
|
+
args.config.onComplete({
|
|
9474
|
+
channelName: args.channelName,
|
|
9475
|
+
...args.chunks ? { chunks: args.chunks } : {},
|
|
9476
|
+
endEvent: args.endEvent,
|
|
9477
|
+
...args.metadata !== void 0 ? { metadata: args.metadata } : {},
|
|
9478
|
+
metrics: args.metrics,
|
|
9479
|
+
output: args.output,
|
|
9480
|
+
result: args.result,
|
|
9481
|
+
span: args.span,
|
|
9482
|
+
startTime: args.startTime
|
|
9483
|
+
});
|
|
9484
|
+
} catch (error) {
|
|
9485
|
+
console.error(`Error in onComplete hook for ${args.channelName}:`, error);
|
|
9486
|
+
}
|
|
9487
|
+
}
|
|
9422
9488
|
function traceAsyncChannel(channel2, config) {
|
|
9423
9489
|
const tracingChannel2 = channel2.tracingChannel();
|
|
9424
9490
|
const states = /* @__PURE__ */ new WeakMap();
|
|
@@ -9546,6 +9612,18 @@ function traceStreamingChannel(channel2, config) {
|
|
|
9546
9612
|
} else if (metrics.time_to_first_token === void 0 && chunks.length > 0) {
|
|
9547
9613
|
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
9548
9614
|
}
|
|
9615
|
+
runStreamingCompletionHook({
|
|
9616
|
+
channelName,
|
|
9617
|
+
chunks,
|
|
9618
|
+
config,
|
|
9619
|
+
endEvent: asyncEndEvent,
|
|
9620
|
+
...metadata !== void 0 ? { metadata } : {},
|
|
9621
|
+
metrics,
|
|
9622
|
+
output,
|
|
9623
|
+
result: asyncEndEvent.result,
|
|
9624
|
+
span,
|
|
9625
|
+
startTime
|
|
9626
|
+
});
|
|
9549
9627
|
span.log({
|
|
9550
9628
|
output,
|
|
9551
9629
|
...metadata !== void 0 ? { metadata } : {},
|
|
@@ -9595,6 +9673,17 @@ function traceStreamingChannel(channel2, config) {
|
|
|
9595
9673
|
asyncEndEvent.result,
|
|
9596
9674
|
asyncEndEvent
|
|
9597
9675
|
);
|
|
9676
|
+
runStreamingCompletionHook({
|
|
9677
|
+
channelName,
|
|
9678
|
+
config,
|
|
9679
|
+
endEvent: asyncEndEvent,
|
|
9680
|
+
...normalizeMetadata(metadata) !== void 0 ? { metadata: normalizeMetadata(metadata) } : {},
|
|
9681
|
+
metrics,
|
|
9682
|
+
output,
|
|
9683
|
+
result: asyncEndEvent.result,
|
|
9684
|
+
span,
|
|
9685
|
+
startTime
|
|
9686
|
+
});
|
|
9598
9687
|
span.log({
|
|
9599
9688
|
output,
|
|
9600
9689
|
...normalizeMetadata(metadata) !== void 0 ? { metadata: normalizeMetadata(metadata) } : {},
|
|
@@ -9643,51 +9732,28 @@ function traceSyncStreamChannel(channel2, config) {
|
|
|
9643
9732
|
}
|
|
9644
9733
|
const { span, startTime } = spanData;
|
|
9645
9734
|
const endEvent = event;
|
|
9646
|
-
|
|
9647
|
-
|
|
9648
|
-
|
|
9649
|
-
|
|
9650
|
-
|
|
9651
|
-
|
|
9652
|
-
|
|
9653
|
-
|
|
9654
|
-
|
|
9655
|
-
|
|
9656
|
-
|
|
9657
|
-
|
|
9658
|
-
|
|
9659
|
-
return;
|
|
9660
|
-
}
|
|
9661
|
-
let first = true;
|
|
9662
|
-
stream.on("chunk", () => {
|
|
9663
|
-
if (first) {
|
|
9664
|
-
span.log({
|
|
9665
|
-
metrics: {
|
|
9666
|
-
time_to_first_token: getCurrentUnixTimestamp() - startTime
|
|
9667
|
-
}
|
|
9668
|
-
});
|
|
9669
|
-
first = false;
|
|
9670
|
-
}
|
|
9671
|
-
});
|
|
9672
|
-
stream.on("chatCompletion", (completion) => {
|
|
9673
|
-
try {
|
|
9674
|
-
if (hasChoices(completion)) {
|
|
9675
|
-
span.log({
|
|
9676
|
-
output: completion.choices
|
|
9677
|
-
});
|
|
9678
|
-
}
|
|
9679
|
-
} catch (error) {
|
|
9680
|
-
console.error(
|
|
9681
|
-
`Error extracting chatCompletion for ${channelName}:`,
|
|
9682
|
-
error
|
|
9683
|
-
);
|
|
9735
|
+
const handleResolvedResult = (result) => {
|
|
9736
|
+
const resolvedEndEvent = {
|
|
9737
|
+
...endEvent,
|
|
9738
|
+
result
|
|
9739
|
+
};
|
|
9740
|
+
if (config.patchResult?.({
|
|
9741
|
+
channelName,
|
|
9742
|
+
endEvent: resolvedEndEvent,
|
|
9743
|
+
result,
|
|
9744
|
+
span,
|
|
9745
|
+
startTime
|
|
9746
|
+
})) {
|
|
9747
|
+
return;
|
|
9684
9748
|
}
|
|
9685
|
-
|
|
9686
|
-
|
|
9687
|
-
|
|
9749
|
+
const stream = result;
|
|
9750
|
+
if (!isSyncStreamLike(stream)) {
|
|
9751
|
+
span.end();
|
|
9752
|
+
states.delete(event);
|
|
9688
9753
|
return;
|
|
9689
9754
|
}
|
|
9690
|
-
|
|
9755
|
+
let first = true;
|
|
9756
|
+
stream.on("chunk", () => {
|
|
9691
9757
|
if (first) {
|
|
9692
9758
|
span.log({
|
|
9693
9759
|
metrics: {
|
|
@@ -9696,25 +9762,55 @@ function traceSyncStreamChannel(channel2, config) {
|
|
|
9696
9762
|
});
|
|
9697
9763
|
first = false;
|
|
9698
9764
|
}
|
|
9699
|
-
|
|
9700
|
-
|
|
9701
|
-
|
|
9765
|
+
});
|
|
9766
|
+
stream.on("chatCompletion", (completion) => {
|
|
9767
|
+
try {
|
|
9768
|
+
if (hasChoices(completion)) {
|
|
9769
|
+
span.log({
|
|
9770
|
+
output: completion.choices
|
|
9771
|
+
});
|
|
9772
|
+
}
|
|
9773
|
+
} catch (error) {
|
|
9774
|
+
console.error(
|
|
9775
|
+
`Error extracting chatCompletion for ${channelName}:`,
|
|
9776
|
+
error
|
|
9777
|
+
);
|
|
9702
9778
|
}
|
|
9703
|
-
} catch (error) {
|
|
9704
|
-
console.error(`Error extracting event for ${channelName}:`, error);
|
|
9705
|
-
}
|
|
9706
|
-
});
|
|
9707
|
-
stream.on("end", () => {
|
|
9708
|
-
span.end();
|
|
9709
|
-
states.delete(event);
|
|
9710
|
-
});
|
|
9711
|
-
stream.on("error", (error) => {
|
|
9712
|
-
span.log({
|
|
9713
|
-
error: error.message
|
|
9714
9779
|
});
|
|
9715
|
-
|
|
9716
|
-
|
|
9717
|
-
|
|
9780
|
+
stream.on("event", (streamEvent) => {
|
|
9781
|
+
if (!config.extractFromEvent) {
|
|
9782
|
+
return;
|
|
9783
|
+
}
|
|
9784
|
+
try {
|
|
9785
|
+
if (first) {
|
|
9786
|
+
span.log({
|
|
9787
|
+
metrics: {
|
|
9788
|
+
time_to_first_token: getCurrentUnixTimestamp() - startTime
|
|
9789
|
+
}
|
|
9790
|
+
});
|
|
9791
|
+
first = false;
|
|
9792
|
+
}
|
|
9793
|
+
const extracted = config.extractFromEvent(streamEvent);
|
|
9794
|
+
if (extracted && Object.keys(extracted).length > 0) {
|
|
9795
|
+
span.log(extracted);
|
|
9796
|
+
}
|
|
9797
|
+
} catch (error) {
|
|
9798
|
+
console.error(`Error extracting event for ${channelName}:`, error);
|
|
9799
|
+
}
|
|
9800
|
+
});
|
|
9801
|
+
stream.on("end", () => {
|
|
9802
|
+
span.end();
|
|
9803
|
+
states.delete(event);
|
|
9804
|
+
});
|
|
9805
|
+
stream.on("error", (error) => {
|
|
9806
|
+
span.log({
|
|
9807
|
+
error: error.message
|
|
9808
|
+
});
|
|
9809
|
+
span.end();
|
|
9810
|
+
states.delete(event);
|
|
9811
|
+
});
|
|
9812
|
+
};
|
|
9813
|
+
handleResolvedResult(endEvent.result);
|
|
9718
9814
|
},
|
|
9719
9815
|
error: (event) => {
|
|
9720
9816
|
logErrorAndEnd(states, event);
|
|
@@ -9971,6 +10067,10 @@ var openAIChannels = defineChannels("openai", {
|
|
|
9971
10067
|
responsesParse: channel({
|
|
9972
10068
|
channelName: "responses.parse",
|
|
9973
10069
|
kind: "async"
|
|
10070
|
+
}),
|
|
10071
|
+
responsesCompact: channel({
|
|
10072
|
+
channelName: "responses.compact",
|
|
10073
|
+
kind: "async"
|
|
9974
10074
|
})
|
|
9975
10075
|
});
|
|
9976
10076
|
|
|
@@ -10250,6 +10350,40 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
10250
10350
|
aggregateChunks: aggregateResponseStreamEvents
|
|
10251
10351
|
})
|
|
10252
10352
|
);
|
|
10353
|
+
this.unsubscribers.push(
|
|
10354
|
+
traceAsyncChannel(openAIChannels.responsesCompact, {
|
|
10355
|
+
name: "openai.responses.compact",
|
|
10356
|
+
type: "llm" /* LLM */,
|
|
10357
|
+
extractInput: ([params]) => {
|
|
10358
|
+
const { input, ...metadata } = params;
|
|
10359
|
+
return {
|
|
10360
|
+
input: processInputAttachments(input),
|
|
10361
|
+
metadata: { ...metadata, provider: "openai" }
|
|
10362
|
+
};
|
|
10363
|
+
},
|
|
10364
|
+
extractOutput: (result) => {
|
|
10365
|
+
return processImagesInOutput(result?.output);
|
|
10366
|
+
},
|
|
10367
|
+
extractMetadata: (result) => {
|
|
10368
|
+
if (!result) {
|
|
10369
|
+
return void 0;
|
|
10370
|
+
}
|
|
10371
|
+
const { output: _output, usage: _usage, ...metadata } = result;
|
|
10372
|
+
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
10373
|
+
},
|
|
10374
|
+
extractMetrics: (result, startTime, endEvent) => {
|
|
10375
|
+
const metrics = withCachedMetric(
|
|
10376
|
+
parseMetricsFromUsage(result?.usage),
|
|
10377
|
+
result,
|
|
10378
|
+
endEvent
|
|
10379
|
+
);
|
|
10380
|
+
if (startTime) {
|
|
10381
|
+
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
10382
|
+
}
|
|
10383
|
+
return metrics;
|
|
10384
|
+
}
|
|
10385
|
+
})
|
|
10386
|
+
);
|
|
10253
10387
|
}
|
|
10254
10388
|
onDisable() {
|
|
10255
10389
|
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
@@ -10537,28 +10671,40 @@ function aggregateAnthropicStreamChunks(chunks) {
|
|
|
10537
10671
|
case "content_block_start":
|
|
10538
10672
|
if (event.content_block) {
|
|
10539
10673
|
contentBlocks[event.index] = event.content_block;
|
|
10540
|
-
contentBlockDeltas[event.index] = [];
|
|
10674
|
+
contentBlockDeltas[event.index] = { textDeltas: [], citations: [] };
|
|
10541
10675
|
}
|
|
10542
10676
|
break;
|
|
10543
|
-
case "content_block_delta":
|
|
10544
|
-
|
|
10545
|
-
|
|
10677
|
+
case "content_block_delta": {
|
|
10678
|
+
const acc = contentBlockDeltas[event.index];
|
|
10679
|
+
const delta = event.delta;
|
|
10680
|
+
if (!delta) break;
|
|
10681
|
+
if (delta.type === "text_delta" && "text" in delta) {
|
|
10682
|
+
const text = delta.text;
|
|
10546
10683
|
if (text) {
|
|
10547
|
-
if (
|
|
10548
|
-
|
|
10549
|
-
contentBlockDeltas[event.index].push(text);
|
|
10684
|
+
if (acc !== void 0) {
|
|
10685
|
+
acc.textDeltas.push(text);
|
|
10550
10686
|
} else {
|
|
10551
10687
|
fallbackTextDeltas.push(text);
|
|
10552
10688
|
}
|
|
10553
10689
|
}
|
|
10554
|
-
} else if (
|
|
10555
|
-
const partialJson =
|
|
10556
|
-
if (partialJson) {
|
|
10557
|
-
|
|
10558
|
-
|
|
10690
|
+
} else if (delta.type === "input_json_delta" && "partial_json" in delta) {
|
|
10691
|
+
const partialJson = delta.partial_json;
|
|
10692
|
+
if (partialJson && acc !== void 0) {
|
|
10693
|
+
acc.textDeltas.push(partialJson);
|
|
10694
|
+
}
|
|
10695
|
+
} else if (delta.type === "thinking_delta" && "thinking" in delta) {
|
|
10696
|
+
const thinking = delta.thinking;
|
|
10697
|
+
if (thinking && acc !== void 0) {
|
|
10698
|
+
acc.textDeltas.push(thinking);
|
|
10699
|
+
}
|
|
10700
|
+
} else if (delta.type === "citations_delta" && "citation" in delta) {
|
|
10701
|
+
const citation = delta.citation;
|
|
10702
|
+
if (citation && acc !== void 0) {
|
|
10703
|
+
acc.citations.push(citation);
|
|
10559
10704
|
}
|
|
10560
10705
|
}
|
|
10561
10706
|
break;
|
|
10707
|
+
}
|
|
10562
10708
|
case "content_block_stop":
|
|
10563
10709
|
finalizeContentBlock(
|
|
10564
10710
|
event.index,
|
|
@@ -10584,7 +10730,7 @@ function aggregateAnthropicStreamChunks(chunks) {
|
|
|
10584
10730
|
})).filter(({ block }) => block !== void 0).sort((left, right) => left.index - right.index).map(({ block }) => block);
|
|
10585
10731
|
let output = fallbackTextDeltas.join("");
|
|
10586
10732
|
if (orderedContent.length > 0) {
|
|
10587
|
-
if (orderedContent.every(isTextContentBlock)) {
|
|
10733
|
+
if (orderedContent.every(isTextContentBlock) && orderedContent.every((block) => !block.citations?.length)) {
|
|
10588
10734
|
output = orderedContent.map((block) => block.text).join("");
|
|
10589
10735
|
} else {
|
|
10590
10736
|
output = {
|
|
@@ -10610,7 +10756,8 @@ function finalizeContentBlock(index, contentBlocks, contentBlockDeltas, fallback
|
|
|
10610
10756
|
if (!contentBlock) {
|
|
10611
10757
|
return;
|
|
10612
10758
|
}
|
|
10613
|
-
const
|
|
10759
|
+
const acc = contentBlockDeltas[index];
|
|
10760
|
+
const text = acc?.textDeltas.join("") ?? "";
|
|
10614
10761
|
if (isToolUseContentBlock(contentBlock)) {
|
|
10615
10762
|
if (!text) {
|
|
10616
10763
|
return;
|
|
@@ -10627,20 +10774,28 @@ function finalizeContentBlock(index, contentBlocks, contentBlockDeltas, fallback
|
|
|
10627
10774
|
return;
|
|
10628
10775
|
}
|
|
10629
10776
|
if (isTextContentBlock(contentBlock)) {
|
|
10777
|
+
if (!text) {
|
|
10778
|
+
delete contentBlocks[index];
|
|
10779
|
+
return;
|
|
10780
|
+
}
|
|
10781
|
+
const updated = { ...contentBlock, text };
|
|
10782
|
+
if (acc?.citations.length) {
|
|
10783
|
+
updated.citations = acc.citations;
|
|
10784
|
+
}
|
|
10785
|
+
contentBlocks[index] = updated;
|
|
10786
|
+
return;
|
|
10787
|
+
}
|
|
10788
|
+
if (isThinkingContentBlock(contentBlock)) {
|
|
10630
10789
|
if (!text) {
|
|
10631
10790
|
delete contentBlocks[index];
|
|
10632
10791
|
return;
|
|
10633
10792
|
}
|
|
10634
10793
|
contentBlocks[index] = {
|
|
10635
10794
|
...contentBlock,
|
|
10636
|
-
text
|
|
10795
|
+
thinking: text
|
|
10637
10796
|
};
|
|
10638
10797
|
return;
|
|
10639
10798
|
}
|
|
10640
|
-
if (text) {
|
|
10641
|
-
fallbackTextDeltas.push(text);
|
|
10642
|
-
}
|
|
10643
|
-
delete contentBlocks[index];
|
|
10644
10799
|
}
|
|
10645
10800
|
function isTextContentBlock(contentBlock) {
|
|
10646
10801
|
return contentBlock.type === "text";
|
|
@@ -10648,6 +10803,9 @@ function isTextContentBlock(contentBlock) {
|
|
|
10648
10803
|
function isToolUseContentBlock(contentBlock) {
|
|
10649
10804
|
return contentBlock.type === "tool_use";
|
|
10650
10805
|
}
|
|
10806
|
+
function isThinkingContentBlock(contentBlock) {
|
|
10807
|
+
return contentBlock.type === "thinking";
|
|
10808
|
+
}
|
|
10651
10809
|
function isAnthropicBase64ContentBlock(input) {
|
|
10652
10810
|
return (input.type === "image" || input.type === "document") && isObject(input.source) && input.source.type === "base64";
|
|
10653
10811
|
}
|
|
@@ -10702,15 +10860,6 @@ function coalesceInput(messages, system) {
|
|
|
10702
10860
|
}
|
|
10703
10861
|
return input;
|
|
10704
10862
|
}
|
|
10705
|
-
function filterFrom(obj, fieldsToRemove) {
|
|
10706
|
-
const result = {};
|
|
10707
|
-
for (const [key, value] of Object.entries(obj)) {
|
|
10708
|
-
if (!fieldsToRemove.includes(key)) {
|
|
10709
|
-
result[key] = value;
|
|
10710
|
-
}
|
|
10711
|
-
}
|
|
10712
|
-
return result;
|
|
10713
|
-
}
|
|
10714
10863
|
|
|
10715
10864
|
// src/wrappers/ai-sdk/normalize-logged-output.ts
|
|
10716
10865
|
var REMOVE_NORMALIZED_VALUE = Symbol("braintrust.ai-sdk.remove-normalized");
|
|
@@ -10840,6 +10989,16 @@ var aiSDKChannels = defineChannels("ai", {
|
|
|
10840
10989
|
channelName: "streamObject.sync",
|
|
10841
10990
|
kind: "sync-stream"
|
|
10842
10991
|
}),
|
|
10992
|
+
embed: channel(
|
|
10993
|
+
{
|
|
10994
|
+
channelName: "embed",
|
|
10995
|
+
kind: "async"
|
|
10996
|
+
}
|
|
10997
|
+
),
|
|
10998
|
+
embedMany: channel({
|
|
10999
|
+
channelName: "embedMany",
|
|
11000
|
+
kind: "async"
|
|
11001
|
+
}),
|
|
10843
11002
|
agentGenerate: channel({
|
|
10844
11003
|
channelName: "Agent.generate",
|
|
10845
11004
|
kind: "async"
|
|
@@ -10848,6 +11007,10 @@ var aiSDKChannels = defineChannels("ai", {
|
|
|
10848
11007
|
channelName: "Agent.stream",
|
|
10849
11008
|
kind: "async"
|
|
10850
11009
|
}),
|
|
11010
|
+
agentStreamSync: channel({
|
|
11011
|
+
channelName: "Agent.stream.sync",
|
|
11012
|
+
kind: "sync-stream"
|
|
11013
|
+
}),
|
|
10851
11014
|
toolLoopAgentGenerate: channel({
|
|
10852
11015
|
channelName: "ToolLoopAgent.generate",
|
|
10853
11016
|
kind: "async"
|
|
@@ -10875,6 +11038,9 @@ var DEFAULT_DENY_OUTPUT_PATHS = [
|
|
|
10875
11038
|
];
|
|
10876
11039
|
var AUTO_PATCHED_MODEL = Symbol.for("braintrust.ai-sdk.auto-patched-model");
|
|
10877
11040
|
var AUTO_PATCHED_TOOL = Symbol.for("braintrust.ai-sdk.auto-patched-tool");
|
|
11041
|
+
var RUNTIME_DENY_OUTPUT_PATHS = Symbol.for(
|
|
11042
|
+
"braintrust.ai-sdk.deny-output-paths"
|
|
11043
|
+
);
|
|
10878
11044
|
var AISDKPlugin = class extends BasePlugin {
|
|
10879
11045
|
config;
|
|
10880
11046
|
constructor(config = {}) {
|
|
@@ -10893,10 +11059,13 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
10893
11059
|
traceStreamingChannel(aiSDKChannels.generateText, {
|
|
10894
11060
|
name: "generateText",
|
|
10895
11061
|
type: "llm" /* LLM */,
|
|
10896
|
-
extractInput: ([params], event, span) =>
|
|
11062
|
+
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
10897
11063
|
extractOutput: (result, endEvent) => {
|
|
10898
11064
|
finalizeAISDKChildTracing(endEvent);
|
|
10899
|
-
return processAISDKOutput(
|
|
11065
|
+
return processAISDKOutput(
|
|
11066
|
+
result,
|
|
11067
|
+
resolveDenyOutputPaths(endEvent, denyOutputPaths)
|
|
11068
|
+
);
|
|
10900
11069
|
},
|
|
10901
11070
|
extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
|
|
10902
11071
|
aggregateChunks: aggregateAISDKChunks
|
|
@@ -10906,12 +11075,15 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
10906
11075
|
traceStreamingChannel(aiSDKChannels.streamText, {
|
|
10907
11076
|
name: "streamText",
|
|
10908
11077
|
type: "llm" /* LLM */,
|
|
10909
|
-
extractInput: ([params], event, span) =>
|
|
10910
|
-
extractOutput: (result) => processAISDKOutput(
|
|
11078
|
+
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
11079
|
+
extractOutput: (result, endEvent) => processAISDKOutput(
|
|
11080
|
+
result,
|
|
11081
|
+
resolveDenyOutputPaths(endEvent, denyOutputPaths)
|
|
11082
|
+
),
|
|
10911
11083
|
extractMetrics: (result, startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent, startTime),
|
|
10912
11084
|
aggregateChunks: aggregateAISDKChunks,
|
|
10913
11085
|
patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
|
|
10914
|
-
denyOutputPaths,
|
|
11086
|
+
defaultDenyOutputPaths: denyOutputPaths,
|
|
10915
11087
|
endEvent,
|
|
10916
11088
|
result,
|
|
10917
11089
|
span,
|
|
@@ -10923,9 +11095,9 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
10923
11095
|
traceSyncStreamChannel(aiSDKChannels.streamTextSync, {
|
|
10924
11096
|
name: "streamText",
|
|
10925
11097
|
type: "llm" /* LLM */,
|
|
10926
|
-
extractInput: ([params], event, span) =>
|
|
11098
|
+
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
10927
11099
|
patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
|
|
10928
|
-
denyOutputPaths,
|
|
11100
|
+
defaultDenyOutputPaths: denyOutputPaths,
|
|
10929
11101
|
endEvent,
|
|
10930
11102
|
result,
|
|
10931
11103
|
span,
|
|
@@ -10937,10 +11109,13 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
10937
11109
|
traceStreamingChannel(aiSDKChannels.generateObject, {
|
|
10938
11110
|
name: "generateObject",
|
|
10939
11111
|
type: "llm" /* LLM */,
|
|
10940
|
-
extractInput: ([params], event, span) =>
|
|
11112
|
+
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
10941
11113
|
extractOutput: (result, endEvent) => {
|
|
10942
11114
|
finalizeAISDKChildTracing(endEvent);
|
|
10943
|
-
return processAISDKOutput(
|
|
11115
|
+
return processAISDKOutput(
|
|
11116
|
+
result,
|
|
11117
|
+
resolveDenyOutputPaths(endEvent, denyOutputPaths)
|
|
11118
|
+
);
|
|
10944
11119
|
},
|
|
10945
11120
|
extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
|
|
10946
11121
|
aggregateChunks: aggregateAISDKChunks
|
|
@@ -10950,12 +11125,15 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
10950
11125
|
traceStreamingChannel(aiSDKChannels.streamObject, {
|
|
10951
11126
|
name: "streamObject",
|
|
10952
11127
|
type: "llm" /* LLM */,
|
|
10953
|
-
extractInput: ([params], event, span) =>
|
|
10954
|
-
extractOutput: (result) => processAISDKOutput(
|
|
11128
|
+
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
11129
|
+
extractOutput: (result, endEvent) => processAISDKOutput(
|
|
11130
|
+
result,
|
|
11131
|
+
resolveDenyOutputPaths(endEvent, denyOutputPaths)
|
|
11132
|
+
),
|
|
10955
11133
|
extractMetrics: (result, startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent, startTime),
|
|
10956
11134
|
aggregateChunks: aggregateAISDKChunks,
|
|
10957
11135
|
patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
|
|
10958
|
-
denyOutputPaths,
|
|
11136
|
+
defaultDenyOutputPaths: denyOutputPaths,
|
|
10959
11137
|
endEvent,
|
|
10960
11138
|
result,
|
|
10961
11139
|
span,
|
|
@@ -10967,9 +11145,9 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
10967
11145
|
traceSyncStreamChannel(aiSDKChannels.streamObjectSync, {
|
|
10968
11146
|
name: "streamObject",
|
|
10969
11147
|
type: "llm" /* LLM */,
|
|
10970
|
-
extractInput: ([params], event, span) =>
|
|
11148
|
+
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
10971
11149
|
patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
|
|
10972
|
-
denyOutputPaths,
|
|
11150
|
+
defaultDenyOutputPaths: denyOutputPaths,
|
|
10973
11151
|
endEvent,
|
|
10974
11152
|
result,
|
|
10975
11153
|
span,
|
|
@@ -10977,14 +11155,41 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
10977
11155
|
})
|
|
10978
11156
|
})
|
|
10979
11157
|
);
|
|
11158
|
+
this.unsubscribers.push(
|
|
11159
|
+
traceAsyncChannel(aiSDKChannels.embed, {
|
|
11160
|
+
name: "embed",
|
|
11161
|
+
type: "llm" /* LLM */,
|
|
11162
|
+
extractInput: ([params], event) => prepareAISDKEmbedInput(params, event.self),
|
|
11163
|
+
extractOutput: (result, endEvent) => processAISDKEmbeddingOutput(
|
|
11164
|
+
result,
|
|
11165
|
+
resolveDenyOutputPaths(endEvent, denyOutputPaths)
|
|
11166
|
+
),
|
|
11167
|
+
extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent)
|
|
11168
|
+
})
|
|
11169
|
+
);
|
|
11170
|
+
this.unsubscribers.push(
|
|
11171
|
+
traceAsyncChannel(aiSDKChannels.embedMany, {
|
|
11172
|
+
name: "embedMany",
|
|
11173
|
+
type: "llm" /* LLM */,
|
|
11174
|
+
extractInput: ([params], event) => prepareAISDKEmbedInput(params, event.self),
|
|
11175
|
+
extractOutput: (result, endEvent) => processAISDKEmbeddingOutput(
|
|
11176
|
+
result,
|
|
11177
|
+
resolveDenyOutputPaths(endEvent, denyOutputPaths)
|
|
11178
|
+
),
|
|
11179
|
+
extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent)
|
|
11180
|
+
})
|
|
11181
|
+
);
|
|
10980
11182
|
this.unsubscribers.push(
|
|
10981
11183
|
traceStreamingChannel(aiSDKChannels.agentGenerate, {
|
|
10982
11184
|
name: "Agent.generate",
|
|
10983
11185
|
type: "llm" /* LLM */,
|
|
10984
|
-
extractInput: ([params], event, span) =>
|
|
11186
|
+
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
10985
11187
|
extractOutput: (result, endEvent) => {
|
|
10986
11188
|
finalizeAISDKChildTracing(endEvent);
|
|
10987
|
-
return processAISDKOutput(
|
|
11189
|
+
return processAISDKOutput(
|
|
11190
|
+
result,
|
|
11191
|
+
resolveDenyOutputPaths(endEvent, denyOutputPaths)
|
|
11192
|
+
);
|
|
10988
11193
|
},
|
|
10989
11194
|
extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
|
|
10990
11195
|
aggregateChunks: aggregateAISDKChunks
|
|
@@ -10994,12 +11199,29 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
10994
11199
|
traceStreamingChannel(aiSDKChannels.agentStream, {
|
|
10995
11200
|
name: "Agent.stream",
|
|
10996
11201
|
type: "llm" /* LLM */,
|
|
10997
|
-
extractInput: ([params], event, span) =>
|
|
10998
|
-
extractOutput: (result) => processAISDKOutput(
|
|
11202
|
+
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
11203
|
+
extractOutput: (result, endEvent) => processAISDKOutput(
|
|
11204
|
+
result,
|
|
11205
|
+
resolveDenyOutputPaths(endEvent, denyOutputPaths)
|
|
11206
|
+
),
|
|
10999
11207
|
extractMetrics: (result, startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent, startTime),
|
|
11000
11208
|
aggregateChunks: aggregateAISDKChunks,
|
|
11001
11209
|
patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
|
|
11002
|
-
denyOutputPaths,
|
|
11210
|
+
defaultDenyOutputPaths: denyOutputPaths,
|
|
11211
|
+
endEvent,
|
|
11212
|
+
result,
|
|
11213
|
+
span,
|
|
11214
|
+
startTime
|
|
11215
|
+
})
|
|
11216
|
+
})
|
|
11217
|
+
);
|
|
11218
|
+
this.unsubscribers.push(
|
|
11219
|
+
traceSyncStreamChannel(aiSDKChannels.agentStreamSync, {
|
|
11220
|
+
name: "Agent.stream",
|
|
11221
|
+
type: "llm" /* LLM */,
|
|
11222
|
+
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
11223
|
+
patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
|
|
11224
|
+
defaultDenyOutputPaths: denyOutputPaths,
|
|
11003
11225
|
endEvent,
|
|
11004
11226
|
result,
|
|
11005
11227
|
span,
|
|
@@ -11011,10 +11233,13 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
11011
11233
|
traceStreamingChannel(aiSDKChannels.toolLoopAgentGenerate, {
|
|
11012
11234
|
name: "ToolLoopAgent.generate",
|
|
11013
11235
|
type: "llm" /* LLM */,
|
|
11014
|
-
extractInput: ([params], event, span) =>
|
|
11236
|
+
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
11015
11237
|
extractOutput: (result, endEvent) => {
|
|
11016
11238
|
finalizeAISDKChildTracing(endEvent);
|
|
11017
|
-
return processAISDKOutput(
|
|
11239
|
+
return processAISDKOutput(
|
|
11240
|
+
result,
|
|
11241
|
+
resolveDenyOutputPaths(endEvent, denyOutputPaths)
|
|
11242
|
+
);
|
|
11018
11243
|
},
|
|
11019
11244
|
extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
|
|
11020
11245
|
aggregateChunks: aggregateAISDKChunks
|
|
@@ -11024,12 +11249,15 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
11024
11249
|
traceStreamingChannel(aiSDKChannels.toolLoopAgentStream, {
|
|
11025
11250
|
name: "ToolLoopAgent.stream",
|
|
11026
11251
|
type: "llm" /* LLM */,
|
|
11027
|
-
extractInput: ([params], event, span) =>
|
|
11028
|
-
extractOutput: (result) => processAISDKOutput(
|
|
11252
|
+
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
11253
|
+
extractOutput: (result, endEvent) => processAISDKOutput(
|
|
11254
|
+
result,
|
|
11255
|
+
resolveDenyOutputPaths(endEvent, denyOutputPaths)
|
|
11256
|
+
),
|
|
11029
11257
|
extractMetrics: (result, startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent, startTime),
|
|
11030
11258
|
aggregateChunks: aggregateAISDKChunks,
|
|
11031
11259
|
patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
|
|
11032
|
-
denyOutputPaths,
|
|
11260
|
+
defaultDenyOutputPaths: denyOutputPaths,
|
|
11033
11261
|
endEvent,
|
|
11034
11262
|
result,
|
|
11035
11263
|
span,
|
|
@@ -11039,75 +11267,391 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
11039
11267
|
);
|
|
11040
11268
|
}
|
|
11041
11269
|
};
|
|
11042
|
-
function
|
|
11043
|
-
if (
|
|
11044
|
-
|
|
11045
|
-
if (!input || typeof input !== "object" || Array.isArray(input)) {
|
|
11046
|
-
return input;
|
|
11270
|
+
function resolveDenyOutputPaths(event, defaultDenyOutputPaths) {
|
|
11271
|
+
if (Array.isArray(event?.denyOutputPaths)) {
|
|
11272
|
+
return event.denyOutputPaths;
|
|
11047
11273
|
}
|
|
11048
|
-
const
|
|
11049
|
-
|
|
11050
|
-
|
|
11051
|
-
function prepareAISDKInput(params, event, span, denyOutputPaths) {
|
|
11052
|
-
const input = processAISDKInput(params);
|
|
11053
|
-
const metadata = extractMetadataFromParams(params, event.self);
|
|
11054
|
-
const childTracing = prepareAISDKChildTracing(
|
|
11055
|
-
params,
|
|
11056
|
-
event.self,
|
|
11057
|
-
span,
|
|
11058
|
-
denyOutputPaths
|
|
11059
|
-
);
|
|
11060
|
-
event.__braintrust_ai_sdk_model_wrapped = childTracing.modelWrapped;
|
|
11061
|
-
if (childTracing.cleanup) {
|
|
11062
|
-
event.__braintrust_ai_sdk_cleanup = childTracing.cleanup;
|
|
11274
|
+
const firstArgument = event?.arguments && event.arguments.length > 0 ? event.arguments[0] : void 0;
|
|
11275
|
+
if (!firstArgument || typeof firstArgument !== "object") {
|
|
11276
|
+
return defaultDenyOutputPaths;
|
|
11063
11277
|
}
|
|
11064
|
-
|
|
11065
|
-
|
|
11066
|
-
|
|
11067
|
-
};
|
|
11068
|
-
}
|
|
11069
|
-
function extractTopLevelAISDKMetrics(result, event, startTime) {
|
|
11070
|
-
const metrics = hasModelChildTracing(event) ? {} : extractTokenMetrics(result);
|
|
11071
|
-
if (startTime) {
|
|
11072
|
-
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
11278
|
+
const runtimeDenyOutputPaths = firstArgument[RUNTIME_DENY_OUTPUT_PATHS];
|
|
11279
|
+
if (Array.isArray(runtimeDenyOutputPaths) && runtimeDenyOutputPaths.every((path2) => typeof path2 === "string")) {
|
|
11280
|
+
return runtimeDenyOutputPaths;
|
|
11073
11281
|
}
|
|
11074
|
-
return
|
|
11075
|
-
}
|
|
11076
|
-
function hasModelChildTracing(event) {
|
|
11077
|
-
return event?.__braintrust_ai_sdk_model_wrapped === true;
|
|
11282
|
+
return defaultDenyOutputPaths;
|
|
11078
11283
|
}
|
|
11079
|
-
|
|
11080
|
-
|
|
11081
|
-
|
|
11082
|
-
|
|
11083
|
-
|
|
11084
|
-
|
|
11085
|
-
}
|
|
11086
|
-
|
|
11087
|
-
|
|
11088
|
-
|
|
11089
|
-
|
|
11090
|
-
if (model) {
|
|
11091
|
-
metadata.model = model;
|
|
11284
|
+
var isZodSchema2 = (value) => {
|
|
11285
|
+
return value != null && typeof value === "object" && "_def" in value && typeof value._def === "object";
|
|
11286
|
+
};
|
|
11287
|
+
var serializeZodSchema2 = (schema) => {
|
|
11288
|
+
try {
|
|
11289
|
+
return zodToJsonSchema(schema);
|
|
11290
|
+
} catch {
|
|
11291
|
+
return {
|
|
11292
|
+
type: "object",
|
|
11293
|
+
description: "Zod schema (conversion failed)"
|
|
11294
|
+
};
|
|
11092
11295
|
}
|
|
11093
|
-
|
|
11094
|
-
|
|
11296
|
+
};
|
|
11297
|
+
var isOutputObject = (value) => {
|
|
11298
|
+
if (value == null || typeof value !== "object") {
|
|
11299
|
+
return false;
|
|
11095
11300
|
}
|
|
11301
|
+
const output = value;
|
|
11302
|
+
if (!("responseFormat" in output)) {
|
|
11303
|
+
return false;
|
|
11304
|
+
}
|
|
11305
|
+
if (output.type === "object" || output.type === "text") {
|
|
11306
|
+
return true;
|
|
11307
|
+
}
|
|
11308
|
+
if (typeof output.responseFormat === "function" || typeof output.responseFormat === "object") {
|
|
11309
|
+
return true;
|
|
11310
|
+
}
|
|
11311
|
+
return false;
|
|
11312
|
+
};
|
|
11313
|
+
var serializeOutputObject = (output, model) => {
|
|
11314
|
+
try {
|
|
11315
|
+
const result = {
|
|
11316
|
+
response_format: null
|
|
11317
|
+
};
|
|
11318
|
+
if (output.type) {
|
|
11319
|
+
result.type = output.type;
|
|
11320
|
+
}
|
|
11321
|
+
let responseFormat;
|
|
11322
|
+
if (typeof output.responseFormat === "function") {
|
|
11323
|
+
const mockModelForSchema = {
|
|
11324
|
+
supportsStructuredOutputs: true,
|
|
11325
|
+
...model && typeof model === "object" ? model : {}
|
|
11326
|
+
};
|
|
11327
|
+
responseFormat = output.responseFormat({ model: mockModelForSchema });
|
|
11328
|
+
} else if (output.responseFormat != null && typeof output.responseFormat === "object") {
|
|
11329
|
+
responseFormat = output.responseFormat;
|
|
11330
|
+
}
|
|
11331
|
+
if (responseFormat) {
|
|
11332
|
+
if (typeof responseFormat.then === "function") {
|
|
11333
|
+
result.response_format = Promise.resolve(responseFormat).then(
|
|
11334
|
+
(resolved) => {
|
|
11335
|
+
if (resolved.schema && isZodSchema2(resolved.schema)) {
|
|
11336
|
+
return {
|
|
11337
|
+
...resolved,
|
|
11338
|
+
schema: serializeZodSchema2(resolved.schema)
|
|
11339
|
+
};
|
|
11340
|
+
}
|
|
11341
|
+
return resolved;
|
|
11342
|
+
}
|
|
11343
|
+
);
|
|
11344
|
+
} else {
|
|
11345
|
+
const syncResponseFormat = responseFormat;
|
|
11346
|
+
if (syncResponseFormat.schema && isZodSchema2(syncResponseFormat.schema)) {
|
|
11347
|
+
responseFormat = {
|
|
11348
|
+
...syncResponseFormat,
|
|
11349
|
+
schema: serializeZodSchema2(syncResponseFormat.schema)
|
|
11350
|
+
};
|
|
11351
|
+
}
|
|
11352
|
+
result.response_format = responseFormat;
|
|
11353
|
+
}
|
|
11354
|
+
}
|
|
11355
|
+
return result;
|
|
11356
|
+
} catch {
|
|
11357
|
+
return {
|
|
11358
|
+
response_format: null
|
|
11359
|
+
};
|
|
11360
|
+
}
|
|
11361
|
+
};
|
|
11362
|
+
var processInputAttachmentsSync = (input) => {
|
|
11363
|
+
if (!input) return { input };
|
|
11364
|
+
const processed = { ...input };
|
|
11365
|
+
if (input.messages && Array.isArray(input.messages)) {
|
|
11366
|
+
processed.messages = input.messages.map(processMessage);
|
|
11367
|
+
}
|
|
11368
|
+
if (input.prompt && typeof input.prompt === "object") {
|
|
11369
|
+
if (Array.isArray(input.prompt)) {
|
|
11370
|
+
processed.prompt = input.prompt.map(processMessage);
|
|
11371
|
+
} else {
|
|
11372
|
+
processed.prompt = processPromptContent(input.prompt);
|
|
11373
|
+
}
|
|
11374
|
+
}
|
|
11375
|
+
if (input.schema && isZodSchema2(input.schema)) {
|
|
11376
|
+
processed.schema = serializeZodSchema2(input.schema);
|
|
11377
|
+
}
|
|
11378
|
+
if (input.callOptionsSchema && isZodSchema2(input.callOptionsSchema)) {
|
|
11379
|
+
processed.callOptionsSchema = serializeZodSchema2(input.callOptionsSchema);
|
|
11380
|
+
}
|
|
11381
|
+
if (input.tools) {
|
|
11382
|
+
processed.tools = serializeAISDKToolsForLogging(input.tools);
|
|
11383
|
+
}
|
|
11384
|
+
let outputPromise;
|
|
11385
|
+
if (input.output && isOutputObject(input.output)) {
|
|
11386
|
+
const serialized = serializeOutputObject(input.output, input.model);
|
|
11387
|
+
if (serialized.response_format && typeof serialized.response_format.then === "function") {
|
|
11388
|
+
processed.output = { ...serialized, response_format: {} };
|
|
11389
|
+
outputPromise = serialized.response_format.then(
|
|
11390
|
+
(resolvedFormat) => ({
|
|
11391
|
+
output: { ...serialized, response_format: resolvedFormat }
|
|
11392
|
+
})
|
|
11393
|
+
);
|
|
11394
|
+
} else {
|
|
11395
|
+
processed.output = serialized;
|
|
11396
|
+
}
|
|
11397
|
+
}
|
|
11398
|
+
if ("prepareCall" in processed && typeof processed.prepareCall === "function") {
|
|
11399
|
+
processed.prepareCall = "[Function]";
|
|
11400
|
+
}
|
|
11401
|
+
return { input: processed, outputPromise };
|
|
11402
|
+
};
|
|
11403
|
+
var processMessage = (message) => {
|
|
11404
|
+
if (!message || typeof message !== "object") return message;
|
|
11405
|
+
if (Array.isArray(message.content)) {
|
|
11406
|
+
return {
|
|
11407
|
+
...message,
|
|
11408
|
+
content: message.content.map(processContentPart)
|
|
11409
|
+
};
|
|
11410
|
+
}
|
|
11411
|
+
if (typeof message.content === "object" && message.content !== null) {
|
|
11412
|
+
return {
|
|
11413
|
+
...message,
|
|
11414
|
+
content: processContentPart(message.content)
|
|
11415
|
+
};
|
|
11416
|
+
}
|
|
11417
|
+
return message;
|
|
11418
|
+
};
|
|
11419
|
+
var processPromptContent = (prompt) => {
|
|
11420
|
+
if (Array.isArray(prompt)) {
|
|
11421
|
+
return prompt.map(processContentPart);
|
|
11422
|
+
}
|
|
11423
|
+
if (prompt.content) {
|
|
11424
|
+
if (Array.isArray(prompt.content)) {
|
|
11425
|
+
return {
|
|
11426
|
+
...prompt,
|
|
11427
|
+
content: prompt.content.map(processContentPart)
|
|
11428
|
+
};
|
|
11429
|
+
} else if (typeof prompt.content === "object") {
|
|
11430
|
+
return {
|
|
11431
|
+
...prompt,
|
|
11432
|
+
content: processContentPart(prompt.content)
|
|
11433
|
+
};
|
|
11434
|
+
}
|
|
11435
|
+
}
|
|
11436
|
+
return prompt;
|
|
11437
|
+
};
|
|
11438
|
+
var processContentPart = (part) => {
|
|
11439
|
+
if (!part || typeof part !== "object") return part;
|
|
11440
|
+
try {
|
|
11441
|
+
if (part.type === "image" && part.image) {
|
|
11442
|
+
const imageAttachment = convertImageToAttachment(
|
|
11443
|
+
part.image,
|
|
11444
|
+
part.mimeType || part.mediaType
|
|
11445
|
+
);
|
|
11446
|
+
if (imageAttachment) {
|
|
11447
|
+
return {
|
|
11448
|
+
...part,
|
|
11449
|
+
image: imageAttachment
|
|
11450
|
+
};
|
|
11451
|
+
}
|
|
11452
|
+
}
|
|
11453
|
+
if (part.type === "file" && part.data && (part.mimeType || part.mediaType)) {
|
|
11454
|
+
const fileAttachment = convertDataToAttachment(
|
|
11455
|
+
part.data,
|
|
11456
|
+
part.mimeType || part.mediaType,
|
|
11457
|
+
part.name || part.filename
|
|
11458
|
+
);
|
|
11459
|
+
if (fileAttachment) {
|
|
11460
|
+
return {
|
|
11461
|
+
...part,
|
|
11462
|
+
data: fileAttachment
|
|
11463
|
+
};
|
|
11464
|
+
}
|
|
11465
|
+
}
|
|
11466
|
+
if (part.type === "image_url" && part.image_url) {
|
|
11467
|
+
if (typeof part.image_url === "object" && part.image_url.url) {
|
|
11468
|
+
const imageAttachment = convertImageToAttachment(part.image_url.url);
|
|
11469
|
+
if (imageAttachment) {
|
|
11470
|
+
return {
|
|
11471
|
+
...part,
|
|
11472
|
+
image_url: {
|
|
11473
|
+
...part.image_url,
|
|
11474
|
+
url: imageAttachment
|
|
11475
|
+
}
|
|
11476
|
+
};
|
|
11477
|
+
}
|
|
11478
|
+
}
|
|
11479
|
+
}
|
|
11480
|
+
} catch (error) {
|
|
11481
|
+
console.warn("Error processing content part:", error);
|
|
11482
|
+
}
|
|
11483
|
+
return part;
|
|
11484
|
+
};
|
|
11485
|
+
var convertImageToAttachment = (image, explicitMimeType) => {
|
|
11486
|
+
try {
|
|
11487
|
+
if (typeof image === "string" && image.startsWith("data:")) {
|
|
11488
|
+
const [mimeTypeSection, base64Data] = image.split(",");
|
|
11489
|
+
const mimeType = mimeTypeSection.match(/data:(.*?);/)?.[1];
|
|
11490
|
+
if (mimeType && base64Data) {
|
|
11491
|
+
const blob = convertDataToBlob(base64Data, mimeType);
|
|
11492
|
+
if (blob) {
|
|
11493
|
+
return new Attachment({
|
|
11494
|
+
data: blob,
|
|
11495
|
+
filename: `image.${getExtensionFromMediaType(mimeType)}`,
|
|
11496
|
+
contentType: mimeType
|
|
11497
|
+
});
|
|
11498
|
+
}
|
|
11499
|
+
}
|
|
11500
|
+
}
|
|
11501
|
+
if (explicitMimeType) {
|
|
11502
|
+
if (image instanceof Uint8Array) {
|
|
11503
|
+
return new Attachment({
|
|
11504
|
+
data: new Blob([image], { type: explicitMimeType }),
|
|
11505
|
+
filename: `image.${getExtensionFromMediaType(explicitMimeType)}`,
|
|
11506
|
+
contentType: explicitMimeType
|
|
11507
|
+
});
|
|
11508
|
+
}
|
|
11509
|
+
if (typeof Buffer !== "undefined" && Buffer.isBuffer(image)) {
|
|
11510
|
+
return new Attachment({
|
|
11511
|
+
data: new Blob([image], { type: explicitMimeType }),
|
|
11512
|
+
filename: `image.${getExtensionFromMediaType(explicitMimeType)}`,
|
|
11513
|
+
contentType: explicitMimeType
|
|
11514
|
+
});
|
|
11515
|
+
}
|
|
11516
|
+
}
|
|
11517
|
+
if (image instanceof Blob && image.type) {
|
|
11518
|
+
return new Attachment({
|
|
11519
|
+
data: image,
|
|
11520
|
+
filename: `image.${getExtensionFromMediaType(image.type)}`,
|
|
11521
|
+
contentType: image.type
|
|
11522
|
+
});
|
|
11523
|
+
}
|
|
11524
|
+
if (image instanceof Attachment) {
|
|
11525
|
+
return image;
|
|
11526
|
+
}
|
|
11527
|
+
} catch (error) {
|
|
11528
|
+
console.warn("Error converting image to attachment:", error);
|
|
11529
|
+
}
|
|
11530
|
+
return null;
|
|
11531
|
+
};
|
|
11532
|
+
var convertDataToAttachment = (data, mimeType, filename) => {
|
|
11533
|
+
if (!mimeType) return null;
|
|
11534
|
+
try {
|
|
11535
|
+
let blob = null;
|
|
11536
|
+
if (typeof data === "string" && data.startsWith("data:")) {
|
|
11537
|
+
const [, base64Data] = data.split(",");
|
|
11538
|
+
if (base64Data) {
|
|
11539
|
+
blob = convertDataToBlob(base64Data, mimeType);
|
|
11540
|
+
}
|
|
11541
|
+
} else if (typeof data === "string" && data.length > 0) {
|
|
11542
|
+
blob = convertDataToBlob(data, mimeType);
|
|
11543
|
+
} else if (data instanceof Uint8Array) {
|
|
11544
|
+
blob = new Blob([data], { type: mimeType });
|
|
11545
|
+
} else if (typeof Buffer !== "undefined" && Buffer.isBuffer(data)) {
|
|
11546
|
+
blob = new Blob([data], { type: mimeType });
|
|
11547
|
+
} else if (data instanceof Blob) {
|
|
11548
|
+
blob = data;
|
|
11549
|
+
}
|
|
11550
|
+
if (blob) {
|
|
11551
|
+
return new Attachment({
|
|
11552
|
+
data: blob,
|
|
11553
|
+
filename: filename || `file.${getExtensionFromMediaType(mimeType)}`,
|
|
11554
|
+
contentType: mimeType
|
|
11555
|
+
});
|
|
11556
|
+
}
|
|
11557
|
+
} catch (error) {
|
|
11558
|
+
console.warn("Error converting data to attachment:", error);
|
|
11559
|
+
}
|
|
11560
|
+
return null;
|
|
11561
|
+
};
|
|
11562
|
+
function processAISDKCallInput(params) {
|
|
11563
|
+
return processInputAttachmentsSync(params);
|
|
11564
|
+
}
|
|
11565
|
+
function prepareAISDKCallInput(params, event, span, defaultDenyOutputPaths) {
|
|
11566
|
+
const { input, outputPromise } = processAISDKCallInput(params);
|
|
11567
|
+
if (outputPromise && input && typeof input === "object") {
|
|
11568
|
+
outputPromise.then((resolvedData) => {
|
|
11569
|
+
span.log({
|
|
11570
|
+
input: {
|
|
11571
|
+
...input,
|
|
11572
|
+
...resolvedData
|
|
11573
|
+
}
|
|
11574
|
+
});
|
|
11575
|
+
}).catch(() => {
|
|
11576
|
+
});
|
|
11577
|
+
}
|
|
11578
|
+
const metadata = extractMetadataFromCallParams(params, event.self);
|
|
11579
|
+
const childTracing = prepareAISDKChildTracing(
|
|
11580
|
+
params,
|
|
11581
|
+
event.self,
|
|
11582
|
+
span,
|
|
11583
|
+
defaultDenyOutputPaths,
|
|
11584
|
+
event.aiSDK
|
|
11585
|
+
);
|
|
11586
|
+
event.modelWrapped = childTracing.modelWrapped;
|
|
11587
|
+
if (childTracing.cleanup) {
|
|
11588
|
+
event.__braintrust_ai_sdk_cleanup = childTracing.cleanup;
|
|
11589
|
+
}
|
|
11590
|
+
return {
|
|
11591
|
+
input,
|
|
11592
|
+
metadata
|
|
11593
|
+
};
|
|
11594
|
+
}
|
|
11595
|
+
function prepareAISDKEmbedInput(params, self) {
|
|
11596
|
+
return {
|
|
11597
|
+
input: { ...params },
|
|
11598
|
+
metadata: extractMetadataFromEmbedParams(params, self)
|
|
11599
|
+
};
|
|
11600
|
+
}
|
|
11601
|
+
function extractTopLevelAISDKMetrics(result, event, startTime) {
|
|
11602
|
+
const metrics = hasModelChildTracing(event) ? {} : extractTokenMetrics(result);
|
|
11603
|
+
if (startTime) {
|
|
11604
|
+
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
11605
|
+
}
|
|
11606
|
+
return metrics;
|
|
11607
|
+
}
|
|
11608
|
+
function hasModelChildTracing(event) {
|
|
11609
|
+
return event?.modelWrapped === true || event?.__braintrust_ai_sdk_model_wrapped === true;
|
|
11610
|
+
}
|
|
11611
|
+
function createAISDKIntegrationMetadata() {
|
|
11612
|
+
return {
|
|
11613
|
+
braintrust: {
|
|
11614
|
+
integration_name: "ai-sdk",
|
|
11615
|
+
sdk_language: "typescript"
|
|
11616
|
+
}
|
|
11617
|
+
};
|
|
11618
|
+
}
|
|
11619
|
+
function resolveModelFromSelf(self) {
|
|
11620
|
+
return self && typeof self === "object" && "model" in self && self.model ? self.model : self && typeof self === "object" && "settings" in self && self.settings?.model ? self.settings?.model : void 0;
|
|
11621
|
+
}
|
|
11622
|
+
function extractBaseMetadata(model, self) {
|
|
11623
|
+
const metadata = createAISDKIntegrationMetadata();
|
|
11624
|
+
const { model: modelId, provider } = serializeModelWithProvider(
|
|
11625
|
+
model ?? resolveModelFromSelf(self)
|
|
11626
|
+
);
|
|
11627
|
+
if (modelId) {
|
|
11628
|
+
metadata.model = modelId;
|
|
11629
|
+
}
|
|
11630
|
+
if (provider) {
|
|
11631
|
+
metadata.provider = provider;
|
|
11632
|
+
}
|
|
11633
|
+
return metadata;
|
|
11634
|
+
}
|
|
11635
|
+
function extractMetadataFromCallParams(params, self) {
|
|
11636
|
+
const metadata = extractBaseMetadata(params.model, self);
|
|
11096
11637
|
const tools = serializeAISDKToolsForLogging(params.tools);
|
|
11097
11638
|
if (tools) {
|
|
11098
11639
|
metadata.tools = tools;
|
|
11099
11640
|
}
|
|
11100
11641
|
return metadata;
|
|
11101
11642
|
}
|
|
11102
|
-
function
|
|
11643
|
+
function extractMetadataFromEmbedParams(params, self) {
|
|
11644
|
+
return extractBaseMetadata(params.model, self);
|
|
11645
|
+
}
|
|
11646
|
+
function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiSDK) {
|
|
11103
11647
|
const cleanup = [];
|
|
11104
11648
|
const patchedModels = /* @__PURE__ */ new WeakSet();
|
|
11105
11649
|
const patchedTools = /* @__PURE__ */ new WeakSet();
|
|
11106
11650
|
let modelWrapped = false;
|
|
11107
11651
|
const patchModel = (model) => {
|
|
11108
|
-
const resolvedModel = resolveAISDKModel(model);
|
|
11652
|
+
const resolvedModel = resolveAISDKModel(model, aiSDK);
|
|
11109
11653
|
if (!resolvedModel || typeof resolvedModel !== "object" || typeof resolvedModel.doGenerate !== "function" || patchedModels.has(resolvedModel) || resolvedModel[AUTO_PATCHED_MODEL]) {
|
|
11110
|
-
return;
|
|
11654
|
+
return resolvedModel;
|
|
11111
11655
|
}
|
|
11112
11656
|
patchedModels.add(resolvedModel);
|
|
11113
11657
|
resolvedModel[AUTO_PATCHED_MODEL] = true;
|
|
@@ -11136,7 +11680,7 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths) {
|
|
|
11136
11680
|
type: "llm" /* LLM */
|
|
11137
11681
|
},
|
|
11138
11682
|
event: {
|
|
11139
|
-
input:
|
|
11683
|
+
input: processAISDKCallInput(options).input,
|
|
11140
11684
|
metadata: baseMetadata
|
|
11141
11685
|
}
|
|
11142
11686
|
}
|
|
@@ -11150,7 +11694,7 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths) {
|
|
|
11150
11694
|
type: "llm" /* LLM */
|
|
11151
11695
|
},
|
|
11152
11696
|
event: {
|
|
11153
|
-
input:
|
|
11697
|
+
input: processAISDKCallInput(options).input,
|
|
11154
11698
|
metadata: baseMetadata
|
|
11155
11699
|
}
|
|
11156
11700
|
});
|
|
@@ -11158,6 +11702,8 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths) {
|
|
|
11158
11702
|
span,
|
|
11159
11703
|
() => Reflect.apply(originalDoStream, resolvedModel, [options])
|
|
11160
11704
|
);
|
|
11705
|
+
const streamStartTime = getCurrentUnixTimestamp();
|
|
11706
|
+
let firstChunkTime;
|
|
11161
11707
|
const output = {};
|
|
11162
11708
|
let text = "";
|
|
11163
11709
|
let reasoning = "";
|
|
@@ -11165,6 +11711,9 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths) {
|
|
|
11165
11711
|
let object = void 0;
|
|
11166
11712
|
const transformStream = new TransformStream({
|
|
11167
11713
|
transform(chunk, controller) {
|
|
11714
|
+
if (firstChunkTime === void 0) {
|
|
11715
|
+
firstChunkTime = getCurrentUnixTimestamp();
|
|
11716
|
+
}
|
|
11168
11717
|
switch (chunk.type) {
|
|
11169
11718
|
case "text-delta":
|
|
11170
11719
|
text += extractTextDelta(chunk);
|
|
@@ -11205,12 +11754,19 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths) {
|
|
|
11205
11754
|
if (object !== void 0) {
|
|
11206
11755
|
output.object = object;
|
|
11207
11756
|
}
|
|
11757
|
+
const metrics = extractTokenMetrics(output);
|
|
11758
|
+
if (firstChunkTime !== void 0) {
|
|
11759
|
+
metrics.time_to_first_token = Math.max(
|
|
11760
|
+
firstChunkTime - streamStartTime,
|
|
11761
|
+
1e-6
|
|
11762
|
+
);
|
|
11763
|
+
}
|
|
11208
11764
|
span.log({
|
|
11209
11765
|
output: processAISDKOutput(
|
|
11210
11766
|
output,
|
|
11211
11767
|
denyOutputPaths
|
|
11212
11768
|
),
|
|
11213
|
-
metrics
|
|
11769
|
+
metrics,
|
|
11214
11770
|
...buildResolvedMetadataPayload(output)
|
|
11215
11771
|
});
|
|
11216
11772
|
span.end();
|
|
@@ -11232,6 +11788,7 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths) {
|
|
|
11232
11788
|
}
|
|
11233
11789
|
delete resolvedModel[AUTO_PATCHED_MODEL];
|
|
11234
11790
|
});
|
|
11791
|
+
return resolvedModel;
|
|
11235
11792
|
};
|
|
11236
11793
|
const patchTool = (tool, name) => {
|
|
11237
11794
|
if (tool == null || typeof tool !== "object" || !("execute" in tool) || typeof tool.execute !== "function" || patchedTools.has(tool) || tool[AUTO_PATCHED_TOOL]) {
|
|
@@ -11304,17 +11861,26 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths) {
|
|
|
11304
11861
|
}
|
|
11305
11862
|
};
|
|
11306
11863
|
if (params && typeof params === "object") {
|
|
11307
|
-
patchModel(params.model);
|
|
11864
|
+
const patchedParamModel = patchModel(params.model);
|
|
11865
|
+
if (typeof params.model === "string" && patchedParamModel && typeof patchedParamModel === "object") {
|
|
11866
|
+
params.model = patchedParamModel;
|
|
11867
|
+
}
|
|
11308
11868
|
patchTools(params.tools);
|
|
11309
11869
|
}
|
|
11310
11870
|
if (self && typeof self === "object") {
|
|
11311
11871
|
const selfRecord = self;
|
|
11312
11872
|
if (selfRecord.model !== void 0) {
|
|
11313
|
-
patchModel(selfRecord.model);
|
|
11873
|
+
const patchedSelfModel = patchModel(selfRecord.model);
|
|
11874
|
+
if (typeof selfRecord.model === "string" && patchedSelfModel && typeof patchedSelfModel === "object") {
|
|
11875
|
+
selfRecord.model = patchedSelfModel;
|
|
11876
|
+
}
|
|
11314
11877
|
}
|
|
11315
11878
|
if (selfRecord.settings && typeof selfRecord.settings === "object") {
|
|
11316
11879
|
if (selfRecord.settings.model !== void 0) {
|
|
11317
|
-
patchModel(selfRecord.settings.model);
|
|
11880
|
+
const patchedSettingsModel = patchModel(selfRecord.settings.model);
|
|
11881
|
+
if (typeof selfRecord.settings.model === "string" && patchedSettingsModel && typeof patchedSettingsModel === "object") {
|
|
11882
|
+
selfRecord.settings.model = patchedSettingsModel;
|
|
11883
|
+
}
|
|
11318
11884
|
}
|
|
11319
11885
|
if (selfRecord.settings.tools !== void 0) {
|
|
11320
11886
|
patchTools(selfRecord.settings.tools);
|
|
@@ -11338,63 +11904,178 @@ function finalizeAISDKChildTracing(event) {
|
|
|
11338
11904
|
}
|
|
11339
11905
|
}
|
|
11340
11906
|
function patchAISDKStreamingResult(args) {
|
|
11341
|
-
const {
|
|
11907
|
+
const { defaultDenyOutputPaths, endEvent, result, span, startTime } = args;
|
|
11342
11908
|
if (!result || typeof result !== "object") {
|
|
11343
11909
|
return false;
|
|
11344
11910
|
}
|
|
11345
11911
|
const resultRecord = result;
|
|
11346
|
-
|
|
11912
|
+
attachKnownResultPromiseHandlers(resultRecord);
|
|
11913
|
+
if (isReadableStreamLike(resultRecord.baseStream)) {
|
|
11914
|
+
let firstChunkTime2;
|
|
11915
|
+
const wrappedBaseStream = resultRecord.baseStream.pipeThrough(
|
|
11916
|
+
new TransformStream({
|
|
11917
|
+
transform(chunk, controller) {
|
|
11918
|
+
if (firstChunkTime2 === void 0) {
|
|
11919
|
+
firstChunkTime2 = getCurrentUnixTimestamp();
|
|
11920
|
+
}
|
|
11921
|
+
controller.enqueue(chunk);
|
|
11922
|
+
},
|
|
11923
|
+
async flush() {
|
|
11924
|
+
const metrics = extractTopLevelAISDKMetrics(result, endEvent);
|
|
11925
|
+
if (metrics.time_to_first_token === void 0 && firstChunkTime2 !== void 0) {
|
|
11926
|
+
metrics.time_to_first_token = firstChunkTime2 - startTime;
|
|
11927
|
+
}
|
|
11928
|
+
const output = await processAISDKStreamingOutput(
|
|
11929
|
+
result,
|
|
11930
|
+
resolveDenyOutputPaths(endEvent, defaultDenyOutputPaths)
|
|
11931
|
+
);
|
|
11932
|
+
const metadata = buildResolvedMetadataPayload(result).metadata;
|
|
11933
|
+
span.log({
|
|
11934
|
+
output,
|
|
11935
|
+
...metadata ? { metadata } : {},
|
|
11936
|
+
metrics
|
|
11937
|
+
});
|
|
11938
|
+
finalizeAISDKChildTracing(endEvent);
|
|
11939
|
+
span.end();
|
|
11940
|
+
}
|
|
11941
|
+
})
|
|
11942
|
+
);
|
|
11943
|
+
Object.defineProperty(resultRecord, "baseStream", {
|
|
11944
|
+
configurable: true,
|
|
11945
|
+
enumerable: true,
|
|
11946
|
+
value: wrappedBaseStream,
|
|
11947
|
+
writable: true
|
|
11948
|
+
});
|
|
11949
|
+
return true;
|
|
11950
|
+
}
|
|
11951
|
+
const streamField = findAsyncIterableField(resultRecord, [
|
|
11952
|
+
"partialObjectStream",
|
|
11953
|
+
"textStream",
|
|
11954
|
+
"fullStream",
|
|
11955
|
+
"stream"
|
|
11956
|
+
]);
|
|
11957
|
+
if (!streamField) {
|
|
11347
11958
|
return false;
|
|
11348
11959
|
}
|
|
11349
11960
|
let firstChunkTime;
|
|
11350
|
-
const
|
|
11351
|
-
|
|
11352
|
-
|
|
11353
|
-
|
|
11354
|
-
firstChunkTime = getCurrentUnixTimestamp();
|
|
11355
|
-
}
|
|
11356
|
-
controller.enqueue(chunk);
|
|
11357
|
-
},
|
|
11358
|
-
async flush() {
|
|
11359
|
-
const metrics = extractTopLevelAISDKMetrics(result, endEvent);
|
|
11360
|
-
if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
|
|
11361
|
-
metrics.time_to_first_token = firstChunkTime - startTime;
|
|
11362
|
-
}
|
|
11363
|
-
const output = await processAISDKStreamingOutput(
|
|
11364
|
-
result,
|
|
11365
|
-
denyOutputPaths
|
|
11366
|
-
);
|
|
11367
|
-
const metadata = buildResolvedMetadataPayload(result).metadata;
|
|
11368
|
-
span.log({
|
|
11369
|
-
output,
|
|
11370
|
-
...metadata ? { metadata } : {},
|
|
11371
|
-
metrics
|
|
11372
|
-
});
|
|
11373
|
-
finalizeAISDKChildTracing(endEvent);
|
|
11374
|
-
span.end();
|
|
11961
|
+
const wrappedStream = createPatchedAsyncIterable(streamField.stream, {
|
|
11962
|
+
onChunk: () => {
|
|
11963
|
+
if (firstChunkTime === void 0) {
|
|
11964
|
+
firstChunkTime = getCurrentUnixTimestamp();
|
|
11375
11965
|
}
|
|
11376
|
-
}
|
|
11377
|
-
|
|
11378
|
-
|
|
11966
|
+
},
|
|
11967
|
+
onComplete: async () => {
|
|
11968
|
+
const metrics = extractTopLevelAISDKMetrics(result, endEvent);
|
|
11969
|
+
if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
|
|
11970
|
+
metrics.time_to_first_token = firstChunkTime - startTime;
|
|
11971
|
+
}
|
|
11972
|
+
const output = await processAISDKStreamingOutput(
|
|
11973
|
+
result,
|
|
11974
|
+
resolveDenyOutputPaths(endEvent, defaultDenyOutputPaths)
|
|
11975
|
+
);
|
|
11976
|
+
const metadata = buildResolvedMetadataPayload(result).metadata;
|
|
11977
|
+
span.log({
|
|
11978
|
+
output,
|
|
11979
|
+
...metadata ? { metadata } : {},
|
|
11980
|
+
metrics
|
|
11981
|
+
});
|
|
11982
|
+
finalizeAISDKChildTracing(endEvent);
|
|
11983
|
+
span.end();
|
|
11984
|
+
},
|
|
11985
|
+
onError: (error) => {
|
|
11986
|
+
span.log({
|
|
11987
|
+
error: error.message
|
|
11988
|
+
});
|
|
11989
|
+
finalizeAISDKChildTracing(endEvent);
|
|
11990
|
+
span.end();
|
|
11991
|
+
}
|
|
11992
|
+
});
|
|
11993
|
+
Object.defineProperty(resultRecord, streamField.field, {
|
|
11379
11994
|
configurable: true,
|
|
11380
11995
|
enumerable: true,
|
|
11381
|
-
value:
|
|
11996
|
+
value: wrappedStream,
|
|
11382
11997
|
writable: true
|
|
11383
11998
|
});
|
|
11384
11999
|
return true;
|
|
11385
12000
|
}
|
|
12001
|
+
function attachKnownResultPromiseHandlers(result) {
|
|
12002
|
+
const promiseLikeFields = [
|
|
12003
|
+
"content",
|
|
12004
|
+
"text",
|
|
12005
|
+
"object",
|
|
12006
|
+
"value",
|
|
12007
|
+
"values",
|
|
12008
|
+
"finishReason",
|
|
12009
|
+
"embedding",
|
|
12010
|
+
"embeddings",
|
|
12011
|
+
"usage",
|
|
12012
|
+
"totalUsage",
|
|
12013
|
+
"responses",
|
|
12014
|
+
"steps"
|
|
12015
|
+
];
|
|
12016
|
+
for (const field of promiseLikeFields) {
|
|
12017
|
+
try {
|
|
12018
|
+
if (!(field in result)) {
|
|
12019
|
+
continue;
|
|
12020
|
+
}
|
|
12021
|
+
const value = result[field];
|
|
12022
|
+
if (isPromiseLike(value)) {
|
|
12023
|
+
void Promise.resolve(value).catch(() => {
|
|
12024
|
+
});
|
|
12025
|
+
}
|
|
12026
|
+
} catch {
|
|
12027
|
+
}
|
|
12028
|
+
}
|
|
12029
|
+
}
|
|
11386
12030
|
function isReadableStreamLike(value) {
|
|
11387
12031
|
return value != null && typeof value === "object" && typeof value.pipeThrough === "function";
|
|
11388
12032
|
}
|
|
12033
|
+
function isAsyncIterableLike(value) {
|
|
12034
|
+
return value != null && typeof value === "object" && typeof value[Symbol.asyncIterator] === "function";
|
|
12035
|
+
}
|
|
12036
|
+
function findAsyncIterableField(result, candidateFields) {
|
|
12037
|
+
for (const field of candidateFields) {
|
|
12038
|
+
try {
|
|
12039
|
+
const stream = result[field];
|
|
12040
|
+
if (isAsyncIterableLike(stream)) {
|
|
12041
|
+
return { field, stream };
|
|
12042
|
+
}
|
|
12043
|
+
} catch {
|
|
12044
|
+
}
|
|
12045
|
+
}
|
|
12046
|
+
return null;
|
|
12047
|
+
}
|
|
12048
|
+
function createPatchedAsyncIterable(stream, hooks) {
|
|
12049
|
+
return {
|
|
12050
|
+
async *[Symbol.asyncIterator]() {
|
|
12051
|
+
try {
|
|
12052
|
+
for await (const chunk of stream) {
|
|
12053
|
+
hooks.onChunk(chunk);
|
|
12054
|
+
yield chunk;
|
|
12055
|
+
}
|
|
12056
|
+
await hooks.onComplete();
|
|
12057
|
+
} catch (error) {
|
|
12058
|
+
hooks.onError(
|
|
12059
|
+
error instanceof Error ? error : new Error(String(error))
|
|
12060
|
+
);
|
|
12061
|
+
throw error;
|
|
12062
|
+
}
|
|
12063
|
+
}
|
|
12064
|
+
};
|
|
12065
|
+
}
|
|
11389
12066
|
async function processAISDKStreamingOutput(result, denyOutputPaths) {
|
|
11390
12067
|
const output = processAISDKOutput(result, denyOutputPaths);
|
|
11391
12068
|
if (!output || typeof output !== "object") {
|
|
11392
12069
|
return output;
|
|
11393
12070
|
}
|
|
11394
12071
|
const outputRecord = output;
|
|
12072
|
+
const isObjectStreamingResult = result != null && typeof result === "object" && "partialObjectStream" in result;
|
|
11395
12073
|
try {
|
|
11396
|
-
if ("text" in result
|
|
11397
|
-
|
|
12074
|
+
if (!isObjectStreamingResult && "text" in result) {
|
|
12075
|
+
const resolvedText = await Promise.resolve(result.text);
|
|
12076
|
+
if (typeof resolvedText === "string") {
|
|
12077
|
+
outputRecord.text = resolvedText;
|
|
12078
|
+
}
|
|
11398
12079
|
}
|
|
11399
12080
|
} catch {
|
|
11400
12081
|
}
|
|
@@ -11407,6 +12088,15 @@ async function processAISDKStreamingOutput(result, denyOutputPaths) {
|
|
|
11407
12088
|
}
|
|
11408
12089
|
} catch {
|
|
11409
12090
|
}
|
|
12091
|
+
try {
|
|
12092
|
+
if ("finishReason" in result) {
|
|
12093
|
+
const resolvedFinishReason = await Promise.resolve(result.finishReason);
|
|
12094
|
+
if (resolvedFinishReason !== void 0) {
|
|
12095
|
+
outputRecord.finishReason = resolvedFinishReason;
|
|
12096
|
+
}
|
|
12097
|
+
}
|
|
12098
|
+
} catch {
|
|
12099
|
+
}
|
|
11410
12100
|
return outputRecord;
|
|
11411
12101
|
}
|
|
11412
12102
|
function buildAISDKChildMetadata(model) {
|
|
@@ -11429,16 +12119,25 @@ function buildResolvedMetadataPayload(result) {
|
|
|
11429
12119
|
if (gatewayInfo?.model) {
|
|
11430
12120
|
metadata.model = gatewayInfo.model;
|
|
11431
12121
|
}
|
|
11432
|
-
|
|
11433
|
-
|
|
12122
|
+
let finishReason;
|
|
12123
|
+
try {
|
|
12124
|
+
finishReason = result.finishReason;
|
|
12125
|
+
} catch {
|
|
12126
|
+
finishReason = void 0;
|
|
12127
|
+
}
|
|
12128
|
+
if (isPromiseLike(finishReason)) {
|
|
12129
|
+
void Promise.resolve(finishReason).catch(() => {
|
|
12130
|
+
});
|
|
12131
|
+
} else if (finishReason !== void 0) {
|
|
12132
|
+
metadata.finish_reason = finishReason;
|
|
11434
12133
|
}
|
|
11435
12134
|
return Object.keys(metadata).length > 0 ? { metadata } : {};
|
|
11436
12135
|
}
|
|
11437
|
-
function resolveAISDKModel(model) {
|
|
12136
|
+
function resolveAISDKModel(model, aiSDK) {
|
|
11438
12137
|
if (typeof model !== "string") {
|
|
11439
12138
|
return model;
|
|
11440
12139
|
}
|
|
11441
|
-
const provider = globalThis.AI_SDK_DEFAULT_PROVIDER ?? null;
|
|
12140
|
+
const provider = globalThis.AI_SDK_DEFAULT_PROVIDER ?? aiSDK?.gateway ?? null;
|
|
11442
12141
|
if (provider && typeof provider.languageModel === "function") {
|
|
11443
12142
|
return provider.languageModel(model);
|
|
11444
12143
|
}
|
|
@@ -11459,23 +12158,55 @@ function processAISDKOutput(output, denyOutputPaths) {
|
|
|
11459
12158
|
const merged = extractSerializableOutputFields(output);
|
|
11460
12159
|
return normalizeAISDKLoggedOutput(omit(merged, denyOutputPaths));
|
|
11461
12160
|
}
|
|
11462
|
-
function
|
|
11463
|
-
|
|
11464
|
-
|
|
11465
|
-
if (!usage && result) {
|
|
11466
|
-
try {
|
|
11467
|
-
if ("totalUsage" in result && typeof result.totalUsage !== "function") {
|
|
11468
|
-
usage = result.totalUsage;
|
|
11469
|
-
} else if ("usage" in result && typeof result.usage !== "function") {
|
|
11470
|
-
usage = result.usage;
|
|
11471
|
-
}
|
|
11472
|
-
} catch {
|
|
11473
|
-
}
|
|
11474
|
-
}
|
|
11475
|
-
if (!usage) {
|
|
11476
|
-
return metrics;
|
|
12161
|
+
function processAISDKEmbeddingOutput(output, denyOutputPaths) {
|
|
12162
|
+
if (!output || typeof output !== "object") {
|
|
12163
|
+
return output;
|
|
11477
12164
|
}
|
|
11478
|
-
const
|
|
12165
|
+
const summarized = {};
|
|
12166
|
+
const whitelistedFields = [
|
|
12167
|
+
"usage",
|
|
12168
|
+
"totalUsage",
|
|
12169
|
+
"warnings",
|
|
12170
|
+
"providerMetadata",
|
|
12171
|
+
"experimental_providerMetadata"
|
|
12172
|
+
];
|
|
12173
|
+
for (const field of whitelistedFields) {
|
|
12174
|
+
const value = safeSerializableFieldRead(output, field);
|
|
12175
|
+
if (value !== void 0 && isSerializableOutputValue(value)) {
|
|
12176
|
+
summarized[field] = value;
|
|
12177
|
+
}
|
|
12178
|
+
}
|
|
12179
|
+
const embedding = safeSerializableFieldRead(output, "embedding");
|
|
12180
|
+
if (Array.isArray(embedding)) {
|
|
12181
|
+
summarized.embedding_length = embedding.length;
|
|
12182
|
+
}
|
|
12183
|
+
const embeddings = safeSerializableFieldRead(output, "embeddings");
|
|
12184
|
+
if (Array.isArray(embeddings)) {
|
|
12185
|
+
summarized.embedding_count = embeddings.length;
|
|
12186
|
+
const firstEmbedding = embeddings.find((item) => Array.isArray(item));
|
|
12187
|
+
if (Array.isArray(firstEmbedding)) {
|
|
12188
|
+
summarized.embedding_length = firstEmbedding.length;
|
|
12189
|
+
}
|
|
12190
|
+
}
|
|
12191
|
+
return normalizeAISDKLoggedOutput(omit(summarized, denyOutputPaths));
|
|
12192
|
+
}
|
|
12193
|
+
function extractTokenMetrics(result) {
|
|
12194
|
+
const metrics = {};
|
|
12195
|
+
let usage;
|
|
12196
|
+
const totalUsageValue = safeResultFieldRead(result, "totalUsage");
|
|
12197
|
+
if (totalUsageValue !== void 0 && !isPromiseLike(totalUsageValue)) {
|
|
12198
|
+
usage = totalUsageValue;
|
|
12199
|
+
}
|
|
12200
|
+
if (!usage) {
|
|
12201
|
+
const usageValue = safeResultFieldRead(result, "usage");
|
|
12202
|
+
if (usageValue !== void 0 && !isPromiseLike(usageValue)) {
|
|
12203
|
+
usage = usageValue;
|
|
12204
|
+
}
|
|
12205
|
+
}
|
|
12206
|
+
if (!usage) {
|
|
12207
|
+
return metrics;
|
|
12208
|
+
}
|
|
12209
|
+
const promptTokens = firstNumber(
|
|
11479
12210
|
usage.inputTokens?.total,
|
|
11480
12211
|
usage.inputTokens,
|
|
11481
12212
|
usage.promptTokens,
|
|
@@ -11507,6 +12238,22 @@ function extractTokenMetrics(result) {
|
|
|
11507
12238
|
}
|
|
11508
12239
|
return metrics;
|
|
11509
12240
|
}
|
|
12241
|
+
function safeResultFieldRead(result, field) {
|
|
12242
|
+
return safeSerializableFieldRead(result, field);
|
|
12243
|
+
}
|
|
12244
|
+
function safeSerializableFieldRead(obj, field) {
|
|
12245
|
+
try {
|
|
12246
|
+
const value = obj?.[field];
|
|
12247
|
+
if (isPromiseLike(value)) {
|
|
12248
|
+
void Promise.resolve(value).catch(() => {
|
|
12249
|
+
});
|
|
12250
|
+
return void 0;
|
|
12251
|
+
}
|
|
12252
|
+
return value;
|
|
12253
|
+
} catch {
|
|
12254
|
+
return void 0;
|
|
12255
|
+
}
|
|
12256
|
+
}
|
|
11510
12257
|
function aggregateAISDKChunks(chunks, _result, endEvent) {
|
|
11511
12258
|
const lastChunk = chunks[chunks.length - 1];
|
|
11512
12259
|
const output = {};
|
|
@@ -11515,17 +12262,21 @@ function aggregateAISDKChunks(chunks, _result, endEvent) {
|
|
|
11515
12262
|
if (lastChunk) {
|
|
11516
12263
|
metrics = hasModelChildTracing(endEvent) ? {} : extractTokenMetrics(lastChunk);
|
|
11517
12264
|
metadata = buildResolvedMetadataPayload(lastChunk).metadata;
|
|
11518
|
-
|
|
11519
|
-
|
|
12265
|
+
const text = safeSerializableFieldRead(lastChunk, "text");
|
|
12266
|
+
if (text !== void 0) {
|
|
12267
|
+
output.text = text;
|
|
11520
12268
|
}
|
|
11521
|
-
|
|
11522
|
-
|
|
12269
|
+
const objectValue = safeSerializableFieldRead(lastChunk, "object");
|
|
12270
|
+
if (objectValue !== void 0) {
|
|
12271
|
+
output.object = objectValue;
|
|
11523
12272
|
}
|
|
11524
|
-
|
|
11525
|
-
|
|
12273
|
+
const finishReason = safeSerializableFieldRead(lastChunk, "finishReason");
|
|
12274
|
+
if (finishReason !== void 0) {
|
|
12275
|
+
output.finishReason = finishReason;
|
|
11526
12276
|
}
|
|
11527
|
-
|
|
11528
|
-
|
|
12277
|
+
const toolCalls = safeSerializableFieldRead(lastChunk, "toolCalls");
|
|
12278
|
+
if (toolCalls !== void 0) {
|
|
12279
|
+
output.toolCalls = toolCalls;
|
|
11529
12280
|
}
|
|
11530
12281
|
}
|
|
11531
12282
|
finalizeAISDKChildTracing(endEvent);
|
|
@@ -11534,14 +12285,20 @@ function aggregateAISDKChunks(chunks, _result, endEvent) {
|
|
|
11534
12285
|
function extractGetterValues(obj) {
|
|
11535
12286
|
const getterValues = {};
|
|
11536
12287
|
const getterNames = [
|
|
12288
|
+
"content",
|
|
11537
12289
|
"text",
|
|
11538
12290
|
"object",
|
|
12291
|
+
"value",
|
|
12292
|
+
"values",
|
|
12293
|
+
"embedding",
|
|
12294
|
+
"embeddings",
|
|
11539
12295
|
"finishReason",
|
|
11540
12296
|
"usage",
|
|
11541
12297
|
"totalUsage",
|
|
11542
12298
|
"toolCalls",
|
|
11543
12299
|
"toolResults",
|
|
11544
12300
|
"warnings",
|
|
12301
|
+
"responses",
|
|
11545
12302
|
"experimental_providerMetadata",
|
|
11546
12303
|
"providerMetadata",
|
|
11547
12304
|
"rawResponse",
|
|
@@ -11549,8 +12306,17 @@ function extractGetterValues(obj) {
|
|
|
11549
12306
|
];
|
|
11550
12307
|
for (const name of getterNames) {
|
|
11551
12308
|
try {
|
|
11552
|
-
if (obj
|
|
11553
|
-
|
|
12309
|
+
if (!obj || !(name in obj)) {
|
|
12310
|
+
continue;
|
|
12311
|
+
}
|
|
12312
|
+
const value = obj[name];
|
|
12313
|
+
if (isPromiseLike(value)) {
|
|
12314
|
+
void Promise.resolve(value).catch(() => {
|
|
12315
|
+
});
|
|
12316
|
+
continue;
|
|
12317
|
+
}
|
|
12318
|
+
if (isSerializableOutputValue(value)) {
|
|
12319
|
+
getterValues[name] = value;
|
|
11554
12320
|
}
|
|
11555
12321
|
} catch {
|
|
11556
12322
|
}
|
|
@@ -11572,6 +12338,11 @@ function extractSerializableOutputFields(output) {
|
|
|
11572
12338
|
for (const name of directFieldNames) {
|
|
11573
12339
|
try {
|
|
11574
12340
|
const value = output?.[name];
|
|
12341
|
+
if (isPromiseLike(value)) {
|
|
12342
|
+
void Promise.resolve(value).catch(() => {
|
|
12343
|
+
});
|
|
12344
|
+
continue;
|
|
12345
|
+
}
|
|
11575
12346
|
if (isSerializableOutputValue(value)) {
|
|
11576
12347
|
serialized[name] = value;
|
|
11577
12348
|
}
|
|
@@ -11583,6 +12354,9 @@ function extractSerializableOutputFields(output) {
|
|
|
11583
12354
|
...extractGetterValues(output)
|
|
11584
12355
|
};
|
|
11585
12356
|
}
|
|
12357
|
+
function isPromiseLike(value) {
|
|
12358
|
+
return value != null && typeof value === "object" && typeof value.then === "function";
|
|
12359
|
+
}
|
|
11586
12360
|
function isSerializableOutputValue(value) {
|
|
11587
12361
|
if (typeof value === "function") {
|
|
11588
12362
|
return false;
|
|
@@ -11624,8 +12398,9 @@ function parseGatewayModelString(modelString) {
|
|
|
11624
12398
|
return { model: modelString };
|
|
11625
12399
|
}
|
|
11626
12400
|
function extractGatewayRoutingInfo(result) {
|
|
11627
|
-
|
|
11628
|
-
|
|
12401
|
+
const steps = safeSerializableFieldRead(result, "steps");
|
|
12402
|
+
if (Array.isArray(steps) && steps.length > 0) {
|
|
12403
|
+
const routing2 = steps[0]?.providerMetadata?.gateway?.routing;
|
|
11629
12404
|
if (routing2) {
|
|
11630
12405
|
return {
|
|
11631
12406
|
provider: routing2.resolvedProvider || routing2.finalProvider,
|
|
@@ -11633,7 +12408,11 @@ function extractGatewayRoutingInfo(result) {
|
|
|
11633
12408
|
};
|
|
11634
12409
|
}
|
|
11635
12410
|
}
|
|
11636
|
-
const
|
|
12411
|
+
const providerMetadata = safeSerializableFieldRead(
|
|
12412
|
+
result,
|
|
12413
|
+
"providerMetadata"
|
|
12414
|
+
);
|
|
12415
|
+
const routing = providerMetadata?.gateway?.routing;
|
|
11637
12416
|
if (routing) {
|
|
11638
12417
|
return {
|
|
11639
12418
|
provider: routing.resolvedProvider || routing.finalProvider,
|
|
@@ -11643,10 +12422,11 @@ function extractGatewayRoutingInfo(result) {
|
|
|
11643
12422
|
return null;
|
|
11644
12423
|
}
|
|
11645
12424
|
function extractCostFromResult(result) {
|
|
11646
|
-
|
|
12425
|
+
const steps = safeSerializableFieldRead(result, "steps");
|
|
12426
|
+
if (Array.isArray(steps) && steps.length > 0) {
|
|
11647
12427
|
let totalCost = 0;
|
|
11648
12428
|
let foundCost = false;
|
|
11649
|
-
for (const step of
|
|
12429
|
+
for (const step of steps) {
|
|
11650
12430
|
const gateway2 = step?.providerMetadata?.gateway;
|
|
11651
12431
|
const stepCost = parseGatewayCost(gateway2?.cost) || parseGatewayCost(gateway2?.marketCost);
|
|
11652
12432
|
if (stepCost !== void 0 && stepCost > 0) {
|
|
@@ -11658,7 +12438,11 @@ function extractCostFromResult(result) {
|
|
|
11658
12438
|
return totalCost;
|
|
11659
12439
|
}
|
|
11660
12440
|
}
|
|
11661
|
-
const
|
|
12441
|
+
const providerMetadata = safeSerializableFieldRead(
|
|
12442
|
+
result,
|
|
12443
|
+
"providerMetadata"
|
|
12444
|
+
);
|
|
12445
|
+
const gateway = providerMetadata?.gateway;
|
|
11662
12446
|
const directCost = parseGatewayCost(gateway?.cost) || parseGatewayCost(gateway?.marketCost);
|
|
11663
12447
|
if (directCost !== void 0 && directCost > 0) {
|
|
11664
12448
|
return directCost;
|
|
@@ -11775,7 +12559,307 @@ var claudeAgentSDKChannels = defineChannels(
|
|
|
11775
12559
|
}
|
|
11776
12560
|
);
|
|
11777
12561
|
|
|
12562
|
+
// src/instrumentation/plugins/claude-agent-sdk-instrumentation-constants.ts
|
|
12563
|
+
var CLAUDE_AGENT_SDK_SKIP_LOCAL_TOOL_HOOKS_OPTION = "__braintrust_skip_local_tool_hooks";
|
|
12564
|
+
|
|
12565
|
+
// src/instrumentation/plugins/claude-agent-sdk-local-tool-context.ts
|
|
12566
|
+
var LOCAL_TOOL_CONTEXT_ASYNC_ITERATOR_PATCHED = Symbol.for(
|
|
12567
|
+
"braintrust.claude_agent_sdk.local_tool_context_async_iterator_patched"
|
|
12568
|
+
);
|
|
12569
|
+
function createLocalToolContextStore() {
|
|
12570
|
+
const maybeIsoWithAsyncLocalStorage = isomorph_default;
|
|
12571
|
+
if (typeof maybeIsoWithAsyncLocalStorage.newAsyncLocalStorage === "function") {
|
|
12572
|
+
return maybeIsoWithAsyncLocalStorage.newAsyncLocalStorage();
|
|
12573
|
+
}
|
|
12574
|
+
let currentStore;
|
|
12575
|
+
return {
|
|
12576
|
+
enterWith(store) {
|
|
12577
|
+
currentStore = store;
|
|
12578
|
+
},
|
|
12579
|
+
getStore() {
|
|
12580
|
+
return currentStore;
|
|
12581
|
+
},
|
|
12582
|
+
run(store, callback) {
|
|
12583
|
+
const previousStore = currentStore;
|
|
12584
|
+
currentStore = store;
|
|
12585
|
+
try {
|
|
12586
|
+
return callback();
|
|
12587
|
+
} finally {
|
|
12588
|
+
currentStore = previousStore;
|
|
12589
|
+
}
|
|
12590
|
+
}
|
|
12591
|
+
};
|
|
12592
|
+
}
|
|
12593
|
+
var localToolContextStore = createLocalToolContextStore();
|
|
12594
|
+
var fallbackLocalToolParentResolver;
|
|
12595
|
+
function createClaudeLocalToolContext() {
|
|
12596
|
+
return {};
|
|
12597
|
+
}
|
|
12598
|
+
function runWithClaudeLocalToolContext(callback, context) {
|
|
12599
|
+
return localToolContextStore.run(
|
|
12600
|
+
context ?? createClaudeLocalToolContext(),
|
|
12601
|
+
callback
|
|
12602
|
+
);
|
|
12603
|
+
}
|
|
12604
|
+
function ensureClaudeLocalToolContext() {
|
|
12605
|
+
const existing = localToolContextStore.getStore();
|
|
12606
|
+
if (existing) {
|
|
12607
|
+
return existing;
|
|
12608
|
+
}
|
|
12609
|
+
const created = {};
|
|
12610
|
+
localToolContextStore.enterWith(created);
|
|
12611
|
+
return created;
|
|
12612
|
+
}
|
|
12613
|
+
function setClaudeLocalToolParentResolver(resolver) {
|
|
12614
|
+
fallbackLocalToolParentResolver = resolver;
|
|
12615
|
+
const context = ensureClaudeLocalToolContext();
|
|
12616
|
+
if (!context) {
|
|
12617
|
+
return;
|
|
12618
|
+
}
|
|
12619
|
+
context.resolveLocalToolParent = resolver;
|
|
12620
|
+
}
|
|
12621
|
+
function getClaudeLocalToolParentResolver() {
|
|
12622
|
+
return localToolContextStore.getStore()?.resolveLocalToolParent ?? fallbackLocalToolParentResolver;
|
|
12623
|
+
}
|
|
12624
|
+
function isAsyncIterable2(value) {
|
|
12625
|
+
return value !== null && typeof value === "object" && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
12626
|
+
}
|
|
12627
|
+
function bindClaudeLocalToolContextToAsyncIterable(result, localToolContext) {
|
|
12628
|
+
if (!isAsyncIterable2(result) || Object.isFrozen(result) || Object.isSealed(result)) {
|
|
12629
|
+
return result;
|
|
12630
|
+
}
|
|
12631
|
+
const stream = result;
|
|
12632
|
+
const originalAsyncIterator = stream[Symbol.asyncIterator];
|
|
12633
|
+
if (originalAsyncIterator[LOCAL_TOOL_CONTEXT_ASYNC_ITERATOR_PATCHED]) {
|
|
12634
|
+
return result;
|
|
12635
|
+
}
|
|
12636
|
+
const patchedAsyncIterator = function() {
|
|
12637
|
+
return runWithClaudeLocalToolContext(() => {
|
|
12638
|
+
const iterator = Reflect.apply(originalAsyncIterator, this, []);
|
|
12639
|
+
if (!iterator || typeof iterator !== "object") {
|
|
12640
|
+
return iterator;
|
|
12641
|
+
}
|
|
12642
|
+
const patchMethod = (methodName) => {
|
|
12643
|
+
const originalMethod = Reflect.get(iterator, methodName);
|
|
12644
|
+
if (typeof originalMethod !== "function") {
|
|
12645
|
+
return;
|
|
12646
|
+
}
|
|
12647
|
+
Reflect.set(
|
|
12648
|
+
iterator,
|
|
12649
|
+
methodName,
|
|
12650
|
+
(...args) => runWithClaudeLocalToolContext(
|
|
12651
|
+
() => Reflect.apply(
|
|
12652
|
+
originalMethod,
|
|
12653
|
+
iterator,
|
|
12654
|
+
args
|
|
12655
|
+
),
|
|
12656
|
+
localToolContext
|
|
12657
|
+
)
|
|
12658
|
+
);
|
|
12659
|
+
};
|
|
12660
|
+
patchMethod("next");
|
|
12661
|
+
patchMethod("return");
|
|
12662
|
+
patchMethod("throw");
|
|
12663
|
+
return iterator;
|
|
12664
|
+
}, localToolContext);
|
|
12665
|
+
};
|
|
12666
|
+
Object.defineProperty(
|
|
12667
|
+
patchedAsyncIterator,
|
|
12668
|
+
LOCAL_TOOL_CONTEXT_ASYNC_ITERATOR_PATCHED,
|
|
12669
|
+
{
|
|
12670
|
+
configurable: false,
|
|
12671
|
+
enumerable: false,
|
|
12672
|
+
value: true,
|
|
12673
|
+
writable: false
|
|
12674
|
+
}
|
|
12675
|
+
);
|
|
12676
|
+
Reflect.set(stream, Symbol.asyncIterator, patchedAsyncIterator);
|
|
12677
|
+
return result;
|
|
12678
|
+
}
|
|
12679
|
+
|
|
12680
|
+
// src/instrumentation/plugins/claude-agent-sdk-local-tool-spans.ts
|
|
12681
|
+
var LOCAL_TOOL_HANDLER_WRAPPED = Symbol.for(
|
|
12682
|
+
"braintrust.claude_agent_sdk.local_tool_handler_wrapped"
|
|
12683
|
+
);
|
|
12684
|
+
function toErrorMessage(error) {
|
|
12685
|
+
return error instanceof Error ? error.message : String(error);
|
|
12686
|
+
}
|
|
12687
|
+
function isPromiseLike2(value) {
|
|
12688
|
+
return value !== null && typeof value === "object" && "then" in value && typeof value.then === "function";
|
|
12689
|
+
}
|
|
12690
|
+
function getToolUseIdFromExtra(extra) {
|
|
12691
|
+
if (!extra || typeof extra !== "object" || !("_meta" in extra)) {
|
|
12692
|
+
return void 0;
|
|
12693
|
+
}
|
|
12694
|
+
const meta = Reflect.get(extra, "_meta");
|
|
12695
|
+
if (!meta || typeof meta !== "object") {
|
|
12696
|
+
return void 0;
|
|
12697
|
+
}
|
|
12698
|
+
const toolUseId = Reflect.get(meta, "claudecode/toolUseId");
|
|
12699
|
+
return typeof toolUseId === "string" ? toolUseId : void 0;
|
|
12700
|
+
}
|
|
12701
|
+
function wrapLocalClaudeToolHandler(handler, getMetadata) {
|
|
12702
|
+
if (handler[LOCAL_TOOL_HANDLER_WRAPPED]) {
|
|
12703
|
+
return handler;
|
|
12704
|
+
}
|
|
12705
|
+
const wrappedHandler = function wrappedLocalToolHandler(...handlerArgs) {
|
|
12706
|
+
const metadata = getMetadata();
|
|
12707
|
+
const rawToolName = metadata.serverName ? `mcp__${metadata.serverName}__${metadata.toolName}` : metadata.toolName;
|
|
12708
|
+
const toolUseId = getToolUseIdFromExtra(handlerArgs[1]);
|
|
12709
|
+
const localToolParentResolver = getClaudeLocalToolParentResolver();
|
|
12710
|
+
const spanName = metadata.serverName ? `tool: ${metadata.serverName}/${metadata.toolName}` : `tool: ${metadata.toolName}`;
|
|
12711
|
+
const runWithResolvedParent = async () => {
|
|
12712
|
+
const parent = toolUseId && localToolParentResolver ? await localToolParentResolver(toolUseId).catch(() => void 0) : void 0;
|
|
12713
|
+
const span = startSpan({
|
|
12714
|
+
event: {
|
|
12715
|
+
input: handlerArgs[0],
|
|
12716
|
+
metadata: {
|
|
12717
|
+
"claude_agent_sdk.raw_tool_name": rawToolName,
|
|
12718
|
+
"gen_ai.tool.name": metadata.toolName,
|
|
12719
|
+
...toolUseId && { "gen_ai.tool.call.id": toolUseId },
|
|
12720
|
+
...metadata.serverName && {
|
|
12721
|
+
"mcp.server": metadata.serverName
|
|
12722
|
+
}
|
|
12723
|
+
}
|
|
12724
|
+
},
|
|
12725
|
+
name: spanName,
|
|
12726
|
+
...parent && { parent },
|
|
12727
|
+
spanAttributes: { type: "tool" /* TOOL */ }
|
|
12728
|
+
});
|
|
12729
|
+
const runHandler = () => Reflect.apply(handler, this, handlerArgs);
|
|
12730
|
+
const finalizeSuccess = (result) => {
|
|
12731
|
+
span.log({ output: result });
|
|
12732
|
+
span.end();
|
|
12733
|
+
return result;
|
|
12734
|
+
};
|
|
12735
|
+
const finalizeError = (error) => {
|
|
12736
|
+
span.log({ error: toErrorMessage(error) });
|
|
12737
|
+
span.end();
|
|
12738
|
+
throw error;
|
|
12739
|
+
};
|
|
12740
|
+
return withCurrent(span, () => {
|
|
12741
|
+
try {
|
|
12742
|
+
const result = runHandler();
|
|
12743
|
+
if (isPromiseLike2(result)) {
|
|
12744
|
+
return result.then(finalizeSuccess, finalizeError);
|
|
12745
|
+
}
|
|
12746
|
+
return finalizeSuccess(result);
|
|
12747
|
+
} catch (error) {
|
|
12748
|
+
return finalizeError(error);
|
|
12749
|
+
}
|
|
12750
|
+
});
|
|
12751
|
+
};
|
|
12752
|
+
return runWithResolvedParent();
|
|
12753
|
+
};
|
|
12754
|
+
Object.defineProperty(wrappedHandler, LOCAL_TOOL_HANDLER_WRAPPED, {
|
|
12755
|
+
configurable: false,
|
|
12756
|
+
enumerable: false,
|
|
12757
|
+
value: true,
|
|
12758
|
+
writable: false
|
|
12759
|
+
});
|
|
12760
|
+
return wrappedHandler;
|
|
12761
|
+
}
|
|
12762
|
+
function getRegisteredTools(instance) {
|
|
12763
|
+
if (!instance || typeof instance !== "object") {
|
|
12764
|
+
return void 0;
|
|
12765
|
+
}
|
|
12766
|
+
if (!("_registeredTools" in instance)) {
|
|
12767
|
+
return void 0;
|
|
12768
|
+
}
|
|
12769
|
+
const registeredTools = Reflect.get(instance, "_registeredTools");
|
|
12770
|
+
if (registeredTools instanceof Map) {
|
|
12771
|
+
return registeredTools;
|
|
12772
|
+
}
|
|
12773
|
+
if (registeredTools && typeof registeredTools === "object") {
|
|
12774
|
+
return registeredTools;
|
|
12775
|
+
}
|
|
12776
|
+
return void 0;
|
|
12777
|
+
}
|
|
12778
|
+
function wrapLocalMcpServerToolHandlers(serverName, serverConfig) {
|
|
12779
|
+
if (!serverConfig || typeof serverConfig !== "object") {
|
|
12780
|
+
return false;
|
|
12781
|
+
}
|
|
12782
|
+
if (!("instance" in serverConfig)) {
|
|
12783
|
+
return false;
|
|
12784
|
+
}
|
|
12785
|
+
const instance = Reflect.get(serverConfig, "instance");
|
|
12786
|
+
const registeredTools = getRegisteredTools(instance);
|
|
12787
|
+
if (!registeredTools) {
|
|
12788
|
+
return false;
|
|
12789
|
+
}
|
|
12790
|
+
let wrappedAny = false;
|
|
12791
|
+
const wrapHandler = (toolName, registration) => {
|
|
12792
|
+
if (!registration || typeof registration !== "object") {
|
|
12793
|
+
return;
|
|
12794
|
+
}
|
|
12795
|
+
const handler = Reflect.get(registration, "handler");
|
|
12796
|
+
if (typeof handler !== "function") {
|
|
12797
|
+
return;
|
|
12798
|
+
}
|
|
12799
|
+
const wrappedHandler = wrapLocalClaudeToolHandler(handler, () => ({
|
|
12800
|
+
serverName,
|
|
12801
|
+
toolName
|
|
12802
|
+
}));
|
|
12803
|
+
if (wrappedHandler !== handler) {
|
|
12804
|
+
Reflect.set(registration, "handler", wrappedHandler);
|
|
12805
|
+
wrappedAny = true;
|
|
12806
|
+
}
|
|
12807
|
+
};
|
|
12808
|
+
if (registeredTools instanceof Map) {
|
|
12809
|
+
for (const [toolName, registration] of registeredTools.entries()) {
|
|
12810
|
+
wrapHandler(toolName, registration);
|
|
12811
|
+
}
|
|
12812
|
+
return wrappedAny;
|
|
12813
|
+
}
|
|
12814
|
+
for (const [toolName, registration] of Object.entries(registeredTools)) {
|
|
12815
|
+
wrapHandler(toolName, registration);
|
|
12816
|
+
}
|
|
12817
|
+
return wrappedAny;
|
|
12818
|
+
}
|
|
12819
|
+
function collectLocalMcpServerToolHookNames(serverName, serverConfig) {
|
|
12820
|
+
const toolNames = /* @__PURE__ */ new Set();
|
|
12821
|
+
if (!serverConfig || typeof serverConfig !== "object") {
|
|
12822
|
+
return toolNames;
|
|
12823
|
+
}
|
|
12824
|
+
if ("instance" in serverConfig) {
|
|
12825
|
+
const instance = Reflect.get(serverConfig, "instance");
|
|
12826
|
+
const registeredTools = getRegisteredTools(instance);
|
|
12827
|
+
if (registeredTools instanceof Map) {
|
|
12828
|
+
for (const toolName of registeredTools.keys()) {
|
|
12829
|
+
toolNames.add(toolName);
|
|
12830
|
+
toolNames.add(`mcp__${serverName}__${toolName}`);
|
|
12831
|
+
}
|
|
12832
|
+
} else if (registeredTools) {
|
|
12833
|
+
for (const toolName of Object.keys(registeredTools)) {
|
|
12834
|
+
toolNames.add(toolName);
|
|
12835
|
+
toolNames.add(`mcp__${serverName}__${toolName}`);
|
|
12836
|
+
}
|
|
12837
|
+
}
|
|
12838
|
+
}
|
|
12839
|
+
if ("tools" in serverConfig) {
|
|
12840
|
+
const rawTools = Reflect.get(serverConfig, "tools");
|
|
12841
|
+
if (Array.isArray(rawTools)) {
|
|
12842
|
+
for (const tool of rawTools) {
|
|
12843
|
+
if (!tool || typeof tool !== "object") {
|
|
12844
|
+
continue;
|
|
12845
|
+
}
|
|
12846
|
+
const toolName = Reflect.get(tool, "name");
|
|
12847
|
+
if (typeof toolName !== "string") {
|
|
12848
|
+
continue;
|
|
12849
|
+
}
|
|
12850
|
+
toolNames.add(toolName);
|
|
12851
|
+
toolNames.add(`mcp__${serverName}__${toolName}`);
|
|
12852
|
+
}
|
|
12853
|
+
}
|
|
12854
|
+
}
|
|
12855
|
+
return toolNames;
|
|
12856
|
+
}
|
|
12857
|
+
|
|
11778
12858
|
// src/instrumentation/plugins/claude-agent-sdk-plugin.ts
|
|
12859
|
+
var ROOT_LLM_PARENT_KEY = "__root__";
|
|
12860
|
+
function llmParentKey(parentToolUseId) {
|
|
12861
|
+
return parentToolUseId ?? ROOT_LLM_PARENT_KEY;
|
|
12862
|
+
}
|
|
11779
12863
|
function isSubAgentToolName(toolName) {
|
|
11780
12864
|
return toolName === "Agent" || toolName === "Task";
|
|
11781
12865
|
}
|
|
@@ -11861,7 +12945,7 @@ function buildLLMInput(prompt, conversationHistory, capturedPromptMessages) {
|
|
|
11861
12945
|
function formatCapturedMessages(messages) {
|
|
11862
12946
|
return messages.length > 0 ? messages : [];
|
|
11863
12947
|
}
|
|
11864
|
-
async function createLLMSpanForMessages(messages, prompt, conversationHistory, options, startTime, capturedPromptMessages, parentSpan) {
|
|
12948
|
+
async function createLLMSpanForMessages(messages, prompt, conversationHistory, options, startTime, capturedPromptMessages, parentSpan, existingSpan) {
|
|
11865
12949
|
if (messages.length === 0) {
|
|
11866
12950
|
return void 0;
|
|
11867
12951
|
}
|
|
@@ -11881,7 +12965,7 @@ async function createLLMSpanForMessages(messages, prompt, conversationHistory, o
|
|
|
11881
12965
|
).filter(
|
|
11882
12966
|
(c) => c !== void 0
|
|
11883
12967
|
);
|
|
11884
|
-
const span = startSpan({
|
|
12968
|
+
const span = existingSpan ?? startSpan({
|
|
11885
12969
|
name: "anthropic.messages.create",
|
|
11886
12970
|
parent: parentSpan,
|
|
11887
12971
|
spanAttributes: {
|
|
@@ -11895,8 +12979,13 @@ async function createLLMSpanForMessages(messages, prompt, conversationHistory, o
|
|
|
11895
12979
|
metrics: usage,
|
|
11896
12980
|
output: outputs
|
|
11897
12981
|
});
|
|
12982
|
+
const spanExport = await span.export();
|
|
11898
12983
|
await span.end();
|
|
11899
|
-
|
|
12984
|
+
const finalMessage = lastMessage.message?.content && lastMessage.message?.role ? { content: lastMessage.message.content, role: lastMessage.message.role } : void 0;
|
|
12985
|
+
return {
|
|
12986
|
+
finalMessage,
|
|
12987
|
+
spanExport
|
|
12988
|
+
};
|
|
11900
12989
|
}
|
|
11901
12990
|
function getMcpServerMetadata(serverName, mcpServers) {
|
|
11902
12991
|
if (!serverName || !mcpServers) {
|
|
@@ -11940,11 +13029,51 @@ function parseToolName(rawToolName) {
|
|
|
11940
13029
|
toolName: rawToolName
|
|
11941
13030
|
};
|
|
11942
13031
|
}
|
|
11943
|
-
function
|
|
13032
|
+
function isLocalToolUse(rawToolName, mcpServers) {
|
|
13033
|
+
const parsed = parseToolName(rawToolName);
|
|
13034
|
+
if (!parsed.mcpServer || !mcpServers) {
|
|
13035
|
+
return false;
|
|
13036
|
+
}
|
|
13037
|
+
const serverConfig = mcpServers[parsed.mcpServer];
|
|
13038
|
+
if (!serverConfig || typeof serverConfig !== "object") {
|
|
13039
|
+
return false;
|
|
13040
|
+
}
|
|
13041
|
+
return serverConfig.type === "sdk" || "transport" in serverConfig;
|
|
13042
|
+
}
|
|
13043
|
+
function prepareLocalToolHandlersInMcpServers(mcpServers) {
|
|
13044
|
+
const localToolHookNames = /* @__PURE__ */ new Set();
|
|
13045
|
+
if (!mcpServers) {
|
|
13046
|
+
return {
|
|
13047
|
+
hasLocalToolHandlers: false,
|
|
13048
|
+
localToolHookNames
|
|
13049
|
+
};
|
|
13050
|
+
}
|
|
13051
|
+
let hasLocalToolHandlers = false;
|
|
13052
|
+
for (const [serverName, serverConfig] of Object.entries(mcpServers)) {
|
|
13053
|
+
const toolNames = collectLocalMcpServerToolHookNames(
|
|
13054
|
+
serverName,
|
|
13055
|
+
serverConfig
|
|
13056
|
+
);
|
|
13057
|
+
for (const toolName of toolNames) {
|
|
13058
|
+
localToolHookNames.add(toolName);
|
|
13059
|
+
}
|
|
13060
|
+
if (toolNames.size > 0) {
|
|
13061
|
+
hasLocalToolHandlers = true;
|
|
13062
|
+
}
|
|
13063
|
+
if (wrapLocalMcpServerToolHandlers(serverName, serverConfig)) {
|
|
13064
|
+
hasLocalToolHandlers = true;
|
|
13065
|
+
}
|
|
13066
|
+
}
|
|
13067
|
+
return { hasLocalToolHandlers, localToolHookNames };
|
|
13068
|
+
}
|
|
13069
|
+
function createToolTracingHooks(resolveParentSpan, activeToolSpans, mcpServers, localToolHookNames, skipLocalToolHooks, subAgentSpans, endedSubAgentSpans) {
|
|
11944
13070
|
const preToolUse = async (input, toolUseID) => {
|
|
11945
13071
|
if (input.hook_event_name !== "PreToolUse" || !toolUseID) {
|
|
11946
13072
|
return {};
|
|
11947
13073
|
}
|
|
13074
|
+
if (skipLocalToolHooks && (isLocalToolUse(input.tool_name, mcpServers) || localToolHookNames.has(input.tool_name))) {
|
|
13075
|
+
return {};
|
|
13076
|
+
}
|
|
11948
13077
|
if (isSubAgentToolName(input.tool_name)) {
|
|
11949
13078
|
return {};
|
|
11950
13079
|
}
|
|
@@ -11973,6 +13102,9 @@ function createToolTracingHooks(resolveParentSpan, activeToolSpans, mcpServers,
|
|
|
11973
13102
|
if (input.hook_event_name !== "PostToolUse" || !toolUseID) {
|
|
11974
13103
|
return {};
|
|
11975
13104
|
}
|
|
13105
|
+
if (skipLocalToolHooks && (isLocalToolUse(input.tool_name, mcpServers) || localToolHookNames.has(input.tool_name))) {
|
|
13106
|
+
return {};
|
|
13107
|
+
}
|
|
11976
13108
|
const subAgentSpan = subAgentSpans.get(toolUseID);
|
|
11977
13109
|
if (subAgentSpan) {
|
|
11978
13110
|
try {
|
|
@@ -12013,6 +13145,9 @@ function createToolTracingHooks(resolveParentSpan, activeToolSpans, mcpServers,
|
|
|
12013
13145
|
if (input.hook_event_name !== "PostToolUseFailure" || !toolUseID) {
|
|
12014
13146
|
return {};
|
|
12015
13147
|
}
|
|
13148
|
+
if (skipLocalToolHooks && (isLocalToolUse(input.tool_name, mcpServers) || localToolHookNames.has(input.tool_name))) {
|
|
13149
|
+
return {};
|
|
13150
|
+
}
|
|
12016
13151
|
const subAgentSpan = subAgentSpans.get(toolUseID);
|
|
12017
13152
|
if (subAgentSpan) {
|
|
12018
13153
|
try {
|
|
@@ -12047,11 +13182,13 @@ function createToolTracingHooks(resolveParentSpan, activeToolSpans, mcpServers,
|
|
|
12047
13182
|
};
|
|
12048
13183
|
return { postToolUse, postToolUseFailure, preToolUse };
|
|
12049
13184
|
}
|
|
12050
|
-
function injectTracingHooks(options, resolveParentSpan, activeToolSpans, subAgentSpans, endedSubAgentSpans) {
|
|
13185
|
+
function injectTracingHooks(options, resolveParentSpan, activeToolSpans, localToolHookNames, skipLocalToolHooks, subAgentSpans, endedSubAgentSpans) {
|
|
12051
13186
|
const { preToolUse, postToolUse, postToolUseFailure } = createToolTracingHooks(
|
|
12052
13187
|
resolveParentSpan,
|
|
12053
13188
|
activeToolSpans,
|
|
12054
13189
|
options.mcpServers,
|
|
13190
|
+
localToolHookNames,
|
|
13191
|
+
skipLocalToolHooks,
|
|
12055
13192
|
subAgentSpans,
|
|
12056
13193
|
endedSubAgentSpans
|
|
12057
13194
|
);
|
|
@@ -12082,6 +13219,7 @@ async function finalizeCurrentMessageGroup(state) {
|
|
|
12082
13219
|
return;
|
|
12083
13220
|
}
|
|
12084
13221
|
const parentToolUseId = state.currentMessages[0]?.parent_tool_use_id ?? null;
|
|
13222
|
+
const parentKey = llmParentKey(parentToolUseId);
|
|
12085
13223
|
let parentSpan = await state.span.export();
|
|
12086
13224
|
if (parentToolUseId) {
|
|
12087
13225
|
const subAgentSpan = state.subAgentSpans.get(parentToolUseId);
|
|
@@ -12089,17 +13227,30 @@ async function finalizeCurrentMessageGroup(state) {
|
|
|
12089
13227
|
parentSpan = await subAgentSpan.export();
|
|
12090
13228
|
}
|
|
12091
13229
|
}
|
|
12092
|
-
const
|
|
13230
|
+
const existingLlmSpan = state.activeLlmSpansByParentToolUse.get(parentKey);
|
|
13231
|
+
const llmSpanResult = await createLLMSpanForMessages(
|
|
12093
13232
|
state.currentMessages,
|
|
12094
13233
|
state.originalPrompt,
|
|
12095
13234
|
state.finalResults,
|
|
12096
13235
|
state.options,
|
|
12097
13236
|
state.currentMessageStartTime,
|
|
12098
13237
|
state.capturedPromptMessages,
|
|
12099
|
-
parentSpan
|
|
13238
|
+
parentSpan,
|
|
13239
|
+
existingLlmSpan
|
|
12100
13240
|
);
|
|
12101
|
-
|
|
12102
|
-
|
|
13241
|
+
state.activeLlmSpansByParentToolUse.delete(parentKey);
|
|
13242
|
+
if (llmSpanResult) {
|
|
13243
|
+
if (parentToolUseId) {
|
|
13244
|
+
state.latestLlmParentBySubAgentToolUse.set(
|
|
13245
|
+
parentToolUseId,
|
|
13246
|
+
llmSpanResult.spanExport
|
|
13247
|
+
);
|
|
13248
|
+
} else {
|
|
13249
|
+
state.latestRootLlmParentRef.value = llmSpanResult.spanExport;
|
|
13250
|
+
}
|
|
13251
|
+
if (llmSpanResult.finalMessage) {
|
|
13252
|
+
state.finalResults.push(llmSpanResult.finalMessage);
|
|
13253
|
+
}
|
|
12103
13254
|
}
|
|
12104
13255
|
const lastMessage = state.currentMessages[state.currentMessages.length - 1];
|
|
12105
13256
|
if (lastMessage?.message?.usage) {
|
|
@@ -12167,6 +13318,29 @@ async function handleStreamMessage(state, message) {
|
|
|
12167
13318
|
state.currentMessageStartTime = getCurrentUnixTimestamp();
|
|
12168
13319
|
}
|
|
12169
13320
|
if (message.type === "assistant" && message.message?.usage) {
|
|
13321
|
+
const parentToolUseId = message.parent_tool_use_id ?? null;
|
|
13322
|
+
const parentKey = llmParentKey(parentToolUseId);
|
|
13323
|
+
if (!state.activeLlmSpansByParentToolUse.has(parentKey)) {
|
|
13324
|
+
let llmParentSpan = await state.span.export();
|
|
13325
|
+
if (parentToolUseId) {
|
|
13326
|
+
const subAgentSpan = await ensureSubAgentSpan(
|
|
13327
|
+
state.pendingSubAgentNames,
|
|
13328
|
+
state.span,
|
|
13329
|
+
state.subAgentSpans,
|
|
13330
|
+
parentToolUseId
|
|
13331
|
+
);
|
|
13332
|
+
llmParentSpan = await subAgentSpan.export();
|
|
13333
|
+
}
|
|
13334
|
+
const llmSpan = startSpan({
|
|
13335
|
+
name: "anthropic.messages.create",
|
|
13336
|
+
parent: llmParentSpan,
|
|
13337
|
+
spanAttributes: {
|
|
13338
|
+
type: "llm" /* LLM */
|
|
13339
|
+
},
|
|
13340
|
+
startTime: state.currentMessageStartTime
|
|
13341
|
+
});
|
|
13342
|
+
state.activeLlmSpansByParentToolUse.set(parentKey, llmSpan);
|
|
13343
|
+
}
|
|
12170
13344
|
state.currentMessages.push(message);
|
|
12171
13345
|
}
|
|
12172
13346
|
if (message.type !== "result" || !message.usage) {
|
|
@@ -12227,6 +13401,10 @@ async function finalizeQuerySpan(state) {
|
|
|
12227
13401
|
}
|
|
12228
13402
|
}
|
|
12229
13403
|
} finally {
|
|
13404
|
+
for (const llmSpan of state.activeLlmSpansByParentToolUse.values()) {
|
|
13405
|
+
llmSpan.end();
|
|
13406
|
+
}
|
|
13407
|
+
state.activeLlmSpansByParentToolUse.clear();
|
|
12230
13408
|
for (const [id, subAgentSpan] of state.subAgentSpans) {
|
|
12231
13409
|
if (!state.endedSubAgentSpans.has(id)) {
|
|
12232
13410
|
subAgentSpan.end();
|
|
@@ -12292,26 +13470,51 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
12292
13470
|
console.error("Error extracting input for Claude Agent SDK:", error);
|
|
12293
13471
|
}
|
|
12294
13472
|
const activeToolSpans = /* @__PURE__ */ new Map();
|
|
13473
|
+
const activeLlmSpansByParentToolUse = /* @__PURE__ */ new Map();
|
|
12295
13474
|
const subAgentSpans = /* @__PURE__ */ new Map();
|
|
12296
13475
|
const endedSubAgentSpans = /* @__PURE__ */ new Set();
|
|
12297
13476
|
const toolUseToParent = /* @__PURE__ */ new Map();
|
|
13477
|
+
const latestLlmParentBySubAgentToolUse = /* @__PURE__ */ new Map();
|
|
13478
|
+
const latestRootLlmParentRef = {
|
|
13479
|
+
value: void 0
|
|
13480
|
+
};
|
|
12298
13481
|
const pendingSubAgentNames = /* @__PURE__ */ new Map();
|
|
13482
|
+
const localToolContext = createClaudeLocalToolContext();
|
|
13483
|
+
const { hasLocalToolHandlers, localToolHookNames } = prepareLocalToolHandlersInMcpServers(options.mcpServers);
|
|
13484
|
+
const skipLocalToolHooks = options[CLAUDE_AGENT_SDK_SKIP_LOCAL_TOOL_HOOKS_OPTION] === true || hasLocalToolHandlers;
|
|
13485
|
+
const resolveToolUseParentSpan = async (toolUseID) => {
|
|
13486
|
+
const parentToolUseId = toolUseToParent.get(toolUseID) ?? null;
|
|
13487
|
+
const parentKey = llmParentKey(parentToolUseId);
|
|
13488
|
+
const activeLlmSpan = activeLlmSpansByParentToolUse.get(parentKey);
|
|
13489
|
+
if (activeLlmSpan) {
|
|
13490
|
+
return activeLlmSpan.export();
|
|
13491
|
+
}
|
|
13492
|
+
if (parentToolUseId) {
|
|
13493
|
+
const parentLlm = latestLlmParentBySubAgentToolUse.get(parentToolUseId);
|
|
13494
|
+
if (parentLlm) {
|
|
13495
|
+
return parentLlm;
|
|
13496
|
+
}
|
|
13497
|
+
const subAgentSpan = await ensureSubAgentSpan(
|
|
13498
|
+
pendingSubAgentNames,
|
|
13499
|
+
span,
|
|
13500
|
+
subAgentSpans,
|
|
13501
|
+
parentToolUseId
|
|
13502
|
+
);
|
|
13503
|
+
return subAgentSpan.export();
|
|
13504
|
+
}
|
|
13505
|
+
if (latestRootLlmParentRef.value) {
|
|
13506
|
+
return latestRootLlmParentRef.value;
|
|
13507
|
+
}
|
|
13508
|
+
return span.export();
|
|
13509
|
+
};
|
|
13510
|
+
localToolContext.resolveLocalToolParent = resolveToolUseParentSpan;
|
|
13511
|
+
setClaudeLocalToolParentResolver(resolveToolUseParentSpan);
|
|
12299
13512
|
const optionsWithHooks = injectTracingHooks(
|
|
12300
13513
|
options,
|
|
12301
|
-
|
|
12302
|
-
const parentToolUseId = toolUseToParent.get(toolUseID);
|
|
12303
|
-
if (parentToolUseId) {
|
|
12304
|
-
const subAgentSpan = await ensureSubAgentSpan(
|
|
12305
|
-
pendingSubAgentNames,
|
|
12306
|
-
span,
|
|
12307
|
-
subAgentSpans,
|
|
12308
|
-
parentToolUseId
|
|
12309
|
-
);
|
|
12310
|
-
return subAgentSpan.export();
|
|
12311
|
-
}
|
|
12312
|
-
return span.export();
|
|
12313
|
-
},
|
|
13514
|
+
resolveToolUseParentSpan,
|
|
12314
13515
|
activeToolSpans,
|
|
13516
|
+
localToolHookNames,
|
|
13517
|
+
skipLocalToolHooks,
|
|
12315
13518
|
subAgentSpans,
|
|
12316
13519
|
endedSubAgentSpans
|
|
12317
13520
|
);
|
|
@@ -12319,6 +13522,7 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
12319
13522
|
event.arguments[0] = params;
|
|
12320
13523
|
spans.set(event, {
|
|
12321
13524
|
accumulatedOutputTokens: 0,
|
|
13525
|
+
activeLlmSpansByParentToolUse,
|
|
12322
13526
|
activeToolSpans,
|
|
12323
13527
|
capturedPromptMessages,
|
|
12324
13528
|
currentMessageId: void 0,
|
|
@@ -12334,7 +13538,10 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
12334
13538
|
promptStarted: () => promptStarted,
|
|
12335
13539
|
span,
|
|
12336
13540
|
subAgentSpans,
|
|
12337
|
-
|
|
13541
|
+
latestLlmParentBySubAgentToolUse,
|
|
13542
|
+
latestRootLlmParentRef,
|
|
13543
|
+
toolUseToParent,
|
|
13544
|
+
localToolContext
|
|
12338
13545
|
});
|
|
12339
13546
|
},
|
|
12340
13547
|
end: (event) => {
|
|
@@ -12342,7 +13549,10 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
12342
13549
|
if (!state) {
|
|
12343
13550
|
return;
|
|
12344
13551
|
}
|
|
12345
|
-
const eventResult =
|
|
13552
|
+
const eventResult = bindClaudeLocalToolContextToAsyncIterable(
|
|
13553
|
+
event.result,
|
|
13554
|
+
state.localToolContext
|
|
13555
|
+
);
|
|
12346
13556
|
if (eventResult === void 0) {
|
|
12347
13557
|
state.span.end();
|
|
12348
13558
|
spans.delete(event);
|
|
@@ -12359,20 +13569,16 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
12359
13569
|
);
|
|
12360
13570
|
});
|
|
12361
13571
|
},
|
|
12362
|
-
onComplete: () => {
|
|
12363
|
-
|
|
12364
|
-
|
|
12365
|
-
|
|
12366
|
-
|
|
12367
|
-
|
|
12368
|
-
void state.processing.then(() => {
|
|
12369
|
-
state.span.log({
|
|
12370
|
-
error: error.message
|
|
12371
|
-
});
|
|
12372
|
-
}).then(() => finalizeQuerySpan(state)).finally(() => {
|
|
12373
|
-
spans.delete(event);
|
|
13572
|
+
onComplete: () => state.processing.then(() => finalizeQuerySpan(state)).finally(() => {
|
|
13573
|
+
spans.delete(event);
|
|
13574
|
+
}),
|
|
13575
|
+
onError: (error) => state.processing.then(() => {
|
|
13576
|
+
state.span.log({
|
|
13577
|
+
error: error.message
|
|
12374
13578
|
});
|
|
12375
|
-
}
|
|
13579
|
+
}).then(() => finalizeQuerySpan(state)).finally(() => {
|
|
13580
|
+
spans.delete(event);
|
|
13581
|
+
})
|
|
12376
13582
|
});
|
|
12377
13583
|
return;
|
|
12378
13584
|
}
|
|
@@ -12520,12 +13726,14 @@ var GoogleGenAIPlugin = class extends BasePlugin {
|
|
|
12520
13726
|
const params = event.arguments[0];
|
|
12521
13727
|
streamEvent.googleGenAIInput = serializeInput(params);
|
|
12522
13728
|
streamEvent.googleGenAIMetadata = extractMetadata(params);
|
|
13729
|
+
streamEvent.googleGenAIStartTime = getCurrentUnixTimestamp();
|
|
12523
13730
|
},
|
|
12524
13731
|
asyncEnd: (event) => {
|
|
12525
13732
|
const streamEvent = event;
|
|
12526
13733
|
patchGoogleGenAIStreamingResult({
|
|
12527
13734
|
input: streamEvent.googleGenAIInput,
|
|
12528
13735
|
metadata: streamEvent.googleGenAIMetadata,
|
|
13736
|
+
startTime: streamEvent.googleGenAIStartTime,
|
|
12529
13737
|
result: streamEvent.result
|
|
12530
13738
|
});
|
|
12531
13739
|
},
|
|
@@ -12549,19 +13757,20 @@ function ensureSpanState(states, event, create) {
|
|
|
12549
13757
|
}
|
|
12550
13758
|
function bindCurrentSpanStoreToStart2(tracingChannel2, states, create) {
|
|
12551
13759
|
const state = _internalGetGlobalState();
|
|
13760
|
+
const contextManager = state?.contextManager;
|
|
12552
13761
|
const startChannel = tracingChannel2.start;
|
|
12553
|
-
const currentSpanStore =
|
|
13762
|
+
const currentSpanStore = contextManager ? contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
|
|
12554
13763
|
if (!startChannel?.bindStore || !currentSpanStore) {
|
|
12555
13764
|
return void 0;
|
|
12556
13765
|
}
|
|
12557
|
-
startChannel.bindStore(
|
|
12558
|
-
|
|
12559
|
-
(event) => ensureSpanState(
|
|
13766
|
+
startChannel.bindStore(currentSpanStore, (event) => {
|
|
13767
|
+
const span = ensureSpanState(
|
|
12560
13768
|
states,
|
|
12561
13769
|
event,
|
|
12562
13770
|
() => create(event)
|
|
12563
|
-
).span
|
|
12564
|
-
|
|
13771
|
+
).span;
|
|
13772
|
+
return contextManager.wrapSpanForStore(span);
|
|
13773
|
+
});
|
|
12565
13774
|
return () => {
|
|
12566
13775
|
startChannel.unbindStore?.(currentSpanStore);
|
|
12567
13776
|
};
|
|
@@ -12578,7 +13787,7 @@ function logErrorAndEndSpan(states, event) {
|
|
|
12578
13787
|
states.delete(event);
|
|
12579
13788
|
}
|
|
12580
13789
|
function patchGoogleGenAIStreamingResult(args) {
|
|
12581
|
-
const { input, metadata, result } = args;
|
|
13790
|
+
const { input, metadata, result, startTime } = args;
|
|
12582
13791
|
if (!input || !metadata || !result || typeof result !== "object" || typeof result.next !== "function") {
|
|
12583
13792
|
return false;
|
|
12584
13793
|
}
|
|
@@ -12586,7 +13795,7 @@ function patchGoogleGenAIStreamingResult(args) {
|
|
|
12586
13795
|
let firstTokenTime = null;
|
|
12587
13796
|
let finalized = false;
|
|
12588
13797
|
let span = null;
|
|
12589
|
-
|
|
13798
|
+
const requestStartTime = startTime ?? getCurrentUnixTimestamp();
|
|
12590
13799
|
const ensureSpan = () => {
|
|
12591
13800
|
if (!span) {
|
|
12592
13801
|
span = startSpan({
|
|
@@ -12599,7 +13808,6 @@ function patchGoogleGenAIStreamingResult(args) {
|
|
|
12599
13808
|
metadata
|
|
12600
13809
|
}
|
|
12601
13810
|
});
|
|
12602
|
-
startTime = getCurrentUnixTimestamp();
|
|
12603
13811
|
}
|
|
12604
13812
|
return span;
|
|
12605
13813
|
};
|
|
@@ -12653,11 +13861,11 @@ function patchGoogleGenAIStreamingResult(args) {
|
|
|
12653
13861
|
}
|
|
12654
13862
|
chunks.push(nextResult.value);
|
|
12655
13863
|
}
|
|
12656
|
-
if (nextResult.done
|
|
13864
|
+
if (nextResult.done) {
|
|
12657
13865
|
finalize({
|
|
12658
13866
|
result: aggregateGenerateContentChunks(
|
|
12659
13867
|
chunks,
|
|
12660
|
-
|
|
13868
|
+
requestStartTime,
|
|
12661
13869
|
firstTokenTime
|
|
12662
13870
|
)
|
|
12663
13871
|
});
|
|
@@ -12677,13 +13885,13 @@ function patchGoogleGenAIStreamingResult(args) {
|
|
|
12677
13885
|
...returnArgs
|
|
12678
13886
|
);
|
|
12679
13887
|
} finally {
|
|
12680
|
-
if (
|
|
13888
|
+
if (chunks.length > 0) {
|
|
12681
13889
|
finalize({
|
|
12682
|
-
result:
|
|
13890
|
+
result: aggregateGenerateContentChunks(
|
|
12683
13891
|
chunks,
|
|
12684
|
-
|
|
13892
|
+
requestStartTime,
|
|
12685
13893
|
firstTokenTime
|
|
12686
|
-
)
|
|
13894
|
+
)
|
|
12687
13895
|
});
|
|
12688
13896
|
} else {
|
|
12689
13897
|
finalize({});
|
|
@@ -12957,46 +14165,161 @@ function tryToDict(obj) {
|
|
|
12957
14165
|
return null;
|
|
12958
14166
|
}
|
|
12959
14167
|
|
|
12960
|
-
// src/instrumentation/plugins/openrouter-channels.ts
|
|
12961
|
-
var
|
|
12962
|
-
chatSend: channel({
|
|
12963
|
-
channelName: "chat.send",
|
|
12964
|
-
kind: "async"
|
|
12965
|
-
}),
|
|
12966
|
-
embeddingsGenerate: channel({
|
|
12967
|
-
channelName: "embeddings.generate",
|
|
12968
|
-
kind: "async"
|
|
12969
|
-
}),
|
|
12970
|
-
betaResponsesSend: channel({
|
|
12971
|
-
channelName: "beta.responses.send",
|
|
12972
|
-
kind: "async"
|
|
12973
|
-
}),
|
|
14168
|
+
// src/instrumentation/plugins/openrouter-agent-channels.ts
|
|
14169
|
+
var openRouterAgentChannels = defineChannels("@openrouter/agent", {
|
|
12974
14170
|
callModel: channel({
|
|
12975
14171
|
channelName: "callModel",
|
|
12976
14172
|
kind: "sync-stream"
|
|
12977
14173
|
}),
|
|
14174
|
+
callModelTurn: channel({
|
|
14175
|
+
channelName: "callModel.turn",
|
|
14176
|
+
kind: "async"
|
|
14177
|
+
}),
|
|
12978
14178
|
toolExecute: channel({
|
|
12979
14179
|
channelName: "tool.execute",
|
|
12980
14180
|
kind: "async"
|
|
12981
14181
|
})
|
|
12982
14182
|
});
|
|
12983
14183
|
|
|
12984
|
-
// src/openrouter-
|
|
12985
|
-
var
|
|
12986
|
-
|
|
12987
|
-
|
|
12988
|
-
|
|
12989
|
-
|
|
12990
|
-
|
|
12991
|
-
|
|
12992
|
-
|
|
12993
|
-
|
|
12994
|
-
|
|
12995
|
-
|
|
12996
|
-
|
|
12997
|
-
|
|
12998
|
-
|
|
12999
|
-
|
|
14184
|
+
// src/instrumentation/plugins/openrouter-agent-plugin.ts
|
|
14185
|
+
var OpenRouterAgentPlugin = class extends BasePlugin {
|
|
14186
|
+
onEnable() {
|
|
14187
|
+
this.subscribeToOpenRouterAgentChannels();
|
|
14188
|
+
}
|
|
14189
|
+
onDisable() {
|
|
14190
|
+
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
14191
|
+
}
|
|
14192
|
+
subscribeToOpenRouterAgentChannels() {
|
|
14193
|
+
this.unsubscribers.push(
|
|
14194
|
+
traceSyncStreamChannel(openRouterAgentChannels.callModel, {
|
|
14195
|
+
name: "openrouter.callModel",
|
|
14196
|
+
type: "llm" /* LLM */,
|
|
14197
|
+
extractInput: (args) => {
|
|
14198
|
+
const request = getOpenRouterCallModelRequestArg(args);
|
|
14199
|
+
return {
|
|
14200
|
+
input: request ? extractOpenRouterCallModelInput(request) : void 0,
|
|
14201
|
+
metadata: request ? extractOpenRouterCallModelMetadata(request) : { provider: "openrouter" }
|
|
14202
|
+
};
|
|
14203
|
+
},
|
|
14204
|
+
patchResult: ({ endEvent, result, span }) => {
|
|
14205
|
+
return patchOpenRouterCallModelResult({
|
|
14206
|
+
request: getOpenRouterCallModelRequestArg(endEvent.arguments),
|
|
14207
|
+
result,
|
|
14208
|
+
span
|
|
14209
|
+
});
|
|
14210
|
+
}
|
|
14211
|
+
})
|
|
14212
|
+
);
|
|
14213
|
+
this.unsubscribers.push(
|
|
14214
|
+
traceAsyncChannel(openRouterAgentChannels.callModelTurn, {
|
|
14215
|
+
name: "openrouter.beta.responses.send",
|
|
14216
|
+
type: "llm" /* LLM */,
|
|
14217
|
+
extractInput: (args, event) => {
|
|
14218
|
+
const request = getOpenRouterCallModelRequestArg(args);
|
|
14219
|
+
const metadata = request ? extractOpenRouterCallModelMetadata(request) : { provider: "openrouter" };
|
|
14220
|
+
if (isObject(metadata) && "tools" in metadata) {
|
|
14221
|
+
delete metadata.tools;
|
|
14222
|
+
}
|
|
14223
|
+
return {
|
|
14224
|
+
input: request ? extractOpenRouterCallModelInput(request) : void 0,
|
|
14225
|
+
metadata: {
|
|
14226
|
+
...metadata,
|
|
14227
|
+
step: event.step,
|
|
14228
|
+
step_type: event.stepType
|
|
14229
|
+
}
|
|
14230
|
+
};
|
|
14231
|
+
},
|
|
14232
|
+
extractOutput: (result) => extractOpenRouterResponseOutput(result),
|
|
14233
|
+
extractMetadata: (result, event) => {
|
|
14234
|
+
if (!isObject(result)) {
|
|
14235
|
+
return {
|
|
14236
|
+
step: event?.step,
|
|
14237
|
+
step_type: event?.stepType
|
|
14238
|
+
};
|
|
14239
|
+
}
|
|
14240
|
+
return {
|
|
14241
|
+
...extractOpenRouterResponseMetadata(result) || {},
|
|
14242
|
+
...event?.step !== void 0 ? { step: event.step } : {},
|
|
14243
|
+
...event?.stepType ? { step_type: event.stepType } : {}
|
|
14244
|
+
};
|
|
14245
|
+
},
|
|
14246
|
+
extractMetrics: (result) => isObject(result) ? parseOpenRouterMetricsFromUsage(result.usage) : {}
|
|
14247
|
+
})
|
|
14248
|
+
);
|
|
14249
|
+
this.unsubscribers.push(
|
|
14250
|
+
traceStreamingChannel(openRouterAgentChannels.toolExecute, {
|
|
14251
|
+
name: "openrouter.tool",
|
|
14252
|
+
type: "tool" /* TOOL */,
|
|
14253
|
+
extractInput: (args, event) => ({
|
|
14254
|
+
input: args[0],
|
|
14255
|
+
metadata: {
|
|
14256
|
+
provider: "openrouter",
|
|
14257
|
+
tool_name: event.toolName,
|
|
14258
|
+
...event.toolCallId ? { tool_call_id: event.toolCallId } : {}
|
|
14259
|
+
}
|
|
14260
|
+
}),
|
|
14261
|
+
extractOutput: (result) => result,
|
|
14262
|
+
extractMetrics: () => ({}),
|
|
14263
|
+
aggregateChunks: (chunks) => ({
|
|
14264
|
+
output: chunks.length > 0 ? chunks[chunks.length - 1] : void 0,
|
|
14265
|
+
metrics: {}
|
|
14266
|
+
})
|
|
14267
|
+
})
|
|
14268
|
+
);
|
|
14269
|
+
const callModelChannel = openRouterAgentChannels.callModel.tracingChannel();
|
|
14270
|
+
const callModelHandlers = {
|
|
14271
|
+
start: (event) => {
|
|
14272
|
+
const request = getOpenRouterCallModelRequestArg(event.arguments);
|
|
14273
|
+
if (!request) {
|
|
14274
|
+
return;
|
|
14275
|
+
}
|
|
14276
|
+
patchOpenRouterCallModelRequestTools(request);
|
|
14277
|
+
}
|
|
14278
|
+
};
|
|
14279
|
+
callModelChannel.subscribe(callModelHandlers);
|
|
14280
|
+
this.unsubscribers.push(() => {
|
|
14281
|
+
callModelChannel.unsubscribe(callModelHandlers);
|
|
14282
|
+
});
|
|
14283
|
+
}
|
|
14284
|
+
};
|
|
14285
|
+
function normalizeArgs(args) {
|
|
14286
|
+
if (Array.isArray(args)) {
|
|
14287
|
+
return args;
|
|
14288
|
+
}
|
|
14289
|
+
if (isArrayLike(args)) {
|
|
14290
|
+
return Array.from(args);
|
|
14291
|
+
}
|
|
14292
|
+
return [args];
|
|
14293
|
+
}
|
|
14294
|
+
function isArrayLike(value) {
|
|
14295
|
+
return isObject(value) && "length" in value && typeof value.length === "number" && Number.isInteger(value.length) && value.length >= 0;
|
|
14296
|
+
}
|
|
14297
|
+
function getOpenRouterCallModelRequestArg(args) {
|
|
14298
|
+
const normalizedArgs = normalizeArgs(args);
|
|
14299
|
+
const keyedRequestArg = normalizedArgs.find(
|
|
14300
|
+
(arg) => isObject(arg) && ("input" in arg || "model" in arg || "tools" in arg)
|
|
14301
|
+
);
|
|
14302
|
+
if (isObject(keyedRequestArg)) {
|
|
14303
|
+
return keyedRequestArg;
|
|
14304
|
+
}
|
|
14305
|
+
const firstObjectArg = normalizedArgs.find((arg) => isObject(arg));
|
|
14306
|
+
return isObject(firstObjectArg) ? firstObjectArg : void 0;
|
|
14307
|
+
}
|
|
14308
|
+
var TOKEN_NAME_MAP2 = {
|
|
14309
|
+
promptTokens: "prompt_tokens",
|
|
14310
|
+
inputTokens: "prompt_tokens",
|
|
14311
|
+
completionTokens: "completion_tokens",
|
|
14312
|
+
outputTokens: "completion_tokens",
|
|
14313
|
+
totalTokens: "tokens",
|
|
14314
|
+
prompt_tokens: "prompt_tokens",
|
|
14315
|
+
input_tokens: "prompt_tokens",
|
|
14316
|
+
completion_tokens: "completion_tokens",
|
|
14317
|
+
output_tokens: "completion_tokens",
|
|
14318
|
+
total_tokens: "tokens"
|
|
14319
|
+
};
|
|
14320
|
+
var TOKEN_DETAIL_PREFIX_MAP = {
|
|
14321
|
+
promptTokensDetails: "prompt",
|
|
14322
|
+
inputTokensDetails: "prompt",
|
|
13000
14323
|
completionTokensDetails: "completion",
|
|
13001
14324
|
outputTokensDetails: "completion",
|
|
13002
14325
|
costDetails: "cost",
|
|
@@ -13047,8 +14370,6 @@ function extractOpenRouterUsageMetadata(usage) {
|
|
|
13047
14370
|
}
|
|
13048
14371
|
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
13049
14372
|
}
|
|
13050
|
-
|
|
13051
|
-
// src/openrouter-logging.ts
|
|
13052
14373
|
var OMITTED_OPENROUTER_KEYS = /* @__PURE__ */ new Set([
|
|
13053
14374
|
"execute",
|
|
13054
14375
|
"render",
|
|
@@ -13068,10 +14389,10 @@ function parseOpenRouterModelString(model) {
|
|
|
13068
14389
|
}
|
|
13069
14390
|
return { model };
|
|
13070
14391
|
}
|
|
13071
|
-
function
|
|
14392
|
+
function isZodSchema3(value) {
|
|
13072
14393
|
return value != null && typeof value === "object" && "_def" in value && typeof value._def === "object";
|
|
13073
14394
|
}
|
|
13074
|
-
function
|
|
14395
|
+
function serializeZodSchema3(schema) {
|
|
13075
14396
|
try {
|
|
13076
14397
|
return zodToJsonSchema(schema);
|
|
13077
14398
|
} catch {
|
|
@@ -13105,8 +14426,8 @@ function serializeOpenRouterToolsForLogging(tools) {
|
|
|
13105
14426
|
return tools.map((tool) => serializeOpenRouterTool(tool));
|
|
13106
14427
|
}
|
|
13107
14428
|
function sanitizeOpenRouterLoggedValue(value) {
|
|
13108
|
-
if (
|
|
13109
|
-
return
|
|
14429
|
+
if (isZodSchema3(value)) {
|
|
14430
|
+
return serializeZodSchema3(value);
|
|
13110
14431
|
}
|
|
13111
14432
|
if (typeof value === "function") {
|
|
13112
14433
|
return "[Function]";
|
|
@@ -13130,7 +14451,7 @@ function sanitizeOpenRouterLoggedValue(value) {
|
|
|
13130
14451
|
}
|
|
13131
14452
|
return sanitized;
|
|
13132
14453
|
}
|
|
13133
|
-
function buildOpenRouterMetadata(metadata, httpReferer, xTitle) {
|
|
14454
|
+
function buildOpenRouterMetadata(metadata, httpReferer, appTitle, appCategories, xTitle) {
|
|
13134
14455
|
const sanitized = sanitizeOpenRouterLoggedValue(metadata);
|
|
13135
14456
|
const metadataRecord = isObject(sanitized) ? sanitized : {};
|
|
13136
14457
|
const { model, provider: providerRouting, ...rest } = metadataRecord;
|
|
@@ -13140,17 +14461,12 @@ function buildOpenRouterMetadata(metadata, httpReferer, xTitle) {
|
|
|
13140
14461
|
...normalizedModel.model !== void 0 ? { model: normalizedModel.model } : {},
|
|
13141
14462
|
...providerRouting !== void 0 ? { providerRouting } : {},
|
|
13142
14463
|
...httpReferer !== void 0 ? { httpReferer } : {},
|
|
14464
|
+
...appTitle !== void 0 ? { appTitle } : {},
|
|
14465
|
+
...appCategories !== void 0 ? { appCategories } : {},
|
|
13143
14466
|
...xTitle !== void 0 ? { xTitle } : {},
|
|
13144
14467
|
provider: normalizedModel.provider || "openrouter"
|
|
13145
14468
|
};
|
|
13146
14469
|
}
|
|
13147
|
-
function buildOpenRouterEmbeddingMetadata(metadata, httpReferer, xTitle) {
|
|
13148
|
-
const normalized = buildOpenRouterMetadata(metadata, httpReferer, xTitle);
|
|
13149
|
-
return typeof normalized.model === "string" ? {
|
|
13150
|
-
...normalized,
|
|
13151
|
-
embedding_model: normalized.model
|
|
13152
|
-
} : normalized;
|
|
13153
|
-
}
|
|
13154
14470
|
function extractOpenRouterCallModelInput(request) {
|
|
13155
14471
|
return isObject(request) && "input" in request ? sanitizeOpenRouterLoggedValue(request.input) : void 0;
|
|
13156
14472
|
}
|
|
@@ -13159,7 +14475,13 @@ function extractOpenRouterCallModelMetadata(request) {
|
|
|
13159
14475
|
return { provider: "openrouter" };
|
|
13160
14476
|
}
|
|
13161
14477
|
const { input: _input, ...metadata } = request;
|
|
13162
|
-
return buildOpenRouterMetadata(
|
|
14478
|
+
return buildOpenRouterMetadata(
|
|
14479
|
+
metadata,
|
|
14480
|
+
void 0,
|
|
14481
|
+
void 0,
|
|
14482
|
+
void 0,
|
|
14483
|
+
void 0
|
|
14484
|
+
);
|
|
13163
14485
|
}
|
|
13164
14486
|
function extractOpenRouterResponseMetadata(result) {
|
|
13165
14487
|
if (!isObject(result)) {
|
|
@@ -13189,9 +14511,101 @@ function extractOpenRouterResponseOutput(response, fallbackOutput) {
|
|
|
13189
14511
|
}
|
|
13190
14512
|
return void 0;
|
|
13191
14513
|
}
|
|
13192
|
-
|
|
13193
|
-
// src/openrouter-tool-wrapping.ts
|
|
13194
14514
|
var OPENROUTER_WRAPPED_TOOL = Symbol("braintrust.openrouter.wrappedTool");
|
|
14515
|
+
function patchOpenRouterCallModelRequestTools(request) {
|
|
14516
|
+
if (!Array.isArray(request.tools) || request.tools.length === 0) {
|
|
14517
|
+
return void 0;
|
|
14518
|
+
}
|
|
14519
|
+
const originalTools = request.tools;
|
|
14520
|
+
const wrappedTools = originalTools.map((tool) => wrapOpenRouterTool(tool));
|
|
14521
|
+
const didPatch = wrappedTools.some(
|
|
14522
|
+
(tool, index) => tool !== originalTools[index]
|
|
14523
|
+
);
|
|
14524
|
+
if (!didPatch) {
|
|
14525
|
+
return void 0;
|
|
14526
|
+
}
|
|
14527
|
+
request.tools = wrappedTools;
|
|
14528
|
+
return () => {
|
|
14529
|
+
request.tools = originalTools;
|
|
14530
|
+
};
|
|
14531
|
+
}
|
|
14532
|
+
function wrapOpenRouterTool(tool) {
|
|
14533
|
+
if (isWrappedTool(tool) || !tool.function || typeof tool.function !== "object" || typeof tool.function.execute !== "function") {
|
|
14534
|
+
return tool;
|
|
14535
|
+
}
|
|
14536
|
+
const toolName = tool.function.name || "tool";
|
|
14537
|
+
const originalExecute = tool.function.execute;
|
|
14538
|
+
const wrappedTool = {
|
|
14539
|
+
...tool,
|
|
14540
|
+
function: {
|
|
14541
|
+
...tool.function,
|
|
14542
|
+
execute(...args) {
|
|
14543
|
+
return traceToolExecution({
|
|
14544
|
+
args,
|
|
14545
|
+
execute: () => Reflect.apply(originalExecute, this, args),
|
|
14546
|
+
toolCallId: getToolCallId(args[1]),
|
|
14547
|
+
toolName
|
|
14548
|
+
});
|
|
14549
|
+
}
|
|
14550
|
+
}
|
|
14551
|
+
};
|
|
14552
|
+
Object.defineProperty(wrappedTool, OPENROUTER_WRAPPED_TOOL, {
|
|
14553
|
+
value: true,
|
|
14554
|
+
enumerable: false,
|
|
14555
|
+
configurable: false
|
|
14556
|
+
});
|
|
14557
|
+
return wrappedTool;
|
|
14558
|
+
}
|
|
14559
|
+
function isWrappedTool(tool) {
|
|
14560
|
+
return Boolean(tool[OPENROUTER_WRAPPED_TOOL]);
|
|
14561
|
+
}
|
|
14562
|
+
function traceToolExecution(args) {
|
|
14563
|
+
const tracingChannel2 = openRouterAgentChannels.toolExecute.tracingChannel();
|
|
14564
|
+
const input = args.args.length > 0 ? args.args[0] : void 0;
|
|
14565
|
+
const event = {
|
|
14566
|
+
arguments: [input],
|
|
14567
|
+
span_info: {
|
|
14568
|
+
name: args.toolName
|
|
14569
|
+
},
|
|
14570
|
+
toolCallId: args.toolCallId,
|
|
14571
|
+
toolName: args.toolName
|
|
14572
|
+
};
|
|
14573
|
+
tracingChannel2.start.publish(event);
|
|
14574
|
+
try {
|
|
14575
|
+
const result = args.execute();
|
|
14576
|
+
return publishToolResult(tracingChannel2, event, result);
|
|
14577
|
+
} catch (error) {
|
|
14578
|
+
event.error = normalizeError(error);
|
|
14579
|
+
tracingChannel2.error.publish(event);
|
|
14580
|
+
throw error;
|
|
14581
|
+
}
|
|
14582
|
+
}
|
|
14583
|
+
function publishToolResult(tracingChannel2, event, result) {
|
|
14584
|
+
if (isPromiseLike3(result)) {
|
|
14585
|
+
return result.then(
|
|
14586
|
+
(resolved) => {
|
|
14587
|
+
event.result = resolved;
|
|
14588
|
+
tracingChannel2.asyncEnd.publish(event);
|
|
14589
|
+
return resolved;
|
|
14590
|
+
},
|
|
14591
|
+
(error) => {
|
|
14592
|
+
event.error = normalizeError(error);
|
|
14593
|
+
tracingChannel2.error.publish(event);
|
|
14594
|
+
throw error;
|
|
14595
|
+
}
|
|
14596
|
+
);
|
|
14597
|
+
}
|
|
14598
|
+
event.result = result;
|
|
14599
|
+
tracingChannel2.asyncEnd.publish(event);
|
|
14600
|
+
return result;
|
|
14601
|
+
}
|
|
14602
|
+
function getToolCallId(context) {
|
|
14603
|
+
const toolContext = context;
|
|
14604
|
+
return typeof toolContext?.toolCall?.id === "string" ? toolContext.toolCall.id : void 0;
|
|
14605
|
+
}
|
|
14606
|
+
function isPromiseLike3(value) {
|
|
14607
|
+
return !!value && (typeof value === "object" || typeof value === "function") && "then" in value && typeof value.then === "function";
|
|
14608
|
+
}
|
|
13195
14609
|
var OPENROUTER_WRAPPED_CALL_MODEL_RESULT = Symbol(
|
|
13196
14610
|
"braintrust.openrouter.wrappedCallModelResult"
|
|
13197
14611
|
);
|
|
@@ -13211,24 +14625,8 @@ var OPENROUTER_CALL_MODEL_CONTEXT_METHODS = [
|
|
|
13211
14625
|
"getToolCalls",
|
|
13212
14626
|
"requiresApproval"
|
|
13213
14627
|
];
|
|
13214
|
-
function
|
|
13215
|
-
|
|
13216
|
-
return void 0;
|
|
13217
|
-
}
|
|
13218
|
-
const originalTools = request.tools;
|
|
13219
|
-
const wrappedTools = originalTools.map((tool) => wrapOpenRouterTool(tool));
|
|
13220
|
-
const didPatch = wrappedTools.some(
|
|
13221
|
-
(tool, index) => tool !== originalTools[index]
|
|
13222
|
-
);
|
|
13223
|
-
if (!didPatch) {
|
|
13224
|
-
return void 0;
|
|
13225
|
-
}
|
|
13226
|
-
request.tools = wrappedTools;
|
|
13227
|
-
return () => {
|
|
13228
|
-
request.tools = originalTools;
|
|
13229
|
-
};
|
|
13230
|
-
}
|
|
13231
|
-
function patchOpenRouterCallModelResult(span, result, request) {
|
|
14628
|
+
function patchOpenRouterCallModelResult(args) {
|
|
14629
|
+
const { request, result, span } = args;
|
|
13232
14630
|
if (!isObject(result) || isWrappedCallModelResult(result)) {
|
|
13233
14631
|
return false;
|
|
13234
14632
|
}
|
|
@@ -13301,10 +14699,10 @@ function patchOpenRouterCallModelResult(span, result, request) {
|
|
|
13301
14699
|
}
|
|
13302
14700
|
};
|
|
13303
14701
|
if (originalGetResponse) {
|
|
13304
|
-
resultLike.getResponse = async (...
|
|
14702
|
+
resultLike.getResponse = async (...args2) => {
|
|
13305
14703
|
return await withCurrent(span, async () => {
|
|
13306
14704
|
try {
|
|
13307
|
-
const response = await originalGetResponse(...
|
|
14705
|
+
const response = await originalGetResponse(...args2);
|
|
13308
14706
|
await endSpanWithResult(response);
|
|
13309
14707
|
return response;
|
|
13310
14708
|
} catch (error) {
|
|
@@ -13316,10 +14714,10 @@ function patchOpenRouterCallModelResult(span, result, request) {
|
|
|
13316
14714
|
}
|
|
13317
14715
|
if (typeof resultLike.getText === "function") {
|
|
13318
14716
|
const originalGetText = resultLike.getText.bind(resultLike);
|
|
13319
|
-
resultLike.getText = async (...
|
|
14717
|
+
resultLike.getText = async (...args2) => {
|
|
13320
14718
|
return await withCurrent(span, async () => {
|
|
13321
14719
|
try {
|
|
13322
|
-
const text = await originalGetText(...
|
|
14720
|
+
const text = await originalGetText(...args2);
|
|
13323
14721
|
await finalizeFromResponse(text);
|
|
13324
14722
|
return text;
|
|
13325
14723
|
} catch (error) {
|
|
@@ -13334,9 +14732,9 @@ function patchOpenRouterCallModelResult(span, result, request) {
|
|
|
13334
14732
|
continue;
|
|
13335
14733
|
}
|
|
13336
14734
|
const originalMethod = resultLike[methodName];
|
|
13337
|
-
resultLike[methodName] = async (...
|
|
14735
|
+
resultLike[methodName] = async (...args2) => {
|
|
13338
14736
|
return await withCurrent(span, async () => {
|
|
13339
|
-
return await originalMethod.apply(resultLike,
|
|
14737
|
+
return await originalMethod.apply(resultLike, args2);
|
|
13340
14738
|
});
|
|
13341
14739
|
};
|
|
13342
14740
|
}
|
|
@@ -13345,12 +14743,12 @@ function patchOpenRouterCallModelResult(span, result, request) {
|
|
|
13345
14743
|
continue;
|
|
13346
14744
|
}
|
|
13347
14745
|
const originalMethod = resultLike[methodName];
|
|
13348
|
-
resultLike[methodName] = (...
|
|
14746
|
+
resultLike[methodName] = (...args2) => {
|
|
13349
14747
|
const stream = withCurrent(
|
|
13350
14748
|
span,
|
|
13351
|
-
() => originalMethod.apply(resultLike,
|
|
14749
|
+
() => originalMethod.apply(resultLike, args2)
|
|
13352
14750
|
);
|
|
13353
|
-
if (!
|
|
14751
|
+
if (!isAsyncIterable3(stream)) {
|
|
13354
14752
|
return stream;
|
|
13355
14753
|
}
|
|
13356
14754
|
return wrapAsyncIterableWithSpan({
|
|
@@ -13363,157 +14761,70 @@ function patchOpenRouterCallModelResult(span, result, request) {
|
|
|
13363
14761
|
}
|
|
13364
14762
|
if (originalGetInitialResponse) {
|
|
13365
14763
|
let initialTurnTraced = false;
|
|
13366
|
-
resultLike.getInitialResponse = async (...
|
|
14764
|
+
resultLike.getInitialResponse = async (...args2) => {
|
|
13367
14765
|
if (initialTurnTraced) {
|
|
13368
14766
|
return await withCurrent(span, async () => {
|
|
13369
|
-
return await originalGetInitialResponse(...
|
|
14767
|
+
return await originalGetInitialResponse(...args2);
|
|
13370
14768
|
});
|
|
13371
14769
|
}
|
|
13372
14770
|
initialTurnTraced = true;
|
|
13373
|
-
const
|
|
13374
|
-
const
|
|
13375
|
-
|
|
13376
|
-
|
|
13377
|
-
|
|
13378
|
-
});
|
|
13379
|
-
return await withCurrent(childSpan, async () => {
|
|
13380
|
-
try {
|
|
13381
|
-
const response = await originalGetInitialResponse(...args);
|
|
14771
|
+
const step = tracedTurnCount + 1;
|
|
14772
|
+
const stepType = tracedTurnCount === 0 ? "initial" : "continue";
|
|
14773
|
+
const response = await traceOpenRouterCallModelTurn({
|
|
14774
|
+
fn: async () => {
|
|
14775
|
+
const nextResponse = await originalGetInitialResponse(...args2);
|
|
13382
14776
|
tracedTurnCount++;
|
|
13383
|
-
|
|
13384
|
-
|
|
13385
|
-
|
|
13386
|
-
|
|
13387
|
-
|
|
13388
|
-
|
|
13389
|
-
return response;
|
|
13390
|
-
} catch (error) {
|
|
13391
|
-
childSpan.log({
|
|
13392
|
-
error: normalizeError(error).message
|
|
13393
|
-
});
|
|
13394
|
-
childSpan.end();
|
|
13395
|
-
throw error;
|
|
13396
|
-
}
|
|
14777
|
+
return nextResponse;
|
|
14778
|
+
},
|
|
14779
|
+
parentSpan: span,
|
|
14780
|
+
request: getOpenRouterResolvedRequest(resultLike, request),
|
|
14781
|
+
step,
|
|
14782
|
+
stepType
|
|
13397
14783
|
});
|
|
14784
|
+
return response;
|
|
13398
14785
|
};
|
|
13399
14786
|
}
|
|
13400
14787
|
if (originalMakeFollowupRequest) {
|
|
13401
|
-
resultLike.makeFollowupRequest = async (...
|
|
13402
|
-
const currentResponse =
|
|
13403
|
-
const toolResults = Array.isArray(
|
|
13404
|
-
const
|
|
13405
|
-
const
|
|
13406
|
-
|
|
13407
|
-
|
|
13408
|
-
toolResults
|
|
13409
|
-
);
|
|
13410
|
-
const childSpan = startOpenRouterCallModelTurnSpan({
|
|
13411
|
-
request: followupRequest,
|
|
13412
|
-
step: tracedTurnCount + 1,
|
|
13413
|
-
stepType: "continue"
|
|
13414
|
-
});
|
|
13415
|
-
return await withCurrent(childSpan, async () => {
|
|
13416
|
-
try {
|
|
13417
|
-
const response = await originalMakeFollowupRequest(...args);
|
|
14788
|
+
resultLike.makeFollowupRequest = async (...args2) => {
|
|
14789
|
+
const currentResponse = args2[0];
|
|
14790
|
+
const toolResults = Array.isArray(args2[1]) ? args2[1] : [];
|
|
14791
|
+
const step = tracedTurnCount + 1;
|
|
14792
|
+
const response = await traceOpenRouterCallModelTurn({
|
|
14793
|
+
fn: async () => {
|
|
14794
|
+
const nextResponse = await originalMakeFollowupRequest(...args2);
|
|
13418
14795
|
tracedTurnCount++;
|
|
13419
|
-
|
|
13420
|
-
|
|
13421
|
-
|
|
13422
|
-
|
|
13423
|
-
|
|
13424
|
-
|
|
13425
|
-
|
|
13426
|
-
|
|
13427
|
-
|
|
13428
|
-
|
|
13429
|
-
});
|
|
13430
|
-
childSpan.end();
|
|
13431
|
-
throw error;
|
|
13432
|
-
}
|
|
14796
|
+
return nextResponse;
|
|
14797
|
+
},
|
|
14798
|
+
parentSpan: span,
|
|
14799
|
+
request: buildOpenRouterFollowupRequest(
|
|
14800
|
+
getOpenRouterResolvedRequest(resultLike, request),
|
|
14801
|
+
currentResponse,
|
|
14802
|
+
toolResults
|
|
14803
|
+
),
|
|
14804
|
+
step,
|
|
14805
|
+
stepType: "continue"
|
|
13433
14806
|
});
|
|
14807
|
+
return response;
|
|
13434
14808
|
};
|
|
13435
14809
|
}
|
|
13436
14810
|
return true;
|
|
13437
14811
|
}
|
|
13438
|
-
function
|
|
13439
|
-
|
|
13440
|
-
|
|
13441
|
-
|
|
13442
|
-
|
|
13443
|
-
const originalExecute = tool.function.execute;
|
|
13444
|
-
const wrappedTool = {
|
|
13445
|
-
...tool,
|
|
13446
|
-
function: {
|
|
13447
|
-
...tool.function,
|
|
13448
|
-
execute(...args) {
|
|
13449
|
-
return traceToolExecution({
|
|
13450
|
-
args,
|
|
13451
|
-
execute: () => Reflect.apply(originalExecute, this, args),
|
|
13452
|
-
toolCallId: getToolCallId(args[1]),
|
|
13453
|
-
toolName
|
|
13454
|
-
});
|
|
13455
|
-
}
|
|
13456
|
-
}
|
|
14812
|
+
async function traceOpenRouterCallModelTurn(args) {
|
|
14813
|
+
const context = {
|
|
14814
|
+
arguments: [args.request],
|
|
14815
|
+
step: args.step,
|
|
14816
|
+
stepType: args.stepType
|
|
13457
14817
|
};
|
|
13458
|
-
|
|
13459
|
-
|
|
13460
|
-
|
|
13461
|
-
|
|
13462
|
-
});
|
|
13463
|
-
return wrappedTool;
|
|
13464
|
-
}
|
|
13465
|
-
function isWrappedTool(tool) {
|
|
13466
|
-
return Boolean(tool[OPENROUTER_WRAPPED_TOOL]);
|
|
14818
|
+
return await withCurrent(
|
|
14819
|
+
args.parentSpan,
|
|
14820
|
+
() => openRouterAgentChannels.callModelTurn.tracePromise(args.fn, context)
|
|
14821
|
+
);
|
|
13467
14822
|
}
|
|
13468
14823
|
function isWrappedCallModelResult(value) {
|
|
13469
14824
|
return Boolean(
|
|
13470
14825
|
isObject(value) && value[OPENROUTER_WRAPPED_CALL_MODEL_RESULT]
|
|
13471
14826
|
);
|
|
13472
14827
|
}
|
|
13473
|
-
function traceToolExecution(args) {
|
|
13474
|
-
const tracingChannel2 = openRouterChannels.toolExecute.tracingChannel();
|
|
13475
|
-
const input = args.args.length > 0 ? args.args[0] : void 0;
|
|
13476
|
-
const event = {
|
|
13477
|
-
arguments: [input],
|
|
13478
|
-
span_info: {
|
|
13479
|
-
name: args.toolName
|
|
13480
|
-
},
|
|
13481
|
-
toolCallId: args.toolCallId,
|
|
13482
|
-
toolName: args.toolName
|
|
13483
|
-
};
|
|
13484
|
-
tracingChannel2.start.publish(event);
|
|
13485
|
-
try {
|
|
13486
|
-
const result = args.execute();
|
|
13487
|
-
return publishToolResult(tracingChannel2, event, result);
|
|
13488
|
-
} catch (error) {
|
|
13489
|
-
event.error = normalizeError(error);
|
|
13490
|
-
tracingChannel2.error.publish(event);
|
|
13491
|
-
throw error;
|
|
13492
|
-
}
|
|
13493
|
-
}
|
|
13494
|
-
function publishToolResult(tracingChannel2, event, result) {
|
|
13495
|
-
if (isPromiseLike(result)) {
|
|
13496
|
-
return result.then(
|
|
13497
|
-
(resolved) => {
|
|
13498
|
-
event.result = resolved;
|
|
13499
|
-
tracingChannel2.asyncEnd.publish(event);
|
|
13500
|
-
return resolved;
|
|
13501
|
-
},
|
|
13502
|
-
(error) => {
|
|
13503
|
-
event.error = normalizeError(error);
|
|
13504
|
-
tracingChannel2.error.publish(event);
|
|
13505
|
-
throw error;
|
|
13506
|
-
}
|
|
13507
|
-
);
|
|
13508
|
-
}
|
|
13509
|
-
event.result = result;
|
|
13510
|
-
tracingChannel2.asyncEnd.publish(event);
|
|
13511
|
-
return result;
|
|
13512
|
-
}
|
|
13513
|
-
function getToolCallId(context) {
|
|
13514
|
-
const toolContext = context;
|
|
13515
|
-
return typeof toolContext?.toolCall?.id === "string" ? toolContext.toolCall.id : void 0;
|
|
13516
|
-
}
|
|
13517
14828
|
function extractOpenRouterCallModelResultMetadata(response, turnCount) {
|
|
13518
14829
|
const combined = {
|
|
13519
14830
|
...extractOpenRouterResponseMetadata(response) || {},
|
|
@@ -13558,45 +14869,6 @@ function buildNextOpenRouterCallModelInput(currentInput, response, toolResults)
|
|
|
13558
14869
|
(entry) => sanitizeOpenRouterLoggedValue(entry)
|
|
13559
14870
|
);
|
|
13560
14871
|
}
|
|
13561
|
-
function startOpenRouterCallModelTurnSpan(args) {
|
|
13562
|
-
const requestRecord = isObject(args.request) ? args.request : void 0;
|
|
13563
|
-
const metadata = requestRecord ? extractOpenRouterCallModelMetadata(requestRecord) : { provider: "openrouter" };
|
|
13564
|
-
if (isObject(metadata) && "tools" in metadata) {
|
|
13565
|
-
delete metadata.tools;
|
|
13566
|
-
}
|
|
13567
|
-
return startSpan({
|
|
13568
|
-
name: "openrouter.beta.responses.send",
|
|
13569
|
-
spanAttributes: {
|
|
13570
|
-
type: "llm" /* LLM */
|
|
13571
|
-
},
|
|
13572
|
-
event: {
|
|
13573
|
-
input: requestRecord ? extractOpenRouterCallModelInput(requestRecord) : void 0,
|
|
13574
|
-
metadata: {
|
|
13575
|
-
...metadata,
|
|
13576
|
-
step: args.step,
|
|
13577
|
-
step_type: args.stepType
|
|
13578
|
-
}
|
|
13579
|
-
}
|
|
13580
|
-
});
|
|
13581
|
-
}
|
|
13582
|
-
function finishOpenRouterCallModelTurnSpan(args) {
|
|
13583
|
-
if (!isObject(args.response)) {
|
|
13584
|
-
args.span.end();
|
|
13585
|
-
return;
|
|
13586
|
-
}
|
|
13587
|
-
args.span.log({
|
|
13588
|
-
output: extractOpenRouterResponseOutput(args.response),
|
|
13589
|
-
...extractOpenRouterResponseMetadata(args.response) ? {
|
|
13590
|
-
metadata: {
|
|
13591
|
-
...extractOpenRouterResponseMetadata(args.response),
|
|
13592
|
-
...args.step !== void 0 ? { step: args.step } : {},
|
|
13593
|
-
...args.stepType ? { step_type: args.stepType } : {}
|
|
13594
|
-
}
|
|
13595
|
-
} : {},
|
|
13596
|
-
metrics: parseOpenRouterMetricsFromUsage(args.response.usage)
|
|
13597
|
-
});
|
|
13598
|
-
args.span.end();
|
|
13599
|
-
}
|
|
13600
14872
|
function getOpenRouterResolvedRequest(result, request) {
|
|
13601
14873
|
if (isObject(result.resolvedRequest)) {
|
|
13602
14874
|
return result.resolvedRequest;
|
|
@@ -13671,16 +14943,41 @@ function wrapAsyncIterableWithSpan(args) {
|
|
|
13671
14943
|
}
|
|
13672
14944
|
};
|
|
13673
14945
|
}
|
|
13674
|
-
function
|
|
14946
|
+
function isAsyncIterable3(value) {
|
|
13675
14947
|
return !!value && (typeof value === "object" || typeof value === "function") && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
13676
14948
|
}
|
|
13677
|
-
function isPromiseLike(value) {
|
|
13678
|
-
return !!value && (typeof value === "object" || typeof value === "function") && "then" in value && typeof value.then === "function";
|
|
13679
|
-
}
|
|
13680
14949
|
function normalizeError(error) {
|
|
13681
14950
|
return error instanceof Error ? error : new Error(String(error));
|
|
13682
14951
|
}
|
|
13683
14952
|
|
|
14953
|
+
// src/instrumentation/plugins/openrouter-channels.ts
|
|
14954
|
+
var openRouterChannels = defineChannels("@openrouter/sdk", {
|
|
14955
|
+
chatSend: channel({
|
|
14956
|
+
channelName: "chat.send",
|
|
14957
|
+
kind: "async"
|
|
14958
|
+
}),
|
|
14959
|
+
embeddingsGenerate: channel({
|
|
14960
|
+
channelName: "embeddings.generate",
|
|
14961
|
+
kind: "async"
|
|
14962
|
+
}),
|
|
14963
|
+
betaResponsesSend: channel({
|
|
14964
|
+
channelName: "beta.responses.send",
|
|
14965
|
+
kind: "async"
|
|
14966
|
+
}),
|
|
14967
|
+
callModel: channel({
|
|
14968
|
+
channelName: "callModel",
|
|
14969
|
+
kind: "sync-stream"
|
|
14970
|
+
}),
|
|
14971
|
+
callModelTurn: channel({
|
|
14972
|
+
channelName: "callModel.turn",
|
|
14973
|
+
kind: "async"
|
|
14974
|
+
}),
|
|
14975
|
+
toolExecute: channel({
|
|
14976
|
+
channelName: "tool.execute",
|
|
14977
|
+
kind: "async"
|
|
14978
|
+
})
|
|
14979
|
+
});
|
|
14980
|
+
|
|
13684
14981
|
// src/instrumentation/plugins/openrouter-plugin.ts
|
|
13685
14982
|
var OpenRouterPlugin = class extends BasePlugin {
|
|
13686
14983
|
onEnable() {
|
|
@@ -13702,14 +14999,14 @@ var OpenRouterPlugin = class extends BasePlugin {
|
|
|
13702
14999
|
const { messages, ...metadata } = chatGenerationParams;
|
|
13703
15000
|
return {
|
|
13704
15001
|
input: messages,
|
|
13705
|
-
metadata:
|
|
15002
|
+
metadata: buildOpenRouterMetadata2(metadata, httpReferer, xTitle)
|
|
13706
15003
|
};
|
|
13707
15004
|
},
|
|
13708
15005
|
extractOutput: (result) => {
|
|
13709
15006
|
return isObject(result) ? result.choices : void 0;
|
|
13710
15007
|
},
|
|
13711
15008
|
extractMetrics: (result, startTime) => {
|
|
13712
|
-
const metrics =
|
|
15009
|
+
const metrics = parseOpenRouterMetricsFromUsage2(result?.usage);
|
|
13713
15010
|
if (startTime) {
|
|
13714
15011
|
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
13715
15012
|
}
|
|
@@ -13748,10 +15045,10 @@ var OpenRouterPlugin = class extends BasePlugin {
|
|
|
13748
15045
|
if (!isObject(result)) {
|
|
13749
15046
|
return void 0;
|
|
13750
15047
|
}
|
|
13751
|
-
return
|
|
15048
|
+
return extractOpenRouterResponseMetadata2(result);
|
|
13752
15049
|
},
|
|
13753
15050
|
extractMetrics: (result) => {
|
|
13754
|
-
return isObject(result) ?
|
|
15051
|
+
return isObject(result) ? parseOpenRouterMetricsFromUsage2(result.usage) : {};
|
|
13755
15052
|
}
|
|
13756
15053
|
})
|
|
13757
15054
|
);
|
|
@@ -13767,13 +15064,13 @@ var OpenRouterPlugin = class extends BasePlugin {
|
|
|
13767
15064
|
const { input, ...metadata } = openResponsesRequest;
|
|
13768
15065
|
return {
|
|
13769
15066
|
input,
|
|
13770
|
-
metadata:
|
|
15067
|
+
metadata: buildOpenRouterMetadata2(metadata, httpReferer, xTitle)
|
|
13771
15068
|
};
|
|
13772
15069
|
},
|
|
13773
|
-
extractOutput: (result) =>
|
|
13774
|
-
extractMetadata: (result) =>
|
|
15070
|
+
extractOutput: (result) => extractOpenRouterResponseOutput2(result),
|
|
15071
|
+
extractMetadata: (result) => extractOpenRouterResponseMetadata2(result),
|
|
13775
15072
|
extractMetrics: (result, startTime) => {
|
|
13776
|
-
const metrics =
|
|
15073
|
+
const metrics = parseOpenRouterMetricsFromUsage2(result?.usage);
|
|
13777
15074
|
if (startTime) {
|
|
13778
15075
|
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
13779
15076
|
}
|
|
@@ -13787,21 +15084,57 @@ var OpenRouterPlugin = class extends BasePlugin {
|
|
|
13787
15084
|
name: "openrouter.callModel",
|
|
13788
15085
|
type: "llm" /* LLM */,
|
|
13789
15086
|
extractInput: (args) => {
|
|
13790
|
-
const request =
|
|
15087
|
+
const request = getOpenRouterCallModelRequestArg2(args);
|
|
13791
15088
|
return {
|
|
13792
|
-
input: request ?
|
|
13793
|
-
metadata: request ?
|
|
15089
|
+
input: request ? extractOpenRouterCallModelInput2(request) : void 0,
|
|
15090
|
+
metadata: request ? extractOpenRouterCallModelMetadata2(request) : { provider: "openrouter" }
|
|
13794
15091
|
};
|
|
13795
15092
|
},
|
|
13796
15093
|
patchResult: ({ endEvent, result, span }) => {
|
|
13797
|
-
return
|
|
13798
|
-
|
|
15094
|
+
return patchOpenRouterCallModelResult2({
|
|
15095
|
+
request: getOpenRouterCallModelRequestArg2(endEvent.arguments),
|
|
13799
15096
|
result,
|
|
13800
|
-
|
|
13801
|
-
);
|
|
15097
|
+
span
|
|
15098
|
+
});
|
|
13802
15099
|
}
|
|
13803
15100
|
})
|
|
13804
15101
|
);
|
|
15102
|
+
this.unsubscribers.push(
|
|
15103
|
+
traceAsyncChannel(openRouterChannels.callModelTurn, {
|
|
15104
|
+
name: "openrouter.beta.responses.send",
|
|
15105
|
+
type: "llm" /* LLM */,
|
|
15106
|
+
extractInput: (args, event) => {
|
|
15107
|
+
const request = getOpenRouterCallModelRequestArg2(args);
|
|
15108
|
+
const metadata = request ? extractOpenRouterCallModelMetadata2(request) : { provider: "openrouter" };
|
|
15109
|
+
if (isObject(metadata) && "tools" in metadata) {
|
|
15110
|
+
delete metadata.tools;
|
|
15111
|
+
}
|
|
15112
|
+
return {
|
|
15113
|
+
input: request ? extractOpenRouterCallModelInput2(request) : void 0,
|
|
15114
|
+
metadata: {
|
|
15115
|
+
...metadata,
|
|
15116
|
+
step: event.step,
|
|
15117
|
+
step_type: event.stepType
|
|
15118
|
+
}
|
|
15119
|
+
};
|
|
15120
|
+
},
|
|
15121
|
+
extractOutput: (result) => extractOpenRouterResponseOutput2(result),
|
|
15122
|
+
extractMetadata: (result, event) => {
|
|
15123
|
+
if (!isObject(result)) {
|
|
15124
|
+
return {
|
|
15125
|
+
step: event?.step,
|
|
15126
|
+
step_type: event?.stepType
|
|
15127
|
+
};
|
|
15128
|
+
}
|
|
15129
|
+
return {
|
|
15130
|
+
...extractOpenRouterResponseMetadata2(result) || {},
|
|
15131
|
+
...event?.step !== void 0 ? { step: event.step } : {},
|
|
15132
|
+
...event?.stepType ? { step_type: event.stepType } : {}
|
|
15133
|
+
};
|
|
15134
|
+
},
|
|
15135
|
+
extractMetrics: (result) => isObject(result) ? parseOpenRouterMetricsFromUsage2(result.usage) : {}
|
|
15136
|
+
})
|
|
15137
|
+
);
|
|
13805
15138
|
this.unsubscribers.push(
|
|
13806
15139
|
traceStreamingChannel(openRouterChannels.toolExecute, {
|
|
13807
15140
|
name: "openrouter.tool",
|
|
@@ -13822,155 +15155,1303 @@ var OpenRouterPlugin = class extends BasePlugin {
|
|
|
13822
15155
|
})
|
|
13823
15156
|
})
|
|
13824
15157
|
);
|
|
13825
|
-
const callModelChannel = openRouterChannels.callModel.tracingChannel();
|
|
13826
|
-
const callModelHandlers = {
|
|
13827
|
-
start: (event) => {
|
|
13828
|
-
const request =
|
|
13829
|
-
if (!request) {
|
|
13830
|
-
return;
|
|
13831
|
-
}
|
|
13832
|
-
|
|
13833
|
-
}
|
|
13834
|
-
};
|
|
13835
|
-
callModelChannel.subscribe(callModelHandlers);
|
|
13836
|
-
this.unsubscribers.push(() => {
|
|
13837
|
-
callModelChannel.unsubscribe(callModelHandlers);
|
|
13838
|
-
});
|
|
15158
|
+
const callModelChannel = openRouterChannels.callModel.tracingChannel();
|
|
15159
|
+
const callModelHandlers = {
|
|
15160
|
+
start: (event) => {
|
|
15161
|
+
const request = getOpenRouterCallModelRequestArg2(event.arguments);
|
|
15162
|
+
if (!request) {
|
|
15163
|
+
return;
|
|
15164
|
+
}
|
|
15165
|
+
patchOpenRouterCallModelRequestTools2(request);
|
|
15166
|
+
}
|
|
15167
|
+
};
|
|
15168
|
+
callModelChannel.subscribe(callModelHandlers);
|
|
15169
|
+
this.unsubscribers.push(() => {
|
|
15170
|
+
callModelChannel.unsubscribe(callModelHandlers);
|
|
15171
|
+
});
|
|
15172
|
+
}
|
|
15173
|
+
};
|
|
15174
|
+
function normalizeArgs2(args) {
|
|
15175
|
+
if (Array.isArray(args)) {
|
|
15176
|
+
return args;
|
|
15177
|
+
}
|
|
15178
|
+
if (isArrayLike2(args)) {
|
|
15179
|
+
return Array.from(args);
|
|
15180
|
+
}
|
|
15181
|
+
return [args];
|
|
15182
|
+
}
|
|
15183
|
+
function isArrayLike2(value) {
|
|
15184
|
+
return isObject(value) && "length" in value && typeof value.length === "number" && Number.isInteger(value.length) && value.length >= 0;
|
|
15185
|
+
}
|
|
15186
|
+
function getOpenRouterRequestArg(args) {
|
|
15187
|
+
const normalizedArgs = normalizeArgs2(args);
|
|
15188
|
+
const keyedCandidate = normalizedArgs.find(
|
|
15189
|
+
(arg) => isObject(arg) && ("chatGenerationParams" in arg || "requestBody" in arg || "openResponsesRequest" in arg)
|
|
15190
|
+
);
|
|
15191
|
+
if (isObject(keyedCandidate)) {
|
|
15192
|
+
return keyedCandidate;
|
|
15193
|
+
}
|
|
15194
|
+
const firstObjectArg = normalizedArgs.find((arg) => isObject(arg));
|
|
15195
|
+
return isObject(firstObjectArg) ? firstObjectArg : void 0;
|
|
15196
|
+
}
|
|
15197
|
+
function getOpenRouterCallModelRequestArg2(args) {
|
|
15198
|
+
const firstObjectArg = normalizeArgs2(args).find((arg) => isObject(arg));
|
|
15199
|
+
return isObject(firstObjectArg) ? firstObjectArg : void 0;
|
|
15200
|
+
}
|
|
15201
|
+
var TOKEN_NAME_MAP3 = {
|
|
15202
|
+
promptTokens: "prompt_tokens",
|
|
15203
|
+
inputTokens: "prompt_tokens",
|
|
15204
|
+
completionTokens: "completion_tokens",
|
|
15205
|
+
outputTokens: "completion_tokens",
|
|
15206
|
+
totalTokens: "tokens",
|
|
15207
|
+
prompt_tokens: "prompt_tokens",
|
|
15208
|
+
input_tokens: "prompt_tokens",
|
|
15209
|
+
completion_tokens: "completion_tokens",
|
|
15210
|
+
output_tokens: "completion_tokens",
|
|
15211
|
+
total_tokens: "tokens"
|
|
15212
|
+
};
|
|
15213
|
+
var TOKEN_DETAIL_PREFIX_MAP2 = {
|
|
15214
|
+
promptTokensDetails: "prompt",
|
|
15215
|
+
inputTokensDetails: "prompt",
|
|
15216
|
+
completionTokensDetails: "completion",
|
|
15217
|
+
outputTokensDetails: "completion",
|
|
15218
|
+
costDetails: "cost",
|
|
15219
|
+
prompt_tokens_details: "prompt",
|
|
15220
|
+
input_tokens_details: "prompt",
|
|
15221
|
+
completion_tokens_details: "completion",
|
|
15222
|
+
output_tokens_details: "completion",
|
|
15223
|
+
cost_details: "cost"
|
|
15224
|
+
};
|
|
15225
|
+
function camelToSnake2(value) {
|
|
15226
|
+
return value.replace(/[A-Z]/g, (match) => `_${match.toLowerCase()}`);
|
|
15227
|
+
}
|
|
15228
|
+
function parseOpenRouterMetricsFromUsage2(usage) {
|
|
15229
|
+
if (!isObject(usage)) {
|
|
15230
|
+
return {};
|
|
15231
|
+
}
|
|
15232
|
+
const metrics = {};
|
|
15233
|
+
for (const [name, value] of Object.entries(usage)) {
|
|
15234
|
+
if (typeof value === "number") {
|
|
15235
|
+
metrics[TOKEN_NAME_MAP3[name] || camelToSnake2(name)] = value;
|
|
15236
|
+
continue;
|
|
15237
|
+
}
|
|
15238
|
+
if (!isObject(value)) {
|
|
15239
|
+
continue;
|
|
15240
|
+
}
|
|
15241
|
+
const prefix = TOKEN_DETAIL_PREFIX_MAP2[name];
|
|
15242
|
+
if (!prefix) {
|
|
15243
|
+
continue;
|
|
15244
|
+
}
|
|
15245
|
+
for (const [nestedName, nestedValue] of Object.entries(value)) {
|
|
15246
|
+
if (typeof nestedValue !== "number") {
|
|
15247
|
+
continue;
|
|
15248
|
+
}
|
|
15249
|
+
metrics[`${prefix}_${camelToSnake2(nestedName)}`] = nestedValue;
|
|
15250
|
+
}
|
|
15251
|
+
}
|
|
15252
|
+
return metrics;
|
|
15253
|
+
}
|
|
15254
|
+
function extractOpenRouterUsageMetadata2(usage) {
|
|
15255
|
+
if (!isObject(usage)) {
|
|
15256
|
+
return void 0;
|
|
15257
|
+
}
|
|
15258
|
+
const metadata = {};
|
|
15259
|
+
if (typeof usage.isByok === "boolean") {
|
|
15260
|
+
metadata.is_byok = usage.isByok;
|
|
15261
|
+
} else if (typeof usage.is_byok === "boolean") {
|
|
15262
|
+
metadata.is_byok = usage.is_byok;
|
|
15263
|
+
}
|
|
15264
|
+
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
15265
|
+
}
|
|
15266
|
+
var OMITTED_OPENROUTER_KEYS2 = /* @__PURE__ */ new Set([
|
|
15267
|
+
"execute",
|
|
15268
|
+
"render",
|
|
15269
|
+
"nextTurnParams",
|
|
15270
|
+
"requireApproval"
|
|
15271
|
+
]);
|
|
15272
|
+
function parseOpenRouterModelString2(model) {
|
|
15273
|
+
if (typeof model !== "string") {
|
|
15274
|
+
return { model };
|
|
15275
|
+
}
|
|
15276
|
+
const slashIndex = model.indexOf("/");
|
|
15277
|
+
if (slashIndex > 0 && slashIndex < model.length - 1) {
|
|
15278
|
+
return {
|
|
15279
|
+
provider: model.substring(0, slashIndex),
|
|
15280
|
+
model: model.substring(slashIndex + 1)
|
|
15281
|
+
};
|
|
15282
|
+
}
|
|
15283
|
+
return { model };
|
|
15284
|
+
}
|
|
15285
|
+
function isZodSchema4(value) {
|
|
15286
|
+
return value != null && typeof value === "object" && "_def" in value && typeof value._def === "object";
|
|
15287
|
+
}
|
|
15288
|
+
function serializeZodSchema4(schema) {
|
|
15289
|
+
try {
|
|
15290
|
+
return zodToJsonSchema(schema);
|
|
15291
|
+
} catch {
|
|
15292
|
+
return {
|
|
15293
|
+
type: "object",
|
|
15294
|
+
description: "Zod schema (conversion failed)"
|
|
15295
|
+
};
|
|
15296
|
+
}
|
|
15297
|
+
}
|
|
15298
|
+
function serializeOpenRouterTool2(tool) {
|
|
15299
|
+
if (!isObject(tool)) {
|
|
15300
|
+
return tool;
|
|
15301
|
+
}
|
|
15302
|
+
const serialized = {};
|
|
15303
|
+
for (const [key, value] of Object.entries(tool)) {
|
|
15304
|
+
if (OMITTED_OPENROUTER_KEYS2.has(key)) {
|
|
15305
|
+
continue;
|
|
15306
|
+
}
|
|
15307
|
+
if (key === "function" && isObject(value)) {
|
|
15308
|
+
serialized.function = sanitizeOpenRouterLoggedValue2(value);
|
|
15309
|
+
continue;
|
|
15310
|
+
}
|
|
15311
|
+
serialized[key] = sanitizeOpenRouterLoggedValue2(value);
|
|
15312
|
+
}
|
|
15313
|
+
return serialized;
|
|
15314
|
+
}
|
|
15315
|
+
function serializeOpenRouterToolsForLogging2(tools) {
|
|
15316
|
+
if (!Array.isArray(tools)) {
|
|
15317
|
+
return void 0;
|
|
15318
|
+
}
|
|
15319
|
+
return tools.map((tool) => serializeOpenRouterTool2(tool));
|
|
15320
|
+
}
|
|
15321
|
+
function sanitizeOpenRouterLoggedValue2(value) {
|
|
15322
|
+
if (isZodSchema4(value)) {
|
|
15323
|
+
return serializeZodSchema4(value);
|
|
15324
|
+
}
|
|
15325
|
+
if (typeof value === "function") {
|
|
15326
|
+
return "[Function]";
|
|
15327
|
+
}
|
|
15328
|
+
if (Array.isArray(value)) {
|
|
15329
|
+
return value.map((entry) => sanitizeOpenRouterLoggedValue2(entry));
|
|
15330
|
+
}
|
|
15331
|
+
if (!isObject(value)) {
|
|
15332
|
+
return value;
|
|
15333
|
+
}
|
|
15334
|
+
const sanitized = {};
|
|
15335
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
15336
|
+
if (OMITTED_OPENROUTER_KEYS2.has(key)) {
|
|
15337
|
+
continue;
|
|
15338
|
+
}
|
|
15339
|
+
if (key === "tools" && Array.isArray(entry)) {
|
|
15340
|
+
sanitized.tools = serializeOpenRouterToolsForLogging2(entry);
|
|
15341
|
+
continue;
|
|
15342
|
+
}
|
|
15343
|
+
sanitized[key] = sanitizeOpenRouterLoggedValue2(entry);
|
|
15344
|
+
}
|
|
15345
|
+
return sanitized;
|
|
15346
|
+
}
|
|
15347
|
+
function buildOpenRouterMetadata2(metadata, httpReferer, xTitle) {
|
|
15348
|
+
const sanitized = sanitizeOpenRouterLoggedValue2(metadata);
|
|
15349
|
+
const metadataRecord = isObject(sanitized) ? sanitized : {};
|
|
15350
|
+
const { model, provider: providerRouting, ...rest } = metadataRecord;
|
|
15351
|
+
const normalizedModel = parseOpenRouterModelString2(model);
|
|
15352
|
+
return {
|
|
15353
|
+
...rest,
|
|
15354
|
+
...normalizedModel.model !== void 0 ? { model: normalizedModel.model } : {},
|
|
15355
|
+
...providerRouting !== void 0 ? { providerRouting } : {},
|
|
15356
|
+
...httpReferer !== void 0 ? { httpReferer } : {},
|
|
15357
|
+
...xTitle !== void 0 ? { xTitle } : {},
|
|
15358
|
+
provider: normalizedModel.provider || "openrouter"
|
|
15359
|
+
};
|
|
15360
|
+
}
|
|
15361
|
+
function buildOpenRouterEmbeddingMetadata(metadata, httpReferer, xTitle) {
|
|
15362
|
+
const normalized = buildOpenRouterMetadata2(metadata, httpReferer, xTitle);
|
|
15363
|
+
return typeof normalized.model === "string" ? {
|
|
15364
|
+
...normalized,
|
|
15365
|
+
embedding_model: normalized.model
|
|
15366
|
+
} : normalized;
|
|
15367
|
+
}
|
|
15368
|
+
function extractOpenRouterCallModelInput2(request) {
|
|
15369
|
+
return isObject(request) && "input" in request ? sanitizeOpenRouterLoggedValue2(request.input) : void 0;
|
|
15370
|
+
}
|
|
15371
|
+
function extractOpenRouterCallModelMetadata2(request) {
|
|
15372
|
+
if (!isObject(request)) {
|
|
15373
|
+
return { provider: "openrouter" };
|
|
15374
|
+
}
|
|
15375
|
+
const { input: _input, ...metadata } = request;
|
|
15376
|
+
return buildOpenRouterMetadata2(metadata, void 0, void 0);
|
|
15377
|
+
}
|
|
15378
|
+
function extractOpenRouterResponseMetadata2(result) {
|
|
15379
|
+
if (!isObject(result)) {
|
|
15380
|
+
return void 0;
|
|
15381
|
+
}
|
|
15382
|
+
const { output: _output, data: _data, usage, ...metadata } = result;
|
|
15383
|
+
const sanitized = sanitizeOpenRouterLoggedValue2(metadata);
|
|
15384
|
+
const metadataRecord = isObject(sanitized) ? sanitized : {};
|
|
15385
|
+
const { model, provider, ...rest } = metadataRecord;
|
|
15386
|
+
const normalizedModel = parseOpenRouterModelString2(model);
|
|
15387
|
+
const normalizedProvider = (typeof provider === "string" ? provider : void 0) || normalizedModel.provider;
|
|
15388
|
+
const usageMetadata = extractOpenRouterUsageMetadata2(usage);
|
|
15389
|
+
const combined = {
|
|
15390
|
+
...rest,
|
|
15391
|
+
...normalizedModel.model !== void 0 ? { model: normalizedModel.model } : {},
|
|
15392
|
+
...usageMetadata || {},
|
|
15393
|
+
...normalizedProvider !== void 0 ? { provider: normalizedProvider } : {}
|
|
15394
|
+
};
|
|
15395
|
+
return Object.keys(combined).length > 0 ? combined : void 0;
|
|
15396
|
+
}
|
|
15397
|
+
function extractOpenRouterResponseOutput2(response, fallbackOutput) {
|
|
15398
|
+
if (isObject(response) && "output" in response && response.output !== void 0) {
|
|
15399
|
+
return sanitizeOpenRouterLoggedValue2(response.output);
|
|
15400
|
+
}
|
|
15401
|
+
if (fallbackOutput !== void 0) {
|
|
15402
|
+
return sanitizeOpenRouterLoggedValue2(fallbackOutput);
|
|
15403
|
+
}
|
|
15404
|
+
return void 0;
|
|
15405
|
+
}
|
|
15406
|
+
var OPENROUTER_WRAPPED_TOOL2 = Symbol("braintrust.openrouter.wrappedTool");
|
|
15407
|
+
function patchOpenRouterCallModelRequestTools2(request) {
|
|
15408
|
+
if (!Array.isArray(request.tools) || request.tools.length === 0) {
|
|
15409
|
+
return void 0;
|
|
15410
|
+
}
|
|
15411
|
+
const originalTools = request.tools;
|
|
15412
|
+
const wrappedTools = originalTools.map((tool) => wrapOpenRouterTool2(tool));
|
|
15413
|
+
const didPatch = wrappedTools.some(
|
|
15414
|
+
(tool, index) => tool !== originalTools[index]
|
|
15415
|
+
);
|
|
15416
|
+
if (!didPatch) {
|
|
15417
|
+
return void 0;
|
|
15418
|
+
}
|
|
15419
|
+
request.tools = wrappedTools;
|
|
15420
|
+
return () => {
|
|
15421
|
+
request.tools = originalTools;
|
|
15422
|
+
};
|
|
15423
|
+
}
|
|
15424
|
+
function wrapOpenRouterTool2(tool) {
|
|
15425
|
+
if (isWrappedTool2(tool) || !tool.function || typeof tool.function !== "object" || typeof tool.function.execute !== "function") {
|
|
15426
|
+
return tool;
|
|
15427
|
+
}
|
|
15428
|
+
const toolName = tool.function.name || "tool";
|
|
15429
|
+
const originalExecute = tool.function.execute;
|
|
15430
|
+
const wrappedTool = {
|
|
15431
|
+
...tool,
|
|
15432
|
+
function: {
|
|
15433
|
+
...tool.function,
|
|
15434
|
+
execute(...args) {
|
|
15435
|
+
return traceToolExecution2({
|
|
15436
|
+
args,
|
|
15437
|
+
execute: () => Reflect.apply(originalExecute, this, args),
|
|
15438
|
+
toolCallId: getToolCallId2(args[1]),
|
|
15439
|
+
toolName
|
|
15440
|
+
});
|
|
15441
|
+
}
|
|
15442
|
+
}
|
|
15443
|
+
};
|
|
15444
|
+
Object.defineProperty(wrappedTool, OPENROUTER_WRAPPED_TOOL2, {
|
|
15445
|
+
value: true,
|
|
15446
|
+
enumerable: false,
|
|
15447
|
+
configurable: false
|
|
15448
|
+
});
|
|
15449
|
+
return wrappedTool;
|
|
15450
|
+
}
|
|
15451
|
+
function isWrappedTool2(tool) {
|
|
15452
|
+
return Boolean(tool[OPENROUTER_WRAPPED_TOOL2]);
|
|
15453
|
+
}
|
|
15454
|
+
function traceToolExecution2(args) {
|
|
15455
|
+
const tracingChannel2 = openRouterChannels.toolExecute.tracingChannel();
|
|
15456
|
+
const input = args.args.length > 0 ? args.args[0] : void 0;
|
|
15457
|
+
const event = {
|
|
15458
|
+
arguments: [input],
|
|
15459
|
+
span_info: {
|
|
15460
|
+
name: args.toolName
|
|
15461
|
+
},
|
|
15462
|
+
toolCallId: args.toolCallId,
|
|
15463
|
+
toolName: args.toolName
|
|
15464
|
+
};
|
|
15465
|
+
tracingChannel2.start.publish(event);
|
|
15466
|
+
try {
|
|
15467
|
+
const result = args.execute();
|
|
15468
|
+
return publishToolResult2(tracingChannel2, event, result);
|
|
15469
|
+
} catch (error) {
|
|
15470
|
+
event.error = normalizeError2(error);
|
|
15471
|
+
tracingChannel2.error.publish(event);
|
|
15472
|
+
throw error;
|
|
15473
|
+
}
|
|
15474
|
+
}
|
|
15475
|
+
function publishToolResult2(tracingChannel2, event, result) {
|
|
15476
|
+
if (isPromiseLike4(result)) {
|
|
15477
|
+
return result.then(
|
|
15478
|
+
(resolved) => {
|
|
15479
|
+
event.result = resolved;
|
|
15480
|
+
tracingChannel2.asyncEnd.publish(event);
|
|
15481
|
+
return resolved;
|
|
15482
|
+
},
|
|
15483
|
+
(error) => {
|
|
15484
|
+
event.error = normalizeError2(error);
|
|
15485
|
+
tracingChannel2.error.publish(event);
|
|
15486
|
+
throw error;
|
|
15487
|
+
}
|
|
15488
|
+
);
|
|
15489
|
+
}
|
|
15490
|
+
event.result = result;
|
|
15491
|
+
tracingChannel2.asyncEnd.publish(event);
|
|
15492
|
+
return result;
|
|
15493
|
+
}
|
|
15494
|
+
function getToolCallId2(context) {
|
|
15495
|
+
const toolContext = context;
|
|
15496
|
+
return typeof toolContext?.toolCall?.id === "string" ? toolContext.toolCall.id : void 0;
|
|
15497
|
+
}
|
|
15498
|
+
function isPromiseLike4(value) {
|
|
15499
|
+
return !!value && (typeof value === "object" || typeof value === "function") && "then" in value && typeof value.then === "function";
|
|
15500
|
+
}
|
|
15501
|
+
function aggregateOpenRouterChatChunks(chunks) {
|
|
15502
|
+
let role;
|
|
15503
|
+
let content = "";
|
|
15504
|
+
let toolCalls;
|
|
15505
|
+
let finishReason;
|
|
15506
|
+
let metrics = {};
|
|
15507
|
+
for (const chunk of chunks) {
|
|
15508
|
+
metrics = {
|
|
15509
|
+
...metrics,
|
|
15510
|
+
...parseOpenRouterMetricsFromUsage2(chunk?.usage)
|
|
15511
|
+
};
|
|
15512
|
+
const choice = chunk?.choices?.[0];
|
|
15513
|
+
const delta = choice?.delta;
|
|
15514
|
+
if (!delta) {
|
|
15515
|
+
if (choice?.finish_reason !== void 0) {
|
|
15516
|
+
finishReason = choice.finish_reason;
|
|
15517
|
+
}
|
|
15518
|
+
continue;
|
|
15519
|
+
}
|
|
15520
|
+
if (!role && delta.role) {
|
|
15521
|
+
role = delta.role;
|
|
15522
|
+
}
|
|
15523
|
+
if (typeof delta.content === "string") {
|
|
15524
|
+
content += delta.content;
|
|
15525
|
+
}
|
|
15526
|
+
const choiceFinishReason = choice?.finishReason ?? choice?.finish_reason ?? void 0;
|
|
15527
|
+
const deltaFinishReason = delta.finishReason ?? delta.finish_reason ?? void 0;
|
|
15528
|
+
if (choiceFinishReason !== void 0) {
|
|
15529
|
+
finishReason = choiceFinishReason;
|
|
15530
|
+
} else if (deltaFinishReason !== void 0) {
|
|
15531
|
+
finishReason = deltaFinishReason;
|
|
15532
|
+
}
|
|
15533
|
+
const toolCallDeltas = Array.isArray(delta.toolCalls) ? delta.toolCalls : Array.isArray(delta.tool_calls) ? delta.tool_calls : void 0;
|
|
15534
|
+
if (!toolCallDeltas) {
|
|
15535
|
+
continue;
|
|
15536
|
+
}
|
|
15537
|
+
for (const toolDelta of toolCallDeltas) {
|
|
15538
|
+
if (!toolDelta?.function) {
|
|
15539
|
+
continue;
|
|
15540
|
+
}
|
|
15541
|
+
const toolIndex = toolDelta.index ?? 0;
|
|
15542
|
+
const existingToolCall = toolCalls?.[toolIndex];
|
|
15543
|
+
if (!existingToolCall || toolDelta.id && existingToolCall.id !== void 0 && existingToolCall.id !== toolDelta.id) {
|
|
15544
|
+
const nextToolCalls = [...toolCalls || []];
|
|
15545
|
+
nextToolCalls[toolIndex] = {
|
|
15546
|
+
index: toolIndex,
|
|
15547
|
+
id: toolDelta.id,
|
|
15548
|
+
type: toolDelta.type,
|
|
15549
|
+
function: {
|
|
15550
|
+
name: toolDelta.function.name,
|
|
15551
|
+
arguments: toolDelta.function.arguments || ""
|
|
15552
|
+
}
|
|
15553
|
+
};
|
|
15554
|
+
toolCalls = nextToolCalls;
|
|
15555
|
+
continue;
|
|
15556
|
+
}
|
|
15557
|
+
const current = existingToolCall;
|
|
15558
|
+
if (toolDelta.id && !current.id) {
|
|
15559
|
+
current.id = toolDelta.id;
|
|
15560
|
+
}
|
|
15561
|
+
if (toolDelta.type && !current.type) {
|
|
15562
|
+
current.type = toolDelta.type;
|
|
15563
|
+
}
|
|
15564
|
+
if (toolDelta.function.name && !current.function.name) {
|
|
15565
|
+
current.function.name = toolDelta.function.name;
|
|
15566
|
+
}
|
|
15567
|
+
current.function.arguments += toolDelta.function.arguments || "";
|
|
15568
|
+
}
|
|
15569
|
+
}
|
|
15570
|
+
return {
|
|
15571
|
+
output: [
|
|
15572
|
+
{
|
|
15573
|
+
index: 0,
|
|
15574
|
+
message: {
|
|
15575
|
+
role,
|
|
15576
|
+
content: content || void 0,
|
|
15577
|
+
...toolCalls ? { tool_calls: toolCalls } : {}
|
|
15578
|
+
},
|
|
15579
|
+
logprobs: null,
|
|
15580
|
+
finish_reason: finishReason
|
|
15581
|
+
}
|
|
15582
|
+
],
|
|
15583
|
+
metrics
|
|
15584
|
+
};
|
|
15585
|
+
}
|
|
15586
|
+
function aggregateOpenRouterResponseStreamEvents(chunks) {
|
|
15587
|
+
let finalResponse;
|
|
15588
|
+
for (const chunk of chunks) {
|
|
15589
|
+
const response = chunk?.response;
|
|
15590
|
+
if (!response) {
|
|
15591
|
+
continue;
|
|
15592
|
+
}
|
|
15593
|
+
if (chunk.type === "response.completed" || chunk.type === "response.incomplete" || chunk.type === "response.failed") {
|
|
15594
|
+
finalResponse = response;
|
|
15595
|
+
}
|
|
15596
|
+
}
|
|
15597
|
+
if (!finalResponse) {
|
|
15598
|
+
return {
|
|
15599
|
+
output: void 0,
|
|
15600
|
+
metrics: {}
|
|
15601
|
+
};
|
|
15602
|
+
}
|
|
15603
|
+
return {
|
|
15604
|
+
output: extractOpenRouterResponseOutput2(finalResponse),
|
|
15605
|
+
metrics: parseOpenRouterMetricsFromUsage2(finalResponse.usage),
|
|
15606
|
+
...extractOpenRouterResponseMetadata2(finalResponse) ? { metadata: extractOpenRouterResponseMetadata2(finalResponse) } : {}
|
|
15607
|
+
};
|
|
15608
|
+
}
|
|
15609
|
+
var OPENROUTER_WRAPPED_CALL_MODEL_RESULT2 = Symbol(
|
|
15610
|
+
"braintrust.openrouter.wrappedCallModelResult"
|
|
15611
|
+
);
|
|
15612
|
+
var OPENROUTER_CALL_MODEL_STREAM_METHODS2 = [
|
|
15613
|
+
"getFullResponsesStream",
|
|
15614
|
+
"getItemsStream",
|
|
15615
|
+
"getNewMessagesStream",
|
|
15616
|
+
"getReasoningStream",
|
|
15617
|
+
"getTextStream",
|
|
15618
|
+
"getToolCallsStream",
|
|
15619
|
+
"getToolStream"
|
|
15620
|
+
];
|
|
15621
|
+
var OPENROUTER_CALL_MODEL_CONTEXT_METHODS2 = [
|
|
15622
|
+
"cancel",
|
|
15623
|
+
"getPendingToolCalls",
|
|
15624
|
+
"getState",
|
|
15625
|
+
"getToolCalls",
|
|
15626
|
+
"requiresApproval"
|
|
15627
|
+
];
|
|
15628
|
+
function patchOpenRouterCallModelResult2(args) {
|
|
15629
|
+
const { request, result, span } = args;
|
|
15630
|
+
if (!isObject(result) || isWrappedCallModelResult2(result)) {
|
|
15631
|
+
return false;
|
|
15632
|
+
}
|
|
15633
|
+
const resultLike = result;
|
|
15634
|
+
const hasInstrumentableMethod = typeof resultLike.getResponse === "function" || typeof resultLike.getText === "function" || OPENROUTER_CALL_MODEL_STREAM_METHODS2.some(
|
|
15635
|
+
(methodName) => typeof resultLike[methodName] === "function"
|
|
15636
|
+
);
|
|
15637
|
+
if (!hasInstrumentableMethod) {
|
|
15638
|
+
return false;
|
|
15639
|
+
}
|
|
15640
|
+
Object.defineProperty(resultLike, OPENROUTER_WRAPPED_CALL_MODEL_RESULT2, {
|
|
15641
|
+
value: true,
|
|
15642
|
+
enumerable: false,
|
|
15643
|
+
configurable: false
|
|
15644
|
+
});
|
|
15645
|
+
const originalGetResponse = typeof resultLike.getResponse === "function" ? resultLike.getResponse.bind(resultLike) : void 0;
|
|
15646
|
+
const originalGetInitialResponse = typeof resultLike.getInitialResponse === "function" ? resultLike.getInitialResponse.bind(resultLike) : void 0;
|
|
15647
|
+
const originalMakeFollowupRequest = typeof resultLike.makeFollowupRequest === "function" ? resultLike.makeFollowupRequest.bind(resultLike) : void 0;
|
|
15648
|
+
let ended = false;
|
|
15649
|
+
let tracedTurnCount = 0;
|
|
15650
|
+
const endSpanWithResult = async (response, fallbackOutput) => {
|
|
15651
|
+
if (ended) {
|
|
15652
|
+
return;
|
|
15653
|
+
}
|
|
15654
|
+
ended = true;
|
|
15655
|
+
const finalResponse = getFinalOpenRouterCallModelResponse2(
|
|
15656
|
+
resultLike,
|
|
15657
|
+
response
|
|
15658
|
+
);
|
|
15659
|
+
if (finalResponse) {
|
|
15660
|
+
const rounds = getOpenRouterCallModelRounds2(resultLike);
|
|
15661
|
+
const metadata = extractOpenRouterCallModelResultMetadata2(
|
|
15662
|
+
finalResponse,
|
|
15663
|
+
rounds.length + 1
|
|
15664
|
+
);
|
|
15665
|
+
span.log({
|
|
15666
|
+
output: extractOpenRouterResponseOutput2(finalResponse, fallbackOutput),
|
|
15667
|
+
...metadata ? { metadata } : {},
|
|
15668
|
+
metrics: aggregateOpenRouterCallModelMetrics2(rounds, finalResponse)
|
|
15669
|
+
});
|
|
15670
|
+
span.end();
|
|
15671
|
+
return;
|
|
15672
|
+
}
|
|
15673
|
+
if (fallbackOutput !== void 0) {
|
|
15674
|
+
span.log({
|
|
15675
|
+
output: fallbackOutput
|
|
15676
|
+
});
|
|
15677
|
+
}
|
|
15678
|
+
span.end();
|
|
15679
|
+
};
|
|
15680
|
+
const endSpanWithError = (error) => {
|
|
15681
|
+
if (ended) {
|
|
15682
|
+
return;
|
|
15683
|
+
}
|
|
15684
|
+
ended = true;
|
|
15685
|
+
span.log({
|
|
15686
|
+
error: normalizeError2(error).message
|
|
15687
|
+
});
|
|
15688
|
+
span.end();
|
|
15689
|
+
};
|
|
15690
|
+
const finalizeFromResponse = async (fallbackOutput) => {
|
|
15691
|
+
if (!originalGetResponse) {
|
|
15692
|
+
await endSpanWithResult(void 0, fallbackOutput);
|
|
15693
|
+
return;
|
|
15694
|
+
}
|
|
15695
|
+
try {
|
|
15696
|
+
await endSpanWithResult(await originalGetResponse(), fallbackOutput);
|
|
15697
|
+
} catch {
|
|
15698
|
+
await endSpanWithResult(void 0, fallbackOutput);
|
|
15699
|
+
}
|
|
15700
|
+
};
|
|
15701
|
+
if (originalGetResponse) {
|
|
15702
|
+
resultLike.getResponse = async (...args2) => {
|
|
15703
|
+
return await withCurrent(span, async () => {
|
|
15704
|
+
try {
|
|
15705
|
+
const response = await originalGetResponse(...args2);
|
|
15706
|
+
await endSpanWithResult(response);
|
|
15707
|
+
return response;
|
|
15708
|
+
} catch (error) {
|
|
15709
|
+
endSpanWithError(error);
|
|
15710
|
+
throw error;
|
|
15711
|
+
}
|
|
15712
|
+
});
|
|
15713
|
+
};
|
|
15714
|
+
}
|
|
15715
|
+
if (typeof resultLike.getText === "function") {
|
|
15716
|
+
const originalGetText = resultLike.getText.bind(resultLike);
|
|
15717
|
+
resultLike.getText = async (...args2) => {
|
|
15718
|
+
return await withCurrent(span, async () => {
|
|
15719
|
+
try {
|
|
15720
|
+
const text = await originalGetText(...args2);
|
|
15721
|
+
await finalizeFromResponse(text);
|
|
15722
|
+
return text;
|
|
15723
|
+
} catch (error) {
|
|
15724
|
+
endSpanWithError(error);
|
|
15725
|
+
throw error;
|
|
15726
|
+
}
|
|
15727
|
+
});
|
|
15728
|
+
};
|
|
15729
|
+
}
|
|
15730
|
+
for (const methodName of OPENROUTER_CALL_MODEL_CONTEXT_METHODS2) {
|
|
15731
|
+
if (typeof resultLike[methodName] !== "function") {
|
|
15732
|
+
continue;
|
|
15733
|
+
}
|
|
15734
|
+
const originalMethod = resultLike[methodName];
|
|
15735
|
+
resultLike[methodName] = async (...args2) => {
|
|
15736
|
+
return await withCurrent(span, async () => {
|
|
15737
|
+
return await originalMethod.apply(resultLike, args2);
|
|
15738
|
+
});
|
|
15739
|
+
};
|
|
15740
|
+
}
|
|
15741
|
+
for (const methodName of OPENROUTER_CALL_MODEL_STREAM_METHODS2) {
|
|
15742
|
+
if (typeof resultLike[methodName] !== "function") {
|
|
15743
|
+
continue;
|
|
15744
|
+
}
|
|
15745
|
+
const originalMethod = resultLike[methodName];
|
|
15746
|
+
resultLike[methodName] = (...args2) => {
|
|
15747
|
+
const stream = withCurrent(
|
|
15748
|
+
span,
|
|
15749
|
+
() => originalMethod.apply(resultLike, args2)
|
|
15750
|
+
);
|
|
15751
|
+
if (!isAsyncIterable4(stream)) {
|
|
15752
|
+
return stream;
|
|
15753
|
+
}
|
|
15754
|
+
return wrapAsyncIterableWithSpan2({
|
|
15755
|
+
finalize: finalizeFromResponse,
|
|
15756
|
+
iteratorFactory: () => stream[Symbol.asyncIterator](),
|
|
15757
|
+
onError: endSpanWithError,
|
|
15758
|
+
span
|
|
15759
|
+
});
|
|
15760
|
+
};
|
|
15761
|
+
}
|
|
15762
|
+
if (originalGetInitialResponse) {
|
|
15763
|
+
let initialTurnTraced = false;
|
|
15764
|
+
resultLike.getInitialResponse = async (...args2) => {
|
|
15765
|
+
if (initialTurnTraced) {
|
|
15766
|
+
return await withCurrent(span, async () => {
|
|
15767
|
+
return await originalGetInitialResponse(...args2);
|
|
15768
|
+
});
|
|
15769
|
+
}
|
|
15770
|
+
initialTurnTraced = true;
|
|
15771
|
+
const step = tracedTurnCount + 1;
|
|
15772
|
+
const stepType = tracedTurnCount === 0 ? "initial" : "continue";
|
|
15773
|
+
const response = await traceOpenRouterCallModelTurn2({
|
|
15774
|
+
fn: async () => {
|
|
15775
|
+
const nextResponse = await originalGetInitialResponse(...args2);
|
|
15776
|
+
tracedTurnCount++;
|
|
15777
|
+
return nextResponse;
|
|
15778
|
+
},
|
|
15779
|
+
parentSpan: span,
|
|
15780
|
+
request: getOpenRouterResolvedRequest2(resultLike, request),
|
|
15781
|
+
step,
|
|
15782
|
+
stepType
|
|
15783
|
+
});
|
|
15784
|
+
return response;
|
|
15785
|
+
};
|
|
15786
|
+
}
|
|
15787
|
+
if (originalMakeFollowupRequest) {
|
|
15788
|
+
resultLike.makeFollowupRequest = async (...args2) => {
|
|
15789
|
+
const currentResponse = args2[0];
|
|
15790
|
+
const toolResults = Array.isArray(args2[1]) ? args2[1] : [];
|
|
15791
|
+
const step = tracedTurnCount + 1;
|
|
15792
|
+
const response = await traceOpenRouterCallModelTurn2({
|
|
15793
|
+
fn: async () => {
|
|
15794
|
+
const nextResponse = await originalMakeFollowupRequest(...args2);
|
|
15795
|
+
tracedTurnCount++;
|
|
15796
|
+
return nextResponse;
|
|
15797
|
+
},
|
|
15798
|
+
parentSpan: span,
|
|
15799
|
+
request: buildOpenRouterFollowupRequest2(
|
|
15800
|
+
getOpenRouterResolvedRequest2(resultLike, request),
|
|
15801
|
+
currentResponse,
|
|
15802
|
+
toolResults
|
|
15803
|
+
),
|
|
15804
|
+
step,
|
|
15805
|
+
stepType: "continue"
|
|
15806
|
+
});
|
|
15807
|
+
return response;
|
|
15808
|
+
};
|
|
15809
|
+
}
|
|
15810
|
+
return true;
|
|
15811
|
+
}
|
|
15812
|
+
async function traceOpenRouterCallModelTurn2(args) {
|
|
15813
|
+
const context = {
|
|
15814
|
+
arguments: [args.request],
|
|
15815
|
+
step: args.step,
|
|
15816
|
+
stepType: args.stepType
|
|
15817
|
+
};
|
|
15818
|
+
return await withCurrent(
|
|
15819
|
+
args.parentSpan,
|
|
15820
|
+
() => openRouterChannels.callModelTurn.tracePromise(args.fn, context)
|
|
15821
|
+
);
|
|
15822
|
+
}
|
|
15823
|
+
function isWrappedCallModelResult2(value) {
|
|
15824
|
+
return Boolean(
|
|
15825
|
+
isObject(value) && value[OPENROUTER_WRAPPED_CALL_MODEL_RESULT2]
|
|
15826
|
+
);
|
|
15827
|
+
}
|
|
15828
|
+
function extractOpenRouterCallModelResultMetadata2(response, turnCount) {
|
|
15829
|
+
const combined = {
|
|
15830
|
+
...extractOpenRouterResponseMetadata2(response) || {},
|
|
15831
|
+
...turnCount !== void 0 ? { turn_count: turnCount } : {}
|
|
15832
|
+
};
|
|
15833
|
+
return Object.keys(combined).length > 0 ? combined : void 0;
|
|
15834
|
+
}
|
|
15835
|
+
function getFinalOpenRouterCallModelResponse2(result, response) {
|
|
15836
|
+
if (isObject(response)) {
|
|
15837
|
+
return response;
|
|
15838
|
+
}
|
|
15839
|
+
return isObject(result.finalResponse) ? result.finalResponse : void 0;
|
|
15840
|
+
}
|
|
15841
|
+
function getOpenRouterCallModelRounds2(result) {
|
|
15842
|
+
if (!Array.isArray(result.allToolExecutionRounds)) {
|
|
15843
|
+
return [];
|
|
15844
|
+
}
|
|
15845
|
+
return result.allToolExecutionRounds.filter((round) => isObject(round)).map((round) => ({
|
|
15846
|
+
response: isObject(round.response) ? round.response : void 0,
|
|
15847
|
+
round: typeof round.round === "number" ? round.round : void 0,
|
|
15848
|
+
toolResults: Array.isArray(round.toolResults) ? round.toolResults : []
|
|
15849
|
+
})).filter((round) => round.response !== void 0);
|
|
15850
|
+
}
|
|
15851
|
+
function aggregateOpenRouterCallModelMetrics2(rounds, finalResponse) {
|
|
15852
|
+
const metrics = {};
|
|
15853
|
+
const responses = [
|
|
15854
|
+
...rounds.map((round) => round.response).filter(isObject),
|
|
15855
|
+
finalResponse
|
|
15856
|
+
];
|
|
15857
|
+
for (const response of responses) {
|
|
15858
|
+
const responseMetrics = parseOpenRouterMetricsFromUsage2(response.usage);
|
|
15859
|
+
for (const [name, value] of Object.entries(responseMetrics)) {
|
|
15860
|
+
metrics[name] = (metrics[name] || 0) + value;
|
|
15861
|
+
}
|
|
15862
|
+
}
|
|
15863
|
+
return metrics;
|
|
15864
|
+
}
|
|
15865
|
+
function buildNextOpenRouterCallModelInput2(currentInput, response, toolResults) {
|
|
15866
|
+
const normalizedInput = Array.isArray(currentInput) ? [...currentInput] : currentInput === void 0 ? [] : [currentInput];
|
|
15867
|
+
const responseOutput = Array.isArray(response.output) ? response.output : response.output === void 0 ? [] : [response.output];
|
|
15868
|
+
return [...normalizedInput, ...responseOutput, ...toolResults].map(
|
|
15869
|
+
(entry) => sanitizeOpenRouterLoggedValue2(entry)
|
|
15870
|
+
);
|
|
15871
|
+
}
|
|
15872
|
+
function getOpenRouterResolvedRequest2(result, request) {
|
|
15873
|
+
if (isObject(result.resolvedRequest)) {
|
|
15874
|
+
return result.resolvedRequest;
|
|
15875
|
+
}
|
|
15876
|
+
return request;
|
|
15877
|
+
}
|
|
15878
|
+
function buildOpenRouterFollowupRequest2(request, currentResponse, toolResults) {
|
|
15879
|
+
if (!request) {
|
|
15880
|
+
return void 0;
|
|
15881
|
+
}
|
|
15882
|
+
return {
|
|
15883
|
+
...request,
|
|
15884
|
+
input: buildNextOpenRouterCallModelInput2(
|
|
15885
|
+
extractOpenRouterCallModelInput2(request),
|
|
15886
|
+
isObject(currentResponse) ? currentResponse : {},
|
|
15887
|
+
toolResults
|
|
15888
|
+
),
|
|
15889
|
+
stream: false
|
|
15890
|
+
};
|
|
15891
|
+
}
|
|
15892
|
+
function wrapAsyncIterableWithSpan2(args) {
|
|
15893
|
+
return {
|
|
15894
|
+
[Symbol.asyncIterator]() {
|
|
15895
|
+
const iterator = args.iteratorFactory();
|
|
15896
|
+
return {
|
|
15897
|
+
next(value) {
|
|
15898
|
+
return withCurrent(
|
|
15899
|
+
args.span,
|
|
15900
|
+
() => value === void 0 ? iterator.next() : iterator.next(value)
|
|
15901
|
+
).then(
|
|
15902
|
+
async (result) => {
|
|
15903
|
+
if (result.done) {
|
|
15904
|
+
await args.finalize();
|
|
15905
|
+
}
|
|
15906
|
+
return result;
|
|
15907
|
+
},
|
|
15908
|
+
(error) => {
|
|
15909
|
+
args.onError(error);
|
|
15910
|
+
throw error;
|
|
15911
|
+
}
|
|
15912
|
+
);
|
|
15913
|
+
},
|
|
15914
|
+
return(value) {
|
|
15915
|
+
if (typeof iterator.return !== "function") {
|
|
15916
|
+
return args.finalize().then(() => ({
|
|
15917
|
+
done: true,
|
|
15918
|
+
value
|
|
15919
|
+
}));
|
|
15920
|
+
}
|
|
15921
|
+
return withCurrent(args.span, () => iterator.return(value)).then(
|
|
15922
|
+
async (result) => {
|
|
15923
|
+
await args.finalize();
|
|
15924
|
+
return result;
|
|
15925
|
+
},
|
|
15926
|
+
(error) => {
|
|
15927
|
+
args.onError(error);
|
|
15928
|
+
throw error;
|
|
15929
|
+
}
|
|
15930
|
+
);
|
|
15931
|
+
},
|
|
15932
|
+
throw(error) {
|
|
15933
|
+
args.onError(error);
|
|
15934
|
+
if (typeof iterator.throw !== "function") {
|
|
15935
|
+
return Promise.reject(error);
|
|
15936
|
+
}
|
|
15937
|
+
return withCurrent(args.span, () => iterator.throw(error));
|
|
15938
|
+
},
|
|
15939
|
+
[Symbol.asyncIterator]() {
|
|
15940
|
+
return this;
|
|
15941
|
+
}
|
|
15942
|
+
};
|
|
15943
|
+
}
|
|
15944
|
+
};
|
|
15945
|
+
}
|
|
15946
|
+
function isAsyncIterable4(value) {
|
|
15947
|
+
return !!value && (typeof value === "object" || typeof value === "function") && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
15948
|
+
}
|
|
15949
|
+
function normalizeError2(error) {
|
|
15950
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
15951
|
+
}
|
|
15952
|
+
|
|
15953
|
+
// src/instrumentation/plugins/mistral-channels.ts
|
|
15954
|
+
var mistralChannels = defineChannels("@mistralai/mistralai", {
|
|
15955
|
+
chatComplete: channel({
|
|
15956
|
+
channelName: "chat.complete",
|
|
15957
|
+
kind: "async"
|
|
15958
|
+
}),
|
|
15959
|
+
chatStream: channel({
|
|
15960
|
+
channelName: "chat.stream",
|
|
15961
|
+
kind: "async"
|
|
15962
|
+
}),
|
|
15963
|
+
embeddingsCreate: channel({
|
|
15964
|
+
channelName: "embeddings.create",
|
|
15965
|
+
kind: "async"
|
|
15966
|
+
}),
|
|
15967
|
+
fimComplete: channel({
|
|
15968
|
+
channelName: "fim.complete",
|
|
15969
|
+
kind: "async"
|
|
15970
|
+
}),
|
|
15971
|
+
fimStream: channel({
|
|
15972
|
+
channelName: "fim.stream",
|
|
15973
|
+
kind: "async"
|
|
15974
|
+
}),
|
|
15975
|
+
agentsComplete: channel({
|
|
15976
|
+
channelName: "agents.complete",
|
|
15977
|
+
kind: "async"
|
|
15978
|
+
}),
|
|
15979
|
+
agentsStream: channel({
|
|
15980
|
+
channelName: "agents.stream",
|
|
15981
|
+
kind: "async"
|
|
15982
|
+
})
|
|
15983
|
+
});
|
|
15984
|
+
|
|
15985
|
+
// src/instrumentation/plugins/mistral-plugin.ts
|
|
15986
|
+
var MistralPlugin = class extends BasePlugin {
|
|
15987
|
+
onEnable() {
|
|
15988
|
+
this.subscribeToMistralChannels();
|
|
15989
|
+
}
|
|
15990
|
+
onDisable() {
|
|
15991
|
+
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
15992
|
+
}
|
|
15993
|
+
subscribeToMistralChannels() {
|
|
15994
|
+
this.unsubscribers.push(
|
|
15995
|
+
traceStreamingChannel(mistralChannels.chatComplete, {
|
|
15996
|
+
name: "mistral.chat.complete",
|
|
15997
|
+
type: "llm" /* LLM */,
|
|
15998
|
+
extractInput: extractMessagesInputWithMetadata,
|
|
15999
|
+
extractOutput: (result) => {
|
|
16000
|
+
return result?.choices;
|
|
16001
|
+
},
|
|
16002
|
+
extractMetadata: (result) => extractMistralResponseMetadata(result),
|
|
16003
|
+
extractMetrics: (result, startTime) => extractMistralMetrics(result?.usage, startTime)
|
|
16004
|
+
})
|
|
16005
|
+
);
|
|
16006
|
+
this.unsubscribers.push(
|
|
16007
|
+
traceStreamingChannel(mistralChannels.chatStream, {
|
|
16008
|
+
name: "mistral.chat.stream",
|
|
16009
|
+
type: "llm" /* LLM */,
|
|
16010
|
+
extractInput: extractMessagesInputWithMetadata,
|
|
16011
|
+
extractOutput: extractMistralStreamOutput,
|
|
16012
|
+
extractMetadata: (result) => extractMistralResponseMetadata(result),
|
|
16013
|
+
extractMetrics: (result, startTime) => extractMistralStreamingMetrics(result, startTime),
|
|
16014
|
+
aggregateChunks: aggregateMistralStreamChunks
|
|
16015
|
+
})
|
|
16016
|
+
);
|
|
16017
|
+
this.unsubscribers.push(
|
|
16018
|
+
traceAsyncChannel(mistralChannels.embeddingsCreate, {
|
|
16019
|
+
name: "mistral.embeddings.create",
|
|
16020
|
+
type: "llm" /* LLM */,
|
|
16021
|
+
extractInput: extractEmbeddingInputWithMetadata,
|
|
16022
|
+
extractOutput: (result) => {
|
|
16023
|
+
const embedding = result?.data?.[0]?.embedding;
|
|
16024
|
+
return Array.isArray(embedding) ? { embedding_length: embedding.length } : void 0;
|
|
16025
|
+
},
|
|
16026
|
+
extractMetadata: (result) => extractMistralResponseMetadata(result),
|
|
16027
|
+
extractMetrics: (result) => parseMistralMetricsFromUsage(result?.usage)
|
|
16028
|
+
})
|
|
16029
|
+
);
|
|
16030
|
+
this.unsubscribers.push(
|
|
16031
|
+
traceStreamingChannel(mistralChannels.fimComplete, {
|
|
16032
|
+
name: "mistral.fim.complete",
|
|
16033
|
+
type: "llm" /* LLM */,
|
|
16034
|
+
extractInput: extractPromptInputWithMetadata,
|
|
16035
|
+
extractOutput: (result) => {
|
|
16036
|
+
return result?.choices;
|
|
16037
|
+
},
|
|
16038
|
+
extractMetadata: (result) => extractMistralResponseMetadata(result),
|
|
16039
|
+
extractMetrics: (result, startTime) => extractMistralMetrics(result?.usage, startTime)
|
|
16040
|
+
})
|
|
16041
|
+
);
|
|
16042
|
+
this.unsubscribers.push(
|
|
16043
|
+
traceStreamingChannel(mistralChannels.fimStream, {
|
|
16044
|
+
name: "mistral.fim.stream",
|
|
16045
|
+
type: "llm" /* LLM */,
|
|
16046
|
+
extractInput: extractPromptInputWithMetadata,
|
|
16047
|
+
extractOutput: extractMistralStreamOutput,
|
|
16048
|
+
extractMetadata: (result) => extractMistralResponseMetadata(result),
|
|
16049
|
+
extractMetrics: (result, startTime) => extractMistralStreamingMetrics(result, startTime),
|
|
16050
|
+
aggregateChunks: aggregateMistralStreamChunks
|
|
16051
|
+
})
|
|
16052
|
+
);
|
|
16053
|
+
this.unsubscribers.push(
|
|
16054
|
+
traceStreamingChannel(mistralChannels.agentsComplete, {
|
|
16055
|
+
name: "mistral.agents.complete",
|
|
16056
|
+
type: "llm" /* LLM */,
|
|
16057
|
+
extractInput: extractMessagesInputWithMetadata,
|
|
16058
|
+
extractOutput: (result) => {
|
|
16059
|
+
return result?.choices;
|
|
16060
|
+
},
|
|
16061
|
+
extractMetadata: (result) => extractMistralResponseMetadata(result),
|
|
16062
|
+
extractMetrics: (result, startTime) => extractMistralMetrics(result?.usage, startTime)
|
|
16063
|
+
})
|
|
16064
|
+
);
|
|
16065
|
+
this.unsubscribers.push(
|
|
16066
|
+
traceStreamingChannel(mistralChannels.agentsStream, {
|
|
16067
|
+
name: "mistral.agents.stream",
|
|
16068
|
+
type: "llm" /* LLM */,
|
|
16069
|
+
extractInput: extractMessagesInputWithMetadata,
|
|
16070
|
+
extractOutput: extractMistralStreamOutput,
|
|
16071
|
+
extractMetadata: (result) => extractMistralResponseMetadata(result),
|
|
16072
|
+
extractMetrics: (result, startTime) => extractMistralStreamingMetrics(result, startTime),
|
|
16073
|
+
aggregateChunks: aggregateMistralStreamChunks
|
|
16074
|
+
})
|
|
16075
|
+
);
|
|
13839
16076
|
}
|
|
13840
16077
|
};
|
|
13841
|
-
|
|
16078
|
+
var TOKEN_NAME_MAP4 = {
|
|
16079
|
+
promptTokens: "prompt_tokens",
|
|
16080
|
+
inputTokens: "prompt_tokens",
|
|
16081
|
+
completionTokens: "completion_tokens",
|
|
16082
|
+
outputTokens: "completion_tokens",
|
|
16083
|
+
totalTokens: "tokens",
|
|
16084
|
+
prompt_tokens: "prompt_tokens",
|
|
16085
|
+
input_tokens: "prompt_tokens",
|
|
16086
|
+
completion_tokens: "completion_tokens",
|
|
16087
|
+
output_tokens: "completion_tokens",
|
|
16088
|
+
total_tokens: "tokens",
|
|
16089
|
+
promptAudioSeconds: "prompt_audio_seconds",
|
|
16090
|
+
prompt_audio_seconds: "prompt_audio_seconds"
|
|
16091
|
+
};
|
|
16092
|
+
var TOKEN_DETAIL_PREFIX_MAP3 = {
|
|
16093
|
+
promptTokensDetails: "prompt",
|
|
16094
|
+
inputTokensDetails: "prompt",
|
|
16095
|
+
completionTokensDetails: "completion",
|
|
16096
|
+
outputTokensDetails: "completion",
|
|
16097
|
+
prompt_tokens_details: "prompt",
|
|
16098
|
+
input_tokens_details: "prompt",
|
|
16099
|
+
completion_tokens_details: "completion",
|
|
16100
|
+
output_tokens_details: "completion"
|
|
16101
|
+
};
|
|
16102
|
+
var MISTRAL_REQUEST_METADATA_ALLOWLIST = /* @__PURE__ */ new Set([
|
|
16103
|
+
"agentId",
|
|
16104
|
+
"agent_id",
|
|
16105
|
+
"encodingFormat",
|
|
16106
|
+
"encoding_format",
|
|
16107
|
+
"frequencyPenalty",
|
|
16108
|
+
"frequency_penalty",
|
|
16109
|
+
"maxTokens",
|
|
16110
|
+
"max_tokens",
|
|
16111
|
+
"model",
|
|
16112
|
+
"n",
|
|
16113
|
+
"presencePenalty",
|
|
16114
|
+
"presence_penalty",
|
|
16115
|
+
"randomSeed",
|
|
16116
|
+
"random_seed",
|
|
16117
|
+
"responseFormat",
|
|
16118
|
+
"response_format",
|
|
16119
|
+
"safePrompt",
|
|
16120
|
+
"safe_prompt",
|
|
16121
|
+
"stream",
|
|
16122
|
+
"stop",
|
|
16123
|
+
"temperature",
|
|
16124
|
+
"toolChoice",
|
|
16125
|
+
"tool_choice",
|
|
16126
|
+
"topP",
|
|
16127
|
+
"top_p"
|
|
16128
|
+
]);
|
|
16129
|
+
var MISTRAL_RESPONSE_METADATA_ALLOWLIST = /* @__PURE__ */ new Set([
|
|
16130
|
+
"agentId",
|
|
16131
|
+
"agent_id",
|
|
16132
|
+
"created",
|
|
16133
|
+
"id",
|
|
16134
|
+
"model",
|
|
16135
|
+
"object"
|
|
16136
|
+
]);
|
|
16137
|
+
function camelToSnake3(value) {
|
|
16138
|
+
return value.replace(/[A-Z]/g, (match) => `_${match.toLowerCase()}`);
|
|
16139
|
+
}
|
|
16140
|
+
function normalizeArgs3(args) {
|
|
13842
16141
|
if (Array.isArray(args)) {
|
|
13843
16142
|
return args;
|
|
13844
16143
|
}
|
|
13845
|
-
if (
|
|
16144
|
+
if (isArrayLike3(args)) {
|
|
13846
16145
|
return Array.from(args);
|
|
13847
16146
|
}
|
|
13848
16147
|
return [args];
|
|
13849
16148
|
}
|
|
13850
|
-
function
|
|
16149
|
+
function isArrayLike3(value) {
|
|
13851
16150
|
return isObject(value) && "length" in value && typeof value.length === "number" && Number.isInteger(value.length) && value.length >= 0;
|
|
13852
16151
|
}
|
|
13853
|
-
function
|
|
13854
|
-
const
|
|
13855
|
-
|
|
13856
|
-
|
|
16152
|
+
function getMistralRequestArg(args) {
|
|
16153
|
+
const firstObjectArg = normalizeArgs3(args).find((arg) => isObject(arg));
|
|
16154
|
+
return isObject(firstObjectArg) ? firstObjectArg : void 0;
|
|
16155
|
+
}
|
|
16156
|
+
function addMistralProviderMetadata(metadata) {
|
|
16157
|
+
return {
|
|
16158
|
+
...metadata,
|
|
16159
|
+
provider: "mistral"
|
|
16160
|
+
};
|
|
16161
|
+
}
|
|
16162
|
+
function pickAllowedMetadata(metadata, allowlist) {
|
|
16163
|
+
if (!metadata) {
|
|
16164
|
+
return {};
|
|
16165
|
+
}
|
|
16166
|
+
const picked = {};
|
|
16167
|
+
for (const key of allowlist) {
|
|
16168
|
+
const value = metadata[key];
|
|
16169
|
+
if (value !== void 0) {
|
|
16170
|
+
picked[key] = value;
|
|
16171
|
+
}
|
|
16172
|
+
}
|
|
16173
|
+
return picked;
|
|
16174
|
+
}
|
|
16175
|
+
function extractMistralRequestMetadata(metadata) {
|
|
16176
|
+
return pickAllowedMetadata(metadata, MISTRAL_REQUEST_METADATA_ALLOWLIST);
|
|
16177
|
+
}
|
|
16178
|
+
function isMistralChatCompletionChunk(value) {
|
|
16179
|
+
return isObject(value);
|
|
16180
|
+
}
|
|
16181
|
+
function isMistralChunkChoice(value) {
|
|
16182
|
+
return isObject(value);
|
|
16183
|
+
}
|
|
16184
|
+
function extractMessagesInputWithMetadata(args) {
|
|
16185
|
+
const params = getMistralRequestArg(args);
|
|
16186
|
+
const { messages, ...rawMetadata } = params || {};
|
|
16187
|
+
return {
|
|
16188
|
+
input: processInputAttachments(messages),
|
|
16189
|
+
metadata: addMistralProviderMetadata(
|
|
16190
|
+
extractMistralRequestMetadata(rawMetadata)
|
|
16191
|
+
)
|
|
16192
|
+
};
|
|
16193
|
+
}
|
|
16194
|
+
function extractEmbeddingInputWithMetadata(args) {
|
|
16195
|
+
const params = getMistralRequestArg(args);
|
|
16196
|
+
const { inputs, ...rawMetadata } = params || {};
|
|
16197
|
+
return {
|
|
16198
|
+
input: inputs,
|
|
16199
|
+
metadata: addMistralProviderMetadata(
|
|
16200
|
+
extractMistralRequestMetadata(rawMetadata)
|
|
16201
|
+
)
|
|
16202
|
+
};
|
|
16203
|
+
}
|
|
16204
|
+
function extractPromptInputWithMetadata(args) {
|
|
16205
|
+
const params = getMistralRequestArg(args);
|
|
16206
|
+
const { prompt, ...rawMetadata } = params || {};
|
|
16207
|
+
return {
|
|
16208
|
+
input: prompt,
|
|
16209
|
+
metadata: addMistralProviderMetadata(
|
|
16210
|
+
extractMistralRequestMetadata(rawMetadata)
|
|
16211
|
+
)
|
|
16212
|
+
};
|
|
16213
|
+
}
|
|
16214
|
+
function extractMistralResponseMetadata(result) {
|
|
16215
|
+
if (!isObject(result)) {
|
|
16216
|
+
return void 0;
|
|
16217
|
+
}
|
|
16218
|
+
const { choices: _choices, usage: _usage, data: _data, ...metadata } = result;
|
|
16219
|
+
const picked = pickAllowedMetadata(
|
|
16220
|
+
metadata,
|
|
16221
|
+
MISTRAL_RESPONSE_METADATA_ALLOWLIST
|
|
13857
16222
|
);
|
|
13858
|
-
|
|
13859
|
-
|
|
16223
|
+
return Object.keys(picked).length > 0 ? picked : void 0;
|
|
16224
|
+
}
|
|
16225
|
+
function extractMistralMetrics(usage, startTime) {
|
|
16226
|
+
const metrics = parseMistralMetricsFromUsage(usage);
|
|
16227
|
+
if (startTime) {
|
|
16228
|
+
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
13860
16229
|
}
|
|
13861
|
-
|
|
13862
|
-
return isObject(firstObjectArg) ? firstObjectArg : void 0;
|
|
16230
|
+
return metrics;
|
|
13863
16231
|
}
|
|
13864
|
-
function
|
|
13865
|
-
|
|
13866
|
-
return isObject(firstObjectArg) ? firstObjectArg : void 0;
|
|
16232
|
+
function extractMistralStreamOutput(result) {
|
|
16233
|
+
return isObject(result) ? result.choices : void 0;
|
|
13867
16234
|
}
|
|
13868
|
-
function
|
|
13869
|
-
|
|
13870
|
-
|
|
13871
|
-
|
|
13872
|
-
|
|
13873
|
-
|
|
13874
|
-
|
|
13875
|
-
|
|
13876
|
-
|
|
13877
|
-
|
|
13878
|
-
|
|
13879
|
-
|
|
13880
|
-
|
|
13881
|
-
|
|
13882
|
-
|
|
13883
|
-
|
|
16235
|
+
function extractMistralStreamingMetrics(result, startTime) {
|
|
16236
|
+
const metrics = isObject(result) ? parseMistralMetricsFromUsage(result.usage) : {};
|
|
16237
|
+
if (startTime) {
|
|
16238
|
+
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
16239
|
+
}
|
|
16240
|
+
return metrics;
|
|
16241
|
+
}
|
|
16242
|
+
function extractDeltaText(content) {
|
|
16243
|
+
if (typeof content === "string") {
|
|
16244
|
+
return content;
|
|
16245
|
+
}
|
|
16246
|
+
if (!Array.isArray(content)) {
|
|
16247
|
+
return void 0;
|
|
16248
|
+
}
|
|
16249
|
+
const textParts = content.map((part) => {
|
|
16250
|
+
if (!isObject(part) || part.type !== "text") {
|
|
16251
|
+
return "";
|
|
16252
|
+
}
|
|
16253
|
+
return typeof part.text === "string" ? part.text : "";
|
|
16254
|
+
}).filter((part) => part.length > 0);
|
|
16255
|
+
return textParts.length > 0 ? textParts.join("") : void 0;
|
|
16256
|
+
}
|
|
16257
|
+
function getDeltaToolCalls(delta) {
|
|
16258
|
+
const toolCalls = Array.isArray(delta.toolCalls) && delta.toolCalls || Array.isArray(delta.tool_calls) && delta.tool_calls || [];
|
|
16259
|
+
return toolCalls.filter((toolCall) => isObject(toolCall));
|
|
16260
|
+
}
|
|
16261
|
+
function getToolCallIndex(toolCall) {
|
|
16262
|
+
return typeof toolCall.index === "number" && toolCall.index >= 0 ? toolCall.index : void 0;
|
|
16263
|
+
}
|
|
16264
|
+
function createMergedToolCallDelta(delta) {
|
|
16265
|
+
return {
|
|
16266
|
+
...delta,
|
|
16267
|
+
function: {
|
|
16268
|
+
...delta.function,
|
|
16269
|
+
arguments: typeof delta.function?.arguments === "string" ? delta.function.arguments : ""
|
|
16270
|
+
}
|
|
16271
|
+
};
|
|
16272
|
+
}
|
|
16273
|
+
function mergeToolCallDeltaPair(current, delta) {
|
|
16274
|
+
const currentArguments = typeof current.function?.arguments === "string" ? current.function.arguments : "";
|
|
16275
|
+
const deltaArguments = typeof delta.function?.arguments === "string" ? delta.function.arguments : "";
|
|
16276
|
+
return {
|
|
16277
|
+
...current,
|
|
16278
|
+
...delta,
|
|
16279
|
+
function: {
|
|
16280
|
+
...current.function || {},
|
|
16281
|
+
...delta.function || {},
|
|
16282
|
+
arguments: `${currentArguments}${deltaArguments}`
|
|
16283
|
+
}
|
|
16284
|
+
};
|
|
16285
|
+
}
|
|
16286
|
+
function mergeToolCallDeltas(toolCalls, deltas) {
|
|
16287
|
+
if (deltas.length === 0) {
|
|
16288
|
+
return toolCalls;
|
|
16289
|
+
}
|
|
16290
|
+
const merged = toolCalls ? [...toolCalls] : [];
|
|
16291
|
+
const indexToPosition = /* @__PURE__ */ new Map();
|
|
16292
|
+
const idToPosition = /* @__PURE__ */ new Map();
|
|
16293
|
+
for (const [position, toolCall] of merged.entries()) {
|
|
16294
|
+
const index = getToolCallIndex(toolCall);
|
|
16295
|
+
if (index !== void 0 && !indexToPosition.has(index)) {
|
|
16296
|
+
indexToPosition.set(index, position);
|
|
16297
|
+
}
|
|
16298
|
+
if (typeof toolCall.id === "string" && !idToPosition.has(toolCall.id)) {
|
|
16299
|
+
idToPosition.set(toolCall.id, position);
|
|
16300
|
+
}
|
|
16301
|
+
}
|
|
16302
|
+
for (const delta of deltas) {
|
|
16303
|
+
const deltaIndex = getToolCallIndex(delta);
|
|
16304
|
+
const existingByIndex = deltaIndex !== void 0 ? indexToPosition.get(deltaIndex) : void 0;
|
|
16305
|
+
const existingById = typeof delta.id === "string" ? idToPosition.get(delta.id) : void 0;
|
|
16306
|
+
const existingPosition = existingByIndex ?? existingById;
|
|
16307
|
+
if (existingPosition === void 0) {
|
|
16308
|
+
const newToolCall = createMergedToolCallDelta(delta);
|
|
16309
|
+
merged.push(newToolCall);
|
|
16310
|
+
const newPosition = merged.length - 1;
|
|
16311
|
+
const newIndex = getToolCallIndex(newToolCall);
|
|
16312
|
+
if (newIndex !== void 0 && !indexToPosition.has(newIndex)) {
|
|
16313
|
+
indexToPosition.set(newIndex, newPosition);
|
|
16314
|
+
}
|
|
16315
|
+
if (typeof newToolCall.id === "string" && !idToPosition.has(newToolCall.id)) {
|
|
16316
|
+
idToPosition.set(newToolCall.id, newPosition);
|
|
13884
16317
|
}
|
|
13885
16318
|
continue;
|
|
13886
16319
|
}
|
|
13887
|
-
|
|
13888
|
-
|
|
16320
|
+
const mergedToolCall = mergeToolCallDeltaPair(
|
|
16321
|
+
merged[existingPosition],
|
|
16322
|
+
delta
|
|
16323
|
+
);
|
|
16324
|
+
merged[existingPosition] = mergedToolCall;
|
|
16325
|
+
const mergedIndex = getToolCallIndex(mergedToolCall);
|
|
16326
|
+
if (mergedIndex !== void 0 && !indexToPosition.has(mergedIndex)) {
|
|
16327
|
+
indexToPosition.set(mergedIndex, existingPosition);
|
|
13889
16328
|
}
|
|
13890
|
-
if (typeof
|
|
13891
|
-
|
|
16329
|
+
if (typeof mergedToolCall.id === "string" && !idToPosition.has(mergedToolCall.id)) {
|
|
16330
|
+
idToPosition.set(mergedToolCall.id, existingPosition);
|
|
13892
16331
|
}
|
|
13893
|
-
|
|
13894
|
-
|
|
13895
|
-
|
|
13896
|
-
|
|
13897
|
-
|
|
13898
|
-
|
|
16332
|
+
}
|
|
16333
|
+
return merged.length > 0 ? merged : void 0;
|
|
16334
|
+
}
|
|
16335
|
+
function getChoiceFinishReason(choice) {
|
|
16336
|
+
if (typeof choice.finishReason === "string" || choice.finishReason === null) {
|
|
16337
|
+
return choice.finishReason;
|
|
16338
|
+
}
|
|
16339
|
+
if (typeof choice.finish_reason === "string" || choice.finish_reason === null) {
|
|
16340
|
+
return choice.finish_reason;
|
|
16341
|
+
}
|
|
16342
|
+
return void 0;
|
|
16343
|
+
}
|
|
16344
|
+
function parseMistralMetricsFromUsage(usage) {
|
|
16345
|
+
if (!isObject(usage)) {
|
|
16346
|
+
return {};
|
|
16347
|
+
}
|
|
16348
|
+
const metrics = {};
|
|
16349
|
+
for (const [name, value] of Object.entries(usage)) {
|
|
16350
|
+
if (typeof value === "number") {
|
|
16351
|
+
metrics[TOKEN_NAME_MAP4[name] || camelToSnake3(name)] = value;
|
|
16352
|
+
continue;
|
|
13899
16353
|
}
|
|
13900
|
-
|
|
13901
|
-
if (!toolCallDeltas) {
|
|
16354
|
+
if (!isObject(value)) {
|
|
13902
16355
|
continue;
|
|
13903
16356
|
}
|
|
13904
|
-
|
|
13905
|
-
|
|
16357
|
+
const prefix = TOKEN_DETAIL_PREFIX_MAP3[name];
|
|
16358
|
+
if (!prefix) {
|
|
16359
|
+
continue;
|
|
16360
|
+
}
|
|
16361
|
+
for (const [nestedName, nestedValue] of Object.entries(value)) {
|
|
16362
|
+
if (typeof nestedValue !== "number") {
|
|
13906
16363
|
continue;
|
|
13907
16364
|
}
|
|
13908
|
-
|
|
13909
|
-
|
|
13910
|
-
|
|
13911
|
-
|
|
13912
|
-
|
|
13913
|
-
|
|
13914
|
-
|
|
13915
|
-
|
|
13916
|
-
|
|
13917
|
-
|
|
13918
|
-
|
|
13919
|
-
|
|
13920
|
-
|
|
13921
|
-
|
|
16365
|
+
metrics[`${prefix}_${camelToSnake3(nestedName)}`] = nestedValue;
|
|
16366
|
+
}
|
|
16367
|
+
}
|
|
16368
|
+
return metrics;
|
|
16369
|
+
}
|
|
16370
|
+
function aggregateMistralStreamChunks(chunks) {
|
|
16371
|
+
const choiceAccumulators = /* @__PURE__ */ new Map();
|
|
16372
|
+
const indexToAccumulatorKey = /* @__PURE__ */ new Map();
|
|
16373
|
+
const positionToAccumulatorKey = /* @__PURE__ */ new Map();
|
|
16374
|
+
let nextAccumulatorOrder = 0;
|
|
16375
|
+
let metrics = {};
|
|
16376
|
+
let metadata;
|
|
16377
|
+
for (const event of chunks) {
|
|
16378
|
+
const chunk = isMistralChatCompletionChunk(event?.data) ? event.data : void 0;
|
|
16379
|
+
if (!chunk) {
|
|
16380
|
+
continue;
|
|
16381
|
+
}
|
|
16382
|
+
if (isObject(chunk.usage)) {
|
|
16383
|
+
metrics = {
|
|
16384
|
+
...metrics,
|
|
16385
|
+
...parseMistralMetricsFromUsage(chunk.usage)
|
|
16386
|
+
};
|
|
16387
|
+
}
|
|
16388
|
+
const chunkMetadata = extractMistralResponseMetadata(chunk);
|
|
16389
|
+
if (chunkMetadata) {
|
|
16390
|
+
metadata = { ...metadata || {}, ...chunkMetadata };
|
|
16391
|
+
}
|
|
16392
|
+
for (const [choicePosition, rawChoice] of (chunk.choices || []).entries()) {
|
|
16393
|
+
if (!isMistralChunkChoice(rawChoice)) {
|
|
13922
16394
|
continue;
|
|
13923
16395
|
}
|
|
13924
|
-
const
|
|
13925
|
-
|
|
13926
|
-
|
|
16396
|
+
const choice = rawChoice;
|
|
16397
|
+
const choiceIndex = typeof choice.index === "number" && choice.index >= 0 ? choice.index : void 0;
|
|
16398
|
+
let accumulatorKey = choiceIndex !== void 0 ? indexToAccumulatorKey.get(choiceIndex) : void 0;
|
|
16399
|
+
if (!accumulatorKey) {
|
|
16400
|
+
accumulatorKey = positionToAccumulatorKey.get(choicePosition);
|
|
16401
|
+
}
|
|
16402
|
+
if (!accumulatorKey) {
|
|
16403
|
+
const initialIndex = choiceIndex ?? choicePosition;
|
|
16404
|
+
const keyPrefix = choiceIndex !== void 0 ? "index" : "position";
|
|
16405
|
+
accumulatorKey = `${keyPrefix}:${initialIndex}`;
|
|
16406
|
+
choiceAccumulators.set(accumulatorKey, {
|
|
16407
|
+
index: initialIndex,
|
|
16408
|
+
order: nextAccumulatorOrder++
|
|
16409
|
+
});
|
|
13927
16410
|
}
|
|
13928
|
-
|
|
13929
|
-
|
|
16411
|
+
const accumulator = choiceAccumulators.get(accumulatorKey);
|
|
16412
|
+
if (!accumulator) {
|
|
16413
|
+
continue;
|
|
13930
16414
|
}
|
|
13931
|
-
if (
|
|
13932
|
-
|
|
16415
|
+
if (choiceIndex !== void 0) {
|
|
16416
|
+
accumulator.index = choiceIndex;
|
|
16417
|
+
indexToAccumulatorKey.set(choiceIndex, accumulatorKey);
|
|
13933
16418
|
}
|
|
13934
|
-
|
|
13935
|
-
|
|
13936
|
-
|
|
13937
|
-
|
|
13938
|
-
|
|
13939
|
-
|
|
13940
|
-
|
|
13941
|
-
|
|
13942
|
-
|
|
13943
|
-
|
|
13944
|
-
|
|
13945
|
-
|
|
13946
|
-
|
|
13947
|
-
|
|
16419
|
+
positionToAccumulatorKey.set(choicePosition, accumulatorKey);
|
|
16420
|
+
const delta = isObject(choice.delta) ? choice.delta : void 0;
|
|
16421
|
+
if (delta) {
|
|
16422
|
+
if (!accumulator.role && typeof delta.role === "string") {
|
|
16423
|
+
accumulator.role = delta.role;
|
|
16424
|
+
}
|
|
16425
|
+
const deltaText = extractDeltaText(delta.content);
|
|
16426
|
+
if (deltaText) {
|
|
16427
|
+
accumulator.content = `${accumulator.content || ""}${deltaText}`;
|
|
16428
|
+
}
|
|
16429
|
+
accumulator.toolCalls = mergeToolCallDeltas(
|
|
16430
|
+
accumulator.toolCalls,
|
|
16431
|
+
getDeltaToolCalls(delta)
|
|
16432
|
+
);
|
|
16433
|
+
}
|
|
16434
|
+
const choiceFinishReason = getChoiceFinishReason(choice);
|
|
16435
|
+
if (choiceFinishReason !== void 0) {
|
|
16436
|
+
accumulator.finishReason = choiceFinishReason;
|
|
13948
16437
|
}
|
|
13949
|
-
],
|
|
13950
|
-
metrics
|
|
13951
|
-
};
|
|
13952
|
-
}
|
|
13953
|
-
function aggregateOpenRouterResponseStreamEvents(chunks) {
|
|
13954
|
-
let finalResponse;
|
|
13955
|
-
for (const chunk of chunks) {
|
|
13956
|
-
const response = chunk?.response;
|
|
13957
|
-
if (!response) {
|
|
13958
|
-
continue;
|
|
13959
|
-
}
|
|
13960
|
-
if (chunk.type === "response.completed" || chunk.type === "response.incomplete" || chunk.type === "response.failed") {
|
|
13961
|
-
finalResponse = response;
|
|
13962
16438
|
}
|
|
13963
16439
|
}
|
|
13964
|
-
|
|
13965
|
-
|
|
13966
|
-
|
|
13967
|
-
|
|
13968
|
-
|
|
13969
|
-
|
|
16440
|
+
const output = Array.from(choiceAccumulators.values()).sort(
|
|
16441
|
+
(left, right) => left.index === right.index ? left.order - right.order : left.index - right.index
|
|
16442
|
+
).map((choice) => ({
|
|
16443
|
+
index: choice.index,
|
|
16444
|
+
message: {
|
|
16445
|
+
...choice.role ? { role: choice.role } : {},
|
|
16446
|
+
content: choice.content ?? null,
|
|
16447
|
+
...choice.toolCalls ? { toolCalls: choice.toolCalls } : {}
|
|
16448
|
+
},
|
|
16449
|
+
...choice.finishReason !== void 0 ? { finishReason: choice.finishReason } : {}
|
|
16450
|
+
}));
|
|
13970
16451
|
return {
|
|
13971
|
-
output
|
|
13972
|
-
metrics
|
|
13973
|
-
...
|
|
16452
|
+
output,
|
|
16453
|
+
metrics,
|
|
16454
|
+
...metadata ? { metadata } : {}
|
|
13974
16455
|
};
|
|
13975
16456
|
}
|
|
13976
16457
|
|
|
@@ -13983,6 +16464,8 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
13983
16464
|
claudeAgentSDKPlugin = null;
|
|
13984
16465
|
googleGenAIPlugin = null;
|
|
13985
16466
|
openRouterPlugin = null;
|
|
16467
|
+
openRouterAgentPlugin = null;
|
|
16468
|
+
mistralPlugin = null;
|
|
13986
16469
|
constructor(config = {}) {
|
|
13987
16470
|
super();
|
|
13988
16471
|
this.config = config;
|
|
@@ -14013,6 +16496,14 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
14013
16496
|
this.openRouterPlugin = new OpenRouterPlugin();
|
|
14014
16497
|
this.openRouterPlugin.enable();
|
|
14015
16498
|
}
|
|
16499
|
+
if (integrations.openrouterAgent !== false) {
|
|
16500
|
+
this.openRouterAgentPlugin = new OpenRouterAgentPlugin();
|
|
16501
|
+
this.openRouterAgentPlugin.enable();
|
|
16502
|
+
}
|
|
16503
|
+
if (integrations.mistral !== false) {
|
|
16504
|
+
this.mistralPlugin = new MistralPlugin();
|
|
16505
|
+
this.mistralPlugin.enable();
|
|
16506
|
+
}
|
|
14016
16507
|
}
|
|
14017
16508
|
onDisable() {
|
|
14018
16509
|
if (this.openaiPlugin) {
|
|
@@ -14039,6 +16530,14 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
14039
16530
|
this.openRouterPlugin.disable();
|
|
14040
16531
|
this.openRouterPlugin = null;
|
|
14041
16532
|
}
|
|
16533
|
+
if (this.openRouterAgentPlugin) {
|
|
16534
|
+
this.openRouterAgentPlugin.disable();
|
|
16535
|
+
this.openRouterAgentPlugin = null;
|
|
16536
|
+
}
|
|
16537
|
+
if (this.mistralPlugin) {
|
|
16538
|
+
this.mistralPlugin.disable();
|
|
16539
|
+
this.mistralPlugin = null;
|
|
16540
|
+
}
|
|
14042
16541
|
}
|
|
14043
16542
|
};
|
|
14044
16543
|
|
|
@@ -14111,7 +16610,9 @@ var PluginRegistry = class {
|
|
|
14111
16610
|
aisdk: true,
|
|
14112
16611
|
google: true,
|
|
14113
16612
|
claudeAgentSDK: true,
|
|
14114
|
-
openrouter: true
|
|
16613
|
+
openrouter: true,
|
|
16614
|
+
openrouterAgent: true,
|
|
16615
|
+
mistral: true
|
|
14115
16616
|
};
|
|
14116
16617
|
}
|
|
14117
16618
|
/**
|
|
@@ -14246,7 +16747,7 @@ function isAsync(fn) {
|
|
|
14246
16747
|
function isAsyncGenerator2(fn) {
|
|
14247
16748
|
return fn[Symbol.toStringTag] === "AsyncGenerator";
|
|
14248
16749
|
}
|
|
14249
|
-
function
|
|
16750
|
+
function isAsyncIterable5(obj) {
|
|
14250
16751
|
return typeof obj[Symbol.asyncIterator] === "function";
|
|
14251
16752
|
}
|
|
14252
16753
|
function wrapAsync(asyncFn) {
|
|
@@ -14296,7 +16797,7 @@ function _asyncMap(eachfn, arr, iteratee, callback) {
|
|
|
14296
16797
|
callback(err, results);
|
|
14297
16798
|
});
|
|
14298
16799
|
}
|
|
14299
|
-
function
|
|
16800
|
+
function isArrayLike4(value) {
|
|
14300
16801
|
return value && typeof value.length === "number" && value.length >= 0 && value.length % 1 === 0;
|
|
14301
16802
|
}
|
|
14302
16803
|
var breakLoop = {};
|
|
@@ -14344,7 +16845,7 @@ function createObjectIterator(obj) {
|
|
|
14344
16845
|
};
|
|
14345
16846
|
}
|
|
14346
16847
|
function createIterator(coll) {
|
|
14347
|
-
if (
|
|
16848
|
+
if (isArrayLike4(coll)) {
|
|
14348
16849
|
return createArrayIterator(coll);
|
|
14349
16850
|
}
|
|
14350
16851
|
var iterator = getIterator(coll);
|
|
@@ -14418,7 +16919,7 @@ var eachOfLimit$2 = (limit) => {
|
|
|
14418
16919
|
if (isAsyncGenerator2(obj)) {
|
|
14419
16920
|
return asyncEachOfLimit(obj, limit, iteratee, callback);
|
|
14420
16921
|
}
|
|
14421
|
-
if (
|
|
16922
|
+
if (isAsyncIterable5(obj)) {
|
|
14422
16923
|
return asyncEachOfLimit(obj[Symbol.asyncIterator](), limit, iteratee, callback);
|
|
14423
16924
|
}
|
|
14424
16925
|
var nextElem = createIterator(obj);
|
|
@@ -14490,7 +16991,7 @@ function eachOfGeneric(coll, iteratee, callback) {
|
|
|
14490
16991
|
return eachOfLimit$1(coll, Infinity, iteratee, callback);
|
|
14491
16992
|
}
|
|
14492
16993
|
function eachOf(coll, iteratee, callback) {
|
|
14493
|
-
var eachOfImplementation =
|
|
16994
|
+
var eachOfImplementation = isArrayLike4(coll) ? eachOfArrayLike : eachOfGeneric;
|
|
14494
16995
|
return eachOfImplementation(coll, wrapAsync(iteratee), callback);
|
|
14495
16996
|
}
|
|
14496
16997
|
var eachOf$1 = awaitify(eachOf, 3);
|
|
@@ -15005,7 +17506,7 @@ function filterGeneric(eachfn, coll, iteratee, callback) {
|
|
|
15005
17506
|
});
|
|
15006
17507
|
}
|
|
15007
17508
|
function _filter(eachfn, coll, iteratee, callback) {
|
|
15008
|
-
var filter2 =
|
|
17509
|
+
var filter2 = isArrayLike4(coll) ? filterArray : filterGeneric;
|
|
15009
17510
|
return filter2(eachfn, coll, wrapAsync(iteratee), callback);
|
|
15010
17511
|
}
|
|
15011
17512
|
function filter(coll, iteratee, callback) {
|
|
@@ -15080,7 +17581,7 @@ if (hasNextTick) {
|
|
|
15080
17581
|
}
|
|
15081
17582
|
var nextTick = wrap(_defer);
|
|
15082
17583
|
var _parallel = awaitify((eachfn, tasks, callback) => {
|
|
15083
|
-
var results =
|
|
17584
|
+
var results = isArrayLike4(tasks) ? [] : {};
|
|
15084
17585
|
eachfn(tasks, (task, key, taskCb) => {
|
|
15085
17586
|
wrapAsync(task)((err, ...result) => {
|
|
15086
17587
|
if (result.length < 2) {
|
|
@@ -15695,7 +18196,28 @@ function validateParametersWithJsonSchema(parameters, schema) {
|
|
|
15695
18196
|
}).join(", ");
|
|
15696
18197
|
throw Error(`Invalid parameters: ${errorMessages}`);
|
|
15697
18198
|
}
|
|
15698
|
-
return parameters;
|
|
18199
|
+
return rehydrateRemoteParameters(parameters, schema);
|
|
18200
|
+
}
|
|
18201
|
+
function rehydrateRemoteParameters(parameters, schema) {
|
|
18202
|
+
const schemaProperties = schema.properties;
|
|
18203
|
+
if (typeof schemaProperties !== "object" || schemaProperties === null) {
|
|
18204
|
+
return parameters;
|
|
18205
|
+
}
|
|
18206
|
+
return Object.fromEntries(
|
|
18207
|
+
Object.entries(parameters).map(([name, value]) => {
|
|
18208
|
+
const propertySchema = Reflect.get(schemaProperties, name);
|
|
18209
|
+
if (typeof propertySchema !== "object" || propertySchema === null) {
|
|
18210
|
+
return [name, value];
|
|
18211
|
+
}
|
|
18212
|
+
if (Reflect.get(propertySchema, "x-bt-type") === "prompt") {
|
|
18213
|
+
return [
|
|
18214
|
+
name,
|
|
18215
|
+
Prompt2.fromPromptData(name, PromptData.parse(value))
|
|
18216
|
+
];
|
|
18217
|
+
}
|
|
18218
|
+
return [name, value];
|
|
18219
|
+
})
|
|
18220
|
+
);
|
|
15699
18221
|
}
|
|
15700
18222
|
|
|
15701
18223
|
// src/framework.ts
|
|
@@ -15761,7 +18283,7 @@ function callEvaluatorData(data) {
|
|
|
15761
18283
|
baseExperiment
|
|
15762
18284
|
};
|
|
15763
18285
|
}
|
|
15764
|
-
function
|
|
18286
|
+
function isAsyncIterable6(value) {
|
|
15765
18287
|
return typeof value === "object" && value !== null && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
15766
18288
|
}
|
|
15767
18289
|
function isIterable(value) {
|
|
@@ -15966,7 +18488,7 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
|
|
|
15966
18488
|
}
|
|
15967
18489
|
const resolvedDataResult = dataResult instanceof Promise ? await dataResult : dataResult;
|
|
15968
18490
|
const dataIterable = (() => {
|
|
15969
|
-
if (
|
|
18491
|
+
if (isAsyncIterable6(resolvedDataResult)) {
|
|
15970
18492
|
return resolvedDataResult;
|
|
15971
18493
|
}
|
|
15972
18494
|
if (Array.isArray(resolvedDataResult) || isIterable(resolvedDataResult)) {
|
|
@@ -16766,7 +19288,7 @@ var parametersContainerSchema = z12.object({
|
|
|
16766
19288
|
var staticParametersContainerSchema = z12.object({
|
|
16767
19289
|
type: z12.literal("braintrust.staticParameters"),
|
|
16768
19290
|
schema: staticParametersSchema,
|
|
16769
|
-
source: z12.null()
|
|
19291
|
+
source: z12.null().nullish()
|
|
16770
19292
|
});
|
|
16771
19293
|
var serializedParametersContainerSchema = z12.union([
|
|
16772
19294
|
parametersContainerSchema,
|
|
@@ -16930,7 +19452,8 @@ var ScorerBuilder = class {
|
|
|
16930
19452
|
type: "llm_classifier",
|
|
16931
19453
|
use_cot: opts.useCot,
|
|
16932
19454
|
choice_scores: opts.choiceScores
|
|
16933
|
-
}
|
|
19455
|
+
},
|
|
19456
|
+
...opts.templateFormat ? { template_format: opts.templateFormat } : {}
|
|
16934
19457
|
};
|
|
16935
19458
|
const codePrompt = new CodePrompt(
|
|
16936
19459
|
this.project,
|