braintrust 3.19.0 → 3.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/NOTICE +20 -0
  2. package/README.md +2 -0
  3. package/dev/dist/index.d.mts +309 -199
  4. package/dev/dist/index.d.ts +309 -199
  5. package/dev/dist/index.js +2833 -987
  6. package/dev/dist/index.mjs +2294 -448
  7. package/dist/apply-auto-instrumentation.js +781 -199
  8. package/dist/apply-auto-instrumentation.mjs +588 -6
  9. package/dist/auto-instrumentations/bundler/esbuild.cjs +594 -2
  10. package/dist/auto-instrumentations/bundler/esbuild.d.mts +2 -2
  11. package/dist/auto-instrumentations/bundler/esbuild.d.ts +2 -2
  12. package/dist/auto-instrumentations/bundler/esbuild.mjs +3 -3
  13. package/dist/auto-instrumentations/bundler/next.cjs +594 -2
  14. package/dist/auto-instrumentations/bundler/next.mjs +4 -4
  15. package/dist/auto-instrumentations/bundler/rollup.cjs +594 -2
  16. package/dist/auto-instrumentations/bundler/rollup.d.mts +2 -2
  17. package/dist/auto-instrumentations/bundler/rollup.d.ts +2 -2
  18. package/dist/auto-instrumentations/bundler/rollup.mjs +3 -3
  19. package/dist/auto-instrumentations/bundler/vite.cjs +594 -2
  20. package/dist/auto-instrumentations/bundler/vite.d.mts +2 -2
  21. package/dist/auto-instrumentations/bundler/vite.d.ts +2 -2
  22. package/dist/auto-instrumentations/bundler/vite.mjs +3 -3
  23. package/dist/auto-instrumentations/bundler/webpack-loader.cjs +593 -9
  24. package/dist/auto-instrumentations/bundler/webpack-loader.d.ts +68 -1
  25. package/dist/auto-instrumentations/bundler/webpack.cjs +594 -2
  26. package/dist/auto-instrumentations/bundler/webpack.d.mts +2 -2
  27. package/dist/auto-instrumentations/bundler/webpack.d.ts +2 -2
  28. package/dist/auto-instrumentations/bundler/webpack.mjs +4 -4
  29. package/dist/auto-instrumentations/{chunk-W4E36GIW.mjs → chunk-BRQX23KL.mjs} +16 -0
  30. package/dist/auto-instrumentations/chunk-M6DLIJ2Z.mjs +784 -0
  31. package/dist/auto-instrumentations/{chunk-K74TZGGM.mjs → chunk-T6J4C7LX.mjs} +1 -1
  32. package/dist/auto-instrumentations/{chunk-S4374IP6.mjs → chunk-TKRPRPGD.mjs} +4 -6
  33. package/dist/auto-instrumentations/chunk-VT6DDNKM.mjs +856 -0
  34. package/dist/auto-instrumentations/hook.mjs +749 -45
  35. package/dist/auto-instrumentations/index.cjs +16 -0
  36. package/dist/auto-instrumentations/index.d.mts +2 -3
  37. package/dist/auto-instrumentations/index.d.ts +2 -3
  38. package/dist/auto-instrumentations/index.mjs +1 -1
  39. package/dist/auto-instrumentations/loader/cjs-patch.cjs +578 -4
  40. package/dist/auto-instrumentations/loader/cjs-patch.d.mts +1 -1
  41. package/dist/auto-instrumentations/loader/cjs-patch.d.ts +1 -1
  42. package/dist/auto-instrumentations/loader/cjs-patch.mjs +3 -7
  43. package/dist/auto-instrumentations/loader/esm-hook.mjs +2 -6
  44. package/dist/auto-instrumentations/{plugin-D7nDswtC.d.mts → plugin-D0KHwSJv.d.mts} +1 -1
  45. package/dist/auto-instrumentations/{plugin-D7nDswtC.d.ts → plugin-G6fgxk1b.d.ts} +1 -1
  46. package/dist/auto-instrumentations/types-RNPaKi9o.d.mts +70 -0
  47. package/dist/auto-instrumentations/types-RNPaKi9o.d.ts +70 -0
  48. package/dist/browser.d.mts +1369 -848
  49. package/dist/browser.d.ts +1369 -848
  50. package/dist/browser.js +2735 -473
  51. package/dist/browser.mjs +2735 -473
  52. package/dist/{chunk-LPC4W2WX.js → chunk-BFGIH2ZJ.js} +4 -0
  53. package/dist/{chunk-37RLJF2U.js → chunk-FY7DAKA5.js} +3149 -1273
  54. package/dist/{chunk-Y7W7WP6H.mjs → chunk-KMGUTPB7.mjs} +4 -0
  55. package/dist/{chunk-VEQ2PCMC.mjs → chunk-O2P765XK.mjs} +2399 -523
  56. package/dist/cli.js +2267 -412
  57. package/dist/edge-light.d.mts +1 -1
  58. package/dist/edge-light.d.ts +1 -1
  59. package/dist/edge-light.js +2735 -473
  60. package/dist/edge-light.mjs +2735 -473
  61. package/dist/index.d.mts +1848 -1327
  62. package/dist/index.d.ts +1848 -1327
  63. package/dist/index.js +754 -352
  64. package/dist/index.mjs +448 -46
  65. package/dist/instrumentation/index.d.mts +119 -21
  66. package/dist/instrumentation/index.d.ts +119 -21
  67. package/dist/instrumentation/index.js +2345 -512
  68. package/dist/instrumentation/index.mjs +2344 -512
  69. package/dist/vitest-evals-reporter.js +16 -16
  70. package/dist/vitest-evals-reporter.mjs +2 -2
  71. package/dist/workerd.d.mts +1 -1
  72. package/dist/workerd.d.ts +1 -1
  73. package/dist/workerd.js +2735 -473
  74. package/dist/workerd.mjs +2735 -473
  75. package/licenses/import-in-the-middle/LICENSE +201 -0
  76. package/licenses/import-in-the-middle/LICENSE-3rdparty.csv +4 -0
  77. package/licenses/import-in-the-middle/NOTICE +34 -0
  78. package/licenses/orchestrion-js/LICENSE +202 -0
  79. package/licenses/orchestrion-js/LICENSE-3rdparty.csv +8 -0
  80. package/licenses/orchestrion-js/NOTICE +3 -0
  81. package/licenses/require-in-the-middle/LICENSE +23 -0
  82. package/package.json +13 -4
  83. package/util/dist/index.d.mts +1 -0
  84. package/util/dist/index.d.ts +1 -0
  85. package/util/dist/index.js +4 -4
  86. package/util/dist/index.mjs +2 -2
  87. package/dist/auto-instrumentations/chunk-J57YF7WS.mjs +0 -208
  88. package/dist/auto-instrumentations/chunk-QFMACSOL.mjs +0 -280
@@ -589,8 +589,291 @@ var UUIDGenerator = class extends IDGenerator {
589
589
  return true;
590
590
  }
591
591
  };
592
+ function generateHexId(bytes) {
593
+ let result = "";
594
+ for (let i = 0; i < bytes; i++) {
595
+ result += Math.floor(Math.random() * 256).toString(16).padStart(2, "0");
596
+ }
597
+ return result;
598
+ }
599
+ var OTELIDGenerator = class extends IDGenerator {
600
+ getSpanId() {
601
+ return generateHexId(8);
602
+ }
603
+ getTraceId() {
604
+ return generateHexId(16);
605
+ }
606
+ shareRootSpanId() {
607
+ return false;
608
+ }
609
+ };
610
+ function parseEnvBool(name) {
611
+ const raw = isomorph_default.getEnv(name);
612
+ if (raw === void 0 || raw === null) {
613
+ return false;
614
+ }
615
+ const normalized = raw.trim().toLowerCase();
616
+ return normalized === "true" || normalized === "1" || normalized === "yes" || normalized === "y" || normalized === "on";
617
+ }
618
+ var _warnedLegacyUuidConflict = false;
619
+ function resolveUseLegacyUuidIds() {
620
+ const legacy = parseEnvBool("BRAINTRUST_LEGACY_IDS");
621
+ if (parseEnvBool("BRAINTRUST_OTEL_COMPAT")) {
622
+ if (legacy && !_warnedLegacyUuidConflict) {
623
+ _warnedLegacyUuidConflict = true;
624
+ debugLogger.warn(
625
+ "BRAINTRUST_LEGACY_IDS is ignored because BRAINTRUST_OTEL_COMPAT requires OpenTelemetry-compatible hex span IDs. Using hex IDs."
626
+ );
627
+ }
628
+ return false;
629
+ }
630
+ return legacy;
631
+ }
592
632
  function getIdGenerator() {
593
- return globalThis.BRAINTRUST_ID_GENERATOR !== void 0 ? new globalThis.BRAINTRUST_ID_GENERATOR() : new UUIDGenerator();
633
+ if (globalThis.BRAINTRUST_ID_GENERATOR !== void 0) {
634
+ return new globalThis.BRAINTRUST_ID_GENERATOR();
635
+ }
636
+ return resolveUseLegacyUuidIds() ? new UUIDGenerator() : new OTELIDGenerator();
637
+ }
638
+
639
+ // src/propagation.ts
640
+ var TRACEPARENT_HEADER = "traceparent";
641
+ var TRACESTATE_HEADER = "tracestate";
642
+ var BAGGAGE_HEADER = "baggage";
643
+ var BRAINTRUST_PARENT_KEY = "braintrust.parent";
644
+ var DEFAULT_TRACE_FLAGS = "01";
645
+ var TRACEPARENT_RE = /^00-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/;
646
+ var ZERO_TRACE_ID = "0".repeat(32);
647
+ var ZERO_SPAN_ID = "0".repeat(16);
648
+ var MAX_BAGGAGE_LENGTH = 8192;
649
+ var MAX_BAGGAGE_MEMBERS = 64;
650
+ var _utf8Encoder = new TextEncoder();
651
+ function utf8ByteLength(value) {
652
+ return _utf8Encoder.encode(value).length;
653
+ }
654
+ function capBaggageToMemberBoundary(value) {
655
+ const totalBytes = utf8ByteLength(value);
656
+ const withinBytes = totalBytes <= MAX_BAGGAGE_LENGTH;
657
+ let commaCount = 0;
658
+ for (let i = 0; i < value.length; i++) {
659
+ if (value.charCodeAt(i) === 44) {
660
+ commaCount++;
661
+ }
662
+ }
663
+ const withinMembers = commaCount < MAX_BAGGAGE_MEMBERS;
664
+ if (withinBytes && withinMembers) {
665
+ return value;
666
+ }
667
+ const kept = [];
668
+ let length = 0;
669
+ for (const rawMember of value.split(",")) {
670
+ if (kept.length >= MAX_BAGGAGE_MEMBERS) {
671
+ break;
672
+ }
673
+ const cost = utf8ByteLength(rawMember) + (kept.length ? 1 : 0);
674
+ if (length + cost > MAX_BAGGAGE_LENGTH) {
675
+ break;
676
+ }
677
+ kept.push(rawMember);
678
+ length += cost;
679
+ }
680
+ if (!kept.length) {
681
+ return "";
682
+ }
683
+ return kept.join(",");
684
+ }
685
+ function isTraceContextHeaderTupleArray(value) {
686
+ return Array.isArray(value) && value.every(
687
+ (item) => Array.isArray(item) && typeof item[0] === "string" && typeof item[1] === "string"
688
+ );
689
+ }
690
+ function isListHeader(name) {
691
+ const lowered = name.toLowerCase();
692
+ return lowered === BAGGAGE_HEADER || lowered === TRACESTATE_HEADER;
693
+ }
694
+ function headerValueToString(value, name) {
695
+ if (value === void 0 || value === null) {
696
+ return void 0;
697
+ }
698
+ if (Array.isArray(value)) {
699
+ const stringValues = value.filter((item) => {
700
+ return typeof item === "string";
701
+ });
702
+ if (!stringValues.length) {
703
+ return void 0;
704
+ }
705
+ return isListHeader(name) ? stringValues.join(",") : stringValues[0];
706
+ }
707
+ return typeof value === "string" ? value : String(value);
708
+ }
709
+ function getHeader(headers, name) {
710
+ if (!headers) {
711
+ return void 0;
712
+ }
713
+ if (isTraceContextHeaderTupleArray(headers)) {
714
+ const lowered2 = name.toLowerCase();
715
+ const matches = headers.filter(([key]) => key.toLowerCase() === lowered2).map(([, value]) => value);
716
+ if (!matches.length) {
717
+ return void 0;
718
+ }
719
+ return headerValueToString(matches, name);
720
+ }
721
+ const getter = headers.get;
722
+ if (typeof getter === "function") {
723
+ try {
724
+ const value = headerValueToString(getter.call(headers, name), name);
725
+ if (value !== void 0) {
726
+ return value;
727
+ }
728
+ } catch {
729
+ }
730
+ }
731
+ const nodeGetter = headers.getHeader;
732
+ if (typeof nodeGetter === "function") {
733
+ try {
734
+ const value = headerValueToString(nodeGetter.call(headers, name), name);
735
+ if (value !== void 0) {
736
+ return value;
737
+ }
738
+ } catch {
739
+ }
740
+ }
741
+ const headerBag = headers;
742
+ const exact = headerValueToString(headerBag[name], name);
743
+ if (exact !== void 0) {
744
+ return exact;
745
+ }
746
+ const lowered = name.toLowerCase();
747
+ for (const key of Object.keys(headers)) {
748
+ if (key !== name && key.toLowerCase() === lowered) {
749
+ const value = headerValueToString(headerBag[key], name);
750
+ if (value !== void 0) {
751
+ return value;
752
+ }
753
+ }
754
+ }
755
+ return void 0;
756
+ }
757
+ function isHex(value, length) {
758
+ if (typeof value !== "string" || value.length !== length) {
759
+ return false;
760
+ }
761
+ for (let i = 0; i < value.length; i++) {
762
+ const c = value[i];
763
+ const isDigit = c >= "0" && c <= "9";
764
+ const isLowerHex = c >= "a" && c <= "f";
765
+ if (!isDigit && !isLowerHex) {
766
+ return false;
767
+ }
768
+ }
769
+ return true;
770
+ }
771
+ function parseTraceparent(value) {
772
+ if (!value || typeof value !== "string") {
773
+ return void 0;
774
+ }
775
+ const match = TRACEPARENT_RE.exec(value.trim());
776
+ if (!match) {
777
+ return void 0;
778
+ }
779
+ const traceId = match[1];
780
+ const spanId = match[2];
781
+ const traceFlags = match[3];
782
+ if (traceId === ZERO_TRACE_ID || spanId === ZERO_SPAN_ID) {
783
+ return void 0;
784
+ }
785
+ return { traceId, spanId, traceFlags };
786
+ }
787
+ function formatTraceparent(traceId, spanId, traceFlags = DEFAULT_TRACE_FLAGS) {
788
+ if (!isHex(traceId, 32) || traceId === ZERO_TRACE_ID) {
789
+ return void 0;
790
+ }
791
+ if (!isHex(spanId, 16) || spanId === ZERO_SPAN_ID) {
792
+ return void 0;
793
+ }
794
+ const flags = isHex(traceFlags, 2) ? traceFlags : DEFAULT_TRACE_FLAGS;
795
+ return `00-${traceId}-${spanId}-${flags}`;
796
+ }
797
+ function percentEncode(value) {
798
+ return encodeURIComponent(value);
799
+ }
800
+ function percentDecode(value) {
801
+ if (!value.includes("%")) {
802
+ return value;
803
+ }
804
+ try {
805
+ return decodeURIComponent(value);
806
+ } catch {
807
+ return value;
808
+ }
809
+ }
810
+ function parseBaggage(value) {
811
+ const result = {};
812
+ if (!value || typeof value !== "string") {
813
+ return result;
814
+ }
815
+ const bounded = capBaggageToMemberBoundary(value);
816
+ for (let member of bounded.split(",")) {
817
+ member = member.trim();
818
+ if (!member || !member.includes("=")) {
819
+ continue;
820
+ }
821
+ member = member.split(";", 1)[0];
822
+ const eq = member.indexOf("=");
823
+ const key = percentDecode(member.slice(0, eq).trim());
824
+ const val = member.slice(eq + 1).trim();
825
+ if (!key) {
826
+ continue;
827
+ }
828
+ result[key] = percentDecode(val);
829
+ }
830
+ return result;
831
+ }
832
+ function mergeBaggage(existing, braintrustParent) {
833
+ let btMember = void 0;
834
+ if (braintrustParent) {
835
+ const encodedKey = percentEncode(BRAINTRUST_PARENT_KEY);
836
+ const encodedVal = percentEncode(String(braintrustParent));
837
+ btMember = `${encodedKey}=${encodedVal}`;
838
+ if (utf8ByteLength(btMember) > MAX_BAGGAGE_LENGTH) {
839
+ btMember = void 0;
840
+ }
841
+ }
842
+ let byteBudget = MAX_BAGGAGE_LENGTH;
843
+ let memberBudget = MAX_BAGGAGE_MEMBERS;
844
+ if (btMember !== void 0) {
845
+ byteBudget -= utf8ByteLength(btMember) + 1;
846
+ memberBudget -= 1;
847
+ }
848
+ const relayed = [];
849
+ let length = 0;
850
+ if (existing && typeof existing === "string") {
851
+ for (const rawMember of existing.split(",")) {
852
+ const member = rawMember.trim();
853
+ if (!member || !member.includes("=")) {
854
+ continue;
855
+ }
856
+ const keyPart = member.split(";", 1)[0].split("=", 1)[0];
857
+ const key = percentDecode(keyPart.trim());
858
+ if (key === BRAINTRUST_PARENT_KEY) {
859
+ continue;
860
+ }
861
+ if (relayed.length >= memberBudget) {
862
+ break;
863
+ }
864
+ const cost = utf8ByteLength(member) + (relayed.length ? 1 : 0);
865
+ if (length + cost > byteBudget) {
866
+ break;
867
+ }
868
+ relayed.push(member);
869
+ length += cost;
870
+ }
871
+ }
872
+ const members = btMember !== void 0 ? [...relayed, btMember] : relayed;
873
+ if (!members.length) {
874
+ return void 0;
875
+ }
876
+ return members.join(",");
594
877
  }
595
878
 
596
879
  // util/db_fields.ts
@@ -1198,7 +1481,7 @@ var SpanComponentsV3 = class _SpanComponentsV3 {
1198
1481
  case 3 /* PLAYGROUND_LOGS */:
1199
1482
  return { prompt_session_id: this.data.object_id, log_id: "x" };
1200
1483
  default:
1201
- const _ = this.data.object_type;
1484
+ this.data.object_type;
1202
1485
  throw new Error("Impossible");
1203
1486
  }
1204
1487
  }
@@ -1731,7 +2014,7 @@ var SpanComponentsV4 = class _SpanComponentsV4 {
1731
2014
  case 3 /* PLAYGROUND_LOGS */:
1732
2015
  return { prompt_session_id: this.data.object_id, log_id: "x" };
1733
2016
  default:
1734
- const _ = this.data.object_type;
2017
+ this.data.object_type;
1735
2018
  throw new Error(`Invalid object_type ${this.data.object_type}`);
1736
2019
  }
1737
2020
  }
@@ -1921,7 +2204,8 @@ var AclObjectType = z6.union([
1921
2204
  "role",
1922
2205
  "org_member",
1923
2206
  "project_log",
1924
- "org_project"
2207
+ "org_project",
2208
+ "org_audit_logs"
1925
2209
  ]),
1926
2210
  z6.null()
1927
2211
  ]);
@@ -1947,6 +2231,17 @@ var Acl = z6.object({
1947
2231
  _object_org_id: z6.string().uuid(),
1948
2232
  created: z6.union([z6.string(), z6.null()]).optional()
1949
2233
  });
2234
+ var Agent = z6.object({
2235
+ id: z6.string().uuid(),
2236
+ project_id: z6.string().uuid(),
2237
+ user_id: z6.string().uuid(),
2238
+ created: z6.union([z6.string(), z6.null()]).optional(),
2239
+ name: z6.string(),
2240
+ slug: z6.string(),
2241
+ kind: z6.string(),
2242
+ description: z6.union([z6.string(), z6.null()]).optional(),
2243
+ metadata: z6.union([z6.object({}).partial().passthrough(), z6.null()]).optional()
2244
+ });
1950
2245
  var AISecret = z6.object({
1951
2246
  id: z6.string().uuid(),
1952
2247
  created: z6.union([z6.string(), z6.null()]).optional(),
@@ -2093,6 +2388,7 @@ var AttachmentStatus = z6.object({
2093
2388
  upload_status: UploadStatus,
2094
2389
  error_message: z6.string().optional()
2095
2390
  });
2391
+ var AutomationStatus = z6.enum(["active", "paused"]);
2096
2392
  var FunctionTypeEnum = z6.enum([
2097
2393
  "llm",
2098
2394
  "scorer",
@@ -2138,7 +2434,9 @@ var TopicMapData = z6.object({
2138
2434
  topic_names: z6.record(z6.string()).optional(),
2139
2435
  generation_settings: TopicMapGenerationSettings.optional(),
2140
2436
  disable_reconciliation: z6.boolean().optional(),
2141
- distance_threshold: z6.number().optional()
2437
+ distance_threshold: z6.number().optional(),
2438
+ btql_filter: z6.string().optional(),
2439
+ automation_btql_filter: z6.string().optional()
2142
2440
  });
2143
2441
  var BatchedFacetData = z6.object({
2144
2442
  type: z6.literal("batched_facet"),
@@ -2421,7 +2719,7 @@ var DatasetEvent = z6.object({
2421
2719
  origin: ObjectReferenceNullish.optional(),
2422
2720
  comments: z6.union([z6.array(z6.unknown()), z6.null()]).optional(),
2423
2721
  audit_data: z6.union([z6.array(z6.unknown()), z6.null()]).optional(),
2424
- facets: z6.union([z6.object({}).partial().passthrough(), z6.null()]).optional(),
2722
+ facets: z6.union([z6.record(z6.union([z6.string(), z6.null()])), z6.null()]).optional(),
2425
2723
  classifications: z6.union([
2426
2724
  z6.record(
2427
2725
  z6.array(
@@ -2573,7 +2871,7 @@ var ExperimentEvent = z6.object({
2573
2871
  origin: ObjectReferenceNullish.optional(),
2574
2872
  comments: z6.union([z6.array(z6.unknown()), z6.null()]).optional(),
2575
2873
  audit_data: z6.union([z6.array(z6.unknown()), z6.null()]).optional(),
2576
- facets: z6.union([z6.object({}).partial().passthrough(), z6.null()]).optional(),
2874
+ facets: z6.union([z6.record(z6.union([z6.string(), z6.null()])), z6.null()]).optional(),
2577
2875
  classifications: z6.union([
2578
2876
  z6.record(
2579
2877
  z6.array(
@@ -2711,7 +3009,8 @@ var PromptParserNullish = z6.union([
2711
3009
  use_cot: z6.boolean(),
2712
3010
  choice_scores: z6.record(z6.number().gte(0).lte(1)).optional(),
2713
3011
  choice: z6.array(z6.string()).optional(),
2714
- allow_no_match: z6.boolean().optional()
3012
+ allow_no_match: z6.boolean().optional(),
3013
+ allow_skip: z6.boolean().optional()
2715
3014
  }),
2716
3015
  z6.null()
2717
3016
  ]);
@@ -3041,6 +3340,9 @@ var Group = z6.object({
3041
3340
  var GroupScope = z6.object({
3042
3341
  type: z6.literal("group"),
3043
3342
  group_by: z6.string(),
3343
+ interval_seconds: z6.number().gte(1).optional(),
3344
+ max_traces: z6.number().int().gte(1).lte(64).optional(),
3345
+ placement: z6.enum(["first", "each"]),
3044
3346
  idle_seconds: z6.number().optional()
3045
3347
  });
3046
3348
  var IfExists = z6.enum(["error", "ignore", "replace"]);
@@ -3189,6 +3491,10 @@ var RetentionObjectType = z6.enum([
3189
3491
  "experiment",
3190
3492
  "dataset"
3191
3493
  ]);
3494
+ var TopicAutomationFacetModel = z6.union([
3495
+ z6.enum(["brain-facet-latest", "brain-facet-1", "brain-facet-2"]),
3496
+ z6.null()
3497
+ ]);
3192
3498
  var TopicMapFunctionAutomation = z6.object({
3193
3499
  function: SavedFunctionId.and(z6.unknown()),
3194
3500
  btql_filter: z6.union([z6.string(), z6.null()]).optional()
@@ -3201,7 +3507,9 @@ var TopicAutomationDataScope = z6.union([
3201
3507
  ]);
3202
3508
  var TopicAutomationConfig = z6.object({
3203
3509
  event_type: z6.literal("topic"),
3510
+ status: AutomationStatus.optional(),
3204
3511
  sampling_rate: z6.number().gte(0).lte(1),
3512
+ facet_model: TopicAutomationFacetModel.optional(),
3205
3513
  facet_functions: z6.array(SavedFunctionId),
3206
3514
  topic_map_functions: z6.array(TopicMapFunctionAutomation),
3207
3515
  scope: z6.union([SpanScope, TraceScope, GroupScope, z6.null()]).optional(),
@@ -3215,6 +3523,19 @@ var TopicAutomationConfig = z6.object({
3215
3523
  z6.null()
3216
3524
  ]).optional()
3217
3525
  });
3526
+ var TopicDigestAutomationConfig = z6.object({
3527
+ event_type: z6.literal("topic_digest"),
3528
+ status: AutomationStatus.optional(),
3529
+ window_seconds: z6.number().int().gte(3600).lte(2592e3).optional().default(86400),
3530
+ scheduled_time_minutes_utc: z6.number().int().gte(0).lte(1439),
3531
+ action: z6.object({
3532
+ type: z6.literal("slack"),
3533
+ workspace_id: z6.string(),
3534
+ channel: z6.string(),
3535
+ message_template: z6.string().optional()
3536
+ }),
3537
+ topic_map_function_ids: z6.array(z6.string()).max(10).optional()
3538
+ });
3218
3539
  var ProjectAutomation = z6.object({
3219
3540
  id: z6.string().uuid(),
3220
3541
  project_id: z6.string().uuid(),
@@ -3239,6 +3560,7 @@ var ProjectAutomation = z6.object({
3239
3560
  }),
3240
3561
  z6.object({
3241
3562
  event_type: z6.literal("btql_export"),
3563
+ status: AutomationStatus.optional(),
3242
3564
  export_definition: z6.union([
3243
3565
  z6.object({ type: z6.literal("log_traces") }),
3244
3566
  z6.object({ type: z6.literal("log_spans") }),
@@ -3261,6 +3583,21 @@ var ProjectAutomation = z6.object({
3261
3583
  ]),
3262
3584
  batch_size: z6.union([z6.number(), z6.null()]).optional()
3263
3585
  }),
3586
+ z6.object({
3587
+ event_type: z6.literal("async_query"),
3588
+ status: AutomationStatus.optional(),
3589
+ created_by_user_id: z6.string().uuid(),
3590
+ object_type: z6.enum([
3591
+ "project_logs",
3592
+ "experiment",
3593
+ "dataset",
3594
+ "playground_logs"
3595
+ ]),
3596
+ object_id: z6.string(),
3597
+ query: z6.string(),
3598
+ format: z6.literal("jsonl"),
3599
+ batch_size: z6.union([z6.number(), z6.null()]).optional()
3600
+ }),
3264
3601
  z6.object({
3265
3602
  event_type: z6.literal("retention"),
3266
3603
  object_type: RetentionObjectType,
@@ -3279,7 +3616,8 @@ var ProjectAutomation = z6.object({
3279
3616
  })
3280
3617
  ])
3281
3618
  }),
3282
- TopicAutomationConfig
3619
+ TopicAutomationConfig,
3620
+ TopicDigestAutomationConfig
3283
3621
  ])
3284
3622
  });
3285
3623
  var ProjectLogsEvent = z6.object({
@@ -3318,7 +3656,7 @@ var ProjectLogsEvent = z6.object({
3318
3656
  comments: z6.union([z6.array(z6.unknown()), z6.null()]).optional(),
3319
3657
  audit_data: z6.union([z6.array(z6.unknown()), z6.null()]).optional(),
3320
3658
  _async_scoring_state: z6.unknown().optional(),
3321
- facets: z6.union([z6.object({}).partial().passthrough(), z6.null()]).optional(),
3659
+ facets: z6.union([z6.record(z6.union([z6.string(), z6.null()])), z6.null()]).optional(),
3322
3660
  classifications: z6.union([
3323
3661
  z6.record(
3324
3662
  z6.array(
@@ -3367,11 +3705,34 @@ var ProjectScoreCategories = z6.union([
3367
3705
  z6.array(z6.string()),
3368
3706
  z6.null()
3369
3707
  ]);
3708
+ var ProjectScoreCondition = z6.union([
3709
+ z6.object({
3710
+ when: z6.object({
3711
+ clauses: z6.union([z6.array(z6.string()), z6.null()]),
3712
+ subspan_clauses: z6.union([z6.array(z6.string()), z6.null()]),
3713
+ trace_clauses: z6.union([z6.array(z6.string()), z6.null()])
3714
+ }).partial(),
3715
+ behavior: z6.literal("hidden").optional().default("hidden")
3716
+ }),
3717
+ z6.null()
3718
+ ]);
3370
3719
  var ProjectScoreConfig = z6.union([
3371
3720
  z6.object({
3372
3721
  multi_select: z6.union([z6.boolean(), z6.null()]),
3373
3722
  destination: z6.union([z6.string(), z6.null()]),
3374
- online: OnlineScoreConfig
3723
+ visibility: z6.union([
3724
+ z6.object({
3725
+ users: z6.union([z6.array(z6.string()), z6.null()]),
3726
+ groups: z6.union([z6.array(z6.string()), z6.null()])
3727
+ }).partial(),
3728
+ z6.null()
3729
+ ]),
3730
+ online: OnlineScoreConfig,
3731
+ condition: ProjectScoreCondition,
3732
+ object_types: z6.union([
3733
+ z6.array(z6.enum(["project_logs", "dataset", "experiment"])),
3734
+ z6.null()
3735
+ ])
3375
3736
  }).partial(),
3376
3737
  z6.null()
3377
3738
  ]);
@@ -3556,8 +3917,7 @@ var User = z6.object({
3556
3917
  family_name: z6.union([z6.string(), z6.null()]).optional(),
3557
3918
  email: z6.union([z6.string(), z6.null()]).optional(),
3558
3919
  avatar_url: z6.union([z6.string(), z6.null()]).optional(),
3559
- created: z6.union([z6.string(), z6.null()]).optional(),
3560
- last_active_at: z6.union([z6.number(), z6.null()]).optional()
3920
+ created: z6.union([z6.string(), z6.null()]).optional()
3561
3921
  });
3562
3922
  var ViewDataSearch = z6.union([
3563
3923
  z6.object({
@@ -4846,7 +5206,10 @@ var BraintrustContextManager = class extends ContextManager {
4846
5206
  }
4847
5207
  };
4848
5208
  function getSpanComponentsClass() {
4849
- return globalThis.BRAINTRUST_SPAN_COMPONENT ? globalThis.BRAINTRUST_SPAN_COMPONENT : SpanComponentsV3;
5209
+ if (globalThis.BRAINTRUST_SPAN_COMPONENT) {
5210
+ return globalThis.BRAINTRUST_SPAN_COMPONENT;
5211
+ }
5212
+ return resolveUseLegacyUuidIds() ? SpanComponentsV3 : SpanComponentsV4;
4850
5213
  }
4851
5214
  function getContextManager() {
4852
5215
  return globalThis.BRAINTRUST_CONTEXT_MANAGER ? new globalThis.BRAINTRUST_CONTEXT_MANAGER() : new BraintrustContextManager();
@@ -4882,6 +5245,9 @@ var NoopSpan = class {
4882
5245
  async export() {
4883
5246
  return "";
4884
5247
  }
5248
+ inject(carrier) {
5249
+ return carrier ?? {};
5250
+ }
4885
5251
  async permalink() {
4886
5252
  return NOOP_SPAN_PERMALINK;
4887
5253
  }
@@ -4932,6 +5298,10 @@ var loginSchema = z8.strictObject({
4932
5298
  debugLogLevelDisabled: z8.boolean().optional()
4933
5299
  });
4934
5300
  var stateNonce = 0;
5301
+ var V1_PROXY_SUFFIX = "/v1/proxy";
5302
+ function normalizeProxyConnUrl(proxyUrl) {
5303
+ return proxyUrl.endsWith(V1_PROXY_SUFFIX) ? proxyUrl.slice(0, proxyUrl.length - V1_PROXY_SUFFIX.length) : proxyUrl;
5304
+ }
4935
5305
  var BraintrustState = class _BraintrustState {
4936
5306
  constructor(loginParams) {
4937
5307
  this.loginParams = loginParams;
@@ -5202,7 +5572,10 @@ var BraintrustState = class _BraintrustState {
5202
5572
  if (!this.proxyUrl) {
5203
5573
  throw new Error("Must initialize proxyUrl before requesting proxyConn");
5204
5574
  }
5205
- this._proxyConn = new HTTPConnection(this.proxyUrl, this.fetch);
5575
+ this._proxyConn = new HTTPConnection(
5576
+ normalizeProxyConnUrl(this.proxyUrl),
5577
+ this.fetch
5578
+ );
5206
5579
  }
5207
5580
  return this._proxyConn;
5208
5581
  }
@@ -5888,7 +6261,7 @@ async function permalink(slug, opts) {
5888
6261
  return state.appUrl;
5889
6262
  };
5890
6263
  try {
5891
- const components = getSpanComponentsClass().fromStr(slug);
6264
+ const components = SpanComponentsV4.fromStr(slug);
5892
6265
  const object_type = spanObjectTypeV3ToString(components.data.object_type);
5893
6266
  const [orgName, appUrl, object_id] = await Promise.all([
5894
6267
  getOrgName(),
@@ -5912,35 +6285,47 @@ function startSpanParentArgs(args) {
5912
6285
  let argParentObjectId = void 0;
5913
6286
  let argParentSpanIds = void 0;
5914
6287
  let argPropagatedEvent = void 0;
5915
- if (args.parent) {
6288
+ let argPropagatedState = void 0;
6289
+ const { parentSlug, propagatedState: parentPropagatedState } = normalizeParent(args.parent, args.state);
6290
+ if (parentSlug) {
5916
6291
  if (args.parentSpanIds) {
5917
6292
  throw new Error("Cannot specify both parent and parentSpanIds");
5918
6293
  }
5919
- const parentComponents = getSpanComponentsClass().fromStr(args.parent);
6294
+ const parentComponents = SpanComponentsV4.fromStr(parentSlug);
5920
6295
  if (args.parentObjectType !== parentComponents.data.object_type) {
5921
6296
  throw new Error(
5922
6297
  `Mismatch between expected span parent object type ${args.parentObjectType} and provided type ${parentComponents.data.object_type}`
5923
6298
  );
5924
6299
  }
5925
6300
  argParentObjectId = args.parentObjectId;
5926
- if (parentComponents.data.row_id) {
6301
+ if (parentComponents.data.row_id && parentSpanIdsUsable(
6302
+ parentComponents.data.span_id,
6303
+ parentComponents.data.root_span_id
6304
+ )) {
5927
6305
  argParentSpanIds = {
5928
6306
  spanId: parentComponents.data.span_id,
5929
6307
  rootSpanId: parentComponents.data.root_span_id
5930
6308
  };
5931
6309
  }
5932
6310
  argPropagatedEvent = args.propagatedEvent ?? (parentComponents.data.propagated_event ?? void 0);
6311
+ const propagatedState = args.propagatedState ?? parentPropagatedState;
6312
+ if (propagatedState) {
6313
+ const { braintrustParent: _ignoredBraintrustParent, ...w3cState } = propagatedState;
6314
+ argPropagatedState = w3cState;
6315
+ }
5933
6316
  } else {
5934
6317
  argParentObjectId = args.parentObjectId;
5935
6318
  argParentSpanIds = args.parentSpanIds;
5936
6319
  argPropagatedEvent = args.propagatedEvent;
6320
+ argPropagatedState = args.propagatedState;
5937
6321
  }
5938
6322
  return {
5939
6323
  parentObjectType: args.parentObjectType,
5940
6324
  parentObjectId: argParentObjectId,
5941
6325
  parentComputeObjectMetadataArgs: args.parentComputeObjectMetadataArgs,
5942
6326
  parentSpanIds: argParentSpanIds,
5943
- propagatedEvent: argPropagatedEvent
6327
+ propagatedEvent: argPropagatedEvent,
6328
+ propagatedState: argPropagatedState
5944
6329
  };
5945
6330
  }
5946
6331
  var Logger = class {
@@ -6141,6 +6526,22 @@ var Logger = class {
6141
6526
  _getLinkBaseUrl() {
6142
6527
  return _getLinkBaseUrl(this.state, this._linkArgs);
6143
6528
  }
6529
+ /**
6530
+ * Return this logger's Braintrust parent string (`project_id:<id>` or
6531
+ * `project_name:<name>`) for the `braintrust.parent` baggage entry, or
6532
+ * undefined when it cannot be determined synchronously.
6533
+ */
6534
+ _getOtelParent() {
6535
+ const id = this.computeMetadataArgs?.project_id || this.lazyId.getSync().value;
6536
+ if (id) {
6537
+ return `project_id:${id}`;
6538
+ }
6539
+ const name = this.computeMetadataArgs?.project_name;
6540
+ if (name) {
6541
+ return `project_name:${name}`;
6542
+ }
6543
+ return void 0;
6544
+ }
6144
6545
  };
6145
6546
  function castLogger(logger, asyncFlush) {
6146
6547
  if (logger === void 0) return void 0;
@@ -6235,12 +6636,12 @@ function stringifyWithOverflowMeta(item) {
6235
6636
  object_ids: pickLogs3OverflowObjectIds(record),
6236
6637
  is_delete: record[OBJECT_DELETE_FIELD] === true,
6237
6638
  input_row: {
6238
- byte_size: utf8ByteLength(str)
6639
+ byte_size: utf8ByteLength2(str)
6239
6640
  }
6240
6641
  }
6241
6642
  };
6242
6643
  }
6243
- function utf8ByteLength(value) {
6644
+ function utf8ByteLength2(value) {
6244
6645
  if (typeof TextEncoder !== "undefined") {
6245
6646
  return new TextEncoder().encode(value).length;
6246
6647
  }
@@ -6571,7 +6972,7 @@ var HTTPBackgroundLogger = class _HTTPBackgroundLogger {
6571
6972
  }) {
6572
6973
  const conn = await this.apiConn.get();
6573
6974
  const dataStr = constructLogs3Data(items);
6574
- const payloadBytes = utf8ByteLength(dataStr);
6975
+ const payloadBytes = utf8ByteLength2(dataStr);
6575
6976
  const useOverflow = canUseOverflow && payloadBytes > maxRequestSize;
6576
6977
  if (this.allPublishPayloadsDir) {
6577
6978
  await _HTTPBackgroundLogger.writePayloadToDir({
@@ -7163,6 +7564,8 @@ function initDataset(projectOrOptions, optionalOptions) {
7163
7564
  const normalizedVersion = selection.version;
7164
7565
  const normalizedEnvironment = selection.environment;
7165
7566
  const normalizedSnapshotName = selection.snapshotName;
7567
+ const cliInternalBtql = globalThis.__bt_eval_internal_btql;
7568
+ const internalBtql = cliInternalBtql === void 0 ? _internal_btql : _internal_btql === void 0 ? cliInternalBtql : isObject(_internal_btql) ? { ...cliInternalBtql, ..._internal_btql } : _internal_btql;
7166
7569
  const state = stateArg ?? _globalState;
7167
7570
  const lazyMetadata = new LazyValue(
7168
7571
  async () => {
@@ -7214,7 +7617,7 @@ function initDataset(projectOrOptions, optionalOptions) {
7214
7617
  lazyMetadata,
7215
7618
  typeof resolvedVersion === "string" ? resolvedVersion : void 0,
7216
7619
  legacy,
7217
- _internal_btql,
7620
+ internalBtql,
7218
7621
  resolvedVersion instanceof LazyValue || normalizedEnvironment !== void 0 || normalizedSnapshotName !== void 0 ? {
7219
7622
  ...resolvedVersion instanceof LazyValue ? {
7220
7623
  lazyPinnedVersion: resolvedVersion
@@ -7425,87 +7828,324 @@ function currentSpan(options) {
7425
7828
  const state = options?.state ?? _globalState;
7426
7829
  return state.contextManager.getCurrentSpan() ?? NOOP_SPAN;
7427
7830
  }
7428
- function getSpanParentObject(options) {
7831
+ function getSpanParentObjectAndPropagatedState(options) {
7429
7832
  const state = options?.state ?? _globalState;
7430
7833
  const parentSpan = currentSpan({ state });
7431
7834
  if (!Object.is(parentSpan, NOOP_SPAN)) {
7432
- return parentSpan;
7835
+ return { parentObject: parentSpan, propagatedState: void 0 };
7836
+ }
7837
+ const parent = options?.parent ?? state.currentParent.getStore();
7838
+ const { parentSlug, propagatedState } = normalizeParent(parent, state);
7839
+ if (parentSlug) {
7840
+ return {
7841
+ parentObject: SpanComponentsV4.fromStr(parentSlug),
7842
+ propagatedState
7843
+ };
7433
7844
  }
7434
- const parentStr = options?.parent ?? state.currentParent.getStore();
7435
- if (parentStr) return getSpanComponentsClass().fromStr(parentStr);
7436
7845
  const experiment = currentExperiment();
7437
7846
  if (experiment) {
7438
- return experiment;
7847
+ return { parentObject: experiment, propagatedState: void 0 };
7439
7848
  }
7440
7849
  const logger = currentLogger(options);
7441
7850
  if (logger) {
7442
- return logger;
7851
+ return { parentObject: logger, propagatedState: void 0 };
7443
7852
  }
7444
- return NOOP_SPAN;
7853
+ return { parentObject: NOOP_SPAN, propagatedState: void 0 };
7445
7854
  }
7446
- function logError(span, error) {
7447
- let errorMessage = "<error>";
7448
- let stackTrace = "";
7449
- if (error instanceof Error) {
7450
- errorMessage = error.message;
7451
- stackTrace = error.stack || "";
7452
- } else {
7453
- errorMessage = String(error);
7855
+ function getSpanParentObject(options) {
7856
+ return getSpanParentObjectAndPropagatedState(options).parentObject;
7857
+ }
7858
+ function currentBraintrustParent(state) {
7859
+ const resolvedState = state ?? _globalState;
7860
+ const experiment = currentExperiment({ state: resolvedState });
7861
+ if (experiment) {
7862
+ try {
7863
+ return experiment._getOtelParent() ?? void 0;
7864
+ } catch {
7865
+ return void 0;
7866
+ }
7454
7867
  }
7455
- span.log({ error: `${errorMessage}
7456
-
7457
- ${stackTrace}` });
7868
+ const logger = currentLogger({ state: resolvedState });
7869
+ if (logger) {
7870
+ try {
7871
+ return logger._getOtelParent() ?? void 0;
7872
+ } catch {
7873
+ return void 0;
7874
+ }
7875
+ }
7876
+ return void 0;
7458
7877
  }
7459
- function traced(callback, args) {
7460
- const { span, isSyncFlushLogger } = startSpanAndIsLogger(args);
7461
- const ret = runCatchFinally(
7462
- () => {
7463
- if (args?.setCurrent ?? true) {
7464
- return withCurrent(span, callback);
7465
- } else {
7466
- return callback(span);
7878
+ function braintrustParentToComponents(braintrustParent) {
7879
+ if (!braintrustParent) {
7880
+ return void 0;
7881
+ }
7882
+ if (braintrustParent.startsWith("project_id:")) {
7883
+ const objectId = braintrustParent.slice("project_id:".length);
7884
+ return objectId ? {
7885
+ objectType: 2 /* PROJECT_LOGS */,
7886
+ objectId,
7887
+ computeArgs: void 0
7888
+ } : void 0;
7889
+ }
7890
+ if (braintrustParent.startsWith("project_name:")) {
7891
+ const name = braintrustParent.slice("project_name:".length);
7892
+ return name ? {
7893
+ objectType: 2 /* PROJECT_LOGS */,
7894
+ objectId: void 0,
7895
+ computeArgs: { project_name: name }
7896
+ } : void 0;
7897
+ }
7898
+ if (braintrustParent.startsWith("experiment_id:")) {
7899
+ const objectId = braintrustParent.slice("experiment_id:".length);
7900
+ return objectId ? {
7901
+ objectType: 1 /* EXPERIMENT */,
7902
+ objectId,
7903
+ computeArgs: void 0
7904
+ } : void 0;
7905
+ }
7906
+ return void 0;
7907
+ }
7908
+ function isMutableHeaderTupleArray(carrier) {
7909
+ return Array.isArray(carrier) && carrier.every((item) => Array.isArray(item) && typeof item[0] === "string");
7910
+ }
7911
+ function setHeader(carrier, name, value) {
7912
+ if (isMutableHeaderTupleArray(carrier)) {
7913
+ const lowered2 = name.toLowerCase();
7914
+ for (let i = carrier.length - 1; i >= 0; i--) {
7915
+ if (carrier[i][0].toLowerCase() === lowered2) {
7916
+ carrier.splice(i, 1);
7467
7917
  }
7468
- },
7469
- (e) => {
7470
- logError(span, e);
7471
- throw e;
7472
- },
7473
- () => span.end()
7474
- );
7475
- if (args?.asyncFlush === void 0 || args?.asyncFlush) {
7476
- return ret;
7477
- } else {
7478
- return (async () => {
7479
- const awaitedRet = await ret;
7480
- if (isSyncFlushLogger) {
7481
- await span.flush();
7918
+ }
7919
+ carrier.push([name, value]);
7920
+ return;
7921
+ }
7922
+ const setter = carrier.set;
7923
+ if (typeof setter === "function") {
7924
+ const deleter = carrier.delete;
7925
+ if (typeof deleter === "function") {
7926
+ try {
7927
+ deleter.call(carrier, name);
7928
+ } catch {
7482
7929
  }
7483
- return awaitedRet;
7484
- })();
7930
+ }
7931
+ setter.call(carrier, name, value);
7932
+ return;
7485
7933
  }
7934
+ const nodeSetter = carrier.setHeader;
7935
+ if (typeof nodeSetter === "function") {
7936
+ const remover = carrier.removeHeader;
7937
+ if (typeof remover === "function") {
7938
+ try {
7939
+ remover.call(carrier, name);
7940
+ } catch {
7941
+ }
7942
+ }
7943
+ nodeSetter.call(carrier, name, value);
7944
+ return;
7945
+ }
7946
+ const headerSetter = carrier.header;
7947
+ if (typeof headerSetter === "function") {
7948
+ const deleter = carrier.delete;
7949
+ if (typeof deleter === "function") {
7950
+ try {
7951
+ deleter.call(carrier, name);
7952
+ } catch {
7953
+ }
7954
+ }
7955
+ const remover = carrier.removeHeader;
7956
+ if (typeof remover === "function") {
7957
+ try {
7958
+ remover.call(carrier, name);
7959
+ } catch {
7960
+ }
7961
+ }
7962
+ headerSetter.call(carrier, name, value);
7963
+ return;
7964
+ }
7965
+ const headerBag = carrier;
7966
+ const lowered = name.toLowerCase();
7967
+ for (const key of Object.keys(headerBag)) {
7968
+ if (key !== name && key.toLowerCase() === lowered) {
7969
+ delete headerBag[key];
7970
+ }
7971
+ }
7972
+ headerBag[name] = value;
7486
7973
  }
7487
- function startSpan(args) {
7488
- return startSpanAndIsLogger(args).span;
7489
- }
7490
- async function flush(options) {
7974
+ function deleteHeader(carrier, name) {
7975
+ const lowered = name.toLowerCase();
7976
+ if (isMutableHeaderTupleArray(carrier)) {
7977
+ for (let i = carrier.length - 1; i >= 0; i--) {
7978
+ if (carrier[i][0].toLowerCase() === lowered) {
7979
+ carrier.splice(i, 1);
7980
+ }
7981
+ }
7982
+ return;
7983
+ }
7984
+ const deleter = carrier.delete;
7985
+ if (typeof deleter === "function") {
7986
+ try {
7987
+ deleter.call(carrier, name);
7988
+ return;
7989
+ } catch {
7990
+ }
7991
+ }
7992
+ const remover = carrier.removeHeader;
7993
+ if (typeof remover === "function") {
7994
+ try {
7995
+ remover.call(carrier, name);
7996
+ return;
7997
+ } catch {
7998
+ }
7999
+ }
8000
+ const headerBag = carrier;
8001
+ for (const key of Object.keys(headerBag)) {
8002
+ if (key.toLowerCase() === lowered) {
8003
+ delete headerBag[key];
8004
+ }
8005
+ }
8006
+ }
8007
+ function _injectIntoCarrier(carrier, args) {
8008
+ const traceFlags = args.propagatedState?.traceFlags;
8009
+ const traceparent = traceFlags ? formatTraceparent(args.traceId, args.spanId, traceFlags) : formatTraceparent(args.traceId, args.spanId);
8010
+ if (traceparent === void 0) {
8011
+ return;
8012
+ }
8013
+ setHeader(carrier, TRACEPARENT_HEADER, traceparent);
8014
+ const tracestate = args.propagatedState?.tracestate;
8015
+ if (tracestate) {
8016
+ setHeader(carrier, TRACESTATE_HEADER, tracestate);
8017
+ }
8018
+ const existing = getHeader(carrier, BAGGAGE_HEADER);
8019
+ const baggageValue = mergeBaggage(existing, args.braintrustParent);
8020
+ if (baggageValue !== void 0) {
8021
+ setHeader(carrier, BAGGAGE_HEADER, baggageValue);
8022
+ } else if (existing !== void 0) {
8023
+ deleteHeader(carrier, BAGGAGE_HEADER);
8024
+ }
8025
+ }
8026
+ function resolveW3cParent(context, state) {
8027
+ const traceparent = getHeader(context, TRACEPARENT_HEADER);
8028
+ const parsed = traceparent ? parseTraceparent(traceparent) : void 0;
8029
+ if (parsed === void 0) {
8030
+ return { parentSlug: void 0, propagatedState: void 0 };
8031
+ }
8032
+ const { traceId, spanId, traceFlags } = parsed;
8033
+ let braintrustParent = void 0;
8034
+ const baggageValue = getHeader(context, BAGGAGE_HEADER);
8035
+ if (baggageValue) {
8036
+ braintrustParent = parseBaggage(baggageValue)[BRAINTRUST_PARENT_KEY];
8037
+ }
8038
+ if (!braintrustParent) {
8039
+ braintrustParent = currentBraintrustParent(state);
8040
+ }
8041
+ if (!braintrustParent) {
8042
+ debugLogger.warn(
8043
+ "Received traceparent without a braintrust.parent and no active logger/experiment; cannot route the trace. Starting a fresh local span instead."
8044
+ );
8045
+ return { parentSlug: void 0, propagatedState: void 0 };
8046
+ }
8047
+ const parsedParent = braintrustParentToComponents(braintrustParent);
8048
+ if (parsedParent === void 0) {
8049
+ debugLogger.warn(
8050
+ `Invalid braintrust.parent: ${JSON.stringify(braintrustParent)}`
8051
+ );
8052
+ return { parentSlug: void 0, propagatedState: void 0 };
8053
+ }
8054
+ const { objectType, objectId, computeArgs } = parsedParent;
8055
+ const tracestate = getHeader(context, TRACESTATE_HEADER);
8056
+ const slug = new SpanComponentsV4({
8057
+ object_type: objectType,
8058
+ ...computeArgs ? { compute_object_metadata_args: computeArgs } : { object_id: objectId },
8059
+ row_id: "bt-propagation",
8060
+ // non-empty to enable span_id/root_span_id
8061
+ span_id: spanId,
8062
+ root_span_id: traceId
8063
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
8064
+ }).toStr();
8065
+ return {
8066
+ parentSlug: slug,
8067
+ propagatedState: { tracestate, traceFlags, braintrustParent }
8068
+ };
8069
+ }
8070
+ function normalizeParent(parent, state) {
8071
+ if (parent && typeof parent === "object") {
8072
+ return resolveW3cParent(parent, state);
8073
+ }
8074
+ return {
8075
+ parentSlug: parent ?? void 0,
8076
+ propagatedState: void 0
8077
+ };
8078
+ }
8079
+ function parentSpanIdsUsable(spanId, rootSpanId) {
8080
+ return Boolean(spanId) && Boolean(rootSpanId);
8081
+ }
8082
+ function logError(span, error) {
8083
+ let errorMessage = "<error>";
8084
+ let stackTrace = "";
8085
+ if (error instanceof Error) {
8086
+ errorMessage = error.message;
8087
+ stackTrace = error.stack || "";
8088
+ } else {
8089
+ errorMessage = String(error);
8090
+ }
8091
+ span.log({ error: `${errorMessage}
8092
+
8093
+ ${stackTrace}` });
8094
+ }
8095
+ function traced(callback, args) {
8096
+ const { span, isSyncFlushLogger } = startSpanAndIsLogger(args);
8097
+ const ret = runCatchFinally(
8098
+ () => {
8099
+ if (args?.setCurrent ?? true) {
8100
+ return withCurrent(span, callback);
8101
+ } else {
8102
+ return callback(span);
8103
+ }
8104
+ },
8105
+ (e) => {
8106
+ logError(span, e);
8107
+ throw e;
8108
+ },
8109
+ () => span.end()
8110
+ );
8111
+ if (args?.asyncFlush === void 0 || args?.asyncFlush) {
8112
+ return ret;
8113
+ } else {
8114
+ return (async () => {
8115
+ const awaitedRet = await ret;
8116
+ if (isSyncFlushLogger) {
8117
+ await span.flush();
8118
+ }
8119
+ return awaitedRet;
8120
+ })();
8121
+ }
8122
+ }
8123
+ function startSpan(args) {
8124
+ return startSpanAndIsLogger(args).span;
8125
+ }
8126
+ async function flush(options) {
7491
8127
  const state = options?.state ?? _globalState;
7492
8128
  return await state.bgLogger().flush();
7493
8129
  }
7494
8130
  function startSpanAndIsLogger(args) {
7495
8131
  const state = args?.state ?? _globalState;
7496
- const parentObject = getSpanParentObject({
8132
+ const { parentObject, propagatedState } = getSpanParentObjectAndPropagatedState({
7497
8133
  asyncFlush: args?.asyncFlush,
7498
8134
  parent: args?.parent,
7499
8135
  state
7500
8136
  });
7501
8137
  if (parentObject instanceof SpanComponentsV3 || parentObject instanceof SpanComponentsV4) {
7502
- const parentSpanIds = parentObject.data.row_id ? {
8138
+ const parentSpanIds = parentObject.data.row_id && parentSpanIdsUsable(
8139
+ parentObject.data.span_id,
8140
+ parentObject.data.root_span_id
8141
+ ) ? {
7503
8142
  spanId: parentObject.data.span_id,
7504
8143
  rootSpanId: parentObject.data.root_span_id
7505
8144
  } : void 0;
8145
+ const { parent: _ignoredParent, ...spanArgs } = args ?? {};
7506
8146
  const span = new SpanImpl({
7507
8147
  state,
7508
- ...args,
8148
+ ...spanArgs,
7509
8149
  parentObjectType: parentObject.data.object_type,
7510
8150
  parentObjectId: new LazyValue(
7511
8151
  spanComponentsToObjectIdLambda(state, parentObject)
@@ -7513,7 +8153,8 @@ function startSpanAndIsLogger(args) {
7513
8153
  parentComputeObjectMetadataArgs: parentObject.data.compute_object_metadata_args ?? void 0,
7514
8154
  parentSpanIds,
7515
8155
  propagatedEvent: args?.propagatedEvent ?? // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
7516
- (parentObject.data.propagated_event ?? void 0)
8156
+ (parentObject.data.propagated_event ?? void 0),
8157
+ propagatedState
7517
8158
  });
7518
8159
  return {
7519
8160
  span,
@@ -7756,11 +8397,12 @@ function validateAndSanitizeExperimentLogFullArgs(event, hasDataset) {
7756
8397
  var DEFAULT_FETCH_BATCH_SIZE = 1e3;
7757
8398
  var MAX_BTQL_ITERATIONS = 1e4;
7758
8399
  var ObjectFetcher = class {
7759
- constructor(objectType, pinnedVersion, mutateRecord, _internal_btql) {
8400
+ constructor(objectType, pinnedVersion, mutateRecord, _internal_btql, _internalBrainstoreRealtime = true) {
7760
8401
  this.objectType = objectType;
7761
8402
  this.pinnedVersion = pinnedVersion;
7762
8403
  this.mutateRecord = mutateRecord;
7763
8404
  this._internal_btql = _internal_btql;
8405
+ this._internalBrainstoreRealtime = _internalBrainstoreRealtime;
7764
8406
  }
7765
8407
  _fetchedData = void 0;
7766
8408
  get id() {
@@ -7819,7 +8461,7 @@ var ObjectFetcher = class {
7819
8461
  ...internalBtqlWithoutReservedQueryKeys
7820
8462
  },
7821
8463
  use_columnstore: false,
7822
- brainstore_realtime: true,
8464
+ brainstore_realtime: this._internalBrainstoreRealtime,
7823
8465
  query_source: `js_sdk_object_fetcher_${this.objectType}`,
7824
8466
  ...this.pinnedVersion !== void 0 ? {
7825
8467
  version: this.pinnedVersion
@@ -8168,6 +8810,15 @@ View complete results in Braintrust or run experiment.summarize() again.`
8168
8810
  object_id: await this.id
8169
8811
  }).toStr();
8170
8812
  }
8813
+ /**
8814
+ * Return this experiment's Braintrust parent string (`experiment_id:<id>`) for
8815
+ * the `braintrust.parent` baggage entry, or undefined when it cannot be
8816
+ * determined synchronously.
8817
+ */
8818
+ _getOtelParent() {
8819
+ const id = this.lazyId.getSync().value;
8820
+ return id ? `experiment_id:${id}` : void 0;
8821
+ }
8171
8822
  /**
8172
8823
  * Flush any pending rows to the server.
8173
8824
  */
@@ -8210,7 +8861,8 @@ var ReadonlyExperiment = class extends ObjectFetcher {
8210
8861
  async *asDataset(options) {
8211
8862
  const records = this.fetch(options);
8212
8863
  for await (const record of records) {
8213
- if (record.root_span_id !== record.span_id) {
8864
+ const isRoot = record.is_root ?? record.root_span_id === record.span_id;
8865
+ if (!isRoot) {
8214
8866
  continue;
8215
8867
  }
8216
8868
  const { output, expected: expectedRecord, metadata } = record;
@@ -8272,9 +8924,16 @@ var SpanImpl = class _SpanImpl {
8272
8924
  _spanId;
8273
8925
  _rootSpanId;
8274
8926
  _spanParents;
8927
+ // Inbound W3C trace-context state (tracestate + raw traceparent flags) to
8928
+ // forward on outbound propagation. Captured at the span that received it (via
8929
+ // extractTraceContextFromHeaders) and inherited by all subspans, so that any
8930
+ // inject() within the trace re-emits the upstream state unchanged, per the W3C
8931
+ // Trace Context spec. Not interpreted.
8932
+ _propagatedState;
8275
8933
  kind = "span";
8276
8934
  constructor(args) {
8277
8935
  this._state = args.state;
8936
+ this._propagatedState = args.propagatedState;
8278
8937
  const spanAttributes = args.spanAttributes ?? {};
8279
8938
  const rawEvent = args.event ?? {};
8280
8939
  const type = args.type ?? (args.parentSpanIds ? void 0 : args.defaultRootType);
@@ -8390,7 +9049,7 @@ var SpanImpl = class _SpanImpl {
8390
9049
  tags: partialRecord.tags,
8391
9050
  span_id: this._spanId,
8392
9051
  span_parents: this._spanParents,
8393
- is_root: this._spanId === this._rootSpanId,
9052
+ is_root: !this._spanParents || this._spanParents.length === 0,
8394
9053
  span_attributes: partialRecord.span_attributes
8395
9054
  };
8396
9055
  this._state.spanCache.queueWrite(
@@ -8452,7 +9111,8 @@ var SpanImpl = class _SpanImpl {
8452
9111
  parentObjectId: this.parentObjectId,
8453
9112
  parentComputeObjectMetadataArgs: this.parentComputeObjectMetadataArgs,
8454
9113
  parentSpanIds,
8455
- propagatedEvent: args?.propagatedEvent ?? this.propagatedEvent
9114
+ propagatedEvent: args?.propagatedEvent ?? this.propagatedEvent,
9115
+ propagatedState: this._propagatedState
8456
9116
  })
8457
9117
  });
8458
9118
  }
@@ -8471,7 +9131,8 @@ var SpanImpl = class _SpanImpl {
8471
9131
  parentObjectId: this.parentObjectId,
8472
9132
  parentComputeObjectMetadataArgs: this.parentComputeObjectMetadataArgs,
8473
9133
  parentSpanIds,
8474
- propagatedEvent: args?.propagatedEvent ?? this.propagatedEvent
9134
+ propagatedEvent: args?.propagatedEvent ?? this.propagatedEvent,
9135
+ propagatedState: this._propagatedState
8475
9136
  }),
8476
9137
  spanId
8477
9138
  });
@@ -8499,6 +9160,42 @@ var SpanImpl = class _SpanImpl {
8499
9160
  propagated_event: this.propagatedEvent
8500
9161
  }).toStr();
8501
9162
  }
9163
+ /**
9164
+ * Return this span's Braintrust parent string (`project_id:<id>`,
9165
+ * `project_name:<name>`, or `experiment_id:<id>`) for the `braintrust.parent`
9166
+ * baggage entry, or undefined when it cannot be determined synchronously.
9167
+ */
9168
+ _getOtelParent() {
9169
+ if (this.parentObjectType === 2 /* PROJECT_LOGS */) {
9170
+ const id = this.parentComputeObjectMetadataArgs?.project_id || this.parentObjectId.getSync().value;
9171
+ const name = this.parentComputeObjectMetadataArgs?.project_name;
9172
+ if (id) {
9173
+ return `project_id:${id}`;
9174
+ } else if (name) {
9175
+ return `project_name:${name}`;
9176
+ }
9177
+ } else if (this.parentObjectType === 1 /* EXPERIMENT */) {
9178
+ const id = this.parentComputeObjectMetadataArgs?.experiment_id || this.parentObjectId.getSync().value;
9179
+ if (id) {
9180
+ return `experiment_id:${id}`;
9181
+ }
9182
+ }
9183
+ return void 0;
9184
+ }
9185
+ inject(carrier) {
9186
+ const resolvedCarrier = carrier ?? {};
9187
+ try {
9188
+ _injectIntoCarrier(resolvedCarrier, {
9189
+ traceId: this._rootSpanId,
9190
+ spanId: this._spanId,
9191
+ braintrustParent: this._getOtelParent() ?? this._propagatedState?.braintrustParent,
9192
+ propagatedState: this._propagatedState
9193
+ });
9194
+ } catch (e) {
9195
+ debugLogger.warn(`Error injecting trace context: ${e}`);
9196
+ }
9197
+ return resolvedCarrier;
9198
+ }
8502
9199
  async permalink() {
8503
9200
  return await permalink(await this.export(), {
8504
9201
  state: this._state
@@ -8634,6 +9331,7 @@ var Dataset2 = class extends ObjectFetcher {
8634
9331
  _internal_btql
8635
9332
  );
8636
9333
  this.state = state;
9334
+ void this.__braintrust_dataset_marker;
8637
9335
  this.lazyMetadata = lazyMetadata;
8638
9336
  this.lazyPinnedVersion = pinState?.lazyPinnedVersion;
8639
9337
  this.pinnedEnvironment = pinState?.pinnedEnvironment;
@@ -9148,6 +9846,7 @@ var Prompt2 = class _Prompt {
9148
9846
  this.metadata = metadata;
9149
9847
  this.defaults = defaults;
9150
9848
  this.noTrace = noTrace;
9849
+ void this.__braintrust_prompt_marker;
9151
9850
  }
9152
9851
  parsedPromptData;
9153
9852
  hasParsedPromptData = false;
@@ -9384,6 +10083,7 @@ var Prompt2 = class _Prompt {
9384
10083
  var RemoteEvalParameters = class {
9385
10084
  constructor(metadata) {
9386
10085
  this.metadata = metadata;
10086
+ void this.__braintrust_parameters_marker;
9387
10087
  }
9388
10088
  __braintrust_parameters_marker = true;
9389
10089
  get id() {
@@ -10255,6 +10955,22 @@ function runStreamingCompletionHook(args) {
10255
10955
  );
10256
10956
  }
10257
10957
  }
10958
+ function runStreamingErrorHook(args) {
10959
+ if (!args.config.onError) {
10960
+ return;
10961
+ }
10962
+ try {
10963
+ args.config.onError({
10964
+ channelName: args.channelName,
10965
+ error: args.error,
10966
+ event: args.event,
10967
+ span: args.span,
10968
+ startTime: args.startTime
10969
+ });
10970
+ } catch (error) {
10971
+ debugLogger.error(`Error in onError hook for ${args.channelName}:`, error);
10972
+ }
10973
+ }
10258
10974
  function traceAsyncChannel(channel2, config) {
10259
10975
  const tracingChannel2 = channel2.tracingChannel();
10260
10976
  const states = /* @__PURE__ */ new WeakMap();
@@ -10416,6 +11132,14 @@ function traceStreamingChannel(channel2, config) {
10416
11132
  }
10417
11133
  },
10418
11134
  onError: (error) => {
11135
+ runStreamingErrorHook({
11136
+ channelName,
11137
+ config,
11138
+ error,
11139
+ event: asyncEndEvent,
11140
+ span,
11141
+ startTime
11142
+ });
10419
11143
  span.log({
10420
11144
  error: error.message
10421
11145
  });
@@ -10473,6 +11197,17 @@ function traceStreamingChannel(channel2, config) {
10473
11197
  }
10474
11198
  },
10475
11199
  error: (event) => {
11200
+ const spanData = states.get(event);
11201
+ if (spanData) {
11202
+ runStreamingErrorHook({
11203
+ channelName,
11204
+ config,
11205
+ error: event.error,
11206
+ event,
11207
+ span: spanData.span,
11208
+ startTime: spanData.startTime
11209
+ });
11210
+ }
10476
11211
  logErrorAndEnd(states, event);
10477
11212
  }
10478
11213
  };
@@ -12835,14 +13570,45 @@ function serializeAISDKToolsForLogging(tools) {
12835
13570
  return serialized;
12836
13571
  }
12837
13572
 
13573
+ // src/vendor-sdk-types/ai-sdk-v7-telemetry.ts
13574
+ var BRAINTRUST_AI_SDK_V7_OPERATION_KEY = /* @__PURE__ */ Symbol.for(
13575
+ "braintrust.ai-sdk.v7.telemetry-operation-key"
13576
+ );
13577
+
13578
+ // src/wrappers/ai-sdk/workflow-agent-context.ts
13579
+ var workflowAgentWrapperSpans = /* @__PURE__ */ new Map();
13580
+ function registerWorkflowAgentWrapperSpan(span) {
13581
+ if (span.spanId) {
13582
+ workflowAgentWrapperSpans.set(span.spanId, span);
13583
+ }
13584
+ }
13585
+ function unregisterWorkflowAgentWrapperSpan(span) {
13586
+ if (span.spanId) {
13587
+ workflowAgentWrapperSpans.delete(span.spanId);
13588
+ }
13589
+ }
13590
+ function currentWorkflowAgentWrapperSpan() {
13591
+ const parentSpanIds = _internalGetGlobalState().contextManager.getParentSpanIds()?.spanParents ?? [];
13592
+ for (const parentSpanId of parentSpanIds) {
13593
+ const span = workflowAgentWrapperSpans.get(parentSpanId);
13594
+ if (span) {
13595
+ return span;
13596
+ }
13597
+ }
13598
+ return void 0;
13599
+ }
13600
+
12838
13601
  // src/wrappers/ai-sdk/telemetry.ts
12839
13602
  function braintrustAISDKTelemetry() {
12840
13603
  const operations = /* @__PURE__ */ new Map();
13604
+ const operationKeysByCallId = /* @__PURE__ */ new Map();
13605
+ const workflowOperationKeyStore = isomorph_default.newAsyncLocalStorage();
12841
13606
  const modelSpans = /* @__PURE__ */ new Map();
12842
13607
  const objectSpans = /* @__PURE__ */ new Map();
12843
13608
  const embedSpans = /* @__PURE__ */ new Map();
12844
13609
  const rerankSpans = /* @__PURE__ */ new Map();
12845
13610
  const toolSpans = /* @__PURE__ */ new Map();
13611
+ let workflowAgentOperationCounter = 0;
12846
13612
  const runSafely = (name, callback) => {
12847
13613
  try {
12848
13614
  callback();
@@ -12850,42 +13616,333 @@ function braintrustAISDKTelemetry() {
12850
13616
  console.error(`Error in Braintrust AI SDK telemetry ${name}:`, error);
12851
13617
  }
12852
13618
  };
12853
- const startChildSpan = (callId, name, type, event) => {
12854
- const parent = operations.get(callId)?.span;
13619
+ const startChildSpan = (operationKey, name, type, event) => {
13620
+ const parent = operations.get(operationKey)?.span;
12855
13621
  const spanArgs = {
12856
13622
  name,
12857
13623
  spanAttributes: { type },
12858
13624
  ...event ? { event } : {}
12859
13625
  };
12860
13626
  const span = parent ? parent.startSpan(spanArgs) : startSpan(spanArgs);
12861
- const state = operations.get(callId);
13627
+ const state = operations.get(operationKey);
12862
13628
  if (state && type === "llm" /* LLM */) {
12863
13629
  state.hadModelChild = true;
12864
13630
  }
12865
13631
  return span;
12866
13632
  };
13633
+ const registerOperation = (state) => {
13634
+ operations.set(state.operationKey, state);
13635
+ const keys = operationKeysByCallId.get(state.callId) ?? [];
13636
+ keys.push(state.operationKey);
13637
+ operationKeysByCallId.set(state.callId, keys);
13638
+ };
13639
+ const deleteOperation = (operationKey) => {
13640
+ const state = operations.get(operationKey);
13641
+ if (!state) {
13642
+ return;
13643
+ }
13644
+ operations.delete(operationKey);
13645
+ if (workflowOperationKeyStore.getStore() === operationKey) {
13646
+ workflowOperationKeyStore.enterWith(void 0);
13647
+ }
13648
+ const keys = operationKeysByCallId.get(state.callId);
13649
+ if (!keys) {
13650
+ return;
13651
+ }
13652
+ const index = keys.indexOf(operationKey);
13653
+ if (index >= 0) {
13654
+ keys.splice(index, 1);
13655
+ }
13656
+ if (keys.length === 0) {
13657
+ operationKeysByCallId.delete(state.callId);
13658
+ }
13659
+ };
13660
+ const explicitOperationKey = (event) => {
13661
+ if (!isObject(event)) {
13662
+ return void 0;
13663
+ }
13664
+ const key = event[BRAINTRUST_AI_SDK_V7_OPERATION_KEY];
13665
+ return typeof key === "string" ? key : void 0;
13666
+ };
13667
+ const createOperationKey = (event, operationName) => {
13668
+ const explicit = explicitOperationKey(event);
13669
+ if (explicit) {
13670
+ return explicit;
13671
+ }
13672
+ if (operationName === "WorkflowAgent.stream") {
13673
+ workflowAgentOperationCounter += 1;
13674
+ return `${event.callId}:${workflowAgentOperationCounter}`;
13675
+ }
13676
+ return event.callId;
13677
+ };
13678
+ const operationKeyForCallId = (callId, mode = "active") => {
13679
+ const keys = operationKeysByCallId.get(callId);
13680
+ if (!keys || keys.length === 0) {
13681
+ return operations.has(callId) ? callId : void 0;
13682
+ }
13683
+ if (keys.length === 1) {
13684
+ return keys[0];
13685
+ }
13686
+ const wrapperSpan = currentWorkflowAgentWrapperSpan();
13687
+ if (wrapperSpan?.spanId) {
13688
+ const key = keys.find(
13689
+ (candidate) => operations.get(candidate)?.span.spanId === wrapperSpan.spanId
13690
+ );
13691
+ if (key) {
13692
+ return key;
13693
+ }
13694
+ }
13695
+ const workflowOperationKey = workflowOperationKeyStore.getStore();
13696
+ if (workflowOperationKey && keys.includes(workflowOperationKey)) {
13697
+ return workflowOperationKey;
13698
+ }
13699
+ if (callId === "workflow-agent") {
13700
+ return void 0;
13701
+ }
13702
+ return mode === "finish" ? keys[0] : keys[keys.length - 1];
13703
+ };
13704
+ const operationKeyFromEvent = (event, mode = "active") => {
13705
+ const explicit = explicitOperationKey(event);
13706
+ if (explicit && operations.has(explicit)) {
13707
+ return explicit;
13708
+ }
13709
+ if (isObject(event)) {
13710
+ const callId = event.callId;
13711
+ if (typeof callId === "string") {
13712
+ const operationKey = operationKeyForCallId(callId, mode);
13713
+ if (operationKey) {
13714
+ return operationKey;
13715
+ }
13716
+ const workflowOperationKey2 = workflowOperationKeyStore.getStore();
13717
+ if (workflowOperationKey2 && operations.has(workflowOperationKey2)) {
13718
+ return workflowOperationKey2;
13719
+ }
13720
+ return callId === "workflow-agent" ? void 0 : callId;
13721
+ }
13722
+ }
13723
+ const workflowOperationKey = workflowOperationKeyStore.getStore();
13724
+ if (workflowOperationKey && operations.has(workflowOperationKey)) {
13725
+ return workflowOperationKey;
13726
+ }
13727
+ const wrapperSpan = currentWorkflowAgentWrapperSpan();
13728
+ if (wrapperSpan?.spanId) {
13729
+ for (const [operationKey, state] of operations) {
13730
+ if (state.operationName === "WorkflowAgent.stream" && state.span.spanId === wrapperSpan.spanId) {
13731
+ return operationKey;
13732
+ }
13733
+ }
13734
+ }
13735
+ const workflowAgentKeys = operationKeysByCallId.get("workflow-agent");
13736
+ if (workflowAgentKeys?.length === 1) {
13737
+ return workflowAgentKeys[0];
13738
+ }
13739
+ if (operations.size === 1) {
13740
+ return operations.keys().next().value;
13741
+ }
13742
+ return void 0;
13743
+ };
13744
+ const closeOpenChildSpans = (operationKey, error) => {
13745
+ const openModelSpans = modelSpans.get(operationKey);
13746
+ if (openModelSpans) {
13747
+ for (const span of openModelSpans) {
13748
+ if (error !== void 0) {
13749
+ logError(span, error);
13750
+ }
13751
+ span.end();
13752
+ }
13753
+ modelSpans.delete(operationKey);
13754
+ }
13755
+ const openObjectSpan = objectSpans.get(operationKey);
13756
+ if (openObjectSpan) {
13757
+ if (error !== void 0) {
13758
+ logError(openObjectSpan, error);
13759
+ }
13760
+ openObjectSpan.end();
13761
+ objectSpans.delete(operationKey);
13762
+ }
13763
+ for (const [embedCallId, embedState] of embedSpans) {
13764
+ if (embedState.operationKey === operationKey) {
13765
+ if (error !== void 0) {
13766
+ logError(embedState.span, error);
13767
+ }
13768
+ embedState.span.end();
13769
+ embedSpans.delete(embedCallId);
13770
+ }
13771
+ }
13772
+ const openRerankSpan = rerankSpans.get(operationKey);
13773
+ if (openRerankSpan) {
13774
+ if (error !== void 0) {
13775
+ logError(openRerankSpan, error);
13776
+ }
13777
+ openRerankSpan.end();
13778
+ rerankSpans.delete(operationKey);
13779
+ }
13780
+ for (const [toolCallId, toolState] of toolSpans) {
13781
+ if (toolState.operationKey === operationKey) {
13782
+ if (error !== void 0) {
13783
+ logError(toolState.span, error);
13784
+ }
13785
+ toolState.span.end();
13786
+ toolSpans.delete(toolCallId);
13787
+ }
13788
+ }
13789
+ };
13790
+ const abortReasonFromEvent = (event) => {
13791
+ if (isObject(event)) {
13792
+ const abortEvent = event;
13793
+ if (abortEvent.error !== void 0) {
13794
+ return abortEvent.error;
13795
+ }
13796
+ if (abortEvent.reason !== void 0) {
13797
+ return abortEvent.reason;
13798
+ }
13799
+ }
13800
+ return new Error("AI SDK operation aborted");
13801
+ };
13802
+ const shouldSkipTelemetryChildren = (state) => state?.operationName === "WorkflowAgent.stream" && !state.ownsSpan;
13803
+ const onObjectStepEnd = (event) => {
13804
+ runSafely("onObjectStepEnd", () => {
13805
+ const operationKey = operationKeyFromEvent(event);
13806
+ const span = operationKey ? objectSpans.get(operationKey) : void 0;
13807
+ if (!operationKey || !span) {
13808
+ return;
13809
+ }
13810
+ const result = {
13811
+ ...event,
13812
+ text: event.objectText
13813
+ };
13814
+ span.log({
13815
+ ...shouldRecordOutputs(event) ? {
13816
+ output: processAISDKOutput(result, DEFAULT_DENY_OUTPUT_PATHS)
13817
+ } : {},
13818
+ metrics: extractTokenMetrics(result)
13819
+ });
13820
+ span.end();
13821
+ objectSpans.delete(operationKey);
13822
+ });
13823
+ };
13824
+ const onEmbedEnd = (event) => {
13825
+ runSafely("onEmbedEnd", () => {
13826
+ const state = embedSpans.get(event.embedCallId);
13827
+ if (!state) {
13828
+ return;
13829
+ }
13830
+ const result = {
13831
+ ...event,
13832
+ embeddings: event.embeddings
13833
+ };
13834
+ state.span.log({
13835
+ ...shouldRecordOutputs(event) ? {
13836
+ output: processAISDKEmbeddingOutput(
13837
+ result,
13838
+ DEFAULT_DENY_OUTPUT_PATHS
13839
+ )
13840
+ } : {},
13841
+ metrics: extractTokenMetrics(result)
13842
+ });
13843
+ state.span.end();
13844
+ embedSpans.delete(event.embedCallId);
13845
+ });
13846
+ };
13847
+ const onRerankEnd = (event) => {
13848
+ runSafely("onRerankEnd", () => {
13849
+ const operationKey = operationKeyFromEvent(event);
13850
+ const span = operationKey ? rerankSpans.get(operationKey) : void 0;
13851
+ if (!operationKey || !span) {
13852
+ return;
13853
+ }
13854
+ const result = {
13855
+ ranking: event.ranking?.map((entry) => ({
13856
+ originalIndex: entry.index,
13857
+ score: entry.relevanceScore
13858
+ }))
13859
+ };
13860
+ span.log({
13861
+ ...shouldRecordOutputs(event) ? {
13862
+ output: processAISDKRerankOutput(
13863
+ result,
13864
+ DEFAULT_DENY_OUTPUT_PATHS
13865
+ )
13866
+ } : {}
13867
+ });
13868
+ span.end();
13869
+ rerankSpans.delete(operationKey);
13870
+ });
13871
+ };
13872
+ const onEnd = (event) => {
13873
+ runSafely("onEnd", () => {
13874
+ const operationKey = operationKeyFromEvent(event, "finish");
13875
+ const state = operationKey ? operations.get(operationKey) : void 0;
13876
+ if (!state) {
13877
+ return;
13878
+ }
13879
+ if (!state.ownsSpan) {
13880
+ deleteOperation(state.operationKey);
13881
+ return;
13882
+ }
13883
+ const result = finishResult(event, state.operationName);
13884
+ const metrics = state.hadModelChild ? {} : extractTokenMetrics(result);
13885
+ const timeToFirstToken = state.operationName === "WorkflowAgent.stream" ? void 0 : extractTimeToFirstToken(result, state);
13886
+ if (timeToFirstToken !== void 0) {
13887
+ metrics.time_to_first_token = timeToFirstToken;
13888
+ }
13889
+ state.span.log({
13890
+ ...shouldRecordOutputs(event) ? {
13891
+ output: finishOutput(result, state.operationName)
13892
+ } : {},
13893
+ metrics
13894
+ });
13895
+ state.span.end();
13896
+ deleteOperation(state.operationKey);
13897
+ });
13898
+ };
12867
13899
  return {
12868
13900
  onStart(event) {
12869
13901
  runSafely("onStart", () => {
12870
13902
  const operationName = operationNameFromId(event.operationId);
12871
- const span = startSpan({
13903
+ const workflowAgent = operationName === "WorkflowAgent.stream";
13904
+ const wrapperSpan = workflowAgent ? currentWorkflowAgentWrapperSpan() : void 0;
13905
+ const ownsSpan = !wrapperSpan;
13906
+ const span = ownsSpan ? startSpan({
12872
13907
  name: operationName,
12873
13908
  spanAttributes: { type: "function" /* FUNCTION */ }
12874
- });
12875
- operations.set(event.callId, {
13909
+ }) : wrapperSpan;
13910
+ const operationKey = createOperationKey(event, operationName);
13911
+ registerOperation({
13912
+ callId: event.callId,
12876
13913
  hadModelChild: false,
13914
+ loggedInput: false,
12877
13915
  operationName,
13916
+ operationKey,
13917
+ ownsSpan,
12878
13918
  span,
12879
13919
  startTime: getCurrentUnixTimestamp()
12880
13920
  });
12881
- const metadata = metadataFromEvent(event);
13921
+ if (!ownsSpan) {
13922
+ return;
13923
+ }
13924
+ if (workflowAgent) {
13925
+ workflowOperationKeyStore.enterWith(operationKey);
13926
+ }
13927
+ let metadata = metadataFromEvent(event);
12882
13928
  const logPayload = { metadata };
13929
+ const workflowAgentCallInput = workflowAgent ? operationInput(event, operationName) : void 0;
13930
+ if (workflowAgentCallInput) {
13931
+ metadata = {
13932
+ ...metadata,
13933
+ ...extractWorkflowMetadataFromCallParams(workflowAgentCallInput)
13934
+ };
13935
+ logPayload.metadata = metadata;
13936
+ }
12883
13937
  if (shouldRecordInputs(event)) {
12884
- const { input, outputPromise } = processAISDKCallInput(
12885
- operationInput(event, operationName)
12886
- );
13938
+ const callInput = workflowAgentCallInput ?? operationInput(event, operationName);
13939
+ const { input, outputPromise } = workflowAgent ? processAISDKWorkflowAgentCallInput(callInput) : processAISDKCallInput(callInput);
12887
13940
  logPayload.input = input;
12888
- if (outputPromise && input && typeof input === "object") {
13941
+ const state = operations.get(operationKey);
13942
+ if (state) {
13943
+ state.loggedInput = hasPromptLikeInput(input);
13944
+ }
13945
+ if (outputPromise && !workflowAgent && input && typeof input === "object") {
12889
13946
  outputPromise.then((resolvedData) => {
12890
13947
  span.log({
12891
13948
  input: {
@@ -12902,41 +13959,67 @@ function braintrustAISDKTelemetry() {
12902
13959
  },
12903
13960
  onLanguageModelCallStart(event) {
12904
13961
  runSafely("onLanguageModelCallStart", () => {
12905
- const state = operations.get(event.callId);
12906
- const openSpans = modelSpans.get(event.callId);
12907
- if (openSpans) {
13962
+ const operationKey = operationKeyFromEvent(event);
13963
+ const state = operationKey ? operations.get(operationKey) : void 0;
13964
+ if (shouldSkipTelemetryChildren(state)) {
13965
+ return;
13966
+ }
13967
+ const operationName = state?.operationName ?? "generateText";
13968
+ const callInput = operationInput(event, operationName);
13969
+ const workflowAgent = operationName === "WorkflowAgent.stream";
13970
+ const processedInput = shouldRecordInputs(event) && workflowAgent ? processAISDKWorkflowAgentModelCallInput(callInput).input : shouldRecordInputs(event) ? processAISDKCallInput(callInput).input : void 0;
13971
+ if (workflowAgent && state?.ownsSpan && !state.loggedInput && hasPromptLikeInput(processedInput)) {
13972
+ state.span.log({
13973
+ input: processedInput,
13974
+ metadata: {
13975
+ ...metadataFromEvent(event),
13976
+ ...extractWorkflowMetadataFromCallParams(callInput)
13977
+ }
13978
+ });
13979
+ state.loggedInput = true;
13980
+ }
13981
+ const openSpans = operationKey ? modelSpans.get(operationKey) : void 0;
13982
+ if (operationKey && openSpans) {
12908
13983
  for (const span2 of openSpans) {
12909
13984
  span2.end();
12910
13985
  }
12911
- modelSpans.delete(event.callId);
13986
+ modelSpans.delete(operationKey);
12912
13987
  }
12913
13988
  const span = startChildSpan(
12914
- event.callId,
12915
- state?.operationName === "streamText" ? "doStream" : "doGenerate",
13989
+ operationKey ?? event.callId,
13990
+ operationName === "streamText" ? "doStream" : "doGenerate",
12916
13991
  "llm" /* LLM */,
12917
13992
  {
12918
13993
  ...shouldRecordInputs(event) ? {
12919
- input: processAISDKCallInput(
12920
- operationInput(
12921
- event,
12922
- state?.operationName ?? "generateText"
12923
- )
12924
- ).input
13994
+ input: processedInput
12925
13995
  } : {},
12926
- metadata: metadataFromEvent(event)
13996
+ metadata: workflowAgent ? {
13997
+ ...metadataFromEvent(event),
13998
+ ...extractWorkflowMetadataFromCallParams(callInput)
13999
+ } : metadataFromEvent(event)
12927
14000
  }
12928
14001
  );
12929
- const spans = modelSpans.get(event.callId) ?? [];
14002
+ const spanKey = operationKey ?? event.callId;
14003
+ const spans = modelSpans.get(spanKey) ?? [];
12930
14004
  spans.push(span);
12931
- modelSpans.set(event.callId, spans);
14005
+ modelSpans.set(spanKey, spans);
12932
14006
  });
12933
14007
  },
12934
14008
  onLanguageModelCallEnd(event) {
12935
14009
  runSafely("onLanguageModelCallEnd", () => {
12936
- const span = shiftModelSpan(modelSpans, event.callId);
14010
+ const operationKey = operationKeyFromEvent(event);
14011
+ const state = operationKey ? operations.get(operationKey) : void 0;
14012
+ if (shouldSkipTelemetryChildren(state)) {
14013
+ return;
14014
+ }
14015
+ const span = operationKey ? shiftModelSpan(modelSpans, operationKey) : void 0;
12937
14016
  if (!span) {
12938
14017
  return;
12939
14018
  }
14019
+ const timeToFirstOutputMs = safePerformance(event)?.timeToFirstOutputMs;
14020
+ if (state?.operationName === "streamText" && state.firstChunkTime === void 0 && typeof timeToFirstOutputMs === "number") {
14021
+ state.firstChunkTime = state.startTime + timeToFirstOutputMs / 1e3;
14022
+ }
12940
14023
  const result = {
12941
14024
  ...event,
12942
14025
  response: event.responseId ? { id: event.responseId } : void 0
@@ -12952,14 +14035,18 @@ function braintrustAISDKTelemetry() {
12952
14035
  },
12953
14036
  onObjectStepStart(event) {
12954
14037
  runSafely("onObjectStepStart", () => {
12955
- const state = operations.get(event.callId);
12956
- const openSpan = objectSpans.get(event.callId);
12957
- if (openSpan) {
14038
+ const operationKey = operationKeyFromEvent(event);
14039
+ const state = operationKey ? operations.get(operationKey) : void 0;
14040
+ if (shouldSkipTelemetryChildren(state)) {
14041
+ return;
14042
+ }
14043
+ const openSpan = operationKey ? objectSpans.get(operationKey) : void 0;
14044
+ if (operationKey && openSpan) {
12958
14045
  openSpan.end();
12959
- objectSpans.delete(event.callId);
14046
+ objectSpans.delete(operationKey);
12960
14047
  }
12961
14048
  const span = startChildSpan(
12962
- event.callId,
14049
+ operationKey ?? event.callId,
12963
14050
  state?.operationName === "streamObject" ? "doStream" : "doGenerate",
12964
14051
  "llm" /* LLM */,
12965
14052
  {
@@ -12971,40 +14058,25 @@ function braintrustAISDKTelemetry() {
12971
14058
  metadata: metadataFromEvent(event)
12972
14059
  }
12973
14060
  );
12974
- objectSpans.set(event.callId, span);
14061
+ objectSpans.set(operationKey ?? event.callId, span);
12975
14062
  });
12976
14063
  },
12977
- onObjectStepFinish(event) {
12978
- runSafely("onObjectStepFinish", () => {
12979
- const span = objectSpans.get(event.callId);
12980
- if (!span) {
14064
+ onObjectStepEnd,
14065
+ onEmbedStart(event) {
14066
+ runSafely("onEmbedStart", () => {
14067
+ const operationKey = operationKeyFromEvent(event);
14068
+ const state = operationKey ? operations.get(operationKey) : void 0;
14069
+ if (shouldSkipTelemetryChildren(state)) {
12981
14070
  return;
12982
14071
  }
12983
- const result = {
12984
- ...event,
12985
- text: event.objectText
12986
- };
12987
- span.log({
12988
- ...shouldRecordOutputs(event) ? {
12989
- output: processAISDKOutput(result, DEFAULT_DENY_OUTPUT_PATHS)
12990
- } : {},
12991
- metrics: extractTokenMetrics(result)
12992
- });
12993
- span.end();
12994
- objectSpans.delete(event.callId);
12995
- });
12996
- },
12997
- onEmbedStart(event) {
12998
- runSafely("onEmbedStart", () => {
12999
- const state = operations.get(event.callId);
13000
14072
  for (const [embedCallId, embedState] of embedSpans) {
13001
- if (embedState.callId === event.callId && (state?.operationName === "embed" || embedState.values === event.values)) {
14073
+ if (embedState.operationKey === operationKey && (state?.operationName === "embed" || embedState.values === event.values)) {
13002
14074
  embedState.span.end();
13003
14075
  embedSpans.delete(embedCallId);
13004
14076
  }
13005
14077
  }
13006
14078
  const span = startChildSpan(
13007
- event.callId,
14079
+ operationKey ?? event.callId,
13008
14080
  "doEmbed",
13009
14081
  "llm" /* LLM */,
13010
14082
  {
@@ -13017,44 +14089,27 @@ function braintrustAISDKTelemetry() {
13017
14089
  }
13018
14090
  );
13019
14091
  embedSpans.set(event.embedCallId, {
13020
- callId: event.callId,
14092
+ operationKey: operationKey ?? event.callId,
13021
14093
  span,
13022
14094
  values: event.values
13023
14095
  });
13024
14096
  });
13025
14097
  },
13026
- onEmbedFinish(event) {
13027
- runSafely("onEmbedFinish", () => {
13028
- const state = embedSpans.get(event.embedCallId);
13029
- if (!state) {
13030
- return;
13031
- }
13032
- const result = {
13033
- ...event,
13034
- embeddings: event.embeddings
13035
- };
13036
- state.span.log({
13037
- ...shouldRecordOutputs(event) ? {
13038
- output: processAISDKEmbeddingOutput(
13039
- result,
13040
- DEFAULT_DENY_OUTPUT_PATHS
13041
- )
13042
- } : {},
13043
- metrics: extractTokenMetrics(result)
13044
- });
13045
- state.span.end();
13046
- embedSpans.delete(event.embedCallId);
13047
- });
13048
- },
14098
+ onEmbedEnd,
13049
14099
  onRerankStart(event) {
13050
14100
  runSafely("onRerankStart", () => {
13051
- const openSpan = rerankSpans.get(event.callId);
13052
- if (openSpan) {
14101
+ const operationKey = operationKeyFromEvent(event);
14102
+ const state = operationKey ? operations.get(operationKey) : void 0;
14103
+ if (shouldSkipTelemetryChildren(state)) {
14104
+ return;
14105
+ }
14106
+ const openSpan = operationKey ? rerankSpans.get(operationKey) : void 0;
14107
+ if (operationKey && openSpan) {
13053
14108
  openSpan.end();
13054
- rerankSpans.delete(event.callId);
14109
+ rerankSpans.delete(operationKey);
13055
14110
  }
13056
14111
  const span = startChildSpan(
13057
- event.callId,
14112
+ operationKey ?? event.callId,
13058
14113
  "doRerank",
13059
14114
  "llm" /* LLM */,
13060
14115
  {
@@ -13068,41 +14123,23 @@ function braintrustAISDKTelemetry() {
13068
14123
  metadata: metadataFromEvent(event)
13069
14124
  }
13070
14125
  );
13071
- rerankSpans.set(event.callId, span);
13072
- });
13073
- },
13074
- onRerankFinish(event) {
13075
- runSafely("onRerankFinish", () => {
13076
- const span = rerankSpans.get(event.callId);
13077
- if (!span) {
13078
- return;
13079
- }
13080
- const result = {
13081
- ranking: event.ranking?.map((entry) => ({
13082
- originalIndex: entry.index,
13083
- score: entry.relevanceScore
13084
- }))
13085
- };
13086
- span.log({
13087
- ...shouldRecordOutputs(event) ? {
13088
- output: processAISDKRerankOutput(
13089
- result,
13090
- DEFAULT_DENY_OUTPUT_PATHS
13091
- )
13092
- } : {}
13093
- });
13094
- span.end();
13095
- rerankSpans.delete(event.callId);
14126
+ rerankSpans.set(operationKey ?? event.callId, span);
13096
14127
  });
13097
14128
  },
14129
+ onRerankEnd,
13098
14130
  onToolExecutionStart(event) {
13099
14131
  runSafely("onToolExecutionStart", () => {
14132
+ const operationKey = operationKeyFromEvent(event);
14133
+ const state = operationKey ? operations.get(operationKey) : void 0;
14134
+ if (shouldSkipTelemetryChildren(state)) {
14135
+ return;
14136
+ }
13100
14137
  const toolCallId = event.toolCall.toolCallId;
13101
- if (!toolCallId) {
14138
+ if (!operationKey || !toolCallId) {
13102
14139
  return;
13103
14140
  }
13104
14141
  const span = startChildSpan(
13105
- event.callId,
14142
+ operationKey,
13106
14143
  event.toolCall.toolName || "tool",
13107
14144
  "tool" /* TOOL */,
13108
14145
  {
@@ -13116,7 +14153,7 @@ function braintrustAISDKTelemetry() {
13116
14153
  }
13117
14154
  }
13118
14155
  );
13119
- toolSpans.set(toolCallId, { callId: event.callId, span });
14156
+ toolSpans.set(toolCallId, { operationKey, span });
13120
14157
  });
13121
14158
  },
13122
14159
  onToolExecutionEnd(event) {
@@ -13127,14 +14164,17 @@ function braintrustAISDKTelemetry() {
13127
14164
  return;
13128
14165
  }
13129
14166
  const toolOutput = event.toolOutput;
13130
- if (toolOutput?.type === "tool-error") {
14167
+ const workflowToolError = event.success === false && "error" in event ? event.error : void 0;
14168
+ if (toolOutput?.type === "tool-error" || workflowToolError !== void 0) {
14169
+ const error = toolOutput?.error ?? workflowToolError;
13131
14170
  state.span.log({
13132
- error: toolOutput.error instanceof Error ? toolOutput.error.message : String(toolOutput?.error),
14171
+ error: error instanceof Error ? error.message : String(error),
13133
14172
  metrics: typeof event.durationMs === "number" ? { duration_ms: event.durationMs } : {}
13134
14173
  });
13135
14174
  } else {
14175
+ const output = toolOutput && "output" in toolOutput ? toolOutput.output : event.output;
13136
14176
  state.span.log({
13137
- ...shouldRecordOutputs(event) ? { output: toolOutput?.output } : {},
14177
+ ...shouldRecordOutputs(event) ? { output } : {},
13138
14178
  metrics: typeof event.durationMs === "number" ? { duration_ms: event.durationMs } : {}
13139
14179
  });
13140
14180
  }
@@ -13148,83 +14188,46 @@ function braintrustAISDKTelemetry() {
13148
14188
  if (!callId) {
13149
14189
  return;
13150
14190
  }
13151
- const state = operations.get(callId);
14191
+ const operationKey = operationKeyForCallId(callId);
14192
+ const state = operationKey ? operations.get(operationKey) : void 0;
13152
14193
  if (!state || state.firstChunkTime !== void 0) {
13153
14194
  return;
13154
14195
  }
13155
14196
  state.firstChunkTime = getCurrentUnixTimestamp();
13156
14197
  });
13157
14198
  },
13158
- onFinish(event) {
13159
- runSafely("onFinish", () => {
13160
- const state = operations.get(event.callId);
13161
- if (!state) {
14199
+ onEnd,
14200
+ onAbort(event) {
14201
+ runSafely("onAbort", () => {
14202
+ const operationKey = operationKeyFromEvent(event, "finish");
14203
+ const state = operationKey ? operations.get(operationKey) : void 0;
14204
+ if (!operationKey || !state) {
13162
14205
  return;
13163
14206
  }
13164
- const result = finishResult(event, state.operationName);
13165
- const metrics = state.hadModelChild ? {} : extractTokenMetrics(result);
13166
- if (state.firstChunkTime !== void 0) {
13167
- metrics.time_to_first_token = state.firstChunkTime - state.startTime;
14207
+ const error = abortReasonFromEvent(event);
14208
+ closeOpenChildSpans(operationKey, error);
14209
+ if (state.ownsSpan) {
14210
+ logError(state.span, error);
14211
+ state.span.end();
13168
14212
  }
13169
- state.span.log({
13170
- ...shouldRecordOutputs(event) ? {
13171
- output: finishOutput(result, state.operationName)
13172
- } : {},
13173
- metrics
13174
- });
13175
- state.span.end();
13176
- operations.delete(event.callId);
14213
+ deleteOperation(operationKey);
13177
14214
  });
13178
14215
  },
13179
14216
  onError(event) {
13180
14217
  runSafely("onError", () => {
13181
14218
  const errorEvent = isObject(event) ? event : {};
13182
- const callId = typeof errorEvent.callId === "string" ? errorEvent.callId : void 0;
13183
- if (!callId) {
13184
- return;
13185
- }
13186
- const state = operations.get(callId);
13187
- if (!state) {
14219
+ const operationKey = operationKeyFromEvent(errorEvent, "finish");
14220
+ const state = operationKey ? operations.get(operationKey) : void 0;
14221
+ if (!operationKey || !state) {
13188
14222
  return;
13189
14223
  }
13190
14224
  const error = errorEvent.error ?? event;
13191
- const openModelSpans = modelSpans.get(callId);
13192
- if (openModelSpans) {
13193
- for (const span of openModelSpans) {
13194
- logError(span, error);
13195
- span.end();
13196
- }
13197
- modelSpans.delete(callId);
13198
- }
13199
- const openObjectSpan = objectSpans.get(callId);
13200
- if (openObjectSpan) {
13201
- logError(openObjectSpan, error);
13202
- openObjectSpan.end();
13203
- objectSpans.delete(callId);
13204
- }
13205
- for (const [embedCallId, embedState] of embedSpans) {
13206
- if (embedState.callId === callId) {
13207
- logError(embedState.span, error);
13208
- embedState.span.end();
13209
- embedSpans.delete(embedCallId);
13210
- }
13211
- }
13212
- const openRerankSpan = rerankSpans.get(callId);
13213
- if (openRerankSpan) {
13214
- logError(openRerankSpan, error);
13215
- openRerankSpan.end();
13216
- rerankSpans.delete(callId);
13217
- }
13218
- for (const [toolCallId, toolState] of toolSpans) {
13219
- if (toolState.callId === callId) {
13220
- logError(toolState.span, error);
13221
- toolState.span.end();
13222
- toolSpans.delete(toolCallId);
13223
- }
14225
+ closeOpenChildSpans(operationKey, error);
14226
+ if (state.ownsSpan) {
14227
+ logError(state.span, error);
14228
+ state.span.end();
13224
14229
  }
13225
- logError(state.span, error);
13226
- state.span.end();
13227
- operations.delete(callId);
14230
+ deleteOperation(operationKey);
13228
14231
  });
13229
14232
  },
13230
14233
  executeTool({ toolCallId, execute }) {
@@ -13239,7 +14242,16 @@ function shouldRecordInputs(event) {
13239
14242
  function shouldRecordOutputs(event) {
13240
14243
  return event.recordOutputs !== false;
13241
14244
  }
14245
+ function hasPromptLikeInput(input) {
14246
+ if (!isObject(input)) {
14247
+ return false;
14248
+ }
14249
+ return input.prompt !== void 0 || input.messages !== void 0;
14250
+ }
13242
14251
  function operationNameFromId(operationId) {
14252
+ if (operationId === "ai.workflowAgent.stream") {
14253
+ return "WorkflowAgent.stream";
14254
+ }
13243
14255
  return operationId?.startsWith("ai.") ? operationId.slice("ai.".length) : operationId || "ai-sdk";
13244
14256
  }
13245
14257
  function modelFromEvent(event) {
@@ -13285,6 +14297,7 @@ function operationInput(event, operationName) {
13285
14297
  }
13286
14298
  return {
13287
14299
  model: modelFromEvent(event),
14300
+ instructions: event.instructions,
13288
14301
  system: event.system,
13289
14302
  prompt: event.prompt,
13290
14303
  messages: event.messages,
@@ -13333,6 +14346,30 @@ function finishResult(event, operationName) {
13333
14346
  }
13334
14347
  return event;
13335
14348
  }
14349
+ function extractTimeToFirstToken(result, state) {
14350
+ if (state.firstChunkTime !== void 0) {
14351
+ return state.firstChunkTime - state.startTime;
14352
+ }
14353
+ const performanceCandidates = [
14354
+ safePerformance(result),
14355
+ safePerformance(result.finalStep),
14356
+ ...Array.isArray(result.steps) ? (result.steps ?? []).map(safePerformance) : []
14357
+ ];
14358
+ for (const performance of performanceCandidates) {
14359
+ const timeToFirstOutputMs = performance?.timeToFirstOutputMs;
14360
+ if (typeof timeToFirstOutputMs === "number") {
14361
+ return timeToFirstOutputMs / 1e3;
14362
+ }
14363
+ }
14364
+ return void 0;
14365
+ }
14366
+ function safePerformance(value) {
14367
+ if (!isObject(value)) {
14368
+ return void 0;
14369
+ }
14370
+ const performance = value.performance;
14371
+ return isObject(performance) ? performance : void 0;
14372
+ }
13336
14373
  function finishOutput(result, operationName) {
13337
14374
  if (operationName === "embed" || operationName === "embedMany") {
13338
14375
  return processAISDKEmbeddingOutput(
@@ -13409,6 +14446,10 @@ var aiSDKChannels = defineChannels("ai", {
13409
14446
  channelName: "ToolLoopAgent.stream",
13410
14447
  kind: "async"
13411
14448
  }),
14449
+ workflowAgentStream: channel({
14450
+ channelName: "WorkflowAgent.stream",
14451
+ kind: "async"
14452
+ }),
13412
14453
  v7CreateTelemetryDispatcher: channel({
13413
14454
  channelName: "createTelemetryDispatcher",
13414
14455
  kind: "sync-stream"
@@ -13419,14 +14460,19 @@ var aiSDKChannels = defineChannels("ai", {
13419
14460
  var DEFAULT_DENY_OUTPUT_PATHS = [
13420
14461
  // v3
13421
14462
  "roundtrips[].request.body",
14463
+ "roundtrips[].request.headers",
13422
14464
  "roundtrips[].response.headers",
13423
14465
  "rawResponse.headers",
13424
14466
  "responseMessages",
13425
14467
  // v5
13426
14468
  "request.body",
14469
+ "request.headers",
14470
+ "responses[].headers",
13427
14471
  "response.body",
13428
14472
  "response.headers",
13429
14473
  "steps[].request.body",
14474
+ "steps[].request.headers",
14475
+ "steps[].responses[].headers",
13430
14476
  "steps[].response.body",
13431
14477
  "steps[].response.headers"
13432
14478
  ];
@@ -13438,6 +14484,18 @@ var AUTO_PATCHED_V7_TELEMETRY_DISPATCHER = /* @__PURE__ */ Symbol.for(
13438
14484
  var RUNTIME_DENY_OUTPUT_PATHS = /* @__PURE__ */ Symbol.for(
13439
14485
  "braintrust.ai-sdk.deny-output-paths"
13440
14486
  );
14487
+ var aiSDKV7TelemetryOperationCounter = 0;
14488
+ var TRANSPORT_PAYLOAD_ROOT_PATHS = [
14489
+ "rawResponse",
14490
+ "request",
14491
+ "response",
14492
+ "responses[]",
14493
+ "roundtrips[].request",
14494
+ "roundtrips[].response",
14495
+ "steps[].request",
14496
+ "steps[].response",
14497
+ "steps[].responses[]"
14498
+ ];
13441
14499
  var AI_SDK_V7_TELEMETRY_CALLBACKS = [
13442
14500
  "onStart",
13443
14501
  "onStepStart",
@@ -13446,14 +14504,16 @@ var AI_SDK_V7_TELEMETRY_CALLBACKS = [
13446
14504
  "onToolExecutionStart",
13447
14505
  "onToolExecutionEnd",
13448
14506
  "onChunk",
14507
+ "onStepEnd",
13449
14508
  "onStepFinish",
13450
14509
  "onObjectStepStart",
13451
- "onObjectStepFinish",
14510
+ "onObjectStepEnd",
13452
14511
  "onEmbedStart",
13453
- "onEmbedFinish",
14512
+ "onEmbedEnd",
13454
14513
  "onRerankStart",
13455
- "onRerankFinish",
13456
- "onFinish",
14514
+ "onRerankEnd",
14515
+ "onEnd",
14516
+ "onAbort",
13457
14517
  "onError"
13458
14518
  ];
13459
14519
  var AISDKPlugin = class extends BasePlugin {
@@ -13611,7 +14671,9 @@ var AISDKPlugin = class extends BasePlugin {
13611
14671
  traceStreamingChannel(aiSDKChannels.agentGenerate, {
13612
14672
  name: "Agent.generate",
13613
14673
  type: "function" /* FUNCTION */,
13614
- extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
14674
+ extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
14675
+ agentOwner: true
14676
+ }),
13615
14677
  extractOutput: (result, endEvent) => {
13616
14678
  finalizeAISDKChildTracing(endEvent);
13617
14679
  return processAISDKOutput(
@@ -13627,7 +14689,9 @@ var AISDKPlugin = class extends BasePlugin {
13627
14689
  traceStreamingChannel(aiSDKChannels.agentStream, {
13628
14690
  name: "Agent.stream",
13629
14691
  type: "function" /* FUNCTION */,
13630
- extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
14692
+ extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
14693
+ agentOwner: true
14694
+ }),
13631
14695
  extractOutput: (result, endEvent) => processAISDKOutput(
13632
14696
  result,
13633
14697
  resolveDenyOutputPaths(endEvent, denyOutputPaths)
@@ -13647,7 +14711,9 @@ var AISDKPlugin = class extends BasePlugin {
13647
14711
  traceSyncStreamChannel(aiSDKChannels.agentStreamSync, {
13648
14712
  name: "Agent.stream",
13649
14713
  type: "function" /* FUNCTION */,
13650
- extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
14714
+ extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
14715
+ agentOwner: true
14716
+ }),
13651
14717
  patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
13652
14718
  defaultDenyOutputPaths: denyOutputPaths,
13653
14719
  endEvent,
@@ -13661,7 +14727,9 @@ var AISDKPlugin = class extends BasePlugin {
13661
14727
  traceStreamingChannel(aiSDKChannels.toolLoopAgentGenerate, {
13662
14728
  name: "ToolLoopAgent.generate",
13663
14729
  type: "function" /* FUNCTION */,
13664
- extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
14730
+ extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
14731
+ agentOwner: true
14732
+ }),
13665
14733
  extractOutput: (result, endEvent) => {
13666
14734
  finalizeAISDKChildTracing(endEvent);
13667
14735
  return processAISDKOutput(
@@ -13677,7 +14745,9 @@ var AISDKPlugin = class extends BasePlugin {
13677
14745
  traceStreamingChannel(aiSDKChannels.toolLoopAgentStream, {
13678
14746
  name: "ToolLoopAgent.stream",
13679
14747
  type: "function" /* FUNCTION */,
13680
- extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
14748
+ extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
14749
+ agentOwner: true
14750
+ }),
13681
14751
  extractOutput: (result, endEvent) => processAISDKOutput(
13682
14752
  result,
13683
14753
  resolveDenyOutputPaths(endEvent, denyOutputPaths)
@@ -13693,6 +14763,42 @@ var AISDKPlugin = class extends BasePlugin {
13693
14763
  })
13694
14764
  })
13695
14765
  );
14766
+ this.unsubscribers.push(
14767
+ traceStreamingChannel(aiSDKChannels.workflowAgentStream, {
14768
+ name: "WorkflowAgent.stream",
14769
+ type: "function" /* FUNCTION */,
14770
+ extractInput: ([params], event, span) => prepareAISDKWorkflowAgentStreamInput(
14771
+ params,
14772
+ event,
14773
+ span,
14774
+ denyOutputPaths
14775
+ ),
14776
+ extractOutput: (result, endEvent) => {
14777
+ finalizeAISDKChildTracing(endEvent);
14778
+ return processAISDKOutput(
14779
+ result,
14780
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
14781
+ );
14782
+ },
14783
+ extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
14784
+ aggregateChunks: aggregateAISDKChunks,
14785
+ onComplete: ({ span }) => {
14786
+ unregisterWorkflowAgentWrapperSpan(span);
14787
+ },
14788
+ onError: ({ event, span }) => {
14789
+ finalizeAISDKChildTracing(event);
14790
+ unregisterWorkflowAgentWrapperSpan(span);
14791
+ },
14792
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
14793
+ defaultDenyOutputPaths: denyOutputPaths,
14794
+ endEvent,
14795
+ onComplete: () => unregisterWorkflowAgentWrapperSpan(span),
14796
+ result,
14797
+ span,
14798
+ startTime
14799
+ })
14800
+ })
14801
+ );
13696
14802
  }
13697
14803
  };
13698
14804
  function subscribeToAISDKV7TelemetryDispatcher() {
@@ -13704,7 +14810,11 @@ function subscribeToAISDKV7TelemetryDispatcher() {
13704
14810
  if (telemetryOptions?.isEnabled === false) {
13705
14811
  return;
13706
14812
  }
13707
- patchAISDKV7TelemetryDispatcher(event.result, telemetry);
14813
+ patchAISDKV7TelemetryDispatcher(
14814
+ event.result,
14815
+ telemetry,
14816
+ telemetryOptions
14817
+ );
13708
14818
  }
13709
14819
  };
13710
14820
  channel2.subscribe(handlers);
@@ -13712,7 +14822,7 @@ function subscribeToAISDKV7TelemetryDispatcher() {
13712
14822
  channel2.unsubscribe(handlers);
13713
14823
  };
13714
14824
  }
13715
- function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry) {
14825
+ function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry, telemetryOptions) {
13716
14826
  if (!isObject(dispatcher)) {
13717
14827
  return;
13718
14828
  }
@@ -13721,6 +14831,54 @@ function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry) {
13721
14831
  return;
13722
14832
  }
13723
14833
  dispatcherRecord[AUTO_PATCHED_V7_TELEMETRY_DISPATCHER] = true;
14834
+ let operationKey;
14835
+ const telemetryEventFields = {};
14836
+ if (typeof telemetryOptions?.recordInputs === "boolean") {
14837
+ telemetryEventFields.recordInputs = telemetryOptions.recordInputs;
14838
+ }
14839
+ if (typeof telemetryOptions?.recordOutputs === "boolean") {
14840
+ telemetryEventFields.recordOutputs = telemetryOptions.recordOutputs;
14841
+ }
14842
+ if (typeof telemetryOptions?.functionId === "string") {
14843
+ telemetryEventFields.functionId = telemetryOptions.functionId;
14844
+ }
14845
+ const eventWithOperationKey = (event) => {
14846
+ if (!isObject(event)) {
14847
+ return event;
14848
+ }
14849
+ const eventRecord = event;
14850
+ const callId = typeof eventRecord.callId === "string" ? eventRecord.callId : "unknown";
14851
+ operationKey ??= `${callId}:${++aiSDKV7TelemetryOperationCounter}`;
14852
+ if (Object.keys(telemetryEventFields).length > 0) {
14853
+ const augmentedEvent = {
14854
+ ...telemetryEventFields,
14855
+ ...event
14856
+ };
14857
+ try {
14858
+ Object.defineProperty(augmentedEvent, BRAINTRUST_AI_SDK_V7_OPERATION_KEY, {
14859
+ configurable: true,
14860
+ enumerable: false,
14861
+ value: operationKey
14862
+ });
14863
+ } catch {
14864
+ augmentedEvent[BRAINTRUST_AI_SDK_V7_OPERATION_KEY] = operationKey;
14865
+ }
14866
+ return augmentedEvent;
14867
+ }
14868
+ try {
14869
+ Object.defineProperty(eventRecord, BRAINTRUST_AI_SDK_V7_OPERATION_KEY, {
14870
+ configurable: true,
14871
+ enumerable: false,
14872
+ value: operationKey
14873
+ });
14874
+ return event;
14875
+ } catch {
14876
+ return {
14877
+ ...event,
14878
+ [BRAINTRUST_AI_SDK_V7_OPERATION_KEY]: operationKey
14879
+ };
14880
+ }
14881
+ };
13724
14882
  for (const key of AI_SDK_V7_TELEMETRY_CALLBACKS) {
13725
14883
  const braintrustCallback = telemetry[key];
13726
14884
  if (typeof braintrustCallback !== "function") {
@@ -13729,11 +14887,17 @@ function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry) {
13729
14887
  const existingCallback = dispatcherRecord[key];
13730
14888
  dispatcherRecord[key] = (event) => {
13731
14889
  const existingResult = typeof existingCallback === "function" ? existingCallback.call(dispatcher, event) : void 0;
13732
- const braintrustResult = braintrustCallback.call(telemetry, event);
13733
- const pending = [existingResult, braintrustResult].filter(isPromiseLike);
13734
- if (pending.length > 0) {
13735
- return Promise.allSettled(pending).then(() => void 0);
14890
+ try {
14891
+ const braintrustResult = braintrustCallback.call(
14892
+ telemetry,
14893
+ eventWithOperationKey(event)
14894
+ );
14895
+ if (isPromiseLike(braintrustResult)) {
14896
+ void Promise.resolve(braintrustResult).catch(() => void 0);
14897
+ }
14898
+ } catch {
13736
14899
  }
14900
+ return existingResult;
13737
14901
  };
13738
14902
  }
13739
14903
  const braintrustExecuteTool = telemetry.executeTool;
@@ -13743,6 +14907,7 @@ function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry) {
13743
14907
  const existingExecuteTool = dispatcherRecord.executeTool;
13744
14908
  dispatcherRecord.executeTool = (args) => braintrustExecuteTool.call(telemetry, {
13745
14909
  ...args,
14910
+ ...operationKey ? { [BRAINTRUST_AI_SDK_V7_OPERATION_KEY]: operationKey } : {},
13746
14911
  execute: () => typeof existingExecuteTool === "function" ? existingExecuteTool.call(dispatcher, args) : args.execute()
13747
14912
  });
13748
14913
  }
@@ -13841,6 +15006,8 @@ var serializeOutputObject = (output, model) => {
13841
15006
  var processInputAttachmentsSync = (input) => {
13842
15007
  if (!input) return { input };
13843
15008
  const processed = { ...input };
15009
+ delete processed.headers;
15010
+ delete processed.experimental_output;
13844
15011
  if (input.messages && Array.isArray(input.messages)) {
13845
15012
  processed.messages = input.messages.map(processMessage);
13846
15013
  }
@@ -13874,10 +15041,10 @@ var processInputAttachmentsSync = (input) => {
13874
15041
  processed.output = serialized;
13875
15042
  }
13876
15043
  }
13877
- if ("prepareCall" in processed && typeof processed.prepareCall === "function") {
13878
- processed.prepareCall = "[Function]";
13879
- }
13880
- return { input: processed, outputPromise };
15044
+ return {
15045
+ input: sanitizeAISDKCallInputValue(processed),
15046
+ outputPromise
15047
+ };
13881
15048
  };
13882
15049
  var processMessage = (message) => {
13883
15050
  if (!message || typeof message !== "object") return message;
@@ -14041,7 +15208,21 @@ var convertDataToAttachment = (data, mimeType, filename) => {
14041
15208
  function processAISDKCallInput(params) {
14042
15209
  return processInputAttachmentsSync(params);
14043
15210
  }
14044
- function prepareAISDKCallInput(params, event, span, defaultDenyOutputPaths) {
15211
+ function processAISDKWorkflowAgentCallInput(params) {
15212
+ const processed = processAISDKCallInput(params);
15213
+ return {
15214
+ ...processed,
15215
+ input: extractWorkflowAgentInput(processed.input)
15216
+ };
15217
+ }
15218
+ function processAISDKWorkflowAgentModelCallInput(params) {
15219
+ const processed = processAISDKCallInput(params);
15220
+ return {
15221
+ ...processed,
15222
+ input: extractWorkflowAgentModelInput(processed.input)
15223
+ };
15224
+ }
15225
+ function prepareAISDKCallInput(params, event, span, defaultDenyOutputPaths, childTracingOptions = {}) {
14045
15226
  const { input, outputPromise } = processAISDKCallInput(params);
14046
15227
  if (outputPromise && input && typeof input === "object") {
14047
15228
  outputPromise.then((resolvedData) => {
@@ -14060,7 +15241,29 @@ function prepareAISDKCallInput(params, event, span, defaultDenyOutputPaths) {
14060
15241
  event.self,
14061
15242
  span,
14062
15243
  defaultDenyOutputPaths,
14063
- event.aiSDK
15244
+ event.aiSDK,
15245
+ childTracingOptions
15246
+ );
15247
+ event.modelWrapped = childTracing.modelWrapped;
15248
+ if (childTracing.cleanup) {
15249
+ event.__braintrust_ai_sdk_cleanup = childTracing.cleanup;
15250
+ }
15251
+ return {
15252
+ input,
15253
+ metadata
15254
+ };
15255
+ }
15256
+ function prepareAISDKWorkflowAgentStreamInput(params, event, span, defaultDenyOutputPaths) {
15257
+ registerWorkflowAgentWrapperSpan(span);
15258
+ const { input } = processAISDKWorkflowAgentCallInput(params);
15259
+ const metadata = extractWorkflowMetadataFromCallParams(params, event.self);
15260
+ const childTracing = prepareAISDKChildTracing(
15261
+ params,
15262
+ event.self,
15263
+ span,
15264
+ defaultDenyOutputPaths,
15265
+ event.aiSDK,
15266
+ { agentOwner: true, workflowAgent: true }
14064
15267
  );
14065
15268
  event.modelWrapped = childTracing.modelWrapped;
14066
15269
  if (childTracing.cleanup) {
@@ -14097,6 +15300,9 @@ function extractTopLevelAISDKMetrics(result, event, startTime) {
14097
15300
  function hasModelChildTracing(event) {
14098
15301
  return event?.modelWrapped === true || event?.__braintrust_ai_sdk_model_wrapped === true;
14099
15302
  }
15303
+ function serializeToolExecutionInput(args) {
15304
+ return args.length > 0 ? args[0] : args;
15305
+ }
14100
15306
  function createAISDKIntegrationMetadata() {
14101
15307
  return {
14102
15308
  braintrust: {
@@ -14108,6 +15314,13 @@ function createAISDKIntegrationMetadata() {
14108
15314
  function resolveModelFromSelf(self) {
14109
15315
  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;
14110
15316
  }
15317
+ function resolveToolsFromSelf(self) {
15318
+ if (!self || typeof self !== "object") {
15319
+ return void 0;
15320
+ }
15321
+ const selfRecord = self;
15322
+ return selfRecord.tools ?? selfRecord.settings?.tools;
15323
+ }
14111
15324
  function extractBaseMetadata(model, self) {
14112
15325
  const metadata = createAISDKIntegrationMetadata();
14113
15326
  const { model: modelId, provider } = serializeModelWithProvider(
@@ -14123,12 +15336,175 @@ function extractBaseMetadata(model, self) {
14123
15336
  }
14124
15337
  function extractMetadataFromCallParams(params, self) {
14125
15338
  const metadata = extractBaseMetadata(params.model, self);
14126
- const tools = serializeAISDKToolsForLogging(params.tools);
15339
+ const tools = serializeAISDKToolsForLogging(
15340
+ params.tools ?? resolveToolsFromSelf(self)
15341
+ );
14127
15342
  if (tools) {
14128
15343
  metadata.tools = tools;
14129
15344
  }
14130
15345
  return metadata;
14131
15346
  }
15347
+ function extractWorkflowMetadataFromCallParams(params, self) {
15348
+ const metadata = extractMetadataFromCallParams(params, self);
15349
+ const options = extractAISDKCallOptionsForMetadata(params);
15350
+ if (Object.keys(options).length > 0) {
15351
+ metadata.options = options;
15352
+ }
15353
+ return metadata;
15354
+ }
15355
+ function extractWorkflowAgentInput(params) {
15356
+ const input = {};
15357
+ if (params.instructions !== void 0) {
15358
+ input.instructions = params.instructions;
15359
+ }
15360
+ if (params.system !== void 0) {
15361
+ input.system = params.system;
15362
+ }
15363
+ if (Array.isArray(params.messages)) {
15364
+ return { ...input, messages: params.messages };
15365
+ }
15366
+ if (typeof params.prompt === "string") {
15367
+ return { ...input, prompt: params.prompt };
15368
+ }
15369
+ if (Array.isArray(params.prompt)) {
15370
+ return { ...input, prompt: params.prompt };
15371
+ }
15372
+ return input;
15373
+ }
15374
+ function extractWorkflowAgentModelInput(params) {
15375
+ const input = {};
15376
+ if (params.instructions !== void 0) {
15377
+ input.instructions = params.instructions;
15378
+ }
15379
+ if (params.system !== void 0) {
15380
+ input.system = params.system;
15381
+ }
15382
+ if (Array.isArray(params.messages)) {
15383
+ return { ...input, messages: params.messages };
15384
+ }
15385
+ if (typeof params.prompt === "string") {
15386
+ return { ...input, prompt: params.prompt };
15387
+ }
15388
+ if (Array.isArray(params.prompt)) {
15389
+ return { ...input, messages: params.prompt };
15390
+ }
15391
+ return input;
15392
+ }
15393
+ function sanitizeAISDKCallInputValue(value, depth = 0) {
15394
+ if (value === void 0 || typeof value === "function") {
15395
+ return void 0;
15396
+ }
15397
+ if (value === null || typeof value !== "object") {
15398
+ return value;
15399
+ }
15400
+ if (isPromiseLike(value)) {
15401
+ return "[Promise]";
15402
+ }
15403
+ if (typeof AbortSignal !== "undefined" && value instanceof AbortSignal) {
15404
+ return "[AbortSignal]";
15405
+ }
15406
+ if (depth >= 8) {
15407
+ return "[Object]";
15408
+ }
15409
+ if (Array.isArray(value)) {
15410
+ return value.map((item) => sanitizeAISDKCallInputValue(item, depth + 1)).filter((item) => item !== void 0);
15411
+ }
15412
+ if (!isObject(value)) {
15413
+ return value;
15414
+ }
15415
+ const prototype = Object.getPrototypeOf(value);
15416
+ if (prototype !== Object.prototype && prototype !== null) {
15417
+ return value;
15418
+ }
15419
+ const sanitized = {};
15420
+ for (const [key, nested] of Object.entries(value)) {
15421
+ if (key === "__proto__" || key === "constructor" || key === "prototype" || key.toLowerCase() === "headers") {
15422
+ continue;
15423
+ }
15424
+ const sanitizedNested = sanitizeAISDKCallInputValue(nested, depth + 1);
15425
+ if (sanitizedNested !== void 0) {
15426
+ sanitized[key] = sanitizedNested;
15427
+ }
15428
+ }
15429
+ return sanitized;
15430
+ }
15431
+ function extractAISDKCallOptionsForMetadata(params) {
15432
+ const options = {};
15433
+ const inputOrTopLevelKeys = /* @__PURE__ */ new Set([
15434
+ "model",
15435
+ "instructions",
15436
+ "messages",
15437
+ "prompt",
15438
+ "system",
15439
+ "tools",
15440
+ "headers",
15441
+ "abortSignal",
15442
+ "signal",
15443
+ "experimental_output"
15444
+ ]);
15445
+ for (const [key, value] of Object.entries(params)) {
15446
+ if (inputOrTopLevelKeys.has(key) || key === "__proto__" || key === "constructor" || key === "prototype" || /^on[A-Z]/.test(key) && typeof value === "function") {
15447
+ continue;
15448
+ }
15449
+ const sanitized = sanitizeAISDKMetadataValue(value);
15450
+ if (sanitized !== void 0) {
15451
+ options[key] = sanitized;
15452
+ }
15453
+ }
15454
+ return options;
15455
+ }
15456
+ function sanitizeAISDKMetadataValue(value, depth = 0) {
15457
+ if (value === void 0) {
15458
+ return void 0;
15459
+ }
15460
+ if (typeof value === "function") {
15461
+ return "[Function]";
15462
+ }
15463
+ if (value === null || typeof value !== "object") {
15464
+ return value;
15465
+ }
15466
+ if (isPromiseLike(value)) {
15467
+ return "[Promise]";
15468
+ }
15469
+ if (typeof AbortSignal !== "undefined" && value instanceof AbortSignal) {
15470
+ return "[AbortSignal]";
15471
+ }
15472
+ if (depth >= 8) {
15473
+ return "[Object]";
15474
+ }
15475
+ if (Array.isArray(value)) {
15476
+ return value.map((item) => sanitizeAISDKMetadataValue(item, depth + 1)).filter((item) => item !== void 0);
15477
+ }
15478
+ if (!isObject(value)) {
15479
+ return value;
15480
+ }
15481
+ const sanitized = {};
15482
+ for (const [key, nested] of Object.entries(value)) {
15483
+ if (key === "__proto__" || key === "constructor" || key === "prototype" || key.toLowerCase() === "headers") {
15484
+ continue;
15485
+ }
15486
+ const sanitizedNested = sanitizeAISDKMetadataValue(nested, depth + 1);
15487
+ if (sanitizedNested !== void 0) {
15488
+ sanitized[key] = sanitizedNested;
15489
+ }
15490
+ }
15491
+ return sanitized;
15492
+ }
15493
+ function buildAISDKModelStartEvent(callOptions, baseMetadata, options) {
15494
+ if (!options.workflowAgent) {
15495
+ return {
15496
+ input: processAISDKCallInput(callOptions).input,
15497
+ metadata: baseMetadata
15498
+ };
15499
+ }
15500
+ return {
15501
+ input: processAISDKWorkflowAgentModelCallInput(callOptions).input,
15502
+ metadata: {
15503
+ ...baseMetadata,
15504
+ ...extractWorkflowMetadataFromCallParams(callOptions)
15505
+ }
15506
+ };
15507
+ }
14132
15508
  function extractMetadataFromEmbedParams(params, self) {
14133
15509
  return extractBaseMetadata(params.model, self);
14134
15510
  }
@@ -14142,65 +15518,228 @@ function extractMetadataFromRerankParams(params, self) {
14142
15518
  }
14143
15519
  return metadata;
14144
15520
  }
14145
- function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiSDK) {
15521
+ function activeAISDKChildPatchEntry(entries) {
15522
+ const activeSpan = currentSpan();
15523
+ const activeSpanId = activeSpan.spanId;
15524
+ if (activeSpanId) {
15525
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
15526
+ const entry = entries[index];
15527
+ if (entry?.activeSpanIds.has(activeSpanId)) {
15528
+ return entry;
15529
+ }
15530
+ }
15531
+ }
15532
+ const activeParentSpanIds = activeSpan.spanParents ?? [];
15533
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
15534
+ const entry = entries[index];
15535
+ if (entry?.parentSpan.spanId && activeParentSpanIds.includes(entry.parentSpan.spanId)) {
15536
+ return entry;
15537
+ }
15538
+ }
15539
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
15540
+ const entry = entries[index];
15541
+ if (entry?.parentSpan.spanId === activeSpanId) {
15542
+ return entry;
15543
+ }
15544
+ }
15545
+ return entries[entries.length - 1];
15546
+ }
15547
+ function attachNestedAISDKChildPatchEntry(entries, nestedSpan, cleanup) {
15548
+ const activeSpanId = currentSpan().spanId;
15549
+ if (!activeSpanId || activeSpanId === nestedSpan.spanId) {
15550
+ return false;
15551
+ }
15552
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
15553
+ const entry = entries[index];
15554
+ if (entry?.parentSpan.spanId === activeSpanId || entry?.activeSpanIds.has(activeSpanId)) {
15555
+ entry.activeSpanIds.add(nestedSpan.spanId);
15556
+ cleanup.push(() => {
15557
+ entry.activeSpanIds.delete(nestedSpan.spanId);
15558
+ });
15559
+ return true;
15560
+ }
15561
+ }
15562
+ return false;
15563
+ }
15564
+ function shadowActiveAISDKChildPatchEntry(entries, entry, nestedSpan, cleanup) {
15565
+ const activeSpanId = currentSpan().spanId;
15566
+ if (!activeSpanId || activeSpanId === nestedSpan.spanId) {
15567
+ return;
15568
+ }
15569
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
15570
+ const existingEntry = entries[index];
15571
+ if (existingEntry?.parentSpan.spanId === activeSpanId || existingEntry?.activeSpanIds.has(activeSpanId)) {
15572
+ entry.activeSpanIds.add(activeSpanId);
15573
+ cleanup.push(() => {
15574
+ entry.activeSpanIds.delete(activeSpanId);
15575
+ });
15576
+ return;
15577
+ }
15578
+ }
15579
+ }
15580
+ function closeOpenAISDKModelPatchSpans(entry) {
15581
+ for (const span of entry.openSpans) {
15582
+ span.end();
15583
+ }
15584
+ entry.openSpans.clear();
15585
+ }
15586
+ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiSDK, childTracingOptions = {}) {
14146
15587
  const cleanup = [];
14147
- const patchedModels = /* @__PURE__ */ new WeakSet();
15588
+ const patchedModels = /* @__PURE__ */ new WeakMap();
14148
15589
  const patchedTools = /* @__PURE__ */ new WeakSet();
14149
15590
  let modelWrapped = false;
14150
15591
  const patchModel = (model) => {
14151
15592
  const resolvedModel = resolveAISDKModel(model, aiSDK);
14152
- if (!resolvedModel || typeof resolvedModel !== "object" || typeof resolvedModel.doGenerate !== "function" || patchedModels.has(resolvedModel) || resolvedModel[AUTO_PATCHED_MODEL]) {
15593
+ if (!resolvedModel || typeof resolvedModel !== "object" || typeof resolvedModel.doGenerate !== "function") {
14153
15594
  return resolvedModel;
14154
15595
  }
14155
- patchedModels.add(resolvedModel);
14156
- resolvedModel[AUTO_PATCHED_MODEL] = true;
15596
+ const existingWrappedModel = patchedModels.get(resolvedModel);
15597
+ if (existingWrappedModel) {
15598
+ modelWrapped = true;
15599
+ return existingWrappedModel;
15600
+ }
14157
15601
  modelWrapped = true;
15602
+ const modelRecord = resolvedModel;
15603
+ const entry = {
15604
+ activeSpanIds: /* @__PURE__ */ new Set([parentSpan.spanId]),
15605
+ baseMetadata: buildAISDKChildMetadata(resolvedModel),
15606
+ childTracingOptions,
15607
+ denyOutputPaths,
15608
+ openSpans: /* @__PURE__ */ new Set(),
15609
+ parentSpan
15610
+ };
15611
+ const cleanupModelEntry = (state2, patchedModel) => {
15612
+ closeOpenAISDKModelPatchSpans(entry);
15613
+ const index = state2.entries.indexOf(entry);
15614
+ if (index >= 0) {
15615
+ state2.entries.splice(index, 1);
15616
+ }
15617
+ if (state2.entries.length > 0) {
15618
+ return;
15619
+ }
15620
+ patchedModel.doGenerate = state2.originalDoGenerate;
15621
+ patchedModel.doStream = state2.originalDoStream;
15622
+ delete patchedModel[AUTO_PATCHED_MODEL];
15623
+ };
15624
+ const existingState = modelRecord[AUTO_PATCHED_MODEL];
15625
+ if (existingState) {
15626
+ patchedModels.set(resolvedModel, resolvedModel);
15627
+ if (childTracingOptions.agentOwner && attachNestedAISDKChildPatchEntry(
15628
+ existingState.entries,
15629
+ parentSpan,
15630
+ cleanup
15631
+ )) {
15632
+ return resolvedModel;
15633
+ }
15634
+ if (!childTracingOptions.agentOwner) {
15635
+ shadowActiveAISDKChildPatchEntry(
15636
+ existingState.entries,
15637
+ entry,
15638
+ parentSpan,
15639
+ cleanup
15640
+ );
15641
+ }
15642
+ existingState.entries.push(entry);
15643
+ cleanup.push(() => {
15644
+ cleanupModelEntry(existingState, modelRecord);
15645
+ });
15646
+ return resolvedModel;
15647
+ }
14158
15648
  const originalDoGenerate = resolvedModel.doGenerate;
14159
15649
  const originalDoStream = resolvedModel.doStream;
14160
- const baseMetadata = buildAISDKChildMetadata(resolvedModel);
14161
- resolvedModel.doGenerate = async function doGeneratePatched(options) {
14162
- return parentSpan.traced(
15650
+ const wrappedModel = Object.create(
15651
+ Object.getPrototypeOf(resolvedModel)
15652
+ );
15653
+ Object.defineProperties(
15654
+ wrappedModel,
15655
+ Object.getOwnPropertyDescriptors(resolvedModel)
15656
+ );
15657
+ const wrappedModelRecord = wrappedModel;
15658
+ const state = {
15659
+ entries: [entry],
15660
+ originalDoGenerate,
15661
+ originalDoStream
15662
+ };
15663
+ Object.defineProperty(wrappedModel, AUTO_PATCHED_MODEL, {
15664
+ configurable: true,
15665
+ value: state
15666
+ });
15667
+ wrappedModel.doGenerate = async function doGeneratePatched(callOptions) {
15668
+ const activeEntry = activeAISDKChildPatchEntry(state.entries);
15669
+ if (!activeEntry) {
15670
+ return Reflect.apply(originalDoGenerate, resolvedModel, [callOptions]);
15671
+ }
15672
+ closeOpenAISDKModelPatchSpans(activeEntry);
15673
+ return activeEntry.parentSpan.traced(
14163
15674
  async (span) => {
14164
- const result = await Reflect.apply(
14165
- originalDoGenerate,
14166
- resolvedModel,
14167
- [options]
14168
- );
14169
- span.log({
14170
- output: processAISDKOutput(result, denyOutputPaths),
14171
- metrics: extractTokenMetrics(result),
14172
- ...buildResolvedMetadataPayload(result)
14173
- });
14174
- return result;
15675
+ activeEntry.openSpans.add(span);
15676
+ try {
15677
+ const result = await Reflect.apply(
15678
+ originalDoGenerate,
15679
+ resolvedModel,
15680
+ [callOptions]
15681
+ );
15682
+ const output = processAISDKOutput(
15683
+ result,
15684
+ activeEntry.denyOutputPaths
15685
+ );
15686
+ const metrics = extractTokenMetrics(result);
15687
+ const metadataPayload = buildResolvedMetadataPayload(result);
15688
+ const missingUsageMetadata = buildMissingUsageMetadata(
15689
+ output,
15690
+ metrics,
15691
+ "ai_sdk_result_missing_usage"
15692
+ );
15693
+ span.log({
15694
+ output,
15695
+ metrics,
15696
+ ...mergeMetadataPayload(metadataPayload, missingUsageMetadata)
15697
+ });
15698
+ return result;
15699
+ } finally {
15700
+ activeEntry.openSpans.delete(span);
15701
+ }
14175
15702
  },
14176
15703
  {
14177
15704
  name: "doGenerate",
14178
15705
  spanAttributes: {
14179
15706
  type: "llm" /* LLM */
14180
- },
14181
- event: {
14182
- input: processAISDKCallInput(options).input,
14183
- metadata: baseMetadata
14184
- }
15707
+ },
15708
+ event: buildAISDKModelStartEvent(
15709
+ callOptions,
15710
+ activeEntry.baseMetadata,
15711
+ {
15712
+ workflowAgent: activeEntry.childTracingOptions.workflowAgent
15713
+ }
15714
+ )
14185
15715
  }
14186
15716
  );
14187
15717
  };
14188
15718
  if (originalDoStream) {
14189
- resolvedModel.doStream = async function doStreamPatched(options) {
14190
- const span = parentSpan.startSpan({
15719
+ wrappedModel.doStream = async function doStreamPatched(callOptions) {
15720
+ const activeEntry = activeAISDKChildPatchEntry(state.entries);
15721
+ if (!activeEntry) {
15722
+ return Reflect.apply(originalDoStream, resolvedModel, [callOptions]);
15723
+ }
15724
+ closeOpenAISDKModelPatchSpans(activeEntry);
15725
+ const span = activeEntry.parentSpan.startSpan({
14191
15726
  name: "doStream",
14192
15727
  spanAttributes: {
14193
15728
  type: "llm" /* LLM */
14194
15729
  },
14195
- event: {
14196
- input: processAISDKCallInput(options).input,
14197
- metadata: baseMetadata
14198
- }
15730
+ event: buildAISDKModelStartEvent(
15731
+ callOptions,
15732
+ activeEntry.baseMetadata,
15733
+ {
15734
+ workflowAgent: activeEntry.childTracingOptions.workflowAgent
15735
+ }
15736
+ )
14199
15737
  });
15738
+ activeEntry.openSpans.add(span);
14200
15739
  const streamStartTime = getCurrentUnixTimestamp();
14201
15740
  const result = await withCurrent(
14202
15741
  span,
14203
- () => Reflect.apply(originalDoStream, resolvedModel, [options])
15742
+ () => Reflect.apply(originalDoStream, resolvedModel, [callOptions])
14204
15743
  );
14205
15744
  let firstChunkTime;
14206
15745
  const output = {};
@@ -14208,6 +15747,44 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
14208
15747
  let reasoning = "";
14209
15748
  const toolCalls = [];
14210
15749
  let object = void 0;
15750
+ let streamSpanEnded = false;
15751
+ const logAndEndStreamSpan = (usageUnavailableReason) => {
15752
+ if (streamSpanEnded) {
15753
+ return;
15754
+ }
15755
+ output.text = text;
15756
+ output.reasoning = reasoning;
15757
+ output.toolCalls = toolCalls;
15758
+ if (object !== void 0) {
15759
+ output.object = object;
15760
+ }
15761
+ const metrics = extractTokenMetrics(output);
15762
+ if (firstChunkTime !== void 0 && !activeEntry.childTracingOptions.workflowAgent) {
15763
+ metrics.time_to_first_token = Math.max(
15764
+ firstChunkTime - streamStartTime,
15765
+ 1e-6
15766
+ );
15767
+ }
15768
+ const metadataPayload = buildResolvedMetadataPayload(
15769
+ output
15770
+ );
15771
+ const missingUsageMetadata = usageUnavailableReason ? { usage_unavailable_reason: usageUnavailableReason } : buildMissingUsageMetadata(
15772
+ output,
15773
+ metrics,
15774
+ "ai_sdk_result_missing_usage"
15775
+ );
15776
+ span.log({
15777
+ output: processAISDKOutput(
15778
+ output,
15779
+ activeEntry.denyOutputPaths
15780
+ ),
15781
+ metrics,
15782
+ ...mergeMetadataPayload(metadataPayload, missingUsageMetadata)
15783
+ });
15784
+ activeEntry.openSpans.delete(span);
15785
+ span.end();
15786
+ streamSpanEnded = true;
15787
+ };
14211
15788
  const transformStream = new TransformStream({
14212
15789
  transform(chunk, controller) {
14213
15790
  if (firstChunkTime === void 0 && isAISDKContentStreamChunk(chunk)) {
@@ -14245,33 +15822,15 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
14245
15822
  }
14246
15823
  break;
14247
15824
  case "finish":
14248
- output.text = text;
14249
- output.reasoning = reasoning;
14250
- output.toolCalls = toolCalls;
14251
15825
  output.finishReason = chunk.finishReason;
14252
15826
  output.usage = chunk.usage;
14253
- if (object !== void 0) {
14254
- output.object = object;
14255
- }
14256
- const metrics = extractTokenMetrics(output);
14257
- if (firstChunkTime !== void 0) {
14258
- metrics.time_to_first_token = Math.max(
14259
- firstChunkTime - streamStartTime,
14260
- 1e-6
14261
- );
14262
- }
14263
- span.log({
14264
- output: processAISDKOutput(
14265
- output,
14266
- denyOutputPaths
14267
- ),
14268
- metrics,
14269
- ...buildResolvedMetadataPayload(output)
14270
- });
14271
- span.end();
15827
+ logAndEndStreamSpan();
14272
15828
  break;
14273
15829
  }
14274
15830
  controller.enqueue(chunk);
15831
+ },
15832
+ flush() {
15833
+ logAndEndStreamSpan("ai_sdk_stream_finished_without_usage");
14275
15834
  }
14276
15835
  });
14277
15836
  return {
@@ -14281,32 +15840,79 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
14281
15840
  };
14282
15841
  }
14283
15842
  cleanup.push(() => {
14284
- resolvedModel.doGenerate = originalDoGenerate;
14285
- if (originalDoStream) {
14286
- resolvedModel.doStream = originalDoStream;
14287
- }
14288
- delete resolvedModel[AUTO_PATCHED_MODEL];
15843
+ cleanupModelEntry(state, wrappedModelRecord);
14289
15844
  });
14290
- return resolvedModel;
15845
+ patchedModels.set(resolvedModel, wrappedModel);
15846
+ patchedModels.set(wrappedModel, wrappedModel);
15847
+ return wrappedModel;
14291
15848
  };
14292
15849
  const patchTool = (tool, name) => {
14293
- if (tool == null || typeof tool !== "object" || !("execute" in tool) || typeof tool.execute !== "function" || patchedTools.has(tool) || tool[AUTO_PATCHED_TOOL]) {
15850
+ if (tool == null || typeof tool !== "object" || !("execute" in tool) || typeof tool.execute !== "function" || patchedTools.has(tool)) {
14294
15851
  return;
14295
15852
  }
14296
15853
  patchedTools.add(tool);
14297
- tool[AUTO_PATCHED_TOOL] = true;
14298
- const originalExecute = tool.execute;
15854
+ const toolRecord = tool;
15855
+ const entry = {
15856
+ activeSpanIds: /* @__PURE__ */ new Set([parentSpan.spanId]),
15857
+ childTracingOptions,
15858
+ name,
15859
+ parentSpan
15860
+ };
15861
+ const cleanupToolEntry = (state2) => {
15862
+ const index = state2.entries.indexOf(entry);
15863
+ if (index >= 0) {
15864
+ state2.entries.splice(index, 1);
15865
+ }
15866
+ if (state2.entries.length > 0) {
15867
+ return;
15868
+ }
15869
+ tool.execute = state2.originalExecute;
15870
+ delete toolRecord[AUTO_PATCHED_TOOL];
15871
+ };
15872
+ const existingState = toolRecord[AUTO_PATCHED_TOOL];
15873
+ if (existingState) {
15874
+ if (childTracingOptions.agentOwner && attachNestedAISDKChildPatchEntry(
15875
+ existingState.entries,
15876
+ parentSpan,
15877
+ cleanup
15878
+ )) {
15879
+ return;
15880
+ }
15881
+ if (!childTracingOptions.agentOwner) {
15882
+ shadowActiveAISDKChildPatchEntry(
15883
+ existingState.entries,
15884
+ entry,
15885
+ parentSpan,
15886
+ cleanup
15887
+ );
15888
+ }
15889
+ existingState.entries.push(entry);
15890
+ cleanup.push(() => {
15891
+ cleanupToolEntry(existingState);
15892
+ });
15893
+ return;
15894
+ }
15895
+ const originalExecute = toolRecord.execute;
15896
+ const state = {
15897
+ entries: [entry],
15898
+ originalExecute
15899
+ };
15900
+ toolRecord[AUTO_PATCHED_TOOL] = state;
14299
15901
  tool.execute = function executePatched(...args) {
15902
+ const activeEntry = activeAISDKChildPatchEntry(state.entries);
14300
15903
  const result = Reflect.apply(originalExecute, this, args);
15904
+ if (!activeEntry) {
15905
+ return result;
15906
+ }
14301
15907
  if (isAsyncGenerator(result)) {
14302
15908
  return (async function* () {
14303
- const span = parentSpan.startSpan({
14304
- name,
15909
+ const span = activeEntry.parentSpan.startSpan({
15910
+ name: activeEntry.name,
14305
15911
  spanAttributes: {
14306
15912
  type: "tool" /* TOOL */
14307
15913
  }
14308
15914
  });
14309
- span.log({ input: args.length === 1 ? args[0] : args });
15915
+ span.log({ input: serializeToolExecutionInput(args) });
14310
15916
  try {
14311
15917
  let lastValue;
14312
15918
  for await (const value of result) {
@@ -14322,15 +15928,15 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
14322
15928
  }
14323
15929
  })();
14324
15930
  }
14325
- return parentSpan.traced(
15931
+ return activeEntry.parentSpan.traced(
14326
15932
  async (span) => {
14327
- span.log({ input: args.length === 1 ? args[0] : args });
15933
+ span.log({ input: serializeToolExecutionInput(args) });
14328
15934
  const awaitedResult = await result;
14329
15935
  span.log({ output: awaitedResult });
14330
15936
  return awaitedResult;
14331
15937
  },
14332
15938
  {
14333
- name,
15939
+ name: activeEntry.name,
14334
15940
  spanAttributes: {
14335
15941
  type: "tool" /* TOOL */
14336
15942
  }
@@ -14338,8 +15944,7 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
14338
15944
  );
14339
15945
  };
14340
15946
  cleanup.push(() => {
14341
- tool.execute = originalExecute;
14342
- delete tool[AUTO_PATCHED_TOOL];
15947
+ cleanupToolEntry(state);
14343
15948
  });
14344
15949
  };
14345
15950
  const patchTools = (tools) => {
@@ -14358,25 +15963,42 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
14358
15963
  }
14359
15964
  };
14360
15965
  if (params && typeof params === "object") {
14361
- const patchedParamModel = patchModel(params.model);
14362
- if (typeof params.model === "string" && patchedParamModel && typeof patchedParamModel === "object") {
15966
+ const originalParamModel = params.model;
15967
+ const patchedParamModel = patchModel(originalParamModel);
15968
+ if (patchedParamModel && patchedParamModel !== originalParamModel) {
14363
15969
  params.model = patchedParamModel;
15970
+ cleanup.push(() => {
15971
+ params.model = originalParamModel;
15972
+ });
14364
15973
  }
14365
15974
  patchTools(params.tools);
14366
15975
  }
14367
15976
  if (self && typeof self === "object") {
14368
15977
  const selfRecord = self;
14369
15978
  if (selfRecord.model !== void 0) {
14370
- const patchedSelfModel = patchModel(selfRecord.model);
14371
- if (typeof selfRecord.model === "string" && patchedSelfModel && typeof patchedSelfModel === "object") {
15979
+ const originalSelfModel = selfRecord.model;
15980
+ const patchedSelfModel = patchModel(originalSelfModel);
15981
+ if (patchedSelfModel && patchedSelfModel !== originalSelfModel) {
14372
15982
  selfRecord.model = patchedSelfModel;
15983
+ cleanup.push(() => {
15984
+ selfRecord.model = originalSelfModel;
15985
+ });
14373
15986
  }
14374
15987
  }
15988
+ if (selfRecord.tools !== void 0) {
15989
+ patchTools(selfRecord.tools);
15990
+ }
14375
15991
  if (selfRecord.settings && typeof selfRecord.settings === "object") {
14376
15992
  if (selfRecord.settings.model !== void 0) {
14377
- const patchedSettingsModel = patchModel(selfRecord.settings.model);
14378
- if (typeof selfRecord.settings.model === "string" && patchedSettingsModel && typeof patchedSettingsModel === "object") {
15993
+ const originalSettingsModel = selfRecord.settings.model;
15994
+ const patchedSettingsModel = patchModel(originalSettingsModel);
15995
+ if (patchedSettingsModel && patchedSettingsModel !== originalSettingsModel) {
14379
15996
  selfRecord.settings.model = patchedSettingsModel;
15997
+ cleanup.push(() => {
15998
+ if (selfRecord.settings) {
15999
+ selfRecord.settings.model = originalSettingsModel;
16000
+ }
16001
+ });
14380
16002
  }
14381
16003
  }
14382
16004
  if (selfRecord.settings.tools !== void 0) {
@@ -14473,99 +16095,190 @@ function isAISDKContentAsyncIterableChunk(chunk) {
14473
16095
  return isObject(part) && typeof part.type !== "string";
14474
16096
  }
14475
16097
  function patchAISDKStreamingResult(args) {
14476
- const { defaultDenyOutputPaths, endEvent, result, span, startTime } = args;
16098
+ const {
16099
+ defaultDenyOutputPaths,
16100
+ endEvent,
16101
+ onComplete,
16102
+ result,
16103
+ span,
16104
+ startTime
16105
+ } = args;
14477
16106
  if (!result || typeof result !== "object") {
14478
16107
  return false;
14479
16108
  }
14480
16109
  const resultRecord = result;
14481
16110
  attachKnownResultPromiseHandlers(resultRecord);
16111
+ let finalized = false;
16112
+ const finalize = () => {
16113
+ if (finalized) {
16114
+ return;
16115
+ }
16116
+ finalized = true;
16117
+ finalizeAISDKChildTracing(endEvent);
16118
+ span.end();
16119
+ onComplete?.();
16120
+ };
16121
+ let outputLogged = false;
16122
+ const logStreamingOutput = async (firstChunkTime) => {
16123
+ if (outputLogged) {
16124
+ return;
16125
+ }
16126
+ outputLogged = true;
16127
+ try {
16128
+ const metrics = extractTopLevelAISDKMetrics(result, endEvent);
16129
+ if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
16130
+ metrics.time_to_first_token = firstChunkTime - startTime;
16131
+ }
16132
+ const output = await processAISDKStreamingOutput(
16133
+ result,
16134
+ resolveDenyOutputPaths(endEvent, defaultDenyOutputPaths)
16135
+ );
16136
+ const metadata = buildResolvedMetadataPayload(result).metadata;
16137
+ span.log({
16138
+ output,
16139
+ ...metadata ? { metadata } : {},
16140
+ metrics
16141
+ });
16142
+ } catch (error) {
16143
+ span.log({ error: toLoggedError(error) });
16144
+ } finally {
16145
+ finalize();
16146
+ }
16147
+ };
16148
+ const createAsyncIterableHooks = () => {
16149
+ let firstChunkTime;
16150
+ return {
16151
+ onChunk: (chunk) => {
16152
+ if (firstChunkTime === void 0 && isAISDKContentAsyncIterableChunk(chunk)) {
16153
+ firstChunkTime = getCurrentUnixTimestamp();
16154
+ }
16155
+ },
16156
+ onComplete: async () => {
16157
+ await logStreamingOutput(firstChunkTime);
16158
+ },
16159
+ onError: (error) => {
16160
+ if (!outputLogged) {
16161
+ outputLogged = true;
16162
+ span.log({
16163
+ error: error.message
16164
+ });
16165
+ }
16166
+ finalize();
16167
+ },
16168
+ onCancel: finalize
16169
+ };
16170
+ };
16171
+ const patchAsyncIterable = (stream) => isReadableStreamLike(stream) ? createPatchedReadableStream(stream, createAsyncIterableHooks()) : createPatchedAsyncIterable(stream, createAsyncIterableHooks());
16172
+ const patchAsyncIterableField = (field) => {
16173
+ let descriptorOwner = resultRecord;
16174
+ let descriptor;
16175
+ while (descriptorOwner) {
16176
+ descriptor = Object.getOwnPropertyDescriptor(descriptorOwner, field);
16177
+ if (descriptor) {
16178
+ break;
16179
+ }
16180
+ descriptorOwner = Object.getPrototypeOf(descriptorOwner);
16181
+ }
16182
+ if (!descriptor || descriptorOwner === resultRecord && !descriptor.configurable) {
16183
+ return false;
16184
+ }
16185
+ if ("value" in descriptor) {
16186
+ if (!isAsyncIterable(descriptor.value)) {
16187
+ return false;
16188
+ }
16189
+ try {
16190
+ Object.defineProperty(resultRecord, field, {
16191
+ configurable: descriptorOwner === resultRecord ? descriptor.configurable : true,
16192
+ enumerable: descriptor.enumerable,
16193
+ value: patchAsyncIterable(descriptor.value),
16194
+ writable: descriptor.writable
16195
+ });
16196
+ return true;
16197
+ } catch {
16198
+ return false;
16199
+ }
16200
+ }
16201
+ if (typeof descriptor.get !== "function") {
16202
+ return false;
16203
+ }
16204
+ const originalGet = descriptor.get;
16205
+ const originalSet = descriptor.set;
16206
+ try {
16207
+ Object.defineProperty(resultRecord, field, {
16208
+ configurable: descriptorOwner === resultRecord ? descriptor.configurable : true,
16209
+ enumerable: descriptor.enumerable,
16210
+ get() {
16211
+ const stream = originalGet.call(this);
16212
+ return isAsyncIterable(stream) ? patchAsyncIterable(stream) : stream;
16213
+ },
16214
+ ...originalSet ? {
16215
+ set(value) {
16216
+ originalSet.call(this, value);
16217
+ }
16218
+ } : {}
16219
+ });
16220
+ return true;
16221
+ } catch {
16222
+ return false;
16223
+ }
16224
+ };
16225
+ let patched = false;
14482
16226
  if (isReadableStreamLike(resultRecord.baseStream)) {
14483
- let firstChunkTime2;
14484
- const wrappedBaseStream = resultRecord.baseStream.pipeThrough(
16227
+ let firstChunkTime;
16228
+ const transformedBaseStream = resultRecord.baseStream.pipeThrough(
14485
16229
  new TransformStream({
14486
16230
  transform(chunk, controller) {
14487
- if (firstChunkTime2 === void 0 && isAISDKContentStreamChunk(chunk)) {
14488
- firstChunkTime2 = getCurrentUnixTimestamp();
16231
+ if (firstChunkTime === void 0 && isAISDKContentStreamChunk(chunk)) {
16232
+ firstChunkTime = getCurrentUnixTimestamp();
14489
16233
  }
14490
16234
  controller.enqueue(chunk);
14491
16235
  },
14492
16236
  async flush() {
14493
- const metrics = extractTopLevelAISDKMetrics(result, endEvent);
14494
- if (metrics.time_to_first_token === void 0 && firstChunkTime2 !== void 0) {
14495
- metrics.time_to_first_token = firstChunkTime2 - startTime;
14496
- }
14497
- const output = await processAISDKStreamingOutput(
14498
- result,
14499
- resolveDenyOutputPaths(endEvent, defaultDenyOutputPaths)
14500
- );
14501
- const metadata = buildResolvedMetadataPayload(result).metadata;
14502
- span.log({
14503
- output,
14504
- ...metadata ? { metadata } : {},
14505
- metrics
14506
- });
14507
- finalizeAISDKChildTracing(endEvent);
14508
- span.end();
16237
+ await logStreamingOutput(firstChunkTime);
14509
16238
  }
14510
16239
  })
14511
16240
  );
16241
+ const reader = transformedBaseStream.getReader();
16242
+ const wrappedBaseStream = new ReadableStream({
16243
+ async pull(controller) {
16244
+ try {
16245
+ const { done, value } = await reader.read();
16246
+ if (done) {
16247
+ controller.close();
16248
+ return;
16249
+ }
16250
+ controller.enqueue(value);
16251
+ } catch (error) {
16252
+ span.log({ error: toLoggedError(error) });
16253
+ finalize();
16254
+ controller.error(error);
16255
+ }
16256
+ },
16257
+ async cancel(reason) {
16258
+ try {
16259
+ finalize();
16260
+ } finally {
16261
+ await reader.cancel(reason);
16262
+ }
16263
+ }
16264
+ });
14512
16265
  Object.defineProperty(resultRecord, "baseStream", {
14513
16266
  configurable: true,
14514
16267
  enumerable: true,
14515
16268
  value: wrappedBaseStream,
14516
16269
  writable: true
14517
16270
  });
14518
- return true;
16271
+ patched = true;
14519
16272
  }
14520
- const streamField = findAsyncIterableField(resultRecord, [
16273
+ for (const field of [
14521
16274
  "partialObjectStream",
14522
16275
  "textStream",
14523
16276
  "fullStream",
14524
16277
  "stream"
14525
- ]);
14526
- if (!streamField) {
14527
- return false;
16278
+ ]) {
16279
+ patched = patchAsyncIterableField(field) || patched;
14528
16280
  }
14529
- let firstChunkTime;
14530
- const wrappedStream = createPatchedAsyncIterable(streamField.stream, {
14531
- onChunk: (chunk) => {
14532
- if (firstChunkTime === void 0 && isAISDKContentAsyncIterableChunk(chunk)) {
14533
- firstChunkTime = getCurrentUnixTimestamp();
14534
- }
14535
- },
14536
- onComplete: async () => {
14537
- const metrics = extractTopLevelAISDKMetrics(result, endEvent);
14538
- if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
14539
- metrics.time_to_first_token = firstChunkTime - startTime;
14540
- }
14541
- const output = await processAISDKStreamingOutput(
14542
- result,
14543
- resolveDenyOutputPaths(endEvent, defaultDenyOutputPaths)
14544
- );
14545
- const metadata = buildResolvedMetadataPayload(result).metadata;
14546
- span.log({
14547
- output,
14548
- ...metadata ? { metadata } : {},
14549
- metrics
14550
- });
14551
- finalizeAISDKChildTracing(endEvent);
14552
- span.end();
14553
- },
14554
- onError: (error) => {
14555
- span.log({
14556
- error: error.message
14557
- });
14558
- finalizeAISDKChildTracing(endEvent);
14559
- span.end();
14560
- }
14561
- });
14562
- Object.defineProperty(resultRecord, streamField.field, {
14563
- configurable: true,
14564
- enumerable: true,
14565
- value: wrappedStream,
14566
- writable: true
14567
- });
14568
- return true;
16281
+ return patched;
14569
16282
  }
14570
16283
  function attachKnownResultPromiseHandlers(result) {
14571
16284
  const promiseLikeFields = [
@@ -14597,34 +16310,72 @@ function attachKnownResultPromiseHandlers(result) {
14597
16310
  }
14598
16311
  }
14599
16312
  function isReadableStreamLike(value) {
14600
- return value != null && typeof value === "object" && typeof value.pipeThrough === "function";
14601
- }
14602
- function findAsyncIterableField(result, candidateFields) {
14603
- for (const field of candidateFields) {
14604
- try {
14605
- const stream = result[field];
14606
- if (isAsyncIterable(stream)) {
14607
- return { field, stream };
16313
+ return value != null && typeof value === "object" && typeof value.getReader === "function" && typeof value.pipeThrough === "function";
16314
+ }
16315
+ function createPatchedReadableStream(stream, hooks) {
16316
+ let reader;
16317
+ let completed = false;
16318
+ return new ReadableStream({
16319
+ async pull(controller) {
16320
+ reader ??= stream.getReader();
16321
+ try {
16322
+ const { done, value } = await reader.read();
16323
+ if (done) {
16324
+ completed = true;
16325
+ await hooks.onComplete();
16326
+ controller.close();
16327
+ return;
16328
+ }
16329
+ hooks.onChunk(value);
16330
+ controller.enqueue(value);
16331
+ } catch (error) {
16332
+ completed = true;
16333
+ hooks.onError(
16334
+ error instanceof Error ? error : new Error(String(error))
16335
+ );
16336
+ controller.error(error);
16337
+ }
16338
+ },
16339
+ async cancel(reason) {
16340
+ if (!completed) {
16341
+ completed = true;
16342
+ try {
16343
+ await hooks.onCancel?.();
16344
+ } catch {
16345
+ }
16346
+ }
16347
+ if (reader) {
16348
+ await reader.cancel(reason);
16349
+ } else if (stream.cancel) {
16350
+ await stream.cancel(reason);
14608
16351
  }
14609
- } catch {
14610
16352
  }
14611
- }
14612
- return null;
16353
+ });
14613
16354
  }
14614
16355
  function createPatchedAsyncIterable(stream, hooks) {
14615
16356
  return {
14616
16357
  async *[Symbol.asyncIterator]() {
16358
+ let completed = false;
14617
16359
  try {
14618
16360
  for await (const chunk of stream) {
14619
16361
  hooks.onChunk(chunk);
14620
16362
  yield chunk;
14621
16363
  }
16364
+ completed = true;
14622
16365
  await hooks.onComplete();
14623
16366
  } catch (error) {
16367
+ completed = true;
14624
16368
  hooks.onError(
14625
16369
  error instanceof Error ? error : new Error(String(error))
14626
16370
  );
14627
16371
  throw error;
16372
+ } finally {
16373
+ if (!completed) {
16374
+ try {
16375
+ await hooks.onCancel?.();
16376
+ } catch {
16377
+ }
16378
+ }
14628
16379
  }
14629
16380
  }
14630
16381
  };
@@ -14699,6 +16450,40 @@ function buildResolvedMetadataPayload(result) {
14699
16450
  }
14700
16451
  return Object.keys(metadata).length > 0 ? { metadata } : {};
14701
16452
  }
16453
+ function mergeMetadataPayload(metadataPayload, extraMetadata) {
16454
+ if (!extraMetadata || Object.keys(extraMetadata).length === 0) {
16455
+ return metadataPayload;
16456
+ }
16457
+ return {
16458
+ metadata: {
16459
+ ...metadataPayload.metadata ?? {},
16460
+ ...extraMetadata
16461
+ }
16462
+ };
16463
+ }
16464
+ function buildMissingUsageMetadata(output, metrics, reason) {
16465
+ if (!hasLoggedOutput(output) || hasTokenUsageMetrics(metrics)) {
16466
+ return void 0;
16467
+ }
16468
+ return { usage_unavailable_reason: reason };
16469
+ }
16470
+ function hasLoggedOutput(output) {
16471
+ if (output === null || output === void 0) {
16472
+ return false;
16473
+ }
16474
+ if (Array.isArray(output)) {
16475
+ return output.length > 0;
16476
+ }
16477
+ if (typeof output === "object") {
16478
+ return Object.keys(output).length > 0;
16479
+ }
16480
+ return true;
16481
+ }
16482
+ function hasTokenUsageMetrics(metrics) {
16483
+ return Object.keys(metrics).some(
16484
+ (key) => key !== "estimated_cost" && key !== "time_to_first_token"
16485
+ );
16486
+ }
14702
16487
  function resolveAISDKModel(model, aiSDK) {
14703
16488
  if (typeof model !== "string") {
14704
16489
  return model;
@@ -14722,7 +16507,45 @@ function isAsyncGenerator(value) {
14722
16507
  function processAISDKOutput(output, denyOutputPaths) {
14723
16508
  if (!output) return output;
14724
16509
  const merged = extractSerializableOutputFields(output);
14725
- return normalizeAISDKLoggedOutput(omit(merged, denyOutputPaths));
16510
+ const deleteOutputPaths = denyOutputPaths.filter(
16511
+ (path2) => path2.toLowerCase().endsWith("headers")
16512
+ );
16513
+ const sanitized = omit(merged, denyOutputPaths, deleteOutputPaths);
16514
+ for (const path2 of TRANSPORT_PAYLOAD_ROOT_PATHS) {
16515
+ const stack = [{ obj: sanitized, keys: parsePath(path2) }];
16516
+ while (stack.length > 0) {
16517
+ const entry = stack.pop();
16518
+ if (!entry || entry.keys.length === 0) {
16519
+ continue;
16520
+ }
16521
+ const firstKey = entry.keys[0];
16522
+ const remainingKeys = entry.keys.slice(1);
16523
+ if (firstKey === "[]") {
16524
+ if (Array.isArray(entry.obj)) {
16525
+ for (const item of entry.obj) {
16526
+ stack.push({
16527
+ obj: item,
16528
+ keys: remainingKeys
16529
+ });
16530
+ }
16531
+ }
16532
+ continue;
16533
+ }
16534
+ if (!entry.obj || typeof entry.obj !== "object" || !(firstKey in entry.obj)) {
16535
+ continue;
16536
+ }
16537
+ const record = entry.obj;
16538
+ if (remainingKeys.length === 0) {
16539
+ record[firstKey] = sanitizeAISDKMetadataValue(record[firstKey]);
16540
+ continue;
16541
+ }
16542
+ stack.push({
16543
+ obj: record[firstKey],
16544
+ keys: remainingKeys
16545
+ });
16546
+ }
16547
+ }
16548
+ return normalizeAISDKLoggedOutput(sanitized);
14726
16549
  }
14727
16550
  function processAISDKEmbeddingOutput(output, denyOutputPaths) {
14728
16551
  if (!output || typeof output !== "object") {
@@ -14813,6 +16636,8 @@ function extractTokenMetrics(result) {
14813
16636
  );
14814
16637
  if (totalTokens !== void 0) {
14815
16638
  metrics.tokens = totalTokens;
16639
+ } else if (promptTokens !== void 0 && completionTokens !== void 0) {
16640
+ metrics.tokens = promptTokens + completionTokens;
14816
16641
  }
14817
16642
  const promptCachedTokens = firstNumber2(
14818
16643
  usage.inputTokens?.cacheRead,
@@ -14936,7 +16761,9 @@ function extractGetterValues(obj) {
14936
16761
  const getterValues = {};
14937
16762
  const getterNames = [
14938
16763
  "content",
16764
+ "messages",
14939
16765
  "text",
16766
+ "output",
14940
16767
  "object",
14941
16768
  "value",
14942
16769
  "values",
@@ -14976,7 +16803,9 @@ function extractGetterValues(obj) {
14976
16803
  function extractSerializableOutputFields(output) {
14977
16804
  const serialized = {};
14978
16805
  const directFieldNames = [
16806
+ "messages",
14979
16807
  "steps",
16808
+ "output",
14980
16809
  "request",
14981
16810
  "responseMessages",
14982
16811
  "warnings",
@@ -15158,7 +16987,7 @@ function parsePath(path2) {
15158
16987
  }
15159
16988
  return keys;
15160
16989
  }
15161
- function omitAtPath(obj, keys) {
16990
+ function omitAtPath(obj, keys, deleteLeaf = false) {
15162
16991
  if (keys.length === 0) return;
15163
16992
  const firstKey = keys[0];
15164
16993
  const remainingKeys = keys.slice(1);
@@ -15168,29 +16997,36 @@ function omitAtPath(obj, keys) {
15168
16997
  if (remainingKeys.length > 0) {
15169
16998
  omitAtPath(
15170
16999
  item,
15171
- remainingKeys
17000
+ remainingKeys,
17001
+ deleteLeaf
15172
17002
  );
15173
17003
  }
15174
17004
  });
15175
17005
  }
15176
17006
  } else if (remainingKeys.length === 0) {
15177
17007
  if (obj && typeof obj === "object" && firstKey in obj) {
15178
- obj[firstKey] = "<omitted>";
17008
+ if (deleteLeaf) {
17009
+ delete obj[firstKey];
17010
+ } else {
17011
+ obj[firstKey] = "<omitted>";
17012
+ }
15179
17013
  }
15180
17014
  } else {
15181
17015
  if (obj && typeof obj === "object" && firstKey in obj) {
15182
17016
  omitAtPath(
15183
17017
  obj[firstKey],
15184
- remainingKeys
17018
+ remainingKeys,
17019
+ deleteLeaf
15185
17020
  );
15186
17021
  }
15187
17022
  }
15188
17023
  }
15189
- function omit(obj, paths) {
17024
+ function omit(obj, paths, deletePaths = []) {
15190
17025
  const result = deepCopy(obj);
17026
+ const deletePathSet = new Set(deletePaths);
15191
17027
  for (const path2 of paths) {
15192
17028
  const keys = parsePath(path2);
15193
- omitAtPath(result, keys);
17029
+ omitAtPath(result, keys, deletePathSet.has(path2));
15194
17030
  }
15195
17031
  return result;
15196
17032
  }
@@ -25239,15 +27075,18 @@ function observeFlue(event, ctx) {
25239
27075
  getObserveBridge().handle(event, ctx);
25240
27076
  }
25241
27077
  var interceptFlueExecution = (operation, ctx, next) => getObserveBridge().intercept(operation, ctx, next);
25242
- var braintrustFlueObserver = Object.assign(
25243
- observeFlue,
25244
- {
27078
+ function braintrustFlueInstrumentation() {
27079
+ return {
25245
27080
  dispose() {
25246
27081
  },
25247
27082
  interceptor: interceptFlueExecution,
25248
27083
  key: FLUE_INSTRUMENTATION_KEY,
25249
27084
  observe: observeFlue
25250
- }
27085
+ };
27086
+ }
27087
+ var braintrustFlueObserver = Object.assign(
27088
+ observeFlue,
27089
+ braintrustFlueInstrumentation()
25251
27090
  );
25252
27091
  var FluePlugin = class extends BasePlugin {
25253
27092
  onEnable() {
@@ -30274,15 +32113,21 @@ async function invoke(args) {
30274
32113
 
30275
32114
  // src/trace.ts
30276
32115
  var SpanFetcher = class _SpanFetcher extends ObjectFetcher {
30277
- constructor(objectType, _objectId, rootSpanId, _state, spanTypeFilter, includeScorers = false) {
32116
+ constructor(objectType, _objectId, rootSpanId, _state, spanTypeFilter, includeScorers = false, brainstoreRealtime = true) {
30278
32117
  const filterExpr = _SpanFetcher.buildFilter(
30279
32118
  rootSpanId,
30280
32119
  spanTypeFilter,
30281
32120
  includeScorers
30282
32121
  );
30283
- super(objectType, void 0, void 0, {
30284
- filter: filterExpr
30285
- });
32122
+ super(
32123
+ objectType,
32124
+ void 0,
32125
+ void 0,
32126
+ {
32127
+ filter: filterExpr
32128
+ },
32129
+ brainstoreRealtime
32130
+ );
30286
32131
  this._objectId = _objectId;
30287
32132
  this.rootSpanId = rootSpanId;
30288
32133
  this._state = _state;
@@ -30336,7 +32181,7 @@ var CachedSpanFetcher = class {
30336
32181
  spanCache = /* @__PURE__ */ new Map();
30337
32182
  allFetched = false;
30338
32183
  fetchFn;
30339
- constructor(objectTypeOrFetchFn, objectId, rootSpanId, getState) {
32184
+ constructor(objectTypeOrFetchFn, objectId, rootSpanId, getState, brainstoreRealtime = true) {
30340
32185
  if (typeof objectTypeOrFetchFn === "function") {
30341
32186
  this.fetchFn = (spanType) => objectTypeOrFetchFn(spanType);
30342
32187
  } else {
@@ -30349,7 +32194,8 @@ var CachedSpanFetcher = class {
30349
32194
  rootSpanId,
30350
32195
  state,
30351
32196
  spanType,
30352
- includeScorers
32197
+ includeScorers,
32198
+ brainstoreRealtime
30353
32199
  );
30354
32200
  const rows = await fetcher.fetchedData();
30355
32201
  return rows.map((row) => ({
@@ -31157,7 +33003,7 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
31157
33003
  }
31158
33004
  };
31159
33005
  const parentStr = state.currentParent.getStore();
31160
- const parentComponents = parentStr ? SpanComponentsV3.fromStr(parentStr) : null;
33006
+ const parentComponents = typeof parentStr === "string" ? SpanComponentsV4.fromStr(parentStr) : null;
31161
33007
  const trace = state ? new LocalTrace({
31162
33008
  objectType: parentComponents ? spanObjectTypeV3ToTypedString(
31163
33009
  parentComponents.data.object_type
@@ -31817,7 +33663,7 @@ var MAIN_ORIGIN = "https://www.braintrust.dev";
31817
33663
  var WHITELISTED_ORIGINS = [
31818
33664
  MAIN_ORIGIN,
31819
33665
  "https://www.braintrustdata.com",
31820
- new RegExp("https://.*.preview.braintrust.dev")
33666
+ new RegExp("^https://[^/]+\\.preview\\.braintrust\\.dev$")
31821
33667
  ].concat(
31822
33668
  process.env.WHITELISTED_ORIGIN ? [process.env.WHITELISTED_ORIGIN] : []
31823
33669
  ).concat(