braintrust 3.26.0 → 3.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dev/dist/index.js +2440 -1067
- package/dev/dist/index.mjs +1644 -271
- package/dist/apply-auto-instrumentation.js +320 -261
- package/dist/apply-auto-instrumentation.mjs +118 -59
- package/dist/auto-instrumentations/bundler/esbuild.cjs +377 -59
- package/dist/auto-instrumentations/bundler/esbuild.mjs +5 -4
- package/dist/auto-instrumentations/bundler/next.cjs +379 -61
- package/dist/auto-instrumentations/bundler/next.mjs +6 -5
- package/dist/auto-instrumentations/bundler/rollup.cjs +377 -59
- package/dist/auto-instrumentations/bundler/rollup.mjs +5 -4
- package/dist/auto-instrumentations/bundler/vite.cjs +406 -60
- package/dist/auto-instrumentations/bundler/vite.mjs +34 -5
- package/dist/auto-instrumentations/bundler/webpack-loader.cjs +363 -59
- package/dist/auto-instrumentations/bundler/webpack.cjs +377 -59
- package/dist/auto-instrumentations/bundler/webpack.mjs +6 -5
- package/dist/auto-instrumentations/{chunk-AKKPLXTP.mjs → chunk-2AMDGD65.mjs} +160 -57
- package/dist/auto-instrumentations/{chunk-V5LEODRX.mjs → chunk-BW33ULMW.mjs} +1 -1
- package/dist/auto-instrumentations/{chunk-XYN63IG5.mjs → chunk-I55G56ZL.mjs} +21 -58
- package/dist/auto-instrumentations/{chunk-NRE4QUQR.mjs → chunk-JPUFNW7X.mjs} +140 -0
- package/dist/auto-instrumentations/{chunk-6E22MYSW.mjs → chunk-XEYKUBLY.mjs} +30 -4
- package/dist/auto-instrumentations/{chunk-XZHHE4Y3.mjs → chunk-ZNHTSSGI.mjs} +155 -2
- package/dist/auto-instrumentations/hook.mjs +161 -3
- package/dist/auto-instrumentations/index.cjs +296 -1
- package/dist/auto-instrumentations/index.d.mts +5 -1
- package/dist/auto-instrumentations/index.d.ts +5 -1
- package/dist/auto-instrumentations/index.mjs +6 -2
- package/dist/auto-instrumentations/loader/cjs-patch.cjs +105 -57
- package/dist/auto-instrumentations/loader/cjs-patch.mjs +2 -2
- package/dist/auto-instrumentations/loader/esm-hook.mjs +1 -1
- package/dist/browser.d.mts +57 -5
- package/dist/browser.d.ts +57 -5
- package/dist/browser.js +1855 -285
- package/dist/browser.mjs +1855 -285
- package/dist/{chunk-PN7EWK66.mjs → chunk-CZM5JIQL.mjs} +209 -1
- package/dist/{chunk-VYNNEKSA.js → chunk-MF7NU6BT.js} +216 -8
- package/dist/{chunk-VRZZQPAA.js → chunk-QRHGVBKU.js} +2403 -1220
- package/dist/{chunk-XIZOM2HO.mjs → chunk-YKD22IMR.mjs} +1454 -271
- package/dist/cli.js +1645 -272
- package/dist/edge-light.d.mts +1 -1
- package/dist/edge-light.d.ts +1 -1
- package/dist/edge-light.js +1855 -285
- package/dist/edge-light.mjs +1855 -285
- package/dist/index.d.mts +57 -5
- package/dist/index.d.ts +57 -5
- package/dist/index.js +600 -413
- package/dist/index.mjs +201 -14
- package/dist/instrumentation/index.d.mts +8 -0
- package/dist/instrumentation/index.d.ts +8 -0
- package/dist/instrumentation/index.js +1839 -466
- package/dist/instrumentation/index.mjs +1839 -466
- package/dist/vitest-evals-reporter.js +45 -43
- package/dist/vitest-evals-reporter.mjs +5 -3
- package/dist/workerd.d.mts +1 -1
- package/dist/workerd.d.ts +1 -1
- package/dist/workerd.js +1855 -285
- package/dist/workerd.mjs +1855 -285
- package/package.json +1 -1
|
@@ -49,8 +49,10 @@ var GLOBAL_INSTRUMENTATION_HOOKS_KEY = "__braintrust_instrumentation_hooks";
|
|
|
49
49
|
var GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION = 1;
|
|
50
50
|
var GLOBAL_INSTRUMENTATION_HOOKS_REGISTRY_BRAND = "braintrust.global-instrumentation-hooks.registry";
|
|
51
51
|
var GLOBAL_INSTRUMENTATION_HOOK_BRAND = "braintrust.global-instrumentation-hooks.hook";
|
|
52
|
+
var GLOBAL_INVOCATION_HOOK_BRAND = "braintrust.global-instrumentation-hooks.invocation-hook";
|
|
52
53
|
var registryBrand = Symbol.for(GLOBAL_INSTRUMENTATION_HOOKS_REGISTRY_BRAND);
|
|
53
54
|
var hookBrand = Symbol.for(GLOBAL_INSTRUMENTATION_HOOK_BRAND);
|
|
55
|
+
var invocationHookBrand = Symbol.for(GLOBAL_INVOCATION_HOOK_BRAND);
|
|
54
56
|
var errorReporter;
|
|
55
57
|
function setGlobalHookErrorReporter(reporter) {
|
|
56
58
|
const previousReporter = errorReporter;
|
|
@@ -195,12 +197,69 @@ var traceEvents = [
|
|
|
195
197
|
"asyncEnd",
|
|
196
198
|
"error"
|
|
197
199
|
];
|
|
200
|
+
function traceInvocation(hook, operator, target, thisArg, args, additional, callbackIndex = -1) {
|
|
201
|
+
const context = {
|
|
202
|
+
...additional,
|
|
203
|
+
arguments: args,
|
|
204
|
+
self: thisArg
|
|
205
|
+
};
|
|
206
|
+
const invoke = () => hook.invoke(target, thisArg, args, additional);
|
|
207
|
+
if (operator === "traceCallback") {
|
|
208
|
+
return hook.traceCallback(invoke, callbackIndex, context);
|
|
209
|
+
}
|
|
210
|
+
if (operator === "tracePromise") {
|
|
211
|
+
return hook.tracePromise(invoke, context);
|
|
212
|
+
}
|
|
213
|
+
return hook.traceSync(invoke, context);
|
|
214
|
+
}
|
|
215
|
+
var InvocationHook = class {
|
|
216
|
+
interceptors = [];
|
|
217
|
+
get hasInterceptors() {
|
|
218
|
+
return this.interceptors.length > 0;
|
|
219
|
+
}
|
|
220
|
+
intercept(interceptor) {
|
|
221
|
+
if (typeof interceptor !== "function") {
|
|
222
|
+
throw new TypeError("interceptor must be a function");
|
|
223
|
+
}
|
|
224
|
+
this.interceptors = [...this.interceptors, interceptor];
|
|
225
|
+
let active = true;
|
|
226
|
+
return () => {
|
|
227
|
+
if (!active) {
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
active = false;
|
|
231
|
+
const index = this.interceptors.indexOf(interceptor);
|
|
232
|
+
if (index !== -1) {
|
|
233
|
+
this.interceptors = [
|
|
234
|
+
...this.interceptors.slice(0, index),
|
|
235
|
+
...this.interceptors.slice(index + 1)
|
|
236
|
+
];
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
invoke(target, thisArg, args, additional) {
|
|
241
|
+
const interceptors = this.interceptors;
|
|
242
|
+
if (interceptors.length === 0) {
|
|
243
|
+
return Reflect.apply(target, thisArg, args);
|
|
244
|
+
}
|
|
245
|
+
let next = target;
|
|
246
|
+
for (let index = interceptors.length - 1; index >= 0; index -= 1) {
|
|
247
|
+
const interceptor = interceptors[index];
|
|
248
|
+
const downstream = next;
|
|
249
|
+
next = function(...nextArgs) {
|
|
250
|
+
return interceptor(downstream, this, nextArgs, additional);
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
return Reflect.apply(next, thisArg, args);
|
|
254
|
+
}
|
|
255
|
+
};
|
|
198
256
|
var TracingHook = class {
|
|
199
257
|
start;
|
|
200
258
|
end;
|
|
201
259
|
asyncStart;
|
|
202
260
|
asyncEnd;
|
|
203
261
|
error;
|
|
262
|
+
invocationHook = new InvocationHook();
|
|
204
263
|
constructor(nameOrChannels) {
|
|
205
264
|
Object.defineProperty(this, hookBrand, {
|
|
206
265
|
configurable: false,
|
|
@@ -208,6 +267,12 @@ var TracingHook = class {
|
|
|
208
267
|
value: GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION,
|
|
209
268
|
writable: false
|
|
210
269
|
});
|
|
270
|
+
Object.defineProperty(this, invocationHookBrand, {
|
|
271
|
+
configurable: false,
|
|
272
|
+
enumerable: false,
|
|
273
|
+
value: GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION,
|
|
274
|
+
writable: false
|
|
275
|
+
});
|
|
211
276
|
if (typeof nameOrChannels === "string") {
|
|
212
277
|
this.start = new HookChannel(`tracing:${nameOrChannels}:start`);
|
|
213
278
|
this.end = new HookChannel(`tracing:${nameOrChannels}:end`);
|
|
@@ -225,6 +290,26 @@ var TracingHook = class {
|
|
|
225
290
|
get hasSubscribers() {
|
|
226
291
|
return this.start.hasSubscribers || this.end.hasSubscribers || this.asyncStart.hasSubscribers || this.asyncEnd.hasSubscribers || this.error.hasSubscribers;
|
|
227
292
|
}
|
|
293
|
+
get hasInterceptors() {
|
|
294
|
+
return this.invocationHook.hasInterceptors;
|
|
295
|
+
}
|
|
296
|
+
intercept(interceptor) {
|
|
297
|
+
return this.invocationHook.intercept(interceptor);
|
|
298
|
+
}
|
|
299
|
+
invoke(target, thisArg, args, additional) {
|
|
300
|
+
return this.invocationHook.invoke(target, thisArg, args, additional);
|
|
301
|
+
}
|
|
302
|
+
traceInvocation(operator, target, thisArg, args, additional, callbackIndex = -1) {
|
|
303
|
+
return traceInvocation(
|
|
304
|
+
this,
|
|
305
|
+
operator,
|
|
306
|
+
target,
|
|
307
|
+
thisArg,
|
|
308
|
+
args,
|
|
309
|
+
additional,
|
|
310
|
+
callbackIndex
|
|
311
|
+
);
|
|
312
|
+
}
|
|
228
313
|
subscribe(handlers) {
|
|
229
314
|
for (const eventName of traceEvents) {
|
|
230
315
|
const handler = handlers[eventName];
|
|
@@ -446,6 +531,60 @@ function hasTracingHookShape(value) {
|
|
|
446
531
|
return false;
|
|
447
532
|
}
|
|
448
533
|
}
|
|
534
|
+
function hasInvocationHookShape(value) {
|
|
535
|
+
if (typeof value !== "object" && typeof value !== "function" || value === null) {
|
|
536
|
+
return false;
|
|
537
|
+
}
|
|
538
|
+
try {
|
|
539
|
+
const hook = value;
|
|
540
|
+
return value[invocationHookBrand] === GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION && typeof hook.hasInterceptors === "boolean" && typeof hook.intercept === "function" && typeof hook.invoke === "function";
|
|
541
|
+
} catch {
|
|
542
|
+
return false;
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
function installInvocationHook(value) {
|
|
546
|
+
const hasInvocationHook = hasInvocationHookShape(value);
|
|
547
|
+
const invocationHook = new InvocationHook();
|
|
548
|
+
try {
|
|
549
|
+
if (!hasInvocationHook) {
|
|
550
|
+
Object.defineProperties(value, {
|
|
551
|
+
[invocationHookBrand]: {
|
|
552
|
+
configurable: false,
|
|
553
|
+
enumerable: false,
|
|
554
|
+
value: GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION,
|
|
555
|
+
writable: false
|
|
556
|
+
},
|
|
557
|
+
hasInterceptors: {
|
|
558
|
+
configurable: false,
|
|
559
|
+
enumerable: false,
|
|
560
|
+
get: () => invocationHook.hasInterceptors
|
|
561
|
+
},
|
|
562
|
+
intercept: {
|
|
563
|
+
configurable: false,
|
|
564
|
+
enumerable: false,
|
|
565
|
+
value: invocationHook.intercept.bind(invocationHook),
|
|
566
|
+
writable: false
|
|
567
|
+
},
|
|
568
|
+
invoke: {
|
|
569
|
+
configurable: false,
|
|
570
|
+
enumerable: false,
|
|
571
|
+
value: invocationHook.invoke.bind(invocationHook),
|
|
572
|
+
writable: false
|
|
573
|
+
}
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
if (typeof value.traceInvocation !== "function") {
|
|
577
|
+
Object.defineProperty(value, "traceInvocation", {
|
|
578
|
+
configurable: false,
|
|
579
|
+
enumerable: false,
|
|
580
|
+
value: traceInvocation.bind(void 0, value),
|
|
581
|
+
writable: false
|
|
582
|
+
});
|
|
583
|
+
}
|
|
584
|
+
} catch (error) {
|
|
585
|
+
reportError(error);
|
|
586
|
+
}
|
|
587
|
+
}
|
|
449
588
|
function isCompatibleTracingHook(value) {
|
|
450
589
|
try {
|
|
451
590
|
return value[hookBrand] === GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION && hasTracingHookShape(value);
|
|
@@ -532,6 +671,7 @@ function newGlobalTracingChannel(nameOrChannels) {
|
|
|
532
671
|
return inertTracingHook;
|
|
533
672
|
}
|
|
534
673
|
if (isCompatibleTracingHook(existing)) {
|
|
674
|
+
installInvocationHook(existing);
|
|
535
675
|
return existing;
|
|
536
676
|
}
|
|
537
677
|
if (existing !== void 0) {
|
|
@@ -587,6 +727,114 @@ var iso = {
|
|
|
587
727
|
};
|
|
588
728
|
var isomorph_default = iso;
|
|
589
729
|
|
|
730
|
+
// src/debug-logger.ts
|
|
731
|
+
var PREFIX = "[braintrust]";
|
|
732
|
+
var DEBUG_LOG_LEVEL_SYMBOL = /* @__PURE__ */ Symbol.for("braintrust-debug-log-level");
|
|
733
|
+
var LOG_LEVEL_PRIORITY = {
|
|
734
|
+
error: 0,
|
|
735
|
+
warn: 1,
|
|
736
|
+
info: 2,
|
|
737
|
+
debug: 3
|
|
738
|
+
};
|
|
739
|
+
var hasWarnedAboutInvalidEnvValue = false;
|
|
740
|
+
var debugLogStateResolver = void 0;
|
|
741
|
+
function warnInvalidEnvValue(value) {
|
|
742
|
+
if (hasWarnedAboutInvalidEnvValue) {
|
|
743
|
+
return;
|
|
744
|
+
}
|
|
745
|
+
hasWarnedAboutInvalidEnvValue = true;
|
|
746
|
+
console.warn(
|
|
747
|
+
PREFIX,
|
|
748
|
+
`Invalid BRAINTRUST_DEBUG_LOG_LEVEL value "${value}". Expected "error", "warn", "info", or "debug".`
|
|
749
|
+
);
|
|
750
|
+
}
|
|
751
|
+
function normalizeDebugLogLevelOption(option) {
|
|
752
|
+
if (option === false) {
|
|
753
|
+
return void 0;
|
|
754
|
+
}
|
|
755
|
+
if (option === "error" || option === "warn" || option === "info" || option === "debug") {
|
|
756
|
+
return option;
|
|
757
|
+
}
|
|
758
|
+
throw new Error(
|
|
759
|
+
`Invalid debugLogLevel value "${option}". Expected false, "error", "warn", "info", or "debug".`
|
|
760
|
+
);
|
|
761
|
+
}
|
|
762
|
+
function parseDebugLogLevelEnv(value) {
|
|
763
|
+
if (!value) {
|
|
764
|
+
return void 0;
|
|
765
|
+
}
|
|
766
|
+
if (value === "error" || value === "warn" || value === "info" || value === "debug") {
|
|
767
|
+
return value;
|
|
768
|
+
}
|
|
769
|
+
warnInvalidEnvValue(value);
|
|
770
|
+
return void 0;
|
|
771
|
+
}
|
|
772
|
+
function getEnvDebugLogLevel() {
|
|
773
|
+
return parseDebugLogLevelEnv(isomorph_default.getEnv("BRAINTRUST_DEBUG_LOG_LEVEL"));
|
|
774
|
+
}
|
|
775
|
+
function setGlobalDebugLogLevel(level) {
|
|
776
|
+
globalThis[DEBUG_LOG_LEVEL_SYMBOL] = level;
|
|
777
|
+
}
|
|
778
|
+
function setDebugLogStateResolver(resolver) {
|
|
779
|
+
debugLogStateResolver = resolver;
|
|
780
|
+
}
|
|
781
|
+
function resolveDebugLogLevel(state) {
|
|
782
|
+
const stateLevel = state?.getDebugLogLevel?.();
|
|
783
|
+
const hasStateOverride = state?.hasDebugLogLevelOverride?.() ?? false;
|
|
784
|
+
if (hasStateOverride) {
|
|
785
|
+
return stateLevel;
|
|
786
|
+
}
|
|
787
|
+
const globalLevel = (
|
|
788
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
789
|
+
globalThis[DEBUG_LOG_LEVEL_SYMBOL]
|
|
790
|
+
);
|
|
791
|
+
if (globalLevel !== void 0) {
|
|
792
|
+
return globalLevel === false ? void 0 : globalLevel;
|
|
793
|
+
}
|
|
794
|
+
return getEnvDebugLogLevel();
|
|
795
|
+
}
|
|
796
|
+
function emit(method, state, args) {
|
|
797
|
+
const level = resolveDebugLogLevel(state);
|
|
798
|
+
if (!level || LOG_LEVEL_PRIORITY[method] > LOG_LEVEL_PRIORITY[level]) {
|
|
799
|
+
return;
|
|
800
|
+
}
|
|
801
|
+
if (method === "info") {
|
|
802
|
+
console.log(PREFIX, ...args);
|
|
803
|
+
} else if (method === "debug") {
|
|
804
|
+
console.debug(PREFIX, ...args);
|
|
805
|
+
} else if (method === "warn") {
|
|
806
|
+
console.warn(PREFIX, ...args);
|
|
807
|
+
} else {
|
|
808
|
+
console.error(PREFIX, ...args);
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
function createDebugLogger(state) {
|
|
812
|
+
const resolveState = () => state ?? debugLogStateResolver?.();
|
|
813
|
+
return {
|
|
814
|
+
info(...args) {
|
|
815
|
+
emit("info", resolveState(), args);
|
|
816
|
+
},
|
|
817
|
+
debug(...args) {
|
|
818
|
+
emit("debug", resolveState(), args);
|
|
819
|
+
},
|
|
820
|
+
warn(...args) {
|
|
821
|
+
emit("warn", resolveState(), args);
|
|
822
|
+
},
|
|
823
|
+
error(...args) {
|
|
824
|
+
emit("error", resolveState(), args);
|
|
825
|
+
}
|
|
826
|
+
};
|
|
827
|
+
}
|
|
828
|
+
var debugLogger = {
|
|
829
|
+
...createDebugLogger(),
|
|
830
|
+
forState(state) {
|
|
831
|
+
return createDebugLogger(state);
|
|
832
|
+
}
|
|
833
|
+
};
|
|
834
|
+
setGlobalHookErrorReporter((error) => {
|
|
835
|
+
debugLogger.error("Global instrumentation hook error:", error);
|
|
836
|
+
});
|
|
837
|
+
|
|
590
838
|
// src/instrumentation/core/stream-patcher.ts
|
|
591
839
|
function isAsyncIterable(value) {
|
|
592
840
|
return value !== null && typeof value === "object" && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
@@ -611,112 +859,133 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
611
859
|
);
|
|
612
860
|
return stream;
|
|
613
861
|
}
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
862
|
+
const chunks = [];
|
|
863
|
+
let completed = false;
|
|
864
|
+
const notifyCancellation = async () => {
|
|
865
|
+
try {
|
|
866
|
+
await (options.onCancel ?? options.onComplete)(chunks);
|
|
867
|
+
} catch (error) {
|
|
868
|
+
debugLogger.error("Error in stream cancellation handler:", error);
|
|
617
869
|
}
|
|
870
|
+
};
|
|
871
|
+
const patchAbortIfPresent = () => {
|
|
618
872
|
try {
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
try {
|
|
626
|
-
const result = await runNextWithWrapper(
|
|
627
|
-
options,
|
|
628
|
-
() => originalNext(...args)
|
|
629
|
-
);
|
|
630
|
-
if (result.done) {
|
|
873
|
+
if ("abort" in stream && typeof stream.abort === "function") {
|
|
874
|
+
const originalAbort = stream.abort.bind(stream);
|
|
875
|
+
stream.abort = (...args) => {
|
|
876
|
+
try {
|
|
877
|
+
return originalAbort(...args);
|
|
878
|
+
} finally {
|
|
631
879
|
if (!completed) {
|
|
632
880
|
completed = true;
|
|
633
|
-
|
|
634
|
-
await options.onComplete(chunks);
|
|
635
|
-
} catch (error) {
|
|
636
|
-
console.error("Error in stream onComplete handler:", error);
|
|
637
|
-
}
|
|
638
|
-
}
|
|
639
|
-
} else {
|
|
640
|
-
const chunk = result.value;
|
|
641
|
-
const shouldCollect = options.shouldCollect ? options.shouldCollect(chunk) : true;
|
|
642
|
-
if (shouldCollect) {
|
|
643
|
-
chunks.push(chunk);
|
|
644
|
-
if (options.onChunk) {
|
|
645
|
-
try {
|
|
646
|
-
await options.onChunk(chunk);
|
|
647
|
-
} catch (error) {
|
|
648
|
-
console.error("Error in stream onChunk handler:", error);
|
|
649
|
-
}
|
|
650
|
-
}
|
|
881
|
+
void notifyCancellation();
|
|
651
882
|
}
|
|
652
883
|
}
|
|
653
|
-
return result;
|
|
654
|
-
} catch (error) {
|
|
655
|
-
if (!completed) {
|
|
656
|
-
completed = true;
|
|
657
|
-
if (options.onError) {
|
|
658
|
-
try {
|
|
659
|
-
await options.onError(
|
|
660
|
-
error instanceof Error ? error : new Error(String(error)),
|
|
661
|
-
chunks
|
|
662
|
-
);
|
|
663
|
-
} catch (handlerError) {
|
|
664
|
-
console.error("Error in stream onError handler:", handlerError);
|
|
665
|
-
}
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
throw error;
|
|
669
|
-
}
|
|
670
|
-
};
|
|
671
|
-
if (originalReturn) {
|
|
672
|
-
stream.return = async (...args) => {
|
|
673
|
-
if (!completed) {
|
|
674
|
-
completed = true;
|
|
675
|
-
try {
|
|
676
|
-
await options.onComplete(chunks);
|
|
677
|
-
} catch (error) {
|
|
678
|
-
console.error("Error in stream onComplete handler:", error);
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
|
-
return originalReturn(...args);
|
|
682
|
-
};
|
|
683
|
-
}
|
|
684
|
-
if (originalThrow) {
|
|
685
|
-
stream.throw = async (...args) => {
|
|
686
|
-
if (!completed) {
|
|
687
|
-
completed = true;
|
|
688
|
-
const rawError = args[0];
|
|
689
|
-
const error = rawError instanceof Error ? rawError : new Error(String(rawError));
|
|
690
|
-
if (options.onError) {
|
|
691
|
-
try {
|
|
692
|
-
await options.onError(error, chunks);
|
|
693
|
-
} catch (handlerError) {
|
|
694
|
-
console.error("Error in stream onError handler:", handlerError);
|
|
695
|
-
}
|
|
696
|
-
}
|
|
697
|
-
}
|
|
698
|
-
return originalThrow(...args);
|
|
699
884
|
};
|
|
700
885
|
}
|
|
701
|
-
Object.defineProperty(stream, "__braintrust_patched_iterator_methods", {
|
|
702
|
-
value: true
|
|
703
|
-
});
|
|
704
|
-
return stream;
|
|
705
886
|
} catch (error) {
|
|
706
|
-
|
|
887
|
+
debugLogger.warn("Failed to patch stream abort method:", error);
|
|
707
888
|
}
|
|
708
|
-
}
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
const
|
|
716
|
-
const
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
889
|
+
};
|
|
890
|
+
if (hasAsyncIteratorMethods(stream) && isSelfAsyncIterator(stream)) {
|
|
891
|
+
if ("__braintrust_patched_iterator_methods" in stream) {
|
|
892
|
+
return stream;
|
|
893
|
+
}
|
|
894
|
+
try {
|
|
895
|
+
const originalNext = stream.next.bind(stream);
|
|
896
|
+
const originalReturn = typeof stream.return === "function" ? stream.return.bind(stream) : null;
|
|
897
|
+
const originalThrow = typeof stream.throw === "function" ? stream.throw.bind(stream) : null;
|
|
898
|
+
stream.next = async (...args) => {
|
|
899
|
+
try {
|
|
900
|
+
const result = await runNextWithWrapper(
|
|
901
|
+
options,
|
|
902
|
+
() => originalNext(...args)
|
|
903
|
+
);
|
|
904
|
+
if (result.done) {
|
|
905
|
+
if (!completed) {
|
|
906
|
+
completed = true;
|
|
907
|
+
try {
|
|
908
|
+
await options.onComplete(chunks);
|
|
909
|
+
} catch (error) {
|
|
910
|
+
console.error("Error in stream onComplete handler:", error);
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
} else {
|
|
914
|
+
const chunk = result.value;
|
|
915
|
+
const shouldCollect = options.shouldCollect ? options.shouldCollect(chunk) : true;
|
|
916
|
+
if (shouldCollect) {
|
|
917
|
+
chunks.push(chunk);
|
|
918
|
+
if (options.onChunk) {
|
|
919
|
+
try {
|
|
920
|
+
await options.onChunk(chunk);
|
|
921
|
+
} catch (error) {
|
|
922
|
+
console.error("Error in stream onChunk handler:", error);
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
return result;
|
|
928
|
+
} catch (error) {
|
|
929
|
+
if (!completed) {
|
|
930
|
+
completed = true;
|
|
931
|
+
if (options.onError) {
|
|
932
|
+
try {
|
|
933
|
+
await options.onError(
|
|
934
|
+
error instanceof Error ? error : new Error(String(error)),
|
|
935
|
+
chunks
|
|
936
|
+
);
|
|
937
|
+
} catch (handlerError) {
|
|
938
|
+
console.error("Error in stream onError handler:", handlerError);
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
throw error;
|
|
943
|
+
}
|
|
944
|
+
};
|
|
945
|
+
if (originalReturn) {
|
|
946
|
+
stream.return = async (...args) => {
|
|
947
|
+
if (!completed) {
|
|
948
|
+
completed = true;
|
|
949
|
+
await notifyCancellation();
|
|
950
|
+
}
|
|
951
|
+
return originalReturn(...args);
|
|
952
|
+
};
|
|
953
|
+
}
|
|
954
|
+
if (originalThrow) {
|
|
955
|
+
stream.throw = async (...args) => {
|
|
956
|
+
if (!completed) {
|
|
957
|
+
completed = true;
|
|
958
|
+
const rawError = args[0];
|
|
959
|
+
const error = rawError instanceof Error ? rawError : new Error(String(rawError));
|
|
960
|
+
if (options.onError) {
|
|
961
|
+
try {
|
|
962
|
+
await options.onError(error, chunks);
|
|
963
|
+
} catch (handlerError) {
|
|
964
|
+
console.error("Error in stream onError handler:", handlerError);
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
return originalThrow(...args);
|
|
969
|
+
};
|
|
970
|
+
}
|
|
971
|
+
Object.defineProperty(stream, "__braintrust_patched_iterator_methods", {
|
|
972
|
+
value: true
|
|
973
|
+
});
|
|
974
|
+
patchAbortIfPresent();
|
|
975
|
+
return stream;
|
|
976
|
+
} catch (error) {
|
|
977
|
+
console.warn("Failed to patch stream iterator methods:", error);
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
const originalIteratorFn = stream[Symbol.asyncIterator];
|
|
981
|
+
if ("__braintrust_patched" in originalIteratorFn && originalIteratorFn["__braintrust_patched"]) {
|
|
982
|
+
return stream;
|
|
983
|
+
}
|
|
984
|
+
try {
|
|
985
|
+
const patchedIteratorFn = function() {
|
|
986
|
+
const iterator = originalIteratorFn.call(this);
|
|
987
|
+
const originalNext = iterator.next.bind(iterator);
|
|
988
|
+
iterator.next = async function(...args) {
|
|
720
989
|
try {
|
|
721
990
|
const result = await runNextWithWrapper(
|
|
722
991
|
options,
|
|
@@ -768,11 +1037,7 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
768
1037
|
iterator.return = async function(...args) {
|
|
769
1038
|
if (!completed) {
|
|
770
1039
|
completed = true;
|
|
771
|
-
|
|
772
|
-
await options.onComplete(chunks);
|
|
773
|
-
} catch (error) {
|
|
774
|
-
console.error("Error in stream onComplete handler:", error);
|
|
775
|
-
}
|
|
1040
|
+
await notifyCancellation();
|
|
776
1041
|
}
|
|
777
1042
|
return originalReturn(...args);
|
|
778
1043
|
};
|
|
@@ -801,6 +1066,7 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
801
1066
|
value: true
|
|
802
1067
|
});
|
|
803
1068
|
stream[Symbol.asyncIterator] = patchedIteratorFn;
|
|
1069
|
+
patchAbortIfPresent();
|
|
804
1070
|
return stream;
|
|
805
1071
|
} catch (error) {
|
|
806
1072
|
console.warn("Failed to patch stream:", error);
|
|
@@ -814,114 +1080,6 @@ function runNextWithWrapper(options, callback) {
|
|
|
814
1080
|
// src/logger.ts
|
|
815
1081
|
var import_uuid2 = require("uuid");
|
|
816
1082
|
|
|
817
|
-
// src/debug-logger.ts
|
|
818
|
-
var PREFIX = "[braintrust]";
|
|
819
|
-
var DEBUG_LOG_LEVEL_SYMBOL = /* @__PURE__ */ Symbol.for("braintrust-debug-log-level");
|
|
820
|
-
var LOG_LEVEL_PRIORITY = {
|
|
821
|
-
error: 0,
|
|
822
|
-
warn: 1,
|
|
823
|
-
info: 2,
|
|
824
|
-
debug: 3
|
|
825
|
-
};
|
|
826
|
-
var hasWarnedAboutInvalidEnvValue = false;
|
|
827
|
-
var debugLogStateResolver = void 0;
|
|
828
|
-
function warnInvalidEnvValue(value) {
|
|
829
|
-
if (hasWarnedAboutInvalidEnvValue) {
|
|
830
|
-
return;
|
|
831
|
-
}
|
|
832
|
-
hasWarnedAboutInvalidEnvValue = true;
|
|
833
|
-
console.warn(
|
|
834
|
-
PREFIX,
|
|
835
|
-
`Invalid BRAINTRUST_DEBUG_LOG_LEVEL value "${value}". Expected "error", "warn", "info", or "debug".`
|
|
836
|
-
);
|
|
837
|
-
}
|
|
838
|
-
function normalizeDebugLogLevelOption(option) {
|
|
839
|
-
if (option === false) {
|
|
840
|
-
return void 0;
|
|
841
|
-
}
|
|
842
|
-
if (option === "error" || option === "warn" || option === "info" || option === "debug") {
|
|
843
|
-
return option;
|
|
844
|
-
}
|
|
845
|
-
throw new Error(
|
|
846
|
-
`Invalid debugLogLevel value "${option}". Expected false, "error", "warn", "info", or "debug".`
|
|
847
|
-
);
|
|
848
|
-
}
|
|
849
|
-
function parseDebugLogLevelEnv(value) {
|
|
850
|
-
if (!value) {
|
|
851
|
-
return void 0;
|
|
852
|
-
}
|
|
853
|
-
if (value === "error" || value === "warn" || value === "info" || value === "debug") {
|
|
854
|
-
return value;
|
|
855
|
-
}
|
|
856
|
-
warnInvalidEnvValue(value);
|
|
857
|
-
return void 0;
|
|
858
|
-
}
|
|
859
|
-
function getEnvDebugLogLevel() {
|
|
860
|
-
return parseDebugLogLevelEnv(isomorph_default.getEnv("BRAINTRUST_DEBUG_LOG_LEVEL"));
|
|
861
|
-
}
|
|
862
|
-
function setGlobalDebugLogLevel(level) {
|
|
863
|
-
globalThis[DEBUG_LOG_LEVEL_SYMBOL] = level;
|
|
864
|
-
}
|
|
865
|
-
function setDebugLogStateResolver(resolver) {
|
|
866
|
-
debugLogStateResolver = resolver;
|
|
867
|
-
}
|
|
868
|
-
function resolveDebugLogLevel(state) {
|
|
869
|
-
const stateLevel = state?.getDebugLogLevel?.();
|
|
870
|
-
const hasStateOverride = state?.hasDebugLogLevelOverride?.() ?? false;
|
|
871
|
-
if (hasStateOverride) {
|
|
872
|
-
return stateLevel;
|
|
873
|
-
}
|
|
874
|
-
const globalLevel = (
|
|
875
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
876
|
-
globalThis[DEBUG_LOG_LEVEL_SYMBOL]
|
|
877
|
-
);
|
|
878
|
-
if (globalLevel !== void 0) {
|
|
879
|
-
return globalLevel === false ? void 0 : globalLevel;
|
|
880
|
-
}
|
|
881
|
-
return getEnvDebugLogLevel();
|
|
882
|
-
}
|
|
883
|
-
function emit(method, state, args) {
|
|
884
|
-
const level = resolveDebugLogLevel(state);
|
|
885
|
-
if (!level || LOG_LEVEL_PRIORITY[method] > LOG_LEVEL_PRIORITY[level]) {
|
|
886
|
-
return;
|
|
887
|
-
}
|
|
888
|
-
if (method === "info") {
|
|
889
|
-
console.log(PREFIX, ...args);
|
|
890
|
-
} else if (method === "debug") {
|
|
891
|
-
console.debug(PREFIX, ...args);
|
|
892
|
-
} else if (method === "warn") {
|
|
893
|
-
console.warn(PREFIX, ...args);
|
|
894
|
-
} else {
|
|
895
|
-
console.error(PREFIX, ...args);
|
|
896
|
-
}
|
|
897
|
-
}
|
|
898
|
-
function createDebugLogger(state) {
|
|
899
|
-
const resolveState = () => state ?? debugLogStateResolver?.();
|
|
900
|
-
return {
|
|
901
|
-
info(...args) {
|
|
902
|
-
emit("info", resolveState(), args);
|
|
903
|
-
},
|
|
904
|
-
debug(...args) {
|
|
905
|
-
emit("debug", resolveState(), args);
|
|
906
|
-
},
|
|
907
|
-
warn(...args) {
|
|
908
|
-
emit("warn", resolveState(), args);
|
|
909
|
-
},
|
|
910
|
-
error(...args) {
|
|
911
|
-
emit("error", resolveState(), args);
|
|
912
|
-
}
|
|
913
|
-
};
|
|
914
|
-
}
|
|
915
|
-
var debugLogger = {
|
|
916
|
-
...createDebugLogger(),
|
|
917
|
-
forState(state) {
|
|
918
|
-
return createDebugLogger(state);
|
|
919
|
-
}
|
|
920
|
-
};
|
|
921
|
-
setGlobalHookErrorReporter((error) => {
|
|
922
|
-
debugLogger.error("Global instrumentation hook error:", error);
|
|
923
|
-
});
|
|
924
|
-
|
|
925
1083
|
// src/queue.ts
|
|
926
1084
|
var DEFAULT_QUEUE_SIZE = 15e3;
|
|
927
1085
|
var Queue = class {
|
|
@@ -5426,6 +5584,7 @@ var INSTRUMENTATION_NAMES = {
|
|
|
5426
5584
|
CLAUDE_AGENT_SDK: "claude-agent-sdk",
|
|
5427
5585
|
CLOUDFLARE_AI_CHAT: "cloudflare-ai-chat",
|
|
5428
5586
|
CLOUDFLARE_AGENTS: "cloudflare-agents",
|
|
5587
|
+
CLOUDFLARE_THINK: "cloudflare-think",
|
|
5429
5588
|
COHERE: "cohere",
|
|
5430
5589
|
CURSOR_SDK: "cursor-sdk",
|
|
5431
5590
|
EVE: "eve",
|
|
@@ -5440,6 +5599,7 @@ var INSTRUMENTATION_NAMES = {
|
|
|
5440
5599
|
LANGSMITH: "langsmith",
|
|
5441
5600
|
MASTRA: "mastra",
|
|
5442
5601
|
MISTRAL: "mistral",
|
|
5602
|
+
OLLAMA: "ollama",
|
|
5443
5603
|
OPENAI: "openai",
|
|
5444
5604
|
OPENAI_AGENTS: "openai-agents",
|
|
5445
5605
|
OPENAI_CODEX: "openai-codex",
|
|
@@ -5451,7 +5611,7 @@ var INSTRUMENTATION_NAMES = {
|
|
|
5451
5611
|
var INTERNAL_SPAN_INSTRUMENTATION_NAME = /* @__PURE__ */ Symbol.for(
|
|
5452
5612
|
"braintrust.spanInstrumentationName"
|
|
5453
5613
|
);
|
|
5454
|
-
var SDK_VERSION = true ? "3.
|
|
5614
|
+
var SDK_VERSION = true ? "3.27.0" : "0.0.0";
|
|
5455
5615
|
function withSpanInstrumentationName(args, instrumentationName) {
|
|
5456
5616
|
return {
|
|
5457
5617
|
...args,
|
|
@@ -10472,6 +10632,33 @@ function traceStreamingChannel(channel2, config) {
|
|
|
10472
10632
|
const { span, startTime } = spanData;
|
|
10473
10633
|
if (isAsyncIterable(asyncEndEvent.result)) {
|
|
10474
10634
|
let firstChunkTime;
|
|
10635
|
+
const handleStreamError = (error) => {
|
|
10636
|
+
try {
|
|
10637
|
+
span.log({ error });
|
|
10638
|
+
} catch (loggingError) {
|
|
10639
|
+
debugLogger.error(
|
|
10640
|
+
`Error logging failure for ${channelName}:`,
|
|
10641
|
+
loggingError
|
|
10642
|
+
);
|
|
10643
|
+
}
|
|
10644
|
+
try {
|
|
10645
|
+
span.end();
|
|
10646
|
+
} catch (endingError) {
|
|
10647
|
+
debugLogger.error(
|
|
10648
|
+
`Error ending span for ${channelName}:`,
|
|
10649
|
+
endingError
|
|
10650
|
+
);
|
|
10651
|
+
}
|
|
10652
|
+
states.delete(event);
|
|
10653
|
+
runStreamingErrorHook({
|
|
10654
|
+
channelName,
|
|
10655
|
+
config,
|
|
10656
|
+
error,
|
|
10657
|
+
event: asyncEndEvent,
|
|
10658
|
+
span,
|
|
10659
|
+
startTime
|
|
10660
|
+
});
|
|
10661
|
+
};
|
|
10475
10662
|
patchStreamIfNeeded(asyncEndEvent.result, {
|
|
10476
10663
|
onChunk: () => {
|
|
10477
10664
|
if (firstChunkTime === void 0) {
|
|
@@ -10551,33 +10738,12 @@ function traceStreamingChannel(channel2, config) {
|
|
|
10551
10738
|
});
|
|
10552
10739
|
}
|
|
10553
10740
|
},
|
|
10554
|
-
|
|
10555
|
-
|
|
10556
|
-
|
|
10557
|
-
|
|
10558
|
-
|
|
10559
|
-
|
|
10560
|
-
loggingError
|
|
10561
|
-
);
|
|
10562
|
-
}
|
|
10563
|
-
try {
|
|
10564
|
-
span.end();
|
|
10565
|
-
} catch (endingError) {
|
|
10566
|
-
debugLogger.error(
|
|
10567
|
-
`Error ending span for ${channelName}:`,
|
|
10568
|
-
endingError
|
|
10569
|
-
);
|
|
10570
|
-
}
|
|
10571
|
-
states.delete(event);
|
|
10572
|
-
runStreamingErrorHook({
|
|
10573
|
-
channelName,
|
|
10574
|
-
config,
|
|
10575
|
-
error,
|
|
10576
|
-
event: asyncEndEvent,
|
|
10577
|
-
span,
|
|
10578
|
-
startTime
|
|
10579
|
-
});
|
|
10580
|
-
}
|
|
10741
|
+
onCancel: () => {
|
|
10742
|
+
const error = new Error("Stream cancelled before completion");
|
|
10743
|
+
error.name = "AbortError";
|
|
10744
|
+
handleStreamError(error);
|
|
10745
|
+
},
|
|
10746
|
+
onError: handleStreamError
|
|
10581
10747
|
});
|
|
10582
10748
|
return;
|
|
10583
10749
|
}
|
|
@@ -10965,11 +11131,21 @@ function defineChannels(pkg, channels, options) {
|
|
|
10965
11131
|
const tracingChannel2 = () => isomorph_default.newTracingChannel(
|
|
10966
11132
|
fullChannelName
|
|
10967
11133
|
);
|
|
11134
|
+
const intercept2 = (interceptor) => {
|
|
11135
|
+
const hook = tracingChannel2();
|
|
11136
|
+
return typeof hook.intercept === "function" ? hook.intercept(interceptor) : () => {
|
|
11137
|
+
};
|
|
11138
|
+
};
|
|
10968
11139
|
return [
|
|
10969
11140
|
key,
|
|
10970
11141
|
{
|
|
10971
11142
|
...asyncSpec,
|
|
10972
11143
|
instrumentationName,
|
|
11144
|
+
intercept: intercept2,
|
|
11145
|
+
invoke: (target, thisArg, args, additional) => {
|
|
11146
|
+
const hook = tracingChannel2();
|
|
11147
|
+
return typeof hook.invoke === "function" ? hook.invoke(target, thisArg, args, additional) : Reflect.apply(target, thisArg, args);
|
|
11148
|
+
},
|
|
10973
11149
|
tracingChannel: tracingChannel2,
|
|
10974
11150
|
tracePromise: (fn, context) => tracingChannel2().tracePromise(
|
|
10975
11151
|
fn,
|
|
@@ -10983,11 +11159,21 @@ function defineChannels(pkg, channels, options) {
|
|
|
10983
11159
|
const tracingChannel = () => isomorph_default.newTracingChannel(
|
|
10984
11160
|
fullChannelName
|
|
10985
11161
|
);
|
|
11162
|
+
const intercept = (interceptor) => {
|
|
11163
|
+
const hook = tracingChannel();
|
|
11164
|
+
return typeof hook.intercept === "function" ? hook.intercept(interceptor) : () => {
|
|
11165
|
+
};
|
|
11166
|
+
};
|
|
10986
11167
|
return [
|
|
10987
11168
|
key,
|
|
10988
11169
|
{
|
|
10989
11170
|
...syncSpec,
|
|
10990
11171
|
instrumentationName,
|
|
11172
|
+
intercept,
|
|
11173
|
+
invoke: (target, thisArg, args, additional) => {
|
|
11174
|
+
const hook = tracingChannel();
|
|
11175
|
+
return typeof hook.invoke === "function" ? hook.invoke(target, thisArg, args, additional) : Reflect.apply(target, thisArg, args);
|
|
11176
|
+
},
|
|
10991
11177
|
tracingChannel,
|
|
10992
11178
|
traceSync: (fn, context) => tracingChannel().traceSync(
|
|
10993
11179
|
fn,
|
|
@@ -12238,6 +12424,12 @@ function extractAnthropicCacheTokens(cacheReadTokens = 0, cacheCreationTokens =
|
|
|
12238
12424
|
return cacheTokens;
|
|
12239
12425
|
}
|
|
12240
12426
|
|
|
12427
|
+
// src/wrappers/anthropic-session-collector.ts
|
|
12428
|
+
var sessionStreamCollectors = /* @__PURE__ */ new WeakMap();
|
|
12429
|
+
function registerAnthropicSessionStreamCollector(stream, collector) {
|
|
12430
|
+
sessionStreamCollectors.set(stream, collector);
|
|
12431
|
+
}
|
|
12432
|
+
|
|
12241
12433
|
// src/instrumentation/plugins/anthropic-channels.ts
|
|
12242
12434
|
var anthropicChannels = defineChannels(
|
|
12243
12435
|
"@anthropic-ai/sdk",
|
|
@@ -12253,6 +12445,14 @@ var anthropicChannels = defineChannels(
|
|
|
12253
12445
|
betaMessagesToolRunner: channel({
|
|
12254
12446
|
channelName: "beta.messages.toolRunner",
|
|
12255
12447
|
kind: "sync-stream"
|
|
12448
|
+
}),
|
|
12449
|
+
betaSessionsEventsStream: channel({
|
|
12450
|
+
channelName: "beta.sessions.events.stream",
|
|
12451
|
+
kind: "async"
|
|
12452
|
+
}),
|
|
12453
|
+
betaSessionsThreadsEventsStream: channel({
|
|
12454
|
+
channelName: "beta.sessions.threads.events.stream",
|
|
12455
|
+
kind: "async"
|
|
12256
12456
|
})
|
|
12257
12457
|
},
|
|
12258
12458
|
{ instrumentationName: INSTRUMENTATION_NAMES.ANTHROPIC }
|
|
@@ -12266,6 +12466,7 @@ var AnthropicPlugin = class extends BasePlugin {
|
|
|
12266
12466
|
onEnable() {
|
|
12267
12467
|
this.subscribeToAnthropicChannels();
|
|
12268
12468
|
this.subscribeToAnthropicToolRunner();
|
|
12469
|
+
this.subscribeToAnthropicSessionStreams();
|
|
12269
12470
|
}
|
|
12270
12471
|
onDisable() {
|
|
12271
12472
|
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
@@ -12383,7 +12584,411 @@ var AnthropicPlugin = class extends BasePlugin {
|
|
|
12383
12584
|
tracingChannel.unsubscribe(handlers);
|
|
12384
12585
|
});
|
|
12385
12586
|
}
|
|
12587
|
+
subscribeToAnthropicSessionStreams() {
|
|
12588
|
+
this.subscribeToAnthropicSessionStream(
|
|
12589
|
+
anthropicChannels.betaSessionsEventsStream,
|
|
12590
|
+
false
|
|
12591
|
+
);
|
|
12592
|
+
this.subscribeToAnthropicSessionStream(
|
|
12593
|
+
anthropicChannels.betaSessionsThreadsEventsStream,
|
|
12594
|
+
true
|
|
12595
|
+
);
|
|
12596
|
+
}
|
|
12597
|
+
subscribeToAnthropicSessionStream(channel2, isThread) {
|
|
12598
|
+
const tracingChannel = channel2.tracingChannel();
|
|
12599
|
+
const pending = /* @__PURE__ */ new WeakSet();
|
|
12600
|
+
const handlers = {
|
|
12601
|
+
start: (event) => {
|
|
12602
|
+
if (isAutoInstrumentationSuppressed()) {
|
|
12603
|
+
return;
|
|
12604
|
+
}
|
|
12605
|
+
pending.add(event);
|
|
12606
|
+
},
|
|
12607
|
+
asyncEnd: (event) => {
|
|
12608
|
+
if (!pending.delete(event)) {
|
|
12609
|
+
return;
|
|
12610
|
+
}
|
|
12611
|
+
const stream = event.result;
|
|
12612
|
+
if (!isAsyncIterable(stream)) {
|
|
12613
|
+
return;
|
|
12614
|
+
}
|
|
12615
|
+
registerAnthropicSessionStreamCollector(stream, () => {
|
|
12616
|
+
wrapAnthropicSessionEventStream(stream, isThread);
|
|
12617
|
+
});
|
|
12618
|
+
},
|
|
12619
|
+
error: (event) => {
|
|
12620
|
+
pending.delete(event);
|
|
12621
|
+
}
|
|
12622
|
+
};
|
|
12623
|
+
tracingChannel.subscribe(handlers);
|
|
12624
|
+
this.unsubscribers.push(() => tracingChannel.unsubscribe(handlers));
|
|
12625
|
+
}
|
|
12386
12626
|
};
|
|
12627
|
+
function wrapAnthropicSessionEventStream(stream, isThread) {
|
|
12628
|
+
const state = {
|
|
12629
|
+
history: [],
|
|
12630
|
+
isThread,
|
|
12631
|
+
pendingInput: [],
|
|
12632
|
+
seenEventIds: /* @__PURE__ */ new Set()
|
|
12633
|
+
};
|
|
12634
|
+
patchStreamIfNeeded(stream, {
|
|
12635
|
+
onChunk: (event) => handleAnthropicSessionEvent(state, event),
|
|
12636
|
+
onComplete: () => finalizeAnthropicSessionTurn(state),
|
|
12637
|
+
onError: (error) => finalizeAnthropicSessionTurn(state, error)
|
|
12638
|
+
});
|
|
12639
|
+
return stream;
|
|
12640
|
+
}
|
|
12641
|
+
function handleAnthropicSessionEvent(state, event) {
|
|
12642
|
+
try {
|
|
12643
|
+
if (typeof event.id === "string" && event.type !== "event_delta" && state.seenEventIds.has(event.id)) {
|
|
12644
|
+
return;
|
|
12645
|
+
}
|
|
12646
|
+
if (typeof event.id === "string" && event.type !== "event_delta") {
|
|
12647
|
+
state.seenEventIds.add(event.id);
|
|
12648
|
+
}
|
|
12649
|
+
switch (event.type) {
|
|
12650
|
+
case "user.message":
|
|
12651
|
+
case "system.message":
|
|
12652
|
+
recordAnthropicSessionInput(
|
|
12653
|
+
state,
|
|
12654
|
+
event
|
|
12655
|
+
);
|
|
12656
|
+
break;
|
|
12657
|
+
case "session.status_running":
|
|
12658
|
+
if (!state.isThread) {
|
|
12659
|
+
ensureAnthropicSessionTurn(state);
|
|
12660
|
+
}
|
|
12661
|
+
break;
|
|
12662
|
+
case "session.thread_status_running":
|
|
12663
|
+
if (state.isThread) {
|
|
12664
|
+
ensureAnthropicSessionTurn(state);
|
|
12665
|
+
}
|
|
12666
|
+
break;
|
|
12667
|
+
case "span.model_request_start":
|
|
12668
|
+
if (typeof event.id === "string") {
|
|
12669
|
+
startAnthropicSessionModel(state, event.id);
|
|
12670
|
+
}
|
|
12671
|
+
break;
|
|
12672
|
+
case "event_delta":
|
|
12673
|
+
recordAnthropicSessionFirstToken(state, event);
|
|
12674
|
+
break;
|
|
12675
|
+
case "agent.message":
|
|
12676
|
+
recordAnthropicSessionMessage(
|
|
12677
|
+
state,
|
|
12678
|
+
event
|
|
12679
|
+
);
|
|
12680
|
+
break;
|
|
12681
|
+
case "agent.custom_tool_use":
|
|
12682
|
+
case "agent.mcp_tool_use":
|
|
12683
|
+
case "agent.tool_use":
|
|
12684
|
+
startAnthropicSessionTool(state, event);
|
|
12685
|
+
break;
|
|
12686
|
+
case "user.tool_confirmation":
|
|
12687
|
+
recordAnthropicSessionToolConfirmation(state, event);
|
|
12688
|
+
break;
|
|
12689
|
+
case "agent.mcp_tool_result":
|
|
12690
|
+
case "agent.tool_result":
|
|
12691
|
+
case "user.custom_tool_result":
|
|
12692
|
+
case "user.tool_result":
|
|
12693
|
+
finalizeAnthropicSessionTool(
|
|
12694
|
+
state,
|
|
12695
|
+
event
|
|
12696
|
+
);
|
|
12697
|
+
break;
|
|
12698
|
+
case "span.model_request_end":
|
|
12699
|
+
finalizeAnthropicSessionModel(
|
|
12700
|
+
state,
|
|
12701
|
+
event
|
|
12702
|
+
);
|
|
12703
|
+
break;
|
|
12704
|
+
case "session.status_idle":
|
|
12705
|
+
case "session.thread_status_idle": {
|
|
12706
|
+
if (event.type === "session.status_idle" && state.isThread || event.type === "session.thread_status_idle" && !state.isThread) {
|
|
12707
|
+
break;
|
|
12708
|
+
}
|
|
12709
|
+
const stopReason = isObject(event.stop_reason) ? event.stop_reason.type : void 0;
|
|
12710
|
+
if (stopReason === "end_turn") {
|
|
12711
|
+
finalizeAnthropicSessionTurn(state);
|
|
12712
|
+
} else if (stopReason === "retries_exhausted") {
|
|
12713
|
+
finalizeAnthropicSessionTurn(
|
|
12714
|
+
state,
|
|
12715
|
+
"Anthropic session retries exhausted"
|
|
12716
|
+
);
|
|
12717
|
+
}
|
|
12718
|
+
break;
|
|
12719
|
+
}
|
|
12720
|
+
case "session.error":
|
|
12721
|
+
finalizeAnthropicSessionTurn(state, event.error);
|
|
12722
|
+
break;
|
|
12723
|
+
case "session.deleted":
|
|
12724
|
+
case "session.status_terminated":
|
|
12725
|
+
case "session.thread_status_terminated":
|
|
12726
|
+
if (event.type === "session.deleted" || event.type === "session.status_terminated" && !state.isThread || event.type === "session.thread_status_terminated" && state.isThread) {
|
|
12727
|
+
finalizeAnthropicSessionTurn(state);
|
|
12728
|
+
}
|
|
12729
|
+
break;
|
|
12730
|
+
default:
|
|
12731
|
+
break;
|
|
12732
|
+
}
|
|
12733
|
+
} catch (error) {
|
|
12734
|
+
debugLogger.debug("Error processing Anthropic Sessions event:", error);
|
|
12735
|
+
}
|
|
12736
|
+
}
|
|
12737
|
+
function ensureAnthropicSessionTurn(state) {
|
|
12738
|
+
if (state.activeTurn) {
|
|
12739
|
+
return state.activeTurn;
|
|
12740
|
+
}
|
|
12741
|
+
const input = state.pendingInput;
|
|
12742
|
+
state.pendingInput = [];
|
|
12743
|
+
const span = startSpan(
|
|
12744
|
+
withSpanInstrumentationName(
|
|
12745
|
+
{
|
|
12746
|
+
event: {
|
|
12747
|
+
...input.length > 0 ? { input } : {},
|
|
12748
|
+
metadata: { provider: "anthropic" }
|
|
12749
|
+
},
|
|
12750
|
+
name: state.isThread ? "anthropic.beta.sessions.thread.turn" : "anthropic.beta.sessions.turn",
|
|
12751
|
+
spanAttributes: { type: "task" /* TASK */ }
|
|
12752
|
+
},
|
|
12753
|
+
INSTRUMENTATION_NAMES.ANTHROPIC
|
|
12754
|
+
)
|
|
12755
|
+
);
|
|
12756
|
+
state.activeTurn = {
|
|
12757
|
+
activeTools: /* @__PURE__ */ new Map(),
|
|
12758
|
+
input: input.slice(),
|
|
12759
|
+
metrics: {},
|
|
12760
|
+
span
|
|
12761
|
+
};
|
|
12762
|
+
return state.activeTurn;
|
|
12763
|
+
}
|
|
12764
|
+
function recordAnthropicSessionInput(state, event) {
|
|
12765
|
+
const content = processAttachmentsInInput(event.content);
|
|
12766
|
+
const message = {
|
|
12767
|
+
role: event.type === "system.message" ? "system" : "user",
|
|
12768
|
+
content
|
|
12769
|
+
};
|
|
12770
|
+
state.history.push(message);
|
|
12771
|
+
if (state.activeTurn) {
|
|
12772
|
+
state.activeTurn.input.push(message);
|
|
12773
|
+
} else {
|
|
12774
|
+
state.pendingInput.push(message);
|
|
12775
|
+
}
|
|
12776
|
+
}
|
|
12777
|
+
function startAnthropicSessionModel(state, startEventId) {
|
|
12778
|
+
const turn = ensureAnthropicSessionTurn(state);
|
|
12779
|
+
if (turn.activeModel) {
|
|
12780
|
+
finalizeAnthropicSessionModelState(state, turn);
|
|
12781
|
+
}
|
|
12782
|
+
const span = withCurrent(
|
|
12783
|
+
turn.span,
|
|
12784
|
+
() => startSpan(
|
|
12785
|
+
withSpanInstrumentationName(
|
|
12786
|
+
{
|
|
12787
|
+
event: {
|
|
12788
|
+
...state.history.length > 0 ? { input: state.history.slice() } : {},
|
|
12789
|
+
metadata: { provider: "anthropic" }
|
|
12790
|
+
},
|
|
12791
|
+
name: "anthropic.messages.create",
|
|
12792
|
+
spanAttributes: { type: "llm" /* LLM */ }
|
|
12793
|
+
},
|
|
12794
|
+
INSTRUMENTATION_NAMES.ANTHROPIC
|
|
12795
|
+
)
|
|
12796
|
+
)
|
|
12797
|
+
);
|
|
12798
|
+
turn.activeModel = {
|
|
12799
|
+
output: [],
|
|
12800
|
+
span,
|
|
12801
|
+
startEventId,
|
|
12802
|
+
startTime: getCurrentUnixTimestamp()
|
|
12803
|
+
};
|
|
12804
|
+
}
|
|
12805
|
+
function recordAnthropicSessionFirstToken(state, event) {
|
|
12806
|
+
const model = state.activeTurn?.activeModel;
|
|
12807
|
+
if (!model || model.firstTokenTime !== void 0 || !isObject(event.delta) || !isObject(event.delta.content) || typeof event.delta.content.text !== "string") {
|
|
12808
|
+
return;
|
|
12809
|
+
}
|
|
12810
|
+
model.firstTokenTime = getCurrentUnixTimestamp();
|
|
12811
|
+
}
|
|
12812
|
+
function recordAnthropicSessionMessage(state, event) {
|
|
12813
|
+
const turn = ensureAnthropicSessionTurn(state);
|
|
12814
|
+
const content = processAttachmentsInInput(
|
|
12815
|
+
event.content
|
|
12816
|
+
);
|
|
12817
|
+
if (turn.activeModel) {
|
|
12818
|
+
turn.activeModel.output.push(...content);
|
|
12819
|
+
} else {
|
|
12820
|
+
const output = { role: "assistant", content };
|
|
12821
|
+
turn.lastOutput = output;
|
|
12822
|
+
state.history.push(output);
|
|
12823
|
+
}
|
|
12824
|
+
}
|
|
12825
|
+
function startAnthropicSessionTool(state, event) {
|
|
12826
|
+
const turn = ensureAnthropicSessionTurn(state);
|
|
12827
|
+
if (turn.activeModel) {
|
|
12828
|
+
turn.activeModel.output.push({
|
|
12829
|
+
type: "tool_use",
|
|
12830
|
+
id: event.id,
|
|
12831
|
+
name: event.name,
|
|
12832
|
+
input: event.input
|
|
12833
|
+
});
|
|
12834
|
+
}
|
|
12835
|
+
const existing = turn.activeTools.get(event.id);
|
|
12836
|
+
if (existing) {
|
|
12837
|
+
existing.span.end();
|
|
12838
|
+
turn.activeTools.delete(event.id);
|
|
12839
|
+
}
|
|
12840
|
+
const span = withCurrent(
|
|
12841
|
+
turn.span,
|
|
12842
|
+
() => startSpan(
|
|
12843
|
+
withSpanInstrumentationName(
|
|
12844
|
+
{
|
|
12845
|
+
event: { input: event.input },
|
|
12846
|
+
name: event.name,
|
|
12847
|
+
spanAttributes: { type: "tool" /* TOOL */ }
|
|
12848
|
+
},
|
|
12849
|
+
INSTRUMENTATION_NAMES.ANTHROPIC
|
|
12850
|
+
)
|
|
12851
|
+
)
|
|
12852
|
+
);
|
|
12853
|
+
const toolState = {
|
|
12854
|
+
approval: event.evaluated_permission === "allow" ? "approved" : event.evaluated_permission === "deny" ? "denied" : void 0,
|
|
12855
|
+
span
|
|
12856
|
+
};
|
|
12857
|
+
turn.activeTools.set(event.id, toolState);
|
|
12858
|
+
if (toolState.approval === "denied") {
|
|
12859
|
+
finalizeAnthropicSessionToolState(toolState);
|
|
12860
|
+
turn.activeTools.delete(event.id);
|
|
12861
|
+
}
|
|
12862
|
+
}
|
|
12863
|
+
function recordAnthropicSessionToolConfirmation(state, event) {
|
|
12864
|
+
if (typeof event.tool_use_id !== "string" || event.result !== "allow" && event.result !== "deny") {
|
|
12865
|
+
return;
|
|
12866
|
+
}
|
|
12867
|
+
const turn = state.activeTurn;
|
|
12868
|
+
const tool = turn?.activeTools.get(event.tool_use_id);
|
|
12869
|
+
if (!turn || !tool) {
|
|
12870
|
+
return;
|
|
12871
|
+
}
|
|
12872
|
+
tool.approval = event.result === "allow" ? "approved" : "denied";
|
|
12873
|
+
if (tool.approval === "denied") {
|
|
12874
|
+
finalizeAnthropicSessionToolState(tool);
|
|
12875
|
+
turn.activeTools.delete(event.tool_use_id);
|
|
12876
|
+
}
|
|
12877
|
+
}
|
|
12878
|
+
function finalizeAnthropicSessionTool(state, event) {
|
|
12879
|
+
const toolUseId = event.tool_use_id ?? event.mcp_tool_use_id ?? event.custom_tool_use_id;
|
|
12880
|
+
if (!toolUseId) {
|
|
12881
|
+
return;
|
|
12882
|
+
}
|
|
12883
|
+
const content = processAttachmentsInInput(event.content);
|
|
12884
|
+
const turn = state.activeTurn;
|
|
12885
|
+
const tool = turn?.activeTools.get(toolUseId);
|
|
12886
|
+
if (turn && tool) {
|
|
12887
|
+
finalizeAnthropicSessionToolState(tool, event, content);
|
|
12888
|
+
turn.activeTools.delete(toolUseId);
|
|
12889
|
+
}
|
|
12890
|
+
const toolResult = {
|
|
12891
|
+
type: "tool_result",
|
|
12892
|
+
tool_use_id: toolUseId,
|
|
12893
|
+
...content !== void 0 ? { content } : {},
|
|
12894
|
+
...event.is_error === true ? { is_error: true } : {}
|
|
12895
|
+
};
|
|
12896
|
+
state.history.push({
|
|
12897
|
+
role: "user",
|
|
12898
|
+
content: [toolResult]
|
|
12899
|
+
});
|
|
12900
|
+
}
|
|
12901
|
+
function finalizeAnthropicSessionToolState(state, event, content = event?.content) {
|
|
12902
|
+
safeAnthropicSessionLog(state.span, {
|
|
12903
|
+
...event?.is_error === true ? {
|
|
12904
|
+
error: content ?? "Anthropic session tool execution failed"
|
|
12905
|
+
} : {},
|
|
12906
|
+
...state.approval ? { metadata: { tool_approval: state.approval } } : {},
|
|
12907
|
+
...content !== void 0 ? { output: content } : {}
|
|
12908
|
+
});
|
|
12909
|
+
state.span.end();
|
|
12910
|
+
}
|
|
12911
|
+
function finalizeAnthropicSessionModel(state, event) {
|
|
12912
|
+
const turn = state.activeTurn;
|
|
12913
|
+
const model = turn?.activeModel;
|
|
12914
|
+
if (!turn || !model || model.startEventId !== event.model_request_start_id) {
|
|
12915
|
+
return;
|
|
12916
|
+
}
|
|
12917
|
+
finalizeAnthropicSessionModelState(state, turn, event);
|
|
12918
|
+
}
|
|
12919
|
+
function finalizeAnthropicSessionModelState(state, turn, event) {
|
|
12920
|
+
const model = turn.activeModel;
|
|
12921
|
+
if (!model) {
|
|
12922
|
+
return;
|
|
12923
|
+
}
|
|
12924
|
+
turn.activeModel = void 0;
|
|
12925
|
+
const metrics = event ? parseAnthropicSessionModelUsage(event.model_usage) : {};
|
|
12926
|
+
if (model.firstTokenTime !== void 0) {
|
|
12927
|
+
metrics.time_to_first_token = model.firstTokenTime - model.startTime;
|
|
12928
|
+
}
|
|
12929
|
+
const output = model.output.length > 0 ? { role: "assistant", content: model.output } : void 0;
|
|
12930
|
+
safeAnthropicSessionLog(model.span, {
|
|
12931
|
+
...event?.is_error ? { error: "Anthropic session model request failed" } : {},
|
|
12932
|
+
...Object.keys(metrics).length > 0 ? { metrics } : {},
|
|
12933
|
+
...output ? { output } : {}
|
|
12934
|
+
});
|
|
12935
|
+
model.span.end();
|
|
12936
|
+
if (output) {
|
|
12937
|
+
turn.lastOutput = output;
|
|
12938
|
+
state.history.push(output);
|
|
12939
|
+
}
|
|
12940
|
+
for (const key of [
|
|
12941
|
+
"prompt_tokens",
|
|
12942
|
+
"completion_tokens",
|
|
12943
|
+
"tokens",
|
|
12944
|
+
"prompt_cached_tokens",
|
|
12945
|
+
"prompt_cache_creation_tokens"
|
|
12946
|
+
]) {
|
|
12947
|
+
const value = metrics[key];
|
|
12948
|
+
if (typeof value === "number") {
|
|
12949
|
+
turn.metrics[key] = (turn.metrics[key] ?? 0) + value;
|
|
12950
|
+
}
|
|
12951
|
+
}
|
|
12952
|
+
}
|
|
12953
|
+
function parseAnthropicSessionModelUsage(usage) {
|
|
12954
|
+
const finalized = finalizeAnthropicTokens({
|
|
12955
|
+
completion_tokens: usage.output_tokens,
|
|
12956
|
+
prompt_cache_creation_tokens: usage.cache_creation_input_tokens,
|
|
12957
|
+
prompt_cached_tokens: usage.cache_read_input_tokens,
|
|
12958
|
+
prompt_tokens: usage.input_tokens
|
|
12959
|
+
});
|
|
12960
|
+
return Object.fromEntries(
|
|
12961
|
+
Object.entries(finalized).filter(
|
|
12962
|
+
(entry) => entry[1] !== void 0
|
|
12963
|
+
)
|
|
12964
|
+
);
|
|
12965
|
+
}
|
|
12966
|
+
function finalizeAnthropicSessionTurn(state, error) {
|
|
12967
|
+
const turn = state.activeTurn;
|
|
12968
|
+
if (!turn) {
|
|
12969
|
+
return;
|
|
12970
|
+
}
|
|
12971
|
+
state.activeTurn = void 0;
|
|
12972
|
+
finalizeAnthropicSessionModelState(state, turn);
|
|
12973
|
+
for (const tool of turn.activeTools.values()) {
|
|
12974
|
+
finalizeAnthropicSessionToolState(tool);
|
|
12975
|
+
}
|
|
12976
|
+
turn.activeTools.clear();
|
|
12977
|
+
safeAnthropicSessionLog(turn.span, {
|
|
12978
|
+
...error !== void 0 ? { error: error instanceof Error ? error : toLoggedError(error) } : {},
|
|
12979
|
+
...turn.input.length > 0 ? { input: turn.input } : {},
|
|
12980
|
+
...turn.lastOutput ? { output: turn.lastOutput } : {},
|
|
12981
|
+
...Object.keys(turn.metrics).length > 0 ? { metrics: turn.metrics } : {}
|
|
12982
|
+
});
|
|
12983
|
+
turn.span.end();
|
|
12984
|
+
}
|
|
12985
|
+
function safeAnthropicSessionLog(span, event) {
|
|
12986
|
+
try {
|
|
12987
|
+
span.log(event);
|
|
12988
|
+
} catch (error) {
|
|
12989
|
+
debugLogger.debug("Error logging Anthropic Sessions span:", error);
|
|
12990
|
+
}
|
|
12991
|
+
}
|
|
12387
12992
|
function parseMetricsFromUsage2(usage) {
|
|
12388
12993
|
if (!usage) {
|
|
12389
12994
|
return {};
|
|
@@ -14257,6 +14862,29 @@ var harnessAgentChannels = defineChannels(
|
|
|
14257
14862
|
{ instrumentationName: INSTRUMENTATION_NAMES.AI_SDK }
|
|
14258
14863
|
);
|
|
14259
14864
|
|
|
14865
|
+
// src/instrumentation/plugins/cloudflare-think-context.ts
|
|
14866
|
+
var cloudflareThinkSpans = /* @__PURE__ */ new Map();
|
|
14867
|
+
function registerCloudflareThinkSpan(span) {
|
|
14868
|
+
if (span.spanId) {
|
|
14869
|
+
cloudflareThinkSpans.set(span.spanId, span);
|
|
14870
|
+
}
|
|
14871
|
+
}
|
|
14872
|
+
function unregisterCloudflareThinkSpan(span) {
|
|
14873
|
+
if (span.spanId) {
|
|
14874
|
+
cloudflareThinkSpans.delete(span.spanId);
|
|
14875
|
+
}
|
|
14876
|
+
}
|
|
14877
|
+
function currentCloudflareThinkSpan() {
|
|
14878
|
+
const parentSpanIds = _internalGetGlobalState()?.contextManager.getParentSpanIds()?.spanParents ?? [];
|
|
14879
|
+
for (const parentSpanId of parentSpanIds) {
|
|
14880
|
+
const span = cloudflareThinkSpans.get(parentSpanId);
|
|
14881
|
+
if (span) {
|
|
14882
|
+
return span;
|
|
14883
|
+
}
|
|
14884
|
+
}
|
|
14885
|
+
return void 0;
|
|
14886
|
+
}
|
|
14887
|
+
|
|
14260
14888
|
// src/instrumentation/plugins/ai-sdk-plugin.ts
|
|
14261
14889
|
var DEFAULT_DENY_OUTPUT_PATHS = [
|
|
14262
14890
|
// v3
|
|
@@ -14363,6 +14991,7 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
14363
14991
|
traceStreamingChannel(aiSDKChannels.streamText, {
|
|
14364
14992
|
name: "streamText",
|
|
14365
14993
|
type: "function" /* FUNCTION */,
|
|
14994
|
+
shouldTrace: () => currentCloudflareThinkSpan() === void 0,
|
|
14366
14995
|
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
14367
14996
|
extractOutput: (result, endEvent) => processAISDKOutput(
|
|
14368
14997
|
result,
|
|
@@ -14383,6 +15012,7 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
14383
15012
|
traceSyncStreamChannel(aiSDKChannels.streamTextSync, {
|
|
14384
15013
|
name: "streamText",
|
|
14385
15014
|
type: "function" /* FUNCTION */,
|
|
15015
|
+
shouldTrace: () => currentCloudflareThinkSpan() === void 0,
|
|
14386
15016
|
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
14387
15017
|
patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
|
|
14388
15018
|
defaultDenyOutputPaths: denyOutputPaths,
|
|
@@ -15368,6 +15998,23 @@ function prepareAISDKWorkflowAgentStreamInput(params, event, span, defaultDenyOu
|
|
|
15368
15998
|
metadata
|
|
15369
15999
|
};
|
|
15370
16000
|
}
|
|
16001
|
+
function prepareAISDKAgentCallInput(params, event, span, defaultDenyOutputPaths = DEFAULT_DENY_OUTPUT_PATHS) {
|
|
16002
|
+
const { input } = processAISDKWorkflowAgentCallInput(params);
|
|
16003
|
+
const metadata = extractMetadataFromCallParams(params, event.self);
|
|
16004
|
+
const childTracing = prepareAISDKChildTracing(
|
|
16005
|
+
params,
|
|
16006
|
+
event.self,
|
|
16007
|
+
span,
|
|
16008
|
+
defaultDenyOutputPaths,
|
|
16009
|
+
event.aiSDK,
|
|
16010
|
+
{ agentOwner: true }
|
|
16011
|
+
);
|
|
16012
|
+
event.modelWrapped = childTracing.modelWrapped;
|
|
16013
|
+
if (childTracing.cleanup) {
|
|
16014
|
+
event.__braintrust_ai_sdk_cleanup = childTracing.cleanup;
|
|
16015
|
+
}
|
|
16016
|
+
return { input, metadata };
|
|
16017
|
+
}
|
|
15371
16018
|
function prepareAISDKEmbedInput(params, self) {
|
|
15372
16019
|
return {
|
|
15373
16020
|
input: { ...params },
|
|
@@ -15391,6 +16038,18 @@ function extractTopLevelAISDKMetrics(result, event, startTime) {
|
|
|
15391
16038
|
}
|
|
15392
16039
|
return metrics;
|
|
15393
16040
|
}
|
|
16041
|
+
async function extractResolvedAISDKTokenMetrics(result) {
|
|
16042
|
+
for (const field of ["totalUsage", "usage"]) {
|
|
16043
|
+
try {
|
|
16044
|
+
const usage = await Promise.resolve(result[field]);
|
|
16045
|
+
if (usage !== void 0) {
|
|
16046
|
+
return extractTokenMetrics({ [field]: usage });
|
|
16047
|
+
}
|
|
16048
|
+
} catch {
|
|
16049
|
+
}
|
|
16050
|
+
}
|
|
16051
|
+
return extractTokenMetrics(result);
|
|
16052
|
+
}
|
|
15394
16053
|
function hasModelChildTracing(event) {
|
|
15395
16054
|
return event?.modelWrapped === true || event?.__braintrust_ai_sdk_model_wrapped === true;
|
|
15396
16055
|
}
|
|
@@ -16208,13 +16867,15 @@ function patchAISDKStreamingResult(args) {
|
|
|
16208
16867
|
const {
|
|
16209
16868
|
defaultDenyOutputPaths,
|
|
16210
16869
|
endEvent,
|
|
16870
|
+
forceTopLevelMetrics,
|
|
16211
16871
|
onComplete,
|
|
16212
16872
|
onCancel,
|
|
16213
16873
|
onError,
|
|
16214
16874
|
result,
|
|
16215
16875
|
resolvePromiseUsage,
|
|
16216
16876
|
span,
|
|
16217
|
-
startTime
|
|
16877
|
+
startTime,
|
|
16878
|
+
transformOutput
|
|
16218
16879
|
} = args;
|
|
16219
16880
|
if (!result || typeof result !== "object") {
|
|
16220
16881
|
return false;
|
|
@@ -16267,8 +16928,8 @@ function patchAISDKStreamingResult(args) {
|
|
|
16267
16928
|
}
|
|
16268
16929
|
outputLogged = true;
|
|
16269
16930
|
try {
|
|
16270
|
-
const metrics = extractTopLevelAISDKMetrics(result, endEvent);
|
|
16271
|
-
if (resolvePromiseUsage) {
|
|
16931
|
+
const metrics = forceTopLevelMetrics ? await extractResolvedAISDKTokenMetrics(result) : extractTopLevelAISDKMetrics(result, endEvent);
|
|
16932
|
+
if (resolvePromiseUsage && !forceTopLevelMetrics) {
|
|
16272
16933
|
try {
|
|
16273
16934
|
const resultRecord2 = result;
|
|
16274
16935
|
const pendingUsage = resultRecord2.totalUsage ?? resultRecord2.usage;
|
|
@@ -16287,10 +16948,11 @@ function patchAISDKStreamingResult(args) {
|
|
|
16287
16948
|
if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
|
|
16288
16949
|
metrics.time_to_first_token = firstChunkTime - startTime;
|
|
16289
16950
|
}
|
|
16290
|
-
const
|
|
16951
|
+
const processedOutput = await processAISDKStreamingOutput(
|
|
16291
16952
|
result,
|
|
16292
16953
|
resolveDenyOutputPaths(endEvent, defaultDenyOutputPaths)
|
|
16293
16954
|
);
|
|
16955
|
+
const output = transformOutput ? transformOutput(processedOutput) : processedOutput;
|
|
16294
16956
|
const metadata = buildResolvedMetadataPayload(result).metadata;
|
|
16295
16957
|
try {
|
|
16296
16958
|
span.log({
|
|
@@ -18712,6 +19374,295 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
18712
19374
|
}
|
|
18713
19375
|
};
|
|
18714
19376
|
|
|
19377
|
+
// src/instrumentation/plugins/cloudflare-think-channels.ts
|
|
19378
|
+
var cloudflareThinkChannels = defineChannels(
|
|
19379
|
+
"@cloudflare/think",
|
|
19380
|
+
{
|
|
19381
|
+
runInferenceLoop: channel({
|
|
19382
|
+
channelName: "Think.runInferenceLoop",
|
|
19383
|
+
kind: "async"
|
|
19384
|
+
})
|
|
19385
|
+
},
|
|
19386
|
+
{ instrumentationName: INSTRUMENTATION_NAMES.CLOUDFLARE_THINK }
|
|
19387
|
+
);
|
|
19388
|
+
|
|
19389
|
+
// src/instrumentation/plugins/cloudflare-think-plugin.ts
|
|
19390
|
+
var THINK_STATE_ID = /* @__PURE__ */ Symbol.for("braintrust.cloudflare-think.state-id");
|
|
19391
|
+
var CloudflareThinkPlugin = class extends BasePlugin {
|
|
19392
|
+
statesBySpanId = /* @__PURE__ */ new Map();
|
|
19393
|
+
onEnable() {
|
|
19394
|
+
this.subscribeToThinkRuns();
|
|
19395
|
+
this.subscribeToAISDKStreamTextSync();
|
|
19396
|
+
this.subscribeToAISDKStreamTextAsync();
|
|
19397
|
+
}
|
|
19398
|
+
onDisable() {
|
|
19399
|
+
for (const unsubscribe of this.unsubscribers) {
|
|
19400
|
+
unsubscribe();
|
|
19401
|
+
}
|
|
19402
|
+
this.unsubscribers = [];
|
|
19403
|
+
for (const state of this.statesBySpanId.values()) {
|
|
19404
|
+
this.finishState(state);
|
|
19405
|
+
}
|
|
19406
|
+
this.statesBySpanId.clear();
|
|
19407
|
+
}
|
|
19408
|
+
subscribeToThinkRuns() {
|
|
19409
|
+
const channel2 = cloudflareThinkChannels.runInferenceLoop.tracingChannel();
|
|
19410
|
+
const states = /* @__PURE__ */ new WeakMap();
|
|
19411
|
+
const state = _internalGetGlobalState();
|
|
19412
|
+
const contextManager = state?.contextManager;
|
|
19413
|
+
const currentSpanStore = contextManager ? contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
|
|
19414
|
+
const ensureState2 = (event) => {
|
|
19415
|
+
if (isAutoInstrumentationSuppressed()) {
|
|
19416
|
+
return void 0;
|
|
19417
|
+
}
|
|
19418
|
+
const existing = states.get(event);
|
|
19419
|
+
if (existing) {
|
|
19420
|
+
return existing;
|
|
19421
|
+
}
|
|
19422
|
+
const span = startSpan(
|
|
19423
|
+
withSpanInstrumentationName(
|
|
19424
|
+
{
|
|
19425
|
+
name: "Think.runTurn",
|
|
19426
|
+
spanAttributes: { type: "task" /* TASK */ }
|
|
19427
|
+
},
|
|
19428
|
+
INSTRUMENTATION_NAMES.CLOUDFLARE_THINK
|
|
19429
|
+
)
|
|
19430
|
+
);
|
|
19431
|
+
const runState = {
|
|
19432
|
+
aiResultPatched: false,
|
|
19433
|
+
fallbackInput: extractFallbackInput(event.self?.messages),
|
|
19434
|
+
finalized: false,
|
|
19435
|
+
inputLogged: false,
|
|
19436
|
+
span,
|
|
19437
|
+
startTime: getCurrentUnixTimestamp()
|
|
19438
|
+
};
|
|
19439
|
+
const metadata = {
|
|
19440
|
+
braintrust: {
|
|
19441
|
+
integration_name: "cloudflare-think",
|
|
19442
|
+
sdk_language: "typescript"
|
|
19443
|
+
}
|
|
19444
|
+
};
|
|
19445
|
+
if (typeof event.moduleVersion === "string") {
|
|
19446
|
+
metadata["cloudflare_think.version"] = event.moduleVersion;
|
|
19447
|
+
}
|
|
19448
|
+
span.log({ metadata });
|
|
19449
|
+
states.set(event, runState);
|
|
19450
|
+
if (span.spanId) {
|
|
19451
|
+
this.statesBySpanId.set(span.spanId, runState);
|
|
19452
|
+
}
|
|
19453
|
+
registerCloudflareThinkSpan(span);
|
|
19454
|
+
return runState;
|
|
19455
|
+
};
|
|
19456
|
+
if (contextManager && currentSpanStore && channel2.start) {
|
|
19457
|
+
channel2.start.bindStore(currentSpanStore, (event) => {
|
|
19458
|
+
const runState = ensureState2(event);
|
|
19459
|
+
return runState ? contextManager.wrapSpanForStore(runState.span) : currentSpanStore.getStore();
|
|
19460
|
+
});
|
|
19461
|
+
this.unsubscribers.push(
|
|
19462
|
+
() => channel2.start?.unbindStore(currentSpanStore)
|
|
19463
|
+
);
|
|
19464
|
+
}
|
|
19465
|
+
const handlers = {
|
|
19466
|
+
start: (event) => {
|
|
19467
|
+
ensureState2(event);
|
|
19468
|
+
},
|
|
19469
|
+
asyncEnd: (event) => {
|
|
19470
|
+
const runState = states.get(event);
|
|
19471
|
+
states.delete(event);
|
|
19472
|
+
if (!runState || runState.finalized || runState.aiResultPatched) {
|
|
19473
|
+
return;
|
|
19474
|
+
}
|
|
19475
|
+
this.finishState(runState, void 0, event.result);
|
|
19476
|
+
},
|
|
19477
|
+
error: (event) => {
|
|
19478
|
+
const runState = states.get(event);
|
|
19479
|
+
states.delete(event);
|
|
19480
|
+
if (runState) {
|
|
19481
|
+
this.finishState(runState, event.error);
|
|
19482
|
+
}
|
|
19483
|
+
}
|
|
19484
|
+
};
|
|
19485
|
+
channel2.subscribe(handlers);
|
|
19486
|
+
this.unsubscribers.push(() => channel2.unsubscribe(handlers));
|
|
19487
|
+
}
|
|
19488
|
+
subscribeToAISDKStreamTextSync() {
|
|
19489
|
+
const channel2 = aiSDKChannels.streamTextSync.tracingChannel();
|
|
19490
|
+
const handlers = {
|
|
19491
|
+
start: (event) => {
|
|
19492
|
+
this.startAISDKStream(event);
|
|
19493
|
+
},
|
|
19494
|
+
end: (event) => {
|
|
19495
|
+
this.endAISDKStream(event);
|
|
19496
|
+
},
|
|
19497
|
+
error: (event) => {
|
|
19498
|
+
this.errorAISDKStream(event);
|
|
19499
|
+
}
|
|
19500
|
+
};
|
|
19501
|
+
channel2.subscribe(handlers);
|
|
19502
|
+
this.unsubscribers.push(() => channel2.unsubscribe(handlers));
|
|
19503
|
+
}
|
|
19504
|
+
subscribeToAISDKStreamTextAsync() {
|
|
19505
|
+
const channel2 = aiSDKChannels.streamText.tracingChannel();
|
|
19506
|
+
const handlers = {
|
|
19507
|
+
start: (event) => {
|
|
19508
|
+
this.startAISDKStream(event);
|
|
19509
|
+
},
|
|
19510
|
+
asyncEnd: (event) => {
|
|
19511
|
+
this.endAISDKStream(event);
|
|
19512
|
+
},
|
|
19513
|
+
error: (event) => {
|
|
19514
|
+
this.errorAISDKStream(event);
|
|
19515
|
+
}
|
|
19516
|
+
};
|
|
19517
|
+
channel2.subscribe(handlers);
|
|
19518
|
+
this.unsubscribers.push(() => channel2.unsubscribe(handlers));
|
|
19519
|
+
}
|
|
19520
|
+
startAISDKStream(event) {
|
|
19521
|
+
const runState = this.currentState();
|
|
19522
|
+
if (!runState || runState.finalized) {
|
|
19523
|
+
return;
|
|
19524
|
+
}
|
|
19525
|
+
try {
|
|
19526
|
+
const prepared = prepareAISDKAgentCallInput(
|
|
19527
|
+
event.arguments[0],
|
|
19528
|
+
event,
|
|
19529
|
+
runState.span
|
|
19530
|
+
);
|
|
19531
|
+
runState.span.log({
|
|
19532
|
+
input: extractThinkTaskInput(prepared.input),
|
|
19533
|
+
metadata: {
|
|
19534
|
+
...prepared.metadata,
|
|
19535
|
+
braintrust: {
|
|
19536
|
+
integration_name: "cloudflare-think",
|
|
19537
|
+
sdk_language: "typescript"
|
|
19538
|
+
}
|
|
19539
|
+
}
|
|
19540
|
+
});
|
|
19541
|
+
runState.inputLogged = true;
|
|
19542
|
+
runState.aiEvent = event;
|
|
19543
|
+
Reflect.set(event, THINK_STATE_ID, runState.span.spanId);
|
|
19544
|
+
} catch (error) {
|
|
19545
|
+
debugLogger.error(
|
|
19546
|
+
"Error preparing @cloudflare/think AI SDK tracing:",
|
|
19547
|
+
error
|
|
19548
|
+
);
|
|
19549
|
+
}
|
|
19550
|
+
}
|
|
19551
|
+
endAISDKStream(event) {
|
|
19552
|
+
const runState = this.stateForAISDKEvent(event);
|
|
19553
|
+
if (!runState || runState.finalized) {
|
|
19554
|
+
return;
|
|
19555
|
+
}
|
|
19556
|
+
const patched = patchAISDKStreamingResult({
|
|
19557
|
+
defaultDenyOutputPaths: DEFAULT_DENY_OUTPUT_PATHS,
|
|
19558
|
+
endEvent: event,
|
|
19559
|
+
forceTopLevelMetrics: true,
|
|
19560
|
+
onComplete: () => this.releaseState(runState),
|
|
19561
|
+
result: event.result,
|
|
19562
|
+
span: runState.span,
|
|
19563
|
+
startTime: runState.startTime,
|
|
19564
|
+
transformOutput: extractThinkTaskOutput
|
|
19565
|
+
});
|
|
19566
|
+
runState.aiResultPatched = patched;
|
|
19567
|
+
if (!patched) {
|
|
19568
|
+
this.finishState(runState, void 0, event.result);
|
|
19569
|
+
}
|
|
19570
|
+
}
|
|
19571
|
+
errorAISDKStream(event) {
|
|
19572
|
+
const runState = this.stateForAISDKEvent(event);
|
|
19573
|
+
if (runState) {
|
|
19574
|
+
this.finishState(runState, event.error);
|
|
19575
|
+
}
|
|
19576
|
+
}
|
|
19577
|
+
currentState() {
|
|
19578
|
+
const parentIds = _internalGetGlobalState()?.contextManager.getParentSpanIds()?.spanParents ?? [];
|
|
19579
|
+
for (const parentId of parentIds) {
|
|
19580
|
+
const state = this.statesBySpanId.get(parentId);
|
|
19581
|
+
if (state) {
|
|
19582
|
+
return state;
|
|
19583
|
+
}
|
|
19584
|
+
}
|
|
19585
|
+
return void 0;
|
|
19586
|
+
}
|
|
19587
|
+
stateForAISDKEvent(event) {
|
|
19588
|
+
const spanId = Reflect.get(event, THINK_STATE_ID);
|
|
19589
|
+
return typeof spanId === "string" ? this.statesBySpanId.get(spanId) : void 0;
|
|
19590
|
+
}
|
|
19591
|
+
finishState(state, error, output) {
|
|
19592
|
+
if (state.finalized) {
|
|
19593
|
+
return;
|
|
19594
|
+
}
|
|
19595
|
+
state.finalized = true;
|
|
19596
|
+
try {
|
|
19597
|
+
if (!state.inputLogged && state.fallbackInput !== void 0) {
|
|
19598
|
+
state.span.log({ input: state.fallbackInput });
|
|
19599
|
+
}
|
|
19600
|
+
if (error !== void 0) {
|
|
19601
|
+
state.span.log({ error });
|
|
19602
|
+
} else if (output !== void 0) {
|
|
19603
|
+
state.span.log({ output: extractThinkTaskOutput(output) });
|
|
19604
|
+
}
|
|
19605
|
+
finalizeAISDKChildTracing(state.aiEvent);
|
|
19606
|
+
state.span.end();
|
|
19607
|
+
} finally {
|
|
19608
|
+
this.releaseState(state);
|
|
19609
|
+
}
|
|
19610
|
+
}
|
|
19611
|
+
releaseState(state) {
|
|
19612
|
+
state.finalized = true;
|
|
19613
|
+
unregisterCloudflareThinkSpan(state.span);
|
|
19614
|
+
if (state.span.spanId) {
|
|
19615
|
+
this.statesBySpanId.delete(state.span.spanId);
|
|
19616
|
+
}
|
|
19617
|
+
}
|
|
19618
|
+
};
|
|
19619
|
+
function extractFallbackInput(messages) {
|
|
19620
|
+
if (!Array.isArray(messages) || messages.length === 0) {
|
|
19621
|
+
return void 0;
|
|
19622
|
+
}
|
|
19623
|
+
let latestUserIndex = -1;
|
|
19624
|
+
for (let index = messages.length - 1; index >= 0; index--) {
|
|
19625
|
+
if (messages[index]?.role === "user") {
|
|
19626
|
+
latestUserIndex = index;
|
|
19627
|
+
break;
|
|
19628
|
+
}
|
|
19629
|
+
}
|
|
19630
|
+
const selected = latestUserIndex >= 0 ? messages.slice(latestUserIndex) : [];
|
|
19631
|
+
return selected.map((message) => ({
|
|
19632
|
+
role: message.role,
|
|
19633
|
+
content: message.content ?? message.parts
|
|
19634
|
+
}));
|
|
19635
|
+
}
|
|
19636
|
+
function extractThinkTaskOutput(output) {
|
|
19637
|
+
if (!isObject(output)) {
|
|
19638
|
+
return output;
|
|
19639
|
+
}
|
|
19640
|
+
if (typeof output.text === "string") {
|
|
19641
|
+
return { role: "assistant", content: output.text };
|
|
19642
|
+
}
|
|
19643
|
+
if (output.object !== void 0) {
|
|
19644
|
+
return output.object;
|
|
19645
|
+
}
|
|
19646
|
+
return output;
|
|
19647
|
+
}
|
|
19648
|
+
function extractThinkTaskInput(input) {
|
|
19649
|
+
if (!isObject(input)) {
|
|
19650
|
+
return input;
|
|
19651
|
+
}
|
|
19652
|
+
const system = input.instructions ?? input.system;
|
|
19653
|
+
if (Array.isArray(input.messages)) {
|
|
19654
|
+
return system === void 0 ? input.messages : [{ role: "system", content: system }, ...input.messages];
|
|
19655
|
+
}
|
|
19656
|
+
if (Array.isArray(input.prompt)) {
|
|
19657
|
+
return system === void 0 ? input.prompt : [{ role: "system", content: system }, ...input.prompt];
|
|
19658
|
+
}
|
|
19659
|
+
if (typeof input.prompt === "string") {
|
|
19660
|
+
const messages = [{ role: "user", content: input.prompt }];
|
|
19661
|
+
return system === void 0 ? messages : [{ role: "system", content: system }, ...messages];
|
|
19662
|
+
}
|
|
19663
|
+
return input;
|
|
19664
|
+
}
|
|
19665
|
+
|
|
18715
19666
|
// src/instrumentation/plugins/cursor-sdk-channels.ts
|
|
18716
19667
|
var cursorSDKChannels = defineChannels(
|
|
18717
19668
|
"@cursor/sdk",
|
|
@@ -24477,6 +25428,470 @@ function aggregateMistralStreamChunks(chunks) {
|
|
|
24477
25428
|
};
|
|
24478
25429
|
}
|
|
24479
25430
|
|
|
25431
|
+
// src/instrumentation/plugins/ollama-channels.ts
|
|
25432
|
+
var ollamaChannels = defineChannels(
|
|
25433
|
+
"ollama",
|
|
25434
|
+
{
|
|
25435
|
+
chat: channel({
|
|
25436
|
+
channelName: "chat",
|
|
25437
|
+
kind: "async"
|
|
25438
|
+
}),
|
|
25439
|
+
generate: channel({
|
|
25440
|
+
channelName: "generate",
|
|
25441
|
+
kind: "async"
|
|
25442
|
+
}),
|
|
25443
|
+
embed: channel({
|
|
25444
|
+
channelName: "embed",
|
|
25445
|
+
kind: "async"
|
|
25446
|
+
})
|
|
25447
|
+
},
|
|
25448
|
+
{ instrumentationName: INSTRUMENTATION_NAMES.OLLAMA }
|
|
25449
|
+
);
|
|
25450
|
+
|
|
25451
|
+
// src/instrumentation/plugins/ollama-plugin.ts
|
|
25452
|
+
var OllamaPlugin = class extends BasePlugin {
|
|
25453
|
+
onEnable() {
|
|
25454
|
+
this.unsubscribers.push(
|
|
25455
|
+
traceStreamingChannel(ollamaChannels.chat, {
|
|
25456
|
+
name: "ollama.chat",
|
|
25457
|
+
type: "llm" /* LLM */,
|
|
25458
|
+
extractInput: extractOllamaChatInput,
|
|
25459
|
+
extractOutput: (result, event) => extractOllamaChatOutput(
|
|
25460
|
+
result,
|
|
25461
|
+
countOllamaToolCalls(event?.arguments?.[0]?.messages)
|
|
25462
|
+
),
|
|
25463
|
+
extractMetadata: extractOllamaResponseMetadata,
|
|
25464
|
+
extractMetrics: extractOllamaMetrics,
|
|
25465
|
+
aggregateChunks: aggregateOllamaChatChunks
|
|
25466
|
+
}),
|
|
25467
|
+
traceStreamingChannel(ollamaChannels.generate, {
|
|
25468
|
+
name: "ollama.generate",
|
|
25469
|
+
type: "llm" /* LLM */,
|
|
25470
|
+
extractInput: extractOllamaGenerateInput,
|
|
25471
|
+
extractOutput: extractOllamaGenerateOutput,
|
|
25472
|
+
extractMetadata: extractOllamaResponseMetadata,
|
|
25473
|
+
extractMetrics: extractOllamaMetrics,
|
|
25474
|
+
aggregateChunks: aggregateOllamaGenerateChunks
|
|
25475
|
+
}),
|
|
25476
|
+
traceAsyncChannel(ollamaChannels.embed, {
|
|
25477
|
+
name: "ollama.embed",
|
|
25478
|
+
type: "llm" /* LLM */,
|
|
25479
|
+
extractInput: extractOllamaEmbedInput,
|
|
25480
|
+
extractOutput: extractOllamaEmbedOutput,
|
|
25481
|
+
extractMetadata: extractOllamaResponseMetadata,
|
|
25482
|
+
extractMetrics: extractOllamaMetrics
|
|
25483
|
+
})
|
|
25484
|
+
);
|
|
25485
|
+
}
|
|
25486
|
+
onDisable() {
|
|
25487
|
+
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
25488
|
+
}
|
|
25489
|
+
};
|
|
25490
|
+
function isNonNegativeNumber(value) {
|
|
25491
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0;
|
|
25492
|
+
}
|
|
25493
|
+
function normalizeFinishReason(response, hasToolCalls = false) {
|
|
25494
|
+
if (hasToolCalls) {
|
|
25495
|
+
return "tool_calls";
|
|
25496
|
+
}
|
|
25497
|
+
return response?.done_reason || "stop";
|
|
25498
|
+
}
|
|
25499
|
+
function stringifyArguments(value) {
|
|
25500
|
+
if (typeof value === "string") {
|
|
25501
|
+
return value;
|
|
25502
|
+
}
|
|
25503
|
+
try {
|
|
25504
|
+
return JSON.stringify(value ?? {});
|
|
25505
|
+
} catch {
|
|
25506
|
+
return String(value);
|
|
25507
|
+
}
|
|
25508
|
+
}
|
|
25509
|
+
function syntheticToolCallId(name, index) {
|
|
25510
|
+
const normalizedName = name.replace(/[^a-zA-Z0-9_-]/g, "_") || "tool";
|
|
25511
|
+
return `ollama_call_${normalizedName}_${index}`;
|
|
25512
|
+
}
|
|
25513
|
+
function normalizeToolCall(toolCall, index) {
|
|
25514
|
+
const name = toolCall.function?.name;
|
|
25515
|
+
if (typeof name !== "string" || name.length === 0) {
|
|
25516
|
+
return void 0;
|
|
25517
|
+
}
|
|
25518
|
+
return {
|
|
25519
|
+
id: typeof toolCall.id === "string" && toolCall.id.length > 0 ? toolCall.id : syntheticToolCallId(name, index),
|
|
25520
|
+
type: "function",
|
|
25521
|
+
function: {
|
|
25522
|
+
name,
|
|
25523
|
+
arguments: stringifyArguments(toolCall.function?.arguments)
|
|
25524
|
+
}
|
|
25525
|
+
};
|
|
25526
|
+
}
|
|
25527
|
+
function normalizeToolCalls(toolCalls, syntheticIdOffset = 0) {
|
|
25528
|
+
if (!Array.isArray(toolCalls)) {
|
|
25529
|
+
return [];
|
|
25530
|
+
}
|
|
25531
|
+
return toolCalls.flatMap((toolCall, index) => {
|
|
25532
|
+
const normalized = normalizeToolCall(toolCall, syntheticIdOffset + index);
|
|
25533
|
+
return normalized ? [normalized] : [];
|
|
25534
|
+
});
|
|
25535
|
+
}
|
|
25536
|
+
function countOllamaToolCalls(messages) {
|
|
25537
|
+
if (!Array.isArray(messages)) {
|
|
25538
|
+
return 0;
|
|
25539
|
+
}
|
|
25540
|
+
return messages.reduce(
|
|
25541
|
+
(count, message) => count + (isObject(message) && Array.isArray(message.tool_calls) ? message.tool_calls.length : 0),
|
|
25542
|
+
0
|
|
25543
|
+
);
|
|
25544
|
+
}
|
|
25545
|
+
function imageBytes(value) {
|
|
25546
|
+
if (value instanceof Uint8Array) {
|
|
25547
|
+
return value;
|
|
25548
|
+
}
|
|
25549
|
+
if (value instanceof ArrayBuffer) {
|
|
25550
|
+
return new Uint8Array(value);
|
|
25551
|
+
}
|
|
25552
|
+
if (typeof value !== "string" || value.startsWith("data:")) {
|
|
25553
|
+
return void 0;
|
|
25554
|
+
}
|
|
25555
|
+
try {
|
|
25556
|
+
const decoded = atob(value.slice(0, 24));
|
|
25557
|
+
return Uint8Array.from(decoded, (character) => character.charCodeAt(0));
|
|
25558
|
+
} catch {
|
|
25559
|
+
return void 0;
|
|
25560
|
+
}
|
|
25561
|
+
}
|
|
25562
|
+
function inferImageMediaType(value) {
|
|
25563
|
+
if (typeof value === "string") {
|
|
25564
|
+
const dataUrlType = value.match(/^data:(image\/[^;]+);base64,/i)?.[1];
|
|
25565
|
+
if (dataUrlType) {
|
|
25566
|
+
return dataUrlType;
|
|
25567
|
+
}
|
|
25568
|
+
}
|
|
25569
|
+
const bytes = imageBytes(value);
|
|
25570
|
+
if (!bytes) {
|
|
25571
|
+
return void 0;
|
|
25572
|
+
}
|
|
25573
|
+
if (bytes[0] === 137 && bytes[1] === 80 && bytes[2] === 78 && bytes[3] === 71) {
|
|
25574
|
+
return "image/png";
|
|
25575
|
+
}
|
|
25576
|
+
if (bytes[0] === 255 && bytes[1] === 216 && bytes[2] === 255) {
|
|
25577
|
+
return "image/jpeg";
|
|
25578
|
+
}
|
|
25579
|
+
const signature = String.fromCharCode(...bytes.slice(0, 12));
|
|
25580
|
+
if (signature.startsWith("GIF87a") || signature.startsWith("GIF89a")) {
|
|
25581
|
+
return "image/gif";
|
|
25582
|
+
}
|
|
25583
|
+
if (signature.startsWith("RIFF") && signature.slice(8, 12) === "WEBP") {
|
|
25584
|
+
return "image/webp";
|
|
25585
|
+
}
|
|
25586
|
+
return void 0;
|
|
25587
|
+
}
|
|
25588
|
+
function normalizeTextAndImages(content, images) {
|
|
25589
|
+
if (!images || images.length === 0) {
|
|
25590
|
+
return { content };
|
|
25591
|
+
}
|
|
25592
|
+
const imageParts = [];
|
|
25593
|
+
const unrecognizedImages = [];
|
|
25594
|
+
for (const image of images) {
|
|
25595
|
+
let localImagePath;
|
|
25596
|
+
let localPathMediaType;
|
|
25597
|
+
if (typeof image === "string" && !/^data:/i.test(image) && !/^https?:\/\//i.test(image)) {
|
|
25598
|
+
const extension = image.match(/\.([a-z0-9]+)$/i)?.[1]?.toLowerCase();
|
|
25599
|
+
const extensionMediaType = {
|
|
25600
|
+
png: "image/png",
|
|
25601
|
+
jpg: "image/jpeg",
|
|
25602
|
+
jpeg: "image/jpeg",
|
|
25603
|
+
gif: "image/gif",
|
|
25604
|
+
webp: "image/webp"
|
|
25605
|
+
}[extension ?? ""];
|
|
25606
|
+
if (extensionMediaType && isomorph_default.statSync) {
|
|
25607
|
+
try {
|
|
25608
|
+
if (isomorph_default.statSync(image).isFile()) {
|
|
25609
|
+
localImagePath = image;
|
|
25610
|
+
localPathMediaType = extensionMediaType;
|
|
25611
|
+
}
|
|
25612
|
+
} catch {
|
|
25613
|
+
}
|
|
25614
|
+
}
|
|
25615
|
+
}
|
|
25616
|
+
const mediaType = localPathMediaType ?? inferImageMediaType(image);
|
|
25617
|
+
if (!mediaType) {
|
|
25618
|
+
unrecognizedImages.push(image);
|
|
25619
|
+
continue;
|
|
25620
|
+
}
|
|
25621
|
+
const processedImage = localImagePath ? new Attachment({
|
|
25622
|
+
data: localImagePath,
|
|
25623
|
+
filename: localImagePath.split(/[\\/]/).at(-1) ?? "image",
|
|
25624
|
+
contentType: mediaType
|
|
25625
|
+
}) : processInputAttachments({
|
|
25626
|
+
type: "image",
|
|
25627
|
+
image,
|
|
25628
|
+
mediaType
|
|
25629
|
+
}).image;
|
|
25630
|
+
imageParts.push({
|
|
25631
|
+
type: "image_url",
|
|
25632
|
+
image_url: { url: processedImage }
|
|
25633
|
+
});
|
|
25634
|
+
}
|
|
25635
|
+
return {
|
|
25636
|
+
content: imageParts.length > 0 ? [...content ? [{ type: "text", text: content }] : [], ...imageParts] : content,
|
|
25637
|
+
...unrecognizedImages.length > 0 ? { unrecognizedImages } : {}
|
|
25638
|
+
};
|
|
25639
|
+
}
|
|
25640
|
+
function normalizeMessage(message, toolCallId, syntheticToolCallIdOffset = 0) {
|
|
25641
|
+
if (typeof message.role !== "string") {
|
|
25642
|
+
return void 0;
|
|
25643
|
+
}
|
|
25644
|
+
const toolCalls = normalizeToolCalls(
|
|
25645
|
+
message.tool_calls,
|
|
25646
|
+
syntheticToolCallIdOffset
|
|
25647
|
+
);
|
|
25648
|
+
if (message.role === "tool") {
|
|
25649
|
+
const toolName = typeof message.tool_name === "string" && message.tool_name.length > 0 ? message.tool_name : "tool";
|
|
25650
|
+
return {
|
|
25651
|
+
role: "tool",
|
|
25652
|
+
tool_call_id: toolCallId ?? syntheticToolCallId(toolName, 0),
|
|
25653
|
+
content: typeof message.content === "string" ? message.content : ""
|
|
25654
|
+
};
|
|
25655
|
+
}
|
|
25656
|
+
const normalizedContent = normalizeTextAndImages(
|
|
25657
|
+
typeof message.content === "string" ? message.content || (toolCalls.length > 0 ? null : "") : toolCalls.length > 0 ? null : "",
|
|
25658
|
+
message.images
|
|
25659
|
+
);
|
|
25660
|
+
return {
|
|
25661
|
+
role: message.role,
|
|
25662
|
+
content: normalizedContent.content,
|
|
25663
|
+
...typeof message.thinking === "string" && message.thinking.length > 0 ? { reasoning: message.thinking } : {},
|
|
25664
|
+
...toolCalls.length > 0 ? { tool_calls: toolCalls } : {},
|
|
25665
|
+
...normalizedContent.unrecognizedImages ? { images: normalizedContent.unrecognizedImages } : {}
|
|
25666
|
+
};
|
|
25667
|
+
}
|
|
25668
|
+
function normalizeMessages(messages) {
|
|
25669
|
+
if (!Array.isArray(messages)) {
|
|
25670
|
+
return [];
|
|
25671
|
+
}
|
|
25672
|
+
const pendingToolCallIds = /* @__PURE__ */ new Map();
|
|
25673
|
+
let syntheticToolCallIdOffset = 0;
|
|
25674
|
+
return messages.flatMap((message) => {
|
|
25675
|
+
if (!isObject(message)) {
|
|
25676
|
+
return [];
|
|
25677
|
+
}
|
|
25678
|
+
const ollamaMessage = message;
|
|
25679
|
+
let toolCallId;
|
|
25680
|
+
if (ollamaMessage.role === "tool") {
|
|
25681
|
+
const toolName = ollamaMessage.tool_name;
|
|
25682
|
+
if (typeof toolName === "string") {
|
|
25683
|
+
toolCallId = pendingToolCallIds.get(toolName)?.shift();
|
|
25684
|
+
}
|
|
25685
|
+
}
|
|
25686
|
+
const normalized = normalizeMessage(
|
|
25687
|
+
ollamaMessage,
|
|
25688
|
+
toolCallId,
|
|
25689
|
+
syntheticToolCallIdOffset
|
|
25690
|
+
);
|
|
25691
|
+
if (Array.isArray(ollamaMessage.tool_calls)) {
|
|
25692
|
+
syntheticToolCallIdOffset += ollamaMessage.tool_calls.length;
|
|
25693
|
+
}
|
|
25694
|
+
if (ollamaMessage.role === "assistant" && normalized) {
|
|
25695
|
+
const toolCalls = Array.isArray(normalized.tool_calls) ? normalized.tool_calls : [];
|
|
25696
|
+
for (const toolCall of toolCalls) {
|
|
25697
|
+
if (!isObject(toolCall) || !isObject(toolCall.function)) {
|
|
25698
|
+
continue;
|
|
25699
|
+
}
|
|
25700
|
+
const name = toolCall.function.name;
|
|
25701
|
+
const id = toolCall.id;
|
|
25702
|
+
if (typeof name === "string" && typeof id === "string") {
|
|
25703
|
+
const ids = pendingToolCallIds.get(name) ?? [];
|
|
25704
|
+
ids.push(id);
|
|
25705
|
+
pendingToolCallIds.set(name, ids);
|
|
25706
|
+
}
|
|
25707
|
+
}
|
|
25708
|
+
}
|
|
25709
|
+
return normalized ? [normalized] : [];
|
|
25710
|
+
});
|
|
25711
|
+
}
|
|
25712
|
+
function normalizeToolDefinition(tool) {
|
|
25713
|
+
const fn = tool.function;
|
|
25714
|
+
if (!fn || typeof fn.name !== "string" || fn.name.length === 0) {
|
|
25715
|
+
return void 0;
|
|
25716
|
+
}
|
|
25717
|
+
return {
|
|
25718
|
+
type: "function",
|
|
25719
|
+
function: {
|
|
25720
|
+
name: fn.name,
|
|
25721
|
+
...typeof fn.description === "string" ? { description: fn.description } : {},
|
|
25722
|
+
...isObject(fn.parameters) ? { parameters: fn.parameters } : {}
|
|
25723
|
+
}
|
|
25724
|
+
};
|
|
25725
|
+
}
|
|
25726
|
+
function extractToolsMetadata(tools) {
|
|
25727
|
+
if (!Array.isArray(tools)) {
|
|
25728
|
+
return {};
|
|
25729
|
+
}
|
|
25730
|
+
const normalized = tools.flatMap((tool) => {
|
|
25731
|
+
if (!isObject(tool)) {
|
|
25732
|
+
return [];
|
|
25733
|
+
}
|
|
25734
|
+
const definition = normalizeToolDefinition(tool);
|
|
25735
|
+
return definition ? [definition] : [];
|
|
25736
|
+
});
|
|
25737
|
+
return normalized.length > 0 ? { tools: normalized } : {};
|
|
25738
|
+
}
|
|
25739
|
+
function extractOptionsMetadata(options) {
|
|
25740
|
+
if (!isObject(options)) {
|
|
25741
|
+
return {};
|
|
25742
|
+
}
|
|
25743
|
+
const metadata = {};
|
|
25744
|
+
const mappings = [
|
|
25745
|
+
["temperature", "temperature"],
|
|
25746
|
+
["top_p", "top_p"],
|
|
25747
|
+
["num_predict", "max_tokens"],
|
|
25748
|
+
["frequency_penalty", "frequency_penalty"],
|
|
25749
|
+
["presence_penalty", "presence_penalty"],
|
|
25750
|
+
["stop", "stop"]
|
|
25751
|
+
];
|
|
25752
|
+
for (const [source, target] of mappings) {
|
|
25753
|
+
if (options[source] !== void 0) {
|
|
25754
|
+
metadata[target] = options[source];
|
|
25755
|
+
}
|
|
25756
|
+
}
|
|
25757
|
+
return metadata;
|
|
25758
|
+
}
|
|
25759
|
+
function extractRequestMetadata(request) {
|
|
25760
|
+
return {
|
|
25761
|
+
provider: "ollama",
|
|
25762
|
+
...typeof request?.model === "string" ? { model: request.model } : {},
|
|
25763
|
+
...extractOptionsMetadata(request?.options),
|
|
25764
|
+
...request?.format !== void 0 ? { response_format: request.format } : {}
|
|
25765
|
+
};
|
|
25766
|
+
}
|
|
25767
|
+
function extractOllamaChatInput([request]) {
|
|
25768
|
+
return {
|
|
25769
|
+
input: normalizeMessages(request.messages),
|
|
25770
|
+
metadata: {
|
|
25771
|
+
...extractRequestMetadata(request),
|
|
25772
|
+
...extractToolsMetadata(request.tools)
|
|
25773
|
+
}
|
|
25774
|
+
};
|
|
25775
|
+
}
|
|
25776
|
+
function extractOllamaGenerateInput([request]) {
|
|
25777
|
+
const normalizedPrompt = normalizeTextAndImages(
|
|
25778
|
+
typeof request.prompt === "string" ? request.prompt : "",
|
|
25779
|
+
Array.isArray(request.images) ? request.images : void 0
|
|
25780
|
+
);
|
|
25781
|
+
const input = [
|
|
25782
|
+
...typeof request.system === "string" ? [{ role: "system", content: request.system }] : [],
|
|
25783
|
+
{
|
|
25784
|
+
role: "user",
|
|
25785
|
+
content: normalizedPrompt.content,
|
|
25786
|
+
...typeof request.suffix === "string" ? { suffix: request.suffix } : {},
|
|
25787
|
+
...normalizedPrompt.unrecognizedImages ? { images: normalizedPrompt.unrecognizedImages } : {}
|
|
25788
|
+
}
|
|
25789
|
+
];
|
|
25790
|
+
return {
|
|
25791
|
+
input,
|
|
25792
|
+
metadata: extractRequestMetadata(request)
|
|
25793
|
+
};
|
|
25794
|
+
}
|
|
25795
|
+
function extractOllamaEmbedInput([request]) {
|
|
25796
|
+
return {
|
|
25797
|
+
input: request.input,
|
|
25798
|
+
metadata: extractRequestMetadata(request)
|
|
25799
|
+
};
|
|
25800
|
+
}
|
|
25801
|
+
function extractOllamaChatOutput(result, syntheticToolCallIdOffset = 0) {
|
|
25802
|
+
if (!isObject(result) || !isObject(result.message)) {
|
|
25803
|
+
return void 0;
|
|
25804
|
+
}
|
|
25805
|
+
const message = normalizeMessage(
|
|
25806
|
+
result.message,
|
|
25807
|
+
void 0,
|
|
25808
|
+
syntheticToolCallIdOffset
|
|
25809
|
+
);
|
|
25810
|
+
if (!message) {
|
|
25811
|
+
return void 0;
|
|
25812
|
+
}
|
|
25813
|
+
const toolCalls = Array.isArray(message.tool_calls) ? message.tool_calls : [];
|
|
25814
|
+
return [
|
|
25815
|
+
{
|
|
25816
|
+
index: 0,
|
|
25817
|
+
finish_reason: normalizeFinishReason(result, toolCalls.length > 0),
|
|
25818
|
+
message
|
|
25819
|
+
}
|
|
25820
|
+
];
|
|
25821
|
+
}
|
|
25822
|
+
function extractOllamaGenerateOutput(result) {
|
|
25823
|
+
if (!isObject(result) || typeof result.response !== "string") {
|
|
25824
|
+
return void 0;
|
|
25825
|
+
}
|
|
25826
|
+
return [
|
|
25827
|
+
{
|
|
25828
|
+
index: 0,
|
|
25829
|
+
finish_reason: normalizeFinishReason(result),
|
|
25830
|
+
message: {
|
|
25831
|
+
role: "assistant",
|
|
25832
|
+
content: result.response,
|
|
25833
|
+
...typeof result.thinking === "string" && result.thinking.length > 0 ? { reasoning: result.thinking } : {}
|
|
25834
|
+
}
|
|
25835
|
+
}
|
|
25836
|
+
];
|
|
25837
|
+
}
|
|
25838
|
+
function extractOllamaEmbedOutput(result) {
|
|
25839
|
+
const embedding = Array.isArray(result?.embeddings) ? result.embeddings[0] : void 0;
|
|
25840
|
+
return Array.isArray(embedding) ? { embedding_length: embedding.length } : void 0;
|
|
25841
|
+
}
|
|
25842
|
+
function extractOllamaResponseMetadata(result) {
|
|
25843
|
+
return typeof result?.model === "string" ? { model: result.model } : void 0;
|
|
25844
|
+
}
|
|
25845
|
+
function extractOllamaMetrics(result) {
|
|
25846
|
+
const metrics = {};
|
|
25847
|
+
const promptTokens = result?.prompt_eval_count;
|
|
25848
|
+
const completionTokens = result?.eval_count;
|
|
25849
|
+
if (isNonNegativeNumber(promptTokens)) {
|
|
25850
|
+
metrics.prompt_tokens = promptTokens;
|
|
25851
|
+
}
|
|
25852
|
+
if (isNonNegativeNumber(completionTokens)) {
|
|
25853
|
+
metrics.completion_tokens = completionTokens;
|
|
25854
|
+
}
|
|
25855
|
+
if (isNonNegativeNumber(promptTokens) || isNonNegativeNumber(completionTokens)) {
|
|
25856
|
+
metrics.tokens = (isNonNegativeNumber(promptTokens) ? promptTokens : 0) + (isNonNegativeNumber(completionTokens) ? completionTokens : 0);
|
|
25857
|
+
}
|
|
25858
|
+
return metrics;
|
|
25859
|
+
}
|
|
25860
|
+
function aggregateOllamaChatChunks(chunks, _result, event, _startTime) {
|
|
25861
|
+
const last = chunks.at(-1);
|
|
25862
|
+
const message = {
|
|
25863
|
+
role: "assistant",
|
|
25864
|
+
content: chunks.map((chunk) => chunk.message?.content ?? "").join(""),
|
|
25865
|
+
thinking: chunks.map((chunk) => chunk.message?.thinking ?? "").join(""),
|
|
25866
|
+
tool_calls: chunks.flatMap((chunk) => chunk.message?.tool_calls ?? [])
|
|
25867
|
+
};
|
|
25868
|
+
const response = {
|
|
25869
|
+
...last,
|
|
25870
|
+
message
|
|
25871
|
+
};
|
|
25872
|
+
return {
|
|
25873
|
+
output: extractOllamaChatOutput(
|
|
25874
|
+
response,
|
|
25875
|
+
countOllamaToolCalls(event?.arguments?.[0]?.messages)
|
|
25876
|
+
),
|
|
25877
|
+
metrics: extractOllamaMetrics(last ?? {}),
|
|
25878
|
+
metadata: extractOllamaResponseMetadata(last ?? {})
|
|
25879
|
+
};
|
|
25880
|
+
}
|
|
25881
|
+
function aggregateOllamaGenerateChunks(chunks, _result, _event, _startTime) {
|
|
25882
|
+
const last = chunks.at(-1);
|
|
25883
|
+
const response = {
|
|
25884
|
+
...last,
|
|
25885
|
+
response: chunks.map((chunk) => chunk.response ?? "").join(""),
|
|
25886
|
+
thinking: chunks.map((chunk) => chunk.thinking ?? "").join("")
|
|
25887
|
+
};
|
|
25888
|
+
return {
|
|
25889
|
+
output: extractOllamaGenerateOutput(response),
|
|
25890
|
+
metrics: extractOllamaMetrics(last ?? {}),
|
|
25891
|
+
metadata: extractOllamaResponseMetadata(last ?? {})
|
|
25892
|
+
};
|
|
25893
|
+
}
|
|
25894
|
+
|
|
24480
25895
|
// src/instrumentation/plugins/google-adk-channels.ts
|
|
24481
25896
|
var googleADKChannels = defineChannels(
|
|
24482
25897
|
"@google/adk",
|
|
@@ -28230,7 +29645,7 @@ var FlueObserveBridge = class {
|
|
|
28230
29645
|
return;
|
|
28231
29646
|
}
|
|
28232
29647
|
const state = this.operationsById.get(event.operationId) ?? this.startSyntheticOperation(event);
|
|
28233
|
-
const output = operationOutput(event);
|
|
29648
|
+
const output = operationOutput(event) ?? outputFromAgentTurn(state.latestAgentOutput);
|
|
28234
29649
|
const metadata = {
|
|
28235
29650
|
...state.metadata,
|
|
28236
29651
|
...extractEventMetadata(event),
|
|
@@ -28239,7 +29654,7 @@ var FlueObserveBridge = class {
|
|
|
28239
29654
|
};
|
|
28240
29655
|
this.finishPendingChildrenForOperation(event, output);
|
|
28241
29656
|
safeLog3(state.span, {
|
|
28242
|
-
...event.isError ? { error: toLoggedError(event.error) } : {},
|
|
29657
|
+
...event.isError ? { error: toLoggedError(event.errorInfo ?? event.error) } : {},
|
|
28243
29658
|
metadata,
|
|
28244
29659
|
metrics: durationMetrics2(event.durationMs),
|
|
28245
29660
|
output
|
|
@@ -28270,7 +29685,7 @@ var FlueObserveBridge = class {
|
|
|
28270
29685
|
};
|
|
28271
29686
|
const parent = this.parentSpanForTurn(event);
|
|
28272
29687
|
const span = startFlueSpan(parent, {
|
|
28273
|
-
name:
|
|
29688
|
+
name: "flue.turn",
|
|
28274
29689
|
spanAttributes: { type: "llm" /* LLM */ },
|
|
28275
29690
|
startTime: eventTime(event.timestamp),
|
|
28276
29691
|
event: {
|
|
@@ -28314,6 +29729,12 @@ var FlueObserveBridge = class {
|
|
|
28314
29729
|
},
|
|
28315
29730
|
output
|
|
28316
29731
|
});
|
|
29732
|
+
if (event.purpose === "agent" && event.operationId) {
|
|
29733
|
+
const operation = this.operationsById.get(event.operationId);
|
|
29734
|
+
if (operation) {
|
|
29735
|
+
operation.latestAgentOutput = output;
|
|
29736
|
+
}
|
|
29737
|
+
}
|
|
28317
29738
|
safeEnd(state.span, eventTime(event.timestamp));
|
|
28318
29739
|
this.turnsByKey.delete(key);
|
|
28319
29740
|
}
|
|
@@ -28393,7 +29814,7 @@ var FlueObserveBridge = class {
|
|
|
28393
29814
|
return;
|
|
28394
29815
|
}
|
|
28395
29816
|
safeLog3(state.span, {
|
|
28396
|
-
...event.isError ? { error: toLoggedError(event.result) } : {},
|
|
29817
|
+
...event.isError ? { error: toLoggedError(event.errorInfo ?? event.result) } : {},
|
|
28397
29818
|
metadata: {
|
|
28398
29819
|
...state.metadata,
|
|
28399
29820
|
...extractEventMetadata(event),
|
|
@@ -28439,6 +29860,7 @@ var FlueObserveBridge = class {
|
|
|
28439
29860
|
...event.usage ? { "flue.usage": event.usage } : {}
|
|
28440
29861
|
};
|
|
28441
29862
|
safeLog3(state.span, {
|
|
29863
|
+
...event.isError ? { error: toLoggedError(event.errorInfo ?? event.error) } : {},
|
|
28442
29864
|
metadata,
|
|
28443
29865
|
metrics: {
|
|
28444
29866
|
...durationMetrics2(event.durationMs),
|
|
@@ -28543,7 +29965,7 @@ var FlueObserveBridge = class {
|
|
|
28543
29965
|
...event.purpose ? { "flue.turn_purpose": event.purpose } : {}
|
|
28544
29966
|
};
|
|
28545
29967
|
const span = startFlueSpan(this.parentSpanForEvent(event), {
|
|
28546
|
-
name:
|
|
29968
|
+
name: "flue.turn",
|
|
28547
29969
|
spanAttributes: { type: "llm" /* LLM */ },
|
|
28548
29970
|
startTime: eventTime(event.timestamp),
|
|
28549
29971
|
event: { metadata }
|
|
@@ -28675,7 +30097,10 @@ function extractEventMetadata(event, ctx) {
|
|
|
28675
30097
|
return {
|
|
28676
30098
|
...event.runId ? { "flue.run_id": event.runId } : {},
|
|
28677
30099
|
...event.instanceId ? { "flue.instance_id": event.instanceId } : {},
|
|
30100
|
+
...event.submissionId ? { "flue.submission_id": event.submissionId } : {},
|
|
28678
30101
|
...event.dispatchId ? { "flue.dispatch_id": event.dispatchId } : {},
|
|
30102
|
+
...event.agentName ? { "flue.agent_name": event.agentName } : {},
|
|
30103
|
+
...event.conversationId ? { "flue.conversation_id": event.conversationId } : {},
|
|
28679
30104
|
...typeof event.eventIndex === "number" ? { "flue.event_index": event.eventIndex } : {},
|
|
28680
30105
|
...event.session ? { "flue.session": event.session } : {},
|
|
28681
30106
|
...event.parentSession ? { "flue.parent_session": event.parentSession } : {},
|
|
@@ -28704,7 +30129,7 @@ function flueTurnRequestInput(event) {
|
|
|
28704
30129
|
return event.request?.input ?? event.input;
|
|
28705
30130
|
}
|
|
28706
30131
|
function flueTurnRequestModel(event) {
|
|
28707
|
-
return event.request?.model ?? event.model;
|
|
30132
|
+
return event.request?.requestedModel ?? event.request?.model ?? event.model;
|
|
28708
30133
|
}
|
|
28709
30134
|
function flueTurnRequestProvider(event) {
|
|
28710
30135
|
return event.request?.providerName ?? event.provider ?? event.request?.providerId;
|
|
@@ -28713,10 +30138,10 @@ function flueTurnRequestApi(event) {
|
|
|
28713
30138
|
return event.request?.api ?? event.api;
|
|
28714
30139
|
}
|
|
28715
30140
|
function flueTurnRequestReasoning(event) {
|
|
28716
|
-
return event.request?.reasoning ?? event.reasoning;
|
|
30141
|
+
return event.request?.reasoningLevel ?? event.request?.reasoning ?? event.reasoning;
|
|
28717
30142
|
}
|
|
28718
30143
|
function flueTurnModel(event) {
|
|
28719
|
-
return event.request?.model ?? event.model;
|
|
30144
|
+
return event.response?.responseModel ?? event.request?.requestedModel ?? event.request?.model ?? event.model;
|
|
28720
30145
|
}
|
|
28721
30146
|
function flueTurnProvider(event) {
|
|
28722
30147
|
return event.request?.providerName ?? event.provider ?? event.request?.providerId;
|
|
@@ -28731,7 +30156,7 @@ function flueTurnOutput(event) {
|
|
|
28731
30156
|
return event.response?.output ?? event.output;
|
|
28732
30157
|
}
|
|
28733
30158
|
function flueTurnStopReason(event) {
|
|
28734
|
-
return event.response?.stopReason ?? event.stopReason;
|
|
30159
|
+
return event.response?.finishReason ?? event.response?.stopReason ?? event.stopReason;
|
|
28735
30160
|
}
|
|
28736
30161
|
function flueTurnError(event) {
|
|
28737
30162
|
return event.response?.error ?? event.response?.errorInfo?.message ?? event.error;
|
|
@@ -28746,6 +30171,9 @@ function flueToolInput(event) {
|
|
|
28746
30171
|
return event.input;
|
|
28747
30172
|
}
|
|
28748
30173
|
function flueToolOutput(event) {
|
|
30174
|
+
if (Object.hasOwn(event, "effectiveResult")) {
|
|
30175
|
+
return event.effectiveResult;
|
|
30176
|
+
}
|
|
28749
30177
|
return event.output !== void 0 ? event.output : event.result;
|
|
28750
30178
|
}
|
|
28751
30179
|
function flueToolError(event) {
|
|
@@ -28753,10 +30181,36 @@ function flueToolError(event) {
|
|
|
28753
30181
|
}
|
|
28754
30182
|
function operationOutput(event) {
|
|
28755
30183
|
if (event.operationKind === "prompt" || event.operationKind === "skill") {
|
|
28756
|
-
return llmResultFromOperationResult(event.result);
|
|
30184
|
+
return outputFromAgentInvocation(event.agentOutput) ?? llmResultFromOperationResult(event.result);
|
|
28757
30185
|
}
|
|
28758
30186
|
return event.result ?? (event.operationKind === "compact" ? { completed: true } : void 0);
|
|
28759
30187
|
}
|
|
30188
|
+
function outputFromAgentInvocation(output) {
|
|
30189
|
+
if (output?.type === "text") {
|
|
30190
|
+
return output.text;
|
|
30191
|
+
}
|
|
30192
|
+
if (output?.type === "data") {
|
|
30193
|
+
return output.data;
|
|
30194
|
+
}
|
|
30195
|
+
return void 0;
|
|
30196
|
+
}
|
|
30197
|
+
function outputFromAgentTurn(output) {
|
|
30198
|
+
if (!isObjectLike(output)) {
|
|
30199
|
+
return output;
|
|
30200
|
+
}
|
|
30201
|
+
const content = Reflect.get(output, "content");
|
|
30202
|
+
if (!Array.isArray(content)) {
|
|
30203
|
+
return output;
|
|
30204
|
+
}
|
|
30205
|
+
const text = content.flatMap((part) => {
|
|
30206
|
+
if (!isObjectLike(part) || Reflect.get(part, "type") !== "text") {
|
|
30207
|
+
return [];
|
|
30208
|
+
}
|
|
30209
|
+
const value = Reflect.get(part, "text");
|
|
30210
|
+
return typeof value === "string" ? [value] : [];
|
|
30211
|
+
});
|
|
30212
|
+
return text.length > 0 ? text.join("") : output;
|
|
30213
|
+
}
|
|
28760
30214
|
function llmResultFromOperationResult(result) {
|
|
28761
30215
|
if (!isObjectLike(result)) {
|
|
28762
30216
|
return result;
|
|
@@ -28855,7 +30309,7 @@ function safeEnd(span, endTime) {
|
|
|
28855
30309
|
}
|
|
28856
30310
|
}
|
|
28857
30311
|
function logInstrumentationError3(label, error) {
|
|
28858
|
-
|
|
30312
|
+
debugLogger.debug(`Error in ${label} instrumentation:`, error);
|
|
28859
30313
|
}
|
|
28860
30314
|
|
|
28861
30315
|
// src/wrappers/langchain/callback-handler.ts
|
|
@@ -29784,12 +31238,13 @@ var piCodingAgentChannels = defineChannels(
|
|
|
29784
31238
|
);
|
|
29785
31239
|
|
|
29786
31240
|
// src/instrumentation/plugins/pi-coding-agent-plugin.ts
|
|
29787
|
-
var
|
|
31241
|
+
var piAgentPatchStates = /* @__PURE__ */ new WeakMap();
|
|
31242
|
+
var piAgentEventSubscriptions = /* @__PURE__ */ new WeakSet();
|
|
29788
31243
|
var piPromptContextStore;
|
|
29789
31244
|
var PiCodingAgentPlugin = class extends BasePlugin {
|
|
29790
31245
|
activePromptStates = /* @__PURE__ */ new Set();
|
|
29791
31246
|
onEnable() {
|
|
29792
|
-
this.
|
|
31247
|
+
this.interceptPrompt();
|
|
29793
31248
|
}
|
|
29794
31249
|
onDisable() {
|
|
29795
31250
|
for (const unsubscribe of this.unsubscribers) {
|
|
@@ -29797,65 +31252,74 @@ var PiCodingAgentPlugin = class extends BasePlugin {
|
|
|
29797
31252
|
}
|
|
29798
31253
|
this.unsubscribers = [];
|
|
29799
31254
|
for (const state of [...this.activePromptStates]) {
|
|
29800
|
-
|
|
29801
|
-
logInstrumentationError4("Pi Coding Agent disable cleanup", error);
|
|
29802
|
-
});
|
|
31255
|
+
finishPiPromptRun(state);
|
|
29803
31256
|
}
|
|
29804
31257
|
}
|
|
29805
|
-
|
|
29806
|
-
|
|
29807
|
-
|
|
29808
|
-
|
|
29809
|
-
|
|
29810
|
-
|
|
29811
|
-
|
|
29812
|
-
|
|
29813
|
-
|
|
29814
|
-
|
|
29815
|
-
|
|
29816
|
-
|
|
29817
|
-
|
|
29818
|
-
|
|
29819
|
-
|
|
29820
|
-
|
|
29821
|
-
|
|
29822
|
-
|
|
29823
|
-
|
|
29824
|
-
states.delete(event);
|
|
29825
|
-
state.promptCallEnded = true;
|
|
29826
|
-
if (!state.finalized && state.deferCompletionUntilTurnEnd && !state.turnEnded) {
|
|
29827
|
-
if (!state.sawStreamFn) {
|
|
29828
|
-
state.queued = true;
|
|
29829
|
-
if (!state.streamPatchState.queuedPromptStates.includes(state)) {
|
|
29830
|
-
state.streamPatchState.queuedPromptStates.push(state);
|
|
29831
|
-
}
|
|
31258
|
+
interceptPrompt() {
|
|
31259
|
+
this.unsubscribers.push(
|
|
31260
|
+
piCodingAgentChannels.prompt.intercept(
|
|
31261
|
+
(target, thisArg, args, additional) => {
|
|
31262
|
+
const invokeTarget = () => Reflect.apply(target, thisArg, args);
|
|
31263
|
+
let state;
|
|
31264
|
+
try {
|
|
31265
|
+
state = startPiPromptRun(
|
|
31266
|
+
{
|
|
31267
|
+
...additional,
|
|
31268
|
+
arguments: args,
|
|
31269
|
+
self: thisArg
|
|
31270
|
+
},
|
|
31271
|
+
(finalizedState) => {
|
|
31272
|
+
this.activePromptStates.delete(finalizedState);
|
|
31273
|
+
}
|
|
31274
|
+
);
|
|
31275
|
+
} catch (error) {
|
|
31276
|
+
logInstrumentationError4("Pi Coding Agent prompt start", error);
|
|
29832
31277
|
}
|
|
29833
|
-
|
|
29834
|
-
|
|
29835
|
-
|
|
29836
|
-
|
|
29837
|
-
|
|
29838
|
-
|
|
29839
|
-
|
|
29840
|
-
|
|
31278
|
+
if (!state) {
|
|
31279
|
+
return runWithAutoInstrumentationSuppressed(invokeTarget);
|
|
31280
|
+
}
|
|
31281
|
+
this.activePromptStates.add(state);
|
|
31282
|
+
return promptContextStore().run(
|
|
31283
|
+
state,
|
|
31284
|
+
() => runWithAutoInstrumentationSuppressed(() => {
|
|
31285
|
+
let result;
|
|
31286
|
+
try {
|
|
31287
|
+
result = invokeTarget();
|
|
31288
|
+
} catch (error) {
|
|
31289
|
+
finishPiPromptRun(state, error);
|
|
31290
|
+
throw error;
|
|
31291
|
+
}
|
|
31292
|
+
return Promise.resolve(result).then(
|
|
31293
|
+
(value) => {
|
|
31294
|
+
finishPiPromptCall(state);
|
|
31295
|
+
return value;
|
|
31296
|
+
},
|
|
31297
|
+
(error) => {
|
|
31298
|
+
finishPiPromptRun(state, error);
|
|
31299
|
+
throw error;
|
|
31300
|
+
}
|
|
31301
|
+
);
|
|
31302
|
+
})
|
|
31303
|
+
);
|
|
29841
31304
|
}
|
|
29842
|
-
|
|
29843
|
-
|
|
29844
|
-
}
|
|
29845
|
-
};
|
|
29846
|
-
channel2.subscribe(handlers);
|
|
29847
|
-
this.unsubscribers.push(() => {
|
|
29848
|
-
unbindAutoInstrumentationSuppression?.();
|
|
29849
|
-
channel2.unsubscribe(handlers);
|
|
29850
|
-
});
|
|
31305
|
+
)
|
|
31306
|
+
);
|
|
29851
31307
|
}
|
|
29852
31308
|
};
|
|
31309
|
+
function finishPiPromptCall(state) {
|
|
31310
|
+
state.promptCallEnded = true;
|
|
31311
|
+
if (state.deferCompletionUntilTurnEnd && !state.turnEnded) {
|
|
31312
|
+
return;
|
|
31313
|
+
}
|
|
31314
|
+
finishPiPromptRun(state);
|
|
31315
|
+
}
|
|
29853
31316
|
function startPiPromptRun(event, onFinalize) {
|
|
29854
31317
|
const session = extractSession(event);
|
|
29855
31318
|
const agent = session?.agent;
|
|
29856
31319
|
if (!session || !isPiAgent(agent)) {
|
|
29857
31320
|
return void 0;
|
|
29858
31321
|
}
|
|
31322
|
+
installPiAgentInstrumentation(agent);
|
|
29859
31323
|
const metadata = {
|
|
29860
31324
|
...extractSessionMetadata(session),
|
|
29861
31325
|
...extractPromptOptionsMetadata(event.arguments[1]),
|
|
@@ -29877,9 +31341,7 @@ function startPiPromptRun(event, onFinalize) {
|
|
|
29877
31341
|
INSTRUMENTATION_NAMES.PI_CODING_AGENT
|
|
29878
31342
|
)
|
|
29879
31343
|
);
|
|
29880
|
-
const streamPatchState = installPiStreamPatch(agent);
|
|
29881
31344
|
const options = event.arguments[1];
|
|
29882
|
-
const promptText = event.arguments[0];
|
|
29883
31345
|
const state = {
|
|
29884
31346
|
activeLlmSpans: /* @__PURE__ */ new Set(),
|
|
29885
31347
|
activeToolSpans: /* @__PURE__ */ new Map(),
|
|
@@ -29891,29 +31353,10 @@ function startPiPromptRun(event, onFinalize) {
|
|
|
29891
31353
|
metrics: {},
|
|
29892
31354
|
onFinalize,
|
|
29893
31355
|
promptCallEnded: false,
|
|
29894
|
-
...typeof promptText === "string" ? { promptText } : {},
|
|
29895
|
-
queued: false,
|
|
29896
31356
|
span,
|
|
29897
|
-
sawStreamFn: false,
|
|
29898
31357
|
startTime: getCurrentUnixTimestamp(),
|
|
29899
|
-
streamPatchState,
|
|
29900
31358
|
turnEnded: false
|
|
29901
31359
|
};
|
|
29902
|
-
state.restorePromptContext = enterPiPromptContext(state);
|
|
29903
|
-
streamPatchState.activePromptStates.add(state);
|
|
29904
|
-
try {
|
|
29905
|
-
state.unsubscribeAgent = agent.subscribe(async (agentEvent) => {
|
|
29906
|
-
try {
|
|
29907
|
-
await runWithAutoInstrumentationSuppressed(
|
|
29908
|
-
() => handlePiAgentEvent(state, agentEvent)
|
|
29909
|
-
);
|
|
29910
|
-
} catch (error) {
|
|
29911
|
-
logInstrumentationError4("Pi Coding Agent event", error);
|
|
29912
|
-
}
|
|
29913
|
-
});
|
|
29914
|
-
} catch (error) {
|
|
29915
|
-
logInstrumentationError4("Pi Coding Agent event subscription", error);
|
|
29916
|
-
}
|
|
29917
31360
|
return state;
|
|
29918
31361
|
}
|
|
29919
31362
|
function extractSession(event) {
|
|
@@ -29927,111 +31370,55 @@ function promptContextStore() {
|
|
|
29927
31370
|
piPromptContextStore ??= isomorph_default.newAsyncLocalStorage();
|
|
29928
31371
|
return piPromptContextStore;
|
|
29929
31372
|
}
|
|
29930
|
-
function currentPromptContextFrames() {
|
|
29931
|
-
return promptContextStore().getStore()?.frames ?? [];
|
|
29932
|
-
}
|
|
29933
31373
|
function currentPiPromptState() {
|
|
29934
|
-
|
|
29935
|
-
|
|
29936
|
-
|
|
29937
|
-
|
|
29938
|
-
|
|
29939
|
-
|
|
29940
|
-
|
|
29941
|
-
|
|
29942
|
-
|
|
29943
|
-
|
|
29944
|
-
|
|
29945
|
-
|
|
29946
|
-
const frames = currentPromptContextFrames().filter(
|
|
29947
|
-
(candidate) => candidate.id !== frame.id
|
|
29948
|
-
);
|
|
29949
|
-
promptContextStore().enterWith(frames.length > 0 ? { frames } : void 0);
|
|
29950
|
-
};
|
|
29951
|
-
}
|
|
29952
|
-
function installPiStreamPatch(agent) {
|
|
29953
|
-
const existing = piStreamPatchStates.get(agent);
|
|
29954
|
-
if (existing) {
|
|
29955
|
-
if (agent.streamFn !== existing.wrappedStreamFn) {
|
|
29956
|
-
debugLogger.debug(
|
|
29957
|
-
"Pi Coding Agent streamFn changed while Braintrust instrumentation was active; preserving existing patch state."
|
|
29958
|
-
);
|
|
29959
|
-
}
|
|
29960
|
-
return existing;
|
|
29961
|
-
}
|
|
29962
|
-
const patchState = {
|
|
29963
|
-
activePromptStates: /* @__PURE__ */ new Set(),
|
|
29964
|
-
agent,
|
|
29965
|
-
originalStreamFn: agent.streamFn,
|
|
29966
|
-
queuedPromptStates: [],
|
|
29967
|
-
wrappedStreamFn: agent.streamFn
|
|
29968
|
-
};
|
|
29969
|
-
patchState.wrappedStreamFn = makeSharedInstrumentedStreamFn(patchState);
|
|
29970
|
-
agent.streamFn = patchState.wrappedStreamFn;
|
|
29971
|
-
piStreamPatchStates.set(agent, patchState);
|
|
29972
|
-
return patchState;
|
|
29973
|
-
}
|
|
29974
|
-
function resolveStreamPromptState(patchState, context) {
|
|
29975
|
-
let lastUserText;
|
|
29976
|
-
if (Array.isArray(context.messages)) {
|
|
29977
|
-
for (let i = context.messages.length - 1; i >= 0; i--) {
|
|
29978
|
-
const message = context.messages[i];
|
|
29979
|
-
if (isPiUserMessage(message)) {
|
|
29980
|
-
if (typeof message.content === "string") {
|
|
29981
|
-
lastUserText = message.content;
|
|
29982
|
-
} else {
|
|
29983
|
-
lastUserText = message.content.flatMap((part) => part.type === "text" ? [part.text] : []).join("");
|
|
29984
|
-
}
|
|
29985
|
-
break;
|
|
29986
|
-
}
|
|
29987
|
-
}
|
|
29988
|
-
}
|
|
29989
|
-
if (lastUserText !== void 0) {
|
|
29990
|
-
const queuedMatch = patchState.queuedPromptStates.find(
|
|
29991
|
-
(state) => state.promptText === lastUserText
|
|
29992
|
-
);
|
|
29993
|
-
if (queuedMatch) {
|
|
29994
|
-
return queuedMatch;
|
|
29995
|
-
}
|
|
29996
|
-
const matches = [...patchState.activePromptStates].filter(
|
|
29997
|
-
(state) => state.promptText === lastUserText
|
|
31374
|
+
return promptContextStore().getStore();
|
|
31375
|
+
}
|
|
31376
|
+
function installPiAgentInstrumentation(agent) {
|
|
31377
|
+
const existing = piAgentPatchStates.get(agent);
|
|
31378
|
+
if (!existing || agent.streamFn !== existing.wrappedStreamFn) {
|
|
31379
|
+
const patchState = {
|
|
31380
|
+
originalStreamFn: agent.streamFn,
|
|
31381
|
+
wrappedStreamFn: agent.streamFn
|
|
31382
|
+
};
|
|
31383
|
+
patchState.wrappedStreamFn = makeInstrumentedStreamFn(
|
|
31384
|
+
agent,
|
|
31385
|
+
patchState.originalStreamFn
|
|
29998
31386
|
);
|
|
29999
|
-
|
|
30000
|
-
|
|
30001
|
-
}
|
|
31387
|
+
agent.streamFn = patchState.wrappedStreamFn;
|
|
31388
|
+
piAgentPatchStates.set(agent, patchState);
|
|
30002
31389
|
}
|
|
30003
|
-
|
|
30004
|
-
|
|
30005
|
-
return contextState;
|
|
31390
|
+
if (piAgentEventSubscriptions.has(agent)) {
|
|
31391
|
+
return;
|
|
30006
31392
|
}
|
|
30007
|
-
|
|
30008
|
-
|
|
31393
|
+
try {
|
|
31394
|
+
agent.subscribe(async (event) => {
|
|
31395
|
+
const state = currentPiPromptState();
|
|
31396
|
+
if (!state || state.agent !== agent || state.finalized) {
|
|
31397
|
+
return;
|
|
31398
|
+
}
|
|
31399
|
+
try {
|
|
31400
|
+
await runWithAutoInstrumentationSuppressed(
|
|
31401
|
+
() => handlePiAgentEvent(state, event)
|
|
31402
|
+
);
|
|
31403
|
+
} catch (error) {
|
|
31404
|
+
logInstrumentationError4("Pi Coding Agent event", error);
|
|
31405
|
+
}
|
|
31406
|
+
});
|
|
31407
|
+
piAgentEventSubscriptions.add(agent);
|
|
31408
|
+
} catch (error) {
|
|
31409
|
+
logInstrumentationError4("Pi Coding Agent event subscription", error);
|
|
30009
31410
|
}
|
|
30010
|
-
return void 0;
|
|
30011
31411
|
}
|
|
30012
|
-
function
|
|
31412
|
+
function makeInstrumentedStreamFn(agent, originalStreamFn) {
|
|
30013
31413
|
return async function instrumentedPiStreamFn(model, context, options) {
|
|
30014
|
-
const
|
|
30015
|
-
|
|
30016
|
-
|
|
30017
|
-
|
|
30018
|
-
context,
|
|
30019
|
-
options
|
|
30020
|
-
]);
|
|
30021
|
-
return patchState.activePromptStates.size > 0 ? runWithAutoInstrumentationSuppressed(invokeOriginal) : invokeOriginal();
|
|
31414
|
+
const invokeOriginal = () => Reflect.apply(originalStreamFn, this, [model, context, options]);
|
|
31415
|
+
const state = currentPiPromptState();
|
|
31416
|
+
if (!state || state.agent !== agent || state.finalized) {
|
|
31417
|
+
return invokeOriginal();
|
|
30022
31418
|
}
|
|
30023
|
-
state.sawStreamFn = true;
|
|
30024
|
-
removeQueuedPromptState(state);
|
|
30025
|
-
state.streamPatchState.eventPromptState = state;
|
|
30026
31419
|
const llmState = await startPiLlmSpan(state, model, context, options);
|
|
30027
31420
|
try {
|
|
30028
|
-
const stream = await runWithAutoInstrumentationSuppressed(
|
|
30029
|
-
() => Reflect.apply(patchState.originalStreamFn, this, [
|
|
30030
|
-
model,
|
|
30031
|
-
context,
|
|
30032
|
-
options
|
|
30033
|
-
])
|
|
30034
|
-
);
|
|
31421
|
+
const stream = await runWithAutoInstrumentationSuppressed(invokeOriginal);
|
|
30035
31422
|
return patchAssistantMessageStream(stream, state, llmState);
|
|
30036
31423
|
} catch (error) {
|
|
30037
31424
|
finishPiLlmSpan(state, llmState, void 0, error);
|
|
@@ -30178,13 +31565,6 @@ async function handlePiAgentEvent(state, event) {
|
|
|
30178
31565
|
if (state.finalized) {
|
|
30179
31566
|
return;
|
|
30180
31567
|
}
|
|
30181
|
-
const eventPromptState = state.streamPatchState.eventPromptState;
|
|
30182
|
-
if (eventPromptState && eventPromptState !== state) {
|
|
30183
|
-
return;
|
|
30184
|
-
}
|
|
30185
|
-
if (!eventPromptState && (state.queued || state.streamPatchState.activePromptStates.size > 1 && currentPiPromptState() !== state)) {
|
|
30186
|
-
return;
|
|
30187
|
-
}
|
|
30188
31568
|
switch (event.type) {
|
|
30189
31569
|
case "message_end":
|
|
30190
31570
|
if (isPiAssistantMessage(event.message)) {
|
|
@@ -30199,11 +31579,8 @@ async function handlePiAgentEvent(state, event) {
|
|
|
30199
31579
|
addMetrics(state.metrics, extractUsageMetrics2(event.message.usage));
|
|
30200
31580
|
}
|
|
30201
31581
|
}
|
|
30202
|
-
if (state.streamPatchState.eventPromptState === state) {
|
|
30203
|
-
state.streamPatchState.eventPromptState = void 0;
|
|
30204
|
-
}
|
|
30205
31582
|
if (state.promptCallEnded && state.deferCompletionUntilTurnEnd) {
|
|
30206
|
-
|
|
31583
|
+
finishPiPromptRun(state);
|
|
30207
31584
|
}
|
|
30208
31585
|
return;
|
|
30209
31586
|
case "tool_execution_start":
|
|
@@ -30276,19 +31653,13 @@ function finishPiToolSpan(state, event) {
|
|
|
30276
31653
|
}
|
|
30277
31654
|
}
|
|
30278
31655
|
}
|
|
30279
|
-
|
|
31656
|
+
function finishPiPromptRun(state, error) {
|
|
30280
31657
|
if (state.finalized) {
|
|
30281
31658
|
return;
|
|
30282
31659
|
}
|
|
30283
31660
|
state.finalized = true;
|
|
30284
31661
|
state.onFinalize?.(state);
|
|
30285
|
-
|
|
30286
|
-
try {
|
|
30287
|
-
state.unsubscribeAgent?.();
|
|
30288
|
-
} catch (unsubscribeError) {
|
|
30289
|
-
logInstrumentationError4("Pi Coding Agent unsubscribe", unsubscribeError);
|
|
30290
|
-
}
|
|
30291
|
-
await finishOpenLlmSpans(state, error);
|
|
31662
|
+
finishOpenLlmSpans(state, error);
|
|
30292
31663
|
finishOpenToolSpans(state, error);
|
|
30293
31664
|
const metadata = {
|
|
30294
31665
|
...state.metadata,
|
|
@@ -30305,34 +31676,14 @@ async function finalizePiPromptRun(state, error) {
|
|
|
30305
31676
|
output: state.output
|
|
30306
31677
|
});
|
|
30307
31678
|
} finally {
|
|
30308
|
-
|
|
30309
|
-
|
|
30310
|
-
}
|
|
30311
|
-
|
|
30312
|
-
|
|
30313
|
-
patchState.activePromptStates.delete(state);
|
|
30314
|
-
removeQueuedPromptState(state);
|
|
30315
|
-
if (patchState.eventPromptState === state) {
|
|
30316
|
-
patchState.eventPromptState = void 0;
|
|
30317
|
-
}
|
|
30318
|
-
state.restorePromptContext?.();
|
|
30319
|
-
if (patchState.activePromptStates.size > 0) {
|
|
30320
|
-
return;
|
|
30321
|
-
}
|
|
30322
|
-
if (patchState.agent.streamFn === patchState.wrappedStreamFn) {
|
|
30323
|
-
patchState.agent.streamFn = patchState.originalStreamFn;
|
|
30324
|
-
}
|
|
30325
|
-
piStreamPatchStates.delete(patchState.agent);
|
|
30326
|
-
}
|
|
30327
|
-
function removeQueuedPromptState(state) {
|
|
30328
|
-
state.queued = false;
|
|
30329
|
-
const queuedPromptStates = state.streamPatchState.queuedPromptStates;
|
|
30330
|
-
const index = queuedPromptStates.indexOf(state);
|
|
30331
|
-
if (index >= 0) {
|
|
30332
|
-
queuedPromptStates.splice(index, 1);
|
|
31679
|
+
try {
|
|
31680
|
+
state.span.end();
|
|
31681
|
+
} catch (endError) {
|
|
31682
|
+
logInstrumentationError4("Pi Coding Agent prompt end", endError);
|
|
31683
|
+
}
|
|
30333
31684
|
}
|
|
30334
31685
|
}
|
|
30335
|
-
|
|
31686
|
+
function finishOpenLlmSpans(state, error) {
|
|
30336
31687
|
for (const llmState of [...state.activeLlmSpans]) {
|
|
30337
31688
|
finishPiLlmSpan(state, llmState, void 0, error);
|
|
30338
31689
|
}
|
|
@@ -30413,7 +31764,7 @@ function normalizeAssistantMessage(message) {
|
|
|
30413
31764
|
(part) => part.type === "thinking" && !part.redacted ? [part.thinking] : []
|
|
30414
31765
|
).join("");
|
|
30415
31766
|
const toolCalls = message.content.flatMap(
|
|
30416
|
-
(part) => part.type === "toolCall" ? [
|
|
31767
|
+
(part) => part.type === "toolCall" ? [normalizeToolCall2(part)] : []
|
|
30417
31768
|
);
|
|
30418
31769
|
return {
|
|
30419
31770
|
role: "assistant",
|
|
@@ -30448,13 +31799,13 @@ function normalizeUserContent(content) {
|
|
|
30448
31799
|
return part;
|
|
30449
31800
|
});
|
|
30450
31801
|
}
|
|
30451
|
-
function
|
|
31802
|
+
function normalizeToolCall2(toolCall) {
|
|
30452
31803
|
return {
|
|
30453
31804
|
id: toolCall.id,
|
|
30454
31805
|
type: "function",
|
|
30455
31806
|
function: {
|
|
30456
31807
|
name: toolCall.name,
|
|
30457
|
-
arguments:
|
|
31808
|
+
arguments: stringifyArguments2(toolCall.arguments)
|
|
30458
31809
|
}
|
|
30459
31810
|
};
|
|
30460
31811
|
}
|
|
@@ -30637,7 +31988,7 @@ function cleanMetrics5(metrics) {
|
|
|
30637
31988
|
}
|
|
30638
31989
|
return cleaned;
|
|
30639
31990
|
}
|
|
30640
|
-
function
|
|
31991
|
+
function stringifyArguments2(value) {
|
|
30641
31992
|
if (typeof value === "string") {
|
|
30642
31993
|
return value;
|
|
30643
31994
|
}
|
|
@@ -32205,6 +33556,7 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
32205
33556
|
anthropicPlugin = null;
|
|
32206
33557
|
aiSDKPlugin = null;
|
|
32207
33558
|
claudeAgentSDKPlugin = null;
|
|
33559
|
+
cloudflareThinkPlugin = null;
|
|
32208
33560
|
cursorSDKPlugin = null;
|
|
32209
33561
|
openAIAgentsPlugin = null;
|
|
32210
33562
|
googleGenAIPlugin = null;
|
|
@@ -32213,6 +33565,7 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
32213
33565
|
openRouterPlugin = null;
|
|
32214
33566
|
openRouterAgentPlugin = null;
|
|
32215
33567
|
mistralPlugin = null;
|
|
33568
|
+
ollamaPlugin = null;
|
|
32216
33569
|
googleADKPlugin = null;
|
|
32217
33570
|
coherePlugin = null;
|
|
32218
33571
|
groqPlugin = null;
|
|
@@ -32252,6 +33605,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
32252
33605
|
this.claudeAgentSDKPlugin = new ClaudeAgentSDKPlugin();
|
|
32253
33606
|
this.claudeAgentSDKPlugin.enable();
|
|
32254
33607
|
}
|
|
33608
|
+
if (integrations.cloudflareThink !== false) {
|
|
33609
|
+
this.cloudflareThinkPlugin = new CloudflareThinkPlugin();
|
|
33610
|
+
this.cloudflareThinkPlugin.enable();
|
|
33611
|
+
}
|
|
32255
33612
|
if (integrations.cursorSDK !== false && integrations.cursor !== false) {
|
|
32256
33613
|
this.cursorSDKPlugin = new CursorSDKPlugin();
|
|
32257
33614
|
this.cursorSDKPlugin.enable();
|
|
@@ -32282,6 +33639,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
32282
33639
|
this.mistralPlugin = new MistralPlugin();
|
|
32283
33640
|
this.mistralPlugin.enable();
|
|
32284
33641
|
}
|
|
33642
|
+
if (integrations.ollama !== false) {
|
|
33643
|
+
this.ollamaPlugin = new OllamaPlugin();
|
|
33644
|
+
this.ollamaPlugin.enable();
|
|
33645
|
+
}
|
|
32285
33646
|
if (integrations.googleADK !== false) {
|
|
32286
33647
|
this.googleADKPlugin = new GoogleADKPlugin();
|
|
32287
33648
|
this.googleADKPlugin.enable();
|
|
@@ -32358,6 +33719,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
32358
33719
|
this.claudeAgentSDKPlugin.disable();
|
|
32359
33720
|
this.claudeAgentSDKPlugin = null;
|
|
32360
33721
|
}
|
|
33722
|
+
if (this.cloudflareThinkPlugin) {
|
|
33723
|
+
this.cloudflareThinkPlugin.disable();
|
|
33724
|
+
this.cloudflareThinkPlugin = null;
|
|
33725
|
+
}
|
|
32361
33726
|
if (this.cursorSDKPlugin) {
|
|
32362
33727
|
this.cursorSDKPlugin.disable();
|
|
32363
33728
|
this.cursorSDKPlugin = null;
|
|
@@ -32390,6 +33755,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
32390
33755
|
this.mistralPlugin.disable();
|
|
32391
33756
|
this.mistralPlugin = null;
|
|
32392
33757
|
}
|
|
33758
|
+
if (this.ollamaPlugin) {
|
|
33759
|
+
this.ollamaPlugin.disable();
|
|
33760
|
+
this.ollamaPlugin = null;
|
|
33761
|
+
}
|
|
32393
33762
|
if (this.googleADKPlugin) {
|
|
32394
33763
|
this.googleADKPlugin.disable();
|
|
32395
33764
|
this.googleADKPlugin = null;
|
|
@@ -34126,6 +35495,7 @@ var envIntegrationAliases = {
|
|
|
34126
35495
|
cloudflareaichat: "cloudflareAIChat",
|
|
34127
35496
|
"cloudflare-ai-chat": "cloudflareAIChat",
|
|
34128
35497
|
"@cloudflare/ai-chat": "cloudflareAIChat",
|
|
35498
|
+
cloudflarethink: "cloudflareThink",
|
|
34129
35499
|
cursor: "cursor",
|
|
34130
35500
|
"cursor-sdk": "cursorSDK",
|
|
34131
35501
|
cursorsdk: "cursorSDK",
|
|
@@ -34146,6 +35516,7 @@ var envIntegrationAliases = {
|
|
|
34146
35516
|
openrouteragent: "openrouterAgent",
|
|
34147
35517
|
"openrouter-agent": "openrouterAgent",
|
|
34148
35518
|
mistral: "mistral",
|
|
35519
|
+
ollama: "ollama",
|
|
34149
35520
|
googleadk: "googleADK",
|
|
34150
35521
|
"google-adk": "googleADK",
|
|
34151
35522
|
cohere: "cohere",
|
|
@@ -34181,6 +35552,7 @@ function getDefaultInstrumentationIntegrations() {
|
|
|
34181
35552
|
huggingface: true,
|
|
34182
35553
|
claudeAgentSDK: true,
|
|
34183
35554
|
cloudflareAIChat: true,
|
|
35555
|
+
cloudflareThink: true,
|
|
34184
35556
|
cursor: true,
|
|
34185
35557
|
cursorSDK: true,
|
|
34186
35558
|
flue: true,
|
|
@@ -34189,6 +35561,7 @@ function getDefaultInstrumentationIntegrations() {
|
|
|
34189
35561
|
openrouter: true,
|
|
34190
35562
|
openrouterAgent: true,
|
|
34191
35563
|
mistral: true,
|
|
35564
|
+
ollama: true,
|
|
34192
35565
|
cohere: true,
|
|
34193
35566
|
groq: true,
|
|
34194
35567
|
bedrock: true,
|