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.
Files changed (53) hide show
  1. package/LICENSE +201 -0
  2. package/dev/dist/index.d.mts +144 -2
  3. package/dev/dist/index.d.ts +144 -2
  4. package/dev/dist/index.js +2432 -430
  5. package/dev/dist/index.mjs +2307 -305
  6. package/dist/auto-instrumentations/bundler/esbuild.cjs +377 -10
  7. package/dist/auto-instrumentations/bundler/esbuild.mjs +2 -2
  8. package/dist/auto-instrumentations/bundler/rollup.cjs +377 -10
  9. package/dist/auto-instrumentations/bundler/rollup.mjs +2 -2
  10. package/dist/auto-instrumentations/bundler/vite.cjs +377 -10
  11. package/dist/auto-instrumentations/bundler/vite.mjs +2 -2
  12. package/dist/auto-instrumentations/bundler/webpack-loader.cjs +377 -10
  13. package/dist/auto-instrumentations/bundler/webpack-loader.d.ts +11 -9
  14. package/dist/auto-instrumentations/bundler/webpack.cjs +377 -10
  15. package/dist/auto-instrumentations/bundler/webpack.mjs +2 -2
  16. package/dist/auto-instrumentations/{chunk-EVUKFMHG.mjs → chunk-ITP7RAUY.mjs} +21 -3
  17. package/dist/auto-instrumentations/{chunk-NY4CGTN6.mjs → chunk-MD7W27YH.mjs} +5 -1
  18. package/dist/auto-instrumentations/{chunk-YCKND42U.mjs → chunk-OLBMPZXE.mjs} +378 -11
  19. package/dist/auto-instrumentations/{chunk-VLEJ5AEK.mjs → chunk-P5YLNB2A.mjs} +21 -3
  20. package/dist/auto-instrumentations/hook.mjs +393 -16
  21. package/dist/auto-instrumentations/index.cjs +379 -10
  22. package/dist/auto-instrumentations/index.d.mts +5 -1
  23. package/dist/auto-instrumentations/index.d.ts +5 -1
  24. package/dist/auto-instrumentations/index.mjs +5 -1
  25. package/dist/auto-instrumentations/loader/cjs-patch.cjs +34 -6
  26. package/dist/auto-instrumentations/loader/cjs-patch.d.mts +1 -0
  27. package/dist/auto-instrumentations/loader/cjs-patch.d.ts +1 -0
  28. package/dist/auto-instrumentations/loader/cjs-patch.mjs +15 -5
  29. package/dist/auto-instrumentations/loader/esm-hook.mjs +8 -3
  30. package/dist/auto-instrumentations/loader/get-package-version.cjs +20 -2
  31. package/dist/auto-instrumentations/loader/get-package-version.mjs +1 -1
  32. package/dist/browser.d.mts +191 -14
  33. package/dist/browser.d.ts +191 -14
  34. package/dist/browser.js +2646 -315
  35. package/dist/browser.mjs +2646 -315
  36. package/dist/cli.js +2411 -409
  37. package/dist/edge-light.d.mts +1 -1
  38. package/dist/edge-light.d.ts +1 -1
  39. package/dist/edge-light.js +12604 -10184
  40. package/dist/edge-light.mjs +12604 -10184
  41. package/dist/index.d.mts +191 -14
  42. package/dist/index.d.ts +191 -14
  43. package/dist/index.js +2823 -492
  44. package/dist/index.mjs +2646 -315
  45. package/dist/instrumentation/index.d.mts +7 -0
  46. package/dist/instrumentation/index.d.ts +7 -0
  47. package/dist/instrumentation/index.js +2409 -407
  48. package/dist/instrumentation/index.mjs +2409 -407
  49. package/dist/workerd.d.mts +1 -1
  50. package/dist/workerd.d.ts +1 -1
  51. package/dist/workerd.js +12604 -10184
  52. package/dist/workerd.mjs +12604 -10184
  53. 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 currentSpanStore = state?.contextManager ? state.contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
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) => ensureSpanStateForEvent(
10102
- states,
10103
- config,
10104
- event,
10105
- channelName
10106
- ).span
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) => prepareAISDKInput(params, event, span, denyOutputPaths),
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) => prepareAISDKInput(params, event, span, denyOutputPaths),
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) => prepareAISDKInput(params, event, span, denyOutputPaths),
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) => prepareAISDKInput(params, event, span, denyOutputPaths),
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) => prepareAISDKInput(params, event, span, denyOutputPaths),
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) => prepareAISDKInput(params, event, span, denyOutputPaths),
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) => prepareAISDKInput(params, event, span, denyOutputPaths),
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) => prepareAISDKInput(params, event, span, denyOutputPaths),
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 processAISDKInput(params) {
12256
+ function processAISDKCallInput(params) {
12049
12257
  return processInputAttachmentsSync(params);
12050
12258
  }
12051
- function prepareAISDKInput(params, event, span, defaultDenyOutputPaths) {
12052
- const { input, outputPromise } = processAISDKInput(params);
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 = extractMetadataFromParams(params, event.self);
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 extractMetadataFromParams(params, self) {
12092
- const metadata = {
12305
+ function createAISDKIntegrationMetadata() {
12306
+ return {
12093
12307
  braintrust: {
12094
12308
  integration_name: "ai-sdk",
12095
12309
  sdk_language: "typescript"
12096
12310
  }
12097
12311
  };
12098
- const agentModel = 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;
12099
- const { model, provider } = serializeModelWithProvider(
12100
- params.model ?? agentModel
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 (model) {
12103
- metadata.model = 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: processAISDKInput(options).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: processAISDKInput(options).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-plugin.ts
12989
- function isSubAgentToolName(toolName) {
12990
- return toolName === "Agent" || toolName === "Task";
12991
- }
12992
- function filterSerializableOptions(options) {
12993
- const allowedKeys = [
12994
- "model",
12995
- "maxTurns",
12996
- "cwd",
12997
- "continue",
12998
- "allowedTools",
12999
- "disallowedTools",
13000
- "additionalDirectories",
13001
- "permissionMode",
13002
- "debug",
13003
- "apiKey",
13004
- "apiKeySource",
13005
- "agentName",
13006
- "instructions"
13007
- ];
13008
- const filtered = {};
13009
- for (const key of allowedKeys) {
13010
- if (options[key] !== void 0) {
13011
- filtered[key] = options[key];
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
- return filtered;
13303
+ const created = {};
13304
+ localToolContextStore.enterWith(created);
13305
+ return created;
13015
13306
  }
13016
- function getNumberProperty(obj, key) {
13017
- if (!obj || typeof obj !== "object" || !(key in obj)) {
13018
- return void 0;
13307
+ function setClaudeLocalToolParentResolver(resolver) {
13308
+ fallbackLocalToolParentResolver = resolver;
13309
+ const context = ensureClaudeLocalToolContext();
13310
+ if (!context) {
13311
+ return;
13019
13312
  }
13020
- const value = Reflect.get(obj, key);
13021
- return typeof value === "number" ? value : void 0;
13313
+ context.resolveLocalToolParent = resolver;
13022
13314
  }
13023
- function extractUsageFromMessage(message) {
13024
- const metrics = {};
13025
- let usage;
13026
- if (message.type === "assistant") {
13027
- usage = message.message?.usage;
13028
- } else if (message.type === "result") {
13029
- usage = message.usage;
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
- if (!usage || typeof usage !== "object") {
13032
- return metrics;
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 inputTokens = getNumberProperty(usage, "input_tokens");
13035
- if (inputTokens !== void 0) {
13036
- metrics.prompt_tokens = inputTokens;
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 outputTokens = getNumberProperty(usage, "output_tokens");
13039
- if (outputTokens !== void 0) {
13040
- metrics.completion_tokens = outputTokens;
13388
+ const meta = Reflect.get(extra, "_meta");
13389
+ if (!meta || typeof meta !== "object") {
13390
+ return void 0;
13041
13391
  }
13042
- const cacheReadTokens = getNumberProperty(usage, "cache_read_input_tokens") || 0;
13043
- const cacheCreationTokens = getNumberProperty(usage, "cache_creation_input_tokens") || 0;
13044
- if (cacheReadTokens > 0 || cacheCreationTokens > 0) {
13045
- Object.assign(
13046
- metrics,
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
- return lastMessage.message?.content && lastMessage.message?.role ? { content: lastMessage.message.content, role: lastMessage.message.role } : void 0;
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 createToolTracingHooks(resolveParentSpan, activeToolSpans, mcpServers, subAgentSpans, endedSubAgentSpans) {
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 finalMessage = await createLLMSpanForMessages(
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
- if (finalMessage) {
13312
- state.finalResults.push(finalMessage);
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
- async (toolUseID) => {
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
- toolUseToParent
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 = event.result;
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 = state?.contextManager ? state.contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
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
- currentSpanStore,
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 openRouterChannels = defineChannels("@openrouter/sdk", {
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 OpenRouterPlugin = class extends BasePlugin {
14878
+ // src/instrumentation/plugins/openrouter-agent-plugin.ts
14879
+ var OpenRouterAgentPlugin = class extends BasePlugin {
14197
14880
  onEnable() {
14198
- this.subscribeToOpenRouterChannels();
14881
+ this.subscribeToOpenRouterAgentChannels();
14199
14882
  }
14200
14883
  onDisable() {
14201
14884
  this.unsubscribers = unsubscribeAll(this.unsubscribers);
14202
14885
  }
14203
- subscribeToOpenRouterChannels() {
14886
+ subscribeToOpenRouterAgentChannels() {
14204
14887
  this.unsubscribers.push(
14205
- traceStreamingChannel(openRouterChannels.chatSend, {
14206
- name: "openrouter.chat.send",
14888
+ traceSyncStreamChannel(openRouterAgentChannels.callModel, {
14889
+ name: "openrouter.callModel",
14207
14890
  type: "llm" /* LLM */,
14208
14891
  extractInput: (args) => {
14209
- const request = getOpenRouterRequestArg(args);
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: messages,
14216
- metadata: buildOpenRouterMetadata(metadata, httpReferer, xTitle)
14894
+ input: request ? extractOpenRouterCallModelInput(request) : void 0,
14895
+ metadata: request ? extractOpenRouterCallModelMetadata(request) : { provider: "openrouter" }
14217
14896
  };
14218
14897
  },
14219
- extractOutput: (result) => {
14220
- return isObject(result) ? result.choices : void 0;
14221
- },
14222
- extractMetrics: (result, startTime) => {
14223
- const metrics = parseOpenRouterMetricsFromUsage(result?.usage);
14224
- if (startTime) {
14225
- metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
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(openRouterChannels.embeddingsGenerate, {
14234
- name: "openrouter.embeddings.generate",
14908
+ traceAsyncChannel(openRouterAgentChannels.callModelTurn, {
14909
+ name: "openrouter.beta.responses.send",
14235
14910
  type: "llm" /* LLM */,
14236
- extractInput: (args) => {
14237
- const request = getOpenRouterRequestArg(args);
14238
- const requestBody = isObject(request?.requestBody) ? request.requestBody : {};
14239
- const httpReferer = request?.httpReferer;
14240
- const xTitle = request?.xTitle;
14241
- const { input, ...metadata } = requestBody;
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: buildOpenRouterEmbeddingMetadata(
14245
- metadata,
14246
- httpReferer,
14247
- xTitle
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 void 0;
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 extractOpenRouterResponseMetadata(result);
15742
+ return extractOpenRouterResponseMetadata2(result);
14263
15743
  },
14264
15744
  extractMetrics: (result) => {
14265
- return isObject(result) ? parseOpenRouterMetricsFromUsage(result.usage) : {};
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: buildOpenRouterMetadata(metadata, httpReferer, xTitle)
15761
+ metadata: buildOpenRouterMetadata2(metadata, httpReferer, xTitle)
14282
15762
  };
14283
15763
  },
14284
- extractOutput: (result) => extractOpenRouterResponseOutput(result),
14285
- extractMetadata: (result) => extractOpenRouterResponseMetadata(result),
15764
+ extractOutput: (result) => extractOpenRouterResponseOutput2(result),
15765
+ extractMetadata: (result) => extractOpenRouterResponseMetadata2(result),
14286
15766
  extractMetrics: (result, startTime) => {
14287
- const metrics = parseOpenRouterMetricsFromUsage(result?.usage);
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 = getOpenRouterCallModelRequestArg(args);
15781
+ const request = getOpenRouterCallModelRequestArg2(args);
14302
15782
  return {
14303
- input: request ? extractOpenRouterCallModelInput(request) : void 0,
14304
- metadata: request ? extractOpenRouterCallModelMetadata(request) : { provider: "openrouter" }
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 patchOpenRouterCallModelResult({
14309
- request: getOpenRouterCallModelRequestArg(endEvent.arguments),
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 = getOpenRouterCallModelRequestArg(args);
14322
- const metadata = request ? extractOpenRouterCallModelMetadata(request) : { provider: "openrouter" };
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 ? extractOpenRouterCallModelInput(request) : void 0,
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) => extractOpenRouterResponseOutput(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
- ...extractOpenRouterResponseMetadata(result) || {},
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) ? parseOpenRouterMetricsFromUsage(result.usage) : {}
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 = getOpenRouterCallModelRequestArg(event.arguments);
15855
+ const request = getOpenRouterCallModelRequestArg2(event.arguments);
14376
15856
  if (!request) {
14377
15857
  return;
14378
15858
  }
14379
- patchOpenRouterCallModelRequestTools(request);
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 normalizeArgs(args) {
15868
+ function normalizeArgs2(args) {
14389
15869
  if (Array.isArray(args)) {
14390
15870
  return args;
14391
15871
  }
14392
- if (isArrayLike(args)) {
15872
+ if (isArrayLike2(args)) {
14393
15873
  return Array.from(args);
14394
15874
  }
14395
15875
  return [args];
14396
15876
  }
14397
- function isArrayLike(value) {
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 = normalizeArgs(args);
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 getOpenRouterCallModelRequestArg(args) {
14412
- const firstObjectArg = normalizeArgs(args).find((arg) => isObject(arg));
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 TOKEN_NAME_MAP2 = {
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 TOKEN_DETAIL_PREFIX_MAP = {
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 camelToSnake(value) {
15919
+ function camelToSnake2(value) {
14440
15920
  return value.replace(/[A-Z]/g, (match) => `_${match.toLowerCase()}`);
14441
15921
  }
14442
- function parseOpenRouterMetricsFromUsage(usage) {
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[TOKEN_NAME_MAP2[name] || camelToSnake(name)] = value;
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 = TOKEN_DETAIL_PREFIX_MAP[name];
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}_${camelToSnake(nestedName)}`] = nestedValue;
15943
+ metrics[`${prefix}_${camelToSnake2(nestedName)}`] = nestedValue;
14464
15944
  }
14465
15945
  }
14466
15946
  return metrics;
14467
15947
  }
14468
- function extractOpenRouterUsageMetadata(usage) {
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 OMITTED_OPENROUTER_KEYS = /* @__PURE__ */ new Set([
15960
+ var OMITTED_OPENROUTER_KEYS2 = /* @__PURE__ */ new Set([
14481
15961
  "execute",
14482
15962
  "render",
14483
15963
  "nextTurnParams",
14484
15964
  "requireApproval"
14485
15965
  ]);
14486
- function parseOpenRouterModelString(model) {
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 isZodSchema3(value) {
15979
+ function isZodSchema4(value) {
14500
15980
  return value != null && typeof value === "object" && "_def" in value && typeof value._def === "object";
14501
15981
  }
14502
- function serializeZodSchema3(schema) {
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 serializeOpenRouterTool(tool) {
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 (OMITTED_OPENROUTER_KEYS.has(key)) {
15998
+ if (OMITTED_OPENROUTER_KEYS2.has(key)) {
14519
15999
  continue;
14520
16000
  }
14521
16001
  if (key === "function" && isObject(value)) {
14522
- serialized.function = sanitizeOpenRouterLoggedValue(value);
16002
+ serialized.function = sanitizeOpenRouterLoggedValue2(value);
14523
16003
  continue;
14524
16004
  }
14525
- serialized[key] = sanitizeOpenRouterLoggedValue(value);
16005
+ serialized[key] = sanitizeOpenRouterLoggedValue2(value);
14526
16006
  }
14527
16007
  return serialized;
14528
16008
  }
14529
- function serializeOpenRouterToolsForLogging(tools) {
16009
+ function serializeOpenRouterToolsForLogging2(tools) {
14530
16010
  if (!Array.isArray(tools)) {
14531
16011
  return void 0;
14532
16012
  }
14533
- return tools.map((tool) => serializeOpenRouterTool(tool));
16013
+ return tools.map((tool) => serializeOpenRouterTool2(tool));
14534
16014
  }
14535
- function sanitizeOpenRouterLoggedValue(value) {
14536
- if (isZodSchema3(value)) {
14537
- return serializeZodSchema3(value);
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) => sanitizeOpenRouterLoggedValue(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 (OMITTED_OPENROUTER_KEYS.has(key)) {
16030
+ if (OMITTED_OPENROUTER_KEYS2.has(key)) {
14551
16031
  continue;
14552
16032
  }
14553
16033
  if (key === "tools" && Array.isArray(entry)) {
14554
- sanitized.tools = serializeOpenRouterToolsForLogging(entry);
16034
+ sanitized.tools = serializeOpenRouterToolsForLogging2(entry);
14555
16035
  continue;
14556
16036
  }
14557
- sanitized[key] = sanitizeOpenRouterLoggedValue(entry);
16037
+ sanitized[key] = sanitizeOpenRouterLoggedValue2(entry);
14558
16038
  }
14559
16039
  return sanitized;
14560
16040
  }
14561
- function buildOpenRouterMetadata(metadata, httpReferer, xTitle) {
14562
- const sanitized = sanitizeOpenRouterLoggedValue(metadata);
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 = parseOpenRouterModelString(model);
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 = buildOpenRouterMetadata(metadata, httpReferer, xTitle);
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 extractOpenRouterCallModelInput(request) {
14583
- return isObject(request) && "input" in request ? sanitizeOpenRouterLoggedValue(request.input) : void 0;
16062
+ function extractOpenRouterCallModelInput2(request) {
16063
+ return isObject(request) && "input" in request ? sanitizeOpenRouterLoggedValue2(request.input) : void 0;
14584
16064
  }
14585
- function extractOpenRouterCallModelMetadata(request) {
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 buildOpenRouterMetadata(metadata, void 0, void 0);
16070
+ return buildOpenRouterMetadata2(metadata, void 0, void 0);
14591
16071
  }
14592
- function extractOpenRouterResponseMetadata(result) {
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 = sanitizeOpenRouterLoggedValue(metadata);
16077
+ const sanitized = sanitizeOpenRouterLoggedValue2(metadata);
14598
16078
  const metadataRecord = isObject(sanitized) ? sanitized : {};
14599
16079
  const { model, provider, ...rest } = metadataRecord;
14600
- const normalizedModel = parseOpenRouterModelString(model);
16080
+ const normalizedModel = parseOpenRouterModelString2(model);
14601
16081
  const normalizedProvider = (typeof provider === "string" ? provider : void 0) || normalizedModel.provider;
14602
- const usageMetadata = extractOpenRouterUsageMetadata(usage);
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 extractOpenRouterResponseOutput(response, fallbackOutput) {
16091
+ function extractOpenRouterResponseOutput2(response, fallbackOutput) {
14612
16092
  if (isObject(response) && "output" in response && response.output !== void 0) {
14613
- return sanitizeOpenRouterLoggedValue(response.output);
16093
+ return sanitizeOpenRouterLoggedValue2(response.output);
14614
16094
  }
14615
16095
  if (fallbackOutput !== void 0) {
14616
- return sanitizeOpenRouterLoggedValue(fallbackOutput);
16096
+ return sanitizeOpenRouterLoggedValue2(fallbackOutput);
14617
16097
  }
14618
16098
  return void 0;
14619
16099
  }
14620
- var OPENROUTER_WRAPPED_TOOL = Symbol("braintrust.openrouter.wrappedTool");
14621
- function patchOpenRouterCallModelRequestTools(request) {
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) => wrapOpenRouterTool(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 wrapOpenRouterTool(tool) {
14639
- if (isWrappedTool(tool) || !tool.function || typeof tool.function !== "object" || typeof tool.function.execute !== "function") {
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 traceToolExecution({
16129
+ return traceToolExecution2({
14650
16130
  args,
14651
16131
  execute: () => Reflect.apply(originalExecute, this, args),
14652
- toolCallId: getToolCallId(args[1]),
16132
+ toolCallId: getToolCallId2(args[1]),
14653
16133
  toolName
14654
16134
  });
14655
16135
  }
14656
16136
  }
14657
16137
  };
14658
- Object.defineProperty(wrappedTool, OPENROUTER_WRAPPED_TOOL, {
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 isWrappedTool(tool) {
14666
- return Boolean(tool[OPENROUTER_WRAPPED_TOOL]);
16145
+ function isWrappedTool2(tool) {
16146
+ return Boolean(tool[OPENROUTER_WRAPPED_TOOL2]);
14667
16147
  }
14668
- function traceToolExecution(args) {
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 publishToolResult(tracingChannel2, event, result);
16162
+ return publishToolResult2(tracingChannel2, event, result);
14683
16163
  } catch (error) {
14684
- event.error = normalizeError(error);
16164
+ event.error = normalizeError2(error);
14685
16165
  tracingChannel2.error.publish(event);
14686
16166
  throw error;
14687
16167
  }
14688
16168
  }
14689
- function publishToolResult(tracingChannel2, event, result) {
14690
- if (isPromiseLike2(result)) {
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 = normalizeError(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 getToolCallId(context) {
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 isPromiseLike2(value) {
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
- ...parseOpenRouterMetricsFromUsage(chunk?.usage)
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: extractOpenRouterResponseOutput(finalResponse),
14819
- metrics: parseOpenRouterMetricsFromUsage(finalResponse.usage),
14820
- ...extractOpenRouterResponseMetadata(finalResponse) ? { metadata: extractOpenRouterResponseMetadata(finalResponse) } : {}
16298
+ output: extractOpenRouterResponseOutput2(finalResponse),
16299
+ metrics: parseOpenRouterMetricsFromUsage2(finalResponse.usage),
16300
+ ...extractOpenRouterResponseMetadata2(finalResponse) ? { metadata: extractOpenRouterResponseMetadata2(finalResponse) } : {}
14821
16301
  };
14822
16302
  }
14823
- var OPENROUTER_WRAPPED_CALL_MODEL_RESULT = Symbol(
16303
+ var OPENROUTER_WRAPPED_CALL_MODEL_RESULT2 = Symbol(
14824
16304
  "braintrust.openrouter.wrappedCallModelResult"
14825
16305
  );
14826
- var OPENROUTER_CALL_MODEL_STREAM_METHODS = [
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 OPENROUTER_CALL_MODEL_CONTEXT_METHODS = [
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 patchOpenRouterCallModelResult(args) {
16322
+ function patchOpenRouterCallModelResult2(args) {
14843
16323
  const { request, result, span } = args;
14844
- if (!isObject(result) || isWrappedCallModelResult(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" || OPENROUTER_CALL_MODEL_STREAM_METHODS.some(
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, OPENROUTER_WRAPPED_CALL_MODEL_RESULT, {
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 = getFinalOpenRouterCallModelResponse(
16349
+ const finalResponse = getFinalOpenRouterCallModelResponse2(
14870
16350
  resultLike,
14871
16351
  response
14872
16352
  );
14873
16353
  if (finalResponse) {
14874
- const rounds = getOpenRouterCallModelRounds(resultLike);
14875
- const metadata = extractOpenRouterCallModelResultMetadata(
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: extractOpenRouterResponseOutput(finalResponse, fallbackOutput),
16360
+ output: extractOpenRouterResponseOutput2(finalResponse, fallbackOutput),
14881
16361
  ...metadata ? { metadata } : {},
14882
- metrics: aggregateOpenRouterCallModelMetrics(rounds, finalResponse)
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: normalizeError(error).message
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 OPENROUTER_CALL_MODEL_CONTEXT_METHODS) {
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 OPENROUTER_CALL_MODEL_STREAM_METHODS) {
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 (!isAsyncIterable2(stream)) {
16445
+ if (!isAsyncIterable4(stream)) {
14966
16446
  return stream;
14967
16447
  }
14968
- return wrapAsyncIterableWithSpan({
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 traceOpenRouterCallModelTurn({
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: getOpenRouterResolvedRequest(resultLike, 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 traceOpenRouterCallModelTurn({
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: buildOpenRouterFollowupRequest(
15014
- getOpenRouterResolvedRequest(resultLike, request),
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 traceOpenRouterCallModelTurn(args) {
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 isWrappedCallModelResult(value) {
16517
+ function isWrappedCallModelResult2(value) {
15038
16518
  return Boolean(
15039
- isObject(value) && value[OPENROUTER_WRAPPED_CALL_MODEL_RESULT]
16519
+ isObject(value) && value[OPENROUTER_WRAPPED_CALL_MODEL_RESULT2]
15040
16520
  );
15041
16521
  }
15042
- function extractOpenRouterCallModelResultMetadata(response, turnCount) {
16522
+ function extractOpenRouterCallModelResultMetadata2(response, turnCount) {
15043
16523
  const combined = {
15044
- ...extractOpenRouterResponseMetadata(response) || {},
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 getFinalOpenRouterCallModelResponse(result, response) {
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 getOpenRouterCallModelRounds(result) {
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 aggregateOpenRouterCallModelMetrics(rounds, finalResponse) {
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 = parseOpenRouterMetricsFromUsage(response.usage);
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 buildNextOpenRouterCallModelInput(currentInput, response, toolResults) {
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) => sanitizeOpenRouterLoggedValue(entry)
16563
+ (entry) => sanitizeOpenRouterLoggedValue2(entry)
15084
16564
  );
15085
16565
  }
15086
- function getOpenRouterResolvedRequest(result, request) {
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 buildOpenRouterFollowupRequest(request, currentResponse, toolResults) {
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: buildNextOpenRouterCallModelInput(
15099
- extractOpenRouterCallModelInput(request),
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 wrapAsyncIterableWithSpan(args) {
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 isAsyncIterable2(value) {
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 normalizeError(error) {
15164
- return error instanceof Error ? error : new Error(String(error));
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 chatProxy2 = new Proxy(typedOpenai.chat, {
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 chatProxy2;
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 camelToSnake2(str) {
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 = camelToSnake2(key);
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
- // Async iterator shenanigans are handled purely in the plugin which consumes this channel emission.
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: [params] }
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" ? wrapCallModel(target.callModel.bind(target)) : target.callModel;
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 wrapCallModel(callModel) {
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 isAsyncIterable3(obj) {
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 isArrayLike2(value) {
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 (isArrayLike2(coll)) {
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 (isAsyncIterable3(obj)) {
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 = isArrayLike2(coll) ? eachOfArrayLike : eachOfGeneric;
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 = isArrayLike2(coll) ? filterArray : filterGeneric;
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 = isArrayLike2(tasks) ? [] : {};
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 isAsyncIterable4(value) {
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 (isAsyncIterable4(resolvedDataResult)) {
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,