braintrust 3.7.1 → 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 +2432 -430
- package/dev/dist/index.mjs +2307 -305
- package/dist/auto-instrumentations/bundler/esbuild.cjs +377 -10
- package/dist/auto-instrumentations/bundler/esbuild.mjs +2 -2
- package/dist/auto-instrumentations/bundler/rollup.cjs +377 -10
- package/dist/auto-instrumentations/bundler/rollup.mjs +2 -2
- package/dist/auto-instrumentations/bundler/vite.cjs +377 -10
- package/dist/auto-instrumentations/bundler/vite.mjs +2 -2
- package/dist/auto-instrumentations/bundler/webpack-loader.cjs +377 -10
- package/dist/auto-instrumentations/bundler/webpack-loader.d.ts +11 -9
- package/dist/auto-instrumentations/bundler/webpack.cjs +377 -10
- 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-NY4CGTN6.mjs → chunk-MD7W27YH.mjs} +5 -1
- package/dist/auto-instrumentations/{chunk-YCKND42U.mjs → chunk-OLBMPZXE.mjs} +378 -11
- package/dist/auto-instrumentations/{chunk-VLEJ5AEK.mjs → chunk-P5YLNB2A.mjs} +21 -3
- package/dist/auto-instrumentations/hook.mjs +393 -16
- package/dist/auto-instrumentations/index.cjs +379 -10
- 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 +191 -14
- package/dist/browser.d.ts +191 -14
- package/dist/browser.js +2646 -315
- package/dist/browser.mjs +2646 -315
- package/dist/cli.js +2411 -409
- package/dist/edge-light.d.mts +1 -1
- package/dist/edge-light.d.ts +1 -1
- package/dist/edge-light.js +12604 -10184
- package/dist/edge-light.mjs +12604 -10184
- package/dist/index.d.mts +191 -14
- package/dist/index.d.ts +191 -14
- package/dist/index.js +2823 -492
- package/dist/index.mjs +2646 -315
- package/dist/instrumentation/index.d.mts +7 -0
- package/dist/instrumentation/index.d.ts +7 -0
- package/dist/instrumentation/index.js +2409 -407
- package/dist/instrumentation/index.mjs +2409 -407
- package/dist/workerd.d.mts +1 -1
- package/dist/workerd.d.ts +1 -1
- package/dist/workerd.js +12604 -10184
- package/dist/workerd.mjs +12604 -10184
- package/package.json +44 -44
package/dist/browser.js
CHANGED
|
@@ -32,6 +32,7 @@ var browser_exports = {};
|
|
|
32
32
|
__export(browser_exports, {
|
|
33
33
|
Attachment: () => Attachment,
|
|
34
34
|
AttachmentReference: () => AttachmentReference,
|
|
35
|
+
BRAINTRUST_CURRENT_SPAN_STORE: () => BRAINTRUST_CURRENT_SPAN_STORE,
|
|
35
36
|
BaseAttachment: () => BaseAttachment,
|
|
36
37
|
BaseExperiment: () => BaseExperiment,
|
|
37
38
|
BraintrustMiddleware: () => BraintrustMiddleware,
|
|
@@ -159,9 +160,11 @@ __export(browser_exports, {
|
|
|
159
160
|
wrapClaudeAgentSDK: () => wrapClaudeAgentSDK,
|
|
160
161
|
wrapGoogleGenAI: () => wrapGoogleGenAI,
|
|
161
162
|
wrapMastraAgent: () => wrapMastraAgent,
|
|
163
|
+
wrapMistral: () => wrapMistral,
|
|
162
164
|
wrapOpenAI: () => wrapOpenAI,
|
|
163
165
|
wrapOpenAIv4: () => wrapOpenAIv4,
|
|
164
166
|
wrapOpenRouter: () => wrapOpenRouter,
|
|
167
|
+
wrapOpenRouterAgent: () => wrapOpenRouterAgent,
|
|
165
168
|
wrapTraced: () => wrapTraced,
|
|
166
169
|
wrapVitest: () => wrapVitest
|
|
167
170
|
});
|
|
@@ -1954,6 +1957,16 @@ var NullableSavedFunctionId = import_v36.z.union([
|
|
|
1954
1957
|
}),
|
|
1955
1958
|
import_v36.z.null()
|
|
1956
1959
|
]);
|
|
1960
|
+
var TopicMapGenerationSettings = import_v36.z.object({
|
|
1961
|
+
algorithm: import_v36.z.enum(["hdbscan", "kmeans"]),
|
|
1962
|
+
dimension_reduction: import_v36.z.enum(["umap", "pca", "none"]),
|
|
1963
|
+
sample_size: import_v36.z.number().int().gt(0).optional(),
|
|
1964
|
+
n_clusters: import_v36.z.number().int().gt(0).optional(),
|
|
1965
|
+
min_cluster_size: import_v36.z.number().int().gt(0).optional(),
|
|
1966
|
+
min_samples: import_v36.z.number().int().gt(0).optional(),
|
|
1967
|
+
hierarchy_threshold: import_v36.z.number().int().gt(0).optional(),
|
|
1968
|
+
naming_model: import_v36.z.string().optional()
|
|
1969
|
+
});
|
|
1957
1970
|
var TopicMapData = import_v36.z.object({
|
|
1958
1971
|
type: import_v36.z.literal("topic_map"),
|
|
1959
1972
|
source_facet: import_v36.z.string(),
|
|
@@ -1961,6 +1974,7 @@ var TopicMapData = import_v36.z.object({
|
|
|
1961
1974
|
bundle_key: import_v36.z.string().optional(),
|
|
1962
1975
|
report_key: import_v36.z.string().optional(),
|
|
1963
1976
|
topic_names: import_v36.z.record(import_v36.z.string()).optional(),
|
|
1977
|
+
generation_settings: TopicMapGenerationSettings.optional(),
|
|
1964
1978
|
distance_threshold: import_v36.z.number().optional()
|
|
1965
1979
|
});
|
|
1966
1980
|
var BatchedFacetData = import_v36.z.object({
|
|
@@ -2185,6 +2199,7 @@ var Dataset = import_v36.z.object({
|
|
|
2185
2199
|
created: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
|
|
2186
2200
|
deleted_at: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
|
|
2187
2201
|
user_id: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
|
|
2202
|
+
tags: import_v36.z.union([import_v36.z.array(import_v36.z.string()), import_v36.z.null()]).optional(),
|
|
2188
2203
|
metadata: import_v36.z.union([import_v36.z.object({}).partial().passthrough(), import_v36.z.null()]).optional(),
|
|
2189
2204
|
url_slug: import_v36.z.string()
|
|
2190
2205
|
});
|
|
@@ -2267,6 +2282,14 @@ var DatasetEvent = import_v36.z.object({
|
|
|
2267
2282
|
import_v36.z.null()
|
|
2268
2283
|
]).optional()
|
|
2269
2284
|
});
|
|
2285
|
+
var DatasetSnapshot = import_v36.z.object({
|
|
2286
|
+
id: import_v36.z.string().uuid(),
|
|
2287
|
+
dataset_id: import_v36.z.string().uuid(),
|
|
2288
|
+
name: import_v36.z.string(),
|
|
2289
|
+
description: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]),
|
|
2290
|
+
xact_id: import_v36.z.string(),
|
|
2291
|
+
created: import_v36.z.union([import_v36.z.string(), import_v36.z.null()])
|
|
2292
|
+
});
|
|
2270
2293
|
var EnvVar = import_v36.z.object({
|
|
2271
2294
|
id: import_v36.z.string().uuid(),
|
|
2272
2295
|
object_type: import_v36.z.enum(["organization", "project", "function"]),
|
|
@@ -3025,6 +3048,8 @@ var TopicAutomationConfig = import_v36.z.object({
|
|
|
3025
3048
|
scope: import_v36.z.union([SpanScope, TraceScope, GroupScope, import_v36.z.null()]).optional(),
|
|
3026
3049
|
data_scope: TopicAutomationDataScope.optional(),
|
|
3027
3050
|
btql_filter: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
|
|
3051
|
+
rerun_seconds: import_v36.z.union([import_v36.z.number(), import_v36.z.null()]).optional(),
|
|
3052
|
+
relabel_overlap_seconds: import_v36.z.union([import_v36.z.number(), import_v36.z.null()]).optional(),
|
|
3028
3053
|
backfill_time_range: import_v36.z.union([
|
|
3029
3054
|
import_v36.z.string(),
|
|
3030
3055
|
import_v36.z.object({ from: import_v36.z.string(), to: import_v36.z.string() }),
|
|
@@ -3361,7 +3386,8 @@ var User = import_v36.z.object({
|
|
|
3361
3386
|
family_name: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
|
|
3362
3387
|
email: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
|
|
3363
3388
|
avatar_url: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
|
|
3364
|
-
created: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional()
|
|
3389
|
+
created: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
|
|
3390
|
+
last_active_at: import_v36.z.union([import_v36.z.number(), import_v36.z.null()]).optional()
|
|
3365
3391
|
});
|
|
3366
3392
|
var ViewDataSearch = import_v36.z.union([
|
|
3367
3393
|
import_v36.z.object({
|
|
@@ -4519,6 +4545,15 @@ var BRAINTRUST_CURRENT_SPAN_STORE = Symbol.for(
|
|
|
4519
4545
|
"braintrust.currentSpanStore"
|
|
4520
4546
|
);
|
|
4521
4547
|
var ContextManager = class {
|
|
4548
|
+
/**
|
|
4549
|
+
* Returns the value to store in the ALS bound to a TracingChannel's start event.
|
|
4550
|
+
* In default mode this is the Span itself; in OTEL mode it is the OTEL Context
|
|
4551
|
+
* containing the span so that OTEL's own ALS stores a proper Context object.
|
|
4552
|
+
*/
|
|
4553
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4554
|
+
wrapSpanForStore(span) {
|
|
4555
|
+
return span;
|
|
4556
|
+
}
|
|
4522
4557
|
};
|
|
4523
4558
|
var BraintrustContextManager = class extends ContextManager {
|
|
4524
4559
|
_currentSpan;
|
|
@@ -10092,18 +10127,22 @@ function ensureSpanStateForEvent(states, config, event, channelName) {
|
|
|
10092
10127
|
function bindCurrentSpanStoreToStart(tracingChannel2, states, config, channelName) {
|
|
10093
10128
|
const state = _internalGetGlobalState();
|
|
10094
10129
|
const startChannel = tracingChannel2.start;
|
|
10095
|
-
const
|
|
10130
|
+
const contextManager = state?.contextManager;
|
|
10131
|
+
const currentSpanStore = contextManager ? contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
|
|
10096
10132
|
if (!currentSpanStore || !startChannel) {
|
|
10097
10133
|
return void 0;
|
|
10098
10134
|
}
|
|
10099
10135
|
startChannel.bindStore(
|
|
10100
10136
|
currentSpanStore,
|
|
10101
|
-
(event) =>
|
|
10102
|
-
|
|
10103
|
-
|
|
10104
|
-
|
|
10105
|
-
|
|
10106
|
-
|
|
10137
|
+
(event) => {
|
|
10138
|
+
const span = ensureSpanStateForEvent(
|
|
10139
|
+
states,
|
|
10140
|
+
config,
|
|
10141
|
+
event,
|
|
10142
|
+
channelName
|
|
10143
|
+
).span;
|
|
10144
|
+
return contextManager.wrapSpanForStore(span);
|
|
10145
|
+
}
|
|
10107
10146
|
);
|
|
10108
10147
|
return () => {
|
|
10109
10148
|
startChannel.unbindStore(currentSpanStore);
|
|
@@ -10120,6 +10159,26 @@ function logErrorAndEnd(states, event) {
|
|
|
10120
10159
|
spanData.span.end();
|
|
10121
10160
|
states.delete(event);
|
|
10122
10161
|
}
|
|
10162
|
+
function runStreamingCompletionHook(args) {
|
|
10163
|
+
if (!args.config.onComplete) {
|
|
10164
|
+
return;
|
|
10165
|
+
}
|
|
10166
|
+
try {
|
|
10167
|
+
args.config.onComplete({
|
|
10168
|
+
channelName: args.channelName,
|
|
10169
|
+
...args.chunks ? { chunks: args.chunks } : {},
|
|
10170
|
+
endEvent: args.endEvent,
|
|
10171
|
+
...args.metadata !== void 0 ? { metadata: args.metadata } : {},
|
|
10172
|
+
metrics: args.metrics,
|
|
10173
|
+
output: args.output,
|
|
10174
|
+
result: args.result,
|
|
10175
|
+
span: args.span,
|
|
10176
|
+
startTime: args.startTime
|
|
10177
|
+
});
|
|
10178
|
+
} catch (error) {
|
|
10179
|
+
console.error(`Error in onComplete hook for ${args.channelName}:`, error);
|
|
10180
|
+
}
|
|
10181
|
+
}
|
|
10123
10182
|
function traceAsyncChannel(channel2, config) {
|
|
10124
10183
|
const tracingChannel2 = channel2.tracingChannel();
|
|
10125
10184
|
const states = /* @__PURE__ */ new WeakMap();
|
|
@@ -10247,6 +10306,18 @@ function traceStreamingChannel(channel2, config) {
|
|
|
10247
10306
|
} else if (metrics.time_to_first_token === void 0 && chunks.length > 0) {
|
|
10248
10307
|
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
10249
10308
|
}
|
|
10309
|
+
runStreamingCompletionHook({
|
|
10310
|
+
channelName,
|
|
10311
|
+
chunks,
|
|
10312
|
+
config,
|
|
10313
|
+
endEvent: asyncEndEvent,
|
|
10314
|
+
...metadata !== void 0 ? { metadata } : {},
|
|
10315
|
+
metrics,
|
|
10316
|
+
output,
|
|
10317
|
+
result: asyncEndEvent.result,
|
|
10318
|
+
span,
|
|
10319
|
+
startTime
|
|
10320
|
+
});
|
|
10250
10321
|
span.log({
|
|
10251
10322
|
output,
|
|
10252
10323
|
...metadata !== void 0 ? { metadata } : {},
|
|
@@ -10296,6 +10367,17 @@ function traceStreamingChannel(channel2, config) {
|
|
|
10296
10367
|
asyncEndEvent.result,
|
|
10297
10368
|
asyncEndEvent
|
|
10298
10369
|
);
|
|
10370
|
+
runStreamingCompletionHook({
|
|
10371
|
+
channelName,
|
|
10372
|
+
config,
|
|
10373
|
+
endEvent: asyncEndEvent,
|
|
10374
|
+
...normalizeMetadata(metadata) !== void 0 ? { metadata: normalizeMetadata(metadata) } : {},
|
|
10375
|
+
metrics,
|
|
10376
|
+
output,
|
|
10377
|
+
result: asyncEndEvent.result,
|
|
10378
|
+
span,
|
|
10379
|
+
startTime
|
|
10380
|
+
});
|
|
10299
10381
|
span.log({
|
|
10300
10382
|
output,
|
|
10301
10383
|
...normalizeMetadata(metadata) !== void 0 ? { metadata: normalizeMetadata(metadata) } : {},
|
|
@@ -10679,6 +10761,10 @@ var openAIChannels = defineChannels("openai", {
|
|
|
10679
10761
|
responsesParse: channel({
|
|
10680
10762
|
channelName: "responses.parse",
|
|
10681
10763
|
kind: "async"
|
|
10764
|
+
}),
|
|
10765
|
+
responsesCompact: channel({
|
|
10766
|
+
channelName: "responses.compact",
|
|
10767
|
+
kind: "async"
|
|
10682
10768
|
})
|
|
10683
10769
|
});
|
|
10684
10770
|
|
|
@@ -10958,6 +11044,40 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
10958
11044
|
aggregateChunks: aggregateResponseStreamEvents
|
|
10959
11045
|
})
|
|
10960
11046
|
);
|
|
11047
|
+
this.unsubscribers.push(
|
|
11048
|
+
traceAsyncChannel(openAIChannels.responsesCompact, {
|
|
11049
|
+
name: "openai.responses.compact",
|
|
11050
|
+
type: "llm" /* LLM */,
|
|
11051
|
+
extractInput: ([params]) => {
|
|
11052
|
+
const { input, ...metadata } = params;
|
|
11053
|
+
return {
|
|
11054
|
+
input: processInputAttachments(input),
|
|
11055
|
+
metadata: { ...metadata, provider: "openai" }
|
|
11056
|
+
};
|
|
11057
|
+
},
|
|
11058
|
+
extractOutput: (result) => {
|
|
11059
|
+
return processImagesInOutput(result?.output);
|
|
11060
|
+
},
|
|
11061
|
+
extractMetadata: (result) => {
|
|
11062
|
+
if (!result) {
|
|
11063
|
+
return void 0;
|
|
11064
|
+
}
|
|
11065
|
+
const { output: _output, usage: _usage, ...metadata } = result;
|
|
11066
|
+
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
11067
|
+
},
|
|
11068
|
+
extractMetrics: (result, startTime, endEvent) => {
|
|
11069
|
+
const metrics = withCachedMetric(
|
|
11070
|
+
parseMetricsFromUsage(result?.usage),
|
|
11071
|
+
result,
|
|
11072
|
+
endEvent
|
|
11073
|
+
);
|
|
11074
|
+
if (startTime) {
|
|
11075
|
+
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
11076
|
+
}
|
|
11077
|
+
return metrics;
|
|
11078
|
+
}
|
|
11079
|
+
})
|
|
11080
|
+
);
|
|
10961
11081
|
}
|
|
10962
11082
|
onDisable() {
|
|
10963
11083
|
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
@@ -11547,6 +11667,10 @@ var aiSDKChannels = defineChannels("ai", {
|
|
|
11547
11667
|
channelName: "streamText",
|
|
11548
11668
|
kind: "async"
|
|
11549
11669
|
}),
|
|
11670
|
+
streamTextSync: channel({
|
|
11671
|
+
channelName: "streamText.sync",
|
|
11672
|
+
kind: "sync-stream"
|
|
11673
|
+
}),
|
|
11550
11674
|
generateObject: channel({
|
|
11551
11675
|
channelName: "generateObject",
|
|
11552
11676
|
kind: "async"
|
|
@@ -11555,6 +11679,20 @@ var aiSDKChannels = defineChannels("ai", {
|
|
|
11555
11679
|
channelName: "streamObject",
|
|
11556
11680
|
kind: "async"
|
|
11557
11681
|
}),
|
|
11682
|
+
streamObjectSync: channel({
|
|
11683
|
+
channelName: "streamObject.sync",
|
|
11684
|
+
kind: "sync-stream"
|
|
11685
|
+
}),
|
|
11686
|
+
embed: channel(
|
|
11687
|
+
{
|
|
11688
|
+
channelName: "embed",
|
|
11689
|
+
kind: "async"
|
|
11690
|
+
}
|
|
11691
|
+
),
|
|
11692
|
+
embedMany: channel({
|
|
11693
|
+
channelName: "embedMany",
|
|
11694
|
+
kind: "async"
|
|
11695
|
+
}),
|
|
11558
11696
|
agentGenerate: channel({
|
|
11559
11697
|
channelName: "Agent.generate",
|
|
11560
11698
|
kind: "async"
|
|
@@ -11563,6 +11701,10 @@ var aiSDKChannels = defineChannels("ai", {
|
|
|
11563
11701
|
channelName: "Agent.stream",
|
|
11564
11702
|
kind: "async"
|
|
11565
11703
|
}),
|
|
11704
|
+
agentStreamSync: channel({
|
|
11705
|
+
channelName: "Agent.stream.sync",
|
|
11706
|
+
kind: "sync-stream"
|
|
11707
|
+
}),
|
|
11566
11708
|
toolLoopAgentGenerate: channel({
|
|
11567
11709
|
channelName: "ToolLoopAgent.generate",
|
|
11568
11710
|
kind: "async"
|
|
@@ -11611,7 +11753,7 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
11611
11753
|
traceStreamingChannel(aiSDKChannels.generateText, {
|
|
11612
11754
|
name: "generateText",
|
|
11613
11755
|
type: "llm" /* LLM */,
|
|
11614
|
-
extractInput: ([params], event, span) =>
|
|
11756
|
+
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
11615
11757
|
extractOutput: (result, endEvent) => {
|
|
11616
11758
|
finalizeAISDKChildTracing(endEvent);
|
|
11617
11759
|
return processAISDKOutput(
|
|
@@ -11627,7 +11769,7 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
11627
11769
|
traceStreamingChannel(aiSDKChannels.streamText, {
|
|
11628
11770
|
name: "streamText",
|
|
11629
11771
|
type: "llm" /* LLM */,
|
|
11630
|
-
extractInput: ([params], event, span) =>
|
|
11772
|
+
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
11631
11773
|
extractOutput: (result, endEvent) => processAISDKOutput(
|
|
11632
11774
|
result,
|
|
11633
11775
|
resolveDenyOutputPaths(endEvent, denyOutputPaths)
|
|
@@ -11643,11 +11785,25 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
11643
11785
|
})
|
|
11644
11786
|
})
|
|
11645
11787
|
);
|
|
11788
|
+
this.unsubscribers.push(
|
|
11789
|
+
traceSyncStreamChannel(aiSDKChannels.streamTextSync, {
|
|
11790
|
+
name: "streamText",
|
|
11791
|
+
type: "llm" /* LLM */,
|
|
11792
|
+
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
11793
|
+
patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
|
|
11794
|
+
defaultDenyOutputPaths: denyOutputPaths,
|
|
11795
|
+
endEvent,
|
|
11796
|
+
result,
|
|
11797
|
+
span,
|
|
11798
|
+
startTime
|
|
11799
|
+
})
|
|
11800
|
+
})
|
|
11801
|
+
);
|
|
11646
11802
|
this.unsubscribers.push(
|
|
11647
11803
|
traceStreamingChannel(aiSDKChannels.generateObject, {
|
|
11648
11804
|
name: "generateObject",
|
|
11649
11805
|
type: "llm" /* LLM */,
|
|
11650
|
-
extractInput: ([params], event, span) =>
|
|
11806
|
+
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
11651
11807
|
extractOutput: (result, endEvent) => {
|
|
11652
11808
|
finalizeAISDKChildTracing(endEvent);
|
|
11653
11809
|
return processAISDKOutput(
|
|
@@ -11663,7 +11819,7 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
11663
11819
|
traceStreamingChannel(aiSDKChannels.streamObject, {
|
|
11664
11820
|
name: "streamObject",
|
|
11665
11821
|
type: "llm" /* LLM */,
|
|
11666
|
-
extractInput: ([params], event, span) =>
|
|
11822
|
+
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
11667
11823
|
extractOutput: (result, endEvent) => processAISDKOutput(
|
|
11668
11824
|
result,
|
|
11669
11825
|
resolveDenyOutputPaths(endEvent, denyOutputPaths)
|
|
@@ -11679,11 +11835,49 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
11679
11835
|
})
|
|
11680
11836
|
})
|
|
11681
11837
|
);
|
|
11838
|
+
this.unsubscribers.push(
|
|
11839
|
+
traceSyncStreamChannel(aiSDKChannels.streamObjectSync, {
|
|
11840
|
+
name: "streamObject",
|
|
11841
|
+
type: "llm" /* LLM */,
|
|
11842
|
+
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
11843
|
+
patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
|
|
11844
|
+
defaultDenyOutputPaths: denyOutputPaths,
|
|
11845
|
+
endEvent,
|
|
11846
|
+
result,
|
|
11847
|
+
span,
|
|
11848
|
+
startTime
|
|
11849
|
+
})
|
|
11850
|
+
})
|
|
11851
|
+
);
|
|
11852
|
+
this.unsubscribers.push(
|
|
11853
|
+
traceAsyncChannel(aiSDKChannels.embed, {
|
|
11854
|
+
name: "embed",
|
|
11855
|
+
type: "llm" /* LLM */,
|
|
11856
|
+
extractInput: ([params], event) => prepareAISDKEmbedInput(params, event.self),
|
|
11857
|
+
extractOutput: (result, endEvent) => processAISDKEmbeddingOutput(
|
|
11858
|
+
result,
|
|
11859
|
+
resolveDenyOutputPaths(endEvent, denyOutputPaths)
|
|
11860
|
+
),
|
|
11861
|
+
extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent)
|
|
11862
|
+
})
|
|
11863
|
+
);
|
|
11864
|
+
this.unsubscribers.push(
|
|
11865
|
+
traceAsyncChannel(aiSDKChannels.embedMany, {
|
|
11866
|
+
name: "embedMany",
|
|
11867
|
+
type: "llm" /* LLM */,
|
|
11868
|
+
extractInput: ([params], event) => prepareAISDKEmbedInput(params, event.self),
|
|
11869
|
+
extractOutput: (result, endEvent) => processAISDKEmbeddingOutput(
|
|
11870
|
+
result,
|
|
11871
|
+
resolveDenyOutputPaths(endEvent, denyOutputPaths)
|
|
11872
|
+
),
|
|
11873
|
+
extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent)
|
|
11874
|
+
})
|
|
11875
|
+
);
|
|
11682
11876
|
this.unsubscribers.push(
|
|
11683
11877
|
traceStreamingChannel(aiSDKChannels.agentGenerate, {
|
|
11684
11878
|
name: "Agent.generate",
|
|
11685
11879
|
type: "llm" /* LLM */,
|
|
11686
|
-
extractInput: ([params], event, span) =>
|
|
11880
|
+
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
11687
11881
|
extractOutput: (result, endEvent) => {
|
|
11688
11882
|
finalizeAISDKChildTracing(endEvent);
|
|
11689
11883
|
return processAISDKOutput(
|
|
@@ -11699,7 +11893,7 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
11699
11893
|
traceStreamingChannel(aiSDKChannels.agentStream, {
|
|
11700
11894
|
name: "Agent.stream",
|
|
11701
11895
|
type: "llm" /* LLM */,
|
|
11702
|
-
extractInput: ([params], event, span) =>
|
|
11896
|
+
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
11703
11897
|
extractOutput: (result, endEvent) => processAISDKOutput(
|
|
11704
11898
|
result,
|
|
11705
11899
|
resolveDenyOutputPaths(endEvent, denyOutputPaths)
|
|
@@ -11715,11 +11909,25 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
11715
11909
|
})
|
|
11716
11910
|
})
|
|
11717
11911
|
);
|
|
11912
|
+
this.unsubscribers.push(
|
|
11913
|
+
traceSyncStreamChannel(aiSDKChannels.agentStreamSync, {
|
|
11914
|
+
name: "Agent.stream",
|
|
11915
|
+
type: "llm" /* LLM */,
|
|
11916
|
+
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
11917
|
+
patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
|
|
11918
|
+
defaultDenyOutputPaths: denyOutputPaths,
|
|
11919
|
+
endEvent,
|
|
11920
|
+
result,
|
|
11921
|
+
span,
|
|
11922
|
+
startTime
|
|
11923
|
+
})
|
|
11924
|
+
})
|
|
11925
|
+
);
|
|
11718
11926
|
this.unsubscribers.push(
|
|
11719
11927
|
traceStreamingChannel(aiSDKChannels.toolLoopAgentGenerate, {
|
|
11720
11928
|
name: "ToolLoopAgent.generate",
|
|
11721
11929
|
type: "llm" /* LLM */,
|
|
11722
|
-
extractInput: ([params], event, span) =>
|
|
11930
|
+
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
11723
11931
|
extractOutput: (result, endEvent) => {
|
|
11724
11932
|
finalizeAISDKChildTracing(endEvent);
|
|
11725
11933
|
return processAISDKOutput(
|
|
@@ -11735,7 +11943,7 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
11735
11943
|
traceStreamingChannel(aiSDKChannels.toolLoopAgentStream, {
|
|
11736
11944
|
name: "ToolLoopAgent.stream",
|
|
11737
11945
|
type: "llm" /* LLM */,
|
|
11738
|
-
extractInput: ([params], event, span) =>
|
|
11946
|
+
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
11739
11947
|
extractOutput: (result, endEvent) => processAISDKOutput(
|
|
11740
11948
|
result,
|
|
11741
11949
|
resolveDenyOutputPaths(endEvent, denyOutputPaths)
|
|
@@ -12045,11 +12253,11 @@ var convertDataToAttachment = (data, mimeType, filename) => {
|
|
|
12045
12253
|
}
|
|
12046
12254
|
return null;
|
|
12047
12255
|
};
|
|
12048
|
-
function
|
|
12256
|
+
function processAISDKCallInput(params) {
|
|
12049
12257
|
return processInputAttachmentsSync(params);
|
|
12050
12258
|
}
|
|
12051
|
-
function
|
|
12052
|
-
const { input, outputPromise } =
|
|
12259
|
+
function prepareAISDKCallInput(params, event, span, defaultDenyOutputPaths) {
|
|
12260
|
+
const { input, outputPromise } = processAISDKCallInput(params);
|
|
12053
12261
|
if (outputPromise && input && typeof input === "object") {
|
|
12054
12262
|
outputPromise.then((resolvedData) => {
|
|
12055
12263
|
span.log({
|
|
@@ -12061,7 +12269,7 @@ function prepareAISDKInput(params, event, span, defaultDenyOutputPaths) {
|
|
|
12061
12269
|
}).catch(() => {
|
|
12062
12270
|
});
|
|
12063
12271
|
}
|
|
12064
|
-
const metadata =
|
|
12272
|
+
const metadata = extractMetadataFromCallParams(params, event.self);
|
|
12065
12273
|
const childTracing = prepareAISDKChildTracing(
|
|
12066
12274
|
params,
|
|
12067
12275
|
event.self,
|
|
@@ -12078,6 +12286,12 @@ function prepareAISDKInput(params, event, span, defaultDenyOutputPaths) {
|
|
|
12078
12286
|
metadata
|
|
12079
12287
|
};
|
|
12080
12288
|
}
|
|
12289
|
+
function prepareAISDKEmbedInput(params, self) {
|
|
12290
|
+
return {
|
|
12291
|
+
input: { ...params },
|
|
12292
|
+
metadata: extractMetadataFromEmbedParams(params, self)
|
|
12293
|
+
};
|
|
12294
|
+
}
|
|
12081
12295
|
function extractTopLevelAISDKMetrics(result, event, startTime) {
|
|
12082
12296
|
const metrics = hasModelChildTracing(event) ? {} : extractTokenMetrics(result);
|
|
12083
12297
|
if (startTime) {
|
|
@@ -12088,29 +12302,41 @@ function extractTopLevelAISDKMetrics(result, event, startTime) {
|
|
|
12088
12302
|
function hasModelChildTracing(event) {
|
|
12089
12303
|
return event?.modelWrapped === true || event?.__braintrust_ai_sdk_model_wrapped === true;
|
|
12090
12304
|
}
|
|
12091
|
-
function
|
|
12092
|
-
|
|
12305
|
+
function createAISDKIntegrationMetadata() {
|
|
12306
|
+
return {
|
|
12093
12307
|
braintrust: {
|
|
12094
12308
|
integration_name: "ai-sdk",
|
|
12095
12309
|
sdk_language: "typescript"
|
|
12096
12310
|
}
|
|
12097
12311
|
};
|
|
12098
|
-
|
|
12099
|
-
|
|
12100
|
-
|
|
12312
|
+
}
|
|
12313
|
+
function resolveModelFromSelf(self) {
|
|
12314
|
+
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;
|
|
12315
|
+
}
|
|
12316
|
+
function extractBaseMetadata(model, self) {
|
|
12317
|
+
const metadata = createAISDKIntegrationMetadata();
|
|
12318
|
+
const { model: modelId, provider } = serializeModelWithProvider(
|
|
12319
|
+
model ?? resolveModelFromSelf(self)
|
|
12101
12320
|
);
|
|
12102
|
-
if (
|
|
12103
|
-
metadata.model =
|
|
12321
|
+
if (modelId) {
|
|
12322
|
+
metadata.model = modelId;
|
|
12104
12323
|
}
|
|
12105
12324
|
if (provider) {
|
|
12106
12325
|
metadata.provider = provider;
|
|
12107
12326
|
}
|
|
12327
|
+
return metadata;
|
|
12328
|
+
}
|
|
12329
|
+
function extractMetadataFromCallParams(params, self) {
|
|
12330
|
+
const metadata = extractBaseMetadata(params.model, self);
|
|
12108
12331
|
const tools = serializeAISDKToolsForLogging(params.tools);
|
|
12109
12332
|
if (tools) {
|
|
12110
12333
|
metadata.tools = tools;
|
|
12111
12334
|
}
|
|
12112
12335
|
return metadata;
|
|
12113
12336
|
}
|
|
12337
|
+
function extractMetadataFromEmbedParams(params, self) {
|
|
12338
|
+
return extractBaseMetadata(params.model, self);
|
|
12339
|
+
}
|
|
12114
12340
|
function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiSDK) {
|
|
12115
12341
|
const cleanup = [];
|
|
12116
12342
|
const patchedModels = /* @__PURE__ */ new WeakSet();
|
|
@@ -12148,7 +12374,7 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
|
|
|
12148
12374
|
type: "llm" /* LLM */
|
|
12149
12375
|
},
|
|
12150
12376
|
event: {
|
|
12151
|
-
input:
|
|
12377
|
+
input: processAISDKCallInput(options).input,
|
|
12152
12378
|
metadata: baseMetadata
|
|
12153
12379
|
}
|
|
12154
12380
|
}
|
|
@@ -12162,7 +12388,7 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
|
|
|
12162
12388
|
type: "llm" /* LLM */
|
|
12163
12389
|
},
|
|
12164
12390
|
event: {
|
|
12165
|
-
input:
|
|
12391
|
+
input: processAISDKCallInput(options).input,
|
|
12166
12392
|
metadata: baseMetadata
|
|
12167
12393
|
}
|
|
12168
12394
|
});
|
|
@@ -12471,9 +12697,14 @@ function attachKnownResultPromiseHandlers(result) {
|
|
|
12471
12697
|
"content",
|
|
12472
12698
|
"text",
|
|
12473
12699
|
"object",
|
|
12700
|
+
"value",
|
|
12701
|
+
"values",
|
|
12474
12702
|
"finishReason",
|
|
12703
|
+
"embedding",
|
|
12704
|
+
"embeddings",
|
|
12475
12705
|
"usage",
|
|
12476
12706
|
"totalUsage",
|
|
12707
|
+
"responses",
|
|
12477
12708
|
"steps"
|
|
12478
12709
|
];
|
|
12479
12710
|
for (const field of promiseLikeFields) {
|
|
@@ -12621,6 +12852,38 @@ function processAISDKOutput(output, denyOutputPaths) {
|
|
|
12621
12852
|
const merged = extractSerializableOutputFields(output);
|
|
12622
12853
|
return normalizeAISDKLoggedOutput(omit(merged, denyOutputPaths));
|
|
12623
12854
|
}
|
|
12855
|
+
function processAISDKEmbeddingOutput(output, denyOutputPaths) {
|
|
12856
|
+
if (!output || typeof output !== "object") {
|
|
12857
|
+
return output;
|
|
12858
|
+
}
|
|
12859
|
+
const summarized = {};
|
|
12860
|
+
const whitelistedFields = [
|
|
12861
|
+
"usage",
|
|
12862
|
+
"totalUsage",
|
|
12863
|
+
"warnings",
|
|
12864
|
+
"providerMetadata",
|
|
12865
|
+
"experimental_providerMetadata"
|
|
12866
|
+
];
|
|
12867
|
+
for (const field of whitelistedFields) {
|
|
12868
|
+
const value = safeSerializableFieldRead(output, field);
|
|
12869
|
+
if (value !== void 0 && isSerializableOutputValue(value)) {
|
|
12870
|
+
summarized[field] = value;
|
|
12871
|
+
}
|
|
12872
|
+
}
|
|
12873
|
+
const embedding = safeSerializableFieldRead(output, "embedding");
|
|
12874
|
+
if (Array.isArray(embedding)) {
|
|
12875
|
+
summarized.embedding_length = embedding.length;
|
|
12876
|
+
}
|
|
12877
|
+
const embeddings = safeSerializableFieldRead(output, "embeddings");
|
|
12878
|
+
if (Array.isArray(embeddings)) {
|
|
12879
|
+
summarized.embedding_count = embeddings.length;
|
|
12880
|
+
const firstEmbedding = embeddings.find((item) => Array.isArray(item));
|
|
12881
|
+
if (Array.isArray(firstEmbedding)) {
|
|
12882
|
+
summarized.embedding_length = firstEmbedding.length;
|
|
12883
|
+
}
|
|
12884
|
+
}
|
|
12885
|
+
return normalizeAISDKLoggedOutput(omit(summarized, denyOutputPaths));
|
|
12886
|
+
}
|
|
12624
12887
|
function extractTokenMetrics(result) {
|
|
12625
12888
|
const metrics = {};
|
|
12626
12889
|
let usage;
|
|
@@ -12719,12 +12982,17 @@ function extractGetterValues(obj) {
|
|
|
12719
12982
|
"content",
|
|
12720
12983
|
"text",
|
|
12721
12984
|
"object",
|
|
12985
|
+
"value",
|
|
12986
|
+
"values",
|
|
12987
|
+
"embedding",
|
|
12988
|
+
"embeddings",
|
|
12722
12989
|
"finishReason",
|
|
12723
12990
|
"usage",
|
|
12724
12991
|
"totalUsage",
|
|
12725
12992
|
"toolCalls",
|
|
12726
12993
|
"toolResults",
|
|
12727
12994
|
"warnings",
|
|
12995
|
+
"responses",
|
|
12728
12996
|
"experimental_providerMetadata",
|
|
12729
12997
|
"providerMetadata",
|
|
12730
12998
|
"rawResponse",
|
|
@@ -12985,65 +13253,365 @@ var claudeAgentSDKChannels = defineChannels(
|
|
|
12985
13253
|
}
|
|
12986
13254
|
);
|
|
12987
13255
|
|
|
12988
|
-
// src/instrumentation/plugins/claude-agent-sdk-
|
|
12989
|
-
|
|
12990
|
-
|
|
12991
|
-
|
|
12992
|
-
|
|
12993
|
-
|
|
12994
|
-
|
|
12995
|
-
|
|
12996
|
-
|
|
12997
|
-
|
|
12998
|
-
|
|
12999
|
-
|
|
13000
|
-
|
|
13001
|
-
|
|
13002
|
-
|
|
13003
|
-
|
|
13004
|
-
|
|
13005
|
-
|
|
13006
|
-
|
|
13007
|
-
|
|
13008
|
-
|
|
13009
|
-
|
|
13010
|
-
|
|
13011
|
-
|
|
13256
|
+
// src/instrumentation/plugins/claude-agent-sdk-instrumentation-constants.ts
|
|
13257
|
+
var CLAUDE_AGENT_SDK_SKIP_LOCAL_TOOL_HOOKS_OPTION = "__braintrust_skip_local_tool_hooks";
|
|
13258
|
+
|
|
13259
|
+
// src/instrumentation/plugins/claude-agent-sdk-local-tool-context.ts
|
|
13260
|
+
var LOCAL_TOOL_CONTEXT_ASYNC_ITERATOR_PATCHED = Symbol.for(
|
|
13261
|
+
"braintrust.claude_agent_sdk.local_tool_context_async_iterator_patched"
|
|
13262
|
+
);
|
|
13263
|
+
function createLocalToolContextStore() {
|
|
13264
|
+
const maybeIsoWithAsyncLocalStorage = isomorph_default;
|
|
13265
|
+
if (typeof maybeIsoWithAsyncLocalStorage.newAsyncLocalStorage === "function") {
|
|
13266
|
+
return maybeIsoWithAsyncLocalStorage.newAsyncLocalStorage();
|
|
13267
|
+
}
|
|
13268
|
+
let currentStore;
|
|
13269
|
+
return {
|
|
13270
|
+
enterWith(store) {
|
|
13271
|
+
currentStore = store;
|
|
13272
|
+
},
|
|
13273
|
+
getStore() {
|
|
13274
|
+
return currentStore;
|
|
13275
|
+
},
|
|
13276
|
+
run(store, callback) {
|
|
13277
|
+
const previousStore = currentStore;
|
|
13278
|
+
currentStore = store;
|
|
13279
|
+
try {
|
|
13280
|
+
return callback();
|
|
13281
|
+
} finally {
|
|
13282
|
+
currentStore = previousStore;
|
|
13283
|
+
}
|
|
13012
13284
|
}
|
|
13285
|
+
};
|
|
13286
|
+
}
|
|
13287
|
+
var localToolContextStore = createLocalToolContextStore();
|
|
13288
|
+
var fallbackLocalToolParentResolver;
|
|
13289
|
+
function createClaudeLocalToolContext() {
|
|
13290
|
+
return {};
|
|
13291
|
+
}
|
|
13292
|
+
function runWithClaudeLocalToolContext(callback, context) {
|
|
13293
|
+
return localToolContextStore.run(
|
|
13294
|
+
context ?? createClaudeLocalToolContext(),
|
|
13295
|
+
callback
|
|
13296
|
+
);
|
|
13297
|
+
}
|
|
13298
|
+
function ensureClaudeLocalToolContext() {
|
|
13299
|
+
const existing = localToolContextStore.getStore();
|
|
13300
|
+
if (existing) {
|
|
13301
|
+
return existing;
|
|
13013
13302
|
}
|
|
13014
|
-
|
|
13303
|
+
const created = {};
|
|
13304
|
+
localToolContextStore.enterWith(created);
|
|
13305
|
+
return created;
|
|
13015
13306
|
}
|
|
13016
|
-
function
|
|
13017
|
-
|
|
13018
|
-
|
|
13307
|
+
function setClaudeLocalToolParentResolver(resolver) {
|
|
13308
|
+
fallbackLocalToolParentResolver = resolver;
|
|
13309
|
+
const context = ensureClaudeLocalToolContext();
|
|
13310
|
+
if (!context) {
|
|
13311
|
+
return;
|
|
13019
13312
|
}
|
|
13020
|
-
|
|
13021
|
-
return typeof value === "number" ? value : void 0;
|
|
13313
|
+
context.resolveLocalToolParent = resolver;
|
|
13022
13314
|
}
|
|
13023
|
-
function
|
|
13024
|
-
|
|
13025
|
-
|
|
13026
|
-
|
|
13027
|
-
|
|
13028
|
-
|
|
13029
|
-
|
|
13315
|
+
function getClaudeLocalToolParentResolver() {
|
|
13316
|
+
return localToolContextStore.getStore()?.resolveLocalToolParent ?? fallbackLocalToolParentResolver;
|
|
13317
|
+
}
|
|
13318
|
+
function isAsyncIterable2(value) {
|
|
13319
|
+
return value !== null && typeof value === "object" && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
13320
|
+
}
|
|
13321
|
+
function bindClaudeLocalToolContextToAsyncIterable(result, localToolContext) {
|
|
13322
|
+
if (!isAsyncIterable2(result) || Object.isFrozen(result) || Object.isSealed(result)) {
|
|
13323
|
+
return result;
|
|
13030
13324
|
}
|
|
13031
|
-
|
|
13032
|
-
|
|
13325
|
+
const stream = result;
|
|
13326
|
+
const originalAsyncIterator = stream[Symbol.asyncIterator];
|
|
13327
|
+
if (originalAsyncIterator[LOCAL_TOOL_CONTEXT_ASYNC_ITERATOR_PATCHED]) {
|
|
13328
|
+
return result;
|
|
13033
13329
|
}
|
|
13034
|
-
const
|
|
13035
|
-
|
|
13036
|
-
|
|
13330
|
+
const patchedAsyncIterator = function() {
|
|
13331
|
+
return runWithClaudeLocalToolContext(() => {
|
|
13332
|
+
const iterator = Reflect.apply(originalAsyncIterator, this, []);
|
|
13333
|
+
if (!iterator || typeof iterator !== "object") {
|
|
13334
|
+
return iterator;
|
|
13335
|
+
}
|
|
13336
|
+
const patchMethod = (methodName) => {
|
|
13337
|
+
const originalMethod = Reflect.get(iterator, methodName);
|
|
13338
|
+
if (typeof originalMethod !== "function") {
|
|
13339
|
+
return;
|
|
13340
|
+
}
|
|
13341
|
+
Reflect.set(
|
|
13342
|
+
iterator,
|
|
13343
|
+
methodName,
|
|
13344
|
+
(...args) => runWithClaudeLocalToolContext(
|
|
13345
|
+
() => Reflect.apply(
|
|
13346
|
+
originalMethod,
|
|
13347
|
+
iterator,
|
|
13348
|
+
args
|
|
13349
|
+
),
|
|
13350
|
+
localToolContext
|
|
13351
|
+
)
|
|
13352
|
+
);
|
|
13353
|
+
};
|
|
13354
|
+
patchMethod("next");
|
|
13355
|
+
patchMethod("return");
|
|
13356
|
+
patchMethod("throw");
|
|
13357
|
+
return iterator;
|
|
13358
|
+
}, localToolContext);
|
|
13359
|
+
};
|
|
13360
|
+
Object.defineProperty(
|
|
13361
|
+
patchedAsyncIterator,
|
|
13362
|
+
LOCAL_TOOL_CONTEXT_ASYNC_ITERATOR_PATCHED,
|
|
13363
|
+
{
|
|
13364
|
+
configurable: false,
|
|
13365
|
+
enumerable: false,
|
|
13366
|
+
value: true,
|
|
13367
|
+
writable: false
|
|
13368
|
+
}
|
|
13369
|
+
);
|
|
13370
|
+
Reflect.set(stream, Symbol.asyncIterator, patchedAsyncIterator);
|
|
13371
|
+
return result;
|
|
13372
|
+
}
|
|
13373
|
+
|
|
13374
|
+
// src/instrumentation/plugins/claude-agent-sdk-local-tool-spans.ts
|
|
13375
|
+
var LOCAL_TOOL_HANDLER_WRAPPED = Symbol.for(
|
|
13376
|
+
"braintrust.claude_agent_sdk.local_tool_handler_wrapped"
|
|
13377
|
+
);
|
|
13378
|
+
function toErrorMessage(error) {
|
|
13379
|
+
return error instanceof Error ? error.message : String(error);
|
|
13380
|
+
}
|
|
13381
|
+
function isPromiseLike2(value) {
|
|
13382
|
+
return value !== null && typeof value === "object" && "then" in value && typeof value.then === "function";
|
|
13383
|
+
}
|
|
13384
|
+
function getToolUseIdFromExtra(extra) {
|
|
13385
|
+
if (!extra || typeof extra !== "object" || !("_meta" in extra)) {
|
|
13386
|
+
return void 0;
|
|
13037
13387
|
}
|
|
13038
|
-
const
|
|
13039
|
-
if (
|
|
13040
|
-
|
|
13388
|
+
const meta = Reflect.get(extra, "_meta");
|
|
13389
|
+
if (!meta || typeof meta !== "object") {
|
|
13390
|
+
return void 0;
|
|
13041
13391
|
}
|
|
13042
|
-
const
|
|
13043
|
-
|
|
13044
|
-
|
|
13045
|
-
|
|
13046
|
-
|
|
13392
|
+
const toolUseId = Reflect.get(meta, "claudecode/toolUseId");
|
|
13393
|
+
return typeof toolUseId === "string" ? toolUseId : void 0;
|
|
13394
|
+
}
|
|
13395
|
+
function wrapLocalClaudeToolHandler(handler, getMetadata) {
|
|
13396
|
+
if (handler[LOCAL_TOOL_HANDLER_WRAPPED]) {
|
|
13397
|
+
return handler;
|
|
13398
|
+
}
|
|
13399
|
+
const wrappedHandler = function wrappedLocalToolHandler(...handlerArgs) {
|
|
13400
|
+
const metadata = getMetadata();
|
|
13401
|
+
const rawToolName = metadata.serverName ? `mcp__${metadata.serverName}__${metadata.toolName}` : metadata.toolName;
|
|
13402
|
+
const toolUseId = getToolUseIdFromExtra(handlerArgs[1]);
|
|
13403
|
+
const localToolParentResolver = getClaudeLocalToolParentResolver();
|
|
13404
|
+
const spanName = metadata.serverName ? `tool: ${metadata.serverName}/${metadata.toolName}` : `tool: ${metadata.toolName}`;
|
|
13405
|
+
const runWithResolvedParent = async () => {
|
|
13406
|
+
const parent = toolUseId && localToolParentResolver ? await localToolParentResolver(toolUseId).catch(() => void 0) : void 0;
|
|
13407
|
+
const span = startSpan({
|
|
13408
|
+
event: {
|
|
13409
|
+
input: handlerArgs[0],
|
|
13410
|
+
metadata: {
|
|
13411
|
+
"claude_agent_sdk.raw_tool_name": rawToolName,
|
|
13412
|
+
"gen_ai.tool.name": metadata.toolName,
|
|
13413
|
+
...toolUseId && { "gen_ai.tool.call.id": toolUseId },
|
|
13414
|
+
...metadata.serverName && {
|
|
13415
|
+
"mcp.server": metadata.serverName
|
|
13416
|
+
}
|
|
13417
|
+
}
|
|
13418
|
+
},
|
|
13419
|
+
name: spanName,
|
|
13420
|
+
...parent && { parent },
|
|
13421
|
+
spanAttributes: { type: "tool" /* TOOL */ }
|
|
13422
|
+
});
|
|
13423
|
+
const runHandler = () => Reflect.apply(handler, this, handlerArgs);
|
|
13424
|
+
const finalizeSuccess = (result) => {
|
|
13425
|
+
span.log({ output: result });
|
|
13426
|
+
span.end();
|
|
13427
|
+
return result;
|
|
13428
|
+
};
|
|
13429
|
+
const finalizeError = (error) => {
|
|
13430
|
+
span.log({ error: toErrorMessage(error) });
|
|
13431
|
+
span.end();
|
|
13432
|
+
throw error;
|
|
13433
|
+
};
|
|
13434
|
+
return withCurrent(span, () => {
|
|
13435
|
+
try {
|
|
13436
|
+
const result = runHandler();
|
|
13437
|
+
if (isPromiseLike2(result)) {
|
|
13438
|
+
return result.then(finalizeSuccess, finalizeError);
|
|
13439
|
+
}
|
|
13440
|
+
return finalizeSuccess(result);
|
|
13441
|
+
} catch (error) {
|
|
13442
|
+
return finalizeError(error);
|
|
13443
|
+
}
|
|
13444
|
+
});
|
|
13445
|
+
};
|
|
13446
|
+
return runWithResolvedParent();
|
|
13447
|
+
};
|
|
13448
|
+
Object.defineProperty(wrappedHandler, LOCAL_TOOL_HANDLER_WRAPPED, {
|
|
13449
|
+
configurable: false,
|
|
13450
|
+
enumerable: false,
|
|
13451
|
+
value: true,
|
|
13452
|
+
writable: false
|
|
13453
|
+
});
|
|
13454
|
+
return wrappedHandler;
|
|
13455
|
+
}
|
|
13456
|
+
function getRegisteredTools(instance) {
|
|
13457
|
+
if (!instance || typeof instance !== "object") {
|
|
13458
|
+
return void 0;
|
|
13459
|
+
}
|
|
13460
|
+
if (!("_registeredTools" in instance)) {
|
|
13461
|
+
return void 0;
|
|
13462
|
+
}
|
|
13463
|
+
const registeredTools = Reflect.get(instance, "_registeredTools");
|
|
13464
|
+
if (registeredTools instanceof Map) {
|
|
13465
|
+
return registeredTools;
|
|
13466
|
+
}
|
|
13467
|
+
if (registeredTools && typeof registeredTools === "object") {
|
|
13468
|
+
return registeredTools;
|
|
13469
|
+
}
|
|
13470
|
+
return void 0;
|
|
13471
|
+
}
|
|
13472
|
+
function wrapLocalMcpServerToolHandlers(serverName, serverConfig) {
|
|
13473
|
+
if (!serverConfig || typeof serverConfig !== "object") {
|
|
13474
|
+
return false;
|
|
13475
|
+
}
|
|
13476
|
+
if (!("instance" in serverConfig)) {
|
|
13477
|
+
return false;
|
|
13478
|
+
}
|
|
13479
|
+
const instance = Reflect.get(serverConfig, "instance");
|
|
13480
|
+
const registeredTools = getRegisteredTools(instance);
|
|
13481
|
+
if (!registeredTools) {
|
|
13482
|
+
return false;
|
|
13483
|
+
}
|
|
13484
|
+
let wrappedAny = false;
|
|
13485
|
+
const wrapHandler = (toolName, registration) => {
|
|
13486
|
+
if (!registration || typeof registration !== "object") {
|
|
13487
|
+
return;
|
|
13488
|
+
}
|
|
13489
|
+
const handler = Reflect.get(registration, "handler");
|
|
13490
|
+
if (typeof handler !== "function") {
|
|
13491
|
+
return;
|
|
13492
|
+
}
|
|
13493
|
+
const wrappedHandler = wrapLocalClaudeToolHandler(handler, () => ({
|
|
13494
|
+
serverName,
|
|
13495
|
+
toolName
|
|
13496
|
+
}));
|
|
13497
|
+
if (wrappedHandler !== handler) {
|
|
13498
|
+
Reflect.set(registration, "handler", wrappedHandler);
|
|
13499
|
+
wrappedAny = true;
|
|
13500
|
+
}
|
|
13501
|
+
};
|
|
13502
|
+
if (registeredTools instanceof Map) {
|
|
13503
|
+
for (const [toolName, registration] of registeredTools.entries()) {
|
|
13504
|
+
wrapHandler(toolName, registration);
|
|
13505
|
+
}
|
|
13506
|
+
return wrappedAny;
|
|
13507
|
+
}
|
|
13508
|
+
for (const [toolName, registration] of Object.entries(registeredTools)) {
|
|
13509
|
+
wrapHandler(toolName, registration);
|
|
13510
|
+
}
|
|
13511
|
+
return wrappedAny;
|
|
13512
|
+
}
|
|
13513
|
+
function collectLocalMcpServerToolHookNames(serverName, serverConfig) {
|
|
13514
|
+
const toolNames = /* @__PURE__ */ new Set();
|
|
13515
|
+
if (!serverConfig || typeof serverConfig !== "object") {
|
|
13516
|
+
return toolNames;
|
|
13517
|
+
}
|
|
13518
|
+
if ("instance" in serverConfig) {
|
|
13519
|
+
const instance = Reflect.get(serverConfig, "instance");
|
|
13520
|
+
const registeredTools = getRegisteredTools(instance);
|
|
13521
|
+
if (registeredTools instanceof Map) {
|
|
13522
|
+
for (const toolName of registeredTools.keys()) {
|
|
13523
|
+
toolNames.add(toolName);
|
|
13524
|
+
toolNames.add(`mcp__${serverName}__${toolName}`);
|
|
13525
|
+
}
|
|
13526
|
+
} else if (registeredTools) {
|
|
13527
|
+
for (const toolName of Object.keys(registeredTools)) {
|
|
13528
|
+
toolNames.add(toolName);
|
|
13529
|
+
toolNames.add(`mcp__${serverName}__${toolName}`);
|
|
13530
|
+
}
|
|
13531
|
+
}
|
|
13532
|
+
}
|
|
13533
|
+
if ("tools" in serverConfig) {
|
|
13534
|
+
const rawTools = Reflect.get(serverConfig, "tools");
|
|
13535
|
+
if (Array.isArray(rawTools)) {
|
|
13536
|
+
for (const tool of rawTools) {
|
|
13537
|
+
if (!tool || typeof tool !== "object") {
|
|
13538
|
+
continue;
|
|
13539
|
+
}
|
|
13540
|
+
const toolName = Reflect.get(tool, "name");
|
|
13541
|
+
if (typeof toolName !== "string") {
|
|
13542
|
+
continue;
|
|
13543
|
+
}
|
|
13544
|
+
toolNames.add(toolName);
|
|
13545
|
+
toolNames.add(`mcp__${serverName}__${toolName}`);
|
|
13546
|
+
}
|
|
13547
|
+
}
|
|
13548
|
+
}
|
|
13549
|
+
return toolNames;
|
|
13550
|
+
}
|
|
13551
|
+
|
|
13552
|
+
// src/instrumentation/plugins/claude-agent-sdk-plugin.ts
|
|
13553
|
+
var ROOT_LLM_PARENT_KEY = "__root__";
|
|
13554
|
+
function llmParentKey(parentToolUseId) {
|
|
13555
|
+
return parentToolUseId ?? ROOT_LLM_PARENT_KEY;
|
|
13556
|
+
}
|
|
13557
|
+
function isSubAgentToolName(toolName) {
|
|
13558
|
+
return toolName === "Agent" || toolName === "Task";
|
|
13559
|
+
}
|
|
13560
|
+
function filterSerializableOptions(options) {
|
|
13561
|
+
const allowedKeys = [
|
|
13562
|
+
"model",
|
|
13563
|
+
"maxTurns",
|
|
13564
|
+
"cwd",
|
|
13565
|
+
"continue",
|
|
13566
|
+
"allowedTools",
|
|
13567
|
+
"disallowedTools",
|
|
13568
|
+
"additionalDirectories",
|
|
13569
|
+
"permissionMode",
|
|
13570
|
+
"debug",
|
|
13571
|
+
"apiKey",
|
|
13572
|
+
"apiKeySource",
|
|
13573
|
+
"agentName",
|
|
13574
|
+
"instructions"
|
|
13575
|
+
];
|
|
13576
|
+
const filtered = {};
|
|
13577
|
+
for (const key of allowedKeys) {
|
|
13578
|
+
if (options[key] !== void 0) {
|
|
13579
|
+
filtered[key] = options[key];
|
|
13580
|
+
}
|
|
13581
|
+
}
|
|
13582
|
+
return filtered;
|
|
13583
|
+
}
|
|
13584
|
+
function getNumberProperty(obj, key) {
|
|
13585
|
+
if (!obj || typeof obj !== "object" || !(key in obj)) {
|
|
13586
|
+
return void 0;
|
|
13587
|
+
}
|
|
13588
|
+
const value = Reflect.get(obj, key);
|
|
13589
|
+
return typeof value === "number" ? value : void 0;
|
|
13590
|
+
}
|
|
13591
|
+
function extractUsageFromMessage(message) {
|
|
13592
|
+
const metrics = {};
|
|
13593
|
+
let usage;
|
|
13594
|
+
if (message.type === "assistant") {
|
|
13595
|
+
usage = message.message?.usage;
|
|
13596
|
+
} else if (message.type === "result") {
|
|
13597
|
+
usage = message.usage;
|
|
13598
|
+
}
|
|
13599
|
+
if (!usage || typeof usage !== "object") {
|
|
13600
|
+
return metrics;
|
|
13601
|
+
}
|
|
13602
|
+
const inputTokens = getNumberProperty(usage, "input_tokens");
|
|
13603
|
+
if (inputTokens !== void 0) {
|
|
13604
|
+
metrics.prompt_tokens = inputTokens;
|
|
13605
|
+
}
|
|
13606
|
+
const outputTokens = getNumberProperty(usage, "output_tokens");
|
|
13607
|
+
if (outputTokens !== void 0) {
|
|
13608
|
+
metrics.completion_tokens = outputTokens;
|
|
13609
|
+
}
|
|
13610
|
+
const cacheReadTokens = getNumberProperty(usage, "cache_read_input_tokens") || 0;
|
|
13611
|
+
const cacheCreationTokens = getNumberProperty(usage, "cache_creation_input_tokens") || 0;
|
|
13612
|
+
if (cacheReadTokens > 0 || cacheCreationTokens > 0) {
|
|
13613
|
+
Object.assign(
|
|
13614
|
+
metrics,
|
|
13047
13615
|
extractAnthropicCacheTokens(cacheReadTokens, cacheCreationTokens)
|
|
13048
13616
|
);
|
|
13049
13617
|
}
|
|
@@ -13071,7 +13639,7 @@ function buildLLMInput(prompt, conversationHistory, capturedPromptMessages) {
|
|
|
13071
13639
|
function formatCapturedMessages(messages) {
|
|
13072
13640
|
return messages.length > 0 ? messages : [];
|
|
13073
13641
|
}
|
|
13074
|
-
async function createLLMSpanForMessages(messages, prompt, conversationHistory, options, startTime, capturedPromptMessages, parentSpan) {
|
|
13642
|
+
async function createLLMSpanForMessages(messages, prompt, conversationHistory, options, startTime, capturedPromptMessages, parentSpan, existingSpan) {
|
|
13075
13643
|
if (messages.length === 0) {
|
|
13076
13644
|
return void 0;
|
|
13077
13645
|
}
|
|
@@ -13091,7 +13659,7 @@ async function createLLMSpanForMessages(messages, prompt, conversationHistory, o
|
|
|
13091
13659
|
).filter(
|
|
13092
13660
|
(c) => c !== void 0
|
|
13093
13661
|
);
|
|
13094
|
-
const span = startSpan({
|
|
13662
|
+
const span = existingSpan ?? startSpan({
|
|
13095
13663
|
name: "anthropic.messages.create",
|
|
13096
13664
|
parent: parentSpan,
|
|
13097
13665
|
spanAttributes: {
|
|
@@ -13105,8 +13673,13 @@ async function createLLMSpanForMessages(messages, prompt, conversationHistory, o
|
|
|
13105
13673
|
metrics: usage,
|
|
13106
13674
|
output: outputs
|
|
13107
13675
|
});
|
|
13676
|
+
const spanExport = await span.export();
|
|
13108
13677
|
await span.end();
|
|
13109
|
-
|
|
13678
|
+
const finalMessage = lastMessage.message?.content && lastMessage.message?.role ? { content: lastMessage.message.content, role: lastMessage.message.role } : void 0;
|
|
13679
|
+
return {
|
|
13680
|
+
finalMessage,
|
|
13681
|
+
spanExport
|
|
13682
|
+
};
|
|
13110
13683
|
}
|
|
13111
13684
|
function getMcpServerMetadata(serverName, mcpServers) {
|
|
13112
13685
|
if (!serverName || !mcpServers) {
|
|
@@ -13150,11 +13723,51 @@ function parseToolName(rawToolName) {
|
|
|
13150
13723
|
toolName: rawToolName
|
|
13151
13724
|
};
|
|
13152
13725
|
}
|
|
13153
|
-
function
|
|
13726
|
+
function isLocalToolUse(rawToolName, mcpServers) {
|
|
13727
|
+
const parsed = parseToolName(rawToolName);
|
|
13728
|
+
if (!parsed.mcpServer || !mcpServers) {
|
|
13729
|
+
return false;
|
|
13730
|
+
}
|
|
13731
|
+
const serverConfig = mcpServers[parsed.mcpServer];
|
|
13732
|
+
if (!serverConfig || typeof serverConfig !== "object") {
|
|
13733
|
+
return false;
|
|
13734
|
+
}
|
|
13735
|
+
return serverConfig.type === "sdk" || "transport" in serverConfig;
|
|
13736
|
+
}
|
|
13737
|
+
function prepareLocalToolHandlersInMcpServers(mcpServers) {
|
|
13738
|
+
const localToolHookNames = /* @__PURE__ */ new Set();
|
|
13739
|
+
if (!mcpServers) {
|
|
13740
|
+
return {
|
|
13741
|
+
hasLocalToolHandlers: false,
|
|
13742
|
+
localToolHookNames
|
|
13743
|
+
};
|
|
13744
|
+
}
|
|
13745
|
+
let hasLocalToolHandlers = false;
|
|
13746
|
+
for (const [serverName, serverConfig] of Object.entries(mcpServers)) {
|
|
13747
|
+
const toolNames = collectLocalMcpServerToolHookNames(
|
|
13748
|
+
serverName,
|
|
13749
|
+
serverConfig
|
|
13750
|
+
);
|
|
13751
|
+
for (const toolName of toolNames) {
|
|
13752
|
+
localToolHookNames.add(toolName);
|
|
13753
|
+
}
|
|
13754
|
+
if (toolNames.size > 0) {
|
|
13755
|
+
hasLocalToolHandlers = true;
|
|
13756
|
+
}
|
|
13757
|
+
if (wrapLocalMcpServerToolHandlers(serverName, serverConfig)) {
|
|
13758
|
+
hasLocalToolHandlers = true;
|
|
13759
|
+
}
|
|
13760
|
+
}
|
|
13761
|
+
return { hasLocalToolHandlers, localToolHookNames };
|
|
13762
|
+
}
|
|
13763
|
+
function createToolTracingHooks(resolveParentSpan, activeToolSpans, mcpServers, localToolHookNames, skipLocalToolHooks, subAgentSpans, endedSubAgentSpans) {
|
|
13154
13764
|
const preToolUse = async (input, toolUseID) => {
|
|
13155
13765
|
if (input.hook_event_name !== "PreToolUse" || !toolUseID) {
|
|
13156
13766
|
return {};
|
|
13157
13767
|
}
|
|
13768
|
+
if (skipLocalToolHooks && (isLocalToolUse(input.tool_name, mcpServers) || localToolHookNames.has(input.tool_name))) {
|
|
13769
|
+
return {};
|
|
13770
|
+
}
|
|
13158
13771
|
if (isSubAgentToolName(input.tool_name)) {
|
|
13159
13772
|
return {};
|
|
13160
13773
|
}
|
|
@@ -13183,6 +13796,9 @@ function createToolTracingHooks(resolveParentSpan, activeToolSpans, mcpServers,
|
|
|
13183
13796
|
if (input.hook_event_name !== "PostToolUse" || !toolUseID) {
|
|
13184
13797
|
return {};
|
|
13185
13798
|
}
|
|
13799
|
+
if (skipLocalToolHooks && (isLocalToolUse(input.tool_name, mcpServers) || localToolHookNames.has(input.tool_name))) {
|
|
13800
|
+
return {};
|
|
13801
|
+
}
|
|
13186
13802
|
const subAgentSpan = subAgentSpans.get(toolUseID);
|
|
13187
13803
|
if (subAgentSpan) {
|
|
13188
13804
|
try {
|
|
@@ -13223,6 +13839,9 @@ function createToolTracingHooks(resolveParentSpan, activeToolSpans, mcpServers,
|
|
|
13223
13839
|
if (input.hook_event_name !== "PostToolUseFailure" || !toolUseID) {
|
|
13224
13840
|
return {};
|
|
13225
13841
|
}
|
|
13842
|
+
if (skipLocalToolHooks && (isLocalToolUse(input.tool_name, mcpServers) || localToolHookNames.has(input.tool_name))) {
|
|
13843
|
+
return {};
|
|
13844
|
+
}
|
|
13226
13845
|
const subAgentSpan = subAgentSpans.get(toolUseID);
|
|
13227
13846
|
if (subAgentSpan) {
|
|
13228
13847
|
try {
|
|
@@ -13257,11 +13876,13 @@ function createToolTracingHooks(resolveParentSpan, activeToolSpans, mcpServers,
|
|
|
13257
13876
|
};
|
|
13258
13877
|
return { postToolUse, postToolUseFailure, preToolUse };
|
|
13259
13878
|
}
|
|
13260
|
-
function injectTracingHooks(options, resolveParentSpan, activeToolSpans, subAgentSpans, endedSubAgentSpans) {
|
|
13879
|
+
function injectTracingHooks(options, resolveParentSpan, activeToolSpans, localToolHookNames, skipLocalToolHooks, subAgentSpans, endedSubAgentSpans) {
|
|
13261
13880
|
const { preToolUse, postToolUse, postToolUseFailure } = createToolTracingHooks(
|
|
13262
13881
|
resolveParentSpan,
|
|
13263
13882
|
activeToolSpans,
|
|
13264
13883
|
options.mcpServers,
|
|
13884
|
+
localToolHookNames,
|
|
13885
|
+
skipLocalToolHooks,
|
|
13265
13886
|
subAgentSpans,
|
|
13266
13887
|
endedSubAgentSpans
|
|
13267
13888
|
);
|
|
@@ -13292,6 +13913,7 @@ async function finalizeCurrentMessageGroup(state) {
|
|
|
13292
13913
|
return;
|
|
13293
13914
|
}
|
|
13294
13915
|
const parentToolUseId = state.currentMessages[0]?.parent_tool_use_id ?? null;
|
|
13916
|
+
const parentKey = llmParentKey(parentToolUseId);
|
|
13295
13917
|
let parentSpan = await state.span.export();
|
|
13296
13918
|
if (parentToolUseId) {
|
|
13297
13919
|
const subAgentSpan = state.subAgentSpans.get(parentToolUseId);
|
|
@@ -13299,17 +13921,30 @@ async function finalizeCurrentMessageGroup(state) {
|
|
|
13299
13921
|
parentSpan = await subAgentSpan.export();
|
|
13300
13922
|
}
|
|
13301
13923
|
}
|
|
13302
|
-
const
|
|
13924
|
+
const existingLlmSpan = state.activeLlmSpansByParentToolUse.get(parentKey);
|
|
13925
|
+
const llmSpanResult = await createLLMSpanForMessages(
|
|
13303
13926
|
state.currentMessages,
|
|
13304
13927
|
state.originalPrompt,
|
|
13305
13928
|
state.finalResults,
|
|
13306
13929
|
state.options,
|
|
13307
13930
|
state.currentMessageStartTime,
|
|
13308
13931
|
state.capturedPromptMessages,
|
|
13309
|
-
parentSpan
|
|
13932
|
+
parentSpan,
|
|
13933
|
+
existingLlmSpan
|
|
13310
13934
|
);
|
|
13311
|
-
|
|
13312
|
-
|
|
13935
|
+
state.activeLlmSpansByParentToolUse.delete(parentKey);
|
|
13936
|
+
if (llmSpanResult) {
|
|
13937
|
+
if (parentToolUseId) {
|
|
13938
|
+
state.latestLlmParentBySubAgentToolUse.set(
|
|
13939
|
+
parentToolUseId,
|
|
13940
|
+
llmSpanResult.spanExport
|
|
13941
|
+
);
|
|
13942
|
+
} else {
|
|
13943
|
+
state.latestRootLlmParentRef.value = llmSpanResult.spanExport;
|
|
13944
|
+
}
|
|
13945
|
+
if (llmSpanResult.finalMessage) {
|
|
13946
|
+
state.finalResults.push(llmSpanResult.finalMessage);
|
|
13947
|
+
}
|
|
13313
13948
|
}
|
|
13314
13949
|
const lastMessage = state.currentMessages[state.currentMessages.length - 1];
|
|
13315
13950
|
if (lastMessage?.message?.usage) {
|
|
@@ -13377,6 +14012,29 @@ async function handleStreamMessage(state, message) {
|
|
|
13377
14012
|
state.currentMessageStartTime = getCurrentUnixTimestamp();
|
|
13378
14013
|
}
|
|
13379
14014
|
if (message.type === "assistant" && message.message?.usage) {
|
|
14015
|
+
const parentToolUseId = message.parent_tool_use_id ?? null;
|
|
14016
|
+
const parentKey = llmParentKey(parentToolUseId);
|
|
14017
|
+
if (!state.activeLlmSpansByParentToolUse.has(parentKey)) {
|
|
14018
|
+
let llmParentSpan = await state.span.export();
|
|
14019
|
+
if (parentToolUseId) {
|
|
14020
|
+
const subAgentSpan = await ensureSubAgentSpan(
|
|
14021
|
+
state.pendingSubAgentNames,
|
|
14022
|
+
state.span,
|
|
14023
|
+
state.subAgentSpans,
|
|
14024
|
+
parentToolUseId
|
|
14025
|
+
);
|
|
14026
|
+
llmParentSpan = await subAgentSpan.export();
|
|
14027
|
+
}
|
|
14028
|
+
const llmSpan = startSpan({
|
|
14029
|
+
name: "anthropic.messages.create",
|
|
14030
|
+
parent: llmParentSpan,
|
|
14031
|
+
spanAttributes: {
|
|
14032
|
+
type: "llm" /* LLM */
|
|
14033
|
+
},
|
|
14034
|
+
startTime: state.currentMessageStartTime
|
|
14035
|
+
});
|
|
14036
|
+
state.activeLlmSpansByParentToolUse.set(parentKey, llmSpan);
|
|
14037
|
+
}
|
|
13380
14038
|
state.currentMessages.push(message);
|
|
13381
14039
|
}
|
|
13382
14040
|
if (message.type !== "result" || !message.usage) {
|
|
@@ -13437,6 +14095,10 @@ async function finalizeQuerySpan(state) {
|
|
|
13437
14095
|
}
|
|
13438
14096
|
}
|
|
13439
14097
|
} finally {
|
|
14098
|
+
for (const llmSpan of state.activeLlmSpansByParentToolUse.values()) {
|
|
14099
|
+
llmSpan.end();
|
|
14100
|
+
}
|
|
14101
|
+
state.activeLlmSpansByParentToolUse.clear();
|
|
13440
14102
|
for (const [id, subAgentSpan] of state.subAgentSpans) {
|
|
13441
14103
|
if (!state.endedSubAgentSpans.has(id)) {
|
|
13442
14104
|
subAgentSpan.end();
|
|
@@ -13502,26 +14164,51 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
13502
14164
|
console.error("Error extracting input for Claude Agent SDK:", error);
|
|
13503
14165
|
}
|
|
13504
14166
|
const activeToolSpans = /* @__PURE__ */ new Map();
|
|
14167
|
+
const activeLlmSpansByParentToolUse = /* @__PURE__ */ new Map();
|
|
13505
14168
|
const subAgentSpans = /* @__PURE__ */ new Map();
|
|
13506
14169
|
const endedSubAgentSpans = /* @__PURE__ */ new Set();
|
|
13507
14170
|
const toolUseToParent = /* @__PURE__ */ new Map();
|
|
14171
|
+
const latestLlmParentBySubAgentToolUse = /* @__PURE__ */ new Map();
|
|
14172
|
+
const latestRootLlmParentRef = {
|
|
14173
|
+
value: void 0
|
|
14174
|
+
};
|
|
13508
14175
|
const pendingSubAgentNames = /* @__PURE__ */ new Map();
|
|
14176
|
+
const localToolContext = createClaudeLocalToolContext();
|
|
14177
|
+
const { hasLocalToolHandlers, localToolHookNames } = prepareLocalToolHandlersInMcpServers(options.mcpServers);
|
|
14178
|
+
const skipLocalToolHooks = options[CLAUDE_AGENT_SDK_SKIP_LOCAL_TOOL_HOOKS_OPTION] === true || hasLocalToolHandlers;
|
|
14179
|
+
const resolveToolUseParentSpan = async (toolUseID) => {
|
|
14180
|
+
const parentToolUseId = toolUseToParent.get(toolUseID) ?? null;
|
|
14181
|
+
const parentKey = llmParentKey(parentToolUseId);
|
|
14182
|
+
const activeLlmSpan = activeLlmSpansByParentToolUse.get(parentKey);
|
|
14183
|
+
if (activeLlmSpan) {
|
|
14184
|
+
return activeLlmSpan.export();
|
|
14185
|
+
}
|
|
14186
|
+
if (parentToolUseId) {
|
|
14187
|
+
const parentLlm = latestLlmParentBySubAgentToolUse.get(parentToolUseId);
|
|
14188
|
+
if (parentLlm) {
|
|
14189
|
+
return parentLlm;
|
|
14190
|
+
}
|
|
14191
|
+
const subAgentSpan = await ensureSubAgentSpan(
|
|
14192
|
+
pendingSubAgentNames,
|
|
14193
|
+
span,
|
|
14194
|
+
subAgentSpans,
|
|
14195
|
+
parentToolUseId
|
|
14196
|
+
);
|
|
14197
|
+
return subAgentSpan.export();
|
|
14198
|
+
}
|
|
14199
|
+
if (latestRootLlmParentRef.value) {
|
|
14200
|
+
return latestRootLlmParentRef.value;
|
|
14201
|
+
}
|
|
14202
|
+
return span.export();
|
|
14203
|
+
};
|
|
14204
|
+
localToolContext.resolveLocalToolParent = resolveToolUseParentSpan;
|
|
14205
|
+
setClaudeLocalToolParentResolver(resolveToolUseParentSpan);
|
|
13509
14206
|
const optionsWithHooks = injectTracingHooks(
|
|
13510
14207
|
options,
|
|
13511
|
-
|
|
13512
|
-
const parentToolUseId = toolUseToParent.get(toolUseID);
|
|
13513
|
-
if (parentToolUseId) {
|
|
13514
|
-
const subAgentSpan = await ensureSubAgentSpan(
|
|
13515
|
-
pendingSubAgentNames,
|
|
13516
|
-
span,
|
|
13517
|
-
subAgentSpans,
|
|
13518
|
-
parentToolUseId
|
|
13519
|
-
);
|
|
13520
|
-
return subAgentSpan.export();
|
|
13521
|
-
}
|
|
13522
|
-
return span.export();
|
|
13523
|
-
},
|
|
14208
|
+
resolveToolUseParentSpan,
|
|
13524
14209
|
activeToolSpans,
|
|
14210
|
+
localToolHookNames,
|
|
14211
|
+
skipLocalToolHooks,
|
|
13525
14212
|
subAgentSpans,
|
|
13526
14213
|
endedSubAgentSpans
|
|
13527
14214
|
);
|
|
@@ -13529,6 +14216,7 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
13529
14216
|
event.arguments[0] = params;
|
|
13530
14217
|
spans.set(event, {
|
|
13531
14218
|
accumulatedOutputTokens: 0,
|
|
14219
|
+
activeLlmSpansByParentToolUse,
|
|
13532
14220
|
activeToolSpans,
|
|
13533
14221
|
capturedPromptMessages,
|
|
13534
14222
|
currentMessageId: void 0,
|
|
@@ -13544,7 +14232,10 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
13544
14232
|
promptStarted: () => promptStarted,
|
|
13545
14233
|
span,
|
|
13546
14234
|
subAgentSpans,
|
|
13547
|
-
|
|
14235
|
+
latestLlmParentBySubAgentToolUse,
|
|
14236
|
+
latestRootLlmParentRef,
|
|
14237
|
+
toolUseToParent,
|
|
14238
|
+
localToolContext
|
|
13548
14239
|
});
|
|
13549
14240
|
},
|
|
13550
14241
|
end: (event) => {
|
|
@@ -13552,7 +14243,10 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
13552
14243
|
if (!state) {
|
|
13553
14244
|
return;
|
|
13554
14245
|
}
|
|
13555
|
-
const eventResult =
|
|
14246
|
+
const eventResult = bindClaudeLocalToolContextToAsyncIterable(
|
|
14247
|
+
event.result,
|
|
14248
|
+
state.localToolContext
|
|
14249
|
+
);
|
|
13556
14250
|
if (eventResult === void 0) {
|
|
13557
14251
|
state.span.end();
|
|
13558
14252
|
spans.delete(event);
|
|
@@ -13757,19 +14451,20 @@ function ensureSpanState(states, event, create) {
|
|
|
13757
14451
|
}
|
|
13758
14452
|
function bindCurrentSpanStoreToStart2(tracingChannel2, states, create) {
|
|
13759
14453
|
const state = _internalGetGlobalState();
|
|
14454
|
+
const contextManager = state?.contextManager;
|
|
13760
14455
|
const startChannel = tracingChannel2.start;
|
|
13761
|
-
const currentSpanStore =
|
|
14456
|
+
const currentSpanStore = contextManager ? contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
|
|
13762
14457
|
if (!startChannel?.bindStore || !currentSpanStore) {
|
|
13763
14458
|
return void 0;
|
|
13764
14459
|
}
|
|
13765
|
-
startChannel.bindStore(
|
|
13766
|
-
|
|
13767
|
-
(event) => ensureSpanState(
|
|
14460
|
+
startChannel.bindStore(currentSpanStore, (event) => {
|
|
14461
|
+
const span = ensureSpanState(
|
|
13768
14462
|
states,
|
|
13769
14463
|
event,
|
|
13770
14464
|
() => create(event)
|
|
13771
|
-
).span
|
|
13772
|
-
|
|
14465
|
+
).span;
|
|
14466
|
+
return contextManager.wrapSpanForStore(span);
|
|
14467
|
+
});
|
|
13773
14468
|
return () => {
|
|
13774
14469
|
startChannel.unbindStore?.(currentSpanStore);
|
|
13775
14470
|
};
|
|
@@ -14164,20 +14859,8 @@ function tryToDict(obj) {
|
|
|
14164
14859
|
return null;
|
|
14165
14860
|
}
|
|
14166
14861
|
|
|
14167
|
-
// src/instrumentation/plugins/openrouter-channels.ts
|
|
14168
|
-
var
|
|
14169
|
-
chatSend: channel({
|
|
14170
|
-
channelName: "chat.send",
|
|
14171
|
-
kind: "async"
|
|
14172
|
-
}),
|
|
14173
|
-
embeddingsGenerate: channel({
|
|
14174
|
-
channelName: "embeddings.generate",
|
|
14175
|
-
kind: "async"
|
|
14176
|
-
}),
|
|
14177
|
-
betaResponsesSend: channel({
|
|
14178
|
-
channelName: "beta.responses.send",
|
|
14179
|
-
kind: "async"
|
|
14180
|
-
}),
|
|
14862
|
+
// src/instrumentation/plugins/openrouter-agent-channels.ts
|
|
14863
|
+
var openRouterAgentChannels = defineChannels("@openrouter/agent", {
|
|
14181
14864
|
callModel: channel({
|
|
14182
14865
|
channelName: "callModel",
|
|
14183
14866
|
kind: "sync-stream"
|
|
@@ -14192,65 +14875,862 @@ var openRouterChannels = defineChannels("@openrouter/sdk", {
|
|
|
14192
14875
|
})
|
|
14193
14876
|
});
|
|
14194
14877
|
|
|
14195
|
-
// src/instrumentation/plugins/openrouter-plugin.ts
|
|
14196
|
-
var
|
|
14878
|
+
// src/instrumentation/plugins/openrouter-agent-plugin.ts
|
|
14879
|
+
var OpenRouterAgentPlugin = class extends BasePlugin {
|
|
14197
14880
|
onEnable() {
|
|
14198
|
-
this.
|
|
14881
|
+
this.subscribeToOpenRouterAgentChannels();
|
|
14199
14882
|
}
|
|
14200
14883
|
onDisable() {
|
|
14201
14884
|
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
14202
14885
|
}
|
|
14203
|
-
|
|
14886
|
+
subscribeToOpenRouterAgentChannels() {
|
|
14204
14887
|
this.unsubscribers.push(
|
|
14205
|
-
|
|
14206
|
-
name: "openrouter.
|
|
14888
|
+
traceSyncStreamChannel(openRouterAgentChannels.callModel, {
|
|
14889
|
+
name: "openrouter.callModel",
|
|
14207
14890
|
type: "llm" /* LLM */,
|
|
14208
14891
|
extractInput: (args) => {
|
|
14209
|
-
const request =
|
|
14210
|
-
const chatGenerationParams = isObject(request?.chatGenerationParams) ? request.chatGenerationParams : {};
|
|
14211
|
-
const httpReferer = request?.httpReferer;
|
|
14212
|
-
const xTitle = request?.xTitle;
|
|
14213
|
-
const { messages, ...metadata } = chatGenerationParams;
|
|
14892
|
+
const request = getOpenRouterCallModelRequestArg(args);
|
|
14214
14893
|
return {
|
|
14215
|
-
input:
|
|
14216
|
-
metadata:
|
|
14894
|
+
input: request ? extractOpenRouterCallModelInput(request) : void 0,
|
|
14895
|
+
metadata: request ? extractOpenRouterCallModelMetadata(request) : { provider: "openrouter" }
|
|
14217
14896
|
};
|
|
14218
14897
|
},
|
|
14219
|
-
|
|
14220
|
-
return
|
|
14221
|
-
|
|
14222
|
-
|
|
14223
|
-
|
|
14224
|
-
|
|
14225
|
-
|
|
14226
|
-
}
|
|
14227
|
-
return metrics;
|
|
14228
|
-
},
|
|
14229
|
-
aggregateChunks: aggregateOpenRouterChatChunks
|
|
14898
|
+
patchResult: ({ endEvent, result, span }) => {
|
|
14899
|
+
return patchOpenRouterCallModelResult({
|
|
14900
|
+
request: getOpenRouterCallModelRequestArg(endEvent.arguments),
|
|
14901
|
+
result,
|
|
14902
|
+
span
|
|
14903
|
+
});
|
|
14904
|
+
}
|
|
14230
14905
|
})
|
|
14231
14906
|
);
|
|
14232
14907
|
this.unsubscribers.push(
|
|
14233
|
-
traceAsyncChannel(
|
|
14234
|
-
name: "openrouter.
|
|
14908
|
+
traceAsyncChannel(openRouterAgentChannels.callModelTurn, {
|
|
14909
|
+
name: "openrouter.beta.responses.send",
|
|
14235
14910
|
type: "llm" /* LLM */,
|
|
14236
|
-
extractInput: (args) => {
|
|
14237
|
-
const request =
|
|
14238
|
-
const
|
|
14239
|
-
|
|
14240
|
-
|
|
14241
|
-
|
|
14911
|
+
extractInput: (args, event) => {
|
|
14912
|
+
const request = getOpenRouterCallModelRequestArg(args);
|
|
14913
|
+
const metadata = request ? extractOpenRouterCallModelMetadata(request) : { provider: "openrouter" };
|
|
14914
|
+
if (isObject(metadata) && "tools" in metadata) {
|
|
14915
|
+
delete metadata.tools;
|
|
14916
|
+
}
|
|
14242
14917
|
return {
|
|
14243
|
-
input,
|
|
14244
|
-
metadata:
|
|
14245
|
-
metadata,
|
|
14246
|
-
|
|
14247
|
-
|
|
14248
|
-
|
|
14918
|
+
input: request ? extractOpenRouterCallModelInput(request) : void 0,
|
|
14919
|
+
metadata: {
|
|
14920
|
+
...metadata,
|
|
14921
|
+
step: event.step,
|
|
14922
|
+
step_type: event.stepType
|
|
14923
|
+
}
|
|
14249
14924
|
};
|
|
14250
14925
|
},
|
|
14251
|
-
extractOutput: (result) =>
|
|
14926
|
+
extractOutput: (result) => extractOpenRouterResponseOutput(result),
|
|
14927
|
+
extractMetadata: (result, event) => {
|
|
14252
14928
|
if (!isObject(result)) {
|
|
14253
|
-
return
|
|
14929
|
+
return {
|
|
14930
|
+
step: event?.step,
|
|
14931
|
+
step_type: event?.stepType
|
|
14932
|
+
};
|
|
14933
|
+
}
|
|
14934
|
+
return {
|
|
14935
|
+
...extractOpenRouterResponseMetadata(result) || {},
|
|
14936
|
+
...event?.step !== void 0 ? { step: event.step } : {},
|
|
14937
|
+
...event?.stepType ? { step_type: event.stepType } : {}
|
|
14938
|
+
};
|
|
14939
|
+
},
|
|
14940
|
+
extractMetrics: (result) => isObject(result) ? parseOpenRouterMetricsFromUsage(result.usage) : {}
|
|
14941
|
+
})
|
|
14942
|
+
);
|
|
14943
|
+
this.unsubscribers.push(
|
|
14944
|
+
traceStreamingChannel(openRouterAgentChannels.toolExecute, {
|
|
14945
|
+
name: "openrouter.tool",
|
|
14946
|
+
type: "tool" /* TOOL */,
|
|
14947
|
+
extractInput: (args, event) => ({
|
|
14948
|
+
input: args[0],
|
|
14949
|
+
metadata: {
|
|
14950
|
+
provider: "openrouter",
|
|
14951
|
+
tool_name: event.toolName,
|
|
14952
|
+
...event.toolCallId ? { tool_call_id: event.toolCallId } : {}
|
|
14953
|
+
}
|
|
14954
|
+
}),
|
|
14955
|
+
extractOutput: (result) => result,
|
|
14956
|
+
extractMetrics: () => ({}),
|
|
14957
|
+
aggregateChunks: (chunks) => ({
|
|
14958
|
+
output: chunks.length > 0 ? chunks[chunks.length - 1] : void 0,
|
|
14959
|
+
metrics: {}
|
|
14960
|
+
})
|
|
14961
|
+
})
|
|
14962
|
+
);
|
|
14963
|
+
const callModelChannel = openRouterAgentChannels.callModel.tracingChannel();
|
|
14964
|
+
const callModelHandlers = {
|
|
14965
|
+
start: (event) => {
|
|
14966
|
+
const request = getOpenRouterCallModelRequestArg(event.arguments);
|
|
14967
|
+
if (!request) {
|
|
14968
|
+
return;
|
|
14969
|
+
}
|
|
14970
|
+
patchOpenRouterCallModelRequestTools(request);
|
|
14971
|
+
}
|
|
14972
|
+
};
|
|
14973
|
+
callModelChannel.subscribe(callModelHandlers);
|
|
14974
|
+
this.unsubscribers.push(() => {
|
|
14975
|
+
callModelChannel.unsubscribe(callModelHandlers);
|
|
14976
|
+
});
|
|
14977
|
+
}
|
|
14978
|
+
};
|
|
14979
|
+
function normalizeArgs(args) {
|
|
14980
|
+
if (Array.isArray(args)) {
|
|
14981
|
+
return args;
|
|
14982
|
+
}
|
|
14983
|
+
if (isArrayLike(args)) {
|
|
14984
|
+
return Array.from(args);
|
|
14985
|
+
}
|
|
14986
|
+
return [args];
|
|
14987
|
+
}
|
|
14988
|
+
function isArrayLike(value) {
|
|
14989
|
+
return isObject(value) && "length" in value && typeof value.length === "number" && Number.isInteger(value.length) && value.length >= 0;
|
|
14990
|
+
}
|
|
14991
|
+
function getOpenRouterCallModelRequestArg(args) {
|
|
14992
|
+
const normalizedArgs = normalizeArgs(args);
|
|
14993
|
+
const keyedRequestArg = normalizedArgs.find(
|
|
14994
|
+
(arg) => isObject(arg) && ("input" in arg || "model" in arg || "tools" in arg)
|
|
14995
|
+
);
|
|
14996
|
+
if (isObject(keyedRequestArg)) {
|
|
14997
|
+
return keyedRequestArg;
|
|
14998
|
+
}
|
|
14999
|
+
const firstObjectArg = normalizedArgs.find((arg) => isObject(arg));
|
|
15000
|
+
return isObject(firstObjectArg) ? firstObjectArg : void 0;
|
|
15001
|
+
}
|
|
15002
|
+
var TOKEN_NAME_MAP2 = {
|
|
15003
|
+
promptTokens: "prompt_tokens",
|
|
15004
|
+
inputTokens: "prompt_tokens",
|
|
15005
|
+
completionTokens: "completion_tokens",
|
|
15006
|
+
outputTokens: "completion_tokens",
|
|
15007
|
+
totalTokens: "tokens",
|
|
15008
|
+
prompt_tokens: "prompt_tokens",
|
|
15009
|
+
input_tokens: "prompt_tokens",
|
|
15010
|
+
completion_tokens: "completion_tokens",
|
|
15011
|
+
output_tokens: "completion_tokens",
|
|
15012
|
+
total_tokens: "tokens"
|
|
15013
|
+
};
|
|
15014
|
+
var TOKEN_DETAIL_PREFIX_MAP = {
|
|
15015
|
+
promptTokensDetails: "prompt",
|
|
15016
|
+
inputTokensDetails: "prompt",
|
|
15017
|
+
completionTokensDetails: "completion",
|
|
15018
|
+
outputTokensDetails: "completion",
|
|
15019
|
+
costDetails: "cost",
|
|
15020
|
+
prompt_tokens_details: "prompt",
|
|
15021
|
+
input_tokens_details: "prompt",
|
|
15022
|
+
completion_tokens_details: "completion",
|
|
15023
|
+
output_tokens_details: "completion",
|
|
15024
|
+
cost_details: "cost"
|
|
15025
|
+
};
|
|
15026
|
+
function camelToSnake(value) {
|
|
15027
|
+
return value.replace(/[A-Z]/g, (match) => `_${match.toLowerCase()}`);
|
|
15028
|
+
}
|
|
15029
|
+
function parseOpenRouterMetricsFromUsage(usage) {
|
|
15030
|
+
if (!isObject(usage)) {
|
|
15031
|
+
return {};
|
|
15032
|
+
}
|
|
15033
|
+
const metrics = {};
|
|
15034
|
+
for (const [name, value] of Object.entries(usage)) {
|
|
15035
|
+
if (typeof value === "number") {
|
|
15036
|
+
metrics[TOKEN_NAME_MAP2[name] || camelToSnake(name)] = value;
|
|
15037
|
+
continue;
|
|
15038
|
+
}
|
|
15039
|
+
if (!isObject(value)) {
|
|
15040
|
+
continue;
|
|
15041
|
+
}
|
|
15042
|
+
const prefix = TOKEN_DETAIL_PREFIX_MAP[name];
|
|
15043
|
+
if (!prefix) {
|
|
15044
|
+
continue;
|
|
15045
|
+
}
|
|
15046
|
+
for (const [nestedName, nestedValue] of Object.entries(value)) {
|
|
15047
|
+
if (typeof nestedValue !== "number") {
|
|
15048
|
+
continue;
|
|
15049
|
+
}
|
|
15050
|
+
metrics[`${prefix}_${camelToSnake(nestedName)}`] = nestedValue;
|
|
15051
|
+
}
|
|
15052
|
+
}
|
|
15053
|
+
return metrics;
|
|
15054
|
+
}
|
|
15055
|
+
function extractOpenRouterUsageMetadata(usage) {
|
|
15056
|
+
if (!isObject(usage)) {
|
|
15057
|
+
return void 0;
|
|
15058
|
+
}
|
|
15059
|
+
const metadata = {};
|
|
15060
|
+
if (typeof usage.isByok === "boolean") {
|
|
15061
|
+
metadata.is_byok = usage.isByok;
|
|
15062
|
+
} else if (typeof usage.is_byok === "boolean") {
|
|
15063
|
+
metadata.is_byok = usage.is_byok;
|
|
15064
|
+
}
|
|
15065
|
+
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
15066
|
+
}
|
|
15067
|
+
var OMITTED_OPENROUTER_KEYS = /* @__PURE__ */ new Set([
|
|
15068
|
+
"execute",
|
|
15069
|
+
"render",
|
|
15070
|
+
"nextTurnParams",
|
|
15071
|
+
"requireApproval"
|
|
15072
|
+
]);
|
|
15073
|
+
function parseOpenRouterModelString(model) {
|
|
15074
|
+
if (typeof model !== "string") {
|
|
15075
|
+
return { model };
|
|
15076
|
+
}
|
|
15077
|
+
const slashIndex = model.indexOf("/");
|
|
15078
|
+
if (slashIndex > 0 && slashIndex < model.length - 1) {
|
|
15079
|
+
return {
|
|
15080
|
+
provider: model.substring(0, slashIndex),
|
|
15081
|
+
model: model.substring(slashIndex + 1)
|
|
15082
|
+
};
|
|
15083
|
+
}
|
|
15084
|
+
return { model };
|
|
15085
|
+
}
|
|
15086
|
+
function isZodSchema3(value) {
|
|
15087
|
+
return value != null && typeof value === "object" && "_def" in value && typeof value._def === "object";
|
|
15088
|
+
}
|
|
15089
|
+
function serializeZodSchema3(schema) {
|
|
15090
|
+
try {
|
|
15091
|
+
return zodToJsonSchema(schema);
|
|
15092
|
+
} catch {
|
|
15093
|
+
return {
|
|
15094
|
+
type: "object",
|
|
15095
|
+
description: "Zod schema (conversion failed)"
|
|
15096
|
+
};
|
|
15097
|
+
}
|
|
15098
|
+
}
|
|
15099
|
+
function serializeOpenRouterTool(tool) {
|
|
15100
|
+
if (!isObject(tool)) {
|
|
15101
|
+
return tool;
|
|
15102
|
+
}
|
|
15103
|
+
const serialized = {};
|
|
15104
|
+
for (const [key, value] of Object.entries(tool)) {
|
|
15105
|
+
if (OMITTED_OPENROUTER_KEYS.has(key)) {
|
|
15106
|
+
continue;
|
|
15107
|
+
}
|
|
15108
|
+
if (key === "function" && isObject(value)) {
|
|
15109
|
+
serialized.function = sanitizeOpenRouterLoggedValue(value);
|
|
15110
|
+
continue;
|
|
15111
|
+
}
|
|
15112
|
+
serialized[key] = sanitizeOpenRouterLoggedValue(value);
|
|
15113
|
+
}
|
|
15114
|
+
return serialized;
|
|
15115
|
+
}
|
|
15116
|
+
function serializeOpenRouterToolsForLogging(tools) {
|
|
15117
|
+
if (!Array.isArray(tools)) {
|
|
15118
|
+
return void 0;
|
|
15119
|
+
}
|
|
15120
|
+
return tools.map((tool) => serializeOpenRouterTool(tool));
|
|
15121
|
+
}
|
|
15122
|
+
function sanitizeOpenRouterLoggedValue(value) {
|
|
15123
|
+
if (isZodSchema3(value)) {
|
|
15124
|
+
return serializeZodSchema3(value);
|
|
15125
|
+
}
|
|
15126
|
+
if (typeof value === "function") {
|
|
15127
|
+
return "[Function]";
|
|
15128
|
+
}
|
|
15129
|
+
if (Array.isArray(value)) {
|
|
15130
|
+
return value.map((entry) => sanitizeOpenRouterLoggedValue(entry));
|
|
15131
|
+
}
|
|
15132
|
+
if (!isObject(value)) {
|
|
15133
|
+
return value;
|
|
15134
|
+
}
|
|
15135
|
+
const sanitized = {};
|
|
15136
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
15137
|
+
if (OMITTED_OPENROUTER_KEYS.has(key)) {
|
|
15138
|
+
continue;
|
|
15139
|
+
}
|
|
15140
|
+
if (key === "tools" && Array.isArray(entry)) {
|
|
15141
|
+
sanitized.tools = serializeOpenRouterToolsForLogging(entry);
|
|
15142
|
+
continue;
|
|
15143
|
+
}
|
|
15144
|
+
sanitized[key] = sanitizeOpenRouterLoggedValue(entry);
|
|
15145
|
+
}
|
|
15146
|
+
return sanitized;
|
|
15147
|
+
}
|
|
15148
|
+
function buildOpenRouterMetadata(metadata, httpReferer, appTitle, appCategories, xTitle) {
|
|
15149
|
+
const sanitized = sanitizeOpenRouterLoggedValue(metadata);
|
|
15150
|
+
const metadataRecord = isObject(sanitized) ? sanitized : {};
|
|
15151
|
+
const { model, provider: providerRouting, ...rest } = metadataRecord;
|
|
15152
|
+
const normalizedModel = parseOpenRouterModelString(model);
|
|
15153
|
+
return {
|
|
15154
|
+
...rest,
|
|
15155
|
+
...normalizedModel.model !== void 0 ? { model: normalizedModel.model } : {},
|
|
15156
|
+
...providerRouting !== void 0 ? { providerRouting } : {},
|
|
15157
|
+
...httpReferer !== void 0 ? { httpReferer } : {},
|
|
15158
|
+
...appTitle !== void 0 ? { appTitle } : {},
|
|
15159
|
+
...appCategories !== void 0 ? { appCategories } : {},
|
|
15160
|
+
...xTitle !== void 0 ? { xTitle } : {},
|
|
15161
|
+
provider: normalizedModel.provider || "openrouter"
|
|
15162
|
+
};
|
|
15163
|
+
}
|
|
15164
|
+
function extractOpenRouterCallModelInput(request) {
|
|
15165
|
+
return isObject(request) && "input" in request ? sanitizeOpenRouterLoggedValue(request.input) : void 0;
|
|
15166
|
+
}
|
|
15167
|
+
function extractOpenRouterCallModelMetadata(request) {
|
|
15168
|
+
if (!isObject(request)) {
|
|
15169
|
+
return { provider: "openrouter" };
|
|
15170
|
+
}
|
|
15171
|
+
const { input: _input, ...metadata } = request;
|
|
15172
|
+
return buildOpenRouterMetadata(
|
|
15173
|
+
metadata,
|
|
15174
|
+
void 0,
|
|
15175
|
+
void 0,
|
|
15176
|
+
void 0,
|
|
15177
|
+
void 0
|
|
15178
|
+
);
|
|
15179
|
+
}
|
|
15180
|
+
function extractOpenRouterResponseMetadata(result) {
|
|
15181
|
+
if (!isObject(result)) {
|
|
15182
|
+
return void 0;
|
|
15183
|
+
}
|
|
15184
|
+
const { output: _output, data: _data, usage, ...metadata } = result;
|
|
15185
|
+
const sanitized = sanitizeOpenRouterLoggedValue(metadata);
|
|
15186
|
+
const metadataRecord = isObject(sanitized) ? sanitized : {};
|
|
15187
|
+
const { model, provider, ...rest } = metadataRecord;
|
|
15188
|
+
const normalizedModel = parseOpenRouterModelString(model);
|
|
15189
|
+
const normalizedProvider = (typeof provider === "string" ? provider : void 0) || normalizedModel.provider;
|
|
15190
|
+
const usageMetadata = extractOpenRouterUsageMetadata(usage);
|
|
15191
|
+
const combined = {
|
|
15192
|
+
...rest,
|
|
15193
|
+
...normalizedModel.model !== void 0 ? { model: normalizedModel.model } : {},
|
|
15194
|
+
...usageMetadata || {},
|
|
15195
|
+
...normalizedProvider !== void 0 ? { provider: normalizedProvider } : {}
|
|
15196
|
+
};
|
|
15197
|
+
return Object.keys(combined).length > 0 ? combined : void 0;
|
|
15198
|
+
}
|
|
15199
|
+
function extractOpenRouterResponseOutput(response, fallbackOutput) {
|
|
15200
|
+
if (isObject(response) && "output" in response && response.output !== void 0) {
|
|
15201
|
+
return sanitizeOpenRouterLoggedValue(response.output);
|
|
15202
|
+
}
|
|
15203
|
+
if (fallbackOutput !== void 0) {
|
|
15204
|
+
return sanitizeOpenRouterLoggedValue(fallbackOutput);
|
|
15205
|
+
}
|
|
15206
|
+
return void 0;
|
|
15207
|
+
}
|
|
15208
|
+
var OPENROUTER_WRAPPED_TOOL = Symbol("braintrust.openrouter.wrappedTool");
|
|
15209
|
+
function patchOpenRouterCallModelRequestTools(request) {
|
|
15210
|
+
if (!Array.isArray(request.tools) || request.tools.length === 0) {
|
|
15211
|
+
return void 0;
|
|
15212
|
+
}
|
|
15213
|
+
const originalTools = request.tools;
|
|
15214
|
+
const wrappedTools = originalTools.map((tool) => wrapOpenRouterTool(tool));
|
|
15215
|
+
const didPatch = wrappedTools.some(
|
|
15216
|
+
(tool, index) => tool !== originalTools[index]
|
|
15217
|
+
);
|
|
15218
|
+
if (!didPatch) {
|
|
15219
|
+
return void 0;
|
|
15220
|
+
}
|
|
15221
|
+
request.tools = wrappedTools;
|
|
15222
|
+
return () => {
|
|
15223
|
+
request.tools = originalTools;
|
|
15224
|
+
};
|
|
15225
|
+
}
|
|
15226
|
+
function wrapOpenRouterTool(tool) {
|
|
15227
|
+
if (isWrappedTool(tool) || !tool.function || typeof tool.function !== "object" || typeof tool.function.execute !== "function") {
|
|
15228
|
+
return tool;
|
|
15229
|
+
}
|
|
15230
|
+
const toolName = tool.function.name || "tool";
|
|
15231
|
+
const originalExecute = tool.function.execute;
|
|
15232
|
+
const wrappedTool = {
|
|
15233
|
+
...tool,
|
|
15234
|
+
function: {
|
|
15235
|
+
...tool.function,
|
|
15236
|
+
execute(...args) {
|
|
15237
|
+
return traceToolExecution({
|
|
15238
|
+
args,
|
|
15239
|
+
execute: () => Reflect.apply(originalExecute, this, args),
|
|
15240
|
+
toolCallId: getToolCallId(args[1]),
|
|
15241
|
+
toolName
|
|
15242
|
+
});
|
|
15243
|
+
}
|
|
15244
|
+
}
|
|
15245
|
+
};
|
|
15246
|
+
Object.defineProperty(wrappedTool, OPENROUTER_WRAPPED_TOOL, {
|
|
15247
|
+
value: true,
|
|
15248
|
+
enumerable: false,
|
|
15249
|
+
configurable: false
|
|
15250
|
+
});
|
|
15251
|
+
return wrappedTool;
|
|
15252
|
+
}
|
|
15253
|
+
function isWrappedTool(tool) {
|
|
15254
|
+
return Boolean(tool[OPENROUTER_WRAPPED_TOOL]);
|
|
15255
|
+
}
|
|
15256
|
+
function traceToolExecution(args) {
|
|
15257
|
+
const tracingChannel2 = openRouterAgentChannels.toolExecute.tracingChannel();
|
|
15258
|
+
const input = args.args.length > 0 ? args.args[0] : void 0;
|
|
15259
|
+
const event = {
|
|
15260
|
+
arguments: [input],
|
|
15261
|
+
span_info: {
|
|
15262
|
+
name: args.toolName
|
|
15263
|
+
},
|
|
15264
|
+
toolCallId: args.toolCallId,
|
|
15265
|
+
toolName: args.toolName
|
|
15266
|
+
};
|
|
15267
|
+
tracingChannel2.start.publish(event);
|
|
15268
|
+
try {
|
|
15269
|
+
const result = args.execute();
|
|
15270
|
+
return publishToolResult(tracingChannel2, event, result);
|
|
15271
|
+
} catch (error) {
|
|
15272
|
+
event.error = normalizeError(error);
|
|
15273
|
+
tracingChannel2.error.publish(event);
|
|
15274
|
+
throw error;
|
|
15275
|
+
}
|
|
15276
|
+
}
|
|
15277
|
+
function publishToolResult(tracingChannel2, event, result) {
|
|
15278
|
+
if (isPromiseLike3(result)) {
|
|
15279
|
+
return result.then(
|
|
15280
|
+
(resolved) => {
|
|
15281
|
+
event.result = resolved;
|
|
15282
|
+
tracingChannel2.asyncEnd.publish(event);
|
|
15283
|
+
return resolved;
|
|
15284
|
+
},
|
|
15285
|
+
(error) => {
|
|
15286
|
+
event.error = normalizeError(error);
|
|
15287
|
+
tracingChannel2.error.publish(event);
|
|
15288
|
+
throw error;
|
|
15289
|
+
}
|
|
15290
|
+
);
|
|
15291
|
+
}
|
|
15292
|
+
event.result = result;
|
|
15293
|
+
tracingChannel2.asyncEnd.publish(event);
|
|
15294
|
+
return result;
|
|
15295
|
+
}
|
|
15296
|
+
function getToolCallId(context) {
|
|
15297
|
+
const toolContext = context;
|
|
15298
|
+
return typeof toolContext?.toolCall?.id === "string" ? toolContext.toolCall.id : void 0;
|
|
15299
|
+
}
|
|
15300
|
+
function isPromiseLike3(value) {
|
|
15301
|
+
return !!value && (typeof value === "object" || typeof value === "function") && "then" in value && typeof value.then === "function";
|
|
15302
|
+
}
|
|
15303
|
+
var OPENROUTER_WRAPPED_CALL_MODEL_RESULT = Symbol(
|
|
15304
|
+
"braintrust.openrouter.wrappedCallModelResult"
|
|
15305
|
+
);
|
|
15306
|
+
var OPENROUTER_CALL_MODEL_STREAM_METHODS = [
|
|
15307
|
+
"getFullResponsesStream",
|
|
15308
|
+
"getItemsStream",
|
|
15309
|
+
"getNewMessagesStream",
|
|
15310
|
+
"getReasoningStream",
|
|
15311
|
+
"getTextStream",
|
|
15312
|
+
"getToolCallsStream",
|
|
15313
|
+
"getToolStream"
|
|
15314
|
+
];
|
|
15315
|
+
var OPENROUTER_CALL_MODEL_CONTEXT_METHODS = [
|
|
15316
|
+
"cancel",
|
|
15317
|
+
"getPendingToolCalls",
|
|
15318
|
+
"getState",
|
|
15319
|
+
"getToolCalls",
|
|
15320
|
+
"requiresApproval"
|
|
15321
|
+
];
|
|
15322
|
+
function patchOpenRouterCallModelResult(args) {
|
|
15323
|
+
const { request, result, span } = args;
|
|
15324
|
+
if (!isObject(result) || isWrappedCallModelResult(result)) {
|
|
15325
|
+
return false;
|
|
15326
|
+
}
|
|
15327
|
+
const resultLike = result;
|
|
15328
|
+
const hasInstrumentableMethod = typeof resultLike.getResponse === "function" || typeof resultLike.getText === "function" || OPENROUTER_CALL_MODEL_STREAM_METHODS.some(
|
|
15329
|
+
(methodName) => typeof resultLike[methodName] === "function"
|
|
15330
|
+
);
|
|
15331
|
+
if (!hasInstrumentableMethod) {
|
|
15332
|
+
return false;
|
|
15333
|
+
}
|
|
15334
|
+
Object.defineProperty(resultLike, OPENROUTER_WRAPPED_CALL_MODEL_RESULT, {
|
|
15335
|
+
value: true,
|
|
15336
|
+
enumerable: false,
|
|
15337
|
+
configurable: false
|
|
15338
|
+
});
|
|
15339
|
+
const originalGetResponse = typeof resultLike.getResponse === "function" ? resultLike.getResponse.bind(resultLike) : void 0;
|
|
15340
|
+
const originalGetInitialResponse = typeof resultLike.getInitialResponse === "function" ? resultLike.getInitialResponse.bind(resultLike) : void 0;
|
|
15341
|
+
const originalMakeFollowupRequest = typeof resultLike.makeFollowupRequest === "function" ? resultLike.makeFollowupRequest.bind(resultLike) : void 0;
|
|
15342
|
+
let ended = false;
|
|
15343
|
+
let tracedTurnCount = 0;
|
|
15344
|
+
const endSpanWithResult = async (response, fallbackOutput) => {
|
|
15345
|
+
if (ended) {
|
|
15346
|
+
return;
|
|
15347
|
+
}
|
|
15348
|
+
ended = true;
|
|
15349
|
+
const finalResponse = getFinalOpenRouterCallModelResponse(
|
|
15350
|
+
resultLike,
|
|
15351
|
+
response
|
|
15352
|
+
);
|
|
15353
|
+
if (finalResponse) {
|
|
15354
|
+
const rounds = getOpenRouterCallModelRounds(resultLike);
|
|
15355
|
+
const metadata = extractOpenRouterCallModelResultMetadata(
|
|
15356
|
+
finalResponse,
|
|
15357
|
+
rounds.length + 1
|
|
15358
|
+
);
|
|
15359
|
+
span.log({
|
|
15360
|
+
output: extractOpenRouterResponseOutput(finalResponse, fallbackOutput),
|
|
15361
|
+
...metadata ? { metadata } : {},
|
|
15362
|
+
metrics: aggregateOpenRouterCallModelMetrics(rounds, finalResponse)
|
|
15363
|
+
});
|
|
15364
|
+
span.end();
|
|
15365
|
+
return;
|
|
15366
|
+
}
|
|
15367
|
+
if (fallbackOutput !== void 0) {
|
|
15368
|
+
span.log({
|
|
15369
|
+
output: fallbackOutput
|
|
15370
|
+
});
|
|
15371
|
+
}
|
|
15372
|
+
span.end();
|
|
15373
|
+
};
|
|
15374
|
+
const endSpanWithError = (error) => {
|
|
15375
|
+
if (ended) {
|
|
15376
|
+
return;
|
|
15377
|
+
}
|
|
15378
|
+
ended = true;
|
|
15379
|
+
span.log({
|
|
15380
|
+
error: normalizeError(error).message
|
|
15381
|
+
});
|
|
15382
|
+
span.end();
|
|
15383
|
+
};
|
|
15384
|
+
const finalizeFromResponse = async (fallbackOutput) => {
|
|
15385
|
+
if (!originalGetResponse) {
|
|
15386
|
+
await endSpanWithResult(void 0, fallbackOutput);
|
|
15387
|
+
return;
|
|
15388
|
+
}
|
|
15389
|
+
try {
|
|
15390
|
+
await endSpanWithResult(await originalGetResponse(), fallbackOutput);
|
|
15391
|
+
} catch {
|
|
15392
|
+
await endSpanWithResult(void 0, fallbackOutput);
|
|
15393
|
+
}
|
|
15394
|
+
};
|
|
15395
|
+
if (originalGetResponse) {
|
|
15396
|
+
resultLike.getResponse = async (...args2) => {
|
|
15397
|
+
return await withCurrent(span, async () => {
|
|
15398
|
+
try {
|
|
15399
|
+
const response = await originalGetResponse(...args2);
|
|
15400
|
+
await endSpanWithResult(response);
|
|
15401
|
+
return response;
|
|
15402
|
+
} catch (error) {
|
|
15403
|
+
endSpanWithError(error);
|
|
15404
|
+
throw error;
|
|
15405
|
+
}
|
|
15406
|
+
});
|
|
15407
|
+
};
|
|
15408
|
+
}
|
|
15409
|
+
if (typeof resultLike.getText === "function") {
|
|
15410
|
+
const originalGetText = resultLike.getText.bind(resultLike);
|
|
15411
|
+
resultLike.getText = async (...args2) => {
|
|
15412
|
+
return await withCurrent(span, async () => {
|
|
15413
|
+
try {
|
|
15414
|
+
const text = await originalGetText(...args2);
|
|
15415
|
+
await finalizeFromResponse(text);
|
|
15416
|
+
return text;
|
|
15417
|
+
} catch (error) {
|
|
15418
|
+
endSpanWithError(error);
|
|
15419
|
+
throw error;
|
|
15420
|
+
}
|
|
15421
|
+
});
|
|
15422
|
+
};
|
|
15423
|
+
}
|
|
15424
|
+
for (const methodName of OPENROUTER_CALL_MODEL_CONTEXT_METHODS) {
|
|
15425
|
+
if (typeof resultLike[methodName] !== "function") {
|
|
15426
|
+
continue;
|
|
15427
|
+
}
|
|
15428
|
+
const originalMethod = resultLike[methodName];
|
|
15429
|
+
resultLike[methodName] = async (...args2) => {
|
|
15430
|
+
return await withCurrent(span, async () => {
|
|
15431
|
+
return await originalMethod.apply(resultLike, args2);
|
|
15432
|
+
});
|
|
15433
|
+
};
|
|
15434
|
+
}
|
|
15435
|
+
for (const methodName of OPENROUTER_CALL_MODEL_STREAM_METHODS) {
|
|
15436
|
+
if (typeof resultLike[methodName] !== "function") {
|
|
15437
|
+
continue;
|
|
15438
|
+
}
|
|
15439
|
+
const originalMethod = resultLike[methodName];
|
|
15440
|
+
resultLike[methodName] = (...args2) => {
|
|
15441
|
+
const stream = withCurrent(
|
|
15442
|
+
span,
|
|
15443
|
+
() => originalMethod.apply(resultLike, args2)
|
|
15444
|
+
);
|
|
15445
|
+
if (!isAsyncIterable3(stream)) {
|
|
15446
|
+
return stream;
|
|
15447
|
+
}
|
|
15448
|
+
return wrapAsyncIterableWithSpan({
|
|
15449
|
+
finalize: finalizeFromResponse,
|
|
15450
|
+
iteratorFactory: () => stream[Symbol.asyncIterator](),
|
|
15451
|
+
onError: endSpanWithError,
|
|
15452
|
+
span
|
|
15453
|
+
});
|
|
15454
|
+
};
|
|
15455
|
+
}
|
|
15456
|
+
if (originalGetInitialResponse) {
|
|
15457
|
+
let initialTurnTraced = false;
|
|
15458
|
+
resultLike.getInitialResponse = async (...args2) => {
|
|
15459
|
+
if (initialTurnTraced) {
|
|
15460
|
+
return await withCurrent(span, async () => {
|
|
15461
|
+
return await originalGetInitialResponse(...args2);
|
|
15462
|
+
});
|
|
15463
|
+
}
|
|
15464
|
+
initialTurnTraced = true;
|
|
15465
|
+
const step = tracedTurnCount + 1;
|
|
15466
|
+
const stepType = tracedTurnCount === 0 ? "initial" : "continue";
|
|
15467
|
+
const response = await traceOpenRouterCallModelTurn({
|
|
15468
|
+
fn: async () => {
|
|
15469
|
+
const nextResponse = await originalGetInitialResponse(...args2);
|
|
15470
|
+
tracedTurnCount++;
|
|
15471
|
+
return nextResponse;
|
|
15472
|
+
},
|
|
15473
|
+
parentSpan: span,
|
|
15474
|
+
request: getOpenRouterResolvedRequest(resultLike, request),
|
|
15475
|
+
step,
|
|
15476
|
+
stepType
|
|
15477
|
+
});
|
|
15478
|
+
return response;
|
|
15479
|
+
};
|
|
15480
|
+
}
|
|
15481
|
+
if (originalMakeFollowupRequest) {
|
|
15482
|
+
resultLike.makeFollowupRequest = async (...args2) => {
|
|
15483
|
+
const currentResponse = args2[0];
|
|
15484
|
+
const toolResults = Array.isArray(args2[1]) ? args2[1] : [];
|
|
15485
|
+
const step = tracedTurnCount + 1;
|
|
15486
|
+
const response = await traceOpenRouterCallModelTurn({
|
|
15487
|
+
fn: async () => {
|
|
15488
|
+
const nextResponse = await originalMakeFollowupRequest(...args2);
|
|
15489
|
+
tracedTurnCount++;
|
|
15490
|
+
return nextResponse;
|
|
15491
|
+
},
|
|
15492
|
+
parentSpan: span,
|
|
15493
|
+
request: buildOpenRouterFollowupRequest(
|
|
15494
|
+
getOpenRouterResolvedRequest(resultLike, request),
|
|
15495
|
+
currentResponse,
|
|
15496
|
+
toolResults
|
|
15497
|
+
),
|
|
15498
|
+
step,
|
|
15499
|
+
stepType: "continue"
|
|
15500
|
+
});
|
|
15501
|
+
return response;
|
|
15502
|
+
};
|
|
15503
|
+
}
|
|
15504
|
+
return true;
|
|
15505
|
+
}
|
|
15506
|
+
async function traceOpenRouterCallModelTurn(args) {
|
|
15507
|
+
const context = {
|
|
15508
|
+
arguments: [args.request],
|
|
15509
|
+
step: args.step,
|
|
15510
|
+
stepType: args.stepType
|
|
15511
|
+
};
|
|
15512
|
+
return await withCurrent(
|
|
15513
|
+
args.parentSpan,
|
|
15514
|
+
() => openRouterAgentChannels.callModelTurn.tracePromise(args.fn, context)
|
|
15515
|
+
);
|
|
15516
|
+
}
|
|
15517
|
+
function isWrappedCallModelResult(value) {
|
|
15518
|
+
return Boolean(
|
|
15519
|
+
isObject(value) && value[OPENROUTER_WRAPPED_CALL_MODEL_RESULT]
|
|
15520
|
+
);
|
|
15521
|
+
}
|
|
15522
|
+
function extractOpenRouterCallModelResultMetadata(response, turnCount) {
|
|
15523
|
+
const combined = {
|
|
15524
|
+
...extractOpenRouterResponseMetadata(response) || {},
|
|
15525
|
+
...turnCount !== void 0 ? { turn_count: turnCount } : {}
|
|
15526
|
+
};
|
|
15527
|
+
return Object.keys(combined).length > 0 ? combined : void 0;
|
|
15528
|
+
}
|
|
15529
|
+
function getFinalOpenRouterCallModelResponse(result, response) {
|
|
15530
|
+
if (isObject(response)) {
|
|
15531
|
+
return response;
|
|
15532
|
+
}
|
|
15533
|
+
return isObject(result.finalResponse) ? result.finalResponse : void 0;
|
|
15534
|
+
}
|
|
15535
|
+
function getOpenRouterCallModelRounds(result) {
|
|
15536
|
+
if (!Array.isArray(result.allToolExecutionRounds)) {
|
|
15537
|
+
return [];
|
|
15538
|
+
}
|
|
15539
|
+
return result.allToolExecutionRounds.filter((round) => isObject(round)).map((round) => ({
|
|
15540
|
+
response: isObject(round.response) ? round.response : void 0,
|
|
15541
|
+
round: typeof round.round === "number" ? round.round : void 0,
|
|
15542
|
+
toolResults: Array.isArray(round.toolResults) ? round.toolResults : []
|
|
15543
|
+
})).filter((round) => round.response !== void 0);
|
|
15544
|
+
}
|
|
15545
|
+
function aggregateOpenRouterCallModelMetrics(rounds, finalResponse) {
|
|
15546
|
+
const metrics = {};
|
|
15547
|
+
const responses = [
|
|
15548
|
+
...rounds.map((round) => round.response).filter(isObject),
|
|
15549
|
+
finalResponse
|
|
15550
|
+
];
|
|
15551
|
+
for (const response of responses) {
|
|
15552
|
+
const responseMetrics = parseOpenRouterMetricsFromUsage(response.usage);
|
|
15553
|
+
for (const [name, value] of Object.entries(responseMetrics)) {
|
|
15554
|
+
metrics[name] = (metrics[name] || 0) + value;
|
|
15555
|
+
}
|
|
15556
|
+
}
|
|
15557
|
+
return metrics;
|
|
15558
|
+
}
|
|
15559
|
+
function buildNextOpenRouterCallModelInput(currentInput, response, toolResults) {
|
|
15560
|
+
const normalizedInput = Array.isArray(currentInput) ? [...currentInput] : currentInput === void 0 ? [] : [currentInput];
|
|
15561
|
+
const responseOutput = Array.isArray(response.output) ? response.output : response.output === void 0 ? [] : [response.output];
|
|
15562
|
+
return [...normalizedInput, ...responseOutput, ...toolResults].map(
|
|
15563
|
+
(entry) => sanitizeOpenRouterLoggedValue(entry)
|
|
15564
|
+
);
|
|
15565
|
+
}
|
|
15566
|
+
function getOpenRouterResolvedRequest(result, request) {
|
|
15567
|
+
if (isObject(result.resolvedRequest)) {
|
|
15568
|
+
return result.resolvedRequest;
|
|
15569
|
+
}
|
|
15570
|
+
return request;
|
|
15571
|
+
}
|
|
15572
|
+
function buildOpenRouterFollowupRequest(request, currentResponse, toolResults) {
|
|
15573
|
+
if (!request) {
|
|
15574
|
+
return void 0;
|
|
15575
|
+
}
|
|
15576
|
+
return {
|
|
15577
|
+
...request,
|
|
15578
|
+
input: buildNextOpenRouterCallModelInput(
|
|
15579
|
+
extractOpenRouterCallModelInput(request),
|
|
15580
|
+
isObject(currentResponse) ? currentResponse : {},
|
|
15581
|
+
toolResults
|
|
15582
|
+
),
|
|
15583
|
+
stream: false
|
|
15584
|
+
};
|
|
15585
|
+
}
|
|
15586
|
+
function wrapAsyncIterableWithSpan(args) {
|
|
15587
|
+
return {
|
|
15588
|
+
[Symbol.asyncIterator]() {
|
|
15589
|
+
const iterator = args.iteratorFactory();
|
|
15590
|
+
return {
|
|
15591
|
+
next(value) {
|
|
15592
|
+
return withCurrent(
|
|
15593
|
+
args.span,
|
|
15594
|
+
() => value === void 0 ? iterator.next() : iterator.next(value)
|
|
15595
|
+
).then(
|
|
15596
|
+
async (result) => {
|
|
15597
|
+
if (result.done) {
|
|
15598
|
+
await args.finalize();
|
|
15599
|
+
}
|
|
15600
|
+
return result;
|
|
15601
|
+
},
|
|
15602
|
+
(error) => {
|
|
15603
|
+
args.onError(error);
|
|
15604
|
+
throw error;
|
|
15605
|
+
}
|
|
15606
|
+
);
|
|
15607
|
+
},
|
|
15608
|
+
return(value) {
|
|
15609
|
+
if (typeof iterator.return !== "function") {
|
|
15610
|
+
return args.finalize().then(() => ({
|
|
15611
|
+
done: true,
|
|
15612
|
+
value
|
|
15613
|
+
}));
|
|
15614
|
+
}
|
|
15615
|
+
return withCurrent(args.span, () => iterator.return(value)).then(
|
|
15616
|
+
async (result) => {
|
|
15617
|
+
await args.finalize();
|
|
15618
|
+
return result;
|
|
15619
|
+
},
|
|
15620
|
+
(error) => {
|
|
15621
|
+
args.onError(error);
|
|
15622
|
+
throw error;
|
|
15623
|
+
}
|
|
15624
|
+
);
|
|
15625
|
+
},
|
|
15626
|
+
throw(error) {
|
|
15627
|
+
args.onError(error);
|
|
15628
|
+
if (typeof iterator.throw !== "function") {
|
|
15629
|
+
return Promise.reject(error);
|
|
15630
|
+
}
|
|
15631
|
+
return withCurrent(args.span, () => iterator.throw(error));
|
|
15632
|
+
},
|
|
15633
|
+
[Symbol.asyncIterator]() {
|
|
15634
|
+
return this;
|
|
15635
|
+
}
|
|
15636
|
+
};
|
|
15637
|
+
}
|
|
15638
|
+
};
|
|
15639
|
+
}
|
|
15640
|
+
function isAsyncIterable3(value) {
|
|
15641
|
+
return !!value && (typeof value === "object" || typeof value === "function") && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
15642
|
+
}
|
|
15643
|
+
function normalizeError(error) {
|
|
15644
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
15645
|
+
}
|
|
15646
|
+
|
|
15647
|
+
// src/instrumentation/plugins/openrouter-channels.ts
|
|
15648
|
+
var openRouterChannels = defineChannels("@openrouter/sdk", {
|
|
15649
|
+
chatSend: channel({
|
|
15650
|
+
channelName: "chat.send",
|
|
15651
|
+
kind: "async"
|
|
15652
|
+
}),
|
|
15653
|
+
embeddingsGenerate: channel({
|
|
15654
|
+
channelName: "embeddings.generate",
|
|
15655
|
+
kind: "async"
|
|
15656
|
+
}),
|
|
15657
|
+
betaResponsesSend: channel({
|
|
15658
|
+
channelName: "beta.responses.send",
|
|
15659
|
+
kind: "async"
|
|
15660
|
+
}),
|
|
15661
|
+
callModel: channel({
|
|
15662
|
+
channelName: "callModel",
|
|
15663
|
+
kind: "sync-stream"
|
|
15664
|
+
}),
|
|
15665
|
+
callModelTurn: channel({
|
|
15666
|
+
channelName: "callModel.turn",
|
|
15667
|
+
kind: "async"
|
|
15668
|
+
}),
|
|
15669
|
+
toolExecute: channel({
|
|
15670
|
+
channelName: "tool.execute",
|
|
15671
|
+
kind: "async"
|
|
15672
|
+
})
|
|
15673
|
+
});
|
|
15674
|
+
|
|
15675
|
+
// src/instrumentation/plugins/openrouter-plugin.ts
|
|
15676
|
+
var OpenRouterPlugin = class extends BasePlugin {
|
|
15677
|
+
onEnable() {
|
|
15678
|
+
this.subscribeToOpenRouterChannels();
|
|
15679
|
+
}
|
|
15680
|
+
onDisable() {
|
|
15681
|
+
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
15682
|
+
}
|
|
15683
|
+
subscribeToOpenRouterChannels() {
|
|
15684
|
+
this.unsubscribers.push(
|
|
15685
|
+
traceStreamingChannel(openRouterChannels.chatSend, {
|
|
15686
|
+
name: "openrouter.chat.send",
|
|
15687
|
+
type: "llm" /* LLM */,
|
|
15688
|
+
extractInput: (args) => {
|
|
15689
|
+
const request = getOpenRouterRequestArg(args);
|
|
15690
|
+
const chatGenerationParams = isObject(request?.chatGenerationParams) ? request.chatGenerationParams : {};
|
|
15691
|
+
const httpReferer = request?.httpReferer;
|
|
15692
|
+
const xTitle = request?.xTitle;
|
|
15693
|
+
const { messages, ...metadata } = chatGenerationParams;
|
|
15694
|
+
return {
|
|
15695
|
+
input: messages,
|
|
15696
|
+
metadata: buildOpenRouterMetadata2(metadata, httpReferer, xTitle)
|
|
15697
|
+
};
|
|
15698
|
+
},
|
|
15699
|
+
extractOutput: (result) => {
|
|
15700
|
+
return isObject(result) ? result.choices : void 0;
|
|
15701
|
+
},
|
|
15702
|
+
extractMetrics: (result, startTime) => {
|
|
15703
|
+
const metrics = parseOpenRouterMetricsFromUsage2(result?.usage);
|
|
15704
|
+
if (startTime) {
|
|
15705
|
+
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
15706
|
+
}
|
|
15707
|
+
return metrics;
|
|
15708
|
+
},
|
|
15709
|
+
aggregateChunks: aggregateOpenRouterChatChunks
|
|
15710
|
+
})
|
|
15711
|
+
);
|
|
15712
|
+
this.unsubscribers.push(
|
|
15713
|
+
traceAsyncChannel(openRouterChannels.embeddingsGenerate, {
|
|
15714
|
+
name: "openrouter.embeddings.generate",
|
|
15715
|
+
type: "llm" /* LLM */,
|
|
15716
|
+
extractInput: (args) => {
|
|
15717
|
+
const request = getOpenRouterRequestArg(args);
|
|
15718
|
+
const requestBody = isObject(request?.requestBody) ? request.requestBody : {};
|
|
15719
|
+
const httpReferer = request?.httpReferer;
|
|
15720
|
+
const xTitle = request?.xTitle;
|
|
15721
|
+
const { input, ...metadata } = requestBody;
|
|
15722
|
+
return {
|
|
15723
|
+
input,
|
|
15724
|
+
metadata: buildOpenRouterEmbeddingMetadata(
|
|
15725
|
+
metadata,
|
|
15726
|
+
httpReferer,
|
|
15727
|
+
xTitle
|
|
15728
|
+
)
|
|
15729
|
+
};
|
|
15730
|
+
},
|
|
15731
|
+
extractOutput: (result) => {
|
|
15732
|
+
if (!isObject(result)) {
|
|
15733
|
+
return void 0;
|
|
14254
15734
|
}
|
|
14255
15735
|
const embedding = result.data?.[0]?.embedding;
|
|
14256
15736
|
return Array.isArray(embedding) ? { embedding_length: embedding.length } : void 0;
|
|
@@ -14259,10 +15739,10 @@ var OpenRouterPlugin = class extends BasePlugin {
|
|
|
14259
15739
|
if (!isObject(result)) {
|
|
14260
15740
|
return void 0;
|
|
14261
15741
|
}
|
|
14262
|
-
return
|
|
15742
|
+
return extractOpenRouterResponseMetadata2(result);
|
|
14263
15743
|
},
|
|
14264
15744
|
extractMetrics: (result) => {
|
|
14265
|
-
return isObject(result) ?
|
|
15745
|
+
return isObject(result) ? parseOpenRouterMetricsFromUsage2(result.usage) : {};
|
|
14266
15746
|
}
|
|
14267
15747
|
})
|
|
14268
15748
|
);
|
|
@@ -14278,13 +15758,13 @@ var OpenRouterPlugin = class extends BasePlugin {
|
|
|
14278
15758
|
const { input, ...metadata } = openResponsesRequest;
|
|
14279
15759
|
return {
|
|
14280
15760
|
input,
|
|
14281
|
-
metadata:
|
|
15761
|
+
metadata: buildOpenRouterMetadata2(metadata, httpReferer, xTitle)
|
|
14282
15762
|
};
|
|
14283
15763
|
},
|
|
14284
|
-
extractOutput: (result) =>
|
|
14285
|
-
extractMetadata: (result) =>
|
|
15764
|
+
extractOutput: (result) => extractOpenRouterResponseOutput2(result),
|
|
15765
|
+
extractMetadata: (result) => extractOpenRouterResponseMetadata2(result),
|
|
14286
15766
|
extractMetrics: (result, startTime) => {
|
|
14287
|
-
const metrics =
|
|
15767
|
+
const metrics = parseOpenRouterMetricsFromUsage2(result?.usage);
|
|
14288
15768
|
if (startTime) {
|
|
14289
15769
|
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
14290
15770
|
}
|
|
@@ -14298,15 +15778,15 @@ var OpenRouterPlugin = class extends BasePlugin {
|
|
|
14298
15778
|
name: "openrouter.callModel",
|
|
14299
15779
|
type: "llm" /* LLM */,
|
|
14300
15780
|
extractInput: (args) => {
|
|
14301
|
-
const request =
|
|
15781
|
+
const request = getOpenRouterCallModelRequestArg2(args);
|
|
14302
15782
|
return {
|
|
14303
|
-
input: request ?
|
|
14304
|
-
metadata: request ?
|
|
15783
|
+
input: request ? extractOpenRouterCallModelInput2(request) : void 0,
|
|
15784
|
+
metadata: request ? extractOpenRouterCallModelMetadata2(request) : { provider: "openrouter" }
|
|
14305
15785
|
};
|
|
14306
15786
|
},
|
|
14307
15787
|
patchResult: ({ endEvent, result, span }) => {
|
|
14308
|
-
return
|
|
14309
|
-
request:
|
|
15788
|
+
return patchOpenRouterCallModelResult2({
|
|
15789
|
+
request: getOpenRouterCallModelRequestArg2(endEvent.arguments),
|
|
14310
15790
|
result,
|
|
14311
15791
|
span
|
|
14312
15792
|
});
|
|
@@ -14318,13 +15798,13 @@ var OpenRouterPlugin = class extends BasePlugin {
|
|
|
14318
15798
|
name: "openrouter.beta.responses.send",
|
|
14319
15799
|
type: "llm" /* LLM */,
|
|
14320
15800
|
extractInput: (args, event) => {
|
|
14321
|
-
const request =
|
|
14322
|
-
const metadata = request ?
|
|
15801
|
+
const request = getOpenRouterCallModelRequestArg2(args);
|
|
15802
|
+
const metadata = request ? extractOpenRouterCallModelMetadata2(request) : { provider: "openrouter" };
|
|
14323
15803
|
if (isObject(metadata) && "tools" in metadata) {
|
|
14324
15804
|
delete metadata.tools;
|
|
14325
15805
|
}
|
|
14326
15806
|
return {
|
|
14327
|
-
input: request ?
|
|
15807
|
+
input: request ? extractOpenRouterCallModelInput2(request) : void 0,
|
|
14328
15808
|
metadata: {
|
|
14329
15809
|
...metadata,
|
|
14330
15810
|
step: event.step,
|
|
@@ -14332,7 +15812,7 @@ var OpenRouterPlugin = class extends BasePlugin {
|
|
|
14332
15812
|
}
|
|
14333
15813
|
};
|
|
14334
15814
|
},
|
|
14335
|
-
extractOutput: (result) =>
|
|
15815
|
+
extractOutput: (result) => extractOpenRouterResponseOutput2(result),
|
|
14336
15816
|
extractMetadata: (result, event) => {
|
|
14337
15817
|
if (!isObject(result)) {
|
|
14338
15818
|
return {
|
|
@@ -14341,12 +15821,12 @@ var OpenRouterPlugin = class extends BasePlugin {
|
|
|
14341
15821
|
};
|
|
14342
15822
|
}
|
|
14343
15823
|
return {
|
|
14344
|
-
...
|
|
15824
|
+
...extractOpenRouterResponseMetadata2(result) || {},
|
|
14345
15825
|
...event?.step !== void 0 ? { step: event.step } : {},
|
|
14346
15826
|
...event?.stepType ? { step_type: event.stepType } : {}
|
|
14347
15827
|
};
|
|
14348
15828
|
},
|
|
14349
|
-
extractMetrics: (result) => isObject(result) ?
|
|
15829
|
+
extractMetrics: (result) => isObject(result) ? parseOpenRouterMetricsFromUsage2(result.usage) : {}
|
|
14350
15830
|
})
|
|
14351
15831
|
);
|
|
14352
15832
|
this.unsubscribers.push(
|
|
@@ -14372,11 +15852,11 @@ var OpenRouterPlugin = class extends BasePlugin {
|
|
|
14372
15852
|
const callModelChannel = openRouterChannels.callModel.tracingChannel();
|
|
14373
15853
|
const callModelHandlers = {
|
|
14374
15854
|
start: (event) => {
|
|
14375
|
-
const request =
|
|
15855
|
+
const request = getOpenRouterCallModelRequestArg2(event.arguments);
|
|
14376
15856
|
if (!request) {
|
|
14377
15857
|
return;
|
|
14378
15858
|
}
|
|
14379
|
-
|
|
15859
|
+
patchOpenRouterCallModelRequestTools2(request);
|
|
14380
15860
|
}
|
|
14381
15861
|
};
|
|
14382
15862
|
callModelChannel.subscribe(callModelHandlers);
|
|
@@ -14385,20 +15865,20 @@ var OpenRouterPlugin = class extends BasePlugin {
|
|
|
14385
15865
|
});
|
|
14386
15866
|
}
|
|
14387
15867
|
};
|
|
14388
|
-
function
|
|
15868
|
+
function normalizeArgs2(args) {
|
|
14389
15869
|
if (Array.isArray(args)) {
|
|
14390
15870
|
return args;
|
|
14391
15871
|
}
|
|
14392
|
-
if (
|
|
15872
|
+
if (isArrayLike2(args)) {
|
|
14393
15873
|
return Array.from(args);
|
|
14394
15874
|
}
|
|
14395
15875
|
return [args];
|
|
14396
15876
|
}
|
|
14397
|
-
function
|
|
15877
|
+
function isArrayLike2(value) {
|
|
14398
15878
|
return isObject(value) && "length" in value && typeof value.length === "number" && Number.isInteger(value.length) && value.length >= 0;
|
|
14399
15879
|
}
|
|
14400
15880
|
function getOpenRouterRequestArg(args) {
|
|
14401
|
-
const normalizedArgs =
|
|
15881
|
+
const normalizedArgs = normalizeArgs2(args);
|
|
14402
15882
|
const keyedCandidate = normalizedArgs.find(
|
|
14403
15883
|
(arg) => isObject(arg) && ("chatGenerationParams" in arg || "requestBody" in arg || "openResponsesRequest" in arg)
|
|
14404
15884
|
);
|
|
@@ -14408,11 +15888,11 @@ function getOpenRouterRequestArg(args) {
|
|
|
14408
15888
|
const firstObjectArg = normalizedArgs.find((arg) => isObject(arg));
|
|
14409
15889
|
return isObject(firstObjectArg) ? firstObjectArg : void 0;
|
|
14410
15890
|
}
|
|
14411
|
-
function
|
|
14412
|
-
const firstObjectArg =
|
|
15891
|
+
function getOpenRouterCallModelRequestArg2(args) {
|
|
15892
|
+
const firstObjectArg = normalizeArgs2(args).find((arg) => isObject(arg));
|
|
14413
15893
|
return isObject(firstObjectArg) ? firstObjectArg : void 0;
|
|
14414
15894
|
}
|
|
14415
|
-
var
|
|
15895
|
+
var TOKEN_NAME_MAP3 = {
|
|
14416
15896
|
promptTokens: "prompt_tokens",
|
|
14417
15897
|
inputTokens: "prompt_tokens",
|
|
14418
15898
|
completionTokens: "completion_tokens",
|
|
@@ -14424,7 +15904,7 @@ var TOKEN_NAME_MAP2 = {
|
|
|
14424
15904
|
output_tokens: "completion_tokens",
|
|
14425
15905
|
total_tokens: "tokens"
|
|
14426
15906
|
};
|
|
14427
|
-
var
|
|
15907
|
+
var TOKEN_DETAIL_PREFIX_MAP2 = {
|
|
14428
15908
|
promptTokensDetails: "prompt",
|
|
14429
15909
|
inputTokensDetails: "prompt",
|
|
14430
15910
|
completionTokensDetails: "completion",
|
|
@@ -14436,23 +15916,23 @@ var TOKEN_DETAIL_PREFIX_MAP = {
|
|
|
14436
15916
|
output_tokens_details: "completion",
|
|
14437
15917
|
cost_details: "cost"
|
|
14438
15918
|
};
|
|
14439
|
-
function
|
|
15919
|
+
function camelToSnake2(value) {
|
|
14440
15920
|
return value.replace(/[A-Z]/g, (match) => `_${match.toLowerCase()}`);
|
|
14441
15921
|
}
|
|
14442
|
-
function
|
|
15922
|
+
function parseOpenRouterMetricsFromUsage2(usage) {
|
|
14443
15923
|
if (!isObject(usage)) {
|
|
14444
15924
|
return {};
|
|
14445
15925
|
}
|
|
14446
15926
|
const metrics = {};
|
|
14447
15927
|
for (const [name, value] of Object.entries(usage)) {
|
|
14448
15928
|
if (typeof value === "number") {
|
|
14449
|
-
metrics[
|
|
15929
|
+
metrics[TOKEN_NAME_MAP3[name] || camelToSnake2(name)] = value;
|
|
14450
15930
|
continue;
|
|
14451
15931
|
}
|
|
14452
15932
|
if (!isObject(value)) {
|
|
14453
15933
|
continue;
|
|
14454
15934
|
}
|
|
14455
|
-
const prefix =
|
|
15935
|
+
const prefix = TOKEN_DETAIL_PREFIX_MAP2[name];
|
|
14456
15936
|
if (!prefix) {
|
|
14457
15937
|
continue;
|
|
14458
15938
|
}
|
|
@@ -14460,12 +15940,12 @@ function parseOpenRouterMetricsFromUsage(usage) {
|
|
|
14460
15940
|
if (typeof nestedValue !== "number") {
|
|
14461
15941
|
continue;
|
|
14462
15942
|
}
|
|
14463
|
-
metrics[`${prefix}_${
|
|
15943
|
+
metrics[`${prefix}_${camelToSnake2(nestedName)}`] = nestedValue;
|
|
14464
15944
|
}
|
|
14465
15945
|
}
|
|
14466
15946
|
return metrics;
|
|
14467
15947
|
}
|
|
14468
|
-
function
|
|
15948
|
+
function extractOpenRouterUsageMetadata2(usage) {
|
|
14469
15949
|
if (!isObject(usage)) {
|
|
14470
15950
|
return void 0;
|
|
14471
15951
|
}
|
|
@@ -14477,13 +15957,13 @@ function extractOpenRouterUsageMetadata(usage) {
|
|
|
14477
15957
|
}
|
|
14478
15958
|
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
14479
15959
|
}
|
|
14480
|
-
var
|
|
15960
|
+
var OMITTED_OPENROUTER_KEYS2 = /* @__PURE__ */ new Set([
|
|
14481
15961
|
"execute",
|
|
14482
15962
|
"render",
|
|
14483
15963
|
"nextTurnParams",
|
|
14484
15964
|
"requireApproval"
|
|
14485
15965
|
]);
|
|
14486
|
-
function
|
|
15966
|
+
function parseOpenRouterModelString2(model) {
|
|
14487
15967
|
if (typeof model !== "string") {
|
|
14488
15968
|
return { model };
|
|
14489
15969
|
}
|
|
@@ -14496,10 +15976,10 @@ function parseOpenRouterModelString(model) {
|
|
|
14496
15976
|
}
|
|
14497
15977
|
return { model };
|
|
14498
15978
|
}
|
|
14499
|
-
function
|
|
15979
|
+
function isZodSchema4(value) {
|
|
14500
15980
|
return value != null && typeof value === "object" && "_def" in value && typeof value._def === "object";
|
|
14501
15981
|
}
|
|
14502
|
-
function
|
|
15982
|
+
function serializeZodSchema4(schema) {
|
|
14503
15983
|
try {
|
|
14504
15984
|
return zodToJsonSchema(schema);
|
|
14505
15985
|
} catch {
|
|
@@ -14509,60 +15989,60 @@ function serializeZodSchema3(schema) {
|
|
|
14509
15989
|
};
|
|
14510
15990
|
}
|
|
14511
15991
|
}
|
|
14512
|
-
function
|
|
15992
|
+
function serializeOpenRouterTool2(tool) {
|
|
14513
15993
|
if (!isObject(tool)) {
|
|
14514
15994
|
return tool;
|
|
14515
15995
|
}
|
|
14516
15996
|
const serialized = {};
|
|
14517
15997
|
for (const [key, value] of Object.entries(tool)) {
|
|
14518
|
-
if (
|
|
15998
|
+
if (OMITTED_OPENROUTER_KEYS2.has(key)) {
|
|
14519
15999
|
continue;
|
|
14520
16000
|
}
|
|
14521
16001
|
if (key === "function" && isObject(value)) {
|
|
14522
|
-
serialized.function =
|
|
16002
|
+
serialized.function = sanitizeOpenRouterLoggedValue2(value);
|
|
14523
16003
|
continue;
|
|
14524
16004
|
}
|
|
14525
|
-
serialized[key] =
|
|
16005
|
+
serialized[key] = sanitizeOpenRouterLoggedValue2(value);
|
|
14526
16006
|
}
|
|
14527
16007
|
return serialized;
|
|
14528
16008
|
}
|
|
14529
|
-
function
|
|
16009
|
+
function serializeOpenRouterToolsForLogging2(tools) {
|
|
14530
16010
|
if (!Array.isArray(tools)) {
|
|
14531
16011
|
return void 0;
|
|
14532
16012
|
}
|
|
14533
|
-
return tools.map((tool) =>
|
|
16013
|
+
return tools.map((tool) => serializeOpenRouterTool2(tool));
|
|
14534
16014
|
}
|
|
14535
|
-
function
|
|
14536
|
-
if (
|
|
14537
|
-
return
|
|
16015
|
+
function sanitizeOpenRouterLoggedValue2(value) {
|
|
16016
|
+
if (isZodSchema4(value)) {
|
|
16017
|
+
return serializeZodSchema4(value);
|
|
14538
16018
|
}
|
|
14539
16019
|
if (typeof value === "function") {
|
|
14540
16020
|
return "[Function]";
|
|
14541
16021
|
}
|
|
14542
16022
|
if (Array.isArray(value)) {
|
|
14543
|
-
return value.map((entry) =>
|
|
16023
|
+
return value.map((entry) => sanitizeOpenRouterLoggedValue2(entry));
|
|
14544
16024
|
}
|
|
14545
16025
|
if (!isObject(value)) {
|
|
14546
16026
|
return value;
|
|
14547
16027
|
}
|
|
14548
16028
|
const sanitized = {};
|
|
14549
16029
|
for (const [key, entry] of Object.entries(value)) {
|
|
14550
|
-
if (
|
|
16030
|
+
if (OMITTED_OPENROUTER_KEYS2.has(key)) {
|
|
14551
16031
|
continue;
|
|
14552
16032
|
}
|
|
14553
16033
|
if (key === "tools" && Array.isArray(entry)) {
|
|
14554
|
-
sanitized.tools =
|
|
16034
|
+
sanitized.tools = serializeOpenRouterToolsForLogging2(entry);
|
|
14555
16035
|
continue;
|
|
14556
16036
|
}
|
|
14557
|
-
sanitized[key] =
|
|
16037
|
+
sanitized[key] = sanitizeOpenRouterLoggedValue2(entry);
|
|
14558
16038
|
}
|
|
14559
16039
|
return sanitized;
|
|
14560
16040
|
}
|
|
14561
|
-
function
|
|
14562
|
-
const sanitized =
|
|
16041
|
+
function buildOpenRouterMetadata2(metadata, httpReferer, xTitle) {
|
|
16042
|
+
const sanitized = sanitizeOpenRouterLoggedValue2(metadata);
|
|
14563
16043
|
const metadataRecord = isObject(sanitized) ? sanitized : {};
|
|
14564
16044
|
const { model, provider: providerRouting, ...rest } = metadataRecord;
|
|
14565
|
-
const normalizedModel =
|
|
16045
|
+
const normalizedModel = parseOpenRouterModelString2(model);
|
|
14566
16046
|
return {
|
|
14567
16047
|
...rest,
|
|
14568
16048
|
...normalizedModel.model !== void 0 ? { model: normalizedModel.model } : {},
|
|
@@ -14573,33 +16053,33 @@ function buildOpenRouterMetadata(metadata, httpReferer, xTitle) {
|
|
|
14573
16053
|
};
|
|
14574
16054
|
}
|
|
14575
16055
|
function buildOpenRouterEmbeddingMetadata(metadata, httpReferer, xTitle) {
|
|
14576
|
-
const normalized =
|
|
16056
|
+
const normalized = buildOpenRouterMetadata2(metadata, httpReferer, xTitle);
|
|
14577
16057
|
return typeof normalized.model === "string" ? {
|
|
14578
16058
|
...normalized,
|
|
14579
16059
|
embedding_model: normalized.model
|
|
14580
16060
|
} : normalized;
|
|
14581
16061
|
}
|
|
14582
|
-
function
|
|
14583
|
-
return isObject(request) && "input" in request ?
|
|
16062
|
+
function extractOpenRouterCallModelInput2(request) {
|
|
16063
|
+
return isObject(request) && "input" in request ? sanitizeOpenRouterLoggedValue2(request.input) : void 0;
|
|
14584
16064
|
}
|
|
14585
|
-
function
|
|
16065
|
+
function extractOpenRouterCallModelMetadata2(request) {
|
|
14586
16066
|
if (!isObject(request)) {
|
|
14587
16067
|
return { provider: "openrouter" };
|
|
14588
16068
|
}
|
|
14589
16069
|
const { input: _input, ...metadata } = request;
|
|
14590
|
-
return
|
|
16070
|
+
return buildOpenRouterMetadata2(metadata, void 0, void 0);
|
|
14591
16071
|
}
|
|
14592
|
-
function
|
|
16072
|
+
function extractOpenRouterResponseMetadata2(result) {
|
|
14593
16073
|
if (!isObject(result)) {
|
|
14594
16074
|
return void 0;
|
|
14595
16075
|
}
|
|
14596
16076
|
const { output: _output, data: _data, usage, ...metadata } = result;
|
|
14597
|
-
const sanitized =
|
|
16077
|
+
const sanitized = sanitizeOpenRouterLoggedValue2(metadata);
|
|
14598
16078
|
const metadataRecord = isObject(sanitized) ? sanitized : {};
|
|
14599
16079
|
const { model, provider, ...rest } = metadataRecord;
|
|
14600
|
-
const normalizedModel =
|
|
16080
|
+
const normalizedModel = parseOpenRouterModelString2(model);
|
|
14601
16081
|
const normalizedProvider = (typeof provider === "string" ? provider : void 0) || normalizedModel.provider;
|
|
14602
|
-
const usageMetadata =
|
|
16082
|
+
const usageMetadata = extractOpenRouterUsageMetadata2(usage);
|
|
14603
16083
|
const combined = {
|
|
14604
16084
|
...rest,
|
|
14605
16085
|
...normalizedModel.model !== void 0 ? { model: normalizedModel.model } : {},
|
|
@@ -14608,22 +16088,22 @@ function extractOpenRouterResponseMetadata(result) {
|
|
|
14608
16088
|
};
|
|
14609
16089
|
return Object.keys(combined).length > 0 ? combined : void 0;
|
|
14610
16090
|
}
|
|
14611
|
-
function
|
|
16091
|
+
function extractOpenRouterResponseOutput2(response, fallbackOutput) {
|
|
14612
16092
|
if (isObject(response) && "output" in response && response.output !== void 0) {
|
|
14613
|
-
return
|
|
16093
|
+
return sanitizeOpenRouterLoggedValue2(response.output);
|
|
14614
16094
|
}
|
|
14615
16095
|
if (fallbackOutput !== void 0) {
|
|
14616
|
-
return
|
|
16096
|
+
return sanitizeOpenRouterLoggedValue2(fallbackOutput);
|
|
14617
16097
|
}
|
|
14618
16098
|
return void 0;
|
|
14619
16099
|
}
|
|
14620
|
-
var
|
|
14621
|
-
function
|
|
16100
|
+
var OPENROUTER_WRAPPED_TOOL2 = Symbol("braintrust.openrouter.wrappedTool");
|
|
16101
|
+
function patchOpenRouterCallModelRequestTools2(request) {
|
|
14622
16102
|
if (!Array.isArray(request.tools) || request.tools.length === 0) {
|
|
14623
16103
|
return void 0;
|
|
14624
16104
|
}
|
|
14625
16105
|
const originalTools = request.tools;
|
|
14626
|
-
const wrappedTools = originalTools.map((tool) =>
|
|
16106
|
+
const wrappedTools = originalTools.map((tool) => wrapOpenRouterTool2(tool));
|
|
14627
16107
|
const didPatch = wrappedTools.some(
|
|
14628
16108
|
(tool, index) => tool !== originalTools[index]
|
|
14629
16109
|
);
|
|
@@ -14635,8 +16115,8 @@ function patchOpenRouterCallModelRequestTools(request) {
|
|
|
14635
16115
|
request.tools = originalTools;
|
|
14636
16116
|
};
|
|
14637
16117
|
}
|
|
14638
|
-
function
|
|
14639
|
-
if (
|
|
16118
|
+
function wrapOpenRouterTool2(tool) {
|
|
16119
|
+
if (isWrappedTool2(tool) || !tool.function || typeof tool.function !== "object" || typeof tool.function.execute !== "function") {
|
|
14640
16120
|
return tool;
|
|
14641
16121
|
}
|
|
14642
16122
|
const toolName = tool.function.name || "tool";
|
|
@@ -14646,26 +16126,26 @@ function wrapOpenRouterTool(tool) {
|
|
|
14646
16126
|
function: {
|
|
14647
16127
|
...tool.function,
|
|
14648
16128
|
execute(...args) {
|
|
14649
|
-
return
|
|
16129
|
+
return traceToolExecution2({
|
|
14650
16130
|
args,
|
|
14651
16131
|
execute: () => Reflect.apply(originalExecute, this, args),
|
|
14652
|
-
toolCallId:
|
|
16132
|
+
toolCallId: getToolCallId2(args[1]),
|
|
14653
16133
|
toolName
|
|
14654
16134
|
});
|
|
14655
16135
|
}
|
|
14656
16136
|
}
|
|
14657
16137
|
};
|
|
14658
|
-
Object.defineProperty(wrappedTool,
|
|
16138
|
+
Object.defineProperty(wrappedTool, OPENROUTER_WRAPPED_TOOL2, {
|
|
14659
16139
|
value: true,
|
|
14660
16140
|
enumerable: false,
|
|
14661
16141
|
configurable: false
|
|
14662
16142
|
});
|
|
14663
16143
|
return wrappedTool;
|
|
14664
16144
|
}
|
|
14665
|
-
function
|
|
14666
|
-
return Boolean(tool[
|
|
16145
|
+
function isWrappedTool2(tool) {
|
|
16146
|
+
return Boolean(tool[OPENROUTER_WRAPPED_TOOL2]);
|
|
14667
16147
|
}
|
|
14668
|
-
function
|
|
16148
|
+
function traceToolExecution2(args) {
|
|
14669
16149
|
const tracingChannel2 = openRouterChannels.toolExecute.tracingChannel();
|
|
14670
16150
|
const input = args.args.length > 0 ? args.args[0] : void 0;
|
|
14671
16151
|
const event = {
|
|
@@ -14679,15 +16159,15 @@ function traceToolExecution(args) {
|
|
|
14679
16159
|
tracingChannel2.start.publish(event);
|
|
14680
16160
|
try {
|
|
14681
16161
|
const result = args.execute();
|
|
14682
|
-
return
|
|
16162
|
+
return publishToolResult2(tracingChannel2, event, result);
|
|
14683
16163
|
} catch (error) {
|
|
14684
|
-
event.error =
|
|
16164
|
+
event.error = normalizeError2(error);
|
|
14685
16165
|
tracingChannel2.error.publish(event);
|
|
14686
16166
|
throw error;
|
|
14687
16167
|
}
|
|
14688
16168
|
}
|
|
14689
|
-
function
|
|
14690
|
-
if (
|
|
16169
|
+
function publishToolResult2(tracingChannel2, event, result) {
|
|
16170
|
+
if (isPromiseLike4(result)) {
|
|
14691
16171
|
return result.then(
|
|
14692
16172
|
(resolved) => {
|
|
14693
16173
|
event.result = resolved;
|
|
@@ -14695,7 +16175,7 @@ function publishToolResult(tracingChannel2, event, result) {
|
|
|
14695
16175
|
return resolved;
|
|
14696
16176
|
},
|
|
14697
16177
|
(error) => {
|
|
14698
|
-
event.error =
|
|
16178
|
+
event.error = normalizeError2(error);
|
|
14699
16179
|
tracingChannel2.error.publish(event);
|
|
14700
16180
|
throw error;
|
|
14701
16181
|
}
|
|
@@ -14705,11 +16185,11 @@ function publishToolResult(tracingChannel2, event, result) {
|
|
|
14705
16185
|
tracingChannel2.asyncEnd.publish(event);
|
|
14706
16186
|
return result;
|
|
14707
16187
|
}
|
|
14708
|
-
function
|
|
16188
|
+
function getToolCallId2(context) {
|
|
14709
16189
|
const toolContext = context;
|
|
14710
16190
|
return typeof toolContext?.toolCall?.id === "string" ? toolContext.toolCall.id : void 0;
|
|
14711
16191
|
}
|
|
14712
|
-
function
|
|
16192
|
+
function isPromiseLike4(value) {
|
|
14713
16193
|
return !!value && (typeof value === "object" || typeof value === "function") && "then" in value && typeof value.then === "function";
|
|
14714
16194
|
}
|
|
14715
16195
|
function aggregateOpenRouterChatChunks(chunks) {
|
|
@@ -14721,7 +16201,7 @@ function aggregateOpenRouterChatChunks(chunks) {
|
|
|
14721
16201
|
for (const chunk of chunks) {
|
|
14722
16202
|
metrics = {
|
|
14723
16203
|
...metrics,
|
|
14724
|
-
...
|
|
16204
|
+
...parseOpenRouterMetricsFromUsage2(chunk?.usage)
|
|
14725
16205
|
};
|
|
14726
16206
|
const choice = chunk?.choices?.[0];
|
|
14727
16207
|
const delta = choice?.delta;
|
|
@@ -14815,15 +16295,15 @@ function aggregateOpenRouterResponseStreamEvents(chunks) {
|
|
|
14815
16295
|
};
|
|
14816
16296
|
}
|
|
14817
16297
|
return {
|
|
14818
|
-
output:
|
|
14819
|
-
metrics:
|
|
14820
|
-
...
|
|
16298
|
+
output: extractOpenRouterResponseOutput2(finalResponse),
|
|
16299
|
+
metrics: parseOpenRouterMetricsFromUsage2(finalResponse.usage),
|
|
16300
|
+
...extractOpenRouterResponseMetadata2(finalResponse) ? { metadata: extractOpenRouterResponseMetadata2(finalResponse) } : {}
|
|
14821
16301
|
};
|
|
14822
16302
|
}
|
|
14823
|
-
var
|
|
16303
|
+
var OPENROUTER_WRAPPED_CALL_MODEL_RESULT2 = Symbol(
|
|
14824
16304
|
"braintrust.openrouter.wrappedCallModelResult"
|
|
14825
16305
|
);
|
|
14826
|
-
var
|
|
16306
|
+
var OPENROUTER_CALL_MODEL_STREAM_METHODS2 = [
|
|
14827
16307
|
"getFullResponsesStream",
|
|
14828
16308
|
"getItemsStream",
|
|
14829
16309
|
"getNewMessagesStream",
|
|
@@ -14832,26 +16312,26 @@ var OPENROUTER_CALL_MODEL_STREAM_METHODS = [
|
|
|
14832
16312
|
"getToolCallsStream",
|
|
14833
16313
|
"getToolStream"
|
|
14834
16314
|
];
|
|
14835
|
-
var
|
|
16315
|
+
var OPENROUTER_CALL_MODEL_CONTEXT_METHODS2 = [
|
|
14836
16316
|
"cancel",
|
|
14837
16317
|
"getPendingToolCalls",
|
|
14838
16318
|
"getState",
|
|
14839
16319
|
"getToolCalls",
|
|
14840
16320
|
"requiresApproval"
|
|
14841
16321
|
];
|
|
14842
|
-
function
|
|
16322
|
+
function patchOpenRouterCallModelResult2(args) {
|
|
14843
16323
|
const { request, result, span } = args;
|
|
14844
|
-
if (!isObject(result) ||
|
|
16324
|
+
if (!isObject(result) || isWrappedCallModelResult2(result)) {
|
|
14845
16325
|
return false;
|
|
14846
16326
|
}
|
|
14847
16327
|
const resultLike = result;
|
|
14848
|
-
const hasInstrumentableMethod = typeof resultLike.getResponse === "function" || typeof resultLike.getText === "function" ||
|
|
16328
|
+
const hasInstrumentableMethod = typeof resultLike.getResponse === "function" || typeof resultLike.getText === "function" || OPENROUTER_CALL_MODEL_STREAM_METHODS2.some(
|
|
14849
16329
|
(methodName) => typeof resultLike[methodName] === "function"
|
|
14850
16330
|
);
|
|
14851
16331
|
if (!hasInstrumentableMethod) {
|
|
14852
16332
|
return false;
|
|
14853
16333
|
}
|
|
14854
|
-
Object.defineProperty(resultLike,
|
|
16334
|
+
Object.defineProperty(resultLike, OPENROUTER_WRAPPED_CALL_MODEL_RESULT2, {
|
|
14855
16335
|
value: true,
|
|
14856
16336
|
enumerable: false,
|
|
14857
16337
|
configurable: false
|
|
@@ -14866,20 +16346,20 @@ function patchOpenRouterCallModelResult(args) {
|
|
|
14866
16346
|
return;
|
|
14867
16347
|
}
|
|
14868
16348
|
ended = true;
|
|
14869
|
-
const finalResponse =
|
|
16349
|
+
const finalResponse = getFinalOpenRouterCallModelResponse2(
|
|
14870
16350
|
resultLike,
|
|
14871
16351
|
response
|
|
14872
16352
|
);
|
|
14873
16353
|
if (finalResponse) {
|
|
14874
|
-
const rounds =
|
|
14875
|
-
const metadata =
|
|
16354
|
+
const rounds = getOpenRouterCallModelRounds2(resultLike);
|
|
16355
|
+
const metadata = extractOpenRouterCallModelResultMetadata2(
|
|
14876
16356
|
finalResponse,
|
|
14877
16357
|
rounds.length + 1
|
|
14878
16358
|
);
|
|
14879
16359
|
span.log({
|
|
14880
|
-
output:
|
|
16360
|
+
output: extractOpenRouterResponseOutput2(finalResponse, fallbackOutput),
|
|
14881
16361
|
...metadata ? { metadata } : {},
|
|
14882
|
-
metrics:
|
|
16362
|
+
metrics: aggregateOpenRouterCallModelMetrics2(rounds, finalResponse)
|
|
14883
16363
|
});
|
|
14884
16364
|
span.end();
|
|
14885
16365
|
return;
|
|
@@ -14897,7 +16377,7 @@ function patchOpenRouterCallModelResult(args) {
|
|
|
14897
16377
|
}
|
|
14898
16378
|
ended = true;
|
|
14899
16379
|
span.log({
|
|
14900
|
-
error:
|
|
16380
|
+
error: normalizeError2(error).message
|
|
14901
16381
|
});
|
|
14902
16382
|
span.end();
|
|
14903
16383
|
};
|
|
@@ -14941,7 +16421,7 @@ function patchOpenRouterCallModelResult(args) {
|
|
|
14941
16421
|
});
|
|
14942
16422
|
};
|
|
14943
16423
|
}
|
|
14944
|
-
for (const methodName of
|
|
16424
|
+
for (const methodName of OPENROUTER_CALL_MODEL_CONTEXT_METHODS2) {
|
|
14945
16425
|
if (typeof resultLike[methodName] !== "function") {
|
|
14946
16426
|
continue;
|
|
14947
16427
|
}
|
|
@@ -14952,7 +16432,7 @@ function patchOpenRouterCallModelResult(args) {
|
|
|
14952
16432
|
});
|
|
14953
16433
|
};
|
|
14954
16434
|
}
|
|
14955
|
-
for (const methodName of
|
|
16435
|
+
for (const methodName of OPENROUTER_CALL_MODEL_STREAM_METHODS2) {
|
|
14956
16436
|
if (typeof resultLike[methodName] !== "function") {
|
|
14957
16437
|
continue;
|
|
14958
16438
|
}
|
|
@@ -14962,10 +16442,10 @@ function patchOpenRouterCallModelResult(args) {
|
|
|
14962
16442
|
span,
|
|
14963
16443
|
() => originalMethod.apply(resultLike, args2)
|
|
14964
16444
|
);
|
|
14965
|
-
if (!
|
|
16445
|
+
if (!isAsyncIterable4(stream)) {
|
|
14966
16446
|
return stream;
|
|
14967
16447
|
}
|
|
14968
|
-
return
|
|
16448
|
+
return wrapAsyncIterableWithSpan2({
|
|
14969
16449
|
finalize: finalizeFromResponse,
|
|
14970
16450
|
iteratorFactory: () => stream[Symbol.asyncIterator](),
|
|
14971
16451
|
onError: endSpanWithError,
|
|
@@ -14984,14 +16464,14 @@ function patchOpenRouterCallModelResult(args) {
|
|
|
14984
16464
|
initialTurnTraced = true;
|
|
14985
16465
|
const step = tracedTurnCount + 1;
|
|
14986
16466
|
const stepType = tracedTurnCount === 0 ? "initial" : "continue";
|
|
14987
|
-
const response = await
|
|
16467
|
+
const response = await traceOpenRouterCallModelTurn2({
|
|
14988
16468
|
fn: async () => {
|
|
14989
16469
|
const nextResponse = await originalGetInitialResponse(...args2);
|
|
14990
16470
|
tracedTurnCount++;
|
|
14991
16471
|
return nextResponse;
|
|
14992
16472
|
},
|
|
14993
16473
|
parentSpan: span,
|
|
14994
|
-
request:
|
|
16474
|
+
request: getOpenRouterResolvedRequest2(resultLike, request),
|
|
14995
16475
|
step,
|
|
14996
16476
|
stepType
|
|
14997
16477
|
});
|
|
@@ -15003,15 +16483,15 @@ function patchOpenRouterCallModelResult(args) {
|
|
|
15003
16483
|
const currentResponse = args2[0];
|
|
15004
16484
|
const toolResults = Array.isArray(args2[1]) ? args2[1] : [];
|
|
15005
16485
|
const step = tracedTurnCount + 1;
|
|
15006
|
-
const response = await
|
|
16486
|
+
const response = await traceOpenRouterCallModelTurn2({
|
|
15007
16487
|
fn: async () => {
|
|
15008
16488
|
const nextResponse = await originalMakeFollowupRequest(...args2);
|
|
15009
16489
|
tracedTurnCount++;
|
|
15010
16490
|
return nextResponse;
|
|
15011
16491
|
},
|
|
15012
16492
|
parentSpan: span,
|
|
15013
|
-
request:
|
|
15014
|
-
|
|
16493
|
+
request: buildOpenRouterFollowupRequest2(
|
|
16494
|
+
getOpenRouterResolvedRequest2(resultLike, request),
|
|
15015
16495
|
currentResponse,
|
|
15016
16496
|
toolResults
|
|
15017
16497
|
),
|
|
@@ -15023,7 +16503,7 @@ function patchOpenRouterCallModelResult(args) {
|
|
|
15023
16503
|
}
|
|
15024
16504
|
return true;
|
|
15025
16505
|
}
|
|
15026
|
-
async function
|
|
16506
|
+
async function traceOpenRouterCallModelTurn2(args) {
|
|
15027
16507
|
const context = {
|
|
15028
16508
|
arguments: [args.request],
|
|
15029
16509
|
step: args.step,
|
|
@@ -15034,25 +16514,25 @@ async function traceOpenRouterCallModelTurn(args) {
|
|
|
15034
16514
|
() => openRouterChannels.callModelTurn.tracePromise(args.fn, context)
|
|
15035
16515
|
);
|
|
15036
16516
|
}
|
|
15037
|
-
function
|
|
16517
|
+
function isWrappedCallModelResult2(value) {
|
|
15038
16518
|
return Boolean(
|
|
15039
|
-
isObject(value) && value[
|
|
16519
|
+
isObject(value) && value[OPENROUTER_WRAPPED_CALL_MODEL_RESULT2]
|
|
15040
16520
|
);
|
|
15041
16521
|
}
|
|
15042
|
-
function
|
|
16522
|
+
function extractOpenRouterCallModelResultMetadata2(response, turnCount) {
|
|
15043
16523
|
const combined = {
|
|
15044
|
-
...
|
|
16524
|
+
...extractOpenRouterResponseMetadata2(response) || {},
|
|
15045
16525
|
...turnCount !== void 0 ? { turn_count: turnCount } : {}
|
|
15046
16526
|
};
|
|
15047
16527
|
return Object.keys(combined).length > 0 ? combined : void 0;
|
|
15048
16528
|
}
|
|
15049
|
-
function
|
|
16529
|
+
function getFinalOpenRouterCallModelResponse2(result, response) {
|
|
15050
16530
|
if (isObject(response)) {
|
|
15051
16531
|
return response;
|
|
15052
16532
|
}
|
|
15053
16533
|
return isObject(result.finalResponse) ? result.finalResponse : void 0;
|
|
15054
16534
|
}
|
|
15055
|
-
function
|
|
16535
|
+
function getOpenRouterCallModelRounds2(result) {
|
|
15056
16536
|
if (!Array.isArray(result.allToolExecutionRounds)) {
|
|
15057
16537
|
return [];
|
|
15058
16538
|
}
|
|
@@ -15062,48 +16542,48 @@ function getOpenRouterCallModelRounds(result) {
|
|
|
15062
16542
|
toolResults: Array.isArray(round.toolResults) ? round.toolResults : []
|
|
15063
16543
|
})).filter((round) => round.response !== void 0);
|
|
15064
16544
|
}
|
|
15065
|
-
function
|
|
16545
|
+
function aggregateOpenRouterCallModelMetrics2(rounds, finalResponse) {
|
|
15066
16546
|
const metrics = {};
|
|
15067
16547
|
const responses = [
|
|
15068
16548
|
...rounds.map((round) => round.response).filter(isObject),
|
|
15069
16549
|
finalResponse
|
|
15070
16550
|
];
|
|
15071
16551
|
for (const response of responses) {
|
|
15072
|
-
const responseMetrics =
|
|
16552
|
+
const responseMetrics = parseOpenRouterMetricsFromUsage2(response.usage);
|
|
15073
16553
|
for (const [name, value] of Object.entries(responseMetrics)) {
|
|
15074
16554
|
metrics[name] = (metrics[name] || 0) + value;
|
|
15075
16555
|
}
|
|
15076
16556
|
}
|
|
15077
16557
|
return metrics;
|
|
15078
16558
|
}
|
|
15079
|
-
function
|
|
16559
|
+
function buildNextOpenRouterCallModelInput2(currentInput, response, toolResults) {
|
|
15080
16560
|
const normalizedInput = Array.isArray(currentInput) ? [...currentInput] : currentInput === void 0 ? [] : [currentInput];
|
|
15081
16561
|
const responseOutput = Array.isArray(response.output) ? response.output : response.output === void 0 ? [] : [response.output];
|
|
15082
16562
|
return [...normalizedInput, ...responseOutput, ...toolResults].map(
|
|
15083
|
-
(entry) =>
|
|
16563
|
+
(entry) => sanitizeOpenRouterLoggedValue2(entry)
|
|
15084
16564
|
);
|
|
15085
16565
|
}
|
|
15086
|
-
function
|
|
16566
|
+
function getOpenRouterResolvedRequest2(result, request) {
|
|
15087
16567
|
if (isObject(result.resolvedRequest)) {
|
|
15088
16568
|
return result.resolvedRequest;
|
|
15089
16569
|
}
|
|
15090
16570
|
return request;
|
|
15091
16571
|
}
|
|
15092
|
-
function
|
|
16572
|
+
function buildOpenRouterFollowupRequest2(request, currentResponse, toolResults) {
|
|
15093
16573
|
if (!request) {
|
|
15094
16574
|
return void 0;
|
|
15095
16575
|
}
|
|
15096
16576
|
return {
|
|
15097
16577
|
...request,
|
|
15098
|
-
input:
|
|
15099
|
-
|
|
16578
|
+
input: buildNextOpenRouterCallModelInput2(
|
|
16579
|
+
extractOpenRouterCallModelInput2(request),
|
|
15100
16580
|
isObject(currentResponse) ? currentResponse : {},
|
|
15101
16581
|
toolResults
|
|
15102
16582
|
),
|
|
15103
16583
|
stream: false
|
|
15104
16584
|
};
|
|
15105
16585
|
}
|
|
15106
|
-
function
|
|
16586
|
+
function wrapAsyncIterableWithSpan2(args) {
|
|
15107
16587
|
return {
|
|
15108
16588
|
[Symbol.asyncIterator]() {
|
|
15109
16589
|
const iterator = args.iteratorFactory();
|
|
@@ -15157,11 +16637,516 @@ function wrapAsyncIterableWithSpan(args) {
|
|
|
15157
16637
|
}
|
|
15158
16638
|
};
|
|
15159
16639
|
}
|
|
15160
|
-
function
|
|
15161
|
-
return !!value && (typeof value === "object" || typeof value === "function") && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
16640
|
+
function isAsyncIterable4(value) {
|
|
16641
|
+
return !!value && (typeof value === "object" || typeof value === "function") && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
16642
|
+
}
|
|
16643
|
+
function normalizeError2(error) {
|
|
16644
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
16645
|
+
}
|
|
16646
|
+
|
|
16647
|
+
// src/instrumentation/plugins/mistral-channels.ts
|
|
16648
|
+
var mistralChannels = defineChannels("@mistralai/mistralai", {
|
|
16649
|
+
chatComplete: channel({
|
|
16650
|
+
channelName: "chat.complete",
|
|
16651
|
+
kind: "async"
|
|
16652
|
+
}),
|
|
16653
|
+
chatStream: channel({
|
|
16654
|
+
channelName: "chat.stream",
|
|
16655
|
+
kind: "async"
|
|
16656
|
+
}),
|
|
16657
|
+
embeddingsCreate: channel({
|
|
16658
|
+
channelName: "embeddings.create",
|
|
16659
|
+
kind: "async"
|
|
16660
|
+
}),
|
|
16661
|
+
fimComplete: channel({
|
|
16662
|
+
channelName: "fim.complete",
|
|
16663
|
+
kind: "async"
|
|
16664
|
+
}),
|
|
16665
|
+
fimStream: channel({
|
|
16666
|
+
channelName: "fim.stream",
|
|
16667
|
+
kind: "async"
|
|
16668
|
+
}),
|
|
16669
|
+
agentsComplete: channel({
|
|
16670
|
+
channelName: "agents.complete",
|
|
16671
|
+
kind: "async"
|
|
16672
|
+
}),
|
|
16673
|
+
agentsStream: channel({
|
|
16674
|
+
channelName: "agents.stream",
|
|
16675
|
+
kind: "async"
|
|
16676
|
+
})
|
|
16677
|
+
});
|
|
16678
|
+
|
|
16679
|
+
// src/instrumentation/plugins/mistral-plugin.ts
|
|
16680
|
+
var MistralPlugin = class extends BasePlugin {
|
|
16681
|
+
onEnable() {
|
|
16682
|
+
this.subscribeToMistralChannels();
|
|
16683
|
+
}
|
|
16684
|
+
onDisable() {
|
|
16685
|
+
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
16686
|
+
}
|
|
16687
|
+
subscribeToMistralChannels() {
|
|
16688
|
+
this.unsubscribers.push(
|
|
16689
|
+
traceStreamingChannel(mistralChannels.chatComplete, {
|
|
16690
|
+
name: "mistral.chat.complete",
|
|
16691
|
+
type: "llm" /* LLM */,
|
|
16692
|
+
extractInput: extractMessagesInputWithMetadata,
|
|
16693
|
+
extractOutput: (result) => {
|
|
16694
|
+
return result?.choices;
|
|
16695
|
+
},
|
|
16696
|
+
extractMetadata: (result) => extractMistralResponseMetadata(result),
|
|
16697
|
+
extractMetrics: (result, startTime) => extractMistralMetrics(result?.usage, startTime)
|
|
16698
|
+
})
|
|
16699
|
+
);
|
|
16700
|
+
this.unsubscribers.push(
|
|
16701
|
+
traceStreamingChannel(mistralChannels.chatStream, {
|
|
16702
|
+
name: "mistral.chat.stream",
|
|
16703
|
+
type: "llm" /* LLM */,
|
|
16704
|
+
extractInput: extractMessagesInputWithMetadata,
|
|
16705
|
+
extractOutput: extractMistralStreamOutput,
|
|
16706
|
+
extractMetadata: (result) => extractMistralResponseMetadata(result),
|
|
16707
|
+
extractMetrics: (result, startTime) => extractMistralStreamingMetrics(result, startTime),
|
|
16708
|
+
aggregateChunks: aggregateMistralStreamChunks
|
|
16709
|
+
})
|
|
16710
|
+
);
|
|
16711
|
+
this.unsubscribers.push(
|
|
16712
|
+
traceAsyncChannel(mistralChannels.embeddingsCreate, {
|
|
16713
|
+
name: "mistral.embeddings.create",
|
|
16714
|
+
type: "llm" /* LLM */,
|
|
16715
|
+
extractInput: extractEmbeddingInputWithMetadata,
|
|
16716
|
+
extractOutput: (result) => {
|
|
16717
|
+
const embedding = result?.data?.[0]?.embedding;
|
|
16718
|
+
return Array.isArray(embedding) ? { embedding_length: embedding.length } : void 0;
|
|
16719
|
+
},
|
|
16720
|
+
extractMetadata: (result) => extractMistralResponseMetadata(result),
|
|
16721
|
+
extractMetrics: (result) => parseMistralMetricsFromUsage(result?.usage)
|
|
16722
|
+
})
|
|
16723
|
+
);
|
|
16724
|
+
this.unsubscribers.push(
|
|
16725
|
+
traceStreamingChannel(mistralChannels.fimComplete, {
|
|
16726
|
+
name: "mistral.fim.complete",
|
|
16727
|
+
type: "llm" /* LLM */,
|
|
16728
|
+
extractInput: extractPromptInputWithMetadata,
|
|
16729
|
+
extractOutput: (result) => {
|
|
16730
|
+
return result?.choices;
|
|
16731
|
+
},
|
|
16732
|
+
extractMetadata: (result) => extractMistralResponseMetadata(result),
|
|
16733
|
+
extractMetrics: (result, startTime) => extractMistralMetrics(result?.usage, startTime)
|
|
16734
|
+
})
|
|
16735
|
+
);
|
|
16736
|
+
this.unsubscribers.push(
|
|
16737
|
+
traceStreamingChannel(mistralChannels.fimStream, {
|
|
16738
|
+
name: "mistral.fim.stream",
|
|
16739
|
+
type: "llm" /* LLM */,
|
|
16740
|
+
extractInput: extractPromptInputWithMetadata,
|
|
16741
|
+
extractOutput: extractMistralStreamOutput,
|
|
16742
|
+
extractMetadata: (result) => extractMistralResponseMetadata(result),
|
|
16743
|
+
extractMetrics: (result, startTime) => extractMistralStreamingMetrics(result, startTime),
|
|
16744
|
+
aggregateChunks: aggregateMistralStreamChunks
|
|
16745
|
+
})
|
|
16746
|
+
);
|
|
16747
|
+
this.unsubscribers.push(
|
|
16748
|
+
traceStreamingChannel(mistralChannels.agentsComplete, {
|
|
16749
|
+
name: "mistral.agents.complete",
|
|
16750
|
+
type: "llm" /* LLM */,
|
|
16751
|
+
extractInput: extractMessagesInputWithMetadata,
|
|
16752
|
+
extractOutput: (result) => {
|
|
16753
|
+
return result?.choices;
|
|
16754
|
+
},
|
|
16755
|
+
extractMetadata: (result) => extractMistralResponseMetadata(result),
|
|
16756
|
+
extractMetrics: (result, startTime) => extractMistralMetrics(result?.usage, startTime)
|
|
16757
|
+
})
|
|
16758
|
+
);
|
|
16759
|
+
this.unsubscribers.push(
|
|
16760
|
+
traceStreamingChannel(mistralChannels.agentsStream, {
|
|
16761
|
+
name: "mistral.agents.stream",
|
|
16762
|
+
type: "llm" /* LLM */,
|
|
16763
|
+
extractInput: extractMessagesInputWithMetadata,
|
|
16764
|
+
extractOutput: extractMistralStreamOutput,
|
|
16765
|
+
extractMetadata: (result) => extractMistralResponseMetadata(result),
|
|
16766
|
+
extractMetrics: (result, startTime) => extractMistralStreamingMetrics(result, startTime),
|
|
16767
|
+
aggregateChunks: aggregateMistralStreamChunks
|
|
16768
|
+
})
|
|
16769
|
+
);
|
|
16770
|
+
}
|
|
16771
|
+
};
|
|
16772
|
+
var TOKEN_NAME_MAP4 = {
|
|
16773
|
+
promptTokens: "prompt_tokens",
|
|
16774
|
+
inputTokens: "prompt_tokens",
|
|
16775
|
+
completionTokens: "completion_tokens",
|
|
16776
|
+
outputTokens: "completion_tokens",
|
|
16777
|
+
totalTokens: "tokens",
|
|
16778
|
+
prompt_tokens: "prompt_tokens",
|
|
16779
|
+
input_tokens: "prompt_tokens",
|
|
16780
|
+
completion_tokens: "completion_tokens",
|
|
16781
|
+
output_tokens: "completion_tokens",
|
|
16782
|
+
total_tokens: "tokens",
|
|
16783
|
+
promptAudioSeconds: "prompt_audio_seconds",
|
|
16784
|
+
prompt_audio_seconds: "prompt_audio_seconds"
|
|
16785
|
+
};
|
|
16786
|
+
var TOKEN_DETAIL_PREFIX_MAP3 = {
|
|
16787
|
+
promptTokensDetails: "prompt",
|
|
16788
|
+
inputTokensDetails: "prompt",
|
|
16789
|
+
completionTokensDetails: "completion",
|
|
16790
|
+
outputTokensDetails: "completion",
|
|
16791
|
+
prompt_tokens_details: "prompt",
|
|
16792
|
+
input_tokens_details: "prompt",
|
|
16793
|
+
completion_tokens_details: "completion",
|
|
16794
|
+
output_tokens_details: "completion"
|
|
16795
|
+
};
|
|
16796
|
+
var MISTRAL_REQUEST_METADATA_ALLOWLIST = /* @__PURE__ */ new Set([
|
|
16797
|
+
"agentId",
|
|
16798
|
+
"agent_id",
|
|
16799
|
+
"encodingFormat",
|
|
16800
|
+
"encoding_format",
|
|
16801
|
+
"frequencyPenalty",
|
|
16802
|
+
"frequency_penalty",
|
|
16803
|
+
"maxTokens",
|
|
16804
|
+
"max_tokens",
|
|
16805
|
+
"model",
|
|
16806
|
+
"n",
|
|
16807
|
+
"presencePenalty",
|
|
16808
|
+
"presence_penalty",
|
|
16809
|
+
"randomSeed",
|
|
16810
|
+
"random_seed",
|
|
16811
|
+
"responseFormat",
|
|
16812
|
+
"response_format",
|
|
16813
|
+
"safePrompt",
|
|
16814
|
+
"safe_prompt",
|
|
16815
|
+
"stream",
|
|
16816
|
+
"stop",
|
|
16817
|
+
"temperature",
|
|
16818
|
+
"toolChoice",
|
|
16819
|
+
"tool_choice",
|
|
16820
|
+
"topP",
|
|
16821
|
+
"top_p"
|
|
16822
|
+
]);
|
|
16823
|
+
var MISTRAL_RESPONSE_METADATA_ALLOWLIST = /* @__PURE__ */ new Set([
|
|
16824
|
+
"agentId",
|
|
16825
|
+
"agent_id",
|
|
16826
|
+
"created",
|
|
16827
|
+
"id",
|
|
16828
|
+
"model",
|
|
16829
|
+
"object"
|
|
16830
|
+
]);
|
|
16831
|
+
function camelToSnake3(value) {
|
|
16832
|
+
return value.replace(/[A-Z]/g, (match) => `_${match.toLowerCase()}`);
|
|
16833
|
+
}
|
|
16834
|
+
function normalizeArgs3(args) {
|
|
16835
|
+
if (Array.isArray(args)) {
|
|
16836
|
+
return args;
|
|
16837
|
+
}
|
|
16838
|
+
if (isArrayLike3(args)) {
|
|
16839
|
+
return Array.from(args);
|
|
16840
|
+
}
|
|
16841
|
+
return [args];
|
|
16842
|
+
}
|
|
16843
|
+
function isArrayLike3(value) {
|
|
16844
|
+
return isObject(value) && "length" in value && typeof value.length === "number" && Number.isInteger(value.length) && value.length >= 0;
|
|
16845
|
+
}
|
|
16846
|
+
function getMistralRequestArg(args) {
|
|
16847
|
+
const firstObjectArg = normalizeArgs3(args).find((arg) => isObject(arg));
|
|
16848
|
+
return isObject(firstObjectArg) ? firstObjectArg : void 0;
|
|
16849
|
+
}
|
|
16850
|
+
function addMistralProviderMetadata(metadata) {
|
|
16851
|
+
return {
|
|
16852
|
+
...metadata,
|
|
16853
|
+
provider: "mistral"
|
|
16854
|
+
};
|
|
16855
|
+
}
|
|
16856
|
+
function pickAllowedMetadata(metadata, allowlist) {
|
|
16857
|
+
if (!metadata) {
|
|
16858
|
+
return {};
|
|
16859
|
+
}
|
|
16860
|
+
const picked = {};
|
|
16861
|
+
for (const key of allowlist) {
|
|
16862
|
+
const value = metadata[key];
|
|
16863
|
+
if (value !== void 0) {
|
|
16864
|
+
picked[key] = value;
|
|
16865
|
+
}
|
|
16866
|
+
}
|
|
16867
|
+
return picked;
|
|
16868
|
+
}
|
|
16869
|
+
function extractMistralRequestMetadata(metadata) {
|
|
16870
|
+
return pickAllowedMetadata(metadata, MISTRAL_REQUEST_METADATA_ALLOWLIST);
|
|
16871
|
+
}
|
|
16872
|
+
function isMistralChatCompletionChunk(value) {
|
|
16873
|
+
return isObject(value);
|
|
16874
|
+
}
|
|
16875
|
+
function isMistralChunkChoice(value) {
|
|
16876
|
+
return isObject(value);
|
|
16877
|
+
}
|
|
16878
|
+
function extractMessagesInputWithMetadata(args) {
|
|
16879
|
+
const params = getMistralRequestArg(args);
|
|
16880
|
+
const { messages, ...rawMetadata } = params || {};
|
|
16881
|
+
return {
|
|
16882
|
+
input: processInputAttachments(messages),
|
|
16883
|
+
metadata: addMistralProviderMetadata(
|
|
16884
|
+
extractMistralRequestMetadata(rawMetadata)
|
|
16885
|
+
)
|
|
16886
|
+
};
|
|
16887
|
+
}
|
|
16888
|
+
function extractEmbeddingInputWithMetadata(args) {
|
|
16889
|
+
const params = getMistralRequestArg(args);
|
|
16890
|
+
const { inputs, ...rawMetadata } = params || {};
|
|
16891
|
+
return {
|
|
16892
|
+
input: inputs,
|
|
16893
|
+
metadata: addMistralProviderMetadata(
|
|
16894
|
+
extractMistralRequestMetadata(rawMetadata)
|
|
16895
|
+
)
|
|
16896
|
+
};
|
|
16897
|
+
}
|
|
16898
|
+
function extractPromptInputWithMetadata(args) {
|
|
16899
|
+
const params = getMistralRequestArg(args);
|
|
16900
|
+
const { prompt, ...rawMetadata } = params || {};
|
|
16901
|
+
return {
|
|
16902
|
+
input: prompt,
|
|
16903
|
+
metadata: addMistralProviderMetadata(
|
|
16904
|
+
extractMistralRequestMetadata(rawMetadata)
|
|
16905
|
+
)
|
|
16906
|
+
};
|
|
16907
|
+
}
|
|
16908
|
+
function extractMistralResponseMetadata(result) {
|
|
16909
|
+
if (!isObject(result)) {
|
|
16910
|
+
return void 0;
|
|
16911
|
+
}
|
|
16912
|
+
const { choices: _choices, usage: _usage, data: _data, ...metadata } = result;
|
|
16913
|
+
const picked = pickAllowedMetadata(
|
|
16914
|
+
metadata,
|
|
16915
|
+
MISTRAL_RESPONSE_METADATA_ALLOWLIST
|
|
16916
|
+
);
|
|
16917
|
+
return Object.keys(picked).length > 0 ? picked : void 0;
|
|
16918
|
+
}
|
|
16919
|
+
function extractMistralMetrics(usage, startTime) {
|
|
16920
|
+
const metrics = parseMistralMetricsFromUsage(usage);
|
|
16921
|
+
if (startTime) {
|
|
16922
|
+
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
16923
|
+
}
|
|
16924
|
+
return metrics;
|
|
16925
|
+
}
|
|
16926
|
+
function extractMistralStreamOutput(result) {
|
|
16927
|
+
return isObject(result) ? result.choices : void 0;
|
|
16928
|
+
}
|
|
16929
|
+
function extractMistralStreamingMetrics(result, startTime) {
|
|
16930
|
+
const metrics = isObject(result) ? parseMistralMetricsFromUsage(result.usage) : {};
|
|
16931
|
+
if (startTime) {
|
|
16932
|
+
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
16933
|
+
}
|
|
16934
|
+
return metrics;
|
|
16935
|
+
}
|
|
16936
|
+
function extractDeltaText(content) {
|
|
16937
|
+
if (typeof content === "string") {
|
|
16938
|
+
return content;
|
|
16939
|
+
}
|
|
16940
|
+
if (!Array.isArray(content)) {
|
|
16941
|
+
return void 0;
|
|
16942
|
+
}
|
|
16943
|
+
const textParts = content.map((part) => {
|
|
16944
|
+
if (!isObject(part) || part.type !== "text") {
|
|
16945
|
+
return "";
|
|
16946
|
+
}
|
|
16947
|
+
return typeof part.text === "string" ? part.text : "";
|
|
16948
|
+
}).filter((part) => part.length > 0);
|
|
16949
|
+
return textParts.length > 0 ? textParts.join("") : void 0;
|
|
16950
|
+
}
|
|
16951
|
+
function getDeltaToolCalls(delta) {
|
|
16952
|
+
const toolCalls = Array.isArray(delta.toolCalls) && delta.toolCalls || Array.isArray(delta.tool_calls) && delta.tool_calls || [];
|
|
16953
|
+
return toolCalls.filter((toolCall) => isObject(toolCall));
|
|
16954
|
+
}
|
|
16955
|
+
function getToolCallIndex(toolCall) {
|
|
16956
|
+
return typeof toolCall.index === "number" && toolCall.index >= 0 ? toolCall.index : void 0;
|
|
16957
|
+
}
|
|
16958
|
+
function createMergedToolCallDelta(delta) {
|
|
16959
|
+
return {
|
|
16960
|
+
...delta,
|
|
16961
|
+
function: {
|
|
16962
|
+
...delta.function,
|
|
16963
|
+
arguments: typeof delta.function?.arguments === "string" ? delta.function.arguments : ""
|
|
16964
|
+
}
|
|
16965
|
+
};
|
|
16966
|
+
}
|
|
16967
|
+
function mergeToolCallDeltaPair(current, delta) {
|
|
16968
|
+
const currentArguments = typeof current.function?.arguments === "string" ? current.function.arguments : "";
|
|
16969
|
+
const deltaArguments = typeof delta.function?.arguments === "string" ? delta.function.arguments : "";
|
|
16970
|
+
return {
|
|
16971
|
+
...current,
|
|
16972
|
+
...delta,
|
|
16973
|
+
function: {
|
|
16974
|
+
...current.function || {},
|
|
16975
|
+
...delta.function || {},
|
|
16976
|
+
arguments: `${currentArguments}${deltaArguments}`
|
|
16977
|
+
}
|
|
16978
|
+
};
|
|
15162
16979
|
}
|
|
15163
|
-
function
|
|
15164
|
-
|
|
16980
|
+
function mergeToolCallDeltas(toolCalls, deltas) {
|
|
16981
|
+
if (deltas.length === 0) {
|
|
16982
|
+
return toolCalls;
|
|
16983
|
+
}
|
|
16984
|
+
const merged = toolCalls ? [...toolCalls] : [];
|
|
16985
|
+
const indexToPosition = /* @__PURE__ */ new Map();
|
|
16986
|
+
const idToPosition = /* @__PURE__ */ new Map();
|
|
16987
|
+
for (const [position, toolCall] of merged.entries()) {
|
|
16988
|
+
const index = getToolCallIndex(toolCall);
|
|
16989
|
+
if (index !== void 0 && !indexToPosition.has(index)) {
|
|
16990
|
+
indexToPosition.set(index, position);
|
|
16991
|
+
}
|
|
16992
|
+
if (typeof toolCall.id === "string" && !idToPosition.has(toolCall.id)) {
|
|
16993
|
+
idToPosition.set(toolCall.id, position);
|
|
16994
|
+
}
|
|
16995
|
+
}
|
|
16996
|
+
for (const delta of deltas) {
|
|
16997
|
+
const deltaIndex = getToolCallIndex(delta);
|
|
16998
|
+
const existingByIndex = deltaIndex !== void 0 ? indexToPosition.get(deltaIndex) : void 0;
|
|
16999
|
+
const existingById = typeof delta.id === "string" ? idToPosition.get(delta.id) : void 0;
|
|
17000
|
+
const existingPosition = existingByIndex ?? existingById;
|
|
17001
|
+
if (existingPosition === void 0) {
|
|
17002
|
+
const newToolCall = createMergedToolCallDelta(delta);
|
|
17003
|
+
merged.push(newToolCall);
|
|
17004
|
+
const newPosition = merged.length - 1;
|
|
17005
|
+
const newIndex = getToolCallIndex(newToolCall);
|
|
17006
|
+
if (newIndex !== void 0 && !indexToPosition.has(newIndex)) {
|
|
17007
|
+
indexToPosition.set(newIndex, newPosition);
|
|
17008
|
+
}
|
|
17009
|
+
if (typeof newToolCall.id === "string" && !idToPosition.has(newToolCall.id)) {
|
|
17010
|
+
idToPosition.set(newToolCall.id, newPosition);
|
|
17011
|
+
}
|
|
17012
|
+
continue;
|
|
17013
|
+
}
|
|
17014
|
+
const mergedToolCall = mergeToolCallDeltaPair(
|
|
17015
|
+
merged[existingPosition],
|
|
17016
|
+
delta
|
|
17017
|
+
);
|
|
17018
|
+
merged[existingPosition] = mergedToolCall;
|
|
17019
|
+
const mergedIndex = getToolCallIndex(mergedToolCall);
|
|
17020
|
+
if (mergedIndex !== void 0 && !indexToPosition.has(mergedIndex)) {
|
|
17021
|
+
indexToPosition.set(mergedIndex, existingPosition);
|
|
17022
|
+
}
|
|
17023
|
+
if (typeof mergedToolCall.id === "string" && !idToPosition.has(mergedToolCall.id)) {
|
|
17024
|
+
idToPosition.set(mergedToolCall.id, existingPosition);
|
|
17025
|
+
}
|
|
17026
|
+
}
|
|
17027
|
+
return merged.length > 0 ? merged : void 0;
|
|
17028
|
+
}
|
|
17029
|
+
function getChoiceFinishReason(choice) {
|
|
17030
|
+
if (typeof choice.finishReason === "string" || choice.finishReason === null) {
|
|
17031
|
+
return choice.finishReason;
|
|
17032
|
+
}
|
|
17033
|
+
if (typeof choice.finish_reason === "string" || choice.finish_reason === null) {
|
|
17034
|
+
return choice.finish_reason;
|
|
17035
|
+
}
|
|
17036
|
+
return void 0;
|
|
17037
|
+
}
|
|
17038
|
+
function parseMistralMetricsFromUsage(usage) {
|
|
17039
|
+
if (!isObject(usage)) {
|
|
17040
|
+
return {};
|
|
17041
|
+
}
|
|
17042
|
+
const metrics = {};
|
|
17043
|
+
for (const [name, value] of Object.entries(usage)) {
|
|
17044
|
+
if (typeof value === "number") {
|
|
17045
|
+
metrics[TOKEN_NAME_MAP4[name] || camelToSnake3(name)] = value;
|
|
17046
|
+
continue;
|
|
17047
|
+
}
|
|
17048
|
+
if (!isObject(value)) {
|
|
17049
|
+
continue;
|
|
17050
|
+
}
|
|
17051
|
+
const prefix = TOKEN_DETAIL_PREFIX_MAP3[name];
|
|
17052
|
+
if (!prefix) {
|
|
17053
|
+
continue;
|
|
17054
|
+
}
|
|
17055
|
+
for (const [nestedName, nestedValue] of Object.entries(value)) {
|
|
17056
|
+
if (typeof nestedValue !== "number") {
|
|
17057
|
+
continue;
|
|
17058
|
+
}
|
|
17059
|
+
metrics[`${prefix}_${camelToSnake3(nestedName)}`] = nestedValue;
|
|
17060
|
+
}
|
|
17061
|
+
}
|
|
17062
|
+
return metrics;
|
|
17063
|
+
}
|
|
17064
|
+
function aggregateMistralStreamChunks(chunks) {
|
|
17065
|
+
const choiceAccumulators = /* @__PURE__ */ new Map();
|
|
17066
|
+
const indexToAccumulatorKey = /* @__PURE__ */ new Map();
|
|
17067
|
+
const positionToAccumulatorKey = /* @__PURE__ */ new Map();
|
|
17068
|
+
let nextAccumulatorOrder = 0;
|
|
17069
|
+
let metrics = {};
|
|
17070
|
+
let metadata;
|
|
17071
|
+
for (const event of chunks) {
|
|
17072
|
+
const chunk = isMistralChatCompletionChunk(event?.data) ? event.data : void 0;
|
|
17073
|
+
if (!chunk) {
|
|
17074
|
+
continue;
|
|
17075
|
+
}
|
|
17076
|
+
if (isObject(chunk.usage)) {
|
|
17077
|
+
metrics = {
|
|
17078
|
+
...metrics,
|
|
17079
|
+
...parseMistralMetricsFromUsage(chunk.usage)
|
|
17080
|
+
};
|
|
17081
|
+
}
|
|
17082
|
+
const chunkMetadata = extractMistralResponseMetadata(chunk);
|
|
17083
|
+
if (chunkMetadata) {
|
|
17084
|
+
metadata = { ...metadata || {}, ...chunkMetadata };
|
|
17085
|
+
}
|
|
17086
|
+
for (const [choicePosition, rawChoice] of (chunk.choices || []).entries()) {
|
|
17087
|
+
if (!isMistralChunkChoice(rawChoice)) {
|
|
17088
|
+
continue;
|
|
17089
|
+
}
|
|
17090
|
+
const choice = rawChoice;
|
|
17091
|
+
const choiceIndex = typeof choice.index === "number" && choice.index >= 0 ? choice.index : void 0;
|
|
17092
|
+
let accumulatorKey = choiceIndex !== void 0 ? indexToAccumulatorKey.get(choiceIndex) : void 0;
|
|
17093
|
+
if (!accumulatorKey) {
|
|
17094
|
+
accumulatorKey = positionToAccumulatorKey.get(choicePosition);
|
|
17095
|
+
}
|
|
17096
|
+
if (!accumulatorKey) {
|
|
17097
|
+
const initialIndex = choiceIndex ?? choicePosition;
|
|
17098
|
+
const keyPrefix = choiceIndex !== void 0 ? "index" : "position";
|
|
17099
|
+
accumulatorKey = `${keyPrefix}:${initialIndex}`;
|
|
17100
|
+
choiceAccumulators.set(accumulatorKey, {
|
|
17101
|
+
index: initialIndex,
|
|
17102
|
+
order: nextAccumulatorOrder++
|
|
17103
|
+
});
|
|
17104
|
+
}
|
|
17105
|
+
const accumulator = choiceAccumulators.get(accumulatorKey);
|
|
17106
|
+
if (!accumulator) {
|
|
17107
|
+
continue;
|
|
17108
|
+
}
|
|
17109
|
+
if (choiceIndex !== void 0) {
|
|
17110
|
+
accumulator.index = choiceIndex;
|
|
17111
|
+
indexToAccumulatorKey.set(choiceIndex, accumulatorKey);
|
|
17112
|
+
}
|
|
17113
|
+
positionToAccumulatorKey.set(choicePosition, accumulatorKey);
|
|
17114
|
+
const delta = isObject(choice.delta) ? choice.delta : void 0;
|
|
17115
|
+
if (delta) {
|
|
17116
|
+
if (!accumulator.role && typeof delta.role === "string") {
|
|
17117
|
+
accumulator.role = delta.role;
|
|
17118
|
+
}
|
|
17119
|
+
const deltaText = extractDeltaText(delta.content);
|
|
17120
|
+
if (deltaText) {
|
|
17121
|
+
accumulator.content = `${accumulator.content || ""}${deltaText}`;
|
|
17122
|
+
}
|
|
17123
|
+
accumulator.toolCalls = mergeToolCallDeltas(
|
|
17124
|
+
accumulator.toolCalls,
|
|
17125
|
+
getDeltaToolCalls(delta)
|
|
17126
|
+
);
|
|
17127
|
+
}
|
|
17128
|
+
const choiceFinishReason = getChoiceFinishReason(choice);
|
|
17129
|
+
if (choiceFinishReason !== void 0) {
|
|
17130
|
+
accumulator.finishReason = choiceFinishReason;
|
|
17131
|
+
}
|
|
17132
|
+
}
|
|
17133
|
+
}
|
|
17134
|
+
const output = Array.from(choiceAccumulators.values()).sort(
|
|
17135
|
+
(left, right) => left.index === right.index ? left.order - right.order : left.index - right.index
|
|
17136
|
+
).map((choice) => ({
|
|
17137
|
+
index: choice.index,
|
|
17138
|
+
message: {
|
|
17139
|
+
...choice.role ? { role: choice.role } : {},
|
|
17140
|
+
content: choice.content ?? null,
|
|
17141
|
+
...choice.toolCalls ? { toolCalls: choice.toolCalls } : {}
|
|
17142
|
+
},
|
|
17143
|
+
...choice.finishReason !== void 0 ? { finishReason: choice.finishReason } : {}
|
|
17144
|
+
}));
|
|
17145
|
+
return {
|
|
17146
|
+
output,
|
|
17147
|
+
metrics,
|
|
17148
|
+
...metadata ? { metadata } : {}
|
|
17149
|
+
};
|
|
15165
17150
|
}
|
|
15166
17151
|
|
|
15167
17152
|
// src/instrumentation/braintrust-plugin.ts
|
|
@@ -15173,6 +17158,8 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
15173
17158
|
claudeAgentSDKPlugin = null;
|
|
15174
17159
|
googleGenAIPlugin = null;
|
|
15175
17160
|
openRouterPlugin = null;
|
|
17161
|
+
openRouterAgentPlugin = null;
|
|
17162
|
+
mistralPlugin = null;
|
|
15176
17163
|
constructor(config = {}) {
|
|
15177
17164
|
super();
|
|
15178
17165
|
this.config = config;
|
|
@@ -15203,6 +17190,14 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
15203
17190
|
this.openRouterPlugin = new OpenRouterPlugin();
|
|
15204
17191
|
this.openRouterPlugin.enable();
|
|
15205
17192
|
}
|
|
17193
|
+
if (integrations.openrouterAgent !== false) {
|
|
17194
|
+
this.openRouterAgentPlugin = new OpenRouterAgentPlugin();
|
|
17195
|
+
this.openRouterAgentPlugin.enable();
|
|
17196
|
+
}
|
|
17197
|
+
if (integrations.mistral !== false) {
|
|
17198
|
+
this.mistralPlugin = new MistralPlugin();
|
|
17199
|
+
this.mistralPlugin.enable();
|
|
17200
|
+
}
|
|
15206
17201
|
}
|
|
15207
17202
|
onDisable() {
|
|
15208
17203
|
if (this.openaiPlugin) {
|
|
@@ -15229,6 +17224,14 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
15229
17224
|
this.openRouterPlugin.disable();
|
|
15230
17225
|
this.openRouterPlugin = null;
|
|
15231
17226
|
}
|
|
17227
|
+
if (this.openRouterAgentPlugin) {
|
|
17228
|
+
this.openRouterAgentPlugin.disable();
|
|
17229
|
+
this.openRouterAgentPlugin = null;
|
|
17230
|
+
}
|
|
17231
|
+
if (this.mistralPlugin) {
|
|
17232
|
+
this.mistralPlugin.disable();
|
|
17233
|
+
this.mistralPlugin = null;
|
|
17234
|
+
}
|
|
15232
17235
|
}
|
|
15233
17236
|
};
|
|
15234
17237
|
|
|
@@ -15301,7 +17304,9 @@ var PluginRegistry = class {
|
|
|
15301
17304
|
aisdk: true,
|
|
15302
17305
|
google: true,
|
|
15303
17306
|
claudeAgentSDK: true,
|
|
15304
|
-
openrouter: true
|
|
17307
|
+
openrouter: true,
|
|
17308
|
+
openrouterAgent: true,
|
|
17309
|
+
mistral: true
|
|
15305
17310
|
};
|
|
15306
17311
|
}
|
|
15307
17312
|
/**
|
|
@@ -15448,6 +17453,7 @@ var exports_exports = {};
|
|
|
15448
17453
|
__export(exports_exports, {
|
|
15449
17454
|
Attachment: () => Attachment,
|
|
15450
17455
|
AttachmentReference: () => AttachmentReference,
|
|
17456
|
+
BRAINTRUST_CURRENT_SPAN_STORE: () => BRAINTRUST_CURRENT_SPAN_STORE,
|
|
15451
17457
|
BaseAttachment: () => BaseAttachment,
|
|
15452
17458
|
BaseExperiment: () => BaseExperiment,
|
|
15453
17459
|
BraintrustMiddleware: () => BraintrustMiddleware,
|
|
@@ -15574,9 +17580,11 @@ __export(exports_exports, {
|
|
|
15574
17580
|
wrapClaudeAgentSDK: () => wrapClaudeAgentSDK,
|
|
15575
17581
|
wrapGoogleGenAI: () => wrapGoogleGenAI,
|
|
15576
17582
|
wrapMastraAgent: () => wrapMastraAgent,
|
|
17583
|
+
wrapMistral: () => wrapMistral,
|
|
15577
17584
|
wrapOpenAI: () => wrapOpenAI,
|
|
15578
17585
|
wrapOpenAIv4: () => wrapOpenAIv4,
|
|
15579
17586
|
wrapOpenRouter: () => wrapOpenRouter,
|
|
17587
|
+
wrapOpenRouterAgent: () => wrapOpenRouterAgent,
|
|
15580
17588
|
wrapTraced: () => wrapTraced,
|
|
15581
17589
|
wrapVitest: () => wrapVitest
|
|
15582
17590
|
});
|
|
@@ -15833,21 +17841,26 @@ function responsesProxy(openai) {
|
|
|
15833
17841
|
}
|
|
15834
17842
|
return new Proxy(openai.responses, {
|
|
15835
17843
|
get(target, name, receiver) {
|
|
15836
|
-
if (name === "create") {
|
|
17844
|
+
if (name === "create" && typeof target.create === "function") {
|
|
15837
17845
|
return wrapResponsesAsync(
|
|
15838
17846
|
target.create.bind(target),
|
|
15839
17847
|
openAIChannels.responsesCreate
|
|
15840
17848
|
);
|
|
15841
|
-
} else if (name === "stream") {
|
|
17849
|
+
} else if (name === "stream" && typeof target.stream === "function") {
|
|
15842
17850
|
return wrapResponsesSyncStream(
|
|
15843
17851
|
target.stream.bind(target),
|
|
15844
17852
|
openAIChannels.responsesStream
|
|
15845
17853
|
);
|
|
15846
|
-
} else if (name === "parse") {
|
|
17854
|
+
} else if (name === "parse" && typeof target.parse === "function") {
|
|
15847
17855
|
return wrapResponsesAsync(
|
|
15848
17856
|
target.parse.bind(target),
|
|
15849
17857
|
openAIChannels.responsesParse
|
|
15850
17858
|
);
|
|
17859
|
+
} else if (name === "compact" && typeof target.compact === "function") {
|
|
17860
|
+
return wrapResponsesAsync(
|
|
17861
|
+
target.compact.bind(target),
|
|
17862
|
+
openAIChannels.responsesCompact
|
|
17863
|
+
);
|
|
15851
17864
|
}
|
|
15852
17865
|
return Reflect.get(target, name, receiver);
|
|
15853
17866
|
}
|
|
@@ -15908,7 +17921,7 @@ function wrapOpenAIv4(openai) {
|
|
|
15908
17921
|
return baseVal;
|
|
15909
17922
|
}
|
|
15910
17923
|
});
|
|
15911
|
-
const
|
|
17924
|
+
const chatProxy3 = new Proxy(typedOpenai.chat, {
|
|
15912
17925
|
get(target, name, receiver) {
|
|
15913
17926
|
if (name === "completions") {
|
|
15914
17927
|
return completionProxy;
|
|
@@ -15955,7 +17968,7 @@ function wrapOpenAIv4(openai) {
|
|
|
15955
17968
|
get(target, name) {
|
|
15956
17969
|
switch (name) {
|
|
15957
17970
|
case "chat":
|
|
15958
|
-
return
|
|
17971
|
+
return chatProxy3;
|
|
15959
17972
|
case "embeddings":
|
|
15960
17973
|
return embeddingProxy;
|
|
15961
17974
|
case "moderations":
|
|
@@ -16124,6 +18137,10 @@ function wrapAISDK(aiSDK, options = {}) {
|
|
|
16124
18137
|
);
|
|
16125
18138
|
case "streamObject":
|
|
16126
18139
|
return wrapStreamObject(typedAISDK.streamObject, options, typedAISDK);
|
|
18140
|
+
case "embed":
|
|
18141
|
+
return wrapEmbed(typedAISDK.embed, options, typedAISDK);
|
|
18142
|
+
case "embedMany":
|
|
18143
|
+
return wrapEmbedMany(typedAISDK.embedMany, options, typedAISDK);
|
|
16127
18144
|
case "Agent":
|
|
16128
18145
|
case "Experimental_Agent":
|
|
16129
18146
|
case "ToolLoopAgent":
|
|
@@ -16224,6 +18241,44 @@ var wrapGenerateObject = (generateObject, options = {}, aiSDK) => {
|
|
|
16224
18241
|
options
|
|
16225
18242
|
);
|
|
16226
18243
|
};
|
|
18244
|
+
var makeEmbedWrapper = (channel2, name, embed, contextOptions = {}, options = {}) => {
|
|
18245
|
+
const wrapper = async function(allParams) {
|
|
18246
|
+
const { span_info, ...params } = allParams;
|
|
18247
|
+
const tracedParams = { ...params };
|
|
18248
|
+
return channel2.tracePromise(
|
|
18249
|
+
() => embed(tracedParams),
|
|
18250
|
+
createAISDKChannelContext(tracedParams, {
|
|
18251
|
+
aiSDK: contextOptions.aiSDK,
|
|
18252
|
+
denyOutputPaths: options.denyOutputPaths,
|
|
18253
|
+
self: contextOptions.self,
|
|
18254
|
+
span_info: mergeSpanInfo(span_info, {
|
|
18255
|
+
name,
|
|
18256
|
+
spanType: contextOptions.spanType
|
|
18257
|
+
})
|
|
18258
|
+
})
|
|
18259
|
+
);
|
|
18260
|
+
};
|
|
18261
|
+
Object.defineProperty(wrapper, "name", { value: name, writable: false });
|
|
18262
|
+
return wrapper;
|
|
18263
|
+
};
|
|
18264
|
+
var wrapEmbed = (embed, options = {}, aiSDK) => {
|
|
18265
|
+
return makeEmbedWrapper(
|
|
18266
|
+
aiSDKChannels.embed,
|
|
18267
|
+
"embed",
|
|
18268
|
+
embed,
|
|
18269
|
+
{ aiSDK },
|
|
18270
|
+
options
|
|
18271
|
+
);
|
|
18272
|
+
};
|
|
18273
|
+
var wrapEmbedMany = (embedMany, options = {}, aiSDK) => {
|
|
18274
|
+
return makeEmbedWrapper(
|
|
18275
|
+
aiSDKChannels.embedMany,
|
|
18276
|
+
"embedMany",
|
|
18277
|
+
embedMany,
|
|
18278
|
+
{ aiSDK },
|
|
18279
|
+
options
|
|
18280
|
+
);
|
|
18281
|
+
};
|
|
16227
18282
|
var makeStreamWrapper = (channel2, name, streamText, contextOptions = {}, options = {}) => {
|
|
16228
18283
|
const wrapper = function(allParams) {
|
|
16229
18284
|
const { span_info, ...params } = allParams;
|
|
@@ -16578,14 +18633,14 @@ function extractModelFromResult(result) {
|
|
|
16578
18633
|
function extractModelFromWrapGenerateCallback(model) {
|
|
16579
18634
|
return model?.modelId;
|
|
16580
18635
|
}
|
|
16581
|
-
function
|
|
18636
|
+
function camelToSnake4(str) {
|
|
16582
18637
|
return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
|
|
16583
18638
|
}
|
|
16584
18639
|
function extractModelParameters(params, excludeKeys) {
|
|
16585
18640
|
const modelParams = {};
|
|
16586
18641
|
for (const [key, value] of Object.entries(params)) {
|
|
16587
18642
|
if (value !== void 0 && !excludeKeys.has(key)) {
|
|
16588
|
-
const snakeKey =
|
|
18643
|
+
const snakeKey = camelToSnake4(key);
|
|
16589
18644
|
modelParams[snakeKey] = value;
|
|
16590
18645
|
}
|
|
16591
18646
|
}
|
|
@@ -16963,20 +19018,80 @@ function wrapClaudeAgentQuery(queryFn, defaultThis) {
|
|
|
16963
19018
|
const proxy = new Proxy(queryFn, {
|
|
16964
19019
|
apply(target, thisArg, argArray) {
|
|
16965
19020
|
const params = argArray[0] ?? {};
|
|
19021
|
+
const wrappedParams = {
|
|
19022
|
+
...params,
|
|
19023
|
+
options: {
|
|
19024
|
+
...params.options ?? {},
|
|
19025
|
+
[CLAUDE_AGENT_SDK_SKIP_LOCAL_TOOL_HOOKS_OPTION]: true
|
|
19026
|
+
}
|
|
19027
|
+
};
|
|
16966
19028
|
const invocationTarget = thisArg === proxy || thisArg === void 0 ? defaultThis ?? thisArg : thisArg;
|
|
16967
19029
|
return claudeAgentSDKChannels.query.traceSync(
|
|
16968
|
-
|
|
16969
|
-
() => Reflect.apply(target, invocationTarget, [params]),
|
|
19030
|
+
() => Reflect.apply(target, invocationTarget, [wrappedParams]),
|
|
16970
19031
|
// The channel carries no extra context fields, but the generated
|
|
16971
19032
|
// StartOf<> type for Record<string, never> is overly strict here.
|
|
16972
|
-
{ arguments: [
|
|
19033
|
+
{ arguments: [wrappedParams] }
|
|
19034
|
+
);
|
|
19035
|
+
}
|
|
19036
|
+
});
|
|
19037
|
+
return proxy;
|
|
19038
|
+
}
|
|
19039
|
+
function wrapClaudeAgentTool(toolFn, localToolMetadataByTool, defaultThis) {
|
|
19040
|
+
const proxy = new Proxy(toolFn, {
|
|
19041
|
+
apply(target, thisArg, argArray) {
|
|
19042
|
+
const invocationTarget = thisArg === proxy || thisArg === void 0 ? defaultThis ?? thisArg : thisArg;
|
|
19043
|
+
const wrappedArgs = [...argArray];
|
|
19044
|
+
const toolName = wrappedArgs[0];
|
|
19045
|
+
let handlerIndex = -1;
|
|
19046
|
+
for (let i = wrappedArgs.length - 1; i >= 0; i -= 1) {
|
|
19047
|
+
if (typeof wrappedArgs[i] === "function") {
|
|
19048
|
+
handlerIndex = i;
|
|
19049
|
+
break;
|
|
19050
|
+
}
|
|
19051
|
+
}
|
|
19052
|
+
if (typeof toolName !== "string" || handlerIndex === -1) {
|
|
19053
|
+
return Reflect.apply(target, invocationTarget, wrappedArgs);
|
|
19054
|
+
}
|
|
19055
|
+
const localToolMetadata = { toolName };
|
|
19056
|
+
const originalHandler = wrappedArgs[handlerIndex];
|
|
19057
|
+
wrappedArgs[handlerIndex] = wrapLocalClaudeToolHandler(
|
|
19058
|
+
originalHandler,
|
|
19059
|
+
() => localToolMetadata
|
|
16973
19060
|
);
|
|
19061
|
+
const wrappedTool = Reflect.apply(target, invocationTarget, wrappedArgs);
|
|
19062
|
+
if (wrappedTool && typeof wrappedTool === "object") {
|
|
19063
|
+
localToolMetadataByTool.set(wrappedTool, localToolMetadata);
|
|
19064
|
+
}
|
|
19065
|
+
return wrappedTool;
|
|
19066
|
+
}
|
|
19067
|
+
});
|
|
19068
|
+
return proxy;
|
|
19069
|
+
}
|
|
19070
|
+
function wrapCreateSdkMcpServer(createSdkMcpServerFn, localToolMetadataByTool, defaultThis) {
|
|
19071
|
+
const proxy = new Proxy(createSdkMcpServerFn, {
|
|
19072
|
+
apply(target, thisArg, argArray) {
|
|
19073
|
+
const invocationTarget = thisArg === proxy || thisArg === void 0 ? defaultThis ?? thisArg : thisArg;
|
|
19074
|
+
const config = argArray[0];
|
|
19075
|
+
const serverName = config?.name;
|
|
19076
|
+
if (typeof serverName === "string" && Array.isArray(config?.tools)) {
|
|
19077
|
+
for (const tool of config.tools) {
|
|
19078
|
+
if (!tool || typeof tool !== "object") {
|
|
19079
|
+
continue;
|
|
19080
|
+
}
|
|
19081
|
+
const metadata = localToolMetadataByTool.get(tool);
|
|
19082
|
+
if (metadata) {
|
|
19083
|
+
metadata.serverName = serverName;
|
|
19084
|
+
}
|
|
19085
|
+
}
|
|
19086
|
+
}
|
|
19087
|
+
return Reflect.apply(target, invocationTarget, argArray);
|
|
16974
19088
|
}
|
|
16975
19089
|
});
|
|
16976
19090
|
return proxy;
|
|
16977
19091
|
}
|
|
16978
19092
|
function claudeAgentSDKProxy(sdk) {
|
|
16979
19093
|
const cache = /* @__PURE__ */ new Map();
|
|
19094
|
+
const localToolMetadataByTool = /* @__PURE__ */ new WeakMap();
|
|
16980
19095
|
return new Proxy(sdk, {
|
|
16981
19096
|
get(target, prop, receiver) {
|
|
16982
19097
|
if (cache.has(prop)) {
|
|
@@ -16988,6 +19103,24 @@ function claudeAgentSDKProxy(sdk) {
|
|
|
16988
19103
|
cache.set(prop, wrappedQuery);
|
|
16989
19104
|
return wrappedQuery;
|
|
16990
19105
|
}
|
|
19106
|
+
if (prop === "tool" && typeof value === "function") {
|
|
19107
|
+
const wrappedTool = wrapClaudeAgentTool(
|
|
19108
|
+
target.tool,
|
|
19109
|
+
localToolMetadataByTool,
|
|
19110
|
+
target
|
|
19111
|
+
);
|
|
19112
|
+
cache.set(prop, wrappedTool);
|
|
19113
|
+
return wrappedTool;
|
|
19114
|
+
}
|
|
19115
|
+
if (prop === "createSdkMcpServer" && typeof value === "function") {
|
|
19116
|
+
const wrappedCreateSdkMcpServer = wrapCreateSdkMcpServer(
|
|
19117
|
+
value,
|
|
19118
|
+
localToolMetadataByTool,
|
|
19119
|
+
target
|
|
19120
|
+
);
|
|
19121
|
+
cache.set(prop, wrappedCreateSdkMcpServer);
|
|
19122
|
+
return wrappedCreateSdkMcpServer;
|
|
19123
|
+
}
|
|
16991
19124
|
if (typeof value === "function") {
|
|
16992
19125
|
const bound = value.bind(target);
|
|
16993
19126
|
cache.set(prop, bound);
|
|
@@ -17073,6 +19206,62 @@ function wrapGenerateContentStream(original) {
|
|
|
17073
19206
|
};
|
|
17074
19207
|
}
|
|
17075
19208
|
|
|
19209
|
+
// src/wrappers/openrouter-agent.ts
|
|
19210
|
+
function wrapOpenRouterAgent(agent) {
|
|
19211
|
+
const candidate = agent;
|
|
19212
|
+
if (candidate && typeof candidate === "object" && "callModel" in candidate && typeof candidate.callModel === "function") {
|
|
19213
|
+
return openRouterAgentProxy(candidate);
|
|
19214
|
+
}
|
|
19215
|
+
console.warn("Unsupported OpenRouter Agent library. Not wrapping.");
|
|
19216
|
+
return agent;
|
|
19217
|
+
}
|
|
19218
|
+
function openRouterAgentProxy(agent) {
|
|
19219
|
+
const cache = /* @__PURE__ */ new Map();
|
|
19220
|
+
return new Proxy(agent, {
|
|
19221
|
+
get(target, prop, receiver) {
|
|
19222
|
+
if (cache.has(prop)) {
|
|
19223
|
+
return cache.get(prop);
|
|
19224
|
+
}
|
|
19225
|
+
const value = Reflect.get(target, prop, receiver);
|
|
19226
|
+
if (prop === "callModel" && typeof value === "function") {
|
|
19227
|
+
const wrapped = wrapCallModel(
|
|
19228
|
+
value,
|
|
19229
|
+
target
|
|
19230
|
+
);
|
|
19231
|
+
cache.set(prop, wrapped);
|
|
19232
|
+
return wrapped;
|
|
19233
|
+
}
|
|
19234
|
+
if (typeof value === "function") {
|
|
19235
|
+
const bound = value.bind(target);
|
|
19236
|
+
cache.set(prop, bound);
|
|
19237
|
+
return bound;
|
|
19238
|
+
}
|
|
19239
|
+
return value;
|
|
19240
|
+
}
|
|
19241
|
+
});
|
|
19242
|
+
}
|
|
19243
|
+
function wrapCallModel(callModelFn, defaultThis) {
|
|
19244
|
+
return new Proxy(callModelFn, {
|
|
19245
|
+
apply(target, thisArg, argArray) {
|
|
19246
|
+
const request = cloneCallModelRequest(argArray[0]);
|
|
19247
|
+
const options = argArray[1];
|
|
19248
|
+
const invocationTarget = thisArg === void 0 ? defaultThis ?? thisArg : thisArg;
|
|
19249
|
+
return openRouterAgentChannels.callModel.traceSync(
|
|
19250
|
+
() => Reflect.apply(target, invocationTarget, [request, options]),
|
|
19251
|
+
{
|
|
19252
|
+
arguments: [request]
|
|
19253
|
+
}
|
|
19254
|
+
);
|
|
19255
|
+
}
|
|
19256
|
+
});
|
|
19257
|
+
}
|
|
19258
|
+
function cloneCallModelRequest(request) {
|
|
19259
|
+
if (!request || typeof request !== "object") {
|
|
19260
|
+
return request;
|
|
19261
|
+
}
|
|
19262
|
+
return { ...request };
|
|
19263
|
+
}
|
|
19264
|
+
|
|
17076
19265
|
// src/wrappers/openrouter.ts
|
|
17077
19266
|
function wrapOpenRouter(openrouter) {
|
|
17078
19267
|
const or = openrouter;
|
|
@@ -17093,7 +19282,7 @@ function openRouterProxy(openrouter) {
|
|
|
17093
19282
|
case "beta":
|
|
17094
19283
|
return target.beta ? betaProxy2(target.beta) : target.beta;
|
|
17095
19284
|
case "callModel":
|
|
17096
|
-
return typeof target.callModel === "function" ?
|
|
19285
|
+
return typeof target.callModel === "function" ? wrapCallModel2(target.callModel.bind(target)) : target.callModel;
|
|
17097
19286
|
default:
|
|
17098
19287
|
return Reflect.get(target, prop, receiver);
|
|
17099
19288
|
}
|
|
@@ -17157,7 +19346,7 @@ function wrapResponsesSend(send) {
|
|
|
17157
19346
|
{ arguments: [request] }
|
|
17158
19347
|
);
|
|
17159
19348
|
}
|
|
17160
|
-
function
|
|
19349
|
+
function wrapCallModel2(callModel) {
|
|
17161
19350
|
return (request, options) => {
|
|
17162
19351
|
const tracedRequest = { ...request };
|
|
17163
19352
|
return openRouterChannels.callModel.traceSync(
|
|
@@ -17169,6 +19358,148 @@ function wrapCallModel(callModel) {
|
|
|
17169
19358
|
};
|
|
17170
19359
|
}
|
|
17171
19360
|
|
|
19361
|
+
// src/wrappers/mistral.ts
|
|
19362
|
+
function wrapMistral(mistral) {
|
|
19363
|
+
if (isSupportedMistralClient(mistral)) {
|
|
19364
|
+
return mistralProxy(mistral);
|
|
19365
|
+
}
|
|
19366
|
+
console.warn("Unsupported Mistral library. Not wrapping.");
|
|
19367
|
+
return mistral;
|
|
19368
|
+
}
|
|
19369
|
+
function isRecord(value) {
|
|
19370
|
+
return typeof value === "object" && value !== null;
|
|
19371
|
+
}
|
|
19372
|
+
function hasFunction(value, methodName) {
|
|
19373
|
+
return isRecord(value) && methodName in value && typeof value[methodName] === "function";
|
|
19374
|
+
}
|
|
19375
|
+
function isSupportedMistralClient(value) {
|
|
19376
|
+
if (!isRecord(value)) {
|
|
19377
|
+
return false;
|
|
19378
|
+
}
|
|
19379
|
+
return value.chat !== void 0 && hasChat(value.chat) || value.embeddings !== void 0 && hasEmbeddings(value.embeddings) || value.fim !== void 0 && hasFim(value.fim) || value.agents !== void 0 && hasAgents(value.agents);
|
|
19380
|
+
}
|
|
19381
|
+
function hasChat(value) {
|
|
19382
|
+
return hasFunction(value, "complete") && hasFunction(value, "stream");
|
|
19383
|
+
}
|
|
19384
|
+
function hasEmbeddings(value) {
|
|
19385
|
+
return hasFunction(value, "create");
|
|
19386
|
+
}
|
|
19387
|
+
function hasFim(value) {
|
|
19388
|
+
return hasFunction(value, "complete") && hasFunction(value, "stream");
|
|
19389
|
+
}
|
|
19390
|
+
function hasAgents(value) {
|
|
19391
|
+
return hasFunction(value, "complete") && hasFunction(value, "stream");
|
|
19392
|
+
}
|
|
19393
|
+
function mistralProxy(mistral) {
|
|
19394
|
+
return new Proxy(mistral, {
|
|
19395
|
+
get(target, prop, receiver) {
|
|
19396
|
+
switch (prop) {
|
|
19397
|
+
case "chat":
|
|
19398
|
+
return target.chat ? chatProxy2(target.chat) : target.chat;
|
|
19399
|
+
case "fim":
|
|
19400
|
+
return target.fim ? fimProxy(target.fim) : target.fim;
|
|
19401
|
+
case "agents":
|
|
19402
|
+
return target.agents ? agentsProxy(target.agents) : target.agents;
|
|
19403
|
+
case "embeddings":
|
|
19404
|
+
return target.embeddings ? embeddingsProxy2(target.embeddings) : target.embeddings;
|
|
19405
|
+
default:
|
|
19406
|
+
return Reflect.get(target, prop, receiver);
|
|
19407
|
+
}
|
|
19408
|
+
}
|
|
19409
|
+
});
|
|
19410
|
+
}
|
|
19411
|
+
function chatProxy2(chat) {
|
|
19412
|
+
return new Proxy(chat, {
|
|
19413
|
+
get(target, prop, receiver) {
|
|
19414
|
+
if (prop === "complete") {
|
|
19415
|
+
return wrapChatComplete(target.complete.bind(target));
|
|
19416
|
+
}
|
|
19417
|
+
if (prop === "stream") {
|
|
19418
|
+
return wrapChatStream(target.stream.bind(target));
|
|
19419
|
+
}
|
|
19420
|
+
return Reflect.get(target, prop, receiver);
|
|
19421
|
+
}
|
|
19422
|
+
});
|
|
19423
|
+
}
|
|
19424
|
+
function embeddingsProxy2(embeddings) {
|
|
19425
|
+
return new Proxy(embeddings, {
|
|
19426
|
+
get(target, prop, receiver) {
|
|
19427
|
+
if (prop === "create") {
|
|
19428
|
+
return wrapEmbeddingsCreate(target.create.bind(target));
|
|
19429
|
+
}
|
|
19430
|
+
return Reflect.get(target, prop, receiver);
|
|
19431
|
+
}
|
|
19432
|
+
});
|
|
19433
|
+
}
|
|
19434
|
+
function fimProxy(fim) {
|
|
19435
|
+
return new Proxy(fim, {
|
|
19436
|
+
get(target, prop, receiver) {
|
|
19437
|
+
if (prop === "complete") {
|
|
19438
|
+
return wrapFimComplete(target.complete.bind(target));
|
|
19439
|
+
}
|
|
19440
|
+
if (prop === "stream") {
|
|
19441
|
+
return wrapFimStream(target.stream.bind(target));
|
|
19442
|
+
}
|
|
19443
|
+
return Reflect.get(target, prop, receiver);
|
|
19444
|
+
}
|
|
19445
|
+
});
|
|
19446
|
+
}
|
|
19447
|
+
function agentsProxy(agents) {
|
|
19448
|
+
return new Proxy(agents, {
|
|
19449
|
+
get(target, prop, receiver) {
|
|
19450
|
+
if (prop === "complete") {
|
|
19451
|
+
return wrapAgentsComplete(target.complete.bind(target));
|
|
19452
|
+
}
|
|
19453
|
+
if (prop === "stream") {
|
|
19454
|
+
return wrapAgentsStream(target.stream.bind(target));
|
|
19455
|
+
}
|
|
19456
|
+
return Reflect.get(target, prop, receiver);
|
|
19457
|
+
}
|
|
19458
|
+
});
|
|
19459
|
+
}
|
|
19460
|
+
function wrapChatComplete(complete) {
|
|
19461
|
+
return (request, options) => mistralChannels.chatComplete.tracePromise(
|
|
19462
|
+
() => complete(request, options),
|
|
19463
|
+
{
|
|
19464
|
+
arguments: [request]
|
|
19465
|
+
}
|
|
19466
|
+
);
|
|
19467
|
+
}
|
|
19468
|
+
function wrapChatStream(stream) {
|
|
19469
|
+
return (request, options) => mistralChannels.chatStream.tracePromise(() => stream(request, options), {
|
|
19470
|
+
arguments: [request]
|
|
19471
|
+
});
|
|
19472
|
+
}
|
|
19473
|
+
function wrapEmbeddingsCreate(create) {
|
|
19474
|
+
return (request, options) => mistralChannels.embeddingsCreate.tracePromise(
|
|
19475
|
+
() => create(request, options),
|
|
19476
|
+
{ arguments: [request] }
|
|
19477
|
+
);
|
|
19478
|
+
}
|
|
19479
|
+
function wrapFimComplete(complete) {
|
|
19480
|
+
return (request, options) => mistralChannels.fimComplete.tracePromise(() => complete(request, options), {
|
|
19481
|
+
arguments: [request]
|
|
19482
|
+
});
|
|
19483
|
+
}
|
|
19484
|
+
function wrapFimStream(stream) {
|
|
19485
|
+
return (request, options) => mistralChannels.fimStream.tracePromise(() => stream(request, options), {
|
|
19486
|
+
arguments: [request]
|
|
19487
|
+
});
|
|
19488
|
+
}
|
|
19489
|
+
function wrapAgentsComplete(complete) {
|
|
19490
|
+
return (request, options) => mistralChannels.agentsComplete.tracePromise(
|
|
19491
|
+
() => complete(request, options),
|
|
19492
|
+
{
|
|
19493
|
+
arguments: [request]
|
|
19494
|
+
}
|
|
19495
|
+
);
|
|
19496
|
+
}
|
|
19497
|
+
function wrapAgentsStream(stream) {
|
|
19498
|
+
return (request, options) => mistralChannels.agentsStream.tracePromise(() => stream(request, options), {
|
|
19499
|
+
arguments: [request]
|
|
19500
|
+
});
|
|
19501
|
+
}
|
|
19502
|
+
|
|
17172
19503
|
// src/wrappers/vitest/context-manager.ts
|
|
17173
19504
|
var VitestContextManager = class {
|
|
17174
19505
|
/**
|
|
@@ -18139,7 +20470,7 @@ function isAsync(fn) {
|
|
|
18139
20470
|
function isAsyncGenerator2(fn) {
|
|
18140
20471
|
return fn[Symbol.toStringTag] === "AsyncGenerator";
|
|
18141
20472
|
}
|
|
18142
|
-
function
|
|
20473
|
+
function isAsyncIterable5(obj) {
|
|
18143
20474
|
return typeof obj[Symbol.asyncIterator] === "function";
|
|
18144
20475
|
}
|
|
18145
20476
|
function wrapAsync(asyncFn) {
|
|
@@ -18189,7 +20520,7 @@ function _asyncMap(eachfn, arr, iteratee, callback) {
|
|
|
18189
20520
|
callback(err, results);
|
|
18190
20521
|
});
|
|
18191
20522
|
}
|
|
18192
|
-
function
|
|
20523
|
+
function isArrayLike4(value) {
|
|
18193
20524
|
return value && typeof value.length === "number" && value.length >= 0 && value.length % 1 === 0;
|
|
18194
20525
|
}
|
|
18195
20526
|
var breakLoop = {};
|
|
@@ -18237,7 +20568,7 @@ function createObjectIterator(obj) {
|
|
|
18237
20568
|
};
|
|
18238
20569
|
}
|
|
18239
20570
|
function createIterator(coll) {
|
|
18240
|
-
if (
|
|
20571
|
+
if (isArrayLike4(coll)) {
|
|
18241
20572
|
return createArrayIterator(coll);
|
|
18242
20573
|
}
|
|
18243
20574
|
var iterator = getIterator(coll);
|
|
@@ -18311,7 +20642,7 @@ var eachOfLimit$2 = (limit) => {
|
|
|
18311
20642
|
if (isAsyncGenerator2(obj)) {
|
|
18312
20643
|
return asyncEachOfLimit(obj, limit, iteratee, callback);
|
|
18313
20644
|
}
|
|
18314
|
-
if (
|
|
20645
|
+
if (isAsyncIterable5(obj)) {
|
|
18315
20646
|
return asyncEachOfLimit(obj[Symbol.asyncIterator](), limit, iteratee, callback);
|
|
18316
20647
|
}
|
|
18317
20648
|
var nextElem = createIterator(obj);
|
|
@@ -18383,7 +20714,7 @@ function eachOfGeneric(coll, iteratee, callback) {
|
|
|
18383
20714
|
return eachOfLimit$1(coll, Infinity, iteratee, callback);
|
|
18384
20715
|
}
|
|
18385
20716
|
function eachOf(coll, iteratee, callback) {
|
|
18386
|
-
var eachOfImplementation =
|
|
20717
|
+
var eachOfImplementation = isArrayLike4(coll) ? eachOfArrayLike : eachOfGeneric;
|
|
18387
20718
|
return eachOfImplementation(coll, wrapAsync(iteratee), callback);
|
|
18388
20719
|
}
|
|
18389
20720
|
var eachOf$1 = awaitify(eachOf, 3);
|
|
@@ -18898,7 +21229,7 @@ function filterGeneric(eachfn, coll, iteratee, callback) {
|
|
|
18898
21229
|
});
|
|
18899
21230
|
}
|
|
18900
21231
|
function _filter(eachfn, coll, iteratee, callback) {
|
|
18901
|
-
var filter2 =
|
|
21232
|
+
var filter2 = isArrayLike4(coll) ? filterArray : filterGeneric;
|
|
18902
21233
|
return filter2(eachfn, coll, wrapAsync(iteratee), callback);
|
|
18903
21234
|
}
|
|
18904
21235
|
function filter(coll, iteratee, callback) {
|
|
@@ -18973,7 +21304,7 @@ if (hasNextTick) {
|
|
|
18973
21304
|
}
|
|
18974
21305
|
var nextTick = wrap(_defer);
|
|
18975
21306
|
var _parallel = awaitify((eachfn, tasks, callback) => {
|
|
18976
|
-
var results =
|
|
21307
|
+
var results = isArrayLike4(tasks) ? [] : {};
|
|
18977
21308
|
eachfn(tasks, (task, key, taskCb) => {
|
|
18978
21309
|
wrapAsync(task)((err, ...result) => {
|
|
18979
21310
|
if (result.length < 2) {
|
|
@@ -19599,7 +21930,7 @@ function callEvaluatorData(data) {
|
|
|
19599
21930
|
baseExperiment
|
|
19600
21931
|
};
|
|
19601
21932
|
}
|
|
19602
|
-
function
|
|
21933
|
+
function isAsyncIterable6(value) {
|
|
19603
21934
|
return typeof value === "object" && value !== null && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
19604
21935
|
}
|
|
19605
21936
|
function isIterable(value) {
|
|
@@ -19823,7 +22154,7 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
|
|
|
19823
22154
|
}
|
|
19824
22155
|
const resolvedDataResult = dataResult instanceof Promise ? await dataResult : dataResult;
|
|
19825
22156
|
const dataIterable = (() => {
|
|
19826
|
-
if (
|
|
22157
|
+
if (isAsyncIterable6(resolvedDataResult)) {
|
|
19827
22158
|
return resolvedDataResult;
|
|
19828
22159
|
}
|
|
19829
22160
|
if (Array.isArray(resolvedDataResult) || isIterable(resolvedDataResult)) {
|
|
@@ -20882,7 +23213,7 @@ var parametersContainerSchema = import_v313.z.object({
|
|
|
20882
23213
|
var staticParametersContainerSchema = import_v313.z.object({
|
|
20883
23214
|
type: import_v313.z.literal("braintrust.staticParameters"),
|
|
20884
23215
|
schema: staticParametersSchema,
|
|
20885
|
-
source: import_v313.z.null()
|
|
23216
|
+
source: import_v313.z.null().nullish()
|
|
20886
23217
|
});
|
|
20887
23218
|
var serializedParametersContainerSchema = import_v313.z.union([
|
|
20888
23219
|
parametersContainerSchema,
|