braintrust 3.28.0 → 3.30.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/README.md +1 -1
- package/dev/dist/index.d.mts +356 -7
- package/dev/dist/index.d.ts +356 -7
- package/dev/dist/index.js +2679 -1828
- package/dev/dist/index.mjs +1862 -1011
- package/dist/apply-auto-instrumentation.js +298 -265
- package/dist/apply-auto-instrumentation.mjs +85 -52
- package/dist/auto-instrumentations/bundler/esbuild.cjs +56 -6
- package/dist/auto-instrumentations/bundler/esbuild.mjs +2 -2
- package/dist/auto-instrumentations/bundler/next.cjs +56 -6
- package/dist/auto-instrumentations/bundler/next.mjs +3 -3
- package/dist/auto-instrumentations/bundler/rollup.cjs +56 -6
- package/dist/auto-instrumentations/bundler/rollup.mjs +2 -2
- package/dist/auto-instrumentations/bundler/vite.cjs +56 -6
- package/dist/auto-instrumentations/bundler/vite.mjs +2 -2
- package/dist/auto-instrumentations/bundler/webpack-loader.cjs +56 -6
- package/dist/auto-instrumentations/bundler/webpack.cjs +56 -6
- package/dist/auto-instrumentations/bundler/webpack.mjs +3 -3
- package/dist/auto-instrumentations/{chunk-26PKVUKB.mjs → chunk-LW4HDHXT.mjs} +12 -4
- package/dist/auto-instrumentations/{chunk-HD35AM3M.mjs → chunk-OXINGIEZ.mjs} +1 -1
- package/dist/auto-instrumentations/{chunk-NP7V4XB2.mjs → chunk-U64OYU4Q.mjs} +45 -3
- package/dist/auto-instrumentations/hook.mjs +967 -136
- package/dist/auto-instrumentations/index.cjs +45 -3
- package/dist/auto-instrumentations/index.mjs +1 -1
- package/dist/browser.d.mts +893 -24
- package/dist/browser.d.ts +893 -24
- package/dist/browser.js +2795 -1136
- package/dist/browser.mjs +2795 -1136
- package/dist/{chunk-BBE7SNRV.js → chunk-2XDW3UCG.js} +155 -23
- package/dist/{chunk-UPFNQCGB.mjs → chunk-BU6SM54N.mjs} +1830 -1045
- package/dist/{chunk-ZHUHZWFY.mjs → chunk-N3JKQ3D3.mjs} +152 -20
- package/dist/{chunk-OBBWQW6K.js → chunk-TWCDSYJN.js} +2890 -2105
- package/dist/cli.js +5976 -1348
- package/dist/edge-light.d.mts +1 -1
- package/dist/edge-light.d.ts +1 -1
- package/dist/edge-light.js +2795 -1136
- package/dist/edge-light.mjs +2795 -1136
- package/dist/index.d.mts +893 -24
- package/dist/index.d.ts +893 -24
- package/dist/index.js +1448 -699
- package/dist/index.mjs +848 -99
- package/dist/instrumentation/index.d.mts +563 -9
- package/dist/instrumentation/index.d.ts +563 -9
- package/dist/instrumentation/index.js +2794 -989
- package/dist/instrumentation/index.mjs +2794 -989
- 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 +2795 -1136
- package/dist/workerd.mjs +2795 -1136
- package/package.json +1 -1
- package/util/dist/index.d.mts +42 -0
- package/util/dist/index.d.ts +42 -0
package/dist/index.mjs
CHANGED
|
@@ -74,7 +74,6 @@ import {
|
|
|
74
74
|
currentLogger,
|
|
75
75
|
currentSpan,
|
|
76
76
|
currentWorkflowAgentWrapperSpan,
|
|
77
|
-
debugLogger,
|
|
78
77
|
deepCopyEvent,
|
|
79
78
|
deserializePlainStringAsJSON,
|
|
80
79
|
devNullWritableStream,
|
|
@@ -144,7 +143,7 @@ import {
|
|
|
144
143
|
wrapMastraAgent,
|
|
145
144
|
wrapTraced,
|
|
146
145
|
zodToJsonSchema
|
|
147
|
-
} from "./chunk-
|
|
146
|
+
} from "./chunk-BU6SM54N.mjs";
|
|
148
147
|
import {
|
|
149
148
|
INSTRUMENTATION_NAMES,
|
|
150
149
|
__export,
|
|
@@ -156,6 +155,7 @@ import {
|
|
|
156
155
|
cloudflareThinkChannels,
|
|
157
156
|
cohereChannels,
|
|
158
157
|
cursorSDKChannels,
|
|
158
|
+
debugLogger,
|
|
159
159
|
genkitChannels,
|
|
160
160
|
gitHubCopilotChannels,
|
|
161
161
|
googleADKChannels,
|
|
@@ -177,7 +177,7 @@ import {
|
|
|
177
177
|
strandsAgentSDKChannels,
|
|
178
178
|
voyageAIChannels,
|
|
179
179
|
withSpanInstrumentationName
|
|
180
|
-
} from "./chunk-
|
|
180
|
+
} from "./chunk-N3JKQ3D3.mjs";
|
|
181
181
|
|
|
182
182
|
// src/exports.ts
|
|
183
183
|
var exports_exports = {};
|
|
@@ -256,6 +256,7 @@ __export(exports_exports, {
|
|
|
256
256
|
braintrustStreamChunkSchema: () => braintrustStreamChunkSchema,
|
|
257
257
|
buildLocalSummary: () => buildLocalSummary,
|
|
258
258
|
collectAnthropicSession: () => collectAnthropicSession,
|
|
259
|
+
completeOpenAIBatchTrace: () => completeOpenAIBatchTrace,
|
|
259
260
|
configureInstrumentation: () => configureInstrumentation,
|
|
260
261
|
constructLogs3OverflowRequest: () => constructLogs3OverflowRequest,
|
|
261
262
|
createFinalValuePassThroughStream: () => createFinalValuePassThroughStream,
|
|
@@ -294,6 +295,8 @@ __export(exports_exports, {
|
|
|
294
295
|
loginToState: () => loginToState,
|
|
295
296
|
logs3OverflowUploadSchema: () => logs3OverflowUploadSchema,
|
|
296
297
|
newId: () => newId,
|
|
298
|
+
openaiBatchesRetrieveTraced: () => openaiBatchesRetrieveTraced,
|
|
299
|
+
openaiFilesCreateTraced: () => openaiFilesCreateTraced,
|
|
297
300
|
parseCachedHeader: () => parseCachedHeader,
|
|
298
301
|
parseTemplateFormat: () => parseTemplateFormat,
|
|
299
302
|
permalink: () => permalink,
|
|
@@ -458,6 +461,260 @@ async function registerSandbox(options) {
|
|
|
458
461
|
};
|
|
459
462
|
}
|
|
460
463
|
|
|
464
|
+
// src/wrappers/openai-promise-utils.ts
|
|
465
|
+
function splitSpanInfo(allParams) {
|
|
466
|
+
const { span_info, ...params } = allParams;
|
|
467
|
+
return {
|
|
468
|
+
params,
|
|
469
|
+
span_info
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
function createChannelContext(_channel, params, span_info) {
|
|
473
|
+
return {
|
|
474
|
+
arguments: (
|
|
475
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
476
|
+
[params]
|
|
477
|
+
),
|
|
478
|
+
span_info
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
async function tracePromiseWithResponse(channel, traceContext, apiPromise) {
|
|
482
|
+
let enhancedResponse;
|
|
483
|
+
const tracePromise = (
|
|
484
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
485
|
+
channel.tracePromise
|
|
486
|
+
);
|
|
487
|
+
const data = await tracePromise(async () => {
|
|
488
|
+
enhancedResponse = await apiPromise.withResponse();
|
|
489
|
+
traceContext.response = enhancedResponse.response;
|
|
490
|
+
return enhancedResponse.data;
|
|
491
|
+
}, traceContext);
|
|
492
|
+
if (!enhancedResponse) {
|
|
493
|
+
throw new Error("Expected withResponse() to provide response");
|
|
494
|
+
}
|
|
495
|
+
return {
|
|
496
|
+
data,
|
|
497
|
+
response: enhancedResponse.response,
|
|
498
|
+
request_id: enhancedResponse.request_id
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
async function tracePromiseAsResponse(channel, traceContext, apiPromise) {
|
|
502
|
+
const tracePromise = (
|
|
503
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
504
|
+
channel.tracePromise
|
|
505
|
+
);
|
|
506
|
+
let response;
|
|
507
|
+
await tracePromise(async () => {
|
|
508
|
+
response = await apiPromise.asResponse();
|
|
509
|
+
traceContext.response = response;
|
|
510
|
+
return void 0;
|
|
511
|
+
}, traceContext);
|
|
512
|
+
if (!response) {
|
|
513
|
+
throw new Error("Expected asResponse() to provide response");
|
|
514
|
+
}
|
|
515
|
+
return response;
|
|
516
|
+
}
|
|
517
|
+
function createLazyAPIPromise(ensureExecuted, ensureResponse, getAPIPromise) {
|
|
518
|
+
let firstConsumption;
|
|
519
|
+
let enhancedResponsePromise;
|
|
520
|
+
let dataPromise;
|
|
521
|
+
let responsePromise;
|
|
522
|
+
const withResponse = () => {
|
|
523
|
+
firstConsumption ??= "data";
|
|
524
|
+
enhancedResponsePromise ??= firstConsumption === "data" ? ensureExecuted() : getAPIPromise().withResponse();
|
|
525
|
+
return enhancedResponsePromise;
|
|
526
|
+
};
|
|
527
|
+
const asResponse = () => {
|
|
528
|
+
firstConsumption ??= "response";
|
|
529
|
+
responsePromise ??= firstConsumption === "response" ? ensureResponse() : getAPIPromise().asResponse();
|
|
530
|
+
return responsePromise;
|
|
531
|
+
};
|
|
532
|
+
return new Proxy({}, {
|
|
533
|
+
get(target, prop, receiver) {
|
|
534
|
+
if (prop === "withResponse") {
|
|
535
|
+
return withResponse;
|
|
536
|
+
}
|
|
537
|
+
if (prop === "asResponse") {
|
|
538
|
+
return asResponse;
|
|
539
|
+
}
|
|
540
|
+
if (prop === "then" || prop === "catch" || prop === "finally" || prop in Promise.prototype) {
|
|
541
|
+
dataPromise ??= withResponse().then((result) => result.data);
|
|
542
|
+
const value = Reflect.get(dataPromise, prop, receiver);
|
|
543
|
+
return typeof value === "function" ? value.bind(dataPromise) : value;
|
|
544
|
+
}
|
|
545
|
+
return Reflect.get(target, prop, receiver);
|
|
546
|
+
}
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
// src/openai-batch.ts
|
|
551
|
+
function read(value, key) {
|
|
552
|
+
if (value === null || typeof value !== "object" && typeof value !== "function") {
|
|
553
|
+
return void 0;
|
|
554
|
+
}
|
|
555
|
+
try {
|
|
556
|
+
return Reflect.get(value, key);
|
|
557
|
+
} catch {
|
|
558
|
+
return void 0;
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
function isAsyncIterable(value) {
|
|
562
|
+
return typeof read(value, Symbol.asyncIterator) === "function";
|
|
563
|
+
}
|
|
564
|
+
function teeAsyncIterable(source) {
|
|
565
|
+
const iterator = source[Symbol.asyncIterator]();
|
|
566
|
+
const stream = new ReadableStream({
|
|
567
|
+
async pull(controller) {
|
|
568
|
+
try {
|
|
569
|
+
const result = await iterator.next();
|
|
570
|
+
if (result.done) {
|
|
571
|
+
controller.close();
|
|
572
|
+
return;
|
|
573
|
+
}
|
|
574
|
+
if (!(result.value instanceof Uint8Array)) {
|
|
575
|
+
throw new TypeError(
|
|
576
|
+
"OpenAI upload streams must yield Uint8Array chunks"
|
|
577
|
+
);
|
|
578
|
+
}
|
|
579
|
+
controller.enqueue(result.value);
|
|
580
|
+
} catch (error) {
|
|
581
|
+
controller.error(error);
|
|
582
|
+
}
|
|
583
|
+
},
|
|
584
|
+
async cancel(reason) {
|
|
585
|
+
await iterator.return?.(reason);
|
|
586
|
+
}
|
|
587
|
+
});
|
|
588
|
+
const [uploadStream, trace] = stream.tee();
|
|
589
|
+
const upload = {
|
|
590
|
+
async *[Symbol.asyncIterator]() {
|
|
591
|
+
const reader = uploadStream.getReader();
|
|
592
|
+
try {
|
|
593
|
+
while (true) {
|
|
594
|
+
const result = await reader.read();
|
|
595
|
+
if (result.done) {
|
|
596
|
+
return;
|
|
597
|
+
}
|
|
598
|
+
yield result.value;
|
|
599
|
+
}
|
|
600
|
+
} finally {
|
|
601
|
+
reader.releaseLock();
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
};
|
|
605
|
+
const path = read(source, "path");
|
|
606
|
+
if (typeof path === "string") {
|
|
607
|
+
Object.defineProperty(upload, "path", { value: path });
|
|
608
|
+
}
|
|
609
|
+
return { upload, trace: new Response(trace) };
|
|
610
|
+
}
|
|
611
|
+
function teeUpload(upload) {
|
|
612
|
+
if (upload instanceof Blob) {
|
|
613
|
+
return { upload, trace: new Response(upload) };
|
|
614
|
+
}
|
|
615
|
+
if (upload instanceof Response) {
|
|
616
|
+
return { upload, trace: upload.clone() };
|
|
617
|
+
}
|
|
618
|
+
if (isAsyncIterable(upload)) {
|
|
619
|
+
return teeAsyncIterable(upload);
|
|
620
|
+
}
|
|
621
|
+
return void 0;
|
|
622
|
+
}
|
|
623
|
+
function openaiFilesCreateTraced(files) {
|
|
624
|
+
return (params, options) => {
|
|
625
|
+
const parent = getSpanParentObject();
|
|
626
|
+
const purpose = read(params, "purpose");
|
|
627
|
+
const file = read(params, "file");
|
|
628
|
+
if (purpose !== "batch") {
|
|
629
|
+
return files.create(params, options);
|
|
630
|
+
}
|
|
631
|
+
let branches;
|
|
632
|
+
try {
|
|
633
|
+
branches = teeUpload(file);
|
|
634
|
+
} catch {
|
|
635
|
+
return files.create(params, options);
|
|
636
|
+
}
|
|
637
|
+
if (!branches) {
|
|
638
|
+
return files.create(params, options);
|
|
639
|
+
}
|
|
640
|
+
const tracedParams = {
|
|
641
|
+
...Object(params),
|
|
642
|
+
file: branches.upload
|
|
643
|
+
};
|
|
644
|
+
const apiPromise = files.create(tracedParams, options);
|
|
645
|
+
let enhancedResponse;
|
|
646
|
+
const tracedResponse = openAIChannels.filesCreateTraced.invoke(
|
|
647
|
+
async () => {
|
|
648
|
+
enhancedResponse = await apiPromise.withResponse();
|
|
649
|
+
return enhancedResponse.data;
|
|
650
|
+
},
|
|
651
|
+
files,
|
|
652
|
+
[{ params, inputFileContent: branches.trace, parent }],
|
|
653
|
+
{}
|
|
654
|
+
).then((data) => {
|
|
655
|
+
if (!enhancedResponse) {
|
|
656
|
+
throw new Error(
|
|
657
|
+
"Expected OpenAI withResponse() to provide a response"
|
|
658
|
+
);
|
|
659
|
+
}
|
|
660
|
+
return { ...enhancedResponse, data };
|
|
661
|
+
});
|
|
662
|
+
return createLazyAPIPromise(
|
|
663
|
+
() => tracedResponse,
|
|
664
|
+
() => tracedResponse.then(({ response }) => response),
|
|
665
|
+
() => apiPromise
|
|
666
|
+
);
|
|
667
|
+
};
|
|
668
|
+
}
|
|
669
|
+
function openaiBatchesRetrieveTraced(batches) {
|
|
670
|
+
return (batchId, options) => {
|
|
671
|
+
const apiPromise = batches.retrieve(batchId, options);
|
|
672
|
+
let enhancedResponse;
|
|
673
|
+
const tracedResponse = openAIChannels.batchesRetrieveTraced.invoke(
|
|
674
|
+
async () => {
|
|
675
|
+
enhancedResponse = await apiPromise.withResponse();
|
|
676
|
+
return enhancedResponse.data;
|
|
677
|
+
},
|
|
678
|
+
batches,
|
|
679
|
+
[{ batchId }],
|
|
680
|
+
{}
|
|
681
|
+
).then((data) => {
|
|
682
|
+
if (!enhancedResponse) {
|
|
683
|
+
throw new Error(
|
|
684
|
+
"Expected OpenAI withResponse() to provide a response"
|
|
685
|
+
);
|
|
686
|
+
}
|
|
687
|
+
return { ...enhancedResponse, data };
|
|
688
|
+
});
|
|
689
|
+
return createLazyAPIPromise(
|
|
690
|
+
() => tracedResponse,
|
|
691
|
+
() => tracedResponse.then(({ response }) => response),
|
|
692
|
+
() => apiPromise
|
|
693
|
+
);
|
|
694
|
+
};
|
|
695
|
+
}
|
|
696
|
+
async function completeOpenAIBatchTrace(args) {
|
|
697
|
+
const inputFileContent = Promise.resolve(args.inputFileContent);
|
|
698
|
+
const outputFileContent = args.outputFileContent === void 0 ? void 0 : Promise.resolve(args.outputFileContent);
|
|
699
|
+
const errorFileContent = args.errorFileContent === void 0 ? void 0 : Promise.resolve(args.errorFileContent);
|
|
700
|
+
void inputFileContent.catch(() => void 0);
|
|
701
|
+
void outputFileContent?.catch(() => void 0);
|
|
702
|
+
void errorFileContent?.catch(() => void 0);
|
|
703
|
+
await openAIChannels.batchesCompleteTrace.invoke(
|
|
704
|
+
async () => void 0,
|
|
705
|
+
void 0,
|
|
706
|
+
[
|
|
707
|
+
{
|
|
708
|
+
...args,
|
|
709
|
+
inputFileContent,
|
|
710
|
+
outputFileContent,
|
|
711
|
+
errorFileContent
|
|
712
|
+
}
|
|
713
|
+
],
|
|
714
|
+
{}
|
|
715
|
+
);
|
|
716
|
+
}
|
|
717
|
+
|
|
461
718
|
// src/functions/invoke.ts
|
|
462
719
|
async function invoke(args) {
|
|
463
720
|
const {
|
|
@@ -560,58 +817,6 @@ function initFunction({
|
|
|
560
817
|
return f;
|
|
561
818
|
}
|
|
562
819
|
|
|
563
|
-
// src/wrappers/openai-promise-utils.ts
|
|
564
|
-
function splitSpanInfo(allParams) {
|
|
565
|
-
const { span_info, ...params } = allParams;
|
|
566
|
-
return {
|
|
567
|
-
params,
|
|
568
|
-
span_info
|
|
569
|
-
};
|
|
570
|
-
}
|
|
571
|
-
function createChannelContext(_channel, params, span_info) {
|
|
572
|
-
return {
|
|
573
|
-
arguments: (
|
|
574
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
575
|
-
[params]
|
|
576
|
-
),
|
|
577
|
-
span_info
|
|
578
|
-
};
|
|
579
|
-
}
|
|
580
|
-
async function tracePromiseWithResponse(channel, traceContext, apiPromise) {
|
|
581
|
-
let enhancedResponse;
|
|
582
|
-
const tracePromise = (
|
|
583
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
584
|
-
channel.tracePromise
|
|
585
|
-
);
|
|
586
|
-
const data = await tracePromise(async () => {
|
|
587
|
-
enhancedResponse = await apiPromise.withResponse();
|
|
588
|
-
traceContext.response = enhancedResponse.response;
|
|
589
|
-
return enhancedResponse.data;
|
|
590
|
-
}, traceContext);
|
|
591
|
-
if (!enhancedResponse) {
|
|
592
|
-
throw new Error("Expected withResponse() to provide response");
|
|
593
|
-
}
|
|
594
|
-
return { data, response: enhancedResponse.response };
|
|
595
|
-
}
|
|
596
|
-
function createLazyAPIPromise(ensureExecuted) {
|
|
597
|
-
let dataPromise = null;
|
|
598
|
-
return new Proxy({}, {
|
|
599
|
-
get(target, prop, receiver) {
|
|
600
|
-
if (prop === "withResponse") {
|
|
601
|
-
return () => ensureExecuted();
|
|
602
|
-
}
|
|
603
|
-
if (prop === "then" || prop === "catch" || prop === "finally" || prop in Promise.prototype) {
|
|
604
|
-
if (!dataPromise) {
|
|
605
|
-
dataPromise = ensureExecuted().then((result) => result.data);
|
|
606
|
-
}
|
|
607
|
-
const value = Reflect.get(dataPromise, prop, receiver);
|
|
608
|
-
return typeof value === "function" ? value.bind(dataPromise) : value;
|
|
609
|
-
}
|
|
610
|
-
return Reflect.get(target, prop, receiver);
|
|
611
|
-
}
|
|
612
|
-
});
|
|
613
|
-
}
|
|
614
|
-
|
|
615
820
|
// src/wrappers/oai_responses.ts
|
|
616
821
|
function responsesProxy(openai) {
|
|
617
822
|
if (!openai.responses) {
|
|
@@ -648,17 +853,33 @@ function wrapResponsesAsync(target, channel) {
|
|
|
648
853
|
return (allParams, options) => {
|
|
649
854
|
const { span_info, params } = splitSpanInfo(allParams);
|
|
650
855
|
let executionPromise = null;
|
|
856
|
+
let apiPromise = null;
|
|
857
|
+
const getAPIPromise = () => {
|
|
858
|
+
apiPromise ??= target(params, options);
|
|
859
|
+
return apiPromise;
|
|
860
|
+
};
|
|
651
861
|
const ensureExecuted = () => {
|
|
652
862
|
if (!executionPromise) {
|
|
653
863
|
executionPromise = (async () => {
|
|
654
864
|
const traceContext = createChannelContext(channel, params, span_info);
|
|
655
|
-
|
|
656
|
-
|
|
865
|
+
return tracePromiseWithResponse(
|
|
866
|
+
channel,
|
|
867
|
+
traceContext,
|
|
868
|
+
getAPIPromise()
|
|
869
|
+
);
|
|
657
870
|
})();
|
|
658
871
|
}
|
|
659
872
|
return executionPromise;
|
|
660
873
|
};
|
|
661
|
-
return createLazyAPIPromise(
|
|
874
|
+
return createLazyAPIPromise(
|
|
875
|
+
ensureExecuted,
|
|
876
|
+
() => tracePromiseAsResponse(
|
|
877
|
+
channel,
|
|
878
|
+
createChannelContext(channel, params, span_info),
|
|
879
|
+
getAPIPromise()
|
|
880
|
+
),
|
|
881
|
+
getAPIPromise
|
|
882
|
+
);
|
|
662
883
|
};
|
|
663
884
|
}
|
|
664
885
|
function wrapResponsesSyncStream(target, channel) {
|
|
@@ -804,6 +1025,11 @@ function wrapChatCompletion(completion) {
|
|
|
804
1025
|
allParams
|
|
805
1026
|
);
|
|
806
1027
|
let executionPromise = null;
|
|
1028
|
+
let apiPromise = null;
|
|
1029
|
+
const getAPIPromise = () => {
|
|
1030
|
+
apiPromise ??= completion(params, options);
|
|
1031
|
+
return apiPromise;
|
|
1032
|
+
};
|
|
807
1033
|
const ensureExecuted = () => {
|
|
808
1034
|
if (!executionPromise) {
|
|
809
1035
|
executionPromise = (async () => {
|
|
@@ -813,32 +1039,44 @@ function wrapChatCompletion(completion) {
|
|
|
813
1039
|
span_info
|
|
814
1040
|
);
|
|
815
1041
|
if (params.stream) {
|
|
816
|
-
const completionPromise =
|
|
817
|
-
|
|
818
|
-
|
|
1042
|
+
const completionPromise = (
|
|
1043
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
1044
|
+
getAPIPromise()
|
|
819
1045
|
);
|
|
820
|
-
const { data: data2, response: response2 } = await tracePromiseWithResponse(
|
|
1046
|
+
const { data: data2, response: response2, request_id: request_id2 } = await tracePromiseWithResponse(
|
|
821
1047
|
openAIChannels.chatCompletionsCreate,
|
|
822
1048
|
traceContext,
|
|
823
1049
|
completionPromise
|
|
824
1050
|
);
|
|
825
|
-
return { data: data2, response: response2 };
|
|
1051
|
+
return { data: data2, response: response2, request_id: request_id2 };
|
|
826
1052
|
}
|
|
827
|
-
const completionResponse =
|
|
828
|
-
|
|
829
|
-
|
|
1053
|
+
const completionResponse = (
|
|
1054
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
1055
|
+
getAPIPromise()
|
|
830
1056
|
);
|
|
831
|
-
const { data, response } = await tracePromiseWithResponse(
|
|
1057
|
+
const { data, response, request_id } = await tracePromiseWithResponse(
|
|
832
1058
|
openAIChannels.chatCompletionsCreate,
|
|
833
1059
|
traceContext,
|
|
834
1060
|
completionResponse
|
|
835
1061
|
);
|
|
836
|
-
return { data, response };
|
|
1062
|
+
return { data, response, request_id };
|
|
837
1063
|
})();
|
|
838
1064
|
}
|
|
839
1065
|
return executionPromise;
|
|
840
1066
|
};
|
|
841
|
-
return createLazyAPIPromise(
|
|
1067
|
+
return createLazyAPIPromise(
|
|
1068
|
+
ensureExecuted,
|
|
1069
|
+
() => tracePromiseAsResponse(
|
|
1070
|
+
openAIChannels.chatCompletionsCreate,
|
|
1071
|
+
createChannelContext(
|
|
1072
|
+
openAIChannels.chatCompletionsCreate,
|
|
1073
|
+
params,
|
|
1074
|
+
span_info
|
|
1075
|
+
),
|
|
1076
|
+
getAPIPromise()
|
|
1077
|
+
),
|
|
1078
|
+
getAPIPromise
|
|
1079
|
+
);
|
|
842
1080
|
};
|
|
843
1081
|
}
|
|
844
1082
|
function createEndpointProxy(target, wrapperFn) {
|
|
@@ -856,6 +1094,11 @@ function wrapApiCreateWithChannel(create, channel) {
|
|
|
856
1094
|
return (allParams, options) => {
|
|
857
1095
|
const { span_info, params } = splitSpanInfo(allParams);
|
|
858
1096
|
let executionPromise = null;
|
|
1097
|
+
let apiPromise = null;
|
|
1098
|
+
const getAPIPromise = () => {
|
|
1099
|
+
apiPromise ??= create(params, options);
|
|
1100
|
+
return apiPromise;
|
|
1101
|
+
};
|
|
859
1102
|
const ensureExecuted = () => {
|
|
860
1103
|
if (!executionPromise) {
|
|
861
1104
|
executionPromise = (async () => {
|
|
@@ -863,13 +1106,21 @@ function wrapApiCreateWithChannel(create, channel) {
|
|
|
863
1106
|
return tracePromiseWithResponse(
|
|
864
1107
|
channel,
|
|
865
1108
|
traceContext,
|
|
866
|
-
|
|
1109
|
+
getAPIPromise()
|
|
867
1110
|
);
|
|
868
1111
|
})();
|
|
869
1112
|
}
|
|
870
1113
|
return executionPromise;
|
|
871
1114
|
};
|
|
872
|
-
return createLazyAPIPromise(
|
|
1115
|
+
return createLazyAPIPromise(
|
|
1116
|
+
ensureExecuted,
|
|
1117
|
+
() => tracePromiseAsResponse(
|
|
1118
|
+
channel,
|
|
1119
|
+
createChannelContext(channel, params, span_info),
|
|
1120
|
+
getAPIPromise()
|
|
1121
|
+
),
|
|
1122
|
+
getAPIPromise
|
|
1123
|
+
);
|
|
873
1124
|
};
|
|
874
1125
|
}
|
|
875
1126
|
var wrapEmbeddings = (create) => wrapApiCreateWithChannel(create, openAIChannels.embeddingsCreate);
|
|
@@ -905,6 +1156,13 @@ function wrapAISDK(aiSDK, options = {}) {
|
|
|
905
1156
|
switch (prop) {
|
|
906
1157
|
case "generateText":
|
|
907
1158
|
return wrapGenerateText(typedAISDK.generateText, options, typedAISDK);
|
|
1159
|
+
case "generateImage":
|
|
1160
|
+
case "experimental_generateImage":
|
|
1161
|
+
return typeof original === "function" ? wrapGenerateImage(
|
|
1162
|
+
original,
|
|
1163
|
+
options,
|
|
1164
|
+
typedAISDK
|
|
1165
|
+
) : original;
|
|
908
1166
|
case "streamText":
|
|
909
1167
|
return wrapStreamText(typedAISDK.streamText, options, typedAISDK);
|
|
910
1168
|
case "generateObject":
|
|
@@ -1141,6 +1399,32 @@ var wrapGenerateObject = (generateObject, options = {}, aiSDK) => {
|
|
|
1141
1399
|
options
|
|
1142
1400
|
);
|
|
1143
1401
|
};
|
|
1402
|
+
var wrapGenerateImage = (generateImage, options = {}, aiSDK) => {
|
|
1403
|
+
return makeGenerateImageWrapper(generateImage, { aiSDK }, options);
|
|
1404
|
+
};
|
|
1405
|
+
var makeGenerateImageWrapper = (generateImage, contextOptions = {}, options = {}) => {
|
|
1406
|
+
const wrapper = async function(allParams) {
|
|
1407
|
+
const { span_info, ...params } = allParams;
|
|
1408
|
+
const tracedParams = { ...params };
|
|
1409
|
+
return aiSDKChannels.generateImage.tracePromise(
|
|
1410
|
+
() => generateImage(tracedParams),
|
|
1411
|
+
createAISDKChannelContext(tracedParams, {
|
|
1412
|
+
aiSDK: contextOptions.aiSDK,
|
|
1413
|
+
denyOutputPaths: options.denyOutputPaths,
|
|
1414
|
+
self: contextOptions.self,
|
|
1415
|
+
span_info: mergeSpanInfo(span_info, {
|
|
1416
|
+
name: "generateImage",
|
|
1417
|
+
spanType: contextOptions.spanType
|
|
1418
|
+
})
|
|
1419
|
+
})
|
|
1420
|
+
);
|
|
1421
|
+
};
|
|
1422
|
+
Object.defineProperty(wrapper, "name", {
|
|
1423
|
+
value: "generateImage",
|
|
1424
|
+
writable: false
|
|
1425
|
+
});
|
|
1426
|
+
return wrapper;
|
|
1427
|
+
};
|
|
1144
1428
|
var makeEmbedWrapper = (channel, name, embed, contextOptions = {}, options = {}) => {
|
|
1145
1429
|
const wrapper = async function(allParams) {
|
|
1146
1430
|
const { span_info, ...params } = allParams;
|
|
@@ -1891,7 +2175,7 @@ function braintrustEveHook(options) {
|
|
|
1891
2175
|
}
|
|
1892
2176
|
};
|
|
1893
2177
|
}
|
|
1894
|
-
function
|
|
2178
|
+
function createLegacyEveInstrumentation(options) {
|
|
1895
2179
|
const state = options.defineState(EVE_TRACE_STATE_KEY, emptyEveTraceState);
|
|
1896
2180
|
return {
|
|
1897
2181
|
events: {
|
|
@@ -3279,8 +3563,10 @@ function capturedModelInput(modelInput) {
|
|
|
3279
3563
|
const value = [];
|
|
3280
3564
|
if (typeof instructions === "string") {
|
|
3281
3565
|
value.push({ content: instructions, role: "system" });
|
|
3282
|
-
} else if (instructions) {
|
|
3566
|
+
} else if (Array.isArray(instructions)) {
|
|
3283
3567
|
value.push(...instructions.map(capturedEveModelMessage));
|
|
3568
|
+
} else if (instructions) {
|
|
3569
|
+
value.push(capturedEveModelMessage(instructions));
|
|
3284
3570
|
}
|
|
3285
3571
|
value.push(...messages.map(capturedEveModelMessage));
|
|
3286
3572
|
try {
|
|
@@ -3524,6 +3810,472 @@ async function deterministicEveId(...parts) {
|
|
|
3524
3810
|
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
3525
3811
|
}
|
|
3526
3812
|
|
|
3813
|
+
// src/instrumentation/plugins/eve-provider.ts
|
|
3814
|
+
var MAX_EVE_PROVIDER_CACHE_ENTRIES = 1e4;
|
|
3815
|
+
function createEveInstrumentationProvider(options = {}) {
|
|
3816
|
+
const bridge = new EveProviderBridge(options.metadata);
|
|
3817
|
+
return {
|
|
3818
|
+
// Eve versions before tracePolicy use capture to decide whether provider
|
|
3819
|
+
// events include content. Newer versions prefer tracePolicy when both are
|
|
3820
|
+
// present, so keep the deprecated field for backwards compatibility.
|
|
3821
|
+
capture: "content",
|
|
3822
|
+
tracePolicy: () => ({
|
|
3823
|
+
emit: true,
|
|
3824
|
+
recordInputs: true,
|
|
3825
|
+
recordOutputs: true
|
|
3826
|
+
}),
|
|
3827
|
+
events: {
|
|
3828
|
+
"action.completed": (event, context) => bridge.handleActionTerminal(event, context),
|
|
3829
|
+
"action.failed": (event, context) => bridge.handleActionTerminal(event, context),
|
|
3830
|
+
"action.started": (event, context) => bridge.handleActionStarted(event, context),
|
|
3831
|
+
"model.call.completed": (event, context) => bridge.handleModelTerminal(event, context),
|
|
3832
|
+
"model.call.failed": (event, context) => bridge.handleModelTerminal(event, context),
|
|
3833
|
+
"model.call.started": (event, context) => bridge.handleModelStarted(event, context),
|
|
3834
|
+
"step.attempt.completed": (event) => bridge.handleStepAttemptTerminal(event),
|
|
3835
|
+
"step.attempt.failed": (event) => bridge.handleStepAttemptTerminal(event),
|
|
3836
|
+
"turn.cancelled": (event, context) => bridge.handleTurnTerminal(event, context),
|
|
3837
|
+
"turn.completed": (event, context) => bridge.handleTurnTerminal(event, context),
|
|
3838
|
+
"turn.failed": (event, context) => bridge.handleTurnTerminal(event, context),
|
|
3839
|
+
"turn.started": (event, context) => bridge.handleTurnStarted(event, context)
|
|
3840
|
+
},
|
|
3841
|
+
flush,
|
|
3842
|
+
setup: options.setup
|
|
3843
|
+
};
|
|
3844
|
+
}
|
|
3845
|
+
var EveProviderBridge = class {
|
|
3846
|
+
constructor(metadata) {
|
|
3847
|
+
this.metadata = metadata;
|
|
3848
|
+
}
|
|
3849
|
+
metadata;
|
|
3850
|
+
activeActions = /* @__PURE__ */ new Map();
|
|
3851
|
+
activeModels = /* @__PURE__ */ new Map();
|
|
3852
|
+
modelsByAttempt = /* @__PURE__ */ new Map();
|
|
3853
|
+
settledOperations = new LRUCache({
|
|
3854
|
+
max: MAX_EVE_PROVIDER_CACHE_ENTRIES
|
|
3855
|
+
});
|
|
3856
|
+
turns = new LRUCache({
|
|
3857
|
+
max: MAX_EVE_PROVIDER_CACHE_ENTRIES
|
|
3858
|
+
});
|
|
3859
|
+
async handleTurnStarted(event, context) {
|
|
3860
|
+
await this.contain("turn start", async () => {
|
|
3861
|
+
if (this.settledOperations.has(event.idempotencyKey)) {
|
|
3862
|
+
context.state.set({ skip: true });
|
|
3863
|
+
return;
|
|
3864
|
+
}
|
|
3865
|
+
const { rowId, spanId } = await generateEveIds(
|
|
3866
|
+
"turn",
|
|
3867
|
+
event.idempotencyKey
|
|
3868
|
+
);
|
|
3869
|
+
const key = turnKey2(event.sessionId, event.turnId);
|
|
3870
|
+
const stored = storedSpan(context);
|
|
3871
|
+
if (stored && "exported" in stored && stored.rootSpanId) {
|
|
3872
|
+
this.turns.set(key, { rootSpanId: stored.rootSpanId, spanId });
|
|
3873
|
+
return;
|
|
3874
|
+
}
|
|
3875
|
+
let rootSpanId = spanId;
|
|
3876
|
+
let parentSpanId;
|
|
3877
|
+
if (event.parentLineage) {
|
|
3878
|
+
const parentTurnKey = turnKey2(
|
|
3879
|
+
event.parentLineage.sessionId,
|
|
3880
|
+
event.parentLineage.turnId
|
|
3881
|
+
);
|
|
3882
|
+
const parentTurn = this.turns.get(parentTurnKey);
|
|
3883
|
+
rootSpanId = parentTurn?.rootSpanId ?? // Eve propagates the root session through every nested subagent. Use
|
|
3884
|
+
// it instead of the immediate parent session when no ancestor ran
|
|
3885
|
+
// in-process.
|
|
3886
|
+
(await generateEveIds(
|
|
3887
|
+
"turn",
|
|
3888
|
+
turnIdempotencyKey(
|
|
3889
|
+
event.rootSessionId,
|
|
3890
|
+
event.parentLineage.turnId
|
|
3891
|
+
)
|
|
3892
|
+
)).spanId;
|
|
3893
|
+
parentSpanId = (await generateEveIds(
|
|
3894
|
+
"subagent",
|
|
3895
|
+
actionIdempotencyKey(
|
|
3896
|
+
event.parentLineage.sessionId,
|
|
3897
|
+
event.parentLineage.turnId,
|
|
3898
|
+
event.parentLineage.callId
|
|
3899
|
+
)
|
|
3900
|
+
)).spanId;
|
|
3901
|
+
}
|
|
3902
|
+
const metadata = this.spanMetadata(event.sessionId);
|
|
3903
|
+
const span = await this.startSpan(
|
|
3904
|
+
context,
|
|
3905
|
+
{
|
|
3906
|
+
event: { id: rowId, metadata },
|
|
3907
|
+
name: "eve.turn",
|
|
3908
|
+
parentSpanIds: parentSpanId ? { rootSpanId, spanId: parentSpanId } : { parentSpanIds: [], rootSpanId },
|
|
3909
|
+
spanAttributes: { type: "task" /* TASK */ },
|
|
3910
|
+
spanId
|
|
3911
|
+
},
|
|
3912
|
+
rootSpanId
|
|
3913
|
+
);
|
|
3914
|
+
span?.log({ metadata });
|
|
3915
|
+
this.turns.set(key, {
|
|
3916
|
+
rootSpanId,
|
|
3917
|
+
spanId
|
|
3918
|
+
});
|
|
3919
|
+
});
|
|
3920
|
+
}
|
|
3921
|
+
async handleTurnTerminal(event, context) {
|
|
3922
|
+
await this.contain("turn terminal", async () => {
|
|
3923
|
+
if (this.settledOperations.has(event.idempotencyKey)) {
|
|
3924
|
+
context.state.set(void 0);
|
|
3925
|
+
return;
|
|
3926
|
+
}
|
|
3927
|
+
const error = event.type === "turn.failed" ? event.error : void 0;
|
|
3928
|
+
this.drainActionsForTurn(event.sessionId, event.turnId, error);
|
|
3929
|
+
const stored = storedSpan(context);
|
|
3930
|
+
if (stored && "exported" in stored) {
|
|
3931
|
+
updateSpan({
|
|
3932
|
+
exported: stored.exported,
|
|
3933
|
+
...error !== void 0 ? { error } : {},
|
|
3934
|
+
metrics: { end: Date.now() / 1e3 }
|
|
3935
|
+
});
|
|
3936
|
+
}
|
|
3937
|
+
this.settledOperations.set(event.idempotencyKey, true);
|
|
3938
|
+
context.state.set(void 0);
|
|
3939
|
+
this.turns.delete(turnKey2(event.sessionId, event.turnId));
|
|
3940
|
+
});
|
|
3941
|
+
}
|
|
3942
|
+
async handleModelStarted(event, context) {
|
|
3943
|
+
await this.contain("model start", async () => {
|
|
3944
|
+
if (this.settledOperations.has(event.idempotencyKey)) {
|
|
3945
|
+
context.state.set({ skip: true });
|
|
3946
|
+
return;
|
|
3947
|
+
}
|
|
3948
|
+
const parent = await this.parentForScope(event.scope);
|
|
3949
|
+
const { rowId, spanId } = await generateEveIds(
|
|
3950
|
+
"step",
|
|
3951
|
+
event.idempotencyKey
|
|
3952
|
+
);
|
|
3953
|
+
const input = event.input ? capturedModelInput(event.input) : void 0;
|
|
3954
|
+
const metadata = {
|
|
3955
|
+
...this.spanMetadata(event.scope.sessionId),
|
|
3956
|
+
model: event.model.modelId,
|
|
3957
|
+
provider: event.model.provider
|
|
3958
|
+
};
|
|
3959
|
+
const span = await this.startSpan(context, {
|
|
3960
|
+
event: {
|
|
3961
|
+
id: rowId,
|
|
3962
|
+
...input !== void 0 ? { input } : {},
|
|
3963
|
+
metadata
|
|
3964
|
+
},
|
|
3965
|
+
name: "eve.step",
|
|
3966
|
+
parentSpanIds: parent,
|
|
3967
|
+
spanAttributes: { type: "llm" /* LLM */ },
|
|
3968
|
+
spanId
|
|
3969
|
+
});
|
|
3970
|
+
if (!span) return;
|
|
3971
|
+
span.log({ ...input !== void 0 ? { input } : {}, metadata });
|
|
3972
|
+
this.activeModels.set(event.idempotencyKey, {
|
|
3973
|
+
span,
|
|
3974
|
+
turnKey: turnKey2(event.scope.sessionId, event.scope.turnId)
|
|
3975
|
+
});
|
|
3976
|
+
const keys = this.modelsByAttempt.get(event.scope.attemptId) ?? /* @__PURE__ */ new Set();
|
|
3977
|
+
keys.add(event.idempotencyKey);
|
|
3978
|
+
this.modelsByAttempt.set(event.scope.attemptId, keys);
|
|
3979
|
+
});
|
|
3980
|
+
}
|
|
3981
|
+
async handleModelTerminal(event, context) {
|
|
3982
|
+
await this.contain("model terminal", async () => {
|
|
3983
|
+
if (this.settledOperations.has(event.idempotencyKey)) {
|
|
3984
|
+
context.state.set(void 0);
|
|
3985
|
+
return;
|
|
3986
|
+
}
|
|
3987
|
+
const active = this.activeModels.get(event.idempotencyKey);
|
|
3988
|
+
if (active) {
|
|
3989
|
+
const span = active.span;
|
|
3990
|
+
if (event.type === "model.call.failed") {
|
|
3991
|
+
if (event.error !== void 0) span.log({ error: event.error });
|
|
3992
|
+
} else {
|
|
3993
|
+
span.log({
|
|
3994
|
+
metrics: usageMetrics(event.usage),
|
|
3995
|
+
output: modelOutput(event)
|
|
3996
|
+
});
|
|
3997
|
+
}
|
|
3998
|
+
span.end();
|
|
3999
|
+
} else {
|
|
4000
|
+
const stored = storedSpan(context);
|
|
4001
|
+
if (stored && "exported" in stored) {
|
|
4002
|
+
updateSpan({
|
|
4003
|
+
exported: stored.exported,
|
|
4004
|
+
...event.type === "model.call.failed" ? event.error !== void 0 ? { error: event.error } : {} : { output: modelOutput(event) },
|
|
4005
|
+
metrics: {
|
|
4006
|
+
...event.type === "model.call.completed" ? usageMetrics(event.usage) : {},
|
|
4007
|
+
end: Date.now() / 1e3
|
|
4008
|
+
}
|
|
4009
|
+
});
|
|
4010
|
+
}
|
|
4011
|
+
}
|
|
4012
|
+
this.settledOperations.set(event.idempotencyKey, true);
|
|
4013
|
+
this.forgetModel(event.scope.attemptId, event.idempotencyKey);
|
|
4014
|
+
context.state.set(void 0);
|
|
4015
|
+
});
|
|
4016
|
+
}
|
|
4017
|
+
async handleActionStarted(event, context) {
|
|
4018
|
+
await this.contain("action start", async () => {
|
|
4019
|
+
if (event.kind === "load-skill" || this.settledOperations.has(event.idempotencyKey)) {
|
|
4020
|
+
context.state.set({ skip: true });
|
|
4021
|
+
return;
|
|
4022
|
+
}
|
|
4023
|
+
const parent = await this.parentForScope(event.scope);
|
|
4024
|
+
const { rowId, spanId } = await generateEveIds(
|
|
4025
|
+
event.kind === "subagent-call" ? "subagent" : "tool",
|
|
4026
|
+
event.idempotencyKey
|
|
4027
|
+
);
|
|
4028
|
+
const metadata = {
|
|
4029
|
+
...this.spanMetadata(event.scope.sessionId),
|
|
4030
|
+
"eve.action_kind": event.kind
|
|
4031
|
+
};
|
|
4032
|
+
const span = await this.startSpan(context, {
|
|
4033
|
+
event: {
|
|
4034
|
+
id: rowId,
|
|
4035
|
+
...event.input !== void 0 ? { input: event.input } : {},
|
|
4036
|
+
metadata
|
|
4037
|
+
},
|
|
4038
|
+
name: event.name,
|
|
4039
|
+
parentSpanIds: parent,
|
|
4040
|
+
spanAttributes: { type: "tool" /* TOOL */ },
|
|
4041
|
+
spanId
|
|
4042
|
+
});
|
|
4043
|
+
if (!span) return;
|
|
4044
|
+
span.log({
|
|
4045
|
+
...event.input !== void 0 ? { input: event.input } : {},
|
|
4046
|
+
metadata
|
|
4047
|
+
});
|
|
4048
|
+
this.activeActions.set(event.idempotencyKey, {
|
|
4049
|
+
span,
|
|
4050
|
+
turnKey: turnKey2(event.scope.sessionId, event.scope.turnId)
|
|
4051
|
+
});
|
|
4052
|
+
});
|
|
4053
|
+
}
|
|
4054
|
+
async handleActionTerminal(event, context) {
|
|
4055
|
+
await this.contain("action terminal", async () => {
|
|
4056
|
+
if (this.settledOperations.has(event.idempotencyKey)) {
|
|
4057
|
+
context.state.set(void 0);
|
|
4058
|
+
return;
|
|
4059
|
+
}
|
|
4060
|
+
const stored = storedSpan(context);
|
|
4061
|
+
if (stored?.skip) {
|
|
4062
|
+
context.state.set(void 0);
|
|
4063
|
+
return;
|
|
4064
|
+
}
|
|
4065
|
+
const active = this.activeActions.get(event.idempotencyKey);
|
|
4066
|
+
const end = finiteTimestamp(event.acceptedAtMs) ?? Date.now();
|
|
4067
|
+
if (active) {
|
|
4068
|
+
const span = active.span;
|
|
4069
|
+
if (event.type === "action.failed") {
|
|
4070
|
+
span.log({
|
|
4071
|
+
error: event.error ?? new Error(event.errorCode ?? `Eve action ${event.outcome}`)
|
|
4072
|
+
});
|
|
4073
|
+
} else if (event.output.type === "error") {
|
|
4074
|
+
span.log({
|
|
4075
|
+
error: event.output.error ?? new Error("Eve action returned an error")
|
|
4076
|
+
});
|
|
4077
|
+
} else {
|
|
4078
|
+
span.log({ output: event.output.output });
|
|
4079
|
+
}
|
|
4080
|
+
span.end({ endTime: end / 1e3 });
|
|
4081
|
+
} else {
|
|
4082
|
+
const stored2 = storedSpan(context);
|
|
4083
|
+
if (stored2 && "exported" in stored2) {
|
|
4084
|
+
updateSpan({
|
|
4085
|
+
exported: stored2.exported,
|
|
4086
|
+
...event.type === "action.failed" ? {
|
|
4087
|
+
error: event.error ?? new Error(event.errorCode ?? `Eve action ${event.outcome}`)
|
|
4088
|
+
} : event.output.type === "error" ? {
|
|
4089
|
+
error: event.output.error ?? new Error("Eve action returned an error")
|
|
4090
|
+
} : { output: event.output.output },
|
|
4091
|
+
metrics: { end: end / 1e3 }
|
|
4092
|
+
});
|
|
4093
|
+
}
|
|
4094
|
+
}
|
|
4095
|
+
this.settledOperations.set(event.idempotencyKey, true);
|
|
4096
|
+
this.activeActions.delete(event.idempotencyKey);
|
|
4097
|
+
context.state.set(void 0);
|
|
4098
|
+
});
|
|
4099
|
+
}
|
|
4100
|
+
handleStepAttemptTerminal(event) {
|
|
4101
|
+
void this.contain("step attempt terminal", () => {
|
|
4102
|
+
const keys = this.modelsByAttempt.get(event.scope.attemptId);
|
|
4103
|
+
if (!keys) return;
|
|
4104
|
+
for (const key of keys) {
|
|
4105
|
+
const active = this.activeModels.get(key);
|
|
4106
|
+
if (!active) continue;
|
|
4107
|
+
if (event.type === "step.attempt.failed" && event.error !== void 0) {
|
|
4108
|
+
active.span.log({ error: event.error });
|
|
4109
|
+
}
|
|
4110
|
+
active.span.end();
|
|
4111
|
+
this.activeModels.delete(key);
|
|
4112
|
+
}
|
|
4113
|
+
this.modelsByAttempt.delete(event.scope.attemptId);
|
|
4114
|
+
});
|
|
4115
|
+
}
|
|
4116
|
+
async parentForScope(scope) {
|
|
4117
|
+
const key = turnKey2(scope.sessionId, scope.turnId);
|
|
4118
|
+
const known = this.turns.get(key);
|
|
4119
|
+
if (known) {
|
|
4120
|
+
return { rootSpanId: known.rootSpanId, spanId: known.spanId };
|
|
4121
|
+
}
|
|
4122
|
+
const [{ spanId }, { spanId: rootSpanId }] = await Promise.all([
|
|
4123
|
+
generateEveIds("turn", turnIdempotencyKey(scope.sessionId, scope.turnId)),
|
|
4124
|
+
generateEveIds(
|
|
4125
|
+
"turn",
|
|
4126
|
+
turnIdempotencyKey(
|
|
4127
|
+
scope.rootSessionId ?? scope.sessionId,
|
|
4128
|
+
scope.turnId
|
|
4129
|
+
)
|
|
4130
|
+
)
|
|
4131
|
+
]);
|
|
4132
|
+
return { rootSpanId, spanId };
|
|
4133
|
+
}
|
|
4134
|
+
async startSpan(context, args, rootSpanId) {
|
|
4135
|
+
const span = withCurrent(
|
|
4136
|
+
NOOP_SPAN,
|
|
4137
|
+
() => _internalStartSpanWithInitialMerge(
|
|
4138
|
+
withSpanInstrumentationName(args ?? {}, INSTRUMENTATION_NAMES.EVE)
|
|
4139
|
+
)
|
|
4140
|
+
);
|
|
4141
|
+
try {
|
|
4142
|
+
context.state.set({
|
|
4143
|
+
exported: await span.export(),
|
|
4144
|
+
...rootSpanId ? { rootSpanId } : {}
|
|
4145
|
+
});
|
|
4146
|
+
} catch (error) {
|
|
4147
|
+
debugLogger.warn("Error exporting Eve provider span:", error);
|
|
4148
|
+
}
|
|
4149
|
+
return span;
|
|
4150
|
+
}
|
|
4151
|
+
drainActionsForTurn(sessionId, turnId, error) {
|
|
4152
|
+
const key = turnKey2(sessionId, turnId);
|
|
4153
|
+
for (const [idempotencyKey, active] of this.activeActions) {
|
|
4154
|
+
if (active.turnKey !== key) continue;
|
|
4155
|
+
if (error !== void 0) active.span.log({ error });
|
|
4156
|
+
active.span.end();
|
|
4157
|
+
this.activeActions.delete(idempotencyKey);
|
|
4158
|
+
}
|
|
4159
|
+
}
|
|
4160
|
+
forgetModel(attemptId, idempotencyKey) {
|
|
4161
|
+
this.activeModels.delete(idempotencyKey);
|
|
4162
|
+
const keys = this.modelsByAttempt.get(attemptId);
|
|
4163
|
+
keys?.delete(idempotencyKey);
|
|
4164
|
+
if (keys?.size === 0) this.modelsByAttempt.delete(attemptId);
|
|
4165
|
+
}
|
|
4166
|
+
spanMetadata(sessionId) {
|
|
4167
|
+
return {
|
|
4168
|
+
...this.metadata ?? {},
|
|
4169
|
+
"eve.session_id": sessionId
|
|
4170
|
+
};
|
|
4171
|
+
}
|
|
4172
|
+
async contain(operation, fn) {
|
|
4173
|
+
try {
|
|
4174
|
+
await fn();
|
|
4175
|
+
} catch (error) {
|
|
4176
|
+
debugLogger.warn(`Error in Eve provider ${operation}:`, error);
|
|
4177
|
+
}
|
|
4178
|
+
}
|
|
4179
|
+
};
|
|
4180
|
+
function storedSpan(context) {
|
|
4181
|
+
const value = context.state.get();
|
|
4182
|
+
if (!isObject(value)) return void 0;
|
|
4183
|
+
if (value["skip"] === true) return { skip: true };
|
|
4184
|
+
return typeof value["exported"] === "string" ? {
|
|
4185
|
+
exported: value["exported"],
|
|
4186
|
+
...typeof value["rootSpanId"] === "string" && value["rootSpanId"].length > 0 ? { rootSpanId: value["rootSpanId"] } : {}
|
|
4187
|
+
} : void 0;
|
|
4188
|
+
}
|
|
4189
|
+
function modelOutput(event) {
|
|
4190
|
+
const content = event.content ?? [];
|
|
4191
|
+
let text = "";
|
|
4192
|
+
const reasoning = [];
|
|
4193
|
+
const toolCalls2 = [];
|
|
4194
|
+
for (const part of content) {
|
|
4195
|
+
if (part.type === "text") {
|
|
4196
|
+
text += part.text;
|
|
4197
|
+
} else if (part.type === "reasoning" && part.text.trim().length > 0) {
|
|
4198
|
+
reasoning.push({ content: part.text });
|
|
4199
|
+
} else if (part.type === "tool-call") {
|
|
4200
|
+
toolCalls2.push({
|
|
4201
|
+
function: {
|
|
4202
|
+
arguments: safeJsonStringify(part.input),
|
|
4203
|
+
name: part.toolName
|
|
4204
|
+
},
|
|
4205
|
+
id: part.callId,
|
|
4206
|
+
type: "function"
|
|
4207
|
+
});
|
|
4208
|
+
}
|
|
4209
|
+
}
|
|
4210
|
+
return [
|
|
4211
|
+
{
|
|
4212
|
+
finish_reason: normalizeFinishReason2(event.finishReason),
|
|
4213
|
+
index: 0,
|
|
4214
|
+
message: {
|
|
4215
|
+
content: text || null,
|
|
4216
|
+
...reasoning.length > 0 ? { reasoning } : {},
|
|
4217
|
+
role: "assistant",
|
|
4218
|
+
...toolCalls2.length > 0 ? { tool_calls: toolCalls2 } : {}
|
|
4219
|
+
}
|
|
4220
|
+
}
|
|
4221
|
+
];
|
|
4222
|
+
}
|
|
4223
|
+
function usageMetrics(usage) {
|
|
4224
|
+
const promptTokens = nonNegativeNumber(usage.inputTokens);
|
|
4225
|
+
const completionTokens = nonNegativeNumber(usage.outputTokens);
|
|
4226
|
+
const cachedTokens = nonNegativeNumber(
|
|
4227
|
+
usage.inputTokenDetails?.cacheReadTokens
|
|
4228
|
+
);
|
|
4229
|
+
const cacheCreationTokens = nonNegativeNumber(
|
|
4230
|
+
usage.inputTokenDetails?.cacheWriteTokens
|
|
4231
|
+
);
|
|
4232
|
+
return {
|
|
4233
|
+
...promptTokens !== void 0 ? { prompt_tokens: promptTokens } : {},
|
|
4234
|
+
...completionTokens !== void 0 ? { completion_tokens: completionTokens } : {},
|
|
4235
|
+
...promptTokens !== void 0 && completionTokens !== void 0 ? { tokens: promptTokens + completionTokens } : {},
|
|
4236
|
+
...cachedTokens !== void 0 ? { prompt_cached_tokens: cachedTokens } : {},
|
|
4237
|
+
...cacheCreationTokens !== void 0 ? { prompt_cache_creation_tokens: cacheCreationTokens } : {}
|
|
4238
|
+
};
|
|
4239
|
+
}
|
|
4240
|
+
function nonNegativeNumber(value) {
|
|
4241
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : void 0;
|
|
4242
|
+
}
|
|
4243
|
+
function finiteTimestamp(value) {
|
|
4244
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
4245
|
+
}
|
|
4246
|
+
function normalizeFinishReason2(value) {
|
|
4247
|
+
if (value === "content-filter") return "content_filter";
|
|
4248
|
+
if (value === "tool-calls") return "tool_calls";
|
|
4249
|
+
return value;
|
|
4250
|
+
}
|
|
4251
|
+
function safeJsonStringify(value) {
|
|
4252
|
+
try {
|
|
4253
|
+
return JSON.stringify(value) ?? "null";
|
|
4254
|
+
} catch {
|
|
4255
|
+
return "null";
|
|
4256
|
+
}
|
|
4257
|
+
}
|
|
4258
|
+
function turnKey2(sessionId, turnId) {
|
|
4259
|
+
return `${sessionId}:${turnId}`;
|
|
4260
|
+
}
|
|
4261
|
+
function turnIdempotencyKey(sessionId, turnId) {
|
|
4262
|
+
return `turn:${sessionId}:${turnId}`;
|
|
4263
|
+
}
|
|
4264
|
+
function actionIdempotencyKey(sessionId, turnId, callId) {
|
|
4265
|
+
return `action:${sessionId}:${turnId}:${callId}`;
|
|
4266
|
+
}
|
|
4267
|
+
|
|
4268
|
+
// src/instrumentation/plugins/eve-instrumentation.ts
|
|
4269
|
+
var EVE_INSTRUMENTATION_PROVIDER = /* @__PURE__ */ Symbol.for("eve.instrumentation.provider");
|
|
4270
|
+
function braintrustEveInstrumentation(options) {
|
|
4271
|
+
const definition = "defineState" in options ? createLegacyEveInstrumentation(options) : createEveInstrumentationProvider(options);
|
|
4272
|
+
const declaration = {
|
|
4273
|
+
...definition,
|
|
4274
|
+
[EVE_INSTRUMENTATION_PROVIDER]: true
|
|
4275
|
+
};
|
|
4276
|
+
return declaration;
|
|
4277
|
+
}
|
|
4278
|
+
|
|
3527
4279
|
// src/typed-instrumentation-helpers.ts
|
|
3528
4280
|
var TypedApplyProxy = Proxy;
|
|
3529
4281
|
|
|
@@ -3705,11 +4457,11 @@ function wrapClaudeAgentQuery(queryFn, defaultThis) {
|
|
|
3705
4457
|
}
|
|
3706
4458
|
};
|
|
3707
4459
|
const invocationTarget = thisArg === proxy || thisArg === void 0 ? defaultThis ?? thisArg : thisArg;
|
|
3708
|
-
return claudeAgentSDKChannels.query.
|
|
3709
|
-
|
|
3710
|
-
|
|
3711
|
-
|
|
3712
|
-
{
|
|
4460
|
+
return claudeAgentSDKChannels.query.invoke(
|
|
4461
|
+
target,
|
|
4462
|
+
invocationTarget,
|
|
4463
|
+
[wrappedParams],
|
|
4464
|
+
{}
|
|
3713
4465
|
);
|
|
3714
4466
|
}
|
|
3715
4467
|
});
|
|
@@ -4324,13 +5076,11 @@ function wrapAgentInstance(agent) {
|
|
|
4324
5076
|
if (prop === "stream" && typeof value === "function") {
|
|
4325
5077
|
return function(args, options) {
|
|
4326
5078
|
const callArgs = [args, options];
|
|
4327
|
-
return strandsAgentSDKChannels.agentStream.
|
|
4328
|
-
|
|
4329
|
-
|
|
4330
|
-
|
|
4331
|
-
|
|
4332
|
-
self: proxy
|
|
4333
|
-
}
|
|
5079
|
+
return strandsAgentSDKChannels.agentStream.invoke(
|
|
5080
|
+
value,
|
|
5081
|
+
target,
|
|
5082
|
+
callArgs,
|
|
5083
|
+
{ agent: proxy }
|
|
4334
5084
|
);
|
|
4335
5085
|
};
|
|
4336
5086
|
}
|
|
@@ -4361,12 +5111,12 @@ function wrapMultiAgentInstance(orchestrator, kind) {
|
|
|
4361
5111
|
return function(input, options) {
|
|
4362
5112
|
const callArgs = [input, options];
|
|
4363
5113
|
const channel = kind === "graph" ? strandsAgentSDKChannels.graphStream : strandsAgentSDKChannels.swarmStream;
|
|
4364
|
-
return channel.
|
|
4365
|
-
|
|
5114
|
+
return channel.invoke(
|
|
5115
|
+
value,
|
|
5116
|
+
target,
|
|
5117
|
+
callArgs,
|
|
4366
5118
|
{
|
|
4367
|
-
|
|
4368
|
-
orchestrator: proxy,
|
|
4369
|
-
self: proxy
|
|
5119
|
+
orchestrator: proxy
|
|
4370
5120
|
}
|
|
4371
5121
|
);
|
|
4372
5122
|
};
|
|
@@ -6318,9 +7068,6 @@ var VitestContextManager = class {
|
|
|
6318
7068
|
getCurrentContext() {
|
|
6319
7069
|
return this.contextStorage.getStore();
|
|
6320
7070
|
}
|
|
6321
|
-
setContext(context) {
|
|
6322
|
-
this.contextStorage.enterWith(context);
|
|
6323
|
-
}
|
|
6324
7071
|
runInContext(context, callback) {
|
|
6325
7072
|
return this.contextStorage.run(context, callback);
|
|
6326
7073
|
}
|
|
@@ -6665,8 +7412,7 @@ function wrapDescribe(originalDescribe, config, afterAll) {
|
|
|
6665
7412
|
if (config.onProgress) {
|
|
6666
7413
|
config.onProgress({ type: "suite_start", suiteName });
|
|
6667
7414
|
}
|
|
6668
|
-
contextManager.
|
|
6669
|
-
factory();
|
|
7415
|
+
contextManager.runInContext(lazyContext, factory);
|
|
6670
7416
|
if (afterAll) {
|
|
6671
7417
|
afterAll(async () => {
|
|
6672
7418
|
await flushExperimentWithSync(context, config);
|
|
@@ -7245,7 +7991,7 @@ function isAsync(fn) {
|
|
|
7245
7991
|
function isAsyncGenerator(fn) {
|
|
7246
7992
|
return fn[Symbol.toStringTag] === "AsyncGenerator";
|
|
7247
7993
|
}
|
|
7248
|
-
function
|
|
7994
|
+
function isAsyncIterable2(obj) {
|
|
7249
7995
|
return typeof obj[Symbol.asyncIterator] === "function";
|
|
7250
7996
|
}
|
|
7251
7997
|
function wrapAsync(asyncFn) {
|
|
@@ -7417,7 +8163,7 @@ var eachOfLimit$2 = (limit) => {
|
|
|
7417
8163
|
if (isAsyncGenerator(obj)) {
|
|
7418
8164
|
return asyncEachOfLimit(obj, limit, iteratee, callback);
|
|
7419
8165
|
}
|
|
7420
|
-
if (
|
|
8166
|
+
if (isAsyncIterable2(obj)) {
|
|
7421
8167
|
return asyncEachOfLimit(obj[Symbol.asyncIterator](), limit, iteratee, callback);
|
|
7422
8168
|
}
|
|
7423
8169
|
var nextElem = createIterator(obj);
|
|
@@ -8772,7 +9518,7 @@ function callEvaluatorData(data) {
|
|
|
8772
9518
|
baseExperiment
|
|
8773
9519
|
};
|
|
8774
9520
|
}
|
|
8775
|
-
function
|
|
9521
|
+
function isAsyncIterable3(value) {
|
|
8776
9522
|
return typeof value === "object" && value !== null && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
8777
9523
|
}
|
|
8778
9524
|
function isIterable(value) {
|
|
@@ -8807,7 +9553,7 @@ async function _internalResolveEvaluatorData(evaluator, experiment) {
|
|
|
8807
9553
|
}).asDataset();
|
|
8808
9554
|
}
|
|
8809
9555
|
const resolvedDataResult = dataResult instanceof Promise ? await dataResult : dataResult;
|
|
8810
|
-
if (
|
|
9556
|
+
if (isAsyncIterable3(resolvedDataResult)) {
|
|
8811
9557
|
return resolvedDataResult;
|
|
8812
9558
|
}
|
|
8813
9559
|
if (Array.isArray(resolvedDataResult) || isIterable(resolvedDataResult)) {
|
|
@@ -11855,6 +12601,7 @@ export {
|
|
|
11855
12601
|
braintrustStreamChunkSchema,
|
|
11856
12602
|
buildLocalSummary,
|
|
11857
12603
|
collectAnthropicSession,
|
|
12604
|
+
completeOpenAIBatchTrace,
|
|
11858
12605
|
configureInstrumentation,
|
|
11859
12606
|
constructLogs3OverflowRequest,
|
|
11860
12607
|
createFinalValuePassThroughStream,
|
|
@@ -11894,6 +12641,8 @@ export {
|
|
|
11894
12641
|
loginToState,
|
|
11895
12642
|
logs3OverflowUploadSchema,
|
|
11896
12643
|
newId,
|
|
12644
|
+
openaiBatchesRetrieveTraced,
|
|
12645
|
+
openaiFilesCreateTraced,
|
|
11897
12646
|
parseCachedHeader,
|
|
11898
12647
|
parseTemplateFormat,
|
|
11899
12648
|
permalink,
|