braintrust 3.20.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 +2826 -983
  6. package/dev/dist/index.mjs +2286 -443
  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 +1357 -847
  49. package/dist/browser.d.ts +1357 -847
  50. package/dist/browser.js +2726 -469
  51. package/dist/browser.mjs +2726 -469
  52. package/dist/{chunk-LPC4W2WX.js → chunk-BFGIH2ZJ.js} +4 -0
  53. package/dist/{chunk-POCCIJAL.js → chunk-FY7DAKA5.js} +3141 -1269
  54. package/dist/{chunk-Y7W7WP6H.mjs → chunk-KMGUTPB7.mjs} +4 -0
  55. package/dist/{chunk-F73OMF66.mjs → chunk-O2P765XK.mjs} +2391 -519
  56. package/dist/cli.js +2260 -408
  57. package/dist/edge-light.d.mts +1 -1
  58. package/dist/edge-light.d.ts +1 -1
  59. package/dist/edge-light.js +2726 -469
  60. package/dist/edge-light.mjs +2726 -469
  61. package/dist/index.d.mts +1837 -1327
  62. package/dist/index.d.ts +1837 -1327
  63. package/dist/index.js +752 -353
  64. package/dist/index.mjs +445 -46
  65. package/dist/instrumentation/index.d.mts +107 -19
  66. package/dist/instrumentation/index.d.ts +107 -19
  67. package/dist/instrumentation/index.js +2337 -509
  68. package/dist/instrumentation/index.mjs +2337 -509
  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 +2726 -469
  74. package/dist/workerd.mjs +2726 -469
  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
@@ -543,8 +543,291 @@ var UUIDGenerator = class extends IDGenerator {
543
543
  return true;
544
544
  }
545
545
  };
546
+ function generateHexId(bytes) {
547
+ let result = "";
548
+ for (let i = 0; i < bytes; i++) {
549
+ result += Math.floor(Math.random() * 256).toString(16).padStart(2, "0");
550
+ }
551
+ return result;
552
+ }
553
+ var OTELIDGenerator = class extends IDGenerator {
554
+ getSpanId() {
555
+ return generateHexId(8);
556
+ }
557
+ getTraceId() {
558
+ return generateHexId(16);
559
+ }
560
+ shareRootSpanId() {
561
+ return false;
562
+ }
563
+ };
564
+ function parseEnvBool(name) {
565
+ const raw = isomorph_default.getEnv(name);
566
+ if (raw === void 0 || raw === null) {
567
+ return false;
568
+ }
569
+ const normalized = raw.trim().toLowerCase();
570
+ return normalized === "true" || normalized === "1" || normalized === "yes" || normalized === "y" || normalized === "on";
571
+ }
572
+ var _warnedLegacyUuidConflict = false;
573
+ function resolveUseLegacyUuidIds() {
574
+ const legacy = parseEnvBool("BRAINTRUST_LEGACY_IDS");
575
+ if (parseEnvBool("BRAINTRUST_OTEL_COMPAT")) {
576
+ if (legacy && !_warnedLegacyUuidConflict) {
577
+ _warnedLegacyUuidConflict = true;
578
+ debugLogger.warn(
579
+ "BRAINTRUST_LEGACY_IDS is ignored because BRAINTRUST_OTEL_COMPAT requires OpenTelemetry-compatible hex span IDs. Using hex IDs."
580
+ );
581
+ }
582
+ return false;
583
+ }
584
+ return legacy;
585
+ }
546
586
  function getIdGenerator() {
547
- return globalThis.BRAINTRUST_ID_GENERATOR !== void 0 ? new globalThis.BRAINTRUST_ID_GENERATOR() : new UUIDGenerator();
587
+ if (globalThis.BRAINTRUST_ID_GENERATOR !== void 0) {
588
+ return new globalThis.BRAINTRUST_ID_GENERATOR();
589
+ }
590
+ return resolveUseLegacyUuidIds() ? new UUIDGenerator() : new OTELIDGenerator();
591
+ }
592
+
593
+ // src/propagation.ts
594
+ var TRACEPARENT_HEADER = "traceparent";
595
+ var TRACESTATE_HEADER = "tracestate";
596
+ var BAGGAGE_HEADER = "baggage";
597
+ var BRAINTRUST_PARENT_KEY = "braintrust.parent";
598
+ var DEFAULT_TRACE_FLAGS = "01";
599
+ var TRACEPARENT_RE = /^00-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/;
600
+ var ZERO_TRACE_ID = "0".repeat(32);
601
+ var ZERO_SPAN_ID = "0".repeat(16);
602
+ var MAX_BAGGAGE_LENGTH = 8192;
603
+ var MAX_BAGGAGE_MEMBERS = 64;
604
+ var _utf8Encoder = new TextEncoder();
605
+ function utf8ByteLength(value) {
606
+ return _utf8Encoder.encode(value).length;
607
+ }
608
+ function capBaggageToMemberBoundary(value) {
609
+ const totalBytes = utf8ByteLength(value);
610
+ const withinBytes = totalBytes <= MAX_BAGGAGE_LENGTH;
611
+ let commaCount = 0;
612
+ for (let i = 0; i < value.length; i++) {
613
+ if (value.charCodeAt(i) === 44) {
614
+ commaCount++;
615
+ }
616
+ }
617
+ const withinMembers = commaCount < MAX_BAGGAGE_MEMBERS;
618
+ if (withinBytes && withinMembers) {
619
+ return value;
620
+ }
621
+ const kept = [];
622
+ let length = 0;
623
+ for (const rawMember of value.split(",")) {
624
+ if (kept.length >= MAX_BAGGAGE_MEMBERS) {
625
+ break;
626
+ }
627
+ const cost = utf8ByteLength(rawMember) + (kept.length ? 1 : 0);
628
+ if (length + cost > MAX_BAGGAGE_LENGTH) {
629
+ break;
630
+ }
631
+ kept.push(rawMember);
632
+ length += cost;
633
+ }
634
+ if (!kept.length) {
635
+ return "";
636
+ }
637
+ return kept.join(",");
638
+ }
639
+ function isTraceContextHeaderTupleArray(value) {
640
+ return Array.isArray(value) && value.every(
641
+ (item) => Array.isArray(item) && typeof item[0] === "string" && typeof item[1] === "string"
642
+ );
643
+ }
644
+ function isListHeader(name) {
645
+ const lowered = name.toLowerCase();
646
+ return lowered === BAGGAGE_HEADER || lowered === TRACESTATE_HEADER;
647
+ }
648
+ function headerValueToString(value, name) {
649
+ if (value === void 0 || value === null) {
650
+ return void 0;
651
+ }
652
+ if (Array.isArray(value)) {
653
+ const stringValues = value.filter((item) => {
654
+ return typeof item === "string";
655
+ });
656
+ if (!stringValues.length) {
657
+ return void 0;
658
+ }
659
+ return isListHeader(name) ? stringValues.join(",") : stringValues[0];
660
+ }
661
+ return typeof value === "string" ? value : String(value);
662
+ }
663
+ function getHeader(headers, name) {
664
+ if (!headers) {
665
+ return void 0;
666
+ }
667
+ if (isTraceContextHeaderTupleArray(headers)) {
668
+ const lowered2 = name.toLowerCase();
669
+ const matches = headers.filter(([key]) => key.toLowerCase() === lowered2).map(([, value]) => value);
670
+ if (!matches.length) {
671
+ return void 0;
672
+ }
673
+ return headerValueToString(matches, name);
674
+ }
675
+ const getter = headers.get;
676
+ if (typeof getter === "function") {
677
+ try {
678
+ const value = headerValueToString(getter.call(headers, name), name);
679
+ if (value !== void 0) {
680
+ return value;
681
+ }
682
+ } catch {
683
+ }
684
+ }
685
+ const nodeGetter = headers.getHeader;
686
+ if (typeof nodeGetter === "function") {
687
+ try {
688
+ const value = headerValueToString(nodeGetter.call(headers, name), name);
689
+ if (value !== void 0) {
690
+ return value;
691
+ }
692
+ } catch {
693
+ }
694
+ }
695
+ const headerBag = headers;
696
+ const exact = headerValueToString(headerBag[name], name);
697
+ if (exact !== void 0) {
698
+ return exact;
699
+ }
700
+ const lowered = name.toLowerCase();
701
+ for (const key of Object.keys(headers)) {
702
+ if (key !== name && key.toLowerCase() === lowered) {
703
+ const value = headerValueToString(headerBag[key], name);
704
+ if (value !== void 0) {
705
+ return value;
706
+ }
707
+ }
708
+ }
709
+ return void 0;
710
+ }
711
+ function isHex(value, length) {
712
+ if (typeof value !== "string" || value.length !== length) {
713
+ return false;
714
+ }
715
+ for (let i = 0; i < value.length; i++) {
716
+ const c = value[i];
717
+ const isDigit = c >= "0" && c <= "9";
718
+ const isLowerHex = c >= "a" && c <= "f";
719
+ if (!isDigit && !isLowerHex) {
720
+ return false;
721
+ }
722
+ }
723
+ return true;
724
+ }
725
+ function parseTraceparent(value) {
726
+ if (!value || typeof value !== "string") {
727
+ return void 0;
728
+ }
729
+ const match = TRACEPARENT_RE.exec(value.trim());
730
+ if (!match) {
731
+ return void 0;
732
+ }
733
+ const traceId = match[1];
734
+ const spanId = match[2];
735
+ const traceFlags = match[3];
736
+ if (traceId === ZERO_TRACE_ID || spanId === ZERO_SPAN_ID) {
737
+ return void 0;
738
+ }
739
+ return { traceId, spanId, traceFlags };
740
+ }
741
+ function formatTraceparent(traceId, spanId, traceFlags = DEFAULT_TRACE_FLAGS) {
742
+ if (!isHex(traceId, 32) || traceId === ZERO_TRACE_ID) {
743
+ return void 0;
744
+ }
745
+ if (!isHex(spanId, 16) || spanId === ZERO_SPAN_ID) {
746
+ return void 0;
747
+ }
748
+ const flags = isHex(traceFlags, 2) ? traceFlags : DEFAULT_TRACE_FLAGS;
749
+ return `00-${traceId}-${spanId}-${flags}`;
750
+ }
751
+ function percentEncode(value) {
752
+ return encodeURIComponent(value);
753
+ }
754
+ function percentDecode(value) {
755
+ if (!value.includes("%")) {
756
+ return value;
757
+ }
758
+ try {
759
+ return decodeURIComponent(value);
760
+ } catch {
761
+ return value;
762
+ }
763
+ }
764
+ function parseBaggage(value) {
765
+ const result = {};
766
+ if (!value || typeof value !== "string") {
767
+ return result;
768
+ }
769
+ const bounded = capBaggageToMemberBoundary(value);
770
+ for (let member of bounded.split(",")) {
771
+ member = member.trim();
772
+ if (!member || !member.includes("=")) {
773
+ continue;
774
+ }
775
+ member = member.split(";", 1)[0];
776
+ const eq = member.indexOf("=");
777
+ const key = percentDecode(member.slice(0, eq).trim());
778
+ const val = member.slice(eq + 1).trim();
779
+ if (!key) {
780
+ continue;
781
+ }
782
+ result[key] = percentDecode(val);
783
+ }
784
+ return result;
785
+ }
786
+ function mergeBaggage(existing, braintrustParent) {
787
+ let btMember = void 0;
788
+ if (braintrustParent) {
789
+ const encodedKey = percentEncode(BRAINTRUST_PARENT_KEY);
790
+ const encodedVal = percentEncode(String(braintrustParent));
791
+ btMember = `${encodedKey}=${encodedVal}`;
792
+ if (utf8ByteLength(btMember) > MAX_BAGGAGE_LENGTH) {
793
+ btMember = void 0;
794
+ }
795
+ }
796
+ let byteBudget = MAX_BAGGAGE_LENGTH;
797
+ let memberBudget = MAX_BAGGAGE_MEMBERS;
798
+ if (btMember !== void 0) {
799
+ byteBudget -= utf8ByteLength(btMember) + 1;
800
+ memberBudget -= 1;
801
+ }
802
+ const relayed = [];
803
+ let length = 0;
804
+ if (existing && typeof existing === "string") {
805
+ for (const rawMember of existing.split(",")) {
806
+ const member = rawMember.trim();
807
+ if (!member || !member.includes("=")) {
808
+ continue;
809
+ }
810
+ const keyPart = member.split(";", 1)[0].split("=", 1)[0];
811
+ const key = percentDecode(keyPart.trim());
812
+ if (key === BRAINTRUST_PARENT_KEY) {
813
+ continue;
814
+ }
815
+ if (relayed.length >= memberBudget) {
816
+ break;
817
+ }
818
+ const cost = utf8ByteLength(member) + (relayed.length ? 1 : 0);
819
+ if (length + cost > byteBudget) {
820
+ break;
821
+ }
822
+ relayed.push(member);
823
+ length += cost;
824
+ }
825
+ }
826
+ const members = btMember !== void 0 ? [...relayed, btMember] : relayed;
827
+ if (!members.length) {
828
+ return void 0;
829
+ }
830
+ return members.join(",");
548
831
  }
549
832
 
550
833
  // util/db_fields.ts
@@ -1152,7 +1435,7 @@ var SpanComponentsV3 = class _SpanComponentsV3 {
1152
1435
  case 3 /* PLAYGROUND_LOGS */:
1153
1436
  return { prompt_session_id: this.data.object_id, log_id: "x" };
1154
1437
  default:
1155
- const _ = this.data.object_type;
1438
+ this.data.object_type;
1156
1439
  throw new Error("Impossible");
1157
1440
  }
1158
1441
  }
@@ -1594,7 +1877,7 @@ var SpanComponentsV4 = class _SpanComponentsV4 {
1594
1877
  case 3 /* PLAYGROUND_LOGS */:
1595
1878
  return { prompt_session_id: this.data.object_id, log_id: "x" };
1596
1879
  default:
1597
- const _ = this.data.object_type;
1880
+ this.data.object_type;
1598
1881
  throw new Error(`Invalid object_type ${this.data.object_type}`);
1599
1882
  }
1600
1883
  }
@@ -1727,7 +2010,8 @@ var AclObjectType = import_v36.z.union([
1727
2010
  "role",
1728
2011
  "org_member",
1729
2012
  "project_log",
1730
- "org_project"
2013
+ "org_project",
2014
+ "org_audit_logs"
1731
2015
  ]),
1732
2016
  import_v36.z.null()
1733
2017
  ]);
@@ -1753,6 +2037,17 @@ var Acl = import_v36.z.object({
1753
2037
  _object_org_id: import_v36.z.string().uuid(),
1754
2038
  created: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional()
1755
2039
  });
2040
+ var Agent = import_v36.z.object({
2041
+ id: import_v36.z.string().uuid(),
2042
+ project_id: import_v36.z.string().uuid(),
2043
+ user_id: import_v36.z.string().uuid(),
2044
+ created: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
2045
+ name: import_v36.z.string(),
2046
+ slug: import_v36.z.string(),
2047
+ kind: import_v36.z.string(),
2048
+ description: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
2049
+ metadata: import_v36.z.union([import_v36.z.object({}).partial().passthrough(), import_v36.z.null()]).optional()
2050
+ });
1756
2051
  var AISecret = import_v36.z.object({
1757
2052
  id: import_v36.z.string().uuid(),
1758
2053
  created: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
@@ -1899,6 +2194,7 @@ var AttachmentStatus = import_v36.z.object({
1899
2194
  upload_status: UploadStatus,
1900
2195
  error_message: import_v36.z.string().optional()
1901
2196
  });
2197
+ var AutomationStatus = import_v36.z.enum(["active", "paused"]);
1902
2198
  var FunctionTypeEnum = import_v36.z.enum([
1903
2199
  "llm",
1904
2200
  "scorer",
@@ -1944,7 +2240,9 @@ var TopicMapData = import_v36.z.object({
1944
2240
  topic_names: import_v36.z.record(import_v36.z.string()).optional(),
1945
2241
  generation_settings: TopicMapGenerationSettings.optional(),
1946
2242
  disable_reconciliation: import_v36.z.boolean().optional(),
1947
- distance_threshold: import_v36.z.number().optional()
2243
+ distance_threshold: import_v36.z.number().optional(),
2244
+ btql_filter: import_v36.z.string().optional(),
2245
+ automation_btql_filter: import_v36.z.string().optional()
1948
2246
  });
1949
2247
  var BatchedFacetData = import_v36.z.object({
1950
2248
  type: import_v36.z.literal("batched_facet"),
@@ -2227,7 +2525,7 @@ var DatasetEvent = import_v36.z.object({
2227
2525
  origin: ObjectReferenceNullish.optional(),
2228
2526
  comments: import_v36.z.union([import_v36.z.array(import_v36.z.unknown()), import_v36.z.null()]).optional(),
2229
2527
  audit_data: import_v36.z.union([import_v36.z.array(import_v36.z.unknown()), import_v36.z.null()]).optional(),
2230
- facets: import_v36.z.union([import_v36.z.object({}).partial().passthrough(), import_v36.z.null()]).optional(),
2528
+ facets: import_v36.z.union([import_v36.z.record(import_v36.z.union([import_v36.z.string(), import_v36.z.null()])), import_v36.z.null()]).optional(),
2231
2529
  classifications: import_v36.z.union([
2232
2530
  import_v36.z.record(
2233
2531
  import_v36.z.array(
@@ -2379,7 +2677,7 @@ var ExperimentEvent = import_v36.z.object({
2379
2677
  origin: ObjectReferenceNullish.optional(),
2380
2678
  comments: import_v36.z.union([import_v36.z.array(import_v36.z.unknown()), import_v36.z.null()]).optional(),
2381
2679
  audit_data: import_v36.z.union([import_v36.z.array(import_v36.z.unknown()), import_v36.z.null()]).optional(),
2382
- facets: import_v36.z.union([import_v36.z.object({}).partial().passthrough(), import_v36.z.null()]).optional(),
2680
+ facets: import_v36.z.union([import_v36.z.record(import_v36.z.union([import_v36.z.string(), import_v36.z.null()])), import_v36.z.null()]).optional(),
2383
2681
  classifications: import_v36.z.union([
2384
2682
  import_v36.z.record(
2385
2683
  import_v36.z.array(
@@ -2517,7 +2815,8 @@ var PromptParserNullish = import_v36.z.union([
2517
2815
  use_cot: import_v36.z.boolean(),
2518
2816
  choice_scores: import_v36.z.record(import_v36.z.number().gte(0).lte(1)).optional(),
2519
2817
  choice: import_v36.z.array(import_v36.z.string()).optional(),
2520
- allow_no_match: import_v36.z.boolean().optional()
2818
+ allow_no_match: import_v36.z.boolean().optional(),
2819
+ allow_skip: import_v36.z.boolean().optional()
2521
2820
  }),
2522
2821
  import_v36.z.null()
2523
2822
  ]);
@@ -2847,6 +3146,9 @@ var Group = import_v36.z.object({
2847
3146
  var GroupScope = import_v36.z.object({
2848
3147
  type: import_v36.z.literal("group"),
2849
3148
  group_by: import_v36.z.string(),
3149
+ interval_seconds: import_v36.z.number().gte(1).optional(),
3150
+ max_traces: import_v36.z.number().int().gte(1).lte(64).optional(),
3151
+ placement: import_v36.z.enum(["first", "each"]),
2850
3152
  idle_seconds: import_v36.z.number().optional()
2851
3153
  });
2852
3154
  var IfExists = import_v36.z.enum(["error", "ignore", "replace"]);
@@ -2995,6 +3297,10 @@ var RetentionObjectType = import_v36.z.enum([
2995
3297
  "experiment",
2996
3298
  "dataset"
2997
3299
  ]);
3300
+ var TopicAutomationFacetModel = import_v36.z.union([
3301
+ import_v36.z.enum(["brain-facet-latest", "brain-facet-1", "brain-facet-2"]),
3302
+ import_v36.z.null()
3303
+ ]);
2998
3304
  var TopicMapFunctionAutomation = import_v36.z.object({
2999
3305
  function: SavedFunctionId.and(import_v36.z.unknown()),
3000
3306
  btql_filter: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional()
@@ -3007,7 +3313,9 @@ var TopicAutomationDataScope = import_v36.z.union([
3007
3313
  ]);
3008
3314
  var TopicAutomationConfig = import_v36.z.object({
3009
3315
  event_type: import_v36.z.literal("topic"),
3316
+ status: AutomationStatus.optional(),
3010
3317
  sampling_rate: import_v36.z.number().gte(0).lte(1),
3318
+ facet_model: TopicAutomationFacetModel.optional(),
3011
3319
  facet_functions: import_v36.z.array(SavedFunctionId),
3012
3320
  topic_map_functions: import_v36.z.array(TopicMapFunctionAutomation),
3013
3321
  scope: import_v36.z.union([SpanScope, TraceScope, GroupScope, import_v36.z.null()]).optional(),
@@ -3021,6 +3329,19 @@ var TopicAutomationConfig = import_v36.z.object({
3021
3329
  import_v36.z.null()
3022
3330
  ]).optional()
3023
3331
  });
3332
+ var TopicDigestAutomationConfig = import_v36.z.object({
3333
+ event_type: import_v36.z.literal("topic_digest"),
3334
+ status: AutomationStatus.optional(),
3335
+ window_seconds: import_v36.z.number().int().gte(3600).lte(2592e3).optional().default(86400),
3336
+ scheduled_time_minutes_utc: import_v36.z.number().int().gte(0).lte(1439),
3337
+ action: import_v36.z.object({
3338
+ type: import_v36.z.literal("slack"),
3339
+ workspace_id: import_v36.z.string(),
3340
+ channel: import_v36.z.string(),
3341
+ message_template: import_v36.z.string().optional()
3342
+ }),
3343
+ topic_map_function_ids: import_v36.z.array(import_v36.z.string()).max(10).optional()
3344
+ });
3024
3345
  var ProjectAutomation = import_v36.z.object({
3025
3346
  id: import_v36.z.string().uuid(),
3026
3347
  project_id: import_v36.z.string().uuid(),
@@ -3045,6 +3366,7 @@ var ProjectAutomation = import_v36.z.object({
3045
3366
  }),
3046
3367
  import_v36.z.object({
3047
3368
  event_type: import_v36.z.literal("btql_export"),
3369
+ status: AutomationStatus.optional(),
3048
3370
  export_definition: import_v36.z.union([
3049
3371
  import_v36.z.object({ type: import_v36.z.literal("log_traces") }),
3050
3372
  import_v36.z.object({ type: import_v36.z.literal("log_spans") }),
@@ -3067,6 +3389,21 @@ var ProjectAutomation = import_v36.z.object({
3067
3389
  ]),
3068
3390
  batch_size: import_v36.z.union([import_v36.z.number(), import_v36.z.null()]).optional()
3069
3391
  }),
3392
+ import_v36.z.object({
3393
+ event_type: import_v36.z.literal("async_query"),
3394
+ status: AutomationStatus.optional(),
3395
+ created_by_user_id: import_v36.z.string().uuid(),
3396
+ object_type: import_v36.z.enum([
3397
+ "project_logs",
3398
+ "experiment",
3399
+ "dataset",
3400
+ "playground_logs"
3401
+ ]),
3402
+ object_id: import_v36.z.string(),
3403
+ query: import_v36.z.string(),
3404
+ format: import_v36.z.literal("jsonl"),
3405
+ batch_size: import_v36.z.union([import_v36.z.number(), import_v36.z.null()]).optional()
3406
+ }),
3070
3407
  import_v36.z.object({
3071
3408
  event_type: import_v36.z.literal("retention"),
3072
3409
  object_type: RetentionObjectType,
@@ -3085,7 +3422,8 @@ var ProjectAutomation = import_v36.z.object({
3085
3422
  })
3086
3423
  ])
3087
3424
  }),
3088
- TopicAutomationConfig
3425
+ TopicAutomationConfig,
3426
+ TopicDigestAutomationConfig
3089
3427
  ])
3090
3428
  });
3091
3429
  var ProjectLogsEvent = import_v36.z.object({
@@ -3124,7 +3462,7 @@ var ProjectLogsEvent = import_v36.z.object({
3124
3462
  comments: import_v36.z.union([import_v36.z.array(import_v36.z.unknown()), import_v36.z.null()]).optional(),
3125
3463
  audit_data: import_v36.z.union([import_v36.z.array(import_v36.z.unknown()), import_v36.z.null()]).optional(),
3126
3464
  _async_scoring_state: import_v36.z.unknown().optional(),
3127
- facets: import_v36.z.union([import_v36.z.object({}).partial().passthrough(), import_v36.z.null()]).optional(),
3465
+ facets: import_v36.z.union([import_v36.z.record(import_v36.z.union([import_v36.z.string(), import_v36.z.null()])), import_v36.z.null()]).optional(),
3128
3466
  classifications: import_v36.z.union([
3129
3467
  import_v36.z.record(
3130
3468
  import_v36.z.array(
@@ -3173,11 +3511,34 @@ var ProjectScoreCategories = import_v36.z.union([
3173
3511
  import_v36.z.array(import_v36.z.string()),
3174
3512
  import_v36.z.null()
3175
3513
  ]);
3514
+ var ProjectScoreCondition = import_v36.z.union([
3515
+ import_v36.z.object({
3516
+ when: import_v36.z.object({
3517
+ clauses: import_v36.z.union([import_v36.z.array(import_v36.z.string()), import_v36.z.null()]),
3518
+ subspan_clauses: import_v36.z.union([import_v36.z.array(import_v36.z.string()), import_v36.z.null()]),
3519
+ trace_clauses: import_v36.z.union([import_v36.z.array(import_v36.z.string()), import_v36.z.null()])
3520
+ }).partial(),
3521
+ behavior: import_v36.z.literal("hidden").optional().default("hidden")
3522
+ }),
3523
+ import_v36.z.null()
3524
+ ]);
3176
3525
  var ProjectScoreConfig = import_v36.z.union([
3177
3526
  import_v36.z.object({
3178
3527
  multi_select: import_v36.z.union([import_v36.z.boolean(), import_v36.z.null()]),
3179
3528
  destination: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]),
3180
- online: OnlineScoreConfig
3529
+ visibility: import_v36.z.union([
3530
+ import_v36.z.object({
3531
+ users: import_v36.z.union([import_v36.z.array(import_v36.z.string()), import_v36.z.null()]),
3532
+ groups: import_v36.z.union([import_v36.z.array(import_v36.z.string()), import_v36.z.null()])
3533
+ }).partial(),
3534
+ import_v36.z.null()
3535
+ ]),
3536
+ online: OnlineScoreConfig,
3537
+ condition: ProjectScoreCondition,
3538
+ object_types: import_v36.z.union([
3539
+ import_v36.z.array(import_v36.z.enum(["project_logs", "dataset", "experiment"])),
3540
+ import_v36.z.null()
3541
+ ])
3181
3542
  }).partial(),
3182
3543
  import_v36.z.null()
3183
3544
  ]);
@@ -3362,8 +3723,7 @@ var User = import_v36.z.object({
3362
3723
  family_name: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
3363
3724
  email: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
3364
3725
  avatar_url: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
3365
- created: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
3366
- last_active_at: import_v36.z.union([import_v36.z.number(), import_v36.z.null()]).optional()
3726
+ created: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional()
3367
3727
  });
3368
3728
  var ViewDataSearch = import_v36.z.union([
3369
3729
  import_v36.z.object({
@@ -4622,7 +4982,10 @@ var BraintrustContextManager = class extends ContextManager {
4622
4982
  }
4623
4983
  };
4624
4984
  function getSpanComponentsClass() {
4625
- return globalThis.BRAINTRUST_SPAN_COMPONENT ? globalThis.BRAINTRUST_SPAN_COMPONENT : SpanComponentsV3;
4985
+ if (globalThis.BRAINTRUST_SPAN_COMPONENT) {
4986
+ return globalThis.BRAINTRUST_SPAN_COMPONENT;
4987
+ }
4988
+ return resolveUseLegacyUuidIds() ? SpanComponentsV3 : SpanComponentsV4;
4626
4989
  }
4627
4990
  function getContextManager() {
4628
4991
  return globalThis.BRAINTRUST_CONTEXT_MANAGER ? new globalThis.BRAINTRUST_CONTEXT_MANAGER() : new BraintrustContextManager();
@@ -4658,6 +5021,9 @@ var NoopSpan = class {
4658
5021
  async export() {
4659
5022
  return "";
4660
5023
  }
5024
+ inject(carrier) {
5025
+ return carrier ?? {};
5026
+ }
4661
5027
  async permalink() {
4662
5028
  return NOOP_SPAN_PERMALINK;
4663
5029
  }
@@ -4708,6 +5074,10 @@ var loginSchema = import_v38.z.strictObject({
4708
5074
  debugLogLevelDisabled: import_v38.z.boolean().optional()
4709
5075
  });
4710
5076
  var stateNonce = 0;
5077
+ var V1_PROXY_SUFFIX = "/v1/proxy";
5078
+ function normalizeProxyConnUrl(proxyUrl) {
5079
+ return proxyUrl.endsWith(V1_PROXY_SUFFIX) ? proxyUrl.slice(0, proxyUrl.length - V1_PROXY_SUFFIX.length) : proxyUrl;
5080
+ }
4711
5081
  var BraintrustState = class _BraintrustState {
4712
5082
  constructor(loginParams) {
4713
5083
  this.loginParams = loginParams;
@@ -4978,7 +5348,10 @@ var BraintrustState = class _BraintrustState {
4978
5348
  if (!this.proxyUrl) {
4979
5349
  throw new Error("Must initialize proxyUrl before requesting proxyConn");
4980
5350
  }
4981
- this._proxyConn = new HTTPConnection(this.proxyUrl, this.fetch);
5351
+ this._proxyConn = new HTTPConnection(
5352
+ normalizeProxyConnUrl(this.proxyUrl),
5353
+ this.fetch
5354
+ );
4982
5355
  }
4983
5356
  return this._proxyConn;
4984
5357
  }
@@ -5651,7 +6024,7 @@ async function permalink(slug, opts) {
5651
6024
  return state.appUrl;
5652
6025
  };
5653
6026
  try {
5654
- const components = getSpanComponentsClass().fromStr(slug);
6027
+ const components = SpanComponentsV4.fromStr(slug);
5655
6028
  const object_type = spanObjectTypeV3ToString(components.data.object_type);
5656
6029
  const [orgName, appUrl, object_id] = await Promise.all([
5657
6030
  getOrgName(),
@@ -5675,35 +6048,47 @@ function startSpanParentArgs(args) {
5675
6048
  let argParentObjectId = void 0;
5676
6049
  let argParentSpanIds = void 0;
5677
6050
  let argPropagatedEvent = void 0;
5678
- if (args.parent) {
6051
+ let argPropagatedState = void 0;
6052
+ const { parentSlug, propagatedState: parentPropagatedState } = normalizeParent(args.parent, args.state);
6053
+ if (parentSlug) {
5679
6054
  if (args.parentSpanIds) {
5680
6055
  throw new Error("Cannot specify both parent and parentSpanIds");
5681
6056
  }
5682
- const parentComponents = getSpanComponentsClass().fromStr(args.parent);
6057
+ const parentComponents = SpanComponentsV4.fromStr(parentSlug);
5683
6058
  if (args.parentObjectType !== parentComponents.data.object_type) {
5684
6059
  throw new Error(
5685
6060
  `Mismatch between expected span parent object type ${args.parentObjectType} and provided type ${parentComponents.data.object_type}`
5686
6061
  );
5687
6062
  }
5688
6063
  argParentObjectId = args.parentObjectId;
5689
- if (parentComponents.data.row_id) {
6064
+ if (parentComponents.data.row_id && parentSpanIdsUsable(
6065
+ parentComponents.data.span_id,
6066
+ parentComponents.data.root_span_id
6067
+ )) {
5690
6068
  argParentSpanIds = {
5691
6069
  spanId: parentComponents.data.span_id,
5692
6070
  rootSpanId: parentComponents.data.root_span_id
5693
6071
  };
5694
6072
  }
5695
6073
  argPropagatedEvent = args.propagatedEvent ?? (parentComponents.data.propagated_event ?? void 0);
6074
+ const propagatedState = args.propagatedState ?? parentPropagatedState;
6075
+ if (propagatedState) {
6076
+ const { braintrustParent: _ignoredBraintrustParent, ...w3cState } = propagatedState;
6077
+ argPropagatedState = w3cState;
6078
+ }
5696
6079
  } else {
5697
6080
  argParentObjectId = args.parentObjectId;
5698
6081
  argParentSpanIds = args.parentSpanIds;
5699
6082
  argPropagatedEvent = args.propagatedEvent;
6083
+ argPropagatedState = args.propagatedState;
5700
6084
  }
5701
6085
  return {
5702
6086
  parentObjectType: args.parentObjectType,
5703
6087
  parentObjectId: argParentObjectId,
5704
6088
  parentComputeObjectMetadataArgs: args.parentComputeObjectMetadataArgs,
5705
6089
  parentSpanIds: argParentSpanIds,
5706
- propagatedEvent: argPropagatedEvent
6090
+ propagatedEvent: argPropagatedEvent,
6091
+ propagatedState: argPropagatedState
5707
6092
  };
5708
6093
  }
5709
6094
  var Logger = class {
@@ -5904,6 +6289,22 @@ var Logger = class {
5904
6289
  _getLinkBaseUrl() {
5905
6290
  return _getLinkBaseUrl(this.state, this._linkArgs);
5906
6291
  }
6292
+ /**
6293
+ * Return this logger's Braintrust parent string (`project_id:<id>` or
6294
+ * `project_name:<name>`) for the `braintrust.parent` baggage entry, or
6295
+ * undefined when it cannot be determined synchronously.
6296
+ */
6297
+ _getOtelParent() {
6298
+ const id = this.computeMetadataArgs?.project_id || this.lazyId.getSync().value;
6299
+ if (id) {
6300
+ return `project_id:${id}`;
6301
+ }
6302
+ const name = this.computeMetadataArgs?.project_name;
6303
+ if (name) {
6304
+ return `project_name:${name}`;
6305
+ }
6306
+ return void 0;
6307
+ }
5907
6308
  };
5908
6309
  function castLogger(logger, asyncFlush) {
5909
6310
  if (logger === void 0) return void 0;
@@ -5998,12 +6399,12 @@ function stringifyWithOverflowMeta(item) {
5998
6399
  object_ids: pickLogs3OverflowObjectIds(record),
5999
6400
  is_delete: record[OBJECT_DELETE_FIELD] === true,
6000
6401
  input_row: {
6001
- byte_size: utf8ByteLength(str)
6402
+ byte_size: utf8ByteLength2(str)
6002
6403
  }
6003
6404
  }
6004
6405
  };
6005
6406
  }
6006
- function utf8ByteLength(value) {
6407
+ function utf8ByteLength2(value) {
6007
6408
  if (typeof TextEncoder !== "undefined") {
6008
6409
  return new TextEncoder().encode(value).length;
6009
6410
  }
@@ -6334,7 +6735,7 @@ var HTTPBackgroundLogger = class _HTTPBackgroundLogger {
6334
6735
  }) {
6335
6736
  const conn = await this.apiConn.get();
6336
6737
  const dataStr = constructLogs3Data(items);
6337
- const payloadBytes = utf8ByteLength(dataStr);
6738
+ const payloadBytes = utf8ByteLength2(dataStr);
6338
6739
  const useOverflow = canUseOverflow && payloadBytes > maxRequestSize;
6339
6740
  if (this.allPublishPayloadsDir) {
6340
6741
  await _HTTPBackgroundLogger.writePayloadToDir({
@@ -6717,100 +7118,335 @@ function currentSpan(options) {
6717
7118
  const state = options?.state ?? _globalState;
6718
7119
  return state.contextManager.getCurrentSpan() ?? NOOP_SPAN;
6719
7120
  }
6720
- function getSpanParentObject(options) {
7121
+ function getSpanParentObjectAndPropagatedState(options) {
6721
7122
  const state = options?.state ?? _globalState;
6722
7123
  const parentSpan = currentSpan({ state });
6723
7124
  if (!Object.is(parentSpan, NOOP_SPAN)) {
6724
- return parentSpan;
7125
+ return { parentObject: parentSpan, propagatedState: void 0 };
7126
+ }
7127
+ const parent = options?.parent ?? state.currentParent.getStore();
7128
+ const { parentSlug, propagatedState } = normalizeParent(parent, state);
7129
+ if (parentSlug) {
7130
+ return {
7131
+ parentObject: SpanComponentsV4.fromStr(parentSlug),
7132
+ propagatedState
7133
+ };
6725
7134
  }
6726
- const parentStr = options?.parent ?? state.currentParent.getStore();
6727
- if (parentStr) return getSpanComponentsClass().fromStr(parentStr);
6728
7135
  const experiment = currentExperiment();
6729
7136
  if (experiment) {
6730
- return experiment;
7137
+ return { parentObject: experiment, propagatedState: void 0 };
6731
7138
  }
6732
7139
  const logger = currentLogger(options);
6733
7140
  if (logger) {
6734
- return logger;
7141
+ return { parentObject: logger, propagatedState: void 0 };
6735
7142
  }
6736
- return NOOP_SPAN;
7143
+ return { parentObject: NOOP_SPAN, propagatedState: void 0 };
6737
7144
  }
6738
- function logError(span, error) {
6739
- let errorMessage = "<error>";
6740
- let stackTrace = "";
6741
- if (error instanceof Error) {
6742
- errorMessage = error.message;
6743
- stackTrace = error.stack || "";
6744
- } else {
6745
- errorMessage = String(error);
7145
+ function currentBraintrustParent(state) {
7146
+ const resolvedState = state ?? _globalState;
7147
+ const experiment = currentExperiment({ state: resolvedState });
7148
+ if (experiment) {
7149
+ try {
7150
+ return experiment._getOtelParent() ?? void 0;
7151
+ } catch {
7152
+ return void 0;
7153
+ }
6746
7154
  }
6747
- span.log({ error: `${errorMessage}
6748
-
6749
- ${stackTrace}` });
6750
- }
6751
- function startSpan(args) {
6752
- return startSpanAndIsLogger(args).span;
6753
- }
6754
- async function flush(options) {
6755
- const state = options?.state ?? _globalState;
6756
- return await state.bgLogger().flush();
7155
+ const logger = currentLogger({ state: resolvedState });
7156
+ if (logger) {
7157
+ try {
7158
+ return logger._getOtelParent() ?? void 0;
7159
+ } catch {
7160
+ return void 0;
7161
+ }
7162
+ }
7163
+ return void 0;
6757
7164
  }
6758
- function startSpanAndIsLogger(args) {
6759
- const state = args?.state ?? _globalState;
6760
- const parentObject = getSpanParentObject({
6761
- asyncFlush: args?.asyncFlush,
6762
- parent: args?.parent,
6763
- state
6764
- });
6765
- if (parentObject instanceof SpanComponentsV3 || parentObject instanceof SpanComponentsV4) {
6766
- const parentSpanIds = parentObject.data.row_id ? {
6767
- spanId: parentObject.data.span_id,
6768
- rootSpanId: parentObject.data.root_span_id
7165
+ function braintrustParentToComponents(braintrustParent) {
7166
+ if (!braintrustParent) {
7167
+ return void 0;
7168
+ }
7169
+ if (braintrustParent.startsWith("project_id:")) {
7170
+ const objectId = braintrustParent.slice("project_id:".length);
7171
+ return objectId ? {
7172
+ objectType: 2 /* PROJECT_LOGS */,
7173
+ objectId,
7174
+ computeArgs: void 0
7175
+ } : void 0;
7176
+ }
7177
+ if (braintrustParent.startsWith("project_name:")) {
7178
+ const name = braintrustParent.slice("project_name:".length);
7179
+ return name ? {
7180
+ objectType: 2 /* PROJECT_LOGS */,
7181
+ objectId: void 0,
7182
+ computeArgs: { project_name: name }
7183
+ } : void 0;
7184
+ }
7185
+ if (braintrustParent.startsWith("experiment_id:")) {
7186
+ const objectId = braintrustParent.slice("experiment_id:".length);
7187
+ return objectId ? {
7188
+ objectType: 1 /* EXPERIMENT */,
7189
+ objectId,
7190
+ computeArgs: void 0
6769
7191
  } : void 0;
6770
- const span = new SpanImpl({
6771
- state,
6772
- ...args,
6773
- parentObjectType: parentObject.data.object_type,
6774
- parentObjectId: new LazyValue(
6775
- spanComponentsToObjectIdLambda(state, parentObject)
6776
- ),
6777
- parentComputeObjectMetadataArgs: parentObject.data.compute_object_metadata_args ?? void 0,
6778
- parentSpanIds,
6779
- propagatedEvent: args?.propagatedEvent ?? // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
6780
- (parentObject.data.propagated_event ?? void 0)
6781
- });
6782
- return {
6783
- span,
6784
- isSyncFlushLogger: parentObject.data.object_type === 2 /* PROJECT_LOGS */ && // Since there's no parent logger here, we're free to choose the async flush
6785
- // behavior, and therefore propagate along whatever we get from the arguments
6786
- args?.asyncFlush === false
6787
- };
6788
- } else {
6789
- const span = parentObject.startSpan(args);
6790
- return {
6791
- span,
6792
- isSyncFlushLogger: parentObject.kind === "logger" && parentObject.asyncFlush === false
6793
- };
6794
7192
  }
7193
+ return void 0;
6795
7194
  }
6796
- function withCurrent(span, callback, state = void 0) {
6797
- const currentState = state ?? _globalState;
6798
- return currentState.contextManager.runInContext(span, () => callback(span));
7195
+ function isMutableHeaderTupleArray(carrier) {
7196
+ return Array.isArray(carrier) && carrier.every((item) => Array.isArray(item) && typeof item[0] === "string");
6799
7197
  }
6800
- function _saveOrgInfo(state, org_info, org_name) {
6801
- if (org_info.length === 0) {
6802
- throw new LoginInvalidOrgError(
6803
- "This user is not part of any organizations."
6804
- );
7198
+ function setHeader(carrier, name, value) {
7199
+ if (isMutableHeaderTupleArray(carrier)) {
7200
+ const lowered2 = name.toLowerCase();
7201
+ for (let i = carrier.length - 1; i >= 0; i--) {
7202
+ if (carrier[i][0].toLowerCase() === lowered2) {
7203
+ carrier.splice(i, 1);
7204
+ }
7205
+ }
7206
+ carrier.push([name, value]);
7207
+ return;
6805
7208
  }
6806
- for (const org of org_info) {
6807
- if (org_name === void 0 || org.name === org_name) {
6808
- state.orgId = org.id;
6809
- state.orgName = org.name;
6810
- state.apiUrl = isomorph_default.getEnv("BRAINTRUST_API_URL") ?? org.api_url;
6811
- state.proxyUrl = isomorph_default.getEnv("BRAINTRUST_PROXY_URL") ?? org.proxy_url;
6812
- state.gitMetadataSettings = org.git_metadata || void 0;
6813
- break;
7209
+ const setter = carrier.set;
7210
+ if (typeof setter === "function") {
7211
+ const deleter = carrier.delete;
7212
+ if (typeof deleter === "function") {
7213
+ try {
7214
+ deleter.call(carrier, name);
7215
+ } catch {
7216
+ }
7217
+ }
7218
+ setter.call(carrier, name, value);
7219
+ return;
7220
+ }
7221
+ const nodeSetter = carrier.setHeader;
7222
+ if (typeof nodeSetter === "function") {
7223
+ const remover = carrier.removeHeader;
7224
+ if (typeof remover === "function") {
7225
+ try {
7226
+ remover.call(carrier, name);
7227
+ } catch {
7228
+ }
7229
+ }
7230
+ nodeSetter.call(carrier, name, value);
7231
+ return;
7232
+ }
7233
+ const headerSetter = carrier.header;
7234
+ if (typeof headerSetter === "function") {
7235
+ const deleter = carrier.delete;
7236
+ if (typeof deleter === "function") {
7237
+ try {
7238
+ deleter.call(carrier, name);
7239
+ } catch {
7240
+ }
7241
+ }
7242
+ const remover = carrier.removeHeader;
7243
+ if (typeof remover === "function") {
7244
+ try {
7245
+ remover.call(carrier, name);
7246
+ } catch {
7247
+ }
7248
+ }
7249
+ headerSetter.call(carrier, name, value);
7250
+ return;
7251
+ }
7252
+ const headerBag = carrier;
7253
+ const lowered = name.toLowerCase();
7254
+ for (const key of Object.keys(headerBag)) {
7255
+ if (key !== name && key.toLowerCase() === lowered) {
7256
+ delete headerBag[key];
7257
+ }
7258
+ }
7259
+ headerBag[name] = value;
7260
+ }
7261
+ function deleteHeader(carrier, name) {
7262
+ const lowered = name.toLowerCase();
7263
+ if (isMutableHeaderTupleArray(carrier)) {
7264
+ for (let i = carrier.length - 1; i >= 0; i--) {
7265
+ if (carrier[i][0].toLowerCase() === lowered) {
7266
+ carrier.splice(i, 1);
7267
+ }
7268
+ }
7269
+ return;
7270
+ }
7271
+ const deleter = carrier.delete;
7272
+ if (typeof deleter === "function") {
7273
+ try {
7274
+ deleter.call(carrier, name);
7275
+ return;
7276
+ } catch {
7277
+ }
7278
+ }
7279
+ const remover = carrier.removeHeader;
7280
+ if (typeof remover === "function") {
7281
+ try {
7282
+ remover.call(carrier, name);
7283
+ return;
7284
+ } catch {
7285
+ }
7286
+ }
7287
+ const headerBag = carrier;
7288
+ for (const key of Object.keys(headerBag)) {
7289
+ if (key.toLowerCase() === lowered) {
7290
+ delete headerBag[key];
7291
+ }
7292
+ }
7293
+ }
7294
+ function _injectIntoCarrier(carrier, args) {
7295
+ const traceFlags = args.propagatedState?.traceFlags;
7296
+ const traceparent = traceFlags ? formatTraceparent(args.traceId, args.spanId, traceFlags) : formatTraceparent(args.traceId, args.spanId);
7297
+ if (traceparent === void 0) {
7298
+ return;
7299
+ }
7300
+ setHeader(carrier, TRACEPARENT_HEADER, traceparent);
7301
+ const tracestate = args.propagatedState?.tracestate;
7302
+ if (tracestate) {
7303
+ setHeader(carrier, TRACESTATE_HEADER, tracestate);
7304
+ }
7305
+ const existing = getHeader(carrier, BAGGAGE_HEADER);
7306
+ const baggageValue = mergeBaggage(existing, args.braintrustParent);
7307
+ if (baggageValue !== void 0) {
7308
+ setHeader(carrier, BAGGAGE_HEADER, baggageValue);
7309
+ } else if (existing !== void 0) {
7310
+ deleteHeader(carrier, BAGGAGE_HEADER);
7311
+ }
7312
+ }
7313
+ function resolveW3cParent(context, state) {
7314
+ const traceparent = getHeader(context, TRACEPARENT_HEADER);
7315
+ const parsed = traceparent ? parseTraceparent(traceparent) : void 0;
7316
+ if (parsed === void 0) {
7317
+ return { parentSlug: void 0, propagatedState: void 0 };
7318
+ }
7319
+ const { traceId, spanId, traceFlags } = parsed;
7320
+ let braintrustParent = void 0;
7321
+ const baggageValue = getHeader(context, BAGGAGE_HEADER);
7322
+ if (baggageValue) {
7323
+ braintrustParent = parseBaggage(baggageValue)[BRAINTRUST_PARENT_KEY];
7324
+ }
7325
+ if (!braintrustParent) {
7326
+ braintrustParent = currentBraintrustParent(state);
7327
+ }
7328
+ if (!braintrustParent) {
7329
+ debugLogger.warn(
7330
+ "Received traceparent without a braintrust.parent and no active logger/experiment; cannot route the trace. Starting a fresh local span instead."
7331
+ );
7332
+ return { parentSlug: void 0, propagatedState: void 0 };
7333
+ }
7334
+ const parsedParent = braintrustParentToComponents(braintrustParent);
7335
+ if (parsedParent === void 0) {
7336
+ debugLogger.warn(
7337
+ `Invalid braintrust.parent: ${JSON.stringify(braintrustParent)}`
7338
+ );
7339
+ return { parentSlug: void 0, propagatedState: void 0 };
7340
+ }
7341
+ const { objectType, objectId, computeArgs } = parsedParent;
7342
+ const tracestate = getHeader(context, TRACESTATE_HEADER);
7343
+ const slug = new SpanComponentsV4({
7344
+ object_type: objectType,
7345
+ ...computeArgs ? { compute_object_metadata_args: computeArgs } : { object_id: objectId },
7346
+ row_id: "bt-propagation",
7347
+ // non-empty to enable span_id/root_span_id
7348
+ span_id: spanId,
7349
+ root_span_id: traceId
7350
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
7351
+ }).toStr();
7352
+ return {
7353
+ parentSlug: slug,
7354
+ propagatedState: { tracestate, traceFlags, braintrustParent }
7355
+ };
7356
+ }
7357
+ function normalizeParent(parent, state) {
7358
+ if (parent && typeof parent === "object") {
7359
+ return resolveW3cParent(parent, state);
7360
+ }
7361
+ return {
7362
+ parentSlug: parent ?? void 0,
7363
+ propagatedState: void 0
7364
+ };
7365
+ }
7366
+ function parentSpanIdsUsable(spanId, rootSpanId) {
7367
+ return Boolean(spanId) && Boolean(rootSpanId);
7368
+ }
7369
+ function logError(span, error) {
7370
+ let errorMessage = "<error>";
7371
+ let stackTrace = "";
7372
+ if (error instanceof Error) {
7373
+ errorMessage = error.message;
7374
+ stackTrace = error.stack || "";
7375
+ } else {
7376
+ errorMessage = String(error);
7377
+ }
7378
+ span.log({ error: `${errorMessage}
7379
+
7380
+ ${stackTrace}` });
7381
+ }
7382
+ function startSpan(args) {
7383
+ return startSpanAndIsLogger(args).span;
7384
+ }
7385
+ async function flush(options) {
7386
+ const state = options?.state ?? _globalState;
7387
+ return await state.bgLogger().flush();
7388
+ }
7389
+ function startSpanAndIsLogger(args) {
7390
+ const state = args?.state ?? _globalState;
7391
+ const { parentObject, propagatedState } = getSpanParentObjectAndPropagatedState({
7392
+ asyncFlush: args?.asyncFlush,
7393
+ parent: args?.parent,
7394
+ state
7395
+ });
7396
+ if (parentObject instanceof SpanComponentsV3 || parentObject instanceof SpanComponentsV4) {
7397
+ const parentSpanIds = parentObject.data.row_id && parentSpanIdsUsable(
7398
+ parentObject.data.span_id,
7399
+ parentObject.data.root_span_id
7400
+ ) ? {
7401
+ spanId: parentObject.data.span_id,
7402
+ rootSpanId: parentObject.data.root_span_id
7403
+ } : void 0;
7404
+ const { parent: _ignoredParent, ...spanArgs } = args ?? {};
7405
+ const span = new SpanImpl({
7406
+ state,
7407
+ ...spanArgs,
7408
+ parentObjectType: parentObject.data.object_type,
7409
+ parentObjectId: new LazyValue(
7410
+ spanComponentsToObjectIdLambda(state, parentObject)
7411
+ ),
7412
+ parentComputeObjectMetadataArgs: parentObject.data.compute_object_metadata_args ?? void 0,
7413
+ parentSpanIds,
7414
+ propagatedEvent: args?.propagatedEvent ?? // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
7415
+ (parentObject.data.propagated_event ?? void 0),
7416
+ propagatedState
7417
+ });
7418
+ return {
7419
+ span,
7420
+ isSyncFlushLogger: parentObject.data.object_type === 2 /* PROJECT_LOGS */ && // Since there's no parent logger here, we're free to choose the async flush
7421
+ // behavior, and therefore propagate along whatever we get from the arguments
7422
+ args?.asyncFlush === false
7423
+ };
7424
+ } else {
7425
+ const span = parentObject.startSpan(args);
7426
+ return {
7427
+ span,
7428
+ isSyncFlushLogger: parentObject.kind === "logger" && parentObject.asyncFlush === false
7429
+ };
7430
+ }
7431
+ }
7432
+ function withCurrent(span, callback, state = void 0) {
7433
+ const currentState = state ?? _globalState;
7434
+ return currentState.contextManager.runInContext(span, () => callback(span));
7435
+ }
7436
+ function _saveOrgInfo(state, org_info, org_name) {
7437
+ if (org_info.length === 0) {
7438
+ throw new LoginInvalidOrgError(
7439
+ "This user is not part of any organizations."
7440
+ );
7441
+ }
7442
+ for (const org of org_info) {
7443
+ if (org_name === void 0 || org.name === org_name) {
7444
+ state.orgId = org.id;
7445
+ state.orgName = org.name;
7446
+ state.apiUrl = isomorph_default.getEnv("BRAINTRUST_API_URL") ?? org.api_url;
7447
+ state.proxyUrl = isomorph_default.getEnv("BRAINTRUST_PROXY_URL") ?? org.proxy_url;
7448
+ state.gitMetadataSettings = org.git_metadata || void 0;
7449
+ break;
6814
7450
  }
6815
7451
  }
6816
7452
  if (state.orgId === void 0) {
@@ -7004,11 +7640,12 @@ function validateAndSanitizeExperimentLogFullArgs(event, hasDataset) {
7004
7640
  var DEFAULT_FETCH_BATCH_SIZE = 1e3;
7005
7641
  var MAX_BTQL_ITERATIONS = 1e4;
7006
7642
  var ObjectFetcher = class {
7007
- constructor(objectType, pinnedVersion, mutateRecord, _internal_btql) {
7643
+ constructor(objectType, pinnedVersion, mutateRecord, _internal_btql, _internalBrainstoreRealtime = true) {
7008
7644
  this.objectType = objectType;
7009
7645
  this.pinnedVersion = pinnedVersion;
7010
7646
  this.mutateRecord = mutateRecord;
7011
7647
  this._internal_btql = _internal_btql;
7648
+ this._internalBrainstoreRealtime = _internalBrainstoreRealtime;
7012
7649
  }
7013
7650
  _fetchedData = void 0;
7014
7651
  get id() {
@@ -7067,7 +7704,7 @@ var ObjectFetcher = class {
7067
7704
  ...internalBtqlWithoutReservedQueryKeys
7068
7705
  },
7069
7706
  use_columnstore: false,
7070
- brainstore_realtime: true,
7707
+ brainstore_realtime: this._internalBrainstoreRealtime,
7071
7708
  query_source: `js_sdk_object_fetcher_${this.objectType}`,
7072
7709
  ...this.pinnedVersion !== void 0 ? {
7073
7710
  version: this.pinnedVersion
@@ -7416,6 +8053,15 @@ View complete results in Braintrust or run experiment.summarize() again.`
7416
8053
  object_id: await this.id
7417
8054
  }).toStr();
7418
8055
  }
8056
+ /**
8057
+ * Return this experiment's Braintrust parent string (`experiment_id:<id>`) for
8058
+ * the `braintrust.parent` baggage entry, or undefined when it cannot be
8059
+ * determined synchronously.
8060
+ */
8061
+ _getOtelParent() {
8062
+ const id = this.lazyId.getSync().value;
8063
+ return id ? `experiment_id:${id}` : void 0;
8064
+ }
7419
8065
  /**
7420
8066
  * Flush any pending rows to the server.
7421
8067
  */
@@ -7480,9 +8126,16 @@ var SpanImpl = class _SpanImpl {
7480
8126
  _spanId;
7481
8127
  _rootSpanId;
7482
8128
  _spanParents;
8129
+ // Inbound W3C trace-context state (tracestate + raw traceparent flags) to
8130
+ // forward on outbound propagation. Captured at the span that received it (via
8131
+ // extractTraceContextFromHeaders) and inherited by all subspans, so that any
8132
+ // inject() within the trace re-emits the upstream state unchanged, per the W3C
8133
+ // Trace Context spec. Not interpreted.
8134
+ _propagatedState;
7483
8135
  kind = "span";
7484
8136
  constructor(args) {
7485
8137
  this._state = args.state;
8138
+ this._propagatedState = args.propagatedState;
7486
8139
  const spanAttributes = args.spanAttributes ?? {};
7487
8140
  const rawEvent = args.event ?? {};
7488
8141
  const type = args.type ?? (args.parentSpanIds ? void 0 : args.defaultRootType);
@@ -7598,7 +8251,7 @@ var SpanImpl = class _SpanImpl {
7598
8251
  tags: partialRecord.tags,
7599
8252
  span_id: this._spanId,
7600
8253
  span_parents: this._spanParents,
7601
- is_root: this._spanId === this._rootSpanId,
8254
+ is_root: !this._spanParents || this._spanParents.length === 0,
7602
8255
  span_attributes: partialRecord.span_attributes
7603
8256
  };
7604
8257
  this._state.spanCache.queueWrite(
@@ -7660,7 +8313,8 @@ var SpanImpl = class _SpanImpl {
7660
8313
  parentObjectId: this.parentObjectId,
7661
8314
  parentComputeObjectMetadataArgs: this.parentComputeObjectMetadataArgs,
7662
8315
  parentSpanIds,
7663
- propagatedEvent: args?.propagatedEvent ?? this.propagatedEvent
8316
+ propagatedEvent: args?.propagatedEvent ?? this.propagatedEvent,
8317
+ propagatedState: this._propagatedState
7664
8318
  })
7665
8319
  });
7666
8320
  }
@@ -7679,7 +8333,8 @@ var SpanImpl = class _SpanImpl {
7679
8333
  parentObjectId: this.parentObjectId,
7680
8334
  parentComputeObjectMetadataArgs: this.parentComputeObjectMetadataArgs,
7681
8335
  parentSpanIds,
7682
- propagatedEvent: args?.propagatedEvent ?? this.propagatedEvent
8336
+ propagatedEvent: args?.propagatedEvent ?? this.propagatedEvent,
8337
+ propagatedState: this._propagatedState
7683
8338
  }),
7684
8339
  spanId
7685
8340
  });
@@ -7707,6 +8362,42 @@ var SpanImpl = class _SpanImpl {
7707
8362
  propagated_event: this.propagatedEvent
7708
8363
  }).toStr();
7709
8364
  }
8365
+ /**
8366
+ * Return this span's Braintrust parent string (`project_id:<id>`,
8367
+ * `project_name:<name>`, or `experiment_id:<id>`) for the `braintrust.parent`
8368
+ * baggage entry, or undefined when it cannot be determined synchronously.
8369
+ */
8370
+ _getOtelParent() {
8371
+ if (this.parentObjectType === 2 /* PROJECT_LOGS */) {
8372
+ const id = this.parentComputeObjectMetadataArgs?.project_id || this.parentObjectId.getSync().value;
8373
+ const name = this.parentComputeObjectMetadataArgs?.project_name;
8374
+ if (id) {
8375
+ return `project_id:${id}`;
8376
+ } else if (name) {
8377
+ return `project_name:${name}`;
8378
+ }
8379
+ } else if (this.parentObjectType === 1 /* EXPERIMENT */) {
8380
+ const id = this.parentComputeObjectMetadataArgs?.experiment_id || this.parentObjectId.getSync().value;
8381
+ if (id) {
8382
+ return `experiment_id:${id}`;
8383
+ }
8384
+ }
8385
+ return void 0;
8386
+ }
8387
+ inject(carrier) {
8388
+ const resolvedCarrier = carrier ?? {};
8389
+ try {
8390
+ _injectIntoCarrier(resolvedCarrier, {
8391
+ traceId: this._rootSpanId,
8392
+ spanId: this._spanId,
8393
+ braintrustParent: this._getOtelParent() ?? this._propagatedState?.braintrustParent,
8394
+ propagatedState: this._propagatedState
8395
+ });
8396
+ } catch (e) {
8397
+ debugLogger.warn(`Error injecting trace context: ${e}`);
8398
+ }
8399
+ return resolvedCarrier;
8400
+ }
7710
8401
  async permalink() {
7711
8402
  return await permalink(await this.export(), {
7712
8403
  state: this._state
@@ -7842,6 +8533,7 @@ var Dataset2 = class extends ObjectFetcher {
7842
8533
  _internal_btql
7843
8534
  );
7844
8535
  this.state = state;
8536
+ void this.__braintrust_dataset_marker;
7845
8537
  this.lazyMetadata = lazyMetadata;
7846
8538
  this.lazyPinnedVersion = pinState?.lazyPinnedVersion;
7847
8539
  this.pinnedEnvironment = pinState?.pinnedEnvironment;
@@ -8808,6 +9500,22 @@ function runStreamingCompletionHook(args) {
8808
9500
  );
8809
9501
  }
8810
9502
  }
9503
+ function runStreamingErrorHook(args) {
9504
+ if (!args.config.onError) {
9505
+ return;
9506
+ }
9507
+ try {
9508
+ args.config.onError({
9509
+ channelName: args.channelName,
9510
+ error: args.error,
9511
+ event: args.event,
9512
+ span: args.span,
9513
+ startTime: args.startTime
9514
+ });
9515
+ } catch (error) {
9516
+ debugLogger.error(`Error in onError hook for ${args.channelName}:`, error);
9517
+ }
9518
+ }
8811
9519
  function traceAsyncChannel(channel2, config) {
8812
9520
  const tracingChannel = channel2.tracingChannel();
8813
9521
  const states = /* @__PURE__ */ new WeakMap();
@@ -8969,6 +9677,14 @@ function traceStreamingChannel(channel2, config) {
8969
9677
  }
8970
9678
  },
8971
9679
  onError: (error) => {
9680
+ runStreamingErrorHook({
9681
+ channelName,
9682
+ config,
9683
+ error,
9684
+ event: asyncEndEvent,
9685
+ span,
9686
+ startTime
9687
+ });
8972
9688
  span.log({
8973
9689
  error: error.message
8974
9690
  });
@@ -9026,6 +9742,17 @@ function traceStreamingChannel(channel2, config) {
9026
9742
  }
9027
9743
  },
9028
9744
  error: (event) => {
9745
+ const spanData = states.get(event);
9746
+ if (spanData) {
9747
+ runStreamingErrorHook({
9748
+ channelName,
9749
+ config,
9750
+ error: event.error,
9751
+ event,
9752
+ span: spanData.span,
9753
+ startTime: spanData.startTime
9754
+ });
9755
+ }
9029
9756
  logErrorAndEnd(states, event);
9030
9757
  }
9031
9758
  };
@@ -11388,14 +12115,45 @@ function serializeAISDKToolsForLogging(tools) {
11388
12115
  return serialized;
11389
12116
  }
11390
12117
 
12118
+ // src/vendor-sdk-types/ai-sdk-v7-telemetry.ts
12119
+ var BRAINTRUST_AI_SDK_V7_OPERATION_KEY = /* @__PURE__ */ Symbol.for(
12120
+ "braintrust.ai-sdk.v7.telemetry-operation-key"
12121
+ );
12122
+
12123
+ // src/wrappers/ai-sdk/workflow-agent-context.ts
12124
+ var workflowAgentWrapperSpans = /* @__PURE__ */ new Map();
12125
+ function registerWorkflowAgentWrapperSpan(span) {
12126
+ if (span.spanId) {
12127
+ workflowAgentWrapperSpans.set(span.spanId, span);
12128
+ }
12129
+ }
12130
+ function unregisterWorkflowAgentWrapperSpan(span) {
12131
+ if (span.spanId) {
12132
+ workflowAgentWrapperSpans.delete(span.spanId);
12133
+ }
12134
+ }
12135
+ function currentWorkflowAgentWrapperSpan() {
12136
+ const parentSpanIds = _internalGetGlobalState().contextManager.getParentSpanIds()?.spanParents ?? [];
12137
+ for (const parentSpanId of parentSpanIds) {
12138
+ const span = workflowAgentWrapperSpans.get(parentSpanId);
12139
+ if (span) {
12140
+ return span;
12141
+ }
12142
+ }
12143
+ return void 0;
12144
+ }
12145
+
11391
12146
  // src/wrappers/ai-sdk/telemetry.ts
11392
12147
  function braintrustAISDKTelemetry() {
11393
12148
  const operations = /* @__PURE__ */ new Map();
12149
+ const operationKeysByCallId = /* @__PURE__ */ new Map();
12150
+ const workflowOperationKeyStore = isomorph_default.newAsyncLocalStorage();
11394
12151
  const modelSpans = /* @__PURE__ */ new Map();
11395
12152
  const objectSpans = /* @__PURE__ */ new Map();
11396
12153
  const embedSpans = /* @__PURE__ */ new Map();
11397
12154
  const rerankSpans = /* @__PURE__ */ new Map();
11398
12155
  const toolSpans = /* @__PURE__ */ new Map();
12156
+ let workflowAgentOperationCounter = 0;
11399
12157
  const runSafely = (name, callback) => {
11400
12158
  try {
11401
12159
  callback();
@@ -11403,139 +12161,413 @@ function braintrustAISDKTelemetry() {
11403
12161
  console.error(`Error in Braintrust AI SDK telemetry ${name}:`, error);
11404
12162
  }
11405
12163
  };
11406
- const startChildSpan = (callId, name, type, event) => {
11407
- const parent = operations.get(callId)?.span;
12164
+ const startChildSpan = (operationKey, name, type, event) => {
12165
+ const parent = operations.get(operationKey)?.span;
11408
12166
  const spanArgs = {
11409
12167
  name,
11410
12168
  spanAttributes: { type },
11411
12169
  ...event ? { event } : {}
11412
12170
  };
11413
12171
  const span = parent ? parent.startSpan(spanArgs) : startSpan(spanArgs);
11414
- const state = operations.get(callId);
12172
+ const state = operations.get(operationKey);
11415
12173
  if (state && type === "llm" /* LLM */) {
11416
12174
  state.hadModelChild = true;
11417
12175
  }
11418
12176
  return span;
11419
12177
  };
11420
- return {
11421
- onStart(event) {
11422
- runSafely("onStart", () => {
11423
- const operationName = operationNameFromId(event.operationId);
11424
- const span = startSpan({
11425
- name: operationName,
11426
- spanAttributes: { type: "function" /* FUNCTION */ }
11427
- });
11428
- operations.set(event.callId, {
11429
- hadModelChild: false,
11430
- operationName,
11431
- span,
11432
- startTime: getCurrentUnixTimestamp()
11433
- });
11434
- const metadata = metadataFromEvent(event);
11435
- const logPayload = { metadata };
11436
- if (shouldRecordInputs(event)) {
11437
- const { input, outputPromise } = processAISDKCallInput(
11438
- operationInput(event, operationName)
11439
- );
11440
- logPayload.input = input;
11441
- if (outputPromise && input && typeof input === "object") {
11442
- outputPromise.then((resolvedData) => {
11443
- span.log({
11444
- input: {
11445
- ...input,
11446
- ...resolvedData
11447
- }
11448
- });
11449
- }).catch(() => {
11450
- });
11451
- }
12178
+ const registerOperation = (state) => {
12179
+ operations.set(state.operationKey, state);
12180
+ const keys = operationKeysByCallId.get(state.callId) ?? [];
12181
+ keys.push(state.operationKey);
12182
+ operationKeysByCallId.set(state.callId, keys);
12183
+ };
12184
+ const deleteOperation = (operationKey) => {
12185
+ const state = operations.get(operationKey);
12186
+ if (!state) {
12187
+ return;
12188
+ }
12189
+ operations.delete(operationKey);
12190
+ if (workflowOperationKeyStore.getStore() === operationKey) {
12191
+ workflowOperationKeyStore.enterWith(void 0);
12192
+ }
12193
+ const keys = operationKeysByCallId.get(state.callId);
12194
+ if (!keys) {
12195
+ return;
12196
+ }
12197
+ const index = keys.indexOf(operationKey);
12198
+ if (index >= 0) {
12199
+ keys.splice(index, 1);
12200
+ }
12201
+ if (keys.length === 0) {
12202
+ operationKeysByCallId.delete(state.callId);
12203
+ }
12204
+ };
12205
+ const explicitOperationKey = (event) => {
12206
+ if (!isObject(event)) {
12207
+ return void 0;
12208
+ }
12209
+ const key = event[BRAINTRUST_AI_SDK_V7_OPERATION_KEY];
12210
+ return typeof key === "string" ? key : void 0;
12211
+ };
12212
+ const createOperationKey = (event, operationName) => {
12213
+ const explicit = explicitOperationKey(event);
12214
+ if (explicit) {
12215
+ return explicit;
12216
+ }
12217
+ if (operationName === "WorkflowAgent.stream") {
12218
+ workflowAgentOperationCounter += 1;
12219
+ return `${event.callId}:${workflowAgentOperationCounter}`;
12220
+ }
12221
+ return event.callId;
12222
+ };
12223
+ const operationKeyForCallId = (callId, mode = "active") => {
12224
+ const keys = operationKeysByCallId.get(callId);
12225
+ if (!keys || keys.length === 0) {
12226
+ return operations.has(callId) ? callId : void 0;
12227
+ }
12228
+ if (keys.length === 1) {
12229
+ return keys[0];
12230
+ }
12231
+ const wrapperSpan = currentWorkflowAgentWrapperSpan();
12232
+ if (wrapperSpan?.spanId) {
12233
+ const key = keys.find(
12234
+ (candidate) => operations.get(candidate)?.span.spanId === wrapperSpan.spanId
12235
+ );
12236
+ if (key) {
12237
+ return key;
12238
+ }
12239
+ }
12240
+ const workflowOperationKey = workflowOperationKeyStore.getStore();
12241
+ if (workflowOperationKey && keys.includes(workflowOperationKey)) {
12242
+ return workflowOperationKey;
12243
+ }
12244
+ if (callId === "workflow-agent") {
12245
+ return void 0;
12246
+ }
12247
+ return mode === "finish" ? keys[0] : keys[keys.length - 1];
12248
+ };
12249
+ const operationKeyFromEvent = (event, mode = "active") => {
12250
+ const explicit = explicitOperationKey(event);
12251
+ if (explicit && operations.has(explicit)) {
12252
+ return explicit;
12253
+ }
12254
+ if (isObject(event)) {
12255
+ const callId = event.callId;
12256
+ if (typeof callId === "string") {
12257
+ const operationKey = operationKeyForCallId(callId, mode);
12258
+ if (operationKey) {
12259
+ return operationKey;
11452
12260
  }
11453
- span.log(logPayload);
11454
- });
11455
- },
11456
- onLanguageModelCallStart(event) {
11457
- runSafely("onLanguageModelCallStart", () => {
11458
- const state = operations.get(event.callId);
11459
- const openSpans = modelSpans.get(event.callId);
11460
- if (openSpans) {
11461
- for (const span2 of openSpans) {
11462
- span2.end();
11463
- }
11464
- modelSpans.delete(event.callId);
12261
+ const workflowOperationKey2 = workflowOperationKeyStore.getStore();
12262
+ if (workflowOperationKey2 && operations.has(workflowOperationKey2)) {
12263
+ return workflowOperationKey2;
11465
12264
  }
11466
- const span = startChildSpan(
11467
- event.callId,
11468
- state?.operationName === "streamText" ? "doStream" : "doGenerate",
11469
- "llm" /* LLM */,
11470
- {
11471
- ...shouldRecordInputs(event) ? {
11472
- input: processAISDKCallInput(
11473
- operationInput(
11474
- event,
11475
- state?.operationName ?? "generateText"
11476
- )
11477
- ).input
11478
- } : {},
11479
- metadata: metadataFromEvent(event)
11480
- }
11481
- );
11482
- const spans = modelSpans.get(event.callId) ?? [];
11483
- spans.push(span);
11484
- modelSpans.set(event.callId, spans);
11485
- });
11486
- },
11487
- onLanguageModelCallEnd(event) {
11488
- runSafely("onLanguageModelCallEnd", () => {
11489
- const span = shiftModelSpan(modelSpans, event.callId);
11490
- if (!span) {
11491
- return;
12265
+ return callId === "workflow-agent" ? void 0 : callId;
12266
+ }
12267
+ }
12268
+ const workflowOperationKey = workflowOperationKeyStore.getStore();
12269
+ if (workflowOperationKey && operations.has(workflowOperationKey)) {
12270
+ return workflowOperationKey;
12271
+ }
12272
+ const wrapperSpan = currentWorkflowAgentWrapperSpan();
12273
+ if (wrapperSpan?.spanId) {
12274
+ for (const [operationKey, state] of operations) {
12275
+ if (state.operationName === "WorkflowAgent.stream" && state.span.spanId === wrapperSpan.spanId) {
12276
+ return operationKey;
12277
+ }
12278
+ }
12279
+ }
12280
+ const workflowAgentKeys = operationKeysByCallId.get("workflow-agent");
12281
+ if (workflowAgentKeys?.length === 1) {
12282
+ return workflowAgentKeys[0];
12283
+ }
12284
+ if (operations.size === 1) {
12285
+ return operations.keys().next().value;
12286
+ }
12287
+ return void 0;
12288
+ };
12289
+ const closeOpenChildSpans = (operationKey, error) => {
12290
+ const openModelSpans = modelSpans.get(operationKey);
12291
+ if (openModelSpans) {
12292
+ for (const span of openModelSpans) {
12293
+ if (error !== void 0) {
12294
+ logError(span, error);
11492
12295
  }
11493
- const result = {
11494
- ...event,
11495
- response: event.responseId ? { id: event.responseId } : void 0
11496
- };
11497
- span.log({
11498
- ...shouldRecordOutputs(event) ? {
11499
- output: processAISDKOutput(result, DEFAULT_DENY_OUTPUT_PATHS)
11500
- } : {},
11501
- metrics: extractTokenMetrics(result)
11502
- });
11503
12296
  span.end();
12297
+ }
12298
+ modelSpans.delete(operationKey);
12299
+ }
12300
+ const openObjectSpan = objectSpans.get(operationKey);
12301
+ if (openObjectSpan) {
12302
+ if (error !== void 0) {
12303
+ logError(openObjectSpan, error);
12304
+ }
12305
+ openObjectSpan.end();
12306
+ objectSpans.delete(operationKey);
12307
+ }
12308
+ for (const [embedCallId, embedState] of embedSpans) {
12309
+ if (embedState.operationKey === operationKey) {
12310
+ if (error !== void 0) {
12311
+ logError(embedState.span, error);
12312
+ }
12313
+ embedState.span.end();
12314
+ embedSpans.delete(embedCallId);
12315
+ }
12316
+ }
12317
+ const openRerankSpan = rerankSpans.get(operationKey);
12318
+ if (openRerankSpan) {
12319
+ if (error !== void 0) {
12320
+ logError(openRerankSpan, error);
12321
+ }
12322
+ openRerankSpan.end();
12323
+ rerankSpans.delete(operationKey);
12324
+ }
12325
+ for (const [toolCallId, toolState] of toolSpans) {
12326
+ if (toolState.operationKey === operationKey) {
12327
+ if (error !== void 0) {
12328
+ logError(toolState.span, error);
12329
+ }
12330
+ toolState.span.end();
12331
+ toolSpans.delete(toolCallId);
12332
+ }
12333
+ }
12334
+ };
12335
+ const abortReasonFromEvent = (event) => {
12336
+ if (isObject(event)) {
12337
+ const abortEvent = event;
12338
+ if (abortEvent.error !== void 0) {
12339
+ return abortEvent.error;
12340
+ }
12341
+ if (abortEvent.reason !== void 0) {
12342
+ return abortEvent.reason;
12343
+ }
12344
+ }
12345
+ return new Error("AI SDK operation aborted");
12346
+ };
12347
+ const shouldSkipTelemetryChildren = (state) => state?.operationName === "WorkflowAgent.stream" && !state.ownsSpan;
12348
+ const onObjectStepEnd = (event) => {
12349
+ runSafely("onObjectStepEnd", () => {
12350
+ const operationKey = operationKeyFromEvent(event);
12351
+ const span = operationKey ? objectSpans.get(operationKey) : void 0;
12352
+ if (!operationKey || !span) {
12353
+ return;
12354
+ }
12355
+ const result = {
12356
+ ...event,
12357
+ text: event.objectText
12358
+ };
12359
+ span.log({
12360
+ ...shouldRecordOutputs(event) ? {
12361
+ output: processAISDKOutput(result, DEFAULT_DENY_OUTPUT_PATHS)
12362
+ } : {},
12363
+ metrics: extractTokenMetrics(result)
12364
+ });
12365
+ span.end();
12366
+ objectSpans.delete(operationKey);
12367
+ });
12368
+ };
12369
+ const onEmbedEnd = (event) => {
12370
+ runSafely("onEmbedEnd", () => {
12371
+ const state = embedSpans.get(event.embedCallId);
12372
+ if (!state) {
12373
+ return;
12374
+ }
12375
+ const result = {
12376
+ ...event,
12377
+ embeddings: event.embeddings
12378
+ };
12379
+ state.span.log({
12380
+ ...shouldRecordOutputs(event) ? {
12381
+ output: processAISDKEmbeddingOutput(
12382
+ result,
12383
+ DEFAULT_DENY_OUTPUT_PATHS
12384
+ )
12385
+ } : {},
12386
+ metrics: extractTokenMetrics(result)
12387
+ });
12388
+ state.span.end();
12389
+ embedSpans.delete(event.embedCallId);
12390
+ });
12391
+ };
12392
+ const onRerankEnd = (event) => {
12393
+ runSafely("onRerankEnd", () => {
12394
+ const operationKey = operationKeyFromEvent(event);
12395
+ const span = operationKey ? rerankSpans.get(operationKey) : void 0;
12396
+ if (!operationKey || !span) {
12397
+ return;
12398
+ }
12399
+ const result = {
12400
+ ranking: event.ranking?.map((entry) => ({
12401
+ originalIndex: entry.index,
12402
+ score: entry.relevanceScore
12403
+ }))
12404
+ };
12405
+ span.log({
12406
+ ...shouldRecordOutputs(event) ? {
12407
+ output: processAISDKRerankOutput(
12408
+ result,
12409
+ DEFAULT_DENY_OUTPUT_PATHS
12410
+ )
12411
+ } : {}
12412
+ });
12413
+ span.end();
12414
+ rerankSpans.delete(operationKey);
12415
+ });
12416
+ };
12417
+ const onEnd = (event) => {
12418
+ runSafely("onEnd", () => {
12419
+ const operationKey = operationKeyFromEvent(event, "finish");
12420
+ const state = operationKey ? operations.get(operationKey) : void 0;
12421
+ if (!state) {
12422
+ return;
12423
+ }
12424
+ if (!state.ownsSpan) {
12425
+ deleteOperation(state.operationKey);
12426
+ return;
12427
+ }
12428
+ const result = finishResult(event, state.operationName);
12429
+ const metrics = state.hadModelChild ? {} : extractTokenMetrics(result);
12430
+ const timeToFirstToken = state.operationName === "WorkflowAgent.stream" ? void 0 : extractTimeToFirstToken(result, state);
12431
+ if (timeToFirstToken !== void 0) {
12432
+ metrics.time_to_first_token = timeToFirstToken;
12433
+ }
12434
+ state.span.log({
12435
+ ...shouldRecordOutputs(event) ? {
12436
+ output: finishOutput(result, state.operationName)
12437
+ } : {},
12438
+ metrics
12439
+ });
12440
+ state.span.end();
12441
+ deleteOperation(state.operationKey);
12442
+ });
12443
+ };
12444
+ return {
12445
+ onStart(event) {
12446
+ runSafely("onStart", () => {
12447
+ const operationName = operationNameFromId(event.operationId);
12448
+ const workflowAgent = operationName === "WorkflowAgent.stream";
12449
+ const wrapperSpan = workflowAgent ? currentWorkflowAgentWrapperSpan() : void 0;
12450
+ const ownsSpan = !wrapperSpan;
12451
+ const span = ownsSpan ? startSpan({
12452
+ name: operationName,
12453
+ spanAttributes: { type: "function" /* FUNCTION */ }
12454
+ }) : wrapperSpan;
12455
+ const operationKey = createOperationKey(event, operationName);
12456
+ registerOperation({
12457
+ callId: event.callId,
12458
+ hadModelChild: false,
12459
+ loggedInput: false,
12460
+ operationName,
12461
+ operationKey,
12462
+ ownsSpan,
12463
+ span,
12464
+ startTime: getCurrentUnixTimestamp()
12465
+ });
12466
+ if (!ownsSpan) {
12467
+ return;
12468
+ }
12469
+ if (workflowAgent) {
12470
+ workflowOperationKeyStore.enterWith(operationKey);
12471
+ }
12472
+ let metadata = metadataFromEvent(event);
12473
+ const logPayload = { metadata };
12474
+ const workflowAgentCallInput = workflowAgent ? operationInput(event, operationName) : void 0;
12475
+ if (workflowAgentCallInput) {
12476
+ metadata = {
12477
+ ...metadata,
12478
+ ...extractWorkflowMetadataFromCallParams(workflowAgentCallInput)
12479
+ };
12480
+ logPayload.metadata = metadata;
12481
+ }
12482
+ if (shouldRecordInputs(event)) {
12483
+ const callInput = workflowAgentCallInput ?? operationInput(event, operationName);
12484
+ const { input, outputPromise } = workflowAgent ? processAISDKWorkflowAgentCallInput(callInput) : processAISDKCallInput(callInput);
12485
+ logPayload.input = input;
12486
+ const state = operations.get(operationKey);
12487
+ if (state) {
12488
+ state.loggedInput = hasPromptLikeInput(input);
12489
+ }
12490
+ if (outputPromise && !workflowAgent && input && typeof input === "object") {
12491
+ outputPromise.then((resolvedData) => {
12492
+ span.log({
12493
+ input: {
12494
+ ...input,
12495
+ ...resolvedData
12496
+ }
12497
+ });
12498
+ }).catch(() => {
12499
+ });
12500
+ }
12501
+ }
12502
+ span.log(logPayload);
11504
12503
  });
11505
12504
  },
11506
- onObjectStepStart(event) {
11507
- runSafely("onObjectStepStart", () => {
11508
- const state = operations.get(event.callId);
11509
- const openSpan = objectSpans.get(event.callId);
11510
- if (openSpan) {
11511
- openSpan.end();
11512
- objectSpans.delete(event.callId);
12505
+ onLanguageModelCallStart(event) {
12506
+ runSafely("onLanguageModelCallStart", () => {
12507
+ const operationKey = operationKeyFromEvent(event);
12508
+ const state = operationKey ? operations.get(operationKey) : void 0;
12509
+ if (shouldSkipTelemetryChildren(state)) {
12510
+ return;
12511
+ }
12512
+ const operationName = state?.operationName ?? "generateText";
12513
+ const callInput = operationInput(event, operationName);
12514
+ const workflowAgent = operationName === "WorkflowAgent.stream";
12515
+ const processedInput = shouldRecordInputs(event) && workflowAgent ? processAISDKWorkflowAgentModelCallInput(callInput).input : shouldRecordInputs(event) ? processAISDKCallInput(callInput).input : void 0;
12516
+ if (workflowAgent && state?.ownsSpan && !state.loggedInput && hasPromptLikeInput(processedInput)) {
12517
+ state.span.log({
12518
+ input: processedInput,
12519
+ metadata: {
12520
+ ...metadataFromEvent(event),
12521
+ ...extractWorkflowMetadataFromCallParams(callInput)
12522
+ }
12523
+ });
12524
+ state.loggedInput = true;
12525
+ }
12526
+ const openSpans = operationKey ? modelSpans.get(operationKey) : void 0;
12527
+ if (operationKey && openSpans) {
12528
+ for (const span2 of openSpans) {
12529
+ span2.end();
12530
+ }
12531
+ modelSpans.delete(operationKey);
11513
12532
  }
11514
12533
  const span = startChildSpan(
11515
- event.callId,
11516
- state?.operationName === "streamObject" ? "doStream" : "doGenerate",
12534
+ operationKey ?? event.callId,
12535
+ operationName === "streamText" ? "doStream" : "doGenerate",
11517
12536
  "llm" /* LLM */,
11518
12537
  {
11519
12538
  ...shouldRecordInputs(event) ? {
11520
- input: {
11521
- prompt: event.promptMessages
11522
- }
12539
+ input: processedInput
11523
12540
  } : {},
11524
- metadata: metadataFromEvent(event)
12541
+ metadata: workflowAgent ? {
12542
+ ...metadataFromEvent(event),
12543
+ ...extractWorkflowMetadataFromCallParams(callInput)
12544
+ } : metadataFromEvent(event)
11525
12545
  }
11526
12546
  );
11527
- objectSpans.set(event.callId, span);
12547
+ const spanKey = operationKey ?? event.callId;
12548
+ const spans = modelSpans.get(spanKey) ?? [];
12549
+ spans.push(span);
12550
+ modelSpans.set(spanKey, spans);
11528
12551
  });
11529
12552
  },
11530
- onObjectStepFinish(event) {
11531
- runSafely("onObjectStepFinish", () => {
11532
- const span = objectSpans.get(event.callId);
12553
+ onLanguageModelCallEnd(event) {
12554
+ runSafely("onLanguageModelCallEnd", () => {
12555
+ const operationKey = operationKeyFromEvent(event);
12556
+ const state = operationKey ? operations.get(operationKey) : void 0;
12557
+ if (shouldSkipTelemetryChildren(state)) {
12558
+ return;
12559
+ }
12560
+ const span = operationKey ? shiftModelSpan(modelSpans, operationKey) : void 0;
11533
12561
  if (!span) {
11534
12562
  return;
11535
12563
  }
12564
+ const timeToFirstOutputMs = safePerformance(event)?.timeToFirstOutputMs;
12565
+ if (state?.operationName === "streamText" && state.firstChunkTime === void 0 && typeof timeToFirstOutputMs === "number") {
12566
+ state.firstChunkTime = state.startTime + timeToFirstOutputMs / 1e3;
12567
+ }
11536
12568
  const result = {
11537
12569
  ...event,
11538
- text: event.objectText
12570
+ response: event.responseId ? { id: event.responseId } : void 0
11539
12571
  };
11540
12572
  span.log({
11541
12573
  ...shouldRecordOutputs(event) ? {
@@ -11544,20 +12576,52 @@ function braintrustAISDKTelemetry() {
11544
12576
  metrics: extractTokenMetrics(result)
11545
12577
  });
11546
12578
  span.end();
11547
- objectSpans.delete(event.callId);
11548
12579
  });
11549
12580
  },
12581
+ onObjectStepStart(event) {
12582
+ runSafely("onObjectStepStart", () => {
12583
+ const operationKey = operationKeyFromEvent(event);
12584
+ const state = operationKey ? operations.get(operationKey) : void 0;
12585
+ if (shouldSkipTelemetryChildren(state)) {
12586
+ return;
12587
+ }
12588
+ const openSpan = operationKey ? objectSpans.get(operationKey) : void 0;
12589
+ if (operationKey && openSpan) {
12590
+ openSpan.end();
12591
+ objectSpans.delete(operationKey);
12592
+ }
12593
+ const span = startChildSpan(
12594
+ operationKey ?? event.callId,
12595
+ state?.operationName === "streamObject" ? "doStream" : "doGenerate",
12596
+ "llm" /* LLM */,
12597
+ {
12598
+ ...shouldRecordInputs(event) ? {
12599
+ input: {
12600
+ prompt: event.promptMessages
12601
+ }
12602
+ } : {},
12603
+ metadata: metadataFromEvent(event)
12604
+ }
12605
+ );
12606
+ objectSpans.set(operationKey ?? event.callId, span);
12607
+ });
12608
+ },
12609
+ onObjectStepEnd,
11550
12610
  onEmbedStart(event) {
11551
12611
  runSafely("onEmbedStart", () => {
11552
- const state = operations.get(event.callId);
12612
+ const operationKey = operationKeyFromEvent(event);
12613
+ const state = operationKey ? operations.get(operationKey) : void 0;
12614
+ if (shouldSkipTelemetryChildren(state)) {
12615
+ return;
12616
+ }
11553
12617
  for (const [embedCallId, embedState] of embedSpans) {
11554
- if (embedState.callId === event.callId && (state?.operationName === "embed" || embedState.values === event.values)) {
12618
+ if (embedState.operationKey === operationKey && (state?.operationName === "embed" || embedState.values === event.values)) {
11555
12619
  embedState.span.end();
11556
12620
  embedSpans.delete(embedCallId);
11557
12621
  }
11558
12622
  }
11559
12623
  const span = startChildSpan(
11560
- event.callId,
12624
+ operationKey ?? event.callId,
11561
12625
  "doEmbed",
11562
12626
  "llm" /* LLM */,
11563
12627
  {
@@ -11570,44 +12634,27 @@ function braintrustAISDKTelemetry() {
11570
12634
  }
11571
12635
  );
11572
12636
  embedSpans.set(event.embedCallId, {
11573
- callId: event.callId,
12637
+ operationKey: operationKey ?? event.callId,
11574
12638
  span,
11575
12639
  values: event.values
11576
12640
  });
11577
12641
  });
11578
12642
  },
11579
- onEmbedFinish(event) {
11580
- runSafely("onEmbedFinish", () => {
11581
- const state = embedSpans.get(event.embedCallId);
11582
- if (!state) {
11583
- return;
11584
- }
11585
- const result = {
11586
- ...event,
11587
- embeddings: event.embeddings
11588
- };
11589
- state.span.log({
11590
- ...shouldRecordOutputs(event) ? {
11591
- output: processAISDKEmbeddingOutput(
11592
- result,
11593
- DEFAULT_DENY_OUTPUT_PATHS
11594
- )
11595
- } : {},
11596
- metrics: extractTokenMetrics(result)
11597
- });
11598
- state.span.end();
11599
- embedSpans.delete(event.embedCallId);
11600
- });
11601
- },
12643
+ onEmbedEnd,
11602
12644
  onRerankStart(event) {
11603
12645
  runSafely("onRerankStart", () => {
11604
- const openSpan = rerankSpans.get(event.callId);
11605
- if (openSpan) {
12646
+ const operationKey = operationKeyFromEvent(event);
12647
+ const state = operationKey ? operations.get(operationKey) : void 0;
12648
+ if (shouldSkipTelemetryChildren(state)) {
12649
+ return;
12650
+ }
12651
+ const openSpan = operationKey ? rerankSpans.get(operationKey) : void 0;
12652
+ if (operationKey && openSpan) {
11606
12653
  openSpan.end();
11607
- rerankSpans.delete(event.callId);
12654
+ rerankSpans.delete(operationKey);
11608
12655
  }
11609
12656
  const span = startChildSpan(
11610
- event.callId,
12657
+ operationKey ?? event.callId,
11611
12658
  "doRerank",
11612
12659
  "llm" /* LLM */,
11613
12660
  {
@@ -11621,41 +12668,23 @@ function braintrustAISDKTelemetry() {
11621
12668
  metadata: metadataFromEvent(event)
11622
12669
  }
11623
12670
  );
11624
- rerankSpans.set(event.callId, span);
11625
- });
11626
- },
11627
- onRerankFinish(event) {
11628
- runSafely("onRerankFinish", () => {
11629
- const span = rerankSpans.get(event.callId);
11630
- if (!span) {
11631
- return;
11632
- }
11633
- const result = {
11634
- ranking: event.ranking?.map((entry) => ({
11635
- originalIndex: entry.index,
11636
- score: entry.relevanceScore
11637
- }))
11638
- };
11639
- span.log({
11640
- ...shouldRecordOutputs(event) ? {
11641
- output: processAISDKRerankOutput(
11642
- result,
11643
- DEFAULT_DENY_OUTPUT_PATHS
11644
- )
11645
- } : {}
11646
- });
11647
- span.end();
11648
- rerankSpans.delete(event.callId);
12671
+ rerankSpans.set(operationKey ?? event.callId, span);
11649
12672
  });
11650
12673
  },
12674
+ onRerankEnd,
11651
12675
  onToolExecutionStart(event) {
11652
12676
  runSafely("onToolExecutionStart", () => {
12677
+ const operationKey = operationKeyFromEvent(event);
12678
+ const state = operationKey ? operations.get(operationKey) : void 0;
12679
+ if (shouldSkipTelemetryChildren(state)) {
12680
+ return;
12681
+ }
11653
12682
  const toolCallId = event.toolCall.toolCallId;
11654
- if (!toolCallId) {
12683
+ if (!operationKey || !toolCallId) {
11655
12684
  return;
11656
12685
  }
11657
12686
  const span = startChildSpan(
11658
- event.callId,
12687
+ operationKey,
11659
12688
  event.toolCall.toolName || "tool",
11660
12689
  "tool" /* TOOL */,
11661
12690
  {
@@ -11669,7 +12698,7 @@ function braintrustAISDKTelemetry() {
11669
12698
  }
11670
12699
  }
11671
12700
  );
11672
- toolSpans.set(toolCallId, { callId: event.callId, span });
12701
+ toolSpans.set(toolCallId, { operationKey, span });
11673
12702
  });
11674
12703
  },
11675
12704
  onToolExecutionEnd(event) {
@@ -11680,14 +12709,17 @@ function braintrustAISDKTelemetry() {
11680
12709
  return;
11681
12710
  }
11682
12711
  const toolOutput = event.toolOutput;
11683
- if (toolOutput?.type === "tool-error") {
12712
+ const workflowToolError = event.success === false && "error" in event ? event.error : void 0;
12713
+ if (toolOutput?.type === "tool-error" || workflowToolError !== void 0) {
12714
+ const error = toolOutput?.error ?? workflowToolError;
11684
12715
  state.span.log({
11685
- error: toolOutput.error instanceof Error ? toolOutput.error.message : String(toolOutput?.error),
12716
+ error: error instanceof Error ? error.message : String(error),
11686
12717
  metrics: typeof event.durationMs === "number" ? { duration_ms: event.durationMs } : {}
11687
12718
  });
11688
12719
  } else {
12720
+ const output = toolOutput && "output" in toolOutput ? toolOutput.output : event.output;
11689
12721
  state.span.log({
11690
- ...shouldRecordOutputs(event) ? { output: toolOutput?.output } : {},
12722
+ ...shouldRecordOutputs(event) ? { output } : {},
11691
12723
  metrics: typeof event.durationMs === "number" ? { duration_ms: event.durationMs } : {}
11692
12724
  });
11693
12725
  }
@@ -11701,83 +12733,46 @@ function braintrustAISDKTelemetry() {
11701
12733
  if (!callId) {
11702
12734
  return;
11703
12735
  }
11704
- const state = operations.get(callId);
12736
+ const operationKey = operationKeyForCallId(callId);
12737
+ const state = operationKey ? operations.get(operationKey) : void 0;
11705
12738
  if (!state || state.firstChunkTime !== void 0) {
11706
12739
  return;
11707
12740
  }
11708
12741
  state.firstChunkTime = getCurrentUnixTimestamp();
11709
12742
  });
11710
12743
  },
11711
- onFinish(event) {
11712
- runSafely("onFinish", () => {
11713
- const state = operations.get(event.callId);
11714
- if (!state) {
12744
+ onEnd,
12745
+ onAbort(event) {
12746
+ runSafely("onAbort", () => {
12747
+ const operationKey = operationKeyFromEvent(event, "finish");
12748
+ const state = operationKey ? operations.get(operationKey) : void 0;
12749
+ if (!operationKey || !state) {
11715
12750
  return;
11716
12751
  }
11717
- const result = finishResult(event, state.operationName);
11718
- const metrics = state.hadModelChild ? {} : extractTokenMetrics(result);
11719
- if (state.firstChunkTime !== void 0) {
11720
- metrics.time_to_first_token = state.firstChunkTime - state.startTime;
12752
+ const error = abortReasonFromEvent(event);
12753
+ closeOpenChildSpans(operationKey, error);
12754
+ if (state.ownsSpan) {
12755
+ logError(state.span, error);
12756
+ state.span.end();
11721
12757
  }
11722
- state.span.log({
11723
- ...shouldRecordOutputs(event) ? {
11724
- output: finishOutput(result, state.operationName)
11725
- } : {},
11726
- metrics
11727
- });
11728
- state.span.end();
11729
- operations.delete(event.callId);
12758
+ deleteOperation(operationKey);
11730
12759
  });
11731
12760
  },
11732
12761
  onError(event) {
11733
12762
  runSafely("onError", () => {
11734
12763
  const errorEvent = isObject(event) ? event : {};
11735
- const callId = typeof errorEvent.callId === "string" ? errorEvent.callId : void 0;
11736
- if (!callId) {
11737
- return;
11738
- }
11739
- const state = operations.get(callId);
11740
- if (!state) {
12764
+ const operationKey = operationKeyFromEvent(errorEvent, "finish");
12765
+ const state = operationKey ? operations.get(operationKey) : void 0;
12766
+ if (!operationKey || !state) {
11741
12767
  return;
11742
12768
  }
11743
12769
  const error = errorEvent.error ?? event;
11744
- const openModelSpans = modelSpans.get(callId);
11745
- if (openModelSpans) {
11746
- for (const span of openModelSpans) {
11747
- logError(span, error);
11748
- span.end();
11749
- }
11750
- modelSpans.delete(callId);
11751
- }
11752
- const openObjectSpan = objectSpans.get(callId);
11753
- if (openObjectSpan) {
11754
- logError(openObjectSpan, error);
11755
- openObjectSpan.end();
11756
- objectSpans.delete(callId);
11757
- }
11758
- for (const [embedCallId, embedState] of embedSpans) {
11759
- if (embedState.callId === callId) {
11760
- logError(embedState.span, error);
11761
- embedState.span.end();
11762
- embedSpans.delete(embedCallId);
11763
- }
11764
- }
11765
- const openRerankSpan = rerankSpans.get(callId);
11766
- if (openRerankSpan) {
11767
- logError(openRerankSpan, error);
11768
- openRerankSpan.end();
11769
- rerankSpans.delete(callId);
11770
- }
11771
- for (const [toolCallId, toolState] of toolSpans) {
11772
- if (toolState.callId === callId) {
11773
- logError(toolState.span, error);
11774
- toolState.span.end();
11775
- toolSpans.delete(toolCallId);
11776
- }
12770
+ closeOpenChildSpans(operationKey, error);
12771
+ if (state.ownsSpan) {
12772
+ logError(state.span, error);
12773
+ state.span.end();
11777
12774
  }
11778
- logError(state.span, error);
11779
- state.span.end();
11780
- operations.delete(callId);
12775
+ deleteOperation(operationKey);
11781
12776
  });
11782
12777
  },
11783
12778
  executeTool({ toolCallId, execute }) {
@@ -11792,7 +12787,16 @@ function shouldRecordInputs(event) {
11792
12787
  function shouldRecordOutputs(event) {
11793
12788
  return event.recordOutputs !== false;
11794
12789
  }
12790
+ function hasPromptLikeInput(input) {
12791
+ if (!isObject(input)) {
12792
+ return false;
12793
+ }
12794
+ return input.prompt !== void 0 || input.messages !== void 0;
12795
+ }
11795
12796
  function operationNameFromId(operationId) {
12797
+ if (operationId === "ai.workflowAgent.stream") {
12798
+ return "WorkflowAgent.stream";
12799
+ }
11796
12800
  return operationId?.startsWith("ai.") ? operationId.slice("ai.".length) : operationId || "ai-sdk";
11797
12801
  }
11798
12802
  function modelFromEvent(event) {
@@ -11838,6 +12842,7 @@ function operationInput(event, operationName) {
11838
12842
  }
11839
12843
  return {
11840
12844
  model: modelFromEvent(event),
12845
+ instructions: event.instructions,
11841
12846
  system: event.system,
11842
12847
  prompt: event.prompt,
11843
12848
  messages: event.messages,
@@ -11886,6 +12891,30 @@ function finishResult(event, operationName) {
11886
12891
  }
11887
12892
  return event;
11888
12893
  }
12894
+ function extractTimeToFirstToken(result, state) {
12895
+ if (state.firstChunkTime !== void 0) {
12896
+ return state.firstChunkTime - state.startTime;
12897
+ }
12898
+ const performanceCandidates = [
12899
+ safePerformance(result),
12900
+ safePerformance(result.finalStep),
12901
+ ...Array.isArray(result.steps) ? (result.steps ?? []).map(safePerformance) : []
12902
+ ];
12903
+ for (const performance of performanceCandidates) {
12904
+ const timeToFirstOutputMs = performance?.timeToFirstOutputMs;
12905
+ if (typeof timeToFirstOutputMs === "number") {
12906
+ return timeToFirstOutputMs / 1e3;
12907
+ }
12908
+ }
12909
+ return void 0;
12910
+ }
12911
+ function safePerformance(value) {
12912
+ if (!isObject(value)) {
12913
+ return void 0;
12914
+ }
12915
+ const performance = value.performance;
12916
+ return isObject(performance) ? performance : void 0;
12917
+ }
11889
12918
  function finishOutput(result, operationName) {
11890
12919
  if (operationName === "embed" || operationName === "embedMany") {
11891
12920
  return processAISDKEmbeddingOutput(
@@ -11962,6 +12991,10 @@ var aiSDKChannels = defineChannels("ai", {
11962
12991
  channelName: "ToolLoopAgent.stream",
11963
12992
  kind: "async"
11964
12993
  }),
12994
+ workflowAgentStream: channel({
12995
+ channelName: "WorkflowAgent.stream",
12996
+ kind: "async"
12997
+ }),
11965
12998
  v7CreateTelemetryDispatcher: channel({
11966
12999
  channelName: "createTelemetryDispatcher",
11967
13000
  kind: "sync-stream"
@@ -11972,14 +13005,19 @@ var aiSDKChannels = defineChannels("ai", {
11972
13005
  var DEFAULT_DENY_OUTPUT_PATHS = [
11973
13006
  // v3
11974
13007
  "roundtrips[].request.body",
13008
+ "roundtrips[].request.headers",
11975
13009
  "roundtrips[].response.headers",
11976
13010
  "rawResponse.headers",
11977
13011
  "responseMessages",
11978
13012
  // v5
11979
13013
  "request.body",
13014
+ "request.headers",
13015
+ "responses[].headers",
11980
13016
  "response.body",
11981
13017
  "response.headers",
11982
13018
  "steps[].request.body",
13019
+ "steps[].request.headers",
13020
+ "steps[].responses[].headers",
11983
13021
  "steps[].response.body",
11984
13022
  "steps[].response.headers"
11985
13023
  ];
@@ -11991,6 +13029,18 @@ var AUTO_PATCHED_V7_TELEMETRY_DISPATCHER = /* @__PURE__ */ Symbol.for(
11991
13029
  var RUNTIME_DENY_OUTPUT_PATHS = /* @__PURE__ */ Symbol.for(
11992
13030
  "braintrust.ai-sdk.deny-output-paths"
11993
13031
  );
13032
+ var aiSDKV7TelemetryOperationCounter = 0;
13033
+ var TRANSPORT_PAYLOAD_ROOT_PATHS = [
13034
+ "rawResponse",
13035
+ "request",
13036
+ "response",
13037
+ "responses[]",
13038
+ "roundtrips[].request",
13039
+ "roundtrips[].response",
13040
+ "steps[].request",
13041
+ "steps[].response",
13042
+ "steps[].responses[]"
13043
+ ];
11994
13044
  var AI_SDK_V7_TELEMETRY_CALLBACKS = [
11995
13045
  "onStart",
11996
13046
  "onStepStart",
@@ -11999,14 +13049,16 @@ var AI_SDK_V7_TELEMETRY_CALLBACKS = [
11999
13049
  "onToolExecutionStart",
12000
13050
  "onToolExecutionEnd",
12001
13051
  "onChunk",
13052
+ "onStepEnd",
12002
13053
  "onStepFinish",
12003
13054
  "onObjectStepStart",
12004
- "onObjectStepFinish",
13055
+ "onObjectStepEnd",
12005
13056
  "onEmbedStart",
12006
- "onEmbedFinish",
13057
+ "onEmbedEnd",
12007
13058
  "onRerankStart",
12008
- "onRerankFinish",
12009
- "onFinish",
13059
+ "onRerankEnd",
13060
+ "onEnd",
13061
+ "onAbort",
12010
13062
  "onError"
12011
13063
  ];
12012
13064
  var AISDKPlugin = class extends BasePlugin {
@@ -12164,7 +13216,9 @@ var AISDKPlugin = class extends BasePlugin {
12164
13216
  traceStreamingChannel(aiSDKChannels.agentGenerate, {
12165
13217
  name: "Agent.generate",
12166
13218
  type: "function" /* FUNCTION */,
12167
- extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
13219
+ extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
13220
+ agentOwner: true
13221
+ }),
12168
13222
  extractOutput: (result, endEvent) => {
12169
13223
  finalizeAISDKChildTracing(endEvent);
12170
13224
  return processAISDKOutput(
@@ -12180,7 +13234,9 @@ var AISDKPlugin = class extends BasePlugin {
12180
13234
  traceStreamingChannel(aiSDKChannels.agentStream, {
12181
13235
  name: "Agent.stream",
12182
13236
  type: "function" /* FUNCTION */,
12183
- extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
13237
+ extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
13238
+ agentOwner: true
13239
+ }),
12184
13240
  extractOutput: (result, endEvent) => processAISDKOutput(
12185
13241
  result,
12186
13242
  resolveDenyOutputPaths(endEvent, denyOutputPaths)
@@ -12200,7 +13256,9 @@ var AISDKPlugin = class extends BasePlugin {
12200
13256
  traceSyncStreamChannel(aiSDKChannels.agentStreamSync, {
12201
13257
  name: "Agent.stream",
12202
13258
  type: "function" /* FUNCTION */,
12203
- extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
13259
+ extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
13260
+ agentOwner: true
13261
+ }),
12204
13262
  patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
12205
13263
  defaultDenyOutputPaths: denyOutputPaths,
12206
13264
  endEvent,
@@ -12214,7 +13272,9 @@ var AISDKPlugin = class extends BasePlugin {
12214
13272
  traceStreamingChannel(aiSDKChannels.toolLoopAgentGenerate, {
12215
13273
  name: "ToolLoopAgent.generate",
12216
13274
  type: "function" /* FUNCTION */,
12217
- extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
13275
+ extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
13276
+ agentOwner: true
13277
+ }),
12218
13278
  extractOutput: (result, endEvent) => {
12219
13279
  finalizeAISDKChildTracing(endEvent);
12220
13280
  return processAISDKOutput(
@@ -12230,7 +13290,9 @@ var AISDKPlugin = class extends BasePlugin {
12230
13290
  traceStreamingChannel(aiSDKChannels.toolLoopAgentStream, {
12231
13291
  name: "ToolLoopAgent.stream",
12232
13292
  type: "function" /* FUNCTION */,
12233
- extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
13293
+ extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
13294
+ agentOwner: true
13295
+ }),
12234
13296
  extractOutput: (result, endEvent) => processAISDKOutput(
12235
13297
  result,
12236
13298
  resolveDenyOutputPaths(endEvent, denyOutputPaths)
@@ -12246,6 +13308,42 @@ var AISDKPlugin = class extends BasePlugin {
12246
13308
  })
12247
13309
  })
12248
13310
  );
13311
+ this.unsubscribers.push(
13312
+ traceStreamingChannel(aiSDKChannels.workflowAgentStream, {
13313
+ name: "WorkflowAgent.stream",
13314
+ type: "function" /* FUNCTION */,
13315
+ extractInput: ([params], event, span) => prepareAISDKWorkflowAgentStreamInput(
13316
+ params,
13317
+ event,
13318
+ span,
13319
+ denyOutputPaths
13320
+ ),
13321
+ extractOutput: (result, endEvent) => {
13322
+ finalizeAISDKChildTracing(endEvent);
13323
+ return processAISDKOutput(
13324
+ result,
13325
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
13326
+ );
13327
+ },
13328
+ extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
13329
+ aggregateChunks: aggregateAISDKChunks,
13330
+ onComplete: ({ span }) => {
13331
+ unregisterWorkflowAgentWrapperSpan(span);
13332
+ },
13333
+ onError: ({ event, span }) => {
13334
+ finalizeAISDKChildTracing(event);
13335
+ unregisterWorkflowAgentWrapperSpan(span);
13336
+ },
13337
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
13338
+ defaultDenyOutputPaths: denyOutputPaths,
13339
+ endEvent,
13340
+ onComplete: () => unregisterWorkflowAgentWrapperSpan(span),
13341
+ result,
13342
+ span,
13343
+ startTime
13344
+ })
13345
+ })
13346
+ );
12249
13347
  }
12250
13348
  };
12251
13349
  function subscribeToAISDKV7TelemetryDispatcher() {
@@ -12257,7 +13355,11 @@ function subscribeToAISDKV7TelemetryDispatcher() {
12257
13355
  if (telemetryOptions?.isEnabled === false) {
12258
13356
  return;
12259
13357
  }
12260
- patchAISDKV7TelemetryDispatcher(event.result, telemetry);
13358
+ patchAISDKV7TelemetryDispatcher(
13359
+ event.result,
13360
+ telemetry,
13361
+ telemetryOptions
13362
+ );
12261
13363
  }
12262
13364
  };
12263
13365
  channel2.subscribe(handlers);
@@ -12265,7 +13367,7 @@ function subscribeToAISDKV7TelemetryDispatcher() {
12265
13367
  channel2.unsubscribe(handlers);
12266
13368
  };
12267
13369
  }
12268
- function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry) {
13370
+ function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry, telemetryOptions) {
12269
13371
  if (!isObject(dispatcher)) {
12270
13372
  return;
12271
13373
  }
@@ -12274,6 +13376,54 @@ function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry) {
12274
13376
  return;
12275
13377
  }
12276
13378
  dispatcherRecord[AUTO_PATCHED_V7_TELEMETRY_DISPATCHER] = true;
13379
+ let operationKey;
13380
+ const telemetryEventFields = {};
13381
+ if (typeof telemetryOptions?.recordInputs === "boolean") {
13382
+ telemetryEventFields.recordInputs = telemetryOptions.recordInputs;
13383
+ }
13384
+ if (typeof telemetryOptions?.recordOutputs === "boolean") {
13385
+ telemetryEventFields.recordOutputs = telemetryOptions.recordOutputs;
13386
+ }
13387
+ if (typeof telemetryOptions?.functionId === "string") {
13388
+ telemetryEventFields.functionId = telemetryOptions.functionId;
13389
+ }
13390
+ const eventWithOperationKey = (event) => {
13391
+ if (!isObject(event)) {
13392
+ return event;
13393
+ }
13394
+ const eventRecord = event;
13395
+ const callId = typeof eventRecord.callId === "string" ? eventRecord.callId : "unknown";
13396
+ operationKey ??= `${callId}:${++aiSDKV7TelemetryOperationCounter}`;
13397
+ if (Object.keys(telemetryEventFields).length > 0) {
13398
+ const augmentedEvent = {
13399
+ ...telemetryEventFields,
13400
+ ...event
13401
+ };
13402
+ try {
13403
+ Object.defineProperty(augmentedEvent, BRAINTRUST_AI_SDK_V7_OPERATION_KEY, {
13404
+ configurable: true,
13405
+ enumerable: false,
13406
+ value: operationKey
13407
+ });
13408
+ } catch {
13409
+ augmentedEvent[BRAINTRUST_AI_SDK_V7_OPERATION_KEY] = operationKey;
13410
+ }
13411
+ return augmentedEvent;
13412
+ }
13413
+ try {
13414
+ Object.defineProperty(eventRecord, BRAINTRUST_AI_SDK_V7_OPERATION_KEY, {
13415
+ configurable: true,
13416
+ enumerable: false,
13417
+ value: operationKey
13418
+ });
13419
+ return event;
13420
+ } catch {
13421
+ return {
13422
+ ...event,
13423
+ [BRAINTRUST_AI_SDK_V7_OPERATION_KEY]: operationKey
13424
+ };
13425
+ }
13426
+ };
12277
13427
  for (const key of AI_SDK_V7_TELEMETRY_CALLBACKS) {
12278
13428
  const braintrustCallback = telemetry[key];
12279
13429
  if (typeof braintrustCallback !== "function") {
@@ -12282,11 +13432,17 @@ function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry) {
12282
13432
  const existingCallback = dispatcherRecord[key];
12283
13433
  dispatcherRecord[key] = (event) => {
12284
13434
  const existingResult = typeof existingCallback === "function" ? existingCallback.call(dispatcher, event) : void 0;
12285
- const braintrustResult = braintrustCallback.call(telemetry, event);
12286
- const pending = [existingResult, braintrustResult].filter(isPromiseLike);
12287
- if (pending.length > 0) {
12288
- return Promise.allSettled(pending).then(() => void 0);
13435
+ try {
13436
+ const braintrustResult = braintrustCallback.call(
13437
+ telemetry,
13438
+ eventWithOperationKey(event)
13439
+ );
13440
+ if (isPromiseLike(braintrustResult)) {
13441
+ void Promise.resolve(braintrustResult).catch(() => void 0);
13442
+ }
13443
+ } catch {
12289
13444
  }
13445
+ return existingResult;
12290
13446
  };
12291
13447
  }
12292
13448
  const braintrustExecuteTool = telemetry.executeTool;
@@ -12296,6 +13452,7 @@ function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry) {
12296
13452
  const existingExecuteTool = dispatcherRecord.executeTool;
12297
13453
  dispatcherRecord.executeTool = (args) => braintrustExecuteTool.call(telemetry, {
12298
13454
  ...args,
13455
+ ...operationKey ? { [BRAINTRUST_AI_SDK_V7_OPERATION_KEY]: operationKey } : {},
12299
13456
  execute: () => typeof existingExecuteTool === "function" ? existingExecuteTool.call(dispatcher, args) : args.execute()
12300
13457
  });
12301
13458
  }
@@ -12394,6 +13551,8 @@ var serializeOutputObject = (output, model) => {
12394
13551
  var processInputAttachmentsSync = (input) => {
12395
13552
  if (!input) return { input };
12396
13553
  const processed = { ...input };
13554
+ delete processed.headers;
13555
+ delete processed.experimental_output;
12397
13556
  if (input.messages && Array.isArray(input.messages)) {
12398
13557
  processed.messages = input.messages.map(processMessage);
12399
13558
  }
@@ -12427,10 +13586,10 @@ var processInputAttachmentsSync = (input) => {
12427
13586
  processed.output = serialized;
12428
13587
  }
12429
13588
  }
12430
- if ("prepareCall" in processed && typeof processed.prepareCall === "function") {
12431
- processed.prepareCall = "[Function]";
12432
- }
12433
- return { input: processed, outputPromise };
13589
+ return {
13590
+ input: sanitizeAISDKCallInputValue(processed),
13591
+ outputPromise
13592
+ };
12434
13593
  };
12435
13594
  var processMessage = (message) => {
12436
13595
  if (!message || typeof message !== "object") return message;
@@ -12594,7 +13753,21 @@ var convertDataToAttachment = (data, mimeType, filename) => {
12594
13753
  function processAISDKCallInput(params) {
12595
13754
  return processInputAttachmentsSync(params);
12596
13755
  }
12597
- function prepareAISDKCallInput(params, event, span, defaultDenyOutputPaths) {
13756
+ function processAISDKWorkflowAgentCallInput(params) {
13757
+ const processed = processAISDKCallInput(params);
13758
+ return {
13759
+ ...processed,
13760
+ input: extractWorkflowAgentInput(processed.input)
13761
+ };
13762
+ }
13763
+ function processAISDKWorkflowAgentModelCallInput(params) {
13764
+ const processed = processAISDKCallInput(params);
13765
+ return {
13766
+ ...processed,
13767
+ input: extractWorkflowAgentModelInput(processed.input)
13768
+ };
13769
+ }
13770
+ function prepareAISDKCallInput(params, event, span, defaultDenyOutputPaths, childTracingOptions = {}) {
12598
13771
  const { input, outputPromise } = processAISDKCallInput(params);
12599
13772
  if (outputPromise && input && typeof input === "object") {
12600
13773
  outputPromise.then((resolvedData) => {
@@ -12613,7 +13786,29 @@ function prepareAISDKCallInput(params, event, span, defaultDenyOutputPaths) {
12613
13786
  event.self,
12614
13787
  span,
12615
13788
  defaultDenyOutputPaths,
12616
- event.aiSDK
13789
+ event.aiSDK,
13790
+ childTracingOptions
13791
+ );
13792
+ event.modelWrapped = childTracing.modelWrapped;
13793
+ if (childTracing.cleanup) {
13794
+ event.__braintrust_ai_sdk_cleanup = childTracing.cleanup;
13795
+ }
13796
+ return {
13797
+ input,
13798
+ metadata
13799
+ };
13800
+ }
13801
+ function prepareAISDKWorkflowAgentStreamInput(params, event, span, defaultDenyOutputPaths) {
13802
+ registerWorkflowAgentWrapperSpan(span);
13803
+ const { input } = processAISDKWorkflowAgentCallInput(params);
13804
+ const metadata = extractWorkflowMetadataFromCallParams(params, event.self);
13805
+ const childTracing = prepareAISDKChildTracing(
13806
+ params,
13807
+ event.self,
13808
+ span,
13809
+ defaultDenyOutputPaths,
13810
+ event.aiSDK,
13811
+ { agentOwner: true, workflowAgent: true }
12617
13812
  );
12618
13813
  event.modelWrapped = childTracing.modelWrapped;
12619
13814
  if (childTracing.cleanup) {
@@ -12650,6 +13845,9 @@ function extractTopLevelAISDKMetrics(result, event, startTime) {
12650
13845
  function hasModelChildTracing(event) {
12651
13846
  return event?.modelWrapped === true || event?.__braintrust_ai_sdk_model_wrapped === true;
12652
13847
  }
13848
+ function serializeToolExecutionInput(args) {
13849
+ return args.length > 0 ? args[0] : args;
13850
+ }
12653
13851
  function createAISDKIntegrationMetadata() {
12654
13852
  return {
12655
13853
  braintrust: {
@@ -12661,6 +13859,13 @@ function createAISDKIntegrationMetadata() {
12661
13859
  function resolveModelFromSelf(self) {
12662
13860
  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;
12663
13861
  }
13862
+ function resolveToolsFromSelf(self) {
13863
+ if (!self || typeof self !== "object") {
13864
+ return void 0;
13865
+ }
13866
+ const selfRecord = self;
13867
+ return selfRecord.tools ?? selfRecord.settings?.tools;
13868
+ }
12664
13869
  function extractBaseMetadata(model, self) {
12665
13870
  const metadata = createAISDKIntegrationMetadata();
12666
13871
  const { model: modelId, provider } = serializeModelWithProvider(
@@ -12676,12 +13881,175 @@ function extractBaseMetadata(model, self) {
12676
13881
  }
12677
13882
  function extractMetadataFromCallParams(params, self) {
12678
13883
  const metadata = extractBaseMetadata(params.model, self);
12679
- const tools = serializeAISDKToolsForLogging(params.tools);
13884
+ const tools = serializeAISDKToolsForLogging(
13885
+ params.tools ?? resolveToolsFromSelf(self)
13886
+ );
12680
13887
  if (tools) {
12681
13888
  metadata.tools = tools;
12682
13889
  }
12683
13890
  return metadata;
12684
13891
  }
13892
+ function extractWorkflowMetadataFromCallParams(params, self) {
13893
+ const metadata = extractMetadataFromCallParams(params, self);
13894
+ const options = extractAISDKCallOptionsForMetadata(params);
13895
+ if (Object.keys(options).length > 0) {
13896
+ metadata.options = options;
13897
+ }
13898
+ return metadata;
13899
+ }
13900
+ function extractWorkflowAgentInput(params) {
13901
+ const input = {};
13902
+ if (params.instructions !== void 0) {
13903
+ input.instructions = params.instructions;
13904
+ }
13905
+ if (params.system !== void 0) {
13906
+ input.system = params.system;
13907
+ }
13908
+ if (Array.isArray(params.messages)) {
13909
+ return { ...input, messages: params.messages };
13910
+ }
13911
+ if (typeof params.prompt === "string") {
13912
+ return { ...input, prompt: params.prompt };
13913
+ }
13914
+ if (Array.isArray(params.prompt)) {
13915
+ return { ...input, prompt: params.prompt };
13916
+ }
13917
+ return input;
13918
+ }
13919
+ function extractWorkflowAgentModelInput(params) {
13920
+ const input = {};
13921
+ if (params.instructions !== void 0) {
13922
+ input.instructions = params.instructions;
13923
+ }
13924
+ if (params.system !== void 0) {
13925
+ input.system = params.system;
13926
+ }
13927
+ if (Array.isArray(params.messages)) {
13928
+ return { ...input, messages: params.messages };
13929
+ }
13930
+ if (typeof params.prompt === "string") {
13931
+ return { ...input, prompt: params.prompt };
13932
+ }
13933
+ if (Array.isArray(params.prompt)) {
13934
+ return { ...input, messages: params.prompt };
13935
+ }
13936
+ return input;
13937
+ }
13938
+ function sanitizeAISDKCallInputValue(value, depth = 0) {
13939
+ if (value === void 0 || typeof value === "function") {
13940
+ return void 0;
13941
+ }
13942
+ if (value === null || typeof value !== "object") {
13943
+ return value;
13944
+ }
13945
+ if (isPromiseLike(value)) {
13946
+ return "[Promise]";
13947
+ }
13948
+ if (typeof AbortSignal !== "undefined" && value instanceof AbortSignal) {
13949
+ return "[AbortSignal]";
13950
+ }
13951
+ if (depth >= 8) {
13952
+ return "[Object]";
13953
+ }
13954
+ if (Array.isArray(value)) {
13955
+ return value.map((item) => sanitizeAISDKCallInputValue(item, depth + 1)).filter((item) => item !== void 0);
13956
+ }
13957
+ if (!isObject(value)) {
13958
+ return value;
13959
+ }
13960
+ const prototype = Object.getPrototypeOf(value);
13961
+ if (prototype !== Object.prototype && prototype !== null) {
13962
+ return value;
13963
+ }
13964
+ const sanitized = {};
13965
+ for (const [key, nested] of Object.entries(value)) {
13966
+ if (key === "__proto__" || key === "constructor" || key === "prototype" || key.toLowerCase() === "headers") {
13967
+ continue;
13968
+ }
13969
+ const sanitizedNested = sanitizeAISDKCallInputValue(nested, depth + 1);
13970
+ if (sanitizedNested !== void 0) {
13971
+ sanitized[key] = sanitizedNested;
13972
+ }
13973
+ }
13974
+ return sanitized;
13975
+ }
13976
+ function extractAISDKCallOptionsForMetadata(params) {
13977
+ const options = {};
13978
+ const inputOrTopLevelKeys = /* @__PURE__ */ new Set([
13979
+ "model",
13980
+ "instructions",
13981
+ "messages",
13982
+ "prompt",
13983
+ "system",
13984
+ "tools",
13985
+ "headers",
13986
+ "abortSignal",
13987
+ "signal",
13988
+ "experimental_output"
13989
+ ]);
13990
+ for (const [key, value] of Object.entries(params)) {
13991
+ if (inputOrTopLevelKeys.has(key) || key === "__proto__" || key === "constructor" || key === "prototype" || /^on[A-Z]/.test(key) && typeof value === "function") {
13992
+ continue;
13993
+ }
13994
+ const sanitized = sanitizeAISDKMetadataValue(value);
13995
+ if (sanitized !== void 0) {
13996
+ options[key] = sanitized;
13997
+ }
13998
+ }
13999
+ return options;
14000
+ }
14001
+ function sanitizeAISDKMetadataValue(value, depth = 0) {
14002
+ if (value === void 0) {
14003
+ return void 0;
14004
+ }
14005
+ if (typeof value === "function") {
14006
+ return "[Function]";
14007
+ }
14008
+ if (value === null || typeof value !== "object") {
14009
+ return value;
14010
+ }
14011
+ if (isPromiseLike(value)) {
14012
+ return "[Promise]";
14013
+ }
14014
+ if (typeof AbortSignal !== "undefined" && value instanceof AbortSignal) {
14015
+ return "[AbortSignal]";
14016
+ }
14017
+ if (depth >= 8) {
14018
+ return "[Object]";
14019
+ }
14020
+ if (Array.isArray(value)) {
14021
+ return value.map((item) => sanitizeAISDKMetadataValue(item, depth + 1)).filter((item) => item !== void 0);
14022
+ }
14023
+ if (!isObject(value)) {
14024
+ return value;
14025
+ }
14026
+ const sanitized = {};
14027
+ for (const [key, nested] of Object.entries(value)) {
14028
+ if (key === "__proto__" || key === "constructor" || key === "prototype" || key.toLowerCase() === "headers") {
14029
+ continue;
14030
+ }
14031
+ const sanitizedNested = sanitizeAISDKMetadataValue(nested, depth + 1);
14032
+ if (sanitizedNested !== void 0) {
14033
+ sanitized[key] = sanitizedNested;
14034
+ }
14035
+ }
14036
+ return sanitized;
14037
+ }
14038
+ function buildAISDKModelStartEvent(callOptions, baseMetadata, options) {
14039
+ if (!options.workflowAgent) {
14040
+ return {
14041
+ input: processAISDKCallInput(callOptions).input,
14042
+ metadata: baseMetadata
14043
+ };
14044
+ }
14045
+ return {
14046
+ input: processAISDKWorkflowAgentModelCallInput(callOptions).input,
14047
+ metadata: {
14048
+ ...baseMetadata,
14049
+ ...extractWorkflowMetadataFromCallParams(callOptions)
14050
+ }
14051
+ };
14052
+ }
12685
14053
  function extractMetadataFromEmbedParams(params, self) {
12686
14054
  return extractBaseMetadata(params.model, self);
12687
14055
  }
@@ -12695,65 +14063,228 @@ function extractMetadataFromRerankParams(params, self) {
12695
14063
  }
12696
14064
  return metadata;
12697
14065
  }
12698
- function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiSDK) {
14066
+ function activeAISDKChildPatchEntry(entries) {
14067
+ const activeSpan = currentSpan();
14068
+ const activeSpanId = activeSpan.spanId;
14069
+ if (activeSpanId) {
14070
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
14071
+ const entry = entries[index];
14072
+ if (entry?.activeSpanIds.has(activeSpanId)) {
14073
+ return entry;
14074
+ }
14075
+ }
14076
+ }
14077
+ const activeParentSpanIds = activeSpan.spanParents ?? [];
14078
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
14079
+ const entry = entries[index];
14080
+ if (entry?.parentSpan.spanId && activeParentSpanIds.includes(entry.parentSpan.spanId)) {
14081
+ return entry;
14082
+ }
14083
+ }
14084
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
14085
+ const entry = entries[index];
14086
+ if (entry?.parentSpan.spanId === activeSpanId) {
14087
+ return entry;
14088
+ }
14089
+ }
14090
+ return entries[entries.length - 1];
14091
+ }
14092
+ function attachNestedAISDKChildPatchEntry(entries, nestedSpan, cleanup) {
14093
+ const activeSpanId = currentSpan().spanId;
14094
+ if (!activeSpanId || activeSpanId === nestedSpan.spanId) {
14095
+ return false;
14096
+ }
14097
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
14098
+ const entry = entries[index];
14099
+ if (entry?.parentSpan.spanId === activeSpanId || entry?.activeSpanIds.has(activeSpanId)) {
14100
+ entry.activeSpanIds.add(nestedSpan.spanId);
14101
+ cleanup.push(() => {
14102
+ entry.activeSpanIds.delete(nestedSpan.spanId);
14103
+ });
14104
+ return true;
14105
+ }
14106
+ }
14107
+ return false;
14108
+ }
14109
+ function shadowActiveAISDKChildPatchEntry(entries, entry, nestedSpan, cleanup) {
14110
+ const activeSpanId = currentSpan().spanId;
14111
+ if (!activeSpanId || activeSpanId === nestedSpan.spanId) {
14112
+ return;
14113
+ }
14114
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
14115
+ const existingEntry = entries[index];
14116
+ if (existingEntry?.parentSpan.spanId === activeSpanId || existingEntry?.activeSpanIds.has(activeSpanId)) {
14117
+ entry.activeSpanIds.add(activeSpanId);
14118
+ cleanup.push(() => {
14119
+ entry.activeSpanIds.delete(activeSpanId);
14120
+ });
14121
+ return;
14122
+ }
14123
+ }
14124
+ }
14125
+ function closeOpenAISDKModelPatchSpans(entry) {
14126
+ for (const span of entry.openSpans) {
14127
+ span.end();
14128
+ }
14129
+ entry.openSpans.clear();
14130
+ }
14131
+ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiSDK, childTracingOptions = {}) {
12699
14132
  const cleanup = [];
12700
- const patchedModels = /* @__PURE__ */ new WeakSet();
14133
+ const patchedModels = /* @__PURE__ */ new WeakMap();
12701
14134
  const patchedTools = /* @__PURE__ */ new WeakSet();
12702
14135
  let modelWrapped = false;
12703
14136
  const patchModel = (model) => {
12704
14137
  const resolvedModel = resolveAISDKModel(model, aiSDK);
12705
- if (!resolvedModel || typeof resolvedModel !== "object" || typeof resolvedModel.doGenerate !== "function" || patchedModels.has(resolvedModel) || resolvedModel[AUTO_PATCHED_MODEL]) {
14138
+ if (!resolvedModel || typeof resolvedModel !== "object" || typeof resolvedModel.doGenerate !== "function") {
12706
14139
  return resolvedModel;
12707
14140
  }
12708
- patchedModels.add(resolvedModel);
12709
- resolvedModel[AUTO_PATCHED_MODEL] = true;
14141
+ const existingWrappedModel = patchedModels.get(resolvedModel);
14142
+ if (existingWrappedModel) {
14143
+ modelWrapped = true;
14144
+ return existingWrappedModel;
14145
+ }
12710
14146
  modelWrapped = true;
14147
+ const modelRecord = resolvedModel;
14148
+ const entry = {
14149
+ activeSpanIds: /* @__PURE__ */ new Set([parentSpan.spanId]),
14150
+ baseMetadata: buildAISDKChildMetadata(resolvedModel),
14151
+ childTracingOptions,
14152
+ denyOutputPaths,
14153
+ openSpans: /* @__PURE__ */ new Set(),
14154
+ parentSpan
14155
+ };
14156
+ const cleanupModelEntry = (state2, patchedModel) => {
14157
+ closeOpenAISDKModelPatchSpans(entry);
14158
+ const index = state2.entries.indexOf(entry);
14159
+ if (index >= 0) {
14160
+ state2.entries.splice(index, 1);
14161
+ }
14162
+ if (state2.entries.length > 0) {
14163
+ return;
14164
+ }
14165
+ patchedModel.doGenerate = state2.originalDoGenerate;
14166
+ patchedModel.doStream = state2.originalDoStream;
14167
+ delete patchedModel[AUTO_PATCHED_MODEL];
14168
+ };
14169
+ const existingState = modelRecord[AUTO_PATCHED_MODEL];
14170
+ if (existingState) {
14171
+ patchedModels.set(resolvedModel, resolvedModel);
14172
+ if (childTracingOptions.agentOwner && attachNestedAISDKChildPatchEntry(
14173
+ existingState.entries,
14174
+ parentSpan,
14175
+ cleanup
14176
+ )) {
14177
+ return resolvedModel;
14178
+ }
14179
+ if (!childTracingOptions.agentOwner) {
14180
+ shadowActiveAISDKChildPatchEntry(
14181
+ existingState.entries,
14182
+ entry,
14183
+ parentSpan,
14184
+ cleanup
14185
+ );
14186
+ }
14187
+ existingState.entries.push(entry);
14188
+ cleanup.push(() => {
14189
+ cleanupModelEntry(existingState, modelRecord);
14190
+ });
14191
+ return resolvedModel;
14192
+ }
12711
14193
  const originalDoGenerate = resolvedModel.doGenerate;
12712
14194
  const originalDoStream = resolvedModel.doStream;
12713
- const baseMetadata = buildAISDKChildMetadata(resolvedModel);
12714
- resolvedModel.doGenerate = async function doGeneratePatched(options) {
12715
- return parentSpan.traced(
12716
- async (span) => {
12717
- const result = await Reflect.apply(
12718
- originalDoGenerate,
12719
- resolvedModel,
12720
- [options]
12721
- );
12722
- span.log({
12723
- output: processAISDKOutput(result, denyOutputPaths),
12724
- metrics: extractTokenMetrics(result),
12725
- ...buildResolvedMetadataPayload(result)
12726
- });
12727
- return result;
14195
+ const wrappedModel = Object.create(
14196
+ Object.getPrototypeOf(resolvedModel)
14197
+ );
14198
+ Object.defineProperties(
14199
+ wrappedModel,
14200
+ Object.getOwnPropertyDescriptors(resolvedModel)
14201
+ );
14202
+ const wrappedModelRecord = wrappedModel;
14203
+ const state = {
14204
+ entries: [entry],
14205
+ originalDoGenerate,
14206
+ originalDoStream
14207
+ };
14208
+ Object.defineProperty(wrappedModel, AUTO_PATCHED_MODEL, {
14209
+ configurable: true,
14210
+ value: state
14211
+ });
14212
+ wrappedModel.doGenerate = async function doGeneratePatched(callOptions) {
14213
+ const activeEntry = activeAISDKChildPatchEntry(state.entries);
14214
+ if (!activeEntry) {
14215
+ return Reflect.apply(originalDoGenerate, resolvedModel, [callOptions]);
14216
+ }
14217
+ closeOpenAISDKModelPatchSpans(activeEntry);
14218
+ return activeEntry.parentSpan.traced(
14219
+ async (span) => {
14220
+ activeEntry.openSpans.add(span);
14221
+ try {
14222
+ const result = await Reflect.apply(
14223
+ originalDoGenerate,
14224
+ resolvedModel,
14225
+ [callOptions]
14226
+ );
14227
+ const output = processAISDKOutput(
14228
+ result,
14229
+ activeEntry.denyOutputPaths
14230
+ );
14231
+ const metrics = extractTokenMetrics(result);
14232
+ const metadataPayload = buildResolvedMetadataPayload(result);
14233
+ const missingUsageMetadata = buildMissingUsageMetadata(
14234
+ output,
14235
+ metrics,
14236
+ "ai_sdk_result_missing_usage"
14237
+ );
14238
+ span.log({
14239
+ output,
14240
+ metrics,
14241
+ ...mergeMetadataPayload(metadataPayload, missingUsageMetadata)
14242
+ });
14243
+ return result;
14244
+ } finally {
14245
+ activeEntry.openSpans.delete(span);
14246
+ }
12728
14247
  },
12729
14248
  {
12730
14249
  name: "doGenerate",
12731
14250
  spanAttributes: {
12732
14251
  type: "llm" /* LLM */
12733
14252
  },
12734
- event: {
12735
- input: processAISDKCallInput(options).input,
12736
- metadata: baseMetadata
12737
- }
14253
+ event: buildAISDKModelStartEvent(
14254
+ callOptions,
14255
+ activeEntry.baseMetadata,
14256
+ {
14257
+ workflowAgent: activeEntry.childTracingOptions.workflowAgent
14258
+ }
14259
+ )
12738
14260
  }
12739
14261
  );
12740
14262
  };
12741
14263
  if (originalDoStream) {
12742
- resolvedModel.doStream = async function doStreamPatched(options) {
12743
- const span = parentSpan.startSpan({
14264
+ wrappedModel.doStream = async function doStreamPatched(callOptions) {
14265
+ const activeEntry = activeAISDKChildPatchEntry(state.entries);
14266
+ if (!activeEntry) {
14267
+ return Reflect.apply(originalDoStream, resolvedModel, [callOptions]);
14268
+ }
14269
+ closeOpenAISDKModelPatchSpans(activeEntry);
14270
+ const span = activeEntry.parentSpan.startSpan({
12744
14271
  name: "doStream",
12745
14272
  spanAttributes: {
12746
14273
  type: "llm" /* LLM */
12747
14274
  },
12748
- event: {
12749
- input: processAISDKCallInput(options).input,
12750
- metadata: baseMetadata
12751
- }
14275
+ event: buildAISDKModelStartEvent(
14276
+ callOptions,
14277
+ activeEntry.baseMetadata,
14278
+ {
14279
+ workflowAgent: activeEntry.childTracingOptions.workflowAgent
14280
+ }
14281
+ )
12752
14282
  });
14283
+ activeEntry.openSpans.add(span);
12753
14284
  const streamStartTime = getCurrentUnixTimestamp();
12754
14285
  const result = await withCurrent(
12755
14286
  span,
12756
- () => Reflect.apply(originalDoStream, resolvedModel, [options])
14287
+ () => Reflect.apply(originalDoStream, resolvedModel, [callOptions])
12757
14288
  );
12758
14289
  let firstChunkTime;
12759
14290
  const output = {};
@@ -12761,6 +14292,44 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
12761
14292
  let reasoning = "";
12762
14293
  const toolCalls = [];
12763
14294
  let object = void 0;
14295
+ let streamSpanEnded = false;
14296
+ const logAndEndStreamSpan = (usageUnavailableReason) => {
14297
+ if (streamSpanEnded) {
14298
+ return;
14299
+ }
14300
+ output.text = text;
14301
+ output.reasoning = reasoning;
14302
+ output.toolCalls = toolCalls;
14303
+ if (object !== void 0) {
14304
+ output.object = object;
14305
+ }
14306
+ const metrics = extractTokenMetrics(output);
14307
+ if (firstChunkTime !== void 0 && !activeEntry.childTracingOptions.workflowAgent) {
14308
+ metrics.time_to_first_token = Math.max(
14309
+ firstChunkTime - streamStartTime,
14310
+ 1e-6
14311
+ );
14312
+ }
14313
+ const metadataPayload = buildResolvedMetadataPayload(
14314
+ output
14315
+ );
14316
+ const missingUsageMetadata = usageUnavailableReason ? { usage_unavailable_reason: usageUnavailableReason } : buildMissingUsageMetadata(
14317
+ output,
14318
+ metrics,
14319
+ "ai_sdk_result_missing_usage"
14320
+ );
14321
+ span.log({
14322
+ output: processAISDKOutput(
14323
+ output,
14324
+ activeEntry.denyOutputPaths
14325
+ ),
14326
+ metrics,
14327
+ ...mergeMetadataPayload(metadataPayload, missingUsageMetadata)
14328
+ });
14329
+ activeEntry.openSpans.delete(span);
14330
+ span.end();
14331
+ streamSpanEnded = true;
14332
+ };
12764
14333
  const transformStream = new TransformStream({
12765
14334
  transform(chunk, controller) {
12766
14335
  if (firstChunkTime === void 0 && isAISDKContentStreamChunk(chunk)) {
@@ -12798,33 +14367,15 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
12798
14367
  }
12799
14368
  break;
12800
14369
  case "finish":
12801
- output.text = text;
12802
- output.reasoning = reasoning;
12803
- output.toolCalls = toolCalls;
12804
14370
  output.finishReason = chunk.finishReason;
12805
14371
  output.usage = chunk.usage;
12806
- if (object !== void 0) {
12807
- output.object = object;
12808
- }
12809
- const metrics = extractTokenMetrics(output);
12810
- if (firstChunkTime !== void 0) {
12811
- metrics.time_to_first_token = Math.max(
12812
- firstChunkTime - streamStartTime,
12813
- 1e-6
12814
- );
12815
- }
12816
- span.log({
12817
- output: processAISDKOutput(
12818
- output,
12819
- denyOutputPaths
12820
- ),
12821
- metrics,
12822
- ...buildResolvedMetadataPayload(output)
12823
- });
12824
- span.end();
14372
+ logAndEndStreamSpan();
12825
14373
  break;
12826
14374
  }
12827
14375
  controller.enqueue(chunk);
14376
+ },
14377
+ flush() {
14378
+ logAndEndStreamSpan("ai_sdk_stream_finished_without_usage");
12828
14379
  }
12829
14380
  });
12830
14381
  return {
@@ -12834,32 +14385,79 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
12834
14385
  };
12835
14386
  }
12836
14387
  cleanup.push(() => {
12837
- resolvedModel.doGenerate = originalDoGenerate;
12838
- if (originalDoStream) {
12839
- resolvedModel.doStream = originalDoStream;
12840
- }
12841
- delete resolvedModel[AUTO_PATCHED_MODEL];
14388
+ cleanupModelEntry(state, wrappedModelRecord);
12842
14389
  });
12843
- return resolvedModel;
14390
+ patchedModels.set(resolvedModel, wrappedModel);
14391
+ patchedModels.set(wrappedModel, wrappedModel);
14392
+ return wrappedModel;
12844
14393
  };
12845
14394
  const patchTool = (tool, name) => {
12846
- if (tool == null || typeof tool !== "object" || !("execute" in tool) || typeof tool.execute !== "function" || patchedTools.has(tool) || tool[AUTO_PATCHED_TOOL]) {
14395
+ if (tool == null || typeof tool !== "object" || !("execute" in tool) || typeof tool.execute !== "function" || patchedTools.has(tool)) {
12847
14396
  return;
12848
14397
  }
12849
14398
  patchedTools.add(tool);
12850
- tool[AUTO_PATCHED_TOOL] = true;
12851
- const originalExecute = tool.execute;
14399
+ const toolRecord = tool;
14400
+ const entry = {
14401
+ activeSpanIds: /* @__PURE__ */ new Set([parentSpan.spanId]),
14402
+ childTracingOptions,
14403
+ name,
14404
+ parentSpan
14405
+ };
14406
+ const cleanupToolEntry = (state2) => {
14407
+ const index = state2.entries.indexOf(entry);
14408
+ if (index >= 0) {
14409
+ state2.entries.splice(index, 1);
14410
+ }
14411
+ if (state2.entries.length > 0) {
14412
+ return;
14413
+ }
14414
+ tool.execute = state2.originalExecute;
14415
+ delete toolRecord[AUTO_PATCHED_TOOL];
14416
+ };
14417
+ const existingState = toolRecord[AUTO_PATCHED_TOOL];
14418
+ if (existingState) {
14419
+ if (childTracingOptions.agentOwner && attachNestedAISDKChildPatchEntry(
14420
+ existingState.entries,
14421
+ parentSpan,
14422
+ cleanup
14423
+ )) {
14424
+ return;
14425
+ }
14426
+ if (!childTracingOptions.agentOwner) {
14427
+ shadowActiveAISDKChildPatchEntry(
14428
+ existingState.entries,
14429
+ entry,
14430
+ parentSpan,
14431
+ cleanup
14432
+ );
14433
+ }
14434
+ existingState.entries.push(entry);
14435
+ cleanup.push(() => {
14436
+ cleanupToolEntry(existingState);
14437
+ });
14438
+ return;
14439
+ }
14440
+ const originalExecute = toolRecord.execute;
14441
+ const state = {
14442
+ entries: [entry],
14443
+ originalExecute
14444
+ };
14445
+ toolRecord[AUTO_PATCHED_TOOL] = state;
12852
14446
  tool.execute = function executePatched(...args) {
14447
+ const activeEntry = activeAISDKChildPatchEntry(state.entries);
12853
14448
  const result = Reflect.apply(originalExecute, this, args);
14449
+ if (!activeEntry) {
14450
+ return result;
14451
+ }
12854
14452
  if (isAsyncGenerator(result)) {
12855
14453
  return (async function* () {
12856
- const span = parentSpan.startSpan({
12857
- name,
14454
+ const span = activeEntry.parentSpan.startSpan({
14455
+ name: activeEntry.name,
12858
14456
  spanAttributes: {
12859
14457
  type: "tool" /* TOOL */
12860
14458
  }
12861
14459
  });
12862
- span.log({ input: args.length === 1 ? args[0] : args });
14460
+ span.log({ input: serializeToolExecutionInput(args) });
12863
14461
  try {
12864
14462
  let lastValue;
12865
14463
  for await (const value of result) {
@@ -12875,15 +14473,15 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
12875
14473
  }
12876
14474
  })();
12877
14475
  }
12878
- return parentSpan.traced(
14476
+ return activeEntry.parentSpan.traced(
12879
14477
  async (span) => {
12880
- span.log({ input: args.length === 1 ? args[0] : args });
14478
+ span.log({ input: serializeToolExecutionInput(args) });
12881
14479
  const awaitedResult = await result;
12882
14480
  span.log({ output: awaitedResult });
12883
14481
  return awaitedResult;
12884
14482
  },
12885
14483
  {
12886
- name,
14484
+ name: activeEntry.name,
12887
14485
  spanAttributes: {
12888
14486
  type: "tool" /* TOOL */
12889
14487
  }
@@ -12891,8 +14489,7 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
12891
14489
  );
12892
14490
  };
12893
14491
  cleanup.push(() => {
12894
- tool.execute = originalExecute;
12895
- delete tool[AUTO_PATCHED_TOOL];
14492
+ cleanupToolEntry(state);
12896
14493
  });
12897
14494
  };
12898
14495
  const patchTools = (tools) => {
@@ -12911,25 +14508,42 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
12911
14508
  }
12912
14509
  };
12913
14510
  if (params && typeof params === "object") {
12914
- const patchedParamModel = patchModel(params.model);
12915
- if (typeof params.model === "string" && patchedParamModel && typeof patchedParamModel === "object") {
14511
+ const originalParamModel = params.model;
14512
+ const patchedParamModel = patchModel(originalParamModel);
14513
+ if (patchedParamModel && patchedParamModel !== originalParamModel) {
12916
14514
  params.model = patchedParamModel;
14515
+ cleanup.push(() => {
14516
+ params.model = originalParamModel;
14517
+ });
12917
14518
  }
12918
14519
  patchTools(params.tools);
12919
14520
  }
12920
14521
  if (self && typeof self === "object") {
12921
14522
  const selfRecord = self;
12922
14523
  if (selfRecord.model !== void 0) {
12923
- const patchedSelfModel = patchModel(selfRecord.model);
12924
- if (typeof selfRecord.model === "string" && patchedSelfModel && typeof patchedSelfModel === "object") {
14524
+ const originalSelfModel = selfRecord.model;
14525
+ const patchedSelfModel = patchModel(originalSelfModel);
14526
+ if (patchedSelfModel && patchedSelfModel !== originalSelfModel) {
12925
14527
  selfRecord.model = patchedSelfModel;
14528
+ cleanup.push(() => {
14529
+ selfRecord.model = originalSelfModel;
14530
+ });
12926
14531
  }
12927
14532
  }
14533
+ if (selfRecord.tools !== void 0) {
14534
+ patchTools(selfRecord.tools);
14535
+ }
12928
14536
  if (selfRecord.settings && typeof selfRecord.settings === "object") {
12929
14537
  if (selfRecord.settings.model !== void 0) {
12930
- const patchedSettingsModel = patchModel(selfRecord.settings.model);
12931
- if (typeof selfRecord.settings.model === "string" && patchedSettingsModel && typeof patchedSettingsModel === "object") {
14538
+ const originalSettingsModel = selfRecord.settings.model;
14539
+ const patchedSettingsModel = patchModel(originalSettingsModel);
14540
+ if (patchedSettingsModel && patchedSettingsModel !== originalSettingsModel) {
12932
14541
  selfRecord.settings.model = patchedSettingsModel;
14542
+ cleanup.push(() => {
14543
+ if (selfRecord.settings) {
14544
+ selfRecord.settings.model = originalSettingsModel;
14545
+ }
14546
+ });
12933
14547
  }
12934
14548
  }
12935
14549
  if (selfRecord.settings.tools !== void 0) {
@@ -13026,99 +14640,190 @@ function isAISDKContentAsyncIterableChunk(chunk) {
13026
14640
  return isObject(part) && typeof part.type !== "string";
13027
14641
  }
13028
14642
  function patchAISDKStreamingResult(args) {
13029
- const { defaultDenyOutputPaths, endEvent, result, span, startTime } = args;
14643
+ const {
14644
+ defaultDenyOutputPaths,
14645
+ endEvent,
14646
+ onComplete,
14647
+ result,
14648
+ span,
14649
+ startTime
14650
+ } = args;
13030
14651
  if (!result || typeof result !== "object") {
13031
14652
  return false;
13032
14653
  }
13033
14654
  const resultRecord = result;
13034
14655
  attachKnownResultPromiseHandlers(resultRecord);
14656
+ let finalized = false;
14657
+ const finalize = () => {
14658
+ if (finalized) {
14659
+ return;
14660
+ }
14661
+ finalized = true;
14662
+ finalizeAISDKChildTracing(endEvent);
14663
+ span.end();
14664
+ onComplete?.();
14665
+ };
14666
+ let outputLogged = false;
14667
+ const logStreamingOutput = async (firstChunkTime) => {
14668
+ if (outputLogged) {
14669
+ return;
14670
+ }
14671
+ outputLogged = true;
14672
+ try {
14673
+ const metrics = extractTopLevelAISDKMetrics(result, endEvent);
14674
+ if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
14675
+ metrics.time_to_first_token = firstChunkTime - startTime;
14676
+ }
14677
+ const output = await processAISDKStreamingOutput(
14678
+ result,
14679
+ resolveDenyOutputPaths(endEvent, defaultDenyOutputPaths)
14680
+ );
14681
+ const metadata = buildResolvedMetadataPayload(result).metadata;
14682
+ span.log({
14683
+ output,
14684
+ ...metadata ? { metadata } : {},
14685
+ metrics
14686
+ });
14687
+ } catch (error) {
14688
+ span.log({ error: toLoggedError(error) });
14689
+ } finally {
14690
+ finalize();
14691
+ }
14692
+ };
14693
+ const createAsyncIterableHooks = () => {
14694
+ let firstChunkTime;
14695
+ return {
14696
+ onChunk: (chunk) => {
14697
+ if (firstChunkTime === void 0 && isAISDKContentAsyncIterableChunk(chunk)) {
14698
+ firstChunkTime = getCurrentUnixTimestamp();
14699
+ }
14700
+ },
14701
+ onComplete: async () => {
14702
+ await logStreamingOutput(firstChunkTime);
14703
+ },
14704
+ onError: (error) => {
14705
+ if (!outputLogged) {
14706
+ outputLogged = true;
14707
+ span.log({
14708
+ error: error.message
14709
+ });
14710
+ }
14711
+ finalize();
14712
+ },
14713
+ onCancel: finalize
14714
+ };
14715
+ };
14716
+ const patchAsyncIterable = (stream) => isReadableStreamLike(stream) ? createPatchedReadableStream(stream, createAsyncIterableHooks()) : createPatchedAsyncIterable(stream, createAsyncIterableHooks());
14717
+ const patchAsyncIterableField = (field) => {
14718
+ let descriptorOwner = resultRecord;
14719
+ let descriptor;
14720
+ while (descriptorOwner) {
14721
+ descriptor = Object.getOwnPropertyDescriptor(descriptorOwner, field);
14722
+ if (descriptor) {
14723
+ break;
14724
+ }
14725
+ descriptorOwner = Object.getPrototypeOf(descriptorOwner);
14726
+ }
14727
+ if (!descriptor || descriptorOwner === resultRecord && !descriptor.configurable) {
14728
+ return false;
14729
+ }
14730
+ if ("value" in descriptor) {
14731
+ if (!isAsyncIterable(descriptor.value)) {
14732
+ return false;
14733
+ }
14734
+ try {
14735
+ Object.defineProperty(resultRecord, field, {
14736
+ configurable: descriptorOwner === resultRecord ? descriptor.configurable : true,
14737
+ enumerable: descriptor.enumerable,
14738
+ value: patchAsyncIterable(descriptor.value),
14739
+ writable: descriptor.writable
14740
+ });
14741
+ return true;
14742
+ } catch {
14743
+ return false;
14744
+ }
14745
+ }
14746
+ if (typeof descriptor.get !== "function") {
14747
+ return false;
14748
+ }
14749
+ const originalGet = descriptor.get;
14750
+ const originalSet = descriptor.set;
14751
+ try {
14752
+ Object.defineProperty(resultRecord, field, {
14753
+ configurable: descriptorOwner === resultRecord ? descriptor.configurable : true,
14754
+ enumerable: descriptor.enumerable,
14755
+ get() {
14756
+ const stream = originalGet.call(this);
14757
+ return isAsyncIterable(stream) ? patchAsyncIterable(stream) : stream;
14758
+ },
14759
+ ...originalSet ? {
14760
+ set(value) {
14761
+ originalSet.call(this, value);
14762
+ }
14763
+ } : {}
14764
+ });
14765
+ return true;
14766
+ } catch {
14767
+ return false;
14768
+ }
14769
+ };
14770
+ let patched = false;
13035
14771
  if (isReadableStreamLike(resultRecord.baseStream)) {
13036
- let firstChunkTime2;
13037
- const wrappedBaseStream = resultRecord.baseStream.pipeThrough(
14772
+ let firstChunkTime;
14773
+ const transformedBaseStream = resultRecord.baseStream.pipeThrough(
13038
14774
  new TransformStream({
13039
14775
  transform(chunk, controller) {
13040
- if (firstChunkTime2 === void 0 && isAISDKContentStreamChunk(chunk)) {
13041
- firstChunkTime2 = getCurrentUnixTimestamp();
14776
+ if (firstChunkTime === void 0 && isAISDKContentStreamChunk(chunk)) {
14777
+ firstChunkTime = getCurrentUnixTimestamp();
13042
14778
  }
13043
14779
  controller.enqueue(chunk);
13044
14780
  },
13045
14781
  async flush() {
13046
- const metrics = extractTopLevelAISDKMetrics(result, endEvent);
13047
- if (metrics.time_to_first_token === void 0 && firstChunkTime2 !== void 0) {
13048
- metrics.time_to_first_token = firstChunkTime2 - startTime;
13049
- }
13050
- const output = await processAISDKStreamingOutput(
13051
- result,
13052
- resolveDenyOutputPaths(endEvent, defaultDenyOutputPaths)
13053
- );
13054
- const metadata = buildResolvedMetadataPayload(result).metadata;
13055
- span.log({
13056
- output,
13057
- ...metadata ? { metadata } : {},
13058
- metrics
13059
- });
13060
- finalizeAISDKChildTracing(endEvent);
13061
- span.end();
14782
+ await logStreamingOutput(firstChunkTime);
13062
14783
  }
13063
14784
  })
13064
14785
  );
14786
+ const reader = transformedBaseStream.getReader();
14787
+ const wrappedBaseStream = new ReadableStream({
14788
+ async pull(controller) {
14789
+ try {
14790
+ const { done, value } = await reader.read();
14791
+ if (done) {
14792
+ controller.close();
14793
+ return;
14794
+ }
14795
+ controller.enqueue(value);
14796
+ } catch (error) {
14797
+ span.log({ error: toLoggedError(error) });
14798
+ finalize();
14799
+ controller.error(error);
14800
+ }
14801
+ },
14802
+ async cancel(reason) {
14803
+ try {
14804
+ finalize();
14805
+ } finally {
14806
+ await reader.cancel(reason);
14807
+ }
14808
+ }
14809
+ });
13065
14810
  Object.defineProperty(resultRecord, "baseStream", {
13066
14811
  configurable: true,
13067
14812
  enumerable: true,
13068
14813
  value: wrappedBaseStream,
13069
14814
  writable: true
13070
14815
  });
13071
- return true;
14816
+ patched = true;
13072
14817
  }
13073
- const streamField = findAsyncIterableField(resultRecord, [
14818
+ for (const field of [
13074
14819
  "partialObjectStream",
13075
14820
  "textStream",
13076
14821
  "fullStream",
13077
14822
  "stream"
13078
- ]);
13079
- if (!streamField) {
13080
- return false;
14823
+ ]) {
14824
+ patched = patchAsyncIterableField(field) || patched;
13081
14825
  }
13082
- let firstChunkTime;
13083
- const wrappedStream = createPatchedAsyncIterable(streamField.stream, {
13084
- onChunk: (chunk) => {
13085
- if (firstChunkTime === void 0 && isAISDKContentAsyncIterableChunk(chunk)) {
13086
- firstChunkTime = getCurrentUnixTimestamp();
13087
- }
13088
- },
13089
- onComplete: async () => {
13090
- const metrics = extractTopLevelAISDKMetrics(result, endEvent);
13091
- if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
13092
- metrics.time_to_first_token = firstChunkTime - startTime;
13093
- }
13094
- const output = await processAISDKStreamingOutput(
13095
- result,
13096
- resolveDenyOutputPaths(endEvent, defaultDenyOutputPaths)
13097
- );
13098
- const metadata = buildResolvedMetadataPayload(result).metadata;
13099
- span.log({
13100
- output,
13101
- ...metadata ? { metadata } : {},
13102
- metrics
13103
- });
13104
- finalizeAISDKChildTracing(endEvent);
13105
- span.end();
13106
- },
13107
- onError: (error) => {
13108
- span.log({
13109
- error: error.message
13110
- });
13111
- finalizeAISDKChildTracing(endEvent);
13112
- span.end();
13113
- }
13114
- });
13115
- Object.defineProperty(resultRecord, streamField.field, {
13116
- configurable: true,
13117
- enumerable: true,
13118
- value: wrappedStream,
13119
- writable: true
13120
- });
13121
- return true;
14826
+ return patched;
13122
14827
  }
13123
14828
  function attachKnownResultPromiseHandlers(result) {
13124
14829
  const promiseLikeFields = [
@@ -13150,34 +14855,72 @@ function attachKnownResultPromiseHandlers(result) {
13150
14855
  }
13151
14856
  }
13152
14857
  function isReadableStreamLike(value) {
13153
- return value != null && typeof value === "object" && typeof value.pipeThrough === "function";
13154
- }
13155
- function findAsyncIterableField(result, candidateFields) {
13156
- for (const field of candidateFields) {
13157
- try {
13158
- const stream = result[field];
13159
- if (isAsyncIterable(stream)) {
13160
- return { field, stream };
14858
+ return value != null && typeof value === "object" && typeof value.getReader === "function" && typeof value.pipeThrough === "function";
14859
+ }
14860
+ function createPatchedReadableStream(stream, hooks) {
14861
+ let reader;
14862
+ let completed = false;
14863
+ return new ReadableStream({
14864
+ async pull(controller) {
14865
+ reader ??= stream.getReader();
14866
+ try {
14867
+ const { done, value } = await reader.read();
14868
+ if (done) {
14869
+ completed = true;
14870
+ await hooks.onComplete();
14871
+ controller.close();
14872
+ return;
14873
+ }
14874
+ hooks.onChunk(value);
14875
+ controller.enqueue(value);
14876
+ } catch (error) {
14877
+ completed = true;
14878
+ hooks.onError(
14879
+ error instanceof Error ? error : new Error(String(error))
14880
+ );
14881
+ controller.error(error);
14882
+ }
14883
+ },
14884
+ async cancel(reason) {
14885
+ if (!completed) {
14886
+ completed = true;
14887
+ try {
14888
+ await hooks.onCancel?.();
14889
+ } catch {
14890
+ }
14891
+ }
14892
+ if (reader) {
14893
+ await reader.cancel(reason);
14894
+ } else if (stream.cancel) {
14895
+ await stream.cancel(reason);
13161
14896
  }
13162
- } catch {
13163
14897
  }
13164
- }
13165
- return null;
14898
+ });
13166
14899
  }
13167
14900
  function createPatchedAsyncIterable(stream, hooks) {
13168
14901
  return {
13169
14902
  async *[Symbol.asyncIterator]() {
14903
+ let completed = false;
13170
14904
  try {
13171
14905
  for await (const chunk of stream) {
13172
14906
  hooks.onChunk(chunk);
13173
14907
  yield chunk;
13174
14908
  }
14909
+ completed = true;
13175
14910
  await hooks.onComplete();
13176
14911
  } catch (error) {
14912
+ completed = true;
13177
14913
  hooks.onError(
13178
14914
  error instanceof Error ? error : new Error(String(error))
13179
14915
  );
13180
14916
  throw error;
14917
+ } finally {
14918
+ if (!completed) {
14919
+ try {
14920
+ await hooks.onCancel?.();
14921
+ } catch {
14922
+ }
14923
+ }
13181
14924
  }
13182
14925
  }
13183
14926
  };
@@ -13252,6 +14995,40 @@ function buildResolvedMetadataPayload(result) {
13252
14995
  }
13253
14996
  return Object.keys(metadata).length > 0 ? { metadata } : {};
13254
14997
  }
14998
+ function mergeMetadataPayload(metadataPayload, extraMetadata) {
14999
+ if (!extraMetadata || Object.keys(extraMetadata).length === 0) {
15000
+ return metadataPayload;
15001
+ }
15002
+ return {
15003
+ metadata: {
15004
+ ...metadataPayload.metadata ?? {},
15005
+ ...extraMetadata
15006
+ }
15007
+ };
15008
+ }
15009
+ function buildMissingUsageMetadata(output, metrics, reason) {
15010
+ if (!hasLoggedOutput(output) || hasTokenUsageMetrics(metrics)) {
15011
+ return void 0;
15012
+ }
15013
+ return { usage_unavailable_reason: reason };
15014
+ }
15015
+ function hasLoggedOutput(output) {
15016
+ if (output === null || output === void 0) {
15017
+ return false;
15018
+ }
15019
+ if (Array.isArray(output)) {
15020
+ return output.length > 0;
15021
+ }
15022
+ if (typeof output === "object") {
15023
+ return Object.keys(output).length > 0;
15024
+ }
15025
+ return true;
15026
+ }
15027
+ function hasTokenUsageMetrics(metrics) {
15028
+ return Object.keys(metrics).some(
15029
+ (key) => key !== "estimated_cost" && key !== "time_to_first_token"
15030
+ );
15031
+ }
13255
15032
  function resolveAISDKModel(model, aiSDK) {
13256
15033
  if (typeof model !== "string") {
13257
15034
  return model;
@@ -13275,7 +15052,45 @@ function isAsyncGenerator(value) {
13275
15052
  function processAISDKOutput(output, denyOutputPaths) {
13276
15053
  if (!output) return output;
13277
15054
  const merged = extractSerializableOutputFields(output);
13278
- return normalizeAISDKLoggedOutput(omit(merged, denyOutputPaths));
15055
+ const deleteOutputPaths = denyOutputPaths.filter(
15056
+ (path) => path.toLowerCase().endsWith("headers")
15057
+ );
15058
+ const sanitized = omit(merged, denyOutputPaths, deleteOutputPaths);
15059
+ for (const path of TRANSPORT_PAYLOAD_ROOT_PATHS) {
15060
+ const stack = [{ obj: sanitized, keys: parsePath(path) }];
15061
+ while (stack.length > 0) {
15062
+ const entry = stack.pop();
15063
+ if (!entry || entry.keys.length === 0) {
15064
+ continue;
15065
+ }
15066
+ const firstKey = entry.keys[0];
15067
+ const remainingKeys = entry.keys.slice(1);
15068
+ if (firstKey === "[]") {
15069
+ if (Array.isArray(entry.obj)) {
15070
+ for (const item of entry.obj) {
15071
+ stack.push({
15072
+ obj: item,
15073
+ keys: remainingKeys
15074
+ });
15075
+ }
15076
+ }
15077
+ continue;
15078
+ }
15079
+ if (!entry.obj || typeof entry.obj !== "object" || !(firstKey in entry.obj)) {
15080
+ continue;
15081
+ }
15082
+ const record = entry.obj;
15083
+ if (remainingKeys.length === 0) {
15084
+ record[firstKey] = sanitizeAISDKMetadataValue(record[firstKey]);
15085
+ continue;
15086
+ }
15087
+ stack.push({
15088
+ obj: record[firstKey],
15089
+ keys: remainingKeys
15090
+ });
15091
+ }
15092
+ }
15093
+ return normalizeAISDKLoggedOutput(sanitized);
13279
15094
  }
13280
15095
  function processAISDKEmbeddingOutput(output, denyOutputPaths) {
13281
15096
  if (!output || typeof output !== "object") {
@@ -13366,6 +15181,8 @@ function extractTokenMetrics(result) {
13366
15181
  );
13367
15182
  if (totalTokens !== void 0) {
13368
15183
  metrics.tokens = totalTokens;
15184
+ } else if (promptTokens !== void 0 && completionTokens !== void 0) {
15185
+ metrics.tokens = promptTokens + completionTokens;
13369
15186
  }
13370
15187
  const promptCachedTokens = firstNumber2(
13371
15188
  usage.inputTokens?.cacheRead,
@@ -13489,7 +15306,9 @@ function extractGetterValues(obj) {
13489
15306
  const getterValues = {};
13490
15307
  const getterNames = [
13491
15308
  "content",
15309
+ "messages",
13492
15310
  "text",
15311
+ "output",
13493
15312
  "object",
13494
15313
  "value",
13495
15314
  "values",
@@ -13529,7 +15348,9 @@ function extractGetterValues(obj) {
13529
15348
  function extractSerializableOutputFields(output) {
13530
15349
  const serialized = {};
13531
15350
  const directFieldNames = [
15351
+ "messages",
13532
15352
  "steps",
15353
+ "output",
13533
15354
  "request",
13534
15355
  "responseMessages",
13535
15356
  "warnings",
@@ -13711,7 +15532,7 @@ function parsePath(path) {
13711
15532
  }
13712
15533
  return keys;
13713
15534
  }
13714
- function omitAtPath(obj, keys) {
15535
+ function omitAtPath(obj, keys, deleteLeaf = false) {
13715
15536
  if (keys.length === 0) return;
13716
15537
  const firstKey = keys[0];
13717
15538
  const remainingKeys = keys.slice(1);
@@ -13721,29 +15542,36 @@ function omitAtPath(obj, keys) {
13721
15542
  if (remainingKeys.length > 0) {
13722
15543
  omitAtPath(
13723
15544
  item,
13724
- remainingKeys
15545
+ remainingKeys,
15546
+ deleteLeaf
13725
15547
  );
13726
15548
  }
13727
15549
  });
13728
15550
  }
13729
15551
  } else if (remainingKeys.length === 0) {
13730
15552
  if (obj && typeof obj === "object" && firstKey in obj) {
13731
- obj[firstKey] = "<omitted>";
15553
+ if (deleteLeaf) {
15554
+ delete obj[firstKey];
15555
+ } else {
15556
+ obj[firstKey] = "<omitted>";
15557
+ }
13732
15558
  }
13733
15559
  } else {
13734
15560
  if (obj && typeof obj === "object" && firstKey in obj) {
13735
15561
  omitAtPath(
13736
15562
  obj[firstKey],
13737
- remainingKeys
15563
+ remainingKeys,
15564
+ deleteLeaf
13738
15565
  );
13739
15566
  }
13740
15567
  }
13741
15568
  }
13742
- function omit(obj, paths) {
15569
+ function omit(obj, paths, deletePaths = []) {
13743
15570
  const result = deepCopy(obj);
15571
+ const deletePathSet = new Set(deletePaths);
13744
15572
  for (const path of paths) {
13745
15573
  const keys = parsePath(path);
13746
- omitAtPath(result, keys);
15574
+ omitAtPath(result, keys, deletePathSet.has(path));
13747
15575
  }
13748
15576
  return result;
13749
15577
  }