braintrust 3.26.0 → 3.28.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.d.mts +519 -186
- package/dev/dist/index.d.ts +519 -186
- package/dev/dist/index.js +3727 -1526
- package/dev/dist/index.mjs +2815 -614
- package/dist/apply-auto-instrumentation.js +372 -261
- package/dist/apply-auto-instrumentation.mjs +171 -60
- package/dist/auto-instrumentations/bundler/esbuild.cjs +458 -61
- package/dist/auto-instrumentations/bundler/esbuild.mjs +5 -4
- package/dist/auto-instrumentations/bundler/next.cjs +460 -63
- package/dist/auto-instrumentations/bundler/next.mjs +6 -5
- package/dist/auto-instrumentations/bundler/rollup.cjs +458 -61
- package/dist/auto-instrumentations/bundler/rollup.mjs +5 -4
- package/dist/auto-instrumentations/bundler/vite.cjs +487 -62
- package/dist/auto-instrumentations/bundler/vite.mjs +34 -5
- package/dist/auto-instrumentations/bundler/webpack-loader.cjs +444 -61
- package/dist/auto-instrumentations/bundler/webpack.cjs +458 -61
- package/dist/auto-instrumentations/bundler/webpack.mjs +6 -5
- package/dist/auto-instrumentations/{chunk-6E22MYSW.mjs → chunk-26PKVUKB.mjs} +109 -5
- package/dist/auto-instrumentations/{chunk-AKKPLXTP.mjs → chunk-2AMDGD65.mjs} +160 -57
- package/dist/auto-instrumentations/{chunk-V5LEODRX.mjs → chunk-HD35AM3M.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-XZHHE4Y3.mjs → chunk-NP7V4XB2.mjs} +157 -3
- package/dist/auto-instrumentations/hook.mjs +396 -32
- package/dist/auto-instrumentations/index.cjs +298 -2
- 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 +683 -56
- package/dist/browser.d.ts +683 -56
- package/dist/browser.js +4242 -655
- package/dist/browser.mjs +4242 -655
- package/dist/{chunk-VYNNEKSA.js → chunk-BBE7SNRV.js} +248 -10
- package/dist/{chunk-VRZZQPAA.js → chunk-OBBWQW6K.js} +3351 -1392
- package/dist/{chunk-XIZOM2HO.mjs → chunk-UPFNQCGB.mjs} +2419 -460
- package/dist/{chunk-PN7EWK66.mjs → chunk-ZHUHZWFY.mjs} +241 -3
- package/dist/cli.js +2867 -668
- package/dist/edge-light.d.mts +1 -1
- package/dist/edge-light.d.ts +1 -1
- package/dist/edge-light.js +4242 -655
- package/dist/edge-light.mjs +4242 -655
- package/dist/index.d.mts +1267 -640
- package/dist/index.d.ts +1267 -640
- package/dist/index.js +2107 -630
- package/dist/index.mjs +1649 -172
- package/dist/instrumentation/index.d.mts +198 -6
- package/dist/instrumentation/index.d.ts +198 -6
- package/dist/instrumentation/index.js +2661 -581
- package/dist/instrumentation/index.mjs +2661 -581
- 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 +4242 -655
- package/dist/workerd.mjs +4242 -655
- package/package.json +2 -3
- package/util/dist/index.d.mts +1545 -100
- package/util/dist/index.d.ts +1545 -100
package/dev/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/node/config.ts
|
|
2
2
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
3
|
-
import * as
|
|
3
|
+
import * as path2 from "node:path";
|
|
4
4
|
import * as fs from "node:fs/promises";
|
|
5
5
|
import * as os from "node:os";
|
|
6
6
|
import * as fsSync from "node:fs";
|
|
@@ -14,8 +14,10 @@ var GLOBAL_INSTRUMENTATION_HOOKS_KEY = "__braintrust_instrumentation_hooks";
|
|
|
14
14
|
var GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION = 1;
|
|
15
15
|
var GLOBAL_INSTRUMENTATION_HOOKS_REGISTRY_BRAND = "braintrust.global-instrumentation-hooks.registry";
|
|
16
16
|
var GLOBAL_INSTRUMENTATION_HOOK_BRAND = "braintrust.global-instrumentation-hooks.hook";
|
|
17
|
+
var GLOBAL_INVOCATION_HOOK_BRAND = "braintrust.global-instrumentation-hooks.invocation-hook";
|
|
17
18
|
var registryBrand = Symbol.for(GLOBAL_INSTRUMENTATION_HOOKS_REGISTRY_BRAND);
|
|
18
19
|
var hookBrand = Symbol.for(GLOBAL_INSTRUMENTATION_HOOK_BRAND);
|
|
20
|
+
var invocationHookBrand = Symbol.for(GLOBAL_INVOCATION_HOOK_BRAND);
|
|
19
21
|
var errorReporter;
|
|
20
22
|
function setGlobalHookErrorReporter(reporter) {
|
|
21
23
|
const previousReporter = errorReporter;
|
|
@@ -160,12 +162,69 @@ var traceEvents = [
|
|
|
160
162
|
"asyncEnd",
|
|
161
163
|
"error"
|
|
162
164
|
];
|
|
165
|
+
function traceInvocation(hook, operator, target, thisArg, args, additional, callbackIndex = -1) {
|
|
166
|
+
const context = {
|
|
167
|
+
...additional,
|
|
168
|
+
arguments: args,
|
|
169
|
+
self: thisArg
|
|
170
|
+
};
|
|
171
|
+
const invoke2 = () => hook.invoke(target, thisArg, args, additional);
|
|
172
|
+
if (operator === "traceCallback") {
|
|
173
|
+
return hook.traceCallback(invoke2, callbackIndex, context);
|
|
174
|
+
}
|
|
175
|
+
if (operator === "tracePromise") {
|
|
176
|
+
return hook.tracePromise(invoke2, context);
|
|
177
|
+
}
|
|
178
|
+
return hook.traceSync(invoke2, context);
|
|
179
|
+
}
|
|
180
|
+
var InvocationHook = class {
|
|
181
|
+
interceptors = [];
|
|
182
|
+
get hasInterceptors() {
|
|
183
|
+
return this.interceptors.length > 0;
|
|
184
|
+
}
|
|
185
|
+
intercept(interceptor) {
|
|
186
|
+
if (typeof interceptor !== "function") {
|
|
187
|
+
throw new TypeError("interceptor must be a function");
|
|
188
|
+
}
|
|
189
|
+
this.interceptors = [...this.interceptors, interceptor];
|
|
190
|
+
let active = true;
|
|
191
|
+
return () => {
|
|
192
|
+
if (!active) {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
active = false;
|
|
196
|
+
const index = this.interceptors.indexOf(interceptor);
|
|
197
|
+
if (index !== -1) {
|
|
198
|
+
this.interceptors = [
|
|
199
|
+
...this.interceptors.slice(0, index),
|
|
200
|
+
...this.interceptors.slice(index + 1)
|
|
201
|
+
];
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
invoke(target, thisArg, args, additional) {
|
|
206
|
+
const interceptors = this.interceptors;
|
|
207
|
+
if (interceptors.length === 0) {
|
|
208
|
+
return Reflect.apply(target, thisArg, args);
|
|
209
|
+
}
|
|
210
|
+
let next = target;
|
|
211
|
+
for (let index = interceptors.length - 1; index >= 0; index -= 1) {
|
|
212
|
+
const interceptor = interceptors[index];
|
|
213
|
+
const downstream = next;
|
|
214
|
+
next = function(...nextArgs) {
|
|
215
|
+
return interceptor(downstream, this, nextArgs, additional);
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
return Reflect.apply(next, thisArg, args);
|
|
219
|
+
}
|
|
220
|
+
};
|
|
163
221
|
var TracingHook = class {
|
|
164
222
|
start;
|
|
165
223
|
end;
|
|
166
224
|
asyncStart;
|
|
167
225
|
asyncEnd;
|
|
168
226
|
error;
|
|
227
|
+
invocationHook = new InvocationHook();
|
|
169
228
|
constructor(nameOrChannels) {
|
|
170
229
|
Object.defineProperty(this, hookBrand, {
|
|
171
230
|
configurable: false,
|
|
@@ -173,6 +232,12 @@ var TracingHook = class {
|
|
|
173
232
|
value: GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION,
|
|
174
233
|
writable: false
|
|
175
234
|
});
|
|
235
|
+
Object.defineProperty(this, invocationHookBrand, {
|
|
236
|
+
configurable: false,
|
|
237
|
+
enumerable: false,
|
|
238
|
+
value: GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION,
|
|
239
|
+
writable: false
|
|
240
|
+
});
|
|
176
241
|
if (typeof nameOrChannels === "string") {
|
|
177
242
|
this.start = new HookChannel(`tracing:${nameOrChannels}:start`);
|
|
178
243
|
this.end = new HookChannel(`tracing:${nameOrChannels}:end`);
|
|
@@ -190,6 +255,26 @@ var TracingHook = class {
|
|
|
190
255
|
get hasSubscribers() {
|
|
191
256
|
return this.start.hasSubscribers || this.end.hasSubscribers || this.asyncStart.hasSubscribers || this.asyncEnd.hasSubscribers || this.error.hasSubscribers;
|
|
192
257
|
}
|
|
258
|
+
get hasInterceptors() {
|
|
259
|
+
return this.invocationHook.hasInterceptors;
|
|
260
|
+
}
|
|
261
|
+
intercept(interceptor) {
|
|
262
|
+
return this.invocationHook.intercept(interceptor);
|
|
263
|
+
}
|
|
264
|
+
invoke(target, thisArg, args, additional) {
|
|
265
|
+
return this.invocationHook.invoke(target, thisArg, args, additional);
|
|
266
|
+
}
|
|
267
|
+
traceInvocation(operator, target, thisArg, args, additional, callbackIndex = -1) {
|
|
268
|
+
return traceInvocation(
|
|
269
|
+
this,
|
|
270
|
+
operator,
|
|
271
|
+
target,
|
|
272
|
+
thisArg,
|
|
273
|
+
args,
|
|
274
|
+
additional,
|
|
275
|
+
callbackIndex
|
|
276
|
+
);
|
|
277
|
+
}
|
|
193
278
|
subscribe(handlers) {
|
|
194
279
|
for (const eventName of traceEvents) {
|
|
195
280
|
const handler = handlers[eventName];
|
|
@@ -411,6 +496,60 @@ function hasTracingHookShape(value) {
|
|
|
411
496
|
return false;
|
|
412
497
|
}
|
|
413
498
|
}
|
|
499
|
+
function hasInvocationHookShape(value) {
|
|
500
|
+
if (typeof value !== "object" && typeof value !== "function" || value === null) {
|
|
501
|
+
return false;
|
|
502
|
+
}
|
|
503
|
+
try {
|
|
504
|
+
const hook = value;
|
|
505
|
+
return value[invocationHookBrand] === GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION && typeof hook.hasInterceptors === "boolean" && typeof hook.intercept === "function" && typeof hook.invoke === "function";
|
|
506
|
+
} catch {
|
|
507
|
+
return false;
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
function installInvocationHook(value) {
|
|
511
|
+
const hasInvocationHook = hasInvocationHookShape(value);
|
|
512
|
+
const invocationHook = new InvocationHook();
|
|
513
|
+
try {
|
|
514
|
+
if (!hasInvocationHook) {
|
|
515
|
+
Object.defineProperties(value, {
|
|
516
|
+
[invocationHookBrand]: {
|
|
517
|
+
configurable: false,
|
|
518
|
+
enumerable: false,
|
|
519
|
+
value: GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION,
|
|
520
|
+
writable: false
|
|
521
|
+
},
|
|
522
|
+
hasInterceptors: {
|
|
523
|
+
configurable: false,
|
|
524
|
+
enumerable: false,
|
|
525
|
+
get: () => invocationHook.hasInterceptors
|
|
526
|
+
},
|
|
527
|
+
intercept: {
|
|
528
|
+
configurable: false,
|
|
529
|
+
enumerable: false,
|
|
530
|
+
value: invocationHook.intercept.bind(invocationHook),
|
|
531
|
+
writable: false
|
|
532
|
+
},
|
|
533
|
+
invoke: {
|
|
534
|
+
configurable: false,
|
|
535
|
+
enumerable: false,
|
|
536
|
+
value: invocationHook.invoke.bind(invocationHook),
|
|
537
|
+
writable: false
|
|
538
|
+
}
|
|
539
|
+
});
|
|
540
|
+
}
|
|
541
|
+
if (typeof value.traceInvocation !== "function") {
|
|
542
|
+
Object.defineProperty(value, "traceInvocation", {
|
|
543
|
+
configurable: false,
|
|
544
|
+
enumerable: false,
|
|
545
|
+
value: traceInvocation.bind(void 0, value),
|
|
546
|
+
writable: false
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
} catch (error) {
|
|
550
|
+
reportError(error);
|
|
551
|
+
}
|
|
552
|
+
}
|
|
414
553
|
function isCompatibleTracingHook(value) {
|
|
415
554
|
try {
|
|
416
555
|
return value[hookBrand] === GLOBAL_INSTRUMENTATION_HOOKS_PROTOCOL_VERSION && hasTracingHookShape(value);
|
|
@@ -497,6 +636,7 @@ function newGlobalTracingChannel(nameOrChannels) {
|
|
|
497
636
|
return inertTracingHook;
|
|
498
637
|
}
|
|
499
638
|
if (isCompatibleTracingHook(existing)) {
|
|
639
|
+
installInvocationHook(existing);
|
|
500
640
|
return existing;
|
|
501
641
|
}
|
|
502
642
|
if (existing !== void 0) {
|
|
@@ -660,34 +800,93 @@ setGlobalHookErrorReporter((error) => {
|
|
|
660
800
|
debugLogger.error("Global instrumentation hook error:", error);
|
|
661
801
|
});
|
|
662
802
|
|
|
663
|
-
// src/
|
|
664
|
-
import {
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
803
|
+
// src/git-command.ts
|
|
804
|
+
import { execFile } from "node:child_process";
|
|
805
|
+
import { constants } from "node:fs";
|
|
806
|
+
import { access } from "node:fs/promises";
|
|
807
|
+
import * as path from "node:path";
|
|
808
|
+
var GIT_EXECUTABLE_NAMES = process.platform === "win32" ? ["git.exe", "git"] : ["git"];
|
|
809
|
+
var GIT_MAX_BUFFER_BYTES = 10 * 1024 * 1024;
|
|
810
|
+
var gitExecutablePromise;
|
|
811
|
+
function executableSearchPath() {
|
|
812
|
+
return Object.entries(process.env).find(
|
|
813
|
+
([name]) => name.toUpperCase() === "PATH"
|
|
814
|
+
)?.[1];
|
|
815
|
+
}
|
|
816
|
+
async function findGitExecutable(searchPath = executableSearchPath()) {
|
|
817
|
+
if (!searchPath) {
|
|
818
|
+
return void 0;
|
|
819
|
+
}
|
|
820
|
+
for (const rawSearchDir of searchPath.split(path.delimiter)) {
|
|
821
|
+
const searchDir = rawSearchDir.trim().replace(/^"(.*)"$/, "$1");
|
|
822
|
+
if (!path.isAbsolute(searchDir)) {
|
|
823
|
+
continue;
|
|
673
824
|
}
|
|
674
|
-
|
|
675
|
-
|
|
825
|
+
for (const executableName of GIT_EXECUTABLE_NAMES) {
|
|
826
|
+
const candidate = path.join(searchDir, executableName);
|
|
827
|
+
try {
|
|
828
|
+
await access(
|
|
829
|
+
candidate,
|
|
830
|
+
process.platform === "win32" ? constants.F_OK : constants.X_OK
|
|
831
|
+
);
|
|
832
|
+
return candidate;
|
|
833
|
+
} catch {
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
return void 0;
|
|
838
|
+
}
|
|
839
|
+
async function resolveGitExecutable() {
|
|
840
|
+
gitExecutablePromise ??= findGitExecutable();
|
|
841
|
+
return await gitExecutablePromise;
|
|
842
|
+
}
|
|
843
|
+
async function runGitCommand(args, options = {}) {
|
|
844
|
+
const executable = await resolveGitExecutable();
|
|
845
|
+
if (!executable) {
|
|
846
|
+
throw new Error("Could not find a git executable on PATH");
|
|
676
847
|
}
|
|
848
|
+
return await new Promise((resolve, reject2) => {
|
|
849
|
+
execFile(
|
|
850
|
+
executable,
|
|
851
|
+
args,
|
|
852
|
+
{
|
|
853
|
+
cwd: options.cwd,
|
|
854
|
+
encoding: "utf8",
|
|
855
|
+
maxBuffer: GIT_MAX_BUFFER_BYTES
|
|
856
|
+
},
|
|
857
|
+
(error, stdout) => {
|
|
858
|
+
if (error) {
|
|
859
|
+
reject2(error);
|
|
860
|
+
} else {
|
|
861
|
+
resolve(stdout);
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
);
|
|
865
|
+
});
|
|
677
866
|
}
|
|
867
|
+
|
|
868
|
+
// src/gitutil.ts
|
|
869
|
+
var COMMON_BASE_BRANCHES = ["main", "master", "develop"];
|
|
678
870
|
var _baseBranch = null;
|
|
679
871
|
async function getBaseBranch(remote = void 0) {
|
|
680
872
|
if (_baseBranch === null) {
|
|
681
|
-
const
|
|
682
|
-
if (
|
|
873
|
+
const repoPath = await currentRepoPath();
|
|
874
|
+
if (!repoPath) {
|
|
683
875
|
throw new Error("Not in a git repo");
|
|
684
876
|
}
|
|
685
|
-
const
|
|
877
|
+
const runGit = async (args) => await runGitCommand(args, { cwd: repoPath });
|
|
878
|
+
const remoteName = remote ?? (await runGit(["remote"])).trim().split(/\r?\n/)[0];
|
|
686
879
|
if (!remoteName) {
|
|
687
880
|
throw new Error("No remote found");
|
|
688
881
|
}
|
|
689
882
|
let branch = null;
|
|
690
|
-
const repoBranches = new Set(
|
|
883
|
+
const repoBranches = new Set(
|
|
884
|
+
(await runGit([
|
|
885
|
+
"for-each-ref",
|
|
886
|
+
"--format=%(refname:short)",
|
|
887
|
+
"refs/heads/"
|
|
888
|
+
])).trim().split(/\r?\n/)
|
|
889
|
+
);
|
|
691
890
|
const matchingBaseBranches = COMMON_BASE_BRANCHES.filter(
|
|
692
891
|
(b) => repoBranches.has(b)
|
|
693
892
|
);
|
|
@@ -695,7 +894,7 @@ async function getBaseBranch(remote = void 0) {
|
|
|
695
894
|
branch = matchingBaseBranches[0];
|
|
696
895
|
} else {
|
|
697
896
|
try {
|
|
698
|
-
const remoteInfo = await
|
|
897
|
+
const remoteInfo = await runGit(["remote", "show", remoteName]);
|
|
699
898
|
if (!remoteInfo) {
|
|
700
899
|
throw new Error(`Could not find remote ${remoteName}`);
|
|
701
900
|
}
|
|
@@ -713,27 +912,28 @@ async function getBaseBranch(remote = void 0) {
|
|
|
713
912
|
return _baseBranch;
|
|
714
913
|
}
|
|
715
914
|
async function getBaseBranchAncestor(remote = void 0) {
|
|
716
|
-
const
|
|
717
|
-
if (
|
|
915
|
+
const repoPath = await currentRepoPath();
|
|
916
|
+
if (!repoPath) {
|
|
718
917
|
throw new Error("Not in a git repo");
|
|
719
918
|
}
|
|
720
919
|
const { remote: remoteName, branch: baseBranch } = await getBaseBranch(remote);
|
|
721
|
-
const isDirty = (await
|
|
920
|
+
const isDirty = (await runGitCommand(["diff", "--name-only"], {
|
|
921
|
+
cwd: repoPath
|
|
922
|
+
})).trim().length > 0;
|
|
722
923
|
const head = isDirty ? "HEAD" : "HEAD^";
|
|
723
924
|
try {
|
|
724
|
-
const ancestor = await
|
|
725
|
-
"merge-base",
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
]);
|
|
925
|
+
const ancestor = await runGitCommand(
|
|
926
|
+
["merge-base", head, `${remoteName}/${baseBranch}`],
|
|
927
|
+
{ cwd: repoPath }
|
|
928
|
+
);
|
|
729
929
|
return ancestor.trim();
|
|
730
930
|
} catch {
|
|
731
931
|
return void 0;
|
|
732
932
|
}
|
|
733
933
|
}
|
|
734
934
|
async function getPastNAncestors(n = 1e3, remote = void 0) {
|
|
735
|
-
const
|
|
736
|
-
if (
|
|
935
|
+
const repoPath = await currentRepoPath();
|
|
936
|
+
if (!repoPath) {
|
|
737
937
|
return [];
|
|
738
938
|
}
|
|
739
939
|
let ancestor = void 0;
|
|
@@ -748,8 +948,10 @@ async function getPastNAncestors(n = 1e3, remote = void 0) {
|
|
|
748
948
|
if (!ancestor) {
|
|
749
949
|
return [];
|
|
750
950
|
}
|
|
751
|
-
const commits = await
|
|
752
|
-
|
|
951
|
+
const commits = (await runGitCommand(["rev-list", `--max-count=${n}`, `${ancestor}..HEAD`], {
|
|
952
|
+
cwd: repoPath
|
|
953
|
+
})).trim();
|
|
954
|
+
return commits ? commits.split(/\r?\n/).slice(0, n) : [];
|
|
753
955
|
}
|
|
754
956
|
async function attempt(fn) {
|
|
755
957
|
try {
|
|
@@ -780,9 +982,14 @@ async function getRepoInfo(settings) {
|
|
|
780
982
|
});
|
|
781
983
|
return sanitized;
|
|
782
984
|
}
|
|
985
|
+
async function currentRepoPath() {
|
|
986
|
+
return await attempt(
|
|
987
|
+
async () => (await runGitCommand(["rev-parse", "--show-toplevel"])).trim()
|
|
988
|
+
);
|
|
989
|
+
}
|
|
783
990
|
async function repoInfo() {
|
|
784
|
-
const
|
|
785
|
-
if (
|
|
991
|
+
const repoPath = await currentRepoPath();
|
|
992
|
+
if (!repoPath) {
|
|
786
993
|
return void 0;
|
|
787
994
|
}
|
|
788
995
|
let commit = void 0;
|
|
@@ -793,29 +1000,32 @@ async function repoInfo() {
|
|
|
793
1000
|
let tag = void 0;
|
|
794
1001
|
let branch = void 0;
|
|
795
1002
|
let git_diff = void 0;
|
|
796
|
-
const
|
|
797
|
-
|
|
1003
|
+
const runGit = async (args) => await runGitCommand(args, { cwd: repoPath });
|
|
1004
|
+
const dirty = (await runGit(["diff", "--name-only"])).trim().length > 0;
|
|
1005
|
+
commit = await attempt(
|
|
1006
|
+
async () => (await runGit(["rev-parse", "HEAD"])).trim()
|
|
1007
|
+
);
|
|
798
1008
|
commit_message = await attempt(
|
|
799
|
-
async () => (await
|
|
1009
|
+
async () => (await runGit(["log", "-1", "--pretty=%B"])).trim()
|
|
800
1010
|
);
|
|
801
1011
|
commit_time = await attempt(
|
|
802
|
-
async () => (await
|
|
1012
|
+
async () => (await runGit(["log", "-1", "--pretty=%cI"])).trim()
|
|
803
1013
|
);
|
|
804
1014
|
author_name = await attempt(
|
|
805
|
-
async () => (await
|
|
1015
|
+
async () => (await runGit(["log", "-1", "--pretty=%aN"])).trim()
|
|
806
1016
|
);
|
|
807
1017
|
author_email = await attempt(
|
|
808
|
-
async () => (await
|
|
1018
|
+
async () => (await runGit(["log", "-1", "--pretty=%aE"])).trim()
|
|
809
1019
|
);
|
|
810
1020
|
tag = await attempt(
|
|
811
|
-
async () => (await
|
|
1021
|
+
async () => (await runGit(["describe", "--tags", "--exact-match", "--always"])).trim()
|
|
812
1022
|
);
|
|
813
1023
|
branch = await attempt(
|
|
814
|
-
async () => (await
|
|
1024
|
+
async () => (await runGit(["rev-parse", "--abbrev-ref", "HEAD"])).trim()
|
|
815
1025
|
);
|
|
816
1026
|
if (dirty) {
|
|
817
1027
|
git_diff = await attempt(
|
|
818
|
-
async () => truncateToByteLimit(await
|
|
1028
|
+
async () => truncateToByteLimit(await runGit(["diff", "--no-ext-diff", "HEAD"]))
|
|
819
1029
|
);
|
|
820
1030
|
}
|
|
821
1031
|
return {
|
|
@@ -1896,15 +2106,15 @@ function mergeDictsWithPaths({
|
|
|
1896
2106
|
function mergeDictsWithPathsHelper({
|
|
1897
2107
|
mergeInto,
|
|
1898
2108
|
mergeFrom,
|
|
1899
|
-
path:
|
|
2109
|
+
path: path3,
|
|
1900
2110
|
mergePaths
|
|
1901
2111
|
}) {
|
|
1902
2112
|
Object.entries(mergeFrom).forEach(([k, mergeFromV]) => {
|
|
1903
2113
|
if (FORBIDDEN_MERGE_KEYS.has(k)) return;
|
|
1904
|
-
const fullPath =
|
|
2114
|
+
const fullPath = path3.concat([k]);
|
|
1905
2115
|
const fullPathSerialized = JSON.stringify(fullPath);
|
|
1906
2116
|
const mergeIntoV = recordFind(mergeInto, k);
|
|
1907
|
-
const isSetUnionField =
|
|
2117
|
+
const isSetUnionField = path3.length === 0 && SET_UNION_FIELDS.has(k) && !mergePaths.has(fullPathSerialized);
|
|
1908
2118
|
if (isSetUnionField && isArray(mergeIntoV) && isArray(mergeFromV)) {
|
|
1909
2119
|
const seen = /* @__PURE__ */ new Set();
|
|
1910
2120
|
const combined = [];
|
|
@@ -1937,9 +2147,9 @@ function mergeDicts(mergeInto, mergeFrom) {
|
|
|
1937
2147
|
function recordFind(m, k) {
|
|
1938
2148
|
return m[k];
|
|
1939
2149
|
}
|
|
1940
|
-
function getObjValueByPath(row,
|
|
2150
|
+
function getObjValueByPath(row, path3) {
|
|
1941
2151
|
let curr = row;
|
|
1942
|
-
for (const p of
|
|
2152
|
+
for (const p of path3) {
|
|
1943
2153
|
if (!isObjectOrArray(curr)) {
|
|
1944
2154
|
return null;
|
|
1945
2155
|
}
|
|
@@ -2566,7 +2776,8 @@ var AclObjectType = z6.union([
|
|
|
2566
2776
|
"org_member",
|
|
2567
2777
|
"project_log",
|
|
2568
2778
|
"org_project",
|
|
2569
|
-
"org_audit_logs"
|
|
2779
|
+
"org_audit_logs",
|
|
2780
|
+
"project_group"
|
|
2570
2781
|
]),
|
|
2571
2782
|
z6.null()
|
|
2572
2783
|
]);
|
|
@@ -2695,7 +2906,8 @@ var AsyncScoringState = z6.union([
|
|
|
2695
2906
|
token: z6.string(),
|
|
2696
2907
|
function_ids: z6.array(z6.unknown()),
|
|
2697
2908
|
skip_logging: z6.union([z6.boolean(), z6.null()]).optional(),
|
|
2698
|
-
triggered_functions: z6.union([z6.record(TriggeredFunctionState), z6.null()]).optional()
|
|
2909
|
+
triggered_functions: z6.union([z6.record(TriggeredFunctionState), z6.null()]).optional(),
|
|
2910
|
+
last_triggered_xact_id: z6.union([z6.string(), z6.number(), z6.null()]).optional()
|
|
2699
2911
|
}),
|
|
2700
2912
|
z6.object({ status: z6.literal("disabled") }),
|
|
2701
2913
|
z6.null(),
|
|
@@ -2764,7 +2976,7 @@ var FunctionTypeEnum = z6.enum([
|
|
|
2764
2976
|
"parameters",
|
|
2765
2977
|
"sandbox"
|
|
2766
2978
|
]);
|
|
2767
|
-
var
|
|
2979
|
+
var FacetPreprocessorId = z6.union([
|
|
2768
2980
|
z6.object({
|
|
2769
2981
|
type: z6.literal("function"),
|
|
2770
2982
|
id: z6.string(),
|
|
@@ -2775,10 +2987,23 @@ var NullableSavedFunctionId = z6.union([
|
|
|
2775
2987
|
name: z6.string(),
|
|
2776
2988
|
function_type: FunctionTypeEnum.optional().default("scorer")
|
|
2777
2989
|
}),
|
|
2990
|
+
z6.object({ type: z6.literal("inline"), code: z6.string().min(1) }),
|
|
2778
2991
|
z6.null()
|
|
2779
2992
|
]);
|
|
2993
|
+
var SavedFunctionId = z6.union([
|
|
2994
|
+
z6.object({
|
|
2995
|
+
type: z6.literal("function"),
|
|
2996
|
+
id: z6.string(),
|
|
2997
|
+
version: z6.string().optional()
|
|
2998
|
+
}),
|
|
2999
|
+
z6.object({
|
|
3000
|
+
type: z6.literal("global"),
|
|
3001
|
+
name: z6.string(),
|
|
3002
|
+
function_type: FunctionTypeEnum.optional().default("scorer")
|
|
3003
|
+
})
|
|
3004
|
+
]);
|
|
2780
3005
|
var TopicMapGenerationSettings = z6.object({
|
|
2781
|
-
algorithm: z6.enum(["hdbscan", "kmeans"]),
|
|
3006
|
+
algorithm: z6.enum(["hdbscan", "kmeans", "community"]),
|
|
2782
3007
|
dimension_reduction: z6.enum(["umap", "pca", "none"]),
|
|
2783
3008
|
sample_size: z6.number().int().gt(0).optional(),
|
|
2784
3009
|
n_clusters: z6.number().int().gt(0).optional(),
|
|
@@ -2790,6 +3015,7 @@ var TopicMapGenerationSettings = z6.object({
|
|
|
2790
3015
|
var TopicMapData = z6.object({
|
|
2791
3016
|
type: z6.literal("topic_map"),
|
|
2792
3017
|
source_facet: z6.string(),
|
|
3018
|
+
source_facet_function: SavedFunctionId.and(z6.unknown()).optional(),
|
|
2793
3019
|
embedding_model: z6.string(),
|
|
2794
3020
|
bundle_key: z6.string().optional(),
|
|
2795
3021
|
report_key: z6.string().optional(),
|
|
@@ -2803,7 +3029,7 @@ var TopicMapData = z6.object({
|
|
|
2803
3029
|
});
|
|
2804
3030
|
var BatchedFacetData = z6.object({
|
|
2805
3031
|
type: z6.literal("batched_facet"),
|
|
2806
|
-
preprocessor:
|
|
3032
|
+
preprocessor: FacetPreprocessorId.optional(),
|
|
2807
3033
|
facets: z6.array(
|
|
2808
3034
|
z6.object({
|
|
2809
3035
|
name: z6.string(),
|
|
@@ -3064,18 +3290,6 @@ var ObjectReferenceNullish = z6.union([
|
|
|
3064
3290
|
}),
|
|
3065
3291
|
z6.null()
|
|
3066
3292
|
]);
|
|
3067
|
-
var SavedFunctionId = z6.union([
|
|
3068
|
-
z6.object({
|
|
3069
|
-
type: z6.literal("function"),
|
|
3070
|
-
id: z6.string(),
|
|
3071
|
-
version: z6.string().optional()
|
|
3072
|
-
}),
|
|
3073
|
-
z6.object({
|
|
3074
|
-
type: z6.literal("global"),
|
|
3075
|
-
name: z6.string(),
|
|
3076
|
-
function_type: FunctionTypeEnum.optional().default("scorer")
|
|
3077
|
-
})
|
|
3078
|
-
]);
|
|
3079
3293
|
var DatasetEvent = z6.object({
|
|
3080
3294
|
id: z6.string(),
|
|
3081
3295
|
_xact_id: z6.string(),
|
|
@@ -3297,7 +3511,7 @@ var ExtendedSavedFunctionId = z6.union([
|
|
|
3297
3511
|
]);
|
|
3298
3512
|
var FacetData = z6.object({
|
|
3299
3513
|
type: z6.literal("facet"),
|
|
3300
|
-
preprocessor:
|
|
3514
|
+
preprocessor: FacetPreprocessorId.optional(),
|
|
3301
3515
|
prompt: z6.string(),
|
|
3302
3516
|
model: z6.string().optional(),
|
|
3303
3517
|
embedding_model: z6.string().optional(),
|
|
@@ -3802,6 +4016,19 @@ var MessageRole = z6.enum([
|
|
|
3802
4016
|
"model",
|
|
3803
4017
|
"developer"
|
|
3804
4018
|
]);
|
|
4019
|
+
var NullableSavedFunctionId = z6.union([
|
|
4020
|
+
z6.object({
|
|
4021
|
+
type: z6.literal("function"),
|
|
4022
|
+
id: z6.string(),
|
|
4023
|
+
version: z6.string().optional()
|
|
4024
|
+
}),
|
|
4025
|
+
z6.object({
|
|
4026
|
+
type: z6.literal("global"),
|
|
4027
|
+
name: z6.string(),
|
|
4028
|
+
function_type: FunctionTypeEnum.optional().default("scorer")
|
|
4029
|
+
}),
|
|
4030
|
+
z6.null()
|
|
4031
|
+
]);
|
|
3805
4032
|
var ObjectReference = z6.object({
|
|
3806
4033
|
object_type: z6.enum([
|
|
3807
4034
|
"project_logs",
|
|
@@ -3823,6 +4050,7 @@ var TraceScope = z6.object({
|
|
|
3823
4050
|
});
|
|
3824
4051
|
var OnlineScoreConfig = z6.union([
|
|
3825
4052
|
z6.object({
|
|
4053
|
+
status: AutomationStatus.optional(),
|
|
3826
4054
|
sampling_rate: z6.number().gte(0).lte(1),
|
|
3827
4055
|
scorers: z6.array(SavedFunctionId),
|
|
3828
4056
|
btql_filter: z6.union([z6.string(), z6.null()]).optional(),
|
|
@@ -3903,6 +4131,72 @@ var Project = z6.object({
|
|
|
3903
4131
|
user_id: z6.union([z6.string(), z6.null()]).optional(),
|
|
3904
4132
|
settings: ProjectSettings.optional()
|
|
3905
4133
|
});
|
|
4134
|
+
var WindowedAutomationConfig = z6.object({
|
|
4135
|
+
event_type: z6.literal("windowed"),
|
|
4136
|
+
product_origin: z6.union([z6.literal("patterns"), z6.null()]).optional(),
|
|
4137
|
+
status: AutomationStatus.optional(),
|
|
4138
|
+
threshold: z6.object({
|
|
4139
|
+
calculation: z6.object({
|
|
4140
|
+
type: z6.literal("btql"),
|
|
4141
|
+
btql_query: z6.string().min(1),
|
|
4142
|
+
output: z6.object({
|
|
4143
|
+
type: z6.literal("scalar"),
|
|
4144
|
+
value_column: z6.string().min(1)
|
|
4145
|
+
})
|
|
4146
|
+
}),
|
|
4147
|
+
policy: z6.object({
|
|
4148
|
+
condition: z6.object({
|
|
4149
|
+
type: z6.literal("threshold"),
|
|
4150
|
+
operator: z6.enum(["lt", "lte", "gt", "gte", "eq", "neq"]),
|
|
4151
|
+
threshold: z6.number()
|
|
4152
|
+
}),
|
|
4153
|
+
pending_seconds: z6.number().int().gte(0).lte(2592e3),
|
|
4154
|
+
no_data_behavior: z6.enum(["keep_last", "resolve", "alert"]),
|
|
4155
|
+
renotify_interval_seconds: z6.union([z6.number(), z6.null()]).optional(),
|
|
4156
|
+
notify_on_recovery: z6.boolean().optional().default(true)
|
|
4157
|
+
})
|
|
4158
|
+
}).optional(),
|
|
4159
|
+
window: z6.object({
|
|
4160
|
+
window_seconds: z6.number().int().gte(1).lte(2592e3),
|
|
4161
|
+
schedule: z6.union([
|
|
4162
|
+
z6.object({
|
|
4163
|
+
type: z6.literal("interval"),
|
|
4164
|
+
evaluation_interval_seconds: z6.number().int().gte(1).lte(2592e3)
|
|
4165
|
+
}),
|
|
4166
|
+
z6.object({
|
|
4167
|
+
type: z6.literal("cron"),
|
|
4168
|
+
cron_expression: z6.string().min(1),
|
|
4169
|
+
timezone: z6.union([z6.string(), z6.null()]).optional()
|
|
4170
|
+
})
|
|
4171
|
+
]),
|
|
4172
|
+
evaluation_delay_seconds: z6.number().int().gte(0).lte(2592e3)
|
|
4173
|
+
}),
|
|
4174
|
+
loop: z6.object({
|
|
4175
|
+
prompt: z6.string().min(1).max(1e4),
|
|
4176
|
+
include_trigger_input: z6.boolean().optional().default(false),
|
|
4177
|
+
agent_slug: z6.string().min(1),
|
|
4178
|
+
auto_approve_tools: z6.array(z6.string().min(1)).optional().default([]),
|
|
4179
|
+
harness: z6.enum(["native", "codex", "claude-code"]).optional(),
|
|
4180
|
+
model: z6.string().min(1).optional(),
|
|
4181
|
+
reasoning_effort: z6.enum(["none", "minimal", "low", "medium", "high", "xhigh", "max"]).optional()
|
|
4182
|
+
}).optional(),
|
|
4183
|
+
actions: z6.array(
|
|
4184
|
+
z6.union([
|
|
4185
|
+
z6.object({
|
|
4186
|
+
type: z6.literal("webhook"),
|
|
4187
|
+
url: z6.string(),
|
|
4188
|
+
formatting_prompt: z6.string().min(1).max(1e4).optional()
|
|
4189
|
+
}),
|
|
4190
|
+
z6.object({
|
|
4191
|
+
type: z6.literal("slack"),
|
|
4192
|
+
workspace_id: z6.string(),
|
|
4193
|
+
channel: z6.string(),
|
|
4194
|
+
message_template: z6.string().optional(),
|
|
4195
|
+
formatting_prompt: z6.string().min(1).max(1e4).optional()
|
|
4196
|
+
})
|
|
4197
|
+
])
|
|
4198
|
+
).max(20).optional().default([])
|
|
4199
|
+
});
|
|
3906
4200
|
var TopicAutomationFacetModel = z6.union([
|
|
3907
4201
|
z6.enum(["brain-facet-latest", "brain-facet-1", "brain-facet-2"]),
|
|
3908
4202
|
z6.null()
|
|
@@ -3944,7 +4238,8 @@ var TopicDigestAutomationConfig = z6.object({
|
|
|
3944
4238
|
type: z6.literal("slack"),
|
|
3945
4239
|
workspace_id: z6.string(),
|
|
3946
4240
|
channel: z6.string(),
|
|
3947
|
-
message_template: z6.string().optional()
|
|
4241
|
+
message_template: z6.string().optional(),
|
|
4242
|
+
formatting_prompt: z6.string().min(1).max(1e4).optional()
|
|
3948
4243
|
}),
|
|
3949
4244
|
topic_map_function_ids: z6.array(z6.string()).max(10).optional()
|
|
3950
4245
|
});
|
|
@@ -3958,15 +4253,21 @@ var ProjectAutomation = z6.object({
|
|
|
3958
4253
|
config: z6.union([
|
|
3959
4254
|
z6.object({
|
|
3960
4255
|
event_type: z6.literal("logs"),
|
|
4256
|
+
status: AutomationStatus.optional(),
|
|
3961
4257
|
btql_filter: z6.string(),
|
|
3962
4258
|
interval_seconds: z6.number().gte(1).lte(2592e3),
|
|
3963
4259
|
action: z6.union([
|
|
3964
|
-
z6.object({
|
|
4260
|
+
z6.object({
|
|
4261
|
+
type: z6.literal("webhook"),
|
|
4262
|
+
url: z6.string(),
|
|
4263
|
+
formatting_prompt: z6.string().min(1).max(1e4).optional()
|
|
4264
|
+
}),
|
|
3965
4265
|
z6.object({
|
|
3966
4266
|
type: z6.literal("slack"),
|
|
3967
4267
|
workspace_id: z6.string(),
|
|
3968
4268
|
channel: z6.string(),
|
|
3969
|
-
message_template: z6.string().optional()
|
|
4269
|
+
message_template: z6.string().optional(),
|
|
4270
|
+
formatting_prompt: z6.string().min(1).max(1e4).optional()
|
|
3970
4271
|
})
|
|
3971
4272
|
])
|
|
3972
4273
|
}),
|
|
@@ -4017,21 +4318,38 @@ var ProjectAutomation = z6.object({
|
|
|
4017
4318
|
}),
|
|
4018
4319
|
z6.object({
|
|
4019
4320
|
event_type: z6.literal("environment_update"),
|
|
4321
|
+
status: AutomationStatus.optional(),
|
|
4020
4322
|
environment_filter: z6.array(z6.string()).optional(),
|
|
4021
4323
|
action: z6.union([
|
|
4022
|
-
z6.object({
|
|
4324
|
+
z6.object({
|
|
4325
|
+
type: z6.literal("webhook"),
|
|
4326
|
+
url: z6.string(),
|
|
4327
|
+
formatting_prompt: z6.string().min(1).max(1e4).optional()
|
|
4328
|
+
}),
|
|
4023
4329
|
z6.object({
|
|
4024
4330
|
type: z6.literal("slack"),
|
|
4025
4331
|
workspace_id: z6.string(),
|
|
4026
4332
|
channel: z6.string(),
|
|
4027
|
-
message_template: z6.string().optional()
|
|
4333
|
+
message_template: z6.string().optional(),
|
|
4334
|
+
formatting_prompt: z6.string().min(1).max(1e4).optional()
|
|
4028
4335
|
})
|
|
4029
4336
|
])
|
|
4030
4337
|
}),
|
|
4338
|
+
WindowedAutomationConfig,
|
|
4031
4339
|
TopicAutomationConfig,
|
|
4032
4340
|
TopicDigestAutomationConfig
|
|
4033
4341
|
])
|
|
4034
4342
|
});
|
|
4343
|
+
var ProjectGroup = z6.object({
|
|
4344
|
+
id: z6.string().uuid(),
|
|
4345
|
+
org_id: z6.string().uuid(),
|
|
4346
|
+
user_id: z6.union([z6.string(), z6.null()]).optional(),
|
|
4347
|
+
created: z6.union([z6.string(), z6.null()]).optional(),
|
|
4348
|
+
name: z6.string(),
|
|
4349
|
+
description: z6.union([z6.string(), z6.null()]).optional(),
|
|
4350
|
+
deleted_at: z6.union([z6.string(), z6.null()]).optional(),
|
|
4351
|
+
member_projects: z6.array(z6.string().uuid()).max(1e4)
|
|
4352
|
+
});
|
|
4035
4353
|
var ProjectLogsEvent = z6.object({
|
|
4036
4354
|
id: z6.string(),
|
|
4037
4355
|
_xact_id: z6.string(),
|
|
@@ -4249,7 +4567,8 @@ var RunEval = z6.object({
|
|
|
4249
4567
|
dataset_environment: z6.union([z6.string(), z6.null()]).optional(),
|
|
4250
4568
|
_internal_btql: z6.union([z6.object({}).partial().passthrough(), z6.null()]).optional()
|
|
4251
4569
|
}),
|
|
4252
|
-
z6.object({ data: z6.array(z6.unknown()) })
|
|
4570
|
+
z6.object({ data: z6.array(z6.unknown()) }),
|
|
4571
|
+
z6.object({ experiment_name: z6.string() })
|
|
4253
4572
|
]),
|
|
4254
4573
|
name: z6.string().optional(),
|
|
4255
4574
|
parameters: z6.object({}).partial().passthrough().optional(),
|
|
@@ -4454,7 +4773,9 @@ var View = z6.object({
|
|
|
4454
4773
|
"for_review_datasets"
|
|
4455
4774
|
]),
|
|
4456
4775
|
name: z6.string(),
|
|
4776
|
+
description: z6.union([z6.string(), z6.null()]).optional(),
|
|
4457
4777
|
created: z6.union([z6.string(), z6.null()]).optional(),
|
|
4778
|
+
updated_at: z6.union([z6.string(), z6.null()]).optional(),
|
|
4458
4779
|
view_data: ViewData.optional(),
|
|
4459
4780
|
options: ViewOptions.optional(),
|
|
4460
4781
|
user_id: z6.union([z6.string(), z6.null()]).optional(),
|
|
@@ -4981,10 +5302,10 @@ var DiskCache = class {
|
|
|
4981
5302
|
return;
|
|
4982
5303
|
}
|
|
4983
5304
|
const stats = await Promise.all(
|
|
4984
|
-
paths.map(async (
|
|
4985
|
-
const stat2 = await isomorph_default.stat(
|
|
5305
|
+
paths.map(async (path3) => {
|
|
5306
|
+
const stat2 = await isomorph_default.stat(path3);
|
|
4986
5307
|
return {
|
|
4987
|
-
path:
|
|
5308
|
+
path: path3,
|
|
4988
5309
|
mtime: stat2.mtime.getTime()
|
|
4989
5310
|
};
|
|
4990
5311
|
})
|
|
@@ -5559,6 +5880,7 @@ var INSTRUMENTATION_NAMES = {
|
|
|
5559
5880
|
CLAUDE_AGENT_SDK: "claude-agent-sdk",
|
|
5560
5881
|
CLOUDFLARE_AI_CHAT: "cloudflare-ai-chat",
|
|
5561
5882
|
CLOUDFLARE_AGENTS: "cloudflare-agents",
|
|
5883
|
+
CLOUDFLARE_THINK: "cloudflare-think",
|
|
5562
5884
|
COHERE: "cohere",
|
|
5563
5885
|
CURSOR_SDK: "cursor-sdk",
|
|
5564
5886
|
EVE: "eve",
|
|
@@ -5573,18 +5895,20 @@ var INSTRUMENTATION_NAMES = {
|
|
|
5573
5895
|
LANGSMITH: "langsmith",
|
|
5574
5896
|
MASTRA: "mastra",
|
|
5575
5897
|
MISTRAL: "mistral",
|
|
5898
|
+
OLLAMA: "ollama",
|
|
5576
5899
|
OPENAI: "openai",
|
|
5577
5900
|
OPENAI_AGENTS: "openai-agents",
|
|
5578
5901
|
OPENAI_CODEX: "openai-codex",
|
|
5579
5902
|
OPENROUTER: "openrouter",
|
|
5580
5903
|
OPENROUTER_AGENT: "openrouter-agent",
|
|
5581
5904
|
PI_CODING_AGENT: "pi-coding-agent",
|
|
5582
|
-
STRANDS_AGENT_SDK: "strands-agent-sdk"
|
|
5905
|
+
STRANDS_AGENT_SDK: "strands-agent-sdk",
|
|
5906
|
+
VOYAGEAI: "voyageai"
|
|
5583
5907
|
};
|
|
5584
5908
|
var INTERNAL_SPAN_INSTRUMENTATION_NAME = /* @__PURE__ */ Symbol.for(
|
|
5585
5909
|
"braintrust.spanInstrumentationName"
|
|
5586
5910
|
);
|
|
5587
|
-
var SDK_VERSION = true ? "3.
|
|
5911
|
+
var SDK_VERSION = true ? "3.28.0" : "0.0.0";
|
|
5588
5912
|
function withSpanInstrumentationName(args, instrumentationName) {
|
|
5589
5913
|
return {
|
|
5590
5914
|
...args,
|
|
@@ -5779,6 +6103,9 @@ function applyMaskingToField(maskingFunction, data, fieldName) {
|
|
|
5779
6103
|
var INITIAL_SPAN_WRITE_AS_MERGE = /* @__PURE__ */ Symbol(
|
|
5780
6104
|
"braintrust.initial-span-write-as-merge"
|
|
5781
6105
|
);
|
|
6106
|
+
var RESUME_SPAN_WITHOUT_INITIAL_WRITE = /* @__PURE__ */ Symbol(
|
|
6107
|
+
"braintrust.resume-span-without-initial-write"
|
|
6108
|
+
);
|
|
5782
6109
|
var INTERNAL_SPAN_CONTEXT = /* @__PURE__ */ Symbol("braintrust.internal-span-context");
|
|
5783
6110
|
var BRAINTRUST_CURRENT_SPAN_STORE = /* @__PURE__ */ Symbol.for(
|
|
5784
6111
|
"braintrust.currentSpanStore"
|
|
@@ -6344,9 +6671,9 @@ var HTTPConnection = class _HTTPConnection {
|
|
|
6344
6671
|
this.headers["Authorization"] = `Bearer ${this.token}`;
|
|
6345
6672
|
}
|
|
6346
6673
|
}
|
|
6347
|
-
async get(
|
|
6674
|
+
async get(path3, params = void 0, config) {
|
|
6348
6675
|
const { headers, ...rest } = config || {};
|
|
6349
|
-
const url = new URL(_urljoin(this.base_url,
|
|
6676
|
+
const url = new URL(_urljoin(this.base_url, path3));
|
|
6350
6677
|
url.search = new URLSearchParams(
|
|
6351
6678
|
params ? Object.entries(params).filter(([_, v]) => v !== void 0).flatMap(
|
|
6352
6679
|
([k, v]) => v !== void 0 ? typeof v === "string" ? [[k, v]] : v.map((x) => [k, x]) : []
|
|
@@ -6367,7 +6694,7 @@ var HTTPConnection = class _HTTPConnection {
|
|
|
6367
6694
|
})
|
|
6368
6695
|
);
|
|
6369
6696
|
}
|
|
6370
|
-
async post(
|
|
6697
|
+
async post(path3, params, config, retries = 0) {
|
|
6371
6698
|
const { headers, ...rest } = config || {};
|
|
6372
6699
|
const this_fetch = this.fetch;
|
|
6373
6700
|
const this_base_url = this.base_url;
|
|
@@ -6376,7 +6703,7 @@ var HTTPConnection = class _HTTPConnection {
|
|
|
6376
6703
|
for (let i = 0; i < tries; i++) {
|
|
6377
6704
|
try {
|
|
6378
6705
|
return await checkResponse(
|
|
6379
|
-
await this_fetch(_urljoin(this_base_url,
|
|
6706
|
+
await this_fetch(_urljoin(this_base_url, path3), {
|
|
6380
6707
|
method: "POST",
|
|
6381
6708
|
headers: {
|
|
6382
6709
|
Accept: "application/json",
|
|
@@ -6397,7 +6724,7 @@ var HTTPConnection = class _HTTPConnection {
|
|
|
6397
6724
|
throw error;
|
|
6398
6725
|
}
|
|
6399
6726
|
debugLogger.debug(
|
|
6400
|
-
`Retrying API request ${
|
|
6727
|
+
`Retrying API request ${path3} after ${formatHTTPError(error)}`
|
|
6401
6728
|
);
|
|
6402
6729
|
const sleepTimeMs = HTTP_RETRY_BASE_SLEEP_TIME_S * 1e3 * 2 ** i + Math.random() * HTTP_RETRY_JITTER_MS;
|
|
6403
6730
|
debugLogger.info(
|
|
@@ -9162,7 +9489,7 @@ var ObjectFetcher = class {
|
|
|
9162
9489
|
const objectId = await this.id;
|
|
9163
9490
|
const batchLimit = batchSize ?? DEFAULT_FETCH_BATCH_SIZE;
|
|
9164
9491
|
const internalLimit = getInternalBtqlLimit(this._internal_btql);
|
|
9165
|
-
|
|
9492
|
+
let remainingLimit = internalLimit;
|
|
9166
9493
|
const internalBtqlWithoutReservedQueryKeys = Object.fromEntries(
|
|
9167
9494
|
Object.entries(this._internal_btql ?? {}).filter(
|
|
9168
9495
|
([key]) => key !== "cursor" && key !== "limit" && key !== "select" && key !== "from"
|
|
@@ -9171,6 +9498,10 @@ var ObjectFetcher = class {
|
|
|
9171
9498
|
let cursor = void 0;
|
|
9172
9499
|
let iterations = 0;
|
|
9173
9500
|
while (true) {
|
|
9501
|
+
if (remainingLimit !== void 0 && remainingLimit <= 0) {
|
|
9502
|
+
return;
|
|
9503
|
+
}
|
|
9504
|
+
const limit = remainingLimit === void 0 ? batchLimit : Math.min(batchLimit, remainingLimit);
|
|
9174
9505
|
const resp = await state.apiConn().post(
|
|
9175
9506
|
`btql`,
|
|
9176
9507
|
{
|
|
@@ -9210,7 +9541,14 @@ var ObjectFetcher = class {
|
|
|
9210
9541
|
const respJson = await resp.json();
|
|
9211
9542
|
const mutate = this.mutateRecord;
|
|
9212
9543
|
for (const record of respJson.data ?? []) {
|
|
9213
|
-
|
|
9544
|
+
if (remainingLimit !== void 0 && remainingLimit <= 0) {
|
|
9545
|
+
return;
|
|
9546
|
+
}
|
|
9547
|
+
const mutatedRecord = mutate ? mutate(record) : record;
|
|
9548
|
+
if (remainingLimit !== void 0) {
|
|
9549
|
+
remainingLimit--;
|
|
9550
|
+
}
|
|
9551
|
+
yield mutatedRecord;
|
|
9214
9552
|
}
|
|
9215
9553
|
if (!respJson.cursor) {
|
|
9216
9554
|
break;
|
|
@@ -9730,7 +10068,9 @@ var SpanImpl = class _SpanImpl {
|
|
|
9730
10068
|
this._rootSpanId = resolvedIds.rootSpanId;
|
|
9731
10069
|
this._spanParents = resolvedIds.spanParents;
|
|
9732
10070
|
this.isMerge = args[INITIAL_SPAN_WRITE_AS_MERGE] === true;
|
|
9733
|
-
|
|
10071
|
+
if (!args[RESUME_SPAN_WITHOUT_INITIAL_WRITE]) {
|
|
10072
|
+
this.logInternal({ event, internalData });
|
|
10073
|
+
}
|
|
9734
10074
|
this.isMerge = true;
|
|
9735
10075
|
}
|
|
9736
10076
|
getParentInfo() {
|
|
@@ -10905,6 +11245,34 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
10905
11245
|
);
|
|
10906
11246
|
return stream;
|
|
10907
11247
|
}
|
|
11248
|
+
const chunks = [];
|
|
11249
|
+
let completed = false;
|
|
11250
|
+
const notifyCancellation = async () => {
|
|
11251
|
+
try {
|
|
11252
|
+
await (options.onCancel ?? options.onComplete)(chunks);
|
|
11253
|
+
} catch (error) {
|
|
11254
|
+
debugLogger.error("Error in stream cancellation handler:", error);
|
|
11255
|
+
}
|
|
11256
|
+
};
|
|
11257
|
+
const patchAbortIfPresent = () => {
|
|
11258
|
+
try {
|
|
11259
|
+
if ("abort" in stream && typeof stream.abort === "function") {
|
|
11260
|
+
const originalAbort = stream.abort.bind(stream);
|
|
11261
|
+
stream.abort = (...args) => {
|
|
11262
|
+
try {
|
|
11263
|
+
return originalAbort(...args);
|
|
11264
|
+
} finally {
|
|
11265
|
+
if (!completed) {
|
|
11266
|
+
completed = true;
|
|
11267
|
+
void notifyCancellation();
|
|
11268
|
+
}
|
|
11269
|
+
}
|
|
11270
|
+
};
|
|
11271
|
+
}
|
|
11272
|
+
} catch (error) {
|
|
11273
|
+
debugLogger.warn("Failed to patch stream abort method:", error);
|
|
11274
|
+
}
|
|
11275
|
+
};
|
|
10908
11276
|
if (hasAsyncIteratorMethods(stream) && isSelfAsyncIterator(stream)) {
|
|
10909
11277
|
if ("__braintrust_patched_iterator_methods" in stream) {
|
|
10910
11278
|
return stream;
|
|
@@ -10913,8 +11281,6 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
10913
11281
|
const originalNext = stream.next.bind(stream);
|
|
10914
11282
|
const originalReturn = typeof stream.return === "function" ? stream.return.bind(stream) : null;
|
|
10915
11283
|
const originalThrow = typeof stream.throw === "function" ? stream.throw.bind(stream) : null;
|
|
10916
|
-
const chunks = [];
|
|
10917
|
-
let completed = false;
|
|
10918
11284
|
stream.next = async (...args) => {
|
|
10919
11285
|
try {
|
|
10920
11286
|
const result = await runNextWithWrapper(
|
|
@@ -10966,11 +11332,7 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
10966
11332
|
stream.return = async (...args) => {
|
|
10967
11333
|
if (!completed) {
|
|
10968
11334
|
completed = true;
|
|
10969
|
-
|
|
10970
|
-
await options.onComplete(chunks);
|
|
10971
|
-
} catch (error) {
|
|
10972
|
-
console.error("Error in stream onComplete handler:", error);
|
|
10973
|
-
}
|
|
11335
|
+
await notifyCancellation();
|
|
10974
11336
|
}
|
|
10975
11337
|
return originalReturn(...args);
|
|
10976
11338
|
};
|
|
@@ -10995,6 +11357,7 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
10995
11357
|
Object.defineProperty(stream, "__braintrust_patched_iterator_methods", {
|
|
10996
11358
|
value: true
|
|
10997
11359
|
});
|
|
11360
|
+
patchAbortIfPresent();
|
|
10998
11361
|
return stream;
|
|
10999
11362
|
} catch (error) {
|
|
11000
11363
|
console.warn("Failed to patch stream iterator methods:", error);
|
|
@@ -11008,8 +11371,6 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
11008
11371
|
const patchedIteratorFn = function() {
|
|
11009
11372
|
const iterator = originalIteratorFn.call(this);
|
|
11010
11373
|
const originalNext = iterator.next.bind(iterator);
|
|
11011
|
-
const chunks = [];
|
|
11012
|
-
let completed = false;
|
|
11013
11374
|
iterator.next = async function(...args) {
|
|
11014
11375
|
try {
|
|
11015
11376
|
const result = await runNextWithWrapper(
|
|
@@ -11062,11 +11423,7 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
11062
11423
|
iterator.return = async function(...args) {
|
|
11063
11424
|
if (!completed) {
|
|
11064
11425
|
completed = true;
|
|
11065
|
-
|
|
11066
|
-
await options.onComplete(chunks);
|
|
11067
|
-
} catch (error) {
|
|
11068
|
-
console.error("Error in stream onComplete handler:", error);
|
|
11069
|
-
}
|
|
11426
|
+
await notifyCancellation();
|
|
11070
11427
|
}
|
|
11071
11428
|
return originalReturn(...args);
|
|
11072
11429
|
};
|
|
@@ -11095,6 +11452,7 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
11095
11452
|
value: true
|
|
11096
11453
|
});
|
|
11097
11454
|
stream[Symbol.asyncIterator] = patchedIteratorFn;
|
|
11455
|
+
patchAbortIfPresent();
|
|
11098
11456
|
return stream;
|
|
11099
11457
|
} catch (error) {
|
|
11100
11458
|
console.warn("Failed to patch stream:", error);
|
|
@@ -11843,6 +12201,33 @@ function traceStreamingChannel(channel2, config) {
|
|
|
11843
12201
|
const { span, startTime } = spanData;
|
|
11844
12202
|
if (isAsyncIterable(asyncEndEvent.result)) {
|
|
11845
12203
|
let firstChunkTime;
|
|
12204
|
+
const handleStreamError = (error) => {
|
|
12205
|
+
try {
|
|
12206
|
+
span.log({ error });
|
|
12207
|
+
} catch (loggingError) {
|
|
12208
|
+
debugLogger.error(
|
|
12209
|
+
`Error logging failure for ${channelName}:`,
|
|
12210
|
+
loggingError
|
|
12211
|
+
);
|
|
12212
|
+
}
|
|
12213
|
+
try {
|
|
12214
|
+
span.end();
|
|
12215
|
+
} catch (endingError) {
|
|
12216
|
+
debugLogger.error(
|
|
12217
|
+
`Error ending span for ${channelName}:`,
|
|
12218
|
+
endingError
|
|
12219
|
+
);
|
|
12220
|
+
}
|
|
12221
|
+
states.delete(event);
|
|
12222
|
+
runStreamingErrorHook({
|
|
12223
|
+
channelName,
|
|
12224
|
+
config,
|
|
12225
|
+
error,
|
|
12226
|
+
event: asyncEndEvent,
|
|
12227
|
+
span,
|
|
12228
|
+
startTime
|
|
12229
|
+
});
|
|
12230
|
+
};
|
|
11846
12231
|
patchStreamIfNeeded(asyncEndEvent.result, {
|
|
11847
12232
|
onChunk: () => {
|
|
11848
12233
|
if (firstChunkTime === void 0) {
|
|
@@ -11922,33 +12307,12 @@ function traceStreamingChannel(channel2, config) {
|
|
|
11922
12307
|
});
|
|
11923
12308
|
}
|
|
11924
12309
|
},
|
|
11925
|
-
|
|
11926
|
-
|
|
11927
|
-
|
|
11928
|
-
|
|
11929
|
-
|
|
11930
|
-
|
|
11931
|
-
loggingError
|
|
11932
|
-
);
|
|
11933
|
-
}
|
|
11934
|
-
try {
|
|
11935
|
-
span.end();
|
|
11936
|
-
} catch (endingError) {
|
|
11937
|
-
debugLogger.error(
|
|
11938
|
-
`Error ending span for ${channelName}:`,
|
|
11939
|
-
endingError
|
|
11940
|
-
);
|
|
11941
|
-
}
|
|
11942
|
-
states.delete(event);
|
|
11943
|
-
runStreamingErrorHook({
|
|
11944
|
-
channelName,
|
|
11945
|
-
config,
|
|
11946
|
-
error,
|
|
11947
|
-
event: asyncEndEvent,
|
|
11948
|
-
span,
|
|
11949
|
-
startTime
|
|
11950
|
-
});
|
|
11951
|
-
}
|
|
12310
|
+
onCancel: () => {
|
|
12311
|
+
const error = new Error("Stream cancelled before completion");
|
|
12312
|
+
error.name = "AbortError";
|
|
12313
|
+
handleStreamError(error);
|
|
12314
|
+
},
|
|
12315
|
+
onError: handleStreamError
|
|
11952
12316
|
});
|
|
11953
12317
|
return;
|
|
11954
12318
|
}
|
|
@@ -12264,6 +12628,22 @@ function processInputAttachments(input) {
|
|
|
12264
12628
|
};
|
|
12265
12629
|
}
|
|
12266
12630
|
}
|
|
12631
|
+
const voyageBase64Key = node.type === "image_base64" ? Object.hasOwn(node, "imageBase64") ? "imageBase64" : "image_base64" : node.type === "video_base64" ? Object.hasOwn(node, "videoBase64") ? "videoBase64" : "video_base64" : void 0;
|
|
12632
|
+
const voyageBase64Value = voyageBase64Key ? node[voyageBase64Key] : void 0;
|
|
12633
|
+
if (voyageBase64Key && typeof voyageBase64Value === "string" && voyageBase64Value.startsWith("data:")) {
|
|
12634
|
+
const mediaType = inferMediaTypeFromDataUrl(
|
|
12635
|
+
voyageBase64Value,
|
|
12636
|
+
node.type === "video_base64" ? "video/mp4" : "image/png"
|
|
12637
|
+
);
|
|
12638
|
+
const filename = `${node.type === "video_base64" ? "video" : "image"}.${getExtensionFromMediaType(mediaType)}`;
|
|
12639
|
+
const attachment = toAttachment(voyageBase64Value, mediaType, filename);
|
|
12640
|
+
if (attachment) {
|
|
12641
|
+
return {
|
|
12642
|
+
...node,
|
|
12643
|
+
[voyageBase64Key]: attachment
|
|
12644
|
+
};
|
|
12645
|
+
}
|
|
12646
|
+
}
|
|
12267
12647
|
if (node.type === "file" && node.file && typeof node.file === "object" && typeof node.file.file_data === "string" && node.file.file_data.startsWith("data:")) {
|
|
12268
12648
|
const mediaType = inferMediaTypeFromDataUrl(
|
|
12269
12649
|
node.file.file_data,
|
|
@@ -12336,11 +12716,21 @@ function defineChannels(pkg, channels, options) {
|
|
|
12336
12716
|
const tracingChannel2 = () => isomorph_default.newTracingChannel(
|
|
12337
12717
|
fullChannelName
|
|
12338
12718
|
);
|
|
12719
|
+
const intercept2 = (interceptor) => {
|
|
12720
|
+
const hook = tracingChannel2();
|
|
12721
|
+
return typeof hook.intercept === "function" ? hook.intercept(interceptor) : () => {
|
|
12722
|
+
};
|
|
12723
|
+
};
|
|
12339
12724
|
return [
|
|
12340
12725
|
key,
|
|
12341
12726
|
{
|
|
12342
12727
|
...asyncSpec,
|
|
12343
12728
|
instrumentationName,
|
|
12729
|
+
intercept: intercept2,
|
|
12730
|
+
invoke: (target, thisArg, args, additional) => {
|
|
12731
|
+
const hook = tracingChannel2();
|
|
12732
|
+
return typeof hook.invoke === "function" ? hook.invoke(target, thisArg, args, additional) : Reflect.apply(target, thisArg, args);
|
|
12733
|
+
},
|
|
12344
12734
|
tracingChannel: tracingChannel2,
|
|
12345
12735
|
tracePromise: (fn, context) => tracingChannel2().tracePromise(
|
|
12346
12736
|
fn,
|
|
@@ -12354,11 +12744,21 @@ function defineChannels(pkg, channels, options) {
|
|
|
12354
12744
|
const tracingChannel = () => isomorph_default.newTracingChannel(
|
|
12355
12745
|
fullChannelName
|
|
12356
12746
|
);
|
|
12747
|
+
const intercept = (interceptor) => {
|
|
12748
|
+
const hook = tracingChannel();
|
|
12749
|
+
return typeof hook.intercept === "function" ? hook.intercept(interceptor) : () => {
|
|
12750
|
+
};
|
|
12751
|
+
};
|
|
12357
12752
|
return [
|
|
12358
12753
|
key,
|
|
12359
12754
|
{
|
|
12360
12755
|
...syncSpec,
|
|
12361
12756
|
instrumentationName,
|
|
12757
|
+
intercept,
|
|
12758
|
+
invoke: (target, thisArg, args, additional) => {
|
|
12759
|
+
const hook = tracingChannel();
|
|
12760
|
+
return typeof hook.invoke === "function" ? hook.invoke(target, thisArg, args, additional) : Reflect.apply(target, thisArg, args);
|
|
12761
|
+
},
|
|
12362
12762
|
tracingChannel,
|
|
12363
12763
|
traceSync: (fn, context) => tracingChannel().traceSync(
|
|
12364
12764
|
fn,
|
|
@@ -13591,12 +13991,30 @@ function logInstrumentationError(context, error) {
|
|
|
13591
13991
|
|
|
13592
13992
|
// src/wrappers/anthropic-tokens-util.ts
|
|
13593
13993
|
function finalizeAnthropicTokens(metrics) {
|
|
13594
|
-
const
|
|
13595
|
-
|
|
13994
|
+
const hasSplitCacheCreationTokens = metrics.prompt_cache_creation_5m_tokens !== void 0 || metrics.prompt_cache_creation_1h_tokens !== void 0;
|
|
13995
|
+
const splitCacheCreationTokens = (metrics.prompt_cache_creation_5m_tokens || 0) + (metrics.prompt_cache_creation_1h_tokens || 0);
|
|
13996
|
+
const aggregateCacheCreationTokens = metrics.prompt_cache_creation_tokens || 0;
|
|
13997
|
+
const effectiveCacheCreationTokens = Math.max(
|
|
13998
|
+
aggregateCacheCreationTokens,
|
|
13999
|
+
splitCacheCreationTokens
|
|
14000
|
+
);
|
|
14001
|
+
const prompt_tokens = (metrics.prompt_tokens || 0) + (metrics.prompt_cached_tokens || 0) + effectiveCacheCreationTokens;
|
|
14002
|
+
const finalized = {
|
|
13596
14003
|
...metrics,
|
|
13597
14004
|
prompt_tokens,
|
|
13598
14005
|
tokens: prompt_tokens + (metrics.completion_tokens || 0)
|
|
13599
14006
|
};
|
|
14007
|
+
if (hasSplitCacheCreationTokens && splitCacheCreationTokens >= aggregateCacheCreationTokens) {
|
|
14008
|
+
delete finalized.prompt_cache_creation_tokens;
|
|
14009
|
+
}
|
|
14010
|
+
return finalized;
|
|
14011
|
+
}
|
|
14012
|
+
function toNumericMetrics(metrics) {
|
|
14013
|
+
return Object.fromEntries(
|
|
14014
|
+
Object.entries(metrics).filter(
|
|
14015
|
+
(entry) => entry[1] !== void 0
|
|
14016
|
+
)
|
|
14017
|
+
);
|
|
13600
14018
|
}
|
|
13601
14019
|
function extractAnthropicCacheTokens(cacheReadTokens = 0, cacheCreationTokens = 0) {
|
|
13602
14020
|
const cacheTokens = {};
|
|
@@ -13609,6 +14027,12 @@ function extractAnthropicCacheTokens(cacheReadTokens = 0, cacheCreationTokens =
|
|
|
13609
14027
|
return cacheTokens;
|
|
13610
14028
|
}
|
|
13611
14029
|
|
|
14030
|
+
// src/wrappers/anthropic-session-collector.ts
|
|
14031
|
+
var sessionStreamCollectors = /* @__PURE__ */ new WeakMap();
|
|
14032
|
+
function registerAnthropicSessionStreamCollector(stream, collector) {
|
|
14033
|
+
sessionStreamCollectors.set(stream, collector);
|
|
14034
|
+
}
|
|
14035
|
+
|
|
13612
14036
|
// src/instrumentation/plugins/anthropic-channels.ts
|
|
13613
14037
|
var anthropicChannels = defineChannels(
|
|
13614
14038
|
"@anthropic-ai/sdk",
|
|
@@ -13624,6 +14048,14 @@ var anthropicChannels = defineChannels(
|
|
|
13624
14048
|
betaMessagesToolRunner: channel({
|
|
13625
14049
|
channelName: "beta.messages.toolRunner",
|
|
13626
14050
|
kind: "sync-stream"
|
|
14051
|
+
}),
|
|
14052
|
+
betaSessionsEventsStream: channel({
|
|
14053
|
+
channelName: "beta.sessions.events.stream",
|
|
14054
|
+
kind: "async"
|
|
14055
|
+
}),
|
|
14056
|
+
betaSessionsThreadsEventsStream: channel({
|
|
14057
|
+
channelName: "beta.sessions.threads.events.stream",
|
|
14058
|
+
kind: "async"
|
|
13627
14059
|
})
|
|
13628
14060
|
},
|
|
13629
14061
|
{ instrumentationName: INSTRUMENTATION_NAMES.ANTHROPIC }
|
|
@@ -13637,6 +14069,7 @@ var AnthropicPlugin = class extends BasePlugin {
|
|
|
13637
14069
|
onEnable() {
|
|
13638
14070
|
this.subscribeToAnthropicChannels();
|
|
13639
14071
|
this.subscribeToAnthropicToolRunner();
|
|
14072
|
+
this.subscribeToAnthropicSessionStreams();
|
|
13640
14073
|
}
|
|
13641
14074
|
onDisable() {
|
|
13642
14075
|
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
@@ -13754,7 +14187,411 @@ var AnthropicPlugin = class extends BasePlugin {
|
|
|
13754
14187
|
tracingChannel.unsubscribe(handlers);
|
|
13755
14188
|
});
|
|
13756
14189
|
}
|
|
14190
|
+
subscribeToAnthropicSessionStreams() {
|
|
14191
|
+
this.subscribeToAnthropicSessionStream(
|
|
14192
|
+
anthropicChannels.betaSessionsEventsStream,
|
|
14193
|
+
false
|
|
14194
|
+
);
|
|
14195
|
+
this.subscribeToAnthropicSessionStream(
|
|
14196
|
+
anthropicChannels.betaSessionsThreadsEventsStream,
|
|
14197
|
+
true
|
|
14198
|
+
);
|
|
14199
|
+
}
|
|
14200
|
+
subscribeToAnthropicSessionStream(channel2, isThread) {
|
|
14201
|
+
const tracingChannel = channel2.tracingChannel();
|
|
14202
|
+
const pending = /* @__PURE__ */ new WeakSet();
|
|
14203
|
+
const handlers = {
|
|
14204
|
+
start: (event) => {
|
|
14205
|
+
if (isAutoInstrumentationSuppressed()) {
|
|
14206
|
+
return;
|
|
14207
|
+
}
|
|
14208
|
+
pending.add(event);
|
|
14209
|
+
},
|
|
14210
|
+
asyncEnd: (event) => {
|
|
14211
|
+
if (!pending.delete(event)) {
|
|
14212
|
+
return;
|
|
14213
|
+
}
|
|
14214
|
+
const stream = event.result;
|
|
14215
|
+
if (!isAsyncIterable(stream)) {
|
|
14216
|
+
return;
|
|
14217
|
+
}
|
|
14218
|
+
registerAnthropicSessionStreamCollector(stream, () => {
|
|
14219
|
+
wrapAnthropicSessionEventStream(stream, isThread);
|
|
14220
|
+
});
|
|
14221
|
+
},
|
|
14222
|
+
error: (event) => {
|
|
14223
|
+
pending.delete(event);
|
|
14224
|
+
}
|
|
14225
|
+
};
|
|
14226
|
+
tracingChannel.subscribe(handlers);
|
|
14227
|
+
this.unsubscribers.push(() => tracingChannel.unsubscribe(handlers));
|
|
14228
|
+
}
|
|
13757
14229
|
};
|
|
14230
|
+
function wrapAnthropicSessionEventStream(stream, isThread) {
|
|
14231
|
+
const state = {
|
|
14232
|
+
history: [],
|
|
14233
|
+
isThread,
|
|
14234
|
+
pendingInput: [],
|
|
14235
|
+
seenEventIds: /* @__PURE__ */ new Set()
|
|
14236
|
+
};
|
|
14237
|
+
patchStreamIfNeeded(stream, {
|
|
14238
|
+
onChunk: (event) => handleAnthropicSessionEvent(state, event),
|
|
14239
|
+
onComplete: () => finalizeAnthropicSessionTurn(state),
|
|
14240
|
+
onError: (error) => finalizeAnthropicSessionTurn(state, error)
|
|
14241
|
+
});
|
|
14242
|
+
return stream;
|
|
14243
|
+
}
|
|
14244
|
+
function handleAnthropicSessionEvent(state, event) {
|
|
14245
|
+
try {
|
|
14246
|
+
if (typeof event.id === "string" && event.type !== "event_delta" && state.seenEventIds.has(event.id)) {
|
|
14247
|
+
return;
|
|
14248
|
+
}
|
|
14249
|
+
if (typeof event.id === "string" && event.type !== "event_delta") {
|
|
14250
|
+
state.seenEventIds.add(event.id);
|
|
14251
|
+
}
|
|
14252
|
+
switch (event.type) {
|
|
14253
|
+
case "user.message":
|
|
14254
|
+
case "system.message":
|
|
14255
|
+
recordAnthropicSessionInput(
|
|
14256
|
+
state,
|
|
14257
|
+
event
|
|
14258
|
+
);
|
|
14259
|
+
break;
|
|
14260
|
+
case "session.status_running":
|
|
14261
|
+
if (!state.isThread) {
|
|
14262
|
+
ensureAnthropicSessionTurn(state);
|
|
14263
|
+
}
|
|
14264
|
+
break;
|
|
14265
|
+
case "session.thread_status_running":
|
|
14266
|
+
if (state.isThread) {
|
|
14267
|
+
ensureAnthropicSessionTurn(state);
|
|
14268
|
+
}
|
|
14269
|
+
break;
|
|
14270
|
+
case "span.model_request_start":
|
|
14271
|
+
if (typeof event.id === "string") {
|
|
14272
|
+
startAnthropicSessionModel(state, event.id);
|
|
14273
|
+
}
|
|
14274
|
+
break;
|
|
14275
|
+
case "event_delta":
|
|
14276
|
+
recordAnthropicSessionFirstToken(state, event);
|
|
14277
|
+
break;
|
|
14278
|
+
case "agent.message":
|
|
14279
|
+
recordAnthropicSessionMessage(
|
|
14280
|
+
state,
|
|
14281
|
+
event
|
|
14282
|
+
);
|
|
14283
|
+
break;
|
|
14284
|
+
case "agent.custom_tool_use":
|
|
14285
|
+
case "agent.mcp_tool_use":
|
|
14286
|
+
case "agent.tool_use":
|
|
14287
|
+
startAnthropicSessionTool(state, event);
|
|
14288
|
+
break;
|
|
14289
|
+
case "user.tool_confirmation":
|
|
14290
|
+
recordAnthropicSessionToolConfirmation(state, event);
|
|
14291
|
+
break;
|
|
14292
|
+
case "agent.mcp_tool_result":
|
|
14293
|
+
case "agent.tool_result":
|
|
14294
|
+
case "user.custom_tool_result":
|
|
14295
|
+
case "user.tool_result":
|
|
14296
|
+
finalizeAnthropicSessionTool(
|
|
14297
|
+
state,
|
|
14298
|
+
event
|
|
14299
|
+
);
|
|
14300
|
+
break;
|
|
14301
|
+
case "span.model_request_end":
|
|
14302
|
+
finalizeAnthropicSessionModel(
|
|
14303
|
+
state,
|
|
14304
|
+
event
|
|
14305
|
+
);
|
|
14306
|
+
break;
|
|
14307
|
+
case "session.status_idle":
|
|
14308
|
+
case "session.thread_status_idle": {
|
|
14309
|
+
if (event.type === "session.status_idle" && state.isThread || event.type === "session.thread_status_idle" && !state.isThread) {
|
|
14310
|
+
break;
|
|
14311
|
+
}
|
|
14312
|
+
const stopReason = isObject(event.stop_reason) ? event.stop_reason.type : void 0;
|
|
14313
|
+
if (stopReason === "end_turn") {
|
|
14314
|
+
finalizeAnthropicSessionTurn(state);
|
|
14315
|
+
} else if (stopReason === "retries_exhausted") {
|
|
14316
|
+
finalizeAnthropicSessionTurn(
|
|
14317
|
+
state,
|
|
14318
|
+
"Anthropic session retries exhausted"
|
|
14319
|
+
);
|
|
14320
|
+
}
|
|
14321
|
+
break;
|
|
14322
|
+
}
|
|
14323
|
+
case "session.error":
|
|
14324
|
+
finalizeAnthropicSessionTurn(state, event.error);
|
|
14325
|
+
break;
|
|
14326
|
+
case "session.deleted":
|
|
14327
|
+
case "session.status_terminated":
|
|
14328
|
+
case "session.thread_status_terminated":
|
|
14329
|
+
if (event.type === "session.deleted" || event.type === "session.status_terminated" && !state.isThread || event.type === "session.thread_status_terminated" && state.isThread) {
|
|
14330
|
+
finalizeAnthropicSessionTurn(state);
|
|
14331
|
+
}
|
|
14332
|
+
break;
|
|
14333
|
+
default:
|
|
14334
|
+
break;
|
|
14335
|
+
}
|
|
14336
|
+
} catch (error) {
|
|
14337
|
+
debugLogger.debug("Error processing Anthropic Sessions event:", error);
|
|
14338
|
+
}
|
|
14339
|
+
}
|
|
14340
|
+
function ensureAnthropicSessionTurn(state) {
|
|
14341
|
+
if (state.activeTurn) {
|
|
14342
|
+
return state.activeTurn;
|
|
14343
|
+
}
|
|
14344
|
+
const input = state.pendingInput;
|
|
14345
|
+
state.pendingInput = [];
|
|
14346
|
+
const span = startSpan(
|
|
14347
|
+
withSpanInstrumentationName(
|
|
14348
|
+
{
|
|
14349
|
+
event: {
|
|
14350
|
+
...input.length > 0 ? { input } : {},
|
|
14351
|
+
metadata: { provider: "anthropic" }
|
|
14352
|
+
},
|
|
14353
|
+
name: state.isThread ? "anthropic.beta.sessions.thread.turn" : "anthropic.beta.sessions.turn",
|
|
14354
|
+
spanAttributes: { type: "task" /* TASK */ }
|
|
14355
|
+
},
|
|
14356
|
+
INSTRUMENTATION_NAMES.ANTHROPIC
|
|
14357
|
+
)
|
|
14358
|
+
);
|
|
14359
|
+
state.activeTurn = {
|
|
14360
|
+
activeTools: /* @__PURE__ */ new Map(),
|
|
14361
|
+
input: input.slice(),
|
|
14362
|
+
metrics: {},
|
|
14363
|
+
span
|
|
14364
|
+
};
|
|
14365
|
+
return state.activeTurn;
|
|
14366
|
+
}
|
|
14367
|
+
function recordAnthropicSessionInput(state, event) {
|
|
14368
|
+
const content = processAttachmentsInInput(event.content);
|
|
14369
|
+
const message = {
|
|
14370
|
+
role: event.type === "system.message" ? "system" : "user",
|
|
14371
|
+
content
|
|
14372
|
+
};
|
|
14373
|
+
state.history.push(message);
|
|
14374
|
+
if (state.activeTurn) {
|
|
14375
|
+
state.activeTurn.input.push(message);
|
|
14376
|
+
} else {
|
|
14377
|
+
state.pendingInput.push(message);
|
|
14378
|
+
}
|
|
14379
|
+
}
|
|
14380
|
+
function startAnthropicSessionModel(state, startEventId) {
|
|
14381
|
+
const turn = ensureAnthropicSessionTurn(state);
|
|
14382
|
+
if (turn.activeModel) {
|
|
14383
|
+
finalizeAnthropicSessionModelState(state, turn);
|
|
14384
|
+
}
|
|
14385
|
+
const span = withCurrent(
|
|
14386
|
+
turn.span,
|
|
14387
|
+
() => startSpan(
|
|
14388
|
+
withSpanInstrumentationName(
|
|
14389
|
+
{
|
|
14390
|
+
event: {
|
|
14391
|
+
...state.history.length > 0 ? { input: state.history.slice() } : {},
|
|
14392
|
+
metadata: { provider: "anthropic" }
|
|
14393
|
+
},
|
|
14394
|
+
name: "anthropic.messages.create",
|
|
14395
|
+
spanAttributes: { type: "llm" /* LLM */ }
|
|
14396
|
+
},
|
|
14397
|
+
INSTRUMENTATION_NAMES.ANTHROPIC
|
|
14398
|
+
)
|
|
14399
|
+
)
|
|
14400
|
+
);
|
|
14401
|
+
turn.activeModel = {
|
|
14402
|
+
output: [],
|
|
14403
|
+
span,
|
|
14404
|
+
startEventId,
|
|
14405
|
+
startTime: getCurrentUnixTimestamp()
|
|
14406
|
+
};
|
|
14407
|
+
}
|
|
14408
|
+
function recordAnthropicSessionFirstToken(state, event) {
|
|
14409
|
+
const model = state.activeTurn?.activeModel;
|
|
14410
|
+
if (!model || model.firstTokenTime !== void 0 || !isObject(event.delta) || !isObject(event.delta.content) || typeof event.delta.content.text !== "string") {
|
|
14411
|
+
return;
|
|
14412
|
+
}
|
|
14413
|
+
model.firstTokenTime = getCurrentUnixTimestamp();
|
|
14414
|
+
}
|
|
14415
|
+
function recordAnthropicSessionMessage(state, event) {
|
|
14416
|
+
const turn = ensureAnthropicSessionTurn(state);
|
|
14417
|
+
const content = processAttachmentsInInput(
|
|
14418
|
+
event.content
|
|
14419
|
+
);
|
|
14420
|
+
if (turn.activeModel) {
|
|
14421
|
+
turn.activeModel.output.push(...content);
|
|
14422
|
+
} else {
|
|
14423
|
+
const output = { role: "assistant", content };
|
|
14424
|
+
turn.lastOutput = output;
|
|
14425
|
+
state.history.push(output);
|
|
14426
|
+
}
|
|
14427
|
+
}
|
|
14428
|
+
function startAnthropicSessionTool(state, event) {
|
|
14429
|
+
const turn = ensureAnthropicSessionTurn(state);
|
|
14430
|
+
if (turn.activeModel) {
|
|
14431
|
+
turn.activeModel.output.push({
|
|
14432
|
+
type: "tool_use",
|
|
14433
|
+
id: event.id,
|
|
14434
|
+
name: event.name,
|
|
14435
|
+
input: event.input
|
|
14436
|
+
});
|
|
14437
|
+
}
|
|
14438
|
+
const existing = turn.activeTools.get(event.id);
|
|
14439
|
+
if (existing) {
|
|
14440
|
+
existing.span.end();
|
|
14441
|
+
turn.activeTools.delete(event.id);
|
|
14442
|
+
}
|
|
14443
|
+
const span = withCurrent(
|
|
14444
|
+
turn.span,
|
|
14445
|
+
() => startSpan(
|
|
14446
|
+
withSpanInstrumentationName(
|
|
14447
|
+
{
|
|
14448
|
+
event: { input: event.input },
|
|
14449
|
+
name: event.name,
|
|
14450
|
+
spanAttributes: { type: "tool" /* TOOL */ }
|
|
14451
|
+
},
|
|
14452
|
+
INSTRUMENTATION_NAMES.ANTHROPIC
|
|
14453
|
+
)
|
|
14454
|
+
)
|
|
14455
|
+
);
|
|
14456
|
+
const toolState = {
|
|
14457
|
+
approval: event.evaluated_permission === "allow" ? "approved" : event.evaluated_permission === "deny" ? "denied" : void 0,
|
|
14458
|
+
span
|
|
14459
|
+
};
|
|
14460
|
+
turn.activeTools.set(event.id, toolState);
|
|
14461
|
+
if (toolState.approval === "denied") {
|
|
14462
|
+
finalizeAnthropicSessionToolState(toolState);
|
|
14463
|
+
turn.activeTools.delete(event.id);
|
|
14464
|
+
}
|
|
14465
|
+
}
|
|
14466
|
+
function recordAnthropicSessionToolConfirmation(state, event) {
|
|
14467
|
+
if (typeof event.tool_use_id !== "string" || event.result !== "allow" && event.result !== "deny") {
|
|
14468
|
+
return;
|
|
14469
|
+
}
|
|
14470
|
+
const turn = state.activeTurn;
|
|
14471
|
+
const tool = turn?.activeTools.get(event.tool_use_id);
|
|
14472
|
+
if (!turn || !tool) {
|
|
14473
|
+
return;
|
|
14474
|
+
}
|
|
14475
|
+
tool.approval = event.result === "allow" ? "approved" : "denied";
|
|
14476
|
+
if (tool.approval === "denied") {
|
|
14477
|
+
finalizeAnthropicSessionToolState(tool);
|
|
14478
|
+
turn.activeTools.delete(event.tool_use_id);
|
|
14479
|
+
}
|
|
14480
|
+
}
|
|
14481
|
+
function finalizeAnthropicSessionTool(state, event) {
|
|
14482
|
+
const toolUseId = event.tool_use_id ?? event.mcp_tool_use_id ?? event.custom_tool_use_id;
|
|
14483
|
+
if (!toolUseId) {
|
|
14484
|
+
return;
|
|
14485
|
+
}
|
|
14486
|
+
const content = processAttachmentsInInput(event.content);
|
|
14487
|
+
const turn = state.activeTurn;
|
|
14488
|
+
const tool = turn?.activeTools.get(toolUseId);
|
|
14489
|
+
if (turn && tool) {
|
|
14490
|
+
finalizeAnthropicSessionToolState(tool, event, content);
|
|
14491
|
+
turn.activeTools.delete(toolUseId);
|
|
14492
|
+
}
|
|
14493
|
+
const toolResult = {
|
|
14494
|
+
type: "tool_result",
|
|
14495
|
+
tool_use_id: toolUseId,
|
|
14496
|
+
...content !== void 0 ? { content } : {},
|
|
14497
|
+
...event.is_error === true ? { is_error: true } : {}
|
|
14498
|
+
};
|
|
14499
|
+
state.history.push({
|
|
14500
|
+
role: "user",
|
|
14501
|
+
content: [toolResult]
|
|
14502
|
+
});
|
|
14503
|
+
}
|
|
14504
|
+
function finalizeAnthropicSessionToolState(state, event, content = event?.content) {
|
|
14505
|
+
safeAnthropicSessionLog(state.span, {
|
|
14506
|
+
...event?.is_error === true ? {
|
|
14507
|
+
error: content ?? "Anthropic session tool execution failed"
|
|
14508
|
+
} : {},
|
|
14509
|
+
...state.approval ? { metadata: { tool_approval: state.approval } } : {},
|
|
14510
|
+
...content !== void 0 ? { output: content } : {}
|
|
14511
|
+
});
|
|
14512
|
+
state.span.end();
|
|
14513
|
+
}
|
|
14514
|
+
function finalizeAnthropicSessionModel(state, event) {
|
|
14515
|
+
const turn = state.activeTurn;
|
|
14516
|
+
const model = turn?.activeModel;
|
|
14517
|
+
if (!turn || !model || model.startEventId !== event.model_request_start_id) {
|
|
14518
|
+
return;
|
|
14519
|
+
}
|
|
14520
|
+
finalizeAnthropicSessionModelState(state, turn, event);
|
|
14521
|
+
}
|
|
14522
|
+
function finalizeAnthropicSessionModelState(state, turn, event) {
|
|
14523
|
+
const model = turn.activeModel;
|
|
14524
|
+
if (!model) {
|
|
14525
|
+
return;
|
|
14526
|
+
}
|
|
14527
|
+
turn.activeModel = void 0;
|
|
14528
|
+
const metrics = event ? parseAnthropicSessionModelUsage(event.model_usage) : {};
|
|
14529
|
+
if (model.firstTokenTime !== void 0) {
|
|
14530
|
+
metrics.time_to_first_token = model.firstTokenTime - model.startTime;
|
|
14531
|
+
}
|
|
14532
|
+
const output = model.output.length > 0 ? { role: "assistant", content: model.output } : void 0;
|
|
14533
|
+
safeAnthropicSessionLog(model.span, {
|
|
14534
|
+
...event?.is_error ? { error: "Anthropic session model request failed" } : {},
|
|
14535
|
+
...Object.keys(metrics).length > 0 ? { metrics } : {},
|
|
14536
|
+
...output ? { output } : {}
|
|
14537
|
+
});
|
|
14538
|
+
model.span.end();
|
|
14539
|
+
if (output) {
|
|
14540
|
+
turn.lastOutput = output;
|
|
14541
|
+
state.history.push(output);
|
|
14542
|
+
}
|
|
14543
|
+
for (const key of [
|
|
14544
|
+
"prompt_tokens",
|
|
14545
|
+
"completion_tokens",
|
|
14546
|
+
"tokens",
|
|
14547
|
+
"prompt_cached_tokens",
|
|
14548
|
+
"prompt_cache_creation_tokens"
|
|
14549
|
+
]) {
|
|
14550
|
+
const value = metrics[key];
|
|
14551
|
+
if (typeof value === "number") {
|
|
14552
|
+
turn.metrics[key] = (turn.metrics[key] ?? 0) + value;
|
|
14553
|
+
}
|
|
14554
|
+
}
|
|
14555
|
+
}
|
|
14556
|
+
function parseAnthropicSessionModelUsage(usage) {
|
|
14557
|
+
const finalized = finalizeAnthropicTokens({
|
|
14558
|
+
completion_tokens: usage.output_tokens,
|
|
14559
|
+
prompt_cache_creation_tokens: usage.cache_creation_input_tokens,
|
|
14560
|
+
prompt_cached_tokens: usage.cache_read_input_tokens,
|
|
14561
|
+
prompt_tokens: usage.input_tokens
|
|
14562
|
+
});
|
|
14563
|
+
return Object.fromEntries(
|
|
14564
|
+
Object.entries(finalized).filter(
|
|
14565
|
+
(entry) => entry[1] !== void 0
|
|
14566
|
+
)
|
|
14567
|
+
);
|
|
14568
|
+
}
|
|
14569
|
+
function finalizeAnthropicSessionTurn(state, error) {
|
|
14570
|
+
const turn = state.activeTurn;
|
|
14571
|
+
if (!turn) {
|
|
14572
|
+
return;
|
|
14573
|
+
}
|
|
14574
|
+
state.activeTurn = void 0;
|
|
14575
|
+
finalizeAnthropicSessionModelState(state, turn);
|
|
14576
|
+
for (const tool of turn.activeTools.values()) {
|
|
14577
|
+
finalizeAnthropicSessionToolState(tool);
|
|
14578
|
+
}
|
|
14579
|
+
turn.activeTools.clear();
|
|
14580
|
+
safeAnthropicSessionLog(turn.span, {
|
|
14581
|
+
...error !== void 0 ? { error: error instanceof Error ? error : toLoggedError(error) } : {},
|
|
14582
|
+
...turn.input.length > 0 ? { input: turn.input } : {},
|
|
14583
|
+
...turn.lastOutput ? { output: turn.lastOutput } : {},
|
|
14584
|
+
...Object.keys(turn.metrics).length > 0 ? { metrics: turn.metrics } : {}
|
|
14585
|
+
});
|
|
14586
|
+
turn.span.end();
|
|
14587
|
+
}
|
|
14588
|
+
function safeAnthropicSessionLog(span, event) {
|
|
14589
|
+
try {
|
|
14590
|
+
span.log(event);
|
|
14591
|
+
} catch (error) {
|
|
14592
|
+
debugLogger.debug("Error logging Anthropic Sessions span:", error);
|
|
14593
|
+
}
|
|
14594
|
+
}
|
|
13758
14595
|
function parseMetricsFromUsage2(usage) {
|
|
13759
14596
|
if (!usage) {
|
|
13760
14597
|
return {};
|
|
@@ -13770,6 +14607,18 @@ function parseMetricsFromUsage2(usage) {
|
|
|
13770
14607
|
saveIfExistsTo("output_tokens", "completion_tokens");
|
|
13771
14608
|
saveIfExistsTo("cache_read_input_tokens", "prompt_cached_tokens");
|
|
13772
14609
|
saveIfExistsTo("cache_creation_input_tokens", "prompt_cache_creation_tokens");
|
|
14610
|
+
if (isObject(usage.cache_creation)) {
|
|
14611
|
+
const cacheCreation = usage.cache_creation;
|
|
14612
|
+
for (const [source, target] of [
|
|
14613
|
+
["ephemeral_5m_input_tokens", "prompt_cache_creation_5m_tokens"],
|
|
14614
|
+
["ephemeral_1h_input_tokens", "prompt_cache_creation_1h_tokens"]
|
|
14615
|
+
]) {
|
|
14616
|
+
const value = cacheCreation[source];
|
|
14617
|
+
if (typeof value === "number") {
|
|
14618
|
+
metrics[target] = value;
|
|
14619
|
+
}
|
|
14620
|
+
}
|
|
14621
|
+
}
|
|
13773
14622
|
if (isObject(usage.server_tool_use)) {
|
|
13774
14623
|
for (const [name, value] of Object.entries(usage.server_tool_use)) {
|
|
13775
14624
|
if (typeof value === "number") {
|
|
@@ -15628,6 +16477,29 @@ var harnessAgentChannels = defineChannels(
|
|
|
15628
16477
|
{ instrumentationName: INSTRUMENTATION_NAMES.AI_SDK }
|
|
15629
16478
|
);
|
|
15630
16479
|
|
|
16480
|
+
// src/instrumentation/plugins/cloudflare-think-context.ts
|
|
16481
|
+
var cloudflareThinkSpans = /* @__PURE__ */ new Map();
|
|
16482
|
+
function registerCloudflareThinkSpan(span) {
|
|
16483
|
+
if (span.spanId) {
|
|
16484
|
+
cloudflareThinkSpans.set(span.spanId, span);
|
|
16485
|
+
}
|
|
16486
|
+
}
|
|
16487
|
+
function unregisterCloudflareThinkSpan(span) {
|
|
16488
|
+
if (span.spanId) {
|
|
16489
|
+
cloudflareThinkSpans.delete(span.spanId);
|
|
16490
|
+
}
|
|
16491
|
+
}
|
|
16492
|
+
function currentCloudflareThinkSpan() {
|
|
16493
|
+
const parentSpanIds = _internalGetGlobalState()?.contextManager.getParentSpanIds()?.spanParents ?? [];
|
|
16494
|
+
for (const parentSpanId of parentSpanIds) {
|
|
16495
|
+
const span = cloudflareThinkSpans.get(parentSpanId);
|
|
16496
|
+
if (span) {
|
|
16497
|
+
return span;
|
|
16498
|
+
}
|
|
16499
|
+
}
|
|
16500
|
+
return void 0;
|
|
16501
|
+
}
|
|
16502
|
+
|
|
15631
16503
|
// src/instrumentation/plugins/ai-sdk-plugin.ts
|
|
15632
16504
|
var DEFAULT_DENY_OUTPUT_PATHS = [
|
|
15633
16505
|
// v3
|
|
@@ -15734,6 +16606,7 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
15734
16606
|
traceStreamingChannel(aiSDKChannels.streamText, {
|
|
15735
16607
|
name: "streamText",
|
|
15736
16608
|
type: "function" /* FUNCTION */,
|
|
16609
|
+
shouldTrace: () => currentCloudflareThinkSpan() === void 0,
|
|
15737
16610
|
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
15738
16611
|
extractOutput: (result, endEvent) => processAISDKOutput(
|
|
15739
16612
|
result,
|
|
@@ -15754,6 +16627,7 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
15754
16627
|
traceSyncStreamChannel(aiSDKChannels.streamTextSync, {
|
|
15755
16628
|
name: "streamText",
|
|
15756
16629
|
type: "function" /* FUNCTION */,
|
|
16630
|
+
shouldTrace: () => currentCloudflareThinkSpan() === void 0,
|
|
15757
16631
|
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
15758
16632
|
patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
|
|
15759
16633
|
defaultDenyOutputPaths: denyOutputPaths,
|
|
@@ -16336,7 +17210,7 @@ function resolveDenyOutputPaths(event, defaultDenyOutputPaths) {
|
|
|
16336
17210
|
return defaultDenyOutputPaths;
|
|
16337
17211
|
}
|
|
16338
17212
|
const runtimeDenyOutputPaths = firstArgument2[RUNTIME_DENY_OUTPUT_PATHS];
|
|
16339
|
-
if (Array.isArray(runtimeDenyOutputPaths) && runtimeDenyOutputPaths.every((
|
|
17213
|
+
if (Array.isArray(runtimeDenyOutputPaths) && runtimeDenyOutputPaths.every((path3) => typeof path3 === "string")) {
|
|
16340
17214
|
return runtimeDenyOutputPaths;
|
|
16341
17215
|
}
|
|
16342
17216
|
return defaultDenyOutputPaths;
|
|
@@ -16739,6 +17613,23 @@ function prepareAISDKWorkflowAgentStreamInput(params, event, span, defaultDenyOu
|
|
|
16739
17613
|
metadata
|
|
16740
17614
|
};
|
|
16741
17615
|
}
|
|
17616
|
+
function prepareAISDKAgentCallInput(params, event, span, defaultDenyOutputPaths = DEFAULT_DENY_OUTPUT_PATHS) {
|
|
17617
|
+
const { input } = processAISDKWorkflowAgentCallInput(params);
|
|
17618
|
+
const metadata = extractMetadataFromCallParams(params, event.self);
|
|
17619
|
+
const childTracing = prepareAISDKChildTracing(
|
|
17620
|
+
params,
|
|
17621
|
+
event.self,
|
|
17622
|
+
span,
|
|
17623
|
+
defaultDenyOutputPaths,
|
|
17624
|
+
event.aiSDK,
|
|
17625
|
+
{ agentOwner: true }
|
|
17626
|
+
);
|
|
17627
|
+
event.modelWrapped = childTracing.modelWrapped;
|
|
17628
|
+
if (childTracing.cleanup) {
|
|
17629
|
+
event.__braintrust_ai_sdk_cleanup = childTracing.cleanup;
|
|
17630
|
+
}
|
|
17631
|
+
return { input, metadata };
|
|
17632
|
+
}
|
|
16742
17633
|
function prepareAISDKEmbedInput(params, self) {
|
|
16743
17634
|
return {
|
|
16744
17635
|
input: { ...params },
|
|
@@ -16762,6 +17653,18 @@ function extractTopLevelAISDKMetrics(result, event, startTime) {
|
|
|
16762
17653
|
}
|
|
16763
17654
|
return metrics;
|
|
16764
17655
|
}
|
|
17656
|
+
async function extractResolvedAISDKTokenMetrics(result) {
|
|
17657
|
+
for (const field of ["totalUsage", "usage"]) {
|
|
17658
|
+
try {
|
|
17659
|
+
const usage = await Promise.resolve(result[field]);
|
|
17660
|
+
if (usage !== void 0) {
|
|
17661
|
+
return extractTokenMetrics({ [field]: usage });
|
|
17662
|
+
}
|
|
17663
|
+
} catch {
|
|
17664
|
+
}
|
|
17665
|
+
}
|
|
17666
|
+
return extractTokenMetrics(result);
|
|
17667
|
+
}
|
|
16765
17668
|
function hasModelChildTracing(event) {
|
|
16766
17669
|
return event?.modelWrapped === true || event?.__braintrust_ai_sdk_model_wrapped === true;
|
|
16767
17670
|
}
|
|
@@ -17579,13 +18482,15 @@ function patchAISDKStreamingResult(args) {
|
|
|
17579
18482
|
const {
|
|
17580
18483
|
defaultDenyOutputPaths,
|
|
17581
18484
|
endEvent,
|
|
18485
|
+
forceTopLevelMetrics,
|
|
17582
18486
|
onComplete,
|
|
17583
18487
|
onCancel,
|
|
17584
18488
|
onError,
|
|
17585
18489
|
result,
|
|
17586
18490
|
resolvePromiseUsage,
|
|
17587
18491
|
span,
|
|
17588
|
-
startTime
|
|
18492
|
+
startTime,
|
|
18493
|
+
transformOutput
|
|
17589
18494
|
} = args;
|
|
17590
18495
|
if (!result || typeof result !== "object") {
|
|
17591
18496
|
return false;
|
|
@@ -17638,8 +18543,8 @@ function patchAISDKStreamingResult(args) {
|
|
|
17638
18543
|
}
|
|
17639
18544
|
outputLogged = true;
|
|
17640
18545
|
try {
|
|
17641
|
-
const metrics = extractTopLevelAISDKMetrics(result, endEvent);
|
|
17642
|
-
if (resolvePromiseUsage) {
|
|
18546
|
+
const metrics = forceTopLevelMetrics ? await extractResolvedAISDKTokenMetrics(result) : extractTopLevelAISDKMetrics(result, endEvent);
|
|
18547
|
+
if (resolvePromiseUsage && !forceTopLevelMetrics) {
|
|
17643
18548
|
try {
|
|
17644
18549
|
const resultRecord2 = result;
|
|
17645
18550
|
const pendingUsage = resultRecord2.totalUsage ?? resultRecord2.usage;
|
|
@@ -17658,10 +18563,11 @@ function patchAISDKStreamingResult(args) {
|
|
|
17658
18563
|
if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
|
|
17659
18564
|
metrics.time_to_first_token = firstChunkTime - startTime;
|
|
17660
18565
|
}
|
|
17661
|
-
const
|
|
18566
|
+
const processedOutput = await processAISDKStreamingOutput(
|
|
17662
18567
|
result,
|
|
17663
18568
|
resolveDenyOutputPaths(endEvent, defaultDenyOutputPaths)
|
|
17664
18569
|
);
|
|
18570
|
+
const output = transformOutput ? transformOutput(processedOutput) : processedOutput;
|
|
17665
18571
|
const metadata = buildResolvedMetadataPayload(result).metadata;
|
|
17666
18572
|
try {
|
|
17667
18573
|
span.log({
|
|
@@ -18066,11 +18972,11 @@ function processAISDKOutput(output, denyOutputPaths) {
|
|
|
18066
18972
|
if (!output) return output;
|
|
18067
18973
|
const merged = extractSerializableOutputFields(output);
|
|
18068
18974
|
const deleteOutputPaths = denyOutputPaths.filter(
|
|
18069
|
-
(
|
|
18975
|
+
(path3) => path3.toLowerCase().endsWith("headers")
|
|
18070
18976
|
);
|
|
18071
18977
|
const sanitized = omit(merged, denyOutputPaths, deleteOutputPaths);
|
|
18072
|
-
for (const
|
|
18073
|
-
const stack = [{ obj: sanitized, keys: parsePath(
|
|
18978
|
+
for (const path3 of TRANSPORT_PAYLOAD_ROOT_PATHS) {
|
|
18979
|
+
const stack = [{ obj: sanitized, keys: parsePath(path3) }];
|
|
18074
18980
|
while (stack.length > 0) {
|
|
18075
18981
|
const entry = stack.pop();
|
|
18076
18982
|
if (!entry || entry.keys.length === 0) {
|
|
@@ -18509,11 +19415,11 @@ function firstNumber2(...values) {
|
|
|
18509
19415
|
function deepCopy(obj) {
|
|
18510
19416
|
return JSON.parse(JSON.stringify(obj));
|
|
18511
19417
|
}
|
|
18512
|
-
function parsePath(
|
|
19418
|
+
function parsePath(path3) {
|
|
18513
19419
|
const keys = [];
|
|
18514
19420
|
let current = "";
|
|
18515
|
-
for (let i = 0; i <
|
|
18516
|
-
const char =
|
|
19421
|
+
for (let i = 0; i < path3.length; i++) {
|
|
19422
|
+
const char = path3[i];
|
|
18517
19423
|
if (char === ".") {
|
|
18518
19424
|
if (current) {
|
|
18519
19425
|
keys.push(current);
|
|
@@ -18526,8 +19432,8 @@ function parsePath(path2) {
|
|
|
18526
19432
|
}
|
|
18527
19433
|
let bracketContent = "";
|
|
18528
19434
|
i++;
|
|
18529
|
-
while (i <
|
|
18530
|
-
bracketContent +=
|
|
19435
|
+
while (i < path3.length && path3[i] !== "]") {
|
|
19436
|
+
bracketContent += path3[i];
|
|
18531
19437
|
i++;
|
|
18532
19438
|
}
|
|
18533
19439
|
if (bracketContent === "") {
|
|
@@ -18582,9 +19488,9 @@ function omitAtPath(obj, keys, deleteLeaf = false) {
|
|
|
18582
19488
|
function omit(obj, paths, deletePaths = []) {
|
|
18583
19489
|
const result = deepCopy(obj);
|
|
18584
19490
|
const deletePathSet = new Set(deletePaths);
|
|
18585
|
-
for (const
|
|
18586
|
-
const keys = parsePath(
|
|
18587
|
-
omitAtPath(result, keys, deletePathSet.has(
|
|
19491
|
+
for (const path3 of paths) {
|
|
19492
|
+
const keys = parsePath(path3);
|
|
19493
|
+
omitAtPath(result, keys, deletePathSet.has(path3));
|
|
18588
19494
|
}
|
|
18589
19495
|
return result;
|
|
18590
19496
|
}
|
|
@@ -19011,37 +19917,97 @@ function seedTaskToolUseIdMapping(taskIdToToolUseId, message) {
|
|
|
19011
19917
|
taskIdToToolUseId.set(message.task_id, message.tool_use_id);
|
|
19012
19918
|
}
|
|
19013
19919
|
}
|
|
19014
|
-
function
|
|
19015
|
-
|
|
19016
|
-
|
|
19017
|
-
|
|
19018
|
-
usage = message.message?.usage;
|
|
19019
|
-
} else if (message.type === "result") {
|
|
19020
|
-
usage = message.usage;
|
|
19021
|
-
}
|
|
19920
|
+
function tokenCount(value) {
|
|
19921
|
+
return typeof value === "number" && Number.isFinite(value) && Number.isInteger(value) && value >= 0 ? value : void 0;
|
|
19922
|
+
}
|
|
19923
|
+
function copyUsage(usage) {
|
|
19022
19924
|
if (!usage || typeof usage !== "object") {
|
|
19023
|
-
return
|
|
19925
|
+
return void 0;
|
|
19926
|
+
}
|
|
19927
|
+
const copy = {};
|
|
19928
|
+
for (const key of [
|
|
19929
|
+
"input_tokens",
|
|
19930
|
+
"output_tokens",
|
|
19931
|
+
"cache_read_input_tokens",
|
|
19932
|
+
"cache_creation_input_tokens"
|
|
19933
|
+
]) {
|
|
19934
|
+
const value = tokenCount(Reflect.get(usage, key));
|
|
19935
|
+
if (value !== void 0) {
|
|
19936
|
+
copy[key] = value;
|
|
19937
|
+
}
|
|
19938
|
+
}
|
|
19939
|
+
const cacheCreation = Reflect.get(usage, "cache_creation");
|
|
19940
|
+
if (cacheCreation && typeof cacheCreation === "object") {
|
|
19941
|
+
const cacheCreationCopy = {};
|
|
19942
|
+
for (const key of [
|
|
19943
|
+
"ephemeral_5m_input_tokens",
|
|
19944
|
+
"ephemeral_1h_input_tokens"
|
|
19945
|
+
]) {
|
|
19946
|
+
const value = tokenCount(Reflect.get(cacheCreation, key));
|
|
19947
|
+
if (value !== void 0) {
|
|
19948
|
+
cacheCreationCopy[key] = value;
|
|
19949
|
+
}
|
|
19950
|
+
}
|
|
19951
|
+
if (Object.keys(cacheCreationCopy).length > 0) {
|
|
19952
|
+
copy.cache_creation = cacheCreationCopy;
|
|
19953
|
+
}
|
|
19954
|
+
}
|
|
19955
|
+
return Object.keys(copy).length > 0 ? copy : void 0;
|
|
19956
|
+
}
|
|
19957
|
+
function mergeUsage(base, override) {
|
|
19958
|
+
if (!base || !override) {
|
|
19959
|
+
return override ?? base;
|
|
19960
|
+
}
|
|
19961
|
+
const cacheCreation = base.cache_creation || override.cache_creation ? { ...base.cache_creation, ...override.cache_creation } : void 0;
|
|
19962
|
+
return {
|
|
19963
|
+
...base,
|
|
19964
|
+
...override,
|
|
19965
|
+
...cacheCreation && { cache_creation: cacheCreation }
|
|
19966
|
+
};
|
|
19967
|
+
}
|
|
19968
|
+
function extractUsage(usage, includeOutput) {
|
|
19969
|
+
const metrics = {};
|
|
19970
|
+
if (!usage) {
|
|
19971
|
+
return {};
|
|
19024
19972
|
}
|
|
19025
19973
|
const inputTokens = getNumberProperty(usage, "input_tokens");
|
|
19026
19974
|
if (inputTokens !== void 0) {
|
|
19027
19975
|
metrics.prompt_tokens = inputTokens;
|
|
19028
19976
|
}
|
|
19029
|
-
|
|
19030
|
-
|
|
19031
|
-
|
|
19977
|
+
if (includeOutput) {
|
|
19978
|
+
const outputTokens = getNumberProperty(usage, "output_tokens");
|
|
19979
|
+
if (outputTokens !== void 0) {
|
|
19980
|
+
metrics.completion_tokens = outputTokens;
|
|
19981
|
+
}
|
|
19032
19982
|
}
|
|
19033
19983
|
const cacheReadTokens = getNumberProperty(usage, "cache_read_input_tokens") || 0;
|
|
19034
19984
|
const cacheCreationTokens = getNumberProperty(usage, "cache_creation_input_tokens") || 0;
|
|
19035
|
-
|
|
19036
|
-
|
|
19037
|
-
|
|
19038
|
-
|
|
19039
|
-
|
|
19985
|
+
Object.assign(
|
|
19986
|
+
metrics,
|
|
19987
|
+
extractAnthropicCacheTokens(cacheReadTokens, cacheCreationTokens)
|
|
19988
|
+
);
|
|
19989
|
+
const cacheCreation5mTokens = getNumberProperty(
|
|
19990
|
+
usage.cache_creation,
|
|
19991
|
+
"ephemeral_5m_input_tokens"
|
|
19992
|
+
);
|
|
19993
|
+
const cacheCreation1hTokens = getNumberProperty(
|
|
19994
|
+
usage.cache_creation,
|
|
19995
|
+
"ephemeral_1h_input_tokens"
|
|
19996
|
+
);
|
|
19997
|
+
if (cacheCreation5mTokens !== void 0) {
|
|
19998
|
+
metrics.prompt_cache_creation_5m_tokens = cacheCreation5mTokens;
|
|
19040
19999
|
}
|
|
19041
|
-
if (
|
|
19042
|
-
|
|
20000
|
+
if (cacheCreation1hTokens !== void 0) {
|
|
20001
|
+
metrics.prompt_cache_creation_1h_tokens = cacheCreation1hTokens;
|
|
19043
20002
|
}
|
|
19044
|
-
|
|
20003
|
+
if (Object.keys(metrics).length === 0) {
|
|
20004
|
+
return {};
|
|
20005
|
+
}
|
|
20006
|
+
const finalized = finalizeAnthropicTokens(metrics);
|
|
20007
|
+
if (metrics.completion_tokens === void 0) {
|
|
20008
|
+
delete finalized.tokens;
|
|
20009
|
+
}
|
|
20010
|
+
return toNumericMetrics(finalized);
|
|
19045
20011
|
}
|
|
19046
20012
|
function buildLLMInput(promptMessages, conversationHistory) {
|
|
19047
20013
|
const inputParts = [...promptMessages, ...conversationHistory];
|
|
@@ -19075,16 +20041,16 @@ function buildRootPromptMessages(prompt, capturedPromptMessages) {
|
|
|
19075
20041
|
function formatCapturedMessages(messages) {
|
|
19076
20042
|
return messages.length > 0 ? messages : [];
|
|
19077
20043
|
}
|
|
19078
|
-
async function createLLMSpanForMessages(messages, promptMessages, conversationHistory, options, startTime, parentSpan, existingSpan) {
|
|
20044
|
+
async function createLLMSpanForMessages(messages, promptMessages, conversationHistory, options, startTime, parentSpan, usage, hasFinalOutputUsage, existingSpan) {
|
|
19079
20045
|
if (messages.length === 0) {
|
|
19080
20046
|
return void 0;
|
|
19081
20047
|
}
|
|
19082
20048
|
const lastMessage = messages[messages.length - 1];
|
|
19083
|
-
if (lastMessage.type !== "assistant"
|
|
20049
|
+
if (lastMessage.type !== "assistant") {
|
|
19084
20050
|
return void 0;
|
|
19085
20051
|
}
|
|
19086
|
-
const model = lastMessage.message
|
|
19087
|
-
const
|
|
20052
|
+
const model = lastMessage.message?.model || options.model;
|
|
20053
|
+
const metrics = options.includePartialMessages ? extractUsage(usage, hasFinalOutputUsage) : {};
|
|
19088
20054
|
const input = buildLLMInput(promptMessages, conversationHistory);
|
|
19089
20055
|
const outputs = messages.map(
|
|
19090
20056
|
(m) => m.message?.content && m.message?.role ? { content: m.message.content, role: m.message.role } : void 0
|
|
@@ -19106,8 +20072,8 @@ async function createLLMSpanForMessages(messages, promptMessages, conversationHi
|
|
|
19106
20072
|
);
|
|
19107
20073
|
span.log({
|
|
19108
20074
|
input,
|
|
19109
|
-
metadata: model
|
|
19110
|
-
metrics:
|
|
20075
|
+
metadata: { ...model && { model }, provider: "anthropic" },
|
|
20076
|
+
...Object.keys(metrics).length > 0 ? { metrics } : {},
|
|
19111
20077
|
output: outputs
|
|
19112
20078
|
});
|
|
19113
20079
|
const spanExport = await span.export();
|
|
@@ -19197,11 +20163,17 @@ function prepareLocalToolHandlersInMcpServers(mcpServers) {
|
|
|
19197
20163
|
}
|
|
19198
20164
|
return { hasLocalToolHandlers, localToolHookNames };
|
|
19199
20165
|
}
|
|
19200
|
-
function createToolTracingHooks(resolveParentSpan, activeToolSpans, mcpServers, localToolHookNames, skipLocalToolHooks, subAgentDetailsByToolUseId, subAgentSpans, endedSubAgentSpans) {
|
|
20166
|
+
function createToolTracingHooks(resolveParentSpan, taskIdToToolUseId, toolUseToParent, activeToolSpans, mcpServers, localToolHookNames, skipLocalToolHooks, subAgentDetailsByToolUseId, subAgentSpans, endedSubAgentSpans) {
|
|
19201
20167
|
const preToolUse = async (input, toolUseID) => {
|
|
19202
20168
|
if (input.hook_event_name !== "PreToolUse" || !toolUseID) {
|
|
19203
20169
|
return {};
|
|
19204
20170
|
}
|
|
20171
|
+
if (!toolUseToParent.has(toolUseID) && input.agent_id) {
|
|
20172
|
+
const parentToolUseId = taskIdToToolUseId.get(input.agent_id);
|
|
20173
|
+
if (parentToolUseId) {
|
|
20174
|
+
toolUseToParent.set(toolUseID, parentToolUseId);
|
|
20175
|
+
}
|
|
20176
|
+
}
|
|
19205
20177
|
if (skipLocalToolHooks && (isLocalToolUse(input.tool_name, mcpServers) || localToolHookNames.has(input.tool_name))) {
|
|
19206
20178
|
return {};
|
|
19207
20179
|
}
|
|
@@ -19397,9 +20369,6 @@ function createToolTracingHooks(resolveParentSpan, activeToolSpans, mcpServers,
|
|
|
19397
20369
|
}
|
|
19398
20370
|
const metadata = {
|
|
19399
20371
|
...subAgentDetailsToMetadata(details),
|
|
19400
|
-
...input.agent_transcript_path && {
|
|
19401
|
-
"claude_agent_sdk.agent_transcript_path": input.agent_transcript_path
|
|
19402
|
-
},
|
|
19403
20372
|
"claude_agent_sdk.stop_hook_active": input.stop_hook_active
|
|
19404
20373
|
};
|
|
19405
20374
|
try {
|
|
@@ -19421,7 +20390,7 @@ function createToolTracingHooks(resolveParentSpan, activeToolSpans, mcpServers,
|
|
|
19421
20390
|
subagentStop
|
|
19422
20391
|
};
|
|
19423
20392
|
}
|
|
19424
|
-
function injectTracingHooks(options, resolveParentSpan, activeToolSpans, localToolHookNames, skipLocalToolHooks, subAgentDetailsByToolUseId, subAgentSpans, endedSubAgentSpans) {
|
|
20393
|
+
function injectTracingHooks(options, resolveParentSpan, taskIdToToolUseId, toolUseToParent, activeToolSpans, localToolHookNames, skipLocalToolHooks, subAgentDetailsByToolUseId, subAgentSpans, endedSubAgentSpans) {
|
|
19425
20394
|
const {
|
|
19426
20395
|
preToolUse,
|
|
19427
20396
|
postToolUse,
|
|
@@ -19430,6 +20399,8 @@ function injectTracingHooks(options, resolveParentSpan, activeToolSpans, localTo
|
|
|
19430
20399
|
subagentStop
|
|
19431
20400
|
} = createToolTracingHooks(
|
|
19432
20401
|
resolveParentSpan,
|
|
20402
|
+
taskIdToToolUseId,
|
|
20403
|
+
toolUseToParent,
|
|
19433
20404
|
activeToolSpans,
|
|
19434
20405
|
options.mcpServers,
|
|
19435
20406
|
localToolHookNames,
|
|
@@ -19511,6 +20482,13 @@ async function finalizeCurrentMessageGroup(state) {
|
|
|
19511
20482
|
}
|
|
19512
20483
|
}
|
|
19513
20484
|
const existingLlmSpan = state.activeLlmSpansByParentToolUse.get(parentKey);
|
|
20485
|
+
const lastMessage = state.currentMessages[state.currentMessages.length - 1];
|
|
20486
|
+
const messageId = lastMessage?.message?.id;
|
|
20487
|
+
const usage = state.options.includePartialMessages ? mergeUsage(
|
|
20488
|
+
copyUsage(lastMessage?.message?.usage),
|
|
20489
|
+
messageId ? state.usageByMessageId.get(messageId) : void 0
|
|
20490
|
+
) : void 0;
|
|
20491
|
+
const hasFinalOutputUsage = messageId !== void 0 && state.finalOutputUsageMessageIds.has(messageId);
|
|
19514
20492
|
const llmSpanResult = await createLLMSpanForMessages(
|
|
19515
20493
|
state.currentMessages,
|
|
19516
20494
|
promptMessages,
|
|
@@ -19518,6 +20496,8 @@ async function finalizeCurrentMessageGroup(state) {
|
|
|
19518
20496
|
state.options,
|
|
19519
20497
|
state.currentMessageStartTime,
|
|
19520
20498
|
parentSpan,
|
|
20499
|
+
usage,
|
|
20500
|
+
hasFinalOutputUsage,
|
|
19521
20501
|
existingLlmSpan
|
|
19522
20502
|
);
|
|
19523
20503
|
if (llmSpanResult) {
|
|
@@ -19535,9 +20515,17 @@ async function finalizeCurrentMessageGroup(state) {
|
|
|
19535
20515
|
}
|
|
19536
20516
|
}
|
|
19537
20517
|
state.activeLlmSpansByParentToolUse.delete(parentKey);
|
|
19538
|
-
|
|
19539
|
-
|
|
19540
|
-
state.
|
|
20518
|
+
if (messageId) {
|
|
20519
|
+
state.usageByMessageId.delete(messageId);
|
|
20520
|
+
state.finalOutputUsageMessageIds.delete(messageId);
|
|
20521
|
+
for (const [
|
|
20522
|
+
parent,
|
|
20523
|
+
activeMessageId
|
|
20524
|
+
] of state.activePartialMessageIdByParentKey) {
|
|
20525
|
+
if (activeMessageId === messageId) {
|
|
20526
|
+
state.activePartialMessageIdByParentKey.delete(parent);
|
|
20527
|
+
}
|
|
20528
|
+
}
|
|
19541
20529
|
}
|
|
19542
20530
|
state.currentMessages.length = 0;
|
|
19543
20531
|
}
|
|
@@ -19628,6 +20616,10 @@ async function ensureActiveLlmSpanForParentToolUse(rootSpan, activeLlmSpansByPar
|
|
|
19628
20616
|
);
|
|
19629
20617
|
llmParentSpan = await subAgentSpan.export();
|
|
19630
20618
|
}
|
|
20619
|
+
const racedLlmSpan = activeLlmSpansByParentToolUse.get(parentKey);
|
|
20620
|
+
if (racedLlmSpan) {
|
|
20621
|
+
return racedLlmSpan;
|
|
20622
|
+
}
|
|
19631
20623
|
const llmSpan = startSpan(
|
|
19632
20624
|
withSpanInstrumentationName(
|
|
19633
20625
|
{
|
|
@@ -19747,7 +20739,49 @@ async function maybeHandleTaskLifecycleMessage(state, message) {
|
|
|
19747
20739
|
}
|
|
19748
20740
|
return true;
|
|
19749
20741
|
}
|
|
20742
|
+
function handlePartialUsageMessage(state, message) {
|
|
20743
|
+
if (message.type !== "stream_event") {
|
|
20744
|
+
return false;
|
|
20745
|
+
}
|
|
20746
|
+
const event = message.event;
|
|
20747
|
+
if (!event || typeof event !== "object") {
|
|
20748
|
+
return true;
|
|
20749
|
+
}
|
|
20750
|
+
const parentKey = llmParentKey(message.parent_tool_use_id ?? null);
|
|
20751
|
+
if (event.type === "message_start") {
|
|
20752
|
+
const messageId2 = event.message?.id;
|
|
20753
|
+
const usage = copyUsage(event.message?.usage);
|
|
20754
|
+
if (messageId2) {
|
|
20755
|
+
state.activePartialMessageIdByParentKey.set(parentKey, messageId2);
|
|
20756
|
+
if (usage) {
|
|
20757
|
+
state.usageByMessageId.set(messageId2, usage);
|
|
20758
|
+
}
|
|
20759
|
+
}
|
|
20760
|
+
return true;
|
|
20761
|
+
}
|
|
20762
|
+
const messageId = state.activePartialMessageIdByParentKey.get(parentKey);
|
|
20763
|
+
if (!messageId) {
|
|
20764
|
+
return true;
|
|
20765
|
+
}
|
|
20766
|
+
if (event.type === "message_delta") {
|
|
20767
|
+
const update = copyUsage(event.usage);
|
|
20768
|
+
if (update) {
|
|
20769
|
+
const usage = state.usageByMessageId.get(messageId) ?? {};
|
|
20770
|
+
Object.assign(usage, update);
|
|
20771
|
+
state.usageByMessageId.set(messageId, usage);
|
|
20772
|
+
if (update.output_tokens !== void 0) {
|
|
20773
|
+
state.finalOutputUsageMessageIds.add(messageId);
|
|
20774
|
+
}
|
|
20775
|
+
}
|
|
20776
|
+
} else if (event.type === "message_stop") {
|
|
20777
|
+
state.activePartialMessageIdByParentKey.delete(parentKey);
|
|
20778
|
+
}
|
|
20779
|
+
return true;
|
|
20780
|
+
}
|
|
19750
20781
|
async function handleStreamMessage(state, message) {
|
|
20782
|
+
if (handlePartialUsageMessage(state, message)) {
|
|
20783
|
+
return;
|
|
20784
|
+
}
|
|
19751
20785
|
maybeTrackToolUseContext(state, message);
|
|
19752
20786
|
if (await maybeHandleTaskLifecycleMessage(state, message)) {
|
|
19753
20787
|
return;
|
|
@@ -19794,36 +20828,9 @@ async function handleStreamMessage(state, message) {
|
|
|
19794
20828
|
);
|
|
19795
20829
|
state.currentMessages.push(message);
|
|
19796
20830
|
}
|
|
19797
|
-
if (message.type !== "result"
|
|
20831
|
+
if (message.type !== "result") {
|
|
19798
20832
|
return;
|
|
19799
20833
|
}
|
|
19800
|
-
const finalUsageMetrics = extractUsageFromMessage(message);
|
|
19801
|
-
if (state.currentMessages.length > 0 && finalUsageMetrics.completion_tokens !== void 0) {
|
|
19802
|
-
const lastMessage = state.currentMessages[state.currentMessages.length - 1];
|
|
19803
|
-
if (lastMessage?.message?.usage) {
|
|
19804
|
-
const adjustedTokens = finalUsageMetrics.completion_tokens - state.accumulatedOutputTokens;
|
|
19805
|
-
if (adjustedTokens >= 0) {
|
|
19806
|
-
lastMessage.message.usage.output_tokens = adjustedTokens;
|
|
19807
|
-
}
|
|
19808
|
-
const resultUsage = message.usage;
|
|
19809
|
-
if (resultUsage && typeof resultUsage === "object") {
|
|
19810
|
-
const cacheReadTokens = getNumberProperty(
|
|
19811
|
-
resultUsage,
|
|
19812
|
-
"cache_read_input_tokens"
|
|
19813
|
-
);
|
|
19814
|
-
if (cacheReadTokens !== void 0) {
|
|
19815
|
-
lastMessage.message.usage.cache_read_input_tokens = cacheReadTokens;
|
|
19816
|
-
}
|
|
19817
|
-
const cacheCreationTokens = getNumberProperty(
|
|
19818
|
-
resultUsage,
|
|
19819
|
-
"cache_creation_input_tokens"
|
|
19820
|
-
);
|
|
19821
|
-
if (cacheCreationTokens !== void 0) {
|
|
19822
|
-
lastMessage.message.usage.cache_creation_input_tokens = cacheCreationTokens;
|
|
19823
|
-
}
|
|
19824
|
-
}
|
|
19825
|
-
}
|
|
19826
|
-
}
|
|
19827
20834
|
const metadata = {};
|
|
19828
20835
|
if (message.num_turns !== void 0) {
|
|
19829
20836
|
metadata.num_turns = message.num_turns;
|
|
@@ -19831,8 +20838,12 @@ async function handleStreamMessage(state, message) {
|
|
|
19831
20838
|
if (message.session_id !== void 0) {
|
|
19832
20839
|
metadata.session_id = message.session_id;
|
|
19833
20840
|
}
|
|
19834
|
-
|
|
19835
|
-
|
|
20841
|
+
const metrics = state.options.includePartialMessages ? {} : extractUsage(copyUsage(message.usage), true);
|
|
20842
|
+
if (Object.keys(metadata).length > 0 || Object.keys(metrics).length > 0) {
|
|
20843
|
+
state.span.log({
|
|
20844
|
+
...Object.keys(metadata).length > 0 ? { metadata } : {},
|
|
20845
|
+
...Object.keys(metrics).length > 0 ? { metrics } : {}
|
|
20846
|
+
});
|
|
19836
20847
|
}
|
|
19837
20848
|
}
|
|
19838
20849
|
async function finalizeQuerySpan(state) {
|
|
@@ -19856,6 +20867,9 @@ async function finalizeQuerySpan(state) {
|
|
|
19856
20867
|
llmSpan.end();
|
|
19857
20868
|
}
|
|
19858
20869
|
state.activeLlmSpansByParentToolUse.clear();
|
|
20870
|
+
state.activePartialMessageIdByParentKey.clear();
|
|
20871
|
+
state.finalOutputUsageMessageIds.clear();
|
|
20872
|
+
state.usageByMessageId.clear();
|
|
19859
20873
|
for (const toolSpan of state.activeToolSpans.values()) {
|
|
19860
20874
|
toolSpan.end();
|
|
19861
20875
|
}
|
|
@@ -19980,6 +20994,8 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
19980
20994
|
const optionsWithHooks = injectTracingHooks(
|
|
19981
20995
|
options,
|
|
19982
20996
|
resolveToolUseParentSpan,
|
|
20997
|
+
taskIdToToolUseId,
|
|
20998
|
+
toolUseToParent,
|
|
19983
20999
|
activeToolSpans,
|
|
19984
21000
|
localToolHookNames,
|
|
19985
21001
|
skipLocalToolHooks,
|
|
@@ -19990,8 +21006,8 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
19990
21006
|
params.options = optionsWithHooks;
|
|
19991
21007
|
event.arguments[0] = params;
|
|
19992
21008
|
spans.set(event, {
|
|
19993
|
-
accumulatedOutputTokens: 0,
|
|
19994
21009
|
activeLlmSpansByParentToolUse,
|
|
21010
|
+
activePartialMessageIdByParentKey: /* @__PURE__ */ new Map(),
|
|
19995
21011
|
activeToolSpans,
|
|
19996
21012
|
conversationHistoryByParentKey,
|
|
19997
21013
|
capturedPromptMessages,
|
|
@@ -19999,6 +21015,7 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
19999
21015
|
currentMessageStartTime: startTime,
|
|
20000
21016
|
currentMessages: [],
|
|
20001
21017
|
endedSubAgentSpans,
|
|
21018
|
+
finalOutputUsageMessageIds: /* @__PURE__ */ new Set(),
|
|
20002
21019
|
finalResults: [],
|
|
20003
21020
|
options: optionsWithHooks,
|
|
20004
21021
|
originalPrompt,
|
|
@@ -20014,6 +21031,7 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
20014
21031
|
latestLlmParentBySubAgentToolUse,
|
|
20015
21032
|
latestRootLlmParentRef,
|
|
20016
21033
|
toolUseToParent,
|
|
21034
|
+
usageByMessageId: /* @__PURE__ */ new Map(),
|
|
20017
21035
|
localToolContext
|
|
20018
21036
|
});
|
|
20019
21037
|
},
|
|
@@ -20083,6 +21101,295 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
20083
21101
|
}
|
|
20084
21102
|
};
|
|
20085
21103
|
|
|
21104
|
+
// src/instrumentation/plugins/cloudflare-think-channels.ts
|
|
21105
|
+
var cloudflareThinkChannels = defineChannels(
|
|
21106
|
+
"@cloudflare/think",
|
|
21107
|
+
{
|
|
21108
|
+
runInferenceLoop: channel({
|
|
21109
|
+
channelName: "Think.runInferenceLoop",
|
|
21110
|
+
kind: "async"
|
|
21111
|
+
})
|
|
21112
|
+
},
|
|
21113
|
+
{ instrumentationName: INSTRUMENTATION_NAMES.CLOUDFLARE_THINK }
|
|
21114
|
+
);
|
|
21115
|
+
|
|
21116
|
+
// src/instrumentation/plugins/cloudflare-think-plugin.ts
|
|
21117
|
+
var THINK_STATE_ID = /* @__PURE__ */ Symbol.for("braintrust.cloudflare-think.state-id");
|
|
21118
|
+
var CloudflareThinkPlugin = class extends BasePlugin {
|
|
21119
|
+
statesBySpanId = /* @__PURE__ */ new Map();
|
|
21120
|
+
onEnable() {
|
|
21121
|
+
this.subscribeToThinkRuns();
|
|
21122
|
+
this.subscribeToAISDKStreamTextSync();
|
|
21123
|
+
this.subscribeToAISDKStreamTextAsync();
|
|
21124
|
+
}
|
|
21125
|
+
onDisable() {
|
|
21126
|
+
for (const unsubscribe of this.unsubscribers) {
|
|
21127
|
+
unsubscribe();
|
|
21128
|
+
}
|
|
21129
|
+
this.unsubscribers = [];
|
|
21130
|
+
for (const state of this.statesBySpanId.values()) {
|
|
21131
|
+
this.finishState(state);
|
|
21132
|
+
}
|
|
21133
|
+
this.statesBySpanId.clear();
|
|
21134
|
+
}
|
|
21135
|
+
subscribeToThinkRuns() {
|
|
21136
|
+
const channel2 = cloudflareThinkChannels.runInferenceLoop.tracingChannel();
|
|
21137
|
+
const states = /* @__PURE__ */ new WeakMap();
|
|
21138
|
+
const state = _internalGetGlobalState();
|
|
21139
|
+
const contextManager = state?.contextManager;
|
|
21140
|
+
const currentSpanStore = contextManager ? contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
|
|
21141
|
+
const ensureState2 = (event) => {
|
|
21142
|
+
if (isAutoInstrumentationSuppressed()) {
|
|
21143
|
+
return void 0;
|
|
21144
|
+
}
|
|
21145
|
+
const existing = states.get(event);
|
|
21146
|
+
if (existing) {
|
|
21147
|
+
return existing;
|
|
21148
|
+
}
|
|
21149
|
+
const span = startSpan(
|
|
21150
|
+
withSpanInstrumentationName(
|
|
21151
|
+
{
|
|
21152
|
+
name: "Think.runTurn",
|
|
21153
|
+
spanAttributes: { type: "task" /* TASK */ }
|
|
21154
|
+
},
|
|
21155
|
+
INSTRUMENTATION_NAMES.CLOUDFLARE_THINK
|
|
21156
|
+
)
|
|
21157
|
+
);
|
|
21158
|
+
const runState = {
|
|
21159
|
+
aiResultPatched: false,
|
|
21160
|
+
fallbackInput: extractFallbackInput(event.self?.messages),
|
|
21161
|
+
finalized: false,
|
|
21162
|
+
inputLogged: false,
|
|
21163
|
+
span,
|
|
21164
|
+
startTime: getCurrentUnixTimestamp()
|
|
21165
|
+
};
|
|
21166
|
+
const metadata = {
|
|
21167
|
+
braintrust: {
|
|
21168
|
+
integration_name: "cloudflare-think",
|
|
21169
|
+
sdk_language: "typescript"
|
|
21170
|
+
}
|
|
21171
|
+
};
|
|
21172
|
+
if (typeof event.moduleVersion === "string") {
|
|
21173
|
+
metadata["cloudflare_think.version"] = event.moduleVersion;
|
|
21174
|
+
}
|
|
21175
|
+
span.log({ metadata });
|
|
21176
|
+
states.set(event, runState);
|
|
21177
|
+
if (span.spanId) {
|
|
21178
|
+
this.statesBySpanId.set(span.spanId, runState);
|
|
21179
|
+
}
|
|
21180
|
+
registerCloudflareThinkSpan(span);
|
|
21181
|
+
return runState;
|
|
21182
|
+
};
|
|
21183
|
+
if (contextManager && currentSpanStore && channel2.start) {
|
|
21184
|
+
channel2.start.bindStore(currentSpanStore, (event) => {
|
|
21185
|
+
const runState = ensureState2(event);
|
|
21186
|
+
return runState ? contextManager.wrapSpanForStore(runState.span) : currentSpanStore.getStore();
|
|
21187
|
+
});
|
|
21188
|
+
this.unsubscribers.push(
|
|
21189
|
+
() => channel2.start?.unbindStore(currentSpanStore)
|
|
21190
|
+
);
|
|
21191
|
+
}
|
|
21192
|
+
const handlers = {
|
|
21193
|
+
start: (event) => {
|
|
21194
|
+
ensureState2(event);
|
|
21195
|
+
},
|
|
21196
|
+
asyncEnd: (event) => {
|
|
21197
|
+
const runState = states.get(event);
|
|
21198
|
+
states.delete(event);
|
|
21199
|
+
if (!runState || runState.finalized || runState.aiResultPatched) {
|
|
21200
|
+
return;
|
|
21201
|
+
}
|
|
21202
|
+
this.finishState(runState, void 0, event.result);
|
|
21203
|
+
},
|
|
21204
|
+
error: (event) => {
|
|
21205
|
+
const runState = states.get(event);
|
|
21206
|
+
states.delete(event);
|
|
21207
|
+
if (runState) {
|
|
21208
|
+
this.finishState(runState, event.error);
|
|
21209
|
+
}
|
|
21210
|
+
}
|
|
21211
|
+
};
|
|
21212
|
+
channel2.subscribe(handlers);
|
|
21213
|
+
this.unsubscribers.push(() => channel2.unsubscribe(handlers));
|
|
21214
|
+
}
|
|
21215
|
+
subscribeToAISDKStreamTextSync() {
|
|
21216
|
+
const channel2 = aiSDKChannels.streamTextSync.tracingChannel();
|
|
21217
|
+
const handlers = {
|
|
21218
|
+
start: (event) => {
|
|
21219
|
+
this.startAISDKStream(event);
|
|
21220
|
+
},
|
|
21221
|
+
end: (event) => {
|
|
21222
|
+
this.endAISDKStream(event);
|
|
21223
|
+
},
|
|
21224
|
+
error: (event) => {
|
|
21225
|
+
this.errorAISDKStream(event);
|
|
21226
|
+
}
|
|
21227
|
+
};
|
|
21228
|
+
channel2.subscribe(handlers);
|
|
21229
|
+
this.unsubscribers.push(() => channel2.unsubscribe(handlers));
|
|
21230
|
+
}
|
|
21231
|
+
subscribeToAISDKStreamTextAsync() {
|
|
21232
|
+
const channel2 = aiSDKChannels.streamText.tracingChannel();
|
|
21233
|
+
const handlers = {
|
|
21234
|
+
start: (event) => {
|
|
21235
|
+
this.startAISDKStream(event);
|
|
21236
|
+
},
|
|
21237
|
+
asyncEnd: (event) => {
|
|
21238
|
+
this.endAISDKStream(event);
|
|
21239
|
+
},
|
|
21240
|
+
error: (event) => {
|
|
21241
|
+
this.errorAISDKStream(event);
|
|
21242
|
+
}
|
|
21243
|
+
};
|
|
21244
|
+
channel2.subscribe(handlers);
|
|
21245
|
+
this.unsubscribers.push(() => channel2.unsubscribe(handlers));
|
|
21246
|
+
}
|
|
21247
|
+
startAISDKStream(event) {
|
|
21248
|
+
const runState = this.currentState();
|
|
21249
|
+
if (!runState || runState.finalized) {
|
|
21250
|
+
return;
|
|
21251
|
+
}
|
|
21252
|
+
try {
|
|
21253
|
+
const prepared = prepareAISDKAgentCallInput(
|
|
21254
|
+
event.arguments[0],
|
|
21255
|
+
event,
|
|
21256
|
+
runState.span
|
|
21257
|
+
);
|
|
21258
|
+
runState.span.log({
|
|
21259
|
+
input: extractThinkTaskInput(prepared.input),
|
|
21260
|
+
metadata: {
|
|
21261
|
+
...prepared.metadata,
|
|
21262
|
+
braintrust: {
|
|
21263
|
+
integration_name: "cloudflare-think",
|
|
21264
|
+
sdk_language: "typescript"
|
|
21265
|
+
}
|
|
21266
|
+
}
|
|
21267
|
+
});
|
|
21268
|
+
runState.inputLogged = true;
|
|
21269
|
+
runState.aiEvent = event;
|
|
21270
|
+
Reflect.set(event, THINK_STATE_ID, runState.span.spanId);
|
|
21271
|
+
} catch (error) {
|
|
21272
|
+
debugLogger.error(
|
|
21273
|
+
"Error preparing @cloudflare/think AI SDK tracing:",
|
|
21274
|
+
error
|
|
21275
|
+
);
|
|
21276
|
+
}
|
|
21277
|
+
}
|
|
21278
|
+
endAISDKStream(event) {
|
|
21279
|
+
const runState = this.stateForAISDKEvent(event);
|
|
21280
|
+
if (!runState || runState.finalized) {
|
|
21281
|
+
return;
|
|
21282
|
+
}
|
|
21283
|
+
const patched = patchAISDKStreamingResult({
|
|
21284
|
+
defaultDenyOutputPaths: DEFAULT_DENY_OUTPUT_PATHS,
|
|
21285
|
+
endEvent: event,
|
|
21286
|
+
forceTopLevelMetrics: true,
|
|
21287
|
+
onComplete: () => this.releaseState(runState),
|
|
21288
|
+
result: event.result,
|
|
21289
|
+
span: runState.span,
|
|
21290
|
+
startTime: runState.startTime,
|
|
21291
|
+
transformOutput: extractThinkTaskOutput
|
|
21292
|
+
});
|
|
21293
|
+
runState.aiResultPatched = patched;
|
|
21294
|
+
if (!patched) {
|
|
21295
|
+
this.finishState(runState, void 0, event.result);
|
|
21296
|
+
}
|
|
21297
|
+
}
|
|
21298
|
+
errorAISDKStream(event) {
|
|
21299
|
+
const runState = this.stateForAISDKEvent(event);
|
|
21300
|
+
if (runState) {
|
|
21301
|
+
this.finishState(runState, event.error);
|
|
21302
|
+
}
|
|
21303
|
+
}
|
|
21304
|
+
currentState() {
|
|
21305
|
+
const parentIds = _internalGetGlobalState()?.contextManager.getParentSpanIds()?.spanParents ?? [];
|
|
21306
|
+
for (const parentId of parentIds) {
|
|
21307
|
+
const state = this.statesBySpanId.get(parentId);
|
|
21308
|
+
if (state) {
|
|
21309
|
+
return state;
|
|
21310
|
+
}
|
|
21311
|
+
}
|
|
21312
|
+
return void 0;
|
|
21313
|
+
}
|
|
21314
|
+
stateForAISDKEvent(event) {
|
|
21315
|
+
const spanId = Reflect.get(event, THINK_STATE_ID);
|
|
21316
|
+
return typeof spanId === "string" ? this.statesBySpanId.get(spanId) : void 0;
|
|
21317
|
+
}
|
|
21318
|
+
finishState(state, error, output) {
|
|
21319
|
+
if (state.finalized) {
|
|
21320
|
+
return;
|
|
21321
|
+
}
|
|
21322
|
+
state.finalized = true;
|
|
21323
|
+
try {
|
|
21324
|
+
if (!state.inputLogged && state.fallbackInput !== void 0) {
|
|
21325
|
+
state.span.log({ input: state.fallbackInput });
|
|
21326
|
+
}
|
|
21327
|
+
if (error !== void 0) {
|
|
21328
|
+
state.span.log({ error });
|
|
21329
|
+
} else if (output !== void 0) {
|
|
21330
|
+
state.span.log({ output: extractThinkTaskOutput(output) });
|
|
21331
|
+
}
|
|
21332
|
+
finalizeAISDKChildTracing(state.aiEvent);
|
|
21333
|
+
state.span.end();
|
|
21334
|
+
} finally {
|
|
21335
|
+
this.releaseState(state);
|
|
21336
|
+
}
|
|
21337
|
+
}
|
|
21338
|
+
releaseState(state) {
|
|
21339
|
+
state.finalized = true;
|
|
21340
|
+
unregisterCloudflareThinkSpan(state.span);
|
|
21341
|
+
if (state.span.spanId) {
|
|
21342
|
+
this.statesBySpanId.delete(state.span.spanId);
|
|
21343
|
+
}
|
|
21344
|
+
}
|
|
21345
|
+
};
|
|
21346
|
+
function extractFallbackInput(messages) {
|
|
21347
|
+
if (!Array.isArray(messages) || messages.length === 0) {
|
|
21348
|
+
return void 0;
|
|
21349
|
+
}
|
|
21350
|
+
let latestUserIndex = -1;
|
|
21351
|
+
for (let index = messages.length - 1; index >= 0; index--) {
|
|
21352
|
+
if (messages[index]?.role === "user") {
|
|
21353
|
+
latestUserIndex = index;
|
|
21354
|
+
break;
|
|
21355
|
+
}
|
|
21356
|
+
}
|
|
21357
|
+
const selected = latestUserIndex >= 0 ? messages.slice(latestUserIndex) : [];
|
|
21358
|
+
return selected.map((message) => ({
|
|
21359
|
+
role: message.role,
|
|
21360
|
+
content: message.content ?? message.parts
|
|
21361
|
+
}));
|
|
21362
|
+
}
|
|
21363
|
+
function extractThinkTaskOutput(output) {
|
|
21364
|
+
if (!isObject(output)) {
|
|
21365
|
+
return output;
|
|
21366
|
+
}
|
|
21367
|
+
if (typeof output.text === "string") {
|
|
21368
|
+
return { role: "assistant", content: output.text };
|
|
21369
|
+
}
|
|
21370
|
+
if (output.object !== void 0) {
|
|
21371
|
+
return output.object;
|
|
21372
|
+
}
|
|
21373
|
+
return output;
|
|
21374
|
+
}
|
|
21375
|
+
function extractThinkTaskInput(input) {
|
|
21376
|
+
if (!isObject(input)) {
|
|
21377
|
+
return input;
|
|
21378
|
+
}
|
|
21379
|
+
const system = input.instructions ?? input.system;
|
|
21380
|
+
if (Array.isArray(input.messages)) {
|
|
21381
|
+
return system === void 0 ? input.messages : [{ role: "system", content: system }, ...input.messages];
|
|
21382
|
+
}
|
|
21383
|
+
if (Array.isArray(input.prompt)) {
|
|
21384
|
+
return system === void 0 ? input.prompt : [{ role: "system", content: system }, ...input.prompt];
|
|
21385
|
+
}
|
|
21386
|
+
if (typeof input.prompt === "string") {
|
|
21387
|
+
const messages = [{ role: "user", content: input.prompt }];
|
|
21388
|
+
return system === void 0 ? messages : [{ role: "system", content: system }, ...messages];
|
|
21389
|
+
}
|
|
21390
|
+
return input;
|
|
21391
|
+
}
|
|
21392
|
+
|
|
20086
21393
|
// src/instrumentation/plugins/cursor-sdk-channels.ts
|
|
20087
21394
|
var cursorSDKChannels = defineChannels(
|
|
20088
21395
|
"@cursor/sdk",
|
|
@@ -22199,9 +23506,9 @@ function extractEmbedPromptTokenCount(response) {
|
|
|
22199
23506
|
let sawAny = false;
|
|
22200
23507
|
for (const embedding of embeddings) {
|
|
22201
23508
|
const embeddingStats = tryToDict(tryToDict(embedding)?.statistics);
|
|
22202
|
-
const
|
|
22203
|
-
if (typeof
|
|
22204
|
-
total +=
|
|
23509
|
+
const tokenCount2 = embeddingStats?.tokenCount;
|
|
23510
|
+
if (typeof tokenCount2 === "number" && Number.isFinite(tokenCount2)) {
|
|
23511
|
+
total += tokenCount2;
|
|
22205
23512
|
sawAny = true;
|
|
22206
23513
|
}
|
|
22207
23514
|
}
|
|
@@ -25848,6 +27155,470 @@ function aggregateMistralStreamChunks(chunks) {
|
|
|
25848
27155
|
};
|
|
25849
27156
|
}
|
|
25850
27157
|
|
|
27158
|
+
// src/instrumentation/plugins/ollama-channels.ts
|
|
27159
|
+
var ollamaChannels = defineChannels(
|
|
27160
|
+
"ollama",
|
|
27161
|
+
{
|
|
27162
|
+
chat: channel({
|
|
27163
|
+
channelName: "chat",
|
|
27164
|
+
kind: "async"
|
|
27165
|
+
}),
|
|
27166
|
+
generate: channel({
|
|
27167
|
+
channelName: "generate",
|
|
27168
|
+
kind: "async"
|
|
27169
|
+
}),
|
|
27170
|
+
embed: channel({
|
|
27171
|
+
channelName: "embed",
|
|
27172
|
+
kind: "async"
|
|
27173
|
+
})
|
|
27174
|
+
},
|
|
27175
|
+
{ instrumentationName: INSTRUMENTATION_NAMES.OLLAMA }
|
|
27176
|
+
);
|
|
27177
|
+
|
|
27178
|
+
// src/instrumentation/plugins/ollama-plugin.ts
|
|
27179
|
+
var OllamaPlugin = class extends BasePlugin {
|
|
27180
|
+
onEnable() {
|
|
27181
|
+
this.unsubscribers.push(
|
|
27182
|
+
traceStreamingChannel(ollamaChannels.chat, {
|
|
27183
|
+
name: "ollama.chat",
|
|
27184
|
+
type: "llm" /* LLM */,
|
|
27185
|
+
extractInput: extractOllamaChatInput,
|
|
27186
|
+
extractOutput: (result, event) => extractOllamaChatOutput(
|
|
27187
|
+
result,
|
|
27188
|
+
countOllamaToolCalls(event?.arguments?.[0]?.messages)
|
|
27189
|
+
),
|
|
27190
|
+
extractMetadata: extractOllamaResponseMetadata,
|
|
27191
|
+
extractMetrics: extractOllamaMetrics,
|
|
27192
|
+
aggregateChunks: aggregateOllamaChatChunks
|
|
27193
|
+
}),
|
|
27194
|
+
traceStreamingChannel(ollamaChannels.generate, {
|
|
27195
|
+
name: "ollama.generate",
|
|
27196
|
+
type: "llm" /* LLM */,
|
|
27197
|
+
extractInput: extractOllamaGenerateInput,
|
|
27198
|
+
extractOutput: extractOllamaGenerateOutput,
|
|
27199
|
+
extractMetadata: extractOllamaResponseMetadata,
|
|
27200
|
+
extractMetrics: extractOllamaMetrics,
|
|
27201
|
+
aggregateChunks: aggregateOllamaGenerateChunks
|
|
27202
|
+
}),
|
|
27203
|
+
traceAsyncChannel(ollamaChannels.embed, {
|
|
27204
|
+
name: "ollama.embed",
|
|
27205
|
+
type: "llm" /* LLM */,
|
|
27206
|
+
extractInput: extractOllamaEmbedInput,
|
|
27207
|
+
extractOutput: extractOllamaEmbedOutput,
|
|
27208
|
+
extractMetadata: extractOllamaResponseMetadata,
|
|
27209
|
+
extractMetrics: extractOllamaMetrics
|
|
27210
|
+
})
|
|
27211
|
+
);
|
|
27212
|
+
}
|
|
27213
|
+
onDisable() {
|
|
27214
|
+
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
27215
|
+
}
|
|
27216
|
+
};
|
|
27217
|
+
function isNonNegativeNumber(value) {
|
|
27218
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0;
|
|
27219
|
+
}
|
|
27220
|
+
function normalizeFinishReason(response, hasToolCalls = false) {
|
|
27221
|
+
if (hasToolCalls) {
|
|
27222
|
+
return "tool_calls";
|
|
27223
|
+
}
|
|
27224
|
+
return response?.done_reason || "stop";
|
|
27225
|
+
}
|
|
27226
|
+
function stringifyArguments(value) {
|
|
27227
|
+
if (typeof value === "string") {
|
|
27228
|
+
return value;
|
|
27229
|
+
}
|
|
27230
|
+
try {
|
|
27231
|
+
return JSON.stringify(value ?? {});
|
|
27232
|
+
} catch {
|
|
27233
|
+
return String(value);
|
|
27234
|
+
}
|
|
27235
|
+
}
|
|
27236
|
+
function syntheticToolCallId(name, index) {
|
|
27237
|
+
const normalizedName = name.replace(/[^a-zA-Z0-9_-]/g, "_") || "tool";
|
|
27238
|
+
return `ollama_call_${normalizedName}_${index}`;
|
|
27239
|
+
}
|
|
27240
|
+
function normalizeToolCall(toolCall, index) {
|
|
27241
|
+
const name = toolCall.function?.name;
|
|
27242
|
+
if (typeof name !== "string" || name.length === 0) {
|
|
27243
|
+
return void 0;
|
|
27244
|
+
}
|
|
27245
|
+
return {
|
|
27246
|
+
id: typeof toolCall.id === "string" && toolCall.id.length > 0 ? toolCall.id : syntheticToolCallId(name, index),
|
|
27247
|
+
type: "function",
|
|
27248
|
+
function: {
|
|
27249
|
+
name,
|
|
27250
|
+
arguments: stringifyArguments(toolCall.function?.arguments)
|
|
27251
|
+
}
|
|
27252
|
+
};
|
|
27253
|
+
}
|
|
27254
|
+
function normalizeToolCalls(toolCalls, syntheticIdOffset = 0) {
|
|
27255
|
+
if (!Array.isArray(toolCalls)) {
|
|
27256
|
+
return [];
|
|
27257
|
+
}
|
|
27258
|
+
return toolCalls.flatMap((toolCall, index) => {
|
|
27259
|
+
const normalized = normalizeToolCall(toolCall, syntheticIdOffset + index);
|
|
27260
|
+
return normalized ? [normalized] : [];
|
|
27261
|
+
});
|
|
27262
|
+
}
|
|
27263
|
+
function countOllamaToolCalls(messages) {
|
|
27264
|
+
if (!Array.isArray(messages)) {
|
|
27265
|
+
return 0;
|
|
27266
|
+
}
|
|
27267
|
+
return messages.reduce(
|
|
27268
|
+
(count, message) => count + (isObject(message) && Array.isArray(message.tool_calls) ? message.tool_calls.length : 0),
|
|
27269
|
+
0
|
|
27270
|
+
);
|
|
27271
|
+
}
|
|
27272
|
+
function imageBytes(value) {
|
|
27273
|
+
if (value instanceof Uint8Array) {
|
|
27274
|
+
return value;
|
|
27275
|
+
}
|
|
27276
|
+
if (value instanceof ArrayBuffer) {
|
|
27277
|
+
return new Uint8Array(value);
|
|
27278
|
+
}
|
|
27279
|
+
if (typeof value !== "string" || value.startsWith("data:")) {
|
|
27280
|
+
return void 0;
|
|
27281
|
+
}
|
|
27282
|
+
try {
|
|
27283
|
+
const decoded = atob(value.slice(0, 24));
|
|
27284
|
+
return Uint8Array.from(decoded, (character) => character.charCodeAt(0));
|
|
27285
|
+
} catch {
|
|
27286
|
+
return void 0;
|
|
27287
|
+
}
|
|
27288
|
+
}
|
|
27289
|
+
function inferImageMediaType(value) {
|
|
27290
|
+
if (typeof value === "string") {
|
|
27291
|
+
const dataUrlType = value.match(/^data:(image\/[^;]+);base64,/i)?.[1];
|
|
27292
|
+
if (dataUrlType) {
|
|
27293
|
+
return dataUrlType;
|
|
27294
|
+
}
|
|
27295
|
+
}
|
|
27296
|
+
const bytes = imageBytes(value);
|
|
27297
|
+
if (!bytes) {
|
|
27298
|
+
return void 0;
|
|
27299
|
+
}
|
|
27300
|
+
if (bytes[0] === 137 && bytes[1] === 80 && bytes[2] === 78 && bytes[3] === 71) {
|
|
27301
|
+
return "image/png";
|
|
27302
|
+
}
|
|
27303
|
+
if (bytes[0] === 255 && bytes[1] === 216 && bytes[2] === 255) {
|
|
27304
|
+
return "image/jpeg";
|
|
27305
|
+
}
|
|
27306
|
+
const signature = String.fromCharCode(...bytes.slice(0, 12));
|
|
27307
|
+
if (signature.startsWith("GIF87a") || signature.startsWith("GIF89a")) {
|
|
27308
|
+
return "image/gif";
|
|
27309
|
+
}
|
|
27310
|
+
if (signature.startsWith("RIFF") && signature.slice(8, 12) === "WEBP") {
|
|
27311
|
+
return "image/webp";
|
|
27312
|
+
}
|
|
27313
|
+
return void 0;
|
|
27314
|
+
}
|
|
27315
|
+
function normalizeTextAndImages(content, images) {
|
|
27316
|
+
if (!images || images.length === 0) {
|
|
27317
|
+
return { content };
|
|
27318
|
+
}
|
|
27319
|
+
const imageParts = [];
|
|
27320
|
+
const unrecognizedImages = [];
|
|
27321
|
+
for (const image of images) {
|
|
27322
|
+
let localImagePath;
|
|
27323
|
+
let localPathMediaType;
|
|
27324
|
+
if (typeof image === "string" && !/^data:/i.test(image) && !/^https?:\/\//i.test(image)) {
|
|
27325
|
+
const extension = image.match(/\.([a-z0-9]+)$/i)?.[1]?.toLowerCase();
|
|
27326
|
+
const extensionMediaType = {
|
|
27327
|
+
png: "image/png",
|
|
27328
|
+
jpg: "image/jpeg",
|
|
27329
|
+
jpeg: "image/jpeg",
|
|
27330
|
+
gif: "image/gif",
|
|
27331
|
+
webp: "image/webp"
|
|
27332
|
+
}[extension ?? ""];
|
|
27333
|
+
if (extensionMediaType && isomorph_default.statSync) {
|
|
27334
|
+
try {
|
|
27335
|
+
if (isomorph_default.statSync(image).isFile()) {
|
|
27336
|
+
localImagePath = image;
|
|
27337
|
+
localPathMediaType = extensionMediaType;
|
|
27338
|
+
}
|
|
27339
|
+
} catch {
|
|
27340
|
+
}
|
|
27341
|
+
}
|
|
27342
|
+
}
|
|
27343
|
+
const mediaType = localPathMediaType ?? inferImageMediaType(image);
|
|
27344
|
+
if (!mediaType) {
|
|
27345
|
+
unrecognizedImages.push(image);
|
|
27346
|
+
continue;
|
|
27347
|
+
}
|
|
27348
|
+
const processedImage = localImagePath ? new Attachment({
|
|
27349
|
+
data: localImagePath,
|
|
27350
|
+
filename: localImagePath.split(/[\\/]/).at(-1) ?? "image",
|
|
27351
|
+
contentType: mediaType
|
|
27352
|
+
}) : processInputAttachments({
|
|
27353
|
+
type: "image",
|
|
27354
|
+
image,
|
|
27355
|
+
mediaType
|
|
27356
|
+
}).image;
|
|
27357
|
+
imageParts.push({
|
|
27358
|
+
type: "image_url",
|
|
27359
|
+
image_url: { url: processedImage }
|
|
27360
|
+
});
|
|
27361
|
+
}
|
|
27362
|
+
return {
|
|
27363
|
+
content: imageParts.length > 0 ? [...content ? [{ type: "text", text: content }] : [], ...imageParts] : content,
|
|
27364
|
+
...unrecognizedImages.length > 0 ? { unrecognizedImages } : {}
|
|
27365
|
+
};
|
|
27366
|
+
}
|
|
27367
|
+
function normalizeMessage(message, toolCallId, syntheticToolCallIdOffset = 0) {
|
|
27368
|
+
if (typeof message.role !== "string") {
|
|
27369
|
+
return void 0;
|
|
27370
|
+
}
|
|
27371
|
+
const toolCalls = normalizeToolCalls(
|
|
27372
|
+
message.tool_calls,
|
|
27373
|
+
syntheticToolCallIdOffset
|
|
27374
|
+
);
|
|
27375
|
+
if (message.role === "tool") {
|
|
27376
|
+
const toolName = typeof message.tool_name === "string" && message.tool_name.length > 0 ? message.tool_name : "tool";
|
|
27377
|
+
return {
|
|
27378
|
+
role: "tool",
|
|
27379
|
+
tool_call_id: toolCallId ?? syntheticToolCallId(toolName, 0),
|
|
27380
|
+
content: typeof message.content === "string" ? message.content : ""
|
|
27381
|
+
};
|
|
27382
|
+
}
|
|
27383
|
+
const normalizedContent = normalizeTextAndImages(
|
|
27384
|
+
typeof message.content === "string" ? message.content || (toolCalls.length > 0 ? null : "") : toolCalls.length > 0 ? null : "",
|
|
27385
|
+
message.images
|
|
27386
|
+
);
|
|
27387
|
+
return {
|
|
27388
|
+
role: message.role,
|
|
27389
|
+
content: normalizedContent.content,
|
|
27390
|
+
...typeof message.thinking === "string" && message.thinking.length > 0 ? { reasoning: message.thinking } : {},
|
|
27391
|
+
...toolCalls.length > 0 ? { tool_calls: toolCalls } : {},
|
|
27392
|
+
...normalizedContent.unrecognizedImages ? { images: normalizedContent.unrecognizedImages } : {}
|
|
27393
|
+
};
|
|
27394
|
+
}
|
|
27395
|
+
function normalizeMessages(messages) {
|
|
27396
|
+
if (!Array.isArray(messages)) {
|
|
27397
|
+
return [];
|
|
27398
|
+
}
|
|
27399
|
+
const pendingToolCallIds = /* @__PURE__ */ new Map();
|
|
27400
|
+
let syntheticToolCallIdOffset = 0;
|
|
27401
|
+
return messages.flatMap((message) => {
|
|
27402
|
+
if (!isObject(message)) {
|
|
27403
|
+
return [];
|
|
27404
|
+
}
|
|
27405
|
+
const ollamaMessage = message;
|
|
27406
|
+
let toolCallId;
|
|
27407
|
+
if (ollamaMessage.role === "tool") {
|
|
27408
|
+
const toolName = ollamaMessage.tool_name;
|
|
27409
|
+
if (typeof toolName === "string") {
|
|
27410
|
+
toolCallId = pendingToolCallIds.get(toolName)?.shift();
|
|
27411
|
+
}
|
|
27412
|
+
}
|
|
27413
|
+
const normalized = normalizeMessage(
|
|
27414
|
+
ollamaMessage,
|
|
27415
|
+
toolCallId,
|
|
27416
|
+
syntheticToolCallIdOffset
|
|
27417
|
+
);
|
|
27418
|
+
if (Array.isArray(ollamaMessage.tool_calls)) {
|
|
27419
|
+
syntheticToolCallIdOffset += ollamaMessage.tool_calls.length;
|
|
27420
|
+
}
|
|
27421
|
+
if (ollamaMessage.role === "assistant" && normalized) {
|
|
27422
|
+
const toolCalls = Array.isArray(normalized.tool_calls) ? normalized.tool_calls : [];
|
|
27423
|
+
for (const toolCall of toolCalls) {
|
|
27424
|
+
if (!isObject(toolCall) || !isObject(toolCall.function)) {
|
|
27425
|
+
continue;
|
|
27426
|
+
}
|
|
27427
|
+
const name = toolCall.function.name;
|
|
27428
|
+
const id = toolCall.id;
|
|
27429
|
+
if (typeof name === "string" && typeof id === "string") {
|
|
27430
|
+
const ids = pendingToolCallIds.get(name) ?? [];
|
|
27431
|
+
ids.push(id);
|
|
27432
|
+
pendingToolCallIds.set(name, ids);
|
|
27433
|
+
}
|
|
27434
|
+
}
|
|
27435
|
+
}
|
|
27436
|
+
return normalized ? [normalized] : [];
|
|
27437
|
+
});
|
|
27438
|
+
}
|
|
27439
|
+
function normalizeToolDefinition(tool) {
|
|
27440
|
+
const fn = tool.function;
|
|
27441
|
+
if (!fn || typeof fn.name !== "string" || fn.name.length === 0) {
|
|
27442
|
+
return void 0;
|
|
27443
|
+
}
|
|
27444
|
+
return {
|
|
27445
|
+
type: "function",
|
|
27446
|
+
function: {
|
|
27447
|
+
name: fn.name,
|
|
27448
|
+
...typeof fn.description === "string" ? { description: fn.description } : {},
|
|
27449
|
+
...isObject(fn.parameters) ? { parameters: fn.parameters } : {}
|
|
27450
|
+
}
|
|
27451
|
+
};
|
|
27452
|
+
}
|
|
27453
|
+
function extractToolsMetadata(tools) {
|
|
27454
|
+
if (!Array.isArray(tools)) {
|
|
27455
|
+
return {};
|
|
27456
|
+
}
|
|
27457
|
+
const normalized = tools.flatMap((tool) => {
|
|
27458
|
+
if (!isObject(tool)) {
|
|
27459
|
+
return [];
|
|
27460
|
+
}
|
|
27461
|
+
const definition = normalizeToolDefinition(tool);
|
|
27462
|
+
return definition ? [definition] : [];
|
|
27463
|
+
});
|
|
27464
|
+
return normalized.length > 0 ? { tools: normalized } : {};
|
|
27465
|
+
}
|
|
27466
|
+
function extractOptionsMetadata(options) {
|
|
27467
|
+
if (!isObject(options)) {
|
|
27468
|
+
return {};
|
|
27469
|
+
}
|
|
27470
|
+
const metadata = {};
|
|
27471
|
+
const mappings = [
|
|
27472
|
+
["temperature", "temperature"],
|
|
27473
|
+
["top_p", "top_p"],
|
|
27474
|
+
["num_predict", "max_tokens"],
|
|
27475
|
+
["frequency_penalty", "frequency_penalty"],
|
|
27476
|
+
["presence_penalty", "presence_penalty"],
|
|
27477
|
+
["stop", "stop"]
|
|
27478
|
+
];
|
|
27479
|
+
for (const [source, target] of mappings) {
|
|
27480
|
+
if (options[source] !== void 0) {
|
|
27481
|
+
metadata[target] = options[source];
|
|
27482
|
+
}
|
|
27483
|
+
}
|
|
27484
|
+
return metadata;
|
|
27485
|
+
}
|
|
27486
|
+
function extractRequestMetadata(request) {
|
|
27487
|
+
return {
|
|
27488
|
+
provider: "ollama",
|
|
27489
|
+
...typeof request?.model === "string" ? { model: request.model } : {},
|
|
27490
|
+
...extractOptionsMetadata(request?.options),
|
|
27491
|
+
...request?.format !== void 0 ? { response_format: request.format } : {}
|
|
27492
|
+
};
|
|
27493
|
+
}
|
|
27494
|
+
function extractOllamaChatInput([request]) {
|
|
27495
|
+
return {
|
|
27496
|
+
input: normalizeMessages(request.messages),
|
|
27497
|
+
metadata: {
|
|
27498
|
+
...extractRequestMetadata(request),
|
|
27499
|
+
...extractToolsMetadata(request.tools)
|
|
27500
|
+
}
|
|
27501
|
+
};
|
|
27502
|
+
}
|
|
27503
|
+
function extractOllamaGenerateInput([request]) {
|
|
27504
|
+
const normalizedPrompt = normalizeTextAndImages(
|
|
27505
|
+
typeof request.prompt === "string" ? request.prompt : "",
|
|
27506
|
+
Array.isArray(request.images) ? request.images : void 0
|
|
27507
|
+
);
|
|
27508
|
+
const input = [
|
|
27509
|
+
...typeof request.system === "string" ? [{ role: "system", content: request.system }] : [],
|
|
27510
|
+
{
|
|
27511
|
+
role: "user",
|
|
27512
|
+
content: normalizedPrompt.content,
|
|
27513
|
+
...typeof request.suffix === "string" ? { suffix: request.suffix } : {},
|
|
27514
|
+
...normalizedPrompt.unrecognizedImages ? { images: normalizedPrompt.unrecognizedImages } : {}
|
|
27515
|
+
}
|
|
27516
|
+
];
|
|
27517
|
+
return {
|
|
27518
|
+
input,
|
|
27519
|
+
metadata: extractRequestMetadata(request)
|
|
27520
|
+
};
|
|
27521
|
+
}
|
|
27522
|
+
function extractOllamaEmbedInput([request]) {
|
|
27523
|
+
return {
|
|
27524
|
+
input: request.input,
|
|
27525
|
+
metadata: extractRequestMetadata(request)
|
|
27526
|
+
};
|
|
27527
|
+
}
|
|
27528
|
+
function extractOllamaChatOutput(result, syntheticToolCallIdOffset = 0) {
|
|
27529
|
+
if (!isObject(result) || !isObject(result.message)) {
|
|
27530
|
+
return void 0;
|
|
27531
|
+
}
|
|
27532
|
+
const message = normalizeMessage(
|
|
27533
|
+
result.message,
|
|
27534
|
+
void 0,
|
|
27535
|
+
syntheticToolCallIdOffset
|
|
27536
|
+
);
|
|
27537
|
+
if (!message) {
|
|
27538
|
+
return void 0;
|
|
27539
|
+
}
|
|
27540
|
+
const toolCalls = Array.isArray(message.tool_calls) ? message.tool_calls : [];
|
|
27541
|
+
return [
|
|
27542
|
+
{
|
|
27543
|
+
index: 0,
|
|
27544
|
+
finish_reason: normalizeFinishReason(result, toolCalls.length > 0),
|
|
27545
|
+
message
|
|
27546
|
+
}
|
|
27547
|
+
];
|
|
27548
|
+
}
|
|
27549
|
+
function extractOllamaGenerateOutput(result) {
|
|
27550
|
+
if (!isObject(result) || typeof result.response !== "string") {
|
|
27551
|
+
return void 0;
|
|
27552
|
+
}
|
|
27553
|
+
return [
|
|
27554
|
+
{
|
|
27555
|
+
index: 0,
|
|
27556
|
+
finish_reason: normalizeFinishReason(result),
|
|
27557
|
+
message: {
|
|
27558
|
+
role: "assistant",
|
|
27559
|
+
content: result.response,
|
|
27560
|
+
...typeof result.thinking === "string" && result.thinking.length > 0 ? { reasoning: result.thinking } : {}
|
|
27561
|
+
}
|
|
27562
|
+
}
|
|
27563
|
+
];
|
|
27564
|
+
}
|
|
27565
|
+
function extractOllamaEmbedOutput(result) {
|
|
27566
|
+
const embedding = Array.isArray(result?.embeddings) ? result.embeddings[0] : void 0;
|
|
27567
|
+
return Array.isArray(embedding) ? { embedding_length: embedding.length } : void 0;
|
|
27568
|
+
}
|
|
27569
|
+
function extractOllamaResponseMetadata(result) {
|
|
27570
|
+
return typeof result?.model === "string" ? { model: result.model } : void 0;
|
|
27571
|
+
}
|
|
27572
|
+
function extractOllamaMetrics(result) {
|
|
27573
|
+
const metrics = {};
|
|
27574
|
+
const promptTokens = result?.prompt_eval_count;
|
|
27575
|
+
const completionTokens = result?.eval_count;
|
|
27576
|
+
if (isNonNegativeNumber(promptTokens)) {
|
|
27577
|
+
metrics.prompt_tokens = promptTokens;
|
|
27578
|
+
}
|
|
27579
|
+
if (isNonNegativeNumber(completionTokens)) {
|
|
27580
|
+
metrics.completion_tokens = completionTokens;
|
|
27581
|
+
}
|
|
27582
|
+
if (isNonNegativeNumber(promptTokens) || isNonNegativeNumber(completionTokens)) {
|
|
27583
|
+
metrics.tokens = (isNonNegativeNumber(promptTokens) ? promptTokens : 0) + (isNonNegativeNumber(completionTokens) ? completionTokens : 0);
|
|
27584
|
+
}
|
|
27585
|
+
return metrics;
|
|
27586
|
+
}
|
|
27587
|
+
function aggregateOllamaChatChunks(chunks, _result, event, _startTime) {
|
|
27588
|
+
const last = chunks.at(-1);
|
|
27589
|
+
const message = {
|
|
27590
|
+
role: "assistant",
|
|
27591
|
+
content: chunks.map((chunk) => chunk.message?.content ?? "").join(""),
|
|
27592
|
+
thinking: chunks.map((chunk) => chunk.message?.thinking ?? "").join(""),
|
|
27593
|
+
tool_calls: chunks.flatMap((chunk) => chunk.message?.tool_calls ?? [])
|
|
27594
|
+
};
|
|
27595
|
+
const response = {
|
|
27596
|
+
...last,
|
|
27597
|
+
message
|
|
27598
|
+
};
|
|
27599
|
+
return {
|
|
27600
|
+
output: extractOllamaChatOutput(
|
|
27601
|
+
response,
|
|
27602
|
+
countOllamaToolCalls(event?.arguments?.[0]?.messages)
|
|
27603
|
+
),
|
|
27604
|
+
metrics: extractOllamaMetrics(last ?? {}),
|
|
27605
|
+
metadata: extractOllamaResponseMetadata(last ?? {})
|
|
27606
|
+
};
|
|
27607
|
+
}
|
|
27608
|
+
function aggregateOllamaGenerateChunks(chunks, _result, _event, _startTime) {
|
|
27609
|
+
const last = chunks.at(-1);
|
|
27610
|
+
const response = {
|
|
27611
|
+
...last,
|
|
27612
|
+
response: chunks.map((chunk) => chunk.response ?? "").join(""),
|
|
27613
|
+
thinking: chunks.map((chunk) => chunk.thinking ?? "").join("")
|
|
27614
|
+
};
|
|
27615
|
+
return {
|
|
27616
|
+
output: extractOllamaGenerateOutput(response),
|
|
27617
|
+
metrics: extractOllamaMetrics(last ?? {}),
|
|
27618
|
+
metadata: extractOllamaResponseMetadata(last ?? {})
|
|
27619
|
+
};
|
|
27620
|
+
}
|
|
27621
|
+
|
|
25851
27622
|
// src/instrumentation/plugins/google-adk-channels.ts
|
|
25852
27623
|
var googleADKChannels = defineChannels(
|
|
25853
27624
|
"@google/adk",
|
|
@@ -28632,7 +30403,7 @@ function getStringProperty2(obj, key) {
|
|
|
28632
30403
|
return typeof value === "string" ? value : void 0;
|
|
28633
30404
|
}
|
|
28634
30405
|
function extractMetricsFromUsage(usage) {
|
|
28635
|
-
const
|
|
30406
|
+
const rawMetrics = {
|
|
28636
30407
|
prompt_tokens: usage.inputTokens,
|
|
28637
30408
|
completion_tokens: usage.outputTokens,
|
|
28638
30409
|
...extractAnthropicCacheTokens(
|
|
@@ -28641,10 +30412,10 @@ function extractMetricsFromUsage(usage) {
|
|
|
28641
30412
|
)
|
|
28642
30413
|
};
|
|
28643
30414
|
if (usage.reasoningTokens !== void 0) {
|
|
28644
|
-
|
|
28645
|
-
|
|
30415
|
+
rawMetrics.completion_reasoning_tokens = usage.reasoningTokens;
|
|
30416
|
+
rawMetrics.reasoning_tokens = usage.reasoningTokens;
|
|
28646
30417
|
}
|
|
28647
|
-
|
|
30418
|
+
const metrics = finalizeAnthropicTokens(rawMetrics);
|
|
28648
30419
|
const metadata = {
|
|
28649
30420
|
model: usage.model
|
|
28650
30421
|
};
|
|
@@ -29583,17 +31354,20 @@ var FlueObserveBridge = class {
|
|
|
29583
31354
|
return;
|
|
29584
31355
|
}
|
|
29585
31356
|
const metadata = {
|
|
31357
|
+
...event.runId ? this.runsById.get(event.runId)?.metadata : {},
|
|
29586
31358
|
...extractEventMetadata(event),
|
|
29587
31359
|
"flue.operation": event.operationKind,
|
|
29588
31360
|
provider: "flue"
|
|
29589
31361
|
};
|
|
29590
31362
|
const parent = this.parentSpanForEvent(event);
|
|
29591
|
-
const
|
|
31363
|
+
const args = {
|
|
29592
31364
|
name: `flue.${event.operationKind}`,
|
|
29593
31365
|
spanAttributes: { type: "task" /* TASK */ },
|
|
29594
31366
|
startTime: eventTime(event.timestamp),
|
|
29595
31367
|
event: { metadata }
|
|
29596
|
-
}
|
|
31368
|
+
};
|
|
31369
|
+
const runSpan = event.runId ? this.runsById.get(event.runId)?.span : void 0;
|
|
31370
|
+
const span = event.operationKind === "prompt" && (!parent || parent === runSpan) ? startFlueRootSpan(args) : startFlueSpan(parent, args);
|
|
29597
31371
|
this.operationsById.set(event.operationId, { metadata, span });
|
|
29598
31372
|
}
|
|
29599
31373
|
handleOperation(event) {
|
|
@@ -29601,16 +31375,21 @@ var FlueObserveBridge = class {
|
|
|
29601
31375
|
return;
|
|
29602
31376
|
}
|
|
29603
31377
|
const state = this.operationsById.get(event.operationId) ?? this.startSyntheticOperation(event);
|
|
29604
|
-
const output = operationOutput(event);
|
|
31378
|
+
const output = operationOutput(event) ?? outputFromAgentTurn(state.latestAgentOutput);
|
|
29605
31379
|
const metadata = {
|
|
29606
31380
|
...state.metadata,
|
|
29607
31381
|
...extractEventMetadata(event),
|
|
29608
31382
|
...event.isError !== void 0 ? { "flue.is_error": event.isError } : {},
|
|
29609
31383
|
...event.usage ? { "flue.usage": event.usage } : {}
|
|
29610
31384
|
};
|
|
31385
|
+
const input = flueOperationInput(event);
|
|
31386
|
+
if (!state.loggedInput && input !== void 0) {
|
|
31387
|
+
safeLog3(state.span, { input });
|
|
31388
|
+
state.loggedInput = true;
|
|
31389
|
+
}
|
|
29611
31390
|
this.finishPendingChildrenForOperation(event, output);
|
|
29612
31391
|
safeLog3(state.span, {
|
|
29613
|
-
...event.isError ? { error: toLoggedError(event.error) } : {},
|
|
31392
|
+
...event.isError ? { error: toLoggedError(event.errorInfo ?? event.error) } : {},
|
|
29614
31393
|
metadata,
|
|
29615
31394
|
metrics: durationMetrics2(event.durationMs),
|
|
29616
31395
|
output
|
|
@@ -29624,6 +31403,8 @@ var FlueObserveBridge = class {
|
|
|
29624
31403
|
return;
|
|
29625
31404
|
}
|
|
29626
31405
|
const input = flueTurnRequestInput(event);
|
|
31406
|
+
const operation = event.operationId ? this.operationsById.get(event.operationId) : void 0;
|
|
31407
|
+
const turnInput = prepareFlueTurnInput(event, input, operation);
|
|
29627
31408
|
const model = flueTurnRequestModel(event);
|
|
29628
31409
|
const provider = flueTurnRequestProvider(event);
|
|
29629
31410
|
const api = flueTurnRequestApi(event);
|
|
@@ -29636,20 +31417,22 @@ var FlueObserveBridge = class {
|
|
|
29636
31417
|
...provider ? { "flue.provider": provider } : {},
|
|
29637
31418
|
...event.purpose ? { "flue.turn_purpose": event.purpose } : {},
|
|
29638
31419
|
...reasoning ? { reasoning } : {},
|
|
29639
|
-
...
|
|
29640
|
-
...input?.tools ? { tools: input.tools } : {}
|
|
31420
|
+
...turnInput.metadata
|
|
29641
31421
|
};
|
|
29642
31422
|
const parent = this.parentSpanForTurn(event);
|
|
29643
31423
|
const span = startFlueSpan(parent, {
|
|
29644
|
-
name:
|
|
31424
|
+
name: "flue.turn",
|
|
29645
31425
|
spanAttributes: { type: "llm" /* LLM */ },
|
|
29646
31426
|
startTime: eventTime(event.timestamp),
|
|
29647
31427
|
event: {
|
|
29648
|
-
input:
|
|
31428
|
+
input: turnInput.messages,
|
|
29649
31429
|
metadata
|
|
29650
31430
|
}
|
|
29651
31431
|
});
|
|
29652
|
-
this.logOperationInput(
|
|
31432
|
+
this.logOperationInput(
|
|
31433
|
+
event.operationId,
|
|
31434
|
+
latestUserMessageInput(input?.messages)
|
|
31435
|
+
);
|
|
29653
31436
|
this.turnsByKey.set(key, { metadata, span });
|
|
29654
31437
|
}
|
|
29655
31438
|
handleTurn(event) {
|
|
@@ -29685,6 +31468,12 @@ var FlueObserveBridge = class {
|
|
|
29685
31468
|
},
|
|
29686
31469
|
output
|
|
29687
31470
|
});
|
|
31471
|
+
if (event.purpose === "agent" && event.operationId) {
|
|
31472
|
+
const operation = this.operationsById.get(event.operationId);
|
|
31473
|
+
if (operation) {
|
|
31474
|
+
operation.latestAgentOutput = output;
|
|
31475
|
+
}
|
|
31476
|
+
}
|
|
29688
31477
|
safeEnd(state.span, eventTime(event.timestamp));
|
|
29689
31478
|
this.turnsByKey.delete(key);
|
|
29690
31479
|
}
|
|
@@ -29764,7 +31553,7 @@ var FlueObserveBridge = class {
|
|
|
29764
31553
|
return;
|
|
29765
31554
|
}
|
|
29766
31555
|
safeLog3(state.span, {
|
|
29767
|
-
...event.isError ? { error: toLoggedError(event.result) } : {},
|
|
31556
|
+
...event.isError ? { error: toLoggedError(event.errorInfo ?? event.result) } : {},
|
|
29768
31557
|
metadata: {
|
|
29769
31558
|
...state.metadata,
|
|
29770
31559
|
...extractEventMetadata(event),
|
|
@@ -29810,6 +31599,7 @@ var FlueObserveBridge = class {
|
|
|
29810
31599
|
...event.usage ? { "flue.usage": event.usage } : {}
|
|
29811
31600
|
};
|
|
29812
31601
|
safeLog3(state.span, {
|
|
31602
|
+
...event.isError ? { error: toLoggedError(event.errorInfo ?? event.error) } : {},
|
|
29813
31603
|
metadata,
|
|
29814
31604
|
metrics: {
|
|
29815
31605
|
...durationMetrics2(event.durationMs),
|
|
@@ -29889,16 +31679,20 @@ var FlueObserveBridge = class {
|
|
|
29889
31679
|
}
|
|
29890
31680
|
startSyntheticOperation(event) {
|
|
29891
31681
|
const metadata = {
|
|
31682
|
+
...event.runId ? this.runsById.get(event.runId)?.metadata : {},
|
|
29892
31683
|
...extractEventMetadata(event),
|
|
29893
31684
|
"flue.operation": event.operationKind,
|
|
29894
31685
|
provider: "flue"
|
|
29895
31686
|
};
|
|
29896
|
-
const
|
|
31687
|
+
const args = {
|
|
29897
31688
|
name: `flue.${event.operationKind}`,
|
|
29898
31689
|
spanAttributes: { type: "task" /* TASK */ },
|
|
29899
31690
|
startTime: eventTime(event.timestamp),
|
|
29900
31691
|
event: { metadata }
|
|
29901
|
-
}
|
|
31692
|
+
};
|
|
31693
|
+
const parent = this.parentSpanForEvent(event);
|
|
31694
|
+
const runSpan = event.runId ? this.runsById.get(event.runId)?.span : void 0;
|
|
31695
|
+
const span = event.operationKind === "prompt" && (!parent || parent === runSpan) ? startFlueRootSpan(args) : startFlueSpan(parent, args);
|
|
29902
31696
|
return { metadata, span };
|
|
29903
31697
|
}
|
|
29904
31698
|
startSyntheticTurn(event) {
|
|
@@ -29914,7 +31708,7 @@ var FlueObserveBridge = class {
|
|
|
29914
31708
|
...event.purpose ? { "flue.turn_purpose": event.purpose } : {}
|
|
29915
31709
|
};
|
|
29916
31710
|
const span = startFlueSpan(this.parentSpanForEvent(event), {
|
|
29917
|
-
name:
|
|
31711
|
+
name: "flue.turn",
|
|
29918
31712
|
spanAttributes: { type: "llm" /* LLM */ },
|
|
29919
31713
|
startTime: eventTime(event.timestamp),
|
|
29920
31714
|
event: { metadata }
|
|
@@ -30046,7 +31840,10 @@ function extractEventMetadata(event, ctx) {
|
|
|
30046
31840
|
return {
|
|
30047
31841
|
...event.runId ? { "flue.run_id": event.runId } : {},
|
|
30048
31842
|
...event.instanceId ? { "flue.instance_id": event.instanceId } : {},
|
|
31843
|
+
...event.submissionId ? { "flue.submission_id": event.submissionId } : {},
|
|
30049
31844
|
...event.dispatchId ? { "flue.dispatch_id": event.dispatchId } : {},
|
|
31845
|
+
...event.agentName ? { "flue.agent_name": event.agentName } : {},
|
|
31846
|
+
...event.conversationId ? { "flue.conversation_id": event.conversationId } : {},
|
|
30050
31847
|
...typeof event.eventIndex === "number" ? { "flue.event_index": event.eventIndex } : {},
|
|
30051
31848
|
...event.session ? { "flue.session": event.session } : {},
|
|
30052
31849
|
...event.parentSession ? { "flue.parent_session": event.parentSession } : {},
|
|
@@ -30074,8 +31871,73 @@ function flueRunInput(event) {
|
|
|
30074
31871
|
function flueTurnRequestInput(event) {
|
|
30075
31872
|
return event.request?.input ?? event.input;
|
|
30076
31873
|
}
|
|
31874
|
+
function prepareFlueTurnInput(event, input, operation) {
|
|
31875
|
+
const messages = input?.messages;
|
|
31876
|
+
const tracksUserTurn = event.purpose === "agent" && operation?.metadata["flue.operation"] === "prompt" && Array.isArray(messages);
|
|
31877
|
+
if (!tracksUserTurn) {
|
|
31878
|
+
return {
|
|
31879
|
+
messages,
|
|
31880
|
+
metadata: {
|
|
31881
|
+
...input?.systemPrompt ? { "flue.system_prompt": input.systemPrompt } : {},
|
|
31882
|
+
...input?.tools ? { tools: input.tools } : {}
|
|
31883
|
+
}
|
|
31884
|
+
};
|
|
31885
|
+
}
|
|
31886
|
+
const previous = operation.turnInputState;
|
|
31887
|
+
const previousMessageCount = previous?.messageCount ?? 0;
|
|
31888
|
+
const boundaryFingerprint = messages.length > 0 ? fingerprintJsonValue(messages[messages.length - 1]) : void 0;
|
|
31889
|
+
const continuesPreviousInput = previous !== void 0 && messages.length >= previousMessageCount && (previousMessageCount === 0 || previous.boundaryFingerprint !== void 0 && previous.boundaryFingerprint === fingerprintJsonValue(messages[previousMessageCount - 1]));
|
|
31890
|
+
const inputMode = previous === void 0 ? "full" : continuesPreviousInput ? "delta" : "reset";
|
|
31891
|
+
const systemPromptFingerprint = fingerprintJsonValue(input?.systemPrompt);
|
|
31892
|
+
const toolsFingerprint = fingerprintJsonValue(input?.tools);
|
|
31893
|
+
operation.turnInputState = {
|
|
31894
|
+
...boundaryFingerprint !== void 0 ? { boundaryFingerprint } : {},
|
|
31895
|
+
messageCount: messages.length,
|
|
31896
|
+
...systemPromptFingerprint !== void 0 ? { systemPromptFingerprint } : {},
|
|
31897
|
+
...toolsFingerprint !== void 0 ? { toolsFingerprint } : {}
|
|
31898
|
+
};
|
|
31899
|
+
return {
|
|
31900
|
+
messages: continuesPreviousInput ? messages.slice(previousMessageCount) : messages,
|
|
31901
|
+
metadata: {
|
|
31902
|
+
"flue.input_mode": inputMode,
|
|
31903
|
+
...continuesPreviousInput ? { "flue.input_message_offset": previousMessageCount } : {},
|
|
31904
|
+
...input?.systemPrompt && (!continuesPreviousInput || systemPromptFingerprint !== previous?.systemPromptFingerprint) ? { "flue.system_prompt": input.systemPrompt } : {},
|
|
31905
|
+
...input?.tools && (!continuesPreviousInput || toolsFingerprint !== previous?.toolsFingerprint) ? { tools: input.tools } : {}
|
|
31906
|
+
}
|
|
31907
|
+
};
|
|
31908
|
+
}
|
|
31909
|
+
function fingerprintJsonValue(value) {
|
|
31910
|
+
try {
|
|
31911
|
+
const serialized = JSON.stringify(value);
|
|
31912
|
+
if (serialized === void 0) {
|
|
31913
|
+
return void 0;
|
|
31914
|
+
}
|
|
31915
|
+
let hash = 2166136261;
|
|
31916
|
+
for (let i = 0; i < serialized.length; i++) {
|
|
31917
|
+
hash = Math.imul(hash ^ serialized.charCodeAt(i), 16777619);
|
|
31918
|
+
}
|
|
31919
|
+
return `${serialized.length}:${hash >>> 0}`;
|
|
31920
|
+
} catch {
|
|
31921
|
+
return void 0;
|
|
31922
|
+
}
|
|
31923
|
+
}
|
|
31924
|
+
function latestUserMessageInput(messages) {
|
|
31925
|
+
if (!messages) {
|
|
31926
|
+
return void 0;
|
|
31927
|
+
}
|
|
31928
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
31929
|
+
const message = messages[i];
|
|
31930
|
+
if (isObjectLike(message) && Reflect.get(message, "role") === "user") {
|
|
31931
|
+
return [message];
|
|
31932
|
+
}
|
|
31933
|
+
}
|
|
31934
|
+
return void 0;
|
|
31935
|
+
}
|
|
31936
|
+
function flueOperationInput(event) {
|
|
31937
|
+
return typeof event.agentInput?.text === "string" ? [{ content: event.agentInput.text, role: "user" }] : void 0;
|
|
31938
|
+
}
|
|
30077
31939
|
function flueTurnRequestModel(event) {
|
|
30078
|
-
return event.request?.model ?? event.model;
|
|
31940
|
+
return event.request?.requestedModel ?? event.request?.model ?? event.model;
|
|
30079
31941
|
}
|
|
30080
31942
|
function flueTurnRequestProvider(event) {
|
|
30081
31943
|
return event.request?.providerName ?? event.provider ?? event.request?.providerId;
|
|
@@ -30084,10 +31946,10 @@ function flueTurnRequestApi(event) {
|
|
|
30084
31946
|
return event.request?.api ?? event.api;
|
|
30085
31947
|
}
|
|
30086
31948
|
function flueTurnRequestReasoning(event) {
|
|
30087
|
-
return event.request?.reasoning ?? event.reasoning;
|
|
31949
|
+
return event.request?.reasoningLevel ?? event.request?.reasoning ?? event.reasoning;
|
|
30088
31950
|
}
|
|
30089
31951
|
function flueTurnModel(event) {
|
|
30090
|
-
return event.request?.model ?? event.model;
|
|
31952
|
+
return event.response?.responseModel ?? event.request?.requestedModel ?? event.request?.model ?? event.model;
|
|
30091
31953
|
}
|
|
30092
31954
|
function flueTurnProvider(event) {
|
|
30093
31955
|
return event.request?.providerName ?? event.provider ?? event.request?.providerId;
|
|
@@ -30102,7 +31964,7 @@ function flueTurnOutput(event) {
|
|
|
30102
31964
|
return event.response?.output ?? event.output;
|
|
30103
31965
|
}
|
|
30104
31966
|
function flueTurnStopReason(event) {
|
|
30105
|
-
return event.response?.stopReason ?? event.stopReason;
|
|
31967
|
+
return event.response?.finishReason ?? event.response?.stopReason ?? event.stopReason;
|
|
30106
31968
|
}
|
|
30107
31969
|
function flueTurnError(event) {
|
|
30108
31970
|
return event.response?.error ?? event.response?.errorInfo?.message ?? event.error;
|
|
@@ -30117,6 +31979,9 @@ function flueToolInput(event) {
|
|
|
30117
31979
|
return event.input;
|
|
30118
31980
|
}
|
|
30119
31981
|
function flueToolOutput(event) {
|
|
31982
|
+
if (Object.hasOwn(event, "effectiveResult")) {
|
|
31983
|
+
return event.effectiveResult;
|
|
31984
|
+
}
|
|
30120
31985
|
return event.output !== void 0 ? event.output : event.result;
|
|
30121
31986
|
}
|
|
30122
31987
|
function flueToolError(event) {
|
|
@@ -30124,10 +31989,36 @@ function flueToolError(event) {
|
|
|
30124
31989
|
}
|
|
30125
31990
|
function operationOutput(event) {
|
|
30126
31991
|
if (event.operationKind === "prompt" || event.operationKind === "skill") {
|
|
30127
|
-
return llmResultFromOperationResult(event.result);
|
|
31992
|
+
return outputFromAgentInvocation(event.agentOutput) ?? llmResultFromOperationResult(event.result);
|
|
30128
31993
|
}
|
|
30129
31994
|
return event.result ?? (event.operationKind === "compact" ? { completed: true } : void 0);
|
|
30130
31995
|
}
|
|
31996
|
+
function outputFromAgentInvocation(output) {
|
|
31997
|
+
if (output?.type === "text") {
|
|
31998
|
+
return output.text;
|
|
31999
|
+
}
|
|
32000
|
+
if (output?.type === "data") {
|
|
32001
|
+
return output.data;
|
|
32002
|
+
}
|
|
32003
|
+
return void 0;
|
|
32004
|
+
}
|
|
32005
|
+
function outputFromAgentTurn(output) {
|
|
32006
|
+
if (!isObjectLike(output)) {
|
|
32007
|
+
return output;
|
|
32008
|
+
}
|
|
32009
|
+
const content = Reflect.get(output, "content");
|
|
32010
|
+
if (!Array.isArray(content)) {
|
|
32011
|
+
return output;
|
|
32012
|
+
}
|
|
32013
|
+
const text = content.flatMap((part) => {
|
|
32014
|
+
if (!isObjectLike(part) || Reflect.get(part, "type") !== "text") {
|
|
32015
|
+
return [];
|
|
32016
|
+
}
|
|
32017
|
+
const value = Reflect.get(part, "text");
|
|
32018
|
+
return typeof value === "string" ? [value] : [];
|
|
32019
|
+
});
|
|
32020
|
+
return text.length > 0 ? text.join("") : output;
|
|
32021
|
+
}
|
|
30131
32022
|
function llmResultFromOperationResult(result) {
|
|
30132
32023
|
if (!isObjectLike(result)) {
|
|
30133
32024
|
return result;
|
|
@@ -30202,6 +32093,21 @@ function startFlueSpan(parent, args) {
|
|
|
30202
32093
|
withSpanInstrumentationName(args, INSTRUMENTATION_NAMES.FLUE)
|
|
30203
32094
|
);
|
|
30204
32095
|
}
|
|
32096
|
+
function startFlueRootSpan(args) {
|
|
32097
|
+
const state = _internalGetGlobalState();
|
|
32098
|
+
const spanId = state.idGenerator.getSpanId();
|
|
32099
|
+
const rootSpanId = state.idGenerator.shareRootSpanId() ? spanId : state.idGenerator.getTraceId();
|
|
32100
|
+
return withCurrent(
|
|
32101
|
+
NOOP_SPAN,
|
|
32102
|
+
() => startSpan({
|
|
32103
|
+
...withSpanInstrumentationName(args, INSTRUMENTATION_NAMES.FLUE),
|
|
32104
|
+
parentSpanIds: { parentSpanIds: [], rootSpanId },
|
|
32105
|
+
spanId,
|
|
32106
|
+
state
|
|
32107
|
+
}),
|
|
32108
|
+
state
|
|
32109
|
+
);
|
|
32110
|
+
}
|
|
30205
32111
|
function runWithCurrentSpanStore(span, next) {
|
|
30206
32112
|
const state = _internalGetGlobalState();
|
|
30207
32113
|
const contextManager = state?.contextManager;
|
|
@@ -30226,7 +32132,7 @@ function safeEnd(span, endTime) {
|
|
|
30226
32132
|
}
|
|
30227
32133
|
}
|
|
30228
32134
|
function logInstrumentationError3(label, error) {
|
|
30229
|
-
|
|
32135
|
+
debugLogger.debug(`Error in ${label} instrumentation:`, error);
|
|
30230
32136
|
}
|
|
30231
32137
|
|
|
30232
32138
|
// src/wrappers/langchain/callback-handler.ts
|
|
@@ -31155,12 +33061,13 @@ var piCodingAgentChannels = defineChannels(
|
|
|
31155
33061
|
);
|
|
31156
33062
|
|
|
31157
33063
|
// src/instrumentation/plugins/pi-coding-agent-plugin.ts
|
|
31158
|
-
var
|
|
33064
|
+
var piAgentPatchStates = /* @__PURE__ */ new WeakMap();
|
|
33065
|
+
var piAgentEventSubscriptions = /* @__PURE__ */ new WeakSet();
|
|
31159
33066
|
var piPromptContextStore;
|
|
31160
33067
|
var PiCodingAgentPlugin = class extends BasePlugin {
|
|
31161
33068
|
activePromptStates = /* @__PURE__ */ new Set();
|
|
31162
33069
|
onEnable() {
|
|
31163
|
-
this.
|
|
33070
|
+
this.interceptPrompt();
|
|
31164
33071
|
}
|
|
31165
33072
|
onDisable() {
|
|
31166
33073
|
for (const unsubscribe of this.unsubscribers) {
|
|
@@ -31168,65 +33075,74 @@ var PiCodingAgentPlugin = class extends BasePlugin {
|
|
|
31168
33075
|
}
|
|
31169
33076
|
this.unsubscribers = [];
|
|
31170
33077
|
for (const state of [...this.activePromptStates]) {
|
|
31171
|
-
|
|
31172
|
-
logInstrumentationError4("Pi Coding Agent disable cleanup", error);
|
|
31173
|
-
});
|
|
33078
|
+
finishPiPromptRun(state);
|
|
31174
33079
|
}
|
|
31175
33080
|
}
|
|
31176
|
-
|
|
31177
|
-
|
|
31178
|
-
|
|
31179
|
-
|
|
31180
|
-
|
|
31181
|
-
|
|
31182
|
-
|
|
31183
|
-
|
|
31184
|
-
|
|
31185
|
-
|
|
31186
|
-
|
|
31187
|
-
|
|
31188
|
-
|
|
31189
|
-
|
|
31190
|
-
|
|
31191
|
-
|
|
31192
|
-
|
|
31193
|
-
|
|
31194
|
-
|
|
31195
|
-
states.delete(event);
|
|
31196
|
-
state.promptCallEnded = true;
|
|
31197
|
-
if (!state.finalized && state.deferCompletionUntilTurnEnd && !state.turnEnded) {
|
|
31198
|
-
if (!state.sawStreamFn) {
|
|
31199
|
-
state.queued = true;
|
|
31200
|
-
if (!state.streamPatchState.queuedPromptStates.includes(state)) {
|
|
31201
|
-
state.streamPatchState.queuedPromptStates.push(state);
|
|
31202
|
-
}
|
|
33081
|
+
interceptPrompt() {
|
|
33082
|
+
this.unsubscribers.push(
|
|
33083
|
+
piCodingAgentChannels.prompt.intercept(
|
|
33084
|
+
(target, thisArg, args, additional) => {
|
|
33085
|
+
const invokeTarget = () => Reflect.apply(target, thisArg, args);
|
|
33086
|
+
let state;
|
|
33087
|
+
try {
|
|
33088
|
+
state = startPiPromptRun(
|
|
33089
|
+
{
|
|
33090
|
+
...additional,
|
|
33091
|
+
arguments: args,
|
|
33092
|
+
self: thisArg
|
|
33093
|
+
},
|
|
33094
|
+
(finalizedState) => {
|
|
33095
|
+
this.activePromptStates.delete(finalizedState);
|
|
33096
|
+
}
|
|
33097
|
+
);
|
|
33098
|
+
} catch (error) {
|
|
33099
|
+
logInstrumentationError4("Pi Coding Agent prompt start", error);
|
|
31203
33100
|
}
|
|
31204
|
-
|
|
31205
|
-
|
|
31206
|
-
|
|
31207
|
-
|
|
31208
|
-
|
|
31209
|
-
|
|
31210
|
-
|
|
31211
|
-
|
|
33101
|
+
if (!state) {
|
|
33102
|
+
return runWithAutoInstrumentationSuppressed(invokeTarget);
|
|
33103
|
+
}
|
|
33104
|
+
this.activePromptStates.add(state);
|
|
33105
|
+
return promptContextStore().run(
|
|
33106
|
+
state,
|
|
33107
|
+
() => runWithAutoInstrumentationSuppressed(() => {
|
|
33108
|
+
let result;
|
|
33109
|
+
try {
|
|
33110
|
+
result = invokeTarget();
|
|
33111
|
+
} catch (error) {
|
|
33112
|
+
finishPiPromptRun(state, error);
|
|
33113
|
+
throw error;
|
|
33114
|
+
}
|
|
33115
|
+
return Promise.resolve(result).then(
|
|
33116
|
+
(value) => {
|
|
33117
|
+
finishPiPromptCall(state);
|
|
33118
|
+
return value;
|
|
33119
|
+
},
|
|
33120
|
+
(error) => {
|
|
33121
|
+
finishPiPromptRun(state, error);
|
|
33122
|
+
throw error;
|
|
33123
|
+
}
|
|
33124
|
+
);
|
|
33125
|
+
})
|
|
33126
|
+
);
|
|
31212
33127
|
}
|
|
31213
|
-
|
|
31214
|
-
|
|
31215
|
-
}
|
|
31216
|
-
};
|
|
31217
|
-
channel2.subscribe(handlers);
|
|
31218
|
-
this.unsubscribers.push(() => {
|
|
31219
|
-
unbindAutoInstrumentationSuppression?.();
|
|
31220
|
-
channel2.unsubscribe(handlers);
|
|
31221
|
-
});
|
|
33128
|
+
)
|
|
33129
|
+
);
|
|
31222
33130
|
}
|
|
31223
33131
|
};
|
|
33132
|
+
function finishPiPromptCall(state) {
|
|
33133
|
+
state.promptCallEnded = true;
|
|
33134
|
+
if (state.deferCompletionUntilTurnEnd && !state.turnEnded) {
|
|
33135
|
+
return;
|
|
33136
|
+
}
|
|
33137
|
+
finishPiPromptRun(state);
|
|
33138
|
+
}
|
|
31224
33139
|
function startPiPromptRun(event, onFinalize) {
|
|
31225
33140
|
const session = extractSession(event);
|
|
31226
33141
|
const agent = session?.agent;
|
|
31227
33142
|
if (!session || !isPiAgent(agent)) {
|
|
31228
33143
|
return void 0;
|
|
31229
33144
|
}
|
|
33145
|
+
installPiAgentInstrumentation(agent);
|
|
31230
33146
|
const metadata = {
|
|
31231
33147
|
...extractSessionMetadata(session),
|
|
31232
33148
|
...extractPromptOptionsMetadata(event.arguments[1]),
|
|
@@ -31248,9 +33164,7 @@ function startPiPromptRun(event, onFinalize) {
|
|
|
31248
33164
|
INSTRUMENTATION_NAMES.PI_CODING_AGENT
|
|
31249
33165
|
)
|
|
31250
33166
|
);
|
|
31251
|
-
const streamPatchState = installPiStreamPatch(agent);
|
|
31252
33167
|
const options = event.arguments[1];
|
|
31253
|
-
const promptText = event.arguments[0];
|
|
31254
33168
|
const state = {
|
|
31255
33169
|
activeLlmSpans: /* @__PURE__ */ new Set(),
|
|
31256
33170
|
activeToolSpans: /* @__PURE__ */ new Map(),
|
|
@@ -31262,29 +33176,10 @@ function startPiPromptRun(event, onFinalize) {
|
|
|
31262
33176
|
metrics: {},
|
|
31263
33177
|
onFinalize,
|
|
31264
33178
|
promptCallEnded: false,
|
|
31265
|
-
...typeof promptText === "string" ? { promptText } : {},
|
|
31266
|
-
queued: false,
|
|
31267
33179
|
span,
|
|
31268
|
-
sawStreamFn: false,
|
|
31269
33180
|
startTime: getCurrentUnixTimestamp(),
|
|
31270
|
-
streamPatchState,
|
|
31271
33181
|
turnEnded: false
|
|
31272
33182
|
};
|
|
31273
|
-
state.restorePromptContext = enterPiPromptContext(state);
|
|
31274
|
-
streamPatchState.activePromptStates.add(state);
|
|
31275
|
-
try {
|
|
31276
|
-
state.unsubscribeAgent = agent.subscribe(async (agentEvent) => {
|
|
31277
|
-
try {
|
|
31278
|
-
await runWithAutoInstrumentationSuppressed(
|
|
31279
|
-
() => handlePiAgentEvent(state, agentEvent)
|
|
31280
|
-
);
|
|
31281
|
-
} catch (error) {
|
|
31282
|
-
logInstrumentationError4("Pi Coding Agent event", error);
|
|
31283
|
-
}
|
|
31284
|
-
});
|
|
31285
|
-
} catch (error) {
|
|
31286
|
-
logInstrumentationError4("Pi Coding Agent event subscription", error);
|
|
31287
|
-
}
|
|
31288
33183
|
return state;
|
|
31289
33184
|
}
|
|
31290
33185
|
function extractSession(event) {
|
|
@@ -31298,111 +33193,55 @@ function promptContextStore() {
|
|
|
31298
33193
|
piPromptContextStore ??= isomorph_default.newAsyncLocalStorage();
|
|
31299
33194
|
return piPromptContextStore;
|
|
31300
33195
|
}
|
|
31301
|
-
function currentPromptContextFrames() {
|
|
31302
|
-
return promptContextStore().getStore()?.frames ?? [];
|
|
31303
|
-
}
|
|
31304
33196
|
function currentPiPromptState() {
|
|
31305
|
-
|
|
31306
|
-
|
|
31307
|
-
|
|
31308
|
-
|
|
31309
|
-
|
|
31310
|
-
|
|
31311
|
-
|
|
31312
|
-
|
|
31313
|
-
|
|
31314
|
-
|
|
31315
|
-
|
|
31316
|
-
|
|
31317
|
-
const frames = currentPromptContextFrames().filter(
|
|
31318
|
-
(candidate) => candidate.id !== frame.id
|
|
31319
|
-
);
|
|
31320
|
-
promptContextStore().enterWith(frames.length > 0 ? { frames } : void 0);
|
|
31321
|
-
};
|
|
31322
|
-
}
|
|
31323
|
-
function installPiStreamPatch(agent) {
|
|
31324
|
-
const existing = piStreamPatchStates.get(agent);
|
|
31325
|
-
if (existing) {
|
|
31326
|
-
if (agent.streamFn !== existing.wrappedStreamFn) {
|
|
31327
|
-
debugLogger.debug(
|
|
31328
|
-
"Pi Coding Agent streamFn changed while Braintrust instrumentation was active; preserving existing patch state."
|
|
31329
|
-
);
|
|
31330
|
-
}
|
|
31331
|
-
return existing;
|
|
31332
|
-
}
|
|
31333
|
-
const patchState = {
|
|
31334
|
-
activePromptStates: /* @__PURE__ */ new Set(),
|
|
31335
|
-
agent,
|
|
31336
|
-
originalStreamFn: agent.streamFn,
|
|
31337
|
-
queuedPromptStates: [],
|
|
31338
|
-
wrappedStreamFn: agent.streamFn
|
|
31339
|
-
};
|
|
31340
|
-
patchState.wrappedStreamFn = makeSharedInstrumentedStreamFn(patchState);
|
|
31341
|
-
agent.streamFn = patchState.wrappedStreamFn;
|
|
31342
|
-
piStreamPatchStates.set(agent, patchState);
|
|
31343
|
-
return patchState;
|
|
31344
|
-
}
|
|
31345
|
-
function resolveStreamPromptState(patchState, context) {
|
|
31346
|
-
let lastUserText;
|
|
31347
|
-
if (Array.isArray(context.messages)) {
|
|
31348
|
-
for (let i = context.messages.length - 1; i >= 0; i--) {
|
|
31349
|
-
const message = context.messages[i];
|
|
31350
|
-
if (isPiUserMessage(message)) {
|
|
31351
|
-
if (typeof message.content === "string") {
|
|
31352
|
-
lastUserText = message.content;
|
|
31353
|
-
} else {
|
|
31354
|
-
lastUserText = message.content.flatMap((part) => part.type === "text" ? [part.text] : []).join("");
|
|
31355
|
-
}
|
|
31356
|
-
break;
|
|
31357
|
-
}
|
|
31358
|
-
}
|
|
31359
|
-
}
|
|
31360
|
-
if (lastUserText !== void 0) {
|
|
31361
|
-
const queuedMatch = patchState.queuedPromptStates.find(
|
|
31362
|
-
(state) => state.promptText === lastUserText
|
|
31363
|
-
);
|
|
31364
|
-
if (queuedMatch) {
|
|
31365
|
-
return queuedMatch;
|
|
31366
|
-
}
|
|
31367
|
-
const matches = [...patchState.activePromptStates].filter(
|
|
31368
|
-
(state) => state.promptText === lastUserText
|
|
33197
|
+
return promptContextStore().getStore();
|
|
33198
|
+
}
|
|
33199
|
+
function installPiAgentInstrumentation(agent) {
|
|
33200
|
+
const existing = piAgentPatchStates.get(agent);
|
|
33201
|
+
if (!existing || agent.streamFn !== existing.wrappedStreamFn) {
|
|
33202
|
+
const patchState = {
|
|
33203
|
+
originalStreamFn: agent.streamFn,
|
|
33204
|
+
wrappedStreamFn: agent.streamFn
|
|
33205
|
+
};
|
|
33206
|
+
patchState.wrappedStreamFn = makeInstrumentedStreamFn(
|
|
33207
|
+
agent,
|
|
33208
|
+
patchState.originalStreamFn
|
|
31369
33209
|
);
|
|
31370
|
-
|
|
31371
|
-
|
|
31372
|
-
}
|
|
33210
|
+
agent.streamFn = patchState.wrappedStreamFn;
|
|
33211
|
+
piAgentPatchStates.set(agent, patchState);
|
|
31373
33212
|
}
|
|
31374
|
-
|
|
31375
|
-
|
|
31376
|
-
return contextState;
|
|
33213
|
+
if (piAgentEventSubscriptions.has(agent)) {
|
|
33214
|
+
return;
|
|
31377
33215
|
}
|
|
31378
|
-
|
|
31379
|
-
|
|
33216
|
+
try {
|
|
33217
|
+
agent.subscribe(async (event) => {
|
|
33218
|
+
const state = currentPiPromptState();
|
|
33219
|
+
if (!state || state.agent !== agent || state.finalized) {
|
|
33220
|
+
return;
|
|
33221
|
+
}
|
|
33222
|
+
try {
|
|
33223
|
+
await runWithAutoInstrumentationSuppressed(
|
|
33224
|
+
() => handlePiAgentEvent(state, event)
|
|
33225
|
+
);
|
|
33226
|
+
} catch (error) {
|
|
33227
|
+
logInstrumentationError4("Pi Coding Agent event", error);
|
|
33228
|
+
}
|
|
33229
|
+
});
|
|
33230
|
+
piAgentEventSubscriptions.add(agent);
|
|
33231
|
+
} catch (error) {
|
|
33232
|
+
logInstrumentationError4("Pi Coding Agent event subscription", error);
|
|
31380
33233
|
}
|
|
31381
|
-
return void 0;
|
|
31382
33234
|
}
|
|
31383
|
-
function
|
|
33235
|
+
function makeInstrumentedStreamFn(agent, originalStreamFn) {
|
|
31384
33236
|
return async function instrumentedPiStreamFn(model, context, options) {
|
|
31385
|
-
const
|
|
31386
|
-
|
|
31387
|
-
|
|
31388
|
-
|
|
31389
|
-
context,
|
|
31390
|
-
options
|
|
31391
|
-
]);
|
|
31392
|
-
return patchState.activePromptStates.size > 0 ? runWithAutoInstrumentationSuppressed(invokeOriginal) : invokeOriginal();
|
|
33237
|
+
const invokeOriginal = () => Reflect.apply(originalStreamFn, this, [model, context, options]);
|
|
33238
|
+
const state = currentPiPromptState();
|
|
33239
|
+
if (!state || state.agent !== agent || state.finalized) {
|
|
33240
|
+
return invokeOriginal();
|
|
31393
33241
|
}
|
|
31394
|
-
state.sawStreamFn = true;
|
|
31395
|
-
removeQueuedPromptState(state);
|
|
31396
|
-
state.streamPatchState.eventPromptState = state;
|
|
31397
33242
|
const llmState = await startPiLlmSpan(state, model, context, options);
|
|
31398
33243
|
try {
|
|
31399
|
-
const stream = await runWithAutoInstrumentationSuppressed(
|
|
31400
|
-
() => Reflect.apply(patchState.originalStreamFn, this, [
|
|
31401
|
-
model,
|
|
31402
|
-
context,
|
|
31403
|
-
options
|
|
31404
|
-
])
|
|
31405
|
-
);
|
|
33244
|
+
const stream = await runWithAutoInstrumentationSuppressed(invokeOriginal);
|
|
31406
33245
|
return patchAssistantMessageStream(stream, state, llmState);
|
|
31407
33246
|
} catch (error) {
|
|
31408
33247
|
finishPiLlmSpan(state, llmState, void 0, error);
|
|
@@ -31549,13 +33388,6 @@ async function handlePiAgentEvent(state, event) {
|
|
|
31549
33388
|
if (state.finalized) {
|
|
31550
33389
|
return;
|
|
31551
33390
|
}
|
|
31552
|
-
const eventPromptState = state.streamPatchState.eventPromptState;
|
|
31553
|
-
if (eventPromptState && eventPromptState !== state) {
|
|
31554
|
-
return;
|
|
31555
|
-
}
|
|
31556
|
-
if (!eventPromptState && (state.queued || state.streamPatchState.activePromptStates.size > 1 && currentPiPromptState() !== state)) {
|
|
31557
|
-
return;
|
|
31558
|
-
}
|
|
31559
33391
|
switch (event.type) {
|
|
31560
33392
|
case "message_end":
|
|
31561
33393
|
if (isPiAssistantMessage(event.message)) {
|
|
@@ -31570,11 +33402,8 @@ async function handlePiAgentEvent(state, event) {
|
|
|
31570
33402
|
addMetrics(state.metrics, extractUsageMetrics2(event.message.usage));
|
|
31571
33403
|
}
|
|
31572
33404
|
}
|
|
31573
|
-
if (state.streamPatchState.eventPromptState === state) {
|
|
31574
|
-
state.streamPatchState.eventPromptState = void 0;
|
|
31575
|
-
}
|
|
31576
33405
|
if (state.promptCallEnded && state.deferCompletionUntilTurnEnd) {
|
|
31577
|
-
|
|
33406
|
+
finishPiPromptRun(state);
|
|
31578
33407
|
}
|
|
31579
33408
|
return;
|
|
31580
33409
|
case "tool_execution_start":
|
|
@@ -31647,19 +33476,13 @@ function finishPiToolSpan(state, event) {
|
|
|
31647
33476
|
}
|
|
31648
33477
|
}
|
|
31649
33478
|
}
|
|
31650
|
-
|
|
33479
|
+
function finishPiPromptRun(state, error) {
|
|
31651
33480
|
if (state.finalized) {
|
|
31652
33481
|
return;
|
|
31653
33482
|
}
|
|
31654
33483
|
state.finalized = true;
|
|
31655
33484
|
state.onFinalize?.(state);
|
|
31656
|
-
|
|
31657
|
-
try {
|
|
31658
|
-
state.unsubscribeAgent?.();
|
|
31659
|
-
} catch (unsubscribeError) {
|
|
31660
|
-
logInstrumentationError4("Pi Coding Agent unsubscribe", unsubscribeError);
|
|
31661
|
-
}
|
|
31662
|
-
await finishOpenLlmSpans(state, error);
|
|
33485
|
+
finishOpenLlmSpans(state, error);
|
|
31663
33486
|
finishOpenToolSpans(state, error);
|
|
31664
33487
|
const metadata = {
|
|
31665
33488
|
...state.metadata,
|
|
@@ -31676,34 +33499,14 @@ async function finalizePiPromptRun(state, error) {
|
|
|
31676
33499
|
output: state.output
|
|
31677
33500
|
});
|
|
31678
33501
|
} finally {
|
|
31679
|
-
|
|
31680
|
-
|
|
31681
|
-
}
|
|
31682
|
-
|
|
31683
|
-
|
|
31684
|
-
patchState.activePromptStates.delete(state);
|
|
31685
|
-
removeQueuedPromptState(state);
|
|
31686
|
-
if (patchState.eventPromptState === state) {
|
|
31687
|
-
patchState.eventPromptState = void 0;
|
|
31688
|
-
}
|
|
31689
|
-
state.restorePromptContext?.();
|
|
31690
|
-
if (patchState.activePromptStates.size > 0) {
|
|
31691
|
-
return;
|
|
31692
|
-
}
|
|
31693
|
-
if (patchState.agent.streamFn === patchState.wrappedStreamFn) {
|
|
31694
|
-
patchState.agent.streamFn = patchState.originalStreamFn;
|
|
31695
|
-
}
|
|
31696
|
-
piStreamPatchStates.delete(patchState.agent);
|
|
31697
|
-
}
|
|
31698
|
-
function removeQueuedPromptState(state) {
|
|
31699
|
-
state.queued = false;
|
|
31700
|
-
const queuedPromptStates = state.streamPatchState.queuedPromptStates;
|
|
31701
|
-
const index = queuedPromptStates.indexOf(state);
|
|
31702
|
-
if (index >= 0) {
|
|
31703
|
-
queuedPromptStates.splice(index, 1);
|
|
33502
|
+
try {
|
|
33503
|
+
state.span.end();
|
|
33504
|
+
} catch (endError) {
|
|
33505
|
+
logInstrumentationError4("Pi Coding Agent prompt end", endError);
|
|
33506
|
+
}
|
|
31704
33507
|
}
|
|
31705
33508
|
}
|
|
31706
|
-
|
|
33509
|
+
function finishOpenLlmSpans(state, error) {
|
|
31707
33510
|
for (const llmState of [...state.activeLlmSpans]) {
|
|
31708
33511
|
finishPiLlmSpan(state, llmState, void 0, error);
|
|
31709
33512
|
}
|
|
@@ -31784,7 +33587,7 @@ function normalizeAssistantMessage(message) {
|
|
|
31784
33587
|
(part) => part.type === "thinking" && !part.redacted ? [part.thinking] : []
|
|
31785
33588
|
).join("");
|
|
31786
33589
|
const toolCalls = message.content.flatMap(
|
|
31787
|
-
(part) => part.type === "toolCall" ? [
|
|
33590
|
+
(part) => part.type === "toolCall" ? [normalizeToolCall2(part)] : []
|
|
31788
33591
|
);
|
|
31789
33592
|
return {
|
|
31790
33593
|
role: "assistant",
|
|
@@ -31819,13 +33622,13 @@ function normalizeUserContent(content) {
|
|
|
31819
33622
|
return part;
|
|
31820
33623
|
});
|
|
31821
33624
|
}
|
|
31822
|
-
function
|
|
33625
|
+
function normalizeToolCall2(toolCall) {
|
|
31823
33626
|
return {
|
|
31824
33627
|
id: toolCall.id,
|
|
31825
33628
|
type: "function",
|
|
31826
33629
|
function: {
|
|
31827
33630
|
name: toolCall.name,
|
|
31828
|
-
arguments:
|
|
33631
|
+
arguments: stringifyArguments2(toolCall.arguments)
|
|
31829
33632
|
}
|
|
31830
33633
|
};
|
|
31831
33634
|
}
|
|
@@ -32008,7 +33811,7 @@ function cleanMetrics5(metrics) {
|
|
|
32008
33811
|
}
|
|
32009
33812
|
return cleaned;
|
|
32010
33813
|
}
|
|
32011
|
-
function
|
|
33814
|
+
function stringifyArguments2(value) {
|
|
32012
33815
|
if (typeof value === "string") {
|
|
32013
33816
|
return value;
|
|
32014
33817
|
}
|
|
@@ -32204,8 +34007,7 @@ function startAgentStream(event, activeChildParents) {
|
|
|
32204
34007
|
...extractAgentMetadata2(agent),
|
|
32205
34008
|
...extractModelMetadata3(model),
|
|
32206
34009
|
"strands.operation": "Agent.stream",
|
|
32207
|
-
provider: extractProvider(model)
|
|
32208
|
-
...event.moduleVersion ? { "strands_agent_sdk.version": event.moduleVersion } : {}
|
|
34010
|
+
provider: extractProvider(model)
|
|
32209
34011
|
};
|
|
32210
34012
|
const parentSpan = agent ? getOnlyChildParent(activeChildParents, agent) : void 0;
|
|
32211
34013
|
const attachmentCache = createStrandsAttachmentCache();
|
|
@@ -32255,8 +34057,7 @@ function startMultiAgentStream(event, operation, activeChildParents) {
|
|
|
32255
34057
|
const metadata = {
|
|
32256
34058
|
"strands.operation": operation,
|
|
32257
34059
|
provider: "strands",
|
|
32258
|
-
...orchestrator?.id ? { "strands.orchestrator.id": orchestrator.id } : {}
|
|
32259
|
-
...event.moduleVersion ? { "strands_agent_sdk.version": event.moduleVersion } : {}
|
|
34060
|
+
...orchestrator?.id ? { "strands.orchestrator.id": orchestrator.id } : {}
|
|
32260
34061
|
};
|
|
32261
34062
|
const parentSpan = orchestrator ? getOnlyChildParent(activeChildParents, orchestrator) : void 0;
|
|
32262
34063
|
const input = processStrandsInputAttachments(event.arguments[0]);
|
|
@@ -33042,6 +34843,320 @@ function logInstrumentationError5(context, error) {
|
|
|
33042
34843
|
debugLogger.debug(`${context}:`, error);
|
|
33043
34844
|
}
|
|
33044
34845
|
|
|
34846
|
+
// src/instrumentation/plugins/voyageai-channels.ts
|
|
34847
|
+
var voyageAIChannels = defineChannels(
|
|
34848
|
+
"voyageai",
|
|
34849
|
+
{
|
|
34850
|
+
embed: channel({
|
|
34851
|
+
channelName: "embed",
|
|
34852
|
+
kind: "async"
|
|
34853
|
+
}),
|
|
34854
|
+
multimodalEmbed: channel({
|
|
34855
|
+
channelName: "multimodalEmbed",
|
|
34856
|
+
kind: "async"
|
|
34857
|
+
}),
|
|
34858
|
+
rerank: channel({
|
|
34859
|
+
channelName: "rerank",
|
|
34860
|
+
kind: "async"
|
|
34861
|
+
}),
|
|
34862
|
+
contextualizedEmbed: channel({
|
|
34863
|
+
channelName: "contextualizedEmbed",
|
|
34864
|
+
kind: "async"
|
|
34865
|
+
})
|
|
34866
|
+
},
|
|
34867
|
+
{ instrumentationName: INSTRUMENTATION_NAMES.VOYAGEAI }
|
|
34868
|
+
);
|
|
34869
|
+
|
|
34870
|
+
// src/instrumentation/plugins/voyageai-plugin.ts
|
|
34871
|
+
var RERANK_METADATA_ALLOWLIST = /* @__PURE__ */ new Set([
|
|
34872
|
+
"model",
|
|
34873
|
+
"returnDocuments",
|
|
34874
|
+
"topK",
|
|
34875
|
+
"truncation"
|
|
34876
|
+
]);
|
|
34877
|
+
var VoyageAIPlugin = class extends BasePlugin {
|
|
34878
|
+
onEnable() {
|
|
34879
|
+
this.unsubscribers.push(
|
|
34880
|
+
interceptVoyageAICall(
|
|
34881
|
+
voyageAIChannels.embed,
|
|
34882
|
+
"voyageai.embed",
|
|
34883
|
+
extractTextEmbeddingInput,
|
|
34884
|
+
summarizeEmbeddingOutput,
|
|
34885
|
+
extractEmbeddingUsageMetrics
|
|
34886
|
+
),
|
|
34887
|
+
interceptVoyageAICall(
|
|
34888
|
+
voyageAIChannels.multimodalEmbed,
|
|
34889
|
+
"voyageai.multimodalEmbed",
|
|
34890
|
+
extractMultimodalEmbeddingInput,
|
|
34891
|
+
summarizeEmbeddingOutput,
|
|
34892
|
+
extractEmbeddingUsageMetrics
|
|
34893
|
+
),
|
|
34894
|
+
interceptVoyageAICall(
|
|
34895
|
+
voyageAIChannels.rerank,
|
|
34896
|
+
"voyageai.rerank",
|
|
34897
|
+
extractRerankInput,
|
|
34898
|
+
summarizeRerankOutput
|
|
34899
|
+
),
|
|
34900
|
+
interceptVoyageAICall(
|
|
34901
|
+
voyageAIChannels.contextualizedEmbed,
|
|
34902
|
+
"voyageai.contextualizedEmbed",
|
|
34903
|
+
extractContextualizedEmbeddingInput,
|
|
34904
|
+
summarizeContextualizedEmbeddingOutput,
|
|
34905
|
+
extractEmbeddingUsageMetrics
|
|
34906
|
+
)
|
|
34907
|
+
);
|
|
34908
|
+
}
|
|
34909
|
+
onDisable() {
|
|
34910
|
+
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
34911
|
+
}
|
|
34912
|
+
};
|
|
34913
|
+
function interceptVoyageAICall(channel2, name, extractInput2, extractOutput2, extractMetrics2 = extractUsageMetrics3) {
|
|
34914
|
+
return channel2.intercept((target, thisArg, args) => {
|
|
34915
|
+
const invokeTarget = () => Reflect.apply(target, thisArg, args);
|
|
34916
|
+
if (isAutoInstrumentationSuppressed()) {
|
|
34917
|
+
return invokeTarget();
|
|
34918
|
+
}
|
|
34919
|
+
let span;
|
|
34920
|
+
try {
|
|
34921
|
+
const { input, metadata } = extractInput2(args);
|
|
34922
|
+
span = startSpan(
|
|
34923
|
+
withSpanInstrumentationName(
|
|
34924
|
+
{
|
|
34925
|
+
event: { input, metadata },
|
|
34926
|
+
name,
|
|
34927
|
+
spanAttributes: { type: "llm" /* LLM */ }
|
|
34928
|
+
},
|
|
34929
|
+
INSTRUMENTATION_NAMES.VOYAGEAI
|
|
34930
|
+
)
|
|
34931
|
+
);
|
|
34932
|
+
} catch (error) {
|
|
34933
|
+
debugLogger.error(`Error starting span for ${name}:`, error);
|
|
34934
|
+
return invokeTarget();
|
|
34935
|
+
}
|
|
34936
|
+
let result;
|
|
34937
|
+
try {
|
|
34938
|
+
result = withCurrent(
|
|
34939
|
+
span,
|
|
34940
|
+
() => runWithAutoInstrumentationSuppressed(invokeTarget)
|
|
34941
|
+
);
|
|
34942
|
+
} catch (error) {
|
|
34943
|
+
finishVoyageAISpan(span, name, () => span.log({ error }));
|
|
34944
|
+
throw error;
|
|
34945
|
+
}
|
|
34946
|
+
void Promise.resolve(result).then(
|
|
34947
|
+
(value) => finishVoyageAISpan(span, name, () => {
|
|
34948
|
+
const metadata = extractResponseMetadata3(value);
|
|
34949
|
+
span.log({
|
|
34950
|
+
output: extractOutput2(value),
|
|
34951
|
+
...metadata ? { metadata } : {},
|
|
34952
|
+
metrics: extractMetrics2(value)
|
|
34953
|
+
});
|
|
34954
|
+
}),
|
|
34955
|
+
(error) => finishVoyageAISpan(span, name, () => span.log({ error }))
|
|
34956
|
+
);
|
|
34957
|
+
return result;
|
|
34958
|
+
});
|
|
34959
|
+
}
|
|
34960
|
+
function finishVoyageAISpan(span, name, log2) {
|
|
34961
|
+
try {
|
|
34962
|
+
log2();
|
|
34963
|
+
} catch (error) {
|
|
34964
|
+
debugLogger.error(`Error logging span for ${name}:`, error);
|
|
34965
|
+
}
|
|
34966
|
+
try {
|
|
34967
|
+
span.end();
|
|
34968
|
+
} catch (error) {
|
|
34969
|
+
debugLogger.error(`Error ending span for ${name}:`, error);
|
|
34970
|
+
}
|
|
34971
|
+
}
|
|
34972
|
+
function getRequestArg2(args) {
|
|
34973
|
+
if (Array.isArray(args)) {
|
|
34974
|
+
return isObject(args[0]) ? args[0] : void 0;
|
|
34975
|
+
}
|
|
34976
|
+
if (!isObject(args)) {
|
|
34977
|
+
return void 0;
|
|
34978
|
+
}
|
|
34979
|
+
const firstArg = Reflect.get(args, "0");
|
|
34980
|
+
return isObject(firstArg) ? firstArg : void 0;
|
|
34981
|
+
}
|
|
34982
|
+
function pickMetadata(request, allowlist) {
|
|
34983
|
+
const metadata = {};
|
|
34984
|
+
if (request) {
|
|
34985
|
+
for (const key of allowlist) {
|
|
34986
|
+
if (!Object.hasOwn(request, key)) {
|
|
34987
|
+
continue;
|
|
34988
|
+
}
|
|
34989
|
+
const value = request[key];
|
|
34990
|
+
if (value !== void 0) {
|
|
34991
|
+
metadata[key] = value;
|
|
34992
|
+
}
|
|
34993
|
+
}
|
|
34994
|
+
}
|
|
34995
|
+
return {
|
|
34996
|
+
...metadata,
|
|
34997
|
+
provider: "voyage"
|
|
34998
|
+
};
|
|
34999
|
+
}
|
|
35000
|
+
function buildEmbeddingInput(inputs, request) {
|
|
35001
|
+
const outputDimensions = request?.outputDimension;
|
|
35002
|
+
return {
|
|
35003
|
+
inputs,
|
|
35004
|
+
...typeof outputDimensions === "number" && Number.isFinite(outputDimensions) ? { output_dimensions: outputDimensions } : {}
|
|
35005
|
+
};
|
|
35006
|
+
}
|
|
35007
|
+
function embeddingMetadata(request) {
|
|
35008
|
+
return {
|
|
35009
|
+
...typeof request?.model === "string" ? { model: request.model } : {},
|
|
35010
|
+
provider: "voyage"
|
|
35011
|
+
};
|
|
35012
|
+
}
|
|
35013
|
+
function extractTextEmbeddingInput(args) {
|
|
35014
|
+
const request = getRequestArg2(args);
|
|
35015
|
+
const rawInput = request?.input;
|
|
35016
|
+
const values = Array.isArray(rawInput) ? rawInput : [rawInput];
|
|
35017
|
+
return {
|
|
35018
|
+
input: buildEmbeddingInput(
|
|
35019
|
+
values.flatMap(
|
|
35020
|
+
(value) => typeof value === "string" ? [{ content: value }] : []
|
|
35021
|
+
),
|
|
35022
|
+
request
|
|
35023
|
+
),
|
|
35024
|
+
metadata: embeddingMetadata(request)
|
|
35025
|
+
};
|
|
35026
|
+
}
|
|
35027
|
+
function extractContextualizedEmbeddingInput(args) {
|
|
35028
|
+
const request = getRequestArg2(args);
|
|
35029
|
+
const rawInputs = request?.inputs;
|
|
35030
|
+
const values = Array.isArray(rawInputs) ? rawInputs.flatMap((value) => Array.isArray(value) ? value : [value]) : [];
|
|
35031
|
+
return {
|
|
35032
|
+
input: buildEmbeddingInput(
|
|
35033
|
+
values.flatMap(
|
|
35034
|
+
(value) => typeof value === "string" ? [{ content: value }] : []
|
|
35035
|
+
),
|
|
35036
|
+
request
|
|
35037
|
+
),
|
|
35038
|
+
metadata: embeddingMetadata(request)
|
|
35039
|
+
};
|
|
35040
|
+
}
|
|
35041
|
+
function extractMultimodalEmbeddingInput(args) {
|
|
35042
|
+
const request = getRequestArg2(args);
|
|
35043
|
+
const rawInputs = request?.inputs;
|
|
35044
|
+
const inputs = Array.isArray(rawInputs) ? rawInputs.map((rawInput) => {
|
|
35045
|
+
const rawContent = isObject(rawInput) ? rawInput.content : void 0;
|
|
35046
|
+
return {
|
|
35047
|
+
content: Array.isArray(rawContent) ? rawContent.flatMap(normalizeMultimodalContentPart) : []
|
|
35048
|
+
};
|
|
35049
|
+
}) : [];
|
|
35050
|
+
const input = buildEmbeddingInput(inputs, request);
|
|
35051
|
+
const processedInput = processInputAttachments(input);
|
|
35052
|
+
return {
|
|
35053
|
+
input: hasInlineEmbeddingMedia(processedInput) ? input : processedInput,
|
|
35054
|
+
metadata: embeddingMetadata(request)
|
|
35055
|
+
};
|
|
35056
|
+
}
|
|
35057
|
+
function normalizeMultimodalContentPart(part) {
|
|
35058
|
+
if (!isObject(part) || typeof part.type !== "string") {
|
|
35059
|
+
return [];
|
|
35060
|
+
}
|
|
35061
|
+
if (part.type === "text") {
|
|
35062
|
+
return typeof part.text === "string" ? [{ type: "text", text: part.text }] : [];
|
|
35063
|
+
}
|
|
35064
|
+
const camelCaseField = {
|
|
35065
|
+
image_base64: "imageBase64",
|
|
35066
|
+
image_url: "imageUrl",
|
|
35067
|
+
video_base64: "videoBase64",
|
|
35068
|
+
video_url: "videoUrl"
|
|
35069
|
+
};
|
|
35070
|
+
const field = camelCaseField[part.type];
|
|
35071
|
+
if (!field) {
|
|
35072
|
+
return [];
|
|
35073
|
+
}
|
|
35074
|
+
const data = typeof part[field] === "string" ? part[field] : part[part.type];
|
|
35075
|
+
if (typeof data !== "string") {
|
|
35076
|
+
return [];
|
|
35077
|
+
}
|
|
35078
|
+
return part.type.startsWith("image_") ? [{ type: "image_url", image_url: { url: data } }] : [{ type: "file", file: { file_data: data } }];
|
|
35079
|
+
}
|
|
35080
|
+
function hasInlineEmbeddingMedia(input) {
|
|
35081
|
+
return input.inputs.some(
|
|
35082
|
+
({ content }) => Array.isArray(content) ? content.some((part) => {
|
|
35083
|
+
const value = part.type === "image_url" ? part.image_url.url : part.type === "file" ? part.file.file_data : void 0;
|
|
35084
|
+
return typeof value === "string" && value.startsWith("data:");
|
|
35085
|
+
}) : false
|
|
35086
|
+
);
|
|
35087
|
+
}
|
|
35088
|
+
function extractRerankInput(args) {
|
|
35089
|
+
const request = getRequestArg2(args);
|
|
35090
|
+
const documents = request?.documents;
|
|
35091
|
+
return {
|
|
35092
|
+
input: {
|
|
35093
|
+
documents,
|
|
35094
|
+
query: request?.query
|
|
35095
|
+
},
|
|
35096
|
+
metadata: {
|
|
35097
|
+
...pickMetadata(request, RERANK_METADATA_ALLOWLIST),
|
|
35098
|
+
...Array.isArray(documents) ? { document_count: documents.length } : {}
|
|
35099
|
+
}
|
|
35100
|
+
};
|
|
35101
|
+
}
|
|
35102
|
+
function extractResponseMetadata3(result) {
|
|
35103
|
+
if (!isObject(result)) {
|
|
35104
|
+
return void 0;
|
|
35105
|
+
}
|
|
35106
|
+
const rawResponse = isObject(result.rawResponse) ? result.rawResponse : void 0;
|
|
35107
|
+
const model = typeof result.model === "string" ? result.model : typeof rawResponse?.model === "string" ? rawResponse.model : void 0;
|
|
35108
|
+
return model ? { model } : void 0;
|
|
35109
|
+
}
|
|
35110
|
+
function summarizeEmbeddingOutput(result) {
|
|
35111
|
+
return {
|
|
35112
|
+
count: isObject(result) && Array.isArray(result.data) ? result.data.length : 0
|
|
35113
|
+
};
|
|
35114
|
+
}
|
|
35115
|
+
function summarizeRerankOutput(result) {
|
|
35116
|
+
if (!isObject(result) || !Array.isArray(result.data)) {
|
|
35117
|
+
return void 0;
|
|
35118
|
+
}
|
|
35119
|
+
return result.data.slice(0, 100).map((item) => ({
|
|
35120
|
+
index: isObject(item) ? item.index : void 0,
|
|
35121
|
+
relevance_score: isObject(item) ? (typeof item.relevanceScore === "number" ? item.relevanceScore : item.relevance_score) ?? null : null
|
|
35122
|
+
}));
|
|
35123
|
+
}
|
|
35124
|
+
function summarizeContextualizedEmbeddingOutput(result) {
|
|
35125
|
+
if (!isObject(result)) {
|
|
35126
|
+
return { count: 0 };
|
|
35127
|
+
}
|
|
35128
|
+
if (Array.isArray(result.results)) {
|
|
35129
|
+
return {
|
|
35130
|
+
count: result.results.reduce(
|
|
35131
|
+
(count, item) => count + (isObject(item) && Array.isArray(item.embeddings) ? item.embeddings.length : 0),
|
|
35132
|
+
0
|
|
35133
|
+
)
|
|
35134
|
+
};
|
|
35135
|
+
}
|
|
35136
|
+
if (!Array.isArray(result.data)) {
|
|
35137
|
+
return { count: 0 };
|
|
35138
|
+
}
|
|
35139
|
+
return {
|
|
35140
|
+
count: result.data.reduce(
|
|
35141
|
+
(count, item) => count + (isObject(item) && Array.isArray(item.data) ? item.data.length : 0),
|
|
35142
|
+
0
|
|
35143
|
+
)
|
|
35144
|
+
};
|
|
35145
|
+
}
|
|
35146
|
+
function extractEmbeddingUsageMetrics(result) {
|
|
35147
|
+
const metrics = extractUsageMetrics3(result);
|
|
35148
|
+
return typeof metrics.tokens === "number" ? { prompt_tokens: metrics.tokens, tokens: metrics.tokens } : {};
|
|
35149
|
+
}
|
|
35150
|
+
function extractUsageMetrics3(result) {
|
|
35151
|
+
if (!isObject(result)) {
|
|
35152
|
+
return {};
|
|
35153
|
+
}
|
|
35154
|
+
const rawResponse = isObject(result.rawResponse) ? result.rawResponse : void 0;
|
|
35155
|
+
const usage = isObject(result.usage) ? result.usage : isObject(rawResponse?.usage) ? rawResponse.usage : void 0;
|
|
35156
|
+
const tokens = typeof result.totalTokens === "number" ? result.totalTokens : usage?.totalTokens ?? usage?.total_tokens;
|
|
35157
|
+
return typeof tokens === "number" && Number.isFinite(tokens) && tokens >= 0 ? { tokens } : {};
|
|
35158
|
+
}
|
|
35159
|
+
|
|
33045
35160
|
// src/instrumentation/plugins/cloudflare-ai-chat-channels.ts
|
|
33046
35161
|
var cloudflareAIChatChannels = defineChannels(
|
|
33047
35162
|
"@cloudflare/ai-chat",
|
|
@@ -33576,6 +35691,7 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
33576
35691
|
anthropicPlugin = null;
|
|
33577
35692
|
aiSDKPlugin = null;
|
|
33578
35693
|
claudeAgentSDKPlugin = null;
|
|
35694
|
+
cloudflareThinkPlugin = null;
|
|
33579
35695
|
cursorSDKPlugin = null;
|
|
33580
35696
|
openAIAgentsPlugin = null;
|
|
33581
35697
|
googleGenAIPlugin = null;
|
|
@@ -33584,6 +35700,7 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
33584
35700
|
openRouterPlugin = null;
|
|
33585
35701
|
openRouterAgentPlugin = null;
|
|
33586
35702
|
mistralPlugin = null;
|
|
35703
|
+
ollamaPlugin = null;
|
|
33587
35704
|
googleADKPlugin = null;
|
|
33588
35705
|
coherePlugin = null;
|
|
33589
35706
|
groqPlugin = null;
|
|
@@ -33595,6 +35712,7 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
33595
35712
|
langSmithPlugin = null;
|
|
33596
35713
|
piCodingAgentPlugin = null;
|
|
33597
35714
|
strandsAgentSDKPlugin = null;
|
|
35715
|
+
voyageAIPlugin = null;
|
|
33598
35716
|
cloudflareAIChatPlugin = null;
|
|
33599
35717
|
cloudflareAgentsPlugin = null;
|
|
33600
35718
|
constructor(config = {}) {
|
|
@@ -33623,6 +35741,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
33623
35741
|
this.claudeAgentSDKPlugin = new ClaudeAgentSDKPlugin();
|
|
33624
35742
|
this.claudeAgentSDKPlugin.enable();
|
|
33625
35743
|
}
|
|
35744
|
+
if (integrations.cloudflareThink !== false) {
|
|
35745
|
+
this.cloudflareThinkPlugin = new CloudflareThinkPlugin();
|
|
35746
|
+
this.cloudflareThinkPlugin.enable();
|
|
35747
|
+
}
|
|
33626
35748
|
if (integrations.cursorSDK !== false && integrations.cursor !== false) {
|
|
33627
35749
|
this.cursorSDKPlugin = new CursorSDKPlugin();
|
|
33628
35750
|
this.cursorSDKPlugin.enable();
|
|
@@ -33653,6 +35775,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
33653
35775
|
this.mistralPlugin = new MistralPlugin();
|
|
33654
35776
|
this.mistralPlugin.enable();
|
|
33655
35777
|
}
|
|
35778
|
+
if (integrations.ollama !== false) {
|
|
35779
|
+
this.ollamaPlugin = new OllamaPlugin();
|
|
35780
|
+
this.ollamaPlugin.enable();
|
|
35781
|
+
}
|
|
33656
35782
|
if (integrations.googleADK !== false) {
|
|
33657
35783
|
this.googleADKPlugin = new GoogleADKPlugin();
|
|
33658
35784
|
this.googleADKPlugin.enable();
|
|
@@ -33661,6 +35787,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
33661
35787
|
this.coherePlugin = new CoherePlugin();
|
|
33662
35788
|
this.coherePlugin.enable();
|
|
33663
35789
|
}
|
|
35790
|
+
if (integrations.voyageai !== false) {
|
|
35791
|
+
this.voyageAIPlugin = new VoyageAIPlugin();
|
|
35792
|
+
this.voyageAIPlugin.enable();
|
|
35793
|
+
}
|
|
33664
35794
|
if (integrations.groq !== false) {
|
|
33665
35795
|
this.groqPlugin = new GroqPlugin();
|
|
33666
35796
|
this.groqPlugin.enable();
|
|
@@ -33729,6 +35859,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
33729
35859
|
this.claudeAgentSDKPlugin.disable();
|
|
33730
35860
|
this.claudeAgentSDKPlugin = null;
|
|
33731
35861
|
}
|
|
35862
|
+
if (this.cloudflareThinkPlugin) {
|
|
35863
|
+
this.cloudflareThinkPlugin.disable();
|
|
35864
|
+
this.cloudflareThinkPlugin = null;
|
|
35865
|
+
}
|
|
33732
35866
|
if (this.cursorSDKPlugin) {
|
|
33733
35867
|
this.cursorSDKPlugin.disable();
|
|
33734
35868
|
this.cursorSDKPlugin = null;
|
|
@@ -33761,6 +35895,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
33761
35895
|
this.mistralPlugin.disable();
|
|
33762
35896
|
this.mistralPlugin = null;
|
|
33763
35897
|
}
|
|
35898
|
+
if (this.ollamaPlugin) {
|
|
35899
|
+
this.ollamaPlugin.disable();
|
|
35900
|
+
this.ollamaPlugin = null;
|
|
35901
|
+
}
|
|
33764
35902
|
if (this.googleADKPlugin) {
|
|
33765
35903
|
this.googleADKPlugin.disable();
|
|
33766
35904
|
this.googleADKPlugin = null;
|
|
@@ -33769,6 +35907,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
33769
35907
|
this.coherePlugin.disable();
|
|
33770
35908
|
this.coherePlugin = null;
|
|
33771
35909
|
}
|
|
35910
|
+
if (this.voyageAIPlugin) {
|
|
35911
|
+
this.voyageAIPlugin.disable();
|
|
35912
|
+
this.voyageAIPlugin = null;
|
|
35913
|
+
}
|
|
33772
35914
|
if (this.groqPlugin) {
|
|
33773
35915
|
this.groqPlugin.disable();
|
|
33774
35916
|
this.groqPlugin = null;
|
|
@@ -33846,6 +35988,7 @@ var envIntegrationAliases = {
|
|
|
33846
35988
|
cloudflareaichat: "cloudflareAIChat",
|
|
33847
35989
|
"cloudflare-ai-chat": "cloudflareAIChat",
|
|
33848
35990
|
"@cloudflare/ai-chat": "cloudflareAIChat",
|
|
35991
|
+
cloudflarethink: "cloudflareThink",
|
|
33849
35992
|
cursor: "cursor",
|
|
33850
35993
|
"cursor-sdk": "cursorSDK",
|
|
33851
35994
|
cursorsdk: "cursorSDK",
|
|
@@ -33866,6 +36009,7 @@ var envIntegrationAliases = {
|
|
|
33866
36009
|
openrouteragent: "openrouterAgent",
|
|
33867
36010
|
"openrouter-agent": "openrouterAgent",
|
|
33868
36011
|
mistral: "mistral",
|
|
36012
|
+
ollama: "ollama",
|
|
33869
36013
|
googleadk: "googleADK",
|
|
33870
36014
|
"google-adk": "googleADK",
|
|
33871
36015
|
cohere: "cohere",
|
|
@@ -33886,7 +36030,10 @@ var envIntegrationAliases = {
|
|
|
33886
36030
|
"langchain-js": "langchain",
|
|
33887
36031
|
"@langchain": "langchain",
|
|
33888
36032
|
langgraph: "langgraph",
|
|
33889
|
-
langsmith: "langsmith"
|
|
36033
|
+
langsmith: "langsmith",
|
|
36034
|
+
voyage: "voyageai",
|
|
36035
|
+
"voyage-ai": "voyageai",
|
|
36036
|
+
voyageai: "voyageai"
|
|
33890
36037
|
};
|
|
33891
36038
|
function getDefaultInstrumentationIntegrations() {
|
|
33892
36039
|
return {
|
|
@@ -33901,6 +36048,7 @@ function getDefaultInstrumentationIntegrations() {
|
|
|
33901
36048
|
huggingface: true,
|
|
33902
36049
|
claudeAgentSDK: true,
|
|
33903
36050
|
cloudflareAIChat: true,
|
|
36051
|
+
cloudflareThink: true,
|
|
33904
36052
|
cursor: true,
|
|
33905
36053
|
cursorSDK: true,
|
|
33906
36054
|
flue: true,
|
|
@@ -33909,6 +36057,7 @@ function getDefaultInstrumentationIntegrations() {
|
|
|
33909
36057
|
openrouter: true,
|
|
33910
36058
|
openrouterAgent: true,
|
|
33911
36059
|
mistral: true,
|
|
36060
|
+
ollama: true,
|
|
33912
36061
|
cohere: true,
|
|
33913
36062
|
groq: true,
|
|
33914
36063
|
bedrock: true,
|
|
@@ -33919,6 +36068,7 @@ function getDefaultInstrumentationIntegrations() {
|
|
|
33919
36068
|
langchain: true,
|
|
33920
36069
|
langgraph: true,
|
|
33921
36070
|
langsmith: true,
|
|
36071
|
+
voyageai: true,
|
|
33922
36072
|
piCodingAgent: true,
|
|
33923
36073
|
strandsAgentSDK: true,
|
|
33924
36074
|
cloudflareAgents: true
|
|
@@ -34339,9 +36489,9 @@ function configureNode() {
|
|
|
34339
36489
|
return value;
|
|
34340
36490
|
}
|
|
34341
36491
|
const envPaths = [];
|
|
34342
|
-
for (let dir2 = process.cwd(), depth = 0; depth <= BRAINTRUST_ENV_SEARCH_PARENT_LIMIT; dir2 =
|
|
34343
|
-
envPaths.push(
|
|
34344
|
-
if (
|
|
36492
|
+
for (let dir2 = process.cwd(), depth = 0; depth <= BRAINTRUST_ENV_SEARCH_PARENT_LIMIT; dir2 = path2.dirname(dir2), depth++) {
|
|
36493
|
+
envPaths.push(path2.join(dir2, ".env.braintrust"));
|
|
36494
|
+
if (path2.dirname(dir2) === dir2) {
|
|
34345
36495
|
break;
|
|
34346
36496
|
}
|
|
34347
36497
|
}
|
|
@@ -34383,10 +36533,10 @@ function configureNode() {
|
|
|
34383
36533
|
isomorph_default.processOn = (event, handler) => {
|
|
34384
36534
|
process.on(event, handler);
|
|
34385
36535
|
};
|
|
34386
|
-
isomorph_default.basename =
|
|
36536
|
+
isomorph_default.basename = path2.basename;
|
|
34387
36537
|
isomorph_default.writeln = (text) => process.stdout.write(text + "\n");
|
|
34388
|
-
isomorph_default.pathJoin =
|
|
34389
|
-
isomorph_default.pathDirname =
|
|
36538
|
+
isomorph_default.pathJoin = path2.join;
|
|
36539
|
+
isomorph_default.pathDirname = path2.dirname;
|
|
34390
36540
|
isomorph_default.mkdir = fs.mkdir;
|
|
34391
36541
|
isomorph_default.writeFile = fs.writeFile;
|
|
34392
36542
|
isomorph_default.readFile = fs.readFile;
|
|
@@ -34421,8 +36571,8 @@ function configureNode() {
|
|
|
34421
36571
|
registry.enable();
|
|
34422
36572
|
}
|
|
34423
36573
|
function getNearestBraintrustEnvValue(name) {
|
|
34424
|
-
for (let dir2 = process.cwd(), depth = 0; depth <= BRAINTRUST_ENV_SEARCH_PARENT_LIMIT; dir2 =
|
|
34425
|
-
const envPath =
|
|
36574
|
+
for (let dir2 = process.cwd(), depth = 0; depth <= BRAINTRUST_ENV_SEARCH_PARENT_LIMIT; dir2 = path2.dirname(dir2), depth++) {
|
|
36575
|
+
const envPath = path2.join(dir2, ".env.braintrust");
|
|
34426
36576
|
try {
|
|
34427
36577
|
const parsed = dotenv.parse(fsSync.readFileSync(envPath, "utf8"));
|
|
34428
36578
|
const value = parsed[name];
|
|
@@ -34432,7 +36582,7 @@ function getNearestBraintrustEnvValue(name) {
|
|
|
34432
36582
|
return void 0;
|
|
34433
36583
|
}
|
|
34434
36584
|
}
|
|
34435
|
-
if (
|
|
36585
|
+
if (path2.dirname(dir2) === dir2) {
|
|
34436
36586
|
break;
|
|
34437
36587
|
}
|
|
34438
36588
|
}
|
|
@@ -35998,8 +38148,8 @@ function validateParametersWithJsonSchema(parameters, schema) {
|
|
|
35998
38148
|
const validate = ajv.compile(schema);
|
|
35999
38149
|
if (!validate(parameters)) {
|
|
36000
38150
|
const errorMessages = validate.errors?.map((err) => {
|
|
36001
|
-
const
|
|
36002
|
-
return `${
|
|
38151
|
+
const path3 = err.instancePath || "root";
|
|
38152
|
+
return `${path3}: ${err.message}`;
|
|
36003
38153
|
}).join(", ");
|
|
36004
38154
|
throw Error(`Invalid parameters: ${errorMessages}`);
|
|
36005
38155
|
}
|
|
@@ -36028,6 +38178,9 @@ function rehydrateRemoteParameters(parameters, schema) {
|
|
|
36028
38178
|
}
|
|
36029
38179
|
|
|
36030
38180
|
// src/framework.ts
|
|
38181
|
+
function BaseExperiment(options = {}) {
|
|
38182
|
+
return { _type: "BaseExperiment", ...options };
|
|
38183
|
+
}
|
|
36031
38184
|
var EvalResultWithSummary = class {
|
|
36032
38185
|
constructor(summary, results) {
|
|
36033
38186
|
this.summary = summary;
|
|
@@ -36088,6 +38241,26 @@ async function getExperimentParametersRef(parameters) {
|
|
|
36088
38241
|
version: resolvedParameters.version
|
|
36089
38242
|
};
|
|
36090
38243
|
}
|
|
38244
|
+
async function _internalInitEvaluatorExperiment(projectName, evaluator, data, options = {}) {
|
|
38245
|
+
if (options.disabled) return null;
|
|
38246
|
+
const { baseExperiment } = callEvaluatorData(data);
|
|
38247
|
+
const parameters = await getExperimentParametersRef(evaluator.parameters);
|
|
38248
|
+
return initExperiment(evaluator.state, {
|
|
38249
|
+
...evaluator.projectId ? { projectId: evaluator.projectId } : { project: projectName },
|
|
38250
|
+
experiment: options.experimentName ?? evaluator.experimentName,
|
|
38251
|
+
description: evaluator.description,
|
|
38252
|
+
metadata: evaluator.metadata,
|
|
38253
|
+
tags: evaluator.tags,
|
|
38254
|
+
isPublic: evaluator.isPublic,
|
|
38255
|
+
update: options.update ?? evaluator.update,
|
|
38256
|
+
baseExperiment: evaluator.baseExperimentName ?? baseExperiment,
|
|
38257
|
+
baseExperimentId: evaluator.baseExperimentId,
|
|
38258
|
+
gitMetadataSettings: evaluator.gitMetadataSettings,
|
|
38259
|
+
repoInfo: evaluator.repoInfo,
|
|
38260
|
+
dataset: Dataset2.isDataset(data) ? data : void 0,
|
|
38261
|
+
parameters
|
|
38262
|
+
});
|
|
38263
|
+
}
|
|
36091
38264
|
function callEvaluatorData(data) {
|
|
36092
38265
|
const dataResult = typeof data === "function" ? data() : data;
|
|
36093
38266
|
let baseExperiment = void 0;
|
|
@@ -36105,6 +38278,48 @@ function isAsyncIterable7(value) {
|
|
|
36105
38278
|
function isIterable(value) {
|
|
36106
38279
|
return typeof value === "object" && value !== null && Symbol.iterator in value && typeof value[Symbol.iterator] === "function";
|
|
36107
38280
|
}
|
|
38281
|
+
async function _internalResolveEvaluatorData(evaluator, experiment) {
|
|
38282
|
+
if (typeof evaluator.data === "string") {
|
|
38283
|
+
throw new Error("Unimplemented: string data paths");
|
|
38284
|
+
}
|
|
38285
|
+
let dataResult = typeof evaluator.data === "function" ? evaluator.data() : evaluator.data;
|
|
38286
|
+
if ("_type" in dataResult) {
|
|
38287
|
+
if (dataResult._type !== "BaseExperiment") {
|
|
38288
|
+
throw new Error("Invalid _type");
|
|
38289
|
+
}
|
|
38290
|
+
if (!experiment) {
|
|
38291
|
+
throw new Error(
|
|
38292
|
+
"Cannot use BaseExperiment() without connecting to Braintrust (you most likely set --no-send-logs)"
|
|
38293
|
+
);
|
|
38294
|
+
}
|
|
38295
|
+
let name = dataResult.name;
|
|
38296
|
+
if (isEmpty2(name)) {
|
|
38297
|
+
const baseExperiment = await experiment.fetchBaseExperiment();
|
|
38298
|
+
if (!baseExperiment) {
|
|
38299
|
+
throw new Error("BaseExperiment() failed to fetch base experiment");
|
|
38300
|
+
}
|
|
38301
|
+
name = baseExperiment.name;
|
|
38302
|
+
}
|
|
38303
|
+
dataResult = initExperiment(evaluator.state, {
|
|
38304
|
+
...evaluator.projectId ? { projectId: evaluator.projectId } : { project: evaluator.projectName },
|
|
38305
|
+
experiment: name,
|
|
38306
|
+
open: true
|
|
38307
|
+
}).asDataset();
|
|
38308
|
+
}
|
|
38309
|
+
const resolvedDataResult = dataResult instanceof Promise ? await dataResult : dataResult;
|
|
38310
|
+
if (isAsyncIterable7(resolvedDataResult)) {
|
|
38311
|
+
return resolvedDataResult;
|
|
38312
|
+
}
|
|
38313
|
+
if (Array.isArray(resolvedDataResult) || isIterable(resolvedDataResult)) {
|
|
38314
|
+
const iterable = resolvedDataResult;
|
|
38315
|
+
return (async function* () {
|
|
38316
|
+
for (const datum of iterable) yield datum;
|
|
38317
|
+
})();
|
|
38318
|
+
}
|
|
38319
|
+
throw new Error(
|
|
38320
|
+
"Evaluator data must be an array, iterable, or async iterable"
|
|
38321
|
+
);
|
|
38322
|
+
}
|
|
36108
38323
|
globalThis._evals = {
|
|
36109
38324
|
functions: [],
|
|
36110
38325
|
prompts: [],
|
|
@@ -36151,25 +38366,13 @@ async function Eval(name, evaluator, reporterOrOpts) {
|
|
|
36151
38366
|
}
|
|
36152
38367
|
const resolvedReporter = options.reporter || defaultReporter;
|
|
36153
38368
|
try {
|
|
36154
|
-
const { data
|
|
36155
|
-
|
|
38369
|
+
const { data } = callEvaluatorData(evaluator.data);
|
|
38370
|
+
const experiment = await _internalInitEvaluatorExperiment(
|
|
38371
|
+
name,
|
|
38372
|
+
evaluator,
|
|
38373
|
+
data,
|
|
38374
|
+
{ disabled: Boolean(options.parent || options.noSendLogs) }
|
|
36156
38375
|
);
|
|
36157
|
-
const parameters = await getExperimentParametersRef(evaluator.parameters);
|
|
36158
|
-
const experiment = options.parent || options.noSendLogs ? null : initExperiment(evaluator.state, {
|
|
36159
|
-
...evaluator.projectId ? { projectId: evaluator.projectId } : { project: name },
|
|
36160
|
-
experiment: evaluator.experimentName,
|
|
36161
|
-
description: evaluator.description,
|
|
36162
|
-
metadata: evaluator.metadata,
|
|
36163
|
-
tags: evaluator.tags,
|
|
36164
|
-
isPublic: evaluator.isPublic,
|
|
36165
|
-
update: evaluator.update,
|
|
36166
|
-
baseExperiment: evaluator.baseExperimentName ?? defaultBaseExperiment,
|
|
36167
|
-
baseExperimentId: evaluator.baseExperimentId,
|
|
36168
|
-
gitMetadataSettings: evaluator.gitMetadataSettings,
|
|
36169
|
-
repoInfo: evaluator.repoInfo,
|
|
36170
|
-
dataset: Dataset2.isDataset(data) ? data : void 0,
|
|
36171
|
-
parameters
|
|
36172
|
-
});
|
|
36173
38376
|
if (experiment && typeof process !== "undefined" && globalThis.BRAINTRUST_CONTEXT_MANAGER !== void 0) {
|
|
36174
38377
|
await experiment._waitForId();
|
|
36175
38378
|
}
|
|
@@ -36238,8 +38441,8 @@ function serializeJSONWithPlainString(v) {
|
|
|
36238
38441
|
}
|
|
36239
38442
|
}
|
|
36240
38443
|
function evaluateFilter(object, filter2) {
|
|
36241
|
-
const { path:
|
|
36242
|
-
const key =
|
|
38444
|
+
const { path: path3, pattern } = filter2;
|
|
38445
|
+
const key = path3.reduce(
|
|
36243
38446
|
(acc, p) => typeof acc === "object" && acc !== null ? (
|
|
36244
38447
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
36245
38448
|
acc[p]
|
|
@@ -36257,19 +38460,74 @@ function scorerName(scorer, scorer_idx) {
|
|
|
36257
38460
|
function classifierName(classifier, classifier_idx) {
|
|
36258
38461
|
return classifier.name || `classifier_${classifier_idx}`;
|
|
36259
38462
|
}
|
|
38463
|
+
async function _internalRunEvaluatorTask(task, datum, trialIndex, parameters, span, reportProgress = () => void 0) {
|
|
38464
|
+
const metadata = {
|
|
38465
|
+
..."metadata" in datum ? datum.metadata : {}
|
|
38466
|
+
};
|
|
38467
|
+
const hooks = {
|
|
38468
|
+
meta(value) {
|
|
38469
|
+
Object.assign(metadata, value);
|
|
38470
|
+
},
|
|
38471
|
+
metadata,
|
|
38472
|
+
expected: "expected" in datum ? datum.expected : void 0,
|
|
38473
|
+
span,
|
|
38474
|
+
parameters,
|
|
38475
|
+
reportProgress,
|
|
38476
|
+
trialIndex,
|
|
38477
|
+
tags: [...datum.tags ?? []]
|
|
38478
|
+
};
|
|
38479
|
+
const output = await task(datum.input, hooks);
|
|
38480
|
+
span.log({ output });
|
|
38481
|
+
return {
|
|
38482
|
+
output,
|
|
38483
|
+
metadata: hooks.metadata,
|
|
38484
|
+
tags: hooks.tags ?? []
|
|
38485
|
+
};
|
|
38486
|
+
}
|
|
36260
38487
|
function buildSpanMetadata(results) {
|
|
36261
|
-
return results.length === 1 ? results[0].metadata :
|
|
36262
|
-
(
|
|
36263
|
-
{}
|
|
38488
|
+
return results.length === 1 ? results[0].metadata : Object.fromEntries(
|
|
38489
|
+
results.map((result) => [result.name, result.metadata])
|
|
36264
38490
|
);
|
|
36265
38491
|
}
|
|
36266
38492
|
function buildSpanScores(results) {
|
|
36267
|
-
const scoresRecord =
|
|
36268
|
-
(
|
|
36269
|
-
{}
|
|
38493
|
+
const scoresRecord = Object.fromEntries(
|
|
38494
|
+
results.map((result) => [result.name, result.score])
|
|
36270
38495
|
);
|
|
36271
38496
|
return { resultMetadata: buildSpanMetadata(results), scoresRecord };
|
|
36272
38497
|
}
|
|
38498
|
+
function _internalPrepareEvaluatorScore(scoreValue, name) {
|
|
38499
|
+
if (scoreValue === null) return { results: null };
|
|
38500
|
+
if (Array.isArray(scoreValue)) {
|
|
38501
|
+
for (const score of scoreValue) {
|
|
38502
|
+
if (!(typeof score === "object" && !isEmpty2(score))) {
|
|
38503
|
+
throw new Error(
|
|
38504
|
+
`When returning an array of scores, each score must be a non-empty object. Got: ${JSON.stringify(score)}`
|
|
38505
|
+
);
|
|
38506
|
+
}
|
|
38507
|
+
}
|
|
38508
|
+
}
|
|
38509
|
+
let results;
|
|
38510
|
+
if (Array.isArray(scoreValue)) {
|
|
38511
|
+
results = scoreValue;
|
|
38512
|
+
} else if (typeof scoreValue === "object" && !isEmpty2(scoreValue)) {
|
|
38513
|
+
results = [scoreValue];
|
|
38514
|
+
} else {
|
|
38515
|
+
results = [{ name, score: scoreValue }];
|
|
38516
|
+
}
|
|
38517
|
+
const { resultMetadata, scoresRecord } = buildSpanScores(results);
|
|
38518
|
+
const fields = (score) => {
|
|
38519
|
+
const { metadata: _metadata, name: _name, ...rest } = score;
|
|
38520
|
+
return rest;
|
|
38521
|
+
};
|
|
38522
|
+
return {
|
|
38523
|
+
results,
|
|
38524
|
+
output: results.length === 1 ? fields(results[0]) : Object.fromEntries(
|
|
38525
|
+
results.map((score) => [score.name ?? name, fields(score)])
|
|
38526
|
+
),
|
|
38527
|
+
metadata: resultMetadata,
|
|
38528
|
+
scores: scoresRecord
|
|
38529
|
+
};
|
|
38530
|
+
}
|
|
36273
38531
|
async function runInScorerSpan(rootSpan, spanName, spanType, propagatedEvent, eventInput, fn) {
|
|
36274
38532
|
try {
|
|
36275
38533
|
const value = await rootSpan.traced(fn, {
|
|
@@ -36314,6 +38572,27 @@ function toClassificationItem(c) {
|
|
|
36314
38572
|
...c.metadata !== void 0 ? { metadata: c.metadata } : {}
|
|
36315
38573
|
};
|
|
36316
38574
|
}
|
|
38575
|
+
function _internalPrepareEvaluatorClassification(value, name) {
|
|
38576
|
+
if (value === null) return { results: null };
|
|
38577
|
+
const results = (Array.isArray(value) ? value : [value]).map(
|
|
38578
|
+
(result) => validateClassificationResult(result, name)
|
|
38579
|
+
);
|
|
38580
|
+
const classifications = /* @__PURE__ */ Object.create(null);
|
|
38581
|
+
for (const result of results) {
|
|
38582
|
+
(classifications[result.name] ??= []).push(toClassificationItem(result));
|
|
38583
|
+
}
|
|
38584
|
+
return {
|
|
38585
|
+
results,
|
|
38586
|
+
output: results.length === 1 ? toClassificationItem(results[0]) : Object.fromEntries(
|
|
38587
|
+
results.map((result) => [
|
|
38588
|
+
result.name,
|
|
38589
|
+
toClassificationItem(result)
|
|
38590
|
+
])
|
|
38591
|
+
),
|
|
38592
|
+
metadata: buildSpanMetadata(results),
|
|
38593
|
+
classifications
|
|
38594
|
+
};
|
|
38595
|
+
}
|
|
36317
38596
|
function logScoringFailures(kind, failures, metadata, rootSpan, state) {
|
|
36318
38597
|
if (!failures.length) return [];
|
|
36319
38598
|
const errorMap = Object.fromEntries(
|
|
@@ -36352,54 +38631,14 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
|
|
|
36352
38631
|
(evaluator.state ?? _internalGetGlobalState())?.spanCache?.start();
|
|
36353
38632
|
}
|
|
36354
38633
|
try {
|
|
36355
|
-
if (typeof evaluator.data === "string") {
|
|
36356
|
-
throw new Error("Unimplemented: string data paths");
|
|
36357
|
-
}
|
|
36358
|
-
let dataResult = typeof evaluator.data === "function" ? evaluator.data() : evaluator.data;
|
|
36359
38634
|
parameters = await validateParameters(
|
|
36360
38635
|
parameters ?? {},
|
|
36361
38636
|
evaluator.parameters
|
|
36362
38637
|
);
|
|
36363
|
-
|
|
36364
|
-
|
|
36365
|
-
|
|
36366
|
-
|
|
36367
|
-
if (!experiment) {
|
|
36368
|
-
throw new Error(
|
|
36369
|
-
"Cannot use BaseExperiment() without connecting to Braintrust (you most likely set --no-send-logs)"
|
|
36370
|
-
);
|
|
36371
|
-
}
|
|
36372
|
-
let name = dataResult.name;
|
|
36373
|
-
if (isEmpty2(name)) {
|
|
36374
|
-
const baseExperiment = await experiment.fetchBaseExperiment();
|
|
36375
|
-
if (!baseExperiment) {
|
|
36376
|
-
throw new Error("BaseExperiment() failed to fetch base experiment");
|
|
36377
|
-
}
|
|
36378
|
-
name = baseExperiment.name;
|
|
36379
|
-
}
|
|
36380
|
-
dataResult = initExperiment(evaluator.state, {
|
|
36381
|
-
...evaluator.projectId ? { projectId: evaluator.projectId } : { project: evaluator.projectName },
|
|
36382
|
-
experiment: name,
|
|
36383
|
-
open: true
|
|
36384
|
-
}).asDataset();
|
|
36385
|
-
}
|
|
36386
|
-
const resolvedDataResult = dataResult instanceof Promise ? await dataResult : dataResult;
|
|
36387
|
-
const dataIterable = (() => {
|
|
36388
|
-
if (isAsyncIterable7(resolvedDataResult)) {
|
|
36389
|
-
return resolvedDataResult;
|
|
36390
|
-
}
|
|
36391
|
-
if (Array.isArray(resolvedDataResult) || isIterable(resolvedDataResult)) {
|
|
36392
|
-
const iterable = resolvedDataResult;
|
|
36393
|
-
return (async function* () {
|
|
36394
|
-
for (const datum of iterable) {
|
|
36395
|
-
yield datum;
|
|
36396
|
-
}
|
|
36397
|
-
})();
|
|
36398
|
-
}
|
|
36399
|
-
throw new Error(
|
|
36400
|
-
"Evaluator data must be an array, iterable, or async iterable"
|
|
36401
|
-
);
|
|
36402
|
-
})();
|
|
38638
|
+
const dataIterable = await _internalResolveEvaluatorData(
|
|
38639
|
+
evaluator,
|
|
38640
|
+
experiment
|
|
38641
|
+
);
|
|
36403
38642
|
progressReporter.start(evaluator.evalName, 0);
|
|
36404
38643
|
const experimentIdPromise = experiment ? (async () => {
|
|
36405
38644
|
try {
|
|
@@ -36468,57 +38707,45 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
|
|
|
36468
38707
|
ensureSpansFlushed,
|
|
36469
38708
|
state
|
|
36470
38709
|
}) : void 0;
|
|
36471
|
-
let metadata = {
|
|
36472
|
-
..."metadata" in datum ? datum.metadata : {}
|
|
36473
|
-
};
|
|
38710
|
+
let metadata = {};
|
|
36474
38711
|
const expected = "expected" in datum ? datum.expected : void 0;
|
|
36475
38712
|
let output = void 0;
|
|
36476
38713
|
let error = void 0;
|
|
36477
|
-
let tags = [
|
|
36478
|
-
const scores =
|
|
36479
|
-
const classifications =
|
|
38714
|
+
let tags = [];
|
|
38715
|
+
const scores = /* @__PURE__ */ Object.create(null);
|
|
38716
|
+
const classifications = /* @__PURE__ */ Object.create(null);
|
|
36480
38717
|
const scorerNames = (evaluator.scores ?? []).map(scorerName);
|
|
36481
38718
|
const classifierNames = (evaluator.classifiers ?? []).map(
|
|
36482
38719
|
classifierName
|
|
36483
38720
|
);
|
|
36484
38721
|
let unhandledScores = scorerNames;
|
|
36485
38722
|
try {
|
|
36486
|
-
const
|
|
36487
|
-
|
|
36488
|
-
|
|
36489
|
-
|
|
36490
|
-
|
|
36491
|
-
|
|
36492
|
-
|
|
36493
|
-
|
|
36494
|
-
|
|
36495
|
-
|
|
36496
|
-
|
|
36497
|
-
|
|
36498
|
-
|
|
36499
|
-
|
|
36500
|
-
|
|
36501
|
-
object_type: "task"
|
|
36502
|
-
});
|
|
36503
|
-
},
|
|
36504
|
-
trialIndex,
|
|
36505
|
-
tags
|
|
36506
|
-
};
|
|
36507
|
-
const outputResult = evaluator.task(datum.input, hooksForTask);
|
|
36508
|
-
if (outputResult instanceof Promise) {
|
|
36509
|
-
output = await outputResult;
|
|
36510
|
-
} else {
|
|
36511
|
-
output = outputResult;
|
|
38723
|
+
const taskResult = await rootSpan.traced(
|
|
38724
|
+
(span) => _internalRunEvaluatorTask(
|
|
38725
|
+
evaluator.task,
|
|
38726
|
+
datum,
|
|
38727
|
+
trialIndex,
|
|
38728
|
+
parameters ?? {},
|
|
38729
|
+
span,
|
|
38730
|
+
(event) => {
|
|
38731
|
+
stream?.({
|
|
38732
|
+
...event,
|
|
38733
|
+
id: rootSpan.id,
|
|
38734
|
+
origin: baseEvent.event?.origin,
|
|
38735
|
+
name: evaluator.evalName,
|
|
38736
|
+
object_type: "task"
|
|
38737
|
+
});
|
|
36512
38738
|
}
|
|
36513
|
-
|
|
36514
|
-
span.log({ output });
|
|
36515
|
-
},
|
|
38739
|
+
),
|
|
36516
38740
|
{
|
|
36517
38741
|
name: "task",
|
|
36518
38742
|
spanAttributes: { type: "task" /* TASK */ },
|
|
36519
38743
|
event: { input: datum.input }
|
|
36520
38744
|
}
|
|
36521
38745
|
);
|
|
38746
|
+
output = taskResult.output;
|
|
38747
|
+
metadata = taskResult.metadata;
|
|
38748
|
+
tags = taskResult.tags;
|
|
36522
38749
|
if (tags.length) {
|
|
36523
38750
|
rootSpan.log({ output, metadata, expected, tags });
|
|
36524
38751
|
} else {
|
|
@@ -36528,20 +38755,18 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
|
|
|
36528
38755
|
await rootSpan.flush();
|
|
36529
38756
|
}
|
|
36530
38757
|
const scoringArgs = {
|
|
38758
|
+
id: datum.id,
|
|
36531
38759
|
input: datum.input,
|
|
36532
38760
|
expected: "expected" in datum ? datum.expected : void 0,
|
|
36533
38761
|
metadata,
|
|
36534
38762
|
output,
|
|
38763
|
+
tags,
|
|
36535
38764
|
trace
|
|
36536
38765
|
};
|
|
36537
38766
|
const { trace: _trace, ...scoringArgsForLogging } = scoringArgs;
|
|
36538
38767
|
const propagatedEvent = makeScorerPropagatedEvent(
|
|
36539
38768
|
await rootSpan.export()
|
|
36540
38769
|
);
|
|
36541
|
-
const getOtherFields = (s) => {
|
|
36542
|
-
const { metadata: _metadata, name: _name, ...rest } = s;
|
|
36543
|
-
return rest;
|
|
36544
|
-
};
|
|
36545
38770
|
const [scoreResults, classificationResults] = await Promise.all([
|
|
36546
38771
|
Promise.all(
|
|
36547
38772
|
(evaluator.scores ?? []).map(
|
|
@@ -36555,35 +38780,17 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
|
|
|
36555
38780
|
const scoreValue = await Promise.resolve(
|
|
36556
38781
|
score(scoringArgs)
|
|
36557
38782
|
);
|
|
36558
|
-
|
|
36559
|
-
|
|
36560
|
-
|
|
36561
|
-
if (!(typeof s === "object" && !isEmpty2(s))) {
|
|
36562
|
-
throw new Error(
|
|
36563
|
-
`When returning an array of scores, each score must be a non-empty object. Got: ${JSON.stringify(s)}`
|
|
36564
|
-
);
|
|
36565
|
-
}
|
|
36566
|
-
}
|
|
36567
|
-
}
|
|
36568
|
-
const results = Array.isArray(scoreValue) ? scoreValue : typeof scoreValue === "object" && !isEmpty2(scoreValue) ? [scoreValue] : [
|
|
36569
|
-
{
|
|
36570
|
-
name: scorerNames[score_idx],
|
|
36571
|
-
score: scoreValue
|
|
36572
|
-
}
|
|
36573
|
-
];
|
|
36574
|
-
const { resultMetadata, scoresRecord } = buildSpanScores(results);
|
|
36575
|
-
const resultOutput = results.length === 1 ? getOtherFields(results[0]) : results.reduce(
|
|
36576
|
-
(prev, s) => mergeDicts(prev, {
|
|
36577
|
-
[s.name]: getOtherFields(s)
|
|
36578
|
-
}),
|
|
36579
|
-
{}
|
|
38783
|
+
const prepared = _internalPrepareEvaluatorScore(
|
|
38784
|
+
scoreValue,
|
|
38785
|
+
scorerNames[score_idx]
|
|
36580
38786
|
);
|
|
38787
|
+
if (prepared.results === null) return null;
|
|
36581
38788
|
span.log({
|
|
36582
|
-
output:
|
|
36583
|
-
metadata:
|
|
36584
|
-
scores:
|
|
38789
|
+
output: prepared.output,
|
|
38790
|
+
metadata: prepared.metadata,
|
|
38791
|
+
scores: prepared.scores
|
|
36585
38792
|
});
|
|
36586
|
-
return results;
|
|
38793
|
+
return prepared.results;
|
|
36587
38794
|
}
|
|
36588
38795
|
)
|
|
36589
38796
|
)
|
|
@@ -36600,24 +38807,16 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
|
|
|
36600
38807
|
const classifierValue = await Promise.resolve(
|
|
36601
38808
|
classifier(scoringArgs)
|
|
36602
38809
|
);
|
|
36603
|
-
|
|
36604
|
-
|
|
36605
|
-
|
|
36606
|
-
result,
|
|
36607
|
-
classifierNames[idx]
|
|
36608
|
-
)
|
|
36609
|
-
);
|
|
36610
|
-
const resultOutput = rawResults.length === 1 ? toClassificationItem(rawResults[0]) : rawResults.reduce(
|
|
36611
|
-
(prev, r) => mergeDicts(prev, {
|
|
36612
|
-
[r.name]: toClassificationItem(r)
|
|
36613
|
-
}),
|
|
36614
|
-
{}
|
|
38810
|
+
const prepared = _internalPrepareEvaluatorClassification(
|
|
38811
|
+
classifierValue,
|
|
38812
|
+
classifierNames[idx]
|
|
36615
38813
|
);
|
|
38814
|
+
if (prepared.results === null) return null;
|
|
36616
38815
|
span.log({
|
|
36617
|
-
output:
|
|
36618
|
-
metadata:
|
|
38816
|
+
output: prepared.output,
|
|
38817
|
+
metadata: prepared.metadata
|
|
36619
38818
|
});
|
|
36620
|
-
return
|
|
38819
|
+
return prepared.results;
|
|
36621
38820
|
}
|
|
36622
38821
|
)
|
|
36623
38822
|
)
|
|
@@ -36846,7 +39045,7 @@ function accumulateScores(accumulator, scores) {
|
|
|
36846
39045
|
}
|
|
36847
39046
|
}
|
|
36848
39047
|
function ensureScoreAccumulator(results) {
|
|
36849
|
-
const accumulator =
|
|
39048
|
+
const accumulator = /* @__PURE__ */ Object.create(null);
|
|
36850
39049
|
for (const result of results) {
|
|
36851
39050
|
accumulateScores(accumulator, result.scores);
|
|
36852
39051
|
}
|
|
@@ -38020,6 +40219,8 @@ async function getDataset(state, data) {
|
|
|
38020
40219
|
environment: data.dataset_environment ?? void 0,
|
|
38021
40220
|
_internal_btql: data._internal_btql ?? void 0
|
|
38022
40221
|
});
|
|
40222
|
+
} else if ("experiment_name" in data) {
|
|
40223
|
+
return BaseExperiment({ name: data.experiment_name });
|
|
38023
40224
|
} else {
|
|
38024
40225
|
return data.data;
|
|
38025
40226
|
}
|