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/dev/dist/index.js CHANGED
@@ -2,6 +2,64 @@
2
2
  var _nodeasync_hooks = require('node:async_hooks');
3
3
  var _nodediagnostics_channel = require('node:diagnostics_channel'); var diagnostics_channel = _interopRequireWildcard(_nodediagnostics_channel);
4
4
  var _nodepath = require('node:path'); var path = _interopRequireWildcard(_nodepath);
5
+
6
+ // src/auto-instrumentations/patch-tracing-channel.ts
7
+ function patchTracingChannel(tracingChannelFn) {
8
+ const dummyChannel = tracingChannelFn("__braintrust_probe__");
9
+ const TracingChannel = _optionalChain([dummyChannel, 'optionalAccess', _2 => _2.constructor]);
10
+ if (!_optionalChain([TracingChannel, 'optionalAccess', _3 => _3.prototype])) {
11
+ return;
12
+ }
13
+ if (!Object.getOwnPropertyDescriptor(TracingChannel.prototype, "hasSubscribers")) {
14
+ Object.defineProperty(TracingChannel.prototype, "hasSubscribers", {
15
+ configurable: true,
16
+ enumerable: false,
17
+ get() {
18
+ return Boolean(
19
+ _optionalChain([this, 'access', _4 => _4.start, 'optionalAccess', _5 => _5.hasSubscribers]) || _optionalChain([this, 'access', _6 => _6.end, 'optionalAccess', _7 => _7.hasSubscribers]) || _optionalChain([this, 'access', _8 => _8.asyncStart, 'optionalAccess', _9 => _9.hasSubscribers]) || _optionalChain([this, 'access', _10 => _10.asyncEnd, 'optionalAccess', _11 => _11.hasSubscribers]) || _optionalChain([this, 'access', _12 => _12.error, 'optionalAccess', _13 => _13.hasSubscribers])
20
+ );
21
+ }
22
+ });
23
+ }
24
+ if (TracingChannel.prototype.tracePromise) {
25
+ TracingChannel.prototype.tracePromise = function(fn, context = {}, thisArg, ...args) {
26
+ const { start, end, asyncStart, asyncEnd, error } = this;
27
+ function reject2(err) {
28
+ context.error = err;
29
+ _optionalChain([error, 'optionalAccess', _14 => _14.publish, 'call', _15 => _15(context)]);
30
+ _optionalChain([asyncStart, 'optionalAccess', _16 => _16.publish, 'call', _17 => _17(context)]);
31
+ _optionalChain([asyncEnd, 'optionalAccess', _18 => _18.publish, 'call', _19 => _19(context)]);
32
+ return Promise.reject(err);
33
+ }
34
+ function resolve(result) {
35
+ context.result = result;
36
+ _optionalChain([asyncStart, 'optionalAccess', _20 => _20.publish, 'call', _21 => _21(context)]);
37
+ _optionalChain([asyncEnd, 'optionalAccess', _22 => _22.publish, 'call', _23 => _23(context)]);
38
+ return result;
39
+ }
40
+ return start.runStores(context, () => {
41
+ try {
42
+ const result = Reflect.apply(fn, thisArg, args);
43
+ _optionalChain([end, 'optionalAccess', _24 => _24.publish, 'call', _25 => _25(context)]);
44
+ if (result && (typeof result === "object" || typeof result === "function") && typeof result.then === "function") {
45
+ return result.then(resolve, reject2);
46
+ }
47
+ context.result = result;
48
+ _optionalChain([asyncStart, 'optionalAccess', _26 => _26.publish, 'call', _27 => _27(context)]);
49
+ _optionalChain([asyncEnd, 'optionalAccess', _28 => _28.publish, 'call', _29 => _29(context)]);
50
+ return result;
51
+ } catch (err) {
52
+ context.error = err;
53
+ _optionalChain([error, 'optionalAccess', _30 => _30.publish, 'call', _31 => _31(context)]);
54
+ _optionalChain([end, 'optionalAccess', _32 => _32.publish, 'call', _33 => _33(context)]);
55
+ throw err;
56
+ }
57
+ });
58
+ };
59
+ }
60
+ }
61
+
62
+ // src/node/config.ts
5
63
  var _promises = require('node:fs/promises'); var fs = _interopRequireWildcard(_promises);
6
64
  var _nodeos = require('node:os'); var os = _interopRequireWildcard(_nodeos);
7
65
  var _nodefs = require('node:fs'); var fsSync = _interopRequireWildcard(_nodefs);
@@ -22,8 +80,54 @@ var DefaultAsyncLocalStorage = class {
22
80
  return void 0;
23
81
  }
24
82
  };
25
- var DefaultTracingChannel = (_class = class {constructor() { _class.prototype.__init.call(this); }
83
+ var DefaultChannel = (_class = class {
84
+ constructor(name) {;_class.prototype.__init.call(this);
85
+ this.name = name;
86
+ }
26
87
  __init() {this.hasSubscribers = false}
88
+ subscribe(_subscription) {
89
+ }
90
+ unsubscribe(_subscription) {
91
+ return false;
92
+ }
93
+ bindStore(_store, _transform) {
94
+ }
95
+ unbindStore(_store) {
96
+ return false;
97
+ }
98
+ publish(_message) {
99
+ }
100
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
101
+ runStores(_message, fn, thisArg, ...args) {
102
+ return fn.apply(thisArg, args);
103
+ }
104
+ }, _class);
105
+ var DefaultTracingChannel = class {
106
+
107
+
108
+
109
+
110
+
111
+ constructor(nameOrChannels) {
112
+ if (typeof nameOrChannels === "string") {
113
+ this.start = new DefaultChannel(`tracing:${nameOrChannels}:start`);
114
+ this.end = new DefaultChannel(`tracing:${nameOrChannels}:end`);
115
+ this.asyncStart = new DefaultChannel(
116
+ `tracing:${nameOrChannels}:asyncStart`
117
+ );
118
+ this.asyncEnd = new DefaultChannel(`tracing:${nameOrChannels}:asyncEnd`);
119
+ this.error = new DefaultChannel(`tracing:${nameOrChannels}:error`);
120
+ return;
121
+ }
122
+ this.start = _nullishCoalesce(nameOrChannels.start, () => ( new DefaultChannel("tracing:start")));
123
+ this.end = _nullishCoalesce(nameOrChannels.end, () => ( new DefaultChannel("tracing:end")));
124
+ this.asyncStart = _nullishCoalesce(nameOrChannels.asyncStart, () => ( new DefaultChannel("tracing:asyncStart")));
125
+ this.asyncEnd = _nullishCoalesce(nameOrChannels.asyncEnd, () => ( new DefaultChannel("tracing:asyncEnd")));
126
+ this.error = _nullishCoalesce(nameOrChannels.error, () => ( new DefaultChannel("tracing:error")));
127
+ }
128
+ get hasSubscribers() {
129
+ return this.start.hasSubscribers || this.end.hasSubscribers || this.asyncStart.hasSubscribers || this.asyncEnd.hasSubscribers || this.error.hasSubscribers;
130
+ }
27
131
  subscribe(_handlers) {
28
132
  }
29
133
  unsubscribe(_handlers) {
@@ -41,7 +145,7 @@ var DefaultTracingChannel = (_class = class {constructor() { _class.prototype.__
41
145
  traceCallback(fn, _position, _message, thisArg, ...args) {
42
146
  return fn.apply(thisArg, args);
43
147
  }
44
- }, _class);
148
+ };
45
149
  var iso = {
46
150
  buildType: "unknown",
47
151
  // Will be set by configureBrowser() or configureNode()
@@ -51,7 +155,7 @@ var iso = {
51
155
  getCallerLocation: () => void 0,
52
156
  newAsyncLocalStorage: () => new DefaultAsyncLocalStorage(),
53
157
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
54
- newTracingChannel: (_nameOrChannels) => new DefaultTracingChannel(),
158
+ newTracingChannel: (nameOrChannels) => new DefaultTracingChannel(nameOrChannels),
55
159
  processOn: (_0, _1) => {
56
160
  },
57
161
  basename: (filepath) => filepath.split(/[\\/]/).pop() || filepath,
@@ -111,8 +215,8 @@ function setDebugLogStateResolver(resolver) {
111
215
  debugLogStateResolver = resolver;
112
216
  }
113
217
  function resolveDebugLogLevel(state) {
114
- const stateLevel = _optionalChain([state, 'optionalAccess', _2 => _2.getDebugLogLevel, 'optionalCall', _3 => _3()]);
115
- const hasStateOverride = _nullishCoalesce(_optionalChain([state, 'optionalAccess', _4 => _4.hasDebugLogLevelOverride, 'optionalCall', _5 => _5()]), () => ( false));
218
+ const stateLevel = _optionalChain([state, 'optionalAccess', _34 => _34.getDebugLogLevel, 'optionalCall', _35 => _35()]);
219
+ const hasStateOverride = _nullishCoalesce(_optionalChain([state, 'optionalAccess', _36 => _36.hasDebugLogLevelOverride, 'optionalCall', _37 => _37()]), () => ( false));
116
220
  if (hasStateOverride) {
117
221
  return stateLevel;
118
222
  }
@@ -141,7 +245,7 @@ function emit(method, state, args) {
141
245
  }
142
246
  }
143
247
  function createDebugLogger(state) {
144
- const resolveState = () => _nullishCoalesce(state, () => ( _optionalChain([debugLogStateResolver, 'optionalCall', _6 => _6()])));
248
+ const resolveState = () => _nullishCoalesce(state, () => ( _optionalChain([debugLogStateResolver, 'optionalCall', _38 => _38()])));
145
249
  return {
146
250
  info(...args) {
147
251
  emit("info", resolveState(), args);
@@ -186,7 +290,7 @@ async function getBaseBranch(remote = void 0) {
186
290
  if (git === null) {
187
291
  throw new Error("Not in a git repo");
188
292
  }
189
- const remoteName = await _asyncNullishCoalesce(remote, async () => ( await _asyncOptionalChain([(await git.getRemotes()), 'access', async _7 => _7[0], 'optionalAccess', async _8 => _8.name])));
293
+ const remoteName = await _asyncNullishCoalesce(remote, async () => ( await _asyncOptionalChain([(await git.getRemotes()), 'access', async _39 => _39[0], 'optionalAccess', async _40 => _40.name])));
190
294
  if (!remoteName) {
191
295
  throw new Error("No remote found");
192
296
  }
@@ -279,7 +383,7 @@ async function getRepoInfo(settings) {
279
383
  return repo;
280
384
  }
281
385
  let sanitized = {};
282
- _optionalChain([settings, 'access', _9 => _9.fields, 'optionalAccess', _10 => _10.forEach, 'call', _11 => _11((field) => {
386
+ _optionalChain([settings, 'access', _41 => _41.fields, 'optionalAccess', _42 => _42.forEach, 'call', _43 => _43((field) => {
283
387
  sanitized = { ...sanitized, [field]: repo[field] };
284
388
  })]);
285
389
  return sanitized;
@@ -365,9 +469,9 @@ function getCallerLocation() {
365
469
  const entries = getStackTrace();
366
470
  for (const frame of entries) {
367
471
  if (thisDir === void 0) {
368
- thisDir = _optionalChain([isomorph_default, 'access', _12 => _12.pathDirname, 'optionalCall', _13 => _13(frame.fileName)]);
472
+ thisDir = _optionalChain([isomorph_default, 'access', _44 => _44.pathDirname, 'optionalCall', _45 => _45(frame.fileName)]);
369
473
  }
370
- if (_optionalChain([isomorph_default, 'access', _14 => _14.pathDirname, 'optionalCall', _15 => _15(frame.fileName)]) !== thisDir) {
474
+ if (_optionalChain([isomorph_default, 'access', _46 => _46.pathDirname, 'optionalCall', _47 => _47(frame.fileName)]) !== thisDir) {
371
475
  return {
372
476
  caller_functionname: frame.functionName,
373
477
  caller_filename: frame.fileName,
@@ -614,7 +718,7 @@ var SpanComponentsV1 = class _SpanComponentsV1 {
614
718
  return {
615
719
  objectType: this.objectType,
616
720
  objectId: this.objectId,
617
- rowIds: _optionalChain([this, 'access', _16 => _16.rowIds, 'optionalAccess', _17 => _17.toObject, 'call', _18 => _18()])
721
+ rowIds: _optionalChain([this, 'access', _48 => _48.rowIds, 'optionalAccess', _49 => _49.toObject, 'call', _50 => _50()])
618
722
  };
619
723
  }
620
724
  };
@@ -828,7 +932,7 @@ var SpanComponentsV2 = class _SpanComponentsV2 {
828
932
  objectType: this.objectType,
829
933
  objectId: this.objectId,
830
934
  computeObjectMetadataArgs: this.computeObjectMetadataArgs,
831
- rowIds: _optionalChain([this, 'access', _19 => _19.rowIds, 'optionalAccess', _20 => _20.toObject, 'call', _21 => _21()])
935
+ rowIds: _optionalChain([this, 'access', _51 => _51.rowIds, 'optionalAccess', _52 => _52.toObject, 'call', _53 => _53()])
832
936
  };
833
937
  }
834
938
  };
@@ -1368,20 +1472,20 @@ function slugify(text, options) {
1368
1472
  \u00FF: "y"
1369
1473
  };
1370
1474
  const replacement = "-";
1371
- const trim = _optionalChain([options, 'optionalAccess', _22 => _22.trim]) !== false;
1475
+ const trim = _optionalChain([options, 'optionalAccess', _54 => _54.trim]) !== false;
1372
1476
  let slug = text.normalize().split("").reduce((result, ch) => {
1373
1477
  const mapped = charMap[ch] || ch;
1374
1478
  const appendChar = mapped === replacement ? " " : mapped;
1375
1479
  return result + appendChar.replace(/[^\w\s$*_+~.()'"!\-:@]+/g, "");
1376
1480
  }, "");
1377
- if (_optionalChain([options, 'optionalAccess', _23 => _23.strict])) {
1481
+ if (_optionalChain([options, 'optionalAccess', _55 => _55.strict])) {
1378
1482
  slug = slug.replace(/[^A-Za-z0-9\s]/g, "");
1379
1483
  }
1380
1484
  if (trim) {
1381
1485
  slug = slug.trim();
1382
1486
  }
1383
1487
  slug = slug.replace(/\s+/g, replacement);
1384
- if (_optionalChain([options, 'optionalAccess', _24 => _24.lower])) {
1488
+ if (_optionalChain([options, 'optionalAccess', _56 => _56.lower])) {
1385
1489
  slug = slug.toLowerCase();
1386
1490
  }
1387
1491
  return slug;
@@ -2334,6 +2438,8 @@ var Experiment = _v3.z.object({
2334
2438
  deleted_at: _v3.z.union([_v3.z.string(), _v3.z.null()]).optional(),
2335
2439
  dataset_id: _v3.z.union([_v3.z.string(), _v3.z.null()]).optional(),
2336
2440
  dataset_version: _v3.z.union([_v3.z.string(), _v3.z.null()]).optional(),
2441
+ parameters_id: _v3.z.union([_v3.z.string(), _v3.z.null()]).optional(),
2442
+ parameters_version: _v3.z.union([_v3.z.string(), _v3.z.null()]).optional(),
2337
2443
  public: _v3.z.boolean(),
2338
2444
  user_id: _v3.z.union([_v3.z.string(), _v3.z.null()]).optional(),
2339
2445
  metadata: _v3.z.union([_v3.z.object({}).partial().passthrough(), _v3.z.null()]).optional(),
@@ -2356,7 +2462,11 @@ var SpanType = _v3.z.union([
2356
2462
  _v3.z.null()
2357
2463
  ]);
2358
2464
  var SpanAttributes = _v3.z.union([
2359
- _v3.z.object({ name: _v3.z.union([_v3.z.string(), _v3.z.null()]), type: SpanType }).partial().passthrough(),
2465
+ _v3.z.object({
2466
+ name: _v3.z.union([_v3.z.string(), _v3.z.null()]),
2467
+ type: SpanType,
2468
+ purpose: _v3.z.union([_v3.z.literal("scorer"), _v3.z.null()])
2469
+ }).partial().passthrough(),
2360
2470
  _v3.z.null()
2361
2471
  ]);
2362
2472
  var ExperimentEvent = _v3.z.object({
@@ -2796,6 +2906,7 @@ var FunctionId = _v3.z.union([
2796
2906
  version: _v3.z.string()
2797
2907
  }),
2798
2908
  code: _v3.z.string(),
2909
+ function_type: FunctionTypeEnum.and(_v3.z.unknown()).optional(),
2799
2910
  name: _v3.z.union([_v3.z.string(), _v3.z.null()]).optional()
2800
2911
  }),
2801
2912
  _v3.z.object({
@@ -3025,7 +3136,12 @@ var TopicAutomationConfig = _v3.z.object({
3025
3136
  topic_map_functions: _v3.z.array(TopicMapFunctionAutomation),
3026
3137
  scope: _v3.z.union([SpanScope, TraceScope, GroupScope, _v3.z.null()]).optional(),
3027
3138
  data_scope: TopicAutomationDataScope.optional(),
3028
- btql_filter: _v3.z.union([_v3.z.string(), _v3.z.null()]).optional()
3139
+ btql_filter: _v3.z.union([_v3.z.string(), _v3.z.null()]).optional(),
3140
+ backfill_time_range: _v3.z.union([
3141
+ _v3.z.string(),
3142
+ _v3.z.object({ from: _v3.z.string(), to: _v3.z.string() }),
3143
+ _v3.z.null()
3144
+ ]).optional()
3029
3145
  });
3030
3146
  var ProjectAutomation = _v3.z.object({
3031
3147
  id: _v3.z.string().uuid(),
@@ -3508,8 +3624,8 @@ var mustachePlugin = {
3508
3624
  defaultOptions: { strict: true, escape: jsonEscape },
3509
3625
  createRenderer() {
3510
3626
  const opts = _nullishCoalesce(this.defaultOptions, () => ( {}));
3511
- const escapeFn = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _25 => _25.escape]), () => ( jsonEscape));
3512
- const strictDefault = typeof _optionalChain([opts, 'optionalAccess', _26 => _26.strict]) === "boolean" ? opts.strict : true;
3627
+ const escapeFn = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _57 => _57.escape]), () => ( jsonEscape));
3628
+ const strictDefault = typeof _optionalChain([opts, 'optionalAccess', _58 => _58.strict]) === "boolean" ? opts.strict : true;
3513
3629
  return {
3514
3630
  render(template, variables, escape, strict) {
3515
3631
  const esc = _nullishCoalesce(escape, () => ( escapeFn));
@@ -3543,7 +3659,7 @@ var TemplatePluginRegistry = (_class5 = class {constructor() { _class5.prototype
3543
3659
  return Array.from(this.plugins.keys());
3544
3660
  }
3545
3661
  get(name) {
3546
- return _optionalChain([this, 'access', _27 => _27.plugins, 'access', _28 => _28.get, 'call', _29 => _29(name), 'optionalAccess', _30 => _30.renderer]);
3662
+ return _optionalChain([this, 'access', _59 => _59.plugins, 'access', _60 => _60.get, 'call', _61 => _61(name), 'optionalAccess', _62 => _62.renderer]);
3547
3663
  }
3548
3664
  isRegistered(name) {
3549
3665
  return this.plugins.has(name);
@@ -4177,7 +4293,7 @@ var SpanCache = (_class6 = class {
4177
4293
  // Small in-memory index tracking which rootSpanIds have data
4178
4294
  __init14() {this.rootSpanIndex = /* @__PURE__ */ new Set()}
4179
4295
  constructor(options) {;_class6.prototype.__init8.call(this);_class6.prototype.__init9.call(this);_class6.prototype.__init10.call(this);_class6.prototype.__init11.call(this);_class6.prototype.__init12.call(this);_class6.prototype.__init13.call(this);_class6.prototype.__init14.call(this);_class6.prototype.__init15.call(this);_class6.prototype.__init16.call(this);_class6.prototype.__init17.call(this);
4180
- this._explicitlyDisabled = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _31 => _31.disabled]), () => ( false));
4296
+ this._explicitlyDisabled = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _63 => _63.disabled]), () => ( false));
4181
4297
  }
4182
4298
  /**
4183
4299
  * Disable the cache at runtime. This is called automatically when
@@ -4448,6 +4564,9 @@ var BRAINTRUST_ATTACHMENT = BraintrustAttachmentReference.shape.type.value;
4448
4564
  var EXTERNAL_ATTACHMENT = ExternalAttachmentReference.shape.type.value;
4449
4565
  var LOGS3_OVERFLOW_REFERENCE_TYPE = "logs3_overflow";
4450
4566
  var BRAINTRUST_PARAMS = Object.keys(BraintrustModelParams.shape);
4567
+ var RESET_CONTEXT_MANAGER_STATE = Symbol.for(
4568
+ "braintrust.resetContextManagerState"
4569
+ );
4451
4570
  var DEFAULT_MAX_REQUEST_SIZE = 6 * 1024 * 1024;
4452
4571
  var parametersRowSchema = _v3.z.object({
4453
4572
  id: _v3.z.string().uuid(),
@@ -4464,6 +4583,12 @@ var parametersRowSchema = _v3.z.object({
4464
4583
  }),
4465
4584
  metadata: _v3.z.union([_v3.z.object({}).partial().passthrough(), _v3.z.null()]).optional()
4466
4585
  });
4586
+ var InlineAttachmentReferenceSchema = _v3.z.object({
4587
+ type: _v3.z.literal("inline_attachment"),
4588
+ src: _v3.z.string().min(1),
4589
+ content_type: _v3.z.string().optional(),
4590
+ filename: _v3.z.string().optional()
4591
+ });
4467
4592
  var LoginInvalidOrgError = class extends Error {
4468
4593
  constructor(message) {
4469
4594
  super(message);
@@ -4504,13 +4629,18 @@ function applyMaskingToField(maskingFunction, data, fieldName) {
4504
4629
  return `ERROR: Failed to mask field '${fieldName}' - ${errorType}`;
4505
4630
  }
4506
4631
  }
4632
+ var BRAINTRUST_CURRENT_SPAN_STORE = Symbol.for(
4633
+ "braintrust.currentSpanStore"
4634
+ );
4507
4635
  var ContextManager = class {
4508
4636
  };
4509
4637
  var BraintrustContextManager = class extends ContextManager {
4510
4638
 
4639
+
4511
4640
  constructor() {
4512
4641
  super();
4513
4642
  this._currentSpan = isomorph_default.newAsyncLocalStorage();
4643
+ this[BRAINTRUST_CURRENT_SPAN_STORE] = this._currentSpan;
4514
4644
  }
4515
4645
  getParentSpanIds() {
4516
4646
  const currentSpan2 = this._currentSpan.getStore();
@@ -4561,7 +4691,7 @@ var NoopSpan = (_class7 = class {
4561
4691
  return this;
4562
4692
  }
4563
4693
  end(args) {
4564
- return _nullishCoalesce(_optionalChain([args, 'optionalAccess', _32 => _32.endTime]), () => ( getCurrentUnixTimestamp()));
4694
+ return _nullishCoalesce(_optionalChain([args, 'optionalAccess', _64 => _64.endTime]), () => ( getCurrentUnixTimestamp()));
4565
4695
  }
4566
4696
  async export() {
4567
4697
  return "";
@@ -4717,6 +4847,9 @@ var BraintrustState = (_class8 = class _BraintrustState {
4717
4847
  resetIdGenState() {
4718
4848
  this._idGenerator = null;
4719
4849
  }
4850
+ [RESET_CONTEXT_MANAGER_STATE]() {
4851
+ this._contextManager = null;
4852
+ }
4720
4853
  get idGenerator() {
4721
4854
  if (this._idGenerator === null) {
4722
4855
  this._idGenerator = getIdGenerator();
@@ -4823,8 +4956,8 @@ var BraintrustState = (_class8 = class _BraintrustState {
4823
4956
  setFetch(fetch2) {
4824
4957
  this.loginParams.fetch = fetch2;
4825
4958
  this.fetch = fetch2;
4826
- _optionalChain([this, 'access', _33 => _33._apiConn, 'optionalAccess', _34 => _34.setFetch, 'call', _35 => _35(fetch2)]);
4827
- _optionalChain([this, 'access', _36 => _36._appConn, 'optionalAccess', _37 => _37.setFetch, 'call', _38 => _38(fetch2)]);
4959
+ _optionalChain([this, 'access', _65 => _65._apiConn, 'optionalAccess', _66 => _66.setFetch, 'call', _67 => _67(fetch2)]);
4960
+ _optionalChain([this, 'access', _68 => _68._appConn, 'optionalAccess', _69 => _69.setFetch, 'call', _70 => _70(fetch2)]);
4828
4961
  }
4829
4962
  setMaskingFunction(maskingFunction) {
4830
4963
  this.bgLogger().setMaskingFunction(maskingFunction);
@@ -5526,8 +5659,8 @@ function _getOrgName(orgName) {
5526
5659
  return orgName || isomorph_default.getEnv("BRAINTRUST_ORG_NAME") || void 0;
5527
5660
  }
5528
5661
  function _getLinkBaseUrl(state, linkArgs) {
5529
- const appUrl = _getAppUrl(state.appUrl || _optionalChain([linkArgs, 'optionalAccess', _39 => _39.app_url]));
5530
- const orgName = _getOrgName(state.orgName || _optionalChain([linkArgs, 'optionalAccess', _40 => _40.org_name]));
5662
+ const appUrl = _getAppUrl(state.appUrl || _optionalChain([linkArgs, 'optionalAccess', _71 => _71.app_url]));
5663
+ const orgName = _getOrgName(state.orgName || _optionalChain([linkArgs, 'optionalAccess', _72 => _72.org_name]));
5531
5664
  if (!orgName) {
5532
5665
  return null;
5533
5666
  }
@@ -5537,9 +5670,9 @@ async function permalink(slug, opts) {
5537
5670
  if (slug === "") {
5538
5671
  return NOOP_SPAN_PERMALINK;
5539
5672
  }
5540
- const state = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _41 => _41.state]), () => ( _globalState));
5673
+ const state = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _73 => _73.state]), () => ( _globalState));
5541
5674
  const getOrgName = async () => {
5542
- if (_optionalChain([opts, 'optionalAccess', _42 => _42.orgName])) {
5675
+ if (_optionalChain([opts, 'optionalAccess', _74 => _74.orgName])) {
5543
5676
  return opts.orgName;
5544
5677
  }
5545
5678
  await state.login({});
@@ -5549,7 +5682,7 @@ async function permalink(slug, opts) {
5549
5682
  return state.orgName;
5550
5683
  };
5551
5684
  const getAppUrl = async () => {
5552
- if (_optionalChain([opts, 'optionalAccess', _43 => _43.appUrl])) {
5685
+ if (_optionalChain([opts, 'optionalAccess', _75 => _75.appUrl])) {
5553
5686
  return opts.appUrl;
5554
5687
  }
5555
5688
  await state.login({});
@@ -5684,7 +5817,7 @@ var Logger = (_class9 = class {
5684
5817
  * @returns The `id` of the logged event.
5685
5818
  */
5686
5819
  log(event, options) {
5687
- if (this.calledStartSpan && !_optionalChain([options, 'optionalAccess', _44 => _44.allowConcurrentWithSpans])) {
5820
+ if (this.calledStartSpan && !_optionalChain([options, 'optionalAccess', _76 => _76.allowConcurrentWithSpans])) {
5688
5821
  throw new Error(
5689
5822
  "Cannot run toplevel `log` method while using spans. To log to the span, call `logger.traced` and then log with `span.log`"
5690
5823
  );
@@ -5752,12 +5885,12 @@ var Logger = (_class9 = class {
5752
5885
  state: this.state,
5753
5886
  ...startSpanParentArgs({
5754
5887
  state: this.state,
5755
- parent: _optionalChain([args, 'optionalAccess', _45 => _45.parent]),
5888
+ parent: _optionalChain([args, 'optionalAccess', _77 => _77.parent]),
5756
5889
  parentObjectType: this.parentObjectType(),
5757
5890
  parentObjectId: this.lazyId,
5758
5891
  parentComputeObjectMetadataArgs: this.computeMetadataArgs,
5759
- parentSpanIds: _optionalChain([args, 'optionalAccess', _46 => _46.parentSpanIds]),
5760
- propagatedEvent: _optionalChain([args, 'optionalAccess', _47 => _47.propagatedEvent])
5892
+ parentSpanIds: _optionalChain([args, 'optionalAccess', _78 => _78.parentSpanIds]),
5893
+ propagatedEvent: _optionalChain([args, 'optionalAccess', _79 => _79.propagatedEvent])
5761
5894
  }),
5762
5895
  defaultRootType: "task" /* TASK */
5763
5896
  });
@@ -6092,7 +6225,7 @@ var HTTPBackgroundLogger = (_class10 = class _HTTPBackgroundLogger {
6092
6225
  this.queue.clear();
6093
6226
  return;
6094
6227
  }
6095
- const batchSize = _nullishCoalesce(_optionalChain([args, 'optionalAccess', _48 => _48.batchSize]), () => ( this.defaultBatchSize));
6228
+ const batchSize = _nullishCoalesce(_optionalChain([args, 'optionalAccess', _80 => _80.batchSize]), () => ( this.defaultBatchSize));
6096
6229
  const wrappedItems = this.queue.drain();
6097
6230
  if (wrappedItems.length === 0) {
6098
6231
  return;
@@ -6406,10 +6539,10 @@ Error: ${errorText}`;
6406
6539
  } catch (err) {
6407
6540
  if (err instanceof AggregateError) {
6408
6541
  for (const e of err.errors) {
6409
- _optionalChain([this, 'access', _49 => _49.onFlushError, 'optionalCall', _50 => _50(e)]);
6542
+ _optionalChain([this, 'access', _81 => _81.onFlushError, 'optionalCall', _82 => _82(e)]);
6410
6543
  }
6411
6544
  } else {
6412
- _optionalChain([this, 'access', _51 => _51.onFlushError, 'optionalCall', _52 => _52(err)]);
6545
+ _optionalChain([this, 'access', _83 => _83.onFlushError, 'optionalCall', _84 => _84(err)]);
6413
6546
  }
6414
6547
  this.activeFlushError = err;
6415
6548
  } finally {
@@ -6453,6 +6586,7 @@ function init(projectOrOptions, optionalOptions) {
6453
6586
  experiment,
6454
6587
  description,
6455
6588
  dataset,
6589
+ parameters,
6456
6590
  baseExperiment,
6457
6591
  isPublic,
6458
6592
  open: open2,
@@ -6570,6 +6704,17 @@ function init(projectOrOptions, optionalOptions) {
6570
6704
  args["dataset_version"] = await dataset.version();
6571
6705
  }
6572
6706
  }
6707
+ if (parameters !== void 0) {
6708
+ if (RemoteEvalParameters.isParameters(parameters)) {
6709
+ args["parameters_id"] = parameters.id;
6710
+ args["parameters_version"] = parameters.version;
6711
+ } else {
6712
+ args["parameters_id"] = parameters.id;
6713
+ if (parameters.version !== void 0) {
6714
+ args["parameters_version"] = parameters.version;
6715
+ }
6716
+ }
6717
+ }
6573
6718
  if (isPublic !== void 0) {
6574
6719
  args["public"] = isPublic;
6575
6720
  }
@@ -6824,24 +6969,24 @@ async function loginToState(options = {}) {
6824
6969
  return state;
6825
6970
  }
6826
6971
  function currentExperiment(options) {
6827
- const state = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _53 => _53.state]), () => ( _globalState));
6972
+ const state = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _85 => _85.state]), () => ( _globalState));
6828
6973
  return state.currentExperiment;
6829
6974
  }
6830
6975
  function currentLogger(options) {
6831
- const state = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _54 => _54.state]), () => ( _globalState));
6832
- return castLogger(state.currentLogger, _optionalChain([options, 'optionalAccess', _55 => _55.asyncFlush]));
6976
+ const state = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _86 => _86.state]), () => ( _globalState));
6977
+ return castLogger(state.currentLogger, _optionalChain([options, 'optionalAccess', _87 => _87.asyncFlush]));
6833
6978
  }
6834
6979
  function currentSpan(options) {
6835
- const state = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _56 => _56.state]), () => ( _globalState));
6980
+ const state = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _88 => _88.state]), () => ( _globalState));
6836
6981
  return _nullishCoalesce(state.contextManager.getCurrentSpan(), () => ( NOOP_SPAN));
6837
6982
  }
6838
6983
  function getSpanParentObject(options) {
6839
- const state = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _57 => _57.state]), () => ( _globalState));
6984
+ const state = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _89 => _89.state]), () => ( _globalState));
6840
6985
  const parentSpan = currentSpan({ state });
6841
6986
  if (!Object.is(parentSpan, NOOP_SPAN)) {
6842
6987
  return parentSpan;
6843
6988
  }
6844
- const parentStr = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _58 => _58.parent]), () => ( state.currentParent.getStore()));
6989
+ const parentStr = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _90 => _90.parent]), () => ( state.currentParent.getStore()));
6845
6990
  if (parentStr) return getSpanComponentsClass().fromStr(parentStr);
6846
6991
  const experiment = currentExperiment();
6847
6992
  if (experiment) {
@@ -6870,7 +7015,7 @@ function traced(callback, args) {
6870
7015
  const { span, isSyncFlushLogger } = startSpanAndIsLogger(args);
6871
7016
  const ret = runCatchFinally(
6872
7017
  () => {
6873
- if (_nullishCoalesce(_optionalChain([args, 'optionalAccess', _59 => _59.setCurrent]), () => ( true))) {
7018
+ if (_nullishCoalesce(_optionalChain([args, 'optionalAccess', _91 => _91.setCurrent]), () => ( true))) {
6874
7019
  return withCurrent(span, callback);
6875
7020
  } else {
6876
7021
  return callback(span);
@@ -6882,7 +7027,7 @@ function traced(callback, args) {
6882
7027
  },
6883
7028
  () => span.end()
6884
7029
  );
6885
- if (_optionalChain([args, 'optionalAccess', _60 => _60.asyncFlush]) === void 0 || _optionalChain([args, 'optionalAccess', _61 => _61.asyncFlush])) {
7030
+ if (_optionalChain([args, 'optionalAccess', _92 => _92.asyncFlush]) === void 0 || _optionalChain([args, 'optionalAccess', _93 => _93.asyncFlush])) {
6886
7031
  return ret;
6887
7032
  } else {
6888
7033
  return (async () => {
@@ -6898,14 +7043,14 @@ function startSpan(args) {
6898
7043
  return startSpanAndIsLogger(args).span;
6899
7044
  }
6900
7045
  async function flush(options) {
6901
- const state = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _62 => _62.state]), () => ( _globalState));
7046
+ const state = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _94 => _94.state]), () => ( _globalState));
6902
7047
  return await state.bgLogger().flush();
6903
7048
  }
6904
7049
  function startSpanAndIsLogger(args) {
6905
- const state = _nullishCoalesce(_optionalChain([args, 'optionalAccess', _63 => _63.state]), () => ( _globalState));
7050
+ const state = _nullishCoalesce(_optionalChain([args, 'optionalAccess', _95 => _95.state]), () => ( _globalState));
6906
7051
  const parentObject = getSpanParentObject({
6907
- asyncFlush: _optionalChain([args, 'optionalAccess', _64 => _64.asyncFlush]),
6908
- parent: _optionalChain([args, 'optionalAccess', _65 => _65.parent]),
7052
+ asyncFlush: _optionalChain([args, 'optionalAccess', _96 => _96.asyncFlush]),
7053
+ parent: _optionalChain([args, 'optionalAccess', _97 => _97.parent]),
6909
7054
  state
6910
7055
  });
6911
7056
  if (parentObject instanceof SpanComponentsV3 || parentObject instanceof SpanComponentsV4) {
@@ -6922,14 +7067,14 @@ function startSpanAndIsLogger(args) {
6922
7067
  ),
6923
7068
  parentComputeObjectMetadataArgs: _nullishCoalesce(parentObject.data.compute_object_metadata_args, () => ( void 0)),
6924
7069
  parentSpanIds,
6925
- propagatedEvent: _nullishCoalesce(_optionalChain([args, 'optionalAccess', _66 => _66.propagatedEvent]), () => ( // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
7070
+ propagatedEvent: _nullishCoalesce(_optionalChain([args, 'optionalAccess', _98 => _98.propagatedEvent]), () => ( // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
6926
7071
  (_nullishCoalesce(parentObject.data.propagated_event, () => ( void 0)))))
6927
7072
  });
6928
7073
  return {
6929
7074
  span,
6930
7075
  isSyncFlushLogger: parentObject.data.object_type === 2 /* PROJECT_LOGS */ && // Since there's no parent logger here, we're free to choose the async flush
6931
7076
  // behavior, and therefore propagate along whatever we get from the arguments
6932
- _optionalChain([args, 'optionalAccess', _67 => _67.asyncFlush]) === false
7077
+ _optionalChain([args, 'optionalAccess', _99 => _99.asyncFlush]) === false
6933
7078
  };
6934
7079
  } else {
6935
7080
  const span = parentObject.startSpan(args);
@@ -7077,10 +7222,10 @@ function extractAttachments(event, attachments) {
7077
7222
  event[key] = value.reference;
7078
7223
  continue;
7079
7224
  }
7080
- if (_optionalChain([value, 'optionalAccess', _68 => _68.type]) === BRAINTRUST_ATTACHMENT && value.key && !value.uploader) {
7225
+ if (_optionalChain([value, 'optionalAccess', _100 => _100.type]) === BRAINTRUST_ATTACHMENT && value.key && !value.uploader) {
7081
7226
  continue;
7082
7227
  }
7083
- if (_optionalChain([value, 'optionalAccess', _69 => _69.reference, 'optionalAccess', _70 => _70.type]) === BRAINTRUST_ATTACHMENT && _optionalChain([value, 'optionalAccess', _71 => _71.uploader])) {
7228
+ if (_optionalChain([value, 'optionalAccess', _101 => _101.reference, 'optionalAccess', _102 => _102.type]) === BRAINTRUST_ATTACHMENT && _optionalChain([value, 'optionalAccess', _103 => _103.uploader])) {
7084
7229
  const attachment = new Attachment({
7085
7230
  data: value.dataDebugString,
7086
7231
  filename: value.reference.filename,
@@ -7164,7 +7309,7 @@ var ObjectFetcher = (_class11 = class {
7164
7309
  const state = await this.getState();
7165
7310
  const objectId = await this.id;
7166
7311
  const batchLimit = _nullishCoalesce(batchSize, () => ( DEFAULT_FETCH_BATCH_SIZE));
7167
- const internalLimit = _optionalChain([this, 'access', _72 => _72._internal_btql, 'optionalAccess', _73 => _73.limit]);
7312
+ const internalLimit = _optionalChain([this, 'access', _104 => _104._internal_btql, 'optionalAccess', _105 => _105.limit]);
7168
7313
  const limit = batchSize !== void 0 ? batchSize : _nullishCoalesce(internalLimit, () => ( batchLimit));
7169
7314
  const internalBtqlWithoutReservedQueryKeys = Object.fromEntries(
7170
7315
  Object.entries(_nullishCoalesce(this._internal_btql, () => ( {}))).filter(
@@ -7238,7 +7383,7 @@ var ObjectFetcher = (_class11 = class {
7238
7383
  }
7239
7384
  return;
7240
7385
  }
7241
- for await (const record of this.fetchRecordsFromApi(_optionalChain([options, 'optionalAccess', _74 => _74.batchSize]))) {
7386
+ for await (const record of this.fetchRecordsFromApi(_optionalChain([options, 'optionalAccess', _106 => _106.batchSize]))) {
7242
7387
  yield record;
7243
7388
  }
7244
7389
  }
@@ -7248,7 +7393,7 @@ var ObjectFetcher = (_class11 = class {
7248
7393
  async fetchedData(options) {
7249
7394
  if (this._fetchedData === void 0) {
7250
7395
  const data = [];
7251
- for await (const record of this.fetchRecordsFromApi(_optionalChain([options, 'optionalAccess', _75 => _75.batchSize]))) {
7396
+ for await (const record of this.fetchRecordsFromApi(_optionalChain([options, 'optionalAccess', _107 => _107.batchSize]))) {
7252
7397
  data.push(record);
7253
7398
  }
7254
7399
  this._fetchedData = data;
@@ -7343,7 +7488,7 @@ var Experiment2 = (_class12 = class extends ObjectFetcher {
7343
7488
  * @returns The `id` of the logged event.
7344
7489
  */
7345
7490
  log(event, options) {
7346
- if (this.calledStartSpan && !_optionalChain([options, 'optionalAccess', _76 => _76.allowConcurrentWithSpans])) {
7491
+ if (this.calledStartSpan && !_optionalChain([options, 'optionalAccess', _108 => _108.allowConcurrentWithSpans])) {
7347
7492
  throw new Error(
7348
7493
  "Cannot run toplevel `log` method while using spans. To log to the span, call `experiment.traced` and then log with `span.log`"
7349
7494
  );
@@ -7396,12 +7541,12 @@ var Experiment2 = (_class12 = class extends ObjectFetcher {
7396
7541
  state: this.state,
7397
7542
  ...startSpanParentArgs({
7398
7543
  state: this.state,
7399
- parent: _optionalChain([args, 'optionalAccess', _77 => _77.parent]),
7544
+ parent: _optionalChain([args, 'optionalAccess', _109 => _109.parent]),
7400
7545
  parentObjectType: this.parentObjectType(),
7401
7546
  parentObjectId: this.lazyId,
7402
7547
  parentComputeObjectMetadataArgs: void 0,
7403
7548
  parentSpanIds: void 0,
7404
- propagatedEvent: _optionalChain([args, 'optionalAccess', _78 => _78.propagatedEvent])
7549
+ propagatedEvent: _optionalChain([args, 'optionalAccess', _110 => _110.propagatedEvent])
7405
7550
  }),
7406
7551
  defaultRootType: "eval" /* EVAL */
7407
7552
  });
@@ -7745,7 +7890,7 @@ var SpanImpl = (_class13 = class _SpanImpl {
7745
7890
  ...serializableInternalData,
7746
7891
  [IS_MERGE_FIELD]: this.isMerge
7747
7892
  });
7748
- if (typeof _optionalChain([partialRecord, 'access', _79 => _79.metrics, 'optionalAccess', _80 => _80.end]) === "number") {
7893
+ if (typeof _optionalChain([partialRecord, 'access', _111 => _111.metrics, 'optionalAccess', _112 => _112.end]) === "number") {
7749
7894
  this.loggedEndTime = partialRecord.metrics.end;
7750
7895
  }
7751
7896
  if (this.parentObjectType === 1 /* EXPERIMENT */) {
@@ -7805,18 +7950,18 @@ var SpanImpl = (_class13 = class _SpanImpl {
7805
7950
  );
7806
7951
  }
7807
7952
  startSpan(args) {
7808
- const parentSpanIds = _optionalChain([args, 'optionalAccess', _81 => _81.parent]) ? void 0 : { spanId: this._spanId, rootSpanId: this._rootSpanId };
7953
+ const parentSpanIds = _optionalChain([args, 'optionalAccess', _113 => _113.parent]) ? void 0 : { spanId: this._spanId, rootSpanId: this._rootSpanId };
7809
7954
  return new _SpanImpl({
7810
7955
  state: this._state,
7811
7956
  ...args,
7812
7957
  ...startSpanParentArgs({
7813
7958
  state: this._state,
7814
- parent: _optionalChain([args, 'optionalAccess', _82 => _82.parent]),
7959
+ parent: _optionalChain([args, 'optionalAccess', _114 => _114.parent]),
7815
7960
  parentObjectType: this.parentObjectType,
7816
7961
  parentObjectId: this.parentObjectId,
7817
7962
  parentComputeObjectMetadataArgs: this.parentComputeObjectMetadataArgs,
7818
7963
  parentSpanIds,
7819
- propagatedEvent: _nullishCoalesce(_optionalChain([args, 'optionalAccess', _83 => _83.propagatedEvent]), () => ( this.propagatedEvent))
7964
+ propagatedEvent: _nullishCoalesce(_optionalChain([args, 'optionalAccess', _115 => _115.propagatedEvent]), () => ( this.propagatedEvent))
7820
7965
  })
7821
7966
  });
7822
7967
  }
@@ -7830,12 +7975,12 @@ var SpanImpl = (_class13 = class _SpanImpl {
7830
7975
  ...args,
7831
7976
  ...startSpanParentArgs({
7832
7977
  state: this._state,
7833
- parent: _optionalChain([args, 'optionalAccess', _84 => _84.parent]),
7978
+ parent: _optionalChain([args, 'optionalAccess', _116 => _116.parent]),
7834
7979
  parentObjectType: this.parentObjectType,
7835
7980
  parentObjectId: this.parentObjectId,
7836
7981
  parentComputeObjectMetadataArgs: this.parentComputeObjectMetadataArgs,
7837
7982
  parentSpanIds,
7838
- propagatedEvent: _nullishCoalesce(_optionalChain([args, 'optionalAccess', _85 => _85.propagatedEvent]), () => ( this.propagatedEvent))
7983
+ propagatedEvent: _nullishCoalesce(_optionalChain([args, 'optionalAccess', _117 => _117.propagatedEvent]), () => ( this.propagatedEvent))
7839
7984
  }),
7840
7985
  spanId
7841
7986
  });
@@ -7844,7 +7989,7 @@ var SpanImpl = (_class13 = class _SpanImpl {
7844
7989
  let endTime;
7845
7990
  let internalData = {};
7846
7991
  if (!this.loggedEndTime) {
7847
- endTime = _nullishCoalesce(_optionalChain([args, 'optionalAccess', _86 => _86.endTime]), () => ( getCurrentUnixTimestamp()));
7992
+ endTime = _nullishCoalesce(_optionalChain([args, 'optionalAccess', _118 => _118.endTime]), () => ( getCurrentUnixTimestamp()));
7848
7993
  internalData = { metrics: { end: endTime } };
7849
7994
  } else {
7850
7995
  endTime = this.loggedEndTime;
@@ -7895,8 +8040,8 @@ var SpanImpl = (_class13 = class _SpanImpl {
7895
8040
  const args = this.parentComputeObjectMetadataArgs;
7896
8041
  switch (this.parentObjectType) {
7897
8042
  case 2 /* PROJECT_LOGS */: {
7898
- const projectID = _optionalChain([args, 'optionalAccess', _87 => _87.project_id]) || this.parentObjectId.getSync().value;
7899
- const projectName = _optionalChain([args, 'optionalAccess', _88 => _88.project_name]);
8043
+ const projectID = _optionalChain([args, 'optionalAccess', _119 => _119.project_id]) || this.parentObjectId.getSync().value;
8044
+ const projectName = _optionalChain([args, 'optionalAccess', _120 => _120.project_name]);
7900
8045
  if (projectID) {
7901
8046
  return `${baseUrl}/object?object_type=project_logs&object_id=${projectID}&id=${this._id}`;
7902
8047
  } else if (projectName) {
@@ -7906,7 +8051,7 @@ var SpanImpl = (_class13 = class _SpanImpl {
7906
8051
  }
7907
8052
  }
7908
8053
  case 1 /* EXPERIMENT */: {
7909
- const expID = _optionalChain([args, 'optionalAccess', _89 => _89.experiment_id]) || _optionalChain([this, 'access', _90 => _90.parentObjectId, 'optionalAccess', _91 => _91.getSync, 'call', _92 => _92(), 'optionalAccess', _93 => _93.value]);
8054
+ const expID = _optionalChain([args, 'optionalAccess', _121 => _121.experiment_id]) || _optionalChain([this, 'access', _122 => _122.parentObjectId, 'optionalAccess', _123 => _123.getSync, 'call', _124 => _124(), 'optionalAccess', _125 => _125.value]);
7910
8055
  if (!expID) {
7911
8056
  return getErrPermlink("provide-experiment-id");
7912
8057
  } else {
@@ -8221,40 +8366,82 @@ var Dataset2 = (_class14 = class extends ObjectFetcher {
8221
8366
  return typeof data === "object" && data !== null && "__braintrust_dataset_marker" in data;
8222
8367
  }
8223
8368
  }, _class14);
8224
- function renderMessage(render, message) {
8369
+ function isAttachmentObject(value) {
8370
+ return BraintrustAttachmentReference.safeParse(value).success || InlineAttachmentReferenceSchema.safeParse(value).success || ExternalAttachmentReference.safeParse(value).success;
8371
+ }
8372
+ function isURL(url) {
8373
+ try {
8374
+ const parsedUrl = new URL(url.trim());
8375
+ return parsedUrl.protocol === "http:" || parsedUrl.protocol === "https:";
8376
+ } catch (e18) {
8377
+ return false;
8378
+ }
8379
+ }
8380
+ function expandAttachmentArrayPreTemplate(content, variables) {
8381
+ if (typeof content !== "string") return null;
8382
+ const match = content.match(/^\{\{\s*([\w.]+)\s*\}\}$/);
8383
+ if (!match) return null;
8384
+ const varPath = match[1];
8385
+ const value = varPath.includes(".") ? getObjValueByPath(variables, varPath.split(".")) : variables[varPath];
8386
+ if (!Array.isArray(value)) return null;
8387
+ const allValid = value.every(
8388
+ (v) => isAttachmentObject(v) || typeof v === "string" && isURL(v)
8389
+ );
8390
+ if (!allValid) return null;
8391
+ return value.map((item) => ({
8392
+ type: "image_url",
8393
+ image_url: { url: item }
8394
+ }));
8395
+ }
8396
+ function renderMessageImpl(render, message, variables) {
8225
8397
  return {
8226
8398
  ...message,
8227
8399
  ..."content" in message ? {
8228
- content: isEmpty2(message.content) ? void 0 : typeof message.content === "string" ? render(message.content) : message.content.map((c) => {
8400
+ content: isEmpty2(message.content) ? void 0 : typeof message.content === "string" ? render(message.content) : message.content.flatMap((c) => {
8229
8401
  switch (c.type) {
8230
8402
  case "text":
8231
- return { ...c, text: render(c.text) };
8403
+ return [{ ...c, text: render(c.text) }];
8232
8404
  case "image_url":
8233
8405
  if (isObject(c.image_url.url)) {
8234
8406
  throw new Error(
8235
8407
  "Attachments must be replaced with URLs before calling `build()`"
8236
8408
  );
8237
8409
  }
8238
- return {
8239
- ...c,
8240
- image_url: {
8241
- ...c.image_url,
8242
- url: render(c.image_url.url)
8410
+ if (variables) {
8411
+ const expanded = expandAttachmentArrayPreTemplate(
8412
+ c.image_url.url,
8413
+ variables
8414
+ );
8415
+ if (expanded) {
8416
+ return expanded;
8243
8417
  }
8244
- };
8418
+ }
8419
+ return [
8420
+ {
8421
+ ...c,
8422
+ image_url: {
8423
+ ...c.image_url,
8424
+ url: render(c.image_url.url)
8425
+ }
8426
+ }
8427
+ ];
8245
8428
  case "file":
8246
- return {
8247
- ...c,
8248
- file: {
8249
- file_data: render(c.file.file_data || ""),
8250
- ...c.file.file_id && {
8251
- file_id: render(c.file.file_id)
8252
- },
8253
- ...c.file.filename && {
8254
- filename: render(c.file.filename)
8429
+ return [
8430
+ {
8431
+ ...c,
8432
+ file: {
8433
+ ...c.file.file_data && {
8434
+ file_data: render(c.file.file_data)
8435
+ },
8436
+ ...c.file.file_id && {
8437
+ file_id: render(c.file.file_id)
8438
+ },
8439
+ ...c.file.filename && {
8440
+ filename: render(c.file.filename)
8441
+ }
8255
8442
  }
8256
8443
  }
8257
- };
8444
+ ];
8258
8445
  default:
8259
8446
  const _exhaustiveCheck = c;
8260
8447
  return _exhaustiveCheck;
@@ -8364,16 +8551,16 @@ var Prompt2 = (_class15 = class _Prompt {
8364
8551
  return "slug" in this.metadata ? this.metadata.slug : this.metadata.id;
8365
8552
  }
8366
8553
  get prompt() {
8367
- return _optionalChain([this, 'access', _94 => _94.getParsedPromptData, 'call', _95 => _95(), 'optionalAccess', _96 => _96.prompt]);
8554
+ return _optionalChain([this, 'access', _126 => _126.getParsedPromptData, 'call', _127 => _127(), 'optionalAccess', _128 => _128.prompt]);
8368
8555
  }
8369
8556
  get version() {
8370
8557
  return this.metadata[TRANSACTION_ID_FIELD];
8371
8558
  }
8372
8559
  get options() {
8373
- return _optionalChain([this, 'access', _97 => _97.getParsedPromptData, 'call', _98 => _98(), 'optionalAccess', _99 => _99.options]) || {};
8560
+ return _optionalChain([this, 'access', _129 => _129.getParsedPromptData, 'call', _130 => _130(), 'optionalAccess', _131 => _131.options]) || {};
8374
8561
  }
8375
8562
  get templateFormat() {
8376
- return _optionalChain([this, 'access', _100 => _100.getParsedPromptData, 'call', _101 => _101(), 'optionalAccess', _102 => _102.template_format]);
8563
+ return _optionalChain([this, 'access', _132 => _132.getParsedPromptData, 'call', _133 => _133(), 'optionalAccess', _134 => _134.template_format]);
8377
8564
  }
8378
8565
  get promptData() {
8379
8566
  return this.getParsedPromptData();
@@ -8411,17 +8598,19 @@ var Prompt2 = (_class15 = class _Prompt {
8411
8598
  }
8412
8599
  runBuild(buildArgs, options) {
8413
8600
  const { flavor } = options;
8414
- const params = {
8415
- ...this.defaults,
8416
- ...Object.fromEntries(
8417
- Object.entries(this.options.params || {}).filter(
8418
- ([k, _v]) => !BRAINTRUST_PARAMS.includes(k)
8419
- )
8420
- ),
8421
- ...!isEmpty2(this.options.model) ? {
8422
- model: this.options.model
8423
- } : {}
8424
- };
8601
+ const params = Object.fromEntries(
8602
+ Object.entries({
8603
+ ...this.defaults,
8604
+ ...Object.fromEntries(
8605
+ Object.entries(this.options.params || {}).filter(
8606
+ ([k, _v]) => !BRAINTRUST_PARAMS.includes(k)
8607
+ )
8608
+ ),
8609
+ ...!isEmpty2(this.options.model) ? {
8610
+ model: this.options.model
8611
+ } : {}
8612
+ }).filter(([key, value]) => key !== "response_format" || value !== null)
8613
+ );
8425
8614
  if (!("model" in params) || isEmpty2(params.model)) {
8426
8615
  throw new Error(
8427
8616
  "No model specified. Either specify it in the prompt or as a default"
@@ -8521,7 +8710,7 @@ var Prompt2 = (_class15 = class _Prompt {
8521
8710
  templateFormat
8522
8711
  });
8523
8712
  const baseMessages = (prompt.messages || []).map(
8524
- (m) => renderMessage(render, m)
8713
+ (m) => renderMessageImpl(render, m, variables)
8525
8714
  );
8526
8715
  const hasSystemPrompt = baseMessages.some((m) => m.role === "system");
8527
8716
  const messages = [
@@ -8533,7 +8722,7 @@ var Prompt2 = (_class15 = class _Prompt {
8533
8722
  return {
8534
8723
  type: "chat",
8535
8724
  messages,
8536
- ..._optionalChain([prompt, 'access', _103 => _103.tools, 'optionalAccess', _104 => _104.trim, 'call', _105 => _105()]) ? {
8725
+ ..._optionalChain([prompt, 'access', _135 => _135.tools, 'optionalAccess', _136 => _136.trim, 'call', _137 => _137()]) ? {
8537
8726
  tools: render(prompt.tools)
8538
8727
  } : void 0
8539
8728
  };
@@ -8749,7 +8938,7 @@ function getChannelSpanInfo(event) {
8749
8938
  if (isObject(event.span_info)) {
8750
8939
  return event.span_info;
8751
8940
  }
8752
- const firstArg = _optionalChain([event, 'access', _106 => _106.arguments, 'optionalAccess', _107 => _107[0]]);
8941
+ const firstArg = _optionalChain([event, 'access', _138 => _138.arguments, 'optionalAccess', _139 => _139[0]]);
8753
8942
  if (hasChannelSpanInfo(firstArg)) {
8754
8943
  return firstArg.span_info;
8755
8944
  }
@@ -8760,13 +8949,13 @@ function buildStartSpanArgs(config, event) {
8760
8949
  const spanAttributes = {
8761
8950
  type: config.type
8762
8951
  };
8763
- if (isObject(_optionalChain([spanInfo, 'optionalAccess', _108 => _108.spanAttributes]))) {
8952
+ if (isObject(_optionalChain([spanInfo, 'optionalAccess', _140 => _140.spanAttributes]))) {
8764
8953
  mergeDicts(spanAttributes, spanInfo.spanAttributes);
8765
8954
  }
8766
8955
  return {
8767
- name: typeof _optionalChain([spanInfo, 'optionalAccess', _109 => _109.name]) === "string" && spanInfo.name ? spanInfo.name : config.name,
8956
+ name: typeof _optionalChain([spanInfo, 'optionalAccess', _141 => _141.name]) === "string" && spanInfo.name ? spanInfo.name : config.name,
8768
8957
  spanAttributes,
8769
- spanInfoMetadata: isObject(_optionalChain([spanInfo, 'optionalAccess', _110 => _110.metadata])) ? spanInfo.metadata : void 0
8958
+ spanInfoMetadata: isObject(_optionalChain([spanInfo, 'optionalAccess', _142 => _142.metadata])) ? spanInfo.metadata : void 0
8770
8959
  };
8771
8960
  }
8772
8961
  function mergeInputMetadata(metadata, spanInfoMetadata) {
@@ -8856,7 +9045,7 @@ var BasePlugin = (_class17 = class {constructor() { _class17.prototype.__init62.
8856
9045
  try {
8857
9046
  const output = config.extractOutput(event.result, event);
8858
9047
  const metrics = config.extractMetrics(event.result, startTime, event);
8859
- const metadata = _optionalChain([config, 'access', _111 => _111.extractMetadata, 'optionalCall', _112 => _112(event.result, event)]);
9048
+ const metadata = _optionalChain([config, 'access', _143 => _143.extractMetadata, 'optionalCall', _144 => _144(event.result, event)]);
8860
9049
  span.log({
8861
9050
  output,
8862
9051
  ...metadata !== void 0 ? { metadata } : {},
@@ -9149,7 +9338,11 @@ function startSpanForEvent(config, event, channelName) {
9149
9338
  });
9150
9339
  const startTime = getCurrentUnixTimestamp();
9151
9340
  try {
9152
- const { input, metadata } = config.extractInput(event.arguments);
9341
+ const { input, metadata } = config.extractInput(
9342
+ event.arguments,
9343
+ event,
9344
+ span
9345
+ );
9153
9346
  span.log({
9154
9347
  input,
9155
9348
  metadata: mergeInputMetadata(metadata, spanInfoMetadata)
@@ -9159,6 +9352,36 @@ function startSpanForEvent(config, event, channelName) {
9159
9352
  }
9160
9353
  return { span, startTime };
9161
9354
  }
9355
+ function ensureSpanStateForEvent(states, config, event, channelName) {
9356
+ const key = event;
9357
+ const existing = states.get(key);
9358
+ if (existing) {
9359
+ return existing;
9360
+ }
9361
+ const created = startSpanForEvent(config, event, channelName);
9362
+ states.set(key, created);
9363
+ return created;
9364
+ }
9365
+ function bindCurrentSpanStoreToStart(tracingChannel2, states, config, channelName) {
9366
+ const state = _internalGetGlobalState();
9367
+ const startChannel = tracingChannel2.start;
9368
+ const currentSpanStore = _optionalChain([state, 'optionalAccess', _145 => _145.contextManager]) ? state.contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
9369
+ if (!currentSpanStore || !startChannel) {
9370
+ return void 0;
9371
+ }
9372
+ startChannel.bindStore(
9373
+ currentSpanStore,
9374
+ (event) => ensureSpanStateForEvent(
9375
+ states,
9376
+ config,
9377
+ event,
9378
+ channelName
9379
+ ).span
9380
+ );
9381
+ return () => {
9382
+ startChannel.unbindStore(currentSpanStore);
9383
+ };
9384
+ }
9162
9385
  function logErrorAndEnd(states, event) {
9163
9386
  const spanData = states.get(event);
9164
9387
  if (!spanData) {
@@ -9174,15 +9397,19 @@ function traceAsyncChannel(channel2, config) {
9174
9397
  const tracingChannel2 = channel2.tracingChannel();
9175
9398
  const states = /* @__PURE__ */ new WeakMap();
9176
9399
  const channelName = channel2.channelName;
9400
+ const unbindCurrentSpanStore = bindCurrentSpanStoreToStart(
9401
+ tracingChannel2,
9402
+ states,
9403
+ config,
9404
+ channelName
9405
+ );
9177
9406
  const handlers = {
9178
9407
  start: (event) => {
9179
- states.set(
9408
+ ensureSpanStateForEvent(
9409
+ states,
9410
+ config,
9180
9411
  event,
9181
- startSpanForEvent(
9182
- config,
9183
- event,
9184
- channelName
9185
- )
9412
+ channelName
9186
9413
  );
9187
9414
  },
9188
9415
  asyncEnd: (event) => {
@@ -9202,7 +9429,7 @@ function traceAsyncChannel(channel2, config) {
9202
9429
  startTime,
9203
9430
  asyncEndEvent
9204
9431
  );
9205
- const metadata = _optionalChain([config, 'access', _113 => _113.extractMetadata, 'optionalCall', _114 => _114(
9432
+ const metadata = _optionalChain([config, 'access', _146 => _146.extractMetadata, 'optionalCall', _147 => _147(
9206
9433
  asyncEndEvent.result,
9207
9434
  asyncEndEvent
9208
9435
  )]);
@@ -9224,6 +9451,7 @@ function traceAsyncChannel(channel2, config) {
9224
9451
  };
9225
9452
  tracingChannel2.subscribe(handlers);
9226
9453
  return () => {
9454
+ _optionalChain([unbindCurrentSpanStore, 'optionalCall', _148 => _148()]);
9227
9455
  tracingChannel2.unsubscribe(handlers);
9228
9456
  };
9229
9457
  }
@@ -9231,15 +9459,19 @@ function traceStreamingChannel(channel2, config) {
9231
9459
  const tracingChannel2 = channel2.tracingChannel();
9232
9460
  const states = /* @__PURE__ */ new WeakMap();
9233
9461
  const channelName = channel2.channelName;
9462
+ const unbindCurrentSpanStore = bindCurrentSpanStoreToStart(
9463
+ tracingChannel2,
9464
+ states,
9465
+ config,
9466
+ channelName
9467
+ );
9234
9468
  const handlers = {
9235
9469
  start: (event) => {
9236
- states.set(
9470
+ ensureSpanStateForEvent(
9471
+ states,
9472
+ config,
9237
9473
  event,
9238
- startSpanForEvent(
9239
- config,
9240
- event,
9241
- channelName
9242
- )
9474
+ channelName
9243
9475
  );
9244
9476
  },
9245
9477
  asyncEnd: (event) => {
@@ -9313,6 +9545,16 @@ function traceStreamingChannel(channel2, config) {
9313
9545
  });
9314
9546
  return;
9315
9547
  }
9548
+ if (_optionalChain([config, 'access', _149 => _149.patchResult, 'optionalCall', _150 => _150({
9549
+ channelName,
9550
+ endEvent: asyncEndEvent,
9551
+ result: asyncEndEvent.result,
9552
+ span,
9553
+ startTime
9554
+ })])) {
9555
+ states.delete(event);
9556
+ return;
9557
+ }
9316
9558
  try {
9317
9559
  const output = config.extractOutput(
9318
9560
  asyncEndEvent.result,
@@ -9323,7 +9565,7 @@ function traceStreamingChannel(channel2, config) {
9323
9565
  startTime,
9324
9566
  asyncEndEvent
9325
9567
  );
9326
- const metadata = _optionalChain([config, 'access', _115 => _115.extractMetadata, 'optionalCall', _116 => _116(
9568
+ const metadata = _optionalChain([config, 'access', _151 => _151.extractMetadata, 'optionalCall', _152 => _152(
9327
9569
  asyncEndEvent.result,
9328
9570
  asyncEndEvent
9329
9571
  )]);
@@ -9345,6 +9587,7 @@ function traceStreamingChannel(channel2, config) {
9345
9587
  };
9346
9588
  tracingChannel2.subscribe(handlers);
9347
9589
  return () => {
9590
+ _optionalChain([unbindCurrentSpanStore, 'optionalCall', _153 => _153()]);
9348
9591
  tracingChannel2.unsubscribe(handlers);
9349
9592
  };
9350
9593
  }
@@ -9352,15 +9595,19 @@ function traceSyncStreamChannel(channel2, config) {
9352
9595
  const tracingChannel2 = channel2.tracingChannel();
9353
9596
  const states = /* @__PURE__ */ new WeakMap();
9354
9597
  const channelName = channel2.channelName;
9598
+ const unbindCurrentSpanStore = bindCurrentSpanStoreToStart(
9599
+ tracingChannel2,
9600
+ states,
9601
+ config,
9602
+ channelName
9603
+ );
9355
9604
  const handlers = {
9356
9605
  start: (event) => {
9357
- states.set(
9606
+ ensureSpanStateForEvent(
9607
+ states,
9608
+ config,
9358
9609
  event,
9359
- startSpanForEvent(
9360
- config,
9361
- event,
9362
- channelName
9363
- )
9610
+ channelName
9364
9611
  );
9365
9612
  },
9366
9613
  end: (event) => {
@@ -9369,8 +9616,17 @@ function traceSyncStreamChannel(channel2, config) {
9369
9616
  return;
9370
9617
  }
9371
9618
  const { span, startTime } = spanData;
9372
- const resultEvent = event;
9373
- const stream = resultEvent.result;
9619
+ const endEvent = event;
9620
+ if (_optionalChain([config, 'access', _154 => _154.patchResult, 'optionalCall', _155 => _155({
9621
+ channelName,
9622
+ endEvent,
9623
+ result: endEvent.result,
9624
+ span,
9625
+ startTime
9626
+ })])) {
9627
+ return;
9628
+ }
9629
+ const stream = endEvent.result;
9374
9630
  if (!isSyncStreamLike(stream)) {
9375
9631
  span.end();
9376
9632
  states.delete(event);
@@ -9440,6 +9696,7 @@ function traceSyncStreamChannel(channel2, config) {
9440
9696
  };
9441
9697
  tracingChannel2.subscribe(handlers);
9442
9698
  return () => {
9699
+ _optionalChain([unbindCurrentSpanStore, 'optionalCall', _156 => _156()]);
9443
9700
  tracingChannel2.unsubscribe(handlers);
9444
9701
  };
9445
9702
  }
@@ -9502,7 +9759,7 @@ function convertDataToBlob(data, mediaType) {
9502
9759
  } else if (typeof Buffer !== "undefined" && data instanceof Buffer) {
9503
9760
  return new Blob([data], { type: mediaType });
9504
9761
  }
9505
- } catch (e18) {
9762
+ } catch (e19) {
9506
9763
  return null;
9507
9764
  }
9508
9765
  return null;
@@ -9514,7 +9771,7 @@ function processInputAttachments(input) {
9514
9771
  let attachmentIndex = 0;
9515
9772
  const inferMediaTypeFromDataUrl = (value, fallback2) => {
9516
9773
  const mediaTypeMatch = value.match(/^data:([^;]+);/);
9517
- return _optionalChain([mediaTypeMatch, 'optionalAccess', _117 => _117[1]]) || fallback2;
9774
+ return _optionalChain([mediaTypeMatch, 'optionalAccess', _157 => _157[1]]) || fallback2;
9518
9775
  };
9519
9776
  const toAttachment = (value, mediaType, filename) => {
9520
9777
  const blob = convertDataToBlob(value, mediaType);
@@ -9764,11 +10021,11 @@ var OpenAIPlugin = class extends BasePlugin {
9764
10021
  };
9765
10022
  },
9766
10023
  extractOutput: (result) => {
9767
- return _optionalChain([result, 'optionalAccess', _118 => _118.choices]);
10024
+ return _optionalChain([result, 'optionalAccess', _158 => _158.choices]);
9768
10025
  },
9769
10026
  extractMetrics: (result, startTime, endEvent) => {
9770
10027
  const metrics = withCachedMetric(
9771
- parseMetricsFromUsage(_optionalChain([result, 'optionalAccess', _119 => _119.usage])),
10028
+ parseMetricsFromUsage(_optionalChain([result, 'optionalAccess', _159 => _159.usage])),
9772
10029
  result,
9773
10030
  endEvent
9774
10031
  );
@@ -9792,12 +10049,12 @@ var OpenAIPlugin = class extends BasePlugin {
9792
10049
  };
9793
10050
  },
9794
10051
  extractOutput: (result) => {
9795
- const embedding = _optionalChain([result, 'optionalAccess', _120 => _120.data, 'optionalAccess', _121 => _121[0], 'optionalAccess', _122 => _122.embedding]);
10052
+ const embedding = _optionalChain([result, 'optionalAccess', _160 => _160.data, 'optionalAccess', _161 => _161[0], 'optionalAccess', _162 => _162.embedding]);
9796
10053
  return Array.isArray(embedding) ? { embedding_length: embedding.length } : void 0;
9797
10054
  },
9798
10055
  extractMetrics: (result, _startTime, endEvent) => {
9799
10056
  return withCachedMetric(
9800
- parseMetricsFromUsage(_optionalChain([result, 'optionalAccess', _123 => _123.usage])),
10057
+ parseMetricsFromUsage(_optionalChain([result, 'optionalAccess', _163 => _163.usage])),
9801
10058
  result,
9802
10059
  endEvent
9803
10060
  );
@@ -9816,11 +10073,11 @@ var OpenAIPlugin = class extends BasePlugin {
9816
10073
  };
9817
10074
  },
9818
10075
  extractOutput: (result) => {
9819
- return _optionalChain([result, 'optionalAccess', _124 => _124.choices]);
10076
+ return _optionalChain([result, 'optionalAccess', _164 => _164.choices]);
9820
10077
  },
9821
10078
  extractMetrics: (result, startTime, endEvent) => {
9822
10079
  const metrics = withCachedMetric(
9823
- parseMetricsFromUsage(_optionalChain([result, 'optionalAccess', _125 => _125.usage])),
10080
+ parseMetricsFromUsage(_optionalChain([result, 'optionalAccess', _165 => _165.usage])),
9824
10081
  result,
9825
10082
  endEvent
9826
10083
  );
@@ -9857,11 +10114,11 @@ var OpenAIPlugin = class extends BasePlugin {
9857
10114
  };
9858
10115
  },
9859
10116
  extractOutput: (result) => {
9860
- return _optionalChain([result, 'optionalAccess', _126 => _126.results]);
10117
+ return _optionalChain([result, 'optionalAccess', _166 => _166.results]);
9861
10118
  },
9862
10119
  extractMetrics: (result, _startTime, endEvent) => {
9863
10120
  return withCachedMetric(
9864
- parseMetricsFromUsage(_optionalChain([result, 'optionalAccess', _127 => _127.usage])),
10121
+ parseMetricsFromUsage(_optionalChain([result, 'optionalAccess', _167 => _167.usage])),
9865
10122
  result,
9866
10123
  endEvent
9867
10124
  );
@@ -9880,7 +10137,7 @@ var OpenAIPlugin = class extends BasePlugin {
9880
10137
  };
9881
10138
  },
9882
10139
  extractOutput: (result) => {
9883
- return processImagesInOutput(_optionalChain([result, 'optionalAccess', _128 => _128.output]));
10140
+ return processImagesInOutput(_optionalChain([result, 'optionalAccess', _168 => _168.output]));
9884
10141
  },
9885
10142
  extractMetadata: (result) => {
9886
10143
  if (!result) {
@@ -9891,7 +10148,7 @@ var OpenAIPlugin = class extends BasePlugin {
9891
10148
  },
9892
10149
  extractMetrics: (result, startTime, endEvent) => {
9893
10150
  const metrics = withCachedMetric(
9894
- parseMetricsFromUsage(_optionalChain([result, 'optionalAccess', _129 => _129.usage])),
10151
+ parseMetricsFromUsage(_optionalChain([result, 'optionalAccess', _169 => _169.usage])),
9895
10152
  result,
9896
10153
  endEvent
9897
10154
  );
@@ -9944,7 +10201,7 @@ var OpenAIPlugin = class extends BasePlugin {
9944
10201
  };
9945
10202
  },
9946
10203
  extractOutput: (result) => {
9947
- return processImagesInOutput(_optionalChain([result, 'optionalAccess', _130 => _130.output]));
10204
+ return processImagesInOutput(_optionalChain([result, 'optionalAccess', _170 => _170.output]));
9948
10205
  },
9949
10206
  extractMetadata: (result) => {
9950
10207
  if (!result) {
@@ -9955,7 +10212,7 @@ var OpenAIPlugin = class extends BasePlugin {
9955
10212
  },
9956
10213
  extractMetrics: (result, startTime, endEvent) => {
9957
10214
  const metrics = withCachedMetric(
9958
- parseMetricsFromUsage(_optionalChain([result, 'optionalAccess', _131 => _131.usage])),
10215
+ parseMetricsFromUsage(_optionalChain([result, 'optionalAccess', _171 => _171.usage])),
9959
10216
  result,
9960
10217
  endEvent
9961
10218
  );
@@ -10051,7 +10308,7 @@ function aggregateChatCompletionChunks(chunks, streamResult, endEvent) {
10051
10308
  ...parseMetricsFromUsage(chunk.usage)
10052
10309
  };
10053
10310
  }
10054
- const delta = _optionalChain([chunk, 'access', _132 => _132.choices, 'optionalAccess', _133 => _133[0], 'optionalAccess', _134 => _134.delta]);
10311
+ const delta = _optionalChain([chunk, 'access', _172 => _172.choices, 'optionalAccess', _173 => _173[0], 'optionalAccess', _174 => _174.delta]);
10055
10312
  if (!delta) {
10056
10313
  continue;
10057
10314
  }
@@ -10109,14 +10366,14 @@ function aggregateResponseStreamEvents(chunks, _streamResult, endEvent) {
10109
10366
  continue;
10110
10367
  }
10111
10368
  const response = chunk.response;
10112
- if (_optionalChain([response, 'optionalAccess', _135 => _135.output]) !== void 0) {
10369
+ if (_optionalChain([response, 'optionalAccess', _175 => _175.output]) !== void 0) {
10113
10370
  output = processImagesInOutput(response.output);
10114
10371
  }
10115
10372
  const { usage: _usage, output: _output, ...rest } = response || {};
10116
10373
  if (Object.keys(rest).length > 0) {
10117
10374
  metadata = rest;
10118
10375
  }
10119
- metrics = parseMetricsFromUsage(_optionalChain([response, 'optionalAccess', _136 => _136.usage]));
10376
+ metrics = parseMetricsFromUsage(_optionalChain([response, 'optionalAccess', _176 => _176.usage]));
10120
10377
  }
10121
10378
  return {
10122
10379
  output,
@@ -10182,7 +10439,7 @@ var AnthropicPlugin = class extends BasePlugin {
10182
10439
  return message ? { role: message.role, content: message.content } : null;
10183
10440
  },
10184
10441
  extractMetrics: (message, startTime) => {
10185
- const metrics = parseMetricsFromUsage2(_optionalChain([message, 'optionalAccess', _137 => _137.usage]));
10442
+ const metrics = parseMetricsFromUsage2(_optionalChain([message, 'optionalAccess', _177 => _177.usage]));
10186
10443
  if (startTime) {
10187
10444
  metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
10188
10445
  }
@@ -10197,7 +10454,7 @@ var AnthropicPlugin = class extends BasePlugin {
10197
10454
  const metadata = {};
10198
10455
  const metas = ["stop_reason", "stop_sequence"];
10199
10456
  for (const m of metas) {
10200
- if (_optionalChain([message, 'optionalAccess', _138 => _138[m]]) !== void 0) {
10457
+ if (_optionalChain([message, 'optionalAccess', _178 => _178[m]]) !== void 0) {
10201
10458
  metadata[m] = message[m];
10202
10459
  }
10203
10460
  }
@@ -10238,15 +10495,15 @@ function aggregateAnthropicStreamChunks(chunks) {
10238
10495
  let metrics = {};
10239
10496
  let metadata = {};
10240
10497
  for (const event of chunks) {
10241
- switch (_optionalChain([event, 'optionalAccess', _139 => _139.type])) {
10498
+ switch (_optionalChain([event, 'optionalAccess', _179 => _179.type])) {
10242
10499
  case "message_start":
10243
- if (_optionalChain([event, 'access', _140 => _140.message, 'optionalAccess', _141 => _141.usage])) {
10500
+ if (_optionalChain([event, 'access', _180 => _180.message, 'optionalAccess', _181 => _181.usage])) {
10244
10501
  const initialMetrics = parseMetricsFromUsage2(event.message.usage);
10245
10502
  metrics = { ...metrics, ...initialMetrics };
10246
10503
  }
10247
10504
  break;
10248
10505
  case "content_block_delta":
10249
- if (_optionalChain([event, 'access', _142 => _142.delta, 'optionalAccess', _143 => _143.type]) === "text_delta") {
10506
+ if (_optionalChain([event, 'access', _182 => _182.delta, 'optionalAccess', _183 => _183.type]) === "text_delta") {
10250
10507
  const text = event.delta.text;
10251
10508
  if (text) {
10252
10509
  deltas.push(text);
@@ -10341,6 +10598,108 @@ function filterFrom(obj, fieldsToRemove) {
10341
10598
  return result;
10342
10599
  }
10343
10600
 
10601
+ // src/wrappers/ai-sdk/normalize-logged-output.ts
10602
+ var REMOVE_NORMALIZED_VALUE = Symbol("braintrust.ai-sdk.remove-normalized");
10603
+ function normalizeAISDKLoggedOutput(value) {
10604
+ const normalized = normalizeAISDKLoggedValue(value);
10605
+ return normalized === REMOVE_NORMALIZED_VALUE ? {} : normalized;
10606
+ }
10607
+ function normalizeAISDKLoggedValue(value, context = {}) {
10608
+ if (Array.isArray(value)) {
10609
+ return value.map((entry) => normalizeAISDKLoggedValue(entry, context)).filter((entry) => entry !== REMOVE_NORMALIZED_VALUE);
10610
+ }
10611
+ if (!value || typeof value !== "object") {
10612
+ return value;
10613
+ }
10614
+ const nextInProviderMetadata = context.inProviderMetadata || context.parentKey === "providerMetadata" || context.parentKey === "experimental_providerMetadata";
10615
+ const normalizedEntries = [];
10616
+ for (const [key, entry] of Object.entries(value)) {
10617
+ if (key === "cachedPromptTokens" && entry === 0) {
10618
+ continue;
10619
+ }
10620
+ if (context.parentKey === "request" && key === "body" && entry === "<omitted>") {
10621
+ continue;
10622
+ }
10623
+ const normalizedEntry = normalizeAISDKLoggedValue(entry, {
10624
+ inProviderMetadata: nextInProviderMetadata,
10625
+ parentKey: key
10626
+ });
10627
+ if (normalizedEntry === REMOVE_NORMALIZED_VALUE) {
10628
+ continue;
10629
+ }
10630
+ normalizedEntries.push([key, normalizedEntry]);
10631
+ }
10632
+ if (normalizedEntries.length === 0) {
10633
+ if (context.parentKey === "request" || nextInProviderMetadata) {
10634
+ return REMOVE_NORMALIZED_VALUE;
10635
+ }
10636
+ return {};
10637
+ }
10638
+ return Object.fromEntries(normalizedEntries);
10639
+ }
10640
+
10641
+ // src/zod/utils.ts
10642
+ var _zodtojsonschema = require('zod-to-json-schema');
10643
+ var _v4 = require('zod/v4'); var z42 = _interopRequireWildcard(_v4);
10644
+ function isZodV4(zodObject) {
10645
+ return typeof zodObject === "object" && zodObject !== null && "_zod" in zodObject && zodObject._zod !== void 0;
10646
+ }
10647
+ function zodToJsonSchema(schema) {
10648
+ if (isZodV4(schema)) {
10649
+ return z42.toJSONSchema(schema, {
10650
+ target: "draft-7"
10651
+ });
10652
+ }
10653
+ return _zodtojsonschema.zodToJsonSchema.call(void 0, schema);
10654
+ }
10655
+
10656
+ // src/wrappers/ai-sdk/tool-serialization.ts
10657
+ function isZodSchema(value) {
10658
+ return value != null && typeof value === "object" && "_def" in value && typeof value._def === "object";
10659
+ }
10660
+ function serializeZodSchema(schema) {
10661
+ try {
10662
+ return zodToJsonSchema(schema);
10663
+ } catch (e20) {
10664
+ return {
10665
+ type: "object",
10666
+ description: "Zod schema (conversion failed)"
10667
+ };
10668
+ }
10669
+ }
10670
+ function serializeTool(tool) {
10671
+ if (!tool || typeof tool !== "object") {
10672
+ return tool;
10673
+ }
10674
+ const serialized = { ...tool };
10675
+ if (isZodSchema(serialized.inputSchema)) {
10676
+ serialized.inputSchema = serializeZodSchema(serialized.inputSchema);
10677
+ }
10678
+ if (isZodSchema(serialized.parameters)) {
10679
+ serialized.parameters = serializeZodSchema(serialized.parameters);
10680
+ }
10681
+ if ("execute" in serialized) {
10682
+ delete serialized.execute;
10683
+ }
10684
+ if ("render" in serialized) {
10685
+ delete serialized.render;
10686
+ }
10687
+ return serialized;
10688
+ }
10689
+ function serializeAISDKToolsForLogging(tools) {
10690
+ if (!tools || typeof tools !== "object") {
10691
+ return tools;
10692
+ }
10693
+ if (Array.isArray(tools)) {
10694
+ return tools.map(serializeTool);
10695
+ }
10696
+ const serialized = {};
10697
+ for (const [key, tool] of Object.entries(tools)) {
10698
+ serialized[key] = serializeTool(tool);
10699
+ }
10700
+ return serialized;
10701
+ }
10702
+
10344
10703
  // src/instrumentation/plugins/ai-sdk-channels.ts
10345
10704
  var aiSDKChannels = defineChannels("ai", {
10346
10705
  generateText: channel({
@@ -10351,6 +10710,10 @@ var aiSDKChannels = defineChannels("ai", {
10351
10710
  channelName: "streamText",
10352
10711
  kind: "async"
10353
10712
  }),
10713
+ streamTextSync: channel({
10714
+ channelName: "streamText.sync",
10715
+ kind: "sync-stream"
10716
+ }),
10354
10717
  generateObject: channel({
10355
10718
  channelName: "generateObject",
10356
10719
  kind: "async"
@@ -10359,6 +10722,10 @@ var aiSDKChannels = defineChannels("ai", {
10359
10722
  channelName: "streamObject",
10360
10723
  kind: "async"
10361
10724
  }),
10725
+ streamObjectSync: channel({
10726
+ channelName: "streamObject.sync",
10727
+ kind: "sync-stream"
10728
+ }),
10362
10729
  agentGenerate: channel({
10363
10730
  channelName: "Agent.generate",
10364
10731
  kind: "async"
@@ -10366,6 +10733,14 @@ var aiSDKChannels = defineChannels("ai", {
10366
10733
  agentStream: channel({
10367
10734
  channelName: "Agent.stream",
10368
10735
  kind: "async"
10736
+ }),
10737
+ toolLoopAgentGenerate: channel({
10738
+ channelName: "ToolLoopAgent.generate",
10739
+ kind: "async"
10740
+ }),
10741
+ toolLoopAgentStream: channel({
10742
+ channelName: "ToolLoopAgent.stream",
10743
+ kind: "async"
10369
10744
  })
10370
10745
  });
10371
10746
 
@@ -10384,6 +10759,8 @@ var DEFAULT_DENY_OUTPUT_PATHS = [
10384
10759
  "steps[].response.body",
10385
10760
  "steps[].response.headers"
10386
10761
  ];
10762
+ var AUTO_PATCHED_MODEL = Symbol.for("braintrust.ai-sdk.auto-patched-model");
10763
+ var AUTO_PATCHED_TOOL = Symbol.for("braintrust.ai-sdk.auto-patched-tool");
10387
10764
  var AISDKPlugin = class extends BasePlugin {
10388
10765
 
10389
10766
  constructor(config = {}) {
@@ -10402,22 +10779,12 @@ var AISDKPlugin = class extends BasePlugin {
10402
10779
  traceStreamingChannel(aiSDKChannels.generateText, {
10403
10780
  name: "generateText",
10404
10781
  type: "llm" /* LLM */,
10405
- extractInput: ([params]) => {
10406
- return {
10407
- input: processAISDKInput(params),
10408
- metadata: extractMetadataFromParams(params)
10409
- };
10410
- },
10411
- extractOutput: (result) => {
10782
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
10783
+ extractOutput: (result, endEvent) => {
10784
+ finalizeAISDKChildTracing(endEvent);
10412
10785
  return processAISDKOutput(result, denyOutputPaths);
10413
10786
  },
10414
- extractMetrics: (result, startTime) => {
10415
- const metrics = extractTokenMetrics(result);
10416
- if (startTime) {
10417
- metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
10418
- }
10419
- return metrics;
10420
- },
10787
+ extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
10421
10788
  aggregateChunks: aggregateAISDKChunks
10422
10789
  })
10423
10790
  );
@@ -10425,45 +10792,43 @@ var AISDKPlugin = class extends BasePlugin {
10425
10792
  traceStreamingChannel(aiSDKChannels.streamText, {
10426
10793
  name: "streamText",
10427
10794
  type: "llm" /* LLM */,
10428
- extractInput: ([params]) => {
10429
- return {
10430
- input: processAISDKInput(params),
10431
- metadata: extractMetadataFromParams(params)
10432
- };
10433
- },
10434
- extractOutput: (result) => {
10435
- return processAISDKOutput(result, denyOutputPaths);
10436
- },
10437
- extractMetrics: (result, startTime) => {
10438
- const metrics = extractTokenMetrics(result);
10439
- if (startTime) {
10440
- metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
10441
- }
10442
- return metrics;
10443
- },
10444
- aggregateChunks: aggregateAISDKChunks
10795
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
10796
+ extractOutput: (result) => processAISDKOutput(result, denyOutputPaths),
10797
+ extractMetrics: (result, startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent, startTime),
10798
+ aggregateChunks: aggregateAISDKChunks,
10799
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
10800
+ denyOutputPaths,
10801
+ endEvent,
10802
+ result,
10803
+ span,
10804
+ startTime
10805
+ })
10806
+ })
10807
+ );
10808
+ this.unsubscribers.push(
10809
+ traceSyncStreamChannel(aiSDKChannels.streamTextSync, {
10810
+ name: "streamText",
10811
+ type: "llm" /* LLM */,
10812
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
10813
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
10814
+ denyOutputPaths,
10815
+ endEvent,
10816
+ result,
10817
+ span,
10818
+ startTime
10819
+ })
10445
10820
  })
10446
10821
  );
10447
10822
  this.unsubscribers.push(
10448
10823
  traceStreamingChannel(aiSDKChannels.generateObject, {
10449
10824
  name: "generateObject",
10450
10825
  type: "llm" /* LLM */,
10451
- extractInput: ([params]) => {
10452
- return {
10453
- input: processAISDKInput(params),
10454
- metadata: extractMetadataFromParams(params)
10455
- };
10456
- },
10457
- extractOutput: (result) => {
10826
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
10827
+ extractOutput: (result, endEvent) => {
10828
+ finalizeAISDKChildTracing(endEvent);
10458
10829
  return processAISDKOutput(result, denyOutputPaths);
10459
10830
  },
10460
- extractMetrics: (result, startTime) => {
10461
- const metrics = extractTokenMetrics(result);
10462
- if (startTime) {
10463
- metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
10464
- }
10465
- return metrics;
10466
- },
10831
+ extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
10467
10832
  aggregateChunks: aggregateAISDKChunks
10468
10833
  })
10469
10834
  );
@@ -10471,45 +10836,43 @@ var AISDKPlugin = class extends BasePlugin {
10471
10836
  traceStreamingChannel(aiSDKChannels.streamObject, {
10472
10837
  name: "streamObject",
10473
10838
  type: "llm" /* LLM */,
10474
- extractInput: ([params]) => {
10475
- return {
10476
- input: processAISDKInput(params),
10477
- metadata: extractMetadataFromParams(params)
10478
- };
10479
- },
10480
- extractOutput: (result) => {
10481
- return processAISDKOutput(result, denyOutputPaths);
10482
- },
10483
- extractMetrics: (result, startTime) => {
10484
- const metrics = extractTokenMetrics(result);
10485
- if (startTime) {
10486
- metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
10487
- }
10488
- return metrics;
10489
- },
10490
- aggregateChunks: aggregateAISDKChunks
10839
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
10840
+ extractOutput: (result) => processAISDKOutput(result, denyOutputPaths),
10841
+ extractMetrics: (result, startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent, startTime),
10842
+ aggregateChunks: aggregateAISDKChunks,
10843
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
10844
+ denyOutputPaths,
10845
+ endEvent,
10846
+ result,
10847
+ span,
10848
+ startTime
10849
+ })
10850
+ })
10851
+ );
10852
+ this.unsubscribers.push(
10853
+ traceSyncStreamChannel(aiSDKChannels.streamObjectSync, {
10854
+ name: "streamObject",
10855
+ type: "llm" /* LLM */,
10856
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
10857
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
10858
+ denyOutputPaths,
10859
+ endEvent,
10860
+ result,
10861
+ span,
10862
+ startTime
10863
+ })
10491
10864
  })
10492
10865
  );
10493
10866
  this.unsubscribers.push(
10494
10867
  traceStreamingChannel(aiSDKChannels.agentGenerate, {
10495
10868
  name: "Agent.generate",
10496
10869
  type: "llm" /* LLM */,
10497
- extractInput: ([params]) => {
10498
- return {
10499
- input: processAISDKInput(params),
10500
- metadata: extractMetadataFromParams(params)
10501
- };
10502
- },
10503
- extractOutput: (result) => {
10870
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
10871
+ extractOutput: (result, endEvent) => {
10872
+ finalizeAISDKChildTracing(endEvent);
10504
10873
  return processAISDKOutput(result, denyOutputPaths);
10505
10874
  },
10506
- extractMetrics: (result, startTime) => {
10507
- const metrics = extractTokenMetrics(result);
10508
- if (startTime) {
10509
- metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
10510
- }
10511
- return metrics;
10512
- },
10875
+ extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
10513
10876
  aggregateChunks: aggregateAISDKChunks
10514
10877
  })
10515
10878
  );
@@ -10517,56 +10880,474 @@ var AISDKPlugin = class extends BasePlugin {
10517
10880
  traceStreamingChannel(aiSDKChannels.agentStream, {
10518
10881
  name: "Agent.stream",
10519
10882
  type: "llm" /* LLM */,
10520
- extractInput: ([params]) => {
10521
- return {
10522
- input: processAISDKInput(params),
10523
- metadata: extractMetadataFromParams(params)
10524
- };
10525
- },
10526
- extractOutput: (result) => {
10883
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
10884
+ extractOutput: (result) => processAISDKOutput(result, denyOutputPaths),
10885
+ extractMetrics: (result, startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent, startTime),
10886
+ aggregateChunks: aggregateAISDKChunks,
10887
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
10888
+ denyOutputPaths,
10889
+ endEvent,
10890
+ result,
10891
+ span,
10892
+ startTime
10893
+ })
10894
+ })
10895
+ );
10896
+ this.unsubscribers.push(
10897
+ traceStreamingChannel(aiSDKChannels.toolLoopAgentGenerate, {
10898
+ name: "ToolLoopAgent.generate",
10899
+ type: "llm" /* LLM */,
10900
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
10901
+ extractOutput: (result, endEvent) => {
10902
+ finalizeAISDKChildTracing(endEvent);
10527
10903
  return processAISDKOutput(result, denyOutputPaths);
10528
10904
  },
10529
- extractMetrics: (result, startTime) => {
10530
- const metrics = extractTokenMetrics(result);
10531
- if (startTime) {
10532
- metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
10533
- }
10534
- return metrics;
10535
- },
10905
+ extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
10536
10906
  aggregateChunks: aggregateAISDKChunks
10537
10907
  })
10538
10908
  );
10909
+ this.unsubscribers.push(
10910
+ traceStreamingChannel(aiSDKChannels.toolLoopAgentStream, {
10911
+ name: "ToolLoopAgent.stream",
10912
+ type: "llm" /* LLM */,
10913
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
10914
+ extractOutput: (result) => processAISDKOutput(result, denyOutputPaths),
10915
+ extractMetrics: (result, startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent, startTime),
10916
+ aggregateChunks: aggregateAISDKChunks,
10917
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
10918
+ denyOutputPaths,
10919
+ endEvent,
10920
+ result,
10921
+ span,
10922
+ startTime
10923
+ })
10924
+ })
10925
+ );
10539
10926
  }
10540
10927
  };
10541
10928
  function processAISDKInput(params) {
10542
10929
  if (!params) return params;
10543
- return processInputAttachments(params);
10930
+ const input = processInputAttachments(params);
10931
+ if (!input || typeof input !== "object" || Array.isArray(input)) {
10932
+ return input;
10933
+ }
10934
+ const { tools: _tools, ...rest } = input;
10935
+ return rest;
10936
+ }
10937
+ function prepareAISDKInput(params, event, span, denyOutputPaths) {
10938
+ const input = processAISDKInput(params);
10939
+ const metadata = extractMetadataFromParams(params, event.self);
10940
+ const childTracing = prepareAISDKChildTracing(
10941
+ params,
10942
+ event.self,
10943
+ span,
10944
+ denyOutputPaths
10945
+ );
10946
+ event.__braintrust_ai_sdk_model_wrapped = childTracing.modelWrapped;
10947
+ if (childTracing.cleanup) {
10948
+ event.__braintrust_ai_sdk_cleanup = childTracing.cleanup;
10949
+ }
10950
+ return {
10951
+ input,
10952
+ metadata
10953
+ };
10954
+ }
10955
+ function extractTopLevelAISDKMetrics(result, event, startTime) {
10956
+ const metrics = hasModelChildTracing(event) ? {} : extractTokenMetrics(result);
10957
+ if (startTime) {
10958
+ metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
10959
+ }
10960
+ return metrics;
10961
+ }
10962
+ function hasModelChildTracing(event) {
10963
+ return _optionalChain([event, 'optionalAccess', _184 => _184.__braintrust_ai_sdk_model_wrapped]) === true;
10544
10964
  }
10545
- function extractMetadataFromParams(params) {
10965
+ function extractMetadataFromParams(params, self) {
10546
10966
  const metadata = {
10547
10967
  braintrust: {
10548
10968
  integration_name: "ai-sdk",
10549
10969
  sdk_language: "typescript"
10550
10970
  }
10551
10971
  };
10552
- const { model, provider } = serializeModelWithProvider(params.model);
10972
+ const agentModel = self && typeof self === "object" && "model" in self && self.model ? self.model : self && typeof self === "object" && "settings" in self && _optionalChain([self, 'access', _185 => _185.settings, 'optionalAccess', _186 => _186.model]) ? _optionalChain([self, 'access', _187 => _187.settings, 'optionalAccess', _188 => _188.model]) : void 0;
10973
+ const { model, provider } = serializeModelWithProvider(
10974
+ _nullishCoalesce(params.model, () => ( agentModel))
10975
+ );
10553
10976
  if (model) {
10554
10977
  metadata.model = model;
10555
10978
  }
10556
10979
  if (provider) {
10557
10980
  metadata.provider = provider;
10558
10981
  }
10982
+ const tools = serializeAISDKToolsForLogging(params.tools);
10983
+ if (tools) {
10984
+ metadata.tools = tools;
10985
+ }
10559
10986
  return metadata;
10560
10987
  }
10988
+ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths) {
10989
+ const cleanup = [];
10990
+ const patchedModels = /* @__PURE__ */ new WeakSet();
10991
+ const patchedTools = /* @__PURE__ */ new WeakSet();
10992
+ let modelWrapped = false;
10993
+ const patchModel = (model) => {
10994
+ const resolvedModel = resolveAISDKModel(model);
10995
+ if (!resolvedModel || typeof resolvedModel !== "object" || typeof resolvedModel.doGenerate !== "function" || patchedModels.has(resolvedModel) || resolvedModel[AUTO_PATCHED_MODEL]) {
10996
+ return;
10997
+ }
10998
+ patchedModels.add(resolvedModel);
10999
+ resolvedModel[AUTO_PATCHED_MODEL] = true;
11000
+ modelWrapped = true;
11001
+ const originalDoGenerate = resolvedModel.doGenerate;
11002
+ const originalDoStream = resolvedModel.doStream;
11003
+ const baseMetadata = buildAISDKChildMetadata(resolvedModel);
11004
+ resolvedModel.doGenerate = async function doGeneratePatched(options) {
11005
+ return parentSpan.traced(
11006
+ async (span) => {
11007
+ const result = await Reflect.apply(
11008
+ originalDoGenerate,
11009
+ resolvedModel,
11010
+ [options]
11011
+ );
11012
+ span.log({
11013
+ output: processAISDKOutput(result, denyOutputPaths),
11014
+ metrics: extractTokenMetrics(result),
11015
+ ...buildResolvedMetadataPayload(result)
11016
+ });
11017
+ return result;
11018
+ },
11019
+ {
11020
+ name: "doGenerate",
11021
+ spanAttributes: {
11022
+ type: "llm" /* LLM */
11023
+ },
11024
+ event: {
11025
+ input: processAISDKInput(options),
11026
+ metadata: baseMetadata
11027
+ }
11028
+ }
11029
+ );
11030
+ };
11031
+ if (originalDoStream) {
11032
+ resolvedModel.doStream = async function doStreamPatched(options) {
11033
+ const span = parentSpan.startSpan({
11034
+ name: "doStream",
11035
+ spanAttributes: {
11036
+ type: "llm" /* LLM */
11037
+ },
11038
+ event: {
11039
+ input: processAISDKInput(options),
11040
+ metadata: baseMetadata
11041
+ }
11042
+ });
11043
+ const result = await withCurrent(
11044
+ span,
11045
+ () => Reflect.apply(originalDoStream, resolvedModel, [options])
11046
+ );
11047
+ const output = {};
11048
+ let text = "";
11049
+ let reasoning = "";
11050
+ const toolCalls = [];
11051
+ let object = void 0;
11052
+ const transformStream = new TransformStream({
11053
+ transform(chunk, controller) {
11054
+ switch (chunk.type) {
11055
+ case "text-delta":
11056
+ text += extractTextDelta(chunk);
11057
+ break;
11058
+ case "reasoning-delta":
11059
+ if (chunk.delta) {
11060
+ reasoning += chunk.delta;
11061
+ } else if (chunk.text) {
11062
+ reasoning += chunk.text;
11063
+ }
11064
+ break;
11065
+ case "tool-call":
11066
+ toolCalls.push(chunk);
11067
+ break;
11068
+ case "object":
11069
+ object = chunk.object;
11070
+ break;
11071
+ case "raw":
11072
+ if (chunk.rawValue) {
11073
+ const rawVal = chunk.rawValue;
11074
+ if (_optionalChain([rawVal, 'access', _189 => _189.delta, 'optionalAccess', _190 => _190.content])) {
11075
+ text += rawVal.delta.content;
11076
+ } else if (_optionalChain([rawVal, 'access', _191 => _191.choices, 'optionalAccess', _192 => _192[0], 'optionalAccess', _193 => _193.delta, 'optionalAccess', _194 => _194.content])) {
11077
+ text += rawVal.choices[0].delta.content;
11078
+ } else if (typeof rawVal.text === "string") {
11079
+ text += rawVal.text;
11080
+ } else if (typeof rawVal.content === "string") {
11081
+ text += rawVal.content;
11082
+ }
11083
+ }
11084
+ break;
11085
+ case "finish":
11086
+ output.text = text;
11087
+ output.reasoning = reasoning;
11088
+ output.toolCalls = toolCalls;
11089
+ output.finishReason = chunk.finishReason;
11090
+ output.usage = chunk.usage;
11091
+ if (object !== void 0) {
11092
+ output.object = object;
11093
+ }
11094
+ span.log({
11095
+ output: processAISDKOutput(
11096
+ output,
11097
+ denyOutputPaths
11098
+ ),
11099
+ metrics: extractTokenMetrics(output),
11100
+ ...buildResolvedMetadataPayload(output)
11101
+ });
11102
+ span.end();
11103
+ break;
11104
+ }
11105
+ controller.enqueue(chunk);
11106
+ }
11107
+ });
11108
+ return {
11109
+ ...result,
11110
+ stream: result.stream.pipeThrough(transformStream)
11111
+ };
11112
+ };
11113
+ }
11114
+ cleanup.push(() => {
11115
+ resolvedModel.doGenerate = originalDoGenerate;
11116
+ if (originalDoStream) {
11117
+ resolvedModel.doStream = originalDoStream;
11118
+ }
11119
+ delete resolvedModel[AUTO_PATCHED_MODEL];
11120
+ });
11121
+ };
11122
+ const patchTool = (tool, name) => {
11123
+ if (tool == null || typeof tool !== "object" || !("execute" in tool) || typeof tool.execute !== "function" || patchedTools.has(tool) || tool[AUTO_PATCHED_TOOL]) {
11124
+ return;
11125
+ }
11126
+ patchedTools.add(tool);
11127
+ tool[AUTO_PATCHED_TOOL] = true;
11128
+ const originalExecute = tool.execute;
11129
+ tool.execute = function executePatched(...args) {
11130
+ const result = Reflect.apply(originalExecute, this, args);
11131
+ if (isAsyncGenerator(result)) {
11132
+ return (async function* () {
11133
+ const span = parentSpan.startSpan({
11134
+ name,
11135
+ spanAttributes: {
11136
+ type: "tool" /* TOOL */
11137
+ }
11138
+ });
11139
+ span.log({ input: args.length === 1 ? args[0] : args });
11140
+ try {
11141
+ let lastValue;
11142
+ for await (const value of result) {
11143
+ lastValue = value;
11144
+ yield value;
11145
+ }
11146
+ span.log({ output: lastValue });
11147
+ } catch (error) {
11148
+ span.log({
11149
+ error: error instanceof Error ? error.message : String(error)
11150
+ });
11151
+ throw error;
11152
+ } finally {
11153
+ span.end();
11154
+ }
11155
+ })();
11156
+ }
11157
+ return parentSpan.traced(
11158
+ async (span) => {
11159
+ span.log({ input: args.length === 1 ? args[0] : args });
11160
+ const awaitedResult = await result;
11161
+ span.log({ output: awaitedResult });
11162
+ return awaitedResult;
11163
+ },
11164
+ {
11165
+ name,
11166
+ spanAttributes: {
11167
+ type: "tool" /* TOOL */
11168
+ }
11169
+ }
11170
+ );
11171
+ };
11172
+ cleanup.push(() => {
11173
+ tool.execute = originalExecute;
11174
+ delete tool[AUTO_PATCHED_TOOL];
11175
+ });
11176
+ };
11177
+ const patchTools = (tools) => {
11178
+ if (!tools) {
11179
+ return;
11180
+ }
11181
+ const inferName = (tool, fallback2) => tool && (tool.name || tool.toolName || tool.id) || fallback2;
11182
+ if (Array.isArray(tools)) {
11183
+ tools.forEach(
11184
+ (tool, index) => patchTool(tool, inferName(tool, `tool[${index}]`))
11185
+ );
11186
+ return;
11187
+ }
11188
+ for (const [key, tool] of Object.entries(tools)) {
11189
+ patchTool(tool, key);
11190
+ }
11191
+ };
11192
+ if (params && typeof params === "object") {
11193
+ patchModel(params.model);
11194
+ patchTools(params.tools);
11195
+ }
11196
+ if (self && typeof self === "object") {
11197
+ const selfRecord = self;
11198
+ if (selfRecord.model !== void 0) {
11199
+ patchModel(selfRecord.model);
11200
+ }
11201
+ if (selfRecord.settings && typeof selfRecord.settings === "object") {
11202
+ if (selfRecord.settings.model !== void 0) {
11203
+ patchModel(selfRecord.settings.model);
11204
+ }
11205
+ if (selfRecord.settings.tools !== void 0) {
11206
+ patchTools(selfRecord.settings.tools);
11207
+ }
11208
+ }
11209
+ }
11210
+ return {
11211
+ cleanup: cleanup.length > 0 ? () => {
11212
+ while (cleanup.length > 0) {
11213
+ _optionalChain([cleanup, 'access', _195 => _195.pop, 'call', _196 => _196(), 'optionalCall', _197 => _197()]);
11214
+ }
11215
+ } : void 0,
11216
+ modelWrapped
11217
+ };
11218
+ }
11219
+ function finalizeAISDKChildTracing(event) {
11220
+ const cleanup = _optionalChain([event, 'optionalAccess', _198 => _198.__braintrust_ai_sdk_cleanup]);
11221
+ if (event && typeof cleanup === "function") {
11222
+ cleanup();
11223
+ delete event.__braintrust_ai_sdk_cleanup;
11224
+ }
11225
+ }
11226
+ function patchAISDKStreamingResult(args) {
11227
+ const { denyOutputPaths, endEvent, result, span, startTime } = args;
11228
+ if (!result || typeof result !== "object") {
11229
+ return false;
11230
+ }
11231
+ const resultRecord = result;
11232
+ if (!isReadableStreamLike(resultRecord.baseStream)) {
11233
+ return false;
11234
+ }
11235
+ let firstChunkTime;
11236
+ const wrappedBaseStream = resultRecord.baseStream.pipeThrough(
11237
+ new TransformStream({
11238
+ transform(chunk, controller) {
11239
+ if (firstChunkTime === void 0) {
11240
+ firstChunkTime = getCurrentUnixTimestamp();
11241
+ }
11242
+ controller.enqueue(chunk);
11243
+ },
11244
+ async flush() {
11245
+ const metrics = extractTopLevelAISDKMetrics(result, endEvent);
11246
+ if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
11247
+ metrics.time_to_first_token = firstChunkTime - startTime;
11248
+ }
11249
+ const output = await processAISDKStreamingOutput(
11250
+ result,
11251
+ denyOutputPaths
11252
+ );
11253
+ const metadata = buildResolvedMetadataPayload(result).metadata;
11254
+ span.log({
11255
+ output,
11256
+ ...metadata ? { metadata } : {},
11257
+ metrics
11258
+ });
11259
+ finalizeAISDKChildTracing(endEvent);
11260
+ span.end();
11261
+ }
11262
+ })
11263
+ );
11264
+ Object.defineProperty(resultRecord, "baseStream", {
11265
+ configurable: true,
11266
+ enumerable: true,
11267
+ value: wrappedBaseStream,
11268
+ writable: true
11269
+ });
11270
+ return true;
11271
+ }
11272
+ function isReadableStreamLike(value) {
11273
+ return value != null && typeof value === "object" && typeof value.pipeThrough === "function";
11274
+ }
11275
+ async function processAISDKStreamingOutput(result, denyOutputPaths) {
11276
+ const output = processAISDKOutput(result, denyOutputPaths);
11277
+ if (!output || typeof output !== "object") {
11278
+ return output;
11279
+ }
11280
+ const outputRecord = output;
11281
+ try {
11282
+ if ("text" in result && typeof result.text === "string") {
11283
+ outputRecord.text = result.text;
11284
+ }
11285
+ } catch (e21) {
11286
+ }
11287
+ try {
11288
+ if ("object" in result) {
11289
+ const resolvedObject = await Promise.resolve(result.object);
11290
+ if (resolvedObject !== void 0) {
11291
+ outputRecord.object = resolvedObject;
11292
+ }
11293
+ }
11294
+ } catch (e22) {
11295
+ }
11296
+ return outputRecord;
11297
+ }
11298
+ function buildAISDKChildMetadata(model) {
11299
+ const { model: modelId, provider } = serializeModelWithProvider(model);
11300
+ return {
11301
+ ...modelId ? { model: modelId } : {},
11302
+ ...provider ? { provider } : {},
11303
+ braintrust: {
11304
+ integration_name: "ai-sdk",
11305
+ sdk_language: "typescript"
11306
+ }
11307
+ };
11308
+ }
11309
+ function buildResolvedMetadataPayload(result) {
11310
+ const gatewayInfo = extractGatewayRoutingInfo(result);
11311
+ const metadata = {};
11312
+ if (_optionalChain([gatewayInfo, 'optionalAccess', _199 => _199.provider])) {
11313
+ metadata.provider = gatewayInfo.provider;
11314
+ }
11315
+ if (_optionalChain([gatewayInfo, 'optionalAccess', _200 => _200.model])) {
11316
+ metadata.model = gatewayInfo.model;
11317
+ }
11318
+ if (result.finishReason !== void 0) {
11319
+ metadata.finish_reason = result.finishReason;
11320
+ }
11321
+ return Object.keys(metadata).length > 0 ? { metadata } : {};
11322
+ }
11323
+ function resolveAISDKModel(model) {
11324
+ if (typeof model !== "string") {
11325
+ return model;
11326
+ }
11327
+ const provider = _nullishCoalesce(globalThis.AI_SDK_DEFAULT_PROVIDER, () => ( null));
11328
+ if (provider && typeof provider.languageModel === "function") {
11329
+ return provider.languageModel(model);
11330
+ }
11331
+ return model;
11332
+ }
11333
+ function extractTextDelta(chunk) {
11334
+ if (typeof chunk.textDelta === "string") return chunk.textDelta;
11335
+ if (typeof chunk.delta === "string") return chunk.delta;
11336
+ if (typeof chunk.text === "string") return chunk.text;
11337
+ if (typeof chunk.content === "string") return chunk.content;
11338
+ return "";
11339
+ }
11340
+ function isAsyncGenerator(value) {
11341
+ return value != null && typeof value === "object" && typeof value[Symbol.asyncIterator] === "function" && typeof value.next === "function" && typeof value.return === "function" && typeof value.throw === "function";
11342
+ }
10561
11343
  function processAISDKOutput(output, denyOutputPaths) {
10562
11344
  if (!output) return output;
10563
- const getterValues = extractGetterValues(output);
10564
- const merged = { ...output, ...getterValues };
10565
- return omit(merged, denyOutputPaths);
11345
+ const merged = extractSerializableOutputFields(output);
11346
+ return normalizeAISDKLoggedOutput(omit(merged, denyOutputPaths));
10566
11347
  }
10567
11348
  function extractTokenMetrics(result) {
10568
11349
  const metrics = {};
10569
- let usage = _optionalChain([result, 'optionalAccess', _144 => _144.totalUsage]) || _optionalChain([result, 'optionalAccess', _145 => _145.usage]);
11350
+ let usage = _optionalChain([result, 'optionalAccess', _201 => _201.totalUsage]) || _optionalChain([result, 'optionalAccess', _202 => _202.usage]);
10570
11351
  if (!usage && result) {
10571
11352
  try {
10572
11353
  if ("totalUsage" in result && typeof result.totalUsage !== "function") {
@@ -10574,14 +11355,14 @@ function extractTokenMetrics(result) {
10574
11355
  } else if ("usage" in result && typeof result.usage !== "function") {
10575
11356
  usage = result.usage;
10576
11357
  }
10577
- } catch (e19) {
11358
+ } catch (e23) {
10578
11359
  }
10579
11360
  }
10580
11361
  if (!usage) {
10581
11362
  return metrics;
10582
11363
  }
10583
11364
  const promptTokens = firstNumber(
10584
- _optionalChain([usage, 'access', _146 => _146.inputTokens, 'optionalAccess', _147 => _147.total]),
11365
+ _optionalChain([usage, 'access', _203 => _203.inputTokens, 'optionalAccess', _204 => _204.total]),
10585
11366
  usage.inputTokens,
10586
11367
  usage.promptTokens,
10587
11368
  usage.prompt_tokens
@@ -10590,7 +11371,7 @@ function extractTokenMetrics(result) {
10590
11371
  metrics.prompt_tokens = promptTokens;
10591
11372
  }
10592
11373
  const completionTokens = firstNumber(
10593
- _optionalChain([usage, 'access', _148 => _148.outputTokens, 'optionalAccess', _149 => _149.total]),
11374
+ _optionalChain([usage, 'access', _205 => _205.outputTokens, 'optionalAccess', _206 => _206.total]),
10594
11375
  usage.outputTokens,
10595
11376
  usage.completionTokens,
10596
11377
  usage.completion_tokens
@@ -10612,12 +11393,14 @@ function extractTokenMetrics(result) {
10612
11393
  }
10613
11394
  return metrics;
10614
11395
  }
10615
- function aggregateAISDKChunks(chunks) {
11396
+ function aggregateAISDKChunks(chunks, _result, endEvent) {
10616
11397
  const lastChunk = chunks[chunks.length - 1];
10617
11398
  const output = {};
10618
11399
  let metrics = {};
11400
+ let metadata;
10619
11401
  if (lastChunk) {
10620
- metrics = extractTokenMetrics(lastChunk);
11402
+ metrics = hasModelChildTracing(endEvent) ? {} : extractTokenMetrics(lastChunk);
11403
+ metadata = buildResolvedMetadataPayload(lastChunk).metadata;
10621
11404
  if (lastChunk.text !== void 0) {
10622
11405
  output.text = lastChunk.text;
10623
11406
  }
@@ -10631,7 +11414,8 @@ function aggregateAISDKChunks(chunks) {
10631
11414
  output.toolCalls = lastChunk.toolCalls;
10632
11415
  }
10633
11416
  }
10634
- return { output, metrics };
11417
+ finalizeAISDKChildTracing(endEvent);
11418
+ return { output, metrics, metadata };
10635
11419
  }
10636
11420
  function extractGetterValues(obj) {
10637
11421
  const getterValues = {};
@@ -10651,17 +11435,58 @@ function extractGetterValues(obj) {
10651
11435
  ];
10652
11436
  for (const name of getterNames) {
10653
11437
  try {
10654
- if (obj && name in obj && typeof obj[name] !== "function") {
11438
+ if (obj && name in obj && isSerializableOutputValue(obj[name])) {
10655
11439
  getterValues[name] = obj[name];
10656
11440
  }
10657
- } catch (e20) {
11441
+ } catch (e24) {
10658
11442
  }
10659
11443
  }
10660
11444
  return getterValues;
10661
11445
  }
11446
+ function extractSerializableOutputFields(output) {
11447
+ const serialized = {};
11448
+ const directFieldNames = [
11449
+ "steps",
11450
+ "request",
11451
+ "responseMessages",
11452
+ "warnings",
11453
+ "rawResponse",
11454
+ "response",
11455
+ "providerMetadata",
11456
+ "experimental_providerMetadata"
11457
+ ];
11458
+ for (const name of directFieldNames) {
11459
+ try {
11460
+ const value = _optionalChain([output, 'optionalAccess', _207 => _207[name]]);
11461
+ if (isSerializableOutputValue(value)) {
11462
+ serialized[name] = value;
11463
+ }
11464
+ } catch (e25) {
11465
+ }
11466
+ }
11467
+ return {
11468
+ ...serialized,
11469
+ ...extractGetterValues(output)
11470
+ };
11471
+ }
11472
+ function isSerializableOutputValue(value) {
11473
+ if (typeof value === "function") {
11474
+ return false;
11475
+ }
11476
+ if (value && typeof value === "object" && typeof value.then === "function") {
11477
+ return false;
11478
+ }
11479
+ if (value && typeof value === "object" && typeof value.getReader === "function") {
11480
+ return false;
11481
+ }
11482
+ if (value && typeof value === "object" && typeof value[Symbol.asyncIterator] === "function") {
11483
+ return false;
11484
+ }
11485
+ return true;
11486
+ }
10662
11487
  function serializeModelWithProvider(model) {
10663
- const modelId = typeof model === "string" ? model : _optionalChain([model, 'optionalAccess', _150 => _150.modelId]);
10664
- const explicitProvider = typeof model === "object" ? _optionalChain([model, 'optionalAccess', _151 => _151.provider]) : void 0;
11488
+ const modelId = typeof model === "string" ? model : _optionalChain([model, 'optionalAccess', _208 => _208.modelId]);
11489
+ const explicitProvider = typeof model === "object" ? _optionalChain([model, 'optionalAccess', _209 => _209.provider]) : void 0;
10665
11490
  if (!modelId) {
10666
11491
  return { model: modelId, provider: explicitProvider };
10667
11492
  }
@@ -10684,13 +11509,32 @@ function parseGatewayModelString(modelString) {
10684
11509
  }
10685
11510
  return { model: modelString };
10686
11511
  }
11512
+ function extractGatewayRoutingInfo(result) {
11513
+ if (_optionalChain([result, 'optionalAccess', _210 => _210.steps]) && Array.isArray(result.steps) && result.steps.length > 0) {
11514
+ const routing2 = _optionalChain([result, 'access', _211 => _211.steps, 'access', _212 => _212[0], 'optionalAccess', _213 => _213.providerMetadata, 'optionalAccess', _214 => _214.gateway, 'optionalAccess', _215 => _215.routing]);
11515
+ if (routing2) {
11516
+ return {
11517
+ provider: routing2.resolvedProvider || routing2.finalProvider,
11518
+ model: routing2.resolvedProviderApiModelId
11519
+ };
11520
+ }
11521
+ }
11522
+ const routing = _optionalChain([result, 'optionalAccess', _216 => _216.providerMetadata, 'optionalAccess', _217 => _217.gateway, 'optionalAccess', _218 => _218.routing]);
11523
+ if (routing) {
11524
+ return {
11525
+ provider: routing.resolvedProvider || routing.finalProvider,
11526
+ model: routing.resolvedProviderApiModelId
11527
+ };
11528
+ }
11529
+ return null;
11530
+ }
10687
11531
  function extractCostFromResult(result) {
10688
- if (_optionalChain([result, 'optionalAccess', _152 => _152.steps]) && Array.isArray(result.steps) && result.steps.length > 0) {
11532
+ if (_optionalChain([result, 'optionalAccess', _219 => _219.steps]) && Array.isArray(result.steps) && result.steps.length > 0) {
10689
11533
  let totalCost = 0;
10690
11534
  let foundCost = false;
10691
11535
  for (const step of result.steps) {
10692
- const gateway2 = _optionalChain([step, 'optionalAccess', _153 => _153.providerMetadata, 'optionalAccess', _154 => _154.gateway]);
10693
- const stepCost = parseGatewayCost(_optionalChain([gateway2, 'optionalAccess', _155 => _155.cost])) || parseGatewayCost(_optionalChain([gateway2, 'optionalAccess', _156 => _156.marketCost]));
11536
+ const gateway2 = _optionalChain([step, 'optionalAccess', _220 => _220.providerMetadata, 'optionalAccess', _221 => _221.gateway]);
11537
+ const stepCost = parseGatewayCost(_optionalChain([gateway2, 'optionalAccess', _222 => _222.cost])) || parseGatewayCost(_optionalChain([gateway2, 'optionalAccess', _223 => _223.marketCost]));
10694
11538
  if (stepCost !== void 0 && stepCost > 0) {
10695
11539
  totalCost += stepCost;
10696
11540
  foundCost = true;
@@ -10700,8 +11544,8 @@ function extractCostFromResult(result) {
10700
11544
  return totalCost;
10701
11545
  }
10702
11546
  }
10703
- const gateway = _optionalChain([result, 'optionalAccess', _157 => _157.providerMetadata, 'optionalAccess', _158 => _158.gateway]);
10704
- const directCost = parseGatewayCost(_optionalChain([gateway, 'optionalAccess', _159 => _159.cost])) || parseGatewayCost(_optionalChain([gateway, 'optionalAccess', _160 => _160.marketCost]));
11547
+ const gateway = _optionalChain([result, 'optionalAccess', _224 => _224.providerMetadata, 'optionalAccess', _225 => _225.gateway]);
11548
+ const directCost = parseGatewayCost(_optionalChain([gateway, 'optionalAccess', _226 => _226.cost])) || parseGatewayCost(_optionalChain([gateway, 'optionalAccess', _227 => _227.marketCost]));
10705
11549
  if (directCost !== void 0 && directCost > 0) {
10706
11550
  return directCost;
10707
11551
  }
@@ -10853,7 +11697,7 @@ function extractUsageFromMessage(message) {
10853
11697
  const metrics = {};
10854
11698
  let usage;
10855
11699
  if (message.type === "assistant") {
10856
- usage = _optionalChain([message, 'access', _161 => _161.message, 'optionalAccess', _162 => _162.usage]);
11700
+ usage = _optionalChain([message, 'access', _228 => _228.message, 'optionalAccess', _229 => _229.usage]);
10857
11701
  } else if (message.type === "result") {
10858
11702
  usage = message.usage;
10859
11703
  }
@@ -10893,14 +11737,14 @@ function buildLLMInput(prompt, conversationHistory) {
10893
11737
  async function createLLMSpanForMessages(messages, prompt, conversationHistory, options, startTime, parentSpan) {
10894
11738
  if (messages.length === 0) return void 0;
10895
11739
  const lastMessage = messages[messages.length - 1];
10896
- if (lastMessage.type !== "assistant" || !_optionalChain([lastMessage, 'access', _163 => _163.message, 'optionalAccess', _164 => _164.usage])) {
11740
+ if (lastMessage.type !== "assistant" || !_optionalChain([lastMessage, 'access', _230 => _230.message, 'optionalAccess', _231 => _231.usage])) {
10897
11741
  return void 0;
10898
11742
  }
10899
11743
  const model = lastMessage.message.model || options.model;
10900
11744
  const usage = extractUsageFromMessage(lastMessage);
10901
11745
  const input = buildLLMInput(prompt, conversationHistory);
10902
11746
  const outputs = messages.map(
10903
- (m) => _optionalChain([m, 'access', _165 => _165.message, 'optionalAccess', _166 => _166.content]) && _optionalChain([m, 'access', _167 => _167.message, 'optionalAccess', _168 => _168.role]) ? { content: m.message.content, role: m.message.role } : void 0
11747
+ (m) => _optionalChain([m, 'access', _232 => _232.message, 'optionalAccess', _233 => _233.content]) && _optionalChain([m, 'access', _234 => _234.message, 'optionalAccess', _235 => _235.role]) ? { content: m.message.content, role: m.message.role } : void 0
10904
11748
  ).filter(
10905
11749
  (c) => c !== void 0
10906
11750
  );
@@ -10919,7 +11763,7 @@ async function createLLMSpanForMessages(messages, prompt, conversationHistory, o
10919
11763
  metrics: usage
10920
11764
  });
10921
11765
  await span.end();
10922
- return _optionalChain([lastMessage, 'access', _169 => _169.message, 'optionalAccess', _170 => _170.content]) && _optionalChain([lastMessage, 'access', _171 => _171.message, 'optionalAccess', _172 => _172.role]) ? { content: lastMessage.message.content, role: lastMessage.message.role } : void 0;
11766
+ return _optionalChain([lastMessage, 'access', _236 => _236.message, 'optionalAccess', _237 => _237.content]) && _optionalChain([lastMessage, 'access', _238 => _238.message, 'optionalAccess', _239 => _239.role]) ? { content: lastMessage.message.content, role: lastMessage.message.role } : void 0;
10923
11767
  }
10924
11768
  var ClaudeAgentSDKPlugin = class extends BasePlugin {
10925
11769
  onEnable() {
@@ -10942,8 +11786,8 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
10942
11786
  const handlers = {
10943
11787
  start: (event) => {
10944
11788
  const params = event.arguments[0];
10945
- const prompt = _optionalChain([params, 'optionalAccess', _173 => _173.prompt]);
10946
- const options = _nullishCoalesce(_optionalChain([params, 'optionalAccess', _174 => _174.options]), () => ( {}));
11789
+ const prompt = _optionalChain([params, 'optionalAccess', _240 => _240.prompt]);
11790
+ const options = _nullishCoalesce(_optionalChain([params, 'optionalAccess', _241 => _241.options]), () => ( {}));
10947
11791
  const span = startSpan({
10948
11792
  name: "Claude Agent",
10949
11793
  spanAttributes: {
@@ -10988,9 +11832,9 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
10988
11832
  onChunk: async (message) => {
10989
11833
  const currentTime = getCurrentUnixTimestamp();
10990
11834
  const params = event.arguments[0];
10991
- const prompt = _optionalChain([params, 'optionalAccess', _175 => _175.prompt]);
10992
- const options = _nullishCoalesce(_optionalChain([params, 'optionalAccess', _176 => _176.options]), () => ( {}));
10993
- const messageId = _optionalChain([message, 'access', _177 => _177.message, 'optionalAccess', _178 => _178.id]);
11835
+ const prompt = _optionalChain([params, 'optionalAccess', _242 => _242.prompt]);
11836
+ const options = _nullishCoalesce(_optionalChain([params, 'optionalAccess', _243 => _243.options]), () => ( {}));
11837
+ const messageId = _optionalChain([message, 'access', _244 => _244.message, 'optionalAccess', _245 => _245.id]);
10994
11838
  if (messageId && messageId !== spanData.currentMessageId) {
10995
11839
  if (spanData.currentMessages.length > 0) {
10996
11840
  const finalMessage = await createLLMSpanForMessages(
@@ -11005,7 +11849,7 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
11005
11849
  spanData.conversationHistory.push(finalMessage);
11006
11850
  }
11007
11851
  const lastMessage = spanData.currentMessages[spanData.currentMessages.length - 1];
11008
- if (_optionalChain([lastMessage, 'optionalAccess', _179 => _179.message, 'optionalAccess', _180 => _180.usage])) {
11852
+ if (_optionalChain([lastMessage, 'optionalAccess', _246 => _246.message, 'optionalAccess', _247 => _247.usage])) {
11009
11853
  const outputTokens = getNumberProperty(
11010
11854
  lastMessage.message.usage,
11011
11855
  "output_tokens"
@@ -11017,14 +11861,14 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
11017
11861
  spanData.currentMessageId = messageId;
11018
11862
  spanData.currentMessageStartTime = currentTime;
11019
11863
  }
11020
- if (message.type === "assistant" && _optionalChain([message, 'access', _181 => _181.message, 'optionalAccess', _182 => _182.usage])) {
11864
+ if (message.type === "assistant" && _optionalChain([message, 'access', _248 => _248.message, 'optionalAccess', _249 => _249.usage])) {
11021
11865
  spanData.currentMessages.push(message);
11022
11866
  }
11023
11867
  if (message.type === "result" && message.usage) {
11024
11868
  const finalUsageMetrics = extractUsageFromMessage(message);
11025
11869
  if (spanData.currentMessages.length > 0 && finalUsageMetrics.completion_tokens !== void 0) {
11026
11870
  const lastMessage = spanData.currentMessages[spanData.currentMessages.length - 1];
11027
- if (_optionalChain([lastMessage, 'optionalAccess', _183 => _183.message, 'optionalAccess', _184 => _184.usage])) {
11871
+ if (_optionalChain([lastMessage, 'optionalAccess', _250 => _250.message, 'optionalAccess', _251 => _251.usage])) {
11028
11872
  const adjustedTokens = finalUsageMetrics.completion_tokens - spanData.accumulatedOutputTokens;
11029
11873
  if (adjustedTokens >= 0) {
11030
11874
  lastMessage.message.usage.output_tokens = adjustedTokens;
@@ -11048,8 +11892,8 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
11048
11892
  onComplete: async () => {
11049
11893
  try {
11050
11894
  const params = event.arguments[0];
11051
- const prompt = _optionalChain([params, 'optionalAccess', _185 => _185.prompt]);
11052
- const options = _nullishCoalesce(_optionalChain([params, 'optionalAccess', _186 => _186.options]), () => ( {}));
11895
+ const prompt = _optionalChain([params, 'optionalAccess', _252 => _252.prompt]);
11896
+ const options = _nullishCoalesce(_optionalChain([params, 'optionalAccess', _253 => _253.options]), () => ( {}));
11053
11897
  if (spanData.currentMessages.length > 0) {
11054
11898
  const finalMessage = await createLLMSpanForMessages(
11055
11899
  spanData.currentMessages,
@@ -11256,7 +12100,7 @@ function serializePart(part) {
11256
12100
  return part;
11257
12101
  }
11258
12102
  function serializeTools(params) {
11259
- if (!_optionalChain([params, 'access', _187 => _187.config, 'optionalAccess', _188 => _188.tools])) {
12103
+ if (!_optionalChain([params, 'access', _254 => _254.config, 'optionalAccess', _255 => _255.tools])) {
11260
12104
  return null;
11261
12105
  }
11262
12106
  try {
@@ -11264,154 +12108,1171 @@ function serializeTools(params) {
11264
12108
  if (typeof tool === "object" && tool.functionDeclarations) {
11265
12109
  return tool;
11266
12110
  }
11267
- return tool;
12111
+ return tool;
12112
+ });
12113
+ } catch (e26) {
12114
+ return null;
12115
+ }
12116
+ }
12117
+ function extractMetadata(params) {
12118
+ const metadata = {};
12119
+ if (params.model) {
12120
+ metadata.model = params.model;
12121
+ }
12122
+ if (params.config) {
12123
+ const config = tryToDict(params.config);
12124
+ if (config) {
12125
+ Object.keys(config).forEach((key) => {
12126
+ if (key !== "tools") {
12127
+ metadata[key] = config[key];
12128
+ }
12129
+ });
12130
+ }
12131
+ }
12132
+ return metadata;
12133
+ }
12134
+ function extractGenerateContentMetrics(response, startTime) {
12135
+ const metrics = {};
12136
+ if (startTime) {
12137
+ const end = getCurrentUnixTimestamp();
12138
+ metrics.duration = end - startTime;
12139
+ }
12140
+ if (_optionalChain([response, 'optionalAccess', _256 => _256.usageMetadata])) {
12141
+ populateUsageMetrics(metrics, response.usageMetadata);
12142
+ }
12143
+ return metrics;
12144
+ }
12145
+ function populateUsageMetrics(metrics, usage) {
12146
+ if (usage.promptTokenCount !== void 0) {
12147
+ metrics.prompt_tokens = usage.promptTokenCount;
12148
+ }
12149
+ if (usage.candidatesTokenCount !== void 0) {
12150
+ metrics.completion_tokens = usage.candidatesTokenCount;
12151
+ }
12152
+ if (usage.totalTokenCount !== void 0) {
12153
+ metrics.tokens = usage.totalTokenCount;
12154
+ }
12155
+ if (usage.cachedContentTokenCount !== void 0) {
12156
+ metrics.prompt_cached_tokens = usage.cachedContentTokenCount;
12157
+ }
12158
+ if (usage.thoughtsTokenCount !== void 0) {
12159
+ metrics.completion_reasoning_tokens = usage.thoughtsTokenCount;
12160
+ }
12161
+ }
12162
+ function aggregateGenerateContentChunks(chunks, startTime) {
12163
+ const metrics = {};
12164
+ if (startTime !== void 0) {
12165
+ const end = getCurrentUnixTimestamp();
12166
+ metrics.duration = end - startTime;
12167
+ }
12168
+ let firstTokenTime = null;
12169
+ if (chunks.length > 0 && firstTokenTime === null && startTime !== void 0) {
12170
+ firstTokenTime = getCurrentUnixTimestamp();
12171
+ metrics.time_to_first_token = firstTokenTime - startTime;
12172
+ }
12173
+ if (chunks.length === 0) {
12174
+ return { output: {}, metrics };
12175
+ }
12176
+ let text = "";
12177
+ let thoughtText = "";
12178
+ const otherParts = [];
12179
+ let usageMetadata = null;
12180
+ let lastResponse = null;
12181
+ for (const chunk of chunks) {
12182
+ lastResponse = chunk;
12183
+ if (chunk.usageMetadata) {
12184
+ usageMetadata = chunk.usageMetadata;
12185
+ }
12186
+ if (chunk.candidates && Array.isArray(chunk.candidates)) {
12187
+ for (const candidate of chunk.candidates) {
12188
+ if (_optionalChain([candidate, 'access', _257 => _257.content, 'optionalAccess', _258 => _258.parts])) {
12189
+ for (const part of candidate.content.parts) {
12190
+ if (part.text !== void 0) {
12191
+ if (part.thought) {
12192
+ thoughtText += part.text;
12193
+ } else {
12194
+ text += part.text;
12195
+ }
12196
+ } else if (part.functionCall) {
12197
+ otherParts.push({ functionCall: part.functionCall });
12198
+ } else if (part.codeExecutionResult) {
12199
+ otherParts.push({
12200
+ codeExecutionResult: part.codeExecutionResult
12201
+ });
12202
+ } else if (part.executableCode) {
12203
+ otherParts.push({ executableCode: part.executableCode });
12204
+ }
12205
+ }
12206
+ }
12207
+ }
12208
+ }
12209
+ }
12210
+ const output = {};
12211
+ const parts = [];
12212
+ if (thoughtText) {
12213
+ parts.push({ text: thoughtText, thought: true });
12214
+ }
12215
+ if (text) {
12216
+ parts.push({ text });
12217
+ }
12218
+ parts.push(...otherParts);
12219
+ if (parts.length > 0 && _optionalChain([lastResponse, 'optionalAccess', _259 => _259.candidates])) {
12220
+ const candidates = [];
12221
+ for (const candidate of lastResponse.candidates) {
12222
+ const candidateDict = {
12223
+ content: {
12224
+ parts,
12225
+ role: "model"
12226
+ }
12227
+ };
12228
+ if (candidate.finishReason !== void 0) {
12229
+ candidateDict.finishReason = candidate.finishReason;
12230
+ }
12231
+ if (candidate.safetyRatings) {
12232
+ candidateDict.safetyRatings = candidate.safetyRatings;
12233
+ }
12234
+ candidates.push(candidateDict);
12235
+ }
12236
+ output.candidates = candidates;
12237
+ }
12238
+ if (usageMetadata) {
12239
+ output.usageMetadata = usageMetadata;
12240
+ populateUsageMetrics(metrics, usageMetadata);
12241
+ }
12242
+ if (text) {
12243
+ output.text = text;
12244
+ }
12245
+ return { output, metrics };
12246
+ }
12247
+ function tryToDict(obj) {
12248
+ if (obj === null || obj === void 0) {
12249
+ return null;
12250
+ }
12251
+ if (typeof obj === "object") {
12252
+ if ("toJSON" in obj && // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
12253
+ typeof obj.toJSON === "function") {
12254
+ return obj.toJSON();
12255
+ }
12256
+ return obj;
12257
+ }
12258
+ return null;
12259
+ }
12260
+
12261
+ // src/instrumentation/plugins/openrouter-channels.ts
12262
+ var openRouterChannels = defineChannels("@openrouter/sdk", {
12263
+ chatSend: channel({
12264
+ channelName: "chat.send",
12265
+ kind: "async"
12266
+ }),
12267
+ embeddingsGenerate: channel({
12268
+ channelName: "embeddings.generate",
12269
+ kind: "async"
12270
+ }),
12271
+ betaResponsesSend: channel({
12272
+ channelName: "beta.responses.send",
12273
+ kind: "async"
12274
+ }),
12275
+ callModel: channel({
12276
+ channelName: "callModel",
12277
+ kind: "sync-stream"
12278
+ }),
12279
+ toolExecute: channel({
12280
+ channelName: "tool.execute",
12281
+ kind: "async"
12282
+ })
12283
+ });
12284
+
12285
+ // src/openrouter-utils.ts
12286
+ var TOKEN_NAME_MAP2 = {
12287
+ promptTokens: "prompt_tokens",
12288
+ inputTokens: "prompt_tokens",
12289
+ completionTokens: "completion_tokens",
12290
+ outputTokens: "completion_tokens",
12291
+ totalTokens: "tokens",
12292
+ prompt_tokens: "prompt_tokens",
12293
+ input_tokens: "prompt_tokens",
12294
+ completion_tokens: "completion_tokens",
12295
+ output_tokens: "completion_tokens",
12296
+ total_tokens: "tokens"
12297
+ };
12298
+ var TOKEN_DETAIL_PREFIX_MAP = {
12299
+ promptTokensDetails: "prompt",
12300
+ inputTokensDetails: "prompt",
12301
+ completionTokensDetails: "completion",
12302
+ outputTokensDetails: "completion",
12303
+ costDetails: "cost",
12304
+ prompt_tokens_details: "prompt",
12305
+ input_tokens_details: "prompt",
12306
+ completion_tokens_details: "completion",
12307
+ output_tokens_details: "completion",
12308
+ cost_details: "cost"
12309
+ };
12310
+ function camelToSnake(value) {
12311
+ return value.replace(/[A-Z]/g, (match) => `_${match.toLowerCase()}`);
12312
+ }
12313
+ function parseOpenRouterMetricsFromUsage(usage) {
12314
+ if (!isObject(usage)) {
12315
+ return {};
12316
+ }
12317
+ const metrics = {};
12318
+ for (const [name, value] of Object.entries(usage)) {
12319
+ if (typeof value === "number") {
12320
+ metrics[TOKEN_NAME_MAP2[name] || camelToSnake(name)] = value;
12321
+ continue;
12322
+ }
12323
+ if (!isObject(value)) {
12324
+ continue;
12325
+ }
12326
+ const prefix = TOKEN_DETAIL_PREFIX_MAP[name];
12327
+ if (!prefix) {
12328
+ continue;
12329
+ }
12330
+ for (const [nestedName, nestedValue] of Object.entries(value)) {
12331
+ if (typeof nestedValue !== "number") {
12332
+ continue;
12333
+ }
12334
+ metrics[`${prefix}_${camelToSnake(nestedName)}`] = nestedValue;
12335
+ }
12336
+ }
12337
+ return metrics;
12338
+ }
12339
+ function extractOpenRouterUsageMetadata(usage) {
12340
+ if (!isObject(usage)) {
12341
+ return void 0;
12342
+ }
12343
+ const metadata = {};
12344
+ if (typeof usage.isByok === "boolean") {
12345
+ metadata.is_byok = usage.isByok;
12346
+ } else if (typeof usage.is_byok === "boolean") {
12347
+ metadata.is_byok = usage.is_byok;
12348
+ }
12349
+ return Object.keys(metadata).length > 0 ? metadata : void 0;
12350
+ }
12351
+
12352
+ // src/openrouter-logging.ts
12353
+ var OMITTED_OPENROUTER_KEYS = /* @__PURE__ */ new Set([
12354
+ "execute",
12355
+ "render",
12356
+ "nextTurnParams",
12357
+ "requireApproval"
12358
+ ]);
12359
+ function parseOpenRouterModelString(model) {
12360
+ if (typeof model !== "string") {
12361
+ return { model };
12362
+ }
12363
+ const slashIndex = model.indexOf("/");
12364
+ if (slashIndex > 0 && slashIndex < model.length - 1) {
12365
+ return {
12366
+ provider: model.substring(0, slashIndex),
12367
+ model: model.substring(slashIndex + 1)
12368
+ };
12369
+ }
12370
+ return { model };
12371
+ }
12372
+ function isZodSchema2(value) {
12373
+ return value != null && typeof value === "object" && "_def" in value && typeof value._def === "object";
12374
+ }
12375
+ function serializeZodSchema2(schema) {
12376
+ try {
12377
+ return zodToJsonSchema(schema);
12378
+ } catch (e27) {
12379
+ return {
12380
+ type: "object",
12381
+ description: "Zod schema (conversion failed)"
12382
+ };
12383
+ }
12384
+ }
12385
+ function serializeOpenRouterTool(tool) {
12386
+ if (!isObject(tool)) {
12387
+ return tool;
12388
+ }
12389
+ const serialized = {};
12390
+ for (const [key, value] of Object.entries(tool)) {
12391
+ if (OMITTED_OPENROUTER_KEYS.has(key)) {
12392
+ continue;
12393
+ }
12394
+ if (key === "function" && isObject(value)) {
12395
+ serialized.function = sanitizeOpenRouterLoggedValue(value);
12396
+ continue;
12397
+ }
12398
+ serialized[key] = sanitizeOpenRouterLoggedValue(value);
12399
+ }
12400
+ return serialized;
12401
+ }
12402
+ function serializeOpenRouterToolsForLogging(tools) {
12403
+ if (!Array.isArray(tools)) {
12404
+ return void 0;
12405
+ }
12406
+ return tools.map((tool) => serializeOpenRouterTool(tool));
12407
+ }
12408
+ function sanitizeOpenRouterLoggedValue(value) {
12409
+ if (isZodSchema2(value)) {
12410
+ return serializeZodSchema2(value);
12411
+ }
12412
+ if (typeof value === "function") {
12413
+ return "[Function]";
12414
+ }
12415
+ if (Array.isArray(value)) {
12416
+ return value.map((entry) => sanitizeOpenRouterLoggedValue(entry));
12417
+ }
12418
+ if (!isObject(value)) {
12419
+ return value;
12420
+ }
12421
+ const sanitized = {};
12422
+ for (const [key, entry] of Object.entries(value)) {
12423
+ if (OMITTED_OPENROUTER_KEYS.has(key)) {
12424
+ continue;
12425
+ }
12426
+ if (key === "tools" && Array.isArray(entry)) {
12427
+ sanitized.tools = serializeOpenRouterToolsForLogging(entry);
12428
+ continue;
12429
+ }
12430
+ sanitized[key] = sanitizeOpenRouterLoggedValue(entry);
12431
+ }
12432
+ return sanitized;
12433
+ }
12434
+ function buildOpenRouterMetadata(metadata, httpReferer, xTitle) {
12435
+ const sanitized = sanitizeOpenRouterLoggedValue(metadata);
12436
+ const metadataRecord = isObject(sanitized) ? sanitized : {};
12437
+ const { model, provider: providerRouting, ...rest } = metadataRecord;
12438
+ const normalizedModel = parseOpenRouterModelString(model);
12439
+ return {
12440
+ ...rest,
12441
+ ...normalizedModel.model !== void 0 ? { model: normalizedModel.model } : {},
12442
+ ...providerRouting !== void 0 ? { providerRouting } : {},
12443
+ ...httpReferer !== void 0 ? { httpReferer } : {},
12444
+ ...xTitle !== void 0 ? { xTitle } : {},
12445
+ provider: normalizedModel.provider || "openrouter"
12446
+ };
12447
+ }
12448
+ function buildOpenRouterEmbeddingMetadata(metadata, httpReferer, xTitle) {
12449
+ const normalized = buildOpenRouterMetadata(metadata, httpReferer, xTitle);
12450
+ return typeof normalized.model === "string" ? {
12451
+ ...normalized,
12452
+ embedding_model: normalized.model
12453
+ } : normalized;
12454
+ }
12455
+ function extractOpenRouterCallModelInput(request) {
12456
+ return isObject(request) && "input" in request ? sanitizeOpenRouterLoggedValue(request.input) : void 0;
12457
+ }
12458
+ function extractOpenRouterCallModelMetadata(request) {
12459
+ if (!isObject(request)) {
12460
+ return { provider: "openrouter" };
12461
+ }
12462
+ const { input: _input, ...metadata } = request;
12463
+ return buildOpenRouterMetadata(metadata, void 0, void 0);
12464
+ }
12465
+ function extractOpenRouterResponseMetadata(result) {
12466
+ if (!isObject(result)) {
12467
+ return void 0;
12468
+ }
12469
+ const { output: _output, data: _data, usage, ...metadata } = result;
12470
+ const sanitized = sanitizeOpenRouterLoggedValue(metadata);
12471
+ const metadataRecord = isObject(sanitized) ? sanitized : {};
12472
+ const { model, provider, ...rest } = metadataRecord;
12473
+ const normalizedModel = parseOpenRouterModelString(model);
12474
+ const normalizedProvider = (typeof provider === "string" ? provider : void 0) || normalizedModel.provider;
12475
+ const usageMetadata = extractOpenRouterUsageMetadata(usage);
12476
+ const combined = {
12477
+ ...rest,
12478
+ ...normalizedModel.model !== void 0 ? { model: normalizedModel.model } : {},
12479
+ ...usageMetadata || {},
12480
+ ...normalizedProvider !== void 0 ? { provider: normalizedProvider } : {}
12481
+ };
12482
+ return Object.keys(combined).length > 0 ? combined : void 0;
12483
+ }
12484
+ function extractOpenRouterResponseOutput(response, fallbackOutput) {
12485
+ if (isObject(response) && "output" in response && response.output !== void 0) {
12486
+ return sanitizeOpenRouterLoggedValue(response.output);
12487
+ }
12488
+ if (fallbackOutput !== void 0) {
12489
+ return sanitizeOpenRouterLoggedValue(fallbackOutput);
12490
+ }
12491
+ return void 0;
12492
+ }
12493
+
12494
+ // src/openrouter-tool-wrapping.ts
12495
+ var OPENROUTER_WRAPPED_TOOL = Symbol("braintrust.openrouter.wrappedTool");
12496
+ var OPENROUTER_WRAPPED_CALL_MODEL_RESULT = Symbol(
12497
+ "braintrust.openrouter.wrappedCallModelResult"
12498
+ );
12499
+ var OPENROUTER_CALL_MODEL_STREAM_METHODS = [
12500
+ "getFullResponsesStream",
12501
+ "getItemsStream",
12502
+ "getNewMessagesStream",
12503
+ "getReasoningStream",
12504
+ "getTextStream",
12505
+ "getToolCallsStream",
12506
+ "getToolStream"
12507
+ ];
12508
+ var OPENROUTER_CALL_MODEL_CONTEXT_METHODS = [
12509
+ "cancel",
12510
+ "getPendingToolCalls",
12511
+ "getState",
12512
+ "getToolCalls",
12513
+ "requiresApproval"
12514
+ ];
12515
+ function patchOpenRouterCallModelRequestTools(request) {
12516
+ if (!Array.isArray(request.tools) || request.tools.length === 0) {
12517
+ return void 0;
12518
+ }
12519
+ const originalTools = request.tools;
12520
+ const wrappedTools = originalTools.map((tool) => wrapOpenRouterTool(tool));
12521
+ const didPatch = wrappedTools.some(
12522
+ (tool, index) => tool !== originalTools[index]
12523
+ );
12524
+ if (!didPatch) {
12525
+ return void 0;
12526
+ }
12527
+ request.tools = wrappedTools;
12528
+ return () => {
12529
+ request.tools = originalTools;
12530
+ };
12531
+ }
12532
+ function patchOpenRouterCallModelResult(span, result, request) {
12533
+ if (!isObject(result) || isWrappedCallModelResult(result)) {
12534
+ return false;
12535
+ }
12536
+ const resultLike = result;
12537
+ const hasInstrumentableMethod = typeof resultLike.getResponse === "function" || typeof resultLike.getText === "function" || OPENROUTER_CALL_MODEL_STREAM_METHODS.some(
12538
+ (methodName) => typeof resultLike[methodName] === "function"
12539
+ );
12540
+ if (!hasInstrumentableMethod) {
12541
+ return false;
12542
+ }
12543
+ Object.defineProperty(resultLike, OPENROUTER_WRAPPED_CALL_MODEL_RESULT, {
12544
+ value: true,
12545
+ enumerable: false,
12546
+ configurable: false
12547
+ });
12548
+ const originalGetResponse = typeof resultLike.getResponse === "function" ? resultLike.getResponse.bind(resultLike) : void 0;
12549
+ const originalGetInitialResponse = typeof resultLike.getInitialResponse === "function" ? resultLike.getInitialResponse.bind(resultLike) : void 0;
12550
+ const originalMakeFollowupRequest = typeof resultLike.makeFollowupRequest === "function" ? resultLike.makeFollowupRequest.bind(resultLike) : void 0;
12551
+ let ended = false;
12552
+ let tracedTurnCount = 0;
12553
+ const endSpanWithResult = async (response, fallbackOutput) => {
12554
+ if (ended) {
12555
+ return;
12556
+ }
12557
+ ended = true;
12558
+ const finalResponse = getFinalOpenRouterCallModelResponse(
12559
+ resultLike,
12560
+ response
12561
+ );
12562
+ if (finalResponse) {
12563
+ const rounds = getOpenRouterCallModelRounds(resultLike);
12564
+ const metadata = extractOpenRouterCallModelResultMetadata(
12565
+ finalResponse,
12566
+ rounds.length + 1
12567
+ );
12568
+ span.log({
12569
+ output: extractOpenRouterResponseOutput(finalResponse, fallbackOutput),
12570
+ ...metadata ? { metadata } : {},
12571
+ metrics: aggregateOpenRouterCallModelMetrics(rounds, finalResponse)
12572
+ });
12573
+ span.end();
12574
+ return;
12575
+ }
12576
+ if (fallbackOutput !== void 0) {
12577
+ span.log({
12578
+ output: fallbackOutput
12579
+ });
12580
+ }
12581
+ span.end();
12582
+ };
12583
+ const endSpanWithError = (error) => {
12584
+ if (ended) {
12585
+ return;
12586
+ }
12587
+ ended = true;
12588
+ span.log({
12589
+ error: normalizeError(error).message
12590
+ });
12591
+ span.end();
12592
+ };
12593
+ const finalizeFromResponse = async (fallbackOutput) => {
12594
+ if (!originalGetResponse) {
12595
+ await endSpanWithResult(void 0, fallbackOutput);
12596
+ return;
12597
+ }
12598
+ try {
12599
+ await endSpanWithResult(await originalGetResponse(), fallbackOutput);
12600
+ } catch (e28) {
12601
+ await endSpanWithResult(void 0, fallbackOutput);
12602
+ }
12603
+ };
12604
+ if (originalGetResponse) {
12605
+ resultLike.getResponse = async (...args) => {
12606
+ return await withCurrent(span, async () => {
12607
+ try {
12608
+ const response = await originalGetResponse(...args);
12609
+ await endSpanWithResult(response);
12610
+ return response;
12611
+ } catch (error) {
12612
+ endSpanWithError(error);
12613
+ throw error;
12614
+ }
12615
+ });
12616
+ };
12617
+ }
12618
+ if (typeof resultLike.getText === "function") {
12619
+ const originalGetText = resultLike.getText.bind(resultLike);
12620
+ resultLike.getText = async (...args) => {
12621
+ return await withCurrent(span, async () => {
12622
+ try {
12623
+ const text = await originalGetText(...args);
12624
+ await finalizeFromResponse(text);
12625
+ return text;
12626
+ } catch (error) {
12627
+ endSpanWithError(error);
12628
+ throw error;
12629
+ }
12630
+ });
12631
+ };
12632
+ }
12633
+ for (const methodName of OPENROUTER_CALL_MODEL_CONTEXT_METHODS) {
12634
+ if (typeof resultLike[methodName] !== "function") {
12635
+ continue;
12636
+ }
12637
+ const originalMethod = resultLike[methodName];
12638
+ resultLike[methodName] = async (...args) => {
12639
+ return await withCurrent(span, async () => {
12640
+ return await originalMethod.apply(resultLike, args);
12641
+ });
12642
+ };
12643
+ }
12644
+ for (const methodName of OPENROUTER_CALL_MODEL_STREAM_METHODS) {
12645
+ if (typeof resultLike[methodName] !== "function") {
12646
+ continue;
12647
+ }
12648
+ const originalMethod = resultLike[methodName];
12649
+ resultLike[methodName] = (...args) => {
12650
+ const stream = withCurrent(
12651
+ span,
12652
+ () => originalMethod.apply(resultLike, args)
12653
+ );
12654
+ if (!isAsyncIterable2(stream)) {
12655
+ return stream;
12656
+ }
12657
+ return wrapAsyncIterableWithSpan({
12658
+ finalize: finalizeFromResponse,
12659
+ iteratorFactory: () => stream[Symbol.asyncIterator](),
12660
+ onError: endSpanWithError,
12661
+ span
12662
+ });
12663
+ };
12664
+ }
12665
+ if (originalGetInitialResponse) {
12666
+ let initialTurnTraced = false;
12667
+ resultLike.getInitialResponse = async (...args) => {
12668
+ if (initialTurnTraced) {
12669
+ return await withCurrent(span, async () => {
12670
+ return await originalGetInitialResponse(...args);
12671
+ });
12672
+ }
12673
+ initialTurnTraced = true;
12674
+ const resolvedRequest = getOpenRouterResolvedRequest(resultLike, request);
12675
+ const childSpan = startOpenRouterCallModelTurnSpan({
12676
+ request: resolvedRequest,
12677
+ step: tracedTurnCount + 1,
12678
+ stepType: tracedTurnCount === 0 ? "initial" : "continue"
12679
+ });
12680
+ return await withCurrent(childSpan, async () => {
12681
+ try {
12682
+ const response = await originalGetInitialResponse(...args);
12683
+ tracedTurnCount++;
12684
+ finishOpenRouterCallModelTurnSpan({
12685
+ response,
12686
+ step: tracedTurnCount,
12687
+ stepType: tracedTurnCount === 1 ? "initial" : "continue",
12688
+ span: childSpan
12689
+ });
12690
+ return response;
12691
+ } catch (error) {
12692
+ childSpan.log({
12693
+ error: normalizeError(error).message
12694
+ });
12695
+ childSpan.end();
12696
+ throw error;
12697
+ }
12698
+ });
12699
+ };
12700
+ }
12701
+ if (originalMakeFollowupRequest) {
12702
+ resultLike.makeFollowupRequest = async (...args) => {
12703
+ const currentResponse = args[0];
12704
+ const toolResults = Array.isArray(args[1]) ? args[1] : [];
12705
+ const resolvedRequest = getOpenRouterResolvedRequest(resultLike, request);
12706
+ const followupRequest = buildOpenRouterFollowupRequest(
12707
+ resolvedRequest,
12708
+ currentResponse,
12709
+ toolResults
12710
+ );
12711
+ const childSpan = startOpenRouterCallModelTurnSpan({
12712
+ request: followupRequest,
12713
+ step: tracedTurnCount + 1,
12714
+ stepType: "continue"
12715
+ });
12716
+ return await withCurrent(childSpan, async () => {
12717
+ try {
12718
+ const response = await originalMakeFollowupRequest(...args);
12719
+ tracedTurnCount++;
12720
+ finishOpenRouterCallModelTurnSpan({
12721
+ response,
12722
+ step: tracedTurnCount,
12723
+ stepType: "continue",
12724
+ span: childSpan
12725
+ });
12726
+ return response;
12727
+ } catch (error) {
12728
+ childSpan.log({
12729
+ error: normalizeError(error).message
12730
+ });
12731
+ childSpan.end();
12732
+ throw error;
12733
+ }
12734
+ });
12735
+ };
12736
+ }
12737
+ return true;
12738
+ }
12739
+ function wrapOpenRouterTool(tool) {
12740
+ if (isWrappedTool(tool) || !tool.function || typeof tool.function !== "object" || typeof tool.function.execute !== "function") {
12741
+ return tool;
12742
+ }
12743
+ const toolName = tool.function.name || "tool";
12744
+ const originalExecute = tool.function.execute;
12745
+ const wrappedTool = {
12746
+ ...tool,
12747
+ function: {
12748
+ ...tool.function,
12749
+ execute(...args) {
12750
+ return traceToolExecution({
12751
+ args,
12752
+ execute: () => Reflect.apply(originalExecute, this, args),
12753
+ toolCallId: getToolCallId(args[1]),
12754
+ toolName
12755
+ });
12756
+ }
12757
+ }
12758
+ };
12759
+ Object.defineProperty(wrappedTool, OPENROUTER_WRAPPED_TOOL, {
12760
+ value: true,
12761
+ enumerable: false,
12762
+ configurable: false
12763
+ });
12764
+ return wrappedTool;
12765
+ }
12766
+ function isWrappedTool(tool) {
12767
+ return Boolean(tool[OPENROUTER_WRAPPED_TOOL]);
12768
+ }
12769
+ function isWrappedCallModelResult(value) {
12770
+ return Boolean(
12771
+ isObject(value) && value[OPENROUTER_WRAPPED_CALL_MODEL_RESULT]
12772
+ );
12773
+ }
12774
+ function traceToolExecution(args) {
12775
+ const tracingChannel2 = openRouterChannels.toolExecute.tracingChannel();
12776
+ const input = args.args.length > 0 ? args.args[0] : void 0;
12777
+ const event = {
12778
+ arguments: [input],
12779
+ span_info: {
12780
+ name: args.toolName
12781
+ },
12782
+ toolCallId: args.toolCallId,
12783
+ toolName: args.toolName
12784
+ };
12785
+ tracingChannel2.start.publish(event);
12786
+ try {
12787
+ const result = args.execute();
12788
+ return publishToolResult(tracingChannel2, event, result);
12789
+ } catch (error) {
12790
+ event.error = normalizeError(error);
12791
+ tracingChannel2.error.publish(event);
12792
+ throw error;
12793
+ }
12794
+ }
12795
+ function publishToolResult(tracingChannel2, event, result) {
12796
+ if (isPromiseLike(result)) {
12797
+ return result.then(
12798
+ (resolved) => {
12799
+ event.result = resolved;
12800
+ tracingChannel2.asyncEnd.publish(event);
12801
+ return resolved;
12802
+ },
12803
+ (error) => {
12804
+ event.error = normalizeError(error);
12805
+ tracingChannel2.error.publish(event);
12806
+ throw error;
12807
+ }
12808
+ );
12809
+ }
12810
+ event.result = result;
12811
+ tracingChannel2.asyncEnd.publish(event);
12812
+ return result;
12813
+ }
12814
+ function getToolCallId(context) {
12815
+ const toolContext = context;
12816
+ return typeof _optionalChain([toolContext, 'optionalAccess', _260 => _260.toolCall, 'optionalAccess', _261 => _261.id]) === "string" ? toolContext.toolCall.id : void 0;
12817
+ }
12818
+ function extractOpenRouterCallModelResultMetadata(response, turnCount) {
12819
+ const combined = {
12820
+ ...extractOpenRouterResponseMetadata(response) || {},
12821
+ ...turnCount !== void 0 ? { turn_count: turnCount } : {}
12822
+ };
12823
+ return Object.keys(combined).length > 0 ? combined : void 0;
12824
+ }
12825
+ function getFinalOpenRouterCallModelResponse(result, response) {
12826
+ if (isObject(response)) {
12827
+ return response;
12828
+ }
12829
+ return isObject(result.finalResponse) ? result.finalResponse : void 0;
12830
+ }
12831
+ function getOpenRouterCallModelRounds(result) {
12832
+ if (!Array.isArray(result.allToolExecutionRounds)) {
12833
+ return [];
12834
+ }
12835
+ return result.allToolExecutionRounds.filter((round) => isObject(round)).map((round) => ({
12836
+ response: isObject(round.response) ? round.response : void 0,
12837
+ round: typeof round.round === "number" ? round.round : void 0,
12838
+ toolResults: Array.isArray(round.toolResults) ? round.toolResults : []
12839
+ })).filter((round) => round.response !== void 0);
12840
+ }
12841
+ function aggregateOpenRouterCallModelMetrics(rounds, finalResponse) {
12842
+ const metrics = {};
12843
+ const responses = [
12844
+ ...rounds.map((round) => round.response).filter(isObject),
12845
+ finalResponse
12846
+ ];
12847
+ for (const response of responses) {
12848
+ const responseMetrics = parseOpenRouterMetricsFromUsage(response.usage);
12849
+ for (const [name, value] of Object.entries(responseMetrics)) {
12850
+ metrics[name] = (metrics[name] || 0) + value;
12851
+ }
12852
+ }
12853
+ return metrics;
12854
+ }
12855
+ function buildNextOpenRouterCallModelInput(currentInput, response, toolResults) {
12856
+ const normalizedInput = Array.isArray(currentInput) ? [...currentInput] : currentInput === void 0 ? [] : [currentInput];
12857
+ const responseOutput = Array.isArray(response.output) ? response.output : response.output === void 0 ? [] : [response.output];
12858
+ return [...normalizedInput, ...responseOutput, ...toolResults].map(
12859
+ (entry) => sanitizeOpenRouterLoggedValue(entry)
12860
+ );
12861
+ }
12862
+ function startOpenRouterCallModelTurnSpan(args) {
12863
+ const requestRecord = isObject(args.request) ? args.request : void 0;
12864
+ const metadata = requestRecord ? extractOpenRouterCallModelMetadata(requestRecord) : { provider: "openrouter" };
12865
+ if (isObject(metadata) && "tools" in metadata) {
12866
+ delete metadata.tools;
12867
+ }
12868
+ return startSpan({
12869
+ name: "openrouter.beta.responses.send",
12870
+ spanAttributes: {
12871
+ type: "llm" /* LLM */
12872
+ },
12873
+ event: {
12874
+ input: requestRecord ? extractOpenRouterCallModelInput(requestRecord) : void 0,
12875
+ metadata: {
12876
+ ...metadata,
12877
+ step: args.step,
12878
+ step_type: args.stepType
12879
+ }
12880
+ }
12881
+ });
12882
+ }
12883
+ function finishOpenRouterCallModelTurnSpan(args) {
12884
+ if (!isObject(args.response)) {
12885
+ args.span.end();
12886
+ return;
12887
+ }
12888
+ args.span.log({
12889
+ output: extractOpenRouterResponseOutput(args.response),
12890
+ ...extractOpenRouterResponseMetadata(args.response) ? {
12891
+ metadata: {
12892
+ ...extractOpenRouterResponseMetadata(args.response),
12893
+ ...args.step !== void 0 ? { step: args.step } : {},
12894
+ ...args.stepType ? { step_type: args.stepType } : {}
12895
+ }
12896
+ } : {},
12897
+ metrics: parseOpenRouterMetricsFromUsage(args.response.usage)
12898
+ });
12899
+ args.span.end();
12900
+ }
12901
+ function getOpenRouterResolvedRequest(result, request) {
12902
+ if (isObject(result.resolvedRequest)) {
12903
+ return result.resolvedRequest;
12904
+ }
12905
+ return request;
12906
+ }
12907
+ function buildOpenRouterFollowupRequest(request, currentResponse, toolResults) {
12908
+ if (!request) {
12909
+ return void 0;
12910
+ }
12911
+ return {
12912
+ ...request,
12913
+ input: buildNextOpenRouterCallModelInput(
12914
+ extractOpenRouterCallModelInput(request),
12915
+ isObject(currentResponse) ? currentResponse : {},
12916
+ toolResults
12917
+ ),
12918
+ stream: false
12919
+ };
12920
+ }
12921
+ function wrapAsyncIterableWithSpan(args) {
12922
+ return {
12923
+ [Symbol.asyncIterator]() {
12924
+ const iterator = args.iteratorFactory();
12925
+ return {
12926
+ next(value) {
12927
+ return withCurrent(
12928
+ args.span,
12929
+ () => value === void 0 ? iterator.next() : iterator.next(value)
12930
+ ).then(
12931
+ async (result) => {
12932
+ if (result.done) {
12933
+ await args.finalize();
12934
+ }
12935
+ return result;
12936
+ },
12937
+ (error) => {
12938
+ args.onError(error);
12939
+ throw error;
12940
+ }
12941
+ );
12942
+ },
12943
+ return(value) {
12944
+ if (typeof iterator.return !== "function") {
12945
+ return args.finalize().then(() => ({
12946
+ done: true,
12947
+ value
12948
+ }));
12949
+ }
12950
+ return withCurrent(args.span, () => iterator.return(value)).then(
12951
+ async (result) => {
12952
+ await args.finalize();
12953
+ return result;
12954
+ },
12955
+ (error) => {
12956
+ args.onError(error);
12957
+ throw error;
12958
+ }
12959
+ );
12960
+ },
12961
+ throw(error) {
12962
+ args.onError(error);
12963
+ if (typeof iterator.throw !== "function") {
12964
+ return Promise.reject(error);
12965
+ }
12966
+ return withCurrent(args.span, () => iterator.throw(error));
12967
+ },
12968
+ [Symbol.asyncIterator]() {
12969
+ return this;
12970
+ }
12971
+ };
12972
+ }
12973
+ };
12974
+ }
12975
+ function isAsyncIterable2(value) {
12976
+ return !!value && (typeof value === "object" || typeof value === "function") && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
12977
+ }
12978
+ function isPromiseLike(value) {
12979
+ return !!value && (typeof value === "object" || typeof value === "function") && "then" in value && typeof value.then === "function";
12980
+ }
12981
+ function normalizeError(error) {
12982
+ return error instanceof Error ? error : new Error(String(error));
12983
+ }
12984
+
12985
+ // src/instrumentation/plugins/openrouter-plugin.ts
12986
+ var OpenRouterPlugin = class extends BasePlugin {
12987
+ onEnable() {
12988
+ this.subscribeToOpenRouterChannels();
12989
+ }
12990
+ onDisable() {
12991
+ this.unsubscribers = unsubscribeAll(this.unsubscribers);
12992
+ }
12993
+ subscribeToOpenRouterChannels() {
12994
+ this.unsubscribers.push(
12995
+ traceStreamingChannel(openRouterChannels.chatSend, {
12996
+ name: "openrouter.chat.send",
12997
+ type: "llm" /* LLM */,
12998
+ extractInput: (args) => {
12999
+ const request = getOpenRouterRequestArg(args);
13000
+ const chatGenerationParams = isObject(_optionalChain([request, 'optionalAccess', _262 => _262.chatGenerationParams])) ? request.chatGenerationParams : {};
13001
+ const httpReferer = _optionalChain([request, 'optionalAccess', _263 => _263.httpReferer]);
13002
+ const xTitle = _optionalChain([request, 'optionalAccess', _264 => _264.xTitle]);
13003
+ const { messages, ...metadata } = chatGenerationParams;
13004
+ return {
13005
+ input: messages,
13006
+ metadata: buildOpenRouterMetadata(metadata, httpReferer, xTitle)
13007
+ };
13008
+ },
13009
+ extractOutput: (result) => {
13010
+ return isObject(result) ? result.choices : void 0;
13011
+ },
13012
+ extractMetrics: (result, startTime) => {
13013
+ const metrics = parseOpenRouterMetricsFromUsage(_optionalChain([result, 'optionalAccess', _265 => _265.usage]));
13014
+ if (startTime) {
13015
+ metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
13016
+ }
13017
+ return metrics;
13018
+ },
13019
+ aggregateChunks: aggregateOpenRouterChatChunks
13020
+ })
13021
+ );
13022
+ this.unsubscribers.push(
13023
+ traceAsyncChannel(openRouterChannels.embeddingsGenerate, {
13024
+ name: "openrouter.embeddings.generate",
13025
+ type: "llm" /* LLM */,
13026
+ extractInput: (args) => {
13027
+ const request = getOpenRouterRequestArg(args);
13028
+ const requestBody = isObject(_optionalChain([request, 'optionalAccess', _266 => _266.requestBody])) ? request.requestBody : {};
13029
+ const httpReferer = _optionalChain([request, 'optionalAccess', _267 => _267.httpReferer]);
13030
+ const xTitle = _optionalChain([request, 'optionalAccess', _268 => _268.xTitle]);
13031
+ const { input, ...metadata } = requestBody;
13032
+ return {
13033
+ input,
13034
+ metadata: buildOpenRouterEmbeddingMetadata(
13035
+ metadata,
13036
+ httpReferer,
13037
+ xTitle
13038
+ )
13039
+ };
13040
+ },
13041
+ extractOutput: (result) => {
13042
+ if (!isObject(result)) {
13043
+ return void 0;
13044
+ }
13045
+ const embedding = _optionalChain([result, 'access', _269 => _269.data, 'optionalAccess', _270 => _270[0], 'optionalAccess', _271 => _271.embedding]);
13046
+ return Array.isArray(embedding) ? { embedding_length: embedding.length } : void 0;
13047
+ },
13048
+ extractMetadata: (result) => {
13049
+ if (!isObject(result)) {
13050
+ return void 0;
13051
+ }
13052
+ return extractOpenRouterResponseMetadata(result);
13053
+ },
13054
+ extractMetrics: (result) => {
13055
+ return isObject(result) ? parseOpenRouterMetricsFromUsage(result.usage) : {};
13056
+ }
13057
+ })
13058
+ );
13059
+ this.unsubscribers.push(
13060
+ traceStreamingChannel(openRouterChannels.betaResponsesSend, {
13061
+ name: "openrouter.beta.responses.send",
13062
+ type: "llm" /* LLM */,
13063
+ extractInput: (args) => {
13064
+ const request = getOpenRouterRequestArg(args);
13065
+ const openResponsesRequest = isObject(_optionalChain([request, 'optionalAccess', _272 => _272.openResponsesRequest])) ? request.openResponsesRequest : {};
13066
+ const httpReferer = _optionalChain([request, 'optionalAccess', _273 => _273.httpReferer]);
13067
+ const xTitle = _optionalChain([request, 'optionalAccess', _274 => _274.xTitle]);
13068
+ const { input, ...metadata } = openResponsesRequest;
13069
+ return {
13070
+ input,
13071
+ metadata: buildOpenRouterMetadata(metadata, httpReferer, xTitle)
13072
+ };
13073
+ },
13074
+ extractOutput: (result) => extractOpenRouterResponseOutput(result),
13075
+ extractMetadata: (result) => extractOpenRouterResponseMetadata(result),
13076
+ extractMetrics: (result, startTime) => {
13077
+ const metrics = parseOpenRouterMetricsFromUsage(_optionalChain([result, 'optionalAccess', _275 => _275.usage]));
13078
+ if (startTime) {
13079
+ metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
13080
+ }
13081
+ return metrics;
13082
+ },
13083
+ aggregateChunks: aggregateOpenRouterResponseStreamEvents
13084
+ })
13085
+ );
13086
+ this.unsubscribers.push(
13087
+ traceSyncStreamChannel(openRouterChannels.callModel, {
13088
+ name: "openrouter.callModel",
13089
+ type: "llm" /* LLM */,
13090
+ extractInput: (args) => {
13091
+ const request = getOpenRouterCallModelRequestArg(args);
13092
+ return {
13093
+ input: request ? extractOpenRouterCallModelInput(request) : void 0,
13094
+ metadata: request ? extractOpenRouterCallModelMetadata(request) : { provider: "openrouter" }
13095
+ };
13096
+ },
13097
+ patchResult: ({ endEvent, result, span }) => {
13098
+ return patchOpenRouterCallModelResult(
13099
+ span,
13100
+ result,
13101
+ getOpenRouterCallModelRequestArg(endEvent.arguments)
13102
+ );
13103
+ }
13104
+ })
13105
+ );
13106
+ this.unsubscribers.push(
13107
+ traceStreamingChannel(openRouterChannels.toolExecute, {
13108
+ name: "openrouter.tool",
13109
+ type: "tool" /* TOOL */,
13110
+ extractInput: (args, event) => ({
13111
+ input: args[0],
13112
+ metadata: {
13113
+ provider: "openrouter",
13114
+ tool_name: event.toolName,
13115
+ ...event.toolCallId ? { tool_call_id: event.toolCallId } : {}
13116
+ }
13117
+ }),
13118
+ extractOutput: (result) => result,
13119
+ extractMetrics: () => ({}),
13120
+ aggregateChunks: (chunks) => ({
13121
+ output: chunks.length > 0 ? chunks[chunks.length - 1] : void 0,
13122
+ metrics: {}
13123
+ })
13124
+ })
13125
+ );
13126
+ const callModelChannel = openRouterChannels.callModel.tracingChannel();
13127
+ const callModelHandlers = {
13128
+ start: (event) => {
13129
+ const request = getOpenRouterCallModelRequestArg(event.arguments);
13130
+ if (!request) {
13131
+ return;
13132
+ }
13133
+ patchOpenRouterCallModelRequestTools(request);
13134
+ }
13135
+ };
13136
+ callModelChannel.subscribe(callModelHandlers);
13137
+ this.unsubscribers.push(() => {
13138
+ callModelChannel.unsubscribe(callModelHandlers);
11268
13139
  });
11269
- } catch (e21) {
11270
- return null;
11271
13140
  }
11272
- }
11273
- function extractMetadata(params) {
11274
- const metadata = {};
11275
- if (params.model) {
11276
- metadata.model = params.model;
13141
+ };
13142
+ function normalizeArgs(args) {
13143
+ if (Array.isArray(args)) {
13144
+ return args;
11277
13145
  }
11278
- if (params.config) {
11279
- const config = tryToDict(params.config);
11280
- if (config) {
11281
- Object.keys(config).forEach((key) => {
11282
- if (key !== "tools") {
11283
- metadata[key] = config[key];
11284
- }
11285
- });
11286
- }
13146
+ if (isArrayLike(args)) {
13147
+ return Array.from(args);
11287
13148
  }
11288
- return metadata;
13149
+ return [args];
11289
13150
  }
11290
- function extractGenerateContentMetrics(response, startTime) {
11291
- const metrics = {};
11292
- if (startTime) {
11293
- const end = getCurrentUnixTimestamp();
11294
- metrics.duration = end - startTime;
11295
- }
11296
- if (_optionalChain([response, 'optionalAccess', _189 => _189.usageMetadata])) {
11297
- populateUsageMetrics(metrics, response.usageMetadata);
11298
- }
11299
- return metrics;
13151
+ function isArrayLike(value) {
13152
+ return isObject(value) && "length" in value && typeof value.length === "number" && Number.isInteger(value.length) && value.length >= 0;
11300
13153
  }
11301
- function populateUsageMetrics(metrics, usage) {
11302
- if (usage.promptTokenCount !== void 0) {
11303
- metrics.prompt_tokens = usage.promptTokenCount;
11304
- }
11305
- if (usage.candidatesTokenCount !== void 0) {
11306
- metrics.completion_tokens = usage.candidatesTokenCount;
11307
- }
11308
- if (usage.totalTokenCount !== void 0) {
11309
- metrics.tokens = usage.totalTokenCount;
11310
- }
11311
- if (usage.cachedContentTokenCount !== void 0) {
11312
- metrics.prompt_cached_tokens = usage.cachedContentTokenCount;
11313
- }
11314
- if (usage.thoughtsTokenCount !== void 0) {
11315
- metrics.completion_reasoning_tokens = usage.thoughtsTokenCount;
13154
+ function getOpenRouterRequestArg(args) {
13155
+ const normalizedArgs = normalizeArgs(args);
13156
+ const keyedCandidate = normalizedArgs.find(
13157
+ (arg) => isObject(arg) && ("chatGenerationParams" in arg || "requestBody" in arg || "openResponsesRequest" in arg)
13158
+ );
13159
+ if (isObject(keyedCandidate)) {
13160
+ return keyedCandidate;
11316
13161
  }
13162
+ const firstObjectArg = normalizedArgs.find((arg) => isObject(arg));
13163
+ return isObject(firstObjectArg) ? firstObjectArg : void 0;
11317
13164
  }
11318
- function aggregateGenerateContentChunks(chunks, startTime) {
11319
- const metrics = {};
11320
- if (startTime !== void 0) {
11321
- const end = getCurrentUnixTimestamp();
11322
- metrics.duration = end - startTime;
11323
- }
11324
- let firstTokenTime = null;
11325
- if (chunks.length > 0 && firstTokenTime === null && startTime !== void 0) {
11326
- firstTokenTime = getCurrentUnixTimestamp();
11327
- metrics.time_to_first_token = firstTokenTime - startTime;
11328
- }
11329
- if (chunks.length === 0) {
11330
- return { output: {}, metrics };
11331
- }
11332
- let text = "";
11333
- let thoughtText = "";
11334
- const otherParts = [];
11335
- let usageMetadata = null;
11336
- let lastResponse = null;
13165
+ function getOpenRouterCallModelRequestArg(args) {
13166
+ const firstObjectArg = normalizeArgs(args).find((arg) => isObject(arg));
13167
+ return isObject(firstObjectArg) ? firstObjectArg : void 0;
13168
+ }
13169
+ function aggregateOpenRouterChatChunks(chunks) {
13170
+ let role;
13171
+ let content = "";
13172
+ let toolCalls;
13173
+ let finishReason;
13174
+ let metrics = {};
11337
13175
  for (const chunk of chunks) {
11338
- lastResponse = chunk;
11339
- if (chunk.usageMetadata) {
11340
- usageMetadata = chunk.usageMetadata;
13176
+ metrics = {
13177
+ ...metrics,
13178
+ ...parseOpenRouterMetricsFromUsage(_optionalChain([chunk, 'optionalAccess', _276 => _276.usage]))
13179
+ };
13180
+ const choice = _optionalChain([chunk, 'optionalAccess', _277 => _277.choices, 'optionalAccess', _278 => _278[0]]);
13181
+ const delta = _optionalChain([choice, 'optionalAccess', _279 => _279.delta]);
13182
+ if (!delta) {
13183
+ if (_optionalChain([choice, 'optionalAccess', _280 => _280.finish_reason]) !== void 0) {
13184
+ finishReason = choice.finish_reason;
13185
+ }
13186
+ continue;
11341
13187
  }
11342
- if (chunk.candidates && Array.isArray(chunk.candidates)) {
11343
- for (const candidate of chunk.candidates) {
11344
- if (_optionalChain([candidate, 'access', _190 => _190.content, 'optionalAccess', _191 => _191.parts])) {
11345
- for (const part of candidate.content.parts) {
11346
- if (part.text !== void 0) {
11347
- if (part.thought) {
11348
- thoughtText += part.text;
11349
- } else {
11350
- text += part.text;
11351
- }
11352
- } else if (part.functionCall) {
11353
- otherParts.push({ functionCall: part.functionCall });
11354
- } else if (part.codeExecutionResult) {
11355
- otherParts.push({
11356
- codeExecutionResult: part.codeExecutionResult
11357
- });
11358
- } else if (part.executableCode) {
11359
- otherParts.push({ executableCode: part.executableCode });
11360
- }
13188
+ if (!role && delta.role) {
13189
+ role = delta.role;
13190
+ }
13191
+ if (typeof delta.content === "string") {
13192
+ content += delta.content;
13193
+ }
13194
+ const choiceFinishReason = _nullishCoalesce(_nullishCoalesce(_optionalChain([choice, 'optionalAccess', _281 => _281.finishReason]), () => ( _optionalChain([choice, 'optionalAccess', _282 => _282.finish_reason]))), () => ( void 0));
13195
+ const deltaFinishReason = _nullishCoalesce(_nullishCoalesce(delta.finishReason, () => ( delta.finish_reason)), () => ( void 0));
13196
+ if (choiceFinishReason !== void 0) {
13197
+ finishReason = choiceFinishReason;
13198
+ } else if (deltaFinishReason !== void 0) {
13199
+ finishReason = deltaFinishReason;
13200
+ }
13201
+ const toolCallDeltas = Array.isArray(delta.toolCalls) ? delta.toolCalls : Array.isArray(delta.tool_calls) ? delta.tool_calls : void 0;
13202
+ if (!toolCallDeltas) {
13203
+ continue;
13204
+ }
13205
+ for (const toolDelta of toolCallDeltas) {
13206
+ if (!_optionalChain([toolDelta, 'optionalAccess', _283 => _283.function])) {
13207
+ continue;
13208
+ }
13209
+ const toolIndex = _nullishCoalesce(toolDelta.index, () => ( 0));
13210
+ const existingToolCall = _optionalChain([toolCalls, 'optionalAccess', _284 => _284[toolIndex]]);
13211
+ if (!existingToolCall || toolDelta.id && existingToolCall.id !== void 0 && existingToolCall.id !== toolDelta.id) {
13212
+ const nextToolCalls = [...toolCalls || []];
13213
+ nextToolCalls[toolIndex] = {
13214
+ index: toolIndex,
13215
+ id: toolDelta.id,
13216
+ type: toolDelta.type,
13217
+ function: {
13218
+ name: toolDelta.function.name,
13219
+ arguments: toolDelta.function.arguments || ""
11361
13220
  }
11362
- }
13221
+ };
13222
+ toolCalls = nextToolCalls;
13223
+ continue;
11363
13224
  }
11364
- }
11365
- }
11366
- const output = {};
11367
- const parts = [];
11368
- if (thoughtText) {
11369
- parts.push({ text: thoughtText, thought: true });
11370
- }
11371
- if (text) {
11372
- parts.push({ text });
11373
- }
11374
- parts.push(...otherParts);
11375
- if (parts.length > 0 && _optionalChain([lastResponse, 'optionalAccess', _192 => _192.candidates])) {
11376
- const candidates = [];
11377
- for (const candidate of lastResponse.candidates) {
11378
- const candidateDict = {
11379
- content: {
11380
- parts,
11381
- role: "model"
11382
- }
11383
- };
11384
- if (candidate.finishReason !== void 0) {
11385
- candidateDict.finishReason = candidate.finishReason;
13225
+ const current = existingToolCall;
13226
+ if (toolDelta.id && !current.id) {
13227
+ current.id = toolDelta.id;
11386
13228
  }
11387
- if (candidate.safetyRatings) {
11388
- candidateDict.safetyRatings = candidate.safetyRatings;
13229
+ if (toolDelta.type && !current.type) {
13230
+ current.type = toolDelta.type;
11389
13231
  }
11390
- candidates.push(candidateDict);
13232
+ if (toolDelta.function.name && !current.function.name) {
13233
+ current.function.name = toolDelta.function.name;
13234
+ }
13235
+ current.function.arguments += toolDelta.function.arguments || "";
11391
13236
  }
11392
- output.candidates = candidates;
11393
- }
11394
- if (usageMetadata) {
11395
- output.usageMetadata = usageMetadata;
11396
- populateUsageMetrics(metrics, usageMetadata);
11397
- }
11398
- if (text) {
11399
- output.text = text;
11400
13237
  }
11401
- return { output, metrics };
13238
+ return {
13239
+ output: [
13240
+ {
13241
+ index: 0,
13242
+ message: {
13243
+ role,
13244
+ content: content || void 0,
13245
+ ...toolCalls ? { tool_calls: toolCalls } : {}
13246
+ },
13247
+ logprobs: null,
13248
+ finish_reason: finishReason
13249
+ }
13250
+ ],
13251
+ metrics
13252
+ };
11402
13253
  }
11403
- function tryToDict(obj) {
11404
- if (obj === null || obj === void 0) {
11405
- return null;
11406
- }
11407
- if (typeof obj === "object") {
11408
- if ("toJSON" in obj && // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
11409
- typeof obj.toJSON === "function") {
11410
- return obj.toJSON();
13254
+ function aggregateOpenRouterResponseStreamEvents(chunks) {
13255
+ let finalResponse;
13256
+ for (const chunk of chunks) {
13257
+ const response = _optionalChain([chunk, 'optionalAccess', _285 => _285.response]);
13258
+ if (!response) {
13259
+ continue;
13260
+ }
13261
+ if (chunk.type === "response.completed" || chunk.type === "response.incomplete" || chunk.type === "response.failed") {
13262
+ finalResponse = response;
11411
13263
  }
11412
- return obj;
11413
13264
  }
11414
- return null;
13265
+ if (!finalResponse) {
13266
+ return {
13267
+ output: void 0,
13268
+ metrics: {}
13269
+ };
13270
+ }
13271
+ return {
13272
+ output: extractOpenRouterResponseOutput(finalResponse),
13273
+ metrics: parseOpenRouterMetricsFromUsage(finalResponse.usage),
13274
+ ...extractOpenRouterResponseMetadata(finalResponse) ? { metadata: extractOpenRouterResponseMetadata(finalResponse) } : {}
13275
+ };
11415
13276
  }
11416
13277
 
11417
13278
  // src/instrumentation/braintrust-plugin.ts
@@ -11422,8 +13283,9 @@ var BraintrustPlugin = (_class18 = class extends BasePlugin {
11422
13283
  __init66() {this.aiSDKPlugin = null}
11423
13284
  __init67() {this.claudeAgentSDKPlugin = null}
11424
13285
  __init68() {this.googleGenAIPlugin = null}
13286
+ __init69() {this.openRouterPlugin = null}
11425
13287
  constructor(config = {}) {
11426
- super();_class18.prototype.__init64.call(this);_class18.prototype.__init65.call(this);_class18.prototype.__init66.call(this);_class18.prototype.__init67.call(this);_class18.prototype.__init68.call(this);;
13288
+ super();_class18.prototype.__init64.call(this);_class18.prototype.__init65.call(this);_class18.prototype.__init66.call(this);_class18.prototype.__init67.call(this);_class18.prototype.__init68.call(this);_class18.prototype.__init69.call(this);;
11427
13289
  this.config = config;
11428
13290
  }
11429
13291
  onEnable() {
@@ -11448,6 +13310,10 @@ var BraintrustPlugin = (_class18 = class extends BasePlugin {
11448
13310
  this.googleGenAIPlugin = new GoogleGenAIPlugin();
11449
13311
  this.googleGenAIPlugin.enable();
11450
13312
  }
13313
+ if (integrations.openrouter !== false) {
13314
+ this.openRouterPlugin = new OpenRouterPlugin();
13315
+ this.openRouterPlugin.enable();
13316
+ }
11451
13317
  }
11452
13318
  onDisable() {
11453
13319
  if (this.openaiPlugin) {
@@ -11470,14 +13336,18 @@ var BraintrustPlugin = (_class18 = class extends BasePlugin {
11470
13336
  this.googleGenAIPlugin.disable();
11471
13337
  this.googleGenAIPlugin = null;
11472
13338
  }
13339
+ if (this.openRouterPlugin) {
13340
+ this.openRouterPlugin.disable();
13341
+ this.openRouterPlugin = null;
13342
+ }
11473
13343
  }
11474
13344
  }, _class18);
11475
13345
 
11476
13346
  // src/instrumentation/registry.ts
11477
- var PluginRegistry = (_class19 = class {constructor() { _class19.prototype.__init69.call(this);_class19.prototype.__init70.call(this);_class19.prototype.__init71.call(this); }
11478
- __init69() {this.braintrustPlugin = null}
11479
- __init70() {this.config = {}}
11480
- __init71() {this.enabled = false}
13347
+ var PluginRegistry = (_class19 = class {constructor() { _class19.prototype.__init70.call(this);_class19.prototype.__init71.call(this);_class19.prototype.__init72.call(this); }
13348
+ __init70() {this.braintrustPlugin = null}
13349
+ __init71() {this.config = {}}
13350
+ __init72() {this.enabled = false}
11481
13351
  /**
11482
13352
  * Configure which integrations should be enabled.
11483
13353
  * This must be called before any SDK imports to take effect.
@@ -11541,7 +13411,8 @@ var PluginRegistry = (_class19 = class {constructor() { _class19.prototype.__ini
11541
13411
  vercel: true,
11542
13412
  aisdk: true,
11543
13413
  google: true,
11544
- claudeAgentSDK: true
13414
+ claudeAgentSDK: true,
13415
+ openrouter: true
11545
13416
  };
11546
13417
  }
11547
13418
  /**
@@ -11571,6 +13442,7 @@ function configureNode() {
11571
13442
  isomorph_default.getCallerLocation = getCallerLocation;
11572
13443
  isomorph_default.newAsyncLocalStorage = () => new (0, _nodeasync_hooks.AsyncLocalStorage)();
11573
13444
  isomorph_default.newTracingChannel = (nameOrChannels) => diagnostics_channel.tracingChannel(nameOrChannels);
13445
+ patchTracingChannel(diagnostics_channel.tracingChannel);
11574
13446
  isomorph_default.processOn = (event, handler) => {
11575
13447
  process.on(event, handler);
11576
13448
  };
@@ -11604,7 +13476,7 @@ function configureNode() {
11604
13476
  var _express = require('express'); var _express2 = _interopRequireDefault(_express);
11605
13477
  var _cors = require('cors'); var _cors2 = _interopRequireDefault(_cors);
11606
13478
 
11607
- // ../node_modules/async/dist/async.mjs
13479
+ // ../node_modules/.pnpm/async@3.2.5/node_modules/async/dist/async.mjs
11608
13480
  function initialParams(fn) {
11609
13481
  return function(...args) {
11610
13482
  var callback = args.pop();
@@ -11672,10 +13544,10 @@ function invokeCallback(callback, error, value) {
11672
13544
  function isAsync(fn) {
11673
13545
  return fn[Symbol.toStringTag] === "AsyncFunction";
11674
13546
  }
11675
- function isAsyncGenerator(fn) {
13547
+ function isAsyncGenerator2(fn) {
11676
13548
  return fn[Symbol.toStringTag] === "AsyncGenerator";
11677
13549
  }
11678
- function isAsyncIterable2(obj) {
13550
+ function isAsyncIterable3(obj) {
11679
13551
  return typeof obj[Symbol.asyncIterator] === "function";
11680
13552
  }
11681
13553
  function wrapAsync(asyncFn) {
@@ -11725,10 +13597,11 @@ function _asyncMap(eachfn, arr, iteratee, callback) {
11725
13597
  callback(err, results);
11726
13598
  });
11727
13599
  }
11728
- function isArrayLike(value) {
13600
+ function isArrayLike2(value) {
11729
13601
  return value && typeof value.length === "number" && value.length >= 0 && value.length % 1 === 0;
11730
13602
  }
11731
13603
  var breakLoop = {};
13604
+ var breakLoop$1 = breakLoop;
11732
13605
  function once(fn) {
11733
13606
  function wrapper(...args) {
11734
13607
  if (fn === null) return;
@@ -11772,7 +13645,7 @@ function createObjectIterator(obj) {
11772
13645
  };
11773
13646
  }
11774
13647
  function createIterator(coll) {
11775
- if (isArrayLike(coll)) {
13648
+ if (isArrayLike2(coll)) {
11776
13649
  return createArrayIterator(coll);
11777
13650
  }
11778
13651
  var iterator = getIterator(coll);
@@ -11820,7 +13693,7 @@ function asyncEachOfLimit(generator, limit, iteratee, callback) {
11820
13693
  canceled = true;
11821
13694
  return;
11822
13695
  }
11823
- if (result === breakLoop || done && running <= 0) {
13696
+ if (result === breakLoop$1 || done && running <= 0) {
11824
13697
  done = true;
11825
13698
  return callback(null);
11826
13699
  }
@@ -11843,10 +13716,10 @@ var eachOfLimit$2 = (limit) => {
11843
13716
  if (!obj) {
11844
13717
  return callback(null);
11845
13718
  }
11846
- if (isAsyncGenerator(obj)) {
13719
+ if (isAsyncGenerator2(obj)) {
11847
13720
  return asyncEachOfLimit(obj, limit, iteratee, callback);
11848
13721
  }
11849
- if (isAsyncIterable2(obj)) {
13722
+ if (isAsyncIterable3(obj)) {
11850
13723
  return asyncEachOfLimit(obj[Symbol.asyncIterator](), limit, iteratee, callback);
11851
13724
  }
11852
13725
  var nextElem = createIterator(obj);
@@ -11863,7 +13736,7 @@ var eachOfLimit$2 = (limit) => {
11863
13736
  } else if (err === false) {
11864
13737
  done = true;
11865
13738
  canceled = true;
11866
- } else if (value === breakLoop || done && running <= 0) {
13739
+ } else if (value === breakLoop$1 || done && running <= 0) {
11867
13740
  done = true;
11868
13741
  return callback(null);
11869
13742
  } else if (!looping) {
@@ -11906,7 +13779,7 @@ function eachOfArrayLike(coll, iteratee, callback) {
11906
13779
  if (canceled === true) return;
11907
13780
  if (err) {
11908
13781
  callback(err);
11909
- } else if (++completed === length || value === breakLoop) {
13782
+ } else if (++completed === length || value === breakLoop$1) {
11910
13783
  callback(null);
11911
13784
  }
11912
13785
  }
@@ -11918,7 +13791,7 @@ function eachOfGeneric(coll, iteratee, callback) {
11918
13791
  return eachOfLimit$1(coll, Infinity, iteratee, callback);
11919
13792
  }
11920
13793
  function eachOf(coll, iteratee, callback) {
11921
- var eachOfImplementation = isArrayLike(coll) ? eachOfArrayLike : eachOfGeneric;
13794
+ var eachOfImplementation = isArrayLike2(coll) ? eachOfArrayLike : eachOfGeneric;
11922
13795
  return eachOfImplementation(coll, wrapAsync(iteratee), callback);
11923
13796
  }
11924
13797
  var eachOf$1 = awaitify(eachOf, 3);
@@ -12302,7 +14175,7 @@ function _createTester(check, getResult) {
12302
14175
  if (check(result) && !testResult) {
12303
14176
  testPassed = true;
12304
14177
  testResult = getResult(true, value);
12305
- return callback(null, breakLoop);
14178
+ return callback(null, breakLoop$1);
12306
14179
  }
12307
14180
  callback();
12308
14181
  });
@@ -12433,7 +14306,7 @@ function filterGeneric(eachfn, coll, iteratee, callback) {
12433
14306
  });
12434
14307
  }
12435
14308
  function _filter(eachfn, coll, iteratee, callback) {
12436
- var filter2 = isArrayLike(coll) ? filterArray : filterGeneric;
14309
+ var filter2 = isArrayLike2(coll) ? filterArray : filterGeneric;
12437
14310
  return filter2(eachfn, coll, wrapAsync(iteratee), callback);
12438
14311
  }
12439
14312
  function filter(coll, iteratee, callback) {
@@ -12508,7 +14381,7 @@ if (hasNextTick) {
12508
14381
  }
12509
14382
  var nextTick = wrap(_defer);
12510
14383
  var _parallel = awaitify((eachfn, tasks, callback) => {
12511
- var results = isArrayLike(tasks) ? [] : {};
14384
+ var results = isArrayLike2(tasks) ? [] : {};
12512
14385
  eachfn(tasks, (task, key, taskCb) => {
12513
14386
  wrapAsync(task)((err, ...result) => {
12514
14387
  if (result.length < 2) {
@@ -12775,10 +14648,10 @@ var SpanFetcher = class _SpanFetcher extends ObjectFetcher {
12775
14648
  }
12776
14649
  };
12777
14650
  var CachedSpanFetcher = (_class20 = class {
12778
- __init72() {this.spanCache = /* @__PURE__ */ new Map()}
12779
- __init73() {this.allFetched = false}
14651
+ __init73() {this.spanCache = /* @__PURE__ */ new Map()}
14652
+ __init74() {this.allFetched = false}
12780
14653
 
12781
- constructor(objectTypeOrFetchFn, objectId, rootSpanId, getState) {;_class20.prototype.__init72.call(this);_class20.prototype.__init73.call(this);
14654
+ constructor(objectTypeOrFetchFn, objectId, rootSpanId, getState) {;_class20.prototype.__init73.call(this);_class20.prototype.__init74.call(this);
12782
14655
  if (typeof objectTypeOrFetchFn === "function") {
12783
14656
  this.fetchFn = objectTypeOrFetchFn;
12784
14657
  } else {
@@ -12793,7 +14666,7 @@ var CachedSpanFetcher = (_class20 = class {
12793
14666
  spanType
12794
14667
  );
12795
14668
  const rows = await fetcher.fetchedData();
12796
- return rows.filter((row) => _optionalChain([row, 'access', _193 => _193.span_attributes, 'optionalAccess', _194 => _194.purpose]) !== "scorer").map((row) => ({
14669
+ return rows.filter((row) => _optionalChain([row, 'access', _286 => _286.span_attributes, 'optionalAccess', _287 => _287.purpose]) !== "scorer").map((row) => ({
12797
14670
  input: row.input,
12798
14671
  output: row.output,
12799
14672
  metadata: row.metadata,
@@ -12827,7 +14700,7 @@ var CachedSpanFetcher = (_class20 = class {
12827
14700
  async fetchSpans(spanType) {
12828
14701
  const spans = await this.fetchFn(spanType);
12829
14702
  for (const span of spans) {
12830
- const type = _nullishCoalesce(_optionalChain([span, 'access', _195 => _195.span_attributes, 'optionalAccess', _196 => _196.type]), () => ( ""));
14703
+ const type = _nullishCoalesce(_optionalChain([span, 'access', _288 => _288.span_attributes, 'optionalAccess', _289 => _289.type]), () => ( ""));
12831
14704
  const existing = _nullishCoalesce(this.spanCache.get(type), () => ( []));
12832
14705
  existing.push(span);
12833
14706
  this.spanCache.set(type, existing);
@@ -12851,17 +14724,17 @@ var LocalTrace = (_class21 = class {
12851
14724
 
12852
14725
 
12853
14726
 
12854
- __init74() {this.spansFlushed = false}
12855
- __init75() {this.spansFlushPromise = null}
14727
+ __init75() {this.spansFlushed = false}
14728
+ __init76() {this.spansFlushPromise = null}
12856
14729
 
12857
- __init76() {this.threadCache = /* @__PURE__ */ new Map()}
14730
+ __init77() {this.threadCache = /* @__PURE__ */ new Map()}
12858
14731
  constructor({
12859
14732
  objectType,
12860
14733
  objectId,
12861
14734
  rootSpanId,
12862
14735
  ensureSpansFlushed,
12863
14736
  state
12864
- }) {;_class21.prototype.__init74.call(this);_class21.prototype.__init75.call(this);_class21.prototype.__init76.call(this);
14737
+ }) {;_class21.prototype.__init75.call(this);_class21.prototype.__init76.call(this);_class21.prototype.__init77.call(this);
12865
14738
  this.objectType = objectType;
12866
14739
  this.objectId = objectId;
12867
14740
  this.rootSpanId = rootSpanId;
@@ -12907,11 +14780,11 @@ var LocalTrace = (_class21 = class {
12907
14780
  const cachedSpans = this.state.spanCache.getByRootSpanId(this.rootSpanId);
12908
14781
  if (cachedSpans && cachedSpans.length > 0) {
12909
14782
  let spans = cachedSpans.filter(
12910
- (span) => _optionalChain([span, 'access', _197 => _197.span_attributes, 'optionalAccess', _198 => _198.purpose]) !== "scorer"
14783
+ (span) => _optionalChain([span, 'access', _290 => _290.span_attributes, 'optionalAccess', _291 => _291.purpose]) !== "scorer"
12911
14784
  );
12912
14785
  if (spanType && spanType.length > 0) {
12913
14786
  spans = spans.filter(
12914
- (span) => spanType.includes(_nullishCoalesce(_optionalChain([span, 'access', _199 => _199.span_attributes, 'optionalAccess', _200 => _200.type]), () => ( "")))
14787
+ (span) => spanType.includes(_nullishCoalesce(_optionalChain([span, 'access', _292 => _292.span_attributes, 'optionalAccess', _293 => _293.type]), () => ( "")))
12915
14788
  );
12916
14789
  }
12917
14790
  return spans.map((span) => ({
@@ -12930,7 +14803,7 @@ var LocalTrace = (_class21 = class {
12930
14803
  * Calls the API with the project_default preprocessor (which falls back to "thread").
12931
14804
  */
12932
14805
  async getThread(options) {
12933
- const cacheKey = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _201 => _201.preprocessor]), () => ( "project_default"));
14806
+ const cacheKey = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _294 => _294.preprocessor]), () => ( "project_default"));
12934
14807
  if (!this.threadCache.has(cacheKey)) {
12935
14808
  const promise = this.fetchThread(options);
12936
14809
  this.threadCache.set(cacheKey, promise);
@@ -12941,7 +14814,7 @@ var LocalTrace = (_class21 = class {
12941
14814
  await this.ensureSpansReady();
12942
14815
  await this.state.login({});
12943
14816
  const result = await invoke({
12944
- globalFunction: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _202 => _202.preprocessor]), () => ( "project_default")),
14817
+ globalFunction: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _295 => _295.preprocessor]), () => ( "project_default")),
12945
14818
  functionType: "preprocessor",
12946
14819
  input: {
12947
14820
  trace_ref: {
@@ -13005,7 +14878,8 @@ var promptDefinitionSchema = promptContentsSchema.and(
13005
14878
  _v3.z.object({
13006
14879
  model: _v3.z.string(),
13007
14880
  params: ModelParams.optional(),
13008
- templateFormat: _v3.z.enum(["mustache", "nunjucks", "none"]).optional()
14881
+ templateFormat: _v3.z.enum(["mustache", "nunjucks", "none"]).optional(),
14882
+ environments: _v3.z.array(_v3.z.string()).optional()
13009
14883
  })
13010
14884
  );
13011
14885
  var promptDefinitionWithToolsSchema = promptDefinitionSchema.and(
@@ -13116,10 +14990,10 @@ function validateParametersWithJsonSchema(parameters, schema) {
13116
14990
  const ajv = new (0, _ajv2.default)({ coerceTypes: true, useDefaults: true, strict: false });
13117
14991
  const validate = ajv.compile(schema);
13118
14992
  if (!validate(parameters)) {
13119
- const errorMessages = _optionalChain([validate, 'access', _203 => _203.errors, 'optionalAccess', _204 => _204.map, 'call', _205 => _205((err) => {
14993
+ const errorMessages = _optionalChain([validate, 'access', _296 => _296.errors, 'optionalAccess', _297 => _297.map, 'call', _298 => _298((err) => {
13120
14994
  const path2 = err.instancePath || "root";
13121
14995
  return `${path2}: ${err.message}`;
13122
- }), 'access', _206 => _206.join, 'call', _207 => _207(", ")]);
14996
+ }), 'access', _299 => _299.join, 'call', _300 => _300(", ")]);
13123
14997
  throw Error(`Invalid parameters: ${errorMessages}`);
13124
14998
  }
13125
14999
  return parameters;
@@ -13161,6 +15035,22 @@ function initExperiment(state, options = {}) {
13161
15035
  setCurrent: false
13162
15036
  });
13163
15037
  }
15038
+ async function getExperimentParametersRef(parameters) {
15039
+ if (!parameters) {
15040
+ return void 0;
15041
+ }
15042
+ const resolvedParameters = parameters instanceof Promise ? await parameters : parameters;
15043
+ if (!RemoteEvalParameters.isParameters(resolvedParameters)) {
15044
+ return void 0;
15045
+ }
15046
+ if (resolvedParameters.id === void 0) {
15047
+ return void 0;
15048
+ }
15049
+ return {
15050
+ id: resolvedParameters.id,
15051
+ version: resolvedParameters.version
15052
+ };
15053
+ }
13164
15054
  function callEvaluatorData(data) {
13165
15055
  const dataResult = typeof data === "function" ? data() : data;
13166
15056
  let baseExperiment = void 0;
@@ -13172,7 +15062,7 @@ function callEvaluatorData(data) {
13172
15062
  baseExperiment
13173
15063
  };
13174
15064
  }
13175
- function isAsyncIterable3(value) {
15065
+ function isAsyncIterable4(value) {
13176
15066
  return typeof value === "object" && value !== null && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
13177
15067
  }
13178
15068
  function isIterable(value) {
@@ -13227,6 +15117,7 @@ async function Eval(name, evaluator, reporterOrOpts) {
13227
15117
  const { data, baseExperiment: defaultBaseExperiment } = callEvaluatorData(
13228
15118
  evaluator.data
13229
15119
  );
15120
+ const parameters = await getExperimentParametersRef(evaluator.parameters);
13230
15121
  const experiment = options.parent || options.noSendLogs ? null : initExperiment(evaluator.state, {
13231
15122
  ...evaluator.projectId ? { projectId: evaluator.projectId } : { project: name },
13232
15123
  experiment: evaluator.experimentName,
@@ -13239,7 +15130,8 @@ async function Eval(name, evaluator, reporterOrOpts) {
13239
15130
  baseExperimentId: evaluator.baseExperimentId,
13240
15131
  gitMetadataSettings: evaluator.gitMetadataSettings,
13241
15132
  repoInfo: evaluator.repoInfo,
13242
- dataset: Dataset2.isDataset(data) ? data : void 0
15133
+ dataset: Dataset2.isDataset(data) ? data : void 0,
15134
+ parameters
13243
15135
  });
13244
15136
  if (experiment && typeof process !== "undefined" && globalThis.BRAINTRUST_CONTEXT_MANAGER !== void 0) {
13245
15137
  await experiment._waitForId();
@@ -13294,7 +15186,7 @@ async function Eval(name, evaluator, reporterOrOpts) {
13294
15186
  if (experiment) {
13295
15187
  await experiment.flush().catch(console.error);
13296
15188
  } else if (options.parent) {
13297
- await flush().catch(console.error);
15189
+ await flush({ state: evaluator.state }).catch(console.error);
13298
15190
  }
13299
15191
  }
13300
15192
  } finally {
@@ -13339,7 +15231,7 @@ async function runEvaluator(experiment, evaluator, progressReporter, filters, st
13339
15231
  }
13340
15232
  async function runEvaluatorInternal(experiment, evaluator, progressReporter, filters, stream, parameters, collectResults, enableCache) {
13341
15233
  if (enableCache) {
13342
- _optionalChain([(_nullishCoalesce(evaluator.state, () => ( _internalGetGlobalState()))), 'optionalAccess', _208 => _208.spanCache, 'optionalAccess', _209 => _209.start, 'call', _210 => _210()]);
15234
+ _optionalChain([(_nullishCoalesce(evaluator.state, () => ( _internalGetGlobalState()))), 'optionalAccess', _301 => _301.spanCache, 'optionalAccess', _302 => _302.start, 'call', _303 => _303()]);
13343
15235
  }
13344
15236
  try {
13345
15237
  if (typeof evaluator.data === "string") {
@@ -13375,7 +15267,7 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
13375
15267
  }
13376
15268
  const resolvedDataResult = dataResult instanceof Promise ? await dataResult : dataResult;
13377
15269
  const dataIterable = (() => {
13378
- if (isAsyncIterable3(resolvedDataResult)) {
15270
+ if (isAsyncIterable4(resolvedDataResult)) {
13379
15271
  return resolvedDataResult;
13380
15272
  }
13381
15273
  if (Array.isArray(resolvedDataResult) || isIterable(resolvedDataResult)) {
@@ -13394,7 +15286,7 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
13394
15286
  const experimentIdPromise = experiment ? (async () => {
13395
15287
  try {
13396
15288
  return await experiment.id;
13397
- } catch (e22) {
15289
+ } catch (e29) {
13398
15290
  return void 0;
13399
15291
  }
13400
15292
  })() : void 0;
@@ -13450,7 +15342,7 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
13450
15342
  objectType: parentComponents ? spanObjectTypeV3ToTypedString(
13451
15343
  parentComponents.data.object_type
13452
15344
  ) : "experiment",
13453
- objectId: await _asyncNullishCoalesce(await _asyncOptionalChain([parentComponents, 'optionalAccess', async _211 => _211.data, 'access', async _212 => _212.object_id]), async () => ( (experimentIdPromise ? await _asyncNullishCoalesce(await experimentIdPromise, async () => ( "")) : ""))),
15345
+ objectId: await _asyncNullishCoalesce(await _asyncOptionalChain([parentComponents, 'optionalAccess', async _304 => _304.data, 'access', async _305 => _305.object_id]), async () => ( (experimentIdPromise ? await _asyncNullishCoalesce(await experimentIdPromise, async () => ( "")) : ""))),
13454
15346
  rootSpanId: rootSpan.rootSpanId,
13455
15347
  ensureSpansFlushed,
13456
15348
  state
@@ -13476,10 +15368,10 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
13476
15368
  span,
13477
15369
  parameters: _nullishCoalesce(parameters, () => ( {})),
13478
15370
  reportProgress: (event) => {
13479
- _optionalChain([stream, 'optionalCall', _213 => _213({
15371
+ _optionalChain([stream, 'optionalCall', _306 => _306({
13480
15372
  ...event,
13481
15373
  id: rootSpan.id,
13482
- origin: _optionalChain([baseEvent, 'access', _214 => _214.event, 'optionalAccess', _215 => _215.origin]),
15374
+ origin: _optionalChain([baseEvent, 'access', _307 => _307.event, 'optionalAccess', _308 => _308.origin]),
13483
15375
  name: evaluator.evalName,
13484
15376
  object_type: "task"
13485
15377
  })]);
@@ -13643,7 +15535,7 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
13643
15535
  metadata,
13644
15536
  scores: mergedScores,
13645
15537
  error,
13646
- origin: _optionalChain([baseEvent, 'access', _216 => _216.event, 'optionalAccess', _217 => _217.origin])
15538
+ origin: _optionalChain([baseEvent, 'access', _309 => _309.event, 'optionalAccess', _310 => _310.origin])
13647
15539
  });
13648
15540
  }
13649
15541
  };
@@ -13663,6 +15555,7 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
13663
15555
  },
13664
15556
  Math.max(_nullishCoalesce(evaluator.maxConcurrency, () => ( Number.MAX_SAFE_INTEGER)), 1)
13665
15557
  );
15558
+ const queueErrors = [];
13666
15559
  const enqueuePromise = (async () => {
13667
15560
  for await (const datum of dataIterable) {
13668
15561
  if (cancelled) {
@@ -13677,8 +15570,12 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
13677
15570
  break;
13678
15571
  }
13679
15572
  scheduledTrials++;
13680
- _optionalChain([progressReporter, 'access', _218 => _218.setTotal, 'optionalCall', _219 => _219(evaluator.evalName, scheduledTrials)]);
13681
- q.push({ datum, trialIndex });
15573
+ _optionalChain([progressReporter, 'access', _311 => _311.setTotal, 'optionalCall', _312 => _312(evaluator.evalName, scheduledTrials)]);
15574
+ q.pushAsync({ datum, trialIndex }).catch((e) => {
15575
+ if (queueErrors.length < 5) {
15576
+ queueErrors.push(e);
15577
+ }
15578
+ });
13682
15579
  }
13683
15580
  }
13684
15581
  })();
@@ -13726,6 +15623,12 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
13726
15623
  })();
13727
15624
  try {
13728
15625
  await Promise.race([waitForQueue, cancel()]);
15626
+ if (queueErrors.length > 0) {
15627
+ throw new AggregateError(
15628
+ queueErrors,
15629
+ `Encountered ${queueErrors.length} unhandled task errors`
15630
+ );
15631
+ }
13729
15632
  } catch (e) {
13730
15633
  q.kill();
13731
15634
  if (e instanceof InternalAbortError) {
@@ -13752,9 +15655,9 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
13752
15655
  );
13753
15656
  } finally {
13754
15657
  if (enableCache) {
13755
- const spanCache = _optionalChain([(_nullishCoalesce(evaluator.state, () => ( _internalGetGlobalState()))), 'optionalAccess', _220 => _220.spanCache]);
13756
- _optionalChain([spanCache, 'optionalAccess', _221 => _221.dispose, 'call', _222 => _222()]);
13757
- _optionalChain([spanCache, 'optionalAccess', _223 => _223.stop, 'call', _224 => _224()]);
15658
+ const spanCache = _optionalChain([(_nullishCoalesce(evaluator.state, () => ( _internalGetGlobalState()))), 'optionalAccess', _313 => _313.spanCache]);
15659
+ _optionalChain([spanCache, 'optionalAccess', _314 => _314.dispose, 'call', _315 => _315()]);
15660
+ _optionalChain([spanCache, 'optionalAccess', _316 => _316.stop, 'call', _317 => _317()]);
13758
15661
  }
13759
15662
  }
13760
15663
  }
@@ -13991,7 +15894,7 @@ async function cachedLogin(options) {
13991
15894
  }
13992
15895
  function makeCheckAuthorized(allowedOrgName) {
13993
15896
  return async (req, _res, next) => {
13994
- if (!_optionalChain([req, 'access', _225 => _225.ctx, 'optionalAccess', _226 => _226.token])) {
15897
+ if (!_optionalChain([req, 'access', _318 => _318.ctx, 'optionalAccess', _319 => _319.token])) {
13995
15898
  return next(_httperrors2.default.call(void 0, 401, "Unauthorized"));
13996
15899
  }
13997
15900
  try {
@@ -14004,7 +15907,7 @@ function makeCheckAuthorized(allowedOrgName) {
14004
15907
  return next(_httperrors2.default.call(void 0, 403, errorMessage));
14005
15908
  }
14006
15909
  const state = await cachedLogin({
14007
- apiKey: _optionalChain([req, 'access', _227 => _227.ctx, 'optionalAccess', _228 => _228.token]),
15910
+ apiKey: _optionalChain([req, 'access', _320 => _320.ctx, 'optionalAccess', _321 => _321.token]),
14008
15911
  orgName
14009
15912
  });
14010
15913
  req.ctx.state = state;
@@ -14187,23 +16090,6 @@ var evaluatorDefinitionsSchema = _v3.z.record(
14187
16090
 
14188
16091
  // src/framework2.ts
14189
16092
 
14190
-
14191
- // src/zod/utils.ts
14192
- var _zodtojsonschema = require('zod-to-json-schema');
14193
- var _v4 = require('zod/v4'); var z42 = _interopRequireWildcard(_v4);
14194
- function isZodV4(zodObject) {
14195
- return typeof zodObject === "object" && zodObject !== null && "_zod" in zodObject && zodObject._zod !== void 0;
14196
- }
14197
- function zodToJsonSchema(schema) {
14198
- if (isZodV4(schema)) {
14199
- return z42.toJSONSchema(schema, {
14200
- target: "draft-7"
14201
- });
14202
- }
14203
- return _zodtojsonschema.zodToJsonSchema.call(void 0, schema);
14204
- }
14205
-
14206
- // src/framework2.ts
14207
16093
  var currentFilename = typeof __filename !== "undefined" ? __filename : "unknown";
14208
16094
  var ProjectBuilder = class {
14209
16095
  create(opts) {
@@ -14218,10 +16104,10 @@ var Project2 = (_class22 = class {
14218
16104
 
14219
16105
 
14220
16106
 
14221
- __init77() {this._publishableCodeFunctions = []}
14222
- __init78() {this._publishablePrompts = []}
14223
- __init79() {this._publishableParameters = []}
14224
- constructor(args) {;_class22.prototype.__init77.call(this);_class22.prototype.__init78.call(this);_class22.prototype.__init79.call(this);
16107
+ __init78() {this._publishableCodeFunctions = []}
16108
+ __init79() {this._publishablePrompts = []}
16109
+ __init80() {this._publishableParameters = []}
16110
+ constructor(args) {;_class22.prototype.__init78.call(this);_class22.prototype.__init79.call(this);_class22.prototype.__init80.call(this);
14225
16111
  _initializeSpanContext();
14226
16112
  this.name = "name" in args ? args.name : void 0;
14227
16113
  this.id = "id" in args ? args.id : void 0;
@@ -14275,10 +16161,10 @@ var Project2 = (_class22 = class {
14275
16161
  }
14276
16162
  }, _class22);
14277
16163
  var ToolBuilder = (_class23 = class {
14278
- constructor(project) {;_class23.prototype.__init80.call(this);
16164
+ constructor(project) {;_class23.prototype.__init81.call(this);
14279
16165
  this.project = project;
14280
16166
  }
14281
- __init80() {this.taskCounter = 0}
16167
+ __init81() {this.taskCounter = 0}
14282
16168
  // This type definition is just a catch all so that the implementation can be
14283
16169
  // less specific than the two more specific declarations above.
14284
16170
  create(opts) {
@@ -14305,10 +16191,10 @@ var ToolBuilder = (_class23 = class {
14305
16191
  }
14306
16192
  }, _class23);
14307
16193
  var ScorerBuilder = (_class24 = class {
14308
- constructor(project) {;_class24.prototype.__init81.call(this);
16194
+ constructor(project) {;_class24.prototype.__init82.call(this);
14309
16195
  this.project = project;
14310
16196
  }
14311
- __init81() {this.taskCounter = 0}
16197
+ __init82() {this.taskCounter = 0}
14312
16198
  create(opts) {
14313
16199
  this.taskCounter++;
14314
16200
  let resolvedName = opts.name;
@@ -14409,6 +16295,7 @@ var CodePrompt = class {
14409
16295
 
14410
16296
 
14411
16297
 
16298
+
14412
16299
  constructor(project, prompt, toolFunctions, opts, functionType) {
14413
16300
  this.project = project;
14414
16301
  this.name = opts.name;
@@ -14421,6 +16308,7 @@ var CodePrompt = class {
14421
16308
  this.functionType = functionType;
14422
16309
  this.tags = opts.tags;
14423
16310
  this.metadata = opts.metadata;
16311
+ this.environmentSlugs = opts.environments;
14424
16312
  }
14425
16313
  async toFunctionDefinition(projectNameToId) {
14426
16314
  const prompt_data = {
@@ -14455,7 +16343,8 @@ var CodePrompt = class {
14455
16343
  prompt_data,
14456
16344
  if_exists: this.ifExists,
14457
16345
  tags: this.tags,
14458
- metadata: this.metadata
16346
+ metadata: this.metadata,
16347
+ environments: this.environmentSlugs && this.environmentSlugs.length > 0 ? this.environmentSlugs.map((slug) => ({ slug })) : void 0
14459
16348
  };
14460
16349
  }
14461
16350
  };
@@ -14660,9 +16549,9 @@ function serializeRemoteEvalParametersContainer(parameters) {
14660
16549
  source: null
14661
16550
  };
14662
16551
  }
14663
- var ProjectNameIdMap = (_class25 = class {constructor() { _class25.prototype.__init82.call(this);_class25.prototype.__init83.call(this); }
14664
- __init82() {this.nameToId = {}}
14665
- __init83() {this.idToName = {}}
16552
+ var ProjectNameIdMap = (_class25 = class {constructor() { _class25.prototype.__init83.call(this);_class25.prototype.__init84.call(this); }
16553
+ __init83() {this.nameToId = {}}
16554
+ __init84() {this.idToName = {}}
14666
16555
  async getId(projectName) {
14667
16556
  if (!(projectName in this.nameToId)) {
14668
16557
  const response = await _internalGetGlobalState().appConn().post_json("api/project/register", {
@@ -14767,7 +16656,7 @@ function runDevServer(evaluators, opts) {
14767
16656
  scores,
14768
16657
  stream
14769
16658
  } = evalBodySchema.parse(req.body);
14770
- if (!_optionalChain([req, 'access', _229 => _229.ctx, 'optionalAccess', _230 => _230.state])) {
16659
+ if (!_optionalChain([req, 'access', _322 => _322.ctx, 'optionalAccess', _323 => _323.state])) {
14771
16660
  res.status(500).json({ error: "Braintrust state not initialized in request" });
14772
16661
  return;
14773
16662
  }
@@ -14818,12 +16707,12 @@ function runDevServer(evaluators, opts) {
14818
16707
  ...evaluator,
14819
16708
  data: evalData.data,
14820
16709
  scores: evaluator.scores.concat(
14821
- _nullishCoalesce(_optionalChain([scores, 'optionalAccess', _231 => _231.map, 'call', _232 => _232(
16710
+ _nullishCoalesce(_optionalChain([scores, 'optionalAccess', _324 => _324.map, 'call', _325 => _325(
14822
16711
  (score) => makeScorer(
14823
16712
  state,
14824
16713
  score.name,
14825
16714
  score.function_id,
14826
- _optionalChain([req, 'access', _233 => _233.ctx, 'optionalAccess', _234 => _234.projectId])
16715
+ _optionalChain([req, 'access', _326 => _326.ctx, 'optionalAccess', _327 => _327.projectId])
14827
16716
  )
14828
16717
  )]), () => ( []))
14829
16718
  ),