braintrust 3.29.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/dev/dist/index.js +1465 -881
- package/dev/dist/index.mjs +846 -262
- package/dist/apply-auto-instrumentation.js +217 -217
- package/dist/apply-auto-instrumentation.mjs +2 -2
- package/dist/auto-instrumentations/bundler/esbuild.cjs +13 -1
- package/dist/auto-instrumentations/bundler/esbuild.mjs +2 -2
- package/dist/auto-instrumentations/bundler/next.cjs +13 -1
- package/dist/auto-instrumentations/bundler/next.mjs +3 -3
- package/dist/auto-instrumentations/bundler/rollup.cjs +13 -1
- package/dist/auto-instrumentations/bundler/rollup.mjs +2 -2
- package/dist/auto-instrumentations/bundler/vite.cjs +13 -1
- package/dist/auto-instrumentations/bundler/vite.mjs +2 -2
- package/dist/auto-instrumentations/bundler/webpack-loader.cjs +13 -1
- package/dist/auto-instrumentations/bundler/webpack.cjs +13 -1
- package/dist/auto-instrumentations/bundler/webpack.mjs +3 -3
- package/dist/auto-instrumentations/{chunk-DKTGDNA7.mjs → chunk-LW4HDHXT.mjs} +1 -1
- package/dist/auto-instrumentations/{chunk-OMCZ3MV2.mjs → chunk-OXINGIEZ.mjs} +1 -1
- package/dist/auto-instrumentations/{chunk-AOIYCVEL.mjs → chunk-U64OYU4Q.mjs} +13 -1
- package/dist/auto-instrumentations/hook.mjs +16 -4
- package/dist/auto-instrumentations/index.cjs +13 -1
- package/dist/auto-instrumentations/index.mjs +1 -1
- package/dist/browser.d.mts +133 -2
- package/dist/browser.d.ts +133 -2
- package/dist/browser.js +1143 -297
- package/dist/browser.mjs +1143 -297
- package/dist/{chunk-6Z5S7VOU.js → chunk-2XDW3UCG.js} +13 -1
- package/dist/{chunk-M6XPNJC4.mjs → chunk-BU6SM54N.mjs} +687 -115
- package/dist/{chunk-7FA6VP2S.mjs → chunk-N3JKQ3D3.mjs} +13 -1
- package/dist/{chunk-XLLGRXGR.js → chunk-TWCDSYJN.js} +1803 -1231
- package/dist/cli.js +819 -235
- package/dist/edge-light.d.mts +1 -1
- package/dist/edge-light.d.ts +1 -1
- package/dist/edge-light.js +1143 -297
- package/dist/edge-light.mjs +1143 -297
- package/dist/index.d.mts +133 -2
- package/dist/index.d.ts +133 -2
- package/dist/index.js +902 -640
- package/dist/index.mjs +336 -74
- package/dist/instrumentation/index.d.mts +15 -0
- package/dist/instrumentation/index.d.ts +15 -0
- package/dist/instrumentation/index.js +857 -262
- package/dist/instrumentation/index.mjs +857 -262
- 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 +1143 -297
- package/dist/workerd.mjs +1143 -297
- package/package.json +1 -1
package/dist/browser.mjs
CHANGED
|
@@ -5672,7 +5672,7 @@ var INSTRUMENTATION_NAMES = {
|
|
|
5672
5672
|
var INTERNAL_SPAN_INSTRUMENTATION_NAME = /* @__PURE__ */ Symbol.for(
|
|
5673
5673
|
"braintrust.spanInstrumentationName"
|
|
5674
5674
|
);
|
|
5675
|
-
var SDK_VERSION = true ? "3.
|
|
5675
|
+
var SDK_VERSION = true ? "3.30.0" : "0.0.0";
|
|
5676
5676
|
function withSpanInstrumentationName(args, instrumentationName) {
|
|
5677
5677
|
return {
|
|
5678
5678
|
...args,
|
|
@@ -9919,6 +9919,15 @@ function _internalStartSpanWithInitialMerge(args) {
|
|
|
9919
9919
|
[INITIAL_SPAN_WRITE_AS_MERGE]: true
|
|
9920
9920
|
}).span;
|
|
9921
9921
|
}
|
|
9922
|
+
function _internalStartSpanWithInitialMergeAndParentSpanIds(args) {
|
|
9923
|
+
return startSpanAndIsLogger(
|
|
9924
|
+
{
|
|
9925
|
+
...args,
|
|
9926
|
+
[INITIAL_SPAN_WRITE_AS_MERGE]: true
|
|
9927
|
+
},
|
|
9928
|
+
{ useParentSpanIdsForObjectParent: true }
|
|
9929
|
+
).span;
|
|
9930
|
+
}
|
|
9922
9931
|
function _internalStartSpanWithContext(args, context) {
|
|
9923
9932
|
return startSpanAndIsLogger({
|
|
9924
9933
|
...args,
|
|
@@ -9932,7 +9941,7 @@ async function flush(options) {
|
|
|
9932
9941
|
function setFetch(fetch2) {
|
|
9933
9942
|
_internalGetGlobalState().setFetch(fetch2);
|
|
9934
9943
|
}
|
|
9935
|
-
function startSpanAndIsLogger(args) {
|
|
9944
|
+
function startSpanAndIsLogger(args, internalOptions) {
|
|
9936
9945
|
const state = args?.state ?? _globalState;
|
|
9937
9946
|
const { parentObject, propagatedState } = getSpanParentObjectAndPropagatedState({
|
|
9938
9947
|
asyncFlush: args?.asyncFlush,
|
|
@@ -9946,7 +9955,7 @@ function startSpanAndIsLogger(args) {
|
|
|
9946
9955
|
) ? {
|
|
9947
9956
|
spanId: parentObject.data.span_id,
|
|
9948
9957
|
rootSpanId: parentObject.data.root_span_id
|
|
9949
|
-
} : void 0;
|
|
9958
|
+
} : internalOptions?.useParentSpanIdsForObjectParent ? args?.parentSpanIds : void 0;
|
|
9950
9959
|
const { parent: _ignoredParent, ...spanArgs } = args ?? {};
|
|
9951
9960
|
const span = new SpanImpl({
|
|
9952
9961
|
state,
|
|
@@ -13390,6 +13399,131 @@ function unsubscribeAll(unsubscribers) {
|
|
|
13390
13399
|
return [];
|
|
13391
13400
|
}
|
|
13392
13401
|
|
|
13402
|
+
// src/instrumentation/core/channel-definitions.ts
|
|
13403
|
+
function channel(spec) {
|
|
13404
|
+
return spec;
|
|
13405
|
+
}
|
|
13406
|
+
function defineChannels(pkg, channels, options) {
|
|
13407
|
+
const { instrumentationName } = options;
|
|
13408
|
+
return Object.fromEntries(
|
|
13409
|
+
Object.entries(channels).map(([key, spec]) => {
|
|
13410
|
+
const fullChannelName = `orchestrion:${pkg}:${spec.channelName}`;
|
|
13411
|
+
if (spec.kind === "async") {
|
|
13412
|
+
const asyncSpec = spec;
|
|
13413
|
+
const tracingChannel2 = () => isomorph_default.newTracingChannel(
|
|
13414
|
+
fullChannelName
|
|
13415
|
+
);
|
|
13416
|
+
const intercept2 = (interceptor) => {
|
|
13417
|
+
const hook = tracingChannel2();
|
|
13418
|
+
return typeof hook.intercept === "function" ? hook.intercept(interceptor) : () => {
|
|
13419
|
+
};
|
|
13420
|
+
};
|
|
13421
|
+
return [
|
|
13422
|
+
key,
|
|
13423
|
+
{
|
|
13424
|
+
...asyncSpec,
|
|
13425
|
+
instrumentationName,
|
|
13426
|
+
intercept: intercept2,
|
|
13427
|
+
invoke: (target, thisArg, args, additional) => {
|
|
13428
|
+
const hook = tracingChannel2();
|
|
13429
|
+
return typeof hook.invoke === "function" ? hook.invoke(target, thisArg, args, additional) : Reflect.apply(target, thisArg, args);
|
|
13430
|
+
},
|
|
13431
|
+
tracingChannel: tracingChannel2,
|
|
13432
|
+
tracePromise: (fn, context) => tracingChannel2().tracePromise(
|
|
13433
|
+
fn,
|
|
13434
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
13435
|
+
context
|
|
13436
|
+
)
|
|
13437
|
+
}
|
|
13438
|
+
];
|
|
13439
|
+
}
|
|
13440
|
+
const syncSpec = spec;
|
|
13441
|
+
const tracingChannel = () => isomorph_default.newTracingChannel(
|
|
13442
|
+
fullChannelName
|
|
13443
|
+
);
|
|
13444
|
+
const intercept = (interceptor) => {
|
|
13445
|
+
const hook = tracingChannel();
|
|
13446
|
+
return typeof hook.intercept === "function" ? hook.intercept(interceptor) : () => {
|
|
13447
|
+
};
|
|
13448
|
+
};
|
|
13449
|
+
return [
|
|
13450
|
+
key,
|
|
13451
|
+
{
|
|
13452
|
+
...syncSpec,
|
|
13453
|
+
instrumentationName,
|
|
13454
|
+
intercept,
|
|
13455
|
+
invoke: (target, thisArg, args, additional) => {
|
|
13456
|
+
const hook = tracingChannel();
|
|
13457
|
+
return typeof hook.invoke === "function" ? hook.invoke(target, thisArg, args, additional) : Reflect.apply(target, thisArg, args);
|
|
13458
|
+
},
|
|
13459
|
+
tracingChannel,
|
|
13460
|
+
traceSync: (fn, context) => tracingChannel().traceSync(
|
|
13461
|
+
fn,
|
|
13462
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
13463
|
+
context
|
|
13464
|
+
)
|
|
13465
|
+
}
|
|
13466
|
+
];
|
|
13467
|
+
})
|
|
13468
|
+
);
|
|
13469
|
+
}
|
|
13470
|
+
|
|
13471
|
+
// src/instrumentation/plugins/openai-channels.ts
|
|
13472
|
+
var openAIChannels = defineChannels(
|
|
13473
|
+
"openai",
|
|
13474
|
+
{
|
|
13475
|
+
filesCreateTraced: channel({
|
|
13476
|
+
channelName: "files.create-traced",
|
|
13477
|
+
kind: "async"
|
|
13478
|
+
}),
|
|
13479
|
+
batchesRetrieveTraced: channel({
|
|
13480
|
+
channelName: "batches.retrieve-traced",
|
|
13481
|
+
kind: "async"
|
|
13482
|
+
}),
|
|
13483
|
+
batchesCompleteTrace: channel({
|
|
13484
|
+
channelName: "batches.complete-trace",
|
|
13485
|
+
kind: "async"
|
|
13486
|
+
}),
|
|
13487
|
+
chatCompletionsCreate: channel({
|
|
13488
|
+
channelName: "chat.completions.create",
|
|
13489
|
+
kind: "async"
|
|
13490
|
+
}),
|
|
13491
|
+
embeddingsCreate: channel({
|
|
13492
|
+
channelName: "embeddings.create",
|
|
13493
|
+
kind: "async"
|
|
13494
|
+
}),
|
|
13495
|
+
betaChatCompletionsParse: channel({
|
|
13496
|
+
channelName: "beta.chat.completions.parse",
|
|
13497
|
+
kind: "async"
|
|
13498
|
+
}),
|
|
13499
|
+
betaChatCompletionsStream: channel({
|
|
13500
|
+
channelName: "beta.chat.completions.stream",
|
|
13501
|
+
kind: "sync-stream"
|
|
13502
|
+
}),
|
|
13503
|
+
moderationsCreate: channel({
|
|
13504
|
+
channelName: "moderations.create",
|
|
13505
|
+
kind: "async"
|
|
13506
|
+
}),
|
|
13507
|
+
responsesCreate: channel({
|
|
13508
|
+
channelName: "responses.create",
|
|
13509
|
+
kind: "async"
|
|
13510
|
+
}),
|
|
13511
|
+
responsesStream: channel({
|
|
13512
|
+
channelName: "responses.stream",
|
|
13513
|
+
kind: "sync-stream"
|
|
13514
|
+
}),
|
|
13515
|
+
responsesParse: channel({
|
|
13516
|
+
channelName: "responses.parse",
|
|
13517
|
+
kind: "async"
|
|
13518
|
+
}),
|
|
13519
|
+
responsesCompact: channel({
|
|
13520
|
+
channelName: "responses.compact",
|
|
13521
|
+
kind: "async"
|
|
13522
|
+
})
|
|
13523
|
+
},
|
|
13524
|
+
{ instrumentationName: INSTRUMENTATION_NAMES.OPENAI }
|
|
13525
|
+
);
|
|
13526
|
+
|
|
13393
13527
|
// src/wrappers/attachment-utils.ts
|
|
13394
13528
|
function getExtensionFromMediaType(mediaType) {
|
|
13395
13529
|
const extensionMap = {
|
|
@@ -13565,118 +13699,91 @@ function processInputAttachments(input) {
|
|
|
13565
13699
|
return processNode(input);
|
|
13566
13700
|
}
|
|
13567
13701
|
|
|
13568
|
-
// src/instrumentation/
|
|
13569
|
-
|
|
13570
|
-
|
|
13571
|
-
|
|
13572
|
-
|
|
13573
|
-
|
|
13574
|
-
|
|
13575
|
-
|
|
13576
|
-
|
|
13577
|
-
|
|
13578
|
-
|
|
13579
|
-
|
|
13580
|
-
|
|
13581
|
-
|
|
13582
|
-
|
|
13583
|
-
|
|
13584
|
-
|
|
13585
|
-
|
|
13586
|
-
|
|
13587
|
-
|
|
13588
|
-
|
|
13589
|
-
|
|
13590
|
-
...asyncSpec,
|
|
13591
|
-
instrumentationName,
|
|
13592
|
-
intercept: intercept2,
|
|
13593
|
-
invoke: (target, thisArg, args, additional) => {
|
|
13594
|
-
const hook = tracingChannel2();
|
|
13595
|
-
return typeof hook.invoke === "function" ? hook.invoke(target, thisArg, args, additional) : Reflect.apply(target, thisArg, args);
|
|
13596
|
-
},
|
|
13597
|
-
tracingChannel: tracingChannel2,
|
|
13598
|
-
tracePromise: (fn, context) => tracingChannel2().tracePromise(
|
|
13599
|
-
fn,
|
|
13600
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
13601
|
-
context
|
|
13602
|
-
)
|
|
13603
|
-
}
|
|
13604
|
-
];
|
|
13702
|
+
// src/instrumentation/plugins/openai-span-data.ts
|
|
13703
|
+
var OPENAI_METADATA_KEYS = [
|
|
13704
|
+
"model",
|
|
13705
|
+
"temperature",
|
|
13706
|
+
"top_p",
|
|
13707
|
+
"max_tokens",
|
|
13708
|
+
"frequency_penalty",
|
|
13709
|
+
"presence_penalty",
|
|
13710
|
+
"stop",
|
|
13711
|
+
"response_format",
|
|
13712
|
+
"tools",
|
|
13713
|
+
"tool_choice",
|
|
13714
|
+
"parallel_tool_calls",
|
|
13715
|
+
"max_tool_calls"
|
|
13716
|
+
];
|
|
13717
|
+
function batchMetadata(params) {
|
|
13718
|
+
const metadata = { provider: "openai" };
|
|
13719
|
+
for (const key of OPENAI_METADATA_KEYS) {
|
|
13720
|
+
try {
|
|
13721
|
+
const value = Reflect.get(params, key);
|
|
13722
|
+
if (value !== void 0) {
|
|
13723
|
+
metadata[key] = value;
|
|
13605
13724
|
}
|
|
13606
|
-
|
|
13607
|
-
|
|
13608
|
-
|
|
13609
|
-
|
|
13610
|
-
|
|
13611
|
-
|
|
13612
|
-
|
|
13613
|
-
|
|
13614
|
-
|
|
13615
|
-
|
|
13616
|
-
|
|
13617
|
-
|
|
13618
|
-
|
|
13619
|
-
|
|
13620
|
-
|
|
13621
|
-
|
|
13622
|
-
|
|
13623
|
-
|
|
13624
|
-
|
|
13625
|
-
|
|
13626
|
-
|
|
13627
|
-
|
|
13628
|
-
|
|
13629
|
-
|
|
13630
|
-
|
|
13631
|
-
|
|
13632
|
-
|
|
13633
|
-
|
|
13634
|
-
|
|
13725
|
+
} catch {
|
|
13726
|
+
}
|
|
13727
|
+
}
|
|
13728
|
+
return metadata;
|
|
13729
|
+
}
|
|
13730
|
+
function extractOpenAIBatchInput(endpoint, params) {
|
|
13731
|
+
const input = endpoint === "/v1/chat/completions" ? params.messages : params.input;
|
|
13732
|
+
return {
|
|
13733
|
+
input: processInputAttachments(input),
|
|
13734
|
+
metadata: batchMetadata(params)
|
|
13735
|
+
};
|
|
13736
|
+
}
|
|
13737
|
+
function extractOpenAIChatInput(params) {
|
|
13738
|
+
const { messages, ...metadata } = params;
|
|
13739
|
+
return {
|
|
13740
|
+
input: processInputAttachments(messages),
|
|
13741
|
+
metadata: { ...metadata, provider: "openai" }
|
|
13742
|
+
};
|
|
13743
|
+
}
|
|
13744
|
+
function extractOpenAIResponsesInput(params) {
|
|
13745
|
+
const { input, ...metadata } = params;
|
|
13746
|
+
return {
|
|
13747
|
+
input: processInputAttachments(input),
|
|
13748
|
+
metadata: { ...metadata, provider: "openai" }
|
|
13749
|
+
};
|
|
13750
|
+
}
|
|
13751
|
+
function extractOpenAIResponsesMetadata(result) {
|
|
13752
|
+
if (!result) {
|
|
13753
|
+
return void 0;
|
|
13754
|
+
}
|
|
13755
|
+
const { output: _output, usage: _usage, ...metadata } = result;
|
|
13756
|
+
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
13757
|
+
}
|
|
13758
|
+
function processImagesInOutput(output) {
|
|
13759
|
+
if (Array.isArray(output)) {
|
|
13760
|
+
return output.map(processImagesInOutput);
|
|
13761
|
+
}
|
|
13762
|
+
if (isObject(output) && output.type === "image_generation_call" && typeof output.result === "string" && output.result) {
|
|
13763
|
+
const fileExtension = output.output_format || "png";
|
|
13764
|
+
const contentType = `image/${fileExtension}`;
|
|
13765
|
+
const baseFilename = typeof output.revised_prompt === "string" ? output.revised_prompt.slice(0, 50).replace(/[^a-zA-Z0-9]/g, "_") : "generated_image";
|
|
13766
|
+
let binaryString;
|
|
13767
|
+
try {
|
|
13768
|
+
binaryString = atob(output.result);
|
|
13769
|
+
} catch {
|
|
13770
|
+
return output;
|
|
13771
|
+
}
|
|
13772
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
13773
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
13774
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
13775
|
+
}
|
|
13776
|
+
return {
|
|
13777
|
+
...output,
|
|
13778
|
+
result: new Attachment({
|
|
13779
|
+
data: new Blob([bytes], { type: contentType }),
|
|
13780
|
+
filename: `${baseFilename}.${fileExtension}`,
|
|
13781
|
+
contentType
|
|
13782
|
+
})
|
|
13783
|
+
};
|
|
13784
|
+
}
|
|
13785
|
+
return output;
|
|
13635
13786
|
}
|
|
13636
|
-
|
|
13637
|
-
// src/instrumentation/plugins/openai-channels.ts
|
|
13638
|
-
var openAIChannels = defineChannels(
|
|
13639
|
-
"openai",
|
|
13640
|
-
{
|
|
13641
|
-
chatCompletionsCreate: channel({
|
|
13642
|
-
channelName: "chat.completions.create",
|
|
13643
|
-
kind: "async"
|
|
13644
|
-
}),
|
|
13645
|
-
embeddingsCreate: channel({
|
|
13646
|
-
channelName: "embeddings.create",
|
|
13647
|
-
kind: "async"
|
|
13648
|
-
}),
|
|
13649
|
-
betaChatCompletionsParse: channel({
|
|
13650
|
-
channelName: "beta.chat.completions.parse",
|
|
13651
|
-
kind: "async"
|
|
13652
|
-
}),
|
|
13653
|
-
betaChatCompletionsStream: channel({
|
|
13654
|
-
channelName: "beta.chat.completions.stream",
|
|
13655
|
-
kind: "sync-stream"
|
|
13656
|
-
}),
|
|
13657
|
-
moderationsCreate: channel({
|
|
13658
|
-
channelName: "moderations.create",
|
|
13659
|
-
kind: "async"
|
|
13660
|
-
}),
|
|
13661
|
-
responsesCreate: channel({
|
|
13662
|
-
channelName: "responses.create",
|
|
13663
|
-
kind: "async"
|
|
13664
|
-
}),
|
|
13665
|
-
responsesStream: channel({
|
|
13666
|
-
channelName: "responses.stream",
|
|
13667
|
-
kind: "sync-stream"
|
|
13668
|
-
}),
|
|
13669
|
-
responsesParse: channel({
|
|
13670
|
-
channelName: "responses.parse",
|
|
13671
|
-
kind: "async"
|
|
13672
|
-
}),
|
|
13673
|
-
responsesCompact: channel({
|
|
13674
|
-
channelName: "responses.compact",
|
|
13675
|
-
kind: "async"
|
|
13676
|
-
})
|
|
13677
|
-
},
|
|
13678
|
-
{ instrumentationName: INSTRUMENTATION_NAMES.OPENAI }
|
|
13679
|
-
);
|
|
13680
13787
|
|
|
13681
13788
|
// src/openai-utils.ts
|
|
13682
13789
|
var BRAINTRUST_CACHED_STREAM_METRIC = "__braintrust_cached_metric";
|
|
@@ -13733,23 +13840,573 @@ function getCachedMetricFromHeaders(headers) {
|
|
|
13733
13840
|
return parseCachedHeader(headers.get(LEGACY_CACHED_HEADER));
|
|
13734
13841
|
}
|
|
13735
13842
|
|
|
13843
|
+
// src/instrumentation/plugins/openai-batch-instrumentation.ts
|
|
13844
|
+
var SUPPORTED_ENDPOINTS = /* @__PURE__ */ new Set(["/v1/chat/completions", "/v1/responses"]);
|
|
13845
|
+
var TERMINAL_STATUSES = /* @__PURE__ */ new Set([
|
|
13846
|
+
"completed",
|
|
13847
|
+
"failed",
|
|
13848
|
+
"expired",
|
|
13849
|
+
"cancelled"
|
|
13850
|
+
]);
|
|
13851
|
+
var pendingBatchTraces = /* @__PURE__ */ new Map();
|
|
13852
|
+
function read(value, key) {
|
|
13853
|
+
if (!isObject(value)) {
|
|
13854
|
+
return void 0;
|
|
13855
|
+
}
|
|
13856
|
+
try {
|
|
13857
|
+
return Reflect.get(value, key);
|
|
13858
|
+
} catch {
|
|
13859
|
+
return void 0;
|
|
13860
|
+
}
|
|
13861
|
+
}
|
|
13862
|
+
function isBatchRecordIterable(value) {
|
|
13863
|
+
if (value === null || typeof value !== "object" && typeof value !== "function") {
|
|
13864
|
+
return false;
|
|
13865
|
+
}
|
|
13866
|
+
return typeof read(value, Symbol.iterator) === "function" || typeof read(value, Symbol.asyncIterator) === "function";
|
|
13867
|
+
}
|
|
13868
|
+
function validCustomId(value) {
|
|
13869
|
+
return typeof value === "string" && value.length > 0 && value.length <= 64;
|
|
13870
|
+
}
|
|
13871
|
+
function logBatchInstrumentationError(context, error) {
|
|
13872
|
+
debugLogger.debug(`OpenAI Batch instrumentation ${context}:`, error);
|
|
13873
|
+
}
|
|
13874
|
+
async function exportParent(parent) {
|
|
13875
|
+
if ("toStr" in parent && typeof parent.toStr === "function") {
|
|
13876
|
+
return parent.toStr();
|
|
13877
|
+
}
|
|
13878
|
+
if ("export" in parent && typeof parent.export === "function") {
|
|
13879
|
+
return await parent.export();
|
|
13880
|
+
}
|
|
13881
|
+
return void 0;
|
|
13882
|
+
}
|
|
13883
|
+
async function deterministicDigest(namespace, ...parts) {
|
|
13884
|
+
const encoded = new TextEncoder().encode(
|
|
13885
|
+
[namespace, ...parts].map((part) => `${part.length}:${part}`).join("\0")
|
|
13886
|
+
);
|
|
13887
|
+
return new Uint8Array(
|
|
13888
|
+
await globalThis.crypto.subtle.digest("SHA-256", encoded)
|
|
13889
|
+
);
|
|
13890
|
+
}
|
|
13891
|
+
function digestHex(bytes, length) {
|
|
13892
|
+
return Array.from(bytes.slice(0, length)).map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
13893
|
+
}
|
|
13894
|
+
function digestUuid(bytes) {
|
|
13895
|
+
const hex = digestHex(bytes, 16);
|
|
13896
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
13897
|
+
}
|
|
13898
|
+
async function batchSpanIds(inputFileId) {
|
|
13899
|
+
const [row, span, root] = await Promise.all([
|
|
13900
|
+
deterministicDigest("openai:batch:row", inputFileId),
|
|
13901
|
+
deterministicDigest("openai:batch:span", inputFileId),
|
|
13902
|
+
deterministicDigest("openai:batch:root", inputFileId)
|
|
13903
|
+
]);
|
|
13904
|
+
return {
|
|
13905
|
+
rowId: digestUuid(row),
|
|
13906
|
+
spanId: digestHex(span, 8),
|
|
13907
|
+
rootSpanId: digestHex(root, 16)
|
|
13908
|
+
};
|
|
13909
|
+
}
|
|
13910
|
+
async function childSpanIds(inputFileId, customId) {
|
|
13911
|
+
const [row, span] = await Promise.all([
|
|
13912
|
+
deterministicDigest("openai:batch:child:row", inputFileId, customId),
|
|
13913
|
+
deterministicDigest("openai:batch:child:span", inputFileId, customId)
|
|
13914
|
+
]);
|
|
13915
|
+
return { rowId: digestUuid(row), spanId: digestHex(span, 8) };
|
|
13916
|
+
}
|
|
13917
|
+
async function startBatchSpan(context) {
|
|
13918
|
+
const ids = await batchSpanIds(context.inputFileId);
|
|
13919
|
+
const parent = SpanComponentsV4.fromStr(context.parent);
|
|
13920
|
+
const hasParentSpan = Boolean(
|
|
13921
|
+
parent.data.row_id && parent.data.span_id && parent.data.root_span_id
|
|
13922
|
+
);
|
|
13923
|
+
return withCurrent(
|
|
13924
|
+
NOOP_SPAN,
|
|
13925
|
+
() => _internalStartSpanWithInitialMergeAndParentSpanIds(
|
|
13926
|
+
withSpanInstrumentationName(
|
|
13927
|
+
{
|
|
13928
|
+
name: "openai.batch",
|
|
13929
|
+
type: "task" /* TASK */,
|
|
13930
|
+
parent: context.parent,
|
|
13931
|
+
...!hasParentSpan ? {
|
|
13932
|
+
parentSpanIds: {
|
|
13933
|
+
parentSpanIds: [],
|
|
13934
|
+
rootSpanId: ids.rootSpanId
|
|
13935
|
+
}
|
|
13936
|
+
} : {},
|
|
13937
|
+
spanId: ids.spanId,
|
|
13938
|
+
startTime: context.taskStartTime,
|
|
13939
|
+
event: {
|
|
13940
|
+
id: ids.rowId,
|
|
13941
|
+
metadata: {
|
|
13942
|
+
endpoint: context.endpoint,
|
|
13943
|
+
input_file_id: context.inputFileId,
|
|
13944
|
+
provider: "openai"
|
|
13945
|
+
}
|
|
13946
|
+
}
|
|
13947
|
+
},
|
|
13948
|
+
INSTRUMENTATION_NAMES.OPENAI
|
|
13949
|
+
)
|
|
13950
|
+
)
|
|
13951
|
+
);
|
|
13952
|
+
}
|
|
13953
|
+
async function startBatchChild(context, taskParent, input) {
|
|
13954
|
+
const ids = await childSpanIds(context.inputFileId, input.customId);
|
|
13955
|
+
return withCurrent(
|
|
13956
|
+
NOOP_SPAN,
|
|
13957
|
+
() => _internalStartSpanWithInitialMerge(
|
|
13958
|
+
withSpanInstrumentationName(
|
|
13959
|
+
{
|
|
13960
|
+
name: context.endpoint === "/v1/chat/completions" ? "Chat Completion" : "openai.responses.create",
|
|
13961
|
+
type: "llm" /* LLM */,
|
|
13962
|
+
parent: taskParent,
|
|
13963
|
+
spanId: ids.spanId,
|
|
13964
|
+
startTime: context.childStartTime,
|
|
13965
|
+
event: {
|
|
13966
|
+
id: ids.rowId,
|
|
13967
|
+
...input.spanData?.input !== void 0 ? { input: input.spanData.input } : {},
|
|
13968
|
+
metadata: {
|
|
13969
|
+
...input.spanData?.metadata,
|
|
13970
|
+
custom_id: input.customId,
|
|
13971
|
+
provider: "openai"
|
|
13972
|
+
}
|
|
13973
|
+
}
|
|
13974
|
+
},
|
|
13975
|
+
INSTRUMENTATION_NAMES.OPENAI
|
|
13976
|
+
)
|
|
13977
|
+
)
|
|
13978
|
+
);
|
|
13979
|
+
}
|
|
13980
|
+
async function* jsonlRecords(file, onIssue = () => {
|
|
13981
|
+
}) {
|
|
13982
|
+
const resolvedFile = await file;
|
|
13983
|
+
if (typeof resolvedFile === "string") {
|
|
13984
|
+
for (const line of resolvedFile.split("\n")) {
|
|
13985
|
+
if (!line.trim()) {
|
|
13986
|
+
continue;
|
|
13987
|
+
}
|
|
13988
|
+
try {
|
|
13989
|
+
yield JSON.parse(line.replace(/\r$/, ""));
|
|
13990
|
+
} catch (error) {
|
|
13991
|
+
logBatchInstrumentationError("skipped malformed JSONL", error);
|
|
13992
|
+
onIssue(new Error("OpenAI Batch file contains malformed JSONL"));
|
|
13993
|
+
}
|
|
13994
|
+
}
|
|
13995
|
+
return;
|
|
13996
|
+
}
|
|
13997
|
+
const body = read(resolvedFile, "body");
|
|
13998
|
+
const getReader = read(body, "getReader");
|
|
13999
|
+
if (isObject(body) && typeof getReader === "function") {
|
|
14000
|
+
let reader;
|
|
14001
|
+
try {
|
|
14002
|
+
reader = Reflect.apply(getReader, body, []);
|
|
14003
|
+
const decoder2 = new TextDecoder();
|
|
14004
|
+
let pending = "";
|
|
14005
|
+
while (true) {
|
|
14006
|
+
const readChunk = read(reader, "read");
|
|
14007
|
+
if (typeof readChunk !== "function") {
|
|
14008
|
+
throw new Error("Response body stream has no read method");
|
|
14009
|
+
}
|
|
14010
|
+
const chunk = await Reflect.apply(readChunk, reader, []);
|
|
14011
|
+
if (!isObject(chunk)) {
|
|
14012
|
+
throw new Error("Response body stream returned an invalid chunk");
|
|
14013
|
+
}
|
|
14014
|
+
if (chunk.done === true) {
|
|
14015
|
+
pending += decoder2.decode();
|
|
14016
|
+
break;
|
|
14017
|
+
}
|
|
14018
|
+
if (!(chunk.value instanceof Uint8Array)) {
|
|
14019
|
+
throw new Error("Response body stream returned a non-byte chunk");
|
|
14020
|
+
}
|
|
14021
|
+
pending += decoder2.decode(chunk.value, { stream: true });
|
|
14022
|
+
let newline = pending.indexOf("\n");
|
|
14023
|
+
while (newline !== -1) {
|
|
14024
|
+
const line = pending.slice(0, newline).replace(/\r$/, "");
|
|
14025
|
+
pending = pending.slice(newline + 1);
|
|
14026
|
+
if (line.trim()) {
|
|
14027
|
+
try {
|
|
14028
|
+
yield JSON.parse(line);
|
|
14029
|
+
} catch (error) {
|
|
14030
|
+
logBatchInstrumentationError("skipped malformed JSONL", error);
|
|
14031
|
+
onIssue(new Error("OpenAI Batch file contains malformed JSONL"));
|
|
14032
|
+
}
|
|
14033
|
+
}
|
|
14034
|
+
newline = pending.indexOf("\n");
|
|
14035
|
+
}
|
|
14036
|
+
}
|
|
14037
|
+
if (pending.trim()) {
|
|
14038
|
+
try {
|
|
14039
|
+
yield JSON.parse(pending.replace(/\r$/, ""));
|
|
14040
|
+
} catch (error) {
|
|
14041
|
+
logBatchInstrumentationError("skipped malformed JSONL", error);
|
|
14042
|
+
onIssue(new Error("OpenAI Batch file contains malformed JSONL"));
|
|
14043
|
+
}
|
|
14044
|
+
}
|
|
14045
|
+
} catch (error) {
|
|
14046
|
+
logBatchInstrumentationError("could not read JSONL response body", error);
|
|
14047
|
+
onIssue(new Error("OpenAI Batch response body could not be read"));
|
|
14048
|
+
} finally {
|
|
14049
|
+
const releaseLock = read(reader, "releaseLock");
|
|
14050
|
+
if (typeof releaseLock === "function") {
|
|
14051
|
+
try {
|
|
14052
|
+
Reflect.apply(releaseLock, reader, []);
|
|
14053
|
+
} catch (error) {
|
|
14054
|
+
logBatchInstrumentationError(
|
|
14055
|
+
"could not release stream reader",
|
|
14056
|
+
error
|
|
14057
|
+
);
|
|
14058
|
+
}
|
|
14059
|
+
}
|
|
14060
|
+
}
|
|
14061
|
+
return;
|
|
14062
|
+
}
|
|
14063
|
+
if (isBatchRecordIterable(resolvedFile)) {
|
|
14064
|
+
for await (const record of resolvedFile) {
|
|
14065
|
+
yield record;
|
|
14066
|
+
}
|
|
14067
|
+
return;
|
|
14068
|
+
}
|
|
14069
|
+
logBatchInstrumentationError("skipped invalid JSONL source", resolvedFile);
|
|
14070
|
+
onIssue(new Error("OpenAI Batch file source is invalid"));
|
|
14071
|
+
}
|
|
14072
|
+
async function readBatchInputs(file) {
|
|
14073
|
+
const inputs = /* @__PURE__ */ new Map();
|
|
14074
|
+
const issues = [];
|
|
14075
|
+
let endpoint;
|
|
14076
|
+
try {
|
|
14077
|
+
for await (const value of jsonlRecords(
|
|
14078
|
+
file,
|
|
14079
|
+
(issue) => issues.push(issue)
|
|
14080
|
+
)) {
|
|
14081
|
+
const customId = read(value, "custom_id");
|
|
14082
|
+
const url = read(value, "url");
|
|
14083
|
+
const body = read(value, "body");
|
|
14084
|
+
if (!validCustomId(customId) || inputs.has(customId) || read(value, "method") !== "POST" || typeof url !== "string" || !SUPPORTED_ENDPOINTS.has(url) || endpoint !== void 0 && endpoint !== url || !isObject(body)) {
|
|
14085
|
+
issues.push(new Error("OpenAI Batch input contains an invalid record"));
|
|
14086
|
+
continue;
|
|
14087
|
+
}
|
|
14088
|
+
endpoint = url;
|
|
14089
|
+
let spanData;
|
|
14090
|
+
try {
|
|
14091
|
+
spanData = extractOpenAIBatchInput(url, body);
|
|
14092
|
+
} catch (error) {
|
|
14093
|
+
logBatchInstrumentationError("could not extract batch input", error);
|
|
14094
|
+
}
|
|
14095
|
+
inputs.set(customId, { customId, spanData });
|
|
14096
|
+
}
|
|
14097
|
+
} catch (error) {
|
|
14098
|
+
logBatchInstrumentationError("could not process input file", error);
|
|
14099
|
+
issues.push(new Error("OpenAI Batch input file could not be processed"));
|
|
14100
|
+
}
|
|
14101
|
+
if (!endpoint || inputs.size === 0) {
|
|
14102
|
+
issues.push(new Error("OpenAI Batch input contains no supported records"));
|
|
14103
|
+
}
|
|
14104
|
+
return { endpoint, inputs, issues };
|
|
14105
|
+
}
|
|
14106
|
+
async function writePendingSpans(trace, endTime) {
|
|
14107
|
+
const task = await startBatchSpan(trace.context);
|
|
14108
|
+
const taskParent = await task.export();
|
|
14109
|
+
for (const input of trace.inputs.values()) {
|
|
14110
|
+
try {
|
|
14111
|
+
const child = await startBatchChild(trace.context, taskParent, input);
|
|
14112
|
+
if (endTime !== void 0) {
|
|
14113
|
+
child.end({ endTime });
|
|
14114
|
+
}
|
|
14115
|
+
} catch (error) {
|
|
14116
|
+
logBatchInstrumentationError("could not write batch request span", error);
|
|
14117
|
+
}
|
|
14118
|
+
}
|
|
14119
|
+
if (endTime !== void 0) {
|
|
14120
|
+
if (trace.status && trace.status !== "completed") {
|
|
14121
|
+
task.log({ error: new Error(`OpenAI Batch ${trace.status}`) });
|
|
14122
|
+
}
|
|
14123
|
+
task.end({ endTime });
|
|
14124
|
+
}
|
|
14125
|
+
}
|
|
14126
|
+
var interceptOpenAIFilesCreateTraced = async (target, thisArg, args) => {
|
|
14127
|
+
const startTime = getCurrentUnixTimestamp();
|
|
14128
|
+
const inputPromise = readBatchInputs(args[0].inputFileContent);
|
|
14129
|
+
const parentPromise = exportParent(args[0].parent);
|
|
14130
|
+
const file = await Reflect.apply(target, thisArg, args);
|
|
14131
|
+
try {
|
|
14132
|
+
const inputFileId = read(file, "id");
|
|
14133
|
+
const [inputData, exportedParent2] = await Promise.all([
|
|
14134
|
+
inputPromise,
|
|
14135
|
+
parentPromise
|
|
14136
|
+
]);
|
|
14137
|
+
if (typeof inputFileId !== "string" || !exportedParent2 || !inputData.endpoint || inputData.issues.length > 0) {
|
|
14138
|
+
if (inputData.issues[0]) {
|
|
14139
|
+
logBatchInstrumentationError(
|
|
14140
|
+
"skipped invalid input file",
|
|
14141
|
+
inputData.issues[0]
|
|
14142
|
+
);
|
|
14143
|
+
}
|
|
14144
|
+
return file;
|
|
14145
|
+
}
|
|
14146
|
+
const trace = {
|
|
14147
|
+
context: {
|
|
14148
|
+
inputFileId,
|
|
14149
|
+
endpoint: inputData.endpoint,
|
|
14150
|
+
parent: exportedParent2,
|
|
14151
|
+
taskStartTime: startTime,
|
|
14152
|
+
childStartTime: startTime
|
|
14153
|
+
},
|
|
14154
|
+
inputs: inputData.inputs
|
|
14155
|
+
};
|
|
14156
|
+
pendingBatchTraces.set(inputFileId, trace);
|
|
14157
|
+
await writePendingSpans(trace);
|
|
14158
|
+
} catch (error) {
|
|
14159
|
+
logBatchInstrumentationError("could not start batch spans", error);
|
|
14160
|
+
}
|
|
14161
|
+
return file;
|
|
14162
|
+
};
|
|
14163
|
+
function validTimestamp(value) {
|
|
14164
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0;
|
|
14165
|
+
}
|
|
14166
|
+
function terminalEndTime(batch, startTime) {
|
|
14167
|
+
let timestamp;
|
|
14168
|
+
switch (batch.status) {
|
|
14169
|
+
case "completed":
|
|
14170
|
+
timestamp = batch.completed_at;
|
|
14171
|
+
break;
|
|
14172
|
+
case "failed":
|
|
14173
|
+
timestamp = batch.failed_at;
|
|
14174
|
+
break;
|
|
14175
|
+
case "expired":
|
|
14176
|
+
timestamp = batch.expired_at;
|
|
14177
|
+
break;
|
|
14178
|
+
default:
|
|
14179
|
+
timestamp = batch.cancelled_at;
|
|
14180
|
+
}
|
|
14181
|
+
return validTimestamp(timestamp) ? Math.max(timestamp, startTime) : Math.max(getCurrentUnixTimestamp(), startTime);
|
|
14182
|
+
}
|
|
14183
|
+
async function updateBatchTimestamps(batch) {
|
|
14184
|
+
const trace = pendingBatchTraces.get(batch.input_file_id);
|
|
14185
|
+
if (!trace || trace.context.endpoint !== batch.endpoint) {
|
|
14186
|
+
return;
|
|
14187
|
+
}
|
|
14188
|
+
if (validTimestamp(batch.created_at)) {
|
|
14189
|
+
trace.context.taskStartTime = batch.created_at;
|
|
14190
|
+
}
|
|
14191
|
+
trace.context.childStartTime = validTimestamp(batch.in_progress_at) ? Math.max(batch.in_progress_at, trace.context.taskStartTime) : trace.context.taskStartTime;
|
|
14192
|
+
trace.status = batch.status;
|
|
14193
|
+
if (TERMINAL_STATUSES.has(batch.status)) {
|
|
14194
|
+
trace.endTime = terminalEndTime(batch, trace.context.childStartTime);
|
|
14195
|
+
}
|
|
14196
|
+
await writePendingSpans(trace, trace.endTime);
|
|
14197
|
+
}
|
|
14198
|
+
var interceptOpenAIBatchesRetrieveTraced = (target, thisArg, args) => Promise.resolve(Reflect.apply(target, thisArg, args)).then(async (batch) => {
|
|
14199
|
+
try {
|
|
14200
|
+
await updateBatchTimestamps(batch);
|
|
14201
|
+
} catch (error) {
|
|
14202
|
+
logBatchInstrumentationError("could not update batch timestamps", error);
|
|
14203
|
+
}
|
|
14204
|
+
return batch;
|
|
14205
|
+
});
|
|
14206
|
+
function errorFromResult(result) {
|
|
14207
|
+
const error = read(result.value, "error");
|
|
14208
|
+
if (isObject(error)) {
|
|
14209
|
+
const message = read(error, "message");
|
|
14210
|
+
return new Error(
|
|
14211
|
+
typeof message === "string" ? message : "OpenAI Batch request failed"
|
|
14212
|
+
);
|
|
14213
|
+
}
|
|
14214
|
+
const response = read(result.value, "response");
|
|
14215
|
+
const statusCode = read(response, "status_code");
|
|
14216
|
+
if (result.source === "error" || typeof statusCode === "number" && (statusCode < 200 || statusCode >= 300)) {
|
|
14217
|
+
const message = read(read(read(response, "body"), "error"), "message");
|
|
14218
|
+
return new Error(
|
|
14219
|
+
typeof message === "string" ? message : "OpenAI Batch request failed"
|
|
14220
|
+
);
|
|
14221
|
+
}
|
|
14222
|
+
return void 0;
|
|
14223
|
+
}
|
|
14224
|
+
async function completeBatchResult(context, taskParent, endTime, input, result) {
|
|
14225
|
+
const child = await startBatchChild(context, taskParent, input);
|
|
14226
|
+
try {
|
|
14227
|
+
const resultError = errorFromResult(result);
|
|
14228
|
+
const responseBody = read(read(result.value, "response"), "body");
|
|
14229
|
+
if (resultError) {
|
|
14230
|
+
child.log({ error: resultError });
|
|
14231
|
+
} else if (isObject(responseBody)) {
|
|
14232
|
+
const model = read(responseBody, "model");
|
|
14233
|
+
child.log({
|
|
14234
|
+
output: context.endpoint === "/v1/chat/completions" ? read(responseBody, "choices") : processImagesInOutput(read(responseBody, "output")),
|
|
14235
|
+
...typeof model === "string" ? { metadata: { model } } : {},
|
|
14236
|
+
metrics: parseMetricsFromUsage(read(responseBody, "usage"))
|
|
14237
|
+
});
|
|
14238
|
+
} else {
|
|
14239
|
+
child.log({ error: new Error("OpenAI Batch response body is missing") });
|
|
14240
|
+
}
|
|
14241
|
+
} catch (error) {
|
|
14242
|
+
child.log({ error });
|
|
14243
|
+
} finally {
|
|
14244
|
+
child.end({ endTime });
|
|
14245
|
+
}
|
|
14246
|
+
}
|
|
14247
|
+
async function completeResultFile({
|
|
14248
|
+
context,
|
|
14249
|
+
endTime,
|
|
14250
|
+
file,
|
|
14251
|
+
inputs,
|
|
14252
|
+
issues,
|
|
14253
|
+
seen,
|
|
14254
|
+
source,
|
|
14255
|
+
taskParent
|
|
14256
|
+
}) {
|
|
14257
|
+
if (file === void 0) {
|
|
14258
|
+
return;
|
|
14259
|
+
}
|
|
14260
|
+
for await (const value of jsonlRecords(file, (issue) => issues.push(issue))) {
|
|
14261
|
+
const customId = read(value, "custom_id");
|
|
14262
|
+
if (!validCustomId(customId) || !isObject(value)) {
|
|
14263
|
+
issues.push(
|
|
14264
|
+
new Error("OpenAI Batch result is missing a valid custom_id")
|
|
14265
|
+
);
|
|
14266
|
+
continue;
|
|
14267
|
+
}
|
|
14268
|
+
if (seen.has(customId)) {
|
|
14269
|
+
issues.push(new Error("OpenAI Batch result contains a duplicate"));
|
|
14270
|
+
continue;
|
|
14271
|
+
}
|
|
14272
|
+
const input = inputs.get(customId);
|
|
14273
|
+
if (!input) {
|
|
14274
|
+
issues.push(
|
|
14275
|
+
new Error("OpenAI Batch result does not match an input record")
|
|
14276
|
+
);
|
|
14277
|
+
continue;
|
|
14278
|
+
}
|
|
14279
|
+
seen.add(customId);
|
|
14280
|
+
await completeBatchResult(context, taskParent, endTime, input, {
|
|
14281
|
+
value,
|
|
14282
|
+
source
|
|
14283
|
+
});
|
|
14284
|
+
}
|
|
14285
|
+
}
|
|
14286
|
+
function sameInputs(first, second) {
|
|
14287
|
+
return first.size === second.size && [...first.keys()].every((customId) => second.has(customId));
|
|
14288
|
+
}
|
|
14289
|
+
async function contextForCompletion(inputFileId, inputData) {
|
|
14290
|
+
if (!inputData.endpoint || inputData.issues.length > 0) {
|
|
14291
|
+
return void 0;
|
|
14292
|
+
}
|
|
14293
|
+
const existing = pendingBatchTraces.get(inputFileId);
|
|
14294
|
+
if (existing) {
|
|
14295
|
+
if (existing.context.endpoint !== inputData.endpoint || !sameInputs(existing.inputs, inputData.inputs)) {
|
|
14296
|
+
return void 0;
|
|
14297
|
+
}
|
|
14298
|
+
return { ...existing, inputs: inputData.inputs };
|
|
14299
|
+
}
|
|
14300
|
+
const parent = await exportParent(getSpanParentObject());
|
|
14301
|
+
if (!parent) {
|
|
14302
|
+
return void 0;
|
|
14303
|
+
}
|
|
14304
|
+
const startTime = getCurrentUnixTimestamp();
|
|
14305
|
+
return {
|
|
14306
|
+
context: {
|
|
14307
|
+
inputFileId,
|
|
14308
|
+
endpoint: inputData.endpoint,
|
|
14309
|
+
parent,
|
|
14310
|
+
taskStartTime: startTime,
|
|
14311
|
+
childStartTime: startTime
|
|
14312
|
+
},
|
|
14313
|
+
inputs: inputData.inputs
|
|
14314
|
+
};
|
|
14315
|
+
}
|
|
14316
|
+
async function completeBatch(args) {
|
|
14317
|
+
const inputData = await readBatchInputs(args.inputFileContent);
|
|
14318
|
+
const trace = await contextForCompletion(args.inputFileId, inputData);
|
|
14319
|
+
if (!trace) {
|
|
14320
|
+
logBatchInstrumentationError(
|
|
14321
|
+
"left batch spans pending",
|
|
14322
|
+
inputData.issues[0] ?? new Error("OpenAI Batch input does not match")
|
|
14323
|
+
);
|
|
14324
|
+
return;
|
|
14325
|
+
}
|
|
14326
|
+
const endTime = trace.endTime ?? getCurrentUnixTimestamp();
|
|
14327
|
+
const task = await startBatchSpan(trace.context);
|
|
14328
|
+
const taskParent = await task.export();
|
|
14329
|
+
const issues = [];
|
|
14330
|
+
const seen = /* @__PURE__ */ new Set();
|
|
14331
|
+
await Promise.all([
|
|
14332
|
+
completeResultFile({
|
|
14333
|
+
context: trace.context,
|
|
14334
|
+
endTime,
|
|
14335
|
+
file: args.outputFileContent,
|
|
14336
|
+
inputs: trace.inputs,
|
|
14337
|
+
issues,
|
|
14338
|
+
seen,
|
|
14339
|
+
source: "output",
|
|
14340
|
+
taskParent
|
|
14341
|
+
}),
|
|
14342
|
+
completeResultFile({
|
|
14343
|
+
context: trace.context,
|
|
14344
|
+
endTime,
|
|
14345
|
+
file: args.errorFileContent,
|
|
14346
|
+
inputs: trace.inputs,
|
|
14347
|
+
issues,
|
|
14348
|
+
seen,
|
|
14349
|
+
source: "error",
|
|
14350
|
+
taskParent
|
|
14351
|
+
})
|
|
14352
|
+
]);
|
|
14353
|
+
if (issues.length > 0) {
|
|
14354
|
+
logBatchInstrumentationError("left batch spans pending", issues[0]);
|
|
14355
|
+
return;
|
|
14356
|
+
}
|
|
14357
|
+
const missing = [...trace.inputs.values()].filter(
|
|
14358
|
+
({ customId }) => !seen.has(customId)
|
|
14359
|
+
);
|
|
14360
|
+
if (!trace.status || trace.status === "completed") {
|
|
14361
|
+
if (missing.length > 0) {
|
|
14362
|
+
logBatchInstrumentationError(
|
|
14363
|
+
"left batch spans pending",
|
|
14364
|
+
new Error("OpenAI Batch result files are incomplete")
|
|
14365
|
+
);
|
|
14366
|
+
return;
|
|
14367
|
+
}
|
|
14368
|
+
} else {
|
|
14369
|
+
for (const input of missing) {
|
|
14370
|
+
const child = await startBatchChild(trace.context, taskParent, input);
|
|
14371
|
+
child.log({ error: new Error(`OpenAI Batch ${trace.status}`) });
|
|
14372
|
+
child.end({ endTime });
|
|
14373
|
+
}
|
|
14374
|
+
task.log({ error: new Error(`OpenAI Batch ${trace.status}`) });
|
|
14375
|
+
}
|
|
14376
|
+
task.end({ endTime });
|
|
14377
|
+
pendingBatchTraces.delete(args.inputFileId);
|
|
14378
|
+
}
|
|
14379
|
+
var interceptOpenAIBatchTraceComplete = (target, thisArg, args) => Promise.resolve(Reflect.apply(target, thisArg, args)).then(async (result) => {
|
|
14380
|
+
try {
|
|
14381
|
+
await completeBatch(args[0]);
|
|
14382
|
+
} catch (error) {
|
|
14383
|
+
logBatchInstrumentationError("could not complete batch", error);
|
|
14384
|
+
}
|
|
14385
|
+
return result;
|
|
14386
|
+
});
|
|
14387
|
+
|
|
13736
14388
|
// src/instrumentation/plugins/openai-plugin.ts
|
|
13737
14389
|
var OpenAIPlugin = class extends BasePlugin {
|
|
13738
14390
|
constructor() {
|
|
13739
14391
|
super();
|
|
13740
14392
|
}
|
|
13741
14393
|
onEnable() {
|
|
14394
|
+
this.unsubscribers.push(
|
|
14395
|
+
openAIChannels.filesCreateTraced.intercept(
|
|
14396
|
+
interceptOpenAIFilesCreateTraced
|
|
14397
|
+
),
|
|
14398
|
+
openAIChannels.batchesRetrieveTraced.intercept(
|
|
14399
|
+
interceptOpenAIBatchesRetrieveTraced
|
|
14400
|
+
),
|
|
14401
|
+
openAIChannels.batchesCompleteTrace.intercept(
|
|
14402
|
+
interceptOpenAIBatchTraceComplete
|
|
14403
|
+
)
|
|
14404
|
+
);
|
|
13742
14405
|
this.unsubscribers.push(
|
|
13743
14406
|
traceStreamingChannel(openAIChannels.chatCompletionsCreate, {
|
|
13744
14407
|
name: "Chat Completion",
|
|
13745
14408
|
type: "llm" /* LLM */,
|
|
13746
|
-
extractInput: ([params]) =>
|
|
13747
|
-
const { messages, ...metadata } = params;
|
|
13748
|
-
return {
|
|
13749
|
-
input: processInputAttachments(messages),
|
|
13750
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13751
|
-
};
|
|
13752
|
-
},
|
|
14409
|
+
extractInput: ([params]) => extractOpenAIChatInput(params),
|
|
13753
14410
|
extractOutput: (result) => {
|
|
13754
14411
|
return result?.choices;
|
|
13755
14412
|
},
|
|
@@ -13795,13 +14452,7 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13795
14452
|
traceStreamingChannel(openAIChannels.betaChatCompletionsParse, {
|
|
13796
14453
|
name: "Chat Completion",
|
|
13797
14454
|
type: "llm" /* LLM */,
|
|
13798
|
-
extractInput: ([params]) =>
|
|
13799
|
-
const { messages, ...metadata } = params;
|
|
13800
|
-
return {
|
|
13801
|
-
input: processInputAttachments(messages),
|
|
13802
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13803
|
-
};
|
|
13804
|
-
},
|
|
14455
|
+
extractInput: ([params]) => extractOpenAIChatInput(params),
|
|
13805
14456
|
extractOutput: (result) => {
|
|
13806
14457
|
return result?.choices;
|
|
13807
14458
|
},
|
|
@@ -13823,13 +14474,7 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13823
14474
|
traceSyncStreamChannel(openAIChannels.betaChatCompletionsStream, {
|
|
13824
14475
|
name: "Chat Completion",
|
|
13825
14476
|
type: "llm" /* LLM */,
|
|
13826
|
-
extractInput: ([params]) =>
|
|
13827
|
-
const { messages, ...metadata } = params;
|
|
13828
|
-
return {
|
|
13829
|
-
input: processInputAttachments(messages),
|
|
13830
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13831
|
-
};
|
|
13832
|
-
}
|
|
14477
|
+
extractInput: ([params]) => extractOpenAIChatInput(params)
|
|
13833
14478
|
})
|
|
13834
14479
|
);
|
|
13835
14480
|
this.unsubscribers.push(
|
|
@@ -13859,23 +14504,11 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13859
14504
|
traceStreamingChannel(openAIChannels.responsesCreate, {
|
|
13860
14505
|
name: "openai.responses.create",
|
|
13861
14506
|
type: "llm" /* LLM */,
|
|
13862
|
-
extractInput: ([params]) =>
|
|
13863
|
-
const { input, ...metadata } = params;
|
|
13864
|
-
return {
|
|
13865
|
-
input: processInputAttachments(input),
|
|
13866
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13867
|
-
};
|
|
13868
|
-
},
|
|
14507
|
+
extractInput: ([params]) => extractOpenAIResponsesInput(params),
|
|
13869
14508
|
extractOutput: (result) => {
|
|
13870
14509
|
return processImagesInOutput(result?.output);
|
|
13871
14510
|
},
|
|
13872
|
-
extractMetadata: (result) =>
|
|
13873
|
-
if (!result) {
|
|
13874
|
-
return void 0;
|
|
13875
|
-
}
|
|
13876
|
-
const { output: _output, usage: _usage, ...metadata } = result;
|
|
13877
|
-
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
13878
|
-
},
|
|
14511
|
+
extractMetadata: (result) => extractOpenAIResponsesMetadata(result),
|
|
13879
14512
|
extractMetrics: (result, startTime, endEvent) => {
|
|
13880
14513
|
const metrics = withCachedMetric(
|
|
13881
14514
|
parseMetricsFromUsage(result?.usage),
|
|
@@ -13894,13 +14527,7 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13894
14527
|
traceSyncStreamChannel(openAIChannels.responsesStream, {
|
|
13895
14528
|
name: "openai.responses.create",
|
|
13896
14529
|
type: "llm" /* LLM */,
|
|
13897
|
-
extractInput: ([params]) =>
|
|
13898
|
-
const { input, ...metadata } = params;
|
|
13899
|
-
return {
|
|
13900
|
-
input: processInputAttachments(input),
|
|
13901
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13902
|
-
};
|
|
13903
|
-
},
|
|
14530
|
+
extractInput: ([params]) => extractOpenAIResponsesInput(params),
|
|
13904
14531
|
extractFromEvent: (event) => {
|
|
13905
14532
|
if (event.type !== "response.completed" || !event.response) {
|
|
13906
14533
|
return {};
|
|
@@ -13923,23 +14550,11 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13923
14550
|
traceStreamingChannel(openAIChannels.responsesParse, {
|
|
13924
14551
|
name: "openai.responses.parse",
|
|
13925
14552
|
type: "llm" /* LLM */,
|
|
13926
|
-
extractInput: ([params]) =>
|
|
13927
|
-
const { input, ...metadata } = params;
|
|
13928
|
-
return {
|
|
13929
|
-
input: processInputAttachments(input),
|
|
13930
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13931
|
-
};
|
|
13932
|
-
},
|
|
14553
|
+
extractInput: ([params]) => extractOpenAIResponsesInput(params),
|
|
13933
14554
|
extractOutput: (result) => {
|
|
13934
14555
|
return processImagesInOutput(result?.output);
|
|
13935
14556
|
},
|
|
13936
|
-
extractMetadata: (result) =>
|
|
13937
|
-
if (!result) {
|
|
13938
|
-
return void 0;
|
|
13939
|
-
}
|
|
13940
|
-
const { output: _output, usage: _usage, ...metadata } = result;
|
|
13941
|
-
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
13942
|
-
},
|
|
14557
|
+
extractMetadata: (result) => extractOpenAIResponsesMetadata(result),
|
|
13943
14558
|
extractMetrics: (result, startTime, endEvent) => {
|
|
13944
14559
|
const metrics = withCachedMetric(
|
|
13945
14560
|
parseMetricsFromUsage(result?.usage),
|
|
@@ -13958,23 +14573,11 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13958
14573
|
traceAsyncChannel(openAIChannels.responsesCompact, {
|
|
13959
14574
|
name: "openai.responses.compact",
|
|
13960
14575
|
type: "llm" /* LLM */,
|
|
13961
|
-
extractInput: ([params]) =>
|
|
13962
|
-
const { input, ...metadata } = params;
|
|
13963
|
-
return {
|
|
13964
|
-
input: processInputAttachments(input),
|
|
13965
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13966
|
-
};
|
|
13967
|
-
},
|
|
14576
|
+
extractInput: ([params]) => extractOpenAIResponsesInput(params),
|
|
13968
14577
|
extractOutput: (result) => {
|
|
13969
14578
|
return processImagesInOutput(result?.output);
|
|
13970
14579
|
},
|
|
13971
|
-
extractMetadata: (result) =>
|
|
13972
|
-
if (!result) {
|
|
13973
|
-
return void 0;
|
|
13974
|
-
}
|
|
13975
|
-
const { output: _output, usage: _usage, ...metadata } = result;
|
|
13976
|
-
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
13977
|
-
},
|
|
14580
|
+
extractMetadata: (result) => extractOpenAIResponsesMetadata(result),
|
|
13978
14581
|
extractMetrics: (result, startTime, endEvent) => {
|
|
13979
14582
|
const metrics = withCachedMetric(
|
|
13980
14583
|
parseMetricsFromUsage(result?.usage),
|
|
@@ -14030,35 +14633,6 @@ function withCachedMetric(metrics, result, endEvent) {
|
|
|
14030
14633
|
cached
|
|
14031
14634
|
};
|
|
14032
14635
|
}
|
|
14033
|
-
function processImagesInOutput(output) {
|
|
14034
|
-
if (Array.isArray(output)) {
|
|
14035
|
-
return output.map(processImagesInOutput);
|
|
14036
|
-
}
|
|
14037
|
-
if (isObject(output)) {
|
|
14038
|
-
if (output.type === "image_generation_call" && output.result && typeof output.result === "string") {
|
|
14039
|
-
const fileExtension = output.output_format || "png";
|
|
14040
|
-
const contentType = `image/${fileExtension}`;
|
|
14041
|
-
const baseFilename = output.revised_prompt && typeof output.revised_prompt === "string" ? output.revised_prompt.slice(0, 50).replace(/[^a-zA-Z0-9]/g, "_") : "generated_image";
|
|
14042
|
-
const filename = `${baseFilename}.${fileExtension}`;
|
|
14043
|
-
const binaryString = atob(output.result);
|
|
14044
|
-
const bytes = new Uint8Array(binaryString.length);
|
|
14045
|
-
for (let i = 0; i < binaryString.length; i++) {
|
|
14046
|
-
bytes[i] = binaryString.charCodeAt(i);
|
|
14047
|
-
}
|
|
14048
|
-
const blob = new Blob([bytes], { type: contentType });
|
|
14049
|
-
const attachment = new Attachment({
|
|
14050
|
-
data: blob,
|
|
14051
|
-
filename,
|
|
14052
|
-
contentType
|
|
14053
|
-
});
|
|
14054
|
-
return {
|
|
14055
|
-
...output,
|
|
14056
|
-
result: attachment
|
|
14057
|
-
};
|
|
14058
|
-
}
|
|
14059
|
-
}
|
|
14060
|
-
return output;
|
|
14061
|
-
}
|
|
14062
14636
|
function mergeLogprobTokens(existing, incoming) {
|
|
14063
14637
|
if (incoming === void 0) {
|
|
14064
14638
|
return existing;
|
|
@@ -34091,7 +34665,7 @@ function extractSession(event) {
|
|
|
34091
34665
|
return isObject(candidate) && typeof candidate.prompt === "function" ? candidate : void 0;
|
|
34092
34666
|
}
|
|
34093
34667
|
function isPiAgent(value) {
|
|
34094
|
-
return isObject(value) && typeof value.streamFn === "function" && typeof value.subscribe === "function";
|
|
34668
|
+
return isObject(value) && (typeof value.streamFunction === "function" || typeof value.streamFn === "function") && typeof value.subscribe === "function";
|
|
34095
34669
|
}
|
|
34096
34670
|
function promptContextStore() {
|
|
34097
34671
|
piPromptContextStore ??= isomorph_default.newAsyncLocalStorage();
|
|
@@ -34101,17 +34675,21 @@ function currentPiPromptState() {
|
|
|
34101
34675
|
return promptContextStore().getStore();
|
|
34102
34676
|
}
|
|
34103
34677
|
function installPiAgentInstrumentation(agent) {
|
|
34678
|
+
const property = typeof agent.streamFunction === "function" ? "streamFunction" : "streamFn";
|
|
34679
|
+
const streamFunction = agent[property];
|
|
34104
34680
|
const existing = piAgentPatchStates.get(agent);
|
|
34105
|
-
if (!existing ||
|
|
34681
|
+
if (streamFunction && (!existing || existing.property !== property || streamFunction !== existing.wrappedStreamFunction)) {
|
|
34106
34682
|
const patchState = {
|
|
34107
|
-
|
|
34108
|
-
|
|
34683
|
+
originalStreamFunction: streamFunction,
|
|
34684
|
+
property,
|
|
34685
|
+
wrappedStreamFunction: streamFunction
|
|
34109
34686
|
};
|
|
34110
|
-
patchState.
|
|
34687
|
+
patchState.wrappedStreamFunction = makeInstrumentedStreamFunction(
|
|
34111
34688
|
agent,
|
|
34112
|
-
patchState.
|
|
34689
|
+
patchState.originalStreamFunction,
|
|
34690
|
+
property
|
|
34113
34691
|
);
|
|
34114
|
-
agent
|
|
34692
|
+
agent[property] = patchState.wrappedStreamFunction;
|
|
34115
34693
|
piAgentPatchStates.set(agent, patchState);
|
|
34116
34694
|
}
|
|
34117
34695
|
if (piAgentEventSubscriptions.has(agent)) {
|
|
@@ -34136,15 +34714,21 @@ function installPiAgentInstrumentation(agent) {
|
|
|
34136
34714
|
logInstrumentationError4("Pi Coding Agent event subscription", error);
|
|
34137
34715
|
}
|
|
34138
34716
|
}
|
|
34139
|
-
function
|
|
34140
|
-
return async function
|
|
34141
|
-
const invokeOriginal = () => Reflect.apply(
|
|
34717
|
+
function makeInstrumentedStreamFunction(agent, originalStreamFunction, property) {
|
|
34718
|
+
return async function instrumentedPiStreamFunction(model, context, options) {
|
|
34719
|
+
const invokeOriginal = () => Reflect.apply(originalStreamFunction, this, [model, context, options]);
|
|
34142
34720
|
const state = currentPiPromptState();
|
|
34143
34721
|
if (!state || state.agent !== agent || state.finalized) {
|
|
34144
34722
|
return invokeOriginal();
|
|
34145
34723
|
}
|
|
34146
34724
|
wrapPiToolExecutors(context.tools);
|
|
34147
|
-
const llmState = await startPiLlmSpan(
|
|
34725
|
+
const llmState = await startPiLlmSpan(
|
|
34726
|
+
state,
|
|
34727
|
+
model,
|
|
34728
|
+
context,
|
|
34729
|
+
property,
|
|
34730
|
+
options
|
|
34731
|
+
);
|
|
34148
34732
|
try {
|
|
34149
34733
|
const stream = await runWithAutoInstrumentationSuppressed(invokeOriginal);
|
|
34150
34734
|
return patchAssistantMessageStream(stream, state, llmState);
|
|
@@ -34181,12 +34765,12 @@ function wrapPiToolExecutors(tools) {
|
|
|
34181
34765
|
}
|
|
34182
34766
|
}
|
|
34183
34767
|
}
|
|
34184
|
-
async function startPiLlmSpan(state, model, context, options) {
|
|
34768
|
+
async function startPiLlmSpan(state, model, context, property, options) {
|
|
34185
34769
|
const metadata = {
|
|
34186
34770
|
...extractModelMetadata2(model),
|
|
34187
34771
|
...extractStreamOptionsMetadata(options),
|
|
34188
34772
|
...extractToolMetadata(context.tools),
|
|
34189
|
-
"pi_coding_agent.operation":
|
|
34773
|
+
"pi_coding_agent.operation": `agent.${property}`
|
|
34190
34774
|
};
|
|
34191
34775
|
const span = startSpan(
|
|
34192
34776
|
withSpanInstrumentationName(
|
|
@@ -37204,6 +37788,7 @@ __export(exports_exports, {
|
|
|
37204
37788
|
braintrustStreamChunkSchema: () => braintrustStreamChunkSchema,
|
|
37205
37789
|
buildLocalSummary: () => buildLocalSummary,
|
|
37206
37790
|
collectAnthropicSession: () => collectAnthropicSession,
|
|
37791
|
+
completeOpenAIBatchTrace: () => completeOpenAIBatchTrace,
|
|
37207
37792
|
configureInstrumentation: () => configureInstrumentation,
|
|
37208
37793
|
constructLogs3OverflowRequest: () => constructLogs3OverflowRequest,
|
|
37209
37794
|
createFinalValuePassThroughStream: () => createFinalValuePassThroughStream,
|
|
@@ -37242,6 +37827,8 @@ __export(exports_exports, {
|
|
|
37242
37827
|
loginToState: () => loginToState,
|
|
37243
37828
|
logs3OverflowUploadSchema: () => logs3OverflowUploadSchema,
|
|
37244
37829
|
newId: () => newId,
|
|
37830
|
+
openaiBatchesRetrieveTraced: () => openaiBatchesRetrieveTraced,
|
|
37831
|
+
openaiFilesCreateTraced: () => openaiFilesCreateTraced,
|
|
37245
37832
|
parseCachedHeader: () => parseCachedHeader,
|
|
37246
37833
|
parseTemplateFormat: () => parseTemplateFormat,
|
|
37247
37834
|
permalink: () => permalink,
|
|
@@ -37406,6 +37993,260 @@ async function registerSandbox(options) {
|
|
|
37406
37993
|
};
|
|
37407
37994
|
}
|
|
37408
37995
|
|
|
37996
|
+
// src/wrappers/openai-promise-utils.ts
|
|
37997
|
+
function splitSpanInfo(allParams) {
|
|
37998
|
+
const { span_info, ...params } = allParams;
|
|
37999
|
+
return {
|
|
38000
|
+
params,
|
|
38001
|
+
span_info
|
|
38002
|
+
};
|
|
38003
|
+
}
|
|
38004
|
+
function createChannelContext(_channel, params, span_info) {
|
|
38005
|
+
return {
|
|
38006
|
+
arguments: (
|
|
38007
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38008
|
+
[params]
|
|
38009
|
+
),
|
|
38010
|
+
span_info
|
|
38011
|
+
};
|
|
38012
|
+
}
|
|
38013
|
+
async function tracePromiseWithResponse(channel2, traceContext, apiPromise) {
|
|
38014
|
+
let enhancedResponse;
|
|
38015
|
+
const tracePromise = (
|
|
38016
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38017
|
+
channel2.tracePromise
|
|
38018
|
+
);
|
|
38019
|
+
const data = await tracePromise(async () => {
|
|
38020
|
+
enhancedResponse = await apiPromise.withResponse();
|
|
38021
|
+
traceContext.response = enhancedResponse.response;
|
|
38022
|
+
return enhancedResponse.data;
|
|
38023
|
+
}, traceContext);
|
|
38024
|
+
if (!enhancedResponse) {
|
|
38025
|
+
throw new Error("Expected withResponse() to provide response");
|
|
38026
|
+
}
|
|
38027
|
+
return {
|
|
38028
|
+
data,
|
|
38029
|
+
response: enhancedResponse.response,
|
|
38030
|
+
request_id: enhancedResponse.request_id
|
|
38031
|
+
};
|
|
38032
|
+
}
|
|
38033
|
+
async function tracePromiseAsResponse(channel2, traceContext, apiPromise) {
|
|
38034
|
+
const tracePromise = (
|
|
38035
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38036
|
+
channel2.tracePromise
|
|
38037
|
+
);
|
|
38038
|
+
let response;
|
|
38039
|
+
await tracePromise(async () => {
|
|
38040
|
+
response = await apiPromise.asResponse();
|
|
38041
|
+
traceContext.response = response;
|
|
38042
|
+
return void 0;
|
|
38043
|
+
}, traceContext);
|
|
38044
|
+
if (!response) {
|
|
38045
|
+
throw new Error("Expected asResponse() to provide response");
|
|
38046
|
+
}
|
|
38047
|
+
return response;
|
|
38048
|
+
}
|
|
38049
|
+
function createLazyAPIPromise(ensureExecuted, ensureResponse, getAPIPromise) {
|
|
38050
|
+
let firstConsumption;
|
|
38051
|
+
let enhancedResponsePromise;
|
|
38052
|
+
let dataPromise;
|
|
38053
|
+
let responsePromise;
|
|
38054
|
+
const withResponse = () => {
|
|
38055
|
+
firstConsumption ??= "data";
|
|
38056
|
+
enhancedResponsePromise ??= firstConsumption === "data" ? ensureExecuted() : getAPIPromise().withResponse();
|
|
38057
|
+
return enhancedResponsePromise;
|
|
38058
|
+
};
|
|
38059
|
+
const asResponse = () => {
|
|
38060
|
+
firstConsumption ??= "response";
|
|
38061
|
+
responsePromise ??= firstConsumption === "response" ? ensureResponse() : getAPIPromise().asResponse();
|
|
38062
|
+
return responsePromise;
|
|
38063
|
+
};
|
|
38064
|
+
return new Proxy({}, {
|
|
38065
|
+
get(target, prop, receiver) {
|
|
38066
|
+
if (prop === "withResponse") {
|
|
38067
|
+
return withResponse;
|
|
38068
|
+
}
|
|
38069
|
+
if (prop === "asResponse") {
|
|
38070
|
+
return asResponse;
|
|
38071
|
+
}
|
|
38072
|
+
if (prop === "then" || prop === "catch" || prop === "finally" || prop in Promise.prototype) {
|
|
38073
|
+
dataPromise ??= withResponse().then((result) => result.data);
|
|
38074
|
+
const value = Reflect.get(dataPromise, prop, receiver);
|
|
38075
|
+
return typeof value === "function" ? value.bind(dataPromise) : value;
|
|
38076
|
+
}
|
|
38077
|
+
return Reflect.get(target, prop, receiver);
|
|
38078
|
+
}
|
|
38079
|
+
});
|
|
38080
|
+
}
|
|
38081
|
+
|
|
38082
|
+
// src/openai-batch.ts
|
|
38083
|
+
function read2(value, key) {
|
|
38084
|
+
if (value === null || typeof value !== "object" && typeof value !== "function") {
|
|
38085
|
+
return void 0;
|
|
38086
|
+
}
|
|
38087
|
+
try {
|
|
38088
|
+
return Reflect.get(value, key);
|
|
38089
|
+
} catch {
|
|
38090
|
+
return void 0;
|
|
38091
|
+
}
|
|
38092
|
+
}
|
|
38093
|
+
function isAsyncIterable5(value) {
|
|
38094
|
+
return typeof read2(value, Symbol.asyncIterator) === "function";
|
|
38095
|
+
}
|
|
38096
|
+
function teeAsyncIterable(source) {
|
|
38097
|
+
const iterator = source[Symbol.asyncIterator]();
|
|
38098
|
+
const stream = new ReadableStream({
|
|
38099
|
+
async pull(controller) {
|
|
38100
|
+
try {
|
|
38101
|
+
const result = await iterator.next();
|
|
38102
|
+
if (result.done) {
|
|
38103
|
+
controller.close();
|
|
38104
|
+
return;
|
|
38105
|
+
}
|
|
38106
|
+
if (!(result.value instanceof Uint8Array)) {
|
|
38107
|
+
throw new TypeError(
|
|
38108
|
+
"OpenAI upload streams must yield Uint8Array chunks"
|
|
38109
|
+
);
|
|
38110
|
+
}
|
|
38111
|
+
controller.enqueue(result.value);
|
|
38112
|
+
} catch (error) {
|
|
38113
|
+
controller.error(error);
|
|
38114
|
+
}
|
|
38115
|
+
},
|
|
38116
|
+
async cancel(reason) {
|
|
38117
|
+
await iterator.return?.(reason);
|
|
38118
|
+
}
|
|
38119
|
+
});
|
|
38120
|
+
const [uploadStream, trace] = stream.tee();
|
|
38121
|
+
const upload = {
|
|
38122
|
+
async *[Symbol.asyncIterator]() {
|
|
38123
|
+
const reader = uploadStream.getReader();
|
|
38124
|
+
try {
|
|
38125
|
+
while (true) {
|
|
38126
|
+
const result = await reader.read();
|
|
38127
|
+
if (result.done) {
|
|
38128
|
+
return;
|
|
38129
|
+
}
|
|
38130
|
+
yield result.value;
|
|
38131
|
+
}
|
|
38132
|
+
} finally {
|
|
38133
|
+
reader.releaseLock();
|
|
38134
|
+
}
|
|
38135
|
+
}
|
|
38136
|
+
};
|
|
38137
|
+
const path = read2(source, "path");
|
|
38138
|
+
if (typeof path === "string") {
|
|
38139
|
+
Object.defineProperty(upload, "path", { value: path });
|
|
38140
|
+
}
|
|
38141
|
+
return { upload, trace: new Response(trace) };
|
|
38142
|
+
}
|
|
38143
|
+
function teeUpload(upload) {
|
|
38144
|
+
if (upload instanceof Blob) {
|
|
38145
|
+
return { upload, trace: new Response(upload) };
|
|
38146
|
+
}
|
|
38147
|
+
if (upload instanceof Response) {
|
|
38148
|
+
return { upload, trace: upload.clone() };
|
|
38149
|
+
}
|
|
38150
|
+
if (isAsyncIterable5(upload)) {
|
|
38151
|
+
return teeAsyncIterable(upload);
|
|
38152
|
+
}
|
|
38153
|
+
return void 0;
|
|
38154
|
+
}
|
|
38155
|
+
function openaiFilesCreateTraced(files) {
|
|
38156
|
+
return (params, options) => {
|
|
38157
|
+
const parent = getSpanParentObject();
|
|
38158
|
+
const purpose = read2(params, "purpose");
|
|
38159
|
+
const file = read2(params, "file");
|
|
38160
|
+
if (purpose !== "batch") {
|
|
38161
|
+
return files.create(params, options);
|
|
38162
|
+
}
|
|
38163
|
+
let branches;
|
|
38164
|
+
try {
|
|
38165
|
+
branches = teeUpload(file);
|
|
38166
|
+
} catch {
|
|
38167
|
+
return files.create(params, options);
|
|
38168
|
+
}
|
|
38169
|
+
if (!branches) {
|
|
38170
|
+
return files.create(params, options);
|
|
38171
|
+
}
|
|
38172
|
+
const tracedParams = {
|
|
38173
|
+
...Object(params),
|
|
38174
|
+
file: branches.upload
|
|
38175
|
+
};
|
|
38176
|
+
const apiPromise = files.create(tracedParams, options);
|
|
38177
|
+
let enhancedResponse;
|
|
38178
|
+
const tracedResponse = openAIChannels.filesCreateTraced.invoke(
|
|
38179
|
+
async () => {
|
|
38180
|
+
enhancedResponse = await apiPromise.withResponse();
|
|
38181
|
+
return enhancedResponse.data;
|
|
38182
|
+
},
|
|
38183
|
+
files,
|
|
38184
|
+
[{ params, inputFileContent: branches.trace, parent }],
|
|
38185
|
+
{}
|
|
38186
|
+
).then((data) => {
|
|
38187
|
+
if (!enhancedResponse) {
|
|
38188
|
+
throw new Error(
|
|
38189
|
+
"Expected OpenAI withResponse() to provide a response"
|
|
38190
|
+
);
|
|
38191
|
+
}
|
|
38192
|
+
return { ...enhancedResponse, data };
|
|
38193
|
+
});
|
|
38194
|
+
return createLazyAPIPromise(
|
|
38195
|
+
() => tracedResponse,
|
|
38196
|
+
() => tracedResponse.then(({ response }) => response),
|
|
38197
|
+
() => apiPromise
|
|
38198
|
+
);
|
|
38199
|
+
};
|
|
38200
|
+
}
|
|
38201
|
+
function openaiBatchesRetrieveTraced(batches) {
|
|
38202
|
+
return (batchId, options) => {
|
|
38203
|
+
const apiPromise = batches.retrieve(batchId, options);
|
|
38204
|
+
let enhancedResponse;
|
|
38205
|
+
const tracedResponse = openAIChannels.batchesRetrieveTraced.invoke(
|
|
38206
|
+
async () => {
|
|
38207
|
+
enhancedResponse = await apiPromise.withResponse();
|
|
38208
|
+
return enhancedResponse.data;
|
|
38209
|
+
},
|
|
38210
|
+
batches,
|
|
38211
|
+
[{ batchId }],
|
|
38212
|
+
{}
|
|
38213
|
+
).then((data) => {
|
|
38214
|
+
if (!enhancedResponse) {
|
|
38215
|
+
throw new Error(
|
|
38216
|
+
"Expected OpenAI withResponse() to provide a response"
|
|
38217
|
+
);
|
|
38218
|
+
}
|
|
38219
|
+
return { ...enhancedResponse, data };
|
|
38220
|
+
});
|
|
38221
|
+
return createLazyAPIPromise(
|
|
38222
|
+
() => tracedResponse,
|
|
38223
|
+
() => tracedResponse.then(({ response }) => response),
|
|
38224
|
+
() => apiPromise
|
|
38225
|
+
);
|
|
38226
|
+
};
|
|
38227
|
+
}
|
|
38228
|
+
async function completeOpenAIBatchTrace(args) {
|
|
38229
|
+
const inputFileContent = Promise.resolve(args.inputFileContent);
|
|
38230
|
+
const outputFileContent = args.outputFileContent === void 0 ? void 0 : Promise.resolve(args.outputFileContent);
|
|
38231
|
+
const errorFileContent = args.errorFileContent === void 0 ? void 0 : Promise.resolve(args.errorFileContent);
|
|
38232
|
+
void inputFileContent.catch(() => void 0);
|
|
38233
|
+
void outputFileContent?.catch(() => void 0);
|
|
38234
|
+
void errorFileContent?.catch(() => void 0);
|
|
38235
|
+
await openAIChannels.batchesCompleteTrace.invoke(
|
|
38236
|
+
async () => void 0,
|
|
38237
|
+
void 0,
|
|
38238
|
+
[
|
|
38239
|
+
{
|
|
38240
|
+
...args,
|
|
38241
|
+
inputFileContent,
|
|
38242
|
+
outputFileContent,
|
|
38243
|
+
errorFileContent
|
|
38244
|
+
}
|
|
38245
|
+
],
|
|
38246
|
+
{}
|
|
38247
|
+
);
|
|
38248
|
+
}
|
|
38249
|
+
|
|
37409
38250
|
// src/functions/invoke.ts
|
|
37410
38251
|
async function invoke(args) {
|
|
37411
38252
|
const {
|
|
@@ -37508,58 +38349,6 @@ function initFunction({
|
|
|
37508
38349
|
return f;
|
|
37509
38350
|
}
|
|
37510
38351
|
|
|
37511
|
-
// src/wrappers/openai-promise-utils.ts
|
|
37512
|
-
function splitSpanInfo(allParams) {
|
|
37513
|
-
const { span_info, ...params } = allParams;
|
|
37514
|
-
return {
|
|
37515
|
-
params,
|
|
37516
|
-
span_info
|
|
37517
|
-
};
|
|
37518
|
-
}
|
|
37519
|
-
function createChannelContext(_channel, params, span_info) {
|
|
37520
|
-
return {
|
|
37521
|
-
arguments: (
|
|
37522
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
37523
|
-
[params]
|
|
37524
|
-
),
|
|
37525
|
-
span_info
|
|
37526
|
-
};
|
|
37527
|
-
}
|
|
37528
|
-
async function tracePromiseWithResponse(channel2, traceContext, apiPromise) {
|
|
37529
|
-
let enhancedResponse;
|
|
37530
|
-
const tracePromise = (
|
|
37531
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
37532
|
-
channel2.tracePromise
|
|
37533
|
-
);
|
|
37534
|
-
const data = await tracePromise(async () => {
|
|
37535
|
-
enhancedResponse = await apiPromise.withResponse();
|
|
37536
|
-
traceContext.response = enhancedResponse.response;
|
|
37537
|
-
return enhancedResponse.data;
|
|
37538
|
-
}, traceContext);
|
|
37539
|
-
if (!enhancedResponse) {
|
|
37540
|
-
throw new Error("Expected withResponse() to provide response");
|
|
37541
|
-
}
|
|
37542
|
-
return { data, response: enhancedResponse.response };
|
|
37543
|
-
}
|
|
37544
|
-
function createLazyAPIPromise(ensureExecuted) {
|
|
37545
|
-
let dataPromise = null;
|
|
37546
|
-
return new Proxy({}, {
|
|
37547
|
-
get(target, prop, receiver) {
|
|
37548
|
-
if (prop === "withResponse") {
|
|
37549
|
-
return () => ensureExecuted();
|
|
37550
|
-
}
|
|
37551
|
-
if (prop === "then" || prop === "catch" || prop === "finally" || prop in Promise.prototype) {
|
|
37552
|
-
if (!dataPromise) {
|
|
37553
|
-
dataPromise = ensureExecuted().then((result) => result.data);
|
|
37554
|
-
}
|
|
37555
|
-
const value = Reflect.get(dataPromise, prop, receiver);
|
|
37556
|
-
return typeof value === "function" ? value.bind(dataPromise) : value;
|
|
37557
|
-
}
|
|
37558
|
-
return Reflect.get(target, prop, receiver);
|
|
37559
|
-
}
|
|
37560
|
-
});
|
|
37561
|
-
}
|
|
37562
|
-
|
|
37563
38352
|
// src/wrappers/oai_responses.ts
|
|
37564
38353
|
function responsesProxy(openai) {
|
|
37565
38354
|
if (!openai.responses) {
|
|
@@ -37596,17 +38385,33 @@ function wrapResponsesAsync(target, channel2) {
|
|
|
37596
38385
|
return (allParams, options) => {
|
|
37597
38386
|
const { span_info, params } = splitSpanInfo(allParams);
|
|
37598
38387
|
let executionPromise = null;
|
|
38388
|
+
let apiPromise = null;
|
|
38389
|
+
const getAPIPromise = () => {
|
|
38390
|
+
apiPromise ??= target(params, options);
|
|
38391
|
+
return apiPromise;
|
|
38392
|
+
};
|
|
37599
38393
|
const ensureExecuted = () => {
|
|
37600
38394
|
if (!executionPromise) {
|
|
37601
38395
|
executionPromise = (async () => {
|
|
37602
38396
|
const traceContext = createChannelContext(channel2, params, span_info);
|
|
37603
|
-
|
|
37604
|
-
|
|
38397
|
+
return tracePromiseWithResponse(
|
|
38398
|
+
channel2,
|
|
38399
|
+
traceContext,
|
|
38400
|
+
getAPIPromise()
|
|
38401
|
+
);
|
|
37605
38402
|
})();
|
|
37606
38403
|
}
|
|
37607
38404
|
return executionPromise;
|
|
37608
38405
|
};
|
|
37609
|
-
return createLazyAPIPromise(
|
|
38406
|
+
return createLazyAPIPromise(
|
|
38407
|
+
ensureExecuted,
|
|
38408
|
+
() => tracePromiseAsResponse(
|
|
38409
|
+
channel2,
|
|
38410
|
+
createChannelContext(channel2, params, span_info),
|
|
38411
|
+
getAPIPromise()
|
|
38412
|
+
),
|
|
38413
|
+
getAPIPromise
|
|
38414
|
+
);
|
|
37610
38415
|
};
|
|
37611
38416
|
}
|
|
37612
38417
|
function wrapResponsesSyncStream(target, channel2) {
|
|
@@ -37752,6 +38557,11 @@ function wrapChatCompletion(completion) {
|
|
|
37752
38557
|
allParams
|
|
37753
38558
|
);
|
|
37754
38559
|
let executionPromise = null;
|
|
38560
|
+
let apiPromise = null;
|
|
38561
|
+
const getAPIPromise = () => {
|
|
38562
|
+
apiPromise ??= completion(params, options);
|
|
38563
|
+
return apiPromise;
|
|
38564
|
+
};
|
|
37755
38565
|
const ensureExecuted = () => {
|
|
37756
38566
|
if (!executionPromise) {
|
|
37757
38567
|
executionPromise = (async () => {
|
|
@@ -37761,32 +38571,44 @@ function wrapChatCompletion(completion) {
|
|
|
37761
38571
|
span_info
|
|
37762
38572
|
);
|
|
37763
38573
|
if (params.stream) {
|
|
37764
|
-
const completionPromise =
|
|
37765
|
-
|
|
37766
|
-
|
|
38574
|
+
const completionPromise = (
|
|
38575
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38576
|
+
getAPIPromise()
|
|
37767
38577
|
);
|
|
37768
|
-
const { data: data2, response: response2 } = await tracePromiseWithResponse(
|
|
38578
|
+
const { data: data2, response: response2, request_id: request_id2 } = await tracePromiseWithResponse(
|
|
37769
38579
|
openAIChannels.chatCompletionsCreate,
|
|
37770
38580
|
traceContext,
|
|
37771
38581
|
completionPromise
|
|
37772
38582
|
);
|
|
37773
|
-
return { data: data2, response: response2 };
|
|
38583
|
+
return { data: data2, response: response2, request_id: request_id2 };
|
|
37774
38584
|
}
|
|
37775
|
-
const completionResponse =
|
|
37776
|
-
|
|
37777
|
-
|
|
38585
|
+
const completionResponse = (
|
|
38586
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38587
|
+
getAPIPromise()
|
|
37778
38588
|
);
|
|
37779
|
-
const { data, response } = await tracePromiseWithResponse(
|
|
38589
|
+
const { data, response, request_id } = await tracePromiseWithResponse(
|
|
37780
38590
|
openAIChannels.chatCompletionsCreate,
|
|
37781
38591
|
traceContext,
|
|
37782
38592
|
completionResponse
|
|
37783
38593
|
);
|
|
37784
|
-
return { data, response };
|
|
38594
|
+
return { data, response, request_id };
|
|
37785
38595
|
})();
|
|
37786
38596
|
}
|
|
37787
38597
|
return executionPromise;
|
|
37788
38598
|
};
|
|
37789
|
-
return createLazyAPIPromise(
|
|
38599
|
+
return createLazyAPIPromise(
|
|
38600
|
+
ensureExecuted,
|
|
38601
|
+
() => tracePromiseAsResponse(
|
|
38602
|
+
openAIChannels.chatCompletionsCreate,
|
|
38603
|
+
createChannelContext(
|
|
38604
|
+
openAIChannels.chatCompletionsCreate,
|
|
38605
|
+
params,
|
|
38606
|
+
span_info
|
|
38607
|
+
),
|
|
38608
|
+
getAPIPromise()
|
|
38609
|
+
),
|
|
38610
|
+
getAPIPromise
|
|
38611
|
+
);
|
|
37790
38612
|
};
|
|
37791
38613
|
}
|
|
37792
38614
|
function createEndpointProxy(target, wrapperFn) {
|
|
@@ -37804,6 +38626,11 @@ function wrapApiCreateWithChannel(create, channel2) {
|
|
|
37804
38626
|
return (allParams, options) => {
|
|
37805
38627
|
const { span_info, params } = splitSpanInfo(allParams);
|
|
37806
38628
|
let executionPromise = null;
|
|
38629
|
+
let apiPromise = null;
|
|
38630
|
+
const getAPIPromise = () => {
|
|
38631
|
+
apiPromise ??= create(params, options);
|
|
38632
|
+
return apiPromise;
|
|
38633
|
+
};
|
|
37807
38634
|
const ensureExecuted = () => {
|
|
37808
38635
|
if (!executionPromise) {
|
|
37809
38636
|
executionPromise = (async () => {
|
|
@@ -37811,13 +38638,21 @@ function wrapApiCreateWithChannel(create, channel2) {
|
|
|
37811
38638
|
return tracePromiseWithResponse(
|
|
37812
38639
|
channel2,
|
|
37813
38640
|
traceContext,
|
|
37814
|
-
|
|
38641
|
+
getAPIPromise()
|
|
37815
38642
|
);
|
|
37816
38643
|
})();
|
|
37817
38644
|
}
|
|
37818
38645
|
return executionPromise;
|
|
37819
38646
|
};
|
|
37820
|
-
return createLazyAPIPromise(
|
|
38647
|
+
return createLazyAPIPromise(
|
|
38648
|
+
ensureExecuted,
|
|
38649
|
+
() => tracePromiseAsResponse(
|
|
38650
|
+
channel2,
|
|
38651
|
+
createChannelContext(channel2, params, span_info),
|
|
38652
|
+
getAPIPromise()
|
|
38653
|
+
),
|
|
38654
|
+
getAPIPromise
|
|
38655
|
+
);
|
|
37821
38656
|
};
|
|
37822
38657
|
}
|
|
37823
38658
|
var wrapEmbeddings = (create) => wrapApiCreateWithChannel(create, openAIChannels.embeddingsCreate);
|
|
@@ -40512,7 +41347,15 @@ var MAX_EVE_PROVIDER_CACHE_ENTRIES = 1e4;
|
|
|
40512
41347
|
function createEveInstrumentationProvider(options = {}) {
|
|
40513
41348
|
const bridge = new EveProviderBridge(options.metadata);
|
|
40514
41349
|
return {
|
|
41350
|
+
// Eve versions before tracePolicy use capture to decide whether provider
|
|
41351
|
+
// events include content. Newer versions prefer tracePolicy when both are
|
|
41352
|
+
// present, so keep the deprecated field for backwards compatibility.
|
|
40515
41353
|
capture: "content",
|
|
41354
|
+
tracePolicy: () => ({
|
|
41355
|
+
emit: true,
|
|
41356
|
+
recordInputs: true,
|
|
41357
|
+
recordOutputs: true
|
|
41358
|
+
}),
|
|
40516
41359
|
events: {
|
|
40517
41360
|
"action.completed": (event, context) => bridge.handleActionTerminal(event, context),
|
|
40518
41361
|
"action.failed": (event, context) => bridge.handleActionTerminal(event, context),
|
|
@@ -44941,7 +45784,7 @@ function isAsync(fn) {
|
|
|
44941
45784
|
function isAsyncGenerator2(fn) {
|
|
44942
45785
|
return fn[Symbol.toStringTag] === "AsyncGenerator";
|
|
44943
45786
|
}
|
|
44944
|
-
function
|
|
45787
|
+
function isAsyncIterable6(obj) {
|
|
44945
45788
|
return typeof obj[Symbol.asyncIterator] === "function";
|
|
44946
45789
|
}
|
|
44947
45790
|
function wrapAsync(asyncFn) {
|
|
@@ -45113,7 +45956,7 @@ var eachOfLimit$2 = (limit) => {
|
|
|
45113
45956
|
if (isAsyncGenerator2(obj)) {
|
|
45114
45957
|
return asyncEachOfLimit(obj, limit, iteratee, callback);
|
|
45115
45958
|
}
|
|
45116
|
-
if (
|
|
45959
|
+
if (isAsyncIterable6(obj)) {
|
|
45117
45960
|
return asyncEachOfLimit(obj[Symbol.asyncIterator](), limit, iteratee, callback);
|
|
45118
45961
|
}
|
|
45119
45962
|
var nextElem = createIterator(obj);
|
|
@@ -46468,7 +47311,7 @@ function callEvaluatorData(data) {
|
|
|
46468
47311
|
baseExperiment
|
|
46469
47312
|
};
|
|
46470
47313
|
}
|
|
46471
|
-
function
|
|
47314
|
+
function isAsyncIterable7(value) {
|
|
46472
47315
|
return typeof value === "object" && value !== null && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
46473
47316
|
}
|
|
46474
47317
|
function isIterable(value) {
|
|
@@ -46503,7 +47346,7 @@ async function _internalResolveEvaluatorData(evaluator, experiment) {
|
|
|
46503
47346
|
}).asDataset();
|
|
46504
47347
|
}
|
|
46505
47348
|
const resolvedDataResult = dataResult instanceof Promise ? await dataResult : dataResult;
|
|
46506
|
-
if (
|
|
47349
|
+
if (isAsyncIterable7(resolvedDataResult)) {
|
|
46507
47350
|
return resolvedDataResult;
|
|
46508
47351
|
}
|
|
46509
47352
|
if (Array.isArray(resolvedDataResult) || isIterable(resolvedDataResult)) {
|
|
@@ -49551,6 +50394,7 @@ export {
|
|
|
49551
50394
|
braintrustStreamChunkSchema,
|
|
49552
50395
|
buildLocalSummary,
|
|
49553
50396
|
collectAnthropicSession,
|
|
50397
|
+
completeOpenAIBatchTrace,
|
|
49554
50398
|
configureInstrumentation,
|
|
49555
50399
|
constructLogs3OverflowRequest,
|
|
49556
50400
|
createFinalValuePassThroughStream,
|
|
@@ -49590,6 +50434,8 @@ export {
|
|
|
49590
50434
|
loginToState,
|
|
49591
50435
|
logs3OverflowUploadSchema,
|
|
49592
50436
|
newId,
|
|
50437
|
+
openaiBatchesRetrieveTraced,
|
|
50438
|
+
openaiFilesCreateTraced,
|
|
49593
50439
|
parseCachedHeader,
|
|
49594
50440
|
parseTemplateFormat,
|
|
49595
50441
|
permalink,
|