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
@@ -499,8 +499,291 @@ var UUIDGenerator = class extends IDGenerator {
499
499
  return true;
500
500
  }
501
501
  };
502
+ function generateHexId(bytes) {
503
+ let result = "";
504
+ for (let i = 0; i < bytes; i++) {
505
+ result += Math.floor(Math.random() * 256).toString(16).padStart(2, "0");
506
+ }
507
+ return result;
508
+ }
509
+ var OTELIDGenerator = class extends IDGenerator {
510
+ getSpanId() {
511
+ return generateHexId(8);
512
+ }
513
+ getTraceId() {
514
+ return generateHexId(16);
515
+ }
516
+ shareRootSpanId() {
517
+ return false;
518
+ }
519
+ };
520
+ function parseEnvBool(name) {
521
+ const raw = isomorph_default.getEnv(name);
522
+ if (raw === void 0 || raw === null) {
523
+ return false;
524
+ }
525
+ const normalized = raw.trim().toLowerCase();
526
+ return normalized === "true" || normalized === "1" || normalized === "yes" || normalized === "y" || normalized === "on";
527
+ }
528
+ var _warnedLegacyUuidConflict = false;
529
+ function resolveUseLegacyUuidIds() {
530
+ const legacy = parseEnvBool("BRAINTRUST_LEGACY_IDS");
531
+ if (parseEnvBool("BRAINTRUST_OTEL_COMPAT")) {
532
+ if (legacy && !_warnedLegacyUuidConflict) {
533
+ _warnedLegacyUuidConflict = true;
534
+ debugLogger.warn(
535
+ "BRAINTRUST_LEGACY_IDS is ignored because BRAINTRUST_OTEL_COMPAT requires OpenTelemetry-compatible hex span IDs. Using hex IDs."
536
+ );
537
+ }
538
+ return false;
539
+ }
540
+ return legacy;
541
+ }
502
542
  function getIdGenerator() {
503
- return globalThis.BRAINTRUST_ID_GENERATOR !== void 0 ? new globalThis.BRAINTRUST_ID_GENERATOR() : new UUIDGenerator();
543
+ if (globalThis.BRAINTRUST_ID_GENERATOR !== void 0) {
544
+ return new globalThis.BRAINTRUST_ID_GENERATOR();
545
+ }
546
+ return resolveUseLegacyUuidIds() ? new UUIDGenerator() : new OTELIDGenerator();
547
+ }
548
+
549
+ // src/propagation.ts
550
+ var TRACEPARENT_HEADER = "traceparent";
551
+ var TRACESTATE_HEADER = "tracestate";
552
+ var BAGGAGE_HEADER = "baggage";
553
+ var BRAINTRUST_PARENT_KEY = "braintrust.parent";
554
+ var DEFAULT_TRACE_FLAGS = "01";
555
+ var TRACEPARENT_RE = /^00-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/;
556
+ var ZERO_TRACE_ID = "0".repeat(32);
557
+ var ZERO_SPAN_ID = "0".repeat(16);
558
+ var MAX_BAGGAGE_LENGTH = 8192;
559
+ var MAX_BAGGAGE_MEMBERS = 64;
560
+ var _utf8Encoder = new TextEncoder();
561
+ function utf8ByteLength(value) {
562
+ return _utf8Encoder.encode(value).length;
563
+ }
564
+ function capBaggageToMemberBoundary(value) {
565
+ const totalBytes = utf8ByteLength(value);
566
+ const withinBytes = totalBytes <= MAX_BAGGAGE_LENGTH;
567
+ let commaCount = 0;
568
+ for (let i = 0; i < value.length; i++) {
569
+ if (value.charCodeAt(i) === 44) {
570
+ commaCount++;
571
+ }
572
+ }
573
+ const withinMembers = commaCount < MAX_BAGGAGE_MEMBERS;
574
+ if (withinBytes && withinMembers) {
575
+ return value;
576
+ }
577
+ const kept = [];
578
+ let length = 0;
579
+ for (const rawMember of value.split(",")) {
580
+ if (kept.length >= MAX_BAGGAGE_MEMBERS) {
581
+ break;
582
+ }
583
+ const cost = utf8ByteLength(rawMember) + (kept.length ? 1 : 0);
584
+ if (length + cost > MAX_BAGGAGE_LENGTH) {
585
+ break;
586
+ }
587
+ kept.push(rawMember);
588
+ length += cost;
589
+ }
590
+ if (!kept.length) {
591
+ return "";
592
+ }
593
+ return kept.join(",");
594
+ }
595
+ function isTraceContextHeaderTupleArray(value) {
596
+ return Array.isArray(value) && value.every(
597
+ (item) => Array.isArray(item) && typeof item[0] === "string" && typeof item[1] === "string"
598
+ );
599
+ }
600
+ function isListHeader(name) {
601
+ const lowered = name.toLowerCase();
602
+ return lowered === BAGGAGE_HEADER || lowered === TRACESTATE_HEADER;
603
+ }
604
+ function headerValueToString(value, name) {
605
+ if (value === void 0 || value === null) {
606
+ return void 0;
607
+ }
608
+ if (Array.isArray(value)) {
609
+ const stringValues = value.filter((item) => {
610
+ return typeof item === "string";
611
+ });
612
+ if (!stringValues.length) {
613
+ return void 0;
614
+ }
615
+ return isListHeader(name) ? stringValues.join(",") : stringValues[0];
616
+ }
617
+ return typeof value === "string" ? value : String(value);
618
+ }
619
+ function getHeader(headers, name) {
620
+ if (!headers) {
621
+ return void 0;
622
+ }
623
+ if (isTraceContextHeaderTupleArray(headers)) {
624
+ const lowered2 = name.toLowerCase();
625
+ const matches = headers.filter(([key]) => key.toLowerCase() === lowered2).map(([, value]) => value);
626
+ if (!matches.length) {
627
+ return void 0;
628
+ }
629
+ return headerValueToString(matches, name);
630
+ }
631
+ const getter = headers.get;
632
+ if (typeof getter === "function") {
633
+ try {
634
+ const value = headerValueToString(getter.call(headers, name), name);
635
+ if (value !== void 0) {
636
+ return value;
637
+ }
638
+ } catch {
639
+ }
640
+ }
641
+ const nodeGetter = headers.getHeader;
642
+ if (typeof nodeGetter === "function") {
643
+ try {
644
+ const value = headerValueToString(nodeGetter.call(headers, name), name);
645
+ if (value !== void 0) {
646
+ return value;
647
+ }
648
+ } catch {
649
+ }
650
+ }
651
+ const headerBag = headers;
652
+ const exact = headerValueToString(headerBag[name], name);
653
+ if (exact !== void 0) {
654
+ return exact;
655
+ }
656
+ const lowered = name.toLowerCase();
657
+ for (const key of Object.keys(headers)) {
658
+ if (key !== name && key.toLowerCase() === lowered) {
659
+ const value = headerValueToString(headerBag[key], name);
660
+ if (value !== void 0) {
661
+ return value;
662
+ }
663
+ }
664
+ }
665
+ return void 0;
666
+ }
667
+ function isHex(value, length) {
668
+ if (typeof value !== "string" || value.length !== length) {
669
+ return false;
670
+ }
671
+ for (let i = 0; i < value.length; i++) {
672
+ const c = value[i];
673
+ const isDigit = c >= "0" && c <= "9";
674
+ const isLowerHex = c >= "a" && c <= "f";
675
+ if (!isDigit && !isLowerHex) {
676
+ return false;
677
+ }
678
+ }
679
+ return true;
680
+ }
681
+ function parseTraceparent(value) {
682
+ if (!value || typeof value !== "string") {
683
+ return void 0;
684
+ }
685
+ const match = TRACEPARENT_RE.exec(value.trim());
686
+ if (!match) {
687
+ return void 0;
688
+ }
689
+ const traceId = match[1];
690
+ const spanId = match[2];
691
+ const traceFlags = match[3];
692
+ if (traceId === ZERO_TRACE_ID || spanId === ZERO_SPAN_ID) {
693
+ return void 0;
694
+ }
695
+ return { traceId, spanId, traceFlags };
696
+ }
697
+ function formatTraceparent(traceId, spanId, traceFlags = DEFAULT_TRACE_FLAGS) {
698
+ if (!isHex(traceId, 32) || traceId === ZERO_TRACE_ID) {
699
+ return void 0;
700
+ }
701
+ if (!isHex(spanId, 16) || spanId === ZERO_SPAN_ID) {
702
+ return void 0;
703
+ }
704
+ const flags = isHex(traceFlags, 2) ? traceFlags : DEFAULT_TRACE_FLAGS;
705
+ return `00-${traceId}-${spanId}-${flags}`;
706
+ }
707
+ function percentEncode(value) {
708
+ return encodeURIComponent(value);
709
+ }
710
+ function percentDecode(value) {
711
+ if (!value.includes("%")) {
712
+ return value;
713
+ }
714
+ try {
715
+ return decodeURIComponent(value);
716
+ } catch {
717
+ return value;
718
+ }
719
+ }
720
+ function parseBaggage(value) {
721
+ const result = {};
722
+ if (!value || typeof value !== "string") {
723
+ return result;
724
+ }
725
+ const bounded = capBaggageToMemberBoundary(value);
726
+ for (let member of bounded.split(",")) {
727
+ member = member.trim();
728
+ if (!member || !member.includes("=")) {
729
+ continue;
730
+ }
731
+ member = member.split(";", 1)[0];
732
+ const eq = member.indexOf("=");
733
+ const key = percentDecode(member.slice(0, eq).trim());
734
+ const val = member.slice(eq + 1).trim();
735
+ if (!key) {
736
+ continue;
737
+ }
738
+ result[key] = percentDecode(val);
739
+ }
740
+ return result;
741
+ }
742
+ function mergeBaggage(existing, braintrustParent) {
743
+ let btMember = void 0;
744
+ if (braintrustParent) {
745
+ const encodedKey = percentEncode(BRAINTRUST_PARENT_KEY);
746
+ const encodedVal = percentEncode(String(braintrustParent));
747
+ btMember = `${encodedKey}=${encodedVal}`;
748
+ if (utf8ByteLength(btMember) > MAX_BAGGAGE_LENGTH) {
749
+ btMember = void 0;
750
+ }
751
+ }
752
+ let byteBudget = MAX_BAGGAGE_LENGTH;
753
+ let memberBudget = MAX_BAGGAGE_MEMBERS;
754
+ if (btMember !== void 0) {
755
+ byteBudget -= utf8ByteLength(btMember) + 1;
756
+ memberBudget -= 1;
757
+ }
758
+ const relayed = [];
759
+ let length = 0;
760
+ if (existing && typeof existing === "string") {
761
+ for (const rawMember of existing.split(",")) {
762
+ const member = rawMember.trim();
763
+ if (!member || !member.includes("=")) {
764
+ continue;
765
+ }
766
+ const keyPart = member.split(";", 1)[0].split("=", 1)[0];
767
+ const key = percentDecode(keyPart.trim());
768
+ if (key === BRAINTRUST_PARENT_KEY) {
769
+ continue;
770
+ }
771
+ if (relayed.length >= memberBudget) {
772
+ break;
773
+ }
774
+ const cost = utf8ByteLength(member) + (relayed.length ? 1 : 0);
775
+ if (length + cost > byteBudget) {
776
+ break;
777
+ }
778
+ relayed.push(member);
779
+ length += cost;
780
+ }
781
+ }
782
+ const members = btMember !== void 0 ? [...relayed, btMember] : relayed;
783
+ if (!members.length) {
784
+ return void 0;
785
+ }
786
+ return members.join(",");
504
787
  }
505
788
 
506
789
  // util/db_fields.ts
@@ -1108,7 +1391,7 @@ var SpanComponentsV3 = class _SpanComponentsV3 {
1108
1391
  case 3 /* PLAYGROUND_LOGS */:
1109
1392
  return { prompt_session_id: this.data.object_id, log_id: "x" };
1110
1393
  default:
1111
- const _ = this.data.object_type;
1394
+ this.data.object_type;
1112
1395
  throw new Error("Impossible");
1113
1396
  }
1114
1397
  }
@@ -1550,7 +1833,7 @@ var SpanComponentsV4 = class _SpanComponentsV4 {
1550
1833
  case 3 /* PLAYGROUND_LOGS */:
1551
1834
  return { prompt_session_id: this.data.object_id, log_id: "x" };
1552
1835
  default:
1553
- const _ = this.data.object_type;
1836
+ this.data.object_type;
1554
1837
  throw new Error(`Invalid object_type ${this.data.object_type}`);
1555
1838
  }
1556
1839
  }
@@ -1683,7 +1966,8 @@ var AclObjectType = z6.union([
1683
1966
  "role",
1684
1967
  "org_member",
1685
1968
  "project_log",
1686
- "org_project"
1969
+ "org_project",
1970
+ "org_audit_logs"
1687
1971
  ]),
1688
1972
  z6.null()
1689
1973
  ]);
@@ -1709,6 +1993,17 @@ var Acl = z6.object({
1709
1993
  _object_org_id: z6.string().uuid(),
1710
1994
  created: z6.union([z6.string(), z6.null()]).optional()
1711
1995
  });
1996
+ var Agent = z6.object({
1997
+ id: z6.string().uuid(),
1998
+ project_id: z6.string().uuid(),
1999
+ user_id: z6.string().uuid(),
2000
+ created: z6.union([z6.string(), z6.null()]).optional(),
2001
+ name: z6.string(),
2002
+ slug: z6.string(),
2003
+ kind: z6.string(),
2004
+ description: z6.union([z6.string(), z6.null()]).optional(),
2005
+ metadata: z6.union([z6.object({}).partial().passthrough(), z6.null()]).optional()
2006
+ });
1712
2007
  var AISecret = z6.object({
1713
2008
  id: z6.string().uuid(),
1714
2009
  created: z6.union([z6.string(), z6.null()]).optional(),
@@ -1855,6 +2150,7 @@ var AttachmentStatus = z6.object({
1855
2150
  upload_status: UploadStatus,
1856
2151
  error_message: z6.string().optional()
1857
2152
  });
2153
+ var AutomationStatus = z6.enum(["active", "paused"]);
1858
2154
  var FunctionTypeEnum = z6.enum([
1859
2155
  "llm",
1860
2156
  "scorer",
@@ -1900,7 +2196,9 @@ var TopicMapData = z6.object({
1900
2196
  topic_names: z6.record(z6.string()).optional(),
1901
2197
  generation_settings: TopicMapGenerationSettings.optional(),
1902
2198
  disable_reconciliation: z6.boolean().optional(),
1903
- distance_threshold: z6.number().optional()
2199
+ distance_threshold: z6.number().optional(),
2200
+ btql_filter: z6.string().optional(),
2201
+ automation_btql_filter: z6.string().optional()
1904
2202
  });
1905
2203
  var BatchedFacetData = z6.object({
1906
2204
  type: z6.literal("batched_facet"),
@@ -2183,7 +2481,7 @@ var DatasetEvent = z6.object({
2183
2481
  origin: ObjectReferenceNullish.optional(),
2184
2482
  comments: z6.union([z6.array(z6.unknown()), z6.null()]).optional(),
2185
2483
  audit_data: z6.union([z6.array(z6.unknown()), z6.null()]).optional(),
2186
- facets: z6.union([z6.object({}).partial().passthrough(), z6.null()]).optional(),
2484
+ facets: z6.union([z6.record(z6.union([z6.string(), z6.null()])), z6.null()]).optional(),
2187
2485
  classifications: z6.union([
2188
2486
  z6.record(
2189
2487
  z6.array(
@@ -2335,7 +2633,7 @@ var ExperimentEvent = z6.object({
2335
2633
  origin: ObjectReferenceNullish.optional(),
2336
2634
  comments: z6.union([z6.array(z6.unknown()), z6.null()]).optional(),
2337
2635
  audit_data: z6.union([z6.array(z6.unknown()), z6.null()]).optional(),
2338
- facets: z6.union([z6.object({}).partial().passthrough(), z6.null()]).optional(),
2636
+ facets: z6.union([z6.record(z6.union([z6.string(), z6.null()])), z6.null()]).optional(),
2339
2637
  classifications: z6.union([
2340
2638
  z6.record(
2341
2639
  z6.array(
@@ -2473,7 +2771,8 @@ var PromptParserNullish = z6.union([
2473
2771
  use_cot: z6.boolean(),
2474
2772
  choice_scores: z6.record(z6.number().gte(0).lte(1)).optional(),
2475
2773
  choice: z6.array(z6.string()).optional(),
2476
- allow_no_match: z6.boolean().optional()
2774
+ allow_no_match: z6.boolean().optional(),
2775
+ allow_skip: z6.boolean().optional()
2477
2776
  }),
2478
2777
  z6.null()
2479
2778
  ]);
@@ -2803,6 +3102,9 @@ var Group = z6.object({
2803
3102
  var GroupScope = z6.object({
2804
3103
  type: z6.literal("group"),
2805
3104
  group_by: z6.string(),
3105
+ interval_seconds: z6.number().gte(1).optional(),
3106
+ max_traces: z6.number().int().gte(1).lte(64).optional(),
3107
+ placement: z6.enum(["first", "each"]),
2806
3108
  idle_seconds: z6.number().optional()
2807
3109
  });
2808
3110
  var IfExists = z6.enum(["error", "ignore", "replace"]);
@@ -2951,6 +3253,10 @@ var RetentionObjectType = z6.enum([
2951
3253
  "experiment",
2952
3254
  "dataset"
2953
3255
  ]);
3256
+ var TopicAutomationFacetModel = z6.union([
3257
+ z6.enum(["brain-facet-latest", "brain-facet-1", "brain-facet-2"]),
3258
+ z6.null()
3259
+ ]);
2954
3260
  var TopicMapFunctionAutomation = z6.object({
2955
3261
  function: SavedFunctionId.and(z6.unknown()),
2956
3262
  btql_filter: z6.union([z6.string(), z6.null()]).optional()
@@ -2963,7 +3269,9 @@ var TopicAutomationDataScope = z6.union([
2963
3269
  ]);
2964
3270
  var TopicAutomationConfig = z6.object({
2965
3271
  event_type: z6.literal("topic"),
3272
+ status: AutomationStatus.optional(),
2966
3273
  sampling_rate: z6.number().gte(0).lte(1),
3274
+ facet_model: TopicAutomationFacetModel.optional(),
2967
3275
  facet_functions: z6.array(SavedFunctionId),
2968
3276
  topic_map_functions: z6.array(TopicMapFunctionAutomation),
2969
3277
  scope: z6.union([SpanScope, TraceScope, GroupScope, z6.null()]).optional(),
@@ -2977,6 +3285,19 @@ var TopicAutomationConfig = z6.object({
2977
3285
  z6.null()
2978
3286
  ]).optional()
2979
3287
  });
3288
+ var TopicDigestAutomationConfig = z6.object({
3289
+ event_type: z6.literal("topic_digest"),
3290
+ status: AutomationStatus.optional(),
3291
+ window_seconds: z6.number().int().gte(3600).lte(2592e3).optional().default(86400),
3292
+ scheduled_time_minutes_utc: z6.number().int().gte(0).lte(1439),
3293
+ action: z6.object({
3294
+ type: z6.literal("slack"),
3295
+ workspace_id: z6.string(),
3296
+ channel: z6.string(),
3297
+ message_template: z6.string().optional()
3298
+ }),
3299
+ topic_map_function_ids: z6.array(z6.string()).max(10).optional()
3300
+ });
2980
3301
  var ProjectAutomation = z6.object({
2981
3302
  id: z6.string().uuid(),
2982
3303
  project_id: z6.string().uuid(),
@@ -3001,6 +3322,7 @@ var ProjectAutomation = z6.object({
3001
3322
  }),
3002
3323
  z6.object({
3003
3324
  event_type: z6.literal("btql_export"),
3325
+ status: AutomationStatus.optional(),
3004
3326
  export_definition: z6.union([
3005
3327
  z6.object({ type: z6.literal("log_traces") }),
3006
3328
  z6.object({ type: z6.literal("log_spans") }),
@@ -3023,6 +3345,21 @@ var ProjectAutomation = z6.object({
3023
3345
  ]),
3024
3346
  batch_size: z6.union([z6.number(), z6.null()]).optional()
3025
3347
  }),
3348
+ z6.object({
3349
+ event_type: z6.literal("async_query"),
3350
+ status: AutomationStatus.optional(),
3351
+ created_by_user_id: z6.string().uuid(),
3352
+ object_type: z6.enum([
3353
+ "project_logs",
3354
+ "experiment",
3355
+ "dataset",
3356
+ "playground_logs"
3357
+ ]),
3358
+ object_id: z6.string(),
3359
+ query: z6.string(),
3360
+ format: z6.literal("jsonl"),
3361
+ batch_size: z6.union([z6.number(), z6.null()]).optional()
3362
+ }),
3026
3363
  z6.object({
3027
3364
  event_type: z6.literal("retention"),
3028
3365
  object_type: RetentionObjectType,
@@ -3041,7 +3378,8 @@ var ProjectAutomation = z6.object({
3041
3378
  })
3042
3379
  ])
3043
3380
  }),
3044
- TopicAutomationConfig
3381
+ TopicAutomationConfig,
3382
+ TopicDigestAutomationConfig
3045
3383
  ])
3046
3384
  });
3047
3385
  var ProjectLogsEvent = z6.object({
@@ -3080,7 +3418,7 @@ var ProjectLogsEvent = z6.object({
3080
3418
  comments: z6.union([z6.array(z6.unknown()), z6.null()]).optional(),
3081
3419
  audit_data: z6.union([z6.array(z6.unknown()), z6.null()]).optional(),
3082
3420
  _async_scoring_state: z6.unknown().optional(),
3083
- facets: z6.union([z6.object({}).partial().passthrough(), z6.null()]).optional(),
3421
+ facets: z6.union([z6.record(z6.union([z6.string(), z6.null()])), z6.null()]).optional(),
3084
3422
  classifications: z6.union([
3085
3423
  z6.record(
3086
3424
  z6.array(
@@ -3129,11 +3467,34 @@ var ProjectScoreCategories = z6.union([
3129
3467
  z6.array(z6.string()),
3130
3468
  z6.null()
3131
3469
  ]);
3470
+ var ProjectScoreCondition = z6.union([
3471
+ z6.object({
3472
+ when: z6.object({
3473
+ clauses: z6.union([z6.array(z6.string()), z6.null()]),
3474
+ subspan_clauses: z6.union([z6.array(z6.string()), z6.null()]),
3475
+ trace_clauses: z6.union([z6.array(z6.string()), z6.null()])
3476
+ }).partial(),
3477
+ behavior: z6.literal("hidden").optional().default("hidden")
3478
+ }),
3479
+ z6.null()
3480
+ ]);
3132
3481
  var ProjectScoreConfig = z6.union([
3133
3482
  z6.object({
3134
3483
  multi_select: z6.union([z6.boolean(), z6.null()]),
3135
3484
  destination: z6.union([z6.string(), z6.null()]),
3136
- online: OnlineScoreConfig
3485
+ visibility: z6.union([
3486
+ z6.object({
3487
+ users: z6.union([z6.array(z6.string()), z6.null()]),
3488
+ groups: z6.union([z6.array(z6.string()), z6.null()])
3489
+ }).partial(),
3490
+ z6.null()
3491
+ ]),
3492
+ online: OnlineScoreConfig,
3493
+ condition: ProjectScoreCondition,
3494
+ object_types: z6.union([
3495
+ z6.array(z6.enum(["project_logs", "dataset", "experiment"])),
3496
+ z6.null()
3497
+ ])
3137
3498
  }).partial(),
3138
3499
  z6.null()
3139
3500
  ]);
@@ -3318,8 +3679,7 @@ var User = z6.object({
3318
3679
  family_name: z6.union([z6.string(), z6.null()]).optional(),
3319
3680
  email: z6.union([z6.string(), z6.null()]).optional(),
3320
3681
  avatar_url: z6.union([z6.string(), z6.null()]).optional(),
3321
- created: z6.union([z6.string(), z6.null()]).optional(),
3322
- last_active_at: z6.union([z6.number(), z6.null()]).optional()
3682
+ created: z6.union([z6.string(), z6.null()]).optional()
3323
3683
  });
3324
3684
  var ViewDataSearch = z6.union([
3325
3685
  z6.object({
@@ -4580,7 +4940,10 @@ var BraintrustContextManager = class extends ContextManager {
4580
4940
  }
4581
4941
  };
4582
4942
  function getSpanComponentsClass() {
4583
- return globalThis.BRAINTRUST_SPAN_COMPONENT ? globalThis.BRAINTRUST_SPAN_COMPONENT : SpanComponentsV3;
4943
+ if (globalThis.BRAINTRUST_SPAN_COMPONENT) {
4944
+ return globalThis.BRAINTRUST_SPAN_COMPONENT;
4945
+ }
4946
+ return resolveUseLegacyUuidIds() ? SpanComponentsV3 : SpanComponentsV4;
4584
4947
  }
4585
4948
  function getContextManager() {
4586
4949
  return globalThis.BRAINTRUST_CONTEXT_MANAGER ? new globalThis.BRAINTRUST_CONTEXT_MANAGER() : new BraintrustContextManager();
@@ -4616,6 +4979,9 @@ var NoopSpan = class {
4616
4979
  async export() {
4617
4980
  return "";
4618
4981
  }
4982
+ inject(carrier) {
4983
+ return carrier ?? {};
4984
+ }
4619
4985
  async permalink() {
4620
4986
  return NOOP_SPAN_PERMALINK;
4621
4987
  }
@@ -4666,6 +5032,10 @@ var loginSchema = z8.strictObject({
4666
5032
  debugLogLevelDisabled: z8.boolean().optional()
4667
5033
  });
4668
5034
  var stateNonce = 0;
5035
+ var V1_PROXY_SUFFIX = "/v1/proxy";
5036
+ function normalizeProxyConnUrl(proxyUrl) {
5037
+ return proxyUrl.endsWith(V1_PROXY_SUFFIX) ? proxyUrl.slice(0, proxyUrl.length - V1_PROXY_SUFFIX.length) : proxyUrl;
5038
+ }
4669
5039
  var BraintrustState = class _BraintrustState {
4670
5040
  constructor(loginParams) {
4671
5041
  this.loginParams = loginParams;
@@ -4936,7 +5306,10 @@ var BraintrustState = class _BraintrustState {
4936
5306
  if (!this.proxyUrl) {
4937
5307
  throw new Error("Must initialize proxyUrl before requesting proxyConn");
4938
5308
  }
4939
- this._proxyConn = new HTTPConnection(this.proxyUrl, this.fetch);
5309
+ this._proxyConn = new HTTPConnection(
5310
+ normalizeProxyConnUrl(this.proxyUrl),
5311
+ this.fetch
5312
+ );
4940
5313
  }
4941
5314
  return this._proxyConn;
4942
5315
  }
@@ -5609,7 +5982,7 @@ async function permalink(slug, opts) {
5609
5982
  return state.appUrl;
5610
5983
  };
5611
5984
  try {
5612
- const components = getSpanComponentsClass().fromStr(slug);
5985
+ const components = SpanComponentsV4.fromStr(slug);
5613
5986
  const object_type = spanObjectTypeV3ToString(components.data.object_type);
5614
5987
  const [orgName, appUrl, object_id] = await Promise.all([
5615
5988
  getOrgName(),
@@ -5633,35 +6006,47 @@ function startSpanParentArgs(args) {
5633
6006
  let argParentObjectId = void 0;
5634
6007
  let argParentSpanIds = void 0;
5635
6008
  let argPropagatedEvent = void 0;
5636
- if (args.parent) {
6009
+ let argPropagatedState = void 0;
6010
+ const { parentSlug, propagatedState: parentPropagatedState } = normalizeParent(args.parent, args.state);
6011
+ if (parentSlug) {
5637
6012
  if (args.parentSpanIds) {
5638
6013
  throw new Error("Cannot specify both parent and parentSpanIds");
5639
6014
  }
5640
- const parentComponents = getSpanComponentsClass().fromStr(args.parent);
6015
+ const parentComponents = SpanComponentsV4.fromStr(parentSlug);
5641
6016
  if (args.parentObjectType !== parentComponents.data.object_type) {
5642
6017
  throw new Error(
5643
6018
  `Mismatch between expected span parent object type ${args.parentObjectType} and provided type ${parentComponents.data.object_type}`
5644
6019
  );
5645
6020
  }
5646
6021
  argParentObjectId = args.parentObjectId;
5647
- if (parentComponents.data.row_id) {
6022
+ if (parentComponents.data.row_id && parentSpanIdsUsable(
6023
+ parentComponents.data.span_id,
6024
+ parentComponents.data.root_span_id
6025
+ )) {
5648
6026
  argParentSpanIds = {
5649
6027
  spanId: parentComponents.data.span_id,
5650
6028
  rootSpanId: parentComponents.data.root_span_id
5651
6029
  };
5652
6030
  }
5653
6031
  argPropagatedEvent = args.propagatedEvent ?? (parentComponents.data.propagated_event ?? void 0);
6032
+ const propagatedState = args.propagatedState ?? parentPropagatedState;
6033
+ if (propagatedState) {
6034
+ const { braintrustParent: _ignoredBraintrustParent, ...w3cState } = propagatedState;
6035
+ argPropagatedState = w3cState;
6036
+ }
5654
6037
  } else {
5655
6038
  argParentObjectId = args.parentObjectId;
5656
6039
  argParentSpanIds = args.parentSpanIds;
5657
6040
  argPropagatedEvent = args.propagatedEvent;
6041
+ argPropagatedState = args.propagatedState;
5658
6042
  }
5659
6043
  return {
5660
6044
  parentObjectType: args.parentObjectType,
5661
6045
  parentObjectId: argParentObjectId,
5662
6046
  parentComputeObjectMetadataArgs: args.parentComputeObjectMetadataArgs,
5663
6047
  parentSpanIds: argParentSpanIds,
5664
- propagatedEvent: argPropagatedEvent
6048
+ propagatedEvent: argPropagatedEvent,
6049
+ propagatedState: argPropagatedState
5665
6050
  };
5666
6051
  }
5667
6052
  var Logger = class {
@@ -5862,6 +6247,22 @@ var Logger = class {
5862
6247
  _getLinkBaseUrl() {
5863
6248
  return _getLinkBaseUrl(this.state, this._linkArgs);
5864
6249
  }
6250
+ /**
6251
+ * Return this logger's Braintrust parent string (`project_id:<id>` or
6252
+ * `project_name:<name>`) for the `braintrust.parent` baggage entry, or
6253
+ * undefined when it cannot be determined synchronously.
6254
+ */
6255
+ _getOtelParent() {
6256
+ const id = this.computeMetadataArgs?.project_id || this.lazyId.getSync().value;
6257
+ if (id) {
6258
+ return `project_id:${id}`;
6259
+ }
6260
+ const name = this.computeMetadataArgs?.project_name;
6261
+ if (name) {
6262
+ return `project_name:${name}`;
6263
+ }
6264
+ return void 0;
6265
+ }
5865
6266
  };
5866
6267
  function castLogger(logger, asyncFlush) {
5867
6268
  if (logger === void 0) return void 0;
@@ -5956,12 +6357,12 @@ function stringifyWithOverflowMeta(item) {
5956
6357
  object_ids: pickLogs3OverflowObjectIds(record),
5957
6358
  is_delete: record[OBJECT_DELETE_FIELD] === true,
5958
6359
  input_row: {
5959
- byte_size: utf8ByteLength(str)
6360
+ byte_size: utf8ByteLength2(str)
5960
6361
  }
5961
6362
  }
5962
6363
  };
5963
6364
  }
5964
- function utf8ByteLength(value) {
6365
+ function utf8ByteLength2(value) {
5965
6366
  if (typeof TextEncoder !== "undefined") {
5966
6367
  return new TextEncoder().encode(value).length;
5967
6368
  }
@@ -6292,7 +6693,7 @@ var HTTPBackgroundLogger = class _HTTPBackgroundLogger {
6292
6693
  }) {
6293
6694
  const conn = await this.apiConn.get();
6294
6695
  const dataStr = constructLogs3Data(items);
6295
- const payloadBytes = utf8ByteLength(dataStr);
6696
+ const payloadBytes = utf8ByteLength2(dataStr);
6296
6697
  const useOverflow = canUseOverflow && payloadBytes > maxRequestSize;
6297
6698
  if (this.allPublishPayloadsDir) {
6298
6699
  await _HTTPBackgroundLogger.writePayloadToDir({
@@ -6675,100 +7076,335 @@ function currentSpan(options) {
6675
7076
  const state = options?.state ?? _globalState;
6676
7077
  return state.contextManager.getCurrentSpan() ?? NOOP_SPAN;
6677
7078
  }
6678
- function getSpanParentObject(options) {
7079
+ function getSpanParentObjectAndPropagatedState(options) {
6679
7080
  const state = options?.state ?? _globalState;
6680
7081
  const parentSpan = currentSpan({ state });
6681
7082
  if (!Object.is(parentSpan, NOOP_SPAN)) {
6682
- return parentSpan;
7083
+ return { parentObject: parentSpan, propagatedState: void 0 };
7084
+ }
7085
+ const parent = options?.parent ?? state.currentParent.getStore();
7086
+ const { parentSlug, propagatedState } = normalizeParent(parent, state);
7087
+ if (parentSlug) {
7088
+ return {
7089
+ parentObject: SpanComponentsV4.fromStr(parentSlug),
7090
+ propagatedState
7091
+ };
6683
7092
  }
6684
- const parentStr = options?.parent ?? state.currentParent.getStore();
6685
- if (parentStr) return getSpanComponentsClass().fromStr(parentStr);
6686
7093
  const experiment = currentExperiment();
6687
7094
  if (experiment) {
6688
- return experiment;
7095
+ return { parentObject: experiment, propagatedState: void 0 };
6689
7096
  }
6690
7097
  const logger = currentLogger(options);
6691
7098
  if (logger) {
6692
- return logger;
7099
+ return { parentObject: logger, propagatedState: void 0 };
6693
7100
  }
6694
- return NOOP_SPAN;
7101
+ return { parentObject: NOOP_SPAN, propagatedState: void 0 };
6695
7102
  }
6696
- function logError(span, error) {
6697
- let errorMessage = "<error>";
6698
- let stackTrace = "";
6699
- if (error instanceof Error) {
6700
- errorMessage = error.message;
6701
- stackTrace = error.stack || "";
6702
- } else {
6703
- errorMessage = String(error);
7103
+ function currentBraintrustParent(state) {
7104
+ const resolvedState = state ?? _globalState;
7105
+ const experiment = currentExperiment({ state: resolvedState });
7106
+ if (experiment) {
7107
+ try {
7108
+ return experiment._getOtelParent() ?? void 0;
7109
+ } catch {
7110
+ return void 0;
7111
+ }
6704
7112
  }
6705
- span.log({ error: `${errorMessage}
6706
-
6707
- ${stackTrace}` });
6708
- }
6709
- function startSpan(args) {
6710
- return startSpanAndIsLogger(args).span;
6711
- }
6712
- async function flush(options) {
6713
- const state = options?.state ?? _globalState;
6714
- return await state.bgLogger().flush();
7113
+ const logger = currentLogger({ state: resolvedState });
7114
+ if (logger) {
7115
+ try {
7116
+ return logger._getOtelParent() ?? void 0;
7117
+ } catch {
7118
+ return void 0;
7119
+ }
7120
+ }
7121
+ return void 0;
6715
7122
  }
6716
- function startSpanAndIsLogger(args) {
6717
- const state = args?.state ?? _globalState;
6718
- const parentObject = getSpanParentObject({
6719
- asyncFlush: args?.asyncFlush,
6720
- parent: args?.parent,
6721
- state
6722
- });
6723
- if (parentObject instanceof SpanComponentsV3 || parentObject instanceof SpanComponentsV4) {
6724
- const parentSpanIds = parentObject.data.row_id ? {
6725
- spanId: parentObject.data.span_id,
6726
- rootSpanId: parentObject.data.root_span_id
7123
+ function braintrustParentToComponents(braintrustParent) {
7124
+ if (!braintrustParent) {
7125
+ return void 0;
7126
+ }
7127
+ if (braintrustParent.startsWith("project_id:")) {
7128
+ const objectId = braintrustParent.slice("project_id:".length);
7129
+ return objectId ? {
7130
+ objectType: 2 /* PROJECT_LOGS */,
7131
+ objectId,
7132
+ computeArgs: void 0
7133
+ } : void 0;
7134
+ }
7135
+ if (braintrustParent.startsWith("project_name:")) {
7136
+ const name = braintrustParent.slice("project_name:".length);
7137
+ return name ? {
7138
+ objectType: 2 /* PROJECT_LOGS */,
7139
+ objectId: void 0,
7140
+ computeArgs: { project_name: name }
7141
+ } : void 0;
7142
+ }
7143
+ if (braintrustParent.startsWith("experiment_id:")) {
7144
+ const objectId = braintrustParent.slice("experiment_id:".length);
7145
+ return objectId ? {
7146
+ objectType: 1 /* EXPERIMENT */,
7147
+ objectId,
7148
+ computeArgs: void 0
6727
7149
  } : void 0;
6728
- const span = new SpanImpl({
6729
- state,
6730
- ...args,
6731
- parentObjectType: parentObject.data.object_type,
6732
- parentObjectId: new LazyValue(
6733
- spanComponentsToObjectIdLambda(state, parentObject)
6734
- ),
6735
- parentComputeObjectMetadataArgs: parentObject.data.compute_object_metadata_args ?? void 0,
6736
- parentSpanIds,
6737
- propagatedEvent: args?.propagatedEvent ?? // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
6738
- (parentObject.data.propagated_event ?? void 0)
6739
- });
6740
- return {
6741
- span,
6742
- isSyncFlushLogger: parentObject.data.object_type === 2 /* PROJECT_LOGS */ && // Since there's no parent logger here, we're free to choose the async flush
6743
- // behavior, and therefore propagate along whatever we get from the arguments
6744
- args?.asyncFlush === false
6745
- };
6746
- } else {
6747
- const span = parentObject.startSpan(args);
6748
- return {
6749
- span,
6750
- isSyncFlushLogger: parentObject.kind === "logger" && parentObject.asyncFlush === false
6751
- };
6752
7150
  }
7151
+ return void 0;
6753
7152
  }
6754
- function withCurrent(span, callback, state = void 0) {
6755
- const currentState = state ?? _globalState;
6756
- return currentState.contextManager.runInContext(span, () => callback(span));
7153
+ function isMutableHeaderTupleArray(carrier) {
7154
+ return Array.isArray(carrier) && carrier.every((item) => Array.isArray(item) && typeof item[0] === "string");
6757
7155
  }
6758
- function _saveOrgInfo(state, org_info, org_name) {
6759
- if (org_info.length === 0) {
6760
- throw new LoginInvalidOrgError(
6761
- "This user is not part of any organizations."
6762
- );
7156
+ function setHeader(carrier, name, value) {
7157
+ if (isMutableHeaderTupleArray(carrier)) {
7158
+ const lowered2 = name.toLowerCase();
7159
+ for (let i = carrier.length - 1; i >= 0; i--) {
7160
+ if (carrier[i][0].toLowerCase() === lowered2) {
7161
+ carrier.splice(i, 1);
7162
+ }
7163
+ }
7164
+ carrier.push([name, value]);
7165
+ return;
6763
7166
  }
6764
- for (const org of org_info) {
6765
- if (org_name === void 0 || org.name === org_name) {
6766
- state.orgId = org.id;
6767
- state.orgName = org.name;
6768
- state.apiUrl = isomorph_default.getEnv("BRAINTRUST_API_URL") ?? org.api_url;
6769
- state.proxyUrl = isomorph_default.getEnv("BRAINTRUST_PROXY_URL") ?? org.proxy_url;
6770
- state.gitMetadataSettings = org.git_metadata || void 0;
6771
- break;
7167
+ const setter = carrier.set;
7168
+ if (typeof setter === "function") {
7169
+ const deleter = carrier.delete;
7170
+ if (typeof deleter === "function") {
7171
+ try {
7172
+ deleter.call(carrier, name);
7173
+ } catch {
7174
+ }
7175
+ }
7176
+ setter.call(carrier, name, value);
7177
+ return;
7178
+ }
7179
+ const nodeSetter = carrier.setHeader;
7180
+ if (typeof nodeSetter === "function") {
7181
+ const remover = carrier.removeHeader;
7182
+ if (typeof remover === "function") {
7183
+ try {
7184
+ remover.call(carrier, name);
7185
+ } catch {
7186
+ }
7187
+ }
7188
+ nodeSetter.call(carrier, name, value);
7189
+ return;
7190
+ }
7191
+ const headerSetter = carrier.header;
7192
+ if (typeof headerSetter === "function") {
7193
+ const deleter = carrier.delete;
7194
+ if (typeof deleter === "function") {
7195
+ try {
7196
+ deleter.call(carrier, name);
7197
+ } catch {
7198
+ }
7199
+ }
7200
+ const remover = carrier.removeHeader;
7201
+ if (typeof remover === "function") {
7202
+ try {
7203
+ remover.call(carrier, name);
7204
+ } catch {
7205
+ }
7206
+ }
7207
+ headerSetter.call(carrier, name, value);
7208
+ return;
7209
+ }
7210
+ const headerBag = carrier;
7211
+ const lowered = name.toLowerCase();
7212
+ for (const key of Object.keys(headerBag)) {
7213
+ if (key !== name && key.toLowerCase() === lowered) {
7214
+ delete headerBag[key];
7215
+ }
7216
+ }
7217
+ headerBag[name] = value;
7218
+ }
7219
+ function deleteHeader(carrier, name) {
7220
+ const lowered = name.toLowerCase();
7221
+ if (isMutableHeaderTupleArray(carrier)) {
7222
+ for (let i = carrier.length - 1; i >= 0; i--) {
7223
+ if (carrier[i][0].toLowerCase() === lowered) {
7224
+ carrier.splice(i, 1);
7225
+ }
7226
+ }
7227
+ return;
7228
+ }
7229
+ const deleter = carrier.delete;
7230
+ if (typeof deleter === "function") {
7231
+ try {
7232
+ deleter.call(carrier, name);
7233
+ return;
7234
+ } catch {
7235
+ }
7236
+ }
7237
+ const remover = carrier.removeHeader;
7238
+ if (typeof remover === "function") {
7239
+ try {
7240
+ remover.call(carrier, name);
7241
+ return;
7242
+ } catch {
7243
+ }
7244
+ }
7245
+ const headerBag = carrier;
7246
+ for (const key of Object.keys(headerBag)) {
7247
+ if (key.toLowerCase() === lowered) {
7248
+ delete headerBag[key];
7249
+ }
7250
+ }
7251
+ }
7252
+ function _injectIntoCarrier(carrier, args) {
7253
+ const traceFlags = args.propagatedState?.traceFlags;
7254
+ const traceparent = traceFlags ? formatTraceparent(args.traceId, args.spanId, traceFlags) : formatTraceparent(args.traceId, args.spanId);
7255
+ if (traceparent === void 0) {
7256
+ return;
7257
+ }
7258
+ setHeader(carrier, TRACEPARENT_HEADER, traceparent);
7259
+ const tracestate = args.propagatedState?.tracestate;
7260
+ if (tracestate) {
7261
+ setHeader(carrier, TRACESTATE_HEADER, tracestate);
7262
+ }
7263
+ const existing = getHeader(carrier, BAGGAGE_HEADER);
7264
+ const baggageValue = mergeBaggage(existing, args.braintrustParent);
7265
+ if (baggageValue !== void 0) {
7266
+ setHeader(carrier, BAGGAGE_HEADER, baggageValue);
7267
+ } else if (existing !== void 0) {
7268
+ deleteHeader(carrier, BAGGAGE_HEADER);
7269
+ }
7270
+ }
7271
+ function resolveW3cParent(context, state) {
7272
+ const traceparent = getHeader(context, TRACEPARENT_HEADER);
7273
+ const parsed = traceparent ? parseTraceparent(traceparent) : void 0;
7274
+ if (parsed === void 0) {
7275
+ return { parentSlug: void 0, propagatedState: void 0 };
7276
+ }
7277
+ const { traceId, spanId, traceFlags } = parsed;
7278
+ let braintrustParent = void 0;
7279
+ const baggageValue = getHeader(context, BAGGAGE_HEADER);
7280
+ if (baggageValue) {
7281
+ braintrustParent = parseBaggage(baggageValue)[BRAINTRUST_PARENT_KEY];
7282
+ }
7283
+ if (!braintrustParent) {
7284
+ braintrustParent = currentBraintrustParent(state);
7285
+ }
7286
+ if (!braintrustParent) {
7287
+ debugLogger.warn(
7288
+ "Received traceparent without a braintrust.parent and no active logger/experiment; cannot route the trace. Starting a fresh local span instead."
7289
+ );
7290
+ return { parentSlug: void 0, propagatedState: void 0 };
7291
+ }
7292
+ const parsedParent = braintrustParentToComponents(braintrustParent);
7293
+ if (parsedParent === void 0) {
7294
+ debugLogger.warn(
7295
+ `Invalid braintrust.parent: ${JSON.stringify(braintrustParent)}`
7296
+ );
7297
+ return { parentSlug: void 0, propagatedState: void 0 };
7298
+ }
7299
+ const { objectType, objectId, computeArgs } = parsedParent;
7300
+ const tracestate = getHeader(context, TRACESTATE_HEADER);
7301
+ const slug = new SpanComponentsV4({
7302
+ object_type: objectType,
7303
+ ...computeArgs ? { compute_object_metadata_args: computeArgs } : { object_id: objectId },
7304
+ row_id: "bt-propagation",
7305
+ // non-empty to enable span_id/root_span_id
7306
+ span_id: spanId,
7307
+ root_span_id: traceId
7308
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
7309
+ }).toStr();
7310
+ return {
7311
+ parentSlug: slug,
7312
+ propagatedState: { tracestate, traceFlags, braintrustParent }
7313
+ };
7314
+ }
7315
+ function normalizeParent(parent, state) {
7316
+ if (parent && typeof parent === "object") {
7317
+ return resolveW3cParent(parent, state);
7318
+ }
7319
+ return {
7320
+ parentSlug: parent ?? void 0,
7321
+ propagatedState: void 0
7322
+ };
7323
+ }
7324
+ function parentSpanIdsUsable(spanId, rootSpanId) {
7325
+ return Boolean(spanId) && Boolean(rootSpanId);
7326
+ }
7327
+ function logError(span, error) {
7328
+ let errorMessage = "<error>";
7329
+ let stackTrace = "";
7330
+ if (error instanceof Error) {
7331
+ errorMessage = error.message;
7332
+ stackTrace = error.stack || "";
7333
+ } else {
7334
+ errorMessage = String(error);
7335
+ }
7336
+ span.log({ error: `${errorMessage}
7337
+
7338
+ ${stackTrace}` });
7339
+ }
7340
+ function startSpan(args) {
7341
+ return startSpanAndIsLogger(args).span;
7342
+ }
7343
+ async function flush(options) {
7344
+ const state = options?.state ?? _globalState;
7345
+ return await state.bgLogger().flush();
7346
+ }
7347
+ function startSpanAndIsLogger(args) {
7348
+ const state = args?.state ?? _globalState;
7349
+ const { parentObject, propagatedState } = getSpanParentObjectAndPropagatedState({
7350
+ asyncFlush: args?.asyncFlush,
7351
+ parent: args?.parent,
7352
+ state
7353
+ });
7354
+ if (parentObject instanceof SpanComponentsV3 || parentObject instanceof SpanComponentsV4) {
7355
+ const parentSpanIds = parentObject.data.row_id && parentSpanIdsUsable(
7356
+ parentObject.data.span_id,
7357
+ parentObject.data.root_span_id
7358
+ ) ? {
7359
+ spanId: parentObject.data.span_id,
7360
+ rootSpanId: parentObject.data.root_span_id
7361
+ } : void 0;
7362
+ const { parent: _ignoredParent, ...spanArgs } = args ?? {};
7363
+ const span = new SpanImpl({
7364
+ state,
7365
+ ...spanArgs,
7366
+ parentObjectType: parentObject.data.object_type,
7367
+ parentObjectId: new LazyValue(
7368
+ spanComponentsToObjectIdLambda(state, parentObject)
7369
+ ),
7370
+ parentComputeObjectMetadataArgs: parentObject.data.compute_object_metadata_args ?? void 0,
7371
+ parentSpanIds,
7372
+ propagatedEvent: args?.propagatedEvent ?? // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
7373
+ (parentObject.data.propagated_event ?? void 0),
7374
+ propagatedState
7375
+ });
7376
+ return {
7377
+ span,
7378
+ isSyncFlushLogger: parentObject.data.object_type === 2 /* PROJECT_LOGS */ && // Since there's no parent logger here, we're free to choose the async flush
7379
+ // behavior, and therefore propagate along whatever we get from the arguments
7380
+ args?.asyncFlush === false
7381
+ };
7382
+ } else {
7383
+ const span = parentObject.startSpan(args);
7384
+ return {
7385
+ span,
7386
+ isSyncFlushLogger: parentObject.kind === "logger" && parentObject.asyncFlush === false
7387
+ };
7388
+ }
7389
+ }
7390
+ function withCurrent(span, callback, state = void 0) {
7391
+ const currentState = state ?? _globalState;
7392
+ return currentState.contextManager.runInContext(span, () => callback(span));
7393
+ }
7394
+ function _saveOrgInfo(state, org_info, org_name) {
7395
+ if (org_info.length === 0) {
7396
+ throw new LoginInvalidOrgError(
7397
+ "This user is not part of any organizations."
7398
+ );
7399
+ }
7400
+ for (const org of org_info) {
7401
+ if (org_name === void 0 || org.name === org_name) {
7402
+ state.orgId = org.id;
7403
+ state.orgName = org.name;
7404
+ state.apiUrl = isomorph_default.getEnv("BRAINTRUST_API_URL") ?? org.api_url;
7405
+ state.proxyUrl = isomorph_default.getEnv("BRAINTRUST_PROXY_URL") ?? org.proxy_url;
7406
+ state.gitMetadataSettings = org.git_metadata || void 0;
7407
+ break;
6772
7408
  }
6773
7409
  }
6774
7410
  if (state.orgId === void 0) {
@@ -6962,11 +7598,12 @@ function validateAndSanitizeExperimentLogFullArgs(event, hasDataset) {
6962
7598
  var DEFAULT_FETCH_BATCH_SIZE = 1e3;
6963
7599
  var MAX_BTQL_ITERATIONS = 1e4;
6964
7600
  var ObjectFetcher = class {
6965
- constructor(objectType, pinnedVersion, mutateRecord, _internal_btql) {
7601
+ constructor(objectType, pinnedVersion, mutateRecord, _internal_btql, _internalBrainstoreRealtime = true) {
6966
7602
  this.objectType = objectType;
6967
7603
  this.pinnedVersion = pinnedVersion;
6968
7604
  this.mutateRecord = mutateRecord;
6969
7605
  this._internal_btql = _internal_btql;
7606
+ this._internalBrainstoreRealtime = _internalBrainstoreRealtime;
6970
7607
  }
6971
7608
  _fetchedData = void 0;
6972
7609
  get id() {
@@ -7025,7 +7662,7 @@ var ObjectFetcher = class {
7025
7662
  ...internalBtqlWithoutReservedQueryKeys
7026
7663
  },
7027
7664
  use_columnstore: false,
7028
- brainstore_realtime: true,
7665
+ brainstore_realtime: this._internalBrainstoreRealtime,
7029
7666
  query_source: `js_sdk_object_fetcher_${this.objectType}`,
7030
7667
  ...this.pinnedVersion !== void 0 ? {
7031
7668
  version: this.pinnedVersion
@@ -7374,6 +8011,15 @@ View complete results in Braintrust or run experiment.summarize() again.`
7374
8011
  object_id: await this.id
7375
8012
  }).toStr();
7376
8013
  }
8014
+ /**
8015
+ * Return this experiment's Braintrust parent string (`experiment_id:<id>`) for
8016
+ * the `braintrust.parent` baggage entry, or undefined when it cannot be
8017
+ * determined synchronously.
8018
+ */
8019
+ _getOtelParent() {
8020
+ const id = this.lazyId.getSync().value;
8021
+ return id ? `experiment_id:${id}` : void 0;
8022
+ }
7377
8023
  /**
7378
8024
  * Flush any pending rows to the server.
7379
8025
  */
@@ -7438,9 +8084,16 @@ var SpanImpl = class _SpanImpl {
7438
8084
  _spanId;
7439
8085
  _rootSpanId;
7440
8086
  _spanParents;
8087
+ // Inbound W3C trace-context state (tracestate + raw traceparent flags) to
8088
+ // forward on outbound propagation. Captured at the span that received it (via
8089
+ // extractTraceContextFromHeaders) and inherited by all subspans, so that any
8090
+ // inject() within the trace re-emits the upstream state unchanged, per the W3C
8091
+ // Trace Context spec. Not interpreted.
8092
+ _propagatedState;
7441
8093
  kind = "span";
7442
8094
  constructor(args) {
7443
8095
  this._state = args.state;
8096
+ this._propagatedState = args.propagatedState;
7444
8097
  const spanAttributes = args.spanAttributes ?? {};
7445
8098
  const rawEvent = args.event ?? {};
7446
8099
  const type = args.type ?? (args.parentSpanIds ? void 0 : args.defaultRootType);
@@ -7556,7 +8209,7 @@ var SpanImpl = class _SpanImpl {
7556
8209
  tags: partialRecord.tags,
7557
8210
  span_id: this._spanId,
7558
8211
  span_parents: this._spanParents,
7559
- is_root: this._spanId === this._rootSpanId,
8212
+ is_root: !this._spanParents || this._spanParents.length === 0,
7560
8213
  span_attributes: partialRecord.span_attributes
7561
8214
  };
7562
8215
  this._state.spanCache.queueWrite(
@@ -7618,7 +8271,8 @@ var SpanImpl = class _SpanImpl {
7618
8271
  parentObjectId: this.parentObjectId,
7619
8272
  parentComputeObjectMetadataArgs: this.parentComputeObjectMetadataArgs,
7620
8273
  parentSpanIds,
7621
- propagatedEvent: args?.propagatedEvent ?? this.propagatedEvent
8274
+ propagatedEvent: args?.propagatedEvent ?? this.propagatedEvent,
8275
+ propagatedState: this._propagatedState
7622
8276
  })
7623
8277
  });
7624
8278
  }
@@ -7637,7 +8291,8 @@ var SpanImpl = class _SpanImpl {
7637
8291
  parentObjectId: this.parentObjectId,
7638
8292
  parentComputeObjectMetadataArgs: this.parentComputeObjectMetadataArgs,
7639
8293
  parentSpanIds,
7640
- propagatedEvent: args?.propagatedEvent ?? this.propagatedEvent
8294
+ propagatedEvent: args?.propagatedEvent ?? this.propagatedEvent,
8295
+ propagatedState: this._propagatedState
7641
8296
  }),
7642
8297
  spanId
7643
8298
  });
@@ -7665,6 +8320,42 @@ var SpanImpl = class _SpanImpl {
7665
8320
  propagated_event: this.propagatedEvent
7666
8321
  }).toStr();
7667
8322
  }
8323
+ /**
8324
+ * Return this span's Braintrust parent string (`project_id:<id>`,
8325
+ * `project_name:<name>`, or `experiment_id:<id>`) for the `braintrust.parent`
8326
+ * baggage entry, or undefined when it cannot be determined synchronously.
8327
+ */
8328
+ _getOtelParent() {
8329
+ if (this.parentObjectType === 2 /* PROJECT_LOGS */) {
8330
+ const id = this.parentComputeObjectMetadataArgs?.project_id || this.parentObjectId.getSync().value;
8331
+ const name = this.parentComputeObjectMetadataArgs?.project_name;
8332
+ if (id) {
8333
+ return `project_id:${id}`;
8334
+ } else if (name) {
8335
+ return `project_name:${name}`;
8336
+ }
8337
+ } else if (this.parentObjectType === 1 /* EXPERIMENT */) {
8338
+ const id = this.parentComputeObjectMetadataArgs?.experiment_id || this.parentObjectId.getSync().value;
8339
+ if (id) {
8340
+ return `experiment_id:${id}`;
8341
+ }
8342
+ }
8343
+ return void 0;
8344
+ }
8345
+ inject(carrier) {
8346
+ const resolvedCarrier = carrier ?? {};
8347
+ try {
8348
+ _injectIntoCarrier(resolvedCarrier, {
8349
+ traceId: this._rootSpanId,
8350
+ spanId: this._spanId,
8351
+ braintrustParent: this._getOtelParent() ?? this._propagatedState?.braintrustParent,
8352
+ propagatedState: this._propagatedState
8353
+ });
8354
+ } catch (e) {
8355
+ debugLogger.warn(`Error injecting trace context: ${e}`);
8356
+ }
8357
+ return resolvedCarrier;
8358
+ }
7668
8359
  async permalink() {
7669
8360
  return await permalink(await this.export(), {
7670
8361
  state: this._state
@@ -7800,6 +8491,7 @@ var Dataset2 = class extends ObjectFetcher {
7800
8491
  _internal_btql
7801
8492
  );
7802
8493
  this.state = state;
8494
+ void this.__braintrust_dataset_marker;
7803
8495
  this.lazyMetadata = lazyMetadata;
7804
8496
  this.lazyPinnedVersion = pinState?.lazyPinnedVersion;
7805
8497
  this.pinnedEnvironment = pinState?.pinnedEnvironment;
@@ -8766,6 +9458,22 @@ function runStreamingCompletionHook(args) {
8766
9458
  );
8767
9459
  }
8768
9460
  }
9461
+ function runStreamingErrorHook(args) {
9462
+ if (!args.config.onError) {
9463
+ return;
9464
+ }
9465
+ try {
9466
+ args.config.onError({
9467
+ channelName: args.channelName,
9468
+ error: args.error,
9469
+ event: args.event,
9470
+ span: args.span,
9471
+ startTime: args.startTime
9472
+ });
9473
+ } catch (error) {
9474
+ debugLogger.error(`Error in onError hook for ${args.channelName}:`, error);
9475
+ }
9476
+ }
8769
9477
  function traceAsyncChannel(channel2, config) {
8770
9478
  const tracingChannel = channel2.tracingChannel();
8771
9479
  const states = /* @__PURE__ */ new WeakMap();
@@ -8927,6 +9635,14 @@ function traceStreamingChannel(channel2, config) {
8927
9635
  }
8928
9636
  },
8929
9637
  onError: (error) => {
9638
+ runStreamingErrorHook({
9639
+ channelName,
9640
+ config,
9641
+ error,
9642
+ event: asyncEndEvent,
9643
+ span,
9644
+ startTime
9645
+ });
8930
9646
  span.log({
8931
9647
  error: error.message
8932
9648
  });
@@ -8984,6 +9700,17 @@ function traceStreamingChannel(channel2, config) {
8984
9700
  }
8985
9701
  },
8986
9702
  error: (event) => {
9703
+ const spanData = states.get(event);
9704
+ if (spanData) {
9705
+ runStreamingErrorHook({
9706
+ channelName,
9707
+ config,
9708
+ error: event.error,
9709
+ event,
9710
+ span: spanData.span,
9711
+ startTime: spanData.startTime
9712
+ });
9713
+ }
8987
9714
  logErrorAndEnd(states, event);
8988
9715
  }
8989
9716
  };
@@ -11346,14 +12073,45 @@ function serializeAISDKToolsForLogging(tools) {
11346
12073
  return serialized;
11347
12074
  }
11348
12075
 
12076
+ // src/vendor-sdk-types/ai-sdk-v7-telemetry.ts
12077
+ var BRAINTRUST_AI_SDK_V7_OPERATION_KEY = /* @__PURE__ */ Symbol.for(
12078
+ "braintrust.ai-sdk.v7.telemetry-operation-key"
12079
+ );
12080
+
12081
+ // src/wrappers/ai-sdk/workflow-agent-context.ts
12082
+ var workflowAgentWrapperSpans = /* @__PURE__ */ new Map();
12083
+ function registerWorkflowAgentWrapperSpan(span) {
12084
+ if (span.spanId) {
12085
+ workflowAgentWrapperSpans.set(span.spanId, span);
12086
+ }
12087
+ }
12088
+ function unregisterWorkflowAgentWrapperSpan(span) {
12089
+ if (span.spanId) {
12090
+ workflowAgentWrapperSpans.delete(span.spanId);
12091
+ }
12092
+ }
12093
+ function currentWorkflowAgentWrapperSpan() {
12094
+ const parentSpanIds = _internalGetGlobalState().contextManager.getParentSpanIds()?.spanParents ?? [];
12095
+ for (const parentSpanId of parentSpanIds) {
12096
+ const span = workflowAgentWrapperSpans.get(parentSpanId);
12097
+ if (span) {
12098
+ return span;
12099
+ }
12100
+ }
12101
+ return void 0;
12102
+ }
12103
+
11349
12104
  // src/wrappers/ai-sdk/telemetry.ts
11350
12105
  function braintrustAISDKTelemetry() {
11351
12106
  const operations = /* @__PURE__ */ new Map();
12107
+ const operationKeysByCallId = /* @__PURE__ */ new Map();
12108
+ const workflowOperationKeyStore = isomorph_default.newAsyncLocalStorage();
11352
12109
  const modelSpans = /* @__PURE__ */ new Map();
11353
12110
  const objectSpans = /* @__PURE__ */ new Map();
11354
12111
  const embedSpans = /* @__PURE__ */ new Map();
11355
12112
  const rerankSpans = /* @__PURE__ */ new Map();
11356
12113
  const toolSpans = /* @__PURE__ */ new Map();
12114
+ let workflowAgentOperationCounter = 0;
11357
12115
  const runSafely = (name, callback) => {
11358
12116
  try {
11359
12117
  callback();
@@ -11361,139 +12119,413 @@ function braintrustAISDKTelemetry() {
11361
12119
  console.error(`Error in Braintrust AI SDK telemetry ${name}:`, error);
11362
12120
  }
11363
12121
  };
11364
- const startChildSpan = (callId, name, type, event) => {
11365
- const parent = operations.get(callId)?.span;
12122
+ const startChildSpan = (operationKey, name, type, event) => {
12123
+ const parent = operations.get(operationKey)?.span;
11366
12124
  const spanArgs = {
11367
12125
  name,
11368
12126
  spanAttributes: { type },
11369
12127
  ...event ? { event } : {}
11370
12128
  };
11371
12129
  const span = parent ? parent.startSpan(spanArgs) : startSpan(spanArgs);
11372
- const state = operations.get(callId);
12130
+ const state = operations.get(operationKey);
11373
12131
  if (state && type === "llm" /* LLM */) {
11374
12132
  state.hadModelChild = true;
11375
12133
  }
11376
12134
  return span;
11377
12135
  };
11378
- return {
11379
- onStart(event) {
11380
- runSafely("onStart", () => {
11381
- const operationName = operationNameFromId(event.operationId);
11382
- const span = startSpan({
11383
- name: operationName,
11384
- spanAttributes: { type: "function" /* FUNCTION */ }
11385
- });
11386
- operations.set(event.callId, {
11387
- hadModelChild: false,
11388
- operationName,
11389
- span,
11390
- startTime: getCurrentUnixTimestamp()
11391
- });
11392
- const metadata = metadataFromEvent(event);
11393
- const logPayload = { metadata };
11394
- if (shouldRecordInputs(event)) {
11395
- const { input, outputPromise } = processAISDKCallInput(
11396
- operationInput(event, operationName)
11397
- );
11398
- logPayload.input = input;
11399
- if (outputPromise && input && typeof input === "object") {
11400
- outputPromise.then((resolvedData) => {
11401
- span.log({
11402
- input: {
11403
- ...input,
11404
- ...resolvedData
11405
- }
11406
- });
11407
- }).catch(() => {
11408
- });
11409
- }
12136
+ const registerOperation = (state) => {
12137
+ operations.set(state.operationKey, state);
12138
+ const keys = operationKeysByCallId.get(state.callId) ?? [];
12139
+ keys.push(state.operationKey);
12140
+ operationKeysByCallId.set(state.callId, keys);
12141
+ };
12142
+ const deleteOperation = (operationKey) => {
12143
+ const state = operations.get(operationKey);
12144
+ if (!state) {
12145
+ return;
12146
+ }
12147
+ operations.delete(operationKey);
12148
+ if (workflowOperationKeyStore.getStore() === operationKey) {
12149
+ workflowOperationKeyStore.enterWith(void 0);
12150
+ }
12151
+ const keys = operationKeysByCallId.get(state.callId);
12152
+ if (!keys) {
12153
+ return;
12154
+ }
12155
+ const index = keys.indexOf(operationKey);
12156
+ if (index >= 0) {
12157
+ keys.splice(index, 1);
12158
+ }
12159
+ if (keys.length === 0) {
12160
+ operationKeysByCallId.delete(state.callId);
12161
+ }
12162
+ };
12163
+ const explicitOperationKey = (event) => {
12164
+ if (!isObject(event)) {
12165
+ return void 0;
12166
+ }
12167
+ const key = event[BRAINTRUST_AI_SDK_V7_OPERATION_KEY];
12168
+ return typeof key === "string" ? key : void 0;
12169
+ };
12170
+ const createOperationKey = (event, operationName) => {
12171
+ const explicit = explicitOperationKey(event);
12172
+ if (explicit) {
12173
+ return explicit;
12174
+ }
12175
+ if (operationName === "WorkflowAgent.stream") {
12176
+ workflowAgentOperationCounter += 1;
12177
+ return `${event.callId}:${workflowAgentOperationCounter}`;
12178
+ }
12179
+ return event.callId;
12180
+ };
12181
+ const operationKeyForCallId = (callId, mode = "active") => {
12182
+ const keys = operationKeysByCallId.get(callId);
12183
+ if (!keys || keys.length === 0) {
12184
+ return operations.has(callId) ? callId : void 0;
12185
+ }
12186
+ if (keys.length === 1) {
12187
+ return keys[0];
12188
+ }
12189
+ const wrapperSpan = currentWorkflowAgentWrapperSpan();
12190
+ if (wrapperSpan?.spanId) {
12191
+ const key = keys.find(
12192
+ (candidate) => operations.get(candidate)?.span.spanId === wrapperSpan.spanId
12193
+ );
12194
+ if (key) {
12195
+ return key;
12196
+ }
12197
+ }
12198
+ const workflowOperationKey = workflowOperationKeyStore.getStore();
12199
+ if (workflowOperationKey && keys.includes(workflowOperationKey)) {
12200
+ return workflowOperationKey;
12201
+ }
12202
+ if (callId === "workflow-agent") {
12203
+ return void 0;
12204
+ }
12205
+ return mode === "finish" ? keys[0] : keys[keys.length - 1];
12206
+ };
12207
+ const operationKeyFromEvent = (event, mode = "active") => {
12208
+ const explicit = explicitOperationKey(event);
12209
+ if (explicit && operations.has(explicit)) {
12210
+ return explicit;
12211
+ }
12212
+ if (isObject(event)) {
12213
+ const callId = event.callId;
12214
+ if (typeof callId === "string") {
12215
+ const operationKey = operationKeyForCallId(callId, mode);
12216
+ if (operationKey) {
12217
+ return operationKey;
11410
12218
  }
11411
- span.log(logPayload);
11412
- });
11413
- },
11414
- onLanguageModelCallStart(event) {
11415
- runSafely("onLanguageModelCallStart", () => {
11416
- const state = operations.get(event.callId);
11417
- const openSpans = modelSpans.get(event.callId);
11418
- if (openSpans) {
11419
- for (const span2 of openSpans) {
11420
- span2.end();
11421
- }
11422
- modelSpans.delete(event.callId);
12219
+ const workflowOperationKey2 = workflowOperationKeyStore.getStore();
12220
+ if (workflowOperationKey2 && operations.has(workflowOperationKey2)) {
12221
+ return workflowOperationKey2;
11423
12222
  }
11424
- const span = startChildSpan(
11425
- event.callId,
11426
- state?.operationName === "streamText" ? "doStream" : "doGenerate",
11427
- "llm" /* LLM */,
11428
- {
11429
- ...shouldRecordInputs(event) ? {
11430
- input: processAISDKCallInput(
11431
- operationInput(
11432
- event,
11433
- state?.operationName ?? "generateText"
11434
- )
11435
- ).input
11436
- } : {},
11437
- metadata: metadataFromEvent(event)
11438
- }
11439
- );
11440
- const spans = modelSpans.get(event.callId) ?? [];
11441
- spans.push(span);
11442
- modelSpans.set(event.callId, spans);
11443
- });
11444
- },
11445
- onLanguageModelCallEnd(event) {
11446
- runSafely("onLanguageModelCallEnd", () => {
11447
- const span = shiftModelSpan(modelSpans, event.callId);
11448
- if (!span) {
11449
- return;
12223
+ return callId === "workflow-agent" ? void 0 : callId;
12224
+ }
12225
+ }
12226
+ const workflowOperationKey = workflowOperationKeyStore.getStore();
12227
+ if (workflowOperationKey && operations.has(workflowOperationKey)) {
12228
+ return workflowOperationKey;
12229
+ }
12230
+ const wrapperSpan = currentWorkflowAgentWrapperSpan();
12231
+ if (wrapperSpan?.spanId) {
12232
+ for (const [operationKey, state] of operations) {
12233
+ if (state.operationName === "WorkflowAgent.stream" && state.span.spanId === wrapperSpan.spanId) {
12234
+ return operationKey;
12235
+ }
12236
+ }
12237
+ }
12238
+ const workflowAgentKeys = operationKeysByCallId.get("workflow-agent");
12239
+ if (workflowAgentKeys?.length === 1) {
12240
+ return workflowAgentKeys[0];
12241
+ }
12242
+ if (operations.size === 1) {
12243
+ return operations.keys().next().value;
12244
+ }
12245
+ return void 0;
12246
+ };
12247
+ const closeOpenChildSpans = (operationKey, error) => {
12248
+ const openModelSpans = modelSpans.get(operationKey);
12249
+ if (openModelSpans) {
12250
+ for (const span of openModelSpans) {
12251
+ if (error !== void 0) {
12252
+ logError(span, error);
11450
12253
  }
11451
- const result = {
11452
- ...event,
11453
- response: event.responseId ? { id: event.responseId } : void 0
11454
- };
11455
- span.log({
11456
- ...shouldRecordOutputs(event) ? {
11457
- output: processAISDKOutput(result, DEFAULT_DENY_OUTPUT_PATHS)
11458
- } : {},
11459
- metrics: extractTokenMetrics(result)
11460
- });
11461
12254
  span.end();
12255
+ }
12256
+ modelSpans.delete(operationKey);
12257
+ }
12258
+ const openObjectSpan = objectSpans.get(operationKey);
12259
+ if (openObjectSpan) {
12260
+ if (error !== void 0) {
12261
+ logError(openObjectSpan, error);
12262
+ }
12263
+ openObjectSpan.end();
12264
+ objectSpans.delete(operationKey);
12265
+ }
12266
+ for (const [embedCallId, embedState] of embedSpans) {
12267
+ if (embedState.operationKey === operationKey) {
12268
+ if (error !== void 0) {
12269
+ logError(embedState.span, error);
12270
+ }
12271
+ embedState.span.end();
12272
+ embedSpans.delete(embedCallId);
12273
+ }
12274
+ }
12275
+ const openRerankSpan = rerankSpans.get(operationKey);
12276
+ if (openRerankSpan) {
12277
+ if (error !== void 0) {
12278
+ logError(openRerankSpan, error);
12279
+ }
12280
+ openRerankSpan.end();
12281
+ rerankSpans.delete(operationKey);
12282
+ }
12283
+ for (const [toolCallId, toolState] of toolSpans) {
12284
+ if (toolState.operationKey === operationKey) {
12285
+ if (error !== void 0) {
12286
+ logError(toolState.span, error);
12287
+ }
12288
+ toolState.span.end();
12289
+ toolSpans.delete(toolCallId);
12290
+ }
12291
+ }
12292
+ };
12293
+ const abortReasonFromEvent = (event) => {
12294
+ if (isObject(event)) {
12295
+ const abortEvent = event;
12296
+ if (abortEvent.error !== void 0) {
12297
+ return abortEvent.error;
12298
+ }
12299
+ if (abortEvent.reason !== void 0) {
12300
+ return abortEvent.reason;
12301
+ }
12302
+ }
12303
+ return new Error("AI SDK operation aborted");
12304
+ };
12305
+ const shouldSkipTelemetryChildren = (state) => state?.operationName === "WorkflowAgent.stream" && !state.ownsSpan;
12306
+ const onObjectStepEnd = (event) => {
12307
+ runSafely("onObjectStepEnd", () => {
12308
+ const operationKey = operationKeyFromEvent(event);
12309
+ const span = operationKey ? objectSpans.get(operationKey) : void 0;
12310
+ if (!operationKey || !span) {
12311
+ return;
12312
+ }
12313
+ const result = {
12314
+ ...event,
12315
+ text: event.objectText
12316
+ };
12317
+ span.log({
12318
+ ...shouldRecordOutputs(event) ? {
12319
+ output: processAISDKOutput(result, DEFAULT_DENY_OUTPUT_PATHS)
12320
+ } : {},
12321
+ metrics: extractTokenMetrics(result)
12322
+ });
12323
+ span.end();
12324
+ objectSpans.delete(operationKey);
12325
+ });
12326
+ };
12327
+ const onEmbedEnd = (event) => {
12328
+ runSafely("onEmbedEnd", () => {
12329
+ const state = embedSpans.get(event.embedCallId);
12330
+ if (!state) {
12331
+ return;
12332
+ }
12333
+ const result = {
12334
+ ...event,
12335
+ embeddings: event.embeddings
12336
+ };
12337
+ state.span.log({
12338
+ ...shouldRecordOutputs(event) ? {
12339
+ output: processAISDKEmbeddingOutput(
12340
+ result,
12341
+ DEFAULT_DENY_OUTPUT_PATHS
12342
+ )
12343
+ } : {},
12344
+ metrics: extractTokenMetrics(result)
12345
+ });
12346
+ state.span.end();
12347
+ embedSpans.delete(event.embedCallId);
12348
+ });
12349
+ };
12350
+ const onRerankEnd = (event) => {
12351
+ runSafely("onRerankEnd", () => {
12352
+ const operationKey = operationKeyFromEvent(event);
12353
+ const span = operationKey ? rerankSpans.get(operationKey) : void 0;
12354
+ if (!operationKey || !span) {
12355
+ return;
12356
+ }
12357
+ const result = {
12358
+ ranking: event.ranking?.map((entry) => ({
12359
+ originalIndex: entry.index,
12360
+ score: entry.relevanceScore
12361
+ }))
12362
+ };
12363
+ span.log({
12364
+ ...shouldRecordOutputs(event) ? {
12365
+ output: processAISDKRerankOutput(
12366
+ result,
12367
+ DEFAULT_DENY_OUTPUT_PATHS
12368
+ )
12369
+ } : {}
12370
+ });
12371
+ span.end();
12372
+ rerankSpans.delete(operationKey);
12373
+ });
12374
+ };
12375
+ const onEnd = (event) => {
12376
+ runSafely("onEnd", () => {
12377
+ const operationKey = operationKeyFromEvent(event, "finish");
12378
+ const state = operationKey ? operations.get(operationKey) : void 0;
12379
+ if (!state) {
12380
+ return;
12381
+ }
12382
+ if (!state.ownsSpan) {
12383
+ deleteOperation(state.operationKey);
12384
+ return;
12385
+ }
12386
+ const result = finishResult(event, state.operationName);
12387
+ const metrics = state.hadModelChild ? {} : extractTokenMetrics(result);
12388
+ const timeToFirstToken = state.operationName === "WorkflowAgent.stream" ? void 0 : extractTimeToFirstToken(result, state);
12389
+ if (timeToFirstToken !== void 0) {
12390
+ metrics.time_to_first_token = timeToFirstToken;
12391
+ }
12392
+ state.span.log({
12393
+ ...shouldRecordOutputs(event) ? {
12394
+ output: finishOutput(result, state.operationName)
12395
+ } : {},
12396
+ metrics
12397
+ });
12398
+ state.span.end();
12399
+ deleteOperation(state.operationKey);
12400
+ });
12401
+ };
12402
+ return {
12403
+ onStart(event) {
12404
+ runSafely("onStart", () => {
12405
+ const operationName = operationNameFromId(event.operationId);
12406
+ const workflowAgent = operationName === "WorkflowAgent.stream";
12407
+ const wrapperSpan = workflowAgent ? currentWorkflowAgentWrapperSpan() : void 0;
12408
+ const ownsSpan = !wrapperSpan;
12409
+ const span = ownsSpan ? startSpan({
12410
+ name: operationName,
12411
+ spanAttributes: { type: "function" /* FUNCTION */ }
12412
+ }) : wrapperSpan;
12413
+ const operationKey = createOperationKey(event, operationName);
12414
+ registerOperation({
12415
+ callId: event.callId,
12416
+ hadModelChild: false,
12417
+ loggedInput: false,
12418
+ operationName,
12419
+ operationKey,
12420
+ ownsSpan,
12421
+ span,
12422
+ startTime: getCurrentUnixTimestamp()
12423
+ });
12424
+ if (!ownsSpan) {
12425
+ return;
12426
+ }
12427
+ if (workflowAgent) {
12428
+ workflowOperationKeyStore.enterWith(operationKey);
12429
+ }
12430
+ let metadata = metadataFromEvent(event);
12431
+ const logPayload = { metadata };
12432
+ const workflowAgentCallInput = workflowAgent ? operationInput(event, operationName) : void 0;
12433
+ if (workflowAgentCallInput) {
12434
+ metadata = {
12435
+ ...metadata,
12436
+ ...extractWorkflowMetadataFromCallParams(workflowAgentCallInput)
12437
+ };
12438
+ logPayload.metadata = metadata;
12439
+ }
12440
+ if (shouldRecordInputs(event)) {
12441
+ const callInput = workflowAgentCallInput ?? operationInput(event, operationName);
12442
+ const { input, outputPromise } = workflowAgent ? processAISDKWorkflowAgentCallInput(callInput) : processAISDKCallInput(callInput);
12443
+ logPayload.input = input;
12444
+ const state = operations.get(operationKey);
12445
+ if (state) {
12446
+ state.loggedInput = hasPromptLikeInput(input);
12447
+ }
12448
+ if (outputPromise && !workflowAgent && input && typeof input === "object") {
12449
+ outputPromise.then((resolvedData) => {
12450
+ span.log({
12451
+ input: {
12452
+ ...input,
12453
+ ...resolvedData
12454
+ }
12455
+ });
12456
+ }).catch(() => {
12457
+ });
12458
+ }
12459
+ }
12460
+ span.log(logPayload);
11462
12461
  });
11463
12462
  },
11464
- onObjectStepStart(event) {
11465
- runSafely("onObjectStepStart", () => {
11466
- const state = operations.get(event.callId);
11467
- const openSpan = objectSpans.get(event.callId);
11468
- if (openSpan) {
11469
- openSpan.end();
11470
- objectSpans.delete(event.callId);
12463
+ onLanguageModelCallStart(event) {
12464
+ runSafely("onLanguageModelCallStart", () => {
12465
+ const operationKey = operationKeyFromEvent(event);
12466
+ const state = operationKey ? operations.get(operationKey) : void 0;
12467
+ if (shouldSkipTelemetryChildren(state)) {
12468
+ return;
12469
+ }
12470
+ const operationName = state?.operationName ?? "generateText";
12471
+ const callInput = operationInput(event, operationName);
12472
+ const workflowAgent = operationName === "WorkflowAgent.stream";
12473
+ const processedInput = shouldRecordInputs(event) && workflowAgent ? processAISDKWorkflowAgentModelCallInput(callInput).input : shouldRecordInputs(event) ? processAISDKCallInput(callInput).input : void 0;
12474
+ if (workflowAgent && state?.ownsSpan && !state.loggedInput && hasPromptLikeInput(processedInput)) {
12475
+ state.span.log({
12476
+ input: processedInput,
12477
+ metadata: {
12478
+ ...metadataFromEvent(event),
12479
+ ...extractWorkflowMetadataFromCallParams(callInput)
12480
+ }
12481
+ });
12482
+ state.loggedInput = true;
12483
+ }
12484
+ const openSpans = operationKey ? modelSpans.get(operationKey) : void 0;
12485
+ if (operationKey && openSpans) {
12486
+ for (const span2 of openSpans) {
12487
+ span2.end();
12488
+ }
12489
+ modelSpans.delete(operationKey);
11471
12490
  }
11472
12491
  const span = startChildSpan(
11473
- event.callId,
11474
- state?.operationName === "streamObject" ? "doStream" : "doGenerate",
12492
+ operationKey ?? event.callId,
12493
+ operationName === "streamText" ? "doStream" : "doGenerate",
11475
12494
  "llm" /* LLM */,
11476
12495
  {
11477
12496
  ...shouldRecordInputs(event) ? {
11478
- input: {
11479
- prompt: event.promptMessages
11480
- }
12497
+ input: processedInput
11481
12498
  } : {},
11482
- metadata: metadataFromEvent(event)
12499
+ metadata: workflowAgent ? {
12500
+ ...metadataFromEvent(event),
12501
+ ...extractWorkflowMetadataFromCallParams(callInput)
12502
+ } : metadataFromEvent(event)
11483
12503
  }
11484
12504
  );
11485
- objectSpans.set(event.callId, span);
12505
+ const spanKey = operationKey ?? event.callId;
12506
+ const spans = modelSpans.get(spanKey) ?? [];
12507
+ spans.push(span);
12508
+ modelSpans.set(spanKey, spans);
11486
12509
  });
11487
12510
  },
11488
- onObjectStepFinish(event) {
11489
- runSafely("onObjectStepFinish", () => {
11490
- const span = objectSpans.get(event.callId);
12511
+ onLanguageModelCallEnd(event) {
12512
+ runSafely("onLanguageModelCallEnd", () => {
12513
+ const operationKey = operationKeyFromEvent(event);
12514
+ const state = operationKey ? operations.get(operationKey) : void 0;
12515
+ if (shouldSkipTelemetryChildren(state)) {
12516
+ return;
12517
+ }
12518
+ const span = operationKey ? shiftModelSpan(modelSpans, operationKey) : void 0;
11491
12519
  if (!span) {
11492
12520
  return;
11493
12521
  }
12522
+ const timeToFirstOutputMs = safePerformance(event)?.timeToFirstOutputMs;
12523
+ if (state?.operationName === "streamText" && state.firstChunkTime === void 0 && typeof timeToFirstOutputMs === "number") {
12524
+ state.firstChunkTime = state.startTime + timeToFirstOutputMs / 1e3;
12525
+ }
11494
12526
  const result = {
11495
12527
  ...event,
11496
- text: event.objectText
12528
+ response: event.responseId ? { id: event.responseId } : void 0
11497
12529
  };
11498
12530
  span.log({
11499
12531
  ...shouldRecordOutputs(event) ? {
@@ -11502,20 +12534,52 @@ function braintrustAISDKTelemetry() {
11502
12534
  metrics: extractTokenMetrics(result)
11503
12535
  });
11504
12536
  span.end();
11505
- objectSpans.delete(event.callId);
11506
12537
  });
11507
12538
  },
12539
+ onObjectStepStart(event) {
12540
+ runSafely("onObjectStepStart", () => {
12541
+ const operationKey = operationKeyFromEvent(event);
12542
+ const state = operationKey ? operations.get(operationKey) : void 0;
12543
+ if (shouldSkipTelemetryChildren(state)) {
12544
+ return;
12545
+ }
12546
+ const openSpan = operationKey ? objectSpans.get(operationKey) : void 0;
12547
+ if (operationKey && openSpan) {
12548
+ openSpan.end();
12549
+ objectSpans.delete(operationKey);
12550
+ }
12551
+ const span = startChildSpan(
12552
+ operationKey ?? event.callId,
12553
+ state?.operationName === "streamObject" ? "doStream" : "doGenerate",
12554
+ "llm" /* LLM */,
12555
+ {
12556
+ ...shouldRecordInputs(event) ? {
12557
+ input: {
12558
+ prompt: event.promptMessages
12559
+ }
12560
+ } : {},
12561
+ metadata: metadataFromEvent(event)
12562
+ }
12563
+ );
12564
+ objectSpans.set(operationKey ?? event.callId, span);
12565
+ });
12566
+ },
12567
+ onObjectStepEnd,
11508
12568
  onEmbedStart(event) {
11509
12569
  runSafely("onEmbedStart", () => {
11510
- const state = operations.get(event.callId);
12570
+ const operationKey = operationKeyFromEvent(event);
12571
+ const state = operationKey ? operations.get(operationKey) : void 0;
12572
+ if (shouldSkipTelemetryChildren(state)) {
12573
+ return;
12574
+ }
11511
12575
  for (const [embedCallId, embedState] of embedSpans) {
11512
- if (embedState.callId === event.callId && (state?.operationName === "embed" || embedState.values === event.values)) {
12576
+ if (embedState.operationKey === operationKey && (state?.operationName === "embed" || embedState.values === event.values)) {
11513
12577
  embedState.span.end();
11514
12578
  embedSpans.delete(embedCallId);
11515
12579
  }
11516
12580
  }
11517
12581
  const span = startChildSpan(
11518
- event.callId,
12582
+ operationKey ?? event.callId,
11519
12583
  "doEmbed",
11520
12584
  "llm" /* LLM */,
11521
12585
  {
@@ -11528,44 +12592,27 @@ function braintrustAISDKTelemetry() {
11528
12592
  }
11529
12593
  );
11530
12594
  embedSpans.set(event.embedCallId, {
11531
- callId: event.callId,
12595
+ operationKey: operationKey ?? event.callId,
11532
12596
  span,
11533
12597
  values: event.values
11534
12598
  });
11535
12599
  });
11536
12600
  },
11537
- onEmbedFinish(event) {
11538
- runSafely("onEmbedFinish", () => {
11539
- const state = embedSpans.get(event.embedCallId);
11540
- if (!state) {
11541
- return;
11542
- }
11543
- const result = {
11544
- ...event,
11545
- embeddings: event.embeddings
11546
- };
11547
- state.span.log({
11548
- ...shouldRecordOutputs(event) ? {
11549
- output: processAISDKEmbeddingOutput(
11550
- result,
11551
- DEFAULT_DENY_OUTPUT_PATHS
11552
- )
11553
- } : {},
11554
- metrics: extractTokenMetrics(result)
11555
- });
11556
- state.span.end();
11557
- embedSpans.delete(event.embedCallId);
11558
- });
11559
- },
12601
+ onEmbedEnd,
11560
12602
  onRerankStart(event) {
11561
12603
  runSafely("onRerankStart", () => {
11562
- const openSpan = rerankSpans.get(event.callId);
11563
- if (openSpan) {
12604
+ const operationKey = operationKeyFromEvent(event);
12605
+ const state = operationKey ? operations.get(operationKey) : void 0;
12606
+ if (shouldSkipTelemetryChildren(state)) {
12607
+ return;
12608
+ }
12609
+ const openSpan = operationKey ? rerankSpans.get(operationKey) : void 0;
12610
+ if (operationKey && openSpan) {
11564
12611
  openSpan.end();
11565
- rerankSpans.delete(event.callId);
12612
+ rerankSpans.delete(operationKey);
11566
12613
  }
11567
12614
  const span = startChildSpan(
11568
- event.callId,
12615
+ operationKey ?? event.callId,
11569
12616
  "doRerank",
11570
12617
  "llm" /* LLM */,
11571
12618
  {
@@ -11579,41 +12626,23 @@ function braintrustAISDKTelemetry() {
11579
12626
  metadata: metadataFromEvent(event)
11580
12627
  }
11581
12628
  );
11582
- rerankSpans.set(event.callId, span);
11583
- });
11584
- },
11585
- onRerankFinish(event) {
11586
- runSafely("onRerankFinish", () => {
11587
- const span = rerankSpans.get(event.callId);
11588
- if (!span) {
11589
- return;
11590
- }
11591
- const result = {
11592
- ranking: event.ranking?.map((entry) => ({
11593
- originalIndex: entry.index,
11594
- score: entry.relevanceScore
11595
- }))
11596
- };
11597
- span.log({
11598
- ...shouldRecordOutputs(event) ? {
11599
- output: processAISDKRerankOutput(
11600
- result,
11601
- DEFAULT_DENY_OUTPUT_PATHS
11602
- )
11603
- } : {}
11604
- });
11605
- span.end();
11606
- rerankSpans.delete(event.callId);
12629
+ rerankSpans.set(operationKey ?? event.callId, span);
11607
12630
  });
11608
12631
  },
12632
+ onRerankEnd,
11609
12633
  onToolExecutionStart(event) {
11610
12634
  runSafely("onToolExecutionStart", () => {
12635
+ const operationKey = operationKeyFromEvent(event);
12636
+ const state = operationKey ? operations.get(operationKey) : void 0;
12637
+ if (shouldSkipTelemetryChildren(state)) {
12638
+ return;
12639
+ }
11611
12640
  const toolCallId = event.toolCall.toolCallId;
11612
- if (!toolCallId) {
12641
+ if (!operationKey || !toolCallId) {
11613
12642
  return;
11614
12643
  }
11615
12644
  const span = startChildSpan(
11616
- event.callId,
12645
+ operationKey,
11617
12646
  event.toolCall.toolName || "tool",
11618
12647
  "tool" /* TOOL */,
11619
12648
  {
@@ -11627,7 +12656,7 @@ function braintrustAISDKTelemetry() {
11627
12656
  }
11628
12657
  }
11629
12658
  );
11630
- toolSpans.set(toolCallId, { callId: event.callId, span });
12659
+ toolSpans.set(toolCallId, { operationKey, span });
11631
12660
  });
11632
12661
  },
11633
12662
  onToolExecutionEnd(event) {
@@ -11638,14 +12667,17 @@ function braintrustAISDKTelemetry() {
11638
12667
  return;
11639
12668
  }
11640
12669
  const toolOutput = event.toolOutput;
11641
- if (toolOutput?.type === "tool-error") {
12670
+ const workflowToolError = event.success === false && "error" in event ? event.error : void 0;
12671
+ if (toolOutput?.type === "tool-error" || workflowToolError !== void 0) {
12672
+ const error = toolOutput?.error ?? workflowToolError;
11642
12673
  state.span.log({
11643
- error: toolOutput.error instanceof Error ? toolOutput.error.message : String(toolOutput?.error),
12674
+ error: error instanceof Error ? error.message : String(error),
11644
12675
  metrics: typeof event.durationMs === "number" ? { duration_ms: event.durationMs } : {}
11645
12676
  });
11646
12677
  } else {
12678
+ const output = toolOutput && "output" in toolOutput ? toolOutput.output : event.output;
11647
12679
  state.span.log({
11648
- ...shouldRecordOutputs(event) ? { output: toolOutput?.output } : {},
12680
+ ...shouldRecordOutputs(event) ? { output } : {},
11649
12681
  metrics: typeof event.durationMs === "number" ? { duration_ms: event.durationMs } : {}
11650
12682
  });
11651
12683
  }
@@ -11659,83 +12691,46 @@ function braintrustAISDKTelemetry() {
11659
12691
  if (!callId) {
11660
12692
  return;
11661
12693
  }
11662
- const state = operations.get(callId);
12694
+ const operationKey = operationKeyForCallId(callId);
12695
+ const state = operationKey ? operations.get(operationKey) : void 0;
11663
12696
  if (!state || state.firstChunkTime !== void 0) {
11664
12697
  return;
11665
12698
  }
11666
12699
  state.firstChunkTime = getCurrentUnixTimestamp();
11667
12700
  });
11668
12701
  },
11669
- onFinish(event) {
11670
- runSafely("onFinish", () => {
11671
- const state = operations.get(event.callId);
11672
- if (!state) {
12702
+ onEnd,
12703
+ onAbort(event) {
12704
+ runSafely("onAbort", () => {
12705
+ const operationKey = operationKeyFromEvent(event, "finish");
12706
+ const state = operationKey ? operations.get(operationKey) : void 0;
12707
+ if (!operationKey || !state) {
11673
12708
  return;
11674
12709
  }
11675
- const result = finishResult(event, state.operationName);
11676
- const metrics = state.hadModelChild ? {} : extractTokenMetrics(result);
11677
- if (state.firstChunkTime !== void 0) {
11678
- metrics.time_to_first_token = state.firstChunkTime - state.startTime;
12710
+ const error = abortReasonFromEvent(event);
12711
+ closeOpenChildSpans(operationKey, error);
12712
+ if (state.ownsSpan) {
12713
+ logError(state.span, error);
12714
+ state.span.end();
11679
12715
  }
11680
- state.span.log({
11681
- ...shouldRecordOutputs(event) ? {
11682
- output: finishOutput(result, state.operationName)
11683
- } : {},
11684
- metrics
11685
- });
11686
- state.span.end();
11687
- operations.delete(event.callId);
12716
+ deleteOperation(operationKey);
11688
12717
  });
11689
12718
  },
11690
12719
  onError(event) {
11691
12720
  runSafely("onError", () => {
11692
12721
  const errorEvent = isObject(event) ? event : {};
11693
- const callId = typeof errorEvent.callId === "string" ? errorEvent.callId : void 0;
11694
- if (!callId) {
11695
- return;
11696
- }
11697
- const state = operations.get(callId);
11698
- if (!state) {
12722
+ const operationKey = operationKeyFromEvent(errorEvent, "finish");
12723
+ const state = operationKey ? operations.get(operationKey) : void 0;
12724
+ if (!operationKey || !state) {
11699
12725
  return;
11700
12726
  }
11701
12727
  const error = errorEvent.error ?? event;
11702
- const openModelSpans = modelSpans.get(callId);
11703
- if (openModelSpans) {
11704
- for (const span of openModelSpans) {
11705
- logError(span, error);
11706
- span.end();
11707
- }
11708
- modelSpans.delete(callId);
11709
- }
11710
- const openObjectSpan = objectSpans.get(callId);
11711
- if (openObjectSpan) {
11712
- logError(openObjectSpan, error);
11713
- openObjectSpan.end();
11714
- objectSpans.delete(callId);
11715
- }
11716
- for (const [embedCallId, embedState] of embedSpans) {
11717
- if (embedState.callId === callId) {
11718
- logError(embedState.span, error);
11719
- embedState.span.end();
11720
- embedSpans.delete(embedCallId);
11721
- }
11722
- }
11723
- const openRerankSpan = rerankSpans.get(callId);
11724
- if (openRerankSpan) {
11725
- logError(openRerankSpan, error);
11726
- openRerankSpan.end();
11727
- rerankSpans.delete(callId);
11728
- }
11729
- for (const [toolCallId, toolState] of toolSpans) {
11730
- if (toolState.callId === callId) {
11731
- logError(toolState.span, error);
11732
- toolState.span.end();
11733
- toolSpans.delete(toolCallId);
11734
- }
12728
+ closeOpenChildSpans(operationKey, error);
12729
+ if (state.ownsSpan) {
12730
+ logError(state.span, error);
12731
+ state.span.end();
11735
12732
  }
11736
- logError(state.span, error);
11737
- state.span.end();
11738
- operations.delete(callId);
12733
+ deleteOperation(operationKey);
11739
12734
  });
11740
12735
  },
11741
12736
  executeTool({ toolCallId, execute }) {
@@ -11750,7 +12745,16 @@ function shouldRecordInputs(event) {
11750
12745
  function shouldRecordOutputs(event) {
11751
12746
  return event.recordOutputs !== false;
11752
12747
  }
12748
+ function hasPromptLikeInput(input) {
12749
+ if (!isObject(input)) {
12750
+ return false;
12751
+ }
12752
+ return input.prompt !== void 0 || input.messages !== void 0;
12753
+ }
11753
12754
  function operationNameFromId(operationId) {
12755
+ if (operationId === "ai.workflowAgent.stream") {
12756
+ return "WorkflowAgent.stream";
12757
+ }
11754
12758
  return operationId?.startsWith("ai.") ? operationId.slice("ai.".length) : operationId || "ai-sdk";
11755
12759
  }
11756
12760
  function modelFromEvent(event) {
@@ -11796,6 +12800,7 @@ function operationInput(event, operationName) {
11796
12800
  }
11797
12801
  return {
11798
12802
  model: modelFromEvent(event),
12803
+ instructions: event.instructions,
11799
12804
  system: event.system,
11800
12805
  prompt: event.prompt,
11801
12806
  messages: event.messages,
@@ -11844,6 +12849,30 @@ function finishResult(event, operationName) {
11844
12849
  }
11845
12850
  return event;
11846
12851
  }
12852
+ function extractTimeToFirstToken(result, state) {
12853
+ if (state.firstChunkTime !== void 0) {
12854
+ return state.firstChunkTime - state.startTime;
12855
+ }
12856
+ const performanceCandidates = [
12857
+ safePerformance(result),
12858
+ safePerformance(result.finalStep),
12859
+ ...Array.isArray(result.steps) ? (result.steps ?? []).map(safePerformance) : []
12860
+ ];
12861
+ for (const performance of performanceCandidates) {
12862
+ const timeToFirstOutputMs = performance?.timeToFirstOutputMs;
12863
+ if (typeof timeToFirstOutputMs === "number") {
12864
+ return timeToFirstOutputMs / 1e3;
12865
+ }
12866
+ }
12867
+ return void 0;
12868
+ }
12869
+ function safePerformance(value) {
12870
+ if (!isObject(value)) {
12871
+ return void 0;
12872
+ }
12873
+ const performance = value.performance;
12874
+ return isObject(performance) ? performance : void 0;
12875
+ }
11847
12876
  function finishOutput(result, operationName) {
11848
12877
  if (operationName === "embed" || operationName === "embedMany") {
11849
12878
  return processAISDKEmbeddingOutput(
@@ -11920,6 +12949,10 @@ var aiSDKChannels = defineChannels("ai", {
11920
12949
  channelName: "ToolLoopAgent.stream",
11921
12950
  kind: "async"
11922
12951
  }),
12952
+ workflowAgentStream: channel({
12953
+ channelName: "WorkflowAgent.stream",
12954
+ kind: "async"
12955
+ }),
11923
12956
  v7CreateTelemetryDispatcher: channel({
11924
12957
  channelName: "createTelemetryDispatcher",
11925
12958
  kind: "sync-stream"
@@ -11930,14 +12963,19 @@ var aiSDKChannels = defineChannels("ai", {
11930
12963
  var DEFAULT_DENY_OUTPUT_PATHS = [
11931
12964
  // v3
11932
12965
  "roundtrips[].request.body",
12966
+ "roundtrips[].request.headers",
11933
12967
  "roundtrips[].response.headers",
11934
12968
  "rawResponse.headers",
11935
12969
  "responseMessages",
11936
12970
  // v5
11937
12971
  "request.body",
12972
+ "request.headers",
12973
+ "responses[].headers",
11938
12974
  "response.body",
11939
12975
  "response.headers",
11940
12976
  "steps[].request.body",
12977
+ "steps[].request.headers",
12978
+ "steps[].responses[].headers",
11941
12979
  "steps[].response.body",
11942
12980
  "steps[].response.headers"
11943
12981
  ];
@@ -11949,6 +12987,18 @@ var AUTO_PATCHED_V7_TELEMETRY_DISPATCHER = /* @__PURE__ */ Symbol.for(
11949
12987
  var RUNTIME_DENY_OUTPUT_PATHS = /* @__PURE__ */ Symbol.for(
11950
12988
  "braintrust.ai-sdk.deny-output-paths"
11951
12989
  );
12990
+ var aiSDKV7TelemetryOperationCounter = 0;
12991
+ var TRANSPORT_PAYLOAD_ROOT_PATHS = [
12992
+ "rawResponse",
12993
+ "request",
12994
+ "response",
12995
+ "responses[]",
12996
+ "roundtrips[].request",
12997
+ "roundtrips[].response",
12998
+ "steps[].request",
12999
+ "steps[].response",
13000
+ "steps[].responses[]"
13001
+ ];
11952
13002
  var AI_SDK_V7_TELEMETRY_CALLBACKS = [
11953
13003
  "onStart",
11954
13004
  "onStepStart",
@@ -11957,14 +13007,16 @@ var AI_SDK_V7_TELEMETRY_CALLBACKS = [
11957
13007
  "onToolExecutionStart",
11958
13008
  "onToolExecutionEnd",
11959
13009
  "onChunk",
13010
+ "onStepEnd",
11960
13011
  "onStepFinish",
11961
13012
  "onObjectStepStart",
11962
- "onObjectStepFinish",
13013
+ "onObjectStepEnd",
11963
13014
  "onEmbedStart",
11964
- "onEmbedFinish",
13015
+ "onEmbedEnd",
11965
13016
  "onRerankStart",
11966
- "onRerankFinish",
11967
- "onFinish",
13017
+ "onRerankEnd",
13018
+ "onEnd",
13019
+ "onAbort",
11968
13020
  "onError"
11969
13021
  ];
11970
13022
  var AISDKPlugin = class extends BasePlugin {
@@ -12122,7 +13174,9 @@ var AISDKPlugin = class extends BasePlugin {
12122
13174
  traceStreamingChannel(aiSDKChannels.agentGenerate, {
12123
13175
  name: "Agent.generate",
12124
13176
  type: "function" /* FUNCTION */,
12125
- extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
13177
+ extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
13178
+ agentOwner: true
13179
+ }),
12126
13180
  extractOutput: (result, endEvent) => {
12127
13181
  finalizeAISDKChildTracing(endEvent);
12128
13182
  return processAISDKOutput(
@@ -12138,7 +13192,9 @@ var AISDKPlugin = class extends BasePlugin {
12138
13192
  traceStreamingChannel(aiSDKChannels.agentStream, {
12139
13193
  name: "Agent.stream",
12140
13194
  type: "function" /* FUNCTION */,
12141
- extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
13195
+ extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
13196
+ agentOwner: true
13197
+ }),
12142
13198
  extractOutput: (result, endEvent) => processAISDKOutput(
12143
13199
  result,
12144
13200
  resolveDenyOutputPaths(endEvent, denyOutputPaths)
@@ -12158,7 +13214,9 @@ var AISDKPlugin = class extends BasePlugin {
12158
13214
  traceSyncStreamChannel(aiSDKChannels.agentStreamSync, {
12159
13215
  name: "Agent.stream",
12160
13216
  type: "function" /* FUNCTION */,
12161
- extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
13217
+ extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
13218
+ agentOwner: true
13219
+ }),
12162
13220
  patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
12163
13221
  defaultDenyOutputPaths: denyOutputPaths,
12164
13222
  endEvent,
@@ -12172,7 +13230,9 @@ var AISDKPlugin = class extends BasePlugin {
12172
13230
  traceStreamingChannel(aiSDKChannels.toolLoopAgentGenerate, {
12173
13231
  name: "ToolLoopAgent.generate",
12174
13232
  type: "function" /* FUNCTION */,
12175
- extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
13233
+ extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
13234
+ agentOwner: true
13235
+ }),
12176
13236
  extractOutput: (result, endEvent) => {
12177
13237
  finalizeAISDKChildTracing(endEvent);
12178
13238
  return processAISDKOutput(
@@ -12188,7 +13248,9 @@ var AISDKPlugin = class extends BasePlugin {
12188
13248
  traceStreamingChannel(aiSDKChannels.toolLoopAgentStream, {
12189
13249
  name: "ToolLoopAgent.stream",
12190
13250
  type: "function" /* FUNCTION */,
12191
- extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
13251
+ extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
13252
+ agentOwner: true
13253
+ }),
12192
13254
  extractOutput: (result, endEvent) => processAISDKOutput(
12193
13255
  result,
12194
13256
  resolveDenyOutputPaths(endEvent, denyOutputPaths)
@@ -12204,6 +13266,42 @@ var AISDKPlugin = class extends BasePlugin {
12204
13266
  })
12205
13267
  })
12206
13268
  );
13269
+ this.unsubscribers.push(
13270
+ traceStreamingChannel(aiSDKChannels.workflowAgentStream, {
13271
+ name: "WorkflowAgent.stream",
13272
+ type: "function" /* FUNCTION */,
13273
+ extractInput: ([params], event, span) => prepareAISDKWorkflowAgentStreamInput(
13274
+ params,
13275
+ event,
13276
+ span,
13277
+ denyOutputPaths
13278
+ ),
13279
+ extractOutput: (result, endEvent) => {
13280
+ finalizeAISDKChildTracing(endEvent);
13281
+ return processAISDKOutput(
13282
+ result,
13283
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
13284
+ );
13285
+ },
13286
+ extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
13287
+ aggregateChunks: aggregateAISDKChunks,
13288
+ onComplete: ({ span }) => {
13289
+ unregisterWorkflowAgentWrapperSpan(span);
13290
+ },
13291
+ onError: ({ event, span }) => {
13292
+ finalizeAISDKChildTracing(event);
13293
+ unregisterWorkflowAgentWrapperSpan(span);
13294
+ },
13295
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
13296
+ defaultDenyOutputPaths: denyOutputPaths,
13297
+ endEvent,
13298
+ onComplete: () => unregisterWorkflowAgentWrapperSpan(span),
13299
+ result,
13300
+ span,
13301
+ startTime
13302
+ })
13303
+ })
13304
+ );
12207
13305
  }
12208
13306
  };
12209
13307
  function subscribeToAISDKV7TelemetryDispatcher() {
@@ -12215,7 +13313,11 @@ function subscribeToAISDKV7TelemetryDispatcher() {
12215
13313
  if (telemetryOptions?.isEnabled === false) {
12216
13314
  return;
12217
13315
  }
12218
- patchAISDKV7TelemetryDispatcher(event.result, telemetry);
13316
+ patchAISDKV7TelemetryDispatcher(
13317
+ event.result,
13318
+ telemetry,
13319
+ telemetryOptions
13320
+ );
12219
13321
  }
12220
13322
  };
12221
13323
  channel2.subscribe(handlers);
@@ -12223,7 +13325,7 @@ function subscribeToAISDKV7TelemetryDispatcher() {
12223
13325
  channel2.unsubscribe(handlers);
12224
13326
  };
12225
13327
  }
12226
- function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry) {
13328
+ function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry, telemetryOptions) {
12227
13329
  if (!isObject(dispatcher)) {
12228
13330
  return;
12229
13331
  }
@@ -12232,6 +13334,54 @@ function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry) {
12232
13334
  return;
12233
13335
  }
12234
13336
  dispatcherRecord[AUTO_PATCHED_V7_TELEMETRY_DISPATCHER] = true;
13337
+ let operationKey;
13338
+ const telemetryEventFields = {};
13339
+ if (typeof telemetryOptions?.recordInputs === "boolean") {
13340
+ telemetryEventFields.recordInputs = telemetryOptions.recordInputs;
13341
+ }
13342
+ if (typeof telemetryOptions?.recordOutputs === "boolean") {
13343
+ telemetryEventFields.recordOutputs = telemetryOptions.recordOutputs;
13344
+ }
13345
+ if (typeof telemetryOptions?.functionId === "string") {
13346
+ telemetryEventFields.functionId = telemetryOptions.functionId;
13347
+ }
13348
+ const eventWithOperationKey = (event) => {
13349
+ if (!isObject(event)) {
13350
+ return event;
13351
+ }
13352
+ const eventRecord = event;
13353
+ const callId = typeof eventRecord.callId === "string" ? eventRecord.callId : "unknown";
13354
+ operationKey ??= `${callId}:${++aiSDKV7TelemetryOperationCounter}`;
13355
+ if (Object.keys(telemetryEventFields).length > 0) {
13356
+ const augmentedEvent = {
13357
+ ...telemetryEventFields,
13358
+ ...event
13359
+ };
13360
+ try {
13361
+ Object.defineProperty(augmentedEvent, BRAINTRUST_AI_SDK_V7_OPERATION_KEY, {
13362
+ configurable: true,
13363
+ enumerable: false,
13364
+ value: operationKey
13365
+ });
13366
+ } catch {
13367
+ augmentedEvent[BRAINTRUST_AI_SDK_V7_OPERATION_KEY] = operationKey;
13368
+ }
13369
+ return augmentedEvent;
13370
+ }
13371
+ try {
13372
+ Object.defineProperty(eventRecord, BRAINTRUST_AI_SDK_V7_OPERATION_KEY, {
13373
+ configurable: true,
13374
+ enumerable: false,
13375
+ value: operationKey
13376
+ });
13377
+ return event;
13378
+ } catch {
13379
+ return {
13380
+ ...event,
13381
+ [BRAINTRUST_AI_SDK_V7_OPERATION_KEY]: operationKey
13382
+ };
13383
+ }
13384
+ };
12235
13385
  for (const key of AI_SDK_V7_TELEMETRY_CALLBACKS) {
12236
13386
  const braintrustCallback = telemetry[key];
12237
13387
  if (typeof braintrustCallback !== "function") {
@@ -12240,11 +13390,17 @@ function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry) {
12240
13390
  const existingCallback = dispatcherRecord[key];
12241
13391
  dispatcherRecord[key] = (event) => {
12242
13392
  const existingResult = typeof existingCallback === "function" ? existingCallback.call(dispatcher, event) : void 0;
12243
- const braintrustResult = braintrustCallback.call(telemetry, event);
12244
- const pending = [existingResult, braintrustResult].filter(isPromiseLike);
12245
- if (pending.length > 0) {
12246
- return Promise.allSettled(pending).then(() => void 0);
13393
+ try {
13394
+ const braintrustResult = braintrustCallback.call(
13395
+ telemetry,
13396
+ eventWithOperationKey(event)
13397
+ );
13398
+ if (isPromiseLike(braintrustResult)) {
13399
+ void Promise.resolve(braintrustResult).catch(() => void 0);
13400
+ }
13401
+ } catch {
12247
13402
  }
13403
+ return existingResult;
12248
13404
  };
12249
13405
  }
12250
13406
  const braintrustExecuteTool = telemetry.executeTool;
@@ -12254,6 +13410,7 @@ function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry) {
12254
13410
  const existingExecuteTool = dispatcherRecord.executeTool;
12255
13411
  dispatcherRecord.executeTool = (args) => braintrustExecuteTool.call(telemetry, {
12256
13412
  ...args,
13413
+ ...operationKey ? { [BRAINTRUST_AI_SDK_V7_OPERATION_KEY]: operationKey } : {},
12257
13414
  execute: () => typeof existingExecuteTool === "function" ? existingExecuteTool.call(dispatcher, args) : args.execute()
12258
13415
  });
12259
13416
  }
@@ -12352,6 +13509,8 @@ var serializeOutputObject = (output, model) => {
12352
13509
  var processInputAttachmentsSync = (input) => {
12353
13510
  if (!input) return { input };
12354
13511
  const processed = { ...input };
13512
+ delete processed.headers;
13513
+ delete processed.experimental_output;
12355
13514
  if (input.messages && Array.isArray(input.messages)) {
12356
13515
  processed.messages = input.messages.map(processMessage);
12357
13516
  }
@@ -12385,10 +13544,10 @@ var processInputAttachmentsSync = (input) => {
12385
13544
  processed.output = serialized;
12386
13545
  }
12387
13546
  }
12388
- if ("prepareCall" in processed && typeof processed.prepareCall === "function") {
12389
- processed.prepareCall = "[Function]";
12390
- }
12391
- return { input: processed, outputPromise };
13547
+ return {
13548
+ input: sanitizeAISDKCallInputValue(processed),
13549
+ outputPromise
13550
+ };
12392
13551
  };
12393
13552
  var processMessage = (message) => {
12394
13553
  if (!message || typeof message !== "object") return message;
@@ -12552,7 +13711,21 @@ var convertDataToAttachment = (data, mimeType, filename) => {
12552
13711
  function processAISDKCallInput(params) {
12553
13712
  return processInputAttachmentsSync(params);
12554
13713
  }
12555
- function prepareAISDKCallInput(params, event, span, defaultDenyOutputPaths) {
13714
+ function processAISDKWorkflowAgentCallInput(params) {
13715
+ const processed = processAISDKCallInput(params);
13716
+ return {
13717
+ ...processed,
13718
+ input: extractWorkflowAgentInput(processed.input)
13719
+ };
13720
+ }
13721
+ function processAISDKWorkflowAgentModelCallInput(params) {
13722
+ const processed = processAISDKCallInput(params);
13723
+ return {
13724
+ ...processed,
13725
+ input: extractWorkflowAgentModelInput(processed.input)
13726
+ };
13727
+ }
13728
+ function prepareAISDKCallInput(params, event, span, defaultDenyOutputPaths, childTracingOptions = {}) {
12556
13729
  const { input, outputPromise } = processAISDKCallInput(params);
12557
13730
  if (outputPromise && input && typeof input === "object") {
12558
13731
  outputPromise.then((resolvedData) => {
@@ -12571,7 +13744,29 @@ function prepareAISDKCallInput(params, event, span, defaultDenyOutputPaths) {
12571
13744
  event.self,
12572
13745
  span,
12573
13746
  defaultDenyOutputPaths,
12574
- event.aiSDK
13747
+ event.aiSDK,
13748
+ childTracingOptions
13749
+ );
13750
+ event.modelWrapped = childTracing.modelWrapped;
13751
+ if (childTracing.cleanup) {
13752
+ event.__braintrust_ai_sdk_cleanup = childTracing.cleanup;
13753
+ }
13754
+ return {
13755
+ input,
13756
+ metadata
13757
+ };
13758
+ }
13759
+ function prepareAISDKWorkflowAgentStreamInput(params, event, span, defaultDenyOutputPaths) {
13760
+ registerWorkflowAgentWrapperSpan(span);
13761
+ const { input } = processAISDKWorkflowAgentCallInput(params);
13762
+ const metadata = extractWorkflowMetadataFromCallParams(params, event.self);
13763
+ const childTracing = prepareAISDKChildTracing(
13764
+ params,
13765
+ event.self,
13766
+ span,
13767
+ defaultDenyOutputPaths,
13768
+ event.aiSDK,
13769
+ { agentOwner: true, workflowAgent: true }
12575
13770
  );
12576
13771
  event.modelWrapped = childTracing.modelWrapped;
12577
13772
  if (childTracing.cleanup) {
@@ -12608,6 +13803,9 @@ function extractTopLevelAISDKMetrics(result, event, startTime) {
12608
13803
  function hasModelChildTracing(event) {
12609
13804
  return event?.modelWrapped === true || event?.__braintrust_ai_sdk_model_wrapped === true;
12610
13805
  }
13806
+ function serializeToolExecutionInput(args) {
13807
+ return args.length > 0 ? args[0] : args;
13808
+ }
12611
13809
  function createAISDKIntegrationMetadata() {
12612
13810
  return {
12613
13811
  braintrust: {
@@ -12619,6 +13817,13 @@ function createAISDKIntegrationMetadata() {
12619
13817
  function resolveModelFromSelf(self) {
12620
13818
  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;
12621
13819
  }
13820
+ function resolveToolsFromSelf(self) {
13821
+ if (!self || typeof self !== "object") {
13822
+ return void 0;
13823
+ }
13824
+ const selfRecord = self;
13825
+ return selfRecord.tools ?? selfRecord.settings?.tools;
13826
+ }
12622
13827
  function extractBaseMetadata(model, self) {
12623
13828
  const metadata = createAISDKIntegrationMetadata();
12624
13829
  const { model: modelId, provider } = serializeModelWithProvider(
@@ -12634,12 +13839,175 @@ function extractBaseMetadata(model, self) {
12634
13839
  }
12635
13840
  function extractMetadataFromCallParams(params, self) {
12636
13841
  const metadata = extractBaseMetadata(params.model, self);
12637
- const tools = serializeAISDKToolsForLogging(params.tools);
13842
+ const tools = serializeAISDKToolsForLogging(
13843
+ params.tools ?? resolveToolsFromSelf(self)
13844
+ );
12638
13845
  if (tools) {
12639
13846
  metadata.tools = tools;
12640
13847
  }
12641
13848
  return metadata;
12642
13849
  }
13850
+ function extractWorkflowMetadataFromCallParams(params, self) {
13851
+ const metadata = extractMetadataFromCallParams(params, self);
13852
+ const options = extractAISDKCallOptionsForMetadata(params);
13853
+ if (Object.keys(options).length > 0) {
13854
+ metadata.options = options;
13855
+ }
13856
+ return metadata;
13857
+ }
13858
+ function extractWorkflowAgentInput(params) {
13859
+ const input = {};
13860
+ if (params.instructions !== void 0) {
13861
+ input.instructions = params.instructions;
13862
+ }
13863
+ if (params.system !== void 0) {
13864
+ input.system = params.system;
13865
+ }
13866
+ if (Array.isArray(params.messages)) {
13867
+ return { ...input, messages: params.messages };
13868
+ }
13869
+ if (typeof params.prompt === "string") {
13870
+ return { ...input, prompt: params.prompt };
13871
+ }
13872
+ if (Array.isArray(params.prompt)) {
13873
+ return { ...input, prompt: params.prompt };
13874
+ }
13875
+ return input;
13876
+ }
13877
+ function extractWorkflowAgentModelInput(params) {
13878
+ const input = {};
13879
+ if (params.instructions !== void 0) {
13880
+ input.instructions = params.instructions;
13881
+ }
13882
+ if (params.system !== void 0) {
13883
+ input.system = params.system;
13884
+ }
13885
+ if (Array.isArray(params.messages)) {
13886
+ return { ...input, messages: params.messages };
13887
+ }
13888
+ if (typeof params.prompt === "string") {
13889
+ return { ...input, prompt: params.prompt };
13890
+ }
13891
+ if (Array.isArray(params.prompt)) {
13892
+ return { ...input, messages: params.prompt };
13893
+ }
13894
+ return input;
13895
+ }
13896
+ function sanitizeAISDKCallInputValue(value, depth = 0) {
13897
+ if (value === void 0 || typeof value === "function") {
13898
+ return void 0;
13899
+ }
13900
+ if (value === null || typeof value !== "object") {
13901
+ return value;
13902
+ }
13903
+ if (isPromiseLike(value)) {
13904
+ return "[Promise]";
13905
+ }
13906
+ if (typeof AbortSignal !== "undefined" && value instanceof AbortSignal) {
13907
+ return "[AbortSignal]";
13908
+ }
13909
+ if (depth >= 8) {
13910
+ return "[Object]";
13911
+ }
13912
+ if (Array.isArray(value)) {
13913
+ return value.map((item) => sanitizeAISDKCallInputValue(item, depth + 1)).filter((item) => item !== void 0);
13914
+ }
13915
+ if (!isObject(value)) {
13916
+ return value;
13917
+ }
13918
+ const prototype = Object.getPrototypeOf(value);
13919
+ if (prototype !== Object.prototype && prototype !== null) {
13920
+ return value;
13921
+ }
13922
+ const sanitized = {};
13923
+ for (const [key, nested] of Object.entries(value)) {
13924
+ if (key === "__proto__" || key === "constructor" || key === "prototype" || key.toLowerCase() === "headers") {
13925
+ continue;
13926
+ }
13927
+ const sanitizedNested = sanitizeAISDKCallInputValue(nested, depth + 1);
13928
+ if (sanitizedNested !== void 0) {
13929
+ sanitized[key] = sanitizedNested;
13930
+ }
13931
+ }
13932
+ return sanitized;
13933
+ }
13934
+ function extractAISDKCallOptionsForMetadata(params) {
13935
+ const options = {};
13936
+ const inputOrTopLevelKeys = /* @__PURE__ */ new Set([
13937
+ "model",
13938
+ "instructions",
13939
+ "messages",
13940
+ "prompt",
13941
+ "system",
13942
+ "tools",
13943
+ "headers",
13944
+ "abortSignal",
13945
+ "signal",
13946
+ "experimental_output"
13947
+ ]);
13948
+ for (const [key, value] of Object.entries(params)) {
13949
+ if (inputOrTopLevelKeys.has(key) || key === "__proto__" || key === "constructor" || key === "prototype" || /^on[A-Z]/.test(key) && typeof value === "function") {
13950
+ continue;
13951
+ }
13952
+ const sanitized = sanitizeAISDKMetadataValue(value);
13953
+ if (sanitized !== void 0) {
13954
+ options[key] = sanitized;
13955
+ }
13956
+ }
13957
+ return options;
13958
+ }
13959
+ function sanitizeAISDKMetadataValue(value, depth = 0) {
13960
+ if (value === void 0) {
13961
+ return void 0;
13962
+ }
13963
+ if (typeof value === "function") {
13964
+ return "[Function]";
13965
+ }
13966
+ if (value === null || typeof value !== "object") {
13967
+ return value;
13968
+ }
13969
+ if (isPromiseLike(value)) {
13970
+ return "[Promise]";
13971
+ }
13972
+ if (typeof AbortSignal !== "undefined" && value instanceof AbortSignal) {
13973
+ return "[AbortSignal]";
13974
+ }
13975
+ if (depth >= 8) {
13976
+ return "[Object]";
13977
+ }
13978
+ if (Array.isArray(value)) {
13979
+ return value.map((item) => sanitizeAISDKMetadataValue(item, depth + 1)).filter((item) => item !== void 0);
13980
+ }
13981
+ if (!isObject(value)) {
13982
+ return value;
13983
+ }
13984
+ const sanitized = {};
13985
+ for (const [key, nested] of Object.entries(value)) {
13986
+ if (key === "__proto__" || key === "constructor" || key === "prototype" || key.toLowerCase() === "headers") {
13987
+ continue;
13988
+ }
13989
+ const sanitizedNested = sanitizeAISDKMetadataValue(nested, depth + 1);
13990
+ if (sanitizedNested !== void 0) {
13991
+ sanitized[key] = sanitizedNested;
13992
+ }
13993
+ }
13994
+ return sanitized;
13995
+ }
13996
+ function buildAISDKModelStartEvent(callOptions, baseMetadata, options) {
13997
+ if (!options.workflowAgent) {
13998
+ return {
13999
+ input: processAISDKCallInput(callOptions).input,
14000
+ metadata: baseMetadata
14001
+ };
14002
+ }
14003
+ return {
14004
+ input: processAISDKWorkflowAgentModelCallInput(callOptions).input,
14005
+ metadata: {
14006
+ ...baseMetadata,
14007
+ ...extractWorkflowMetadataFromCallParams(callOptions)
14008
+ }
14009
+ };
14010
+ }
12643
14011
  function extractMetadataFromEmbedParams(params, self) {
12644
14012
  return extractBaseMetadata(params.model, self);
12645
14013
  }
@@ -12653,65 +14021,228 @@ function extractMetadataFromRerankParams(params, self) {
12653
14021
  }
12654
14022
  return metadata;
12655
14023
  }
12656
- function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiSDK) {
14024
+ function activeAISDKChildPatchEntry(entries) {
14025
+ const activeSpan = currentSpan();
14026
+ const activeSpanId = activeSpan.spanId;
14027
+ if (activeSpanId) {
14028
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
14029
+ const entry = entries[index];
14030
+ if (entry?.activeSpanIds.has(activeSpanId)) {
14031
+ return entry;
14032
+ }
14033
+ }
14034
+ }
14035
+ const activeParentSpanIds = activeSpan.spanParents ?? [];
14036
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
14037
+ const entry = entries[index];
14038
+ if (entry?.parentSpan.spanId && activeParentSpanIds.includes(entry.parentSpan.spanId)) {
14039
+ return entry;
14040
+ }
14041
+ }
14042
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
14043
+ const entry = entries[index];
14044
+ if (entry?.parentSpan.spanId === activeSpanId) {
14045
+ return entry;
14046
+ }
14047
+ }
14048
+ return entries[entries.length - 1];
14049
+ }
14050
+ function attachNestedAISDKChildPatchEntry(entries, nestedSpan, cleanup) {
14051
+ const activeSpanId = currentSpan().spanId;
14052
+ if (!activeSpanId || activeSpanId === nestedSpan.spanId) {
14053
+ return false;
14054
+ }
14055
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
14056
+ const entry = entries[index];
14057
+ if (entry?.parentSpan.spanId === activeSpanId || entry?.activeSpanIds.has(activeSpanId)) {
14058
+ entry.activeSpanIds.add(nestedSpan.spanId);
14059
+ cleanup.push(() => {
14060
+ entry.activeSpanIds.delete(nestedSpan.spanId);
14061
+ });
14062
+ return true;
14063
+ }
14064
+ }
14065
+ return false;
14066
+ }
14067
+ function shadowActiveAISDKChildPatchEntry(entries, entry, nestedSpan, cleanup) {
14068
+ const activeSpanId = currentSpan().spanId;
14069
+ if (!activeSpanId || activeSpanId === nestedSpan.spanId) {
14070
+ return;
14071
+ }
14072
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
14073
+ const existingEntry = entries[index];
14074
+ if (existingEntry?.parentSpan.spanId === activeSpanId || existingEntry?.activeSpanIds.has(activeSpanId)) {
14075
+ entry.activeSpanIds.add(activeSpanId);
14076
+ cleanup.push(() => {
14077
+ entry.activeSpanIds.delete(activeSpanId);
14078
+ });
14079
+ return;
14080
+ }
14081
+ }
14082
+ }
14083
+ function closeOpenAISDKModelPatchSpans(entry) {
14084
+ for (const span of entry.openSpans) {
14085
+ span.end();
14086
+ }
14087
+ entry.openSpans.clear();
14088
+ }
14089
+ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiSDK, childTracingOptions = {}) {
12657
14090
  const cleanup = [];
12658
- const patchedModels = /* @__PURE__ */ new WeakSet();
14091
+ const patchedModels = /* @__PURE__ */ new WeakMap();
12659
14092
  const patchedTools = /* @__PURE__ */ new WeakSet();
12660
14093
  let modelWrapped = false;
12661
14094
  const patchModel = (model) => {
12662
14095
  const resolvedModel = resolveAISDKModel(model, aiSDK);
12663
- if (!resolvedModel || typeof resolvedModel !== "object" || typeof resolvedModel.doGenerate !== "function" || patchedModels.has(resolvedModel) || resolvedModel[AUTO_PATCHED_MODEL]) {
14096
+ if (!resolvedModel || typeof resolvedModel !== "object" || typeof resolvedModel.doGenerate !== "function") {
12664
14097
  return resolvedModel;
12665
14098
  }
12666
- patchedModels.add(resolvedModel);
12667
- resolvedModel[AUTO_PATCHED_MODEL] = true;
14099
+ const existingWrappedModel = patchedModels.get(resolvedModel);
14100
+ if (existingWrappedModel) {
14101
+ modelWrapped = true;
14102
+ return existingWrappedModel;
14103
+ }
12668
14104
  modelWrapped = true;
14105
+ const modelRecord = resolvedModel;
14106
+ const entry = {
14107
+ activeSpanIds: /* @__PURE__ */ new Set([parentSpan.spanId]),
14108
+ baseMetadata: buildAISDKChildMetadata(resolvedModel),
14109
+ childTracingOptions,
14110
+ denyOutputPaths,
14111
+ openSpans: /* @__PURE__ */ new Set(),
14112
+ parentSpan
14113
+ };
14114
+ const cleanupModelEntry = (state2, patchedModel) => {
14115
+ closeOpenAISDKModelPatchSpans(entry);
14116
+ const index = state2.entries.indexOf(entry);
14117
+ if (index >= 0) {
14118
+ state2.entries.splice(index, 1);
14119
+ }
14120
+ if (state2.entries.length > 0) {
14121
+ return;
14122
+ }
14123
+ patchedModel.doGenerate = state2.originalDoGenerate;
14124
+ patchedModel.doStream = state2.originalDoStream;
14125
+ delete patchedModel[AUTO_PATCHED_MODEL];
14126
+ };
14127
+ const existingState = modelRecord[AUTO_PATCHED_MODEL];
14128
+ if (existingState) {
14129
+ patchedModels.set(resolvedModel, resolvedModel);
14130
+ if (childTracingOptions.agentOwner && attachNestedAISDKChildPatchEntry(
14131
+ existingState.entries,
14132
+ parentSpan,
14133
+ cleanup
14134
+ )) {
14135
+ return resolvedModel;
14136
+ }
14137
+ if (!childTracingOptions.agentOwner) {
14138
+ shadowActiveAISDKChildPatchEntry(
14139
+ existingState.entries,
14140
+ entry,
14141
+ parentSpan,
14142
+ cleanup
14143
+ );
14144
+ }
14145
+ existingState.entries.push(entry);
14146
+ cleanup.push(() => {
14147
+ cleanupModelEntry(existingState, modelRecord);
14148
+ });
14149
+ return resolvedModel;
14150
+ }
12669
14151
  const originalDoGenerate = resolvedModel.doGenerate;
12670
14152
  const originalDoStream = resolvedModel.doStream;
12671
- const baseMetadata = buildAISDKChildMetadata(resolvedModel);
12672
- resolvedModel.doGenerate = async function doGeneratePatched(options) {
12673
- return parentSpan.traced(
14153
+ const wrappedModel = Object.create(
14154
+ Object.getPrototypeOf(resolvedModel)
14155
+ );
14156
+ Object.defineProperties(
14157
+ wrappedModel,
14158
+ Object.getOwnPropertyDescriptors(resolvedModel)
14159
+ );
14160
+ const wrappedModelRecord = wrappedModel;
14161
+ const state = {
14162
+ entries: [entry],
14163
+ originalDoGenerate,
14164
+ originalDoStream
14165
+ };
14166
+ Object.defineProperty(wrappedModel, AUTO_PATCHED_MODEL, {
14167
+ configurable: true,
14168
+ value: state
14169
+ });
14170
+ wrappedModel.doGenerate = async function doGeneratePatched(callOptions) {
14171
+ const activeEntry = activeAISDKChildPatchEntry(state.entries);
14172
+ if (!activeEntry) {
14173
+ return Reflect.apply(originalDoGenerate, resolvedModel, [callOptions]);
14174
+ }
14175
+ closeOpenAISDKModelPatchSpans(activeEntry);
14176
+ return activeEntry.parentSpan.traced(
12674
14177
  async (span) => {
12675
- const result = await Reflect.apply(
12676
- originalDoGenerate,
12677
- resolvedModel,
12678
- [options]
12679
- );
12680
- span.log({
12681
- output: processAISDKOutput(result, denyOutputPaths),
12682
- metrics: extractTokenMetrics(result),
12683
- ...buildResolvedMetadataPayload(result)
12684
- });
12685
- return result;
14178
+ activeEntry.openSpans.add(span);
14179
+ try {
14180
+ const result = await Reflect.apply(
14181
+ originalDoGenerate,
14182
+ resolvedModel,
14183
+ [callOptions]
14184
+ );
14185
+ const output = processAISDKOutput(
14186
+ result,
14187
+ activeEntry.denyOutputPaths
14188
+ );
14189
+ const metrics = extractTokenMetrics(result);
14190
+ const metadataPayload = buildResolvedMetadataPayload(result);
14191
+ const missingUsageMetadata = buildMissingUsageMetadata(
14192
+ output,
14193
+ metrics,
14194
+ "ai_sdk_result_missing_usage"
14195
+ );
14196
+ span.log({
14197
+ output,
14198
+ metrics,
14199
+ ...mergeMetadataPayload(metadataPayload, missingUsageMetadata)
14200
+ });
14201
+ return result;
14202
+ } finally {
14203
+ activeEntry.openSpans.delete(span);
14204
+ }
12686
14205
  },
12687
14206
  {
12688
14207
  name: "doGenerate",
12689
14208
  spanAttributes: {
12690
14209
  type: "llm" /* LLM */
12691
14210
  },
12692
- event: {
12693
- input: processAISDKCallInput(options).input,
12694
- metadata: baseMetadata
12695
- }
14211
+ event: buildAISDKModelStartEvent(
14212
+ callOptions,
14213
+ activeEntry.baseMetadata,
14214
+ {
14215
+ workflowAgent: activeEntry.childTracingOptions.workflowAgent
14216
+ }
14217
+ )
12696
14218
  }
12697
14219
  );
12698
14220
  };
12699
14221
  if (originalDoStream) {
12700
- resolvedModel.doStream = async function doStreamPatched(options) {
12701
- const span = parentSpan.startSpan({
14222
+ wrappedModel.doStream = async function doStreamPatched(callOptions) {
14223
+ const activeEntry = activeAISDKChildPatchEntry(state.entries);
14224
+ if (!activeEntry) {
14225
+ return Reflect.apply(originalDoStream, resolvedModel, [callOptions]);
14226
+ }
14227
+ closeOpenAISDKModelPatchSpans(activeEntry);
14228
+ const span = activeEntry.parentSpan.startSpan({
12702
14229
  name: "doStream",
12703
14230
  spanAttributes: {
12704
14231
  type: "llm" /* LLM */
12705
14232
  },
12706
- event: {
12707
- input: processAISDKCallInput(options).input,
12708
- metadata: baseMetadata
12709
- }
14233
+ event: buildAISDKModelStartEvent(
14234
+ callOptions,
14235
+ activeEntry.baseMetadata,
14236
+ {
14237
+ workflowAgent: activeEntry.childTracingOptions.workflowAgent
14238
+ }
14239
+ )
12710
14240
  });
14241
+ activeEntry.openSpans.add(span);
12711
14242
  const streamStartTime = getCurrentUnixTimestamp();
12712
14243
  const result = await withCurrent(
12713
14244
  span,
12714
- () => Reflect.apply(originalDoStream, resolvedModel, [options])
14245
+ () => Reflect.apply(originalDoStream, resolvedModel, [callOptions])
12715
14246
  );
12716
14247
  let firstChunkTime;
12717
14248
  const output = {};
@@ -12719,6 +14250,44 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
12719
14250
  let reasoning = "";
12720
14251
  const toolCalls = [];
12721
14252
  let object = void 0;
14253
+ let streamSpanEnded = false;
14254
+ const logAndEndStreamSpan = (usageUnavailableReason) => {
14255
+ if (streamSpanEnded) {
14256
+ return;
14257
+ }
14258
+ output.text = text;
14259
+ output.reasoning = reasoning;
14260
+ output.toolCalls = toolCalls;
14261
+ if (object !== void 0) {
14262
+ output.object = object;
14263
+ }
14264
+ const metrics = extractTokenMetrics(output);
14265
+ if (firstChunkTime !== void 0 && !activeEntry.childTracingOptions.workflowAgent) {
14266
+ metrics.time_to_first_token = Math.max(
14267
+ firstChunkTime - streamStartTime,
14268
+ 1e-6
14269
+ );
14270
+ }
14271
+ const metadataPayload = buildResolvedMetadataPayload(
14272
+ output
14273
+ );
14274
+ const missingUsageMetadata = usageUnavailableReason ? { usage_unavailable_reason: usageUnavailableReason } : buildMissingUsageMetadata(
14275
+ output,
14276
+ metrics,
14277
+ "ai_sdk_result_missing_usage"
14278
+ );
14279
+ span.log({
14280
+ output: processAISDKOutput(
14281
+ output,
14282
+ activeEntry.denyOutputPaths
14283
+ ),
14284
+ metrics,
14285
+ ...mergeMetadataPayload(metadataPayload, missingUsageMetadata)
14286
+ });
14287
+ activeEntry.openSpans.delete(span);
14288
+ span.end();
14289
+ streamSpanEnded = true;
14290
+ };
12722
14291
  const transformStream = new TransformStream({
12723
14292
  transform(chunk, controller) {
12724
14293
  if (firstChunkTime === void 0 && isAISDKContentStreamChunk(chunk)) {
@@ -12756,33 +14325,15 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
12756
14325
  }
12757
14326
  break;
12758
14327
  case "finish":
12759
- output.text = text;
12760
- output.reasoning = reasoning;
12761
- output.toolCalls = toolCalls;
12762
14328
  output.finishReason = chunk.finishReason;
12763
14329
  output.usage = chunk.usage;
12764
- if (object !== void 0) {
12765
- output.object = object;
12766
- }
12767
- const metrics = extractTokenMetrics(output);
12768
- if (firstChunkTime !== void 0) {
12769
- metrics.time_to_first_token = Math.max(
12770
- firstChunkTime - streamStartTime,
12771
- 1e-6
12772
- );
12773
- }
12774
- span.log({
12775
- output: processAISDKOutput(
12776
- output,
12777
- denyOutputPaths
12778
- ),
12779
- metrics,
12780
- ...buildResolvedMetadataPayload(output)
12781
- });
12782
- span.end();
14330
+ logAndEndStreamSpan();
12783
14331
  break;
12784
14332
  }
12785
14333
  controller.enqueue(chunk);
14334
+ },
14335
+ flush() {
14336
+ logAndEndStreamSpan("ai_sdk_stream_finished_without_usage");
12786
14337
  }
12787
14338
  });
12788
14339
  return {
@@ -12792,32 +14343,79 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
12792
14343
  };
12793
14344
  }
12794
14345
  cleanup.push(() => {
12795
- resolvedModel.doGenerate = originalDoGenerate;
12796
- if (originalDoStream) {
12797
- resolvedModel.doStream = originalDoStream;
12798
- }
12799
- delete resolvedModel[AUTO_PATCHED_MODEL];
14346
+ cleanupModelEntry(state, wrappedModelRecord);
12800
14347
  });
12801
- return resolvedModel;
14348
+ patchedModels.set(resolvedModel, wrappedModel);
14349
+ patchedModels.set(wrappedModel, wrappedModel);
14350
+ return wrappedModel;
12802
14351
  };
12803
14352
  const patchTool = (tool, name) => {
12804
- if (tool == null || typeof tool !== "object" || !("execute" in tool) || typeof tool.execute !== "function" || patchedTools.has(tool) || tool[AUTO_PATCHED_TOOL]) {
14353
+ if (tool == null || typeof tool !== "object" || !("execute" in tool) || typeof tool.execute !== "function" || patchedTools.has(tool)) {
12805
14354
  return;
12806
14355
  }
12807
14356
  patchedTools.add(tool);
12808
- tool[AUTO_PATCHED_TOOL] = true;
12809
- const originalExecute = tool.execute;
14357
+ const toolRecord = tool;
14358
+ const entry = {
14359
+ activeSpanIds: /* @__PURE__ */ new Set([parentSpan.spanId]),
14360
+ childTracingOptions,
14361
+ name,
14362
+ parentSpan
14363
+ };
14364
+ const cleanupToolEntry = (state2) => {
14365
+ const index = state2.entries.indexOf(entry);
14366
+ if (index >= 0) {
14367
+ state2.entries.splice(index, 1);
14368
+ }
14369
+ if (state2.entries.length > 0) {
14370
+ return;
14371
+ }
14372
+ tool.execute = state2.originalExecute;
14373
+ delete toolRecord[AUTO_PATCHED_TOOL];
14374
+ };
14375
+ const existingState = toolRecord[AUTO_PATCHED_TOOL];
14376
+ if (existingState) {
14377
+ if (childTracingOptions.agentOwner && attachNestedAISDKChildPatchEntry(
14378
+ existingState.entries,
14379
+ parentSpan,
14380
+ cleanup
14381
+ )) {
14382
+ return;
14383
+ }
14384
+ if (!childTracingOptions.agentOwner) {
14385
+ shadowActiveAISDKChildPatchEntry(
14386
+ existingState.entries,
14387
+ entry,
14388
+ parentSpan,
14389
+ cleanup
14390
+ );
14391
+ }
14392
+ existingState.entries.push(entry);
14393
+ cleanup.push(() => {
14394
+ cleanupToolEntry(existingState);
14395
+ });
14396
+ return;
14397
+ }
14398
+ const originalExecute = toolRecord.execute;
14399
+ const state = {
14400
+ entries: [entry],
14401
+ originalExecute
14402
+ };
14403
+ toolRecord[AUTO_PATCHED_TOOL] = state;
12810
14404
  tool.execute = function executePatched(...args) {
14405
+ const activeEntry = activeAISDKChildPatchEntry(state.entries);
12811
14406
  const result = Reflect.apply(originalExecute, this, args);
14407
+ if (!activeEntry) {
14408
+ return result;
14409
+ }
12812
14410
  if (isAsyncGenerator(result)) {
12813
14411
  return (async function* () {
12814
- const span = parentSpan.startSpan({
12815
- name,
14412
+ const span = activeEntry.parentSpan.startSpan({
14413
+ name: activeEntry.name,
12816
14414
  spanAttributes: {
12817
14415
  type: "tool" /* TOOL */
12818
14416
  }
12819
14417
  });
12820
- span.log({ input: args.length === 1 ? args[0] : args });
14418
+ span.log({ input: serializeToolExecutionInput(args) });
12821
14419
  try {
12822
14420
  let lastValue;
12823
14421
  for await (const value of result) {
@@ -12833,15 +14431,15 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
12833
14431
  }
12834
14432
  })();
12835
14433
  }
12836
- return parentSpan.traced(
14434
+ return activeEntry.parentSpan.traced(
12837
14435
  async (span) => {
12838
- span.log({ input: args.length === 1 ? args[0] : args });
14436
+ span.log({ input: serializeToolExecutionInput(args) });
12839
14437
  const awaitedResult = await result;
12840
14438
  span.log({ output: awaitedResult });
12841
14439
  return awaitedResult;
12842
14440
  },
12843
14441
  {
12844
- name,
14442
+ name: activeEntry.name,
12845
14443
  spanAttributes: {
12846
14444
  type: "tool" /* TOOL */
12847
14445
  }
@@ -12849,8 +14447,7 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
12849
14447
  );
12850
14448
  };
12851
14449
  cleanup.push(() => {
12852
- tool.execute = originalExecute;
12853
- delete tool[AUTO_PATCHED_TOOL];
14450
+ cleanupToolEntry(state);
12854
14451
  });
12855
14452
  };
12856
14453
  const patchTools = (tools) => {
@@ -12869,25 +14466,42 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
12869
14466
  }
12870
14467
  };
12871
14468
  if (params && typeof params === "object") {
12872
- const patchedParamModel = patchModel(params.model);
12873
- if (typeof params.model === "string" && patchedParamModel && typeof patchedParamModel === "object") {
14469
+ const originalParamModel = params.model;
14470
+ const patchedParamModel = patchModel(originalParamModel);
14471
+ if (patchedParamModel && patchedParamModel !== originalParamModel) {
12874
14472
  params.model = patchedParamModel;
14473
+ cleanup.push(() => {
14474
+ params.model = originalParamModel;
14475
+ });
12875
14476
  }
12876
14477
  patchTools(params.tools);
12877
14478
  }
12878
14479
  if (self && typeof self === "object") {
12879
14480
  const selfRecord = self;
12880
14481
  if (selfRecord.model !== void 0) {
12881
- const patchedSelfModel = patchModel(selfRecord.model);
12882
- if (typeof selfRecord.model === "string" && patchedSelfModel && typeof patchedSelfModel === "object") {
14482
+ const originalSelfModel = selfRecord.model;
14483
+ const patchedSelfModel = patchModel(originalSelfModel);
14484
+ if (patchedSelfModel && patchedSelfModel !== originalSelfModel) {
12883
14485
  selfRecord.model = patchedSelfModel;
14486
+ cleanup.push(() => {
14487
+ selfRecord.model = originalSelfModel;
14488
+ });
12884
14489
  }
12885
14490
  }
14491
+ if (selfRecord.tools !== void 0) {
14492
+ patchTools(selfRecord.tools);
14493
+ }
12886
14494
  if (selfRecord.settings && typeof selfRecord.settings === "object") {
12887
14495
  if (selfRecord.settings.model !== void 0) {
12888
- const patchedSettingsModel = patchModel(selfRecord.settings.model);
12889
- if (typeof selfRecord.settings.model === "string" && patchedSettingsModel && typeof patchedSettingsModel === "object") {
14496
+ const originalSettingsModel = selfRecord.settings.model;
14497
+ const patchedSettingsModel = patchModel(originalSettingsModel);
14498
+ if (patchedSettingsModel && patchedSettingsModel !== originalSettingsModel) {
12890
14499
  selfRecord.settings.model = patchedSettingsModel;
14500
+ cleanup.push(() => {
14501
+ if (selfRecord.settings) {
14502
+ selfRecord.settings.model = originalSettingsModel;
14503
+ }
14504
+ });
12891
14505
  }
12892
14506
  }
12893
14507
  if (selfRecord.settings.tools !== void 0) {
@@ -12984,99 +14598,190 @@ function isAISDKContentAsyncIterableChunk(chunk) {
12984
14598
  return isObject(part) && typeof part.type !== "string";
12985
14599
  }
12986
14600
  function patchAISDKStreamingResult(args) {
12987
- const { defaultDenyOutputPaths, endEvent, result, span, startTime } = args;
14601
+ const {
14602
+ defaultDenyOutputPaths,
14603
+ endEvent,
14604
+ onComplete,
14605
+ result,
14606
+ span,
14607
+ startTime
14608
+ } = args;
12988
14609
  if (!result || typeof result !== "object") {
12989
14610
  return false;
12990
14611
  }
12991
14612
  const resultRecord = result;
12992
14613
  attachKnownResultPromiseHandlers(resultRecord);
14614
+ let finalized = false;
14615
+ const finalize = () => {
14616
+ if (finalized) {
14617
+ return;
14618
+ }
14619
+ finalized = true;
14620
+ finalizeAISDKChildTracing(endEvent);
14621
+ span.end();
14622
+ onComplete?.();
14623
+ };
14624
+ let outputLogged = false;
14625
+ const logStreamingOutput = async (firstChunkTime) => {
14626
+ if (outputLogged) {
14627
+ return;
14628
+ }
14629
+ outputLogged = true;
14630
+ try {
14631
+ const metrics = extractTopLevelAISDKMetrics(result, endEvent);
14632
+ if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
14633
+ metrics.time_to_first_token = firstChunkTime - startTime;
14634
+ }
14635
+ const output = await processAISDKStreamingOutput(
14636
+ result,
14637
+ resolveDenyOutputPaths(endEvent, defaultDenyOutputPaths)
14638
+ );
14639
+ const metadata = buildResolvedMetadataPayload(result).metadata;
14640
+ span.log({
14641
+ output,
14642
+ ...metadata ? { metadata } : {},
14643
+ metrics
14644
+ });
14645
+ } catch (error) {
14646
+ span.log({ error: toLoggedError(error) });
14647
+ } finally {
14648
+ finalize();
14649
+ }
14650
+ };
14651
+ const createAsyncIterableHooks = () => {
14652
+ let firstChunkTime;
14653
+ return {
14654
+ onChunk: (chunk) => {
14655
+ if (firstChunkTime === void 0 && isAISDKContentAsyncIterableChunk(chunk)) {
14656
+ firstChunkTime = getCurrentUnixTimestamp();
14657
+ }
14658
+ },
14659
+ onComplete: async () => {
14660
+ await logStreamingOutput(firstChunkTime);
14661
+ },
14662
+ onError: (error) => {
14663
+ if (!outputLogged) {
14664
+ outputLogged = true;
14665
+ span.log({
14666
+ error: error.message
14667
+ });
14668
+ }
14669
+ finalize();
14670
+ },
14671
+ onCancel: finalize
14672
+ };
14673
+ };
14674
+ const patchAsyncIterable = (stream) => isReadableStreamLike(stream) ? createPatchedReadableStream(stream, createAsyncIterableHooks()) : createPatchedAsyncIterable(stream, createAsyncIterableHooks());
14675
+ const patchAsyncIterableField = (field) => {
14676
+ let descriptorOwner = resultRecord;
14677
+ let descriptor;
14678
+ while (descriptorOwner) {
14679
+ descriptor = Object.getOwnPropertyDescriptor(descriptorOwner, field);
14680
+ if (descriptor) {
14681
+ break;
14682
+ }
14683
+ descriptorOwner = Object.getPrototypeOf(descriptorOwner);
14684
+ }
14685
+ if (!descriptor || descriptorOwner === resultRecord && !descriptor.configurable) {
14686
+ return false;
14687
+ }
14688
+ if ("value" in descriptor) {
14689
+ if (!isAsyncIterable(descriptor.value)) {
14690
+ return false;
14691
+ }
14692
+ try {
14693
+ Object.defineProperty(resultRecord, field, {
14694
+ configurable: descriptorOwner === resultRecord ? descriptor.configurable : true,
14695
+ enumerable: descriptor.enumerable,
14696
+ value: patchAsyncIterable(descriptor.value),
14697
+ writable: descriptor.writable
14698
+ });
14699
+ return true;
14700
+ } catch {
14701
+ return false;
14702
+ }
14703
+ }
14704
+ if (typeof descriptor.get !== "function") {
14705
+ return false;
14706
+ }
14707
+ const originalGet = descriptor.get;
14708
+ const originalSet = descriptor.set;
14709
+ try {
14710
+ Object.defineProperty(resultRecord, field, {
14711
+ configurable: descriptorOwner === resultRecord ? descriptor.configurable : true,
14712
+ enumerable: descriptor.enumerable,
14713
+ get() {
14714
+ const stream = originalGet.call(this);
14715
+ return isAsyncIterable(stream) ? patchAsyncIterable(stream) : stream;
14716
+ },
14717
+ ...originalSet ? {
14718
+ set(value) {
14719
+ originalSet.call(this, value);
14720
+ }
14721
+ } : {}
14722
+ });
14723
+ return true;
14724
+ } catch {
14725
+ return false;
14726
+ }
14727
+ };
14728
+ let patched = false;
12993
14729
  if (isReadableStreamLike(resultRecord.baseStream)) {
12994
- let firstChunkTime2;
12995
- const wrappedBaseStream = resultRecord.baseStream.pipeThrough(
14730
+ let firstChunkTime;
14731
+ const transformedBaseStream = resultRecord.baseStream.pipeThrough(
12996
14732
  new TransformStream({
12997
14733
  transform(chunk, controller) {
12998
- if (firstChunkTime2 === void 0 && isAISDKContentStreamChunk(chunk)) {
12999
- firstChunkTime2 = getCurrentUnixTimestamp();
14734
+ if (firstChunkTime === void 0 && isAISDKContentStreamChunk(chunk)) {
14735
+ firstChunkTime = getCurrentUnixTimestamp();
13000
14736
  }
13001
14737
  controller.enqueue(chunk);
13002
14738
  },
13003
14739
  async flush() {
13004
- const metrics = extractTopLevelAISDKMetrics(result, endEvent);
13005
- if (metrics.time_to_first_token === void 0 && firstChunkTime2 !== void 0) {
13006
- metrics.time_to_first_token = firstChunkTime2 - startTime;
13007
- }
13008
- const output = await processAISDKStreamingOutput(
13009
- result,
13010
- resolveDenyOutputPaths(endEvent, defaultDenyOutputPaths)
13011
- );
13012
- const metadata = buildResolvedMetadataPayload(result).metadata;
13013
- span.log({
13014
- output,
13015
- ...metadata ? { metadata } : {},
13016
- metrics
13017
- });
13018
- finalizeAISDKChildTracing(endEvent);
13019
- span.end();
14740
+ await logStreamingOutput(firstChunkTime);
13020
14741
  }
13021
14742
  })
13022
14743
  );
14744
+ const reader = transformedBaseStream.getReader();
14745
+ const wrappedBaseStream = new ReadableStream({
14746
+ async pull(controller) {
14747
+ try {
14748
+ const { done, value } = await reader.read();
14749
+ if (done) {
14750
+ controller.close();
14751
+ return;
14752
+ }
14753
+ controller.enqueue(value);
14754
+ } catch (error) {
14755
+ span.log({ error: toLoggedError(error) });
14756
+ finalize();
14757
+ controller.error(error);
14758
+ }
14759
+ },
14760
+ async cancel(reason) {
14761
+ try {
14762
+ finalize();
14763
+ } finally {
14764
+ await reader.cancel(reason);
14765
+ }
14766
+ }
14767
+ });
13023
14768
  Object.defineProperty(resultRecord, "baseStream", {
13024
14769
  configurable: true,
13025
14770
  enumerable: true,
13026
14771
  value: wrappedBaseStream,
13027
14772
  writable: true
13028
14773
  });
13029
- return true;
14774
+ patched = true;
13030
14775
  }
13031
- const streamField = findAsyncIterableField(resultRecord, [
14776
+ for (const field of [
13032
14777
  "partialObjectStream",
13033
14778
  "textStream",
13034
14779
  "fullStream",
13035
14780
  "stream"
13036
- ]);
13037
- if (!streamField) {
13038
- return false;
14781
+ ]) {
14782
+ patched = patchAsyncIterableField(field) || patched;
13039
14783
  }
13040
- let firstChunkTime;
13041
- const wrappedStream = createPatchedAsyncIterable(streamField.stream, {
13042
- onChunk: (chunk) => {
13043
- if (firstChunkTime === void 0 && isAISDKContentAsyncIterableChunk(chunk)) {
13044
- firstChunkTime = getCurrentUnixTimestamp();
13045
- }
13046
- },
13047
- onComplete: async () => {
13048
- const metrics = extractTopLevelAISDKMetrics(result, endEvent);
13049
- if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
13050
- metrics.time_to_first_token = firstChunkTime - startTime;
13051
- }
13052
- const output = await processAISDKStreamingOutput(
13053
- result,
13054
- resolveDenyOutputPaths(endEvent, defaultDenyOutputPaths)
13055
- );
13056
- const metadata = buildResolvedMetadataPayload(result).metadata;
13057
- span.log({
13058
- output,
13059
- ...metadata ? { metadata } : {},
13060
- metrics
13061
- });
13062
- finalizeAISDKChildTracing(endEvent);
13063
- span.end();
13064
- },
13065
- onError: (error) => {
13066
- span.log({
13067
- error: error.message
13068
- });
13069
- finalizeAISDKChildTracing(endEvent);
13070
- span.end();
13071
- }
13072
- });
13073
- Object.defineProperty(resultRecord, streamField.field, {
13074
- configurable: true,
13075
- enumerable: true,
13076
- value: wrappedStream,
13077
- writable: true
13078
- });
13079
- return true;
14784
+ return patched;
13080
14785
  }
13081
14786
  function attachKnownResultPromiseHandlers(result) {
13082
14787
  const promiseLikeFields = [
@@ -13108,34 +14813,72 @@ function attachKnownResultPromiseHandlers(result) {
13108
14813
  }
13109
14814
  }
13110
14815
  function isReadableStreamLike(value) {
13111
- return value != null && typeof value === "object" && typeof value.pipeThrough === "function";
13112
- }
13113
- function findAsyncIterableField(result, candidateFields) {
13114
- for (const field of candidateFields) {
13115
- try {
13116
- const stream = result[field];
13117
- if (isAsyncIterable(stream)) {
13118
- return { field, stream };
14816
+ return value != null && typeof value === "object" && typeof value.getReader === "function" && typeof value.pipeThrough === "function";
14817
+ }
14818
+ function createPatchedReadableStream(stream, hooks) {
14819
+ let reader;
14820
+ let completed = false;
14821
+ return new ReadableStream({
14822
+ async pull(controller) {
14823
+ reader ??= stream.getReader();
14824
+ try {
14825
+ const { done, value } = await reader.read();
14826
+ if (done) {
14827
+ completed = true;
14828
+ await hooks.onComplete();
14829
+ controller.close();
14830
+ return;
14831
+ }
14832
+ hooks.onChunk(value);
14833
+ controller.enqueue(value);
14834
+ } catch (error) {
14835
+ completed = true;
14836
+ hooks.onError(
14837
+ error instanceof Error ? error : new Error(String(error))
14838
+ );
14839
+ controller.error(error);
14840
+ }
14841
+ },
14842
+ async cancel(reason) {
14843
+ if (!completed) {
14844
+ completed = true;
14845
+ try {
14846
+ await hooks.onCancel?.();
14847
+ } catch {
14848
+ }
14849
+ }
14850
+ if (reader) {
14851
+ await reader.cancel(reason);
14852
+ } else if (stream.cancel) {
14853
+ await stream.cancel(reason);
13119
14854
  }
13120
- } catch {
13121
14855
  }
13122
- }
13123
- return null;
14856
+ });
13124
14857
  }
13125
14858
  function createPatchedAsyncIterable(stream, hooks) {
13126
14859
  return {
13127
14860
  async *[Symbol.asyncIterator]() {
14861
+ let completed = false;
13128
14862
  try {
13129
14863
  for await (const chunk of stream) {
13130
14864
  hooks.onChunk(chunk);
13131
14865
  yield chunk;
13132
14866
  }
14867
+ completed = true;
13133
14868
  await hooks.onComplete();
13134
14869
  } catch (error) {
14870
+ completed = true;
13135
14871
  hooks.onError(
13136
14872
  error instanceof Error ? error : new Error(String(error))
13137
14873
  );
13138
14874
  throw error;
14875
+ } finally {
14876
+ if (!completed) {
14877
+ try {
14878
+ await hooks.onCancel?.();
14879
+ } catch {
14880
+ }
14881
+ }
13139
14882
  }
13140
14883
  }
13141
14884
  };
@@ -13210,6 +14953,40 @@ function buildResolvedMetadataPayload(result) {
13210
14953
  }
13211
14954
  return Object.keys(metadata).length > 0 ? { metadata } : {};
13212
14955
  }
14956
+ function mergeMetadataPayload(metadataPayload, extraMetadata) {
14957
+ if (!extraMetadata || Object.keys(extraMetadata).length === 0) {
14958
+ return metadataPayload;
14959
+ }
14960
+ return {
14961
+ metadata: {
14962
+ ...metadataPayload.metadata ?? {},
14963
+ ...extraMetadata
14964
+ }
14965
+ };
14966
+ }
14967
+ function buildMissingUsageMetadata(output, metrics, reason) {
14968
+ if (!hasLoggedOutput(output) || hasTokenUsageMetrics(metrics)) {
14969
+ return void 0;
14970
+ }
14971
+ return { usage_unavailable_reason: reason };
14972
+ }
14973
+ function hasLoggedOutput(output) {
14974
+ if (output === null || output === void 0) {
14975
+ return false;
14976
+ }
14977
+ if (Array.isArray(output)) {
14978
+ return output.length > 0;
14979
+ }
14980
+ if (typeof output === "object") {
14981
+ return Object.keys(output).length > 0;
14982
+ }
14983
+ return true;
14984
+ }
14985
+ function hasTokenUsageMetrics(metrics) {
14986
+ return Object.keys(metrics).some(
14987
+ (key) => key !== "estimated_cost" && key !== "time_to_first_token"
14988
+ );
14989
+ }
13213
14990
  function resolveAISDKModel(model, aiSDK) {
13214
14991
  if (typeof model !== "string") {
13215
14992
  return model;
@@ -13233,7 +15010,45 @@ function isAsyncGenerator(value) {
13233
15010
  function processAISDKOutput(output, denyOutputPaths) {
13234
15011
  if (!output) return output;
13235
15012
  const merged = extractSerializableOutputFields(output);
13236
- return normalizeAISDKLoggedOutput(omit(merged, denyOutputPaths));
15013
+ const deleteOutputPaths = denyOutputPaths.filter(
15014
+ (path) => path.toLowerCase().endsWith("headers")
15015
+ );
15016
+ const sanitized = omit(merged, denyOutputPaths, deleteOutputPaths);
15017
+ for (const path of TRANSPORT_PAYLOAD_ROOT_PATHS) {
15018
+ const stack = [{ obj: sanitized, keys: parsePath(path) }];
15019
+ while (stack.length > 0) {
15020
+ const entry = stack.pop();
15021
+ if (!entry || entry.keys.length === 0) {
15022
+ continue;
15023
+ }
15024
+ const firstKey = entry.keys[0];
15025
+ const remainingKeys = entry.keys.slice(1);
15026
+ if (firstKey === "[]") {
15027
+ if (Array.isArray(entry.obj)) {
15028
+ for (const item of entry.obj) {
15029
+ stack.push({
15030
+ obj: item,
15031
+ keys: remainingKeys
15032
+ });
15033
+ }
15034
+ }
15035
+ continue;
15036
+ }
15037
+ if (!entry.obj || typeof entry.obj !== "object" || !(firstKey in entry.obj)) {
15038
+ continue;
15039
+ }
15040
+ const record = entry.obj;
15041
+ if (remainingKeys.length === 0) {
15042
+ record[firstKey] = sanitizeAISDKMetadataValue(record[firstKey]);
15043
+ continue;
15044
+ }
15045
+ stack.push({
15046
+ obj: record[firstKey],
15047
+ keys: remainingKeys
15048
+ });
15049
+ }
15050
+ }
15051
+ return normalizeAISDKLoggedOutput(sanitized);
13237
15052
  }
13238
15053
  function processAISDKEmbeddingOutput(output, denyOutputPaths) {
13239
15054
  if (!output || typeof output !== "object") {
@@ -13324,6 +15139,8 @@ function extractTokenMetrics(result) {
13324
15139
  );
13325
15140
  if (totalTokens !== void 0) {
13326
15141
  metrics.tokens = totalTokens;
15142
+ } else if (promptTokens !== void 0 && completionTokens !== void 0) {
15143
+ metrics.tokens = promptTokens + completionTokens;
13327
15144
  }
13328
15145
  const promptCachedTokens = firstNumber2(
13329
15146
  usage.inputTokens?.cacheRead,
@@ -13447,7 +15264,9 @@ function extractGetterValues(obj) {
13447
15264
  const getterValues = {};
13448
15265
  const getterNames = [
13449
15266
  "content",
15267
+ "messages",
13450
15268
  "text",
15269
+ "output",
13451
15270
  "object",
13452
15271
  "value",
13453
15272
  "values",
@@ -13487,7 +15306,9 @@ function extractGetterValues(obj) {
13487
15306
  function extractSerializableOutputFields(output) {
13488
15307
  const serialized = {};
13489
15308
  const directFieldNames = [
15309
+ "messages",
13490
15310
  "steps",
15311
+ "output",
13491
15312
  "request",
13492
15313
  "responseMessages",
13493
15314
  "warnings",
@@ -13669,7 +15490,7 @@ function parsePath(path) {
13669
15490
  }
13670
15491
  return keys;
13671
15492
  }
13672
- function omitAtPath(obj, keys) {
15493
+ function omitAtPath(obj, keys, deleteLeaf = false) {
13673
15494
  if (keys.length === 0) return;
13674
15495
  const firstKey = keys[0];
13675
15496
  const remainingKeys = keys.slice(1);
@@ -13679,29 +15500,36 @@ function omitAtPath(obj, keys) {
13679
15500
  if (remainingKeys.length > 0) {
13680
15501
  omitAtPath(
13681
15502
  item,
13682
- remainingKeys
15503
+ remainingKeys,
15504
+ deleteLeaf
13683
15505
  );
13684
15506
  }
13685
15507
  });
13686
15508
  }
13687
15509
  } else if (remainingKeys.length === 0) {
13688
15510
  if (obj && typeof obj === "object" && firstKey in obj) {
13689
- obj[firstKey] = "<omitted>";
15511
+ if (deleteLeaf) {
15512
+ delete obj[firstKey];
15513
+ } else {
15514
+ obj[firstKey] = "<omitted>";
15515
+ }
13690
15516
  }
13691
15517
  } else {
13692
15518
  if (obj && typeof obj === "object" && firstKey in obj) {
13693
15519
  omitAtPath(
13694
15520
  obj[firstKey],
13695
- remainingKeys
15521
+ remainingKeys,
15522
+ deleteLeaf
13696
15523
  );
13697
15524
  }
13698
15525
  }
13699
15526
  }
13700
- function omit(obj, paths) {
15527
+ function omit(obj, paths, deletePaths = []) {
13701
15528
  const result = deepCopy(obj);
15529
+ const deletePathSet = new Set(deletePaths);
13702
15530
  for (const path of paths) {
13703
15531
  const keys = parsePath(path);
13704
- omitAtPath(result, keys);
15532
+ omitAtPath(result, keys, deletePathSet.has(path));
13705
15533
  }
13706
15534
  return result;
13707
15535
  }
@@ -23750,15 +25578,18 @@ function observeFlue(event, ctx) {
23750
25578
  getObserveBridge().handle(event, ctx);
23751
25579
  }
23752
25580
  var interceptFlueExecution = (operation, ctx, next) => getObserveBridge().intercept(operation, ctx, next);
23753
- var braintrustFlueObserver = Object.assign(
23754
- observeFlue,
23755
- {
25581
+ function braintrustFlueInstrumentation() {
25582
+ return {
23756
25583
  dispose() {
23757
25584
  },
23758
25585
  interceptor: interceptFlueExecution,
23759
25586
  key: FLUE_INSTRUMENTATION_KEY,
23760
25587
  observe: observeFlue
23761
- }
25588
+ };
25589
+ }
25590
+ var braintrustFlueObserver = Object.assign(
25591
+ observeFlue,
25592
+ braintrustFlueInstrumentation()
23762
25593
  );
23763
25594
  var FluePlugin = class extends BasePlugin {
23764
25595
  onEnable() {
@@ -27314,6 +29145,7 @@ export {
27314
29145
  BasePlugin,
27315
29146
  BraintrustPlugin,
27316
29147
  OpenAIAgentsTraceProcessor,
29148
+ braintrustFlueInstrumentation,
27317
29149
  braintrustFlueObserver,
27318
29150
  configureInstrumentation,
27319
29151
  createChannelName,