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.js
CHANGED
|
@@ -104,6 +104,7 @@ __export(browser_exports, {
|
|
|
104
104
|
braintrustStreamChunkSchema: () => braintrustStreamChunkSchema,
|
|
105
105
|
buildLocalSummary: () => buildLocalSummary,
|
|
106
106
|
collectAnthropicSession: () => collectAnthropicSession,
|
|
107
|
+
completeOpenAIBatchTrace: () => completeOpenAIBatchTrace,
|
|
107
108
|
configureInstrumentation: () => configureInstrumentation,
|
|
108
109
|
constructLogs3OverflowRequest: () => constructLogs3OverflowRequest,
|
|
109
110
|
createFinalValuePassThroughStream: () => createFinalValuePassThroughStream,
|
|
@@ -143,6 +144,8 @@ __export(browser_exports, {
|
|
|
143
144
|
loginToState: () => loginToState,
|
|
144
145
|
logs3OverflowUploadSchema: () => logs3OverflowUploadSchema,
|
|
145
146
|
newId: () => newId,
|
|
147
|
+
openaiBatchesRetrieveTraced: () => openaiBatchesRetrieveTraced,
|
|
148
|
+
openaiFilesCreateTraced: () => openaiFilesCreateTraced,
|
|
146
149
|
parseCachedHeader: () => parseCachedHeader,
|
|
147
150
|
parseTemplateFormat: () => parseTemplateFormat,
|
|
148
151
|
permalink: () => permalink,
|
|
@@ -5880,7 +5883,7 @@ var INSTRUMENTATION_NAMES = {
|
|
|
5880
5883
|
var INTERNAL_SPAN_INSTRUMENTATION_NAME = /* @__PURE__ */ Symbol.for(
|
|
5881
5884
|
"braintrust.spanInstrumentationName"
|
|
5882
5885
|
);
|
|
5883
|
-
var SDK_VERSION = true ? "3.
|
|
5886
|
+
var SDK_VERSION = true ? "3.30.0" : "0.0.0";
|
|
5884
5887
|
function withSpanInstrumentationName(args, instrumentationName) {
|
|
5885
5888
|
return {
|
|
5886
5889
|
...args,
|
|
@@ -10127,6 +10130,15 @@ function _internalStartSpanWithInitialMerge(args) {
|
|
|
10127
10130
|
[INITIAL_SPAN_WRITE_AS_MERGE]: true
|
|
10128
10131
|
}).span;
|
|
10129
10132
|
}
|
|
10133
|
+
function _internalStartSpanWithInitialMergeAndParentSpanIds(args) {
|
|
10134
|
+
return startSpanAndIsLogger(
|
|
10135
|
+
{
|
|
10136
|
+
...args,
|
|
10137
|
+
[INITIAL_SPAN_WRITE_AS_MERGE]: true
|
|
10138
|
+
},
|
|
10139
|
+
{ useParentSpanIdsForObjectParent: true }
|
|
10140
|
+
).span;
|
|
10141
|
+
}
|
|
10130
10142
|
function _internalStartSpanWithContext(args, context) {
|
|
10131
10143
|
return startSpanAndIsLogger({
|
|
10132
10144
|
...args,
|
|
@@ -10140,7 +10152,7 @@ async function flush(options) {
|
|
|
10140
10152
|
function setFetch(fetch2) {
|
|
10141
10153
|
_internalGetGlobalState().setFetch(fetch2);
|
|
10142
10154
|
}
|
|
10143
|
-
function startSpanAndIsLogger(args) {
|
|
10155
|
+
function startSpanAndIsLogger(args, internalOptions) {
|
|
10144
10156
|
const state = args?.state ?? _globalState;
|
|
10145
10157
|
const { parentObject, propagatedState } = getSpanParentObjectAndPropagatedState({
|
|
10146
10158
|
asyncFlush: args?.asyncFlush,
|
|
@@ -10154,7 +10166,7 @@ function startSpanAndIsLogger(args) {
|
|
|
10154
10166
|
) ? {
|
|
10155
10167
|
spanId: parentObject.data.span_id,
|
|
10156
10168
|
rootSpanId: parentObject.data.root_span_id
|
|
10157
|
-
} : void 0;
|
|
10169
|
+
} : internalOptions?.useParentSpanIdsForObjectParent ? args?.parentSpanIds : void 0;
|
|
10158
10170
|
const { parent: _ignoredParent, ...spanArgs } = args ?? {};
|
|
10159
10171
|
const span = new SpanImpl({
|
|
10160
10172
|
state,
|
|
@@ -13598,6 +13610,131 @@ function unsubscribeAll(unsubscribers) {
|
|
|
13598
13610
|
return [];
|
|
13599
13611
|
}
|
|
13600
13612
|
|
|
13613
|
+
// src/instrumentation/core/channel-definitions.ts
|
|
13614
|
+
function channel(spec) {
|
|
13615
|
+
return spec;
|
|
13616
|
+
}
|
|
13617
|
+
function defineChannels(pkg, channels, options) {
|
|
13618
|
+
const { instrumentationName } = options;
|
|
13619
|
+
return Object.fromEntries(
|
|
13620
|
+
Object.entries(channels).map(([key, spec]) => {
|
|
13621
|
+
const fullChannelName = `orchestrion:${pkg}:${spec.channelName}`;
|
|
13622
|
+
if (spec.kind === "async") {
|
|
13623
|
+
const asyncSpec = spec;
|
|
13624
|
+
const tracingChannel2 = () => isomorph_default.newTracingChannel(
|
|
13625
|
+
fullChannelName
|
|
13626
|
+
);
|
|
13627
|
+
const intercept2 = (interceptor) => {
|
|
13628
|
+
const hook = tracingChannel2();
|
|
13629
|
+
return typeof hook.intercept === "function" ? hook.intercept(interceptor) : () => {
|
|
13630
|
+
};
|
|
13631
|
+
};
|
|
13632
|
+
return [
|
|
13633
|
+
key,
|
|
13634
|
+
{
|
|
13635
|
+
...asyncSpec,
|
|
13636
|
+
instrumentationName,
|
|
13637
|
+
intercept: intercept2,
|
|
13638
|
+
invoke: (target, thisArg, args, additional) => {
|
|
13639
|
+
const hook = tracingChannel2();
|
|
13640
|
+
return typeof hook.invoke === "function" ? hook.invoke(target, thisArg, args, additional) : Reflect.apply(target, thisArg, args);
|
|
13641
|
+
},
|
|
13642
|
+
tracingChannel: tracingChannel2,
|
|
13643
|
+
tracePromise: (fn, context) => tracingChannel2().tracePromise(
|
|
13644
|
+
fn,
|
|
13645
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
13646
|
+
context
|
|
13647
|
+
)
|
|
13648
|
+
}
|
|
13649
|
+
];
|
|
13650
|
+
}
|
|
13651
|
+
const syncSpec = spec;
|
|
13652
|
+
const tracingChannel = () => isomorph_default.newTracingChannel(
|
|
13653
|
+
fullChannelName
|
|
13654
|
+
);
|
|
13655
|
+
const intercept = (interceptor) => {
|
|
13656
|
+
const hook = tracingChannel();
|
|
13657
|
+
return typeof hook.intercept === "function" ? hook.intercept(interceptor) : () => {
|
|
13658
|
+
};
|
|
13659
|
+
};
|
|
13660
|
+
return [
|
|
13661
|
+
key,
|
|
13662
|
+
{
|
|
13663
|
+
...syncSpec,
|
|
13664
|
+
instrumentationName,
|
|
13665
|
+
intercept,
|
|
13666
|
+
invoke: (target, thisArg, args, additional) => {
|
|
13667
|
+
const hook = tracingChannel();
|
|
13668
|
+
return typeof hook.invoke === "function" ? hook.invoke(target, thisArg, args, additional) : Reflect.apply(target, thisArg, args);
|
|
13669
|
+
},
|
|
13670
|
+
tracingChannel,
|
|
13671
|
+
traceSync: (fn, context) => tracingChannel().traceSync(
|
|
13672
|
+
fn,
|
|
13673
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
13674
|
+
context
|
|
13675
|
+
)
|
|
13676
|
+
}
|
|
13677
|
+
];
|
|
13678
|
+
})
|
|
13679
|
+
);
|
|
13680
|
+
}
|
|
13681
|
+
|
|
13682
|
+
// src/instrumentation/plugins/openai-channels.ts
|
|
13683
|
+
var openAIChannels = defineChannels(
|
|
13684
|
+
"openai",
|
|
13685
|
+
{
|
|
13686
|
+
filesCreateTraced: channel({
|
|
13687
|
+
channelName: "files.create-traced",
|
|
13688
|
+
kind: "async"
|
|
13689
|
+
}),
|
|
13690
|
+
batchesRetrieveTraced: channel({
|
|
13691
|
+
channelName: "batches.retrieve-traced",
|
|
13692
|
+
kind: "async"
|
|
13693
|
+
}),
|
|
13694
|
+
batchesCompleteTrace: channel({
|
|
13695
|
+
channelName: "batches.complete-trace",
|
|
13696
|
+
kind: "async"
|
|
13697
|
+
}),
|
|
13698
|
+
chatCompletionsCreate: channel({
|
|
13699
|
+
channelName: "chat.completions.create",
|
|
13700
|
+
kind: "async"
|
|
13701
|
+
}),
|
|
13702
|
+
embeddingsCreate: channel({
|
|
13703
|
+
channelName: "embeddings.create",
|
|
13704
|
+
kind: "async"
|
|
13705
|
+
}),
|
|
13706
|
+
betaChatCompletionsParse: channel({
|
|
13707
|
+
channelName: "beta.chat.completions.parse",
|
|
13708
|
+
kind: "async"
|
|
13709
|
+
}),
|
|
13710
|
+
betaChatCompletionsStream: channel({
|
|
13711
|
+
channelName: "beta.chat.completions.stream",
|
|
13712
|
+
kind: "sync-stream"
|
|
13713
|
+
}),
|
|
13714
|
+
moderationsCreate: channel({
|
|
13715
|
+
channelName: "moderations.create",
|
|
13716
|
+
kind: "async"
|
|
13717
|
+
}),
|
|
13718
|
+
responsesCreate: channel({
|
|
13719
|
+
channelName: "responses.create",
|
|
13720
|
+
kind: "async"
|
|
13721
|
+
}),
|
|
13722
|
+
responsesStream: channel({
|
|
13723
|
+
channelName: "responses.stream",
|
|
13724
|
+
kind: "sync-stream"
|
|
13725
|
+
}),
|
|
13726
|
+
responsesParse: channel({
|
|
13727
|
+
channelName: "responses.parse",
|
|
13728
|
+
kind: "async"
|
|
13729
|
+
}),
|
|
13730
|
+
responsesCompact: channel({
|
|
13731
|
+
channelName: "responses.compact",
|
|
13732
|
+
kind: "async"
|
|
13733
|
+
})
|
|
13734
|
+
},
|
|
13735
|
+
{ instrumentationName: INSTRUMENTATION_NAMES.OPENAI }
|
|
13736
|
+
);
|
|
13737
|
+
|
|
13601
13738
|
// src/wrappers/attachment-utils.ts
|
|
13602
13739
|
function getExtensionFromMediaType(mediaType) {
|
|
13603
13740
|
const extensionMap = {
|
|
@@ -13773,118 +13910,91 @@ function processInputAttachments(input) {
|
|
|
13773
13910
|
return processNode(input);
|
|
13774
13911
|
}
|
|
13775
13912
|
|
|
13776
|
-
// src/instrumentation/
|
|
13777
|
-
|
|
13778
|
-
|
|
13779
|
-
|
|
13780
|
-
|
|
13781
|
-
|
|
13782
|
-
|
|
13783
|
-
|
|
13784
|
-
|
|
13785
|
-
|
|
13786
|
-
|
|
13787
|
-
|
|
13788
|
-
|
|
13789
|
-
|
|
13790
|
-
|
|
13791
|
-
|
|
13792
|
-
|
|
13793
|
-
|
|
13794
|
-
|
|
13795
|
-
|
|
13796
|
-
|
|
13797
|
-
|
|
13798
|
-
...asyncSpec,
|
|
13799
|
-
instrumentationName,
|
|
13800
|
-
intercept: intercept2,
|
|
13801
|
-
invoke: (target, thisArg, args, additional) => {
|
|
13802
|
-
const hook = tracingChannel2();
|
|
13803
|
-
return typeof hook.invoke === "function" ? hook.invoke(target, thisArg, args, additional) : Reflect.apply(target, thisArg, args);
|
|
13804
|
-
},
|
|
13805
|
-
tracingChannel: tracingChannel2,
|
|
13806
|
-
tracePromise: (fn, context) => tracingChannel2().tracePromise(
|
|
13807
|
-
fn,
|
|
13808
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
13809
|
-
context
|
|
13810
|
-
)
|
|
13811
|
-
}
|
|
13812
|
-
];
|
|
13913
|
+
// src/instrumentation/plugins/openai-span-data.ts
|
|
13914
|
+
var OPENAI_METADATA_KEYS = [
|
|
13915
|
+
"model",
|
|
13916
|
+
"temperature",
|
|
13917
|
+
"top_p",
|
|
13918
|
+
"max_tokens",
|
|
13919
|
+
"frequency_penalty",
|
|
13920
|
+
"presence_penalty",
|
|
13921
|
+
"stop",
|
|
13922
|
+
"response_format",
|
|
13923
|
+
"tools",
|
|
13924
|
+
"tool_choice",
|
|
13925
|
+
"parallel_tool_calls",
|
|
13926
|
+
"max_tool_calls"
|
|
13927
|
+
];
|
|
13928
|
+
function batchMetadata(params) {
|
|
13929
|
+
const metadata = { provider: "openai" };
|
|
13930
|
+
for (const key of OPENAI_METADATA_KEYS) {
|
|
13931
|
+
try {
|
|
13932
|
+
const value = Reflect.get(params, key);
|
|
13933
|
+
if (value !== void 0) {
|
|
13934
|
+
metadata[key] = value;
|
|
13813
13935
|
}
|
|
13814
|
-
|
|
13815
|
-
|
|
13816
|
-
|
|
13817
|
-
|
|
13818
|
-
|
|
13819
|
-
|
|
13820
|
-
|
|
13821
|
-
|
|
13822
|
-
|
|
13823
|
-
|
|
13824
|
-
|
|
13825
|
-
|
|
13826
|
-
|
|
13827
|
-
|
|
13828
|
-
|
|
13829
|
-
|
|
13830
|
-
|
|
13831
|
-
|
|
13832
|
-
|
|
13833
|
-
|
|
13834
|
-
|
|
13835
|
-
|
|
13836
|
-
|
|
13837
|
-
|
|
13838
|
-
|
|
13839
|
-
|
|
13840
|
-
|
|
13841
|
-
|
|
13842
|
-
|
|
13936
|
+
} catch {
|
|
13937
|
+
}
|
|
13938
|
+
}
|
|
13939
|
+
return metadata;
|
|
13940
|
+
}
|
|
13941
|
+
function extractOpenAIBatchInput(endpoint, params) {
|
|
13942
|
+
const input = endpoint === "/v1/chat/completions" ? params.messages : params.input;
|
|
13943
|
+
return {
|
|
13944
|
+
input: processInputAttachments(input),
|
|
13945
|
+
metadata: batchMetadata(params)
|
|
13946
|
+
};
|
|
13947
|
+
}
|
|
13948
|
+
function extractOpenAIChatInput(params) {
|
|
13949
|
+
const { messages, ...metadata } = params;
|
|
13950
|
+
return {
|
|
13951
|
+
input: processInputAttachments(messages),
|
|
13952
|
+
metadata: { ...metadata, provider: "openai" }
|
|
13953
|
+
};
|
|
13954
|
+
}
|
|
13955
|
+
function extractOpenAIResponsesInput(params) {
|
|
13956
|
+
const { input, ...metadata } = params;
|
|
13957
|
+
return {
|
|
13958
|
+
input: processInputAttachments(input),
|
|
13959
|
+
metadata: { ...metadata, provider: "openai" }
|
|
13960
|
+
};
|
|
13961
|
+
}
|
|
13962
|
+
function extractOpenAIResponsesMetadata(result) {
|
|
13963
|
+
if (!result) {
|
|
13964
|
+
return void 0;
|
|
13965
|
+
}
|
|
13966
|
+
const { output: _output, usage: _usage, ...metadata } = result;
|
|
13967
|
+
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
13968
|
+
}
|
|
13969
|
+
function processImagesInOutput(output) {
|
|
13970
|
+
if (Array.isArray(output)) {
|
|
13971
|
+
return output.map(processImagesInOutput);
|
|
13972
|
+
}
|
|
13973
|
+
if (isObject(output) && output.type === "image_generation_call" && typeof output.result === "string" && output.result) {
|
|
13974
|
+
const fileExtension = output.output_format || "png";
|
|
13975
|
+
const contentType = `image/${fileExtension}`;
|
|
13976
|
+
const baseFilename = typeof output.revised_prompt === "string" ? output.revised_prompt.slice(0, 50).replace(/[^a-zA-Z0-9]/g, "_") : "generated_image";
|
|
13977
|
+
let binaryString;
|
|
13978
|
+
try {
|
|
13979
|
+
binaryString = atob(output.result);
|
|
13980
|
+
} catch {
|
|
13981
|
+
return output;
|
|
13982
|
+
}
|
|
13983
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
13984
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
13985
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
13986
|
+
}
|
|
13987
|
+
return {
|
|
13988
|
+
...output,
|
|
13989
|
+
result: new Attachment({
|
|
13990
|
+
data: new Blob([bytes], { type: contentType }),
|
|
13991
|
+
filename: `${baseFilename}.${fileExtension}`,
|
|
13992
|
+
contentType
|
|
13993
|
+
})
|
|
13994
|
+
};
|
|
13995
|
+
}
|
|
13996
|
+
return output;
|
|
13843
13997
|
}
|
|
13844
|
-
|
|
13845
|
-
// src/instrumentation/plugins/openai-channels.ts
|
|
13846
|
-
var openAIChannels = defineChannels(
|
|
13847
|
-
"openai",
|
|
13848
|
-
{
|
|
13849
|
-
chatCompletionsCreate: channel({
|
|
13850
|
-
channelName: "chat.completions.create",
|
|
13851
|
-
kind: "async"
|
|
13852
|
-
}),
|
|
13853
|
-
embeddingsCreate: channel({
|
|
13854
|
-
channelName: "embeddings.create",
|
|
13855
|
-
kind: "async"
|
|
13856
|
-
}),
|
|
13857
|
-
betaChatCompletionsParse: channel({
|
|
13858
|
-
channelName: "beta.chat.completions.parse",
|
|
13859
|
-
kind: "async"
|
|
13860
|
-
}),
|
|
13861
|
-
betaChatCompletionsStream: channel({
|
|
13862
|
-
channelName: "beta.chat.completions.stream",
|
|
13863
|
-
kind: "sync-stream"
|
|
13864
|
-
}),
|
|
13865
|
-
moderationsCreate: channel({
|
|
13866
|
-
channelName: "moderations.create",
|
|
13867
|
-
kind: "async"
|
|
13868
|
-
}),
|
|
13869
|
-
responsesCreate: channel({
|
|
13870
|
-
channelName: "responses.create",
|
|
13871
|
-
kind: "async"
|
|
13872
|
-
}),
|
|
13873
|
-
responsesStream: channel({
|
|
13874
|
-
channelName: "responses.stream",
|
|
13875
|
-
kind: "sync-stream"
|
|
13876
|
-
}),
|
|
13877
|
-
responsesParse: channel({
|
|
13878
|
-
channelName: "responses.parse",
|
|
13879
|
-
kind: "async"
|
|
13880
|
-
}),
|
|
13881
|
-
responsesCompact: channel({
|
|
13882
|
-
channelName: "responses.compact",
|
|
13883
|
-
kind: "async"
|
|
13884
|
-
})
|
|
13885
|
-
},
|
|
13886
|
-
{ instrumentationName: INSTRUMENTATION_NAMES.OPENAI }
|
|
13887
|
-
);
|
|
13888
13998
|
|
|
13889
13999
|
// src/openai-utils.ts
|
|
13890
14000
|
var BRAINTRUST_CACHED_STREAM_METRIC = "__braintrust_cached_metric";
|
|
@@ -13941,23 +14051,573 @@ function getCachedMetricFromHeaders(headers) {
|
|
|
13941
14051
|
return parseCachedHeader(headers.get(LEGACY_CACHED_HEADER));
|
|
13942
14052
|
}
|
|
13943
14053
|
|
|
14054
|
+
// src/instrumentation/plugins/openai-batch-instrumentation.ts
|
|
14055
|
+
var SUPPORTED_ENDPOINTS = /* @__PURE__ */ new Set(["/v1/chat/completions", "/v1/responses"]);
|
|
14056
|
+
var TERMINAL_STATUSES = /* @__PURE__ */ new Set([
|
|
14057
|
+
"completed",
|
|
14058
|
+
"failed",
|
|
14059
|
+
"expired",
|
|
14060
|
+
"cancelled"
|
|
14061
|
+
]);
|
|
14062
|
+
var pendingBatchTraces = /* @__PURE__ */ new Map();
|
|
14063
|
+
function read(value, key) {
|
|
14064
|
+
if (!isObject(value)) {
|
|
14065
|
+
return void 0;
|
|
14066
|
+
}
|
|
14067
|
+
try {
|
|
14068
|
+
return Reflect.get(value, key);
|
|
14069
|
+
} catch {
|
|
14070
|
+
return void 0;
|
|
14071
|
+
}
|
|
14072
|
+
}
|
|
14073
|
+
function isBatchRecordIterable(value) {
|
|
14074
|
+
if (value === null || typeof value !== "object" && typeof value !== "function") {
|
|
14075
|
+
return false;
|
|
14076
|
+
}
|
|
14077
|
+
return typeof read(value, Symbol.iterator) === "function" || typeof read(value, Symbol.asyncIterator) === "function";
|
|
14078
|
+
}
|
|
14079
|
+
function validCustomId(value) {
|
|
14080
|
+
return typeof value === "string" && value.length > 0 && value.length <= 64;
|
|
14081
|
+
}
|
|
14082
|
+
function logBatchInstrumentationError(context, error) {
|
|
14083
|
+
debugLogger.debug(`OpenAI Batch instrumentation ${context}:`, error);
|
|
14084
|
+
}
|
|
14085
|
+
async function exportParent(parent) {
|
|
14086
|
+
if ("toStr" in parent && typeof parent.toStr === "function") {
|
|
14087
|
+
return parent.toStr();
|
|
14088
|
+
}
|
|
14089
|
+
if ("export" in parent && typeof parent.export === "function") {
|
|
14090
|
+
return await parent.export();
|
|
14091
|
+
}
|
|
14092
|
+
return void 0;
|
|
14093
|
+
}
|
|
14094
|
+
async function deterministicDigest(namespace, ...parts) {
|
|
14095
|
+
const encoded = new TextEncoder().encode(
|
|
14096
|
+
[namespace, ...parts].map((part) => `${part.length}:${part}`).join("\0")
|
|
14097
|
+
);
|
|
14098
|
+
return new Uint8Array(
|
|
14099
|
+
await globalThis.crypto.subtle.digest("SHA-256", encoded)
|
|
14100
|
+
);
|
|
14101
|
+
}
|
|
14102
|
+
function digestHex(bytes, length) {
|
|
14103
|
+
return Array.from(bytes.slice(0, length)).map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
14104
|
+
}
|
|
14105
|
+
function digestUuid(bytes) {
|
|
14106
|
+
const hex = digestHex(bytes, 16);
|
|
14107
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
14108
|
+
}
|
|
14109
|
+
async function batchSpanIds(inputFileId) {
|
|
14110
|
+
const [row, span, root] = await Promise.all([
|
|
14111
|
+
deterministicDigest("openai:batch:row", inputFileId),
|
|
14112
|
+
deterministicDigest("openai:batch:span", inputFileId),
|
|
14113
|
+
deterministicDigest("openai:batch:root", inputFileId)
|
|
14114
|
+
]);
|
|
14115
|
+
return {
|
|
14116
|
+
rowId: digestUuid(row),
|
|
14117
|
+
spanId: digestHex(span, 8),
|
|
14118
|
+
rootSpanId: digestHex(root, 16)
|
|
14119
|
+
};
|
|
14120
|
+
}
|
|
14121
|
+
async function childSpanIds(inputFileId, customId) {
|
|
14122
|
+
const [row, span] = await Promise.all([
|
|
14123
|
+
deterministicDigest("openai:batch:child:row", inputFileId, customId),
|
|
14124
|
+
deterministicDigest("openai:batch:child:span", inputFileId, customId)
|
|
14125
|
+
]);
|
|
14126
|
+
return { rowId: digestUuid(row), spanId: digestHex(span, 8) };
|
|
14127
|
+
}
|
|
14128
|
+
async function startBatchSpan(context) {
|
|
14129
|
+
const ids = await batchSpanIds(context.inputFileId);
|
|
14130
|
+
const parent = SpanComponentsV4.fromStr(context.parent);
|
|
14131
|
+
const hasParentSpan = Boolean(
|
|
14132
|
+
parent.data.row_id && parent.data.span_id && parent.data.root_span_id
|
|
14133
|
+
);
|
|
14134
|
+
return withCurrent(
|
|
14135
|
+
NOOP_SPAN,
|
|
14136
|
+
() => _internalStartSpanWithInitialMergeAndParentSpanIds(
|
|
14137
|
+
withSpanInstrumentationName(
|
|
14138
|
+
{
|
|
14139
|
+
name: "openai.batch",
|
|
14140
|
+
type: "task" /* TASK */,
|
|
14141
|
+
parent: context.parent,
|
|
14142
|
+
...!hasParentSpan ? {
|
|
14143
|
+
parentSpanIds: {
|
|
14144
|
+
parentSpanIds: [],
|
|
14145
|
+
rootSpanId: ids.rootSpanId
|
|
14146
|
+
}
|
|
14147
|
+
} : {},
|
|
14148
|
+
spanId: ids.spanId,
|
|
14149
|
+
startTime: context.taskStartTime,
|
|
14150
|
+
event: {
|
|
14151
|
+
id: ids.rowId,
|
|
14152
|
+
metadata: {
|
|
14153
|
+
endpoint: context.endpoint,
|
|
14154
|
+
input_file_id: context.inputFileId,
|
|
14155
|
+
provider: "openai"
|
|
14156
|
+
}
|
|
14157
|
+
}
|
|
14158
|
+
},
|
|
14159
|
+
INSTRUMENTATION_NAMES.OPENAI
|
|
14160
|
+
)
|
|
14161
|
+
)
|
|
14162
|
+
);
|
|
14163
|
+
}
|
|
14164
|
+
async function startBatchChild(context, taskParent, input) {
|
|
14165
|
+
const ids = await childSpanIds(context.inputFileId, input.customId);
|
|
14166
|
+
return withCurrent(
|
|
14167
|
+
NOOP_SPAN,
|
|
14168
|
+
() => _internalStartSpanWithInitialMerge(
|
|
14169
|
+
withSpanInstrumentationName(
|
|
14170
|
+
{
|
|
14171
|
+
name: context.endpoint === "/v1/chat/completions" ? "Chat Completion" : "openai.responses.create",
|
|
14172
|
+
type: "llm" /* LLM */,
|
|
14173
|
+
parent: taskParent,
|
|
14174
|
+
spanId: ids.spanId,
|
|
14175
|
+
startTime: context.childStartTime,
|
|
14176
|
+
event: {
|
|
14177
|
+
id: ids.rowId,
|
|
14178
|
+
...input.spanData?.input !== void 0 ? { input: input.spanData.input } : {},
|
|
14179
|
+
metadata: {
|
|
14180
|
+
...input.spanData?.metadata,
|
|
14181
|
+
custom_id: input.customId,
|
|
14182
|
+
provider: "openai"
|
|
14183
|
+
}
|
|
14184
|
+
}
|
|
14185
|
+
},
|
|
14186
|
+
INSTRUMENTATION_NAMES.OPENAI
|
|
14187
|
+
)
|
|
14188
|
+
)
|
|
14189
|
+
);
|
|
14190
|
+
}
|
|
14191
|
+
async function* jsonlRecords(file, onIssue = () => {
|
|
14192
|
+
}) {
|
|
14193
|
+
const resolvedFile = await file;
|
|
14194
|
+
if (typeof resolvedFile === "string") {
|
|
14195
|
+
for (const line of resolvedFile.split("\n")) {
|
|
14196
|
+
if (!line.trim()) {
|
|
14197
|
+
continue;
|
|
14198
|
+
}
|
|
14199
|
+
try {
|
|
14200
|
+
yield JSON.parse(line.replace(/\r$/, ""));
|
|
14201
|
+
} catch (error) {
|
|
14202
|
+
logBatchInstrumentationError("skipped malformed JSONL", error);
|
|
14203
|
+
onIssue(new Error("OpenAI Batch file contains malformed JSONL"));
|
|
14204
|
+
}
|
|
14205
|
+
}
|
|
14206
|
+
return;
|
|
14207
|
+
}
|
|
14208
|
+
const body = read(resolvedFile, "body");
|
|
14209
|
+
const getReader = read(body, "getReader");
|
|
14210
|
+
if (isObject(body) && typeof getReader === "function") {
|
|
14211
|
+
let reader;
|
|
14212
|
+
try {
|
|
14213
|
+
reader = Reflect.apply(getReader, body, []);
|
|
14214
|
+
const decoder2 = new TextDecoder();
|
|
14215
|
+
let pending = "";
|
|
14216
|
+
while (true) {
|
|
14217
|
+
const readChunk = read(reader, "read");
|
|
14218
|
+
if (typeof readChunk !== "function") {
|
|
14219
|
+
throw new Error("Response body stream has no read method");
|
|
14220
|
+
}
|
|
14221
|
+
const chunk = await Reflect.apply(readChunk, reader, []);
|
|
14222
|
+
if (!isObject(chunk)) {
|
|
14223
|
+
throw new Error("Response body stream returned an invalid chunk");
|
|
14224
|
+
}
|
|
14225
|
+
if (chunk.done === true) {
|
|
14226
|
+
pending += decoder2.decode();
|
|
14227
|
+
break;
|
|
14228
|
+
}
|
|
14229
|
+
if (!(chunk.value instanceof Uint8Array)) {
|
|
14230
|
+
throw new Error("Response body stream returned a non-byte chunk");
|
|
14231
|
+
}
|
|
14232
|
+
pending += decoder2.decode(chunk.value, { stream: true });
|
|
14233
|
+
let newline = pending.indexOf("\n");
|
|
14234
|
+
while (newline !== -1) {
|
|
14235
|
+
const line = pending.slice(0, newline).replace(/\r$/, "");
|
|
14236
|
+
pending = pending.slice(newline + 1);
|
|
14237
|
+
if (line.trim()) {
|
|
14238
|
+
try {
|
|
14239
|
+
yield JSON.parse(line);
|
|
14240
|
+
} catch (error) {
|
|
14241
|
+
logBatchInstrumentationError("skipped malformed JSONL", error);
|
|
14242
|
+
onIssue(new Error("OpenAI Batch file contains malformed JSONL"));
|
|
14243
|
+
}
|
|
14244
|
+
}
|
|
14245
|
+
newline = pending.indexOf("\n");
|
|
14246
|
+
}
|
|
14247
|
+
}
|
|
14248
|
+
if (pending.trim()) {
|
|
14249
|
+
try {
|
|
14250
|
+
yield JSON.parse(pending.replace(/\r$/, ""));
|
|
14251
|
+
} catch (error) {
|
|
14252
|
+
logBatchInstrumentationError("skipped malformed JSONL", error);
|
|
14253
|
+
onIssue(new Error("OpenAI Batch file contains malformed JSONL"));
|
|
14254
|
+
}
|
|
14255
|
+
}
|
|
14256
|
+
} catch (error) {
|
|
14257
|
+
logBatchInstrumentationError("could not read JSONL response body", error);
|
|
14258
|
+
onIssue(new Error("OpenAI Batch response body could not be read"));
|
|
14259
|
+
} finally {
|
|
14260
|
+
const releaseLock = read(reader, "releaseLock");
|
|
14261
|
+
if (typeof releaseLock === "function") {
|
|
14262
|
+
try {
|
|
14263
|
+
Reflect.apply(releaseLock, reader, []);
|
|
14264
|
+
} catch (error) {
|
|
14265
|
+
logBatchInstrumentationError(
|
|
14266
|
+
"could not release stream reader",
|
|
14267
|
+
error
|
|
14268
|
+
);
|
|
14269
|
+
}
|
|
14270
|
+
}
|
|
14271
|
+
}
|
|
14272
|
+
return;
|
|
14273
|
+
}
|
|
14274
|
+
if (isBatchRecordIterable(resolvedFile)) {
|
|
14275
|
+
for await (const record of resolvedFile) {
|
|
14276
|
+
yield record;
|
|
14277
|
+
}
|
|
14278
|
+
return;
|
|
14279
|
+
}
|
|
14280
|
+
logBatchInstrumentationError("skipped invalid JSONL source", resolvedFile);
|
|
14281
|
+
onIssue(new Error("OpenAI Batch file source is invalid"));
|
|
14282
|
+
}
|
|
14283
|
+
async function readBatchInputs(file) {
|
|
14284
|
+
const inputs = /* @__PURE__ */ new Map();
|
|
14285
|
+
const issues = [];
|
|
14286
|
+
let endpoint;
|
|
14287
|
+
try {
|
|
14288
|
+
for await (const value of jsonlRecords(
|
|
14289
|
+
file,
|
|
14290
|
+
(issue) => issues.push(issue)
|
|
14291
|
+
)) {
|
|
14292
|
+
const customId = read(value, "custom_id");
|
|
14293
|
+
const url = read(value, "url");
|
|
14294
|
+
const body = read(value, "body");
|
|
14295
|
+
if (!validCustomId(customId) || inputs.has(customId) || read(value, "method") !== "POST" || typeof url !== "string" || !SUPPORTED_ENDPOINTS.has(url) || endpoint !== void 0 && endpoint !== url || !isObject(body)) {
|
|
14296
|
+
issues.push(new Error("OpenAI Batch input contains an invalid record"));
|
|
14297
|
+
continue;
|
|
14298
|
+
}
|
|
14299
|
+
endpoint = url;
|
|
14300
|
+
let spanData;
|
|
14301
|
+
try {
|
|
14302
|
+
spanData = extractOpenAIBatchInput(url, body);
|
|
14303
|
+
} catch (error) {
|
|
14304
|
+
logBatchInstrumentationError("could not extract batch input", error);
|
|
14305
|
+
}
|
|
14306
|
+
inputs.set(customId, { customId, spanData });
|
|
14307
|
+
}
|
|
14308
|
+
} catch (error) {
|
|
14309
|
+
logBatchInstrumentationError("could not process input file", error);
|
|
14310
|
+
issues.push(new Error("OpenAI Batch input file could not be processed"));
|
|
14311
|
+
}
|
|
14312
|
+
if (!endpoint || inputs.size === 0) {
|
|
14313
|
+
issues.push(new Error("OpenAI Batch input contains no supported records"));
|
|
14314
|
+
}
|
|
14315
|
+
return { endpoint, inputs, issues };
|
|
14316
|
+
}
|
|
14317
|
+
async function writePendingSpans(trace, endTime) {
|
|
14318
|
+
const task = await startBatchSpan(trace.context);
|
|
14319
|
+
const taskParent = await task.export();
|
|
14320
|
+
for (const input of trace.inputs.values()) {
|
|
14321
|
+
try {
|
|
14322
|
+
const child = await startBatchChild(trace.context, taskParent, input);
|
|
14323
|
+
if (endTime !== void 0) {
|
|
14324
|
+
child.end({ endTime });
|
|
14325
|
+
}
|
|
14326
|
+
} catch (error) {
|
|
14327
|
+
logBatchInstrumentationError("could not write batch request span", error);
|
|
14328
|
+
}
|
|
14329
|
+
}
|
|
14330
|
+
if (endTime !== void 0) {
|
|
14331
|
+
if (trace.status && trace.status !== "completed") {
|
|
14332
|
+
task.log({ error: new Error(`OpenAI Batch ${trace.status}`) });
|
|
14333
|
+
}
|
|
14334
|
+
task.end({ endTime });
|
|
14335
|
+
}
|
|
14336
|
+
}
|
|
14337
|
+
var interceptOpenAIFilesCreateTraced = async (target, thisArg, args) => {
|
|
14338
|
+
const startTime = getCurrentUnixTimestamp();
|
|
14339
|
+
const inputPromise = readBatchInputs(args[0].inputFileContent);
|
|
14340
|
+
const parentPromise = exportParent(args[0].parent);
|
|
14341
|
+
const file = await Reflect.apply(target, thisArg, args);
|
|
14342
|
+
try {
|
|
14343
|
+
const inputFileId = read(file, "id");
|
|
14344
|
+
const [inputData, exportedParent2] = await Promise.all([
|
|
14345
|
+
inputPromise,
|
|
14346
|
+
parentPromise
|
|
14347
|
+
]);
|
|
14348
|
+
if (typeof inputFileId !== "string" || !exportedParent2 || !inputData.endpoint || inputData.issues.length > 0) {
|
|
14349
|
+
if (inputData.issues[0]) {
|
|
14350
|
+
logBatchInstrumentationError(
|
|
14351
|
+
"skipped invalid input file",
|
|
14352
|
+
inputData.issues[0]
|
|
14353
|
+
);
|
|
14354
|
+
}
|
|
14355
|
+
return file;
|
|
14356
|
+
}
|
|
14357
|
+
const trace = {
|
|
14358
|
+
context: {
|
|
14359
|
+
inputFileId,
|
|
14360
|
+
endpoint: inputData.endpoint,
|
|
14361
|
+
parent: exportedParent2,
|
|
14362
|
+
taskStartTime: startTime,
|
|
14363
|
+
childStartTime: startTime
|
|
14364
|
+
},
|
|
14365
|
+
inputs: inputData.inputs
|
|
14366
|
+
};
|
|
14367
|
+
pendingBatchTraces.set(inputFileId, trace);
|
|
14368
|
+
await writePendingSpans(trace);
|
|
14369
|
+
} catch (error) {
|
|
14370
|
+
logBatchInstrumentationError("could not start batch spans", error);
|
|
14371
|
+
}
|
|
14372
|
+
return file;
|
|
14373
|
+
};
|
|
14374
|
+
function validTimestamp(value) {
|
|
14375
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0;
|
|
14376
|
+
}
|
|
14377
|
+
function terminalEndTime(batch, startTime) {
|
|
14378
|
+
let timestamp;
|
|
14379
|
+
switch (batch.status) {
|
|
14380
|
+
case "completed":
|
|
14381
|
+
timestamp = batch.completed_at;
|
|
14382
|
+
break;
|
|
14383
|
+
case "failed":
|
|
14384
|
+
timestamp = batch.failed_at;
|
|
14385
|
+
break;
|
|
14386
|
+
case "expired":
|
|
14387
|
+
timestamp = batch.expired_at;
|
|
14388
|
+
break;
|
|
14389
|
+
default:
|
|
14390
|
+
timestamp = batch.cancelled_at;
|
|
14391
|
+
}
|
|
14392
|
+
return validTimestamp(timestamp) ? Math.max(timestamp, startTime) : Math.max(getCurrentUnixTimestamp(), startTime);
|
|
14393
|
+
}
|
|
14394
|
+
async function updateBatchTimestamps(batch) {
|
|
14395
|
+
const trace = pendingBatchTraces.get(batch.input_file_id);
|
|
14396
|
+
if (!trace || trace.context.endpoint !== batch.endpoint) {
|
|
14397
|
+
return;
|
|
14398
|
+
}
|
|
14399
|
+
if (validTimestamp(batch.created_at)) {
|
|
14400
|
+
trace.context.taskStartTime = batch.created_at;
|
|
14401
|
+
}
|
|
14402
|
+
trace.context.childStartTime = validTimestamp(batch.in_progress_at) ? Math.max(batch.in_progress_at, trace.context.taskStartTime) : trace.context.taskStartTime;
|
|
14403
|
+
trace.status = batch.status;
|
|
14404
|
+
if (TERMINAL_STATUSES.has(batch.status)) {
|
|
14405
|
+
trace.endTime = terminalEndTime(batch, trace.context.childStartTime);
|
|
14406
|
+
}
|
|
14407
|
+
await writePendingSpans(trace, trace.endTime);
|
|
14408
|
+
}
|
|
14409
|
+
var interceptOpenAIBatchesRetrieveTraced = (target, thisArg, args) => Promise.resolve(Reflect.apply(target, thisArg, args)).then(async (batch) => {
|
|
14410
|
+
try {
|
|
14411
|
+
await updateBatchTimestamps(batch);
|
|
14412
|
+
} catch (error) {
|
|
14413
|
+
logBatchInstrumentationError("could not update batch timestamps", error);
|
|
14414
|
+
}
|
|
14415
|
+
return batch;
|
|
14416
|
+
});
|
|
14417
|
+
function errorFromResult(result) {
|
|
14418
|
+
const error = read(result.value, "error");
|
|
14419
|
+
if (isObject(error)) {
|
|
14420
|
+
const message = read(error, "message");
|
|
14421
|
+
return new Error(
|
|
14422
|
+
typeof message === "string" ? message : "OpenAI Batch request failed"
|
|
14423
|
+
);
|
|
14424
|
+
}
|
|
14425
|
+
const response = read(result.value, "response");
|
|
14426
|
+
const statusCode = read(response, "status_code");
|
|
14427
|
+
if (result.source === "error" || typeof statusCode === "number" && (statusCode < 200 || statusCode >= 300)) {
|
|
14428
|
+
const message = read(read(read(response, "body"), "error"), "message");
|
|
14429
|
+
return new Error(
|
|
14430
|
+
typeof message === "string" ? message : "OpenAI Batch request failed"
|
|
14431
|
+
);
|
|
14432
|
+
}
|
|
14433
|
+
return void 0;
|
|
14434
|
+
}
|
|
14435
|
+
async function completeBatchResult(context, taskParent, endTime, input, result) {
|
|
14436
|
+
const child = await startBatchChild(context, taskParent, input);
|
|
14437
|
+
try {
|
|
14438
|
+
const resultError = errorFromResult(result);
|
|
14439
|
+
const responseBody = read(read(result.value, "response"), "body");
|
|
14440
|
+
if (resultError) {
|
|
14441
|
+
child.log({ error: resultError });
|
|
14442
|
+
} else if (isObject(responseBody)) {
|
|
14443
|
+
const model = read(responseBody, "model");
|
|
14444
|
+
child.log({
|
|
14445
|
+
output: context.endpoint === "/v1/chat/completions" ? read(responseBody, "choices") : processImagesInOutput(read(responseBody, "output")),
|
|
14446
|
+
...typeof model === "string" ? { metadata: { model } } : {},
|
|
14447
|
+
metrics: parseMetricsFromUsage(read(responseBody, "usage"))
|
|
14448
|
+
});
|
|
14449
|
+
} else {
|
|
14450
|
+
child.log({ error: new Error("OpenAI Batch response body is missing") });
|
|
14451
|
+
}
|
|
14452
|
+
} catch (error) {
|
|
14453
|
+
child.log({ error });
|
|
14454
|
+
} finally {
|
|
14455
|
+
child.end({ endTime });
|
|
14456
|
+
}
|
|
14457
|
+
}
|
|
14458
|
+
async function completeResultFile({
|
|
14459
|
+
context,
|
|
14460
|
+
endTime,
|
|
14461
|
+
file,
|
|
14462
|
+
inputs,
|
|
14463
|
+
issues,
|
|
14464
|
+
seen,
|
|
14465
|
+
source,
|
|
14466
|
+
taskParent
|
|
14467
|
+
}) {
|
|
14468
|
+
if (file === void 0) {
|
|
14469
|
+
return;
|
|
14470
|
+
}
|
|
14471
|
+
for await (const value of jsonlRecords(file, (issue) => issues.push(issue))) {
|
|
14472
|
+
const customId = read(value, "custom_id");
|
|
14473
|
+
if (!validCustomId(customId) || !isObject(value)) {
|
|
14474
|
+
issues.push(
|
|
14475
|
+
new Error("OpenAI Batch result is missing a valid custom_id")
|
|
14476
|
+
);
|
|
14477
|
+
continue;
|
|
14478
|
+
}
|
|
14479
|
+
if (seen.has(customId)) {
|
|
14480
|
+
issues.push(new Error("OpenAI Batch result contains a duplicate"));
|
|
14481
|
+
continue;
|
|
14482
|
+
}
|
|
14483
|
+
const input = inputs.get(customId);
|
|
14484
|
+
if (!input) {
|
|
14485
|
+
issues.push(
|
|
14486
|
+
new Error("OpenAI Batch result does not match an input record")
|
|
14487
|
+
);
|
|
14488
|
+
continue;
|
|
14489
|
+
}
|
|
14490
|
+
seen.add(customId);
|
|
14491
|
+
await completeBatchResult(context, taskParent, endTime, input, {
|
|
14492
|
+
value,
|
|
14493
|
+
source
|
|
14494
|
+
});
|
|
14495
|
+
}
|
|
14496
|
+
}
|
|
14497
|
+
function sameInputs(first, second) {
|
|
14498
|
+
return first.size === second.size && [...first.keys()].every((customId) => second.has(customId));
|
|
14499
|
+
}
|
|
14500
|
+
async function contextForCompletion(inputFileId, inputData) {
|
|
14501
|
+
if (!inputData.endpoint || inputData.issues.length > 0) {
|
|
14502
|
+
return void 0;
|
|
14503
|
+
}
|
|
14504
|
+
const existing = pendingBatchTraces.get(inputFileId);
|
|
14505
|
+
if (existing) {
|
|
14506
|
+
if (existing.context.endpoint !== inputData.endpoint || !sameInputs(existing.inputs, inputData.inputs)) {
|
|
14507
|
+
return void 0;
|
|
14508
|
+
}
|
|
14509
|
+
return { ...existing, inputs: inputData.inputs };
|
|
14510
|
+
}
|
|
14511
|
+
const parent = await exportParent(getSpanParentObject());
|
|
14512
|
+
if (!parent) {
|
|
14513
|
+
return void 0;
|
|
14514
|
+
}
|
|
14515
|
+
const startTime = getCurrentUnixTimestamp();
|
|
14516
|
+
return {
|
|
14517
|
+
context: {
|
|
14518
|
+
inputFileId,
|
|
14519
|
+
endpoint: inputData.endpoint,
|
|
14520
|
+
parent,
|
|
14521
|
+
taskStartTime: startTime,
|
|
14522
|
+
childStartTime: startTime
|
|
14523
|
+
},
|
|
14524
|
+
inputs: inputData.inputs
|
|
14525
|
+
};
|
|
14526
|
+
}
|
|
14527
|
+
async function completeBatch(args) {
|
|
14528
|
+
const inputData = await readBatchInputs(args.inputFileContent);
|
|
14529
|
+
const trace = await contextForCompletion(args.inputFileId, inputData);
|
|
14530
|
+
if (!trace) {
|
|
14531
|
+
logBatchInstrumentationError(
|
|
14532
|
+
"left batch spans pending",
|
|
14533
|
+
inputData.issues[0] ?? new Error("OpenAI Batch input does not match")
|
|
14534
|
+
);
|
|
14535
|
+
return;
|
|
14536
|
+
}
|
|
14537
|
+
const endTime = trace.endTime ?? getCurrentUnixTimestamp();
|
|
14538
|
+
const task = await startBatchSpan(trace.context);
|
|
14539
|
+
const taskParent = await task.export();
|
|
14540
|
+
const issues = [];
|
|
14541
|
+
const seen = /* @__PURE__ */ new Set();
|
|
14542
|
+
await Promise.all([
|
|
14543
|
+
completeResultFile({
|
|
14544
|
+
context: trace.context,
|
|
14545
|
+
endTime,
|
|
14546
|
+
file: args.outputFileContent,
|
|
14547
|
+
inputs: trace.inputs,
|
|
14548
|
+
issues,
|
|
14549
|
+
seen,
|
|
14550
|
+
source: "output",
|
|
14551
|
+
taskParent
|
|
14552
|
+
}),
|
|
14553
|
+
completeResultFile({
|
|
14554
|
+
context: trace.context,
|
|
14555
|
+
endTime,
|
|
14556
|
+
file: args.errorFileContent,
|
|
14557
|
+
inputs: trace.inputs,
|
|
14558
|
+
issues,
|
|
14559
|
+
seen,
|
|
14560
|
+
source: "error",
|
|
14561
|
+
taskParent
|
|
14562
|
+
})
|
|
14563
|
+
]);
|
|
14564
|
+
if (issues.length > 0) {
|
|
14565
|
+
logBatchInstrumentationError("left batch spans pending", issues[0]);
|
|
14566
|
+
return;
|
|
14567
|
+
}
|
|
14568
|
+
const missing = [...trace.inputs.values()].filter(
|
|
14569
|
+
({ customId }) => !seen.has(customId)
|
|
14570
|
+
);
|
|
14571
|
+
if (!trace.status || trace.status === "completed") {
|
|
14572
|
+
if (missing.length > 0) {
|
|
14573
|
+
logBatchInstrumentationError(
|
|
14574
|
+
"left batch spans pending",
|
|
14575
|
+
new Error("OpenAI Batch result files are incomplete")
|
|
14576
|
+
);
|
|
14577
|
+
return;
|
|
14578
|
+
}
|
|
14579
|
+
} else {
|
|
14580
|
+
for (const input of missing) {
|
|
14581
|
+
const child = await startBatchChild(trace.context, taskParent, input);
|
|
14582
|
+
child.log({ error: new Error(`OpenAI Batch ${trace.status}`) });
|
|
14583
|
+
child.end({ endTime });
|
|
14584
|
+
}
|
|
14585
|
+
task.log({ error: new Error(`OpenAI Batch ${trace.status}`) });
|
|
14586
|
+
}
|
|
14587
|
+
task.end({ endTime });
|
|
14588
|
+
pendingBatchTraces.delete(args.inputFileId);
|
|
14589
|
+
}
|
|
14590
|
+
var interceptOpenAIBatchTraceComplete = (target, thisArg, args) => Promise.resolve(Reflect.apply(target, thisArg, args)).then(async (result) => {
|
|
14591
|
+
try {
|
|
14592
|
+
await completeBatch(args[0]);
|
|
14593
|
+
} catch (error) {
|
|
14594
|
+
logBatchInstrumentationError("could not complete batch", error);
|
|
14595
|
+
}
|
|
14596
|
+
return result;
|
|
14597
|
+
});
|
|
14598
|
+
|
|
13944
14599
|
// src/instrumentation/plugins/openai-plugin.ts
|
|
13945
14600
|
var OpenAIPlugin = class extends BasePlugin {
|
|
13946
14601
|
constructor() {
|
|
13947
14602
|
super();
|
|
13948
14603
|
}
|
|
13949
14604
|
onEnable() {
|
|
14605
|
+
this.unsubscribers.push(
|
|
14606
|
+
openAIChannels.filesCreateTraced.intercept(
|
|
14607
|
+
interceptOpenAIFilesCreateTraced
|
|
14608
|
+
),
|
|
14609
|
+
openAIChannels.batchesRetrieveTraced.intercept(
|
|
14610
|
+
interceptOpenAIBatchesRetrieveTraced
|
|
14611
|
+
),
|
|
14612
|
+
openAIChannels.batchesCompleteTrace.intercept(
|
|
14613
|
+
interceptOpenAIBatchTraceComplete
|
|
14614
|
+
)
|
|
14615
|
+
);
|
|
13950
14616
|
this.unsubscribers.push(
|
|
13951
14617
|
traceStreamingChannel(openAIChannels.chatCompletionsCreate, {
|
|
13952
14618
|
name: "Chat Completion",
|
|
13953
14619
|
type: "llm" /* LLM */,
|
|
13954
|
-
extractInput: ([params]) =>
|
|
13955
|
-
const { messages, ...metadata } = params;
|
|
13956
|
-
return {
|
|
13957
|
-
input: processInputAttachments(messages),
|
|
13958
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13959
|
-
};
|
|
13960
|
-
},
|
|
14620
|
+
extractInput: ([params]) => extractOpenAIChatInput(params),
|
|
13961
14621
|
extractOutput: (result) => {
|
|
13962
14622
|
return result?.choices;
|
|
13963
14623
|
},
|
|
@@ -14003,13 +14663,7 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
14003
14663
|
traceStreamingChannel(openAIChannels.betaChatCompletionsParse, {
|
|
14004
14664
|
name: "Chat Completion",
|
|
14005
14665
|
type: "llm" /* LLM */,
|
|
14006
|
-
extractInput: ([params]) =>
|
|
14007
|
-
const { messages, ...metadata } = params;
|
|
14008
|
-
return {
|
|
14009
|
-
input: processInputAttachments(messages),
|
|
14010
|
-
metadata: { ...metadata, provider: "openai" }
|
|
14011
|
-
};
|
|
14012
|
-
},
|
|
14666
|
+
extractInput: ([params]) => extractOpenAIChatInput(params),
|
|
14013
14667
|
extractOutput: (result) => {
|
|
14014
14668
|
return result?.choices;
|
|
14015
14669
|
},
|
|
@@ -14031,13 +14685,7 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
14031
14685
|
traceSyncStreamChannel(openAIChannels.betaChatCompletionsStream, {
|
|
14032
14686
|
name: "Chat Completion",
|
|
14033
14687
|
type: "llm" /* LLM */,
|
|
14034
|
-
extractInput: ([params]) =>
|
|
14035
|
-
const { messages, ...metadata } = params;
|
|
14036
|
-
return {
|
|
14037
|
-
input: processInputAttachments(messages),
|
|
14038
|
-
metadata: { ...metadata, provider: "openai" }
|
|
14039
|
-
};
|
|
14040
|
-
}
|
|
14688
|
+
extractInput: ([params]) => extractOpenAIChatInput(params)
|
|
14041
14689
|
})
|
|
14042
14690
|
);
|
|
14043
14691
|
this.unsubscribers.push(
|
|
@@ -14067,23 +14715,11 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
14067
14715
|
traceStreamingChannel(openAIChannels.responsesCreate, {
|
|
14068
14716
|
name: "openai.responses.create",
|
|
14069
14717
|
type: "llm" /* LLM */,
|
|
14070
|
-
extractInput: ([params]) =>
|
|
14071
|
-
const { input, ...metadata } = params;
|
|
14072
|
-
return {
|
|
14073
|
-
input: processInputAttachments(input),
|
|
14074
|
-
metadata: { ...metadata, provider: "openai" }
|
|
14075
|
-
};
|
|
14076
|
-
},
|
|
14718
|
+
extractInput: ([params]) => extractOpenAIResponsesInput(params),
|
|
14077
14719
|
extractOutput: (result) => {
|
|
14078
14720
|
return processImagesInOutput(result?.output);
|
|
14079
14721
|
},
|
|
14080
|
-
extractMetadata: (result) =>
|
|
14081
|
-
if (!result) {
|
|
14082
|
-
return void 0;
|
|
14083
|
-
}
|
|
14084
|
-
const { output: _output, usage: _usage, ...metadata } = result;
|
|
14085
|
-
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
14086
|
-
},
|
|
14722
|
+
extractMetadata: (result) => extractOpenAIResponsesMetadata(result),
|
|
14087
14723
|
extractMetrics: (result, startTime, endEvent) => {
|
|
14088
14724
|
const metrics = withCachedMetric(
|
|
14089
14725
|
parseMetricsFromUsage(result?.usage),
|
|
@@ -14102,13 +14738,7 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
14102
14738
|
traceSyncStreamChannel(openAIChannels.responsesStream, {
|
|
14103
14739
|
name: "openai.responses.create",
|
|
14104
14740
|
type: "llm" /* LLM */,
|
|
14105
|
-
extractInput: ([params]) =>
|
|
14106
|
-
const { input, ...metadata } = params;
|
|
14107
|
-
return {
|
|
14108
|
-
input: processInputAttachments(input),
|
|
14109
|
-
metadata: { ...metadata, provider: "openai" }
|
|
14110
|
-
};
|
|
14111
|
-
},
|
|
14741
|
+
extractInput: ([params]) => extractOpenAIResponsesInput(params),
|
|
14112
14742
|
extractFromEvent: (event) => {
|
|
14113
14743
|
if (event.type !== "response.completed" || !event.response) {
|
|
14114
14744
|
return {};
|
|
@@ -14131,23 +14761,11 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
14131
14761
|
traceStreamingChannel(openAIChannels.responsesParse, {
|
|
14132
14762
|
name: "openai.responses.parse",
|
|
14133
14763
|
type: "llm" /* LLM */,
|
|
14134
|
-
extractInput: ([params]) =>
|
|
14135
|
-
const { input, ...metadata } = params;
|
|
14136
|
-
return {
|
|
14137
|
-
input: processInputAttachments(input),
|
|
14138
|
-
metadata: { ...metadata, provider: "openai" }
|
|
14139
|
-
};
|
|
14140
|
-
},
|
|
14764
|
+
extractInput: ([params]) => extractOpenAIResponsesInput(params),
|
|
14141
14765
|
extractOutput: (result) => {
|
|
14142
14766
|
return processImagesInOutput(result?.output);
|
|
14143
14767
|
},
|
|
14144
|
-
extractMetadata: (result) =>
|
|
14145
|
-
if (!result) {
|
|
14146
|
-
return void 0;
|
|
14147
|
-
}
|
|
14148
|
-
const { output: _output, usage: _usage, ...metadata } = result;
|
|
14149
|
-
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
14150
|
-
},
|
|
14768
|
+
extractMetadata: (result) => extractOpenAIResponsesMetadata(result),
|
|
14151
14769
|
extractMetrics: (result, startTime, endEvent) => {
|
|
14152
14770
|
const metrics = withCachedMetric(
|
|
14153
14771
|
parseMetricsFromUsage(result?.usage),
|
|
@@ -14166,23 +14784,11 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
14166
14784
|
traceAsyncChannel(openAIChannels.responsesCompact, {
|
|
14167
14785
|
name: "openai.responses.compact",
|
|
14168
14786
|
type: "llm" /* LLM */,
|
|
14169
|
-
extractInput: ([params]) =>
|
|
14170
|
-
const { input, ...metadata } = params;
|
|
14171
|
-
return {
|
|
14172
|
-
input: processInputAttachments(input),
|
|
14173
|
-
metadata: { ...metadata, provider: "openai" }
|
|
14174
|
-
};
|
|
14175
|
-
},
|
|
14787
|
+
extractInput: ([params]) => extractOpenAIResponsesInput(params),
|
|
14176
14788
|
extractOutput: (result) => {
|
|
14177
14789
|
return processImagesInOutput(result?.output);
|
|
14178
14790
|
},
|
|
14179
|
-
extractMetadata: (result) =>
|
|
14180
|
-
if (!result) {
|
|
14181
|
-
return void 0;
|
|
14182
|
-
}
|
|
14183
|
-
const { output: _output, usage: _usage, ...metadata } = result;
|
|
14184
|
-
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
14185
|
-
},
|
|
14791
|
+
extractMetadata: (result) => extractOpenAIResponsesMetadata(result),
|
|
14186
14792
|
extractMetrics: (result, startTime, endEvent) => {
|
|
14187
14793
|
const metrics = withCachedMetric(
|
|
14188
14794
|
parseMetricsFromUsage(result?.usage),
|
|
@@ -14238,35 +14844,6 @@ function withCachedMetric(metrics, result, endEvent) {
|
|
|
14238
14844
|
cached
|
|
14239
14845
|
};
|
|
14240
14846
|
}
|
|
14241
|
-
function processImagesInOutput(output) {
|
|
14242
|
-
if (Array.isArray(output)) {
|
|
14243
|
-
return output.map(processImagesInOutput);
|
|
14244
|
-
}
|
|
14245
|
-
if (isObject(output)) {
|
|
14246
|
-
if (output.type === "image_generation_call" && output.result && typeof output.result === "string") {
|
|
14247
|
-
const fileExtension = output.output_format || "png";
|
|
14248
|
-
const contentType = `image/${fileExtension}`;
|
|
14249
|
-
const baseFilename = output.revised_prompt && typeof output.revised_prompt === "string" ? output.revised_prompt.slice(0, 50).replace(/[^a-zA-Z0-9]/g, "_") : "generated_image";
|
|
14250
|
-
const filename = `${baseFilename}.${fileExtension}`;
|
|
14251
|
-
const binaryString = atob(output.result);
|
|
14252
|
-
const bytes = new Uint8Array(binaryString.length);
|
|
14253
|
-
for (let i = 0; i < binaryString.length; i++) {
|
|
14254
|
-
bytes[i] = binaryString.charCodeAt(i);
|
|
14255
|
-
}
|
|
14256
|
-
const blob = new Blob([bytes], { type: contentType });
|
|
14257
|
-
const attachment = new Attachment({
|
|
14258
|
-
data: blob,
|
|
14259
|
-
filename,
|
|
14260
|
-
contentType
|
|
14261
|
-
});
|
|
14262
|
-
return {
|
|
14263
|
-
...output,
|
|
14264
|
-
result: attachment
|
|
14265
|
-
};
|
|
14266
|
-
}
|
|
14267
|
-
}
|
|
14268
|
-
return output;
|
|
14269
|
-
}
|
|
14270
14847
|
function mergeLogprobTokens(existing, incoming) {
|
|
14271
14848
|
if (incoming === void 0) {
|
|
14272
14849
|
return existing;
|
|
@@ -34299,7 +34876,7 @@ function extractSession(event) {
|
|
|
34299
34876
|
return isObject(candidate) && typeof candidate.prompt === "function" ? candidate : void 0;
|
|
34300
34877
|
}
|
|
34301
34878
|
function isPiAgent(value) {
|
|
34302
|
-
return isObject(value) && typeof value.streamFn === "function" && typeof value.subscribe === "function";
|
|
34879
|
+
return isObject(value) && (typeof value.streamFunction === "function" || typeof value.streamFn === "function") && typeof value.subscribe === "function";
|
|
34303
34880
|
}
|
|
34304
34881
|
function promptContextStore() {
|
|
34305
34882
|
piPromptContextStore ??= isomorph_default.newAsyncLocalStorage();
|
|
@@ -34309,17 +34886,21 @@ function currentPiPromptState() {
|
|
|
34309
34886
|
return promptContextStore().getStore();
|
|
34310
34887
|
}
|
|
34311
34888
|
function installPiAgentInstrumentation(agent) {
|
|
34889
|
+
const property = typeof agent.streamFunction === "function" ? "streamFunction" : "streamFn";
|
|
34890
|
+
const streamFunction = agent[property];
|
|
34312
34891
|
const existing = piAgentPatchStates.get(agent);
|
|
34313
|
-
if (!existing ||
|
|
34892
|
+
if (streamFunction && (!existing || existing.property !== property || streamFunction !== existing.wrappedStreamFunction)) {
|
|
34314
34893
|
const patchState = {
|
|
34315
|
-
|
|
34316
|
-
|
|
34894
|
+
originalStreamFunction: streamFunction,
|
|
34895
|
+
property,
|
|
34896
|
+
wrappedStreamFunction: streamFunction
|
|
34317
34897
|
};
|
|
34318
|
-
patchState.
|
|
34898
|
+
patchState.wrappedStreamFunction = makeInstrumentedStreamFunction(
|
|
34319
34899
|
agent,
|
|
34320
|
-
patchState.
|
|
34900
|
+
patchState.originalStreamFunction,
|
|
34901
|
+
property
|
|
34321
34902
|
);
|
|
34322
|
-
agent
|
|
34903
|
+
agent[property] = patchState.wrappedStreamFunction;
|
|
34323
34904
|
piAgentPatchStates.set(agent, patchState);
|
|
34324
34905
|
}
|
|
34325
34906
|
if (piAgentEventSubscriptions.has(agent)) {
|
|
@@ -34344,15 +34925,21 @@ function installPiAgentInstrumentation(agent) {
|
|
|
34344
34925
|
logInstrumentationError4("Pi Coding Agent event subscription", error);
|
|
34345
34926
|
}
|
|
34346
34927
|
}
|
|
34347
|
-
function
|
|
34348
|
-
return async function
|
|
34349
|
-
const invokeOriginal = () => Reflect.apply(
|
|
34928
|
+
function makeInstrumentedStreamFunction(agent, originalStreamFunction, property) {
|
|
34929
|
+
return async function instrumentedPiStreamFunction(model, context, options) {
|
|
34930
|
+
const invokeOriginal = () => Reflect.apply(originalStreamFunction, this, [model, context, options]);
|
|
34350
34931
|
const state = currentPiPromptState();
|
|
34351
34932
|
if (!state || state.agent !== agent || state.finalized) {
|
|
34352
34933
|
return invokeOriginal();
|
|
34353
34934
|
}
|
|
34354
34935
|
wrapPiToolExecutors(context.tools);
|
|
34355
|
-
const llmState = await startPiLlmSpan(
|
|
34936
|
+
const llmState = await startPiLlmSpan(
|
|
34937
|
+
state,
|
|
34938
|
+
model,
|
|
34939
|
+
context,
|
|
34940
|
+
property,
|
|
34941
|
+
options
|
|
34942
|
+
);
|
|
34356
34943
|
try {
|
|
34357
34944
|
const stream = await runWithAutoInstrumentationSuppressed(invokeOriginal);
|
|
34358
34945
|
return patchAssistantMessageStream(stream, state, llmState);
|
|
@@ -34389,12 +34976,12 @@ function wrapPiToolExecutors(tools) {
|
|
|
34389
34976
|
}
|
|
34390
34977
|
}
|
|
34391
34978
|
}
|
|
34392
|
-
async function startPiLlmSpan(state, model, context, options) {
|
|
34979
|
+
async function startPiLlmSpan(state, model, context, property, options) {
|
|
34393
34980
|
const metadata = {
|
|
34394
34981
|
...extractModelMetadata2(model),
|
|
34395
34982
|
...extractStreamOptionsMetadata(options),
|
|
34396
34983
|
...extractToolMetadata(context.tools),
|
|
34397
|
-
"pi_coding_agent.operation":
|
|
34984
|
+
"pi_coding_agent.operation": `agent.${property}`
|
|
34398
34985
|
};
|
|
34399
34986
|
const span = startSpan(
|
|
34400
34987
|
withSpanInstrumentationName(
|
|
@@ -37412,6 +37999,7 @@ __export(exports_exports, {
|
|
|
37412
37999
|
braintrustStreamChunkSchema: () => braintrustStreamChunkSchema,
|
|
37413
38000
|
buildLocalSummary: () => buildLocalSummary,
|
|
37414
38001
|
collectAnthropicSession: () => collectAnthropicSession,
|
|
38002
|
+
completeOpenAIBatchTrace: () => completeOpenAIBatchTrace,
|
|
37415
38003
|
configureInstrumentation: () => configureInstrumentation,
|
|
37416
38004
|
constructLogs3OverflowRequest: () => constructLogs3OverflowRequest,
|
|
37417
38005
|
createFinalValuePassThroughStream: () => createFinalValuePassThroughStream,
|
|
@@ -37450,6 +38038,8 @@ __export(exports_exports, {
|
|
|
37450
38038
|
loginToState: () => loginToState,
|
|
37451
38039
|
logs3OverflowUploadSchema: () => logs3OverflowUploadSchema,
|
|
37452
38040
|
newId: () => newId,
|
|
38041
|
+
openaiBatchesRetrieveTraced: () => openaiBatchesRetrieveTraced,
|
|
38042
|
+
openaiFilesCreateTraced: () => openaiFilesCreateTraced,
|
|
37453
38043
|
parseCachedHeader: () => parseCachedHeader,
|
|
37454
38044
|
parseTemplateFormat: () => parseTemplateFormat,
|
|
37455
38045
|
permalink: () => permalink,
|
|
@@ -37614,6 +38204,260 @@ async function registerSandbox(options) {
|
|
|
37614
38204
|
};
|
|
37615
38205
|
}
|
|
37616
38206
|
|
|
38207
|
+
// src/wrappers/openai-promise-utils.ts
|
|
38208
|
+
function splitSpanInfo(allParams) {
|
|
38209
|
+
const { span_info, ...params } = allParams;
|
|
38210
|
+
return {
|
|
38211
|
+
params,
|
|
38212
|
+
span_info
|
|
38213
|
+
};
|
|
38214
|
+
}
|
|
38215
|
+
function createChannelContext(_channel, params, span_info) {
|
|
38216
|
+
return {
|
|
38217
|
+
arguments: (
|
|
38218
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38219
|
+
[params]
|
|
38220
|
+
),
|
|
38221
|
+
span_info
|
|
38222
|
+
};
|
|
38223
|
+
}
|
|
38224
|
+
async function tracePromiseWithResponse(channel2, traceContext, apiPromise) {
|
|
38225
|
+
let enhancedResponse;
|
|
38226
|
+
const tracePromise = (
|
|
38227
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38228
|
+
channel2.tracePromise
|
|
38229
|
+
);
|
|
38230
|
+
const data = await tracePromise(async () => {
|
|
38231
|
+
enhancedResponse = await apiPromise.withResponse();
|
|
38232
|
+
traceContext.response = enhancedResponse.response;
|
|
38233
|
+
return enhancedResponse.data;
|
|
38234
|
+
}, traceContext);
|
|
38235
|
+
if (!enhancedResponse) {
|
|
38236
|
+
throw new Error("Expected withResponse() to provide response");
|
|
38237
|
+
}
|
|
38238
|
+
return {
|
|
38239
|
+
data,
|
|
38240
|
+
response: enhancedResponse.response,
|
|
38241
|
+
request_id: enhancedResponse.request_id
|
|
38242
|
+
};
|
|
38243
|
+
}
|
|
38244
|
+
async function tracePromiseAsResponse(channel2, traceContext, apiPromise) {
|
|
38245
|
+
const tracePromise = (
|
|
38246
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38247
|
+
channel2.tracePromise
|
|
38248
|
+
);
|
|
38249
|
+
let response;
|
|
38250
|
+
await tracePromise(async () => {
|
|
38251
|
+
response = await apiPromise.asResponse();
|
|
38252
|
+
traceContext.response = response;
|
|
38253
|
+
return void 0;
|
|
38254
|
+
}, traceContext);
|
|
38255
|
+
if (!response) {
|
|
38256
|
+
throw new Error("Expected asResponse() to provide response");
|
|
38257
|
+
}
|
|
38258
|
+
return response;
|
|
38259
|
+
}
|
|
38260
|
+
function createLazyAPIPromise(ensureExecuted, ensureResponse, getAPIPromise) {
|
|
38261
|
+
let firstConsumption;
|
|
38262
|
+
let enhancedResponsePromise;
|
|
38263
|
+
let dataPromise;
|
|
38264
|
+
let responsePromise;
|
|
38265
|
+
const withResponse = () => {
|
|
38266
|
+
firstConsumption ??= "data";
|
|
38267
|
+
enhancedResponsePromise ??= firstConsumption === "data" ? ensureExecuted() : getAPIPromise().withResponse();
|
|
38268
|
+
return enhancedResponsePromise;
|
|
38269
|
+
};
|
|
38270
|
+
const asResponse = () => {
|
|
38271
|
+
firstConsumption ??= "response";
|
|
38272
|
+
responsePromise ??= firstConsumption === "response" ? ensureResponse() : getAPIPromise().asResponse();
|
|
38273
|
+
return responsePromise;
|
|
38274
|
+
};
|
|
38275
|
+
return new Proxy({}, {
|
|
38276
|
+
get(target, prop, receiver) {
|
|
38277
|
+
if (prop === "withResponse") {
|
|
38278
|
+
return withResponse;
|
|
38279
|
+
}
|
|
38280
|
+
if (prop === "asResponse") {
|
|
38281
|
+
return asResponse;
|
|
38282
|
+
}
|
|
38283
|
+
if (prop === "then" || prop === "catch" || prop === "finally" || prop in Promise.prototype) {
|
|
38284
|
+
dataPromise ??= withResponse().then((result) => result.data);
|
|
38285
|
+
const value = Reflect.get(dataPromise, prop, receiver);
|
|
38286
|
+
return typeof value === "function" ? value.bind(dataPromise) : value;
|
|
38287
|
+
}
|
|
38288
|
+
return Reflect.get(target, prop, receiver);
|
|
38289
|
+
}
|
|
38290
|
+
});
|
|
38291
|
+
}
|
|
38292
|
+
|
|
38293
|
+
// src/openai-batch.ts
|
|
38294
|
+
function read2(value, key) {
|
|
38295
|
+
if (value === null || typeof value !== "object" && typeof value !== "function") {
|
|
38296
|
+
return void 0;
|
|
38297
|
+
}
|
|
38298
|
+
try {
|
|
38299
|
+
return Reflect.get(value, key);
|
|
38300
|
+
} catch {
|
|
38301
|
+
return void 0;
|
|
38302
|
+
}
|
|
38303
|
+
}
|
|
38304
|
+
function isAsyncIterable5(value) {
|
|
38305
|
+
return typeof read2(value, Symbol.asyncIterator) === "function";
|
|
38306
|
+
}
|
|
38307
|
+
function teeAsyncIterable(source) {
|
|
38308
|
+
const iterator = source[Symbol.asyncIterator]();
|
|
38309
|
+
const stream = new ReadableStream({
|
|
38310
|
+
async pull(controller) {
|
|
38311
|
+
try {
|
|
38312
|
+
const result = await iterator.next();
|
|
38313
|
+
if (result.done) {
|
|
38314
|
+
controller.close();
|
|
38315
|
+
return;
|
|
38316
|
+
}
|
|
38317
|
+
if (!(result.value instanceof Uint8Array)) {
|
|
38318
|
+
throw new TypeError(
|
|
38319
|
+
"OpenAI upload streams must yield Uint8Array chunks"
|
|
38320
|
+
);
|
|
38321
|
+
}
|
|
38322
|
+
controller.enqueue(result.value);
|
|
38323
|
+
} catch (error) {
|
|
38324
|
+
controller.error(error);
|
|
38325
|
+
}
|
|
38326
|
+
},
|
|
38327
|
+
async cancel(reason) {
|
|
38328
|
+
await iterator.return?.(reason);
|
|
38329
|
+
}
|
|
38330
|
+
});
|
|
38331
|
+
const [uploadStream, trace] = stream.tee();
|
|
38332
|
+
const upload = {
|
|
38333
|
+
async *[Symbol.asyncIterator]() {
|
|
38334
|
+
const reader = uploadStream.getReader();
|
|
38335
|
+
try {
|
|
38336
|
+
while (true) {
|
|
38337
|
+
const result = await reader.read();
|
|
38338
|
+
if (result.done) {
|
|
38339
|
+
return;
|
|
38340
|
+
}
|
|
38341
|
+
yield result.value;
|
|
38342
|
+
}
|
|
38343
|
+
} finally {
|
|
38344
|
+
reader.releaseLock();
|
|
38345
|
+
}
|
|
38346
|
+
}
|
|
38347
|
+
};
|
|
38348
|
+
const path = read2(source, "path");
|
|
38349
|
+
if (typeof path === "string") {
|
|
38350
|
+
Object.defineProperty(upload, "path", { value: path });
|
|
38351
|
+
}
|
|
38352
|
+
return { upload, trace: new Response(trace) };
|
|
38353
|
+
}
|
|
38354
|
+
function teeUpload(upload) {
|
|
38355
|
+
if (upload instanceof Blob) {
|
|
38356
|
+
return { upload, trace: new Response(upload) };
|
|
38357
|
+
}
|
|
38358
|
+
if (upload instanceof Response) {
|
|
38359
|
+
return { upload, trace: upload.clone() };
|
|
38360
|
+
}
|
|
38361
|
+
if (isAsyncIterable5(upload)) {
|
|
38362
|
+
return teeAsyncIterable(upload);
|
|
38363
|
+
}
|
|
38364
|
+
return void 0;
|
|
38365
|
+
}
|
|
38366
|
+
function openaiFilesCreateTraced(files) {
|
|
38367
|
+
return (params, options) => {
|
|
38368
|
+
const parent = getSpanParentObject();
|
|
38369
|
+
const purpose = read2(params, "purpose");
|
|
38370
|
+
const file = read2(params, "file");
|
|
38371
|
+
if (purpose !== "batch") {
|
|
38372
|
+
return files.create(params, options);
|
|
38373
|
+
}
|
|
38374
|
+
let branches;
|
|
38375
|
+
try {
|
|
38376
|
+
branches = teeUpload(file);
|
|
38377
|
+
} catch {
|
|
38378
|
+
return files.create(params, options);
|
|
38379
|
+
}
|
|
38380
|
+
if (!branches) {
|
|
38381
|
+
return files.create(params, options);
|
|
38382
|
+
}
|
|
38383
|
+
const tracedParams = {
|
|
38384
|
+
...Object(params),
|
|
38385
|
+
file: branches.upload
|
|
38386
|
+
};
|
|
38387
|
+
const apiPromise = files.create(tracedParams, options);
|
|
38388
|
+
let enhancedResponse;
|
|
38389
|
+
const tracedResponse = openAIChannels.filesCreateTraced.invoke(
|
|
38390
|
+
async () => {
|
|
38391
|
+
enhancedResponse = await apiPromise.withResponse();
|
|
38392
|
+
return enhancedResponse.data;
|
|
38393
|
+
},
|
|
38394
|
+
files,
|
|
38395
|
+
[{ params, inputFileContent: branches.trace, parent }],
|
|
38396
|
+
{}
|
|
38397
|
+
).then((data) => {
|
|
38398
|
+
if (!enhancedResponse) {
|
|
38399
|
+
throw new Error(
|
|
38400
|
+
"Expected OpenAI withResponse() to provide a response"
|
|
38401
|
+
);
|
|
38402
|
+
}
|
|
38403
|
+
return { ...enhancedResponse, data };
|
|
38404
|
+
});
|
|
38405
|
+
return createLazyAPIPromise(
|
|
38406
|
+
() => tracedResponse,
|
|
38407
|
+
() => tracedResponse.then(({ response }) => response),
|
|
38408
|
+
() => apiPromise
|
|
38409
|
+
);
|
|
38410
|
+
};
|
|
38411
|
+
}
|
|
38412
|
+
function openaiBatchesRetrieveTraced(batches) {
|
|
38413
|
+
return (batchId, options) => {
|
|
38414
|
+
const apiPromise = batches.retrieve(batchId, options);
|
|
38415
|
+
let enhancedResponse;
|
|
38416
|
+
const tracedResponse = openAIChannels.batchesRetrieveTraced.invoke(
|
|
38417
|
+
async () => {
|
|
38418
|
+
enhancedResponse = await apiPromise.withResponse();
|
|
38419
|
+
return enhancedResponse.data;
|
|
38420
|
+
},
|
|
38421
|
+
batches,
|
|
38422
|
+
[{ batchId }],
|
|
38423
|
+
{}
|
|
38424
|
+
).then((data) => {
|
|
38425
|
+
if (!enhancedResponse) {
|
|
38426
|
+
throw new Error(
|
|
38427
|
+
"Expected OpenAI withResponse() to provide a response"
|
|
38428
|
+
);
|
|
38429
|
+
}
|
|
38430
|
+
return { ...enhancedResponse, data };
|
|
38431
|
+
});
|
|
38432
|
+
return createLazyAPIPromise(
|
|
38433
|
+
() => tracedResponse,
|
|
38434
|
+
() => tracedResponse.then(({ response }) => response),
|
|
38435
|
+
() => apiPromise
|
|
38436
|
+
);
|
|
38437
|
+
};
|
|
38438
|
+
}
|
|
38439
|
+
async function completeOpenAIBatchTrace(args) {
|
|
38440
|
+
const inputFileContent = Promise.resolve(args.inputFileContent);
|
|
38441
|
+
const outputFileContent = args.outputFileContent === void 0 ? void 0 : Promise.resolve(args.outputFileContent);
|
|
38442
|
+
const errorFileContent = args.errorFileContent === void 0 ? void 0 : Promise.resolve(args.errorFileContent);
|
|
38443
|
+
void inputFileContent.catch(() => void 0);
|
|
38444
|
+
void outputFileContent?.catch(() => void 0);
|
|
38445
|
+
void errorFileContent?.catch(() => void 0);
|
|
38446
|
+
await openAIChannels.batchesCompleteTrace.invoke(
|
|
38447
|
+
async () => void 0,
|
|
38448
|
+
void 0,
|
|
38449
|
+
[
|
|
38450
|
+
{
|
|
38451
|
+
...args,
|
|
38452
|
+
inputFileContent,
|
|
38453
|
+
outputFileContent,
|
|
38454
|
+
errorFileContent
|
|
38455
|
+
}
|
|
38456
|
+
],
|
|
38457
|
+
{}
|
|
38458
|
+
);
|
|
38459
|
+
}
|
|
38460
|
+
|
|
37617
38461
|
// src/functions/invoke.ts
|
|
37618
38462
|
async function invoke(args) {
|
|
37619
38463
|
const {
|
|
@@ -37716,58 +38560,6 @@ function initFunction({
|
|
|
37716
38560
|
return f;
|
|
37717
38561
|
}
|
|
37718
38562
|
|
|
37719
|
-
// src/wrappers/openai-promise-utils.ts
|
|
37720
|
-
function splitSpanInfo(allParams) {
|
|
37721
|
-
const { span_info, ...params } = allParams;
|
|
37722
|
-
return {
|
|
37723
|
-
params,
|
|
37724
|
-
span_info
|
|
37725
|
-
};
|
|
37726
|
-
}
|
|
37727
|
-
function createChannelContext(_channel, params, span_info) {
|
|
37728
|
-
return {
|
|
37729
|
-
arguments: (
|
|
37730
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
37731
|
-
[params]
|
|
37732
|
-
),
|
|
37733
|
-
span_info
|
|
37734
|
-
};
|
|
37735
|
-
}
|
|
37736
|
-
async function tracePromiseWithResponse(channel2, traceContext, apiPromise) {
|
|
37737
|
-
let enhancedResponse;
|
|
37738
|
-
const tracePromise = (
|
|
37739
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
37740
|
-
channel2.tracePromise
|
|
37741
|
-
);
|
|
37742
|
-
const data = await tracePromise(async () => {
|
|
37743
|
-
enhancedResponse = await apiPromise.withResponse();
|
|
37744
|
-
traceContext.response = enhancedResponse.response;
|
|
37745
|
-
return enhancedResponse.data;
|
|
37746
|
-
}, traceContext);
|
|
37747
|
-
if (!enhancedResponse) {
|
|
37748
|
-
throw new Error("Expected withResponse() to provide response");
|
|
37749
|
-
}
|
|
37750
|
-
return { data, response: enhancedResponse.response };
|
|
37751
|
-
}
|
|
37752
|
-
function createLazyAPIPromise(ensureExecuted) {
|
|
37753
|
-
let dataPromise = null;
|
|
37754
|
-
return new Proxy({}, {
|
|
37755
|
-
get(target, prop, receiver) {
|
|
37756
|
-
if (prop === "withResponse") {
|
|
37757
|
-
return () => ensureExecuted();
|
|
37758
|
-
}
|
|
37759
|
-
if (prop === "then" || prop === "catch" || prop === "finally" || prop in Promise.prototype) {
|
|
37760
|
-
if (!dataPromise) {
|
|
37761
|
-
dataPromise = ensureExecuted().then((result) => result.data);
|
|
37762
|
-
}
|
|
37763
|
-
const value = Reflect.get(dataPromise, prop, receiver);
|
|
37764
|
-
return typeof value === "function" ? value.bind(dataPromise) : value;
|
|
37765
|
-
}
|
|
37766
|
-
return Reflect.get(target, prop, receiver);
|
|
37767
|
-
}
|
|
37768
|
-
});
|
|
37769
|
-
}
|
|
37770
|
-
|
|
37771
38563
|
// src/wrappers/oai_responses.ts
|
|
37772
38564
|
function responsesProxy(openai) {
|
|
37773
38565
|
if (!openai.responses) {
|
|
@@ -37804,17 +38596,33 @@ function wrapResponsesAsync(target, channel2) {
|
|
|
37804
38596
|
return (allParams, options) => {
|
|
37805
38597
|
const { span_info, params } = splitSpanInfo(allParams);
|
|
37806
38598
|
let executionPromise = null;
|
|
38599
|
+
let apiPromise = null;
|
|
38600
|
+
const getAPIPromise = () => {
|
|
38601
|
+
apiPromise ??= target(params, options);
|
|
38602
|
+
return apiPromise;
|
|
38603
|
+
};
|
|
37807
38604
|
const ensureExecuted = () => {
|
|
37808
38605
|
if (!executionPromise) {
|
|
37809
38606
|
executionPromise = (async () => {
|
|
37810
38607
|
const traceContext = createChannelContext(channel2, params, span_info);
|
|
37811
|
-
|
|
37812
|
-
|
|
38608
|
+
return tracePromiseWithResponse(
|
|
38609
|
+
channel2,
|
|
38610
|
+
traceContext,
|
|
38611
|
+
getAPIPromise()
|
|
38612
|
+
);
|
|
37813
38613
|
})();
|
|
37814
38614
|
}
|
|
37815
38615
|
return executionPromise;
|
|
37816
38616
|
};
|
|
37817
|
-
return createLazyAPIPromise(
|
|
38617
|
+
return createLazyAPIPromise(
|
|
38618
|
+
ensureExecuted,
|
|
38619
|
+
() => tracePromiseAsResponse(
|
|
38620
|
+
channel2,
|
|
38621
|
+
createChannelContext(channel2, params, span_info),
|
|
38622
|
+
getAPIPromise()
|
|
38623
|
+
),
|
|
38624
|
+
getAPIPromise
|
|
38625
|
+
);
|
|
37818
38626
|
};
|
|
37819
38627
|
}
|
|
37820
38628
|
function wrapResponsesSyncStream(target, channel2) {
|
|
@@ -37960,6 +38768,11 @@ function wrapChatCompletion(completion) {
|
|
|
37960
38768
|
allParams
|
|
37961
38769
|
);
|
|
37962
38770
|
let executionPromise = null;
|
|
38771
|
+
let apiPromise = null;
|
|
38772
|
+
const getAPIPromise = () => {
|
|
38773
|
+
apiPromise ??= completion(params, options);
|
|
38774
|
+
return apiPromise;
|
|
38775
|
+
};
|
|
37963
38776
|
const ensureExecuted = () => {
|
|
37964
38777
|
if (!executionPromise) {
|
|
37965
38778
|
executionPromise = (async () => {
|
|
@@ -37969,32 +38782,44 @@ function wrapChatCompletion(completion) {
|
|
|
37969
38782
|
span_info
|
|
37970
38783
|
);
|
|
37971
38784
|
if (params.stream) {
|
|
37972
|
-
const completionPromise =
|
|
37973
|
-
|
|
37974
|
-
|
|
38785
|
+
const completionPromise = (
|
|
38786
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38787
|
+
getAPIPromise()
|
|
37975
38788
|
);
|
|
37976
|
-
const { data: data2, response: response2 } = await tracePromiseWithResponse(
|
|
38789
|
+
const { data: data2, response: response2, request_id: request_id2 } = await tracePromiseWithResponse(
|
|
37977
38790
|
openAIChannels.chatCompletionsCreate,
|
|
37978
38791
|
traceContext,
|
|
37979
38792
|
completionPromise
|
|
37980
38793
|
);
|
|
37981
|
-
return { data: data2, response: response2 };
|
|
38794
|
+
return { data: data2, response: response2, request_id: request_id2 };
|
|
37982
38795
|
}
|
|
37983
|
-
const completionResponse =
|
|
37984
|
-
|
|
37985
|
-
|
|
38796
|
+
const completionResponse = (
|
|
38797
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38798
|
+
getAPIPromise()
|
|
37986
38799
|
);
|
|
37987
|
-
const { data, response } = await tracePromiseWithResponse(
|
|
38800
|
+
const { data, response, request_id } = await tracePromiseWithResponse(
|
|
37988
38801
|
openAIChannels.chatCompletionsCreate,
|
|
37989
38802
|
traceContext,
|
|
37990
38803
|
completionResponse
|
|
37991
38804
|
);
|
|
37992
|
-
return { data, response };
|
|
38805
|
+
return { data, response, request_id };
|
|
37993
38806
|
})();
|
|
37994
38807
|
}
|
|
37995
38808
|
return executionPromise;
|
|
37996
38809
|
};
|
|
37997
|
-
return createLazyAPIPromise(
|
|
38810
|
+
return createLazyAPIPromise(
|
|
38811
|
+
ensureExecuted,
|
|
38812
|
+
() => tracePromiseAsResponse(
|
|
38813
|
+
openAIChannels.chatCompletionsCreate,
|
|
38814
|
+
createChannelContext(
|
|
38815
|
+
openAIChannels.chatCompletionsCreate,
|
|
38816
|
+
params,
|
|
38817
|
+
span_info
|
|
38818
|
+
),
|
|
38819
|
+
getAPIPromise()
|
|
38820
|
+
),
|
|
38821
|
+
getAPIPromise
|
|
38822
|
+
);
|
|
37998
38823
|
};
|
|
37999
38824
|
}
|
|
38000
38825
|
function createEndpointProxy(target, wrapperFn) {
|
|
@@ -38012,6 +38837,11 @@ function wrapApiCreateWithChannel(create, channel2) {
|
|
|
38012
38837
|
return (allParams, options) => {
|
|
38013
38838
|
const { span_info, params } = splitSpanInfo(allParams);
|
|
38014
38839
|
let executionPromise = null;
|
|
38840
|
+
let apiPromise = null;
|
|
38841
|
+
const getAPIPromise = () => {
|
|
38842
|
+
apiPromise ??= create(params, options);
|
|
38843
|
+
return apiPromise;
|
|
38844
|
+
};
|
|
38015
38845
|
const ensureExecuted = () => {
|
|
38016
38846
|
if (!executionPromise) {
|
|
38017
38847
|
executionPromise = (async () => {
|
|
@@ -38019,13 +38849,21 @@ function wrapApiCreateWithChannel(create, channel2) {
|
|
|
38019
38849
|
return tracePromiseWithResponse(
|
|
38020
38850
|
channel2,
|
|
38021
38851
|
traceContext,
|
|
38022
|
-
|
|
38852
|
+
getAPIPromise()
|
|
38023
38853
|
);
|
|
38024
38854
|
})();
|
|
38025
38855
|
}
|
|
38026
38856
|
return executionPromise;
|
|
38027
38857
|
};
|
|
38028
|
-
return createLazyAPIPromise(
|
|
38858
|
+
return createLazyAPIPromise(
|
|
38859
|
+
ensureExecuted,
|
|
38860
|
+
() => tracePromiseAsResponse(
|
|
38861
|
+
channel2,
|
|
38862
|
+
createChannelContext(channel2, params, span_info),
|
|
38863
|
+
getAPIPromise()
|
|
38864
|
+
),
|
|
38865
|
+
getAPIPromise
|
|
38866
|
+
);
|
|
38029
38867
|
};
|
|
38030
38868
|
}
|
|
38031
38869
|
var wrapEmbeddings = (create) => wrapApiCreateWithChannel(create, openAIChannels.embeddingsCreate);
|
|
@@ -40720,7 +41558,15 @@ var MAX_EVE_PROVIDER_CACHE_ENTRIES = 1e4;
|
|
|
40720
41558
|
function createEveInstrumentationProvider(options = {}) {
|
|
40721
41559
|
const bridge = new EveProviderBridge(options.metadata);
|
|
40722
41560
|
return {
|
|
41561
|
+
// Eve versions before tracePolicy use capture to decide whether provider
|
|
41562
|
+
// events include content. Newer versions prefer tracePolicy when both are
|
|
41563
|
+
// present, so keep the deprecated field for backwards compatibility.
|
|
40723
41564
|
capture: "content",
|
|
41565
|
+
tracePolicy: () => ({
|
|
41566
|
+
emit: true,
|
|
41567
|
+
recordInputs: true,
|
|
41568
|
+
recordOutputs: true
|
|
41569
|
+
}),
|
|
40724
41570
|
events: {
|
|
40725
41571
|
"action.completed": (event, context) => bridge.handleActionTerminal(event, context),
|
|
40726
41572
|
"action.failed": (event, context) => bridge.handleActionTerminal(event, context),
|
|
@@ -45149,7 +45995,7 @@ function isAsync(fn) {
|
|
|
45149
45995
|
function isAsyncGenerator2(fn) {
|
|
45150
45996
|
return fn[Symbol.toStringTag] === "AsyncGenerator";
|
|
45151
45997
|
}
|
|
45152
|
-
function
|
|
45998
|
+
function isAsyncIterable6(obj) {
|
|
45153
45999
|
return typeof obj[Symbol.asyncIterator] === "function";
|
|
45154
46000
|
}
|
|
45155
46001
|
function wrapAsync(asyncFn) {
|
|
@@ -45321,7 +46167,7 @@ var eachOfLimit$2 = (limit) => {
|
|
|
45321
46167
|
if (isAsyncGenerator2(obj)) {
|
|
45322
46168
|
return asyncEachOfLimit(obj, limit, iteratee, callback);
|
|
45323
46169
|
}
|
|
45324
|
-
if (
|
|
46170
|
+
if (isAsyncIterable6(obj)) {
|
|
45325
46171
|
return asyncEachOfLimit(obj[Symbol.asyncIterator](), limit, iteratee, callback);
|
|
45326
46172
|
}
|
|
45327
46173
|
var nextElem = createIterator(obj);
|
|
@@ -46676,7 +47522,7 @@ function callEvaluatorData(data) {
|
|
|
46676
47522
|
baseExperiment
|
|
46677
47523
|
};
|
|
46678
47524
|
}
|
|
46679
|
-
function
|
|
47525
|
+
function isAsyncIterable7(value) {
|
|
46680
47526
|
return typeof value === "object" && value !== null && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
46681
47527
|
}
|
|
46682
47528
|
function isIterable(value) {
|
|
@@ -46711,7 +47557,7 @@ async function _internalResolveEvaluatorData(evaluator, experiment) {
|
|
|
46711
47557
|
}).asDataset();
|
|
46712
47558
|
}
|
|
46713
47559
|
const resolvedDataResult = dataResult instanceof Promise ? await dataResult : dataResult;
|
|
46714
|
-
if (
|
|
47560
|
+
if (isAsyncIterable7(resolvedDataResult)) {
|
|
46715
47561
|
return resolvedDataResult;
|
|
46716
47562
|
}
|
|
46717
47563
|
if (Array.isArray(resolvedDataResult) || isIterable(resolvedDataResult)) {
|