braintrust 3.20.0 → 3.21.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/NOTICE +20 -0
- package/README.md +2 -0
- package/dev/dist/index.d.mts +309 -199
- package/dev/dist/index.d.ts +309 -199
- package/dev/dist/index.js +2826 -983
- package/dev/dist/index.mjs +2286 -443
- package/dist/apply-auto-instrumentation.js +781 -199
- package/dist/apply-auto-instrumentation.mjs +588 -6
- package/dist/auto-instrumentations/bundler/esbuild.cjs +594 -2
- package/dist/auto-instrumentations/bundler/esbuild.d.mts +2 -2
- package/dist/auto-instrumentations/bundler/esbuild.d.ts +2 -2
- package/dist/auto-instrumentations/bundler/esbuild.mjs +3 -3
- package/dist/auto-instrumentations/bundler/next.cjs +594 -2
- package/dist/auto-instrumentations/bundler/next.mjs +4 -4
- package/dist/auto-instrumentations/bundler/rollup.cjs +594 -2
- package/dist/auto-instrumentations/bundler/rollup.d.mts +2 -2
- package/dist/auto-instrumentations/bundler/rollup.d.ts +2 -2
- package/dist/auto-instrumentations/bundler/rollup.mjs +3 -3
- package/dist/auto-instrumentations/bundler/vite.cjs +594 -2
- package/dist/auto-instrumentations/bundler/vite.d.mts +2 -2
- package/dist/auto-instrumentations/bundler/vite.d.ts +2 -2
- package/dist/auto-instrumentations/bundler/vite.mjs +3 -3
- package/dist/auto-instrumentations/bundler/webpack-loader.cjs +593 -9
- package/dist/auto-instrumentations/bundler/webpack-loader.d.ts +68 -1
- package/dist/auto-instrumentations/bundler/webpack.cjs +594 -2
- package/dist/auto-instrumentations/bundler/webpack.d.mts +2 -2
- package/dist/auto-instrumentations/bundler/webpack.d.ts +2 -2
- package/dist/auto-instrumentations/bundler/webpack.mjs +4 -4
- package/dist/auto-instrumentations/{chunk-W4E36GIW.mjs → chunk-BRQX23KL.mjs} +16 -0
- package/dist/auto-instrumentations/chunk-M6DLIJ2Z.mjs +784 -0
- package/dist/auto-instrumentations/{chunk-K74TZGGM.mjs → chunk-T6J4C7LX.mjs} +1 -1
- package/dist/auto-instrumentations/{chunk-S4374IP6.mjs → chunk-TKRPRPGD.mjs} +4 -6
- package/dist/auto-instrumentations/chunk-VT6DDNKM.mjs +856 -0
- package/dist/auto-instrumentations/hook.mjs +749 -45
- package/dist/auto-instrumentations/index.cjs +16 -0
- package/dist/auto-instrumentations/index.d.mts +2 -3
- package/dist/auto-instrumentations/index.d.ts +2 -3
- package/dist/auto-instrumentations/index.mjs +1 -1
- package/dist/auto-instrumentations/loader/cjs-patch.cjs +578 -4
- package/dist/auto-instrumentations/loader/cjs-patch.d.mts +1 -1
- package/dist/auto-instrumentations/loader/cjs-patch.d.ts +1 -1
- package/dist/auto-instrumentations/loader/cjs-patch.mjs +3 -7
- package/dist/auto-instrumentations/loader/esm-hook.mjs +2 -6
- package/dist/auto-instrumentations/{plugin-D7nDswtC.d.mts → plugin-D0KHwSJv.d.mts} +1 -1
- package/dist/auto-instrumentations/{plugin-D7nDswtC.d.ts → plugin-G6fgxk1b.d.ts} +1 -1
- package/dist/auto-instrumentations/types-RNPaKi9o.d.mts +70 -0
- package/dist/auto-instrumentations/types-RNPaKi9o.d.ts +70 -0
- package/dist/browser.d.mts +1357 -847
- package/dist/browser.d.ts +1357 -847
- package/dist/browser.js +2726 -469
- package/dist/browser.mjs +2726 -469
- package/dist/{chunk-LPC4W2WX.js → chunk-BFGIH2ZJ.js} +4 -0
- package/dist/{chunk-POCCIJAL.js → chunk-FY7DAKA5.js} +3141 -1269
- package/dist/{chunk-Y7W7WP6H.mjs → chunk-KMGUTPB7.mjs} +4 -0
- package/dist/{chunk-F73OMF66.mjs → chunk-O2P765XK.mjs} +2391 -519
- package/dist/cli.js +2260 -408
- package/dist/edge-light.d.mts +1 -1
- package/dist/edge-light.d.ts +1 -1
- package/dist/edge-light.js +2726 -469
- package/dist/edge-light.mjs +2726 -469
- package/dist/index.d.mts +1837 -1327
- package/dist/index.d.ts +1837 -1327
- package/dist/index.js +752 -353
- package/dist/index.mjs +445 -46
- package/dist/instrumentation/index.d.mts +107 -19
- package/dist/instrumentation/index.d.ts +107 -19
- package/dist/instrumentation/index.js +2337 -509
- package/dist/instrumentation/index.mjs +2337 -509
- package/dist/vitest-evals-reporter.js +16 -16
- package/dist/vitest-evals-reporter.mjs +2 -2
- package/dist/workerd.d.mts +1 -1
- package/dist/workerd.d.ts +1 -1
- package/dist/workerd.js +2726 -469
- package/dist/workerd.mjs +2726 -469
- package/licenses/import-in-the-middle/LICENSE +201 -0
- package/licenses/import-in-the-middle/LICENSE-3rdparty.csv +4 -0
- package/licenses/import-in-the-middle/NOTICE +34 -0
- package/licenses/orchestrion-js/LICENSE +202 -0
- package/licenses/orchestrion-js/LICENSE-3rdparty.csv +8 -0
- package/licenses/orchestrion-js/NOTICE +3 -0
- package/licenses/require-in-the-middle/LICENSE +23 -0
- package/package.json +13 -4
- package/util/dist/index.d.mts +1 -0
- package/util/dist/index.d.ts +1 -0
- package/util/dist/index.js +4 -4
- package/util/dist/index.mjs +2 -2
- package/dist/auto-instrumentations/chunk-J57YF7WS.mjs +0 -208
- package/dist/auto-instrumentations/chunk-QFMACSOL.mjs +0 -280
package/dist/browser.mjs
CHANGED
|
@@ -288,8 +288,291 @@ var UUIDGenerator = class extends IDGenerator {
|
|
|
288
288
|
return true;
|
|
289
289
|
}
|
|
290
290
|
};
|
|
291
|
+
function generateHexId(bytes) {
|
|
292
|
+
let result = "";
|
|
293
|
+
for (let i = 0; i < bytes; i++) {
|
|
294
|
+
result += Math.floor(Math.random() * 256).toString(16).padStart(2, "0");
|
|
295
|
+
}
|
|
296
|
+
return result;
|
|
297
|
+
}
|
|
298
|
+
var OTELIDGenerator = class extends IDGenerator {
|
|
299
|
+
getSpanId() {
|
|
300
|
+
return generateHexId(8);
|
|
301
|
+
}
|
|
302
|
+
getTraceId() {
|
|
303
|
+
return generateHexId(16);
|
|
304
|
+
}
|
|
305
|
+
shareRootSpanId() {
|
|
306
|
+
return false;
|
|
307
|
+
}
|
|
308
|
+
};
|
|
309
|
+
function parseEnvBool(name) {
|
|
310
|
+
const raw = isomorph_default.getEnv(name);
|
|
311
|
+
if (raw === void 0 || raw === null) {
|
|
312
|
+
return false;
|
|
313
|
+
}
|
|
314
|
+
const normalized = raw.trim().toLowerCase();
|
|
315
|
+
return normalized === "true" || normalized === "1" || normalized === "yes" || normalized === "y" || normalized === "on";
|
|
316
|
+
}
|
|
317
|
+
var _warnedLegacyUuidConflict = false;
|
|
318
|
+
function resolveUseLegacyUuidIds() {
|
|
319
|
+
const legacy = parseEnvBool("BRAINTRUST_LEGACY_IDS");
|
|
320
|
+
if (parseEnvBool("BRAINTRUST_OTEL_COMPAT")) {
|
|
321
|
+
if (legacy && !_warnedLegacyUuidConflict) {
|
|
322
|
+
_warnedLegacyUuidConflict = true;
|
|
323
|
+
debugLogger.warn(
|
|
324
|
+
"BRAINTRUST_LEGACY_IDS is ignored because BRAINTRUST_OTEL_COMPAT requires OpenTelemetry-compatible hex span IDs. Using hex IDs."
|
|
325
|
+
);
|
|
326
|
+
}
|
|
327
|
+
return false;
|
|
328
|
+
}
|
|
329
|
+
return legacy;
|
|
330
|
+
}
|
|
291
331
|
function getIdGenerator() {
|
|
292
|
-
|
|
332
|
+
if (globalThis.BRAINTRUST_ID_GENERATOR !== void 0) {
|
|
333
|
+
return new globalThis.BRAINTRUST_ID_GENERATOR();
|
|
334
|
+
}
|
|
335
|
+
return resolveUseLegacyUuidIds() ? new UUIDGenerator() : new OTELIDGenerator();
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// src/propagation.ts
|
|
339
|
+
var TRACEPARENT_HEADER = "traceparent";
|
|
340
|
+
var TRACESTATE_HEADER = "tracestate";
|
|
341
|
+
var BAGGAGE_HEADER = "baggage";
|
|
342
|
+
var BRAINTRUST_PARENT_KEY = "braintrust.parent";
|
|
343
|
+
var DEFAULT_TRACE_FLAGS = "01";
|
|
344
|
+
var TRACEPARENT_RE = /^00-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/;
|
|
345
|
+
var ZERO_TRACE_ID = "0".repeat(32);
|
|
346
|
+
var ZERO_SPAN_ID = "0".repeat(16);
|
|
347
|
+
var MAX_BAGGAGE_LENGTH = 8192;
|
|
348
|
+
var MAX_BAGGAGE_MEMBERS = 64;
|
|
349
|
+
var _utf8Encoder = new TextEncoder();
|
|
350
|
+
function utf8ByteLength(value) {
|
|
351
|
+
return _utf8Encoder.encode(value).length;
|
|
352
|
+
}
|
|
353
|
+
function capBaggageToMemberBoundary(value) {
|
|
354
|
+
const totalBytes = utf8ByteLength(value);
|
|
355
|
+
const withinBytes = totalBytes <= MAX_BAGGAGE_LENGTH;
|
|
356
|
+
let commaCount = 0;
|
|
357
|
+
for (let i = 0; i < value.length; i++) {
|
|
358
|
+
if (value.charCodeAt(i) === 44) {
|
|
359
|
+
commaCount++;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
const withinMembers = commaCount < MAX_BAGGAGE_MEMBERS;
|
|
363
|
+
if (withinBytes && withinMembers) {
|
|
364
|
+
return value;
|
|
365
|
+
}
|
|
366
|
+
const kept = [];
|
|
367
|
+
let length = 0;
|
|
368
|
+
for (const rawMember of value.split(",")) {
|
|
369
|
+
if (kept.length >= MAX_BAGGAGE_MEMBERS) {
|
|
370
|
+
break;
|
|
371
|
+
}
|
|
372
|
+
const cost = utf8ByteLength(rawMember) + (kept.length ? 1 : 0);
|
|
373
|
+
if (length + cost > MAX_BAGGAGE_LENGTH) {
|
|
374
|
+
break;
|
|
375
|
+
}
|
|
376
|
+
kept.push(rawMember);
|
|
377
|
+
length += cost;
|
|
378
|
+
}
|
|
379
|
+
if (!kept.length) {
|
|
380
|
+
return "";
|
|
381
|
+
}
|
|
382
|
+
return kept.join(",");
|
|
383
|
+
}
|
|
384
|
+
function isTraceContextHeaderTupleArray(value) {
|
|
385
|
+
return Array.isArray(value) && value.every(
|
|
386
|
+
(item) => Array.isArray(item) && typeof item[0] === "string" && typeof item[1] === "string"
|
|
387
|
+
);
|
|
388
|
+
}
|
|
389
|
+
function isListHeader(name) {
|
|
390
|
+
const lowered = name.toLowerCase();
|
|
391
|
+
return lowered === BAGGAGE_HEADER || lowered === TRACESTATE_HEADER;
|
|
392
|
+
}
|
|
393
|
+
function headerValueToString(value, name) {
|
|
394
|
+
if (value === void 0 || value === null) {
|
|
395
|
+
return void 0;
|
|
396
|
+
}
|
|
397
|
+
if (Array.isArray(value)) {
|
|
398
|
+
const stringValues = value.filter((item) => {
|
|
399
|
+
return typeof item === "string";
|
|
400
|
+
});
|
|
401
|
+
if (!stringValues.length) {
|
|
402
|
+
return void 0;
|
|
403
|
+
}
|
|
404
|
+
return isListHeader(name) ? stringValues.join(",") : stringValues[0];
|
|
405
|
+
}
|
|
406
|
+
return typeof value === "string" ? value : String(value);
|
|
407
|
+
}
|
|
408
|
+
function getHeader(headers, name) {
|
|
409
|
+
if (!headers) {
|
|
410
|
+
return void 0;
|
|
411
|
+
}
|
|
412
|
+
if (isTraceContextHeaderTupleArray(headers)) {
|
|
413
|
+
const lowered2 = name.toLowerCase();
|
|
414
|
+
const matches = headers.filter(([key]) => key.toLowerCase() === lowered2).map(([, value]) => value);
|
|
415
|
+
if (!matches.length) {
|
|
416
|
+
return void 0;
|
|
417
|
+
}
|
|
418
|
+
return headerValueToString(matches, name);
|
|
419
|
+
}
|
|
420
|
+
const getter = headers.get;
|
|
421
|
+
if (typeof getter === "function") {
|
|
422
|
+
try {
|
|
423
|
+
const value = headerValueToString(getter.call(headers, name), name);
|
|
424
|
+
if (value !== void 0) {
|
|
425
|
+
return value;
|
|
426
|
+
}
|
|
427
|
+
} catch {
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
const nodeGetter = headers.getHeader;
|
|
431
|
+
if (typeof nodeGetter === "function") {
|
|
432
|
+
try {
|
|
433
|
+
const value = headerValueToString(nodeGetter.call(headers, name), name);
|
|
434
|
+
if (value !== void 0) {
|
|
435
|
+
return value;
|
|
436
|
+
}
|
|
437
|
+
} catch {
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
const headerBag = headers;
|
|
441
|
+
const exact = headerValueToString(headerBag[name], name);
|
|
442
|
+
if (exact !== void 0) {
|
|
443
|
+
return exact;
|
|
444
|
+
}
|
|
445
|
+
const lowered = name.toLowerCase();
|
|
446
|
+
for (const key of Object.keys(headers)) {
|
|
447
|
+
if (key !== name && key.toLowerCase() === lowered) {
|
|
448
|
+
const value = headerValueToString(headerBag[key], name);
|
|
449
|
+
if (value !== void 0) {
|
|
450
|
+
return value;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
return void 0;
|
|
455
|
+
}
|
|
456
|
+
function isHex(value, length) {
|
|
457
|
+
if (typeof value !== "string" || value.length !== length) {
|
|
458
|
+
return false;
|
|
459
|
+
}
|
|
460
|
+
for (let i = 0; i < value.length; i++) {
|
|
461
|
+
const c = value[i];
|
|
462
|
+
const isDigit = c >= "0" && c <= "9";
|
|
463
|
+
const isLowerHex = c >= "a" && c <= "f";
|
|
464
|
+
if (!isDigit && !isLowerHex) {
|
|
465
|
+
return false;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
return true;
|
|
469
|
+
}
|
|
470
|
+
function parseTraceparent(value) {
|
|
471
|
+
if (!value || typeof value !== "string") {
|
|
472
|
+
return void 0;
|
|
473
|
+
}
|
|
474
|
+
const match = TRACEPARENT_RE.exec(value.trim());
|
|
475
|
+
if (!match) {
|
|
476
|
+
return void 0;
|
|
477
|
+
}
|
|
478
|
+
const traceId = match[1];
|
|
479
|
+
const spanId = match[2];
|
|
480
|
+
const traceFlags = match[3];
|
|
481
|
+
if (traceId === ZERO_TRACE_ID || spanId === ZERO_SPAN_ID) {
|
|
482
|
+
return void 0;
|
|
483
|
+
}
|
|
484
|
+
return { traceId, spanId, traceFlags };
|
|
485
|
+
}
|
|
486
|
+
function formatTraceparent(traceId, spanId, traceFlags = DEFAULT_TRACE_FLAGS) {
|
|
487
|
+
if (!isHex(traceId, 32) || traceId === ZERO_TRACE_ID) {
|
|
488
|
+
return void 0;
|
|
489
|
+
}
|
|
490
|
+
if (!isHex(spanId, 16) || spanId === ZERO_SPAN_ID) {
|
|
491
|
+
return void 0;
|
|
492
|
+
}
|
|
493
|
+
const flags = isHex(traceFlags, 2) ? traceFlags : DEFAULT_TRACE_FLAGS;
|
|
494
|
+
return `00-${traceId}-${spanId}-${flags}`;
|
|
495
|
+
}
|
|
496
|
+
function percentEncode(value) {
|
|
497
|
+
return encodeURIComponent(value);
|
|
498
|
+
}
|
|
499
|
+
function percentDecode(value) {
|
|
500
|
+
if (!value.includes("%")) {
|
|
501
|
+
return value;
|
|
502
|
+
}
|
|
503
|
+
try {
|
|
504
|
+
return decodeURIComponent(value);
|
|
505
|
+
} catch {
|
|
506
|
+
return value;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
function parseBaggage(value) {
|
|
510
|
+
const result = {};
|
|
511
|
+
if (!value || typeof value !== "string") {
|
|
512
|
+
return result;
|
|
513
|
+
}
|
|
514
|
+
const bounded = capBaggageToMemberBoundary(value);
|
|
515
|
+
for (let member of bounded.split(",")) {
|
|
516
|
+
member = member.trim();
|
|
517
|
+
if (!member || !member.includes("=")) {
|
|
518
|
+
continue;
|
|
519
|
+
}
|
|
520
|
+
member = member.split(";", 1)[0];
|
|
521
|
+
const eq = member.indexOf("=");
|
|
522
|
+
const key = percentDecode(member.slice(0, eq).trim());
|
|
523
|
+
const val = member.slice(eq + 1).trim();
|
|
524
|
+
if (!key) {
|
|
525
|
+
continue;
|
|
526
|
+
}
|
|
527
|
+
result[key] = percentDecode(val);
|
|
528
|
+
}
|
|
529
|
+
return result;
|
|
530
|
+
}
|
|
531
|
+
function mergeBaggage(existing, braintrustParent) {
|
|
532
|
+
let btMember = void 0;
|
|
533
|
+
if (braintrustParent) {
|
|
534
|
+
const encodedKey = percentEncode(BRAINTRUST_PARENT_KEY);
|
|
535
|
+
const encodedVal = percentEncode(String(braintrustParent));
|
|
536
|
+
btMember = `${encodedKey}=${encodedVal}`;
|
|
537
|
+
if (utf8ByteLength(btMember) > MAX_BAGGAGE_LENGTH) {
|
|
538
|
+
btMember = void 0;
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
let byteBudget = MAX_BAGGAGE_LENGTH;
|
|
542
|
+
let memberBudget = MAX_BAGGAGE_MEMBERS;
|
|
543
|
+
if (btMember !== void 0) {
|
|
544
|
+
byteBudget -= utf8ByteLength(btMember) + 1;
|
|
545
|
+
memberBudget -= 1;
|
|
546
|
+
}
|
|
547
|
+
const relayed = [];
|
|
548
|
+
let length = 0;
|
|
549
|
+
if (existing && typeof existing === "string") {
|
|
550
|
+
for (const rawMember of existing.split(",")) {
|
|
551
|
+
const member = rawMember.trim();
|
|
552
|
+
if (!member || !member.includes("=")) {
|
|
553
|
+
continue;
|
|
554
|
+
}
|
|
555
|
+
const keyPart = member.split(";", 1)[0].split("=", 1)[0];
|
|
556
|
+
const key = percentDecode(keyPart.trim());
|
|
557
|
+
if (key === BRAINTRUST_PARENT_KEY) {
|
|
558
|
+
continue;
|
|
559
|
+
}
|
|
560
|
+
if (relayed.length >= memberBudget) {
|
|
561
|
+
break;
|
|
562
|
+
}
|
|
563
|
+
const cost = utf8ByteLength(member) + (relayed.length ? 1 : 0);
|
|
564
|
+
if (length + cost > byteBudget) {
|
|
565
|
+
break;
|
|
566
|
+
}
|
|
567
|
+
relayed.push(member);
|
|
568
|
+
length += cost;
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
const members = btMember !== void 0 ? [...relayed, btMember] : relayed;
|
|
572
|
+
if (!members.length) {
|
|
573
|
+
return void 0;
|
|
574
|
+
}
|
|
575
|
+
return members.join(",");
|
|
293
576
|
}
|
|
294
577
|
|
|
295
578
|
// util/db_fields.ts
|
|
@@ -897,7 +1180,7 @@ var SpanComponentsV3 = class _SpanComponentsV3 {
|
|
|
897
1180
|
case 3 /* PLAYGROUND_LOGS */:
|
|
898
1181
|
return { prompt_session_id: this.data.object_id, log_id: "x" };
|
|
899
1182
|
default:
|
|
900
|
-
|
|
1183
|
+
this.data.object_type;
|
|
901
1184
|
throw new Error("Impossible");
|
|
902
1185
|
}
|
|
903
1186
|
}
|
|
@@ -1426,7 +1709,7 @@ var SpanComponentsV4 = class _SpanComponentsV4 {
|
|
|
1426
1709
|
case 3 /* PLAYGROUND_LOGS */:
|
|
1427
1710
|
return { prompt_session_id: this.data.object_id, log_id: "x" };
|
|
1428
1711
|
default:
|
|
1429
|
-
|
|
1712
|
+
this.data.object_type;
|
|
1430
1713
|
throw new Error(`Invalid object_type ${this.data.object_type}`);
|
|
1431
1714
|
}
|
|
1432
1715
|
}
|
|
@@ -1605,7 +1888,8 @@ var AclObjectType = z6.union([
|
|
|
1605
1888
|
"role",
|
|
1606
1889
|
"org_member",
|
|
1607
1890
|
"project_log",
|
|
1608
|
-
"org_project"
|
|
1891
|
+
"org_project",
|
|
1892
|
+
"org_audit_logs"
|
|
1609
1893
|
]),
|
|
1610
1894
|
z6.null()
|
|
1611
1895
|
]);
|
|
@@ -1631,6 +1915,17 @@ var Acl = z6.object({
|
|
|
1631
1915
|
_object_org_id: z6.string().uuid(),
|
|
1632
1916
|
created: z6.union([z6.string(), z6.null()]).optional()
|
|
1633
1917
|
});
|
|
1918
|
+
var Agent = z6.object({
|
|
1919
|
+
id: z6.string().uuid(),
|
|
1920
|
+
project_id: z6.string().uuid(),
|
|
1921
|
+
user_id: z6.string().uuid(),
|
|
1922
|
+
created: z6.union([z6.string(), z6.null()]).optional(),
|
|
1923
|
+
name: z6.string(),
|
|
1924
|
+
slug: z6.string(),
|
|
1925
|
+
kind: z6.string(),
|
|
1926
|
+
description: z6.union([z6.string(), z6.null()]).optional(),
|
|
1927
|
+
metadata: z6.union([z6.object({}).partial().passthrough(), z6.null()]).optional()
|
|
1928
|
+
});
|
|
1634
1929
|
var AISecret = z6.object({
|
|
1635
1930
|
id: z6.string().uuid(),
|
|
1636
1931
|
created: z6.union([z6.string(), z6.null()]).optional(),
|
|
@@ -1777,6 +2072,7 @@ var AttachmentStatus = z6.object({
|
|
|
1777
2072
|
upload_status: UploadStatus,
|
|
1778
2073
|
error_message: z6.string().optional()
|
|
1779
2074
|
});
|
|
2075
|
+
var AutomationStatus = z6.enum(["active", "paused"]);
|
|
1780
2076
|
var FunctionTypeEnum = z6.enum([
|
|
1781
2077
|
"llm",
|
|
1782
2078
|
"scorer",
|
|
@@ -1822,7 +2118,9 @@ var TopicMapData = z6.object({
|
|
|
1822
2118
|
topic_names: z6.record(z6.string()).optional(),
|
|
1823
2119
|
generation_settings: TopicMapGenerationSettings.optional(),
|
|
1824
2120
|
disable_reconciliation: z6.boolean().optional(),
|
|
1825
|
-
distance_threshold: z6.number().optional()
|
|
2121
|
+
distance_threshold: z6.number().optional(),
|
|
2122
|
+
btql_filter: z6.string().optional(),
|
|
2123
|
+
automation_btql_filter: z6.string().optional()
|
|
1826
2124
|
});
|
|
1827
2125
|
var BatchedFacetData = z6.object({
|
|
1828
2126
|
type: z6.literal("batched_facet"),
|
|
@@ -2105,7 +2403,7 @@ var DatasetEvent = z6.object({
|
|
|
2105
2403
|
origin: ObjectReferenceNullish.optional(),
|
|
2106
2404
|
comments: z6.union([z6.array(z6.unknown()), z6.null()]).optional(),
|
|
2107
2405
|
audit_data: z6.union([z6.array(z6.unknown()), z6.null()]).optional(),
|
|
2108
|
-
facets: z6.union([z6.
|
|
2406
|
+
facets: z6.union([z6.record(z6.union([z6.string(), z6.null()])), z6.null()]).optional(),
|
|
2109
2407
|
classifications: z6.union([
|
|
2110
2408
|
z6.record(
|
|
2111
2409
|
z6.array(
|
|
@@ -2257,7 +2555,7 @@ var ExperimentEvent = z6.object({
|
|
|
2257
2555
|
origin: ObjectReferenceNullish.optional(),
|
|
2258
2556
|
comments: z6.union([z6.array(z6.unknown()), z6.null()]).optional(),
|
|
2259
2557
|
audit_data: z6.union([z6.array(z6.unknown()), z6.null()]).optional(),
|
|
2260
|
-
facets: z6.union([z6.
|
|
2558
|
+
facets: z6.union([z6.record(z6.union([z6.string(), z6.null()])), z6.null()]).optional(),
|
|
2261
2559
|
classifications: z6.union([
|
|
2262
2560
|
z6.record(
|
|
2263
2561
|
z6.array(
|
|
@@ -2395,7 +2693,8 @@ var PromptParserNullish = z6.union([
|
|
|
2395
2693
|
use_cot: z6.boolean(),
|
|
2396
2694
|
choice_scores: z6.record(z6.number().gte(0).lte(1)).optional(),
|
|
2397
2695
|
choice: z6.array(z6.string()).optional(),
|
|
2398
|
-
allow_no_match: z6.boolean().optional()
|
|
2696
|
+
allow_no_match: z6.boolean().optional(),
|
|
2697
|
+
allow_skip: z6.boolean().optional()
|
|
2399
2698
|
}),
|
|
2400
2699
|
z6.null()
|
|
2401
2700
|
]);
|
|
@@ -2725,6 +3024,9 @@ var Group = z6.object({
|
|
|
2725
3024
|
var GroupScope = z6.object({
|
|
2726
3025
|
type: z6.literal("group"),
|
|
2727
3026
|
group_by: z6.string(),
|
|
3027
|
+
interval_seconds: z6.number().gte(1).optional(),
|
|
3028
|
+
max_traces: z6.number().int().gte(1).lte(64).optional(),
|
|
3029
|
+
placement: z6.enum(["first", "each"]),
|
|
2728
3030
|
idle_seconds: z6.number().optional()
|
|
2729
3031
|
});
|
|
2730
3032
|
var IfExists = z6.enum(["error", "ignore", "replace"]);
|
|
@@ -2873,6 +3175,10 @@ var RetentionObjectType = z6.enum([
|
|
|
2873
3175
|
"experiment",
|
|
2874
3176
|
"dataset"
|
|
2875
3177
|
]);
|
|
3178
|
+
var TopicAutomationFacetModel = z6.union([
|
|
3179
|
+
z6.enum(["brain-facet-latest", "brain-facet-1", "brain-facet-2"]),
|
|
3180
|
+
z6.null()
|
|
3181
|
+
]);
|
|
2876
3182
|
var TopicMapFunctionAutomation = z6.object({
|
|
2877
3183
|
function: SavedFunctionId.and(z6.unknown()),
|
|
2878
3184
|
btql_filter: z6.union([z6.string(), z6.null()]).optional()
|
|
@@ -2885,7 +3191,9 @@ var TopicAutomationDataScope = z6.union([
|
|
|
2885
3191
|
]);
|
|
2886
3192
|
var TopicAutomationConfig = z6.object({
|
|
2887
3193
|
event_type: z6.literal("topic"),
|
|
3194
|
+
status: AutomationStatus.optional(),
|
|
2888
3195
|
sampling_rate: z6.number().gte(0).lte(1),
|
|
3196
|
+
facet_model: TopicAutomationFacetModel.optional(),
|
|
2889
3197
|
facet_functions: z6.array(SavedFunctionId),
|
|
2890
3198
|
topic_map_functions: z6.array(TopicMapFunctionAutomation),
|
|
2891
3199
|
scope: z6.union([SpanScope, TraceScope, GroupScope, z6.null()]).optional(),
|
|
@@ -2899,6 +3207,19 @@ var TopicAutomationConfig = z6.object({
|
|
|
2899
3207
|
z6.null()
|
|
2900
3208
|
]).optional()
|
|
2901
3209
|
});
|
|
3210
|
+
var TopicDigestAutomationConfig = z6.object({
|
|
3211
|
+
event_type: z6.literal("topic_digest"),
|
|
3212
|
+
status: AutomationStatus.optional(),
|
|
3213
|
+
window_seconds: z6.number().int().gte(3600).lte(2592e3).optional().default(86400),
|
|
3214
|
+
scheduled_time_minutes_utc: z6.number().int().gte(0).lte(1439),
|
|
3215
|
+
action: z6.object({
|
|
3216
|
+
type: z6.literal("slack"),
|
|
3217
|
+
workspace_id: z6.string(),
|
|
3218
|
+
channel: z6.string(),
|
|
3219
|
+
message_template: z6.string().optional()
|
|
3220
|
+
}),
|
|
3221
|
+
topic_map_function_ids: z6.array(z6.string()).max(10).optional()
|
|
3222
|
+
});
|
|
2902
3223
|
var ProjectAutomation = z6.object({
|
|
2903
3224
|
id: z6.string().uuid(),
|
|
2904
3225
|
project_id: z6.string().uuid(),
|
|
@@ -2923,6 +3244,7 @@ var ProjectAutomation = z6.object({
|
|
|
2923
3244
|
}),
|
|
2924
3245
|
z6.object({
|
|
2925
3246
|
event_type: z6.literal("btql_export"),
|
|
3247
|
+
status: AutomationStatus.optional(),
|
|
2926
3248
|
export_definition: z6.union([
|
|
2927
3249
|
z6.object({ type: z6.literal("log_traces") }),
|
|
2928
3250
|
z6.object({ type: z6.literal("log_spans") }),
|
|
@@ -2945,6 +3267,21 @@ var ProjectAutomation = z6.object({
|
|
|
2945
3267
|
]),
|
|
2946
3268
|
batch_size: z6.union([z6.number(), z6.null()]).optional()
|
|
2947
3269
|
}),
|
|
3270
|
+
z6.object({
|
|
3271
|
+
event_type: z6.literal("async_query"),
|
|
3272
|
+
status: AutomationStatus.optional(),
|
|
3273
|
+
created_by_user_id: z6.string().uuid(),
|
|
3274
|
+
object_type: z6.enum([
|
|
3275
|
+
"project_logs",
|
|
3276
|
+
"experiment",
|
|
3277
|
+
"dataset",
|
|
3278
|
+
"playground_logs"
|
|
3279
|
+
]),
|
|
3280
|
+
object_id: z6.string(),
|
|
3281
|
+
query: z6.string(),
|
|
3282
|
+
format: z6.literal("jsonl"),
|
|
3283
|
+
batch_size: z6.union([z6.number(), z6.null()]).optional()
|
|
3284
|
+
}),
|
|
2948
3285
|
z6.object({
|
|
2949
3286
|
event_type: z6.literal("retention"),
|
|
2950
3287
|
object_type: RetentionObjectType,
|
|
@@ -2963,7 +3300,8 @@ var ProjectAutomation = z6.object({
|
|
|
2963
3300
|
})
|
|
2964
3301
|
])
|
|
2965
3302
|
}),
|
|
2966
|
-
TopicAutomationConfig
|
|
3303
|
+
TopicAutomationConfig,
|
|
3304
|
+
TopicDigestAutomationConfig
|
|
2967
3305
|
])
|
|
2968
3306
|
});
|
|
2969
3307
|
var ProjectLogsEvent = z6.object({
|
|
@@ -3002,7 +3340,7 @@ var ProjectLogsEvent = z6.object({
|
|
|
3002
3340
|
comments: z6.union([z6.array(z6.unknown()), z6.null()]).optional(),
|
|
3003
3341
|
audit_data: z6.union([z6.array(z6.unknown()), z6.null()]).optional(),
|
|
3004
3342
|
_async_scoring_state: z6.unknown().optional(),
|
|
3005
|
-
facets: z6.union([z6.
|
|
3343
|
+
facets: z6.union([z6.record(z6.union([z6.string(), z6.null()])), z6.null()]).optional(),
|
|
3006
3344
|
classifications: z6.union([
|
|
3007
3345
|
z6.record(
|
|
3008
3346
|
z6.array(
|
|
@@ -3051,11 +3389,34 @@ var ProjectScoreCategories = z6.union([
|
|
|
3051
3389
|
z6.array(z6.string()),
|
|
3052
3390
|
z6.null()
|
|
3053
3391
|
]);
|
|
3392
|
+
var ProjectScoreCondition = z6.union([
|
|
3393
|
+
z6.object({
|
|
3394
|
+
when: z6.object({
|
|
3395
|
+
clauses: z6.union([z6.array(z6.string()), z6.null()]),
|
|
3396
|
+
subspan_clauses: z6.union([z6.array(z6.string()), z6.null()]),
|
|
3397
|
+
trace_clauses: z6.union([z6.array(z6.string()), z6.null()])
|
|
3398
|
+
}).partial(),
|
|
3399
|
+
behavior: z6.literal("hidden").optional().default("hidden")
|
|
3400
|
+
}),
|
|
3401
|
+
z6.null()
|
|
3402
|
+
]);
|
|
3054
3403
|
var ProjectScoreConfig = z6.union([
|
|
3055
3404
|
z6.object({
|
|
3056
3405
|
multi_select: z6.union([z6.boolean(), z6.null()]),
|
|
3057
3406
|
destination: z6.union([z6.string(), z6.null()]),
|
|
3058
|
-
|
|
3407
|
+
visibility: z6.union([
|
|
3408
|
+
z6.object({
|
|
3409
|
+
users: z6.union([z6.array(z6.string()), z6.null()]),
|
|
3410
|
+
groups: z6.union([z6.array(z6.string()), z6.null()])
|
|
3411
|
+
}).partial(),
|
|
3412
|
+
z6.null()
|
|
3413
|
+
]),
|
|
3414
|
+
online: OnlineScoreConfig,
|
|
3415
|
+
condition: ProjectScoreCondition,
|
|
3416
|
+
object_types: z6.union([
|
|
3417
|
+
z6.array(z6.enum(["project_logs", "dataset", "experiment"])),
|
|
3418
|
+
z6.null()
|
|
3419
|
+
])
|
|
3059
3420
|
}).partial(),
|
|
3060
3421
|
z6.null()
|
|
3061
3422
|
]);
|
|
@@ -3240,8 +3601,7 @@ var User = z6.object({
|
|
|
3240
3601
|
family_name: z6.union([z6.string(), z6.null()]).optional(),
|
|
3241
3602
|
email: z6.union([z6.string(), z6.null()]).optional(),
|
|
3242
3603
|
avatar_url: z6.union([z6.string(), z6.null()]).optional(),
|
|
3243
|
-
created: z6.union([z6.string(), z6.null()]).optional()
|
|
3244
|
-
last_active_at: z6.union([z6.number(), z6.null()]).optional()
|
|
3604
|
+
created: z6.union([z6.string(), z6.null()]).optional()
|
|
3245
3605
|
});
|
|
3246
3606
|
var ViewDataSearch = z6.union([
|
|
3247
3607
|
z6.object({
|
|
@@ -4530,7 +4890,10 @@ var BraintrustContextManager = class extends ContextManager {
|
|
|
4530
4890
|
}
|
|
4531
4891
|
};
|
|
4532
4892
|
function getSpanComponentsClass() {
|
|
4533
|
-
|
|
4893
|
+
if (globalThis.BRAINTRUST_SPAN_COMPONENT) {
|
|
4894
|
+
return globalThis.BRAINTRUST_SPAN_COMPONENT;
|
|
4895
|
+
}
|
|
4896
|
+
return resolveUseLegacyUuidIds() ? SpanComponentsV3 : SpanComponentsV4;
|
|
4534
4897
|
}
|
|
4535
4898
|
function getContextManager() {
|
|
4536
4899
|
return globalThis.BRAINTRUST_CONTEXT_MANAGER ? new globalThis.BRAINTRUST_CONTEXT_MANAGER() : new BraintrustContextManager();
|
|
@@ -4566,6 +4929,9 @@ var NoopSpan = class {
|
|
|
4566
4929
|
async export() {
|
|
4567
4930
|
return "";
|
|
4568
4931
|
}
|
|
4932
|
+
inject(carrier) {
|
|
4933
|
+
return carrier ?? {};
|
|
4934
|
+
}
|
|
4569
4935
|
async permalink() {
|
|
4570
4936
|
return NOOP_SPAN_PERMALINK;
|
|
4571
4937
|
}
|
|
@@ -4616,6 +4982,10 @@ var loginSchema = z8.strictObject({
|
|
|
4616
4982
|
debugLogLevelDisabled: z8.boolean().optional()
|
|
4617
4983
|
});
|
|
4618
4984
|
var stateNonce = 0;
|
|
4985
|
+
var V1_PROXY_SUFFIX = "/v1/proxy";
|
|
4986
|
+
function normalizeProxyConnUrl(proxyUrl) {
|
|
4987
|
+
return proxyUrl.endsWith(V1_PROXY_SUFFIX) ? proxyUrl.slice(0, proxyUrl.length - V1_PROXY_SUFFIX.length) : proxyUrl;
|
|
4988
|
+
}
|
|
4619
4989
|
var BraintrustState = class _BraintrustState {
|
|
4620
4990
|
constructor(loginParams) {
|
|
4621
4991
|
this.loginParams = loginParams;
|
|
@@ -4886,7 +5256,10 @@ var BraintrustState = class _BraintrustState {
|
|
|
4886
5256
|
if (!this.proxyUrl) {
|
|
4887
5257
|
throw new Error("Must initialize proxyUrl before requesting proxyConn");
|
|
4888
5258
|
}
|
|
4889
|
-
this._proxyConn = new HTTPConnection(
|
|
5259
|
+
this._proxyConn = new HTTPConnection(
|
|
5260
|
+
normalizeProxyConnUrl(this.proxyUrl),
|
|
5261
|
+
this.fetch
|
|
5262
|
+
);
|
|
4890
5263
|
}
|
|
4891
5264
|
return this._proxyConn;
|
|
4892
5265
|
}
|
|
@@ -5644,7 +6017,7 @@ function updateSpan({
|
|
|
5644
6017
|
...event
|
|
5645
6018
|
}) {
|
|
5646
6019
|
const resolvedState = state ?? _globalState;
|
|
5647
|
-
const components =
|
|
6020
|
+
const components = SpanComponentsV4.fromStr(exported);
|
|
5648
6021
|
if (!components.data.row_id) {
|
|
5649
6022
|
throw new Error("Exported span must have a row id");
|
|
5650
6023
|
}
|
|
@@ -5744,7 +6117,7 @@ async function permalink(slug, opts) {
|
|
|
5744
6117
|
return state.appUrl;
|
|
5745
6118
|
};
|
|
5746
6119
|
try {
|
|
5747
|
-
const components =
|
|
6120
|
+
const components = SpanComponentsV4.fromStr(slug);
|
|
5748
6121
|
const object_type = spanObjectTypeV3ToString(components.data.object_type);
|
|
5749
6122
|
const [orgName, appUrl, object_id] = await Promise.all([
|
|
5750
6123
|
getOrgName(),
|
|
@@ -5768,35 +6141,47 @@ function startSpanParentArgs(args) {
|
|
|
5768
6141
|
let argParentObjectId = void 0;
|
|
5769
6142
|
let argParentSpanIds = void 0;
|
|
5770
6143
|
let argPropagatedEvent = void 0;
|
|
5771
|
-
|
|
6144
|
+
let argPropagatedState = void 0;
|
|
6145
|
+
const { parentSlug, propagatedState: parentPropagatedState } = normalizeParent(args.parent, args.state);
|
|
6146
|
+
if (parentSlug) {
|
|
5772
6147
|
if (args.parentSpanIds) {
|
|
5773
6148
|
throw new Error("Cannot specify both parent and parentSpanIds");
|
|
5774
6149
|
}
|
|
5775
|
-
const parentComponents =
|
|
6150
|
+
const parentComponents = SpanComponentsV4.fromStr(parentSlug);
|
|
5776
6151
|
if (args.parentObjectType !== parentComponents.data.object_type) {
|
|
5777
6152
|
throw new Error(
|
|
5778
6153
|
`Mismatch between expected span parent object type ${args.parentObjectType} and provided type ${parentComponents.data.object_type}`
|
|
5779
6154
|
);
|
|
5780
6155
|
}
|
|
5781
6156
|
argParentObjectId = args.parentObjectId;
|
|
5782
|
-
if (parentComponents.data.row_id
|
|
6157
|
+
if (parentComponents.data.row_id && parentSpanIdsUsable(
|
|
6158
|
+
parentComponents.data.span_id,
|
|
6159
|
+
parentComponents.data.root_span_id
|
|
6160
|
+
)) {
|
|
5783
6161
|
argParentSpanIds = {
|
|
5784
6162
|
spanId: parentComponents.data.span_id,
|
|
5785
6163
|
rootSpanId: parentComponents.data.root_span_id
|
|
5786
6164
|
};
|
|
5787
6165
|
}
|
|
5788
6166
|
argPropagatedEvent = args.propagatedEvent ?? (parentComponents.data.propagated_event ?? void 0);
|
|
6167
|
+
const propagatedState = args.propagatedState ?? parentPropagatedState;
|
|
6168
|
+
if (propagatedState) {
|
|
6169
|
+
const { braintrustParent: _ignoredBraintrustParent, ...w3cState } = propagatedState;
|
|
6170
|
+
argPropagatedState = w3cState;
|
|
6171
|
+
}
|
|
5789
6172
|
} else {
|
|
5790
6173
|
argParentObjectId = args.parentObjectId;
|
|
5791
6174
|
argParentSpanIds = args.parentSpanIds;
|
|
5792
6175
|
argPropagatedEvent = args.propagatedEvent;
|
|
6176
|
+
argPropagatedState = args.propagatedState;
|
|
5793
6177
|
}
|
|
5794
6178
|
return {
|
|
5795
6179
|
parentObjectType: args.parentObjectType,
|
|
5796
6180
|
parentObjectId: argParentObjectId,
|
|
5797
6181
|
parentComputeObjectMetadataArgs: args.parentComputeObjectMetadataArgs,
|
|
5798
6182
|
parentSpanIds: argParentSpanIds,
|
|
5799
|
-
propagatedEvent: argPropagatedEvent
|
|
6183
|
+
propagatedEvent: argPropagatedEvent,
|
|
6184
|
+
propagatedState: argPropagatedState
|
|
5800
6185
|
};
|
|
5801
6186
|
}
|
|
5802
6187
|
var Logger = class {
|
|
@@ -5997,6 +6382,22 @@ var Logger = class {
|
|
|
5997
6382
|
_getLinkBaseUrl() {
|
|
5998
6383
|
return _getLinkBaseUrl(this.state, this._linkArgs);
|
|
5999
6384
|
}
|
|
6385
|
+
/**
|
|
6386
|
+
* Return this logger's Braintrust parent string (`project_id:<id>` or
|
|
6387
|
+
* `project_name:<name>`) for the `braintrust.parent` baggage entry, or
|
|
6388
|
+
* undefined when it cannot be determined synchronously.
|
|
6389
|
+
*/
|
|
6390
|
+
_getOtelParent() {
|
|
6391
|
+
const id = this.computeMetadataArgs?.project_id || this.lazyId.getSync().value;
|
|
6392
|
+
if (id) {
|
|
6393
|
+
return `project_id:${id}`;
|
|
6394
|
+
}
|
|
6395
|
+
const name = this.computeMetadataArgs?.project_name;
|
|
6396
|
+
if (name) {
|
|
6397
|
+
return `project_name:${name}`;
|
|
6398
|
+
}
|
|
6399
|
+
return void 0;
|
|
6400
|
+
}
|
|
6000
6401
|
};
|
|
6001
6402
|
function castLogger(logger, asyncFlush) {
|
|
6002
6403
|
if (logger === void 0) return void 0;
|
|
@@ -6091,12 +6492,12 @@ function stringifyWithOverflowMeta(item) {
|
|
|
6091
6492
|
object_ids: pickLogs3OverflowObjectIds(record),
|
|
6092
6493
|
is_delete: record[OBJECT_DELETE_FIELD] === true,
|
|
6093
6494
|
input_row: {
|
|
6094
|
-
byte_size:
|
|
6495
|
+
byte_size: utf8ByteLength2(str)
|
|
6095
6496
|
}
|
|
6096
6497
|
}
|
|
6097
6498
|
};
|
|
6098
6499
|
}
|
|
6099
|
-
function
|
|
6500
|
+
function utf8ByteLength2(value) {
|
|
6100
6501
|
if (typeof TextEncoder !== "undefined") {
|
|
6101
6502
|
return new TextEncoder().encode(value).length;
|
|
6102
6503
|
}
|
|
@@ -6484,7 +6885,7 @@ var HTTPBackgroundLogger = class _HTTPBackgroundLogger {
|
|
|
6484
6885
|
}) {
|
|
6485
6886
|
const conn = await this.apiConn.get();
|
|
6486
6887
|
const dataStr = constructLogs3Data(items);
|
|
6487
|
-
const payloadBytes =
|
|
6888
|
+
const payloadBytes = utf8ByteLength2(dataStr);
|
|
6488
6889
|
const useOverflow = canUseOverflow && payloadBytes > maxRequestSize;
|
|
6489
6890
|
if (this.allPublishPayloadsDir) {
|
|
6490
6891
|
await _HTTPBackgroundLogger.writePayloadToDir({
|
|
@@ -7105,6 +7506,8 @@ function initDataset(projectOrOptions, optionalOptions) {
|
|
|
7105
7506
|
const normalizedVersion = selection.version;
|
|
7106
7507
|
const normalizedEnvironment = selection.environment;
|
|
7107
7508
|
const normalizedSnapshotName = selection.snapshotName;
|
|
7509
|
+
const cliInternalBtql = globalThis.__bt_eval_internal_btql;
|
|
7510
|
+
const internalBtql = cliInternalBtql === void 0 ? _internal_btql : _internal_btql === void 0 ? cliInternalBtql : isObject(_internal_btql) ? { ...cliInternalBtql, ..._internal_btql } : _internal_btql;
|
|
7108
7511
|
const state = stateArg ?? _globalState;
|
|
7109
7512
|
const lazyMetadata = new LazyValue(
|
|
7110
7513
|
async () => {
|
|
@@ -7156,7 +7559,7 @@ function initDataset(projectOrOptions, optionalOptions) {
|
|
|
7156
7559
|
lazyMetadata,
|
|
7157
7560
|
typeof resolvedVersion === "string" ? resolvedVersion : void 0,
|
|
7158
7561
|
legacy,
|
|
7159
|
-
|
|
7562
|
+
internalBtql,
|
|
7160
7563
|
resolvedVersion instanceof LazyValue || normalizedEnvironment !== void 0 || normalizedSnapshotName !== void 0 ? {
|
|
7161
7564
|
...resolvedVersion instanceof LazyValue ? {
|
|
7162
7565
|
lazyPinnedVersion: resolvedVersion
|
|
@@ -7620,23 +8023,285 @@ function currentSpan(options) {
|
|
|
7620
8023
|
const state = options?.state ?? _globalState;
|
|
7621
8024
|
return state.contextManager.getCurrentSpan() ?? NOOP_SPAN;
|
|
7622
8025
|
}
|
|
7623
|
-
function
|
|
8026
|
+
function getSpanParentObjectAndPropagatedState(options) {
|
|
7624
8027
|
const state = options?.state ?? _globalState;
|
|
7625
8028
|
const parentSpan = currentSpan({ state });
|
|
7626
8029
|
if (!Object.is(parentSpan, NOOP_SPAN)) {
|
|
7627
|
-
return parentSpan;
|
|
8030
|
+
return { parentObject: parentSpan, propagatedState: void 0 };
|
|
8031
|
+
}
|
|
8032
|
+
const parent = options?.parent ?? state.currentParent.getStore();
|
|
8033
|
+
const { parentSlug, propagatedState } = normalizeParent(parent, state);
|
|
8034
|
+
if (parentSlug) {
|
|
8035
|
+
return {
|
|
8036
|
+
parentObject: SpanComponentsV4.fromStr(parentSlug),
|
|
8037
|
+
propagatedState
|
|
8038
|
+
};
|
|
7628
8039
|
}
|
|
7629
|
-
const parentStr = options?.parent ?? state.currentParent.getStore();
|
|
7630
|
-
if (parentStr) return getSpanComponentsClass().fromStr(parentStr);
|
|
7631
8040
|
const experiment = currentExperiment();
|
|
7632
8041
|
if (experiment) {
|
|
7633
|
-
return experiment;
|
|
8042
|
+
return { parentObject: experiment, propagatedState: void 0 };
|
|
7634
8043
|
}
|
|
7635
8044
|
const logger = currentLogger(options);
|
|
7636
8045
|
if (logger) {
|
|
7637
|
-
return logger;
|
|
8046
|
+
return { parentObject: logger, propagatedState: void 0 };
|
|
8047
|
+
}
|
|
8048
|
+
return { parentObject: NOOP_SPAN, propagatedState: void 0 };
|
|
8049
|
+
}
|
|
8050
|
+
function getSpanParentObject(options) {
|
|
8051
|
+
return getSpanParentObjectAndPropagatedState(options).parentObject;
|
|
8052
|
+
}
|
|
8053
|
+
function currentBraintrustParent(state) {
|
|
8054
|
+
const resolvedState = state ?? _globalState;
|
|
8055
|
+
const experiment = currentExperiment({ state: resolvedState });
|
|
8056
|
+
if (experiment) {
|
|
8057
|
+
try {
|
|
8058
|
+
return experiment._getOtelParent() ?? void 0;
|
|
8059
|
+
} catch {
|
|
8060
|
+
return void 0;
|
|
8061
|
+
}
|
|
8062
|
+
}
|
|
8063
|
+
const logger = currentLogger({ state: resolvedState });
|
|
8064
|
+
if (logger) {
|
|
8065
|
+
try {
|
|
8066
|
+
return logger._getOtelParent() ?? void 0;
|
|
8067
|
+
} catch {
|
|
8068
|
+
return void 0;
|
|
8069
|
+
}
|
|
8070
|
+
}
|
|
8071
|
+
return void 0;
|
|
8072
|
+
}
|
|
8073
|
+
function braintrustParentToComponents(braintrustParent) {
|
|
8074
|
+
if (!braintrustParent) {
|
|
8075
|
+
return void 0;
|
|
8076
|
+
}
|
|
8077
|
+
if (braintrustParent.startsWith("project_id:")) {
|
|
8078
|
+
const objectId = braintrustParent.slice("project_id:".length);
|
|
8079
|
+
return objectId ? {
|
|
8080
|
+
objectType: 2 /* PROJECT_LOGS */,
|
|
8081
|
+
objectId,
|
|
8082
|
+
computeArgs: void 0
|
|
8083
|
+
} : void 0;
|
|
8084
|
+
}
|
|
8085
|
+
if (braintrustParent.startsWith("project_name:")) {
|
|
8086
|
+
const name = braintrustParent.slice("project_name:".length);
|
|
8087
|
+
return name ? {
|
|
8088
|
+
objectType: 2 /* PROJECT_LOGS */,
|
|
8089
|
+
objectId: void 0,
|
|
8090
|
+
computeArgs: { project_name: name }
|
|
8091
|
+
} : void 0;
|
|
8092
|
+
}
|
|
8093
|
+
if (braintrustParent.startsWith("experiment_id:")) {
|
|
8094
|
+
const objectId = braintrustParent.slice("experiment_id:".length);
|
|
8095
|
+
return objectId ? {
|
|
8096
|
+
objectType: 1 /* EXPERIMENT */,
|
|
8097
|
+
objectId,
|
|
8098
|
+
computeArgs: void 0
|
|
8099
|
+
} : void 0;
|
|
8100
|
+
}
|
|
8101
|
+
return void 0;
|
|
8102
|
+
}
|
|
8103
|
+
function isMutableHeaderTupleArray(carrier) {
|
|
8104
|
+
return Array.isArray(carrier) && carrier.every((item) => Array.isArray(item) && typeof item[0] === "string");
|
|
8105
|
+
}
|
|
8106
|
+
function setHeader(carrier, name, value) {
|
|
8107
|
+
if (isMutableHeaderTupleArray(carrier)) {
|
|
8108
|
+
const lowered2 = name.toLowerCase();
|
|
8109
|
+
for (let i = carrier.length - 1; i >= 0; i--) {
|
|
8110
|
+
if (carrier[i][0].toLowerCase() === lowered2) {
|
|
8111
|
+
carrier.splice(i, 1);
|
|
8112
|
+
}
|
|
8113
|
+
}
|
|
8114
|
+
carrier.push([name, value]);
|
|
8115
|
+
return;
|
|
8116
|
+
}
|
|
8117
|
+
const setter = carrier.set;
|
|
8118
|
+
if (typeof setter === "function") {
|
|
8119
|
+
const deleter = carrier.delete;
|
|
8120
|
+
if (typeof deleter === "function") {
|
|
8121
|
+
try {
|
|
8122
|
+
deleter.call(carrier, name);
|
|
8123
|
+
} catch {
|
|
8124
|
+
}
|
|
8125
|
+
}
|
|
8126
|
+
setter.call(carrier, name, value);
|
|
8127
|
+
return;
|
|
8128
|
+
}
|
|
8129
|
+
const nodeSetter = carrier.setHeader;
|
|
8130
|
+
if (typeof nodeSetter === "function") {
|
|
8131
|
+
const remover = carrier.removeHeader;
|
|
8132
|
+
if (typeof remover === "function") {
|
|
8133
|
+
try {
|
|
8134
|
+
remover.call(carrier, name);
|
|
8135
|
+
} catch {
|
|
8136
|
+
}
|
|
8137
|
+
}
|
|
8138
|
+
nodeSetter.call(carrier, name, value);
|
|
8139
|
+
return;
|
|
8140
|
+
}
|
|
8141
|
+
const headerSetter = carrier.header;
|
|
8142
|
+
if (typeof headerSetter === "function") {
|
|
8143
|
+
const deleter = carrier.delete;
|
|
8144
|
+
if (typeof deleter === "function") {
|
|
8145
|
+
try {
|
|
8146
|
+
deleter.call(carrier, name);
|
|
8147
|
+
} catch {
|
|
8148
|
+
}
|
|
8149
|
+
}
|
|
8150
|
+
const remover = carrier.removeHeader;
|
|
8151
|
+
if (typeof remover === "function") {
|
|
8152
|
+
try {
|
|
8153
|
+
remover.call(carrier, name);
|
|
8154
|
+
} catch {
|
|
8155
|
+
}
|
|
8156
|
+
}
|
|
8157
|
+
headerSetter.call(carrier, name, value);
|
|
8158
|
+
return;
|
|
8159
|
+
}
|
|
8160
|
+
const headerBag = carrier;
|
|
8161
|
+
const lowered = name.toLowerCase();
|
|
8162
|
+
for (const key of Object.keys(headerBag)) {
|
|
8163
|
+
if (key !== name && key.toLowerCase() === lowered) {
|
|
8164
|
+
delete headerBag[key];
|
|
8165
|
+
}
|
|
8166
|
+
}
|
|
8167
|
+
headerBag[name] = value;
|
|
8168
|
+
}
|
|
8169
|
+
function deleteHeader(carrier, name) {
|
|
8170
|
+
const lowered = name.toLowerCase();
|
|
8171
|
+
if (isMutableHeaderTupleArray(carrier)) {
|
|
8172
|
+
for (let i = carrier.length - 1; i >= 0; i--) {
|
|
8173
|
+
if (carrier[i][0].toLowerCase() === lowered) {
|
|
8174
|
+
carrier.splice(i, 1);
|
|
8175
|
+
}
|
|
8176
|
+
}
|
|
8177
|
+
return;
|
|
8178
|
+
}
|
|
8179
|
+
const deleter = carrier.delete;
|
|
8180
|
+
if (typeof deleter === "function") {
|
|
8181
|
+
try {
|
|
8182
|
+
deleter.call(carrier, name);
|
|
8183
|
+
return;
|
|
8184
|
+
} catch {
|
|
8185
|
+
}
|
|
8186
|
+
}
|
|
8187
|
+
const remover = carrier.removeHeader;
|
|
8188
|
+
if (typeof remover === "function") {
|
|
8189
|
+
try {
|
|
8190
|
+
remover.call(carrier, name);
|
|
8191
|
+
return;
|
|
8192
|
+
} catch {
|
|
8193
|
+
}
|
|
7638
8194
|
}
|
|
7639
|
-
|
|
8195
|
+
const headerBag = carrier;
|
|
8196
|
+
for (const key of Object.keys(headerBag)) {
|
|
8197
|
+
if (key.toLowerCase() === lowered) {
|
|
8198
|
+
delete headerBag[key];
|
|
8199
|
+
}
|
|
8200
|
+
}
|
|
8201
|
+
}
|
|
8202
|
+
function _injectIntoCarrier(carrier, args) {
|
|
8203
|
+
const traceFlags = args.propagatedState?.traceFlags;
|
|
8204
|
+
const traceparent = traceFlags ? formatTraceparent(args.traceId, args.spanId, traceFlags) : formatTraceparent(args.traceId, args.spanId);
|
|
8205
|
+
if (traceparent === void 0) {
|
|
8206
|
+
return;
|
|
8207
|
+
}
|
|
8208
|
+
setHeader(carrier, TRACEPARENT_HEADER, traceparent);
|
|
8209
|
+
const tracestate = args.propagatedState?.tracestate;
|
|
8210
|
+
if (tracestate) {
|
|
8211
|
+
setHeader(carrier, TRACESTATE_HEADER, tracestate);
|
|
8212
|
+
}
|
|
8213
|
+
const existing = getHeader(carrier, BAGGAGE_HEADER);
|
|
8214
|
+
const baggageValue = mergeBaggage(existing, args.braintrustParent);
|
|
8215
|
+
if (baggageValue !== void 0) {
|
|
8216
|
+
setHeader(carrier, BAGGAGE_HEADER, baggageValue);
|
|
8217
|
+
} else if (existing !== void 0) {
|
|
8218
|
+
deleteHeader(carrier, BAGGAGE_HEADER);
|
|
8219
|
+
}
|
|
8220
|
+
}
|
|
8221
|
+
function injectTraceContext(carrier, options) {
|
|
8222
|
+
const resolvedCarrier = carrier ?? {};
|
|
8223
|
+
const span = options?.span ?? currentSpan({ state: options?.state });
|
|
8224
|
+
try {
|
|
8225
|
+
return span.inject(resolvedCarrier);
|
|
8226
|
+
} catch (e) {
|
|
8227
|
+
debugLogger.warn(`Error injecting trace context: ${e}`);
|
|
8228
|
+
return resolvedCarrier;
|
|
8229
|
+
}
|
|
8230
|
+
}
|
|
8231
|
+
function extractTraceContextFromHeaders(headers) {
|
|
8232
|
+
if (!headers) {
|
|
8233
|
+
return void 0;
|
|
8234
|
+
}
|
|
8235
|
+
const traceparent = getHeader(headers, TRACEPARENT_HEADER);
|
|
8236
|
+
if (!traceparent || parseTraceparent(traceparent) === void 0) {
|
|
8237
|
+
return void 0;
|
|
8238
|
+
}
|
|
8239
|
+
const context = { [TRACEPARENT_HEADER]: traceparent };
|
|
8240
|
+
const baggageValue = getHeader(headers, BAGGAGE_HEADER);
|
|
8241
|
+
if (baggageValue) {
|
|
8242
|
+
context[BAGGAGE_HEADER] = baggageValue;
|
|
8243
|
+
}
|
|
8244
|
+
const tracestate = getHeader(headers, TRACESTATE_HEADER);
|
|
8245
|
+
if (tracestate) {
|
|
8246
|
+
context[TRACESTATE_HEADER] = tracestate;
|
|
8247
|
+
}
|
|
8248
|
+
return context;
|
|
8249
|
+
}
|
|
8250
|
+
function resolveW3cParent(context, state) {
|
|
8251
|
+
const traceparent = getHeader(context, TRACEPARENT_HEADER);
|
|
8252
|
+
const parsed = traceparent ? parseTraceparent(traceparent) : void 0;
|
|
8253
|
+
if (parsed === void 0) {
|
|
8254
|
+
return { parentSlug: void 0, propagatedState: void 0 };
|
|
8255
|
+
}
|
|
8256
|
+
const { traceId, spanId, traceFlags } = parsed;
|
|
8257
|
+
let braintrustParent = void 0;
|
|
8258
|
+
const baggageValue = getHeader(context, BAGGAGE_HEADER);
|
|
8259
|
+
if (baggageValue) {
|
|
8260
|
+
braintrustParent = parseBaggage(baggageValue)[BRAINTRUST_PARENT_KEY];
|
|
8261
|
+
}
|
|
8262
|
+
if (!braintrustParent) {
|
|
8263
|
+
braintrustParent = currentBraintrustParent(state);
|
|
8264
|
+
}
|
|
8265
|
+
if (!braintrustParent) {
|
|
8266
|
+
debugLogger.warn(
|
|
8267
|
+
"Received traceparent without a braintrust.parent and no active logger/experiment; cannot route the trace. Starting a fresh local span instead."
|
|
8268
|
+
);
|
|
8269
|
+
return { parentSlug: void 0, propagatedState: void 0 };
|
|
8270
|
+
}
|
|
8271
|
+
const parsedParent = braintrustParentToComponents(braintrustParent);
|
|
8272
|
+
if (parsedParent === void 0) {
|
|
8273
|
+
debugLogger.warn(
|
|
8274
|
+
`Invalid braintrust.parent: ${JSON.stringify(braintrustParent)}`
|
|
8275
|
+
);
|
|
8276
|
+
return { parentSlug: void 0, propagatedState: void 0 };
|
|
8277
|
+
}
|
|
8278
|
+
const { objectType, objectId, computeArgs } = parsedParent;
|
|
8279
|
+
const tracestate = getHeader(context, TRACESTATE_HEADER);
|
|
8280
|
+
const slug = new SpanComponentsV4({
|
|
8281
|
+
object_type: objectType,
|
|
8282
|
+
...computeArgs ? { compute_object_metadata_args: computeArgs } : { object_id: objectId },
|
|
8283
|
+
row_id: "bt-propagation",
|
|
8284
|
+
// non-empty to enable span_id/root_span_id
|
|
8285
|
+
span_id: spanId,
|
|
8286
|
+
root_span_id: traceId
|
|
8287
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
8288
|
+
}).toStr();
|
|
8289
|
+
return {
|
|
8290
|
+
parentSlug: slug,
|
|
8291
|
+
propagatedState: { tracestate, traceFlags, braintrustParent }
|
|
8292
|
+
};
|
|
8293
|
+
}
|
|
8294
|
+
function normalizeParent(parent, state) {
|
|
8295
|
+
if (parent && typeof parent === "object") {
|
|
8296
|
+
return resolveW3cParent(parent, state);
|
|
8297
|
+
}
|
|
8298
|
+
return {
|
|
8299
|
+
parentSlug: parent ?? void 0,
|
|
8300
|
+
propagatedState: void 0
|
|
8301
|
+
};
|
|
8302
|
+
}
|
|
8303
|
+
function parentSpanIdsUsable(spanId, rootSpanId) {
|
|
8304
|
+
return Boolean(spanId) && Boolean(rootSpanId);
|
|
7640
8305
|
}
|
|
7641
8306
|
function logError(span, error) {
|
|
7642
8307
|
let errorMessage = "<error>";
|
|
@@ -7844,19 +8509,23 @@ function setFetch(fetch2) {
|
|
|
7844
8509
|
}
|
|
7845
8510
|
function startSpanAndIsLogger(args) {
|
|
7846
8511
|
const state = args?.state ?? _globalState;
|
|
7847
|
-
const parentObject =
|
|
8512
|
+
const { parentObject, propagatedState } = getSpanParentObjectAndPropagatedState({
|
|
7848
8513
|
asyncFlush: args?.asyncFlush,
|
|
7849
8514
|
parent: args?.parent,
|
|
7850
8515
|
state
|
|
7851
8516
|
});
|
|
7852
8517
|
if (parentObject instanceof SpanComponentsV3 || parentObject instanceof SpanComponentsV4) {
|
|
7853
|
-
const parentSpanIds = parentObject.data.row_id
|
|
8518
|
+
const parentSpanIds = parentObject.data.row_id && parentSpanIdsUsable(
|
|
8519
|
+
parentObject.data.span_id,
|
|
8520
|
+
parentObject.data.root_span_id
|
|
8521
|
+
) ? {
|
|
7854
8522
|
spanId: parentObject.data.span_id,
|
|
7855
8523
|
rootSpanId: parentObject.data.root_span_id
|
|
7856
8524
|
} : void 0;
|
|
8525
|
+
const { parent: _ignoredParent, ...spanArgs } = args ?? {};
|
|
7857
8526
|
const span = new SpanImpl({
|
|
7858
8527
|
state,
|
|
7859
|
-
...
|
|
8528
|
+
...spanArgs,
|
|
7860
8529
|
parentObjectType: parentObject.data.object_type,
|
|
7861
8530
|
parentObjectId: new LazyValue(
|
|
7862
8531
|
spanComponentsToObjectIdLambda(state, parentObject)
|
|
@@ -7864,7 +8533,8 @@ function startSpanAndIsLogger(args) {
|
|
|
7864
8533
|
parentComputeObjectMetadataArgs: parentObject.data.compute_object_metadata_args ?? void 0,
|
|
7865
8534
|
parentSpanIds,
|
|
7866
8535
|
propagatedEvent: args?.propagatedEvent ?? // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
7867
|
-
(parentObject.data.propagated_event ?? void 0)
|
|
8536
|
+
(parentObject.data.propagated_event ?? void 0),
|
|
8537
|
+
propagatedState
|
|
7868
8538
|
});
|
|
7869
8539
|
return {
|
|
7870
8540
|
span,
|
|
@@ -8153,11 +8823,12 @@ function validateAndSanitizeExperimentLogFullArgs(event, hasDataset) {
|
|
|
8153
8823
|
var DEFAULT_FETCH_BATCH_SIZE = 1e3;
|
|
8154
8824
|
var MAX_BTQL_ITERATIONS = 1e4;
|
|
8155
8825
|
var ObjectFetcher = class {
|
|
8156
|
-
constructor(objectType, pinnedVersion, mutateRecord, _internal_btql) {
|
|
8826
|
+
constructor(objectType, pinnedVersion, mutateRecord, _internal_btql, _internalBrainstoreRealtime = true) {
|
|
8157
8827
|
this.objectType = objectType;
|
|
8158
8828
|
this.pinnedVersion = pinnedVersion;
|
|
8159
8829
|
this.mutateRecord = mutateRecord;
|
|
8160
8830
|
this._internal_btql = _internal_btql;
|
|
8831
|
+
this._internalBrainstoreRealtime = _internalBrainstoreRealtime;
|
|
8161
8832
|
}
|
|
8162
8833
|
_fetchedData = void 0;
|
|
8163
8834
|
get id() {
|
|
@@ -8216,7 +8887,7 @@ var ObjectFetcher = class {
|
|
|
8216
8887
|
...internalBtqlWithoutReservedQueryKeys
|
|
8217
8888
|
},
|
|
8218
8889
|
use_columnstore: false,
|
|
8219
|
-
brainstore_realtime:
|
|
8890
|
+
brainstore_realtime: this._internalBrainstoreRealtime,
|
|
8220
8891
|
query_source: `js_sdk_object_fetcher_${this.objectType}`,
|
|
8221
8892
|
...this.pinnedVersion !== void 0 ? {
|
|
8222
8893
|
version: this.pinnedVersion
|
|
@@ -8565,6 +9236,15 @@ View complete results in Braintrust or run experiment.summarize() again.`
|
|
|
8565
9236
|
object_id: await this.id
|
|
8566
9237
|
}).toStr();
|
|
8567
9238
|
}
|
|
9239
|
+
/**
|
|
9240
|
+
* Return this experiment's Braintrust parent string (`experiment_id:<id>`) for
|
|
9241
|
+
* the `braintrust.parent` baggage entry, or undefined when it cannot be
|
|
9242
|
+
* determined synchronously.
|
|
9243
|
+
*/
|
|
9244
|
+
_getOtelParent() {
|
|
9245
|
+
const id = this.lazyId.getSync().value;
|
|
9246
|
+
return id ? `experiment_id:${id}` : void 0;
|
|
9247
|
+
}
|
|
8568
9248
|
/**
|
|
8569
9249
|
* Flush any pending rows to the server.
|
|
8570
9250
|
*/
|
|
@@ -8607,7 +9287,8 @@ var ReadonlyExperiment = class extends ObjectFetcher {
|
|
|
8607
9287
|
async *asDataset(options) {
|
|
8608
9288
|
const records = this.fetch(options);
|
|
8609
9289
|
for await (const record of records) {
|
|
8610
|
-
|
|
9290
|
+
const isRoot = record.is_root ?? record.root_span_id === record.span_id;
|
|
9291
|
+
if (!isRoot) {
|
|
8611
9292
|
continue;
|
|
8612
9293
|
}
|
|
8613
9294
|
const { output, expected: expectedRecord, metadata } = record;
|
|
@@ -8669,9 +9350,16 @@ var SpanImpl = class _SpanImpl {
|
|
|
8669
9350
|
_spanId;
|
|
8670
9351
|
_rootSpanId;
|
|
8671
9352
|
_spanParents;
|
|
9353
|
+
// Inbound W3C trace-context state (tracestate + raw traceparent flags) to
|
|
9354
|
+
// forward on outbound propagation. Captured at the span that received it (via
|
|
9355
|
+
// extractTraceContextFromHeaders) and inherited by all subspans, so that any
|
|
9356
|
+
// inject() within the trace re-emits the upstream state unchanged, per the W3C
|
|
9357
|
+
// Trace Context spec. Not interpreted.
|
|
9358
|
+
_propagatedState;
|
|
8672
9359
|
kind = "span";
|
|
8673
9360
|
constructor(args) {
|
|
8674
9361
|
this._state = args.state;
|
|
9362
|
+
this._propagatedState = args.propagatedState;
|
|
8675
9363
|
const spanAttributes = args.spanAttributes ?? {};
|
|
8676
9364
|
const rawEvent = args.event ?? {};
|
|
8677
9365
|
const type = args.type ?? (args.parentSpanIds ? void 0 : args.defaultRootType);
|
|
@@ -8787,7 +9475,7 @@ var SpanImpl = class _SpanImpl {
|
|
|
8787
9475
|
tags: partialRecord.tags,
|
|
8788
9476
|
span_id: this._spanId,
|
|
8789
9477
|
span_parents: this._spanParents,
|
|
8790
|
-
is_root: this.
|
|
9478
|
+
is_root: !this._spanParents || this._spanParents.length === 0,
|
|
8791
9479
|
span_attributes: partialRecord.span_attributes
|
|
8792
9480
|
};
|
|
8793
9481
|
this._state.spanCache.queueWrite(
|
|
@@ -8849,7 +9537,8 @@ var SpanImpl = class _SpanImpl {
|
|
|
8849
9537
|
parentObjectId: this.parentObjectId,
|
|
8850
9538
|
parentComputeObjectMetadataArgs: this.parentComputeObjectMetadataArgs,
|
|
8851
9539
|
parentSpanIds,
|
|
8852
|
-
propagatedEvent: args?.propagatedEvent ?? this.propagatedEvent
|
|
9540
|
+
propagatedEvent: args?.propagatedEvent ?? this.propagatedEvent,
|
|
9541
|
+
propagatedState: this._propagatedState
|
|
8853
9542
|
})
|
|
8854
9543
|
});
|
|
8855
9544
|
}
|
|
@@ -8868,7 +9557,8 @@ var SpanImpl = class _SpanImpl {
|
|
|
8868
9557
|
parentObjectId: this.parentObjectId,
|
|
8869
9558
|
parentComputeObjectMetadataArgs: this.parentComputeObjectMetadataArgs,
|
|
8870
9559
|
parentSpanIds,
|
|
8871
|
-
propagatedEvent: args?.propagatedEvent ?? this.propagatedEvent
|
|
9560
|
+
propagatedEvent: args?.propagatedEvent ?? this.propagatedEvent,
|
|
9561
|
+
propagatedState: this._propagatedState
|
|
8872
9562
|
}),
|
|
8873
9563
|
spanId
|
|
8874
9564
|
});
|
|
@@ -8896,6 +9586,42 @@ var SpanImpl = class _SpanImpl {
|
|
|
8896
9586
|
propagated_event: this.propagatedEvent
|
|
8897
9587
|
}).toStr();
|
|
8898
9588
|
}
|
|
9589
|
+
/**
|
|
9590
|
+
* Return this span's Braintrust parent string (`project_id:<id>`,
|
|
9591
|
+
* `project_name:<name>`, or `experiment_id:<id>`) for the `braintrust.parent`
|
|
9592
|
+
* baggage entry, or undefined when it cannot be determined synchronously.
|
|
9593
|
+
*/
|
|
9594
|
+
_getOtelParent() {
|
|
9595
|
+
if (this.parentObjectType === 2 /* PROJECT_LOGS */) {
|
|
9596
|
+
const id = this.parentComputeObjectMetadataArgs?.project_id || this.parentObjectId.getSync().value;
|
|
9597
|
+
const name = this.parentComputeObjectMetadataArgs?.project_name;
|
|
9598
|
+
if (id) {
|
|
9599
|
+
return `project_id:${id}`;
|
|
9600
|
+
} else if (name) {
|
|
9601
|
+
return `project_name:${name}`;
|
|
9602
|
+
}
|
|
9603
|
+
} else if (this.parentObjectType === 1 /* EXPERIMENT */) {
|
|
9604
|
+
const id = this.parentComputeObjectMetadataArgs?.experiment_id || this.parentObjectId.getSync().value;
|
|
9605
|
+
if (id) {
|
|
9606
|
+
return `experiment_id:${id}`;
|
|
9607
|
+
}
|
|
9608
|
+
}
|
|
9609
|
+
return void 0;
|
|
9610
|
+
}
|
|
9611
|
+
inject(carrier) {
|
|
9612
|
+
const resolvedCarrier = carrier ?? {};
|
|
9613
|
+
try {
|
|
9614
|
+
_injectIntoCarrier(resolvedCarrier, {
|
|
9615
|
+
traceId: this._rootSpanId,
|
|
9616
|
+
spanId: this._spanId,
|
|
9617
|
+
braintrustParent: this._getOtelParent() ?? this._propagatedState?.braintrustParent,
|
|
9618
|
+
propagatedState: this._propagatedState
|
|
9619
|
+
});
|
|
9620
|
+
} catch (e) {
|
|
9621
|
+
debugLogger.warn(`Error injecting trace context: ${e}`);
|
|
9622
|
+
}
|
|
9623
|
+
return resolvedCarrier;
|
|
9624
|
+
}
|
|
8899
9625
|
async permalink() {
|
|
8900
9626
|
return await permalink(await this.export(), {
|
|
8901
9627
|
state: this._state
|
|
@@ -9031,6 +9757,7 @@ var Dataset2 = class extends ObjectFetcher {
|
|
|
9031
9757
|
_internal_btql
|
|
9032
9758
|
);
|
|
9033
9759
|
this.state = state;
|
|
9760
|
+
void this.__braintrust_dataset_marker;
|
|
9034
9761
|
this.lazyMetadata = lazyMetadata;
|
|
9035
9762
|
this.lazyPinnedVersion = pinState?.lazyPinnedVersion;
|
|
9036
9763
|
this.pinnedEnvironment = pinState?.pinnedEnvironment;
|
|
@@ -9548,6 +10275,7 @@ var Prompt2 = class _Prompt {
|
|
|
9548
10275
|
this.metadata = metadata;
|
|
9549
10276
|
this.defaults = defaults;
|
|
9550
10277
|
this.noTrace = noTrace;
|
|
10278
|
+
void this.__braintrust_prompt_marker;
|
|
9551
10279
|
}
|
|
9552
10280
|
parsedPromptData;
|
|
9553
10281
|
hasParsedPromptData = false;
|
|
@@ -9784,6 +10512,7 @@ var Prompt2 = class _Prompt {
|
|
|
9784
10512
|
var RemoteEvalParameters = class {
|
|
9785
10513
|
constructor(metadata) {
|
|
9786
10514
|
this.metadata = metadata;
|
|
10515
|
+
void this.__braintrust_parameters_marker;
|
|
9787
10516
|
}
|
|
9788
10517
|
__braintrust_parameters_marker = true;
|
|
9789
10518
|
get id() {
|
|
@@ -9920,6 +10649,7 @@ var _exportsForTestingOnly = {
|
|
|
9920
10649
|
isAsyncGeneratorFunction,
|
|
9921
10650
|
resetIdGenStateForTests,
|
|
9922
10651
|
validateTags,
|
|
10652
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
9923
10653
|
isomorph: isomorph_default
|
|
9924
10654
|
// Expose isomorph for build type detection
|
|
9925
10655
|
};
|
|
@@ -10748,6 +11478,22 @@ function runStreamingCompletionHook(args) {
|
|
|
10748
11478
|
);
|
|
10749
11479
|
}
|
|
10750
11480
|
}
|
|
11481
|
+
function runStreamingErrorHook(args) {
|
|
11482
|
+
if (!args.config.onError) {
|
|
11483
|
+
return;
|
|
11484
|
+
}
|
|
11485
|
+
try {
|
|
11486
|
+
args.config.onError({
|
|
11487
|
+
channelName: args.channelName,
|
|
11488
|
+
error: args.error,
|
|
11489
|
+
event: args.event,
|
|
11490
|
+
span: args.span,
|
|
11491
|
+
startTime: args.startTime
|
|
11492
|
+
});
|
|
11493
|
+
} catch (error) {
|
|
11494
|
+
debugLogger.error(`Error in onError hook for ${args.channelName}:`, error);
|
|
11495
|
+
}
|
|
11496
|
+
}
|
|
10751
11497
|
function traceAsyncChannel(channel2, config) {
|
|
10752
11498
|
const tracingChannel2 = channel2.tracingChannel();
|
|
10753
11499
|
const states = /* @__PURE__ */ new WeakMap();
|
|
@@ -10909,6 +11655,14 @@ function traceStreamingChannel(channel2, config) {
|
|
|
10909
11655
|
}
|
|
10910
11656
|
},
|
|
10911
11657
|
onError: (error) => {
|
|
11658
|
+
runStreamingErrorHook({
|
|
11659
|
+
channelName,
|
|
11660
|
+
config,
|
|
11661
|
+
error,
|
|
11662
|
+
event: asyncEndEvent,
|
|
11663
|
+
span,
|
|
11664
|
+
startTime
|
|
11665
|
+
});
|
|
10912
11666
|
span.log({
|
|
10913
11667
|
error: error.message
|
|
10914
11668
|
});
|
|
@@ -10966,6 +11720,17 @@ function traceStreamingChannel(channel2, config) {
|
|
|
10966
11720
|
}
|
|
10967
11721
|
},
|
|
10968
11722
|
error: (event) => {
|
|
11723
|
+
const spanData = states.get(event);
|
|
11724
|
+
if (spanData) {
|
|
11725
|
+
runStreamingErrorHook({
|
|
11726
|
+
channelName,
|
|
11727
|
+
config,
|
|
11728
|
+
error: event.error,
|
|
11729
|
+
event,
|
|
11730
|
+
span: spanData.span,
|
|
11731
|
+
startTime: spanData.startTime
|
|
11732
|
+
});
|
|
11733
|
+
}
|
|
10969
11734
|
logErrorAndEnd(states, event);
|
|
10970
11735
|
}
|
|
10971
11736
|
};
|
|
@@ -13328,14 +14093,45 @@ function serializeAISDKToolsForLogging(tools) {
|
|
|
13328
14093
|
return serialized;
|
|
13329
14094
|
}
|
|
13330
14095
|
|
|
14096
|
+
// src/vendor-sdk-types/ai-sdk-v7-telemetry.ts
|
|
14097
|
+
var BRAINTRUST_AI_SDK_V7_OPERATION_KEY = /* @__PURE__ */ Symbol.for(
|
|
14098
|
+
"braintrust.ai-sdk.v7.telemetry-operation-key"
|
|
14099
|
+
);
|
|
14100
|
+
|
|
14101
|
+
// src/wrappers/ai-sdk/workflow-agent-context.ts
|
|
14102
|
+
var workflowAgentWrapperSpans = /* @__PURE__ */ new Map();
|
|
14103
|
+
function registerWorkflowAgentWrapperSpan(span) {
|
|
14104
|
+
if (span.spanId) {
|
|
14105
|
+
workflowAgentWrapperSpans.set(span.spanId, span);
|
|
14106
|
+
}
|
|
14107
|
+
}
|
|
14108
|
+
function unregisterWorkflowAgentWrapperSpan(span) {
|
|
14109
|
+
if (span.spanId) {
|
|
14110
|
+
workflowAgentWrapperSpans.delete(span.spanId);
|
|
14111
|
+
}
|
|
14112
|
+
}
|
|
14113
|
+
function currentWorkflowAgentWrapperSpan() {
|
|
14114
|
+
const parentSpanIds = _internalGetGlobalState().contextManager.getParentSpanIds()?.spanParents ?? [];
|
|
14115
|
+
for (const parentSpanId of parentSpanIds) {
|
|
14116
|
+
const span = workflowAgentWrapperSpans.get(parentSpanId);
|
|
14117
|
+
if (span) {
|
|
14118
|
+
return span;
|
|
14119
|
+
}
|
|
14120
|
+
}
|
|
14121
|
+
return void 0;
|
|
14122
|
+
}
|
|
14123
|
+
|
|
13331
14124
|
// src/wrappers/ai-sdk/telemetry.ts
|
|
13332
14125
|
function braintrustAISDKTelemetry() {
|
|
13333
14126
|
const operations = /* @__PURE__ */ new Map();
|
|
14127
|
+
const operationKeysByCallId = /* @__PURE__ */ new Map();
|
|
14128
|
+
const workflowOperationKeyStore = isomorph_default.newAsyncLocalStorage();
|
|
13334
14129
|
const modelSpans = /* @__PURE__ */ new Map();
|
|
13335
14130
|
const objectSpans = /* @__PURE__ */ new Map();
|
|
13336
14131
|
const embedSpans = /* @__PURE__ */ new Map();
|
|
13337
14132
|
const rerankSpans = /* @__PURE__ */ new Map();
|
|
13338
14133
|
const toolSpans = /* @__PURE__ */ new Map();
|
|
14134
|
+
let workflowAgentOperationCounter = 0;
|
|
13339
14135
|
const runSafely = (name, callback) => {
|
|
13340
14136
|
try {
|
|
13341
14137
|
callback();
|
|
@@ -13343,42 +14139,333 @@ function braintrustAISDKTelemetry() {
|
|
|
13343
14139
|
console.error(`Error in Braintrust AI SDK telemetry ${name}:`, error);
|
|
13344
14140
|
}
|
|
13345
14141
|
};
|
|
13346
|
-
const startChildSpan = (
|
|
13347
|
-
const parent = operations.get(
|
|
14142
|
+
const startChildSpan = (operationKey, name, type, event) => {
|
|
14143
|
+
const parent = operations.get(operationKey)?.span;
|
|
13348
14144
|
const spanArgs = {
|
|
13349
14145
|
name,
|
|
13350
14146
|
spanAttributes: { type },
|
|
13351
14147
|
...event ? { event } : {}
|
|
13352
14148
|
};
|
|
13353
14149
|
const span = parent ? parent.startSpan(spanArgs) : startSpan(spanArgs);
|
|
13354
|
-
const state = operations.get(
|
|
14150
|
+
const state = operations.get(operationKey);
|
|
13355
14151
|
if (state && type === "llm" /* LLM */) {
|
|
13356
14152
|
state.hadModelChild = true;
|
|
13357
14153
|
}
|
|
13358
14154
|
return span;
|
|
13359
14155
|
};
|
|
14156
|
+
const registerOperation = (state) => {
|
|
14157
|
+
operations.set(state.operationKey, state);
|
|
14158
|
+
const keys = operationKeysByCallId.get(state.callId) ?? [];
|
|
14159
|
+
keys.push(state.operationKey);
|
|
14160
|
+
operationKeysByCallId.set(state.callId, keys);
|
|
14161
|
+
};
|
|
14162
|
+
const deleteOperation = (operationKey) => {
|
|
14163
|
+
const state = operations.get(operationKey);
|
|
14164
|
+
if (!state) {
|
|
14165
|
+
return;
|
|
14166
|
+
}
|
|
14167
|
+
operations.delete(operationKey);
|
|
14168
|
+
if (workflowOperationKeyStore.getStore() === operationKey) {
|
|
14169
|
+
workflowOperationKeyStore.enterWith(void 0);
|
|
14170
|
+
}
|
|
14171
|
+
const keys = operationKeysByCallId.get(state.callId);
|
|
14172
|
+
if (!keys) {
|
|
14173
|
+
return;
|
|
14174
|
+
}
|
|
14175
|
+
const index = keys.indexOf(operationKey);
|
|
14176
|
+
if (index >= 0) {
|
|
14177
|
+
keys.splice(index, 1);
|
|
14178
|
+
}
|
|
14179
|
+
if (keys.length === 0) {
|
|
14180
|
+
operationKeysByCallId.delete(state.callId);
|
|
14181
|
+
}
|
|
14182
|
+
};
|
|
14183
|
+
const explicitOperationKey = (event) => {
|
|
14184
|
+
if (!isObject(event)) {
|
|
14185
|
+
return void 0;
|
|
14186
|
+
}
|
|
14187
|
+
const key = event[BRAINTRUST_AI_SDK_V7_OPERATION_KEY];
|
|
14188
|
+
return typeof key === "string" ? key : void 0;
|
|
14189
|
+
};
|
|
14190
|
+
const createOperationKey = (event, operationName) => {
|
|
14191
|
+
const explicit = explicitOperationKey(event);
|
|
14192
|
+
if (explicit) {
|
|
14193
|
+
return explicit;
|
|
14194
|
+
}
|
|
14195
|
+
if (operationName === "WorkflowAgent.stream") {
|
|
14196
|
+
workflowAgentOperationCounter += 1;
|
|
14197
|
+
return `${event.callId}:${workflowAgentOperationCounter}`;
|
|
14198
|
+
}
|
|
14199
|
+
return event.callId;
|
|
14200
|
+
};
|
|
14201
|
+
const operationKeyForCallId = (callId, mode = "active") => {
|
|
14202
|
+
const keys = operationKeysByCallId.get(callId);
|
|
14203
|
+
if (!keys || keys.length === 0) {
|
|
14204
|
+
return operations.has(callId) ? callId : void 0;
|
|
14205
|
+
}
|
|
14206
|
+
if (keys.length === 1) {
|
|
14207
|
+
return keys[0];
|
|
14208
|
+
}
|
|
14209
|
+
const wrapperSpan = currentWorkflowAgentWrapperSpan();
|
|
14210
|
+
if (wrapperSpan?.spanId) {
|
|
14211
|
+
const key = keys.find(
|
|
14212
|
+
(candidate) => operations.get(candidate)?.span.spanId === wrapperSpan.spanId
|
|
14213
|
+
);
|
|
14214
|
+
if (key) {
|
|
14215
|
+
return key;
|
|
14216
|
+
}
|
|
14217
|
+
}
|
|
14218
|
+
const workflowOperationKey = workflowOperationKeyStore.getStore();
|
|
14219
|
+
if (workflowOperationKey && keys.includes(workflowOperationKey)) {
|
|
14220
|
+
return workflowOperationKey;
|
|
14221
|
+
}
|
|
14222
|
+
if (callId === "workflow-agent") {
|
|
14223
|
+
return void 0;
|
|
14224
|
+
}
|
|
14225
|
+
return mode === "finish" ? keys[0] : keys[keys.length - 1];
|
|
14226
|
+
};
|
|
14227
|
+
const operationKeyFromEvent = (event, mode = "active") => {
|
|
14228
|
+
const explicit = explicitOperationKey(event);
|
|
14229
|
+
if (explicit && operations.has(explicit)) {
|
|
14230
|
+
return explicit;
|
|
14231
|
+
}
|
|
14232
|
+
if (isObject(event)) {
|
|
14233
|
+
const callId = event.callId;
|
|
14234
|
+
if (typeof callId === "string") {
|
|
14235
|
+
const operationKey = operationKeyForCallId(callId, mode);
|
|
14236
|
+
if (operationKey) {
|
|
14237
|
+
return operationKey;
|
|
14238
|
+
}
|
|
14239
|
+
const workflowOperationKey2 = workflowOperationKeyStore.getStore();
|
|
14240
|
+
if (workflowOperationKey2 && operations.has(workflowOperationKey2)) {
|
|
14241
|
+
return workflowOperationKey2;
|
|
14242
|
+
}
|
|
14243
|
+
return callId === "workflow-agent" ? void 0 : callId;
|
|
14244
|
+
}
|
|
14245
|
+
}
|
|
14246
|
+
const workflowOperationKey = workflowOperationKeyStore.getStore();
|
|
14247
|
+
if (workflowOperationKey && operations.has(workflowOperationKey)) {
|
|
14248
|
+
return workflowOperationKey;
|
|
14249
|
+
}
|
|
14250
|
+
const wrapperSpan = currentWorkflowAgentWrapperSpan();
|
|
14251
|
+
if (wrapperSpan?.spanId) {
|
|
14252
|
+
for (const [operationKey, state] of operations) {
|
|
14253
|
+
if (state.operationName === "WorkflowAgent.stream" && state.span.spanId === wrapperSpan.spanId) {
|
|
14254
|
+
return operationKey;
|
|
14255
|
+
}
|
|
14256
|
+
}
|
|
14257
|
+
}
|
|
14258
|
+
const workflowAgentKeys = operationKeysByCallId.get("workflow-agent");
|
|
14259
|
+
if (workflowAgentKeys?.length === 1) {
|
|
14260
|
+
return workflowAgentKeys[0];
|
|
14261
|
+
}
|
|
14262
|
+
if (operations.size === 1) {
|
|
14263
|
+
return operations.keys().next().value;
|
|
14264
|
+
}
|
|
14265
|
+
return void 0;
|
|
14266
|
+
};
|
|
14267
|
+
const closeOpenChildSpans = (operationKey, error) => {
|
|
14268
|
+
const openModelSpans = modelSpans.get(operationKey);
|
|
14269
|
+
if (openModelSpans) {
|
|
14270
|
+
for (const span of openModelSpans) {
|
|
14271
|
+
if (error !== void 0) {
|
|
14272
|
+
logError(span, error);
|
|
14273
|
+
}
|
|
14274
|
+
span.end();
|
|
14275
|
+
}
|
|
14276
|
+
modelSpans.delete(operationKey);
|
|
14277
|
+
}
|
|
14278
|
+
const openObjectSpan = objectSpans.get(operationKey);
|
|
14279
|
+
if (openObjectSpan) {
|
|
14280
|
+
if (error !== void 0) {
|
|
14281
|
+
logError(openObjectSpan, error);
|
|
14282
|
+
}
|
|
14283
|
+
openObjectSpan.end();
|
|
14284
|
+
objectSpans.delete(operationKey);
|
|
14285
|
+
}
|
|
14286
|
+
for (const [embedCallId, embedState] of embedSpans) {
|
|
14287
|
+
if (embedState.operationKey === operationKey) {
|
|
14288
|
+
if (error !== void 0) {
|
|
14289
|
+
logError(embedState.span, error);
|
|
14290
|
+
}
|
|
14291
|
+
embedState.span.end();
|
|
14292
|
+
embedSpans.delete(embedCallId);
|
|
14293
|
+
}
|
|
14294
|
+
}
|
|
14295
|
+
const openRerankSpan = rerankSpans.get(operationKey);
|
|
14296
|
+
if (openRerankSpan) {
|
|
14297
|
+
if (error !== void 0) {
|
|
14298
|
+
logError(openRerankSpan, error);
|
|
14299
|
+
}
|
|
14300
|
+
openRerankSpan.end();
|
|
14301
|
+
rerankSpans.delete(operationKey);
|
|
14302
|
+
}
|
|
14303
|
+
for (const [toolCallId, toolState] of toolSpans) {
|
|
14304
|
+
if (toolState.operationKey === operationKey) {
|
|
14305
|
+
if (error !== void 0) {
|
|
14306
|
+
logError(toolState.span, error);
|
|
14307
|
+
}
|
|
14308
|
+
toolState.span.end();
|
|
14309
|
+
toolSpans.delete(toolCallId);
|
|
14310
|
+
}
|
|
14311
|
+
}
|
|
14312
|
+
};
|
|
14313
|
+
const abortReasonFromEvent = (event) => {
|
|
14314
|
+
if (isObject(event)) {
|
|
14315
|
+
const abortEvent = event;
|
|
14316
|
+
if (abortEvent.error !== void 0) {
|
|
14317
|
+
return abortEvent.error;
|
|
14318
|
+
}
|
|
14319
|
+
if (abortEvent.reason !== void 0) {
|
|
14320
|
+
return abortEvent.reason;
|
|
14321
|
+
}
|
|
14322
|
+
}
|
|
14323
|
+
return new Error("AI SDK operation aborted");
|
|
14324
|
+
};
|
|
14325
|
+
const shouldSkipTelemetryChildren = (state) => state?.operationName === "WorkflowAgent.stream" && !state.ownsSpan;
|
|
14326
|
+
const onObjectStepEnd = (event) => {
|
|
14327
|
+
runSafely("onObjectStepEnd", () => {
|
|
14328
|
+
const operationKey = operationKeyFromEvent(event);
|
|
14329
|
+
const span = operationKey ? objectSpans.get(operationKey) : void 0;
|
|
14330
|
+
if (!operationKey || !span) {
|
|
14331
|
+
return;
|
|
14332
|
+
}
|
|
14333
|
+
const result = {
|
|
14334
|
+
...event,
|
|
14335
|
+
text: event.objectText
|
|
14336
|
+
};
|
|
14337
|
+
span.log({
|
|
14338
|
+
...shouldRecordOutputs(event) ? {
|
|
14339
|
+
output: processAISDKOutput(result, DEFAULT_DENY_OUTPUT_PATHS)
|
|
14340
|
+
} : {},
|
|
14341
|
+
metrics: extractTokenMetrics(result)
|
|
14342
|
+
});
|
|
14343
|
+
span.end();
|
|
14344
|
+
objectSpans.delete(operationKey);
|
|
14345
|
+
});
|
|
14346
|
+
};
|
|
14347
|
+
const onEmbedEnd = (event) => {
|
|
14348
|
+
runSafely("onEmbedEnd", () => {
|
|
14349
|
+
const state = embedSpans.get(event.embedCallId);
|
|
14350
|
+
if (!state) {
|
|
14351
|
+
return;
|
|
14352
|
+
}
|
|
14353
|
+
const result = {
|
|
14354
|
+
...event,
|
|
14355
|
+
embeddings: event.embeddings
|
|
14356
|
+
};
|
|
14357
|
+
state.span.log({
|
|
14358
|
+
...shouldRecordOutputs(event) ? {
|
|
14359
|
+
output: processAISDKEmbeddingOutput(
|
|
14360
|
+
result,
|
|
14361
|
+
DEFAULT_DENY_OUTPUT_PATHS
|
|
14362
|
+
)
|
|
14363
|
+
} : {},
|
|
14364
|
+
metrics: extractTokenMetrics(result)
|
|
14365
|
+
});
|
|
14366
|
+
state.span.end();
|
|
14367
|
+
embedSpans.delete(event.embedCallId);
|
|
14368
|
+
});
|
|
14369
|
+
};
|
|
14370
|
+
const onRerankEnd = (event) => {
|
|
14371
|
+
runSafely("onRerankEnd", () => {
|
|
14372
|
+
const operationKey = operationKeyFromEvent(event);
|
|
14373
|
+
const span = operationKey ? rerankSpans.get(operationKey) : void 0;
|
|
14374
|
+
if (!operationKey || !span) {
|
|
14375
|
+
return;
|
|
14376
|
+
}
|
|
14377
|
+
const result = {
|
|
14378
|
+
ranking: event.ranking?.map((entry) => ({
|
|
14379
|
+
originalIndex: entry.index,
|
|
14380
|
+
score: entry.relevanceScore
|
|
14381
|
+
}))
|
|
14382
|
+
};
|
|
14383
|
+
span.log({
|
|
14384
|
+
...shouldRecordOutputs(event) ? {
|
|
14385
|
+
output: processAISDKRerankOutput(
|
|
14386
|
+
result,
|
|
14387
|
+
DEFAULT_DENY_OUTPUT_PATHS
|
|
14388
|
+
)
|
|
14389
|
+
} : {}
|
|
14390
|
+
});
|
|
14391
|
+
span.end();
|
|
14392
|
+
rerankSpans.delete(operationKey);
|
|
14393
|
+
});
|
|
14394
|
+
};
|
|
14395
|
+
const onEnd = (event) => {
|
|
14396
|
+
runSafely("onEnd", () => {
|
|
14397
|
+
const operationKey = operationKeyFromEvent(event, "finish");
|
|
14398
|
+
const state = operationKey ? operations.get(operationKey) : void 0;
|
|
14399
|
+
if (!state) {
|
|
14400
|
+
return;
|
|
14401
|
+
}
|
|
14402
|
+
if (!state.ownsSpan) {
|
|
14403
|
+
deleteOperation(state.operationKey);
|
|
14404
|
+
return;
|
|
14405
|
+
}
|
|
14406
|
+
const result = finishResult(event, state.operationName);
|
|
14407
|
+
const metrics = state.hadModelChild ? {} : extractTokenMetrics(result);
|
|
14408
|
+
const timeToFirstToken = state.operationName === "WorkflowAgent.stream" ? void 0 : extractTimeToFirstToken(result, state);
|
|
14409
|
+
if (timeToFirstToken !== void 0) {
|
|
14410
|
+
metrics.time_to_first_token = timeToFirstToken;
|
|
14411
|
+
}
|
|
14412
|
+
state.span.log({
|
|
14413
|
+
...shouldRecordOutputs(event) ? {
|
|
14414
|
+
output: finishOutput(result, state.operationName)
|
|
14415
|
+
} : {},
|
|
14416
|
+
metrics
|
|
14417
|
+
});
|
|
14418
|
+
state.span.end();
|
|
14419
|
+
deleteOperation(state.operationKey);
|
|
14420
|
+
});
|
|
14421
|
+
};
|
|
13360
14422
|
return {
|
|
13361
14423
|
onStart(event) {
|
|
13362
14424
|
runSafely("onStart", () => {
|
|
13363
14425
|
const operationName = operationNameFromId(event.operationId);
|
|
13364
|
-
const
|
|
14426
|
+
const workflowAgent = operationName === "WorkflowAgent.stream";
|
|
14427
|
+
const wrapperSpan = workflowAgent ? currentWorkflowAgentWrapperSpan() : void 0;
|
|
14428
|
+
const ownsSpan = !wrapperSpan;
|
|
14429
|
+
const span = ownsSpan ? startSpan({
|
|
13365
14430
|
name: operationName,
|
|
13366
14431
|
spanAttributes: { type: "function" /* FUNCTION */ }
|
|
13367
|
-
});
|
|
13368
|
-
|
|
14432
|
+
}) : wrapperSpan;
|
|
14433
|
+
const operationKey = createOperationKey(event, operationName);
|
|
14434
|
+
registerOperation({
|
|
14435
|
+
callId: event.callId,
|
|
13369
14436
|
hadModelChild: false,
|
|
14437
|
+
loggedInput: false,
|
|
13370
14438
|
operationName,
|
|
14439
|
+
operationKey,
|
|
14440
|
+
ownsSpan,
|
|
13371
14441
|
span,
|
|
13372
14442
|
startTime: getCurrentUnixTimestamp()
|
|
13373
14443
|
});
|
|
13374
|
-
|
|
14444
|
+
if (!ownsSpan) {
|
|
14445
|
+
return;
|
|
14446
|
+
}
|
|
14447
|
+
if (workflowAgent) {
|
|
14448
|
+
workflowOperationKeyStore.enterWith(operationKey);
|
|
14449
|
+
}
|
|
14450
|
+
let metadata = metadataFromEvent(event);
|
|
13375
14451
|
const logPayload = { metadata };
|
|
14452
|
+
const workflowAgentCallInput = workflowAgent ? operationInput(event, operationName) : void 0;
|
|
14453
|
+
if (workflowAgentCallInput) {
|
|
14454
|
+
metadata = {
|
|
14455
|
+
...metadata,
|
|
14456
|
+
...extractWorkflowMetadataFromCallParams(workflowAgentCallInput)
|
|
14457
|
+
};
|
|
14458
|
+
logPayload.metadata = metadata;
|
|
14459
|
+
}
|
|
13376
14460
|
if (shouldRecordInputs(event)) {
|
|
13377
|
-
const
|
|
13378
|
-
|
|
13379
|
-
);
|
|
14461
|
+
const callInput = workflowAgentCallInput ?? operationInput(event, operationName);
|
|
14462
|
+
const { input, outputPromise } = workflowAgent ? processAISDKWorkflowAgentCallInput(callInput) : processAISDKCallInput(callInput);
|
|
13380
14463
|
logPayload.input = input;
|
|
13381
|
-
|
|
14464
|
+
const state = operations.get(operationKey);
|
|
14465
|
+
if (state) {
|
|
14466
|
+
state.loggedInput = hasPromptLikeInput(input);
|
|
14467
|
+
}
|
|
14468
|
+
if (outputPromise && !workflowAgent && input && typeof input === "object") {
|
|
13382
14469
|
outputPromise.then((resolvedData) => {
|
|
13383
14470
|
span.log({
|
|
13384
14471
|
input: {
|
|
@@ -13395,41 +14482,67 @@ function braintrustAISDKTelemetry() {
|
|
|
13395
14482
|
},
|
|
13396
14483
|
onLanguageModelCallStart(event) {
|
|
13397
14484
|
runSafely("onLanguageModelCallStart", () => {
|
|
13398
|
-
const
|
|
13399
|
-
const
|
|
13400
|
-
if (
|
|
14485
|
+
const operationKey = operationKeyFromEvent(event);
|
|
14486
|
+
const state = operationKey ? operations.get(operationKey) : void 0;
|
|
14487
|
+
if (shouldSkipTelemetryChildren(state)) {
|
|
14488
|
+
return;
|
|
14489
|
+
}
|
|
14490
|
+
const operationName = state?.operationName ?? "generateText";
|
|
14491
|
+
const callInput = operationInput(event, operationName);
|
|
14492
|
+
const workflowAgent = operationName === "WorkflowAgent.stream";
|
|
14493
|
+
const processedInput = shouldRecordInputs(event) && workflowAgent ? processAISDKWorkflowAgentModelCallInput(callInput).input : shouldRecordInputs(event) ? processAISDKCallInput(callInput).input : void 0;
|
|
14494
|
+
if (workflowAgent && state?.ownsSpan && !state.loggedInput && hasPromptLikeInput(processedInput)) {
|
|
14495
|
+
state.span.log({
|
|
14496
|
+
input: processedInput,
|
|
14497
|
+
metadata: {
|
|
14498
|
+
...metadataFromEvent(event),
|
|
14499
|
+
...extractWorkflowMetadataFromCallParams(callInput)
|
|
14500
|
+
}
|
|
14501
|
+
});
|
|
14502
|
+
state.loggedInput = true;
|
|
14503
|
+
}
|
|
14504
|
+
const openSpans = operationKey ? modelSpans.get(operationKey) : void 0;
|
|
14505
|
+
if (operationKey && openSpans) {
|
|
13401
14506
|
for (const span2 of openSpans) {
|
|
13402
14507
|
span2.end();
|
|
13403
14508
|
}
|
|
13404
|
-
modelSpans.delete(
|
|
14509
|
+
modelSpans.delete(operationKey);
|
|
13405
14510
|
}
|
|
13406
14511
|
const span = startChildSpan(
|
|
13407
|
-
event.callId,
|
|
13408
|
-
|
|
14512
|
+
operationKey ?? event.callId,
|
|
14513
|
+
operationName === "streamText" ? "doStream" : "doGenerate",
|
|
13409
14514
|
"llm" /* LLM */,
|
|
13410
14515
|
{
|
|
13411
14516
|
...shouldRecordInputs(event) ? {
|
|
13412
|
-
input:
|
|
13413
|
-
operationInput(
|
|
13414
|
-
event,
|
|
13415
|
-
state?.operationName ?? "generateText"
|
|
13416
|
-
)
|
|
13417
|
-
).input
|
|
14517
|
+
input: processedInput
|
|
13418
14518
|
} : {},
|
|
13419
|
-
metadata:
|
|
14519
|
+
metadata: workflowAgent ? {
|
|
14520
|
+
...metadataFromEvent(event),
|
|
14521
|
+
...extractWorkflowMetadataFromCallParams(callInput)
|
|
14522
|
+
} : metadataFromEvent(event)
|
|
13420
14523
|
}
|
|
13421
14524
|
);
|
|
13422
|
-
const
|
|
14525
|
+
const spanKey = operationKey ?? event.callId;
|
|
14526
|
+
const spans = modelSpans.get(spanKey) ?? [];
|
|
13423
14527
|
spans.push(span);
|
|
13424
|
-
modelSpans.set(
|
|
14528
|
+
modelSpans.set(spanKey, spans);
|
|
13425
14529
|
});
|
|
13426
14530
|
},
|
|
13427
14531
|
onLanguageModelCallEnd(event) {
|
|
13428
14532
|
runSafely("onLanguageModelCallEnd", () => {
|
|
13429
|
-
const
|
|
14533
|
+
const operationKey = operationKeyFromEvent(event);
|
|
14534
|
+
const state = operationKey ? operations.get(operationKey) : void 0;
|
|
14535
|
+
if (shouldSkipTelemetryChildren(state)) {
|
|
14536
|
+
return;
|
|
14537
|
+
}
|
|
14538
|
+
const span = operationKey ? shiftModelSpan(modelSpans, operationKey) : void 0;
|
|
13430
14539
|
if (!span) {
|
|
13431
14540
|
return;
|
|
13432
14541
|
}
|
|
14542
|
+
const timeToFirstOutputMs = safePerformance(event)?.timeToFirstOutputMs;
|
|
14543
|
+
if (state?.operationName === "streamText" && state.firstChunkTime === void 0 && typeof timeToFirstOutputMs === "number") {
|
|
14544
|
+
state.firstChunkTime = state.startTime + timeToFirstOutputMs / 1e3;
|
|
14545
|
+
}
|
|
13433
14546
|
const result = {
|
|
13434
14547
|
...event,
|
|
13435
14548
|
response: event.responseId ? { id: event.responseId } : void 0
|
|
@@ -13445,14 +14558,18 @@ function braintrustAISDKTelemetry() {
|
|
|
13445
14558
|
},
|
|
13446
14559
|
onObjectStepStart(event) {
|
|
13447
14560
|
runSafely("onObjectStepStart", () => {
|
|
13448
|
-
const
|
|
13449
|
-
const
|
|
13450
|
-
if (
|
|
14561
|
+
const operationKey = operationKeyFromEvent(event);
|
|
14562
|
+
const state = operationKey ? operations.get(operationKey) : void 0;
|
|
14563
|
+
if (shouldSkipTelemetryChildren(state)) {
|
|
14564
|
+
return;
|
|
14565
|
+
}
|
|
14566
|
+
const openSpan = operationKey ? objectSpans.get(operationKey) : void 0;
|
|
14567
|
+
if (operationKey && openSpan) {
|
|
13451
14568
|
openSpan.end();
|
|
13452
|
-
objectSpans.delete(
|
|
14569
|
+
objectSpans.delete(operationKey);
|
|
13453
14570
|
}
|
|
13454
14571
|
const span = startChildSpan(
|
|
13455
|
-
event.callId,
|
|
14572
|
+
operationKey ?? event.callId,
|
|
13456
14573
|
state?.operationName === "streamObject" ? "doStream" : "doGenerate",
|
|
13457
14574
|
"llm" /* LLM */,
|
|
13458
14575
|
{
|
|
@@ -13464,40 +14581,25 @@ function braintrustAISDKTelemetry() {
|
|
|
13464
14581
|
metadata: metadataFromEvent(event)
|
|
13465
14582
|
}
|
|
13466
14583
|
);
|
|
13467
|
-
objectSpans.set(event.callId, span);
|
|
13468
|
-
});
|
|
13469
|
-
},
|
|
13470
|
-
onObjectStepFinish(event) {
|
|
13471
|
-
runSafely("onObjectStepFinish", () => {
|
|
13472
|
-
const span = objectSpans.get(event.callId);
|
|
13473
|
-
if (!span) {
|
|
13474
|
-
return;
|
|
13475
|
-
}
|
|
13476
|
-
const result = {
|
|
13477
|
-
...event,
|
|
13478
|
-
text: event.objectText
|
|
13479
|
-
};
|
|
13480
|
-
span.log({
|
|
13481
|
-
...shouldRecordOutputs(event) ? {
|
|
13482
|
-
output: processAISDKOutput(result, DEFAULT_DENY_OUTPUT_PATHS)
|
|
13483
|
-
} : {},
|
|
13484
|
-
metrics: extractTokenMetrics(result)
|
|
13485
|
-
});
|
|
13486
|
-
span.end();
|
|
13487
|
-
objectSpans.delete(event.callId);
|
|
14584
|
+
objectSpans.set(operationKey ?? event.callId, span);
|
|
13488
14585
|
});
|
|
13489
14586
|
},
|
|
14587
|
+
onObjectStepEnd,
|
|
13490
14588
|
onEmbedStart(event) {
|
|
13491
14589
|
runSafely("onEmbedStart", () => {
|
|
13492
|
-
const
|
|
14590
|
+
const operationKey = operationKeyFromEvent(event);
|
|
14591
|
+
const state = operationKey ? operations.get(operationKey) : void 0;
|
|
14592
|
+
if (shouldSkipTelemetryChildren(state)) {
|
|
14593
|
+
return;
|
|
14594
|
+
}
|
|
13493
14595
|
for (const [embedCallId, embedState] of embedSpans) {
|
|
13494
|
-
if (embedState.
|
|
14596
|
+
if (embedState.operationKey === operationKey && (state?.operationName === "embed" || embedState.values === event.values)) {
|
|
13495
14597
|
embedState.span.end();
|
|
13496
14598
|
embedSpans.delete(embedCallId);
|
|
13497
14599
|
}
|
|
13498
14600
|
}
|
|
13499
14601
|
const span = startChildSpan(
|
|
13500
|
-
event.callId,
|
|
14602
|
+
operationKey ?? event.callId,
|
|
13501
14603
|
"doEmbed",
|
|
13502
14604
|
"llm" /* LLM */,
|
|
13503
14605
|
{
|
|
@@ -13510,44 +14612,27 @@ function braintrustAISDKTelemetry() {
|
|
|
13510
14612
|
}
|
|
13511
14613
|
);
|
|
13512
14614
|
embedSpans.set(event.embedCallId, {
|
|
13513
|
-
|
|
14615
|
+
operationKey: operationKey ?? event.callId,
|
|
13514
14616
|
span,
|
|
13515
14617
|
values: event.values
|
|
13516
14618
|
});
|
|
13517
14619
|
});
|
|
13518
14620
|
},
|
|
13519
|
-
|
|
13520
|
-
runSafely("onEmbedFinish", () => {
|
|
13521
|
-
const state = embedSpans.get(event.embedCallId);
|
|
13522
|
-
if (!state) {
|
|
13523
|
-
return;
|
|
13524
|
-
}
|
|
13525
|
-
const result = {
|
|
13526
|
-
...event,
|
|
13527
|
-
embeddings: event.embeddings
|
|
13528
|
-
};
|
|
13529
|
-
state.span.log({
|
|
13530
|
-
...shouldRecordOutputs(event) ? {
|
|
13531
|
-
output: processAISDKEmbeddingOutput(
|
|
13532
|
-
result,
|
|
13533
|
-
DEFAULT_DENY_OUTPUT_PATHS
|
|
13534
|
-
)
|
|
13535
|
-
} : {},
|
|
13536
|
-
metrics: extractTokenMetrics(result)
|
|
13537
|
-
});
|
|
13538
|
-
state.span.end();
|
|
13539
|
-
embedSpans.delete(event.embedCallId);
|
|
13540
|
-
});
|
|
13541
|
-
},
|
|
14621
|
+
onEmbedEnd,
|
|
13542
14622
|
onRerankStart(event) {
|
|
13543
14623
|
runSafely("onRerankStart", () => {
|
|
13544
|
-
const
|
|
13545
|
-
|
|
14624
|
+
const operationKey = operationKeyFromEvent(event);
|
|
14625
|
+
const state = operationKey ? operations.get(operationKey) : void 0;
|
|
14626
|
+
if (shouldSkipTelemetryChildren(state)) {
|
|
14627
|
+
return;
|
|
14628
|
+
}
|
|
14629
|
+
const openSpan = operationKey ? rerankSpans.get(operationKey) : void 0;
|
|
14630
|
+
if (operationKey && openSpan) {
|
|
13546
14631
|
openSpan.end();
|
|
13547
|
-
rerankSpans.delete(
|
|
14632
|
+
rerankSpans.delete(operationKey);
|
|
13548
14633
|
}
|
|
13549
14634
|
const span = startChildSpan(
|
|
13550
|
-
event.callId,
|
|
14635
|
+
operationKey ?? event.callId,
|
|
13551
14636
|
"doRerank",
|
|
13552
14637
|
"llm" /* LLM */,
|
|
13553
14638
|
{
|
|
@@ -13561,41 +14646,23 @@ function braintrustAISDKTelemetry() {
|
|
|
13561
14646
|
metadata: metadataFromEvent(event)
|
|
13562
14647
|
}
|
|
13563
14648
|
);
|
|
13564
|
-
rerankSpans.set(event.callId, span);
|
|
13565
|
-
});
|
|
13566
|
-
},
|
|
13567
|
-
onRerankFinish(event) {
|
|
13568
|
-
runSafely("onRerankFinish", () => {
|
|
13569
|
-
const span = rerankSpans.get(event.callId);
|
|
13570
|
-
if (!span) {
|
|
13571
|
-
return;
|
|
13572
|
-
}
|
|
13573
|
-
const result = {
|
|
13574
|
-
ranking: event.ranking?.map((entry) => ({
|
|
13575
|
-
originalIndex: entry.index,
|
|
13576
|
-
score: entry.relevanceScore
|
|
13577
|
-
}))
|
|
13578
|
-
};
|
|
13579
|
-
span.log({
|
|
13580
|
-
...shouldRecordOutputs(event) ? {
|
|
13581
|
-
output: processAISDKRerankOutput(
|
|
13582
|
-
result,
|
|
13583
|
-
DEFAULT_DENY_OUTPUT_PATHS
|
|
13584
|
-
)
|
|
13585
|
-
} : {}
|
|
13586
|
-
});
|
|
13587
|
-
span.end();
|
|
13588
|
-
rerankSpans.delete(event.callId);
|
|
14649
|
+
rerankSpans.set(operationKey ?? event.callId, span);
|
|
13589
14650
|
});
|
|
13590
14651
|
},
|
|
14652
|
+
onRerankEnd,
|
|
13591
14653
|
onToolExecutionStart(event) {
|
|
13592
14654
|
runSafely("onToolExecutionStart", () => {
|
|
14655
|
+
const operationKey = operationKeyFromEvent(event);
|
|
14656
|
+
const state = operationKey ? operations.get(operationKey) : void 0;
|
|
14657
|
+
if (shouldSkipTelemetryChildren(state)) {
|
|
14658
|
+
return;
|
|
14659
|
+
}
|
|
13593
14660
|
const toolCallId = event.toolCall.toolCallId;
|
|
13594
|
-
if (!toolCallId) {
|
|
14661
|
+
if (!operationKey || !toolCallId) {
|
|
13595
14662
|
return;
|
|
13596
14663
|
}
|
|
13597
14664
|
const span = startChildSpan(
|
|
13598
|
-
|
|
14665
|
+
operationKey,
|
|
13599
14666
|
event.toolCall.toolName || "tool",
|
|
13600
14667
|
"tool" /* TOOL */,
|
|
13601
14668
|
{
|
|
@@ -13609,7 +14676,7 @@ function braintrustAISDKTelemetry() {
|
|
|
13609
14676
|
}
|
|
13610
14677
|
}
|
|
13611
14678
|
);
|
|
13612
|
-
toolSpans.set(toolCallId, {
|
|
14679
|
+
toolSpans.set(toolCallId, { operationKey, span });
|
|
13613
14680
|
});
|
|
13614
14681
|
},
|
|
13615
14682
|
onToolExecutionEnd(event) {
|
|
@@ -13620,14 +14687,17 @@ function braintrustAISDKTelemetry() {
|
|
|
13620
14687
|
return;
|
|
13621
14688
|
}
|
|
13622
14689
|
const toolOutput = event.toolOutput;
|
|
13623
|
-
|
|
14690
|
+
const workflowToolError = event.success === false && "error" in event ? event.error : void 0;
|
|
14691
|
+
if (toolOutput?.type === "tool-error" || workflowToolError !== void 0) {
|
|
14692
|
+
const error = toolOutput?.error ?? workflowToolError;
|
|
13624
14693
|
state.span.log({
|
|
13625
|
-
error:
|
|
14694
|
+
error: error instanceof Error ? error.message : String(error),
|
|
13626
14695
|
metrics: typeof event.durationMs === "number" ? { duration_ms: event.durationMs } : {}
|
|
13627
14696
|
});
|
|
13628
14697
|
} else {
|
|
14698
|
+
const output = toolOutput && "output" in toolOutput ? toolOutput.output : event.output;
|
|
13629
14699
|
state.span.log({
|
|
13630
|
-
...shouldRecordOutputs(event) ? { output
|
|
14700
|
+
...shouldRecordOutputs(event) ? { output } : {},
|
|
13631
14701
|
metrics: typeof event.durationMs === "number" ? { duration_ms: event.durationMs } : {}
|
|
13632
14702
|
});
|
|
13633
14703
|
}
|
|
@@ -13641,83 +14711,46 @@ function braintrustAISDKTelemetry() {
|
|
|
13641
14711
|
if (!callId) {
|
|
13642
14712
|
return;
|
|
13643
14713
|
}
|
|
13644
|
-
const
|
|
14714
|
+
const operationKey = operationKeyForCallId(callId);
|
|
14715
|
+
const state = operationKey ? operations.get(operationKey) : void 0;
|
|
13645
14716
|
if (!state || state.firstChunkTime !== void 0) {
|
|
13646
14717
|
return;
|
|
13647
14718
|
}
|
|
13648
14719
|
state.firstChunkTime = getCurrentUnixTimestamp();
|
|
13649
14720
|
});
|
|
13650
14721
|
},
|
|
13651
|
-
|
|
13652
|
-
|
|
13653
|
-
|
|
13654
|
-
|
|
14722
|
+
onEnd,
|
|
14723
|
+
onAbort(event) {
|
|
14724
|
+
runSafely("onAbort", () => {
|
|
14725
|
+
const operationKey = operationKeyFromEvent(event, "finish");
|
|
14726
|
+
const state = operationKey ? operations.get(operationKey) : void 0;
|
|
14727
|
+
if (!operationKey || !state) {
|
|
13655
14728
|
return;
|
|
13656
14729
|
}
|
|
13657
|
-
const
|
|
13658
|
-
|
|
13659
|
-
if (state.
|
|
13660
|
-
|
|
14730
|
+
const error = abortReasonFromEvent(event);
|
|
14731
|
+
closeOpenChildSpans(operationKey, error);
|
|
14732
|
+
if (state.ownsSpan) {
|
|
14733
|
+
logError(state.span, error);
|
|
14734
|
+
state.span.end();
|
|
13661
14735
|
}
|
|
13662
|
-
|
|
13663
|
-
...shouldRecordOutputs(event) ? {
|
|
13664
|
-
output: finishOutput(result, state.operationName)
|
|
13665
|
-
} : {},
|
|
13666
|
-
metrics
|
|
13667
|
-
});
|
|
13668
|
-
state.span.end();
|
|
13669
|
-
operations.delete(event.callId);
|
|
14736
|
+
deleteOperation(operationKey);
|
|
13670
14737
|
});
|
|
13671
14738
|
},
|
|
13672
14739
|
onError(event) {
|
|
13673
14740
|
runSafely("onError", () => {
|
|
13674
14741
|
const errorEvent = isObject(event) ? event : {};
|
|
13675
|
-
const
|
|
13676
|
-
|
|
13677
|
-
|
|
13678
|
-
}
|
|
13679
|
-
const state = operations.get(callId);
|
|
13680
|
-
if (!state) {
|
|
14742
|
+
const operationKey = operationKeyFromEvent(errorEvent, "finish");
|
|
14743
|
+
const state = operationKey ? operations.get(operationKey) : void 0;
|
|
14744
|
+
if (!operationKey || !state) {
|
|
13681
14745
|
return;
|
|
13682
14746
|
}
|
|
13683
14747
|
const error = errorEvent.error ?? event;
|
|
13684
|
-
|
|
13685
|
-
if (
|
|
13686
|
-
|
|
13687
|
-
|
|
13688
|
-
span.end();
|
|
13689
|
-
}
|
|
13690
|
-
modelSpans.delete(callId);
|
|
13691
|
-
}
|
|
13692
|
-
const openObjectSpan = objectSpans.get(callId);
|
|
13693
|
-
if (openObjectSpan) {
|
|
13694
|
-
logError(openObjectSpan, error);
|
|
13695
|
-
openObjectSpan.end();
|
|
13696
|
-
objectSpans.delete(callId);
|
|
13697
|
-
}
|
|
13698
|
-
for (const [embedCallId, embedState] of embedSpans) {
|
|
13699
|
-
if (embedState.callId === callId) {
|
|
13700
|
-
logError(embedState.span, error);
|
|
13701
|
-
embedState.span.end();
|
|
13702
|
-
embedSpans.delete(embedCallId);
|
|
13703
|
-
}
|
|
13704
|
-
}
|
|
13705
|
-
const openRerankSpan = rerankSpans.get(callId);
|
|
13706
|
-
if (openRerankSpan) {
|
|
13707
|
-
logError(openRerankSpan, error);
|
|
13708
|
-
openRerankSpan.end();
|
|
13709
|
-
rerankSpans.delete(callId);
|
|
13710
|
-
}
|
|
13711
|
-
for (const [toolCallId, toolState] of toolSpans) {
|
|
13712
|
-
if (toolState.callId === callId) {
|
|
13713
|
-
logError(toolState.span, error);
|
|
13714
|
-
toolState.span.end();
|
|
13715
|
-
toolSpans.delete(toolCallId);
|
|
13716
|
-
}
|
|
14748
|
+
closeOpenChildSpans(operationKey, error);
|
|
14749
|
+
if (state.ownsSpan) {
|
|
14750
|
+
logError(state.span, error);
|
|
14751
|
+
state.span.end();
|
|
13717
14752
|
}
|
|
13718
|
-
|
|
13719
|
-
state.span.end();
|
|
13720
|
-
operations.delete(callId);
|
|
14753
|
+
deleteOperation(operationKey);
|
|
13721
14754
|
});
|
|
13722
14755
|
},
|
|
13723
14756
|
executeTool({ toolCallId, execute }) {
|
|
@@ -13732,7 +14765,16 @@ function shouldRecordInputs(event) {
|
|
|
13732
14765
|
function shouldRecordOutputs(event) {
|
|
13733
14766
|
return event.recordOutputs !== false;
|
|
13734
14767
|
}
|
|
14768
|
+
function hasPromptLikeInput(input) {
|
|
14769
|
+
if (!isObject(input)) {
|
|
14770
|
+
return false;
|
|
14771
|
+
}
|
|
14772
|
+
return input.prompt !== void 0 || input.messages !== void 0;
|
|
14773
|
+
}
|
|
13735
14774
|
function operationNameFromId(operationId) {
|
|
14775
|
+
if (operationId === "ai.workflowAgent.stream") {
|
|
14776
|
+
return "WorkflowAgent.stream";
|
|
14777
|
+
}
|
|
13736
14778
|
return operationId?.startsWith("ai.") ? operationId.slice("ai.".length) : operationId || "ai-sdk";
|
|
13737
14779
|
}
|
|
13738
14780
|
function modelFromEvent(event) {
|
|
@@ -13778,6 +14820,7 @@ function operationInput(event, operationName) {
|
|
|
13778
14820
|
}
|
|
13779
14821
|
return {
|
|
13780
14822
|
model: modelFromEvent(event),
|
|
14823
|
+
instructions: event.instructions,
|
|
13781
14824
|
system: event.system,
|
|
13782
14825
|
prompt: event.prompt,
|
|
13783
14826
|
messages: event.messages,
|
|
@@ -13826,6 +14869,30 @@ function finishResult(event, operationName) {
|
|
|
13826
14869
|
}
|
|
13827
14870
|
return event;
|
|
13828
14871
|
}
|
|
14872
|
+
function extractTimeToFirstToken(result, state) {
|
|
14873
|
+
if (state.firstChunkTime !== void 0) {
|
|
14874
|
+
return state.firstChunkTime - state.startTime;
|
|
14875
|
+
}
|
|
14876
|
+
const performanceCandidates = [
|
|
14877
|
+
safePerformance(result),
|
|
14878
|
+
safePerformance(result.finalStep),
|
|
14879
|
+
...Array.isArray(result.steps) ? (result.steps ?? []).map(safePerformance) : []
|
|
14880
|
+
];
|
|
14881
|
+
for (const performance2 of performanceCandidates) {
|
|
14882
|
+
const timeToFirstOutputMs = performance2?.timeToFirstOutputMs;
|
|
14883
|
+
if (typeof timeToFirstOutputMs === "number") {
|
|
14884
|
+
return timeToFirstOutputMs / 1e3;
|
|
14885
|
+
}
|
|
14886
|
+
}
|
|
14887
|
+
return void 0;
|
|
14888
|
+
}
|
|
14889
|
+
function safePerformance(value) {
|
|
14890
|
+
if (!isObject(value)) {
|
|
14891
|
+
return void 0;
|
|
14892
|
+
}
|
|
14893
|
+
const performance2 = value.performance;
|
|
14894
|
+
return isObject(performance2) ? performance2 : void 0;
|
|
14895
|
+
}
|
|
13829
14896
|
function finishOutput(result, operationName) {
|
|
13830
14897
|
if (operationName === "embed" || operationName === "embedMany") {
|
|
13831
14898
|
return processAISDKEmbeddingOutput(
|
|
@@ -13902,6 +14969,10 @@ var aiSDKChannels = defineChannels("ai", {
|
|
|
13902
14969
|
channelName: "ToolLoopAgent.stream",
|
|
13903
14970
|
kind: "async"
|
|
13904
14971
|
}),
|
|
14972
|
+
workflowAgentStream: channel({
|
|
14973
|
+
channelName: "WorkflowAgent.stream",
|
|
14974
|
+
kind: "async"
|
|
14975
|
+
}),
|
|
13905
14976
|
v7CreateTelemetryDispatcher: channel({
|
|
13906
14977
|
channelName: "createTelemetryDispatcher",
|
|
13907
14978
|
kind: "sync-stream"
|
|
@@ -13912,14 +14983,19 @@ var aiSDKChannels = defineChannels("ai", {
|
|
|
13912
14983
|
var DEFAULT_DENY_OUTPUT_PATHS = [
|
|
13913
14984
|
// v3
|
|
13914
14985
|
"roundtrips[].request.body",
|
|
14986
|
+
"roundtrips[].request.headers",
|
|
13915
14987
|
"roundtrips[].response.headers",
|
|
13916
14988
|
"rawResponse.headers",
|
|
13917
14989
|
"responseMessages",
|
|
13918
14990
|
// v5
|
|
13919
14991
|
"request.body",
|
|
14992
|
+
"request.headers",
|
|
14993
|
+
"responses[].headers",
|
|
13920
14994
|
"response.body",
|
|
13921
14995
|
"response.headers",
|
|
13922
14996
|
"steps[].request.body",
|
|
14997
|
+
"steps[].request.headers",
|
|
14998
|
+
"steps[].responses[].headers",
|
|
13923
14999
|
"steps[].response.body",
|
|
13924
15000
|
"steps[].response.headers"
|
|
13925
15001
|
];
|
|
@@ -13931,6 +15007,18 @@ var AUTO_PATCHED_V7_TELEMETRY_DISPATCHER = /* @__PURE__ */ Symbol.for(
|
|
|
13931
15007
|
var RUNTIME_DENY_OUTPUT_PATHS = /* @__PURE__ */ Symbol.for(
|
|
13932
15008
|
"braintrust.ai-sdk.deny-output-paths"
|
|
13933
15009
|
);
|
|
15010
|
+
var aiSDKV7TelemetryOperationCounter = 0;
|
|
15011
|
+
var TRANSPORT_PAYLOAD_ROOT_PATHS = [
|
|
15012
|
+
"rawResponse",
|
|
15013
|
+
"request",
|
|
15014
|
+
"response",
|
|
15015
|
+
"responses[]",
|
|
15016
|
+
"roundtrips[].request",
|
|
15017
|
+
"roundtrips[].response",
|
|
15018
|
+
"steps[].request",
|
|
15019
|
+
"steps[].response",
|
|
15020
|
+
"steps[].responses[]"
|
|
15021
|
+
];
|
|
13934
15022
|
var AI_SDK_V7_TELEMETRY_CALLBACKS = [
|
|
13935
15023
|
"onStart",
|
|
13936
15024
|
"onStepStart",
|
|
@@ -13939,14 +15027,16 @@ var AI_SDK_V7_TELEMETRY_CALLBACKS = [
|
|
|
13939
15027
|
"onToolExecutionStart",
|
|
13940
15028
|
"onToolExecutionEnd",
|
|
13941
15029
|
"onChunk",
|
|
15030
|
+
"onStepEnd",
|
|
13942
15031
|
"onStepFinish",
|
|
13943
15032
|
"onObjectStepStart",
|
|
13944
|
-
"
|
|
15033
|
+
"onObjectStepEnd",
|
|
13945
15034
|
"onEmbedStart",
|
|
13946
|
-
"
|
|
15035
|
+
"onEmbedEnd",
|
|
13947
15036
|
"onRerankStart",
|
|
13948
|
-
"
|
|
13949
|
-
"
|
|
15037
|
+
"onRerankEnd",
|
|
15038
|
+
"onEnd",
|
|
15039
|
+
"onAbort",
|
|
13950
15040
|
"onError"
|
|
13951
15041
|
];
|
|
13952
15042
|
var AISDKPlugin = class extends BasePlugin {
|
|
@@ -14104,7 +15194,9 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
14104
15194
|
traceStreamingChannel(aiSDKChannels.agentGenerate, {
|
|
14105
15195
|
name: "Agent.generate",
|
|
14106
15196
|
type: "function" /* FUNCTION */,
|
|
14107
|
-
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths
|
|
15197
|
+
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
|
|
15198
|
+
agentOwner: true
|
|
15199
|
+
}),
|
|
14108
15200
|
extractOutput: (result, endEvent) => {
|
|
14109
15201
|
finalizeAISDKChildTracing(endEvent);
|
|
14110
15202
|
return processAISDKOutput(
|
|
@@ -14120,7 +15212,9 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
14120
15212
|
traceStreamingChannel(aiSDKChannels.agentStream, {
|
|
14121
15213
|
name: "Agent.stream",
|
|
14122
15214
|
type: "function" /* FUNCTION */,
|
|
14123
|
-
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths
|
|
15215
|
+
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
|
|
15216
|
+
agentOwner: true
|
|
15217
|
+
}),
|
|
14124
15218
|
extractOutput: (result, endEvent) => processAISDKOutput(
|
|
14125
15219
|
result,
|
|
14126
15220
|
resolveDenyOutputPaths(endEvent, denyOutputPaths)
|
|
@@ -14140,7 +15234,9 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
14140
15234
|
traceSyncStreamChannel(aiSDKChannels.agentStreamSync, {
|
|
14141
15235
|
name: "Agent.stream",
|
|
14142
15236
|
type: "function" /* FUNCTION */,
|
|
14143
|
-
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths
|
|
15237
|
+
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
|
|
15238
|
+
agentOwner: true
|
|
15239
|
+
}),
|
|
14144
15240
|
patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
|
|
14145
15241
|
defaultDenyOutputPaths: denyOutputPaths,
|
|
14146
15242
|
endEvent,
|
|
@@ -14154,7 +15250,9 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
14154
15250
|
traceStreamingChannel(aiSDKChannels.toolLoopAgentGenerate, {
|
|
14155
15251
|
name: "ToolLoopAgent.generate",
|
|
14156
15252
|
type: "function" /* FUNCTION */,
|
|
14157
|
-
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths
|
|
15253
|
+
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
|
|
15254
|
+
agentOwner: true
|
|
15255
|
+
}),
|
|
14158
15256
|
extractOutput: (result, endEvent) => {
|
|
14159
15257
|
finalizeAISDKChildTracing(endEvent);
|
|
14160
15258
|
return processAISDKOutput(
|
|
@@ -14170,7 +15268,9 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
14170
15268
|
traceStreamingChannel(aiSDKChannels.toolLoopAgentStream, {
|
|
14171
15269
|
name: "ToolLoopAgent.stream",
|
|
14172
15270
|
type: "function" /* FUNCTION */,
|
|
14173
|
-
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths
|
|
15271
|
+
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
|
|
15272
|
+
agentOwner: true
|
|
15273
|
+
}),
|
|
14174
15274
|
extractOutput: (result, endEvent) => processAISDKOutput(
|
|
14175
15275
|
result,
|
|
14176
15276
|
resolveDenyOutputPaths(endEvent, denyOutputPaths)
|
|
@@ -14186,6 +15286,42 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
14186
15286
|
})
|
|
14187
15287
|
})
|
|
14188
15288
|
);
|
|
15289
|
+
this.unsubscribers.push(
|
|
15290
|
+
traceStreamingChannel(aiSDKChannels.workflowAgentStream, {
|
|
15291
|
+
name: "WorkflowAgent.stream",
|
|
15292
|
+
type: "function" /* FUNCTION */,
|
|
15293
|
+
extractInput: ([params], event, span) => prepareAISDKWorkflowAgentStreamInput(
|
|
15294
|
+
params,
|
|
15295
|
+
event,
|
|
15296
|
+
span,
|
|
15297
|
+
denyOutputPaths
|
|
15298
|
+
),
|
|
15299
|
+
extractOutput: (result, endEvent) => {
|
|
15300
|
+
finalizeAISDKChildTracing(endEvent);
|
|
15301
|
+
return processAISDKOutput(
|
|
15302
|
+
result,
|
|
15303
|
+
resolveDenyOutputPaths(endEvent, denyOutputPaths)
|
|
15304
|
+
);
|
|
15305
|
+
},
|
|
15306
|
+
extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
|
|
15307
|
+
aggregateChunks: aggregateAISDKChunks,
|
|
15308
|
+
onComplete: ({ span }) => {
|
|
15309
|
+
unregisterWorkflowAgentWrapperSpan(span);
|
|
15310
|
+
},
|
|
15311
|
+
onError: ({ event, span }) => {
|
|
15312
|
+
finalizeAISDKChildTracing(event);
|
|
15313
|
+
unregisterWorkflowAgentWrapperSpan(span);
|
|
15314
|
+
},
|
|
15315
|
+
patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
|
|
15316
|
+
defaultDenyOutputPaths: denyOutputPaths,
|
|
15317
|
+
endEvent,
|
|
15318
|
+
onComplete: () => unregisterWorkflowAgentWrapperSpan(span),
|
|
15319
|
+
result,
|
|
15320
|
+
span,
|
|
15321
|
+
startTime
|
|
15322
|
+
})
|
|
15323
|
+
})
|
|
15324
|
+
);
|
|
14189
15325
|
}
|
|
14190
15326
|
};
|
|
14191
15327
|
function subscribeToAISDKV7TelemetryDispatcher() {
|
|
@@ -14197,7 +15333,11 @@ function subscribeToAISDKV7TelemetryDispatcher() {
|
|
|
14197
15333
|
if (telemetryOptions?.isEnabled === false) {
|
|
14198
15334
|
return;
|
|
14199
15335
|
}
|
|
14200
|
-
patchAISDKV7TelemetryDispatcher(
|
|
15336
|
+
patchAISDKV7TelemetryDispatcher(
|
|
15337
|
+
event.result,
|
|
15338
|
+
telemetry,
|
|
15339
|
+
telemetryOptions
|
|
15340
|
+
);
|
|
14201
15341
|
}
|
|
14202
15342
|
};
|
|
14203
15343
|
channel2.subscribe(handlers);
|
|
@@ -14205,7 +15345,7 @@ function subscribeToAISDKV7TelemetryDispatcher() {
|
|
|
14205
15345
|
channel2.unsubscribe(handlers);
|
|
14206
15346
|
};
|
|
14207
15347
|
}
|
|
14208
|
-
function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry) {
|
|
15348
|
+
function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry, telemetryOptions) {
|
|
14209
15349
|
if (!isObject(dispatcher)) {
|
|
14210
15350
|
return;
|
|
14211
15351
|
}
|
|
@@ -14214,6 +15354,54 @@ function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry) {
|
|
|
14214
15354
|
return;
|
|
14215
15355
|
}
|
|
14216
15356
|
dispatcherRecord[AUTO_PATCHED_V7_TELEMETRY_DISPATCHER] = true;
|
|
15357
|
+
let operationKey;
|
|
15358
|
+
const telemetryEventFields = {};
|
|
15359
|
+
if (typeof telemetryOptions?.recordInputs === "boolean") {
|
|
15360
|
+
telemetryEventFields.recordInputs = telemetryOptions.recordInputs;
|
|
15361
|
+
}
|
|
15362
|
+
if (typeof telemetryOptions?.recordOutputs === "boolean") {
|
|
15363
|
+
telemetryEventFields.recordOutputs = telemetryOptions.recordOutputs;
|
|
15364
|
+
}
|
|
15365
|
+
if (typeof telemetryOptions?.functionId === "string") {
|
|
15366
|
+
telemetryEventFields.functionId = telemetryOptions.functionId;
|
|
15367
|
+
}
|
|
15368
|
+
const eventWithOperationKey = (event) => {
|
|
15369
|
+
if (!isObject(event)) {
|
|
15370
|
+
return event;
|
|
15371
|
+
}
|
|
15372
|
+
const eventRecord = event;
|
|
15373
|
+
const callId = typeof eventRecord.callId === "string" ? eventRecord.callId : "unknown";
|
|
15374
|
+
operationKey ??= `${callId}:${++aiSDKV7TelemetryOperationCounter}`;
|
|
15375
|
+
if (Object.keys(telemetryEventFields).length > 0) {
|
|
15376
|
+
const augmentedEvent = {
|
|
15377
|
+
...telemetryEventFields,
|
|
15378
|
+
...event
|
|
15379
|
+
};
|
|
15380
|
+
try {
|
|
15381
|
+
Object.defineProperty(augmentedEvent, BRAINTRUST_AI_SDK_V7_OPERATION_KEY, {
|
|
15382
|
+
configurable: true,
|
|
15383
|
+
enumerable: false,
|
|
15384
|
+
value: operationKey
|
|
15385
|
+
});
|
|
15386
|
+
} catch {
|
|
15387
|
+
augmentedEvent[BRAINTRUST_AI_SDK_V7_OPERATION_KEY] = operationKey;
|
|
15388
|
+
}
|
|
15389
|
+
return augmentedEvent;
|
|
15390
|
+
}
|
|
15391
|
+
try {
|
|
15392
|
+
Object.defineProperty(eventRecord, BRAINTRUST_AI_SDK_V7_OPERATION_KEY, {
|
|
15393
|
+
configurable: true,
|
|
15394
|
+
enumerable: false,
|
|
15395
|
+
value: operationKey
|
|
15396
|
+
});
|
|
15397
|
+
return event;
|
|
15398
|
+
} catch {
|
|
15399
|
+
return {
|
|
15400
|
+
...event,
|
|
15401
|
+
[BRAINTRUST_AI_SDK_V7_OPERATION_KEY]: operationKey
|
|
15402
|
+
};
|
|
15403
|
+
}
|
|
15404
|
+
};
|
|
14217
15405
|
for (const key of AI_SDK_V7_TELEMETRY_CALLBACKS) {
|
|
14218
15406
|
const braintrustCallback = telemetry[key];
|
|
14219
15407
|
if (typeof braintrustCallback !== "function") {
|
|
@@ -14222,11 +15410,17 @@ function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry) {
|
|
|
14222
15410
|
const existingCallback = dispatcherRecord[key];
|
|
14223
15411
|
dispatcherRecord[key] = (event) => {
|
|
14224
15412
|
const existingResult = typeof existingCallback === "function" ? existingCallback.call(dispatcher, event) : void 0;
|
|
14225
|
-
|
|
14226
|
-
|
|
14227
|
-
|
|
14228
|
-
|
|
15413
|
+
try {
|
|
15414
|
+
const braintrustResult = braintrustCallback.call(
|
|
15415
|
+
telemetry,
|
|
15416
|
+
eventWithOperationKey(event)
|
|
15417
|
+
);
|
|
15418
|
+
if (isPromiseLike(braintrustResult)) {
|
|
15419
|
+
void Promise.resolve(braintrustResult).catch(() => void 0);
|
|
15420
|
+
}
|
|
15421
|
+
} catch {
|
|
14229
15422
|
}
|
|
15423
|
+
return existingResult;
|
|
14230
15424
|
};
|
|
14231
15425
|
}
|
|
14232
15426
|
const braintrustExecuteTool = telemetry.executeTool;
|
|
@@ -14236,6 +15430,7 @@ function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry) {
|
|
|
14236
15430
|
const existingExecuteTool = dispatcherRecord.executeTool;
|
|
14237
15431
|
dispatcherRecord.executeTool = (args) => braintrustExecuteTool.call(telemetry, {
|
|
14238
15432
|
...args,
|
|
15433
|
+
...operationKey ? { [BRAINTRUST_AI_SDK_V7_OPERATION_KEY]: operationKey } : {},
|
|
14239
15434
|
execute: () => typeof existingExecuteTool === "function" ? existingExecuteTool.call(dispatcher, args) : args.execute()
|
|
14240
15435
|
});
|
|
14241
15436
|
}
|
|
@@ -14334,6 +15529,8 @@ var serializeOutputObject = (output, model) => {
|
|
|
14334
15529
|
var processInputAttachmentsSync = (input) => {
|
|
14335
15530
|
if (!input) return { input };
|
|
14336
15531
|
const processed = { ...input };
|
|
15532
|
+
delete processed.headers;
|
|
15533
|
+
delete processed.experimental_output;
|
|
14337
15534
|
if (input.messages && Array.isArray(input.messages)) {
|
|
14338
15535
|
processed.messages = input.messages.map(processMessage);
|
|
14339
15536
|
}
|
|
@@ -14367,10 +15564,10 @@ var processInputAttachmentsSync = (input) => {
|
|
|
14367
15564
|
processed.output = serialized;
|
|
14368
15565
|
}
|
|
14369
15566
|
}
|
|
14370
|
-
|
|
14371
|
-
processed
|
|
14372
|
-
|
|
14373
|
-
|
|
15567
|
+
return {
|
|
15568
|
+
input: sanitizeAISDKCallInputValue(processed),
|
|
15569
|
+
outputPromise
|
|
15570
|
+
};
|
|
14374
15571
|
};
|
|
14375
15572
|
var processMessage = (message) => {
|
|
14376
15573
|
if (!message || typeof message !== "object") return message;
|
|
@@ -14534,7 +15731,21 @@ var convertDataToAttachment = (data, mimeType, filename) => {
|
|
|
14534
15731
|
function processAISDKCallInput(params) {
|
|
14535
15732
|
return processInputAttachmentsSync(params);
|
|
14536
15733
|
}
|
|
14537
|
-
function
|
|
15734
|
+
function processAISDKWorkflowAgentCallInput(params) {
|
|
15735
|
+
const processed = processAISDKCallInput(params);
|
|
15736
|
+
return {
|
|
15737
|
+
...processed,
|
|
15738
|
+
input: extractWorkflowAgentInput(processed.input)
|
|
15739
|
+
};
|
|
15740
|
+
}
|
|
15741
|
+
function processAISDKWorkflowAgentModelCallInput(params) {
|
|
15742
|
+
const processed = processAISDKCallInput(params);
|
|
15743
|
+
return {
|
|
15744
|
+
...processed,
|
|
15745
|
+
input: extractWorkflowAgentModelInput(processed.input)
|
|
15746
|
+
};
|
|
15747
|
+
}
|
|
15748
|
+
function prepareAISDKCallInput(params, event, span, defaultDenyOutputPaths, childTracingOptions = {}) {
|
|
14538
15749
|
const { input, outputPromise } = processAISDKCallInput(params);
|
|
14539
15750
|
if (outputPromise && input && typeof input === "object") {
|
|
14540
15751
|
outputPromise.then((resolvedData) => {
|
|
@@ -14553,7 +15764,29 @@ function prepareAISDKCallInput(params, event, span, defaultDenyOutputPaths) {
|
|
|
14553
15764
|
event.self,
|
|
14554
15765
|
span,
|
|
14555
15766
|
defaultDenyOutputPaths,
|
|
14556
|
-
event.aiSDK
|
|
15767
|
+
event.aiSDK,
|
|
15768
|
+
childTracingOptions
|
|
15769
|
+
);
|
|
15770
|
+
event.modelWrapped = childTracing.modelWrapped;
|
|
15771
|
+
if (childTracing.cleanup) {
|
|
15772
|
+
event.__braintrust_ai_sdk_cleanup = childTracing.cleanup;
|
|
15773
|
+
}
|
|
15774
|
+
return {
|
|
15775
|
+
input,
|
|
15776
|
+
metadata
|
|
15777
|
+
};
|
|
15778
|
+
}
|
|
15779
|
+
function prepareAISDKWorkflowAgentStreamInput(params, event, span, defaultDenyOutputPaths) {
|
|
15780
|
+
registerWorkflowAgentWrapperSpan(span);
|
|
15781
|
+
const { input } = processAISDKWorkflowAgentCallInput(params);
|
|
15782
|
+
const metadata = extractWorkflowMetadataFromCallParams(params, event.self);
|
|
15783
|
+
const childTracing = prepareAISDKChildTracing(
|
|
15784
|
+
params,
|
|
15785
|
+
event.self,
|
|
15786
|
+
span,
|
|
15787
|
+
defaultDenyOutputPaths,
|
|
15788
|
+
event.aiSDK,
|
|
15789
|
+
{ agentOwner: true, workflowAgent: true }
|
|
14557
15790
|
);
|
|
14558
15791
|
event.modelWrapped = childTracing.modelWrapped;
|
|
14559
15792
|
if (childTracing.cleanup) {
|
|
@@ -14590,6 +15823,9 @@ function extractTopLevelAISDKMetrics(result, event, startTime) {
|
|
|
14590
15823
|
function hasModelChildTracing(event) {
|
|
14591
15824
|
return event?.modelWrapped === true || event?.__braintrust_ai_sdk_model_wrapped === true;
|
|
14592
15825
|
}
|
|
15826
|
+
function serializeToolExecutionInput(args) {
|
|
15827
|
+
return args.length > 0 ? args[0] : args;
|
|
15828
|
+
}
|
|
14593
15829
|
function createAISDKIntegrationMetadata() {
|
|
14594
15830
|
return {
|
|
14595
15831
|
braintrust: {
|
|
@@ -14601,6 +15837,13 @@ function createAISDKIntegrationMetadata() {
|
|
|
14601
15837
|
function resolveModelFromSelf(self) {
|
|
14602
15838
|
return self && typeof self === "object" && "model" in self && self.model ? self.model : self && typeof self === "object" && "settings" in self && self.settings?.model ? self.settings?.model : void 0;
|
|
14603
15839
|
}
|
|
15840
|
+
function resolveToolsFromSelf(self) {
|
|
15841
|
+
if (!self || typeof self !== "object") {
|
|
15842
|
+
return void 0;
|
|
15843
|
+
}
|
|
15844
|
+
const selfRecord = self;
|
|
15845
|
+
return selfRecord.tools ?? selfRecord.settings?.tools;
|
|
15846
|
+
}
|
|
14604
15847
|
function extractBaseMetadata(model, self) {
|
|
14605
15848
|
const metadata = createAISDKIntegrationMetadata();
|
|
14606
15849
|
const { model: modelId, provider } = serializeModelWithProvider(
|
|
@@ -14616,12 +15859,175 @@ function extractBaseMetadata(model, self) {
|
|
|
14616
15859
|
}
|
|
14617
15860
|
function extractMetadataFromCallParams(params, self) {
|
|
14618
15861
|
const metadata = extractBaseMetadata(params.model, self);
|
|
14619
|
-
const tools = serializeAISDKToolsForLogging(
|
|
15862
|
+
const tools = serializeAISDKToolsForLogging(
|
|
15863
|
+
params.tools ?? resolveToolsFromSelf(self)
|
|
15864
|
+
);
|
|
14620
15865
|
if (tools) {
|
|
14621
15866
|
metadata.tools = tools;
|
|
14622
15867
|
}
|
|
14623
15868
|
return metadata;
|
|
14624
15869
|
}
|
|
15870
|
+
function extractWorkflowMetadataFromCallParams(params, self) {
|
|
15871
|
+
const metadata = extractMetadataFromCallParams(params, self);
|
|
15872
|
+
const options = extractAISDKCallOptionsForMetadata(params);
|
|
15873
|
+
if (Object.keys(options).length > 0) {
|
|
15874
|
+
metadata.options = options;
|
|
15875
|
+
}
|
|
15876
|
+
return metadata;
|
|
15877
|
+
}
|
|
15878
|
+
function extractWorkflowAgentInput(params) {
|
|
15879
|
+
const input = {};
|
|
15880
|
+
if (params.instructions !== void 0) {
|
|
15881
|
+
input.instructions = params.instructions;
|
|
15882
|
+
}
|
|
15883
|
+
if (params.system !== void 0) {
|
|
15884
|
+
input.system = params.system;
|
|
15885
|
+
}
|
|
15886
|
+
if (Array.isArray(params.messages)) {
|
|
15887
|
+
return { ...input, messages: params.messages };
|
|
15888
|
+
}
|
|
15889
|
+
if (typeof params.prompt === "string") {
|
|
15890
|
+
return { ...input, prompt: params.prompt };
|
|
15891
|
+
}
|
|
15892
|
+
if (Array.isArray(params.prompt)) {
|
|
15893
|
+
return { ...input, prompt: params.prompt };
|
|
15894
|
+
}
|
|
15895
|
+
return input;
|
|
15896
|
+
}
|
|
15897
|
+
function extractWorkflowAgentModelInput(params) {
|
|
15898
|
+
const input = {};
|
|
15899
|
+
if (params.instructions !== void 0) {
|
|
15900
|
+
input.instructions = params.instructions;
|
|
15901
|
+
}
|
|
15902
|
+
if (params.system !== void 0) {
|
|
15903
|
+
input.system = params.system;
|
|
15904
|
+
}
|
|
15905
|
+
if (Array.isArray(params.messages)) {
|
|
15906
|
+
return { ...input, messages: params.messages };
|
|
15907
|
+
}
|
|
15908
|
+
if (typeof params.prompt === "string") {
|
|
15909
|
+
return { ...input, prompt: params.prompt };
|
|
15910
|
+
}
|
|
15911
|
+
if (Array.isArray(params.prompt)) {
|
|
15912
|
+
return { ...input, messages: params.prompt };
|
|
15913
|
+
}
|
|
15914
|
+
return input;
|
|
15915
|
+
}
|
|
15916
|
+
function sanitizeAISDKCallInputValue(value, depth = 0) {
|
|
15917
|
+
if (value === void 0 || typeof value === "function") {
|
|
15918
|
+
return void 0;
|
|
15919
|
+
}
|
|
15920
|
+
if (value === null || typeof value !== "object") {
|
|
15921
|
+
return value;
|
|
15922
|
+
}
|
|
15923
|
+
if (isPromiseLike(value)) {
|
|
15924
|
+
return "[Promise]";
|
|
15925
|
+
}
|
|
15926
|
+
if (typeof AbortSignal !== "undefined" && value instanceof AbortSignal) {
|
|
15927
|
+
return "[AbortSignal]";
|
|
15928
|
+
}
|
|
15929
|
+
if (depth >= 8) {
|
|
15930
|
+
return "[Object]";
|
|
15931
|
+
}
|
|
15932
|
+
if (Array.isArray(value)) {
|
|
15933
|
+
return value.map((item) => sanitizeAISDKCallInputValue(item, depth + 1)).filter((item) => item !== void 0);
|
|
15934
|
+
}
|
|
15935
|
+
if (!isObject(value)) {
|
|
15936
|
+
return value;
|
|
15937
|
+
}
|
|
15938
|
+
const prototype = Object.getPrototypeOf(value);
|
|
15939
|
+
if (prototype !== Object.prototype && prototype !== null) {
|
|
15940
|
+
return value;
|
|
15941
|
+
}
|
|
15942
|
+
const sanitized = {};
|
|
15943
|
+
for (const [key, nested] of Object.entries(value)) {
|
|
15944
|
+
if (key === "__proto__" || key === "constructor" || key === "prototype" || key.toLowerCase() === "headers") {
|
|
15945
|
+
continue;
|
|
15946
|
+
}
|
|
15947
|
+
const sanitizedNested = sanitizeAISDKCallInputValue(nested, depth + 1);
|
|
15948
|
+
if (sanitizedNested !== void 0) {
|
|
15949
|
+
sanitized[key] = sanitizedNested;
|
|
15950
|
+
}
|
|
15951
|
+
}
|
|
15952
|
+
return sanitized;
|
|
15953
|
+
}
|
|
15954
|
+
function extractAISDKCallOptionsForMetadata(params) {
|
|
15955
|
+
const options = {};
|
|
15956
|
+
const inputOrTopLevelKeys = /* @__PURE__ */ new Set([
|
|
15957
|
+
"model",
|
|
15958
|
+
"instructions",
|
|
15959
|
+
"messages",
|
|
15960
|
+
"prompt",
|
|
15961
|
+
"system",
|
|
15962
|
+
"tools",
|
|
15963
|
+
"headers",
|
|
15964
|
+
"abortSignal",
|
|
15965
|
+
"signal",
|
|
15966
|
+
"experimental_output"
|
|
15967
|
+
]);
|
|
15968
|
+
for (const [key, value] of Object.entries(params)) {
|
|
15969
|
+
if (inputOrTopLevelKeys.has(key) || key === "__proto__" || key === "constructor" || key === "prototype" || /^on[A-Z]/.test(key) && typeof value === "function") {
|
|
15970
|
+
continue;
|
|
15971
|
+
}
|
|
15972
|
+
const sanitized = sanitizeAISDKMetadataValue(value);
|
|
15973
|
+
if (sanitized !== void 0) {
|
|
15974
|
+
options[key] = sanitized;
|
|
15975
|
+
}
|
|
15976
|
+
}
|
|
15977
|
+
return options;
|
|
15978
|
+
}
|
|
15979
|
+
function sanitizeAISDKMetadataValue(value, depth = 0) {
|
|
15980
|
+
if (value === void 0) {
|
|
15981
|
+
return void 0;
|
|
15982
|
+
}
|
|
15983
|
+
if (typeof value === "function") {
|
|
15984
|
+
return "[Function]";
|
|
15985
|
+
}
|
|
15986
|
+
if (value === null || typeof value !== "object") {
|
|
15987
|
+
return value;
|
|
15988
|
+
}
|
|
15989
|
+
if (isPromiseLike(value)) {
|
|
15990
|
+
return "[Promise]";
|
|
15991
|
+
}
|
|
15992
|
+
if (typeof AbortSignal !== "undefined" && value instanceof AbortSignal) {
|
|
15993
|
+
return "[AbortSignal]";
|
|
15994
|
+
}
|
|
15995
|
+
if (depth >= 8) {
|
|
15996
|
+
return "[Object]";
|
|
15997
|
+
}
|
|
15998
|
+
if (Array.isArray(value)) {
|
|
15999
|
+
return value.map((item) => sanitizeAISDKMetadataValue(item, depth + 1)).filter((item) => item !== void 0);
|
|
16000
|
+
}
|
|
16001
|
+
if (!isObject(value)) {
|
|
16002
|
+
return value;
|
|
16003
|
+
}
|
|
16004
|
+
const sanitized = {};
|
|
16005
|
+
for (const [key, nested] of Object.entries(value)) {
|
|
16006
|
+
if (key === "__proto__" || key === "constructor" || key === "prototype" || key.toLowerCase() === "headers") {
|
|
16007
|
+
continue;
|
|
16008
|
+
}
|
|
16009
|
+
const sanitizedNested = sanitizeAISDKMetadataValue(nested, depth + 1);
|
|
16010
|
+
if (sanitizedNested !== void 0) {
|
|
16011
|
+
sanitized[key] = sanitizedNested;
|
|
16012
|
+
}
|
|
16013
|
+
}
|
|
16014
|
+
return sanitized;
|
|
16015
|
+
}
|
|
16016
|
+
function buildAISDKModelStartEvent(callOptions, baseMetadata, options) {
|
|
16017
|
+
if (!options.workflowAgent) {
|
|
16018
|
+
return {
|
|
16019
|
+
input: processAISDKCallInput(callOptions).input,
|
|
16020
|
+
metadata: baseMetadata
|
|
16021
|
+
};
|
|
16022
|
+
}
|
|
16023
|
+
return {
|
|
16024
|
+
input: processAISDKWorkflowAgentModelCallInput(callOptions).input,
|
|
16025
|
+
metadata: {
|
|
16026
|
+
...baseMetadata,
|
|
16027
|
+
...extractWorkflowMetadataFromCallParams(callOptions)
|
|
16028
|
+
}
|
|
16029
|
+
};
|
|
16030
|
+
}
|
|
14625
16031
|
function extractMetadataFromEmbedParams(params, self) {
|
|
14626
16032
|
return extractBaseMetadata(params.model, self);
|
|
14627
16033
|
}
|
|
@@ -14635,72 +16041,273 @@ function extractMetadataFromRerankParams(params, self) {
|
|
|
14635
16041
|
}
|
|
14636
16042
|
return metadata;
|
|
14637
16043
|
}
|
|
14638
|
-
function
|
|
16044
|
+
function activeAISDKChildPatchEntry(entries) {
|
|
16045
|
+
const activeSpan = currentSpan();
|
|
16046
|
+
const activeSpanId = activeSpan.spanId;
|
|
16047
|
+
if (activeSpanId) {
|
|
16048
|
+
for (let index = entries.length - 1; index >= 0; index -= 1) {
|
|
16049
|
+
const entry = entries[index];
|
|
16050
|
+
if (entry?.activeSpanIds.has(activeSpanId)) {
|
|
16051
|
+
return entry;
|
|
16052
|
+
}
|
|
16053
|
+
}
|
|
16054
|
+
}
|
|
16055
|
+
const activeParentSpanIds = activeSpan.spanParents ?? [];
|
|
16056
|
+
for (let index = entries.length - 1; index >= 0; index -= 1) {
|
|
16057
|
+
const entry = entries[index];
|
|
16058
|
+
if (entry?.parentSpan.spanId && activeParentSpanIds.includes(entry.parentSpan.spanId)) {
|
|
16059
|
+
return entry;
|
|
16060
|
+
}
|
|
16061
|
+
}
|
|
16062
|
+
for (let index = entries.length - 1; index >= 0; index -= 1) {
|
|
16063
|
+
const entry = entries[index];
|
|
16064
|
+
if (entry?.parentSpan.spanId === activeSpanId) {
|
|
16065
|
+
return entry;
|
|
16066
|
+
}
|
|
16067
|
+
}
|
|
16068
|
+
return entries[entries.length - 1];
|
|
16069
|
+
}
|
|
16070
|
+
function attachNestedAISDKChildPatchEntry(entries, nestedSpan, cleanup) {
|
|
16071
|
+
const activeSpanId = currentSpan().spanId;
|
|
16072
|
+
if (!activeSpanId || activeSpanId === nestedSpan.spanId) {
|
|
16073
|
+
return false;
|
|
16074
|
+
}
|
|
16075
|
+
for (let index = entries.length - 1; index >= 0; index -= 1) {
|
|
16076
|
+
const entry = entries[index];
|
|
16077
|
+
if (entry?.parentSpan.spanId === activeSpanId || entry?.activeSpanIds.has(activeSpanId)) {
|
|
16078
|
+
entry.activeSpanIds.add(nestedSpan.spanId);
|
|
16079
|
+
cleanup.push(() => {
|
|
16080
|
+
entry.activeSpanIds.delete(nestedSpan.spanId);
|
|
16081
|
+
});
|
|
16082
|
+
return true;
|
|
16083
|
+
}
|
|
16084
|
+
}
|
|
16085
|
+
return false;
|
|
16086
|
+
}
|
|
16087
|
+
function shadowActiveAISDKChildPatchEntry(entries, entry, nestedSpan, cleanup) {
|
|
16088
|
+
const activeSpanId = currentSpan().spanId;
|
|
16089
|
+
if (!activeSpanId || activeSpanId === nestedSpan.spanId) {
|
|
16090
|
+
return;
|
|
16091
|
+
}
|
|
16092
|
+
for (let index = entries.length - 1; index >= 0; index -= 1) {
|
|
16093
|
+
const existingEntry = entries[index];
|
|
16094
|
+
if (existingEntry?.parentSpan.spanId === activeSpanId || existingEntry?.activeSpanIds.has(activeSpanId)) {
|
|
16095
|
+
entry.activeSpanIds.add(activeSpanId);
|
|
16096
|
+
cleanup.push(() => {
|
|
16097
|
+
entry.activeSpanIds.delete(activeSpanId);
|
|
16098
|
+
});
|
|
16099
|
+
return;
|
|
16100
|
+
}
|
|
16101
|
+
}
|
|
16102
|
+
}
|
|
16103
|
+
function closeOpenAISDKModelPatchSpans(entry) {
|
|
16104
|
+
for (const span of entry.openSpans) {
|
|
16105
|
+
span.end();
|
|
16106
|
+
}
|
|
16107
|
+
entry.openSpans.clear();
|
|
16108
|
+
}
|
|
16109
|
+
function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiSDK, childTracingOptions = {}) {
|
|
14639
16110
|
const cleanup = [];
|
|
14640
|
-
const patchedModels = /* @__PURE__ */ new
|
|
16111
|
+
const patchedModels = /* @__PURE__ */ new WeakMap();
|
|
14641
16112
|
const patchedTools = /* @__PURE__ */ new WeakSet();
|
|
14642
16113
|
let modelWrapped = false;
|
|
14643
16114
|
const patchModel = (model) => {
|
|
14644
16115
|
const resolvedModel = resolveAISDKModel(model, aiSDK);
|
|
14645
|
-
if (!resolvedModel || typeof resolvedModel !== "object" || typeof resolvedModel.doGenerate !== "function"
|
|
16116
|
+
if (!resolvedModel || typeof resolvedModel !== "object" || typeof resolvedModel.doGenerate !== "function") {
|
|
14646
16117
|
return resolvedModel;
|
|
14647
16118
|
}
|
|
14648
|
-
patchedModels.
|
|
14649
|
-
|
|
16119
|
+
const existingWrappedModel = patchedModels.get(resolvedModel);
|
|
16120
|
+
if (existingWrappedModel) {
|
|
16121
|
+
modelWrapped = true;
|
|
16122
|
+
return existingWrappedModel;
|
|
16123
|
+
}
|
|
14650
16124
|
modelWrapped = true;
|
|
16125
|
+
const modelRecord = resolvedModel;
|
|
16126
|
+
const entry = {
|
|
16127
|
+
activeSpanIds: /* @__PURE__ */ new Set([parentSpan.spanId]),
|
|
16128
|
+
baseMetadata: buildAISDKChildMetadata(resolvedModel),
|
|
16129
|
+
childTracingOptions,
|
|
16130
|
+
denyOutputPaths,
|
|
16131
|
+
openSpans: /* @__PURE__ */ new Set(),
|
|
16132
|
+
parentSpan
|
|
16133
|
+
};
|
|
16134
|
+
const cleanupModelEntry = (state2, patchedModel) => {
|
|
16135
|
+
closeOpenAISDKModelPatchSpans(entry);
|
|
16136
|
+
const index = state2.entries.indexOf(entry);
|
|
16137
|
+
if (index >= 0) {
|
|
16138
|
+
state2.entries.splice(index, 1);
|
|
16139
|
+
}
|
|
16140
|
+
if (state2.entries.length > 0) {
|
|
16141
|
+
return;
|
|
16142
|
+
}
|
|
16143
|
+
patchedModel.doGenerate = state2.originalDoGenerate;
|
|
16144
|
+
patchedModel.doStream = state2.originalDoStream;
|
|
16145
|
+
delete patchedModel[AUTO_PATCHED_MODEL];
|
|
16146
|
+
};
|
|
16147
|
+
const existingState = modelRecord[AUTO_PATCHED_MODEL];
|
|
16148
|
+
if (existingState) {
|
|
16149
|
+
patchedModels.set(resolvedModel, resolvedModel);
|
|
16150
|
+
if (childTracingOptions.agentOwner && attachNestedAISDKChildPatchEntry(
|
|
16151
|
+
existingState.entries,
|
|
16152
|
+
parentSpan,
|
|
16153
|
+
cleanup
|
|
16154
|
+
)) {
|
|
16155
|
+
return resolvedModel;
|
|
16156
|
+
}
|
|
16157
|
+
if (!childTracingOptions.agentOwner) {
|
|
16158
|
+
shadowActiveAISDKChildPatchEntry(
|
|
16159
|
+
existingState.entries,
|
|
16160
|
+
entry,
|
|
16161
|
+
parentSpan,
|
|
16162
|
+
cleanup
|
|
16163
|
+
);
|
|
16164
|
+
}
|
|
16165
|
+
existingState.entries.push(entry);
|
|
16166
|
+
cleanup.push(() => {
|
|
16167
|
+
cleanupModelEntry(existingState, modelRecord);
|
|
16168
|
+
});
|
|
16169
|
+
return resolvedModel;
|
|
16170
|
+
}
|
|
14651
16171
|
const originalDoGenerate = resolvedModel.doGenerate;
|
|
14652
16172
|
const originalDoStream = resolvedModel.doStream;
|
|
14653
|
-
const
|
|
14654
|
-
|
|
14655
|
-
|
|
16173
|
+
const wrappedModel = Object.create(
|
|
16174
|
+
Object.getPrototypeOf(resolvedModel)
|
|
16175
|
+
);
|
|
16176
|
+
Object.defineProperties(
|
|
16177
|
+
wrappedModel,
|
|
16178
|
+
Object.getOwnPropertyDescriptors(resolvedModel)
|
|
16179
|
+
);
|
|
16180
|
+
const wrappedModelRecord = wrappedModel;
|
|
16181
|
+
const state = {
|
|
16182
|
+
entries: [entry],
|
|
16183
|
+
originalDoGenerate,
|
|
16184
|
+
originalDoStream
|
|
16185
|
+
};
|
|
16186
|
+
Object.defineProperty(wrappedModel, AUTO_PATCHED_MODEL, {
|
|
16187
|
+
configurable: true,
|
|
16188
|
+
value: state
|
|
16189
|
+
});
|
|
16190
|
+
wrappedModel.doGenerate = async function doGeneratePatched(callOptions) {
|
|
16191
|
+
const activeEntry = activeAISDKChildPatchEntry(state.entries);
|
|
16192
|
+
if (!activeEntry) {
|
|
16193
|
+
return Reflect.apply(originalDoGenerate, resolvedModel, [callOptions]);
|
|
16194
|
+
}
|
|
16195
|
+
closeOpenAISDKModelPatchSpans(activeEntry);
|
|
16196
|
+
return activeEntry.parentSpan.traced(
|
|
14656
16197
|
async (span) => {
|
|
14657
|
-
|
|
14658
|
-
|
|
14659
|
-
|
|
14660
|
-
|
|
14661
|
-
|
|
14662
|
-
|
|
14663
|
-
|
|
14664
|
-
|
|
14665
|
-
|
|
14666
|
-
|
|
14667
|
-
|
|
16198
|
+
activeEntry.openSpans.add(span);
|
|
16199
|
+
try {
|
|
16200
|
+
const result = await Reflect.apply(
|
|
16201
|
+
originalDoGenerate,
|
|
16202
|
+
resolvedModel,
|
|
16203
|
+
[callOptions]
|
|
16204
|
+
);
|
|
16205
|
+
const output = processAISDKOutput(
|
|
16206
|
+
result,
|
|
16207
|
+
activeEntry.denyOutputPaths
|
|
16208
|
+
);
|
|
16209
|
+
const metrics = extractTokenMetrics(result);
|
|
16210
|
+
const metadataPayload = buildResolvedMetadataPayload(result);
|
|
16211
|
+
const missingUsageMetadata = buildMissingUsageMetadata(
|
|
16212
|
+
output,
|
|
16213
|
+
metrics,
|
|
16214
|
+
"ai_sdk_result_missing_usage"
|
|
16215
|
+
);
|
|
16216
|
+
span.log({
|
|
16217
|
+
output,
|
|
16218
|
+
metrics,
|
|
16219
|
+
...mergeMetadataPayload(metadataPayload, missingUsageMetadata)
|
|
16220
|
+
});
|
|
16221
|
+
return result;
|
|
16222
|
+
} finally {
|
|
16223
|
+
activeEntry.openSpans.delete(span);
|
|
16224
|
+
}
|
|
14668
16225
|
},
|
|
14669
16226
|
{
|
|
14670
16227
|
name: "doGenerate",
|
|
14671
16228
|
spanAttributes: {
|
|
14672
16229
|
type: "llm" /* LLM */
|
|
14673
16230
|
},
|
|
14674
|
-
event:
|
|
14675
|
-
|
|
14676
|
-
|
|
14677
|
-
|
|
16231
|
+
event: buildAISDKModelStartEvent(
|
|
16232
|
+
callOptions,
|
|
16233
|
+
activeEntry.baseMetadata,
|
|
16234
|
+
{
|
|
16235
|
+
workflowAgent: activeEntry.childTracingOptions.workflowAgent
|
|
16236
|
+
}
|
|
16237
|
+
)
|
|
14678
16238
|
}
|
|
14679
16239
|
);
|
|
14680
16240
|
};
|
|
14681
16241
|
if (originalDoStream) {
|
|
14682
|
-
|
|
14683
|
-
const
|
|
16242
|
+
wrappedModel.doStream = async function doStreamPatched(callOptions) {
|
|
16243
|
+
const activeEntry = activeAISDKChildPatchEntry(state.entries);
|
|
16244
|
+
if (!activeEntry) {
|
|
16245
|
+
return Reflect.apply(originalDoStream, resolvedModel, [callOptions]);
|
|
16246
|
+
}
|
|
16247
|
+
closeOpenAISDKModelPatchSpans(activeEntry);
|
|
16248
|
+
const span = activeEntry.parentSpan.startSpan({
|
|
14684
16249
|
name: "doStream",
|
|
14685
16250
|
spanAttributes: {
|
|
14686
16251
|
type: "llm" /* LLM */
|
|
14687
16252
|
},
|
|
14688
|
-
event:
|
|
14689
|
-
|
|
14690
|
-
|
|
14691
|
-
|
|
16253
|
+
event: buildAISDKModelStartEvent(
|
|
16254
|
+
callOptions,
|
|
16255
|
+
activeEntry.baseMetadata,
|
|
16256
|
+
{
|
|
16257
|
+
workflowAgent: activeEntry.childTracingOptions.workflowAgent
|
|
16258
|
+
}
|
|
16259
|
+
)
|
|
14692
16260
|
});
|
|
16261
|
+
activeEntry.openSpans.add(span);
|
|
14693
16262
|
const streamStartTime = getCurrentUnixTimestamp();
|
|
14694
16263
|
const result = await withCurrent(
|
|
14695
16264
|
span,
|
|
14696
|
-
() => Reflect.apply(originalDoStream, resolvedModel, [
|
|
16265
|
+
() => Reflect.apply(originalDoStream, resolvedModel, [callOptions])
|
|
14697
16266
|
);
|
|
14698
16267
|
let firstChunkTime;
|
|
14699
16268
|
const output = {};
|
|
14700
16269
|
let text = "";
|
|
14701
16270
|
let reasoning = "";
|
|
14702
|
-
const
|
|
16271
|
+
const toolCalls2 = [];
|
|
14703
16272
|
let object = void 0;
|
|
16273
|
+
let streamSpanEnded = false;
|
|
16274
|
+
const logAndEndStreamSpan = (usageUnavailableReason) => {
|
|
16275
|
+
if (streamSpanEnded) {
|
|
16276
|
+
return;
|
|
16277
|
+
}
|
|
16278
|
+
output.text = text;
|
|
16279
|
+
output.reasoning = reasoning;
|
|
16280
|
+
output.toolCalls = toolCalls2;
|
|
16281
|
+
if (object !== void 0) {
|
|
16282
|
+
output.object = object;
|
|
16283
|
+
}
|
|
16284
|
+
const metrics = extractTokenMetrics(output);
|
|
16285
|
+
if (firstChunkTime !== void 0 && !activeEntry.childTracingOptions.workflowAgent) {
|
|
16286
|
+
metrics.time_to_first_token = Math.max(
|
|
16287
|
+
firstChunkTime - streamStartTime,
|
|
16288
|
+
1e-6
|
|
16289
|
+
);
|
|
16290
|
+
}
|
|
16291
|
+
const metadataPayload = buildResolvedMetadataPayload(
|
|
16292
|
+
output
|
|
16293
|
+
);
|
|
16294
|
+
const missingUsageMetadata = usageUnavailableReason ? { usage_unavailable_reason: usageUnavailableReason } : buildMissingUsageMetadata(
|
|
16295
|
+
output,
|
|
16296
|
+
metrics,
|
|
16297
|
+
"ai_sdk_result_missing_usage"
|
|
16298
|
+
);
|
|
16299
|
+
span.log({
|
|
16300
|
+
output: processAISDKOutput(
|
|
16301
|
+
output,
|
|
16302
|
+
activeEntry.denyOutputPaths
|
|
16303
|
+
),
|
|
16304
|
+
metrics,
|
|
16305
|
+
...mergeMetadataPayload(metadataPayload, missingUsageMetadata)
|
|
16306
|
+
});
|
|
16307
|
+
activeEntry.openSpans.delete(span);
|
|
16308
|
+
span.end();
|
|
16309
|
+
streamSpanEnded = true;
|
|
16310
|
+
};
|
|
14704
16311
|
const transformStream = new TransformStream({
|
|
14705
16312
|
transform(chunk, controller) {
|
|
14706
16313
|
if (firstChunkTime === void 0 && isAISDKContentStreamChunk(chunk)) {
|
|
@@ -14718,7 +16325,7 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
|
|
|
14718
16325
|
}
|
|
14719
16326
|
break;
|
|
14720
16327
|
case "tool-call":
|
|
14721
|
-
|
|
16328
|
+
toolCalls2.push(chunk);
|
|
14722
16329
|
break;
|
|
14723
16330
|
case "object":
|
|
14724
16331
|
object = chunk.object;
|
|
@@ -14738,33 +16345,15 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
|
|
|
14738
16345
|
}
|
|
14739
16346
|
break;
|
|
14740
16347
|
case "finish":
|
|
14741
|
-
output.text = text;
|
|
14742
|
-
output.reasoning = reasoning;
|
|
14743
|
-
output.toolCalls = toolCalls;
|
|
14744
16348
|
output.finishReason = chunk.finishReason;
|
|
14745
16349
|
output.usage = chunk.usage;
|
|
14746
|
-
|
|
14747
|
-
output.object = object;
|
|
14748
|
-
}
|
|
14749
|
-
const metrics = extractTokenMetrics(output);
|
|
14750
|
-
if (firstChunkTime !== void 0) {
|
|
14751
|
-
metrics.time_to_first_token = Math.max(
|
|
14752
|
-
firstChunkTime - streamStartTime,
|
|
14753
|
-
1e-6
|
|
14754
|
-
);
|
|
14755
|
-
}
|
|
14756
|
-
span.log({
|
|
14757
|
-
output: processAISDKOutput(
|
|
14758
|
-
output,
|
|
14759
|
-
denyOutputPaths
|
|
14760
|
-
),
|
|
14761
|
-
metrics,
|
|
14762
|
-
...buildResolvedMetadataPayload(output)
|
|
14763
|
-
});
|
|
14764
|
-
span.end();
|
|
16350
|
+
logAndEndStreamSpan();
|
|
14765
16351
|
break;
|
|
14766
16352
|
}
|
|
14767
16353
|
controller.enqueue(chunk);
|
|
16354
|
+
},
|
|
16355
|
+
flush() {
|
|
16356
|
+
logAndEndStreamSpan("ai_sdk_stream_finished_without_usage");
|
|
14768
16357
|
}
|
|
14769
16358
|
});
|
|
14770
16359
|
return {
|
|
@@ -14774,32 +16363,79 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
|
|
|
14774
16363
|
};
|
|
14775
16364
|
}
|
|
14776
16365
|
cleanup.push(() => {
|
|
14777
|
-
|
|
14778
|
-
if (originalDoStream) {
|
|
14779
|
-
resolvedModel.doStream = originalDoStream;
|
|
14780
|
-
}
|
|
14781
|
-
delete resolvedModel[AUTO_PATCHED_MODEL];
|
|
16366
|
+
cleanupModelEntry(state, wrappedModelRecord);
|
|
14782
16367
|
});
|
|
14783
|
-
|
|
16368
|
+
patchedModels.set(resolvedModel, wrappedModel);
|
|
16369
|
+
patchedModels.set(wrappedModel, wrappedModel);
|
|
16370
|
+
return wrappedModel;
|
|
14784
16371
|
};
|
|
14785
16372
|
const patchTool = (tool, name) => {
|
|
14786
|
-
if (tool == null || typeof tool !== "object" || !("execute" in tool) || typeof tool.execute !== "function" || patchedTools.has(tool)
|
|
16373
|
+
if (tool == null || typeof tool !== "object" || !("execute" in tool) || typeof tool.execute !== "function" || patchedTools.has(tool)) {
|
|
14787
16374
|
return;
|
|
14788
16375
|
}
|
|
14789
16376
|
patchedTools.add(tool);
|
|
14790
|
-
|
|
14791
|
-
const
|
|
16377
|
+
const toolRecord = tool;
|
|
16378
|
+
const entry = {
|
|
16379
|
+
activeSpanIds: /* @__PURE__ */ new Set([parentSpan.spanId]),
|
|
16380
|
+
childTracingOptions,
|
|
16381
|
+
name,
|
|
16382
|
+
parentSpan
|
|
16383
|
+
};
|
|
16384
|
+
const cleanupToolEntry = (state2) => {
|
|
16385
|
+
const index = state2.entries.indexOf(entry);
|
|
16386
|
+
if (index >= 0) {
|
|
16387
|
+
state2.entries.splice(index, 1);
|
|
16388
|
+
}
|
|
16389
|
+
if (state2.entries.length > 0) {
|
|
16390
|
+
return;
|
|
16391
|
+
}
|
|
16392
|
+
tool.execute = state2.originalExecute;
|
|
16393
|
+
delete toolRecord[AUTO_PATCHED_TOOL];
|
|
16394
|
+
};
|
|
16395
|
+
const existingState = toolRecord[AUTO_PATCHED_TOOL];
|
|
16396
|
+
if (existingState) {
|
|
16397
|
+
if (childTracingOptions.agentOwner && attachNestedAISDKChildPatchEntry(
|
|
16398
|
+
existingState.entries,
|
|
16399
|
+
parentSpan,
|
|
16400
|
+
cleanup
|
|
16401
|
+
)) {
|
|
16402
|
+
return;
|
|
16403
|
+
}
|
|
16404
|
+
if (!childTracingOptions.agentOwner) {
|
|
16405
|
+
shadowActiveAISDKChildPatchEntry(
|
|
16406
|
+
existingState.entries,
|
|
16407
|
+
entry,
|
|
16408
|
+
parentSpan,
|
|
16409
|
+
cleanup
|
|
16410
|
+
);
|
|
16411
|
+
}
|
|
16412
|
+
existingState.entries.push(entry);
|
|
16413
|
+
cleanup.push(() => {
|
|
16414
|
+
cleanupToolEntry(existingState);
|
|
16415
|
+
});
|
|
16416
|
+
return;
|
|
16417
|
+
}
|
|
16418
|
+
const originalExecute = toolRecord.execute;
|
|
16419
|
+
const state = {
|
|
16420
|
+
entries: [entry],
|
|
16421
|
+
originalExecute
|
|
16422
|
+
};
|
|
16423
|
+
toolRecord[AUTO_PATCHED_TOOL] = state;
|
|
14792
16424
|
tool.execute = function executePatched(...args) {
|
|
16425
|
+
const activeEntry = activeAISDKChildPatchEntry(state.entries);
|
|
14793
16426
|
const result = Reflect.apply(originalExecute, this, args);
|
|
16427
|
+
if (!activeEntry) {
|
|
16428
|
+
return result;
|
|
16429
|
+
}
|
|
14794
16430
|
if (isAsyncGenerator(result)) {
|
|
14795
16431
|
return (async function* () {
|
|
14796
|
-
const span = parentSpan.startSpan({
|
|
14797
|
-
name,
|
|
16432
|
+
const span = activeEntry.parentSpan.startSpan({
|
|
16433
|
+
name: activeEntry.name,
|
|
14798
16434
|
spanAttributes: {
|
|
14799
16435
|
type: "tool" /* TOOL */
|
|
14800
16436
|
}
|
|
14801
16437
|
});
|
|
14802
|
-
span.log({ input: args
|
|
16438
|
+
span.log({ input: serializeToolExecutionInput(args) });
|
|
14803
16439
|
try {
|
|
14804
16440
|
let lastValue;
|
|
14805
16441
|
for await (const value of result) {
|
|
@@ -14815,15 +16451,15 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
|
|
|
14815
16451
|
}
|
|
14816
16452
|
})();
|
|
14817
16453
|
}
|
|
14818
|
-
return parentSpan.traced(
|
|
16454
|
+
return activeEntry.parentSpan.traced(
|
|
14819
16455
|
async (span) => {
|
|
14820
|
-
span.log({ input: args
|
|
16456
|
+
span.log({ input: serializeToolExecutionInput(args) });
|
|
14821
16457
|
const awaitedResult = await result;
|
|
14822
16458
|
span.log({ output: awaitedResult });
|
|
14823
16459
|
return awaitedResult;
|
|
14824
16460
|
},
|
|
14825
16461
|
{
|
|
14826
|
-
name,
|
|
16462
|
+
name: activeEntry.name,
|
|
14827
16463
|
spanAttributes: {
|
|
14828
16464
|
type: "tool" /* TOOL */
|
|
14829
16465
|
}
|
|
@@ -14831,8 +16467,7 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
|
|
|
14831
16467
|
);
|
|
14832
16468
|
};
|
|
14833
16469
|
cleanup.push(() => {
|
|
14834
|
-
|
|
14835
|
-
delete tool[AUTO_PATCHED_TOOL];
|
|
16470
|
+
cleanupToolEntry(state);
|
|
14836
16471
|
});
|
|
14837
16472
|
};
|
|
14838
16473
|
const patchTools = (tools) => {
|
|
@@ -14851,25 +16486,42 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
|
|
|
14851
16486
|
}
|
|
14852
16487
|
};
|
|
14853
16488
|
if (params && typeof params === "object") {
|
|
14854
|
-
const
|
|
14855
|
-
|
|
16489
|
+
const originalParamModel = params.model;
|
|
16490
|
+
const patchedParamModel = patchModel(originalParamModel);
|
|
16491
|
+
if (patchedParamModel && patchedParamModel !== originalParamModel) {
|
|
14856
16492
|
params.model = patchedParamModel;
|
|
16493
|
+
cleanup.push(() => {
|
|
16494
|
+
params.model = originalParamModel;
|
|
16495
|
+
});
|
|
14857
16496
|
}
|
|
14858
16497
|
patchTools(params.tools);
|
|
14859
16498
|
}
|
|
14860
16499
|
if (self && typeof self === "object") {
|
|
14861
16500
|
const selfRecord = self;
|
|
14862
16501
|
if (selfRecord.model !== void 0) {
|
|
14863
|
-
const
|
|
14864
|
-
|
|
16502
|
+
const originalSelfModel = selfRecord.model;
|
|
16503
|
+
const patchedSelfModel = patchModel(originalSelfModel);
|
|
16504
|
+
if (patchedSelfModel && patchedSelfModel !== originalSelfModel) {
|
|
14865
16505
|
selfRecord.model = patchedSelfModel;
|
|
16506
|
+
cleanup.push(() => {
|
|
16507
|
+
selfRecord.model = originalSelfModel;
|
|
16508
|
+
});
|
|
14866
16509
|
}
|
|
14867
16510
|
}
|
|
16511
|
+
if (selfRecord.tools !== void 0) {
|
|
16512
|
+
patchTools(selfRecord.tools);
|
|
16513
|
+
}
|
|
14868
16514
|
if (selfRecord.settings && typeof selfRecord.settings === "object") {
|
|
14869
16515
|
if (selfRecord.settings.model !== void 0) {
|
|
14870
|
-
const
|
|
14871
|
-
|
|
16516
|
+
const originalSettingsModel = selfRecord.settings.model;
|
|
16517
|
+
const patchedSettingsModel = patchModel(originalSettingsModel);
|
|
16518
|
+
if (patchedSettingsModel && patchedSettingsModel !== originalSettingsModel) {
|
|
14872
16519
|
selfRecord.settings.model = patchedSettingsModel;
|
|
16520
|
+
cleanup.push(() => {
|
|
16521
|
+
if (selfRecord.settings) {
|
|
16522
|
+
selfRecord.settings.model = originalSettingsModel;
|
|
16523
|
+
}
|
|
16524
|
+
});
|
|
14873
16525
|
}
|
|
14874
16526
|
}
|
|
14875
16527
|
if (selfRecord.settings.tools !== void 0) {
|
|
@@ -14966,99 +16618,190 @@ function isAISDKContentAsyncIterableChunk(chunk) {
|
|
|
14966
16618
|
return isObject(part) && typeof part.type !== "string";
|
|
14967
16619
|
}
|
|
14968
16620
|
function patchAISDKStreamingResult(args) {
|
|
14969
|
-
const {
|
|
16621
|
+
const {
|
|
16622
|
+
defaultDenyOutputPaths,
|
|
16623
|
+
endEvent,
|
|
16624
|
+
onComplete,
|
|
16625
|
+
result,
|
|
16626
|
+
span,
|
|
16627
|
+
startTime
|
|
16628
|
+
} = args;
|
|
14970
16629
|
if (!result || typeof result !== "object") {
|
|
14971
16630
|
return false;
|
|
14972
16631
|
}
|
|
14973
16632
|
const resultRecord = result;
|
|
14974
16633
|
attachKnownResultPromiseHandlers(resultRecord);
|
|
16634
|
+
let finalized = false;
|
|
16635
|
+
const finalize = () => {
|
|
16636
|
+
if (finalized) {
|
|
16637
|
+
return;
|
|
16638
|
+
}
|
|
16639
|
+
finalized = true;
|
|
16640
|
+
finalizeAISDKChildTracing(endEvent);
|
|
16641
|
+
span.end();
|
|
16642
|
+
onComplete?.();
|
|
16643
|
+
};
|
|
16644
|
+
let outputLogged = false;
|
|
16645
|
+
const logStreamingOutput = async (firstChunkTime) => {
|
|
16646
|
+
if (outputLogged) {
|
|
16647
|
+
return;
|
|
16648
|
+
}
|
|
16649
|
+
outputLogged = true;
|
|
16650
|
+
try {
|
|
16651
|
+
const metrics = extractTopLevelAISDKMetrics(result, endEvent);
|
|
16652
|
+
if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
|
|
16653
|
+
metrics.time_to_first_token = firstChunkTime - startTime;
|
|
16654
|
+
}
|
|
16655
|
+
const output = await processAISDKStreamingOutput(
|
|
16656
|
+
result,
|
|
16657
|
+
resolveDenyOutputPaths(endEvent, defaultDenyOutputPaths)
|
|
16658
|
+
);
|
|
16659
|
+
const metadata = buildResolvedMetadataPayload(result).metadata;
|
|
16660
|
+
span.log({
|
|
16661
|
+
output,
|
|
16662
|
+
...metadata ? { metadata } : {},
|
|
16663
|
+
metrics
|
|
16664
|
+
});
|
|
16665
|
+
} catch (error) {
|
|
16666
|
+
span.log({ error: toLoggedError(error) });
|
|
16667
|
+
} finally {
|
|
16668
|
+
finalize();
|
|
16669
|
+
}
|
|
16670
|
+
};
|
|
16671
|
+
const createAsyncIterableHooks = () => {
|
|
16672
|
+
let firstChunkTime;
|
|
16673
|
+
return {
|
|
16674
|
+
onChunk: (chunk) => {
|
|
16675
|
+
if (firstChunkTime === void 0 && isAISDKContentAsyncIterableChunk(chunk)) {
|
|
16676
|
+
firstChunkTime = getCurrentUnixTimestamp();
|
|
16677
|
+
}
|
|
16678
|
+
},
|
|
16679
|
+
onComplete: async () => {
|
|
16680
|
+
await logStreamingOutput(firstChunkTime);
|
|
16681
|
+
},
|
|
16682
|
+
onError: (error) => {
|
|
16683
|
+
if (!outputLogged) {
|
|
16684
|
+
outputLogged = true;
|
|
16685
|
+
span.log({
|
|
16686
|
+
error: error.message
|
|
16687
|
+
});
|
|
16688
|
+
}
|
|
16689
|
+
finalize();
|
|
16690
|
+
},
|
|
16691
|
+
onCancel: finalize
|
|
16692
|
+
};
|
|
16693
|
+
};
|
|
16694
|
+
const patchAsyncIterable = (stream) => isReadableStreamLike(stream) ? createPatchedReadableStream(stream, createAsyncIterableHooks()) : createPatchedAsyncIterable(stream, createAsyncIterableHooks());
|
|
16695
|
+
const patchAsyncIterableField = (field) => {
|
|
16696
|
+
let descriptorOwner = resultRecord;
|
|
16697
|
+
let descriptor;
|
|
16698
|
+
while (descriptorOwner) {
|
|
16699
|
+
descriptor = Object.getOwnPropertyDescriptor(descriptorOwner, field);
|
|
16700
|
+
if (descriptor) {
|
|
16701
|
+
break;
|
|
16702
|
+
}
|
|
16703
|
+
descriptorOwner = Object.getPrototypeOf(descriptorOwner);
|
|
16704
|
+
}
|
|
16705
|
+
if (!descriptor || descriptorOwner === resultRecord && !descriptor.configurable) {
|
|
16706
|
+
return false;
|
|
16707
|
+
}
|
|
16708
|
+
if ("value" in descriptor) {
|
|
16709
|
+
if (!isAsyncIterable(descriptor.value)) {
|
|
16710
|
+
return false;
|
|
16711
|
+
}
|
|
16712
|
+
try {
|
|
16713
|
+
Object.defineProperty(resultRecord, field, {
|
|
16714
|
+
configurable: descriptorOwner === resultRecord ? descriptor.configurable : true,
|
|
16715
|
+
enumerable: descriptor.enumerable,
|
|
16716
|
+
value: patchAsyncIterable(descriptor.value),
|
|
16717
|
+
writable: descriptor.writable
|
|
16718
|
+
});
|
|
16719
|
+
return true;
|
|
16720
|
+
} catch {
|
|
16721
|
+
return false;
|
|
16722
|
+
}
|
|
16723
|
+
}
|
|
16724
|
+
if (typeof descriptor.get !== "function") {
|
|
16725
|
+
return false;
|
|
16726
|
+
}
|
|
16727
|
+
const originalGet = descriptor.get;
|
|
16728
|
+
const originalSet = descriptor.set;
|
|
16729
|
+
try {
|
|
16730
|
+
Object.defineProperty(resultRecord, field, {
|
|
16731
|
+
configurable: descriptorOwner === resultRecord ? descriptor.configurable : true,
|
|
16732
|
+
enumerable: descriptor.enumerable,
|
|
16733
|
+
get() {
|
|
16734
|
+
const stream = originalGet.call(this);
|
|
16735
|
+
return isAsyncIterable(stream) ? patchAsyncIterable(stream) : stream;
|
|
16736
|
+
},
|
|
16737
|
+
...originalSet ? {
|
|
16738
|
+
set(value) {
|
|
16739
|
+
originalSet.call(this, value);
|
|
16740
|
+
}
|
|
16741
|
+
} : {}
|
|
16742
|
+
});
|
|
16743
|
+
return true;
|
|
16744
|
+
} catch {
|
|
16745
|
+
return false;
|
|
16746
|
+
}
|
|
16747
|
+
};
|
|
16748
|
+
let patched = false;
|
|
14975
16749
|
if (isReadableStreamLike(resultRecord.baseStream)) {
|
|
14976
|
-
let
|
|
14977
|
-
const
|
|
16750
|
+
let firstChunkTime;
|
|
16751
|
+
const transformedBaseStream = resultRecord.baseStream.pipeThrough(
|
|
14978
16752
|
new TransformStream({
|
|
14979
16753
|
transform(chunk, controller) {
|
|
14980
|
-
if (
|
|
14981
|
-
|
|
16754
|
+
if (firstChunkTime === void 0 && isAISDKContentStreamChunk(chunk)) {
|
|
16755
|
+
firstChunkTime = getCurrentUnixTimestamp();
|
|
14982
16756
|
}
|
|
14983
16757
|
controller.enqueue(chunk);
|
|
14984
16758
|
},
|
|
14985
16759
|
async flush() {
|
|
14986
|
-
|
|
14987
|
-
if (metrics.time_to_first_token === void 0 && firstChunkTime2 !== void 0) {
|
|
14988
|
-
metrics.time_to_first_token = firstChunkTime2 - startTime;
|
|
14989
|
-
}
|
|
14990
|
-
const output = await processAISDKStreamingOutput(
|
|
14991
|
-
result,
|
|
14992
|
-
resolveDenyOutputPaths(endEvent, defaultDenyOutputPaths)
|
|
14993
|
-
);
|
|
14994
|
-
const metadata = buildResolvedMetadataPayload(result).metadata;
|
|
14995
|
-
span.log({
|
|
14996
|
-
output,
|
|
14997
|
-
...metadata ? { metadata } : {},
|
|
14998
|
-
metrics
|
|
14999
|
-
});
|
|
15000
|
-
finalizeAISDKChildTracing(endEvent);
|
|
15001
|
-
span.end();
|
|
16760
|
+
await logStreamingOutput(firstChunkTime);
|
|
15002
16761
|
}
|
|
15003
16762
|
})
|
|
15004
16763
|
);
|
|
16764
|
+
const reader = transformedBaseStream.getReader();
|
|
16765
|
+
const wrappedBaseStream = new ReadableStream({
|
|
16766
|
+
async pull(controller) {
|
|
16767
|
+
try {
|
|
16768
|
+
const { done, value } = await reader.read();
|
|
16769
|
+
if (done) {
|
|
16770
|
+
controller.close();
|
|
16771
|
+
return;
|
|
16772
|
+
}
|
|
16773
|
+
controller.enqueue(value);
|
|
16774
|
+
} catch (error) {
|
|
16775
|
+
span.log({ error: toLoggedError(error) });
|
|
16776
|
+
finalize();
|
|
16777
|
+
controller.error(error);
|
|
16778
|
+
}
|
|
16779
|
+
},
|
|
16780
|
+
async cancel(reason) {
|
|
16781
|
+
try {
|
|
16782
|
+
finalize();
|
|
16783
|
+
} finally {
|
|
16784
|
+
await reader.cancel(reason);
|
|
16785
|
+
}
|
|
16786
|
+
}
|
|
16787
|
+
});
|
|
15005
16788
|
Object.defineProperty(resultRecord, "baseStream", {
|
|
15006
16789
|
configurable: true,
|
|
15007
16790
|
enumerable: true,
|
|
15008
16791
|
value: wrappedBaseStream,
|
|
15009
16792
|
writable: true
|
|
15010
16793
|
});
|
|
15011
|
-
|
|
16794
|
+
patched = true;
|
|
15012
16795
|
}
|
|
15013
|
-
const
|
|
16796
|
+
for (const field of [
|
|
15014
16797
|
"partialObjectStream",
|
|
15015
16798
|
"textStream",
|
|
15016
16799
|
"fullStream",
|
|
15017
16800
|
"stream"
|
|
15018
|
-
])
|
|
15019
|
-
|
|
15020
|
-
return false;
|
|
16801
|
+
]) {
|
|
16802
|
+
patched = patchAsyncIterableField(field) || patched;
|
|
15021
16803
|
}
|
|
15022
|
-
|
|
15023
|
-
const wrappedStream = createPatchedAsyncIterable(streamField.stream, {
|
|
15024
|
-
onChunk: (chunk) => {
|
|
15025
|
-
if (firstChunkTime === void 0 && isAISDKContentAsyncIterableChunk(chunk)) {
|
|
15026
|
-
firstChunkTime = getCurrentUnixTimestamp();
|
|
15027
|
-
}
|
|
15028
|
-
},
|
|
15029
|
-
onComplete: async () => {
|
|
15030
|
-
const metrics = extractTopLevelAISDKMetrics(result, endEvent);
|
|
15031
|
-
if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
|
|
15032
|
-
metrics.time_to_first_token = firstChunkTime - startTime;
|
|
15033
|
-
}
|
|
15034
|
-
const output = await processAISDKStreamingOutput(
|
|
15035
|
-
result,
|
|
15036
|
-
resolveDenyOutputPaths(endEvent, defaultDenyOutputPaths)
|
|
15037
|
-
);
|
|
15038
|
-
const metadata = buildResolvedMetadataPayload(result).metadata;
|
|
15039
|
-
span.log({
|
|
15040
|
-
output,
|
|
15041
|
-
...metadata ? { metadata } : {},
|
|
15042
|
-
metrics
|
|
15043
|
-
});
|
|
15044
|
-
finalizeAISDKChildTracing(endEvent);
|
|
15045
|
-
span.end();
|
|
15046
|
-
},
|
|
15047
|
-
onError: (error) => {
|
|
15048
|
-
span.log({
|
|
15049
|
-
error: error.message
|
|
15050
|
-
});
|
|
15051
|
-
finalizeAISDKChildTracing(endEvent);
|
|
15052
|
-
span.end();
|
|
15053
|
-
}
|
|
15054
|
-
});
|
|
15055
|
-
Object.defineProperty(resultRecord, streamField.field, {
|
|
15056
|
-
configurable: true,
|
|
15057
|
-
enumerable: true,
|
|
15058
|
-
value: wrappedStream,
|
|
15059
|
-
writable: true
|
|
15060
|
-
});
|
|
15061
|
-
return true;
|
|
16804
|
+
return patched;
|
|
15062
16805
|
}
|
|
15063
16806
|
function attachKnownResultPromiseHandlers(result) {
|
|
15064
16807
|
const promiseLikeFields = [
|
|
@@ -15090,34 +16833,72 @@ function attachKnownResultPromiseHandlers(result) {
|
|
|
15090
16833
|
}
|
|
15091
16834
|
}
|
|
15092
16835
|
function isReadableStreamLike(value) {
|
|
15093
|
-
return value != null && typeof value === "object" && typeof value.pipeThrough === "function";
|
|
15094
|
-
}
|
|
15095
|
-
function
|
|
15096
|
-
|
|
15097
|
-
|
|
15098
|
-
|
|
15099
|
-
|
|
15100
|
-
|
|
16836
|
+
return value != null && typeof value === "object" && typeof value.getReader === "function" && typeof value.pipeThrough === "function";
|
|
16837
|
+
}
|
|
16838
|
+
function createPatchedReadableStream(stream, hooks) {
|
|
16839
|
+
let reader;
|
|
16840
|
+
let completed = false;
|
|
16841
|
+
return new ReadableStream({
|
|
16842
|
+
async pull(controller) {
|
|
16843
|
+
reader ??= stream.getReader();
|
|
16844
|
+
try {
|
|
16845
|
+
const { done, value } = await reader.read();
|
|
16846
|
+
if (done) {
|
|
16847
|
+
completed = true;
|
|
16848
|
+
await hooks.onComplete();
|
|
16849
|
+
controller.close();
|
|
16850
|
+
return;
|
|
16851
|
+
}
|
|
16852
|
+
hooks.onChunk(value);
|
|
16853
|
+
controller.enqueue(value);
|
|
16854
|
+
} catch (error) {
|
|
16855
|
+
completed = true;
|
|
16856
|
+
hooks.onError(
|
|
16857
|
+
error instanceof Error ? error : new Error(String(error))
|
|
16858
|
+
);
|
|
16859
|
+
controller.error(error);
|
|
16860
|
+
}
|
|
16861
|
+
},
|
|
16862
|
+
async cancel(reason) {
|
|
16863
|
+
if (!completed) {
|
|
16864
|
+
completed = true;
|
|
16865
|
+
try {
|
|
16866
|
+
await hooks.onCancel?.();
|
|
16867
|
+
} catch {
|
|
16868
|
+
}
|
|
16869
|
+
}
|
|
16870
|
+
if (reader) {
|
|
16871
|
+
await reader.cancel(reason);
|
|
16872
|
+
} else if (stream.cancel) {
|
|
16873
|
+
await stream.cancel(reason);
|
|
15101
16874
|
}
|
|
15102
|
-
} catch {
|
|
15103
16875
|
}
|
|
15104
|
-
}
|
|
15105
|
-
return null;
|
|
16876
|
+
});
|
|
15106
16877
|
}
|
|
15107
16878
|
function createPatchedAsyncIterable(stream, hooks) {
|
|
15108
16879
|
return {
|
|
15109
16880
|
async *[Symbol.asyncIterator]() {
|
|
16881
|
+
let completed = false;
|
|
15110
16882
|
try {
|
|
15111
16883
|
for await (const chunk of stream) {
|
|
15112
16884
|
hooks.onChunk(chunk);
|
|
15113
16885
|
yield chunk;
|
|
15114
16886
|
}
|
|
16887
|
+
completed = true;
|
|
15115
16888
|
await hooks.onComplete();
|
|
15116
16889
|
} catch (error) {
|
|
16890
|
+
completed = true;
|
|
15117
16891
|
hooks.onError(
|
|
15118
16892
|
error instanceof Error ? error : new Error(String(error))
|
|
15119
16893
|
);
|
|
15120
16894
|
throw error;
|
|
16895
|
+
} finally {
|
|
16896
|
+
if (!completed) {
|
|
16897
|
+
try {
|
|
16898
|
+
await hooks.onCancel?.();
|
|
16899
|
+
} catch {
|
|
16900
|
+
}
|
|
16901
|
+
}
|
|
15121
16902
|
}
|
|
15122
16903
|
}
|
|
15123
16904
|
};
|
|
@@ -15192,6 +16973,40 @@ function buildResolvedMetadataPayload(result) {
|
|
|
15192
16973
|
}
|
|
15193
16974
|
return Object.keys(metadata).length > 0 ? { metadata } : {};
|
|
15194
16975
|
}
|
|
16976
|
+
function mergeMetadataPayload(metadataPayload, extraMetadata) {
|
|
16977
|
+
if (!extraMetadata || Object.keys(extraMetadata).length === 0) {
|
|
16978
|
+
return metadataPayload;
|
|
16979
|
+
}
|
|
16980
|
+
return {
|
|
16981
|
+
metadata: {
|
|
16982
|
+
...metadataPayload.metadata ?? {},
|
|
16983
|
+
...extraMetadata
|
|
16984
|
+
}
|
|
16985
|
+
};
|
|
16986
|
+
}
|
|
16987
|
+
function buildMissingUsageMetadata(output, metrics, reason) {
|
|
16988
|
+
if (!hasLoggedOutput(output) || hasTokenUsageMetrics(metrics)) {
|
|
16989
|
+
return void 0;
|
|
16990
|
+
}
|
|
16991
|
+
return { usage_unavailable_reason: reason };
|
|
16992
|
+
}
|
|
16993
|
+
function hasLoggedOutput(output) {
|
|
16994
|
+
if (output === null || output === void 0) {
|
|
16995
|
+
return false;
|
|
16996
|
+
}
|
|
16997
|
+
if (Array.isArray(output)) {
|
|
16998
|
+
return output.length > 0;
|
|
16999
|
+
}
|
|
17000
|
+
if (typeof output === "object") {
|
|
17001
|
+
return Object.keys(output).length > 0;
|
|
17002
|
+
}
|
|
17003
|
+
return true;
|
|
17004
|
+
}
|
|
17005
|
+
function hasTokenUsageMetrics(metrics) {
|
|
17006
|
+
return Object.keys(metrics).some(
|
|
17007
|
+
(key) => key !== "estimated_cost" && key !== "time_to_first_token"
|
|
17008
|
+
);
|
|
17009
|
+
}
|
|
15195
17010
|
function resolveAISDKModel(model, aiSDK) {
|
|
15196
17011
|
if (typeof model !== "string") {
|
|
15197
17012
|
return model;
|
|
@@ -15215,7 +17030,45 @@ function isAsyncGenerator(value) {
|
|
|
15215
17030
|
function processAISDKOutput(output, denyOutputPaths) {
|
|
15216
17031
|
if (!output) return output;
|
|
15217
17032
|
const merged = extractSerializableOutputFields(output);
|
|
15218
|
-
|
|
17033
|
+
const deleteOutputPaths = denyOutputPaths.filter(
|
|
17034
|
+
(path) => path.toLowerCase().endsWith("headers")
|
|
17035
|
+
);
|
|
17036
|
+
const sanitized = omit(merged, denyOutputPaths, deleteOutputPaths);
|
|
17037
|
+
for (const path of TRANSPORT_PAYLOAD_ROOT_PATHS) {
|
|
17038
|
+
const stack = [{ obj: sanitized, keys: parsePath(path) }];
|
|
17039
|
+
while (stack.length > 0) {
|
|
17040
|
+
const entry = stack.pop();
|
|
17041
|
+
if (!entry || entry.keys.length === 0) {
|
|
17042
|
+
continue;
|
|
17043
|
+
}
|
|
17044
|
+
const firstKey = entry.keys[0];
|
|
17045
|
+
const remainingKeys = entry.keys.slice(1);
|
|
17046
|
+
if (firstKey === "[]") {
|
|
17047
|
+
if (Array.isArray(entry.obj)) {
|
|
17048
|
+
for (const item of entry.obj) {
|
|
17049
|
+
stack.push({
|
|
17050
|
+
obj: item,
|
|
17051
|
+
keys: remainingKeys
|
|
17052
|
+
});
|
|
17053
|
+
}
|
|
17054
|
+
}
|
|
17055
|
+
continue;
|
|
17056
|
+
}
|
|
17057
|
+
if (!entry.obj || typeof entry.obj !== "object" || !(firstKey in entry.obj)) {
|
|
17058
|
+
continue;
|
|
17059
|
+
}
|
|
17060
|
+
const record = entry.obj;
|
|
17061
|
+
if (remainingKeys.length === 0) {
|
|
17062
|
+
record[firstKey] = sanitizeAISDKMetadataValue(record[firstKey]);
|
|
17063
|
+
continue;
|
|
17064
|
+
}
|
|
17065
|
+
stack.push({
|
|
17066
|
+
obj: record[firstKey],
|
|
17067
|
+
keys: remainingKeys
|
|
17068
|
+
});
|
|
17069
|
+
}
|
|
17070
|
+
}
|
|
17071
|
+
return normalizeAISDKLoggedOutput(sanitized);
|
|
15219
17072
|
}
|
|
15220
17073
|
function processAISDKEmbeddingOutput(output, denyOutputPaths) {
|
|
15221
17074
|
if (!output || typeof output !== "object") {
|
|
@@ -15306,6 +17159,8 @@ function extractTokenMetrics(result) {
|
|
|
15306
17159
|
);
|
|
15307
17160
|
if (totalTokens !== void 0) {
|
|
15308
17161
|
metrics.tokens = totalTokens;
|
|
17162
|
+
} else if (promptTokens !== void 0 && completionTokens !== void 0) {
|
|
17163
|
+
metrics.tokens = promptTokens + completionTokens;
|
|
15309
17164
|
}
|
|
15310
17165
|
const promptCachedTokens = firstNumber2(
|
|
15311
17166
|
usage.inputTokens?.cacheRead,
|
|
@@ -15417,9 +17272,9 @@ function aggregateAISDKChunks(chunks, _result, endEvent) {
|
|
|
15417
17272
|
if (finishReason !== void 0) {
|
|
15418
17273
|
output.finishReason = finishReason;
|
|
15419
17274
|
}
|
|
15420
|
-
const
|
|
15421
|
-
if (
|
|
15422
|
-
output.toolCalls =
|
|
17275
|
+
const toolCalls2 = safeSerializableFieldRead(lastChunk, "toolCalls");
|
|
17276
|
+
if (toolCalls2 !== void 0) {
|
|
17277
|
+
output.toolCalls = toolCalls2;
|
|
15423
17278
|
}
|
|
15424
17279
|
}
|
|
15425
17280
|
finalizeAISDKChildTracing(endEvent);
|
|
@@ -15429,7 +17284,9 @@ function extractGetterValues(obj) {
|
|
|
15429
17284
|
const getterValues = {};
|
|
15430
17285
|
const getterNames = [
|
|
15431
17286
|
"content",
|
|
17287
|
+
"messages",
|
|
15432
17288
|
"text",
|
|
17289
|
+
"output",
|
|
15433
17290
|
"object",
|
|
15434
17291
|
"value",
|
|
15435
17292
|
"values",
|
|
@@ -15469,7 +17326,9 @@ function extractGetterValues(obj) {
|
|
|
15469
17326
|
function extractSerializableOutputFields(output) {
|
|
15470
17327
|
const serialized = {};
|
|
15471
17328
|
const directFieldNames = [
|
|
17329
|
+
"messages",
|
|
15472
17330
|
"steps",
|
|
17331
|
+
"output",
|
|
15473
17332
|
"request",
|
|
15474
17333
|
"responseMessages",
|
|
15475
17334
|
"warnings",
|
|
@@ -15651,7 +17510,7 @@ function parsePath(path) {
|
|
|
15651
17510
|
}
|
|
15652
17511
|
return keys;
|
|
15653
17512
|
}
|
|
15654
|
-
function omitAtPath(obj, keys) {
|
|
17513
|
+
function omitAtPath(obj, keys, deleteLeaf = false) {
|
|
15655
17514
|
if (keys.length === 0) return;
|
|
15656
17515
|
const firstKey = keys[0];
|
|
15657
17516
|
const remainingKeys = keys.slice(1);
|
|
@@ -15661,29 +17520,36 @@ function omitAtPath(obj, keys) {
|
|
|
15661
17520
|
if (remainingKeys.length > 0) {
|
|
15662
17521
|
omitAtPath(
|
|
15663
17522
|
item,
|
|
15664
|
-
remainingKeys
|
|
17523
|
+
remainingKeys,
|
|
17524
|
+
deleteLeaf
|
|
15665
17525
|
);
|
|
15666
17526
|
}
|
|
15667
17527
|
});
|
|
15668
17528
|
}
|
|
15669
17529
|
} else if (remainingKeys.length === 0) {
|
|
15670
17530
|
if (obj && typeof obj === "object" && firstKey in obj) {
|
|
15671
|
-
|
|
17531
|
+
if (deleteLeaf) {
|
|
17532
|
+
delete obj[firstKey];
|
|
17533
|
+
} else {
|
|
17534
|
+
obj[firstKey] = "<omitted>";
|
|
17535
|
+
}
|
|
15672
17536
|
}
|
|
15673
17537
|
} else {
|
|
15674
17538
|
if (obj && typeof obj === "object" && firstKey in obj) {
|
|
15675
17539
|
omitAtPath(
|
|
15676
17540
|
obj[firstKey],
|
|
15677
|
-
remainingKeys
|
|
17541
|
+
remainingKeys,
|
|
17542
|
+
deleteLeaf
|
|
15678
17543
|
);
|
|
15679
17544
|
}
|
|
15680
17545
|
}
|
|
15681
17546
|
}
|
|
15682
|
-
function omit(obj, paths) {
|
|
17547
|
+
function omit(obj, paths, deletePaths = []) {
|
|
15683
17548
|
const result = deepCopy(obj);
|
|
17549
|
+
const deletePathSet = new Set(deletePaths);
|
|
15684
17550
|
for (const path of paths) {
|
|
15685
17551
|
const keys = parsePath(path);
|
|
15686
|
-
omitAtPath(result, keys);
|
|
17552
|
+
omitAtPath(result, keys, deletePathSet.has(path));
|
|
15687
17553
|
}
|
|
15688
17554
|
return result;
|
|
15689
17555
|
}
|
|
@@ -19892,8 +21758,8 @@ function getChatToolCallDeltas(value) {
|
|
|
19892
21758
|
if (!Array.isArray(value?.tool_calls)) {
|
|
19893
21759
|
return void 0;
|
|
19894
21760
|
}
|
|
19895
|
-
const
|
|
19896
|
-
return
|
|
21761
|
+
const toolCalls2 = value.tool_calls.filter((toolCall) => isObject(toolCall));
|
|
21762
|
+
return toolCalls2.length > 0 ? toolCalls2 : void 0;
|
|
19897
21763
|
}
|
|
19898
21764
|
function mergeChatToolCallDeltas(toolCallsByIndex, toolCallDeltas) {
|
|
19899
21765
|
for (const toolDelta of toolCallDeltas) {
|
|
@@ -21382,7 +23248,7 @@ function aggregateOpenRouterChatChunks(chunks) {
|
|
|
21382
23248
|
let reasoningContent = "";
|
|
21383
23249
|
let hasReasoningContent = false;
|
|
21384
23250
|
let reasoningDetails;
|
|
21385
|
-
let
|
|
23251
|
+
let toolCalls2;
|
|
21386
23252
|
let finishReason;
|
|
21387
23253
|
let metrics = {};
|
|
21388
23254
|
for (const chunk of chunks) {
|
|
@@ -21435,9 +23301,9 @@ function aggregateOpenRouterChatChunks(chunks) {
|
|
|
21435
23301
|
continue;
|
|
21436
23302
|
}
|
|
21437
23303
|
const toolIndex = toolDelta.index ?? 0;
|
|
21438
|
-
const existingToolCall =
|
|
23304
|
+
const existingToolCall = toolCalls2?.[toolIndex];
|
|
21439
23305
|
if (!existingToolCall || toolDelta.id && existingToolCall.id !== void 0 && existingToolCall.id !== toolDelta.id) {
|
|
21440
|
-
const nextToolCalls = [...
|
|
23306
|
+
const nextToolCalls = [...toolCalls2 || []];
|
|
21441
23307
|
nextToolCalls[toolIndex] = {
|
|
21442
23308
|
index: toolIndex,
|
|
21443
23309
|
id: toolDelta.id,
|
|
@@ -21447,7 +23313,7 @@ function aggregateOpenRouterChatChunks(chunks) {
|
|
|
21447
23313
|
arguments: toolDelta.function.arguments || ""
|
|
21448
23314
|
}
|
|
21449
23315
|
};
|
|
21450
|
-
|
|
23316
|
+
toolCalls2 = nextToolCalls;
|
|
21451
23317
|
continue;
|
|
21452
23318
|
}
|
|
21453
23319
|
const current = existingToolCall;
|
|
@@ -21473,7 +23339,7 @@ function aggregateOpenRouterChatChunks(chunks) {
|
|
|
21473
23339
|
...hasReasoning || hasReasoningContent ? { reasoning } : {},
|
|
21474
23340
|
...hasReasoningContent ? { reasoning_content: reasoningContent } : {},
|
|
21475
23341
|
...reasoningDetails ? { reasoning_details: reasoningDetails } : {},
|
|
21476
|
-
...
|
|
23342
|
+
...toolCalls2 ? { tool_calls: toolCalls2 } : {}
|
|
21477
23343
|
},
|
|
21478
23344
|
logprobs: null,
|
|
21479
23345
|
finish_reason: finishReason
|
|
@@ -22318,8 +24184,8 @@ function appendMistralContent(accumulator, content) {
|
|
|
22318
24184
|
delete accumulator.content;
|
|
22319
24185
|
}
|
|
22320
24186
|
function getDeltaToolCalls(delta) {
|
|
22321
|
-
const
|
|
22322
|
-
return
|
|
24187
|
+
const toolCalls2 = Array.isArray(delta.toolCalls) && delta.toolCalls || Array.isArray(delta.tool_calls) && delta.tool_calls || [];
|
|
24188
|
+
return toolCalls2.filter((toolCall) => isObject(toolCall));
|
|
22323
24189
|
}
|
|
22324
24190
|
function getToolCallIndex(toolCall) {
|
|
22325
24191
|
return typeof toolCall.index === "number" && toolCall.index >= 0 ? toolCall.index : void 0;
|
|
@@ -22346,11 +24212,11 @@ function mergeToolCallDeltaPair(current, delta) {
|
|
|
22346
24212
|
}
|
|
22347
24213
|
};
|
|
22348
24214
|
}
|
|
22349
|
-
function mergeToolCallDeltas(
|
|
24215
|
+
function mergeToolCallDeltas(toolCalls2, deltas) {
|
|
22350
24216
|
if (deltas.length === 0) {
|
|
22351
|
-
return
|
|
24217
|
+
return toolCalls2;
|
|
22352
24218
|
}
|
|
22353
|
-
const merged =
|
|
24219
|
+
const merged = toolCalls2 ? [...toolCalls2] : [];
|
|
22354
24220
|
const indexToPosition = /* @__PURE__ */ new Map();
|
|
22355
24221
|
const idToPosition = /* @__PURE__ */ new Map();
|
|
22356
24222
|
for (const [position, toolCall] of merged.entries()) {
|
|
@@ -23421,12 +25287,12 @@ function extractCohereChatOutput(result) {
|
|
|
23421
25287
|
if (typeof result.text !== "string") {
|
|
23422
25288
|
return void 0;
|
|
23423
25289
|
}
|
|
23424
|
-
const
|
|
23425
|
-
if (
|
|
25290
|
+
const toolCalls2 = Array.isArray(result.toolCalls) ? result.toolCalls : Array.isArray(result.tool_calls) ? result.tool_calls : void 0;
|
|
25291
|
+
if (toolCalls2 && toolCalls2.length > 0) {
|
|
23426
25292
|
return {
|
|
23427
25293
|
content: result.text,
|
|
23428
25294
|
role: "assistant",
|
|
23429
|
-
toolCalls
|
|
25295
|
+
toolCalls: toolCalls2
|
|
23430
25296
|
};
|
|
23431
25297
|
}
|
|
23432
25298
|
return result.text;
|
|
@@ -23759,10 +25625,10 @@ function aggregateCohereChatStreamChunks(chunks) {
|
|
|
23759
25625
|
continue;
|
|
23760
25626
|
}
|
|
23761
25627
|
if (eventType === "tool-call-start") {
|
|
23762
|
-
const
|
|
25628
|
+
const toolCalls2 = isObject(chunk.delta) && isObject(chunk.delta.message) ? toToolCallArray(
|
|
23763
25629
|
Array.isArray(chunk.delta.message.toolCalls) ? chunk.delta.message.toolCalls : chunk.delta.message.toolCalls ?? chunk.delta.message.tool_calls
|
|
23764
25630
|
) : [];
|
|
23765
|
-
for (const [index, toolCall] of
|
|
25631
|
+
for (const [index, toolCall] of toolCalls2.entries()) {
|
|
23766
25632
|
const normalizedIndex = getToolCallIndex2(
|
|
23767
25633
|
toolCall,
|
|
23768
25634
|
typeof chunk.index === "number" ? chunk.index : index
|
|
@@ -27837,14 +29703,14 @@ function normalizeAssistantMessage(message) {
|
|
|
27837
29703
|
const thinking = message.content.flatMap(
|
|
27838
29704
|
(part) => part.type === "thinking" && !part.redacted ? [part.thinking] : []
|
|
27839
29705
|
).join("");
|
|
27840
|
-
const
|
|
29706
|
+
const toolCalls2 = message.content.flatMap(
|
|
27841
29707
|
(part) => part.type === "toolCall" ? [normalizeToolCall(part)] : []
|
|
27842
29708
|
);
|
|
27843
29709
|
return {
|
|
27844
29710
|
role: "assistant",
|
|
27845
|
-
content: text || (
|
|
29711
|
+
content: text || (toolCalls2.length > 0 ? null : ""),
|
|
27846
29712
|
...thinking ? { reasoning: thinking } : {},
|
|
27847
|
-
...
|
|
29713
|
+
...toolCalls2.length > 0 ? { tool_calls: toolCalls2 } : {}
|
|
27848
29714
|
};
|
|
27849
29715
|
}
|
|
27850
29716
|
function normalizeToolResultMessage(message) {
|
|
@@ -29427,8 +31293,10 @@ var exports_exports = {};
|
|
|
29427
31293
|
__export(exports_exports, {
|
|
29428
31294
|
Attachment: () => Attachment,
|
|
29429
31295
|
AttachmentReference: () => AttachmentReference,
|
|
31296
|
+
BAGGAGE_HEADER: () => BAGGAGE_HEADER,
|
|
29430
31297
|
BRAINTRUST_CURRENT_SPAN_STORE: () => BRAINTRUST_CURRENT_SPAN_STORE,
|
|
29431
31298
|
BRAINTRUST_LANGCHAIN_CALLBACK_HANDLER_NAME: () => BRAINTRUST_LANGCHAIN_CALLBACK_HANDLER_NAME,
|
|
31299
|
+
BRAINTRUST_PARENT_KEY: () => BRAINTRUST_PARENT_KEY,
|
|
29432
31300
|
BaseAttachment: () => BaseAttachment,
|
|
29433
31301
|
BaseExperiment: () => BaseExperiment,
|
|
29434
31302
|
BraintrustLangChainCallbackHandler: () => BraintrustLangChainCallbackHandler,
|
|
@@ -29461,6 +31329,7 @@ __export(exports_exports, {
|
|
|
29461
31329
|
NOOP_SPAN: () => NOOP_SPAN,
|
|
29462
31330
|
NOOP_SPAN_PERMALINK: () => NOOP_SPAN_PERMALINK,
|
|
29463
31331
|
NoopSpan: () => NoopSpan,
|
|
31332
|
+
OTELIDGenerator: () => OTELIDGenerator,
|
|
29464
31333
|
ObjectFetcher: () => ObjectFetcher,
|
|
29465
31334
|
Project: () => Project2,
|
|
29466
31335
|
ProjectNameIdMap: () => ProjectNameIdMap,
|
|
@@ -29472,6 +31341,8 @@ __export(exports_exports, {
|
|
|
29472
31341
|
ScorerBuilder: () => ScorerBuilder,
|
|
29473
31342
|
SpanFetcher: () => SpanFetcher,
|
|
29474
31343
|
SpanImpl: () => SpanImpl,
|
|
31344
|
+
TRACEPARENT_HEADER: () => TRACEPARENT_HEADER,
|
|
31345
|
+
TRACESTATE_HEADER: () => TRACESTATE_HEADER,
|
|
29475
31346
|
TestBackgroundLogger: () => TestBackgroundLogger,
|
|
29476
31347
|
ToolBuilder: () => ToolBuilder,
|
|
29477
31348
|
UUIDGenerator: () => UUIDGenerator,
|
|
@@ -29481,6 +31352,7 @@ __export(exports_exports, {
|
|
|
29481
31352
|
_internalIso: () => isomorph_default,
|
|
29482
31353
|
_internalSetInitialState: () => _internalSetInitialState,
|
|
29483
31354
|
addAzureBlobHeaders: () => addAzureBlobHeaders,
|
|
31355
|
+
agentAssertionScorer: () => agentAssertionScorer,
|
|
29484
31356
|
braintrustAISDKTelemetry: () => braintrustAISDKTelemetry,
|
|
29485
31357
|
braintrustFlueInstrumentation: () => braintrustFlueInstrumentation,
|
|
29486
31358
|
braintrustFlueObserver: () => braintrustFlueObserver,
|
|
@@ -29498,6 +31370,7 @@ __export(exports_exports, {
|
|
|
29498
31370
|
devNullWritableStream: () => devNullWritableStream,
|
|
29499
31371
|
evaluatorDefinitionSchema: () => evaluatorDefinitionSchema,
|
|
29500
31372
|
evaluatorDefinitionsSchema: () => evaluatorDefinitionsSchema,
|
|
31373
|
+
extractTraceContextFromHeaders: () => extractTraceContextFromHeaders,
|
|
29501
31374
|
flush: () => flush,
|
|
29502
31375
|
getContextManager: () => getContextManager,
|
|
29503
31376
|
getIdGenerator: () => getIdGenerator,
|
|
@@ -29511,6 +31384,7 @@ __export(exports_exports, {
|
|
|
29511
31384
|
initFunction: () => initFunction,
|
|
29512
31385
|
initLogger: () => initLogger,
|
|
29513
31386
|
initNodeTestSuite: () => initNodeTestSuite,
|
|
31387
|
+
injectTraceContext: () => injectTraceContext,
|
|
29514
31388
|
invoke: () => invoke,
|
|
29515
31389
|
isTemplateFormat: () => isTemplateFormat,
|
|
29516
31390
|
loadParameters: () => loadParameters,
|
|
@@ -29549,7 +31423,7 @@ __export(exports_exports, {
|
|
|
29549
31423
|
traced: () => traced,
|
|
29550
31424
|
updateSpan: () => updateSpan,
|
|
29551
31425
|
uploadLogs3OverflowPayload: () => uploadLogs3OverflowPayload,
|
|
29552
|
-
utf8ByteLength: () =>
|
|
31426
|
+
utf8ByteLength: () => utf8ByteLength2,
|
|
29553
31427
|
withCurrent: () => withCurrent,
|
|
29554
31428
|
withDataset: () => withDataset,
|
|
29555
31429
|
withExperiment: () => withExperiment,
|
|
@@ -30142,6 +32016,7 @@ function wrapAISDK(aiSDK, options = {}) {
|
|
|
30142
32016
|
case "Agent":
|
|
30143
32017
|
case "Experimental_Agent":
|
|
30144
32018
|
case "ToolLoopAgent":
|
|
32019
|
+
case "WorkflowAgent":
|
|
30145
32020
|
return original ? wrapAgentClass(original, options) : original;
|
|
30146
32021
|
}
|
|
30147
32022
|
return original;
|
|
@@ -30160,10 +32035,10 @@ var wrapAgentClass = (AgentClass, options = {}) => {
|
|
|
30160
32035
|
return new Proxy(instance, {
|
|
30161
32036
|
get(instanceTarget, prop, instanceReceiver) {
|
|
30162
32037
|
const original = Reflect.get(instanceTarget, prop, instanceTarget);
|
|
30163
|
-
if (prop === "generate") {
|
|
32038
|
+
if (prop === "generate" && typeof original === "function" && instanceTarget.constructor.name !== "WorkflowAgent") {
|
|
30164
32039
|
return wrapAgentGenerate(original, instanceTarget, options);
|
|
30165
32040
|
}
|
|
30166
|
-
if (prop === "stream") {
|
|
32041
|
+
if (prop === "stream" && typeof original === "function") {
|
|
30167
32042
|
return wrapAgentStream(original, instanceTarget, options);
|
|
30168
32043
|
}
|
|
30169
32044
|
if (typeof original === "function") {
|
|
@@ -30178,7 +32053,7 @@ var wrapAgentClass = (AgentClass, options = {}) => {
|
|
|
30178
32053
|
var wrapAgentGenerate = (generate, instance, options = {}) => {
|
|
30179
32054
|
const defaultName = `${instance.constructor.name}.generate`;
|
|
30180
32055
|
return async (params) => makeGenerateTextWrapper(
|
|
30181
|
-
|
|
32056
|
+
generateChannelForAgent(instance.constructor.name),
|
|
30182
32057
|
defaultName,
|
|
30183
32058
|
generate.bind(instance),
|
|
30184
32059
|
{
|
|
@@ -30188,19 +32063,42 @@ var wrapAgentGenerate = (generate, instance, options = {}) => {
|
|
|
30188
32063
|
options
|
|
30189
32064
|
)({ ...instance.settings, ...params });
|
|
30190
32065
|
};
|
|
32066
|
+
function generateChannelForAgent(agentName) {
|
|
32067
|
+
if (agentName === "ToolLoopAgent") {
|
|
32068
|
+
return aiSDKChannels.toolLoopAgentGenerate;
|
|
32069
|
+
}
|
|
32070
|
+
return aiSDKChannels.agentGenerate;
|
|
32071
|
+
}
|
|
30191
32072
|
var wrapAgentStream = (stream, instance, options = {}) => {
|
|
30192
32073
|
const defaultName = `${instance.constructor.name}.stream`;
|
|
30193
|
-
return (params) =>
|
|
30194
|
-
|
|
30195
|
-
|
|
30196
|
-
|
|
30197
|
-
|
|
30198
|
-
|
|
30199
|
-
|
|
30200
|
-
|
|
30201
|
-
|
|
30202
|
-
|
|
32074
|
+
return (params) => {
|
|
32075
|
+
const workflowAgent = instance.constructor.name === "WorkflowAgent";
|
|
32076
|
+
if (workflowAgent && currentWorkflowAgentWrapperSpan()) {
|
|
32077
|
+
const { span_info: _spanInfo, ...cleanParams } = params;
|
|
32078
|
+
return stream.call(instance, { ...instance.settings, ...cleanParams });
|
|
32079
|
+
}
|
|
32080
|
+
const trace = () => makeStreamWrapper(
|
|
32081
|
+
streamChannelForAgent(instance.constructor.name),
|
|
32082
|
+
defaultName,
|
|
32083
|
+
stream.bind(instance),
|
|
32084
|
+
{
|
|
32085
|
+
self: instance,
|
|
32086
|
+
spanType: "function" /* FUNCTION */
|
|
32087
|
+
},
|
|
32088
|
+
options
|
|
32089
|
+
)({ ...instance.settings, ...params });
|
|
32090
|
+
return trace();
|
|
32091
|
+
};
|
|
30203
32092
|
};
|
|
32093
|
+
function streamChannelForAgent(agentName) {
|
|
32094
|
+
if (agentName === "ToolLoopAgent") {
|
|
32095
|
+
return aiSDKChannels.toolLoopAgentStream;
|
|
32096
|
+
}
|
|
32097
|
+
if (agentName === "WorkflowAgent") {
|
|
32098
|
+
return aiSDKChannels.workflowAgentStream;
|
|
32099
|
+
}
|
|
32100
|
+
return aiSDKChannels.agentStream;
|
|
32101
|
+
}
|
|
30204
32102
|
var makeGenerateTextWrapper = (channel2, name, generateText, contextOptions = {}, options = {}) => {
|
|
30205
32103
|
const wrapper = async function(allParams) {
|
|
30206
32104
|
const { span_info, ...params } = allParams;
|
|
@@ -30462,7 +32360,7 @@ var BraintrustLanguageModelWrapper = class {
|
|
|
30462
32360
|
let time_to_first_token = void 0;
|
|
30463
32361
|
let usage = void 0;
|
|
30464
32362
|
let fullText = void 0;
|
|
30465
|
-
const
|
|
32363
|
+
const toolCalls2 = {};
|
|
30466
32364
|
let finishReason = void 0;
|
|
30467
32365
|
return {
|
|
30468
32366
|
...ret,
|
|
@@ -30481,7 +32379,7 @@ var BraintrustLanguageModelWrapper = class {
|
|
|
30481
32379
|
fullText += chunk.textDelta;
|
|
30482
32380
|
break;
|
|
30483
32381
|
case "tool-call":
|
|
30484
|
-
|
|
32382
|
+
toolCalls2[chunk.toolCallId] = {
|
|
30485
32383
|
toolCallType: chunk.toolCallType,
|
|
30486
32384
|
toolCallId: chunk.toolCallId,
|
|
30487
32385
|
toolName: chunk.toolName,
|
|
@@ -30489,15 +32387,15 @@ var BraintrustLanguageModelWrapper = class {
|
|
|
30489
32387
|
};
|
|
30490
32388
|
break;
|
|
30491
32389
|
case "tool-call-delta":
|
|
30492
|
-
if (
|
|
30493
|
-
|
|
32390
|
+
if (toolCalls2[chunk.toolCallId] === void 0) {
|
|
32391
|
+
toolCalls2[chunk.toolCallId] = {
|
|
30494
32392
|
toolCallType: chunk.toolCallType,
|
|
30495
32393
|
toolCallId: chunk.toolCallId,
|
|
30496
32394
|
toolName: chunk.toolName,
|
|
30497
32395
|
args: ""
|
|
30498
32396
|
};
|
|
30499
32397
|
}
|
|
30500
|
-
|
|
32398
|
+
toolCalls2[chunk.toolCallId].args += chunk.argsTextDelta;
|
|
30501
32399
|
break;
|
|
30502
32400
|
case "finish":
|
|
30503
32401
|
usage = chunk.usage;
|
|
@@ -30510,7 +32408,7 @@ var BraintrustLanguageModelWrapper = class {
|
|
|
30510
32408
|
span.log({
|
|
30511
32409
|
output: postProcessOutput(
|
|
30512
32410
|
fullText,
|
|
30513
|
-
Object.keys(
|
|
32411
|
+
Object.keys(toolCalls2).length > 0 ? Object.values(toolCalls2) : void 0,
|
|
30514
32412
|
finishReason
|
|
30515
32413
|
),
|
|
30516
32414
|
metrics: {
|
|
@@ -30611,15 +32509,15 @@ function postProcessPrompt(prompt) {
|
|
|
30611
32509
|
}
|
|
30612
32510
|
});
|
|
30613
32511
|
}
|
|
30614
|
-
function postProcessOutput(text,
|
|
32512
|
+
function postProcessOutput(text, toolCalls2, finishReason) {
|
|
30615
32513
|
return [
|
|
30616
32514
|
{
|
|
30617
32515
|
index: 0,
|
|
30618
32516
|
message: {
|
|
30619
32517
|
role: "assistant",
|
|
30620
32518
|
content: text ?? "",
|
|
30621
|
-
...
|
|
30622
|
-
tool_calls:
|
|
32519
|
+
...toolCalls2 && toolCalls2.length > 0 ? {
|
|
32520
|
+
tool_calls: toolCalls2.map((toolCall) => ({
|
|
30623
32521
|
id: toolCall.toolCallId,
|
|
30624
32522
|
function: {
|
|
30625
32523
|
name: toolCall.toolName,
|
|
@@ -30718,29 +32616,29 @@ function normalizeFinishReason(reason) {
|
|
|
30718
32616
|
if (typeof reason !== "string") return void 0;
|
|
30719
32617
|
return reason.replace(/-/g, "_");
|
|
30720
32618
|
}
|
|
30721
|
-
function buildAssistantOutputWithToolCalls(result,
|
|
32619
|
+
function buildAssistantOutputWithToolCalls(result, toolCalls2) {
|
|
30722
32620
|
return [
|
|
30723
32621
|
{
|
|
30724
32622
|
index: 0,
|
|
30725
32623
|
logprobs: null,
|
|
30726
|
-
finish_reason: normalizeFinishReason(result?.finishReason) ?? (
|
|
32624
|
+
finish_reason: normalizeFinishReason(result?.finishReason) ?? (toolCalls2.length ? "tool_calls" : void 0),
|
|
30727
32625
|
message: {
|
|
30728
32626
|
role: "assistant",
|
|
30729
|
-
tool_calls:
|
|
32627
|
+
tool_calls: toolCalls2.length > 0 ? toolCalls2 : void 0
|
|
30730
32628
|
}
|
|
30731
32629
|
}
|
|
30732
32630
|
];
|
|
30733
32631
|
}
|
|
30734
32632
|
function extractToolCallsFromSteps(steps) {
|
|
30735
|
-
const
|
|
30736
|
-
if (!Array.isArray(steps)) return
|
|
32633
|
+
const toolCalls2 = [];
|
|
32634
|
+
if (!Array.isArray(steps)) return toolCalls2;
|
|
30737
32635
|
let idx = 0;
|
|
30738
32636
|
for (const step of steps) {
|
|
30739
32637
|
const blocks = step?.content;
|
|
30740
32638
|
if (!Array.isArray(blocks)) continue;
|
|
30741
32639
|
for (const block of blocks) {
|
|
30742
32640
|
if (block && typeof block === "object" && block.type === "tool-call") {
|
|
30743
|
-
|
|
32641
|
+
toolCalls2.push({
|
|
30744
32642
|
id: block.toolCallId,
|
|
30745
32643
|
type: "function",
|
|
30746
32644
|
index: idx++,
|
|
@@ -30752,7 +32650,7 @@ function extractToolCallsFromSteps(steps) {
|
|
|
30752
32650
|
}
|
|
30753
32651
|
}
|
|
30754
32652
|
}
|
|
30755
|
-
return
|
|
32653
|
+
return toolCalls2;
|
|
30756
32654
|
}
|
|
30757
32655
|
function extractToolCallsFromBlocks(blocks) {
|
|
30758
32656
|
if (!Array.isArray(blocks)) return [];
|
|
@@ -30818,12 +32716,12 @@ function BraintrustMiddleware(config = {}) {
|
|
|
30818
32716
|
metadata.model = modelId;
|
|
30819
32717
|
}
|
|
30820
32718
|
}
|
|
30821
|
-
let
|
|
30822
|
-
if (!
|
|
30823
|
-
|
|
32719
|
+
let toolCalls2 = extractToolCallsFromSteps(result?.steps);
|
|
32720
|
+
if (!toolCalls2 || toolCalls2.length === 0) {
|
|
32721
|
+
toolCalls2 = extractToolCallsFromBlocks(result?.content);
|
|
30824
32722
|
}
|
|
30825
32723
|
span.log({
|
|
30826
|
-
output:
|
|
32724
|
+
output: toolCalls2.length > 0 ? buildAssistantOutputWithToolCalls(result, toolCalls2) : result?.content,
|
|
30827
32725
|
metadata,
|
|
30828
32726
|
metrics: normalizeUsageMetrics(
|
|
30829
32727
|
result.usage,
|
|
@@ -30912,13 +32810,13 @@ function BraintrustMiddleware(config = {}) {
|
|
|
30912
32810
|
metadata.model = model;
|
|
30913
32811
|
}
|
|
30914
32812
|
if (toolBlocks.length > 0) {
|
|
30915
|
-
const
|
|
32813
|
+
const toolCalls2 = extractToolCallsFromSteps([
|
|
30916
32814
|
{ content: toolBlocks }
|
|
30917
32815
|
]);
|
|
30918
|
-
if (
|
|
32816
|
+
if (toolCalls2.length > 0) {
|
|
30919
32817
|
output = buildAssistantOutputWithToolCalls(
|
|
30920
32818
|
resultForDetection,
|
|
30921
|
-
|
|
32819
|
+
toolCalls2
|
|
30922
32820
|
);
|
|
30923
32821
|
}
|
|
30924
32822
|
}
|
|
@@ -31553,9 +33451,9 @@ function isModuleNamespace3(obj) {
|
|
|
31553
33451
|
const descriptor = Object.getOwnPropertyDescriptor(obj, keys[0]);
|
|
31554
33452
|
return descriptor ? !descriptor.configurable && !descriptor.writable : false;
|
|
31555
33453
|
}
|
|
31556
|
-
function wrapCursorAgentClass(
|
|
33454
|
+
function wrapCursorAgentClass(Agent2) {
|
|
31557
33455
|
const cache = /* @__PURE__ */ new Map();
|
|
31558
|
-
return new Proxy(
|
|
33456
|
+
return new Proxy(Agent2, {
|
|
31559
33457
|
get(target, prop, receiver) {
|
|
31560
33458
|
if (cache.has(prop)) {
|
|
31561
33459
|
return cache.get(prop);
|
|
@@ -35103,15 +37001,21 @@ var waterfall$1 = awaitify(waterfall);
|
|
|
35103
37001
|
|
|
35104
37002
|
// src/trace.ts
|
|
35105
37003
|
var SpanFetcher = class _SpanFetcher extends ObjectFetcher {
|
|
35106
|
-
constructor(objectType, _objectId, rootSpanId, _state, spanTypeFilter, includeScorers = false) {
|
|
37004
|
+
constructor(objectType, _objectId, rootSpanId, _state, spanTypeFilter, includeScorers = false, brainstoreRealtime = true) {
|
|
35107
37005
|
const filterExpr = _SpanFetcher.buildFilter(
|
|
35108
37006
|
rootSpanId,
|
|
35109
37007
|
spanTypeFilter,
|
|
35110
37008
|
includeScorers
|
|
35111
37009
|
);
|
|
35112
|
-
super(
|
|
35113
|
-
|
|
35114
|
-
|
|
37010
|
+
super(
|
|
37011
|
+
objectType,
|
|
37012
|
+
void 0,
|
|
37013
|
+
void 0,
|
|
37014
|
+
{
|
|
37015
|
+
filter: filterExpr
|
|
37016
|
+
},
|
|
37017
|
+
brainstoreRealtime
|
|
37018
|
+
);
|
|
35115
37019
|
this._objectId = _objectId;
|
|
35116
37020
|
this.rootSpanId = rootSpanId;
|
|
35117
37021
|
this._state = _state;
|
|
@@ -35165,7 +37069,7 @@ var CachedSpanFetcher = class {
|
|
|
35165
37069
|
spanCache = /* @__PURE__ */ new Map();
|
|
35166
37070
|
allFetched = false;
|
|
35167
37071
|
fetchFn;
|
|
35168
|
-
constructor(objectTypeOrFetchFn, objectId, rootSpanId, getState) {
|
|
37072
|
+
constructor(objectTypeOrFetchFn, objectId, rootSpanId, getState, brainstoreRealtime = true) {
|
|
35169
37073
|
if (typeof objectTypeOrFetchFn === "function") {
|
|
35170
37074
|
this.fetchFn = (spanType) => objectTypeOrFetchFn(spanType);
|
|
35171
37075
|
} else {
|
|
@@ -35178,7 +37082,8 @@ var CachedSpanFetcher = class {
|
|
|
35178
37082
|
rootSpanId,
|
|
35179
37083
|
state,
|
|
35180
37084
|
spanType,
|
|
35181
|
-
includeScorers
|
|
37085
|
+
includeScorers,
|
|
37086
|
+
brainstoreRealtime
|
|
35182
37087
|
);
|
|
35183
37088
|
const rows = await fetcher.fetchedData();
|
|
35184
37089
|
return rows.map((row) => ({
|
|
@@ -36008,7 +37913,7 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
|
|
|
36008
37913
|
}
|
|
36009
37914
|
};
|
|
36010
37915
|
const parentStr = state.currentParent.getStore();
|
|
36011
|
-
const parentComponents = parentStr ?
|
|
37916
|
+
const parentComponents = typeof parentStr === "string" ? SpanComponentsV4.fromStr(parentStr) : null;
|
|
36012
37917
|
const trace = state ? new LocalTrace({
|
|
36013
37918
|
objectType: parentComponents ? spanObjectTypeV3ToTypedString(
|
|
36014
37919
|
parentComponents.data.object_type
|
|
@@ -36534,6 +38439,350 @@ var defaultReporter = {
|
|
|
36534
38439
|
}
|
|
36535
38440
|
};
|
|
36536
38441
|
|
|
38442
|
+
// src/agent-assertions.ts
|
|
38443
|
+
function agentAssertionScorer(callback, options = {}) {
|
|
38444
|
+
return async (args) => {
|
|
38445
|
+
const { trace: _trace, ...callbackArgs } = args;
|
|
38446
|
+
const callbackMetadata = callbackArgs.metadata ?? {};
|
|
38447
|
+
const assertions = await callback({
|
|
38448
|
+
...callbackArgs,
|
|
38449
|
+
metadata: callbackMetadata,
|
|
38450
|
+
assert: agentAssertionHelpers
|
|
38451
|
+
});
|
|
38452
|
+
const resources = {};
|
|
38453
|
+
if (assertions.some((assertion) => assertion.requiresTrace)) {
|
|
38454
|
+
resources.spans = await args.trace?.getSpans({ spanType: ["tool"] });
|
|
38455
|
+
}
|
|
38456
|
+
const results = await Promise.all(
|
|
38457
|
+
assertions.map(async (assertion) => {
|
|
38458
|
+
const result = await assertion.evaluate(resources);
|
|
38459
|
+
return {
|
|
38460
|
+
name: assertion.name,
|
|
38461
|
+
passed: result.passed,
|
|
38462
|
+
failure: result.failure
|
|
38463
|
+
};
|
|
38464
|
+
})
|
|
38465
|
+
);
|
|
38466
|
+
const passed = results.filter((result) => result.passed).length;
|
|
38467
|
+
const total = results.length;
|
|
38468
|
+
const failed = results.filter((result) => !result.passed).map(
|
|
38469
|
+
(result) => `${result.name}: ${result.failure ?? "assertion did not pass"}`
|
|
38470
|
+
);
|
|
38471
|
+
return {
|
|
38472
|
+
name: options.name ?? "assertions",
|
|
38473
|
+
score: total === 0 ? 1 : passed / total,
|
|
38474
|
+
metadata: {
|
|
38475
|
+
assertions: results.map(({ name, passed: passed2 }) => ({ name, passed: passed2 })),
|
|
38476
|
+
failed
|
|
38477
|
+
}
|
|
38478
|
+
};
|
|
38479
|
+
};
|
|
38480
|
+
}
|
|
38481
|
+
var agentAssertionHelpers = {
|
|
38482
|
+
equals: (actual, expected, name = "equals") => ({
|
|
38483
|
+
name,
|
|
38484
|
+
evaluate: () => {
|
|
38485
|
+
const passed = deepEqual(actual, expected);
|
|
38486
|
+
return {
|
|
38487
|
+
passed,
|
|
38488
|
+
failure: passed ? void 0 : `expected ${formatValue(actual)} to equal ${formatValue(expected)}`
|
|
38489
|
+
};
|
|
38490
|
+
}
|
|
38491
|
+
}),
|
|
38492
|
+
notEquals: (actual, expected, name = "not equals") => ({
|
|
38493
|
+
name,
|
|
38494
|
+
evaluate: () => {
|
|
38495
|
+
const passed = !deepEqual(actual, expected);
|
|
38496
|
+
return {
|
|
38497
|
+
passed,
|
|
38498
|
+
failure: passed ? void 0 : `expected ${formatValue(actual)} not to equal ${formatValue(expected)}`
|
|
38499
|
+
};
|
|
38500
|
+
}
|
|
38501
|
+
}),
|
|
38502
|
+
contains: (value, expected, name = "contains") => ({
|
|
38503
|
+
name,
|
|
38504
|
+
evaluate: () => {
|
|
38505
|
+
const searchedValue = typeof value === "string" ? value : formatValue(value);
|
|
38506
|
+
const passed = expected instanceof RegExp ? testRegex(expected, value) : searchedValue.includes(expected);
|
|
38507
|
+
return {
|
|
38508
|
+
passed,
|
|
38509
|
+
failure: passed ? void 0 : `expected ${formatValue(value)} to contain ${formatValue(expected)}`
|
|
38510
|
+
};
|
|
38511
|
+
}
|
|
38512
|
+
}),
|
|
38513
|
+
matches: (value, schema, name = "matches schema") => ({
|
|
38514
|
+
name,
|
|
38515
|
+
evaluate: async () => {
|
|
38516
|
+
const result = await validateSchema(schema, value);
|
|
38517
|
+
return {
|
|
38518
|
+
passed: result.passed,
|
|
38519
|
+
failure: result.passed ? void 0 : `expected value to match schema: ${result.message}`
|
|
38520
|
+
};
|
|
38521
|
+
}
|
|
38522
|
+
}),
|
|
38523
|
+
calledTool: (toolName, options = {}, name = `called tool ${toolName}`) => ({
|
|
38524
|
+
name,
|
|
38525
|
+
requiresTrace: true,
|
|
38526
|
+
evaluate: ({ spans }) => {
|
|
38527
|
+
const calls = matchingToolCalls(spans ?? [], toolName, options);
|
|
38528
|
+
const passed = options.times === void 0 ? calls.length > 0 : calls.length === options.times;
|
|
38529
|
+
return {
|
|
38530
|
+
passed,
|
|
38531
|
+
failure: passed ? void 0 : options.times === void 0 ? `expected tool "${toolName}" to be called; found ${calls.length} matching call${calls.length === 1 ? "" : "s"}` : `expected tool "${toolName}" to be called ${options.times} time${options.times === 1 ? "" : "s"}; found ${calls.length} matching call${calls.length === 1 ? "" : "s"}`
|
|
38532
|
+
};
|
|
38533
|
+
}
|
|
38534
|
+
}),
|
|
38535
|
+
notCalledTool: (toolName, name = `did not call tool ${toolName}`) => ({
|
|
38536
|
+
name,
|
|
38537
|
+
requiresTrace: true,
|
|
38538
|
+
evaluate: ({ spans }) => {
|
|
38539
|
+
const calls = toolCalls(spans ?? []).filter(
|
|
38540
|
+
(span) => getToolName(span) === toolName
|
|
38541
|
+
);
|
|
38542
|
+
const passed = calls.length === 0;
|
|
38543
|
+
return {
|
|
38544
|
+
passed,
|
|
38545
|
+
failure: passed ? void 0 : `expected tool "${toolName}" not to be called; found ${calls.length} call${calls.length === 1 ? "" : "s"}`
|
|
38546
|
+
};
|
|
38547
|
+
}
|
|
38548
|
+
}),
|
|
38549
|
+
toolOrder: (toolNames, name = "tool order") => ({
|
|
38550
|
+
name,
|
|
38551
|
+
requiresTrace: true,
|
|
38552
|
+
evaluate: ({ spans }) => {
|
|
38553
|
+
const observed = toolCalls(spans ?? []).map(getToolName).filter((toolName) => toolName !== void 0);
|
|
38554
|
+
let fromIndex = 0;
|
|
38555
|
+
const passed = toolNames.every((toolName) => {
|
|
38556
|
+
const index = observed.indexOf(toolName, fromIndex);
|
|
38557
|
+
if (index === -1) return false;
|
|
38558
|
+
fromIndex = index + 1;
|
|
38559
|
+
return true;
|
|
38560
|
+
});
|
|
38561
|
+
return {
|
|
38562
|
+
passed,
|
|
38563
|
+
failure: passed ? void 0 : `expected tool order ${toolNames.join(" -> ")}; observed ${observed.join(" -> ") || "no tools"}`
|
|
38564
|
+
};
|
|
38565
|
+
}
|
|
38566
|
+
}),
|
|
38567
|
+
usedNoTools: (name = "used no tools") => ({
|
|
38568
|
+
name,
|
|
38569
|
+
requiresTrace: true,
|
|
38570
|
+
evaluate: ({ spans }) => {
|
|
38571
|
+
const calls = toolCalls(spans ?? []);
|
|
38572
|
+
const passed = calls.length === 0;
|
|
38573
|
+
return {
|
|
38574
|
+
passed,
|
|
38575
|
+
failure: passed ? void 0 : `expected no tool calls; found ${calls.length}`
|
|
38576
|
+
};
|
|
38577
|
+
}
|
|
38578
|
+
}),
|
|
38579
|
+
maxToolCalls: (max, name = `at most ${max} tool calls`) => ({
|
|
38580
|
+
name,
|
|
38581
|
+
requiresTrace: true,
|
|
38582
|
+
evaluate: ({ spans }) => {
|
|
38583
|
+
const calls = toolCalls(spans ?? []);
|
|
38584
|
+
const passed = calls.length <= max;
|
|
38585
|
+
return {
|
|
38586
|
+
passed,
|
|
38587
|
+
failure: passed ? void 0 : `expected at most ${max} tool call${max === 1 ? "" : "s"}; found ${calls.length}`
|
|
38588
|
+
};
|
|
38589
|
+
}
|
|
38590
|
+
})
|
|
38591
|
+
};
|
|
38592
|
+
async function validateSchema(schema, value) {
|
|
38593
|
+
try {
|
|
38594
|
+
if ("safeParse" in schema) {
|
|
38595
|
+
const result2 = schema.safeParse(value);
|
|
38596
|
+
return result2.success ? { passed: true, message: "" } : { passed: false, message: formatSchemaError(result2.error) };
|
|
38597
|
+
}
|
|
38598
|
+
if ("parse" in schema) {
|
|
38599
|
+
schema.parse(value);
|
|
38600
|
+
return { passed: true, message: "" };
|
|
38601
|
+
}
|
|
38602
|
+
const result = await schema["~standard"].validate(value);
|
|
38603
|
+
if (typeof result === "object" && result !== null && "issues" in result && Array.isArray(result.issues) && result.issues.length > 0) {
|
|
38604
|
+
return { passed: false, message: formatValue(result.issues) };
|
|
38605
|
+
}
|
|
38606
|
+
return { passed: true, message: "" };
|
|
38607
|
+
} catch (e) {
|
|
38608
|
+
return { passed: false, message: formatSchemaError(e) };
|
|
38609
|
+
}
|
|
38610
|
+
}
|
|
38611
|
+
function toolCalls(spans) {
|
|
38612
|
+
return spans.filter((span) => span.span_attributes?.type === "tool");
|
|
38613
|
+
}
|
|
38614
|
+
function matchingToolCalls(spans, toolName, options) {
|
|
38615
|
+
return toolCalls(spans).filter((span) => {
|
|
38616
|
+
if (getToolName(span) !== toolName) return false;
|
|
38617
|
+
if (Object.prototype.hasOwnProperty.call(options, "input") && !matchesValue(span.input, options.input)) {
|
|
38618
|
+
return false;
|
|
38619
|
+
}
|
|
38620
|
+
if (Object.prototype.hasOwnProperty.call(options, "output") && !matchesValue(span.output, options.output)) {
|
|
38621
|
+
return false;
|
|
38622
|
+
}
|
|
38623
|
+
if (options.isError !== void 0 && Boolean(span.error) !== options.isError) {
|
|
38624
|
+
return false;
|
|
38625
|
+
}
|
|
38626
|
+
return true;
|
|
38627
|
+
});
|
|
38628
|
+
}
|
|
38629
|
+
function getToolName(span) {
|
|
38630
|
+
const spanName = [span.span_attributes?.name, span.name].map(normalizeToolName).find((value) => value !== void 0);
|
|
38631
|
+
if (spanName?.includes("/")) {
|
|
38632
|
+
return spanName;
|
|
38633
|
+
}
|
|
38634
|
+
const metadataName = [
|
|
38635
|
+
span.metadata?.tool_name,
|
|
38636
|
+
span.metadata?.["gen_ai.tool.name"]
|
|
38637
|
+
].map(normalizeToolName).find((value) => value !== void 0);
|
|
38638
|
+
const mcpServer = [
|
|
38639
|
+
span.metadata?.["mcp.server"],
|
|
38640
|
+
span.metadata?.["openai_codex.mcp.server"]
|
|
38641
|
+
].find((value) => typeof value === "string" && value !== "");
|
|
38642
|
+
if (metadataName && mcpServer) {
|
|
38643
|
+
return `${mcpServer}/${metadataName}`;
|
|
38644
|
+
}
|
|
38645
|
+
return metadataName ?? spanName;
|
|
38646
|
+
}
|
|
38647
|
+
function normalizeToolName(value) {
|
|
38648
|
+
if (typeof value !== "string" || value === "") {
|
|
38649
|
+
return void 0;
|
|
38650
|
+
}
|
|
38651
|
+
return value.startsWith("tool:") ? value.slice("tool:".length).trim() : value;
|
|
38652
|
+
}
|
|
38653
|
+
function matchesValue(actual, matcher) {
|
|
38654
|
+
if (matcher instanceof RegExp) {
|
|
38655
|
+
return testRegex(matcher, actual);
|
|
38656
|
+
}
|
|
38657
|
+
if (typeof matcher === "function") {
|
|
38658
|
+
return matcher(actual);
|
|
38659
|
+
}
|
|
38660
|
+
if (Array.isArray(matcher)) {
|
|
38661
|
+
return Array.isArray(actual) && actual.length === matcher.length && matcher.every((value, index) => matchesValue(actual[index], value));
|
|
38662
|
+
}
|
|
38663
|
+
if (isPlainObject(matcher) && isPlainObject(actual)) {
|
|
38664
|
+
return Object.entries(matcher).every(
|
|
38665
|
+
([key, value]) => Object.prototype.hasOwnProperty.call(actual, key) && matchesValue(actual[key], value)
|
|
38666
|
+
);
|
|
38667
|
+
}
|
|
38668
|
+
return deepEqual(actual, matcher);
|
|
38669
|
+
}
|
|
38670
|
+
function testRegex(matcher, value) {
|
|
38671
|
+
matcher.lastIndex = 0;
|
|
38672
|
+
return matcher.test(typeof value === "string" ? value : formatValue(value));
|
|
38673
|
+
}
|
|
38674
|
+
function deepEqual(left, right) {
|
|
38675
|
+
if (Object.is(left, right)) return true;
|
|
38676
|
+
if (Array.isArray(left) && Array.isArray(right)) {
|
|
38677
|
+
return left.length === right.length && left.every((item, index) => deepEqual(item, right[index]));
|
|
38678
|
+
}
|
|
38679
|
+
if (isPlainObject(left) && isPlainObject(right)) {
|
|
38680
|
+
const leftKeys = Object.keys(left);
|
|
38681
|
+
const rightKeys = Object.keys(right);
|
|
38682
|
+
return leftKeys.length === rightKeys.length && leftKeys.every(
|
|
38683
|
+
(key) => Object.prototype.hasOwnProperty.call(right, key) && deepEqual(left[key], right[key])
|
|
38684
|
+
);
|
|
38685
|
+
}
|
|
38686
|
+
return false;
|
|
38687
|
+
}
|
|
38688
|
+
function isPlainObject(value) {
|
|
38689
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;
|
|
38690
|
+
}
|
|
38691
|
+
function formatSchemaError(error) {
|
|
38692
|
+
if (error instanceof Error) {
|
|
38693
|
+
return error.message;
|
|
38694
|
+
}
|
|
38695
|
+
return formatValue(error);
|
|
38696
|
+
}
|
|
38697
|
+
function formatValue(value) {
|
|
38698
|
+
if (value instanceof RegExp) {
|
|
38699
|
+
return value.toString();
|
|
38700
|
+
}
|
|
38701
|
+
if (typeof value === "string") {
|
|
38702
|
+
return JSON.stringify(value);
|
|
38703
|
+
}
|
|
38704
|
+
try {
|
|
38705
|
+
const serialized = JSON.stringify(value);
|
|
38706
|
+
if (serialized !== void 0 && !hasUndefinedJsonValue(value)) {
|
|
38707
|
+
return serialized;
|
|
38708
|
+
}
|
|
38709
|
+
return formatValueWithUndefined(value, /* @__PURE__ */ new Set());
|
|
38710
|
+
} catch {
|
|
38711
|
+
return String(value);
|
|
38712
|
+
}
|
|
38713
|
+
}
|
|
38714
|
+
function hasUndefinedJsonValue(value, seen = /* @__PURE__ */ new Set()) {
|
|
38715
|
+
if (value === void 0) {
|
|
38716
|
+
return true;
|
|
38717
|
+
}
|
|
38718
|
+
if (typeof value !== "object" || value === null) {
|
|
38719
|
+
return false;
|
|
38720
|
+
}
|
|
38721
|
+
if (seen.has(value)) {
|
|
38722
|
+
return false;
|
|
38723
|
+
}
|
|
38724
|
+
seen.add(value);
|
|
38725
|
+
if (Array.isArray(value)) {
|
|
38726
|
+
return Array.from({ length: value.length }).some(
|
|
38727
|
+
(_, index) => hasUndefinedJsonValue(value[index], seen)
|
|
38728
|
+
);
|
|
38729
|
+
}
|
|
38730
|
+
return Object.keys(value).some(
|
|
38731
|
+
(key) => hasUndefinedJsonValue(value[key], seen)
|
|
38732
|
+
);
|
|
38733
|
+
}
|
|
38734
|
+
function formatValueWithUndefined(value, seen) {
|
|
38735
|
+
if (value === void 0) {
|
|
38736
|
+
return "undefined";
|
|
38737
|
+
}
|
|
38738
|
+
if (value === null) {
|
|
38739
|
+
return "null";
|
|
38740
|
+
}
|
|
38741
|
+
if (typeof value === "string") {
|
|
38742
|
+
return JSON.stringify(value);
|
|
38743
|
+
}
|
|
38744
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
38745
|
+
return JSON.stringify(value);
|
|
38746
|
+
}
|
|
38747
|
+
if (typeof value === "bigint" || typeof value === "function") {
|
|
38748
|
+
return String(value);
|
|
38749
|
+
}
|
|
38750
|
+
if (typeof value === "symbol") {
|
|
38751
|
+
return String(value);
|
|
38752
|
+
}
|
|
38753
|
+
if (value instanceof RegExp) {
|
|
38754
|
+
return value.toString();
|
|
38755
|
+
}
|
|
38756
|
+
if (typeof value !== "object") {
|
|
38757
|
+
return String(value);
|
|
38758
|
+
}
|
|
38759
|
+
if (seen.has(value)) {
|
|
38760
|
+
return '"[Circular]"';
|
|
38761
|
+
}
|
|
38762
|
+
seen.add(value);
|
|
38763
|
+
if (typeof value.toJSON === "function") {
|
|
38764
|
+
const jsonValue = value.toJSON();
|
|
38765
|
+
seen.delete(value);
|
|
38766
|
+
return formatValueWithUndefined(jsonValue, seen);
|
|
38767
|
+
}
|
|
38768
|
+
if (Array.isArray(value)) {
|
|
38769
|
+
const formatted2 = Array.from(
|
|
38770
|
+
{ length: value.length },
|
|
38771
|
+
(_, index) => formatValueWithUndefined(value[index], seen)
|
|
38772
|
+
);
|
|
38773
|
+
seen.delete(value);
|
|
38774
|
+
return `[${formatted2.join(",")}]`;
|
|
38775
|
+
}
|
|
38776
|
+
const formatted = Object.keys(value).map(
|
|
38777
|
+
(key) => `${JSON.stringify(key)}:${formatValueWithUndefined(
|
|
38778
|
+
value[key],
|
|
38779
|
+
seen
|
|
38780
|
+
)}`
|
|
38781
|
+
);
|
|
38782
|
+
seen.delete(value);
|
|
38783
|
+
return `{${formatted.join(",")}}`;
|
|
38784
|
+
}
|
|
38785
|
+
|
|
36537
38786
|
// src/dataset-pipeline.ts
|
|
36538
38787
|
function DatasetPipeline(definition) {
|
|
36539
38788
|
if (!globalThis.__braintrust_dataset_pipelines) {
|
|
@@ -37110,8 +39359,10 @@ configureBrowser();
|
|
|
37110
39359
|
export {
|
|
37111
39360
|
Attachment,
|
|
37112
39361
|
AttachmentReference,
|
|
39362
|
+
BAGGAGE_HEADER,
|
|
37113
39363
|
BRAINTRUST_CURRENT_SPAN_STORE,
|
|
37114
39364
|
BRAINTRUST_LANGCHAIN_CALLBACK_HANDLER_NAME,
|
|
39365
|
+
BRAINTRUST_PARENT_KEY,
|
|
37115
39366
|
BaseAttachment,
|
|
37116
39367
|
BaseExperiment,
|
|
37117
39368
|
BraintrustLangChainCallbackHandler,
|
|
@@ -37144,6 +39395,7 @@ export {
|
|
|
37144
39395
|
NOOP_SPAN,
|
|
37145
39396
|
NOOP_SPAN_PERMALINK,
|
|
37146
39397
|
NoopSpan,
|
|
39398
|
+
OTELIDGenerator,
|
|
37147
39399
|
ObjectFetcher,
|
|
37148
39400
|
Project2 as Project,
|
|
37149
39401
|
ProjectNameIdMap,
|
|
@@ -37155,6 +39407,8 @@ export {
|
|
|
37155
39407
|
ScorerBuilder,
|
|
37156
39408
|
SpanFetcher,
|
|
37157
39409
|
SpanImpl,
|
|
39410
|
+
TRACEPARENT_HEADER,
|
|
39411
|
+
TRACESTATE_HEADER,
|
|
37158
39412
|
TestBackgroundLogger,
|
|
37159
39413
|
ToolBuilder,
|
|
37160
39414
|
UUIDGenerator,
|
|
@@ -37164,6 +39418,7 @@ export {
|
|
|
37164
39418
|
isomorph_default as _internalIso,
|
|
37165
39419
|
_internalSetInitialState,
|
|
37166
39420
|
addAzureBlobHeaders,
|
|
39421
|
+
agentAssertionScorer,
|
|
37167
39422
|
braintrustAISDKTelemetry,
|
|
37168
39423
|
braintrustFlueInstrumentation,
|
|
37169
39424
|
braintrustFlueObserver,
|
|
@@ -37182,6 +39437,7 @@ export {
|
|
|
37182
39437
|
devNullWritableStream,
|
|
37183
39438
|
evaluatorDefinitionSchema,
|
|
37184
39439
|
evaluatorDefinitionsSchema,
|
|
39440
|
+
extractTraceContextFromHeaders,
|
|
37185
39441
|
flush,
|
|
37186
39442
|
getContextManager,
|
|
37187
39443
|
getIdGenerator,
|
|
@@ -37195,6 +39451,7 @@ export {
|
|
|
37195
39451
|
initFunction,
|
|
37196
39452
|
initLogger,
|
|
37197
39453
|
initNodeTestSuite,
|
|
39454
|
+
injectTraceContext,
|
|
37198
39455
|
invoke,
|
|
37199
39456
|
isTemplateFormat,
|
|
37200
39457
|
loadParameters,
|
|
@@ -37233,7 +39490,7 @@ export {
|
|
|
37233
39490
|
traced,
|
|
37234
39491
|
updateSpan,
|
|
37235
39492
|
uploadLogs3OverflowPayload,
|
|
37236
|
-
utf8ByteLength,
|
|
39493
|
+
utf8ByteLength2 as utf8ByteLength,
|
|
37237
39494
|
withCurrent,
|
|
37238
39495
|
withDataset,
|
|
37239
39496
|
withExperiment,
|