braintrust 3.20.0 → 3.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/NOTICE +20 -0
  2. package/README.md +2 -0
  3. package/dev/dist/index.d.mts +309 -199
  4. package/dev/dist/index.d.ts +309 -199
  5. package/dev/dist/index.js +2826 -983
  6. package/dev/dist/index.mjs +2286 -443
  7. package/dist/apply-auto-instrumentation.js +781 -199
  8. package/dist/apply-auto-instrumentation.mjs +588 -6
  9. package/dist/auto-instrumentations/bundler/esbuild.cjs +594 -2
  10. package/dist/auto-instrumentations/bundler/esbuild.d.mts +2 -2
  11. package/dist/auto-instrumentations/bundler/esbuild.d.ts +2 -2
  12. package/dist/auto-instrumentations/bundler/esbuild.mjs +3 -3
  13. package/dist/auto-instrumentations/bundler/next.cjs +594 -2
  14. package/dist/auto-instrumentations/bundler/next.mjs +4 -4
  15. package/dist/auto-instrumentations/bundler/rollup.cjs +594 -2
  16. package/dist/auto-instrumentations/bundler/rollup.d.mts +2 -2
  17. package/dist/auto-instrumentations/bundler/rollup.d.ts +2 -2
  18. package/dist/auto-instrumentations/bundler/rollup.mjs +3 -3
  19. package/dist/auto-instrumentations/bundler/vite.cjs +594 -2
  20. package/dist/auto-instrumentations/bundler/vite.d.mts +2 -2
  21. package/dist/auto-instrumentations/bundler/vite.d.ts +2 -2
  22. package/dist/auto-instrumentations/bundler/vite.mjs +3 -3
  23. package/dist/auto-instrumentations/bundler/webpack-loader.cjs +593 -9
  24. package/dist/auto-instrumentations/bundler/webpack-loader.d.ts +68 -1
  25. package/dist/auto-instrumentations/bundler/webpack.cjs +594 -2
  26. package/dist/auto-instrumentations/bundler/webpack.d.mts +2 -2
  27. package/dist/auto-instrumentations/bundler/webpack.d.ts +2 -2
  28. package/dist/auto-instrumentations/bundler/webpack.mjs +4 -4
  29. package/dist/auto-instrumentations/{chunk-W4E36GIW.mjs → chunk-BRQX23KL.mjs} +16 -0
  30. package/dist/auto-instrumentations/chunk-M6DLIJ2Z.mjs +784 -0
  31. package/dist/auto-instrumentations/{chunk-K74TZGGM.mjs → chunk-T6J4C7LX.mjs} +1 -1
  32. package/dist/auto-instrumentations/{chunk-S4374IP6.mjs → chunk-TKRPRPGD.mjs} +4 -6
  33. package/dist/auto-instrumentations/chunk-VT6DDNKM.mjs +856 -0
  34. package/dist/auto-instrumentations/hook.mjs +749 -45
  35. package/dist/auto-instrumentations/index.cjs +16 -0
  36. package/dist/auto-instrumentations/index.d.mts +2 -3
  37. package/dist/auto-instrumentations/index.d.ts +2 -3
  38. package/dist/auto-instrumentations/index.mjs +1 -1
  39. package/dist/auto-instrumentations/loader/cjs-patch.cjs +578 -4
  40. package/dist/auto-instrumentations/loader/cjs-patch.d.mts +1 -1
  41. package/dist/auto-instrumentations/loader/cjs-patch.d.ts +1 -1
  42. package/dist/auto-instrumentations/loader/cjs-patch.mjs +3 -7
  43. package/dist/auto-instrumentations/loader/esm-hook.mjs +2 -6
  44. package/dist/auto-instrumentations/{plugin-D7nDswtC.d.mts → plugin-D0KHwSJv.d.mts} +1 -1
  45. package/dist/auto-instrumentations/{plugin-D7nDswtC.d.ts → plugin-G6fgxk1b.d.ts} +1 -1
  46. package/dist/auto-instrumentations/types-RNPaKi9o.d.mts +70 -0
  47. package/dist/auto-instrumentations/types-RNPaKi9o.d.ts +70 -0
  48. package/dist/browser.d.mts +1357 -847
  49. package/dist/browser.d.ts +1357 -847
  50. package/dist/browser.js +2726 -469
  51. package/dist/browser.mjs +2726 -469
  52. package/dist/{chunk-LPC4W2WX.js → chunk-BFGIH2ZJ.js} +4 -0
  53. package/dist/{chunk-POCCIJAL.js → chunk-FY7DAKA5.js} +3141 -1269
  54. package/dist/{chunk-Y7W7WP6H.mjs → chunk-KMGUTPB7.mjs} +4 -0
  55. package/dist/{chunk-F73OMF66.mjs → chunk-O2P765XK.mjs} +2391 -519
  56. package/dist/cli.js +2260 -408
  57. package/dist/edge-light.d.mts +1 -1
  58. package/dist/edge-light.d.ts +1 -1
  59. package/dist/edge-light.js +2726 -469
  60. package/dist/edge-light.mjs +2726 -469
  61. package/dist/index.d.mts +1837 -1327
  62. package/dist/index.d.ts +1837 -1327
  63. package/dist/index.js +752 -353
  64. package/dist/index.mjs +445 -46
  65. package/dist/instrumentation/index.d.mts +107 -19
  66. package/dist/instrumentation/index.d.ts +107 -19
  67. package/dist/instrumentation/index.js +2337 -509
  68. package/dist/instrumentation/index.mjs +2337 -509
  69. package/dist/vitest-evals-reporter.js +16 -16
  70. package/dist/vitest-evals-reporter.mjs +2 -2
  71. package/dist/workerd.d.mts +1 -1
  72. package/dist/workerd.d.ts +1 -1
  73. package/dist/workerd.js +2726 -469
  74. package/dist/workerd.mjs +2726 -469
  75. package/licenses/import-in-the-middle/LICENSE +201 -0
  76. package/licenses/import-in-the-middle/LICENSE-3rdparty.csv +4 -0
  77. package/licenses/import-in-the-middle/NOTICE +34 -0
  78. package/licenses/orchestrion-js/LICENSE +202 -0
  79. package/licenses/orchestrion-js/LICENSE-3rdparty.csv +8 -0
  80. package/licenses/orchestrion-js/NOTICE +3 -0
  81. package/licenses/require-in-the-middle/LICENSE +23 -0
  82. package/package.json +13 -4
  83. package/util/dist/index.d.mts +1 -0
  84. package/util/dist/index.d.ts +1 -0
  85. package/util/dist/index.js +4 -4
  86. package/util/dist/index.mjs +2 -2
  87. package/dist/auto-instrumentations/chunk-J57YF7WS.mjs +0 -208
  88. package/dist/auto-instrumentations/chunk-QFMACSOL.mjs +0 -280
@@ -30,10 +30,121 @@ import {
30
30
  smithyClientChannels,
31
31
  smithyCoreChannels,
32
32
  strandsAgentSDKChannels
33
- } from "./chunk-Y7W7WP6H.mjs";
33
+ } from "./chunk-KMGUTPB7.mjs";
34
34
 
35
35
  // src/id-gen.ts
36
36
  import { v4 as uuidv4 } from "uuid";
37
+
38
+ // src/debug-logger.ts
39
+ var PREFIX = "[braintrust]";
40
+ var DEBUG_LOG_LEVEL_SYMBOL = /* @__PURE__ */ Symbol.for("braintrust-debug-log-level");
41
+ var LOG_LEVEL_PRIORITY = {
42
+ error: 0,
43
+ warn: 1,
44
+ info: 2,
45
+ debug: 3
46
+ };
47
+ var hasWarnedAboutInvalidEnvValue = false;
48
+ var debugLogStateResolver = void 0;
49
+ function warnInvalidEnvValue(value) {
50
+ if (hasWarnedAboutInvalidEnvValue) {
51
+ return;
52
+ }
53
+ hasWarnedAboutInvalidEnvValue = true;
54
+ console.warn(
55
+ PREFIX,
56
+ `Invalid BRAINTRUST_DEBUG_LOG_LEVEL value "${value}". Expected "error", "warn", "info", or "debug".`
57
+ );
58
+ }
59
+ function normalizeDebugLogLevelOption(option) {
60
+ if (option === false) {
61
+ return void 0;
62
+ }
63
+ if (option === "error" || option === "warn" || option === "info" || option === "debug") {
64
+ return option;
65
+ }
66
+ throw new Error(
67
+ `Invalid debugLogLevel value "${option}". Expected false, "error", "warn", "info", or "debug".`
68
+ );
69
+ }
70
+ function parseDebugLogLevelEnv(value) {
71
+ if (!value) {
72
+ return void 0;
73
+ }
74
+ if (value === "error" || value === "warn" || value === "info" || value === "debug") {
75
+ return value;
76
+ }
77
+ warnInvalidEnvValue(value);
78
+ return void 0;
79
+ }
80
+ function getEnvDebugLogLevel() {
81
+ return parseDebugLogLevelEnv(isomorph_default.getEnv("BRAINTRUST_DEBUG_LOG_LEVEL"));
82
+ }
83
+ function setGlobalDebugLogLevel(level) {
84
+ globalThis[DEBUG_LOG_LEVEL_SYMBOL] = level;
85
+ }
86
+ function resetDebugLoggerForTests() {
87
+ hasWarnedAboutInvalidEnvValue = false;
88
+ setGlobalDebugLogLevel(void 0);
89
+ }
90
+ function setDebugLogStateResolver(resolver) {
91
+ debugLogStateResolver = resolver;
92
+ }
93
+ function resolveDebugLogLevel(state) {
94
+ const stateLevel = state?.getDebugLogLevel?.();
95
+ const hasStateOverride = state?.hasDebugLogLevelOverride?.() ?? false;
96
+ if (hasStateOverride) {
97
+ return stateLevel;
98
+ }
99
+ const globalLevel = (
100
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
101
+ globalThis[DEBUG_LOG_LEVEL_SYMBOL]
102
+ );
103
+ if (globalLevel !== void 0) {
104
+ return globalLevel === false ? void 0 : globalLevel;
105
+ }
106
+ return getEnvDebugLogLevel();
107
+ }
108
+ function emit(method, state, args) {
109
+ const level = resolveDebugLogLevel(state);
110
+ if (!level || LOG_LEVEL_PRIORITY[method] > LOG_LEVEL_PRIORITY[level]) {
111
+ return;
112
+ }
113
+ if (method === "info") {
114
+ console.log(PREFIX, ...args);
115
+ } else if (method === "debug") {
116
+ console.debug(PREFIX, ...args);
117
+ } else if (method === "warn") {
118
+ console.warn(PREFIX, ...args);
119
+ } else {
120
+ console.error(PREFIX, ...args);
121
+ }
122
+ }
123
+ function createDebugLogger(state) {
124
+ const resolveState = () => state ?? debugLogStateResolver?.();
125
+ return {
126
+ info(...args) {
127
+ emit("info", resolveState(), args);
128
+ },
129
+ debug(...args) {
130
+ emit("debug", resolveState(), args);
131
+ },
132
+ warn(...args) {
133
+ emit("warn", resolveState(), args);
134
+ },
135
+ error(...args) {
136
+ emit("error", resolveState(), args);
137
+ }
138
+ };
139
+ }
140
+ var debugLogger = {
141
+ ...createDebugLogger(),
142
+ forState(state) {
143
+ return createDebugLogger(state);
144
+ }
145
+ };
146
+
147
+ // src/id-gen.ts
37
148
  var IDGenerator = class {
38
149
  };
39
150
  var UUIDGenerator = class extends IDGenerator {
@@ -47,8 +158,291 @@ var UUIDGenerator = class extends IDGenerator {
47
158
  return true;
48
159
  }
49
160
  };
161
+ function generateHexId(bytes) {
162
+ let result = "";
163
+ for (let i = 0; i < bytes; i++) {
164
+ result += Math.floor(Math.random() * 256).toString(16).padStart(2, "0");
165
+ }
166
+ return result;
167
+ }
168
+ var OTELIDGenerator = class extends IDGenerator {
169
+ getSpanId() {
170
+ return generateHexId(8);
171
+ }
172
+ getTraceId() {
173
+ return generateHexId(16);
174
+ }
175
+ shareRootSpanId() {
176
+ return false;
177
+ }
178
+ };
179
+ function parseEnvBool(name) {
180
+ const raw = isomorph_default.getEnv(name);
181
+ if (raw === void 0 || raw === null) {
182
+ return false;
183
+ }
184
+ const normalized = raw.trim().toLowerCase();
185
+ return normalized === "true" || normalized === "1" || normalized === "yes" || normalized === "y" || normalized === "on";
186
+ }
187
+ var _warnedLegacyUuidConflict = false;
188
+ function resolveUseLegacyUuidIds() {
189
+ const legacy = parseEnvBool("BRAINTRUST_LEGACY_IDS");
190
+ if (parseEnvBool("BRAINTRUST_OTEL_COMPAT")) {
191
+ if (legacy && !_warnedLegacyUuidConflict) {
192
+ _warnedLegacyUuidConflict = true;
193
+ debugLogger.warn(
194
+ "BRAINTRUST_LEGACY_IDS is ignored because BRAINTRUST_OTEL_COMPAT requires OpenTelemetry-compatible hex span IDs. Using hex IDs."
195
+ );
196
+ }
197
+ return false;
198
+ }
199
+ return legacy;
200
+ }
50
201
  function getIdGenerator() {
51
- return globalThis.BRAINTRUST_ID_GENERATOR !== void 0 ? new globalThis.BRAINTRUST_ID_GENERATOR() : new UUIDGenerator();
202
+ if (globalThis.BRAINTRUST_ID_GENERATOR !== void 0) {
203
+ return new globalThis.BRAINTRUST_ID_GENERATOR();
204
+ }
205
+ return resolveUseLegacyUuidIds() ? new UUIDGenerator() : new OTELIDGenerator();
206
+ }
207
+
208
+ // src/propagation.ts
209
+ var TRACEPARENT_HEADER = "traceparent";
210
+ var TRACESTATE_HEADER = "tracestate";
211
+ var BAGGAGE_HEADER = "baggage";
212
+ var BRAINTRUST_PARENT_KEY = "braintrust.parent";
213
+ var DEFAULT_TRACE_FLAGS = "01";
214
+ var TRACEPARENT_RE = /^00-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/;
215
+ var ZERO_TRACE_ID = "0".repeat(32);
216
+ var ZERO_SPAN_ID = "0".repeat(16);
217
+ var MAX_BAGGAGE_LENGTH = 8192;
218
+ var MAX_BAGGAGE_MEMBERS = 64;
219
+ var _utf8Encoder = new TextEncoder();
220
+ function utf8ByteLength(value) {
221
+ return _utf8Encoder.encode(value).length;
222
+ }
223
+ function capBaggageToMemberBoundary(value) {
224
+ const totalBytes = utf8ByteLength(value);
225
+ const withinBytes = totalBytes <= MAX_BAGGAGE_LENGTH;
226
+ let commaCount = 0;
227
+ for (let i = 0; i < value.length; i++) {
228
+ if (value.charCodeAt(i) === 44) {
229
+ commaCount++;
230
+ }
231
+ }
232
+ const withinMembers = commaCount < MAX_BAGGAGE_MEMBERS;
233
+ if (withinBytes && withinMembers) {
234
+ return value;
235
+ }
236
+ const kept = [];
237
+ let length = 0;
238
+ for (const rawMember of value.split(",")) {
239
+ if (kept.length >= MAX_BAGGAGE_MEMBERS) {
240
+ break;
241
+ }
242
+ const cost = utf8ByteLength(rawMember) + (kept.length ? 1 : 0);
243
+ if (length + cost > MAX_BAGGAGE_LENGTH) {
244
+ break;
245
+ }
246
+ kept.push(rawMember);
247
+ length += cost;
248
+ }
249
+ if (!kept.length) {
250
+ return "";
251
+ }
252
+ return kept.join(",");
253
+ }
254
+ function isTraceContextHeaderTupleArray(value) {
255
+ return Array.isArray(value) && value.every(
256
+ (item) => Array.isArray(item) && typeof item[0] === "string" && typeof item[1] === "string"
257
+ );
258
+ }
259
+ function isListHeader(name) {
260
+ const lowered = name.toLowerCase();
261
+ return lowered === BAGGAGE_HEADER || lowered === TRACESTATE_HEADER;
262
+ }
263
+ function headerValueToString(value, name) {
264
+ if (value === void 0 || value === null) {
265
+ return void 0;
266
+ }
267
+ if (Array.isArray(value)) {
268
+ const stringValues = value.filter((item) => {
269
+ return typeof item === "string";
270
+ });
271
+ if (!stringValues.length) {
272
+ return void 0;
273
+ }
274
+ return isListHeader(name) ? stringValues.join(",") : stringValues[0];
275
+ }
276
+ return typeof value === "string" ? value : String(value);
277
+ }
278
+ function getHeader(headers, name) {
279
+ if (!headers) {
280
+ return void 0;
281
+ }
282
+ if (isTraceContextHeaderTupleArray(headers)) {
283
+ const lowered2 = name.toLowerCase();
284
+ const matches = headers.filter(([key]) => key.toLowerCase() === lowered2).map(([, value]) => value);
285
+ if (!matches.length) {
286
+ return void 0;
287
+ }
288
+ return headerValueToString(matches, name);
289
+ }
290
+ const getter = headers.get;
291
+ if (typeof getter === "function") {
292
+ try {
293
+ const value = headerValueToString(getter.call(headers, name), name);
294
+ if (value !== void 0) {
295
+ return value;
296
+ }
297
+ } catch {
298
+ }
299
+ }
300
+ const nodeGetter = headers.getHeader;
301
+ if (typeof nodeGetter === "function") {
302
+ try {
303
+ const value = headerValueToString(nodeGetter.call(headers, name), name);
304
+ if (value !== void 0) {
305
+ return value;
306
+ }
307
+ } catch {
308
+ }
309
+ }
310
+ const headerBag = headers;
311
+ const exact = headerValueToString(headerBag[name], name);
312
+ if (exact !== void 0) {
313
+ return exact;
314
+ }
315
+ const lowered = name.toLowerCase();
316
+ for (const key of Object.keys(headers)) {
317
+ if (key !== name && key.toLowerCase() === lowered) {
318
+ const value = headerValueToString(headerBag[key], name);
319
+ if (value !== void 0) {
320
+ return value;
321
+ }
322
+ }
323
+ }
324
+ return void 0;
325
+ }
326
+ function isHex(value, length) {
327
+ if (typeof value !== "string" || value.length !== length) {
328
+ return false;
329
+ }
330
+ for (let i = 0; i < value.length; i++) {
331
+ const c = value[i];
332
+ const isDigit = c >= "0" && c <= "9";
333
+ const isLowerHex = c >= "a" && c <= "f";
334
+ if (!isDigit && !isLowerHex) {
335
+ return false;
336
+ }
337
+ }
338
+ return true;
339
+ }
340
+ function parseTraceparent(value) {
341
+ if (!value || typeof value !== "string") {
342
+ return void 0;
343
+ }
344
+ const match = TRACEPARENT_RE.exec(value.trim());
345
+ if (!match) {
346
+ return void 0;
347
+ }
348
+ const traceId = match[1];
349
+ const spanId = match[2];
350
+ const traceFlags = match[3];
351
+ if (traceId === ZERO_TRACE_ID || spanId === ZERO_SPAN_ID) {
352
+ return void 0;
353
+ }
354
+ return { traceId, spanId, traceFlags };
355
+ }
356
+ function formatTraceparent(traceId, spanId, traceFlags = DEFAULT_TRACE_FLAGS) {
357
+ if (!isHex(traceId, 32) || traceId === ZERO_TRACE_ID) {
358
+ return void 0;
359
+ }
360
+ if (!isHex(spanId, 16) || spanId === ZERO_SPAN_ID) {
361
+ return void 0;
362
+ }
363
+ const flags = isHex(traceFlags, 2) ? traceFlags : DEFAULT_TRACE_FLAGS;
364
+ return `00-${traceId}-${spanId}-${flags}`;
365
+ }
366
+ function percentEncode(value) {
367
+ return encodeURIComponent(value);
368
+ }
369
+ function percentDecode(value) {
370
+ if (!value.includes("%")) {
371
+ return value;
372
+ }
373
+ try {
374
+ return decodeURIComponent(value);
375
+ } catch {
376
+ return value;
377
+ }
378
+ }
379
+ function parseBaggage(value) {
380
+ const result = {};
381
+ if (!value || typeof value !== "string") {
382
+ return result;
383
+ }
384
+ const bounded = capBaggageToMemberBoundary(value);
385
+ for (let member of bounded.split(",")) {
386
+ member = member.trim();
387
+ if (!member || !member.includes("=")) {
388
+ continue;
389
+ }
390
+ member = member.split(";", 1)[0];
391
+ const eq = member.indexOf("=");
392
+ const key = percentDecode(member.slice(0, eq).trim());
393
+ const val = member.slice(eq + 1).trim();
394
+ if (!key) {
395
+ continue;
396
+ }
397
+ result[key] = percentDecode(val);
398
+ }
399
+ return result;
400
+ }
401
+ function mergeBaggage(existing, braintrustParent) {
402
+ let btMember = void 0;
403
+ if (braintrustParent) {
404
+ const encodedKey = percentEncode(BRAINTRUST_PARENT_KEY);
405
+ const encodedVal = percentEncode(String(braintrustParent));
406
+ btMember = `${encodedKey}=${encodedVal}`;
407
+ if (utf8ByteLength(btMember) > MAX_BAGGAGE_LENGTH) {
408
+ btMember = void 0;
409
+ }
410
+ }
411
+ let byteBudget = MAX_BAGGAGE_LENGTH;
412
+ let memberBudget = MAX_BAGGAGE_MEMBERS;
413
+ if (btMember !== void 0) {
414
+ byteBudget -= utf8ByteLength(btMember) + 1;
415
+ memberBudget -= 1;
416
+ }
417
+ const relayed = [];
418
+ let length = 0;
419
+ if (existing && typeof existing === "string") {
420
+ for (const rawMember of existing.split(",")) {
421
+ const member = rawMember.trim();
422
+ if (!member || !member.includes("=")) {
423
+ continue;
424
+ }
425
+ const keyPart = member.split(";", 1)[0].split("=", 1)[0];
426
+ const key = percentDecode(keyPart.trim());
427
+ if (key === BRAINTRUST_PARENT_KEY) {
428
+ continue;
429
+ }
430
+ if (relayed.length >= memberBudget) {
431
+ break;
432
+ }
433
+ const cost = utf8ByteLength(member) + (relayed.length ? 1 : 0);
434
+ if (length + cost > byteBudget) {
435
+ break;
436
+ }
437
+ relayed.push(member);
438
+ length += cost;
439
+ }
440
+ }
441
+ const members = btMember !== void 0 ? [...relayed, btMember] : relayed;
442
+ if (!members.length) {
443
+ return void 0;
444
+ }
445
+ return members.join(",");
52
446
  }
53
447
 
54
448
  // util/type_util.ts
@@ -670,7 +1064,7 @@ var SpanComponentsV3 = class _SpanComponentsV3 {
670
1064
  case 3 /* PLAYGROUND_LOGS */:
671
1065
  return { prompt_session_id: this.data.object_id, log_id: "x" };
672
1066
  default:
673
- const _ = this.data.object_type;
1067
+ this.data.object_type;
674
1068
  throw new Error("Impossible");
675
1069
  }
676
1070
  }
@@ -1185,7 +1579,7 @@ var SpanComponentsV4 = class _SpanComponentsV4 {
1185
1579
  case 3 /* PLAYGROUND_LOGS */:
1186
1580
  return { prompt_session_id: this.data.object_id, log_id: "x" };
1187
1581
  default:
1188
- const _ = this.data.object_type;
1582
+ this.data.object_type;
1189
1583
  throw new Error(`Invalid object_type ${this.data.object_type}`);
1190
1584
  }
1191
1585
  }
@@ -1364,7 +1758,8 @@ var AclObjectType = z6.union([
1364
1758
  "role",
1365
1759
  "org_member",
1366
1760
  "project_log",
1367
- "org_project"
1761
+ "org_project",
1762
+ "org_audit_logs"
1368
1763
  ]),
1369
1764
  z6.null()
1370
1765
  ]);
@@ -1390,6 +1785,17 @@ var Acl = z6.object({
1390
1785
  _object_org_id: z6.string().uuid(),
1391
1786
  created: z6.union([z6.string(), z6.null()]).optional()
1392
1787
  });
1788
+ var Agent = z6.object({
1789
+ id: z6.string().uuid(),
1790
+ project_id: z6.string().uuid(),
1791
+ user_id: z6.string().uuid(),
1792
+ created: z6.union([z6.string(), z6.null()]).optional(),
1793
+ name: z6.string(),
1794
+ slug: z6.string(),
1795
+ kind: z6.string(),
1796
+ description: z6.union([z6.string(), z6.null()]).optional(),
1797
+ metadata: z6.union([z6.object({}).partial().passthrough(), z6.null()]).optional()
1798
+ });
1393
1799
  var AISecret = z6.object({
1394
1800
  id: z6.string().uuid(),
1395
1801
  created: z6.union([z6.string(), z6.null()]).optional(),
@@ -1536,6 +1942,7 @@ var AttachmentStatus = z6.object({
1536
1942
  upload_status: UploadStatus,
1537
1943
  error_message: z6.string().optional()
1538
1944
  });
1945
+ var AutomationStatus = z6.enum(["active", "paused"]);
1539
1946
  var FunctionTypeEnum = z6.enum([
1540
1947
  "llm",
1541
1948
  "scorer",
@@ -1581,7 +1988,9 @@ var TopicMapData = z6.object({
1581
1988
  topic_names: z6.record(z6.string()).optional(),
1582
1989
  generation_settings: TopicMapGenerationSettings.optional(),
1583
1990
  disable_reconciliation: z6.boolean().optional(),
1584
- distance_threshold: z6.number().optional()
1991
+ distance_threshold: z6.number().optional(),
1992
+ btql_filter: z6.string().optional(),
1993
+ automation_btql_filter: z6.string().optional()
1585
1994
  });
1586
1995
  var BatchedFacetData = z6.object({
1587
1996
  type: z6.literal("batched_facet"),
@@ -1864,7 +2273,7 @@ var DatasetEvent = z6.object({
1864
2273
  origin: ObjectReferenceNullish.optional(),
1865
2274
  comments: z6.union([z6.array(z6.unknown()), z6.null()]).optional(),
1866
2275
  audit_data: z6.union([z6.array(z6.unknown()), z6.null()]).optional(),
1867
- facets: z6.union([z6.object({}).partial().passthrough(), z6.null()]).optional(),
2276
+ facets: z6.union([z6.record(z6.union([z6.string(), z6.null()])), z6.null()]).optional(),
1868
2277
  classifications: z6.union([
1869
2278
  z6.record(
1870
2279
  z6.array(
@@ -2016,7 +2425,7 @@ var ExperimentEvent = z6.object({
2016
2425
  origin: ObjectReferenceNullish.optional(),
2017
2426
  comments: z6.union([z6.array(z6.unknown()), z6.null()]).optional(),
2018
2427
  audit_data: z6.union([z6.array(z6.unknown()), z6.null()]).optional(),
2019
- facets: z6.union([z6.object({}).partial().passthrough(), z6.null()]).optional(),
2428
+ facets: z6.union([z6.record(z6.union([z6.string(), z6.null()])), z6.null()]).optional(),
2020
2429
  classifications: z6.union([
2021
2430
  z6.record(
2022
2431
  z6.array(
@@ -2154,7 +2563,8 @@ var PromptParserNullish = z6.union([
2154
2563
  use_cot: z6.boolean(),
2155
2564
  choice_scores: z6.record(z6.number().gte(0).lte(1)).optional(),
2156
2565
  choice: z6.array(z6.string()).optional(),
2157
- allow_no_match: z6.boolean().optional()
2566
+ allow_no_match: z6.boolean().optional(),
2567
+ allow_skip: z6.boolean().optional()
2158
2568
  }),
2159
2569
  z6.null()
2160
2570
  ]);
@@ -2484,6 +2894,9 @@ var Group = z6.object({
2484
2894
  var GroupScope = z6.object({
2485
2895
  type: z6.literal("group"),
2486
2896
  group_by: z6.string(),
2897
+ interval_seconds: z6.number().gte(1).optional(),
2898
+ max_traces: z6.number().int().gte(1).lte(64).optional(),
2899
+ placement: z6.enum(["first", "each"]),
2487
2900
  idle_seconds: z6.number().optional()
2488
2901
  });
2489
2902
  var IfExists = z6.enum(["error", "ignore", "replace"]);
@@ -2632,6 +3045,10 @@ var RetentionObjectType = z6.enum([
2632
3045
  "experiment",
2633
3046
  "dataset"
2634
3047
  ]);
3048
+ var TopicAutomationFacetModel = z6.union([
3049
+ z6.enum(["brain-facet-latest", "brain-facet-1", "brain-facet-2"]),
3050
+ z6.null()
3051
+ ]);
2635
3052
  var TopicMapFunctionAutomation = z6.object({
2636
3053
  function: SavedFunctionId.and(z6.unknown()),
2637
3054
  btql_filter: z6.union([z6.string(), z6.null()]).optional()
@@ -2644,7 +3061,9 @@ var TopicAutomationDataScope = z6.union([
2644
3061
  ]);
2645
3062
  var TopicAutomationConfig = z6.object({
2646
3063
  event_type: z6.literal("topic"),
3064
+ status: AutomationStatus.optional(),
2647
3065
  sampling_rate: z6.number().gte(0).lte(1),
3066
+ facet_model: TopicAutomationFacetModel.optional(),
2648
3067
  facet_functions: z6.array(SavedFunctionId),
2649
3068
  topic_map_functions: z6.array(TopicMapFunctionAutomation),
2650
3069
  scope: z6.union([SpanScope, TraceScope, GroupScope, z6.null()]).optional(),
@@ -2658,6 +3077,19 @@ var TopicAutomationConfig = z6.object({
2658
3077
  z6.null()
2659
3078
  ]).optional()
2660
3079
  });
3080
+ var TopicDigestAutomationConfig = z6.object({
3081
+ event_type: z6.literal("topic_digest"),
3082
+ status: AutomationStatus.optional(),
3083
+ window_seconds: z6.number().int().gte(3600).lte(2592e3).optional().default(86400),
3084
+ scheduled_time_minutes_utc: z6.number().int().gte(0).lte(1439),
3085
+ action: z6.object({
3086
+ type: z6.literal("slack"),
3087
+ workspace_id: z6.string(),
3088
+ channel: z6.string(),
3089
+ message_template: z6.string().optional()
3090
+ }),
3091
+ topic_map_function_ids: z6.array(z6.string()).max(10).optional()
3092
+ });
2661
3093
  var ProjectAutomation = z6.object({
2662
3094
  id: z6.string().uuid(),
2663
3095
  project_id: z6.string().uuid(),
@@ -2682,6 +3114,7 @@ var ProjectAutomation = z6.object({
2682
3114
  }),
2683
3115
  z6.object({
2684
3116
  event_type: z6.literal("btql_export"),
3117
+ status: AutomationStatus.optional(),
2685
3118
  export_definition: z6.union([
2686
3119
  z6.object({ type: z6.literal("log_traces") }),
2687
3120
  z6.object({ type: z6.literal("log_spans") }),
@@ -2704,6 +3137,21 @@ var ProjectAutomation = z6.object({
2704
3137
  ]),
2705
3138
  batch_size: z6.union([z6.number(), z6.null()]).optional()
2706
3139
  }),
3140
+ z6.object({
3141
+ event_type: z6.literal("async_query"),
3142
+ status: AutomationStatus.optional(),
3143
+ created_by_user_id: z6.string().uuid(),
3144
+ object_type: z6.enum([
3145
+ "project_logs",
3146
+ "experiment",
3147
+ "dataset",
3148
+ "playground_logs"
3149
+ ]),
3150
+ object_id: z6.string(),
3151
+ query: z6.string(),
3152
+ format: z6.literal("jsonl"),
3153
+ batch_size: z6.union([z6.number(), z6.null()]).optional()
3154
+ }),
2707
3155
  z6.object({
2708
3156
  event_type: z6.literal("retention"),
2709
3157
  object_type: RetentionObjectType,
@@ -2722,7 +3170,8 @@ var ProjectAutomation = z6.object({
2722
3170
  })
2723
3171
  ])
2724
3172
  }),
2725
- TopicAutomationConfig
3173
+ TopicAutomationConfig,
3174
+ TopicDigestAutomationConfig
2726
3175
  ])
2727
3176
  });
2728
3177
  var ProjectLogsEvent = z6.object({
@@ -2761,7 +3210,7 @@ var ProjectLogsEvent = z6.object({
2761
3210
  comments: z6.union([z6.array(z6.unknown()), z6.null()]).optional(),
2762
3211
  audit_data: z6.union([z6.array(z6.unknown()), z6.null()]).optional(),
2763
3212
  _async_scoring_state: z6.unknown().optional(),
2764
- facets: z6.union([z6.object({}).partial().passthrough(), z6.null()]).optional(),
3213
+ facets: z6.union([z6.record(z6.union([z6.string(), z6.null()])), z6.null()]).optional(),
2765
3214
  classifications: z6.union([
2766
3215
  z6.record(
2767
3216
  z6.array(
@@ -2810,16 +3259,39 @@ var ProjectScoreCategories = z6.union([
2810
3259
  z6.array(z6.string()),
2811
3260
  z6.null()
2812
3261
  ]);
3262
+ var ProjectScoreCondition = z6.union([
3263
+ z6.object({
3264
+ when: z6.object({
3265
+ clauses: z6.union([z6.array(z6.string()), z6.null()]),
3266
+ subspan_clauses: z6.union([z6.array(z6.string()), z6.null()]),
3267
+ trace_clauses: z6.union([z6.array(z6.string()), z6.null()])
3268
+ }).partial(),
3269
+ behavior: z6.literal("hidden").optional().default("hidden")
3270
+ }),
3271
+ z6.null()
3272
+ ]);
2813
3273
  var ProjectScoreConfig = z6.union([
2814
3274
  z6.object({
2815
3275
  multi_select: z6.union([z6.boolean(), z6.null()]),
2816
3276
  destination: z6.union([z6.string(), z6.null()]),
2817
- online: OnlineScoreConfig
2818
- }).partial(),
2819
- z6.null()
2820
- ]);
2821
- var ProjectScore = z6.object({
2822
- id: z6.string().uuid(),
3277
+ visibility: z6.union([
3278
+ z6.object({
3279
+ users: z6.union([z6.array(z6.string()), z6.null()]),
3280
+ groups: z6.union([z6.array(z6.string()), z6.null()])
3281
+ }).partial(),
3282
+ z6.null()
3283
+ ]),
3284
+ online: OnlineScoreConfig,
3285
+ condition: ProjectScoreCondition,
3286
+ object_types: z6.union([
3287
+ z6.array(z6.enum(["project_logs", "dataset", "experiment"])),
3288
+ z6.null()
3289
+ ])
3290
+ }).partial(),
3291
+ z6.null()
3292
+ ]);
3293
+ var ProjectScore = z6.object({
3294
+ id: z6.string().uuid(),
2823
3295
  project_id: z6.string().uuid(),
2824
3296
  user_id: z6.string().uuid(),
2825
3297
  created: z6.union([z6.string(), z6.null()]).optional(),
@@ -2999,8 +3471,7 @@ var User = z6.object({
2999
3471
  family_name: z6.union([z6.string(), z6.null()]).optional(),
3000
3472
  email: z6.union([z6.string(), z6.null()]).optional(),
3001
3473
  avatar_url: z6.union([z6.string(), z6.null()]).optional(),
3002
- created: z6.union([z6.string(), z6.null()]).optional(),
3003
- last_active_at: z6.union([z6.number(), z6.null()]).optional()
3474
+ created: z6.union([z6.string(), z6.null()]).optional()
3004
3475
  });
3005
3476
  var ViewDataSearch = z6.union([
3006
3477
  z6.object({
@@ -3553,115 +4024,6 @@ function devNullWritableStream() {
3553
4024
  // src/logger.ts
3554
4025
  import { v4 as uuidv42 } from "uuid";
3555
4026
 
3556
- // src/debug-logger.ts
3557
- var PREFIX = "[braintrust]";
3558
- var DEBUG_LOG_LEVEL_SYMBOL = /* @__PURE__ */ Symbol.for("braintrust-debug-log-level");
3559
- var LOG_LEVEL_PRIORITY = {
3560
- error: 0,
3561
- warn: 1,
3562
- info: 2,
3563
- debug: 3
3564
- };
3565
- var hasWarnedAboutInvalidEnvValue = false;
3566
- var debugLogStateResolver = void 0;
3567
- function warnInvalidEnvValue(value) {
3568
- if (hasWarnedAboutInvalidEnvValue) {
3569
- return;
3570
- }
3571
- hasWarnedAboutInvalidEnvValue = true;
3572
- console.warn(
3573
- PREFIX,
3574
- `Invalid BRAINTRUST_DEBUG_LOG_LEVEL value "${value}". Expected "error", "warn", "info", or "debug".`
3575
- );
3576
- }
3577
- function normalizeDebugLogLevelOption(option) {
3578
- if (option === false) {
3579
- return void 0;
3580
- }
3581
- if (option === "error" || option === "warn" || option === "info" || option === "debug") {
3582
- return option;
3583
- }
3584
- throw new Error(
3585
- `Invalid debugLogLevel value "${option}". Expected false, "error", "warn", "info", or "debug".`
3586
- );
3587
- }
3588
- function parseDebugLogLevelEnv(value) {
3589
- if (!value) {
3590
- return void 0;
3591
- }
3592
- if (value === "error" || value === "warn" || value === "info" || value === "debug") {
3593
- return value;
3594
- }
3595
- warnInvalidEnvValue(value);
3596
- return void 0;
3597
- }
3598
- function getEnvDebugLogLevel() {
3599
- return parseDebugLogLevelEnv(isomorph_default.getEnv("BRAINTRUST_DEBUG_LOG_LEVEL"));
3600
- }
3601
- function setGlobalDebugLogLevel(level) {
3602
- globalThis[DEBUG_LOG_LEVEL_SYMBOL] = level;
3603
- }
3604
- function resetDebugLoggerForTests() {
3605
- hasWarnedAboutInvalidEnvValue = false;
3606
- setGlobalDebugLogLevel(void 0);
3607
- }
3608
- function setDebugLogStateResolver(resolver) {
3609
- debugLogStateResolver = resolver;
3610
- }
3611
- function resolveDebugLogLevel(state) {
3612
- const stateLevel = state?.getDebugLogLevel?.();
3613
- const hasStateOverride = state?.hasDebugLogLevelOverride?.() ?? false;
3614
- if (hasStateOverride) {
3615
- return stateLevel;
3616
- }
3617
- const globalLevel = (
3618
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
3619
- globalThis[DEBUG_LOG_LEVEL_SYMBOL]
3620
- );
3621
- if (globalLevel !== void 0) {
3622
- return globalLevel === false ? void 0 : globalLevel;
3623
- }
3624
- return getEnvDebugLogLevel();
3625
- }
3626
- function emit(method, state, args) {
3627
- const level = resolveDebugLogLevel(state);
3628
- if (!level || LOG_LEVEL_PRIORITY[method] > LOG_LEVEL_PRIORITY[level]) {
3629
- return;
3630
- }
3631
- if (method === "info") {
3632
- console.log(PREFIX, ...args);
3633
- } else if (method === "debug") {
3634
- console.debug(PREFIX, ...args);
3635
- } else if (method === "warn") {
3636
- console.warn(PREFIX, ...args);
3637
- } else {
3638
- console.error(PREFIX, ...args);
3639
- }
3640
- }
3641
- function createDebugLogger(state) {
3642
- const resolveState = () => state ?? debugLogStateResolver?.();
3643
- return {
3644
- info(...args) {
3645
- emit("info", resolveState(), args);
3646
- },
3647
- debug(...args) {
3648
- emit("debug", resolveState(), args);
3649
- },
3650
- warn(...args) {
3651
- emit("warn", resolveState(), args);
3652
- },
3653
- error(...args) {
3654
- emit("error", resolveState(), args);
3655
- }
3656
- };
3657
- }
3658
- var debugLogger = {
3659
- ...createDebugLogger(),
3660
- forState(state) {
3661
- return createDebugLogger(state);
3662
- }
3663
- };
3664
-
3665
4027
  // src/queue.ts
3666
4028
  var DEFAULT_QUEUE_SIZE = 15e3;
3667
4029
  var Queue = class {
@@ -4455,7 +4817,10 @@ var BraintrustContextManager = class extends ContextManager {
4455
4817
  }
4456
4818
  };
4457
4819
  function getSpanComponentsClass() {
4458
- return globalThis.BRAINTRUST_SPAN_COMPONENT ? globalThis.BRAINTRUST_SPAN_COMPONENT : SpanComponentsV3;
4820
+ if (globalThis.BRAINTRUST_SPAN_COMPONENT) {
4821
+ return globalThis.BRAINTRUST_SPAN_COMPONENT;
4822
+ }
4823
+ return resolveUseLegacyUuidIds() ? SpanComponentsV3 : SpanComponentsV4;
4459
4824
  }
4460
4825
  function getContextManager() {
4461
4826
  return globalThis.BRAINTRUST_CONTEXT_MANAGER ? new globalThis.BRAINTRUST_CONTEXT_MANAGER() : new BraintrustContextManager();
@@ -4491,6 +4856,9 @@ var NoopSpan = class {
4491
4856
  async export() {
4492
4857
  return "";
4493
4858
  }
4859
+ inject(carrier) {
4860
+ return carrier ?? {};
4861
+ }
4494
4862
  async permalink() {
4495
4863
  return NOOP_SPAN_PERMALINK;
4496
4864
  }
@@ -4541,6 +4909,10 @@ var loginSchema = z8.strictObject({
4541
4909
  debugLogLevelDisabled: z8.boolean().optional()
4542
4910
  });
4543
4911
  var stateNonce = 0;
4912
+ var V1_PROXY_SUFFIX = "/v1/proxy";
4913
+ function normalizeProxyConnUrl(proxyUrl) {
4914
+ return proxyUrl.endsWith(V1_PROXY_SUFFIX) ? proxyUrl.slice(0, proxyUrl.length - V1_PROXY_SUFFIX.length) : proxyUrl;
4915
+ }
4544
4916
  var BraintrustState = class _BraintrustState {
4545
4917
  constructor(loginParams) {
4546
4918
  this.loginParams = loginParams;
@@ -4811,7 +5183,10 @@ var BraintrustState = class _BraintrustState {
4811
5183
  if (!this.proxyUrl) {
4812
5184
  throw new Error("Must initialize proxyUrl before requesting proxyConn");
4813
5185
  }
4814
- this._proxyConn = new HTTPConnection(this.proxyUrl, this.fetch);
5186
+ this._proxyConn = new HTTPConnection(
5187
+ normalizeProxyConnUrl(this.proxyUrl),
5188
+ this.fetch
5189
+ );
4815
5190
  }
4816
5191
  return this._proxyConn;
4817
5192
  }
@@ -5569,7 +5944,7 @@ function updateSpan({
5569
5944
  ...event
5570
5945
  }) {
5571
5946
  const resolvedState = state ?? _globalState;
5572
- const components = getSpanComponentsClass().fromStr(exported);
5947
+ const components = SpanComponentsV4.fromStr(exported);
5573
5948
  if (!components.data.row_id) {
5574
5949
  throw new Error("Exported span must have a row id");
5575
5950
  }
@@ -5669,7 +6044,7 @@ async function permalink(slug, opts) {
5669
6044
  return state.appUrl;
5670
6045
  };
5671
6046
  try {
5672
- const components = getSpanComponentsClass().fromStr(slug);
6047
+ const components = SpanComponentsV4.fromStr(slug);
5673
6048
  const object_type = spanObjectTypeV3ToString(components.data.object_type);
5674
6049
  const [orgName, appUrl, object_id] = await Promise.all([
5675
6050
  getOrgName(),
@@ -5693,35 +6068,47 @@ function startSpanParentArgs(args) {
5693
6068
  let argParentObjectId = void 0;
5694
6069
  let argParentSpanIds = void 0;
5695
6070
  let argPropagatedEvent = void 0;
5696
- if (args.parent) {
6071
+ let argPropagatedState = void 0;
6072
+ const { parentSlug, propagatedState: parentPropagatedState } = normalizeParent(args.parent, args.state);
6073
+ if (parentSlug) {
5697
6074
  if (args.parentSpanIds) {
5698
6075
  throw new Error("Cannot specify both parent and parentSpanIds");
5699
6076
  }
5700
- const parentComponents = getSpanComponentsClass().fromStr(args.parent);
6077
+ const parentComponents = SpanComponentsV4.fromStr(parentSlug);
5701
6078
  if (args.parentObjectType !== parentComponents.data.object_type) {
5702
6079
  throw new Error(
5703
6080
  `Mismatch between expected span parent object type ${args.parentObjectType} and provided type ${parentComponents.data.object_type}`
5704
6081
  );
5705
6082
  }
5706
6083
  argParentObjectId = args.parentObjectId;
5707
- if (parentComponents.data.row_id) {
6084
+ if (parentComponents.data.row_id && parentSpanIdsUsable(
6085
+ parentComponents.data.span_id,
6086
+ parentComponents.data.root_span_id
6087
+ )) {
5708
6088
  argParentSpanIds = {
5709
6089
  spanId: parentComponents.data.span_id,
5710
6090
  rootSpanId: parentComponents.data.root_span_id
5711
6091
  };
5712
6092
  }
5713
6093
  argPropagatedEvent = args.propagatedEvent ?? (parentComponents.data.propagated_event ?? void 0);
6094
+ const propagatedState = args.propagatedState ?? parentPropagatedState;
6095
+ if (propagatedState) {
6096
+ const { braintrustParent: _ignoredBraintrustParent, ...w3cState } = propagatedState;
6097
+ argPropagatedState = w3cState;
6098
+ }
5714
6099
  } else {
5715
6100
  argParentObjectId = args.parentObjectId;
5716
6101
  argParentSpanIds = args.parentSpanIds;
5717
6102
  argPropagatedEvent = args.propagatedEvent;
6103
+ argPropagatedState = args.propagatedState;
5718
6104
  }
5719
6105
  return {
5720
6106
  parentObjectType: args.parentObjectType,
5721
6107
  parentObjectId: argParentObjectId,
5722
6108
  parentComputeObjectMetadataArgs: args.parentComputeObjectMetadataArgs,
5723
6109
  parentSpanIds: argParentSpanIds,
5724
- propagatedEvent: argPropagatedEvent
6110
+ propagatedEvent: argPropagatedEvent,
6111
+ propagatedState: argPropagatedState
5725
6112
  };
5726
6113
  }
5727
6114
  var Logger = class {
@@ -5922,6 +6309,22 @@ var Logger = class {
5922
6309
  _getLinkBaseUrl() {
5923
6310
  return _getLinkBaseUrl(this.state, this._linkArgs);
5924
6311
  }
6312
+ /**
6313
+ * Return this logger's Braintrust parent string (`project_id:<id>` or
6314
+ * `project_name:<name>`) for the `braintrust.parent` baggage entry, or
6315
+ * undefined when it cannot be determined synchronously.
6316
+ */
6317
+ _getOtelParent() {
6318
+ const id = this.computeMetadataArgs?.project_id || this.lazyId.getSync().value;
6319
+ if (id) {
6320
+ return `project_id:${id}`;
6321
+ }
6322
+ const name = this.computeMetadataArgs?.project_name;
6323
+ if (name) {
6324
+ return `project_name:${name}`;
6325
+ }
6326
+ return void 0;
6327
+ }
5925
6328
  };
5926
6329
  function castLogger(logger, asyncFlush) {
5927
6330
  if (logger === void 0) return void 0;
@@ -6016,12 +6419,12 @@ function stringifyWithOverflowMeta(item) {
6016
6419
  object_ids: pickLogs3OverflowObjectIds(record),
6017
6420
  is_delete: record[OBJECT_DELETE_FIELD] === true,
6018
6421
  input_row: {
6019
- byte_size: utf8ByteLength(str)
6422
+ byte_size: utf8ByteLength2(str)
6020
6423
  }
6021
6424
  }
6022
6425
  };
6023
6426
  }
6024
- function utf8ByteLength(value) {
6427
+ function utf8ByteLength2(value) {
6025
6428
  if (typeof TextEncoder !== "undefined") {
6026
6429
  return new TextEncoder().encode(value).length;
6027
6430
  }
@@ -6409,7 +6812,7 @@ var HTTPBackgroundLogger = class _HTTPBackgroundLogger {
6409
6812
  }) {
6410
6813
  const conn = await this.apiConn.get();
6411
6814
  const dataStr = constructLogs3Data(items);
6412
- const payloadBytes = utf8ByteLength(dataStr);
6815
+ const payloadBytes = utf8ByteLength2(dataStr);
6413
6816
  const useOverflow = canUseOverflow && payloadBytes > maxRequestSize;
6414
6817
  if (this.allPublishPayloadsDir) {
6415
6818
  await _HTTPBackgroundLogger.writePayloadToDir({
@@ -7030,6 +7433,8 @@ function initDataset(projectOrOptions, optionalOptions) {
7030
7433
  const normalizedVersion = selection.version;
7031
7434
  const normalizedEnvironment = selection.environment;
7032
7435
  const normalizedSnapshotName = selection.snapshotName;
7436
+ const cliInternalBtql = globalThis.__bt_eval_internal_btql;
7437
+ const internalBtql = cliInternalBtql === void 0 ? _internal_btql : _internal_btql === void 0 ? cliInternalBtql : isObject(_internal_btql) ? { ...cliInternalBtql, ..._internal_btql } : _internal_btql;
7033
7438
  const state = stateArg ?? _globalState;
7034
7439
  const lazyMetadata = new LazyValue(
7035
7440
  async () => {
@@ -7081,7 +7486,7 @@ function initDataset(projectOrOptions, optionalOptions) {
7081
7486
  lazyMetadata,
7082
7487
  typeof resolvedVersion === "string" ? resolvedVersion : void 0,
7083
7488
  legacy,
7084
- _internal_btql,
7489
+ internalBtql,
7085
7490
  resolvedVersion instanceof LazyValue || normalizedEnvironment !== void 0 || normalizedSnapshotName !== void 0 ? {
7086
7491
  ...resolvedVersion instanceof LazyValue ? {
7087
7492
  lazyPinnedVersion: resolvedVersion
@@ -7545,23 +7950,285 @@ function currentSpan(options) {
7545
7950
  const state = options?.state ?? _globalState;
7546
7951
  return state.contextManager.getCurrentSpan() ?? NOOP_SPAN;
7547
7952
  }
7548
- function getSpanParentObject(options) {
7953
+ function getSpanParentObjectAndPropagatedState(options) {
7549
7954
  const state = options?.state ?? _globalState;
7550
7955
  const parentSpan = currentSpan({ state });
7551
7956
  if (!Object.is(parentSpan, NOOP_SPAN)) {
7552
- return parentSpan;
7957
+ return { parentObject: parentSpan, propagatedState: void 0 };
7958
+ }
7959
+ const parent = options?.parent ?? state.currentParent.getStore();
7960
+ const { parentSlug, propagatedState } = normalizeParent(parent, state);
7961
+ if (parentSlug) {
7962
+ return {
7963
+ parentObject: SpanComponentsV4.fromStr(parentSlug),
7964
+ propagatedState
7965
+ };
7553
7966
  }
7554
- const parentStr = options?.parent ?? state.currentParent.getStore();
7555
- if (parentStr) return getSpanComponentsClass().fromStr(parentStr);
7556
7967
  const experiment = currentExperiment();
7557
7968
  if (experiment) {
7558
- return experiment;
7969
+ return { parentObject: experiment, propagatedState: void 0 };
7559
7970
  }
7560
7971
  const logger = currentLogger(options);
7561
7972
  if (logger) {
7562
- return logger;
7973
+ return { parentObject: logger, propagatedState: void 0 };
7974
+ }
7975
+ return { parentObject: NOOP_SPAN, propagatedState: void 0 };
7976
+ }
7977
+ function getSpanParentObject(options) {
7978
+ return getSpanParentObjectAndPropagatedState(options).parentObject;
7979
+ }
7980
+ function currentBraintrustParent(state) {
7981
+ const resolvedState = state ?? _globalState;
7982
+ const experiment = currentExperiment({ state: resolvedState });
7983
+ if (experiment) {
7984
+ try {
7985
+ return experiment._getOtelParent() ?? void 0;
7986
+ } catch {
7987
+ return void 0;
7988
+ }
7989
+ }
7990
+ const logger = currentLogger({ state: resolvedState });
7991
+ if (logger) {
7992
+ try {
7993
+ return logger._getOtelParent() ?? void 0;
7994
+ } catch {
7995
+ return void 0;
7996
+ }
7997
+ }
7998
+ return void 0;
7999
+ }
8000
+ function braintrustParentToComponents(braintrustParent) {
8001
+ if (!braintrustParent) {
8002
+ return void 0;
8003
+ }
8004
+ if (braintrustParent.startsWith("project_id:")) {
8005
+ const objectId = braintrustParent.slice("project_id:".length);
8006
+ return objectId ? {
8007
+ objectType: 2 /* PROJECT_LOGS */,
8008
+ objectId,
8009
+ computeArgs: void 0
8010
+ } : void 0;
8011
+ }
8012
+ if (braintrustParent.startsWith("project_name:")) {
8013
+ const name = braintrustParent.slice("project_name:".length);
8014
+ return name ? {
8015
+ objectType: 2 /* PROJECT_LOGS */,
8016
+ objectId: void 0,
8017
+ computeArgs: { project_name: name }
8018
+ } : void 0;
8019
+ }
8020
+ if (braintrustParent.startsWith("experiment_id:")) {
8021
+ const objectId = braintrustParent.slice("experiment_id:".length);
8022
+ return objectId ? {
8023
+ objectType: 1 /* EXPERIMENT */,
8024
+ objectId,
8025
+ computeArgs: void 0
8026
+ } : void 0;
8027
+ }
8028
+ return void 0;
8029
+ }
8030
+ function isMutableHeaderTupleArray(carrier) {
8031
+ return Array.isArray(carrier) && carrier.every((item) => Array.isArray(item) && typeof item[0] === "string");
8032
+ }
8033
+ function setHeader(carrier, name, value) {
8034
+ if (isMutableHeaderTupleArray(carrier)) {
8035
+ const lowered2 = name.toLowerCase();
8036
+ for (let i = carrier.length - 1; i >= 0; i--) {
8037
+ if (carrier[i][0].toLowerCase() === lowered2) {
8038
+ carrier.splice(i, 1);
8039
+ }
8040
+ }
8041
+ carrier.push([name, value]);
8042
+ return;
8043
+ }
8044
+ const setter = carrier.set;
8045
+ if (typeof setter === "function") {
8046
+ const deleter = carrier.delete;
8047
+ if (typeof deleter === "function") {
8048
+ try {
8049
+ deleter.call(carrier, name);
8050
+ } catch {
8051
+ }
8052
+ }
8053
+ setter.call(carrier, name, value);
8054
+ return;
8055
+ }
8056
+ const nodeSetter = carrier.setHeader;
8057
+ if (typeof nodeSetter === "function") {
8058
+ const remover = carrier.removeHeader;
8059
+ if (typeof remover === "function") {
8060
+ try {
8061
+ remover.call(carrier, name);
8062
+ } catch {
8063
+ }
8064
+ }
8065
+ nodeSetter.call(carrier, name, value);
8066
+ return;
8067
+ }
8068
+ const headerSetter = carrier.header;
8069
+ if (typeof headerSetter === "function") {
8070
+ const deleter = carrier.delete;
8071
+ if (typeof deleter === "function") {
8072
+ try {
8073
+ deleter.call(carrier, name);
8074
+ } catch {
8075
+ }
8076
+ }
8077
+ const remover = carrier.removeHeader;
8078
+ if (typeof remover === "function") {
8079
+ try {
8080
+ remover.call(carrier, name);
8081
+ } catch {
8082
+ }
8083
+ }
8084
+ headerSetter.call(carrier, name, value);
8085
+ return;
8086
+ }
8087
+ const headerBag = carrier;
8088
+ const lowered = name.toLowerCase();
8089
+ for (const key of Object.keys(headerBag)) {
8090
+ if (key !== name && key.toLowerCase() === lowered) {
8091
+ delete headerBag[key];
8092
+ }
8093
+ }
8094
+ headerBag[name] = value;
8095
+ }
8096
+ function deleteHeader(carrier, name) {
8097
+ const lowered = name.toLowerCase();
8098
+ if (isMutableHeaderTupleArray(carrier)) {
8099
+ for (let i = carrier.length - 1; i >= 0; i--) {
8100
+ if (carrier[i][0].toLowerCase() === lowered) {
8101
+ carrier.splice(i, 1);
8102
+ }
8103
+ }
8104
+ return;
8105
+ }
8106
+ const deleter = carrier.delete;
8107
+ if (typeof deleter === "function") {
8108
+ try {
8109
+ deleter.call(carrier, name);
8110
+ return;
8111
+ } catch {
8112
+ }
8113
+ }
8114
+ const remover = carrier.removeHeader;
8115
+ if (typeof remover === "function") {
8116
+ try {
8117
+ remover.call(carrier, name);
8118
+ return;
8119
+ } catch {
8120
+ }
8121
+ }
8122
+ const headerBag = carrier;
8123
+ for (const key of Object.keys(headerBag)) {
8124
+ if (key.toLowerCase() === lowered) {
8125
+ delete headerBag[key];
8126
+ }
8127
+ }
8128
+ }
8129
+ function _injectIntoCarrier(carrier, args) {
8130
+ const traceFlags = args.propagatedState?.traceFlags;
8131
+ const traceparent = traceFlags ? formatTraceparent(args.traceId, args.spanId, traceFlags) : formatTraceparent(args.traceId, args.spanId);
8132
+ if (traceparent === void 0) {
8133
+ return;
8134
+ }
8135
+ setHeader(carrier, TRACEPARENT_HEADER, traceparent);
8136
+ const tracestate = args.propagatedState?.tracestate;
8137
+ if (tracestate) {
8138
+ setHeader(carrier, TRACESTATE_HEADER, tracestate);
8139
+ }
8140
+ const existing = getHeader(carrier, BAGGAGE_HEADER);
8141
+ const baggageValue = mergeBaggage(existing, args.braintrustParent);
8142
+ if (baggageValue !== void 0) {
8143
+ setHeader(carrier, BAGGAGE_HEADER, baggageValue);
8144
+ } else if (existing !== void 0) {
8145
+ deleteHeader(carrier, BAGGAGE_HEADER);
8146
+ }
8147
+ }
8148
+ function injectTraceContext(carrier, options) {
8149
+ const resolvedCarrier = carrier ?? {};
8150
+ const span = options?.span ?? currentSpan({ state: options?.state });
8151
+ try {
8152
+ return span.inject(resolvedCarrier);
8153
+ } catch (e) {
8154
+ debugLogger.warn(`Error injecting trace context: ${e}`);
8155
+ return resolvedCarrier;
8156
+ }
8157
+ }
8158
+ function extractTraceContextFromHeaders(headers) {
8159
+ if (!headers) {
8160
+ return void 0;
8161
+ }
8162
+ const traceparent = getHeader(headers, TRACEPARENT_HEADER);
8163
+ if (!traceparent || parseTraceparent(traceparent) === void 0) {
8164
+ return void 0;
8165
+ }
8166
+ const context = { [TRACEPARENT_HEADER]: traceparent };
8167
+ const baggageValue = getHeader(headers, BAGGAGE_HEADER);
8168
+ if (baggageValue) {
8169
+ context[BAGGAGE_HEADER] = baggageValue;
8170
+ }
8171
+ const tracestate = getHeader(headers, TRACESTATE_HEADER);
8172
+ if (tracestate) {
8173
+ context[TRACESTATE_HEADER] = tracestate;
8174
+ }
8175
+ return context;
8176
+ }
8177
+ function resolveW3cParent(context, state) {
8178
+ const traceparent = getHeader(context, TRACEPARENT_HEADER);
8179
+ const parsed = traceparent ? parseTraceparent(traceparent) : void 0;
8180
+ if (parsed === void 0) {
8181
+ return { parentSlug: void 0, propagatedState: void 0 };
8182
+ }
8183
+ const { traceId, spanId, traceFlags } = parsed;
8184
+ let braintrustParent = void 0;
8185
+ const baggageValue = getHeader(context, BAGGAGE_HEADER);
8186
+ if (baggageValue) {
8187
+ braintrustParent = parseBaggage(baggageValue)[BRAINTRUST_PARENT_KEY];
8188
+ }
8189
+ if (!braintrustParent) {
8190
+ braintrustParent = currentBraintrustParent(state);
8191
+ }
8192
+ if (!braintrustParent) {
8193
+ debugLogger.warn(
8194
+ "Received traceparent without a braintrust.parent and no active logger/experiment; cannot route the trace. Starting a fresh local span instead."
8195
+ );
8196
+ return { parentSlug: void 0, propagatedState: void 0 };
8197
+ }
8198
+ const parsedParent = braintrustParentToComponents(braintrustParent);
8199
+ if (parsedParent === void 0) {
8200
+ debugLogger.warn(
8201
+ `Invalid braintrust.parent: ${JSON.stringify(braintrustParent)}`
8202
+ );
8203
+ return { parentSlug: void 0, propagatedState: void 0 };
8204
+ }
8205
+ const { objectType, objectId, computeArgs } = parsedParent;
8206
+ const tracestate = getHeader(context, TRACESTATE_HEADER);
8207
+ const slug = new SpanComponentsV4({
8208
+ object_type: objectType,
8209
+ ...computeArgs ? { compute_object_metadata_args: computeArgs } : { object_id: objectId },
8210
+ row_id: "bt-propagation",
8211
+ // non-empty to enable span_id/root_span_id
8212
+ span_id: spanId,
8213
+ root_span_id: traceId
8214
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
8215
+ }).toStr();
8216
+ return {
8217
+ parentSlug: slug,
8218
+ propagatedState: { tracestate, traceFlags, braintrustParent }
8219
+ };
8220
+ }
8221
+ function normalizeParent(parent, state) {
8222
+ if (parent && typeof parent === "object") {
8223
+ return resolveW3cParent(parent, state);
7563
8224
  }
7564
- return NOOP_SPAN;
8225
+ return {
8226
+ parentSlug: parent ?? void 0,
8227
+ propagatedState: void 0
8228
+ };
8229
+ }
8230
+ function parentSpanIdsUsable(spanId, rootSpanId) {
8231
+ return Boolean(spanId) && Boolean(rootSpanId);
7565
8232
  }
7566
8233
  function logError(span, error) {
7567
8234
  let errorMessage = "<error>";
@@ -7769,19 +8436,23 @@ function setFetch(fetch2) {
7769
8436
  }
7770
8437
  function startSpanAndIsLogger(args) {
7771
8438
  const state = args?.state ?? _globalState;
7772
- const parentObject = getSpanParentObject({
8439
+ const { parentObject, propagatedState } = getSpanParentObjectAndPropagatedState({
7773
8440
  asyncFlush: args?.asyncFlush,
7774
8441
  parent: args?.parent,
7775
8442
  state
7776
8443
  });
7777
8444
  if (parentObject instanceof SpanComponentsV3 || parentObject instanceof SpanComponentsV4) {
7778
- const parentSpanIds = parentObject.data.row_id ? {
8445
+ const parentSpanIds = parentObject.data.row_id && parentSpanIdsUsable(
8446
+ parentObject.data.span_id,
8447
+ parentObject.data.root_span_id
8448
+ ) ? {
7779
8449
  spanId: parentObject.data.span_id,
7780
8450
  rootSpanId: parentObject.data.root_span_id
7781
8451
  } : void 0;
8452
+ const { parent: _ignoredParent, ...spanArgs } = args ?? {};
7782
8453
  const span = new SpanImpl({
7783
8454
  state,
7784
- ...args,
8455
+ ...spanArgs,
7785
8456
  parentObjectType: parentObject.data.object_type,
7786
8457
  parentObjectId: new LazyValue(
7787
8458
  spanComponentsToObjectIdLambda(state, parentObject)
@@ -7789,7 +8460,8 @@ function startSpanAndIsLogger(args) {
7789
8460
  parentComputeObjectMetadataArgs: parentObject.data.compute_object_metadata_args ?? void 0,
7790
8461
  parentSpanIds,
7791
8462
  propagatedEvent: args?.propagatedEvent ?? // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
7792
- (parentObject.data.propagated_event ?? void 0)
8463
+ (parentObject.data.propagated_event ?? void 0),
8464
+ propagatedState
7793
8465
  });
7794
8466
  return {
7795
8467
  span,
@@ -8078,11 +8750,12 @@ function validateAndSanitizeExperimentLogFullArgs(event, hasDataset) {
8078
8750
  var DEFAULT_FETCH_BATCH_SIZE = 1e3;
8079
8751
  var MAX_BTQL_ITERATIONS = 1e4;
8080
8752
  var ObjectFetcher = class {
8081
- constructor(objectType, pinnedVersion, mutateRecord, _internal_btql) {
8753
+ constructor(objectType, pinnedVersion, mutateRecord, _internal_btql, _internalBrainstoreRealtime = true) {
8082
8754
  this.objectType = objectType;
8083
8755
  this.pinnedVersion = pinnedVersion;
8084
8756
  this.mutateRecord = mutateRecord;
8085
8757
  this._internal_btql = _internal_btql;
8758
+ this._internalBrainstoreRealtime = _internalBrainstoreRealtime;
8086
8759
  }
8087
8760
  _fetchedData = void 0;
8088
8761
  get id() {
@@ -8141,7 +8814,7 @@ var ObjectFetcher = class {
8141
8814
  ...internalBtqlWithoutReservedQueryKeys
8142
8815
  },
8143
8816
  use_columnstore: false,
8144
- brainstore_realtime: true,
8817
+ brainstore_realtime: this._internalBrainstoreRealtime,
8145
8818
  query_source: `js_sdk_object_fetcher_${this.objectType}`,
8146
8819
  ...this.pinnedVersion !== void 0 ? {
8147
8820
  version: this.pinnedVersion
@@ -8490,6 +9163,15 @@ View complete results in Braintrust or run experiment.summarize() again.`
8490
9163
  object_id: await this.id
8491
9164
  }).toStr();
8492
9165
  }
9166
+ /**
9167
+ * Return this experiment's Braintrust parent string (`experiment_id:<id>`) for
9168
+ * the `braintrust.parent` baggage entry, or undefined when it cannot be
9169
+ * determined synchronously.
9170
+ */
9171
+ _getOtelParent() {
9172
+ const id = this.lazyId.getSync().value;
9173
+ return id ? `experiment_id:${id}` : void 0;
9174
+ }
8493
9175
  /**
8494
9176
  * Flush any pending rows to the server.
8495
9177
  */
@@ -8532,7 +9214,8 @@ var ReadonlyExperiment = class extends ObjectFetcher {
8532
9214
  async *asDataset(options) {
8533
9215
  const records = this.fetch(options);
8534
9216
  for await (const record of records) {
8535
- if (record.root_span_id !== record.span_id) {
9217
+ const isRoot = record.is_root ?? record.root_span_id === record.span_id;
9218
+ if (!isRoot) {
8536
9219
  continue;
8537
9220
  }
8538
9221
  const { output, expected: expectedRecord, metadata } = record;
@@ -8594,9 +9277,16 @@ var SpanImpl = class _SpanImpl {
8594
9277
  _spanId;
8595
9278
  _rootSpanId;
8596
9279
  _spanParents;
9280
+ // Inbound W3C trace-context state (tracestate + raw traceparent flags) to
9281
+ // forward on outbound propagation. Captured at the span that received it (via
9282
+ // extractTraceContextFromHeaders) and inherited by all subspans, so that any
9283
+ // inject() within the trace re-emits the upstream state unchanged, per the W3C
9284
+ // Trace Context spec. Not interpreted.
9285
+ _propagatedState;
8597
9286
  kind = "span";
8598
9287
  constructor(args) {
8599
9288
  this._state = args.state;
9289
+ this._propagatedState = args.propagatedState;
8600
9290
  const spanAttributes = args.spanAttributes ?? {};
8601
9291
  const rawEvent = args.event ?? {};
8602
9292
  const type = args.type ?? (args.parentSpanIds ? void 0 : args.defaultRootType);
@@ -8712,7 +9402,7 @@ var SpanImpl = class _SpanImpl {
8712
9402
  tags: partialRecord.tags,
8713
9403
  span_id: this._spanId,
8714
9404
  span_parents: this._spanParents,
8715
- is_root: this._spanId === this._rootSpanId,
9405
+ is_root: !this._spanParents || this._spanParents.length === 0,
8716
9406
  span_attributes: partialRecord.span_attributes
8717
9407
  };
8718
9408
  this._state.spanCache.queueWrite(
@@ -8774,7 +9464,8 @@ var SpanImpl = class _SpanImpl {
8774
9464
  parentObjectId: this.parentObjectId,
8775
9465
  parentComputeObjectMetadataArgs: this.parentComputeObjectMetadataArgs,
8776
9466
  parentSpanIds,
8777
- propagatedEvent: args?.propagatedEvent ?? this.propagatedEvent
9467
+ propagatedEvent: args?.propagatedEvent ?? this.propagatedEvent,
9468
+ propagatedState: this._propagatedState
8778
9469
  })
8779
9470
  });
8780
9471
  }
@@ -8793,7 +9484,8 @@ var SpanImpl = class _SpanImpl {
8793
9484
  parentObjectId: this.parentObjectId,
8794
9485
  parentComputeObjectMetadataArgs: this.parentComputeObjectMetadataArgs,
8795
9486
  parentSpanIds,
8796
- propagatedEvent: args?.propagatedEvent ?? this.propagatedEvent
9487
+ propagatedEvent: args?.propagatedEvent ?? this.propagatedEvent,
9488
+ propagatedState: this._propagatedState
8797
9489
  }),
8798
9490
  spanId
8799
9491
  });
@@ -8821,11 +9513,47 @@ var SpanImpl = class _SpanImpl {
8821
9513
  propagated_event: this.propagatedEvent
8822
9514
  }).toStr();
8823
9515
  }
8824
- async permalink() {
8825
- return await permalink(await this.export(), {
8826
- state: this._state
8827
- });
8828
- }
9516
+ /**
9517
+ * Return this span's Braintrust parent string (`project_id:<id>`,
9518
+ * `project_name:<name>`, or `experiment_id:<id>`) for the `braintrust.parent`
9519
+ * baggage entry, or undefined when it cannot be determined synchronously.
9520
+ */
9521
+ _getOtelParent() {
9522
+ if (this.parentObjectType === 2 /* PROJECT_LOGS */) {
9523
+ const id = this.parentComputeObjectMetadataArgs?.project_id || this.parentObjectId.getSync().value;
9524
+ const name = this.parentComputeObjectMetadataArgs?.project_name;
9525
+ if (id) {
9526
+ return `project_id:${id}`;
9527
+ } else if (name) {
9528
+ return `project_name:${name}`;
9529
+ }
9530
+ } else if (this.parentObjectType === 1 /* EXPERIMENT */) {
9531
+ const id = this.parentComputeObjectMetadataArgs?.experiment_id || this.parentObjectId.getSync().value;
9532
+ if (id) {
9533
+ return `experiment_id:${id}`;
9534
+ }
9535
+ }
9536
+ return void 0;
9537
+ }
9538
+ inject(carrier) {
9539
+ const resolvedCarrier = carrier ?? {};
9540
+ try {
9541
+ _injectIntoCarrier(resolvedCarrier, {
9542
+ traceId: this._rootSpanId,
9543
+ spanId: this._spanId,
9544
+ braintrustParent: this._getOtelParent() ?? this._propagatedState?.braintrustParent,
9545
+ propagatedState: this._propagatedState
9546
+ });
9547
+ } catch (e) {
9548
+ debugLogger.warn(`Error injecting trace context: ${e}`);
9549
+ }
9550
+ return resolvedCarrier;
9551
+ }
9552
+ async permalink() {
9553
+ return await permalink(await this.export(), {
9554
+ state: this._state
9555
+ });
9556
+ }
8829
9557
  link() {
8830
9558
  if (!this.id) {
8831
9559
  return NOOP_SPAN_PERMALINK;
@@ -8956,6 +9684,7 @@ var Dataset2 = class extends ObjectFetcher {
8956
9684
  _internal_btql
8957
9685
  );
8958
9686
  this.state = state;
9687
+ void this.__braintrust_dataset_marker;
8959
9688
  this.lazyMetadata = lazyMetadata;
8960
9689
  this.lazyPinnedVersion = pinState?.lazyPinnedVersion;
8961
9690
  this.pinnedEnvironment = pinState?.pinnedEnvironment;
@@ -9473,6 +10202,7 @@ var Prompt2 = class _Prompt {
9473
10202
  this.metadata = metadata;
9474
10203
  this.defaults = defaults;
9475
10204
  this.noTrace = noTrace;
10205
+ void this.__braintrust_prompt_marker;
9476
10206
  }
9477
10207
  parsedPromptData;
9478
10208
  hasParsedPromptData = false;
@@ -9709,6 +10439,7 @@ var Prompt2 = class _Prompt {
9709
10439
  var RemoteEvalParameters = class {
9710
10440
  constructor(metadata) {
9711
10441
  this.metadata = metadata;
10442
+ void this.__braintrust_parameters_marker;
9712
10443
  }
9713
10444
  __braintrust_parameters_marker = true;
9714
10445
  get id() {
@@ -9845,6 +10576,7 @@ var _exportsForTestingOnly = {
9845
10576
  isAsyncGeneratorFunction,
9846
10577
  resetIdGenStateForTests,
9847
10578
  validateTags,
10579
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
9848
10580
  isomorph: isomorph_default
9849
10581
  // Expose isomorph for build type detection
9850
10582
  };
@@ -10728,6 +11460,22 @@ function runStreamingCompletionHook(args) {
10728
11460
  );
10729
11461
  }
10730
11462
  }
11463
+ function runStreamingErrorHook(args) {
11464
+ if (!args.config.onError) {
11465
+ return;
11466
+ }
11467
+ try {
11468
+ args.config.onError({
11469
+ channelName: args.channelName,
11470
+ error: args.error,
11471
+ event: args.event,
11472
+ span: args.span,
11473
+ startTime: args.startTime
11474
+ });
11475
+ } catch (error) {
11476
+ debugLogger.error(`Error in onError hook for ${args.channelName}:`, error);
11477
+ }
11478
+ }
10731
11479
  function traceAsyncChannel(channel, config) {
10732
11480
  const tracingChannel2 = channel.tracingChannel();
10733
11481
  const states = /* @__PURE__ */ new WeakMap();
@@ -10889,6 +11637,14 @@ function traceStreamingChannel(channel, config) {
10889
11637
  }
10890
11638
  },
10891
11639
  onError: (error) => {
11640
+ runStreamingErrorHook({
11641
+ channelName,
11642
+ config,
11643
+ error,
11644
+ event: asyncEndEvent,
11645
+ span,
11646
+ startTime
11647
+ });
10892
11648
  span.log({
10893
11649
  error: error.message
10894
11650
  });
@@ -10946,6 +11702,17 @@ function traceStreamingChannel(channel, config) {
10946
11702
  }
10947
11703
  },
10948
11704
  error: (event) => {
11705
+ const spanData = states.get(event);
11706
+ if (spanData) {
11707
+ runStreamingErrorHook({
11708
+ channelName,
11709
+ config,
11710
+ error: event.error,
11711
+ event,
11712
+ span: spanData.span,
11713
+ startTime: spanData.startTime
11714
+ });
11715
+ }
10949
11716
  logErrorAndEnd(states, event);
10950
11717
  }
10951
11718
  };
@@ -11345,18 +12112,51 @@ function serializeAISDKToolsForLogging(tools) {
11345
12112
  return serialized;
11346
12113
  }
11347
12114
 
12115
+ // src/wrappers/ai-sdk/workflow-agent-context.ts
12116
+ var workflowAgentWrapperSpans = /* @__PURE__ */ new Map();
12117
+ function registerWorkflowAgentWrapperSpan(span) {
12118
+ if (span.spanId) {
12119
+ workflowAgentWrapperSpans.set(span.spanId, span);
12120
+ }
12121
+ }
12122
+ function unregisterWorkflowAgentWrapperSpan(span) {
12123
+ if (span.spanId) {
12124
+ workflowAgentWrapperSpans.delete(span.spanId);
12125
+ }
12126
+ }
12127
+ function currentWorkflowAgentWrapperSpan() {
12128
+ const parentSpanIds = _internalGetGlobalState().contextManager.getParentSpanIds()?.spanParents ?? [];
12129
+ for (const parentSpanId of parentSpanIds) {
12130
+ const span = workflowAgentWrapperSpans.get(parentSpanId);
12131
+ if (span) {
12132
+ return span;
12133
+ }
12134
+ }
12135
+ return void 0;
12136
+ }
12137
+
12138
+ // src/vendor-sdk-types/ai-sdk-v7-telemetry.ts
12139
+ var BRAINTRUST_AI_SDK_V7_OPERATION_KEY = /* @__PURE__ */ Symbol.for(
12140
+ "braintrust.ai-sdk.v7.telemetry-operation-key"
12141
+ );
12142
+
11348
12143
  // src/instrumentation/plugins/ai-sdk-plugin.ts
11349
12144
  var DEFAULT_DENY_OUTPUT_PATHS = [
11350
12145
  // v3
11351
12146
  "roundtrips[].request.body",
12147
+ "roundtrips[].request.headers",
11352
12148
  "roundtrips[].response.headers",
11353
12149
  "rawResponse.headers",
11354
12150
  "responseMessages",
11355
12151
  // v5
11356
12152
  "request.body",
12153
+ "request.headers",
12154
+ "responses[].headers",
11357
12155
  "response.body",
11358
12156
  "response.headers",
11359
12157
  "steps[].request.body",
12158
+ "steps[].request.headers",
12159
+ "steps[].responses[].headers",
11360
12160
  "steps[].response.body",
11361
12161
  "steps[].response.headers"
11362
12162
  ];
@@ -11368,6 +12168,18 @@ var AUTO_PATCHED_V7_TELEMETRY_DISPATCHER = /* @__PURE__ */ Symbol.for(
11368
12168
  var RUNTIME_DENY_OUTPUT_PATHS = /* @__PURE__ */ Symbol.for(
11369
12169
  "braintrust.ai-sdk.deny-output-paths"
11370
12170
  );
12171
+ var aiSDKV7TelemetryOperationCounter = 0;
12172
+ var TRANSPORT_PAYLOAD_ROOT_PATHS = [
12173
+ "rawResponse",
12174
+ "request",
12175
+ "response",
12176
+ "responses[]",
12177
+ "roundtrips[].request",
12178
+ "roundtrips[].response",
12179
+ "steps[].request",
12180
+ "steps[].response",
12181
+ "steps[].responses[]"
12182
+ ];
11371
12183
  var AI_SDK_V7_TELEMETRY_CALLBACKS = [
11372
12184
  "onStart",
11373
12185
  "onStepStart",
@@ -11376,14 +12188,16 @@ var AI_SDK_V7_TELEMETRY_CALLBACKS = [
11376
12188
  "onToolExecutionStart",
11377
12189
  "onToolExecutionEnd",
11378
12190
  "onChunk",
12191
+ "onStepEnd",
11379
12192
  "onStepFinish",
11380
12193
  "onObjectStepStart",
11381
- "onObjectStepFinish",
12194
+ "onObjectStepEnd",
11382
12195
  "onEmbedStart",
11383
- "onEmbedFinish",
12196
+ "onEmbedEnd",
11384
12197
  "onRerankStart",
11385
- "onRerankFinish",
11386
- "onFinish",
12198
+ "onRerankEnd",
12199
+ "onEnd",
12200
+ "onAbort",
11387
12201
  "onError"
11388
12202
  ];
11389
12203
  var AISDKPlugin = class extends BasePlugin {
@@ -11541,7 +12355,9 @@ var AISDKPlugin = class extends BasePlugin {
11541
12355
  traceStreamingChannel(aiSDKChannels.agentGenerate, {
11542
12356
  name: "Agent.generate",
11543
12357
  type: "function" /* FUNCTION */,
11544
- extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
12358
+ extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
12359
+ agentOwner: true
12360
+ }),
11545
12361
  extractOutput: (result, endEvent) => {
11546
12362
  finalizeAISDKChildTracing(endEvent);
11547
12363
  return processAISDKOutput(
@@ -11557,7 +12373,9 @@ var AISDKPlugin = class extends BasePlugin {
11557
12373
  traceStreamingChannel(aiSDKChannels.agentStream, {
11558
12374
  name: "Agent.stream",
11559
12375
  type: "function" /* FUNCTION */,
11560
- extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
12376
+ extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
12377
+ agentOwner: true
12378
+ }),
11561
12379
  extractOutput: (result, endEvent) => processAISDKOutput(
11562
12380
  result,
11563
12381
  resolveDenyOutputPaths(endEvent, denyOutputPaths)
@@ -11577,7 +12395,9 @@ var AISDKPlugin = class extends BasePlugin {
11577
12395
  traceSyncStreamChannel(aiSDKChannels.agentStreamSync, {
11578
12396
  name: "Agent.stream",
11579
12397
  type: "function" /* FUNCTION */,
11580
- extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
12398
+ extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
12399
+ agentOwner: true
12400
+ }),
11581
12401
  patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
11582
12402
  defaultDenyOutputPaths: denyOutputPaths,
11583
12403
  endEvent,
@@ -11591,7 +12411,9 @@ var AISDKPlugin = class extends BasePlugin {
11591
12411
  traceStreamingChannel(aiSDKChannels.toolLoopAgentGenerate, {
11592
12412
  name: "ToolLoopAgent.generate",
11593
12413
  type: "function" /* FUNCTION */,
11594
- extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
12414
+ extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
12415
+ agentOwner: true
12416
+ }),
11595
12417
  extractOutput: (result, endEvent) => {
11596
12418
  finalizeAISDKChildTracing(endEvent);
11597
12419
  return processAISDKOutput(
@@ -11607,7 +12429,9 @@ var AISDKPlugin = class extends BasePlugin {
11607
12429
  traceStreamingChannel(aiSDKChannels.toolLoopAgentStream, {
11608
12430
  name: "ToolLoopAgent.stream",
11609
12431
  type: "function" /* FUNCTION */,
11610
- extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
12432
+ extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
12433
+ agentOwner: true
12434
+ }),
11611
12435
  extractOutput: (result, endEvent) => processAISDKOutput(
11612
12436
  result,
11613
12437
  resolveDenyOutputPaths(endEvent, denyOutputPaths)
@@ -11623,6 +12447,42 @@ var AISDKPlugin = class extends BasePlugin {
11623
12447
  })
11624
12448
  })
11625
12449
  );
12450
+ this.unsubscribers.push(
12451
+ traceStreamingChannel(aiSDKChannels.workflowAgentStream, {
12452
+ name: "WorkflowAgent.stream",
12453
+ type: "function" /* FUNCTION */,
12454
+ extractInput: ([params], event, span) => prepareAISDKWorkflowAgentStreamInput(
12455
+ params,
12456
+ event,
12457
+ span,
12458
+ denyOutputPaths
12459
+ ),
12460
+ extractOutput: (result, endEvent) => {
12461
+ finalizeAISDKChildTracing(endEvent);
12462
+ return processAISDKOutput(
12463
+ result,
12464
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
12465
+ );
12466
+ },
12467
+ extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
12468
+ aggregateChunks: aggregateAISDKChunks,
12469
+ onComplete: ({ span }) => {
12470
+ unregisterWorkflowAgentWrapperSpan(span);
12471
+ },
12472
+ onError: ({ event, span }) => {
12473
+ finalizeAISDKChildTracing(event);
12474
+ unregisterWorkflowAgentWrapperSpan(span);
12475
+ },
12476
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
12477
+ defaultDenyOutputPaths: denyOutputPaths,
12478
+ endEvent,
12479
+ onComplete: () => unregisterWorkflowAgentWrapperSpan(span),
12480
+ result,
12481
+ span,
12482
+ startTime
12483
+ })
12484
+ })
12485
+ );
11626
12486
  }
11627
12487
  };
11628
12488
  function subscribeToAISDKV7TelemetryDispatcher() {
@@ -11634,7 +12494,11 @@ function subscribeToAISDKV7TelemetryDispatcher() {
11634
12494
  if (telemetryOptions?.isEnabled === false) {
11635
12495
  return;
11636
12496
  }
11637
- patchAISDKV7TelemetryDispatcher(event.result, telemetry);
12497
+ patchAISDKV7TelemetryDispatcher(
12498
+ event.result,
12499
+ telemetry,
12500
+ telemetryOptions
12501
+ );
11638
12502
  }
11639
12503
  };
11640
12504
  channel.subscribe(handlers);
@@ -11642,7 +12506,7 @@ function subscribeToAISDKV7TelemetryDispatcher() {
11642
12506
  channel.unsubscribe(handlers);
11643
12507
  };
11644
12508
  }
11645
- function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry) {
12509
+ function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry, telemetryOptions) {
11646
12510
  if (!isObject(dispatcher)) {
11647
12511
  return;
11648
12512
  }
@@ -11651,6 +12515,54 @@ function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry) {
11651
12515
  return;
11652
12516
  }
11653
12517
  dispatcherRecord[AUTO_PATCHED_V7_TELEMETRY_DISPATCHER] = true;
12518
+ let operationKey;
12519
+ const telemetryEventFields = {};
12520
+ if (typeof telemetryOptions?.recordInputs === "boolean") {
12521
+ telemetryEventFields.recordInputs = telemetryOptions.recordInputs;
12522
+ }
12523
+ if (typeof telemetryOptions?.recordOutputs === "boolean") {
12524
+ telemetryEventFields.recordOutputs = telemetryOptions.recordOutputs;
12525
+ }
12526
+ if (typeof telemetryOptions?.functionId === "string") {
12527
+ telemetryEventFields.functionId = telemetryOptions.functionId;
12528
+ }
12529
+ const eventWithOperationKey = (event) => {
12530
+ if (!isObject(event)) {
12531
+ return event;
12532
+ }
12533
+ const eventRecord = event;
12534
+ const callId = typeof eventRecord.callId === "string" ? eventRecord.callId : "unknown";
12535
+ operationKey ??= `${callId}:${++aiSDKV7TelemetryOperationCounter}`;
12536
+ if (Object.keys(telemetryEventFields).length > 0) {
12537
+ const augmentedEvent = {
12538
+ ...telemetryEventFields,
12539
+ ...event
12540
+ };
12541
+ try {
12542
+ Object.defineProperty(augmentedEvent, BRAINTRUST_AI_SDK_V7_OPERATION_KEY, {
12543
+ configurable: true,
12544
+ enumerable: false,
12545
+ value: operationKey
12546
+ });
12547
+ } catch {
12548
+ augmentedEvent[BRAINTRUST_AI_SDK_V7_OPERATION_KEY] = operationKey;
12549
+ }
12550
+ return augmentedEvent;
12551
+ }
12552
+ try {
12553
+ Object.defineProperty(eventRecord, BRAINTRUST_AI_SDK_V7_OPERATION_KEY, {
12554
+ configurable: true,
12555
+ enumerable: false,
12556
+ value: operationKey
12557
+ });
12558
+ return event;
12559
+ } catch {
12560
+ return {
12561
+ ...event,
12562
+ [BRAINTRUST_AI_SDK_V7_OPERATION_KEY]: operationKey
12563
+ };
12564
+ }
12565
+ };
11654
12566
  for (const key of AI_SDK_V7_TELEMETRY_CALLBACKS) {
11655
12567
  const braintrustCallback = telemetry[key];
11656
12568
  if (typeof braintrustCallback !== "function") {
@@ -11659,11 +12571,17 @@ function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry) {
11659
12571
  const existingCallback = dispatcherRecord[key];
11660
12572
  dispatcherRecord[key] = (event) => {
11661
12573
  const existingResult = typeof existingCallback === "function" ? existingCallback.call(dispatcher, event) : void 0;
11662
- const braintrustResult = braintrustCallback.call(telemetry, event);
11663
- const pending = [existingResult, braintrustResult].filter(isPromiseLike);
11664
- if (pending.length > 0) {
11665
- return Promise.allSettled(pending).then(() => void 0);
12574
+ try {
12575
+ const braintrustResult = braintrustCallback.call(
12576
+ telemetry,
12577
+ eventWithOperationKey(event)
12578
+ );
12579
+ if (isPromiseLike(braintrustResult)) {
12580
+ void Promise.resolve(braintrustResult).catch(() => void 0);
12581
+ }
12582
+ } catch {
11666
12583
  }
12584
+ return existingResult;
11667
12585
  };
11668
12586
  }
11669
12587
  const braintrustExecuteTool = telemetry.executeTool;
@@ -11673,6 +12591,7 @@ function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry) {
11673
12591
  const existingExecuteTool = dispatcherRecord.executeTool;
11674
12592
  dispatcherRecord.executeTool = (args) => braintrustExecuteTool.call(telemetry, {
11675
12593
  ...args,
12594
+ ...operationKey ? { [BRAINTRUST_AI_SDK_V7_OPERATION_KEY]: operationKey } : {},
11676
12595
  execute: () => typeof existingExecuteTool === "function" ? existingExecuteTool.call(dispatcher, args) : args.execute()
11677
12596
  });
11678
12597
  }
@@ -11771,6 +12690,8 @@ var serializeOutputObject = (output, model) => {
11771
12690
  var processInputAttachmentsSync = (input) => {
11772
12691
  if (!input) return { input };
11773
12692
  const processed = { ...input };
12693
+ delete processed.headers;
12694
+ delete processed.experimental_output;
11774
12695
  if (input.messages && Array.isArray(input.messages)) {
11775
12696
  processed.messages = input.messages.map(processMessage);
11776
12697
  }
@@ -11804,10 +12725,10 @@ var processInputAttachmentsSync = (input) => {
11804
12725
  processed.output = serialized;
11805
12726
  }
11806
12727
  }
11807
- if ("prepareCall" in processed && typeof processed.prepareCall === "function") {
11808
- processed.prepareCall = "[Function]";
11809
- }
11810
- return { input: processed, outputPromise };
12728
+ return {
12729
+ input: sanitizeAISDKCallInputValue(processed),
12730
+ outputPromise
12731
+ };
11811
12732
  };
11812
12733
  var processMessage = (message) => {
11813
12734
  if (!message || typeof message !== "object") return message;
@@ -11971,7 +12892,21 @@ var convertDataToAttachment = (data, mimeType, filename) => {
11971
12892
  function processAISDKCallInput(params) {
11972
12893
  return processInputAttachmentsSync(params);
11973
12894
  }
11974
- function prepareAISDKCallInput(params, event, span, defaultDenyOutputPaths) {
12895
+ function processAISDKWorkflowAgentCallInput(params) {
12896
+ const processed = processAISDKCallInput(params);
12897
+ return {
12898
+ ...processed,
12899
+ input: extractWorkflowAgentInput(processed.input)
12900
+ };
12901
+ }
12902
+ function processAISDKWorkflowAgentModelCallInput(params) {
12903
+ const processed = processAISDKCallInput(params);
12904
+ return {
12905
+ ...processed,
12906
+ input: extractWorkflowAgentModelInput(processed.input)
12907
+ };
12908
+ }
12909
+ function prepareAISDKCallInput(params, event, span, defaultDenyOutputPaths, childTracingOptions = {}) {
11975
12910
  const { input, outputPromise } = processAISDKCallInput(params);
11976
12911
  if (outputPromise && input && typeof input === "object") {
11977
12912
  outputPromise.then((resolvedData) => {
@@ -11990,7 +12925,29 @@ function prepareAISDKCallInput(params, event, span, defaultDenyOutputPaths) {
11990
12925
  event.self,
11991
12926
  span,
11992
12927
  defaultDenyOutputPaths,
11993
- event.aiSDK
12928
+ event.aiSDK,
12929
+ childTracingOptions
12930
+ );
12931
+ event.modelWrapped = childTracing.modelWrapped;
12932
+ if (childTracing.cleanup) {
12933
+ event.__braintrust_ai_sdk_cleanup = childTracing.cleanup;
12934
+ }
12935
+ return {
12936
+ input,
12937
+ metadata
12938
+ };
12939
+ }
12940
+ function prepareAISDKWorkflowAgentStreamInput(params, event, span, defaultDenyOutputPaths) {
12941
+ registerWorkflowAgentWrapperSpan(span);
12942
+ const { input } = processAISDKWorkflowAgentCallInput(params);
12943
+ const metadata = extractWorkflowMetadataFromCallParams(params, event.self);
12944
+ const childTracing = prepareAISDKChildTracing(
12945
+ params,
12946
+ event.self,
12947
+ span,
12948
+ defaultDenyOutputPaths,
12949
+ event.aiSDK,
12950
+ { agentOwner: true, workflowAgent: true }
11994
12951
  );
11995
12952
  event.modelWrapped = childTracing.modelWrapped;
11996
12953
  if (childTracing.cleanup) {
@@ -12027,6 +12984,9 @@ function extractTopLevelAISDKMetrics(result, event, startTime) {
12027
12984
  function hasModelChildTracing(event) {
12028
12985
  return event?.modelWrapped === true || event?.__braintrust_ai_sdk_model_wrapped === true;
12029
12986
  }
12987
+ function serializeToolExecutionInput(args) {
12988
+ return args.length > 0 ? args[0] : args;
12989
+ }
12030
12990
  function createAISDKIntegrationMetadata() {
12031
12991
  return {
12032
12992
  braintrust: {
@@ -12038,6 +12998,13 @@ function createAISDKIntegrationMetadata() {
12038
12998
  function resolveModelFromSelf(self) {
12039
12999
  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;
12040
13000
  }
13001
+ function resolveToolsFromSelf(self) {
13002
+ if (!self || typeof self !== "object") {
13003
+ return void 0;
13004
+ }
13005
+ const selfRecord = self;
13006
+ return selfRecord.tools ?? selfRecord.settings?.tools;
13007
+ }
12041
13008
  function extractBaseMetadata(model, self) {
12042
13009
  const metadata = createAISDKIntegrationMetadata();
12043
13010
  const { model: modelId, provider } = serializeModelWithProvider(
@@ -12053,12 +13020,175 @@ function extractBaseMetadata(model, self) {
12053
13020
  }
12054
13021
  function extractMetadataFromCallParams(params, self) {
12055
13022
  const metadata = extractBaseMetadata(params.model, self);
12056
- const tools = serializeAISDKToolsForLogging(params.tools);
13023
+ const tools = serializeAISDKToolsForLogging(
13024
+ params.tools ?? resolveToolsFromSelf(self)
13025
+ );
12057
13026
  if (tools) {
12058
13027
  metadata.tools = tools;
12059
13028
  }
12060
13029
  return metadata;
12061
13030
  }
13031
+ function extractWorkflowMetadataFromCallParams(params, self) {
13032
+ const metadata = extractMetadataFromCallParams(params, self);
13033
+ const options = extractAISDKCallOptionsForMetadata(params);
13034
+ if (Object.keys(options).length > 0) {
13035
+ metadata.options = options;
13036
+ }
13037
+ return metadata;
13038
+ }
13039
+ function extractWorkflowAgentInput(params) {
13040
+ const input = {};
13041
+ if (params.instructions !== void 0) {
13042
+ input.instructions = params.instructions;
13043
+ }
13044
+ if (params.system !== void 0) {
13045
+ input.system = params.system;
13046
+ }
13047
+ if (Array.isArray(params.messages)) {
13048
+ return { ...input, messages: params.messages };
13049
+ }
13050
+ if (typeof params.prompt === "string") {
13051
+ return { ...input, prompt: params.prompt };
13052
+ }
13053
+ if (Array.isArray(params.prompt)) {
13054
+ return { ...input, prompt: params.prompt };
13055
+ }
13056
+ return input;
13057
+ }
13058
+ function extractWorkflowAgentModelInput(params) {
13059
+ const input = {};
13060
+ if (params.instructions !== void 0) {
13061
+ input.instructions = params.instructions;
13062
+ }
13063
+ if (params.system !== void 0) {
13064
+ input.system = params.system;
13065
+ }
13066
+ if (Array.isArray(params.messages)) {
13067
+ return { ...input, messages: params.messages };
13068
+ }
13069
+ if (typeof params.prompt === "string") {
13070
+ return { ...input, prompt: params.prompt };
13071
+ }
13072
+ if (Array.isArray(params.prompt)) {
13073
+ return { ...input, messages: params.prompt };
13074
+ }
13075
+ return input;
13076
+ }
13077
+ function sanitizeAISDKCallInputValue(value, depth = 0) {
13078
+ if (value === void 0 || typeof value === "function") {
13079
+ return void 0;
13080
+ }
13081
+ if (value === null || typeof value !== "object") {
13082
+ return value;
13083
+ }
13084
+ if (isPromiseLike(value)) {
13085
+ return "[Promise]";
13086
+ }
13087
+ if (typeof AbortSignal !== "undefined" && value instanceof AbortSignal) {
13088
+ return "[AbortSignal]";
13089
+ }
13090
+ if (depth >= 8) {
13091
+ return "[Object]";
13092
+ }
13093
+ if (Array.isArray(value)) {
13094
+ return value.map((item) => sanitizeAISDKCallInputValue(item, depth + 1)).filter((item) => item !== void 0);
13095
+ }
13096
+ if (!isObject(value)) {
13097
+ return value;
13098
+ }
13099
+ const prototype = Object.getPrototypeOf(value);
13100
+ if (prototype !== Object.prototype && prototype !== null) {
13101
+ return value;
13102
+ }
13103
+ const sanitized = {};
13104
+ for (const [key, nested] of Object.entries(value)) {
13105
+ if (key === "__proto__" || key === "constructor" || key === "prototype" || key.toLowerCase() === "headers") {
13106
+ continue;
13107
+ }
13108
+ const sanitizedNested = sanitizeAISDKCallInputValue(nested, depth + 1);
13109
+ if (sanitizedNested !== void 0) {
13110
+ sanitized[key] = sanitizedNested;
13111
+ }
13112
+ }
13113
+ return sanitized;
13114
+ }
13115
+ function extractAISDKCallOptionsForMetadata(params) {
13116
+ const options = {};
13117
+ const inputOrTopLevelKeys = /* @__PURE__ */ new Set([
13118
+ "model",
13119
+ "instructions",
13120
+ "messages",
13121
+ "prompt",
13122
+ "system",
13123
+ "tools",
13124
+ "headers",
13125
+ "abortSignal",
13126
+ "signal",
13127
+ "experimental_output"
13128
+ ]);
13129
+ for (const [key, value] of Object.entries(params)) {
13130
+ if (inputOrTopLevelKeys.has(key) || key === "__proto__" || key === "constructor" || key === "prototype" || /^on[A-Z]/.test(key) && typeof value === "function") {
13131
+ continue;
13132
+ }
13133
+ const sanitized = sanitizeAISDKMetadataValue(value);
13134
+ if (sanitized !== void 0) {
13135
+ options[key] = sanitized;
13136
+ }
13137
+ }
13138
+ return options;
13139
+ }
13140
+ function sanitizeAISDKMetadataValue(value, depth = 0) {
13141
+ if (value === void 0) {
13142
+ return void 0;
13143
+ }
13144
+ if (typeof value === "function") {
13145
+ return "[Function]";
13146
+ }
13147
+ if (value === null || typeof value !== "object") {
13148
+ return value;
13149
+ }
13150
+ if (isPromiseLike(value)) {
13151
+ return "[Promise]";
13152
+ }
13153
+ if (typeof AbortSignal !== "undefined" && value instanceof AbortSignal) {
13154
+ return "[AbortSignal]";
13155
+ }
13156
+ if (depth >= 8) {
13157
+ return "[Object]";
13158
+ }
13159
+ if (Array.isArray(value)) {
13160
+ return value.map((item) => sanitizeAISDKMetadataValue(item, depth + 1)).filter((item) => item !== void 0);
13161
+ }
13162
+ if (!isObject(value)) {
13163
+ return value;
13164
+ }
13165
+ const sanitized = {};
13166
+ for (const [key, nested] of Object.entries(value)) {
13167
+ if (key === "__proto__" || key === "constructor" || key === "prototype" || key.toLowerCase() === "headers") {
13168
+ continue;
13169
+ }
13170
+ const sanitizedNested = sanitizeAISDKMetadataValue(nested, depth + 1);
13171
+ if (sanitizedNested !== void 0) {
13172
+ sanitized[key] = sanitizedNested;
13173
+ }
13174
+ }
13175
+ return sanitized;
13176
+ }
13177
+ function buildAISDKModelStartEvent(callOptions, baseMetadata, options) {
13178
+ if (!options.workflowAgent) {
13179
+ return {
13180
+ input: processAISDKCallInput(callOptions).input,
13181
+ metadata: baseMetadata
13182
+ };
13183
+ }
13184
+ return {
13185
+ input: processAISDKWorkflowAgentModelCallInput(callOptions).input,
13186
+ metadata: {
13187
+ ...baseMetadata,
13188
+ ...extractWorkflowMetadataFromCallParams(callOptions)
13189
+ }
13190
+ };
13191
+ }
12062
13192
  function extractMetadataFromEmbedParams(params, self) {
12063
13193
  return extractBaseMetadata(params.model, self);
12064
13194
  }
@@ -12072,65 +13202,228 @@ function extractMetadataFromRerankParams(params, self) {
12072
13202
  }
12073
13203
  return metadata;
12074
13204
  }
12075
- function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiSDK) {
13205
+ function activeAISDKChildPatchEntry(entries) {
13206
+ const activeSpan = currentSpan();
13207
+ const activeSpanId = activeSpan.spanId;
13208
+ if (activeSpanId) {
13209
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
13210
+ const entry = entries[index];
13211
+ if (entry?.activeSpanIds.has(activeSpanId)) {
13212
+ return entry;
13213
+ }
13214
+ }
13215
+ }
13216
+ const activeParentSpanIds = activeSpan.spanParents ?? [];
13217
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
13218
+ const entry = entries[index];
13219
+ if (entry?.parentSpan.spanId && activeParentSpanIds.includes(entry.parentSpan.spanId)) {
13220
+ return entry;
13221
+ }
13222
+ }
13223
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
13224
+ const entry = entries[index];
13225
+ if (entry?.parentSpan.spanId === activeSpanId) {
13226
+ return entry;
13227
+ }
13228
+ }
13229
+ return entries[entries.length - 1];
13230
+ }
13231
+ function attachNestedAISDKChildPatchEntry(entries, nestedSpan, cleanup) {
13232
+ const activeSpanId = currentSpan().spanId;
13233
+ if (!activeSpanId || activeSpanId === nestedSpan.spanId) {
13234
+ return false;
13235
+ }
13236
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
13237
+ const entry = entries[index];
13238
+ if (entry?.parentSpan.spanId === activeSpanId || entry?.activeSpanIds.has(activeSpanId)) {
13239
+ entry.activeSpanIds.add(nestedSpan.spanId);
13240
+ cleanup.push(() => {
13241
+ entry.activeSpanIds.delete(nestedSpan.spanId);
13242
+ });
13243
+ return true;
13244
+ }
13245
+ }
13246
+ return false;
13247
+ }
13248
+ function shadowActiveAISDKChildPatchEntry(entries, entry, nestedSpan, cleanup) {
13249
+ const activeSpanId = currentSpan().spanId;
13250
+ if (!activeSpanId || activeSpanId === nestedSpan.spanId) {
13251
+ return;
13252
+ }
13253
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
13254
+ const existingEntry = entries[index];
13255
+ if (existingEntry?.parentSpan.spanId === activeSpanId || existingEntry?.activeSpanIds.has(activeSpanId)) {
13256
+ entry.activeSpanIds.add(activeSpanId);
13257
+ cleanup.push(() => {
13258
+ entry.activeSpanIds.delete(activeSpanId);
13259
+ });
13260
+ return;
13261
+ }
13262
+ }
13263
+ }
13264
+ function closeOpenAISDKModelPatchSpans(entry) {
13265
+ for (const span of entry.openSpans) {
13266
+ span.end();
13267
+ }
13268
+ entry.openSpans.clear();
13269
+ }
13270
+ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiSDK, childTracingOptions = {}) {
12076
13271
  const cleanup = [];
12077
- const patchedModels = /* @__PURE__ */ new WeakSet();
13272
+ const patchedModels = /* @__PURE__ */ new WeakMap();
12078
13273
  const patchedTools = /* @__PURE__ */ new WeakSet();
12079
13274
  let modelWrapped = false;
12080
13275
  const patchModel = (model) => {
12081
13276
  const resolvedModel = resolveAISDKModel(model, aiSDK);
12082
- if (!resolvedModel || typeof resolvedModel !== "object" || typeof resolvedModel.doGenerate !== "function" || patchedModels.has(resolvedModel) || resolvedModel[AUTO_PATCHED_MODEL]) {
13277
+ if (!resolvedModel || typeof resolvedModel !== "object" || typeof resolvedModel.doGenerate !== "function") {
12083
13278
  return resolvedModel;
12084
13279
  }
12085
- patchedModels.add(resolvedModel);
12086
- resolvedModel[AUTO_PATCHED_MODEL] = true;
13280
+ const existingWrappedModel = patchedModels.get(resolvedModel);
13281
+ if (existingWrappedModel) {
13282
+ modelWrapped = true;
13283
+ return existingWrappedModel;
13284
+ }
12087
13285
  modelWrapped = true;
13286
+ const modelRecord = resolvedModel;
13287
+ const entry = {
13288
+ activeSpanIds: /* @__PURE__ */ new Set([parentSpan.spanId]),
13289
+ baseMetadata: buildAISDKChildMetadata(resolvedModel),
13290
+ childTracingOptions,
13291
+ denyOutputPaths,
13292
+ openSpans: /* @__PURE__ */ new Set(),
13293
+ parentSpan
13294
+ };
13295
+ const cleanupModelEntry = (state2, patchedModel) => {
13296
+ closeOpenAISDKModelPatchSpans(entry);
13297
+ const index = state2.entries.indexOf(entry);
13298
+ if (index >= 0) {
13299
+ state2.entries.splice(index, 1);
13300
+ }
13301
+ if (state2.entries.length > 0) {
13302
+ return;
13303
+ }
13304
+ patchedModel.doGenerate = state2.originalDoGenerate;
13305
+ patchedModel.doStream = state2.originalDoStream;
13306
+ delete patchedModel[AUTO_PATCHED_MODEL];
13307
+ };
13308
+ const existingState = modelRecord[AUTO_PATCHED_MODEL];
13309
+ if (existingState) {
13310
+ patchedModels.set(resolvedModel, resolvedModel);
13311
+ if (childTracingOptions.agentOwner && attachNestedAISDKChildPatchEntry(
13312
+ existingState.entries,
13313
+ parentSpan,
13314
+ cleanup
13315
+ )) {
13316
+ return resolvedModel;
13317
+ }
13318
+ if (!childTracingOptions.agentOwner) {
13319
+ shadowActiveAISDKChildPatchEntry(
13320
+ existingState.entries,
13321
+ entry,
13322
+ parentSpan,
13323
+ cleanup
13324
+ );
13325
+ }
13326
+ existingState.entries.push(entry);
13327
+ cleanup.push(() => {
13328
+ cleanupModelEntry(existingState, modelRecord);
13329
+ });
13330
+ return resolvedModel;
13331
+ }
12088
13332
  const originalDoGenerate = resolvedModel.doGenerate;
12089
13333
  const originalDoStream = resolvedModel.doStream;
12090
- const baseMetadata = buildAISDKChildMetadata(resolvedModel);
12091
- resolvedModel.doGenerate = async function doGeneratePatched(options) {
12092
- return parentSpan.traced(
13334
+ const wrappedModel = Object.create(
13335
+ Object.getPrototypeOf(resolvedModel)
13336
+ );
13337
+ Object.defineProperties(
13338
+ wrappedModel,
13339
+ Object.getOwnPropertyDescriptors(resolvedModel)
13340
+ );
13341
+ const wrappedModelRecord = wrappedModel;
13342
+ const state = {
13343
+ entries: [entry],
13344
+ originalDoGenerate,
13345
+ originalDoStream
13346
+ };
13347
+ Object.defineProperty(wrappedModel, AUTO_PATCHED_MODEL, {
13348
+ configurable: true,
13349
+ value: state
13350
+ });
13351
+ wrappedModel.doGenerate = async function doGeneratePatched(callOptions) {
13352
+ const activeEntry = activeAISDKChildPatchEntry(state.entries);
13353
+ if (!activeEntry) {
13354
+ return Reflect.apply(originalDoGenerate, resolvedModel, [callOptions]);
13355
+ }
13356
+ closeOpenAISDKModelPatchSpans(activeEntry);
13357
+ return activeEntry.parentSpan.traced(
12093
13358
  async (span) => {
12094
- const result = await Reflect.apply(
12095
- originalDoGenerate,
12096
- resolvedModel,
12097
- [options]
12098
- );
12099
- span.log({
12100
- output: processAISDKOutput(result, denyOutputPaths),
12101
- metrics: extractTokenMetrics(result),
12102
- ...buildResolvedMetadataPayload(result)
12103
- });
12104
- return result;
13359
+ activeEntry.openSpans.add(span);
13360
+ try {
13361
+ const result = await Reflect.apply(
13362
+ originalDoGenerate,
13363
+ resolvedModel,
13364
+ [callOptions]
13365
+ );
13366
+ const output = processAISDKOutput(
13367
+ result,
13368
+ activeEntry.denyOutputPaths
13369
+ );
13370
+ const metrics = extractTokenMetrics(result);
13371
+ const metadataPayload = buildResolvedMetadataPayload(result);
13372
+ const missingUsageMetadata = buildMissingUsageMetadata(
13373
+ output,
13374
+ metrics,
13375
+ "ai_sdk_result_missing_usage"
13376
+ );
13377
+ span.log({
13378
+ output,
13379
+ metrics,
13380
+ ...mergeMetadataPayload(metadataPayload, missingUsageMetadata)
13381
+ });
13382
+ return result;
13383
+ } finally {
13384
+ activeEntry.openSpans.delete(span);
13385
+ }
12105
13386
  },
12106
13387
  {
12107
13388
  name: "doGenerate",
12108
13389
  spanAttributes: {
12109
13390
  type: "llm" /* LLM */
12110
13391
  },
12111
- event: {
12112
- input: processAISDKCallInput(options).input,
12113
- metadata: baseMetadata
12114
- }
13392
+ event: buildAISDKModelStartEvent(
13393
+ callOptions,
13394
+ activeEntry.baseMetadata,
13395
+ {
13396
+ workflowAgent: activeEntry.childTracingOptions.workflowAgent
13397
+ }
13398
+ )
12115
13399
  }
12116
13400
  );
12117
13401
  };
12118
13402
  if (originalDoStream) {
12119
- resolvedModel.doStream = async function doStreamPatched(options) {
12120
- const span = parentSpan.startSpan({
13403
+ wrappedModel.doStream = async function doStreamPatched(callOptions) {
13404
+ const activeEntry = activeAISDKChildPatchEntry(state.entries);
13405
+ if (!activeEntry) {
13406
+ return Reflect.apply(originalDoStream, resolvedModel, [callOptions]);
13407
+ }
13408
+ closeOpenAISDKModelPatchSpans(activeEntry);
13409
+ const span = activeEntry.parentSpan.startSpan({
12121
13410
  name: "doStream",
12122
13411
  spanAttributes: {
12123
13412
  type: "llm" /* LLM */
12124
13413
  },
12125
- event: {
12126
- input: processAISDKCallInput(options).input,
12127
- metadata: baseMetadata
12128
- }
13414
+ event: buildAISDKModelStartEvent(
13415
+ callOptions,
13416
+ activeEntry.baseMetadata,
13417
+ {
13418
+ workflowAgent: activeEntry.childTracingOptions.workflowAgent
13419
+ }
13420
+ )
12129
13421
  });
13422
+ activeEntry.openSpans.add(span);
12130
13423
  const streamStartTime = getCurrentUnixTimestamp();
12131
13424
  const result = await withCurrent(
12132
13425
  span,
12133
- () => Reflect.apply(originalDoStream, resolvedModel, [options])
13426
+ () => Reflect.apply(originalDoStream, resolvedModel, [callOptions])
12134
13427
  );
12135
13428
  let firstChunkTime;
12136
13429
  const output = {};
@@ -12138,6 +13431,44 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
12138
13431
  let reasoning = "";
12139
13432
  const toolCalls = [];
12140
13433
  let object = void 0;
13434
+ let streamSpanEnded = false;
13435
+ const logAndEndStreamSpan = (usageUnavailableReason) => {
13436
+ if (streamSpanEnded) {
13437
+ return;
13438
+ }
13439
+ output.text = text;
13440
+ output.reasoning = reasoning;
13441
+ output.toolCalls = toolCalls;
13442
+ if (object !== void 0) {
13443
+ output.object = object;
13444
+ }
13445
+ const metrics = extractTokenMetrics(output);
13446
+ if (firstChunkTime !== void 0 && !activeEntry.childTracingOptions.workflowAgent) {
13447
+ metrics.time_to_first_token = Math.max(
13448
+ firstChunkTime - streamStartTime,
13449
+ 1e-6
13450
+ );
13451
+ }
13452
+ const metadataPayload = buildResolvedMetadataPayload(
13453
+ output
13454
+ );
13455
+ const missingUsageMetadata = usageUnavailableReason ? { usage_unavailable_reason: usageUnavailableReason } : buildMissingUsageMetadata(
13456
+ output,
13457
+ metrics,
13458
+ "ai_sdk_result_missing_usage"
13459
+ );
13460
+ span.log({
13461
+ output: processAISDKOutput(
13462
+ output,
13463
+ activeEntry.denyOutputPaths
13464
+ ),
13465
+ metrics,
13466
+ ...mergeMetadataPayload(metadataPayload, missingUsageMetadata)
13467
+ });
13468
+ activeEntry.openSpans.delete(span);
13469
+ span.end();
13470
+ streamSpanEnded = true;
13471
+ };
12141
13472
  const transformStream = new TransformStream({
12142
13473
  transform(chunk, controller) {
12143
13474
  if (firstChunkTime === void 0 && isAISDKContentStreamChunk(chunk)) {
@@ -12175,33 +13506,15 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
12175
13506
  }
12176
13507
  break;
12177
13508
  case "finish":
12178
- output.text = text;
12179
- output.reasoning = reasoning;
12180
- output.toolCalls = toolCalls;
12181
13509
  output.finishReason = chunk.finishReason;
12182
13510
  output.usage = chunk.usage;
12183
- if (object !== void 0) {
12184
- output.object = object;
12185
- }
12186
- const metrics = extractTokenMetrics(output);
12187
- if (firstChunkTime !== void 0) {
12188
- metrics.time_to_first_token = Math.max(
12189
- firstChunkTime - streamStartTime,
12190
- 1e-6
12191
- );
12192
- }
12193
- span.log({
12194
- output: processAISDKOutput(
12195
- output,
12196
- denyOutputPaths
12197
- ),
12198
- metrics,
12199
- ...buildResolvedMetadataPayload(output)
12200
- });
12201
- span.end();
13511
+ logAndEndStreamSpan();
12202
13512
  break;
12203
13513
  }
12204
13514
  controller.enqueue(chunk);
13515
+ },
13516
+ flush() {
13517
+ logAndEndStreamSpan("ai_sdk_stream_finished_without_usage");
12205
13518
  }
12206
13519
  });
12207
13520
  return {
@@ -12211,32 +13524,79 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
12211
13524
  };
12212
13525
  }
12213
13526
  cleanup.push(() => {
12214
- resolvedModel.doGenerate = originalDoGenerate;
12215
- if (originalDoStream) {
12216
- resolvedModel.doStream = originalDoStream;
12217
- }
12218
- delete resolvedModel[AUTO_PATCHED_MODEL];
13527
+ cleanupModelEntry(state, wrappedModelRecord);
12219
13528
  });
12220
- return resolvedModel;
13529
+ patchedModels.set(resolvedModel, wrappedModel);
13530
+ patchedModels.set(wrappedModel, wrappedModel);
13531
+ return wrappedModel;
12221
13532
  };
12222
13533
  const patchTool = (tool, name) => {
12223
- if (tool == null || typeof tool !== "object" || !("execute" in tool) || typeof tool.execute !== "function" || patchedTools.has(tool) || tool[AUTO_PATCHED_TOOL]) {
13534
+ if (tool == null || typeof tool !== "object" || !("execute" in tool) || typeof tool.execute !== "function" || patchedTools.has(tool)) {
12224
13535
  return;
12225
13536
  }
12226
13537
  patchedTools.add(tool);
12227
- tool[AUTO_PATCHED_TOOL] = true;
12228
- const originalExecute = tool.execute;
13538
+ const toolRecord = tool;
13539
+ const entry = {
13540
+ activeSpanIds: /* @__PURE__ */ new Set([parentSpan.spanId]),
13541
+ childTracingOptions,
13542
+ name,
13543
+ parentSpan
13544
+ };
13545
+ const cleanupToolEntry = (state2) => {
13546
+ const index = state2.entries.indexOf(entry);
13547
+ if (index >= 0) {
13548
+ state2.entries.splice(index, 1);
13549
+ }
13550
+ if (state2.entries.length > 0) {
13551
+ return;
13552
+ }
13553
+ tool.execute = state2.originalExecute;
13554
+ delete toolRecord[AUTO_PATCHED_TOOL];
13555
+ };
13556
+ const existingState = toolRecord[AUTO_PATCHED_TOOL];
13557
+ if (existingState) {
13558
+ if (childTracingOptions.agentOwner && attachNestedAISDKChildPatchEntry(
13559
+ existingState.entries,
13560
+ parentSpan,
13561
+ cleanup
13562
+ )) {
13563
+ return;
13564
+ }
13565
+ if (!childTracingOptions.agentOwner) {
13566
+ shadowActiveAISDKChildPatchEntry(
13567
+ existingState.entries,
13568
+ entry,
13569
+ parentSpan,
13570
+ cleanup
13571
+ );
13572
+ }
13573
+ existingState.entries.push(entry);
13574
+ cleanup.push(() => {
13575
+ cleanupToolEntry(existingState);
13576
+ });
13577
+ return;
13578
+ }
13579
+ const originalExecute = toolRecord.execute;
13580
+ const state = {
13581
+ entries: [entry],
13582
+ originalExecute
13583
+ };
13584
+ toolRecord[AUTO_PATCHED_TOOL] = state;
12229
13585
  tool.execute = function executePatched(...args) {
13586
+ const activeEntry = activeAISDKChildPatchEntry(state.entries);
12230
13587
  const result = Reflect.apply(originalExecute, this, args);
13588
+ if (!activeEntry) {
13589
+ return result;
13590
+ }
12231
13591
  if (isAsyncGenerator(result)) {
12232
13592
  return (async function* () {
12233
- const span = parentSpan.startSpan({
12234
- name,
13593
+ const span = activeEntry.parentSpan.startSpan({
13594
+ name: activeEntry.name,
12235
13595
  spanAttributes: {
12236
13596
  type: "tool" /* TOOL */
12237
13597
  }
12238
13598
  });
12239
- span.log({ input: args.length === 1 ? args[0] : args });
13599
+ span.log({ input: serializeToolExecutionInput(args) });
12240
13600
  try {
12241
13601
  let lastValue;
12242
13602
  for await (const value of result) {
@@ -12252,15 +13612,15 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
12252
13612
  }
12253
13613
  })();
12254
13614
  }
12255
- return parentSpan.traced(
13615
+ return activeEntry.parentSpan.traced(
12256
13616
  async (span) => {
12257
- span.log({ input: args.length === 1 ? args[0] : args });
13617
+ span.log({ input: serializeToolExecutionInput(args) });
12258
13618
  const awaitedResult = await result;
12259
13619
  span.log({ output: awaitedResult });
12260
13620
  return awaitedResult;
12261
13621
  },
12262
13622
  {
12263
- name,
13623
+ name: activeEntry.name,
12264
13624
  spanAttributes: {
12265
13625
  type: "tool" /* TOOL */
12266
13626
  }
@@ -12268,8 +13628,7 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
12268
13628
  );
12269
13629
  };
12270
13630
  cleanup.push(() => {
12271
- tool.execute = originalExecute;
12272
- delete tool[AUTO_PATCHED_TOOL];
13631
+ cleanupToolEntry(state);
12273
13632
  });
12274
13633
  };
12275
13634
  const patchTools = (tools) => {
@@ -12288,25 +13647,42 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
12288
13647
  }
12289
13648
  };
12290
13649
  if (params && typeof params === "object") {
12291
- const patchedParamModel = patchModel(params.model);
12292
- if (typeof params.model === "string" && patchedParamModel && typeof patchedParamModel === "object") {
13650
+ const originalParamModel = params.model;
13651
+ const patchedParamModel = patchModel(originalParamModel);
13652
+ if (patchedParamModel && patchedParamModel !== originalParamModel) {
12293
13653
  params.model = patchedParamModel;
13654
+ cleanup.push(() => {
13655
+ params.model = originalParamModel;
13656
+ });
12294
13657
  }
12295
13658
  patchTools(params.tools);
12296
13659
  }
12297
13660
  if (self && typeof self === "object") {
12298
13661
  const selfRecord = self;
12299
13662
  if (selfRecord.model !== void 0) {
12300
- const patchedSelfModel = patchModel(selfRecord.model);
12301
- if (typeof selfRecord.model === "string" && patchedSelfModel && typeof patchedSelfModel === "object") {
13663
+ const originalSelfModel = selfRecord.model;
13664
+ const patchedSelfModel = patchModel(originalSelfModel);
13665
+ if (patchedSelfModel && patchedSelfModel !== originalSelfModel) {
12302
13666
  selfRecord.model = patchedSelfModel;
13667
+ cleanup.push(() => {
13668
+ selfRecord.model = originalSelfModel;
13669
+ });
12303
13670
  }
12304
13671
  }
13672
+ if (selfRecord.tools !== void 0) {
13673
+ patchTools(selfRecord.tools);
13674
+ }
12305
13675
  if (selfRecord.settings && typeof selfRecord.settings === "object") {
12306
13676
  if (selfRecord.settings.model !== void 0) {
12307
- const patchedSettingsModel = patchModel(selfRecord.settings.model);
12308
- if (typeof selfRecord.settings.model === "string" && patchedSettingsModel && typeof patchedSettingsModel === "object") {
13677
+ const originalSettingsModel = selfRecord.settings.model;
13678
+ const patchedSettingsModel = patchModel(originalSettingsModel);
13679
+ if (patchedSettingsModel && patchedSettingsModel !== originalSettingsModel) {
12309
13680
  selfRecord.settings.model = patchedSettingsModel;
13681
+ cleanup.push(() => {
13682
+ if (selfRecord.settings) {
13683
+ selfRecord.settings.model = originalSettingsModel;
13684
+ }
13685
+ });
12310
13686
  }
12311
13687
  }
12312
13688
  if (selfRecord.settings.tools !== void 0) {
@@ -12403,99 +13779,190 @@ function isAISDKContentAsyncIterableChunk(chunk) {
12403
13779
  return isObject(part) && typeof part.type !== "string";
12404
13780
  }
12405
13781
  function patchAISDKStreamingResult(args) {
12406
- const { defaultDenyOutputPaths, endEvent, result, span, startTime } = args;
13782
+ const {
13783
+ defaultDenyOutputPaths,
13784
+ endEvent,
13785
+ onComplete,
13786
+ result,
13787
+ span,
13788
+ startTime
13789
+ } = args;
12407
13790
  if (!result || typeof result !== "object") {
12408
13791
  return false;
12409
13792
  }
12410
13793
  const resultRecord = result;
12411
13794
  attachKnownResultPromiseHandlers(resultRecord);
13795
+ let finalized = false;
13796
+ const finalize = () => {
13797
+ if (finalized) {
13798
+ return;
13799
+ }
13800
+ finalized = true;
13801
+ finalizeAISDKChildTracing(endEvent);
13802
+ span.end();
13803
+ onComplete?.();
13804
+ };
13805
+ let outputLogged = false;
13806
+ const logStreamingOutput = async (firstChunkTime) => {
13807
+ if (outputLogged) {
13808
+ return;
13809
+ }
13810
+ outputLogged = true;
13811
+ try {
13812
+ const metrics = extractTopLevelAISDKMetrics(result, endEvent);
13813
+ if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
13814
+ metrics.time_to_first_token = firstChunkTime - startTime;
13815
+ }
13816
+ const output = await processAISDKStreamingOutput(
13817
+ result,
13818
+ resolveDenyOutputPaths(endEvent, defaultDenyOutputPaths)
13819
+ );
13820
+ const metadata = buildResolvedMetadataPayload(result).metadata;
13821
+ span.log({
13822
+ output,
13823
+ ...metadata ? { metadata } : {},
13824
+ metrics
13825
+ });
13826
+ } catch (error) {
13827
+ span.log({ error: toLoggedError(error) });
13828
+ } finally {
13829
+ finalize();
13830
+ }
13831
+ };
13832
+ const createAsyncIterableHooks = () => {
13833
+ let firstChunkTime;
13834
+ return {
13835
+ onChunk: (chunk) => {
13836
+ if (firstChunkTime === void 0 && isAISDKContentAsyncIterableChunk(chunk)) {
13837
+ firstChunkTime = getCurrentUnixTimestamp();
13838
+ }
13839
+ },
13840
+ onComplete: async () => {
13841
+ await logStreamingOutput(firstChunkTime);
13842
+ },
13843
+ onError: (error) => {
13844
+ if (!outputLogged) {
13845
+ outputLogged = true;
13846
+ span.log({
13847
+ error: error.message
13848
+ });
13849
+ }
13850
+ finalize();
13851
+ },
13852
+ onCancel: finalize
13853
+ };
13854
+ };
13855
+ const patchAsyncIterable = (stream) => isReadableStreamLike(stream) ? createPatchedReadableStream(stream, createAsyncIterableHooks()) : createPatchedAsyncIterable(stream, createAsyncIterableHooks());
13856
+ const patchAsyncIterableField = (field) => {
13857
+ let descriptorOwner = resultRecord;
13858
+ let descriptor;
13859
+ while (descriptorOwner) {
13860
+ descriptor = Object.getOwnPropertyDescriptor(descriptorOwner, field);
13861
+ if (descriptor) {
13862
+ break;
13863
+ }
13864
+ descriptorOwner = Object.getPrototypeOf(descriptorOwner);
13865
+ }
13866
+ if (!descriptor || descriptorOwner === resultRecord && !descriptor.configurable) {
13867
+ return false;
13868
+ }
13869
+ if ("value" in descriptor) {
13870
+ if (!isAsyncIterable(descriptor.value)) {
13871
+ return false;
13872
+ }
13873
+ try {
13874
+ Object.defineProperty(resultRecord, field, {
13875
+ configurable: descriptorOwner === resultRecord ? descriptor.configurable : true,
13876
+ enumerable: descriptor.enumerable,
13877
+ value: patchAsyncIterable(descriptor.value),
13878
+ writable: descriptor.writable
13879
+ });
13880
+ return true;
13881
+ } catch {
13882
+ return false;
13883
+ }
13884
+ }
13885
+ if (typeof descriptor.get !== "function") {
13886
+ return false;
13887
+ }
13888
+ const originalGet = descriptor.get;
13889
+ const originalSet = descriptor.set;
13890
+ try {
13891
+ Object.defineProperty(resultRecord, field, {
13892
+ configurable: descriptorOwner === resultRecord ? descriptor.configurable : true,
13893
+ enumerable: descriptor.enumerable,
13894
+ get() {
13895
+ const stream = originalGet.call(this);
13896
+ return isAsyncIterable(stream) ? patchAsyncIterable(stream) : stream;
13897
+ },
13898
+ ...originalSet ? {
13899
+ set(value) {
13900
+ originalSet.call(this, value);
13901
+ }
13902
+ } : {}
13903
+ });
13904
+ return true;
13905
+ } catch {
13906
+ return false;
13907
+ }
13908
+ };
13909
+ let patched = false;
12412
13910
  if (isReadableStreamLike(resultRecord.baseStream)) {
12413
- let firstChunkTime2;
12414
- const wrappedBaseStream = resultRecord.baseStream.pipeThrough(
13911
+ let firstChunkTime;
13912
+ const transformedBaseStream = resultRecord.baseStream.pipeThrough(
12415
13913
  new TransformStream({
12416
13914
  transform(chunk, controller) {
12417
- if (firstChunkTime2 === void 0 && isAISDKContentStreamChunk(chunk)) {
12418
- firstChunkTime2 = getCurrentUnixTimestamp();
13915
+ if (firstChunkTime === void 0 && isAISDKContentStreamChunk(chunk)) {
13916
+ firstChunkTime = getCurrentUnixTimestamp();
12419
13917
  }
12420
13918
  controller.enqueue(chunk);
12421
13919
  },
12422
13920
  async flush() {
12423
- const metrics = extractTopLevelAISDKMetrics(result, endEvent);
12424
- if (metrics.time_to_first_token === void 0 && firstChunkTime2 !== void 0) {
12425
- metrics.time_to_first_token = firstChunkTime2 - startTime;
12426
- }
12427
- const output = await processAISDKStreamingOutput(
12428
- result,
12429
- resolveDenyOutputPaths(endEvent, defaultDenyOutputPaths)
12430
- );
12431
- const metadata = buildResolvedMetadataPayload(result).metadata;
12432
- span.log({
12433
- output,
12434
- ...metadata ? { metadata } : {},
12435
- metrics
12436
- });
12437
- finalizeAISDKChildTracing(endEvent);
12438
- span.end();
13921
+ await logStreamingOutput(firstChunkTime);
12439
13922
  }
12440
13923
  })
12441
13924
  );
13925
+ const reader = transformedBaseStream.getReader();
13926
+ const wrappedBaseStream = new ReadableStream({
13927
+ async pull(controller) {
13928
+ try {
13929
+ const { done, value } = await reader.read();
13930
+ if (done) {
13931
+ controller.close();
13932
+ return;
13933
+ }
13934
+ controller.enqueue(value);
13935
+ } catch (error) {
13936
+ span.log({ error: toLoggedError(error) });
13937
+ finalize();
13938
+ controller.error(error);
13939
+ }
13940
+ },
13941
+ async cancel(reason) {
13942
+ try {
13943
+ finalize();
13944
+ } finally {
13945
+ await reader.cancel(reason);
13946
+ }
13947
+ }
13948
+ });
12442
13949
  Object.defineProperty(resultRecord, "baseStream", {
12443
13950
  configurable: true,
12444
13951
  enumerable: true,
12445
13952
  value: wrappedBaseStream,
12446
13953
  writable: true
12447
13954
  });
12448
- return true;
13955
+ patched = true;
12449
13956
  }
12450
- const streamField = findAsyncIterableField(resultRecord, [
13957
+ for (const field of [
12451
13958
  "partialObjectStream",
12452
13959
  "textStream",
12453
13960
  "fullStream",
12454
13961
  "stream"
12455
- ]);
12456
- if (!streamField) {
12457
- return false;
13962
+ ]) {
13963
+ patched = patchAsyncIterableField(field) || patched;
12458
13964
  }
12459
- let firstChunkTime;
12460
- const wrappedStream = createPatchedAsyncIterable(streamField.stream, {
12461
- onChunk: (chunk) => {
12462
- if (firstChunkTime === void 0 && isAISDKContentAsyncIterableChunk(chunk)) {
12463
- firstChunkTime = getCurrentUnixTimestamp();
12464
- }
12465
- },
12466
- onComplete: async () => {
12467
- const metrics = extractTopLevelAISDKMetrics(result, endEvent);
12468
- if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
12469
- metrics.time_to_first_token = firstChunkTime - startTime;
12470
- }
12471
- const output = await processAISDKStreamingOutput(
12472
- result,
12473
- resolveDenyOutputPaths(endEvent, defaultDenyOutputPaths)
12474
- );
12475
- const metadata = buildResolvedMetadataPayload(result).metadata;
12476
- span.log({
12477
- output,
12478
- ...metadata ? { metadata } : {},
12479
- metrics
12480
- });
12481
- finalizeAISDKChildTracing(endEvent);
12482
- span.end();
12483
- },
12484
- onError: (error) => {
12485
- span.log({
12486
- error: error.message
12487
- });
12488
- finalizeAISDKChildTracing(endEvent);
12489
- span.end();
12490
- }
12491
- });
12492
- Object.defineProperty(resultRecord, streamField.field, {
12493
- configurable: true,
12494
- enumerable: true,
12495
- value: wrappedStream,
12496
- writable: true
12497
- });
12498
- return true;
13965
+ return patched;
12499
13966
  }
12500
13967
  function attachKnownResultPromiseHandlers(result) {
12501
13968
  const promiseLikeFields = [
@@ -12527,34 +13994,72 @@ function attachKnownResultPromiseHandlers(result) {
12527
13994
  }
12528
13995
  }
12529
13996
  function isReadableStreamLike(value) {
12530
- return value != null && typeof value === "object" && typeof value.pipeThrough === "function";
12531
- }
12532
- function findAsyncIterableField(result, candidateFields) {
12533
- for (const field of candidateFields) {
12534
- try {
12535
- const stream = result[field];
12536
- if (isAsyncIterable(stream)) {
12537
- return { field, stream };
13997
+ return value != null && typeof value === "object" && typeof value.getReader === "function" && typeof value.pipeThrough === "function";
13998
+ }
13999
+ function createPatchedReadableStream(stream, hooks) {
14000
+ let reader;
14001
+ let completed = false;
14002
+ return new ReadableStream({
14003
+ async pull(controller) {
14004
+ reader ??= stream.getReader();
14005
+ try {
14006
+ const { done, value } = await reader.read();
14007
+ if (done) {
14008
+ completed = true;
14009
+ await hooks.onComplete();
14010
+ controller.close();
14011
+ return;
14012
+ }
14013
+ hooks.onChunk(value);
14014
+ controller.enqueue(value);
14015
+ } catch (error) {
14016
+ completed = true;
14017
+ hooks.onError(
14018
+ error instanceof Error ? error : new Error(String(error))
14019
+ );
14020
+ controller.error(error);
14021
+ }
14022
+ },
14023
+ async cancel(reason) {
14024
+ if (!completed) {
14025
+ completed = true;
14026
+ try {
14027
+ await hooks.onCancel?.();
14028
+ } catch {
14029
+ }
14030
+ }
14031
+ if (reader) {
14032
+ await reader.cancel(reason);
14033
+ } else if (stream.cancel) {
14034
+ await stream.cancel(reason);
12538
14035
  }
12539
- } catch {
12540
14036
  }
12541
- }
12542
- return null;
14037
+ });
12543
14038
  }
12544
14039
  function createPatchedAsyncIterable(stream, hooks) {
12545
14040
  return {
12546
14041
  async *[Symbol.asyncIterator]() {
14042
+ let completed = false;
12547
14043
  try {
12548
14044
  for await (const chunk of stream) {
12549
14045
  hooks.onChunk(chunk);
12550
14046
  yield chunk;
12551
14047
  }
14048
+ completed = true;
12552
14049
  await hooks.onComplete();
12553
14050
  } catch (error) {
14051
+ completed = true;
12554
14052
  hooks.onError(
12555
14053
  error instanceof Error ? error : new Error(String(error))
12556
14054
  );
12557
14055
  throw error;
14056
+ } finally {
14057
+ if (!completed) {
14058
+ try {
14059
+ await hooks.onCancel?.();
14060
+ } catch {
14061
+ }
14062
+ }
12558
14063
  }
12559
14064
  }
12560
14065
  };
@@ -12629,6 +14134,40 @@ function buildResolvedMetadataPayload(result) {
12629
14134
  }
12630
14135
  return Object.keys(metadata).length > 0 ? { metadata } : {};
12631
14136
  }
14137
+ function mergeMetadataPayload(metadataPayload, extraMetadata) {
14138
+ if (!extraMetadata || Object.keys(extraMetadata).length === 0) {
14139
+ return metadataPayload;
14140
+ }
14141
+ return {
14142
+ metadata: {
14143
+ ...metadataPayload.metadata ?? {},
14144
+ ...extraMetadata
14145
+ }
14146
+ };
14147
+ }
14148
+ function buildMissingUsageMetadata(output, metrics, reason) {
14149
+ if (!hasLoggedOutput(output) || hasTokenUsageMetrics(metrics)) {
14150
+ return void 0;
14151
+ }
14152
+ return { usage_unavailable_reason: reason };
14153
+ }
14154
+ function hasLoggedOutput(output) {
14155
+ if (output === null || output === void 0) {
14156
+ return false;
14157
+ }
14158
+ if (Array.isArray(output)) {
14159
+ return output.length > 0;
14160
+ }
14161
+ if (typeof output === "object") {
14162
+ return Object.keys(output).length > 0;
14163
+ }
14164
+ return true;
14165
+ }
14166
+ function hasTokenUsageMetrics(metrics) {
14167
+ return Object.keys(metrics).some(
14168
+ (key) => key !== "estimated_cost" && key !== "time_to_first_token"
14169
+ );
14170
+ }
12632
14171
  function resolveAISDKModel(model, aiSDK) {
12633
14172
  if (typeof model !== "string") {
12634
14173
  return model;
@@ -12652,7 +14191,45 @@ function isAsyncGenerator(value) {
12652
14191
  function processAISDKOutput(output, denyOutputPaths) {
12653
14192
  if (!output) return output;
12654
14193
  const merged = extractSerializableOutputFields(output);
12655
- return normalizeAISDKLoggedOutput(omit(merged, denyOutputPaths));
14194
+ const deleteOutputPaths = denyOutputPaths.filter(
14195
+ (path2) => path2.toLowerCase().endsWith("headers")
14196
+ );
14197
+ const sanitized = omit(merged, denyOutputPaths, deleteOutputPaths);
14198
+ for (const path2 of TRANSPORT_PAYLOAD_ROOT_PATHS) {
14199
+ const stack = [{ obj: sanitized, keys: parsePath(path2) }];
14200
+ while (stack.length > 0) {
14201
+ const entry = stack.pop();
14202
+ if (!entry || entry.keys.length === 0) {
14203
+ continue;
14204
+ }
14205
+ const firstKey = entry.keys[0];
14206
+ const remainingKeys = entry.keys.slice(1);
14207
+ if (firstKey === "[]") {
14208
+ if (Array.isArray(entry.obj)) {
14209
+ for (const item of entry.obj) {
14210
+ stack.push({
14211
+ obj: item,
14212
+ keys: remainingKeys
14213
+ });
14214
+ }
14215
+ }
14216
+ continue;
14217
+ }
14218
+ if (!entry.obj || typeof entry.obj !== "object" || !(firstKey in entry.obj)) {
14219
+ continue;
14220
+ }
14221
+ const record = entry.obj;
14222
+ if (remainingKeys.length === 0) {
14223
+ record[firstKey] = sanitizeAISDKMetadataValue(record[firstKey]);
14224
+ continue;
14225
+ }
14226
+ stack.push({
14227
+ obj: record[firstKey],
14228
+ keys: remainingKeys
14229
+ });
14230
+ }
14231
+ }
14232
+ return normalizeAISDKLoggedOutput(sanitized);
12656
14233
  }
12657
14234
  function processAISDKEmbeddingOutput(output, denyOutputPaths) {
12658
14235
  if (!output || typeof output !== "object") {
@@ -12743,6 +14320,8 @@ function extractTokenMetrics(result) {
12743
14320
  );
12744
14321
  if (totalTokens !== void 0) {
12745
14322
  metrics.tokens = totalTokens;
14323
+ } else if (promptTokens !== void 0 && completionTokens !== void 0) {
14324
+ metrics.tokens = promptTokens + completionTokens;
12746
14325
  }
12747
14326
  const promptCachedTokens = firstNumber(
12748
14327
  usage.inputTokens?.cacheRead,
@@ -12866,7 +14445,9 @@ function extractGetterValues(obj) {
12866
14445
  const getterValues = {};
12867
14446
  const getterNames = [
12868
14447
  "content",
14448
+ "messages",
12869
14449
  "text",
14450
+ "output",
12870
14451
  "object",
12871
14452
  "value",
12872
14453
  "values",
@@ -12906,7 +14487,9 @@ function extractGetterValues(obj) {
12906
14487
  function extractSerializableOutputFields(output) {
12907
14488
  const serialized = {};
12908
14489
  const directFieldNames = [
14490
+ "messages",
12909
14491
  "steps",
14492
+ "output",
12910
14493
  "request",
12911
14494
  "responseMessages",
12912
14495
  "warnings",
@@ -13088,7 +14671,7 @@ function parsePath(path2) {
13088
14671
  }
13089
14672
  return keys;
13090
14673
  }
13091
- function omitAtPath(obj, keys) {
14674
+ function omitAtPath(obj, keys, deleteLeaf = false) {
13092
14675
  if (keys.length === 0) return;
13093
14676
  const firstKey = keys[0];
13094
14677
  const remainingKeys = keys.slice(1);
@@ -13098,29 +14681,36 @@ function omitAtPath(obj, keys) {
13098
14681
  if (remainingKeys.length > 0) {
13099
14682
  omitAtPath(
13100
14683
  item,
13101
- remainingKeys
14684
+ remainingKeys,
14685
+ deleteLeaf
13102
14686
  );
13103
14687
  }
13104
14688
  });
13105
14689
  }
13106
14690
  } else if (remainingKeys.length === 0) {
13107
14691
  if (obj && typeof obj === "object" && firstKey in obj) {
13108
- obj[firstKey] = "<omitted>";
14692
+ if (deleteLeaf) {
14693
+ delete obj[firstKey];
14694
+ } else {
14695
+ obj[firstKey] = "<omitted>";
14696
+ }
13109
14697
  }
13110
14698
  } else {
13111
14699
  if (obj && typeof obj === "object" && firstKey in obj) {
13112
14700
  omitAtPath(
13113
14701
  obj[firstKey],
13114
- remainingKeys
14702
+ remainingKeys,
14703
+ deleteLeaf
13115
14704
  );
13116
14705
  }
13117
14706
  }
13118
14707
  }
13119
- function omit(obj, paths) {
14708
+ function omit(obj, paths, deletePaths = []) {
13120
14709
  const result = deepCopy(obj);
14710
+ const deletePathSet = new Set(deletePaths);
13121
14711
  for (const path2 of paths) {
13122
14712
  const keys = parsePath(path2);
13123
- omitAtPath(result, keys);
14713
+ omitAtPath(result, keys, deletePathSet.has(path2));
13124
14714
  }
13125
14715
  return result;
13126
14716
  }
@@ -13128,11 +14718,14 @@ function omit(obj, paths) {
13128
14718
  // src/wrappers/ai-sdk/telemetry.ts
13129
14719
  function braintrustAISDKTelemetry() {
13130
14720
  const operations = /* @__PURE__ */ new Map();
14721
+ const operationKeysByCallId = /* @__PURE__ */ new Map();
14722
+ const workflowOperationKeyStore = isomorph_default.newAsyncLocalStorage();
13131
14723
  const modelSpans = /* @__PURE__ */ new Map();
13132
14724
  const objectSpans = /* @__PURE__ */ new Map();
13133
14725
  const embedSpans = /* @__PURE__ */ new Map();
13134
14726
  const rerankSpans = /* @__PURE__ */ new Map();
13135
14727
  const toolSpans = /* @__PURE__ */ new Map();
14728
+ let workflowAgentOperationCounter = 0;
13136
14729
  const runSafely = (name, callback) => {
13137
14730
  try {
13138
14731
  callback();
@@ -13140,42 +14733,333 @@ function braintrustAISDKTelemetry() {
13140
14733
  console.error(`Error in Braintrust AI SDK telemetry ${name}:`, error);
13141
14734
  }
13142
14735
  };
13143
- const startChildSpan = (callId, name, type, event) => {
13144
- const parent = operations.get(callId)?.span;
14736
+ const startChildSpan = (operationKey, name, type, event) => {
14737
+ const parent = operations.get(operationKey)?.span;
13145
14738
  const spanArgs = {
13146
14739
  name,
13147
14740
  spanAttributes: { type },
13148
14741
  ...event ? { event } : {}
13149
14742
  };
13150
14743
  const span = parent ? parent.startSpan(spanArgs) : startSpan(spanArgs);
13151
- const state = operations.get(callId);
14744
+ const state = operations.get(operationKey);
13152
14745
  if (state && type === "llm" /* LLM */) {
13153
14746
  state.hadModelChild = true;
13154
14747
  }
13155
14748
  return span;
13156
14749
  };
14750
+ const registerOperation = (state) => {
14751
+ operations.set(state.operationKey, state);
14752
+ const keys = operationKeysByCallId.get(state.callId) ?? [];
14753
+ keys.push(state.operationKey);
14754
+ operationKeysByCallId.set(state.callId, keys);
14755
+ };
14756
+ const deleteOperation = (operationKey) => {
14757
+ const state = operations.get(operationKey);
14758
+ if (!state) {
14759
+ return;
14760
+ }
14761
+ operations.delete(operationKey);
14762
+ if (workflowOperationKeyStore.getStore() === operationKey) {
14763
+ workflowOperationKeyStore.enterWith(void 0);
14764
+ }
14765
+ const keys = operationKeysByCallId.get(state.callId);
14766
+ if (!keys) {
14767
+ return;
14768
+ }
14769
+ const index = keys.indexOf(operationKey);
14770
+ if (index >= 0) {
14771
+ keys.splice(index, 1);
14772
+ }
14773
+ if (keys.length === 0) {
14774
+ operationKeysByCallId.delete(state.callId);
14775
+ }
14776
+ };
14777
+ const explicitOperationKey = (event) => {
14778
+ if (!isObject(event)) {
14779
+ return void 0;
14780
+ }
14781
+ const key = event[BRAINTRUST_AI_SDK_V7_OPERATION_KEY];
14782
+ return typeof key === "string" ? key : void 0;
14783
+ };
14784
+ const createOperationKey = (event, operationName) => {
14785
+ const explicit = explicitOperationKey(event);
14786
+ if (explicit) {
14787
+ return explicit;
14788
+ }
14789
+ if (operationName === "WorkflowAgent.stream") {
14790
+ workflowAgentOperationCounter += 1;
14791
+ return `${event.callId}:${workflowAgentOperationCounter}`;
14792
+ }
14793
+ return event.callId;
14794
+ };
14795
+ const operationKeyForCallId = (callId, mode = "active") => {
14796
+ const keys = operationKeysByCallId.get(callId);
14797
+ if (!keys || keys.length === 0) {
14798
+ return operations.has(callId) ? callId : void 0;
14799
+ }
14800
+ if (keys.length === 1) {
14801
+ return keys[0];
14802
+ }
14803
+ const wrapperSpan = currentWorkflowAgentWrapperSpan();
14804
+ if (wrapperSpan?.spanId) {
14805
+ const key = keys.find(
14806
+ (candidate) => operations.get(candidate)?.span.spanId === wrapperSpan.spanId
14807
+ );
14808
+ if (key) {
14809
+ return key;
14810
+ }
14811
+ }
14812
+ const workflowOperationKey = workflowOperationKeyStore.getStore();
14813
+ if (workflowOperationKey && keys.includes(workflowOperationKey)) {
14814
+ return workflowOperationKey;
14815
+ }
14816
+ if (callId === "workflow-agent") {
14817
+ return void 0;
14818
+ }
14819
+ return mode === "finish" ? keys[0] : keys[keys.length - 1];
14820
+ };
14821
+ const operationKeyFromEvent = (event, mode = "active") => {
14822
+ const explicit = explicitOperationKey(event);
14823
+ if (explicit && operations.has(explicit)) {
14824
+ return explicit;
14825
+ }
14826
+ if (isObject(event)) {
14827
+ const callId = event.callId;
14828
+ if (typeof callId === "string") {
14829
+ const operationKey = operationKeyForCallId(callId, mode);
14830
+ if (operationKey) {
14831
+ return operationKey;
14832
+ }
14833
+ const workflowOperationKey2 = workflowOperationKeyStore.getStore();
14834
+ if (workflowOperationKey2 && operations.has(workflowOperationKey2)) {
14835
+ return workflowOperationKey2;
14836
+ }
14837
+ return callId === "workflow-agent" ? void 0 : callId;
14838
+ }
14839
+ }
14840
+ const workflowOperationKey = workflowOperationKeyStore.getStore();
14841
+ if (workflowOperationKey && operations.has(workflowOperationKey)) {
14842
+ return workflowOperationKey;
14843
+ }
14844
+ const wrapperSpan = currentWorkflowAgentWrapperSpan();
14845
+ if (wrapperSpan?.spanId) {
14846
+ for (const [operationKey, state] of operations) {
14847
+ if (state.operationName === "WorkflowAgent.stream" && state.span.spanId === wrapperSpan.spanId) {
14848
+ return operationKey;
14849
+ }
14850
+ }
14851
+ }
14852
+ const workflowAgentKeys = operationKeysByCallId.get("workflow-agent");
14853
+ if (workflowAgentKeys?.length === 1) {
14854
+ return workflowAgentKeys[0];
14855
+ }
14856
+ if (operations.size === 1) {
14857
+ return operations.keys().next().value;
14858
+ }
14859
+ return void 0;
14860
+ };
14861
+ const closeOpenChildSpans = (operationKey, error) => {
14862
+ const openModelSpans = modelSpans.get(operationKey);
14863
+ if (openModelSpans) {
14864
+ for (const span of openModelSpans) {
14865
+ if (error !== void 0) {
14866
+ logError(span, error);
14867
+ }
14868
+ span.end();
14869
+ }
14870
+ modelSpans.delete(operationKey);
14871
+ }
14872
+ const openObjectSpan = objectSpans.get(operationKey);
14873
+ if (openObjectSpan) {
14874
+ if (error !== void 0) {
14875
+ logError(openObjectSpan, error);
14876
+ }
14877
+ openObjectSpan.end();
14878
+ objectSpans.delete(operationKey);
14879
+ }
14880
+ for (const [embedCallId, embedState] of embedSpans) {
14881
+ if (embedState.operationKey === operationKey) {
14882
+ if (error !== void 0) {
14883
+ logError(embedState.span, error);
14884
+ }
14885
+ embedState.span.end();
14886
+ embedSpans.delete(embedCallId);
14887
+ }
14888
+ }
14889
+ const openRerankSpan = rerankSpans.get(operationKey);
14890
+ if (openRerankSpan) {
14891
+ if (error !== void 0) {
14892
+ logError(openRerankSpan, error);
14893
+ }
14894
+ openRerankSpan.end();
14895
+ rerankSpans.delete(operationKey);
14896
+ }
14897
+ for (const [toolCallId, toolState] of toolSpans) {
14898
+ if (toolState.operationKey === operationKey) {
14899
+ if (error !== void 0) {
14900
+ logError(toolState.span, error);
14901
+ }
14902
+ toolState.span.end();
14903
+ toolSpans.delete(toolCallId);
14904
+ }
14905
+ }
14906
+ };
14907
+ const abortReasonFromEvent = (event) => {
14908
+ if (isObject(event)) {
14909
+ const abortEvent = event;
14910
+ if (abortEvent.error !== void 0) {
14911
+ return abortEvent.error;
14912
+ }
14913
+ if (abortEvent.reason !== void 0) {
14914
+ return abortEvent.reason;
14915
+ }
14916
+ }
14917
+ return new Error("AI SDK operation aborted");
14918
+ };
14919
+ const shouldSkipTelemetryChildren = (state) => state?.operationName === "WorkflowAgent.stream" && !state.ownsSpan;
14920
+ const onObjectStepEnd = (event) => {
14921
+ runSafely("onObjectStepEnd", () => {
14922
+ const operationKey = operationKeyFromEvent(event);
14923
+ const span = operationKey ? objectSpans.get(operationKey) : void 0;
14924
+ if (!operationKey || !span) {
14925
+ return;
14926
+ }
14927
+ const result = {
14928
+ ...event,
14929
+ text: event.objectText
14930
+ };
14931
+ span.log({
14932
+ ...shouldRecordOutputs(event) ? {
14933
+ output: processAISDKOutput(result, DEFAULT_DENY_OUTPUT_PATHS)
14934
+ } : {},
14935
+ metrics: extractTokenMetrics(result)
14936
+ });
14937
+ span.end();
14938
+ objectSpans.delete(operationKey);
14939
+ });
14940
+ };
14941
+ const onEmbedEnd = (event) => {
14942
+ runSafely("onEmbedEnd", () => {
14943
+ const state = embedSpans.get(event.embedCallId);
14944
+ if (!state) {
14945
+ return;
14946
+ }
14947
+ const result = {
14948
+ ...event,
14949
+ embeddings: event.embeddings
14950
+ };
14951
+ state.span.log({
14952
+ ...shouldRecordOutputs(event) ? {
14953
+ output: processAISDKEmbeddingOutput(
14954
+ result,
14955
+ DEFAULT_DENY_OUTPUT_PATHS
14956
+ )
14957
+ } : {},
14958
+ metrics: extractTokenMetrics(result)
14959
+ });
14960
+ state.span.end();
14961
+ embedSpans.delete(event.embedCallId);
14962
+ });
14963
+ };
14964
+ const onRerankEnd = (event) => {
14965
+ runSafely("onRerankEnd", () => {
14966
+ const operationKey = operationKeyFromEvent(event);
14967
+ const span = operationKey ? rerankSpans.get(operationKey) : void 0;
14968
+ if (!operationKey || !span) {
14969
+ return;
14970
+ }
14971
+ const result = {
14972
+ ranking: event.ranking?.map((entry) => ({
14973
+ originalIndex: entry.index,
14974
+ score: entry.relevanceScore
14975
+ }))
14976
+ };
14977
+ span.log({
14978
+ ...shouldRecordOutputs(event) ? {
14979
+ output: processAISDKRerankOutput(
14980
+ result,
14981
+ DEFAULT_DENY_OUTPUT_PATHS
14982
+ )
14983
+ } : {}
14984
+ });
14985
+ span.end();
14986
+ rerankSpans.delete(operationKey);
14987
+ });
14988
+ };
14989
+ const onEnd = (event) => {
14990
+ runSafely("onEnd", () => {
14991
+ const operationKey = operationKeyFromEvent(event, "finish");
14992
+ const state = operationKey ? operations.get(operationKey) : void 0;
14993
+ if (!state) {
14994
+ return;
14995
+ }
14996
+ if (!state.ownsSpan) {
14997
+ deleteOperation(state.operationKey);
14998
+ return;
14999
+ }
15000
+ const result = finishResult(event, state.operationName);
15001
+ const metrics = state.hadModelChild ? {} : extractTokenMetrics(result);
15002
+ const timeToFirstToken = state.operationName === "WorkflowAgent.stream" ? void 0 : extractTimeToFirstToken(result, state);
15003
+ if (timeToFirstToken !== void 0) {
15004
+ metrics.time_to_first_token = timeToFirstToken;
15005
+ }
15006
+ state.span.log({
15007
+ ...shouldRecordOutputs(event) ? {
15008
+ output: finishOutput(result, state.operationName)
15009
+ } : {},
15010
+ metrics
15011
+ });
15012
+ state.span.end();
15013
+ deleteOperation(state.operationKey);
15014
+ });
15015
+ };
13157
15016
  return {
13158
15017
  onStart(event) {
13159
15018
  runSafely("onStart", () => {
13160
15019
  const operationName = operationNameFromId(event.operationId);
13161
- const span = startSpan({
15020
+ const workflowAgent = operationName === "WorkflowAgent.stream";
15021
+ const wrapperSpan = workflowAgent ? currentWorkflowAgentWrapperSpan() : void 0;
15022
+ const ownsSpan = !wrapperSpan;
15023
+ const span = ownsSpan ? startSpan({
13162
15024
  name: operationName,
13163
15025
  spanAttributes: { type: "function" /* FUNCTION */ }
13164
- });
13165
- operations.set(event.callId, {
15026
+ }) : wrapperSpan;
15027
+ const operationKey = createOperationKey(event, operationName);
15028
+ registerOperation({
15029
+ callId: event.callId,
13166
15030
  hadModelChild: false,
15031
+ loggedInput: false,
13167
15032
  operationName,
15033
+ operationKey,
15034
+ ownsSpan,
13168
15035
  span,
13169
15036
  startTime: getCurrentUnixTimestamp()
13170
15037
  });
13171
- const metadata = metadataFromEvent(event);
15038
+ if (!ownsSpan) {
15039
+ return;
15040
+ }
15041
+ if (workflowAgent) {
15042
+ workflowOperationKeyStore.enterWith(operationKey);
15043
+ }
15044
+ let metadata = metadataFromEvent(event);
13172
15045
  const logPayload = { metadata };
15046
+ const workflowAgentCallInput = workflowAgent ? operationInput(event, operationName) : void 0;
15047
+ if (workflowAgentCallInput) {
15048
+ metadata = {
15049
+ ...metadata,
15050
+ ...extractWorkflowMetadataFromCallParams(workflowAgentCallInput)
15051
+ };
15052
+ logPayload.metadata = metadata;
15053
+ }
13173
15054
  if (shouldRecordInputs(event)) {
13174
- const { input, outputPromise } = processAISDKCallInput(
13175
- operationInput(event, operationName)
13176
- );
15055
+ const callInput = workflowAgentCallInput ?? operationInput(event, operationName);
15056
+ const { input, outputPromise } = workflowAgent ? processAISDKWorkflowAgentCallInput(callInput) : processAISDKCallInput(callInput);
13177
15057
  logPayload.input = input;
13178
- if (outputPromise && input && typeof input === "object") {
15058
+ const state = operations.get(operationKey);
15059
+ if (state) {
15060
+ state.loggedInput = hasPromptLikeInput(input);
15061
+ }
15062
+ if (outputPromise && !workflowAgent && input && typeof input === "object") {
13179
15063
  outputPromise.then((resolvedData) => {
13180
15064
  span.log({
13181
15065
  input: {
@@ -13192,41 +15076,67 @@ function braintrustAISDKTelemetry() {
13192
15076
  },
13193
15077
  onLanguageModelCallStart(event) {
13194
15078
  runSafely("onLanguageModelCallStart", () => {
13195
- const state = operations.get(event.callId);
13196
- const openSpans = modelSpans.get(event.callId);
13197
- if (openSpans) {
15079
+ const operationKey = operationKeyFromEvent(event);
15080
+ const state = operationKey ? operations.get(operationKey) : void 0;
15081
+ if (shouldSkipTelemetryChildren(state)) {
15082
+ return;
15083
+ }
15084
+ const operationName = state?.operationName ?? "generateText";
15085
+ const callInput = operationInput(event, operationName);
15086
+ const workflowAgent = operationName === "WorkflowAgent.stream";
15087
+ const processedInput = shouldRecordInputs(event) && workflowAgent ? processAISDKWorkflowAgentModelCallInput(callInput).input : shouldRecordInputs(event) ? processAISDKCallInput(callInput).input : void 0;
15088
+ if (workflowAgent && state?.ownsSpan && !state.loggedInput && hasPromptLikeInput(processedInput)) {
15089
+ state.span.log({
15090
+ input: processedInput,
15091
+ metadata: {
15092
+ ...metadataFromEvent(event),
15093
+ ...extractWorkflowMetadataFromCallParams(callInput)
15094
+ }
15095
+ });
15096
+ state.loggedInput = true;
15097
+ }
15098
+ const openSpans = operationKey ? modelSpans.get(operationKey) : void 0;
15099
+ if (operationKey && openSpans) {
13198
15100
  for (const span2 of openSpans) {
13199
15101
  span2.end();
13200
15102
  }
13201
- modelSpans.delete(event.callId);
15103
+ modelSpans.delete(operationKey);
13202
15104
  }
13203
15105
  const span = startChildSpan(
13204
- event.callId,
13205
- state?.operationName === "streamText" ? "doStream" : "doGenerate",
15106
+ operationKey ?? event.callId,
15107
+ operationName === "streamText" ? "doStream" : "doGenerate",
13206
15108
  "llm" /* LLM */,
13207
15109
  {
13208
15110
  ...shouldRecordInputs(event) ? {
13209
- input: processAISDKCallInput(
13210
- operationInput(
13211
- event,
13212
- state?.operationName ?? "generateText"
13213
- )
13214
- ).input
15111
+ input: processedInput
13215
15112
  } : {},
13216
- metadata: metadataFromEvent(event)
15113
+ metadata: workflowAgent ? {
15114
+ ...metadataFromEvent(event),
15115
+ ...extractWorkflowMetadataFromCallParams(callInput)
15116
+ } : metadataFromEvent(event)
13217
15117
  }
13218
15118
  );
13219
- const spans = modelSpans.get(event.callId) ?? [];
15119
+ const spanKey = operationKey ?? event.callId;
15120
+ const spans = modelSpans.get(spanKey) ?? [];
13220
15121
  spans.push(span);
13221
- modelSpans.set(event.callId, spans);
15122
+ modelSpans.set(spanKey, spans);
13222
15123
  });
13223
15124
  },
13224
15125
  onLanguageModelCallEnd(event) {
13225
15126
  runSafely("onLanguageModelCallEnd", () => {
13226
- const span = shiftModelSpan(modelSpans, event.callId);
15127
+ const operationKey = operationKeyFromEvent(event);
15128
+ const state = operationKey ? operations.get(operationKey) : void 0;
15129
+ if (shouldSkipTelemetryChildren(state)) {
15130
+ return;
15131
+ }
15132
+ const span = operationKey ? shiftModelSpan(modelSpans, operationKey) : void 0;
13227
15133
  if (!span) {
13228
15134
  return;
13229
15135
  }
15136
+ const timeToFirstOutputMs = safePerformance(event)?.timeToFirstOutputMs;
15137
+ if (state?.operationName === "streamText" && state.firstChunkTime === void 0 && typeof timeToFirstOutputMs === "number") {
15138
+ state.firstChunkTime = state.startTime + timeToFirstOutputMs / 1e3;
15139
+ }
13230
15140
  const result = {
13231
15141
  ...event,
13232
15142
  response: event.responseId ? { id: event.responseId } : void 0
@@ -13242,14 +15152,18 @@ function braintrustAISDKTelemetry() {
13242
15152
  },
13243
15153
  onObjectStepStart(event) {
13244
15154
  runSafely("onObjectStepStart", () => {
13245
- const state = operations.get(event.callId);
13246
- const openSpan = objectSpans.get(event.callId);
13247
- if (openSpan) {
15155
+ const operationKey = operationKeyFromEvent(event);
15156
+ const state = operationKey ? operations.get(operationKey) : void 0;
15157
+ if (shouldSkipTelemetryChildren(state)) {
15158
+ return;
15159
+ }
15160
+ const openSpan = operationKey ? objectSpans.get(operationKey) : void 0;
15161
+ if (operationKey && openSpan) {
13248
15162
  openSpan.end();
13249
- objectSpans.delete(event.callId);
15163
+ objectSpans.delete(operationKey);
13250
15164
  }
13251
15165
  const span = startChildSpan(
13252
- event.callId,
15166
+ operationKey ?? event.callId,
13253
15167
  state?.operationName === "streamObject" ? "doStream" : "doGenerate",
13254
15168
  "llm" /* LLM */,
13255
15169
  {
@@ -13261,40 +15175,25 @@ function braintrustAISDKTelemetry() {
13261
15175
  metadata: metadataFromEvent(event)
13262
15176
  }
13263
15177
  );
13264
- objectSpans.set(event.callId, span);
13265
- });
13266
- },
13267
- onObjectStepFinish(event) {
13268
- runSafely("onObjectStepFinish", () => {
13269
- const span = objectSpans.get(event.callId);
13270
- if (!span) {
13271
- return;
13272
- }
13273
- const result = {
13274
- ...event,
13275
- text: event.objectText
13276
- };
13277
- span.log({
13278
- ...shouldRecordOutputs(event) ? {
13279
- output: processAISDKOutput(result, DEFAULT_DENY_OUTPUT_PATHS)
13280
- } : {},
13281
- metrics: extractTokenMetrics(result)
13282
- });
13283
- span.end();
13284
- objectSpans.delete(event.callId);
15178
+ objectSpans.set(operationKey ?? event.callId, span);
13285
15179
  });
13286
15180
  },
15181
+ onObjectStepEnd,
13287
15182
  onEmbedStart(event) {
13288
15183
  runSafely("onEmbedStart", () => {
13289
- const state = operations.get(event.callId);
15184
+ const operationKey = operationKeyFromEvent(event);
15185
+ const state = operationKey ? operations.get(operationKey) : void 0;
15186
+ if (shouldSkipTelemetryChildren(state)) {
15187
+ return;
15188
+ }
13290
15189
  for (const [embedCallId, embedState] of embedSpans) {
13291
- if (embedState.callId === event.callId && (state?.operationName === "embed" || embedState.values === event.values)) {
15190
+ if (embedState.operationKey === operationKey && (state?.operationName === "embed" || embedState.values === event.values)) {
13292
15191
  embedState.span.end();
13293
15192
  embedSpans.delete(embedCallId);
13294
15193
  }
13295
15194
  }
13296
15195
  const span = startChildSpan(
13297
- event.callId,
15196
+ operationKey ?? event.callId,
13298
15197
  "doEmbed",
13299
15198
  "llm" /* LLM */,
13300
15199
  {
@@ -13307,44 +15206,27 @@ function braintrustAISDKTelemetry() {
13307
15206
  }
13308
15207
  );
13309
15208
  embedSpans.set(event.embedCallId, {
13310
- callId: event.callId,
15209
+ operationKey: operationKey ?? event.callId,
13311
15210
  span,
13312
15211
  values: event.values
13313
15212
  });
13314
15213
  });
13315
15214
  },
13316
- onEmbedFinish(event) {
13317
- runSafely("onEmbedFinish", () => {
13318
- const state = embedSpans.get(event.embedCallId);
13319
- if (!state) {
13320
- return;
13321
- }
13322
- const result = {
13323
- ...event,
13324
- embeddings: event.embeddings
13325
- };
13326
- state.span.log({
13327
- ...shouldRecordOutputs(event) ? {
13328
- output: processAISDKEmbeddingOutput(
13329
- result,
13330
- DEFAULT_DENY_OUTPUT_PATHS
13331
- )
13332
- } : {},
13333
- metrics: extractTokenMetrics(result)
13334
- });
13335
- state.span.end();
13336
- embedSpans.delete(event.embedCallId);
13337
- });
13338
- },
15215
+ onEmbedEnd,
13339
15216
  onRerankStart(event) {
13340
15217
  runSafely("onRerankStart", () => {
13341
- const openSpan = rerankSpans.get(event.callId);
13342
- if (openSpan) {
15218
+ const operationKey = operationKeyFromEvent(event);
15219
+ const state = operationKey ? operations.get(operationKey) : void 0;
15220
+ if (shouldSkipTelemetryChildren(state)) {
15221
+ return;
15222
+ }
15223
+ const openSpan = operationKey ? rerankSpans.get(operationKey) : void 0;
15224
+ if (operationKey && openSpan) {
13343
15225
  openSpan.end();
13344
- rerankSpans.delete(event.callId);
15226
+ rerankSpans.delete(operationKey);
13345
15227
  }
13346
15228
  const span = startChildSpan(
13347
- event.callId,
15229
+ operationKey ?? event.callId,
13348
15230
  "doRerank",
13349
15231
  "llm" /* LLM */,
13350
15232
  {
@@ -13358,41 +15240,23 @@ function braintrustAISDKTelemetry() {
13358
15240
  metadata: metadataFromEvent(event)
13359
15241
  }
13360
15242
  );
13361
- rerankSpans.set(event.callId, span);
13362
- });
13363
- },
13364
- onRerankFinish(event) {
13365
- runSafely("onRerankFinish", () => {
13366
- const span = rerankSpans.get(event.callId);
13367
- if (!span) {
13368
- return;
13369
- }
13370
- const result = {
13371
- ranking: event.ranking?.map((entry) => ({
13372
- originalIndex: entry.index,
13373
- score: entry.relevanceScore
13374
- }))
13375
- };
13376
- span.log({
13377
- ...shouldRecordOutputs(event) ? {
13378
- output: processAISDKRerankOutput(
13379
- result,
13380
- DEFAULT_DENY_OUTPUT_PATHS
13381
- )
13382
- } : {}
13383
- });
13384
- span.end();
13385
- rerankSpans.delete(event.callId);
15243
+ rerankSpans.set(operationKey ?? event.callId, span);
13386
15244
  });
13387
15245
  },
15246
+ onRerankEnd,
13388
15247
  onToolExecutionStart(event) {
13389
15248
  runSafely("onToolExecutionStart", () => {
15249
+ const operationKey = operationKeyFromEvent(event);
15250
+ const state = operationKey ? operations.get(operationKey) : void 0;
15251
+ if (shouldSkipTelemetryChildren(state)) {
15252
+ return;
15253
+ }
13390
15254
  const toolCallId = event.toolCall.toolCallId;
13391
- if (!toolCallId) {
15255
+ if (!operationKey || !toolCallId) {
13392
15256
  return;
13393
15257
  }
13394
15258
  const span = startChildSpan(
13395
- event.callId,
15259
+ operationKey,
13396
15260
  event.toolCall.toolName || "tool",
13397
15261
  "tool" /* TOOL */,
13398
15262
  {
@@ -13406,7 +15270,7 @@ function braintrustAISDKTelemetry() {
13406
15270
  }
13407
15271
  }
13408
15272
  );
13409
- toolSpans.set(toolCallId, { callId: event.callId, span });
15273
+ toolSpans.set(toolCallId, { operationKey, span });
13410
15274
  });
13411
15275
  },
13412
15276
  onToolExecutionEnd(event) {
@@ -13417,14 +15281,17 @@ function braintrustAISDKTelemetry() {
13417
15281
  return;
13418
15282
  }
13419
15283
  const toolOutput = event.toolOutput;
13420
- if (toolOutput?.type === "tool-error") {
15284
+ const workflowToolError = event.success === false && "error" in event ? event.error : void 0;
15285
+ if (toolOutput?.type === "tool-error" || workflowToolError !== void 0) {
15286
+ const error = toolOutput?.error ?? workflowToolError;
13421
15287
  state.span.log({
13422
- error: toolOutput.error instanceof Error ? toolOutput.error.message : String(toolOutput?.error),
15288
+ error: error instanceof Error ? error.message : String(error),
13423
15289
  metrics: typeof event.durationMs === "number" ? { duration_ms: event.durationMs } : {}
13424
15290
  });
13425
15291
  } else {
15292
+ const output = toolOutput && "output" in toolOutput ? toolOutput.output : event.output;
13426
15293
  state.span.log({
13427
- ...shouldRecordOutputs(event) ? { output: toolOutput?.output } : {},
15294
+ ...shouldRecordOutputs(event) ? { output } : {},
13428
15295
  metrics: typeof event.durationMs === "number" ? { duration_ms: event.durationMs } : {}
13429
15296
  });
13430
15297
  }
@@ -13438,83 +15305,46 @@ function braintrustAISDKTelemetry() {
13438
15305
  if (!callId) {
13439
15306
  return;
13440
15307
  }
13441
- const state = operations.get(callId);
15308
+ const operationKey = operationKeyForCallId(callId);
15309
+ const state = operationKey ? operations.get(operationKey) : void 0;
13442
15310
  if (!state || state.firstChunkTime !== void 0) {
13443
15311
  return;
13444
15312
  }
13445
15313
  state.firstChunkTime = getCurrentUnixTimestamp();
13446
15314
  });
13447
15315
  },
13448
- onFinish(event) {
13449
- runSafely("onFinish", () => {
13450
- const state = operations.get(event.callId);
13451
- if (!state) {
15316
+ onEnd,
15317
+ onAbort(event) {
15318
+ runSafely("onAbort", () => {
15319
+ const operationKey = operationKeyFromEvent(event, "finish");
15320
+ const state = operationKey ? operations.get(operationKey) : void 0;
15321
+ if (!operationKey || !state) {
13452
15322
  return;
13453
15323
  }
13454
- const result = finishResult(event, state.operationName);
13455
- const metrics = state.hadModelChild ? {} : extractTokenMetrics(result);
13456
- if (state.firstChunkTime !== void 0) {
13457
- metrics.time_to_first_token = state.firstChunkTime - state.startTime;
15324
+ const error = abortReasonFromEvent(event);
15325
+ closeOpenChildSpans(operationKey, error);
15326
+ if (state.ownsSpan) {
15327
+ logError(state.span, error);
15328
+ state.span.end();
13458
15329
  }
13459
- state.span.log({
13460
- ...shouldRecordOutputs(event) ? {
13461
- output: finishOutput(result, state.operationName)
13462
- } : {},
13463
- metrics
13464
- });
13465
- state.span.end();
13466
- operations.delete(event.callId);
15330
+ deleteOperation(operationKey);
13467
15331
  });
13468
15332
  },
13469
15333
  onError(event) {
13470
15334
  runSafely("onError", () => {
13471
15335
  const errorEvent = isObject(event) ? event : {};
13472
- const callId = typeof errorEvent.callId === "string" ? errorEvent.callId : void 0;
13473
- if (!callId) {
13474
- return;
13475
- }
13476
- const state = operations.get(callId);
13477
- if (!state) {
15336
+ const operationKey = operationKeyFromEvent(errorEvent, "finish");
15337
+ const state = operationKey ? operations.get(operationKey) : void 0;
15338
+ if (!operationKey || !state) {
13478
15339
  return;
13479
15340
  }
13480
15341
  const error = errorEvent.error ?? event;
13481
- const openModelSpans = modelSpans.get(callId);
13482
- if (openModelSpans) {
13483
- for (const span of openModelSpans) {
13484
- logError(span, error);
13485
- span.end();
13486
- }
13487
- modelSpans.delete(callId);
13488
- }
13489
- const openObjectSpan = objectSpans.get(callId);
13490
- if (openObjectSpan) {
13491
- logError(openObjectSpan, error);
13492
- openObjectSpan.end();
13493
- objectSpans.delete(callId);
13494
- }
13495
- for (const [embedCallId, embedState] of embedSpans) {
13496
- if (embedState.callId === callId) {
13497
- logError(embedState.span, error);
13498
- embedState.span.end();
13499
- embedSpans.delete(embedCallId);
13500
- }
13501
- }
13502
- const openRerankSpan = rerankSpans.get(callId);
13503
- if (openRerankSpan) {
13504
- logError(openRerankSpan, error);
13505
- openRerankSpan.end();
13506
- rerankSpans.delete(callId);
13507
- }
13508
- for (const [toolCallId, toolState] of toolSpans) {
13509
- if (toolState.callId === callId) {
13510
- logError(toolState.span, error);
13511
- toolState.span.end();
13512
- toolSpans.delete(toolCallId);
13513
- }
15342
+ closeOpenChildSpans(operationKey, error);
15343
+ if (state.ownsSpan) {
15344
+ logError(state.span, error);
15345
+ state.span.end();
13514
15346
  }
13515
- logError(state.span, error);
13516
- state.span.end();
13517
- operations.delete(callId);
15347
+ deleteOperation(operationKey);
13518
15348
  });
13519
15349
  },
13520
15350
  executeTool({ toolCallId, execute }) {
@@ -13529,7 +15359,16 @@ function shouldRecordInputs(event) {
13529
15359
  function shouldRecordOutputs(event) {
13530
15360
  return event.recordOutputs !== false;
13531
15361
  }
15362
+ function hasPromptLikeInput(input) {
15363
+ if (!isObject(input)) {
15364
+ return false;
15365
+ }
15366
+ return input.prompt !== void 0 || input.messages !== void 0;
15367
+ }
13532
15368
  function operationNameFromId(operationId) {
15369
+ if (operationId === "ai.workflowAgent.stream") {
15370
+ return "WorkflowAgent.stream";
15371
+ }
13533
15372
  return operationId?.startsWith("ai.") ? operationId.slice("ai.".length) : operationId || "ai-sdk";
13534
15373
  }
13535
15374
  function modelFromEvent(event) {
@@ -13575,6 +15414,7 @@ function operationInput(event, operationName) {
13575
15414
  }
13576
15415
  return {
13577
15416
  model: modelFromEvent(event),
15417
+ instructions: event.instructions,
13578
15418
  system: event.system,
13579
15419
  prompt: event.prompt,
13580
15420
  messages: event.messages,
@@ -13623,6 +15463,30 @@ function finishResult(event, operationName) {
13623
15463
  }
13624
15464
  return event;
13625
15465
  }
15466
+ function extractTimeToFirstToken(result, state) {
15467
+ if (state.firstChunkTime !== void 0) {
15468
+ return state.firstChunkTime - state.startTime;
15469
+ }
15470
+ const performanceCandidates = [
15471
+ safePerformance(result),
15472
+ safePerformance(result.finalStep),
15473
+ ...Array.isArray(result.steps) ? (result.steps ?? []).map(safePerformance) : []
15474
+ ];
15475
+ for (const performance of performanceCandidates) {
15476
+ const timeToFirstOutputMs = performance?.timeToFirstOutputMs;
15477
+ if (typeof timeToFirstOutputMs === "number") {
15478
+ return timeToFirstOutputMs / 1e3;
15479
+ }
15480
+ }
15481
+ return void 0;
15482
+ }
15483
+ function safePerformance(value) {
15484
+ if (!isObject(value)) {
15485
+ return void 0;
15486
+ }
15487
+ const performance = value.performance;
15488
+ return isObject(performance) ? performance : void 0;
15489
+ }
13626
15490
  function finishOutput(result, operationName) {
13627
15491
  if (operationName === "embed" || operationName === "embedMany") {
13628
15492
  return processAISDKEmbeddingOutput(
@@ -29136,12 +31000,17 @@ export {
29136
31000
  debugLogger,
29137
31001
  IDGenerator,
29138
31002
  UUIDGenerator,
31003
+ OTELIDGenerator,
29139
31004
  getIdGenerator,
31005
+ TRACEPARENT_HEADER,
31006
+ TRACESTATE_HEADER,
31007
+ BAGGAGE_HEADER,
31008
+ BRAINTRUST_PARENT_KEY,
29140
31009
  spanObjectTypeV3ToTypedString,
29141
- SpanComponentsV3,
29142
31010
  isObject,
29143
31011
  mergeDicts,
29144
31012
  slugify,
31013
+ SpanComponentsV4,
29145
31014
  makeScorerPropagatedEvent,
29146
31015
  loadPrettyXact,
29147
31016
  getCurrentUnixTimestamp,
@@ -29197,7 +31066,7 @@ export {
29197
31066
  constructLogs3OverflowRequest,
29198
31067
  pickLogs3OverflowObjectIds,
29199
31068
  uploadLogs3OverflowPayload,
29200
- utf8ByteLength,
31069
+ utf8ByteLength2 as utf8ByteLength,
29201
31070
  TestBackgroundLogger,
29202
31071
  init,
29203
31072
  initExperiment,
@@ -29217,6 +31086,8 @@ export {
29217
31086
  currentLogger,
29218
31087
  currentSpan,
29219
31088
  getSpanParentObject,
31089
+ injectTraceContext,
31090
+ extractTraceContextFromHeaders,
29220
31091
  logError,
29221
31092
  traced,
29222
31093
  wrapTraced,
@@ -29249,6 +31120,7 @@ export {
29249
31120
  finalizeAnthropicTokens,
29250
31121
  extractAnthropicCacheTokens,
29251
31122
  zodToJsonSchema,
31123
+ currentWorkflowAgentWrapperSpan,
29252
31124
  braintrustAISDKTelemetry,
29253
31125
  CLAUDE_AGENT_SDK_SKIP_LOCAL_TOOL_HOOKS_OPTION,
29254
31126
  wrapLocalClaudeToolHandler,