braintrust 3.29.0 → 3.31.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.d.mts +4 -1
- package/dev/dist/index.d.ts +4 -1
- package/dev/dist/index.js +1492 -887
- package/dev/dist/index.mjs +836 -231
- 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 +22 -4
- package/dist/auto-instrumentations/bundler/next.mjs +12 -6
- 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 +18 -4
- package/dist/auto-instrumentations/index.cjs +13 -1
- package/dist/auto-instrumentations/index.mjs +1 -1
- package/dist/browser.d.mts +614 -480
- package/dist/browser.d.ts +614 -480
- package/dist/browser.js +1172 -305
- package/dist/browser.mjs +1172 -305
- package/dist/{chunk-6Z5S7VOU.js → chunk-4AQGZS6X.js} +13 -1
- package/dist/{chunk-M6XPNJC4.mjs → chunk-AJT4FR25.mjs} +703 -120
- package/dist/{chunk-7FA6VP2S.mjs → chunk-CE3BLB2L.mjs} +13 -1
- package/dist/{chunk-XLLGRXGR.js → chunk-V32LW47Z.js} +1819 -1236
- package/dist/cli.js +846 -241
- package/dist/edge-light.d.mts +1 -1
- package/dist/edge-light.d.ts +1 -1
- package/dist/edge-light.js +1172 -305
- package/dist/edge-light.mjs +1172 -305
- package/dist/index.d.mts +614 -480
- package/dist/index.d.ts +614 -480
- package/dist/index.js +915 -643
- package/dist/index.mjs +349 -77
- package/dist/instrumentation/index.d.mts +15 -0
- package/dist/instrumentation/index.d.ts +15 -0
- package/dist/instrumentation/index.js +836 -230
- package/dist/instrumentation/index.mjs +836 -230
- 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 +1172 -305
- package/dist/workerd.mjs +1172 -305
- package/package.json +1 -1
package/dist/edge-light.mjs
CHANGED
|
@@ -3818,6 +3818,7 @@ var ProjectSettings = z6.union([
|
|
|
3818
3818
|
]),
|
|
3819
3819
|
disable_realtime_queries: z6.union([z6.boolean(), z6.null()]),
|
|
3820
3820
|
monitor_charts_use_metrics_start: z6.union([z6.boolean(), z6.null()]),
|
|
3821
|
+
blind_reviews: z6.union([z6.boolean(), z6.null()]),
|
|
3821
3822
|
default_preprocessor: NullableSavedFunctionId
|
|
3822
3823
|
}).partial(),
|
|
3823
3824
|
z6.null()
|
|
@@ -3879,6 +3880,7 @@ var WindowedAutomationConfig = z6.object({
|
|
|
3879
3880
|
auto_approve_tools: z6.array(z6.string().min(1)).optional().default([]),
|
|
3880
3881
|
harness: z6.enum(["native", "codex", "claude-code"]).optional(),
|
|
3881
3882
|
model: z6.string().min(1).optional(),
|
|
3883
|
+
endpoint_name: z6.string().min(1).optional(),
|
|
3882
3884
|
reasoning_effort: z6.enum(["none", "minimal", "low", "medium", "high", "xhigh", "max"]).optional()
|
|
3883
3885
|
}).optional(),
|
|
3884
3886
|
actions: z6.array(
|
|
@@ -5672,7 +5674,7 @@ var INSTRUMENTATION_NAMES = {
|
|
|
5672
5674
|
var INTERNAL_SPAN_INSTRUMENTATION_NAME = /* @__PURE__ */ Symbol.for(
|
|
5673
5675
|
"braintrust.spanInstrumentationName"
|
|
5674
5676
|
);
|
|
5675
|
-
var SDK_VERSION = true ? "3.
|
|
5677
|
+
var SDK_VERSION = true ? "3.31.0" : "0.0.0";
|
|
5676
5678
|
function withSpanInstrumentationName(args, instrumentationName) {
|
|
5677
5679
|
return {
|
|
5678
5680
|
...args,
|
|
@@ -9919,6 +9921,15 @@ function _internalStartSpanWithInitialMerge(args) {
|
|
|
9919
9921
|
[INITIAL_SPAN_WRITE_AS_MERGE]: true
|
|
9920
9922
|
}).span;
|
|
9921
9923
|
}
|
|
9924
|
+
function _internalStartSpanWithInitialMergeAndParentSpanIds(args) {
|
|
9925
|
+
return startSpanAndIsLogger(
|
|
9926
|
+
{
|
|
9927
|
+
...args,
|
|
9928
|
+
[INITIAL_SPAN_WRITE_AS_MERGE]: true
|
|
9929
|
+
},
|
|
9930
|
+
{ useParentSpanIdsForObjectParent: true }
|
|
9931
|
+
).span;
|
|
9932
|
+
}
|
|
9922
9933
|
function _internalStartSpanWithContext(args, context) {
|
|
9923
9934
|
return startSpanAndIsLogger({
|
|
9924
9935
|
...args,
|
|
@@ -9932,7 +9943,7 @@ async function flush(options) {
|
|
|
9932
9943
|
function setFetch(fetch2) {
|
|
9933
9944
|
_internalGetGlobalState().setFetch(fetch2);
|
|
9934
9945
|
}
|
|
9935
|
-
function startSpanAndIsLogger(args) {
|
|
9946
|
+
function startSpanAndIsLogger(args, internalOptions) {
|
|
9936
9947
|
const state = args?.state ?? _globalState;
|
|
9937
9948
|
const { parentObject, propagatedState } = getSpanParentObjectAndPropagatedState({
|
|
9938
9949
|
asyncFlush: args?.asyncFlush,
|
|
@@ -9946,7 +9957,7 @@ function startSpanAndIsLogger(args) {
|
|
|
9946
9957
|
) ? {
|
|
9947
9958
|
spanId: parentObject.data.span_id,
|
|
9948
9959
|
rootSpanId: parentObject.data.root_span_id
|
|
9949
|
-
} : void 0;
|
|
9960
|
+
} : internalOptions?.useParentSpanIdsForObjectParent ? args?.parentSpanIds : void 0;
|
|
9950
9961
|
const { parent: _ignoredParent, ...spanArgs } = args ?? {};
|
|
9951
9962
|
const span = new SpanImpl({
|
|
9952
9963
|
state,
|
|
@@ -13424,6 +13435,131 @@ function unsubscribeAll(unsubscribers) {
|
|
|
13424
13435
|
return [];
|
|
13425
13436
|
}
|
|
13426
13437
|
|
|
13438
|
+
// src/instrumentation/core/channel-definitions.ts
|
|
13439
|
+
function channel(spec) {
|
|
13440
|
+
return spec;
|
|
13441
|
+
}
|
|
13442
|
+
function defineChannels(pkg, channels, options) {
|
|
13443
|
+
const { instrumentationName } = options;
|
|
13444
|
+
return Object.fromEntries(
|
|
13445
|
+
Object.entries(channels).map(([key, spec]) => {
|
|
13446
|
+
const fullChannelName = `orchestrion:${pkg}:${spec.channelName}`;
|
|
13447
|
+
if (spec.kind === "async") {
|
|
13448
|
+
const asyncSpec = spec;
|
|
13449
|
+
const tracingChannel2 = () => isomorph_default.newTracingChannel(
|
|
13450
|
+
fullChannelName
|
|
13451
|
+
);
|
|
13452
|
+
const intercept2 = (interceptor) => {
|
|
13453
|
+
const hook = tracingChannel2();
|
|
13454
|
+
return typeof hook.intercept === "function" ? hook.intercept(interceptor) : () => {
|
|
13455
|
+
};
|
|
13456
|
+
};
|
|
13457
|
+
return [
|
|
13458
|
+
key,
|
|
13459
|
+
{
|
|
13460
|
+
...asyncSpec,
|
|
13461
|
+
instrumentationName,
|
|
13462
|
+
intercept: intercept2,
|
|
13463
|
+
invoke: (target, thisArg, args, additional) => {
|
|
13464
|
+
const hook = tracingChannel2();
|
|
13465
|
+
return typeof hook.invoke === "function" ? hook.invoke(target, thisArg, args, additional) : Reflect.apply(target, thisArg, args);
|
|
13466
|
+
},
|
|
13467
|
+
tracingChannel: tracingChannel2,
|
|
13468
|
+
tracePromise: (fn, context) => tracingChannel2().tracePromise(
|
|
13469
|
+
fn,
|
|
13470
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
13471
|
+
context
|
|
13472
|
+
)
|
|
13473
|
+
}
|
|
13474
|
+
];
|
|
13475
|
+
}
|
|
13476
|
+
const syncSpec = spec;
|
|
13477
|
+
const tracingChannel = () => isomorph_default.newTracingChannel(
|
|
13478
|
+
fullChannelName
|
|
13479
|
+
);
|
|
13480
|
+
const intercept = (interceptor) => {
|
|
13481
|
+
const hook = tracingChannel();
|
|
13482
|
+
return typeof hook.intercept === "function" ? hook.intercept(interceptor) : () => {
|
|
13483
|
+
};
|
|
13484
|
+
};
|
|
13485
|
+
return [
|
|
13486
|
+
key,
|
|
13487
|
+
{
|
|
13488
|
+
...syncSpec,
|
|
13489
|
+
instrumentationName,
|
|
13490
|
+
intercept,
|
|
13491
|
+
invoke: (target, thisArg, args, additional) => {
|
|
13492
|
+
const hook = tracingChannel();
|
|
13493
|
+
return typeof hook.invoke === "function" ? hook.invoke(target, thisArg, args, additional) : Reflect.apply(target, thisArg, args);
|
|
13494
|
+
},
|
|
13495
|
+
tracingChannel,
|
|
13496
|
+
traceSync: (fn, context) => tracingChannel().traceSync(
|
|
13497
|
+
fn,
|
|
13498
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
13499
|
+
context
|
|
13500
|
+
)
|
|
13501
|
+
}
|
|
13502
|
+
];
|
|
13503
|
+
})
|
|
13504
|
+
);
|
|
13505
|
+
}
|
|
13506
|
+
|
|
13507
|
+
// src/instrumentation/plugins/openai-channels.ts
|
|
13508
|
+
var openAIChannels = defineChannels(
|
|
13509
|
+
"openai",
|
|
13510
|
+
{
|
|
13511
|
+
filesCreateTraced: channel({
|
|
13512
|
+
channelName: "files.create-traced",
|
|
13513
|
+
kind: "async"
|
|
13514
|
+
}),
|
|
13515
|
+
batchesRetrieveTraced: channel({
|
|
13516
|
+
channelName: "batches.retrieve-traced",
|
|
13517
|
+
kind: "async"
|
|
13518
|
+
}),
|
|
13519
|
+
batchesCompleteTrace: channel({
|
|
13520
|
+
channelName: "batches.complete-trace",
|
|
13521
|
+
kind: "async"
|
|
13522
|
+
}),
|
|
13523
|
+
chatCompletionsCreate: channel({
|
|
13524
|
+
channelName: "chat.completions.create",
|
|
13525
|
+
kind: "async"
|
|
13526
|
+
}),
|
|
13527
|
+
embeddingsCreate: channel({
|
|
13528
|
+
channelName: "embeddings.create",
|
|
13529
|
+
kind: "async"
|
|
13530
|
+
}),
|
|
13531
|
+
betaChatCompletionsParse: channel({
|
|
13532
|
+
channelName: "beta.chat.completions.parse",
|
|
13533
|
+
kind: "async"
|
|
13534
|
+
}),
|
|
13535
|
+
betaChatCompletionsStream: channel({
|
|
13536
|
+
channelName: "beta.chat.completions.stream",
|
|
13537
|
+
kind: "sync-stream"
|
|
13538
|
+
}),
|
|
13539
|
+
moderationsCreate: channel({
|
|
13540
|
+
channelName: "moderations.create",
|
|
13541
|
+
kind: "async"
|
|
13542
|
+
}),
|
|
13543
|
+
responsesCreate: channel({
|
|
13544
|
+
channelName: "responses.create",
|
|
13545
|
+
kind: "async"
|
|
13546
|
+
}),
|
|
13547
|
+
responsesStream: channel({
|
|
13548
|
+
channelName: "responses.stream",
|
|
13549
|
+
kind: "sync-stream"
|
|
13550
|
+
}),
|
|
13551
|
+
responsesParse: channel({
|
|
13552
|
+
channelName: "responses.parse",
|
|
13553
|
+
kind: "async"
|
|
13554
|
+
}),
|
|
13555
|
+
responsesCompact: channel({
|
|
13556
|
+
channelName: "responses.compact",
|
|
13557
|
+
kind: "async"
|
|
13558
|
+
})
|
|
13559
|
+
},
|
|
13560
|
+
{ instrumentationName: INSTRUMENTATION_NAMES.OPENAI }
|
|
13561
|
+
);
|
|
13562
|
+
|
|
13427
13563
|
// src/wrappers/attachment-utils.ts
|
|
13428
13564
|
function getExtensionFromMediaType(mediaType) {
|
|
13429
13565
|
const extensionMap = {
|
|
@@ -13599,118 +13735,91 @@ function processInputAttachments(input) {
|
|
|
13599
13735
|
return processNode(input);
|
|
13600
13736
|
}
|
|
13601
13737
|
|
|
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
|
-
];
|
|
13738
|
+
// src/instrumentation/plugins/openai-span-data.ts
|
|
13739
|
+
var OPENAI_METADATA_KEYS = [
|
|
13740
|
+
"model",
|
|
13741
|
+
"temperature",
|
|
13742
|
+
"top_p",
|
|
13743
|
+
"max_tokens",
|
|
13744
|
+
"frequency_penalty",
|
|
13745
|
+
"presence_penalty",
|
|
13746
|
+
"stop",
|
|
13747
|
+
"response_format",
|
|
13748
|
+
"tools",
|
|
13749
|
+
"tool_choice",
|
|
13750
|
+
"parallel_tool_calls",
|
|
13751
|
+
"max_tool_calls"
|
|
13752
|
+
];
|
|
13753
|
+
function batchMetadata(params) {
|
|
13754
|
+
const metadata = { provider: "openai" };
|
|
13755
|
+
for (const key of OPENAI_METADATA_KEYS) {
|
|
13756
|
+
try {
|
|
13757
|
+
const value = Reflect.get(params, key);
|
|
13758
|
+
if (value !== void 0) {
|
|
13759
|
+
metadata[key] = value;
|
|
13639
13760
|
}
|
|
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
|
-
|
|
13761
|
+
} catch {
|
|
13762
|
+
}
|
|
13763
|
+
}
|
|
13764
|
+
return metadata;
|
|
13765
|
+
}
|
|
13766
|
+
function extractOpenAIBatchInput(endpoint, params) {
|
|
13767
|
+
const input = endpoint === "/v1/chat/completions" ? params.messages : params.input;
|
|
13768
|
+
return {
|
|
13769
|
+
input: processInputAttachments(input),
|
|
13770
|
+
metadata: batchMetadata(params)
|
|
13771
|
+
};
|
|
13772
|
+
}
|
|
13773
|
+
function extractOpenAIChatInput(params) {
|
|
13774
|
+
const { messages, ...metadata } = params;
|
|
13775
|
+
return {
|
|
13776
|
+
input: processInputAttachments(messages),
|
|
13777
|
+
metadata: { ...metadata, provider: "openai" }
|
|
13778
|
+
};
|
|
13779
|
+
}
|
|
13780
|
+
function extractOpenAIResponsesInput(params) {
|
|
13781
|
+
const { input, ...metadata } = params;
|
|
13782
|
+
return {
|
|
13783
|
+
input: processInputAttachments(input),
|
|
13784
|
+
metadata: { ...metadata, provider: "openai" }
|
|
13785
|
+
};
|
|
13786
|
+
}
|
|
13787
|
+
function extractOpenAIResponsesMetadata(result) {
|
|
13788
|
+
if (!result) {
|
|
13789
|
+
return void 0;
|
|
13790
|
+
}
|
|
13791
|
+
const { output: _output, usage: _usage, ...metadata } = result;
|
|
13792
|
+
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
13793
|
+
}
|
|
13794
|
+
function processImagesInOutput(output) {
|
|
13795
|
+
if (Array.isArray(output)) {
|
|
13796
|
+
return output.map(processImagesInOutput);
|
|
13797
|
+
}
|
|
13798
|
+
if (isObject(output) && output.type === "image_generation_call" && typeof output.result === "string" && output.result) {
|
|
13799
|
+
const fileExtension = output.output_format || "png";
|
|
13800
|
+
const contentType = `image/${fileExtension}`;
|
|
13801
|
+
const baseFilename = typeof output.revised_prompt === "string" ? output.revised_prompt.slice(0, 50).replace(/[^a-zA-Z0-9]/g, "_") : "generated_image";
|
|
13802
|
+
let binaryString;
|
|
13803
|
+
try {
|
|
13804
|
+
binaryString = atob(output.result);
|
|
13805
|
+
} catch {
|
|
13806
|
+
return output;
|
|
13807
|
+
}
|
|
13808
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
13809
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
13810
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
13811
|
+
}
|
|
13812
|
+
return {
|
|
13813
|
+
...output,
|
|
13814
|
+
result: new Attachment({
|
|
13815
|
+
data: new Blob([bytes], { type: contentType }),
|
|
13816
|
+
filename: `${baseFilename}.${fileExtension}`,
|
|
13817
|
+
contentType
|
|
13818
|
+
})
|
|
13819
|
+
};
|
|
13820
|
+
}
|
|
13821
|
+
return output;
|
|
13669
13822
|
}
|
|
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
13823
|
|
|
13715
13824
|
// src/openai-utils.ts
|
|
13716
13825
|
var BRAINTRUST_CACHED_STREAM_METRIC = "__braintrust_cached_metric";
|
|
@@ -13767,23 +13876,573 @@ function getCachedMetricFromHeaders(headers) {
|
|
|
13767
13876
|
return parseCachedHeader(headers.get(LEGACY_CACHED_HEADER));
|
|
13768
13877
|
}
|
|
13769
13878
|
|
|
13879
|
+
// src/instrumentation/plugins/openai-batch-instrumentation.ts
|
|
13880
|
+
var SUPPORTED_ENDPOINTS = /* @__PURE__ */ new Set(["/v1/chat/completions", "/v1/responses"]);
|
|
13881
|
+
var TERMINAL_STATUSES = /* @__PURE__ */ new Set([
|
|
13882
|
+
"completed",
|
|
13883
|
+
"failed",
|
|
13884
|
+
"expired",
|
|
13885
|
+
"cancelled"
|
|
13886
|
+
]);
|
|
13887
|
+
var pendingBatchTraces = /* @__PURE__ */ new Map();
|
|
13888
|
+
function read(value, key) {
|
|
13889
|
+
if (!isObject(value)) {
|
|
13890
|
+
return void 0;
|
|
13891
|
+
}
|
|
13892
|
+
try {
|
|
13893
|
+
return Reflect.get(value, key);
|
|
13894
|
+
} catch {
|
|
13895
|
+
return void 0;
|
|
13896
|
+
}
|
|
13897
|
+
}
|
|
13898
|
+
function isBatchRecordIterable(value) {
|
|
13899
|
+
if (value === null || typeof value !== "object" && typeof value !== "function") {
|
|
13900
|
+
return false;
|
|
13901
|
+
}
|
|
13902
|
+
return typeof read(value, Symbol.iterator) === "function" || typeof read(value, Symbol.asyncIterator) === "function";
|
|
13903
|
+
}
|
|
13904
|
+
function validCustomId(value) {
|
|
13905
|
+
return typeof value === "string" && value.length > 0 && value.length <= 64;
|
|
13906
|
+
}
|
|
13907
|
+
function logBatchInstrumentationError(context, error) {
|
|
13908
|
+
debugLogger.debug(`OpenAI Batch instrumentation ${context}:`, error);
|
|
13909
|
+
}
|
|
13910
|
+
async function exportParent(parent) {
|
|
13911
|
+
if ("toStr" in parent && typeof parent.toStr === "function") {
|
|
13912
|
+
return parent.toStr();
|
|
13913
|
+
}
|
|
13914
|
+
if ("export" in parent && typeof parent.export === "function") {
|
|
13915
|
+
return await parent.export();
|
|
13916
|
+
}
|
|
13917
|
+
return void 0;
|
|
13918
|
+
}
|
|
13919
|
+
async function deterministicDigest(namespace, ...parts) {
|
|
13920
|
+
const encoded = new TextEncoder().encode(
|
|
13921
|
+
[namespace, ...parts].map((part) => `${part.length}:${part}`).join("\0")
|
|
13922
|
+
);
|
|
13923
|
+
return new Uint8Array(
|
|
13924
|
+
await globalThis.crypto.subtle.digest("SHA-256", encoded)
|
|
13925
|
+
);
|
|
13926
|
+
}
|
|
13927
|
+
function digestHex(bytes, length) {
|
|
13928
|
+
return Array.from(bytes.slice(0, length)).map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
13929
|
+
}
|
|
13930
|
+
function digestUuid(bytes) {
|
|
13931
|
+
const hex = digestHex(bytes, 16);
|
|
13932
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
13933
|
+
}
|
|
13934
|
+
async function batchSpanIds(inputFileId) {
|
|
13935
|
+
const [row, span, root] = await Promise.all([
|
|
13936
|
+
deterministicDigest("openai:batch:row", inputFileId),
|
|
13937
|
+
deterministicDigest("openai:batch:span", inputFileId),
|
|
13938
|
+
deterministicDigest("openai:batch:root", inputFileId)
|
|
13939
|
+
]);
|
|
13940
|
+
return {
|
|
13941
|
+
rowId: digestUuid(row),
|
|
13942
|
+
spanId: digestHex(span, 8),
|
|
13943
|
+
rootSpanId: digestHex(root, 16)
|
|
13944
|
+
};
|
|
13945
|
+
}
|
|
13946
|
+
async function childSpanIds(inputFileId, customId) {
|
|
13947
|
+
const [row, span] = await Promise.all([
|
|
13948
|
+
deterministicDigest("openai:batch:child:row", inputFileId, customId),
|
|
13949
|
+
deterministicDigest("openai:batch:child:span", inputFileId, customId)
|
|
13950
|
+
]);
|
|
13951
|
+
return { rowId: digestUuid(row), spanId: digestHex(span, 8) };
|
|
13952
|
+
}
|
|
13953
|
+
async function startBatchSpan(context) {
|
|
13954
|
+
const ids = await batchSpanIds(context.inputFileId);
|
|
13955
|
+
const parent = SpanComponentsV4.fromStr(context.parent);
|
|
13956
|
+
const hasParentSpan = Boolean(
|
|
13957
|
+
parent.data.row_id && parent.data.span_id && parent.data.root_span_id
|
|
13958
|
+
);
|
|
13959
|
+
return withCurrent(
|
|
13960
|
+
NOOP_SPAN,
|
|
13961
|
+
() => _internalStartSpanWithInitialMergeAndParentSpanIds(
|
|
13962
|
+
withSpanInstrumentationName(
|
|
13963
|
+
{
|
|
13964
|
+
name: "openai.batch",
|
|
13965
|
+
type: "task" /* TASK */,
|
|
13966
|
+
parent: context.parent,
|
|
13967
|
+
...!hasParentSpan ? {
|
|
13968
|
+
parentSpanIds: {
|
|
13969
|
+
parentSpanIds: [],
|
|
13970
|
+
rootSpanId: ids.rootSpanId
|
|
13971
|
+
}
|
|
13972
|
+
} : {},
|
|
13973
|
+
spanId: ids.spanId,
|
|
13974
|
+
startTime: context.taskStartTime,
|
|
13975
|
+
event: {
|
|
13976
|
+
id: ids.rowId,
|
|
13977
|
+
metadata: {
|
|
13978
|
+
endpoint: context.endpoint,
|
|
13979
|
+
input_file_id: context.inputFileId,
|
|
13980
|
+
provider: "openai"
|
|
13981
|
+
}
|
|
13982
|
+
}
|
|
13983
|
+
},
|
|
13984
|
+
INSTRUMENTATION_NAMES.OPENAI
|
|
13985
|
+
)
|
|
13986
|
+
)
|
|
13987
|
+
);
|
|
13988
|
+
}
|
|
13989
|
+
async function startBatchChild(context, taskParent, input) {
|
|
13990
|
+
const ids = await childSpanIds(context.inputFileId, input.customId);
|
|
13991
|
+
return withCurrent(
|
|
13992
|
+
NOOP_SPAN,
|
|
13993
|
+
() => _internalStartSpanWithInitialMerge(
|
|
13994
|
+
withSpanInstrumentationName(
|
|
13995
|
+
{
|
|
13996
|
+
name: context.endpoint === "/v1/chat/completions" ? "Chat Completion" : "openai.responses.create",
|
|
13997
|
+
type: "llm" /* LLM */,
|
|
13998
|
+
parent: taskParent,
|
|
13999
|
+
spanId: ids.spanId,
|
|
14000
|
+
startTime: context.childStartTime,
|
|
14001
|
+
event: {
|
|
14002
|
+
id: ids.rowId,
|
|
14003
|
+
...input.spanData?.input !== void 0 ? { input: input.spanData.input } : {},
|
|
14004
|
+
metadata: {
|
|
14005
|
+
...input.spanData?.metadata,
|
|
14006
|
+
custom_id: input.customId,
|
|
14007
|
+
provider: "openai"
|
|
14008
|
+
}
|
|
14009
|
+
}
|
|
14010
|
+
},
|
|
14011
|
+
INSTRUMENTATION_NAMES.OPENAI
|
|
14012
|
+
)
|
|
14013
|
+
)
|
|
14014
|
+
);
|
|
14015
|
+
}
|
|
14016
|
+
async function* jsonlRecords(file, onIssue = () => {
|
|
14017
|
+
}) {
|
|
14018
|
+
const resolvedFile = await file;
|
|
14019
|
+
if (typeof resolvedFile === "string") {
|
|
14020
|
+
for (const line of resolvedFile.split("\n")) {
|
|
14021
|
+
if (!line.trim()) {
|
|
14022
|
+
continue;
|
|
14023
|
+
}
|
|
14024
|
+
try {
|
|
14025
|
+
yield JSON.parse(line.replace(/\r$/, ""));
|
|
14026
|
+
} catch (error) {
|
|
14027
|
+
logBatchInstrumentationError("skipped malformed JSONL", error);
|
|
14028
|
+
onIssue(new Error("OpenAI Batch file contains malformed JSONL"));
|
|
14029
|
+
}
|
|
14030
|
+
}
|
|
14031
|
+
return;
|
|
14032
|
+
}
|
|
14033
|
+
const body = read(resolvedFile, "body");
|
|
14034
|
+
const getReader = read(body, "getReader");
|
|
14035
|
+
if (isObject(body) && typeof getReader === "function") {
|
|
14036
|
+
let reader;
|
|
14037
|
+
try {
|
|
14038
|
+
reader = Reflect.apply(getReader, body, []);
|
|
14039
|
+
const decoder2 = new TextDecoder();
|
|
14040
|
+
let pending = "";
|
|
14041
|
+
while (true) {
|
|
14042
|
+
const readChunk = read(reader, "read");
|
|
14043
|
+
if (typeof readChunk !== "function") {
|
|
14044
|
+
throw new Error("Response body stream has no read method");
|
|
14045
|
+
}
|
|
14046
|
+
const chunk = await Reflect.apply(readChunk, reader, []);
|
|
14047
|
+
if (!isObject(chunk)) {
|
|
14048
|
+
throw new Error("Response body stream returned an invalid chunk");
|
|
14049
|
+
}
|
|
14050
|
+
if (chunk.done === true) {
|
|
14051
|
+
pending += decoder2.decode();
|
|
14052
|
+
break;
|
|
14053
|
+
}
|
|
14054
|
+
if (!(chunk.value instanceof Uint8Array)) {
|
|
14055
|
+
throw new Error("Response body stream returned a non-byte chunk");
|
|
14056
|
+
}
|
|
14057
|
+
pending += decoder2.decode(chunk.value, { stream: true });
|
|
14058
|
+
let newline = pending.indexOf("\n");
|
|
14059
|
+
while (newline !== -1) {
|
|
14060
|
+
const line = pending.slice(0, newline).replace(/\r$/, "");
|
|
14061
|
+
pending = pending.slice(newline + 1);
|
|
14062
|
+
if (line.trim()) {
|
|
14063
|
+
try {
|
|
14064
|
+
yield JSON.parse(line);
|
|
14065
|
+
} catch (error) {
|
|
14066
|
+
logBatchInstrumentationError("skipped malformed JSONL", error);
|
|
14067
|
+
onIssue(new Error("OpenAI Batch file contains malformed JSONL"));
|
|
14068
|
+
}
|
|
14069
|
+
}
|
|
14070
|
+
newline = pending.indexOf("\n");
|
|
14071
|
+
}
|
|
14072
|
+
}
|
|
14073
|
+
if (pending.trim()) {
|
|
14074
|
+
try {
|
|
14075
|
+
yield JSON.parse(pending.replace(/\r$/, ""));
|
|
14076
|
+
} catch (error) {
|
|
14077
|
+
logBatchInstrumentationError("skipped malformed JSONL", error);
|
|
14078
|
+
onIssue(new Error("OpenAI Batch file contains malformed JSONL"));
|
|
14079
|
+
}
|
|
14080
|
+
}
|
|
14081
|
+
} catch (error) {
|
|
14082
|
+
logBatchInstrumentationError("could not read JSONL response body", error);
|
|
14083
|
+
onIssue(new Error("OpenAI Batch response body could not be read"));
|
|
14084
|
+
} finally {
|
|
14085
|
+
const releaseLock = read(reader, "releaseLock");
|
|
14086
|
+
if (typeof releaseLock === "function") {
|
|
14087
|
+
try {
|
|
14088
|
+
Reflect.apply(releaseLock, reader, []);
|
|
14089
|
+
} catch (error) {
|
|
14090
|
+
logBatchInstrumentationError(
|
|
14091
|
+
"could not release stream reader",
|
|
14092
|
+
error
|
|
14093
|
+
);
|
|
14094
|
+
}
|
|
14095
|
+
}
|
|
14096
|
+
}
|
|
14097
|
+
return;
|
|
14098
|
+
}
|
|
14099
|
+
if (isBatchRecordIterable(resolvedFile)) {
|
|
14100
|
+
for await (const record of resolvedFile) {
|
|
14101
|
+
yield record;
|
|
14102
|
+
}
|
|
14103
|
+
return;
|
|
14104
|
+
}
|
|
14105
|
+
logBatchInstrumentationError("skipped invalid JSONL source", resolvedFile);
|
|
14106
|
+
onIssue(new Error("OpenAI Batch file source is invalid"));
|
|
14107
|
+
}
|
|
14108
|
+
async function readBatchInputs(file) {
|
|
14109
|
+
const inputs = /* @__PURE__ */ new Map();
|
|
14110
|
+
const issues = [];
|
|
14111
|
+
let endpoint;
|
|
14112
|
+
try {
|
|
14113
|
+
for await (const value of jsonlRecords(
|
|
14114
|
+
file,
|
|
14115
|
+
(issue) => issues.push(issue)
|
|
14116
|
+
)) {
|
|
14117
|
+
const customId = read(value, "custom_id");
|
|
14118
|
+
const url = read(value, "url");
|
|
14119
|
+
const body = read(value, "body");
|
|
14120
|
+
if (!validCustomId(customId) || inputs.has(customId) || read(value, "method") !== "POST" || typeof url !== "string" || !SUPPORTED_ENDPOINTS.has(url) || endpoint !== void 0 && endpoint !== url || !isObject(body)) {
|
|
14121
|
+
issues.push(new Error("OpenAI Batch input contains an invalid record"));
|
|
14122
|
+
continue;
|
|
14123
|
+
}
|
|
14124
|
+
endpoint = url;
|
|
14125
|
+
let spanData;
|
|
14126
|
+
try {
|
|
14127
|
+
spanData = extractOpenAIBatchInput(url, body);
|
|
14128
|
+
} catch (error) {
|
|
14129
|
+
logBatchInstrumentationError("could not extract batch input", error);
|
|
14130
|
+
}
|
|
14131
|
+
inputs.set(customId, { customId, spanData });
|
|
14132
|
+
}
|
|
14133
|
+
} catch (error) {
|
|
14134
|
+
logBatchInstrumentationError("could not process input file", error);
|
|
14135
|
+
issues.push(new Error("OpenAI Batch input file could not be processed"));
|
|
14136
|
+
}
|
|
14137
|
+
if (!endpoint || inputs.size === 0) {
|
|
14138
|
+
issues.push(new Error("OpenAI Batch input contains no supported records"));
|
|
14139
|
+
}
|
|
14140
|
+
return { endpoint, inputs, issues };
|
|
14141
|
+
}
|
|
14142
|
+
async function writePendingSpans(trace, endTime) {
|
|
14143
|
+
const task = await startBatchSpan(trace.context);
|
|
14144
|
+
const taskParent = await task.export();
|
|
14145
|
+
for (const input of trace.inputs.values()) {
|
|
14146
|
+
try {
|
|
14147
|
+
const child = await startBatchChild(trace.context, taskParent, input);
|
|
14148
|
+
if (endTime !== void 0) {
|
|
14149
|
+
child.end({ endTime });
|
|
14150
|
+
}
|
|
14151
|
+
} catch (error) {
|
|
14152
|
+
logBatchInstrumentationError("could not write batch request span", error);
|
|
14153
|
+
}
|
|
14154
|
+
}
|
|
14155
|
+
if (endTime !== void 0) {
|
|
14156
|
+
if (trace.status && trace.status !== "completed") {
|
|
14157
|
+
task.log({ error: new Error(`OpenAI Batch ${trace.status}`) });
|
|
14158
|
+
}
|
|
14159
|
+
task.end({ endTime });
|
|
14160
|
+
}
|
|
14161
|
+
}
|
|
14162
|
+
var interceptOpenAIFilesCreateTraced = async (target, thisArg, args) => {
|
|
14163
|
+
const startTime = getCurrentUnixTimestamp();
|
|
14164
|
+
const inputPromise = readBatchInputs(args[0].inputFileContent);
|
|
14165
|
+
const parentPromise = exportParent(args[0].parent);
|
|
14166
|
+
const file = await Reflect.apply(target, thisArg, args);
|
|
14167
|
+
try {
|
|
14168
|
+
const inputFileId = read(file, "id");
|
|
14169
|
+
const [inputData, exportedParent2] = await Promise.all([
|
|
14170
|
+
inputPromise,
|
|
14171
|
+
parentPromise
|
|
14172
|
+
]);
|
|
14173
|
+
if (typeof inputFileId !== "string" || !exportedParent2 || !inputData.endpoint || inputData.issues.length > 0) {
|
|
14174
|
+
if (inputData.issues[0]) {
|
|
14175
|
+
logBatchInstrumentationError(
|
|
14176
|
+
"skipped invalid input file",
|
|
14177
|
+
inputData.issues[0]
|
|
14178
|
+
);
|
|
14179
|
+
}
|
|
14180
|
+
return file;
|
|
14181
|
+
}
|
|
14182
|
+
const trace = {
|
|
14183
|
+
context: {
|
|
14184
|
+
inputFileId,
|
|
14185
|
+
endpoint: inputData.endpoint,
|
|
14186
|
+
parent: exportedParent2,
|
|
14187
|
+
taskStartTime: startTime,
|
|
14188
|
+
childStartTime: startTime
|
|
14189
|
+
},
|
|
14190
|
+
inputs: inputData.inputs
|
|
14191
|
+
};
|
|
14192
|
+
pendingBatchTraces.set(inputFileId, trace);
|
|
14193
|
+
await writePendingSpans(trace);
|
|
14194
|
+
} catch (error) {
|
|
14195
|
+
logBatchInstrumentationError("could not start batch spans", error);
|
|
14196
|
+
}
|
|
14197
|
+
return file;
|
|
14198
|
+
};
|
|
14199
|
+
function validTimestamp(value) {
|
|
14200
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0;
|
|
14201
|
+
}
|
|
14202
|
+
function terminalEndTime(batch, startTime) {
|
|
14203
|
+
let timestamp;
|
|
14204
|
+
switch (batch.status) {
|
|
14205
|
+
case "completed":
|
|
14206
|
+
timestamp = batch.completed_at;
|
|
14207
|
+
break;
|
|
14208
|
+
case "failed":
|
|
14209
|
+
timestamp = batch.failed_at;
|
|
14210
|
+
break;
|
|
14211
|
+
case "expired":
|
|
14212
|
+
timestamp = batch.expired_at;
|
|
14213
|
+
break;
|
|
14214
|
+
default:
|
|
14215
|
+
timestamp = batch.cancelled_at;
|
|
14216
|
+
}
|
|
14217
|
+
return validTimestamp(timestamp) ? Math.max(timestamp, startTime) : Math.max(getCurrentUnixTimestamp(), startTime);
|
|
14218
|
+
}
|
|
14219
|
+
async function updateBatchTimestamps(batch) {
|
|
14220
|
+
const trace = pendingBatchTraces.get(batch.input_file_id);
|
|
14221
|
+
if (!trace || trace.context.endpoint !== batch.endpoint) {
|
|
14222
|
+
return;
|
|
14223
|
+
}
|
|
14224
|
+
if (validTimestamp(batch.created_at)) {
|
|
14225
|
+
trace.context.taskStartTime = batch.created_at;
|
|
14226
|
+
}
|
|
14227
|
+
trace.context.childStartTime = validTimestamp(batch.in_progress_at) ? Math.max(batch.in_progress_at, trace.context.taskStartTime) : trace.context.taskStartTime;
|
|
14228
|
+
trace.status = batch.status;
|
|
14229
|
+
if (TERMINAL_STATUSES.has(batch.status)) {
|
|
14230
|
+
trace.endTime = terminalEndTime(batch, trace.context.childStartTime);
|
|
14231
|
+
}
|
|
14232
|
+
await writePendingSpans(trace, trace.endTime);
|
|
14233
|
+
}
|
|
14234
|
+
var interceptOpenAIBatchesRetrieveTraced = (target, thisArg, args) => Promise.resolve(Reflect.apply(target, thisArg, args)).then(async (batch) => {
|
|
14235
|
+
try {
|
|
14236
|
+
await updateBatchTimestamps(batch);
|
|
14237
|
+
} catch (error) {
|
|
14238
|
+
logBatchInstrumentationError("could not update batch timestamps", error);
|
|
14239
|
+
}
|
|
14240
|
+
return batch;
|
|
14241
|
+
});
|
|
14242
|
+
function errorFromResult(result) {
|
|
14243
|
+
const error = read(result.value, "error");
|
|
14244
|
+
if (isObject(error)) {
|
|
14245
|
+
const message = read(error, "message");
|
|
14246
|
+
return new Error(
|
|
14247
|
+
typeof message === "string" ? message : "OpenAI Batch request failed"
|
|
14248
|
+
);
|
|
14249
|
+
}
|
|
14250
|
+
const response = read(result.value, "response");
|
|
14251
|
+
const statusCode = read(response, "status_code");
|
|
14252
|
+
if (result.source === "error" || typeof statusCode === "number" && (statusCode < 200 || statusCode >= 300)) {
|
|
14253
|
+
const message = read(read(read(response, "body"), "error"), "message");
|
|
14254
|
+
return new Error(
|
|
14255
|
+
typeof message === "string" ? message : "OpenAI Batch request failed"
|
|
14256
|
+
);
|
|
14257
|
+
}
|
|
14258
|
+
return void 0;
|
|
14259
|
+
}
|
|
14260
|
+
async function completeBatchResult(context, taskParent, endTime, input, result) {
|
|
14261
|
+
const child = await startBatchChild(context, taskParent, input);
|
|
14262
|
+
try {
|
|
14263
|
+
const resultError = errorFromResult(result);
|
|
14264
|
+
const responseBody = read(read(result.value, "response"), "body");
|
|
14265
|
+
if (resultError) {
|
|
14266
|
+
child.log({ error: resultError });
|
|
14267
|
+
} else if (isObject(responseBody)) {
|
|
14268
|
+
const model = read(responseBody, "model");
|
|
14269
|
+
child.log({
|
|
14270
|
+
output: context.endpoint === "/v1/chat/completions" ? read(responseBody, "choices") : processImagesInOutput(read(responseBody, "output")),
|
|
14271
|
+
...typeof model === "string" ? { metadata: { model } } : {},
|
|
14272
|
+
metrics: parseMetricsFromUsage(read(responseBody, "usage"))
|
|
14273
|
+
});
|
|
14274
|
+
} else {
|
|
14275
|
+
child.log({ error: new Error("OpenAI Batch response body is missing") });
|
|
14276
|
+
}
|
|
14277
|
+
} catch (error) {
|
|
14278
|
+
child.log({ error });
|
|
14279
|
+
} finally {
|
|
14280
|
+
child.end({ endTime });
|
|
14281
|
+
}
|
|
14282
|
+
}
|
|
14283
|
+
async function completeResultFile({
|
|
14284
|
+
context,
|
|
14285
|
+
endTime,
|
|
14286
|
+
file,
|
|
14287
|
+
inputs,
|
|
14288
|
+
issues,
|
|
14289
|
+
seen,
|
|
14290
|
+
source,
|
|
14291
|
+
taskParent
|
|
14292
|
+
}) {
|
|
14293
|
+
if (file === void 0) {
|
|
14294
|
+
return;
|
|
14295
|
+
}
|
|
14296
|
+
for await (const value of jsonlRecords(file, (issue) => issues.push(issue))) {
|
|
14297
|
+
const customId = read(value, "custom_id");
|
|
14298
|
+
if (!validCustomId(customId) || !isObject(value)) {
|
|
14299
|
+
issues.push(
|
|
14300
|
+
new Error("OpenAI Batch result is missing a valid custom_id")
|
|
14301
|
+
);
|
|
14302
|
+
continue;
|
|
14303
|
+
}
|
|
14304
|
+
if (seen.has(customId)) {
|
|
14305
|
+
issues.push(new Error("OpenAI Batch result contains a duplicate"));
|
|
14306
|
+
continue;
|
|
14307
|
+
}
|
|
14308
|
+
const input = inputs.get(customId);
|
|
14309
|
+
if (!input) {
|
|
14310
|
+
issues.push(
|
|
14311
|
+
new Error("OpenAI Batch result does not match an input record")
|
|
14312
|
+
);
|
|
14313
|
+
continue;
|
|
14314
|
+
}
|
|
14315
|
+
seen.add(customId);
|
|
14316
|
+
await completeBatchResult(context, taskParent, endTime, input, {
|
|
14317
|
+
value,
|
|
14318
|
+
source
|
|
14319
|
+
});
|
|
14320
|
+
}
|
|
14321
|
+
}
|
|
14322
|
+
function sameInputs(first, second) {
|
|
14323
|
+
return first.size === second.size && [...first.keys()].every((customId) => second.has(customId));
|
|
14324
|
+
}
|
|
14325
|
+
async function contextForCompletion(inputFileId, inputData) {
|
|
14326
|
+
if (!inputData.endpoint || inputData.issues.length > 0) {
|
|
14327
|
+
return void 0;
|
|
14328
|
+
}
|
|
14329
|
+
const existing = pendingBatchTraces.get(inputFileId);
|
|
14330
|
+
if (existing) {
|
|
14331
|
+
if (existing.context.endpoint !== inputData.endpoint || !sameInputs(existing.inputs, inputData.inputs)) {
|
|
14332
|
+
return void 0;
|
|
14333
|
+
}
|
|
14334
|
+
return { ...existing, inputs: inputData.inputs };
|
|
14335
|
+
}
|
|
14336
|
+
const parent = await exportParent(getSpanParentObject());
|
|
14337
|
+
if (!parent) {
|
|
14338
|
+
return void 0;
|
|
14339
|
+
}
|
|
14340
|
+
const startTime = getCurrentUnixTimestamp();
|
|
14341
|
+
return {
|
|
14342
|
+
context: {
|
|
14343
|
+
inputFileId,
|
|
14344
|
+
endpoint: inputData.endpoint,
|
|
14345
|
+
parent,
|
|
14346
|
+
taskStartTime: startTime,
|
|
14347
|
+
childStartTime: startTime
|
|
14348
|
+
},
|
|
14349
|
+
inputs: inputData.inputs
|
|
14350
|
+
};
|
|
14351
|
+
}
|
|
14352
|
+
async function completeBatch(args) {
|
|
14353
|
+
const inputData = await readBatchInputs(args.inputFileContent);
|
|
14354
|
+
const trace = await contextForCompletion(args.inputFileId, inputData);
|
|
14355
|
+
if (!trace) {
|
|
14356
|
+
logBatchInstrumentationError(
|
|
14357
|
+
"left batch spans pending",
|
|
14358
|
+
inputData.issues[0] ?? new Error("OpenAI Batch input does not match")
|
|
14359
|
+
);
|
|
14360
|
+
return;
|
|
14361
|
+
}
|
|
14362
|
+
const endTime = trace.endTime ?? getCurrentUnixTimestamp();
|
|
14363
|
+
const task = await startBatchSpan(trace.context);
|
|
14364
|
+
const taskParent = await task.export();
|
|
14365
|
+
const issues = [];
|
|
14366
|
+
const seen = /* @__PURE__ */ new Set();
|
|
14367
|
+
await Promise.all([
|
|
14368
|
+
completeResultFile({
|
|
14369
|
+
context: trace.context,
|
|
14370
|
+
endTime,
|
|
14371
|
+
file: args.outputFileContent,
|
|
14372
|
+
inputs: trace.inputs,
|
|
14373
|
+
issues,
|
|
14374
|
+
seen,
|
|
14375
|
+
source: "output",
|
|
14376
|
+
taskParent
|
|
14377
|
+
}),
|
|
14378
|
+
completeResultFile({
|
|
14379
|
+
context: trace.context,
|
|
14380
|
+
endTime,
|
|
14381
|
+
file: args.errorFileContent,
|
|
14382
|
+
inputs: trace.inputs,
|
|
14383
|
+
issues,
|
|
14384
|
+
seen,
|
|
14385
|
+
source: "error",
|
|
14386
|
+
taskParent
|
|
14387
|
+
})
|
|
14388
|
+
]);
|
|
14389
|
+
if (issues.length > 0) {
|
|
14390
|
+
logBatchInstrumentationError("left batch spans pending", issues[0]);
|
|
14391
|
+
return;
|
|
14392
|
+
}
|
|
14393
|
+
const missing = [...trace.inputs.values()].filter(
|
|
14394
|
+
({ customId }) => !seen.has(customId)
|
|
14395
|
+
);
|
|
14396
|
+
if (!trace.status || trace.status === "completed") {
|
|
14397
|
+
if (missing.length > 0) {
|
|
14398
|
+
logBatchInstrumentationError(
|
|
14399
|
+
"left batch spans pending",
|
|
14400
|
+
new Error("OpenAI Batch result files are incomplete")
|
|
14401
|
+
);
|
|
14402
|
+
return;
|
|
14403
|
+
}
|
|
14404
|
+
} else {
|
|
14405
|
+
for (const input of missing) {
|
|
14406
|
+
const child = await startBatchChild(trace.context, taskParent, input);
|
|
14407
|
+
child.log({ error: new Error(`OpenAI Batch ${trace.status}`) });
|
|
14408
|
+
child.end({ endTime });
|
|
14409
|
+
}
|
|
14410
|
+
task.log({ error: new Error(`OpenAI Batch ${trace.status}`) });
|
|
14411
|
+
}
|
|
14412
|
+
task.end({ endTime });
|
|
14413
|
+
pendingBatchTraces.delete(args.inputFileId);
|
|
14414
|
+
}
|
|
14415
|
+
var interceptOpenAIBatchTraceComplete = (target, thisArg, args) => Promise.resolve(Reflect.apply(target, thisArg, args)).then(async (result) => {
|
|
14416
|
+
try {
|
|
14417
|
+
await completeBatch(args[0]);
|
|
14418
|
+
} catch (error) {
|
|
14419
|
+
logBatchInstrumentationError("could not complete batch", error);
|
|
14420
|
+
}
|
|
14421
|
+
return result;
|
|
14422
|
+
});
|
|
14423
|
+
|
|
13770
14424
|
// src/instrumentation/plugins/openai-plugin.ts
|
|
13771
14425
|
var OpenAIPlugin = class extends BasePlugin {
|
|
13772
14426
|
constructor() {
|
|
13773
14427
|
super();
|
|
13774
14428
|
}
|
|
13775
14429
|
onEnable() {
|
|
14430
|
+
this.unsubscribers.push(
|
|
14431
|
+
openAIChannels.filesCreateTraced.intercept(
|
|
14432
|
+
interceptOpenAIFilesCreateTraced
|
|
14433
|
+
),
|
|
14434
|
+
openAIChannels.batchesRetrieveTraced.intercept(
|
|
14435
|
+
interceptOpenAIBatchesRetrieveTraced
|
|
14436
|
+
),
|
|
14437
|
+
openAIChannels.batchesCompleteTrace.intercept(
|
|
14438
|
+
interceptOpenAIBatchTraceComplete
|
|
14439
|
+
)
|
|
14440
|
+
);
|
|
13776
14441
|
this.unsubscribers.push(
|
|
13777
14442
|
traceStreamingChannel(openAIChannels.chatCompletionsCreate, {
|
|
13778
14443
|
name: "Chat Completion",
|
|
13779
14444
|
type: "llm" /* LLM */,
|
|
13780
|
-
extractInput: ([params]) =>
|
|
13781
|
-
const { messages, ...metadata } = params;
|
|
13782
|
-
return {
|
|
13783
|
-
input: processInputAttachments(messages),
|
|
13784
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13785
|
-
};
|
|
13786
|
-
},
|
|
14445
|
+
extractInput: ([params]) => extractOpenAIChatInput(params),
|
|
13787
14446
|
extractOutput: (result) => {
|
|
13788
14447
|
return result?.choices;
|
|
13789
14448
|
},
|
|
@@ -13829,13 +14488,7 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13829
14488
|
traceStreamingChannel(openAIChannels.betaChatCompletionsParse, {
|
|
13830
14489
|
name: "Chat Completion",
|
|
13831
14490
|
type: "llm" /* LLM */,
|
|
13832
|
-
extractInput: ([params]) =>
|
|
13833
|
-
const { messages, ...metadata } = params;
|
|
13834
|
-
return {
|
|
13835
|
-
input: processInputAttachments(messages),
|
|
13836
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13837
|
-
};
|
|
13838
|
-
},
|
|
14491
|
+
extractInput: ([params]) => extractOpenAIChatInput(params),
|
|
13839
14492
|
extractOutput: (result) => {
|
|
13840
14493
|
return result?.choices;
|
|
13841
14494
|
},
|
|
@@ -13857,13 +14510,7 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13857
14510
|
traceSyncStreamChannel(openAIChannels.betaChatCompletionsStream, {
|
|
13858
14511
|
name: "Chat Completion",
|
|
13859
14512
|
type: "llm" /* LLM */,
|
|
13860
|
-
extractInput: ([params]) =>
|
|
13861
|
-
const { messages, ...metadata } = params;
|
|
13862
|
-
return {
|
|
13863
|
-
input: processInputAttachments(messages),
|
|
13864
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13865
|
-
};
|
|
13866
|
-
}
|
|
14513
|
+
extractInput: ([params]) => extractOpenAIChatInput(params)
|
|
13867
14514
|
})
|
|
13868
14515
|
);
|
|
13869
14516
|
this.unsubscribers.push(
|
|
@@ -13893,23 +14540,11 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13893
14540
|
traceStreamingChannel(openAIChannels.responsesCreate, {
|
|
13894
14541
|
name: "openai.responses.create",
|
|
13895
14542
|
type: "llm" /* LLM */,
|
|
13896
|
-
extractInput: ([params]) =>
|
|
13897
|
-
const { input, ...metadata } = params;
|
|
13898
|
-
return {
|
|
13899
|
-
input: processInputAttachments(input),
|
|
13900
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13901
|
-
};
|
|
13902
|
-
},
|
|
14543
|
+
extractInput: ([params]) => extractOpenAIResponsesInput(params),
|
|
13903
14544
|
extractOutput: (result) => {
|
|
13904
14545
|
return processImagesInOutput(result?.output);
|
|
13905
14546
|
},
|
|
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
|
-
},
|
|
14547
|
+
extractMetadata: (result) => extractOpenAIResponsesMetadata(result),
|
|
13913
14548
|
extractMetrics: (result, startTime, endEvent) => {
|
|
13914
14549
|
const metrics = withCachedMetric(
|
|
13915
14550
|
parseMetricsFromUsage(result?.usage),
|
|
@@ -13928,13 +14563,7 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13928
14563
|
traceSyncStreamChannel(openAIChannels.responsesStream, {
|
|
13929
14564
|
name: "openai.responses.create",
|
|
13930
14565
|
type: "llm" /* LLM */,
|
|
13931
|
-
extractInput: ([params]) =>
|
|
13932
|
-
const { input, ...metadata } = params;
|
|
13933
|
-
return {
|
|
13934
|
-
input: processInputAttachments(input),
|
|
13935
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13936
|
-
};
|
|
13937
|
-
},
|
|
14566
|
+
extractInput: ([params]) => extractOpenAIResponsesInput(params),
|
|
13938
14567
|
extractFromEvent: (event) => {
|
|
13939
14568
|
if (event.type !== "response.completed" || !event.response) {
|
|
13940
14569
|
return {};
|
|
@@ -13957,23 +14586,11 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13957
14586
|
traceStreamingChannel(openAIChannels.responsesParse, {
|
|
13958
14587
|
name: "openai.responses.parse",
|
|
13959
14588
|
type: "llm" /* LLM */,
|
|
13960
|
-
extractInput: ([params]) =>
|
|
13961
|
-
const { input, ...metadata } = params;
|
|
13962
|
-
return {
|
|
13963
|
-
input: processInputAttachments(input),
|
|
13964
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13965
|
-
};
|
|
13966
|
-
},
|
|
14589
|
+
extractInput: ([params]) => extractOpenAIResponsesInput(params),
|
|
13967
14590
|
extractOutput: (result) => {
|
|
13968
14591
|
return processImagesInOutput(result?.output);
|
|
13969
14592
|
},
|
|
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
|
-
},
|
|
14593
|
+
extractMetadata: (result) => extractOpenAIResponsesMetadata(result),
|
|
13977
14594
|
extractMetrics: (result, startTime, endEvent) => {
|
|
13978
14595
|
const metrics = withCachedMetric(
|
|
13979
14596
|
parseMetricsFromUsage(result?.usage),
|
|
@@ -13992,23 +14609,11 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13992
14609
|
traceAsyncChannel(openAIChannels.responsesCompact, {
|
|
13993
14610
|
name: "openai.responses.compact",
|
|
13994
14611
|
type: "llm" /* LLM */,
|
|
13995
|
-
extractInput: ([params]) =>
|
|
13996
|
-
const { input, ...metadata } = params;
|
|
13997
|
-
return {
|
|
13998
|
-
input: processInputAttachments(input),
|
|
13999
|
-
metadata: { ...metadata, provider: "openai" }
|
|
14000
|
-
};
|
|
14001
|
-
},
|
|
14612
|
+
extractInput: ([params]) => extractOpenAIResponsesInput(params),
|
|
14002
14613
|
extractOutput: (result) => {
|
|
14003
14614
|
return processImagesInOutput(result?.output);
|
|
14004
14615
|
},
|
|
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
|
-
},
|
|
14616
|
+
extractMetadata: (result) => extractOpenAIResponsesMetadata(result),
|
|
14012
14617
|
extractMetrics: (result, startTime, endEvent) => {
|
|
14013
14618
|
const metrics = withCachedMetric(
|
|
14014
14619
|
parseMetricsFromUsage(result?.usage),
|
|
@@ -14064,35 +14669,6 @@ function withCachedMetric(metrics, result, endEvent) {
|
|
|
14064
14669
|
cached
|
|
14065
14670
|
};
|
|
14066
14671
|
}
|
|
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
14672
|
function mergeLogprobTokens(existing, incoming) {
|
|
14097
14673
|
if (incoming === void 0) {
|
|
14098
14674
|
return existing;
|
|
@@ -19249,6 +19825,12 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
|
|
|
19249
19825
|
if (!activeEntry) {
|
|
19250
19826
|
return result;
|
|
19251
19827
|
}
|
|
19828
|
+
const executionOptions = args[1];
|
|
19829
|
+
const toolCallId = isObject(executionOptions) ? executionOptions.toolCallId : void 0;
|
|
19830
|
+
const toolInput = {
|
|
19831
|
+
input: serializeToolExecutionInput(args),
|
|
19832
|
+
...typeof toolCallId === "string" ? { metadata: { toolCallId } } : {}
|
|
19833
|
+
};
|
|
19252
19834
|
if (isAsyncGenerator(result)) {
|
|
19253
19835
|
return (async function* () {
|
|
19254
19836
|
const span = activeEntry.parentSpan.startSpan(
|
|
@@ -19262,7 +19844,7 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
|
|
|
19262
19844
|
INSTRUMENTATION_NAMES.AI_SDK
|
|
19263
19845
|
)
|
|
19264
19846
|
);
|
|
19265
|
-
span.log(
|
|
19847
|
+
span.log(toolInput);
|
|
19266
19848
|
try {
|
|
19267
19849
|
let lastValue;
|
|
19268
19850
|
for await (const value of result) {
|
|
@@ -19280,7 +19862,7 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
|
|
|
19280
19862
|
}
|
|
19281
19863
|
return activeEntry.parentSpan.traced(
|
|
19282
19864
|
async (span) => {
|
|
19283
|
-
span.log(
|
|
19865
|
+
span.log(toolInput);
|
|
19284
19866
|
const awaitedResult = await result;
|
|
19285
19867
|
span.log({ output: awaitedResult });
|
|
19286
19868
|
return awaitedResult;
|
|
@@ -33402,14 +33984,17 @@ function getMetricsFromResponse(response) {
|
|
|
33402
33984
|
if (!isRecord(usageMetadata)) {
|
|
33403
33985
|
continue;
|
|
33404
33986
|
}
|
|
33405
|
-
const inputTokenDetails = usageMetadata.input_token_details;
|
|
33987
|
+
const inputTokenDetails = isRecord(usageMetadata.input_token_details) ? usageMetadata.input_token_details : {};
|
|
33406
33988
|
const outputTokenDetails = usageMetadata.output_token_details;
|
|
33407
33989
|
return normalizeTokenMetrics({
|
|
33408
33990
|
total_tokens: usageMetadata.total_tokens,
|
|
33409
33991
|
prompt_tokens: usageMetadata.input_tokens,
|
|
33410
33992
|
completion_tokens: usageMetadata.output_tokens,
|
|
33411
|
-
|
|
33412
|
-
|
|
33993
|
+
// Prefer TTL-specific cache writes over the aggregate when available.
|
|
33994
|
+
prompt_cache_creation_tokens: inputTokenDetails.ephemeral_5m_input_tokens == null && inputTokenDetails.ephemeral_1h_input_tokens == null ? inputTokenDetails.cache_creation : void 0,
|
|
33995
|
+
prompt_cache_creation_5m_tokens: inputTokenDetails.ephemeral_5m_input_tokens,
|
|
33996
|
+
prompt_cache_creation_1h_tokens: inputTokenDetails.ephemeral_1h_input_tokens,
|
|
33997
|
+
prompt_cached_tokens: inputTokenDetails.cache_read,
|
|
33413
33998
|
completion_reasoning_tokens: isRecord(outputTokenDetails) ? outputTokenDetails.reasoning : void 0
|
|
33414
33999
|
});
|
|
33415
34000
|
}
|
|
@@ -34125,7 +34710,7 @@ function extractSession(event) {
|
|
|
34125
34710
|
return isObject(candidate) && typeof candidate.prompt === "function" ? candidate : void 0;
|
|
34126
34711
|
}
|
|
34127
34712
|
function isPiAgent(value) {
|
|
34128
|
-
return isObject(value) && typeof value.streamFn === "function" && typeof value.subscribe === "function";
|
|
34713
|
+
return isObject(value) && (typeof value.streamFunction === "function" || typeof value.streamFn === "function") && typeof value.subscribe === "function";
|
|
34129
34714
|
}
|
|
34130
34715
|
function promptContextStore() {
|
|
34131
34716
|
piPromptContextStore ??= isomorph_default.newAsyncLocalStorage();
|
|
@@ -34135,17 +34720,21 @@ function currentPiPromptState() {
|
|
|
34135
34720
|
return promptContextStore().getStore();
|
|
34136
34721
|
}
|
|
34137
34722
|
function installPiAgentInstrumentation(agent) {
|
|
34723
|
+
const property = typeof agent.streamFunction === "function" ? "streamFunction" : "streamFn";
|
|
34724
|
+
const streamFunction = agent[property];
|
|
34138
34725
|
const existing = piAgentPatchStates.get(agent);
|
|
34139
|
-
if (!existing ||
|
|
34726
|
+
if (streamFunction && (!existing || existing.property !== property || streamFunction !== existing.wrappedStreamFunction)) {
|
|
34140
34727
|
const patchState = {
|
|
34141
|
-
|
|
34142
|
-
|
|
34728
|
+
originalStreamFunction: streamFunction,
|
|
34729
|
+
property,
|
|
34730
|
+
wrappedStreamFunction: streamFunction
|
|
34143
34731
|
};
|
|
34144
|
-
patchState.
|
|
34732
|
+
patchState.wrappedStreamFunction = makeInstrumentedStreamFunction(
|
|
34145
34733
|
agent,
|
|
34146
|
-
patchState.
|
|
34734
|
+
patchState.originalStreamFunction,
|
|
34735
|
+
property
|
|
34147
34736
|
);
|
|
34148
|
-
agent
|
|
34737
|
+
agent[property] = patchState.wrappedStreamFunction;
|
|
34149
34738
|
piAgentPatchStates.set(agent, patchState);
|
|
34150
34739
|
}
|
|
34151
34740
|
if (piAgentEventSubscriptions.has(agent)) {
|
|
@@ -34170,15 +34759,21 @@ function installPiAgentInstrumentation(agent) {
|
|
|
34170
34759
|
logInstrumentationError4("Pi Coding Agent event subscription", error);
|
|
34171
34760
|
}
|
|
34172
34761
|
}
|
|
34173
|
-
function
|
|
34174
|
-
return async function
|
|
34175
|
-
const invokeOriginal = () => Reflect.apply(
|
|
34762
|
+
function makeInstrumentedStreamFunction(agent, originalStreamFunction, property) {
|
|
34763
|
+
return async function instrumentedPiStreamFunction(model, context, options) {
|
|
34764
|
+
const invokeOriginal = () => Reflect.apply(originalStreamFunction, this, [model, context, options]);
|
|
34176
34765
|
const state = currentPiPromptState();
|
|
34177
34766
|
if (!state || state.agent !== agent || state.finalized) {
|
|
34178
34767
|
return invokeOriginal();
|
|
34179
34768
|
}
|
|
34180
34769
|
wrapPiToolExecutors(context.tools);
|
|
34181
|
-
const llmState = await startPiLlmSpan(
|
|
34770
|
+
const llmState = await startPiLlmSpan(
|
|
34771
|
+
state,
|
|
34772
|
+
model,
|
|
34773
|
+
context,
|
|
34774
|
+
property,
|
|
34775
|
+
options
|
|
34776
|
+
);
|
|
34182
34777
|
try {
|
|
34183
34778
|
const stream = await runWithAutoInstrumentationSuppressed(invokeOriginal);
|
|
34184
34779
|
return patchAssistantMessageStream(stream, state, llmState);
|
|
@@ -34215,12 +34810,12 @@ function wrapPiToolExecutors(tools) {
|
|
|
34215
34810
|
}
|
|
34216
34811
|
}
|
|
34217
34812
|
}
|
|
34218
|
-
async function startPiLlmSpan(state, model, context, options) {
|
|
34813
|
+
async function startPiLlmSpan(state, model, context, property, options) {
|
|
34219
34814
|
const metadata = {
|
|
34220
34815
|
...extractModelMetadata2(model),
|
|
34221
34816
|
...extractStreamOptionsMetadata(options),
|
|
34222
34817
|
...extractToolMetadata(context.tools),
|
|
34223
|
-
"pi_coding_agent.operation":
|
|
34818
|
+
"pi_coding_agent.operation": `agent.${property}`
|
|
34224
34819
|
};
|
|
34225
34820
|
const span = startSpan(
|
|
34226
34821
|
withSpanInstrumentationName(
|
|
@@ -37236,6 +37831,7 @@ __export(exports_exports, {
|
|
|
37236
37831
|
braintrustStreamChunkSchema: () => braintrustStreamChunkSchema,
|
|
37237
37832
|
buildLocalSummary: () => buildLocalSummary,
|
|
37238
37833
|
collectAnthropicSession: () => collectAnthropicSession,
|
|
37834
|
+
completeOpenAIBatchTrace: () => completeOpenAIBatchTrace,
|
|
37239
37835
|
configureInstrumentation: () => configureInstrumentation,
|
|
37240
37836
|
constructLogs3OverflowRequest: () => constructLogs3OverflowRequest,
|
|
37241
37837
|
createFinalValuePassThroughStream: () => createFinalValuePassThroughStream,
|
|
@@ -37274,6 +37870,8 @@ __export(exports_exports, {
|
|
|
37274
37870
|
loginToState: () => loginToState,
|
|
37275
37871
|
logs3OverflowUploadSchema: () => logs3OverflowUploadSchema,
|
|
37276
37872
|
newId: () => newId,
|
|
37873
|
+
openaiBatchesRetrieveTraced: () => openaiBatchesRetrieveTraced,
|
|
37874
|
+
openaiFilesCreateTraced: () => openaiFilesCreateTraced,
|
|
37277
37875
|
parseCachedHeader: () => parseCachedHeader,
|
|
37278
37876
|
parseTemplateFormat: () => parseTemplateFormat,
|
|
37279
37877
|
permalink: () => permalink,
|
|
@@ -37438,6 +38036,260 @@ async function registerSandbox(options) {
|
|
|
37438
38036
|
};
|
|
37439
38037
|
}
|
|
37440
38038
|
|
|
38039
|
+
// src/wrappers/openai-promise-utils.ts
|
|
38040
|
+
function splitSpanInfo(allParams) {
|
|
38041
|
+
const { span_info, ...params } = allParams;
|
|
38042
|
+
return {
|
|
38043
|
+
params,
|
|
38044
|
+
span_info
|
|
38045
|
+
};
|
|
38046
|
+
}
|
|
38047
|
+
function createChannelContext(_channel, params, span_info) {
|
|
38048
|
+
return {
|
|
38049
|
+
arguments: (
|
|
38050
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38051
|
+
[params]
|
|
38052
|
+
),
|
|
38053
|
+
span_info
|
|
38054
|
+
};
|
|
38055
|
+
}
|
|
38056
|
+
async function tracePromiseWithResponse(channel2, traceContext, apiPromise) {
|
|
38057
|
+
let enhancedResponse;
|
|
38058
|
+
const tracePromise = (
|
|
38059
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38060
|
+
channel2.tracePromise
|
|
38061
|
+
);
|
|
38062
|
+
const data = await tracePromise(async () => {
|
|
38063
|
+
enhancedResponse = await apiPromise.withResponse();
|
|
38064
|
+
traceContext.response = enhancedResponse.response;
|
|
38065
|
+
return enhancedResponse.data;
|
|
38066
|
+
}, traceContext);
|
|
38067
|
+
if (!enhancedResponse) {
|
|
38068
|
+
throw new Error("Expected withResponse() to provide response");
|
|
38069
|
+
}
|
|
38070
|
+
return {
|
|
38071
|
+
data,
|
|
38072
|
+
response: enhancedResponse.response,
|
|
38073
|
+
request_id: enhancedResponse.request_id
|
|
38074
|
+
};
|
|
38075
|
+
}
|
|
38076
|
+
async function tracePromiseAsResponse(channel2, traceContext, apiPromise) {
|
|
38077
|
+
const tracePromise = (
|
|
38078
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38079
|
+
channel2.tracePromise
|
|
38080
|
+
);
|
|
38081
|
+
let response;
|
|
38082
|
+
await tracePromise(async () => {
|
|
38083
|
+
response = await apiPromise.asResponse();
|
|
38084
|
+
traceContext.response = response;
|
|
38085
|
+
return void 0;
|
|
38086
|
+
}, traceContext);
|
|
38087
|
+
if (!response) {
|
|
38088
|
+
throw new Error("Expected asResponse() to provide response");
|
|
38089
|
+
}
|
|
38090
|
+
return response;
|
|
38091
|
+
}
|
|
38092
|
+
function createLazyAPIPromise(ensureExecuted, ensureResponse, getAPIPromise) {
|
|
38093
|
+
let firstConsumption;
|
|
38094
|
+
let enhancedResponsePromise;
|
|
38095
|
+
let dataPromise;
|
|
38096
|
+
let responsePromise;
|
|
38097
|
+
const withResponse = () => {
|
|
38098
|
+
firstConsumption ??= "data";
|
|
38099
|
+
enhancedResponsePromise ??= firstConsumption === "data" ? ensureExecuted() : getAPIPromise().withResponse();
|
|
38100
|
+
return enhancedResponsePromise;
|
|
38101
|
+
};
|
|
38102
|
+
const asResponse = () => {
|
|
38103
|
+
firstConsumption ??= "response";
|
|
38104
|
+
responsePromise ??= firstConsumption === "response" ? ensureResponse() : getAPIPromise().asResponse();
|
|
38105
|
+
return responsePromise;
|
|
38106
|
+
};
|
|
38107
|
+
return new Proxy({}, {
|
|
38108
|
+
get(target, prop, receiver) {
|
|
38109
|
+
if (prop === "withResponse") {
|
|
38110
|
+
return withResponse;
|
|
38111
|
+
}
|
|
38112
|
+
if (prop === "asResponse") {
|
|
38113
|
+
return asResponse;
|
|
38114
|
+
}
|
|
38115
|
+
if (prop === "then" || prop === "catch" || prop === "finally" || prop in Promise.prototype) {
|
|
38116
|
+
dataPromise ??= withResponse().then((result) => result.data);
|
|
38117
|
+
const value = Reflect.get(dataPromise, prop, receiver);
|
|
38118
|
+
return typeof value === "function" ? value.bind(dataPromise) : value;
|
|
38119
|
+
}
|
|
38120
|
+
return Reflect.get(target, prop, receiver);
|
|
38121
|
+
}
|
|
38122
|
+
});
|
|
38123
|
+
}
|
|
38124
|
+
|
|
38125
|
+
// src/openai-batch.ts
|
|
38126
|
+
function read2(value, key) {
|
|
38127
|
+
if (value === null || typeof value !== "object" && typeof value !== "function") {
|
|
38128
|
+
return void 0;
|
|
38129
|
+
}
|
|
38130
|
+
try {
|
|
38131
|
+
return Reflect.get(value, key);
|
|
38132
|
+
} catch {
|
|
38133
|
+
return void 0;
|
|
38134
|
+
}
|
|
38135
|
+
}
|
|
38136
|
+
function isAsyncIterable5(value) {
|
|
38137
|
+
return typeof read2(value, Symbol.asyncIterator) === "function";
|
|
38138
|
+
}
|
|
38139
|
+
function teeAsyncIterable(source) {
|
|
38140
|
+
const iterator = source[Symbol.asyncIterator]();
|
|
38141
|
+
const stream = new ReadableStream({
|
|
38142
|
+
async pull(controller) {
|
|
38143
|
+
try {
|
|
38144
|
+
const result = await iterator.next();
|
|
38145
|
+
if (result.done) {
|
|
38146
|
+
controller.close();
|
|
38147
|
+
return;
|
|
38148
|
+
}
|
|
38149
|
+
if (!(result.value instanceof Uint8Array)) {
|
|
38150
|
+
throw new TypeError(
|
|
38151
|
+
"OpenAI upload streams must yield Uint8Array chunks"
|
|
38152
|
+
);
|
|
38153
|
+
}
|
|
38154
|
+
controller.enqueue(result.value);
|
|
38155
|
+
} catch (error) {
|
|
38156
|
+
controller.error(error);
|
|
38157
|
+
}
|
|
38158
|
+
},
|
|
38159
|
+
async cancel(reason) {
|
|
38160
|
+
await iterator.return?.(reason);
|
|
38161
|
+
}
|
|
38162
|
+
});
|
|
38163
|
+
const [uploadStream, trace] = stream.tee();
|
|
38164
|
+
const upload = {
|
|
38165
|
+
async *[Symbol.asyncIterator]() {
|
|
38166
|
+
const reader = uploadStream.getReader();
|
|
38167
|
+
try {
|
|
38168
|
+
while (true) {
|
|
38169
|
+
const result = await reader.read();
|
|
38170
|
+
if (result.done) {
|
|
38171
|
+
return;
|
|
38172
|
+
}
|
|
38173
|
+
yield result.value;
|
|
38174
|
+
}
|
|
38175
|
+
} finally {
|
|
38176
|
+
reader.releaseLock();
|
|
38177
|
+
}
|
|
38178
|
+
}
|
|
38179
|
+
};
|
|
38180
|
+
const path = read2(source, "path");
|
|
38181
|
+
if (typeof path === "string") {
|
|
38182
|
+
Object.defineProperty(upload, "path", { value: path });
|
|
38183
|
+
}
|
|
38184
|
+
return { upload, trace: new Response(trace) };
|
|
38185
|
+
}
|
|
38186
|
+
function teeUpload(upload) {
|
|
38187
|
+
if (upload instanceof Blob) {
|
|
38188
|
+
return { upload, trace: new Response(upload) };
|
|
38189
|
+
}
|
|
38190
|
+
if (upload instanceof Response) {
|
|
38191
|
+
return { upload, trace: upload.clone() };
|
|
38192
|
+
}
|
|
38193
|
+
if (isAsyncIterable5(upload)) {
|
|
38194
|
+
return teeAsyncIterable(upload);
|
|
38195
|
+
}
|
|
38196
|
+
return void 0;
|
|
38197
|
+
}
|
|
38198
|
+
function openaiFilesCreateTraced(files) {
|
|
38199
|
+
return (params, options) => {
|
|
38200
|
+
const parent = getSpanParentObject();
|
|
38201
|
+
const purpose = read2(params, "purpose");
|
|
38202
|
+
const file = read2(params, "file");
|
|
38203
|
+
if (purpose !== "batch") {
|
|
38204
|
+
return files.create(params, options);
|
|
38205
|
+
}
|
|
38206
|
+
let branches;
|
|
38207
|
+
try {
|
|
38208
|
+
branches = teeUpload(file);
|
|
38209
|
+
} catch {
|
|
38210
|
+
return files.create(params, options);
|
|
38211
|
+
}
|
|
38212
|
+
if (!branches) {
|
|
38213
|
+
return files.create(params, options);
|
|
38214
|
+
}
|
|
38215
|
+
const tracedParams = {
|
|
38216
|
+
...Object(params),
|
|
38217
|
+
file: branches.upload
|
|
38218
|
+
};
|
|
38219
|
+
const apiPromise = files.create(tracedParams, options);
|
|
38220
|
+
let enhancedResponse;
|
|
38221
|
+
const tracedResponse = openAIChannels.filesCreateTraced.invoke(
|
|
38222
|
+
async () => {
|
|
38223
|
+
enhancedResponse = await apiPromise.withResponse();
|
|
38224
|
+
return enhancedResponse.data;
|
|
38225
|
+
},
|
|
38226
|
+
files,
|
|
38227
|
+
[{ params, inputFileContent: branches.trace, parent }],
|
|
38228
|
+
{}
|
|
38229
|
+
).then((data) => {
|
|
38230
|
+
if (!enhancedResponse) {
|
|
38231
|
+
throw new Error(
|
|
38232
|
+
"Expected OpenAI withResponse() to provide a response"
|
|
38233
|
+
);
|
|
38234
|
+
}
|
|
38235
|
+
return { ...enhancedResponse, data };
|
|
38236
|
+
});
|
|
38237
|
+
return createLazyAPIPromise(
|
|
38238
|
+
() => tracedResponse,
|
|
38239
|
+
() => tracedResponse.then(({ response }) => response),
|
|
38240
|
+
() => apiPromise
|
|
38241
|
+
);
|
|
38242
|
+
};
|
|
38243
|
+
}
|
|
38244
|
+
function openaiBatchesRetrieveTraced(batches) {
|
|
38245
|
+
return (batchId, options) => {
|
|
38246
|
+
const apiPromise = batches.retrieve(batchId, options);
|
|
38247
|
+
let enhancedResponse;
|
|
38248
|
+
const tracedResponse = openAIChannels.batchesRetrieveTraced.invoke(
|
|
38249
|
+
async () => {
|
|
38250
|
+
enhancedResponse = await apiPromise.withResponse();
|
|
38251
|
+
return enhancedResponse.data;
|
|
38252
|
+
},
|
|
38253
|
+
batches,
|
|
38254
|
+
[{ batchId }],
|
|
38255
|
+
{}
|
|
38256
|
+
).then((data) => {
|
|
38257
|
+
if (!enhancedResponse) {
|
|
38258
|
+
throw new Error(
|
|
38259
|
+
"Expected OpenAI withResponse() to provide a response"
|
|
38260
|
+
);
|
|
38261
|
+
}
|
|
38262
|
+
return { ...enhancedResponse, data };
|
|
38263
|
+
});
|
|
38264
|
+
return createLazyAPIPromise(
|
|
38265
|
+
() => tracedResponse,
|
|
38266
|
+
() => tracedResponse.then(({ response }) => response),
|
|
38267
|
+
() => apiPromise
|
|
38268
|
+
);
|
|
38269
|
+
};
|
|
38270
|
+
}
|
|
38271
|
+
async function completeOpenAIBatchTrace(args) {
|
|
38272
|
+
const inputFileContent = Promise.resolve(args.inputFileContent);
|
|
38273
|
+
const outputFileContent = args.outputFileContent === void 0 ? void 0 : Promise.resolve(args.outputFileContent);
|
|
38274
|
+
const errorFileContent = args.errorFileContent === void 0 ? void 0 : Promise.resolve(args.errorFileContent);
|
|
38275
|
+
void inputFileContent.catch(() => void 0);
|
|
38276
|
+
void outputFileContent?.catch(() => void 0);
|
|
38277
|
+
void errorFileContent?.catch(() => void 0);
|
|
38278
|
+
await openAIChannels.batchesCompleteTrace.invoke(
|
|
38279
|
+
async () => void 0,
|
|
38280
|
+
void 0,
|
|
38281
|
+
[
|
|
38282
|
+
{
|
|
38283
|
+
...args,
|
|
38284
|
+
inputFileContent,
|
|
38285
|
+
outputFileContent,
|
|
38286
|
+
errorFileContent
|
|
38287
|
+
}
|
|
38288
|
+
],
|
|
38289
|
+
{}
|
|
38290
|
+
);
|
|
38291
|
+
}
|
|
38292
|
+
|
|
37441
38293
|
// src/functions/invoke.ts
|
|
37442
38294
|
async function invoke(args) {
|
|
37443
38295
|
const {
|
|
@@ -37540,58 +38392,6 @@ function initFunction({
|
|
|
37540
38392
|
return f;
|
|
37541
38393
|
}
|
|
37542
38394
|
|
|
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
38395
|
// src/wrappers/oai_responses.ts
|
|
37596
38396
|
function responsesProxy(openai) {
|
|
37597
38397
|
if (!openai.responses) {
|
|
@@ -37628,17 +38428,33 @@ function wrapResponsesAsync(target, channel2) {
|
|
|
37628
38428
|
return (allParams, options) => {
|
|
37629
38429
|
const { span_info, params } = splitSpanInfo(allParams);
|
|
37630
38430
|
let executionPromise = null;
|
|
38431
|
+
let apiPromise = null;
|
|
38432
|
+
const getAPIPromise = () => {
|
|
38433
|
+
apiPromise ??= target(params, options);
|
|
38434
|
+
return apiPromise;
|
|
38435
|
+
};
|
|
37631
38436
|
const ensureExecuted = () => {
|
|
37632
38437
|
if (!executionPromise) {
|
|
37633
38438
|
executionPromise = (async () => {
|
|
37634
38439
|
const traceContext = createChannelContext(channel2, params, span_info);
|
|
37635
|
-
|
|
37636
|
-
|
|
38440
|
+
return tracePromiseWithResponse(
|
|
38441
|
+
channel2,
|
|
38442
|
+
traceContext,
|
|
38443
|
+
getAPIPromise()
|
|
38444
|
+
);
|
|
37637
38445
|
})();
|
|
37638
38446
|
}
|
|
37639
38447
|
return executionPromise;
|
|
37640
38448
|
};
|
|
37641
|
-
return createLazyAPIPromise(
|
|
38449
|
+
return createLazyAPIPromise(
|
|
38450
|
+
ensureExecuted,
|
|
38451
|
+
() => tracePromiseAsResponse(
|
|
38452
|
+
channel2,
|
|
38453
|
+
createChannelContext(channel2, params, span_info),
|
|
38454
|
+
getAPIPromise()
|
|
38455
|
+
),
|
|
38456
|
+
getAPIPromise
|
|
38457
|
+
);
|
|
37642
38458
|
};
|
|
37643
38459
|
}
|
|
37644
38460
|
function wrapResponsesSyncStream(target, channel2) {
|
|
@@ -37784,6 +38600,11 @@ function wrapChatCompletion(completion) {
|
|
|
37784
38600
|
allParams
|
|
37785
38601
|
);
|
|
37786
38602
|
let executionPromise = null;
|
|
38603
|
+
let apiPromise = null;
|
|
38604
|
+
const getAPIPromise = () => {
|
|
38605
|
+
apiPromise ??= completion(params, options);
|
|
38606
|
+
return apiPromise;
|
|
38607
|
+
};
|
|
37787
38608
|
const ensureExecuted = () => {
|
|
37788
38609
|
if (!executionPromise) {
|
|
37789
38610
|
executionPromise = (async () => {
|
|
@@ -37793,32 +38614,44 @@ function wrapChatCompletion(completion) {
|
|
|
37793
38614
|
span_info
|
|
37794
38615
|
);
|
|
37795
38616
|
if (params.stream) {
|
|
37796
|
-
const completionPromise =
|
|
37797
|
-
|
|
37798
|
-
|
|
38617
|
+
const completionPromise = (
|
|
38618
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38619
|
+
getAPIPromise()
|
|
37799
38620
|
);
|
|
37800
|
-
const { data: data2, response: response2 } = await tracePromiseWithResponse(
|
|
38621
|
+
const { data: data2, response: response2, request_id: request_id2 } = await tracePromiseWithResponse(
|
|
37801
38622
|
openAIChannels.chatCompletionsCreate,
|
|
37802
38623
|
traceContext,
|
|
37803
38624
|
completionPromise
|
|
37804
38625
|
);
|
|
37805
|
-
return { data: data2, response: response2 };
|
|
38626
|
+
return { data: data2, response: response2, request_id: request_id2 };
|
|
37806
38627
|
}
|
|
37807
|
-
const completionResponse =
|
|
37808
|
-
|
|
37809
|
-
|
|
38628
|
+
const completionResponse = (
|
|
38629
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38630
|
+
getAPIPromise()
|
|
37810
38631
|
);
|
|
37811
|
-
const { data, response } = await tracePromiseWithResponse(
|
|
38632
|
+
const { data, response, request_id } = await tracePromiseWithResponse(
|
|
37812
38633
|
openAIChannels.chatCompletionsCreate,
|
|
37813
38634
|
traceContext,
|
|
37814
38635
|
completionResponse
|
|
37815
38636
|
);
|
|
37816
|
-
return { data, response };
|
|
38637
|
+
return { data, response, request_id };
|
|
37817
38638
|
})();
|
|
37818
38639
|
}
|
|
37819
38640
|
return executionPromise;
|
|
37820
38641
|
};
|
|
37821
|
-
return createLazyAPIPromise(
|
|
38642
|
+
return createLazyAPIPromise(
|
|
38643
|
+
ensureExecuted,
|
|
38644
|
+
() => tracePromiseAsResponse(
|
|
38645
|
+
openAIChannels.chatCompletionsCreate,
|
|
38646
|
+
createChannelContext(
|
|
38647
|
+
openAIChannels.chatCompletionsCreate,
|
|
38648
|
+
params,
|
|
38649
|
+
span_info
|
|
38650
|
+
),
|
|
38651
|
+
getAPIPromise()
|
|
38652
|
+
),
|
|
38653
|
+
getAPIPromise
|
|
38654
|
+
);
|
|
37822
38655
|
};
|
|
37823
38656
|
}
|
|
37824
38657
|
function createEndpointProxy(target, wrapperFn) {
|
|
@@ -37836,6 +38669,11 @@ function wrapApiCreateWithChannel(create, channel2) {
|
|
|
37836
38669
|
return (allParams, options) => {
|
|
37837
38670
|
const { span_info, params } = splitSpanInfo(allParams);
|
|
37838
38671
|
let executionPromise = null;
|
|
38672
|
+
let apiPromise = null;
|
|
38673
|
+
const getAPIPromise = () => {
|
|
38674
|
+
apiPromise ??= create(params, options);
|
|
38675
|
+
return apiPromise;
|
|
38676
|
+
};
|
|
37839
38677
|
const ensureExecuted = () => {
|
|
37840
38678
|
if (!executionPromise) {
|
|
37841
38679
|
executionPromise = (async () => {
|
|
@@ -37843,13 +38681,21 @@ function wrapApiCreateWithChannel(create, channel2) {
|
|
|
37843
38681
|
return tracePromiseWithResponse(
|
|
37844
38682
|
channel2,
|
|
37845
38683
|
traceContext,
|
|
37846
|
-
|
|
38684
|
+
getAPIPromise()
|
|
37847
38685
|
);
|
|
37848
38686
|
})();
|
|
37849
38687
|
}
|
|
37850
38688
|
return executionPromise;
|
|
37851
38689
|
};
|
|
37852
|
-
return createLazyAPIPromise(
|
|
38690
|
+
return createLazyAPIPromise(
|
|
38691
|
+
ensureExecuted,
|
|
38692
|
+
() => tracePromiseAsResponse(
|
|
38693
|
+
channel2,
|
|
38694
|
+
createChannelContext(channel2, params, span_info),
|
|
38695
|
+
getAPIPromise()
|
|
38696
|
+
),
|
|
38697
|
+
getAPIPromise
|
|
38698
|
+
);
|
|
37853
38699
|
};
|
|
37854
38700
|
}
|
|
37855
38701
|
var wrapEmbeddings = (create) => wrapApiCreateWithChannel(create, openAIChannels.embeddingsCreate);
|
|
@@ -40544,7 +41390,15 @@ var MAX_EVE_PROVIDER_CACHE_ENTRIES = 1e4;
|
|
|
40544
41390
|
function createEveInstrumentationProvider(options = {}) {
|
|
40545
41391
|
const bridge = new EveProviderBridge(options.metadata);
|
|
40546
41392
|
return {
|
|
41393
|
+
// Eve versions before tracePolicy use capture to decide whether provider
|
|
41394
|
+
// events include content. Newer versions prefer tracePolicy when both are
|
|
41395
|
+
// present, so keep the deprecated field for backwards compatibility.
|
|
40547
41396
|
capture: "content",
|
|
41397
|
+
tracePolicy: () => ({
|
|
41398
|
+
emit: true,
|
|
41399
|
+
recordInputs: true,
|
|
41400
|
+
recordOutputs: true
|
|
41401
|
+
}),
|
|
40548
41402
|
events: {
|
|
40549
41403
|
"action.completed": (event, context) => bridge.handleActionTerminal(event, context),
|
|
40550
41404
|
"action.failed": (event, context) => bridge.handleActionTerminal(event, context),
|
|
@@ -44152,8 +45006,8 @@ function normalizeScores(result) {
|
|
|
44152
45006
|
(s) => s !== null && s !== void 0 && typeof s === "object" && isScore(s)
|
|
44153
45007
|
);
|
|
44154
45008
|
}
|
|
44155
|
-
if (typeof result === "object" && result !== null &&
|
|
44156
|
-
return [result];
|
|
45009
|
+
if (typeof result === "object" && result !== null && "score" in result) {
|
|
45010
|
+
return [{ ...result, name: result.name ?? "score" }];
|
|
44157
45011
|
}
|
|
44158
45012
|
return [];
|
|
44159
45013
|
}
|
|
@@ -44973,7 +45827,7 @@ function isAsync(fn) {
|
|
|
44973
45827
|
function isAsyncGenerator2(fn) {
|
|
44974
45828
|
return fn[Symbol.toStringTag] === "AsyncGenerator";
|
|
44975
45829
|
}
|
|
44976
|
-
function
|
|
45830
|
+
function isAsyncIterable6(obj) {
|
|
44977
45831
|
return typeof obj[Symbol.asyncIterator] === "function";
|
|
44978
45832
|
}
|
|
44979
45833
|
function wrapAsync(asyncFn) {
|
|
@@ -45145,7 +45999,7 @@ var eachOfLimit$2 = (limit) => {
|
|
|
45145
45999
|
if (isAsyncGenerator2(obj)) {
|
|
45146
46000
|
return asyncEachOfLimit(obj, limit, iteratee, callback);
|
|
45147
46001
|
}
|
|
45148
|
-
if (
|
|
46002
|
+
if (isAsyncIterable6(obj)) {
|
|
45149
46003
|
return asyncEachOfLimit(obj[Symbol.asyncIterator](), limit, iteratee, callback);
|
|
45150
46004
|
}
|
|
45151
46005
|
var nextElem = createIterator(obj);
|
|
@@ -46500,7 +47354,7 @@ function callEvaluatorData(data) {
|
|
|
46500
47354
|
baseExperiment
|
|
46501
47355
|
};
|
|
46502
47356
|
}
|
|
46503
|
-
function
|
|
47357
|
+
function isAsyncIterable7(value) {
|
|
46504
47358
|
return typeof value === "object" && value !== null && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
46505
47359
|
}
|
|
46506
47360
|
function isIterable(value) {
|
|
@@ -46535,7 +47389,7 @@ async function _internalResolveEvaluatorData(evaluator, experiment) {
|
|
|
46535
47389
|
}).asDataset();
|
|
46536
47390
|
}
|
|
46537
47391
|
const resolvedDataResult = dataResult instanceof Promise ? await dataResult : dataResult;
|
|
46538
|
-
if (
|
|
47392
|
+
if (isAsyncIterable7(resolvedDataResult)) {
|
|
46539
47393
|
return resolvedDataResult;
|
|
46540
47394
|
}
|
|
46541
47395
|
if (Array.isArray(resolvedDataResult) || isIterable(resolvedDataResult)) {
|
|
@@ -46736,19 +47590,29 @@ function buildSpanScores(results) {
|
|
|
46736
47590
|
function _internalPrepareEvaluatorScore(scoreValue, name) {
|
|
46737
47591
|
if (scoreValue === null) return { results: null };
|
|
46738
47592
|
if (Array.isArray(scoreValue)) {
|
|
47593
|
+
const names = /* @__PURE__ */ new Set();
|
|
46739
47594
|
for (const score of scoreValue) {
|
|
46740
47595
|
if (!(typeof score === "object" && !isEmpty2(score))) {
|
|
46741
47596
|
throw new Error(
|
|
46742
47597
|
`When returning an array of scores, each score must be a non-empty object. Got: ${JSON.stringify(score)}`
|
|
46743
47598
|
);
|
|
46744
47599
|
}
|
|
47600
|
+
if (typeof score.name !== "string") {
|
|
47601
|
+
throw new Error(
|
|
47602
|
+
`When returning an array of scores, each score must have a name. Got: ${JSON.stringify(score)}`
|
|
47603
|
+
);
|
|
47604
|
+
}
|
|
47605
|
+
if (names.has(score.name)) {
|
|
47606
|
+
throw new Error(`Duplicate score name '${score.name}' in score array`);
|
|
47607
|
+
}
|
|
47608
|
+
names.add(score.name);
|
|
46745
47609
|
}
|
|
46746
47610
|
}
|
|
46747
47611
|
let results;
|
|
46748
47612
|
if (Array.isArray(scoreValue)) {
|
|
46749
47613
|
results = scoreValue;
|
|
46750
47614
|
} else if (typeof scoreValue === "object" && !isEmpty2(scoreValue)) {
|
|
46751
|
-
results = [scoreValue];
|
|
47615
|
+
results = [{ ...scoreValue, name: scoreValue.name ?? name }];
|
|
46752
47616
|
} else {
|
|
46753
47617
|
results = [{ name, score: scoreValue }];
|
|
46754
47618
|
}
|
|
@@ -49583,6 +50447,7 @@ export {
|
|
|
49583
50447
|
braintrustStreamChunkSchema,
|
|
49584
50448
|
buildLocalSummary,
|
|
49585
50449
|
collectAnthropicSession,
|
|
50450
|
+
completeOpenAIBatchTrace,
|
|
49586
50451
|
configureInstrumentation,
|
|
49587
50452
|
constructLogs3OverflowRequest,
|
|
49588
50453
|
createFinalValuePassThroughStream,
|
|
@@ -49622,6 +50487,8 @@ export {
|
|
|
49622
50487
|
loginToState,
|
|
49623
50488
|
logs3OverflowUploadSchema,
|
|
49624
50489
|
newId,
|
|
50490
|
+
openaiBatchesRetrieveTraced,
|
|
50491
|
+
openaiFilesCreateTraced,
|
|
49625
50492
|
parseCachedHeader,
|
|
49626
50493
|
parseTemplateFormat,
|
|
49627
50494
|
permalink,
|