braintrust 3.4.0 → 3.6.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 (58) hide show
  1. package/dev/dist/index.d.mts +49 -7
  2. package/dev/dist/index.d.ts +49 -7
  3. package/dev/dist/index.js +2383 -494
  4. package/dev/dist/index.mjs +2213 -324
  5. package/dist/auto-instrumentations/bundler/esbuild.cjs +289 -10
  6. package/dist/auto-instrumentations/bundler/esbuild.d.mts +2 -2
  7. package/dist/auto-instrumentations/bundler/esbuild.d.ts +2 -2
  8. package/dist/auto-instrumentations/bundler/esbuild.mjs +2 -2
  9. package/dist/auto-instrumentations/bundler/rollup.cjs +289 -10
  10. package/dist/auto-instrumentations/bundler/rollup.mjs +2 -2
  11. package/dist/auto-instrumentations/bundler/vite.cjs +289 -10
  12. package/dist/auto-instrumentations/bundler/vite.d.mts +2 -2
  13. package/dist/auto-instrumentations/bundler/vite.d.ts +2 -2
  14. package/dist/auto-instrumentations/bundler/vite.mjs +2 -2
  15. package/dist/auto-instrumentations/bundler/webpack.cjs +289 -10
  16. package/dist/auto-instrumentations/bundler/webpack.d.mts +2 -2
  17. package/dist/auto-instrumentations/bundler/webpack.d.ts +2 -2
  18. package/dist/auto-instrumentations/bundler/webpack.mjs +2 -2
  19. package/dist/auto-instrumentations/chunk-EVUKFMHG.mjs +41 -0
  20. package/dist/auto-instrumentations/{chunk-LVWWLUMN.mjs → chunk-F7WAXFNM.mjs} +290 -11
  21. package/dist/auto-instrumentations/chunk-VLEJ5AEK.mjs +41 -0
  22. package/dist/auto-instrumentations/{chunk-D5ZPIUEL.mjs → chunk-WOUC73KB.mjs} +3 -1
  23. package/dist/auto-instrumentations/hook.mjs +358 -48
  24. package/dist/auto-instrumentations/index.cjs +290 -10
  25. package/dist/auto-instrumentations/index.d.mts +3 -1
  26. package/dist/auto-instrumentations/index.d.ts +3 -1
  27. package/dist/auto-instrumentations/index.mjs +3 -1
  28. package/dist/auto-instrumentations/loader/cjs-patch.cjs +32 -10
  29. package/dist/auto-instrumentations/loader/cjs-patch.mjs +10 -5
  30. package/dist/auto-instrumentations/loader/esm-hook.mjs +4 -4
  31. package/dist/auto-instrumentations/loader/get-package-version.cjs +28 -8
  32. package/dist/auto-instrumentations/loader/get-package-version.d.mts +2 -1
  33. package/dist/auto-instrumentations/loader/get-package-version.d.ts +2 -1
  34. package/dist/auto-instrumentations/loader/get-package-version.mjs +3 -1
  35. package/dist/browser.d.mts +357 -271
  36. package/dist/browser.d.ts +357 -271
  37. package/dist/browser.js +2345 -343
  38. package/dist/browser.mjs +2345 -343
  39. package/dist/cli.js +2296 -414
  40. package/dist/edge-light.d.mts +1 -1
  41. package/dist/edge-light.d.ts +1 -1
  42. package/dist/edge-light.js +2292 -315
  43. package/dist/edge-light.mjs +2292 -315
  44. package/dist/index.d.mts +370 -284
  45. package/dist/index.d.ts +370 -284
  46. package/dist/index.js +2642 -638
  47. package/dist/index.mjs +2385 -381
  48. package/dist/instrumentation/index.d.mts +3 -0
  49. package/dist/instrumentation/index.d.ts +3 -0
  50. package/dist/instrumentation/index.js +1955 -198
  51. package/dist/instrumentation/index.mjs +1955 -198
  52. package/dist/workerd.d.mts +1 -1
  53. package/dist/workerd.d.ts +1 -1
  54. package/dist/workerd.js +2292 -315
  55. package/dist/workerd.mjs +2292 -315
  56. package/package.json +22 -6
  57. package/dist/auto-instrumentations/chunk-XDBPUTVE.mjs +0 -22
  58. package/dist/auto-instrumentations/chunk-ZEC7BCL4.mjs +0 -22
package/dist/cli.js CHANGED
@@ -31,9 +31,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
31
31
  ));
32
32
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
33
33
 
34
- // ../node_modules/@nodelib/fs.stat/out/providers/async.js
34
+ // ../node_modules/.pnpm/@nodelib+fs.stat@2.0.5/node_modules/@nodelib/fs.stat/out/providers/async.js
35
35
  var require_async = __commonJS({
36
- "../node_modules/@nodelib/fs.stat/out/providers/async.js"(exports2) {
36
+ "../node_modules/.pnpm/@nodelib+fs.stat@2.0.5/node_modules/@nodelib/fs.stat/out/providers/async.js"(exports2) {
37
37
  "use strict";
38
38
  Object.defineProperty(exports2, "__esModule", { value: true });
39
39
  exports2.read = void 0;
@@ -73,9 +73,9 @@ var require_async = __commonJS({
73
73
  }
74
74
  });
75
75
 
76
- // ../node_modules/@nodelib/fs.stat/out/providers/sync.js
76
+ // ../node_modules/.pnpm/@nodelib+fs.stat@2.0.5/node_modules/@nodelib/fs.stat/out/providers/sync.js
77
77
  var require_sync = __commonJS({
78
- "../node_modules/@nodelib/fs.stat/out/providers/sync.js"(exports2) {
78
+ "../node_modules/.pnpm/@nodelib+fs.stat@2.0.5/node_modules/@nodelib/fs.stat/out/providers/sync.js"(exports2) {
79
79
  "use strict";
80
80
  Object.defineProperty(exports2, "__esModule", { value: true });
81
81
  exports2.read = void 0;
@@ -101,9 +101,9 @@ var require_sync = __commonJS({
101
101
  }
102
102
  });
103
103
 
104
- // ../node_modules/@nodelib/fs.stat/out/adapters/fs.js
104
+ // ../node_modules/.pnpm/@nodelib+fs.stat@2.0.5/node_modules/@nodelib/fs.stat/out/adapters/fs.js
105
105
  var require_fs = __commonJS({
106
- "../node_modules/@nodelib/fs.stat/out/adapters/fs.js"(exports2) {
106
+ "../node_modules/.pnpm/@nodelib+fs.stat@2.0.5/node_modules/@nodelib/fs.stat/out/adapters/fs.js"(exports2) {
107
107
  "use strict";
108
108
  Object.defineProperty(exports2, "__esModule", { value: true });
109
109
  exports2.createFileSystemAdapter = exports2.FILE_SYSTEM_ADAPTER = void 0;
@@ -124,9 +124,9 @@ var require_fs = __commonJS({
124
124
  }
125
125
  });
126
126
 
127
- // ../node_modules/@nodelib/fs.stat/out/settings.js
127
+ // ../node_modules/.pnpm/@nodelib+fs.stat@2.0.5/node_modules/@nodelib/fs.stat/out/settings.js
128
128
  var require_settings = __commonJS({
129
- "../node_modules/@nodelib/fs.stat/out/settings.js"(exports2) {
129
+ "../node_modules/.pnpm/@nodelib+fs.stat@2.0.5/node_modules/@nodelib/fs.stat/out/settings.js"(exports2) {
130
130
  "use strict";
131
131
  Object.defineProperty(exports2, "__esModule", { value: true });
132
132
  var fs6 = require_fs();
@@ -146,9 +146,9 @@ var require_settings = __commonJS({
146
146
  }
147
147
  });
148
148
 
149
- // ../node_modules/@nodelib/fs.stat/out/index.js
149
+ // ../node_modules/.pnpm/@nodelib+fs.stat@2.0.5/node_modules/@nodelib/fs.stat/out/index.js
150
150
  var require_out = __commonJS({
151
- "../node_modules/@nodelib/fs.stat/out/index.js"(exports2) {
151
+ "../node_modules/.pnpm/@nodelib+fs.stat@2.0.5/node_modules/@nodelib/fs.stat/out/index.js"(exports2) {
152
152
  "use strict";
153
153
  Object.defineProperty(exports2, "__esModule", { value: true });
154
154
  exports2.statSync = exports2.stat = exports2.Settings = void 0;
@@ -178,9 +178,9 @@ var require_out = __commonJS({
178
178
  }
179
179
  });
180
180
 
181
- // ../node_modules/queue-microtask/index.js
181
+ // ../node_modules/.pnpm/queue-microtask@1.2.3/node_modules/queue-microtask/index.js
182
182
  var require_queue_microtask = __commonJS({
183
- "../node_modules/queue-microtask/index.js"(exports2, module2) {
183
+ "../node_modules/.pnpm/queue-microtask@1.2.3/node_modules/queue-microtask/index.js"(exports2, module2) {
184
184
  "use strict";
185
185
  var promise;
186
186
  module2.exports = typeof queueMicrotask === "function" ? queueMicrotask.bind(typeof window !== "undefined" ? window : global) : (cb) => (promise || (promise = Promise.resolve())).then(cb).catch((err) => setTimeout(() => {
@@ -189,9 +189,9 @@ var require_queue_microtask = __commonJS({
189
189
  }
190
190
  });
191
191
 
192
- // ../node_modules/run-parallel/index.js
192
+ // ../node_modules/.pnpm/run-parallel@1.2.0/node_modules/run-parallel/index.js
193
193
  var require_run_parallel = __commonJS({
194
- "../node_modules/run-parallel/index.js"(exports2, module2) {
194
+ "../node_modules/.pnpm/run-parallel@1.2.0/node_modules/run-parallel/index.js"(exports2, module2) {
195
195
  "use strict";
196
196
  module2.exports = runParallel;
197
197
  var queueMicrotask2 = require_queue_microtask();
@@ -240,9 +240,9 @@ var require_run_parallel = __commonJS({
240
240
  }
241
241
  });
242
242
 
243
- // ../node_modules/@nodelib/fs.scandir/out/constants.js
243
+ // ../node_modules/.pnpm/@nodelib+fs.scandir@2.1.5/node_modules/@nodelib/fs.scandir/out/constants.js
244
244
  var require_constants = __commonJS({
245
- "../node_modules/@nodelib/fs.scandir/out/constants.js"(exports2) {
245
+ "../node_modules/.pnpm/@nodelib+fs.scandir@2.1.5/node_modules/@nodelib/fs.scandir/out/constants.js"(exports2) {
246
246
  "use strict";
247
247
  Object.defineProperty(exports2, "__esModule", { value: true });
248
248
  exports2.IS_SUPPORT_READDIR_WITH_FILE_TYPES = void 0;
@@ -260,9 +260,9 @@ var require_constants = __commonJS({
260
260
  }
261
261
  });
262
262
 
263
- // ../node_modules/@nodelib/fs.scandir/out/utils/fs.js
263
+ // ../node_modules/.pnpm/@nodelib+fs.scandir@2.1.5/node_modules/@nodelib/fs.scandir/out/utils/fs.js
264
264
  var require_fs2 = __commonJS({
265
- "../node_modules/@nodelib/fs.scandir/out/utils/fs.js"(exports2) {
265
+ "../node_modules/.pnpm/@nodelib+fs.scandir@2.1.5/node_modules/@nodelib/fs.scandir/out/utils/fs.js"(exports2) {
266
266
  "use strict";
267
267
  Object.defineProperty(exports2, "__esModule", { value: true });
268
268
  exports2.createDirentFromStats = void 0;
@@ -285,9 +285,9 @@ var require_fs2 = __commonJS({
285
285
  }
286
286
  });
287
287
 
288
- // ../node_modules/@nodelib/fs.scandir/out/utils/index.js
288
+ // ../node_modules/.pnpm/@nodelib+fs.scandir@2.1.5/node_modules/@nodelib/fs.scandir/out/utils/index.js
289
289
  var require_utils = __commonJS({
290
- "../node_modules/@nodelib/fs.scandir/out/utils/index.js"(exports2) {
290
+ "../node_modules/.pnpm/@nodelib+fs.scandir@2.1.5/node_modules/@nodelib/fs.scandir/out/utils/index.js"(exports2) {
291
291
  "use strict";
292
292
  Object.defineProperty(exports2, "__esModule", { value: true });
293
293
  exports2.fs = void 0;
@@ -296,9 +296,9 @@ var require_utils = __commonJS({
296
296
  }
297
297
  });
298
298
 
299
- // ../node_modules/@nodelib/fs.scandir/out/providers/common.js
299
+ // ../node_modules/.pnpm/@nodelib+fs.scandir@2.1.5/node_modules/@nodelib/fs.scandir/out/providers/common.js
300
300
  var require_common = __commonJS({
301
- "../node_modules/@nodelib/fs.scandir/out/providers/common.js"(exports2) {
301
+ "../node_modules/.pnpm/@nodelib+fs.scandir@2.1.5/node_modules/@nodelib/fs.scandir/out/providers/common.js"(exports2) {
302
302
  "use strict";
303
303
  Object.defineProperty(exports2, "__esModule", { value: true });
304
304
  exports2.joinPathSegments = void 0;
@@ -312,9 +312,9 @@ var require_common = __commonJS({
312
312
  }
313
313
  });
314
314
 
315
- // ../node_modules/@nodelib/fs.scandir/out/providers/async.js
315
+ // ../node_modules/.pnpm/@nodelib+fs.scandir@2.1.5/node_modules/@nodelib/fs.scandir/out/providers/async.js
316
316
  var require_async2 = __commonJS({
317
- "../node_modules/@nodelib/fs.scandir/out/providers/async.js"(exports2) {
317
+ "../node_modules/.pnpm/@nodelib+fs.scandir@2.1.5/node_modules/@nodelib/fs.scandir/out/providers/async.js"(exports2) {
318
318
  "use strict";
319
319
  Object.defineProperty(exports2, "__esModule", { value: true });
320
320
  exports2.readdir = exports2.readdirWithFileTypes = exports2.read = void 0;
@@ -422,9 +422,9 @@ var require_async2 = __commonJS({
422
422
  }
423
423
  });
424
424
 
425
- // ../node_modules/@nodelib/fs.scandir/out/providers/sync.js
425
+ // ../node_modules/.pnpm/@nodelib+fs.scandir@2.1.5/node_modules/@nodelib/fs.scandir/out/providers/sync.js
426
426
  var require_sync2 = __commonJS({
427
- "../node_modules/@nodelib/fs.scandir/out/providers/sync.js"(exports2) {
427
+ "../node_modules/.pnpm/@nodelib+fs.scandir@2.1.5/node_modules/@nodelib/fs.scandir/out/providers/sync.js"(exports2) {
428
428
  "use strict";
429
429
  Object.defineProperty(exports2, "__esModule", { value: true });
430
430
  exports2.readdir = exports2.readdirWithFileTypes = exports2.read = void 0;
@@ -481,9 +481,9 @@ var require_sync2 = __commonJS({
481
481
  }
482
482
  });
483
483
 
484
- // ../node_modules/@nodelib/fs.scandir/out/adapters/fs.js
484
+ // ../node_modules/.pnpm/@nodelib+fs.scandir@2.1.5/node_modules/@nodelib/fs.scandir/out/adapters/fs.js
485
485
  var require_fs3 = __commonJS({
486
- "../node_modules/@nodelib/fs.scandir/out/adapters/fs.js"(exports2) {
486
+ "../node_modules/.pnpm/@nodelib+fs.scandir@2.1.5/node_modules/@nodelib/fs.scandir/out/adapters/fs.js"(exports2) {
487
487
  "use strict";
488
488
  Object.defineProperty(exports2, "__esModule", { value: true });
489
489
  exports2.createFileSystemAdapter = exports2.FILE_SYSTEM_ADAPTER = void 0;
@@ -506,9 +506,9 @@ var require_fs3 = __commonJS({
506
506
  }
507
507
  });
508
508
 
509
- // ../node_modules/@nodelib/fs.scandir/out/settings.js
509
+ // ../node_modules/.pnpm/@nodelib+fs.scandir@2.1.5/node_modules/@nodelib/fs.scandir/out/settings.js
510
510
  var require_settings2 = __commonJS({
511
- "../node_modules/@nodelib/fs.scandir/out/settings.js"(exports2) {
511
+ "../node_modules/.pnpm/@nodelib+fs.scandir@2.1.5/node_modules/@nodelib/fs.scandir/out/settings.js"(exports2) {
512
512
  "use strict";
513
513
  Object.defineProperty(exports2, "__esModule", { value: true });
514
514
  var path8 = require("path");
@@ -536,9 +536,9 @@ var require_settings2 = __commonJS({
536
536
  }
537
537
  });
538
538
 
539
- // ../node_modules/@nodelib/fs.scandir/out/index.js
539
+ // ../node_modules/.pnpm/@nodelib+fs.scandir@2.1.5/node_modules/@nodelib/fs.scandir/out/index.js
540
540
  var require_out2 = __commonJS({
541
- "../node_modules/@nodelib/fs.scandir/out/index.js"(exports2) {
541
+ "../node_modules/.pnpm/@nodelib+fs.scandir@2.1.5/node_modules/@nodelib/fs.scandir/out/index.js"(exports2) {
542
542
  "use strict";
543
543
  Object.defineProperty(exports2, "__esModule", { value: true });
544
544
  exports2.Settings = exports2.scandirSync = exports2.scandir = void 0;
@@ -568,9 +568,9 @@ var require_out2 = __commonJS({
568
568
  }
569
569
  });
570
570
 
571
- // ../node_modules/reusify/reusify.js
571
+ // ../node_modules/.pnpm/reusify@1.0.4/node_modules/reusify/reusify.js
572
572
  var require_reusify = __commonJS({
573
- "../node_modules/reusify/reusify.js"(exports2, module2) {
573
+ "../node_modules/.pnpm/reusify@1.0.4/node_modules/reusify/reusify.js"(exports2, module2) {
574
574
  "use strict";
575
575
  function reusify(Constructor) {
576
576
  var head = new Constructor();
@@ -599,19 +599,19 @@ var require_reusify = __commonJS({
599
599
  }
600
600
  });
601
601
 
602
- // ../node_modules/fastq/queue.js
602
+ // ../node_modules/.pnpm/fastq@1.16.0/node_modules/fastq/queue.js
603
603
  var require_queue = __commonJS({
604
- "../node_modules/fastq/queue.js"(exports2, module2) {
604
+ "../node_modules/.pnpm/fastq@1.16.0/node_modules/fastq/queue.js"(exports2, module2) {
605
605
  "use strict";
606
606
  var reusify = require_reusify();
607
- function fastqueue(context2, worker, _concurrency) {
607
+ function fastqueue(context2, worker, concurrency) {
608
608
  if (typeof context2 === "function") {
609
- _concurrency = worker;
609
+ concurrency = worker;
610
610
  worker = context2;
611
611
  context2 = null;
612
612
  }
613
- if (!(_concurrency >= 1)) {
614
- throw new Error("fastqueue concurrency must be equal to or greater than 1");
613
+ if (concurrency < 1) {
614
+ throw new Error("fastqueue concurrency must be greater than 1");
615
615
  }
616
616
  var cache = reusify(Task);
617
617
  var queueHead = null;
@@ -624,20 +624,7 @@ var require_queue = __commonJS({
624
624
  saturated: noop,
625
625
  pause,
626
626
  paused: false,
627
- get concurrency() {
628
- return _concurrency;
629
- },
630
- set concurrency(value) {
631
- if (!(value >= 1)) {
632
- throw new Error("fastqueue concurrency must be equal to or greater than 1");
633
- }
634
- _concurrency = value;
635
- if (self.paused) return;
636
- for (; queueHead && _running < _concurrency; ) {
637
- _running++;
638
- release();
639
- }
640
- },
627
+ concurrency,
641
628
  running,
642
629
  resume,
643
630
  idle,
@@ -647,8 +634,7 @@ var require_queue = __commonJS({
647
634
  empty: noop,
648
635
  kill,
649
636
  killAndDrain,
650
- error: error2,
651
- abort
637
+ error: error2
652
638
  };
653
639
  return self;
654
640
  function running() {
@@ -678,12 +664,7 @@ var require_queue = __commonJS({
678
664
  function resume() {
679
665
  if (!self.paused) return;
680
666
  self.paused = false;
681
- if (queueHead === null) {
682
- _running++;
683
- release();
684
- return;
685
- }
686
- for (; queueHead && _running < _concurrency; ) {
667
+ for (var i = 0; i < self.concurrency; i++) {
687
668
  _running++;
688
669
  release();
689
670
  }
@@ -698,7 +679,7 @@ var require_queue = __commonJS({
698
679
  current.value = value;
699
680
  current.callback = done || noop;
700
681
  current.errorHandler = errorHandler2;
701
- if (_running >= _concurrency || self.paused) {
682
+ if (_running === self.concurrency || self.paused) {
702
683
  if (queueTail) {
703
684
  queueTail.next = current;
704
685
  queueTail = current;
@@ -719,7 +700,7 @@ var require_queue = __commonJS({
719
700
  current.value = value;
720
701
  current.callback = done || noop;
721
702
  current.errorHandler = errorHandler2;
722
- if (_running >= _concurrency || self.paused) {
703
+ if (_running === self.concurrency || self.paused) {
723
704
  if (queueHead) {
724
705
  current.next = queueHead;
725
706
  queueHead = current;
@@ -738,7 +719,7 @@ var require_queue = __commonJS({
738
719
  cache.release(holder);
739
720
  }
740
721
  var next = queueHead;
741
- if (next && _running <= _concurrency) {
722
+ if (next) {
742
723
  if (!self.paused) {
743
724
  if (queueTail === queueHead) {
744
725
  queueTail = null;
@@ -767,28 +748,6 @@ var require_queue = __commonJS({
767
748
  self.drain();
768
749
  self.drain = noop;
769
750
  }
770
- function abort() {
771
- var current = queueHead;
772
- queueHead = null;
773
- queueTail = null;
774
- while (current) {
775
- var next = current.next;
776
- var callback = current.callback;
777
- var errorHandler3 = current.errorHandler;
778
- var val = current.value;
779
- var context3 = current.context;
780
- current.value = null;
781
- current.callback = noop;
782
- current.errorHandler = null;
783
- if (errorHandler3) {
784
- errorHandler3(new Error("abort"), val);
785
- }
786
- callback.call(context3, new Error("abort"));
787
- current.release(current);
788
- current = next;
789
- }
790
- self.drain = noop;
791
- }
792
751
  function error2(handler) {
793
752
  errorHandler2 = handler;
794
753
  }
@@ -816,9 +775,9 @@ var require_queue = __commonJS({
816
775
  self.release(self);
817
776
  };
818
777
  }
819
- function queueAsPromised(context2, worker, _concurrency) {
778
+ function queueAsPromised(context2, worker, concurrency) {
820
779
  if (typeof context2 === "function") {
821
- _concurrency = worker;
780
+ concurrency = worker;
822
781
  worker = context2;
823
782
  context2 = null;
824
783
  }
@@ -827,7 +786,7 @@ var require_queue = __commonJS({
827
786
  cb(null, res);
828
787
  }, cb);
829
788
  }
830
- var queue2 = fastqueue(context2, asyncWrapper, _concurrency);
789
+ var queue2 = fastqueue(context2, asyncWrapper, concurrency);
831
790
  var pushCb = queue2.push;
832
791
  var unshiftCb = queue2.unshift;
833
792
  queue2.push = push;
@@ -861,19 +820,17 @@ var require_queue = __commonJS({
861
820
  return p;
862
821
  }
863
822
  function drained() {
864
- var p = new Promise(function(resolve2) {
865
- process.nextTick(function() {
866
- if (queue2.idle()) {
867
- resolve2();
868
- } else {
869
- var previousDrain = queue2.drain;
870
- queue2.drain = function() {
871
- if (typeof previousDrain === "function") previousDrain();
872
- resolve2();
873
- queue2.drain = previousDrain;
874
- };
875
- }
823
+ if (queue2.idle()) {
824
+ return new Promise(function(resolve2) {
825
+ resolve2();
876
826
  });
827
+ }
828
+ var previousDrain = queue2.drain;
829
+ var p = new Promise(function(resolve2) {
830
+ queue2.drain = function() {
831
+ previousDrain();
832
+ resolve2();
833
+ };
877
834
  });
878
835
  return p;
879
836
  }
@@ -883,9 +840,9 @@ var require_queue = __commonJS({
883
840
  }
884
841
  });
885
842
 
886
- // ../node_modules/@nodelib/fs.walk/out/readers/common.js
843
+ // ../node_modules/.pnpm/@nodelib+fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/readers/common.js
887
844
  var require_common2 = __commonJS({
888
- "../node_modules/@nodelib/fs.walk/out/readers/common.js"(exports2) {
845
+ "../node_modules/.pnpm/@nodelib+fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/readers/common.js"(exports2) {
889
846
  "use strict";
890
847
  Object.defineProperty(exports2, "__esModule", { value: true });
891
848
  exports2.joinPathSegments = exports2.replacePathSegmentSeparator = exports2.isAppliedFilter = exports2.isFatalError = void 0;
@@ -917,9 +874,9 @@ var require_common2 = __commonJS({
917
874
  }
918
875
  });
919
876
 
920
- // ../node_modules/@nodelib/fs.walk/out/readers/reader.js
877
+ // ../node_modules/.pnpm/@nodelib+fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/readers/reader.js
921
878
  var require_reader = __commonJS({
922
- "../node_modules/@nodelib/fs.walk/out/readers/reader.js"(exports2) {
879
+ "../node_modules/.pnpm/@nodelib+fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/readers/reader.js"(exports2) {
923
880
  "use strict";
924
881
  Object.defineProperty(exports2, "__esModule", { value: true });
925
882
  var common = require_common2();
@@ -934,9 +891,9 @@ var require_reader = __commonJS({
934
891
  }
935
892
  });
936
893
 
937
- // ../node_modules/@nodelib/fs.walk/out/readers/async.js
894
+ // ../node_modules/.pnpm/@nodelib+fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/readers/async.js
938
895
  var require_async3 = __commonJS({
939
- "../node_modules/@nodelib/fs.walk/out/readers/async.js"(exports2) {
896
+ "../node_modules/.pnpm/@nodelib+fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/readers/async.js"(exports2) {
940
897
  "use strict";
941
898
  Object.defineProperty(exports2, "__esModule", { value: true });
942
899
  var events_1 = require("events");
@@ -1037,9 +994,9 @@ var require_async3 = __commonJS({
1037
994
  }
1038
995
  });
1039
996
 
1040
- // ../node_modules/@nodelib/fs.walk/out/providers/async.js
997
+ // ../node_modules/.pnpm/@nodelib+fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/providers/async.js
1041
998
  var require_async4 = __commonJS({
1042
- "../node_modules/@nodelib/fs.walk/out/providers/async.js"(exports2) {
999
+ "../node_modules/.pnpm/@nodelib+fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/providers/async.js"(exports2) {
1043
1000
  "use strict";
1044
1001
  Object.defineProperty(exports2, "__esModule", { value: true });
1045
1002
  var async_1 = require_async3();
@@ -1073,9 +1030,9 @@ var require_async4 = __commonJS({
1073
1030
  }
1074
1031
  });
1075
1032
 
1076
- // ../node_modules/@nodelib/fs.walk/out/providers/stream.js
1033
+ // ../node_modules/.pnpm/@nodelib+fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/providers/stream.js
1077
1034
  var require_stream = __commonJS({
1078
- "../node_modules/@nodelib/fs.walk/out/providers/stream.js"(exports2) {
1035
+ "../node_modules/.pnpm/@nodelib+fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/providers/stream.js"(exports2) {
1079
1036
  "use strict";
1080
1037
  Object.defineProperty(exports2, "__esModule", { value: true });
1081
1038
  var stream_1 = require("stream");
@@ -1114,9 +1071,9 @@ var require_stream = __commonJS({
1114
1071
  }
1115
1072
  });
1116
1073
 
1117
- // ../node_modules/@nodelib/fs.walk/out/readers/sync.js
1074
+ // ../node_modules/.pnpm/@nodelib+fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/readers/sync.js
1118
1075
  var require_sync3 = __commonJS({
1119
- "../node_modules/@nodelib/fs.walk/out/readers/sync.js"(exports2) {
1076
+ "../node_modules/.pnpm/@nodelib+fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/readers/sync.js"(exports2) {
1120
1077
  "use strict";
1121
1078
  Object.defineProperty(exports2, "__esModule", { value: true });
1122
1079
  var fsScandir = require_out2();
@@ -1178,9 +1135,9 @@ var require_sync3 = __commonJS({
1178
1135
  }
1179
1136
  });
1180
1137
 
1181
- // ../node_modules/@nodelib/fs.walk/out/providers/sync.js
1138
+ // ../node_modules/.pnpm/@nodelib+fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/providers/sync.js
1182
1139
  var require_sync4 = __commonJS({
1183
- "../node_modules/@nodelib/fs.walk/out/providers/sync.js"(exports2) {
1140
+ "../node_modules/.pnpm/@nodelib+fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/providers/sync.js"(exports2) {
1184
1141
  "use strict";
1185
1142
  Object.defineProperty(exports2, "__esModule", { value: true });
1186
1143
  var sync_1 = require_sync3();
@@ -1198,9 +1155,9 @@ var require_sync4 = __commonJS({
1198
1155
  }
1199
1156
  });
1200
1157
 
1201
- // ../node_modules/@nodelib/fs.walk/out/settings.js
1158
+ // ../node_modules/.pnpm/@nodelib+fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/settings.js
1202
1159
  var require_settings3 = __commonJS({
1203
- "../node_modules/@nodelib/fs.walk/out/settings.js"(exports2) {
1160
+ "../node_modules/.pnpm/@nodelib+fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/settings.js"(exports2) {
1204
1161
  "use strict";
1205
1162
  Object.defineProperty(exports2, "__esModule", { value: true });
1206
1163
  var path8 = require("path");
@@ -1230,9 +1187,9 @@ var require_settings3 = __commonJS({
1230
1187
  }
1231
1188
  });
1232
1189
 
1233
- // ../node_modules/@nodelib/fs.walk/out/index.js
1190
+ // ../node_modules/.pnpm/@nodelib+fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/index.js
1234
1191
  var require_out3 = __commonJS({
1235
- "../node_modules/@nodelib/fs.walk/out/index.js"(exports2) {
1192
+ "../node_modules/.pnpm/@nodelib+fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/index.js"(exports2) {
1236
1193
  "use strict";
1237
1194
  Object.defineProperty(exports2, "__esModule", { value: true });
1238
1195
  exports2.Settings = exports2.walkStream = exports2.walkSync = exports2.walk = void 0;
@@ -1275,7 +1232,7 @@ var require_package = __commonJS({
1275
1232
  "package.json"(exports2, module2) {
1276
1233
  module2.exports = {
1277
1234
  name: "braintrust",
1278
- version: "3.4.0",
1235
+ version: "3.6.0",
1279
1236
  description: "SDK for integrating Braintrust",
1280
1237
  repository: {
1281
1238
  type: "git",
@@ -1387,6 +1344,17 @@ var require_package = __commonJS({
1387
1344
  clean: "rm -r dist/* && rm -r dev/dist/*",
1388
1345
  docs: "npx typedoc --options typedoc.json src/node/index.ts",
1389
1346
  test: 'vitest run --exclude "src/wrappers/**/*.test.ts" --exclude "src/otel/**/*.test.ts" --exclude "smoke/**/*.test.ts" --exclude "src/zod/**/*.test.ts" --exclude "tests/api-compatibility/**"',
1347
+ "test:core": "pnpm prune && pnpm test",
1348
+ "test:checks": "pnpm run test:core && pnpm run test:vitest",
1349
+ "test:external": "pnpm run test:external:openai && pnpm run test:external:anthropic && pnpm run test:external:google-genai && pnpm run test:external:ai-sdk && pnpm run test:external:claude-agent-sdk",
1350
+ "test:external:openai": "bash scripts/test-provider.sh test:openai openai",
1351
+ "test:external:anthropic": "bash scripts/test-provider.sh test:anthropic @anthropic-ai/sdk",
1352
+ "test:external:google-genai": "bash scripts/test-provider.sh test:google-genai @google/genai",
1353
+ "test:external:ai-sdk": "pnpm run test:external:ai-sdk-v5 && pnpm run test:external:ai-sdk-v6",
1354
+ "test:external:ai-sdk-v5": "cd src/wrappers/ai-sdk/tests/v5 && pnpm install --ignore-workspace && pnpm test",
1355
+ "test:external:ai-sdk-v6": "cd src/wrappers/ai-sdk/tests/v6 && pnpm install --ignore-workspace && pnpm test",
1356
+ "test:external:claude-agent-sdk": "cd src/wrappers/claude-agent-sdk && pnpm install && pnpm test",
1357
+ "test:all": "pnpm run test:checks && pnpm run test:external",
1390
1358
  "test:api-compat": "vitest run tests/api-compatibility/api-compatibility.test.ts",
1391
1359
  "test:anthropic": "vitest run src/wrappers/anthropic.test.ts",
1392
1360
  "test:openai": "vitest run src/wrappers/oai.test.ts",
@@ -1402,9 +1370,14 @@ var require_package = __commonJS({
1402
1370
  "test:claude-agent-sdk": "pnpm --filter @braintrust/claude-agent-sdk-tests test",
1403
1371
  "test:vitest": "pnpm --filter @braintrust/vitest-wrapper-tests test",
1404
1372
  "test:output": "tsx scripts/test-output.ts --with-comparison --with-metrics --with-progress",
1373
+ bench: "npx tsx src/queue.bench.ts",
1374
+ "publish:validate": "./scripts/validate-release.sh && pnpm install --frozen-lockfile && pnpm run build && npm publish",
1405
1375
  lint: "eslint .",
1406
1376
  "fix:lint": "eslint --fix .",
1407
- playground: "tsx playground.ts"
1377
+ playground: "tsx playground.ts",
1378
+ "playground:auto": "mkdir -p .context && pnpm exec esbuild playground.ts --platform=node --format=esm --outfile=.context/playground.auto.mjs && node --import ./dist/auto-instrumentations/hook.mjs ./.context/playground.auto.mjs",
1379
+ "playground:cli:push": "node dist/cli.js push playground.ts",
1380
+ "playground:cli:eval": "node dist/cli.js eval playground.ts"
1408
1381
  },
1409
1382
  author: "",
1410
1383
  license: "MIT",
@@ -1438,18 +1411,18 @@ var require_package = __commonJS({
1438
1411
  openai: "6.25.0",
1439
1412
  "openapi-zod-client": "^1.18.3",
1440
1413
  rollup: "^4.28.1",
1441
- vite: "^5.4.14",
1442
- webpack: "^5.97.1",
1443
1414
  tar: "^7.5.2",
1444
1415
  tinybench: "^4.0.1",
1445
1416
  "ts-jest": "^29.1.4",
1446
1417
  tsup: "^8.5.1",
1447
- tsx: "^3.14.0",
1418
+ tsx: "^4.21.0",
1448
1419
  typedoc: "^0.25.13",
1449
1420
  "typedoc-plugin-markdown": "^3.17.1",
1450
1421
  typescript: "5.4.4",
1422
+ vite: "^6.4.1",
1451
1423
  "vite-tsconfig-paths": "^4.3.2",
1452
- vitest: "^2.1.9",
1424
+ vitest: "^4.1.0",
1425
+ webpack: "^5.97.1",
1453
1426
  zod: "^3.25.34"
1454
1427
  },
1455
1428
  dependencies: {
@@ -1525,8 +1498,54 @@ var DefaultAsyncLocalStorage = class {
1525
1498
  return void 0;
1526
1499
  }
1527
1500
  };
1528
- var DefaultTracingChannel = class {
1501
+ var DefaultChannel = class {
1502
+ constructor(name) {
1503
+ this.name = name;
1504
+ }
1529
1505
  hasSubscribers = false;
1506
+ subscribe(_subscription) {
1507
+ }
1508
+ unsubscribe(_subscription) {
1509
+ return false;
1510
+ }
1511
+ bindStore(_store, _transform) {
1512
+ }
1513
+ unbindStore(_store) {
1514
+ return false;
1515
+ }
1516
+ publish(_message) {
1517
+ }
1518
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1519
+ runStores(_message, fn, thisArg, ...args) {
1520
+ return fn.apply(thisArg, args);
1521
+ }
1522
+ };
1523
+ var DefaultTracingChannel = class {
1524
+ start;
1525
+ end;
1526
+ asyncStart;
1527
+ asyncEnd;
1528
+ error;
1529
+ constructor(nameOrChannels) {
1530
+ if (typeof nameOrChannels === "string") {
1531
+ this.start = new DefaultChannel(`tracing:${nameOrChannels}:start`);
1532
+ this.end = new DefaultChannel(`tracing:${nameOrChannels}:end`);
1533
+ this.asyncStart = new DefaultChannel(
1534
+ `tracing:${nameOrChannels}:asyncStart`
1535
+ );
1536
+ this.asyncEnd = new DefaultChannel(`tracing:${nameOrChannels}:asyncEnd`);
1537
+ this.error = new DefaultChannel(`tracing:${nameOrChannels}:error`);
1538
+ return;
1539
+ }
1540
+ this.start = nameOrChannels.start ?? new DefaultChannel("tracing:start");
1541
+ this.end = nameOrChannels.end ?? new DefaultChannel("tracing:end");
1542
+ this.asyncStart = nameOrChannels.asyncStart ?? new DefaultChannel("tracing:asyncStart");
1543
+ this.asyncEnd = nameOrChannels.asyncEnd ?? new DefaultChannel("tracing:asyncEnd");
1544
+ this.error = nameOrChannels.error ?? new DefaultChannel("tracing:error");
1545
+ }
1546
+ get hasSubscribers() {
1547
+ return this.start.hasSubscribers || this.end.hasSubscribers || this.asyncStart.hasSubscribers || this.asyncEnd.hasSubscribers || this.error.hasSubscribers;
1548
+ }
1530
1549
  subscribe(_handlers) {
1531
1550
  }
1532
1551
  unsubscribe(_handlers) {
@@ -1554,7 +1573,7 @@ var iso = {
1554
1573
  getCallerLocation: () => void 0,
1555
1574
  newAsyncLocalStorage: () => new DefaultAsyncLocalStorage(),
1556
1575
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
1557
- newTracingChannel: (_nameOrChannels) => new DefaultTracingChannel(),
1576
+ newTracingChannel: (nameOrChannels) => new DefaultTracingChannel(nameOrChannels),
1558
1577
  processOn: (_0, _1) => {
1559
1578
  },
1560
1579
  basename: (filepath) => filepath.split(/[\\/]/).pop() || filepath,
@@ -3632,6 +3651,8 @@ var Experiment = import_v36.z.object({
3632
3651
  deleted_at: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
3633
3652
  dataset_id: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
3634
3653
  dataset_version: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
3654
+ parameters_id: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
3655
+ parameters_version: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
3635
3656
  public: import_v36.z.boolean(),
3636
3657
  user_id: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
3637
3658
  metadata: import_v36.z.union([import_v36.z.object({}).partial().passthrough(), import_v36.z.null()]).optional(),
@@ -3654,7 +3675,11 @@ var SpanType = import_v36.z.union([
3654
3675
  import_v36.z.null()
3655
3676
  ]);
3656
3677
  var SpanAttributes = import_v36.z.union([
3657
- import_v36.z.object({ name: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]), type: SpanType }).partial().passthrough(),
3678
+ import_v36.z.object({
3679
+ name: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]),
3680
+ type: SpanType,
3681
+ purpose: import_v36.z.union([import_v36.z.literal("scorer"), import_v36.z.null()])
3682
+ }).partial().passthrough(),
3658
3683
  import_v36.z.null()
3659
3684
  ]);
3660
3685
  var ExperimentEvent = import_v36.z.object({
@@ -4094,6 +4119,7 @@ var FunctionId = import_v36.z.union([
4094
4119
  version: import_v36.z.string()
4095
4120
  }),
4096
4121
  code: import_v36.z.string(),
4122
+ function_type: FunctionTypeEnum.and(import_v36.z.unknown()).optional(),
4097
4123
  name: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional()
4098
4124
  }),
4099
4125
  import_v36.z.object({
@@ -4323,7 +4349,12 @@ var TopicAutomationConfig = import_v36.z.object({
4323
4349
  topic_map_functions: import_v36.z.array(TopicMapFunctionAutomation),
4324
4350
  scope: import_v36.z.union([SpanScope, TraceScope, GroupScope, import_v36.z.null()]).optional(),
4325
4351
  data_scope: TopicAutomationDataScope.optional(),
4326
- btql_filter: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional()
4352
+ btql_filter: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
4353
+ backfill_time_range: import_v36.z.union([
4354
+ import_v36.z.string(),
4355
+ import_v36.z.object({ from: import_v36.z.string(), to: import_v36.z.string() }),
4356
+ import_v36.z.null()
4357
+ ]).optional()
4327
4358
  });
4328
4359
  var ProjectAutomation = import_v36.z.object({
4329
4360
  id: import_v36.z.string().uuid(),
@@ -5744,6 +5775,9 @@ var BRAINTRUST_ATTACHMENT = BraintrustAttachmentReference.shape.type.value;
5744
5775
  var EXTERNAL_ATTACHMENT = ExternalAttachmentReference.shape.type.value;
5745
5776
  var LOGS3_OVERFLOW_REFERENCE_TYPE = "logs3_overflow";
5746
5777
  var BRAINTRUST_PARAMS = Object.keys(BraintrustModelParams.shape);
5778
+ var RESET_CONTEXT_MANAGER_STATE = Symbol.for(
5779
+ "braintrust.resetContextManagerState"
5780
+ );
5747
5781
  var DEFAULT_MAX_REQUEST_SIZE = 6 * 1024 * 1024;
5748
5782
  var parametersRowSchema = import_v38.z.object({
5749
5783
  id: import_v38.z.string().uuid(),
@@ -5760,6 +5794,12 @@ var parametersRowSchema = import_v38.z.object({
5760
5794
  }),
5761
5795
  metadata: import_v38.z.union([import_v38.z.object({}).partial().passthrough(), import_v38.z.null()]).optional()
5762
5796
  });
5797
+ var InlineAttachmentReferenceSchema = import_v38.z.object({
5798
+ type: import_v38.z.literal("inline_attachment"),
5799
+ src: import_v38.z.string().min(1),
5800
+ content_type: import_v38.z.string().optional(),
5801
+ filename: import_v38.z.string().optional()
5802
+ });
5763
5803
  var LoginInvalidOrgError = class extends Error {
5764
5804
  constructor(message) {
5765
5805
  super(message);
@@ -5800,13 +5840,18 @@ function applyMaskingToField(maskingFunction, data, fieldName) {
5800
5840
  return `ERROR: Failed to mask field '${fieldName}' - ${errorType}`;
5801
5841
  }
5802
5842
  }
5843
+ var BRAINTRUST_CURRENT_SPAN_STORE = Symbol.for(
5844
+ "braintrust.currentSpanStore"
5845
+ );
5803
5846
  var ContextManager = class {
5804
5847
  };
5805
5848
  var BraintrustContextManager = class extends ContextManager {
5806
5849
  _currentSpan;
5850
+ [BRAINTRUST_CURRENT_SPAN_STORE];
5807
5851
  constructor() {
5808
5852
  super();
5809
5853
  this._currentSpan = isomorph_default.newAsyncLocalStorage();
5854
+ this[BRAINTRUST_CURRENT_SPAN_STORE] = this._currentSpan;
5810
5855
  }
5811
5856
  getParentSpanIds() {
5812
5857
  const currentSpan2 = this._currentSpan.getStore();
@@ -6013,6 +6058,9 @@ var BraintrustState = class _BraintrustState {
6013
6058
  resetIdGenState() {
6014
6059
  this._idGenerator = null;
6015
6060
  }
6061
+ [RESET_CONTEXT_MANAGER_STATE]() {
6062
+ this._contextManager = null;
6063
+ }
6016
6064
  get idGenerator() {
6017
6065
  if (this._idGenerator === null) {
6018
6066
  this._idGenerator = getIdGenerator();
@@ -7749,6 +7797,7 @@ function init(projectOrOptions, optionalOptions) {
7749
7797
  experiment,
7750
7798
  description,
7751
7799
  dataset,
7800
+ parameters,
7752
7801
  baseExperiment,
7753
7802
  isPublic,
7754
7803
  open: open2,
@@ -7866,6 +7915,17 @@ function init(projectOrOptions, optionalOptions) {
7866
7915
  args["dataset_version"] = await dataset.version();
7867
7916
  }
7868
7917
  }
7918
+ if (parameters !== void 0) {
7919
+ if (RemoteEvalParameters.isParameters(parameters)) {
7920
+ args["parameters_id"] = parameters.id;
7921
+ args["parameters_version"] = parameters.version;
7922
+ } else {
7923
+ args["parameters_id"] = parameters.id;
7924
+ if (parameters.version !== void 0) {
7925
+ args["parameters_version"] = parameters.version;
7926
+ }
7927
+ }
7928
+ }
7869
7929
  if (isPublic !== void 0) {
7870
7930
  args["public"] = isPublic;
7871
7931
  }
@@ -9517,40 +9577,82 @@ var Dataset2 = class extends ObjectFetcher {
9517
9577
  return typeof data === "object" && data !== null && "__braintrust_dataset_marker" in data;
9518
9578
  }
9519
9579
  };
9520
- function renderMessage(render, message) {
9580
+ function isAttachmentObject(value) {
9581
+ return BraintrustAttachmentReference.safeParse(value).success || InlineAttachmentReferenceSchema.safeParse(value).success || ExternalAttachmentReference.safeParse(value).success;
9582
+ }
9583
+ function isURL(url) {
9584
+ try {
9585
+ const parsedUrl = new URL(url.trim());
9586
+ return parsedUrl.protocol === "http:" || parsedUrl.protocol === "https:";
9587
+ } catch {
9588
+ return false;
9589
+ }
9590
+ }
9591
+ function expandAttachmentArrayPreTemplate(content, variables) {
9592
+ if (typeof content !== "string") return null;
9593
+ const match = content.match(/^\{\{\s*([\w.]+)\s*\}\}$/);
9594
+ if (!match) return null;
9595
+ const varPath = match[1];
9596
+ const value = varPath.includes(".") ? getObjValueByPath(variables, varPath.split(".")) : variables[varPath];
9597
+ if (!Array.isArray(value)) return null;
9598
+ const allValid = value.every(
9599
+ (v) => isAttachmentObject(v) || typeof v === "string" && isURL(v)
9600
+ );
9601
+ if (!allValid) return null;
9602
+ return value.map((item) => ({
9603
+ type: "image_url",
9604
+ image_url: { url: item }
9605
+ }));
9606
+ }
9607
+ function renderMessageImpl(render, message, variables) {
9521
9608
  return {
9522
9609
  ...message,
9523
9610
  ..."content" in message ? {
9524
- content: isEmpty2(message.content) ? void 0 : typeof message.content === "string" ? render(message.content) : message.content.map((c) => {
9611
+ content: isEmpty2(message.content) ? void 0 : typeof message.content === "string" ? render(message.content) : message.content.flatMap((c) => {
9525
9612
  switch (c.type) {
9526
9613
  case "text":
9527
- return { ...c, text: render(c.text) };
9614
+ return [{ ...c, text: render(c.text) }];
9528
9615
  case "image_url":
9529
9616
  if (isObject(c.image_url.url)) {
9530
9617
  throw new Error(
9531
9618
  "Attachments must be replaced with URLs before calling `build()`"
9532
9619
  );
9533
9620
  }
9534
- return {
9535
- ...c,
9536
- image_url: {
9537
- ...c.image_url,
9538
- url: render(c.image_url.url)
9621
+ if (variables) {
9622
+ const expanded = expandAttachmentArrayPreTemplate(
9623
+ c.image_url.url,
9624
+ variables
9625
+ );
9626
+ if (expanded) {
9627
+ return expanded;
9539
9628
  }
9540
- };
9629
+ }
9630
+ return [
9631
+ {
9632
+ ...c,
9633
+ image_url: {
9634
+ ...c.image_url,
9635
+ url: render(c.image_url.url)
9636
+ }
9637
+ }
9638
+ ];
9541
9639
  case "file":
9542
- return {
9543
- ...c,
9544
- file: {
9545
- file_data: render(c.file.file_data || ""),
9546
- ...c.file.file_id && {
9547
- file_id: render(c.file.file_id)
9548
- },
9549
- ...c.file.filename && {
9550
- filename: render(c.file.filename)
9640
+ return [
9641
+ {
9642
+ ...c,
9643
+ file: {
9644
+ ...c.file.file_data && {
9645
+ file_data: render(c.file.file_data)
9646
+ },
9647
+ ...c.file.file_id && {
9648
+ file_id: render(c.file.file_id)
9649
+ },
9650
+ ...c.file.filename && {
9651
+ filename: render(c.file.filename)
9652
+ }
9551
9653
  }
9552
9654
  }
9553
- };
9655
+ ];
9554
9656
  default:
9555
9657
  const _exhaustiveCheck = c;
9556
9658
  return _exhaustiveCheck;
@@ -9707,17 +9809,19 @@ var Prompt2 = class _Prompt {
9707
9809
  }
9708
9810
  runBuild(buildArgs, options) {
9709
9811
  const { flavor } = options;
9710
- const params = {
9711
- ...this.defaults,
9712
- ...Object.fromEntries(
9713
- Object.entries(this.options.params || {}).filter(
9714
- ([k, _v]) => !BRAINTRUST_PARAMS.includes(k)
9715
- )
9716
- ),
9717
- ...!isEmpty2(this.options.model) ? {
9718
- model: this.options.model
9719
- } : {}
9720
- };
9812
+ const params = Object.fromEntries(
9813
+ Object.entries({
9814
+ ...this.defaults,
9815
+ ...Object.fromEntries(
9816
+ Object.entries(this.options.params || {}).filter(
9817
+ ([k, _v]) => !BRAINTRUST_PARAMS.includes(k)
9818
+ )
9819
+ ),
9820
+ ...!isEmpty2(this.options.model) ? {
9821
+ model: this.options.model
9822
+ } : {}
9823
+ }).filter(([key, value]) => key !== "response_format" || value !== null)
9824
+ );
9721
9825
  if (!("model" in params) || isEmpty2(params.model)) {
9722
9826
  throw new Error(
9723
9827
  "No model specified. Either specify it in the prompt or as a default"
@@ -9817,7 +9921,7 @@ var Prompt2 = class _Prompt {
9817
9921
  templateFormat
9818
9922
  });
9819
9923
  const baseMessages = (prompt.messages || []).map(
9820
- (m) => renderMessage(render, m)
9924
+ (m) => renderMessageImpl(render, m, variables)
9821
9925
  );
9822
9926
  const hasSystemPrompt = baseMessages.some((m) => m.role === "system");
9823
9927
  const messages = [
@@ -9984,7 +10088,7 @@ var BarProgressReporter = class {
9984
10088
  var import_chalk3 = __toESM(require("chalk"));
9985
10089
  var import_termi_link2 = require("termi-link");
9986
10090
 
9987
- // ../node_modules/async/dist/async.mjs
10091
+ // ../node_modules/.pnpm/async@3.2.5/node_modules/async/dist/async.mjs
9988
10092
  function initialParams(fn) {
9989
10093
  return function(...args) {
9990
10094
  var callback = args.pop();
@@ -10109,6 +10213,7 @@ function isArrayLike(value) {
10109
10213
  return value && typeof value.length === "number" && value.length >= 0 && value.length % 1 === 0;
10110
10214
  }
10111
10215
  var breakLoop = {};
10216
+ var breakLoop$1 = breakLoop;
10112
10217
  function once(fn) {
10113
10218
  function wrapper(...args) {
10114
10219
  if (fn === null) return;
@@ -10200,7 +10305,7 @@ function asyncEachOfLimit(generator, limit, iteratee, callback) {
10200
10305
  canceled = true;
10201
10306
  return;
10202
10307
  }
10203
- if (result === breakLoop || done && running <= 0) {
10308
+ if (result === breakLoop$1 || done && running <= 0) {
10204
10309
  done = true;
10205
10310
  return callback(null);
10206
10311
  }
@@ -10243,7 +10348,7 @@ var eachOfLimit$2 = (limit) => {
10243
10348
  } else if (err === false) {
10244
10349
  done = true;
10245
10350
  canceled = true;
10246
- } else if (value === breakLoop || done && running <= 0) {
10351
+ } else if (value === breakLoop$1 || done && running <= 0) {
10247
10352
  done = true;
10248
10353
  return callback(null);
10249
10354
  } else if (!looping) {
@@ -10286,7 +10391,7 @@ function eachOfArrayLike(coll, iteratee, callback) {
10286
10391
  if (canceled === true) return;
10287
10392
  if (err) {
10288
10393
  callback(err);
10289
- } else if (++completed === length || value === breakLoop) {
10394
+ } else if (++completed === length || value === breakLoop$1) {
10290
10395
  callback(null);
10291
10396
  }
10292
10397
  }
@@ -10682,7 +10787,7 @@ function _createTester(check, getResult) {
10682
10787
  if (check(result) && !testResult) {
10683
10788
  testPassed = true;
10684
10789
  testResult = getResult(true, value);
10685
- return callback(null, breakLoop);
10790
+ return callback(null, breakLoop$1);
10686
10791
  }
10687
10792
  callback();
10688
10793
  });
@@ -11372,7 +11477,8 @@ var promptDefinitionSchema = promptContentsSchema.and(
11372
11477
  import_v39.z.object({
11373
11478
  model: import_v39.z.string(),
11374
11479
  params: ModelParams.optional(),
11375
- templateFormat: import_v39.z.enum(["mustache", "nunjucks", "none"]).optional()
11480
+ templateFormat: import_v39.z.enum(["mustache", "nunjucks", "none"]).optional(),
11481
+ environments: import_v39.z.array(import_v39.z.string()).optional()
11376
11482
  })
11377
11483
  );
11378
11484
  var promptDefinitionWithToolsSchema = promptDefinitionSchema.and(
@@ -11528,6 +11634,22 @@ function initExperiment(state, options = {}) {
11528
11634
  setCurrent: false
11529
11635
  });
11530
11636
  }
11637
+ async function getExperimentParametersRef(parameters) {
11638
+ if (!parameters) {
11639
+ return void 0;
11640
+ }
11641
+ const resolvedParameters = parameters instanceof Promise ? await parameters : parameters;
11642
+ if (!RemoteEvalParameters.isParameters(resolvedParameters)) {
11643
+ return void 0;
11644
+ }
11645
+ if (resolvedParameters.id === void 0) {
11646
+ return void 0;
11647
+ }
11648
+ return {
11649
+ id: resolvedParameters.id,
11650
+ version: resolvedParameters.version
11651
+ };
11652
+ }
11531
11653
  function callEvaluatorData(data) {
11532
11654
  const dataResult = typeof data === "function" ? data() : data;
11533
11655
  let baseExperiment = void 0;
@@ -11594,6 +11716,7 @@ async function Eval(name, evaluator, reporterOrOpts) {
11594
11716
  const { data, baseExperiment: defaultBaseExperiment } = callEvaluatorData(
11595
11717
  evaluator.data
11596
11718
  );
11719
+ const parameters = await getExperimentParametersRef(evaluator.parameters);
11597
11720
  const experiment = options.parent || options.noSendLogs ? null : initExperiment(evaluator.state, {
11598
11721
  ...evaluator.projectId ? { projectId: evaluator.projectId } : { project: name },
11599
11722
  experiment: evaluator.experimentName,
@@ -11606,7 +11729,8 @@ async function Eval(name, evaluator, reporterOrOpts) {
11606
11729
  baseExperimentId: evaluator.baseExperimentId,
11607
11730
  gitMetadataSettings: evaluator.gitMetadataSettings,
11608
11731
  repoInfo: evaluator.repoInfo,
11609
- dataset: Dataset2.isDataset(data) ? data : void 0
11732
+ dataset: Dataset2.isDataset(data) ? data : void 0,
11733
+ parameters
11610
11734
  });
11611
11735
  if (experiment && typeof process !== "undefined" && globalThis.BRAINTRUST_CONTEXT_MANAGER !== void 0) {
11612
11736
  await experiment._waitForId();
@@ -11661,7 +11785,7 @@ async function Eval(name, evaluator, reporterOrOpts) {
11661
11785
  if (experiment) {
11662
11786
  await experiment.flush().catch(console.error);
11663
11787
  } else if (options.parent) {
11664
- await flush().catch(console.error);
11788
+ await flush({ state: evaluator.state }).catch(console.error);
11665
11789
  }
11666
11790
  }
11667
11791
  } finally {
@@ -12056,6 +12180,7 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
12056
12180
  },
12057
12181
  Math.max(evaluator.maxConcurrency ?? Number.MAX_SAFE_INTEGER, 1)
12058
12182
  );
12183
+ const queueErrors = [];
12059
12184
  const enqueuePromise = (async () => {
12060
12185
  for await (const datum of dataIterable) {
12061
12186
  if (cancelled) {
@@ -12071,7 +12196,11 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
12071
12196
  }
12072
12197
  scheduledTrials++;
12073
12198
  progressReporter.setTotal?.(evaluator.evalName, scheduledTrials);
12074
- q.push({ datum, trialIndex });
12199
+ q.pushAsync({ datum, trialIndex }).catch((e) => {
12200
+ if (queueErrors.length < 5) {
12201
+ queueErrors.push(e);
12202
+ }
12203
+ });
12075
12204
  }
12076
12205
  }
12077
12206
  })();
@@ -12119,6 +12248,12 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
12119
12248
  })();
12120
12249
  try {
12121
12250
  await Promise.race([waitForQueue, cancel()]);
12251
+ if (queueErrors.length > 0) {
12252
+ throw new AggregateError(
12253
+ queueErrors,
12254
+ `Encountered ${queueErrors.length} unhandled task errors`
12255
+ );
12256
+ }
12122
12257
  } catch (e) {
12123
12258
  q.kill();
12124
12259
  if (e instanceof InternalAbortError) {
@@ -12472,6 +12607,64 @@ var fancyReporter = {
12472
12607
  var import_node_async_hooks = require("node:async_hooks");
12473
12608
  var diagnostics_channel = __toESM(require("node:diagnostics_channel"));
12474
12609
  var path = __toESM(require("node:path"));
12610
+
12611
+ // src/auto-instrumentations/patch-tracing-channel.ts
12612
+ function patchTracingChannel(tracingChannelFn) {
12613
+ const dummyChannel = tracingChannelFn("__braintrust_probe__");
12614
+ const TracingChannel = dummyChannel?.constructor;
12615
+ if (!TracingChannel?.prototype) {
12616
+ return;
12617
+ }
12618
+ if (!Object.getOwnPropertyDescriptor(TracingChannel.prototype, "hasSubscribers")) {
12619
+ Object.defineProperty(TracingChannel.prototype, "hasSubscribers", {
12620
+ configurable: true,
12621
+ enumerable: false,
12622
+ get() {
12623
+ return Boolean(
12624
+ this.start?.hasSubscribers || this.end?.hasSubscribers || this.asyncStart?.hasSubscribers || this.asyncEnd?.hasSubscribers || this.error?.hasSubscribers
12625
+ );
12626
+ }
12627
+ });
12628
+ }
12629
+ if (TracingChannel.prototype.tracePromise) {
12630
+ TracingChannel.prototype.tracePromise = function(fn, context2 = {}, thisArg, ...args) {
12631
+ const { start, end, asyncStart, asyncEnd, error: error2 } = this;
12632
+ function reject2(err) {
12633
+ context2.error = err;
12634
+ error2?.publish(context2);
12635
+ asyncStart?.publish(context2);
12636
+ asyncEnd?.publish(context2);
12637
+ return Promise.reject(err);
12638
+ }
12639
+ function resolve2(result) {
12640
+ context2.result = result;
12641
+ asyncStart?.publish(context2);
12642
+ asyncEnd?.publish(context2);
12643
+ return result;
12644
+ }
12645
+ return start.runStores(context2, () => {
12646
+ try {
12647
+ const result = Reflect.apply(fn, thisArg, args);
12648
+ end?.publish(context2);
12649
+ if (result && (typeof result === "object" || typeof result === "function") && typeof result.then === "function") {
12650
+ return result.then(resolve2, reject2);
12651
+ }
12652
+ context2.result = result;
12653
+ asyncStart?.publish(context2);
12654
+ asyncEnd?.publish(context2);
12655
+ return result;
12656
+ } catch (err) {
12657
+ context2.error = err;
12658
+ error2?.publish(context2);
12659
+ end?.publish(context2);
12660
+ throw err;
12661
+ }
12662
+ });
12663
+ };
12664
+ }
12665
+ }
12666
+
12667
+ // src/node/config.ts
12475
12668
  var fs = __toESM(require("node:fs/promises"));
12476
12669
  var os = __toESM(require("node:os"));
12477
12670
  var fsSync = __toESM(require("node:fs"));
@@ -13214,7 +13407,11 @@ function startSpanForEvent(config3, event, channelName) {
13214
13407
  });
13215
13408
  const startTime = getCurrentUnixTimestamp();
13216
13409
  try {
13217
- const { input, metadata } = config3.extractInput(event.arguments);
13410
+ const { input, metadata } = config3.extractInput(
13411
+ event.arguments,
13412
+ event,
13413
+ span
13414
+ );
13218
13415
  span.log({
13219
13416
  input,
13220
13417
  metadata: mergeInputMetadata(metadata, spanInfoMetadata)
@@ -13224,6 +13421,36 @@ function startSpanForEvent(config3, event, channelName) {
13224
13421
  }
13225
13422
  return { span, startTime };
13226
13423
  }
13424
+ function ensureSpanStateForEvent(states, config3, event, channelName) {
13425
+ const key = event;
13426
+ const existing = states.get(key);
13427
+ if (existing) {
13428
+ return existing;
13429
+ }
13430
+ const created = startSpanForEvent(config3, event, channelName);
13431
+ states.set(key, created);
13432
+ return created;
13433
+ }
13434
+ function bindCurrentSpanStoreToStart(tracingChannel2, states, config3, channelName) {
13435
+ const state = _internalGetGlobalState();
13436
+ const startChannel = tracingChannel2.start;
13437
+ const currentSpanStore = state?.contextManager ? state.contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
13438
+ if (!currentSpanStore || !startChannel) {
13439
+ return void 0;
13440
+ }
13441
+ startChannel.bindStore(
13442
+ currentSpanStore,
13443
+ (event) => ensureSpanStateForEvent(
13444
+ states,
13445
+ config3,
13446
+ event,
13447
+ channelName
13448
+ ).span
13449
+ );
13450
+ return () => {
13451
+ startChannel.unbindStore(currentSpanStore);
13452
+ };
13453
+ }
13227
13454
  function logErrorAndEnd(states, event) {
13228
13455
  const spanData = states.get(event);
13229
13456
  if (!spanData) {
@@ -13239,15 +13466,19 @@ function traceAsyncChannel(channel2, config3) {
13239
13466
  const tracingChannel2 = channel2.tracingChannel();
13240
13467
  const states = /* @__PURE__ */ new WeakMap();
13241
13468
  const channelName = channel2.channelName;
13469
+ const unbindCurrentSpanStore = bindCurrentSpanStoreToStart(
13470
+ tracingChannel2,
13471
+ states,
13472
+ config3,
13473
+ channelName
13474
+ );
13242
13475
  const handlers = {
13243
13476
  start: (event) => {
13244
- states.set(
13477
+ ensureSpanStateForEvent(
13478
+ states,
13479
+ config3,
13245
13480
  event,
13246
- startSpanForEvent(
13247
- config3,
13248
- event,
13249
- channelName
13250
- )
13481
+ channelName
13251
13482
  );
13252
13483
  },
13253
13484
  asyncEnd: (event) => {
@@ -13289,6 +13520,7 @@ function traceAsyncChannel(channel2, config3) {
13289
13520
  };
13290
13521
  tracingChannel2.subscribe(handlers);
13291
13522
  return () => {
13523
+ unbindCurrentSpanStore?.();
13292
13524
  tracingChannel2.unsubscribe(handlers);
13293
13525
  };
13294
13526
  }
@@ -13296,15 +13528,19 @@ function traceStreamingChannel(channel2, config3) {
13296
13528
  const tracingChannel2 = channel2.tracingChannel();
13297
13529
  const states = /* @__PURE__ */ new WeakMap();
13298
13530
  const channelName = channel2.channelName;
13531
+ const unbindCurrentSpanStore = bindCurrentSpanStoreToStart(
13532
+ tracingChannel2,
13533
+ states,
13534
+ config3,
13535
+ channelName
13536
+ );
13299
13537
  const handlers = {
13300
13538
  start: (event) => {
13301
- states.set(
13539
+ ensureSpanStateForEvent(
13540
+ states,
13541
+ config3,
13302
13542
  event,
13303
- startSpanForEvent(
13304
- config3,
13305
- event,
13306
- channelName
13307
- )
13543
+ channelName
13308
13544
  );
13309
13545
  },
13310
13546
  asyncEnd: (event) => {
@@ -13378,6 +13614,16 @@ function traceStreamingChannel(channel2, config3) {
13378
13614
  });
13379
13615
  return;
13380
13616
  }
13617
+ if (config3.patchResult?.({
13618
+ channelName,
13619
+ endEvent: asyncEndEvent,
13620
+ result: asyncEndEvent.result,
13621
+ span,
13622
+ startTime
13623
+ })) {
13624
+ states.delete(event);
13625
+ return;
13626
+ }
13381
13627
  try {
13382
13628
  const output = config3.extractOutput(
13383
13629
  asyncEndEvent.result,
@@ -13410,6 +13656,7 @@ function traceStreamingChannel(channel2, config3) {
13410
13656
  };
13411
13657
  tracingChannel2.subscribe(handlers);
13412
13658
  return () => {
13659
+ unbindCurrentSpanStore?.();
13413
13660
  tracingChannel2.unsubscribe(handlers);
13414
13661
  };
13415
13662
  }
@@ -13417,15 +13664,19 @@ function traceSyncStreamChannel(channel2, config3) {
13417
13664
  const tracingChannel2 = channel2.tracingChannel();
13418
13665
  const states = /* @__PURE__ */ new WeakMap();
13419
13666
  const channelName = channel2.channelName;
13667
+ const unbindCurrentSpanStore = bindCurrentSpanStoreToStart(
13668
+ tracingChannel2,
13669
+ states,
13670
+ config3,
13671
+ channelName
13672
+ );
13420
13673
  const handlers = {
13421
13674
  start: (event) => {
13422
- states.set(
13675
+ ensureSpanStateForEvent(
13676
+ states,
13677
+ config3,
13423
13678
  event,
13424
- startSpanForEvent(
13425
- config3,
13426
- event,
13427
- channelName
13428
- )
13679
+ channelName
13429
13680
  );
13430
13681
  },
13431
13682
  end: (event) => {
@@ -13434,8 +13685,17 @@ function traceSyncStreamChannel(channel2, config3) {
13434
13685
  return;
13435
13686
  }
13436
13687
  const { span, startTime } = spanData;
13437
- const resultEvent = event;
13438
- const stream = resultEvent.result;
13688
+ const endEvent = event;
13689
+ if (config3.patchResult?.({
13690
+ channelName,
13691
+ endEvent,
13692
+ result: endEvent.result,
13693
+ span,
13694
+ startTime
13695
+ })) {
13696
+ return;
13697
+ }
13698
+ const stream = endEvent.result;
13439
13699
  if (!isSyncStreamLike(stream)) {
13440
13700
  span.end();
13441
13701
  states.delete(event);
@@ -13505,6 +13765,7 @@ function traceSyncStreamChannel(channel2, config3) {
13505
13765
  };
13506
13766
  tracingChannel2.subscribe(handlers);
13507
13767
  return () => {
13768
+ unbindCurrentSpanStore?.();
13508
13769
  tracingChannel2.unsubscribe(handlers);
13509
13770
  };
13510
13771
  }
@@ -14406,6 +14667,108 @@ function filterFrom(obj, fieldsToRemove) {
14406
14667
  return result;
14407
14668
  }
14408
14669
 
14670
+ // src/wrappers/ai-sdk/normalize-logged-output.ts
14671
+ var REMOVE_NORMALIZED_VALUE = Symbol("braintrust.ai-sdk.remove-normalized");
14672
+ function normalizeAISDKLoggedOutput(value) {
14673
+ const normalized = normalizeAISDKLoggedValue(value);
14674
+ return normalized === REMOVE_NORMALIZED_VALUE ? {} : normalized;
14675
+ }
14676
+ function normalizeAISDKLoggedValue(value, context2 = {}) {
14677
+ if (Array.isArray(value)) {
14678
+ return value.map((entry) => normalizeAISDKLoggedValue(entry, context2)).filter((entry) => entry !== REMOVE_NORMALIZED_VALUE);
14679
+ }
14680
+ if (!value || typeof value !== "object") {
14681
+ return value;
14682
+ }
14683
+ const nextInProviderMetadata = context2.inProviderMetadata || context2.parentKey === "providerMetadata" || context2.parentKey === "experimental_providerMetadata";
14684
+ const normalizedEntries = [];
14685
+ for (const [key, entry] of Object.entries(value)) {
14686
+ if (key === "cachedPromptTokens" && entry === 0) {
14687
+ continue;
14688
+ }
14689
+ if (context2.parentKey === "request" && key === "body" && entry === "<omitted>") {
14690
+ continue;
14691
+ }
14692
+ const normalizedEntry = normalizeAISDKLoggedValue(entry, {
14693
+ inProviderMetadata: nextInProviderMetadata,
14694
+ parentKey: key
14695
+ });
14696
+ if (normalizedEntry === REMOVE_NORMALIZED_VALUE) {
14697
+ continue;
14698
+ }
14699
+ normalizedEntries.push([key, normalizedEntry]);
14700
+ }
14701
+ if (normalizedEntries.length === 0) {
14702
+ if (context2.parentKey === "request" || nextInProviderMetadata) {
14703
+ return REMOVE_NORMALIZED_VALUE;
14704
+ }
14705
+ return {};
14706
+ }
14707
+ return Object.fromEntries(normalizedEntries);
14708
+ }
14709
+
14710
+ // src/zod/utils.ts
14711
+ var import_zod_to_json_schema = require("zod-to-json-schema");
14712
+ var z42 = __toESM(require("zod/v4"));
14713
+ function isZodV4(zodObject) {
14714
+ return typeof zodObject === "object" && zodObject !== null && "_zod" in zodObject && zodObject._zod !== void 0;
14715
+ }
14716
+ function zodToJsonSchema(schema) {
14717
+ if (isZodV4(schema)) {
14718
+ return z42.toJSONSchema(schema, {
14719
+ target: "draft-7"
14720
+ });
14721
+ }
14722
+ return (0, import_zod_to_json_schema.zodToJsonSchema)(schema);
14723
+ }
14724
+
14725
+ // src/wrappers/ai-sdk/tool-serialization.ts
14726
+ function isZodSchema(value) {
14727
+ return value != null && typeof value === "object" && "_def" in value && typeof value._def === "object";
14728
+ }
14729
+ function serializeZodSchema(schema) {
14730
+ try {
14731
+ return zodToJsonSchema(schema);
14732
+ } catch {
14733
+ return {
14734
+ type: "object",
14735
+ description: "Zod schema (conversion failed)"
14736
+ };
14737
+ }
14738
+ }
14739
+ function serializeTool(tool) {
14740
+ if (!tool || typeof tool !== "object") {
14741
+ return tool;
14742
+ }
14743
+ const serialized = { ...tool };
14744
+ if (isZodSchema(serialized.inputSchema)) {
14745
+ serialized.inputSchema = serializeZodSchema(serialized.inputSchema);
14746
+ }
14747
+ if (isZodSchema(serialized.parameters)) {
14748
+ serialized.parameters = serializeZodSchema(serialized.parameters);
14749
+ }
14750
+ if ("execute" in serialized) {
14751
+ delete serialized.execute;
14752
+ }
14753
+ if ("render" in serialized) {
14754
+ delete serialized.render;
14755
+ }
14756
+ return serialized;
14757
+ }
14758
+ function serializeAISDKToolsForLogging(tools) {
14759
+ if (!tools || typeof tools !== "object") {
14760
+ return tools;
14761
+ }
14762
+ if (Array.isArray(tools)) {
14763
+ return tools.map(serializeTool);
14764
+ }
14765
+ const serialized = {};
14766
+ for (const [key, tool] of Object.entries(tools)) {
14767
+ serialized[key] = serializeTool(tool);
14768
+ }
14769
+ return serialized;
14770
+ }
14771
+
14409
14772
  // src/instrumentation/plugins/ai-sdk-channels.ts
14410
14773
  var aiSDKChannels = defineChannels("ai", {
14411
14774
  generateText: channel({
@@ -14416,6 +14779,10 @@ var aiSDKChannels = defineChannels("ai", {
14416
14779
  channelName: "streamText",
14417
14780
  kind: "async"
14418
14781
  }),
14782
+ streamTextSync: channel({
14783
+ channelName: "streamText.sync",
14784
+ kind: "sync-stream"
14785
+ }),
14419
14786
  generateObject: channel({
14420
14787
  channelName: "generateObject",
14421
14788
  kind: "async"
@@ -14424,6 +14791,10 @@ var aiSDKChannels = defineChannels("ai", {
14424
14791
  channelName: "streamObject",
14425
14792
  kind: "async"
14426
14793
  }),
14794
+ streamObjectSync: channel({
14795
+ channelName: "streamObject.sync",
14796
+ kind: "sync-stream"
14797
+ }),
14427
14798
  agentGenerate: channel({
14428
14799
  channelName: "Agent.generate",
14429
14800
  kind: "async"
@@ -14431,6 +14802,14 @@ var aiSDKChannels = defineChannels("ai", {
14431
14802
  agentStream: channel({
14432
14803
  channelName: "Agent.stream",
14433
14804
  kind: "async"
14805
+ }),
14806
+ toolLoopAgentGenerate: channel({
14807
+ channelName: "ToolLoopAgent.generate",
14808
+ kind: "async"
14809
+ }),
14810
+ toolLoopAgentStream: channel({
14811
+ channelName: "ToolLoopAgent.stream",
14812
+ kind: "async"
14434
14813
  })
14435
14814
  });
14436
14815
 
@@ -14449,6 +14828,8 @@ var DEFAULT_DENY_OUTPUT_PATHS = [
14449
14828
  "steps[].response.body",
14450
14829
  "steps[].response.headers"
14451
14830
  ];
14831
+ var AUTO_PATCHED_MODEL = Symbol.for("braintrust.ai-sdk.auto-patched-model");
14832
+ var AUTO_PATCHED_TOOL = Symbol.for("braintrust.ai-sdk.auto-patched-tool");
14452
14833
  var AISDKPlugin = class extends BasePlugin {
14453
14834
  config;
14454
14835
  constructor(config3 = {}) {
@@ -14467,22 +14848,12 @@ var AISDKPlugin = class extends BasePlugin {
14467
14848
  traceStreamingChannel(aiSDKChannels.generateText, {
14468
14849
  name: "generateText",
14469
14850
  type: "llm" /* LLM */,
14470
- extractInput: ([params]) => {
14471
- return {
14472
- input: processAISDKInput(params),
14473
- metadata: extractMetadataFromParams(params)
14474
- };
14475
- },
14476
- extractOutput: (result) => {
14851
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
14852
+ extractOutput: (result, endEvent) => {
14853
+ finalizeAISDKChildTracing(endEvent);
14477
14854
  return processAISDKOutput(result, denyOutputPaths);
14478
14855
  },
14479
- extractMetrics: (result, startTime) => {
14480
- const metrics = extractTokenMetrics(result);
14481
- if (startTime) {
14482
- metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
14483
- }
14484
- return metrics;
14485
- },
14856
+ extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
14486
14857
  aggregateChunks: aggregateAISDKChunks
14487
14858
  })
14488
14859
  );
@@ -14490,45 +14861,43 @@ var AISDKPlugin = class extends BasePlugin {
14490
14861
  traceStreamingChannel(aiSDKChannels.streamText, {
14491
14862
  name: "streamText",
14492
14863
  type: "llm" /* LLM */,
14493
- extractInput: ([params]) => {
14494
- return {
14495
- input: processAISDKInput(params),
14496
- metadata: extractMetadataFromParams(params)
14497
- };
14498
- },
14499
- extractOutput: (result) => {
14500
- return processAISDKOutput(result, denyOutputPaths);
14501
- },
14502
- extractMetrics: (result, startTime) => {
14503
- const metrics = extractTokenMetrics(result);
14504
- if (startTime) {
14505
- metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
14506
- }
14507
- return metrics;
14508
- },
14509
- aggregateChunks: aggregateAISDKChunks
14864
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
14865
+ extractOutput: (result) => processAISDKOutput(result, denyOutputPaths),
14866
+ extractMetrics: (result, startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent, startTime),
14867
+ aggregateChunks: aggregateAISDKChunks,
14868
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
14869
+ denyOutputPaths,
14870
+ endEvent,
14871
+ result,
14872
+ span,
14873
+ startTime
14874
+ })
14875
+ })
14876
+ );
14877
+ this.unsubscribers.push(
14878
+ traceSyncStreamChannel(aiSDKChannels.streamTextSync, {
14879
+ name: "streamText",
14880
+ type: "llm" /* LLM */,
14881
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
14882
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
14883
+ denyOutputPaths,
14884
+ endEvent,
14885
+ result,
14886
+ span,
14887
+ startTime
14888
+ })
14510
14889
  })
14511
14890
  );
14512
14891
  this.unsubscribers.push(
14513
14892
  traceStreamingChannel(aiSDKChannels.generateObject, {
14514
14893
  name: "generateObject",
14515
14894
  type: "llm" /* LLM */,
14516
- extractInput: ([params]) => {
14517
- return {
14518
- input: processAISDKInput(params),
14519
- metadata: extractMetadataFromParams(params)
14520
- };
14521
- },
14522
- extractOutput: (result) => {
14895
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
14896
+ extractOutput: (result, endEvent) => {
14897
+ finalizeAISDKChildTracing(endEvent);
14523
14898
  return processAISDKOutput(result, denyOutputPaths);
14524
14899
  },
14525
- extractMetrics: (result, startTime) => {
14526
- const metrics = extractTokenMetrics(result);
14527
- if (startTime) {
14528
- metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
14529
- }
14530
- return metrics;
14531
- },
14900
+ extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
14532
14901
  aggregateChunks: aggregateAISDKChunks
14533
14902
  })
14534
14903
  );
@@ -14536,45 +14905,43 @@ var AISDKPlugin = class extends BasePlugin {
14536
14905
  traceStreamingChannel(aiSDKChannels.streamObject, {
14537
14906
  name: "streamObject",
14538
14907
  type: "llm" /* LLM */,
14539
- extractInput: ([params]) => {
14540
- return {
14541
- input: processAISDKInput(params),
14542
- metadata: extractMetadataFromParams(params)
14543
- };
14544
- },
14545
- extractOutput: (result) => {
14546
- return processAISDKOutput(result, denyOutputPaths);
14547
- },
14548
- extractMetrics: (result, startTime) => {
14549
- const metrics = extractTokenMetrics(result);
14550
- if (startTime) {
14551
- metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
14552
- }
14553
- return metrics;
14554
- },
14555
- aggregateChunks: aggregateAISDKChunks
14908
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
14909
+ extractOutput: (result) => processAISDKOutput(result, denyOutputPaths),
14910
+ extractMetrics: (result, startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent, startTime),
14911
+ aggregateChunks: aggregateAISDKChunks,
14912
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
14913
+ denyOutputPaths,
14914
+ endEvent,
14915
+ result,
14916
+ span,
14917
+ startTime
14918
+ })
14919
+ })
14920
+ );
14921
+ this.unsubscribers.push(
14922
+ traceSyncStreamChannel(aiSDKChannels.streamObjectSync, {
14923
+ name: "streamObject",
14924
+ type: "llm" /* LLM */,
14925
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
14926
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
14927
+ denyOutputPaths,
14928
+ endEvent,
14929
+ result,
14930
+ span,
14931
+ startTime
14932
+ })
14556
14933
  })
14557
14934
  );
14558
14935
  this.unsubscribers.push(
14559
14936
  traceStreamingChannel(aiSDKChannels.agentGenerate, {
14560
14937
  name: "Agent.generate",
14561
14938
  type: "llm" /* LLM */,
14562
- extractInput: ([params]) => {
14563
- return {
14564
- input: processAISDKInput(params),
14565
- metadata: extractMetadataFromParams(params)
14566
- };
14567
- },
14568
- extractOutput: (result) => {
14939
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
14940
+ extractOutput: (result, endEvent) => {
14941
+ finalizeAISDKChildTracing(endEvent);
14569
14942
  return processAISDKOutput(result, denyOutputPaths);
14570
14943
  },
14571
- extractMetrics: (result, startTime) => {
14572
- const metrics = extractTokenMetrics(result);
14573
- if (startTime) {
14574
- metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
14575
- }
14576
- return metrics;
14577
- },
14944
+ extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
14578
14945
  aggregateChunks: aggregateAISDKChunks
14579
14946
  })
14580
14947
  );
@@ -14582,52 +14949,470 @@ var AISDKPlugin = class extends BasePlugin {
14582
14949
  traceStreamingChannel(aiSDKChannels.agentStream, {
14583
14950
  name: "Agent.stream",
14584
14951
  type: "llm" /* LLM */,
14585
- extractInput: ([params]) => {
14586
- return {
14587
- input: processAISDKInput(params),
14588
- metadata: extractMetadataFromParams(params)
14589
- };
14590
- },
14591
- extractOutput: (result) => {
14952
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
14953
+ extractOutput: (result) => processAISDKOutput(result, denyOutputPaths),
14954
+ extractMetrics: (result, startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent, startTime),
14955
+ aggregateChunks: aggregateAISDKChunks,
14956
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
14957
+ denyOutputPaths,
14958
+ endEvent,
14959
+ result,
14960
+ span,
14961
+ startTime
14962
+ })
14963
+ })
14964
+ );
14965
+ this.unsubscribers.push(
14966
+ traceStreamingChannel(aiSDKChannels.toolLoopAgentGenerate, {
14967
+ name: "ToolLoopAgent.generate",
14968
+ type: "llm" /* LLM */,
14969
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
14970
+ extractOutput: (result, endEvent) => {
14971
+ finalizeAISDKChildTracing(endEvent);
14592
14972
  return processAISDKOutput(result, denyOutputPaths);
14593
14973
  },
14594
- extractMetrics: (result, startTime) => {
14595
- const metrics = extractTokenMetrics(result);
14596
- if (startTime) {
14597
- metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
14598
- }
14599
- return metrics;
14600
- },
14974
+ extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
14601
14975
  aggregateChunks: aggregateAISDKChunks
14602
14976
  })
14603
14977
  );
14978
+ this.unsubscribers.push(
14979
+ traceStreamingChannel(aiSDKChannels.toolLoopAgentStream, {
14980
+ name: "ToolLoopAgent.stream",
14981
+ type: "llm" /* LLM */,
14982
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
14983
+ extractOutput: (result) => processAISDKOutput(result, denyOutputPaths),
14984
+ extractMetrics: (result, startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent, startTime),
14985
+ aggregateChunks: aggregateAISDKChunks,
14986
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
14987
+ denyOutputPaths,
14988
+ endEvent,
14989
+ result,
14990
+ span,
14991
+ startTime
14992
+ })
14993
+ })
14994
+ );
14604
14995
  }
14605
14996
  };
14606
14997
  function processAISDKInput(params) {
14607
14998
  if (!params) return params;
14608
- return processInputAttachments(params);
14999
+ const input = processInputAttachments(params);
15000
+ if (!input || typeof input !== "object" || Array.isArray(input)) {
15001
+ return input;
15002
+ }
15003
+ const { tools: _tools, ...rest } = input;
15004
+ return rest;
15005
+ }
15006
+ function prepareAISDKInput(params, event, span, denyOutputPaths) {
15007
+ const input = processAISDKInput(params);
15008
+ const metadata = extractMetadataFromParams(params, event.self);
15009
+ const childTracing = prepareAISDKChildTracing(
15010
+ params,
15011
+ event.self,
15012
+ span,
15013
+ denyOutputPaths
15014
+ );
15015
+ event.__braintrust_ai_sdk_model_wrapped = childTracing.modelWrapped;
15016
+ if (childTracing.cleanup) {
15017
+ event.__braintrust_ai_sdk_cleanup = childTracing.cleanup;
15018
+ }
15019
+ return {
15020
+ input,
15021
+ metadata
15022
+ };
14609
15023
  }
14610
- function extractMetadataFromParams(params) {
15024
+ function extractTopLevelAISDKMetrics(result, event, startTime) {
15025
+ const metrics = hasModelChildTracing(event) ? {} : extractTokenMetrics(result);
15026
+ if (startTime) {
15027
+ metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
15028
+ }
15029
+ return metrics;
15030
+ }
15031
+ function hasModelChildTracing(event) {
15032
+ return event?.__braintrust_ai_sdk_model_wrapped === true;
15033
+ }
15034
+ function extractMetadataFromParams(params, self) {
14611
15035
  const metadata = {
14612
15036
  braintrust: {
14613
15037
  integration_name: "ai-sdk",
14614
15038
  sdk_language: "typescript"
14615
15039
  }
14616
15040
  };
14617
- const { model, provider } = serializeModelWithProvider(params.model);
15041
+ 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;
15042
+ const { model, provider } = serializeModelWithProvider(
15043
+ params.model ?? agentModel
15044
+ );
14618
15045
  if (model) {
14619
15046
  metadata.model = model;
14620
15047
  }
14621
15048
  if (provider) {
14622
15049
  metadata.provider = provider;
14623
15050
  }
15051
+ const tools = serializeAISDKToolsForLogging(params.tools);
15052
+ if (tools) {
15053
+ metadata.tools = tools;
15054
+ }
14624
15055
  return metadata;
14625
15056
  }
15057
+ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths) {
15058
+ const cleanup = [];
15059
+ const patchedModels = /* @__PURE__ */ new WeakSet();
15060
+ const patchedTools = /* @__PURE__ */ new WeakSet();
15061
+ let modelWrapped = false;
15062
+ const patchModel = (model) => {
15063
+ const resolvedModel = resolveAISDKModel(model);
15064
+ if (!resolvedModel || typeof resolvedModel !== "object" || typeof resolvedModel.doGenerate !== "function" || patchedModels.has(resolvedModel) || resolvedModel[AUTO_PATCHED_MODEL]) {
15065
+ return;
15066
+ }
15067
+ patchedModels.add(resolvedModel);
15068
+ resolvedModel[AUTO_PATCHED_MODEL] = true;
15069
+ modelWrapped = true;
15070
+ const originalDoGenerate = resolvedModel.doGenerate;
15071
+ const originalDoStream = resolvedModel.doStream;
15072
+ const baseMetadata = buildAISDKChildMetadata(resolvedModel);
15073
+ resolvedModel.doGenerate = async function doGeneratePatched(options) {
15074
+ return parentSpan.traced(
15075
+ async (span) => {
15076
+ const result = await Reflect.apply(
15077
+ originalDoGenerate,
15078
+ resolvedModel,
15079
+ [options]
15080
+ );
15081
+ span.log({
15082
+ output: processAISDKOutput(result, denyOutputPaths),
15083
+ metrics: extractTokenMetrics(result),
15084
+ ...buildResolvedMetadataPayload(result)
15085
+ });
15086
+ return result;
15087
+ },
15088
+ {
15089
+ name: "doGenerate",
15090
+ spanAttributes: {
15091
+ type: "llm" /* LLM */
15092
+ },
15093
+ event: {
15094
+ input: processAISDKInput(options),
15095
+ metadata: baseMetadata
15096
+ }
15097
+ }
15098
+ );
15099
+ };
15100
+ if (originalDoStream) {
15101
+ resolvedModel.doStream = async function doStreamPatched(options) {
15102
+ const span = parentSpan.startSpan({
15103
+ name: "doStream",
15104
+ spanAttributes: {
15105
+ type: "llm" /* LLM */
15106
+ },
15107
+ event: {
15108
+ input: processAISDKInput(options),
15109
+ metadata: baseMetadata
15110
+ }
15111
+ });
15112
+ const result = await withCurrent(
15113
+ span,
15114
+ () => Reflect.apply(originalDoStream, resolvedModel, [options])
15115
+ );
15116
+ const output = {};
15117
+ let text = "";
15118
+ let reasoning = "";
15119
+ const toolCalls = [];
15120
+ let object = void 0;
15121
+ const transformStream = new TransformStream({
15122
+ transform(chunk, controller) {
15123
+ switch (chunk.type) {
15124
+ case "text-delta":
15125
+ text += extractTextDelta(chunk);
15126
+ break;
15127
+ case "reasoning-delta":
15128
+ if (chunk.delta) {
15129
+ reasoning += chunk.delta;
15130
+ } else if (chunk.text) {
15131
+ reasoning += chunk.text;
15132
+ }
15133
+ break;
15134
+ case "tool-call":
15135
+ toolCalls.push(chunk);
15136
+ break;
15137
+ case "object":
15138
+ object = chunk.object;
15139
+ break;
15140
+ case "raw":
15141
+ if (chunk.rawValue) {
15142
+ const rawVal = chunk.rawValue;
15143
+ if (rawVal.delta?.content) {
15144
+ text += rawVal.delta.content;
15145
+ } else if (rawVal.choices?.[0]?.delta?.content) {
15146
+ text += rawVal.choices[0].delta.content;
15147
+ } else if (typeof rawVal.text === "string") {
15148
+ text += rawVal.text;
15149
+ } else if (typeof rawVal.content === "string") {
15150
+ text += rawVal.content;
15151
+ }
15152
+ }
15153
+ break;
15154
+ case "finish":
15155
+ output.text = text;
15156
+ output.reasoning = reasoning;
15157
+ output.toolCalls = toolCalls;
15158
+ output.finishReason = chunk.finishReason;
15159
+ output.usage = chunk.usage;
15160
+ if (object !== void 0) {
15161
+ output.object = object;
15162
+ }
15163
+ span.log({
15164
+ output: processAISDKOutput(
15165
+ output,
15166
+ denyOutputPaths
15167
+ ),
15168
+ metrics: extractTokenMetrics(output),
15169
+ ...buildResolvedMetadataPayload(output)
15170
+ });
15171
+ span.end();
15172
+ break;
15173
+ }
15174
+ controller.enqueue(chunk);
15175
+ }
15176
+ });
15177
+ return {
15178
+ ...result,
15179
+ stream: result.stream.pipeThrough(transformStream)
15180
+ };
15181
+ };
15182
+ }
15183
+ cleanup.push(() => {
15184
+ resolvedModel.doGenerate = originalDoGenerate;
15185
+ if (originalDoStream) {
15186
+ resolvedModel.doStream = originalDoStream;
15187
+ }
15188
+ delete resolvedModel[AUTO_PATCHED_MODEL];
15189
+ });
15190
+ };
15191
+ const patchTool = (tool, name) => {
15192
+ if (tool == null || typeof tool !== "object" || !("execute" in tool) || typeof tool.execute !== "function" || patchedTools.has(tool) || tool[AUTO_PATCHED_TOOL]) {
15193
+ return;
15194
+ }
15195
+ patchedTools.add(tool);
15196
+ tool[AUTO_PATCHED_TOOL] = true;
15197
+ const originalExecute = tool.execute;
15198
+ tool.execute = function executePatched(...args) {
15199
+ const result = Reflect.apply(originalExecute, this, args);
15200
+ if (isAsyncGenerator2(result)) {
15201
+ return (async function* () {
15202
+ const span = parentSpan.startSpan({
15203
+ name,
15204
+ spanAttributes: {
15205
+ type: "tool" /* TOOL */
15206
+ }
15207
+ });
15208
+ span.log({ input: args.length === 1 ? args[0] : args });
15209
+ try {
15210
+ let lastValue;
15211
+ for await (const value of result) {
15212
+ lastValue = value;
15213
+ yield value;
15214
+ }
15215
+ span.log({ output: lastValue });
15216
+ } catch (error2) {
15217
+ span.log({
15218
+ error: error2 instanceof Error ? error2.message : String(error2)
15219
+ });
15220
+ throw error2;
15221
+ } finally {
15222
+ span.end();
15223
+ }
15224
+ })();
15225
+ }
15226
+ return parentSpan.traced(
15227
+ async (span) => {
15228
+ span.log({ input: args.length === 1 ? args[0] : args });
15229
+ const awaitedResult = await result;
15230
+ span.log({ output: awaitedResult });
15231
+ return awaitedResult;
15232
+ },
15233
+ {
15234
+ name,
15235
+ spanAttributes: {
15236
+ type: "tool" /* TOOL */
15237
+ }
15238
+ }
15239
+ );
15240
+ };
15241
+ cleanup.push(() => {
15242
+ tool.execute = originalExecute;
15243
+ delete tool[AUTO_PATCHED_TOOL];
15244
+ });
15245
+ };
15246
+ const patchTools = (tools) => {
15247
+ if (!tools) {
15248
+ return;
15249
+ }
15250
+ const inferName = (tool, fallback2) => tool && (tool.name || tool.toolName || tool.id) || fallback2;
15251
+ if (Array.isArray(tools)) {
15252
+ tools.forEach(
15253
+ (tool, index) => patchTool(tool, inferName(tool, `tool[${index}]`))
15254
+ );
15255
+ return;
15256
+ }
15257
+ for (const [key, tool] of Object.entries(tools)) {
15258
+ patchTool(tool, key);
15259
+ }
15260
+ };
15261
+ if (params && typeof params === "object") {
15262
+ patchModel(params.model);
15263
+ patchTools(params.tools);
15264
+ }
15265
+ if (self && typeof self === "object") {
15266
+ const selfRecord = self;
15267
+ if (selfRecord.model !== void 0) {
15268
+ patchModel(selfRecord.model);
15269
+ }
15270
+ if (selfRecord.settings && typeof selfRecord.settings === "object") {
15271
+ if (selfRecord.settings.model !== void 0) {
15272
+ patchModel(selfRecord.settings.model);
15273
+ }
15274
+ if (selfRecord.settings.tools !== void 0) {
15275
+ patchTools(selfRecord.settings.tools);
15276
+ }
15277
+ }
15278
+ }
15279
+ return {
15280
+ cleanup: cleanup.length > 0 ? () => {
15281
+ while (cleanup.length > 0) {
15282
+ cleanup.pop()?.();
15283
+ }
15284
+ } : void 0,
15285
+ modelWrapped
15286
+ };
15287
+ }
15288
+ function finalizeAISDKChildTracing(event) {
15289
+ const cleanup = event?.__braintrust_ai_sdk_cleanup;
15290
+ if (event && typeof cleanup === "function") {
15291
+ cleanup();
15292
+ delete event.__braintrust_ai_sdk_cleanup;
15293
+ }
15294
+ }
15295
+ function patchAISDKStreamingResult(args) {
15296
+ const { denyOutputPaths, endEvent, result, span, startTime } = args;
15297
+ if (!result || typeof result !== "object") {
15298
+ return false;
15299
+ }
15300
+ const resultRecord = result;
15301
+ if (!isReadableStreamLike(resultRecord.baseStream)) {
15302
+ return false;
15303
+ }
15304
+ let firstChunkTime;
15305
+ const wrappedBaseStream = resultRecord.baseStream.pipeThrough(
15306
+ new TransformStream({
15307
+ transform(chunk, controller) {
15308
+ if (firstChunkTime === void 0) {
15309
+ firstChunkTime = getCurrentUnixTimestamp();
15310
+ }
15311
+ controller.enqueue(chunk);
15312
+ },
15313
+ async flush() {
15314
+ const metrics = extractTopLevelAISDKMetrics(result, endEvent);
15315
+ if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
15316
+ metrics.time_to_first_token = firstChunkTime - startTime;
15317
+ }
15318
+ const output = await processAISDKStreamingOutput(
15319
+ result,
15320
+ denyOutputPaths
15321
+ );
15322
+ const metadata = buildResolvedMetadataPayload(result).metadata;
15323
+ span.log({
15324
+ output,
15325
+ ...metadata ? { metadata } : {},
15326
+ metrics
15327
+ });
15328
+ finalizeAISDKChildTracing(endEvent);
15329
+ span.end();
15330
+ }
15331
+ })
15332
+ );
15333
+ Object.defineProperty(resultRecord, "baseStream", {
15334
+ configurable: true,
15335
+ enumerable: true,
15336
+ value: wrappedBaseStream,
15337
+ writable: true
15338
+ });
15339
+ return true;
15340
+ }
15341
+ function isReadableStreamLike(value) {
15342
+ return value != null && typeof value === "object" && typeof value.pipeThrough === "function";
15343
+ }
15344
+ async function processAISDKStreamingOutput(result, denyOutputPaths) {
15345
+ const output = processAISDKOutput(result, denyOutputPaths);
15346
+ if (!output || typeof output !== "object") {
15347
+ return output;
15348
+ }
15349
+ const outputRecord = output;
15350
+ try {
15351
+ if ("text" in result && typeof result.text === "string") {
15352
+ outputRecord.text = result.text;
15353
+ }
15354
+ } catch {
15355
+ }
15356
+ try {
15357
+ if ("object" in result) {
15358
+ const resolvedObject = await Promise.resolve(result.object);
15359
+ if (resolvedObject !== void 0) {
15360
+ outputRecord.object = resolvedObject;
15361
+ }
15362
+ }
15363
+ } catch {
15364
+ }
15365
+ return outputRecord;
15366
+ }
15367
+ function buildAISDKChildMetadata(model) {
15368
+ const { model: modelId, provider } = serializeModelWithProvider(model);
15369
+ return {
15370
+ ...modelId ? { model: modelId } : {},
15371
+ ...provider ? { provider } : {},
15372
+ braintrust: {
15373
+ integration_name: "ai-sdk",
15374
+ sdk_language: "typescript"
15375
+ }
15376
+ };
15377
+ }
15378
+ function buildResolvedMetadataPayload(result) {
15379
+ const gatewayInfo = extractGatewayRoutingInfo(result);
15380
+ const metadata = {};
15381
+ if (gatewayInfo?.provider) {
15382
+ metadata.provider = gatewayInfo.provider;
15383
+ }
15384
+ if (gatewayInfo?.model) {
15385
+ metadata.model = gatewayInfo.model;
15386
+ }
15387
+ if (result.finishReason !== void 0) {
15388
+ metadata.finish_reason = result.finishReason;
15389
+ }
15390
+ return Object.keys(metadata).length > 0 ? { metadata } : {};
15391
+ }
15392
+ function resolveAISDKModel(model) {
15393
+ if (typeof model !== "string") {
15394
+ return model;
15395
+ }
15396
+ const provider = globalThis.AI_SDK_DEFAULT_PROVIDER ?? null;
15397
+ if (provider && typeof provider.languageModel === "function") {
15398
+ return provider.languageModel(model);
15399
+ }
15400
+ return model;
15401
+ }
15402
+ function extractTextDelta(chunk) {
15403
+ if (typeof chunk.textDelta === "string") return chunk.textDelta;
15404
+ if (typeof chunk.delta === "string") return chunk.delta;
15405
+ if (typeof chunk.text === "string") return chunk.text;
15406
+ if (typeof chunk.content === "string") return chunk.content;
15407
+ return "";
15408
+ }
15409
+ function isAsyncGenerator2(value) {
15410
+ return value != null && typeof value === "object" && typeof value[Symbol.asyncIterator] === "function" && typeof value.next === "function" && typeof value.return === "function" && typeof value.throw === "function";
15411
+ }
14626
15412
  function processAISDKOutput(output, denyOutputPaths) {
14627
15413
  if (!output) return output;
14628
- const getterValues = extractGetterValues(output);
14629
- const merged = { ...output, ...getterValues };
14630
- return omit(merged, denyOutputPaths);
15414
+ const merged = extractSerializableOutputFields(output);
15415
+ return normalizeAISDKLoggedOutput(omit(merged, denyOutputPaths));
14631
15416
  }
14632
15417
  function extractTokenMetrics(result) {
14633
15418
  const metrics = {};
@@ -14677,12 +15462,14 @@ function extractTokenMetrics(result) {
14677
15462
  }
14678
15463
  return metrics;
14679
15464
  }
14680
- function aggregateAISDKChunks(chunks) {
15465
+ function aggregateAISDKChunks(chunks, _result, endEvent) {
14681
15466
  const lastChunk = chunks[chunks.length - 1];
14682
15467
  const output = {};
14683
15468
  let metrics = {};
15469
+ let metadata;
14684
15470
  if (lastChunk) {
14685
- metrics = extractTokenMetrics(lastChunk);
15471
+ metrics = hasModelChildTracing(endEvent) ? {} : extractTokenMetrics(lastChunk);
15472
+ metadata = buildResolvedMetadataPayload(lastChunk).metadata;
14686
15473
  if (lastChunk.text !== void 0) {
14687
15474
  output.text = lastChunk.text;
14688
15475
  }
@@ -14696,7 +15483,8 @@ function aggregateAISDKChunks(chunks) {
14696
15483
  output.toolCalls = lastChunk.toolCalls;
14697
15484
  }
14698
15485
  }
14699
- return { output, metrics };
15486
+ finalizeAISDKChildTracing(endEvent);
15487
+ return { output, metrics, metadata };
14700
15488
  }
14701
15489
  function extractGetterValues(obj) {
14702
15490
  const getterValues = {};
@@ -14716,7 +15504,7 @@ function extractGetterValues(obj) {
14716
15504
  ];
14717
15505
  for (const name of getterNames) {
14718
15506
  try {
14719
- if (obj && name in obj && typeof obj[name] !== "function") {
15507
+ if (obj && name in obj && isSerializableOutputValue(obj[name])) {
14720
15508
  getterValues[name] = obj[name];
14721
15509
  }
14722
15510
  } catch {
@@ -14724,6 +15512,47 @@ function extractGetterValues(obj) {
14724
15512
  }
14725
15513
  return getterValues;
14726
15514
  }
15515
+ function extractSerializableOutputFields(output) {
15516
+ const serialized = {};
15517
+ const directFieldNames = [
15518
+ "steps",
15519
+ "request",
15520
+ "responseMessages",
15521
+ "warnings",
15522
+ "rawResponse",
15523
+ "response",
15524
+ "providerMetadata",
15525
+ "experimental_providerMetadata"
15526
+ ];
15527
+ for (const name of directFieldNames) {
15528
+ try {
15529
+ const value = output?.[name];
15530
+ if (isSerializableOutputValue(value)) {
15531
+ serialized[name] = value;
15532
+ }
15533
+ } catch {
15534
+ }
15535
+ }
15536
+ return {
15537
+ ...serialized,
15538
+ ...extractGetterValues(output)
15539
+ };
15540
+ }
15541
+ function isSerializableOutputValue(value) {
15542
+ if (typeof value === "function") {
15543
+ return false;
15544
+ }
15545
+ if (value && typeof value === "object" && typeof value.then === "function") {
15546
+ return false;
15547
+ }
15548
+ if (value && typeof value === "object" && typeof value.getReader === "function") {
15549
+ return false;
15550
+ }
15551
+ if (value && typeof value === "object" && typeof value[Symbol.asyncIterator] === "function") {
15552
+ return false;
15553
+ }
15554
+ return true;
15555
+ }
14727
15556
  function serializeModelWithProvider(model) {
14728
15557
  const modelId = typeof model === "string" ? model : model?.modelId;
14729
15558
  const explicitProvider = typeof model === "object" ? model?.provider : void 0;
@@ -14749,6 +15578,25 @@ function parseGatewayModelString(modelString) {
14749
15578
  }
14750
15579
  return { model: modelString };
14751
15580
  }
15581
+ function extractGatewayRoutingInfo(result) {
15582
+ if (result?.steps && Array.isArray(result.steps) && result.steps.length > 0) {
15583
+ const routing2 = result.steps[0]?.providerMetadata?.gateway?.routing;
15584
+ if (routing2) {
15585
+ return {
15586
+ provider: routing2.resolvedProvider || routing2.finalProvider,
15587
+ model: routing2.resolvedProviderApiModelId
15588
+ };
15589
+ }
15590
+ }
15591
+ const routing = result?.providerMetadata?.gateway?.routing;
15592
+ if (routing) {
15593
+ return {
15594
+ provider: routing.resolvedProvider || routing.finalProvider,
15595
+ model: routing.resolvedProviderApiModelId
15596
+ };
15597
+ }
15598
+ return null;
15599
+ }
14752
15600
  function extractCostFromResult(result) {
14753
15601
  if (result?.steps && Array.isArray(result.steps) && result.steps.length > 0) {
14754
15602
  let totalCost = 0;
@@ -15352,131 +16200,1148 @@ function extractMetadata(params) {
15352
16200
  }
15353
16201
  return metadata;
15354
16202
  }
15355
- function extractGenerateContentMetrics(response, startTime) {
15356
- const metrics = {};
15357
- if (startTime) {
15358
- const end = getCurrentUnixTimestamp();
15359
- metrics.duration = end - startTime;
15360
- }
15361
- if (response?.usageMetadata) {
15362
- populateUsageMetrics(metrics, response.usageMetadata);
15363
- }
15364
- return metrics;
16203
+ function extractGenerateContentMetrics(response, startTime) {
16204
+ const metrics = {};
16205
+ if (startTime) {
16206
+ const end = getCurrentUnixTimestamp();
16207
+ metrics.duration = end - startTime;
16208
+ }
16209
+ if (response?.usageMetadata) {
16210
+ populateUsageMetrics(metrics, response.usageMetadata);
16211
+ }
16212
+ return metrics;
16213
+ }
16214
+ function populateUsageMetrics(metrics, usage) {
16215
+ if (usage.promptTokenCount !== void 0) {
16216
+ metrics.prompt_tokens = usage.promptTokenCount;
16217
+ }
16218
+ if (usage.candidatesTokenCount !== void 0) {
16219
+ metrics.completion_tokens = usage.candidatesTokenCount;
16220
+ }
16221
+ if (usage.totalTokenCount !== void 0) {
16222
+ metrics.tokens = usage.totalTokenCount;
16223
+ }
16224
+ if (usage.cachedContentTokenCount !== void 0) {
16225
+ metrics.prompt_cached_tokens = usage.cachedContentTokenCount;
16226
+ }
16227
+ if (usage.thoughtsTokenCount !== void 0) {
16228
+ metrics.completion_reasoning_tokens = usage.thoughtsTokenCount;
16229
+ }
16230
+ }
16231
+ function aggregateGenerateContentChunks(chunks, startTime) {
16232
+ const metrics = {};
16233
+ if (startTime !== void 0) {
16234
+ const end = getCurrentUnixTimestamp();
16235
+ metrics.duration = end - startTime;
16236
+ }
16237
+ let firstTokenTime = null;
16238
+ if (chunks.length > 0 && firstTokenTime === null && startTime !== void 0) {
16239
+ firstTokenTime = getCurrentUnixTimestamp();
16240
+ metrics.time_to_first_token = firstTokenTime - startTime;
16241
+ }
16242
+ if (chunks.length === 0) {
16243
+ return { output: {}, metrics };
16244
+ }
16245
+ let text = "";
16246
+ let thoughtText = "";
16247
+ const otherParts = [];
16248
+ let usageMetadata = null;
16249
+ let lastResponse = null;
16250
+ for (const chunk of chunks) {
16251
+ lastResponse = chunk;
16252
+ if (chunk.usageMetadata) {
16253
+ usageMetadata = chunk.usageMetadata;
16254
+ }
16255
+ if (chunk.candidates && Array.isArray(chunk.candidates)) {
16256
+ for (const candidate of chunk.candidates) {
16257
+ if (candidate.content?.parts) {
16258
+ for (const part of candidate.content.parts) {
16259
+ if (part.text !== void 0) {
16260
+ if (part.thought) {
16261
+ thoughtText += part.text;
16262
+ } else {
16263
+ text += part.text;
16264
+ }
16265
+ } else if (part.functionCall) {
16266
+ otherParts.push({ functionCall: part.functionCall });
16267
+ } else if (part.codeExecutionResult) {
16268
+ otherParts.push({
16269
+ codeExecutionResult: part.codeExecutionResult
16270
+ });
16271
+ } else if (part.executableCode) {
16272
+ otherParts.push({ executableCode: part.executableCode });
16273
+ }
16274
+ }
16275
+ }
16276
+ }
16277
+ }
16278
+ }
16279
+ const output = {};
16280
+ const parts = [];
16281
+ if (thoughtText) {
16282
+ parts.push({ text: thoughtText, thought: true });
16283
+ }
16284
+ if (text) {
16285
+ parts.push({ text });
16286
+ }
16287
+ parts.push(...otherParts);
16288
+ if (parts.length > 0 && lastResponse?.candidates) {
16289
+ const candidates = [];
16290
+ for (const candidate of lastResponse.candidates) {
16291
+ const candidateDict = {
16292
+ content: {
16293
+ parts,
16294
+ role: "model"
16295
+ }
16296
+ };
16297
+ if (candidate.finishReason !== void 0) {
16298
+ candidateDict.finishReason = candidate.finishReason;
16299
+ }
16300
+ if (candidate.safetyRatings) {
16301
+ candidateDict.safetyRatings = candidate.safetyRatings;
16302
+ }
16303
+ candidates.push(candidateDict);
16304
+ }
16305
+ output.candidates = candidates;
16306
+ }
16307
+ if (usageMetadata) {
16308
+ output.usageMetadata = usageMetadata;
16309
+ populateUsageMetrics(metrics, usageMetadata);
16310
+ }
16311
+ if (text) {
16312
+ output.text = text;
16313
+ }
16314
+ return { output, metrics };
16315
+ }
16316
+ function tryToDict(obj) {
16317
+ if (obj === null || obj === void 0) {
16318
+ return null;
16319
+ }
16320
+ if (typeof obj === "object") {
16321
+ if ("toJSON" in obj && // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
16322
+ typeof obj.toJSON === "function") {
16323
+ return obj.toJSON();
16324
+ }
16325
+ return obj;
16326
+ }
16327
+ return null;
16328
+ }
16329
+
16330
+ // src/instrumentation/plugins/openrouter-channels.ts
16331
+ var openRouterChannels = defineChannels("@openrouter/sdk", {
16332
+ chatSend: channel({
16333
+ channelName: "chat.send",
16334
+ kind: "async"
16335
+ }),
16336
+ embeddingsGenerate: channel({
16337
+ channelName: "embeddings.generate",
16338
+ kind: "async"
16339
+ }),
16340
+ betaResponsesSend: channel({
16341
+ channelName: "beta.responses.send",
16342
+ kind: "async"
16343
+ }),
16344
+ callModel: channel({
16345
+ channelName: "callModel",
16346
+ kind: "sync-stream"
16347
+ }),
16348
+ toolExecute: channel({
16349
+ channelName: "tool.execute",
16350
+ kind: "async"
16351
+ })
16352
+ });
16353
+
16354
+ // src/openrouter-utils.ts
16355
+ var TOKEN_NAME_MAP2 = {
16356
+ promptTokens: "prompt_tokens",
16357
+ inputTokens: "prompt_tokens",
16358
+ completionTokens: "completion_tokens",
16359
+ outputTokens: "completion_tokens",
16360
+ totalTokens: "tokens",
16361
+ prompt_tokens: "prompt_tokens",
16362
+ input_tokens: "prompt_tokens",
16363
+ completion_tokens: "completion_tokens",
16364
+ output_tokens: "completion_tokens",
16365
+ total_tokens: "tokens"
16366
+ };
16367
+ var TOKEN_DETAIL_PREFIX_MAP = {
16368
+ promptTokensDetails: "prompt",
16369
+ inputTokensDetails: "prompt",
16370
+ completionTokensDetails: "completion",
16371
+ outputTokensDetails: "completion",
16372
+ costDetails: "cost",
16373
+ prompt_tokens_details: "prompt",
16374
+ input_tokens_details: "prompt",
16375
+ completion_tokens_details: "completion",
16376
+ output_tokens_details: "completion",
16377
+ cost_details: "cost"
16378
+ };
16379
+ function camelToSnake(value) {
16380
+ return value.replace(/[A-Z]/g, (match) => `_${match.toLowerCase()}`);
16381
+ }
16382
+ function parseOpenRouterMetricsFromUsage(usage) {
16383
+ if (!isObject(usage)) {
16384
+ return {};
16385
+ }
16386
+ const metrics = {};
16387
+ for (const [name, value] of Object.entries(usage)) {
16388
+ if (typeof value === "number") {
16389
+ metrics[TOKEN_NAME_MAP2[name] || camelToSnake(name)] = value;
16390
+ continue;
16391
+ }
16392
+ if (!isObject(value)) {
16393
+ continue;
16394
+ }
16395
+ const prefix = TOKEN_DETAIL_PREFIX_MAP[name];
16396
+ if (!prefix) {
16397
+ continue;
16398
+ }
16399
+ for (const [nestedName, nestedValue] of Object.entries(value)) {
16400
+ if (typeof nestedValue !== "number") {
16401
+ continue;
16402
+ }
16403
+ metrics[`${prefix}_${camelToSnake(nestedName)}`] = nestedValue;
16404
+ }
16405
+ }
16406
+ return metrics;
16407
+ }
16408
+ function extractOpenRouterUsageMetadata(usage) {
16409
+ if (!isObject(usage)) {
16410
+ return void 0;
16411
+ }
16412
+ const metadata = {};
16413
+ if (typeof usage.isByok === "boolean") {
16414
+ metadata.is_byok = usage.isByok;
16415
+ } else if (typeof usage.is_byok === "boolean") {
16416
+ metadata.is_byok = usage.is_byok;
16417
+ }
16418
+ return Object.keys(metadata).length > 0 ? metadata : void 0;
16419
+ }
16420
+
16421
+ // src/openrouter-logging.ts
16422
+ var OMITTED_OPENROUTER_KEYS = /* @__PURE__ */ new Set([
16423
+ "execute",
16424
+ "render",
16425
+ "nextTurnParams",
16426
+ "requireApproval"
16427
+ ]);
16428
+ function parseOpenRouterModelString(model) {
16429
+ if (typeof model !== "string") {
16430
+ return { model };
16431
+ }
16432
+ const slashIndex = model.indexOf("/");
16433
+ if (slashIndex > 0 && slashIndex < model.length - 1) {
16434
+ return {
16435
+ provider: model.substring(0, slashIndex),
16436
+ model: model.substring(slashIndex + 1)
16437
+ };
16438
+ }
16439
+ return { model };
16440
+ }
16441
+ function isZodSchema2(value) {
16442
+ return value != null && typeof value === "object" && "_def" in value && typeof value._def === "object";
16443
+ }
16444
+ function serializeZodSchema2(schema) {
16445
+ try {
16446
+ return zodToJsonSchema(schema);
16447
+ } catch {
16448
+ return {
16449
+ type: "object",
16450
+ description: "Zod schema (conversion failed)"
16451
+ };
16452
+ }
16453
+ }
16454
+ function serializeOpenRouterTool(tool) {
16455
+ if (!isObject(tool)) {
16456
+ return tool;
16457
+ }
16458
+ const serialized = {};
16459
+ for (const [key, value] of Object.entries(tool)) {
16460
+ if (OMITTED_OPENROUTER_KEYS.has(key)) {
16461
+ continue;
16462
+ }
16463
+ if (key === "function" && isObject(value)) {
16464
+ serialized.function = sanitizeOpenRouterLoggedValue(value);
16465
+ continue;
16466
+ }
16467
+ serialized[key] = sanitizeOpenRouterLoggedValue(value);
16468
+ }
16469
+ return serialized;
16470
+ }
16471
+ function serializeOpenRouterToolsForLogging(tools) {
16472
+ if (!Array.isArray(tools)) {
16473
+ return void 0;
16474
+ }
16475
+ return tools.map((tool) => serializeOpenRouterTool(tool));
16476
+ }
16477
+ function sanitizeOpenRouterLoggedValue(value) {
16478
+ if (isZodSchema2(value)) {
16479
+ return serializeZodSchema2(value);
16480
+ }
16481
+ if (typeof value === "function") {
16482
+ return "[Function]";
16483
+ }
16484
+ if (Array.isArray(value)) {
16485
+ return value.map((entry) => sanitizeOpenRouterLoggedValue(entry));
16486
+ }
16487
+ if (!isObject(value)) {
16488
+ return value;
16489
+ }
16490
+ const sanitized = {};
16491
+ for (const [key, entry] of Object.entries(value)) {
16492
+ if (OMITTED_OPENROUTER_KEYS.has(key)) {
16493
+ continue;
16494
+ }
16495
+ if (key === "tools" && Array.isArray(entry)) {
16496
+ sanitized.tools = serializeOpenRouterToolsForLogging(entry);
16497
+ continue;
16498
+ }
16499
+ sanitized[key] = sanitizeOpenRouterLoggedValue(entry);
16500
+ }
16501
+ return sanitized;
16502
+ }
16503
+ function buildOpenRouterMetadata(metadata, httpReferer, xTitle) {
16504
+ const sanitized = sanitizeOpenRouterLoggedValue(metadata);
16505
+ const metadataRecord = isObject(sanitized) ? sanitized : {};
16506
+ const { model, provider: providerRouting, ...rest } = metadataRecord;
16507
+ const normalizedModel = parseOpenRouterModelString(model);
16508
+ return {
16509
+ ...rest,
16510
+ ...normalizedModel.model !== void 0 ? { model: normalizedModel.model } : {},
16511
+ ...providerRouting !== void 0 ? { providerRouting } : {},
16512
+ ...httpReferer !== void 0 ? { httpReferer } : {},
16513
+ ...xTitle !== void 0 ? { xTitle } : {},
16514
+ provider: normalizedModel.provider || "openrouter"
16515
+ };
16516
+ }
16517
+ function buildOpenRouterEmbeddingMetadata(metadata, httpReferer, xTitle) {
16518
+ const normalized = buildOpenRouterMetadata(metadata, httpReferer, xTitle);
16519
+ return typeof normalized.model === "string" ? {
16520
+ ...normalized,
16521
+ embedding_model: normalized.model
16522
+ } : normalized;
16523
+ }
16524
+ function extractOpenRouterCallModelInput(request) {
16525
+ return isObject(request) && "input" in request ? sanitizeOpenRouterLoggedValue(request.input) : void 0;
16526
+ }
16527
+ function extractOpenRouterCallModelMetadata(request) {
16528
+ if (!isObject(request)) {
16529
+ return { provider: "openrouter" };
16530
+ }
16531
+ const { input: _input, ...metadata } = request;
16532
+ return buildOpenRouterMetadata(metadata, void 0, void 0);
16533
+ }
16534
+ function extractOpenRouterResponseMetadata(result) {
16535
+ if (!isObject(result)) {
16536
+ return void 0;
16537
+ }
16538
+ const { output: _output, data: _data, usage, ...metadata } = result;
16539
+ const sanitized = sanitizeOpenRouterLoggedValue(metadata);
16540
+ const metadataRecord = isObject(sanitized) ? sanitized : {};
16541
+ const { model, provider, ...rest } = metadataRecord;
16542
+ const normalizedModel = parseOpenRouterModelString(model);
16543
+ const normalizedProvider = (typeof provider === "string" ? provider : void 0) || normalizedModel.provider;
16544
+ const usageMetadata = extractOpenRouterUsageMetadata(usage);
16545
+ const combined = {
16546
+ ...rest,
16547
+ ...normalizedModel.model !== void 0 ? { model: normalizedModel.model } : {},
16548
+ ...usageMetadata || {},
16549
+ ...normalizedProvider !== void 0 ? { provider: normalizedProvider } : {}
16550
+ };
16551
+ return Object.keys(combined).length > 0 ? combined : void 0;
16552
+ }
16553
+ function extractOpenRouterResponseOutput(response, fallbackOutput) {
16554
+ if (isObject(response) && "output" in response && response.output !== void 0) {
16555
+ return sanitizeOpenRouterLoggedValue(response.output);
16556
+ }
16557
+ if (fallbackOutput !== void 0) {
16558
+ return sanitizeOpenRouterLoggedValue(fallbackOutput);
16559
+ }
16560
+ return void 0;
16561
+ }
16562
+
16563
+ // src/openrouter-tool-wrapping.ts
16564
+ var OPENROUTER_WRAPPED_TOOL = Symbol("braintrust.openrouter.wrappedTool");
16565
+ var OPENROUTER_WRAPPED_CALL_MODEL_RESULT = Symbol(
16566
+ "braintrust.openrouter.wrappedCallModelResult"
16567
+ );
16568
+ var OPENROUTER_CALL_MODEL_STREAM_METHODS = [
16569
+ "getFullResponsesStream",
16570
+ "getItemsStream",
16571
+ "getNewMessagesStream",
16572
+ "getReasoningStream",
16573
+ "getTextStream",
16574
+ "getToolCallsStream",
16575
+ "getToolStream"
16576
+ ];
16577
+ var OPENROUTER_CALL_MODEL_CONTEXT_METHODS = [
16578
+ "cancel",
16579
+ "getPendingToolCalls",
16580
+ "getState",
16581
+ "getToolCalls",
16582
+ "requiresApproval"
16583
+ ];
16584
+ function patchOpenRouterCallModelRequestTools(request) {
16585
+ if (!Array.isArray(request.tools) || request.tools.length === 0) {
16586
+ return void 0;
16587
+ }
16588
+ const originalTools = request.tools;
16589
+ const wrappedTools = originalTools.map((tool) => wrapOpenRouterTool(tool));
16590
+ const didPatch = wrappedTools.some(
16591
+ (tool, index) => tool !== originalTools[index]
16592
+ );
16593
+ if (!didPatch) {
16594
+ return void 0;
16595
+ }
16596
+ request.tools = wrappedTools;
16597
+ return () => {
16598
+ request.tools = originalTools;
16599
+ };
16600
+ }
16601
+ function patchOpenRouterCallModelResult(span, result, request) {
16602
+ if (!isObject(result) || isWrappedCallModelResult(result)) {
16603
+ return false;
16604
+ }
16605
+ const resultLike = result;
16606
+ const hasInstrumentableMethod = typeof resultLike.getResponse === "function" || typeof resultLike.getText === "function" || OPENROUTER_CALL_MODEL_STREAM_METHODS.some(
16607
+ (methodName) => typeof resultLike[methodName] === "function"
16608
+ );
16609
+ if (!hasInstrumentableMethod) {
16610
+ return false;
16611
+ }
16612
+ Object.defineProperty(resultLike, OPENROUTER_WRAPPED_CALL_MODEL_RESULT, {
16613
+ value: true,
16614
+ enumerable: false,
16615
+ configurable: false
16616
+ });
16617
+ const originalGetResponse = typeof resultLike.getResponse === "function" ? resultLike.getResponse.bind(resultLike) : void 0;
16618
+ const originalGetInitialResponse = typeof resultLike.getInitialResponse === "function" ? resultLike.getInitialResponse.bind(resultLike) : void 0;
16619
+ const originalMakeFollowupRequest = typeof resultLike.makeFollowupRequest === "function" ? resultLike.makeFollowupRequest.bind(resultLike) : void 0;
16620
+ let ended = false;
16621
+ let tracedTurnCount = 0;
16622
+ const endSpanWithResult = async (response, fallbackOutput) => {
16623
+ if (ended) {
16624
+ return;
16625
+ }
16626
+ ended = true;
16627
+ const finalResponse = getFinalOpenRouterCallModelResponse(
16628
+ resultLike,
16629
+ response
16630
+ );
16631
+ if (finalResponse) {
16632
+ const rounds = getOpenRouterCallModelRounds(resultLike);
16633
+ const metadata = extractOpenRouterCallModelResultMetadata(
16634
+ finalResponse,
16635
+ rounds.length + 1
16636
+ );
16637
+ span.log({
16638
+ output: extractOpenRouterResponseOutput(finalResponse, fallbackOutput),
16639
+ ...metadata ? { metadata } : {},
16640
+ metrics: aggregateOpenRouterCallModelMetrics(rounds, finalResponse)
16641
+ });
16642
+ span.end();
16643
+ return;
16644
+ }
16645
+ if (fallbackOutput !== void 0) {
16646
+ span.log({
16647
+ output: fallbackOutput
16648
+ });
16649
+ }
16650
+ span.end();
16651
+ };
16652
+ const endSpanWithError = (error2) => {
16653
+ if (ended) {
16654
+ return;
16655
+ }
16656
+ ended = true;
16657
+ span.log({
16658
+ error: normalizeError(error2).message
16659
+ });
16660
+ span.end();
16661
+ };
16662
+ const finalizeFromResponse = async (fallbackOutput) => {
16663
+ if (!originalGetResponse) {
16664
+ await endSpanWithResult(void 0, fallbackOutput);
16665
+ return;
16666
+ }
16667
+ try {
16668
+ await endSpanWithResult(await originalGetResponse(), fallbackOutput);
16669
+ } catch {
16670
+ await endSpanWithResult(void 0, fallbackOutput);
16671
+ }
16672
+ };
16673
+ if (originalGetResponse) {
16674
+ resultLike.getResponse = async (...args) => {
16675
+ return await withCurrent(span, async () => {
16676
+ try {
16677
+ const response = await originalGetResponse(...args);
16678
+ await endSpanWithResult(response);
16679
+ return response;
16680
+ } catch (error2) {
16681
+ endSpanWithError(error2);
16682
+ throw error2;
16683
+ }
16684
+ });
16685
+ };
16686
+ }
16687
+ if (typeof resultLike.getText === "function") {
16688
+ const originalGetText = resultLike.getText.bind(resultLike);
16689
+ resultLike.getText = async (...args) => {
16690
+ return await withCurrent(span, async () => {
16691
+ try {
16692
+ const text = await originalGetText(...args);
16693
+ await finalizeFromResponse(text);
16694
+ return text;
16695
+ } catch (error2) {
16696
+ endSpanWithError(error2);
16697
+ throw error2;
16698
+ }
16699
+ });
16700
+ };
16701
+ }
16702
+ for (const methodName of OPENROUTER_CALL_MODEL_CONTEXT_METHODS) {
16703
+ if (typeof resultLike[methodName] !== "function") {
16704
+ continue;
16705
+ }
16706
+ const originalMethod = resultLike[methodName];
16707
+ resultLike[methodName] = async (...args) => {
16708
+ return await withCurrent(span, async () => {
16709
+ return await originalMethod.apply(resultLike, args);
16710
+ });
16711
+ };
16712
+ }
16713
+ for (const methodName of OPENROUTER_CALL_MODEL_STREAM_METHODS) {
16714
+ if (typeof resultLike[methodName] !== "function") {
16715
+ continue;
16716
+ }
16717
+ const originalMethod = resultLike[methodName];
16718
+ resultLike[methodName] = (...args) => {
16719
+ const stream = withCurrent(
16720
+ span,
16721
+ () => originalMethod.apply(resultLike, args)
16722
+ );
16723
+ if (!isAsyncIterable4(stream)) {
16724
+ return stream;
16725
+ }
16726
+ return wrapAsyncIterableWithSpan({
16727
+ finalize: finalizeFromResponse,
16728
+ iteratorFactory: () => stream[Symbol.asyncIterator](),
16729
+ onError: endSpanWithError,
16730
+ span
16731
+ });
16732
+ };
16733
+ }
16734
+ if (originalGetInitialResponse) {
16735
+ let initialTurnTraced = false;
16736
+ resultLike.getInitialResponse = async (...args) => {
16737
+ if (initialTurnTraced) {
16738
+ return await withCurrent(span, async () => {
16739
+ return await originalGetInitialResponse(...args);
16740
+ });
16741
+ }
16742
+ initialTurnTraced = true;
16743
+ const resolvedRequest = getOpenRouterResolvedRequest(resultLike, request);
16744
+ const childSpan = startOpenRouterCallModelTurnSpan({
16745
+ request: resolvedRequest,
16746
+ step: tracedTurnCount + 1,
16747
+ stepType: tracedTurnCount === 0 ? "initial" : "continue"
16748
+ });
16749
+ return await withCurrent(childSpan, async () => {
16750
+ try {
16751
+ const response = await originalGetInitialResponse(...args);
16752
+ tracedTurnCount++;
16753
+ finishOpenRouterCallModelTurnSpan({
16754
+ response,
16755
+ step: tracedTurnCount,
16756
+ stepType: tracedTurnCount === 1 ? "initial" : "continue",
16757
+ span: childSpan
16758
+ });
16759
+ return response;
16760
+ } catch (error2) {
16761
+ childSpan.log({
16762
+ error: normalizeError(error2).message
16763
+ });
16764
+ childSpan.end();
16765
+ throw error2;
16766
+ }
16767
+ });
16768
+ };
16769
+ }
16770
+ if (originalMakeFollowupRequest) {
16771
+ resultLike.makeFollowupRequest = async (...args) => {
16772
+ const currentResponse = args[0];
16773
+ const toolResults = Array.isArray(args[1]) ? args[1] : [];
16774
+ const resolvedRequest = getOpenRouterResolvedRequest(resultLike, request);
16775
+ const followupRequest = buildOpenRouterFollowupRequest(
16776
+ resolvedRequest,
16777
+ currentResponse,
16778
+ toolResults
16779
+ );
16780
+ const childSpan = startOpenRouterCallModelTurnSpan({
16781
+ request: followupRequest,
16782
+ step: tracedTurnCount + 1,
16783
+ stepType: "continue"
16784
+ });
16785
+ return await withCurrent(childSpan, async () => {
16786
+ try {
16787
+ const response = await originalMakeFollowupRequest(...args);
16788
+ tracedTurnCount++;
16789
+ finishOpenRouterCallModelTurnSpan({
16790
+ response,
16791
+ step: tracedTurnCount,
16792
+ stepType: "continue",
16793
+ span: childSpan
16794
+ });
16795
+ return response;
16796
+ } catch (error2) {
16797
+ childSpan.log({
16798
+ error: normalizeError(error2).message
16799
+ });
16800
+ childSpan.end();
16801
+ throw error2;
16802
+ }
16803
+ });
16804
+ };
16805
+ }
16806
+ return true;
16807
+ }
16808
+ function wrapOpenRouterTool(tool) {
16809
+ if (isWrappedTool(tool) || !tool.function || typeof tool.function !== "object" || typeof tool.function.execute !== "function") {
16810
+ return tool;
16811
+ }
16812
+ const toolName = tool.function.name || "tool";
16813
+ const originalExecute = tool.function.execute;
16814
+ const wrappedTool = {
16815
+ ...tool,
16816
+ function: {
16817
+ ...tool.function,
16818
+ execute(...args) {
16819
+ return traceToolExecution({
16820
+ args,
16821
+ execute: () => Reflect.apply(originalExecute, this, args),
16822
+ toolCallId: getToolCallId(args[1]),
16823
+ toolName
16824
+ });
16825
+ }
16826
+ }
16827
+ };
16828
+ Object.defineProperty(wrappedTool, OPENROUTER_WRAPPED_TOOL, {
16829
+ value: true,
16830
+ enumerable: false,
16831
+ configurable: false
16832
+ });
16833
+ return wrappedTool;
16834
+ }
16835
+ function isWrappedTool(tool) {
16836
+ return Boolean(tool[OPENROUTER_WRAPPED_TOOL]);
16837
+ }
16838
+ function isWrappedCallModelResult(value) {
16839
+ return Boolean(
16840
+ isObject(value) && value[OPENROUTER_WRAPPED_CALL_MODEL_RESULT]
16841
+ );
16842
+ }
16843
+ function traceToolExecution(args) {
16844
+ const tracingChannel2 = openRouterChannels.toolExecute.tracingChannel();
16845
+ const input = args.args.length > 0 ? args.args[0] : void 0;
16846
+ const event = {
16847
+ arguments: [input],
16848
+ span_info: {
16849
+ name: args.toolName
16850
+ },
16851
+ toolCallId: args.toolCallId,
16852
+ toolName: args.toolName
16853
+ };
16854
+ tracingChannel2.start.publish(event);
16855
+ try {
16856
+ const result = args.execute();
16857
+ return publishToolResult(tracingChannel2, event, result);
16858
+ } catch (error2) {
16859
+ event.error = normalizeError(error2);
16860
+ tracingChannel2.error.publish(event);
16861
+ throw error2;
16862
+ }
16863
+ }
16864
+ function publishToolResult(tracingChannel2, event, result) {
16865
+ if (isPromiseLike(result)) {
16866
+ return result.then(
16867
+ (resolved) => {
16868
+ event.result = resolved;
16869
+ tracingChannel2.asyncEnd.publish(event);
16870
+ return resolved;
16871
+ },
16872
+ (error2) => {
16873
+ event.error = normalizeError(error2);
16874
+ tracingChannel2.error.publish(event);
16875
+ throw error2;
16876
+ }
16877
+ );
16878
+ }
16879
+ event.result = result;
16880
+ tracingChannel2.asyncEnd.publish(event);
16881
+ return result;
16882
+ }
16883
+ function getToolCallId(context2) {
16884
+ const toolContext = context2;
16885
+ return typeof toolContext?.toolCall?.id === "string" ? toolContext.toolCall.id : void 0;
16886
+ }
16887
+ function extractOpenRouterCallModelResultMetadata(response, turnCount) {
16888
+ const combined = {
16889
+ ...extractOpenRouterResponseMetadata(response) || {},
16890
+ ...turnCount !== void 0 ? { turn_count: turnCount } : {}
16891
+ };
16892
+ return Object.keys(combined).length > 0 ? combined : void 0;
16893
+ }
16894
+ function getFinalOpenRouterCallModelResponse(result, response) {
16895
+ if (isObject(response)) {
16896
+ return response;
16897
+ }
16898
+ return isObject(result.finalResponse) ? result.finalResponse : void 0;
16899
+ }
16900
+ function getOpenRouterCallModelRounds(result) {
16901
+ if (!Array.isArray(result.allToolExecutionRounds)) {
16902
+ return [];
16903
+ }
16904
+ return result.allToolExecutionRounds.filter((round) => isObject(round)).map((round) => ({
16905
+ response: isObject(round.response) ? round.response : void 0,
16906
+ round: typeof round.round === "number" ? round.round : void 0,
16907
+ toolResults: Array.isArray(round.toolResults) ? round.toolResults : []
16908
+ })).filter((round) => round.response !== void 0);
16909
+ }
16910
+ function aggregateOpenRouterCallModelMetrics(rounds, finalResponse) {
16911
+ const metrics = {};
16912
+ const responses = [
16913
+ ...rounds.map((round) => round.response).filter(isObject),
16914
+ finalResponse
16915
+ ];
16916
+ for (const response of responses) {
16917
+ const responseMetrics = parseOpenRouterMetricsFromUsage(response.usage);
16918
+ for (const [name, value] of Object.entries(responseMetrics)) {
16919
+ metrics[name] = (metrics[name] || 0) + value;
16920
+ }
16921
+ }
16922
+ return metrics;
16923
+ }
16924
+ function buildNextOpenRouterCallModelInput(currentInput, response, toolResults) {
16925
+ const normalizedInput = Array.isArray(currentInput) ? [...currentInput] : currentInput === void 0 ? [] : [currentInput];
16926
+ const responseOutput = Array.isArray(response.output) ? response.output : response.output === void 0 ? [] : [response.output];
16927
+ return [...normalizedInput, ...responseOutput, ...toolResults].map(
16928
+ (entry) => sanitizeOpenRouterLoggedValue(entry)
16929
+ );
16930
+ }
16931
+ function startOpenRouterCallModelTurnSpan(args) {
16932
+ const requestRecord = isObject(args.request) ? args.request : void 0;
16933
+ const metadata = requestRecord ? extractOpenRouterCallModelMetadata(requestRecord) : { provider: "openrouter" };
16934
+ if (isObject(metadata) && "tools" in metadata) {
16935
+ delete metadata.tools;
16936
+ }
16937
+ return startSpan({
16938
+ name: "openrouter.beta.responses.send",
16939
+ spanAttributes: {
16940
+ type: "llm" /* LLM */
16941
+ },
16942
+ event: {
16943
+ input: requestRecord ? extractOpenRouterCallModelInput(requestRecord) : void 0,
16944
+ metadata: {
16945
+ ...metadata,
16946
+ step: args.step,
16947
+ step_type: args.stepType
16948
+ }
16949
+ }
16950
+ });
16951
+ }
16952
+ function finishOpenRouterCallModelTurnSpan(args) {
16953
+ if (!isObject(args.response)) {
16954
+ args.span.end();
16955
+ return;
16956
+ }
16957
+ args.span.log({
16958
+ output: extractOpenRouterResponseOutput(args.response),
16959
+ ...extractOpenRouterResponseMetadata(args.response) ? {
16960
+ metadata: {
16961
+ ...extractOpenRouterResponseMetadata(args.response),
16962
+ ...args.step !== void 0 ? { step: args.step } : {},
16963
+ ...args.stepType ? { step_type: args.stepType } : {}
16964
+ }
16965
+ } : {},
16966
+ metrics: parseOpenRouterMetricsFromUsage(args.response.usage)
16967
+ });
16968
+ args.span.end();
16969
+ }
16970
+ function getOpenRouterResolvedRequest(result, request) {
16971
+ if (isObject(result.resolvedRequest)) {
16972
+ return result.resolvedRequest;
16973
+ }
16974
+ return request;
16975
+ }
16976
+ function buildOpenRouterFollowupRequest(request, currentResponse, toolResults) {
16977
+ if (!request) {
16978
+ return void 0;
16979
+ }
16980
+ return {
16981
+ ...request,
16982
+ input: buildNextOpenRouterCallModelInput(
16983
+ extractOpenRouterCallModelInput(request),
16984
+ isObject(currentResponse) ? currentResponse : {},
16985
+ toolResults
16986
+ ),
16987
+ stream: false
16988
+ };
16989
+ }
16990
+ function wrapAsyncIterableWithSpan(args) {
16991
+ return {
16992
+ [Symbol.asyncIterator]() {
16993
+ const iterator = args.iteratorFactory();
16994
+ return {
16995
+ next(value) {
16996
+ return withCurrent(
16997
+ args.span,
16998
+ () => value === void 0 ? iterator.next() : iterator.next(value)
16999
+ ).then(
17000
+ async (result) => {
17001
+ if (result.done) {
17002
+ await args.finalize();
17003
+ }
17004
+ return result;
17005
+ },
17006
+ (error2) => {
17007
+ args.onError(error2);
17008
+ throw error2;
17009
+ }
17010
+ );
17011
+ },
17012
+ return(value) {
17013
+ if (typeof iterator.return !== "function") {
17014
+ return args.finalize().then(() => ({
17015
+ done: true,
17016
+ value
17017
+ }));
17018
+ }
17019
+ return withCurrent(args.span, () => iterator.return(value)).then(
17020
+ async (result) => {
17021
+ await args.finalize();
17022
+ return result;
17023
+ },
17024
+ (error2) => {
17025
+ args.onError(error2);
17026
+ throw error2;
17027
+ }
17028
+ );
17029
+ },
17030
+ throw(error2) {
17031
+ args.onError(error2);
17032
+ if (typeof iterator.throw !== "function") {
17033
+ return Promise.reject(error2);
17034
+ }
17035
+ return withCurrent(args.span, () => iterator.throw(error2));
17036
+ },
17037
+ [Symbol.asyncIterator]() {
17038
+ return this;
17039
+ }
17040
+ };
17041
+ }
17042
+ };
17043
+ }
17044
+ function isAsyncIterable4(value) {
17045
+ return !!value && (typeof value === "object" || typeof value === "function") && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
15365
17046
  }
15366
- function populateUsageMetrics(metrics, usage) {
15367
- if (usage.promptTokenCount !== void 0) {
15368
- metrics.prompt_tokens = usage.promptTokenCount;
17047
+ function isPromiseLike(value) {
17048
+ return !!value && (typeof value === "object" || typeof value === "function") && "then" in value && typeof value.then === "function";
17049
+ }
17050
+ function normalizeError(error2) {
17051
+ return error2 instanceof Error ? error2 : new Error(String(error2));
17052
+ }
17053
+
17054
+ // src/instrumentation/plugins/openrouter-plugin.ts
17055
+ var OpenRouterPlugin = class extends BasePlugin {
17056
+ onEnable() {
17057
+ this.subscribeToOpenRouterChannels();
15369
17058
  }
15370
- if (usage.candidatesTokenCount !== void 0) {
15371
- metrics.completion_tokens = usage.candidatesTokenCount;
17059
+ onDisable() {
17060
+ this.unsubscribers = unsubscribeAll(this.unsubscribers);
15372
17061
  }
15373
- if (usage.totalTokenCount !== void 0) {
15374
- metrics.tokens = usage.totalTokenCount;
17062
+ subscribeToOpenRouterChannels() {
17063
+ this.unsubscribers.push(
17064
+ traceStreamingChannel(openRouterChannels.chatSend, {
17065
+ name: "openrouter.chat.send",
17066
+ type: "llm" /* LLM */,
17067
+ extractInput: (args) => {
17068
+ const request = getOpenRouterRequestArg(args);
17069
+ const chatGenerationParams = isObject(request?.chatGenerationParams) ? request.chatGenerationParams : {};
17070
+ const httpReferer = request?.httpReferer;
17071
+ const xTitle = request?.xTitle;
17072
+ const { messages, ...metadata } = chatGenerationParams;
17073
+ return {
17074
+ input: messages,
17075
+ metadata: buildOpenRouterMetadata(metadata, httpReferer, xTitle)
17076
+ };
17077
+ },
17078
+ extractOutput: (result) => {
17079
+ return isObject(result) ? result.choices : void 0;
17080
+ },
17081
+ extractMetrics: (result, startTime) => {
17082
+ const metrics = parseOpenRouterMetricsFromUsage(result?.usage);
17083
+ if (startTime) {
17084
+ metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
17085
+ }
17086
+ return metrics;
17087
+ },
17088
+ aggregateChunks: aggregateOpenRouterChatChunks
17089
+ })
17090
+ );
17091
+ this.unsubscribers.push(
17092
+ traceAsyncChannel(openRouterChannels.embeddingsGenerate, {
17093
+ name: "openrouter.embeddings.generate",
17094
+ type: "llm" /* LLM */,
17095
+ extractInput: (args) => {
17096
+ const request = getOpenRouterRequestArg(args);
17097
+ const requestBody = isObject(request?.requestBody) ? request.requestBody : {};
17098
+ const httpReferer = request?.httpReferer;
17099
+ const xTitle = request?.xTitle;
17100
+ const { input, ...metadata } = requestBody;
17101
+ return {
17102
+ input,
17103
+ metadata: buildOpenRouterEmbeddingMetadata(
17104
+ metadata,
17105
+ httpReferer,
17106
+ xTitle
17107
+ )
17108
+ };
17109
+ },
17110
+ extractOutput: (result) => {
17111
+ if (!isObject(result)) {
17112
+ return void 0;
17113
+ }
17114
+ const embedding = result.data?.[0]?.embedding;
17115
+ return Array.isArray(embedding) ? { embedding_length: embedding.length } : void 0;
17116
+ },
17117
+ extractMetadata: (result) => {
17118
+ if (!isObject(result)) {
17119
+ return void 0;
17120
+ }
17121
+ return extractOpenRouterResponseMetadata(result);
17122
+ },
17123
+ extractMetrics: (result) => {
17124
+ return isObject(result) ? parseOpenRouterMetricsFromUsage(result.usage) : {};
17125
+ }
17126
+ })
17127
+ );
17128
+ this.unsubscribers.push(
17129
+ traceStreamingChannel(openRouterChannels.betaResponsesSend, {
17130
+ name: "openrouter.beta.responses.send",
17131
+ type: "llm" /* LLM */,
17132
+ extractInput: (args) => {
17133
+ const request = getOpenRouterRequestArg(args);
17134
+ const openResponsesRequest = isObject(request?.openResponsesRequest) ? request.openResponsesRequest : {};
17135
+ const httpReferer = request?.httpReferer;
17136
+ const xTitle = request?.xTitle;
17137
+ const { input, ...metadata } = openResponsesRequest;
17138
+ return {
17139
+ input,
17140
+ metadata: buildOpenRouterMetadata(metadata, httpReferer, xTitle)
17141
+ };
17142
+ },
17143
+ extractOutput: (result) => extractOpenRouterResponseOutput(result),
17144
+ extractMetadata: (result) => extractOpenRouterResponseMetadata(result),
17145
+ extractMetrics: (result, startTime) => {
17146
+ const metrics = parseOpenRouterMetricsFromUsage(result?.usage);
17147
+ if (startTime) {
17148
+ metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
17149
+ }
17150
+ return metrics;
17151
+ },
17152
+ aggregateChunks: aggregateOpenRouterResponseStreamEvents
17153
+ })
17154
+ );
17155
+ this.unsubscribers.push(
17156
+ traceSyncStreamChannel(openRouterChannels.callModel, {
17157
+ name: "openrouter.callModel",
17158
+ type: "llm" /* LLM */,
17159
+ extractInput: (args) => {
17160
+ const request = getOpenRouterCallModelRequestArg(args);
17161
+ return {
17162
+ input: request ? extractOpenRouterCallModelInput(request) : void 0,
17163
+ metadata: request ? extractOpenRouterCallModelMetadata(request) : { provider: "openrouter" }
17164
+ };
17165
+ },
17166
+ patchResult: ({ endEvent, result, span }) => {
17167
+ return patchOpenRouterCallModelResult(
17168
+ span,
17169
+ result,
17170
+ getOpenRouterCallModelRequestArg(endEvent.arguments)
17171
+ );
17172
+ }
17173
+ })
17174
+ );
17175
+ this.unsubscribers.push(
17176
+ traceStreamingChannel(openRouterChannels.toolExecute, {
17177
+ name: "openrouter.tool",
17178
+ type: "tool" /* TOOL */,
17179
+ extractInput: (args, event) => ({
17180
+ input: args[0],
17181
+ metadata: {
17182
+ provider: "openrouter",
17183
+ tool_name: event.toolName,
17184
+ ...event.toolCallId ? { tool_call_id: event.toolCallId } : {}
17185
+ }
17186
+ }),
17187
+ extractOutput: (result) => result,
17188
+ extractMetrics: () => ({}),
17189
+ aggregateChunks: (chunks) => ({
17190
+ output: chunks.length > 0 ? chunks[chunks.length - 1] : void 0,
17191
+ metrics: {}
17192
+ })
17193
+ })
17194
+ );
17195
+ const callModelChannel = openRouterChannels.callModel.tracingChannel();
17196
+ const callModelHandlers = {
17197
+ start: (event) => {
17198
+ const request = getOpenRouterCallModelRequestArg(event.arguments);
17199
+ if (!request) {
17200
+ return;
17201
+ }
17202
+ patchOpenRouterCallModelRequestTools(request);
17203
+ }
17204
+ };
17205
+ callModelChannel.subscribe(callModelHandlers);
17206
+ this.unsubscribers.push(() => {
17207
+ callModelChannel.unsubscribe(callModelHandlers);
17208
+ });
15375
17209
  }
15376
- if (usage.cachedContentTokenCount !== void 0) {
15377
- metrics.prompt_cached_tokens = usage.cachedContentTokenCount;
17210
+ };
17211
+ function normalizeArgs(args) {
17212
+ if (Array.isArray(args)) {
17213
+ return args;
15378
17214
  }
15379
- if (usage.thoughtsTokenCount !== void 0) {
15380
- metrics.completion_reasoning_tokens = usage.thoughtsTokenCount;
17215
+ if (isArrayLike2(args)) {
17216
+ return Array.from(args);
15381
17217
  }
17218
+ return [args];
15382
17219
  }
15383
- function aggregateGenerateContentChunks(chunks, startTime) {
15384
- const metrics = {};
15385
- if (startTime !== void 0) {
15386
- const end = getCurrentUnixTimestamp();
15387
- metrics.duration = end - startTime;
15388
- }
15389
- let firstTokenTime = null;
15390
- if (chunks.length > 0 && firstTokenTime === null && startTime !== void 0) {
15391
- firstTokenTime = getCurrentUnixTimestamp();
15392
- metrics.time_to_first_token = firstTokenTime - startTime;
15393
- }
15394
- if (chunks.length === 0) {
15395
- return { output: {}, metrics };
17220
+ function isArrayLike2(value) {
17221
+ return isObject(value) && "length" in value && typeof value.length === "number" && Number.isInteger(value.length) && value.length >= 0;
17222
+ }
17223
+ function getOpenRouterRequestArg(args) {
17224
+ const normalizedArgs = normalizeArgs(args);
17225
+ const keyedCandidate = normalizedArgs.find(
17226
+ (arg) => isObject(arg) && ("chatGenerationParams" in arg || "requestBody" in arg || "openResponsesRequest" in arg)
17227
+ );
17228
+ if (isObject(keyedCandidate)) {
17229
+ return keyedCandidate;
15396
17230
  }
15397
- let text = "";
15398
- let thoughtText = "";
15399
- const otherParts = [];
15400
- let usageMetadata = null;
15401
- let lastResponse = null;
17231
+ const firstObjectArg = normalizedArgs.find((arg) => isObject(arg));
17232
+ return isObject(firstObjectArg) ? firstObjectArg : void 0;
17233
+ }
17234
+ function getOpenRouterCallModelRequestArg(args) {
17235
+ const firstObjectArg = normalizeArgs(args).find((arg) => isObject(arg));
17236
+ return isObject(firstObjectArg) ? firstObjectArg : void 0;
17237
+ }
17238
+ function aggregateOpenRouterChatChunks(chunks) {
17239
+ let role;
17240
+ let content = "";
17241
+ let toolCalls;
17242
+ let finishReason;
17243
+ let metrics = {};
15402
17244
  for (const chunk of chunks) {
15403
- lastResponse = chunk;
15404
- if (chunk.usageMetadata) {
15405
- usageMetadata = chunk.usageMetadata;
17245
+ metrics = {
17246
+ ...metrics,
17247
+ ...parseOpenRouterMetricsFromUsage(chunk?.usage)
17248
+ };
17249
+ const choice = chunk?.choices?.[0];
17250
+ const delta = choice?.delta;
17251
+ if (!delta) {
17252
+ if (choice?.finish_reason !== void 0) {
17253
+ finishReason = choice.finish_reason;
17254
+ }
17255
+ continue;
15406
17256
  }
15407
- if (chunk.candidates && Array.isArray(chunk.candidates)) {
15408
- for (const candidate of chunk.candidates) {
15409
- if (candidate.content?.parts) {
15410
- for (const part of candidate.content.parts) {
15411
- if (part.text !== void 0) {
15412
- if (part.thought) {
15413
- thoughtText += part.text;
15414
- } else {
15415
- text += part.text;
15416
- }
15417
- } else if (part.functionCall) {
15418
- otherParts.push({ functionCall: part.functionCall });
15419
- } else if (part.codeExecutionResult) {
15420
- otherParts.push({
15421
- codeExecutionResult: part.codeExecutionResult
15422
- });
15423
- } else if (part.executableCode) {
15424
- otherParts.push({ executableCode: part.executableCode });
15425
- }
17257
+ if (!role && delta.role) {
17258
+ role = delta.role;
17259
+ }
17260
+ if (typeof delta.content === "string") {
17261
+ content += delta.content;
17262
+ }
17263
+ const choiceFinishReason = choice?.finishReason ?? choice?.finish_reason ?? void 0;
17264
+ const deltaFinishReason = delta.finishReason ?? delta.finish_reason ?? void 0;
17265
+ if (choiceFinishReason !== void 0) {
17266
+ finishReason = choiceFinishReason;
17267
+ } else if (deltaFinishReason !== void 0) {
17268
+ finishReason = deltaFinishReason;
17269
+ }
17270
+ const toolCallDeltas = Array.isArray(delta.toolCalls) ? delta.toolCalls : Array.isArray(delta.tool_calls) ? delta.tool_calls : void 0;
17271
+ if (!toolCallDeltas) {
17272
+ continue;
17273
+ }
17274
+ for (const toolDelta of toolCallDeltas) {
17275
+ if (!toolDelta?.function) {
17276
+ continue;
17277
+ }
17278
+ const toolIndex = toolDelta.index ?? 0;
17279
+ const existingToolCall = toolCalls?.[toolIndex];
17280
+ if (!existingToolCall || toolDelta.id && existingToolCall.id !== void 0 && existingToolCall.id !== toolDelta.id) {
17281
+ const nextToolCalls = [...toolCalls || []];
17282
+ nextToolCalls[toolIndex] = {
17283
+ index: toolIndex,
17284
+ id: toolDelta.id,
17285
+ type: toolDelta.type,
17286
+ function: {
17287
+ name: toolDelta.function.name,
17288
+ arguments: toolDelta.function.arguments || ""
15426
17289
  }
15427
- }
17290
+ };
17291
+ toolCalls = nextToolCalls;
17292
+ continue;
15428
17293
  }
15429
- }
15430
- }
15431
- const output = {};
15432
- const parts = [];
15433
- if (thoughtText) {
15434
- parts.push({ text: thoughtText, thought: true });
15435
- }
15436
- if (text) {
15437
- parts.push({ text });
15438
- }
15439
- parts.push(...otherParts);
15440
- if (parts.length > 0 && lastResponse?.candidates) {
15441
- const candidates = [];
15442
- for (const candidate of lastResponse.candidates) {
15443
- const candidateDict = {
15444
- content: {
15445
- parts,
15446
- role: "model"
15447
- }
15448
- };
15449
- if (candidate.finishReason !== void 0) {
15450
- candidateDict.finishReason = candidate.finishReason;
17294
+ const current = existingToolCall;
17295
+ if (toolDelta.id && !current.id) {
17296
+ current.id = toolDelta.id;
15451
17297
  }
15452
- if (candidate.safetyRatings) {
15453
- candidateDict.safetyRatings = candidate.safetyRatings;
17298
+ if (toolDelta.type && !current.type) {
17299
+ current.type = toolDelta.type;
15454
17300
  }
15455
- candidates.push(candidateDict);
17301
+ if (toolDelta.function.name && !current.function.name) {
17302
+ current.function.name = toolDelta.function.name;
17303
+ }
17304
+ current.function.arguments += toolDelta.function.arguments || "";
15456
17305
  }
15457
- output.candidates = candidates;
15458
17306
  }
15459
- if (usageMetadata) {
15460
- output.usageMetadata = usageMetadata;
15461
- populateUsageMetrics(metrics, usageMetadata);
15462
- }
15463
- if (text) {
15464
- output.text = text;
15465
- }
15466
- return { output, metrics };
17307
+ return {
17308
+ output: [
17309
+ {
17310
+ index: 0,
17311
+ message: {
17312
+ role,
17313
+ content: content || void 0,
17314
+ ...toolCalls ? { tool_calls: toolCalls } : {}
17315
+ },
17316
+ logprobs: null,
17317
+ finish_reason: finishReason
17318
+ }
17319
+ ],
17320
+ metrics
17321
+ };
15467
17322
  }
15468
- function tryToDict(obj) {
15469
- if (obj === null || obj === void 0) {
15470
- return null;
15471
- }
15472
- if (typeof obj === "object") {
15473
- if ("toJSON" in obj && // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
15474
- typeof obj.toJSON === "function") {
15475
- return obj.toJSON();
17323
+ function aggregateOpenRouterResponseStreamEvents(chunks) {
17324
+ let finalResponse;
17325
+ for (const chunk of chunks) {
17326
+ const response = chunk?.response;
17327
+ if (!response) {
17328
+ continue;
17329
+ }
17330
+ if (chunk.type === "response.completed" || chunk.type === "response.incomplete" || chunk.type === "response.failed") {
17331
+ finalResponse = response;
15476
17332
  }
15477
- return obj;
15478
17333
  }
15479
- return null;
17334
+ if (!finalResponse) {
17335
+ return {
17336
+ output: void 0,
17337
+ metrics: {}
17338
+ };
17339
+ }
17340
+ return {
17341
+ output: extractOpenRouterResponseOutput(finalResponse),
17342
+ metrics: parseOpenRouterMetricsFromUsage(finalResponse.usage),
17343
+ ...extractOpenRouterResponseMetadata(finalResponse) ? { metadata: extractOpenRouterResponseMetadata(finalResponse) } : {}
17344
+ };
15480
17345
  }
15481
17346
 
15482
17347
  // src/instrumentation/braintrust-plugin.ts
@@ -15487,6 +17352,7 @@ var BraintrustPlugin = class extends BasePlugin {
15487
17352
  aiSDKPlugin = null;
15488
17353
  claudeAgentSDKPlugin = null;
15489
17354
  googleGenAIPlugin = null;
17355
+ openRouterPlugin = null;
15490
17356
  constructor(config3 = {}) {
15491
17357
  super();
15492
17358
  this.config = config3;
@@ -15513,6 +17379,10 @@ var BraintrustPlugin = class extends BasePlugin {
15513
17379
  this.googleGenAIPlugin = new GoogleGenAIPlugin();
15514
17380
  this.googleGenAIPlugin.enable();
15515
17381
  }
17382
+ if (integrations.openrouter !== false) {
17383
+ this.openRouterPlugin = new OpenRouterPlugin();
17384
+ this.openRouterPlugin.enable();
17385
+ }
15516
17386
  }
15517
17387
  onDisable() {
15518
17388
  if (this.openaiPlugin) {
@@ -15535,6 +17405,10 @@ var BraintrustPlugin = class extends BasePlugin {
15535
17405
  this.googleGenAIPlugin.disable();
15536
17406
  this.googleGenAIPlugin = null;
15537
17407
  }
17408
+ if (this.openRouterPlugin) {
17409
+ this.openRouterPlugin.disable();
17410
+ this.openRouterPlugin = null;
17411
+ }
15538
17412
  }
15539
17413
  };
15540
17414
 
@@ -15606,7 +17480,8 @@ var PluginRegistry = class {
15606
17480
  vercel: true,
15607
17481
  aisdk: true,
15608
17482
  google: true,
15609
- claudeAgentSDK: true
17483
+ claudeAgentSDK: true,
17484
+ openrouter: true
15610
17485
  };
15611
17486
  }
15612
17487
  /**
@@ -15636,6 +17511,7 @@ function configureNode() {
15636
17511
  isomorph_default.getCallerLocation = getCallerLocation;
15637
17512
  isomorph_default.newAsyncLocalStorage = () => new import_node_async_hooks.AsyncLocalStorage();
15638
17513
  isomorph_default.newTracingChannel = (nameOrChannels) => diagnostics_channel.tracingChannel(nameOrChannels);
17514
+ patchTracingChannel(diagnostics_channel.tracingChannel);
15639
17515
  isomorph_default.processOn = (event, handler) => {
15640
17516
  process.on(event, handler);
15641
17517
  };
@@ -15929,21 +17805,6 @@ async function getTsModule() {
15929
17805
  return tsModule;
15930
17806
  }
15931
17807
 
15932
- // src/zod/utils.ts
15933
- var import_zod_to_json_schema = require("zod-to-json-schema");
15934
- var z42 = __toESM(require("zod/v4"));
15935
- function isZodV4(zodObject) {
15936
- return typeof zodObject === "object" && zodObject !== null && "_zod" in zodObject && zodObject._zod !== void 0;
15937
- }
15938
- function zodToJsonSchema(schema) {
15939
- if (isZodV4(schema)) {
15940
- return z42.toJSONSchema(schema, {
15941
- target: "draft-7"
15942
- });
15943
- }
15944
- return (0, import_zod_to_json_schema.zodToJsonSchema)(schema);
15945
- }
15946
-
15947
17808
  // src/cli/functions/upload.ts
15948
17809
  var import_pluralize2 = __toESM(require("pluralize"));
15949
17810
 
@@ -16154,6 +18015,7 @@ var CodePrompt = class {
16154
18015
  toolFunctions;
16155
18016
  tags;
16156
18017
  metadata;
18018
+ environmentSlugs;
16157
18019
  constructor(project, prompt, toolFunctions, opts, functionType) {
16158
18020
  this.project = project;
16159
18021
  this.name = opts.name;
@@ -16166,6 +18028,7 @@ var CodePrompt = class {
16166
18028
  this.functionType = functionType;
16167
18029
  this.tags = opts.tags;
16168
18030
  this.metadata = opts.metadata;
18031
+ this.environmentSlugs = opts.environments;
16169
18032
  }
16170
18033
  async toFunctionDefinition(projectNameToId) {
16171
18034
  const prompt_data = {
@@ -16200,7 +18063,8 @@ var CodePrompt = class {
16200
18063
  prompt_data,
16201
18064
  if_exists: this.ifExists,
16202
18065
  tags: this.tags,
16203
- metadata: this.metadata
18066
+ metadata: this.metadata,
18067
+ environments: this.environmentSlugs && this.environmentSlugs.length > 0 ? this.environmentSlugs.map((slug) => ({ slug })) : void 0
16204
18068
  };
16205
18069
  }
16206
18070
  };
@@ -17753,6 +19617,7 @@ function evaluateBuildResults(inFile, buildResult) {
17753
19617
  }
17754
19618
  async function initExperiment2(evaluator, evaluatorData) {
17755
19619
  const { data, baseExperiment: defaultBaseExperiment } = evaluatorData;
19620
+ const parameters = await getExperimentParametersRef2(evaluator.parameters);
17756
19621
  const logger = init({
17757
19622
  state: evaluator.state,
17758
19623
  ...evaluator.projectId ? { projectId: evaluator.projectId } : { project: evaluator.projectName },
@@ -17767,6 +19632,7 @@ async function initExperiment2(evaluator, evaluatorData) {
17767
19632
  gitMetadataSettings: evaluator.gitMetadataSettings,
17768
19633
  repoInfo: evaluator.repoInfo,
17769
19634
  dataset: Dataset2.isDataset(data) ? data : void 0,
19635
+ parameters,
17770
19636
  setCurrent: false
17771
19637
  });
17772
19638
  const info = await logger.summarize({ summarizeScores: false });
@@ -17778,6 +19644,22 @@ async function initExperiment2(evaluator, evaluatorData) {
17778
19644
  );
17779
19645
  return logger;
17780
19646
  }
19647
+ async function getExperimentParametersRef2(parameters) {
19648
+ if (!parameters) {
19649
+ return void 0;
19650
+ }
19651
+ const resolvedParameters = parameters instanceof Promise ? await parameters : parameters;
19652
+ if (!RemoteEvalParameters.isParameters(resolvedParameters)) {
19653
+ return void 0;
19654
+ }
19655
+ if (resolvedParameters.id === void 0) {
19656
+ return void 0;
19657
+ }
19658
+ return {
19659
+ id: resolvedParameters.id,
19660
+ version: resolvedParameters.version
19661
+ };
19662
+ }
17781
19663
  function resolveReporter(reporter, reporters) {
17782
19664
  if (typeof reporter === "string") {
17783
19665
  if (!reporters[reporter]) {