braintrust 3.5.0 → 3.7.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 (43) hide show
  1. package/dev/dist/index.d.mts +4 -2
  2. package/dev/dist/index.d.ts +4 -2
  3. package/dev/dist/index.js +2453 -612
  4. package/dev/dist/index.mjs +2150 -309
  5. package/dist/auto-instrumentations/bundler/esbuild.cjs +115 -6
  6. package/dist/auto-instrumentations/bundler/esbuild.mjs +2 -2
  7. package/dist/auto-instrumentations/bundler/rollup.cjs +115 -6
  8. package/dist/auto-instrumentations/bundler/rollup.mjs +2 -2
  9. package/dist/auto-instrumentations/bundler/vite.cjs +115 -6
  10. package/dist/auto-instrumentations/bundler/vite.mjs +2 -2
  11. package/dist/auto-instrumentations/bundler/webpack-loader.cjs +955 -0
  12. package/dist/auto-instrumentations/bundler/webpack-loader.d.ts +53 -0
  13. package/dist/auto-instrumentations/bundler/webpack.cjs +115 -6
  14. package/dist/auto-instrumentations/bundler/webpack.mjs +2 -2
  15. package/dist/auto-instrumentations/{chunk-DQTPSXJB.mjs → chunk-AKEXR4AL.mjs} +116 -7
  16. package/dist/auto-instrumentations/{chunk-F3TJZ3Z2.mjs → chunk-ZK2IYER2.mjs} +3 -1
  17. package/dist/auto-instrumentations/hook.mjs +199 -55
  18. package/dist/auto-instrumentations/index.cjs +116 -6
  19. package/dist/auto-instrumentations/index.d.mts +3 -1
  20. package/dist/auto-instrumentations/index.d.ts +3 -1
  21. package/dist/auto-instrumentations/index.mjs +3 -1
  22. package/dist/browser.d.mts +17 -4
  23. package/dist/browser.d.ts +17 -4
  24. package/dist/browser.js +2386 -440
  25. package/dist/browser.mjs +2386 -440
  26. package/dist/cli.js +2118 -273
  27. package/dist/edge-light.d.mts +1 -1
  28. package/dist/edge-light.d.ts +1 -1
  29. package/dist/edge-light.js +2348 -485
  30. package/dist/edge-light.mjs +2348 -485
  31. package/dist/index.d.mts +30 -17
  32. package/dist/index.d.ts +30 -17
  33. package/dist/index.js +2709 -761
  34. package/dist/index.mjs +2392 -444
  35. package/dist/instrumentation/index.d.mts +3 -0
  36. package/dist/instrumentation/index.d.ts +3 -0
  37. package/dist/instrumentation/index.js +2030 -274
  38. package/dist/instrumentation/index.mjs +2030 -274
  39. package/dist/workerd.d.mts +1 -1
  40. package/dist/workerd.d.ts +1 -1
  41. package/dist/workerd.js +2348 -485
  42. package/dist/workerd.mjs +2348 -485
  43. package/package.json +5 -1
package/dev/dist/index.js CHANGED
@@ -2,6 +2,90 @@
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 publishRejected(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
+ }
33
+ function publishResolved(result) {
34
+ context.result = result;
35
+ _optionalChain([asyncStart, 'optionalAccess', _20 => _20.publish, 'call', _21 => _21(context)]);
36
+ _optionalChain([asyncEnd, 'optionalAccess', _22 => _22.publish, 'call', _23 => _23(context)]);
37
+ }
38
+ return start.runStores(context, () => {
39
+ try {
40
+ const result = Reflect.apply(fn, thisArg, args);
41
+ _optionalChain([end, 'optionalAccess', _24 => _24.publish, 'call', _25 => _25(context)]);
42
+ if (result && (typeof result === "object" || typeof result === "function") && typeof result.then === "function") {
43
+ if (result.constructor === Promise) {
44
+ return result.then(
45
+ (res) => {
46
+ publishResolved(res);
47
+ return res;
48
+ },
49
+ (err) => {
50
+ publishRejected(err);
51
+ return Promise.reject(err);
52
+ }
53
+ );
54
+ }
55
+ void result.then(
56
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
57
+ (resolved) => {
58
+ try {
59
+ publishResolved(resolved);
60
+ } catch (e2) {
61
+ }
62
+ },
63
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
64
+ (err) => {
65
+ try {
66
+ publishRejected(err);
67
+ } catch (e3) {
68
+ }
69
+ }
70
+ );
71
+ return result;
72
+ }
73
+ context.result = result;
74
+ _optionalChain([asyncStart, 'optionalAccess', _26 => _26.publish, 'call', _27 => _27(context)]);
75
+ _optionalChain([asyncEnd, 'optionalAccess', _28 => _28.publish, 'call', _29 => _29(context)]);
76
+ return result;
77
+ } catch (err) {
78
+ context.error = err;
79
+ _optionalChain([error, 'optionalAccess', _30 => _30.publish, 'call', _31 => _31(context)]);
80
+ _optionalChain([end, 'optionalAccess', _32 => _32.publish, 'call', _33 => _33(context)]);
81
+ throw err;
82
+ }
83
+ });
84
+ };
85
+ }
86
+ }
87
+
88
+ // src/node/config.ts
5
89
  var _promises = require('node:fs/promises'); var fs = _interopRequireWildcard(_promises);
6
90
  var _nodeos = require('node:os'); var os = _interopRequireWildcard(_nodeos);
7
91
  var _nodefs = require('node:fs'); var fsSync = _interopRequireWildcard(_nodefs);
@@ -157,8 +241,8 @@ function setDebugLogStateResolver(resolver) {
157
241
  debugLogStateResolver = resolver;
158
242
  }
159
243
  function resolveDebugLogLevel(state) {
160
- const stateLevel = _optionalChain([state, 'optionalAccess', _2 => _2.getDebugLogLevel, 'optionalCall', _3 => _3()]);
161
- const hasStateOverride = _nullishCoalesce(_optionalChain([state, 'optionalAccess', _4 => _4.hasDebugLogLevelOverride, 'optionalCall', _5 => _5()]), () => ( false));
244
+ const stateLevel = _optionalChain([state, 'optionalAccess', _34 => _34.getDebugLogLevel, 'optionalCall', _35 => _35()]);
245
+ const hasStateOverride = _nullishCoalesce(_optionalChain([state, 'optionalAccess', _36 => _36.hasDebugLogLevelOverride, 'optionalCall', _37 => _37()]), () => ( false));
162
246
  if (hasStateOverride) {
163
247
  return stateLevel;
164
248
  }
@@ -187,7 +271,7 @@ function emit(method, state, args) {
187
271
  }
188
272
  }
189
273
  function createDebugLogger(state) {
190
- const resolveState = () => _nullishCoalesce(state, () => ( _optionalChain([debugLogStateResolver, 'optionalCall', _6 => _6()])));
274
+ const resolveState = () => _nullishCoalesce(state, () => ( _optionalChain([debugLogStateResolver, 'optionalCall', _38 => _38()])));
191
275
  return {
192
276
  info(...args) {
193
277
  emit("info", resolveState(), args);
@@ -221,7 +305,7 @@ async function currentRepo() {
221
305
  } else {
222
306
  return null;
223
307
  }
224
- } catch (e2) {
308
+ } catch (e4) {
225
309
  return null;
226
310
  }
227
311
  }
@@ -232,7 +316,7 @@ async function getBaseBranch(remote = void 0) {
232
316
  if (git === null) {
233
317
  throw new Error("Not in a git repo");
234
318
  }
235
- const remoteName = await _asyncNullishCoalesce(remote, async () => ( await _asyncOptionalChain([(await git.getRemotes()), 'access', async _7 => _7[0], 'optionalAccess', async _8 => _8.name])));
319
+ const remoteName = await _asyncNullishCoalesce(remote, async () => ( await _asyncOptionalChain([(await git.getRemotes()), 'access', async _39 => _39[0], 'optionalAccess', async _40 => _40.name])));
236
320
  if (!remoteName) {
237
321
  throw new Error("No remote found");
238
322
  }
@@ -254,7 +338,7 @@ async function getBaseBranch(remote = void 0) {
254
338
  throw new Error(`Could not find HEAD branch in remote ${remoteName}`);
255
339
  }
256
340
  branch = match[1];
257
- } catch (e3) {
341
+ } catch (e5) {
258
342
  branch = "main";
259
343
  }
260
344
  }
@@ -277,7 +361,7 @@ async function getBaseBranchAncestor(remote = void 0) {
277
361
  `${remoteName}/${baseBranch}`
278
362
  ]);
279
363
  return ancestor.trim();
280
- } catch (e4) {
364
+ } catch (e6) {
281
365
  return void 0;
282
366
  }
283
367
  }
@@ -304,7 +388,7 @@ async function getPastNAncestors(n = 1e3, remote = void 0) {
304
388
  async function attempt(fn) {
305
389
  try {
306
390
  return await fn();
307
- } catch (e5) {
391
+ } catch (e7) {
308
392
  return void 0;
309
393
  }
310
394
  }
@@ -325,7 +409,7 @@ async function getRepoInfo(settings) {
325
409
  return repo;
326
410
  }
327
411
  let sanitized = {};
328
- _optionalChain([settings, 'access', _9 => _9.fields, 'optionalAccess', _10 => _10.forEach, 'call', _11 => _11((field) => {
412
+ _optionalChain([settings, 'access', _41 => _41.fields, 'optionalAccess', _42 => _42.forEach, 'call', _43 => _43((field) => {
329
413
  sanitized = { ...sanitized, [field]: repo[field] };
330
414
  })]);
331
415
  return sanitized;
@@ -411,9 +495,9 @@ function getCallerLocation() {
411
495
  const entries = getStackTrace();
412
496
  for (const frame of entries) {
413
497
  if (thisDir === void 0) {
414
- thisDir = _optionalChain([isomorph_default, 'access', _12 => _12.pathDirname, 'optionalCall', _13 => _13(frame.fileName)]);
498
+ thisDir = _optionalChain([isomorph_default, 'access', _44 => _44.pathDirname, 'optionalCall', _45 => _45(frame.fileName)]);
415
499
  }
416
- if (_optionalChain([isomorph_default, 'access', _14 => _14.pathDirname, 'optionalCall', _15 => _15(frame.fileName)]) !== thisDir) {
500
+ if (_optionalChain([isomorph_default, 'access', _46 => _46.pathDirname, 'optionalCall', _47 => _47(frame.fileName)]) !== thisDir) {
417
501
  return {
418
502
  caller_functionname: frame.functionName,
419
503
  caller_filename: frame.fileName,
@@ -660,7 +744,7 @@ var SpanComponentsV1 = class _SpanComponentsV1 {
660
744
  return {
661
745
  objectType: this.objectType,
662
746
  objectId: this.objectId,
663
- rowIds: _optionalChain([this, 'access', _16 => _16.rowIds, 'optionalAccess', _17 => _17.toObject, 'call', _18 => _18()])
747
+ rowIds: _optionalChain([this, 'access', _48 => _48.rowIds, 'optionalAccess', _49 => _49.toObject, 'call', _50 => _50()])
664
748
  };
665
749
  }
666
750
  };
@@ -874,7 +958,7 @@ var SpanComponentsV2 = class _SpanComponentsV2 {
874
958
  objectType: this.objectType,
875
959
  objectId: this.objectId,
876
960
  computeObjectMetadataArgs: this.computeObjectMetadataArgs,
877
- rowIds: _optionalChain([this, 'access', _19 => _19.rowIds, 'optionalAccess', _20 => _20.toObject, 'call', _21 => _21()])
961
+ rowIds: _optionalChain([this, 'access', _51 => _51.rowIds, 'optionalAccess', _52 => _52.toObject, 'call', _53 => _53()])
878
962
  };
879
963
  }
880
964
  };
@@ -925,7 +1009,7 @@ function tryMakeUuid3(s) {
925
1009
  throw new Error();
926
1010
  }
927
1011
  return { bytes: new Uint8Array(ret), isUUID: true };
928
- } catch (e6) {
1012
+ } catch (e8) {
929
1013
  return { bytes: void 0, isUUID: false };
930
1014
  }
931
1015
  }
@@ -1089,7 +1173,7 @@ var SpanComponentsV3 = class _SpanComponentsV3 {
1089
1173
  }
1090
1174
  }
1091
1175
  return _SpanComponentsV3.fromJsonObj(jsonObj);
1092
- } catch (e7) {
1176
+ } catch (e9) {
1093
1177
  throw new Error(INVALID_ENCODING_ERRMSG3);
1094
1178
  }
1095
1179
  }
@@ -1414,20 +1498,20 @@ function slugify(text, options) {
1414
1498
  \u00FF: "y"
1415
1499
  };
1416
1500
  const replacement = "-";
1417
- const trim = _optionalChain([options, 'optionalAccess', _22 => _22.trim]) !== false;
1501
+ const trim = _optionalChain([options, 'optionalAccess', _54 => _54.trim]) !== false;
1418
1502
  let slug = text.normalize().split("").reduce((result, ch) => {
1419
1503
  const mapped = charMap[ch] || ch;
1420
1504
  const appendChar = mapped === replacement ? " " : mapped;
1421
1505
  return result + appendChar.replace(/[^\w\s$*_+~.()'"!\-:@]+/g, "");
1422
1506
  }, "");
1423
- if (_optionalChain([options, 'optionalAccess', _23 => _23.strict])) {
1507
+ if (_optionalChain([options, 'optionalAccess', _55 => _55.strict])) {
1424
1508
  slug = slug.replace(/[^A-Za-z0-9\s]/g, "");
1425
1509
  }
1426
1510
  if (trim) {
1427
1511
  slug = slug.trim();
1428
1512
  }
1429
1513
  slug = slug.replace(/\s+/g, replacement);
1430
- if (_optionalChain([options, 'optionalAccess', _24 => _24.lower])) {
1514
+ if (_optionalChain([options, 'optionalAccess', _56 => _56.lower])) {
1431
1515
  slug = slug.toLowerCase();
1432
1516
  }
1433
1517
  return slug;
@@ -1448,7 +1532,7 @@ function tryMakeHexTraceId(s) {
1448
1532
  }
1449
1533
  return { bytes, isHex: true };
1450
1534
  }
1451
- } catch (e8) {
1535
+ } catch (e10) {
1452
1536
  }
1453
1537
  return { bytes: void 0, isHex: false };
1454
1538
  }
@@ -1464,7 +1548,7 @@ function tryMakeHexSpanId(s) {
1464
1548
  }
1465
1549
  return { bytes, isHex: true };
1466
1550
  }
1467
- } catch (e9) {
1551
+ } catch (e11) {
1468
1552
  }
1469
1553
  return { bytes: void 0, isHex: false };
1470
1554
  }
@@ -1613,7 +1697,7 @@ var SpanComponentsV4 = class _SpanComponentsV4 {
1613
1697
  }
1614
1698
  }
1615
1699
  return _SpanComponentsV4.fromJsonObj(jsonObj);
1616
- } catch (e10) {
1700
+ } catch (e12) {
1617
1701
  throw new Error(INVALID_ENCODING_ERRMSG_V4);
1618
1702
  }
1619
1703
  }
@@ -3554,7 +3638,7 @@ function getMustacheVars(prompt) {
3554
3638
  return _mustache2.default.parse(prompt).filter(
3555
3639
  (span) => span[0] === "name" || span[0] === "&"
3556
3640
  );
3557
- } catch (e11) {
3641
+ } catch (e13) {
3558
3642
  return [];
3559
3643
  }
3560
3644
  }
@@ -3566,8 +3650,8 @@ var mustachePlugin = {
3566
3650
  defaultOptions: { strict: true, escape: jsonEscape },
3567
3651
  createRenderer() {
3568
3652
  const opts = _nullishCoalesce(this.defaultOptions, () => ( {}));
3569
- const escapeFn = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _25 => _25.escape]), () => ( jsonEscape));
3570
- const strictDefault = typeof _optionalChain([opts, 'optionalAccess', _26 => _26.strict]) === "boolean" ? opts.strict : true;
3653
+ const escapeFn = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _57 => _57.escape]), () => ( jsonEscape));
3654
+ const strictDefault = typeof _optionalChain([opts, 'optionalAccess', _58 => _58.strict]) === "boolean" ? opts.strict : true;
3571
3655
  return {
3572
3656
  render(template, variables, escape, strict) {
3573
3657
  const esc = _nullishCoalesce(escape, () => ( escapeFn));
@@ -3601,7 +3685,7 @@ var TemplatePluginRegistry = (_class5 = class {constructor() { _class5.prototype
3601
3685
  return Array.from(this.plugins.keys());
3602
3686
  }
3603
3687
  get(name) {
3604
- return _optionalChain([this, 'access', _27 => _27.plugins, 'access', _28 => _28.get, 'call', _29 => _29(name), 'optionalAccess', _30 => _30.renderer]);
3688
+ return _optionalChain([this, 'access', _59 => _59.plugins, 'access', _60 => _60.get, 'call', _61 => _61(name), 'optionalAccess', _62 => _62.renderer]);
3605
3689
  }
3606
3690
  isRegistered(name) {
3607
3691
  return this.plugins.has(name);
@@ -4235,7 +4319,7 @@ var SpanCache = (_class6 = class {
4235
4319
  // Small in-memory index tracking which rootSpanIds have data
4236
4320
  __init14() {this.rootSpanIndex = /* @__PURE__ */ new Set()}
4237
4321
  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);
4238
- this._explicitlyDisabled = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _31 => _31.disabled]), () => ( false));
4322
+ this._explicitlyDisabled = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _63 => _63.disabled]), () => ( false));
4239
4323
  }
4240
4324
  /**
4241
4325
  * Disable the cache at runtime. This is called automatically when
@@ -4313,13 +4397,13 @@ var SpanCache = (_class6 = class {
4313
4397
  cache.fileHandle.close().catch(() => {
4314
4398
  });
4315
4399
  cache.fileHandle = null;
4316
- } catch (e12) {
4400
+ } catch (e14) {
4317
4401
  }
4318
4402
  }
4319
4403
  if (cache.cacheFilePath && canUseSpanCache() && isomorph_default.unlinkSync) {
4320
4404
  try {
4321
4405
  isomorph_default.unlinkSync(cache.cacheFilePath);
4322
- } catch (e13) {
4406
+ } catch (e15) {
4323
4407
  }
4324
4408
  }
4325
4409
  }
@@ -4416,10 +4500,10 @@ var SpanCache = (_class6 = class {
4416
4500
  } else {
4417
4501
  spanMap.set(record.spanId, record.data);
4418
4502
  }
4419
- } catch (e14) {
4503
+ } catch (e16) {
4420
4504
  }
4421
4505
  }
4422
- } catch (e15) {
4506
+ } catch (e17) {
4423
4507
  }
4424
4508
  }
4425
4509
  for (const record of this.writeBuffer) {
@@ -4491,7 +4575,7 @@ var SpanCache = (_class6 = class {
4491
4575
  if (this.cacheFilePath && canUseSpanCache() && isomorph_default.unlinkSync) {
4492
4576
  try {
4493
4577
  isomorph_default.unlinkSync(this.cacheFilePath);
4494
- } catch (e16) {
4578
+ } catch (e18) {
4495
4579
  }
4496
4580
  this.cacheFilePath = null;
4497
4581
  }
@@ -4506,6 +4590,9 @@ var BRAINTRUST_ATTACHMENT = BraintrustAttachmentReference.shape.type.value;
4506
4590
  var EXTERNAL_ATTACHMENT = ExternalAttachmentReference.shape.type.value;
4507
4591
  var LOGS3_OVERFLOW_REFERENCE_TYPE = "logs3_overflow";
4508
4592
  var BRAINTRUST_PARAMS = Object.keys(BraintrustModelParams.shape);
4593
+ var RESET_CONTEXT_MANAGER_STATE = Symbol.for(
4594
+ "braintrust.resetContextManagerState"
4595
+ );
4509
4596
  var DEFAULT_MAX_REQUEST_SIZE = 6 * 1024 * 1024;
4510
4597
  var parametersRowSchema = _v3.z.object({
4511
4598
  id: _v3.z.string().uuid(),
@@ -4568,13 +4655,18 @@ function applyMaskingToField(maskingFunction, data, fieldName) {
4568
4655
  return `ERROR: Failed to mask field '${fieldName}' - ${errorType}`;
4569
4656
  }
4570
4657
  }
4658
+ var BRAINTRUST_CURRENT_SPAN_STORE = Symbol.for(
4659
+ "braintrust.currentSpanStore"
4660
+ );
4571
4661
  var ContextManager = class {
4572
4662
  };
4573
4663
  var BraintrustContextManager = class extends ContextManager {
4574
4664
 
4665
+
4575
4666
  constructor() {
4576
4667
  super();
4577
4668
  this._currentSpan = isomorph_default.newAsyncLocalStorage();
4669
+ this[BRAINTRUST_CURRENT_SPAN_STORE] = this._currentSpan;
4578
4670
  }
4579
4671
  getParentSpanIds() {
4580
4672
  const currentSpan2 = this._currentSpan.getStore();
@@ -4625,7 +4717,7 @@ var NoopSpan = (_class7 = class {
4625
4717
  return this;
4626
4718
  }
4627
4719
  end(args) {
4628
- return _nullishCoalesce(_optionalChain([args, 'optionalAccess', _32 => _32.endTime]), () => ( getCurrentUnixTimestamp()));
4720
+ return _nullishCoalesce(_optionalChain([args, 'optionalAccess', _64 => _64.endTime]), () => ( getCurrentUnixTimestamp()));
4629
4721
  }
4630
4722
  async export() {
4631
4723
  return "";
@@ -4781,6 +4873,9 @@ var BraintrustState = (_class8 = class _BraintrustState {
4781
4873
  resetIdGenState() {
4782
4874
  this._idGenerator = null;
4783
4875
  }
4876
+ [RESET_CONTEXT_MANAGER_STATE]() {
4877
+ this._contextManager = null;
4878
+ }
4784
4879
  get idGenerator() {
4785
4880
  if (this._idGenerator === null) {
4786
4881
  this._idGenerator = getIdGenerator();
@@ -4887,8 +4982,8 @@ var BraintrustState = (_class8 = class _BraintrustState {
4887
4982
  setFetch(fetch2) {
4888
4983
  this.loginParams.fetch = fetch2;
4889
4984
  this.fetch = fetch2;
4890
- _optionalChain([this, 'access', _33 => _33._apiConn, 'optionalAccess', _34 => _34.setFetch, 'call', _35 => _35(fetch2)]);
4891
- _optionalChain([this, 'access', _36 => _36._appConn, 'optionalAccess', _37 => _37.setFetch, 'call', _38 => _38(fetch2)]);
4985
+ _optionalChain([this, 'access', _65 => _65._apiConn, 'optionalAccess', _66 => _66.setFetch, 'call', _67 => _67(fetch2)]);
4986
+ _optionalChain([this, 'access', _68 => _68._appConn, 'optionalAccess', _69 => _69.setFetch, 'call', _70 => _70(fetch2)]);
4892
4987
  }
4893
4988
  setMaskingFunction(maskingFunction) {
4894
4989
  this.bgLogger().setMaskingFunction(maskingFunction);
@@ -5061,7 +5156,7 @@ var HTTPConnection = class _HTTPConnection {
5061
5156
  try {
5062
5157
  const resp = await this.get("ping");
5063
5158
  return resp.status === 200;
5064
- } catch (e17) {
5159
+ } catch (e19) {
5065
5160
  return false;
5066
5161
  }
5067
5162
  }
@@ -5590,8 +5685,8 @@ function _getOrgName(orgName) {
5590
5685
  return orgName || isomorph_default.getEnv("BRAINTRUST_ORG_NAME") || void 0;
5591
5686
  }
5592
5687
  function _getLinkBaseUrl(state, linkArgs) {
5593
- const appUrl = _getAppUrl(state.appUrl || _optionalChain([linkArgs, 'optionalAccess', _39 => _39.app_url]));
5594
- const orgName = _getOrgName(state.orgName || _optionalChain([linkArgs, 'optionalAccess', _40 => _40.org_name]));
5688
+ const appUrl = _getAppUrl(state.appUrl || _optionalChain([linkArgs, 'optionalAccess', _71 => _71.app_url]));
5689
+ const orgName = _getOrgName(state.orgName || _optionalChain([linkArgs, 'optionalAccess', _72 => _72.org_name]));
5595
5690
  if (!orgName) {
5596
5691
  return null;
5597
5692
  }
@@ -5601,9 +5696,9 @@ async function permalink(slug, opts) {
5601
5696
  if (slug === "") {
5602
5697
  return NOOP_SPAN_PERMALINK;
5603
5698
  }
5604
- const state = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _41 => _41.state]), () => ( _globalState));
5699
+ const state = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _73 => _73.state]), () => ( _globalState));
5605
5700
  const getOrgName = async () => {
5606
- if (_optionalChain([opts, 'optionalAccess', _42 => _42.orgName])) {
5701
+ if (_optionalChain([opts, 'optionalAccess', _74 => _74.orgName])) {
5607
5702
  return opts.orgName;
5608
5703
  }
5609
5704
  await state.login({});
@@ -5613,7 +5708,7 @@ async function permalink(slug, opts) {
5613
5708
  return state.orgName;
5614
5709
  };
5615
5710
  const getAppUrl = async () => {
5616
- if (_optionalChain([opts, 'optionalAccess', _43 => _43.appUrl])) {
5711
+ if (_optionalChain([opts, 'optionalAccess', _75 => _75.appUrl])) {
5617
5712
  return opts.appUrl;
5618
5713
  }
5619
5714
  await state.login({});
@@ -5748,7 +5843,7 @@ var Logger = (_class9 = class {
5748
5843
  * @returns The `id` of the logged event.
5749
5844
  */
5750
5845
  log(event, options) {
5751
- if (this.calledStartSpan && !_optionalChain([options, 'optionalAccess', _44 => _44.allowConcurrentWithSpans])) {
5846
+ if (this.calledStartSpan && !_optionalChain([options, 'optionalAccess', _76 => _76.allowConcurrentWithSpans])) {
5752
5847
  throw new Error(
5753
5848
  "Cannot run toplevel `log` method while using spans. To log to the span, call `logger.traced` and then log with `span.log`"
5754
5849
  );
@@ -5816,12 +5911,12 @@ var Logger = (_class9 = class {
5816
5911
  state: this.state,
5817
5912
  ...startSpanParentArgs({
5818
5913
  state: this.state,
5819
- parent: _optionalChain([args, 'optionalAccess', _45 => _45.parent]),
5914
+ parent: _optionalChain([args, 'optionalAccess', _77 => _77.parent]),
5820
5915
  parentObjectType: this.parentObjectType(),
5821
5916
  parentObjectId: this.lazyId,
5822
5917
  parentComputeObjectMetadataArgs: this.computeMetadataArgs,
5823
- parentSpanIds: _optionalChain([args, 'optionalAccess', _46 => _46.parentSpanIds]),
5824
- propagatedEvent: _optionalChain([args, 'optionalAccess', _47 => _47.propagatedEvent])
5918
+ parentSpanIds: _optionalChain([args, 'optionalAccess', _78 => _78.parentSpanIds]),
5919
+ propagatedEvent: _optionalChain([args, 'optionalAccess', _79 => _79.propagatedEvent])
5825
5920
  }),
5826
5921
  defaultRootType: "task" /* TASK */
5827
5922
  });
@@ -6156,7 +6251,7 @@ var HTTPBackgroundLogger = (_class10 = class _HTTPBackgroundLogger {
6156
6251
  this.queue.clear();
6157
6252
  return;
6158
6253
  }
6159
- const batchSize = _nullishCoalesce(_optionalChain([args, 'optionalAccess', _48 => _48.batchSize]), () => ( this.defaultBatchSize));
6254
+ const batchSize = _nullishCoalesce(_optionalChain([args, 'optionalAccess', _80 => _80.batchSize]), () => ( this.defaultBatchSize));
6160
6255
  const wrappedItems = this.queue.drain();
6161
6256
  if (wrappedItems.length === 0) {
6162
6257
  return;
@@ -6470,10 +6565,10 @@ Error: ${errorText}`;
6470
6565
  } catch (err) {
6471
6566
  if (err instanceof AggregateError) {
6472
6567
  for (const e of err.errors) {
6473
- _optionalChain([this, 'access', _49 => _49.onFlushError, 'optionalCall', _50 => _50(e)]);
6568
+ _optionalChain([this, 'access', _81 => _81.onFlushError, 'optionalCall', _82 => _82(e)]);
6474
6569
  }
6475
6570
  } else {
6476
- _optionalChain([this, 'access', _51 => _51.onFlushError, 'optionalCall', _52 => _52(err)]);
6571
+ _optionalChain([this, 'access', _83 => _83.onFlushError, 'optionalCall', _84 => _84(err)]);
6477
6572
  }
6478
6573
  this.activeFlushError = err;
6479
6574
  } finally {
@@ -6900,24 +6995,24 @@ async function loginToState(options = {}) {
6900
6995
  return state;
6901
6996
  }
6902
6997
  function currentExperiment(options) {
6903
- const state = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _53 => _53.state]), () => ( _globalState));
6998
+ const state = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _85 => _85.state]), () => ( _globalState));
6904
6999
  return state.currentExperiment;
6905
7000
  }
6906
7001
  function currentLogger(options) {
6907
- const state = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _54 => _54.state]), () => ( _globalState));
6908
- return castLogger(state.currentLogger, _optionalChain([options, 'optionalAccess', _55 => _55.asyncFlush]));
7002
+ const state = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _86 => _86.state]), () => ( _globalState));
7003
+ return castLogger(state.currentLogger, _optionalChain([options, 'optionalAccess', _87 => _87.asyncFlush]));
6909
7004
  }
6910
7005
  function currentSpan(options) {
6911
- const state = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _56 => _56.state]), () => ( _globalState));
7006
+ const state = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _88 => _88.state]), () => ( _globalState));
6912
7007
  return _nullishCoalesce(state.contextManager.getCurrentSpan(), () => ( NOOP_SPAN));
6913
7008
  }
6914
7009
  function getSpanParentObject(options) {
6915
- const state = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _57 => _57.state]), () => ( _globalState));
7010
+ const state = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _89 => _89.state]), () => ( _globalState));
6916
7011
  const parentSpan = currentSpan({ state });
6917
7012
  if (!Object.is(parentSpan, NOOP_SPAN)) {
6918
7013
  return parentSpan;
6919
7014
  }
6920
- const parentStr = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _58 => _58.parent]), () => ( state.currentParent.getStore()));
7015
+ const parentStr = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _90 => _90.parent]), () => ( state.currentParent.getStore()));
6921
7016
  if (parentStr) return getSpanComponentsClass().fromStr(parentStr);
6922
7017
  const experiment = currentExperiment();
6923
7018
  if (experiment) {
@@ -6946,7 +7041,7 @@ function traced(callback, args) {
6946
7041
  const { span, isSyncFlushLogger } = startSpanAndIsLogger(args);
6947
7042
  const ret = runCatchFinally(
6948
7043
  () => {
6949
- if (_nullishCoalesce(_optionalChain([args, 'optionalAccess', _59 => _59.setCurrent]), () => ( true))) {
7044
+ if (_nullishCoalesce(_optionalChain([args, 'optionalAccess', _91 => _91.setCurrent]), () => ( true))) {
6950
7045
  return withCurrent(span, callback);
6951
7046
  } else {
6952
7047
  return callback(span);
@@ -6958,7 +7053,7 @@ function traced(callback, args) {
6958
7053
  },
6959
7054
  () => span.end()
6960
7055
  );
6961
- if (_optionalChain([args, 'optionalAccess', _60 => _60.asyncFlush]) === void 0 || _optionalChain([args, 'optionalAccess', _61 => _61.asyncFlush])) {
7056
+ if (_optionalChain([args, 'optionalAccess', _92 => _92.asyncFlush]) === void 0 || _optionalChain([args, 'optionalAccess', _93 => _93.asyncFlush])) {
6962
7057
  return ret;
6963
7058
  } else {
6964
7059
  return (async () => {
@@ -6974,14 +7069,14 @@ function startSpan(args) {
6974
7069
  return startSpanAndIsLogger(args).span;
6975
7070
  }
6976
7071
  async function flush(options) {
6977
- const state = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _62 => _62.state]), () => ( _globalState));
7072
+ const state = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _94 => _94.state]), () => ( _globalState));
6978
7073
  return await state.bgLogger().flush();
6979
7074
  }
6980
7075
  function startSpanAndIsLogger(args) {
6981
- const state = _nullishCoalesce(_optionalChain([args, 'optionalAccess', _63 => _63.state]), () => ( _globalState));
7076
+ const state = _nullishCoalesce(_optionalChain([args, 'optionalAccess', _95 => _95.state]), () => ( _globalState));
6982
7077
  const parentObject = getSpanParentObject({
6983
- asyncFlush: _optionalChain([args, 'optionalAccess', _64 => _64.asyncFlush]),
6984
- parent: _optionalChain([args, 'optionalAccess', _65 => _65.parent]),
7078
+ asyncFlush: _optionalChain([args, 'optionalAccess', _96 => _96.asyncFlush]),
7079
+ parent: _optionalChain([args, 'optionalAccess', _97 => _97.parent]),
6985
7080
  state
6986
7081
  });
6987
7082
  if (parentObject instanceof SpanComponentsV3 || parentObject instanceof SpanComponentsV4) {
@@ -6998,14 +7093,14 @@ function startSpanAndIsLogger(args) {
6998
7093
  ),
6999
7094
  parentComputeObjectMetadataArgs: _nullishCoalesce(parentObject.data.compute_object_metadata_args, () => ( void 0)),
7000
7095
  parentSpanIds,
7001
- propagatedEvent: _nullishCoalesce(_optionalChain([args, 'optionalAccess', _66 => _66.propagatedEvent]), () => ( // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
7096
+ propagatedEvent: _nullishCoalesce(_optionalChain([args, 'optionalAccess', _98 => _98.propagatedEvent]), () => ( // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
7002
7097
  (_nullishCoalesce(parentObject.data.propagated_event, () => ( void 0)))))
7003
7098
  });
7004
7099
  return {
7005
7100
  span,
7006
7101
  isSyncFlushLogger: parentObject.data.object_type === 2 /* PROJECT_LOGS */ && // Since there's no parent logger here, we're free to choose the async flush
7007
7102
  // behavior, and therefore propagate along whatever we get from the arguments
7008
- _optionalChain([args, 'optionalAccess', _67 => _67.asyncFlush]) === false
7103
+ _optionalChain([args, 'optionalAccess', _99 => _99.asyncFlush]) === false
7009
7104
  };
7010
7105
  } else {
7011
7106
  const span = parentObject.startSpan(args);
@@ -7153,10 +7248,10 @@ function extractAttachments(event, attachments) {
7153
7248
  event[key] = value.reference;
7154
7249
  continue;
7155
7250
  }
7156
- if (_optionalChain([value, 'optionalAccess', _68 => _68.type]) === BRAINTRUST_ATTACHMENT && value.key && !value.uploader) {
7251
+ if (_optionalChain([value, 'optionalAccess', _100 => _100.type]) === BRAINTRUST_ATTACHMENT && value.key && !value.uploader) {
7157
7252
  continue;
7158
7253
  }
7159
- if (_optionalChain([value, 'optionalAccess', _69 => _69.reference, 'optionalAccess', _70 => _70.type]) === BRAINTRUST_ATTACHMENT && _optionalChain([value, 'optionalAccess', _71 => _71.uploader])) {
7254
+ if (_optionalChain([value, 'optionalAccess', _101 => _101.reference, 'optionalAccess', _102 => _102.type]) === BRAINTRUST_ATTACHMENT && _optionalChain([value, 'optionalAccess', _103 => _103.uploader])) {
7160
7255
  const attachment = new Attachment({
7161
7256
  data: value.dataDebugString,
7162
7257
  filename: value.reference.filename,
@@ -7240,7 +7335,7 @@ var ObjectFetcher = (_class11 = class {
7240
7335
  const state = await this.getState();
7241
7336
  const objectId = await this.id;
7242
7337
  const batchLimit = _nullishCoalesce(batchSize, () => ( DEFAULT_FETCH_BATCH_SIZE));
7243
- const internalLimit = _optionalChain([this, 'access', _72 => _72._internal_btql, 'optionalAccess', _73 => _73.limit]);
7338
+ const internalLimit = _optionalChain([this, 'access', _104 => _104._internal_btql, 'optionalAccess', _105 => _105.limit]);
7244
7339
  const limit = batchSize !== void 0 ? batchSize : _nullishCoalesce(internalLimit, () => ( batchLimit));
7245
7340
  const internalBtqlWithoutReservedQueryKeys = Object.fromEntries(
7246
7341
  Object.entries(_nullishCoalesce(this._internal_btql, () => ( {}))).filter(
@@ -7314,7 +7409,7 @@ var ObjectFetcher = (_class11 = class {
7314
7409
  }
7315
7410
  return;
7316
7411
  }
7317
- for await (const record of this.fetchRecordsFromApi(_optionalChain([options, 'optionalAccess', _74 => _74.batchSize]))) {
7412
+ for await (const record of this.fetchRecordsFromApi(_optionalChain([options, 'optionalAccess', _106 => _106.batchSize]))) {
7318
7413
  yield record;
7319
7414
  }
7320
7415
  }
@@ -7324,7 +7419,7 @@ var ObjectFetcher = (_class11 = class {
7324
7419
  async fetchedData(options) {
7325
7420
  if (this._fetchedData === void 0) {
7326
7421
  const data = [];
7327
- for await (const record of this.fetchRecordsFromApi(_optionalChain([options, 'optionalAccess', _75 => _75.batchSize]))) {
7422
+ for await (const record of this.fetchRecordsFromApi(_optionalChain([options, 'optionalAccess', _107 => _107.batchSize]))) {
7328
7423
  data.push(record);
7329
7424
  }
7330
7425
  this._fetchedData = data;
@@ -7419,7 +7514,7 @@ var Experiment2 = (_class12 = class extends ObjectFetcher {
7419
7514
  * @returns The `id` of the logged event.
7420
7515
  */
7421
7516
  log(event, options) {
7422
- if (this.calledStartSpan && !_optionalChain([options, 'optionalAccess', _76 => _76.allowConcurrentWithSpans])) {
7517
+ if (this.calledStartSpan && !_optionalChain([options, 'optionalAccess', _108 => _108.allowConcurrentWithSpans])) {
7423
7518
  throw new Error(
7424
7519
  "Cannot run toplevel `log` method while using spans. To log to the span, call `experiment.traced` and then log with `span.log`"
7425
7520
  );
@@ -7472,12 +7567,12 @@ var Experiment2 = (_class12 = class extends ObjectFetcher {
7472
7567
  state: this.state,
7473
7568
  ...startSpanParentArgs({
7474
7569
  state: this.state,
7475
- parent: _optionalChain([args, 'optionalAccess', _77 => _77.parent]),
7570
+ parent: _optionalChain([args, 'optionalAccess', _109 => _109.parent]),
7476
7571
  parentObjectType: this.parentObjectType(),
7477
7572
  parentObjectId: this.lazyId,
7478
7573
  parentComputeObjectMetadataArgs: void 0,
7479
7574
  parentSpanIds: void 0,
7480
- propagatedEvent: _optionalChain([args, 'optionalAccess', _78 => _78.propagatedEvent])
7575
+ propagatedEvent: _optionalChain([args, 'optionalAccess', _110 => _110.propagatedEvent])
7481
7576
  }),
7482
7577
  defaultRootType: "eval" /* EVAL */
7483
7578
  });
@@ -7821,7 +7916,7 @@ var SpanImpl = (_class13 = class _SpanImpl {
7821
7916
  ...serializableInternalData,
7822
7917
  [IS_MERGE_FIELD]: this.isMerge
7823
7918
  });
7824
- if (typeof _optionalChain([partialRecord, 'access', _79 => _79.metrics, 'optionalAccess', _80 => _80.end]) === "number") {
7919
+ if (typeof _optionalChain([partialRecord, 'access', _111 => _111.metrics, 'optionalAccess', _112 => _112.end]) === "number") {
7825
7920
  this.loggedEndTime = partialRecord.metrics.end;
7826
7921
  }
7827
7922
  if (this.parentObjectType === 1 /* EXPERIMENT */) {
@@ -7881,18 +7976,18 @@ var SpanImpl = (_class13 = class _SpanImpl {
7881
7976
  );
7882
7977
  }
7883
7978
  startSpan(args) {
7884
- const parentSpanIds = _optionalChain([args, 'optionalAccess', _81 => _81.parent]) ? void 0 : { spanId: this._spanId, rootSpanId: this._rootSpanId };
7979
+ const parentSpanIds = _optionalChain([args, 'optionalAccess', _113 => _113.parent]) ? void 0 : { spanId: this._spanId, rootSpanId: this._rootSpanId };
7885
7980
  return new _SpanImpl({
7886
7981
  state: this._state,
7887
7982
  ...args,
7888
7983
  ...startSpanParentArgs({
7889
7984
  state: this._state,
7890
- parent: _optionalChain([args, 'optionalAccess', _82 => _82.parent]),
7985
+ parent: _optionalChain([args, 'optionalAccess', _114 => _114.parent]),
7891
7986
  parentObjectType: this.parentObjectType,
7892
7987
  parentObjectId: this.parentObjectId,
7893
7988
  parentComputeObjectMetadataArgs: this.parentComputeObjectMetadataArgs,
7894
7989
  parentSpanIds,
7895
- propagatedEvent: _nullishCoalesce(_optionalChain([args, 'optionalAccess', _83 => _83.propagatedEvent]), () => ( this.propagatedEvent))
7990
+ propagatedEvent: _nullishCoalesce(_optionalChain([args, 'optionalAccess', _115 => _115.propagatedEvent]), () => ( this.propagatedEvent))
7896
7991
  })
7897
7992
  });
7898
7993
  }
@@ -7906,12 +8001,12 @@ var SpanImpl = (_class13 = class _SpanImpl {
7906
8001
  ...args,
7907
8002
  ...startSpanParentArgs({
7908
8003
  state: this._state,
7909
- parent: _optionalChain([args, 'optionalAccess', _84 => _84.parent]),
8004
+ parent: _optionalChain([args, 'optionalAccess', _116 => _116.parent]),
7910
8005
  parentObjectType: this.parentObjectType,
7911
8006
  parentObjectId: this.parentObjectId,
7912
8007
  parentComputeObjectMetadataArgs: this.parentComputeObjectMetadataArgs,
7913
8008
  parentSpanIds,
7914
- propagatedEvent: _nullishCoalesce(_optionalChain([args, 'optionalAccess', _85 => _85.propagatedEvent]), () => ( this.propagatedEvent))
8009
+ propagatedEvent: _nullishCoalesce(_optionalChain([args, 'optionalAccess', _117 => _117.propagatedEvent]), () => ( this.propagatedEvent))
7915
8010
  }),
7916
8011
  spanId
7917
8012
  });
@@ -7920,7 +8015,7 @@ var SpanImpl = (_class13 = class _SpanImpl {
7920
8015
  let endTime;
7921
8016
  let internalData = {};
7922
8017
  if (!this.loggedEndTime) {
7923
- endTime = _nullishCoalesce(_optionalChain([args, 'optionalAccess', _86 => _86.endTime]), () => ( getCurrentUnixTimestamp()));
8018
+ endTime = _nullishCoalesce(_optionalChain([args, 'optionalAccess', _118 => _118.endTime]), () => ( getCurrentUnixTimestamp()));
7924
8019
  internalData = { metrics: { end: endTime } };
7925
8020
  } else {
7926
8021
  endTime = this.loggedEndTime;
@@ -7971,8 +8066,8 @@ var SpanImpl = (_class13 = class _SpanImpl {
7971
8066
  const args = this.parentComputeObjectMetadataArgs;
7972
8067
  switch (this.parentObjectType) {
7973
8068
  case 2 /* PROJECT_LOGS */: {
7974
- const projectID = _optionalChain([args, 'optionalAccess', _87 => _87.project_id]) || this.parentObjectId.getSync().value;
7975
- const projectName = _optionalChain([args, 'optionalAccess', _88 => _88.project_name]);
8069
+ const projectID = _optionalChain([args, 'optionalAccess', _119 => _119.project_id]) || this.parentObjectId.getSync().value;
8070
+ const projectName = _optionalChain([args, 'optionalAccess', _120 => _120.project_name]);
7976
8071
  if (projectID) {
7977
8072
  return `${baseUrl}/object?object_type=project_logs&object_id=${projectID}&id=${this._id}`;
7978
8073
  } else if (projectName) {
@@ -7982,7 +8077,7 @@ var SpanImpl = (_class13 = class _SpanImpl {
7982
8077
  }
7983
8078
  }
7984
8079
  case 1 /* EXPERIMENT */: {
7985
- 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]);
8080
+ 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]);
7986
8081
  if (!expID) {
7987
8082
  return getErrPermlink("provide-experiment-id");
7988
8083
  } else {
@@ -8304,7 +8399,7 @@ function isURL(url) {
8304
8399
  try {
8305
8400
  const parsedUrl = new URL(url.trim());
8306
8401
  return parsedUrl.protocol === "http:" || parsedUrl.protocol === "https:";
8307
- } catch (e18) {
8402
+ } catch (e20) {
8308
8403
  return false;
8309
8404
  }
8310
8405
  }
@@ -8482,16 +8577,16 @@ var Prompt2 = (_class15 = class _Prompt {
8482
8577
  return "slug" in this.metadata ? this.metadata.slug : this.metadata.id;
8483
8578
  }
8484
8579
  get prompt() {
8485
- return _optionalChain([this, 'access', _94 => _94.getParsedPromptData, 'call', _95 => _95(), 'optionalAccess', _96 => _96.prompt]);
8580
+ return _optionalChain([this, 'access', _126 => _126.getParsedPromptData, 'call', _127 => _127(), 'optionalAccess', _128 => _128.prompt]);
8486
8581
  }
8487
8582
  get version() {
8488
8583
  return this.metadata[TRANSACTION_ID_FIELD];
8489
8584
  }
8490
8585
  get options() {
8491
- return _optionalChain([this, 'access', _97 => _97.getParsedPromptData, 'call', _98 => _98(), 'optionalAccess', _99 => _99.options]) || {};
8586
+ return _optionalChain([this, 'access', _129 => _129.getParsedPromptData, 'call', _130 => _130(), 'optionalAccess', _131 => _131.options]) || {};
8492
8587
  }
8493
8588
  get templateFormat() {
8494
- return _optionalChain([this, 'access', _100 => _100.getParsedPromptData, 'call', _101 => _101(), 'optionalAccess', _102 => _102.template_format]);
8589
+ return _optionalChain([this, 'access', _132 => _132.getParsedPromptData, 'call', _133 => _133(), 'optionalAccess', _134 => _134.template_format]);
8495
8590
  }
8496
8591
  get promptData() {
8497
8592
  return this.getParsedPromptData();
@@ -8653,7 +8748,7 @@ var Prompt2 = (_class15 = class _Prompt {
8653
8748
  return {
8654
8749
  type: "chat",
8655
8750
  messages,
8656
- ..._optionalChain([prompt, 'access', _103 => _103.tools, 'optionalAccess', _104 => _104.trim, 'call', _105 => _105()]) ? {
8751
+ ..._optionalChain([prompt, 'access', _135 => _135.tools, 'optionalAccess', _136 => _136.trim, 'call', _137 => _137()]) ? {
8657
8752
  tools: render(prompt.tools)
8658
8753
  } : void 0
8659
8754
  };
@@ -8869,7 +8964,7 @@ function getChannelSpanInfo(event) {
8869
8964
  if (isObject(event.span_info)) {
8870
8965
  return event.span_info;
8871
8966
  }
8872
- const firstArg = _optionalChain([event, 'access', _106 => _106.arguments, 'optionalAccess', _107 => _107[0]]);
8967
+ const firstArg = _optionalChain([event, 'access', _138 => _138.arguments, 'optionalAccess', _139 => _139[0]]);
8873
8968
  if (hasChannelSpanInfo(firstArg)) {
8874
8969
  return firstArg.span_info;
8875
8970
  }
@@ -8880,13 +8975,13 @@ function buildStartSpanArgs(config, event) {
8880
8975
  const spanAttributes = {
8881
8976
  type: config.type
8882
8977
  };
8883
- if (isObject(_optionalChain([spanInfo, 'optionalAccess', _108 => _108.spanAttributes]))) {
8978
+ if (isObject(_optionalChain([spanInfo, 'optionalAccess', _140 => _140.spanAttributes]))) {
8884
8979
  mergeDicts(spanAttributes, spanInfo.spanAttributes);
8885
8980
  }
8886
8981
  return {
8887
- name: typeof _optionalChain([spanInfo, 'optionalAccess', _109 => _109.name]) === "string" && spanInfo.name ? spanInfo.name : config.name,
8982
+ name: typeof _optionalChain([spanInfo, 'optionalAccess', _141 => _141.name]) === "string" && spanInfo.name ? spanInfo.name : config.name,
8888
8983
  spanAttributes,
8889
- spanInfoMetadata: isObject(_optionalChain([spanInfo, 'optionalAccess', _110 => _110.metadata])) ? spanInfo.metadata : void 0
8984
+ spanInfoMetadata: isObject(_optionalChain([spanInfo, 'optionalAccess', _142 => _142.metadata])) ? spanInfo.metadata : void 0
8890
8985
  };
8891
8986
  }
8892
8987
  function mergeInputMetadata(metadata, spanInfoMetadata) {
@@ -8976,7 +9071,7 @@ var BasePlugin = (_class17 = class {constructor() { _class17.prototype.__init62.
8976
9071
  try {
8977
9072
  const output = config.extractOutput(event.result, event);
8978
9073
  const metrics = config.extractMetrics(event.result, startTime, event);
8979
- const metadata = _optionalChain([config, 'access', _111 => _111.extractMetadata, 'optionalCall', _112 => _112(event.result, event)]);
9074
+ const metadata = _optionalChain([config, 'access', _143 => _143.extractMetadata, 'optionalCall', _144 => _144(event.result, event)]);
8980
9075
  span.log({
8981
9076
  output,
8982
9077
  ...metadata !== void 0 ? { metadata } : {},
@@ -9283,6 +9378,36 @@ function startSpanForEvent(config, event, channelName) {
9283
9378
  }
9284
9379
  return { span, startTime };
9285
9380
  }
9381
+ function ensureSpanStateForEvent(states, config, event, channelName) {
9382
+ const key = event;
9383
+ const existing = states.get(key);
9384
+ if (existing) {
9385
+ return existing;
9386
+ }
9387
+ const created = startSpanForEvent(config, event, channelName);
9388
+ states.set(key, created);
9389
+ return created;
9390
+ }
9391
+ function bindCurrentSpanStoreToStart(tracingChannel2, states, config, channelName) {
9392
+ const state = _internalGetGlobalState();
9393
+ const startChannel = tracingChannel2.start;
9394
+ const currentSpanStore = _optionalChain([state, 'optionalAccess', _145 => _145.contextManager]) ? state.contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
9395
+ if (!currentSpanStore || !startChannel) {
9396
+ return void 0;
9397
+ }
9398
+ startChannel.bindStore(
9399
+ currentSpanStore,
9400
+ (event) => ensureSpanStateForEvent(
9401
+ states,
9402
+ config,
9403
+ event,
9404
+ channelName
9405
+ ).span
9406
+ );
9407
+ return () => {
9408
+ startChannel.unbindStore(currentSpanStore);
9409
+ };
9410
+ }
9286
9411
  function logErrorAndEnd(states, event) {
9287
9412
  const spanData = states.get(event);
9288
9413
  if (!spanData) {
@@ -9298,15 +9423,19 @@ function traceAsyncChannel(channel2, config) {
9298
9423
  const tracingChannel2 = channel2.tracingChannel();
9299
9424
  const states = /* @__PURE__ */ new WeakMap();
9300
9425
  const channelName = channel2.channelName;
9426
+ const unbindCurrentSpanStore = bindCurrentSpanStoreToStart(
9427
+ tracingChannel2,
9428
+ states,
9429
+ config,
9430
+ channelName
9431
+ );
9301
9432
  const handlers = {
9302
9433
  start: (event) => {
9303
- states.set(
9434
+ ensureSpanStateForEvent(
9435
+ states,
9436
+ config,
9304
9437
  event,
9305
- startSpanForEvent(
9306
- config,
9307
- event,
9308
- channelName
9309
- )
9438
+ channelName
9310
9439
  );
9311
9440
  },
9312
9441
  asyncEnd: (event) => {
@@ -9326,7 +9455,7 @@ function traceAsyncChannel(channel2, config) {
9326
9455
  startTime,
9327
9456
  asyncEndEvent
9328
9457
  );
9329
- const metadata = _optionalChain([config, 'access', _113 => _113.extractMetadata, 'optionalCall', _114 => _114(
9458
+ const metadata = _optionalChain([config, 'access', _146 => _146.extractMetadata, 'optionalCall', _147 => _147(
9330
9459
  asyncEndEvent.result,
9331
9460
  asyncEndEvent
9332
9461
  )]);
@@ -9348,6 +9477,7 @@ function traceAsyncChannel(channel2, config) {
9348
9477
  };
9349
9478
  tracingChannel2.subscribe(handlers);
9350
9479
  return () => {
9480
+ _optionalChain([unbindCurrentSpanStore, 'optionalCall', _148 => _148()]);
9351
9481
  tracingChannel2.unsubscribe(handlers);
9352
9482
  };
9353
9483
  }
@@ -9355,15 +9485,19 @@ function traceStreamingChannel(channel2, config) {
9355
9485
  const tracingChannel2 = channel2.tracingChannel();
9356
9486
  const states = /* @__PURE__ */ new WeakMap();
9357
9487
  const channelName = channel2.channelName;
9488
+ const unbindCurrentSpanStore = bindCurrentSpanStoreToStart(
9489
+ tracingChannel2,
9490
+ states,
9491
+ config,
9492
+ channelName
9493
+ );
9358
9494
  const handlers = {
9359
9495
  start: (event) => {
9360
- states.set(
9496
+ ensureSpanStateForEvent(
9497
+ states,
9498
+ config,
9361
9499
  event,
9362
- startSpanForEvent(
9363
- config,
9364
- event,
9365
- channelName
9366
- )
9500
+ channelName
9367
9501
  );
9368
9502
  },
9369
9503
  asyncEnd: (event) => {
@@ -9437,7 +9571,7 @@ function traceStreamingChannel(channel2, config) {
9437
9571
  });
9438
9572
  return;
9439
9573
  }
9440
- if (_optionalChain([config, 'access', _115 => _115.patchResult, 'optionalCall', _116 => _116({
9574
+ if (_optionalChain([config, 'access', _149 => _149.patchResult, 'optionalCall', _150 => _150({
9441
9575
  channelName,
9442
9576
  endEvent: asyncEndEvent,
9443
9577
  result: asyncEndEvent.result,
@@ -9457,7 +9591,7 @@ function traceStreamingChannel(channel2, config) {
9457
9591
  startTime,
9458
9592
  asyncEndEvent
9459
9593
  );
9460
- const metadata = _optionalChain([config, 'access', _117 => _117.extractMetadata, 'optionalCall', _118 => _118(
9594
+ const metadata = _optionalChain([config, 'access', _151 => _151.extractMetadata, 'optionalCall', _152 => _152(
9461
9595
  asyncEndEvent.result,
9462
9596
  asyncEndEvent
9463
9597
  )]);
@@ -9479,6 +9613,7 @@ function traceStreamingChannel(channel2, config) {
9479
9613
  };
9480
9614
  tracingChannel2.subscribe(handlers);
9481
9615
  return () => {
9616
+ _optionalChain([unbindCurrentSpanStore, 'optionalCall', _153 => _153()]);
9482
9617
  tracingChannel2.unsubscribe(handlers);
9483
9618
  };
9484
9619
  }
@@ -9486,15 +9621,19 @@ function traceSyncStreamChannel(channel2, config) {
9486
9621
  const tracingChannel2 = channel2.tracingChannel();
9487
9622
  const states = /* @__PURE__ */ new WeakMap();
9488
9623
  const channelName = channel2.channelName;
9624
+ const unbindCurrentSpanStore = bindCurrentSpanStoreToStart(
9625
+ tracingChannel2,
9626
+ states,
9627
+ config,
9628
+ channelName
9629
+ );
9489
9630
  const handlers = {
9490
9631
  start: (event) => {
9491
- states.set(
9632
+ ensureSpanStateForEvent(
9633
+ states,
9634
+ config,
9492
9635
  event,
9493
- startSpanForEvent(
9494
- config,
9495
- event,
9496
- channelName
9497
- )
9636
+ channelName
9498
9637
  );
9499
9638
  },
9500
9639
  end: (event) => {
@@ -9504,7 +9643,7 @@ function traceSyncStreamChannel(channel2, config) {
9504
9643
  }
9505
9644
  const { span, startTime } = spanData;
9506
9645
  const endEvent = event;
9507
- if (_optionalChain([config, 'access', _119 => _119.patchResult, 'optionalCall', _120 => _120({
9646
+ if (_optionalChain([config, 'access', _154 => _154.patchResult, 'optionalCall', _155 => _155({
9508
9647
  channelName,
9509
9648
  endEvent,
9510
9649
  result: endEvent.result,
@@ -9583,6 +9722,7 @@ function traceSyncStreamChannel(channel2, config) {
9583
9722
  };
9584
9723
  tracingChannel2.subscribe(handlers);
9585
9724
  return () => {
9725
+ _optionalChain([unbindCurrentSpanStore, 'optionalCall', _156 => _156()]);
9586
9726
  tracingChannel2.unsubscribe(handlers);
9587
9727
  };
9588
9728
  }
@@ -9645,7 +9785,7 @@ function convertDataToBlob(data, mediaType) {
9645
9785
  } else if (typeof Buffer !== "undefined" && data instanceof Buffer) {
9646
9786
  return new Blob([data], { type: mediaType });
9647
9787
  }
9648
- } catch (e19) {
9788
+ } catch (e21) {
9649
9789
  return null;
9650
9790
  }
9651
9791
  return null;
@@ -9657,7 +9797,7 @@ function processInputAttachments(input) {
9657
9797
  let attachmentIndex = 0;
9658
9798
  const inferMediaTypeFromDataUrl = (value, fallback2) => {
9659
9799
  const mediaTypeMatch = value.match(/^data:([^;]+);/);
9660
- return _optionalChain([mediaTypeMatch, 'optionalAccess', _121 => _121[1]]) || fallback2;
9800
+ return _optionalChain([mediaTypeMatch, 'optionalAccess', _157 => _157[1]]) || fallback2;
9661
9801
  };
9662
9802
  const toAttachment = (value, mediaType, filename) => {
9663
9803
  const blob = convertDataToBlob(value, mediaType);
@@ -9907,11 +10047,11 @@ var OpenAIPlugin = class extends BasePlugin {
9907
10047
  };
9908
10048
  },
9909
10049
  extractOutput: (result) => {
9910
- return _optionalChain([result, 'optionalAccess', _122 => _122.choices]);
10050
+ return _optionalChain([result, 'optionalAccess', _158 => _158.choices]);
9911
10051
  },
9912
10052
  extractMetrics: (result, startTime, endEvent) => {
9913
10053
  const metrics = withCachedMetric(
9914
- parseMetricsFromUsage(_optionalChain([result, 'optionalAccess', _123 => _123.usage])),
10054
+ parseMetricsFromUsage(_optionalChain([result, 'optionalAccess', _159 => _159.usage])),
9915
10055
  result,
9916
10056
  endEvent
9917
10057
  );
@@ -9935,12 +10075,12 @@ var OpenAIPlugin = class extends BasePlugin {
9935
10075
  };
9936
10076
  },
9937
10077
  extractOutput: (result) => {
9938
- const embedding = _optionalChain([result, 'optionalAccess', _124 => _124.data, 'optionalAccess', _125 => _125[0], 'optionalAccess', _126 => _126.embedding]);
10078
+ const embedding = _optionalChain([result, 'optionalAccess', _160 => _160.data, 'optionalAccess', _161 => _161[0], 'optionalAccess', _162 => _162.embedding]);
9939
10079
  return Array.isArray(embedding) ? { embedding_length: embedding.length } : void 0;
9940
10080
  },
9941
10081
  extractMetrics: (result, _startTime, endEvent) => {
9942
10082
  return withCachedMetric(
9943
- parseMetricsFromUsage(_optionalChain([result, 'optionalAccess', _127 => _127.usage])),
10083
+ parseMetricsFromUsage(_optionalChain([result, 'optionalAccess', _163 => _163.usage])),
9944
10084
  result,
9945
10085
  endEvent
9946
10086
  );
@@ -9959,11 +10099,11 @@ var OpenAIPlugin = class extends BasePlugin {
9959
10099
  };
9960
10100
  },
9961
10101
  extractOutput: (result) => {
9962
- return _optionalChain([result, 'optionalAccess', _128 => _128.choices]);
10102
+ return _optionalChain([result, 'optionalAccess', _164 => _164.choices]);
9963
10103
  },
9964
10104
  extractMetrics: (result, startTime, endEvent) => {
9965
10105
  const metrics = withCachedMetric(
9966
- parseMetricsFromUsage(_optionalChain([result, 'optionalAccess', _129 => _129.usage])),
10106
+ parseMetricsFromUsage(_optionalChain([result, 'optionalAccess', _165 => _165.usage])),
9967
10107
  result,
9968
10108
  endEvent
9969
10109
  );
@@ -10000,11 +10140,11 @@ var OpenAIPlugin = class extends BasePlugin {
10000
10140
  };
10001
10141
  },
10002
10142
  extractOutput: (result) => {
10003
- return _optionalChain([result, 'optionalAccess', _130 => _130.results]);
10143
+ return _optionalChain([result, 'optionalAccess', _166 => _166.results]);
10004
10144
  },
10005
10145
  extractMetrics: (result, _startTime, endEvent) => {
10006
10146
  return withCachedMetric(
10007
- parseMetricsFromUsage(_optionalChain([result, 'optionalAccess', _131 => _131.usage])),
10147
+ parseMetricsFromUsage(_optionalChain([result, 'optionalAccess', _167 => _167.usage])),
10008
10148
  result,
10009
10149
  endEvent
10010
10150
  );
@@ -10023,7 +10163,7 @@ var OpenAIPlugin = class extends BasePlugin {
10023
10163
  };
10024
10164
  },
10025
10165
  extractOutput: (result) => {
10026
- return processImagesInOutput(_optionalChain([result, 'optionalAccess', _132 => _132.output]));
10166
+ return processImagesInOutput(_optionalChain([result, 'optionalAccess', _168 => _168.output]));
10027
10167
  },
10028
10168
  extractMetadata: (result) => {
10029
10169
  if (!result) {
@@ -10034,7 +10174,7 @@ var OpenAIPlugin = class extends BasePlugin {
10034
10174
  },
10035
10175
  extractMetrics: (result, startTime, endEvent) => {
10036
10176
  const metrics = withCachedMetric(
10037
- parseMetricsFromUsage(_optionalChain([result, 'optionalAccess', _133 => _133.usage])),
10177
+ parseMetricsFromUsage(_optionalChain([result, 'optionalAccess', _169 => _169.usage])),
10038
10178
  result,
10039
10179
  endEvent
10040
10180
  );
@@ -10087,7 +10227,7 @@ var OpenAIPlugin = class extends BasePlugin {
10087
10227
  };
10088
10228
  },
10089
10229
  extractOutput: (result) => {
10090
- return processImagesInOutput(_optionalChain([result, 'optionalAccess', _134 => _134.output]));
10230
+ return processImagesInOutput(_optionalChain([result, 'optionalAccess', _170 => _170.output]));
10091
10231
  },
10092
10232
  extractMetadata: (result) => {
10093
10233
  if (!result) {
@@ -10098,7 +10238,7 @@ var OpenAIPlugin = class extends BasePlugin {
10098
10238
  },
10099
10239
  extractMetrics: (result, startTime, endEvent) => {
10100
10240
  const metrics = withCachedMetric(
10101
- parseMetricsFromUsage(_optionalChain([result, 'optionalAccess', _135 => _135.usage])),
10241
+ parseMetricsFromUsage(_optionalChain([result, 'optionalAccess', _171 => _171.usage])),
10102
10242
  result,
10103
10243
  endEvent
10104
10244
  );
@@ -10194,7 +10334,7 @@ function aggregateChatCompletionChunks(chunks, streamResult, endEvent) {
10194
10334
  ...parseMetricsFromUsage(chunk.usage)
10195
10335
  };
10196
10336
  }
10197
- const delta = _optionalChain([chunk, 'access', _136 => _136.choices, 'optionalAccess', _137 => _137[0], 'optionalAccess', _138 => _138.delta]);
10337
+ const delta = _optionalChain([chunk, 'access', _172 => _172.choices, 'optionalAccess', _173 => _173[0], 'optionalAccess', _174 => _174.delta]);
10198
10338
  if (!delta) {
10199
10339
  continue;
10200
10340
  }
@@ -10252,14 +10392,14 @@ function aggregateResponseStreamEvents(chunks, _streamResult, endEvent) {
10252
10392
  continue;
10253
10393
  }
10254
10394
  const response = chunk.response;
10255
- if (_optionalChain([response, 'optionalAccess', _139 => _139.output]) !== void 0) {
10395
+ if (_optionalChain([response, 'optionalAccess', _175 => _175.output]) !== void 0) {
10256
10396
  output = processImagesInOutput(response.output);
10257
10397
  }
10258
10398
  const { usage: _usage, output: _output, ...rest } = response || {};
10259
10399
  if (Object.keys(rest).length > 0) {
10260
10400
  metadata = rest;
10261
10401
  }
10262
- metrics = parseMetricsFromUsage(_optionalChain([response, 'optionalAccess', _140 => _140.usage]));
10402
+ metrics = parseMetricsFromUsage(_optionalChain([response, 'optionalAccess', _176 => _176.usage]));
10263
10403
  }
10264
10404
  return {
10265
10405
  output,
@@ -10325,7 +10465,7 @@ var AnthropicPlugin = class extends BasePlugin {
10325
10465
  return message ? { role: message.role, content: message.content } : null;
10326
10466
  },
10327
10467
  extractMetrics: (message, startTime) => {
10328
- const metrics = parseMetricsFromUsage2(_optionalChain([message, 'optionalAccess', _141 => _141.usage]));
10468
+ const metrics = parseMetricsFromUsage2(_optionalChain([message, 'optionalAccess', _177 => _177.usage]));
10329
10469
  if (startTime) {
10330
10470
  metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
10331
10471
  }
@@ -10340,7 +10480,7 @@ var AnthropicPlugin = class extends BasePlugin {
10340
10480
  const metadata = {};
10341
10481
  const metas = ["stop_reason", "stop_sequence"];
10342
10482
  for (const m of metas) {
10343
- if (_optionalChain([message, 'optionalAccess', _142 => _142[m]]) !== void 0) {
10483
+ if (_optionalChain([message, 'optionalAccess', _178 => _178[m]]) !== void 0) {
10344
10484
  metadata[m] = message[m];
10345
10485
  }
10346
10486
  }
@@ -10354,7 +10494,7 @@ var AnthropicPlugin = class extends BasePlugin {
10354
10494
  this.unsubscribers.push(
10355
10495
  traceStreamingChannel(anthropicChannels.betaMessagesCreate, {
10356
10496
  ...anthropicConfig,
10357
- name: "anthropic.beta.messages.create"
10497
+ name: "anthropic.messages.create"
10358
10498
  })
10359
10499
  );
10360
10500
  }
@@ -10377,25 +10517,56 @@ function parseMetricsFromUsage2(usage) {
10377
10517
  return metrics;
10378
10518
  }
10379
10519
  function aggregateAnthropicStreamChunks(chunks) {
10380
- const deltas = [];
10520
+ const fallbackTextDeltas = [];
10521
+ const contentBlocks = {};
10522
+ const contentBlockDeltas = {};
10381
10523
  let metrics = {};
10382
10524
  let metadata = {};
10525
+ let role;
10383
10526
  for (const event of chunks) {
10384
- switch (_optionalChain([event, 'optionalAccess', _143 => _143.type])) {
10527
+ switch (_optionalChain([event, 'optionalAccess', _179 => _179.type])) {
10385
10528
  case "message_start":
10386
- if (_optionalChain([event, 'access', _144 => _144.message, 'optionalAccess', _145 => _145.usage])) {
10529
+ if (_optionalChain([event, 'access', _180 => _180.message, 'optionalAccess', _181 => _181.usage])) {
10387
10530
  const initialMetrics = parseMetricsFromUsage2(event.message.usage);
10388
10531
  metrics = { ...metrics, ...initialMetrics };
10389
10532
  }
10533
+ if (typeof _optionalChain([event, 'access', _182 => _182.message, 'optionalAccess', _183 => _183.role]) === "string") {
10534
+ role = event.message.role;
10535
+ }
10536
+ break;
10537
+ case "content_block_start":
10538
+ if (event.content_block) {
10539
+ contentBlocks[event.index] = event.content_block;
10540
+ contentBlockDeltas[event.index] = [];
10541
+ }
10390
10542
  break;
10391
10543
  case "content_block_delta":
10392
- if (_optionalChain([event, 'access', _146 => _146.delta, 'optionalAccess', _147 => _147.type]) === "text_delta") {
10544
+ if (_optionalChain([event, 'access', _184 => _184.delta, 'optionalAccess', _185 => _185.type]) === "text_delta") {
10393
10545
  const text = event.delta.text;
10394
10546
  if (text) {
10395
- deltas.push(text);
10547
+ if (contentBlocks[event.index] !== void 0 || contentBlockDeltas[event.index] !== void 0) {
10548
+ contentBlockDeltas[event.index] ??= [];
10549
+ contentBlockDeltas[event.index].push(text);
10550
+ } else {
10551
+ fallbackTextDeltas.push(text);
10552
+ }
10553
+ }
10554
+ } else if (_optionalChain([event, 'access', _186 => _186.delta, 'optionalAccess', _187 => _187.type]) === "input_json_delta") {
10555
+ const partialJson = event.delta.partial_json;
10556
+ if (partialJson) {
10557
+ contentBlockDeltas[event.index] ??= [];
10558
+ contentBlockDeltas[event.index].push(partialJson);
10396
10559
  }
10397
10560
  }
10398
10561
  break;
10562
+ case "content_block_stop":
10563
+ finalizeContentBlock(
10564
+ event.index,
10565
+ contentBlocks,
10566
+ contentBlockDeltas,
10567
+ fallbackTextDeltas
10568
+ );
10569
+ break;
10399
10570
  case "message_delta":
10400
10571
  if (event.usage) {
10401
10572
  const finalMetrics = parseMetricsFromUsage2(event.usage);
@@ -10407,7 +10578,21 @@ function aggregateAnthropicStreamChunks(chunks) {
10407
10578
  break;
10408
10579
  }
10409
10580
  }
10410
- const output = deltas.join("");
10581
+ const orderedContent = Object.entries(contentBlocks).map(([index, block]) => ({
10582
+ block,
10583
+ index: Number(index)
10584
+ })).filter(({ block }) => block !== void 0).sort((left, right) => left.index - right.index).map(({ block }) => block);
10585
+ let output = fallbackTextDeltas.join("");
10586
+ if (orderedContent.length > 0) {
10587
+ if (orderedContent.every(isTextContentBlock)) {
10588
+ output = orderedContent.map((block) => block.text).join("");
10589
+ } else {
10590
+ output = {
10591
+ ...role ? { role } : {},
10592
+ content: orderedContent
10593
+ };
10594
+ }
10595
+ }
10411
10596
  const finalized = finalizeAnthropicTokens(metrics);
10412
10597
  const filteredMetrics = Object.fromEntries(
10413
10598
  Object.entries(finalized).filter(
@@ -10420,6 +10605,49 @@ function aggregateAnthropicStreamChunks(chunks) {
10420
10605
  metadata
10421
10606
  };
10422
10607
  }
10608
+ function finalizeContentBlock(index, contentBlocks, contentBlockDeltas, fallbackTextDeltas) {
10609
+ const contentBlock = contentBlocks[index];
10610
+ if (!contentBlock) {
10611
+ return;
10612
+ }
10613
+ const text = _nullishCoalesce(_optionalChain([contentBlockDeltas, 'access', _188 => _188[index], 'optionalAccess', _189 => _189.join, 'call', _190 => _190("")]), () => ( ""));
10614
+ if (isToolUseContentBlock(contentBlock)) {
10615
+ if (!text) {
10616
+ return;
10617
+ }
10618
+ try {
10619
+ contentBlocks[index] = {
10620
+ ...contentBlock,
10621
+ input: JSON.parse(text)
10622
+ };
10623
+ } catch (e22) {
10624
+ fallbackTextDeltas.push(text);
10625
+ delete contentBlocks[index];
10626
+ }
10627
+ return;
10628
+ }
10629
+ if (isTextContentBlock(contentBlock)) {
10630
+ if (!text) {
10631
+ delete contentBlocks[index];
10632
+ return;
10633
+ }
10634
+ contentBlocks[index] = {
10635
+ ...contentBlock,
10636
+ text
10637
+ };
10638
+ return;
10639
+ }
10640
+ if (text) {
10641
+ fallbackTextDeltas.push(text);
10642
+ }
10643
+ delete contentBlocks[index];
10644
+ }
10645
+ function isTextContentBlock(contentBlock) {
10646
+ return contentBlock.type === "text";
10647
+ }
10648
+ function isToolUseContentBlock(contentBlock) {
10649
+ return contentBlock.type === "tool_use";
10650
+ }
10423
10651
  function isAnthropicBase64ContentBlock(input) {
10424
10652
  return (input.type === "image" || input.type === "document") && isObject(input.source) && input.source.type === "base64";
10425
10653
  }
@@ -10546,7 +10774,7 @@ function isZodSchema(value) {
10546
10774
  function serializeZodSchema(schema) {
10547
10775
  try {
10548
10776
  return zodToJsonSchema(schema);
10549
- } catch (e20) {
10777
+ } catch (e23) {
10550
10778
  return {
10551
10779
  type: "object",
10552
10780
  description: "Zod schema (conversion failed)"
@@ -10846,7 +11074,7 @@ function extractTopLevelAISDKMetrics(result, event, startTime) {
10846
11074
  return metrics;
10847
11075
  }
10848
11076
  function hasModelChildTracing(event) {
10849
- return _optionalChain([event, 'optionalAccess', _148 => _148.__braintrust_ai_sdk_model_wrapped]) === true;
11077
+ return _optionalChain([event, 'optionalAccess', _191 => _191.__braintrust_ai_sdk_model_wrapped]) === true;
10850
11078
  }
10851
11079
  function extractMetadataFromParams(params, self) {
10852
11080
  const metadata = {
@@ -10855,7 +11083,7 @@ function extractMetadataFromParams(params, self) {
10855
11083
  sdk_language: "typescript"
10856
11084
  }
10857
11085
  };
10858
- const agentModel = self && typeof self === "object" && "model" in self && self.model ? self.model : self && typeof self === "object" && "settings" in self && _optionalChain([self, 'access', _149 => _149.settings, 'optionalAccess', _150 => _150.model]) ? _optionalChain([self, 'access', _151 => _151.settings, 'optionalAccess', _152 => _152.model]) : void 0;
11086
+ const agentModel = self && typeof self === "object" && "model" in self && self.model ? self.model : self && typeof self === "object" && "settings" in self && _optionalChain([self, 'access', _192 => _192.settings, 'optionalAccess', _193 => _193.model]) ? _optionalChain([self, 'access', _194 => _194.settings, 'optionalAccess', _195 => _195.model]) : void 0;
10859
11087
  const { model, provider } = serializeModelWithProvider(
10860
11088
  _nullishCoalesce(params.model, () => ( agentModel))
10861
11089
  );
@@ -10957,9 +11185,9 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths) {
10957
11185
  case "raw":
10958
11186
  if (chunk.rawValue) {
10959
11187
  const rawVal = chunk.rawValue;
10960
- if (_optionalChain([rawVal, 'access', _153 => _153.delta, 'optionalAccess', _154 => _154.content])) {
11188
+ if (_optionalChain([rawVal, 'access', _196 => _196.delta, 'optionalAccess', _197 => _197.content])) {
10961
11189
  text += rawVal.delta.content;
10962
- } else if (_optionalChain([rawVal, 'access', _155 => _155.choices, 'optionalAccess', _156 => _156[0], 'optionalAccess', _157 => _157.delta, 'optionalAccess', _158 => _158.content])) {
11190
+ } else if (_optionalChain([rawVal, 'access', _198 => _198.choices, 'optionalAccess', _199 => _199[0], 'optionalAccess', _200 => _200.delta, 'optionalAccess', _201 => _201.content])) {
10963
11191
  text += rawVal.choices[0].delta.content;
10964
11192
  } else if (typeof rawVal.text === "string") {
10965
11193
  text += rawVal.text;
@@ -11096,14 +11324,14 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths) {
11096
11324
  return {
11097
11325
  cleanup: cleanup.length > 0 ? () => {
11098
11326
  while (cleanup.length > 0) {
11099
- _optionalChain([cleanup, 'access', _159 => _159.pop, 'call', _160 => _160(), 'optionalCall', _161 => _161()]);
11327
+ _optionalChain([cleanup, 'access', _202 => _202.pop, 'call', _203 => _203(), 'optionalCall', _204 => _204()]);
11100
11328
  }
11101
11329
  } : void 0,
11102
11330
  modelWrapped
11103
11331
  };
11104
11332
  }
11105
11333
  function finalizeAISDKChildTracing(event) {
11106
- const cleanup = _optionalChain([event, 'optionalAccess', _162 => _162.__braintrust_ai_sdk_cleanup]);
11334
+ const cleanup = _optionalChain([event, 'optionalAccess', _205 => _205.__braintrust_ai_sdk_cleanup]);
11107
11335
  if (event && typeof cleanup === "function") {
11108
11336
  cleanup();
11109
11337
  delete event.__braintrust_ai_sdk_cleanup;
@@ -11168,7 +11396,7 @@ async function processAISDKStreamingOutput(result, denyOutputPaths) {
11168
11396
  if ("text" in result && typeof result.text === "string") {
11169
11397
  outputRecord.text = result.text;
11170
11398
  }
11171
- } catch (e21) {
11399
+ } catch (e24) {
11172
11400
  }
11173
11401
  try {
11174
11402
  if ("object" in result) {
@@ -11177,7 +11405,7 @@ async function processAISDKStreamingOutput(result, denyOutputPaths) {
11177
11405
  outputRecord.object = resolvedObject;
11178
11406
  }
11179
11407
  }
11180
- } catch (e22) {
11408
+ } catch (e25) {
11181
11409
  }
11182
11410
  return outputRecord;
11183
11411
  }
@@ -11195,10 +11423,10 @@ function buildAISDKChildMetadata(model) {
11195
11423
  function buildResolvedMetadataPayload(result) {
11196
11424
  const gatewayInfo = extractGatewayRoutingInfo(result);
11197
11425
  const metadata = {};
11198
- if (_optionalChain([gatewayInfo, 'optionalAccess', _163 => _163.provider])) {
11426
+ if (_optionalChain([gatewayInfo, 'optionalAccess', _206 => _206.provider])) {
11199
11427
  metadata.provider = gatewayInfo.provider;
11200
11428
  }
11201
- if (_optionalChain([gatewayInfo, 'optionalAccess', _164 => _164.model])) {
11429
+ if (_optionalChain([gatewayInfo, 'optionalAccess', _207 => _207.model])) {
11202
11430
  metadata.model = gatewayInfo.model;
11203
11431
  }
11204
11432
  if (result.finishReason !== void 0) {
@@ -11233,7 +11461,7 @@ function processAISDKOutput(output, denyOutputPaths) {
11233
11461
  }
11234
11462
  function extractTokenMetrics(result) {
11235
11463
  const metrics = {};
11236
- let usage = _optionalChain([result, 'optionalAccess', _165 => _165.totalUsage]) || _optionalChain([result, 'optionalAccess', _166 => _166.usage]);
11464
+ let usage = _optionalChain([result, 'optionalAccess', _208 => _208.totalUsage]) || _optionalChain([result, 'optionalAccess', _209 => _209.usage]);
11237
11465
  if (!usage && result) {
11238
11466
  try {
11239
11467
  if ("totalUsage" in result && typeof result.totalUsage !== "function") {
@@ -11241,14 +11469,14 @@ function extractTokenMetrics(result) {
11241
11469
  } else if ("usage" in result && typeof result.usage !== "function") {
11242
11470
  usage = result.usage;
11243
11471
  }
11244
- } catch (e23) {
11472
+ } catch (e26) {
11245
11473
  }
11246
11474
  }
11247
11475
  if (!usage) {
11248
11476
  return metrics;
11249
11477
  }
11250
11478
  const promptTokens = firstNumber(
11251
- _optionalChain([usage, 'access', _167 => _167.inputTokens, 'optionalAccess', _168 => _168.total]),
11479
+ _optionalChain([usage, 'access', _210 => _210.inputTokens, 'optionalAccess', _211 => _211.total]),
11252
11480
  usage.inputTokens,
11253
11481
  usage.promptTokens,
11254
11482
  usage.prompt_tokens
@@ -11257,7 +11485,7 @@ function extractTokenMetrics(result) {
11257
11485
  metrics.prompt_tokens = promptTokens;
11258
11486
  }
11259
11487
  const completionTokens = firstNumber(
11260
- _optionalChain([usage, 'access', _169 => _169.outputTokens, 'optionalAccess', _170 => _170.total]),
11488
+ _optionalChain([usage, 'access', _212 => _212.outputTokens, 'optionalAccess', _213 => _213.total]),
11261
11489
  usage.outputTokens,
11262
11490
  usage.completionTokens,
11263
11491
  usage.completion_tokens
@@ -11324,7 +11552,7 @@ function extractGetterValues(obj) {
11324
11552
  if (obj && name in obj && isSerializableOutputValue(obj[name])) {
11325
11553
  getterValues[name] = obj[name];
11326
11554
  }
11327
- } catch (e24) {
11555
+ } catch (e27) {
11328
11556
  }
11329
11557
  }
11330
11558
  return getterValues;
@@ -11343,11 +11571,11 @@ function extractSerializableOutputFields(output) {
11343
11571
  ];
11344
11572
  for (const name of directFieldNames) {
11345
11573
  try {
11346
- const value = _optionalChain([output, 'optionalAccess', _171 => _171[name]]);
11574
+ const value = _optionalChain([output, 'optionalAccess', _214 => _214[name]]);
11347
11575
  if (isSerializableOutputValue(value)) {
11348
11576
  serialized[name] = value;
11349
11577
  }
11350
- } catch (e25) {
11578
+ } catch (e28) {
11351
11579
  }
11352
11580
  }
11353
11581
  return {
@@ -11371,8 +11599,8 @@ function isSerializableOutputValue(value) {
11371
11599
  return true;
11372
11600
  }
11373
11601
  function serializeModelWithProvider(model) {
11374
- const modelId = typeof model === "string" ? model : _optionalChain([model, 'optionalAccess', _172 => _172.modelId]);
11375
- const explicitProvider = typeof model === "object" ? _optionalChain([model, 'optionalAccess', _173 => _173.provider]) : void 0;
11602
+ const modelId = typeof model === "string" ? model : _optionalChain([model, 'optionalAccess', _215 => _215.modelId]);
11603
+ const explicitProvider = typeof model === "object" ? _optionalChain([model, 'optionalAccess', _216 => _216.provider]) : void 0;
11376
11604
  if (!modelId) {
11377
11605
  return { model: modelId, provider: explicitProvider };
11378
11606
  }
@@ -11396,8 +11624,8 @@ function parseGatewayModelString(modelString) {
11396
11624
  return { model: modelString };
11397
11625
  }
11398
11626
  function extractGatewayRoutingInfo(result) {
11399
- if (_optionalChain([result, 'optionalAccess', _174 => _174.steps]) && Array.isArray(result.steps) && result.steps.length > 0) {
11400
- const routing2 = _optionalChain([result, 'access', _175 => _175.steps, 'access', _176 => _176[0], 'optionalAccess', _177 => _177.providerMetadata, 'optionalAccess', _178 => _178.gateway, 'optionalAccess', _179 => _179.routing]);
11627
+ if (_optionalChain([result, 'optionalAccess', _217 => _217.steps]) && Array.isArray(result.steps) && result.steps.length > 0) {
11628
+ const routing2 = _optionalChain([result, 'access', _218 => _218.steps, 'access', _219 => _219[0], 'optionalAccess', _220 => _220.providerMetadata, 'optionalAccess', _221 => _221.gateway, 'optionalAccess', _222 => _222.routing]);
11401
11629
  if (routing2) {
11402
11630
  return {
11403
11631
  provider: routing2.resolvedProvider || routing2.finalProvider,
@@ -11405,7 +11633,7 @@ function extractGatewayRoutingInfo(result) {
11405
11633
  };
11406
11634
  }
11407
11635
  }
11408
- const routing = _optionalChain([result, 'optionalAccess', _180 => _180.providerMetadata, 'optionalAccess', _181 => _181.gateway, 'optionalAccess', _182 => _182.routing]);
11636
+ const routing = _optionalChain([result, 'optionalAccess', _223 => _223.providerMetadata, 'optionalAccess', _224 => _224.gateway, 'optionalAccess', _225 => _225.routing]);
11409
11637
  if (routing) {
11410
11638
  return {
11411
11639
  provider: routing.resolvedProvider || routing.finalProvider,
@@ -11415,12 +11643,12 @@ function extractGatewayRoutingInfo(result) {
11415
11643
  return null;
11416
11644
  }
11417
11645
  function extractCostFromResult(result) {
11418
- if (_optionalChain([result, 'optionalAccess', _183 => _183.steps]) && Array.isArray(result.steps) && result.steps.length > 0) {
11646
+ if (_optionalChain([result, 'optionalAccess', _226 => _226.steps]) && Array.isArray(result.steps) && result.steps.length > 0) {
11419
11647
  let totalCost = 0;
11420
11648
  let foundCost = false;
11421
11649
  for (const step of result.steps) {
11422
- const gateway2 = _optionalChain([step, 'optionalAccess', _184 => _184.providerMetadata, 'optionalAccess', _185 => _185.gateway]);
11423
- const stepCost = parseGatewayCost(_optionalChain([gateway2, 'optionalAccess', _186 => _186.cost])) || parseGatewayCost(_optionalChain([gateway2, 'optionalAccess', _187 => _187.marketCost]));
11650
+ const gateway2 = _optionalChain([step, 'optionalAccess', _227 => _227.providerMetadata, 'optionalAccess', _228 => _228.gateway]);
11651
+ const stepCost = parseGatewayCost(_optionalChain([gateway2, 'optionalAccess', _229 => _229.cost])) || parseGatewayCost(_optionalChain([gateway2, 'optionalAccess', _230 => _230.marketCost]));
11424
11652
  if (stepCost !== void 0 && stepCost > 0) {
11425
11653
  totalCost += stepCost;
11426
11654
  foundCost = true;
@@ -11430,8 +11658,8 @@ function extractCostFromResult(result) {
11430
11658
  return totalCost;
11431
11659
  }
11432
11660
  }
11433
- const gateway = _optionalChain([result, 'optionalAccess', _188 => _188.providerMetadata, 'optionalAccess', _189 => _189.gateway]);
11434
- const directCost = parseGatewayCost(_optionalChain([gateway, 'optionalAccess', _190 => _190.cost])) || parseGatewayCost(_optionalChain([gateway, 'optionalAccess', _191 => _191.marketCost]));
11661
+ const gateway = _optionalChain([result, 'optionalAccess', _231 => _231.providerMetadata, 'optionalAccess', _232 => _232.gateway]);
11662
+ const directCost = parseGatewayCost(_optionalChain([gateway, 'optionalAccess', _233 => _233.cost])) || parseGatewayCost(_optionalChain([gateway, 'optionalAccess', _234 => _234.marketCost]));
11435
11663
  if (directCost !== void 0 && directCost > 0) {
11436
11664
  return directCost;
11437
11665
  }
@@ -11542,12 +11770,15 @@ var claudeAgentSDKChannels = defineChannels(
11542
11770
  {
11543
11771
  query: channel({
11544
11772
  channelName: "query",
11545
- kind: "async"
11773
+ kind: "sync-stream"
11546
11774
  })
11547
11775
  }
11548
11776
  );
11549
11777
 
11550
11778
  // src/instrumentation/plugins/claude-agent-sdk-plugin.ts
11779
+ function isSubAgentToolName(toolName) {
11780
+ return toolName === "Agent" || toolName === "Task";
11781
+ }
11551
11782
  function filterSerializableOptions(options) {
11552
11783
  const allowedKeys = [
11553
11784
  "model",
@@ -11583,7 +11814,7 @@ function extractUsageFromMessage(message) {
11583
11814
  const metrics = {};
11584
11815
  let usage;
11585
11816
  if (message.type === "assistant") {
11586
- usage = _optionalChain([message, 'access', _192 => _192.message, 'optionalAccess', _193 => _193.usage]);
11817
+ usage = _optionalChain([message, 'access', _235 => _235.message, 'optionalAccess', _236 => _236.usage]);
11587
11818
  } else if (message.type === "result") {
11588
11819
  usage = message.usage;
11589
11820
  }
@@ -11601,55 +11832,409 @@ function extractUsageFromMessage(message) {
11601
11832
  const cacheReadTokens = getNumberProperty(usage, "cache_read_input_tokens") || 0;
11602
11833
  const cacheCreationTokens = getNumberProperty(usage, "cache_creation_input_tokens") || 0;
11603
11834
  if (cacheReadTokens > 0 || cacheCreationTokens > 0) {
11604
- const cacheTokens = extractAnthropicCacheTokens(
11605
- cacheReadTokens,
11606
- cacheCreationTokens
11835
+ Object.assign(
11836
+ metrics,
11837
+ extractAnthropicCacheTokens(cacheReadTokens, cacheCreationTokens)
11607
11838
  );
11608
- Object.assign(metrics, cacheTokens);
11609
11839
  }
11610
11840
  if (Object.keys(metrics).length > 0) {
11611
11841
  Object.assign(metrics, finalizeAnthropicTokens(metrics));
11612
11842
  }
11613
11843
  return metrics;
11614
11844
  }
11615
- function buildLLMInput(prompt, conversationHistory) {
11616
- const promptMessage = typeof prompt === "string" ? { content: prompt, role: "user" } : void 0;
11617
- const inputParts = [
11618
- ...promptMessage ? [promptMessage] : [],
11619
- ...conversationHistory
11620
- ];
11845
+ function buildLLMInput(prompt, conversationHistory, capturedPromptMessages) {
11846
+ const promptMessages = [];
11847
+ if (typeof prompt === "string") {
11848
+ promptMessages.push({ content: prompt, role: "user" });
11849
+ } else if (capturedPromptMessages && capturedPromptMessages.length > 0) {
11850
+ for (const msg of capturedPromptMessages) {
11851
+ const role = _optionalChain([msg, 'access', _237 => _237.message, 'optionalAccess', _238 => _238.role]);
11852
+ const content = _optionalChain([msg, 'access', _239 => _239.message, 'optionalAccess', _240 => _240.content]);
11853
+ if (role && content !== void 0) {
11854
+ promptMessages.push({ content, role });
11855
+ }
11856
+ }
11857
+ }
11858
+ const inputParts = [...promptMessages, ...conversationHistory];
11621
11859
  return inputParts.length > 0 ? inputParts : void 0;
11622
11860
  }
11623
- async function createLLMSpanForMessages(messages, prompt, conversationHistory, options, startTime, parentSpan) {
11624
- if (messages.length === 0) return void 0;
11861
+ function formatCapturedMessages(messages) {
11862
+ return messages.length > 0 ? messages : [];
11863
+ }
11864
+ async function createLLMSpanForMessages(messages, prompt, conversationHistory, options, startTime, capturedPromptMessages, parentSpan) {
11865
+ if (messages.length === 0) {
11866
+ return void 0;
11867
+ }
11625
11868
  const lastMessage = messages[messages.length - 1];
11626
- if (lastMessage.type !== "assistant" || !_optionalChain([lastMessage, 'access', _194 => _194.message, 'optionalAccess', _195 => _195.usage])) {
11869
+ if (lastMessage.type !== "assistant" || !_optionalChain([lastMessage, 'access', _241 => _241.message, 'optionalAccess', _242 => _242.usage])) {
11627
11870
  return void 0;
11628
11871
  }
11629
11872
  const model = lastMessage.message.model || options.model;
11630
11873
  const usage = extractUsageFromMessage(lastMessage);
11631
- const input = buildLLMInput(prompt, conversationHistory);
11874
+ const input = buildLLMInput(
11875
+ prompt,
11876
+ conversationHistory,
11877
+ capturedPromptMessages
11878
+ );
11632
11879
  const outputs = messages.map(
11633
- (m) => _optionalChain([m, 'access', _196 => _196.message, 'optionalAccess', _197 => _197.content]) && _optionalChain([m, 'access', _198 => _198.message, 'optionalAccess', _199 => _199.role]) ? { content: m.message.content, role: m.message.role } : void 0
11880
+ (m) => _optionalChain([m, 'access', _243 => _243.message, 'optionalAccess', _244 => _244.content]) && _optionalChain([m, 'access', _245 => _245.message, 'optionalAccess', _246 => _246.role]) ? { content: m.message.content, role: m.message.role } : void 0
11634
11881
  ).filter(
11635
11882
  (c) => c !== void 0
11636
11883
  );
11637
11884
  const span = startSpan({
11638
11885
  name: "anthropic.messages.create",
11886
+ parent: parentSpan,
11639
11887
  spanAttributes: {
11640
11888
  type: "llm" /* LLM */
11641
11889
  },
11642
- startTime,
11643
- parent: parentSpan
11890
+ startTime
11644
11891
  });
11645
11892
  span.log({
11646
11893
  input,
11647
- output: outputs,
11648
11894
  metadata: model ? { model } : void 0,
11649
- metrics: usage
11895
+ metrics: usage,
11896
+ output: outputs
11650
11897
  });
11651
11898
  await span.end();
11652
- return _optionalChain([lastMessage, 'access', _200 => _200.message, 'optionalAccess', _201 => _201.content]) && _optionalChain([lastMessage, 'access', _202 => _202.message, 'optionalAccess', _203 => _203.role]) ? { content: lastMessage.message.content, role: lastMessage.message.role } : void 0;
11899
+ return _optionalChain([lastMessage, 'access', _247 => _247.message, 'optionalAccess', _248 => _248.content]) && _optionalChain([lastMessage, 'access', _249 => _249.message, 'optionalAccess', _250 => _250.role]) ? { content: lastMessage.message.content, role: lastMessage.message.role } : void 0;
11900
+ }
11901
+ function getMcpServerMetadata(serverName, mcpServers) {
11902
+ if (!serverName || !mcpServers) {
11903
+ return {};
11904
+ }
11905
+ const serverConfig = mcpServers[serverName];
11906
+ if (!serverConfig) {
11907
+ return {};
11908
+ }
11909
+ const metadata = {};
11910
+ if (serverConfig.type) {
11911
+ metadata["mcp.type"] = serverConfig.type;
11912
+ } else if (typeof serverConfig === "object" && "transport" in serverConfig) {
11913
+ metadata["mcp.type"] = "sdk";
11914
+ }
11915
+ if (serverConfig.url) {
11916
+ metadata["mcp.url"] = serverConfig.url;
11917
+ }
11918
+ if (serverConfig.command) {
11919
+ metadata["mcp.command"] = serverConfig.command;
11920
+ if (serverConfig.args) {
11921
+ metadata["mcp.args"] = serverConfig.args.join(" ");
11922
+ }
11923
+ }
11924
+ return metadata;
11925
+ }
11926
+ function parseToolName(rawToolName) {
11927
+ const mcpMatch = rawToolName.match(/^mcp__([^_]+)__(.+)$/);
11928
+ if (mcpMatch) {
11929
+ const [, mcpServer, toolName] = mcpMatch;
11930
+ return {
11931
+ displayName: `tool: ${mcpServer}/${toolName}`,
11932
+ mcpServer,
11933
+ rawToolName,
11934
+ toolName
11935
+ };
11936
+ }
11937
+ return {
11938
+ displayName: `tool: ${rawToolName}`,
11939
+ rawToolName,
11940
+ toolName: rawToolName
11941
+ };
11942
+ }
11943
+ function createToolTracingHooks(resolveParentSpan, activeToolSpans, mcpServers, subAgentSpans, endedSubAgentSpans) {
11944
+ const preToolUse = async (input, toolUseID) => {
11945
+ if (input.hook_event_name !== "PreToolUse" || !toolUseID) {
11946
+ return {};
11947
+ }
11948
+ if (isSubAgentToolName(input.tool_name)) {
11949
+ return {};
11950
+ }
11951
+ const parsed = parseToolName(input.tool_name);
11952
+ const toolSpan = startSpan({
11953
+ event: {
11954
+ input: input.tool_input,
11955
+ metadata: {
11956
+ "claude_agent_sdk.cwd": input.cwd,
11957
+ "claude_agent_sdk.raw_tool_name": parsed.rawToolName,
11958
+ "claude_agent_sdk.session_id": input.session_id,
11959
+ "gen_ai.tool.call.id": toolUseID,
11960
+ "gen_ai.tool.name": parsed.toolName,
11961
+ ...parsed.mcpServer && { "mcp.server": parsed.mcpServer },
11962
+ ...getMcpServerMetadata(parsed.mcpServer, mcpServers)
11963
+ }
11964
+ },
11965
+ name: parsed.displayName,
11966
+ parent: await resolveParentSpan(toolUseID),
11967
+ spanAttributes: { type: "tool" /* TOOL */ }
11968
+ });
11969
+ activeToolSpans.set(toolUseID, toolSpan);
11970
+ return {};
11971
+ };
11972
+ const postToolUse = async (input, toolUseID) => {
11973
+ if (input.hook_event_name !== "PostToolUse" || !toolUseID) {
11974
+ return {};
11975
+ }
11976
+ const subAgentSpan = subAgentSpans.get(toolUseID);
11977
+ if (subAgentSpan) {
11978
+ try {
11979
+ const response = input.tool_response;
11980
+ const metadata = {};
11981
+ if (_optionalChain([response, 'optionalAccess', _251 => _251.status])) {
11982
+ metadata["claude_agent_sdk.status"] = response.status;
11983
+ }
11984
+ if (_optionalChain([response, 'optionalAccess', _252 => _252.totalDurationMs])) {
11985
+ metadata["claude_agent_sdk.duration_ms"] = response.totalDurationMs;
11986
+ }
11987
+ if (_optionalChain([response, 'optionalAccess', _253 => _253.totalToolUseCount]) !== void 0) {
11988
+ metadata["claude_agent_sdk.tool_use_count"] = response.totalToolUseCount;
11989
+ }
11990
+ subAgentSpan.log({
11991
+ metadata,
11992
+ output: _optionalChain([response, 'optionalAccess', _254 => _254.content])
11993
+ });
11994
+ } finally {
11995
+ subAgentSpan.end();
11996
+ endedSubAgentSpans.add(toolUseID);
11997
+ }
11998
+ return {};
11999
+ }
12000
+ const toolSpan = activeToolSpans.get(toolUseID);
12001
+ if (!toolSpan) {
12002
+ return {};
12003
+ }
12004
+ try {
12005
+ toolSpan.log({ output: input.tool_response });
12006
+ } finally {
12007
+ toolSpan.end();
12008
+ activeToolSpans.delete(toolUseID);
12009
+ }
12010
+ return {};
12011
+ };
12012
+ const postToolUseFailure = async (input, toolUseID) => {
12013
+ if (input.hook_event_name !== "PostToolUseFailure" || !toolUseID) {
12014
+ return {};
12015
+ }
12016
+ const subAgentSpan = subAgentSpans.get(toolUseID);
12017
+ if (subAgentSpan) {
12018
+ try {
12019
+ subAgentSpan.log({ error: input.error });
12020
+ } finally {
12021
+ subAgentSpan.end();
12022
+ endedSubAgentSpans.add(toolUseID);
12023
+ }
12024
+ return {};
12025
+ }
12026
+ const toolSpan = activeToolSpans.get(toolUseID);
12027
+ if (!toolSpan) {
12028
+ return {};
12029
+ }
12030
+ const parsed = parseToolName(input.tool_name);
12031
+ try {
12032
+ toolSpan.log({
12033
+ error: input.error,
12034
+ metadata: {
12035
+ "claude_agent_sdk.is_interrupt": input.is_interrupt,
12036
+ "claude_agent_sdk.session_id": input.session_id,
12037
+ "gen_ai.tool.call.id": toolUseID,
12038
+ "gen_ai.tool.name": parsed.toolName,
12039
+ ...parsed.mcpServer && { "mcp.server": parsed.mcpServer }
12040
+ }
12041
+ });
12042
+ } finally {
12043
+ toolSpan.end();
12044
+ activeToolSpans.delete(toolUseID);
12045
+ }
12046
+ return {};
12047
+ };
12048
+ return { postToolUse, postToolUseFailure, preToolUse };
12049
+ }
12050
+ function injectTracingHooks(options, resolveParentSpan, activeToolSpans, subAgentSpans, endedSubAgentSpans) {
12051
+ const { preToolUse, postToolUse, postToolUseFailure } = createToolTracingHooks(
12052
+ resolveParentSpan,
12053
+ activeToolSpans,
12054
+ options.mcpServers,
12055
+ subAgentSpans,
12056
+ endedSubAgentSpans
12057
+ );
12058
+ const existingHooks = _nullishCoalesce(options.hooks, () => ( {}));
12059
+ return {
12060
+ ...options,
12061
+ hooks: {
12062
+ ...existingHooks,
12063
+ PostToolUse: [
12064
+ ..._nullishCoalesce(existingHooks.PostToolUse, () => ( [])),
12065
+ { hooks: [postToolUse] }
12066
+ ],
12067
+ PostToolUseFailure: [
12068
+ ..._nullishCoalesce(existingHooks.PostToolUseFailure, () => ( [])),
12069
+ {
12070
+ hooks: [postToolUseFailure]
12071
+ }
12072
+ ],
12073
+ PreToolUse: [
12074
+ ..._nullishCoalesce(existingHooks.PreToolUse, () => ( [])),
12075
+ { hooks: [preToolUse] }
12076
+ ]
12077
+ }
12078
+ };
12079
+ }
12080
+ async function finalizeCurrentMessageGroup(state) {
12081
+ if (state.currentMessages.length === 0) {
12082
+ return;
12083
+ }
12084
+ const parentToolUseId = _nullishCoalesce(_optionalChain([state, 'access', _255 => _255.currentMessages, 'access', _256 => _256[0], 'optionalAccess', _257 => _257.parent_tool_use_id]), () => ( null));
12085
+ let parentSpan = await state.span.export();
12086
+ if (parentToolUseId) {
12087
+ const subAgentSpan = state.subAgentSpans.get(parentToolUseId);
12088
+ if (subAgentSpan) {
12089
+ parentSpan = await subAgentSpan.export();
12090
+ }
12091
+ }
12092
+ const finalMessage = await createLLMSpanForMessages(
12093
+ state.currentMessages,
12094
+ state.originalPrompt,
12095
+ state.finalResults,
12096
+ state.options,
12097
+ state.currentMessageStartTime,
12098
+ state.capturedPromptMessages,
12099
+ parentSpan
12100
+ );
12101
+ if (finalMessage) {
12102
+ state.finalResults.push(finalMessage);
12103
+ }
12104
+ const lastMessage = state.currentMessages[state.currentMessages.length - 1];
12105
+ if (_optionalChain([lastMessage, 'optionalAccess', _258 => _258.message, 'optionalAccess', _259 => _259.usage])) {
12106
+ state.accumulatedOutputTokens += getNumberProperty(lastMessage.message.usage, "output_tokens") || 0;
12107
+ }
12108
+ state.currentMessages.length = 0;
12109
+ }
12110
+ function maybeTrackToolUseContext(state, message) {
12111
+ if (message.type !== "assistant" || !Array.isArray(_optionalChain([message, 'access', _260 => _260.message, 'optionalAccess', _261 => _261.content]))) {
12112
+ return;
12113
+ }
12114
+ const parentToolUseId = _nullishCoalesce(message.parent_tool_use_id, () => ( null));
12115
+ for (const block of message.message.content) {
12116
+ if (typeof block !== "object" || block === null || !("type" in block) || block.type !== "tool_use" || !("id" in block) || typeof block.id !== "string") {
12117
+ continue;
12118
+ }
12119
+ state.toolUseToParent.set(block.id, parentToolUseId);
12120
+ if (block.name === "Task" && typeof block.input === "object" && block.input !== null && "subagent_type" in block.input && typeof block.input.subagent_type === "string") {
12121
+ state.pendingSubAgentNames.set(block.id, block.input.subagent_type);
12122
+ }
12123
+ }
12124
+ }
12125
+ async function maybeStartSubAgentSpan(state, message) {
12126
+ if (!("parent_tool_use_id" in message)) {
12127
+ return;
12128
+ }
12129
+ const parentToolUseId = message.parent_tool_use_id;
12130
+ if (!parentToolUseId) {
12131
+ return;
12132
+ }
12133
+ await ensureSubAgentSpan(
12134
+ state.pendingSubAgentNames,
12135
+ state.span,
12136
+ state.subAgentSpans,
12137
+ parentToolUseId
12138
+ );
12139
+ }
12140
+ async function ensureSubAgentSpan(pendingSubAgentNames, rootSpan, subAgentSpans, parentToolUseId) {
12141
+ const existingSpan = subAgentSpans.get(parentToolUseId);
12142
+ if (existingSpan) {
12143
+ return existingSpan;
12144
+ }
12145
+ const agentName = pendingSubAgentNames.get(parentToolUseId);
12146
+ const spanName = agentName ? `Agent: ${agentName}` : "Agent: sub-agent";
12147
+ const subAgentSpan = startSpan({
12148
+ event: {
12149
+ metadata: {
12150
+ ...agentName && { "claude_agent_sdk.agent_type": agentName }
12151
+ }
12152
+ },
12153
+ name: spanName,
12154
+ parent: await rootSpan.export(),
12155
+ spanAttributes: { type: "task" /* TASK */ }
12156
+ });
12157
+ subAgentSpans.set(parentToolUseId, subAgentSpan);
12158
+ return subAgentSpan;
12159
+ }
12160
+ async function handleStreamMessage(state, message) {
12161
+ maybeTrackToolUseContext(state, message);
12162
+ await maybeStartSubAgentSpan(state, message);
12163
+ const messageId = _optionalChain([message, 'access', _262 => _262.message, 'optionalAccess', _263 => _263.id]);
12164
+ if (messageId && messageId !== state.currentMessageId) {
12165
+ await finalizeCurrentMessageGroup(state);
12166
+ state.currentMessageId = messageId;
12167
+ state.currentMessageStartTime = getCurrentUnixTimestamp();
12168
+ }
12169
+ if (message.type === "assistant" && _optionalChain([message, 'access', _264 => _264.message, 'optionalAccess', _265 => _265.usage])) {
12170
+ state.currentMessages.push(message);
12171
+ }
12172
+ if (message.type !== "result" || !message.usage) {
12173
+ return;
12174
+ }
12175
+ const finalUsageMetrics = extractUsageFromMessage(message);
12176
+ if (state.currentMessages.length > 0 && finalUsageMetrics.completion_tokens !== void 0) {
12177
+ const lastMessage = state.currentMessages[state.currentMessages.length - 1];
12178
+ if (_optionalChain([lastMessage, 'optionalAccess', _266 => _266.message, 'optionalAccess', _267 => _267.usage])) {
12179
+ const adjustedTokens = finalUsageMetrics.completion_tokens - state.accumulatedOutputTokens;
12180
+ if (adjustedTokens >= 0) {
12181
+ lastMessage.message.usage.output_tokens = adjustedTokens;
12182
+ }
12183
+ const resultUsage = message.usage;
12184
+ if (resultUsage && typeof resultUsage === "object") {
12185
+ const cacheReadTokens = getNumberProperty(
12186
+ resultUsage,
12187
+ "cache_read_input_tokens"
12188
+ );
12189
+ if (cacheReadTokens !== void 0) {
12190
+ lastMessage.message.usage.cache_read_input_tokens = cacheReadTokens;
12191
+ }
12192
+ const cacheCreationTokens = getNumberProperty(
12193
+ resultUsage,
12194
+ "cache_creation_input_tokens"
12195
+ );
12196
+ if (cacheCreationTokens !== void 0) {
12197
+ lastMessage.message.usage.cache_creation_input_tokens = cacheCreationTokens;
12198
+ }
12199
+ }
12200
+ }
12201
+ }
12202
+ const metadata = {};
12203
+ if (message.num_turns !== void 0) {
12204
+ metadata.num_turns = message.num_turns;
12205
+ }
12206
+ if (message.session_id !== void 0) {
12207
+ metadata.session_id = message.session_id;
12208
+ }
12209
+ if (Object.keys(metadata).length > 0) {
12210
+ state.span.log({ metadata });
12211
+ }
12212
+ }
12213
+ async function finalizeQuerySpan(state) {
12214
+ try {
12215
+ await finalizeCurrentMessageGroup(state);
12216
+ state.span.log({
12217
+ output: state.finalResults.length > 0 ? state.finalResults[state.finalResults.length - 1] : void 0
12218
+ });
12219
+ if (state.capturedPromptMessages) {
12220
+ if (state.promptStarted()) {
12221
+ await state.promptDone;
12222
+ }
12223
+ if (state.capturedPromptMessages.length > 0) {
12224
+ state.span.log({
12225
+ input: formatCapturedMessages(state.capturedPromptMessages)
12226
+ });
12227
+ }
12228
+ }
12229
+ } finally {
12230
+ for (const [id, subAgentSpan] of state.subAgentSpans) {
12231
+ if (!state.endedSubAgentSpans.has(id)) {
12232
+ subAgentSpan.end();
12233
+ }
12234
+ }
12235
+ state.subAgentSpans.clear();
12236
+ state.span.end();
12237
+ }
11653
12238
  }
11654
12239
  var ClaudeAgentSDKPlugin = class extends BasePlugin {
11655
12240
  onEnable() {
@@ -11661,19 +12246,36 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
11661
12246
  }
11662
12247
  this.unsubscribers = [];
11663
12248
  }
11664
- /**
11665
- * Subscribe to the query channel for agent interactions.
11666
- * Handles streaming responses and traces both the top-level agent task
11667
- * and individual LLM calls.
11668
- */
11669
12249
  subscribeToQuery() {
11670
12250
  const channel2 = claudeAgentSDKChannels.query.tracingChannel();
11671
12251
  const spans = /* @__PURE__ */ new WeakMap();
11672
12252
  const handlers = {
11673
12253
  start: (event) => {
11674
- const params = event.arguments[0];
11675
- const prompt = _optionalChain([params, 'optionalAccess', _204 => _204.prompt]);
11676
- const options = _nullishCoalesce(_optionalChain([params, 'optionalAccess', _205 => _205.options]), () => ( {}));
12254
+ const params = _nullishCoalesce(event.arguments[0], () => ( {}));
12255
+ const originalPrompt = params.prompt;
12256
+ const options = _nullishCoalesce(params.options, () => ( {}));
12257
+ const promptIsAsyncIterable = isAsyncIterable(originalPrompt);
12258
+ let promptStarted = false;
12259
+ let capturedPromptMessages;
12260
+ let resolvePromptDone;
12261
+ const promptDone = new Promise((resolve) => {
12262
+ resolvePromptDone = resolve;
12263
+ });
12264
+ if (promptIsAsyncIterable) {
12265
+ capturedPromptMessages = [];
12266
+ const promptStream = originalPrompt;
12267
+ params.prompt = (async function* () {
12268
+ promptStarted = true;
12269
+ try {
12270
+ for await (const message of promptStream) {
12271
+ capturedPromptMessages.push(message);
12272
+ yield message;
12273
+ }
12274
+ } finally {
12275
+ _optionalChain([resolvePromptDone, 'optionalCall', _268 => _268()]);
12276
+ }
12277
+ })();
12278
+ }
11677
12279
  const span = startSpan({
11678
12280
  name: "Claude Agent",
11679
12281
  spanAttributes: {
@@ -11683,163 +12285,115 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
11683
12285
  const startTime = getCurrentUnixTimestamp();
11684
12286
  try {
11685
12287
  span.log({
11686
- input: typeof prompt === "string" ? prompt : {
11687
- type: "streaming",
11688
- description: "AsyncIterable<ClaudeAgentSDKMessage>"
11689
- },
12288
+ input: typeof originalPrompt === "string" ? originalPrompt : promptIsAsyncIterable ? void 0 : originalPrompt !== void 0 ? String(originalPrompt) : void 0,
11690
12289
  metadata: filterSerializableOptions(options)
11691
12290
  });
11692
12291
  } catch (error) {
11693
12292
  console.error("Error extracting input for Claude Agent SDK:", error);
11694
12293
  }
12294
+ const activeToolSpans = /* @__PURE__ */ new Map();
12295
+ const subAgentSpans = /* @__PURE__ */ new Map();
12296
+ const endedSubAgentSpans = /* @__PURE__ */ new Set();
12297
+ const toolUseToParent = /* @__PURE__ */ new Map();
12298
+ const pendingSubAgentNames = /* @__PURE__ */ new Map();
12299
+ const optionsWithHooks = injectTracingHooks(
12300
+ options,
12301
+ async (toolUseID) => {
12302
+ const parentToolUseId = toolUseToParent.get(toolUseID);
12303
+ if (parentToolUseId) {
12304
+ const subAgentSpan = await ensureSubAgentSpan(
12305
+ pendingSubAgentNames,
12306
+ span,
12307
+ subAgentSpans,
12308
+ parentToolUseId
12309
+ );
12310
+ return subAgentSpan.export();
12311
+ }
12312
+ return span.export();
12313
+ },
12314
+ activeToolSpans,
12315
+ subAgentSpans,
12316
+ endedSubAgentSpans
12317
+ );
12318
+ params.options = optionsWithHooks;
12319
+ event.arguments[0] = params;
11695
12320
  spans.set(event, {
11696
- span,
11697
- startTime,
11698
- conversationHistory: [],
11699
- currentMessages: [],
12321
+ accumulatedOutputTokens: 0,
12322
+ activeToolSpans,
12323
+ capturedPromptMessages,
11700
12324
  currentMessageId: void 0,
11701
12325
  currentMessageStartTime: startTime,
11702
- accumulatedOutputTokens: 0
12326
+ currentMessages: [],
12327
+ endedSubAgentSpans,
12328
+ finalResults: [],
12329
+ options: optionsWithHooks,
12330
+ originalPrompt,
12331
+ pendingSubAgentNames,
12332
+ processing: Promise.resolve(),
12333
+ promptDone,
12334
+ promptStarted: () => promptStarted,
12335
+ span,
12336
+ subAgentSpans,
12337
+ toolUseToParent
11703
12338
  });
11704
12339
  },
11705
- asyncEnd: (event) => {
11706
- const spanData = spans.get(event);
11707
- if (!spanData) {
12340
+ end: (event) => {
12341
+ const state = spans.get(event);
12342
+ if (!state) {
11708
12343
  return;
11709
12344
  }
11710
12345
  const eventResult = event.result;
11711
12346
  if (eventResult === void 0) {
11712
- spanData.span.end();
12347
+ state.span.end();
11713
12348
  spans.delete(event);
11714
12349
  return;
11715
12350
  }
11716
12351
  if (isAsyncIterable(eventResult)) {
11717
12352
  patchStreamIfNeeded(eventResult, {
11718
- onChunk: async (message) => {
11719
- const currentTime = getCurrentUnixTimestamp();
11720
- const params = event.arguments[0];
11721
- const prompt = _optionalChain([params, 'optionalAccess', _206 => _206.prompt]);
11722
- const options = _nullishCoalesce(_optionalChain([params, 'optionalAccess', _207 => _207.options]), () => ( {}));
11723
- const messageId = _optionalChain([message, 'access', _208 => _208.message, 'optionalAccess', _209 => _209.id]);
11724
- if (messageId && messageId !== spanData.currentMessageId) {
11725
- if (spanData.currentMessages.length > 0) {
11726
- const finalMessage = await createLLMSpanForMessages(
11727
- spanData.currentMessages,
11728
- prompt,
11729
- spanData.conversationHistory,
11730
- options,
11731
- spanData.currentMessageStartTime,
11732
- await spanData.span.export()
11733
- );
11734
- if (finalMessage) {
11735
- spanData.conversationHistory.push(finalMessage);
11736
- }
11737
- const lastMessage = spanData.currentMessages[spanData.currentMessages.length - 1];
11738
- if (_optionalChain([lastMessage, 'optionalAccess', _210 => _210.message, 'optionalAccess', _211 => _211.usage])) {
11739
- const outputTokens = getNumberProperty(
11740
- lastMessage.message.usage,
11741
- "output_tokens"
11742
- ) || 0;
11743
- spanData.accumulatedOutputTokens += outputTokens;
11744
- }
11745
- spanData.currentMessages = [];
11746
- }
11747
- spanData.currentMessageId = messageId;
11748
- spanData.currentMessageStartTime = currentTime;
11749
- }
11750
- if (message.type === "assistant" && _optionalChain([message, 'access', _212 => _212.message, 'optionalAccess', _213 => _213.usage])) {
11751
- spanData.currentMessages.push(message);
11752
- }
11753
- if (message.type === "result" && message.usage) {
11754
- const finalUsageMetrics = extractUsageFromMessage(message);
11755
- if (spanData.currentMessages.length > 0 && finalUsageMetrics.completion_tokens !== void 0) {
11756
- const lastMessage = spanData.currentMessages[spanData.currentMessages.length - 1];
11757
- if (_optionalChain([lastMessage, 'optionalAccess', _214 => _214.message, 'optionalAccess', _215 => _215.usage])) {
11758
- const adjustedTokens = finalUsageMetrics.completion_tokens - spanData.accumulatedOutputTokens;
11759
- if (adjustedTokens >= 0) {
11760
- lastMessage.message.usage.output_tokens = adjustedTokens;
11761
- }
11762
- }
11763
- }
11764
- const result_metadata = {};
11765
- if (message.num_turns !== void 0) {
11766
- result_metadata.num_turns = message.num_turns;
11767
- }
11768
- if (message.session_id !== void 0) {
11769
- result_metadata.session_id = message.session_id;
11770
- }
11771
- if (Object.keys(result_metadata).length > 0) {
11772
- spanData.span.log({
11773
- metadata: result_metadata
11774
- });
11775
- }
11776
- }
11777
- },
11778
- onComplete: async () => {
11779
- try {
11780
- const params = event.arguments[0];
11781
- const prompt = _optionalChain([params, 'optionalAccess', _216 => _216.prompt]);
11782
- const options = _nullishCoalesce(_optionalChain([params, 'optionalAccess', _217 => _217.options]), () => ( {}));
11783
- if (spanData.currentMessages.length > 0) {
11784
- const finalMessage = await createLLMSpanForMessages(
11785
- spanData.currentMessages,
11786
- prompt,
11787
- spanData.conversationHistory,
11788
- options,
11789
- spanData.currentMessageStartTime,
11790
- await spanData.span.export()
11791
- );
11792
- if (finalMessage) {
11793
- spanData.conversationHistory.push(finalMessage);
11794
- }
11795
- }
11796
- spanData.span.log({
11797
- output: spanData.conversationHistory.length > 0 ? spanData.conversationHistory[spanData.conversationHistory.length - 1] : void 0
11798
- });
11799
- } catch (error) {
12353
+ onChunk: (message) => {
12354
+ maybeTrackToolUseContext(state, message);
12355
+ state.processing = state.processing.then(() => handleStreamMessage(state, message)).catch((error) => {
11800
12356
  console.error(
11801
- "Error extracting output for Claude Agent SDK:",
12357
+ "Error processing Claude Agent SDK stream chunk:",
11802
12358
  error
11803
12359
  );
11804
- } finally {
11805
- spanData.span.end();
12360
+ });
12361
+ },
12362
+ onComplete: () => {
12363
+ void state.processing.then(() => finalizeQuerySpan(state)).finally(() => {
11806
12364
  spans.delete(event);
11807
- }
12365
+ });
11808
12366
  },
11809
12367
  onError: (error) => {
11810
- spanData.span.log({
11811
- error: error.message
12368
+ void state.processing.then(() => {
12369
+ state.span.log({
12370
+ error: error.message
12371
+ });
12372
+ }).then(() => finalizeQuerySpan(state)).finally(() => {
12373
+ spans.delete(event);
11812
12374
  });
11813
- spanData.span.end();
11814
- spans.delete(event);
11815
12375
  }
11816
12376
  });
11817
- } else {
11818
- try {
11819
- spanData.span.log({
11820
- output: eventResult
11821
- });
11822
- } catch (error) {
11823
- console.error(
11824
- "Error extracting output for Claude Agent SDK:",
11825
- error
11826
- );
11827
- } finally {
11828
- spanData.span.end();
11829
- spans.delete(event);
11830
- }
12377
+ return;
12378
+ }
12379
+ try {
12380
+ state.span.log({ output: eventResult });
12381
+ } catch (error) {
12382
+ console.error("Error extracting output for Claude Agent SDK:", error);
12383
+ } finally {
12384
+ state.span.end();
12385
+ spans.delete(event);
11831
12386
  }
11832
12387
  },
11833
12388
  error: (event) => {
11834
- const spanData = spans.get(event);
11835
- if (!spanData || !event.error) {
12389
+ const state = spans.get(event);
12390
+ if (!state || !event.error) {
11836
12391
  return;
11837
12392
  }
11838
- const { span } = spanData;
11839
- span.log({
12393
+ state.span.log({
11840
12394
  error: event.error.message
11841
12395
  });
11842
- span.end();
12396
+ state.span.end();
11843
12397
  spans.delete(event);
11844
12398
  }
11845
12399
  };
@@ -11863,6 +12417,18 @@ var googleGenAIChannels = defineChannels("@google/genai", {
11863
12417
  });
11864
12418
 
11865
12419
  // src/instrumentation/plugins/google-genai-plugin.ts
12420
+ var GOOGLE_GENAI_INTERNAL_CONTEXT = {
12421
+ caller_filename: "<node-internal>",
12422
+ caller_functionname: "<node-internal>",
12423
+ caller_lineno: 0
12424
+ };
12425
+ function createWrapperParityEvent(args) {
12426
+ return {
12427
+ context: GOOGLE_GENAI_INTERNAL_CONTEXT,
12428
+ input: args.input,
12429
+ metadata: args.metadata
12430
+ };
12431
+ }
11866
12432
  var GoogleGenAIPlugin = class extends BasePlugin {
11867
12433
  onEnable() {
11868
12434
  this.subscribeToGoogleGenAIChannels();
@@ -11871,277 +12437,1541 @@ var GoogleGenAIPlugin = class extends BasePlugin {
11871
12437
  this.unsubscribers = unsubscribeAll(this.unsubscribers);
11872
12438
  }
11873
12439
  subscribeToGoogleGenAIChannels() {
11874
- this.unsubscribers.push(
11875
- traceAsyncChannel(googleGenAIChannels.generateContent, {
11876
- name: "google-genai.generateContent",
11877
- type: "llm" /* LLM */,
11878
- extractInput: ([params]) => {
12440
+ this.subscribeToGenerateContentChannel();
12441
+ this.subscribeToGenerateContentStreamChannel();
12442
+ }
12443
+ subscribeToGenerateContentChannel() {
12444
+ const tracingChannel2 = googleGenAIChannels.generateContent.tracingChannel();
12445
+ const states = /* @__PURE__ */ new WeakMap();
12446
+ const unbindCurrentSpanStore = bindCurrentSpanStoreToStart2(
12447
+ tracingChannel2,
12448
+ states,
12449
+ (event) => {
12450
+ const params = event.arguments[0];
12451
+ const input = serializeInput(params);
12452
+ const metadata = extractMetadata(params);
12453
+ const span = startSpan({
12454
+ name: "generate_content",
12455
+ spanAttributes: {
12456
+ type: "llm" /* LLM */
12457
+ },
12458
+ event: createWrapperParityEvent({ input, metadata })
12459
+ });
12460
+ return {
12461
+ span,
12462
+ startTime: getCurrentUnixTimestamp()
12463
+ };
12464
+ }
12465
+ );
12466
+ const handlers = {
12467
+ start: (event) => {
12468
+ ensureSpanState(states, event, () => {
12469
+ const params = event.arguments[0];
11879
12470
  const input = serializeInput(params);
11880
12471
  const metadata = extractMetadata(params);
12472
+ const span = startSpan({
12473
+ name: "generate_content",
12474
+ spanAttributes: {
12475
+ type: "llm" /* LLM */
12476
+ },
12477
+ event: createWrapperParityEvent({ input, metadata })
12478
+ });
11881
12479
  return {
11882
- input,
11883
- metadata: { ...metadata, provider: "google-genai" }
12480
+ span,
12481
+ startTime: getCurrentUnixTimestamp()
11884
12482
  };
12483
+ });
12484
+ },
12485
+ asyncEnd: (event) => {
12486
+ const spanState = states.get(event);
12487
+ if (!spanState) {
12488
+ return;
12489
+ }
12490
+ try {
12491
+ spanState.span.log({
12492
+ metrics: cleanMetrics(
12493
+ extractGenerateContentMetrics(
12494
+ event.result,
12495
+ spanState.startTime
12496
+ )
12497
+ ),
12498
+ output: event.result
12499
+ });
12500
+ } finally {
12501
+ spanState.span.end();
12502
+ states.delete(event);
12503
+ }
12504
+ },
12505
+ error: (event) => {
12506
+ logErrorAndEndSpan(states, event);
12507
+ }
12508
+ };
12509
+ tracingChannel2.subscribe(handlers);
12510
+ this.unsubscribers.push(() => {
12511
+ _optionalChain([unbindCurrentSpanStore, 'optionalCall', _269 => _269()]);
12512
+ tracingChannel2.unsubscribe(handlers);
12513
+ });
12514
+ }
12515
+ subscribeToGenerateContentStreamChannel() {
12516
+ const tracingChannel2 = googleGenAIChannels.generateContentStream.tracingChannel();
12517
+ const handlers = {
12518
+ start: (event) => {
12519
+ const streamEvent = event;
12520
+ const params = event.arguments[0];
12521
+ streamEvent.googleGenAIInput = serializeInput(params);
12522
+ streamEvent.googleGenAIMetadata = extractMetadata(params);
12523
+ },
12524
+ asyncEnd: (event) => {
12525
+ const streamEvent = event;
12526
+ patchGoogleGenAIStreamingResult({
12527
+ input: streamEvent.googleGenAIInput,
12528
+ metadata: streamEvent.googleGenAIMetadata,
12529
+ result: streamEvent.result
12530
+ });
12531
+ },
12532
+ error: () => {
12533
+ }
12534
+ };
12535
+ tracingChannel2.subscribe(handlers);
12536
+ this.unsubscribers.push(() => {
12537
+ tracingChannel2.unsubscribe(handlers);
12538
+ });
12539
+ }
12540
+ };
12541
+ function ensureSpanState(states, event, create) {
12542
+ const existing = states.get(event);
12543
+ if (existing) {
12544
+ return existing;
12545
+ }
12546
+ const created = create();
12547
+ states.set(event, created);
12548
+ return created;
12549
+ }
12550
+ function bindCurrentSpanStoreToStart2(tracingChannel2, states, create) {
12551
+ const state = _internalGetGlobalState();
12552
+ const startChannel = tracingChannel2.start;
12553
+ const currentSpanStore = _optionalChain([state, 'optionalAccess', _270 => _270.contextManager]) ? state.contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
12554
+ if (!_optionalChain([startChannel, 'optionalAccess', _271 => _271.bindStore]) || !currentSpanStore) {
12555
+ return void 0;
12556
+ }
12557
+ startChannel.bindStore(
12558
+ currentSpanStore,
12559
+ (event) => ensureSpanState(
12560
+ states,
12561
+ event,
12562
+ () => create(event)
12563
+ ).span
12564
+ );
12565
+ return () => {
12566
+ _optionalChain([startChannel, 'access', _272 => _272.unbindStore, 'optionalCall', _273 => _273(currentSpanStore)]);
12567
+ };
12568
+ }
12569
+ function logErrorAndEndSpan(states, event) {
12570
+ const spanState = states.get(event);
12571
+ if (!spanState) {
12572
+ return;
12573
+ }
12574
+ spanState.span.log({
12575
+ error: event.error.message
12576
+ });
12577
+ spanState.span.end();
12578
+ states.delete(event);
12579
+ }
12580
+ function patchGoogleGenAIStreamingResult(args) {
12581
+ const { input, metadata, result } = args;
12582
+ if (!input || !metadata || !result || typeof result !== "object" || typeof result.next !== "function") {
12583
+ return false;
12584
+ }
12585
+ const chunks = [];
12586
+ let firstTokenTime = null;
12587
+ let finalized = false;
12588
+ let span = null;
12589
+ let startTime = null;
12590
+ const ensureSpan = () => {
12591
+ if (!span) {
12592
+ span = startSpan({
12593
+ name: "generate_content_stream",
12594
+ spanAttributes: {
12595
+ type: "llm" /* LLM */
11885
12596
  },
11886
- extractOutput: (result) => {
11887
- return result;
11888
- },
11889
- extractMetrics: (result, startTime) => {
11890
- return extractGenerateContentMetrics(result, startTime);
12597
+ event: {
12598
+ input,
12599
+ metadata
11891
12600
  }
11892
- })
11893
- );
11894
- this.unsubscribers.push(
11895
- traceStreamingChannel(googleGenAIChannels.generateContentStream, {
11896
- name: "google-genai.generateContentStream",
11897
- type: "llm" /* LLM */,
11898
- extractInput: ([params]) => {
11899
- const input = serializeInput(params);
11900
- const metadata = extractMetadata(params);
12601
+ });
12602
+ startTime = getCurrentUnixTimestamp();
12603
+ }
12604
+ return span;
12605
+ };
12606
+ const finalize = (options) => {
12607
+ if (finalized || !span) {
12608
+ return;
12609
+ }
12610
+ finalized = true;
12611
+ if (options.result) {
12612
+ const { end, ...metricsWithoutEnd } = options.result.metrics;
12613
+ span.log({
12614
+ metrics: cleanMetrics(metricsWithoutEnd),
12615
+ output: options.result.aggregated
12616
+ });
12617
+ span.end(typeof end === "number" ? { endTime: end } : void 0);
12618
+ return;
12619
+ }
12620
+ if (options.error !== void 0) {
12621
+ span.log({
12622
+ error: options.error instanceof Error ? options.error.message : String(options.error)
12623
+ });
12624
+ }
12625
+ span.end();
12626
+ };
12627
+ const patchIterator = (iterator) => {
12628
+ if (typeof iterator !== "object" || iterator === null || "__braintrustGoogleGenAIPatched" in iterator) {
12629
+ return iterator;
12630
+ }
12631
+ const iteratorRecord = iterator;
12632
+ const originalNext = typeof iteratorRecord.next === "function" ? iteratorRecord.next.bind(iterator) : void 0;
12633
+ const originalReturn = typeof iteratorRecord.return === "function" ? iteratorRecord.return.bind(iterator) : void 0;
12634
+ const originalThrow = typeof iteratorRecord.throw === "function" ? iteratorRecord.throw.bind(iterator) : void 0;
12635
+ const asyncIteratorMethod = iteratorRecord[Symbol.asyncIterator];
12636
+ const originalAsyncIterator = typeof asyncIteratorMethod === "function" ? asyncIteratorMethod.bind(iterator) : void 0;
12637
+ Object.defineProperty(iteratorRecord, "__braintrustGoogleGenAIPatched", {
12638
+ configurable: true,
12639
+ enumerable: false,
12640
+ value: true,
12641
+ writable: false
12642
+ });
12643
+ if (originalNext) {
12644
+ iteratorRecord.next = async (...nextArgs) => {
12645
+ ensureSpan();
12646
+ try {
12647
+ const nextResult = await originalNext(
12648
+ ...nextArgs
12649
+ );
12650
+ if (!nextResult.done && nextResult.value) {
12651
+ if (firstTokenTime === null) {
12652
+ firstTokenTime = getCurrentUnixTimestamp();
12653
+ }
12654
+ chunks.push(nextResult.value);
12655
+ }
12656
+ if (nextResult.done && startTime !== null) {
12657
+ finalize({
12658
+ result: aggregateGenerateContentChunks(
12659
+ chunks,
12660
+ startTime,
12661
+ firstTokenTime
12662
+ )
12663
+ });
12664
+ }
12665
+ return nextResult;
12666
+ } catch (error) {
12667
+ finalize({ error });
12668
+ throw error;
12669
+ }
12670
+ };
12671
+ }
12672
+ if (originalReturn) {
12673
+ iteratorRecord.return = async (...returnArgs) => {
12674
+ ensureSpan();
12675
+ try {
12676
+ return await originalReturn(
12677
+ ...returnArgs
12678
+ );
12679
+ } finally {
12680
+ if (startTime !== null) {
12681
+ finalize({
12682
+ result: chunks.length > 0 ? aggregateGenerateContentChunks(
12683
+ chunks,
12684
+ startTime,
12685
+ firstTokenTime
12686
+ ) : void 0
12687
+ });
12688
+ } else {
12689
+ finalize({});
12690
+ }
12691
+ }
12692
+ };
12693
+ }
12694
+ if (originalThrow) {
12695
+ iteratorRecord.throw = async (...throwArgs) => {
12696
+ ensureSpan();
12697
+ try {
12698
+ return await originalThrow(
12699
+ ...throwArgs
12700
+ );
12701
+ } catch (error) {
12702
+ finalize({ error });
12703
+ throw error;
12704
+ }
12705
+ };
12706
+ }
12707
+ iteratorRecord[Symbol.asyncIterator] = () => {
12708
+ const asyncIterator = originalAsyncIterator ? originalAsyncIterator() : iterator;
12709
+ return patchIterator(asyncIterator);
12710
+ };
12711
+ return iterator;
12712
+ };
12713
+ patchIterator(result);
12714
+ return true;
12715
+ }
12716
+ function serializeInput(params) {
12717
+ const input = {
12718
+ model: params.model,
12719
+ contents: serializeContents(params.contents)
12720
+ };
12721
+ if (params.config) {
12722
+ const config = tryToDict(params.config);
12723
+ if (config) {
12724
+ const filteredConfig = {};
12725
+ Object.keys(config).forEach((key) => {
12726
+ if (key !== "tools") {
12727
+ filteredConfig[key] = config[key];
12728
+ }
12729
+ });
12730
+ input.config = filteredConfig;
12731
+ }
12732
+ }
12733
+ return input;
12734
+ }
12735
+ function serializeContents(contents) {
12736
+ if (contents === null || contents === void 0) {
12737
+ return null;
12738
+ }
12739
+ if (Array.isArray(contents)) {
12740
+ return contents.map((item) => serializeContentItem(item));
12741
+ }
12742
+ return serializeContentItem(contents);
12743
+ }
12744
+ function serializeContentItem(item) {
12745
+ if (typeof item === "object" && item !== null) {
12746
+ if (item.parts && Array.isArray(item.parts)) {
12747
+ return {
12748
+ ...item,
12749
+ parts: item.parts.map((part) => serializePart(part))
12750
+ };
12751
+ }
12752
+ return item;
12753
+ }
12754
+ if (typeof item === "string") {
12755
+ return { text: item };
12756
+ }
12757
+ return item;
12758
+ }
12759
+ function serializePart(part) {
12760
+ if (!part || typeof part !== "object") {
12761
+ return part;
12762
+ }
12763
+ if (part.inlineData && part.inlineData.data) {
12764
+ const { data, mimeType } = part.inlineData;
12765
+ if (data instanceof Uint8Array || typeof Buffer !== "undefined" && Buffer.isBuffer(data) || typeof data === "string") {
12766
+ const extension = mimeType ? mimeType.split("/")[1] : "bin";
12767
+ const filename = `file.${extension}`;
12768
+ const buffer = typeof data === "string" ? typeof Buffer !== "undefined" ? Buffer.from(data, "base64") : new Uint8Array(
12769
+ atob(data).split("").map((c) => c.charCodeAt(0))
12770
+ ) : typeof Buffer !== "undefined" ? Buffer.from(data) : new Uint8Array(data);
12771
+ const arrayBuffer = buffer instanceof Uint8Array ? buffer.buffer.slice(
12772
+ buffer.byteOffset,
12773
+ buffer.byteOffset + buffer.byteLength
12774
+ ) : buffer;
12775
+ const attachment = new Attachment({
12776
+ data: arrayBuffer,
12777
+ filename,
12778
+ contentType: mimeType || "application/octet-stream"
12779
+ });
12780
+ return {
12781
+ image_url: { url: attachment }
12782
+ };
12783
+ }
12784
+ }
12785
+ return part;
12786
+ }
12787
+ function serializeTools(params) {
12788
+ if (!_optionalChain([params, 'access', _274 => _274.config, 'optionalAccess', _275 => _275.tools])) {
12789
+ return null;
12790
+ }
12791
+ try {
12792
+ return params.config.tools.map((tool) => {
12793
+ if (typeof tool === "object" && tool.functionDeclarations) {
12794
+ return tool;
12795
+ }
12796
+ return tool;
12797
+ });
12798
+ } catch (e29) {
12799
+ return null;
12800
+ }
12801
+ }
12802
+ function extractMetadata(params) {
12803
+ const metadata = {};
12804
+ if (params.model) {
12805
+ metadata.model = params.model;
12806
+ }
12807
+ if (params.config) {
12808
+ const config = tryToDict(params.config);
12809
+ if (config) {
12810
+ Object.keys(config).forEach((key) => {
12811
+ if (key !== "tools") {
12812
+ metadata[key] = config[key];
12813
+ }
12814
+ });
12815
+ }
12816
+ }
12817
+ const tools = serializeTools(params);
12818
+ if (tools) {
12819
+ metadata.tools = tools;
12820
+ }
12821
+ return metadata;
12822
+ }
12823
+ function extractGenerateContentMetrics(response, startTime) {
12824
+ const metrics = {};
12825
+ if (startTime !== void 0) {
12826
+ const end = getCurrentUnixTimestamp();
12827
+ metrics.start = startTime;
12828
+ metrics.end = end;
12829
+ metrics.duration = end - startTime;
12830
+ }
12831
+ if (_optionalChain([response, 'optionalAccess', _276 => _276.usageMetadata])) {
12832
+ populateUsageMetrics(metrics, response.usageMetadata);
12833
+ }
12834
+ return metrics;
12835
+ }
12836
+ function populateUsageMetrics(metrics, usage) {
12837
+ if (usage.promptTokenCount !== void 0) {
12838
+ metrics.prompt_tokens = usage.promptTokenCount;
12839
+ }
12840
+ if (usage.candidatesTokenCount !== void 0) {
12841
+ metrics.completion_tokens = usage.candidatesTokenCount;
12842
+ }
12843
+ if (usage.totalTokenCount !== void 0) {
12844
+ metrics.tokens = usage.totalTokenCount;
12845
+ }
12846
+ if (usage.cachedContentTokenCount !== void 0) {
12847
+ metrics.prompt_cached_tokens = usage.cachedContentTokenCount;
12848
+ }
12849
+ if (usage.thoughtsTokenCount !== void 0) {
12850
+ metrics.completion_reasoning_tokens = usage.thoughtsTokenCount;
12851
+ }
12852
+ }
12853
+ function aggregateGenerateContentChunks(chunks, startTime, firstTokenTime) {
12854
+ const end = getCurrentUnixTimestamp();
12855
+ const metrics = {
12856
+ start: startTime,
12857
+ end,
12858
+ duration: end - startTime
12859
+ };
12860
+ if (firstTokenTime !== null) {
12861
+ metrics.time_to_first_token = firstTokenTime - startTime;
12862
+ }
12863
+ if (chunks.length === 0) {
12864
+ return { aggregated: {}, metrics };
12865
+ }
12866
+ let text = "";
12867
+ let thoughtText = "";
12868
+ const otherParts = [];
12869
+ let usageMetadata = null;
12870
+ let lastResponse = null;
12871
+ for (const chunk of chunks) {
12872
+ lastResponse = chunk;
12873
+ if (chunk.usageMetadata) {
12874
+ usageMetadata = chunk.usageMetadata;
12875
+ }
12876
+ if (chunk.candidates && Array.isArray(chunk.candidates)) {
12877
+ for (const candidate of chunk.candidates) {
12878
+ if (_optionalChain([candidate, 'access', _277 => _277.content, 'optionalAccess', _278 => _278.parts])) {
12879
+ for (const part of candidate.content.parts) {
12880
+ if (part.text !== void 0) {
12881
+ if (part.thought) {
12882
+ thoughtText += part.text;
12883
+ } else {
12884
+ text += part.text;
12885
+ }
12886
+ } else if (part.functionCall) {
12887
+ otherParts.push({ functionCall: part.functionCall });
12888
+ } else if (part.codeExecutionResult) {
12889
+ otherParts.push({
12890
+ codeExecutionResult: part.codeExecutionResult
12891
+ });
12892
+ } else if (part.executableCode) {
12893
+ otherParts.push({ executableCode: part.executableCode });
12894
+ }
12895
+ }
12896
+ }
12897
+ }
12898
+ }
12899
+ }
12900
+ const aggregated = {};
12901
+ const parts = [];
12902
+ if (thoughtText) {
12903
+ parts.push({ text: thoughtText, thought: true });
12904
+ }
12905
+ if (text) {
12906
+ parts.push({ text });
12907
+ }
12908
+ parts.push(...otherParts);
12909
+ if (parts.length > 0 && _optionalChain([lastResponse, 'optionalAccess', _279 => _279.candidates])) {
12910
+ const candidates = [];
12911
+ for (const candidate of lastResponse.candidates) {
12912
+ const candidateDict = {
12913
+ content: {
12914
+ parts,
12915
+ role: "model"
12916
+ }
12917
+ };
12918
+ if (candidate.finishReason !== void 0) {
12919
+ candidateDict.finishReason = candidate.finishReason;
12920
+ }
12921
+ if (candidate.safetyRatings) {
12922
+ candidateDict.safetyRatings = candidate.safetyRatings;
12923
+ }
12924
+ candidates.push(candidateDict);
12925
+ }
12926
+ aggregated.candidates = candidates;
12927
+ }
12928
+ if (usageMetadata) {
12929
+ aggregated.usageMetadata = usageMetadata;
12930
+ populateUsageMetrics(metrics, usageMetadata);
12931
+ }
12932
+ if (text) {
12933
+ aggregated.text = text;
12934
+ }
12935
+ return { aggregated, metrics };
12936
+ }
12937
+ function cleanMetrics(metrics) {
12938
+ const cleaned = {};
12939
+ for (const [key, value] of Object.entries(metrics)) {
12940
+ if (value !== null && value !== void 0) {
12941
+ cleaned[key] = value;
12942
+ }
12943
+ }
12944
+ return cleaned;
12945
+ }
12946
+ function tryToDict(obj) {
12947
+ if (obj === null || obj === void 0) {
12948
+ return null;
12949
+ }
12950
+ if (typeof obj === "object") {
12951
+ if ("toJSON" in obj && // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
12952
+ typeof obj.toJSON === "function") {
12953
+ return obj.toJSON();
12954
+ }
12955
+ return obj;
12956
+ }
12957
+ return null;
12958
+ }
12959
+
12960
+ // src/instrumentation/plugins/openrouter-channels.ts
12961
+ var openRouterChannels = defineChannels("@openrouter/sdk", {
12962
+ chatSend: channel({
12963
+ channelName: "chat.send",
12964
+ kind: "async"
12965
+ }),
12966
+ embeddingsGenerate: channel({
12967
+ channelName: "embeddings.generate",
12968
+ kind: "async"
12969
+ }),
12970
+ betaResponsesSend: channel({
12971
+ channelName: "beta.responses.send",
12972
+ kind: "async"
12973
+ }),
12974
+ callModel: channel({
12975
+ channelName: "callModel",
12976
+ kind: "sync-stream"
12977
+ }),
12978
+ toolExecute: channel({
12979
+ channelName: "tool.execute",
12980
+ kind: "async"
12981
+ })
12982
+ });
12983
+
12984
+ // src/openrouter-utils.ts
12985
+ var TOKEN_NAME_MAP2 = {
12986
+ promptTokens: "prompt_tokens",
12987
+ inputTokens: "prompt_tokens",
12988
+ completionTokens: "completion_tokens",
12989
+ outputTokens: "completion_tokens",
12990
+ totalTokens: "tokens",
12991
+ prompt_tokens: "prompt_tokens",
12992
+ input_tokens: "prompt_tokens",
12993
+ completion_tokens: "completion_tokens",
12994
+ output_tokens: "completion_tokens",
12995
+ total_tokens: "tokens"
12996
+ };
12997
+ var TOKEN_DETAIL_PREFIX_MAP = {
12998
+ promptTokensDetails: "prompt",
12999
+ inputTokensDetails: "prompt",
13000
+ completionTokensDetails: "completion",
13001
+ outputTokensDetails: "completion",
13002
+ costDetails: "cost",
13003
+ prompt_tokens_details: "prompt",
13004
+ input_tokens_details: "prompt",
13005
+ completion_tokens_details: "completion",
13006
+ output_tokens_details: "completion",
13007
+ cost_details: "cost"
13008
+ };
13009
+ function camelToSnake(value) {
13010
+ return value.replace(/[A-Z]/g, (match) => `_${match.toLowerCase()}`);
13011
+ }
13012
+ function parseOpenRouterMetricsFromUsage(usage) {
13013
+ if (!isObject(usage)) {
13014
+ return {};
13015
+ }
13016
+ const metrics = {};
13017
+ for (const [name, value] of Object.entries(usage)) {
13018
+ if (typeof value === "number") {
13019
+ metrics[TOKEN_NAME_MAP2[name] || camelToSnake(name)] = value;
13020
+ continue;
13021
+ }
13022
+ if (!isObject(value)) {
13023
+ continue;
13024
+ }
13025
+ const prefix = TOKEN_DETAIL_PREFIX_MAP[name];
13026
+ if (!prefix) {
13027
+ continue;
13028
+ }
13029
+ for (const [nestedName, nestedValue] of Object.entries(value)) {
13030
+ if (typeof nestedValue !== "number") {
13031
+ continue;
13032
+ }
13033
+ metrics[`${prefix}_${camelToSnake(nestedName)}`] = nestedValue;
13034
+ }
13035
+ }
13036
+ return metrics;
13037
+ }
13038
+ function extractOpenRouterUsageMetadata(usage) {
13039
+ if (!isObject(usage)) {
13040
+ return void 0;
13041
+ }
13042
+ const metadata = {};
13043
+ if (typeof usage.isByok === "boolean") {
13044
+ metadata.is_byok = usage.isByok;
13045
+ } else if (typeof usage.is_byok === "boolean") {
13046
+ metadata.is_byok = usage.is_byok;
13047
+ }
13048
+ return Object.keys(metadata).length > 0 ? metadata : void 0;
13049
+ }
13050
+
13051
+ // src/openrouter-logging.ts
13052
+ var OMITTED_OPENROUTER_KEYS = /* @__PURE__ */ new Set([
13053
+ "execute",
13054
+ "render",
13055
+ "nextTurnParams",
13056
+ "requireApproval"
13057
+ ]);
13058
+ function parseOpenRouterModelString(model) {
13059
+ if (typeof model !== "string") {
13060
+ return { model };
13061
+ }
13062
+ const slashIndex = model.indexOf("/");
13063
+ if (slashIndex > 0 && slashIndex < model.length - 1) {
13064
+ return {
13065
+ provider: model.substring(0, slashIndex),
13066
+ model: model.substring(slashIndex + 1)
13067
+ };
13068
+ }
13069
+ return { model };
13070
+ }
13071
+ function isZodSchema2(value) {
13072
+ return value != null && typeof value === "object" && "_def" in value && typeof value._def === "object";
13073
+ }
13074
+ function serializeZodSchema2(schema) {
13075
+ try {
13076
+ return zodToJsonSchema(schema);
13077
+ } catch (e30) {
13078
+ return {
13079
+ type: "object",
13080
+ description: "Zod schema (conversion failed)"
13081
+ };
13082
+ }
13083
+ }
13084
+ function serializeOpenRouterTool(tool) {
13085
+ if (!isObject(tool)) {
13086
+ return tool;
13087
+ }
13088
+ const serialized = {};
13089
+ for (const [key, value] of Object.entries(tool)) {
13090
+ if (OMITTED_OPENROUTER_KEYS.has(key)) {
13091
+ continue;
13092
+ }
13093
+ if (key === "function" && isObject(value)) {
13094
+ serialized.function = sanitizeOpenRouterLoggedValue(value);
13095
+ continue;
13096
+ }
13097
+ serialized[key] = sanitizeOpenRouterLoggedValue(value);
13098
+ }
13099
+ return serialized;
13100
+ }
13101
+ function serializeOpenRouterToolsForLogging(tools) {
13102
+ if (!Array.isArray(tools)) {
13103
+ return void 0;
13104
+ }
13105
+ return tools.map((tool) => serializeOpenRouterTool(tool));
13106
+ }
13107
+ function sanitizeOpenRouterLoggedValue(value) {
13108
+ if (isZodSchema2(value)) {
13109
+ return serializeZodSchema2(value);
13110
+ }
13111
+ if (typeof value === "function") {
13112
+ return "[Function]";
13113
+ }
13114
+ if (Array.isArray(value)) {
13115
+ return value.map((entry) => sanitizeOpenRouterLoggedValue(entry));
13116
+ }
13117
+ if (!isObject(value)) {
13118
+ return value;
13119
+ }
13120
+ const sanitized = {};
13121
+ for (const [key, entry] of Object.entries(value)) {
13122
+ if (OMITTED_OPENROUTER_KEYS.has(key)) {
13123
+ continue;
13124
+ }
13125
+ if (key === "tools" && Array.isArray(entry)) {
13126
+ sanitized.tools = serializeOpenRouterToolsForLogging(entry);
13127
+ continue;
13128
+ }
13129
+ sanitized[key] = sanitizeOpenRouterLoggedValue(entry);
13130
+ }
13131
+ return sanitized;
13132
+ }
13133
+ function buildOpenRouterMetadata(metadata, httpReferer, xTitle) {
13134
+ const sanitized = sanitizeOpenRouterLoggedValue(metadata);
13135
+ const metadataRecord = isObject(sanitized) ? sanitized : {};
13136
+ const { model, provider: providerRouting, ...rest } = metadataRecord;
13137
+ const normalizedModel = parseOpenRouterModelString(model);
13138
+ return {
13139
+ ...rest,
13140
+ ...normalizedModel.model !== void 0 ? { model: normalizedModel.model } : {},
13141
+ ...providerRouting !== void 0 ? { providerRouting } : {},
13142
+ ...httpReferer !== void 0 ? { httpReferer } : {},
13143
+ ...xTitle !== void 0 ? { xTitle } : {},
13144
+ provider: normalizedModel.provider || "openrouter"
13145
+ };
13146
+ }
13147
+ function buildOpenRouterEmbeddingMetadata(metadata, httpReferer, xTitle) {
13148
+ const normalized = buildOpenRouterMetadata(metadata, httpReferer, xTitle);
13149
+ return typeof normalized.model === "string" ? {
13150
+ ...normalized,
13151
+ embedding_model: normalized.model
13152
+ } : normalized;
13153
+ }
13154
+ function extractOpenRouterCallModelInput(request) {
13155
+ return isObject(request) && "input" in request ? sanitizeOpenRouterLoggedValue(request.input) : void 0;
13156
+ }
13157
+ function extractOpenRouterCallModelMetadata(request) {
13158
+ if (!isObject(request)) {
13159
+ return { provider: "openrouter" };
13160
+ }
13161
+ const { input: _input, ...metadata } = request;
13162
+ return buildOpenRouterMetadata(metadata, void 0, void 0);
13163
+ }
13164
+ function extractOpenRouterResponseMetadata(result) {
13165
+ if (!isObject(result)) {
13166
+ return void 0;
13167
+ }
13168
+ const { output: _output, data: _data, usage, ...metadata } = result;
13169
+ const sanitized = sanitizeOpenRouterLoggedValue(metadata);
13170
+ const metadataRecord = isObject(sanitized) ? sanitized : {};
13171
+ const { model, provider, ...rest } = metadataRecord;
13172
+ const normalizedModel = parseOpenRouterModelString(model);
13173
+ const normalizedProvider = (typeof provider === "string" ? provider : void 0) || normalizedModel.provider;
13174
+ const usageMetadata = extractOpenRouterUsageMetadata(usage);
13175
+ const combined = {
13176
+ ...rest,
13177
+ ...normalizedModel.model !== void 0 ? { model: normalizedModel.model } : {},
13178
+ ...usageMetadata || {},
13179
+ ...normalizedProvider !== void 0 ? { provider: normalizedProvider } : {}
13180
+ };
13181
+ return Object.keys(combined).length > 0 ? combined : void 0;
13182
+ }
13183
+ function extractOpenRouterResponseOutput(response, fallbackOutput) {
13184
+ if (isObject(response) && "output" in response && response.output !== void 0) {
13185
+ return sanitizeOpenRouterLoggedValue(response.output);
13186
+ }
13187
+ if (fallbackOutput !== void 0) {
13188
+ return sanitizeOpenRouterLoggedValue(fallbackOutput);
13189
+ }
13190
+ return void 0;
13191
+ }
13192
+
13193
+ // src/openrouter-tool-wrapping.ts
13194
+ var OPENROUTER_WRAPPED_TOOL = Symbol("braintrust.openrouter.wrappedTool");
13195
+ var OPENROUTER_WRAPPED_CALL_MODEL_RESULT = Symbol(
13196
+ "braintrust.openrouter.wrappedCallModelResult"
13197
+ );
13198
+ var OPENROUTER_CALL_MODEL_STREAM_METHODS = [
13199
+ "getFullResponsesStream",
13200
+ "getItemsStream",
13201
+ "getNewMessagesStream",
13202
+ "getReasoningStream",
13203
+ "getTextStream",
13204
+ "getToolCallsStream",
13205
+ "getToolStream"
13206
+ ];
13207
+ var OPENROUTER_CALL_MODEL_CONTEXT_METHODS = [
13208
+ "cancel",
13209
+ "getPendingToolCalls",
13210
+ "getState",
13211
+ "getToolCalls",
13212
+ "requiresApproval"
13213
+ ];
13214
+ function patchOpenRouterCallModelRequestTools(request) {
13215
+ if (!Array.isArray(request.tools) || request.tools.length === 0) {
13216
+ return void 0;
13217
+ }
13218
+ const originalTools = request.tools;
13219
+ const wrappedTools = originalTools.map((tool) => wrapOpenRouterTool(tool));
13220
+ const didPatch = wrappedTools.some(
13221
+ (tool, index) => tool !== originalTools[index]
13222
+ );
13223
+ if (!didPatch) {
13224
+ return void 0;
13225
+ }
13226
+ request.tools = wrappedTools;
13227
+ return () => {
13228
+ request.tools = originalTools;
13229
+ };
13230
+ }
13231
+ function patchOpenRouterCallModelResult(span, result, request) {
13232
+ if (!isObject(result) || isWrappedCallModelResult(result)) {
13233
+ return false;
13234
+ }
13235
+ const resultLike = result;
13236
+ const hasInstrumentableMethod = typeof resultLike.getResponse === "function" || typeof resultLike.getText === "function" || OPENROUTER_CALL_MODEL_STREAM_METHODS.some(
13237
+ (methodName) => typeof resultLike[methodName] === "function"
13238
+ );
13239
+ if (!hasInstrumentableMethod) {
13240
+ return false;
13241
+ }
13242
+ Object.defineProperty(resultLike, OPENROUTER_WRAPPED_CALL_MODEL_RESULT, {
13243
+ value: true,
13244
+ enumerable: false,
13245
+ configurable: false
13246
+ });
13247
+ const originalGetResponse = typeof resultLike.getResponse === "function" ? resultLike.getResponse.bind(resultLike) : void 0;
13248
+ const originalGetInitialResponse = typeof resultLike.getInitialResponse === "function" ? resultLike.getInitialResponse.bind(resultLike) : void 0;
13249
+ const originalMakeFollowupRequest = typeof resultLike.makeFollowupRequest === "function" ? resultLike.makeFollowupRequest.bind(resultLike) : void 0;
13250
+ let ended = false;
13251
+ let tracedTurnCount = 0;
13252
+ const endSpanWithResult = async (response, fallbackOutput) => {
13253
+ if (ended) {
13254
+ return;
13255
+ }
13256
+ ended = true;
13257
+ const finalResponse = getFinalOpenRouterCallModelResponse(
13258
+ resultLike,
13259
+ response
13260
+ );
13261
+ if (finalResponse) {
13262
+ const rounds = getOpenRouterCallModelRounds(resultLike);
13263
+ const metadata = extractOpenRouterCallModelResultMetadata(
13264
+ finalResponse,
13265
+ rounds.length + 1
13266
+ );
13267
+ span.log({
13268
+ output: extractOpenRouterResponseOutput(finalResponse, fallbackOutput),
13269
+ ...metadata ? { metadata } : {},
13270
+ metrics: aggregateOpenRouterCallModelMetrics(rounds, finalResponse)
13271
+ });
13272
+ span.end();
13273
+ return;
13274
+ }
13275
+ if (fallbackOutput !== void 0) {
13276
+ span.log({
13277
+ output: fallbackOutput
13278
+ });
13279
+ }
13280
+ span.end();
13281
+ };
13282
+ const endSpanWithError = (error) => {
13283
+ if (ended) {
13284
+ return;
13285
+ }
13286
+ ended = true;
13287
+ span.log({
13288
+ error: normalizeError(error).message
13289
+ });
13290
+ span.end();
13291
+ };
13292
+ const finalizeFromResponse = async (fallbackOutput) => {
13293
+ if (!originalGetResponse) {
13294
+ await endSpanWithResult(void 0, fallbackOutput);
13295
+ return;
13296
+ }
13297
+ try {
13298
+ await endSpanWithResult(await originalGetResponse(), fallbackOutput);
13299
+ } catch (e31) {
13300
+ await endSpanWithResult(void 0, fallbackOutput);
13301
+ }
13302
+ };
13303
+ if (originalGetResponse) {
13304
+ resultLike.getResponse = async (...args) => {
13305
+ return await withCurrent(span, async () => {
13306
+ try {
13307
+ const response = await originalGetResponse(...args);
13308
+ await endSpanWithResult(response);
13309
+ return response;
13310
+ } catch (error) {
13311
+ endSpanWithError(error);
13312
+ throw error;
13313
+ }
13314
+ });
13315
+ };
13316
+ }
13317
+ if (typeof resultLike.getText === "function") {
13318
+ const originalGetText = resultLike.getText.bind(resultLike);
13319
+ resultLike.getText = async (...args) => {
13320
+ return await withCurrent(span, async () => {
13321
+ try {
13322
+ const text = await originalGetText(...args);
13323
+ await finalizeFromResponse(text);
13324
+ return text;
13325
+ } catch (error) {
13326
+ endSpanWithError(error);
13327
+ throw error;
13328
+ }
13329
+ });
13330
+ };
13331
+ }
13332
+ for (const methodName of OPENROUTER_CALL_MODEL_CONTEXT_METHODS) {
13333
+ if (typeof resultLike[methodName] !== "function") {
13334
+ continue;
13335
+ }
13336
+ const originalMethod = resultLike[methodName];
13337
+ resultLike[methodName] = async (...args) => {
13338
+ return await withCurrent(span, async () => {
13339
+ return await originalMethod.apply(resultLike, args);
13340
+ });
13341
+ };
13342
+ }
13343
+ for (const methodName of OPENROUTER_CALL_MODEL_STREAM_METHODS) {
13344
+ if (typeof resultLike[methodName] !== "function") {
13345
+ continue;
13346
+ }
13347
+ const originalMethod = resultLike[methodName];
13348
+ resultLike[methodName] = (...args) => {
13349
+ const stream = withCurrent(
13350
+ span,
13351
+ () => originalMethod.apply(resultLike, args)
13352
+ );
13353
+ if (!isAsyncIterable2(stream)) {
13354
+ return stream;
13355
+ }
13356
+ return wrapAsyncIterableWithSpan({
13357
+ finalize: finalizeFromResponse,
13358
+ iteratorFactory: () => stream[Symbol.asyncIterator](),
13359
+ onError: endSpanWithError,
13360
+ span
13361
+ });
13362
+ };
13363
+ }
13364
+ if (originalGetInitialResponse) {
13365
+ let initialTurnTraced = false;
13366
+ resultLike.getInitialResponse = async (...args) => {
13367
+ if (initialTurnTraced) {
13368
+ return await withCurrent(span, async () => {
13369
+ return await originalGetInitialResponse(...args);
13370
+ });
13371
+ }
13372
+ initialTurnTraced = true;
13373
+ const resolvedRequest = getOpenRouterResolvedRequest(resultLike, request);
13374
+ const childSpan = startOpenRouterCallModelTurnSpan({
13375
+ request: resolvedRequest,
13376
+ step: tracedTurnCount + 1,
13377
+ stepType: tracedTurnCount === 0 ? "initial" : "continue"
13378
+ });
13379
+ return await withCurrent(childSpan, async () => {
13380
+ try {
13381
+ const response = await originalGetInitialResponse(...args);
13382
+ tracedTurnCount++;
13383
+ finishOpenRouterCallModelTurnSpan({
13384
+ response,
13385
+ step: tracedTurnCount,
13386
+ stepType: tracedTurnCount === 1 ? "initial" : "continue",
13387
+ span: childSpan
13388
+ });
13389
+ return response;
13390
+ } catch (error) {
13391
+ childSpan.log({
13392
+ error: normalizeError(error).message
13393
+ });
13394
+ childSpan.end();
13395
+ throw error;
13396
+ }
13397
+ });
13398
+ };
13399
+ }
13400
+ if (originalMakeFollowupRequest) {
13401
+ resultLike.makeFollowupRequest = async (...args) => {
13402
+ const currentResponse = args[0];
13403
+ const toolResults = Array.isArray(args[1]) ? args[1] : [];
13404
+ const resolvedRequest = getOpenRouterResolvedRequest(resultLike, request);
13405
+ const followupRequest = buildOpenRouterFollowupRequest(
13406
+ resolvedRequest,
13407
+ currentResponse,
13408
+ toolResults
13409
+ );
13410
+ const childSpan = startOpenRouterCallModelTurnSpan({
13411
+ request: followupRequest,
13412
+ step: tracedTurnCount + 1,
13413
+ stepType: "continue"
13414
+ });
13415
+ return await withCurrent(childSpan, async () => {
13416
+ try {
13417
+ const response = await originalMakeFollowupRequest(...args);
13418
+ tracedTurnCount++;
13419
+ finishOpenRouterCallModelTurnSpan({
13420
+ response,
13421
+ step: tracedTurnCount,
13422
+ stepType: "continue",
13423
+ span: childSpan
13424
+ });
13425
+ return response;
13426
+ } catch (error) {
13427
+ childSpan.log({
13428
+ error: normalizeError(error).message
13429
+ });
13430
+ childSpan.end();
13431
+ throw error;
13432
+ }
13433
+ });
13434
+ };
13435
+ }
13436
+ return true;
13437
+ }
13438
+ function wrapOpenRouterTool(tool) {
13439
+ if (isWrappedTool(tool) || !tool.function || typeof tool.function !== "object" || typeof tool.function.execute !== "function") {
13440
+ return tool;
13441
+ }
13442
+ const toolName = tool.function.name || "tool";
13443
+ const originalExecute = tool.function.execute;
13444
+ const wrappedTool = {
13445
+ ...tool,
13446
+ function: {
13447
+ ...tool.function,
13448
+ execute(...args) {
13449
+ return traceToolExecution({
13450
+ args,
13451
+ execute: () => Reflect.apply(originalExecute, this, args),
13452
+ toolCallId: getToolCallId(args[1]),
13453
+ toolName
13454
+ });
13455
+ }
13456
+ }
13457
+ };
13458
+ Object.defineProperty(wrappedTool, OPENROUTER_WRAPPED_TOOL, {
13459
+ value: true,
13460
+ enumerable: false,
13461
+ configurable: false
13462
+ });
13463
+ return wrappedTool;
13464
+ }
13465
+ function isWrappedTool(tool) {
13466
+ return Boolean(tool[OPENROUTER_WRAPPED_TOOL]);
13467
+ }
13468
+ function isWrappedCallModelResult(value) {
13469
+ return Boolean(
13470
+ isObject(value) && value[OPENROUTER_WRAPPED_CALL_MODEL_RESULT]
13471
+ );
13472
+ }
13473
+ function traceToolExecution(args) {
13474
+ const tracingChannel2 = openRouterChannels.toolExecute.tracingChannel();
13475
+ const input = args.args.length > 0 ? args.args[0] : void 0;
13476
+ const event = {
13477
+ arguments: [input],
13478
+ span_info: {
13479
+ name: args.toolName
13480
+ },
13481
+ toolCallId: args.toolCallId,
13482
+ toolName: args.toolName
13483
+ };
13484
+ tracingChannel2.start.publish(event);
13485
+ try {
13486
+ const result = args.execute();
13487
+ return publishToolResult(tracingChannel2, event, result);
13488
+ } catch (error) {
13489
+ event.error = normalizeError(error);
13490
+ tracingChannel2.error.publish(event);
13491
+ throw error;
13492
+ }
13493
+ }
13494
+ function publishToolResult(tracingChannel2, event, result) {
13495
+ if (isPromiseLike(result)) {
13496
+ return result.then(
13497
+ (resolved) => {
13498
+ event.result = resolved;
13499
+ tracingChannel2.asyncEnd.publish(event);
13500
+ return resolved;
13501
+ },
13502
+ (error) => {
13503
+ event.error = normalizeError(error);
13504
+ tracingChannel2.error.publish(event);
13505
+ throw error;
13506
+ }
13507
+ );
13508
+ }
13509
+ event.result = result;
13510
+ tracingChannel2.asyncEnd.publish(event);
13511
+ return result;
13512
+ }
13513
+ function getToolCallId(context) {
13514
+ const toolContext = context;
13515
+ return typeof _optionalChain([toolContext, 'optionalAccess', _280 => _280.toolCall, 'optionalAccess', _281 => _281.id]) === "string" ? toolContext.toolCall.id : void 0;
13516
+ }
13517
+ function extractOpenRouterCallModelResultMetadata(response, turnCount) {
13518
+ const combined = {
13519
+ ...extractOpenRouterResponseMetadata(response) || {},
13520
+ ...turnCount !== void 0 ? { turn_count: turnCount } : {}
13521
+ };
13522
+ return Object.keys(combined).length > 0 ? combined : void 0;
13523
+ }
13524
+ function getFinalOpenRouterCallModelResponse(result, response) {
13525
+ if (isObject(response)) {
13526
+ return response;
13527
+ }
13528
+ return isObject(result.finalResponse) ? result.finalResponse : void 0;
13529
+ }
13530
+ function getOpenRouterCallModelRounds(result) {
13531
+ if (!Array.isArray(result.allToolExecutionRounds)) {
13532
+ return [];
13533
+ }
13534
+ return result.allToolExecutionRounds.filter((round) => isObject(round)).map((round) => ({
13535
+ response: isObject(round.response) ? round.response : void 0,
13536
+ round: typeof round.round === "number" ? round.round : void 0,
13537
+ toolResults: Array.isArray(round.toolResults) ? round.toolResults : []
13538
+ })).filter((round) => round.response !== void 0);
13539
+ }
13540
+ function aggregateOpenRouterCallModelMetrics(rounds, finalResponse) {
13541
+ const metrics = {};
13542
+ const responses = [
13543
+ ...rounds.map((round) => round.response).filter(isObject),
13544
+ finalResponse
13545
+ ];
13546
+ for (const response of responses) {
13547
+ const responseMetrics = parseOpenRouterMetricsFromUsage(response.usage);
13548
+ for (const [name, value] of Object.entries(responseMetrics)) {
13549
+ metrics[name] = (metrics[name] || 0) + value;
13550
+ }
13551
+ }
13552
+ return metrics;
13553
+ }
13554
+ function buildNextOpenRouterCallModelInput(currentInput, response, toolResults) {
13555
+ const normalizedInput = Array.isArray(currentInput) ? [...currentInput] : currentInput === void 0 ? [] : [currentInput];
13556
+ const responseOutput = Array.isArray(response.output) ? response.output : response.output === void 0 ? [] : [response.output];
13557
+ return [...normalizedInput, ...responseOutput, ...toolResults].map(
13558
+ (entry) => sanitizeOpenRouterLoggedValue(entry)
13559
+ );
13560
+ }
13561
+ function startOpenRouterCallModelTurnSpan(args) {
13562
+ const requestRecord = isObject(args.request) ? args.request : void 0;
13563
+ const metadata = requestRecord ? extractOpenRouterCallModelMetadata(requestRecord) : { provider: "openrouter" };
13564
+ if (isObject(metadata) && "tools" in metadata) {
13565
+ delete metadata.tools;
13566
+ }
13567
+ return startSpan({
13568
+ name: "openrouter.beta.responses.send",
13569
+ spanAttributes: {
13570
+ type: "llm" /* LLM */
13571
+ },
13572
+ event: {
13573
+ input: requestRecord ? extractOpenRouterCallModelInput(requestRecord) : void 0,
13574
+ metadata: {
13575
+ ...metadata,
13576
+ step: args.step,
13577
+ step_type: args.stepType
13578
+ }
13579
+ }
13580
+ });
13581
+ }
13582
+ function finishOpenRouterCallModelTurnSpan(args) {
13583
+ if (!isObject(args.response)) {
13584
+ args.span.end();
13585
+ return;
13586
+ }
13587
+ args.span.log({
13588
+ output: extractOpenRouterResponseOutput(args.response),
13589
+ ...extractOpenRouterResponseMetadata(args.response) ? {
13590
+ metadata: {
13591
+ ...extractOpenRouterResponseMetadata(args.response),
13592
+ ...args.step !== void 0 ? { step: args.step } : {},
13593
+ ...args.stepType ? { step_type: args.stepType } : {}
13594
+ }
13595
+ } : {},
13596
+ metrics: parseOpenRouterMetricsFromUsage(args.response.usage)
13597
+ });
13598
+ args.span.end();
13599
+ }
13600
+ function getOpenRouterResolvedRequest(result, request) {
13601
+ if (isObject(result.resolvedRequest)) {
13602
+ return result.resolvedRequest;
13603
+ }
13604
+ return request;
13605
+ }
13606
+ function buildOpenRouterFollowupRequest(request, currentResponse, toolResults) {
13607
+ if (!request) {
13608
+ return void 0;
13609
+ }
13610
+ return {
13611
+ ...request,
13612
+ input: buildNextOpenRouterCallModelInput(
13613
+ extractOpenRouterCallModelInput(request),
13614
+ isObject(currentResponse) ? currentResponse : {},
13615
+ toolResults
13616
+ ),
13617
+ stream: false
13618
+ };
13619
+ }
13620
+ function wrapAsyncIterableWithSpan(args) {
13621
+ return {
13622
+ [Symbol.asyncIterator]() {
13623
+ const iterator = args.iteratorFactory();
13624
+ return {
13625
+ next(value) {
13626
+ return withCurrent(
13627
+ args.span,
13628
+ () => value === void 0 ? iterator.next() : iterator.next(value)
13629
+ ).then(
13630
+ async (result) => {
13631
+ if (result.done) {
13632
+ await args.finalize();
13633
+ }
13634
+ return result;
13635
+ },
13636
+ (error) => {
13637
+ args.onError(error);
13638
+ throw error;
13639
+ }
13640
+ );
13641
+ },
13642
+ return(value) {
13643
+ if (typeof iterator.return !== "function") {
13644
+ return args.finalize().then(() => ({
13645
+ done: true,
13646
+ value
13647
+ }));
13648
+ }
13649
+ return withCurrent(args.span, () => iterator.return(value)).then(
13650
+ async (result) => {
13651
+ await args.finalize();
13652
+ return result;
13653
+ },
13654
+ (error) => {
13655
+ args.onError(error);
13656
+ throw error;
13657
+ }
13658
+ );
13659
+ },
13660
+ throw(error) {
13661
+ args.onError(error);
13662
+ if (typeof iterator.throw !== "function") {
13663
+ return Promise.reject(error);
13664
+ }
13665
+ return withCurrent(args.span, () => iterator.throw(error));
13666
+ },
13667
+ [Symbol.asyncIterator]() {
13668
+ return this;
13669
+ }
13670
+ };
13671
+ }
13672
+ };
13673
+ }
13674
+ function isAsyncIterable2(value) {
13675
+ return !!value && (typeof value === "object" || typeof value === "function") && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
13676
+ }
13677
+ function isPromiseLike(value) {
13678
+ return !!value && (typeof value === "object" || typeof value === "function") && "then" in value && typeof value.then === "function";
13679
+ }
13680
+ function normalizeError(error) {
13681
+ return error instanceof Error ? error : new Error(String(error));
13682
+ }
13683
+
13684
+ // src/instrumentation/plugins/openrouter-plugin.ts
13685
+ var OpenRouterPlugin = class extends BasePlugin {
13686
+ onEnable() {
13687
+ this.subscribeToOpenRouterChannels();
13688
+ }
13689
+ onDisable() {
13690
+ this.unsubscribers = unsubscribeAll(this.unsubscribers);
13691
+ }
13692
+ subscribeToOpenRouterChannels() {
13693
+ this.unsubscribers.push(
13694
+ traceStreamingChannel(openRouterChannels.chatSend, {
13695
+ name: "openrouter.chat.send",
13696
+ type: "llm" /* LLM */,
13697
+ extractInput: (args) => {
13698
+ const request = getOpenRouterRequestArg(args);
13699
+ const chatGenerationParams = isObject(_optionalChain([request, 'optionalAccess', _282 => _282.chatGenerationParams])) ? request.chatGenerationParams : {};
13700
+ const httpReferer = _optionalChain([request, 'optionalAccess', _283 => _283.httpReferer]);
13701
+ const xTitle = _optionalChain([request, 'optionalAccess', _284 => _284.xTitle]);
13702
+ const { messages, ...metadata } = chatGenerationParams;
13703
+ return {
13704
+ input: messages,
13705
+ metadata: buildOpenRouterMetadata(metadata, httpReferer, xTitle)
13706
+ };
13707
+ },
13708
+ extractOutput: (result) => {
13709
+ return isObject(result) ? result.choices : void 0;
13710
+ },
13711
+ extractMetrics: (result, startTime) => {
13712
+ const metrics = parseOpenRouterMetricsFromUsage(_optionalChain([result, 'optionalAccess', _285 => _285.usage]));
13713
+ if (startTime) {
13714
+ metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
13715
+ }
13716
+ return metrics;
13717
+ },
13718
+ aggregateChunks: aggregateOpenRouterChatChunks
13719
+ })
13720
+ );
13721
+ this.unsubscribers.push(
13722
+ traceAsyncChannel(openRouterChannels.embeddingsGenerate, {
13723
+ name: "openrouter.embeddings.generate",
13724
+ type: "llm" /* LLM */,
13725
+ extractInput: (args) => {
13726
+ const request = getOpenRouterRequestArg(args);
13727
+ const requestBody = isObject(_optionalChain([request, 'optionalAccess', _286 => _286.requestBody])) ? request.requestBody : {};
13728
+ const httpReferer = _optionalChain([request, 'optionalAccess', _287 => _287.httpReferer]);
13729
+ const xTitle = _optionalChain([request, 'optionalAccess', _288 => _288.xTitle]);
13730
+ const { input, ...metadata } = requestBody;
13731
+ return {
13732
+ input,
13733
+ metadata: buildOpenRouterEmbeddingMetadata(
13734
+ metadata,
13735
+ httpReferer,
13736
+ xTitle
13737
+ )
13738
+ };
13739
+ },
13740
+ extractOutput: (result) => {
13741
+ if (!isObject(result)) {
13742
+ return void 0;
13743
+ }
13744
+ const embedding = _optionalChain([result, 'access', _289 => _289.data, 'optionalAccess', _290 => _290[0], 'optionalAccess', _291 => _291.embedding]);
13745
+ return Array.isArray(embedding) ? { embedding_length: embedding.length } : void 0;
13746
+ },
13747
+ extractMetadata: (result) => {
13748
+ if (!isObject(result)) {
13749
+ return void 0;
13750
+ }
13751
+ return extractOpenRouterResponseMetadata(result);
13752
+ },
13753
+ extractMetrics: (result) => {
13754
+ return isObject(result) ? parseOpenRouterMetricsFromUsage(result.usage) : {};
13755
+ }
13756
+ })
13757
+ );
13758
+ this.unsubscribers.push(
13759
+ traceStreamingChannel(openRouterChannels.betaResponsesSend, {
13760
+ name: "openrouter.beta.responses.send",
13761
+ type: "llm" /* LLM */,
13762
+ extractInput: (args) => {
13763
+ const request = getOpenRouterRequestArg(args);
13764
+ const openResponsesRequest = isObject(_optionalChain([request, 'optionalAccess', _292 => _292.openResponsesRequest])) ? request.openResponsesRequest : {};
13765
+ const httpReferer = _optionalChain([request, 'optionalAccess', _293 => _293.httpReferer]);
13766
+ const xTitle = _optionalChain([request, 'optionalAccess', _294 => _294.xTitle]);
13767
+ const { input, ...metadata } = openResponsesRequest;
13768
+ return {
13769
+ input,
13770
+ metadata: buildOpenRouterMetadata(metadata, httpReferer, xTitle)
13771
+ };
13772
+ },
13773
+ extractOutput: (result) => extractOpenRouterResponseOutput(result),
13774
+ extractMetadata: (result) => extractOpenRouterResponseMetadata(result),
13775
+ extractMetrics: (result, startTime) => {
13776
+ const metrics = parseOpenRouterMetricsFromUsage(_optionalChain([result, 'optionalAccess', _295 => _295.usage]));
13777
+ if (startTime) {
13778
+ metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
13779
+ }
13780
+ return metrics;
13781
+ },
13782
+ aggregateChunks: aggregateOpenRouterResponseStreamEvents
13783
+ })
13784
+ );
13785
+ this.unsubscribers.push(
13786
+ traceSyncStreamChannel(openRouterChannels.callModel, {
13787
+ name: "openrouter.callModel",
13788
+ type: "llm" /* LLM */,
13789
+ extractInput: (args) => {
13790
+ const request = getOpenRouterCallModelRequestArg(args);
11901
13791
  return {
11902
- input,
11903
- metadata: { ...metadata, provider: "google-genai" }
13792
+ input: request ? extractOpenRouterCallModelInput(request) : void 0,
13793
+ metadata: request ? extractOpenRouterCallModelMetadata(request) : { provider: "openrouter" }
11904
13794
  };
11905
13795
  },
11906
- extractOutput: (result) => {
11907
- return result;
11908
- },
11909
- extractMetrics: () => {
11910
- return {};
11911
- },
11912
- aggregateChunks: (chunks, _result, _endEvent, startTime) => {
11913
- return aggregateGenerateContentChunks(chunks, startTime);
13796
+ patchResult: ({ endEvent, result, span }) => {
13797
+ return patchOpenRouterCallModelResult(
13798
+ span,
13799
+ result,
13800
+ getOpenRouterCallModelRequestArg(endEvent.arguments)
13801
+ );
11914
13802
  }
11915
13803
  })
11916
13804
  );
11917
- }
11918
- };
11919
- function serializeInput(params) {
11920
- const input = {
11921
- model: params.model,
11922
- contents: serializeContents(params.contents)
11923
- };
11924
- if (params.config) {
11925
- const config = tryToDict(params.config);
11926
- if (config) {
11927
- const tools = serializeTools(params);
11928
- if (tools) {
11929
- config.tools = tools;
11930
- }
11931
- input.config = config;
11932
- }
11933
- }
11934
- return input;
11935
- }
11936
- function serializeContents(contents) {
11937
- if (contents === null || contents === void 0) {
11938
- return null;
11939
- }
11940
- if (Array.isArray(contents)) {
11941
- return contents.map((item) => serializeContentItem(item));
11942
- }
11943
- return serializeContentItem(contents);
11944
- }
11945
- function serializeContentItem(item) {
11946
- if (typeof item === "object" && item !== null) {
11947
- if (item.parts && Array.isArray(item.parts)) {
11948
- return {
11949
- ...item,
11950
- parts: item.parts.map((part) => serializePart(part))
11951
- };
11952
- }
11953
- return item;
11954
- }
11955
- if (typeof item === "string") {
11956
- return { text: item };
11957
- }
11958
- return item;
11959
- }
11960
- function serializePart(part) {
11961
- if (!part || typeof part !== "object") {
11962
- return part;
11963
- }
11964
- if (part.inlineData && part.inlineData.data) {
11965
- const { data, mimeType } = part.inlineData;
11966
- if (data instanceof Uint8Array || typeof Buffer !== "undefined" && Buffer.isBuffer(data) || typeof data === "string") {
11967
- const extension = mimeType ? mimeType.split("/")[1] : "bin";
11968
- const filename = `file.${extension}`;
11969
- const buffer = typeof data === "string" ? typeof Buffer !== "undefined" ? Buffer.from(data, "base64") : new Uint8Array(
11970
- atob(data).split("").map((c) => c.charCodeAt(0))
11971
- ) : typeof Buffer !== "undefined" ? Buffer.from(data) : new Uint8Array(data);
11972
- const arrayBuffer = buffer instanceof Uint8Array ? buffer.buffer.slice(
11973
- buffer.byteOffset,
11974
- buffer.byteOffset + buffer.byteLength
11975
- ) : buffer;
11976
- const attachment = new Attachment({
11977
- data: arrayBuffer,
11978
- filename,
11979
- contentType: mimeType || "application/octet-stream"
11980
- });
11981
- return {
11982
- image_url: { url: attachment }
11983
- };
11984
- }
11985
- }
11986
- return part;
11987
- }
11988
- function serializeTools(params) {
11989
- if (!_optionalChain([params, 'access', _218 => _218.config, 'optionalAccess', _219 => _219.tools])) {
11990
- return null;
11991
- }
11992
- try {
11993
- return params.config.tools.map((tool) => {
11994
- if (typeof tool === "object" && tool.functionDeclarations) {
11995
- return tool;
13805
+ this.unsubscribers.push(
13806
+ traceStreamingChannel(openRouterChannels.toolExecute, {
13807
+ name: "openrouter.tool",
13808
+ type: "tool" /* TOOL */,
13809
+ extractInput: (args, event) => ({
13810
+ input: args[0],
13811
+ metadata: {
13812
+ provider: "openrouter",
13813
+ tool_name: event.toolName,
13814
+ ...event.toolCallId ? { tool_call_id: event.toolCallId } : {}
13815
+ }
13816
+ }),
13817
+ extractOutput: (result) => result,
13818
+ extractMetrics: () => ({}),
13819
+ aggregateChunks: (chunks) => ({
13820
+ output: chunks.length > 0 ? chunks[chunks.length - 1] : void 0,
13821
+ metrics: {}
13822
+ })
13823
+ })
13824
+ );
13825
+ const callModelChannel = openRouterChannels.callModel.tracingChannel();
13826
+ const callModelHandlers = {
13827
+ start: (event) => {
13828
+ const request = getOpenRouterCallModelRequestArg(event.arguments);
13829
+ if (!request) {
13830
+ return;
13831
+ }
13832
+ patchOpenRouterCallModelRequestTools(request);
11996
13833
  }
11997
- return tool;
13834
+ };
13835
+ callModelChannel.subscribe(callModelHandlers);
13836
+ this.unsubscribers.push(() => {
13837
+ callModelChannel.unsubscribe(callModelHandlers);
11998
13838
  });
11999
- } catch (e26) {
12000
- return null;
12001
13839
  }
12002
- }
12003
- function extractMetadata(params) {
12004
- const metadata = {};
12005
- if (params.model) {
12006
- metadata.model = params.model;
13840
+ };
13841
+ function normalizeArgs(args) {
13842
+ if (Array.isArray(args)) {
13843
+ return args;
12007
13844
  }
12008
- if (params.config) {
12009
- const config = tryToDict(params.config);
12010
- if (config) {
12011
- Object.keys(config).forEach((key) => {
12012
- if (key !== "tools") {
12013
- metadata[key] = config[key];
12014
- }
12015
- });
12016
- }
13845
+ if (isArrayLike(args)) {
13846
+ return Array.from(args);
12017
13847
  }
12018
- return metadata;
13848
+ return [args];
12019
13849
  }
12020
- function extractGenerateContentMetrics(response, startTime) {
12021
- const metrics = {};
12022
- if (startTime) {
12023
- const end = getCurrentUnixTimestamp();
12024
- metrics.duration = end - startTime;
12025
- }
12026
- if (_optionalChain([response, 'optionalAccess', _220 => _220.usageMetadata])) {
12027
- populateUsageMetrics(metrics, response.usageMetadata);
12028
- }
12029
- return metrics;
13850
+ function isArrayLike(value) {
13851
+ return isObject(value) && "length" in value && typeof value.length === "number" && Number.isInteger(value.length) && value.length >= 0;
12030
13852
  }
12031
- function populateUsageMetrics(metrics, usage) {
12032
- if (usage.promptTokenCount !== void 0) {
12033
- metrics.prompt_tokens = usage.promptTokenCount;
12034
- }
12035
- if (usage.candidatesTokenCount !== void 0) {
12036
- metrics.completion_tokens = usage.candidatesTokenCount;
12037
- }
12038
- if (usage.totalTokenCount !== void 0) {
12039
- metrics.tokens = usage.totalTokenCount;
12040
- }
12041
- if (usage.cachedContentTokenCount !== void 0) {
12042
- metrics.prompt_cached_tokens = usage.cachedContentTokenCount;
12043
- }
12044
- if (usage.thoughtsTokenCount !== void 0) {
12045
- metrics.completion_reasoning_tokens = usage.thoughtsTokenCount;
13853
+ function getOpenRouterRequestArg(args) {
13854
+ const normalizedArgs = normalizeArgs(args);
13855
+ const keyedCandidate = normalizedArgs.find(
13856
+ (arg) => isObject(arg) && ("chatGenerationParams" in arg || "requestBody" in arg || "openResponsesRequest" in arg)
13857
+ );
13858
+ if (isObject(keyedCandidate)) {
13859
+ return keyedCandidate;
12046
13860
  }
13861
+ const firstObjectArg = normalizedArgs.find((arg) => isObject(arg));
13862
+ return isObject(firstObjectArg) ? firstObjectArg : void 0;
12047
13863
  }
12048
- function aggregateGenerateContentChunks(chunks, startTime) {
12049
- const metrics = {};
12050
- if (startTime !== void 0) {
12051
- const end = getCurrentUnixTimestamp();
12052
- metrics.duration = end - startTime;
12053
- }
12054
- let firstTokenTime = null;
12055
- if (chunks.length > 0 && firstTokenTime === null && startTime !== void 0) {
12056
- firstTokenTime = getCurrentUnixTimestamp();
12057
- metrics.time_to_first_token = firstTokenTime - startTime;
12058
- }
12059
- if (chunks.length === 0) {
12060
- return { output: {}, metrics };
12061
- }
12062
- let text = "";
12063
- let thoughtText = "";
12064
- const otherParts = [];
12065
- let usageMetadata = null;
12066
- let lastResponse = null;
13864
+ function getOpenRouterCallModelRequestArg(args) {
13865
+ const firstObjectArg = normalizeArgs(args).find((arg) => isObject(arg));
13866
+ return isObject(firstObjectArg) ? firstObjectArg : void 0;
13867
+ }
13868
+ function aggregateOpenRouterChatChunks(chunks) {
13869
+ let role;
13870
+ let content = "";
13871
+ let toolCalls;
13872
+ let finishReason;
13873
+ let metrics = {};
12067
13874
  for (const chunk of chunks) {
12068
- lastResponse = chunk;
12069
- if (chunk.usageMetadata) {
12070
- usageMetadata = chunk.usageMetadata;
13875
+ metrics = {
13876
+ ...metrics,
13877
+ ...parseOpenRouterMetricsFromUsage(_optionalChain([chunk, 'optionalAccess', _296 => _296.usage]))
13878
+ };
13879
+ const choice = _optionalChain([chunk, 'optionalAccess', _297 => _297.choices, 'optionalAccess', _298 => _298[0]]);
13880
+ const delta = _optionalChain([choice, 'optionalAccess', _299 => _299.delta]);
13881
+ if (!delta) {
13882
+ if (_optionalChain([choice, 'optionalAccess', _300 => _300.finish_reason]) !== void 0) {
13883
+ finishReason = choice.finish_reason;
13884
+ }
13885
+ continue;
12071
13886
  }
12072
- if (chunk.candidates && Array.isArray(chunk.candidates)) {
12073
- for (const candidate of chunk.candidates) {
12074
- if (_optionalChain([candidate, 'access', _221 => _221.content, 'optionalAccess', _222 => _222.parts])) {
12075
- for (const part of candidate.content.parts) {
12076
- if (part.text !== void 0) {
12077
- if (part.thought) {
12078
- thoughtText += part.text;
12079
- } else {
12080
- text += part.text;
12081
- }
12082
- } else if (part.functionCall) {
12083
- otherParts.push({ functionCall: part.functionCall });
12084
- } else if (part.codeExecutionResult) {
12085
- otherParts.push({
12086
- codeExecutionResult: part.codeExecutionResult
12087
- });
12088
- } else if (part.executableCode) {
12089
- otherParts.push({ executableCode: part.executableCode });
12090
- }
13887
+ if (!role && delta.role) {
13888
+ role = delta.role;
13889
+ }
13890
+ if (typeof delta.content === "string") {
13891
+ content += delta.content;
13892
+ }
13893
+ const choiceFinishReason = _nullishCoalesce(_nullishCoalesce(_optionalChain([choice, 'optionalAccess', _301 => _301.finishReason]), () => ( _optionalChain([choice, 'optionalAccess', _302 => _302.finish_reason]))), () => ( void 0));
13894
+ const deltaFinishReason = _nullishCoalesce(_nullishCoalesce(delta.finishReason, () => ( delta.finish_reason)), () => ( void 0));
13895
+ if (choiceFinishReason !== void 0) {
13896
+ finishReason = choiceFinishReason;
13897
+ } else if (deltaFinishReason !== void 0) {
13898
+ finishReason = deltaFinishReason;
13899
+ }
13900
+ const toolCallDeltas = Array.isArray(delta.toolCalls) ? delta.toolCalls : Array.isArray(delta.tool_calls) ? delta.tool_calls : void 0;
13901
+ if (!toolCallDeltas) {
13902
+ continue;
13903
+ }
13904
+ for (const toolDelta of toolCallDeltas) {
13905
+ if (!_optionalChain([toolDelta, 'optionalAccess', _303 => _303.function])) {
13906
+ continue;
13907
+ }
13908
+ const toolIndex = _nullishCoalesce(toolDelta.index, () => ( 0));
13909
+ const existingToolCall = _optionalChain([toolCalls, 'optionalAccess', _304 => _304[toolIndex]]);
13910
+ if (!existingToolCall || toolDelta.id && existingToolCall.id !== void 0 && existingToolCall.id !== toolDelta.id) {
13911
+ const nextToolCalls = [...toolCalls || []];
13912
+ nextToolCalls[toolIndex] = {
13913
+ index: toolIndex,
13914
+ id: toolDelta.id,
13915
+ type: toolDelta.type,
13916
+ function: {
13917
+ name: toolDelta.function.name,
13918
+ arguments: toolDelta.function.arguments || ""
12091
13919
  }
12092
- }
13920
+ };
13921
+ toolCalls = nextToolCalls;
13922
+ continue;
12093
13923
  }
12094
- }
12095
- }
12096
- const output = {};
12097
- const parts = [];
12098
- if (thoughtText) {
12099
- parts.push({ text: thoughtText, thought: true });
12100
- }
12101
- if (text) {
12102
- parts.push({ text });
12103
- }
12104
- parts.push(...otherParts);
12105
- if (parts.length > 0 && _optionalChain([lastResponse, 'optionalAccess', _223 => _223.candidates])) {
12106
- const candidates = [];
12107
- for (const candidate of lastResponse.candidates) {
12108
- const candidateDict = {
12109
- content: {
12110
- parts,
12111
- role: "model"
12112
- }
12113
- };
12114
- if (candidate.finishReason !== void 0) {
12115
- candidateDict.finishReason = candidate.finishReason;
13924
+ const current = existingToolCall;
13925
+ if (toolDelta.id && !current.id) {
13926
+ current.id = toolDelta.id;
12116
13927
  }
12117
- if (candidate.safetyRatings) {
12118
- candidateDict.safetyRatings = candidate.safetyRatings;
13928
+ if (toolDelta.type && !current.type) {
13929
+ current.type = toolDelta.type;
12119
13930
  }
12120
- candidates.push(candidateDict);
13931
+ if (toolDelta.function.name && !current.function.name) {
13932
+ current.function.name = toolDelta.function.name;
13933
+ }
13934
+ current.function.arguments += toolDelta.function.arguments || "";
12121
13935
  }
12122
- output.candidates = candidates;
12123
- }
12124
- if (usageMetadata) {
12125
- output.usageMetadata = usageMetadata;
12126
- populateUsageMetrics(metrics, usageMetadata);
12127
- }
12128
- if (text) {
12129
- output.text = text;
12130
13936
  }
12131
- return { output, metrics };
13937
+ return {
13938
+ output: [
13939
+ {
13940
+ index: 0,
13941
+ message: {
13942
+ role,
13943
+ content: content || void 0,
13944
+ ...toolCalls ? { tool_calls: toolCalls } : {}
13945
+ },
13946
+ logprobs: null,
13947
+ finish_reason: finishReason
13948
+ }
13949
+ ],
13950
+ metrics
13951
+ };
12132
13952
  }
12133
- function tryToDict(obj) {
12134
- if (obj === null || obj === void 0) {
12135
- return null;
12136
- }
12137
- if (typeof obj === "object") {
12138
- if ("toJSON" in obj && // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
12139
- typeof obj.toJSON === "function") {
12140
- return obj.toJSON();
13953
+ function aggregateOpenRouterResponseStreamEvents(chunks) {
13954
+ let finalResponse;
13955
+ for (const chunk of chunks) {
13956
+ const response = _optionalChain([chunk, 'optionalAccess', _305 => _305.response]);
13957
+ if (!response) {
13958
+ continue;
13959
+ }
13960
+ if (chunk.type === "response.completed" || chunk.type === "response.incomplete" || chunk.type === "response.failed") {
13961
+ finalResponse = response;
12141
13962
  }
12142
- return obj;
12143
13963
  }
12144
- return null;
13964
+ if (!finalResponse) {
13965
+ return {
13966
+ output: void 0,
13967
+ metrics: {}
13968
+ };
13969
+ }
13970
+ return {
13971
+ output: extractOpenRouterResponseOutput(finalResponse),
13972
+ metrics: parseOpenRouterMetricsFromUsage(finalResponse.usage),
13973
+ ...extractOpenRouterResponseMetadata(finalResponse) ? { metadata: extractOpenRouterResponseMetadata(finalResponse) } : {}
13974
+ };
12145
13975
  }
12146
13976
 
12147
13977
  // src/instrumentation/braintrust-plugin.ts
@@ -12152,8 +13982,9 @@ var BraintrustPlugin = (_class18 = class extends BasePlugin {
12152
13982
  __init66() {this.aiSDKPlugin = null}
12153
13983
  __init67() {this.claudeAgentSDKPlugin = null}
12154
13984
  __init68() {this.googleGenAIPlugin = null}
13985
+ __init69() {this.openRouterPlugin = null}
12155
13986
  constructor(config = {}) {
12156
- 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);;
13987
+ 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);;
12157
13988
  this.config = config;
12158
13989
  }
12159
13990
  onEnable() {
@@ -12178,6 +14009,10 @@ var BraintrustPlugin = (_class18 = class extends BasePlugin {
12178
14009
  this.googleGenAIPlugin = new GoogleGenAIPlugin();
12179
14010
  this.googleGenAIPlugin.enable();
12180
14011
  }
14012
+ if (integrations.openrouter !== false) {
14013
+ this.openRouterPlugin = new OpenRouterPlugin();
14014
+ this.openRouterPlugin.enable();
14015
+ }
12181
14016
  }
12182
14017
  onDisable() {
12183
14018
  if (this.openaiPlugin) {
@@ -12200,14 +14035,18 @@ var BraintrustPlugin = (_class18 = class extends BasePlugin {
12200
14035
  this.googleGenAIPlugin.disable();
12201
14036
  this.googleGenAIPlugin = null;
12202
14037
  }
14038
+ if (this.openRouterPlugin) {
14039
+ this.openRouterPlugin.disable();
14040
+ this.openRouterPlugin = null;
14041
+ }
12203
14042
  }
12204
14043
  }, _class18);
12205
14044
 
12206
14045
  // src/instrumentation/registry.ts
12207
- var PluginRegistry = (_class19 = class {constructor() { _class19.prototype.__init69.call(this);_class19.prototype.__init70.call(this);_class19.prototype.__init71.call(this); }
12208
- __init69() {this.braintrustPlugin = null}
12209
- __init70() {this.config = {}}
12210
- __init71() {this.enabled = false}
14046
+ var PluginRegistry = (_class19 = class {constructor() { _class19.prototype.__init70.call(this);_class19.prototype.__init71.call(this);_class19.prototype.__init72.call(this); }
14047
+ __init70() {this.braintrustPlugin = null}
14048
+ __init71() {this.config = {}}
14049
+ __init72() {this.enabled = false}
12211
14050
  /**
12212
14051
  * Configure which integrations should be enabled.
12213
14052
  * This must be called before any SDK imports to take effect.
@@ -12271,7 +14110,8 @@ var PluginRegistry = (_class19 = class {constructor() { _class19.prototype.__ini
12271
14110
  vercel: true,
12272
14111
  aisdk: true,
12273
14112
  google: true,
12274
- claudeAgentSDK: true
14113
+ claudeAgentSDK: true,
14114
+ openrouter: true
12275
14115
  };
12276
14116
  }
12277
14117
  /**
@@ -12301,6 +14141,7 @@ function configureNode() {
12301
14141
  isomorph_default.getCallerLocation = getCallerLocation;
12302
14142
  isomorph_default.newAsyncLocalStorage = () => new (0, _nodeasync_hooks.AsyncLocalStorage)();
12303
14143
  isomorph_default.newTracingChannel = (nameOrChannels) => diagnostics_channel.tracingChannel(nameOrChannels);
14144
+ patchTracingChannel(diagnostics_channel.tracingChannel);
12304
14145
  isomorph_default.processOn = (event, handler) => {
12305
14146
  process.on(event, handler);
12306
14147
  };
@@ -12405,7 +14246,7 @@ function isAsync(fn) {
12405
14246
  function isAsyncGenerator2(fn) {
12406
14247
  return fn[Symbol.toStringTag] === "AsyncGenerator";
12407
14248
  }
12408
- function isAsyncIterable2(obj) {
14249
+ function isAsyncIterable3(obj) {
12409
14250
  return typeof obj[Symbol.asyncIterator] === "function";
12410
14251
  }
12411
14252
  function wrapAsync(asyncFn) {
@@ -12455,7 +14296,7 @@ function _asyncMap(eachfn, arr, iteratee, callback) {
12455
14296
  callback(err, results);
12456
14297
  });
12457
14298
  }
12458
- function isArrayLike(value) {
14299
+ function isArrayLike2(value) {
12459
14300
  return value && typeof value.length === "number" && value.length >= 0 && value.length % 1 === 0;
12460
14301
  }
12461
14302
  var breakLoop = {};
@@ -12503,7 +14344,7 @@ function createObjectIterator(obj) {
12503
14344
  };
12504
14345
  }
12505
14346
  function createIterator(coll) {
12506
- if (isArrayLike(coll)) {
14347
+ if (isArrayLike2(coll)) {
12507
14348
  return createArrayIterator(coll);
12508
14349
  }
12509
14350
  var iterator = getIterator(coll);
@@ -12577,7 +14418,7 @@ var eachOfLimit$2 = (limit) => {
12577
14418
  if (isAsyncGenerator2(obj)) {
12578
14419
  return asyncEachOfLimit(obj, limit, iteratee, callback);
12579
14420
  }
12580
- if (isAsyncIterable2(obj)) {
14421
+ if (isAsyncIterable3(obj)) {
12581
14422
  return asyncEachOfLimit(obj[Symbol.asyncIterator](), limit, iteratee, callback);
12582
14423
  }
12583
14424
  var nextElem = createIterator(obj);
@@ -12649,7 +14490,7 @@ function eachOfGeneric(coll, iteratee, callback) {
12649
14490
  return eachOfLimit$1(coll, Infinity, iteratee, callback);
12650
14491
  }
12651
14492
  function eachOf(coll, iteratee, callback) {
12652
- var eachOfImplementation = isArrayLike(coll) ? eachOfArrayLike : eachOfGeneric;
14493
+ var eachOfImplementation = isArrayLike2(coll) ? eachOfArrayLike : eachOfGeneric;
12653
14494
  return eachOfImplementation(coll, wrapAsync(iteratee), callback);
12654
14495
  }
12655
14496
  var eachOf$1 = awaitify(eachOf, 3);
@@ -13164,7 +15005,7 @@ function filterGeneric(eachfn, coll, iteratee, callback) {
13164
15005
  });
13165
15006
  }
13166
15007
  function _filter(eachfn, coll, iteratee, callback) {
13167
- var filter2 = isArrayLike(coll) ? filterArray : filterGeneric;
15008
+ var filter2 = isArrayLike2(coll) ? filterArray : filterGeneric;
13168
15009
  return filter2(eachfn, coll, wrapAsync(iteratee), callback);
13169
15010
  }
13170
15011
  function filter(coll, iteratee, callback) {
@@ -13239,7 +15080,7 @@ if (hasNextTick) {
13239
15080
  }
13240
15081
  var nextTick = wrap(_defer);
13241
15082
  var _parallel = awaitify((eachfn, tasks, callback) => {
13242
- var results = isArrayLike(tasks) ? [] : {};
15083
+ var results = isArrayLike2(tasks) ? [] : {};
13243
15084
  eachfn(tasks, (task, key, taskCb) => {
13244
15085
  wrapAsync(task)((err, ...result) => {
13245
15086
  if (result.length < 2) {
@@ -13506,10 +15347,10 @@ var SpanFetcher = class _SpanFetcher extends ObjectFetcher {
13506
15347
  }
13507
15348
  };
13508
15349
  var CachedSpanFetcher = (_class20 = class {
13509
- __init72() {this.spanCache = /* @__PURE__ */ new Map()}
13510
- __init73() {this.allFetched = false}
15350
+ __init73() {this.spanCache = /* @__PURE__ */ new Map()}
15351
+ __init74() {this.allFetched = false}
13511
15352
 
13512
- constructor(objectTypeOrFetchFn, objectId, rootSpanId, getState) {;_class20.prototype.__init72.call(this);_class20.prototype.__init73.call(this);
15353
+ constructor(objectTypeOrFetchFn, objectId, rootSpanId, getState) {;_class20.prototype.__init73.call(this);_class20.prototype.__init74.call(this);
13513
15354
  if (typeof objectTypeOrFetchFn === "function") {
13514
15355
  this.fetchFn = objectTypeOrFetchFn;
13515
15356
  } else {
@@ -13524,7 +15365,7 @@ var CachedSpanFetcher = (_class20 = class {
13524
15365
  spanType
13525
15366
  );
13526
15367
  const rows = await fetcher.fetchedData();
13527
- return rows.filter((row) => _optionalChain([row, 'access', _224 => _224.span_attributes, 'optionalAccess', _225 => _225.purpose]) !== "scorer").map((row) => ({
15368
+ return rows.filter((row) => _optionalChain([row, 'access', _306 => _306.span_attributes, 'optionalAccess', _307 => _307.purpose]) !== "scorer").map((row) => ({
13528
15369
  input: row.input,
13529
15370
  output: row.output,
13530
15371
  metadata: row.metadata,
@@ -13558,7 +15399,7 @@ var CachedSpanFetcher = (_class20 = class {
13558
15399
  async fetchSpans(spanType) {
13559
15400
  const spans = await this.fetchFn(spanType);
13560
15401
  for (const span of spans) {
13561
- const type = _nullishCoalesce(_optionalChain([span, 'access', _226 => _226.span_attributes, 'optionalAccess', _227 => _227.type]), () => ( ""));
15402
+ const type = _nullishCoalesce(_optionalChain([span, 'access', _308 => _308.span_attributes, 'optionalAccess', _309 => _309.type]), () => ( ""));
13562
15403
  const existing = _nullishCoalesce(this.spanCache.get(type), () => ( []));
13563
15404
  existing.push(span);
13564
15405
  this.spanCache.set(type, existing);
@@ -13582,17 +15423,17 @@ var LocalTrace = (_class21 = class {
13582
15423
 
13583
15424
 
13584
15425
 
13585
- __init74() {this.spansFlushed = false}
13586
- __init75() {this.spansFlushPromise = null}
15426
+ __init75() {this.spansFlushed = false}
15427
+ __init76() {this.spansFlushPromise = null}
13587
15428
 
13588
- __init76() {this.threadCache = /* @__PURE__ */ new Map()}
15429
+ __init77() {this.threadCache = /* @__PURE__ */ new Map()}
13589
15430
  constructor({
13590
15431
  objectType,
13591
15432
  objectId,
13592
15433
  rootSpanId,
13593
15434
  ensureSpansFlushed,
13594
15435
  state
13595
- }) {;_class21.prototype.__init74.call(this);_class21.prototype.__init75.call(this);_class21.prototype.__init76.call(this);
15436
+ }) {;_class21.prototype.__init75.call(this);_class21.prototype.__init76.call(this);_class21.prototype.__init77.call(this);
13596
15437
  this.objectType = objectType;
13597
15438
  this.objectId = objectId;
13598
15439
  this.rootSpanId = rootSpanId;
@@ -13638,11 +15479,11 @@ var LocalTrace = (_class21 = class {
13638
15479
  const cachedSpans = this.state.spanCache.getByRootSpanId(this.rootSpanId);
13639
15480
  if (cachedSpans && cachedSpans.length > 0) {
13640
15481
  let spans = cachedSpans.filter(
13641
- (span) => _optionalChain([span, 'access', _228 => _228.span_attributes, 'optionalAccess', _229 => _229.purpose]) !== "scorer"
15482
+ (span) => _optionalChain([span, 'access', _310 => _310.span_attributes, 'optionalAccess', _311 => _311.purpose]) !== "scorer"
13642
15483
  );
13643
15484
  if (spanType && spanType.length > 0) {
13644
15485
  spans = spans.filter(
13645
- (span) => spanType.includes(_nullishCoalesce(_optionalChain([span, 'access', _230 => _230.span_attributes, 'optionalAccess', _231 => _231.type]), () => ( "")))
15486
+ (span) => spanType.includes(_nullishCoalesce(_optionalChain([span, 'access', _312 => _312.span_attributes, 'optionalAccess', _313 => _313.type]), () => ( "")))
13646
15487
  );
13647
15488
  }
13648
15489
  return spans.map((span) => ({
@@ -13661,7 +15502,7 @@ var LocalTrace = (_class21 = class {
13661
15502
  * Calls the API with the project_default preprocessor (which falls back to "thread").
13662
15503
  */
13663
15504
  async getThread(options) {
13664
- const cacheKey = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _232 => _232.preprocessor]), () => ( "project_default"));
15505
+ const cacheKey = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _314 => _314.preprocessor]), () => ( "project_default"));
13665
15506
  if (!this.threadCache.has(cacheKey)) {
13666
15507
  const promise = this.fetchThread(options);
13667
15508
  this.threadCache.set(cacheKey, promise);
@@ -13672,7 +15513,7 @@ var LocalTrace = (_class21 = class {
13672
15513
  await this.ensureSpansReady();
13673
15514
  await this.state.login({});
13674
15515
  const result = await invoke({
13675
- globalFunction: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _233 => _233.preprocessor]), () => ( "project_default")),
15516
+ globalFunction: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _315 => _315.preprocessor]), () => ( "project_default")),
13676
15517
  functionType: "preprocessor",
13677
15518
  input: {
13678
15519
  trace_ref: {
@@ -13848,10 +15689,10 @@ function validateParametersWithJsonSchema(parameters, schema) {
13848
15689
  const ajv = new (0, _ajv2.default)({ coerceTypes: true, useDefaults: true, strict: false });
13849
15690
  const validate = ajv.compile(schema);
13850
15691
  if (!validate(parameters)) {
13851
- const errorMessages = _optionalChain([validate, 'access', _234 => _234.errors, 'optionalAccess', _235 => _235.map, 'call', _236 => _236((err) => {
15692
+ const errorMessages = _optionalChain([validate, 'access', _316 => _316.errors, 'optionalAccess', _317 => _317.map, 'call', _318 => _318((err) => {
13852
15693
  const path2 = err.instancePath || "root";
13853
15694
  return `${path2}: ${err.message}`;
13854
- }), 'access', _237 => _237.join, 'call', _238 => _238(", ")]);
15695
+ }), 'access', _319 => _319.join, 'call', _320 => _320(", ")]);
13855
15696
  throw Error(`Invalid parameters: ${errorMessages}`);
13856
15697
  }
13857
15698
  return parameters;
@@ -13920,7 +15761,7 @@ function callEvaluatorData(data) {
13920
15761
  baseExperiment
13921
15762
  };
13922
15763
  }
13923
- function isAsyncIterable3(value) {
15764
+ function isAsyncIterable4(value) {
13924
15765
  return typeof value === "object" && value !== null && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
13925
15766
  }
13926
15767
  function isIterable(value) {
@@ -14089,7 +15930,7 @@ async function runEvaluator(experiment, evaluator, progressReporter, filters, st
14089
15930
  }
14090
15931
  async function runEvaluatorInternal(experiment, evaluator, progressReporter, filters, stream, parameters, collectResults, enableCache) {
14091
15932
  if (enableCache) {
14092
- _optionalChain([(_nullishCoalesce(evaluator.state, () => ( _internalGetGlobalState()))), 'optionalAccess', _239 => _239.spanCache, 'optionalAccess', _240 => _240.start, 'call', _241 => _241()]);
15933
+ _optionalChain([(_nullishCoalesce(evaluator.state, () => ( _internalGetGlobalState()))), 'optionalAccess', _321 => _321.spanCache, 'optionalAccess', _322 => _322.start, 'call', _323 => _323()]);
14093
15934
  }
14094
15935
  try {
14095
15936
  if (typeof evaluator.data === "string") {
@@ -14125,7 +15966,7 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
14125
15966
  }
14126
15967
  const resolvedDataResult = dataResult instanceof Promise ? await dataResult : dataResult;
14127
15968
  const dataIterable = (() => {
14128
- if (isAsyncIterable3(resolvedDataResult)) {
15969
+ if (isAsyncIterable4(resolvedDataResult)) {
14129
15970
  return resolvedDataResult;
14130
15971
  }
14131
15972
  if (Array.isArray(resolvedDataResult) || isIterable(resolvedDataResult)) {
@@ -14144,7 +15985,7 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
14144
15985
  const experimentIdPromise = experiment ? (async () => {
14145
15986
  try {
14146
15987
  return await experiment.id;
14147
- } catch (e27) {
15988
+ } catch (e32) {
14148
15989
  return void 0;
14149
15990
  }
14150
15991
  })() : void 0;
@@ -14200,7 +16041,7 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
14200
16041
  objectType: parentComponents ? spanObjectTypeV3ToTypedString(
14201
16042
  parentComponents.data.object_type
14202
16043
  ) : "experiment",
14203
- objectId: await _asyncNullishCoalesce(await _asyncOptionalChain([parentComponents, 'optionalAccess', async _242 => _242.data, 'access', async _243 => _243.object_id]), async () => ( (experimentIdPromise ? await _asyncNullishCoalesce(await experimentIdPromise, async () => ( "")) : ""))),
16044
+ objectId: await _asyncNullishCoalesce(await _asyncOptionalChain([parentComponents, 'optionalAccess', async _324 => _324.data, 'access', async _325 => _325.object_id]), async () => ( (experimentIdPromise ? await _asyncNullishCoalesce(await experimentIdPromise, async () => ( "")) : ""))),
14204
16045
  rootSpanId: rootSpan.rootSpanId,
14205
16046
  ensureSpansFlushed,
14206
16047
  state
@@ -14226,10 +16067,10 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
14226
16067
  span,
14227
16068
  parameters: _nullishCoalesce(parameters, () => ( {})),
14228
16069
  reportProgress: (event) => {
14229
- _optionalChain([stream, 'optionalCall', _244 => _244({
16070
+ _optionalChain([stream, 'optionalCall', _326 => _326({
14230
16071
  ...event,
14231
16072
  id: rootSpan.id,
14232
- origin: _optionalChain([baseEvent, 'access', _245 => _245.event, 'optionalAccess', _246 => _246.origin]),
16073
+ origin: _optionalChain([baseEvent, 'access', _327 => _327.event, 'optionalAccess', _328 => _328.origin]),
14233
16074
  name: evaluator.evalName,
14234
16075
  object_type: "task"
14235
16076
  })]);
@@ -14393,7 +16234,7 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
14393
16234
  metadata,
14394
16235
  scores: mergedScores,
14395
16236
  error,
14396
- origin: _optionalChain([baseEvent, 'access', _247 => _247.event, 'optionalAccess', _248 => _248.origin])
16237
+ origin: _optionalChain([baseEvent, 'access', _329 => _329.event, 'optionalAccess', _330 => _330.origin])
14397
16238
  });
14398
16239
  }
14399
16240
  };
@@ -14428,7 +16269,7 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
14428
16269
  break;
14429
16270
  }
14430
16271
  scheduledTrials++;
14431
- _optionalChain([progressReporter, 'access', _249 => _249.setTotal, 'optionalCall', _250 => _250(evaluator.evalName, scheduledTrials)]);
16272
+ _optionalChain([progressReporter, 'access', _331 => _331.setTotal, 'optionalCall', _332 => _332(evaluator.evalName, scheduledTrials)]);
14432
16273
  q.pushAsync({ datum, trialIndex }).catch((e) => {
14433
16274
  if (queueErrors.length < 5) {
14434
16275
  queueErrors.push(e);
@@ -14513,9 +16354,9 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
14513
16354
  );
14514
16355
  } finally {
14515
16356
  if (enableCache) {
14516
- const spanCache = _optionalChain([(_nullishCoalesce(evaluator.state, () => ( _internalGetGlobalState()))), 'optionalAccess', _251 => _251.spanCache]);
14517
- _optionalChain([spanCache, 'optionalAccess', _252 => _252.dispose, 'call', _253 => _253()]);
14518
- _optionalChain([spanCache, 'optionalAccess', _254 => _254.stop, 'call', _255 => _255()]);
16357
+ const spanCache = _optionalChain([(_nullishCoalesce(evaluator.state, () => ( _internalGetGlobalState()))), 'optionalAccess', _333 => _333.spanCache]);
16358
+ _optionalChain([spanCache, 'optionalAccess', _334 => _334.dispose, 'call', _335 => _335()]);
16359
+ _optionalChain([spanCache, 'optionalAccess', _336 => _336.stop, 'call', _337 => _337()]);
14519
16360
  }
14520
16361
  }
14521
16362
  }
@@ -14752,7 +16593,7 @@ async function cachedLogin(options) {
14752
16593
  }
14753
16594
  function makeCheckAuthorized(allowedOrgName) {
14754
16595
  return async (req, _res, next) => {
14755
- if (!_optionalChain([req, 'access', _256 => _256.ctx, 'optionalAccess', _257 => _257.token])) {
16596
+ if (!_optionalChain([req, 'access', _338 => _338.ctx, 'optionalAccess', _339 => _339.token])) {
14756
16597
  return next(_httperrors2.default.call(void 0, 401, "Unauthorized"));
14757
16598
  }
14758
16599
  try {
@@ -14765,7 +16606,7 @@ function makeCheckAuthorized(allowedOrgName) {
14765
16606
  return next(_httperrors2.default.call(void 0, 403, errorMessage));
14766
16607
  }
14767
16608
  const state = await cachedLogin({
14768
- apiKey: _optionalChain([req, 'access', _258 => _258.ctx, 'optionalAccess', _259 => _259.token]),
16609
+ apiKey: _optionalChain([req, 'access', _340 => _340.ctx, 'optionalAccess', _341 => _341.token]),
14769
16610
  orgName
14770
16611
  });
14771
16612
  req.ctx.state = state;
@@ -14962,10 +16803,10 @@ var Project2 = (_class22 = class {
14962
16803
 
14963
16804
 
14964
16805
 
14965
- __init77() {this._publishableCodeFunctions = []}
14966
- __init78() {this._publishablePrompts = []}
14967
- __init79() {this._publishableParameters = []}
14968
- constructor(args) {;_class22.prototype.__init77.call(this);_class22.prototype.__init78.call(this);_class22.prototype.__init79.call(this);
16806
+ __init78() {this._publishableCodeFunctions = []}
16807
+ __init79() {this._publishablePrompts = []}
16808
+ __init80() {this._publishableParameters = []}
16809
+ constructor(args) {;_class22.prototype.__init78.call(this);_class22.prototype.__init79.call(this);_class22.prototype.__init80.call(this);
14969
16810
  _initializeSpanContext();
14970
16811
  this.name = "name" in args ? args.name : void 0;
14971
16812
  this.id = "id" in args ? args.id : void 0;
@@ -15019,10 +16860,10 @@ var Project2 = (_class22 = class {
15019
16860
  }
15020
16861
  }, _class22);
15021
16862
  var ToolBuilder = (_class23 = class {
15022
- constructor(project) {;_class23.prototype.__init80.call(this);
16863
+ constructor(project) {;_class23.prototype.__init81.call(this);
15023
16864
  this.project = project;
15024
16865
  }
15025
- __init80() {this.taskCounter = 0}
16866
+ __init81() {this.taskCounter = 0}
15026
16867
  // This type definition is just a catch all so that the implementation can be
15027
16868
  // less specific than the two more specific declarations above.
15028
16869
  create(opts) {
@@ -15049,10 +16890,10 @@ var ToolBuilder = (_class23 = class {
15049
16890
  }
15050
16891
  }, _class23);
15051
16892
  var ScorerBuilder = (_class24 = class {
15052
- constructor(project) {;_class24.prototype.__init81.call(this);
16893
+ constructor(project) {;_class24.prototype.__init82.call(this);
15053
16894
  this.project = project;
15054
16895
  }
15055
- __init81() {this.taskCounter = 0}
16896
+ __init82() {this.taskCounter = 0}
15056
16897
  create(opts) {
15057
16898
  this.taskCounter++;
15058
16899
  let resolvedName = opts.name;
@@ -15407,9 +17248,9 @@ function serializeRemoteEvalParametersContainer(parameters) {
15407
17248
  source: null
15408
17249
  };
15409
17250
  }
15410
- var ProjectNameIdMap = (_class25 = class {constructor() { _class25.prototype.__init82.call(this);_class25.prototype.__init83.call(this); }
15411
- __init82() {this.nameToId = {}}
15412
- __init83() {this.idToName = {}}
17251
+ var ProjectNameIdMap = (_class25 = class {constructor() { _class25.prototype.__init83.call(this);_class25.prototype.__init84.call(this); }
17252
+ __init83() {this.nameToId = {}}
17253
+ __init84() {this.idToName = {}}
15413
17254
  async getId(projectName) {
15414
17255
  if (!(projectName in this.nameToId)) {
15415
17256
  const response = await _internalGetGlobalState().appConn().post_json("api/project/register", {
@@ -15514,7 +17355,7 @@ function runDevServer(evaluators, opts) {
15514
17355
  scores,
15515
17356
  stream
15516
17357
  } = evalBodySchema.parse(req.body);
15517
- if (!_optionalChain([req, 'access', _260 => _260.ctx, 'optionalAccess', _261 => _261.state])) {
17358
+ if (!_optionalChain([req, 'access', _342 => _342.ctx, 'optionalAccess', _343 => _343.state])) {
15518
17359
  res.status(500).json({ error: "Braintrust state not initialized in request" });
15519
17360
  return;
15520
17361
  }
@@ -15565,12 +17406,12 @@ function runDevServer(evaluators, opts) {
15565
17406
  ...evaluator,
15566
17407
  data: evalData.data,
15567
17408
  scores: evaluator.scores.concat(
15568
- _nullishCoalesce(_optionalChain([scores, 'optionalAccess', _262 => _262.map, 'call', _263 => _263(
17409
+ _nullishCoalesce(_optionalChain([scores, 'optionalAccess', _344 => _344.map, 'call', _345 => _345(
15569
17410
  (score) => makeScorer(
15570
17411
  state,
15571
17412
  score.name,
15572
17413
  score.function_id,
15573
- _optionalChain([req, 'access', _264 => _264.ctx, 'optionalAccess', _265 => _265.projectId])
17414
+ _optionalChain([req, 'access', _346 => _346.ctx, 'optionalAccess', _347 => _347.projectId])
15574
17415
  )
15575
17416
  )]), () => ( []))
15576
17417
  ),