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
|
@@ -3,8 +3,10 @@ var GLOBAL_INSTRUMENTATION_HOOKS_KEY = "__braintrust_instrumentation_hooks";
|
|
|
3
3
|
var GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION = 1;
|
|
4
4
|
var GLOBAL_INSTRUMENTATION_HOOKS_REGISTRY_BRAND = "braintrust.global-instrumentation-hooks.registry";
|
|
5
5
|
var GLOBAL_INSTRUMENTATION_HOOK_BRAND = "braintrust.global-instrumentation-hooks.hook";
|
|
6
|
+
var GLOBAL_INVOCATION_HOOK_BRAND = "braintrust.global-instrumentation-hooks.invocation-hook";
|
|
6
7
|
var registryBrand = Symbol.for(GLOBAL_INSTRUMENTATION_HOOKS_REGISTRY_BRAND);
|
|
7
8
|
var hookBrand = Symbol.for(GLOBAL_INSTRUMENTATION_HOOK_BRAND);
|
|
9
|
+
var invocationHookBrand = Symbol.for(GLOBAL_INVOCATION_HOOK_BRAND);
|
|
8
10
|
var errorReporter;
|
|
9
11
|
function setGlobalHookErrorReporter(reporter) {
|
|
10
12
|
const previousReporter = errorReporter;
|
|
@@ -149,12 +151,69 @@ var traceEvents = [
|
|
|
149
151
|
"asyncEnd",
|
|
150
152
|
"error"
|
|
151
153
|
];
|
|
154
|
+
function traceInvocation(hook, operator, target, thisArg, args, additional, callbackIndex = -1) {
|
|
155
|
+
const context = {
|
|
156
|
+
...additional,
|
|
157
|
+
arguments: args,
|
|
158
|
+
self: thisArg
|
|
159
|
+
};
|
|
160
|
+
const invoke = () => hook.invoke(target, thisArg, args, additional);
|
|
161
|
+
if (operator === "traceCallback") {
|
|
162
|
+
return hook.traceCallback(invoke, callbackIndex, context);
|
|
163
|
+
}
|
|
164
|
+
if (operator === "tracePromise") {
|
|
165
|
+
return hook.tracePromise(invoke, context);
|
|
166
|
+
}
|
|
167
|
+
return hook.traceSync(invoke, context);
|
|
168
|
+
}
|
|
169
|
+
var InvocationHook = class {
|
|
170
|
+
interceptors = [];
|
|
171
|
+
get hasInterceptors() {
|
|
172
|
+
return this.interceptors.length > 0;
|
|
173
|
+
}
|
|
174
|
+
intercept(interceptor) {
|
|
175
|
+
if (typeof interceptor !== "function") {
|
|
176
|
+
throw new TypeError("interceptor must be a function");
|
|
177
|
+
}
|
|
178
|
+
this.interceptors = [...this.interceptors, interceptor];
|
|
179
|
+
let active = true;
|
|
180
|
+
return () => {
|
|
181
|
+
if (!active) {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
active = false;
|
|
185
|
+
const index = this.interceptors.indexOf(interceptor);
|
|
186
|
+
if (index !== -1) {
|
|
187
|
+
this.interceptors = [
|
|
188
|
+
...this.interceptors.slice(0, index),
|
|
189
|
+
...this.interceptors.slice(index + 1)
|
|
190
|
+
];
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
invoke(target, thisArg, args, additional) {
|
|
195
|
+
const interceptors = this.interceptors;
|
|
196
|
+
if (interceptors.length === 0) {
|
|
197
|
+
return Reflect.apply(target, thisArg, args);
|
|
198
|
+
}
|
|
199
|
+
let next = target;
|
|
200
|
+
for (let index = interceptors.length - 1; index >= 0; index -= 1) {
|
|
201
|
+
const interceptor = interceptors[index];
|
|
202
|
+
const downstream = next;
|
|
203
|
+
next = function(...nextArgs) {
|
|
204
|
+
return interceptor(downstream, this, nextArgs, additional);
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
return Reflect.apply(next, thisArg, args);
|
|
208
|
+
}
|
|
209
|
+
};
|
|
152
210
|
var TracingHook = class {
|
|
153
211
|
start;
|
|
154
212
|
end;
|
|
155
213
|
asyncStart;
|
|
156
214
|
asyncEnd;
|
|
157
215
|
error;
|
|
216
|
+
invocationHook = new InvocationHook();
|
|
158
217
|
constructor(nameOrChannels) {
|
|
159
218
|
Object.defineProperty(this, hookBrand, {
|
|
160
219
|
configurable: false,
|
|
@@ -162,6 +221,12 @@ var TracingHook = class {
|
|
|
162
221
|
value: GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION,
|
|
163
222
|
writable: false
|
|
164
223
|
});
|
|
224
|
+
Object.defineProperty(this, invocationHookBrand, {
|
|
225
|
+
configurable: false,
|
|
226
|
+
enumerable: false,
|
|
227
|
+
value: GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION,
|
|
228
|
+
writable: false
|
|
229
|
+
});
|
|
165
230
|
if (typeof nameOrChannels === "string") {
|
|
166
231
|
this.start = new HookChannel(`tracing:${nameOrChannels}:start`);
|
|
167
232
|
this.end = new HookChannel(`tracing:${nameOrChannels}:end`);
|
|
@@ -179,6 +244,26 @@ var TracingHook = class {
|
|
|
179
244
|
get hasSubscribers() {
|
|
180
245
|
return this.start.hasSubscribers || this.end.hasSubscribers || this.asyncStart.hasSubscribers || this.asyncEnd.hasSubscribers || this.error.hasSubscribers;
|
|
181
246
|
}
|
|
247
|
+
get hasInterceptors() {
|
|
248
|
+
return this.invocationHook.hasInterceptors;
|
|
249
|
+
}
|
|
250
|
+
intercept(interceptor) {
|
|
251
|
+
return this.invocationHook.intercept(interceptor);
|
|
252
|
+
}
|
|
253
|
+
invoke(target, thisArg, args, additional) {
|
|
254
|
+
return this.invocationHook.invoke(target, thisArg, args, additional);
|
|
255
|
+
}
|
|
256
|
+
traceInvocation(operator, target, thisArg, args, additional, callbackIndex = -1) {
|
|
257
|
+
return traceInvocation(
|
|
258
|
+
this,
|
|
259
|
+
operator,
|
|
260
|
+
target,
|
|
261
|
+
thisArg,
|
|
262
|
+
args,
|
|
263
|
+
additional,
|
|
264
|
+
callbackIndex
|
|
265
|
+
);
|
|
266
|
+
}
|
|
182
267
|
subscribe(handlers) {
|
|
183
268
|
for (const eventName of traceEvents) {
|
|
184
269
|
const handler = handlers[eventName];
|
|
@@ -400,6 +485,60 @@ function hasTracingHookShape(value) {
|
|
|
400
485
|
return false;
|
|
401
486
|
}
|
|
402
487
|
}
|
|
488
|
+
function hasInvocationHookShape(value) {
|
|
489
|
+
if (typeof value !== "object" && typeof value !== "function" || value === null) {
|
|
490
|
+
return false;
|
|
491
|
+
}
|
|
492
|
+
try {
|
|
493
|
+
const hook = value;
|
|
494
|
+
return value[invocationHookBrand] === GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION && typeof hook.hasInterceptors === "boolean" && typeof hook.intercept === "function" && typeof hook.invoke === "function";
|
|
495
|
+
} catch {
|
|
496
|
+
return false;
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
function installInvocationHook(value) {
|
|
500
|
+
const hasInvocationHook = hasInvocationHookShape(value);
|
|
501
|
+
const invocationHook = new InvocationHook();
|
|
502
|
+
try {
|
|
503
|
+
if (!hasInvocationHook) {
|
|
504
|
+
Object.defineProperties(value, {
|
|
505
|
+
[invocationHookBrand]: {
|
|
506
|
+
configurable: false,
|
|
507
|
+
enumerable: false,
|
|
508
|
+
value: GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION,
|
|
509
|
+
writable: false
|
|
510
|
+
},
|
|
511
|
+
hasInterceptors: {
|
|
512
|
+
configurable: false,
|
|
513
|
+
enumerable: false,
|
|
514
|
+
get: () => invocationHook.hasInterceptors
|
|
515
|
+
},
|
|
516
|
+
intercept: {
|
|
517
|
+
configurable: false,
|
|
518
|
+
enumerable: false,
|
|
519
|
+
value: invocationHook.intercept.bind(invocationHook),
|
|
520
|
+
writable: false
|
|
521
|
+
},
|
|
522
|
+
invoke: {
|
|
523
|
+
configurable: false,
|
|
524
|
+
enumerable: false,
|
|
525
|
+
value: invocationHook.invoke.bind(invocationHook),
|
|
526
|
+
writable: false
|
|
527
|
+
}
|
|
528
|
+
});
|
|
529
|
+
}
|
|
530
|
+
if (typeof value.traceInvocation !== "function") {
|
|
531
|
+
Object.defineProperty(value, "traceInvocation", {
|
|
532
|
+
configurable: false,
|
|
533
|
+
enumerable: false,
|
|
534
|
+
value: traceInvocation.bind(void 0, value),
|
|
535
|
+
writable: false
|
|
536
|
+
});
|
|
537
|
+
}
|
|
538
|
+
} catch (error) {
|
|
539
|
+
reportError(error);
|
|
540
|
+
}
|
|
541
|
+
}
|
|
403
542
|
function isCompatibleTracingHook(value) {
|
|
404
543
|
try {
|
|
405
544
|
return value[hookBrand] === GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION && hasTracingHookShape(value);
|
|
@@ -486,6 +625,7 @@ function newGlobalTracingChannel(nameOrChannels) {
|
|
|
486
625
|
return inertTracingHook;
|
|
487
626
|
}
|
|
488
627
|
if (isCompatibleTracingHook(existing)) {
|
|
628
|
+
installInvocationHook(existing);
|
|
489
629
|
return existing;
|
|
490
630
|
}
|
|
491
631
|
if (existing !== void 0) {
|
|
@@ -541,6 +681,114 @@ var iso = {
|
|
|
541
681
|
};
|
|
542
682
|
var isomorph_default = iso;
|
|
543
683
|
|
|
684
|
+
// src/debug-logger.ts
|
|
685
|
+
var PREFIX = "[braintrust]";
|
|
686
|
+
var DEBUG_LOG_LEVEL_SYMBOL = /* @__PURE__ */ Symbol.for("braintrust-debug-log-level");
|
|
687
|
+
var LOG_LEVEL_PRIORITY = {
|
|
688
|
+
error: 0,
|
|
689
|
+
warn: 1,
|
|
690
|
+
info: 2,
|
|
691
|
+
debug: 3
|
|
692
|
+
};
|
|
693
|
+
var hasWarnedAboutInvalidEnvValue = false;
|
|
694
|
+
var debugLogStateResolver = void 0;
|
|
695
|
+
function warnInvalidEnvValue(value) {
|
|
696
|
+
if (hasWarnedAboutInvalidEnvValue) {
|
|
697
|
+
return;
|
|
698
|
+
}
|
|
699
|
+
hasWarnedAboutInvalidEnvValue = true;
|
|
700
|
+
console.warn(
|
|
701
|
+
PREFIX,
|
|
702
|
+
`Invalid BRAINTRUST_DEBUG_LOG_LEVEL value "${value}". Expected "error", "warn", "info", or "debug".`
|
|
703
|
+
);
|
|
704
|
+
}
|
|
705
|
+
function normalizeDebugLogLevelOption(option) {
|
|
706
|
+
if (option === false) {
|
|
707
|
+
return void 0;
|
|
708
|
+
}
|
|
709
|
+
if (option === "error" || option === "warn" || option === "info" || option === "debug") {
|
|
710
|
+
return option;
|
|
711
|
+
}
|
|
712
|
+
throw new Error(
|
|
713
|
+
`Invalid debugLogLevel value "${option}". Expected false, "error", "warn", "info", or "debug".`
|
|
714
|
+
);
|
|
715
|
+
}
|
|
716
|
+
function parseDebugLogLevelEnv(value) {
|
|
717
|
+
if (!value) {
|
|
718
|
+
return void 0;
|
|
719
|
+
}
|
|
720
|
+
if (value === "error" || value === "warn" || value === "info" || value === "debug") {
|
|
721
|
+
return value;
|
|
722
|
+
}
|
|
723
|
+
warnInvalidEnvValue(value);
|
|
724
|
+
return void 0;
|
|
725
|
+
}
|
|
726
|
+
function getEnvDebugLogLevel() {
|
|
727
|
+
return parseDebugLogLevelEnv(isomorph_default.getEnv("BRAINTRUST_DEBUG_LOG_LEVEL"));
|
|
728
|
+
}
|
|
729
|
+
function setGlobalDebugLogLevel(level) {
|
|
730
|
+
globalThis[DEBUG_LOG_LEVEL_SYMBOL] = level;
|
|
731
|
+
}
|
|
732
|
+
function setDebugLogStateResolver(resolver) {
|
|
733
|
+
debugLogStateResolver = resolver;
|
|
734
|
+
}
|
|
735
|
+
function resolveDebugLogLevel(state) {
|
|
736
|
+
const stateLevel = state?.getDebugLogLevel?.();
|
|
737
|
+
const hasStateOverride = state?.hasDebugLogLevelOverride?.() ?? false;
|
|
738
|
+
if (hasStateOverride) {
|
|
739
|
+
return stateLevel;
|
|
740
|
+
}
|
|
741
|
+
const globalLevel = (
|
|
742
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
743
|
+
globalThis[DEBUG_LOG_LEVEL_SYMBOL]
|
|
744
|
+
);
|
|
745
|
+
if (globalLevel !== void 0) {
|
|
746
|
+
return globalLevel === false ? void 0 : globalLevel;
|
|
747
|
+
}
|
|
748
|
+
return getEnvDebugLogLevel();
|
|
749
|
+
}
|
|
750
|
+
function emit(method, state, args) {
|
|
751
|
+
const level = resolveDebugLogLevel(state);
|
|
752
|
+
if (!level || LOG_LEVEL_PRIORITY[method] > LOG_LEVEL_PRIORITY[level]) {
|
|
753
|
+
return;
|
|
754
|
+
}
|
|
755
|
+
if (method === "info") {
|
|
756
|
+
console.log(PREFIX, ...args);
|
|
757
|
+
} else if (method === "debug") {
|
|
758
|
+
console.debug(PREFIX, ...args);
|
|
759
|
+
} else if (method === "warn") {
|
|
760
|
+
console.warn(PREFIX, ...args);
|
|
761
|
+
} else {
|
|
762
|
+
console.error(PREFIX, ...args);
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
function createDebugLogger(state) {
|
|
766
|
+
const resolveState = () => state ?? debugLogStateResolver?.();
|
|
767
|
+
return {
|
|
768
|
+
info(...args) {
|
|
769
|
+
emit("info", resolveState(), args);
|
|
770
|
+
},
|
|
771
|
+
debug(...args) {
|
|
772
|
+
emit("debug", resolveState(), args);
|
|
773
|
+
},
|
|
774
|
+
warn(...args) {
|
|
775
|
+
emit("warn", resolveState(), args);
|
|
776
|
+
},
|
|
777
|
+
error(...args) {
|
|
778
|
+
emit("error", resolveState(), args);
|
|
779
|
+
}
|
|
780
|
+
};
|
|
781
|
+
}
|
|
782
|
+
var debugLogger = {
|
|
783
|
+
...createDebugLogger(),
|
|
784
|
+
forState(state) {
|
|
785
|
+
return createDebugLogger(state);
|
|
786
|
+
}
|
|
787
|
+
};
|
|
788
|
+
setGlobalHookErrorReporter((error) => {
|
|
789
|
+
debugLogger.error("Global instrumentation hook error:", error);
|
|
790
|
+
});
|
|
791
|
+
|
|
544
792
|
// src/instrumentation/core/stream-patcher.ts
|
|
545
793
|
function isAsyncIterable(value) {
|
|
546
794
|
return value !== null && typeof value === "object" && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
@@ -565,112 +813,133 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
565
813
|
);
|
|
566
814
|
return stream;
|
|
567
815
|
}
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
816
|
+
const chunks = [];
|
|
817
|
+
let completed = false;
|
|
818
|
+
const notifyCancellation = async () => {
|
|
819
|
+
try {
|
|
820
|
+
await (options.onCancel ?? options.onComplete)(chunks);
|
|
821
|
+
} catch (error) {
|
|
822
|
+
debugLogger.error("Error in stream cancellation handler:", error);
|
|
571
823
|
}
|
|
824
|
+
};
|
|
825
|
+
const patchAbortIfPresent = () => {
|
|
572
826
|
try {
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
try {
|
|
580
|
-
const result = await runNextWithWrapper(
|
|
581
|
-
options,
|
|
582
|
-
() => originalNext(...args)
|
|
583
|
-
);
|
|
584
|
-
if (result.done) {
|
|
827
|
+
if ("abort" in stream && typeof stream.abort === "function") {
|
|
828
|
+
const originalAbort = stream.abort.bind(stream);
|
|
829
|
+
stream.abort = (...args) => {
|
|
830
|
+
try {
|
|
831
|
+
return originalAbort(...args);
|
|
832
|
+
} finally {
|
|
585
833
|
if (!completed) {
|
|
586
834
|
completed = true;
|
|
587
|
-
|
|
588
|
-
await options.onComplete(chunks);
|
|
589
|
-
} catch (error) {
|
|
590
|
-
console.error("Error in stream onComplete handler:", error);
|
|
591
|
-
}
|
|
592
|
-
}
|
|
593
|
-
} else {
|
|
594
|
-
const chunk = result.value;
|
|
595
|
-
const shouldCollect = options.shouldCollect ? options.shouldCollect(chunk) : true;
|
|
596
|
-
if (shouldCollect) {
|
|
597
|
-
chunks.push(chunk);
|
|
598
|
-
if (options.onChunk) {
|
|
599
|
-
try {
|
|
600
|
-
await options.onChunk(chunk);
|
|
601
|
-
} catch (error) {
|
|
602
|
-
console.error("Error in stream onChunk handler:", error);
|
|
603
|
-
}
|
|
604
|
-
}
|
|
835
|
+
void notifyCancellation();
|
|
605
836
|
}
|
|
606
837
|
}
|
|
607
|
-
return result;
|
|
608
|
-
} catch (error) {
|
|
609
|
-
if (!completed) {
|
|
610
|
-
completed = true;
|
|
611
|
-
if (options.onError) {
|
|
612
|
-
try {
|
|
613
|
-
await options.onError(
|
|
614
|
-
error instanceof Error ? error : new Error(String(error)),
|
|
615
|
-
chunks
|
|
616
|
-
);
|
|
617
|
-
} catch (handlerError) {
|
|
618
|
-
console.error("Error in stream onError handler:", handlerError);
|
|
619
|
-
}
|
|
620
|
-
}
|
|
621
|
-
}
|
|
622
|
-
throw error;
|
|
623
|
-
}
|
|
624
|
-
};
|
|
625
|
-
if (originalReturn) {
|
|
626
|
-
stream.return = async (...args) => {
|
|
627
|
-
if (!completed) {
|
|
628
|
-
completed = true;
|
|
629
|
-
try {
|
|
630
|
-
await options.onComplete(chunks);
|
|
631
|
-
} catch (error) {
|
|
632
|
-
console.error("Error in stream onComplete handler:", error);
|
|
633
|
-
}
|
|
634
|
-
}
|
|
635
|
-
return originalReturn(...args);
|
|
636
|
-
};
|
|
637
|
-
}
|
|
638
|
-
if (originalThrow) {
|
|
639
|
-
stream.throw = async (...args) => {
|
|
640
|
-
if (!completed) {
|
|
641
|
-
completed = true;
|
|
642
|
-
const rawError = args[0];
|
|
643
|
-
const error = rawError instanceof Error ? rawError : new Error(String(rawError));
|
|
644
|
-
if (options.onError) {
|
|
645
|
-
try {
|
|
646
|
-
await options.onError(error, chunks);
|
|
647
|
-
} catch (handlerError) {
|
|
648
|
-
console.error("Error in stream onError handler:", handlerError);
|
|
649
|
-
}
|
|
650
|
-
}
|
|
651
|
-
}
|
|
652
|
-
return originalThrow(...args);
|
|
653
838
|
};
|
|
654
839
|
}
|
|
655
|
-
Object.defineProperty(stream, "__braintrust_patched_iterator_methods", {
|
|
656
|
-
value: true
|
|
657
|
-
});
|
|
658
|
-
return stream;
|
|
659
840
|
} catch (error) {
|
|
660
|
-
|
|
841
|
+
debugLogger.warn("Failed to patch stream abort method:", error);
|
|
661
842
|
}
|
|
662
|
-
}
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
const
|
|
670
|
-
const
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
843
|
+
};
|
|
844
|
+
if (hasAsyncIteratorMethods(stream) && isSelfAsyncIterator(stream)) {
|
|
845
|
+
if ("__braintrust_patched_iterator_methods" in stream) {
|
|
846
|
+
return stream;
|
|
847
|
+
}
|
|
848
|
+
try {
|
|
849
|
+
const originalNext = stream.next.bind(stream);
|
|
850
|
+
const originalReturn = typeof stream.return === "function" ? stream.return.bind(stream) : null;
|
|
851
|
+
const originalThrow = typeof stream.throw === "function" ? stream.throw.bind(stream) : null;
|
|
852
|
+
stream.next = async (...args) => {
|
|
853
|
+
try {
|
|
854
|
+
const result = await runNextWithWrapper(
|
|
855
|
+
options,
|
|
856
|
+
() => originalNext(...args)
|
|
857
|
+
);
|
|
858
|
+
if (result.done) {
|
|
859
|
+
if (!completed) {
|
|
860
|
+
completed = true;
|
|
861
|
+
try {
|
|
862
|
+
await options.onComplete(chunks);
|
|
863
|
+
} catch (error) {
|
|
864
|
+
console.error("Error in stream onComplete handler:", error);
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
} else {
|
|
868
|
+
const chunk = result.value;
|
|
869
|
+
const shouldCollect = options.shouldCollect ? options.shouldCollect(chunk) : true;
|
|
870
|
+
if (shouldCollect) {
|
|
871
|
+
chunks.push(chunk);
|
|
872
|
+
if (options.onChunk) {
|
|
873
|
+
try {
|
|
874
|
+
await options.onChunk(chunk);
|
|
875
|
+
} catch (error) {
|
|
876
|
+
console.error("Error in stream onChunk handler:", error);
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
return result;
|
|
882
|
+
} catch (error) {
|
|
883
|
+
if (!completed) {
|
|
884
|
+
completed = true;
|
|
885
|
+
if (options.onError) {
|
|
886
|
+
try {
|
|
887
|
+
await options.onError(
|
|
888
|
+
error instanceof Error ? error : new Error(String(error)),
|
|
889
|
+
chunks
|
|
890
|
+
);
|
|
891
|
+
} catch (handlerError) {
|
|
892
|
+
console.error("Error in stream onError handler:", handlerError);
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
throw error;
|
|
897
|
+
}
|
|
898
|
+
};
|
|
899
|
+
if (originalReturn) {
|
|
900
|
+
stream.return = async (...args) => {
|
|
901
|
+
if (!completed) {
|
|
902
|
+
completed = true;
|
|
903
|
+
await notifyCancellation();
|
|
904
|
+
}
|
|
905
|
+
return originalReturn(...args);
|
|
906
|
+
};
|
|
907
|
+
}
|
|
908
|
+
if (originalThrow) {
|
|
909
|
+
stream.throw = async (...args) => {
|
|
910
|
+
if (!completed) {
|
|
911
|
+
completed = true;
|
|
912
|
+
const rawError = args[0];
|
|
913
|
+
const error = rawError instanceof Error ? rawError : new Error(String(rawError));
|
|
914
|
+
if (options.onError) {
|
|
915
|
+
try {
|
|
916
|
+
await options.onError(error, chunks);
|
|
917
|
+
} catch (handlerError) {
|
|
918
|
+
console.error("Error in stream onError handler:", handlerError);
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
return originalThrow(...args);
|
|
923
|
+
};
|
|
924
|
+
}
|
|
925
|
+
Object.defineProperty(stream, "__braintrust_patched_iterator_methods", {
|
|
926
|
+
value: true
|
|
927
|
+
});
|
|
928
|
+
patchAbortIfPresent();
|
|
929
|
+
return stream;
|
|
930
|
+
} catch (error) {
|
|
931
|
+
console.warn("Failed to patch stream iterator methods:", error);
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
const originalIteratorFn = stream[Symbol.asyncIterator];
|
|
935
|
+
if ("__braintrust_patched" in originalIteratorFn && originalIteratorFn["__braintrust_patched"]) {
|
|
936
|
+
return stream;
|
|
937
|
+
}
|
|
938
|
+
try {
|
|
939
|
+
const patchedIteratorFn = function() {
|
|
940
|
+
const iterator = originalIteratorFn.call(this);
|
|
941
|
+
const originalNext = iterator.next.bind(iterator);
|
|
942
|
+
iterator.next = async function(...args) {
|
|
674
943
|
try {
|
|
675
944
|
const result = await runNextWithWrapper(
|
|
676
945
|
options,
|
|
@@ -722,11 +991,7 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
722
991
|
iterator.return = async function(...args) {
|
|
723
992
|
if (!completed) {
|
|
724
993
|
completed = true;
|
|
725
|
-
|
|
726
|
-
await options.onComplete(chunks);
|
|
727
|
-
} catch (error) {
|
|
728
|
-
console.error("Error in stream onComplete handler:", error);
|
|
729
|
-
}
|
|
994
|
+
await notifyCancellation();
|
|
730
995
|
}
|
|
731
996
|
return originalReturn(...args);
|
|
732
997
|
};
|
|
@@ -755,6 +1020,7 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
755
1020
|
value: true
|
|
756
1021
|
});
|
|
757
1022
|
stream[Symbol.asyncIterator] = patchedIteratorFn;
|
|
1023
|
+
patchAbortIfPresent();
|
|
758
1024
|
return stream;
|
|
759
1025
|
} catch (error) {
|
|
760
1026
|
console.warn("Failed to patch stream:", error);
|
|
@@ -768,114 +1034,6 @@ function runNextWithWrapper(options, callback) {
|
|
|
768
1034
|
// src/logger.ts
|
|
769
1035
|
import { v4 as uuidv42 } from "uuid";
|
|
770
1036
|
|
|
771
|
-
// src/debug-logger.ts
|
|
772
|
-
var PREFIX = "[braintrust]";
|
|
773
|
-
var DEBUG_LOG_LEVEL_SYMBOL = /* @__PURE__ */ Symbol.for("braintrust-debug-log-level");
|
|
774
|
-
var LOG_LEVEL_PRIORITY = {
|
|
775
|
-
error: 0,
|
|
776
|
-
warn: 1,
|
|
777
|
-
info: 2,
|
|
778
|
-
debug: 3
|
|
779
|
-
};
|
|
780
|
-
var hasWarnedAboutInvalidEnvValue = false;
|
|
781
|
-
var debugLogStateResolver = void 0;
|
|
782
|
-
function warnInvalidEnvValue(value) {
|
|
783
|
-
if (hasWarnedAboutInvalidEnvValue) {
|
|
784
|
-
return;
|
|
785
|
-
}
|
|
786
|
-
hasWarnedAboutInvalidEnvValue = true;
|
|
787
|
-
console.warn(
|
|
788
|
-
PREFIX,
|
|
789
|
-
`Invalid BRAINTRUST_DEBUG_LOG_LEVEL value "${value}". Expected "error", "warn", "info", or "debug".`
|
|
790
|
-
);
|
|
791
|
-
}
|
|
792
|
-
function normalizeDebugLogLevelOption(option) {
|
|
793
|
-
if (option === false) {
|
|
794
|
-
return void 0;
|
|
795
|
-
}
|
|
796
|
-
if (option === "error" || option === "warn" || option === "info" || option === "debug") {
|
|
797
|
-
return option;
|
|
798
|
-
}
|
|
799
|
-
throw new Error(
|
|
800
|
-
`Invalid debugLogLevel value "${option}". Expected false, "error", "warn", "info", or "debug".`
|
|
801
|
-
);
|
|
802
|
-
}
|
|
803
|
-
function parseDebugLogLevelEnv(value) {
|
|
804
|
-
if (!value) {
|
|
805
|
-
return void 0;
|
|
806
|
-
}
|
|
807
|
-
if (value === "error" || value === "warn" || value === "info" || value === "debug") {
|
|
808
|
-
return value;
|
|
809
|
-
}
|
|
810
|
-
warnInvalidEnvValue(value);
|
|
811
|
-
return void 0;
|
|
812
|
-
}
|
|
813
|
-
function getEnvDebugLogLevel() {
|
|
814
|
-
return parseDebugLogLevelEnv(isomorph_default.getEnv("BRAINTRUST_DEBUG_LOG_LEVEL"));
|
|
815
|
-
}
|
|
816
|
-
function setGlobalDebugLogLevel(level) {
|
|
817
|
-
globalThis[DEBUG_LOG_LEVEL_SYMBOL] = level;
|
|
818
|
-
}
|
|
819
|
-
function setDebugLogStateResolver(resolver) {
|
|
820
|
-
debugLogStateResolver = resolver;
|
|
821
|
-
}
|
|
822
|
-
function resolveDebugLogLevel(state) {
|
|
823
|
-
const stateLevel = state?.getDebugLogLevel?.();
|
|
824
|
-
const hasStateOverride = state?.hasDebugLogLevelOverride?.() ?? false;
|
|
825
|
-
if (hasStateOverride) {
|
|
826
|
-
return stateLevel;
|
|
827
|
-
}
|
|
828
|
-
const globalLevel = (
|
|
829
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
830
|
-
globalThis[DEBUG_LOG_LEVEL_SYMBOL]
|
|
831
|
-
);
|
|
832
|
-
if (globalLevel !== void 0) {
|
|
833
|
-
return globalLevel === false ? void 0 : globalLevel;
|
|
834
|
-
}
|
|
835
|
-
return getEnvDebugLogLevel();
|
|
836
|
-
}
|
|
837
|
-
function emit(method, state, args) {
|
|
838
|
-
const level = resolveDebugLogLevel(state);
|
|
839
|
-
if (!level || LOG_LEVEL_PRIORITY[method] > LOG_LEVEL_PRIORITY[level]) {
|
|
840
|
-
return;
|
|
841
|
-
}
|
|
842
|
-
if (method === "info") {
|
|
843
|
-
console.log(PREFIX, ...args);
|
|
844
|
-
} else if (method === "debug") {
|
|
845
|
-
console.debug(PREFIX, ...args);
|
|
846
|
-
} else if (method === "warn") {
|
|
847
|
-
console.warn(PREFIX, ...args);
|
|
848
|
-
} else {
|
|
849
|
-
console.error(PREFIX, ...args);
|
|
850
|
-
}
|
|
851
|
-
}
|
|
852
|
-
function createDebugLogger(state) {
|
|
853
|
-
const resolveState = () => state ?? debugLogStateResolver?.();
|
|
854
|
-
return {
|
|
855
|
-
info(...args) {
|
|
856
|
-
emit("info", resolveState(), args);
|
|
857
|
-
},
|
|
858
|
-
debug(...args) {
|
|
859
|
-
emit("debug", resolveState(), args);
|
|
860
|
-
},
|
|
861
|
-
warn(...args) {
|
|
862
|
-
emit("warn", resolveState(), args);
|
|
863
|
-
},
|
|
864
|
-
error(...args) {
|
|
865
|
-
emit("error", resolveState(), args);
|
|
866
|
-
}
|
|
867
|
-
};
|
|
868
|
-
}
|
|
869
|
-
var debugLogger = {
|
|
870
|
-
...createDebugLogger(),
|
|
871
|
-
forState(state) {
|
|
872
|
-
return createDebugLogger(state);
|
|
873
|
-
}
|
|
874
|
-
};
|
|
875
|
-
setGlobalHookErrorReporter((error) => {
|
|
876
|
-
debugLogger.error("Global instrumentation hook error:", error);
|
|
877
|
-
});
|
|
878
|
-
|
|
879
1037
|
// src/queue.ts
|
|
880
1038
|
var DEFAULT_QUEUE_SIZE = 15e3;
|
|
881
1039
|
var Queue = class {
|
|
@@ -5382,6 +5540,7 @@ var INSTRUMENTATION_NAMES = {
|
|
|
5382
5540
|
CLAUDE_AGENT_SDK: "claude-agent-sdk",
|
|
5383
5541
|
CLOUDFLARE_AI_CHAT: "cloudflare-ai-chat",
|
|
5384
5542
|
CLOUDFLARE_AGENTS: "cloudflare-agents",
|
|
5543
|
+
CLOUDFLARE_THINK: "cloudflare-think",
|
|
5385
5544
|
COHERE: "cohere",
|
|
5386
5545
|
CURSOR_SDK: "cursor-sdk",
|
|
5387
5546
|
EVE: "eve",
|
|
@@ -5396,6 +5555,7 @@ var INSTRUMENTATION_NAMES = {
|
|
|
5396
5555
|
LANGSMITH: "langsmith",
|
|
5397
5556
|
MASTRA: "mastra",
|
|
5398
5557
|
MISTRAL: "mistral",
|
|
5558
|
+
OLLAMA: "ollama",
|
|
5399
5559
|
OPENAI: "openai",
|
|
5400
5560
|
OPENAI_AGENTS: "openai-agents",
|
|
5401
5561
|
OPENAI_CODEX: "openai-codex",
|
|
@@ -5407,7 +5567,7 @@ var INSTRUMENTATION_NAMES = {
|
|
|
5407
5567
|
var INTERNAL_SPAN_INSTRUMENTATION_NAME = /* @__PURE__ */ Symbol.for(
|
|
5408
5568
|
"braintrust.spanInstrumentationName"
|
|
5409
5569
|
);
|
|
5410
|
-
var SDK_VERSION = true ? "3.
|
|
5570
|
+
var SDK_VERSION = true ? "3.27.0" : "0.0.0";
|
|
5411
5571
|
function withSpanInstrumentationName(args, instrumentationName) {
|
|
5412
5572
|
return {
|
|
5413
5573
|
...args,
|
|
@@ -10428,6 +10588,33 @@ function traceStreamingChannel(channel2, config) {
|
|
|
10428
10588
|
const { span, startTime } = spanData;
|
|
10429
10589
|
if (isAsyncIterable(asyncEndEvent.result)) {
|
|
10430
10590
|
let firstChunkTime;
|
|
10591
|
+
const handleStreamError = (error) => {
|
|
10592
|
+
try {
|
|
10593
|
+
span.log({ error });
|
|
10594
|
+
} catch (loggingError) {
|
|
10595
|
+
debugLogger.error(
|
|
10596
|
+
`Error logging failure for ${channelName}:`,
|
|
10597
|
+
loggingError
|
|
10598
|
+
);
|
|
10599
|
+
}
|
|
10600
|
+
try {
|
|
10601
|
+
span.end();
|
|
10602
|
+
} catch (endingError) {
|
|
10603
|
+
debugLogger.error(
|
|
10604
|
+
`Error ending span for ${channelName}:`,
|
|
10605
|
+
endingError
|
|
10606
|
+
);
|
|
10607
|
+
}
|
|
10608
|
+
states.delete(event);
|
|
10609
|
+
runStreamingErrorHook({
|
|
10610
|
+
channelName,
|
|
10611
|
+
config,
|
|
10612
|
+
error,
|
|
10613
|
+
event: asyncEndEvent,
|
|
10614
|
+
span,
|
|
10615
|
+
startTime
|
|
10616
|
+
});
|
|
10617
|
+
};
|
|
10431
10618
|
patchStreamIfNeeded(asyncEndEvent.result, {
|
|
10432
10619
|
onChunk: () => {
|
|
10433
10620
|
if (firstChunkTime === void 0) {
|
|
@@ -10507,33 +10694,12 @@ function traceStreamingChannel(channel2, config) {
|
|
|
10507
10694
|
});
|
|
10508
10695
|
}
|
|
10509
10696
|
},
|
|
10510
|
-
|
|
10511
|
-
|
|
10512
|
-
|
|
10513
|
-
|
|
10514
|
-
|
|
10515
|
-
|
|
10516
|
-
loggingError
|
|
10517
|
-
);
|
|
10518
|
-
}
|
|
10519
|
-
try {
|
|
10520
|
-
span.end();
|
|
10521
|
-
} catch (endingError) {
|
|
10522
|
-
debugLogger.error(
|
|
10523
|
-
`Error ending span for ${channelName}:`,
|
|
10524
|
-
endingError
|
|
10525
|
-
);
|
|
10526
|
-
}
|
|
10527
|
-
states.delete(event);
|
|
10528
|
-
runStreamingErrorHook({
|
|
10529
|
-
channelName,
|
|
10530
|
-
config,
|
|
10531
|
-
error,
|
|
10532
|
-
event: asyncEndEvent,
|
|
10533
|
-
span,
|
|
10534
|
-
startTime
|
|
10535
|
-
});
|
|
10536
|
-
}
|
|
10697
|
+
onCancel: () => {
|
|
10698
|
+
const error = new Error("Stream cancelled before completion");
|
|
10699
|
+
error.name = "AbortError";
|
|
10700
|
+
handleStreamError(error);
|
|
10701
|
+
},
|
|
10702
|
+
onError: handleStreamError
|
|
10537
10703
|
});
|
|
10538
10704
|
return;
|
|
10539
10705
|
}
|
|
@@ -10921,11 +11087,21 @@ function defineChannels(pkg, channels, options) {
|
|
|
10921
11087
|
const tracingChannel2 = () => isomorph_default.newTracingChannel(
|
|
10922
11088
|
fullChannelName
|
|
10923
11089
|
);
|
|
11090
|
+
const intercept2 = (interceptor) => {
|
|
11091
|
+
const hook = tracingChannel2();
|
|
11092
|
+
return typeof hook.intercept === "function" ? hook.intercept(interceptor) : () => {
|
|
11093
|
+
};
|
|
11094
|
+
};
|
|
10924
11095
|
return [
|
|
10925
11096
|
key,
|
|
10926
11097
|
{
|
|
10927
11098
|
...asyncSpec,
|
|
10928
11099
|
instrumentationName,
|
|
11100
|
+
intercept: intercept2,
|
|
11101
|
+
invoke: (target, thisArg, args, additional) => {
|
|
11102
|
+
const hook = tracingChannel2();
|
|
11103
|
+
return typeof hook.invoke === "function" ? hook.invoke(target, thisArg, args, additional) : Reflect.apply(target, thisArg, args);
|
|
11104
|
+
},
|
|
10929
11105
|
tracingChannel: tracingChannel2,
|
|
10930
11106
|
tracePromise: (fn, context) => tracingChannel2().tracePromise(
|
|
10931
11107
|
fn,
|
|
@@ -10939,11 +11115,21 @@ function defineChannels(pkg, channels, options) {
|
|
|
10939
11115
|
const tracingChannel = () => isomorph_default.newTracingChannel(
|
|
10940
11116
|
fullChannelName
|
|
10941
11117
|
);
|
|
11118
|
+
const intercept = (interceptor) => {
|
|
11119
|
+
const hook = tracingChannel();
|
|
11120
|
+
return typeof hook.intercept === "function" ? hook.intercept(interceptor) : () => {
|
|
11121
|
+
};
|
|
11122
|
+
};
|
|
10942
11123
|
return [
|
|
10943
11124
|
key,
|
|
10944
11125
|
{
|
|
10945
11126
|
...syncSpec,
|
|
10946
11127
|
instrumentationName,
|
|
11128
|
+
intercept,
|
|
11129
|
+
invoke: (target, thisArg, args, additional) => {
|
|
11130
|
+
const hook = tracingChannel();
|
|
11131
|
+
return typeof hook.invoke === "function" ? hook.invoke(target, thisArg, args, additional) : Reflect.apply(target, thisArg, args);
|
|
11132
|
+
},
|
|
10947
11133
|
tracingChannel,
|
|
10948
11134
|
traceSync: (fn, context) => tracingChannel().traceSync(
|
|
10949
11135
|
fn,
|
|
@@ -12194,6 +12380,12 @@ function extractAnthropicCacheTokens(cacheReadTokens = 0, cacheCreationTokens =
|
|
|
12194
12380
|
return cacheTokens;
|
|
12195
12381
|
}
|
|
12196
12382
|
|
|
12383
|
+
// src/wrappers/anthropic-session-collector.ts
|
|
12384
|
+
var sessionStreamCollectors = /* @__PURE__ */ new WeakMap();
|
|
12385
|
+
function registerAnthropicSessionStreamCollector(stream, collector) {
|
|
12386
|
+
sessionStreamCollectors.set(stream, collector);
|
|
12387
|
+
}
|
|
12388
|
+
|
|
12197
12389
|
// src/instrumentation/plugins/anthropic-channels.ts
|
|
12198
12390
|
var anthropicChannels = defineChannels(
|
|
12199
12391
|
"@anthropic-ai/sdk",
|
|
@@ -12209,6 +12401,14 @@ var anthropicChannels = defineChannels(
|
|
|
12209
12401
|
betaMessagesToolRunner: channel({
|
|
12210
12402
|
channelName: "beta.messages.toolRunner",
|
|
12211
12403
|
kind: "sync-stream"
|
|
12404
|
+
}),
|
|
12405
|
+
betaSessionsEventsStream: channel({
|
|
12406
|
+
channelName: "beta.sessions.events.stream",
|
|
12407
|
+
kind: "async"
|
|
12408
|
+
}),
|
|
12409
|
+
betaSessionsThreadsEventsStream: channel({
|
|
12410
|
+
channelName: "beta.sessions.threads.events.stream",
|
|
12411
|
+
kind: "async"
|
|
12212
12412
|
})
|
|
12213
12413
|
},
|
|
12214
12414
|
{ instrumentationName: INSTRUMENTATION_NAMES.ANTHROPIC }
|
|
@@ -12222,6 +12422,7 @@ var AnthropicPlugin = class extends BasePlugin {
|
|
|
12222
12422
|
onEnable() {
|
|
12223
12423
|
this.subscribeToAnthropicChannels();
|
|
12224
12424
|
this.subscribeToAnthropicToolRunner();
|
|
12425
|
+
this.subscribeToAnthropicSessionStreams();
|
|
12225
12426
|
}
|
|
12226
12427
|
onDisable() {
|
|
12227
12428
|
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
@@ -12339,7 +12540,411 @@ var AnthropicPlugin = class extends BasePlugin {
|
|
|
12339
12540
|
tracingChannel.unsubscribe(handlers);
|
|
12340
12541
|
});
|
|
12341
12542
|
}
|
|
12543
|
+
subscribeToAnthropicSessionStreams() {
|
|
12544
|
+
this.subscribeToAnthropicSessionStream(
|
|
12545
|
+
anthropicChannels.betaSessionsEventsStream,
|
|
12546
|
+
false
|
|
12547
|
+
);
|
|
12548
|
+
this.subscribeToAnthropicSessionStream(
|
|
12549
|
+
anthropicChannels.betaSessionsThreadsEventsStream,
|
|
12550
|
+
true
|
|
12551
|
+
);
|
|
12552
|
+
}
|
|
12553
|
+
subscribeToAnthropicSessionStream(channel2, isThread) {
|
|
12554
|
+
const tracingChannel = channel2.tracingChannel();
|
|
12555
|
+
const pending = /* @__PURE__ */ new WeakSet();
|
|
12556
|
+
const handlers = {
|
|
12557
|
+
start: (event) => {
|
|
12558
|
+
if (isAutoInstrumentationSuppressed()) {
|
|
12559
|
+
return;
|
|
12560
|
+
}
|
|
12561
|
+
pending.add(event);
|
|
12562
|
+
},
|
|
12563
|
+
asyncEnd: (event) => {
|
|
12564
|
+
if (!pending.delete(event)) {
|
|
12565
|
+
return;
|
|
12566
|
+
}
|
|
12567
|
+
const stream = event.result;
|
|
12568
|
+
if (!isAsyncIterable(stream)) {
|
|
12569
|
+
return;
|
|
12570
|
+
}
|
|
12571
|
+
registerAnthropicSessionStreamCollector(stream, () => {
|
|
12572
|
+
wrapAnthropicSessionEventStream(stream, isThread);
|
|
12573
|
+
});
|
|
12574
|
+
},
|
|
12575
|
+
error: (event) => {
|
|
12576
|
+
pending.delete(event);
|
|
12577
|
+
}
|
|
12578
|
+
};
|
|
12579
|
+
tracingChannel.subscribe(handlers);
|
|
12580
|
+
this.unsubscribers.push(() => tracingChannel.unsubscribe(handlers));
|
|
12581
|
+
}
|
|
12342
12582
|
};
|
|
12583
|
+
function wrapAnthropicSessionEventStream(stream, isThread) {
|
|
12584
|
+
const state = {
|
|
12585
|
+
history: [],
|
|
12586
|
+
isThread,
|
|
12587
|
+
pendingInput: [],
|
|
12588
|
+
seenEventIds: /* @__PURE__ */ new Set()
|
|
12589
|
+
};
|
|
12590
|
+
patchStreamIfNeeded(stream, {
|
|
12591
|
+
onChunk: (event) => handleAnthropicSessionEvent(state, event),
|
|
12592
|
+
onComplete: () => finalizeAnthropicSessionTurn(state),
|
|
12593
|
+
onError: (error) => finalizeAnthropicSessionTurn(state, error)
|
|
12594
|
+
});
|
|
12595
|
+
return stream;
|
|
12596
|
+
}
|
|
12597
|
+
function handleAnthropicSessionEvent(state, event) {
|
|
12598
|
+
try {
|
|
12599
|
+
if (typeof event.id === "string" && event.type !== "event_delta" && state.seenEventIds.has(event.id)) {
|
|
12600
|
+
return;
|
|
12601
|
+
}
|
|
12602
|
+
if (typeof event.id === "string" && event.type !== "event_delta") {
|
|
12603
|
+
state.seenEventIds.add(event.id);
|
|
12604
|
+
}
|
|
12605
|
+
switch (event.type) {
|
|
12606
|
+
case "user.message":
|
|
12607
|
+
case "system.message":
|
|
12608
|
+
recordAnthropicSessionInput(
|
|
12609
|
+
state,
|
|
12610
|
+
event
|
|
12611
|
+
);
|
|
12612
|
+
break;
|
|
12613
|
+
case "session.status_running":
|
|
12614
|
+
if (!state.isThread) {
|
|
12615
|
+
ensureAnthropicSessionTurn(state);
|
|
12616
|
+
}
|
|
12617
|
+
break;
|
|
12618
|
+
case "session.thread_status_running":
|
|
12619
|
+
if (state.isThread) {
|
|
12620
|
+
ensureAnthropicSessionTurn(state);
|
|
12621
|
+
}
|
|
12622
|
+
break;
|
|
12623
|
+
case "span.model_request_start":
|
|
12624
|
+
if (typeof event.id === "string") {
|
|
12625
|
+
startAnthropicSessionModel(state, event.id);
|
|
12626
|
+
}
|
|
12627
|
+
break;
|
|
12628
|
+
case "event_delta":
|
|
12629
|
+
recordAnthropicSessionFirstToken(state, event);
|
|
12630
|
+
break;
|
|
12631
|
+
case "agent.message":
|
|
12632
|
+
recordAnthropicSessionMessage(
|
|
12633
|
+
state,
|
|
12634
|
+
event
|
|
12635
|
+
);
|
|
12636
|
+
break;
|
|
12637
|
+
case "agent.custom_tool_use":
|
|
12638
|
+
case "agent.mcp_tool_use":
|
|
12639
|
+
case "agent.tool_use":
|
|
12640
|
+
startAnthropicSessionTool(state, event);
|
|
12641
|
+
break;
|
|
12642
|
+
case "user.tool_confirmation":
|
|
12643
|
+
recordAnthropicSessionToolConfirmation(state, event);
|
|
12644
|
+
break;
|
|
12645
|
+
case "agent.mcp_tool_result":
|
|
12646
|
+
case "agent.tool_result":
|
|
12647
|
+
case "user.custom_tool_result":
|
|
12648
|
+
case "user.tool_result":
|
|
12649
|
+
finalizeAnthropicSessionTool(
|
|
12650
|
+
state,
|
|
12651
|
+
event
|
|
12652
|
+
);
|
|
12653
|
+
break;
|
|
12654
|
+
case "span.model_request_end":
|
|
12655
|
+
finalizeAnthropicSessionModel(
|
|
12656
|
+
state,
|
|
12657
|
+
event
|
|
12658
|
+
);
|
|
12659
|
+
break;
|
|
12660
|
+
case "session.status_idle":
|
|
12661
|
+
case "session.thread_status_idle": {
|
|
12662
|
+
if (event.type === "session.status_idle" && state.isThread || event.type === "session.thread_status_idle" && !state.isThread) {
|
|
12663
|
+
break;
|
|
12664
|
+
}
|
|
12665
|
+
const stopReason = isObject(event.stop_reason) ? event.stop_reason.type : void 0;
|
|
12666
|
+
if (stopReason === "end_turn") {
|
|
12667
|
+
finalizeAnthropicSessionTurn(state);
|
|
12668
|
+
} else if (stopReason === "retries_exhausted") {
|
|
12669
|
+
finalizeAnthropicSessionTurn(
|
|
12670
|
+
state,
|
|
12671
|
+
"Anthropic session retries exhausted"
|
|
12672
|
+
);
|
|
12673
|
+
}
|
|
12674
|
+
break;
|
|
12675
|
+
}
|
|
12676
|
+
case "session.error":
|
|
12677
|
+
finalizeAnthropicSessionTurn(state, event.error);
|
|
12678
|
+
break;
|
|
12679
|
+
case "session.deleted":
|
|
12680
|
+
case "session.status_terminated":
|
|
12681
|
+
case "session.thread_status_terminated":
|
|
12682
|
+
if (event.type === "session.deleted" || event.type === "session.status_terminated" && !state.isThread || event.type === "session.thread_status_terminated" && state.isThread) {
|
|
12683
|
+
finalizeAnthropicSessionTurn(state);
|
|
12684
|
+
}
|
|
12685
|
+
break;
|
|
12686
|
+
default:
|
|
12687
|
+
break;
|
|
12688
|
+
}
|
|
12689
|
+
} catch (error) {
|
|
12690
|
+
debugLogger.debug("Error processing Anthropic Sessions event:", error);
|
|
12691
|
+
}
|
|
12692
|
+
}
|
|
12693
|
+
function ensureAnthropicSessionTurn(state) {
|
|
12694
|
+
if (state.activeTurn) {
|
|
12695
|
+
return state.activeTurn;
|
|
12696
|
+
}
|
|
12697
|
+
const input = state.pendingInput;
|
|
12698
|
+
state.pendingInput = [];
|
|
12699
|
+
const span = startSpan(
|
|
12700
|
+
withSpanInstrumentationName(
|
|
12701
|
+
{
|
|
12702
|
+
event: {
|
|
12703
|
+
...input.length > 0 ? { input } : {},
|
|
12704
|
+
metadata: { provider: "anthropic" }
|
|
12705
|
+
},
|
|
12706
|
+
name: state.isThread ? "anthropic.beta.sessions.thread.turn" : "anthropic.beta.sessions.turn",
|
|
12707
|
+
spanAttributes: { type: "task" /* TASK */ }
|
|
12708
|
+
},
|
|
12709
|
+
INSTRUMENTATION_NAMES.ANTHROPIC
|
|
12710
|
+
)
|
|
12711
|
+
);
|
|
12712
|
+
state.activeTurn = {
|
|
12713
|
+
activeTools: /* @__PURE__ */ new Map(),
|
|
12714
|
+
input: input.slice(),
|
|
12715
|
+
metrics: {},
|
|
12716
|
+
span
|
|
12717
|
+
};
|
|
12718
|
+
return state.activeTurn;
|
|
12719
|
+
}
|
|
12720
|
+
function recordAnthropicSessionInput(state, event) {
|
|
12721
|
+
const content = processAttachmentsInInput(event.content);
|
|
12722
|
+
const message = {
|
|
12723
|
+
role: event.type === "system.message" ? "system" : "user",
|
|
12724
|
+
content
|
|
12725
|
+
};
|
|
12726
|
+
state.history.push(message);
|
|
12727
|
+
if (state.activeTurn) {
|
|
12728
|
+
state.activeTurn.input.push(message);
|
|
12729
|
+
} else {
|
|
12730
|
+
state.pendingInput.push(message);
|
|
12731
|
+
}
|
|
12732
|
+
}
|
|
12733
|
+
function startAnthropicSessionModel(state, startEventId) {
|
|
12734
|
+
const turn = ensureAnthropicSessionTurn(state);
|
|
12735
|
+
if (turn.activeModel) {
|
|
12736
|
+
finalizeAnthropicSessionModelState(state, turn);
|
|
12737
|
+
}
|
|
12738
|
+
const span = withCurrent(
|
|
12739
|
+
turn.span,
|
|
12740
|
+
() => startSpan(
|
|
12741
|
+
withSpanInstrumentationName(
|
|
12742
|
+
{
|
|
12743
|
+
event: {
|
|
12744
|
+
...state.history.length > 0 ? { input: state.history.slice() } : {},
|
|
12745
|
+
metadata: { provider: "anthropic" }
|
|
12746
|
+
},
|
|
12747
|
+
name: "anthropic.messages.create",
|
|
12748
|
+
spanAttributes: { type: "llm" /* LLM */ }
|
|
12749
|
+
},
|
|
12750
|
+
INSTRUMENTATION_NAMES.ANTHROPIC
|
|
12751
|
+
)
|
|
12752
|
+
)
|
|
12753
|
+
);
|
|
12754
|
+
turn.activeModel = {
|
|
12755
|
+
output: [],
|
|
12756
|
+
span,
|
|
12757
|
+
startEventId,
|
|
12758
|
+
startTime: getCurrentUnixTimestamp()
|
|
12759
|
+
};
|
|
12760
|
+
}
|
|
12761
|
+
function recordAnthropicSessionFirstToken(state, event) {
|
|
12762
|
+
const model = state.activeTurn?.activeModel;
|
|
12763
|
+
if (!model || model.firstTokenTime !== void 0 || !isObject(event.delta) || !isObject(event.delta.content) || typeof event.delta.content.text !== "string") {
|
|
12764
|
+
return;
|
|
12765
|
+
}
|
|
12766
|
+
model.firstTokenTime = getCurrentUnixTimestamp();
|
|
12767
|
+
}
|
|
12768
|
+
function recordAnthropicSessionMessage(state, event) {
|
|
12769
|
+
const turn = ensureAnthropicSessionTurn(state);
|
|
12770
|
+
const content = processAttachmentsInInput(
|
|
12771
|
+
event.content
|
|
12772
|
+
);
|
|
12773
|
+
if (turn.activeModel) {
|
|
12774
|
+
turn.activeModel.output.push(...content);
|
|
12775
|
+
} else {
|
|
12776
|
+
const output = { role: "assistant", content };
|
|
12777
|
+
turn.lastOutput = output;
|
|
12778
|
+
state.history.push(output);
|
|
12779
|
+
}
|
|
12780
|
+
}
|
|
12781
|
+
function startAnthropicSessionTool(state, event) {
|
|
12782
|
+
const turn = ensureAnthropicSessionTurn(state);
|
|
12783
|
+
if (turn.activeModel) {
|
|
12784
|
+
turn.activeModel.output.push({
|
|
12785
|
+
type: "tool_use",
|
|
12786
|
+
id: event.id,
|
|
12787
|
+
name: event.name,
|
|
12788
|
+
input: event.input
|
|
12789
|
+
});
|
|
12790
|
+
}
|
|
12791
|
+
const existing = turn.activeTools.get(event.id);
|
|
12792
|
+
if (existing) {
|
|
12793
|
+
existing.span.end();
|
|
12794
|
+
turn.activeTools.delete(event.id);
|
|
12795
|
+
}
|
|
12796
|
+
const span = withCurrent(
|
|
12797
|
+
turn.span,
|
|
12798
|
+
() => startSpan(
|
|
12799
|
+
withSpanInstrumentationName(
|
|
12800
|
+
{
|
|
12801
|
+
event: { input: event.input },
|
|
12802
|
+
name: event.name,
|
|
12803
|
+
spanAttributes: { type: "tool" /* TOOL */ }
|
|
12804
|
+
},
|
|
12805
|
+
INSTRUMENTATION_NAMES.ANTHROPIC
|
|
12806
|
+
)
|
|
12807
|
+
)
|
|
12808
|
+
);
|
|
12809
|
+
const toolState = {
|
|
12810
|
+
approval: event.evaluated_permission === "allow" ? "approved" : event.evaluated_permission === "deny" ? "denied" : void 0,
|
|
12811
|
+
span
|
|
12812
|
+
};
|
|
12813
|
+
turn.activeTools.set(event.id, toolState);
|
|
12814
|
+
if (toolState.approval === "denied") {
|
|
12815
|
+
finalizeAnthropicSessionToolState(toolState);
|
|
12816
|
+
turn.activeTools.delete(event.id);
|
|
12817
|
+
}
|
|
12818
|
+
}
|
|
12819
|
+
function recordAnthropicSessionToolConfirmation(state, event) {
|
|
12820
|
+
if (typeof event.tool_use_id !== "string" || event.result !== "allow" && event.result !== "deny") {
|
|
12821
|
+
return;
|
|
12822
|
+
}
|
|
12823
|
+
const turn = state.activeTurn;
|
|
12824
|
+
const tool = turn?.activeTools.get(event.tool_use_id);
|
|
12825
|
+
if (!turn || !tool) {
|
|
12826
|
+
return;
|
|
12827
|
+
}
|
|
12828
|
+
tool.approval = event.result === "allow" ? "approved" : "denied";
|
|
12829
|
+
if (tool.approval === "denied") {
|
|
12830
|
+
finalizeAnthropicSessionToolState(tool);
|
|
12831
|
+
turn.activeTools.delete(event.tool_use_id);
|
|
12832
|
+
}
|
|
12833
|
+
}
|
|
12834
|
+
function finalizeAnthropicSessionTool(state, event) {
|
|
12835
|
+
const toolUseId = event.tool_use_id ?? event.mcp_tool_use_id ?? event.custom_tool_use_id;
|
|
12836
|
+
if (!toolUseId) {
|
|
12837
|
+
return;
|
|
12838
|
+
}
|
|
12839
|
+
const content = processAttachmentsInInput(event.content);
|
|
12840
|
+
const turn = state.activeTurn;
|
|
12841
|
+
const tool = turn?.activeTools.get(toolUseId);
|
|
12842
|
+
if (turn && tool) {
|
|
12843
|
+
finalizeAnthropicSessionToolState(tool, event, content);
|
|
12844
|
+
turn.activeTools.delete(toolUseId);
|
|
12845
|
+
}
|
|
12846
|
+
const toolResult = {
|
|
12847
|
+
type: "tool_result",
|
|
12848
|
+
tool_use_id: toolUseId,
|
|
12849
|
+
...content !== void 0 ? { content } : {},
|
|
12850
|
+
...event.is_error === true ? { is_error: true } : {}
|
|
12851
|
+
};
|
|
12852
|
+
state.history.push({
|
|
12853
|
+
role: "user",
|
|
12854
|
+
content: [toolResult]
|
|
12855
|
+
});
|
|
12856
|
+
}
|
|
12857
|
+
function finalizeAnthropicSessionToolState(state, event, content = event?.content) {
|
|
12858
|
+
safeAnthropicSessionLog(state.span, {
|
|
12859
|
+
...event?.is_error === true ? {
|
|
12860
|
+
error: content ?? "Anthropic session tool execution failed"
|
|
12861
|
+
} : {},
|
|
12862
|
+
...state.approval ? { metadata: { tool_approval: state.approval } } : {},
|
|
12863
|
+
...content !== void 0 ? { output: content } : {}
|
|
12864
|
+
});
|
|
12865
|
+
state.span.end();
|
|
12866
|
+
}
|
|
12867
|
+
function finalizeAnthropicSessionModel(state, event) {
|
|
12868
|
+
const turn = state.activeTurn;
|
|
12869
|
+
const model = turn?.activeModel;
|
|
12870
|
+
if (!turn || !model || model.startEventId !== event.model_request_start_id) {
|
|
12871
|
+
return;
|
|
12872
|
+
}
|
|
12873
|
+
finalizeAnthropicSessionModelState(state, turn, event);
|
|
12874
|
+
}
|
|
12875
|
+
function finalizeAnthropicSessionModelState(state, turn, event) {
|
|
12876
|
+
const model = turn.activeModel;
|
|
12877
|
+
if (!model) {
|
|
12878
|
+
return;
|
|
12879
|
+
}
|
|
12880
|
+
turn.activeModel = void 0;
|
|
12881
|
+
const metrics = event ? parseAnthropicSessionModelUsage(event.model_usage) : {};
|
|
12882
|
+
if (model.firstTokenTime !== void 0) {
|
|
12883
|
+
metrics.time_to_first_token = model.firstTokenTime - model.startTime;
|
|
12884
|
+
}
|
|
12885
|
+
const output = model.output.length > 0 ? { role: "assistant", content: model.output } : void 0;
|
|
12886
|
+
safeAnthropicSessionLog(model.span, {
|
|
12887
|
+
...event?.is_error ? { error: "Anthropic session model request failed" } : {},
|
|
12888
|
+
...Object.keys(metrics).length > 0 ? { metrics } : {},
|
|
12889
|
+
...output ? { output } : {}
|
|
12890
|
+
});
|
|
12891
|
+
model.span.end();
|
|
12892
|
+
if (output) {
|
|
12893
|
+
turn.lastOutput = output;
|
|
12894
|
+
state.history.push(output);
|
|
12895
|
+
}
|
|
12896
|
+
for (const key of [
|
|
12897
|
+
"prompt_tokens",
|
|
12898
|
+
"completion_tokens",
|
|
12899
|
+
"tokens",
|
|
12900
|
+
"prompt_cached_tokens",
|
|
12901
|
+
"prompt_cache_creation_tokens"
|
|
12902
|
+
]) {
|
|
12903
|
+
const value = metrics[key];
|
|
12904
|
+
if (typeof value === "number") {
|
|
12905
|
+
turn.metrics[key] = (turn.metrics[key] ?? 0) + value;
|
|
12906
|
+
}
|
|
12907
|
+
}
|
|
12908
|
+
}
|
|
12909
|
+
function parseAnthropicSessionModelUsage(usage) {
|
|
12910
|
+
const finalized = finalizeAnthropicTokens({
|
|
12911
|
+
completion_tokens: usage.output_tokens,
|
|
12912
|
+
prompt_cache_creation_tokens: usage.cache_creation_input_tokens,
|
|
12913
|
+
prompt_cached_tokens: usage.cache_read_input_tokens,
|
|
12914
|
+
prompt_tokens: usage.input_tokens
|
|
12915
|
+
});
|
|
12916
|
+
return Object.fromEntries(
|
|
12917
|
+
Object.entries(finalized).filter(
|
|
12918
|
+
(entry) => entry[1] !== void 0
|
|
12919
|
+
)
|
|
12920
|
+
);
|
|
12921
|
+
}
|
|
12922
|
+
function finalizeAnthropicSessionTurn(state, error) {
|
|
12923
|
+
const turn = state.activeTurn;
|
|
12924
|
+
if (!turn) {
|
|
12925
|
+
return;
|
|
12926
|
+
}
|
|
12927
|
+
state.activeTurn = void 0;
|
|
12928
|
+
finalizeAnthropicSessionModelState(state, turn);
|
|
12929
|
+
for (const tool of turn.activeTools.values()) {
|
|
12930
|
+
finalizeAnthropicSessionToolState(tool);
|
|
12931
|
+
}
|
|
12932
|
+
turn.activeTools.clear();
|
|
12933
|
+
safeAnthropicSessionLog(turn.span, {
|
|
12934
|
+
...error !== void 0 ? { error: error instanceof Error ? error : toLoggedError(error) } : {},
|
|
12935
|
+
...turn.input.length > 0 ? { input: turn.input } : {},
|
|
12936
|
+
...turn.lastOutput ? { output: turn.lastOutput } : {},
|
|
12937
|
+
...Object.keys(turn.metrics).length > 0 ? { metrics: turn.metrics } : {}
|
|
12938
|
+
});
|
|
12939
|
+
turn.span.end();
|
|
12940
|
+
}
|
|
12941
|
+
function safeAnthropicSessionLog(span, event) {
|
|
12942
|
+
try {
|
|
12943
|
+
span.log(event);
|
|
12944
|
+
} catch (error) {
|
|
12945
|
+
debugLogger.debug("Error logging Anthropic Sessions span:", error);
|
|
12946
|
+
}
|
|
12947
|
+
}
|
|
12343
12948
|
function parseMetricsFromUsage2(usage) {
|
|
12344
12949
|
if (!usage) {
|
|
12345
12950
|
return {};
|
|
@@ -14213,6 +14818,29 @@ var harnessAgentChannels = defineChannels(
|
|
|
14213
14818
|
{ instrumentationName: INSTRUMENTATION_NAMES.AI_SDK }
|
|
14214
14819
|
);
|
|
14215
14820
|
|
|
14821
|
+
// src/instrumentation/plugins/cloudflare-think-context.ts
|
|
14822
|
+
var cloudflareThinkSpans = /* @__PURE__ */ new Map();
|
|
14823
|
+
function registerCloudflareThinkSpan(span) {
|
|
14824
|
+
if (span.spanId) {
|
|
14825
|
+
cloudflareThinkSpans.set(span.spanId, span);
|
|
14826
|
+
}
|
|
14827
|
+
}
|
|
14828
|
+
function unregisterCloudflareThinkSpan(span) {
|
|
14829
|
+
if (span.spanId) {
|
|
14830
|
+
cloudflareThinkSpans.delete(span.spanId);
|
|
14831
|
+
}
|
|
14832
|
+
}
|
|
14833
|
+
function currentCloudflareThinkSpan() {
|
|
14834
|
+
const parentSpanIds = _internalGetGlobalState()?.contextManager.getParentSpanIds()?.spanParents ?? [];
|
|
14835
|
+
for (const parentSpanId of parentSpanIds) {
|
|
14836
|
+
const span = cloudflareThinkSpans.get(parentSpanId);
|
|
14837
|
+
if (span) {
|
|
14838
|
+
return span;
|
|
14839
|
+
}
|
|
14840
|
+
}
|
|
14841
|
+
return void 0;
|
|
14842
|
+
}
|
|
14843
|
+
|
|
14216
14844
|
// src/instrumentation/plugins/ai-sdk-plugin.ts
|
|
14217
14845
|
var DEFAULT_DENY_OUTPUT_PATHS = [
|
|
14218
14846
|
// v3
|
|
@@ -14319,6 +14947,7 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
14319
14947
|
traceStreamingChannel(aiSDKChannels.streamText, {
|
|
14320
14948
|
name: "streamText",
|
|
14321
14949
|
type: "function" /* FUNCTION */,
|
|
14950
|
+
shouldTrace: () => currentCloudflareThinkSpan() === void 0,
|
|
14322
14951
|
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
14323
14952
|
extractOutput: (result, endEvent) => processAISDKOutput(
|
|
14324
14953
|
result,
|
|
@@ -14339,6 +14968,7 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
14339
14968
|
traceSyncStreamChannel(aiSDKChannels.streamTextSync, {
|
|
14340
14969
|
name: "streamText",
|
|
14341
14970
|
type: "function" /* FUNCTION */,
|
|
14971
|
+
shouldTrace: () => currentCloudflareThinkSpan() === void 0,
|
|
14342
14972
|
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
14343
14973
|
patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
|
|
14344
14974
|
defaultDenyOutputPaths: denyOutputPaths,
|
|
@@ -15324,6 +15954,23 @@ function prepareAISDKWorkflowAgentStreamInput(params, event, span, defaultDenyOu
|
|
|
15324
15954
|
metadata
|
|
15325
15955
|
};
|
|
15326
15956
|
}
|
|
15957
|
+
function prepareAISDKAgentCallInput(params, event, span, defaultDenyOutputPaths = DEFAULT_DENY_OUTPUT_PATHS) {
|
|
15958
|
+
const { input } = processAISDKWorkflowAgentCallInput(params);
|
|
15959
|
+
const metadata = extractMetadataFromCallParams(params, event.self);
|
|
15960
|
+
const childTracing = prepareAISDKChildTracing(
|
|
15961
|
+
params,
|
|
15962
|
+
event.self,
|
|
15963
|
+
span,
|
|
15964
|
+
defaultDenyOutputPaths,
|
|
15965
|
+
event.aiSDK,
|
|
15966
|
+
{ agentOwner: true }
|
|
15967
|
+
);
|
|
15968
|
+
event.modelWrapped = childTracing.modelWrapped;
|
|
15969
|
+
if (childTracing.cleanup) {
|
|
15970
|
+
event.__braintrust_ai_sdk_cleanup = childTracing.cleanup;
|
|
15971
|
+
}
|
|
15972
|
+
return { input, metadata };
|
|
15973
|
+
}
|
|
15327
15974
|
function prepareAISDKEmbedInput(params, self) {
|
|
15328
15975
|
return {
|
|
15329
15976
|
input: { ...params },
|
|
@@ -15347,6 +15994,18 @@ function extractTopLevelAISDKMetrics(result, event, startTime) {
|
|
|
15347
15994
|
}
|
|
15348
15995
|
return metrics;
|
|
15349
15996
|
}
|
|
15997
|
+
async function extractResolvedAISDKTokenMetrics(result) {
|
|
15998
|
+
for (const field of ["totalUsage", "usage"]) {
|
|
15999
|
+
try {
|
|
16000
|
+
const usage = await Promise.resolve(result[field]);
|
|
16001
|
+
if (usage !== void 0) {
|
|
16002
|
+
return extractTokenMetrics({ [field]: usage });
|
|
16003
|
+
}
|
|
16004
|
+
} catch {
|
|
16005
|
+
}
|
|
16006
|
+
}
|
|
16007
|
+
return extractTokenMetrics(result);
|
|
16008
|
+
}
|
|
15350
16009
|
function hasModelChildTracing(event) {
|
|
15351
16010
|
return event?.modelWrapped === true || event?.__braintrust_ai_sdk_model_wrapped === true;
|
|
15352
16011
|
}
|
|
@@ -16164,13 +16823,15 @@ function patchAISDKStreamingResult(args) {
|
|
|
16164
16823
|
const {
|
|
16165
16824
|
defaultDenyOutputPaths,
|
|
16166
16825
|
endEvent,
|
|
16826
|
+
forceTopLevelMetrics,
|
|
16167
16827
|
onComplete,
|
|
16168
16828
|
onCancel,
|
|
16169
16829
|
onError,
|
|
16170
16830
|
result,
|
|
16171
16831
|
resolvePromiseUsage,
|
|
16172
16832
|
span,
|
|
16173
|
-
startTime
|
|
16833
|
+
startTime,
|
|
16834
|
+
transformOutput
|
|
16174
16835
|
} = args;
|
|
16175
16836
|
if (!result || typeof result !== "object") {
|
|
16176
16837
|
return false;
|
|
@@ -16223,8 +16884,8 @@ function patchAISDKStreamingResult(args) {
|
|
|
16223
16884
|
}
|
|
16224
16885
|
outputLogged = true;
|
|
16225
16886
|
try {
|
|
16226
|
-
const metrics = extractTopLevelAISDKMetrics(result, endEvent);
|
|
16227
|
-
if (resolvePromiseUsage) {
|
|
16887
|
+
const metrics = forceTopLevelMetrics ? await extractResolvedAISDKTokenMetrics(result) : extractTopLevelAISDKMetrics(result, endEvent);
|
|
16888
|
+
if (resolvePromiseUsage && !forceTopLevelMetrics) {
|
|
16228
16889
|
try {
|
|
16229
16890
|
const resultRecord2 = result;
|
|
16230
16891
|
const pendingUsage = resultRecord2.totalUsage ?? resultRecord2.usage;
|
|
@@ -16243,10 +16904,11 @@ function patchAISDKStreamingResult(args) {
|
|
|
16243
16904
|
if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
|
|
16244
16905
|
metrics.time_to_first_token = firstChunkTime - startTime;
|
|
16245
16906
|
}
|
|
16246
|
-
const
|
|
16907
|
+
const processedOutput = await processAISDKStreamingOutput(
|
|
16247
16908
|
result,
|
|
16248
16909
|
resolveDenyOutputPaths(endEvent, defaultDenyOutputPaths)
|
|
16249
16910
|
);
|
|
16911
|
+
const output = transformOutput ? transformOutput(processedOutput) : processedOutput;
|
|
16250
16912
|
const metadata = buildResolvedMetadataPayload(result).metadata;
|
|
16251
16913
|
try {
|
|
16252
16914
|
span.log({
|
|
@@ -18668,6 +19330,295 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
18668
19330
|
}
|
|
18669
19331
|
};
|
|
18670
19332
|
|
|
19333
|
+
// src/instrumentation/plugins/cloudflare-think-channels.ts
|
|
19334
|
+
var cloudflareThinkChannels = defineChannels(
|
|
19335
|
+
"@cloudflare/think",
|
|
19336
|
+
{
|
|
19337
|
+
runInferenceLoop: channel({
|
|
19338
|
+
channelName: "Think.runInferenceLoop",
|
|
19339
|
+
kind: "async"
|
|
19340
|
+
})
|
|
19341
|
+
},
|
|
19342
|
+
{ instrumentationName: INSTRUMENTATION_NAMES.CLOUDFLARE_THINK }
|
|
19343
|
+
);
|
|
19344
|
+
|
|
19345
|
+
// src/instrumentation/plugins/cloudflare-think-plugin.ts
|
|
19346
|
+
var THINK_STATE_ID = /* @__PURE__ */ Symbol.for("braintrust.cloudflare-think.state-id");
|
|
19347
|
+
var CloudflareThinkPlugin = class extends BasePlugin {
|
|
19348
|
+
statesBySpanId = /* @__PURE__ */ new Map();
|
|
19349
|
+
onEnable() {
|
|
19350
|
+
this.subscribeToThinkRuns();
|
|
19351
|
+
this.subscribeToAISDKStreamTextSync();
|
|
19352
|
+
this.subscribeToAISDKStreamTextAsync();
|
|
19353
|
+
}
|
|
19354
|
+
onDisable() {
|
|
19355
|
+
for (const unsubscribe of this.unsubscribers) {
|
|
19356
|
+
unsubscribe();
|
|
19357
|
+
}
|
|
19358
|
+
this.unsubscribers = [];
|
|
19359
|
+
for (const state of this.statesBySpanId.values()) {
|
|
19360
|
+
this.finishState(state);
|
|
19361
|
+
}
|
|
19362
|
+
this.statesBySpanId.clear();
|
|
19363
|
+
}
|
|
19364
|
+
subscribeToThinkRuns() {
|
|
19365
|
+
const channel2 = cloudflareThinkChannels.runInferenceLoop.tracingChannel();
|
|
19366
|
+
const states = /* @__PURE__ */ new WeakMap();
|
|
19367
|
+
const state = _internalGetGlobalState();
|
|
19368
|
+
const contextManager = state?.contextManager;
|
|
19369
|
+
const currentSpanStore = contextManager ? contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
|
|
19370
|
+
const ensureState2 = (event) => {
|
|
19371
|
+
if (isAutoInstrumentationSuppressed()) {
|
|
19372
|
+
return void 0;
|
|
19373
|
+
}
|
|
19374
|
+
const existing = states.get(event);
|
|
19375
|
+
if (existing) {
|
|
19376
|
+
return existing;
|
|
19377
|
+
}
|
|
19378
|
+
const span = startSpan(
|
|
19379
|
+
withSpanInstrumentationName(
|
|
19380
|
+
{
|
|
19381
|
+
name: "Think.runTurn",
|
|
19382
|
+
spanAttributes: { type: "task" /* TASK */ }
|
|
19383
|
+
},
|
|
19384
|
+
INSTRUMENTATION_NAMES.CLOUDFLARE_THINK
|
|
19385
|
+
)
|
|
19386
|
+
);
|
|
19387
|
+
const runState = {
|
|
19388
|
+
aiResultPatched: false,
|
|
19389
|
+
fallbackInput: extractFallbackInput(event.self?.messages),
|
|
19390
|
+
finalized: false,
|
|
19391
|
+
inputLogged: false,
|
|
19392
|
+
span,
|
|
19393
|
+
startTime: getCurrentUnixTimestamp()
|
|
19394
|
+
};
|
|
19395
|
+
const metadata = {
|
|
19396
|
+
braintrust: {
|
|
19397
|
+
integration_name: "cloudflare-think",
|
|
19398
|
+
sdk_language: "typescript"
|
|
19399
|
+
}
|
|
19400
|
+
};
|
|
19401
|
+
if (typeof event.moduleVersion === "string") {
|
|
19402
|
+
metadata["cloudflare_think.version"] = event.moduleVersion;
|
|
19403
|
+
}
|
|
19404
|
+
span.log({ metadata });
|
|
19405
|
+
states.set(event, runState);
|
|
19406
|
+
if (span.spanId) {
|
|
19407
|
+
this.statesBySpanId.set(span.spanId, runState);
|
|
19408
|
+
}
|
|
19409
|
+
registerCloudflareThinkSpan(span);
|
|
19410
|
+
return runState;
|
|
19411
|
+
};
|
|
19412
|
+
if (contextManager && currentSpanStore && channel2.start) {
|
|
19413
|
+
channel2.start.bindStore(currentSpanStore, (event) => {
|
|
19414
|
+
const runState = ensureState2(event);
|
|
19415
|
+
return runState ? contextManager.wrapSpanForStore(runState.span) : currentSpanStore.getStore();
|
|
19416
|
+
});
|
|
19417
|
+
this.unsubscribers.push(
|
|
19418
|
+
() => channel2.start?.unbindStore(currentSpanStore)
|
|
19419
|
+
);
|
|
19420
|
+
}
|
|
19421
|
+
const handlers = {
|
|
19422
|
+
start: (event) => {
|
|
19423
|
+
ensureState2(event);
|
|
19424
|
+
},
|
|
19425
|
+
asyncEnd: (event) => {
|
|
19426
|
+
const runState = states.get(event);
|
|
19427
|
+
states.delete(event);
|
|
19428
|
+
if (!runState || runState.finalized || runState.aiResultPatched) {
|
|
19429
|
+
return;
|
|
19430
|
+
}
|
|
19431
|
+
this.finishState(runState, void 0, event.result);
|
|
19432
|
+
},
|
|
19433
|
+
error: (event) => {
|
|
19434
|
+
const runState = states.get(event);
|
|
19435
|
+
states.delete(event);
|
|
19436
|
+
if (runState) {
|
|
19437
|
+
this.finishState(runState, event.error);
|
|
19438
|
+
}
|
|
19439
|
+
}
|
|
19440
|
+
};
|
|
19441
|
+
channel2.subscribe(handlers);
|
|
19442
|
+
this.unsubscribers.push(() => channel2.unsubscribe(handlers));
|
|
19443
|
+
}
|
|
19444
|
+
subscribeToAISDKStreamTextSync() {
|
|
19445
|
+
const channel2 = aiSDKChannels.streamTextSync.tracingChannel();
|
|
19446
|
+
const handlers = {
|
|
19447
|
+
start: (event) => {
|
|
19448
|
+
this.startAISDKStream(event);
|
|
19449
|
+
},
|
|
19450
|
+
end: (event) => {
|
|
19451
|
+
this.endAISDKStream(event);
|
|
19452
|
+
},
|
|
19453
|
+
error: (event) => {
|
|
19454
|
+
this.errorAISDKStream(event);
|
|
19455
|
+
}
|
|
19456
|
+
};
|
|
19457
|
+
channel2.subscribe(handlers);
|
|
19458
|
+
this.unsubscribers.push(() => channel2.unsubscribe(handlers));
|
|
19459
|
+
}
|
|
19460
|
+
subscribeToAISDKStreamTextAsync() {
|
|
19461
|
+
const channel2 = aiSDKChannels.streamText.tracingChannel();
|
|
19462
|
+
const handlers = {
|
|
19463
|
+
start: (event) => {
|
|
19464
|
+
this.startAISDKStream(event);
|
|
19465
|
+
},
|
|
19466
|
+
asyncEnd: (event) => {
|
|
19467
|
+
this.endAISDKStream(event);
|
|
19468
|
+
},
|
|
19469
|
+
error: (event) => {
|
|
19470
|
+
this.errorAISDKStream(event);
|
|
19471
|
+
}
|
|
19472
|
+
};
|
|
19473
|
+
channel2.subscribe(handlers);
|
|
19474
|
+
this.unsubscribers.push(() => channel2.unsubscribe(handlers));
|
|
19475
|
+
}
|
|
19476
|
+
startAISDKStream(event) {
|
|
19477
|
+
const runState = this.currentState();
|
|
19478
|
+
if (!runState || runState.finalized) {
|
|
19479
|
+
return;
|
|
19480
|
+
}
|
|
19481
|
+
try {
|
|
19482
|
+
const prepared = prepareAISDKAgentCallInput(
|
|
19483
|
+
event.arguments[0],
|
|
19484
|
+
event,
|
|
19485
|
+
runState.span
|
|
19486
|
+
);
|
|
19487
|
+
runState.span.log({
|
|
19488
|
+
input: extractThinkTaskInput(prepared.input),
|
|
19489
|
+
metadata: {
|
|
19490
|
+
...prepared.metadata,
|
|
19491
|
+
braintrust: {
|
|
19492
|
+
integration_name: "cloudflare-think",
|
|
19493
|
+
sdk_language: "typescript"
|
|
19494
|
+
}
|
|
19495
|
+
}
|
|
19496
|
+
});
|
|
19497
|
+
runState.inputLogged = true;
|
|
19498
|
+
runState.aiEvent = event;
|
|
19499
|
+
Reflect.set(event, THINK_STATE_ID, runState.span.spanId);
|
|
19500
|
+
} catch (error) {
|
|
19501
|
+
debugLogger.error(
|
|
19502
|
+
"Error preparing @cloudflare/think AI SDK tracing:",
|
|
19503
|
+
error
|
|
19504
|
+
);
|
|
19505
|
+
}
|
|
19506
|
+
}
|
|
19507
|
+
endAISDKStream(event) {
|
|
19508
|
+
const runState = this.stateForAISDKEvent(event);
|
|
19509
|
+
if (!runState || runState.finalized) {
|
|
19510
|
+
return;
|
|
19511
|
+
}
|
|
19512
|
+
const patched = patchAISDKStreamingResult({
|
|
19513
|
+
defaultDenyOutputPaths: DEFAULT_DENY_OUTPUT_PATHS,
|
|
19514
|
+
endEvent: event,
|
|
19515
|
+
forceTopLevelMetrics: true,
|
|
19516
|
+
onComplete: () => this.releaseState(runState),
|
|
19517
|
+
result: event.result,
|
|
19518
|
+
span: runState.span,
|
|
19519
|
+
startTime: runState.startTime,
|
|
19520
|
+
transformOutput: extractThinkTaskOutput
|
|
19521
|
+
});
|
|
19522
|
+
runState.aiResultPatched = patched;
|
|
19523
|
+
if (!patched) {
|
|
19524
|
+
this.finishState(runState, void 0, event.result);
|
|
19525
|
+
}
|
|
19526
|
+
}
|
|
19527
|
+
errorAISDKStream(event) {
|
|
19528
|
+
const runState = this.stateForAISDKEvent(event);
|
|
19529
|
+
if (runState) {
|
|
19530
|
+
this.finishState(runState, event.error);
|
|
19531
|
+
}
|
|
19532
|
+
}
|
|
19533
|
+
currentState() {
|
|
19534
|
+
const parentIds = _internalGetGlobalState()?.contextManager.getParentSpanIds()?.spanParents ?? [];
|
|
19535
|
+
for (const parentId of parentIds) {
|
|
19536
|
+
const state = this.statesBySpanId.get(parentId);
|
|
19537
|
+
if (state) {
|
|
19538
|
+
return state;
|
|
19539
|
+
}
|
|
19540
|
+
}
|
|
19541
|
+
return void 0;
|
|
19542
|
+
}
|
|
19543
|
+
stateForAISDKEvent(event) {
|
|
19544
|
+
const spanId = Reflect.get(event, THINK_STATE_ID);
|
|
19545
|
+
return typeof spanId === "string" ? this.statesBySpanId.get(spanId) : void 0;
|
|
19546
|
+
}
|
|
19547
|
+
finishState(state, error, output) {
|
|
19548
|
+
if (state.finalized) {
|
|
19549
|
+
return;
|
|
19550
|
+
}
|
|
19551
|
+
state.finalized = true;
|
|
19552
|
+
try {
|
|
19553
|
+
if (!state.inputLogged && state.fallbackInput !== void 0) {
|
|
19554
|
+
state.span.log({ input: state.fallbackInput });
|
|
19555
|
+
}
|
|
19556
|
+
if (error !== void 0) {
|
|
19557
|
+
state.span.log({ error });
|
|
19558
|
+
} else if (output !== void 0) {
|
|
19559
|
+
state.span.log({ output: extractThinkTaskOutput(output) });
|
|
19560
|
+
}
|
|
19561
|
+
finalizeAISDKChildTracing(state.aiEvent);
|
|
19562
|
+
state.span.end();
|
|
19563
|
+
} finally {
|
|
19564
|
+
this.releaseState(state);
|
|
19565
|
+
}
|
|
19566
|
+
}
|
|
19567
|
+
releaseState(state) {
|
|
19568
|
+
state.finalized = true;
|
|
19569
|
+
unregisterCloudflareThinkSpan(state.span);
|
|
19570
|
+
if (state.span.spanId) {
|
|
19571
|
+
this.statesBySpanId.delete(state.span.spanId);
|
|
19572
|
+
}
|
|
19573
|
+
}
|
|
19574
|
+
};
|
|
19575
|
+
function extractFallbackInput(messages) {
|
|
19576
|
+
if (!Array.isArray(messages) || messages.length === 0) {
|
|
19577
|
+
return void 0;
|
|
19578
|
+
}
|
|
19579
|
+
let latestUserIndex = -1;
|
|
19580
|
+
for (let index = messages.length - 1; index >= 0; index--) {
|
|
19581
|
+
if (messages[index]?.role === "user") {
|
|
19582
|
+
latestUserIndex = index;
|
|
19583
|
+
break;
|
|
19584
|
+
}
|
|
19585
|
+
}
|
|
19586
|
+
const selected = latestUserIndex >= 0 ? messages.slice(latestUserIndex) : [];
|
|
19587
|
+
return selected.map((message) => ({
|
|
19588
|
+
role: message.role,
|
|
19589
|
+
content: message.content ?? message.parts
|
|
19590
|
+
}));
|
|
19591
|
+
}
|
|
19592
|
+
function extractThinkTaskOutput(output) {
|
|
19593
|
+
if (!isObject(output)) {
|
|
19594
|
+
return output;
|
|
19595
|
+
}
|
|
19596
|
+
if (typeof output.text === "string") {
|
|
19597
|
+
return { role: "assistant", content: output.text };
|
|
19598
|
+
}
|
|
19599
|
+
if (output.object !== void 0) {
|
|
19600
|
+
return output.object;
|
|
19601
|
+
}
|
|
19602
|
+
return output;
|
|
19603
|
+
}
|
|
19604
|
+
function extractThinkTaskInput(input) {
|
|
19605
|
+
if (!isObject(input)) {
|
|
19606
|
+
return input;
|
|
19607
|
+
}
|
|
19608
|
+
const system = input.instructions ?? input.system;
|
|
19609
|
+
if (Array.isArray(input.messages)) {
|
|
19610
|
+
return system === void 0 ? input.messages : [{ role: "system", content: system }, ...input.messages];
|
|
19611
|
+
}
|
|
19612
|
+
if (Array.isArray(input.prompt)) {
|
|
19613
|
+
return system === void 0 ? input.prompt : [{ role: "system", content: system }, ...input.prompt];
|
|
19614
|
+
}
|
|
19615
|
+
if (typeof input.prompt === "string") {
|
|
19616
|
+
const messages = [{ role: "user", content: input.prompt }];
|
|
19617
|
+
return system === void 0 ? messages : [{ role: "system", content: system }, ...messages];
|
|
19618
|
+
}
|
|
19619
|
+
return input;
|
|
19620
|
+
}
|
|
19621
|
+
|
|
18671
19622
|
// src/instrumentation/plugins/cursor-sdk-channels.ts
|
|
18672
19623
|
var cursorSDKChannels = defineChannels(
|
|
18673
19624
|
"@cursor/sdk",
|
|
@@ -24433,6 +25384,470 @@ function aggregateMistralStreamChunks(chunks) {
|
|
|
24433
25384
|
};
|
|
24434
25385
|
}
|
|
24435
25386
|
|
|
25387
|
+
// src/instrumentation/plugins/ollama-channels.ts
|
|
25388
|
+
var ollamaChannels = defineChannels(
|
|
25389
|
+
"ollama",
|
|
25390
|
+
{
|
|
25391
|
+
chat: channel({
|
|
25392
|
+
channelName: "chat",
|
|
25393
|
+
kind: "async"
|
|
25394
|
+
}),
|
|
25395
|
+
generate: channel({
|
|
25396
|
+
channelName: "generate",
|
|
25397
|
+
kind: "async"
|
|
25398
|
+
}),
|
|
25399
|
+
embed: channel({
|
|
25400
|
+
channelName: "embed",
|
|
25401
|
+
kind: "async"
|
|
25402
|
+
})
|
|
25403
|
+
},
|
|
25404
|
+
{ instrumentationName: INSTRUMENTATION_NAMES.OLLAMA }
|
|
25405
|
+
);
|
|
25406
|
+
|
|
25407
|
+
// src/instrumentation/plugins/ollama-plugin.ts
|
|
25408
|
+
var OllamaPlugin = class extends BasePlugin {
|
|
25409
|
+
onEnable() {
|
|
25410
|
+
this.unsubscribers.push(
|
|
25411
|
+
traceStreamingChannel(ollamaChannels.chat, {
|
|
25412
|
+
name: "ollama.chat",
|
|
25413
|
+
type: "llm" /* LLM */,
|
|
25414
|
+
extractInput: extractOllamaChatInput,
|
|
25415
|
+
extractOutput: (result, event) => extractOllamaChatOutput(
|
|
25416
|
+
result,
|
|
25417
|
+
countOllamaToolCalls(event?.arguments?.[0]?.messages)
|
|
25418
|
+
),
|
|
25419
|
+
extractMetadata: extractOllamaResponseMetadata,
|
|
25420
|
+
extractMetrics: extractOllamaMetrics,
|
|
25421
|
+
aggregateChunks: aggregateOllamaChatChunks
|
|
25422
|
+
}),
|
|
25423
|
+
traceStreamingChannel(ollamaChannels.generate, {
|
|
25424
|
+
name: "ollama.generate",
|
|
25425
|
+
type: "llm" /* LLM */,
|
|
25426
|
+
extractInput: extractOllamaGenerateInput,
|
|
25427
|
+
extractOutput: extractOllamaGenerateOutput,
|
|
25428
|
+
extractMetadata: extractOllamaResponseMetadata,
|
|
25429
|
+
extractMetrics: extractOllamaMetrics,
|
|
25430
|
+
aggregateChunks: aggregateOllamaGenerateChunks
|
|
25431
|
+
}),
|
|
25432
|
+
traceAsyncChannel(ollamaChannels.embed, {
|
|
25433
|
+
name: "ollama.embed",
|
|
25434
|
+
type: "llm" /* LLM */,
|
|
25435
|
+
extractInput: extractOllamaEmbedInput,
|
|
25436
|
+
extractOutput: extractOllamaEmbedOutput,
|
|
25437
|
+
extractMetadata: extractOllamaResponseMetadata,
|
|
25438
|
+
extractMetrics: extractOllamaMetrics
|
|
25439
|
+
})
|
|
25440
|
+
);
|
|
25441
|
+
}
|
|
25442
|
+
onDisable() {
|
|
25443
|
+
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
25444
|
+
}
|
|
25445
|
+
};
|
|
25446
|
+
function isNonNegativeNumber(value) {
|
|
25447
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0;
|
|
25448
|
+
}
|
|
25449
|
+
function normalizeFinishReason(response, hasToolCalls = false) {
|
|
25450
|
+
if (hasToolCalls) {
|
|
25451
|
+
return "tool_calls";
|
|
25452
|
+
}
|
|
25453
|
+
return response?.done_reason || "stop";
|
|
25454
|
+
}
|
|
25455
|
+
function stringifyArguments(value) {
|
|
25456
|
+
if (typeof value === "string") {
|
|
25457
|
+
return value;
|
|
25458
|
+
}
|
|
25459
|
+
try {
|
|
25460
|
+
return JSON.stringify(value ?? {});
|
|
25461
|
+
} catch {
|
|
25462
|
+
return String(value);
|
|
25463
|
+
}
|
|
25464
|
+
}
|
|
25465
|
+
function syntheticToolCallId(name, index) {
|
|
25466
|
+
const normalizedName = name.replace(/[^a-zA-Z0-9_-]/g, "_") || "tool";
|
|
25467
|
+
return `ollama_call_${normalizedName}_${index}`;
|
|
25468
|
+
}
|
|
25469
|
+
function normalizeToolCall(toolCall, index) {
|
|
25470
|
+
const name = toolCall.function?.name;
|
|
25471
|
+
if (typeof name !== "string" || name.length === 0) {
|
|
25472
|
+
return void 0;
|
|
25473
|
+
}
|
|
25474
|
+
return {
|
|
25475
|
+
id: typeof toolCall.id === "string" && toolCall.id.length > 0 ? toolCall.id : syntheticToolCallId(name, index),
|
|
25476
|
+
type: "function",
|
|
25477
|
+
function: {
|
|
25478
|
+
name,
|
|
25479
|
+
arguments: stringifyArguments(toolCall.function?.arguments)
|
|
25480
|
+
}
|
|
25481
|
+
};
|
|
25482
|
+
}
|
|
25483
|
+
function normalizeToolCalls(toolCalls, syntheticIdOffset = 0) {
|
|
25484
|
+
if (!Array.isArray(toolCalls)) {
|
|
25485
|
+
return [];
|
|
25486
|
+
}
|
|
25487
|
+
return toolCalls.flatMap((toolCall, index) => {
|
|
25488
|
+
const normalized = normalizeToolCall(toolCall, syntheticIdOffset + index);
|
|
25489
|
+
return normalized ? [normalized] : [];
|
|
25490
|
+
});
|
|
25491
|
+
}
|
|
25492
|
+
function countOllamaToolCalls(messages) {
|
|
25493
|
+
if (!Array.isArray(messages)) {
|
|
25494
|
+
return 0;
|
|
25495
|
+
}
|
|
25496
|
+
return messages.reduce(
|
|
25497
|
+
(count, message) => count + (isObject(message) && Array.isArray(message.tool_calls) ? message.tool_calls.length : 0),
|
|
25498
|
+
0
|
|
25499
|
+
);
|
|
25500
|
+
}
|
|
25501
|
+
function imageBytes(value) {
|
|
25502
|
+
if (value instanceof Uint8Array) {
|
|
25503
|
+
return value;
|
|
25504
|
+
}
|
|
25505
|
+
if (value instanceof ArrayBuffer) {
|
|
25506
|
+
return new Uint8Array(value);
|
|
25507
|
+
}
|
|
25508
|
+
if (typeof value !== "string" || value.startsWith("data:")) {
|
|
25509
|
+
return void 0;
|
|
25510
|
+
}
|
|
25511
|
+
try {
|
|
25512
|
+
const decoded = atob(value.slice(0, 24));
|
|
25513
|
+
return Uint8Array.from(decoded, (character) => character.charCodeAt(0));
|
|
25514
|
+
} catch {
|
|
25515
|
+
return void 0;
|
|
25516
|
+
}
|
|
25517
|
+
}
|
|
25518
|
+
function inferImageMediaType(value) {
|
|
25519
|
+
if (typeof value === "string") {
|
|
25520
|
+
const dataUrlType = value.match(/^data:(image\/[^;]+);base64,/i)?.[1];
|
|
25521
|
+
if (dataUrlType) {
|
|
25522
|
+
return dataUrlType;
|
|
25523
|
+
}
|
|
25524
|
+
}
|
|
25525
|
+
const bytes = imageBytes(value);
|
|
25526
|
+
if (!bytes) {
|
|
25527
|
+
return void 0;
|
|
25528
|
+
}
|
|
25529
|
+
if (bytes[0] === 137 && bytes[1] === 80 && bytes[2] === 78 && bytes[3] === 71) {
|
|
25530
|
+
return "image/png";
|
|
25531
|
+
}
|
|
25532
|
+
if (bytes[0] === 255 && bytes[1] === 216 && bytes[2] === 255) {
|
|
25533
|
+
return "image/jpeg";
|
|
25534
|
+
}
|
|
25535
|
+
const signature = String.fromCharCode(...bytes.slice(0, 12));
|
|
25536
|
+
if (signature.startsWith("GIF87a") || signature.startsWith("GIF89a")) {
|
|
25537
|
+
return "image/gif";
|
|
25538
|
+
}
|
|
25539
|
+
if (signature.startsWith("RIFF") && signature.slice(8, 12) === "WEBP") {
|
|
25540
|
+
return "image/webp";
|
|
25541
|
+
}
|
|
25542
|
+
return void 0;
|
|
25543
|
+
}
|
|
25544
|
+
function normalizeTextAndImages(content, images) {
|
|
25545
|
+
if (!images || images.length === 0) {
|
|
25546
|
+
return { content };
|
|
25547
|
+
}
|
|
25548
|
+
const imageParts = [];
|
|
25549
|
+
const unrecognizedImages = [];
|
|
25550
|
+
for (const image of images) {
|
|
25551
|
+
let localImagePath;
|
|
25552
|
+
let localPathMediaType;
|
|
25553
|
+
if (typeof image === "string" && !/^data:/i.test(image) && !/^https?:\/\//i.test(image)) {
|
|
25554
|
+
const extension = image.match(/\.([a-z0-9]+)$/i)?.[1]?.toLowerCase();
|
|
25555
|
+
const extensionMediaType = {
|
|
25556
|
+
png: "image/png",
|
|
25557
|
+
jpg: "image/jpeg",
|
|
25558
|
+
jpeg: "image/jpeg",
|
|
25559
|
+
gif: "image/gif",
|
|
25560
|
+
webp: "image/webp"
|
|
25561
|
+
}[extension ?? ""];
|
|
25562
|
+
if (extensionMediaType && isomorph_default.statSync) {
|
|
25563
|
+
try {
|
|
25564
|
+
if (isomorph_default.statSync(image).isFile()) {
|
|
25565
|
+
localImagePath = image;
|
|
25566
|
+
localPathMediaType = extensionMediaType;
|
|
25567
|
+
}
|
|
25568
|
+
} catch {
|
|
25569
|
+
}
|
|
25570
|
+
}
|
|
25571
|
+
}
|
|
25572
|
+
const mediaType = localPathMediaType ?? inferImageMediaType(image);
|
|
25573
|
+
if (!mediaType) {
|
|
25574
|
+
unrecognizedImages.push(image);
|
|
25575
|
+
continue;
|
|
25576
|
+
}
|
|
25577
|
+
const processedImage = localImagePath ? new Attachment({
|
|
25578
|
+
data: localImagePath,
|
|
25579
|
+
filename: localImagePath.split(/[\\/]/).at(-1) ?? "image",
|
|
25580
|
+
contentType: mediaType
|
|
25581
|
+
}) : processInputAttachments({
|
|
25582
|
+
type: "image",
|
|
25583
|
+
image,
|
|
25584
|
+
mediaType
|
|
25585
|
+
}).image;
|
|
25586
|
+
imageParts.push({
|
|
25587
|
+
type: "image_url",
|
|
25588
|
+
image_url: { url: processedImage }
|
|
25589
|
+
});
|
|
25590
|
+
}
|
|
25591
|
+
return {
|
|
25592
|
+
content: imageParts.length > 0 ? [...content ? [{ type: "text", text: content }] : [], ...imageParts] : content,
|
|
25593
|
+
...unrecognizedImages.length > 0 ? { unrecognizedImages } : {}
|
|
25594
|
+
};
|
|
25595
|
+
}
|
|
25596
|
+
function normalizeMessage(message, toolCallId, syntheticToolCallIdOffset = 0) {
|
|
25597
|
+
if (typeof message.role !== "string") {
|
|
25598
|
+
return void 0;
|
|
25599
|
+
}
|
|
25600
|
+
const toolCalls = normalizeToolCalls(
|
|
25601
|
+
message.tool_calls,
|
|
25602
|
+
syntheticToolCallIdOffset
|
|
25603
|
+
);
|
|
25604
|
+
if (message.role === "tool") {
|
|
25605
|
+
const toolName = typeof message.tool_name === "string" && message.tool_name.length > 0 ? message.tool_name : "tool";
|
|
25606
|
+
return {
|
|
25607
|
+
role: "tool",
|
|
25608
|
+
tool_call_id: toolCallId ?? syntheticToolCallId(toolName, 0),
|
|
25609
|
+
content: typeof message.content === "string" ? message.content : ""
|
|
25610
|
+
};
|
|
25611
|
+
}
|
|
25612
|
+
const normalizedContent = normalizeTextAndImages(
|
|
25613
|
+
typeof message.content === "string" ? message.content || (toolCalls.length > 0 ? null : "") : toolCalls.length > 0 ? null : "",
|
|
25614
|
+
message.images
|
|
25615
|
+
);
|
|
25616
|
+
return {
|
|
25617
|
+
role: message.role,
|
|
25618
|
+
content: normalizedContent.content,
|
|
25619
|
+
...typeof message.thinking === "string" && message.thinking.length > 0 ? { reasoning: message.thinking } : {},
|
|
25620
|
+
...toolCalls.length > 0 ? { tool_calls: toolCalls } : {},
|
|
25621
|
+
...normalizedContent.unrecognizedImages ? { images: normalizedContent.unrecognizedImages } : {}
|
|
25622
|
+
};
|
|
25623
|
+
}
|
|
25624
|
+
function normalizeMessages(messages) {
|
|
25625
|
+
if (!Array.isArray(messages)) {
|
|
25626
|
+
return [];
|
|
25627
|
+
}
|
|
25628
|
+
const pendingToolCallIds = /* @__PURE__ */ new Map();
|
|
25629
|
+
let syntheticToolCallIdOffset = 0;
|
|
25630
|
+
return messages.flatMap((message) => {
|
|
25631
|
+
if (!isObject(message)) {
|
|
25632
|
+
return [];
|
|
25633
|
+
}
|
|
25634
|
+
const ollamaMessage = message;
|
|
25635
|
+
let toolCallId;
|
|
25636
|
+
if (ollamaMessage.role === "tool") {
|
|
25637
|
+
const toolName = ollamaMessage.tool_name;
|
|
25638
|
+
if (typeof toolName === "string") {
|
|
25639
|
+
toolCallId = pendingToolCallIds.get(toolName)?.shift();
|
|
25640
|
+
}
|
|
25641
|
+
}
|
|
25642
|
+
const normalized = normalizeMessage(
|
|
25643
|
+
ollamaMessage,
|
|
25644
|
+
toolCallId,
|
|
25645
|
+
syntheticToolCallIdOffset
|
|
25646
|
+
);
|
|
25647
|
+
if (Array.isArray(ollamaMessage.tool_calls)) {
|
|
25648
|
+
syntheticToolCallIdOffset += ollamaMessage.tool_calls.length;
|
|
25649
|
+
}
|
|
25650
|
+
if (ollamaMessage.role === "assistant" && normalized) {
|
|
25651
|
+
const toolCalls = Array.isArray(normalized.tool_calls) ? normalized.tool_calls : [];
|
|
25652
|
+
for (const toolCall of toolCalls) {
|
|
25653
|
+
if (!isObject(toolCall) || !isObject(toolCall.function)) {
|
|
25654
|
+
continue;
|
|
25655
|
+
}
|
|
25656
|
+
const name = toolCall.function.name;
|
|
25657
|
+
const id = toolCall.id;
|
|
25658
|
+
if (typeof name === "string" && typeof id === "string") {
|
|
25659
|
+
const ids = pendingToolCallIds.get(name) ?? [];
|
|
25660
|
+
ids.push(id);
|
|
25661
|
+
pendingToolCallIds.set(name, ids);
|
|
25662
|
+
}
|
|
25663
|
+
}
|
|
25664
|
+
}
|
|
25665
|
+
return normalized ? [normalized] : [];
|
|
25666
|
+
});
|
|
25667
|
+
}
|
|
25668
|
+
function normalizeToolDefinition(tool) {
|
|
25669
|
+
const fn = tool.function;
|
|
25670
|
+
if (!fn || typeof fn.name !== "string" || fn.name.length === 0) {
|
|
25671
|
+
return void 0;
|
|
25672
|
+
}
|
|
25673
|
+
return {
|
|
25674
|
+
type: "function",
|
|
25675
|
+
function: {
|
|
25676
|
+
name: fn.name,
|
|
25677
|
+
...typeof fn.description === "string" ? { description: fn.description } : {},
|
|
25678
|
+
...isObject(fn.parameters) ? { parameters: fn.parameters } : {}
|
|
25679
|
+
}
|
|
25680
|
+
};
|
|
25681
|
+
}
|
|
25682
|
+
function extractToolsMetadata(tools) {
|
|
25683
|
+
if (!Array.isArray(tools)) {
|
|
25684
|
+
return {};
|
|
25685
|
+
}
|
|
25686
|
+
const normalized = tools.flatMap((tool) => {
|
|
25687
|
+
if (!isObject(tool)) {
|
|
25688
|
+
return [];
|
|
25689
|
+
}
|
|
25690
|
+
const definition = normalizeToolDefinition(tool);
|
|
25691
|
+
return definition ? [definition] : [];
|
|
25692
|
+
});
|
|
25693
|
+
return normalized.length > 0 ? { tools: normalized } : {};
|
|
25694
|
+
}
|
|
25695
|
+
function extractOptionsMetadata(options) {
|
|
25696
|
+
if (!isObject(options)) {
|
|
25697
|
+
return {};
|
|
25698
|
+
}
|
|
25699
|
+
const metadata = {};
|
|
25700
|
+
const mappings = [
|
|
25701
|
+
["temperature", "temperature"],
|
|
25702
|
+
["top_p", "top_p"],
|
|
25703
|
+
["num_predict", "max_tokens"],
|
|
25704
|
+
["frequency_penalty", "frequency_penalty"],
|
|
25705
|
+
["presence_penalty", "presence_penalty"],
|
|
25706
|
+
["stop", "stop"]
|
|
25707
|
+
];
|
|
25708
|
+
for (const [source, target] of mappings) {
|
|
25709
|
+
if (options[source] !== void 0) {
|
|
25710
|
+
metadata[target] = options[source];
|
|
25711
|
+
}
|
|
25712
|
+
}
|
|
25713
|
+
return metadata;
|
|
25714
|
+
}
|
|
25715
|
+
function extractRequestMetadata(request) {
|
|
25716
|
+
return {
|
|
25717
|
+
provider: "ollama",
|
|
25718
|
+
...typeof request?.model === "string" ? { model: request.model } : {},
|
|
25719
|
+
...extractOptionsMetadata(request?.options),
|
|
25720
|
+
...request?.format !== void 0 ? { response_format: request.format } : {}
|
|
25721
|
+
};
|
|
25722
|
+
}
|
|
25723
|
+
function extractOllamaChatInput([request]) {
|
|
25724
|
+
return {
|
|
25725
|
+
input: normalizeMessages(request.messages),
|
|
25726
|
+
metadata: {
|
|
25727
|
+
...extractRequestMetadata(request),
|
|
25728
|
+
...extractToolsMetadata(request.tools)
|
|
25729
|
+
}
|
|
25730
|
+
};
|
|
25731
|
+
}
|
|
25732
|
+
function extractOllamaGenerateInput([request]) {
|
|
25733
|
+
const normalizedPrompt = normalizeTextAndImages(
|
|
25734
|
+
typeof request.prompt === "string" ? request.prompt : "",
|
|
25735
|
+
Array.isArray(request.images) ? request.images : void 0
|
|
25736
|
+
);
|
|
25737
|
+
const input = [
|
|
25738
|
+
...typeof request.system === "string" ? [{ role: "system", content: request.system }] : [],
|
|
25739
|
+
{
|
|
25740
|
+
role: "user",
|
|
25741
|
+
content: normalizedPrompt.content,
|
|
25742
|
+
...typeof request.suffix === "string" ? { suffix: request.suffix } : {},
|
|
25743
|
+
...normalizedPrompt.unrecognizedImages ? { images: normalizedPrompt.unrecognizedImages } : {}
|
|
25744
|
+
}
|
|
25745
|
+
];
|
|
25746
|
+
return {
|
|
25747
|
+
input,
|
|
25748
|
+
metadata: extractRequestMetadata(request)
|
|
25749
|
+
};
|
|
25750
|
+
}
|
|
25751
|
+
function extractOllamaEmbedInput([request]) {
|
|
25752
|
+
return {
|
|
25753
|
+
input: request.input,
|
|
25754
|
+
metadata: extractRequestMetadata(request)
|
|
25755
|
+
};
|
|
25756
|
+
}
|
|
25757
|
+
function extractOllamaChatOutput(result, syntheticToolCallIdOffset = 0) {
|
|
25758
|
+
if (!isObject(result) || !isObject(result.message)) {
|
|
25759
|
+
return void 0;
|
|
25760
|
+
}
|
|
25761
|
+
const message = normalizeMessage(
|
|
25762
|
+
result.message,
|
|
25763
|
+
void 0,
|
|
25764
|
+
syntheticToolCallIdOffset
|
|
25765
|
+
);
|
|
25766
|
+
if (!message) {
|
|
25767
|
+
return void 0;
|
|
25768
|
+
}
|
|
25769
|
+
const toolCalls = Array.isArray(message.tool_calls) ? message.tool_calls : [];
|
|
25770
|
+
return [
|
|
25771
|
+
{
|
|
25772
|
+
index: 0,
|
|
25773
|
+
finish_reason: normalizeFinishReason(result, toolCalls.length > 0),
|
|
25774
|
+
message
|
|
25775
|
+
}
|
|
25776
|
+
];
|
|
25777
|
+
}
|
|
25778
|
+
function extractOllamaGenerateOutput(result) {
|
|
25779
|
+
if (!isObject(result) || typeof result.response !== "string") {
|
|
25780
|
+
return void 0;
|
|
25781
|
+
}
|
|
25782
|
+
return [
|
|
25783
|
+
{
|
|
25784
|
+
index: 0,
|
|
25785
|
+
finish_reason: normalizeFinishReason(result),
|
|
25786
|
+
message: {
|
|
25787
|
+
role: "assistant",
|
|
25788
|
+
content: result.response,
|
|
25789
|
+
...typeof result.thinking === "string" && result.thinking.length > 0 ? { reasoning: result.thinking } : {}
|
|
25790
|
+
}
|
|
25791
|
+
}
|
|
25792
|
+
];
|
|
25793
|
+
}
|
|
25794
|
+
function extractOllamaEmbedOutput(result) {
|
|
25795
|
+
const embedding = Array.isArray(result?.embeddings) ? result.embeddings[0] : void 0;
|
|
25796
|
+
return Array.isArray(embedding) ? { embedding_length: embedding.length } : void 0;
|
|
25797
|
+
}
|
|
25798
|
+
function extractOllamaResponseMetadata(result) {
|
|
25799
|
+
return typeof result?.model === "string" ? { model: result.model } : void 0;
|
|
25800
|
+
}
|
|
25801
|
+
function extractOllamaMetrics(result) {
|
|
25802
|
+
const metrics = {};
|
|
25803
|
+
const promptTokens = result?.prompt_eval_count;
|
|
25804
|
+
const completionTokens = result?.eval_count;
|
|
25805
|
+
if (isNonNegativeNumber(promptTokens)) {
|
|
25806
|
+
metrics.prompt_tokens = promptTokens;
|
|
25807
|
+
}
|
|
25808
|
+
if (isNonNegativeNumber(completionTokens)) {
|
|
25809
|
+
metrics.completion_tokens = completionTokens;
|
|
25810
|
+
}
|
|
25811
|
+
if (isNonNegativeNumber(promptTokens) || isNonNegativeNumber(completionTokens)) {
|
|
25812
|
+
metrics.tokens = (isNonNegativeNumber(promptTokens) ? promptTokens : 0) + (isNonNegativeNumber(completionTokens) ? completionTokens : 0);
|
|
25813
|
+
}
|
|
25814
|
+
return metrics;
|
|
25815
|
+
}
|
|
25816
|
+
function aggregateOllamaChatChunks(chunks, _result, event, _startTime) {
|
|
25817
|
+
const last = chunks.at(-1);
|
|
25818
|
+
const message = {
|
|
25819
|
+
role: "assistant",
|
|
25820
|
+
content: chunks.map((chunk) => chunk.message?.content ?? "").join(""),
|
|
25821
|
+
thinking: chunks.map((chunk) => chunk.message?.thinking ?? "").join(""),
|
|
25822
|
+
tool_calls: chunks.flatMap((chunk) => chunk.message?.tool_calls ?? [])
|
|
25823
|
+
};
|
|
25824
|
+
const response = {
|
|
25825
|
+
...last,
|
|
25826
|
+
message
|
|
25827
|
+
};
|
|
25828
|
+
return {
|
|
25829
|
+
output: extractOllamaChatOutput(
|
|
25830
|
+
response,
|
|
25831
|
+
countOllamaToolCalls(event?.arguments?.[0]?.messages)
|
|
25832
|
+
),
|
|
25833
|
+
metrics: extractOllamaMetrics(last ?? {}),
|
|
25834
|
+
metadata: extractOllamaResponseMetadata(last ?? {})
|
|
25835
|
+
};
|
|
25836
|
+
}
|
|
25837
|
+
function aggregateOllamaGenerateChunks(chunks, _result, _event, _startTime) {
|
|
25838
|
+
const last = chunks.at(-1);
|
|
25839
|
+
const response = {
|
|
25840
|
+
...last,
|
|
25841
|
+
response: chunks.map((chunk) => chunk.response ?? "").join(""),
|
|
25842
|
+
thinking: chunks.map((chunk) => chunk.thinking ?? "").join("")
|
|
25843
|
+
};
|
|
25844
|
+
return {
|
|
25845
|
+
output: extractOllamaGenerateOutput(response),
|
|
25846
|
+
metrics: extractOllamaMetrics(last ?? {}),
|
|
25847
|
+
metadata: extractOllamaResponseMetadata(last ?? {})
|
|
25848
|
+
};
|
|
25849
|
+
}
|
|
25850
|
+
|
|
24436
25851
|
// src/instrumentation/plugins/google-adk-channels.ts
|
|
24437
25852
|
var googleADKChannels = defineChannels(
|
|
24438
25853
|
"@google/adk",
|
|
@@ -28186,7 +29601,7 @@ var FlueObserveBridge = class {
|
|
|
28186
29601
|
return;
|
|
28187
29602
|
}
|
|
28188
29603
|
const state = this.operationsById.get(event.operationId) ?? this.startSyntheticOperation(event);
|
|
28189
|
-
const output = operationOutput(event);
|
|
29604
|
+
const output = operationOutput(event) ?? outputFromAgentTurn(state.latestAgentOutput);
|
|
28190
29605
|
const metadata = {
|
|
28191
29606
|
...state.metadata,
|
|
28192
29607
|
...extractEventMetadata(event),
|
|
@@ -28195,7 +29610,7 @@ var FlueObserveBridge = class {
|
|
|
28195
29610
|
};
|
|
28196
29611
|
this.finishPendingChildrenForOperation(event, output);
|
|
28197
29612
|
safeLog3(state.span, {
|
|
28198
|
-
...event.isError ? { error: toLoggedError(event.error) } : {},
|
|
29613
|
+
...event.isError ? { error: toLoggedError(event.errorInfo ?? event.error) } : {},
|
|
28199
29614
|
metadata,
|
|
28200
29615
|
metrics: durationMetrics2(event.durationMs),
|
|
28201
29616
|
output
|
|
@@ -28226,7 +29641,7 @@ var FlueObserveBridge = class {
|
|
|
28226
29641
|
};
|
|
28227
29642
|
const parent = this.parentSpanForTurn(event);
|
|
28228
29643
|
const span = startFlueSpan(parent, {
|
|
28229
|
-
name:
|
|
29644
|
+
name: "flue.turn",
|
|
28230
29645
|
spanAttributes: { type: "llm" /* LLM */ },
|
|
28231
29646
|
startTime: eventTime(event.timestamp),
|
|
28232
29647
|
event: {
|
|
@@ -28270,6 +29685,12 @@ var FlueObserveBridge = class {
|
|
|
28270
29685
|
},
|
|
28271
29686
|
output
|
|
28272
29687
|
});
|
|
29688
|
+
if (event.purpose === "agent" && event.operationId) {
|
|
29689
|
+
const operation = this.operationsById.get(event.operationId);
|
|
29690
|
+
if (operation) {
|
|
29691
|
+
operation.latestAgentOutput = output;
|
|
29692
|
+
}
|
|
29693
|
+
}
|
|
28273
29694
|
safeEnd(state.span, eventTime(event.timestamp));
|
|
28274
29695
|
this.turnsByKey.delete(key);
|
|
28275
29696
|
}
|
|
@@ -28349,7 +29770,7 @@ var FlueObserveBridge = class {
|
|
|
28349
29770
|
return;
|
|
28350
29771
|
}
|
|
28351
29772
|
safeLog3(state.span, {
|
|
28352
|
-
...event.isError ? { error: toLoggedError(event.result) } : {},
|
|
29773
|
+
...event.isError ? { error: toLoggedError(event.errorInfo ?? event.result) } : {},
|
|
28353
29774
|
metadata: {
|
|
28354
29775
|
...state.metadata,
|
|
28355
29776
|
...extractEventMetadata(event),
|
|
@@ -28395,6 +29816,7 @@ var FlueObserveBridge = class {
|
|
|
28395
29816
|
...event.usage ? { "flue.usage": event.usage } : {}
|
|
28396
29817
|
};
|
|
28397
29818
|
safeLog3(state.span, {
|
|
29819
|
+
...event.isError ? { error: toLoggedError(event.errorInfo ?? event.error) } : {},
|
|
28398
29820
|
metadata,
|
|
28399
29821
|
metrics: {
|
|
28400
29822
|
...durationMetrics2(event.durationMs),
|
|
@@ -28499,7 +29921,7 @@ var FlueObserveBridge = class {
|
|
|
28499
29921
|
...event.purpose ? { "flue.turn_purpose": event.purpose } : {}
|
|
28500
29922
|
};
|
|
28501
29923
|
const span = startFlueSpan(this.parentSpanForEvent(event), {
|
|
28502
|
-
name:
|
|
29924
|
+
name: "flue.turn",
|
|
28503
29925
|
spanAttributes: { type: "llm" /* LLM */ },
|
|
28504
29926
|
startTime: eventTime(event.timestamp),
|
|
28505
29927
|
event: { metadata }
|
|
@@ -28631,7 +30053,10 @@ function extractEventMetadata(event, ctx) {
|
|
|
28631
30053
|
return {
|
|
28632
30054
|
...event.runId ? { "flue.run_id": event.runId } : {},
|
|
28633
30055
|
...event.instanceId ? { "flue.instance_id": event.instanceId } : {},
|
|
30056
|
+
...event.submissionId ? { "flue.submission_id": event.submissionId } : {},
|
|
28634
30057
|
...event.dispatchId ? { "flue.dispatch_id": event.dispatchId } : {},
|
|
30058
|
+
...event.agentName ? { "flue.agent_name": event.agentName } : {},
|
|
30059
|
+
...event.conversationId ? { "flue.conversation_id": event.conversationId } : {},
|
|
28635
30060
|
...typeof event.eventIndex === "number" ? { "flue.event_index": event.eventIndex } : {},
|
|
28636
30061
|
...event.session ? { "flue.session": event.session } : {},
|
|
28637
30062
|
...event.parentSession ? { "flue.parent_session": event.parentSession } : {},
|
|
@@ -28660,7 +30085,7 @@ function flueTurnRequestInput(event) {
|
|
|
28660
30085
|
return event.request?.input ?? event.input;
|
|
28661
30086
|
}
|
|
28662
30087
|
function flueTurnRequestModel(event) {
|
|
28663
|
-
return event.request?.model ?? event.model;
|
|
30088
|
+
return event.request?.requestedModel ?? event.request?.model ?? event.model;
|
|
28664
30089
|
}
|
|
28665
30090
|
function flueTurnRequestProvider(event) {
|
|
28666
30091
|
return event.request?.providerName ?? event.provider ?? event.request?.providerId;
|
|
@@ -28669,10 +30094,10 @@ function flueTurnRequestApi(event) {
|
|
|
28669
30094
|
return event.request?.api ?? event.api;
|
|
28670
30095
|
}
|
|
28671
30096
|
function flueTurnRequestReasoning(event) {
|
|
28672
|
-
return event.request?.reasoning ?? event.reasoning;
|
|
30097
|
+
return event.request?.reasoningLevel ?? event.request?.reasoning ?? event.reasoning;
|
|
28673
30098
|
}
|
|
28674
30099
|
function flueTurnModel(event) {
|
|
28675
|
-
return event.request?.model ?? event.model;
|
|
30100
|
+
return event.response?.responseModel ?? event.request?.requestedModel ?? event.request?.model ?? event.model;
|
|
28676
30101
|
}
|
|
28677
30102
|
function flueTurnProvider(event) {
|
|
28678
30103
|
return event.request?.providerName ?? event.provider ?? event.request?.providerId;
|
|
@@ -28687,7 +30112,7 @@ function flueTurnOutput(event) {
|
|
|
28687
30112
|
return event.response?.output ?? event.output;
|
|
28688
30113
|
}
|
|
28689
30114
|
function flueTurnStopReason(event) {
|
|
28690
|
-
return event.response?.stopReason ?? event.stopReason;
|
|
30115
|
+
return event.response?.finishReason ?? event.response?.stopReason ?? event.stopReason;
|
|
28691
30116
|
}
|
|
28692
30117
|
function flueTurnError(event) {
|
|
28693
30118
|
return event.response?.error ?? event.response?.errorInfo?.message ?? event.error;
|
|
@@ -28702,6 +30127,9 @@ function flueToolInput(event) {
|
|
|
28702
30127
|
return event.input;
|
|
28703
30128
|
}
|
|
28704
30129
|
function flueToolOutput(event) {
|
|
30130
|
+
if (Object.hasOwn(event, "effectiveResult")) {
|
|
30131
|
+
return event.effectiveResult;
|
|
30132
|
+
}
|
|
28705
30133
|
return event.output !== void 0 ? event.output : event.result;
|
|
28706
30134
|
}
|
|
28707
30135
|
function flueToolError(event) {
|
|
@@ -28709,10 +30137,36 @@ function flueToolError(event) {
|
|
|
28709
30137
|
}
|
|
28710
30138
|
function operationOutput(event) {
|
|
28711
30139
|
if (event.operationKind === "prompt" || event.operationKind === "skill") {
|
|
28712
|
-
return llmResultFromOperationResult(event.result);
|
|
30140
|
+
return outputFromAgentInvocation(event.agentOutput) ?? llmResultFromOperationResult(event.result);
|
|
28713
30141
|
}
|
|
28714
30142
|
return event.result ?? (event.operationKind === "compact" ? { completed: true } : void 0);
|
|
28715
30143
|
}
|
|
30144
|
+
function outputFromAgentInvocation(output) {
|
|
30145
|
+
if (output?.type === "text") {
|
|
30146
|
+
return output.text;
|
|
30147
|
+
}
|
|
30148
|
+
if (output?.type === "data") {
|
|
30149
|
+
return output.data;
|
|
30150
|
+
}
|
|
30151
|
+
return void 0;
|
|
30152
|
+
}
|
|
30153
|
+
function outputFromAgentTurn(output) {
|
|
30154
|
+
if (!isObjectLike(output)) {
|
|
30155
|
+
return output;
|
|
30156
|
+
}
|
|
30157
|
+
const content = Reflect.get(output, "content");
|
|
30158
|
+
if (!Array.isArray(content)) {
|
|
30159
|
+
return output;
|
|
30160
|
+
}
|
|
30161
|
+
const text = content.flatMap((part) => {
|
|
30162
|
+
if (!isObjectLike(part) || Reflect.get(part, "type") !== "text") {
|
|
30163
|
+
return [];
|
|
30164
|
+
}
|
|
30165
|
+
const value = Reflect.get(part, "text");
|
|
30166
|
+
return typeof value === "string" ? [value] : [];
|
|
30167
|
+
});
|
|
30168
|
+
return text.length > 0 ? text.join("") : output;
|
|
30169
|
+
}
|
|
28716
30170
|
function llmResultFromOperationResult(result) {
|
|
28717
30171
|
if (!isObjectLike(result)) {
|
|
28718
30172
|
return result;
|
|
@@ -28811,7 +30265,7 @@ function safeEnd(span, endTime) {
|
|
|
28811
30265
|
}
|
|
28812
30266
|
}
|
|
28813
30267
|
function logInstrumentationError3(label, error) {
|
|
28814
|
-
|
|
30268
|
+
debugLogger.debug(`Error in ${label} instrumentation:`, error);
|
|
28815
30269
|
}
|
|
28816
30270
|
|
|
28817
30271
|
// src/wrappers/langchain/callback-handler.ts
|
|
@@ -29740,12 +31194,13 @@ var piCodingAgentChannels = defineChannels(
|
|
|
29740
31194
|
);
|
|
29741
31195
|
|
|
29742
31196
|
// src/instrumentation/plugins/pi-coding-agent-plugin.ts
|
|
29743
|
-
var
|
|
31197
|
+
var piAgentPatchStates = /* @__PURE__ */ new WeakMap();
|
|
31198
|
+
var piAgentEventSubscriptions = /* @__PURE__ */ new WeakSet();
|
|
29744
31199
|
var piPromptContextStore;
|
|
29745
31200
|
var PiCodingAgentPlugin = class extends BasePlugin {
|
|
29746
31201
|
activePromptStates = /* @__PURE__ */ new Set();
|
|
29747
31202
|
onEnable() {
|
|
29748
|
-
this.
|
|
31203
|
+
this.interceptPrompt();
|
|
29749
31204
|
}
|
|
29750
31205
|
onDisable() {
|
|
29751
31206
|
for (const unsubscribe of this.unsubscribers) {
|
|
@@ -29753,65 +31208,74 @@ var PiCodingAgentPlugin = class extends BasePlugin {
|
|
|
29753
31208
|
}
|
|
29754
31209
|
this.unsubscribers = [];
|
|
29755
31210
|
for (const state of [...this.activePromptStates]) {
|
|
29756
|
-
|
|
29757
|
-
logInstrumentationError4("Pi Coding Agent disable cleanup", error);
|
|
29758
|
-
});
|
|
31211
|
+
finishPiPromptRun(state);
|
|
29759
31212
|
}
|
|
29760
31213
|
}
|
|
29761
|
-
|
|
29762
|
-
|
|
29763
|
-
|
|
29764
|
-
|
|
29765
|
-
|
|
29766
|
-
|
|
29767
|
-
|
|
29768
|
-
|
|
29769
|
-
|
|
29770
|
-
|
|
29771
|
-
|
|
29772
|
-
|
|
29773
|
-
|
|
29774
|
-
|
|
29775
|
-
|
|
29776
|
-
|
|
29777
|
-
|
|
29778
|
-
|
|
29779
|
-
|
|
29780
|
-
states.delete(event);
|
|
29781
|
-
state.promptCallEnded = true;
|
|
29782
|
-
if (!state.finalized && state.deferCompletionUntilTurnEnd && !state.turnEnded) {
|
|
29783
|
-
if (!state.sawStreamFn) {
|
|
29784
|
-
state.queued = true;
|
|
29785
|
-
if (!state.streamPatchState.queuedPromptStates.includes(state)) {
|
|
29786
|
-
state.streamPatchState.queuedPromptStates.push(state);
|
|
29787
|
-
}
|
|
31214
|
+
interceptPrompt() {
|
|
31215
|
+
this.unsubscribers.push(
|
|
31216
|
+
piCodingAgentChannels.prompt.intercept(
|
|
31217
|
+
(target, thisArg, args, additional) => {
|
|
31218
|
+
const invokeTarget = () => Reflect.apply(target, thisArg, args);
|
|
31219
|
+
let state;
|
|
31220
|
+
try {
|
|
31221
|
+
state = startPiPromptRun(
|
|
31222
|
+
{
|
|
31223
|
+
...additional,
|
|
31224
|
+
arguments: args,
|
|
31225
|
+
self: thisArg
|
|
31226
|
+
},
|
|
31227
|
+
(finalizedState) => {
|
|
31228
|
+
this.activePromptStates.delete(finalizedState);
|
|
31229
|
+
}
|
|
31230
|
+
);
|
|
31231
|
+
} catch (error) {
|
|
31232
|
+
logInstrumentationError4("Pi Coding Agent prompt start", error);
|
|
29788
31233
|
}
|
|
29789
|
-
|
|
29790
|
-
|
|
29791
|
-
|
|
29792
|
-
|
|
29793
|
-
|
|
29794
|
-
|
|
29795
|
-
|
|
29796
|
-
|
|
31234
|
+
if (!state) {
|
|
31235
|
+
return runWithAutoInstrumentationSuppressed(invokeTarget);
|
|
31236
|
+
}
|
|
31237
|
+
this.activePromptStates.add(state);
|
|
31238
|
+
return promptContextStore().run(
|
|
31239
|
+
state,
|
|
31240
|
+
() => runWithAutoInstrumentationSuppressed(() => {
|
|
31241
|
+
let result;
|
|
31242
|
+
try {
|
|
31243
|
+
result = invokeTarget();
|
|
31244
|
+
} catch (error) {
|
|
31245
|
+
finishPiPromptRun(state, error);
|
|
31246
|
+
throw error;
|
|
31247
|
+
}
|
|
31248
|
+
return Promise.resolve(result).then(
|
|
31249
|
+
(value) => {
|
|
31250
|
+
finishPiPromptCall(state);
|
|
31251
|
+
return value;
|
|
31252
|
+
},
|
|
31253
|
+
(error) => {
|
|
31254
|
+
finishPiPromptRun(state, error);
|
|
31255
|
+
throw error;
|
|
31256
|
+
}
|
|
31257
|
+
);
|
|
31258
|
+
})
|
|
31259
|
+
);
|
|
29797
31260
|
}
|
|
29798
|
-
|
|
29799
|
-
|
|
29800
|
-
}
|
|
29801
|
-
};
|
|
29802
|
-
channel2.subscribe(handlers);
|
|
29803
|
-
this.unsubscribers.push(() => {
|
|
29804
|
-
unbindAutoInstrumentationSuppression?.();
|
|
29805
|
-
channel2.unsubscribe(handlers);
|
|
29806
|
-
});
|
|
31261
|
+
)
|
|
31262
|
+
);
|
|
29807
31263
|
}
|
|
29808
31264
|
};
|
|
31265
|
+
function finishPiPromptCall(state) {
|
|
31266
|
+
state.promptCallEnded = true;
|
|
31267
|
+
if (state.deferCompletionUntilTurnEnd && !state.turnEnded) {
|
|
31268
|
+
return;
|
|
31269
|
+
}
|
|
31270
|
+
finishPiPromptRun(state);
|
|
31271
|
+
}
|
|
29809
31272
|
function startPiPromptRun(event, onFinalize) {
|
|
29810
31273
|
const session = extractSession(event);
|
|
29811
31274
|
const agent = session?.agent;
|
|
29812
31275
|
if (!session || !isPiAgent(agent)) {
|
|
29813
31276
|
return void 0;
|
|
29814
31277
|
}
|
|
31278
|
+
installPiAgentInstrumentation(agent);
|
|
29815
31279
|
const metadata = {
|
|
29816
31280
|
...extractSessionMetadata(session),
|
|
29817
31281
|
...extractPromptOptionsMetadata(event.arguments[1]),
|
|
@@ -29833,9 +31297,7 @@ function startPiPromptRun(event, onFinalize) {
|
|
|
29833
31297
|
INSTRUMENTATION_NAMES.PI_CODING_AGENT
|
|
29834
31298
|
)
|
|
29835
31299
|
);
|
|
29836
|
-
const streamPatchState = installPiStreamPatch(agent);
|
|
29837
31300
|
const options = event.arguments[1];
|
|
29838
|
-
const promptText = event.arguments[0];
|
|
29839
31301
|
const state = {
|
|
29840
31302
|
activeLlmSpans: /* @__PURE__ */ new Set(),
|
|
29841
31303
|
activeToolSpans: /* @__PURE__ */ new Map(),
|
|
@@ -29847,29 +31309,10 @@ function startPiPromptRun(event, onFinalize) {
|
|
|
29847
31309
|
metrics: {},
|
|
29848
31310
|
onFinalize,
|
|
29849
31311
|
promptCallEnded: false,
|
|
29850
|
-
...typeof promptText === "string" ? { promptText } : {},
|
|
29851
|
-
queued: false,
|
|
29852
31312
|
span,
|
|
29853
|
-
sawStreamFn: false,
|
|
29854
31313
|
startTime: getCurrentUnixTimestamp(),
|
|
29855
|
-
streamPatchState,
|
|
29856
31314
|
turnEnded: false
|
|
29857
31315
|
};
|
|
29858
|
-
state.restorePromptContext = enterPiPromptContext(state);
|
|
29859
|
-
streamPatchState.activePromptStates.add(state);
|
|
29860
|
-
try {
|
|
29861
|
-
state.unsubscribeAgent = agent.subscribe(async (agentEvent) => {
|
|
29862
|
-
try {
|
|
29863
|
-
await runWithAutoInstrumentationSuppressed(
|
|
29864
|
-
() => handlePiAgentEvent(state, agentEvent)
|
|
29865
|
-
);
|
|
29866
|
-
} catch (error) {
|
|
29867
|
-
logInstrumentationError4("Pi Coding Agent event", error);
|
|
29868
|
-
}
|
|
29869
|
-
});
|
|
29870
|
-
} catch (error) {
|
|
29871
|
-
logInstrumentationError4("Pi Coding Agent event subscription", error);
|
|
29872
|
-
}
|
|
29873
31316
|
return state;
|
|
29874
31317
|
}
|
|
29875
31318
|
function extractSession(event) {
|
|
@@ -29883,111 +31326,55 @@ function promptContextStore() {
|
|
|
29883
31326
|
piPromptContextStore ??= isomorph_default.newAsyncLocalStorage();
|
|
29884
31327
|
return piPromptContextStore;
|
|
29885
31328
|
}
|
|
29886
|
-
function currentPromptContextFrames() {
|
|
29887
|
-
return promptContextStore().getStore()?.frames ?? [];
|
|
29888
|
-
}
|
|
29889
31329
|
function currentPiPromptState() {
|
|
29890
|
-
|
|
29891
|
-
|
|
29892
|
-
|
|
29893
|
-
|
|
29894
|
-
|
|
29895
|
-
|
|
29896
|
-
|
|
29897
|
-
|
|
29898
|
-
|
|
29899
|
-
|
|
29900
|
-
|
|
29901
|
-
|
|
29902
|
-
const frames = currentPromptContextFrames().filter(
|
|
29903
|
-
(candidate) => candidate.id !== frame.id
|
|
29904
|
-
);
|
|
29905
|
-
promptContextStore().enterWith(frames.length > 0 ? { frames } : void 0);
|
|
29906
|
-
};
|
|
29907
|
-
}
|
|
29908
|
-
function installPiStreamPatch(agent) {
|
|
29909
|
-
const existing = piStreamPatchStates.get(agent);
|
|
29910
|
-
if (existing) {
|
|
29911
|
-
if (agent.streamFn !== existing.wrappedStreamFn) {
|
|
29912
|
-
debugLogger.debug(
|
|
29913
|
-
"Pi Coding Agent streamFn changed while Braintrust instrumentation was active; preserving existing patch state."
|
|
29914
|
-
);
|
|
29915
|
-
}
|
|
29916
|
-
return existing;
|
|
29917
|
-
}
|
|
29918
|
-
const patchState = {
|
|
29919
|
-
activePromptStates: /* @__PURE__ */ new Set(),
|
|
29920
|
-
agent,
|
|
29921
|
-
originalStreamFn: agent.streamFn,
|
|
29922
|
-
queuedPromptStates: [],
|
|
29923
|
-
wrappedStreamFn: agent.streamFn
|
|
29924
|
-
};
|
|
29925
|
-
patchState.wrappedStreamFn = makeSharedInstrumentedStreamFn(patchState);
|
|
29926
|
-
agent.streamFn = patchState.wrappedStreamFn;
|
|
29927
|
-
piStreamPatchStates.set(agent, patchState);
|
|
29928
|
-
return patchState;
|
|
29929
|
-
}
|
|
29930
|
-
function resolveStreamPromptState(patchState, context) {
|
|
29931
|
-
let lastUserText;
|
|
29932
|
-
if (Array.isArray(context.messages)) {
|
|
29933
|
-
for (let i = context.messages.length - 1; i >= 0; i--) {
|
|
29934
|
-
const message = context.messages[i];
|
|
29935
|
-
if (isPiUserMessage(message)) {
|
|
29936
|
-
if (typeof message.content === "string") {
|
|
29937
|
-
lastUserText = message.content;
|
|
29938
|
-
} else {
|
|
29939
|
-
lastUserText = message.content.flatMap((part) => part.type === "text" ? [part.text] : []).join("");
|
|
29940
|
-
}
|
|
29941
|
-
break;
|
|
29942
|
-
}
|
|
29943
|
-
}
|
|
29944
|
-
}
|
|
29945
|
-
if (lastUserText !== void 0) {
|
|
29946
|
-
const queuedMatch = patchState.queuedPromptStates.find(
|
|
29947
|
-
(state) => state.promptText === lastUserText
|
|
29948
|
-
);
|
|
29949
|
-
if (queuedMatch) {
|
|
29950
|
-
return queuedMatch;
|
|
29951
|
-
}
|
|
29952
|
-
const matches = [...patchState.activePromptStates].filter(
|
|
29953
|
-
(state) => state.promptText === lastUserText
|
|
31330
|
+
return promptContextStore().getStore();
|
|
31331
|
+
}
|
|
31332
|
+
function installPiAgentInstrumentation(agent) {
|
|
31333
|
+
const existing = piAgentPatchStates.get(agent);
|
|
31334
|
+
if (!existing || agent.streamFn !== existing.wrappedStreamFn) {
|
|
31335
|
+
const patchState = {
|
|
31336
|
+
originalStreamFn: agent.streamFn,
|
|
31337
|
+
wrappedStreamFn: agent.streamFn
|
|
31338
|
+
};
|
|
31339
|
+
patchState.wrappedStreamFn = makeInstrumentedStreamFn(
|
|
31340
|
+
agent,
|
|
31341
|
+
patchState.originalStreamFn
|
|
29954
31342
|
);
|
|
29955
|
-
|
|
29956
|
-
|
|
29957
|
-
}
|
|
31343
|
+
agent.streamFn = patchState.wrappedStreamFn;
|
|
31344
|
+
piAgentPatchStates.set(agent, patchState);
|
|
29958
31345
|
}
|
|
29959
|
-
|
|
29960
|
-
|
|
29961
|
-
return contextState;
|
|
31346
|
+
if (piAgentEventSubscriptions.has(agent)) {
|
|
31347
|
+
return;
|
|
29962
31348
|
}
|
|
29963
|
-
|
|
29964
|
-
|
|
31349
|
+
try {
|
|
31350
|
+
agent.subscribe(async (event) => {
|
|
31351
|
+
const state = currentPiPromptState();
|
|
31352
|
+
if (!state || state.agent !== agent || state.finalized) {
|
|
31353
|
+
return;
|
|
31354
|
+
}
|
|
31355
|
+
try {
|
|
31356
|
+
await runWithAutoInstrumentationSuppressed(
|
|
31357
|
+
() => handlePiAgentEvent(state, event)
|
|
31358
|
+
);
|
|
31359
|
+
} catch (error) {
|
|
31360
|
+
logInstrumentationError4("Pi Coding Agent event", error);
|
|
31361
|
+
}
|
|
31362
|
+
});
|
|
31363
|
+
piAgentEventSubscriptions.add(agent);
|
|
31364
|
+
} catch (error) {
|
|
31365
|
+
logInstrumentationError4("Pi Coding Agent event subscription", error);
|
|
29965
31366
|
}
|
|
29966
|
-
return void 0;
|
|
29967
31367
|
}
|
|
29968
|
-
function
|
|
31368
|
+
function makeInstrumentedStreamFn(agent, originalStreamFn) {
|
|
29969
31369
|
return async function instrumentedPiStreamFn(model, context, options) {
|
|
29970
|
-
const
|
|
29971
|
-
|
|
29972
|
-
|
|
29973
|
-
|
|
29974
|
-
context,
|
|
29975
|
-
options
|
|
29976
|
-
]);
|
|
29977
|
-
return patchState.activePromptStates.size > 0 ? runWithAutoInstrumentationSuppressed(invokeOriginal) : invokeOriginal();
|
|
31370
|
+
const invokeOriginal = () => Reflect.apply(originalStreamFn, this, [model, context, options]);
|
|
31371
|
+
const state = currentPiPromptState();
|
|
31372
|
+
if (!state || state.agent !== agent || state.finalized) {
|
|
31373
|
+
return invokeOriginal();
|
|
29978
31374
|
}
|
|
29979
|
-
state.sawStreamFn = true;
|
|
29980
|
-
removeQueuedPromptState(state);
|
|
29981
|
-
state.streamPatchState.eventPromptState = state;
|
|
29982
31375
|
const llmState = await startPiLlmSpan(state, model, context, options);
|
|
29983
31376
|
try {
|
|
29984
|
-
const stream = await runWithAutoInstrumentationSuppressed(
|
|
29985
|
-
() => Reflect.apply(patchState.originalStreamFn, this, [
|
|
29986
|
-
model,
|
|
29987
|
-
context,
|
|
29988
|
-
options
|
|
29989
|
-
])
|
|
29990
|
-
);
|
|
31377
|
+
const stream = await runWithAutoInstrumentationSuppressed(invokeOriginal);
|
|
29991
31378
|
return patchAssistantMessageStream(stream, state, llmState);
|
|
29992
31379
|
} catch (error) {
|
|
29993
31380
|
finishPiLlmSpan(state, llmState, void 0, error);
|
|
@@ -30134,13 +31521,6 @@ async function handlePiAgentEvent(state, event) {
|
|
|
30134
31521
|
if (state.finalized) {
|
|
30135
31522
|
return;
|
|
30136
31523
|
}
|
|
30137
|
-
const eventPromptState = state.streamPatchState.eventPromptState;
|
|
30138
|
-
if (eventPromptState && eventPromptState !== state) {
|
|
30139
|
-
return;
|
|
30140
|
-
}
|
|
30141
|
-
if (!eventPromptState && (state.queued || state.streamPatchState.activePromptStates.size > 1 && currentPiPromptState() !== state)) {
|
|
30142
|
-
return;
|
|
30143
|
-
}
|
|
30144
31524
|
switch (event.type) {
|
|
30145
31525
|
case "message_end":
|
|
30146
31526
|
if (isPiAssistantMessage(event.message)) {
|
|
@@ -30155,11 +31535,8 @@ async function handlePiAgentEvent(state, event) {
|
|
|
30155
31535
|
addMetrics(state.metrics, extractUsageMetrics2(event.message.usage));
|
|
30156
31536
|
}
|
|
30157
31537
|
}
|
|
30158
|
-
if (state.streamPatchState.eventPromptState === state) {
|
|
30159
|
-
state.streamPatchState.eventPromptState = void 0;
|
|
30160
|
-
}
|
|
30161
31538
|
if (state.promptCallEnded && state.deferCompletionUntilTurnEnd) {
|
|
30162
|
-
|
|
31539
|
+
finishPiPromptRun(state);
|
|
30163
31540
|
}
|
|
30164
31541
|
return;
|
|
30165
31542
|
case "tool_execution_start":
|
|
@@ -30232,19 +31609,13 @@ function finishPiToolSpan(state, event) {
|
|
|
30232
31609
|
}
|
|
30233
31610
|
}
|
|
30234
31611
|
}
|
|
30235
|
-
|
|
31612
|
+
function finishPiPromptRun(state, error) {
|
|
30236
31613
|
if (state.finalized) {
|
|
30237
31614
|
return;
|
|
30238
31615
|
}
|
|
30239
31616
|
state.finalized = true;
|
|
30240
31617
|
state.onFinalize?.(state);
|
|
30241
|
-
|
|
30242
|
-
try {
|
|
30243
|
-
state.unsubscribeAgent?.();
|
|
30244
|
-
} catch (unsubscribeError) {
|
|
30245
|
-
logInstrumentationError4("Pi Coding Agent unsubscribe", unsubscribeError);
|
|
30246
|
-
}
|
|
30247
|
-
await finishOpenLlmSpans(state, error);
|
|
31618
|
+
finishOpenLlmSpans(state, error);
|
|
30248
31619
|
finishOpenToolSpans(state, error);
|
|
30249
31620
|
const metadata = {
|
|
30250
31621
|
...state.metadata,
|
|
@@ -30261,34 +31632,14 @@ async function finalizePiPromptRun(state, error) {
|
|
|
30261
31632
|
output: state.output
|
|
30262
31633
|
});
|
|
30263
31634
|
} finally {
|
|
30264
|
-
|
|
30265
|
-
|
|
30266
|
-
}
|
|
30267
|
-
|
|
30268
|
-
|
|
30269
|
-
patchState.activePromptStates.delete(state);
|
|
30270
|
-
removeQueuedPromptState(state);
|
|
30271
|
-
if (patchState.eventPromptState === state) {
|
|
30272
|
-
patchState.eventPromptState = void 0;
|
|
30273
|
-
}
|
|
30274
|
-
state.restorePromptContext?.();
|
|
30275
|
-
if (patchState.activePromptStates.size > 0) {
|
|
30276
|
-
return;
|
|
30277
|
-
}
|
|
30278
|
-
if (patchState.agent.streamFn === patchState.wrappedStreamFn) {
|
|
30279
|
-
patchState.agent.streamFn = patchState.originalStreamFn;
|
|
30280
|
-
}
|
|
30281
|
-
piStreamPatchStates.delete(patchState.agent);
|
|
30282
|
-
}
|
|
30283
|
-
function removeQueuedPromptState(state) {
|
|
30284
|
-
state.queued = false;
|
|
30285
|
-
const queuedPromptStates = state.streamPatchState.queuedPromptStates;
|
|
30286
|
-
const index = queuedPromptStates.indexOf(state);
|
|
30287
|
-
if (index >= 0) {
|
|
30288
|
-
queuedPromptStates.splice(index, 1);
|
|
31635
|
+
try {
|
|
31636
|
+
state.span.end();
|
|
31637
|
+
} catch (endError) {
|
|
31638
|
+
logInstrumentationError4("Pi Coding Agent prompt end", endError);
|
|
31639
|
+
}
|
|
30289
31640
|
}
|
|
30290
31641
|
}
|
|
30291
|
-
|
|
31642
|
+
function finishOpenLlmSpans(state, error) {
|
|
30292
31643
|
for (const llmState of [...state.activeLlmSpans]) {
|
|
30293
31644
|
finishPiLlmSpan(state, llmState, void 0, error);
|
|
30294
31645
|
}
|
|
@@ -30369,7 +31720,7 @@ function normalizeAssistantMessage(message) {
|
|
|
30369
31720
|
(part) => part.type === "thinking" && !part.redacted ? [part.thinking] : []
|
|
30370
31721
|
).join("");
|
|
30371
31722
|
const toolCalls = message.content.flatMap(
|
|
30372
|
-
(part) => part.type === "toolCall" ? [
|
|
31723
|
+
(part) => part.type === "toolCall" ? [normalizeToolCall2(part)] : []
|
|
30373
31724
|
);
|
|
30374
31725
|
return {
|
|
30375
31726
|
role: "assistant",
|
|
@@ -30404,13 +31755,13 @@ function normalizeUserContent(content) {
|
|
|
30404
31755
|
return part;
|
|
30405
31756
|
});
|
|
30406
31757
|
}
|
|
30407
|
-
function
|
|
31758
|
+
function normalizeToolCall2(toolCall) {
|
|
30408
31759
|
return {
|
|
30409
31760
|
id: toolCall.id,
|
|
30410
31761
|
type: "function",
|
|
30411
31762
|
function: {
|
|
30412
31763
|
name: toolCall.name,
|
|
30413
|
-
arguments:
|
|
31764
|
+
arguments: stringifyArguments2(toolCall.arguments)
|
|
30414
31765
|
}
|
|
30415
31766
|
};
|
|
30416
31767
|
}
|
|
@@ -30593,7 +31944,7 @@ function cleanMetrics5(metrics) {
|
|
|
30593
31944
|
}
|
|
30594
31945
|
return cleaned;
|
|
30595
31946
|
}
|
|
30596
|
-
function
|
|
31947
|
+
function stringifyArguments2(value) {
|
|
30597
31948
|
if (typeof value === "string") {
|
|
30598
31949
|
return value;
|
|
30599
31950
|
}
|
|
@@ -32161,6 +33512,7 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
32161
33512
|
anthropicPlugin = null;
|
|
32162
33513
|
aiSDKPlugin = null;
|
|
32163
33514
|
claudeAgentSDKPlugin = null;
|
|
33515
|
+
cloudflareThinkPlugin = null;
|
|
32164
33516
|
cursorSDKPlugin = null;
|
|
32165
33517
|
openAIAgentsPlugin = null;
|
|
32166
33518
|
googleGenAIPlugin = null;
|
|
@@ -32169,6 +33521,7 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
32169
33521
|
openRouterPlugin = null;
|
|
32170
33522
|
openRouterAgentPlugin = null;
|
|
32171
33523
|
mistralPlugin = null;
|
|
33524
|
+
ollamaPlugin = null;
|
|
32172
33525
|
googleADKPlugin = null;
|
|
32173
33526
|
coherePlugin = null;
|
|
32174
33527
|
groqPlugin = null;
|
|
@@ -32208,6 +33561,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
32208
33561
|
this.claudeAgentSDKPlugin = new ClaudeAgentSDKPlugin();
|
|
32209
33562
|
this.claudeAgentSDKPlugin.enable();
|
|
32210
33563
|
}
|
|
33564
|
+
if (integrations.cloudflareThink !== false) {
|
|
33565
|
+
this.cloudflareThinkPlugin = new CloudflareThinkPlugin();
|
|
33566
|
+
this.cloudflareThinkPlugin.enable();
|
|
33567
|
+
}
|
|
32211
33568
|
if (integrations.cursorSDK !== false && integrations.cursor !== false) {
|
|
32212
33569
|
this.cursorSDKPlugin = new CursorSDKPlugin();
|
|
32213
33570
|
this.cursorSDKPlugin.enable();
|
|
@@ -32238,6 +33595,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
32238
33595
|
this.mistralPlugin = new MistralPlugin();
|
|
32239
33596
|
this.mistralPlugin.enable();
|
|
32240
33597
|
}
|
|
33598
|
+
if (integrations.ollama !== false) {
|
|
33599
|
+
this.ollamaPlugin = new OllamaPlugin();
|
|
33600
|
+
this.ollamaPlugin.enable();
|
|
33601
|
+
}
|
|
32241
33602
|
if (integrations.googleADK !== false) {
|
|
32242
33603
|
this.googleADKPlugin = new GoogleADKPlugin();
|
|
32243
33604
|
this.googleADKPlugin.enable();
|
|
@@ -32314,6 +33675,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
32314
33675
|
this.claudeAgentSDKPlugin.disable();
|
|
32315
33676
|
this.claudeAgentSDKPlugin = null;
|
|
32316
33677
|
}
|
|
33678
|
+
if (this.cloudflareThinkPlugin) {
|
|
33679
|
+
this.cloudflareThinkPlugin.disable();
|
|
33680
|
+
this.cloudflareThinkPlugin = null;
|
|
33681
|
+
}
|
|
32317
33682
|
if (this.cursorSDKPlugin) {
|
|
32318
33683
|
this.cursorSDKPlugin.disable();
|
|
32319
33684
|
this.cursorSDKPlugin = null;
|
|
@@ -32346,6 +33711,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
32346
33711
|
this.mistralPlugin.disable();
|
|
32347
33712
|
this.mistralPlugin = null;
|
|
32348
33713
|
}
|
|
33714
|
+
if (this.ollamaPlugin) {
|
|
33715
|
+
this.ollamaPlugin.disable();
|
|
33716
|
+
this.ollamaPlugin = null;
|
|
33717
|
+
}
|
|
32349
33718
|
if (this.googleADKPlugin) {
|
|
32350
33719
|
this.googleADKPlugin.disable();
|
|
32351
33720
|
this.googleADKPlugin = null;
|
|
@@ -34082,6 +35451,7 @@ var envIntegrationAliases = {
|
|
|
34082
35451
|
cloudflareaichat: "cloudflareAIChat",
|
|
34083
35452
|
"cloudflare-ai-chat": "cloudflareAIChat",
|
|
34084
35453
|
"@cloudflare/ai-chat": "cloudflareAIChat",
|
|
35454
|
+
cloudflarethink: "cloudflareThink",
|
|
34085
35455
|
cursor: "cursor",
|
|
34086
35456
|
"cursor-sdk": "cursorSDK",
|
|
34087
35457
|
cursorsdk: "cursorSDK",
|
|
@@ -34102,6 +35472,7 @@ var envIntegrationAliases = {
|
|
|
34102
35472
|
openrouteragent: "openrouterAgent",
|
|
34103
35473
|
"openrouter-agent": "openrouterAgent",
|
|
34104
35474
|
mistral: "mistral",
|
|
35475
|
+
ollama: "ollama",
|
|
34105
35476
|
googleadk: "googleADK",
|
|
34106
35477
|
"google-adk": "googleADK",
|
|
34107
35478
|
cohere: "cohere",
|
|
@@ -34137,6 +35508,7 @@ function getDefaultInstrumentationIntegrations() {
|
|
|
34137
35508
|
huggingface: true,
|
|
34138
35509
|
claudeAgentSDK: true,
|
|
34139
35510
|
cloudflareAIChat: true,
|
|
35511
|
+
cloudflareThink: true,
|
|
34140
35512
|
cursor: true,
|
|
34141
35513
|
cursorSDK: true,
|
|
34142
35514
|
flue: true,
|
|
@@ -34145,6 +35517,7 @@ function getDefaultInstrumentationIntegrations() {
|
|
|
34145
35517
|
openrouter: true,
|
|
34146
35518
|
openrouterAgent: true,
|
|
34147
35519
|
mistral: true,
|
|
35520
|
+
ollama: true,
|
|
34148
35521
|
cohere: true,
|
|
34149
35522
|
groq: true,
|
|
34150
35523
|
bedrock: true,
|