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/workerd.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,
|
|
@@ -13424,6 +13433,131 @@ function unsubscribeAll(unsubscribers) {
|
|
|
13424
13433
|
return [];
|
|
13425
13434
|
}
|
|
13426
13435
|
|
|
13436
|
+
// src/instrumentation/core/channel-definitions.ts
|
|
13437
|
+
function channel(spec) {
|
|
13438
|
+
return spec;
|
|
13439
|
+
}
|
|
13440
|
+
function defineChannels(pkg, channels, options) {
|
|
13441
|
+
const { instrumentationName } = options;
|
|
13442
|
+
return Object.fromEntries(
|
|
13443
|
+
Object.entries(channels).map(([key, spec]) => {
|
|
13444
|
+
const fullChannelName = `orchestrion:${pkg}:${spec.channelName}`;
|
|
13445
|
+
if (spec.kind === "async") {
|
|
13446
|
+
const asyncSpec = spec;
|
|
13447
|
+
const tracingChannel2 = () => isomorph_default.newTracingChannel(
|
|
13448
|
+
fullChannelName
|
|
13449
|
+
);
|
|
13450
|
+
const intercept2 = (interceptor) => {
|
|
13451
|
+
const hook = tracingChannel2();
|
|
13452
|
+
return typeof hook.intercept === "function" ? hook.intercept(interceptor) : () => {
|
|
13453
|
+
};
|
|
13454
|
+
};
|
|
13455
|
+
return [
|
|
13456
|
+
key,
|
|
13457
|
+
{
|
|
13458
|
+
...asyncSpec,
|
|
13459
|
+
instrumentationName,
|
|
13460
|
+
intercept: intercept2,
|
|
13461
|
+
invoke: (target, thisArg, args, additional) => {
|
|
13462
|
+
const hook = tracingChannel2();
|
|
13463
|
+
return typeof hook.invoke === "function" ? hook.invoke(target, thisArg, args, additional) : Reflect.apply(target, thisArg, args);
|
|
13464
|
+
},
|
|
13465
|
+
tracingChannel: tracingChannel2,
|
|
13466
|
+
tracePromise: (fn, context) => tracingChannel2().tracePromise(
|
|
13467
|
+
fn,
|
|
13468
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
13469
|
+
context
|
|
13470
|
+
)
|
|
13471
|
+
}
|
|
13472
|
+
];
|
|
13473
|
+
}
|
|
13474
|
+
const syncSpec = spec;
|
|
13475
|
+
const tracingChannel = () => isomorph_default.newTracingChannel(
|
|
13476
|
+
fullChannelName
|
|
13477
|
+
);
|
|
13478
|
+
const intercept = (interceptor) => {
|
|
13479
|
+
const hook = tracingChannel();
|
|
13480
|
+
return typeof hook.intercept === "function" ? hook.intercept(interceptor) : () => {
|
|
13481
|
+
};
|
|
13482
|
+
};
|
|
13483
|
+
return [
|
|
13484
|
+
key,
|
|
13485
|
+
{
|
|
13486
|
+
...syncSpec,
|
|
13487
|
+
instrumentationName,
|
|
13488
|
+
intercept,
|
|
13489
|
+
invoke: (target, thisArg, args, additional) => {
|
|
13490
|
+
const hook = tracingChannel();
|
|
13491
|
+
return typeof hook.invoke === "function" ? hook.invoke(target, thisArg, args, additional) : Reflect.apply(target, thisArg, args);
|
|
13492
|
+
},
|
|
13493
|
+
tracingChannel,
|
|
13494
|
+
traceSync: (fn, context) => tracingChannel().traceSync(
|
|
13495
|
+
fn,
|
|
13496
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
13497
|
+
context
|
|
13498
|
+
)
|
|
13499
|
+
}
|
|
13500
|
+
];
|
|
13501
|
+
})
|
|
13502
|
+
);
|
|
13503
|
+
}
|
|
13504
|
+
|
|
13505
|
+
// src/instrumentation/plugins/openai-channels.ts
|
|
13506
|
+
var openAIChannels = defineChannels(
|
|
13507
|
+
"openai",
|
|
13508
|
+
{
|
|
13509
|
+
filesCreateTraced: channel({
|
|
13510
|
+
channelName: "files.create-traced",
|
|
13511
|
+
kind: "async"
|
|
13512
|
+
}),
|
|
13513
|
+
batchesRetrieveTraced: channel({
|
|
13514
|
+
channelName: "batches.retrieve-traced",
|
|
13515
|
+
kind: "async"
|
|
13516
|
+
}),
|
|
13517
|
+
batchesCompleteTrace: channel({
|
|
13518
|
+
channelName: "batches.complete-trace",
|
|
13519
|
+
kind: "async"
|
|
13520
|
+
}),
|
|
13521
|
+
chatCompletionsCreate: channel({
|
|
13522
|
+
channelName: "chat.completions.create",
|
|
13523
|
+
kind: "async"
|
|
13524
|
+
}),
|
|
13525
|
+
embeddingsCreate: channel({
|
|
13526
|
+
channelName: "embeddings.create",
|
|
13527
|
+
kind: "async"
|
|
13528
|
+
}),
|
|
13529
|
+
betaChatCompletionsParse: channel({
|
|
13530
|
+
channelName: "beta.chat.completions.parse",
|
|
13531
|
+
kind: "async"
|
|
13532
|
+
}),
|
|
13533
|
+
betaChatCompletionsStream: channel({
|
|
13534
|
+
channelName: "beta.chat.completions.stream",
|
|
13535
|
+
kind: "sync-stream"
|
|
13536
|
+
}),
|
|
13537
|
+
moderationsCreate: channel({
|
|
13538
|
+
channelName: "moderations.create",
|
|
13539
|
+
kind: "async"
|
|
13540
|
+
}),
|
|
13541
|
+
responsesCreate: channel({
|
|
13542
|
+
channelName: "responses.create",
|
|
13543
|
+
kind: "async"
|
|
13544
|
+
}),
|
|
13545
|
+
responsesStream: channel({
|
|
13546
|
+
channelName: "responses.stream",
|
|
13547
|
+
kind: "sync-stream"
|
|
13548
|
+
}),
|
|
13549
|
+
responsesParse: channel({
|
|
13550
|
+
channelName: "responses.parse",
|
|
13551
|
+
kind: "async"
|
|
13552
|
+
}),
|
|
13553
|
+
responsesCompact: channel({
|
|
13554
|
+
channelName: "responses.compact",
|
|
13555
|
+
kind: "async"
|
|
13556
|
+
})
|
|
13557
|
+
},
|
|
13558
|
+
{ instrumentationName: INSTRUMENTATION_NAMES.OPENAI }
|
|
13559
|
+
);
|
|
13560
|
+
|
|
13427
13561
|
// src/wrappers/attachment-utils.ts
|
|
13428
13562
|
function getExtensionFromMediaType(mediaType) {
|
|
13429
13563
|
const extensionMap = {
|
|
@@ -13599,118 +13733,91 @@ function processInputAttachments(input) {
|
|
|
13599
13733
|
return processNode(input);
|
|
13600
13734
|
}
|
|
13601
13735
|
|
|
13602
|
-
// src/instrumentation/
|
|
13603
|
-
|
|
13604
|
-
|
|
13605
|
-
|
|
13606
|
-
|
|
13607
|
-
|
|
13608
|
-
|
|
13609
|
-
|
|
13610
|
-
|
|
13611
|
-
|
|
13612
|
-
|
|
13613
|
-
|
|
13614
|
-
|
|
13615
|
-
|
|
13616
|
-
|
|
13617
|
-
|
|
13618
|
-
|
|
13619
|
-
|
|
13620
|
-
|
|
13621
|
-
|
|
13622
|
-
|
|
13623
|
-
|
|
13624
|
-
...asyncSpec,
|
|
13625
|
-
instrumentationName,
|
|
13626
|
-
intercept: intercept2,
|
|
13627
|
-
invoke: (target, thisArg, args, additional) => {
|
|
13628
|
-
const hook = tracingChannel2();
|
|
13629
|
-
return typeof hook.invoke === "function" ? hook.invoke(target, thisArg, args, additional) : Reflect.apply(target, thisArg, args);
|
|
13630
|
-
},
|
|
13631
|
-
tracingChannel: tracingChannel2,
|
|
13632
|
-
tracePromise: (fn, context) => tracingChannel2().tracePromise(
|
|
13633
|
-
fn,
|
|
13634
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
13635
|
-
context
|
|
13636
|
-
)
|
|
13637
|
-
}
|
|
13638
|
-
];
|
|
13736
|
+
// src/instrumentation/plugins/openai-span-data.ts
|
|
13737
|
+
var OPENAI_METADATA_KEYS = [
|
|
13738
|
+
"model",
|
|
13739
|
+
"temperature",
|
|
13740
|
+
"top_p",
|
|
13741
|
+
"max_tokens",
|
|
13742
|
+
"frequency_penalty",
|
|
13743
|
+
"presence_penalty",
|
|
13744
|
+
"stop",
|
|
13745
|
+
"response_format",
|
|
13746
|
+
"tools",
|
|
13747
|
+
"tool_choice",
|
|
13748
|
+
"parallel_tool_calls",
|
|
13749
|
+
"max_tool_calls"
|
|
13750
|
+
];
|
|
13751
|
+
function batchMetadata(params) {
|
|
13752
|
+
const metadata = { provider: "openai" };
|
|
13753
|
+
for (const key of OPENAI_METADATA_KEYS) {
|
|
13754
|
+
try {
|
|
13755
|
+
const value = Reflect.get(params, key);
|
|
13756
|
+
if (value !== void 0) {
|
|
13757
|
+
metadata[key] = value;
|
|
13639
13758
|
}
|
|
13640
|
-
|
|
13641
|
-
|
|
13642
|
-
|
|
13643
|
-
|
|
13644
|
-
|
|
13645
|
-
|
|
13646
|
-
|
|
13647
|
-
|
|
13648
|
-
|
|
13649
|
-
|
|
13650
|
-
|
|
13651
|
-
|
|
13652
|
-
|
|
13653
|
-
|
|
13654
|
-
|
|
13655
|
-
|
|
13656
|
-
|
|
13657
|
-
|
|
13658
|
-
|
|
13659
|
-
|
|
13660
|
-
|
|
13661
|
-
|
|
13662
|
-
|
|
13663
|
-
|
|
13664
|
-
|
|
13665
|
-
|
|
13666
|
-
|
|
13667
|
-
|
|
13668
|
-
|
|
13759
|
+
} catch {
|
|
13760
|
+
}
|
|
13761
|
+
}
|
|
13762
|
+
return metadata;
|
|
13763
|
+
}
|
|
13764
|
+
function extractOpenAIBatchInput(endpoint, params) {
|
|
13765
|
+
const input = endpoint === "/v1/chat/completions" ? params.messages : params.input;
|
|
13766
|
+
return {
|
|
13767
|
+
input: processInputAttachments(input),
|
|
13768
|
+
metadata: batchMetadata(params)
|
|
13769
|
+
};
|
|
13770
|
+
}
|
|
13771
|
+
function extractOpenAIChatInput(params) {
|
|
13772
|
+
const { messages, ...metadata } = params;
|
|
13773
|
+
return {
|
|
13774
|
+
input: processInputAttachments(messages),
|
|
13775
|
+
metadata: { ...metadata, provider: "openai" }
|
|
13776
|
+
};
|
|
13777
|
+
}
|
|
13778
|
+
function extractOpenAIResponsesInput(params) {
|
|
13779
|
+
const { input, ...metadata } = params;
|
|
13780
|
+
return {
|
|
13781
|
+
input: processInputAttachments(input),
|
|
13782
|
+
metadata: { ...metadata, provider: "openai" }
|
|
13783
|
+
};
|
|
13784
|
+
}
|
|
13785
|
+
function extractOpenAIResponsesMetadata(result) {
|
|
13786
|
+
if (!result) {
|
|
13787
|
+
return void 0;
|
|
13788
|
+
}
|
|
13789
|
+
const { output: _output, usage: _usage, ...metadata } = result;
|
|
13790
|
+
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
13791
|
+
}
|
|
13792
|
+
function processImagesInOutput(output) {
|
|
13793
|
+
if (Array.isArray(output)) {
|
|
13794
|
+
return output.map(processImagesInOutput);
|
|
13795
|
+
}
|
|
13796
|
+
if (isObject(output) && output.type === "image_generation_call" && typeof output.result === "string" && output.result) {
|
|
13797
|
+
const fileExtension = output.output_format || "png";
|
|
13798
|
+
const contentType = `image/${fileExtension}`;
|
|
13799
|
+
const baseFilename = typeof output.revised_prompt === "string" ? output.revised_prompt.slice(0, 50).replace(/[^a-zA-Z0-9]/g, "_") : "generated_image";
|
|
13800
|
+
let binaryString;
|
|
13801
|
+
try {
|
|
13802
|
+
binaryString = atob(output.result);
|
|
13803
|
+
} catch {
|
|
13804
|
+
return output;
|
|
13805
|
+
}
|
|
13806
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
13807
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
13808
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
13809
|
+
}
|
|
13810
|
+
return {
|
|
13811
|
+
...output,
|
|
13812
|
+
result: new Attachment({
|
|
13813
|
+
data: new Blob([bytes], { type: contentType }),
|
|
13814
|
+
filename: `${baseFilename}.${fileExtension}`,
|
|
13815
|
+
contentType
|
|
13816
|
+
})
|
|
13817
|
+
};
|
|
13818
|
+
}
|
|
13819
|
+
return output;
|
|
13669
13820
|
}
|
|
13670
|
-
|
|
13671
|
-
// src/instrumentation/plugins/openai-channels.ts
|
|
13672
|
-
var openAIChannels = defineChannels(
|
|
13673
|
-
"openai",
|
|
13674
|
-
{
|
|
13675
|
-
chatCompletionsCreate: channel({
|
|
13676
|
-
channelName: "chat.completions.create",
|
|
13677
|
-
kind: "async"
|
|
13678
|
-
}),
|
|
13679
|
-
embeddingsCreate: channel({
|
|
13680
|
-
channelName: "embeddings.create",
|
|
13681
|
-
kind: "async"
|
|
13682
|
-
}),
|
|
13683
|
-
betaChatCompletionsParse: channel({
|
|
13684
|
-
channelName: "beta.chat.completions.parse",
|
|
13685
|
-
kind: "async"
|
|
13686
|
-
}),
|
|
13687
|
-
betaChatCompletionsStream: channel({
|
|
13688
|
-
channelName: "beta.chat.completions.stream",
|
|
13689
|
-
kind: "sync-stream"
|
|
13690
|
-
}),
|
|
13691
|
-
moderationsCreate: channel({
|
|
13692
|
-
channelName: "moderations.create",
|
|
13693
|
-
kind: "async"
|
|
13694
|
-
}),
|
|
13695
|
-
responsesCreate: channel({
|
|
13696
|
-
channelName: "responses.create",
|
|
13697
|
-
kind: "async"
|
|
13698
|
-
}),
|
|
13699
|
-
responsesStream: channel({
|
|
13700
|
-
channelName: "responses.stream",
|
|
13701
|
-
kind: "sync-stream"
|
|
13702
|
-
}),
|
|
13703
|
-
responsesParse: channel({
|
|
13704
|
-
channelName: "responses.parse",
|
|
13705
|
-
kind: "async"
|
|
13706
|
-
}),
|
|
13707
|
-
responsesCompact: channel({
|
|
13708
|
-
channelName: "responses.compact",
|
|
13709
|
-
kind: "async"
|
|
13710
|
-
})
|
|
13711
|
-
},
|
|
13712
|
-
{ instrumentationName: INSTRUMENTATION_NAMES.OPENAI }
|
|
13713
|
-
);
|
|
13714
13821
|
|
|
13715
13822
|
// src/openai-utils.ts
|
|
13716
13823
|
var BRAINTRUST_CACHED_STREAM_METRIC = "__braintrust_cached_metric";
|
|
@@ -13767,23 +13874,573 @@ function getCachedMetricFromHeaders(headers) {
|
|
|
13767
13874
|
return parseCachedHeader(headers.get(LEGACY_CACHED_HEADER));
|
|
13768
13875
|
}
|
|
13769
13876
|
|
|
13877
|
+
// src/instrumentation/plugins/openai-batch-instrumentation.ts
|
|
13878
|
+
var SUPPORTED_ENDPOINTS = /* @__PURE__ */ new Set(["/v1/chat/completions", "/v1/responses"]);
|
|
13879
|
+
var TERMINAL_STATUSES = /* @__PURE__ */ new Set([
|
|
13880
|
+
"completed",
|
|
13881
|
+
"failed",
|
|
13882
|
+
"expired",
|
|
13883
|
+
"cancelled"
|
|
13884
|
+
]);
|
|
13885
|
+
var pendingBatchTraces = /* @__PURE__ */ new Map();
|
|
13886
|
+
function read(value, key) {
|
|
13887
|
+
if (!isObject(value)) {
|
|
13888
|
+
return void 0;
|
|
13889
|
+
}
|
|
13890
|
+
try {
|
|
13891
|
+
return Reflect.get(value, key);
|
|
13892
|
+
} catch {
|
|
13893
|
+
return void 0;
|
|
13894
|
+
}
|
|
13895
|
+
}
|
|
13896
|
+
function isBatchRecordIterable(value) {
|
|
13897
|
+
if (value === null || typeof value !== "object" && typeof value !== "function") {
|
|
13898
|
+
return false;
|
|
13899
|
+
}
|
|
13900
|
+
return typeof read(value, Symbol.iterator) === "function" || typeof read(value, Symbol.asyncIterator) === "function";
|
|
13901
|
+
}
|
|
13902
|
+
function validCustomId(value) {
|
|
13903
|
+
return typeof value === "string" && value.length > 0 && value.length <= 64;
|
|
13904
|
+
}
|
|
13905
|
+
function logBatchInstrumentationError(context, error) {
|
|
13906
|
+
debugLogger.debug(`OpenAI Batch instrumentation ${context}:`, error);
|
|
13907
|
+
}
|
|
13908
|
+
async function exportParent(parent) {
|
|
13909
|
+
if ("toStr" in parent && typeof parent.toStr === "function") {
|
|
13910
|
+
return parent.toStr();
|
|
13911
|
+
}
|
|
13912
|
+
if ("export" in parent && typeof parent.export === "function") {
|
|
13913
|
+
return await parent.export();
|
|
13914
|
+
}
|
|
13915
|
+
return void 0;
|
|
13916
|
+
}
|
|
13917
|
+
async function deterministicDigest(namespace, ...parts) {
|
|
13918
|
+
const encoded = new TextEncoder().encode(
|
|
13919
|
+
[namespace, ...parts].map((part) => `${part.length}:${part}`).join("\0")
|
|
13920
|
+
);
|
|
13921
|
+
return new Uint8Array(
|
|
13922
|
+
await globalThis.crypto.subtle.digest("SHA-256", encoded)
|
|
13923
|
+
);
|
|
13924
|
+
}
|
|
13925
|
+
function digestHex(bytes, length) {
|
|
13926
|
+
return Array.from(bytes.slice(0, length)).map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
13927
|
+
}
|
|
13928
|
+
function digestUuid(bytes) {
|
|
13929
|
+
const hex = digestHex(bytes, 16);
|
|
13930
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
13931
|
+
}
|
|
13932
|
+
async function batchSpanIds(inputFileId) {
|
|
13933
|
+
const [row, span, root] = await Promise.all([
|
|
13934
|
+
deterministicDigest("openai:batch:row", inputFileId),
|
|
13935
|
+
deterministicDigest("openai:batch:span", inputFileId),
|
|
13936
|
+
deterministicDigest("openai:batch:root", inputFileId)
|
|
13937
|
+
]);
|
|
13938
|
+
return {
|
|
13939
|
+
rowId: digestUuid(row),
|
|
13940
|
+
spanId: digestHex(span, 8),
|
|
13941
|
+
rootSpanId: digestHex(root, 16)
|
|
13942
|
+
};
|
|
13943
|
+
}
|
|
13944
|
+
async function childSpanIds(inputFileId, customId) {
|
|
13945
|
+
const [row, span] = await Promise.all([
|
|
13946
|
+
deterministicDigest("openai:batch:child:row", inputFileId, customId),
|
|
13947
|
+
deterministicDigest("openai:batch:child:span", inputFileId, customId)
|
|
13948
|
+
]);
|
|
13949
|
+
return { rowId: digestUuid(row), spanId: digestHex(span, 8) };
|
|
13950
|
+
}
|
|
13951
|
+
async function startBatchSpan(context) {
|
|
13952
|
+
const ids = await batchSpanIds(context.inputFileId);
|
|
13953
|
+
const parent = SpanComponentsV4.fromStr(context.parent);
|
|
13954
|
+
const hasParentSpan = Boolean(
|
|
13955
|
+
parent.data.row_id && parent.data.span_id && parent.data.root_span_id
|
|
13956
|
+
);
|
|
13957
|
+
return withCurrent(
|
|
13958
|
+
NOOP_SPAN,
|
|
13959
|
+
() => _internalStartSpanWithInitialMergeAndParentSpanIds(
|
|
13960
|
+
withSpanInstrumentationName(
|
|
13961
|
+
{
|
|
13962
|
+
name: "openai.batch",
|
|
13963
|
+
type: "task" /* TASK */,
|
|
13964
|
+
parent: context.parent,
|
|
13965
|
+
...!hasParentSpan ? {
|
|
13966
|
+
parentSpanIds: {
|
|
13967
|
+
parentSpanIds: [],
|
|
13968
|
+
rootSpanId: ids.rootSpanId
|
|
13969
|
+
}
|
|
13970
|
+
} : {},
|
|
13971
|
+
spanId: ids.spanId,
|
|
13972
|
+
startTime: context.taskStartTime,
|
|
13973
|
+
event: {
|
|
13974
|
+
id: ids.rowId,
|
|
13975
|
+
metadata: {
|
|
13976
|
+
endpoint: context.endpoint,
|
|
13977
|
+
input_file_id: context.inputFileId,
|
|
13978
|
+
provider: "openai"
|
|
13979
|
+
}
|
|
13980
|
+
}
|
|
13981
|
+
},
|
|
13982
|
+
INSTRUMENTATION_NAMES.OPENAI
|
|
13983
|
+
)
|
|
13984
|
+
)
|
|
13985
|
+
);
|
|
13986
|
+
}
|
|
13987
|
+
async function startBatchChild(context, taskParent, input) {
|
|
13988
|
+
const ids = await childSpanIds(context.inputFileId, input.customId);
|
|
13989
|
+
return withCurrent(
|
|
13990
|
+
NOOP_SPAN,
|
|
13991
|
+
() => _internalStartSpanWithInitialMerge(
|
|
13992
|
+
withSpanInstrumentationName(
|
|
13993
|
+
{
|
|
13994
|
+
name: context.endpoint === "/v1/chat/completions" ? "Chat Completion" : "openai.responses.create",
|
|
13995
|
+
type: "llm" /* LLM */,
|
|
13996
|
+
parent: taskParent,
|
|
13997
|
+
spanId: ids.spanId,
|
|
13998
|
+
startTime: context.childStartTime,
|
|
13999
|
+
event: {
|
|
14000
|
+
id: ids.rowId,
|
|
14001
|
+
...input.spanData?.input !== void 0 ? { input: input.spanData.input } : {},
|
|
14002
|
+
metadata: {
|
|
14003
|
+
...input.spanData?.metadata,
|
|
14004
|
+
custom_id: input.customId,
|
|
14005
|
+
provider: "openai"
|
|
14006
|
+
}
|
|
14007
|
+
}
|
|
14008
|
+
},
|
|
14009
|
+
INSTRUMENTATION_NAMES.OPENAI
|
|
14010
|
+
)
|
|
14011
|
+
)
|
|
14012
|
+
);
|
|
14013
|
+
}
|
|
14014
|
+
async function* jsonlRecords(file, onIssue = () => {
|
|
14015
|
+
}) {
|
|
14016
|
+
const resolvedFile = await file;
|
|
14017
|
+
if (typeof resolvedFile === "string") {
|
|
14018
|
+
for (const line of resolvedFile.split("\n")) {
|
|
14019
|
+
if (!line.trim()) {
|
|
14020
|
+
continue;
|
|
14021
|
+
}
|
|
14022
|
+
try {
|
|
14023
|
+
yield JSON.parse(line.replace(/\r$/, ""));
|
|
14024
|
+
} catch (error) {
|
|
14025
|
+
logBatchInstrumentationError("skipped malformed JSONL", error);
|
|
14026
|
+
onIssue(new Error("OpenAI Batch file contains malformed JSONL"));
|
|
14027
|
+
}
|
|
14028
|
+
}
|
|
14029
|
+
return;
|
|
14030
|
+
}
|
|
14031
|
+
const body = read(resolvedFile, "body");
|
|
14032
|
+
const getReader = read(body, "getReader");
|
|
14033
|
+
if (isObject(body) && typeof getReader === "function") {
|
|
14034
|
+
let reader;
|
|
14035
|
+
try {
|
|
14036
|
+
reader = Reflect.apply(getReader, body, []);
|
|
14037
|
+
const decoder2 = new TextDecoder();
|
|
14038
|
+
let pending = "";
|
|
14039
|
+
while (true) {
|
|
14040
|
+
const readChunk = read(reader, "read");
|
|
14041
|
+
if (typeof readChunk !== "function") {
|
|
14042
|
+
throw new Error("Response body stream has no read method");
|
|
14043
|
+
}
|
|
14044
|
+
const chunk = await Reflect.apply(readChunk, reader, []);
|
|
14045
|
+
if (!isObject(chunk)) {
|
|
14046
|
+
throw new Error("Response body stream returned an invalid chunk");
|
|
14047
|
+
}
|
|
14048
|
+
if (chunk.done === true) {
|
|
14049
|
+
pending += decoder2.decode();
|
|
14050
|
+
break;
|
|
14051
|
+
}
|
|
14052
|
+
if (!(chunk.value instanceof Uint8Array)) {
|
|
14053
|
+
throw new Error("Response body stream returned a non-byte chunk");
|
|
14054
|
+
}
|
|
14055
|
+
pending += decoder2.decode(chunk.value, { stream: true });
|
|
14056
|
+
let newline = pending.indexOf("\n");
|
|
14057
|
+
while (newline !== -1) {
|
|
14058
|
+
const line = pending.slice(0, newline).replace(/\r$/, "");
|
|
14059
|
+
pending = pending.slice(newline + 1);
|
|
14060
|
+
if (line.trim()) {
|
|
14061
|
+
try {
|
|
14062
|
+
yield JSON.parse(line);
|
|
14063
|
+
} catch (error) {
|
|
14064
|
+
logBatchInstrumentationError("skipped malformed JSONL", error);
|
|
14065
|
+
onIssue(new Error("OpenAI Batch file contains malformed JSONL"));
|
|
14066
|
+
}
|
|
14067
|
+
}
|
|
14068
|
+
newline = pending.indexOf("\n");
|
|
14069
|
+
}
|
|
14070
|
+
}
|
|
14071
|
+
if (pending.trim()) {
|
|
14072
|
+
try {
|
|
14073
|
+
yield JSON.parse(pending.replace(/\r$/, ""));
|
|
14074
|
+
} catch (error) {
|
|
14075
|
+
logBatchInstrumentationError("skipped malformed JSONL", error);
|
|
14076
|
+
onIssue(new Error("OpenAI Batch file contains malformed JSONL"));
|
|
14077
|
+
}
|
|
14078
|
+
}
|
|
14079
|
+
} catch (error) {
|
|
14080
|
+
logBatchInstrumentationError("could not read JSONL response body", error);
|
|
14081
|
+
onIssue(new Error("OpenAI Batch response body could not be read"));
|
|
14082
|
+
} finally {
|
|
14083
|
+
const releaseLock = read(reader, "releaseLock");
|
|
14084
|
+
if (typeof releaseLock === "function") {
|
|
14085
|
+
try {
|
|
14086
|
+
Reflect.apply(releaseLock, reader, []);
|
|
14087
|
+
} catch (error) {
|
|
14088
|
+
logBatchInstrumentationError(
|
|
14089
|
+
"could not release stream reader",
|
|
14090
|
+
error
|
|
14091
|
+
);
|
|
14092
|
+
}
|
|
14093
|
+
}
|
|
14094
|
+
}
|
|
14095
|
+
return;
|
|
14096
|
+
}
|
|
14097
|
+
if (isBatchRecordIterable(resolvedFile)) {
|
|
14098
|
+
for await (const record of resolvedFile) {
|
|
14099
|
+
yield record;
|
|
14100
|
+
}
|
|
14101
|
+
return;
|
|
14102
|
+
}
|
|
14103
|
+
logBatchInstrumentationError("skipped invalid JSONL source", resolvedFile);
|
|
14104
|
+
onIssue(new Error("OpenAI Batch file source is invalid"));
|
|
14105
|
+
}
|
|
14106
|
+
async function readBatchInputs(file) {
|
|
14107
|
+
const inputs = /* @__PURE__ */ new Map();
|
|
14108
|
+
const issues = [];
|
|
14109
|
+
let endpoint;
|
|
14110
|
+
try {
|
|
14111
|
+
for await (const value of jsonlRecords(
|
|
14112
|
+
file,
|
|
14113
|
+
(issue) => issues.push(issue)
|
|
14114
|
+
)) {
|
|
14115
|
+
const customId = read(value, "custom_id");
|
|
14116
|
+
const url = read(value, "url");
|
|
14117
|
+
const body = read(value, "body");
|
|
14118
|
+
if (!validCustomId(customId) || inputs.has(customId) || read(value, "method") !== "POST" || typeof url !== "string" || !SUPPORTED_ENDPOINTS.has(url) || endpoint !== void 0 && endpoint !== url || !isObject(body)) {
|
|
14119
|
+
issues.push(new Error("OpenAI Batch input contains an invalid record"));
|
|
14120
|
+
continue;
|
|
14121
|
+
}
|
|
14122
|
+
endpoint = url;
|
|
14123
|
+
let spanData;
|
|
14124
|
+
try {
|
|
14125
|
+
spanData = extractOpenAIBatchInput(url, body);
|
|
14126
|
+
} catch (error) {
|
|
14127
|
+
logBatchInstrumentationError("could not extract batch input", error);
|
|
14128
|
+
}
|
|
14129
|
+
inputs.set(customId, { customId, spanData });
|
|
14130
|
+
}
|
|
14131
|
+
} catch (error) {
|
|
14132
|
+
logBatchInstrumentationError("could not process input file", error);
|
|
14133
|
+
issues.push(new Error("OpenAI Batch input file could not be processed"));
|
|
14134
|
+
}
|
|
14135
|
+
if (!endpoint || inputs.size === 0) {
|
|
14136
|
+
issues.push(new Error("OpenAI Batch input contains no supported records"));
|
|
14137
|
+
}
|
|
14138
|
+
return { endpoint, inputs, issues };
|
|
14139
|
+
}
|
|
14140
|
+
async function writePendingSpans(trace, endTime) {
|
|
14141
|
+
const task = await startBatchSpan(trace.context);
|
|
14142
|
+
const taskParent = await task.export();
|
|
14143
|
+
for (const input of trace.inputs.values()) {
|
|
14144
|
+
try {
|
|
14145
|
+
const child = await startBatchChild(trace.context, taskParent, input);
|
|
14146
|
+
if (endTime !== void 0) {
|
|
14147
|
+
child.end({ endTime });
|
|
14148
|
+
}
|
|
14149
|
+
} catch (error) {
|
|
14150
|
+
logBatchInstrumentationError("could not write batch request span", error);
|
|
14151
|
+
}
|
|
14152
|
+
}
|
|
14153
|
+
if (endTime !== void 0) {
|
|
14154
|
+
if (trace.status && trace.status !== "completed") {
|
|
14155
|
+
task.log({ error: new Error(`OpenAI Batch ${trace.status}`) });
|
|
14156
|
+
}
|
|
14157
|
+
task.end({ endTime });
|
|
14158
|
+
}
|
|
14159
|
+
}
|
|
14160
|
+
var interceptOpenAIFilesCreateTraced = async (target, thisArg, args) => {
|
|
14161
|
+
const startTime = getCurrentUnixTimestamp();
|
|
14162
|
+
const inputPromise = readBatchInputs(args[0].inputFileContent);
|
|
14163
|
+
const parentPromise = exportParent(args[0].parent);
|
|
14164
|
+
const file = await Reflect.apply(target, thisArg, args);
|
|
14165
|
+
try {
|
|
14166
|
+
const inputFileId = read(file, "id");
|
|
14167
|
+
const [inputData, exportedParent2] = await Promise.all([
|
|
14168
|
+
inputPromise,
|
|
14169
|
+
parentPromise
|
|
14170
|
+
]);
|
|
14171
|
+
if (typeof inputFileId !== "string" || !exportedParent2 || !inputData.endpoint || inputData.issues.length > 0) {
|
|
14172
|
+
if (inputData.issues[0]) {
|
|
14173
|
+
logBatchInstrumentationError(
|
|
14174
|
+
"skipped invalid input file",
|
|
14175
|
+
inputData.issues[0]
|
|
14176
|
+
);
|
|
14177
|
+
}
|
|
14178
|
+
return file;
|
|
14179
|
+
}
|
|
14180
|
+
const trace = {
|
|
14181
|
+
context: {
|
|
14182
|
+
inputFileId,
|
|
14183
|
+
endpoint: inputData.endpoint,
|
|
14184
|
+
parent: exportedParent2,
|
|
14185
|
+
taskStartTime: startTime,
|
|
14186
|
+
childStartTime: startTime
|
|
14187
|
+
},
|
|
14188
|
+
inputs: inputData.inputs
|
|
14189
|
+
};
|
|
14190
|
+
pendingBatchTraces.set(inputFileId, trace);
|
|
14191
|
+
await writePendingSpans(trace);
|
|
14192
|
+
} catch (error) {
|
|
14193
|
+
logBatchInstrumentationError("could not start batch spans", error);
|
|
14194
|
+
}
|
|
14195
|
+
return file;
|
|
14196
|
+
};
|
|
14197
|
+
function validTimestamp(value) {
|
|
14198
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0;
|
|
14199
|
+
}
|
|
14200
|
+
function terminalEndTime(batch, startTime) {
|
|
14201
|
+
let timestamp;
|
|
14202
|
+
switch (batch.status) {
|
|
14203
|
+
case "completed":
|
|
14204
|
+
timestamp = batch.completed_at;
|
|
14205
|
+
break;
|
|
14206
|
+
case "failed":
|
|
14207
|
+
timestamp = batch.failed_at;
|
|
14208
|
+
break;
|
|
14209
|
+
case "expired":
|
|
14210
|
+
timestamp = batch.expired_at;
|
|
14211
|
+
break;
|
|
14212
|
+
default:
|
|
14213
|
+
timestamp = batch.cancelled_at;
|
|
14214
|
+
}
|
|
14215
|
+
return validTimestamp(timestamp) ? Math.max(timestamp, startTime) : Math.max(getCurrentUnixTimestamp(), startTime);
|
|
14216
|
+
}
|
|
14217
|
+
async function updateBatchTimestamps(batch) {
|
|
14218
|
+
const trace = pendingBatchTraces.get(batch.input_file_id);
|
|
14219
|
+
if (!trace || trace.context.endpoint !== batch.endpoint) {
|
|
14220
|
+
return;
|
|
14221
|
+
}
|
|
14222
|
+
if (validTimestamp(batch.created_at)) {
|
|
14223
|
+
trace.context.taskStartTime = batch.created_at;
|
|
14224
|
+
}
|
|
14225
|
+
trace.context.childStartTime = validTimestamp(batch.in_progress_at) ? Math.max(batch.in_progress_at, trace.context.taskStartTime) : trace.context.taskStartTime;
|
|
14226
|
+
trace.status = batch.status;
|
|
14227
|
+
if (TERMINAL_STATUSES.has(batch.status)) {
|
|
14228
|
+
trace.endTime = terminalEndTime(batch, trace.context.childStartTime);
|
|
14229
|
+
}
|
|
14230
|
+
await writePendingSpans(trace, trace.endTime);
|
|
14231
|
+
}
|
|
14232
|
+
var interceptOpenAIBatchesRetrieveTraced = (target, thisArg, args) => Promise.resolve(Reflect.apply(target, thisArg, args)).then(async (batch) => {
|
|
14233
|
+
try {
|
|
14234
|
+
await updateBatchTimestamps(batch);
|
|
14235
|
+
} catch (error) {
|
|
14236
|
+
logBatchInstrumentationError("could not update batch timestamps", error);
|
|
14237
|
+
}
|
|
14238
|
+
return batch;
|
|
14239
|
+
});
|
|
14240
|
+
function errorFromResult(result) {
|
|
14241
|
+
const error = read(result.value, "error");
|
|
14242
|
+
if (isObject(error)) {
|
|
14243
|
+
const message = read(error, "message");
|
|
14244
|
+
return new Error(
|
|
14245
|
+
typeof message === "string" ? message : "OpenAI Batch request failed"
|
|
14246
|
+
);
|
|
14247
|
+
}
|
|
14248
|
+
const response = read(result.value, "response");
|
|
14249
|
+
const statusCode = read(response, "status_code");
|
|
14250
|
+
if (result.source === "error" || typeof statusCode === "number" && (statusCode < 200 || statusCode >= 300)) {
|
|
14251
|
+
const message = read(read(read(response, "body"), "error"), "message");
|
|
14252
|
+
return new Error(
|
|
14253
|
+
typeof message === "string" ? message : "OpenAI Batch request failed"
|
|
14254
|
+
);
|
|
14255
|
+
}
|
|
14256
|
+
return void 0;
|
|
14257
|
+
}
|
|
14258
|
+
async function completeBatchResult(context, taskParent, endTime, input, result) {
|
|
14259
|
+
const child = await startBatchChild(context, taskParent, input);
|
|
14260
|
+
try {
|
|
14261
|
+
const resultError = errorFromResult(result);
|
|
14262
|
+
const responseBody = read(read(result.value, "response"), "body");
|
|
14263
|
+
if (resultError) {
|
|
14264
|
+
child.log({ error: resultError });
|
|
14265
|
+
} else if (isObject(responseBody)) {
|
|
14266
|
+
const model = read(responseBody, "model");
|
|
14267
|
+
child.log({
|
|
14268
|
+
output: context.endpoint === "/v1/chat/completions" ? read(responseBody, "choices") : processImagesInOutput(read(responseBody, "output")),
|
|
14269
|
+
...typeof model === "string" ? { metadata: { model } } : {},
|
|
14270
|
+
metrics: parseMetricsFromUsage(read(responseBody, "usage"))
|
|
14271
|
+
});
|
|
14272
|
+
} else {
|
|
14273
|
+
child.log({ error: new Error("OpenAI Batch response body is missing") });
|
|
14274
|
+
}
|
|
14275
|
+
} catch (error) {
|
|
14276
|
+
child.log({ error });
|
|
14277
|
+
} finally {
|
|
14278
|
+
child.end({ endTime });
|
|
14279
|
+
}
|
|
14280
|
+
}
|
|
14281
|
+
async function completeResultFile({
|
|
14282
|
+
context,
|
|
14283
|
+
endTime,
|
|
14284
|
+
file,
|
|
14285
|
+
inputs,
|
|
14286
|
+
issues,
|
|
14287
|
+
seen,
|
|
14288
|
+
source,
|
|
14289
|
+
taskParent
|
|
14290
|
+
}) {
|
|
14291
|
+
if (file === void 0) {
|
|
14292
|
+
return;
|
|
14293
|
+
}
|
|
14294
|
+
for await (const value of jsonlRecords(file, (issue) => issues.push(issue))) {
|
|
14295
|
+
const customId = read(value, "custom_id");
|
|
14296
|
+
if (!validCustomId(customId) || !isObject(value)) {
|
|
14297
|
+
issues.push(
|
|
14298
|
+
new Error("OpenAI Batch result is missing a valid custom_id")
|
|
14299
|
+
);
|
|
14300
|
+
continue;
|
|
14301
|
+
}
|
|
14302
|
+
if (seen.has(customId)) {
|
|
14303
|
+
issues.push(new Error("OpenAI Batch result contains a duplicate"));
|
|
14304
|
+
continue;
|
|
14305
|
+
}
|
|
14306
|
+
const input = inputs.get(customId);
|
|
14307
|
+
if (!input) {
|
|
14308
|
+
issues.push(
|
|
14309
|
+
new Error("OpenAI Batch result does not match an input record")
|
|
14310
|
+
);
|
|
14311
|
+
continue;
|
|
14312
|
+
}
|
|
14313
|
+
seen.add(customId);
|
|
14314
|
+
await completeBatchResult(context, taskParent, endTime, input, {
|
|
14315
|
+
value,
|
|
14316
|
+
source
|
|
14317
|
+
});
|
|
14318
|
+
}
|
|
14319
|
+
}
|
|
14320
|
+
function sameInputs(first, second) {
|
|
14321
|
+
return first.size === second.size && [...first.keys()].every((customId) => second.has(customId));
|
|
14322
|
+
}
|
|
14323
|
+
async function contextForCompletion(inputFileId, inputData) {
|
|
14324
|
+
if (!inputData.endpoint || inputData.issues.length > 0) {
|
|
14325
|
+
return void 0;
|
|
14326
|
+
}
|
|
14327
|
+
const existing = pendingBatchTraces.get(inputFileId);
|
|
14328
|
+
if (existing) {
|
|
14329
|
+
if (existing.context.endpoint !== inputData.endpoint || !sameInputs(existing.inputs, inputData.inputs)) {
|
|
14330
|
+
return void 0;
|
|
14331
|
+
}
|
|
14332
|
+
return { ...existing, inputs: inputData.inputs };
|
|
14333
|
+
}
|
|
14334
|
+
const parent = await exportParent(getSpanParentObject());
|
|
14335
|
+
if (!parent) {
|
|
14336
|
+
return void 0;
|
|
14337
|
+
}
|
|
14338
|
+
const startTime = getCurrentUnixTimestamp();
|
|
14339
|
+
return {
|
|
14340
|
+
context: {
|
|
14341
|
+
inputFileId,
|
|
14342
|
+
endpoint: inputData.endpoint,
|
|
14343
|
+
parent,
|
|
14344
|
+
taskStartTime: startTime,
|
|
14345
|
+
childStartTime: startTime
|
|
14346
|
+
},
|
|
14347
|
+
inputs: inputData.inputs
|
|
14348
|
+
};
|
|
14349
|
+
}
|
|
14350
|
+
async function completeBatch(args) {
|
|
14351
|
+
const inputData = await readBatchInputs(args.inputFileContent);
|
|
14352
|
+
const trace = await contextForCompletion(args.inputFileId, inputData);
|
|
14353
|
+
if (!trace) {
|
|
14354
|
+
logBatchInstrumentationError(
|
|
14355
|
+
"left batch spans pending",
|
|
14356
|
+
inputData.issues[0] ?? new Error("OpenAI Batch input does not match")
|
|
14357
|
+
);
|
|
14358
|
+
return;
|
|
14359
|
+
}
|
|
14360
|
+
const endTime = trace.endTime ?? getCurrentUnixTimestamp();
|
|
14361
|
+
const task = await startBatchSpan(trace.context);
|
|
14362
|
+
const taskParent = await task.export();
|
|
14363
|
+
const issues = [];
|
|
14364
|
+
const seen = /* @__PURE__ */ new Set();
|
|
14365
|
+
await Promise.all([
|
|
14366
|
+
completeResultFile({
|
|
14367
|
+
context: trace.context,
|
|
14368
|
+
endTime,
|
|
14369
|
+
file: args.outputFileContent,
|
|
14370
|
+
inputs: trace.inputs,
|
|
14371
|
+
issues,
|
|
14372
|
+
seen,
|
|
14373
|
+
source: "output",
|
|
14374
|
+
taskParent
|
|
14375
|
+
}),
|
|
14376
|
+
completeResultFile({
|
|
14377
|
+
context: trace.context,
|
|
14378
|
+
endTime,
|
|
14379
|
+
file: args.errorFileContent,
|
|
14380
|
+
inputs: trace.inputs,
|
|
14381
|
+
issues,
|
|
14382
|
+
seen,
|
|
14383
|
+
source: "error",
|
|
14384
|
+
taskParent
|
|
14385
|
+
})
|
|
14386
|
+
]);
|
|
14387
|
+
if (issues.length > 0) {
|
|
14388
|
+
logBatchInstrumentationError("left batch spans pending", issues[0]);
|
|
14389
|
+
return;
|
|
14390
|
+
}
|
|
14391
|
+
const missing = [...trace.inputs.values()].filter(
|
|
14392
|
+
({ customId }) => !seen.has(customId)
|
|
14393
|
+
);
|
|
14394
|
+
if (!trace.status || trace.status === "completed") {
|
|
14395
|
+
if (missing.length > 0) {
|
|
14396
|
+
logBatchInstrumentationError(
|
|
14397
|
+
"left batch spans pending",
|
|
14398
|
+
new Error("OpenAI Batch result files are incomplete")
|
|
14399
|
+
);
|
|
14400
|
+
return;
|
|
14401
|
+
}
|
|
14402
|
+
} else {
|
|
14403
|
+
for (const input of missing) {
|
|
14404
|
+
const child = await startBatchChild(trace.context, taskParent, input);
|
|
14405
|
+
child.log({ error: new Error(`OpenAI Batch ${trace.status}`) });
|
|
14406
|
+
child.end({ endTime });
|
|
14407
|
+
}
|
|
14408
|
+
task.log({ error: new Error(`OpenAI Batch ${trace.status}`) });
|
|
14409
|
+
}
|
|
14410
|
+
task.end({ endTime });
|
|
14411
|
+
pendingBatchTraces.delete(args.inputFileId);
|
|
14412
|
+
}
|
|
14413
|
+
var interceptOpenAIBatchTraceComplete = (target, thisArg, args) => Promise.resolve(Reflect.apply(target, thisArg, args)).then(async (result) => {
|
|
14414
|
+
try {
|
|
14415
|
+
await completeBatch(args[0]);
|
|
14416
|
+
} catch (error) {
|
|
14417
|
+
logBatchInstrumentationError("could not complete batch", error);
|
|
14418
|
+
}
|
|
14419
|
+
return result;
|
|
14420
|
+
});
|
|
14421
|
+
|
|
13770
14422
|
// src/instrumentation/plugins/openai-plugin.ts
|
|
13771
14423
|
var OpenAIPlugin = class extends BasePlugin {
|
|
13772
14424
|
constructor() {
|
|
13773
14425
|
super();
|
|
13774
14426
|
}
|
|
13775
14427
|
onEnable() {
|
|
14428
|
+
this.unsubscribers.push(
|
|
14429
|
+
openAIChannels.filesCreateTraced.intercept(
|
|
14430
|
+
interceptOpenAIFilesCreateTraced
|
|
14431
|
+
),
|
|
14432
|
+
openAIChannels.batchesRetrieveTraced.intercept(
|
|
14433
|
+
interceptOpenAIBatchesRetrieveTraced
|
|
14434
|
+
),
|
|
14435
|
+
openAIChannels.batchesCompleteTrace.intercept(
|
|
14436
|
+
interceptOpenAIBatchTraceComplete
|
|
14437
|
+
)
|
|
14438
|
+
);
|
|
13776
14439
|
this.unsubscribers.push(
|
|
13777
14440
|
traceStreamingChannel(openAIChannels.chatCompletionsCreate, {
|
|
13778
14441
|
name: "Chat Completion",
|
|
13779
14442
|
type: "llm" /* LLM */,
|
|
13780
|
-
extractInput: ([params]) =>
|
|
13781
|
-
const { messages, ...metadata } = params;
|
|
13782
|
-
return {
|
|
13783
|
-
input: processInputAttachments(messages),
|
|
13784
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13785
|
-
};
|
|
13786
|
-
},
|
|
14443
|
+
extractInput: ([params]) => extractOpenAIChatInput(params),
|
|
13787
14444
|
extractOutput: (result) => {
|
|
13788
14445
|
return result?.choices;
|
|
13789
14446
|
},
|
|
@@ -13829,13 +14486,7 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13829
14486
|
traceStreamingChannel(openAIChannels.betaChatCompletionsParse, {
|
|
13830
14487
|
name: "Chat Completion",
|
|
13831
14488
|
type: "llm" /* LLM */,
|
|
13832
|
-
extractInput: ([params]) =>
|
|
13833
|
-
const { messages, ...metadata } = params;
|
|
13834
|
-
return {
|
|
13835
|
-
input: processInputAttachments(messages),
|
|
13836
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13837
|
-
};
|
|
13838
|
-
},
|
|
14489
|
+
extractInput: ([params]) => extractOpenAIChatInput(params),
|
|
13839
14490
|
extractOutput: (result) => {
|
|
13840
14491
|
return result?.choices;
|
|
13841
14492
|
},
|
|
@@ -13857,13 +14508,7 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13857
14508
|
traceSyncStreamChannel(openAIChannels.betaChatCompletionsStream, {
|
|
13858
14509
|
name: "Chat Completion",
|
|
13859
14510
|
type: "llm" /* LLM */,
|
|
13860
|
-
extractInput: ([params]) =>
|
|
13861
|
-
const { messages, ...metadata } = params;
|
|
13862
|
-
return {
|
|
13863
|
-
input: processInputAttachments(messages),
|
|
13864
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13865
|
-
};
|
|
13866
|
-
}
|
|
14511
|
+
extractInput: ([params]) => extractOpenAIChatInput(params)
|
|
13867
14512
|
})
|
|
13868
14513
|
);
|
|
13869
14514
|
this.unsubscribers.push(
|
|
@@ -13893,23 +14538,11 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13893
14538
|
traceStreamingChannel(openAIChannels.responsesCreate, {
|
|
13894
14539
|
name: "openai.responses.create",
|
|
13895
14540
|
type: "llm" /* LLM */,
|
|
13896
|
-
extractInput: ([params]) =>
|
|
13897
|
-
const { input, ...metadata } = params;
|
|
13898
|
-
return {
|
|
13899
|
-
input: processInputAttachments(input),
|
|
13900
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13901
|
-
};
|
|
13902
|
-
},
|
|
14541
|
+
extractInput: ([params]) => extractOpenAIResponsesInput(params),
|
|
13903
14542
|
extractOutput: (result) => {
|
|
13904
14543
|
return processImagesInOutput(result?.output);
|
|
13905
14544
|
},
|
|
13906
|
-
extractMetadata: (result) =>
|
|
13907
|
-
if (!result) {
|
|
13908
|
-
return void 0;
|
|
13909
|
-
}
|
|
13910
|
-
const { output: _output, usage: _usage, ...metadata } = result;
|
|
13911
|
-
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
13912
|
-
},
|
|
14545
|
+
extractMetadata: (result) => extractOpenAIResponsesMetadata(result),
|
|
13913
14546
|
extractMetrics: (result, startTime, endEvent) => {
|
|
13914
14547
|
const metrics = withCachedMetric(
|
|
13915
14548
|
parseMetricsFromUsage(result?.usage),
|
|
@@ -13928,13 +14561,7 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13928
14561
|
traceSyncStreamChannel(openAIChannels.responsesStream, {
|
|
13929
14562
|
name: "openai.responses.create",
|
|
13930
14563
|
type: "llm" /* LLM */,
|
|
13931
|
-
extractInput: ([params]) =>
|
|
13932
|
-
const { input, ...metadata } = params;
|
|
13933
|
-
return {
|
|
13934
|
-
input: processInputAttachments(input),
|
|
13935
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13936
|
-
};
|
|
13937
|
-
},
|
|
14564
|
+
extractInput: ([params]) => extractOpenAIResponsesInput(params),
|
|
13938
14565
|
extractFromEvent: (event) => {
|
|
13939
14566
|
if (event.type !== "response.completed" || !event.response) {
|
|
13940
14567
|
return {};
|
|
@@ -13957,23 +14584,11 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13957
14584
|
traceStreamingChannel(openAIChannels.responsesParse, {
|
|
13958
14585
|
name: "openai.responses.parse",
|
|
13959
14586
|
type: "llm" /* LLM */,
|
|
13960
|
-
extractInput: ([params]) =>
|
|
13961
|
-
const { input, ...metadata } = params;
|
|
13962
|
-
return {
|
|
13963
|
-
input: processInputAttachments(input),
|
|
13964
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13965
|
-
};
|
|
13966
|
-
},
|
|
14587
|
+
extractInput: ([params]) => extractOpenAIResponsesInput(params),
|
|
13967
14588
|
extractOutput: (result) => {
|
|
13968
14589
|
return processImagesInOutput(result?.output);
|
|
13969
14590
|
},
|
|
13970
|
-
extractMetadata: (result) =>
|
|
13971
|
-
if (!result) {
|
|
13972
|
-
return void 0;
|
|
13973
|
-
}
|
|
13974
|
-
const { output: _output, usage: _usage, ...metadata } = result;
|
|
13975
|
-
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
13976
|
-
},
|
|
14591
|
+
extractMetadata: (result) => extractOpenAIResponsesMetadata(result),
|
|
13977
14592
|
extractMetrics: (result, startTime, endEvent) => {
|
|
13978
14593
|
const metrics = withCachedMetric(
|
|
13979
14594
|
parseMetricsFromUsage(result?.usage),
|
|
@@ -13992,23 +14607,11 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13992
14607
|
traceAsyncChannel(openAIChannels.responsesCompact, {
|
|
13993
14608
|
name: "openai.responses.compact",
|
|
13994
14609
|
type: "llm" /* LLM */,
|
|
13995
|
-
extractInput: ([params]) =>
|
|
13996
|
-
const { input, ...metadata } = params;
|
|
13997
|
-
return {
|
|
13998
|
-
input: processInputAttachments(input),
|
|
13999
|
-
metadata: { ...metadata, provider: "openai" }
|
|
14000
|
-
};
|
|
14001
|
-
},
|
|
14610
|
+
extractInput: ([params]) => extractOpenAIResponsesInput(params),
|
|
14002
14611
|
extractOutput: (result) => {
|
|
14003
14612
|
return processImagesInOutput(result?.output);
|
|
14004
14613
|
},
|
|
14005
|
-
extractMetadata: (result) =>
|
|
14006
|
-
if (!result) {
|
|
14007
|
-
return void 0;
|
|
14008
|
-
}
|
|
14009
|
-
const { output: _output, usage: _usage, ...metadata } = result;
|
|
14010
|
-
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
14011
|
-
},
|
|
14614
|
+
extractMetadata: (result) => extractOpenAIResponsesMetadata(result),
|
|
14012
14615
|
extractMetrics: (result, startTime, endEvent) => {
|
|
14013
14616
|
const metrics = withCachedMetric(
|
|
14014
14617
|
parseMetricsFromUsage(result?.usage),
|
|
@@ -14064,35 +14667,6 @@ function withCachedMetric(metrics, result, endEvent) {
|
|
|
14064
14667
|
cached
|
|
14065
14668
|
};
|
|
14066
14669
|
}
|
|
14067
|
-
function processImagesInOutput(output) {
|
|
14068
|
-
if (Array.isArray(output)) {
|
|
14069
|
-
return output.map(processImagesInOutput);
|
|
14070
|
-
}
|
|
14071
|
-
if (isObject(output)) {
|
|
14072
|
-
if (output.type === "image_generation_call" && output.result && typeof output.result === "string") {
|
|
14073
|
-
const fileExtension = output.output_format || "png";
|
|
14074
|
-
const contentType = `image/${fileExtension}`;
|
|
14075
|
-
const baseFilename = output.revised_prompt && typeof output.revised_prompt === "string" ? output.revised_prompt.slice(0, 50).replace(/[^a-zA-Z0-9]/g, "_") : "generated_image";
|
|
14076
|
-
const filename = `${baseFilename}.${fileExtension}`;
|
|
14077
|
-
const binaryString = atob(output.result);
|
|
14078
|
-
const bytes = new Uint8Array(binaryString.length);
|
|
14079
|
-
for (let i = 0; i < binaryString.length; i++) {
|
|
14080
|
-
bytes[i] = binaryString.charCodeAt(i);
|
|
14081
|
-
}
|
|
14082
|
-
const blob = new Blob([bytes], { type: contentType });
|
|
14083
|
-
const attachment = new Attachment({
|
|
14084
|
-
data: blob,
|
|
14085
|
-
filename,
|
|
14086
|
-
contentType
|
|
14087
|
-
});
|
|
14088
|
-
return {
|
|
14089
|
-
...output,
|
|
14090
|
-
result: attachment
|
|
14091
|
-
};
|
|
14092
|
-
}
|
|
14093
|
-
}
|
|
14094
|
-
return output;
|
|
14095
|
-
}
|
|
14096
14670
|
function mergeLogprobTokens(existing, incoming) {
|
|
14097
14671
|
if (incoming === void 0) {
|
|
14098
14672
|
return existing;
|
|
@@ -34125,7 +34699,7 @@ function extractSession(event) {
|
|
|
34125
34699
|
return isObject(candidate) && typeof candidate.prompt === "function" ? candidate : void 0;
|
|
34126
34700
|
}
|
|
34127
34701
|
function isPiAgent(value) {
|
|
34128
|
-
return isObject(value) && typeof value.streamFn === "function" && typeof value.subscribe === "function";
|
|
34702
|
+
return isObject(value) && (typeof value.streamFunction === "function" || typeof value.streamFn === "function") && typeof value.subscribe === "function";
|
|
34129
34703
|
}
|
|
34130
34704
|
function promptContextStore() {
|
|
34131
34705
|
piPromptContextStore ??= isomorph_default.newAsyncLocalStorage();
|
|
@@ -34135,17 +34709,21 @@ function currentPiPromptState() {
|
|
|
34135
34709
|
return promptContextStore().getStore();
|
|
34136
34710
|
}
|
|
34137
34711
|
function installPiAgentInstrumentation(agent) {
|
|
34712
|
+
const property = typeof agent.streamFunction === "function" ? "streamFunction" : "streamFn";
|
|
34713
|
+
const streamFunction = agent[property];
|
|
34138
34714
|
const existing = piAgentPatchStates.get(agent);
|
|
34139
|
-
if (!existing ||
|
|
34715
|
+
if (streamFunction && (!existing || existing.property !== property || streamFunction !== existing.wrappedStreamFunction)) {
|
|
34140
34716
|
const patchState = {
|
|
34141
|
-
|
|
34142
|
-
|
|
34717
|
+
originalStreamFunction: streamFunction,
|
|
34718
|
+
property,
|
|
34719
|
+
wrappedStreamFunction: streamFunction
|
|
34143
34720
|
};
|
|
34144
|
-
patchState.
|
|
34721
|
+
patchState.wrappedStreamFunction = makeInstrumentedStreamFunction(
|
|
34145
34722
|
agent,
|
|
34146
|
-
patchState.
|
|
34723
|
+
patchState.originalStreamFunction,
|
|
34724
|
+
property
|
|
34147
34725
|
);
|
|
34148
|
-
agent
|
|
34726
|
+
agent[property] = patchState.wrappedStreamFunction;
|
|
34149
34727
|
piAgentPatchStates.set(agent, patchState);
|
|
34150
34728
|
}
|
|
34151
34729
|
if (piAgentEventSubscriptions.has(agent)) {
|
|
@@ -34170,15 +34748,21 @@ function installPiAgentInstrumentation(agent) {
|
|
|
34170
34748
|
logInstrumentationError4("Pi Coding Agent event subscription", error);
|
|
34171
34749
|
}
|
|
34172
34750
|
}
|
|
34173
|
-
function
|
|
34174
|
-
return async function
|
|
34175
|
-
const invokeOriginal = () => Reflect.apply(
|
|
34751
|
+
function makeInstrumentedStreamFunction(agent, originalStreamFunction, property) {
|
|
34752
|
+
return async function instrumentedPiStreamFunction(model, context, options) {
|
|
34753
|
+
const invokeOriginal = () => Reflect.apply(originalStreamFunction, this, [model, context, options]);
|
|
34176
34754
|
const state = currentPiPromptState();
|
|
34177
34755
|
if (!state || state.agent !== agent || state.finalized) {
|
|
34178
34756
|
return invokeOriginal();
|
|
34179
34757
|
}
|
|
34180
34758
|
wrapPiToolExecutors(context.tools);
|
|
34181
|
-
const llmState = await startPiLlmSpan(
|
|
34759
|
+
const llmState = await startPiLlmSpan(
|
|
34760
|
+
state,
|
|
34761
|
+
model,
|
|
34762
|
+
context,
|
|
34763
|
+
property,
|
|
34764
|
+
options
|
|
34765
|
+
);
|
|
34182
34766
|
try {
|
|
34183
34767
|
const stream = await runWithAutoInstrumentationSuppressed(invokeOriginal);
|
|
34184
34768
|
return patchAssistantMessageStream(stream, state, llmState);
|
|
@@ -34215,12 +34799,12 @@ function wrapPiToolExecutors(tools) {
|
|
|
34215
34799
|
}
|
|
34216
34800
|
}
|
|
34217
34801
|
}
|
|
34218
|
-
async function startPiLlmSpan(state, model, context, options) {
|
|
34802
|
+
async function startPiLlmSpan(state, model, context, property, options) {
|
|
34219
34803
|
const metadata = {
|
|
34220
34804
|
...extractModelMetadata2(model),
|
|
34221
34805
|
...extractStreamOptionsMetadata(options),
|
|
34222
34806
|
...extractToolMetadata(context.tools),
|
|
34223
|
-
"pi_coding_agent.operation":
|
|
34807
|
+
"pi_coding_agent.operation": `agent.${property}`
|
|
34224
34808
|
};
|
|
34225
34809
|
const span = startSpan(
|
|
34226
34810
|
withSpanInstrumentationName(
|
|
@@ -37236,6 +37820,7 @@ __export(exports_exports, {
|
|
|
37236
37820
|
braintrustStreamChunkSchema: () => braintrustStreamChunkSchema,
|
|
37237
37821
|
buildLocalSummary: () => buildLocalSummary,
|
|
37238
37822
|
collectAnthropicSession: () => collectAnthropicSession,
|
|
37823
|
+
completeOpenAIBatchTrace: () => completeOpenAIBatchTrace,
|
|
37239
37824
|
configureInstrumentation: () => configureInstrumentation,
|
|
37240
37825
|
constructLogs3OverflowRequest: () => constructLogs3OverflowRequest,
|
|
37241
37826
|
createFinalValuePassThroughStream: () => createFinalValuePassThroughStream,
|
|
@@ -37274,6 +37859,8 @@ __export(exports_exports, {
|
|
|
37274
37859
|
loginToState: () => loginToState,
|
|
37275
37860
|
logs3OverflowUploadSchema: () => logs3OverflowUploadSchema,
|
|
37276
37861
|
newId: () => newId,
|
|
37862
|
+
openaiBatchesRetrieveTraced: () => openaiBatchesRetrieveTraced,
|
|
37863
|
+
openaiFilesCreateTraced: () => openaiFilesCreateTraced,
|
|
37277
37864
|
parseCachedHeader: () => parseCachedHeader,
|
|
37278
37865
|
parseTemplateFormat: () => parseTemplateFormat,
|
|
37279
37866
|
permalink: () => permalink,
|
|
@@ -37438,6 +38025,260 @@ async function registerSandbox(options) {
|
|
|
37438
38025
|
};
|
|
37439
38026
|
}
|
|
37440
38027
|
|
|
38028
|
+
// src/wrappers/openai-promise-utils.ts
|
|
38029
|
+
function splitSpanInfo(allParams) {
|
|
38030
|
+
const { span_info, ...params } = allParams;
|
|
38031
|
+
return {
|
|
38032
|
+
params,
|
|
38033
|
+
span_info
|
|
38034
|
+
};
|
|
38035
|
+
}
|
|
38036
|
+
function createChannelContext(_channel, params, span_info) {
|
|
38037
|
+
return {
|
|
38038
|
+
arguments: (
|
|
38039
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38040
|
+
[params]
|
|
38041
|
+
),
|
|
38042
|
+
span_info
|
|
38043
|
+
};
|
|
38044
|
+
}
|
|
38045
|
+
async function tracePromiseWithResponse(channel2, traceContext, apiPromise) {
|
|
38046
|
+
let enhancedResponse;
|
|
38047
|
+
const tracePromise = (
|
|
38048
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38049
|
+
channel2.tracePromise
|
|
38050
|
+
);
|
|
38051
|
+
const data = await tracePromise(async () => {
|
|
38052
|
+
enhancedResponse = await apiPromise.withResponse();
|
|
38053
|
+
traceContext.response = enhancedResponse.response;
|
|
38054
|
+
return enhancedResponse.data;
|
|
38055
|
+
}, traceContext);
|
|
38056
|
+
if (!enhancedResponse) {
|
|
38057
|
+
throw new Error("Expected withResponse() to provide response");
|
|
38058
|
+
}
|
|
38059
|
+
return {
|
|
38060
|
+
data,
|
|
38061
|
+
response: enhancedResponse.response,
|
|
38062
|
+
request_id: enhancedResponse.request_id
|
|
38063
|
+
};
|
|
38064
|
+
}
|
|
38065
|
+
async function tracePromiseAsResponse(channel2, traceContext, apiPromise) {
|
|
38066
|
+
const tracePromise = (
|
|
38067
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38068
|
+
channel2.tracePromise
|
|
38069
|
+
);
|
|
38070
|
+
let response;
|
|
38071
|
+
await tracePromise(async () => {
|
|
38072
|
+
response = await apiPromise.asResponse();
|
|
38073
|
+
traceContext.response = response;
|
|
38074
|
+
return void 0;
|
|
38075
|
+
}, traceContext);
|
|
38076
|
+
if (!response) {
|
|
38077
|
+
throw new Error("Expected asResponse() to provide response");
|
|
38078
|
+
}
|
|
38079
|
+
return response;
|
|
38080
|
+
}
|
|
38081
|
+
function createLazyAPIPromise(ensureExecuted, ensureResponse, getAPIPromise) {
|
|
38082
|
+
let firstConsumption;
|
|
38083
|
+
let enhancedResponsePromise;
|
|
38084
|
+
let dataPromise;
|
|
38085
|
+
let responsePromise;
|
|
38086
|
+
const withResponse = () => {
|
|
38087
|
+
firstConsumption ??= "data";
|
|
38088
|
+
enhancedResponsePromise ??= firstConsumption === "data" ? ensureExecuted() : getAPIPromise().withResponse();
|
|
38089
|
+
return enhancedResponsePromise;
|
|
38090
|
+
};
|
|
38091
|
+
const asResponse = () => {
|
|
38092
|
+
firstConsumption ??= "response";
|
|
38093
|
+
responsePromise ??= firstConsumption === "response" ? ensureResponse() : getAPIPromise().asResponse();
|
|
38094
|
+
return responsePromise;
|
|
38095
|
+
};
|
|
38096
|
+
return new Proxy({}, {
|
|
38097
|
+
get(target, prop, receiver) {
|
|
38098
|
+
if (prop === "withResponse") {
|
|
38099
|
+
return withResponse;
|
|
38100
|
+
}
|
|
38101
|
+
if (prop === "asResponse") {
|
|
38102
|
+
return asResponse;
|
|
38103
|
+
}
|
|
38104
|
+
if (prop === "then" || prop === "catch" || prop === "finally" || prop in Promise.prototype) {
|
|
38105
|
+
dataPromise ??= withResponse().then((result) => result.data);
|
|
38106
|
+
const value = Reflect.get(dataPromise, prop, receiver);
|
|
38107
|
+
return typeof value === "function" ? value.bind(dataPromise) : value;
|
|
38108
|
+
}
|
|
38109
|
+
return Reflect.get(target, prop, receiver);
|
|
38110
|
+
}
|
|
38111
|
+
});
|
|
38112
|
+
}
|
|
38113
|
+
|
|
38114
|
+
// src/openai-batch.ts
|
|
38115
|
+
function read2(value, key) {
|
|
38116
|
+
if (value === null || typeof value !== "object" && typeof value !== "function") {
|
|
38117
|
+
return void 0;
|
|
38118
|
+
}
|
|
38119
|
+
try {
|
|
38120
|
+
return Reflect.get(value, key);
|
|
38121
|
+
} catch {
|
|
38122
|
+
return void 0;
|
|
38123
|
+
}
|
|
38124
|
+
}
|
|
38125
|
+
function isAsyncIterable5(value) {
|
|
38126
|
+
return typeof read2(value, Symbol.asyncIterator) === "function";
|
|
38127
|
+
}
|
|
38128
|
+
function teeAsyncIterable(source) {
|
|
38129
|
+
const iterator = source[Symbol.asyncIterator]();
|
|
38130
|
+
const stream = new ReadableStream({
|
|
38131
|
+
async pull(controller) {
|
|
38132
|
+
try {
|
|
38133
|
+
const result = await iterator.next();
|
|
38134
|
+
if (result.done) {
|
|
38135
|
+
controller.close();
|
|
38136
|
+
return;
|
|
38137
|
+
}
|
|
38138
|
+
if (!(result.value instanceof Uint8Array)) {
|
|
38139
|
+
throw new TypeError(
|
|
38140
|
+
"OpenAI upload streams must yield Uint8Array chunks"
|
|
38141
|
+
);
|
|
38142
|
+
}
|
|
38143
|
+
controller.enqueue(result.value);
|
|
38144
|
+
} catch (error) {
|
|
38145
|
+
controller.error(error);
|
|
38146
|
+
}
|
|
38147
|
+
},
|
|
38148
|
+
async cancel(reason) {
|
|
38149
|
+
await iterator.return?.(reason);
|
|
38150
|
+
}
|
|
38151
|
+
});
|
|
38152
|
+
const [uploadStream, trace] = stream.tee();
|
|
38153
|
+
const upload = {
|
|
38154
|
+
async *[Symbol.asyncIterator]() {
|
|
38155
|
+
const reader = uploadStream.getReader();
|
|
38156
|
+
try {
|
|
38157
|
+
while (true) {
|
|
38158
|
+
const result = await reader.read();
|
|
38159
|
+
if (result.done) {
|
|
38160
|
+
return;
|
|
38161
|
+
}
|
|
38162
|
+
yield result.value;
|
|
38163
|
+
}
|
|
38164
|
+
} finally {
|
|
38165
|
+
reader.releaseLock();
|
|
38166
|
+
}
|
|
38167
|
+
}
|
|
38168
|
+
};
|
|
38169
|
+
const path = read2(source, "path");
|
|
38170
|
+
if (typeof path === "string") {
|
|
38171
|
+
Object.defineProperty(upload, "path", { value: path });
|
|
38172
|
+
}
|
|
38173
|
+
return { upload, trace: new Response(trace) };
|
|
38174
|
+
}
|
|
38175
|
+
function teeUpload(upload) {
|
|
38176
|
+
if (upload instanceof Blob) {
|
|
38177
|
+
return { upload, trace: new Response(upload) };
|
|
38178
|
+
}
|
|
38179
|
+
if (upload instanceof Response) {
|
|
38180
|
+
return { upload, trace: upload.clone() };
|
|
38181
|
+
}
|
|
38182
|
+
if (isAsyncIterable5(upload)) {
|
|
38183
|
+
return teeAsyncIterable(upload);
|
|
38184
|
+
}
|
|
38185
|
+
return void 0;
|
|
38186
|
+
}
|
|
38187
|
+
function openaiFilesCreateTraced(files) {
|
|
38188
|
+
return (params, options) => {
|
|
38189
|
+
const parent = getSpanParentObject();
|
|
38190
|
+
const purpose = read2(params, "purpose");
|
|
38191
|
+
const file = read2(params, "file");
|
|
38192
|
+
if (purpose !== "batch") {
|
|
38193
|
+
return files.create(params, options);
|
|
38194
|
+
}
|
|
38195
|
+
let branches;
|
|
38196
|
+
try {
|
|
38197
|
+
branches = teeUpload(file);
|
|
38198
|
+
} catch {
|
|
38199
|
+
return files.create(params, options);
|
|
38200
|
+
}
|
|
38201
|
+
if (!branches) {
|
|
38202
|
+
return files.create(params, options);
|
|
38203
|
+
}
|
|
38204
|
+
const tracedParams = {
|
|
38205
|
+
...Object(params),
|
|
38206
|
+
file: branches.upload
|
|
38207
|
+
};
|
|
38208
|
+
const apiPromise = files.create(tracedParams, options);
|
|
38209
|
+
let enhancedResponse;
|
|
38210
|
+
const tracedResponse = openAIChannels.filesCreateTraced.invoke(
|
|
38211
|
+
async () => {
|
|
38212
|
+
enhancedResponse = await apiPromise.withResponse();
|
|
38213
|
+
return enhancedResponse.data;
|
|
38214
|
+
},
|
|
38215
|
+
files,
|
|
38216
|
+
[{ params, inputFileContent: branches.trace, parent }],
|
|
38217
|
+
{}
|
|
38218
|
+
).then((data) => {
|
|
38219
|
+
if (!enhancedResponse) {
|
|
38220
|
+
throw new Error(
|
|
38221
|
+
"Expected OpenAI withResponse() to provide a response"
|
|
38222
|
+
);
|
|
38223
|
+
}
|
|
38224
|
+
return { ...enhancedResponse, data };
|
|
38225
|
+
});
|
|
38226
|
+
return createLazyAPIPromise(
|
|
38227
|
+
() => tracedResponse,
|
|
38228
|
+
() => tracedResponse.then(({ response }) => response),
|
|
38229
|
+
() => apiPromise
|
|
38230
|
+
);
|
|
38231
|
+
};
|
|
38232
|
+
}
|
|
38233
|
+
function openaiBatchesRetrieveTraced(batches) {
|
|
38234
|
+
return (batchId, options) => {
|
|
38235
|
+
const apiPromise = batches.retrieve(batchId, options);
|
|
38236
|
+
let enhancedResponse;
|
|
38237
|
+
const tracedResponse = openAIChannels.batchesRetrieveTraced.invoke(
|
|
38238
|
+
async () => {
|
|
38239
|
+
enhancedResponse = await apiPromise.withResponse();
|
|
38240
|
+
return enhancedResponse.data;
|
|
38241
|
+
},
|
|
38242
|
+
batches,
|
|
38243
|
+
[{ batchId }],
|
|
38244
|
+
{}
|
|
38245
|
+
).then((data) => {
|
|
38246
|
+
if (!enhancedResponse) {
|
|
38247
|
+
throw new Error(
|
|
38248
|
+
"Expected OpenAI withResponse() to provide a response"
|
|
38249
|
+
);
|
|
38250
|
+
}
|
|
38251
|
+
return { ...enhancedResponse, data };
|
|
38252
|
+
});
|
|
38253
|
+
return createLazyAPIPromise(
|
|
38254
|
+
() => tracedResponse,
|
|
38255
|
+
() => tracedResponse.then(({ response }) => response),
|
|
38256
|
+
() => apiPromise
|
|
38257
|
+
);
|
|
38258
|
+
};
|
|
38259
|
+
}
|
|
38260
|
+
async function completeOpenAIBatchTrace(args) {
|
|
38261
|
+
const inputFileContent = Promise.resolve(args.inputFileContent);
|
|
38262
|
+
const outputFileContent = args.outputFileContent === void 0 ? void 0 : Promise.resolve(args.outputFileContent);
|
|
38263
|
+
const errorFileContent = args.errorFileContent === void 0 ? void 0 : Promise.resolve(args.errorFileContent);
|
|
38264
|
+
void inputFileContent.catch(() => void 0);
|
|
38265
|
+
void outputFileContent?.catch(() => void 0);
|
|
38266
|
+
void errorFileContent?.catch(() => void 0);
|
|
38267
|
+
await openAIChannels.batchesCompleteTrace.invoke(
|
|
38268
|
+
async () => void 0,
|
|
38269
|
+
void 0,
|
|
38270
|
+
[
|
|
38271
|
+
{
|
|
38272
|
+
...args,
|
|
38273
|
+
inputFileContent,
|
|
38274
|
+
outputFileContent,
|
|
38275
|
+
errorFileContent
|
|
38276
|
+
}
|
|
38277
|
+
],
|
|
38278
|
+
{}
|
|
38279
|
+
);
|
|
38280
|
+
}
|
|
38281
|
+
|
|
37441
38282
|
// src/functions/invoke.ts
|
|
37442
38283
|
async function invoke(args) {
|
|
37443
38284
|
const {
|
|
@@ -37540,58 +38381,6 @@ function initFunction({
|
|
|
37540
38381
|
return f;
|
|
37541
38382
|
}
|
|
37542
38383
|
|
|
37543
|
-
// src/wrappers/openai-promise-utils.ts
|
|
37544
|
-
function splitSpanInfo(allParams) {
|
|
37545
|
-
const { span_info, ...params } = allParams;
|
|
37546
|
-
return {
|
|
37547
|
-
params,
|
|
37548
|
-
span_info
|
|
37549
|
-
};
|
|
37550
|
-
}
|
|
37551
|
-
function createChannelContext(_channel, params, span_info) {
|
|
37552
|
-
return {
|
|
37553
|
-
arguments: (
|
|
37554
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
37555
|
-
[params]
|
|
37556
|
-
),
|
|
37557
|
-
span_info
|
|
37558
|
-
};
|
|
37559
|
-
}
|
|
37560
|
-
async function tracePromiseWithResponse(channel2, traceContext, apiPromise) {
|
|
37561
|
-
let enhancedResponse;
|
|
37562
|
-
const tracePromise = (
|
|
37563
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
37564
|
-
channel2.tracePromise
|
|
37565
|
-
);
|
|
37566
|
-
const data = await tracePromise(async () => {
|
|
37567
|
-
enhancedResponse = await apiPromise.withResponse();
|
|
37568
|
-
traceContext.response = enhancedResponse.response;
|
|
37569
|
-
return enhancedResponse.data;
|
|
37570
|
-
}, traceContext);
|
|
37571
|
-
if (!enhancedResponse) {
|
|
37572
|
-
throw new Error("Expected withResponse() to provide response");
|
|
37573
|
-
}
|
|
37574
|
-
return { data, response: enhancedResponse.response };
|
|
37575
|
-
}
|
|
37576
|
-
function createLazyAPIPromise(ensureExecuted) {
|
|
37577
|
-
let dataPromise = null;
|
|
37578
|
-
return new Proxy({}, {
|
|
37579
|
-
get(target, prop, receiver) {
|
|
37580
|
-
if (prop === "withResponse") {
|
|
37581
|
-
return () => ensureExecuted();
|
|
37582
|
-
}
|
|
37583
|
-
if (prop === "then" || prop === "catch" || prop === "finally" || prop in Promise.prototype) {
|
|
37584
|
-
if (!dataPromise) {
|
|
37585
|
-
dataPromise = ensureExecuted().then((result) => result.data);
|
|
37586
|
-
}
|
|
37587
|
-
const value = Reflect.get(dataPromise, prop, receiver);
|
|
37588
|
-
return typeof value === "function" ? value.bind(dataPromise) : value;
|
|
37589
|
-
}
|
|
37590
|
-
return Reflect.get(target, prop, receiver);
|
|
37591
|
-
}
|
|
37592
|
-
});
|
|
37593
|
-
}
|
|
37594
|
-
|
|
37595
38384
|
// src/wrappers/oai_responses.ts
|
|
37596
38385
|
function responsesProxy(openai) {
|
|
37597
38386
|
if (!openai.responses) {
|
|
@@ -37628,17 +38417,33 @@ function wrapResponsesAsync(target, channel2) {
|
|
|
37628
38417
|
return (allParams, options) => {
|
|
37629
38418
|
const { span_info, params } = splitSpanInfo(allParams);
|
|
37630
38419
|
let executionPromise = null;
|
|
38420
|
+
let apiPromise = null;
|
|
38421
|
+
const getAPIPromise = () => {
|
|
38422
|
+
apiPromise ??= target(params, options);
|
|
38423
|
+
return apiPromise;
|
|
38424
|
+
};
|
|
37631
38425
|
const ensureExecuted = () => {
|
|
37632
38426
|
if (!executionPromise) {
|
|
37633
38427
|
executionPromise = (async () => {
|
|
37634
38428
|
const traceContext = createChannelContext(channel2, params, span_info);
|
|
37635
|
-
|
|
37636
|
-
|
|
38429
|
+
return tracePromiseWithResponse(
|
|
38430
|
+
channel2,
|
|
38431
|
+
traceContext,
|
|
38432
|
+
getAPIPromise()
|
|
38433
|
+
);
|
|
37637
38434
|
})();
|
|
37638
38435
|
}
|
|
37639
38436
|
return executionPromise;
|
|
37640
38437
|
};
|
|
37641
|
-
return createLazyAPIPromise(
|
|
38438
|
+
return createLazyAPIPromise(
|
|
38439
|
+
ensureExecuted,
|
|
38440
|
+
() => tracePromiseAsResponse(
|
|
38441
|
+
channel2,
|
|
38442
|
+
createChannelContext(channel2, params, span_info),
|
|
38443
|
+
getAPIPromise()
|
|
38444
|
+
),
|
|
38445
|
+
getAPIPromise
|
|
38446
|
+
);
|
|
37642
38447
|
};
|
|
37643
38448
|
}
|
|
37644
38449
|
function wrapResponsesSyncStream(target, channel2) {
|
|
@@ -37784,6 +38589,11 @@ function wrapChatCompletion(completion) {
|
|
|
37784
38589
|
allParams
|
|
37785
38590
|
);
|
|
37786
38591
|
let executionPromise = null;
|
|
38592
|
+
let apiPromise = null;
|
|
38593
|
+
const getAPIPromise = () => {
|
|
38594
|
+
apiPromise ??= completion(params, options);
|
|
38595
|
+
return apiPromise;
|
|
38596
|
+
};
|
|
37787
38597
|
const ensureExecuted = () => {
|
|
37788
38598
|
if (!executionPromise) {
|
|
37789
38599
|
executionPromise = (async () => {
|
|
@@ -37793,32 +38603,44 @@ function wrapChatCompletion(completion) {
|
|
|
37793
38603
|
span_info
|
|
37794
38604
|
);
|
|
37795
38605
|
if (params.stream) {
|
|
37796
|
-
const completionPromise =
|
|
37797
|
-
|
|
37798
|
-
|
|
38606
|
+
const completionPromise = (
|
|
38607
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38608
|
+
getAPIPromise()
|
|
37799
38609
|
);
|
|
37800
|
-
const { data: data2, response: response2 } = await tracePromiseWithResponse(
|
|
38610
|
+
const { data: data2, response: response2, request_id: request_id2 } = await tracePromiseWithResponse(
|
|
37801
38611
|
openAIChannels.chatCompletionsCreate,
|
|
37802
38612
|
traceContext,
|
|
37803
38613
|
completionPromise
|
|
37804
38614
|
);
|
|
37805
|
-
return { data: data2, response: response2 };
|
|
38615
|
+
return { data: data2, response: response2, request_id: request_id2 };
|
|
37806
38616
|
}
|
|
37807
|
-
const completionResponse =
|
|
37808
|
-
|
|
37809
|
-
|
|
38617
|
+
const completionResponse = (
|
|
38618
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38619
|
+
getAPIPromise()
|
|
37810
38620
|
);
|
|
37811
|
-
const { data, response } = await tracePromiseWithResponse(
|
|
38621
|
+
const { data, response, request_id } = await tracePromiseWithResponse(
|
|
37812
38622
|
openAIChannels.chatCompletionsCreate,
|
|
37813
38623
|
traceContext,
|
|
37814
38624
|
completionResponse
|
|
37815
38625
|
);
|
|
37816
|
-
return { data, response };
|
|
38626
|
+
return { data, response, request_id };
|
|
37817
38627
|
})();
|
|
37818
38628
|
}
|
|
37819
38629
|
return executionPromise;
|
|
37820
38630
|
};
|
|
37821
|
-
return createLazyAPIPromise(
|
|
38631
|
+
return createLazyAPIPromise(
|
|
38632
|
+
ensureExecuted,
|
|
38633
|
+
() => tracePromiseAsResponse(
|
|
38634
|
+
openAIChannels.chatCompletionsCreate,
|
|
38635
|
+
createChannelContext(
|
|
38636
|
+
openAIChannels.chatCompletionsCreate,
|
|
38637
|
+
params,
|
|
38638
|
+
span_info
|
|
38639
|
+
),
|
|
38640
|
+
getAPIPromise()
|
|
38641
|
+
),
|
|
38642
|
+
getAPIPromise
|
|
38643
|
+
);
|
|
37822
38644
|
};
|
|
37823
38645
|
}
|
|
37824
38646
|
function createEndpointProxy(target, wrapperFn) {
|
|
@@ -37836,6 +38658,11 @@ function wrapApiCreateWithChannel(create, channel2) {
|
|
|
37836
38658
|
return (allParams, options) => {
|
|
37837
38659
|
const { span_info, params } = splitSpanInfo(allParams);
|
|
37838
38660
|
let executionPromise = null;
|
|
38661
|
+
let apiPromise = null;
|
|
38662
|
+
const getAPIPromise = () => {
|
|
38663
|
+
apiPromise ??= create(params, options);
|
|
38664
|
+
return apiPromise;
|
|
38665
|
+
};
|
|
37839
38666
|
const ensureExecuted = () => {
|
|
37840
38667
|
if (!executionPromise) {
|
|
37841
38668
|
executionPromise = (async () => {
|
|
@@ -37843,13 +38670,21 @@ function wrapApiCreateWithChannel(create, channel2) {
|
|
|
37843
38670
|
return tracePromiseWithResponse(
|
|
37844
38671
|
channel2,
|
|
37845
38672
|
traceContext,
|
|
37846
|
-
|
|
38673
|
+
getAPIPromise()
|
|
37847
38674
|
);
|
|
37848
38675
|
})();
|
|
37849
38676
|
}
|
|
37850
38677
|
return executionPromise;
|
|
37851
38678
|
};
|
|
37852
|
-
return createLazyAPIPromise(
|
|
38679
|
+
return createLazyAPIPromise(
|
|
38680
|
+
ensureExecuted,
|
|
38681
|
+
() => tracePromiseAsResponse(
|
|
38682
|
+
channel2,
|
|
38683
|
+
createChannelContext(channel2, params, span_info),
|
|
38684
|
+
getAPIPromise()
|
|
38685
|
+
),
|
|
38686
|
+
getAPIPromise
|
|
38687
|
+
);
|
|
37853
38688
|
};
|
|
37854
38689
|
}
|
|
37855
38690
|
var wrapEmbeddings = (create) => wrapApiCreateWithChannel(create, openAIChannels.embeddingsCreate);
|
|
@@ -40544,7 +41379,15 @@ var MAX_EVE_PROVIDER_CACHE_ENTRIES = 1e4;
|
|
|
40544
41379
|
function createEveInstrumentationProvider(options = {}) {
|
|
40545
41380
|
const bridge = new EveProviderBridge(options.metadata);
|
|
40546
41381
|
return {
|
|
41382
|
+
// Eve versions before tracePolicy use capture to decide whether provider
|
|
41383
|
+
// events include content. Newer versions prefer tracePolicy when both are
|
|
41384
|
+
// present, so keep the deprecated field for backwards compatibility.
|
|
40547
41385
|
capture: "content",
|
|
41386
|
+
tracePolicy: () => ({
|
|
41387
|
+
emit: true,
|
|
41388
|
+
recordInputs: true,
|
|
41389
|
+
recordOutputs: true
|
|
41390
|
+
}),
|
|
40548
41391
|
events: {
|
|
40549
41392
|
"action.completed": (event, context) => bridge.handleActionTerminal(event, context),
|
|
40550
41393
|
"action.failed": (event, context) => bridge.handleActionTerminal(event, context),
|
|
@@ -44973,7 +45816,7 @@ function isAsync(fn) {
|
|
|
44973
45816
|
function isAsyncGenerator2(fn) {
|
|
44974
45817
|
return fn[Symbol.toStringTag] === "AsyncGenerator";
|
|
44975
45818
|
}
|
|
44976
|
-
function
|
|
45819
|
+
function isAsyncIterable6(obj) {
|
|
44977
45820
|
return typeof obj[Symbol.asyncIterator] === "function";
|
|
44978
45821
|
}
|
|
44979
45822
|
function wrapAsync(asyncFn) {
|
|
@@ -45145,7 +45988,7 @@ var eachOfLimit$2 = (limit) => {
|
|
|
45145
45988
|
if (isAsyncGenerator2(obj)) {
|
|
45146
45989
|
return asyncEachOfLimit(obj, limit, iteratee, callback);
|
|
45147
45990
|
}
|
|
45148
|
-
if (
|
|
45991
|
+
if (isAsyncIterable6(obj)) {
|
|
45149
45992
|
return asyncEachOfLimit(obj[Symbol.asyncIterator](), limit, iteratee, callback);
|
|
45150
45993
|
}
|
|
45151
45994
|
var nextElem = createIterator(obj);
|
|
@@ -46500,7 +47343,7 @@ function callEvaluatorData(data) {
|
|
|
46500
47343
|
baseExperiment
|
|
46501
47344
|
};
|
|
46502
47345
|
}
|
|
46503
|
-
function
|
|
47346
|
+
function isAsyncIterable7(value) {
|
|
46504
47347
|
return typeof value === "object" && value !== null && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
46505
47348
|
}
|
|
46506
47349
|
function isIterable(value) {
|
|
@@ -46535,7 +47378,7 @@ async function _internalResolveEvaluatorData(evaluator, experiment) {
|
|
|
46535
47378
|
}).asDataset();
|
|
46536
47379
|
}
|
|
46537
47380
|
const resolvedDataResult = dataResult instanceof Promise ? await dataResult : dataResult;
|
|
46538
|
-
if (
|
|
47381
|
+
if (isAsyncIterable7(resolvedDataResult)) {
|
|
46539
47382
|
return resolvedDataResult;
|
|
46540
47383
|
}
|
|
46541
47384
|
if (Array.isArray(resolvedDataResult) || isIterable(resolvedDataResult)) {
|
|
@@ -49583,6 +50426,7 @@ export {
|
|
|
49583
50426
|
braintrustStreamChunkSchema,
|
|
49584
50427
|
buildLocalSummary,
|
|
49585
50428
|
collectAnthropicSession,
|
|
50429
|
+
completeOpenAIBatchTrace,
|
|
49586
50430
|
configureInstrumentation,
|
|
49587
50431
|
constructLogs3OverflowRequest,
|
|
49588
50432
|
createFinalValuePassThroughStream,
|
|
@@ -49622,6 +50466,8 @@ export {
|
|
|
49622
50466
|
loginToState,
|
|
49623
50467
|
logs3OverflowUploadSchema,
|
|
49624
50468
|
newId,
|
|
50469
|
+
openaiBatchesRetrieveTraced,
|
|
50470
|
+
openaiFilesCreateTraced,
|
|
49625
50471
|
parseCachedHeader,
|
|
49626
50472
|
parseTemplateFormat,
|
|
49627
50473
|
permalink,
|