braintrust 3.25.0 → 3.26.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 (78) 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 +2455 -1116
  5. package/dev/dist/index.mjs +1599 -260
  6. package/dist/apply-auto-instrumentation.js +439 -398
  7. package/dist/apply-auto-instrumentation.mjs +242 -201
  8. package/dist/auto-instrumentations/bundler/esbuild.cjs +853 -337
  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 +5 -8
  12. package/dist/auto-instrumentations/bundler/next.cjs +852 -356
  13. package/dist/auto-instrumentations/bundler/next.mjs +6 -29
  14. package/dist/auto-instrumentations/bundler/rollup.cjs +853 -337
  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 +5 -8
  18. package/dist/auto-instrumentations/bundler/vite.cjs +853 -337
  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 +5 -8
  22. package/dist/auto-instrumentations/bundler/webpack-loader.cjs +1006 -266
  23. package/dist/auto-instrumentations/bundler/webpack-loader.d.ts +20 -12
  24. package/dist/auto-instrumentations/bundler/webpack.cjs +853 -337
  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 +5 -4
  28. package/dist/auto-instrumentations/{chunk-JPVCUKTY.mjs → chunk-6E22MYSW.mjs} +165 -73
  29. package/dist/auto-instrumentations/{chunk-VT6DDNKM.mjs → chunk-AKKPLXTP.mjs} +631 -194
  30. package/dist/auto-instrumentations/chunk-NRE4QUQR.mjs +509 -0
  31. package/dist/auto-instrumentations/{chunk-7P6563SW.mjs → chunk-V5LEODRX.mjs} +2 -6
  32. package/dist/auto-instrumentations/{chunk-M6DLIJ2Z.mjs → chunk-XYN63IG5.mjs} +124 -194
  33. package/dist/auto-instrumentations/{chunk-CZ24KNHT.mjs → chunk-XZHHE4Y3.mjs} +77 -68
  34. package/dist/auto-instrumentations/hook.mjs +247 -182
  35. package/dist/auto-instrumentations/index.cjs +557 -48
  36. package/dist/auto-instrumentations/index.d.mts +6 -2
  37. package/dist/auto-instrumentations/index.d.ts +6 -2
  38. package/dist/auto-instrumentations/index.mjs +6 -1
  39. package/dist/auto-instrumentations/loader/cjs-patch.cjs +492 -195
  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 +817 -197
  49. package/dist/browser.d.ts +817 -197
  50. package/dist/browser.js +1883 -265
  51. package/dist/browser.mjs +1883 -265
  52. package/dist/{chunk-ABR2QWDP.mjs → chunk-PN7EWK66.mjs} +581 -133
  53. package/dist/{chunk-GSIDVFE6.js → chunk-VRZZQPAA.js} +1670 -736
  54. package/dist/{chunk-P25IOOU4.js → chunk-VYNNEKSA.js} +586 -138
  55. package/dist/{chunk-2SANLSWX.mjs → chunk-XIZOM2HO.mjs} +1052 -118
  56. package/dist/cli.js +1601 -263
  57. package/dist/edge-light.d.mts +1 -1
  58. package/dist/edge-light.d.ts +1 -1
  59. package/dist/edge-light.js +1883 -268
  60. package/dist/edge-light.mjs +1883 -268
  61. package/dist/index.d.mts +817 -197
  62. package/dist/index.d.ts +817 -197
  63. package/dist/index.js +695 -435
  64. package/dist/index.mjs +264 -4
  65. package/dist/instrumentation/index.d.mts +130 -6
  66. package/dist/instrumentation/index.d.ts +130 -6
  67. package/dist/instrumentation/index.js +1510 -80
  68. package/dist/instrumentation/index.mjs +1510 -80
  69. package/dist/vitest-evals-reporter.js +16 -16
  70. package/dist/vitest-evals-reporter.mjs +2 -2
  71. package/dist/workerd.d.mts +1 -1
  72. package/dist/workerd.d.ts +1 -1
  73. package/dist/workerd.js +1883 -268
  74. package/dist/workerd.mjs +1883 -268
  75. package/licenses/node-diagnostics-channel/LICENSE +19 -0
  76. package/package.json +34 -35
  77. package/dist/auto-instrumentations/plugin-D0KHwSJv.d.mts +0 -44
  78. 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,528 @@ 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 registryBrand = Symbol.for(GLOBAL_INSTRUMENTATION_HOOKS_REGISTRY_BRAND);
18
+ var hookBrand = Symbol.for(GLOBAL_INSTRUMENTATION_HOOK_BRAND);
19
+ var errorReporter;
20
+ function setGlobalHookErrorReporter(reporter) {
21
+ const previousReporter = errorReporter;
22
+ errorReporter = reporter;
23
+ return () => {
24
+ if (errorReporter === reporter) {
25
+ errorReporter = previousReporter;
26
+ }
27
+ };
28
+ }
29
+ function reportError(error) {
30
+ try {
31
+ errorReporter?.(error);
32
+ } catch {
109
33
  }
110
- getStore() {
111
- return void 0;
34
+ }
35
+ function setContextValue(context, key, value) {
36
+ try {
37
+ context[key] = value;
38
+ } catch (error) {
39
+ reportError(error);
112
40
  }
113
- };
114
- var DefaultChannel = class {
41
+ }
42
+ function wrapStoreRun(store, message, next, transform) {
43
+ return () => {
44
+ let context;
45
+ try {
46
+ context = transform ? transform(message) : message;
47
+ } catch (error) {
48
+ reportError(error);
49
+ return next();
50
+ }
51
+ let called = false;
52
+ let result;
53
+ let providerError;
54
+ let providerThrew = false;
55
+ const runNext = () => {
56
+ if (called) {
57
+ reportError(
58
+ new Error(
59
+ "Instrumentation store invoked its callback more than once"
60
+ )
61
+ );
62
+ if (providerThrew) {
63
+ throw providerError;
64
+ }
65
+ return result;
66
+ }
67
+ called = true;
68
+ try {
69
+ result = next();
70
+ return result;
71
+ } catch (error) {
72
+ providerThrew = true;
73
+ providerError = error;
74
+ throw error;
75
+ }
76
+ };
77
+ try {
78
+ store.run(context, runNext);
79
+ } catch (error) {
80
+ if (!providerThrew || error !== providerError) {
81
+ reportError(error);
82
+ }
83
+ }
84
+ if (!called) {
85
+ reportError(
86
+ new Error("Instrumentation store did not invoke its callback")
87
+ );
88
+ return runNext();
89
+ }
90
+ if (providerThrew) {
91
+ throw providerError;
92
+ }
93
+ return result;
94
+ };
95
+ }
96
+ var HookChannel = class {
115
97
  constructor(name) {
116
98
  this.name = name;
117
99
  }
118
100
  name;
119
- hasSubscribers = false;
120
- subscribe(_subscription) {
101
+ subscribers = [];
102
+ stores = /* @__PURE__ */ new Map();
103
+ get hasSubscribers() {
104
+ return this.subscribers.length > 0 || this.stores.size > 0;
121
105
  }
122
- unsubscribe(_subscription) {
123
- return false;
106
+ subscribe(subscription) {
107
+ if (typeof subscription !== "function") {
108
+ throw new TypeError("subscription must be a function");
109
+ }
110
+ this.subscribers = [...this.subscribers, subscription];
124
111
  }
125
- bindStore(_store, _transform) {
112
+ unsubscribe(subscription) {
113
+ const index = this.subscribers.indexOf(subscription);
114
+ if (index === -1) {
115
+ return false;
116
+ }
117
+ this.subscribers = [
118
+ ...this.subscribers.slice(0, index),
119
+ ...this.subscribers.slice(index + 1)
120
+ ];
121
+ return true;
126
122
  }
127
- unbindStore(_store) {
128
- return false;
123
+ bindStore(store, transform) {
124
+ if (!store || typeof store.run !== "function") {
125
+ throw new TypeError("store must have a run method");
126
+ }
127
+ this.stores.set(
128
+ store,
129
+ transform
130
+ );
129
131
  }
130
- publish(_message) {
132
+ unbindStore(store) {
133
+ return this.stores.delete(store);
131
134
  }
132
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
133
- runStores(_message, fn, thisArg, ...args) {
134
- return fn.apply(thisArg, args);
135
+ publish(message) {
136
+ const subscribers = this.subscribers;
137
+ for (const subscriber of subscribers) {
138
+ try {
139
+ subscriber(message, this.name);
140
+ } catch (error) {
141
+ reportError(error);
142
+ }
143
+ }
144
+ }
145
+ runStores(message, fn, thisArg, ...args) {
146
+ let run = () => {
147
+ this.publish(message);
148
+ return Reflect.apply(fn, thisArg, args);
149
+ };
150
+ for (const [store, transform] of this.stores.entries()) {
151
+ run = wrapStoreRun(store, message, run, transform);
152
+ }
153
+ return run();
135
154
  }
136
155
  };
137
- var DefaultTracingChannel = class {
156
+ var traceEvents = [
157
+ "start",
158
+ "end",
159
+ "asyncStart",
160
+ "asyncEnd",
161
+ "error"
162
+ ];
163
+ var TracingHook = class {
138
164
  start;
139
165
  end;
140
166
  asyncStart;
141
167
  asyncEnd;
142
168
  error;
143
169
  constructor(nameOrChannels) {
170
+ Object.defineProperty(this, hookBrand, {
171
+ configurable: false,
172
+ enumerable: false,
173
+ value: GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION,
174
+ writable: false
175
+ });
144
176
  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`);
177
+ this.start = new HookChannel(`tracing:${nameOrChannels}:start`);
178
+ this.end = new HookChannel(`tracing:${nameOrChannels}:end`);
179
+ this.asyncStart = new HookChannel(`tracing:${nameOrChannels}:asyncStart`);
180
+ this.asyncEnd = new HookChannel(`tracing:${nameOrChannels}:asyncEnd`);
181
+ this.error = new HookChannel(`tracing:${nameOrChannels}:error`);
152
182
  return;
153
183
  }
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");
184
+ this.start = nameOrChannels.start ?? new HookChannel("tracing:start");
185
+ this.end = nameOrChannels.end ?? new HookChannel("tracing:end");
186
+ this.asyncStart = nameOrChannels.asyncStart ?? new HookChannel("tracing:asyncStart");
187
+ this.asyncEnd = nameOrChannels.asyncEnd ?? new HookChannel("tracing:asyncEnd");
188
+ this.error = nameOrChannels.error ?? new HookChannel("tracing:error");
159
189
  }
160
190
  get hasSubscribers() {
161
191
  return this.start.hasSubscribers || this.end.hasSubscribers || this.asyncStart.hasSubscribers || this.asyncEnd.hasSubscribers || this.error.hasSubscribers;
162
192
  }
163
- subscribe(_handlers) {
193
+ subscribe(handlers) {
194
+ for (const eventName of traceEvents) {
195
+ const handler = handlers[eventName];
196
+ if (handler) {
197
+ this[eventName].subscribe(handler);
198
+ }
199
+ }
200
+ }
201
+ unsubscribe(handlers) {
202
+ let done = true;
203
+ for (const eventName of traceEvents) {
204
+ const handler = handlers[eventName];
205
+ if (handler && !this[eventName].unsubscribe(handler)) {
206
+ done = false;
207
+ }
208
+ }
209
+ return done;
210
+ }
211
+ traceSync(fn, message = {}, thisArg, ...args) {
212
+ if (!this.hasSubscribers) {
213
+ return Reflect.apply(fn, thisArg, args);
214
+ }
215
+ const context = message;
216
+ return this.start.runStores(message, () => {
217
+ try {
218
+ const result = Reflect.apply(fn, thisArg, args);
219
+ setContextValue(context, "result", result);
220
+ return result;
221
+ } catch (error) {
222
+ setContextValue(context, "error", error);
223
+ this.error.publish(message);
224
+ throw error;
225
+ } finally {
226
+ this.end.publish(message);
227
+ }
228
+ });
164
229
  }
165
- unsubscribe(_handlers) {
230
+ tracePromise(fn, message = {}, thisArg, ...args) {
231
+ if (!this.hasSubscribers) {
232
+ return Reflect.apply(fn, thisArg, args);
233
+ }
234
+ const context = message;
235
+ return this.start.runStores(message, () => {
236
+ let result;
237
+ try {
238
+ result = Reflect.apply(fn, thisArg, args);
239
+ } catch (error) {
240
+ setContextValue(context, "error", error);
241
+ this.error.publish(message);
242
+ this.end.publish(message);
243
+ throw error;
244
+ }
245
+ this.end.publish(message);
246
+ if (!result || typeof result !== "object" && typeof result !== "function") {
247
+ setContextValue(context, "result", result);
248
+ this.asyncStart.publish(message);
249
+ this.asyncEnd.publish(message);
250
+ return result;
251
+ }
252
+ let terminalPublished = false;
253
+ const finishUnobservedResult = (error) => {
254
+ reportError(error);
255
+ if (!terminalPublished) {
256
+ terminalPublished = true;
257
+ setContextValue(context, "result", result);
258
+ this.asyncStart.publish(message);
259
+ this.asyncEnd.publish(message);
260
+ }
261
+ return result;
262
+ };
263
+ let then;
264
+ try {
265
+ then = result.then;
266
+ } catch (error) {
267
+ return finishUnobservedResult(error);
268
+ }
269
+ if (typeof then !== "function") {
270
+ setContextValue(context, "result", result);
271
+ this.asyncStart.publish(message);
272
+ this.asyncEnd.publish(message);
273
+ return result;
274
+ }
275
+ const resolve = (resolved) => {
276
+ if (!terminalPublished) {
277
+ terminalPublished = true;
278
+ setContextValue(context, "result", resolved);
279
+ this.asyncStart.publish(message);
280
+ this.asyncEnd.publish(message);
281
+ }
282
+ return resolved;
283
+ };
284
+ let rejectionThrown = false;
285
+ let rejectionError;
286
+ const reject2 = (error) => {
287
+ if (!terminalPublished) {
288
+ terminalPublished = true;
289
+ setContextValue(context, "error", error);
290
+ this.error.publish(message);
291
+ this.asyncStart.publish(message);
292
+ this.asyncEnd.publish(message);
293
+ }
294
+ rejectionThrown = true;
295
+ rejectionError = error;
296
+ throw error;
297
+ };
298
+ let isPlainPromise;
299
+ try {
300
+ isPlainPromise = result instanceof Promise && result.constructor === Promise;
301
+ } catch (error) {
302
+ return finishUnobservedResult(error);
303
+ }
304
+ try {
305
+ if (isPlainPromise) {
306
+ return Reflect.apply(then, result, [resolve, reject2]);
307
+ }
308
+ Reflect.apply(then, result, [
309
+ resolve,
310
+ (error) => {
311
+ try {
312
+ reject2(error);
313
+ } catch {
314
+ }
315
+ }
316
+ ]);
317
+ } catch (error) {
318
+ if (rejectionThrown && error === rejectionError) {
319
+ return result;
320
+ }
321
+ return finishUnobservedResult(error);
322
+ }
323
+ return result;
324
+ });
325
+ }
326
+ traceCallback(fn, position = -1, message = {}, thisArg, ...args) {
327
+ if (!this.hasSubscribers) {
328
+ return Reflect.apply(fn, thisArg, args);
329
+ }
330
+ const context = message;
331
+ const callArgs = args.length > 0 ? args : context.arguments ?? args;
332
+ const callback = Array.prototype.at.call(callArgs, position);
333
+ if (typeof callback !== "function") {
334
+ return Reflect.apply(fn, thisArg, args);
335
+ }
336
+ const { asyncStart, asyncEnd, error: errorChannel } = this;
337
+ function wrappedCallback(error, result) {
338
+ if (error) {
339
+ setContextValue(context, "error", error);
340
+ errorChannel.publish(message);
341
+ } else {
342
+ setContextValue(context, "result", result);
343
+ }
344
+ return asyncStart.runStores(message, () => {
345
+ try {
346
+ return Reflect.apply(callback, this, arguments);
347
+ } finally {
348
+ asyncEnd.publish(message);
349
+ }
350
+ });
351
+ }
352
+ Array.prototype.splice.call(callArgs, position, 1, wrappedCallback);
353
+ return this.start.runStores(message, () => {
354
+ try {
355
+ return Reflect.apply(fn, thisArg, args);
356
+ } catch (error) {
357
+ setContextValue(context, "error", error);
358
+ this.error.publish(message);
359
+ throw error;
360
+ } finally {
361
+ this.end.publish(message);
362
+ }
363
+ });
364
+ }
365
+ };
366
+ var inertChannel = Object.freeze({
367
+ name: "braintrust:inert",
368
+ hasSubscribers: false,
369
+ subscribe() {
370
+ },
371
+ unsubscribe() {
166
372
  return false;
373
+ },
374
+ bindStore() {
375
+ },
376
+ unbindStore() {
377
+ return false;
378
+ },
379
+ publish() {
380
+ },
381
+ runStores(_message, fn, thisArg, ...args) {
382
+ return Reflect.apply(fn, thisArg, args);
167
383
  }
168
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
169
- traceSync(fn, _message, thisArg, ...args) {
170
- return fn.apply(thisArg, args);
384
+ });
385
+ var inertTracingHook = new TracingHook({
386
+ start: inertChannel,
387
+ end: inertChannel,
388
+ asyncStart: inertChannel,
389
+ asyncEnd: inertChannel,
390
+ error: inertChannel
391
+ });
392
+ function isHookChannel(value) {
393
+ if (typeof value !== "object" && typeof value !== "function" || value === null) {
394
+ return false;
171
395
  }
172
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
173
- tracePromise(fn, _message, thisArg, ...args) {
174
- return fn.apply(thisArg, args);
396
+ try {
397
+ const channel2 = value;
398
+ 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";
399
+ } catch {
400
+ return false;
175
401
  }
176
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
177
- traceCallback(fn, _position, _message, thisArg, ...args) {
178
- return fn.apply(thisArg, args);
402
+ }
403
+ function hasTracingHookShape(value) {
404
+ if (typeof value !== "object" && typeof value !== "function" || value === null) {
405
+ return false;
406
+ }
407
+ try {
408
+ const hook = value;
409
+ 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);
410
+ } catch {
411
+ return false;
412
+ }
413
+ }
414
+ function isCompatibleTracingHook(value) {
415
+ try {
416
+ return value[hookBrand] === GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION && hasTracingHookShape(value);
417
+ } catch {
418
+ return false;
419
+ }
420
+ }
421
+ function isCompatibleHookRegistry(value) {
422
+ try {
423
+ return value instanceof Map && value[registryBrand] === GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION;
424
+ } catch {
425
+ return false;
426
+ }
427
+ }
428
+ function getHookRegistry() {
429
+ let descriptor;
430
+ try {
431
+ descriptor = Object.getOwnPropertyDescriptor(
432
+ globalThis,
433
+ GLOBAL_INSTRUMENTATION_HOOKS_KEY
434
+ );
435
+ } catch (error) {
436
+ reportError(error);
437
+ return void 0;
438
+ }
439
+ if (descriptor && "value" in descriptor && isCompatibleHookRegistry(descriptor.value) && (descriptor.configurable || descriptor.enumerable === false)) {
440
+ if (descriptor.configurable || descriptor.writable) {
441
+ try {
442
+ Object.defineProperty(globalThis, GLOBAL_INSTRUMENTATION_HOOKS_KEY, {
443
+ configurable: false,
444
+ enumerable: false,
445
+ value: descriptor.value,
446
+ writable: false
447
+ });
448
+ } catch (error) {
449
+ reportError(error);
450
+ return void 0;
451
+ }
452
+ }
453
+ return descriptor.value;
454
+ }
455
+ if (descriptor && !descriptor.configurable) {
456
+ reportError(new Error("Incompatible global instrumentation hook registry"));
457
+ return void 0;
458
+ }
459
+ const registry2 = /* @__PURE__ */ new Map();
460
+ try {
461
+ Object.defineProperty(registry2, registryBrand, {
462
+ configurable: false,
463
+ enumerable: false,
464
+ value: GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION,
465
+ writable: false
466
+ });
467
+ } catch (error) {
468
+ reportError(error);
469
+ return void 0;
470
+ }
471
+ try {
472
+ Object.defineProperty(globalThis, GLOBAL_INSTRUMENTATION_HOOKS_KEY, {
473
+ configurable: false,
474
+ enumerable: false,
475
+ value: registry2,
476
+ writable: false
477
+ });
478
+ return registry2;
479
+ } catch (error) {
480
+ reportError(error);
481
+ return void 0;
482
+ }
483
+ }
484
+ function newGlobalTracingChannel(nameOrChannels) {
485
+ if (typeof nameOrChannels !== "string") {
486
+ return new TracingHook(nameOrChannels);
487
+ }
488
+ const registry2 = getHookRegistry();
489
+ if (!registry2) {
490
+ return inertTracingHook;
491
+ }
492
+ let existing;
493
+ try {
494
+ existing = Map.prototype.get.call(registry2, nameOrChannels);
495
+ } catch (error) {
496
+ reportError(error);
497
+ return inertTracingHook;
498
+ }
499
+ if (isCompatibleTracingHook(existing)) {
500
+ return existing;
501
+ }
502
+ if (existing !== void 0) {
503
+ reportError(
504
+ new Error(`Invalid global instrumentation hook: ${nameOrChannels}`)
505
+ );
506
+ try {
507
+ Map.prototype.delete.call(registry2, nameOrChannels);
508
+ } catch (error) {
509
+ reportError(error);
510
+ return inertTracingHook;
511
+ }
512
+ }
513
+ const hook = new TracingHook(nameOrChannels);
514
+ try {
515
+ Map.prototype.set.call(registry2, nameOrChannels, hook);
516
+ } catch (error) {
517
+ reportError(error);
518
+ return inertTracingHook;
519
+ }
520
+ return hook;
521
+ }
522
+
523
+ // src/isomorph.ts
524
+ var DefaultAsyncLocalStorage = class {
525
+ constructor() {
526
+ }
527
+ enterWith(_) {
528
+ }
529
+ run(_, callback) {
530
+ return callback();
531
+ }
532
+ getStore() {
533
+ return void 0;
179
534
  }
180
535
  };
181
536
  var iso = {
@@ -188,7 +543,7 @@ var iso = {
188
543
  getCallerLocation: () => void 0,
189
544
  newAsyncLocalStorage: () => new DefaultAsyncLocalStorage(),
190
545
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
191
- newTracingChannel: (nameOrChannels) => new DefaultTracingChannel(nameOrChannels),
546
+ newTracingChannel: (nameOrChannels) => newGlobalTracingChannel(nameOrChannels),
192
547
  processOn: (_0, _1) => {
193
548
  },
194
549
  basename: (filepath) => filepath.split(/[\\/]/).pop() || filepath,
@@ -301,6 +656,9 @@ var debugLogger = {
301
656
  return createDebugLogger(state);
302
657
  }
303
658
  };
659
+ setGlobalHookErrorReporter((error) => {
660
+ debugLogger.error("Global instrumentation hook error:", error);
661
+ });
304
662
 
305
663
  // src/gitutil.ts
306
664
  import { simpleGit } from "simple-git";
@@ -2317,7 +2675,8 @@ var ApiKey = z6.object({
2317
2675
  user_email: z6.union([z6.string(), z6.null()]).optional(),
2318
2676
  user_given_name: z6.union([z6.string(), z6.null()]).optional(),
2319
2677
  user_family_name: z6.union([z6.string(), z6.null()]).optional(),
2320
- org_id: z6.union([z6.string(), z6.null()]).optional()
2678
+ org_id: z6.union([z6.string(), z6.null()]).optional(),
2679
+ expires_at: z6.union([z6.string(), z6.null()]).optional()
2321
2680
  });
2322
2681
  var TriggeredFunctionState = z6.object({
2323
2682
  triggered_xact_id: z6.string(),
@@ -2437,6 +2796,7 @@ var TopicMapData = z6.object({
2437
2796
  topic_names: z6.record(z6.string()).optional(),
2438
2797
  generation_settings: TopicMapGenerationSettings.optional(),
2439
2798
  disable_reconciliation: z6.boolean().optional(),
2799
+ reconcile_mode: z6.enum(["evolve", "names_only"]).optional(),
2440
2800
  distance_threshold: z6.number().optional(),
2441
2801
  btql_filter: z6.string().optional(),
2442
2802
  automation_btql_filter: z6.string().optional()
@@ -3017,7 +3377,12 @@ var ModelParams = z6.union([
3017
3377
  }).partial().passthrough()
3018
3378
  ]);
3019
3379
  var PromptOptionsNullish = z6.union([
3020
- z6.object({ model: z6.string(), params: ModelParams, position: z6.string() }).partial(),
3380
+ z6.object({
3381
+ model: z6.string(),
3382
+ params: ModelParams,
3383
+ position: z6.string(),
3384
+ endpoint_name: z6.union([z6.string(), z6.null()])
3385
+ }).partial(),
3021
3386
  z6.null()
3022
3387
  ]);
3023
3388
  var PromptParserNullish = z6.union([
@@ -3031,11 +3396,25 @@ var PromptParserNullish = z6.union([
3031
3396
  }),
3032
3397
  z6.null()
3033
3398
  ]);
3399
+ var PreprocessorSavedFunctionId = z6.union([
3400
+ z6.object({
3401
+ type: z6.literal("function"),
3402
+ id: z6.string(),
3403
+ version: z6.string().optional()
3404
+ }),
3405
+ z6.object({
3406
+ type: z6.literal("global"),
3407
+ name: z6.string(),
3408
+ function_type: z6.literal("preprocessor").optional().default("preprocessor")
3409
+ }),
3410
+ z6.null()
3411
+ ]);
3034
3412
  var PromptDataNullish = z6.union([
3035
3413
  z6.object({
3036
3414
  prompt: PromptBlockDataNullish,
3037
3415
  options: PromptOptionsNullish,
3038
3416
  parser: PromptParserNullish,
3417
+ preprocessor: PreprocessorSavedFunctionId,
3039
3418
  tool_functions: z6.union([z6.array(SavedFunctionId), z6.null()]),
3040
3419
  template_format: z6.union([
3041
3420
  z6.enum(["mustache", "nunjucks", "none"]),
@@ -3237,6 +3616,7 @@ var PromptData = z6.object({
3237
3616
  prompt: PromptBlockDataNullish,
3238
3617
  options: PromptOptionsNullish,
3239
3618
  parser: PromptParserNullish,
3619
+ preprocessor: PreprocessorSavedFunctionId,
3240
3620
  tool_functions: z6.union([z6.array(SavedFunctionId), z6.null()]),
3241
3621
  template_format: z6.union([
3242
3622
  z6.enum(["mustache", "nunjucks", "none"]),
@@ -3399,7 +3779,8 @@ var InvokeFunction = FunctionId.and(
3399
3779
  mode: StreamingMode,
3400
3780
  strict: z6.union([z6.boolean(), z6.null()]),
3401
3781
  mcp_auth: z6.record(z6.object({ oauth_token: z6.string() }).partial()),
3402
- overrides: z6.union([z6.object({}).partial().passthrough(), z6.null()])
3782
+ overrides: z6.union([z6.object({}).partial().passthrough(), z6.null()]),
3783
+ endpoint_name: z6.union([z6.string(), z6.null()])
3403
3784
  }).partial()
3404
3785
  );
3405
3786
  var MCPServer = z6.object({
@@ -3463,6 +3844,24 @@ var Organization = z6.object({
3463
3844
  created: z6.union([z6.string(), z6.null()]).optional(),
3464
3845
  image_rendering_mode: ImageRenderingMode.optional()
3465
3846
  });
3847
+ var RetentionObjectType = z6.enum([
3848
+ "project_logs",
3849
+ "experiment",
3850
+ "dataset"
3851
+ ]);
3852
+ var OrgAutomation = z6.object({
3853
+ id: z6.string().uuid(),
3854
+ org_id: z6.string().uuid(),
3855
+ user_id: z6.union([z6.string(), z6.null()]).optional(),
3856
+ created: z6.union([z6.string(), z6.null()]).optional(),
3857
+ name: z6.string(),
3858
+ description: z6.union([z6.string(), z6.null()]).optional(),
3859
+ config: z6.object({
3860
+ event_type: z6.literal("retention"),
3861
+ object_type: RetentionObjectType,
3862
+ retention_days: z6.number().int().gte(0)
3863
+ })
3864
+ });
3466
3865
  var ProjectSettings = z6.union([
3467
3866
  z6.object({
3468
3867
  comparison_key: z6.union([z6.string(), z6.null()]),
@@ -3489,6 +3888,7 @@ var ProjectSettings = z6.union([
3489
3888
  z6.null()
3490
3889
  ]),
3491
3890
  disable_realtime_queries: z6.union([z6.boolean(), z6.null()]),
3891
+ monitor_charts_use_metrics_start: z6.union([z6.boolean(), z6.null()]),
3492
3892
  default_preprocessor: NullableSavedFunctionId
3493
3893
  }).partial(),
3494
3894
  z6.null()
@@ -3503,11 +3903,6 @@ var Project = z6.object({
3503
3903
  user_id: z6.union([z6.string(), z6.null()]).optional(),
3504
3904
  settings: ProjectSettings.optional()
3505
3905
  });
3506
- var RetentionObjectType = z6.enum([
3507
- "project_logs",
3508
- "experiment",
3509
- "dataset"
3510
- ]);
3511
3906
  var TopicAutomationFacetModel = z6.union([
3512
3907
  z6.enum(["brain-facet-latest", "brain-facet-1", "brain-facet-2"]),
3513
3908
  z6.null()
@@ -3618,7 +4013,7 @@ var ProjectAutomation = z6.object({
3618
4013
  z6.object({
3619
4014
  event_type: z6.literal("retention"),
3620
4015
  object_type: RetentionObjectType,
3621
- retention_days: z6.number().gte(0)
4016
+ retention_days: z6.number().int().gte(0)
3622
4017
  }),
3623
4018
  z6.object({
3624
4019
  event_type: z6.literal("environment_update"),
@@ -3790,7 +4185,12 @@ var Prompt = z6.object({
3790
4185
  metadata: z6.union([z6.object({}).partial().passthrough(), z6.null()]).optional(),
3791
4186
  function_type: FunctionTypeEnumNullish.optional()
3792
4187
  });
3793
- var PromptOptions = z6.object({ model: z6.string(), params: ModelParams, position: z6.string() }).partial();
4188
+ var PromptOptions = z6.object({
4189
+ model: z6.string(),
4190
+ params: ModelParams,
4191
+ position: z6.string(),
4192
+ endpoint_name: z6.union([z6.string(), z6.null()])
4193
+ }).partial();
3794
4194
  var PromptSessionEvent = z6.object({
3795
4195
  id: z6.string(),
3796
4196
  _xact_id: z6.string(),
@@ -3873,7 +4273,8 @@ var RunEval = z6.object({
3873
4273
  stop_token: z6.union([z6.string(), z6.null()]).optional(),
3874
4274
  extra_messages: z6.string().optional(),
3875
4275
  tags: z6.array(z6.string()).optional(),
3876
- mcp_auth: z6.record(z6.object({ oauth_token: z6.string() }).partial()).optional()
4276
+ mcp_auth: z6.record(z6.object({ oauth_token: z6.string() }).partial()).optional(),
4277
+ endpoint_name: z6.union([z6.string(), z6.null()]).optional()
3877
4278
  });
3878
4279
  var ServiceToken = z6.object({
3879
4280
  id: z6.string().uuid(),
@@ -3883,7 +4284,8 @@ var ServiceToken = z6.object({
3883
4284
  service_account_id: z6.union([z6.string(), z6.null()]).optional(),
3884
4285
  service_account_email: z6.union([z6.string(), z6.null()]).optional(),
3885
4286
  service_account_name: z6.union([z6.string(), z6.null()]).optional(),
3886
- org_id: z6.union([z6.string(), z6.null()]).optional()
4287
+ org_id: z6.union([z6.string(), z6.null()]).optional(),
4288
+ expires_at: z6.union([z6.string(), z6.null()]).optional()
3887
4289
  });
3888
4290
  var SpanIFrame = z6.object({
3889
4291
  id: z6.string().uuid(),
@@ -4005,6 +4407,13 @@ var ViewOptions = z6.union([
4005
4407
  }),
4006
4408
  z6.null()
4007
4409
  ]),
4410
+ pointSizeMetric: z6.union([
4411
+ z6.object({
4412
+ type: z6.enum(["none", "score", "metric", "metadata"]),
4413
+ value: z6.string()
4414
+ }),
4415
+ z6.null()
4416
+ ]),
4008
4417
  xAxisAggregation: z6.union([z6.string(), z6.null()]),
4009
4418
  chartAnnotations: z6.union([
4010
4419
  z6.array(z6.object({ id: z6.string(), text: z6.string() })),
@@ -5148,6 +5557,8 @@ var INSTRUMENTATION_NAMES = {
5148
5557
  BEDROCK_RUNTIME: "bedrock-runtime",
5149
5558
  BRAINTRUST_JS_LOGGER: "braintrust-js-logger",
5150
5559
  CLAUDE_AGENT_SDK: "claude-agent-sdk",
5560
+ CLOUDFLARE_AI_CHAT: "cloudflare-ai-chat",
5561
+ CLOUDFLARE_AGENTS: "cloudflare-agents",
5151
5562
  COHERE: "cohere",
5152
5563
  CURSOR_SDK: "cursor-sdk",
5153
5564
  EVE: "eve",
@@ -5173,7 +5584,7 @@ var INSTRUMENTATION_NAMES = {
5173
5584
  var INTERNAL_SPAN_INSTRUMENTATION_NAME = /* @__PURE__ */ Symbol.for(
5174
5585
  "braintrust.spanInstrumentationName"
5175
5586
  );
5176
- var SDK_VERSION = true ? "3.25.0" : "0.0.0";
5587
+ var SDK_VERSION = true ? "3.26.0" : "0.0.0";
5177
5588
  function withSpanInstrumentationName(args, instrumentationName) {
5178
5589
  return {
5179
5590
  ...args,
@@ -5368,12 +5779,13 @@ function applyMaskingToField(maskingFunction, data, fieldName) {
5368
5779
  var INITIAL_SPAN_WRITE_AS_MERGE = /* @__PURE__ */ Symbol(
5369
5780
  "braintrust.initial-span-write-as-merge"
5370
5781
  );
5782
+ var INTERNAL_SPAN_CONTEXT = /* @__PURE__ */ Symbol("braintrust.internal-span-context");
5371
5783
  var BRAINTRUST_CURRENT_SPAN_STORE = /* @__PURE__ */ Symbol.for(
5372
5784
  "braintrust.currentSpanStore"
5373
5785
  );
5374
5786
  var ContextManager = class {
5375
5787
  /**
5376
- * Returns the value to store in the ALS bound to a TracingChannel's start event.
5788
+ * Returns the value to store in the ALS bound to a global hook's start event.
5377
5789
  * In default mode this is the Span itself; in OTEL mode it is the OTEL Context
5378
5790
  * containing the span so that OTEL's own ALS stores a proper Context object.
5379
5791
  */
@@ -8435,6 +8847,12 @@ function _internalStartSpanWithInitialMerge(args) {
8435
8847
  [INITIAL_SPAN_WRITE_AS_MERGE]: true
8436
8848
  }).span;
8437
8849
  }
8850
+ function _internalStartSpanWithContext(args, context) {
8851
+ return startSpanAndIsLogger({
8852
+ ...args,
8853
+ [INTERNAL_SPAN_CONTEXT]: context
8854
+ }).span;
8855
+ }
8438
8856
  async function flush(options) {
8439
8857
  const state = options?.state ?? _globalState;
8440
8858
  return await state.bgLogger().flush();
@@ -9287,7 +9705,7 @@ var SpanImpl = class _SpanImpl {
9287
9705
  start: args.startTime ?? getCurrentUnixTimestamp()
9288
9706
  },
9289
9707
  context: mergeSpanOriginContext(
9290
- { ...callerLocation },
9708
+ { ...callerLocation, ...args[INTERNAL_SPAN_CONTEXT] },
9291
9709
  instrumentationName,
9292
9710
  this._state.spanOriginEnvironment
9293
9711
  ),
@@ -11129,8 +11547,8 @@ function runWithAutoInstrumentationSuppressed(callback) {
11129
11547
  callback
11130
11548
  );
11131
11549
  }
11132
- function bindAutoInstrumentationSuppressionToStart(tracingChannel2) {
11133
- const startChannel = tracingChannel2.start;
11550
+ function bindAutoInstrumentationSuppressionToStart(tracingChannel) {
11551
+ const startChannel = tracingChannel.start;
11134
11552
  if (!startChannel) {
11135
11553
  return void 0;
11136
11554
  }
@@ -11241,9 +11659,9 @@ function ensureSpanStateForEvent(states, config, event, channelName, instrumenta
11241
11659
  states.set(key, created);
11242
11660
  return created;
11243
11661
  }
11244
- function bindCurrentSpanStoreToStart(tracingChannel2, states, config, channelName, instrumentationName) {
11662
+ function bindCurrentSpanStoreToStart(tracingChannel, states, config, channelName, instrumentationName) {
11245
11663
  const state = _internalGetGlobalState();
11246
- const startChannel = tracingChannel2.start;
11664
+ const startChannel = tracingChannel.start;
11247
11665
  const contextManager = state?.contextManager;
11248
11666
  const currentSpanStore = contextManager ? contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
11249
11667
  if (!currentSpanStore || !startChannel) {
@@ -11326,11 +11744,11 @@ function runStreamingErrorHook(args) {
11326
11744
  }
11327
11745
  }
11328
11746
  function traceAsyncChannel(channel2, config) {
11329
- const tracingChannel2 = channel2.tracingChannel();
11747
+ const tracingChannel = channel2.tracingChannel();
11330
11748
  const states = /* @__PURE__ */ new WeakMap();
11331
11749
  const channelName = channel2.channelName;
11332
11750
  const unbindCurrentSpanStore = bindCurrentSpanStoreToStart(
11333
- tracingChannel2,
11751
+ tracingChannel,
11334
11752
  states,
11335
11753
  config,
11336
11754
  channelName,
@@ -11386,18 +11804,18 @@ function traceAsyncChannel(channel2, config) {
11386
11804
  logErrorAndEnd(states, event, channelName);
11387
11805
  }
11388
11806
  };
11389
- tracingChannel2.subscribe(handlers);
11807
+ tracingChannel.subscribe(handlers);
11390
11808
  return () => {
11391
11809
  unbindCurrentSpanStore?.();
11392
- tracingChannel2.unsubscribe(handlers);
11810
+ tracingChannel.unsubscribe(handlers);
11393
11811
  };
11394
11812
  }
11395
11813
  function traceStreamingChannel(channel2, config) {
11396
- const tracingChannel2 = channel2.tracingChannel();
11814
+ const tracingChannel = channel2.tracingChannel();
11397
11815
  const states = /* @__PURE__ */ new WeakMap();
11398
11816
  const channelName = channel2.channelName;
11399
11817
  const unbindCurrentSpanStore = bindCurrentSpanStoreToStart(
11400
- tracingChannel2,
11818
+ tracingChannel,
11401
11819
  states,
11402
11820
  config,
11403
11821
  channelName,
@@ -11608,18 +12026,18 @@ function traceStreamingChannel(channel2, config) {
11608
12026
  }
11609
12027
  }
11610
12028
  };
11611
- tracingChannel2.subscribe(handlers);
12029
+ tracingChannel.subscribe(handlers);
11612
12030
  return () => {
11613
12031
  unbindCurrentSpanStore?.();
11614
- tracingChannel2.unsubscribe(handlers);
12032
+ tracingChannel.unsubscribe(handlers);
11615
12033
  };
11616
12034
  }
11617
12035
  function traceSyncStreamChannel(channel2, config) {
11618
- const tracingChannel2 = channel2.tracingChannel();
12036
+ const tracingChannel = channel2.tracingChannel();
11619
12037
  const states = /* @__PURE__ */ new WeakMap();
11620
12038
  const channelName = channel2.channelName;
11621
12039
  const unbindCurrentSpanStore = bindCurrentSpanStoreToStart(
11622
- tracingChannel2,
12040
+ tracingChannel,
11623
12041
  states,
11624
12042
  config,
11625
12043
  channelName,
@@ -11732,10 +12150,10 @@ function traceSyncStreamChannel(channel2, config) {
11732
12150
  logErrorAndEnd(states, event, channelName);
11733
12151
  }
11734
12152
  };
11735
- tracingChannel2.subscribe(handlers);
12153
+ tracingChannel.subscribe(handlers);
11736
12154
  return () => {
11737
12155
  unbindCurrentSpanStore?.();
11738
- tracingChannel2.unsubscribe(handlers);
12156
+ tracingChannel.unsubscribe(handlers);
11739
12157
  };
11740
12158
  }
11741
12159
  function unsubscribeAll(unsubscribers) {
@@ -11915,7 +12333,7 @@ function defineChannels(pkg, channels, options) {
11915
12333
  const fullChannelName = `orchestrion:${pkg}:${spec.channelName}`;
11916
12334
  if (spec.kind === "async") {
11917
12335
  const asyncSpec = spec;
11918
- const tracingChannel3 = () => isomorph_default.newTracingChannel(
12336
+ const tracingChannel2 = () => isomorph_default.newTracingChannel(
11919
12337
  fullChannelName
11920
12338
  );
11921
12339
  return [
@@ -11923,8 +12341,8 @@ function defineChannels(pkg, channels, options) {
11923
12341
  {
11924
12342
  ...asyncSpec,
11925
12343
  instrumentationName,
11926
- tracingChannel: tracingChannel3,
11927
- tracePromise: (fn, context) => tracingChannel3().tracePromise(
12344
+ tracingChannel: tracingChannel2,
12345
+ tracePromise: (fn, context) => tracingChannel2().tracePromise(
11928
12346
  fn,
11929
12347
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
11930
12348
  context
@@ -11933,7 +12351,7 @@ function defineChannels(pkg, channels, options) {
11933
12351
  ];
11934
12352
  }
11935
12353
  const syncSpec = spec;
11936
- const tracingChannel2 = () => isomorph_default.newTracingChannel(
12354
+ const tracingChannel = () => isomorph_default.newTracingChannel(
11937
12355
  fullChannelName
11938
12356
  );
11939
12357
  return [
@@ -11941,8 +12359,8 @@ function defineChannels(pkg, channels, options) {
11941
12359
  {
11942
12360
  ...syncSpec,
11943
12361
  instrumentationName,
11944
- tracingChannel: tracingChannel2,
11945
- traceSync: (fn, context) => tracingChannel2().traceSync(
12362
+ tracingChannel,
12363
+ traceSync: (fn, context) => tracingChannel().traceSync(
11946
12364
  fn,
11947
12365
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
11948
12366
  context
@@ -13274,7 +13692,7 @@ var AnthropicPlugin = class extends BasePlugin {
13274
13692
  );
13275
13693
  }
13276
13694
  subscribeToAnthropicToolRunner() {
13277
- const tracingChannel2 = anthropicChannels.betaMessagesToolRunner.tracingChannel();
13695
+ const tracingChannel = anthropicChannels.betaMessagesToolRunner.tracingChannel();
13278
13696
  const states = /* @__PURE__ */ new WeakMap();
13279
13697
  const handlers = {
13280
13698
  start: (event) => {
@@ -13331,9 +13749,9 @@ var AnthropicPlugin = class extends BasePlugin {
13331
13749
  states.delete(event);
13332
13750
  }
13333
13751
  };
13334
- tracingChannel2.subscribe(handlers);
13752
+ tracingChannel.subscribe(handlers);
13335
13753
  this.unsubscribers.push(() => {
13336
- tracingChannel2.unsubscribe(handlers);
13754
+ tracingChannel.unsubscribe(handlers);
13337
13755
  });
13338
13756
  }
13339
13757
  };
@@ -14245,8 +14663,8 @@ function registerHarnessSessionParent(session, parent) {
14245
14663
  function currentHarnessTurnParent() {
14246
14664
  return harnessTurnParentStore?.getStore() ?? wrapperTurnParents.get(currentSpan());
14247
14665
  }
14248
- function bindHarnessTurnParentToStart(tracingChannel2, parentFromEvent) {
14249
- const startChannel = tracingChannel2.start;
14666
+ function bindHarnessTurnParentToStart(tracingChannel, parentFromEvent) {
14667
+ const startChannel = tracingChannel.start;
14250
14668
  if (!startChannel) {
14251
14669
  return () => {
14252
14670
  };
@@ -19712,7 +20130,7 @@ var CursorSDKPlugin = class extends BasePlugin {
19712
20130
  this.subscribeToAgentFactory(cursorSDKChannels.resume);
19713
20131
  }
19714
20132
  subscribeToAgentFactory(channel2) {
19715
- const tracingChannel2 = channel2.tracingChannel();
20133
+ const tracingChannel = channel2.tracingChannel();
19716
20134
  const handlers = {
19717
20135
  asyncEnd: (event) => {
19718
20136
  patchCursorAgentInPlace(event.result);
@@ -19720,9 +20138,9 @@ var CursorSDKPlugin = class extends BasePlugin {
19720
20138
  error: () => {
19721
20139
  }
19722
20140
  };
19723
- tracingChannel2.subscribe(handlers);
20141
+ tracingChannel.subscribe(handlers);
19724
20142
  this.unsubscribers.push(() => {
19725
- tracingChannel2.unsubscribe(handlers);
20143
+ tracingChannel.unsubscribe(handlers);
19726
20144
  });
19727
20145
  }
19728
20146
  subscribeToPrompt() {
@@ -21078,10 +21496,10 @@ var GoogleGenAIPlugin = class extends BasePlugin {
21078
21496
  this.subscribeToInteractionsCreateChannel();
21079
21497
  }
21080
21498
  subscribeToGenerateContentChannel() {
21081
- const tracingChannel2 = googleGenAIChannels.generateContent.tracingChannel();
21499
+ const tracingChannel = googleGenAIChannels.generateContent.tracingChannel();
21082
21500
  const states = /* @__PURE__ */ new WeakMap();
21083
21501
  const unbindCurrentSpanStore = bindCurrentSpanStoreToStart2(
21084
- tracingChannel2,
21502
+ tracingChannel,
21085
21503
  states,
21086
21504
  (event) => {
21087
21505
  const params = event.arguments[0];
@@ -21155,14 +21573,14 @@ var GoogleGenAIPlugin = class extends BasePlugin {
21155
21573
  logErrorAndEndSpan(states, event);
21156
21574
  }
21157
21575
  };
21158
- tracingChannel2.subscribe(handlers);
21576
+ tracingChannel.subscribe(handlers);
21159
21577
  this.unsubscribers.push(() => {
21160
21578
  unbindCurrentSpanStore?.();
21161
- tracingChannel2.unsubscribe(handlers);
21579
+ tracingChannel.unsubscribe(handlers);
21162
21580
  });
21163
21581
  }
21164
21582
  subscribeToGenerateContentStreamChannel() {
21165
- const tracingChannel2 = googleGenAIChannels.generateContentStream.tracingChannel();
21583
+ const tracingChannel = googleGenAIChannels.generateContentStream.tracingChannel();
21166
21584
  const handlers = {
21167
21585
  start: (event) => {
21168
21586
  const streamEvent = event;
@@ -21183,16 +21601,16 @@ var GoogleGenAIPlugin = class extends BasePlugin {
21183
21601
  error: () => {
21184
21602
  }
21185
21603
  };
21186
- tracingChannel2.subscribe(handlers);
21604
+ tracingChannel.subscribe(handlers);
21187
21605
  this.unsubscribers.push(() => {
21188
- tracingChannel2.unsubscribe(handlers);
21606
+ tracingChannel.unsubscribe(handlers);
21189
21607
  });
21190
21608
  }
21191
21609
  subscribeToEmbedContentChannel() {
21192
- const tracingChannel2 = googleGenAIChannels.embedContent.tracingChannel();
21610
+ const tracingChannel = googleGenAIChannels.embedContent.tracingChannel();
21193
21611
  const states = /* @__PURE__ */ new WeakMap();
21194
21612
  const unbindCurrentSpanStore = bindCurrentSpanStoreToStart2(
21195
- tracingChannel2,
21613
+ tracingChannel,
21196
21614
  states,
21197
21615
  (event) => {
21198
21616
  const params = event.arguments[0];
@@ -21262,10 +21680,10 @@ var GoogleGenAIPlugin = class extends BasePlugin {
21262
21680
  logErrorAndEndSpan(states, event);
21263
21681
  }
21264
21682
  };
21265
- tracingChannel2.subscribe(handlers);
21683
+ tracingChannel.subscribe(handlers);
21266
21684
  this.unsubscribers.push(() => {
21267
21685
  unbindCurrentSpanStore?.();
21268
- tracingChannel2.unsubscribe(handlers);
21686
+ tracingChannel.unsubscribe(handlers);
21269
21687
  });
21270
21688
  }
21271
21689
  subscribeToInteractionsCreateChannel() {
@@ -21301,10 +21719,10 @@ function ensureSpanState(states, event, create) {
21301
21719
  states.set(event, created);
21302
21720
  return created;
21303
21721
  }
21304
- function bindCurrentSpanStoreToStart2(tracingChannel2, states, create) {
21722
+ function bindCurrentSpanStoreToStart2(tracingChannel, states, create) {
21305
21723
  const state = _internalGetGlobalState();
21306
21724
  const contextManager = state?.contextManager;
21307
- const startChannel = tracingChannel2.start;
21725
+ const startChannel = tracingChannel.start;
21308
21726
  const currentSpanStore = contextManager ? contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
21309
21727
  if (!startChannel?.bindStore || !currentSpanStore) {
21310
21728
  return void 0;
@@ -21807,11 +22225,11 @@ function summarizeEmbedContentOutput(response) {
21807
22225
  };
21808
22226
  }
21809
22227
  function populateUsageMetrics(metrics, usage) {
21810
- if (usage.promptTokenCount !== void 0) {
21811
- metrics.prompt_tokens = usage.promptTokenCount;
22228
+ if (usage.promptTokenCount !== void 0 || usage.toolUsePromptTokenCount !== void 0) {
22229
+ metrics.prompt_tokens = (usage.promptTokenCount ?? 0) + (usage.toolUsePromptTokenCount ?? 0);
21812
22230
  }
21813
- if (usage.candidatesTokenCount !== void 0) {
21814
- metrics.completion_tokens = usage.candidatesTokenCount;
22231
+ if (usage.candidatesTokenCount !== void 0 || usage.thoughtsTokenCount !== void 0) {
22232
+ metrics.completion_tokens = (usage.candidatesTokenCount ?? 0) + (usage.thoughtsTokenCount ?? 0);
21815
22233
  }
21816
22234
  if (usage.totalTokenCount !== void 0) {
21817
22235
  metrics.tokens = usage.totalTokenCount;
@@ -21822,13 +22240,26 @@ function populateUsageMetrics(metrics, usage) {
21822
22240
  if (usage.thoughtsTokenCount !== void 0) {
21823
22241
  metrics.completion_reasoning_tokens = usage.thoughtsTokenCount;
21824
22242
  }
22243
+ for (const detail of usage.promptTokensDetails ?? []) {
22244
+ if (detail.modality === "AUDIO" && detail.tokenCount !== void 0) {
22245
+ metrics.prompt_audio_tokens = (metrics.prompt_audio_tokens ?? 0) + detail.tokenCount;
22246
+ }
22247
+ }
22248
+ for (const detail of usage.candidatesTokensDetails ?? []) {
22249
+ if (detail.modality === "AUDIO" && detail.tokenCount !== void 0) {
22250
+ metrics.completion_audio_tokens = (metrics.completion_audio_tokens ?? 0) + detail.tokenCount;
22251
+ }
22252
+ if (detail.modality === "IMAGE" && detail.tokenCount !== void 0) {
22253
+ metrics.completion_image_tokens = (metrics.completion_image_tokens ?? 0) + detail.tokenCount;
22254
+ }
22255
+ }
21825
22256
  }
21826
22257
  function populateInteractionUsageMetrics(metrics, usage) {
21827
22258
  if (typeof usage.total_input_tokens === "number") {
21828
22259
  metrics.prompt_tokens = usage.total_input_tokens;
21829
22260
  }
21830
22261
  if (typeof usage.total_output_tokens === "number") {
21831
- metrics.completion_tokens = usage.total_output_tokens;
22262
+ metrics.completion_tokens = usage.total_output_tokens + (typeof usage.total_thought_tokens === "number" ? usage.total_thought_tokens : 0);
21832
22263
  }
21833
22264
  if (typeof usage.total_tokens === "number") {
21834
22265
  metrics.tokens = usage.total_tokens;
@@ -21839,6 +22270,24 @@ function populateInteractionUsageMetrics(metrics, usage) {
21839
22270
  if (typeof usage.total_thought_tokens === "number") {
21840
22271
  metrics.completion_reasoning_tokens = usage.total_thought_tokens;
21841
22272
  }
22273
+ for (const detail of Array.isArray(usage.input_tokens_by_modality) ? usage.input_tokens_by_modality : []) {
22274
+ if (typeof detail?.modality === "string" && detail.modality.toLowerCase() === "audio" && typeof detail.tokens === "number") {
22275
+ metrics.prompt_audio_tokens = (metrics.prompt_audio_tokens ?? 0) + detail.tokens;
22276
+ }
22277
+ }
22278
+ for (const detail of Array.isArray(usage.output_tokens_by_modality) ? usage.output_tokens_by_modality : []) {
22279
+ if (typeof detail?.modality !== "string" || typeof detail.tokens !== "number") {
22280
+ continue;
22281
+ }
22282
+ switch (detail.modality.toLowerCase()) {
22283
+ case "audio":
22284
+ metrics.completion_audio_tokens = (metrics.completion_audio_tokens ?? 0) + detail.tokens;
22285
+ break;
22286
+ case "image":
22287
+ metrics.completion_image_tokens = (metrics.completion_image_tokens ?? 0) + detail.tokens;
22288
+ break;
22289
+ }
22290
+ }
21842
22291
  }
21843
22292
  function aggregateGenerateContentChunks(chunks, startTime, firstTokenTime) {
21844
22293
  const end = getCurrentUnixTimestamp();
@@ -22577,6 +23026,299 @@ function extractTextGenerationStreamMetadata(chunks) {
22577
23026
  return void 0;
22578
23027
  }
22579
23028
 
23029
+ // src/instrumentation/plugins/huggingface-transformers-channels.ts
23030
+ var SUPPORTED_TASKS = /* @__PURE__ */ new Set([
23031
+ "text-generation",
23032
+ "text2text-generation",
23033
+ "summarization",
23034
+ "feature-extraction",
23035
+ "question-answering"
23036
+ ]);
23037
+ var pipelineInfo = /* @__PURE__ */ new WeakMap();
23038
+ function isSupportedHuggingFaceTransformersTask(task) {
23039
+ return typeof task === "string" && SUPPORTED_TASKS.has(task);
23040
+ }
23041
+ function registerHuggingFaceTransformersPipeline(pipeline, task, model) {
23042
+ if (typeof task !== "string") {
23043
+ return;
23044
+ }
23045
+ const info = { task };
23046
+ if (typeof model === "string") {
23047
+ info.model = model;
23048
+ }
23049
+ pipelineInfo.set(pipeline, info);
23050
+ }
23051
+ function getHuggingFaceTransformersPipelineInfo(pipeline) {
23052
+ return pipeline ? pipelineInfo.get(pipeline) : void 0;
23053
+ }
23054
+ var huggingFaceTransformersChannels = defineChannels(
23055
+ "@huggingface/transformers",
23056
+ {
23057
+ pipeline: channel({
23058
+ channelName: "pipeline",
23059
+ kind: "async"
23060
+ }),
23061
+ pipelineCall: channel({
23062
+ channelName: "pipeline.call",
23063
+ kind: "async"
23064
+ })
23065
+ },
23066
+ { instrumentationName: INSTRUMENTATION_NAMES.HUGGINGFACE }
23067
+ );
23068
+
23069
+ // src/instrumentation/plugins/huggingface-transformers-plugin.ts
23070
+ var REQUEST_METADATA_KEYS = [
23071
+ "temperature",
23072
+ "top_p",
23073
+ "max_tokens",
23074
+ "stop"
23075
+ ];
23076
+ var HuggingFaceTransformersPlugin = class extends BasePlugin {
23077
+ onEnable() {
23078
+ this.subscribeToPipelineFactory();
23079
+ this.unsubscribers.push(
23080
+ traceAsyncChannel(huggingFaceTransformersChannels.pipelineCall, {
23081
+ name: (_args, event) => {
23082
+ const task = getTask(event);
23083
+ const operation = task?.replaceAll("-", "_") ?? "unknown";
23084
+ return `huggingface.transformers.${operation}`;
23085
+ },
23086
+ type: "llm" /* LLM */,
23087
+ shouldTrace: (_args, event) => isSupportedHuggingFaceTransformersTask(
23088
+ getTask(event)
23089
+ ),
23090
+ extractInput: (args, event) => ({
23091
+ input: extractInput(
23092
+ getTask(event),
23093
+ args
23094
+ ),
23095
+ metadata: extractMetadata(
23096
+ event,
23097
+ args
23098
+ )
23099
+ }),
23100
+ extractOutput: (result, event) => extractOutput(
23101
+ getTask(event),
23102
+ result
23103
+ ),
23104
+ extractMetrics: () => ({})
23105
+ })
23106
+ );
23107
+ }
23108
+ onDisable() {
23109
+ this.unsubscribers = unsubscribeAll(this.unsubscribers);
23110
+ }
23111
+ subscribeToPipelineFactory() {
23112
+ const channel2 = huggingFaceTransformersChannels.pipeline.tracingChannel();
23113
+ const handlers = {
23114
+ asyncEnd: (event) => {
23115
+ if (typeof event.result !== "function") {
23116
+ return;
23117
+ }
23118
+ registerHuggingFaceTransformersPipeline(
23119
+ event.result,
23120
+ event.arguments?.[0],
23121
+ event.arguments?.[1]
23122
+ );
23123
+ }
23124
+ };
23125
+ channel2.subscribe(handlers);
23126
+ this.unsubscribers.push(() => channel2.unsubscribe(handlers));
23127
+ }
23128
+ };
23129
+ function getTask(event) {
23130
+ const self = event.self;
23131
+ const registeredTask = getHuggingFaceTransformersPipelineInfo(self)?.task;
23132
+ if (registeredTask !== void 0) {
23133
+ return registeredTask;
23134
+ }
23135
+ if (typeof self?.task === "string") {
23136
+ return self.task;
23137
+ }
23138
+ return void 0;
23139
+ }
23140
+ function extractMetadata(event, args) {
23141
+ const metadata = {
23142
+ provider: "huggingface"
23143
+ };
23144
+ const registeredModel = getHuggingFaceTransformersPipelineInfo(
23145
+ event.self
23146
+ )?.model;
23147
+ const model = registeredModel ?? modelIdentifier(event.self);
23148
+ if (model) {
23149
+ metadata.model = model;
23150
+ }
23151
+ const task = getTask(event);
23152
+ const options = task === "question-answering" ? args[2] : args[1];
23153
+ if (isObject(options)) {
23154
+ for (const key of REQUEST_METADATA_KEYS) {
23155
+ if (options[key] !== void 0) {
23156
+ metadata[key] = options[key];
23157
+ }
23158
+ }
23159
+ }
23160
+ return metadata;
23161
+ }
23162
+ function modelIdentifier(pipeline) {
23163
+ const model = pipeline?.model;
23164
+ if (!isObject(model)) {
23165
+ return void 0;
23166
+ }
23167
+ const config = isObject(model.config) ? model.config : void 0;
23168
+ for (const value of [
23169
+ config?._name_or_path,
23170
+ config?.name_or_path,
23171
+ config?.model_id,
23172
+ config?.modelId,
23173
+ model.name
23174
+ ]) {
23175
+ if (typeof value === "string" && value.length > 0) {
23176
+ return value;
23177
+ }
23178
+ }
23179
+ return void 0;
23180
+ }
23181
+ function extractInput(task, args) {
23182
+ switch (task) {
23183
+ case "feature-extraction":
23184
+ return args[0];
23185
+ case "question-answering": {
23186
+ const question = args[0];
23187
+ const context = args[1];
23188
+ if (Array.isArray(question) && Array.isArray(context) && question.every((value) => typeof value === "string") && context.every((value) => typeof value === "string")) {
23189
+ return question.map((value, index) => [
23190
+ {
23191
+ role: "user",
23192
+ content: `Context:
23193
+ ${context[index] ?? ""}
23194
+
23195
+ Question:
23196
+ ${value}`
23197
+ }
23198
+ ]);
23199
+ }
23200
+ if (typeof question === "string" && typeof context === "string") {
23201
+ return [
23202
+ {
23203
+ role: "user",
23204
+ content: `Context:
23205
+ ${context}
23206
+
23207
+ Question:
23208
+ ${question}`
23209
+ }
23210
+ ];
23211
+ }
23212
+ return { context, question };
23213
+ }
23214
+ }
23215
+ const input = args[0];
23216
+ if (task === "text-generation" && isChat(input)) {
23217
+ return input;
23218
+ }
23219
+ if (task === "text-generation" && Array.isArray(input) && input.every(isChat)) {
23220
+ return input;
23221
+ }
23222
+ if (typeof input === "string") {
23223
+ return [{ role: "user", content: input }];
23224
+ }
23225
+ if (Array.isArray(input) && input.every((value) => typeof value === "string")) {
23226
+ return input.map((value) => [
23227
+ {
23228
+ role: "user",
23229
+ content: value
23230
+ }
23231
+ ]);
23232
+ }
23233
+ return input;
23234
+ }
23235
+ function isChat(value) {
23236
+ return Array.isArray(value) && value.length > 0 && value.every(
23237
+ (message) => isObject(message) && typeof message.role === "string" && "content" in message
23238
+ );
23239
+ }
23240
+ function extractOutput(task, result) {
23241
+ switch (task) {
23242
+ case "feature-extraction":
23243
+ return summarizeEmbedding(result);
23244
+ case "question-answering":
23245
+ return choicesFromAnswers(result);
23246
+ default:
23247
+ return choicesFromGenerations(result);
23248
+ }
23249
+ }
23250
+ function summarizeEmbedding(result) {
23251
+ if (!isObject(result) || !Array.isArray(result.dims)) {
23252
+ return void 0;
23253
+ }
23254
+ const { dims } = result;
23255
+ if (dims.length === 0 || !dims.every((dimension) => typeof dimension === "number")) {
23256
+ return void 0;
23257
+ }
23258
+ if (dims.length === 1) {
23259
+ return { embedding_length: dims[0] };
23260
+ }
23261
+ if (dims.length === 2) {
23262
+ return {
23263
+ embedding_count: dims[0],
23264
+ embedding_length: dims[1]
23265
+ };
23266
+ }
23267
+ return {
23268
+ embedding_batch_count: dims[0],
23269
+ embedding_count: dims[1],
23270
+ embedding_length: dims.at(-1) ?? 0
23271
+ };
23272
+ }
23273
+ function choicesFromAnswers(result) {
23274
+ const answers = Array.isArray(result) ? result.flat() : [result];
23275
+ const choices = answers.flatMap((answer, index) => {
23276
+ if (!isObject(answer) || typeof answer.answer !== "string") {
23277
+ return [];
23278
+ }
23279
+ return [
23280
+ {
23281
+ index,
23282
+ finish_reason: "stop",
23283
+ message: {
23284
+ role: "assistant",
23285
+ content: answer.answer
23286
+ }
23287
+ }
23288
+ ];
23289
+ });
23290
+ return choices.length > 0 ? choices : void 0;
23291
+ }
23292
+ function choicesFromGenerations(result) {
23293
+ const generations = Array.isArray(result) ? result.flat() : [result];
23294
+ const choices = generations.flatMap((generation, index) => {
23295
+ if (!isObject(generation)) {
23296
+ return [];
23297
+ }
23298
+ const generated = generation.generated_text ?? generation.summary_text;
23299
+ let content;
23300
+ if (typeof generated === "string") {
23301
+ content = generated;
23302
+ } else if (isChat(generated)) {
23303
+ content = generated.at(-1)?.content;
23304
+ }
23305
+ if (typeof content !== "string") {
23306
+ return [];
23307
+ }
23308
+ return [
23309
+ {
23310
+ index,
23311
+ finish_reason: "stop",
23312
+ message: {
23313
+ role: "assistant",
23314
+ content
23315
+ }
23316
+ }
23317
+ ];
23318
+ });
23319
+ return choices.length > 0 ? choices : void 0;
23320
+ }
23321
+
22580
23322
  // src/instrumentation/plugins/openrouter-agent-channels.ts
22581
23323
  var openRouterAgentChannels = defineChannels(
22582
23324
  "@openrouter/agent",
@@ -22976,7 +23718,7 @@ function isWrappedTool(tool) {
22976
23718
  return Boolean(tool[OPENROUTER_WRAPPED_TOOL]);
22977
23719
  }
22978
23720
  function traceToolExecution(args) {
22979
- const tracingChannel2 = openRouterAgentChannels.toolExecute.tracingChannel();
23721
+ const tracingChannel = openRouterAgentChannels.toolExecute.tracingChannel();
22980
23722
  const input = args.args.length > 0 ? args.args[0] : void 0;
22981
23723
  const event = {
22982
23724
  arguments: [input],
@@ -22986,33 +23728,33 @@ function traceToolExecution(args) {
22986
23728
  toolCallId: args.toolCallId,
22987
23729
  toolName: args.toolName
22988
23730
  };
22989
- tracingChannel2.start.publish(event);
23731
+ tracingChannel.start.publish(event);
22990
23732
  try {
22991
23733
  const result = args.execute();
22992
- return publishToolResult(tracingChannel2, event, result);
23734
+ return publishToolResult(tracingChannel, event, result);
22993
23735
  } catch (error) {
22994
23736
  event.error = normalizeError(error);
22995
- tracingChannel2.error.publish(event);
23737
+ tracingChannel.error.publish(event);
22996
23738
  throw error;
22997
23739
  }
22998
23740
  }
22999
- function publishToolResult(tracingChannel2, event, result) {
23741
+ function publishToolResult(tracingChannel, event, result) {
23000
23742
  if (isPromiseLike(result)) {
23001
23743
  return result.then(
23002
23744
  (resolved) => {
23003
23745
  event.result = resolved;
23004
- tracingChannel2.asyncEnd.publish(event);
23746
+ tracingChannel.asyncEnd.publish(event);
23005
23747
  return resolved;
23006
23748
  },
23007
23749
  (error) => {
23008
23750
  event.error = normalizeError(error);
23009
- tracingChannel2.error.publish(event);
23751
+ tracingChannel.error.publish(event);
23010
23752
  throw error;
23011
23753
  }
23012
23754
  );
23013
23755
  }
23014
23756
  event.result = result;
23015
- tracingChannel2.asyncEnd.publish(event);
23757
+ tracingChannel.asyncEnd.publish(event);
23016
23758
  return result;
23017
23759
  }
23018
23760
  function getToolCallId(context) {
@@ -23918,7 +24660,7 @@ function isWrappedTool2(tool) {
23918
24660
  return Boolean(tool[OPENROUTER_WRAPPED_TOOL2]);
23919
24661
  }
23920
24662
  function traceToolExecution2(args) {
23921
- const tracingChannel2 = openRouterChannels.toolExecute.tracingChannel();
24663
+ const tracingChannel = openRouterChannels.toolExecute.tracingChannel();
23922
24664
  const input = args.args.length > 0 ? args.args[0] : void 0;
23923
24665
  const event = {
23924
24666
  arguments: [input],
@@ -23928,33 +24670,33 @@ function traceToolExecution2(args) {
23928
24670
  toolCallId: args.toolCallId,
23929
24671
  toolName: args.toolName
23930
24672
  };
23931
- tracingChannel2.start.publish(event);
24673
+ tracingChannel.start.publish(event);
23932
24674
  try {
23933
24675
  const result = args.execute();
23934
- return publishToolResult2(tracingChannel2, event, result);
24676
+ return publishToolResult2(tracingChannel, event, result);
23935
24677
  } catch (error) {
23936
24678
  event.error = normalizeError2(error);
23937
- tracingChannel2.error.publish(event);
24679
+ tracingChannel.error.publish(event);
23938
24680
  throw error;
23939
24681
  }
23940
24682
  }
23941
- function publishToolResult2(tracingChannel2, event, result) {
24683
+ function publishToolResult2(tracingChannel, event, result) {
23942
24684
  if (isPromiseLike(result)) {
23943
24685
  return result.then(
23944
24686
  (resolved) => {
23945
24687
  event.result = resolved;
23946
- tracingChannel2.asyncEnd.publish(event);
24688
+ tracingChannel.asyncEnd.publish(event);
23947
24689
  return resolved;
23948
24690
  },
23949
24691
  (error) => {
23950
24692
  event.error = normalizeError2(error);
23951
- tracingChannel2.error.publish(event);
24693
+ tracingChannel.error.publish(event);
23952
24694
  throw error;
23953
24695
  }
23954
24696
  );
23955
24697
  }
23956
24698
  event.result = result;
23957
- tracingChannel2.asyncEnd.publish(event);
24699
+ tracingChannel.asyncEnd.publish(event);
23958
24700
  return result;
23959
24701
  }
23960
24702
  function getToolCallId2(context) {
@@ -25144,7 +25886,7 @@ var GoogleADKPlugin = class extends BasePlugin {
25144
25886
  this.activeAgentSpans.clear();
25145
25887
  }
25146
25888
  subscribeToRunnerRunAsync() {
25147
- const tracingChannel2 = googleADKChannels.runnerRunAsync.tracingChannel();
25889
+ const tracingChannel = googleADKChannels.runnerRunAsync.tracingChannel();
25148
25890
  const states = /* @__PURE__ */ new WeakMap();
25149
25891
  const createState = (event) => {
25150
25892
  const params = event.arguments[0] ?? {};
@@ -25175,7 +25917,7 @@ var GoogleADKPlugin = class extends BasePlugin {
25175
25917
  return { span, startTime, events: [], contextKey };
25176
25918
  };
25177
25919
  const unbindCurrentSpanStore = bindCurrentSpanStoreToStart3(
25178
- tracingChannel2,
25920
+ tracingChannel,
25179
25921
  states,
25180
25922
  createState
25181
25923
  );
@@ -25227,14 +25969,14 @@ var GoogleADKPlugin = class extends BasePlugin {
25227
25969
  states.delete(event);
25228
25970
  }
25229
25971
  };
25230
- tracingChannel2.subscribe(handlers);
25972
+ tracingChannel.subscribe(handlers);
25231
25973
  this.unsubscribers.push(() => {
25232
25974
  unbindCurrentSpanStore?.();
25233
- tracingChannel2.unsubscribe(handlers);
25975
+ tracingChannel.unsubscribe(handlers);
25234
25976
  });
25235
25977
  }
25236
25978
  subscribeToAgentRunAsync() {
25237
- const tracingChannel2 = googleADKChannels.agentRunAsync.tracingChannel();
25979
+ const tracingChannel = googleADKChannels.agentRunAsync.tracingChannel();
25238
25980
  const states = /* @__PURE__ */ new WeakMap();
25239
25981
  const createState = (event) => {
25240
25982
  const parentContext = event.arguments[0];
@@ -25283,7 +26025,7 @@ var GoogleADKPlugin = class extends BasePlugin {
25283
26025
  return { span, startTime, events: [], contextKey, name: agentName };
25284
26026
  };
25285
26027
  const unbindCurrentSpanStore = bindCurrentSpanStoreToStart3(
25286
- tracingChannel2,
26028
+ tracingChannel,
25287
26029
  states,
25288
26030
  createState
25289
26031
  );
@@ -25335,14 +26077,14 @@ var GoogleADKPlugin = class extends BasePlugin {
25335
26077
  states.delete(event);
25336
26078
  }
25337
26079
  };
25338
- tracingChannel2.subscribe(handlers);
26080
+ tracingChannel.subscribe(handlers);
25339
26081
  this.unsubscribers.push(() => {
25340
26082
  unbindCurrentSpanStore?.();
25341
- tracingChannel2.unsubscribe(handlers);
26083
+ tracingChannel.unsubscribe(handlers);
25342
26084
  });
25343
26085
  }
25344
26086
  subscribeToToolRunAsync() {
25345
- const tracingChannel2 = googleADKChannels.toolRunAsync.tracingChannel();
26087
+ const tracingChannel = googleADKChannels.toolRunAsync.tracingChannel();
25346
26088
  const states = /* @__PURE__ */ new WeakMap();
25347
26089
  const handlers = {
25348
26090
  start: (event) => {
@@ -25409,9 +26151,9 @@ var GoogleADKPlugin = class extends BasePlugin {
25409
26151
  states.delete(event);
25410
26152
  }
25411
26153
  };
25412
- tracingChannel2.subscribe(handlers);
26154
+ tracingChannel.subscribe(handlers);
25413
26155
  this.unsubscribers.push(() => {
25414
- tracingChannel2.unsubscribe(handlers);
26156
+ tracingChannel.unsubscribe(handlers);
25415
26157
  });
25416
26158
  }
25417
26159
  };
@@ -25487,10 +26229,10 @@ function bindAsyncIterableToCurrentSpan(stream, span) {
25487
26229
  }
25488
26230
  return stream;
25489
26231
  }
25490
- function bindCurrentSpanStoreToStart3(tracingChannel2, states, create) {
26232
+ function bindCurrentSpanStoreToStart3(tracingChannel, states, create) {
25491
26233
  const state = _internalGetGlobalState();
25492
26234
  const contextManager = state?.contextManager;
25493
- const startChannel = tracingChannel2.start;
26235
+ const startChannel = tracingChannel.start;
25494
26236
  const currentSpanStore = contextManager ? contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
25495
26237
  if (!startChannel?.bindStore || !currentSpanStore) {
25496
26238
  return void 0;
@@ -25742,15 +26484,32 @@ function aggregateUsageFromEvents(events) {
25742
26484
  if (usage.thoughtsTokenCount !== void 0) {
25743
26485
  aggregated.thoughtsTokenCount = (aggregated.thoughtsTokenCount ?? 0) + usage.thoughtsTokenCount;
25744
26486
  }
26487
+ if (usage.toolUsePromptTokenCount !== void 0) {
26488
+ aggregated.toolUsePromptTokenCount = (aggregated.toolUsePromptTokenCount ?? 0) + usage.toolUsePromptTokenCount;
26489
+ }
26490
+ for (const detailsField of [
26491
+ "promptTokensDetails",
26492
+ "cacheTokensDetails",
26493
+ "candidatesTokensDetails",
26494
+ "toolUsePromptTokensDetails"
26495
+ ]) {
26496
+ const details = usage[detailsField];
26497
+ if (details !== void 0) {
26498
+ aggregated[detailsField] = [
26499
+ ...aggregated[detailsField] ?? [],
26500
+ ...details
26501
+ ];
26502
+ }
26503
+ }
25745
26504
  }
25746
26505
  return hasUsage ? aggregated : void 0;
25747
26506
  }
25748
26507
  function populateUsageMetrics2(metrics, usage) {
25749
- if (usage.promptTokenCount !== void 0) {
25750
- metrics.prompt_tokens = usage.promptTokenCount;
26508
+ if (usage.promptTokenCount !== void 0 || usage.toolUsePromptTokenCount !== void 0) {
26509
+ metrics.prompt_tokens = (usage.promptTokenCount ?? 0) + (usage.toolUsePromptTokenCount ?? 0);
25751
26510
  }
25752
- if (usage.candidatesTokenCount !== void 0) {
25753
- metrics.completion_tokens = usage.candidatesTokenCount;
26511
+ if (usage.candidatesTokenCount !== void 0 || usage.thoughtsTokenCount !== void 0) {
26512
+ metrics.completion_tokens = (usage.candidatesTokenCount ?? 0) + (usage.thoughtsTokenCount ?? 0);
25754
26513
  }
25755
26514
  if (usage.totalTokenCount !== void 0) {
25756
26515
  metrics.tokens = usage.totalTokenCount;
@@ -25761,6 +26520,19 @@ function populateUsageMetrics2(metrics, usage) {
25761
26520
  if (usage.thoughtsTokenCount !== void 0) {
25762
26521
  metrics.completion_reasoning_tokens = usage.thoughtsTokenCount;
25763
26522
  }
26523
+ for (const detail of usage.promptTokensDetails ?? []) {
26524
+ if (detail.modality === "AUDIO" && detail.tokenCount !== void 0) {
26525
+ metrics.prompt_audio_tokens = (metrics.prompt_audio_tokens ?? 0) + detail.tokenCount;
26526
+ }
26527
+ }
26528
+ for (const detail of usage.candidatesTokensDetails ?? []) {
26529
+ if (detail.modality === "AUDIO" && detail.tokenCount !== void 0) {
26530
+ metrics.completion_audio_tokens = (metrics.completion_audio_tokens ?? 0) + detail.tokenCount;
26531
+ }
26532
+ if (detail.modality === "IMAGE" && detail.tokenCount !== void 0) {
26533
+ metrics.completion_image_tokens = (metrics.completion_image_tokens ?? 0) + detail.tokenCount;
26534
+ }
26535
+ }
25764
26536
  }
25765
26537
  function cleanMetrics4(metrics) {
25766
26538
  const cleaned = {};
@@ -27326,10 +28098,10 @@ var GenkitPlugin = class extends BasePlugin {
27326
28098
  this.subscribeToActionStream();
27327
28099
  }
27328
28100
  subscribeToActionRun() {
27329
- const tracingChannel2 = genkitChannels.actionRun.tracingChannel();
28101
+ const tracingChannel = genkitChannels.actionRun.tracingChannel();
27330
28102
  const states = /* @__PURE__ */ new WeakMap();
27331
28103
  const unbindCurrentSpanStore = bindActionCurrentSpanStoreToStart(
27332
- tracingChannel2,
28104
+ tracingChannel,
27333
28105
  states,
27334
28106
  (event) => startActionRunSpan(event)
27335
28107
  );
@@ -27366,17 +28138,17 @@ var GenkitPlugin = class extends BasePlugin {
27366
28138
  states.delete(event);
27367
28139
  }
27368
28140
  };
27369
- tracingChannel2.subscribe(handlers);
28141
+ tracingChannel.subscribe(handlers);
27370
28142
  this.unsubscribers.push(() => {
27371
28143
  unbindCurrentSpanStore?.();
27372
- tracingChannel2.unsubscribe(handlers);
28144
+ tracingChannel.unsubscribe(handlers);
27373
28145
  });
27374
28146
  }
27375
28147
  subscribeToActionSpan() {
27376
- const tracingChannel2 = genkitCoreChannels.actionSpan.tracingChannel();
28148
+ const tracingChannel = genkitCoreChannels.actionSpan.tracingChannel();
27377
28149
  const states = /* @__PURE__ */ new WeakMap();
27378
28150
  const unbindCurrentSpanStore = bindActionCurrentSpanStoreToStart(
27379
- tracingChannel2,
28151
+ tracingChannel,
27380
28152
  states,
27381
28153
  (event) => startActionSpan(event)
27382
28154
  );
@@ -27414,10 +28186,10 @@ var GenkitPlugin = class extends BasePlugin {
27414
28186
  states.delete(event);
27415
28187
  }
27416
28188
  };
27417
- tracingChannel2.subscribe(handlers);
28189
+ tracingChannel.subscribe(handlers);
27418
28190
  this.unsubscribers.push(() => {
27419
28191
  unbindCurrentSpanStore?.();
27420
- tracingChannel2.unsubscribe(handlers);
28192
+ tracingChannel.unsubscribe(handlers);
27421
28193
  });
27422
28194
  }
27423
28195
  subscribeToActionStream() {
@@ -27486,10 +28258,10 @@ function ensureActionSpanState(states, event, create) {
27486
28258
  }
27487
28259
  return created;
27488
28260
  }
27489
- function bindActionCurrentSpanStoreToStart(tracingChannel2, states, create) {
28261
+ function bindActionCurrentSpanStoreToStart(tracingChannel, states, create) {
27490
28262
  const state = _internalGetGlobalState();
27491
28263
  const contextManager = state?.contextManager;
27492
- const startChannel = tracingChannel2.start;
28264
+ const startChannel = tracingChannel.start;
27493
28265
  const currentSpanStore = contextManager ? contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
27494
28266
  if (!startChannel?.bindStore || !currentSpanStore) {
27495
28267
  return void 0;
@@ -29851,7 +30623,7 @@ var LangChainPlugin = class extends BasePlugin {
29851
30623
  this.injectedManagers = /* @__PURE__ */ new WeakSet();
29852
30624
  }
29853
30625
  subscribeToConfigure(channel2) {
29854
- const tracingChannel2 = channel2.tracingChannel();
30626
+ const tracingChannel = channel2.tracingChannel();
29855
30627
  const handlers = {
29856
30628
  start: (event) => {
29857
30629
  injectHandlerIntoArguments(event.arguments);
@@ -29860,9 +30632,9 @@ var LangChainPlugin = class extends BasePlugin {
29860
30632
  this.injectHandler(event.result);
29861
30633
  }
29862
30634
  };
29863
- tracingChannel2.subscribe(handlers);
30635
+ tracingChannel.subscribe(handlers);
29864
30636
  this.unsubscribers.push(() => {
29865
- tracingChannel2.unsubscribe(handlers);
30637
+ tracingChannel.unsubscribe(handlers);
29866
30638
  });
29867
30639
  }
29868
30640
  injectHandler(result) {
@@ -30126,7 +30898,7 @@ var LangSmithPlugin = class extends BasePlugin {
30126
30898
  const inputs = preferOwnValue(run, previous, "inputs");
30127
30899
  const outputs = preferOwnValue(run, previous, "outputs");
30128
30900
  const error = errorMessage(preferOwnValue(run, previous, "error"));
30129
- const metadata = extractMetadata(run, previous);
30901
+ const metadata = extractMetadata2(run, previous);
30130
30902
  const tags = extractTags(preferOwnValue(run, previous, "tags"));
30131
30903
  const metrics = extractMetrics(run, previous);
30132
30904
  span.log({
@@ -30231,7 +31003,7 @@ function mapRunType(runType) {
30231
31003
  return "task" /* TASK */;
30232
31004
  }
30233
31005
  }
30234
- function extractMetadata(run, previous) {
31006
+ function extractMetadata2(run, previous) {
30235
31007
  const extra = preferOwnValue(run, previous, "extra");
30236
31008
  const rawMetadata = ownValue(extra, "metadata");
30237
31009
  if (!isRecord2(rawMetadata)) {
@@ -31362,9 +32134,9 @@ var StrandsAgentSDKPlugin = class extends BasePlugin {
31362
32134
  });
31363
32135
  }
31364
32136
  subscribeToMultiAgentStream(channel2, operation) {
31365
- const tracingChannel2 = channel2.tracingChannel();
32137
+ const tracingChannel = channel2.tracingChannel();
31366
32138
  const states = /* @__PURE__ */ new WeakMap();
31367
- const unbindAutoInstrumentationSuppression = bindAutoInstrumentationSuppressionToStart(tracingChannel2);
32139
+ const unbindAutoInstrumentationSuppression = bindAutoInstrumentationSuppressionToStart(tracingChannel);
31368
32140
  const handlers = {
31369
32141
  start: (event) => {
31370
32142
  const state = startMultiAgentStream(
@@ -31418,10 +32190,10 @@ var StrandsAgentSDKPlugin = class extends BasePlugin {
31418
32190
  states.delete(event);
31419
32191
  }
31420
32192
  };
31421
- tracingChannel2.subscribe(handlers);
32193
+ tracingChannel.subscribe(handlers);
31422
32194
  this.unsubscribers.push(() => {
31423
32195
  unbindAutoInstrumentationSuppression?.();
31424
- tracingChannel2.unsubscribe(handlers);
32196
+ tracingChannel.unsubscribe(handlers);
31425
32197
  });
31426
32198
  }
31427
32199
  };
@@ -31604,6 +32376,15 @@ function handleMultiAgentStreamEvent(state, event, activeChildParents) {
31604
32376
  logInstrumentationError5("Strands Agent SDK multi-agent event", error);
31605
32377
  }
31606
32378
  }
32379
+ function buildModelSpanInput(event, attachmentCache) {
32380
+ const systemPrompt = typeof event.agent?.systemPrompt === "string" && event.agent.systemPrompt.length > 0 ? event.agent.systemPrompt : void 0;
32381
+ const processedMessages = Array.isArray(event.agent?.messages) ? processStrandsInputAttachments(event.agent.messages, attachmentCache) : void 0;
32382
+ if (!systemPrompt) {
32383
+ return processedMessages;
32384
+ }
32385
+ const systemMessage = { role: "system", content: systemPrompt };
32386
+ return Array.isArray(processedMessages) ? [systemMessage, ...processedMessages] : [systemMessage];
32387
+ }
31607
32388
  function startModelSpan(state, event) {
31608
32389
  if (state.activeModel) {
31609
32390
  finalizeModelSpan(state);
@@ -31621,10 +32402,7 @@ function startModelSpan(state, event) {
31621
32402
  withSpanInstrumentationName(
31622
32403
  {
31623
32404
  event: {
31624
- input: Array.isArray(event.agent?.messages) ? processStrandsInputAttachments(
31625
- event.agent.messages,
31626
- state.attachmentCache
31627
- ) : void 0,
32405
+ input: buildModelSpanInput(event, state.attachmentCache),
31628
32406
  metadata
31629
32407
  },
31630
32408
  name: formatModelSpanName(model),
@@ -32264,6 +33042,532 @@ function logInstrumentationError5(context, error) {
32264
33042
  debugLogger.debug(`${context}:`, error);
32265
33043
  }
32266
33044
 
33045
+ // src/instrumentation/plugins/cloudflare-ai-chat-channels.ts
33046
+ var cloudflareAIChatChannels = defineChannels(
33047
+ "@cloudflare/ai-chat",
33048
+ {
33049
+ runExclusiveChatTurn: channel({
33050
+ channelName: "AIChatAgent._runExclusiveChatTurn",
33051
+ kind: "async"
33052
+ }),
33053
+ onChatResponse: channel({
33054
+ channelName: "AIChatAgent.onChatResponse",
33055
+ kind: "sync-stream"
33056
+ })
33057
+ },
33058
+ { instrumentationName: INSTRUMENTATION_NAMES.CLOUDFLARE_AI_CHAT }
33059
+ );
33060
+
33061
+ // src/instrumentation/plugins/cloudflare-ai-chat-instrumentation.ts
33062
+ var wrappedResponseHooks = /* @__PURE__ */ new WeakSet();
33063
+ function instrumentCloudflareAIChatResponseHook(agent) {
33064
+ try {
33065
+ const original = Reflect.get(agent, "onChatResponse");
33066
+ if (typeof original !== "function" || wrappedResponseHooks.has(original)) {
33067
+ return;
33068
+ }
33069
+ const wrapped = function(result) {
33070
+ const args = [result];
33071
+ return cloudflareAIChatChannels.onChatResponse.traceSync(
33072
+ () => Reflect.apply(original, this, args),
33073
+ {
33074
+ arguments: args,
33075
+ self: this
33076
+ }
33077
+ );
33078
+ };
33079
+ wrappedResponseHooks.add(wrapped);
33080
+ defineWrappedMethod(agent, "onChatResponse", original, wrapped);
33081
+ } catch (error) {
33082
+ debugLogger.debug(
33083
+ "Failed to wrap @cloudflare/ai-chat response hook:",
33084
+ error
33085
+ );
33086
+ }
33087
+ }
33088
+ function defineWrappedMethod(target, property, original, wrapped) {
33089
+ const ownDescriptor = Object.getOwnPropertyDescriptor(target, property);
33090
+ Object.defineProperty(target, property, {
33091
+ configurable: ownDescriptor?.configurable ?? true,
33092
+ enumerable: ownDescriptor?.enumerable ?? false,
33093
+ value: wrapped,
33094
+ writable: ownDescriptor && "writable" in ownDescriptor ? ownDescriptor.writable : true
33095
+ });
33096
+ try {
33097
+ Object.defineProperty(wrapped, "name", {
33098
+ configurable: true,
33099
+ value: original.name
33100
+ });
33101
+ } catch {
33102
+ }
33103
+ }
33104
+
33105
+ // src/instrumentation/plugins/cloudflare-ai-chat-plugin.ts
33106
+ var BLOCKED_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
33107
+ var RESPONSE_STATE_RETENTION_MS = 6e4;
33108
+ var CloudflareAIChatPlugin = class extends BasePlugin {
33109
+ activeStates = /* @__PURE__ */ new Set();
33110
+ activeTurns = /* @__PURE__ */ new WeakMap();
33111
+ eventStates = /* @__PURE__ */ new WeakMap();
33112
+ onEnable() {
33113
+ this.subscribeToResponseHook();
33114
+ this.subscribeToTurnRunner();
33115
+ }
33116
+ onDisable() {
33117
+ for (const unsubscribe of this.unsubscribers) {
33118
+ unsubscribe();
33119
+ }
33120
+ this.unsubscribers = [];
33121
+ for (const state of this.activeStates) {
33122
+ this.cleanupState(state);
33123
+ }
33124
+ this.activeStates.clear();
33125
+ }
33126
+ subscribeToTurnRunner() {
33127
+ const tracingChannel = cloudflareAIChatChannels.runExclusiveChatTurn.tracingChannel();
33128
+ const unbindCurrentSpanStore = this.bindCurrentSpanStore(tracingChannel);
33129
+ const handlers = {
33130
+ start: (event) => {
33131
+ this.ensureEventState(event);
33132
+ },
33133
+ asyncEnd: (event) => {
33134
+ this.finishEvent(event);
33135
+ },
33136
+ error: (event) => {
33137
+ this.finishEvent(event, event.error);
33138
+ }
33139
+ };
33140
+ tracingChannel.subscribe(handlers);
33141
+ this.unsubscribers.push(() => {
33142
+ unbindCurrentSpanStore?.();
33143
+ tracingChannel.unsubscribe(handlers);
33144
+ });
33145
+ }
33146
+ subscribeToResponseHook() {
33147
+ const tracingChannel = cloudflareAIChatChannels.onChatResponse.tracingChannel();
33148
+ const handlers = {
33149
+ start: (event) => {
33150
+ let state;
33151
+ try {
33152
+ const agent = asObject(event.self);
33153
+ const result = event.arguments[0];
33154
+ state = agent ? this.findResponseState(
33155
+ agent,
33156
+ stringValue3(ownValue2(result, "requestId"))
33157
+ ) : void 0;
33158
+ if (!state) {
33159
+ return;
33160
+ }
33161
+ state.responseObserved = true;
33162
+ const output = serializeMessage(ownValue2(result, "message"));
33163
+ const status = stringValue3(ownValue2(result, "status"));
33164
+ const error = ownValue2(result, "error");
33165
+ const input = ownValue2(result, "continuation") === true ? state.input : serializeMessages(readProperty(agent, "messages"))?.filter(
33166
+ (message) => typeof output?.id !== "string" || message.id !== output.id
33167
+ );
33168
+ state.span.log({
33169
+ ...input !== void 0 ? { input } : {},
33170
+ ...output !== void 0 ? { output } : {},
33171
+ ...status === "error" && error !== void 0 ? { error } : {}
33172
+ });
33173
+ } catch (error) {
33174
+ debugLogger.debug(
33175
+ "Failed to process @cloudflare/ai-chat response hook:",
33176
+ error
33177
+ );
33178
+ } finally {
33179
+ if (state?.settled) {
33180
+ this.cleanupState(state);
33181
+ }
33182
+ }
33183
+ }
33184
+ };
33185
+ tracingChannel.subscribe(handlers);
33186
+ this.unsubscribers.push(() => tracingChannel.unsubscribe(handlers));
33187
+ }
33188
+ bindCurrentSpanStore(tracingChannel) {
33189
+ const globalState = _internalGetGlobalState();
33190
+ const contextManager = globalState?.contextManager;
33191
+ const startChannel = tracingChannel.start;
33192
+ const currentSpanStore = contextManager ? contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
33193
+ if (!startChannel || !currentSpanStore || !contextManager) {
33194
+ return void 0;
33195
+ }
33196
+ startChannel.bindStore(currentSpanStore, (event) => {
33197
+ const state = this.ensureEventState(event);
33198
+ return state ? contextManager.wrapSpanForStore(state.span) : currentSpanStore.getStore();
33199
+ });
33200
+ return () => startChannel.unbindStore(currentSpanStore);
33201
+ }
33202
+ ensureEventState(event) {
33203
+ const eventKey = event;
33204
+ const known = this.eventStates.get(eventKey);
33205
+ if (known) {
33206
+ return known;
33207
+ }
33208
+ try {
33209
+ const agent = asObject(event.self);
33210
+ const requestId = stringValue3(event.arguments[0]);
33211
+ const key = requestId ?? /* @__PURE__ */ Symbol("cloudflare-ai-chat-turn");
33212
+ const activeForAgent = agent ? this.getActiveTurns(agent) : void 0;
33213
+ const existing = activeForAgent?.get(key);
33214
+ const state = existing && !existing.settled ? existing : this.createTurnState(agent, key);
33215
+ if (existing && !existing.settled) {
33216
+ state.depth += 1;
33217
+ }
33218
+ this.eventStates.set(eventKey, state);
33219
+ this.bindTurnCallback(event, agent, state);
33220
+ if (agent) {
33221
+ instrumentCloudflareAIChatResponseHook(agent);
33222
+ }
33223
+ return state;
33224
+ } catch (error) {
33225
+ debugLogger.debug(
33226
+ "Failed to start @cloudflare/ai-chat instrumentation:",
33227
+ error
33228
+ );
33229
+ return void 0;
33230
+ }
33231
+ }
33232
+ createTurnState(agent, key) {
33233
+ const span = startSpan(
33234
+ withSpanInstrumentationName(
33235
+ {
33236
+ name: "AIChatAgent.onChatMessage",
33237
+ spanAttributes: { type: "task" /* TASK */ }
33238
+ },
33239
+ INSTRUMENTATION_NAMES.CLOUDFLARE_AI_CHAT
33240
+ )
33241
+ );
33242
+ const state = {
33243
+ agent,
33244
+ depth: 1,
33245
+ ended: false,
33246
+ key,
33247
+ responseObserved: false,
33248
+ settled: false,
33249
+ span
33250
+ };
33251
+ this.activeStates.add(state);
33252
+ if (agent) {
33253
+ this.getActiveTurns(agent).set(key, state);
33254
+ }
33255
+ return state;
33256
+ }
33257
+ bindTurnCallback(event, agent, state) {
33258
+ const callback = event.arguments[1];
33259
+ if (typeof callback !== "function") {
33260
+ return;
33261
+ }
33262
+ try {
33263
+ event.arguments[1] = function(...args) {
33264
+ return withCurrent(state.span, () => {
33265
+ try {
33266
+ const input = serializeMessages(readProperty(agent, "messages"));
33267
+ if (input !== void 0 && state.input === void 0) {
33268
+ state.input = input;
33269
+ state.span.log({ input });
33270
+ }
33271
+ } catch (error) {
33272
+ debugLogger.debug(
33273
+ "Failed to capture @cloudflare/ai-chat messages:",
33274
+ error
33275
+ );
33276
+ }
33277
+ return Reflect.apply(callback, this, args);
33278
+ });
33279
+ };
33280
+ } catch (error) {
33281
+ debugLogger.debug(
33282
+ "Failed to bind @cloudflare/ai-chat turn callback context:",
33283
+ error
33284
+ );
33285
+ }
33286
+ }
33287
+ finishEvent(event, error) {
33288
+ const eventKey = event;
33289
+ const state = this.eventStates.get(eventKey);
33290
+ if (!state || state.ended) {
33291
+ return;
33292
+ }
33293
+ this.eventStates.delete(eventKey);
33294
+ if (error !== void 0 && state.pendingError === void 0) {
33295
+ state.pendingError = error;
33296
+ }
33297
+ state.depth -= 1;
33298
+ if (state.depth === 0) {
33299
+ state.settled = true;
33300
+ this.endState(state);
33301
+ if (state.responseObserved || error !== void 0) {
33302
+ this.cleanupState(state);
33303
+ } else {
33304
+ state.cleanupTimer = setTimeout(
33305
+ () => this.cleanupState(state),
33306
+ RESPONSE_STATE_RETENTION_MS
33307
+ );
33308
+ if (typeof state.cleanupTimer === "object" && state.cleanupTimer !== null && "unref" in state.cleanupTimer && typeof state.cleanupTimer.unref === "function") {
33309
+ state.cleanupTimer.unref();
33310
+ }
33311
+ }
33312
+ }
33313
+ }
33314
+ endState(state) {
33315
+ if (state.ended) {
33316
+ return;
33317
+ }
33318
+ state.ended = true;
33319
+ try {
33320
+ if (state.pendingError !== void 0) {
33321
+ state.span.log({ error: state.pendingError });
33322
+ }
33323
+ } finally {
33324
+ state.span.end();
33325
+ }
33326
+ }
33327
+ cleanupState(state) {
33328
+ if (state.cleanupTimer !== void 0) {
33329
+ clearTimeout(state.cleanupTimer);
33330
+ state.cleanupTimer = void 0;
33331
+ }
33332
+ try {
33333
+ this.endState(state);
33334
+ } finally {
33335
+ this.activeStates.delete(state);
33336
+ if (state.agent) {
33337
+ const activeForAgent = this.activeTurns.get(state.agent);
33338
+ if (activeForAgent?.get(state.key) === state) {
33339
+ activeForAgent.delete(state.key);
33340
+ }
33341
+ }
33342
+ }
33343
+ }
33344
+ getActiveTurns(agent) {
33345
+ let turns = this.activeTurns.get(agent);
33346
+ if (!turns) {
33347
+ turns = /* @__PURE__ */ new Map();
33348
+ this.activeTurns.set(agent, turns);
33349
+ }
33350
+ return turns;
33351
+ }
33352
+ findResponseState(agent, requestId) {
33353
+ const turns = this.activeTurns.get(agent);
33354
+ if (!turns) {
33355
+ return void 0;
33356
+ }
33357
+ if (requestId !== void 0) {
33358
+ return turns.get(requestId);
33359
+ }
33360
+ const active = [...turns.values()];
33361
+ return active.length === 1 ? active[0] : void 0;
33362
+ }
33363
+ };
33364
+ function asObject(value) {
33365
+ return value !== null && (typeof value === "object" || typeof value === "function") ? value : void 0;
33366
+ }
33367
+ function readProperty(value, key) {
33368
+ const object = asObject(value);
33369
+ return object ? Reflect.get(object, key) : void 0;
33370
+ }
33371
+ function ownValue2(value, key) {
33372
+ const object = asObject(value);
33373
+ if (!object) {
33374
+ return void 0;
33375
+ }
33376
+ const descriptor = Object.getOwnPropertyDescriptor(object, key);
33377
+ return descriptor && "value" in descriptor ? descriptor.value : void 0;
33378
+ }
33379
+ function stringValue3(value) {
33380
+ return typeof value === "string" ? value : void 0;
33381
+ }
33382
+ function serializeMessages(value) {
33383
+ if (!Array.isArray(value)) {
33384
+ return void 0;
33385
+ }
33386
+ return value.flatMap((message) => {
33387
+ const serialized = serializeMessage(message);
33388
+ return serialized === void 0 ? [] : [serialized];
33389
+ });
33390
+ }
33391
+ function serializeMessage(value) {
33392
+ const message = asObject(value);
33393
+ if (!message) {
33394
+ return void 0;
33395
+ }
33396
+ const serialized = [];
33397
+ const id = ownValue2(message, "id");
33398
+ const role = ownValue2(message, "role");
33399
+ const parts = ownValue2(message, "parts");
33400
+ if (typeof id === "string") {
33401
+ serialized.push(["id", id]);
33402
+ }
33403
+ if (typeof role === "string") {
33404
+ serialized.push(["role", role]);
33405
+ }
33406
+ const sanitizedParts = sanitizeLoggedValue2(parts);
33407
+ if (sanitizedParts !== void 0) {
33408
+ serialized.push(["parts", sanitizedParts]);
33409
+ }
33410
+ return serialized.length > 0 ? Object.fromEntries(serialized) : void 0;
33411
+ }
33412
+ function sanitizeLoggedValue2(value, seen = /* @__PURE__ */ new WeakSet(), depth = 0) {
33413
+ if (value === null || typeof value === "string" || typeof value === "boolean") {
33414
+ return value;
33415
+ }
33416
+ if (typeof value === "number") {
33417
+ return Number.isFinite(value) ? value : void 0;
33418
+ }
33419
+ const object = asObject(value);
33420
+ if (!object || depth >= 20 || typeof value === "function") {
33421
+ return void 0;
33422
+ }
33423
+ if (seen.has(object)) {
33424
+ return "[Circular]";
33425
+ }
33426
+ seen.add(object);
33427
+ if (Array.isArray(value)) {
33428
+ return value.map((entry) => sanitizeLoggedValue2(entry, seen, depth + 1));
33429
+ }
33430
+ const entries = [];
33431
+ for (const [key, descriptor] of Object.entries(
33432
+ Object.getOwnPropertyDescriptors(object)
33433
+ )) {
33434
+ if (BLOCKED_KEYS.has(key) || !descriptor.enumerable || !("value" in descriptor)) {
33435
+ continue;
33436
+ }
33437
+ const sanitized = sanitizeLoggedValue2(descriptor.value, seen, depth + 1);
33438
+ if (sanitized !== void 0) {
33439
+ entries.push([key, sanitized]);
33440
+ }
33441
+ }
33442
+ return Object.fromEntries(entries);
33443
+ }
33444
+
33445
+ // src/instrumentation/plugins/cloudflare-agents-channels.ts
33446
+ var cloudflareAgentsChannels = defineChannels(
33447
+ "agents",
33448
+ {
33449
+ runAgentTool: channel({
33450
+ channelName: "Agent.runAgentTool",
33451
+ kind: "async"
33452
+ })
33453
+ },
33454
+ { instrumentationName: INSTRUMENTATION_NAMES.CLOUDFLARE_AGENTS }
33455
+ );
33456
+
33457
+ // src/instrumentation/plugins/cloudflare-agents-plugin.ts
33458
+ var CLOUDFLARE_WORKERS_CONTEXT = {
33459
+ span_origin: {
33460
+ environment: { type: "server", name: "cloudflare_workers" }
33461
+ }
33462
+ };
33463
+ var CloudflareAgentsPlugin = class extends BasePlugin {
33464
+ onEnable() {
33465
+ const channel2 = cloudflareAgentsChannels.runAgentTool.tracingChannel();
33466
+ const spans = /* @__PURE__ */ new WeakMap();
33467
+ const handlers = {
33468
+ start: (event) => {
33469
+ try {
33470
+ const agentClass = event.arguments[0];
33471
+ const options = event.arguments[1];
33472
+ if (ownValue3(options, "detached")) {
33473
+ return;
33474
+ }
33475
+ const name = ownValue3(agentClass, "name");
33476
+ if (typeof name !== "string" || name.length === 0) {
33477
+ debugLogger.warn(
33478
+ "Skipping Cloudflare Agents runAgentTool span because the child agent class has no name."
33479
+ );
33480
+ return;
33481
+ }
33482
+ const span = _internalStartSpanWithContext(
33483
+ withSpanInstrumentationName(
33484
+ {
33485
+ name,
33486
+ spanAttributes: { type: "tool" /* TOOL */ },
33487
+ event: {
33488
+ input: ownValue3(options, "input")
33489
+ }
33490
+ },
33491
+ INSTRUMENTATION_NAMES.CLOUDFLARE_AGENTS
33492
+ ),
33493
+ CLOUDFLARE_WORKERS_CONTEXT
33494
+ );
33495
+ spans.set(event, span);
33496
+ } catch (error) {
33497
+ logInstrumentationError6("start", error);
33498
+ }
33499
+ },
33500
+ asyncEnd: (event) => {
33501
+ const span = spans.get(event);
33502
+ if (!span) {
33503
+ return;
33504
+ }
33505
+ spans.delete(event);
33506
+ try {
33507
+ const status = ownValue3(event.result, "status");
33508
+ if (status === "completed") {
33509
+ span.log({ output: ownValue3(event.result, "output") });
33510
+ } else {
33511
+ const error = ownValue3(event.result, "error");
33512
+ if (typeof error === "string") {
33513
+ span.log({ error });
33514
+ }
33515
+ }
33516
+ } catch (error) {
33517
+ logInstrumentationError6("completion", error);
33518
+ } finally {
33519
+ safelyEndSpan(span);
33520
+ }
33521
+ },
33522
+ error: (event) => {
33523
+ const span = spans.get(event);
33524
+ if (!span) {
33525
+ return;
33526
+ }
33527
+ spans.delete(event);
33528
+ try {
33529
+ span.log({ error: event.error });
33530
+ } catch (error) {
33531
+ logInstrumentationError6("rejection", error);
33532
+ } finally {
33533
+ safelyEndSpan(span);
33534
+ }
33535
+ }
33536
+ };
33537
+ channel2.subscribe(handlers);
33538
+ this.unsubscribers.push(() => channel2.unsubscribe(handlers));
33539
+ }
33540
+ onDisable() {
33541
+ for (const unsubscribe of this.unsubscribers) {
33542
+ unsubscribe();
33543
+ }
33544
+ this.unsubscribers = [];
33545
+ }
33546
+ };
33547
+ function ownValue3(value, key) {
33548
+ if (!isObjectLike2(value)) {
33549
+ return void 0;
33550
+ }
33551
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
33552
+ return descriptor && "value" in descriptor ? descriptor.value : void 0;
33553
+ }
33554
+ function isObjectLike2(value) {
33555
+ return typeof value === "object" && value !== null || typeof value === "function";
33556
+ }
33557
+ function safelyEndSpan(span) {
33558
+ try {
33559
+ span.end();
33560
+ } catch (error) {
33561
+ logInstrumentationError6("span end", error);
33562
+ }
33563
+ }
33564
+ function logInstrumentationError6(operation, error) {
33565
+ debugLogger.error(
33566
+ `Failed to process Cloudflare Agents ${operation} instrumentation:`,
33567
+ error
33568
+ );
33569
+ }
33570
+
32267
33571
  // src/instrumentation/braintrust-plugin.ts
32268
33572
  var BraintrustPlugin = class extends BasePlugin {
32269
33573
  config;
@@ -32276,6 +33580,7 @@ var BraintrustPlugin = class extends BasePlugin {
32276
33580
  openAIAgentsPlugin = null;
32277
33581
  googleGenAIPlugin = null;
32278
33582
  huggingFacePlugin = null;
33583
+ huggingFaceTransformersPlugin = null;
32279
33584
  openRouterPlugin = null;
32280
33585
  openRouterAgentPlugin = null;
32281
33586
  mistralPlugin = null;
@@ -32290,6 +33595,8 @@ var BraintrustPlugin = class extends BasePlugin {
32290
33595
  langSmithPlugin = null;
32291
33596
  piCodingAgentPlugin = null;
32292
33597
  strandsAgentSDKPlugin = null;
33598
+ cloudflareAIChatPlugin = null;
33599
+ cloudflareAgentsPlugin = null;
32293
33600
  constructor(config = {}) {
32294
33601
  super();
32295
33602
  this.config = config;
@@ -32331,6 +33638,8 @@ var BraintrustPlugin = class extends BasePlugin {
32331
33638
  if (integrations.huggingface !== false) {
32332
33639
  this.huggingFacePlugin = new HuggingFacePlugin();
32333
33640
  this.huggingFacePlugin.enable();
33641
+ this.huggingFaceTransformersPlugin = new HuggingFaceTransformersPlugin();
33642
+ this.huggingFaceTransformersPlugin.enable();
32334
33643
  }
32335
33644
  if (integrations.openrouter !== false) {
32336
33645
  this.openRouterPlugin = new OpenRouterPlugin();
@@ -32376,6 +33685,14 @@ var BraintrustPlugin = class extends BasePlugin {
32376
33685
  this.strandsAgentSDKPlugin = new StrandsAgentSDKPlugin();
32377
33686
  this.strandsAgentSDKPlugin.enable();
32378
33687
  }
33688
+ if (integrations.cloudflareAIChat !== false) {
33689
+ this.cloudflareAIChatPlugin = new CloudflareAIChatPlugin();
33690
+ this.cloudflareAIChatPlugin.enable();
33691
+ }
33692
+ if (integrations.cloudflareAgents !== false) {
33693
+ this.cloudflareAgentsPlugin = new CloudflareAgentsPlugin();
33694
+ this.cloudflareAgentsPlugin.enable();
33695
+ }
32379
33696
  if (integrations.flue !== false) {
32380
33697
  this.fluePlugin = new FluePlugin();
32381
33698
  this.fluePlugin.enable();
@@ -32428,6 +33745,10 @@ var BraintrustPlugin = class extends BasePlugin {
32428
33745
  this.huggingFacePlugin.disable();
32429
33746
  this.huggingFacePlugin = null;
32430
33747
  }
33748
+ if (this.huggingFaceTransformersPlugin) {
33749
+ this.huggingFaceTransformersPlugin.disable();
33750
+ this.huggingFaceTransformersPlugin = null;
33751
+ }
32431
33752
  if (this.openRouterPlugin) {
32432
33753
  this.openRouterPlugin.disable();
32433
33754
  this.openRouterPlugin = null;
@@ -32472,6 +33793,14 @@ var BraintrustPlugin = class extends BasePlugin {
32472
33793
  this.strandsAgentSDKPlugin.disable();
32473
33794
  this.strandsAgentSDKPlugin = null;
32474
33795
  }
33796
+ if (this.cloudflareAIChatPlugin) {
33797
+ this.cloudflareAIChatPlugin.disable();
33798
+ this.cloudflareAIChatPlugin = null;
33799
+ }
33800
+ if (this.cloudflareAgentsPlugin) {
33801
+ this.cloudflareAgentsPlugin.disable();
33802
+ this.cloudflareAgentsPlugin = null;
33803
+ }
32475
33804
  if (this.fluePlugin) {
32476
33805
  this.fluePlugin.disable();
32477
33806
  this.fluePlugin = null;
@@ -32504,6 +33833,9 @@ var envIntegrationAliases = {
32504
33833
  strandsagentsdk: "strandsAgentSDK",
32505
33834
  "strands-agent-sdk": "strandsAgentSDK",
32506
33835
  "@strands-agents/sdk": "strandsAgentSDK",
33836
+ agents: "cloudflareAgents",
33837
+ "cloudflare-agents": "cloudflareAgents",
33838
+ cloudflareagents: "cloudflareAgents",
32507
33839
  anthropic: "anthropic",
32508
33840
  aisdk: "aisdk",
32509
33841
  "ai-sdk": "aisdk",
@@ -32511,6 +33843,9 @@ var envIntegrationAliases = {
32511
33843
  vercel: "vercel",
32512
33844
  claudeagentsdk: "claudeAgentSDK",
32513
33845
  "claude-agent-sdk": "claudeAgentSDK",
33846
+ cloudflareaichat: "cloudflareAIChat",
33847
+ "cloudflare-ai-chat": "cloudflareAIChat",
33848
+ "@cloudflare/ai-chat": "cloudflareAIChat",
32514
33849
  cursor: "cursor",
32515
33850
  "cursor-sdk": "cursorSDK",
32516
33851
  cursorsdk: "cursorSDK",
@@ -32525,6 +33860,8 @@ var envIntegrationAliases = {
32525
33860
  "google-genai": "googleGenAI",
32526
33861
  googlegenai: "googleGenAI",
32527
33862
  huggingface: "huggingface",
33863
+ "@huggingface/transformers": "huggingface",
33864
+ transformers: "huggingface",
32528
33865
  openrouter: "openrouter",
32529
33866
  openrouteragent: "openrouterAgent",
32530
33867
  "openrouter-agent": "openrouterAgent",
@@ -32563,6 +33900,7 @@ function getDefaultInstrumentationIntegrations() {
32563
33900
  googleADK: true,
32564
33901
  huggingface: true,
32565
33902
  claudeAgentSDK: true,
33903
+ cloudflareAIChat: true,
32566
33904
  cursor: true,
32567
33905
  cursorSDK: true,
32568
33906
  flue: true,
@@ -32582,7 +33920,8 @@ function getDefaultInstrumentationIntegrations() {
32582
33920
  langgraph: true,
32583
33921
  langsmith: true,
32584
33922
  piCodingAgent: true,
32585
- strandsAgentSDK: true
33923
+ strandsAgentSDK: true,
33924
+ cloudflareAgents: true
32586
33925
  };
32587
33926
  }
32588
33927
  function readDisabledInstrumentationEnvConfig(disabledList) {
@@ -32603,7 +33942,9 @@ function isInstrumentationIntegrationDisabled(integrations, ...names) {
32603
33942
  }
32604
33943
 
32605
33944
  // src/instrumentation/registry.ts
32606
- var REGISTRY_STATE_KEY = /* @__PURE__ */ Symbol.for("braintrust.registry");
33945
+ var REGISTRY_STATE_KEY = /* @__PURE__ */ Symbol.for(
33946
+ `braintrust.registry.global-hooks.v${GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION}`
33947
+ );
32607
33948
  function getSharedState() {
32608
33949
  const state = globalThis[/* @__PURE__ */ Symbol.for("braintrust-state")];
32609
33950
  return state && typeof state === "object" ? state : void 0;
@@ -33039,8 +34380,6 @@ function configureNode() {
33039
34380
  };
33040
34381
  isomorph_default.getCallerLocation = getCallerLocation;
33041
34382
  isomorph_default.newAsyncLocalStorage = () => new AsyncLocalStorage();
33042
- isomorph_default.newTracingChannel = (nameOrChannels) => diagnostics_channel.tracingChannel(nameOrChannels);
33043
- patchTracingChannel(diagnostics_channel.tracingChannel);
33044
34383
  isomorph_default.processOn = (event, handler) => {
33045
34384
  process.on(event, handler);
33046
34385
  };