braintrust 3.25.0 → 3.27.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 (79) hide show
  1. package/NOTICE +6 -0
  2. package/dev/dist/index.d.mts +130 -2
  3. package/dev/dist/index.d.ts +130 -2
  4. package/dev/dist/index.js +4133 -1421
  5. package/dev/dist/index.mjs +3242 -530
  6. package/dist/apply-auto-instrumentation.js +526 -426
  7. package/dist/apply-auto-instrumentation.mjs +329 -229
  8. package/dist/auto-instrumentations/bundler/esbuild.cjs +1198 -364
  9. package/dist/auto-instrumentations/bundler/esbuild.d.mts +4 -4
  10. package/dist/auto-instrumentations/bundler/esbuild.d.ts +4 -4
  11. package/dist/auto-instrumentations/bundler/esbuild.mjs +6 -8
  12. package/dist/auto-instrumentations/bundler/next.cjs +1227 -413
  13. package/dist/auto-instrumentations/bundler/next.mjs +7 -29
  14. package/dist/auto-instrumentations/bundler/rollup.cjs +1198 -364
  15. package/dist/auto-instrumentations/bundler/rollup.d.mts +4 -4
  16. package/dist/auto-instrumentations/bundler/rollup.d.ts +4 -4
  17. package/dist/auto-instrumentations/bundler/rollup.mjs +6 -8
  18. package/dist/auto-instrumentations/bundler/vite.cjs +1249 -387
  19. package/dist/auto-instrumentations/bundler/vite.d.mts +4 -4
  20. package/dist/auto-instrumentations/bundler/vite.d.ts +4 -4
  21. package/dist/auto-instrumentations/bundler/vite.mjs +34 -8
  22. package/dist/auto-instrumentations/bundler/webpack-loader.cjs +1368 -324
  23. package/dist/auto-instrumentations/bundler/webpack-loader.d.ts +20 -12
  24. package/dist/auto-instrumentations/bundler/webpack.cjs +1198 -364
  25. package/dist/auto-instrumentations/bundler/webpack.d.mts +4 -4
  26. package/dist/auto-instrumentations/bundler/webpack.d.ts +4 -4
  27. package/dist/auto-instrumentations/bundler/webpack.mjs +6 -4
  28. package/dist/auto-instrumentations/chunk-2AMDGD65.mjs +1396 -0
  29. package/dist/auto-instrumentations/{chunk-7P6563SW.mjs → chunk-BW33ULMW.mjs} +2 -6
  30. package/dist/auto-instrumentations/{chunk-M6DLIJ2Z.mjs → chunk-I55G56ZL.mjs} +114 -221
  31. package/dist/auto-instrumentations/chunk-JPUFNW7X.mjs +649 -0
  32. package/dist/auto-instrumentations/{chunk-JPVCUKTY.mjs → chunk-XEYKUBLY.mjs} +191 -73
  33. package/dist/auto-instrumentations/{chunk-CZ24KNHT.mjs → chunk-ZNHTSSGI.mjs} +231 -69
  34. package/dist/auto-instrumentations/hook.mjs +406 -183
  35. package/dist/auto-instrumentations/index.cjs +853 -49
  36. package/dist/auto-instrumentations/index.d.mts +10 -2
  37. package/dist/auto-instrumentations/index.d.ts +10 -2
  38. package/dist/auto-instrumentations/index.mjs +10 -1
  39. package/dist/auto-instrumentations/loader/cjs-patch.cjs +566 -221
  40. package/dist/auto-instrumentations/loader/cjs-patch.d.mts +2 -2
  41. package/dist/auto-instrumentations/loader/cjs-patch.d.ts +2 -2
  42. package/dist/auto-instrumentations/loader/cjs-patch.mjs +3 -2
  43. package/dist/auto-instrumentations/loader/esm-hook.mjs +1 -1
  44. package/dist/auto-instrumentations/plugin-B-aZh7EP.d.ts +30 -0
  45. package/dist/auto-instrumentations/plugin-Bnj4E_6B.d.mts +30 -0
  46. package/dist/auto-instrumentations/{types-RNPaKi9o.d.mts → types-C1fVeiCp.d.mts} +1 -1
  47. package/dist/auto-instrumentations/{types-RNPaKi9o.d.ts → types-C1fVeiCp.d.ts} +1 -1
  48. package/dist/browser.d.mts +871 -199
  49. package/dist/browser.d.ts +871 -199
  50. package/dist/browser.js +3737 -549
  51. package/dist/browser.mjs +3737 -549
  52. package/dist/{chunk-ABR2QWDP.mjs → chunk-CZM5JIQL.mjs} +788 -132
  53. package/dist/{chunk-P25IOOU4.js → chunk-MF7NU6BT.js} +795 -139
  54. package/dist/{chunk-GSIDVFE6.js → chunk-QRHGVBKU.js} +3580 -1463
  55. package/dist/{chunk-2SANLSWX.mjs → chunk-YKD22IMR.mjs} +2505 -388
  56. package/dist/cli.js +3244 -533
  57. package/dist/edge-light.d.mts +1 -1
  58. package/dist/edge-light.d.ts +1 -1
  59. package/dist/edge-light.js +3737 -552
  60. package/dist/edge-light.mjs +3737 -552
  61. package/dist/index.d.mts +871 -199
  62. package/dist/index.d.ts +871 -199
  63. package/dist/index.js +893 -446
  64. package/dist/index.mjs +463 -16
  65. package/dist/instrumentation/index.d.mts +138 -6
  66. package/dist/instrumentation/index.d.ts +138 -6
  67. package/dist/instrumentation/index.js +3362 -559
  68. package/dist/instrumentation/index.mjs +3362 -559
  69. package/dist/vitest-evals-reporter.js +45 -43
  70. package/dist/vitest-evals-reporter.mjs +5 -3
  71. package/dist/workerd.d.mts +1 -1
  72. package/dist/workerd.d.ts +1 -1
  73. package/dist/workerd.js +3737 -552
  74. package/dist/workerd.mjs +3737 -552
  75. package/licenses/node-diagnostics-channel/LICENSE +19 -0
  76. package/package.json +34 -35
  77. package/dist/auto-instrumentations/chunk-VT6DDNKM.mjs +0 -856
  78. package/dist/auto-instrumentations/plugin-D0KHwSJv.d.mts +0 -44
  79. package/dist/auto-instrumentations/plugin-G6fgxk1b.d.ts +0 -44
@@ -1,95 +1,6 @@
1
1
  // src/node/config.ts
2
2
  import { AsyncLocalStorage } from "node:async_hooks";
3
- import * as diagnostics_channel from "node:diagnostics_channel";
4
3
  import * as path from "node:path";
5
-
6
- // src/auto-instrumentations/patch-tracing-channel.ts
7
- function patchTracingChannel(tracingChannelFn) {
8
- const dummyChannel = tracingChannelFn("__braintrust_probe__");
9
- const TracingChannel = dummyChannel?.constructor;
10
- if (!TracingChannel?.prototype) {
11
- return;
12
- }
13
- if (!Object.getOwnPropertyDescriptor(TracingChannel.prototype, "hasSubscribers")) {
14
- Object.defineProperty(TracingChannel.prototype, "hasSubscribers", {
15
- configurable: true,
16
- enumerable: false,
17
- get() {
18
- return Boolean(
19
- this.start?.hasSubscribers || this.end?.hasSubscribers || this.asyncStart?.hasSubscribers || this.asyncEnd?.hasSubscribers || this.error?.hasSubscribers
20
- );
21
- }
22
- });
23
- }
24
- if (TracingChannel.prototype.tracePromise) {
25
- TracingChannel.prototype.tracePromise = function(fn, context = {}, thisArg, ...args) {
26
- const start = this.start;
27
- const end = this.end;
28
- const asyncStart = this.asyncStart;
29
- const asyncEnd = this.asyncEnd;
30
- const error = this.error;
31
- function publishRejected(err) {
32
- context.error = err;
33
- error?.publish(context);
34
- asyncStart?.publish(context);
35
- asyncEnd?.publish(context);
36
- }
37
- function publishResolved(result) {
38
- context.result = result;
39
- asyncStart?.publish(context);
40
- asyncEnd?.publish(context);
41
- }
42
- return start.runStores(context, () => {
43
- try {
44
- const result = Reflect.apply(fn, thisArg, args);
45
- end?.publish(context);
46
- if (result && (typeof result === "object" || typeof result === "function") && typeof result.then === "function") {
47
- if (result.constructor === Promise) {
48
- return result.then(
49
- (res) => {
50
- publishResolved(res);
51
- return res;
52
- },
53
- (err) => {
54
- publishRejected(err);
55
- return Promise.reject(err);
56
- }
57
- );
58
- }
59
- void result.then(
60
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
61
- (resolved) => {
62
- try {
63
- publishResolved(resolved);
64
- } catch {
65
- }
66
- },
67
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
68
- (err) => {
69
- try {
70
- publishRejected(err);
71
- } catch {
72
- }
73
- }
74
- );
75
- return result;
76
- }
77
- context.result = result;
78
- asyncStart?.publish(context);
79
- asyncEnd?.publish(context);
80
- return result;
81
- } catch (err) {
82
- context.error = err;
83
- error?.publish(context);
84
- end?.publish(context);
85
- throw err;
86
- }
87
- });
88
- };
89
- }
90
- }
91
-
92
- // src/node/config.ts
93
4
  import * as fs from "node:fs/promises";
94
5
  import * as os from "node:os";
95
6
  import * as fsSync from "node:fs";
@@ -98,84 +9,668 @@ import { promisify } from "node:util";
98
9
  import * as zlib from "node:zlib";
99
10
  import * as dotenv from "dotenv";
100
11
 
101
- // src/isomorph.ts
102
- var DefaultAsyncLocalStorage = class {
103
- constructor() {
104
- }
105
- enterWith(_) {
106
- }
107
- run(_, callback) {
108
- return callback();
12
+ // src/global-instrumentation-hooks.ts
13
+ var GLOBAL_INSTRUMENTATION_HOOKS_KEY = "__braintrust_instrumentation_hooks";
14
+ var GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION = 1;
15
+ var GLOBAL_INSTRUMENTATION_HOOKS_REGISTRY_BRAND = "braintrust.global-instrumentation-hooks.registry";
16
+ var GLOBAL_INSTRUMENTATION_HOOK_BRAND = "braintrust.global-instrumentation-hooks.hook";
17
+ var GLOBAL_INVOCATION_HOOK_BRAND = "braintrust.global-instrumentation-hooks.invocation-hook";
18
+ var registryBrand = Symbol.for(GLOBAL_INSTRUMENTATION_HOOKS_REGISTRY_BRAND);
19
+ var hookBrand = Symbol.for(GLOBAL_INSTRUMENTATION_HOOK_BRAND);
20
+ var invocationHookBrand = Symbol.for(GLOBAL_INVOCATION_HOOK_BRAND);
21
+ var errorReporter;
22
+ function setGlobalHookErrorReporter(reporter) {
23
+ const previousReporter = errorReporter;
24
+ errorReporter = reporter;
25
+ return () => {
26
+ if (errorReporter === reporter) {
27
+ errorReporter = previousReporter;
28
+ }
29
+ };
30
+ }
31
+ function reportError(error) {
32
+ try {
33
+ errorReporter?.(error);
34
+ } catch {
109
35
  }
110
- getStore() {
111
- return void 0;
36
+ }
37
+ function setContextValue(context, key, value) {
38
+ try {
39
+ context[key] = value;
40
+ } catch (error) {
41
+ reportError(error);
112
42
  }
113
- };
114
- var DefaultChannel = class {
43
+ }
44
+ function wrapStoreRun(store, message, next, transform) {
45
+ return () => {
46
+ let context;
47
+ try {
48
+ context = transform ? transform(message) : message;
49
+ } catch (error) {
50
+ reportError(error);
51
+ return next();
52
+ }
53
+ let called = false;
54
+ let result;
55
+ let providerError;
56
+ let providerThrew = false;
57
+ const runNext = () => {
58
+ if (called) {
59
+ reportError(
60
+ new Error(
61
+ "Instrumentation store invoked its callback more than once"
62
+ )
63
+ );
64
+ if (providerThrew) {
65
+ throw providerError;
66
+ }
67
+ return result;
68
+ }
69
+ called = true;
70
+ try {
71
+ result = next();
72
+ return result;
73
+ } catch (error) {
74
+ providerThrew = true;
75
+ providerError = error;
76
+ throw error;
77
+ }
78
+ };
79
+ try {
80
+ store.run(context, runNext);
81
+ } catch (error) {
82
+ if (!providerThrew || error !== providerError) {
83
+ reportError(error);
84
+ }
85
+ }
86
+ if (!called) {
87
+ reportError(
88
+ new Error("Instrumentation store did not invoke its callback")
89
+ );
90
+ return runNext();
91
+ }
92
+ if (providerThrew) {
93
+ throw providerError;
94
+ }
95
+ return result;
96
+ };
97
+ }
98
+ var HookChannel = class {
115
99
  constructor(name) {
116
100
  this.name = name;
117
101
  }
118
102
  name;
119
- hasSubscribers = false;
120
- subscribe(_subscription) {
103
+ subscribers = [];
104
+ stores = /* @__PURE__ */ new Map();
105
+ get hasSubscribers() {
106
+ return this.subscribers.length > 0 || this.stores.size > 0;
121
107
  }
122
- unsubscribe(_subscription) {
123
- return false;
108
+ subscribe(subscription) {
109
+ if (typeof subscription !== "function") {
110
+ throw new TypeError("subscription must be a function");
111
+ }
112
+ this.subscribers = [...this.subscribers, subscription];
124
113
  }
125
- bindStore(_store, _transform) {
114
+ unsubscribe(subscription) {
115
+ const index = this.subscribers.indexOf(subscription);
116
+ if (index === -1) {
117
+ return false;
118
+ }
119
+ this.subscribers = [
120
+ ...this.subscribers.slice(0, index),
121
+ ...this.subscribers.slice(index + 1)
122
+ ];
123
+ return true;
126
124
  }
127
- unbindStore(_store) {
128
- return false;
125
+ bindStore(store, transform) {
126
+ if (!store || typeof store.run !== "function") {
127
+ throw new TypeError("store must have a run method");
128
+ }
129
+ this.stores.set(
130
+ store,
131
+ transform
132
+ );
129
133
  }
130
- publish(_message) {
134
+ unbindStore(store) {
135
+ return this.stores.delete(store);
131
136
  }
132
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
133
- runStores(_message, fn, thisArg, ...args) {
134
- return fn.apply(thisArg, args);
137
+ publish(message) {
138
+ const subscribers = this.subscribers;
139
+ for (const subscriber of subscribers) {
140
+ try {
141
+ subscriber(message, this.name);
142
+ } catch (error) {
143
+ reportError(error);
144
+ }
145
+ }
146
+ }
147
+ runStores(message, fn, thisArg, ...args) {
148
+ let run = () => {
149
+ this.publish(message);
150
+ return Reflect.apply(fn, thisArg, args);
151
+ };
152
+ for (const [store, transform] of this.stores.entries()) {
153
+ run = wrapStoreRun(store, message, run, transform);
154
+ }
155
+ return run();
156
+ }
157
+ };
158
+ var traceEvents = [
159
+ "start",
160
+ "end",
161
+ "asyncStart",
162
+ "asyncEnd",
163
+ "error"
164
+ ];
165
+ function traceInvocation(hook, operator, target, thisArg, args, additional, callbackIndex = -1) {
166
+ const context = {
167
+ ...additional,
168
+ arguments: args,
169
+ self: thisArg
170
+ };
171
+ const invoke2 = () => hook.invoke(target, thisArg, args, additional);
172
+ if (operator === "traceCallback") {
173
+ return hook.traceCallback(invoke2, callbackIndex, context);
174
+ }
175
+ if (operator === "tracePromise") {
176
+ return hook.tracePromise(invoke2, context);
177
+ }
178
+ return hook.traceSync(invoke2, context);
179
+ }
180
+ var InvocationHook = class {
181
+ interceptors = [];
182
+ get hasInterceptors() {
183
+ return this.interceptors.length > 0;
184
+ }
185
+ intercept(interceptor) {
186
+ if (typeof interceptor !== "function") {
187
+ throw new TypeError("interceptor must be a function");
188
+ }
189
+ this.interceptors = [...this.interceptors, interceptor];
190
+ let active = true;
191
+ return () => {
192
+ if (!active) {
193
+ return;
194
+ }
195
+ active = false;
196
+ const index = this.interceptors.indexOf(interceptor);
197
+ if (index !== -1) {
198
+ this.interceptors = [
199
+ ...this.interceptors.slice(0, index),
200
+ ...this.interceptors.slice(index + 1)
201
+ ];
202
+ }
203
+ };
204
+ }
205
+ invoke(target, thisArg, args, additional) {
206
+ const interceptors = this.interceptors;
207
+ if (interceptors.length === 0) {
208
+ return Reflect.apply(target, thisArg, args);
209
+ }
210
+ let next = target;
211
+ for (let index = interceptors.length - 1; index >= 0; index -= 1) {
212
+ const interceptor = interceptors[index];
213
+ const downstream = next;
214
+ next = function(...nextArgs) {
215
+ return interceptor(downstream, this, nextArgs, additional);
216
+ };
217
+ }
218
+ return Reflect.apply(next, thisArg, args);
135
219
  }
136
220
  };
137
- var DefaultTracingChannel = class {
221
+ var TracingHook = class {
138
222
  start;
139
223
  end;
140
224
  asyncStart;
141
225
  asyncEnd;
142
226
  error;
227
+ invocationHook = new InvocationHook();
143
228
  constructor(nameOrChannels) {
229
+ Object.defineProperty(this, hookBrand, {
230
+ configurable: false,
231
+ enumerable: false,
232
+ value: GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION,
233
+ writable: false
234
+ });
235
+ Object.defineProperty(this, invocationHookBrand, {
236
+ configurable: false,
237
+ enumerable: false,
238
+ value: GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION,
239
+ writable: false
240
+ });
144
241
  if (typeof nameOrChannels === "string") {
145
- this.start = new DefaultChannel(`tracing:${nameOrChannels}:start`);
146
- this.end = new DefaultChannel(`tracing:${nameOrChannels}:end`);
147
- this.asyncStart = new DefaultChannel(
148
- `tracing:${nameOrChannels}:asyncStart`
149
- );
150
- this.asyncEnd = new DefaultChannel(`tracing:${nameOrChannels}:asyncEnd`);
151
- this.error = new DefaultChannel(`tracing:${nameOrChannels}:error`);
242
+ this.start = new HookChannel(`tracing:${nameOrChannels}:start`);
243
+ this.end = new HookChannel(`tracing:${nameOrChannels}:end`);
244
+ this.asyncStart = new HookChannel(`tracing:${nameOrChannels}:asyncStart`);
245
+ this.asyncEnd = new HookChannel(`tracing:${nameOrChannels}:asyncEnd`);
246
+ this.error = new HookChannel(`tracing:${nameOrChannels}:error`);
152
247
  return;
153
248
  }
154
- this.start = nameOrChannels.start ?? new DefaultChannel("tracing:start");
155
- this.end = nameOrChannels.end ?? new DefaultChannel("tracing:end");
156
- this.asyncStart = nameOrChannels.asyncStart ?? new DefaultChannel("tracing:asyncStart");
157
- this.asyncEnd = nameOrChannels.asyncEnd ?? new DefaultChannel("tracing:asyncEnd");
158
- this.error = nameOrChannels.error ?? new DefaultChannel("tracing:error");
249
+ this.start = nameOrChannels.start ?? new HookChannel("tracing:start");
250
+ this.end = nameOrChannels.end ?? new HookChannel("tracing:end");
251
+ this.asyncStart = nameOrChannels.asyncStart ?? new HookChannel("tracing:asyncStart");
252
+ this.asyncEnd = nameOrChannels.asyncEnd ?? new HookChannel("tracing:asyncEnd");
253
+ this.error = nameOrChannels.error ?? new HookChannel("tracing:error");
159
254
  }
160
255
  get hasSubscribers() {
161
256
  return this.start.hasSubscribers || this.end.hasSubscribers || this.asyncStart.hasSubscribers || this.asyncEnd.hasSubscribers || this.error.hasSubscribers;
162
257
  }
163
- subscribe(_handlers) {
258
+ get hasInterceptors() {
259
+ return this.invocationHook.hasInterceptors;
260
+ }
261
+ intercept(interceptor) {
262
+ return this.invocationHook.intercept(interceptor);
263
+ }
264
+ invoke(target, thisArg, args, additional) {
265
+ return this.invocationHook.invoke(target, thisArg, args, additional);
266
+ }
267
+ traceInvocation(operator, target, thisArg, args, additional, callbackIndex = -1) {
268
+ return traceInvocation(
269
+ this,
270
+ operator,
271
+ target,
272
+ thisArg,
273
+ args,
274
+ additional,
275
+ callbackIndex
276
+ );
277
+ }
278
+ subscribe(handlers) {
279
+ for (const eventName of traceEvents) {
280
+ const handler = handlers[eventName];
281
+ if (handler) {
282
+ this[eventName].subscribe(handler);
283
+ }
284
+ }
164
285
  }
165
- unsubscribe(_handlers) {
286
+ unsubscribe(handlers) {
287
+ let done = true;
288
+ for (const eventName of traceEvents) {
289
+ const handler = handlers[eventName];
290
+ if (handler && !this[eventName].unsubscribe(handler)) {
291
+ done = false;
292
+ }
293
+ }
294
+ return done;
295
+ }
296
+ traceSync(fn, message = {}, thisArg, ...args) {
297
+ if (!this.hasSubscribers) {
298
+ return Reflect.apply(fn, thisArg, args);
299
+ }
300
+ const context = message;
301
+ return this.start.runStores(message, () => {
302
+ try {
303
+ const result = Reflect.apply(fn, thisArg, args);
304
+ setContextValue(context, "result", result);
305
+ return result;
306
+ } catch (error) {
307
+ setContextValue(context, "error", error);
308
+ this.error.publish(message);
309
+ throw error;
310
+ } finally {
311
+ this.end.publish(message);
312
+ }
313
+ });
314
+ }
315
+ tracePromise(fn, message = {}, thisArg, ...args) {
316
+ if (!this.hasSubscribers) {
317
+ return Reflect.apply(fn, thisArg, args);
318
+ }
319
+ const context = message;
320
+ return this.start.runStores(message, () => {
321
+ let result;
322
+ try {
323
+ result = Reflect.apply(fn, thisArg, args);
324
+ } catch (error) {
325
+ setContextValue(context, "error", error);
326
+ this.error.publish(message);
327
+ this.end.publish(message);
328
+ throw error;
329
+ }
330
+ this.end.publish(message);
331
+ if (!result || typeof result !== "object" && typeof result !== "function") {
332
+ setContextValue(context, "result", result);
333
+ this.asyncStart.publish(message);
334
+ this.asyncEnd.publish(message);
335
+ return result;
336
+ }
337
+ let terminalPublished = false;
338
+ const finishUnobservedResult = (error) => {
339
+ reportError(error);
340
+ if (!terminalPublished) {
341
+ terminalPublished = true;
342
+ setContextValue(context, "result", result);
343
+ this.asyncStart.publish(message);
344
+ this.asyncEnd.publish(message);
345
+ }
346
+ return result;
347
+ };
348
+ let then;
349
+ try {
350
+ then = result.then;
351
+ } catch (error) {
352
+ return finishUnobservedResult(error);
353
+ }
354
+ if (typeof then !== "function") {
355
+ setContextValue(context, "result", result);
356
+ this.asyncStart.publish(message);
357
+ this.asyncEnd.publish(message);
358
+ return result;
359
+ }
360
+ const resolve = (resolved) => {
361
+ if (!terminalPublished) {
362
+ terminalPublished = true;
363
+ setContextValue(context, "result", resolved);
364
+ this.asyncStart.publish(message);
365
+ this.asyncEnd.publish(message);
366
+ }
367
+ return resolved;
368
+ };
369
+ let rejectionThrown = false;
370
+ let rejectionError;
371
+ const reject2 = (error) => {
372
+ if (!terminalPublished) {
373
+ terminalPublished = true;
374
+ setContextValue(context, "error", error);
375
+ this.error.publish(message);
376
+ this.asyncStart.publish(message);
377
+ this.asyncEnd.publish(message);
378
+ }
379
+ rejectionThrown = true;
380
+ rejectionError = error;
381
+ throw error;
382
+ };
383
+ let isPlainPromise;
384
+ try {
385
+ isPlainPromise = result instanceof Promise && result.constructor === Promise;
386
+ } catch (error) {
387
+ return finishUnobservedResult(error);
388
+ }
389
+ try {
390
+ if (isPlainPromise) {
391
+ return Reflect.apply(then, result, [resolve, reject2]);
392
+ }
393
+ Reflect.apply(then, result, [
394
+ resolve,
395
+ (error) => {
396
+ try {
397
+ reject2(error);
398
+ } catch {
399
+ }
400
+ }
401
+ ]);
402
+ } catch (error) {
403
+ if (rejectionThrown && error === rejectionError) {
404
+ return result;
405
+ }
406
+ return finishUnobservedResult(error);
407
+ }
408
+ return result;
409
+ });
410
+ }
411
+ traceCallback(fn, position = -1, message = {}, thisArg, ...args) {
412
+ if (!this.hasSubscribers) {
413
+ return Reflect.apply(fn, thisArg, args);
414
+ }
415
+ const context = message;
416
+ const callArgs = args.length > 0 ? args : context.arguments ?? args;
417
+ const callback = Array.prototype.at.call(callArgs, position);
418
+ if (typeof callback !== "function") {
419
+ return Reflect.apply(fn, thisArg, args);
420
+ }
421
+ const { asyncStart, asyncEnd, error: errorChannel } = this;
422
+ function wrappedCallback(error, result) {
423
+ if (error) {
424
+ setContextValue(context, "error", error);
425
+ errorChannel.publish(message);
426
+ } else {
427
+ setContextValue(context, "result", result);
428
+ }
429
+ return asyncStart.runStores(message, () => {
430
+ try {
431
+ return Reflect.apply(callback, this, arguments);
432
+ } finally {
433
+ asyncEnd.publish(message);
434
+ }
435
+ });
436
+ }
437
+ Array.prototype.splice.call(callArgs, position, 1, wrappedCallback);
438
+ return this.start.runStores(message, () => {
439
+ try {
440
+ return Reflect.apply(fn, thisArg, args);
441
+ } catch (error) {
442
+ setContextValue(context, "error", error);
443
+ this.error.publish(message);
444
+ throw error;
445
+ } finally {
446
+ this.end.publish(message);
447
+ }
448
+ });
449
+ }
450
+ };
451
+ var inertChannel = Object.freeze({
452
+ name: "braintrust:inert",
453
+ hasSubscribers: false,
454
+ subscribe() {
455
+ },
456
+ unsubscribe() {
166
457
  return false;
458
+ },
459
+ bindStore() {
460
+ },
461
+ unbindStore() {
462
+ return false;
463
+ },
464
+ publish() {
465
+ },
466
+ runStores(_message, fn, thisArg, ...args) {
467
+ return Reflect.apply(fn, thisArg, args);
167
468
  }
168
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
169
- traceSync(fn, _message, thisArg, ...args) {
170
- return fn.apply(thisArg, args);
469
+ });
470
+ var inertTracingHook = new TracingHook({
471
+ start: inertChannel,
472
+ end: inertChannel,
473
+ asyncStart: inertChannel,
474
+ asyncEnd: inertChannel,
475
+ error: inertChannel
476
+ });
477
+ function isHookChannel(value) {
478
+ if (typeof value !== "object" && typeof value !== "function" || value === null) {
479
+ return false;
171
480
  }
172
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
173
- tracePromise(fn, _message, thisArg, ...args) {
174
- return fn.apply(thisArg, args);
481
+ try {
482
+ const channel2 = value;
483
+ return typeof channel2.hasSubscribers === "boolean" && typeof channel2.subscribe === "function" && typeof channel2.unsubscribe === "function" && typeof channel2.bindStore === "function" && typeof channel2.unbindStore === "function" && typeof channel2.publish === "function" && typeof channel2.runStores === "function";
484
+ } catch {
485
+ return false;
175
486
  }
176
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
177
- traceCallback(fn, _position, _message, thisArg, ...args) {
178
- return fn.apply(thisArg, args);
487
+ }
488
+ function hasTracingHookShape(value) {
489
+ if (typeof value !== "object" && typeof value !== "function" || value === null) {
490
+ return false;
491
+ }
492
+ try {
493
+ const hook = value;
494
+ return typeof hook.hasSubscribers === "boolean" && typeof hook.subscribe === "function" && typeof hook.unsubscribe === "function" && typeof hook.traceSync === "function" && typeof hook.tracePromise === "function" && typeof hook.traceCallback === "function" && isHookChannel(hook.start) && isHookChannel(hook.end) && isHookChannel(hook.asyncStart) && isHookChannel(hook.asyncEnd) && isHookChannel(hook.error);
495
+ } catch {
496
+ return false;
497
+ }
498
+ }
499
+ function hasInvocationHookShape(value) {
500
+ if (typeof value !== "object" && typeof value !== "function" || value === null) {
501
+ return false;
502
+ }
503
+ try {
504
+ const hook = value;
505
+ return value[invocationHookBrand] === GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION && typeof hook.hasInterceptors === "boolean" && typeof hook.intercept === "function" && typeof hook.invoke === "function";
506
+ } catch {
507
+ return false;
508
+ }
509
+ }
510
+ function installInvocationHook(value) {
511
+ const hasInvocationHook = hasInvocationHookShape(value);
512
+ const invocationHook = new InvocationHook();
513
+ try {
514
+ if (!hasInvocationHook) {
515
+ Object.defineProperties(value, {
516
+ [invocationHookBrand]: {
517
+ configurable: false,
518
+ enumerable: false,
519
+ value: GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION,
520
+ writable: false
521
+ },
522
+ hasInterceptors: {
523
+ configurable: false,
524
+ enumerable: false,
525
+ get: () => invocationHook.hasInterceptors
526
+ },
527
+ intercept: {
528
+ configurable: false,
529
+ enumerable: false,
530
+ value: invocationHook.intercept.bind(invocationHook),
531
+ writable: false
532
+ },
533
+ invoke: {
534
+ configurable: false,
535
+ enumerable: false,
536
+ value: invocationHook.invoke.bind(invocationHook),
537
+ writable: false
538
+ }
539
+ });
540
+ }
541
+ if (typeof value.traceInvocation !== "function") {
542
+ Object.defineProperty(value, "traceInvocation", {
543
+ configurable: false,
544
+ enumerable: false,
545
+ value: traceInvocation.bind(void 0, value),
546
+ writable: false
547
+ });
548
+ }
549
+ } catch (error) {
550
+ reportError(error);
551
+ }
552
+ }
553
+ function isCompatibleTracingHook(value) {
554
+ try {
555
+ return value[hookBrand] === GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION && hasTracingHookShape(value);
556
+ } catch {
557
+ return false;
558
+ }
559
+ }
560
+ function isCompatibleHookRegistry(value) {
561
+ try {
562
+ return value instanceof Map && value[registryBrand] === GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION;
563
+ } catch {
564
+ return false;
565
+ }
566
+ }
567
+ function getHookRegistry() {
568
+ let descriptor;
569
+ try {
570
+ descriptor = Object.getOwnPropertyDescriptor(
571
+ globalThis,
572
+ GLOBAL_INSTRUMENTATION_HOOKS_KEY
573
+ );
574
+ } catch (error) {
575
+ reportError(error);
576
+ return void 0;
577
+ }
578
+ if (descriptor && "value" in descriptor && isCompatibleHookRegistry(descriptor.value) && (descriptor.configurable || descriptor.enumerable === false)) {
579
+ if (descriptor.configurable || descriptor.writable) {
580
+ try {
581
+ Object.defineProperty(globalThis, GLOBAL_INSTRUMENTATION_HOOKS_KEY, {
582
+ configurable: false,
583
+ enumerable: false,
584
+ value: descriptor.value,
585
+ writable: false
586
+ });
587
+ } catch (error) {
588
+ reportError(error);
589
+ return void 0;
590
+ }
591
+ }
592
+ return descriptor.value;
593
+ }
594
+ if (descriptor && !descriptor.configurable) {
595
+ reportError(new Error("Incompatible global instrumentation hook registry"));
596
+ return void 0;
597
+ }
598
+ const registry2 = /* @__PURE__ */ new Map();
599
+ try {
600
+ Object.defineProperty(registry2, registryBrand, {
601
+ configurable: false,
602
+ enumerable: false,
603
+ value: GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION,
604
+ writable: false
605
+ });
606
+ } catch (error) {
607
+ reportError(error);
608
+ return void 0;
609
+ }
610
+ try {
611
+ Object.defineProperty(globalThis, GLOBAL_INSTRUMENTATION_HOOKS_KEY, {
612
+ configurable: false,
613
+ enumerable: false,
614
+ value: registry2,
615
+ writable: false
616
+ });
617
+ return registry2;
618
+ } catch (error) {
619
+ reportError(error);
620
+ return void 0;
621
+ }
622
+ }
623
+ function newGlobalTracingChannel(nameOrChannels) {
624
+ if (typeof nameOrChannels !== "string") {
625
+ return new TracingHook(nameOrChannels);
626
+ }
627
+ const registry2 = getHookRegistry();
628
+ if (!registry2) {
629
+ return inertTracingHook;
630
+ }
631
+ let existing;
632
+ try {
633
+ existing = Map.prototype.get.call(registry2, nameOrChannels);
634
+ } catch (error) {
635
+ reportError(error);
636
+ return inertTracingHook;
637
+ }
638
+ if (isCompatibleTracingHook(existing)) {
639
+ installInvocationHook(existing);
640
+ return existing;
641
+ }
642
+ if (existing !== void 0) {
643
+ reportError(
644
+ new Error(`Invalid global instrumentation hook: ${nameOrChannels}`)
645
+ );
646
+ try {
647
+ Map.prototype.delete.call(registry2, nameOrChannels);
648
+ } catch (error) {
649
+ reportError(error);
650
+ return inertTracingHook;
651
+ }
652
+ }
653
+ const hook = new TracingHook(nameOrChannels);
654
+ try {
655
+ Map.prototype.set.call(registry2, nameOrChannels, hook);
656
+ } catch (error) {
657
+ reportError(error);
658
+ return inertTracingHook;
659
+ }
660
+ return hook;
661
+ }
662
+
663
+ // src/isomorph.ts
664
+ var DefaultAsyncLocalStorage = class {
665
+ constructor() {
666
+ }
667
+ enterWith(_) {
668
+ }
669
+ run(_, callback) {
670
+ return callback();
671
+ }
672
+ getStore() {
673
+ return void 0;
179
674
  }
180
675
  };
181
676
  var iso = {
@@ -188,7 +683,7 @@ var iso = {
188
683
  getCallerLocation: () => void 0,
189
684
  newAsyncLocalStorage: () => new DefaultAsyncLocalStorage(),
190
685
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
191
- newTracingChannel: (nameOrChannels) => new DefaultTracingChannel(nameOrChannels),
686
+ newTracingChannel: (nameOrChannels) => newGlobalTracingChannel(nameOrChannels),
192
687
  processOn: (_0, _1) => {
193
688
  },
194
689
  basename: (filepath) => filepath.split(/[\\/]/).pop() || filepath,
@@ -301,6 +796,9 @@ var debugLogger = {
301
796
  return createDebugLogger(state);
302
797
  }
303
798
  };
799
+ setGlobalHookErrorReporter((error) => {
800
+ debugLogger.error("Global instrumentation hook error:", error);
801
+ });
304
802
 
305
803
  // src/gitutil.ts
306
804
  import { simpleGit } from "simple-git";
@@ -2317,7 +2815,8 @@ var ApiKey = z6.object({
2317
2815
  user_email: z6.union([z6.string(), z6.null()]).optional(),
2318
2816
  user_given_name: z6.union([z6.string(), z6.null()]).optional(),
2319
2817
  user_family_name: z6.union([z6.string(), z6.null()]).optional(),
2320
- org_id: z6.union([z6.string(), z6.null()]).optional()
2818
+ org_id: z6.union([z6.string(), z6.null()]).optional(),
2819
+ expires_at: z6.union([z6.string(), z6.null()]).optional()
2321
2820
  });
2322
2821
  var TriggeredFunctionState = z6.object({
2323
2822
  triggered_xact_id: z6.string(),
@@ -2437,6 +2936,7 @@ var TopicMapData = z6.object({
2437
2936
  topic_names: z6.record(z6.string()).optional(),
2438
2937
  generation_settings: TopicMapGenerationSettings.optional(),
2439
2938
  disable_reconciliation: z6.boolean().optional(),
2939
+ reconcile_mode: z6.enum(["evolve", "names_only"]).optional(),
2440
2940
  distance_threshold: z6.number().optional(),
2441
2941
  btql_filter: z6.string().optional(),
2442
2942
  automation_btql_filter: z6.string().optional()
@@ -3017,7 +3517,12 @@ var ModelParams = z6.union([
3017
3517
  }).partial().passthrough()
3018
3518
  ]);
3019
3519
  var PromptOptionsNullish = z6.union([
3020
- z6.object({ model: z6.string(), params: ModelParams, position: z6.string() }).partial(),
3520
+ z6.object({
3521
+ model: z6.string(),
3522
+ params: ModelParams,
3523
+ position: z6.string(),
3524
+ endpoint_name: z6.union([z6.string(), z6.null()])
3525
+ }).partial(),
3021
3526
  z6.null()
3022
3527
  ]);
3023
3528
  var PromptParserNullish = z6.union([
@@ -3031,11 +3536,25 @@ var PromptParserNullish = z6.union([
3031
3536
  }),
3032
3537
  z6.null()
3033
3538
  ]);
3539
+ var PreprocessorSavedFunctionId = z6.union([
3540
+ z6.object({
3541
+ type: z6.literal("function"),
3542
+ id: z6.string(),
3543
+ version: z6.string().optional()
3544
+ }),
3545
+ z6.object({
3546
+ type: z6.literal("global"),
3547
+ name: z6.string(),
3548
+ function_type: z6.literal("preprocessor").optional().default("preprocessor")
3549
+ }),
3550
+ z6.null()
3551
+ ]);
3034
3552
  var PromptDataNullish = z6.union([
3035
3553
  z6.object({
3036
3554
  prompt: PromptBlockDataNullish,
3037
3555
  options: PromptOptionsNullish,
3038
3556
  parser: PromptParserNullish,
3557
+ preprocessor: PreprocessorSavedFunctionId,
3039
3558
  tool_functions: z6.union([z6.array(SavedFunctionId), z6.null()]),
3040
3559
  template_format: z6.union([
3041
3560
  z6.enum(["mustache", "nunjucks", "none"]),
@@ -3237,6 +3756,7 @@ var PromptData = z6.object({
3237
3756
  prompt: PromptBlockDataNullish,
3238
3757
  options: PromptOptionsNullish,
3239
3758
  parser: PromptParserNullish,
3759
+ preprocessor: PreprocessorSavedFunctionId,
3240
3760
  tool_functions: z6.union([z6.array(SavedFunctionId), z6.null()]),
3241
3761
  template_format: z6.union([
3242
3762
  z6.enum(["mustache", "nunjucks", "none"]),
@@ -3399,7 +3919,8 @@ var InvokeFunction = FunctionId.and(
3399
3919
  mode: StreamingMode,
3400
3920
  strict: z6.union([z6.boolean(), z6.null()]),
3401
3921
  mcp_auth: z6.record(z6.object({ oauth_token: z6.string() }).partial()),
3402
- overrides: z6.union([z6.object({}).partial().passthrough(), z6.null()])
3922
+ overrides: z6.union([z6.object({}).partial().passthrough(), z6.null()]),
3923
+ endpoint_name: z6.union([z6.string(), z6.null()])
3403
3924
  }).partial()
3404
3925
  );
3405
3926
  var MCPServer = z6.object({
@@ -3463,6 +3984,24 @@ var Organization = z6.object({
3463
3984
  created: z6.union([z6.string(), z6.null()]).optional(),
3464
3985
  image_rendering_mode: ImageRenderingMode.optional()
3465
3986
  });
3987
+ var RetentionObjectType = z6.enum([
3988
+ "project_logs",
3989
+ "experiment",
3990
+ "dataset"
3991
+ ]);
3992
+ var OrgAutomation = z6.object({
3993
+ id: z6.string().uuid(),
3994
+ org_id: z6.string().uuid(),
3995
+ user_id: z6.union([z6.string(), z6.null()]).optional(),
3996
+ created: z6.union([z6.string(), z6.null()]).optional(),
3997
+ name: z6.string(),
3998
+ description: z6.union([z6.string(), z6.null()]).optional(),
3999
+ config: z6.object({
4000
+ event_type: z6.literal("retention"),
4001
+ object_type: RetentionObjectType,
4002
+ retention_days: z6.number().int().gte(0)
4003
+ })
4004
+ });
3466
4005
  var ProjectSettings = z6.union([
3467
4006
  z6.object({
3468
4007
  comparison_key: z6.union([z6.string(), z6.null()]),
@@ -3489,6 +4028,7 @@ var ProjectSettings = z6.union([
3489
4028
  z6.null()
3490
4029
  ]),
3491
4030
  disable_realtime_queries: z6.union([z6.boolean(), z6.null()]),
4031
+ monitor_charts_use_metrics_start: z6.union([z6.boolean(), z6.null()]),
3492
4032
  default_preprocessor: NullableSavedFunctionId
3493
4033
  }).partial(),
3494
4034
  z6.null()
@@ -3503,11 +4043,6 @@ var Project = z6.object({
3503
4043
  user_id: z6.union([z6.string(), z6.null()]).optional(),
3504
4044
  settings: ProjectSettings.optional()
3505
4045
  });
3506
- var RetentionObjectType = z6.enum([
3507
- "project_logs",
3508
- "experiment",
3509
- "dataset"
3510
- ]);
3511
4046
  var TopicAutomationFacetModel = z6.union([
3512
4047
  z6.enum(["brain-facet-latest", "brain-facet-1", "brain-facet-2"]),
3513
4048
  z6.null()
@@ -3618,7 +4153,7 @@ var ProjectAutomation = z6.object({
3618
4153
  z6.object({
3619
4154
  event_type: z6.literal("retention"),
3620
4155
  object_type: RetentionObjectType,
3621
- retention_days: z6.number().gte(0)
4156
+ retention_days: z6.number().int().gte(0)
3622
4157
  }),
3623
4158
  z6.object({
3624
4159
  event_type: z6.literal("environment_update"),
@@ -3790,7 +4325,12 @@ var Prompt = z6.object({
3790
4325
  metadata: z6.union([z6.object({}).partial().passthrough(), z6.null()]).optional(),
3791
4326
  function_type: FunctionTypeEnumNullish.optional()
3792
4327
  });
3793
- var PromptOptions = z6.object({ model: z6.string(), params: ModelParams, position: z6.string() }).partial();
4328
+ var PromptOptions = z6.object({
4329
+ model: z6.string(),
4330
+ params: ModelParams,
4331
+ position: z6.string(),
4332
+ endpoint_name: z6.union([z6.string(), z6.null()])
4333
+ }).partial();
3794
4334
  var PromptSessionEvent = z6.object({
3795
4335
  id: z6.string(),
3796
4336
  _xact_id: z6.string(),
@@ -3873,7 +4413,8 @@ var RunEval = z6.object({
3873
4413
  stop_token: z6.union([z6.string(), z6.null()]).optional(),
3874
4414
  extra_messages: z6.string().optional(),
3875
4415
  tags: z6.array(z6.string()).optional(),
3876
- mcp_auth: z6.record(z6.object({ oauth_token: z6.string() }).partial()).optional()
4416
+ mcp_auth: z6.record(z6.object({ oauth_token: z6.string() }).partial()).optional(),
4417
+ endpoint_name: z6.union([z6.string(), z6.null()]).optional()
3877
4418
  });
3878
4419
  var ServiceToken = z6.object({
3879
4420
  id: z6.string().uuid(),
@@ -3883,7 +4424,8 @@ var ServiceToken = z6.object({
3883
4424
  service_account_id: z6.union([z6.string(), z6.null()]).optional(),
3884
4425
  service_account_email: z6.union([z6.string(), z6.null()]).optional(),
3885
4426
  service_account_name: z6.union([z6.string(), z6.null()]).optional(),
3886
- org_id: z6.union([z6.string(), z6.null()]).optional()
4427
+ org_id: z6.union([z6.string(), z6.null()]).optional(),
4428
+ expires_at: z6.union([z6.string(), z6.null()]).optional()
3887
4429
  });
3888
4430
  var SpanIFrame = z6.object({
3889
4431
  id: z6.string().uuid(),
@@ -4005,6 +4547,13 @@ var ViewOptions = z6.union([
4005
4547
  }),
4006
4548
  z6.null()
4007
4549
  ]),
4550
+ pointSizeMetric: z6.union([
4551
+ z6.object({
4552
+ type: z6.enum(["none", "score", "metric", "metadata"]),
4553
+ value: z6.string()
4554
+ }),
4555
+ z6.null()
4556
+ ]),
4008
4557
  xAxisAggregation: z6.union([z6.string(), z6.null()]),
4009
4558
  chartAnnotations: z6.union([
4010
4559
  z6.array(z6.object({ id: z6.string(), text: z6.string() })),
@@ -5148,6 +5697,9 @@ var INSTRUMENTATION_NAMES = {
5148
5697
  BEDROCK_RUNTIME: "bedrock-runtime",
5149
5698
  BRAINTRUST_JS_LOGGER: "braintrust-js-logger",
5150
5699
  CLAUDE_AGENT_SDK: "claude-agent-sdk",
5700
+ CLOUDFLARE_AI_CHAT: "cloudflare-ai-chat",
5701
+ CLOUDFLARE_AGENTS: "cloudflare-agents",
5702
+ CLOUDFLARE_THINK: "cloudflare-think",
5151
5703
  COHERE: "cohere",
5152
5704
  CURSOR_SDK: "cursor-sdk",
5153
5705
  EVE: "eve",
@@ -5162,6 +5714,7 @@ var INSTRUMENTATION_NAMES = {
5162
5714
  LANGSMITH: "langsmith",
5163
5715
  MASTRA: "mastra",
5164
5716
  MISTRAL: "mistral",
5717
+ OLLAMA: "ollama",
5165
5718
  OPENAI: "openai",
5166
5719
  OPENAI_AGENTS: "openai-agents",
5167
5720
  OPENAI_CODEX: "openai-codex",
@@ -5173,7 +5726,7 @@ var INSTRUMENTATION_NAMES = {
5173
5726
  var INTERNAL_SPAN_INSTRUMENTATION_NAME = /* @__PURE__ */ Symbol.for(
5174
5727
  "braintrust.spanInstrumentationName"
5175
5728
  );
5176
- var SDK_VERSION = true ? "3.25.0" : "0.0.0";
5729
+ var SDK_VERSION = true ? "3.27.0" : "0.0.0";
5177
5730
  function withSpanInstrumentationName(args, instrumentationName) {
5178
5731
  return {
5179
5732
  ...args,
@@ -5368,12 +5921,13 @@ function applyMaskingToField(maskingFunction, data, fieldName) {
5368
5921
  var INITIAL_SPAN_WRITE_AS_MERGE = /* @__PURE__ */ Symbol(
5369
5922
  "braintrust.initial-span-write-as-merge"
5370
5923
  );
5924
+ var INTERNAL_SPAN_CONTEXT = /* @__PURE__ */ Symbol("braintrust.internal-span-context");
5371
5925
  var BRAINTRUST_CURRENT_SPAN_STORE = /* @__PURE__ */ Symbol.for(
5372
5926
  "braintrust.currentSpanStore"
5373
5927
  );
5374
5928
  var ContextManager = class {
5375
5929
  /**
5376
- * Returns the value to store in the ALS bound to a TracingChannel's start event.
5930
+ * Returns the value to store in the ALS bound to a global hook's start event.
5377
5931
  * In default mode this is the Span itself; in OTEL mode it is the OTEL Context
5378
5932
  * containing the span so that OTEL's own ALS stores a proper Context object.
5379
5933
  */
@@ -8435,6 +8989,12 @@ function _internalStartSpanWithInitialMerge(args) {
8435
8989
  [INITIAL_SPAN_WRITE_AS_MERGE]: true
8436
8990
  }).span;
8437
8991
  }
8992
+ function _internalStartSpanWithContext(args, context) {
8993
+ return startSpanAndIsLogger({
8994
+ ...args,
8995
+ [INTERNAL_SPAN_CONTEXT]: context
8996
+ }).span;
8997
+ }
8438
8998
  async function flush(options) {
8439
8999
  const state = options?.state ?? _globalState;
8440
9000
  return await state.bgLogger().flush();
@@ -9287,7 +9847,7 @@ var SpanImpl = class _SpanImpl {
9287
9847
  start: args.startTime ?? getCurrentUnixTimestamp()
9288
9848
  },
9289
9849
  context: mergeSpanOriginContext(
9290
- { ...callerLocation },
9850
+ { ...callerLocation, ...args[INTERNAL_SPAN_CONTEXT] },
9291
9851
  instrumentationName,
9292
9852
  this._state.spanOriginEnvironment
9293
9853
  ),
@@ -10487,6 +11047,34 @@ function patchStreamIfNeeded(stream, options) {
10487
11047
  );
10488
11048
  return stream;
10489
11049
  }
11050
+ const chunks = [];
11051
+ let completed = false;
11052
+ const notifyCancellation = async () => {
11053
+ try {
11054
+ await (options.onCancel ?? options.onComplete)(chunks);
11055
+ } catch (error) {
11056
+ debugLogger.error("Error in stream cancellation handler:", error);
11057
+ }
11058
+ };
11059
+ const patchAbortIfPresent = () => {
11060
+ try {
11061
+ if ("abort" in stream && typeof stream.abort === "function") {
11062
+ const originalAbort = stream.abort.bind(stream);
11063
+ stream.abort = (...args) => {
11064
+ try {
11065
+ return originalAbort(...args);
11066
+ } finally {
11067
+ if (!completed) {
11068
+ completed = true;
11069
+ void notifyCancellation();
11070
+ }
11071
+ }
11072
+ };
11073
+ }
11074
+ } catch (error) {
11075
+ debugLogger.warn("Failed to patch stream abort method:", error);
11076
+ }
11077
+ };
10490
11078
  if (hasAsyncIteratorMethods(stream) && isSelfAsyncIterator(stream)) {
10491
11079
  if ("__braintrust_patched_iterator_methods" in stream) {
10492
11080
  return stream;
@@ -10495,8 +11083,6 @@ function patchStreamIfNeeded(stream, options) {
10495
11083
  const originalNext = stream.next.bind(stream);
10496
11084
  const originalReturn = typeof stream.return === "function" ? stream.return.bind(stream) : null;
10497
11085
  const originalThrow = typeof stream.throw === "function" ? stream.throw.bind(stream) : null;
10498
- const chunks = [];
10499
- let completed = false;
10500
11086
  stream.next = async (...args) => {
10501
11087
  try {
10502
11088
  const result = await runNextWithWrapper(
@@ -10548,11 +11134,7 @@ function patchStreamIfNeeded(stream, options) {
10548
11134
  stream.return = async (...args) => {
10549
11135
  if (!completed) {
10550
11136
  completed = true;
10551
- try {
10552
- await options.onComplete(chunks);
10553
- } catch (error) {
10554
- console.error("Error in stream onComplete handler:", error);
10555
- }
11137
+ await notifyCancellation();
10556
11138
  }
10557
11139
  return originalReturn(...args);
10558
11140
  };
@@ -10577,6 +11159,7 @@ function patchStreamIfNeeded(stream, options) {
10577
11159
  Object.defineProperty(stream, "__braintrust_patched_iterator_methods", {
10578
11160
  value: true
10579
11161
  });
11162
+ patchAbortIfPresent();
10580
11163
  return stream;
10581
11164
  } catch (error) {
10582
11165
  console.warn("Failed to patch stream iterator methods:", error);
@@ -10590,8 +11173,6 @@ function patchStreamIfNeeded(stream, options) {
10590
11173
  const patchedIteratorFn = function() {
10591
11174
  const iterator = originalIteratorFn.call(this);
10592
11175
  const originalNext = iterator.next.bind(iterator);
10593
- const chunks = [];
10594
- let completed = false;
10595
11176
  iterator.next = async function(...args) {
10596
11177
  try {
10597
11178
  const result = await runNextWithWrapper(
@@ -10644,11 +11225,7 @@ function patchStreamIfNeeded(stream, options) {
10644
11225
  iterator.return = async function(...args) {
10645
11226
  if (!completed) {
10646
11227
  completed = true;
10647
- try {
10648
- await options.onComplete(chunks);
10649
- } catch (error) {
10650
- console.error("Error in stream onComplete handler:", error);
10651
- }
11228
+ await notifyCancellation();
10652
11229
  }
10653
11230
  return originalReturn(...args);
10654
11231
  };
@@ -10677,6 +11254,7 @@ function patchStreamIfNeeded(stream, options) {
10677
11254
  value: true
10678
11255
  });
10679
11256
  stream[Symbol.asyncIterator] = patchedIteratorFn;
11257
+ patchAbortIfPresent();
10680
11258
  return stream;
10681
11259
  } catch (error) {
10682
11260
  console.warn("Failed to patch stream:", error);
@@ -11129,8 +11707,8 @@ function runWithAutoInstrumentationSuppressed(callback) {
11129
11707
  callback
11130
11708
  );
11131
11709
  }
11132
- function bindAutoInstrumentationSuppressionToStart(tracingChannel2) {
11133
- const startChannel = tracingChannel2.start;
11710
+ function bindAutoInstrumentationSuppressionToStart(tracingChannel) {
11711
+ const startChannel = tracingChannel.start;
11134
11712
  if (!startChannel) {
11135
11713
  return void 0;
11136
11714
  }
@@ -11241,9 +11819,9 @@ function ensureSpanStateForEvent(states, config, event, channelName, instrumenta
11241
11819
  states.set(key, created);
11242
11820
  return created;
11243
11821
  }
11244
- function bindCurrentSpanStoreToStart(tracingChannel2, states, config, channelName, instrumentationName) {
11822
+ function bindCurrentSpanStoreToStart(tracingChannel, states, config, channelName, instrumentationName) {
11245
11823
  const state = _internalGetGlobalState();
11246
- const startChannel = tracingChannel2.start;
11824
+ const startChannel = tracingChannel.start;
11247
11825
  const contextManager = state?.contextManager;
11248
11826
  const currentSpanStore = contextManager ? contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
11249
11827
  if (!currentSpanStore || !startChannel) {
@@ -11326,11 +11904,11 @@ function runStreamingErrorHook(args) {
11326
11904
  }
11327
11905
  }
11328
11906
  function traceAsyncChannel(channel2, config) {
11329
- const tracingChannel2 = channel2.tracingChannel();
11907
+ const tracingChannel = channel2.tracingChannel();
11330
11908
  const states = /* @__PURE__ */ new WeakMap();
11331
11909
  const channelName = channel2.channelName;
11332
11910
  const unbindCurrentSpanStore = bindCurrentSpanStoreToStart(
11333
- tracingChannel2,
11911
+ tracingChannel,
11334
11912
  states,
11335
11913
  config,
11336
11914
  channelName,
@@ -11386,18 +11964,18 @@ function traceAsyncChannel(channel2, config) {
11386
11964
  logErrorAndEnd(states, event, channelName);
11387
11965
  }
11388
11966
  };
11389
- tracingChannel2.subscribe(handlers);
11967
+ tracingChannel.subscribe(handlers);
11390
11968
  return () => {
11391
11969
  unbindCurrentSpanStore?.();
11392
- tracingChannel2.unsubscribe(handlers);
11970
+ tracingChannel.unsubscribe(handlers);
11393
11971
  };
11394
11972
  }
11395
11973
  function traceStreamingChannel(channel2, config) {
11396
- const tracingChannel2 = channel2.tracingChannel();
11974
+ const tracingChannel = channel2.tracingChannel();
11397
11975
  const states = /* @__PURE__ */ new WeakMap();
11398
11976
  const channelName = channel2.channelName;
11399
11977
  const unbindCurrentSpanStore = bindCurrentSpanStoreToStart(
11400
- tracingChannel2,
11978
+ tracingChannel,
11401
11979
  states,
11402
11980
  config,
11403
11981
  channelName,
@@ -11425,6 +12003,33 @@ function traceStreamingChannel(channel2, config) {
11425
12003
  const { span, startTime } = spanData;
11426
12004
  if (isAsyncIterable(asyncEndEvent.result)) {
11427
12005
  let firstChunkTime;
12006
+ const handleStreamError = (error) => {
12007
+ try {
12008
+ span.log({ error });
12009
+ } catch (loggingError) {
12010
+ debugLogger.error(
12011
+ `Error logging failure for ${channelName}:`,
12012
+ loggingError
12013
+ );
12014
+ }
12015
+ try {
12016
+ span.end();
12017
+ } catch (endingError) {
12018
+ debugLogger.error(
12019
+ `Error ending span for ${channelName}:`,
12020
+ endingError
12021
+ );
12022
+ }
12023
+ states.delete(event);
12024
+ runStreamingErrorHook({
12025
+ channelName,
12026
+ config,
12027
+ error,
12028
+ event: asyncEndEvent,
12029
+ span,
12030
+ startTime
12031
+ });
12032
+ };
11428
12033
  patchStreamIfNeeded(asyncEndEvent.result, {
11429
12034
  onChunk: () => {
11430
12035
  if (firstChunkTime === void 0) {
@@ -11504,33 +12109,12 @@ function traceStreamingChannel(channel2, config) {
11504
12109
  });
11505
12110
  }
11506
12111
  },
11507
- onError: (error) => {
11508
- try {
11509
- span.log({ error });
11510
- } catch (loggingError) {
11511
- debugLogger.error(
11512
- `Error logging failure for ${channelName}:`,
11513
- loggingError
11514
- );
11515
- }
11516
- try {
11517
- span.end();
11518
- } catch (endingError) {
11519
- debugLogger.error(
11520
- `Error ending span for ${channelName}:`,
11521
- endingError
11522
- );
11523
- }
11524
- states.delete(event);
11525
- runStreamingErrorHook({
11526
- channelName,
11527
- config,
11528
- error,
11529
- event: asyncEndEvent,
11530
- span,
11531
- startTime
11532
- });
11533
- }
12112
+ onCancel: () => {
12113
+ const error = new Error("Stream cancelled before completion");
12114
+ error.name = "AbortError";
12115
+ handleStreamError(error);
12116
+ },
12117
+ onError: handleStreamError
11534
12118
  });
11535
12119
  return;
11536
12120
  }
@@ -11608,18 +12192,18 @@ function traceStreamingChannel(channel2, config) {
11608
12192
  }
11609
12193
  }
11610
12194
  };
11611
- tracingChannel2.subscribe(handlers);
12195
+ tracingChannel.subscribe(handlers);
11612
12196
  return () => {
11613
12197
  unbindCurrentSpanStore?.();
11614
- tracingChannel2.unsubscribe(handlers);
12198
+ tracingChannel.unsubscribe(handlers);
11615
12199
  };
11616
12200
  }
11617
12201
  function traceSyncStreamChannel(channel2, config) {
11618
- const tracingChannel2 = channel2.tracingChannel();
12202
+ const tracingChannel = channel2.tracingChannel();
11619
12203
  const states = /* @__PURE__ */ new WeakMap();
11620
12204
  const channelName = channel2.channelName;
11621
12205
  const unbindCurrentSpanStore = bindCurrentSpanStoreToStart(
11622
- tracingChannel2,
12206
+ tracingChannel,
11623
12207
  states,
11624
12208
  config,
11625
12209
  channelName,
@@ -11732,10 +12316,10 @@ function traceSyncStreamChannel(channel2, config) {
11732
12316
  logErrorAndEnd(states, event, channelName);
11733
12317
  }
11734
12318
  };
11735
- tracingChannel2.subscribe(handlers);
12319
+ tracingChannel.subscribe(handlers);
11736
12320
  return () => {
11737
12321
  unbindCurrentSpanStore?.();
11738
- tracingChannel2.unsubscribe(handlers);
12322
+ tracingChannel.unsubscribe(handlers);
11739
12323
  };
11740
12324
  }
11741
12325
  function unsubscribeAll(unsubscribers) {
@@ -11915,16 +12499,26 @@ function defineChannels(pkg, channels, options) {
11915
12499
  const fullChannelName = `orchestrion:${pkg}:${spec.channelName}`;
11916
12500
  if (spec.kind === "async") {
11917
12501
  const asyncSpec = spec;
11918
- const tracingChannel3 = () => isomorph_default.newTracingChannel(
12502
+ const tracingChannel2 = () => isomorph_default.newTracingChannel(
11919
12503
  fullChannelName
11920
12504
  );
12505
+ const intercept2 = (interceptor) => {
12506
+ const hook = tracingChannel2();
12507
+ return typeof hook.intercept === "function" ? hook.intercept(interceptor) : () => {
12508
+ };
12509
+ };
11921
12510
  return [
11922
12511
  key,
11923
12512
  {
11924
12513
  ...asyncSpec,
11925
12514
  instrumentationName,
11926
- tracingChannel: tracingChannel3,
11927
- tracePromise: (fn, context) => tracingChannel3().tracePromise(
12515
+ intercept: intercept2,
12516
+ invoke: (target, thisArg, args, additional) => {
12517
+ const hook = tracingChannel2();
12518
+ return typeof hook.invoke === "function" ? hook.invoke(target, thisArg, args, additional) : Reflect.apply(target, thisArg, args);
12519
+ },
12520
+ tracingChannel: tracingChannel2,
12521
+ tracePromise: (fn, context) => tracingChannel2().tracePromise(
11928
12522
  fn,
11929
12523
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
11930
12524
  context
@@ -11933,16 +12527,26 @@ function defineChannels(pkg, channels, options) {
11933
12527
  ];
11934
12528
  }
11935
12529
  const syncSpec = spec;
11936
- const tracingChannel2 = () => isomorph_default.newTracingChannel(
12530
+ const tracingChannel = () => isomorph_default.newTracingChannel(
11937
12531
  fullChannelName
11938
12532
  );
12533
+ const intercept = (interceptor) => {
12534
+ const hook = tracingChannel();
12535
+ return typeof hook.intercept === "function" ? hook.intercept(interceptor) : () => {
12536
+ };
12537
+ };
11939
12538
  return [
11940
12539
  key,
11941
12540
  {
11942
12541
  ...syncSpec,
11943
12542
  instrumentationName,
11944
- tracingChannel: tracingChannel2,
11945
- traceSync: (fn, context) => tracingChannel2().traceSync(
12543
+ intercept,
12544
+ invoke: (target, thisArg, args, additional) => {
12545
+ const hook = tracingChannel();
12546
+ return typeof hook.invoke === "function" ? hook.invoke(target, thisArg, args, additional) : Reflect.apply(target, thisArg, args);
12547
+ },
12548
+ tracingChannel,
12549
+ traceSync: (fn, context) => tracingChannel().traceSync(
11946
12550
  fn,
11947
12551
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
11948
12552
  context
@@ -13191,6 +13795,12 @@ function extractAnthropicCacheTokens(cacheReadTokens = 0, cacheCreationTokens =
13191
13795
  return cacheTokens;
13192
13796
  }
13193
13797
 
13798
+ // src/wrappers/anthropic-session-collector.ts
13799
+ var sessionStreamCollectors = /* @__PURE__ */ new WeakMap();
13800
+ function registerAnthropicSessionStreamCollector(stream, collector) {
13801
+ sessionStreamCollectors.set(stream, collector);
13802
+ }
13803
+
13194
13804
  // src/instrumentation/plugins/anthropic-channels.ts
13195
13805
  var anthropicChannels = defineChannels(
13196
13806
  "@anthropic-ai/sdk",
@@ -13206,6 +13816,14 @@ var anthropicChannels = defineChannels(
13206
13816
  betaMessagesToolRunner: channel({
13207
13817
  channelName: "beta.messages.toolRunner",
13208
13818
  kind: "sync-stream"
13819
+ }),
13820
+ betaSessionsEventsStream: channel({
13821
+ channelName: "beta.sessions.events.stream",
13822
+ kind: "async"
13823
+ }),
13824
+ betaSessionsThreadsEventsStream: channel({
13825
+ channelName: "beta.sessions.threads.events.stream",
13826
+ kind: "async"
13209
13827
  })
13210
13828
  },
13211
13829
  { instrumentationName: INSTRUMENTATION_NAMES.ANTHROPIC }
@@ -13219,6 +13837,7 @@ var AnthropicPlugin = class extends BasePlugin {
13219
13837
  onEnable() {
13220
13838
  this.subscribeToAnthropicChannels();
13221
13839
  this.subscribeToAnthropicToolRunner();
13840
+ this.subscribeToAnthropicSessionStreams();
13222
13841
  }
13223
13842
  onDisable() {
13224
13843
  this.unsubscribers = unsubscribeAll(this.unsubscribers);
@@ -13274,7 +13893,7 @@ var AnthropicPlugin = class extends BasePlugin {
13274
13893
  );
13275
13894
  }
13276
13895
  subscribeToAnthropicToolRunner() {
13277
- const tracingChannel2 = anthropicChannels.betaMessagesToolRunner.tracingChannel();
13896
+ const tracingChannel = anthropicChannels.betaMessagesToolRunner.tracingChannel();
13278
13897
  const states = /* @__PURE__ */ new WeakMap();
13279
13898
  const handlers = {
13280
13899
  start: (event) => {
@@ -13331,12 +13950,416 @@ var AnthropicPlugin = class extends BasePlugin {
13331
13950
  states.delete(event);
13332
13951
  }
13333
13952
  };
13334
- tracingChannel2.subscribe(handlers);
13953
+ tracingChannel.subscribe(handlers);
13335
13954
  this.unsubscribers.push(() => {
13336
- tracingChannel2.unsubscribe(handlers);
13955
+ tracingChannel.unsubscribe(handlers);
13337
13956
  });
13338
13957
  }
13958
+ subscribeToAnthropicSessionStreams() {
13959
+ this.subscribeToAnthropicSessionStream(
13960
+ anthropicChannels.betaSessionsEventsStream,
13961
+ false
13962
+ );
13963
+ this.subscribeToAnthropicSessionStream(
13964
+ anthropicChannels.betaSessionsThreadsEventsStream,
13965
+ true
13966
+ );
13967
+ }
13968
+ subscribeToAnthropicSessionStream(channel2, isThread) {
13969
+ const tracingChannel = channel2.tracingChannel();
13970
+ const pending = /* @__PURE__ */ new WeakSet();
13971
+ const handlers = {
13972
+ start: (event) => {
13973
+ if (isAutoInstrumentationSuppressed()) {
13974
+ return;
13975
+ }
13976
+ pending.add(event);
13977
+ },
13978
+ asyncEnd: (event) => {
13979
+ if (!pending.delete(event)) {
13980
+ return;
13981
+ }
13982
+ const stream = event.result;
13983
+ if (!isAsyncIterable(stream)) {
13984
+ return;
13985
+ }
13986
+ registerAnthropicSessionStreamCollector(stream, () => {
13987
+ wrapAnthropicSessionEventStream(stream, isThread);
13988
+ });
13989
+ },
13990
+ error: (event) => {
13991
+ pending.delete(event);
13992
+ }
13993
+ };
13994
+ tracingChannel.subscribe(handlers);
13995
+ this.unsubscribers.push(() => tracingChannel.unsubscribe(handlers));
13996
+ }
13339
13997
  };
13998
+ function wrapAnthropicSessionEventStream(stream, isThread) {
13999
+ const state = {
14000
+ history: [],
14001
+ isThread,
14002
+ pendingInput: [],
14003
+ seenEventIds: /* @__PURE__ */ new Set()
14004
+ };
14005
+ patchStreamIfNeeded(stream, {
14006
+ onChunk: (event) => handleAnthropicSessionEvent(state, event),
14007
+ onComplete: () => finalizeAnthropicSessionTurn(state),
14008
+ onError: (error) => finalizeAnthropicSessionTurn(state, error)
14009
+ });
14010
+ return stream;
14011
+ }
14012
+ function handleAnthropicSessionEvent(state, event) {
14013
+ try {
14014
+ if (typeof event.id === "string" && event.type !== "event_delta" && state.seenEventIds.has(event.id)) {
14015
+ return;
14016
+ }
14017
+ if (typeof event.id === "string" && event.type !== "event_delta") {
14018
+ state.seenEventIds.add(event.id);
14019
+ }
14020
+ switch (event.type) {
14021
+ case "user.message":
14022
+ case "system.message":
14023
+ recordAnthropicSessionInput(
14024
+ state,
14025
+ event
14026
+ );
14027
+ break;
14028
+ case "session.status_running":
14029
+ if (!state.isThread) {
14030
+ ensureAnthropicSessionTurn(state);
14031
+ }
14032
+ break;
14033
+ case "session.thread_status_running":
14034
+ if (state.isThread) {
14035
+ ensureAnthropicSessionTurn(state);
14036
+ }
14037
+ break;
14038
+ case "span.model_request_start":
14039
+ if (typeof event.id === "string") {
14040
+ startAnthropicSessionModel(state, event.id);
14041
+ }
14042
+ break;
14043
+ case "event_delta":
14044
+ recordAnthropicSessionFirstToken(state, event);
14045
+ break;
14046
+ case "agent.message":
14047
+ recordAnthropicSessionMessage(
14048
+ state,
14049
+ event
14050
+ );
14051
+ break;
14052
+ case "agent.custom_tool_use":
14053
+ case "agent.mcp_tool_use":
14054
+ case "agent.tool_use":
14055
+ startAnthropicSessionTool(state, event);
14056
+ break;
14057
+ case "user.tool_confirmation":
14058
+ recordAnthropicSessionToolConfirmation(state, event);
14059
+ break;
14060
+ case "agent.mcp_tool_result":
14061
+ case "agent.tool_result":
14062
+ case "user.custom_tool_result":
14063
+ case "user.tool_result":
14064
+ finalizeAnthropicSessionTool(
14065
+ state,
14066
+ event
14067
+ );
14068
+ break;
14069
+ case "span.model_request_end":
14070
+ finalizeAnthropicSessionModel(
14071
+ state,
14072
+ event
14073
+ );
14074
+ break;
14075
+ case "session.status_idle":
14076
+ case "session.thread_status_idle": {
14077
+ if (event.type === "session.status_idle" && state.isThread || event.type === "session.thread_status_idle" && !state.isThread) {
14078
+ break;
14079
+ }
14080
+ const stopReason = isObject(event.stop_reason) ? event.stop_reason.type : void 0;
14081
+ if (stopReason === "end_turn") {
14082
+ finalizeAnthropicSessionTurn(state);
14083
+ } else if (stopReason === "retries_exhausted") {
14084
+ finalizeAnthropicSessionTurn(
14085
+ state,
14086
+ "Anthropic session retries exhausted"
14087
+ );
14088
+ }
14089
+ break;
14090
+ }
14091
+ case "session.error":
14092
+ finalizeAnthropicSessionTurn(state, event.error);
14093
+ break;
14094
+ case "session.deleted":
14095
+ case "session.status_terminated":
14096
+ case "session.thread_status_terminated":
14097
+ if (event.type === "session.deleted" || event.type === "session.status_terminated" && !state.isThread || event.type === "session.thread_status_terminated" && state.isThread) {
14098
+ finalizeAnthropicSessionTurn(state);
14099
+ }
14100
+ break;
14101
+ default:
14102
+ break;
14103
+ }
14104
+ } catch (error) {
14105
+ debugLogger.debug("Error processing Anthropic Sessions event:", error);
14106
+ }
14107
+ }
14108
+ function ensureAnthropicSessionTurn(state) {
14109
+ if (state.activeTurn) {
14110
+ return state.activeTurn;
14111
+ }
14112
+ const input = state.pendingInput;
14113
+ state.pendingInput = [];
14114
+ const span = startSpan(
14115
+ withSpanInstrumentationName(
14116
+ {
14117
+ event: {
14118
+ ...input.length > 0 ? { input } : {},
14119
+ metadata: { provider: "anthropic" }
14120
+ },
14121
+ name: state.isThread ? "anthropic.beta.sessions.thread.turn" : "anthropic.beta.sessions.turn",
14122
+ spanAttributes: { type: "task" /* TASK */ }
14123
+ },
14124
+ INSTRUMENTATION_NAMES.ANTHROPIC
14125
+ )
14126
+ );
14127
+ state.activeTurn = {
14128
+ activeTools: /* @__PURE__ */ new Map(),
14129
+ input: input.slice(),
14130
+ metrics: {},
14131
+ span
14132
+ };
14133
+ return state.activeTurn;
14134
+ }
14135
+ function recordAnthropicSessionInput(state, event) {
14136
+ const content = processAttachmentsInInput(event.content);
14137
+ const message = {
14138
+ role: event.type === "system.message" ? "system" : "user",
14139
+ content
14140
+ };
14141
+ state.history.push(message);
14142
+ if (state.activeTurn) {
14143
+ state.activeTurn.input.push(message);
14144
+ } else {
14145
+ state.pendingInput.push(message);
14146
+ }
14147
+ }
14148
+ function startAnthropicSessionModel(state, startEventId) {
14149
+ const turn = ensureAnthropicSessionTurn(state);
14150
+ if (turn.activeModel) {
14151
+ finalizeAnthropicSessionModelState(state, turn);
14152
+ }
14153
+ const span = withCurrent(
14154
+ turn.span,
14155
+ () => startSpan(
14156
+ withSpanInstrumentationName(
14157
+ {
14158
+ event: {
14159
+ ...state.history.length > 0 ? { input: state.history.slice() } : {},
14160
+ metadata: { provider: "anthropic" }
14161
+ },
14162
+ name: "anthropic.messages.create",
14163
+ spanAttributes: { type: "llm" /* LLM */ }
14164
+ },
14165
+ INSTRUMENTATION_NAMES.ANTHROPIC
14166
+ )
14167
+ )
14168
+ );
14169
+ turn.activeModel = {
14170
+ output: [],
14171
+ span,
14172
+ startEventId,
14173
+ startTime: getCurrentUnixTimestamp()
14174
+ };
14175
+ }
14176
+ function recordAnthropicSessionFirstToken(state, event) {
14177
+ const model = state.activeTurn?.activeModel;
14178
+ if (!model || model.firstTokenTime !== void 0 || !isObject(event.delta) || !isObject(event.delta.content) || typeof event.delta.content.text !== "string") {
14179
+ return;
14180
+ }
14181
+ model.firstTokenTime = getCurrentUnixTimestamp();
14182
+ }
14183
+ function recordAnthropicSessionMessage(state, event) {
14184
+ const turn = ensureAnthropicSessionTurn(state);
14185
+ const content = processAttachmentsInInput(
14186
+ event.content
14187
+ );
14188
+ if (turn.activeModel) {
14189
+ turn.activeModel.output.push(...content);
14190
+ } else {
14191
+ const output = { role: "assistant", content };
14192
+ turn.lastOutput = output;
14193
+ state.history.push(output);
14194
+ }
14195
+ }
14196
+ function startAnthropicSessionTool(state, event) {
14197
+ const turn = ensureAnthropicSessionTurn(state);
14198
+ if (turn.activeModel) {
14199
+ turn.activeModel.output.push({
14200
+ type: "tool_use",
14201
+ id: event.id,
14202
+ name: event.name,
14203
+ input: event.input
14204
+ });
14205
+ }
14206
+ const existing = turn.activeTools.get(event.id);
14207
+ if (existing) {
14208
+ existing.span.end();
14209
+ turn.activeTools.delete(event.id);
14210
+ }
14211
+ const span = withCurrent(
14212
+ turn.span,
14213
+ () => startSpan(
14214
+ withSpanInstrumentationName(
14215
+ {
14216
+ event: { input: event.input },
14217
+ name: event.name,
14218
+ spanAttributes: { type: "tool" /* TOOL */ }
14219
+ },
14220
+ INSTRUMENTATION_NAMES.ANTHROPIC
14221
+ )
14222
+ )
14223
+ );
14224
+ const toolState = {
14225
+ approval: event.evaluated_permission === "allow" ? "approved" : event.evaluated_permission === "deny" ? "denied" : void 0,
14226
+ span
14227
+ };
14228
+ turn.activeTools.set(event.id, toolState);
14229
+ if (toolState.approval === "denied") {
14230
+ finalizeAnthropicSessionToolState(toolState);
14231
+ turn.activeTools.delete(event.id);
14232
+ }
14233
+ }
14234
+ function recordAnthropicSessionToolConfirmation(state, event) {
14235
+ if (typeof event.tool_use_id !== "string" || event.result !== "allow" && event.result !== "deny") {
14236
+ return;
14237
+ }
14238
+ const turn = state.activeTurn;
14239
+ const tool = turn?.activeTools.get(event.tool_use_id);
14240
+ if (!turn || !tool) {
14241
+ return;
14242
+ }
14243
+ tool.approval = event.result === "allow" ? "approved" : "denied";
14244
+ if (tool.approval === "denied") {
14245
+ finalizeAnthropicSessionToolState(tool);
14246
+ turn.activeTools.delete(event.tool_use_id);
14247
+ }
14248
+ }
14249
+ function finalizeAnthropicSessionTool(state, event) {
14250
+ const toolUseId = event.tool_use_id ?? event.mcp_tool_use_id ?? event.custom_tool_use_id;
14251
+ if (!toolUseId) {
14252
+ return;
14253
+ }
14254
+ const content = processAttachmentsInInput(event.content);
14255
+ const turn = state.activeTurn;
14256
+ const tool = turn?.activeTools.get(toolUseId);
14257
+ if (turn && tool) {
14258
+ finalizeAnthropicSessionToolState(tool, event, content);
14259
+ turn.activeTools.delete(toolUseId);
14260
+ }
14261
+ const toolResult = {
14262
+ type: "tool_result",
14263
+ tool_use_id: toolUseId,
14264
+ ...content !== void 0 ? { content } : {},
14265
+ ...event.is_error === true ? { is_error: true } : {}
14266
+ };
14267
+ state.history.push({
14268
+ role: "user",
14269
+ content: [toolResult]
14270
+ });
14271
+ }
14272
+ function finalizeAnthropicSessionToolState(state, event, content = event?.content) {
14273
+ safeAnthropicSessionLog(state.span, {
14274
+ ...event?.is_error === true ? {
14275
+ error: content ?? "Anthropic session tool execution failed"
14276
+ } : {},
14277
+ ...state.approval ? { metadata: { tool_approval: state.approval } } : {},
14278
+ ...content !== void 0 ? { output: content } : {}
14279
+ });
14280
+ state.span.end();
14281
+ }
14282
+ function finalizeAnthropicSessionModel(state, event) {
14283
+ const turn = state.activeTurn;
14284
+ const model = turn?.activeModel;
14285
+ if (!turn || !model || model.startEventId !== event.model_request_start_id) {
14286
+ return;
14287
+ }
14288
+ finalizeAnthropicSessionModelState(state, turn, event);
14289
+ }
14290
+ function finalizeAnthropicSessionModelState(state, turn, event) {
14291
+ const model = turn.activeModel;
14292
+ if (!model) {
14293
+ return;
14294
+ }
14295
+ turn.activeModel = void 0;
14296
+ const metrics = event ? parseAnthropicSessionModelUsage(event.model_usage) : {};
14297
+ if (model.firstTokenTime !== void 0) {
14298
+ metrics.time_to_first_token = model.firstTokenTime - model.startTime;
14299
+ }
14300
+ const output = model.output.length > 0 ? { role: "assistant", content: model.output } : void 0;
14301
+ safeAnthropicSessionLog(model.span, {
14302
+ ...event?.is_error ? { error: "Anthropic session model request failed" } : {},
14303
+ ...Object.keys(metrics).length > 0 ? { metrics } : {},
14304
+ ...output ? { output } : {}
14305
+ });
14306
+ model.span.end();
14307
+ if (output) {
14308
+ turn.lastOutput = output;
14309
+ state.history.push(output);
14310
+ }
14311
+ for (const key of [
14312
+ "prompt_tokens",
14313
+ "completion_tokens",
14314
+ "tokens",
14315
+ "prompt_cached_tokens",
14316
+ "prompt_cache_creation_tokens"
14317
+ ]) {
14318
+ const value = metrics[key];
14319
+ if (typeof value === "number") {
14320
+ turn.metrics[key] = (turn.metrics[key] ?? 0) + value;
14321
+ }
14322
+ }
14323
+ }
14324
+ function parseAnthropicSessionModelUsage(usage) {
14325
+ const finalized = finalizeAnthropicTokens({
14326
+ completion_tokens: usage.output_tokens,
14327
+ prompt_cache_creation_tokens: usage.cache_creation_input_tokens,
14328
+ prompt_cached_tokens: usage.cache_read_input_tokens,
14329
+ prompt_tokens: usage.input_tokens
14330
+ });
14331
+ return Object.fromEntries(
14332
+ Object.entries(finalized).filter(
14333
+ (entry) => entry[1] !== void 0
14334
+ )
14335
+ );
14336
+ }
14337
+ function finalizeAnthropicSessionTurn(state, error) {
14338
+ const turn = state.activeTurn;
14339
+ if (!turn) {
14340
+ return;
14341
+ }
14342
+ state.activeTurn = void 0;
14343
+ finalizeAnthropicSessionModelState(state, turn);
14344
+ for (const tool of turn.activeTools.values()) {
14345
+ finalizeAnthropicSessionToolState(tool);
14346
+ }
14347
+ turn.activeTools.clear();
14348
+ safeAnthropicSessionLog(turn.span, {
14349
+ ...error !== void 0 ? { error: error instanceof Error ? error : toLoggedError(error) } : {},
14350
+ ...turn.input.length > 0 ? { input: turn.input } : {},
14351
+ ...turn.lastOutput ? { output: turn.lastOutput } : {},
14352
+ ...Object.keys(turn.metrics).length > 0 ? { metrics: turn.metrics } : {}
14353
+ });
14354
+ turn.span.end();
14355
+ }
14356
+ function safeAnthropicSessionLog(span, event) {
14357
+ try {
14358
+ span.log(event);
14359
+ } catch (error) {
14360
+ debugLogger.debug("Error logging Anthropic Sessions span:", error);
14361
+ }
14362
+ }
13340
14363
  function parseMetricsFromUsage2(usage) {
13341
14364
  if (!usage) {
13342
14365
  return {};
@@ -14245,8 +15268,8 @@ function registerHarnessSessionParent(session, parent) {
14245
15268
  function currentHarnessTurnParent() {
14246
15269
  return harnessTurnParentStore?.getStore() ?? wrapperTurnParents.get(currentSpan());
14247
15270
  }
14248
- function bindHarnessTurnParentToStart(tracingChannel2, parentFromEvent) {
14249
- const startChannel = tracingChannel2.start;
15271
+ function bindHarnessTurnParentToStart(tracingChannel, parentFromEvent) {
15272
+ const startChannel = tracingChannel.start;
14250
15273
  if (!startChannel) {
14251
15274
  return () => {
14252
15275
  };
@@ -15210,6 +16233,29 @@ var harnessAgentChannels = defineChannels(
15210
16233
  { instrumentationName: INSTRUMENTATION_NAMES.AI_SDK }
15211
16234
  );
15212
16235
 
16236
+ // src/instrumentation/plugins/cloudflare-think-context.ts
16237
+ var cloudflareThinkSpans = /* @__PURE__ */ new Map();
16238
+ function registerCloudflareThinkSpan(span) {
16239
+ if (span.spanId) {
16240
+ cloudflareThinkSpans.set(span.spanId, span);
16241
+ }
16242
+ }
16243
+ function unregisterCloudflareThinkSpan(span) {
16244
+ if (span.spanId) {
16245
+ cloudflareThinkSpans.delete(span.spanId);
16246
+ }
16247
+ }
16248
+ function currentCloudflareThinkSpan() {
16249
+ const parentSpanIds = _internalGetGlobalState()?.contextManager.getParentSpanIds()?.spanParents ?? [];
16250
+ for (const parentSpanId of parentSpanIds) {
16251
+ const span = cloudflareThinkSpans.get(parentSpanId);
16252
+ if (span) {
16253
+ return span;
16254
+ }
16255
+ }
16256
+ return void 0;
16257
+ }
16258
+
15213
16259
  // src/instrumentation/plugins/ai-sdk-plugin.ts
15214
16260
  var DEFAULT_DENY_OUTPUT_PATHS = [
15215
16261
  // v3
@@ -15316,6 +16362,7 @@ var AISDKPlugin = class extends BasePlugin {
15316
16362
  traceStreamingChannel(aiSDKChannels.streamText, {
15317
16363
  name: "streamText",
15318
16364
  type: "function" /* FUNCTION */,
16365
+ shouldTrace: () => currentCloudflareThinkSpan() === void 0,
15319
16366
  extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
15320
16367
  extractOutput: (result, endEvent) => processAISDKOutput(
15321
16368
  result,
@@ -15336,6 +16383,7 @@ var AISDKPlugin = class extends BasePlugin {
15336
16383
  traceSyncStreamChannel(aiSDKChannels.streamTextSync, {
15337
16384
  name: "streamText",
15338
16385
  type: "function" /* FUNCTION */,
16386
+ shouldTrace: () => currentCloudflareThinkSpan() === void 0,
15339
16387
  extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
15340
16388
  patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
15341
16389
  defaultDenyOutputPaths: denyOutputPaths,
@@ -16321,6 +17369,23 @@ function prepareAISDKWorkflowAgentStreamInput(params, event, span, defaultDenyOu
16321
17369
  metadata
16322
17370
  };
16323
17371
  }
17372
+ function prepareAISDKAgentCallInput(params, event, span, defaultDenyOutputPaths = DEFAULT_DENY_OUTPUT_PATHS) {
17373
+ const { input } = processAISDKWorkflowAgentCallInput(params);
17374
+ const metadata = extractMetadataFromCallParams(params, event.self);
17375
+ const childTracing = prepareAISDKChildTracing(
17376
+ params,
17377
+ event.self,
17378
+ span,
17379
+ defaultDenyOutputPaths,
17380
+ event.aiSDK,
17381
+ { agentOwner: true }
17382
+ );
17383
+ event.modelWrapped = childTracing.modelWrapped;
17384
+ if (childTracing.cleanup) {
17385
+ event.__braintrust_ai_sdk_cleanup = childTracing.cleanup;
17386
+ }
17387
+ return { input, metadata };
17388
+ }
16324
17389
  function prepareAISDKEmbedInput(params, self) {
16325
17390
  return {
16326
17391
  input: { ...params },
@@ -16344,6 +17409,18 @@ function extractTopLevelAISDKMetrics(result, event, startTime) {
16344
17409
  }
16345
17410
  return metrics;
16346
17411
  }
17412
+ async function extractResolvedAISDKTokenMetrics(result) {
17413
+ for (const field of ["totalUsage", "usage"]) {
17414
+ try {
17415
+ const usage = await Promise.resolve(result[field]);
17416
+ if (usage !== void 0) {
17417
+ return extractTokenMetrics({ [field]: usage });
17418
+ }
17419
+ } catch {
17420
+ }
17421
+ }
17422
+ return extractTokenMetrics(result);
17423
+ }
16347
17424
  function hasModelChildTracing(event) {
16348
17425
  return event?.modelWrapped === true || event?.__braintrust_ai_sdk_model_wrapped === true;
16349
17426
  }
@@ -17161,13 +18238,15 @@ function patchAISDKStreamingResult(args) {
17161
18238
  const {
17162
18239
  defaultDenyOutputPaths,
17163
18240
  endEvent,
18241
+ forceTopLevelMetrics,
17164
18242
  onComplete,
17165
18243
  onCancel,
17166
18244
  onError,
17167
18245
  result,
17168
18246
  resolvePromiseUsage,
17169
18247
  span,
17170
- startTime
18248
+ startTime,
18249
+ transformOutput
17171
18250
  } = args;
17172
18251
  if (!result || typeof result !== "object") {
17173
18252
  return false;
@@ -17220,8 +18299,8 @@ function patchAISDKStreamingResult(args) {
17220
18299
  }
17221
18300
  outputLogged = true;
17222
18301
  try {
17223
- const metrics = extractTopLevelAISDKMetrics(result, endEvent);
17224
- if (resolvePromiseUsage) {
18302
+ const metrics = forceTopLevelMetrics ? await extractResolvedAISDKTokenMetrics(result) : extractTopLevelAISDKMetrics(result, endEvent);
18303
+ if (resolvePromiseUsage && !forceTopLevelMetrics) {
17225
18304
  try {
17226
18305
  const resultRecord2 = result;
17227
18306
  const pendingUsage = resultRecord2.totalUsage ?? resultRecord2.usage;
@@ -17240,10 +18319,11 @@ function patchAISDKStreamingResult(args) {
17240
18319
  if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
17241
18320
  metrics.time_to_first_token = firstChunkTime - startTime;
17242
18321
  }
17243
- const output = await processAISDKStreamingOutput(
18322
+ const processedOutput = await processAISDKStreamingOutput(
17244
18323
  result,
17245
18324
  resolveDenyOutputPaths(endEvent, defaultDenyOutputPaths)
17246
18325
  );
18326
+ const output = transformOutput ? transformOutput(processedOutput) : processedOutput;
17247
18327
  const metadata = buildResolvedMetadataPayload(result).metadata;
17248
18328
  try {
17249
18329
  span.log({
@@ -19665,6 +20745,295 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
19665
20745
  }
19666
20746
  };
19667
20747
 
20748
+ // src/instrumentation/plugins/cloudflare-think-channels.ts
20749
+ var cloudflareThinkChannels = defineChannels(
20750
+ "@cloudflare/think",
20751
+ {
20752
+ runInferenceLoop: channel({
20753
+ channelName: "Think.runInferenceLoop",
20754
+ kind: "async"
20755
+ })
20756
+ },
20757
+ { instrumentationName: INSTRUMENTATION_NAMES.CLOUDFLARE_THINK }
20758
+ );
20759
+
20760
+ // src/instrumentation/plugins/cloudflare-think-plugin.ts
20761
+ var THINK_STATE_ID = /* @__PURE__ */ Symbol.for("braintrust.cloudflare-think.state-id");
20762
+ var CloudflareThinkPlugin = class extends BasePlugin {
20763
+ statesBySpanId = /* @__PURE__ */ new Map();
20764
+ onEnable() {
20765
+ this.subscribeToThinkRuns();
20766
+ this.subscribeToAISDKStreamTextSync();
20767
+ this.subscribeToAISDKStreamTextAsync();
20768
+ }
20769
+ onDisable() {
20770
+ for (const unsubscribe of this.unsubscribers) {
20771
+ unsubscribe();
20772
+ }
20773
+ this.unsubscribers = [];
20774
+ for (const state of this.statesBySpanId.values()) {
20775
+ this.finishState(state);
20776
+ }
20777
+ this.statesBySpanId.clear();
20778
+ }
20779
+ subscribeToThinkRuns() {
20780
+ const channel2 = cloudflareThinkChannels.runInferenceLoop.tracingChannel();
20781
+ const states = /* @__PURE__ */ new WeakMap();
20782
+ const state = _internalGetGlobalState();
20783
+ const contextManager = state?.contextManager;
20784
+ const currentSpanStore = contextManager ? contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
20785
+ const ensureState2 = (event) => {
20786
+ if (isAutoInstrumentationSuppressed()) {
20787
+ return void 0;
20788
+ }
20789
+ const existing = states.get(event);
20790
+ if (existing) {
20791
+ return existing;
20792
+ }
20793
+ const span = startSpan(
20794
+ withSpanInstrumentationName(
20795
+ {
20796
+ name: "Think.runTurn",
20797
+ spanAttributes: { type: "task" /* TASK */ }
20798
+ },
20799
+ INSTRUMENTATION_NAMES.CLOUDFLARE_THINK
20800
+ )
20801
+ );
20802
+ const runState = {
20803
+ aiResultPatched: false,
20804
+ fallbackInput: extractFallbackInput(event.self?.messages),
20805
+ finalized: false,
20806
+ inputLogged: false,
20807
+ span,
20808
+ startTime: getCurrentUnixTimestamp()
20809
+ };
20810
+ const metadata = {
20811
+ braintrust: {
20812
+ integration_name: "cloudflare-think",
20813
+ sdk_language: "typescript"
20814
+ }
20815
+ };
20816
+ if (typeof event.moduleVersion === "string") {
20817
+ metadata["cloudflare_think.version"] = event.moduleVersion;
20818
+ }
20819
+ span.log({ metadata });
20820
+ states.set(event, runState);
20821
+ if (span.spanId) {
20822
+ this.statesBySpanId.set(span.spanId, runState);
20823
+ }
20824
+ registerCloudflareThinkSpan(span);
20825
+ return runState;
20826
+ };
20827
+ if (contextManager && currentSpanStore && channel2.start) {
20828
+ channel2.start.bindStore(currentSpanStore, (event) => {
20829
+ const runState = ensureState2(event);
20830
+ return runState ? contextManager.wrapSpanForStore(runState.span) : currentSpanStore.getStore();
20831
+ });
20832
+ this.unsubscribers.push(
20833
+ () => channel2.start?.unbindStore(currentSpanStore)
20834
+ );
20835
+ }
20836
+ const handlers = {
20837
+ start: (event) => {
20838
+ ensureState2(event);
20839
+ },
20840
+ asyncEnd: (event) => {
20841
+ const runState = states.get(event);
20842
+ states.delete(event);
20843
+ if (!runState || runState.finalized || runState.aiResultPatched) {
20844
+ return;
20845
+ }
20846
+ this.finishState(runState, void 0, event.result);
20847
+ },
20848
+ error: (event) => {
20849
+ const runState = states.get(event);
20850
+ states.delete(event);
20851
+ if (runState) {
20852
+ this.finishState(runState, event.error);
20853
+ }
20854
+ }
20855
+ };
20856
+ channel2.subscribe(handlers);
20857
+ this.unsubscribers.push(() => channel2.unsubscribe(handlers));
20858
+ }
20859
+ subscribeToAISDKStreamTextSync() {
20860
+ const channel2 = aiSDKChannels.streamTextSync.tracingChannel();
20861
+ const handlers = {
20862
+ start: (event) => {
20863
+ this.startAISDKStream(event);
20864
+ },
20865
+ end: (event) => {
20866
+ this.endAISDKStream(event);
20867
+ },
20868
+ error: (event) => {
20869
+ this.errorAISDKStream(event);
20870
+ }
20871
+ };
20872
+ channel2.subscribe(handlers);
20873
+ this.unsubscribers.push(() => channel2.unsubscribe(handlers));
20874
+ }
20875
+ subscribeToAISDKStreamTextAsync() {
20876
+ const channel2 = aiSDKChannels.streamText.tracingChannel();
20877
+ const handlers = {
20878
+ start: (event) => {
20879
+ this.startAISDKStream(event);
20880
+ },
20881
+ asyncEnd: (event) => {
20882
+ this.endAISDKStream(event);
20883
+ },
20884
+ error: (event) => {
20885
+ this.errorAISDKStream(event);
20886
+ }
20887
+ };
20888
+ channel2.subscribe(handlers);
20889
+ this.unsubscribers.push(() => channel2.unsubscribe(handlers));
20890
+ }
20891
+ startAISDKStream(event) {
20892
+ const runState = this.currentState();
20893
+ if (!runState || runState.finalized) {
20894
+ return;
20895
+ }
20896
+ try {
20897
+ const prepared = prepareAISDKAgentCallInput(
20898
+ event.arguments[0],
20899
+ event,
20900
+ runState.span
20901
+ );
20902
+ runState.span.log({
20903
+ input: extractThinkTaskInput(prepared.input),
20904
+ metadata: {
20905
+ ...prepared.metadata,
20906
+ braintrust: {
20907
+ integration_name: "cloudflare-think",
20908
+ sdk_language: "typescript"
20909
+ }
20910
+ }
20911
+ });
20912
+ runState.inputLogged = true;
20913
+ runState.aiEvent = event;
20914
+ Reflect.set(event, THINK_STATE_ID, runState.span.spanId);
20915
+ } catch (error) {
20916
+ debugLogger.error(
20917
+ "Error preparing @cloudflare/think AI SDK tracing:",
20918
+ error
20919
+ );
20920
+ }
20921
+ }
20922
+ endAISDKStream(event) {
20923
+ const runState = this.stateForAISDKEvent(event);
20924
+ if (!runState || runState.finalized) {
20925
+ return;
20926
+ }
20927
+ const patched = patchAISDKStreamingResult({
20928
+ defaultDenyOutputPaths: DEFAULT_DENY_OUTPUT_PATHS,
20929
+ endEvent: event,
20930
+ forceTopLevelMetrics: true,
20931
+ onComplete: () => this.releaseState(runState),
20932
+ result: event.result,
20933
+ span: runState.span,
20934
+ startTime: runState.startTime,
20935
+ transformOutput: extractThinkTaskOutput
20936
+ });
20937
+ runState.aiResultPatched = patched;
20938
+ if (!patched) {
20939
+ this.finishState(runState, void 0, event.result);
20940
+ }
20941
+ }
20942
+ errorAISDKStream(event) {
20943
+ const runState = this.stateForAISDKEvent(event);
20944
+ if (runState) {
20945
+ this.finishState(runState, event.error);
20946
+ }
20947
+ }
20948
+ currentState() {
20949
+ const parentIds = _internalGetGlobalState()?.contextManager.getParentSpanIds()?.spanParents ?? [];
20950
+ for (const parentId of parentIds) {
20951
+ const state = this.statesBySpanId.get(parentId);
20952
+ if (state) {
20953
+ return state;
20954
+ }
20955
+ }
20956
+ return void 0;
20957
+ }
20958
+ stateForAISDKEvent(event) {
20959
+ const spanId = Reflect.get(event, THINK_STATE_ID);
20960
+ return typeof spanId === "string" ? this.statesBySpanId.get(spanId) : void 0;
20961
+ }
20962
+ finishState(state, error, output) {
20963
+ if (state.finalized) {
20964
+ return;
20965
+ }
20966
+ state.finalized = true;
20967
+ try {
20968
+ if (!state.inputLogged && state.fallbackInput !== void 0) {
20969
+ state.span.log({ input: state.fallbackInput });
20970
+ }
20971
+ if (error !== void 0) {
20972
+ state.span.log({ error });
20973
+ } else if (output !== void 0) {
20974
+ state.span.log({ output: extractThinkTaskOutput(output) });
20975
+ }
20976
+ finalizeAISDKChildTracing(state.aiEvent);
20977
+ state.span.end();
20978
+ } finally {
20979
+ this.releaseState(state);
20980
+ }
20981
+ }
20982
+ releaseState(state) {
20983
+ state.finalized = true;
20984
+ unregisterCloudflareThinkSpan(state.span);
20985
+ if (state.span.spanId) {
20986
+ this.statesBySpanId.delete(state.span.spanId);
20987
+ }
20988
+ }
20989
+ };
20990
+ function extractFallbackInput(messages) {
20991
+ if (!Array.isArray(messages) || messages.length === 0) {
20992
+ return void 0;
20993
+ }
20994
+ let latestUserIndex = -1;
20995
+ for (let index = messages.length - 1; index >= 0; index--) {
20996
+ if (messages[index]?.role === "user") {
20997
+ latestUserIndex = index;
20998
+ break;
20999
+ }
21000
+ }
21001
+ const selected = latestUserIndex >= 0 ? messages.slice(latestUserIndex) : [];
21002
+ return selected.map((message) => ({
21003
+ role: message.role,
21004
+ content: message.content ?? message.parts
21005
+ }));
21006
+ }
21007
+ function extractThinkTaskOutput(output) {
21008
+ if (!isObject(output)) {
21009
+ return output;
21010
+ }
21011
+ if (typeof output.text === "string") {
21012
+ return { role: "assistant", content: output.text };
21013
+ }
21014
+ if (output.object !== void 0) {
21015
+ return output.object;
21016
+ }
21017
+ return output;
21018
+ }
21019
+ function extractThinkTaskInput(input) {
21020
+ if (!isObject(input)) {
21021
+ return input;
21022
+ }
21023
+ const system = input.instructions ?? input.system;
21024
+ if (Array.isArray(input.messages)) {
21025
+ return system === void 0 ? input.messages : [{ role: "system", content: system }, ...input.messages];
21026
+ }
21027
+ if (Array.isArray(input.prompt)) {
21028
+ return system === void 0 ? input.prompt : [{ role: "system", content: system }, ...input.prompt];
21029
+ }
21030
+ if (typeof input.prompt === "string") {
21031
+ const messages = [{ role: "user", content: input.prompt }];
21032
+ return system === void 0 ? messages : [{ role: "system", content: system }, ...messages];
21033
+ }
21034
+ return input;
21035
+ }
21036
+
19668
21037
  // src/instrumentation/plugins/cursor-sdk-channels.ts
19669
21038
  var cursorSDKChannels = defineChannels(
19670
21039
  "@cursor/sdk",
@@ -19712,7 +21081,7 @@ var CursorSDKPlugin = class extends BasePlugin {
19712
21081
  this.subscribeToAgentFactory(cursorSDKChannels.resume);
19713
21082
  }
19714
21083
  subscribeToAgentFactory(channel2) {
19715
- const tracingChannel2 = channel2.tracingChannel();
21084
+ const tracingChannel = channel2.tracingChannel();
19716
21085
  const handlers = {
19717
21086
  asyncEnd: (event) => {
19718
21087
  patchCursorAgentInPlace(event.result);
@@ -19720,9 +21089,9 @@ var CursorSDKPlugin = class extends BasePlugin {
19720
21089
  error: () => {
19721
21090
  }
19722
21091
  };
19723
- tracingChannel2.subscribe(handlers);
21092
+ tracingChannel.subscribe(handlers);
19724
21093
  this.unsubscribers.push(() => {
19725
- tracingChannel2.unsubscribe(handlers);
21094
+ tracingChannel.unsubscribe(handlers);
19726
21095
  });
19727
21096
  }
19728
21097
  subscribeToPrompt() {
@@ -21078,10 +22447,10 @@ var GoogleGenAIPlugin = class extends BasePlugin {
21078
22447
  this.subscribeToInteractionsCreateChannel();
21079
22448
  }
21080
22449
  subscribeToGenerateContentChannel() {
21081
- const tracingChannel2 = googleGenAIChannels.generateContent.tracingChannel();
22450
+ const tracingChannel = googleGenAIChannels.generateContent.tracingChannel();
21082
22451
  const states = /* @__PURE__ */ new WeakMap();
21083
22452
  const unbindCurrentSpanStore = bindCurrentSpanStoreToStart2(
21084
- tracingChannel2,
22453
+ tracingChannel,
21085
22454
  states,
21086
22455
  (event) => {
21087
22456
  const params = event.arguments[0];
@@ -21155,14 +22524,14 @@ var GoogleGenAIPlugin = class extends BasePlugin {
21155
22524
  logErrorAndEndSpan(states, event);
21156
22525
  }
21157
22526
  };
21158
- tracingChannel2.subscribe(handlers);
22527
+ tracingChannel.subscribe(handlers);
21159
22528
  this.unsubscribers.push(() => {
21160
22529
  unbindCurrentSpanStore?.();
21161
- tracingChannel2.unsubscribe(handlers);
22530
+ tracingChannel.unsubscribe(handlers);
21162
22531
  });
21163
22532
  }
21164
22533
  subscribeToGenerateContentStreamChannel() {
21165
- const tracingChannel2 = googleGenAIChannels.generateContentStream.tracingChannel();
22534
+ const tracingChannel = googleGenAIChannels.generateContentStream.tracingChannel();
21166
22535
  const handlers = {
21167
22536
  start: (event) => {
21168
22537
  const streamEvent = event;
@@ -21183,16 +22552,16 @@ var GoogleGenAIPlugin = class extends BasePlugin {
21183
22552
  error: () => {
21184
22553
  }
21185
22554
  };
21186
- tracingChannel2.subscribe(handlers);
22555
+ tracingChannel.subscribe(handlers);
21187
22556
  this.unsubscribers.push(() => {
21188
- tracingChannel2.unsubscribe(handlers);
22557
+ tracingChannel.unsubscribe(handlers);
21189
22558
  });
21190
22559
  }
21191
22560
  subscribeToEmbedContentChannel() {
21192
- const tracingChannel2 = googleGenAIChannels.embedContent.tracingChannel();
22561
+ const tracingChannel = googleGenAIChannels.embedContent.tracingChannel();
21193
22562
  const states = /* @__PURE__ */ new WeakMap();
21194
22563
  const unbindCurrentSpanStore = bindCurrentSpanStoreToStart2(
21195
- tracingChannel2,
22564
+ tracingChannel,
21196
22565
  states,
21197
22566
  (event) => {
21198
22567
  const params = event.arguments[0];
@@ -21262,10 +22631,10 @@ var GoogleGenAIPlugin = class extends BasePlugin {
21262
22631
  logErrorAndEndSpan(states, event);
21263
22632
  }
21264
22633
  };
21265
- tracingChannel2.subscribe(handlers);
22634
+ tracingChannel.subscribe(handlers);
21266
22635
  this.unsubscribers.push(() => {
21267
22636
  unbindCurrentSpanStore?.();
21268
- tracingChannel2.unsubscribe(handlers);
22637
+ tracingChannel.unsubscribe(handlers);
21269
22638
  });
21270
22639
  }
21271
22640
  subscribeToInteractionsCreateChannel() {
@@ -21301,10 +22670,10 @@ function ensureSpanState(states, event, create) {
21301
22670
  states.set(event, created);
21302
22671
  return created;
21303
22672
  }
21304
- function bindCurrentSpanStoreToStart2(tracingChannel2, states, create) {
22673
+ function bindCurrentSpanStoreToStart2(tracingChannel, states, create) {
21305
22674
  const state = _internalGetGlobalState();
21306
22675
  const contextManager = state?.contextManager;
21307
- const startChannel = tracingChannel2.start;
22676
+ const startChannel = tracingChannel.start;
21308
22677
  const currentSpanStore = contextManager ? contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
21309
22678
  if (!startChannel?.bindStore || !currentSpanStore) {
21310
22679
  return void 0;
@@ -21807,11 +23176,11 @@ function summarizeEmbedContentOutput(response) {
21807
23176
  };
21808
23177
  }
21809
23178
  function populateUsageMetrics(metrics, usage) {
21810
- if (usage.promptTokenCount !== void 0) {
21811
- metrics.prompt_tokens = usage.promptTokenCount;
23179
+ if (usage.promptTokenCount !== void 0 || usage.toolUsePromptTokenCount !== void 0) {
23180
+ metrics.prompt_tokens = (usage.promptTokenCount ?? 0) + (usage.toolUsePromptTokenCount ?? 0);
21812
23181
  }
21813
- if (usage.candidatesTokenCount !== void 0) {
21814
- metrics.completion_tokens = usage.candidatesTokenCount;
23182
+ if (usage.candidatesTokenCount !== void 0 || usage.thoughtsTokenCount !== void 0) {
23183
+ metrics.completion_tokens = (usage.candidatesTokenCount ?? 0) + (usage.thoughtsTokenCount ?? 0);
21815
23184
  }
21816
23185
  if (usage.totalTokenCount !== void 0) {
21817
23186
  metrics.tokens = usage.totalTokenCount;
@@ -21822,13 +23191,26 @@ function populateUsageMetrics(metrics, usage) {
21822
23191
  if (usage.thoughtsTokenCount !== void 0) {
21823
23192
  metrics.completion_reasoning_tokens = usage.thoughtsTokenCount;
21824
23193
  }
23194
+ for (const detail of usage.promptTokensDetails ?? []) {
23195
+ if (detail.modality === "AUDIO" && detail.tokenCount !== void 0) {
23196
+ metrics.prompt_audio_tokens = (metrics.prompt_audio_tokens ?? 0) + detail.tokenCount;
23197
+ }
23198
+ }
23199
+ for (const detail of usage.candidatesTokensDetails ?? []) {
23200
+ if (detail.modality === "AUDIO" && detail.tokenCount !== void 0) {
23201
+ metrics.completion_audio_tokens = (metrics.completion_audio_tokens ?? 0) + detail.tokenCount;
23202
+ }
23203
+ if (detail.modality === "IMAGE" && detail.tokenCount !== void 0) {
23204
+ metrics.completion_image_tokens = (metrics.completion_image_tokens ?? 0) + detail.tokenCount;
23205
+ }
23206
+ }
21825
23207
  }
21826
23208
  function populateInteractionUsageMetrics(metrics, usage) {
21827
23209
  if (typeof usage.total_input_tokens === "number") {
21828
23210
  metrics.prompt_tokens = usage.total_input_tokens;
21829
23211
  }
21830
23212
  if (typeof usage.total_output_tokens === "number") {
21831
- metrics.completion_tokens = usage.total_output_tokens;
23213
+ metrics.completion_tokens = usage.total_output_tokens + (typeof usage.total_thought_tokens === "number" ? usage.total_thought_tokens : 0);
21832
23214
  }
21833
23215
  if (typeof usage.total_tokens === "number") {
21834
23216
  metrics.tokens = usage.total_tokens;
@@ -21839,6 +23221,24 @@ function populateInteractionUsageMetrics(metrics, usage) {
21839
23221
  if (typeof usage.total_thought_tokens === "number") {
21840
23222
  metrics.completion_reasoning_tokens = usage.total_thought_tokens;
21841
23223
  }
23224
+ for (const detail of Array.isArray(usage.input_tokens_by_modality) ? usage.input_tokens_by_modality : []) {
23225
+ if (typeof detail?.modality === "string" && detail.modality.toLowerCase() === "audio" && typeof detail.tokens === "number") {
23226
+ metrics.prompt_audio_tokens = (metrics.prompt_audio_tokens ?? 0) + detail.tokens;
23227
+ }
23228
+ }
23229
+ for (const detail of Array.isArray(usage.output_tokens_by_modality) ? usage.output_tokens_by_modality : []) {
23230
+ if (typeof detail?.modality !== "string" || typeof detail.tokens !== "number") {
23231
+ continue;
23232
+ }
23233
+ switch (detail.modality.toLowerCase()) {
23234
+ case "audio":
23235
+ metrics.completion_audio_tokens = (metrics.completion_audio_tokens ?? 0) + detail.tokens;
23236
+ break;
23237
+ case "image":
23238
+ metrics.completion_image_tokens = (metrics.completion_image_tokens ?? 0) + detail.tokens;
23239
+ break;
23240
+ }
23241
+ }
21842
23242
  }
21843
23243
  function aggregateGenerateContentChunks(chunks, startTime, firstTokenTime) {
21844
23244
  const end = getCurrentUnixTimestamp();
@@ -22577,6 +23977,299 @@ function extractTextGenerationStreamMetadata(chunks) {
22577
23977
  return void 0;
22578
23978
  }
22579
23979
 
23980
+ // src/instrumentation/plugins/huggingface-transformers-channels.ts
23981
+ var SUPPORTED_TASKS = /* @__PURE__ */ new Set([
23982
+ "text-generation",
23983
+ "text2text-generation",
23984
+ "summarization",
23985
+ "feature-extraction",
23986
+ "question-answering"
23987
+ ]);
23988
+ var pipelineInfo = /* @__PURE__ */ new WeakMap();
23989
+ function isSupportedHuggingFaceTransformersTask(task) {
23990
+ return typeof task === "string" && SUPPORTED_TASKS.has(task);
23991
+ }
23992
+ function registerHuggingFaceTransformersPipeline(pipeline, task, model) {
23993
+ if (typeof task !== "string") {
23994
+ return;
23995
+ }
23996
+ const info = { task };
23997
+ if (typeof model === "string") {
23998
+ info.model = model;
23999
+ }
24000
+ pipelineInfo.set(pipeline, info);
24001
+ }
24002
+ function getHuggingFaceTransformersPipelineInfo(pipeline) {
24003
+ return pipeline ? pipelineInfo.get(pipeline) : void 0;
24004
+ }
24005
+ var huggingFaceTransformersChannels = defineChannels(
24006
+ "@huggingface/transformers",
24007
+ {
24008
+ pipeline: channel({
24009
+ channelName: "pipeline",
24010
+ kind: "async"
24011
+ }),
24012
+ pipelineCall: channel({
24013
+ channelName: "pipeline.call",
24014
+ kind: "async"
24015
+ })
24016
+ },
24017
+ { instrumentationName: INSTRUMENTATION_NAMES.HUGGINGFACE }
24018
+ );
24019
+
24020
+ // src/instrumentation/plugins/huggingface-transformers-plugin.ts
24021
+ var REQUEST_METADATA_KEYS = [
24022
+ "temperature",
24023
+ "top_p",
24024
+ "max_tokens",
24025
+ "stop"
24026
+ ];
24027
+ var HuggingFaceTransformersPlugin = class extends BasePlugin {
24028
+ onEnable() {
24029
+ this.subscribeToPipelineFactory();
24030
+ this.unsubscribers.push(
24031
+ traceAsyncChannel(huggingFaceTransformersChannels.pipelineCall, {
24032
+ name: (_args, event) => {
24033
+ const task = getTask(event);
24034
+ const operation = task?.replaceAll("-", "_") ?? "unknown";
24035
+ return `huggingface.transformers.${operation}`;
24036
+ },
24037
+ type: "llm" /* LLM */,
24038
+ shouldTrace: (_args, event) => isSupportedHuggingFaceTransformersTask(
24039
+ getTask(event)
24040
+ ),
24041
+ extractInput: (args, event) => ({
24042
+ input: extractInput(
24043
+ getTask(event),
24044
+ args
24045
+ ),
24046
+ metadata: extractMetadata(
24047
+ event,
24048
+ args
24049
+ )
24050
+ }),
24051
+ extractOutput: (result, event) => extractOutput(
24052
+ getTask(event),
24053
+ result
24054
+ ),
24055
+ extractMetrics: () => ({})
24056
+ })
24057
+ );
24058
+ }
24059
+ onDisable() {
24060
+ this.unsubscribers = unsubscribeAll(this.unsubscribers);
24061
+ }
24062
+ subscribeToPipelineFactory() {
24063
+ const channel2 = huggingFaceTransformersChannels.pipeline.tracingChannel();
24064
+ const handlers = {
24065
+ asyncEnd: (event) => {
24066
+ if (typeof event.result !== "function") {
24067
+ return;
24068
+ }
24069
+ registerHuggingFaceTransformersPipeline(
24070
+ event.result,
24071
+ event.arguments?.[0],
24072
+ event.arguments?.[1]
24073
+ );
24074
+ }
24075
+ };
24076
+ channel2.subscribe(handlers);
24077
+ this.unsubscribers.push(() => channel2.unsubscribe(handlers));
24078
+ }
24079
+ };
24080
+ function getTask(event) {
24081
+ const self = event.self;
24082
+ const registeredTask = getHuggingFaceTransformersPipelineInfo(self)?.task;
24083
+ if (registeredTask !== void 0) {
24084
+ return registeredTask;
24085
+ }
24086
+ if (typeof self?.task === "string") {
24087
+ return self.task;
24088
+ }
24089
+ return void 0;
24090
+ }
24091
+ function extractMetadata(event, args) {
24092
+ const metadata = {
24093
+ provider: "huggingface"
24094
+ };
24095
+ const registeredModel = getHuggingFaceTransformersPipelineInfo(
24096
+ event.self
24097
+ )?.model;
24098
+ const model = registeredModel ?? modelIdentifier(event.self);
24099
+ if (model) {
24100
+ metadata.model = model;
24101
+ }
24102
+ const task = getTask(event);
24103
+ const options = task === "question-answering" ? args[2] : args[1];
24104
+ if (isObject(options)) {
24105
+ for (const key of REQUEST_METADATA_KEYS) {
24106
+ if (options[key] !== void 0) {
24107
+ metadata[key] = options[key];
24108
+ }
24109
+ }
24110
+ }
24111
+ return metadata;
24112
+ }
24113
+ function modelIdentifier(pipeline) {
24114
+ const model = pipeline?.model;
24115
+ if (!isObject(model)) {
24116
+ return void 0;
24117
+ }
24118
+ const config = isObject(model.config) ? model.config : void 0;
24119
+ for (const value of [
24120
+ config?._name_or_path,
24121
+ config?.name_or_path,
24122
+ config?.model_id,
24123
+ config?.modelId,
24124
+ model.name
24125
+ ]) {
24126
+ if (typeof value === "string" && value.length > 0) {
24127
+ return value;
24128
+ }
24129
+ }
24130
+ return void 0;
24131
+ }
24132
+ function extractInput(task, args) {
24133
+ switch (task) {
24134
+ case "feature-extraction":
24135
+ return args[0];
24136
+ case "question-answering": {
24137
+ const question = args[0];
24138
+ const context = args[1];
24139
+ if (Array.isArray(question) && Array.isArray(context) && question.every((value) => typeof value === "string") && context.every((value) => typeof value === "string")) {
24140
+ return question.map((value, index) => [
24141
+ {
24142
+ role: "user",
24143
+ content: `Context:
24144
+ ${context[index] ?? ""}
24145
+
24146
+ Question:
24147
+ ${value}`
24148
+ }
24149
+ ]);
24150
+ }
24151
+ if (typeof question === "string" && typeof context === "string") {
24152
+ return [
24153
+ {
24154
+ role: "user",
24155
+ content: `Context:
24156
+ ${context}
24157
+
24158
+ Question:
24159
+ ${question}`
24160
+ }
24161
+ ];
24162
+ }
24163
+ return { context, question };
24164
+ }
24165
+ }
24166
+ const input = args[0];
24167
+ if (task === "text-generation" && isChat(input)) {
24168
+ return input;
24169
+ }
24170
+ if (task === "text-generation" && Array.isArray(input) && input.every(isChat)) {
24171
+ return input;
24172
+ }
24173
+ if (typeof input === "string") {
24174
+ return [{ role: "user", content: input }];
24175
+ }
24176
+ if (Array.isArray(input) && input.every((value) => typeof value === "string")) {
24177
+ return input.map((value) => [
24178
+ {
24179
+ role: "user",
24180
+ content: value
24181
+ }
24182
+ ]);
24183
+ }
24184
+ return input;
24185
+ }
24186
+ function isChat(value) {
24187
+ return Array.isArray(value) && value.length > 0 && value.every(
24188
+ (message) => isObject(message) && typeof message.role === "string" && "content" in message
24189
+ );
24190
+ }
24191
+ function extractOutput(task, result) {
24192
+ switch (task) {
24193
+ case "feature-extraction":
24194
+ return summarizeEmbedding(result);
24195
+ case "question-answering":
24196
+ return choicesFromAnswers(result);
24197
+ default:
24198
+ return choicesFromGenerations(result);
24199
+ }
24200
+ }
24201
+ function summarizeEmbedding(result) {
24202
+ if (!isObject(result) || !Array.isArray(result.dims)) {
24203
+ return void 0;
24204
+ }
24205
+ const { dims } = result;
24206
+ if (dims.length === 0 || !dims.every((dimension) => typeof dimension === "number")) {
24207
+ return void 0;
24208
+ }
24209
+ if (dims.length === 1) {
24210
+ return { embedding_length: dims[0] };
24211
+ }
24212
+ if (dims.length === 2) {
24213
+ return {
24214
+ embedding_count: dims[0],
24215
+ embedding_length: dims[1]
24216
+ };
24217
+ }
24218
+ return {
24219
+ embedding_batch_count: dims[0],
24220
+ embedding_count: dims[1],
24221
+ embedding_length: dims.at(-1) ?? 0
24222
+ };
24223
+ }
24224
+ function choicesFromAnswers(result) {
24225
+ const answers = Array.isArray(result) ? result.flat() : [result];
24226
+ const choices = answers.flatMap((answer, index) => {
24227
+ if (!isObject(answer) || typeof answer.answer !== "string") {
24228
+ return [];
24229
+ }
24230
+ return [
24231
+ {
24232
+ index,
24233
+ finish_reason: "stop",
24234
+ message: {
24235
+ role: "assistant",
24236
+ content: answer.answer
24237
+ }
24238
+ }
24239
+ ];
24240
+ });
24241
+ return choices.length > 0 ? choices : void 0;
24242
+ }
24243
+ function choicesFromGenerations(result) {
24244
+ const generations = Array.isArray(result) ? result.flat() : [result];
24245
+ const choices = generations.flatMap((generation, index) => {
24246
+ if (!isObject(generation)) {
24247
+ return [];
24248
+ }
24249
+ const generated = generation.generated_text ?? generation.summary_text;
24250
+ let content;
24251
+ if (typeof generated === "string") {
24252
+ content = generated;
24253
+ } else if (isChat(generated)) {
24254
+ content = generated.at(-1)?.content;
24255
+ }
24256
+ if (typeof content !== "string") {
24257
+ return [];
24258
+ }
24259
+ return [
24260
+ {
24261
+ index,
24262
+ finish_reason: "stop",
24263
+ message: {
24264
+ role: "assistant",
24265
+ content
24266
+ }
24267
+ }
24268
+ ];
24269
+ });
24270
+ return choices.length > 0 ? choices : void 0;
24271
+ }
24272
+
22580
24273
  // src/instrumentation/plugins/openrouter-agent-channels.ts
22581
24274
  var openRouterAgentChannels = defineChannels(
22582
24275
  "@openrouter/agent",
@@ -22976,7 +24669,7 @@ function isWrappedTool(tool) {
22976
24669
  return Boolean(tool[OPENROUTER_WRAPPED_TOOL]);
22977
24670
  }
22978
24671
  function traceToolExecution(args) {
22979
- const tracingChannel2 = openRouterAgentChannels.toolExecute.tracingChannel();
24672
+ const tracingChannel = openRouterAgentChannels.toolExecute.tracingChannel();
22980
24673
  const input = args.args.length > 0 ? args.args[0] : void 0;
22981
24674
  const event = {
22982
24675
  arguments: [input],
@@ -22986,33 +24679,33 @@ function traceToolExecution(args) {
22986
24679
  toolCallId: args.toolCallId,
22987
24680
  toolName: args.toolName
22988
24681
  };
22989
- tracingChannel2.start.publish(event);
24682
+ tracingChannel.start.publish(event);
22990
24683
  try {
22991
24684
  const result = args.execute();
22992
- return publishToolResult(tracingChannel2, event, result);
24685
+ return publishToolResult(tracingChannel, event, result);
22993
24686
  } catch (error) {
22994
24687
  event.error = normalizeError(error);
22995
- tracingChannel2.error.publish(event);
24688
+ tracingChannel.error.publish(event);
22996
24689
  throw error;
22997
24690
  }
22998
24691
  }
22999
- function publishToolResult(tracingChannel2, event, result) {
24692
+ function publishToolResult(tracingChannel, event, result) {
23000
24693
  if (isPromiseLike(result)) {
23001
24694
  return result.then(
23002
24695
  (resolved) => {
23003
24696
  event.result = resolved;
23004
- tracingChannel2.asyncEnd.publish(event);
24697
+ tracingChannel.asyncEnd.publish(event);
23005
24698
  return resolved;
23006
24699
  },
23007
24700
  (error) => {
23008
24701
  event.error = normalizeError(error);
23009
- tracingChannel2.error.publish(event);
24702
+ tracingChannel.error.publish(event);
23010
24703
  throw error;
23011
24704
  }
23012
24705
  );
23013
24706
  }
23014
24707
  event.result = result;
23015
- tracingChannel2.asyncEnd.publish(event);
24708
+ tracingChannel.asyncEnd.publish(event);
23016
24709
  return result;
23017
24710
  }
23018
24711
  function getToolCallId(context) {
@@ -23918,7 +25611,7 @@ function isWrappedTool2(tool) {
23918
25611
  return Boolean(tool[OPENROUTER_WRAPPED_TOOL2]);
23919
25612
  }
23920
25613
  function traceToolExecution2(args) {
23921
- const tracingChannel2 = openRouterChannels.toolExecute.tracingChannel();
25614
+ const tracingChannel = openRouterChannels.toolExecute.tracingChannel();
23922
25615
  const input = args.args.length > 0 ? args.args[0] : void 0;
23923
25616
  const event = {
23924
25617
  arguments: [input],
@@ -23928,33 +25621,33 @@ function traceToolExecution2(args) {
23928
25621
  toolCallId: args.toolCallId,
23929
25622
  toolName: args.toolName
23930
25623
  };
23931
- tracingChannel2.start.publish(event);
25624
+ tracingChannel.start.publish(event);
23932
25625
  try {
23933
25626
  const result = args.execute();
23934
- return publishToolResult2(tracingChannel2, event, result);
25627
+ return publishToolResult2(tracingChannel, event, result);
23935
25628
  } catch (error) {
23936
25629
  event.error = normalizeError2(error);
23937
- tracingChannel2.error.publish(event);
25630
+ tracingChannel.error.publish(event);
23938
25631
  throw error;
23939
25632
  }
23940
25633
  }
23941
- function publishToolResult2(tracingChannel2, event, result) {
25634
+ function publishToolResult2(tracingChannel, event, result) {
23942
25635
  if (isPromiseLike(result)) {
23943
25636
  return result.then(
23944
25637
  (resolved) => {
23945
25638
  event.result = resolved;
23946
- tracingChannel2.asyncEnd.publish(event);
25639
+ tracingChannel.asyncEnd.publish(event);
23947
25640
  return resolved;
23948
25641
  },
23949
25642
  (error) => {
23950
25643
  event.error = normalizeError2(error);
23951
- tracingChannel2.error.publish(event);
25644
+ tracingChannel.error.publish(event);
23952
25645
  throw error;
23953
25646
  }
23954
25647
  );
23955
25648
  }
23956
25649
  event.result = result;
23957
- tracingChannel2.asyncEnd.publish(event);
25650
+ tracingChannel.asyncEnd.publish(event);
23958
25651
  return result;
23959
25652
  }
23960
25653
  function getToolCallId2(context) {
@@ -25106,6 +26799,470 @@ function aggregateMistralStreamChunks(chunks) {
25106
26799
  };
25107
26800
  }
25108
26801
 
26802
+ // src/instrumentation/plugins/ollama-channels.ts
26803
+ var ollamaChannels = defineChannels(
26804
+ "ollama",
26805
+ {
26806
+ chat: channel({
26807
+ channelName: "chat",
26808
+ kind: "async"
26809
+ }),
26810
+ generate: channel({
26811
+ channelName: "generate",
26812
+ kind: "async"
26813
+ }),
26814
+ embed: channel({
26815
+ channelName: "embed",
26816
+ kind: "async"
26817
+ })
26818
+ },
26819
+ { instrumentationName: INSTRUMENTATION_NAMES.OLLAMA }
26820
+ );
26821
+
26822
+ // src/instrumentation/plugins/ollama-plugin.ts
26823
+ var OllamaPlugin = class extends BasePlugin {
26824
+ onEnable() {
26825
+ this.unsubscribers.push(
26826
+ traceStreamingChannel(ollamaChannels.chat, {
26827
+ name: "ollama.chat",
26828
+ type: "llm" /* LLM */,
26829
+ extractInput: extractOllamaChatInput,
26830
+ extractOutput: (result, event) => extractOllamaChatOutput(
26831
+ result,
26832
+ countOllamaToolCalls(event?.arguments?.[0]?.messages)
26833
+ ),
26834
+ extractMetadata: extractOllamaResponseMetadata,
26835
+ extractMetrics: extractOllamaMetrics,
26836
+ aggregateChunks: aggregateOllamaChatChunks
26837
+ }),
26838
+ traceStreamingChannel(ollamaChannels.generate, {
26839
+ name: "ollama.generate",
26840
+ type: "llm" /* LLM */,
26841
+ extractInput: extractOllamaGenerateInput,
26842
+ extractOutput: extractOllamaGenerateOutput,
26843
+ extractMetadata: extractOllamaResponseMetadata,
26844
+ extractMetrics: extractOllamaMetrics,
26845
+ aggregateChunks: aggregateOllamaGenerateChunks
26846
+ }),
26847
+ traceAsyncChannel(ollamaChannels.embed, {
26848
+ name: "ollama.embed",
26849
+ type: "llm" /* LLM */,
26850
+ extractInput: extractOllamaEmbedInput,
26851
+ extractOutput: extractOllamaEmbedOutput,
26852
+ extractMetadata: extractOllamaResponseMetadata,
26853
+ extractMetrics: extractOllamaMetrics
26854
+ })
26855
+ );
26856
+ }
26857
+ onDisable() {
26858
+ this.unsubscribers = unsubscribeAll(this.unsubscribers);
26859
+ }
26860
+ };
26861
+ function isNonNegativeNumber(value) {
26862
+ return typeof value === "number" && Number.isFinite(value) && value >= 0;
26863
+ }
26864
+ function normalizeFinishReason(response, hasToolCalls = false) {
26865
+ if (hasToolCalls) {
26866
+ return "tool_calls";
26867
+ }
26868
+ return response?.done_reason || "stop";
26869
+ }
26870
+ function stringifyArguments(value) {
26871
+ if (typeof value === "string") {
26872
+ return value;
26873
+ }
26874
+ try {
26875
+ return JSON.stringify(value ?? {});
26876
+ } catch {
26877
+ return String(value);
26878
+ }
26879
+ }
26880
+ function syntheticToolCallId(name, index) {
26881
+ const normalizedName = name.replace(/[^a-zA-Z0-9_-]/g, "_") || "tool";
26882
+ return `ollama_call_${normalizedName}_${index}`;
26883
+ }
26884
+ function normalizeToolCall(toolCall, index) {
26885
+ const name = toolCall.function?.name;
26886
+ if (typeof name !== "string" || name.length === 0) {
26887
+ return void 0;
26888
+ }
26889
+ return {
26890
+ id: typeof toolCall.id === "string" && toolCall.id.length > 0 ? toolCall.id : syntheticToolCallId(name, index),
26891
+ type: "function",
26892
+ function: {
26893
+ name,
26894
+ arguments: stringifyArguments(toolCall.function?.arguments)
26895
+ }
26896
+ };
26897
+ }
26898
+ function normalizeToolCalls(toolCalls, syntheticIdOffset = 0) {
26899
+ if (!Array.isArray(toolCalls)) {
26900
+ return [];
26901
+ }
26902
+ return toolCalls.flatMap((toolCall, index) => {
26903
+ const normalized = normalizeToolCall(toolCall, syntheticIdOffset + index);
26904
+ return normalized ? [normalized] : [];
26905
+ });
26906
+ }
26907
+ function countOllamaToolCalls(messages) {
26908
+ if (!Array.isArray(messages)) {
26909
+ return 0;
26910
+ }
26911
+ return messages.reduce(
26912
+ (count, message) => count + (isObject(message) && Array.isArray(message.tool_calls) ? message.tool_calls.length : 0),
26913
+ 0
26914
+ );
26915
+ }
26916
+ function imageBytes(value) {
26917
+ if (value instanceof Uint8Array) {
26918
+ return value;
26919
+ }
26920
+ if (value instanceof ArrayBuffer) {
26921
+ return new Uint8Array(value);
26922
+ }
26923
+ if (typeof value !== "string" || value.startsWith("data:")) {
26924
+ return void 0;
26925
+ }
26926
+ try {
26927
+ const decoded = atob(value.slice(0, 24));
26928
+ return Uint8Array.from(decoded, (character) => character.charCodeAt(0));
26929
+ } catch {
26930
+ return void 0;
26931
+ }
26932
+ }
26933
+ function inferImageMediaType(value) {
26934
+ if (typeof value === "string") {
26935
+ const dataUrlType = value.match(/^data:(image\/[^;]+);base64,/i)?.[1];
26936
+ if (dataUrlType) {
26937
+ return dataUrlType;
26938
+ }
26939
+ }
26940
+ const bytes = imageBytes(value);
26941
+ if (!bytes) {
26942
+ return void 0;
26943
+ }
26944
+ if (bytes[0] === 137 && bytes[1] === 80 && bytes[2] === 78 && bytes[3] === 71) {
26945
+ return "image/png";
26946
+ }
26947
+ if (bytes[0] === 255 && bytes[1] === 216 && bytes[2] === 255) {
26948
+ return "image/jpeg";
26949
+ }
26950
+ const signature = String.fromCharCode(...bytes.slice(0, 12));
26951
+ if (signature.startsWith("GIF87a") || signature.startsWith("GIF89a")) {
26952
+ return "image/gif";
26953
+ }
26954
+ if (signature.startsWith("RIFF") && signature.slice(8, 12) === "WEBP") {
26955
+ return "image/webp";
26956
+ }
26957
+ return void 0;
26958
+ }
26959
+ function normalizeTextAndImages(content, images) {
26960
+ if (!images || images.length === 0) {
26961
+ return { content };
26962
+ }
26963
+ const imageParts = [];
26964
+ const unrecognizedImages = [];
26965
+ for (const image of images) {
26966
+ let localImagePath;
26967
+ let localPathMediaType;
26968
+ if (typeof image === "string" && !/^data:/i.test(image) && !/^https?:\/\//i.test(image)) {
26969
+ const extension = image.match(/\.([a-z0-9]+)$/i)?.[1]?.toLowerCase();
26970
+ const extensionMediaType = {
26971
+ png: "image/png",
26972
+ jpg: "image/jpeg",
26973
+ jpeg: "image/jpeg",
26974
+ gif: "image/gif",
26975
+ webp: "image/webp"
26976
+ }[extension ?? ""];
26977
+ if (extensionMediaType && isomorph_default.statSync) {
26978
+ try {
26979
+ if (isomorph_default.statSync(image).isFile()) {
26980
+ localImagePath = image;
26981
+ localPathMediaType = extensionMediaType;
26982
+ }
26983
+ } catch {
26984
+ }
26985
+ }
26986
+ }
26987
+ const mediaType = localPathMediaType ?? inferImageMediaType(image);
26988
+ if (!mediaType) {
26989
+ unrecognizedImages.push(image);
26990
+ continue;
26991
+ }
26992
+ const processedImage = localImagePath ? new Attachment({
26993
+ data: localImagePath,
26994
+ filename: localImagePath.split(/[\\/]/).at(-1) ?? "image",
26995
+ contentType: mediaType
26996
+ }) : processInputAttachments({
26997
+ type: "image",
26998
+ image,
26999
+ mediaType
27000
+ }).image;
27001
+ imageParts.push({
27002
+ type: "image_url",
27003
+ image_url: { url: processedImage }
27004
+ });
27005
+ }
27006
+ return {
27007
+ content: imageParts.length > 0 ? [...content ? [{ type: "text", text: content }] : [], ...imageParts] : content,
27008
+ ...unrecognizedImages.length > 0 ? { unrecognizedImages } : {}
27009
+ };
27010
+ }
27011
+ function normalizeMessage(message, toolCallId, syntheticToolCallIdOffset = 0) {
27012
+ if (typeof message.role !== "string") {
27013
+ return void 0;
27014
+ }
27015
+ const toolCalls = normalizeToolCalls(
27016
+ message.tool_calls,
27017
+ syntheticToolCallIdOffset
27018
+ );
27019
+ if (message.role === "tool") {
27020
+ const toolName = typeof message.tool_name === "string" && message.tool_name.length > 0 ? message.tool_name : "tool";
27021
+ return {
27022
+ role: "tool",
27023
+ tool_call_id: toolCallId ?? syntheticToolCallId(toolName, 0),
27024
+ content: typeof message.content === "string" ? message.content : ""
27025
+ };
27026
+ }
27027
+ const normalizedContent = normalizeTextAndImages(
27028
+ typeof message.content === "string" ? message.content || (toolCalls.length > 0 ? null : "") : toolCalls.length > 0 ? null : "",
27029
+ message.images
27030
+ );
27031
+ return {
27032
+ role: message.role,
27033
+ content: normalizedContent.content,
27034
+ ...typeof message.thinking === "string" && message.thinking.length > 0 ? { reasoning: message.thinking } : {},
27035
+ ...toolCalls.length > 0 ? { tool_calls: toolCalls } : {},
27036
+ ...normalizedContent.unrecognizedImages ? { images: normalizedContent.unrecognizedImages } : {}
27037
+ };
27038
+ }
27039
+ function normalizeMessages(messages) {
27040
+ if (!Array.isArray(messages)) {
27041
+ return [];
27042
+ }
27043
+ const pendingToolCallIds = /* @__PURE__ */ new Map();
27044
+ let syntheticToolCallIdOffset = 0;
27045
+ return messages.flatMap((message) => {
27046
+ if (!isObject(message)) {
27047
+ return [];
27048
+ }
27049
+ const ollamaMessage = message;
27050
+ let toolCallId;
27051
+ if (ollamaMessage.role === "tool") {
27052
+ const toolName = ollamaMessage.tool_name;
27053
+ if (typeof toolName === "string") {
27054
+ toolCallId = pendingToolCallIds.get(toolName)?.shift();
27055
+ }
27056
+ }
27057
+ const normalized = normalizeMessage(
27058
+ ollamaMessage,
27059
+ toolCallId,
27060
+ syntheticToolCallIdOffset
27061
+ );
27062
+ if (Array.isArray(ollamaMessage.tool_calls)) {
27063
+ syntheticToolCallIdOffset += ollamaMessage.tool_calls.length;
27064
+ }
27065
+ if (ollamaMessage.role === "assistant" && normalized) {
27066
+ const toolCalls = Array.isArray(normalized.tool_calls) ? normalized.tool_calls : [];
27067
+ for (const toolCall of toolCalls) {
27068
+ if (!isObject(toolCall) || !isObject(toolCall.function)) {
27069
+ continue;
27070
+ }
27071
+ const name = toolCall.function.name;
27072
+ const id = toolCall.id;
27073
+ if (typeof name === "string" && typeof id === "string") {
27074
+ const ids = pendingToolCallIds.get(name) ?? [];
27075
+ ids.push(id);
27076
+ pendingToolCallIds.set(name, ids);
27077
+ }
27078
+ }
27079
+ }
27080
+ return normalized ? [normalized] : [];
27081
+ });
27082
+ }
27083
+ function normalizeToolDefinition(tool) {
27084
+ const fn = tool.function;
27085
+ if (!fn || typeof fn.name !== "string" || fn.name.length === 0) {
27086
+ return void 0;
27087
+ }
27088
+ return {
27089
+ type: "function",
27090
+ function: {
27091
+ name: fn.name,
27092
+ ...typeof fn.description === "string" ? { description: fn.description } : {},
27093
+ ...isObject(fn.parameters) ? { parameters: fn.parameters } : {}
27094
+ }
27095
+ };
27096
+ }
27097
+ function extractToolsMetadata(tools) {
27098
+ if (!Array.isArray(tools)) {
27099
+ return {};
27100
+ }
27101
+ const normalized = tools.flatMap((tool) => {
27102
+ if (!isObject(tool)) {
27103
+ return [];
27104
+ }
27105
+ const definition = normalizeToolDefinition(tool);
27106
+ return definition ? [definition] : [];
27107
+ });
27108
+ return normalized.length > 0 ? { tools: normalized } : {};
27109
+ }
27110
+ function extractOptionsMetadata(options) {
27111
+ if (!isObject(options)) {
27112
+ return {};
27113
+ }
27114
+ const metadata = {};
27115
+ const mappings = [
27116
+ ["temperature", "temperature"],
27117
+ ["top_p", "top_p"],
27118
+ ["num_predict", "max_tokens"],
27119
+ ["frequency_penalty", "frequency_penalty"],
27120
+ ["presence_penalty", "presence_penalty"],
27121
+ ["stop", "stop"]
27122
+ ];
27123
+ for (const [source, target] of mappings) {
27124
+ if (options[source] !== void 0) {
27125
+ metadata[target] = options[source];
27126
+ }
27127
+ }
27128
+ return metadata;
27129
+ }
27130
+ function extractRequestMetadata(request) {
27131
+ return {
27132
+ provider: "ollama",
27133
+ ...typeof request?.model === "string" ? { model: request.model } : {},
27134
+ ...extractOptionsMetadata(request?.options),
27135
+ ...request?.format !== void 0 ? { response_format: request.format } : {}
27136
+ };
27137
+ }
27138
+ function extractOllamaChatInput([request]) {
27139
+ return {
27140
+ input: normalizeMessages(request.messages),
27141
+ metadata: {
27142
+ ...extractRequestMetadata(request),
27143
+ ...extractToolsMetadata(request.tools)
27144
+ }
27145
+ };
27146
+ }
27147
+ function extractOllamaGenerateInput([request]) {
27148
+ const normalizedPrompt = normalizeTextAndImages(
27149
+ typeof request.prompt === "string" ? request.prompt : "",
27150
+ Array.isArray(request.images) ? request.images : void 0
27151
+ );
27152
+ const input = [
27153
+ ...typeof request.system === "string" ? [{ role: "system", content: request.system }] : [],
27154
+ {
27155
+ role: "user",
27156
+ content: normalizedPrompt.content,
27157
+ ...typeof request.suffix === "string" ? { suffix: request.suffix } : {},
27158
+ ...normalizedPrompt.unrecognizedImages ? { images: normalizedPrompt.unrecognizedImages } : {}
27159
+ }
27160
+ ];
27161
+ return {
27162
+ input,
27163
+ metadata: extractRequestMetadata(request)
27164
+ };
27165
+ }
27166
+ function extractOllamaEmbedInput([request]) {
27167
+ return {
27168
+ input: request.input,
27169
+ metadata: extractRequestMetadata(request)
27170
+ };
27171
+ }
27172
+ function extractOllamaChatOutput(result, syntheticToolCallIdOffset = 0) {
27173
+ if (!isObject(result) || !isObject(result.message)) {
27174
+ return void 0;
27175
+ }
27176
+ const message = normalizeMessage(
27177
+ result.message,
27178
+ void 0,
27179
+ syntheticToolCallIdOffset
27180
+ );
27181
+ if (!message) {
27182
+ return void 0;
27183
+ }
27184
+ const toolCalls = Array.isArray(message.tool_calls) ? message.tool_calls : [];
27185
+ return [
27186
+ {
27187
+ index: 0,
27188
+ finish_reason: normalizeFinishReason(result, toolCalls.length > 0),
27189
+ message
27190
+ }
27191
+ ];
27192
+ }
27193
+ function extractOllamaGenerateOutput(result) {
27194
+ if (!isObject(result) || typeof result.response !== "string") {
27195
+ return void 0;
27196
+ }
27197
+ return [
27198
+ {
27199
+ index: 0,
27200
+ finish_reason: normalizeFinishReason(result),
27201
+ message: {
27202
+ role: "assistant",
27203
+ content: result.response,
27204
+ ...typeof result.thinking === "string" && result.thinking.length > 0 ? { reasoning: result.thinking } : {}
27205
+ }
27206
+ }
27207
+ ];
27208
+ }
27209
+ function extractOllamaEmbedOutput(result) {
27210
+ const embedding = Array.isArray(result?.embeddings) ? result.embeddings[0] : void 0;
27211
+ return Array.isArray(embedding) ? { embedding_length: embedding.length } : void 0;
27212
+ }
27213
+ function extractOllamaResponseMetadata(result) {
27214
+ return typeof result?.model === "string" ? { model: result.model } : void 0;
27215
+ }
27216
+ function extractOllamaMetrics(result) {
27217
+ const metrics = {};
27218
+ const promptTokens = result?.prompt_eval_count;
27219
+ const completionTokens = result?.eval_count;
27220
+ if (isNonNegativeNumber(promptTokens)) {
27221
+ metrics.prompt_tokens = promptTokens;
27222
+ }
27223
+ if (isNonNegativeNumber(completionTokens)) {
27224
+ metrics.completion_tokens = completionTokens;
27225
+ }
27226
+ if (isNonNegativeNumber(promptTokens) || isNonNegativeNumber(completionTokens)) {
27227
+ metrics.tokens = (isNonNegativeNumber(promptTokens) ? promptTokens : 0) + (isNonNegativeNumber(completionTokens) ? completionTokens : 0);
27228
+ }
27229
+ return metrics;
27230
+ }
27231
+ function aggregateOllamaChatChunks(chunks, _result, event, _startTime) {
27232
+ const last = chunks.at(-1);
27233
+ const message = {
27234
+ role: "assistant",
27235
+ content: chunks.map((chunk) => chunk.message?.content ?? "").join(""),
27236
+ thinking: chunks.map((chunk) => chunk.message?.thinking ?? "").join(""),
27237
+ tool_calls: chunks.flatMap((chunk) => chunk.message?.tool_calls ?? [])
27238
+ };
27239
+ const response = {
27240
+ ...last,
27241
+ message
27242
+ };
27243
+ return {
27244
+ output: extractOllamaChatOutput(
27245
+ response,
27246
+ countOllamaToolCalls(event?.arguments?.[0]?.messages)
27247
+ ),
27248
+ metrics: extractOllamaMetrics(last ?? {}),
27249
+ metadata: extractOllamaResponseMetadata(last ?? {})
27250
+ };
27251
+ }
27252
+ function aggregateOllamaGenerateChunks(chunks, _result, _event, _startTime) {
27253
+ const last = chunks.at(-1);
27254
+ const response = {
27255
+ ...last,
27256
+ response: chunks.map((chunk) => chunk.response ?? "").join(""),
27257
+ thinking: chunks.map((chunk) => chunk.thinking ?? "").join("")
27258
+ };
27259
+ return {
27260
+ output: extractOllamaGenerateOutput(response),
27261
+ metrics: extractOllamaMetrics(last ?? {}),
27262
+ metadata: extractOllamaResponseMetadata(last ?? {})
27263
+ };
27264
+ }
27265
+
25109
27266
  // src/instrumentation/plugins/google-adk-channels.ts
25110
27267
  var googleADKChannels = defineChannels(
25111
27268
  "@google/adk",
@@ -25144,7 +27301,7 @@ var GoogleADKPlugin = class extends BasePlugin {
25144
27301
  this.activeAgentSpans.clear();
25145
27302
  }
25146
27303
  subscribeToRunnerRunAsync() {
25147
- const tracingChannel2 = googleADKChannels.runnerRunAsync.tracingChannel();
27304
+ const tracingChannel = googleADKChannels.runnerRunAsync.tracingChannel();
25148
27305
  const states = /* @__PURE__ */ new WeakMap();
25149
27306
  const createState = (event) => {
25150
27307
  const params = event.arguments[0] ?? {};
@@ -25175,7 +27332,7 @@ var GoogleADKPlugin = class extends BasePlugin {
25175
27332
  return { span, startTime, events: [], contextKey };
25176
27333
  };
25177
27334
  const unbindCurrentSpanStore = bindCurrentSpanStoreToStart3(
25178
- tracingChannel2,
27335
+ tracingChannel,
25179
27336
  states,
25180
27337
  createState
25181
27338
  );
@@ -25227,14 +27384,14 @@ var GoogleADKPlugin = class extends BasePlugin {
25227
27384
  states.delete(event);
25228
27385
  }
25229
27386
  };
25230
- tracingChannel2.subscribe(handlers);
27387
+ tracingChannel.subscribe(handlers);
25231
27388
  this.unsubscribers.push(() => {
25232
27389
  unbindCurrentSpanStore?.();
25233
- tracingChannel2.unsubscribe(handlers);
27390
+ tracingChannel.unsubscribe(handlers);
25234
27391
  });
25235
27392
  }
25236
27393
  subscribeToAgentRunAsync() {
25237
- const tracingChannel2 = googleADKChannels.agentRunAsync.tracingChannel();
27394
+ const tracingChannel = googleADKChannels.agentRunAsync.tracingChannel();
25238
27395
  const states = /* @__PURE__ */ new WeakMap();
25239
27396
  const createState = (event) => {
25240
27397
  const parentContext = event.arguments[0];
@@ -25283,7 +27440,7 @@ var GoogleADKPlugin = class extends BasePlugin {
25283
27440
  return { span, startTime, events: [], contextKey, name: agentName };
25284
27441
  };
25285
27442
  const unbindCurrentSpanStore = bindCurrentSpanStoreToStart3(
25286
- tracingChannel2,
27443
+ tracingChannel,
25287
27444
  states,
25288
27445
  createState
25289
27446
  );
@@ -25335,14 +27492,14 @@ var GoogleADKPlugin = class extends BasePlugin {
25335
27492
  states.delete(event);
25336
27493
  }
25337
27494
  };
25338
- tracingChannel2.subscribe(handlers);
27495
+ tracingChannel.subscribe(handlers);
25339
27496
  this.unsubscribers.push(() => {
25340
27497
  unbindCurrentSpanStore?.();
25341
- tracingChannel2.unsubscribe(handlers);
27498
+ tracingChannel.unsubscribe(handlers);
25342
27499
  });
25343
27500
  }
25344
27501
  subscribeToToolRunAsync() {
25345
- const tracingChannel2 = googleADKChannels.toolRunAsync.tracingChannel();
27502
+ const tracingChannel = googleADKChannels.toolRunAsync.tracingChannel();
25346
27503
  const states = /* @__PURE__ */ new WeakMap();
25347
27504
  const handlers = {
25348
27505
  start: (event) => {
@@ -25409,9 +27566,9 @@ var GoogleADKPlugin = class extends BasePlugin {
25409
27566
  states.delete(event);
25410
27567
  }
25411
27568
  };
25412
- tracingChannel2.subscribe(handlers);
27569
+ tracingChannel.subscribe(handlers);
25413
27570
  this.unsubscribers.push(() => {
25414
- tracingChannel2.unsubscribe(handlers);
27571
+ tracingChannel.unsubscribe(handlers);
25415
27572
  });
25416
27573
  }
25417
27574
  };
@@ -25487,10 +27644,10 @@ function bindAsyncIterableToCurrentSpan(stream, span) {
25487
27644
  }
25488
27645
  return stream;
25489
27646
  }
25490
- function bindCurrentSpanStoreToStart3(tracingChannel2, states, create) {
27647
+ function bindCurrentSpanStoreToStart3(tracingChannel, states, create) {
25491
27648
  const state = _internalGetGlobalState();
25492
27649
  const contextManager = state?.contextManager;
25493
- const startChannel = tracingChannel2.start;
27650
+ const startChannel = tracingChannel.start;
25494
27651
  const currentSpanStore = contextManager ? contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
25495
27652
  if (!startChannel?.bindStore || !currentSpanStore) {
25496
27653
  return void 0;
@@ -25742,15 +27899,32 @@ function aggregateUsageFromEvents(events) {
25742
27899
  if (usage.thoughtsTokenCount !== void 0) {
25743
27900
  aggregated.thoughtsTokenCount = (aggregated.thoughtsTokenCount ?? 0) + usage.thoughtsTokenCount;
25744
27901
  }
27902
+ if (usage.toolUsePromptTokenCount !== void 0) {
27903
+ aggregated.toolUsePromptTokenCount = (aggregated.toolUsePromptTokenCount ?? 0) + usage.toolUsePromptTokenCount;
27904
+ }
27905
+ for (const detailsField of [
27906
+ "promptTokensDetails",
27907
+ "cacheTokensDetails",
27908
+ "candidatesTokensDetails",
27909
+ "toolUsePromptTokensDetails"
27910
+ ]) {
27911
+ const details = usage[detailsField];
27912
+ if (details !== void 0) {
27913
+ aggregated[detailsField] = [
27914
+ ...aggregated[detailsField] ?? [],
27915
+ ...details
27916
+ ];
27917
+ }
27918
+ }
25745
27919
  }
25746
27920
  return hasUsage ? aggregated : void 0;
25747
27921
  }
25748
27922
  function populateUsageMetrics2(metrics, usage) {
25749
- if (usage.promptTokenCount !== void 0) {
25750
- metrics.prompt_tokens = usage.promptTokenCount;
27923
+ if (usage.promptTokenCount !== void 0 || usage.toolUsePromptTokenCount !== void 0) {
27924
+ metrics.prompt_tokens = (usage.promptTokenCount ?? 0) + (usage.toolUsePromptTokenCount ?? 0);
25751
27925
  }
25752
- if (usage.candidatesTokenCount !== void 0) {
25753
- metrics.completion_tokens = usage.candidatesTokenCount;
27926
+ if (usage.candidatesTokenCount !== void 0 || usage.thoughtsTokenCount !== void 0) {
27927
+ metrics.completion_tokens = (usage.candidatesTokenCount ?? 0) + (usage.thoughtsTokenCount ?? 0);
25754
27928
  }
25755
27929
  if (usage.totalTokenCount !== void 0) {
25756
27930
  metrics.tokens = usage.totalTokenCount;
@@ -25761,6 +27935,19 @@ function populateUsageMetrics2(metrics, usage) {
25761
27935
  if (usage.thoughtsTokenCount !== void 0) {
25762
27936
  metrics.completion_reasoning_tokens = usage.thoughtsTokenCount;
25763
27937
  }
27938
+ for (const detail of usage.promptTokensDetails ?? []) {
27939
+ if (detail.modality === "AUDIO" && detail.tokenCount !== void 0) {
27940
+ metrics.prompt_audio_tokens = (metrics.prompt_audio_tokens ?? 0) + detail.tokenCount;
27941
+ }
27942
+ }
27943
+ for (const detail of usage.candidatesTokensDetails ?? []) {
27944
+ if (detail.modality === "AUDIO" && detail.tokenCount !== void 0) {
27945
+ metrics.completion_audio_tokens = (metrics.completion_audio_tokens ?? 0) + detail.tokenCount;
27946
+ }
27947
+ if (detail.modality === "IMAGE" && detail.tokenCount !== void 0) {
27948
+ metrics.completion_image_tokens = (metrics.completion_image_tokens ?? 0) + detail.tokenCount;
27949
+ }
27950
+ }
25764
27951
  }
25765
27952
  function cleanMetrics4(metrics) {
25766
27953
  const cleaned = {};
@@ -27326,10 +29513,10 @@ var GenkitPlugin = class extends BasePlugin {
27326
29513
  this.subscribeToActionStream();
27327
29514
  }
27328
29515
  subscribeToActionRun() {
27329
- const tracingChannel2 = genkitChannels.actionRun.tracingChannel();
29516
+ const tracingChannel = genkitChannels.actionRun.tracingChannel();
27330
29517
  const states = /* @__PURE__ */ new WeakMap();
27331
29518
  const unbindCurrentSpanStore = bindActionCurrentSpanStoreToStart(
27332
- tracingChannel2,
29519
+ tracingChannel,
27333
29520
  states,
27334
29521
  (event) => startActionRunSpan(event)
27335
29522
  );
@@ -27366,17 +29553,17 @@ var GenkitPlugin = class extends BasePlugin {
27366
29553
  states.delete(event);
27367
29554
  }
27368
29555
  };
27369
- tracingChannel2.subscribe(handlers);
29556
+ tracingChannel.subscribe(handlers);
27370
29557
  this.unsubscribers.push(() => {
27371
29558
  unbindCurrentSpanStore?.();
27372
- tracingChannel2.unsubscribe(handlers);
29559
+ tracingChannel.unsubscribe(handlers);
27373
29560
  });
27374
29561
  }
27375
29562
  subscribeToActionSpan() {
27376
- const tracingChannel2 = genkitCoreChannels.actionSpan.tracingChannel();
29563
+ const tracingChannel = genkitCoreChannels.actionSpan.tracingChannel();
27377
29564
  const states = /* @__PURE__ */ new WeakMap();
27378
29565
  const unbindCurrentSpanStore = bindActionCurrentSpanStoreToStart(
27379
- tracingChannel2,
29566
+ tracingChannel,
27380
29567
  states,
27381
29568
  (event) => startActionSpan(event)
27382
29569
  );
@@ -27414,10 +29601,10 @@ var GenkitPlugin = class extends BasePlugin {
27414
29601
  states.delete(event);
27415
29602
  }
27416
29603
  };
27417
- tracingChannel2.subscribe(handlers);
29604
+ tracingChannel.subscribe(handlers);
27418
29605
  this.unsubscribers.push(() => {
27419
29606
  unbindCurrentSpanStore?.();
27420
- tracingChannel2.unsubscribe(handlers);
29607
+ tracingChannel.unsubscribe(handlers);
27421
29608
  });
27422
29609
  }
27423
29610
  subscribeToActionStream() {
@@ -27486,10 +29673,10 @@ function ensureActionSpanState(states, event, create) {
27486
29673
  }
27487
29674
  return created;
27488
29675
  }
27489
- function bindActionCurrentSpanStoreToStart(tracingChannel2, states, create) {
29676
+ function bindActionCurrentSpanStoreToStart(tracingChannel, states, create) {
27490
29677
  const state = _internalGetGlobalState();
27491
29678
  const contextManager = state?.contextManager;
27492
- const startChannel = tracingChannel2.start;
29679
+ const startChannel = tracingChannel.start;
27493
29680
  const currentSpanStore = contextManager ? contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
27494
29681
  if (!startChannel?.bindStore || !currentSpanStore) {
27495
29682
  return void 0;
@@ -28829,7 +31016,7 @@ var FlueObserveBridge = class {
28829
31016
  return;
28830
31017
  }
28831
31018
  const state = this.operationsById.get(event.operationId) ?? this.startSyntheticOperation(event);
28832
- const output = operationOutput(event);
31019
+ const output = operationOutput(event) ?? outputFromAgentTurn(state.latestAgentOutput);
28833
31020
  const metadata = {
28834
31021
  ...state.metadata,
28835
31022
  ...extractEventMetadata(event),
@@ -28838,7 +31025,7 @@ var FlueObserveBridge = class {
28838
31025
  };
28839
31026
  this.finishPendingChildrenForOperation(event, output);
28840
31027
  safeLog3(state.span, {
28841
- ...event.isError ? { error: toLoggedError(event.error) } : {},
31028
+ ...event.isError ? { error: toLoggedError(event.errorInfo ?? event.error) } : {},
28842
31029
  metadata,
28843
31030
  metrics: durationMetrics2(event.durationMs),
28844
31031
  output
@@ -28869,7 +31056,7 @@ var FlueObserveBridge = class {
28869
31056
  };
28870
31057
  const parent = this.parentSpanForTurn(event);
28871
31058
  const span = startFlueSpan(parent, {
28872
- name: `llm:${model ?? event.purpose ?? "unknown"}`,
31059
+ name: "flue.turn",
28873
31060
  spanAttributes: { type: "llm" /* LLM */ },
28874
31061
  startTime: eventTime(event.timestamp),
28875
31062
  event: {
@@ -28913,6 +31100,12 @@ var FlueObserveBridge = class {
28913
31100
  },
28914
31101
  output
28915
31102
  });
31103
+ if (event.purpose === "agent" && event.operationId) {
31104
+ const operation = this.operationsById.get(event.operationId);
31105
+ if (operation) {
31106
+ operation.latestAgentOutput = output;
31107
+ }
31108
+ }
28916
31109
  safeEnd(state.span, eventTime(event.timestamp));
28917
31110
  this.turnsByKey.delete(key);
28918
31111
  }
@@ -28992,7 +31185,7 @@ var FlueObserveBridge = class {
28992
31185
  return;
28993
31186
  }
28994
31187
  safeLog3(state.span, {
28995
- ...event.isError ? { error: toLoggedError(event.result) } : {},
31188
+ ...event.isError ? { error: toLoggedError(event.errorInfo ?? event.result) } : {},
28996
31189
  metadata: {
28997
31190
  ...state.metadata,
28998
31191
  ...extractEventMetadata(event),
@@ -29038,6 +31231,7 @@ var FlueObserveBridge = class {
29038
31231
  ...event.usage ? { "flue.usage": event.usage } : {}
29039
31232
  };
29040
31233
  safeLog3(state.span, {
31234
+ ...event.isError ? { error: toLoggedError(event.errorInfo ?? event.error) } : {},
29041
31235
  metadata,
29042
31236
  metrics: {
29043
31237
  ...durationMetrics2(event.durationMs),
@@ -29142,7 +31336,7 @@ var FlueObserveBridge = class {
29142
31336
  ...event.purpose ? { "flue.turn_purpose": event.purpose } : {}
29143
31337
  };
29144
31338
  const span = startFlueSpan(this.parentSpanForEvent(event), {
29145
- name: `llm:${model ?? event.purpose ?? "unknown"}`,
31339
+ name: "flue.turn",
29146
31340
  spanAttributes: { type: "llm" /* LLM */ },
29147
31341
  startTime: eventTime(event.timestamp),
29148
31342
  event: { metadata }
@@ -29274,7 +31468,10 @@ function extractEventMetadata(event, ctx) {
29274
31468
  return {
29275
31469
  ...event.runId ? { "flue.run_id": event.runId } : {},
29276
31470
  ...event.instanceId ? { "flue.instance_id": event.instanceId } : {},
31471
+ ...event.submissionId ? { "flue.submission_id": event.submissionId } : {},
29277
31472
  ...event.dispatchId ? { "flue.dispatch_id": event.dispatchId } : {},
31473
+ ...event.agentName ? { "flue.agent_name": event.agentName } : {},
31474
+ ...event.conversationId ? { "flue.conversation_id": event.conversationId } : {},
29278
31475
  ...typeof event.eventIndex === "number" ? { "flue.event_index": event.eventIndex } : {},
29279
31476
  ...event.session ? { "flue.session": event.session } : {},
29280
31477
  ...event.parentSession ? { "flue.parent_session": event.parentSession } : {},
@@ -29303,7 +31500,7 @@ function flueTurnRequestInput(event) {
29303
31500
  return event.request?.input ?? event.input;
29304
31501
  }
29305
31502
  function flueTurnRequestModel(event) {
29306
- return event.request?.model ?? event.model;
31503
+ return event.request?.requestedModel ?? event.request?.model ?? event.model;
29307
31504
  }
29308
31505
  function flueTurnRequestProvider(event) {
29309
31506
  return event.request?.providerName ?? event.provider ?? event.request?.providerId;
@@ -29312,10 +31509,10 @@ function flueTurnRequestApi(event) {
29312
31509
  return event.request?.api ?? event.api;
29313
31510
  }
29314
31511
  function flueTurnRequestReasoning(event) {
29315
- return event.request?.reasoning ?? event.reasoning;
31512
+ return event.request?.reasoningLevel ?? event.request?.reasoning ?? event.reasoning;
29316
31513
  }
29317
31514
  function flueTurnModel(event) {
29318
- return event.request?.model ?? event.model;
31515
+ return event.response?.responseModel ?? event.request?.requestedModel ?? event.request?.model ?? event.model;
29319
31516
  }
29320
31517
  function flueTurnProvider(event) {
29321
31518
  return event.request?.providerName ?? event.provider ?? event.request?.providerId;
@@ -29330,7 +31527,7 @@ function flueTurnOutput(event) {
29330
31527
  return event.response?.output ?? event.output;
29331
31528
  }
29332
31529
  function flueTurnStopReason(event) {
29333
- return event.response?.stopReason ?? event.stopReason;
31530
+ return event.response?.finishReason ?? event.response?.stopReason ?? event.stopReason;
29334
31531
  }
29335
31532
  function flueTurnError(event) {
29336
31533
  return event.response?.error ?? event.response?.errorInfo?.message ?? event.error;
@@ -29345,6 +31542,9 @@ function flueToolInput(event) {
29345
31542
  return event.input;
29346
31543
  }
29347
31544
  function flueToolOutput(event) {
31545
+ if (Object.hasOwn(event, "effectiveResult")) {
31546
+ return event.effectiveResult;
31547
+ }
29348
31548
  return event.output !== void 0 ? event.output : event.result;
29349
31549
  }
29350
31550
  function flueToolError(event) {
@@ -29352,10 +31552,36 @@ function flueToolError(event) {
29352
31552
  }
29353
31553
  function operationOutput(event) {
29354
31554
  if (event.operationKind === "prompt" || event.operationKind === "skill") {
29355
- return llmResultFromOperationResult(event.result);
31555
+ return outputFromAgentInvocation(event.agentOutput) ?? llmResultFromOperationResult(event.result);
29356
31556
  }
29357
31557
  return event.result ?? (event.operationKind === "compact" ? { completed: true } : void 0);
29358
31558
  }
31559
+ function outputFromAgentInvocation(output) {
31560
+ if (output?.type === "text") {
31561
+ return output.text;
31562
+ }
31563
+ if (output?.type === "data") {
31564
+ return output.data;
31565
+ }
31566
+ return void 0;
31567
+ }
31568
+ function outputFromAgentTurn(output) {
31569
+ if (!isObjectLike(output)) {
31570
+ return output;
31571
+ }
31572
+ const content = Reflect.get(output, "content");
31573
+ if (!Array.isArray(content)) {
31574
+ return output;
31575
+ }
31576
+ const text = content.flatMap((part) => {
31577
+ if (!isObjectLike(part) || Reflect.get(part, "type") !== "text") {
31578
+ return [];
31579
+ }
31580
+ const value = Reflect.get(part, "text");
31581
+ return typeof value === "string" ? [value] : [];
31582
+ });
31583
+ return text.length > 0 ? text.join("") : output;
31584
+ }
29359
31585
  function llmResultFromOperationResult(result) {
29360
31586
  if (!isObjectLike(result)) {
29361
31587
  return result;
@@ -29454,7 +31680,7 @@ function safeEnd(span, endTime) {
29454
31680
  }
29455
31681
  }
29456
31682
  function logInstrumentationError3(label, error) {
29457
- console.error(`Error in ${label} instrumentation:`, error);
31683
+ debugLogger.debug(`Error in ${label} instrumentation:`, error);
29458
31684
  }
29459
31685
 
29460
31686
  // src/wrappers/langchain/callback-handler.ts
@@ -29851,7 +32077,7 @@ var LangChainPlugin = class extends BasePlugin {
29851
32077
  this.injectedManagers = /* @__PURE__ */ new WeakSet();
29852
32078
  }
29853
32079
  subscribeToConfigure(channel2) {
29854
- const tracingChannel2 = channel2.tracingChannel();
32080
+ const tracingChannel = channel2.tracingChannel();
29855
32081
  const handlers = {
29856
32082
  start: (event) => {
29857
32083
  injectHandlerIntoArguments(event.arguments);
@@ -29860,9 +32086,9 @@ var LangChainPlugin = class extends BasePlugin {
29860
32086
  this.injectHandler(event.result);
29861
32087
  }
29862
32088
  };
29863
- tracingChannel2.subscribe(handlers);
32089
+ tracingChannel.subscribe(handlers);
29864
32090
  this.unsubscribers.push(() => {
29865
- tracingChannel2.unsubscribe(handlers);
32091
+ tracingChannel.unsubscribe(handlers);
29866
32092
  });
29867
32093
  }
29868
32094
  injectHandler(result) {
@@ -30126,7 +32352,7 @@ var LangSmithPlugin = class extends BasePlugin {
30126
32352
  const inputs = preferOwnValue(run, previous, "inputs");
30127
32353
  const outputs = preferOwnValue(run, previous, "outputs");
30128
32354
  const error = errorMessage(preferOwnValue(run, previous, "error"));
30129
- const metadata = extractMetadata(run, previous);
32355
+ const metadata = extractMetadata2(run, previous);
30130
32356
  const tags = extractTags(preferOwnValue(run, previous, "tags"));
30131
32357
  const metrics = extractMetrics(run, previous);
30132
32358
  span.log({
@@ -30231,7 +32457,7 @@ function mapRunType(runType) {
30231
32457
  return "task" /* TASK */;
30232
32458
  }
30233
32459
  }
30234
- function extractMetadata(run, previous) {
32460
+ function extractMetadata2(run, previous) {
30235
32461
  const extra = preferOwnValue(run, previous, "extra");
30236
32462
  const rawMetadata = ownValue(extra, "metadata");
30237
32463
  if (!isRecord2(rawMetadata)) {
@@ -30383,12 +32609,13 @@ var piCodingAgentChannels = defineChannels(
30383
32609
  );
30384
32610
 
30385
32611
  // src/instrumentation/plugins/pi-coding-agent-plugin.ts
30386
- var piStreamPatchStates = /* @__PURE__ */ new WeakMap();
32612
+ var piAgentPatchStates = /* @__PURE__ */ new WeakMap();
32613
+ var piAgentEventSubscriptions = /* @__PURE__ */ new WeakSet();
30387
32614
  var piPromptContextStore;
30388
32615
  var PiCodingAgentPlugin = class extends BasePlugin {
30389
32616
  activePromptStates = /* @__PURE__ */ new Set();
30390
32617
  onEnable() {
30391
- this.subscribeToPrompt();
32618
+ this.interceptPrompt();
30392
32619
  }
30393
32620
  onDisable() {
30394
32621
  for (const unsubscribe of this.unsubscribers) {
@@ -30396,65 +32623,74 @@ var PiCodingAgentPlugin = class extends BasePlugin {
30396
32623
  }
30397
32624
  this.unsubscribers = [];
30398
32625
  for (const state of [...this.activePromptStates]) {
30399
- void finalizePiPromptRun(state).catch((error) => {
30400
- logInstrumentationError4("Pi Coding Agent disable cleanup", error);
30401
- });
32626
+ finishPiPromptRun(state);
30402
32627
  }
30403
32628
  }
30404
- subscribeToPrompt() {
30405
- const channel2 = piCodingAgentChannels.prompt.tracingChannel();
30406
- const states = /* @__PURE__ */ new WeakMap();
30407
- const unbindAutoInstrumentationSuppression = bindAutoInstrumentationSuppressionToStart(channel2);
30408
- const handlers = {
30409
- start: (event) => {
30410
- const state = startPiPromptRun(event, (state2) => {
30411
- this.activePromptStates.delete(state2);
30412
- });
30413
- if (state) {
30414
- this.activePromptStates.add(state);
30415
- states.set(event, state);
30416
- }
30417
- },
30418
- asyncEnd: async (event) => {
30419
- const state = states.get(event);
30420
- if (!state) {
30421
- return;
30422
- }
30423
- states.delete(event);
30424
- state.promptCallEnded = true;
30425
- if (!state.finalized && state.deferCompletionUntilTurnEnd && !state.turnEnded) {
30426
- if (!state.sawStreamFn) {
30427
- state.queued = true;
30428
- if (!state.streamPatchState.queuedPromptStates.includes(state)) {
30429
- state.streamPatchState.queuedPromptStates.push(state);
30430
- }
32629
+ interceptPrompt() {
32630
+ this.unsubscribers.push(
32631
+ piCodingAgentChannels.prompt.intercept(
32632
+ (target, thisArg, args, additional) => {
32633
+ const invokeTarget = () => Reflect.apply(target, thisArg, args);
32634
+ let state;
32635
+ try {
32636
+ state = startPiPromptRun(
32637
+ {
32638
+ ...additional,
32639
+ arguments: args,
32640
+ self: thisArg
32641
+ },
32642
+ (finalizedState) => {
32643
+ this.activePromptStates.delete(finalizedState);
32644
+ }
32645
+ );
32646
+ } catch (error) {
32647
+ logInstrumentationError4("Pi Coding Agent prompt start", error);
30431
32648
  }
30432
- return;
30433
- }
30434
- await finalizePiPromptRun(state);
30435
- },
30436
- error: async (event) => {
30437
- const state = states.get(event);
30438
- if (!state) {
30439
- return;
32649
+ if (!state) {
32650
+ return runWithAutoInstrumentationSuppressed(invokeTarget);
32651
+ }
32652
+ this.activePromptStates.add(state);
32653
+ return promptContextStore().run(
32654
+ state,
32655
+ () => runWithAutoInstrumentationSuppressed(() => {
32656
+ let result;
32657
+ try {
32658
+ result = invokeTarget();
32659
+ } catch (error) {
32660
+ finishPiPromptRun(state, error);
32661
+ throw error;
32662
+ }
32663
+ return Promise.resolve(result).then(
32664
+ (value) => {
32665
+ finishPiPromptCall(state);
32666
+ return value;
32667
+ },
32668
+ (error) => {
32669
+ finishPiPromptRun(state, error);
32670
+ throw error;
32671
+ }
32672
+ );
32673
+ })
32674
+ );
30440
32675
  }
30441
- states.delete(event);
30442
- await finalizePiPromptRun(state, event.error);
30443
- }
30444
- };
30445
- channel2.subscribe(handlers);
30446
- this.unsubscribers.push(() => {
30447
- unbindAutoInstrumentationSuppression?.();
30448
- channel2.unsubscribe(handlers);
30449
- });
32676
+ )
32677
+ );
30450
32678
  }
30451
32679
  };
32680
+ function finishPiPromptCall(state) {
32681
+ state.promptCallEnded = true;
32682
+ if (state.deferCompletionUntilTurnEnd && !state.turnEnded) {
32683
+ return;
32684
+ }
32685
+ finishPiPromptRun(state);
32686
+ }
30452
32687
  function startPiPromptRun(event, onFinalize) {
30453
32688
  const session = extractSession(event);
30454
32689
  const agent = session?.agent;
30455
32690
  if (!session || !isPiAgent(agent)) {
30456
32691
  return void 0;
30457
32692
  }
32693
+ installPiAgentInstrumentation(agent);
30458
32694
  const metadata = {
30459
32695
  ...extractSessionMetadata(session),
30460
32696
  ...extractPromptOptionsMetadata(event.arguments[1]),
@@ -30476,9 +32712,7 @@ function startPiPromptRun(event, onFinalize) {
30476
32712
  INSTRUMENTATION_NAMES.PI_CODING_AGENT
30477
32713
  )
30478
32714
  );
30479
- const streamPatchState = installPiStreamPatch(agent);
30480
32715
  const options = event.arguments[1];
30481
- const promptText = event.arguments[0];
30482
32716
  const state = {
30483
32717
  activeLlmSpans: /* @__PURE__ */ new Set(),
30484
32718
  activeToolSpans: /* @__PURE__ */ new Map(),
@@ -30490,29 +32724,10 @@ function startPiPromptRun(event, onFinalize) {
30490
32724
  metrics: {},
30491
32725
  onFinalize,
30492
32726
  promptCallEnded: false,
30493
- ...typeof promptText === "string" ? { promptText } : {},
30494
- queued: false,
30495
32727
  span,
30496
- sawStreamFn: false,
30497
32728
  startTime: getCurrentUnixTimestamp(),
30498
- streamPatchState,
30499
32729
  turnEnded: false
30500
32730
  };
30501
- state.restorePromptContext = enterPiPromptContext(state);
30502
- streamPatchState.activePromptStates.add(state);
30503
- try {
30504
- state.unsubscribeAgent = agent.subscribe(async (agentEvent) => {
30505
- try {
30506
- await runWithAutoInstrumentationSuppressed(
30507
- () => handlePiAgentEvent(state, agentEvent)
30508
- );
30509
- } catch (error) {
30510
- logInstrumentationError4("Pi Coding Agent event", error);
30511
- }
30512
- });
30513
- } catch (error) {
30514
- logInstrumentationError4("Pi Coding Agent event subscription", error);
30515
- }
30516
32731
  return state;
30517
32732
  }
30518
32733
  function extractSession(event) {
@@ -30526,111 +32741,55 @@ function promptContextStore() {
30526
32741
  piPromptContextStore ??= isomorph_default.newAsyncLocalStorage();
30527
32742
  return piPromptContextStore;
30528
32743
  }
30529
- function currentPromptContextFrames() {
30530
- return promptContextStore().getStore()?.frames ?? [];
30531
- }
30532
32744
  function currentPiPromptState() {
30533
- const frames = currentPromptContextFrames();
30534
- return frames[frames.length - 1]?.state;
30535
- }
30536
- function enterPiPromptContext(state) {
30537
- const frame = {
30538
- id: /* @__PURE__ */ Symbol("braintrust.pi-coding-agent.prompt"),
30539
- state
30540
- };
30541
- promptContextStore().enterWith({
30542
- frames: [...currentPromptContextFrames(), frame]
30543
- });
30544
- return () => {
30545
- const frames = currentPromptContextFrames().filter(
30546
- (candidate) => candidate.id !== frame.id
30547
- );
30548
- promptContextStore().enterWith(frames.length > 0 ? { frames } : void 0);
30549
- };
30550
- }
30551
- function installPiStreamPatch(agent) {
30552
- const existing = piStreamPatchStates.get(agent);
30553
- if (existing) {
30554
- if (agent.streamFn !== existing.wrappedStreamFn) {
30555
- debugLogger.debug(
30556
- "Pi Coding Agent streamFn changed while Braintrust instrumentation was active; preserving existing patch state."
30557
- );
30558
- }
30559
- return existing;
30560
- }
30561
- const patchState = {
30562
- activePromptStates: /* @__PURE__ */ new Set(),
30563
- agent,
30564
- originalStreamFn: agent.streamFn,
30565
- queuedPromptStates: [],
30566
- wrappedStreamFn: agent.streamFn
30567
- };
30568
- patchState.wrappedStreamFn = makeSharedInstrumentedStreamFn(patchState);
30569
- agent.streamFn = patchState.wrappedStreamFn;
30570
- piStreamPatchStates.set(agent, patchState);
30571
- return patchState;
30572
- }
30573
- function resolveStreamPromptState(patchState, context) {
30574
- let lastUserText;
30575
- if (Array.isArray(context.messages)) {
30576
- for (let i = context.messages.length - 1; i >= 0; i--) {
30577
- const message = context.messages[i];
30578
- if (isPiUserMessage(message)) {
30579
- if (typeof message.content === "string") {
30580
- lastUserText = message.content;
30581
- } else {
30582
- lastUserText = message.content.flatMap((part) => part.type === "text" ? [part.text] : []).join("");
30583
- }
30584
- break;
30585
- }
30586
- }
30587
- }
30588
- if (lastUserText !== void 0) {
30589
- const queuedMatch = patchState.queuedPromptStates.find(
30590
- (state) => state.promptText === lastUserText
30591
- );
30592
- if (queuedMatch) {
30593
- return queuedMatch;
30594
- }
30595
- const matches = [...patchState.activePromptStates].filter(
30596
- (state) => state.promptText === lastUserText
32745
+ return promptContextStore().getStore();
32746
+ }
32747
+ function installPiAgentInstrumentation(agent) {
32748
+ const existing = piAgentPatchStates.get(agent);
32749
+ if (!existing || agent.streamFn !== existing.wrappedStreamFn) {
32750
+ const patchState = {
32751
+ originalStreamFn: agent.streamFn,
32752
+ wrappedStreamFn: agent.streamFn
32753
+ };
32754
+ patchState.wrappedStreamFn = makeInstrumentedStreamFn(
32755
+ agent,
32756
+ patchState.originalStreamFn
30597
32757
  );
30598
- if (matches.length === 1) {
30599
- return matches[0];
30600
- }
32758
+ agent.streamFn = patchState.wrappedStreamFn;
32759
+ piAgentPatchStates.set(agent, patchState);
30601
32760
  }
30602
- const contextState = currentPiPromptState();
30603
- if (contextState && patchState.activePromptStates.has(contextState) && (!contextState.queued || lastUserText !== void 0 && contextState.promptText === lastUserText)) {
30604
- return contextState;
32761
+ if (piAgentEventSubscriptions.has(agent)) {
32762
+ return;
30605
32763
  }
30606
- if (patchState.activePromptStates.size === 1) {
30607
- return [...patchState.activePromptStates][0];
32764
+ try {
32765
+ agent.subscribe(async (event) => {
32766
+ const state = currentPiPromptState();
32767
+ if (!state || state.agent !== agent || state.finalized) {
32768
+ return;
32769
+ }
32770
+ try {
32771
+ await runWithAutoInstrumentationSuppressed(
32772
+ () => handlePiAgentEvent(state, event)
32773
+ );
32774
+ } catch (error) {
32775
+ logInstrumentationError4("Pi Coding Agent event", error);
32776
+ }
32777
+ });
32778
+ piAgentEventSubscriptions.add(agent);
32779
+ } catch (error) {
32780
+ logInstrumentationError4("Pi Coding Agent event subscription", error);
30608
32781
  }
30609
- return void 0;
30610
32782
  }
30611
- function makeSharedInstrumentedStreamFn(patchState) {
32783
+ function makeInstrumentedStreamFn(agent, originalStreamFn) {
30612
32784
  return async function instrumentedPiStreamFn(model, context, options) {
30613
- const state = resolveStreamPromptState(patchState, context);
30614
- if (!state) {
30615
- const invokeOriginal = () => Reflect.apply(patchState.originalStreamFn, this, [
30616
- model,
30617
- context,
30618
- options
30619
- ]);
30620
- return patchState.activePromptStates.size > 0 ? runWithAutoInstrumentationSuppressed(invokeOriginal) : invokeOriginal();
32785
+ const invokeOriginal = () => Reflect.apply(originalStreamFn, this, [model, context, options]);
32786
+ const state = currentPiPromptState();
32787
+ if (!state || state.agent !== agent || state.finalized) {
32788
+ return invokeOriginal();
30621
32789
  }
30622
- state.sawStreamFn = true;
30623
- removeQueuedPromptState(state);
30624
- state.streamPatchState.eventPromptState = state;
30625
32790
  const llmState = await startPiLlmSpan(state, model, context, options);
30626
32791
  try {
30627
- const stream = await runWithAutoInstrumentationSuppressed(
30628
- () => Reflect.apply(patchState.originalStreamFn, this, [
30629
- model,
30630
- context,
30631
- options
30632
- ])
30633
- );
32792
+ const stream = await runWithAutoInstrumentationSuppressed(invokeOriginal);
30634
32793
  return patchAssistantMessageStream(stream, state, llmState);
30635
32794
  } catch (error) {
30636
32795
  finishPiLlmSpan(state, llmState, void 0, error);
@@ -30777,13 +32936,6 @@ async function handlePiAgentEvent(state, event) {
30777
32936
  if (state.finalized) {
30778
32937
  return;
30779
32938
  }
30780
- const eventPromptState = state.streamPatchState.eventPromptState;
30781
- if (eventPromptState && eventPromptState !== state) {
30782
- return;
30783
- }
30784
- if (!eventPromptState && (state.queued || state.streamPatchState.activePromptStates.size > 1 && currentPiPromptState() !== state)) {
30785
- return;
30786
- }
30787
32939
  switch (event.type) {
30788
32940
  case "message_end":
30789
32941
  if (isPiAssistantMessage(event.message)) {
@@ -30798,11 +32950,8 @@ async function handlePiAgentEvent(state, event) {
30798
32950
  addMetrics(state.metrics, extractUsageMetrics2(event.message.usage));
30799
32951
  }
30800
32952
  }
30801
- if (state.streamPatchState.eventPromptState === state) {
30802
- state.streamPatchState.eventPromptState = void 0;
30803
- }
30804
32953
  if (state.promptCallEnded && state.deferCompletionUntilTurnEnd) {
30805
- await finalizePiPromptRun(state);
32954
+ finishPiPromptRun(state);
30806
32955
  }
30807
32956
  return;
30808
32957
  case "tool_execution_start":
@@ -30875,19 +33024,13 @@ function finishPiToolSpan(state, event) {
30875
33024
  }
30876
33025
  }
30877
33026
  }
30878
- async function finalizePiPromptRun(state, error) {
33027
+ function finishPiPromptRun(state, error) {
30879
33028
  if (state.finalized) {
30880
33029
  return;
30881
33030
  }
30882
33031
  state.finalized = true;
30883
33032
  state.onFinalize?.(state);
30884
- restorePiStreamFn(state);
30885
- try {
30886
- state.unsubscribeAgent?.();
30887
- } catch (unsubscribeError) {
30888
- logInstrumentationError4("Pi Coding Agent unsubscribe", unsubscribeError);
30889
- }
30890
- await finishOpenLlmSpans(state, error);
33033
+ finishOpenLlmSpans(state, error);
30891
33034
  finishOpenToolSpans(state, error);
30892
33035
  const metadata = {
30893
33036
  ...state.metadata,
@@ -30904,34 +33047,14 @@ async function finalizePiPromptRun(state, error) {
30904
33047
  output: state.output
30905
33048
  });
30906
33049
  } finally {
30907
- state.span.end();
30908
- }
30909
- }
30910
- function restorePiStreamFn(state) {
30911
- const patchState = state.streamPatchState;
30912
- patchState.activePromptStates.delete(state);
30913
- removeQueuedPromptState(state);
30914
- if (patchState.eventPromptState === state) {
30915
- patchState.eventPromptState = void 0;
30916
- }
30917
- state.restorePromptContext?.();
30918
- if (patchState.activePromptStates.size > 0) {
30919
- return;
30920
- }
30921
- if (patchState.agent.streamFn === patchState.wrappedStreamFn) {
30922
- patchState.agent.streamFn = patchState.originalStreamFn;
30923
- }
30924
- piStreamPatchStates.delete(patchState.agent);
30925
- }
30926
- function removeQueuedPromptState(state) {
30927
- state.queued = false;
30928
- const queuedPromptStates = state.streamPatchState.queuedPromptStates;
30929
- const index = queuedPromptStates.indexOf(state);
30930
- if (index >= 0) {
30931
- queuedPromptStates.splice(index, 1);
33050
+ try {
33051
+ state.span.end();
33052
+ } catch (endError) {
33053
+ logInstrumentationError4("Pi Coding Agent prompt end", endError);
33054
+ }
30932
33055
  }
30933
33056
  }
30934
- async function finishOpenLlmSpans(state, error) {
33057
+ function finishOpenLlmSpans(state, error) {
30935
33058
  for (const llmState of [...state.activeLlmSpans]) {
30936
33059
  finishPiLlmSpan(state, llmState, void 0, error);
30937
33060
  }
@@ -31012,7 +33135,7 @@ function normalizeAssistantMessage(message) {
31012
33135
  (part) => part.type === "thinking" && !part.redacted ? [part.thinking] : []
31013
33136
  ).join("");
31014
33137
  const toolCalls = message.content.flatMap(
31015
- (part) => part.type === "toolCall" ? [normalizeToolCall(part)] : []
33138
+ (part) => part.type === "toolCall" ? [normalizeToolCall2(part)] : []
31016
33139
  );
31017
33140
  return {
31018
33141
  role: "assistant",
@@ -31047,13 +33170,13 @@ function normalizeUserContent(content) {
31047
33170
  return part;
31048
33171
  });
31049
33172
  }
31050
- function normalizeToolCall(toolCall) {
33173
+ function normalizeToolCall2(toolCall) {
31051
33174
  return {
31052
33175
  id: toolCall.id,
31053
33176
  type: "function",
31054
33177
  function: {
31055
33178
  name: toolCall.name,
31056
- arguments: stringifyArguments(toolCall.arguments)
33179
+ arguments: stringifyArguments2(toolCall.arguments)
31057
33180
  }
31058
33181
  };
31059
33182
  }
@@ -31236,7 +33359,7 @@ function cleanMetrics5(metrics) {
31236
33359
  }
31237
33360
  return cleaned;
31238
33361
  }
31239
- function stringifyArguments(value) {
33362
+ function stringifyArguments2(value) {
31240
33363
  if (typeof value === "string") {
31241
33364
  return value;
31242
33365
  }
@@ -31362,9 +33485,9 @@ var StrandsAgentSDKPlugin = class extends BasePlugin {
31362
33485
  });
31363
33486
  }
31364
33487
  subscribeToMultiAgentStream(channel2, operation) {
31365
- const tracingChannel2 = channel2.tracingChannel();
33488
+ const tracingChannel = channel2.tracingChannel();
31366
33489
  const states = /* @__PURE__ */ new WeakMap();
31367
- const unbindAutoInstrumentationSuppression = bindAutoInstrumentationSuppressionToStart(tracingChannel2);
33490
+ const unbindAutoInstrumentationSuppression = bindAutoInstrumentationSuppressionToStart(tracingChannel);
31368
33491
  const handlers = {
31369
33492
  start: (event) => {
31370
33493
  const state = startMultiAgentStream(
@@ -31418,10 +33541,10 @@ var StrandsAgentSDKPlugin = class extends BasePlugin {
31418
33541
  states.delete(event);
31419
33542
  }
31420
33543
  };
31421
- tracingChannel2.subscribe(handlers);
33544
+ tracingChannel.subscribe(handlers);
31422
33545
  this.unsubscribers.push(() => {
31423
33546
  unbindAutoInstrumentationSuppression?.();
31424
- tracingChannel2.unsubscribe(handlers);
33547
+ tracingChannel.unsubscribe(handlers);
31425
33548
  });
31426
33549
  }
31427
33550
  };
@@ -31604,6 +33727,15 @@ function handleMultiAgentStreamEvent(state, event, activeChildParents) {
31604
33727
  logInstrumentationError5("Strands Agent SDK multi-agent event", error);
31605
33728
  }
31606
33729
  }
33730
+ function buildModelSpanInput(event, attachmentCache) {
33731
+ const systemPrompt = typeof event.agent?.systemPrompt === "string" && event.agent.systemPrompt.length > 0 ? event.agent.systemPrompt : void 0;
33732
+ const processedMessages = Array.isArray(event.agent?.messages) ? processStrandsInputAttachments(event.agent.messages, attachmentCache) : void 0;
33733
+ if (!systemPrompt) {
33734
+ return processedMessages;
33735
+ }
33736
+ const systemMessage = { role: "system", content: systemPrompt };
33737
+ return Array.isArray(processedMessages) ? [systemMessage, ...processedMessages] : [systemMessage];
33738
+ }
31607
33739
  function startModelSpan(state, event) {
31608
33740
  if (state.activeModel) {
31609
33741
  finalizeModelSpan(state);
@@ -31621,10 +33753,7 @@ function startModelSpan(state, event) {
31621
33753
  withSpanInstrumentationName(
31622
33754
  {
31623
33755
  event: {
31624
- input: Array.isArray(event.agent?.messages) ? processStrandsInputAttachments(
31625
- event.agent.messages,
31626
- state.attachmentCache
31627
- ) : void 0,
33756
+ input: buildModelSpanInput(event, state.attachmentCache),
31628
33757
  metadata
31629
33758
  },
31630
33759
  name: formatModelSpanName(model),
@@ -32264,6 +34393,532 @@ function logInstrumentationError5(context, error) {
32264
34393
  debugLogger.debug(`${context}:`, error);
32265
34394
  }
32266
34395
 
34396
+ // src/instrumentation/plugins/cloudflare-ai-chat-channels.ts
34397
+ var cloudflareAIChatChannels = defineChannels(
34398
+ "@cloudflare/ai-chat",
34399
+ {
34400
+ runExclusiveChatTurn: channel({
34401
+ channelName: "AIChatAgent._runExclusiveChatTurn",
34402
+ kind: "async"
34403
+ }),
34404
+ onChatResponse: channel({
34405
+ channelName: "AIChatAgent.onChatResponse",
34406
+ kind: "sync-stream"
34407
+ })
34408
+ },
34409
+ { instrumentationName: INSTRUMENTATION_NAMES.CLOUDFLARE_AI_CHAT }
34410
+ );
34411
+
34412
+ // src/instrumentation/plugins/cloudflare-ai-chat-instrumentation.ts
34413
+ var wrappedResponseHooks = /* @__PURE__ */ new WeakSet();
34414
+ function instrumentCloudflareAIChatResponseHook(agent) {
34415
+ try {
34416
+ const original = Reflect.get(agent, "onChatResponse");
34417
+ if (typeof original !== "function" || wrappedResponseHooks.has(original)) {
34418
+ return;
34419
+ }
34420
+ const wrapped = function(result) {
34421
+ const args = [result];
34422
+ return cloudflareAIChatChannels.onChatResponse.traceSync(
34423
+ () => Reflect.apply(original, this, args),
34424
+ {
34425
+ arguments: args,
34426
+ self: this
34427
+ }
34428
+ );
34429
+ };
34430
+ wrappedResponseHooks.add(wrapped);
34431
+ defineWrappedMethod(agent, "onChatResponse", original, wrapped);
34432
+ } catch (error) {
34433
+ debugLogger.debug(
34434
+ "Failed to wrap @cloudflare/ai-chat response hook:",
34435
+ error
34436
+ );
34437
+ }
34438
+ }
34439
+ function defineWrappedMethod(target, property, original, wrapped) {
34440
+ const ownDescriptor = Object.getOwnPropertyDescriptor(target, property);
34441
+ Object.defineProperty(target, property, {
34442
+ configurable: ownDescriptor?.configurable ?? true,
34443
+ enumerable: ownDescriptor?.enumerable ?? false,
34444
+ value: wrapped,
34445
+ writable: ownDescriptor && "writable" in ownDescriptor ? ownDescriptor.writable : true
34446
+ });
34447
+ try {
34448
+ Object.defineProperty(wrapped, "name", {
34449
+ configurable: true,
34450
+ value: original.name
34451
+ });
34452
+ } catch {
34453
+ }
34454
+ }
34455
+
34456
+ // src/instrumentation/plugins/cloudflare-ai-chat-plugin.ts
34457
+ var BLOCKED_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
34458
+ var RESPONSE_STATE_RETENTION_MS = 6e4;
34459
+ var CloudflareAIChatPlugin = class extends BasePlugin {
34460
+ activeStates = /* @__PURE__ */ new Set();
34461
+ activeTurns = /* @__PURE__ */ new WeakMap();
34462
+ eventStates = /* @__PURE__ */ new WeakMap();
34463
+ onEnable() {
34464
+ this.subscribeToResponseHook();
34465
+ this.subscribeToTurnRunner();
34466
+ }
34467
+ onDisable() {
34468
+ for (const unsubscribe of this.unsubscribers) {
34469
+ unsubscribe();
34470
+ }
34471
+ this.unsubscribers = [];
34472
+ for (const state of this.activeStates) {
34473
+ this.cleanupState(state);
34474
+ }
34475
+ this.activeStates.clear();
34476
+ }
34477
+ subscribeToTurnRunner() {
34478
+ const tracingChannel = cloudflareAIChatChannels.runExclusiveChatTurn.tracingChannel();
34479
+ const unbindCurrentSpanStore = this.bindCurrentSpanStore(tracingChannel);
34480
+ const handlers = {
34481
+ start: (event) => {
34482
+ this.ensureEventState(event);
34483
+ },
34484
+ asyncEnd: (event) => {
34485
+ this.finishEvent(event);
34486
+ },
34487
+ error: (event) => {
34488
+ this.finishEvent(event, event.error);
34489
+ }
34490
+ };
34491
+ tracingChannel.subscribe(handlers);
34492
+ this.unsubscribers.push(() => {
34493
+ unbindCurrentSpanStore?.();
34494
+ tracingChannel.unsubscribe(handlers);
34495
+ });
34496
+ }
34497
+ subscribeToResponseHook() {
34498
+ const tracingChannel = cloudflareAIChatChannels.onChatResponse.tracingChannel();
34499
+ const handlers = {
34500
+ start: (event) => {
34501
+ let state;
34502
+ try {
34503
+ const agent = asObject(event.self);
34504
+ const result = event.arguments[0];
34505
+ state = agent ? this.findResponseState(
34506
+ agent,
34507
+ stringValue3(ownValue2(result, "requestId"))
34508
+ ) : void 0;
34509
+ if (!state) {
34510
+ return;
34511
+ }
34512
+ state.responseObserved = true;
34513
+ const output = serializeMessage(ownValue2(result, "message"));
34514
+ const status = stringValue3(ownValue2(result, "status"));
34515
+ const error = ownValue2(result, "error");
34516
+ const input = ownValue2(result, "continuation") === true ? state.input : serializeMessages(readProperty(agent, "messages"))?.filter(
34517
+ (message) => typeof output?.id !== "string" || message.id !== output.id
34518
+ );
34519
+ state.span.log({
34520
+ ...input !== void 0 ? { input } : {},
34521
+ ...output !== void 0 ? { output } : {},
34522
+ ...status === "error" && error !== void 0 ? { error } : {}
34523
+ });
34524
+ } catch (error) {
34525
+ debugLogger.debug(
34526
+ "Failed to process @cloudflare/ai-chat response hook:",
34527
+ error
34528
+ );
34529
+ } finally {
34530
+ if (state?.settled) {
34531
+ this.cleanupState(state);
34532
+ }
34533
+ }
34534
+ }
34535
+ };
34536
+ tracingChannel.subscribe(handlers);
34537
+ this.unsubscribers.push(() => tracingChannel.unsubscribe(handlers));
34538
+ }
34539
+ bindCurrentSpanStore(tracingChannel) {
34540
+ const globalState = _internalGetGlobalState();
34541
+ const contextManager = globalState?.contextManager;
34542
+ const startChannel = tracingChannel.start;
34543
+ const currentSpanStore = contextManager ? contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
34544
+ if (!startChannel || !currentSpanStore || !contextManager) {
34545
+ return void 0;
34546
+ }
34547
+ startChannel.bindStore(currentSpanStore, (event) => {
34548
+ const state = this.ensureEventState(event);
34549
+ return state ? contextManager.wrapSpanForStore(state.span) : currentSpanStore.getStore();
34550
+ });
34551
+ return () => startChannel.unbindStore(currentSpanStore);
34552
+ }
34553
+ ensureEventState(event) {
34554
+ const eventKey = event;
34555
+ const known = this.eventStates.get(eventKey);
34556
+ if (known) {
34557
+ return known;
34558
+ }
34559
+ try {
34560
+ const agent = asObject(event.self);
34561
+ const requestId = stringValue3(event.arguments[0]);
34562
+ const key = requestId ?? /* @__PURE__ */ Symbol("cloudflare-ai-chat-turn");
34563
+ const activeForAgent = agent ? this.getActiveTurns(agent) : void 0;
34564
+ const existing = activeForAgent?.get(key);
34565
+ const state = existing && !existing.settled ? existing : this.createTurnState(agent, key);
34566
+ if (existing && !existing.settled) {
34567
+ state.depth += 1;
34568
+ }
34569
+ this.eventStates.set(eventKey, state);
34570
+ this.bindTurnCallback(event, agent, state);
34571
+ if (agent) {
34572
+ instrumentCloudflareAIChatResponseHook(agent);
34573
+ }
34574
+ return state;
34575
+ } catch (error) {
34576
+ debugLogger.debug(
34577
+ "Failed to start @cloudflare/ai-chat instrumentation:",
34578
+ error
34579
+ );
34580
+ return void 0;
34581
+ }
34582
+ }
34583
+ createTurnState(agent, key) {
34584
+ const span = startSpan(
34585
+ withSpanInstrumentationName(
34586
+ {
34587
+ name: "AIChatAgent.onChatMessage",
34588
+ spanAttributes: { type: "task" /* TASK */ }
34589
+ },
34590
+ INSTRUMENTATION_NAMES.CLOUDFLARE_AI_CHAT
34591
+ )
34592
+ );
34593
+ const state = {
34594
+ agent,
34595
+ depth: 1,
34596
+ ended: false,
34597
+ key,
34598
+ responseObserved: false,
34599
+ settled: false,
34600
+ span
34601
+ };
34602
+ this.activeStates.add(state);
34603
+ if (agent) {
34604
+ this.getActiveTurns(agent).set(key, state);
34605
+ }
34606
+ return state;
34607
+ }
34608
+ bindTurnCallback(event, agent, state) {
34609
+ const callback = event.arguments[1];
34610
+ if (typeof callback !== "function") {
34611
+ return;
34612
+ }
34613
+ try {
34614
+ event.arguments[1] = function(...args) {
34615
+ return withCurrent(state.span, () => {
34616
+ try {
34617
+ const input = serializeMessages(readProperty(agent, "messages"));
34618
+ if (input !== void 0 && state.input === void 0) {
34619
+ state.input = input;
34620
+ state.span.log({ input });
34621
+ }
34622
+ } catch (error) {
34623
+ debugLogger.debug(
34624
+ "Failed to capture @cloudflare/ai-chat messages:",
34625
+ error
34626
+ );
34627
+ }
34628
+ return Reflect.apply(callback, this, args);
34629
+ });
34630
+ };
34631
+ } catch (error) {
34632
+ debugLogger.debug(
34633
+ "Failed to bind @cloudflare/ai-chat turn callback context:",
34634
+ error
34635
+ );
34636
+ }
34637
+ }
34638
+ finishEvent(event, error) {
34639
+ const eventKey = event;
34640
+ const state = this.eventStates.get(eventKey);
34641
+ if (!state || state.ended) {
34642
+ return;
34643
+ }
34644
+ this.eventStates.delete(eventKey);
34645
+ if (error !== void 0 && state.pendingError === void 0) {
34646
+ state.pendingError = error;
34647
+ }
34648
+ state.depth -= 1;
34649
+ if (state.depth === 0) {
34650
+ state.settled = true;
34651
+ this.endState(state);
34652
+ if (state.responseObserved || error !== void 0) {
34653
+ this.cleanupState(state);
34654
+ } else {
34655
+ state.cleanupTimer = setTimeout(
34656
+ () => this.cleanupState(state),
34657
+ RESPONSE_STATE_RETENTION_MS
34658
+ );
34659
+ if (typeof state.cleanupTimer === "object" && state.cleanupTimer !== null && "unref" in state.cleanupTimer && typeof state.cleanupTimer.unref === "function") {
34660
+ state.cleanupTimer.unref();
34661
+ }
34662
+ }
34663
+ }
34664
+ }
34665
+ endState(state) {
34666
+ if (state.ended) {
34667
+ return;
34668
+ }
34669
+ state.ended = true;
34670
+ try {
34671
+ if (state.pendingError !== void 0) {
34672
+ state.span.log({ error: state.pendingError });
34673
+ }
34674
+ } finally {
34675
+ state.span.end();
34676
+ }
34677
+ }
34678
+ cleanupState(state) {
34679
+ if (state.cleanupTimer !== void 0) {
34680
+ clearTimeout(state.cleanupTimer);
34681
+ state.cleanupTimer = void 0;
34682
+ }
34683
+ try {
34684
+ this.endState(state);
34685
+ } finally {
34686
+ this.activeStates.delete(state);
34687
+ if (state.agent) {
34688
+ const activeForAgent = this.activeTurns.get(state.agent);
34689
+ if (activeForAgent?.get(state.key) === state) {
34690
+ activeForAgent.delete(state.key);
34691
+ }
34692
+ }
34693
+ }
34694
+ }
34695
+ getActiveTurns(agent) {
34696
+ let turns = this.activeTurns.get(agent);
34697
+ if (!turns) {
34698
+ turns = /* @__PURE__ */ new Map();
34699
+ this.activeTurns.set(agent, turns);
34700
+ }
34701
+ return turns;
34702
+ }
34703
+ findResponseState(agent, requestId) {
34704
+ const turns = this.activeTurns.get(agent);
34705
+ if (!turns) {
34706
+ return void 0;
34707
+ }
34708
+ if (requestId !== void 0) {
34709
+ return turns.get(requestId);
34710
+ }
34711
+ const active = [...turns.values()];
34712
+ return active.length === 1 ? active[0] : void 0;
34713
+ }
34714
+ };
34715
+ function asObject(value) {
34716
+ return value !== null && (typeof value === "object" || typeof value === "function") ? value : void 0;
34717
+ }
34718
+ function readProperty(value, key) {
34719
+ const object = asObject(value);
34720
+ return object ? Reflect.get(object, key) : void 0;
34721
+ }
34722
+ function ownValue2(value, key) {
34723
+ const object = asObject(value);
34724
+ if (!object) {
34725
+ return void 0;
34726
+ }
34727
+ const descriptor = Object.getOwnPropertyDescriptor(object, key);
34728
+ return descriptor && "value" in descriptor ? descriptor.value : void 0;
34729
+ }
34730
+ function stringValue3(value) {
34731
+ return typeof value === "string" ? value : void 0;
34732
+ }
34733
+ function serializeMessages(value) {
34734
+ if (!Array.isArray(value)) {
34735
+ return void 0;
34736
+ }
34737
+ return value.flatMap((message) => {
34738
+ const serialized = serializeMessage(message);
34739
+ return serialized === void 0 ? [] : [serialized];
34740
+ });
34741
+ }
34742
+ function serializeMessage(value) {
34743
+ const message = asObject(value);
34744
+ if (!message) {
34745
+ return void 0;
34746
+ }
34747
+ const serialized = [];
34748
+ const id = ownValue2(message, "id");
34749
+ const role = ownValue2(message, "role");
34750
+ const parts = ownValue2(message, "parts");
34751
+ if (typeof id === "string") {
34752
+ serialized.push(["id", id]);
34753
+ }
34754
+ if (typeof role === "string") {
34755
+ serialized.push(["role", role]);
34756
+ }
34757
+ const sanitizedParts = sanitizeLoggedValue2(parts);
34758
+ if (sanitizedParts !== void 0) {
34759
+ serialized.push(["parts", sanitizedParts]);
34760
+ }
34761
+ return serialized.length > 0 ? Object.fromEntries(serialized) : void 0;
34762
+ }
34763
+ function sanitizeLoggedValue2(value, seen = /* @__PURE__ */ new WeakSet(), depth = 0) {
34764
+ if (value === null || typeof value === "string" || typeof value === "boolean") {
34765
+ return value;
34766
+ }
34767
+ if (typeof value === "number") {
34768
+ return Number.isFinite(value) ? value : void 0;
34769
+ }
34770
+ const object = asObject(value);
34771
+ if (!object || depth >= 20 || typeof value === "function") {
34772
+ return void 0;
34773
+ }
34774
+ if (seen.has(object)) {
34775
+ return "[Circular]";
34776
+ }
34777
+ seen.add(object);
34778
+ if (Array.isArray(value)) {
34779
+ return value.map((entry) => sanitizeLoggedValue2(entry, seen, depth + 1));
34780
+ }
34781
+ const entries = [];
34782
+ for (const [key, descriptor] of Object.entries(
34783
+ Object.getOwnPropertyDescriptors(object)
34784
+ )) {
34785
+ if (BLOCKED_KEYS.has(key) || !descriptor.enumerable || !("value" in descriptor)) {
34786
+ continue;
34787
+ }
34788
+ const sanitized = sanitizeLoggedValue2(descriptor.value, seen, depth + 1);
34789
+ if (sanitized !== void 0) {
34790
+ entries.push([key, sanitized]);
34791
+ }
34792
+ }
34793
+ return Object.fromEntries(entries);
34794
+ }
34795
+
34796
+ // src/instrumentation/plugins/cloudflare-agents-channels.ts
34797
+ var cloudflareAgentsChannels = defineChannels(
34798
+ "agents",
34799
+ {
34800
+ runAgentTool: channel({
34801
+ channelName: "Agent.runAgentTool",
34802
+ kind: "async"
34803
+ })
34804
+ },
34805
+ { instrumentationName: INSTRUMENTATION_NAMES.CLOUDFLARE_AGENTS }
34806
+ );
34807
+
34808
+ // src/instrumentation/plugins/cloudflare-agents-plugin.ts
34809
+ var CLOUDFLARE_WORKERS_CONTEXT = {
34810
+ span_origin: {
34811
+ environment: { type: "server", name: "cloudflare_workers" }
34812
+ }
34813
+ };
34814
+ var CloudflareAgentsPlugin = class extends BasePlugin {
34815
+ onEnable() {
34816
+ const channel2 = cloudflareAgentsChannels.runAgentTool.tracingChannel();
34817
+ const spans = /* @__PURE__ */ new WeakMap();
34818
+ const handlers = {
34819
+ start: (event) => {
34820
+ try {
34821
+ const agentClass = event.arguments[0];
34822
+ const options = event.arguments[1];
34823
+ if (ownValue3(options, "detached")) {
34824
+ return;
34825
+ }
34826
+ const name = ownValue3(agentClass, "name");
34827
+ if (typeof name !== "string" || name.length === 0) {
34828
+ debugLogger.warn(
34829
+ "Skipping Cloudflare Agents runAgentTool span because the child agent class has no name."
34830
+ );
34831
+ return;
34832
+ }
34833
+ const span = _internalStartSpanWithContext(
34834
+ withSpanInstrumentationName(
34835
+ {
34836
+ name,
34837
+ spanAttributes: { type: "tool" /* TOOL */ },
34838
+ event: {
34839
+ input: ownValue3(options, "input")
34840
+ }
34841
+ },
34842
+ INSTRUMENTATION_NAMES.CLOUDFLARE_AGENTS
34843
+ ),
34844
+ CLOUDFLARE_WORKERS_CONTEXT
34845
+ );
34846
+ spans.set(event, span);
34847
+ } catch (error) {
34848
+ logInstrumentationError6("start", error);
34849
+ }
34850
+ },
34851
+ asyncEnd: (event) => {
34852
+ const span = spans.get(event);
34853
+ if (!span) {
34854
+ return;
34855
+ }
34856
+ spans.delete(event);
34857
+ try {
34858
+ const status = ownValue3(event.result, "status");
34859
+ if (status === "completed") {
34860
+ span.log({ output: ownValue3(event.result, "output") });
34861
+ } else {
34862
+ const error = ownValue3(event.result, "error");
34863
+ if (typeof error === "string") {
34864
+ span.log({ error });
34865
+ }
34866
+ }
34867
+ } catch (error) {
34868
+ logInstrumentationError6("completion", error);
34869
+ } finally {
34870
+ safelyEndSpan(span);
34871
+ }
34872
+ },
34873
+ error: (event) => {
34874
+ const span = spans.get(event);
34875
+ if (!span) {
34876
+ return;
34877
+ }
34878
+ spans.delete(event);
34879
+ try {
34880
+ span.log({ error: event.error });
34881
+ } catch (error) {
34882
+ logInstrumentationError6("rejection", error);
34883
+ } finally {
34884
+ safelyEndSpan(span);
34885
+ }
34886
+ }
34887
+ };
34888
+ channel2.subscribe(handlers);
34889
+ this.unsubscribers.push(() => channel2.unsubscribe(handlers));
34890
+ }
34891
+ onDisable() {
34892
+ for (const unsubscribe of this.unsubscribers) {
34893
+ unsubscribe();
34894
+ }
34895
+ this.unsubscribers = [];
34896
+ }
34897
+ };
34898
+ function ownValue3(value, key) {
34899
+ if (!isObjectLike2(value)) {
34900
+ return void 0;
34901
+ }
34902
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
34903
+ return descriptor && "value" in descriptor ? descriptor.value : void 0;
34904
+ }
34905
+ function isObjectLike2(value) {
34906
+ return typeof value === "object" && value !== null || typeof value === "function";
34907
+ }
34908
+ function safelyEndSpan(span) {
34909
+ try {
34910
+ span.end();
34911
+ } catch (error) {
34912
+ logInstrumentationError6("span end", error);
34913
+ }
34914
+ }
34915
+ function logInstrumentationError6(operation, error) {
34916
+ debugLogger.error(
34917
+ `Failed to process Cloudflare Agents ${operation} instrumentation:`,
34918
+ error
34919
+ );
34920
+ }
34921
+
32267
34922
  // src/instrumentation/braintrust-plugin.ts
32268
34923
  var BraintrustPlugin = class extends BasePlugin {
32269
34924
  config;
@@ -32272,13 +34927,16 @@ var BraintrustPlugin = class extends BasePlugin {
32272
34927
  anthropicPlugin = null;
32273
34928
  aiSDKPlugin = null;
32274
34929
  claudeAgentSDKPlugin = null;
34930
+ cloudflareThinkPlugin = null;
32275
34931
  cursorSDKPlugin = null;
32276
34932
  openAIAgentsPlugin = null;
32277
34933
  googleGenAIPlugin = null;
32278
34934
  huggingFacePlugin = null;
34935
+ huggingFaceTransformersPlugin = null;
32279
34936
  openRouterPlugin = null;
32280
34937
  openRouterAgentPlugin = null;
32281
34938
  mistralPlugin = null;
34939
+ ollamaPlugin = null;
32282
34940
  googleADKPlugin = null;
32283
34941
  coherePlugin = null;
32284
34942
  groqPlugin = null;
@@ -32290,6 +34948,8 @@ var BraintrustPlugin = class extends BasePlugin {
32290
34948
  langSmithPlugin = null;
32291
34949
  piCodingAgentPlugin = null;
32292
34950
  strandsAgentSDKPlugin = null;
34951
+ cloudflareAIChatPlugin = null;
34952
+ cloudflareAgentsPlugin = null;
32293
34953
  constructor(config = {}) {
32294
34954
  super();
32295
34955
  this.config = config;
@@ -32316,6 +34976,10 @@ var BraintrustPlugin = class extends BasePlugin {
32316
34976
  this.claudeAgentSDKPlugin = new ClaudeAgentSDKPlugin();
32317
34977
  this.claudeAgentSDKPlugin.enable();
32318
34978
  }
34979
+ if (integrations.cloudflareThink !== false) {
34980
+ this.cloudflareThinkPlugin = new CloudflareThinkPlugin();
34981
+ this.cloudflareThinkPlugin.enable();
34982
+ }
32319
34983
  if (integrations.cursorSDK !== false && integrations.cursor !== false) {
32320
34984
  this.cursorSDKPlugin = new CursorSDKPlugin();
32321
34985
  this.cursorSDKPlugin.enable();
@@ -32331,6 +34995,8 @@ var BraintrustPlugin = class extends BasePlugin {
32331
34995
  if (integrations.huggingface !== false) {
32332
34996
  this.huggingFacePlugin = new HuggingFacePlugin();
32333
34997
  this.huggingFacePlugin.enable();
34998
+ this.huggingFaceTransformersPlugin = new HuggingFaceTransformersPlugin();
34999
+ this.huggingFaceTransformersPlugin.enable();
32334
35000
  }
32335
35001
  if (integrations.openrouter !== false) {
32336
35002
  this.openRouterPlugin = new OpenRouterPlugin();
@@ -32344,6 +35010,10 @@ var BraintrustPlugin = class extends BasePlugin {
32344
35010
  this.mistralPlugin = new MistralPlugin();
32345
35011
  this.mistralPlugin.enable();
32346
35012
  }
35013
+ if (integrations.ollama !== false) {
35014
+ this.ollamaPlugin = new OllamaPlugin();
35015
+ this.ollamaPlugin.enable();
35016
+ }
32347
35017
  if (integrations.googleADK !== false) {
32348
35018
  this.googleADKPlugin = new GoogleADKPlugin();
32349
35019
  this.googleADKPlugin.enable();
@@ -32376,6 +35046,14 @@ var BraintrustPlugin = class extends BasePlugin {
32376
35046
  this.strandsAgentSDKPlugin = new StrandsAgentSDKPlugin();
32377
35047
  this.strandsAgentSDKPlugin.enable();
32378
35048
  }
35049
+ if (integrations.cloudflareAIChat !== false) {
35050
+ this.cloudflareAIChatPlugin = new CloudflareAIChatPlugin();
35051
+ this.cloudflareAIChatPlugin.enable();
35052
+ }
35053
+ if (integrations.cloudflareAgents !== false) {
35054
+ this.cloudflareAgentsPlugin = new CloudflareAgentsPlugin();
35055
+ this.cloudflareAgentsPlugin.enable();
35056
+ }
32379
35057
  if (integrations.flue !== false) {
32380
35058
  this.fluePlugin = new FluePlugin();
32381
35059
  this.fluePlugin.enable();
@@ -32412,6 +35090,10 @@ var BraintrustPlugin = class extends BasePlugin {
32412
35090
  this.claudeAgentSDKPlugin.disable();
32413
35091
  this.claudeAgentSDKPlugin = null;
32414
35092
  }
35093
+ if (this.cloudflareThinkPlugin) {
35094
+ this.cloudflareThinkPlugin.disable();
35095
+ this.cloudflareThinkPlugin = null;
35096
+ }
32415
35097
  if (this.cursorSDKPlugin) {
32416
35098
  this.cursorSDKPlugin.disable();
32417
35099
  this.cursorSDKPlugin = null;
@@ -32428,6 +35110,10 @@ var BraintrustPlugin = class extends BasePlugin {
32428
35110
  this.huggingFacePlugin.disable();
32429
35111
  this.huggingFacePlugin = null;
32430
35112
  }
35113
+ if (this.huggingFaceTransformersPlugin) {
35114
+ this.huggingFaceTransformersPlugin.disable();
35115
+ this.huggingFaceTransformersPlugin = null;
35116
+ }
32431
35117
  if (this.openRouterPlugin) {
32432
35118
  this.openRouterPlugin.disable();
32433
35119
  this.openRouterPlugin = null;
@@ -32440,6 +35126,10 @@ var BraintrustPlugin = class extends BasePlugin {
32440
35126
  this.mistralPlugin.disable();
32441
35127
  this.mistralPlugin = null;
32442
35128
  }
35129
+ if (this.ollamaPlugin) {
35130
+ this.ollamaPlugin.disable();
35131
+ this.ollamaPlugin = null;
35132
+ }
32443
35133
  if (this.googleADKPlugin) {
32444
35134
  this.googleADKPlugin.disable();
32445
35135
  this.googleADKPlugin = null;
@@ -32472,6 +35162,14 @@ var BraintrustPlugin = class extends BasePlugin {
32472
35162
  this.strandsAgentSDKPlugin.disable();
32473
35163
  this.strandsAgentSDKPlugin = null;
32474
35164
  }
35165
+ if (this.cloudflareAIChatPlugin) {
35166
+ this.cloudflareAIChatPlugin.disable();
35167
+ this.cloudflareAIChatPlugin = null;
35168
+ }
35169
+ if (this.cloudflareAgentsPlugin) {
35170
+ this.cloudflareAgentsPlugin.disable();
35171
+ this.cloudflareAgentsPlugin = null;
35172
+ }
32475
35173
  if (this.fluePlugin) {
32476
35174
  this.fluePlugin.disable();
32477
35175
  this.fluePlugin = null;
@@ -32504,6 +35202,9 @@ var envIntegrationAliases = {
32504
35202
  strandsagentsdk: "strandsAgentSDK",
32505
35203
  "strands-agent-sdk": "strandsAgentSDK",
32506
35204
  "@strands-agents/sdk": "strandsAgentSDK",
35205
+ agents: "cloudflareAgents",
35206
+ "cloudflare-agents": "cloudflareAgents",
35207
+ cloudflareagents: "cloudflareAgents",
32507
35208
  anthropic: "anthropic",
32508
35209
  aisdk: "aisdk",
32509
35210
  "ai-sdk": "aisdk",
@@ -32511,6 +35212,10 @@ var envIntegrationAliases = {
32511
35212
  vercel: "vercel",
32512
35213
  claudeagentsdk: "claudeAgentSDK",
32513
35214
  "claude-agent-sdk": "claudeAgentSDK",
35215
+ cloudflareaichat: "cloudflareAIChat",
35216
+ "cloudflare-ai-chat": "cloudflareAIChat",
35217
+ "@cloudflare/ai-chat": "cloudflareAIChat",
35218
+ cloudflarethink: "cloudflareThink",
32514
35219
  cursor: "cursor",
32515
35220
  "cursor-sdk": "cursorSDK",
32516
35221
  cursorsdk: "cursorSDK",
@@ -32525,10 +35230,13 @@ var envIntegrationAliases = {
32525
35230
  "google-genai": "googleGenAI",
32526
35231
  googlegenai: "googleGenAI",
32527
35232
  huggingface: "huggingface",
35233
+ "@huggingface/transformers": "huggingface",
35234
+ transformers: "huggingface",
32528
35235
  openrouter: "openrouter",
32529
35236
  openrouteragent: "openrouterAgent",
32530
35237
  "openrouter-agent": "openrouterAgent",
32531
35238
  mistral: "mistral",
35239
+ ollama: "ollama",
32532
35240
  googleadk: "googleADK",
32533
35241
  "google-adk": "googleADK",
32534
35242
  cohere: "cohere",
@@ -32563,6 +35271,8 @@ function getDefaultInstrumentationIntegrations() {
32563
35271
  googleADK: true,
32564
35272
  huggingface: true,
32565
35273
  claudeAgentSDK: true,
35274
+ cloudflareAIChat: true,
35275
+ cloudflareThink: true,
32566
35276
  cursor: true,
32567
35277
  cursorSDK: true,
32568
35278
  flue: true,
@@ -32571,6 +35281,7 @@ function getDefaultInstrumentationIntegrations() {
32571
35281
  openrouter: true,
32572
35282
  openrouterAgent: true,
32573
35283
  mistral: true,
35284
+ ollama: true,
32574
35285
  cohere: true,
32575
35286
  groq: true,
32576
35287
  bedrock: true,
@@ -32582,7 +35293,8 @@ function getDefaultInstrumentationIntegrations() {
32582
35293
  langgraph: true,
32583
35294
  langsmith: true,
32584
35295
  piCodingAgent: true,
32585
- strandsAgentSDK: true
35296
+ strandsAgentSDK: true,
35297
+ cloudflareAgents: true
32586
35298
  };
32587
35299
  }
32588
35300
  function readDisabledInstrumentationEnvConfig(disabledList) {
@@ -32603,7 +35315,9 @@ function isInstrumentationIntegrationDisabled(integrations, ...names) {
32603
35315
  }
32604
35316
 
32605
35317
  // src/instrumentation/registry.ts
32606
- var REGISTRY_STATE_KEY = /* @__PURE__ */ Symbol.for("braintrust.registry");
35318
+ var REGISTRY_STATE_KEY = /* @__PURE__ */ Symbol.for(
35319
+ `braintrust.registry.global-hooks.v${GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION}`
35320
+ );
32607
35321
  function getSharedState() {
32608
35322
  const state = globalThis[/* @__PURE__ */ Symbol.for("braintrust-state")];
32609
35323
  return state && typeof state === "object" ? state : void 0;
@@ -33039,8 +35753,6 @@ function configureNode() {
33039
35753
  };
33040
35754
  isomorph_default.getCallerLocation = getCallerLocation;
33041
35755
  isomorph_default.newAsyncLocalStorage = () => new AsyncLocalStorage();
33042
- isomorph_default.newTracingChannel = (nameOrChannels) => diagnostics_channel.tracingChannel(nameOrChannels);
33043
- patchTracingChannel(diagnostics_channel.tracingChannel);
33044
35756
  isomorph_default.processOn = (event, handler) => {
33045
35757
  process.on(event, handler);
33046
35758
  };