braintrust 3.19.0 → 3.21.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 (88) hide show
  1. package/NOTICE +20 -0
  2. package/README.md +2 -0
  3. package/dev/dist/index.d.mts +309 -199
  4. package/dev/dist/index.d.ts +309 -199
  5. package/dev/dist/index.js +2833 -987
  6. package/dev/dist/index.mjs +2294 -448
  7. package/dist/apply-auto-instrumentation.js +781 -199
  8. package/dist/apply-auto-instrumentation.mjs +588 -6
  9. package/dist/auto-instrumentations/bundler/esbuild.cjs +594 -2
  10. package/dist/auto-instrumentations/bundler/esbuild.d.mts +2 -2
  11. package/dist/auto-instrumentations/bundler/esbuild.d.ts +2 -2
  12. package/dist/auto-instrumentations/bundler/esbuild.mjs +3 -3
  13. package/dist/auto-instrumentations/bundler/next.cjs +594 -2
  14. package/dist/auto-instrumentations/bundler/next.mjs +4 -4
  15. package/dist/auto-instrumentations/bundler/rollup.cjs +594 -2
  16. package/dist/auto-instrumentations/bundler/rollup.d.mts +2 -2
  17. package/dist/auto-instrumentations/bundler/rollup.d.ts +2 -2
  18. package/dist/auto-instrumentations/bundler/rollup.mjs +3 -3
  19. package/dist/auto-instrumentations/bundler/vite.cjs +594 -2
  20. package/dist/auto-instrumentations/bundler/vite.d.mts +2 -2
  21. package/dist/auto-instrumentations/bundler/vite.d.ts +2 -2
  22. package/dist/auto-instrumentations/bundler/vite.mjs +3 -3
  23. package/dist/auto-instrumentations/bundler/webpack-loader.cjs +593 -9
  24. package/dist/auto-instrumentations/bundler/webpack-loader.d.ts +68 -1
  25. package/dist/auto-instrumentations/bundler/webpack.cjs +594 -2
  26. package/dist/auto-instrumentations/bundler/webpack.d.mts +2 -2
  27. package/dist/auto-instrumentations/bundler/webpack.d.ts +2 -2
  28. package/dist/auto-instrumentations/bundler/webpack.mjs +4 -4
  29. package/dist/auto-instrumentations/{chunk-W4E36GIW.mjs → chunk-BRQX23KL.mjs} +16 -0
  30. package/dist/auto-instrumentations/chunk-M6DLIJ2Z.mjs +784 -0
  31. package/dist/auto-instrumentations/{chunk-K74TZGGM.mjs → chunk-T6J4C7LX.mjs} +1 -1
  32. package/dist/auto-instrumentations/{chunk-S4374IP6.mjs → chunk-TKRPRPGD.mjs} +4 -6
  33. package/dist/auto-instrumentations/chunk-VT6DDNKM.mjs +856 -0
  34. package/dist/auto-instrumentations/hook.mjs +749 -45
  35. package/dist/auto-instrumentations/index.cjs +16 -0
  36. package/dist/auto-instrumentations/index.d.mts +2 -3
  37. package/dist/auto-instrumentations/index.d.ts +2 -3
  38. package/dist/auto-instrumentations/index.mjs +1 -1
  39. package/dist/auto-instrumentations/loader/cjs-patch.cjs +578 -4
  40. package/dist/auto-instrumentations/loader/cjs-patch.d.mts +1 -1
  41. package/dist/auto-instrumentations/loader/cjs-patch.d.ts +1 -1
  42. package/dist/auto-instrumentations/loader/cjs-patch.mjs +3 -7
  43. package/dist/auto-instrumentations/loader/esm-hook.mjs +2 -6
  44. package/dist/auto-instrumentations/{plugin-D7nDswtC.d.mts → plugin-D0KHwSJv.d.mts} +1 -1
  45. package/dist/auto-instrumentations/{plugin-D7nDswtC.d.ts → plugin-G6fgxk1b.d.ts} +1 -1
  46. package/dist/auto-instrumentations/types-RNPaKi9o.d.mts +70 -0
  47. package/dist/auto-instrumentations/types-RNPaKi9o.d.ts +70 -0
  48. package/dist/browser.d.mts +1369 -848
  49. package/dist/browser.d.ts +1369 -848
  50. package/dist/browser.js +2735 -473
  51. package/dist/browser.mjs +2735 -473
  52. package/dist/{chunk-LPC4W2WX.js → chunk-BFGIH2ZJ.js} +4 -0
  53. package/dist/{chunk-37RLJF2U.js → chunk-FY7DAKA5.js} +3149 -1273
  54. package/dist/{chunk-Y7W7WP6H.mjs → chunk-KMGUTPB7.mjs} +4 -0
  55. package/dist/{chunk-VEQ2PCMC.mjs → chunk-O2P765XK.mjs} +2399 -523
  56. package/dist/cli.js +2267 -412
  57. package/dist/edge-light.d.mts +1 -1
  58. package/dist/edge-light.d.ts +1 -1
  59. package/dist/edge-light.js +2735 -473
  60. package/dist/edge-light.mjs +2735 -473
  61. package/dist/index.d.mts +1848 -1327
  62. package/dist/index.d.ts +1848 -1327
  63. package/dist/index.js +754 -352
  64. package/dist/index.mjs +448 -46
  65. package/dist/instrumentation/index.d.mts +119 -21
  66. package/dist/instrumentation/index.d.ts +119 -21
  67. package/dist/instrumentation/index.js +2345 -512
  68. package/dist/instrumentation/index.mjs +2344 -512
  69. package/dist/vitest-evals-reporter.js +16 -16
  70. package/dist/vitest-evals-reporter.mjs +2 -2
  71. package/dist/workerd.d.mts +1 -1
  72. package/dist/workerd.d.ts +1 -1
  73. package/dist/workerd.js +2735 -473
  74. package/dist/workerd.mjs +2735 -473
  75. package/licenses/import-in-the-middle/LICENSE +201 -0
  76. package/licenses/import-in-the-middle/LICENSE-3rdparty.csv +4 -0
  77. package/licenses/import-in-the-middle/NOTICE +34 -0
  78. package/licenses/orchestrion-js/LICENSE +202 -0
  79. package/licenses/orchestrion-js/LICENSE-3rdparty.csv +8 -0
  80. package/licenses/orchestrion-js/NOTICE +3 -0
  81. package/licenses/require-in-the-middle/LICENSE +23 -0
  82. package/package.json +13 -4
  83. package/util/dist/index.d.mts +1 -0
  84. package/util/dist/index.d.ts +1 -0
  85. package/util/dist/index.js +4 -4
  86. package/util/dist/index.mjs +2 -2
  87. package/dist/auto-instrumentations/chunk-J57YF7WS.mjs +0 -208
  88. package/dist/auto-instrumentations/chunk-QFMACSOL.mjs +0 -280
package/dist/workerd.mjs CHANGED
@@ -285,8 +285,291 @@ var UUIDGenerator = class extends IDGenerator {
285
285
  return true;
286
286
  }
287
287
  };
288
+ function generateHexId(bytes) {
289
+ let result = "";
290
+ for (let i = 0; i < bytes; i++) {
291
+ result += Math.floor(Math.random() * 256).toString(16).padStart(2, "0");
292
+ }
293
+ return result;
294
+ }
295
+ var OTELIDGenerator = class extends IDGenerator {
296
+ getSpanId() {
297
+ return generateHexId(8);
298
+ }
299
+ getTraceId() {
300
+ return generateHexId(16);
301
+ }
302
+ shareRootSpanId() {
303
+ return false;
304
+ }
305
+ };
306
+ function parseEnvBool(name) {
307
+ const raw = isomorph_default.getEnv(name);
308
+ if (raw === void 0 || raw === null) {
309
+ return false;
310
+ }
311
+ const normalized = raw.trim().toLowerCase();
312
+ return normalized === "true" || normalized === "1" || normalized === "yes" || normalized === "y" || normalized === "on";
313
+ }
314
+ var _warnedLegacyUuidConflict = false;
315
+ function resolveUseLegacyUuidIds() {
316
+ const legacy = parseEnvBool("BRAINTRUST_LEGACY_IDS");
317
+ if (parseEnvBool("BRAINTRUST_OTEL_COMPAT")) {
318
+ if (legacy && !_warnedLegacyUuidConflict) {
319
+ _warnedLegacyUuidConflict = true;
320
+ debugLogger.warn(
321
+ "BRAINTRUST_LEGACY_IDS is ignored because BRAINTRUST_OTEL_COMPAT requires OpenTelemetry-compatible hex span IDs. Using hex IDs."
322
+ );
323
+ }
324
+ return false;
325
+ }
326
+ return legacy;
327
+ }
288
328
  function getIdGenerator() {
289
- return globalThis.BRAINTRUST_ID_GENERATOR !== void 0 ? new globalThis.BRAINTRUST_ID_GENERATOR() : new UUIDGenerator();
329
+ if (globalThis.BRAINTRUST_ID_GENERATOR !== void 0) {
330
+ return new globalThis.BRAINTRUST_ID_GENERATOR();
331
+ }
332
+ return resolveUseLegacyUuidIds() ? new UUIDGenerator() : new OTELIDGenerator();
333
+ }
334
+
335
+ // src/propagation.ts
336
+ var TRACEPARENT_HEADER = "traceparent";
337
+ var TRACESTATE_HEADER = "tracestate";
338
+ var BAGGAGE_HEADER = "baggage";
339
+ var BRAINTRUST_PARENT_KEY = "braintrust.parent";
340
+ var DEFAULT_TRACE_FLAGS = "01";
341
+ var TRACEPARENT_RE = /^00-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/;
342
+ var ZERO_TRACE_ID = "0".repeat(32);
343
+ var ZERO_SPAN_ID = "0".repeat(16);
344
+ var MAX_BAGGAGE_LENGTH = 8192;
345
+ var MAX_BAGGAGE_MEMBERS = 64;
346
+ var _utf8Encoder = new TextEncoder();
347
+ function utf8ByteLength(value) {
348
+ return _utf8Encoder.encode(value).length;
349
+ }
350
+ function capBaggageToMemberBoundary(value) {
351
+ const totalBytes = utf8ByteLength(value);
352
+ const withinBytes = totalBytes <= MAX_BAGGAGE_LENGTH;
353
+ let commaCount = 0;
354
+ for (let i = 0; i < value.length; i++) {
355
+ if (value.charCodeAt(i) === 44) {
356
+ commaCount++;
357
+ }
358
+ }
359
+ const withinMembers = commaCount < MAX_BAGGAGE_MEMBERS;
360
+ if (withinBytes && withinMembers) {
361
+ return value;
362
+ }
363
+ const kept = [];
364
+ let length = 0;
365
+ for (const rawMember of value.split(",")) {
366
+ if (kept.length >= MAX_BAGGAGE_MEMBERS) {
367
+ break;
368
+ }
369
+ const cost = utf8ByteLength(rawMember) + (kept.length ? 1 : 0);
370
+ if (length + cost > MAX_BAGGAGE_LENGTH) {
371
+ break;
372
+ }
373
+ kept.push(rawMember);
374
+ length += cost;
375
+ }
376
+ if (!kept.length) {
377
+ return "";
378
+ }
379
+ return kept.join(",");
380
+ }
381
+ function isTraceContextHeaderTupleArray(value) {
382
+ return Array.isArray(value) && value.every(
383
+ (item) => Array.isArray(item) && typeof item[0] === "string" && typeof item[1] === "string"
384
+ );
385
+ }
386
+ function isListHeader(name) {
387
+ const lowered = name.toLowerCase();
388
+ return lowered === BAGGAGE_HEADER || lowered === TRACESTATE_HEADER;
389
+ }
390
+ function headerValueToString(value, name) {
391
+ if (value === void 0 || value === null) {
392
+ return void 0;
393
+ }
394
+ if (Array.isArray(value)) {
395
+ const stringValues = value.filter((item) => {
396
+ return typeof item === "string";
397
+ });
398
+ if (!stringValues.length) {
399
+ return void 0;
400
+ }
401
+ return isListHeader(name) ? stringValues.join(",") : stringValues[0];
402
+ }
403
+ return typeof value === "string" ? value : String(value);
404
+ }
405
+ function getHeader(headers, name) {
406
+ if (!headers) {
407
+ return void 0;
408
+ }
409
+ if (isTraceContextHeaderTupleArray(headers)) {
410
+ const lowered2 = name.toLowerCase();
411
+ const matches = headers.filter(([key]) => key.toLowerCase() === lowered2).map(([, value]) => value);
412
+ if (!matches.length) {
413
+ return void 0;
414
+ }
415
+ return headerValueToString(matches, name);
416
+ }
417
+ const getter = headers.get;
418
+ if (typeof getter === "function") {
419
+ try {
420
+ const value = headerValueToString(getter.call(headers, name), name);
421
+ if (value !== void 0) {
422
+ return value;
423
+ }
424
+ } catch {
425
+ }
426
+ }
427
+ const nodeGetter = headers.getHeader;
428
+ if (typeof nodeGetter === "function") {
429
+ try {
430
+ const value = headerValueToString(nodeGetter.call(headers, name), name);
431
+ if (value !== void 0) {
432
+ return value;
433
+ }
434
+ } catch {
435
+ }
436
+ }
437
+ const headerBag = headers;
438
+ const exact = headerValueToString(headerBag[name], name);
439
+ if (exact !== void 0) {
440
+ return exact;
441
+ }
442
+ const lowered = name.toLowerCase();
443
+ for (const key of Object.keys(headers)) {
444
+ if (key !== name && key.toLowerCase() === lowered) {
445
+ const value = headerValueToString(headerBag[key], name);
446
+ if (value !== void 0) {
447
+ return value;
448
+ }
449
+ }
450
+ }
451
+ return void 0;
452
+ }
453
+ function isHex(value, length) {
454
+ if (typeof value !== "string" || value.length !== length) {
455
+ return false;
456
+ }
457
+ for (let i = 0; i < value.length; i++) {
458
+ const c = value[i];
459
+ const isDigit = c >= "0" && c <= "9";
460
+ const isLowerHex = c >= "a" && c <= "f";
461
+ if (!isDigit && !isLowerHex) {
462
+ return false;
463
+ }
464
+ }
465
+ return true;
466
+ }
467
+ function parseTraceparent(value) {
468
+ if (!value || typeof value !== "string") {
469
+ return void 0;
470
+ }
471
+ const match = TRACEPARENT_RE.exec(value.trim());
472
+ if (!match) {
473
+ return void 0;
474
+ }
475
+ const traceId = match[1];
476
+ const spanId = match[2];
477
+ const traceFlags = match[3];
478
+ if (traceId === ZERO_TRACE_ID || spanId === ZERO_SPAN_ID) {
479
+ return void 0;
480
+ }
481
+ return { traceId, spanId, traceFlags };
482
+ }
483
+ function formatTraceparent(traceId, spanId, traceFlags = DEFAULT_TRACE_FLAGS) {
484
+ if (!isHex(traceId, 32) || traceId === ZERO_TRACE_ID) {
485
+ return void 0;
486
+ }
487
+ if (!isHex(spanId, 16) || spanId === ZERO_SPAN_ID) {
488
+ return void 0;
489
+ }
490
+ const flags = isHex(traceFlags, 2) ? traceFlags : DEFAULT_TRACE_FLAGS;
491
+ return `00-${traceId}-${spanId}-${flags}`;
492
+ }
493
+ function percentEncode(value) {
494
+ return encodeURIComponent(value);
495
+ }
496
+ function percentDecode(value) {
497
+ if (!value.includes("%")) {
498
+ return value;
499
+ }
500
+ try {
501
+ return decodeURIComponent(value);
502
+ } catch {
503
+ return value;
504
+ }
505
+ }
506
+ function parseBaggage(value) {
507
+ const result = {};
508
+ if (!value || typeof value !== "string") {
509
+ return result;
510
+ }
511
+ const bounded = capBaggageToMemberBoundary(value);
512
+ for (let member of bounded.split(",")) {
513
+ member = member.trim();
514
+ if (!member || !member.includes("=")) {
515
+ continue;
516
+ }
517
+ member = member.split(";", 1)[0];
518
+ const eq = member.indexOf("=");
519
+ const key = percentDecode(member.slice(0, eq).trim());
520
+ const val = member.slice(eq + 1).trim();
521
+ if (!key) {
522
+ continue;
523
+ }
524
+ result[key] = percentDecode(val);
525
+ }
526
+ return result;
527
+ }
528
+ function mergeBaggage(existing, braintrustParent) {
529
+ let btMember = void 0;
530
+ if (braintrustParent) {
531
+ const encodedKey = percentEncode(BRAINTRUST_PARENT_KEY);
532
+ const encodedVal = percentEncode(String(braintrustParent));
533
+ btMember = `${encodedKey}=${encodedVal}`;
534
+ if (utf8ByteLength(btMember) > MAX_BAGGAGE_LENGTH) {
535
+ btMember = void 0;
536
+ }
537
+ }
538
+ let byteBudget = MAX_BAGGAGE_LENGTH;
539
+ let memberBudget = MAX_BAGGAGE_MEMBERS;
540
+ if (btMember !== void 0) {
541
+ byteBudget -= utf8ByteLength(btMember) + 1;
542
+ memberBudget -= 1;
543
+ }
544
+ const relayed = [];
545
+ let length = 0;
546
+ if (existing && typeof existing === "string") {
547
+ for (const rawMember of existing.split(",")) {
548
+ const member = rawMember.trim();
549
+ if (!member || !member.includes("=")) {
550
+ continue;
551
+ }
552
+ const keyPart = member.split(";", 1)[0].split("=", 1)[0];
553
+ const key = percentDecode(keyPart.trim());
554
+ if (key === BRAINTRUST_PARENT_KEY) {
555
+ continue;
556
+ }
557
+ if (relayed.length >= memberBudget) {
558
+ break;
559
+ }
560
+ const cost = utf8ByteLength(member) + (relayed.length ? 1 : 0);
561
+ if (length + cost > byteBudget) {
562
+ break;
563
+ }
564
+ relayed.push(member);
565
+ length += cost;
566
+ }
567
+ }
568
+ const members = btMember !== void 0 ? [...relayed, btMember] : relayed;
569
+ if (!members.length) {
570
+ return void 0;
571
+ }
572
+ return members.join(",");
290
573
  }
291
574
 
292
575
  // util/db_fields.ts
@@ -894,7 +1177,7 @@ var SpanComponentsV3 = class _SpanComponentsV3 {
894
1177
  case 3 /* PLAYGROUND_LOGS */:
895
1178
  return { prompt_session_id: this.data.object_id, log_id: "x" };
896
1179
  default:
897
- const _ = this.data.object_type;
1180
+ this.data.object_type;
898
1181
  throw new Error("Impossible");
899
1182
  }
900
1183
  }
@@ -1423,7 +1706,7 @@ var SpanComponentsV4 = class _SpanComponentsV4 {
1423
1706
  case 3 /* PLAYGROUND_LOGS */:
1424
1707
  return { prompt_session_id: this.data.object_id, log_id: "x" };
1425
1708
  default:
1426
- const _ = this.data.object_type;
1709
+ this.data.object_type;
1427
1710
  throw new Error(`Invalid object_type ${this.data.object_type}`);
1428
1711
  }
1429
1712
  }
@@ -1602,7 +1885,8 @@ var AclObjectType = z6.union([
1602
1885
  "role",
1603
1886
  "org_member",
1604
1887
  "project_log",
1605
- "org_project"
1888
+ "org_project",
1889
+ "org_audit_logs"
1606
1890
  ]),
1607
1891
  z6.null()
1608
1892
  ]);
@@ -1628,6 +1912,17 @@ var Acl = z6.object({
1628
1912
  _object_org_id: z6.string().uuid(),
1629
1913
  created: z6.union([z6.string(), z6.null()]).optional()
1630
1914
  });
1915
+ var Agent = z6.object({
1916
+ id: z6.string().uuid(),
1917
+ project_id: z6.string().uuid(),
1918
+ user_id: z6.string().uuid(),
1919
+ created: z6.union([z6.string(), z6.null()]).optional(),
1920
+ name: z6.string(),
1921
+ slug: z6.string(),
1922
+ kind: z6.string(),
1923
+ description: z6.union([z6.string(), z6.null()]).optional(),
1924
+ metadata: z6.union([z6.object({}).partial().passthrough(), z6.null()]).optional()
1925
+ });
1631
1926
  var AISecret = z6.object({
1632
1927
  id: z6.string().uuid(),
1633
1928
  created: z6.union([z6.string(), z6.null()]).optional(),
@@ -1774,6 +2069,7 @@ var AttachmentStatus = z6.object({
1774
2069
  upload_status: UploadStatus,
1775
2070
  error_message: z6.string().optional()
1776
2071
  });
2072
+ var AutomationStatus = z6.enum(["active", "paused"]);
1777
2073
  var FunctionTypeEnum = z6.enum([
1778
2074
  "llm",
1779
2075
  "scorer",
@@ -1819,7 +2115,9 @@ var TopicMapData = z6.object({
1819
2115
  topic_names: z6.record(z6.string()).optional(),
1820
2116
  generation_settings: TopicMapGenerationSettings.optional(),
1821
2117
  disable_reconciliation: z6.boolean().optional(),
1822
- distance_threshold: z6.number().optional()
2118
+ distance_threshold: z6.number().optional(),
2119
+ btql_filter: z6.string().optional(),
2120
+ automation_btql_filter: z6.string().optional()
1823
2121
  });
1824
2122
  var BatchedFacetData = z6.object({
1825
2123
  type: z6.literal("batched_facet"),
@@ -2102,7 +2400,7 @@ var DatasetEvent = z6.object({
2102
2400
  origin: ObjectReferenceNullish.optional(),
2103
2401
  comments: z6.union([z6.array(z6.unknown()), z6.null()]).optional(),
2104
2402
  audit_data: z6.union([z6.array(z6.unknown()), z6.null()]).optional(),
2105
- facets: z6.union([z6.object({}).partial().passthrough(), z6.null()]).optional(),
2403
+ facets: z6.union([z6.record(z6.union([z6.string(), z6.null()])), z6.null()]).optional(),
2106
2404
  classifications: z6.union([
2107
2405
  z6.record(
2108
2406
  z6.array(
@@ -2254,7 +2552,7 @@ var ExperimentEvent = z6.object({
2254
2552
  origin: ObjectReferenceNullish.optional(),
2255
2553
  comments: z6.union([z6.array(z6.unknown()), z6.null()]).optional(),
2256
2554
  audit_data: z6.union([z6.array(z6.unknown()), z6.null()]).optional(),
2257
- facets: z6.union([z6.object({}).partial().passthrough(), z6.null()]).optional(),
2555
+ facets: z6.union([z6.record(z6.union([z6.string(), z6.null()])), z6.null()]).optional(),
2258
2556
  classifications: z6.union([
2259
2557
  z6.record(
2260
2558
  z6.array(
@@ -2392,7 +2690,8 @@ var PromptParserNullish = z6.union([
2392
2690
  use_cot: z6.boolean(),
2393
2691
  choice_scores: z6.record(z6.number().gte(0).lte(1)).optional(),
2394
2692
  choice: z6.array(z6.string()).optional(),
2395
- allow_no_match: z6.boolean().optional()
2693
+ allow_no_match: z6.boolean().optional(),
2694
+ allow_skip: z6.boolean().optional()
2396
2695
  }),
2397
2696
  z6.null()
2398
2697
  ]);
@@ -2722,6 +3021,9 @@ var Group = z6.object({
2722
3021
  var GroupScope = z6.object({
2723
3022
  type: z6.literal("group"),
2724
3023
  group_by: z6.string(),
3024
+ interval_seconds: z6.number().gte(1).optional(),
3025
+ max_traces: z6.number().int().gte(1).lte(64).optional(),
3026
+ placement: z6.enum(["first", "each"]),
2725
3027
  idle_seconds: z6.number().optional()
2726
3028
  });
2727
3029
  var IfExists = z6.enum(["error", "ignore", "replace"]);
@@ -2870,6 +3172,10 @@ var RetentionObjectType = z6.enum([
2870
3172
  "experiment",
2871
3173
  "dataset"
2872
3174
  ]);
3175
+ var TopicAutomationFacetModel = z6.union([
3176
+ z6.enum(["brain-facet-latest", "brain-facet-1", "brain-facet-2"]),
3177
+ z6.null()
3178
+ ]);
2873
3179
  var TopicMapFunctionAutomation = z6.object({
2874
3180
  function: SavedFunctionId.and(z6.unknown()),
2875
3181
  btql_filter: z6.union([z6.string(), z6.null()]).optional()
@@ -2882,7 +3188,9 @@ var TopicAutomationDataScope = z6.union([
2882
3188
  ]);
2883
3189
  var TopicAutomationConfig = z6.object({
2884
3190
  event_type: z6.literal("topic"),
3191
+ status: AutomationStatus.optional(),
2885
3192
  sampling_rate: z6.number().gte(0).lte(1),
3193
+ facet_model: TopicAutomationFacetModel.optional(),
2886
3194
  facet_functions: z6.array(SavedFunctionId),
2887
3195
  topic_map_functions: z6.array(TopicMapFunctionAutomation),
2888
3196
  scope: z6.union([SpanScope, TraceScope, GroupScope, z6.null()]).optional(),
@@ -2896,6 +3204,19 @@ var TopicAutomationConfig = z6.object({
2896
3204
  z6.null()
2897
3205
  ]).optional()
2898
3206
  });
3207
+ var TopicDigestAutomationConfig = z6.object({
3208
+ event_type: z6.literal("topic_digest"),
3209
+ status: AutomationStatus.optional(),
3210
+ window_seconds: z6.number().int().gte(3600).lte(2592e3).optional().default(86400),
3211
+ scheduled_time_minutes_utc: z6.number().int().gte(0).lte(1439),
3212
+ action: z6.object({
3213
+ type: z6.literal("slack"),
3214
+ workspace_id: z6.string(),
3215
+ channel: z6.string(),
3216
+ message_template: z6.string().optional()
3217
+ }),
3218
+ topic_map_function_ids: z6.array(z6.string()).max(10).optional()
3219
+ });
2899
3220
  var ProjectAutomation = z6.object({
2900
3221
  id: z6.string().uuid(),
2901
3222
  project_id: z6.string().uuid(),
@@ -2920,6 +3241,7 @@ var ProjectAutomation = z6.object({
2920
3241
  }),
2921
3242
  z6.object({
2922
3243
  event_type: z6.literal("btql_export"),
3244
+ status: AutomationStatus.optional(),
2923
3245
  export_definition: z6.union([
2924
3246
  z6.object({ type: z6.literal("log_traces") }),
2925
3247
  z6.object({ type: z6.literal("log_spans") }),
@@ -2942,6 +3264,21 @@ var ProjectAutomation = z6.object({
2942
3264
  ]),
2943
3265
  batch_size: z6.union([z6.number(), z6.null()]).optional()
2944
3266
  }),
3267
+ z6.object({
3268
+ event_type: z6.literal("async_query"),
3269
+ status: AutomationStatus.optional(),
3270
+ created_by_user_id: z6.string().uuid(),
3271
+ object_type: z6.enum([
3272
+ "project_logs",
3273
+ "experiment",
3274
+ "dataset",
3275
+ "playground_logs"
3276
+ ]),
3277
+ object_id: z6.string(),
3278
+ query: z6.string(),
3279
+ format: z6.literal("jsonl"),
3280
+ batch_size: z6.union([z6.number(), z6.null()]).optional()
3281
+ }),
2945
3282
  z6.object({
2946
3283
  event_type: z6.literal("retention"),
2947
3284
  object_type: RetentionObjectType,
@@ -2960,7 +3297,8 @@ var ProjectAutomation = z6.object({
2960
3297
  })
2961
3298
  ])
2962
3299
  }),
2963
- TopicAutomationConfig
3300
+ TopicAutomationConfig,
3301
+ TopicDigestAutomationConfig
2964
3302
  ])
2965
3303
  });
2966
3304
  var ProjectLogsEvent = z6.object({
@@ -2999,7 +3337,7 @@ var ProjectLogsEvent = z6.object({
2999
3337
  comments: z6.union([z6.array(z6.unknown()), z6.null()]).optional(),
3000
3338
  audit_data: z6.union([z6.array(z6.unknown()), z6.null()]).optional(),
3001
3339
  _async_scoring_state: z6.unknown().optional(),
3002
- facets: z6.union([z6.object({}).partial().passthrough(), z6.null()]).optional(),
3340
+ facets: z6.union([z6.record(z6.union([z6.string(), z6.null()])), z6.null()]).optional(),
3003
3341
  classifications: z6.union([
3004
3342
  z6.record(
3005
3343
  z6.array(
@@ -3048,11 +3386,34 @@ var ProjectScoreCategories = z6.union([
3048
3386
  z6.array(z6.string()),
3049
3387
  z6.null()
3050
3388
  ]);
3389
+ var ProjectScoreCondition = z6.union([
3390
+ z6.object({
3391
+ when: z6.object({
3392
+ clauses: z6.union([z6.array(z6.string()), z6.null()]),
3393
+ subspan_clauses: z6.union([z6.array(z6.string()), z6.null()]),
3394
+ trace_clauses: z6.union([z6.array(z6.string()), z6.null()])
3395
+ }).partial(),
3396
+ behavior: z6.literal("hidden").optional().default("hidden")
3397
+ }),
3398
+ z6.null()
3399
+ ]);
3051
3400
  var ProjectScoreConfig = z6.union([
3052
3401
  z6.object({
3053
3402
  multi_select: z6.union([z6.boolean(), z6.null()]),
3054
3403
  destination: z6.union([z6.string(), z6.null()]),
3055
- online: OnlineScoreConfig
3404
+ visibility: z6.union([
3405
+ z6.object({
3406
+ users: z6.union([z6.array(z6.string()), z6.null()]),
3407
+ groups: z6.union([z6.array(z6.string()), z6.null()])
3408
+ }).partial(),
3409
+ z6.null()
3410
+ ]),
3411
+ online: OnlineScoreConfig,
3412
+ condition: ProjectScoreCondition,
3413
+ object_types: z6.union([
3414
+ z6.array(z6.enum(["project_logs", "dataset", "experiment"])),
3415
+ z6.null()
3416
+ ])
3056
3417
  }).partial(),
3057
3418
  z6.null()
3058
3419
  ]);
@@ -3237,8 +3598,7 @@ var User = z6.object({
3237
3598
  family_name: z6.union([z6.string(), z6.null()]).optional(),
3238
3599
  email: z6.union([z6.string(), z6.null()]).optional(),
3239
3600
  avatar_url: z6.union([z6.string(), z6.null()]).optional(),
3240
- created: z6.union([z6.string(), z6.null()]).optional(),
3241
- last_active_at: z6.union([z6.number(), z6.null()]).optional()
3601
+ created: z6.union([z6.string(), z6.null()]).optional()
3242
3602
  });
3243
3603
  var ViewDataSearch = z6.union([
3244
3604
  z6.object({
@@ -4527,7 +4887,10 @@ var BraintrustContextManager = class extends ContextManager {
4527
4887
  }
4528
4888
  };
4529
4889
  function getSpanComponentsClass() {
4530
- return globalThis.BRAINTRUST_SPAN_COMPONENT ? globalThis.BRAINTRUST_SPAN_COMPONENT : SpanComponentsV3;
4890
+ if (globalThis.BRAINTRUST_SPAN_COMPONENT) {
4891
+ return globalThis.BRAINTRUST_SPAN_COMPONENT;
4892
+ }
4893
+ return resolveUseLegacyUuidIds() ? SpanComponentsV3 : SpanComponentsV4;
4531
4894
  }
4532
4895
  function getContextManager() {
4533
4896
  return globalThis.BRAINTRUST_CONTEXT_MANAGER ? new globalThis.BRAINTRUST_CONTEXT_MANAGER() : new BraintrustContextManager();
@@ -4563,6 +4926,9 @@ var NoopSpan = class {
4563
4926
  async export() {
4564
4927
  return "";
4565
4928
  }
4929
+ inject(carrier) {
4930
+ return carrier ?? {};
4931
+ }
4566
4932
  async permalink() {
4567
4933
  return NOOP_SPAN_PERMALINK;
4568
4934
  }
@@ -4613,6 +4979,10 @@ var loginSchema = z8.strictObject({
4613
4979
  debugLogLevelDisabled: z8.boolean().optional()
4614
4980
  });
4615
4981
  var stateNonce = 0;
4982
+ var V1_PROXY_SUFFIX = "/v1/proxy";
4983
+ function normalizeProxyConnUrl(proxyUrl) {
4984
+ return proxyUrl.endsWith(V1_PROXY_SUFFIX) ? proxyUrl.slice(0, proxyUrl.length - V1_PROXY_SUFFIX.length) : proxyUrl;
4985
+ }
4616
4986
  var BraintrustState = class _BraintrustState {
4617
4987
  constructor(loginParams) {
4618
4988
  this.loginParams = loginParams;
@@ -4883,7 +5253,10 @@ var BraintrustState = class _BraintrustState {
4883
5253
  if (!this.proxyUrl) {
4884
5254
  throw new Error("Must initialize proxyUrl before requesting proxyConn");
4885
5255
  }
4886
- this._proxyConn = new HTTPConnection(this.proxyUrl, this.fetch);
5256
+ this._proxyConn = new HTTPConnection(
5257
+ normalizeProxyConnUrl(this.proxyUrl),
5258
+ this.fetch
5259
+ );
4887
5260
  }
4888
5261
  return this._proxyConn;
4889
5262
  }
@@ -5641,7 +6014,7 @@ function updateSpan({
5641
6014
  ...event
5642
6015
  }) {
5643
6016
  const resolvedState = state ?? _globalState;
5644
- const components = getSpanComponentsClass().fromStr(exported);
6017
+ const components = SpanComponentsV4.fromStr(exported);
5645
6018
  if (!components.data.row_id) {
5646
6019
  throw new Error("Exported span must have a row id");
5647
6020
  }
@@ -5741,7 +6114,7 @@ async function permalink(slug, opts) {
5741
6114
  return state.appUrl;
5742
6115
  };
5743
6116
  try {
5744
- const components = getSpanComponentsClass().fromStr(slug);
6117
+ const components = SpanComponentsV4.fromStr(slug);
5745
6118
  const object_type = spanObjectTypeV3ToString(components.data.object_type);
5746
6119
  const [orgName, appUrl, object_id] = await Promise.all([
5747
6120
  getOrgName(),
@@ -5765,35 +6138,47 @@ function startSpanParentArgs(args) {
5765
6138
  let argParentObjectId = void 0;
5766
6139
  let argParentSpanIds = void 0;
5767
6140
  let argPropagatedEvent = void 0;
5768
- if (args.parent) {
6141
+ let argPropagatedState = void 0;
6142
+ const { parentSlug, propagatedState: parentPropagatedState } = normalizeParent(args.parent, args.state);
6143
+ if (parentSlug) {
5769
6144
  if (args.parentSpanIds) {
5770
6145
  throw new Error("Cannot specify both parent and parentSpanIds");
5771
6146
  }
5772
- const parentComponents = getSpanComponentsClass().fromStr(args.parent);
6147
+ const parentComponents = SpanComponentsV4.fromStr(parentSlug);
5773
6148
  if (args.parentObjectType !== parentComponents.data.object_type) {
5774
6149
  throw new Error(
5775
6150
  `Mismatch between expected span parent object type ${args.parentObjectType} and provided type ${parentComponents.data.object_type}`
5776
6151
  );
5777
6152
  }
5778
6153
  argParentObjectId = args.parentObjectId;
5779
- if (parentComponents.data.row_id) {
6154
+ if (parentComponents.data.row_id && parentSpanIdsUsable(
6155
+ parentComponents.data.span_id,
6156
+ parentComponents.data.root_span_id
6157
+ )) {
5780
6158
  argParentSpanIds = {
5781
6159
  spanId: parentComponents.data.span_id,
5782
6160
  rootSpanId: parentComponents.data.root_span_id
5783
6161
  };
5784
6162
  }
5785
6163
  argPropagatedEvent = args.propagatedEvent ?? (parentComponents.data.propagated_event ?? void 0);
6164
+ const propagatedState = args.propagatedState ?? parentPropagatedState;
6165
+ if (propagatedState) {
6166
+ const { braintrustParent: _ignoredBraintrustParent, ...w3cState } = propagatedState;
6167
+ argPropagatedState = w3cState;
6168
+ }
5786
6169
  } else {
5787
6170
  argParentObjectId = args.parentObjectId;
5788
6171
  argParentSpanIds = args.parentSpanIds;
5789
6172
  argPropagatedEvent = args.propagatedEvent;
6173
+ argPropagatedState = args.propagatedState;
5790
6174
  }
5791
6175
  return {
5792
6176
  parentObjectType: args.parentObjectType,
5793
6177
  parentObjectId: argParentObjectId,
5794
6178
  parentComputeObjectMetadataArgs: args.parentComputeObjectMetadataArgs,
5795
6179
  parentSpanIds: argParentSpanIds,
5796
- propagatedEvent: argPropagatedEvent
6180
+ propagatedEvent: argPropagatedEvent,
6181
+ propagatedState: argPropagatedState
5797
6182
  };
5798
6183
  }
5799
6184
  var Logger = class {
@@ -5994,6 +6379,22 @@ var Logger = class {
5994
6379
  _getLinkBaseUrl() {
5995
6380
  return _getLinkBaseUrl(this.state, this._linkArgs);
5996
6381
  }
6382
+ /**
6383
+ * Return this logger's Braintrust parent string (`project_id:<id>` or
6384
+ * `project_name:<name>`) for the `braintrust.parent` baggage entry, or
6385
+ * undefined when it cannot be determined synchronously.
6386
+ */
6387
+ _getOtelParent() {
6388
+ const id = this.computeMetadataArgs?.project_id || this.lazyId.getSync().value;
6389
+ if (id) {
6390
+ return `project_id:${id}`;
6391
+ }
6392
+ const name = this.computeMetadataArgs?.project_name;
6393
+ if (name) {
6394
+ return `project_name:${name}`;
6395
+ }
6396
+ return void 0;
6397
+ }
5997
6398
  };
5998
6399
  function castLogger(logger, asyncFlush) {
5999
6400
  if (logger === void 0) return void 0;
@@ -6088,12 +6489,12 @@ function stringifyWithOverflowMeta(item) {
6088
6489
  object_ids: pickLogs3OverflowObjectIds(record),
6089
6490
  is_delete: record[OBJECT_DELETE_FIELD] === true,
6090
6491
  input_row: {
6091
- byte_size: utf8ByteLength(str)
6492
+ byte_size: utf8ByteLength2(str)
6092
6493
  }
6093
6494
  }
6094
6495
  };
6095
6496
  }
6096
- function utf8ByteLength(value) {
6497
+ function utf8ByteLength2(value) {
6097
6498
  if (typeof TextEncoder !== "undefined") {
6098
6499
  return new TextEncoder().encode(value).length;
6099
6500
  }
@@ -6481,7 +6882,7 @@ var HTTPBackgroundLogger = class _HTTPBackgroundLogger {
6481
6882
  }) {
6482
6883
  const conn = await this.apiConn.get();
6483
6884
  const dataStr = constructLogs3Data(items);
6484
- const payloadBytes = utf8ByteLength(dataStr);
6885
+ const payloadBytes = utf8ByteLength2(dataStr);
6485
6886
  const useOverflow = canUseOverflow && payloadBytes > maxRequestSize;
6486
6887
  if (this.allPublishPayloadsDir) {
6487
6888
  await _HTTPBackgroundLogger.writePayloadToDir({
@@ -7102,6 +7503,8 @@ function initDataset(projectOrOptions, optionalOptions) {
7102
7503
  const normalizedVersion = selection.version;
7103
7504
  const normalizedEnvironment = selection.environment;
7104
7505
  const normalizedSnapshotName = selection.snapshotName;
7506
+ const cliInternalBtql = globalThis.__bt_eval_internal_btql;
7507
+ const internalBtql = cliInternalBtql === void 0 ? _internal_btql : _internal_btql === void 0 ? cliInternalBtql : isObject(_internal_btql) ? { ...cliInternalBtql, ..._internal_btql } : _internal_btql;
7105
7508
  const state = stateArg ?? _globalState;
7106
7509
  const lazyMetadata = new LazyValue(
7107
7510
  async () => {
@@ -7153,7 +7556,7 @@ function initDataset(projectOrOptions, optionalOptions) {
7153
7556
  lazyMetadata,
7154
7557
  typeof resolvedVersion === "string" ? resolvedVersion : void 0,
7155
7558
  legacy,
7156
- _internal_btql,
7559
+ internalBtql,
7157
7560
  resolvedVersion instanceof LazyValue || normalizedEnvironment !== void 0 || normalizedSnapshotName !== void 0 ? {
7158
7561
  ...resolvedVersion instanceof LazyValue ? {
7159
7562
  lazyPinnedVersion: resolvedVersion
@@ -7617,23 +8020,285 @@ function currentSpan(options) {
7617
8020
  const state = options?.state ?? _globalState;
7618
8021
  return state.contextManager.getCurrentSpan() ?? NOOP_SPAN;
7619
8022
  }
7620
- function getSpanParentObject(options) {
8023
+ function getSpanParentObjectAndPropagatedState(options) {
7621
8024
  const state = options?.state ?? _globalState;
7622
8025
  const parentSpan = currentSpan({ state });
7623
8026
  if (!Object.is(parentSpan, NOOP_SPAN)) {
7624
- return parentSpan;
8027
+ return { parentObject: parentSpan, propagatedState: void 0 };
8028
+ }
8029
+ const parent = options?.parent ?? state.currentParent.getStore();
8030
+ const { parentSlug, propagatedState } = normalizeParent(parent, state);
8031
+ if (parentSlug) {
8032
+ return {
8033
+ parentObject: SpanComponentsV4.fromStr(parentSlug),
8034
+ propagatedState
8035
+ };
7625
8036
  }
7626
- const parentStr = options?.parent ?? state.currentParent.getStore();
7627
- if (parentStr) return getSpanComponentsClass().fromStr(parentStr);
7628
8037
  const experiment = currentExperiment();
7629
8038
  if (experiment) {
7630
- return experiment;
8039
+ return { parentObject: experiment, propagatedState: void 0 };
7631
8040
  }
7632
8041
  const logger = currentLogger(options);
7633
8042
  if (logger) {
7634
- return logger;
8043
+ return { parentObject: logger, propagatedState: void 0 };
8044
+ }
8045
+ return { parentObject: NOOP_SPAN, propagatedState: void 0 };
8046
+ }
8047
+ function getSpanParentObject(options) {
8048
+ return getSpanParentObjectAndPropagatedState(options).parentObject;
8049
+ }
8050
+ function currentBraintrustParent(state) {
8051
+ const resolvedState = state ?? _globalState;
8052
+ const experiment = currentExperiment({ state: resolvedState });
8053
+ if (experiment) {
8054
+ try {
8055
+ return experiment._getOtelParent() ?? void 0;
8056
+ } catch {
8057
+ return void 0;
8058
+ }
8059
+ }
8060
+ const logger = currentLogger({ state: resolvedState });
8061
+ if (logger) {
8062
+ try {
8063
+ return logger._getOtelParent() ?? void 0;
8064
+ } catch {
8065
+ return void 0;
8066
+ }
8067
+ }
8068
+ return void 0;
8069
+ }
8070
+ function braintrustParentToComponents(braintrustParent) {
8071
+ if (!braintrustParent) {
8072
+ return void 0;
8073
+ }
8074
+ if (braintrustParent.startsWith("project_id:")) {
8075
+ const objectId = braintrustParent.slice("project_id:".length);
8076
+ return objectId ? {
8077
+ objectType: 2 /* PROJECT_LOGS */,
8078
+ objectId,
8079
+ computeArgs: void 0
8080
+ } : void 0;
8081
+ }
8082
+ if (braintrustParent.startsWith("project_name:")) {
8083
+ const name = braintrustParent.slice("project_name:".length);
8084
+ return name ? {
8085
+ objectType: 2 /* PROJECT_LOGS */,
8086
+ objectId: void 0,
8087
+ computeArgs: { project_name: name }
8088
+ } : void 0;
8089
+ }
8090
+ if (braintrustParent.startsWith("experiment_id:")) {
8091
+ const objectId = braintrustParent.slice("experiment_id:".length);
8092
+ return objectId ? {
8093
+ objectType: 1 /* EXPERIMENT */,
8094
+ objectId,
8095
+ computeArgs: void 0
8096
+ } : void 0;
8097
+ }
8098
+ return void 0;
8099
+ }
8100
+ function isMutableHeaderTupleArray(carrier) {
8101
+ return Array.isArray(carrier) && carrier.every((item) => Array.isArray(item) && typeof item[0] === "string");
8102
+ }
8103
+ function setHeader(carrier, name, value) {
8104
+ if (isMutableHeaderTupleArray(carrier)) {
8105
+ const lowered2 = name.toLowerCase();
8106
+ for (let i = carrier.length - 1; i >= 0; i--) {
8107
+ if (carrier[i][0].toLowerCase() === lowered2) {
8108
+ carrier.splice(i, 1);
8109
+ }
8110
+ }
8111
+ carrier.push([name, value]);
8112
+ return;
8113
+ }
8114
+ const setter = carrier.set;
8115
+ if (typeof setter === "function") {
8116
+ const deleter = carrier.delete;
8117
+ if (typeof deleter === "function") {
8118
+ try {
8119
+ deleter.call(carrier, name);
8120
+ } catch {
8121
+ }
8122
+ }
8123
+ setter.call(carrier, name, value);
8124
+ return;
8125
+ }
8126
+ const nodeSetter = carrier.setHeader;
8127
+ if (typeof nodeSetter === "function") {
8128
+ const remover = carrier.removeHeader;
8129
+ if (typeof remover === "function") {
8130
+ try {
8131
+ remover.call(carrier, name);
8132
+ } catch {
8133
+ }
8134
+ }
8135
+ nodeSetter.call(carrier, name, value);
8136
+ return;
8137
+ }
8138
+ const headerSetter = carrier.header;
8139
+ if (typeof headerSetter === "function") {
8140
+ const deleter = carrier.delete;
8141
+ if (typeof deleter === "function") {
8142
+ try {
8143
+ deleter.call(carrier, name);
8144
+ } catch {
8145
+ }
8146
+ }
8147
+ const remover = carrier.removeHeader;
8148
+ if (typeof remover === "function") {
8149
+ try {
8150
+ remover.call(carrier, name);
8151
+ } catch {
8152
+ }
8153
+ }
8154
+ headerSetter.call(carrier, name, value);
8155
+ return;
8156
+ }
8157
+ const headerBag = carrier;
8158
+ const lowered = name.toLowerCase();
8159
+ for (const key of Object.keys(headerBag)) {
8160
+ if (key !== name && key.toLowerCase() === lowered) {
8161
+ delete headerBag[key];
8162
+ }
8163
+ }
8164
+ headerBag[name] = value;
8165
+ }
8166
+ function deleteHeader(carrier, name) {
8167
+ const lowered = name.toLowerCase();
8168
+ if (isMutableHeaderTupleArray(carrier)) {
8169
+ for (let i = carrier.length - 1; i >= 0; i--) {
8170
+ if (carrier[i][0].toLowerCase() === lowered) {
8171
+ carrier.splice(i, 1);
8172
+ }
8173
+ }
8174
+ return;
8175
+ }
8176
+ const deleter = carrier.delete;
8177
+ if (typeof deleter === "function") {
8178
+ try {
8179
+ deleter.call(carrier, name);
8180
+ return;
8181
+ } catch {
8182
+ }
8183
+ }
8184
+ const remover = carrier.removeHeader;
8185
+ if (typeof remover === "function") {
8186
+ try {
8187
+ remover.call(carrier, name);
8188
+ return;
8189
+ } catch {
8190
+ }
7635
8191
  }
7636
- return NOOP_SPAN;
8192
+ const headerBag = carrier;
8193
+ for (const key of Object.keys(headerBag)) {
8194
+ if (key.toLowerCase() === lowered) {
8195
+ delete headerBag[key];
8196
+ }
8197
+ }
8198
+ }
8199
+ function _injectIntoCarrier(carrier, args) {
8200
+ const traceFlags = args.propagatedState?.traceFlags;
8201
+ const traceparent = traceFlags ? formatTraceparent(args.traceId, args.spanId, traceFlags) : formatTraceparent(args.traceId, args.spanId);
8202
+ if (traceparent === void 0) {
8203
+ return;
8204
+ }
8205
+ setHeader(carrier, TRACEPARENT_HEADER, traceparent);
8206
+ const tracestate = args.propagatedState?.tracestate;
8207
+ if (tracestate) {
8208
+ setHeader(carrier, TRACESTATE_HEADER, tracestate);
8209
+ }
8210
+ const existing = getHeader(carrier, BAGGAGE_HEADER);
8211
+ const baggageValue = mergeBaggage(existing, args.braintrustParent);
8212
+ if (baggageValue !== void 0) {
8213
+ setHeader(carrier, BAGGAGE_HEADER, baggageValue);
8214
+ } else if (existing !== void 0) {
8215
+ deleteHeader(carrier, BAGGAGE_HEADER);
8216
+ }
8217
+ }
8218
+ function injectTraceContext(carrier, options) {
8219
+ const resolvedCarrier = carrier ?? {};
8220
+ const span = options?.span ?? currentSpan({ state: options?.state });
8221
+ try {
8222
+ return span.inject(resolvedCarrier);
8223
+ } catch (e) {
8224
+ debugLogger.warn(`Error injecting trace context: ${e}`);
8225
+ return resolvedCarrier;
8226
+ }
8227
+ }
8228
+ function extractTraceContextFromHeaders(headers) {
8229
+ if (!headers) {
8230
+ return void 0;
8231
+ }
8232
+ const traceparent = getHeader(headers, TRACEPARENT_HEADER);
8233
+ if (!traceparent || parseTraceparent(traceparent) === void 0) {
8234
+ return void 0;
8235
+ }
8236
+ const context = { [TRACEPARENT_HEADER]: traceparent };
8237
+ const baggageValue = getHeader(headers, BAGGAGE_HEADER);
8238
+ if (baggageValue) {
8239
+ context[BAGGAGE_HEADER] = baggageValue;
8240
+ }
8241
+ const tracestate = getHeader(headers, TRACESTATE_HEADER);
8242
+ if (tracestate) {
8243
+ context[TRACESTATE_HEADER] = tracestate;
8244
+ }
8245
+ return context;
8246
+ }
8247
+ function resolveW3cParent(context, state) {
8248
+ const traceparent = getHeader(context, TRACEPARENT_HEADER);
8249
+ const parsed = traceparent ? parseTraceparent(traceparent) : void 0;
8250
+ if (parsed === void 0) {
8251
+ return { parentSlug: void 0, propagatedState: void 0 };
8252
+ }
8253
+ const { traceId, spanId, traceFlags } = parsed;
8254
+ let braintrustParent = void 0;
8255
+ const baggageValue = getHeader(context, BAGGAGE_HEADER);
8256
+ if (baggageValue) {
8257
+ braintrustParent = parseBaggage(baggageValue)[BRAINTRUST_PARENT_KEY];
8258
+ }
8259
+ if (!braintrustParent) {
8260
+ braintrustParent = currentBraintrustParent(state);
8261
+ }
8262
+ if (!braintrustParent) {
8263
+ debugLogger.warn(
8264
+ "Received traceparent without a braintrust.parent and no active logger/experiment; cannot route the trace. Starting a fresh local span instead."
8265
+ );
8266
+ return { parentSlug: void 0, propagatedState: void 0 };
8267
+ }
8268
+ const parsedParent = braintrustParentToComponents(braintrustParent);
8269
+ if (parsedParent === void 0) {
8270
+ debugLogger.warn(
8271
+ `Invalid braintrust.parent: ${JSON.stringify(braintrustParent)}`
8272
+ );
8273
+ return { parentSlug: void 0, propagatedState: void 0 };
8274
+ }
8275
+ const { objectType, objectId, computeArgs } = parsedParent;
8276
+ const tracestate = getHeader(context, TRACESTATE_HEADER);
8277
+ const slug = new SpanComponentsV4({
8278
+ object_type: objectType,
8279
+ ...computeArgs ? { compute_object_metadata_args: computeArgs } : { object_id: objectId },
8280
+ row_id: "bt-propagation",
8281
+ // non-empty to enable span_id/root_span_id
8282
+ span_id: spanId,
8283
+ root_span_id: traceId
8284
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
8285
+ }).toStr();
8286
+ return {
8287
+ parentSlug: slug,
8288
+ propagatedState: { tracestate, traceFlags, braintrustParent }
8289
+ };
8290
+ }
8291
+ function normalizeParent(parent, state) {
8292
+ if (parent && typeof parent === "object") {
8293
+ return resolveW3cParent(parent, state);
8294
+ }
8295
+ return {
8296
+ parentSlug: parent ?? void 0,
8297
+ propagatedState: void 0
8298
+ };
8299
+ }
8300
+ function parentSpanIdsUsable(spanId, rootSpanId) {
8301
+ return Boolean(spanId) && Boolean(rootSpanId);
7637
8302
  }
7638
8303
  function logError(span, error) {
7639
8304
  let errorMessage = "<error>";
@@ -7841,19 +8506,23 @@ function setFetch(fetch2) {
7841
8506
  }
7842
8507
  function startSpanAndIsLogger(args) {
7843
8508
  const state = args?.state ?? _globalState;
7844
- const parentObject = getSpanParentObject({
8509
+ const { parentObject, propagatedState } = getSpanParentObjectAndPropagatedState({
7845
8510
  asyncFlush: args?.asyncFlush,
7846
8511
  parent: args?.parent,
7847
8512
  state
7848
8513
  });
7849
8514
  if (parentObject instanceof SpanComponentsV3 || parentObject instanceof SpanComponentsV4) {
7850
- const parentSpanIds = parentObject.data.row_id ? {
8515
+ const parentSpanIds = parentObject.data.row_id && parentSpanIdsUsable(
8516
+ parentObject.data.span_id,
8517
+ parentObject.data.root_span_id
8518
+ ) ? {
7851
8519
  spanId: parentObject.data.span_id,
7852
8520
  rootSpanId: parentObject.data.root_span_id
7853
8521
  } : void 0;
8522
+ const { parent: _ignoredParent, ...spanArgs } = args ?? {};
7854
8523
  const span = new SpanImpl({
7855
8524
  state,
7856
- ...args,
8525
+ ...spanArgs,
7857
8526
  parentObjectType: parentObject.data.object_type,
7858
8527
  parentObjectId: new LazyValue(
7859
8528
  spanComponentsToObjectIdLambda(state, parentObject)
@@ -7861,7 +8530,8 @@ function startSpanAndIsLogger(args) {
7861
8530
  parentComputeObjectMetadataArgs: parentObject.data.compute_object_metadata_args ?? void 0,
7862
8531
  parentSpanIds,
7863
8532
  propagatedEvent: args?.propagatedEvent ?? // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
7864
- (parentObject.data.propagated_event ?? void 0)
8533
+ (parentObject.data.propagated_event ?? void 0),
8534
+ propagatedState
7865
8535
  });
7866
8536
  return {
7867
8537
  span,
@@ -8150,11 +8820,12 @@ function validateAndSanitizeExperimentLogFullArgs(event, hasDataset) {
8150
8820
  var DEFAULT_FETCH_BATCH_SIZE = 1e3;
8151
8821
  var MAX_BTQL_ITERATIONS = 1e4;
8152
8822
  var ObjectFetcher = class {
8153
- constructor(objectType, pinnedVersion, mutateRecord, _internal_btql) {
8823
+ constructor(objectType, pinnedVersion, mutateRecord, _internal_btql, _internalBrainstoreRealtime = true) {
8154
8824
  this.objectType = objectType;
8155
8825
  this.pinnedVersion = pinnedVersion;
8156
8826
  this.mutateRecord = mutateRecord;
8157
8827
  this._internal_btql = _internal_btql;
8828
+ this._internalBrainstoreRealtime = _internalBrainstoreRealtime;
8158
8829
  }
8159
8830
  _fetchedData = void 0;
8160
8831
  get id() {
@@ -8213,7 +8884,7 @@ var ObjectFetcher = class {
8213
8884
  ...internalBtqlWithoutReservedQueryKeys
8214
8885
  },
8215
8886
  use_columnstore: false,
8216
- brainstore_realtime: true,
8887
+ brainstore_realtime: this._internalBrainstoreRealtime,
8217
8888
  query_source: `js_sdk_object_fetcher_${this.objectType}`,
8218
8889
  ...this.pinnedVersion !== void 0 ? {
8219
8890
  version: this.pinnedVersion
@@ -8562,6 +9233,15 @@ View complete results in Braintrust or run experiment.summarize() again.`
8562
9233
  object_id: await this.id
8563
9234
  }).toStr();
8564
9235
  }
9236
+ /**
9237
+ * Return this experiment's Braintrust parent string (`experiment_id:<id>`) for
9238
+ * the `braintrust.parent` baggage entry, or undefined when it cannot be
9239
+ * determined synchronously.
9240
+ */
9241
+ _getOtelParent() {
9242
+ const id = this.lazyId.getSync().value;
9243
+ return id ? `experiment_id:${id}` : void 0;
9244
+ }
8565
9245
  /**
8566
9246
  * Flush any pending rows to the server.
8567
9247
  */
@@ -8604,7 +9284,8 @@ var ReadonlyExperiment = class extends ObjectFetcher {
8604
9284
  async *asDataset(options) {
8605
9285
  const records = this.fetch(options);
8606
9286
  for await (const record of records) {
8607
- if (record.root_span_id !== record.span_id) {
9287
+ const isRoot = record.is_root ?? record.root_span_id === record.span_id;
9288
+ if (!isRoot) {
8608
9289
  continue;
8609
9290
  }
8610
9291
  const { output, expected: expectedRecord, metadata } = record;
@@ -8666,9 +9347,16 @@ var SpanImpl = class _SpanImpl {
8666
9347
  _spanId;
8667
9348
  _rootSpanId;
8668
9349
  _spanParents;
9350
+ // Inbound W3C trace-context state (tracestate + raw traceparent flags) to
9351
+ // forward on outbound propagation. Captured at the span that received it (via
9352
+ // extractTraceContextFromHeaders) and inherited by all subspans, so that any
9353
+ // inject() within the trace re-emits the upstream state unchanged, per the W3C
9354
+ // Trace Context spec. Not interpreted.
9355
+ _propagatedState;
8669
9356
  kind = "span";
8670
9357
  constructor(args) {
8671
9358
  this._state = args.state;
9359
+ this._propagatedState = args.propagatedState;
8672
9360
  const spanAttributes = args.spanAttributes ?? {};
8673
9361
  const rawEvent = args.event ?? {};
8674
9362
  const type = args.type ?? (args.parentSpanIds ? void 0 : args.defaultRootType);
@@ -8784,7 +9472,7 @@ var SpanImpl = class _SpanImpl {
8784
9472
  tags: partialRecord.tags,
8785
9473
  span_id: this._spanId,
8786
9474
  span_parents: this._spanParents,
8787
- is_root: this._spanId === this._rootSpanId,
9475
+ is_root: !this._spanParents || this._spanParents.length === 0,
8788
9476
  span_attributes: partialRecord.span_attributes
8789
9477
  };
8790
9478
  this._state.spanCache.queueWrite(
@@ -8846,7 +9534,8 @@ var SpanImpl = class _SpanImpl {
8846
9534
  parentObjectId: this.parentObjectId,
8847
9535
  parentComputeObjectMetadataArgs: this.parentComputeObjectMetadataArgs,
8848
9536
  parentSpanIds,
8849
- propagatedEvent: args?.propagatedEvent ?? this.propagatedEvent
9537
+ propagatedEvent: args?.propagatedEvent ?? this.propagatedEvent,
9538
+ propagatedState: this._propagatedState
8850
9539
  })
8851
9540
  });
8852
9541
  }
@@ -8865,7 +9554,8 @@ var SpanImpl = class _SpanImpl {
8865
9554
  parentObjectId: this.parentObjectId,
8866
9555
  parentComputeObjectMetadataArgs: this.parentComputeObjectMetadataArgs,
8867
9556
  parentSpanIds,
8868
- propagatedEvent: args?.propagatedEvent ?? this.propagatedEvent
9557
+ propagatedEvent: args?.propagatedEvent ?? this.propagatedEvent,
9558
+ propagatedState: this._propagatedState
8869
9559
  }),
8870
9560
  spanId
8871
9561
  });
@@ -8893,6 +9583,42 @@ var SpanImpl = class _SpanImpl {
8893
9583
  propagated_event: this.propagatedEvent
8894
9584
  }).toStr();
8895
9585
  }
9586
+ /**
9587
+ * Return this span's Braintrust parent string (`project_id:<id>`,
9588
+ * `project_name:<name>`, or `experiment_id:<id>`) for the `braintrust.parent`
9589
+ * baggage entry, or undefined when it cannot be determined synchronously.
9590
+ */
9591
+ _getOtelParent() {
9592
+ if (this.parentObjectType === 2 /* PROJECT_LOGS */) {
9593
+ const id = this.parentComputeObjectMetadataArgs?.project_id || this.parentObjectId.getSync().value;
9594
+ const name = this.parentComputeObjectMetadataArgs?.project_name;
9595
+ if (id) {
9596
+ return `project_id:${id}`;
9597
+ } else if (name) {
9598
+ return `project_name:${name}`;
9599
+ }
9600
+ } else if (this.parentObjectType === 1 /* EXPERIMENT */) {
9601
+ const id = this.parentComputeObjectMetadataArgs?.experiment_id || this.parentObjectId.getSync().value;
9602
+ if (id) {
9603
+ return `experiment_id:${id}`;
9604
+ }
9605
+ }
9606
+ return void 0;
9607
+ }
9608
+ inject(carrier) {
9609
+ const resolvedCarrier = carrier ?? {};
9610
+ try {
9611
+ _injectIntoCarrier(resolvedCarrier, {
9612
+ traceId: this._rootSpanId,
9613
+ spanId: this._spanId,
9614
+ braintrustParent: this._getOtelParent() ?? this._propagatedState?.braintrustParent,
9615
+ propagatedState: this._propagatedState
9616
+ });
9617
+ } catch (e) {
9618
+ debugLogger.warn(`Error injecting trace context: ${e}`);
9619
+ }
9620
+ return resolvedCarrier;
9621
+ }
8896
9622
  async permalink() {
8897
9623
  return await permalink(await this.export(), {
8898
9624
  state: this._state
@@ -9028,6 +9754,7 @@ var Dataset2 = class extends ObjectFetcher {
9028
9754
  _internal_btql
9029
9755
  );
9030
9756
  this.state = state;
9757
+ void this.__braintrust_dataset_marker;
9031
9758
  this.lazyMetadata = lazyMetadata;
9032
9759
  this.lazyPinnedVersion = pinState?.lazyPinnedVersion;
9033
9760
  this.pinnedEnvironment = pinState?.pinnedEnvironment;
@@ -9545,6 +10272,7 @@ var Prompt2 = class _Prompt {
9545
10272
  this.metadata = metadata;
9546
10273
  this.defaults = defaults;
9547
10274
  this.noTrace = noTrace;
10275
+ void this.__braintrust_prompt_marker;
9548
10276
  }
9549
10277
  parsedPromptData;
9550
10278
  hasParsedPromptData = false;
@@ -9781,6 +10509,7 @@ var Prompt2 = class _Prompt {
9781
10509
  var RemoteEvalParameters = class {
9782
10510
  constructor(metadata) {
9783
10511
  this.metadata = metadata;
10512
+ void this.__braintrust_parameters_marker;
9784
10513
  }
9785
10514
  __braintrust_parameters_marker = true;
9786
10515
  get id() {
@@ -9917,6 +10646,7 @@ var _exportsForTestingOnly = {
9917
10646
  isAsyncGeneratorFunction,
9918
10647
  resetIdGenStateForTests,
9919
10648
  validateTags,
10649
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
9920
10650
  isomorph: isomorph_default
9921
10651
  // Expose isomorph for build type detection
9922
10652
  };
@@ -10868,6 +11598,22 @@ function runStreamingCompletionHook(args) {
10868
11598
  );
10869
11599
  }
10870
11600
  }
11601
+ function runStreamingErrorHook(args) {
11602
+ if (!args.config.onError) {
11603
+ return;
11604
+ }
11605
+ try {
11606
+ args.config.onError({
11607
+ channelName: args.channelName,
11608
+ error: args.error,
11609
+ event: args.event,
11610
+ span: args.span,
11611
+ startTime: args.startTime
11612
+ });
11613
+ } catch (error) {
11614
+ debugLogger.error(`Error in onError hook for ${args.channelName}:`, error);
11615
+ }
11616
+ }
10871
11617
  function traceAsyncChannel(channel2, config) {
10872
11618
  const tracingChannel2 = channel2.tracingChannel();
10873
11619
  const states = /* @__PURE__ */ new WeakMap();
@@ -11029,6 +11775,14 @@ function traceStreamingChannel(channel2, config) {
11029
11775
  }
11030
11776
  },
11031
11777
  onError: (error) => {
11778
+ runStreamingErrorHook({
11779
+ channelName,
11780
+ config,
11781
+ error,
11782
+ event: asyncEndEvent,
11783
+ span,
11784
+ startTime
11785
+ });
11032
11786
  span.log({
11033
11787
  error: error.message
11034
11788
  });
@@ -11086,6 +11840,17 @@ function traceStreamingChannel(channel2, config) {
11086
11840
  }
11087
11841
  },
11088
11842
  error: (event) => {
11843
+ const spanData = states.get(event);
11844
+ if (spanData) {
11845
+ runStreamingErrorHook({
11846
+ channelName,
11847
+ config,
11848
+ error: event.error,
11849
+ event,
11850
+ span: spanData.span,
11851
+ startTime: spanData.startTime
11852
+ });
11853
+ }
11089
11854
  logErrorAndEnd(states, event);
11090
11855
  }
11091
11856
  };
@@ -13448,14 +14213,45 @@ function serializeAISDKToolsForLogging(tools) {
13448
14213
  return serialized;
13449
14214
  }
13450
14215
 
14216
+ // src/vendor-sdk-types/ai-sdk-v7-telemetry.ts
14217
+ var BRAINTRUST_AI_SDK_V7_OPERATION_KEY = /* @__PURE__ */ Symbol.for(
14218
+ "braintrust.ai-sdk.v7.telemetry-operation-key"
14219
+ );
14220
+
14221
+ // src/wrappers/ai-sdk/workflow-agent-context.ts
14222
+ var workflowAgentWrapperSpans = /* @__PURE__ */ new Map();
14223
+ function registerWorkflowAgentWrapperSpan(span) {
14224
+ if (span.spanId) {
14225
+ workflowAgentWrapperSpans.set(span.spanId, span);
14226
+ }
14227
+ }
14228
+ function unregisterWorkflowAgentWrapperSpan(span) {
14229
+ if (span.spanId) {
14230
+ workflowAgentWrapperSpans.delete(span.spanId);
14231
+ }
14232
+ }
14233
+ function currentWorkflowAgentWrapperSpan() {
14234
+ const parentSpanIds = _internalGetGlobalState().contextManager.getParentSpanIds()?.spanParents ?? [];
14235
+ for (const parentSpanId of parentSpanIds) {
14236
+ const span = workflowAgentWrapperSpans.get(parentSpanId);
14237
+ if (span) {
14238
+ return span;
14239
+ }
14240
+ }
14241
+ return void 0;
14242
+ }
14243
+
13451
14244
  // src/wrappers/ai-sdk/telemetry.ts
13452
14245
  function braintrustAISDKTelemetry() {
13453
14246
  const operations = /* @__PURE__ */ new Map();
14247
+ const operationKeysByCallId = /* @__PURE__ */ new Map();
14248
+ const workflowOperationKeyStore = isomorph_default.newAsyncLocalStorage();
13454
14249
  const modelSpans = /* @__PURE__ */ new Map();
13455
14250
  const objectSpans = /* @__PURE__ */ new Map();
13456
14251
  const embedSpans = /* @__PURE__ */ new Map();
13457
14252
  const rerankSpans = /* @__PURE__ */ new Map();
13458
14253
  const toolSpans = /* @__PURE__ */ new Map();
14254
+ let workflowAgentOperationCounter = 0;
13459
14255
  const runSafely = (name, callback) => {
13460
14256
  try {
13461
14257
  callback();
@@ -13463,42 +14259,333 @@ function braintrustAISDKTelemetry() {
13463
14259
  console.error(`Error in Braintrust AI SDK telemetry ${name}:`, error);
13464
14260
  }
13465
14261
  };
13466
- const startChildSpan = (callId, name, type, event) => {
13467
- const parent = operations.get(callId)?.span;
14262
+ const startChildSpan = (operationKey, name, type, event) => {
14263
+ const parent = operations.get(operationKey)?.span;
13468
14264
  const spanArgs = {
13469
14265
  name,
13470
14266
  spanAttributes: { type },
13471
14267
  ...event ? { event } : {}
13472
14268
  };
13473
14269
  const span = parent ? parent.startSpan(spanArgs) : startSpan(spanArgs);
13474
- const state = operations.get(callId);
14270
+ const state = operations.get(operationKey);
13475
14271
  if (state && type === "llm" /* LLM */) {
13476
14272
  state.hadModelChild = true;
13477
14273
  }
13478
14274
  return span;
13479
14275
  };
14276
+ const registerOperation = (state) => {
14277
+ operations.set(state.operationKey, state);
14278
+ const keys = operationKeysByCallId.get(state.callId) ?? [];
14279
+ keys.push(state.operationKey);
14280
+ operationKeysByCallId.set(state.callId, keys);
14281
+ };
14282
+ const deleteOperation = (operationKey) => {
14283
+ const state = operations.get(operationKey);
14284
+ if (!state) {
14285
+ return;
14286
+ }
14287
+ operations.delete(operationKey);
14288
+ if (workflowOperationKeyStore.getStore() === operationKey) {
14289
+ workflowOperationKeyStore.enterWith(void 0);
14290
+ }
14291
+ const keys = operationKeysByCallId.get(state.callId);
14292
+ if (!keys) {
14293
+ return;
14294
+ }
14295
+ const index = keys.indexOf(operationKey);
14296
+ if (index >= 0) {
14297
+ keys.splice(index, 1);
14298
+ }
14299
+ if (keys.length === 0) {
14300
+ operationKeysByCallId.delete(state.callId);
14301
+ }
14302
+ };
14303
+ const explicitOperationKey = (event) => {
14304
+ if (!isObject(event)) {
14305
+ return void 0;
14306
+ }
14307
+ const key = event[BRAINTRUST_AI_SDK_V7_OPERATION_KEY];
14308
+ return typeof key === "string" ? key : void 0;
14309
+ };
14310
+ const createOperationKey = (event, operationName) => {
14311
+ const explicit = explicitOperationKey(event);
14312
+ if (explicit) {
14313
+ return explicit;
14314
+ }
14315
+ if (operationName === "WorkflowAgent.stream") {
14316
+ workflowAgentOperationCounter += 1;
14317
+ return `${event.callId}:${workflowAgentOperationCounter}`;
14318
+ }
14319
+ return event.callId;
14320
+ };
14321
+ const operationKeyForCallId = (callId, mode = "active") => {
14322
+ const keys = operationKeysByCallId.get(callId);
14323
+ if (!keys || keys.length === 0) {
14324
+ return operations.has(callId) ? callId : void 0;
14325
+ }
14326
+ if (keys.length === 1) {
14327
+ return keys[0];
14328
+ }
14329
+ const wrapperSpan = currentWorkflowAgentWrapperSpan();
14330
+ if (wrapperSpan?.spanId) {
14331
+ const key = keys.find(
14332
+ (candidate) => operations.get(candidate)?.span.spanId === wrapperSpan.spanId
14333
+ );
14334
+ if (key) {
14335
+ return key;
14336
+ }
14337
+ }
14338
+ const workflowOperationKey = workflowOperationKeyStore.getStore();
14339
+ if (workflowOperationKey && keys.includes(workflowOperationKey)) {
14340
+ return workflowOperationKey;
14341
+ }
14342
+ if (callId === "workflow-agent") {
14343
+ return void 0;
14344
+ }
14345
+ return mode === "finish" ? keys[0] : keys[keys.length - 1];
14346
+ };
14347
+ const operationKeyFromEvent = (event, mode = "active") => {
14348
+ const explicit = explicitOperationKey(event);
14349
+ if (explicit && operations.has(explicit)) {
14350
+ return explicit;
14351
+ }
14352
+ if (isObject(event)) {
14353
+ const callId = event.callId;
14354
+ if (typeof callId === "string") {
14355
+ const operationKey = operationKeyForCallId(callId, mode);
14356
+ if (operationKey) {
14357
+ return operationKey;
14358
+ }
14359
+ const workflowOperationKey2 = workflowOperationKeyStore.getStore();
14360
+ if (workflowOperationKey2 && operations.has(workflowOperationKey2)) {
14361
+ return workflowOperationKey2;
14362
+ }
14363
+ return callId === "workflow-agent" ? void 0 : callId;
14364
+ }
14365
+ }
14366
+ const workflowOperationKey = workflowOperationKeyStore.getStore();
14367
+ if (workflowOperationKey && operations.has(workflowOperationKey)) {
14368
+ return workflowOperationKey;
14369
+ }
14370
+ const wrapperSpan = currentWorkflowAgentWrapperSpan();
14371
+ if (wrapperSpan?.spanId) {
14372
+ for (const [operationKey, state] of operations) {
14373
+ if (state.operationName === "WorkflowAgent.stream" && state.span.spanId === wrapperSpan.spanId) {
14374
+ return operationKey;
14375
+ }
14376
+ }
14377
+ }
14378
+ const workflowAgentKeys = operationKeysByCallId.get("workflow-agent");
14379
+ if (workflowAgentKeys?.length === 1) {
14380
+ return workflowAgentKeys[0];
14381
+ }
14382
+ if (operations.size === 1) {
14383
+ return operations.keys().next().value;
14384
+ }
14385
+ return void 0;
14386
+ };
14387
+ const closeOpenChildSpans = (operationKey, error) => {
14388
+ const openModelSpans = modelSpans.get(operationKey);
14389
+ if (openModelSpans) {
14390
+ for (const span of openModelSpans) {
14391
+ if (error !== void 0) {
14392
+ logError(span, error);
14393
+ }
14394
+ span.end();
14395
+ }
14396
+ modelSpans.delete(operationKey);
14397
+ }
14398
+ const openObjectSpan = objectSpans.get(operationKey);
14399
+ if (openObjectSpan) {
14400
+ if (error !== void 0) {
14401
+ logError(openObjectSpan, error);
14402
+ }
14403
+ openObjectSpan.end();
14404
+ objectSpans.delete(operationKey);
14405
+ }
14406
+ for (const [embedCallId, embedState] of embedSpans) {
14407
+ if (embedState.operationKey === operationKey) {
14408
+ if (error !== void 0) {
14409
+ logError(embedState.span, error);
14410
+ }
14411
+ embedState.span.end();
14412
+ embedSpans.delete(embedCallId);
14413
+ }
14414
+ }
14415
+ const openRerankSpan = rerankSpans.get(operationKey);
14416
+ if (openRerankSpan) {
14417
+ if (error !== void 0) {
14418
+ logError(openRerankSpan, error);
14419
+ }
14420
+ openRerankSpan.end();
14421
+ rerankSpans.delete(operationKey);
14422
+ }
14423
+ for (const [toolCallId, toolState] of toolSpans) {
14424
+ if (toolState.operationKey === operationKey) {
14425
+ if (error !== void 0) {
14426
+ logError(toolState.span, error);
14427
+ }
14428
+ toolState.span.end();
14429
+ toolSpans.delete(toolCallId);
14430
+ }
14431
+ }
14432
+ };
14433
+ const abortReasonFromEvent = (event) => {
14434
+ if (isObject(event)) {
14435
+ const abortEvent = event;
14436
+ if (abortEvent.error !== void 0) {
14437
+ return abortEvent.error;
14438
+ }
14439
+ if (abortEvent.reason !== void 0) {
14440
+ return abortEvent.reason;
14441
+ }
14442
+ }
14443
+ return new Error("AI SDK operation aborted");
14444
+ };
14445
+ const shouldSkipTelemetryChildren = (state) => state?.operationName === "WorkflowAgent.stream" && !state.ownsSpan;
14446
+ const onObjectStepEnd = (event) => {
14447
+ runSafely("onObjectStepEnd", () => {
14448
+ const operationKey = operationKeyFromEvent(event);
14449
+ const span = operationKey ? objectSpans.get(operationKey) : void 0;
14450
+ if (!operationKey || !span) {
14451
+ return;
14452
+ }
14453
+ const result = {
14454
+ ...event,
14455
+ text: event.objectText
14456
+ };
14457
+ span.log({
14458
+ ...shouldRecordOutputs(event) ? {
14459
+ output: processAISDKOutput(result, DEFAULT_DENY_OUTPUT_PATHS)
14460
+ } : {},
14461
+ metrics: extractTokenMetrics(result)
14462
+ });
14463
+ span.end();
14464
+ objectSpans.delete(operationKey);
14465
+ });
14466
+ };
14467
+ const onEmbedEnd = (event) => {
14468
+ runSafely("onEmbedEnd", () => {
14469
+ const state = embedSpans.get(event.embedCallId);
14470
+ if (!state) {
14471
+ return;
14472
+ }
14473
+ const result = {
14474
+ ...event,
14475
+ embeddings: event.embeddings
14476
+ };
14477
+ state.span.log({
14478
+ ...shouldRecordOutputs(event) ? {
14479
+ output: processAISDKEmbeddingOutput(
14480
+ result,
14481
+ DEFAULT_DENY_OUTPUT_PATHS
14482
+ )
14483
+ } : {},
14484
+ metrics: extractTokenMetrics(result)
14485
+ });
14486
+ state.span.end();
14487
+ embedSpans.delete(event.embedCallId);
14488
+ });
14489
+ };
14490
+ const onRerankEnd = (event) => {
14491
+ runSafely("onRerankEnd", () => {
14492
+ const operationKey = operationKeyFromEvent(event);
14493
+ const span = operationKey ? rerankSpans.get(operationKey) : void 0;
14494
+ if (!operationKey || !span) {
14495
+ return;
14496
+ }
14497
+ const result = {
14498
+ ranking: event.ranking?.map((entry) => ({
14499
+ originalIndex: entry.index,
14500
+ score: entry.relevanceScore
14501
+ }))
14502
+ };
14503
+ span.log({
14504
+ ...shouldRecordOutputs(event) ? {
14505
+ output: processAISDKRerankOutput(
14506
+ result,
14507
+ DEFAULT_DENY_OUTPUT_PATHS
14508
+ )
14509
+ } : {}
14510
+ });
14511
+ span.end();
14512
+ rerankSpans.delete(operationKey);
14513
+ });
14514
+ };
14515
+ const onEnd = (event) => {
14516
+ runSafely("onEnd", () => {
14517
+ const operationKey = operationKeyFromEvent(event, "finish");
14518
+ const state = operationKey ? operations.get(operationKey) : void 0;
14519
+ if (!state) {
14520
+ return;
14521
+ }
14522
+ if (!state.ownsSpan) {
14523
+ deleteOperation(state.operationKey);
14524
+ return;
14525
+ }
14526
+ const result = finishResult(event, state.operationName);
14527
+ const metrics = state.hadModelChild ? {} : extractTokenMetrics(result);
14528
+ const timeToFirstToken = state.operationName === "WorkflowAgent.stream" ? void 0 : extractTimeToFirstToken(result, state);
14529
+ if (timeToFirstToken !== void 0) {
14530
+ metrics.time_to_first_token = timeToFirstToken;
14531
+ }
14532
+ state.span.log({
14533
+ ...shouldRecordOutputs(event) ? {
14534
+ output: finishOutput(result, state.operationName)
14535
+ } : {},
14536
+ metrics
14537
+ });
14538
+ state.span.end();
14539
+ deleteOperation(state.operationKey);
14540
+ });
14541
+ };
13480
14542
  return {
13481
14543
  onStart(event) {
13482
14544
  runSafely("onStart", () => {
13483
14545
  const operationName = operationNameFromId(event.operationId);
13484
- const span = startSpan({
14546
+ const workflowAgent = operationName === "WorkflowAgent.stream";
14547
+ const wrapperSpan = workflowAgent ? currentWorkflowAgentWrapperSpan() : void 0;
14548
+ const ownsSpan = !wrapperSpan;
14549
+ const span = ownsSpan ? startSpan({
13485
14550
  name: operationName,
13486
14551
  spanAttributes: { type: "function" /* FUNCTION */ }
13487
- });
13488
- operations.set(event.callId, {
14552
+ }) : wrapperSpan;
14553
+ const operationKey = createOperationKey(event, operationName);
14554
+ registerOperation({
14555
+ callId: event.callId,
13489
14556
  hadModelChild: false,
14557
+ loggedInput: false,
13490
14558
  operationName,
14559
+ operationKey,
14560
+ ownsSpan,
13491
14561
  span,
13492
14562
  startTime: getCurrentUnixTimestamp()
13493
14563
  });
13494
- const metadata = metadataFromEvent(event);
14564
+ if (!ownsSpan) {
14565
+ return;
14566
+ }
14567
+ if (workflowAgent) {
14568
+ workflowOperationKeyStore.enterWith(operationKey);
14569
+ }
14570
+ let metadata = metadataFromEvent(event);
13495
14571
  const logPayload = { metadata };
14572
+ const workflowAgentCallInput = workflowAgent ? operationInput(event, operationName) : void 0;
14573
+ if (workflowAgentCallInput) {
14574
+ metadata = {
14575
+ ...metadata,
14576
+ ...extractWorkflowMetadataFromCallParams(workflowAgentCallInput)
14577
+ };
14578
+ logPayload.metadata = metadata;
14579
+ }
13496
14580
  if (shouldRecordInputs(event)) {
13497
- const { input, outputPromise } = processAISDKCallInput(
13498
- operationInput(event, operationName)
13499
- );
14581
+ const callInput = workflowAgentCallInput ?? operationInput(event, operationName);
14582
+ const { input, outputPromise } = workflowAgent ? processAISDKWorkflowAgentCallInput(callInput) : processAISDKCallInput(callInput);
13500
14583
  logPayload.input = input;
13501
- if (outputPromise && input && typeof input === "object") {
14584
+ const state = operations.get(operationKey);
14585
+ if (state) {
14586
+ state.loggedInput = hasPromptLikeInput(input);
14587
+ }
14588
+ if (outputPromise && !workflowAgent && input && typeof input === "object") {
13502
14589
  outputPromise.then((resolvedData) => {
13503
14590
  span.log({
13504
14591
  input: {
@@ -13515,41 +14602,67 @@ function braintrustAISDKTelemetry() {
13515
14602
  },
13516
14603
  onLanguageModelCallStart(event) {
13517
14604
  runSafely("onLanguageModelCallStart", () => {
13518
- const state = operations.get(event.callId);
13519
- const openSpans = modelSpans.get(event.callId);
13520
- if (openSpans) {
14605
+ const operationKey = operationKeyFromEvent(event);
14606
+ const state = operationKey ? operations.get(operationKey) : void 0;
14607
+ if (shouldSkipTelemetryChildren(state)) {
14608
+ return;
14609
+ }
14610
+ const operationName = state?.operationName ?? "generateText";
14611
+ const callInput = operationInput(event, operationName);
14612
+ const workflowAgent = operationName === "WorkflowAgent.stream";
14613
+ const processedInput = shouldRecordInputs(event) && workflowAgent ? processAISDKWorkflowAgentModelCallInput(callInput).input : shouldRecordInputs(event) ? processAISDKCallInput(callInput).input : void 0;
14614
+ if (workflowAgent && state?.ownsSpan && !state.loggedInput && hasPromptLikeInput(processedInput)) {
14615
+ state.span.log({
14616
+ input: processedInput,
14617
+ metadata: {
14618
+ ...metadataFromEvent(event),
14619
+ ...extractWorkflowMetadataFromCallParams(callInput)
14620
+ }
14621
+ });
14622
+ state.loggedInput = true;
14623
+ }
14624
+ const openSpans = operationKey ? modelSpans.get(operationKey) : void 0;
14625
+ if (operationKey && openSpans) {
13521
14626
  for (const span2 of openSpans) {
13522
14627
  span2.end();
13523
14628
  }
13524
- modelSpans.delete(event.callId);
14629
+ modelSpans.delete(operationKey);
13525
14630
  }
13526
14631
  const span = startChildSpan(
13527
- event.callId,
13528
- state?.operationName === "streamText" ? "doStream" : "doGenerate",
14632
+ operationKey ?? event.callId,
14633
+ operationName === "streamText" ? "doStream" : "doGenerate",
13529
14634
  "llm" /* LLM */,
13530
14635
  {
13531
14636
  ...shouldRecordInputs(event) ? {
13532
- input: processAISDKCallInput(
13533
- operationInput(
13534
- event,
13535
- state?.operationName ?? "generateText"
13536
- )
13537
- ).input
14637
+ input: processedInput
13538
14638
  } : {},
13539
- metadata: metadataFromEvent(event)
14639
+ metadata: workflowAgent ? {
14640
+ ...metadataFromEvent(event),
14641
+ ...extractWorkflowMetadataFromCallParams(callInput)
14642
+ } : metadataFromEvent(event)
13540
14643
  }
13541
14644
  );
13542
- const spans = modelSpans.get(event.callId) ?? [];
14645
+ const spanKey = operationKey ?? event.callId;
14646
+ const spans = modelSpans.get(spanKey) ?? [];
13543
14647
  spans.push(span);
13544
- modelSpans.set(event.callId, spans);
14648
+ modelSpans.set(spanKey, spans);
13545
14649
  });
13546
14650
  },
13547
14651
  onLanguageModelCallEnd(event) {
13548
14652
  runSafely("onLanguageModelCallEnd", () => {
13549
- const span = shiftModelSpan(modelSpans, event.callId);
14653
+ const operationKey = operationKeyFromEvent(event);
14654
+ const state = operationKey ? operations.get(operationKey) : void 0;
14655
+ if (shouldSkipTelemetryChildren(state)) {
14656
+ return;
14657
+ }
14658
+ const span = operationKey ? shiftModelSpan(modelSpans, operationKey) : void 0;
13550
14659
  if (!span) {
13551
14660
  return;
13552
14661
  }
14662
+ const timeToFirstOutputMs = safePerformance(event)?.timeToFirstOutputMs;
14663
+ if (state?.operationName === "streamText" && state.firstChunkTime === void 0 && typeof timeToFirstOutputMs === "number") {
14664
+ state.firstChunkTime = state.startTime + timeToFirstOutputMs / 1e3;
14665
+ }
13553
14666
  const result = {
13554
14667
  ...event,
13555
14668
  response: event.responseId ? { id: event.responseId } : void 0
@@ -13565,14 +14678,18 @@ function braintrustAISDKTelemetry() {
13565
14678
  },
13566
14679
  onObjectStepStart(event) {
13567
14680
  runSafely("onObjectStepStart", () => {
13568
- const state = operations.get(event.callId);
13569
- const openSpan = objectSpans.get(event.callId);
13570
- if (openSpan) {
14681
+ const operationKey = operationKeyFromEvent(event);
14682
+ const state = operationKey ? operations.get(operationKey) : void 0;
14683
+ if (shouldSkipTelemetryChildren(state)) {
14684
+ return;
14685
+ }
14686
+ const openSpan = operationKey ? objectSpans.get(operationKey) : void 0;
14687
+ if (operationKey && openSpan) {
13571
14688
  openSpan.end();
13572
- objectSpans.delete(event.callId);
14689
+ objectSpans.delete(operationKey);
13573
14690
  }
13574
14691
  const span = startChildSpan(
13575
- event.callId,
14692
+ operationKey ?? event.callId,
13576
14693
  state?.operationName === "streamObject" ? "doStream" : "doGenerate",
13577
14694
  "llm" /* LLM */,
13578
14695
  {
@@ -13584,40 +14701,25 @@ function braintrustAISDKTelemetry() {
13584
14701
  metadata: metadataFromEvent(event)
13585
14702
  }
13586
14703
  );
13587
- objectSpans.set(event.callId, span);
13588
- });
13589
- },
13590
- onObjectStepFinish(event) {
13591
- runSafely("onObjectStepFinish", () => {
13592
- const span = objectSpans.get(event.callId);
13593
- if (!span) {
13594
- return;
13595
- }
13596
- const result = {
13597
- ...event,
13598
- text: event.objectText
13599
- };
13600
- span.log({
13601
- ...shouldRecordOutputs(event) ? {
13602
- output: processAISDKOutput(result, DEFAULT_DENY_OUTPUT_PATHS)
13603
- } : {},
13604
- metrics: extractTokenMetrics(result)
13605
- });
13606
- span.end();
13607
- objectSpans.delete(event.callId);
14704
+ objectSpans.set(operationKey ?? event.callId, span);
13608
14705
  });
13609
14706
  },
14707
+ onObjectStepEnd,
13610
14708
  onEmbedStart(event) {
13611
14709
  runSafely("onEmbedStart", () => {
13612
- const state = operations.get(event.callId);
14710
+ const operationKey = operationKeyFromEvent(event);
14711
+ const state = operationKey ? operations.get(operationKey) : void 0;
14712
+ if (shouldSkipTelemetryChildren(state)) {
14713
+ return;
14714
+ }
13613
14715
  for (const [embedCallId, embedState] of embedSpans) {
13614
- if (embedState.callId === event.callId && (state?.operationName === "embed" || embedState.values === event.values)) {
14716
+ if (embedState.operationKey === operationKey && (state?.operationName === "embed" || embedState.values === event.values)) {
13615
14717
  embedState.span.end();
13616
14718
  embedSpans.delete(embedCallId);
13617
14719
  }
13618
14720
  }
13619
14721
  const span = startChildSpan(
13620
- event.callId,
14722
+ operationKey ?? event.callId,
13621
14723
  "doEmbed",
13622
14724
  "llm" /* LLM */,
13623
14725
  {
@@ -13630,44 +14732,27 @@ function braintrustAISDKTelemetry() {
13630
14732
  }
13631
14733
  );
13632
14734
  embedSpans.set(event.embedCallId, {
13633
- callId: event.callId,
14735
+ operationKey: operationKey ?? event.callId,
13634
14736
  span,
13635
14737
  values: event.values
13636
14738
  });
13637
14739
  });
13638
14740
  },
13639
- onEmbedFinish(event) {
13640
- runSafely("onEmbedFinish", () => {
13641
- const state = embedSpans.get(event.embedCallId);
13642
- if (!state) {
13643
- return;
13644
- }
13645
- const result = {
13646
- ...event,
13647
- embeddings: event.embeddings
13648
- };
13649
- state.span.log({
13650
- ...shouldRecordOutputs(event) ? {
13651
- output: processAISDKEmbeddingOutput(
13652
- result,
13653
- DEFAULT_DENY_OUTPUT_PATHS
13654
- )
13655
- } : {},
13656
- metrics: extractTokenMetrics(result)
13657
- });
13658
- state.span.end();
13659
- embedSpans.delete(event.embedCallId);
13660
- });
13661
- },
14741
+ onEmbedEnd,
13662
14742
  onRerankStart(event) {
13663
14743
  runSafely("onRerankStart", () => {
13664
- const openSpan = rerankSpans.get(event.callId);
13665
- if (openSpan) {
14744
+ const operationKey = operationKeyFromEvent(event);
14745
+ const state = operationKey ? operations.get(operationKey) : void 0;
14746
+ if (shouldSkipTelemetryChildren(state)) {
14747
+ return;
14748
+ }
14749
+ const openSpan = operationKey ? rerankSpans.get(operationKey) : void 0;
14750
+ if (operationKey && openSpan) {
13666
14751
  openSpan.end();
13667
- rerankSpans.delete(event.callId);
14752
+ rerankSpans.delete(operationKey);
13668
14753
  }
13669
14754
  const span = startChildSpan(
13670
- event.callId,
14755
+ operationKey ?? event.callId,
13671
14756
  "doRerank",
13672
14757
  "llm" /* LLM */,
13673
14758
  {
@@ -13681,41 +14766,23 @@ function braintrustAISDKTelemetry() {
13681
14766
  metadata: metadataFromEvent(event)
13682
14767
  }
13683
14768
  );
13684
- rerankSpans.set(event.callId, span);
13685
- });
13686
- },
13687
- onRerankFinish(event) {
13688
- runSafely("onRerankFinish", () => {
13689
- const span = rerankSpans.get(event.callId);
13690
- if (!span) {
13691
- return;
13692
- }
13693
- const result = {
13694
- ranking: event.ranking?.map((entry) => ({
13695
- originalIndex: entry.index,
13696
- score: entry.relevanceScore
13697
- }))
13698
- };
13699
- span.log({
13700
- ...shouldRecordOutputs(event) ? {
13701
- output: processAISDKRerankOutput(
13702
- result,
13703
- DEFAULT_DENY_OUTPUT_PATHS
13704
- )
13705
- } : {}
13706
- });
13707
- span.end();
13708
- rerankSpans.delete(event.callId);
14769
+ rerankSpans.set(operationKey ?? event.callId, span);
13709
14770
  });
13710
14771
  },
14772
+ onRerankEnd,
13711
14773
  onToolExecutionStart(event) {
13712
14774
  runSafely("onToolExecutionStart", () => {
14775
+ const operationKey = operationKeyFromEvent(event);
14776
+ const state = operationKey ? operations.get(operationKey) : void 0;
14777
+ if (shouldSkipTelemetryChildren(state)) {
14778
+ return;
14779
+ }
13713
14780
  const toolCallId = event.toolCall.toolCallId;
13714
- if (!toolCallId) {
14781
+ if (!operationKey || !toolCallId) {
13715
14782
  return;
13716
14783
  }
13717
14784
  const span = startChildSpan(
13718
- event.callId,
14785
+ operationKey,
13719
14786
  event.toolCall.toolName || "tool",
13720
14787
  "tool" /* TOOL */,
13721
14788
  {
@@ -13729,7 +14796,7 @@ function braintrustAISDKTelemetry() {
13729
14796
  }
13730
14797
  }
13731
14798
  );
13732
- toolSpans.set(toolCallId, { callId: event.callId, span });
14799
+ toolSpans.set(toolCallId, { operationKey, span });
13733
14800
  });
13734
14801
  },
13735
14802
  onToolExecutionEnd(event) {
@@ -13740,14 +14807,17 @@ function braintrustAISDKTelemetry() {
13740
14807
  return;
13741
14808
  }
13742
14809
  const toolOutput = event.toolOutput;
13743
- if (toolOutput?.type === "tool-error") {
14810
+ const workflowToolError = event.success === false && "error" in event ? event.error : void 0;
14811
+ if (toolOutput?.type === "tool-error" || workflowToolError !== void 0) {
14812
+ const error = toolOutput?.error ?? workflowToolError;
13744
14813
  state.span.log({
13745
- error: toolOutput.error instanceof Error ? toolOutput.error.message : String(toolOutput?.error),
14814
+ error: error instanceof Error ? error.message : String(error),
13746
14815
  metrics: typeof event.durationMs === "number" ? { duration_ms: event.durationMs } : {}
13747
14816
  });
13748
14817
  } else {
14818
+ const output = toolOutput && "output" in toolOutput ? toolOutput.output : event.output;
13749
14819
  state.span.log({
13750
- ...shouldRecordOutputs(event) ? { output: toolOutput?.output } : {},
14820
+ ...shouldRecordOutputs(event) ? { output } : {},
13751
14821
  metrics: typeof event.durationMs === "number" ? { duration_ms: event.durationMs } : {}
13752
14822
  });
13753
14823
  }
@@ -13761,83 +14831,46 @@ function braintrustAISDKTelemetry() {
13761
14831
  if (!callId) {
13762
14832
  return;
13763
14833
  }
13764
- const state = operations.get(callId);
14834
+ const operationKey = operationKeyForCallId(callId);
14835
+ const state = operationKey ? operations.get(operationKey) : void 0;
13765
14836
  if (!state || state.firstChunkTime !== void 0) {
13766
14837
  return;
13767
14838
  }
13768
14839
  state.firstChunkTime = getCurrentUnixTimestamp();
13769
14840
  });
13770
14841
  },
13771
- onFinish(event) {
13772
- runSafely("onFinish", () => {
13773
- const state = operations.get(event.callId);
13774
- if (!state) {
14842
+ onEnd,
14843
+ onAbort(event) {
14844
+ runSafely("onAbort", () => {
14845
+ const operationKey = operationKeyFromEvent(event, "finish");
14846
+ const state = operationKey ? operations.get(operationKey) : void 0;
14847
+ if (!operationKey || !state) {
13775
14848
  return;
13776
14849
  }
13777
- const result = finishResult(event, state.operationName);
13778
- const metrics = state.hadModelChild ? {} : extractTokenMetrics(result);
13779
- if (state.firstChunkTime !== void 0) {
13780
- metrics.time_to_first_token = state.firstChunkTime - state.startTime;
14850
+ const error = abortReasonFromEvent(event);
14851
+ closeOpenChildSpans(operationKey, error);
14852
+ if (state.ownsSpan) {
14853
+ logError(state.span, error);
14854
+ state.span.end();
13781
14855
  }
13782
- state.span.log({
13783
- ...shouldRecordOutputs(event) ? {
13784
- output: finishOutput(result, state.operationName)
13785
- } : {},
13786
- metrics
13787
- });
13788
- state.span.end();
13789
- operations.delete(event.callId);
14856
+ deleteOperation(operationKey);
13790
14857
  });
13791
14858
  },
13792
14859
  onError(event) {
13793
14860
  runSafely("onError", () => {
13794
14861
  const errorEvent = isObject(event) ? event : {};
13795
- const callId = typeof errorEvent.callId === "string" ? errorEvent.callId : void 0;
13796
- if (!callId) {
13797
- return;
13798
- }
13799
- const state = operations.get(callId);
13800
- if (!state) {
14862
+ const operationKey = operationKeyFromEvent(errorEvent, "finish");
14863
+ const state = operationKey ? operations.get(operationKey) : void 0;
14864
+ if (!operationKey || !state) {
13801
14865
  return;
13802
14866
  }
13803
14867
  const error = errorEvent.error ?? event;
13804
- const openModelSpans = modelSpans.get(callId);
13805
- if (openModelSpans) {
13806
- for (const span of openModelSpans) {
13807
- logError(span, error);
13808
- span.end();
13809
- }
13810
- modelSpans.delete(callId);
13811
- }
13812
- const openObjectSpan = objectSpans.get(callId);
13813
- if (openObjectSpan) {
13814
- logError(openObjectSpan, error);
13815
- openObjectSpan.end();
13816
- objectSpans.delete(callId);
13817
- }
13818
- for (const [embedCallId, embedState] of embedSpans) {
13819
- if (embedState.callId === callId) {
13820
- logError(embedState.span, error);
13821
- embedState.span.end();
13822
- embedSpans.delete(embedCallId);
13823
- }
13824
- }
13825
- const openRerankSpan = rerankSpans.get(callId);
13826
- if (openRerankSpan) {
13827
- logError(openRerankSpan, error);
13828
- openRerankSpan.end();
13829
- rerankSpans.delete(callId);
13830
- }
13831
- for (const [toolCallId, toolState] of toolSpans) {
13832
- if (toolState.callId === callId) {
13833
- logError(toolState.span, error);
13834
- toolState.span.end();
13835
- toolSpans.delete(toolCallId);
13836
- }
14868
+ closeOpenChildSpans(operationKey, error);
14869
+ if (state.ownsSpan) {
14870
+ logError(state.span, error);
14871
+ state.span.end();
13837
14872
  }
13838
- logError(state.span, error);
13839
- state.span.end();
13840
- operations.delete(callId);
14873
+ deleteOperation(operationKey);
13841
14874
  });
13842
14875
  },
13843
14876
  executeTool({ toolCallId, execute }) {
@@ -13852,7 +14885,16 @@ function shouldRecordInputs(event) {
13852
14885
  function shouldRecordOutputs(event) {
13853
14886
  return event.recordOutputs !== false;
13854
14887
  }
14888
+ function hasPromptLikeInput(input) {
14889
+ if (!isObject(input)) {
14890
+ return false;
14891
+ }
14892
+ return input.prompt !== void 0 || input.messages !== void 0;
14893
+ }
13855
14894
  function operationNameFromId(operationId) {
14895
+ if (operationId === "ai.workflowAgent.stream") {
14896
+ return "WorkflowAgent.stream";
14897
+ }
13856
14898
  return operationId?.startsWith("ai.") ? operationId.slice("ai.".length) : operationId || "ai-sdk";
13857
14899
  }
13858
14900
  function modelFromEvent(event) {
@@ -13898,6 +14940,7 @@ function operationInput(event, operationName) {
13898
14940
  }
13899
14941
  return {
13900
14942
  model: modelFromEvent(event),
14943
+ instructions: event.instructions,
13901
14944
  system: event.system,
13902
14945
  prompt: event.prompt,
13903
14946
  messages: event.messages,
@@ -13946,6 +14989,30 @@ function finishResult(event, operationName) {
13946
14989
  }
13947
14990
  return event;
13948
14991
  }
14992
+ function extractTimeToFirstToken(result, state) {
14993
+ if (state.firstChunkTime !== void 0) {
14994
+ return state.firstChunkTime - state.startTime;
14995
+ }
14996
+ const performanceCandidates = [
14997
+ safePerformance(result),
14998
+ safePerformance(result.finalStep),
14999
+ ...Array.isArray(result.steps) ? (result.steps ?? []).map(safePerformance) : []
15000
+ ];
15001
+ for (const performance2 of performanceCandidates) {
15002
+ const timeToFirstOutputMs = performance2?.timeToFirstOutputMs;
15003
+ if (typeof timeToFirstOutputMs === "number") {
15004
+ return timeToFirstOutputMs / 1e3;
15005
+ }
15006
+ }
15007
+ return void 0;
15008
+ }
15009
+ function safePerformance(value) {
15010
+ if (!isObject(value)) {
15011
+ return void 0;
15012
+ }
15013
+ const performance2 = value.performance;
15014
+ return isObject(performance2) ? performance2 : void 0;
15015
+ }
13949
15016
  function finishOutput(result, operationName) {
13950
15017
  if (operationName === "embed" || operationName === "embedMany") {
13951
15018
  return processAISDKEmbeddingOutput(
@@ -14022,6 +15089,10 @@ var aiSDKChannels = defineChannels("ai", {
14022
15089
  channelName: "ToolLoopAgent.stream",
14023
15090
  kind: "async"
14024
15091
  }),
15092
+ workflowAgentStream: channel({
15093
+ channelName: "WorkflowAgent.stream",
15094
+ kind: "async"
15095
+ }),
14025
15096
  v7CreateTelemetryDispatcher: channel({
14026
15097
  channelName: "createTelemetryDispatcher",
14027
15098
  kind: "sync-stream"
@@ -14032,14 +15103,19 @@ var aiSDKChannels = defineChannels("ai", {
14032
15103
  var DEFAULT_DENY_OUTPUT_PATHS = [
14033
15104
  // v3
14034
15105
  "roundtrips[].request.body",
15106
+ "roundtrips[].request.headers",
14035
15107
  "roundtrips[].response.headers",
14036
15108
  "rawResponse.headers",
14037
15109
  "responseMessages",
14038
15110
  // v5
14039
15111
  "request.body",
15112
+ "request.headers",
15113
+ "responses[].headers",
14040
15114
  "response.body",
14041
15115
  "response.headers",
14042
15116
  "steps[].request.body",
15117
+ "steps[].request.headers",
15118
+ "steps[].responses[].headers",
14043
15119
  "steps[].response.body",
14044
15120
  "steps[].response.headers"
14045
15121
  ];
@@ -14051,6 +15127,18 @@ var AUTO_PATCHED_V7_TELEMETRY_DISPATCHER = /* @__PURE__ */ Symbol.for(
14051
15127
  var RUNTIME_DENY_OUTPUT_PATHS = /* @__PURE__ */ Symbol.for(
14052
15128
  "braintrust.ai-sdk.deny-output-paths"
14053
15129
  );
15130
+ var aiSDKV7TelemetryOperationCounter = 0;
15131
+ var TRANSPORT_PAYLOAD_ROOT_PATHS = [
15132
+ "rawResponse",
15133
+ "request",
15134
+ "response",
15135
+ "responses[]",
15136
+ "roundtrips[].request",
15137
+ "roundtrips[].response",
15138
+ "steps[].request",
15139
+ "steps[].response",
15140
+ "steps[].responses[]"
15141
+ ];
14054
15142
  var AI_SDK_V7_TELEMETRY_CALLBACKS = [
14055
15143
  "onStart",
14056
15144
  "onStepStart",
@@ -14059,14 +15147,16 @@ var AI_SDK_V7_TELEMETRY_CALLBACKS = [
14059
15147
  "onToolExecutionStart",
14060
15148
  "onToolExecutionEnd",
14061
15149
  "onChunk",
15150
+ "onStepEnd",
14062
15151
  "onStepFinish",
14063
15152
  "onObjectStepStart",
14064
- "onObjectStepFinish",
15153
+ "onObjectStepEnd",
14065
15154
  "onEmbedStart",
14066
- "onEmbedFinish",
15155
+ "onEmbedEnd",
14067
15156
  "onRerankStart",
14068
- "onRerankFinish",
14069
- "onFinish",
15157
+ "onRerankEnd",
15158
+ "onEnd",
15159
+ "onAbort",
14070
15160
  "onError"
14071
15161
  ];
14072
15162
  var AISDKPlugin = class extends BasePlugin {
@@ -14224,7 +15314,9 @@ var AISDKPlugin = class extends BasePlugin {
14224
15314
  traceStreamingChannel(aiSDKChannels.agentGenerate, {
14225
15315
  name: "Agent.generate",
14226
15316
  type: "function" /* FUNCTION */,
14227
- extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
15317
+ extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
15318
+ agentOwner: true
15319
+ }),
14228
15320
  extractOutput: (result, endEvent) => {
14229
15321
  finalizeAISDKChildTracing(endEvent);
14230
15322
  return processAISDKOutput(
@@ -14240,7 +15332,9 @@ var AISDKPlugin = class extends BasePlugin {
14240
15332
  traceStreamingChannel(aiSDKChannels.agentStream, {
14241
15333
  name: "Agent.stream",
14242
15334
  type: "function" /* FUNCTION */,
14243
- extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
15335
+ extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
15336
+ agentOwner: true
15337
+ }),
14244
15338
  extractOutput: (result, endEvent) => processAISDKOutput(
14245
15339
  result,
14246
15340
  resolveDenyOutputPaths(endEvent, denyOutputPaths)
@@ -14260,7 +15354,9 @@ var AISDKPlugin = class extends BasePlugin {
14260
15354
  traceSyncStreamChannel(aiSDKChannels.agentStreamSync, {
14261
15355
  name: "Agent.stream",
14262
15356
  type: "function" /* FUNCTION */,
14263
- extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
15357
+ extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
15358
+ agentOwner: true
15359
+ }),
14264
15360
  patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
14265
15361
  defaultDenyOutputPaths: denyOutputPaths,
14266
15362
  endEvent,
@@ -14274,7 +15370,9 @@ var AISDKPlugin = class extends BasePlugin {
14274
15370
  traceStreamingChannel(aiSDKChannels.toolLoopAgentGenerate, {
14275
15371
  name: "ToolLoopAgent.generate",
14276
15372
  type: "function" /* FUNCTION */,
14277
- extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
15373
+ extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
15374
+ agentOwner: true
15375
+ }),
14278
15376
  extractOutput: (result, endEvent) => {
14279
15377
  finalizeAISDKChildTracing(endEvent);
14280
15378
  return processAISDKOutput(
@@ -14290,7 +15388,9 @@ var AISDKPlugin = class extends BasePlugin {
14290
15388
  traceStreamingChannel(aiSDKChannels.toolLoopAgentStream, {
14291
15389
  name: "ToolLoopAgent.stream",
14292
15390
  type: "function" /* FUNCTION */,
14293
- extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
15391
+ extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
15392
+ agentOwner: true
15393
+ }),
14294
15394
  extractOutput: (result, endEvent) => processAISDKOutput(
14295
15395
  result,
14296
15396
  resolveDenyOutputPaths(endEvent, denyOutputPaths)
@@ -14306,6 +15406,42 @@ var AISDKPlugin = class extends BasePlugin {
14306
15406
  })
14307
15407
  })
14308
15408
  );
15409
+ this.unsubscribers.push(
15410
+ traceStreamingChannel(aiSDKChannels.workflowAgentStream, {
15411
+ name: "WorkflowAgent.stream",
15412
+ type: "function" /* FUNCTION */,
15413
+ extractInput: ([params], event, span) => prepareAISDKWorkflowAgentStreamInput(
15414
+ params,
15415
+ event,
15416
+ span,
15417
+ denyOutputPaths
15418
+ ),
15419
+ extractOutput: (result, endEvent) => {
15420
+ finalizeAISDKChildTracing(endEvent);
15421
+ return processAISDKOutput(
15422
+ result,
15423
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
15424
+ );
15425
+ },
15426
+ extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
15427
+ aggregateChunks: aggregateAISDKChunks,
15428
+ onComplete: ({ span }) => {
15429
+ unregisterWorkflowAgentWrapperSpan(span);
15430
+ },
15431
+ onError: ({ event, span }) => {
15432
+ finalizeAISDKChildTracing(event);
15433
+ unregisterWorkflowAgentWrapperSpan(span);
15434
+ },
15435
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
15436
+ defaultDenyOutputPaths: denyOutputPaths,
15437
+ endEvent,
15438
+ onComplete: () => unregisterWorkflowAgentWrapperSpan(span),
15439
+ result,
15440
+ span,
15441
+ startTime
15442
+ })
15443
+ })
15444
+ );
14309
15445
  }
14310
15446
  };
14311
15447
  function subscribeToAISDKV7TelemetryDispatcher() {
@@ -14317,7 +15453,11 @@ function subscribeToAISDKV7TelemetryDispatcher() {
14317
15453
  if (telemetryOptions?.isEnabled === false) {
14318
15454
  return;
14319
15455
  }
14320
- patchAISDKV7TelemetryDispatcher(event.result, telemetry);
15456
+ patchAISDKV7TelemetryDispatcher(
15457
+ event.result,
15458
+ telemetry,
15459
+ telemetryOptions
15460
+ );
14321
15461
  }
14322
15462
  };
14323
15463
  channel2.subscribe(handlers);
@@ -14325,7 +15465,7 @@ function subscribeToAISDKV7TelemetryDispatcher() {
14325
15465
  channel2.unsubscribe(handlers);
14326
15466
  };
14327
15467
  }
14328
- function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry) {
15468
+ function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry, telemetryOptions) {
14329
15469
  if (!isObject(dispatcher)) {
14330
15470
  return;
14331
15471
  }
@@ -14334,6 +15474,54 @@ function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry) {
14334
15474
  return;
14335
15475
  }
14336
15476
  dispatcherRecord[AUTO_PATCHED_V7_TELEMETRY_DISPATCHER] = true;
15477
+ let operationKey;
15478
+ const telemetryEventFields = {};
15479
+ if (typeof telemetryOptions?.recordInputs === "boolean") {
15480
+ telemetryEventFields.recordInputs = telemetryOptions.recordInputs;
15481
+ }
15482
+ if (typeof telemetryOptions?.recordOutputs === "boolean") {
15483
+ telemetryEventFields.recordOutputs = telemetryOptions.recordOutputs;
15484
+ }
15485
+ if (typeof telemetryOptions?.functionId === "string") {
15486
+ telemetryEventFields.functionId = telemetryOptions.functionId;
15487
+ }
15488
+ const eventWithOperationKey = (event) => {
15489
+ if (!isObject(event)) {
15490
+ return event;
15491
+ }
15492
+ const eventRecord = event;
15493
+ const callId = typeof eventRecord.callId === "string" ? eventRecord.callId : "unknown";
15494
+ operationKey ??= `${callId}:${++aiSDKV7TelemetryOperationCounter}`;
15495
+ if (Object.keys(telemetryEventFields).length > 0) {
15496
+ const augmentedEvent = {
15497
+ ...telemetryEventFields,
15498
+ ...event
15499
+ };
15500
+ try {
15501
+ Object.defineProperty(augmentedEvent, BRAINTRUST_AI_SDK_V7_OPERATION_KEY, {
15502
+ configurable: true,
15503
+ enumerable: false,
15504
+ value: operationKey
15505
+ });
15506
+ } catch {
15507
+ augmentedEvent[BRAINTRUST_AI_SDK_V7_OPERATION_KEY] = operationKey;
15508
+ }
15509
+ return augmentedEvent;
15510
+ }
15511
+ try {
15512
+ Object.defineProperty(eventRecord, BRAINTRUST_AI_SDK_V7_OPERATION_KEY, {
15513
+ configurable: true,
15514
+ enumerable: false,
15515
+ value: operationKey
15516
+ });
15517
+ return event;
15518
+ } catch {
15519
+ return {
15520
+ ...event,
15521
+ [BRAINTRUST_AI_SDK_V7_OPERATION_KEY]: operationKey
15522
+ };
15523
+ }
15524
+ };
14337
15525
  for (const key of AI_SDK_V7_TELEMETRY_CALLBACKS) {
14338
15526
  const braintrustCallback = telemetry[key];
14339
15527
  if (typeof braintrustCallback !== "function") {
@@ -14342,11 +15530,17 @@ function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry) {
14342
15530
  const existingCallback = dispatcherRecord[key];
14343
15531
  dispatcherRecord[key] = (event) => {
14344
15532
  const existingResult = typeof existingCallback === "function" ? existingCallback.call(dispatcher, event) : void 0;
14345
- const braintrustResult = braintrustCallback.call(telemetry, event);
14346
- const pending = [existingResult, braintrustResult].filter(isPromiseLike);
14347
- if (pending.length > 0) {
14348
- return Promise.allSettled(pending).then(() => void 0);
15533
+ try {
15534
+ const braintrustResult = braintrustCallback.call(
15535
+ telemetry,
15536
+ eventWithOperationKey(event)
15537
+ );
15538
+ if (isPromiseLike(braintrustResult)) {
15539
+ void Promise.resolve(braintrustResult).catch(() => void 0);
15540
+ }
15541
+ } catch {
14349
15542
  }
15543
+ return existingResult;
14350
15544
  };
14351
15545
  }
14352
15546
  const braintrustExecuteTool = telemetry.executeTool;
@@ -14356,6 +15550,7 @@ function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry) {
14356
15550
  const existingExecuteTool = dispatcherRecord.executeTool;
14357
15551
  dispatcherRecord.executeTool = (args) => braintrustExecuteTool.call(telemetry, {
14358
15552
  ...args,
15553
+ ...operationKey ? { [BRAINTRUST_AI_SDK_V7_OPERATION_KEY]: operationKey } : {},
14359
15554
  execute: () => typeof existingExecuteTool === "function" ? existingExecuteTool.call(dispatcher, args) : args.execute()
14360
15555
  });
14361
15556
  }
@@ -14454,6 +15649,8 @@ var serializeOutputObject = (output, model) => {
14454
15649
  var processInputAttachmentsSync = (input) => {
14455
15650
  if (!input) return { input };
14456
15651
  const processed = { ...input };
15652
+ delete processed.headers;
15653
+ delete processed.experimental_output;
14457
15654
  if (input.messages && Array.isArray(input.messages)) {
14458
15655
  processed.messages = input.messages.map(processMessage);
14459
15656
  }
@@ -14487,10 +15684,10 @@ var processInputAttachmentsSync = (input) => {
14487
15684
  processed.output = serialized;
14488
15685
  }
14489
15686
  }
14490
- if ("prepareCall" in processed && typeof processed.prepareCall === "function") {
14491
- processed.prepareCall = "[Function]";
14492
- }
14493
- return { input: processed, outputPromise };
15687
+ return {
15688
+ input: sanitizeAISDKCallInputValue(processed),
15689
+ outputPromise
15690
+ };
14494
15691
  };
14495
15692
  var processMessage = (message) => {
14496
15693
  if (!message || typeof message !== "object") return message;
@@ -14654,7 +15851,21 @@ var convertDataToAttachment = (data, mimeType, filename) => {
14654
15851
  function processAISDKCallInput(params) {
14655
15852
  return processInputAttachmentsSync(params);
14656
15853
  }
14657
- function prepareAISDKCallInput(params, event, span, defaultDenyOutputPaths) {
15854
+ function processAISDKWorkflowAgentCallInput(params) {
15855
+ const processed = processAISDKCallInput(params);
15856
+ return {
15857
+ ...processed,
15858
+ input: extractWorkflowAgentInput(processed.input)
15859
+ };
15860
+ }
15861
+ function processAISDKWorkflowAgentModelCallInput(params) {
15862
+ const processed = processAISDKCallInput(params);
15863
+ return {
15864
+ ...processed,
15865
+ input: extractWorkflowAgentModelInput(processed.input)
15866
+ };
15867
+ }
15868
+ function prepareAISDKCallInput(params, event, span, defaultDenyOutputPaths, childTracingOptions = {}) {
14658
15869
  const { input, outputPromise } = processAISDKCallInput(params);
14659
15870
  if (outputPromise && input && typeof input === "object") {
14660
15871
  outputPromise.then((resolvedData) => {
@@ -14673,7 +15884,29 @@ function prepareAISDKCallInput(params, event, span, defaultDenyOutputPaths) {
14673
15884
  event.self,
14674
15885
  span,
14675
15886
  defaultDenyOutputPaths,
14676
- event.aiSDK
15887
+ event.aiSDK,
15888
+ childTracingOptions
15889
+ );
15890
+ event.modelWrapped = childTracing.modelWrapped;
15891
+ if (childTracing.cleanup) {
15892
+ event.__braintrust_ai_sdk_cleanup = childTracing.cleanup;
15893
+ }
15894
+ return {
15895
+ input,
15896
+ metadata
15897
+ };
15898
+ }
15899
+ function prepareAISDKWorkflowAgentStreamInput(params, event, span, defaultDenyOutputPaths) {
15900
+ registerWorkflowAgentWrapperSpan(span);
15901
+ const { input } = processAISDKWorkflowAgentCallInput(params);
15902
+ const metadata = extractWorkflowMetadataFromCallParams(params, event.self);
15903
+ const childTracing = prepareAISDKChildTracing(
15904
+ params,
15905
+ event.self,
15906
+ span,
15907
+ defaultDenyOutputPaths,
15908
+ event.aiSDK,
15909
+ { agentOwner: true, workflowAgent: true }
14677
15910
  );
14678
15911
  event.modelWrapped = childTracing.modelWrapped;
14679
15912
  if (childTracing.cleanup) {
@@ -14710,6 +15943,9 @@ function extractTopLevelAISDKMetrics(result, event, startTime) {
14710
15943
  function hasModelChildTracing(event) {
14711
15944
  return event?.modelWrapped === true || event?.__braintrust_ai_sdk_model_wrapped === true;
14712
15945
  }
15946
+ function serializeToolExecutionInput(args) {
15947
+ return args.length > 0 ? args[0] : args;
15948
+ }
14713
15949
  function createAISDKIntegrationMetadata() {
14714
15950
  return {
14715
15951
  braintrust: {
@@ -14721,6 +15957,13 @@ function createAISDKIntegrationMetadata() {
14721
15957
  function resolveModelFromSelf(self) {
14722
15958
  return self && typeof self === "object" && "model" in self && self.model ? self.model : self && typeof self === "object" && "settings" in self && self.settings?.model ? self.settings?.model : void 0;
14723
15959
  }
15960
+ function resolveToolsFromSelf(self) {
15961
+ if (!self || typeof self !== "object") {
15962
+ return void 0;
15963
+ }
15964
+ const selfRecord = self;
15965
+ return selfRecord.tools ?? selfRecord.settings?.tools;
15966
+ }
14724
15967
  function extractBaseMetadata(model, self) {
14725
15968
  const metadata = createAISDKIntegrationMetadata();
14726
15969
  const { model: modelId, provider } = serializeModelWithProvider(
@@ -14736,12 +15979,175 @@ function extractBaseMetadata(model, self) {
14736
15979
  }
14737
15980
  function extractMetadataFromCallParams(params, self) {
14738
15981
  const metadata = extractBaseMetadata(params.model, self);
14739
- const tools = serializeAISDKToolsForLogging(params.tools);
15982
+ const tools = serializeAISDKToolsForLogging(
15983
+ params.tools ?? resolveToolsFromSelf(self)
15984
+ );
14740
15985
  if (tools) {
14741
15986
  metadata.tools = tools;
14742
15987
  }
14743
15988
  return metadata;
14744
15989
  }
15990
+ function extractWorkflowMetadataFromCallParams(params, self) {
15991
+ const metadata = extractMetadataFromCallParams(params, self);
15992
+ const options = extractAISDKCallOptionsForMetadata(params);
15993
+ if (Object.keys(options).length > 0) {
15994
+ metadata.options = options;
15995
+ }
15996
+ return metadata;
15997
+ }
15998
+ function extractWorkflowAgentInput(params) {
15999
+ const input = {};
16000
+ if (params.instructions !== void 0) {
16001
+ input.instructions = params.instructions;
16002
+ }
16003
+ if (params.system !== void 0) {
16004
+ input.system = params.system;
16005
+ }
16006
+ if (Array.isArray(params.messages)) {
16007
+ return { ...input, messages: params.messages };
16008
+ }
16009
+ if (typeof params.prompt === "string") {
16010
+ return { ...input, prompt: params.prompt };
16011
+ }
16012
+ if (Array.isArray(params.prompt)) {
16013
+ return { ...input, prompt: params.prompt };
16014
+ }
16015
+ return input;
16016
+ }
16017
+ function extractWorkflowAgentModelInput(params) {
16018
+ const input = {};
16019
+ if (params.instructions !== void 0) {
16020
+ input.instructions = params.instructions;
16021
+ }
16022
+ if (params.system !== void 0) {
16023
+ input.system = params.system;
16024
+ }
16025
+ if (Array.isArray(params.messages)) {
16026
+ return { ...input, messages: params.messages };
16027
+ }
16028
+ if (typeof params.prompt === "string") {
16029
+ return { ...input, prompt: params.prompt };
16030
+ }
16031
+ if (Array.isArray(params.prompt)) {
16032
+ return { ...input, messages: params.prompt };
16033
+ }
16034
+ return input;
16035
+ }
16036
+ function sanitizeAISDKCallInputValue(value, depth = 0) {
16037
+ if (value === void 0 || typeof value === "function") {
16038
+ return void 0;
16039
+ }
16040
+ if (value === null || typeof value !== "object") {
16041
+ return value;
16042
+ }
16043
+ if (isPromiseLike(value)) {
16044
+ return "[Promise]";
16045
+ }
16046
+ if (typeof AbortSignal !== "undefined" && value instanceof AbortSignal) {
16047
+ return "[AbortSignal]";
16048
+ }
16049
+ if (depth >= 8) {
16050
+ return "[Object]";
16051
+ }
16052
+ if (Array.isArray(value)) {
16053
+ return value.map((item) => sanitizeAISDKCallInputValue(item, depth + 1)).filter((item) => item !== void 0);
16054
+ }
16055
+ if (!isObject(value)) {
16056
+ return value;
16057
+ }
16058
+ const prototype = Object.getPrototypeOf(value);
16059
+ if (prototype !== Object.prototype && prototype !== null) {
16060
+ return value;
16061
+ }
16062
+ const sanitized = {};
16063
+ for (const [key, nested] of Object.entries(value)) {
16064
+ if (key === "__proto__" || key === "constructor" || key === "prototype" || key.toLowerCase() === "headers") {
16065
+ continue;
16066
+ }
16067
+ const sanitizedNested = sanitizeAISDKCallInputValue(nested, depth + 1);
16068
+ if (sanitizedNested !== void 0) {
16069
+ sanitized[key] = sanitizedNested;
16070
+ }
16071
+ }
16072
+ return sanitized;
16073
+ }
16074
+ function extractAISDKCallOptionsForMetadata(params) {
16075
+ const options = {};
16076
+ const inputOrTopLevelKeys = /* @__PURE__ */ new Set([
16077
+ "model",
16078
+ "instructions",
16079
+ "messages",
16080
+ "prompt",
16081
+ "system",
16082
+ "tools",
16083
+ "headers",
16084
+ "abortSignal",
16085
+ "signal",
16086
+ "experimental_output"
16087
+ ]);
16088
+ for (const [key, value] of Object.entries(params)) {
16089
+ if (inputOrTopLevelKeys.has(key) || key === "__proto__" || key === "constructor" || key === "prototype" || /^on[A-Z]/.test(key) && typeof value === "function") {
16090
+ continue;
16091
+ }
16092
+ const sanitized = sanitizeAISDKMetadataValue(value);
16093
+ if (sanitized !== void 0) {
16094
+ options[key] = sanitized;
16095
+ }
16096
+ }
16097
+ return options;
16098
+ }
16099
+ function sanitizeAISDKMetadataValue(value, depth = 0) {
16100
+ if (value === void 0) {
16101
+ return void 0;
16102
+ }
16103
+ if (typeof value === "function") {
16104
+ return "[Function]";
16105
+ }
16106
+ if (value === null || typeof value !== "object") {
16107
+ return value;
16108
+ }
16109
+ if (isPromiseLike(value)) {
16110
+ return "[Promise]";
16111
+ }
16112
+ if (typeof AbortSignal !== "undefined" && value instanceof AbortSignal) {
16113
+ return "[AbortSignal]";
16114
+ }
16115
+ if (depth >= 8) {
16116
+ return "[Object]";
16117
+ }
16118
+ if (Array.isArray(value)) {
16119
+ return value.map((item) => sanitizeAISDKMetadataValue(item, depth + 1)).filter((item) => item !== void 0);
16120
+ }
16121
+ if (!isObject(value)) {
16122
+ return value;
16123
+ }
16124
+ const sanitized = {};
16125
+ for (const [key, nested] of Object.entries(value)) {
16126
+ if (key === "__proto__" || key === "constructor" || key === "prototype" || key.toLowerCase() === "headers") {
16127
+ continue;
16128
+ }
16129
+ const sanitizedNested = sanitizeAISDKMetadataValue(nested, depth + 1);
16130
+ if (sanitizedNested !== void 0) {
16131
+ sanitized[key] = sanitizedNested;
16132
+ }
16133
+ }
16134
+ return sanitized;
16135
+ }
16136
+ function buildAISDKModelStartEvent(callOptions, baseMetadata, options) {
16137
+ if (!options.workflowAgent) {
16138
+ return {
16139
+ input: processAISDKCallInput(callOptions).input,
16140
+ metadata: baseMetadata
16141
+ };
16142
+ }
16143
+ return {
16144
+ input: processAISDKWorkflowAgentModelCallInput(callOptions).input,
16145
+ metadata: {
16146
+ ...baseMetadata,
16147
+ ...extractWorkflowMetadataFromCallParams(callOptions)
16148
+ }
16149
+ };
16150
+ }
14745
16151
  function extractMetadataFromEmbedParams(params, self) {
14746
16152
  return extractBaseMetadata(params.model, self);
14747
16153
  }
@@ -14755,72 +16161,273 @@ function extractMetadataFromRerankParams(params, self) {
14755
16161
  }
14756
16162
  return metadata;
14757
16163
  }
14758
- function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiSDK) {
16164
+ function activeAISDKChildPatchEntry(entries) {
16165
+ const activeSpan = currentSpan();
16166
+ const activeSpanId = activeSpan.spanId;
16167
+ if (activeSpanId) {
16168
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
16169
+ const entry = entries[index];
16170
+ if (entry?.activeSpanIds.has(activeSpanId)) {
16171
+ return entry;
16172
+ }
16173
+ }
16174
+ }
16175
+ const activeParentSpanIds = activeSpan.spanParents ?? [];
16176
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
16177
+ const entry = entries[index];
16178
+ if (entry?.parentSpan.spanId && activeParentSpanIds.includes(entry.parentSpan.spanId)) {
16179
+ return entry;
16180
+ }
16181
+ }
16182
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
16183
+ const entry = entries[index];
16184
+ if (entry?.parentSpan.spanId === activeSpanId) {
16185
+ return entry;
16186
+ }
16187
+ }
16188
+ return entries[entries.length - 1];
16189
+ }
16190
+ function attachNestedAISDKChildPatchEntry(entries, nestedSpan, cleanup) {
16191
+ const activeSpanId = currentSpan().spanId;
16192
+ if (!activeSpanId || activeSpanId === nestedSpan.spanId) {
16193
+ return false;
16194
+ }
16195
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
16196
+ const entry = entries[index];
16197
+ if (entry?.parentSpan.spanId === activeSpanId || entry?.activeSpanIds.has(activeSpanId)) {
16198
+ entry.activeSpanIds.add(nestedSpan.spanId);
16199
+ cleanup.push(() => {
16200
+ entry.activeSpanIds.delete(nestedSpan.spanId);
16201
+ });
16202
+ return true;
16203
+ }
16204
+ }
16205
+ return false;
16206
+ }
16207
+ function shadowActiveAISDKChildPatchEntry(entries, entry, nestedSpan, cleanup) {
16208
+ const activeSpanId = currentSpan().spanId;
16209
+ if (!activeSpanId || activeSpanId === nestedSpan.spanId) {
16210
+ return;
16211
+ }
16212
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
16213
+ const existingEntry = entries[index];
16214
+ if (existingEntry?.parentSpan.spanId === activeSpanId || existingEntry?.activeSpanIds.has(activeSpanId)) {
16215
+ entry.activeSpanIds.add(activeSpanId);
16216
+ cleanup.push(() => {
16217
+ entry.activeSpanIds.delete(activeSpanId);
16218
+ });
16219
+ return;
16220
+ }
16221
+ }
16222
+ }
16223
+ function closeOpenAISDKModelPatchSpans(entry) {
16224
+ for (const span of entry.openSpans) {
16225
+ span.end();
16226
+ }
16227
+ entry.openSpans.clear();
16228
+ }
16229
+ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiSDK, childTracingOptions = {}) {
14759
16230
  const cleanup = [];
14760
- const patchedModels = /* @__PURE__ */ new WeakSet();
16231
+ const patchedModels = /* @__PURE__ */ new WeakMap();
14761
16232
  const patchedTools = /* @__PURE__ */ new WeakSet();
14762
16233
  let modelWrapped = false;
14763
16234
  const patchModel = (model) => {
14764
16235
  const resolvedModel = resolveAISDKModel(model, aiSDK);
14765
- if (!resolvedModel || typeof resolvedModel !== "object" || typeof resolvedModel.doGenerate !== "function" || patchedModels.has(resolvedModel) || resolvedModel[AUTO_PATCHED_MODEL]) {
16236
+ if (!resolvedModel || typeof resolvedModel !== "object" || typeof resolvedModel.doGenerate !== "function") {
14766
16237
  return resolvedModel;
14767
16238
  }
14768
- patchedModels.add(resolvedModel);
14769
- resolvedModel[AUTO_PATCHED_MODEL] = true;
16239
+ const existingWrappedModel = patchedModels.get(resolvedModel);
16240
+ if (existingWrappedModel) {
16241
+ modelWrapped = true;
16242
+ return existingWrappedModel;
16243
+ }
14770
16244
  modelWrapped = true;
16245
+ const modelRecord = resolvedModel;
16246
+ const entry = {
16247
+ activeSpanIds: /* @__PURE__ */ new Set([parentSpan.spanId]),
16248
+ baseMetadata: buildAISDKChildMetadata(resolvedModel),
16249
+ childTracingOptions,
16250
+ denyOutputPaths,
16251
+ openSpans: /* @__PURE__ */ new Set(),
16252
+ parentSpan
16253
+ };
16254
+ const cleanupModelEntry = (state2, patchedModel) => {
16255
+ closeOpenAISDKModelPatchSpans(entry);
16256
+ const index = state2.entries.indexOf(entry);
16257
+ if (index >= 0) {
16258
+ state2.entries.splice(index, 1);
16259
+ }
16260
+ if (state2.entries.length > 0) {
16261
+ return;
16262
+ }
16263
+ patchedModel.doGenerate = state2.originalDoGenerate;
16264
+ patchedModel.doStream = state2.originalDoStream;
16265
+ delete patchedModel[AUTO_PATCHED_MODEL];
16266
+ };
16267
+ const existingState = modelRecord[AUTO_PATCHED_MODEL];
16268
+ if (existingState) {
16269
+ patchedModels.set(resolvedModel, resolvedModel);
16270
+ if (childTracingOptions.agentOwner && attachNestedAISDKChildPatchEntry(
16271
+ existingState.entries,
16272
+ parentSpan,
16273
+ cleanup
16274
+ )) {
16275
+ return resolvedModel;
16276
+ }
16277
+ if (!childTracingOptions.agentOwner) {
16278
+ shadowActiveAISDKChildPatchEntry(
16279
+ existingState.entries,
16280
+ entry,
16281
+ parentSpan,
16282
+ cleanup
16283
+ );
16284
+ }
16285
+ existingState.entries.push(entry);
16286
+ cleanup.push(() => {
16287
+ cleanupModelEntry(existingState, modelRecord);
16288
+ });
16289
+ return resolvedModel;
16290
+ }
14771
16291
  const originalDoGenerate = resolvedModel.doGenerate;
14772
16292
  const originalDoStream = resolvedModel.doStream;
14773
- const baseMetadata = buildAISDKChildMetadata(resolvedModel);
14774
- resolvedModel.doGenerate = async function doGeneratePatched(options) {
14775
- return parentSpan.traced(
16293
+ const wrappedModel = Object.create(
16294
+ Object.getPrototypeOf(resolvedModel)
16295
+ );
16296
+ Object.defineProperties(
16297
+ wrappedModel,
16298
+ Object.getOwnPropertyDescriptors(resolvedModel)
16299
+ );
16300
+ const wrappedModelRecord = wrappedModel;
16301
+ const state = {
16302
+ entries: [entry],
16303
+ originalDoGenerate,
16304
+ originalDoStream
16305
+ };
16306
+ Object.defineProperty(wrappedModel, AUTO_PATCHED_MODEL, {
16307
+ configurable: true,
16308
+ value: state
16309
+ });
16310
+ wrappedModel.doGenerate = async function doGeneratePatched(callOptions) {
16311
+ const activeEntry = activeAISDKChildPatchEntry(state.entries);
16312
+ if (!activeEntry) {
16313
+ return Reflect.apply(originalDoGenerate, resolvedModel, [callOptions]);
16314
+ }
16315
+ closeOpenAISDKModelPatchSpans(activeEntry);
16316
+ return activeEntry.parentSpan.traced(
14776
16317
  async (span) => {
14777
- const result = await Reflect.apply(
14778
- originalDoGenerate,
14779
- resolvedModel,
14780
- [options]
14781
- );
14782
- span.log({
14783
- output: processAISDKOutput(result, denyOutputPaths),
14784
- metrics: extractTokenMetrics(result),
14785
- ...buildResolvedMetadataPayload(result)
14786
- });
14787
- return result;
16318
+ activeEntry.openSpans.add(span);
16319
+ try {
16320
+ const result = await Reflect.apply(
16321
+ originalDoGenerate,
16322
+ resolvedModel,
16323
+ [callOptions]
16324
+ );
16325
+ const output = processAISDKOutput(
16326
+ result,
16327
+ activeEntry.denyOutputPaths
16328
+ );
16329
+ const metrics = extractTokenMetrics(result);
16330
+ const metadataPayload = buildResolvedMetadataPayload(result);
16331
+ const missingUsageMetadata = buildMissingUsageMetadata(
16332
+ output,
16333
+ metrics,
16334
+ "ai_sdk_result_missing_usage"
16335
+ );
16336
+ span.log({
16337
+ output,
16338
+ metrics,
16339
+ ...mergeMetadataPayload(metadataPayload, missingUsageMetadata)
16340
+ });
16341
+ return result;
16342
+ } finally {
16343
+ activeEntry.openSpans.delete(span);
16344
+ }
14788
16345
  },
14789
16346
  {
14790
16347
  name: "doGenerate",
14791
16348
  spanAttributes: {
14792
16349
  type: "llm" /* LLM */
14793
16350
  },
14794
- event: {
14795
- input: processAISDKCallInput(options).input,
14796
- metadata: baseMetadata
14797
- }
16351
+ event: buildAISDKModelStartEvent(
16352
+ callOptions,
16353
+ activeEntry.baseMetadata,
16354
+ {
16355
+ workflowAgent: activeEntry.childTracingOptions.workflowAgent
16356
+ }
16357
+ )
14798
16358
  }
14799
16359
  );
14800
16360
  };
14801
16361
  if (originalDoStream) {
14802
- resolvedModel.doStream = async function doStreamPatched(options) {
14803
- const span = parentSpan.startSpan({
16362
+ wrappedModel.doStream = async function doStreamPatched(callOptions) {
16363
+ const activeEntry = activeAISDKChildPatchEntry(state.entries);
16364
+ if (!activeEntry) {
16365
+ return Reflect.apply(originalDoStream, resolvedModel, [callOptions]);
16366
+ }
16367
+ closeOpenAISDKModelPatchSpans(activeEntry);
16368
+ const span = activeEntry.parentSpan.startSpan({
14804
16369
  name: "doStream",
14805
16370
  spanAttributes: {
14806
16371
  type: "llm" /* LLM */
14807
16372
  },
14808
- event: {
14809
- input: processAISDKCallInput(options).input,
14810
- metadata: baseMetadata
14811
- }
16373
+ event: buildAISDKModelStartEvent(
16374
+ callOptions,
16375
+ activeEntry.baseMetadata,
16376
+ {
16377
+ workflowAgent: activeEntry.childTracingOptions.workflowAgent
16378
+ }
16379
+ )
14812
16380
  });
16381
+ activeEntry.openSpans.add(span);
14813
16382
  const streamStartTime = getCurrentUnixTimestamp();
14814
16383
  const result = await withCurrent(
14815
16384
  span,
14816
- () => Reflect.apply(originalDoStream, resolvedModel, [options])
16385
+ () => Reflect.apply(originalDoStream, resolvedModel, [callOptions])
14817
16386
  );
14818
16387
  let firstChunkTime;
14819
16388
  const output = {};
14820
16389
  let text = "";
14821
16390
  let reasoning = "";
14822
- const toolCalls = [];
16391
+ const toolCalls2 = [];
14823
16392
  let object = void 0;
16393
+ let streamSpanEnded = false;
16394
+ const logAndEndStreamSpan = (usageUnavailableReason) => {
16395
+ if (streamSpanEnded) {
16396
+ return;
16397
+ }
16398
+ output.text = text;
16399
+ output.reasoning = reasoning;
16400
+ output.toolCalls = toolCalls2;
16401
+ if (object !== void 0) {
16402
+ output.object = object;
16403
+ }
16404
+ const metrics = extractTokenMetrics(output);
16405
+ if (firstChunkTime !== void 0 && !activeEntry.childTracingOptions.workflowAgent) {
16406
+ metrics.time_to_first_token = Math.max(
16407
+ firstChunkTime - streamStartTime,
16408
+ 1e-6
16409
+ );
16410
+ }
16411
+ const metadataPayload = buildResolvedMetadataPayload(
16412
+ output
16413
+ );
16414
+ const missingUsageMetadata = usageUnavailableReason ? { usage_unavailable_reason: usageUnavailableReason } : buildMissingUsageMetadata(
16415
+ output,
16416
+ metrics,
16417
+ "ai_sdk_result_missing_usage"
16418
+ );
16419
+ span.log({
16420
+ output: processAISDKOutput(
16421
+ output,
16422
+ activeEntry.denyOutputPaths
16423
+ ),
16424
+ metrics,
16425
+ ...mergeMetadataPayload(metadataPayload, missingUsageMetadata)
16426
+ });
16427
+ activeEntry.openSpans.delete(span);
16428
+ span.end();
16429
+ streamSpanEnded = true;
16430
+ };
14824
16431
  const transformStream = new TransformStream({
14825
16432
  transform(chunk, controller) {
14826
16433
  if (firstChunkTime === void 0 && isAISDKContentStreamChunk(chunk)) {
@@ -14838,7 +16445,7 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
14838
16445
  }
14839
16446
  break;
14840
16447
  case "tool-call":
14841
- toolCalls.push(chunk);
16448
+ toolCalls2.push(chunk);
14842
16449
  break;
14843
16450
  case "object":
14844
16451
  object = chunk.object;
@@ -14858,33 +16465,15 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
14858
16465
  }
14859
16466
  break;
14860
16467
  case "finish":
14861
- output.text = text;
14862
- output.reasoning = reasoning;
14863
- output.toolCalls = toolCalls;
14864
16468
  output.finishReason = chunk.finishReason;
14865
16469
  output.usage = chunk.usage;
14866
- if (object !== void 0) {
14867
- output.object = object;
14868
- }
14869
- const metrics = extractTokenMetrics(output);
14870
- if (firstChunkTime !== void 0) {
14871
- metrics.time_to_first_token = Math.max(
14872
- firstChunkTime - streamStartTime,
14873
- 1e-6
14874
- );
14875
- }
14876
- span.log({
14877
- output: processAISDKOutput(
14878
- output,
14879
- denyOutputPaths
14880
- ),
14881
- metrics,
14882
- ...buildResolvedMetadataPayload(output)
14883
- });
14884
- span.end();
16470
+ logAndEndStreamSpan();
14885
16471
  break;
14886
16472
  }
14887
16473
  controller.enqueue(chunk);
16474
+ },
16475
+ flush() {
16476
+ logAndEndStreamSpan("ai_sdk_stream_finished_without_usage");
14888
16477
  }
14889
16478
  });
14890
16479
  return {
@@ -14894,32 +16483,79 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
14894
16483
  };
14895
16484
  }
14896
16485
  cleanup.push(() => {
14897
- resolvedModel.doGenerate = originalDoGenerate;
14898
- if (originalDoStream) {
14899
- resolvedModel.doStream = originalDoStream;
14900
- }
14901
- delete resolvedModel[AUTO_PATCHED_MODEL];
16486
+ cleanupModelEntry(state, wrappedModelRecord);
14902
16487
  });
14903
- return resolvedModel;
16488
+ patchedModels.set(resolvedModel, wrappedModel);
16489
+ patchedModels.set(wrappedModel, wrappedModel);
16490
+ return wrappedModel;
14904
16491
  };
14905
16492
  const patchTool = (tool, name) => {
14906
- if (tool == null || typeof tool !== "object" || !("execute" in tool) || typeof tool.execute !== "function" || patchedTools.has(tool) || tool[AUTO_PATCHED_TOOL]) {
16493
+ if (tool == null || typeof tool !== "object" || !("execute" in tool) || typeof tool.execute !== "function" || patchedTools.has(tool)) {
14907
16494
  return;
14908
16495
  }
14909
16496
  patchedTools.add(tool);
14910
- tool[AUTO_PATCHED_TOOL] = true;
14911
- const originalExecute = tool.execute;
16497
+ const toolRecord = tool;
16498
+ const entry = {
16499
+ activeSpanIds: /* @__PURE__ */ new Set([parentSpan.spanId]),
16500
+ childTracingOptions,
16501
+ name,
16502
+ parentSpan
16503
+ };
16504
+ const cleanupToolEntry = (state2) => {
16505
+ const index = state2.entries.indexOf(entry);
16506
+ if (index >= 0) {
16507
+ state2.entries.splice(index, 1);
16508
+ }
16509
+ if (state2.entries.length > 0) {
16510
+ return;
16511
+ }
16512
+ tool.execute = state2.originalExecute;
16513
+ delete toolRecord[AUTO_PATCHED_TOOL];
16514
+ };
16515
+ const existingState = toolRecord[AUTO_PATCHED_TOOL];
16516
+ if (existingState) {
16517
+ if (childTracingOptions.agentOwner && attachNestedAISDKChildPatchEntry(
16518
+ existingState.entries,
16519
+ parentSpan,
16520
+ cleanup
16521
+ )) {
16522
+ return;
16523
+ }
16524
+ if (!childTracingOptions.agentOwner) {
16525
+ shadowActiveAISDKChildPatchEntry(
16526
+ existingState.entries,
16527
+ entry,
16528
+ parentSpan,
16529
+ cleanup
16530
+ );
16531
+ }
16532
+ existingState.entries.push(entry);
16533
+ cleanup.push(() => {
16534
+ cleanupToolEntry(existingState);
16535
+ });
16536
+ return;
16537
+ }
16538
+ const originalExecute = toolRecord.execute;
16539
+ const state = {
16540
+ entries: [entry],
16541
+ originalExecute
16542
+ };
16543
+ toolRecord[AUTO_PATCHED_TOOL] = state;
14912
16544
  tool.execute = function executePatched(...args) {
16545
+ const activeEntry = activeAISDKChildPatchEntry(state.entries);
14913
16546
  const result = Reflect.apply(originalExecute, this, args);
16547
+ if (!activeEntry) {
16548
+ return result;
16549
+ }
14914
16550
  if (isAsyncGenerator(result)) {
14915
16551
  return (async function* () {
14916
- const span = parentSpan.startSpan({
14917
- name,
16552
+ const span = activeEntry.parentSpan.startSpan({
16553
+ name: activeEntry.name,
14918
16554
  spanAttributes: {
14919
16555
  type: "tool" /* TOOL */
14920
16556
  }
14921
16557
  });
14922
- span.log({ input: args.length === 1 ? args[0] : args });
16558
+ span.log({ input: serializeToolExecutionInput(args) });
14923
16559
  try {
14924
16560
  let lastValue;
14925
16561
  for await (const value of result) {
@@ -14935,15 +16571,15 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
14935
16571
  }
14936
16572
  })();
14937
16573
  }
14938
- return parentSpan.traced(
16574
+ return activeEntry.parentSpan.traced(
14939
16575
  async (span) => {
14940
- span.log({ input: args.length === 1 ? args[0] : args });
16576
+ span.log({ input: serializeToolExecutionInput(args) });
14941
16577
  const awaitedResult = await result;
14942
16578
  span.log({ output: awaitedResult });
14943
16579
  return awaitedResult;
14944
16580
  },
14945
16581
  {
14946
- name,
16582
+ name: activeEntry.name,
14947
16583
  spanAttributes: {
14948
16584
  type: "tool" /* TOOL */
14949
16585
  }
@@ -14951,8 +16587,7 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
14951
16587
  );
14952
16588
  };
14953
16589
  cleanup.push(() => {
14954
- tool.execute = originalExecute;
14955
- delete tool[AUTO_PATCHED_TOOL];
16590
+ cleanupToolEntry(state);
14956
16591
  });
14957
16592
  };
14958
16593
  const patchTools = (tools) => {
@@ -14971,25 +16606,42 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
14971
16606
  }
14972
16607
  };
14973
16608
  if (params && typeof params === "object") {
14974
- const patchedParamModel = patchModel(params.model);
14975
- if (typeof params.model === "string" && patchedParamModel && typeof patchedParamModel === "object") {
16609
+ const originalParamModel = params.model;
16610
+ const patchedParamModel = patchModel(originalParamModel);
16611
+ if (patchedParamModel && patchedParamModel !== originalParamModel) {
14976
16612
  params.model = patchedParamModel;
16613
+ cleanup.push(() => {
16614
+ params.model = originalParamModel;
16615
+ });
14977
16616
  }
14978
16617
  patchTools(params.tools);
14979
16618
  }
14980
16619
  if (self && typeof self === "object") {
14981
16620
  const selfRecord = self;
14982
16621
  if (selfRecord.model !== void 0) {
14983
- const patchedSelfModel = patchModel(selfRecord.model);
14984
- if (typeof selfRecord.model === "string" && patchedSelfModel && typeof patchedSelfModel === "object") {
16622
+ const originalSelfModel = selfRecord.model;
16623
+ const patchedSelfModel = patchModel(originalSelfModel);
16624
+ if (patchedSelfModel && patchedSelfModel !== originalSelfModel) {
14985
16625
  selfRecord.model = patchedSelfModel;
16626
+ cleanup.push(() => {
16627
+ selfRecord.model = originalSelfModel;
16628
+ });
14986
16629
  }
14987
16630
  }
16631
+ if (selfRecord.tools !== void 0) {
16632
+ patchTools(selfRecord.tools);
16633
+ }
14988
16634
  if (selfRecord.settings && typeof selfRecord.settings === "object") {
14989
16635
  if (selfRecord.settings.model !== void 0) {
14990
- const patchedSettingsModel = patchModel(selfRecord.settings.model);
14991
- if (typeof selfRecord.settings.model === "string" && patchedSettingsModel && typeof patchedSettingsModel === "object") {
16636
+ const originalSettingsModel = selfRecord.settings.model;
16637
+ const patchedSettingsModel = patchModel(originalSettingsModel);
16638
+ if (patchedSettingsModel && patchedSettingsModel !== originalSettingsModel) {
14992
16639
  selfRecord.settings.model = patchedSettingsModel;
16640
+ cleanup.push(() => {
16641
+ if (selfRecord.settings) {
16642
+ selfRecord.settings.model = originalSettingsModel;
16643
+ }
16644
+ });
14993
16645
  }
14994
16646
  }
14995
16647
  if (selfRecord.settings.tools !== void 0) {
@@ -15086,99 +16738,190 @@ function isAISDKContentAsyncIterableChunk(chunk) {
15086
16738
  return isObject(part) && typeof part.type !== "string";
15087
16739
  }
15088
16740
  function patchAISDKStreamingResult(args) {
15089
- const { defaultDenyOutputPaths, endEvent, result, span, startTime } = args;
16741
+ const {
16742
+ defaultDenyOutputPaths,
16743
+ endEvent,
16744
+ onComplete,
16745
+ result,
16746
+ span,
16747
+ startTime
16748
+ } = args;
15090
16749
  if (!result || typeof result !== "object") {
15091
16750
  return false;
15092
16751
  }
15093
16752
  const resultRecord = result;
15094
16753
  attachKnownResultPromiseHandlers(resultRecord);
16754
+ let finalized = false;
16755
+ const finalize = () => {
16756
+ if (finalized) {
16757
+ return;
16758
+ }
16759
+ finalized = true;
16760
+ finalizeAISDKChildTracing(endEvent);
16761
+ span.end();
16762
+ onComplete?.();
16763
+ };
16764
+ let outputLogged = false;
16765
+ const logStreamingOutput = async (firstChunkTime) => {
16766
+ if (outputLogged) {
16767
+ return;
16768
+ }
16769
+ outputLogged = true;
16770
+ try {
16771
+ const metrics = extractTopLevelAISDKMetrics(result, endEvent);
16772
+ if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
16773
+ metrics.time_to_first_token = firstChunkTime - startTime;
16774
+ }
16775
+ const output = await processAISDKStreamingOutput(
16776
+ result,
16777
+ resolveDenyOutputPaths(endEvent, defaultDenyOutputPaths)
16778
+ );
16779
+ const metadata = buildResolvedMetadataPayload(result).metadata;
16780
+ span.log({
16781
+ output,
16782
+ ...metadata ? { metadata } : {},
16783
+ metrics
16784
+ });
16785
+ } catch (error) {
16786
+ span.log({ error: toLoggedError(error) });
16787
+ } finally {
16788
+ finalize();
16789
+ }
16790
+ };
16791
+ const createAsyncIterableHooks = () => {
16792
+ let firstChunkTime;
16793
+ return {
16794
+ onChunk: (chunk) => {
16795
+ if (firstChunkTime === void 0 && isAISDKContentAsyncIterableChunk(chunk)) {
16796
+ firstChunkTime = getCurrentUnixTimestamp();
16797
+ }
16798
+ },
16799
+ onComplete: async () => {
16800
+ await logStreamingOutput(firstChunkTime);
16801
+ },
16802
+ onError: (error) => {
16803
+ if (!outputLogged) {
16804
+ outputLogged = true;
16805
+ span.log({
16806
+ error: error.message
16807
+ });
16808
+ }
16809
+ finalize();
16810
+ },
16811
+ onCancel: finalize
16812
+ };
16813
+ };
16814
+ const patchAsyncIterable = (stream) => isReadableStreamLike(stream) ? createPatchedReadableStream(stream, createAsyncIterableHooks()) : createPatchedAsyncIterable(stream, createAsyncIterableHooks());
16815
+ const patchAsyncIterableField = (field) => {
16816
+ let descriptorOwner = resultRecord;
16817
+ let descriptor;
16818
+ while (descriptorOwner) {
16819
+ descriptor = Object.getOwnPropertyDescriptor(descriptorOwner, field);
16820
+ if (descriptor) {
16821
+ break;
16822
+ }
16823
+ descriptorOwner = Object.getPrototypeOf(descriptorOwner);
16824
+ }
16825
+ if (!descriptor || descriptorOwner === resultRecord && !descriptor.configurable) {
16826
+ return false;
16827
+ }
16828
+ if ("value" in descriptor) {
16829
+ if (!isAsyncIterable(descriptor.value)) {
16830
+ return false;
16831
+ }
16832
+ try {
16833
+ Object.defineProperty(resultRecord, field, {
16834
+ configurable: descriptorOwner === resultRecord ? descriptor.configurable : true,
16835
+ enumerable: descriptor.enumerable,
16836
+ value: patchAsyncIterable(descriptor.value),
16837
+ writable: descriptor.writable
16838
+ });
16839
+ return true;
16840
+ } catch {
16841
+ return false;
16842
+ }
16843
+ }
16844
+ if (typeof descriptor.get !== "function") {
16845
+ return false;
16846
+ }
16847
+ const originalGet = descriptor.get;
16848
+ const originalSet = descriptor.set;
16849
+ try {
16850
+ Object.defineProperty(resultRecord, field, {
16851
+ configurable: descriptorOwner === resultRecord ? descriptor.configurable : true,
16852
+ enumerable: descriptor.enumerable,
16853
+ get() {
16854
+ const stream = originalGet.call(this);
16855
+ return isAsyncIterable(stream) ? patchAsyncIterable(stream) : stream;
16856
+ },
16857
+ ...originalSet ? {
16858
+ set(value) {
16859
+ originalSet.call(this, value);
16860
+ }
16861
+ } : {}
16862
+ });
16863
+ return true;
16864
+ } catch {
16865
+ return false;
16866
+ }
16867
+ };
16868
+ let patched = false;
15095
16869
  if (isReadableStreamLike(resultRecord.baseStream)) {
15096
- let firstChunkTime2;
15097
- const wrappedBaseStream = resultRecord.baseStream.pipeThrough(
16870
+ let firstChunkTime;
16871
+ const transformedBaseStream = resultRecord.baseStream.pipeThrough(
15098
16872
  new TransformStream({
15099
16873
  transform(chunk, controller) {
15100
- if (firstChunkTime2 === void 0 && isAISDKContentStreamChunk(chunk)) {
15101
- firstChunkTime2 = getCurrentUnixTimestamp();
16874
+ if (firstChunkTime === void 0 && isAISDKContentStreamChunk(chunk)) {
16875
+ firstChunkTime = getCurrentUnixTimestamp();
15102
16876
  }
15103
16877
  controller.enqueue(chunk);
15104
16878
  },
15105
16879
  async flush() {
15106
- const metrics = extractTopLevelAISDKMetrics(result, endEvent);
15107
- if (metrics.time_to_first_token === void 0 && firstChunkTime2 !== void 0) {
15108
- metrics.time_to_first_token = firstChunkTime2 - startTime;
15109
- }
15110
- const output = await processAISDKStreamingOutput(
15111
- result,
15112
- resolveDenyOutputPaths(endEvent, defaultDenyOutputPaths)
15113
- );
15114
- const metadata = buildResolvedMetadataPayload(result).metadata;
15115
- span.log({
15116
- output,
15117
- ...metadata ? { metadata } : {},
15118
- metrics
15119
- });
15120
- finalizeAISDKChildTracing(endEvent);
15121
- span.end();
16880
+ await logStreamingOutput(firstChunkTime);
15122
16881
  }
15123
16882
  })
15124
16883
  );
16884
+ const reader = transformedBaseStream.getReader();
16885
+ const wrappedBaseStream = new ReadableStream({
16886
+ async pull(controller) {
16887
+ try {
16888
+ const { done, value } = await reader.read();
16889
+ if (done) {
16890
+ controller.close();
16891
+ return;
16892
+ }
16893
+ controller.enqueue(value);
16894
+ } catch (error) {
16895
+ span.log({ error: toLoggedError(error) });
16896
+ finalize();
16897
+ controller.error(error);
16898
+ }
16899
+ },
16900
+ async cancel(reason) {
16901
+ try {
16902
+ finalize();
16903
+ } finally {
16904
+ await reader.cancel(reason);
16905
+ }
16906
+ }
16907
+ });
15125
16908
  Object.defineProperty(resultRecord, "baseStream", {
15126
16909
  configurable: true,
15127
16910
  enumerable: true,
15128
16911
  value: wrappedBaseStream,
15129
16912
  writable: true
15130
16913
  });
15131
- return true;
16914
+ patched = true;
15132
16915
  }
15133
- const streamField = findAsyncIterableField(resultRecord, [
16916
+ for (const field of [
15134
16917
  "partialObjectStream",
15135
16918
  "textStream",
15136
16919
  "fullStream",
15137
16920
  "stream"
15138
- ]);
15139
- if (!streamField) {
15140
- return false;
16921
+ ]) {
16922
+ patched = patchAsyncIterableField(field) || patched;
15141
16923
  }
15142
- let firstChunkTime;
15143
- const wrappedStream = createPatchedAsyncIterable(streamField.stream, {
15144
- onChunk: (chunk) => {
15145
- if (firstChunkTime === void 0 && isAISDKContentAsyncIterableChunk(chunk)) {
15146
- firstChunkTime = getCurrentUnixTimestamp();
15147
- }
15148
- },
15149
- onComplete: async () => {
15150
- const metrics = extractTopLevelAISDKMetrics(result, endEvent);
15151
- if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
15152
- metrics.time_to_first_token = firstChunkTime - startTime;
15153
- }
15154
- const output = await processAISDKStreamingOutput(
15155
- result,
15156
- resolveDenyOutputPaths(endEvent, defaultDenyOutputPaths)
15157
- );
15158
- const metadata = buildResolvedMetadataPayload(result).metadata;
15159
- span.log({
15160
- output,
15161
- ...metadata ? { metadata } : {},
15162
- metrics
15163
- });
15164
- finalizeAISDKChildTracing(endEvent);
15165
- span.end();
15166
- },
15167
- onError: (error) => {
15168
- span.log({
15169
- error: error.message
15170
- });
15171
- finalizeAISDKChildTracing(endEvent);
15172
- span.end();
15173
- }
15174
- });
15175
- Object.defineProperty(resultRecord, streamField.field, {
15176
- configurable: true,
15177
- enumerable: true,
15178
- value: wrappedStream,
15179
- writable: true
15180
- });
15181
- return true;
16924
+ return patched;
15182
16925
  }
15183
16926
  function attachKnownResultPromiseHandlers(result) {
15184
16927
  const promiseLikeFields = [
@@ -15210,34 +16953,72 @@ function attachKnownResultPromiseHandlers(result) {
15210
16953
  }
15211
16954
  }
15212
16955
  function isReadableStreamLike(value) {
15213
- return value != null && typeof value === "object" && typeof value.pipeThrough === "function";
15214
- }
15215
- function findAsyncIterableField(result, candidateFields) {
15216
- for (const field of candidateFields) {
15217
- try {
15218
- const stream = result[field];
15219
- if (isAsyncIterable(stream)) {
15220
- return { field, stream };
16956
+ return value != null && typeof value === "object" && typeof value.getReader === "function" && typeof value.pipeThrough === "function";
16957
+ }
16958
+ function createPatchedReadableStream(stream, hooks) {
16959
+ let reader;
16960
+ let completed = false;
16961
+ return new ReadableStream({
16962
+ async pull(controller) {
16963
+ reader ??= stream.getReader();
16964
+ try {
16965
+ const { done, value } = await reader.read();
16966
+ if (done) {
16967
+ completed = true;
16968
+ await hooks.onComplete();
16969
+ controller.close();
16970
+ return;
16971
+ }
16972
+ hooks.onChunk(value);
16973
+ controller.enqueue(value);
16974
+ } catch (error) {
16975
+ completed = true;
16976
+ hooks.onError(
16977
+ error instanceof Error ? error : new Error(String(error))
16978
+ );
16979
+ controller.error(error);
16980
+ }
16981
+ },
16982
+ async cancel(reason) {
16983
+ if (!completed) {
16984
+ completed = true;
16985
+ try {
16986
+ await hooks.onCancel?.();
16987
+ } catch {
16988
+ }
16989
+ }
16990
+ if (reader) {
16991
+ await reader.cancel(reason);
16992
+ } else if (stream.cancel) {
16993
+ await stream.cancel(reason);
15221
16994
  }
15222
- } catch {
15223
16995
  }
15224
- }
15225
- return null;
16996
+ });
15226
16997
  }
15227
16998
  function createPatchedAsyncIterable(stream, hooks) {
15228
16999
  return {
15229
17000
  async *[Symbol.asyncIterator]() {
17001
+ let completed = false;
15230
17002
  try {
15231
17003
  for await (const chunk of stream) {
15232
17004
  hooks.onChunk(chunk);
15233
17005
  yield chunk;
15234
17006
  }
17007
+ completed = true;
15235
17008
  await hooks.onComplete();
15236
17009
  } catch (error) {
17010
+ completed = true;
15237
17011
  hooks.onError(
15238
17012
  error instanceof Error ? error : new Error(String(error))
15239
17013
  );
15240
17014
  throw error;
17015
+ } finally {
17016
+ if (!completed) {
17017
+ try {
17018
+ await hooks.onCancel?.();
17019
+ } catch {
17020
+ }
17021
+ }
15241
17022
  }
15242
17023
  }
15243
17024
  };
@@ -15312,6 +17093,40 @@ function buildResolvedMetadataPayload(result) {
15312
17093
  }
15313
17094
  return Object.keys(metadata).length > 0 ? { metadata } : {};
15314
17095
  }
17096
+ function mergeMetadataPayload(metadataPayload, extraMetadata) {
17097
+ if (!extraMetadata || Object.keys(extraMetadata).length === 0) {
17098
+ return metadataPayload;
17099
+ }
17100
+ return {
17101
+ metadata: {
17102
+ ...metadataPayload.metadata ?? {},
17103
+ ...extraMetadata
17104
+ }
17105
+ };
17106
+ }
17107
+ function buildMissingUsageMetadata(output, metrics, reason) {
17108
+ if (!hasLoggedOutput(output) || hasTokenUsageMetrics(metrics)) {
17109
+ return void 0;
17110
+ }
17111
+ return { usage_unavailable_reason: reason };
17112
+ }
17113
+ function hasLoggedOutput(output) {
17114
+ if (output === null || output === void 0) {
17115
+ return false;
17116
+ }
17117
+ if (Array.isArray(output)) {
17118
+ return output.length > 0;
17119
+ }
17120
+ if (typeof output === "object") {
17121
+ return Object.keys(output).length > 0;
17122
+ }
17123
+ return true;
17124
+ }
17125
+ function hasTokenUsageMetrics(metrics) {
17126
+ return Object.keys(metrics).some(
17127
+ (key) => key !== "estimated_cost" && key !== "time_to_first_token"
17128
+ );
17129
+ }
15315
17130
  function resolveAISDKModel(model, aiSDK) {
15316
17131
  if (typeof model !== "string") {
15317
17132
  return model;
@@ -15335,7 +17150,45 @@ function isAsyncGenerator(value) {
15335
17150
  function processAISDKOutput(output, denyOutputPaths) {
15336
17151
  if (!output) return output;
15337
17152
  const merged = extractSerializableOutputFields(output);
15338
- return normalizeAISDKLoggedOutput(omit(merged, denyOutputPaths));
17153
+ const deleteOutputPaths = denyOutputPaths.filter(
17154
+ (path) => path.toLowerCase().endsWith("headers")
17155
+ );
17156
+ const sanitized = omit(merged, denyOutputPaths, deleteOutputPaths);
17157
+ for (const path of TRANSPORT_PAYLOAD_ROOT_PATHS) {
17158
+ const stack = [{ obj: sanitized, keys: parsePath(path) }];
17159
+ while (stack.length > 0) {
17160
+ const entry = stack.pop();
17161
+ if (!entry || entry.keys.length === 0) {
17162
+ continue;
17163
+ }
17164
+ const firstKey = entry.keys[0];
17165
+ const remainingKeys = entry.keys.slice(1);
17166
+ if (firstKey === "[]") {
17167
+ if (Array.isArray(entry.obj)) {
17168
+ for (const item of entry.obj) {
17169
+ stack.push({
17170
+ obj: item,
17171
+ keys: remainingKeys
17172
+ });
17173
+ }
17174
+ }
17175
+ continue;
17176
+ }
17177
+ if (!entry.obj || typeof entry.obj !== "object" || !(firstKey in entry.obj)) {
17178
+ continue;
17179
+ }
17180
+ const record = entry.obj;
17181
+ if (remainingKeys.length === 0) {
17182
+ record[firstKey] = sanitizeAISDKMetadataValue(record[firstKey]);
17183
+ continue;
17184
+ }
17185
+ stack.push({
17186
+ obj: record[firstKey],
17187
+ keys: remainingKeys
17188
+ });
17189
+ }
17190
+ }
17191
+ return normalizeAISDKLoggedOutput(sanitized);
15339
17192
  }
15340
17193
  function processAISDKEmbeddingOutput(output, denyOutputPaths) {
15341
17194
  if (!output || typeof output !== "object") {
@@ -15426,6 +17279,8 @@ function extractTokenMetrics(result) {
15426
17279
  );
15427
17280
  if (totalTokens !== void 0) {
15428
17281
  metrics.tokens = totalTokens;
17282
+ } else if (promptTokens !== void 0 && completionTokens !== void 0) {
17283
+ metrics.tokens = promptTokens + completionTokens;
15429
17284
  }
15430
17285
  const promptCachedTokens = firstNumber2(
15431
17286
  usage.inputTokens?.cacheRead,
@@ -15537,9 +17392,9 @@ function aggregateAISDKChunks(chunks, _result, endEvent) {
15537
17392
  if (finishReason !== void 0) {
15538
17393
  output.finishReason = finishReason;
15539
17394
  }
15540
- const toolCalls = safeSerializableFieldRead(lastChunk, "toolCalls");
15541
- if (toolCalls !== void 0) {
15542
- output.toolCalls = toolCalls;
17395
+ const toolCalls2 = safeSerializableFieldRead(lastChunk, "toolCalls");
17396
+ if (toolCalls2 !== void 0) {
17397
+ output.toolCalls = toolCalls2;
15543
17398
  }
15544
17399
  }
15545
17400
  finalizeAISDKChildTracing(endEvent);
@@ -15549,7 +17404,9 @@ function extractGetterValues(obj) {
15549
17404
  const getterValues = {};
15550
17405
  const getterNames = [
15551
17406
  "content",
17407
+ "messages",
15552
17408
  "text",
17409
+ "output",
15553
17410
  "object",
15554
17411
  "value",
15555
17412
  "values",
@@ -15589,7 +17446,9 @@ function extractGetterValues(obj) {
15589
17446
  function extractSerializableOutputFields(output) {
15590
17447
  const serialized = {};
15591
17448
  const directFieldNames = [
17449
+ "messages",
15592
17450
  "steps",
17451
+ "output",
15593
17452
  "request",
15594
17453
  "responseMessages",
15595
17454
  "warnings",
@@ -15771,7 +17630,7 @@ function parsePath(path) {
15771
17630
  }
15772
17631
  return keys;
15773
17632
  }
15774
- function omitAtPath(obj, keys) {
17633
+ function omitAtPath(obj, keys, deleteLeaf = false) {
15775
17634
  if (keys.length === 0) return;
15776
17635
  const firstKey = keys[0];
15777
17636
  const remainingKeys = keys.slice(1);
@@ -15781,29 +17640,36 @@ function omitAtPath(obj, keys) {
15781
17640
  if (remainingKeys.length > 0) {
15782
17641
  omitAtPath(
15783
17642
  item,
15784
- remainingKeys
17643
+ remainingKeys,
17644
+ deleteLeaf
15785
17645
  );
15786
17646
  }
15787
17647
  });
15788
17648
  }
15789
17649
  } else if (remainingKeys.length === 0) {
15790
17650
  if (obj && typeof obj === "object" && firstKey in obj) {
15791
- obj[firstKey] = "<omitted>";
17651
+ if (deleteLeaf) {
17652
+ delete obj[firstKey];
17653
+ } else {
17654
+ obj[firstKey] = "<omitted>";
17655
+ }
15792
17656
  }
15793
17657
  } else {
15794
17658
  if (obj && typeof obj === "object" && firstKey in obj) {
15795
17659
  omitAtPath(
15796
17660
  obj[firstKey],
15797
- remainingKeys
17661
+ remainingKeys,
17662
+ deleteLeaf
15798
17663
  );
15799
17664
  }
15800
17665
  }
15801
17666
  }
15802
- function omit(obj, paths) {
17667
+ function omit(obj, paths, deletePaths = []) {
15803
17668
  const result = deepCopy(obj);
17669
+ const deletePathSet = new Set(deletePaths);
15804
17670
  for (const path of paths) {
15805
17671
  const keys = parsePath(path);
15806
- omitAtPath(result, keys);
17672
+ omitAtPath(result, keys, deletePathSet.has(path));
15807
17673
  }
15808
17674
  return result;
15809
17675
  }
@@ -20012,8 +21878,8 @@ function getChatToolCallDeltas(value) {
20012
21878
  if (!Array.isArray(value?.tool_calls)) {
20013
21879
  return void 0;
20014
21880
  }
20015
- const toolCalls = value.tool_calls.filter((toolCall) => isObject(toolCall));
20016
- return toolCalls.length > 0 ? toolCalls : void 0;
21881
+ const toolCalls2 = value.tool_calls.filter((toolCall) => isObject(toolCall));
21882
+ return toolCalls2.length > 0 ? toolCalls2 : void 0;
20017
21883
  }
20018
21884
  function mergeChatToolCallDeltas(toolCallsByIndex, toolCallDeltas) {
20019
21885
  for (const toolDelta of toolCallDeltas) {
@@ -21502,7 +23368,7 @@ function aggregateOpenRouterChatChunks(chunks) {
21502
23368
  let reasoningContent = "";
21503
23369
  let hasReasoningContent = false;
21504
23370
  let reasoningDetails;
21505
- let toolCalls;
23371
+ let toolCalls2;
21506
23372
  let finishReason;
21507
23373
  let metrics = {};
21508
23374
  for (const chunk of chunks) {
@@ -21555,9 +23421,9 @@ function aggregateOpenRouterChatChunks(chunks) {
21555
23421
  continue;
21556
23422
  }
21557
23423
  const toolIndex = toolDelta.index ?? 0;
21558
- const existingToolCall = toolCalls?.[toolIndex];
23424
+ const existingToolCall = toolCalls2?.[toolIndex];
21559
23425
  if (!existingToolCall || toolDelta.id && existingToolCall.id !== void 0 && existingToolCall.id !== toolDelta.id) {
21560
- const nextToolCalls = [...toolCalls || []];
23426
+ const nextToolCalls = [...toolCalls2 || []];
21561
23427
  nextToolCalls[toolIndex] = {
21562
23428
  index: toolIndex,
21563
23429
  id: toolDelta.id,
@@ -21567,7 +23433,7 @@ function aggregateOpenRouterChatChunks(chunks) {
21567
23433
  arguments: toolDelta.function.arguments || ""
21568
23434
  }
21569
23435
  };
21570
- toolCalls = nextToolCalls;
23436
+ toolCalls2 = nextToolCalls;
21571
23437
  continue;
21572
23438
  }
21573
23439
  const current = existingToolCall;
@@ -21593,7 +23459,7 @@ function aggregateOpenRouterChatChunks(chunks) {
21593
23459
  ...hasReasoning || hasReasoningContent ? { reasoning } : {},
21594
23460
  ...hasReasoningContent ? { reasoning_content: reasoningContent } : {},
21595
23461
  ...reasoningDetails ? { reasoning_details: reasoningDetails } : {},
21596
- ...toolCalls ? { tool_calls: toolCalls } : {}
23462
+ ...toolCalls2 ? { tool_calls: toolCalls2 } : {}
21597
23463
  },
21598
23464
  logprobs: null,
21599
23465
  finish_reason: finishReason
@@ -22438,8 +24304,8 @@ function appendMistralContent(accumulator, content) {
22438
24304
  delete accumulator.content;
22439
24305
  }
22440
24306
  function getDeltaToolCalls(delta) {
22441
- const toolCalls = Array.isArray(delta.toolCalls) && delta.toolCalls || Array.isArray(delta.tool_calls) && delta.tool_calls || [];
22442
- return toolCalls.filter((toolCall) => isObject(toolCall));
24307
+ const toolCalls2 = Array.isArray(delta.toolCalls) && delta.toolCalls || Array.isArray(delta.tool_calls) && delta.tool_calls || [];
24308
+ return toolCalls2.filter((toolCall) => isObject(toolCall));
22443
24309
  }
22444
24310
  function getToolCallIndex(toolCall) {
22445
24311
  return typeof toolCall.index === "number" && toolCall.index >= 0 ? toolCall.index : void 0;
@@ -22466,11 +24332,11 @@ function mergeToolCallDeltaPair(current, delta) {
22466
24332
  }
22467
24333
  };
22468
24334
  }
22469
- function mergeToolCallDeltas(toolCalls, deltas) {
24335
+ function mergeToolCallDeltas(toolCalls2, deltas) {
22470
24336
  if (deltas.length === 0) {
22471
- return toolCalls;
24337
+ return toolCalls2;
22472
24338
  }
22473
- const merged = toolCalls ? [...toolCalls] : [];
24339
+ const merged = toolCalls2 ? [...toolCalls2] : [];
22474
24340
  const indexToPosition = /* @__PURE__ */ new Map();
22475
24341
  const idToPosition = /* @__PURE__ */ new Map();
22476
24342
  for (const [position, toolCall] of merged.entries()) {
@@ -23541,12 +25407,12 @@ function extractCohereChatOutput(result) {
23541
25407
  if (typeof result.text !== "string") {
23542
25408
  return void 0;
23543
25409
  }
23544
- const toolCalls = Array.isArray(result.toolCalls) ? result.toolCalls : Array.isArray(result.tool_calls) ? result.tool_calls : void 0;
23545
- if (toolCalls && toolCalls.length > 0) {
25410
+ const toolCalls2 = Array.isArray(result.toolCalls) ? result.toolCalls : Array.isArray(result.tool_calls) ? result.tool_calls : void 0;
25411
+ if (toolCalls2 && toolCalls2.length > 0) {
23546
25412
  return {
23547
25413
  content: result.text,
23548
25414
  role: "assistant",
23549
- toolCalls
25415
+ toolCalls: toolCalls2
23550
25416
  };
23551
25417
  }
23552
25418
  return result.text;
@@ -23879,10 +25745,10 @@ function aggregateCohereChatStreamChunks(chunks) {
23879
25745
  continue;
23880
25746
  }
23881
25747
  if (eventType === "tool-call-start") {
23882
- const toolCalls = isObject(chunk.delta) && isObject(chunk.delta.message) ? toToolCallArray(
25748
+ const toolCalls2 = isObject(chunk.delta) && isObject(chunk.delta.message) ? toToolCallArray(
23883
25749
  Array.isArray(chunk.delta.message.toolCalls) ? chunk.delta.message.toolCalls : chunk.delta.message.toolCalls ?? chunk.delta.message.tool_calls
23884
25750
  ) : [];
23885
- for (const [index, toolCall] of toolCalls.entries()) {
25751
+ for (const [index, toolCall] of toolCalls2.entries()) {
23886
25752
  const normalizedIndex = getToolCallIndex2(
23887
25753
  toolCall,
23888
25754
  typeof chunk.index === "number" ? chunk.index : index
@@ -25852,15 +27718,18 @@ function observeFlue(event, ctx) {
25852
27718
  getObserveBridge().handle(event, ctx);
25853
27719
  }
25854
27720
  var interceptFlueExecution = (operation, ctx, next) => getObserveBridge().intercept(operation, ctx, next);
25855
- var braintrustFlueObserver = Object.assign(
25856
- observeFlue,
25857
- {
27721
+ function braintrustFlueInstrumentation() {
27722
+ return {
25858
27723
  dispose() {
25859
27724
  },
25860
27725
  interceptor: interceptFlueExecution,
25861
27726
  key: FLUE_INSTRUMENTATION_KEY,
25862
27727
  observe: observeFlue
25863
- }
27728
+ };
27729
+ }
27730
+ var braintrustFlueObserver = Object.assign(
27731
+ observeFlue,
27732
+ braintrustFlueInstrumentation()
25864
27733
  );
25865
27734
  var FluePlugin = class extends BasePlugin {
25866
27735
  onEnable() {
@@ -27954,14 +29823,14 @@ function normalizeAssistantMessage(message) {
27954
29823
  const thinking = message.content.flatMap(
27955
29824
  (part) => part.type === "thinking" && !part.redacted ? [part.thinking] : []
27956
29825
  ).join("");
27957
- const toolCalls = message.content.flatMap(
29826
+ const toolCalls2 = message.content.flatMap(
27958
29827
  (part) => part.type === "toolCall" ? [normalizeToolCall(part)] : []
27959
29828
  );
27960
29829
  return {
27961
29830
  role: "assistant",
27962
- content: text || (toolCalls.length > 0 ? null : ""),
29831
+ content: text || (toolCalls2.length > 0 ? null : ""),
27963
29832
  ...thinking ? { reasoning: thinking } : {},
27964
- ...toolCalls.length > 0 ? { tool_calls: toolCalls } : {}
29833
+ ...toolCalls2.length > 0 ? { tool_calls: toolCalls2 } : {}
27965
29834
  };
27966
29835
  }
27967
29836
  function normalizeToolResultMessage(message) {
@@ -29459,8 +31328,10 @@ var exports_exports = {};
29459
31328
  __export(exports_exports, {
29460
31329
  Attachment: () => Attachment,
29461
31330
  AttachmentReference: () => AttachmentReference,
31331
+ BAGGAGE_HEADER: () => BAGGAGE_HEADER,
29462
31332
  BRAINTRUST_CURRENT_SPAN_STORE: () => BRAINTRUST_CURRENT_SPAN_STORE,
29463
31333
  BRAINTRUST_LANGCHAIN_CALLBACK_HANDLER_NAME: () => BRAINTRUST_LANGCHAIN_CALLBACK_HANDLER_NAME,
31334
+ BRAINTRUST_PARENT_KEY: () => BRAINTRUST_PARENT_KEY,
29464
31335
  BaseAttachment: () => BaseAttachment,
29465
31336
  BaseExperiment: () => BaseExperiment,
29466
31337
  BraintrustLangChainCallbackHandler: () => BraintrustLangChainCallbackHandler,
@@ -29493,6 +31364,7 @@ __export(exports_exports, {
29493
31364
  NOOP_SPAN: () => NOOP_SPAN,
29494
31365
  NOOP_SPAN_PERMALINK: () => NOOP_SPAN_PERMALINK,
29495
31366
  NoopSpan: () => NoopSpan,
31367
+ OTELIDGenerator: () => OTELIDGenerator,
29496
31368
  ObjectFetcher: () => ObjectFetcher,
29497
31369
  Project: () => Project2,
29498
31370
  ProjectNameIdMap: () => ProjectNameIdMap,
@@ -29504,6 +31376,8 @@ __export(exports_exports, {
29504
31376
  ScorerBuilder: () => ScorerBuilder,
29505
31377
  SpanFetcher: () => SpanFetcher,
29506
31378
  SpanImpl: () => SpanImpl,
31379
+ TRACEPARENT_HEADER: () => TRACEPARENT_HEADER,
31380
+ TRACESTATE_HEADER: () => TRACESTATE_HEADER,
29507
31381
  TestBackgroundLogger: () => TestBackgroundLogger,
29508
31382
  ToolBuilder: () => ToolBuilder,
29509
31383
  UUIDGenerator: () => UUIDGenerator,
@@ -29513,7 +31387,9 @@ __export(exports_exports, {
29513
31387
  _internalIso: () => isomorph_default,
29514
31388
  _internalSetInitialState: () => _internalSetInitialState,
29515
31389
  addAzureBlobHeaders: () => addAzureBlobHeaders,
31390
+ agentAssertionScorer: () => agentAssertionScorer,
29516
31391
  braintrustAISDKTelemetry: () => braintrustAISDKTelemetry,
31392
+ braintrustFlueInstrumentation: () => braintrustFlueInstrumentation,
29517
31393
  braintrustFlueObserver: () => braintrustFlueObserver,
29518
31394
  braintrustStreamChunkSchema: () => braintrustStreamChunkSchema,
29519
31395
  buildLocalSummary: () => buildLocalSummary,
@@ -29529,6 +31405,7 @@ __export(exports_exports, {
29529
31405
  devNullWritableStream: () => devNullWritableStream,
29530
31406
  evaluatorDefinitionSchema: () => evaluatorDefinitionSchema,
29531
31407
  evaluatorDefinitionsSchema: () => evaluatorDefinitionsSchema,
31408
+ extractTraceContextFromHeaders: () => extractTraceContextFromHeaders,
29532
31409
  flush: () => flush,
29533
31410
  getContextManager: () => getContextManager,
29534
31411
  getIdGenerator: () => getIdGenerator,
@@ -29542,6 +31419,7 @@ __export(exports_exports, {
29542
31419
  initFunction: () => initFunction,
29543
31420
  initLogger: () => initLogger,
29544
31421
  initNodeTestSuite: () => initNodeTestSuite,
31422
+ injectTraceContext: () => injectTraceContext,
29545
31423
  invoke: () => invoke,
29546
31424
  isTemplateFormat: () => isTemplateFormat,
29547
31425
  loadParameters: () => loadParameters,
@@ -29580,7 +31458,7 @@ __export(exports_exports, {
29580
31458
  traced: () => traced,
29581
31459
  updateSpan: () => updateSpan,
29582
31460
  uploadLogs3OverflowPayload: () => uploadLogs3OverflowPayload,
29583
- utf8ByteLength: () => utf8ByteLength,
31461
+ utf8ByteLength: () => utf8ByteLength2,
29584
31462
  withCurrent: () => withCurrent,
29585
31463
  withDataset: () => withDataset,
29586
31464
  withExperiment: () => withExperiment,
@@ -30173,6 +32051,7 @@ function wrapAISDK(aiSDK, options = {}) {
30173
32051
  case "Agent":
30174
32052
  case "Experimental_Agent":
30175
32053
  case "ToolLoopAgent":
32054
+ case "WorkflowAgent":
30176
32055
  return original ? wrapAgentClass(original, options) : original;
30177
32056
  }
30178
32057
  return original;
@@ -30191,10 +32070,10 @@ var wrapAgentClass = (AgentClass, options = {}) => {
30191
32070
  return new Proxy(instance, {
30192
32071
  get(instanceTarget, prop, instanceReceiver) {
30193
32072
  const original = Reflect.get(instanceTarget, prop, instanceTarget);
30194
- if (prop === "generate") {
32073
+ if (prop === "generate" && typeof original === "function" && instanceTarget.constructor.name !== "WorkflowAgent") {
30195
32074
  return wrapAgentGenerate(original, instanceTarget, options);
30196
32075
  }
30197
- if (prop === "stream") {
32076
+ if (prop === "stream" && typeof original === "function") {
30198
32077
  return wrapAgentStream(original, instanceTarget, options);
30199
32078
  }
30200
32079
  if (typeof original === "function") {
@@ -30209,7 +32088,7 @@ var wrapAgentClass = (AgentClass, options = {}) => {
30209
32088
  var wrapAgentGenerate = (generate, instance, options = {}) => {
30210
32089
  const defaultName = `${instance.constructor.name}.generate`;
30211
32090
  return async (params) => makeGenerateTextWrapper(
30212
- aiSDKChannels.generateText,
32091
+ generateChannelForAgent(instance.constructor.name),
30213
32092
  defaultName,
30214
32093
  generate.bind(instance),
30215
32094
  {
@@ -30219,19 +32098,42 @@ var wrapAgentGenerate = (generate, instance, options = {}) => {
30219
32098
  options
30220
32099
  )({ ...instance.settings, ...params });
30221
32100
  };
32101
+ function generateChannelForAgent(agentName) {
32102
+ if (agentName === "ToolLoopAgent") {
32103
+ return aiSDKChannels.toolLoopAgentGenerate;
32104
+ }
32105
+ return aiSDKChannels.agentGenerate;
32106
+ }
30222
32107
  var wrapAgentStream = (stream, instance, options = {}) => {
30223
32108
  const defaultName = `${instance.constructor.name}.stream`;
30224
- return (params) => makeStreamWrapper(
30225
- aiSDKChannels.agentStream,
30226
- defaultName,
30227
- stream.bind(instance),
30228
- {
30229
- self: instance,
30230
- spanType: "function" /* FUNCTION */
30231
- },
30232
- options
30233
- )({ ...instance.settings, ...params });
32109
+ return (params) => {
32110
+ const workflowAgent = instance.constructor.name === "WorkflowAgent";
32111
+ if (workflowAgent && currentWorkflowAgentWrapperSpan()) {
32112
+ const { span_info: _spanInfo, ...cleanParams } = params;
32113
+ return stream.call(instance, { ...instance.settings, ...cleanParams });
32114
+ }
32115
+ const trace = () => makeStreamWrapper(
32116
+ streamChannelForAgent(instance.constructor.name),
32117
+ defaultName,
32118
+ stream.bind(instance),
32119
+ {
32120
+ self: instance,
32121
+ spanType: "function" /* FUNCTION */
32122
+ },
32123
+ options
32124
+ )({ ...instance.settings, ...params });
32125
+ return trace();
32126
+ };
30234
32127
  };
32128
+ function streamChannelForAgent(agentName) {
32129
+ if (agentName === "ToolLoopAgent") {
32130
+ return aiSDKChannels.toolLoopAgentStream;
32131
+ }
32132
+ if (agentName === "WorkflowAgent") {
32133
+ return aiSDKChannels.workflowAgentStream;
32134
+ }
32135
+ return aiSDKChannels.agentStream;
32136
+ }
30235
32137
  var makeGenerateTextWrapper = (channel2, name, generateText, contextOptions = {}, options = {}) => {
30236
32138
  const wrapper = async function(allParams) {
30237
32139
  const { span_info, ...params } = allParams;
@@ -30493,7 +32395,7 @@ var BraintrustLanguageModelWrapper = class {
30493
32395
  let time_to_first_token = void 0;
30494
32396
  let usage = void 0;
30495
32397
  let fullText = void 0;
30496
- const toolCalls = {};
32398
+ const toolCalls2 = {};
30497
32399
  let finishReason = void 0;
30498
32400
  return {
30499
32401
  ...ret,
@@ -30512,7 +32414,7 @@ var BraintrustLanguageModelWrapper = class {
30512
32414
  fullText += chunk.textDelta;
30513
32415
  break;
30514
32416
  case "tool-call":
30515
- toolCalls[chunk.toolCallId] = {
32417
+ toolCalls2[chunk.toolCallId] = {
30516
32418
  toolCallType: chunk.toolCallType,
30517
32419
  toolCallId: chunk.toolCallId,
30518
32420
  toolName: chunk.toolName,
@@ -30520,15 +32422,15 @@ var BraintrustLanguageModelWrapper = class {
30520
32422
  };
30521
32423
  break;
30522
32424
  case "tool-call-delta":
30523
- if (toolCalls[chunk.toolCallId] === void 0) {
30524
- toolCalls[chunk.toolCallId] = {
32425
+ if (toolCalls2[chunk.toolCallId] === void 0) {
32426
+ toolCalls2[chunk.toolCallId] = {
30525
32427
  toolCallType: chunk.toolCallType,
30526
32428
  toolCallId: chunk.toolCallId,
30527
32429
  toolName: chunk.toolName,
30528
32430
  args: ""
30529
32431
  };
30530
32432
  }
30531
- toolCalls[chunk.toolCallId].args += chunk.argsTextDelta;
32433
+ toolCalls2[chunk.toolCallId].args += chunk.argsTextDelta;
30532
32434
  break;
30533
32435
  case "finish":
30534
32436
  usage = chunk.usage;
@@ -30541,7 +32443,7 @@ var BraintrustLanguageModelWrapper = class {
30541
32443
  span.log({
30542
32444
  output: postProcessOutput(
30543
32445
  fullText,
30544
- Object.keys(toolCalls).length > 0 ? Object.values(toolCalls) : void 0,
32446
+ Object.keys(toolCalls2).length > 0 ? Object.values(toolCalls2) : void 0,
30545
32447
  finishReason
30546
32448
  ),
30547
32449
  metrics: {
@@ -30642,15 +32544,15 @@ function postProcessPrompt(prompt) {
30642
32544
  }
30643
32545
  });
30644
32546
  }
30645
- function postProcessOutput(text, toolCalls, finishReason) {
32547
+ function postProcessOutput(text, toolCalls2, finishReason) {
30646
32548
  return [
30647
32549
  {
30648
32550
  index: 0,
30649
32551
  message: {
30650
32552
  role: "assistant",
30651
32553
  content: text ?? "",
30652
- ...toolCalls && toolCalls.length > 0 ? {
30653
- tool_calls: toolCalls.map((toolCall) => ({
32554
+ ...toolCalls2 && toolCalls2.length > 0 ? {
32555
+ tool_calls: toolCalls2.map((toolCall) => ({
30654
32556
  id: toolCall.toolCallId,
30655
32557
  function: {
30656
32558
  name: toolCall.toolName,
@@ -30749,29 +32651,29 @@ function normalizeFinishReason(reason) {
30749
32651
  if (typeof reason !== "string") return void 0;
30750
32652
  return reason.replace(/-/g, "_");
30751
32653
  }
30752
- function buildAssistantOutputWithToolCalls(result, toolCalls) {
32654
+ function buildAssistantOutputWithToolCalls(result, toolCalls2) {
30753
32655
  return [
30754
32656
  {
30755
32657
  index: 0,
30756
32658
  logprobs: null,
30757
- finish_reason: normalizeFinishReason(result?.finishReason) ?? (toolCalls.length ? "tool_calls" : void 0),
32659
+ finish_reason: normalizeFinishReason(result?.finishReason) ?? (toolCalls2.length ? "tool_calls" : void 0),
30758
32660
  message: {
30759
32661
  role: "assistant",
30760
- tool_calls: toolCalls.length > 0 ? toolCalls : void 0
32662
+ tool_calls: toolCalls2.length > 0 ? toolCalls2 : void 0
30761
32663
  }
30762
32664
  }
30763
32665
  ];
30764
32666
  }
30765
32667
  function extractToolCallsFromSteps(steps) {
30766
- const toolCalls = [];
30767
- if (!Array.isArray(steps)) return toolCalls;
32668
+ const toolCalls2 = [];
32669
+ if (!Array.isArray(steps)) return toolCalls2;
30768
32670
  let idx = 0;
30769
32671
  for (const step of steps) {
30770
32672
  const blocks = step?.content;
30771
32673
  if (!Array.isArray(blocks)) continue;
30772
32674
  for (const block of blocks) {
30773
32675
  if (block && typeof block === "object" && block.type === "tool-call") {
30774
- toolCalls.push({
32676
+ toolCalls2.push({
30775
32677
  id: block.toolCallId,
30776
32678
  type: "function",
30777
32679
  index: idx++,
@@ -30783,7 +32685,7 @@ function extractToolCallsFromSteps(steps) {
30783
32685
  }
30784
32686
  }
30785
32687
  }
30786
- return toolCalls;
32688
+ return toolCalls2;
30787
32689
  }
30788
32690
  function extractToolCallsFromBlocks(blocks) {
30789
32691
  if (!Array.isArray(blocks)) return [];
@@ -30849,12 +32751,12 @@ function BraintrustMiddleware(config = {}) {
30849
32751
  metadata.model = modelId;
30850
32752
  }
30851
32753
  }
30852
- let toolCalls = extractToolCallsFromSteps(result?.steps);
30853
- if (!toolCalls || toolCalls.length === 0) {
30854
- toolCalls = extractToolCallsFromBlocks(result?.content);
32754
+ let toolCalls2 = extractToolCallsFromSteps(result?.steps);
32755
+ if (!toolCalls2 || toolCalls2.length === 0) {
32756
+ toolCalls2 = extractToolCallsFromBlocks(result?.content);
30855
32757
  }
30856
32758
  span.log({
30857
- output: toolCalls.length > 0 ? buildAssistantOutputWithToolCalls(result, toolCalls) : result?.content,
32759
+ output: toolCalls2.length > 0 ? buildAssistantOutputWithToolCalls(result, toolCalls2) : result?.content,
30858
32760
  metadata,
30859
32761
  metrics: normalizeUsageMetrics(
30860
32762
  result.usage,
@@ -30943,13 +32845,13 @@ function BraintrustMiddleware(config = {}) {
30943
32845
  metadata.model = model;
30944
32846
  }
30945
32847
  if (toolBlocks.length > 0) {
30946
- const toolCalls = extractToolCallsFromSteps([
32848
+ const toolCalls2 = extractToolCallsFromSteps([
30947
32849
  { content: toolBlocks }
30948
32850
  ]);
30949
- if (toolCalls.length > 0) {
32851
+ if (toolCalls2.length > 0) {
30950
32852
  output = buildAssistantOutputWithToolCalls(
30951
32853
  resultForDetection,
30952
- toolCalls
32854
+ toolCalls2
30953
32855
  );
30954
32856
  }
30955
32857
  }
@@ -31584,9 +33486,9 @@ function isModuleNamespace3(obj) {
31584
33486
  const descriptor = Object.getOwnPropertyDescriptor(obj, keys[0]);
31585
33487
  return descriptor ? !descriptor.configurable && !descriptor.writable : false;
31586
33488
  }
31587
- function wrapCursorAgentClass(Agent) {
33489
+ function wrapCursorAgentClass(Agent2) {
31588
33490
  const cache = /* @__PURE__ */ new Map();
31589
- return new Proxy(Agent, {
33491
+ return new Proxy(Agent2, {
31590
33492
  get(target, prop, receiver) {
31591
33493
  if (cache.has(prop)) {
31592
33494
  return cache.get(prop);
@@ -35134,15 +37036,21 @@ var waterfall$1 = awaitify(waterfall);
35134
37036
 
35135
37037
  // src/trace.ts
35136
37038
  var SpanFetcher = class _SpanFetcher extends ObjectFetcher {
35137
- constructor(objectType, _objectId, rootSpanId, _state, spanTypeFilter, includeScorers = false) {
37039
+ constructor(objectType, _objectId, rootSpanId, _state, spanTypeFilter, includeScorers = false, brainstoreRealtime = true) {
35138
37040
  const filterExpr = _SpanFetcher.buildFilter(
35139
37041
  rootSpanId,
35140
37042
  spanTypeFilter,
35141
37043
  includeScorers
35142
37044
  );
35143
- super(objectType, void 0, void 0, {
35144
- filter: filterExpr
35145
- });
37045
+ super(
37046
+ objectType,
37047
+ void 0,
37048
+ void 0,
37049
+ {
37050
+ filter: filterExpr
37051
+ },
37052
+ brainstoreRealtime
37053
+ );
35146
37054
  this._objectId = _objectId;
35147
37055
  this.rootSpanId = rootSpanId;
35148
37056
  this._state = _state;
@@ -35196,7 +37104,7 @@ var CachedSpanFetcher = class {
35196
37104
  spanCache = /* @__PURE__ */ new Map();
35197
37105
  allFetched = false;
35198
37106
  fetchFn;
35199
- constructor(objectTypeOrFetchFn, objectId, rootSpanId, getState) {
37107
+ constructor(objectTypeOrFetchFn, objectId, rootSpanId, getState, brainstoreRealtime = true) {
35200
37108
  if (typeof objectTypeOrFetchFn === "function") {
35201
37109
  this.fetchFn = (spanType) => objectTypeOrFetchFn(spanType);
35202
37110
  } else {
@@ -35209,7 +37117,8 @@ var CachedSpanFetcher = class {
35209
37117
  rootSpanId,
35210
37118
  state,
35211
37119
  spanType,
35212
- includeScorers
37120
+ includeScorers,
37121
+ brainstoreRealtime
35213
37122
  );
35214
37123
  const rows = await fetcher.fetchedData();
35215
37124
  return rows.map((row) => ({
@@ -36039,7 +37948,7 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
36039
37948
  }
36040
37949
  };
36041
37950
  const parentStr = state.currentParent.getStore();
36042
- const parentComponents = parentStr ? SpanComponentsV3.fromStr(parentStr) : null;
37951
+ const parentComponents = typeof parentStr === "string" ? SpanComponentsV4.fromStr(parentStr) : null;
36043
37952
  const trace = state ? new LocalTrace({
36044
37953
  objectType: parentComponents ? spanObjectTypeV3ToTypedString(
36045
37954
  parentComponents.data.object_type
@@ -36565,6 +38474,350 @@ var defaultReporter = {
36565
38474
  }
36566
38475
  };
36567
38476
 
38477
+ // src/agent-assertions.ts
38478
+ function agentAssertionScorer(callback, options = {}) {
38479
+ return async (args) => {
38480
+ const { trace: _trace, ...callbackArgs } = args;
38481
+ const callbackMetadata = callbackArgs.metadata ?? {};
38482
+ const assertions = await callback({
38483
+ ...callbackArgs,
38484
+ metadata: callbackMetadata,
38485
+ assert: agentAssertionHelpers
38486
+ });
38487
+ const resources = {};
38488
+ if (assertions.some((assertion) => assertion.requiresTrace)) {
38489
+ resources.spans = await args.trace?.getSpans({ spanType: ["tool"] });
38490
+ }
38491
+ const results = await Promise.all(
38492
+ assertions.map(async (assertion) => {
38493
+ const result = await assertion.evaluate(resources);
38494
+ return {
38495
+ name: assertion.name,
38496
+ passed: result.passed,
38497
+ failure: result.failure
38498
+ };
38499
+ })
38500
+ );
38501
+ const passed = results.filter((result) => result.passed).length;
38502
+ const total = results.length;
38503
+ const failed = results.filter((result) => !result.passed).map(
38504
+ (result) => `${result.name}: ${result.failure ?? "assertion did not pass"}`
38505
+ );
38506
+ return {
38507
+ name: options.name ?? "assertions",
38508
+ score: total === 0 ? 1 : passed / total,
38509
+ metadata: {
38510
+ assertions: results.map(({ name, passed: passed2 }) => ({ name, passed: passed2 })),
38511
+ failed
38512
+ }
38513
+ };
38514
+ };
38515
+ }
38516
+ var agentAssertionHelpers = {
38517
+ equals: (actual, expected, name = "equals") => ({
38518
+ name,
38519
+ evaluate: () => {
38520
+ const passed = deepEqual(actual, expected);
38521
+ return {
38522
+ passed,
38523
+ failure: passed ? void 0 : `expected ${formatValue(actual)} to equal ${formatValue(expected)}`
38524
+ };
38525
+ }
38526
+ }),
38527
+ notEquals: (actual, expected, name = "not equals") => ({
38528
+ name,
38529
+ evaluate: () => {
38530
+ const passed = !deepEqual(actual, expected);
38531
+ return {
38532
+ passed,
38533
+ failure: passed ? void 0 : `expected ${formatValue(actual)} not to equal ${formatValue(expected)}`
38534
+ };
38535
+ }
38536
+ }),
38537
+ contains: (value, expected, name = "contains") => ({
38538
+ name,
38539
+ evaluate: () => {
38540
+ const searchedValue = typeof value === "string" ? value : formatValue(value);
38541
+ const passed = expected instanceof RegExp ? testRegex(expected, value) : searchedValue.includes(expected);
38542
+ return {
38543
+ passed,
38544
+ failure: passed ? void 0 : `expected ${formatValue(value)} to contain ${formatValue(expected)}`
38545
+ };
38546
+ }
38547
+ }),
38548
+ matches: (value, schema, name = "matches schema") => ({
38549
+ name,
38550
+ evaluate: async () => {
38551
+ const result = await validateSchema(schema, value);
38552
+ return {
38553
+ passed: result.passed,
38554
+ failure: result.passed ? void 0 : `expected value to match schema: ${result.message}`
38555
+ };
38556
+ }
38557
+ }),
38558
+ calledTool: (toolName, options = {}, name = `called tool ${toolName}`) => ({
38559
+ name,
38560
+ requiresTrace: true,
38561
+ evaluate: ({ spans }) => {
38562
+ const calls = matchingToolCalls(spans ?? [], toolName, options);
38563
+ const passed = options.times === void 0 ? calls.length > 0 : calls.length === options.times;
38564
+ return {
38565
+ passed,
38566
+ failure: passed ? void 0 : options.times === void 0 ? `expected tool "${toolName}" to be called; found ${calls.length} matching call${calls.length === 1 ? "" : "s"}` : `expected tool "${toolName}" to be called ${options.times} time${options.times === 1 ? "" : "s"}; found ${calls.length} matching call${calls.length === 1 ? "" : "s"}`
38567
+ };
38568
+ }
38569
+ }),
38570
+ notCalledTool: (toolName, name = `did not call tool ${toolName}`) => ({
38571
+ name,
38572
+ requiresTrace: true,
38573
+ evaluate: ({ spans }) => {
38574
+ const calls = toolCalls(spans ?? []).filter(
38575
+ (span) => getToolName(span) === toolName
38576
+ );
38577
+ const passed = calls.length === 0;
38578
+ return {
38579
+ passed,
38580
+ failure: passed ? void 0 : `expected tool "${toolName}" not to be called; found ${calls.length} call${calls.length === 1 ? "" : "s"}`
38581
+ };
38582
+ }
38583
+ }),
38584
+ toolOrder: (toolNames, name = "tool order") => ({
38585
+ name,
38586
+ requiresTrace: true,
38587
+ evaluate: ({ spans }) => {
38588
+ const observed = toolCalls(spans ?? []).map(getToolName).filter((toolName) => toolName !== void 0);
38589
+ let fromIndex = 0;
38590
+ const passed = toolNames.every((toolName) => {
38591
+ const index = observed.indexOf(toolName, fromIndex);
38592
+ if (index === -1) return false;
38593
+ fromIndex = index + 1;
38594
+ return true;
38595
+ });
38596
+ return {
38597
+ passed,
38598
+ failure: passed ? void 0 : `expected tool order ${toolNames.join(" -> ")}; observed ${observed.join(" -> ") || "no tools"}`
38599
+ };
38600
+ }
38601
+ }),
38602
+ usedNoTools: (name = "used no tools") => ({
38603
+ name,
38604
+ requiresTrace: true,
38605
+ evaluate: ({ spans }) => {
38606
+ const calls = toolCalls(spans ?? []);
38607
+ const passed = calls.length === 0;
38608
+ return {
38609
+ passed,
38610
+ failure: passed ? void 0 : `expected no tool calls; found ${calls.length}`
38611
+ };
38612
+ }
38613
+ }),
38614
+ maxToolCalls: (max, name = `at most ${max} tool calls`) => ({
38615
+ name,
38616
+ requiresTrace: true,
38617
+ evaluate: ({ spans }) => {
38618
+ const calls = toolCalls(spans ?? []);
38619
+ const passed = calls.length <= max;
38620
+ return {
38621
+ passed,
38622
+ failure: passed ? void 0 : `expected at most ${max} tool call${max === 1 ? "" : "s"}; found ${calls.length}`
38623
+ };
38624
+ }
38625
+ })
38626
+ };
38627
+ async function validateSchema(schema, value) {
38628
+ try {
38629
+ if ("safeParse" in schema) {
38630
+ const result2 = schema.safeParse(value);
38631
+ return result2.success ? { passed: true, message: "" } : { passed: false, message: formatSchemaError(result2.error) };
38632
+ }
38633
+ if ("parse" in schema) {
38634
+ schema.parse(value);
38635
+ return { passed: true, message: "" };
38636
+ }
38637
+ const result = await schema["~standard"].validate(value);
38638
+ if (typeof result === "object" && result !== null && "issues" in result && Array.isArray(result.issues) && result.issues.length > 0) {
38639
+ return { passed: false, message: formatValue(result.issues) };
38640
+ }
38641
+ return { passed: true, message: "" };
38642
+ } catch (e) {
38643
+ return { passed: false, message: formatSchemaError(e) };
38644
+ }
38645
+ }
38646
+ function toolCalls(spans) {
38647
+ return spans.filter((span) => span.span_attributes?.type === "tool");
38648
+ }
38649
+ function matchingToolCalls(spans, toolName, options) {
38650
+ return toolCalls(spans).filter((span) => {
38651
+ if (getToolName(span) !== toolName) return false;
38652
+ if (Object.prototype.hasOwnProperty.call(options, "input") && !matchesValue(span.input, options.input)) {
38653
+ return false;
38654
+ }
38655
+ if (Object.prototype.hasOwnProperty.call(options, "output") && !matchesValue(span.output, options.output)) {
38656
+ return false;
38657
+ }
38658
+ if (options.isError !== void 0 && Boolean(span.error) !== options.isError) {
38659
+ return false;
38660
+ }
38661
+ return true;
38662
+ });
38663
+ }
38664
+ function getToolName(span) {
38665
+ const spanName = [span.span_attributes?.name, span.name].map(normalizeToolName).find((value) => value !== void 0);
38666
+ if (spanName?.includes("/")) {
38667
+ return spanName;
38668
+ }
38669
+ const metadataName = [
38670
+ span.metadata?.tool_name,
38671
+ span.metadata?.["gen_ai.tool.name"]
38672
+ ].map(normalizeToolName).find((value) => value !== void 0);
38673
+ const mcpServer = [
38674
+ span.metadata?.["mcp.server"],
38675
+ span.metadata?.["openai_codex.mcp.server"]
38676
+ ].find((value) => typeof value === "string" && value !== "");
38677
+ if (metadataName && mcpServer) {
38678
+ return `${mcpServer}/${metadataName}`;
38679
+ }
38680
+ return metadataName ?? spanName;
38681
+ }
38682
+ function normalizeToolName(value) {
38683
+ if (typeof value !== "string" || value === "") {
38684
+ return void 0;
38685
+ }
38686
+ return value.startsWith("tool:") ? value.slice("tool:".length).trim() : value;
38687
+ }
38688
+ function matchesValue(actual, matcher) {
38689
+ if (matcher instanceof RegExp) {
38690
+ return testRegex(matcher, actual);
38691
+ }
38692
+ if (typeof matcher === "function") {
38693
+ return matcher(actual);
38694
+ }
38695
+ if (Array.isArray(matcher)) {
38696
+ return Array.isArray(actual) && actual.length === matcher.length && matcher.every((value, index) => matchesValue(actual[index], value));
38697
+ }
38698
+ if (isPlainObject(matcher) && isPlainObject(actual)) {
38699
+ return Object.entries(matcher).every(
38700
+ ([key, value]) => Object.prototype.hasOwnProperty.call(actual, key) && matchesValue(actual[key], value)
38701
+ );
38702
+ }
38703
+ return deepEqual(actual, matcher);
38704
+ }
38705
+ function testRegex(matcher, value) {
38706
+ matcher.lastIndex = 0;
38707
+ return matcher.test(typeof value === "string" ? value : formatValue(value));
38708
+ }
38709
+ function deepEqual(left, right) {
38710
+ if (Object.is(left, right)) return true;
38711
+ if (Array.isArray(left) && Array.isArray(right)) {
38712
+ return left.length === right.length && left.every((item, index) => deepEqual(item, right[index]));
38713
+ }
38714
+ if (isPlainObject(left) && isPlainObject(right)) {
38715
+ const leftKeys = Object.keys(left);
38716
+ const rightKeys = Object.keys(right);
38717
+ return leftKeys.length === rightKeys.length && leftKeys.every(
38718
+ (key) => Object.prototype.hasOwnProperty.call(right, key) && deepEqual(left[key], right[key])
38719
+ );
38720
+ }
38721
+ return false;
38722
+ }
38723
+ function isPlainObject(value) {
38724
+ return typeof value === "object" && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;
38725
+ }
38726
+ function formatSchemaError(error) {
38727
+ if (error instanceof Error) {
38728
+ return error.message;
38729
+ }
38730
+ return formatValue(error);
38731
+ }
38732
+ function formatValue(value) {
38733
+ if (value instanceof RegExp) {
38734
+ return value.toString();
38735
+ }
38736
+ if (typeof value === "string") {
38737
+ return JSON.stringify(value);
38738
+ }
38739
+ try {
38740
+ const serialized = JSON.stringify(value);
38741
+ if (serialized !== void 0 && !hasUndefinedJsonValue(value)) {
38742
+ return serialized;
38743
+ }
38744
+ return formatValueWithUndefined(value, /* @__PURE__ */ new Set());
38745
+ } catch {
38746
+ return String(value);
38747
+ }
38748
+ }
38749
+ function hasUndefinedJsonValue(value, seen = /* @__PURE__ */ new Set()) {
38750
+ if (value === void 0) {
38751
+ return true;
38752
+ }
38753
+ if (typeof value !== "object" || value === null) {
38754
+ return false;
38755
+ }
38756
+ if (seen.has(value)) {
38757
+ return false;
38758
+ }
38759
+ seen.add(value);
38760
+ if (Array.isArray(value)) {
38761
+ return Array.from({ length: value.length }).some(
38762
+ (_, index) => hasUndefinedJsonValue(value[index], seen)
38763
+ );
38764
+ }
38765
+ return Object.keys(value).some(
38766
+ (key) => hasUndefinedJsonValue(value[key], seen)
38767
+ );
38768
+ }
38769
+ function formatValueWithUndefined(value, seen) {
38770
+ if (value === void 0) {
38771
+ return "undefined";
38772
+ }
38773
+ if (value === null) {
38774
+ return "null";
38775
+ }
38776
+ if (typeof value === "string") {
38777
+ return JSON.stringify(value);
38778
+ }
38779
+ if (typeof value === "number" || typeof value === "boolean") {
38780
+ return JSON.stringify(value);
38781
+ }
38782
+ if (typeof value === "bigint" || typeof value === "function") {
38783
+ return String(value);
38784
+ }
38785
+ if (typeof value === "symbol") {
38786
+ return String(value);
38787
+ }
38788
+ if (value instanceof RegExp) {
38789
+ return value.toString();
38790
+ }
38791
+ if (typeof value !== "object") {
38792
+ return String(value);
38793
+ }
38794
+ if (seen.has(value)) {
38795
+ return '"[Circular]"';
38796
+ }
38797
+ seen.add(value);
38798
+ if (typeof value.toJSON === "function") {
38799
+ const jsonValue = value.toJSON();
38800
+ seen.delete(value);
38801
+ return formatValueWithUndefined(jsonValue, seen);
38802
+ }
38803
+ if (Array.isArray(value)) {
38804
+ const formatted2 = Array.from(
38805
+ { length: value.length },
38806
+ (_, index) => formatValueWithUndefined(value[index], seen)
38807
+ );
38808
+ seen.delete(value);
38809
+ return `[${formatted2.join(",")}]`;
38810
+ }
38811
+ const formatted = Object.keys(value).map(
38812
+ (key) => `${JSON.stringify(key)}:${formatValueWithUndefined(
38813
+ value[key],
38814
+ seen
38815
+ )}`
38816
+ );
38817
+ seen.delete(value);
38818
+ return `{${formatted.join(",")}}`;
38819
+ }
38820
+
36568
38821
  // src/dataset-pipeline.ts
36569
38822
  function DatasetPipeline(definition) {
36570
38823
  if (!globalThis.__braintrust_dataset_pipelines) {
@@ -37141,8 +39394,10 @@ configureWorkerd();
37141
39394
  export {
37142
39395
  Attachment,
37143
39396
  AttachmentReference,
39397
+ BAGGAGE_HEADER,
37144
39398
  BRAINTRUST_CURRENT_SPAN_STORE,
37145
39399
  BRAINTRUST_LANGCHAIN_CALLBACK_HANDLER_NAME,
39400
+ BRAINTRUST_PARENT_KEY,
37146
39401
  BaseAttachment,
37147
39402
  BaseExperiment,
37148
39403
  BraintrustLangChainCallbackHandler,
@@ -37175,6 +39430,7 @@ export {
37175
39430
  NOOP_SPAN,
37176
39431
  NOOP_SPAN_PERMALINK,
37177
39432
  NoopSpan,
39433
+ OTELIDGenerator,
37178
39434
  ObjectFetcher,
37179
39435
  Project2 as Project,
37180
39436
  ProjectNameIdMap,
@@ -37186,6 +39442,8 @@ export {
37186
39442
  ScorerBuilder,
37187
39443
  SpanFetcher,
37188
39444
  SpanImpl,
39445
+ TRACEPARENT_HEADER,
39446
+ TRACESTATE_HEADER,
37189
39447
  TestBackgroundLogger,
37190
39448
  ToolBuilder,
37191
39449
  UUIDGenerator,
@@ -37195,7 +39453,9 @@ export {
37195
39453
  isomorph_default as _internalIso,
37196
39454
  _internalSetInitialState,
37197
39455
  addAzureBlobHeaders,
39456
+ agentAssertionScorer,
37198
39457
  braintrustAISDKTelemetry,
39458
+ braintrustFlueInstrumentation,
37199
39459
  braintrustFlueObserver,
37200
39460
  braintrustStreamChunkSchema,
37201
39461
  buildLocalSummary,
@@ -37212,6 +39472,7 @@ export {
37212
39472
  devNullWritableStream,
37213
39473
  evaluatorDefinitionSchema,
37214
39474
  evaluatorDefinitionsSchema,
39475
+ extractTraceContextFromHeaders,
37215
39476
  flush,
37216
39477
  getContextManager,
37217
39478
  getIdGenerator,
@@ -37225,6 +39486,7 @@ export {
37225
39486
  initFunction,
37226
39487
  initLogger,
37227
39488
  initNodeTestSuite,
39489
+ injectTraceContext,
37228
39490
  invoke,
37229
39491
  isTemplateFormat,
37230
39492
  loadParameters,
@@ -37263,7 +39525,7 @@ export {
37263
39525
  traced,
37264
39526
  updateSpan,
37265
39527
  uploadLogs3OverflowPayload,
37266
- utf8ByteLength,
39528
+ utf8ByteLength2 as utf8ByteLength,
37267
39529
  withCurrent,
37268
39530
  withDataset,
37269
39531
  withExperiment,