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/browser.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,
|
|
@@ -13390,6 +13401,131 @@ function unsubscribeAll(unsubscribers) {
|
|
|
13390
13401
|
return [];
|
|
13391
13402
|
}
|
|
13392
13403
|
|
|
13404
|
+
// src/instrumentation/core/channel-definitions.ts
|
|
13405
|
+
function channel(spec) {
|
|
13406
|
+
return spec;
|
|
13407
|
+
}
|
|
13408
|
+
function defineChannels(pkg, channels, options) {
|
|
13409
|
+
const { instrumentationName } = options;
|
|
13410
|
+
return Object.fromEntries(
|
|
13411
|
+
Object.entries(channels).map(([key, spec]) => {
|
|
13412
|
+
const fullChannelName = `orchestrion:${pkg}:${spec.channelName}`;
|
|
13413
|
+
if (spec.kind === "async") {
|
|
13414
|
+
const asyncSpec = spec;
|
|
13415
|
+
const tracingChannel2 = () => isomorph_default.newTracingChannel(
|
|
13416
|
+
fullChannelName
|
|
13417
|
+
);
|
|
13418
|
+
const intercept2 = (interceptor) => {
|
|
13419
|
+
const hook = tracingChannel2();
|
|
13420
|
+
return typeof hook.intercept === "function" ? hook.intercept(interceptor) : () => {
|
|
13421
|
+
};
|
|
13422
|
+
};
|
|
13423
|
+
return [
|
|
13424
|
+
key,
|
|
13425
|
+
{
|
|
13426
|
+
...asyncSpec,
|
|
13427
|
+
instrumentationName,
|
|
13428
|
+
intercept: intercept2,
|
|
13429
|
+
invoke: (target, thisArg, args, additional) => {
|
|
13430
|
+
const hook = tracingChannel2();
|
|
13431
|
+
return typeof hook.invoke === "function" ? hook.invoke(target, thisArg, args, additional) : Reflect.apply(target, thisArg, args);
|
|
13432
|
+
},
|
|
13433
|
+
tracingChannel: tracingChannel2,
|
|
13434
|
+
tracePromise: (fn, context) => tracingChannel2().tracePromise(
|
|
13435
|
+
fn,
|
|
13436
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
13437
|
+
context
|
|
13438
|
+
)
|
|
13439
|
+
}
|
|
13440
|
+
];
|
|
13441
|
+
}
|
|
13442
|
+
const syncSpec = spec;
|
|
13443
|
+
const tracingChannel = () => isomorph_default.newTracingChannel(
|
|
13444
|
+
fullChannelName
|
|
13445
|
+
);
|
|
13446
|
+
const intercept = (interceptor) => {
|
|
13447
|
+
const hook = tracingChannel();
|
|
13448
|
+
return typeof hook.intercept === "function" ? hook.intercept(interceptor) : () => {
|
|
13449
|
+
};
|
|
13450
|
+
};
|
|
13451
|
+
return [
|
|
13452
|
+
key,
|
|
13453
|
+
{
|
|
13454
|
+
...syncSpec,
|
|
13455
|
+
instrumentationName,
|
|
13456
|
+
intercept,
|
|
13457
|
+
invoke: (target, thisArg, args, additional) => {
|
|
13458
|
+
const hook = tracingChannel();
|
|
13459
|
+
return typeof hook.invoke === "function" ? hook.invoke(target, thisArg, args, additional) : Reflect.apply(target, thisArg, args);
|
|
13460
|
+
},
|
|
13461
|
+
tracingChannel,
|
|
13462
|
+
traceSync: (fn, context) => tracingChannel().traceSync(
|
|
13463
|
+
fn,
|
|
13464
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
13465
|
+
context
|
|
13466
|
+
)
|
|
13467
|
+
}
|
|
13468
|
+
];
|
|
13469
|
+
})
|
|
13470
|
+
);
|
|
13471
|
+
}
|
|
13472
|
+
|
|
13473
|
+
// src/instrumentation/plugins/openai-channels.ts
|
|
13474
|
+
var openAIChannels = defineChannels(
|
|
13475
|
+
"openai",
|
|
13476
|
+
{
|
|
13477
|
+
filesCreateTraced: channel({
|
|
13478
|
+
channelName: "files.create-traced",
|
|
13479
|
+
kind: "async"
|
|
13480
|
+
}),
|
|
13481
|
+
batchesRetrieveTraced: channel({
|
|
13482
|
+
channelName: "batches.retrieve-traced",
|
|
13483
|
+
kind: "async"
|
|
13484
|
+
}),
|
|
13485
|
+
batchesCompleteTrace: channel({
|
|
13486
|
+
channelName: "batches.complete-trace",
|
|
13487
|
+
kind: "async"
|
|
13488
|
+
}),
|
|
13489
|
+
chatCompletionsCreate: channel({
|
|
13490
|
+
channelName: "chat.completions.create",
|
|
13491
|
+
kind: "async"
|
|
13492
|
+
}),
|
|
13493
|
+
embeddingsCreate: channel({
|
|
13494
|
+
channelName: "embeddings.create",
|
|
13495
|
+
kind: "async"
|
|
13496
|
+
}),
|
|
13497
|
+
betaChatCompletionsParse: channel({
|
|
13498
|
+
channelName: "beta.chat.completions.parse",
|
|
13499
|
+
kind: "async"
|
|
13500
|
+
}),
|
|
13501
|
+
betaChatCompletionsStream: channel({
|
|
13502
|
+
channelName: "beta.chat.completions.stream",
|
|
13503
|
+
kind: "sync-stream"
|
|
13504
|
+
}),
|
|
13505
|
+
moderationsCreate: channel({
|
|
13506
|
+
channelName: "moderations.create",
|
|
13507
|
+
kind: "async"
|
|
13508
|
+
}),
|
|
13509
|
+
responsesCreate: channel({
|
|
13510
|
+
channelName: "responses.create",
|
|
13511
|
+
kind: "async"
|
|
13512
|
+
}),
|
|
13513
|
+
responsesStream: channel({
|
|
13514
|
+
channelName: "responses.stream",
|
|
13515
|
+
kind: "sync-stream"
|
|
13516
|
+
}),
|
|
13517
|
+
responsesParse: channel({
|
|
13518
|
+
channelName: "responses.parse",
|
|
13519
|
+
kind: "async"
|
|
13520
|
+
}),
|
|
13521
|
+
responsesCompact: channel({
|
|
13522
|
+
channelName: "responses.compact",
|
|
13523
|
+
kind: "async"
|
|
13524
|
+
})
|
|
13525
|
+
},
|
|
13526
|
+
{ instrumentationName: INSTRUMENTATION_NAMES.OPENAI }
|
|
13527
|
+
);
|
|
13528
|
+
|
|
13393
13529
|
// src/wrappers/attachment-utils.ts
|
|
13394
13530
|
function getExtensionFromMediaType(mediaType) {
|
|
13395
13531
|
const extensionMap = {
|
|
@@ -13565,118 +13701,91 @@ function processInputAttachments(input) {
|
|
|
13565
13701
|
return processNode(input);
|
|
13566
13702
|
}
|
|
13567
13703
|
|
|
13568
|
-
// src/instrumentation/
|
|
13569
|
-
|
|
13570
|
-
|
|
13571
|
-
|
|
13572
|
-
|
|
13573
|
-
|
|
13574
|
-
|
|
13575
|
-
|
|
13576
|
-
|
|
13577
|
-
|
|
13578
|
-
|
|
13579
|
-
|
|
13580
|
-
|
|
13581
|
-
|
|
13582
|
-
|
|
13583
|
-
|
|
13584
|
-
|
|
13585
|
-
|
|
13586
|
-
|
|
13587
|
-
|
|
13588
|
-
|
|
13589
|
-
|
|
13590
|
-
...asyncSpec,
|
|
13591
|
-
instrumentationName,
|
|
13592
|
-
intercept: intercept2,
|
|
13593
|
-
invoke: (target, thisArg, args, additional) => {
|
|
13594
|
-
const hook = tracingChannel2();
|
|
13595
|
-
return typeof hook.invoke === "function" ? hook.invoke(target, thisArg, args, additional) : Reflect.apply(target, thisArg, args);
|
|
13596
|
-
},
|
|
13597
|
-
tracingChannel: tracingChannel2,
|
|
13598
|
-
tracePromise: (fn, context) => tracingChannel2().tracePromise(
|
|
13599
|
-
fn,
|
|
13600
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
13601
|
-
context
|
|
13602
|
-
)
|
|
13603
|
-
}
|
|
13604
|
-
];
|
|
13704
|
+
// src/instrumentation/plugins/openai-span-data.ts
|
|
13705
|
+
var OPENAI_METADATA_KEYS = [
|
|
13706
|
+
"model",
|
|
13707
|
+
"temperature",
|
|
13708
|
+
"top_p",
|
|
13709
|
+
"max_tokens",
|
|
13710
|
+
"frequency_penalty",
|
|
13711
|
+
"presence_penalty",
|
|
13712
|
+
"stop",
|
|
13713
|
+
"response_format",
|
|
13714
|
+
"tools",
|
|
13715
|
+
"tool_choice",
|
|
13716
|
+
"parallel_tool_calls",
|
|
13717
|
+
"max_tool_calls"
|
|
13718
|
+
];
|
|
13719
|
+
function batchMetadata(params) {
|
|
13720
|
+
const metadata = { provider: "openai" };
|
|
13721
|
+
for (const key of OPENAI_METADATA_KEYS) {
|
|
13722
|
+
try {
|
|
13723
|
+
const value = Reflect.get(params, key);
|
|
13724
|
+
if (value !== void 0) {
|
|
13725
|
+
metadata[key] = value;
|
|
13605
13726
|
}
|
|
13606
|
-
|
|
13607
|
-
|
|
13608
|
-
|
|
13609
|
-
|
|
13610
|
-
|
|
13611
|
-
|
|
13612
|
-
|
|
13613
|
-
|
|
13614
|
-
|
|
13615
|
-
|
|
13616
|
-
|
|
13617
|
-
|
|
13618
|
-
|
|
13619
|
-
|
|
13620
|
-
|
|
13621
|
-
|
|
13622
|
-
|
|
13623
|
-
|
|
13624
|
-
|
|
13625
|
-
|
|
13626
|
-
|
|
13627
|
-
|
|
13628
|
-
|
|
13629
|
-
|
|
13630
|
-
|
|
13631
|
-
|
|
13632
|
-
|
|
13633
|
-
|
|
13634
|
-
|
|
13727
|
+
} catch {
|
|
13728
|
+
}
|
|
13729
|
+
}
|
|
13730
|
+
return metadata;
|
|
13731
|
+
}
|
|
13732
|
+
function extractOpenAIBatchInput(endpoint, params) {
|
|
13733
|
+
const input = endpoint === "/v1/chat/completions" ? params.messages : params.input;
|
|
13734
|
+
return {
|
|
13735
|
+
input: processInputAttachments(input),
|
|
13736
|
+
metadata: batchMetadata(params)
|
|
13737
|
+
};
|
|
13738
|
+
}
|
|
13739
|
+
function extractOpenAIChatInput(params) {
|
|
13740
|
+
const { messages, ...metadata } = params;
|
|
13741
|
+
return {
|
|
13742
|
+
input: processInputAttachments(messages),
|
|
13743
|
+
metadata: { ...metadata, provider: "openai" }
|
|
13744
|
+
};
|
|
13745
|
+
}
|
|
13746
|
+
function extractOpenAIResponsesInput(params) {
|
|
13747
|
+
const { input, ...metadata } = params;
|
|
13748
|
+
return {
|
|
13749
|
+
input: processInputAttachments(input),
|
|
13750
|
+
metadata: { ...metadata, provider: "openai" }
|
|
13751
|
+
};
|
|
13752
|
+
}
|
|
13753
|
+
function extractOpenAIResponsesMetadata(result) {
|
|
13754
|
+
if (!result) {
|
|
13755
|
+
return void 0;
|
|
13756
|
+
}
|
|
13757
|
+
const { output: _output, usage: _usage, ...metadata } = result;
|
|
13758
|
+
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
13759
|
+
}
|
|
13760
|
+
function processImagesInOutput(output) {
|
|
13761
|
+
if (Array.isArray(output)) {
|
|
13762
|
+
return output.map(processImagesInOutput);
|
|
13763
|
+
}
|
|
13764
|
+
if (isObject(output) && output.type === "image_generation_call" && typeof output.result === "string" && output.result) {
|
|
13765
|
+
const fileExtension = output.output_format || "png";
|
|
13766
|
+
const contentType = `image/${fileExtension}`;
|
|
13767
|
+
const baseFilename = typeof output.revised_prompt === "string" ? output.revised_prompt.slice(0, 50).replace(/[^a-zA-Z0-9]/g, "_") : "generated_image";
|
|
13768
|
+
let binaryString;
|
|
13769
|
+
try {
|
|
13770
|
+
binaryString = atob(output.result);
|
|
13771
|
+
} catch {
|
|
13772
|
+
return output;
|
|
13773
|
+
}
|
|
13774
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
13775
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
13776
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
13777
|
+
}
|
|
13778
|
+
return {
|
|
13779
|
+
...output,
|
|
13780
|
+
result: new Attachment({
|
|
13781
|
+
data: new Blob([bytes], { type: contentType }),
|
|
13782
|
+
filename: `${baseFilename}.${fileExtension}`,
|
|
13783
|
+
contentType
|
|
13784
|
+
})
|
|
13785
|
+
};
|
|
13786
|
+
}
|
|
13787
|
+
return output;
|
|
13635
13788
|
}
|
|
13636
|
-
|
|
13637
|
-
// src/instrumentation/plugins/openai-channels.ts
|
|
13638
|
-
var openAIChannels = defineChannels(
|
|
13639
|
-
"openai",
|
|
13640
|
-
{
|
|
13641
|
-
chatCompletionsCreate: channel({
|
|
13642
|
-
channelName: "chat.completions.create",
|
|
13643
|
-
kind: "async"
|
|
13644
|
-
}),
|
|
13645
|
-
embeddingsCreate: channel({
|
|
13646
|
-
channelName: "embeddings.create",
|
|
13647
|
-
kind: "async"
|
|
13648
|
-
}),
|
|
13649
|
-
betaChatCompletionsParse: channel({
|
|
13650
|
-
channelName: "beta.chat.completions.parse",
|
|
13651
|
-
kind: "async"
|
|
13652
|
-
}),
|
|
13653
|
-
betaChatCompletionsStream: channel({
|
|
13654
|
-
channelName: "beta.chat.completions.stream",
|
|
13655
|
-
kind: "sync-stream"
|
|
13656
|
-
}),
|
|
13657
|
-
moderationsCreate: channel({
|
|
13658
|
-
channelName: "moderations.create",
|
|
13659
|
-
kind: "async"
|
|
13660
|
-
}),
|
|
13661
|
-
responsesCreate: channel({
|
|
13662
|
-
channelName: "responses.create",
|
|
13663
|
-
kind: "async"
|
|
13664
|
-
}),
|
|
13665
|
-
responsesStream: channel({
|
|
13666
|
-
channelName: "responses.stream",
|
|
13667
|
-
kind: "sync-stream"
|
|
13668
|
-
}),
|
|
13669
|
-
responsesParse: channel({
|
|
13670
|
-
channelName: "responses.parse",
|
|
13671
|
-
kind: "async"
|
|
13672
|
-
}),
|
|
13673
|
-
responsesCompact: channel({
|
|
13674
|
-
channelName: "responses.compact",
|
|
13675
|
-
kind: "async"
|
|
13676
|
-
})
|
|
13677
|
-
},
|
|
13678
|
-
{ instrumentationName: INSTRUMENTATION_NAMES.OPENAI }
|
|
13679
|
-
);
|
|
13680
13789
|
|
|
13681
13790
|
// src/openai-utils.ts
|
|
13682
13791
|
var BRAINTRUST_CACHED_STREAM_METRIC = "__braintrust_cached_metric";
|
|
@@ -13733,23 +13842,573 @@ function getCachedMetricFromHeaders(headers) {
|
|
|
13733
13842
|
return parseCachedHeader(headers.get(LEGACY_CACHED_HEADER));
|
|
13734
13843
|
}
|
|
13735
13844
|
|
|
13845
|
+
// src/instrumentation/plugins/openai-batch-instrumentation.ts
|
|
13846
|
+
var SUPPORTED_ENDPOINTS = /* @__PURE__ */ new Set(["/v1/chat/completions", "/v1/responses"]);
|
|
13847
|
+
var TERMINAL_STATUSES = /* @__PURE__ */ new Set([
|
|
13848
|
+
"completed",
|
|
13849
|
+
"failed",
|
|
13850
|
+
"expired",
|
|
13851
|
+
"cancelled"
|
|
13852
|
+
]);
|
|
13853
|
+
var pendingBatchTraces = /* @__PURE__ */ new Map();
|
|
13854
|
+
function read(value, key) {
|
|
13855
|
+
if (!isObject(value)) {
|
|
13856
|
+
return void 0;
|
|
13857
|
+
}
|
|
13858
|
+
try {
|
|
13859
|
+
return Reflect.get(value, key);
|
|
13860
|
+
} catch {
|
|
13861
|
+
return void 0;
|
|
13862
|
+
}
|
|
13863
|
+
}
|
|
13864
|
+
function isBatchRecordIterable(value) {
|
|
13865
|
+
if (value === null || typeof value !== "object" && typeof value !== "function") {
|
|
13866
|
+
return false;
|
|
13867
|
+
}
|
|
13868
|
+
return typeof read(value, Symbol.iterator) === "function" || typeof read(value, Symbol.asyncIterator) === "function";
|
|
13869
|
+
}
|
|
13870
|
+
function validCustomId(value) {
|
|
13871
|
+
return typeof value === "string" && value.length > 0 && value.length <= 64;
|
|
13872
|
+
}
|
|
13873
|
+
function logBatchInstrumentationError(context, error) {
|
|
13874
|
+
debugLogger.debug(`OpenAI Batch instrumentation ${context}:`, error);
|
|
13875
|
+
}
|
|
13876
|
+
async function exportParent(parent) {
|
|
13877
|
+
if ("toStr" in parent && typeof parent.toStr === "function") {
|
|
13878
|
+
return parent.toStr();
|
|
13879
|
+
}
|
|
13880
|
+
if ("export" in parent && typeof parent.export === "function") {
|
|
13881
|
+
return await parent.export();
|
|
13882
|
+
}
|
|
13883
|
+
return void 0;
|
|
13884
|
+
}
|
|
13885
|
+
async function deterministicDigest(namespace, ...parts) {
|
|
13886
|
+
const encoded = new TextEncoder().encode(
|
|
13887
|
+
[namespace, ...parts].map((part) => `${part.length}:${part}`).join("\0")
|
|
13888
|
+
);
|
|
13889
|
+
return new Uint8Array(
|
|
13890
|
+
await globalThis.crypto.subtle.digest("SHA-256", encoded)
|
|
13891
|
+
);
|
|
13892
|
+
}
|
|
13893
|
+
function digestHex(bytes, length) {
|
|
13894
|
+
return Array.from(bytes.slice(0, length)).map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
13895
|
+
}
|
|
13896
|
+
function digestUuid(bytes) {
|
|
13897
|
+
const hex = digestHex(bytes, 16);
|
|
13898
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
13899
|
+
}
|
|
13900
|
+
async function batchSpanIds(inputFileId) {
|
|
13901
|
+
const [row, span, root] = await Promise.all([
|
|
13902
|
+
deterministicDigest("openai:batch:row", inputFileId),
|
|
13903
|
+
deterministicDigest("openai:batch:span", inputFileId),
|
|
13904
|
+
deterministicDigest("openai:batch:root", inputFileId)
|
|
13905
|
+
]);
|
|
13906
|
+
return {
|
|
13907
|
+
rowId: digestUuid(row),
|
|
13908
|
+
spanId: digestHex(span, 8),
|
|
13909
|
+
rootSpanId: digestHex(root, 16)
|
|
13910
|
+
};
|
|
13911
|
+
}
|
|
13912
|
+
async function childSpanIds(inputFileId, customId) {
|
|
13913
|
+
const [row, span] = await Promise.all([
|
|
13914
|
+
deterministicDigest("openai:batch:child:row", inputFileId, customId),
|
|
13915
|
+
deterministicDigest("openai:batch:child:span", inputFileId, customId)
|
|
13916
|
+
]);
|
|
13917
|
+
return { rowId: digestUuid(row), spanId: digestHex(span, 8) };
|
|
13918
|
+
}
|
|
13919
|
+
async function startBatchSpan(context) {
|
|
13920
|
+
const ids = await batchSpanIds(context.inputFileId);
|
|
13921
|
+
const parent = SpanComponentsV4.fromStr(context.parent);
|
|
13922
|
+
const hasParentSpan = Boolean(
|
|
13923
|
+
parent.data.row_id && parent.data.span_id && parent.data.root_span_id
|
|
13924
|
+
);
|
|
13925
|
+
return withCurrent(
|
|
13926
|
+
NOOP_SPAN,
|
|
13927
|
+
() => _internalStartSpanWithInitialMergeAndParentSpanIds(
|
|
13928
|
+
withSpanInstrumentationName(
|
|
13929
|
+
{
|
|
13930
|
+
name: "openai.batch",
|
|
13931
|
+
type: "task" /* TASK */,
|
|
13932
|
+
parent: context.parent,
|
|
13933
|
+
...!hasParentSpan ? {
|
|
13934
|
+
parentSpanIds: {
|
|
13935
|
+
parentSpanIds: [],
|
|
13936
|
+
rootSpanId: ids.rootSpanId
|
|
13937
|
+
}
|
|
13938
|
+
} : {},
|
|
13939
|
+
spanId: ids.spanId,
|
|
13940
|
+
startTime: context.taskStartTime,
|
|
13941
|
+
event: {
|
|
13942
|
+
id: ids.rowId,
|
|
13943
|
+
metadata: {
|
|
13944
|
+
endpoint: context.endpoint,
|
|
13945
|
+
input_file_id: context.inputFileId,
|
|
13946
|
+
provider: "openai"
|
|
13947
|
+
}
|
|
13948
|
+
}
|
|
13949
|
+
},
|
|
13950
|
+
INSTRUMENTATION_NAMES.OPENAI
|
|
13951
|
+
)
|
|
13952
|
+
)
|
|
13953
|
+
);
|
|
13954
|
+
}
|
|
13955
|
+
async function startBatchChild(context, taskParent, input) {
|
|
13956
|
+
const ids = await childSpanIds(context.inputFileId, input.customId);
|
|
13957
|
+
return withCurrent(
|
|
13958
|
+
NOOP_SPAN,
|
|
13959
|
+
() => _internalStartSpanWithInitialMerge(
|
|
13960
|
+
withSpanInstrumentationName(
|
|
13961
|
+
{
|
|
13962
|
+
name: context.endpoint === "/v1/chat/completions" ? "Chat Completion" : "openai.responses.create",
|
|
13963
|
+
type: "llm" /* LLM */,
|
|
13964
|
+
parent: taskParent,
|
|
13965
|
+
spanId: ids.spanId,
|
|
13966
|
+
startTime: context.childStartTime,
|
|
13967
|
+
event: {
|
|
13968
|
+
id: ids.rowId,
|
|
13969
|
+
...input.spanData?.input !== void 0 ? { input: input.spanData.input } : {},
|
|
13970
|
+
metadata: {
|
|
13971
|
+
...input.spanData?.metadata,
|
|
13972
|
+
custom_id: input.customId,
|
|
13973
|
+
provider: "openai"
|
|
13974
|
+
}
|
|
13975
|
+
}
|
|
13976
|
+
},
|
|
13977
|
+
INSTRUMENTATION_NAMES.OPENAI
|
|
13978
|
+
)
|
|
13979
|
+
)
|
|
13980
|
+
);
|
|
13981
|
+
}
|
|
13982
|
+
async function* jsonlRecords(file, onIssue = () => {
|
|
13983
|
+
}) {
|
|
13984
|
+
const resolvedFile = await file;
|
|
13985
|
+
if (typeof resolvedFile === "string") {
|
|
13986
|
+
for (const line of resolvedFile.split("\n")) {
|
|
13987
|
+
if (!line.trim()) {
|
|
13988
|
+
continue;
|
|
13989
|
+
}
|
|
13990
|
+
try {
|
|
13991
|
+
yield JSON.parse(line.replace(/\r$/, ""));
|
|
13992
|
+
} catch (error) {
|
|
13993
|
+
logBatchInstrumentationError("skipped malformed JSONL", error);
|
|
13994
|
+
onIssue(new Error("OpenAI Batch file contains malformed JSONL"));
|
|
13995
|
+
}
|
|
13996
|
+
}
|
|
13997
|
+
return;
|
|
13998
|
+
}
|
|
13999
|
+
const body = read(resolvedFile, "body");
|
|
14000
|
+
const getReader = read(body, "getReader");
|
|
14001
|
+
if (isObject(body) && typeof getReader === "function") {
|
|
14002
|
+
let reader;
|
|
14003
|
+
try {
|
|
14004
|
+
reader = Reflect.apply(getReader, body, []);
|
|
14005
|
+
const decoder2 = new TextDecoder();
|
|
14006
|
+
let pending = "";
|
|
14007
|
+
while (true) {
|
|
14008
|
+
const readChunk = read(reader, "read");
|
|
14009
|
+
if (typeof readChunk !== "function") {
|
|
14010
|
+
throw new Error("Response body stream has no read method");
|
|
14011
|
+
}
|
|
14012
|
+
const chunk = await Reflect.apply(readChunk, reader, []);
|
|
14013
|
+
if (!isObject(chunk)) {
|
|
14014
|
+
throw new Error("Response body stream returned an invalid chunk");
|
|
14015
|
+
}
|
|
14016
|
+
if (chunk.done === true) {
|
|
14017
|
+
pending += decoder2.decode();
|
|
14018
|
+
break;
|
|
14019
|
+
}
|
|
14020
|
+
if (!(chunk.value instanceof Uint8Array)) {
|
|
14021
|
+
throw new Error("Response body stream returned a non-byte chunk");
|
|
14022
|
+
}
|
|
14023
|
+
pending += decoder2.decode(chunk.value, { stream: true });
|
|
14024
|
+
let newline = pending.indexOf("\n");
|
|
14025
|
+
while (newline !== -1) {
|
|
14026
|
+
const line = pending.slice(0, newline).replace(/\r$/, "");
|
|
14027
|
+
pending = pending.slice(newline + 1);
|
|
14028
|
+
if (line.trim()) {
|
|
14029
|
+
try {
|
|
14030
|
+
yield JSON.parse(line);
|
|
14031
|
+
} catch (error) {
|
|
14032
|
+
logBatchInstrumentationError("skipped malformed JSONL", error);
|
|
14033
|
+
onIssue(new Error("OpenAI Batch file contains malformed JSONL"));
|
|
14034
|
+
}
|
|
14035
|
+
}
|
|
14036
|
+
newline = pending.indexOf("\n");
|
|
14037
|
+
}
|
|
14038
|
+
}
|
|
14039
|
+
if (pending.trim()) {
|
|
14040
|
+
try {
|
|
14041
|
+
yield JSON.parse(pending.replace(/\r$/, ""));
|
|
14042
|
+
} catch (error) {
|
|
14043
|
+
logBatchInstrumentationError("skipped malformed JSONL", error);
|
|
14044
|
+
onIssue(new Error("OpenAI Batch file contains malformed JSONL"));
|
|
14045
|
+
}
|
|
14046
|
+
}
|
|
14047
|
+
} catch (error) {
|
|
14048
|
+
logBatchInstrumentationError("could not read JSONL response body", error);
|
|
14049
|
+
onIssue(new Error("OpenAI Batch response body could not be read"));
|
|
14050
|
+
} finally {
|
|
14051
|
+
const releaseLock = read(reader, "releaseLock");
|
|
14052
|
+
if (typeof releaseLock === "function") {
|
|
14053
|
+
try {
|
|
14054
|
+
Reflect.apply(releaseLock, reader, []);
|
|
14055
|
+
} catch (error) {
|
|
14056
|
+
logBatchInstrumentationError(
|
|
14057
|
+
"could not release stream reader",
|
|
14058
|
+
error
|
|
14059
|
+
);
|
|
14060
|
+
}
|
|
14061
|
+
}
|
|
14062
|
+
}
|
|
14063
|
+
return;
|
|
14064
|
+
}
|
|
14065
|
+
if (isBatchRecordIterable(resolvedFile)) {
|
|
14066
|
+
for await (const record of resolvedFile) {
|
|
14067
|
+
yield record;
|
|
14068
|
+
}
|
|
14069
|
+
return;
|
|
14070
|
+
}
|
|
14071
|
+
logBatchInstrumentationError("skipped invalid JSONL source", resolvedFile);
|
|
14072
|
+
onIssue(new Error("OpenAI Batch file source is invalid"));
|
|
14073
|
+
}
|
|
14074
|
+
async function readBatchInputs(file) {
|
|
14075
|
+
const inputs = /* @__PURE__ */ new Map();
|
|
14076
|
+
const issues = [];
|
|
14077
|
+
let endpoint;
|
|
14078
|
+
try {
|
|
14079
|
+
for await (const value of jsonlRecords(
|
|
14080
|
+
file,
|
|
14081
|
+
(issue) => issues.push(issue)
|
|
14082
|
+
)) {
|
|
14083
|
+
const customId = read(value, "custom_id");
|
|
14084
|
+
const url = read(value, "url");
|
|
14085
|
+
const body = read(value, "body");
|
|
14086
|
+
if (!validCustomId(customId) || inputs.has(customId) || read(value, "method") !== "POST" || typeof url !== "string" || !SUPPORTED_ENDPOINTS.has(url) || endpoint !== void 0 && endpoint !== url || !isObject(body)) {
|
|
14087
|
+
issues.push(new Error("OpenAI Batch input contains an invalid record"));
|
|
14088
|
+
continue;
|
|
14089
|
+
}
|
|
14090
|
+
endpoint = url;
|
|
14091
|
+
let spanData;
|
|
14092
|
+
try {
|
|
14093
|
+
spanData = extractOpenAIBatchInput(url, body);
|
|
14094
|
+
} catch (error) {
|
|
14095
|
+
logBatchInstrumentationError("could not extract batch input", error);
|
|
14096
|
+
}
|
|
14097
|
+
inputs.set(customId, { customId, spanData });
|
|
14098
|
+
}
|
|
14099
|
+
} catch (error) {
|
|
14100
|
+
logBatchInstrumentationError("could not process input file", error);
|
|
14101
|
+
issues.push(new Error("OpenAI Batch input file could not be processed"));
|
|
14102
|
+
}
|
|
14103
|
+
if (!endpoint || inputs.size === 0) {
|
|
14104
|
+
issues.push(new Error("OpenAI Batch input contains no supported records"));
|
|
14105
|
+
}
|
|
14106
|
+
return { endpoint, inputs, issues };
|
|
14107
|
+
}
|
|
14108
|
+
async function writePendingSpans(trace, endTime) {
|
|
14109
|
+
const task = await startBatchSpan(trace.context);
|
|
14110
|
+
const taskParent = await task.export();
|
|
14111
|
+
for (const input of trace.inputs.values()) {
|
|
14112
|
+
try {
|
|
14113
|
+
const child = await startBatchChild(trace.context, taskParent, input);
|
|
14114
|
+
if (endTime !== void 0) {
|
|
14115
|
+
child.end({ endTime });
|
|
14116
|
+
}
|
|
14117
|
+
} catch (error) {
|
|
14118
|
+
logBatchInstrumentationError("could not write batch request span", error);
|
|
14119
|
+
}
|
|
14120
|
+
}
|
|
14121
|
+
if (endTime !== void 0) {
|
|
14122
|
+
if (trace.status && trace.status !== "completed") {
|
|
14123
|
+
task.log({ error: new Error(`OpenAI Batch ${trace.status}`) });
|
|
14124
|
+
}
|
|
14125
|
+
task.end({ endTime });
|
|
14126
|
+
}
|
|
14127
|
+
}
|
|
14128
|
+
var interceptOpenAIFilesCreateTraced = async (target, thisArg, args) => {
|
|
14129
|
+
const startTime = getCurrentUnixTimestamp();
|
|
14130
|
+
const inputPromise = readBatchInputs(args[0].inputFileContent);
|
|
14131
|
+
const parentPromise = exportParent(args[0].parent);
|
|
14132
|
+
const file = await Reflect.apply(target, thisArg, args);
|
|
14133
|
+
try {
|
|
14134
|
+
const inputFileId = read(file, "id");
|
|
14135
|
+
const [inputData, exportedParent2] = await Promise.all([
|
|
14136
|
+
inputPromise,
|
|
14137
|
+
parentPromise
|
|
14138
|
+
]);
|
|
14139
|
+
if (typeof inputFileId !== "string" || !exportedParent2 || !inputData.endpoint || inputData.issues.length > 0) {
|
|
14140
|
+
if (inputData.issues[0]) {
|
|
14141
|
+
logBatchInstrumentationError(
|
|
14142
|
+
"skipped invalid input file",
|
|
14143
|
+
inputData.issues[0]
|
|
14144
|
+
);
|
|
14145
|
+
}
|
|
14146
|
+
return file;
|
|
14147
|
+
}
|
|
14148
|
+
const trace = {
|
|
14149
|
+
context: {
|
|
14150
|
+
inputFileId,
|
|
14151
|
+
endpoint: inputData.endpoint,
|
|
14152
|
+
parent: exportedParent2,
|
|
14153
|
+
taskStartTime: startTime,
|
|
14154
|
+
childStartTime: startTime
|
|
14155
|
+
},
|
|
14156
|
+
inputs: inputData.inputs
|
|
14157
|
+
};
|
|
14158
|
+
pendingBatchTraces.set(inputFileId, trace);
|
|
14159
|
+
await writePendingSpans(trace);
|
|
14160
|
+
} catch (error) {
|
|
14161
|
+
logBatchInstrumentationError("could not start batch spans", error);
|
|
14162
|
+
}
|
|
14163
|
+
return file;
|
|
14164
|
+
};
|
|
14165
|
+
function validTimestamp(value) {
|
|
14166
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0;
|
|
14167
|
+
}
|
|
14168
|
+
function terminalEndTime(batch, startTime) {
|
|
14169
|
+
let timestamp;
|
|
14170
|
+
switch (batch.status) {
|
|
14171
|
+
case "completed":
|
|
14172
|
+
timestamp = batch.completed_at;
|
|
14173
|
+
break;
|
|
14174
|
+
case "failed":
|
|
14175
|
+
timestamp = batch.failed_at;
|
|
14176
|
+
break;
|
|
14177
|
+
case "expired":
|
|
14178
|
+
timestamp = batch.expired_at;
|
|
14179
|
+
break;
|
|
14180
|
+
default:
|
|
14181
|
+
timestamp = batch.cancelled_at;
|
|
14182
|
+
}
|
|
14183
|
+
return validTimestamp(timestamp) ? Math.max(timestamp, startTime) : Math.max(getCurrentUnixTimestamp(), startTime);
|
|
14184
|
+
}
|
|
14185
|
+
async function updateBatchTimestamps(batch) {
|
|
14186
|
+
const trace = pendingBatchTraces.get(batch.input_file_id);
|
|
14187
|
+
if (!trace || trace.context.endpoint !== batch.endpoint) {
|
|
14188
|
+
return;
|
|
14189
|
+
}
|
|
14190
|
+
if (validTimestamp(batch.created_at)) {
|
|
14191
|
+
trace.context.taskStartTime = batch.created_at;
|
|
14192
|
+
}
|
|
14193
|
+
trace.context.childStartTime = validTimestamp(batch.in_progress_at) ? Math.max(batch.in_progress_at, trace.context.taskStartTime) : trace.context.taskStartTime;
|
|
14194
|
+
trace.status = batch.status;
|
|
14195
|
+
if (TERMINAL_STATUSES.has(batch.status)) {
|
|
14196
|
+
trace.endTime = terminalEndTime(batch, trace.context.childStartTime);
|
|
14197
|
+
}
|
|
14198
|
+
await writePendingSpans(trace, trace.endTime);
|
|
14199
|
+
}
|
|
14200
|
+
var interceptOpenAIBatchesRetrieveTraced = (target, thisArg, args) => Promise.resolve(Reflect.apply(target, thisArg, args)).then(async (batch) => {
|
|
14201
|
+
try {
|
|
14202
|
+
await updateBatchTimestamps(batch);
|
|
14203
|
+
} catch (error) {
|
|
14204
|
+
logBatchInstrumentationError("could not update batch timestamps", error);
|
|
14205
|
+
}
|
|
14206
|
+
return batch;
|
|
14207
|
+
});
|
|
14208
|
+
function errorFromResult(result) {
|
|
14209
|
+
const error = read(result.value, "error");
|
|
14210
|
+
if (isObject(error)) {
|
|
14211
|
+
const message = read(error, "message");
|
|
14212
|
+
return new Error(
|
|
14213
|
+
typeof message === "string" ? message : "OpenAI Batch request failed"
|
|
14214
|
+
);
|
|
14215
|
+
}
|
|
14216
|
+
const response = read(result.value, "response");
|
|
14217
|
+
const statusCode = read(response, "status_code");
|
|
14218
|
+
if (result.source === "error" || typeof statusCode === "number" && (statusCode < 200 || statusCode >= 300)) {
|
|
14219
|
+
const message = read(read(read(response, "body"), "error"), "message");
|
|
14220
|
+
return new Error(
|
|
14221
|
+
typeof message === "string" ? message : "OpenAI Batch request failed"
|
|
14222
|
+
);
|
|
14223
|
+
}
|
|
14224
|
+
return void 0;
|
|
14225
|
+
}
|
|
14226
|
+
async function completeBatchResult(context, taskParent, endTime, input, result) {
|
|
14227
|
+
const child = await startBatchChild(context, taskParent, input);
|
|
14228
|
+
try {
|
|
14229
|
+
const resultError = errorFromResult(result);
|
|
14230
|
+
const responseBody = read(read(result.value, "response"), "body");
|
|
14231
|
+
if (resultError) {
|
|
14232
|
+
child.log({ error: resultError });
|
|
14233
|
+
} else if (isObject(responseBody)) {
|
|
14234
|
+
const model = read(responseBody, "model");
|
|
14235
|
+
child.log({
|
|
14236
|
+
output: context.endpoint === "/v1/chat/completions" ? read(responseBody, "choices") : processImagesInOutput(read(responseBody, "output")),
|
|
14237
|
+
...typeof model === "string" ? { metadata: { model } } : {},
|
|
14238
|
+
metrics: parseMetricsFromUsage(read(responseBody, "usage"))
|
|
14239
|
+
});
|
|
14240
|
+
} else {
|
|
14241
|
+
child.log({ error: new Error("OpenAI Batch response body is missing") });
|
|
14242
|
+
}
|
|
14243
|
+
} catch (error) {
|
|
14244
|
+
child.log({ error });
|
|
14245
|
+
} finally {
|
|
14246
|
+
child.end({ endTime });
|
|
14247
|
+
}
|
|
14248
|
+
}
|
|
14249
|
+
async function completeResultFile({
|
|
14250
|
+
context,
|
|
14251
|
+
endTime,
|
|
14252
|
+
file,
|
|
14253
|
+
inputs,
|
|
14254
|
+
issues,
|
|
14255
|
+
seen,
|
|
14256
|
+
source,
|
|
14257
|
+
taskParent
|
|
14258
|
+
}) {
|
|
14259
|
+
if (file === void 0) {
|
|
14260
|
+
return;
|
|
14261
|
+
}
|
|
14262
|
+
for await (const value of jsonlRecords(file, (issue) => issues.push(issue))) {
|
|
14263
|
+
const customId = read(value, "custom_id");
|
|
14264
|
+
if (!validCustomId(customId) || !isObject(value)) {
|
|
14265
|
+
issues.push(
|
|
14266
|
+
new Error("OpenAI Batch result is missing a valid custom_id")
|
|
14267
|
+
);
|
|
14268
|
+
continue;
|
|
14269
|
+
}
|
|
14270
|
+
if (seen.has(customId)) {
|
|
14271
|
+
issues.push(new Error("OpenAI Batch result contains a duplicate"));
|
|
14272
|
+
continue;
|
|
14273
|
+
}
|
|
14274
|
+
const input = inputs.get(customId);
|
|
14275
|
+
if (!input) {
|
|
14276
|
+
issues.push(
|
|
14277
|
+
new Error("OpenAI Batch result does not match an input record")
|
|
14278
|
+
);
|
|
14279
|
+
continue;
|
|
14280
|
+
}
|
|
14281
|
+
seen.add(customId);
|
|
14282
|
+
await completeBatchResult(context, taskParent, endTime, input, {
|
|
14283
|
+
value,
|
|
14284
|
+
source
|
|
14285
|
+
});
|
|
14286
|
+
}
|
|
14287
|
+
}
|
|
14288
|
+
function sameInputs(first, second) {
|
|
14289
|
+
return first.size === second.size && [...first.keys()].every((customId) => second.has(customId));
|
|
14290
|
+
}
|
|
14291
|
+
async function contextForCompletion(inputFileId, inputData) {
|
|
14292
|
+
if (!inputData.endpoint || inputData.issues.length > 0) {
|
|
14293
|
+
return void 0;
|
|
14294
|
+
}
|
|
14295
|
+
const existing = pendingBatchTraces.get(inputFileId);
|
|
14296
|
+
if (existing) {
|
|
14297
|
+
if (existing.context.endpoint !== inputData.endpoint || !sameInputs(existing.inputs, inputData.inputs)) {
|
|
14298
|
+
return void 0;
|
|
14299
|
+
}
|
|
14300
|
+
return { ...existing, inputs: inputData.inputs };
|
|
14301
|
+
}
|
|
14302
|
+
const parent = await exportParent(getSpanParentObject());
|
|
14303
|
+
if (!parent) {
|
|
14304
|
+
return void 0;
|
|
14305
|
+
}
|
|
14306
|
+
const startTime = getCurrentUnixTimestamp();
|
|
14307
|
+
return {
|
|
14308
|
+
context: {
|
|
14309
|
+
inputFileId,
|
|
14310
|
+
endpoint: inputData.endpoint,
|
|
14311
|
+
parent,
|
|
14312
|
+
taskStartTime: startTime,
|
|
14313
|
+
childStartTime: startTime
|
|
14314
|
+
},
|
|
14315
|
+
inputs: inputData.inputs
|
|
14316
|
+
};
|
|
14317
|
+
}
|
|
14318
|
+
async function completeBatch(args) {
|
|
14319
|
+
const inputData = await readBatchInputs(args.inputFileContent);
|
|
14320
|
+
const trace = await contextForCompletion(args.inputFileId, inputData);
|
|
14321
|
+
if (!trace) {
|
|
14322
|
+
logBatchInstrumentationError(
|
|
14323
|
+
"left batch spans pending",
|
|
14324
|
+
inputData.issues[0] ?? new Error("OpenAI Batch input does not match")
|
|
14325
|
+
);
|
|
14326
|
+
return;
|
|
14327
|
+
}
|
|
14328
|
+
const endTime = trace.endTime ?? getCurrentUnixTimestamp();
|
|
14329
|
+
const task = await startBatchSpan(trace.context);
|
|
14330
|
+
const taskParent = await task.export();
|
|
14331
|
+
const issues = [];
|
|
14332
|
+
const seen = /* @__PURE__ */ new Set();
|
|
14333
|
+
await Promise.all([
|
|
14334
|
+
completeResultFile({
|
|
14335
|
+
context: trace.context,
|
|
14336
|
+
endTime,
|
|
14337
|
+
file: args.outputFileContent,
|
|
14338
|
+
inputs: trace.inputs,
|
|
14339
|
+
issues,
|
|
14340
|
+
seen,
|
|
14341
|
+
source: "output",
|
|
14342
|
+
taskParent
|
|
14343
|
+
}),
|
|
14344
|
+
completeResultFile({
|
|
14345
|
+
context: trace.context,
|
|
14346
|
+
endTime,
|
|
14347
|
+
file: args.errorFileContent,
|
|
14348
|
+
inputs: trace.inputs,
|
|
14349
|
+
issues,
|
|
14350
|
+
seen,
|
|
14351
|
+
source: "error",
|
|
14352
|
+
taskParent
|
|
14353
|
+
})
|
|
14354
|
+
]);
|
|
14355
|
+
if (issues.length > 0) {
|
|
14356
|
+
logBatchInstrumentationError("left batch spans pending", issues[0]);
|
|
14357
|
+
return;
|
|
14358
|
+
}
|
|
14359
|
+
const missing = [...trace.inputs.values()].filter(
|
|
14360
|
+
({ customId }) => !seen.has(customId)
|
|
14361
|
+
);
|
|
14362
|
+
if (!trace.status || trace.status === "completed") {
|
|
14363
|
+
if (missing.length > 0) {
|
|
14364
|
+
logBatchInstrumentationError(
|
|
14365
|
+
"left batch spans pending",
|
|
14366
|
+
new Error("OpenAI Batch result files are incomplete")
|
|
14367
|
+
);
|
|
14368
|
+
return;
|
|
14369
|
+
}
|
|
14370
|
+
} else {
|
|
14371
|
+
for (const input of missing) {
|
|
14372
|
+
const child = await startBatchChild(trace.context, taskParent, input);
|
|
14373
|
+
child.log({ error: new Error(`OpenAI Batch ${trace.status}`) });
|
|
14374
|
+
child.end({ endTime });
|
|
14375
|
+
}
|
|
14376
|
+
task.log({ error: new Error(`OpenAI Batch ${trace.status}`) });
|
|
14377
|
+
}
|
|
14378
|
+
task.end({ endTime });
|
|
14379
|
+
pendingBatchTraces.delete(args.inputFileId);
|
|
14380
|
+
}
|
|
14381
|
+
var interceptOpenAIBatchTraceComplete = (target, thisArg, args) => Promise.resolve(Reflect.apply(target, thisArg, args)).then(async (result) => {
|
|
14382
|
+
try {
|
|
14383
|
+
await completeBatch(args[0]);
|
|
14384
|
+
} catch (error) {
|
|
14385
|
+
logBatchInstrumentationError("could not complete batch", error);
|
|
14386
|
+
}
|
|
14387
|
+
return result;
|
|
14388
|
+
});
|
|
14389
|
+
|
|
13736
14390
|
// src/instrumentation/plugins/openai-plugin.ts
|
|
13737
14391
|
var OpenAIPlugin = class extends BasePlugin {
|
|
13738
14392
|
constructor() {
|
|
13739
14393
|
super();
|
|
13740
14394
|
}
|
|
13741
14395
|
onEnable() {
|
|
14396
|
+
this.unsubscribers.push(
|
|
14397
|
+
openAIChannels.filesCreateTraced.intercept(
|
|
14398
|
+
interceptOpenAIFilesCreateTraced
|
|
14399
|
+
),
|
|
14400
|
+
openAIChannels.batchesRetrieveTraced.intercept(
|
|
14401
|
+
interceptOpenAIBatchesRetrieveTraced
|
|
14402
|
+
),
|
|
14403
|
+
openAIChannels.batchesCompleteTrace.intercept(
|
|
14404
|
+
interceptOpenAIBatchTraceComplete
|
|
14405
|
+
)
|
|
14406
|
+
);
|
|
13742
14407
|
this.unsubscribers.push(
|
|
13743
14408
|
traceStreamingChannel(openAIChannels.chatCompletionsCreate, {
|
|
13744
14409
|
name: "Chat Completion",
|
|
13745
14410
|
type: "llm" /* LLM */,
|
|
13746
|
-
extractInput: ([params]) =>
|
|
13747
|
-
const { messages, ...metadata } = params;
|
|
13748
|
-
return {
|
|
13749
|
-
input: processInputAttachments(messages),
|
|
13750
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13751
|
-
};
|
|
13752
|
-
},
|
|
14411
|
+
extractInput: ([params]) => extractOpenAIChatInput(params),
|
|
13753
14412
|
extractOutput: (result) => {
|
|
13754
14413
|
return result?.choices;
|
|
13755
14414
|
},
|
|
@@ -13795,13 +14454,7 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13795
14454
|
traceStreamingChannel(openAIChannels.betaChatCompletionsParse, {
|
|
13796
14455
|
name: "Chat Completion",
|
|
13797
14456
|
type: "llm" /* LLM */,
|
|
13798
|
-
extractInput: ([params]) =>
|
|
13799
|
-
const { messages, ...metadata } = params;
|
|
13800
|
-
return {
|
|
13801
|
-
input: processInputAttachments(messages),
|
|
13802
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13803
|
-
};
|
|
13804
|
-
},
|
|
14457
|
+
extractInput: ([params]) => extractOpenAIChatInput(params),
|
|
13805
14458
|
extractOutput: (result) => {
|
|
13806
14459
|
return result?.choices;
|
|
13807
14460
|
},
|
|
@@ -13823,13 +14476,7 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13823
14476
|
traceSyncStreamChannel(openAIChannels.betaChatCompletionsStream, {
|
|
13824
14477
|
name: "Chat Completion",
|
|
13825
14478
|
type: "llm" /* LLM */,
|
|
13826
|
-
extractInput: ([params]) =>
|
|
13827
|
-
const { messages, ...metadata } = params;
|
|
13828
|
-
return {
|
|
13829
|
-
input: processInputAttachments(messages),
|
|
13830
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13831
|
-
};
|
|
13832
|
-
}
|
|
14479
|
+
extractInput: ([params]) => extractOpenAIChatInput(params)
|
|
13833
14480
|
})
|
|
13834
14481
|
);
|
|
13835
14482
|
this.unsubscribers.push(
|
|
@@ -13859,23 +14506,11 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13859
14506
|
traceStreamingChannel(openAIChannels.responsesCreate, {
|
|
13860
14507
|
name: "openai.responses.create",
|
|
13861
14508
|
type: "llm" /* LLM */,
|
|
13862
|
-
extractInput: ([params]) =>
|
|
13863
|
-
const { input, ...metadata } = params;
|
|
13864
|
-
return {
|
|
13865
|
-
input: processInputAttachments(input),
|
|
13866
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13867
|
-
};
|
|
13868
|
-
},
|
|
14509
|
+
extractInput: ([params]) => extractOpenAIResponsesInput(params),
|
|
13869
14510
|
extractOutput: (result) => {
|
|
13870
14511
|
return processImagesInOutput(result?.output);
|
|
13871
14512
|
},
|
|
13872
|
-
extractMetadata: (result) =>
|
|
13873
|
-
if (!result) {
|
|
13874
|
-
return void 0;
|
|
13875
|
-
}
|
|
13876
|
-
const { output: _output, usage: _usage, ...metadata } = result;
|
|
13877
|
-
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
13878
|
-
},
|
|
14513
|
+
extractMetadata: (result) => extractOpenAIResponsesMetadata(result),
|
|
13879
14514
|
extractMetrics: (result, startTime, endEvent) => {
|
|
13880
14515
|
const metrics = withCachedMetric(
|
|
13881
14516
|
parseMetricsFromUsage(result?.usage),
|
|
@@ -13894,13 +14529,7 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13894
14529
|
traceSyncStreamChannel(openAIChannels.responsesStream, {
|
|
13895
14530
|
name: "openai.responses.create",
|
|
13896
14531
|
type: "llm" /* LLM */,
|
|
13897
|
-
extractInput: ([params]) =>
|
|
13898
|
-
const { input, ...metadata } = params;
|
|
13899
|
-
return {
|
|
13900
|
-
input: processInputAttachments(input),
|
|
13901
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13902
|
-
};
|
|
13903
|
-
},
|
|
14532
|
+
extractInput: ([params]) => extractOpenAIResponsesInput(params),
|
|
13904
14533
|
extractFromEvent: (event) => {
|
|
13905
14534
|
if (event.type !== "response.completed" || !event.response) {
|
|
13906
14535
|
return {};
|
|
@@ -13923,23 +14552,11 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13923
14552
|
traceStreamingChannel(openAIChannels.responsesParse, {
|
|
13924
14553
|
name: "openai.responses.parse",
|
|
13925
14554
|
type: "llm" /* LLM */,
|
|
13926
|
-
extractInput: ([params]) =>
|
|
13927
|
-
const { input, ...metadata } = params;
|
|
13928
|
-
return {
|
|
13929
|
-
input: processInputAttachments(input),
|
|
13930
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13931
|
-
};
|
|
13932
|
-
},
|
|
14555
|
+
extractInput: ([params]) => extractOpenAIResponsesInput(params),
|
|
13933
14556
|
extractOutput: (result) => {
|
|
13934
14557
|
return processImagesInOutput(result?.output);
|
|
13935
14558
|
},
|
|
13936
|
-
extractMetadata: (result) =>
|
|
13937
|
-
if (!result) {
|
|
13938
|
-
return void 0;
|
|
13939
|
-
}
|
|
13940
|
-
const { output: _output, usage: _usage, ...metadata } = result;
|
|
13941
|
-
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
13942
|
-
},
|
|
14559
|
+
extractMetadata: (result) => extractOpenAIResponsesMetadata(result),
|
|
13943
14560
|
extractMetrics: (result, startTime, endEvent) => {
|
|
13944
14561
|
const metrics = withCachedMetric(
|
|
13945
14562
|
parseMetricsFromUsage(result?.usage),
|
|
@@ -13958,23 +14575,11 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13958
14575
|
traceAsyncChannel(openAIChannels.responsesCompact, {
|
|
13959
14576
|
name: "openai.responses.compact",
|
|
13960
14577
|
type: "llm" /* LLM */,
|
|
13961
|
-
extractInput: ([params]) =>
|
|
13962
|
-
const { input, ...metadata } = params;
|
|
13963
|
-
return {
|
|
13964
|
-
input: processInputAttachments(input),
|
|
13965
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13966
|
-
};
|
|
13967
|
-
},
|
|
14578
|
+
extractInput: ([params]) => extractOpenAIResponsesInput(params),
|
|
13968
14579
|
extractOutput: (result) => {
|
|
13969
14580
|
return processImagesInOutput(result?.output);
|
|
13970
14581
|
},
|
|
13971
|
-
extractMetadata: (result) =>
|
|
13972
|
-
if (!result) {
|
|
13973
|
-
return void 0;
|
|
13974
|
-
}
|
|
13975
|
-
const { output: _output, usage: _usage, ...metadata } = result;
|
|
13976
|
-
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
13977
|
-
},
|
|
14582
|
+
extractMetadata: (result) => extractOpenAIResponsesMetadata(result),
|
|
13978
14583
|
extractMetrics: (result, startTime, endEvent) => {
|
|
13979
14584
|
const metrics = withCachedMetric(
|
|
13980
14585
|
parseMetricsFromUsage(result?.usage),
|
|
@@ -14030,35 +14635,6 @@ function withCachedMetric(metrics, result, endEvent) {
|
|
|
14030
14635
|
cached
|
|
14031
14636
|
};
|
|
14032
14637
|
}
|
|
14033
|
-
function processImagesInOutput(output) {
|
|
14034
|
-
if (Array.isArray(output)) {
|
|
14035
|
-
return output.map(processImagesInOutput);
|
|
14036
|
-
}
|
|
14037
|
-
if (isObject(output)) {
|
|
14038
|
-
if (output.type === "image_generation_call" && output.result && typeof output.result === "string") {
|
|
14039
|
-
const fileExtension = output.output_format || "png";
|
|
14040
|
-
const contentType = `image/${fileExtension}`;
|
|
14041
|
-
const baseFilename = output.revised_prompt && typeof output.revised_prompt === "string" ? output.revised_prompt.slice(0, 50).replace(/[^a-zA-Z0-9]/g, "_") : "generated_image";
|
|
14042
|
-
const filename = `${baseFilename}.${fileExtension}`;
|
|
14043
|
-
const binaryString = atob(output.result);
|
|
14044
|
-
const bytes = new Uint8Array(binaryString.length);
|
|
14045
|
-
for (let i = 0; i < binaryString.length; i++) {
|
|
14046
|
-
bytes[i] = binaryString.charCodeAt(i);
|
|
14047
|
-
}
|
|
14048
|
-
const blob = new Blob([bytes], { type: contentType });
|
|
14049
|
-
const attachment = new Attachment({
|
|
14050
|
-
data: blob,
|
|
14051
|
-
filename,
|
|
14052
|
-
contentType
|
|
14053
|
-
});
|
|
14054
|
-
return {
|
|
14055
|
-
...output,
|
|
14056
|
-
result: attachment
|
|
14057
|
-
};
|
|
14058
|
-
}
|
|
14059
|
-
}
|
|
14060
|
-
return output;
|
|
14061
|
-
}
|
|
14062
14638
|
function mergeLogprobTokens(existing, incoming) {
|
|
14063
14639
|
if (incoming === void 0) {
|
|
14064
14640
|
return existing;
|
|
@@ -19215,6 +19791,12 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
|
|
|
19215
19791
|
if (!activeEntry) {
|
|
19216
19792
|
return result;
|
|
19217
19793
|
}
|
|
19794
|
+
const executionOptions = args[1];
|
|
19795
|
+
const toolCallId = isObject(executionOptions) ? executionOptions.toolCallId : void 0;
|
|
19796
|
+
const toolInput = {
|
|
19797
|
+
input: serializeToolExecutionInput(args),
|
|
19798
|
+
...typeof toolCallId === "string" ? { metadata: { toolCallId } } : {}
|
|
19799
|
+
};
|
|
19218
19800
|
if (isAsyncGenerator(result)) {
|
|
19219
19801
|
return (async function* () {
|
|
19220
19802
|
const span = activeEntry.parentSpan.startSpan(
|
|
@@ -19228,7 +19810,7 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
|
|
|
19228
19810
|
INSTRUMENTATION_NAMES.AI_SDK
|
|
19229
19811
|
)
|
|
19230
19812
|
);
|
|
19231
|
-
span.log(
|
|
19813
|
+
span.log(toolInput);
|
|
19232
19814
|
try {
|
|
19233
19815
|
let lastValue;
|
|
19234
19816
|
for await (const value of result) {
|
|
@@ -19246,7 +19828,7 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
|
|
|
19246
19828
|
}
|
|
19247
19829
|
return activeEntry.parentSpan.traced(
|
|
19248
19830
|
async (span) => {
|
|
19249
|
-
span.log(
|
|
19831
|
+
span.log(toolInput);
|
|
19250
19832
|
const awaitedResult = await result;
|
|
19251
19833
|
span.log({ output: awaitedResult });
|
|
19252
19834
|
return awaitedResult;
|
|
@@ -33368,14 +33950,17 @@ function getMetricsFromResponse(response) {
|
|
|
33368
33950
|
if (!isRecord(usageMetadata)) {
|
|
33369
33951
|
continue;
|
|
33370
33952
|
}
|
|
33371
|
-
const inputTokenDetails = usageMetadata.input_token_details;
|
|
33953
|
+
const inputTokenDetails = isRecord(usageMetadata.input_token_details) ? usageMetadata.input_token_details : {};
|
|
33372
33954
|
const outputTokenDetails = usageMetadata.output_token_details;
|
|
33373
33955
|
return normalizeTokenMetrics({
|
|
33374
33956
|
total_tokens: usageMetadata.total_tokens,
|
|
33375
33957
|
prompt_tokens: usageMetadata.input_tokens,
|
|
33376
33958
|
completion_tokens: usageMetadata.output_tokens,
|
|
33377
|
-
|
|
33378
|
-
|
|
33959
|
+
// Prefer TTL-specific cache writes over the aggregate when available.
|
|
33960
|
+
prompt_cache_creation_tokens: inputTokenDetails.ephemeral_5m_input_tokens == null && inputTokenDetails.ephemeral_1h_input_tokens == null ? inputTokenDetails.cache_creation : void 0,
|
|
33961
|
+
prompt_cache_creation_5m_tokens: inputTokenDetails.ephemeral_5m_input_tokens,
|
|
33962
|
+
prompt_cache_creation_1h_tokens: inputTokenDetails.ephemeral_1h_input_tokens,
|
|
33963
|
+
prompt_cached_tokens: inputTokenDetails.cache_read,
|
|
33379
33964
|
completion_reasoning_tokens: isRecord(outputTokenDetails) ? outputTokenDetails.reasoning : void 0
|
|
33380
33965
|
});
|
|
33381
33966
|
}
|
|
@@ -34091,7 +34676,7 @@ function extractSession(event) {
|
|
|
34091
34676
|
return isObject(candidate) && typeof candidate.prompt === "function" ? candidate : void 0;
|
|
34092
34677
|
}
|
|
34093
34678
|
function isPiAgent(value) {
|
|
34094
|
-
return isObject(value) && typeof value.streamFn === "function" && typeof value.subscribe === "function";
|
|
34679
|
+
return isObject(value) && (typeof value.streamFunction === "function" || typeof value.streamFn === "function") && typeof value.subscribe === "function";
|
|
34095
34680
|
}
|
|
34096
34681
|
function promptContextStore() {
|
|
34097
34682
|
piPromptContextStore ??= isomorph_default.newAsyncLocalStorage();
|
|
@@ -34101,17 +34686,21 @@ function currentPiPromptState() {
|
|
|
34101
34686
|
return promptContextStore().getStore();
|
|
34102
34687
|
}
|
|
34103
34688
|
function installPiAgentInstrumentation(agent) {
|
|
34689
|
+
const property = typeof agent.streamFunction === "function" ? "streamFunction" : "streamFn";
|
|
34690
|
+
const streamFunction = agent[property];
|
|
34104
34691
|
const existing = piAgentPatchStates.get(agent);
|
|
34105
|
-
if (!existing ||
|
|
34692
|
+
if (streamFunction && (!existing || existing.property !== property || streamFunction !== existing.wrappedStreamFunction)) {
|
|
34106
34693
|
const patchState = {
|
|
34107
|
-
|
|
34108
|
-
|
|
34694
|
+
originalStreamFunction: streamFunction,
|
|
34695
|
+
property,
|
|
34696
|
+
wrappedStreamFunction: streamFunction
|
|
34109
34697
|
};
|
|
34110
|
-
patchState.
|
|
34698
|
+
patchState.wrappedStreamFunction = makeInstrumentedStreamFunction(
|
|
34111
34699
|
agent,
|
|
34112
|
-
patchState.
|
|
34700
|
+
patchState.originalStreamFunction,
|
|
34701
|
+
property
|
|
34113
34702
|
);
|
|
34114
|
-
agent
|
|
34703
|
+
agent[property] = patchState.wrappedStreamFunction;
|
|
34115
34704
|
piAgentPatchStates.set(agent, patchState);
|
|
34116
34705
|
}
|
|
34117
34706
|
if (piAgentEventSubscriptions.has(agent)) {
|
|
@@ -34136,15 +34725,21 @@ function installPiAgentInstrumentation(agent) {
|
|
|
34136
34725
|
logInstrumentationError4("Pi Coding Agent event subscription", error);
|
|
34137
34726
|
}
|
|
34138
34727
|
}
|
|
34139
|
-
function
|
|
34140
|
-
return async function
|
|
34141
|
-
const invokeOriginal = () => Reflect.apply(
|
|
34728
|
+
function makeInstrumentedStreamFunction(agent, originalStreamFunction, property) {
|
|
34729
|
+
return async function instrumentedPiStreamFunction(model, context, options) {
|
|
34730
|
+
const invokeOriginal = () => Reflect.apply(originalStreamFunction, this, [model, context, options]);
|
|
34142
34731
|
const state = currentPiPromptState();
|
|
34143
34732
|
if (!state || state.agent !== agent || state.finalized) {
|
|
34144
34733
|
return invokeOriginal();
|
|
34145
34734
|
}
|
|
34146
34735
|
wrapPiToolExecutors(context.tools);
|
|
34147
|
-
const llmState = await startPiLlmSpan(
|
|
34736
|
+
const llmState = await startPiLlmSpan(
|
|
34737
|
+
state,
|
|
34738
|
+
model,
|
|
34739
|
+
context,
|
|
34740
|
+
property,
|
|
34741
|
+
options
|
|
34742
|
+
);
|
|
34148
34743
|
try {
|
|
34149
34744
|
const stream = await runWithAutoInstrumentationSuppressed(invokeOriginal);
|
|
34150
34745
|
return patchAssistantMessageStream(stream, state, llmState);
|
|
@@ -34181,12 +34776,12 @@ function wrapPiToolExecutors(tools) {
|
|
|
34181
34776
|
}
|
|
34182
34777
|
}
|
|
34183
34778
|
}
|
|
34184
|
-
async function startPiLlmSpan(state, model, context, options) {
|
|
34779
|
+
async function startPiLlmSpan(state, model, context, property, options) {
|
|
34185
34780
|
const metadata = {
|
|
34186
34781
|
...extractModelMetadata2(model),
|
|
34187
34782
|
...extractStreamOptionsMetadata(options),
|
|
34188
34783
|
...extractToolMetadata(context.tools),
|
|
34189
|
-
"pi_coding_agent.operation":
|
|
34784
|
+
"pi_coding_agent.operation": `agent.${property}`
|
|
34190
34785
|
};
|
|
34191
34786
|
const span = startSpan(
|
|
34192
34787
|
withSpanInstrumentationName(
|
|
@@ -37204,6 +37799,7 @@ __export(exports_exports, {
|
|
|
37204
37799
|
braintrustStreamChunkSchema: () => braintrustStreamChunkSchema,
|
|
37205
37800
|
buildLocalSummary: () => buildLocalSummary,
|
|
37206
37801
|
collectAnthropicSession: () => collectAnthropicSession,
|
|
37802
|
+
completeOpenAIBatchTrace: () => completeOpenAIBatchTrace,
|
|
37207
37803
|
configureInstrumentation: () => configureInstrumentation,
|
|
37208
37804
|
constructLogs3OverflowRequest: () => constructLogs3OverflowRequest,
|
|
37209
37805
|
createFinalValuePassThroughStream: () => createFinalValuePassThroughStream,
|
|
@@ -37242,6 +37838,8 @@ __export(exports_exports, {
|
|
|
37242
37838
|
loginToState: () => loginToState,
|
|
37243
37839
|
logs3OverflowUploadSchema: () => logs3OverflowUploadSchema,
|
|
37244
37840
|
newId: () => newId,
|
|
37841
|
+
openaiBatchesRetrieveTraced: () => openaiBatchesRetrieveTraced,
|
|
37842
|
+
openaiFilesCreateTraced: () => openaiFilesCreateTraced,
|
|
37245
37843
|
parseCachedHeader: () => parseCachedHeader,
|
|
37246
37844
|
parseTemplateFormat: () => parseTemplateFormat,
|
|
37247
37845
|
permalink: () => permalink,
|
|
@@ -37406,6 +38004,260 @@ async function registerSandbox(options) {
|
|
|
37406
38004
|
};
|
|
37407
38005
|
}
|
|
37408
38006
|
|
|
38007
|
+
// src/wrappers/openai-promise-utils.ts
|
|
38008
|
+
function splitSpanInfo(allParams) {
|
|
38009
|
+
const { span_info, ...params } = allParams;
|
|
38010
|
+
return {
|
|
38011
|
+
params,
|
|
38012
|
+
span_info
|
|
38013
|
+
};
|
|
38014
|
+
}
|
|
38015
|
+
function createChannelContext(_channel, params, span_info) {
|
|
38016
|
+
return {
|
|
38017
|
+
arguments: (
|
|
38018
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38019
|
+
[params]
|
|
38020
|
+
),
|
|
38021
|
+
span_info
|
|
38022
|
+
};
|
|
38023
|
+
}
|
|
38024
|
+
async function tracePromiseWithResponse(channel2, traceContext, apiPromise) {
|
|
38025
|
+
let enhancedResponse;
|
|
38026
|
+
const tracePromise = (
|
|
38027
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38028
|
+
channel2.tracePromise
|
|
38029
|
+
);
|
|
38030
|
+
const data = await tracePromise(async () => {
|
|
38031
|
+
enhancedResponse = await apiPromise.withResponse();
|
|
38032
|
+
traceContext.response = enhancedResponse.response;
|
|
38033
|
+
return enhancedResponse.data;
|
|
38034
|
+
}, traceContext);
|
|
38035
|
+
if (!enhancedResponse) {
|
|
38036
|
+
throw new Error("Expected withResponse() to provide response");
|
|
38037
|
+
}
|
|
38038
|
+
return {
|
|
38039
|
+
data,
|
|
38040
|
+
response: enhancedResponse.response,
|
|
38041
|
+
request_id: enhancedResponse.request_id
|
|
38042
|
+
};
|
|
38043
|
+
}
|
|
38044
|
+
async function tracePromiseAsResponse(channel2, traceContext, apiPromise) {
|
|
38045
|
+
const tracePromise = (
|
|
38046
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38047
|
+
channel2.tracePromise
|
|
38048
|
+
);
|
|
38049
|
+
let response;
|
|
38050
|
+
await tracePromise(async () => {
|
|
38051
|
+
response = await apiPromise.asResponse();
|
|
38052
|
+
traceContext.response = response;
|
|
38053
|
+
return void 0;
|
|
38054
|
+
}, traceContext);
|
|
38055
|
+
if (!response) {
|
|
38056
|
+
throw new Error("Expected asResponse() to provide response");
|
|
38057
|
+
}
|
|
38058
|
+
return response;
|
|
38059
|
+
}
|
|
38060
|
+
function createLazyAPIPromise(ensureExecuted, ensureResponse, getAPIPromise) {
|
|
38061
|
+
let firstConsumption;
|
|
38062
|
+
let enhancedResponsePromise;
|
|
38063
|
+
let dataPromise;
|
|
38064
|
+
let responsePromise;
|
|
38065
|
+
const withResponse = () => {
|
|
38066
|
+
firstConsumption ??= "data";
|
|
38067
|
+
enhancedResponsePromise ??= firstConsumption === "data" ? ensureExecuted() : getAPIPromise().withResponse();
|
|
38068
|
+
return enhancedResponsePromise;
|
|
38069
|
+
};
|
|
38070
|
+
const asResponse = () => {
|
|
38071
|
+
firstConsumption ??= "response";
|
|
38072
|
+
responsePromise ??= firstConsumption === "response" ? ensureResponse() : getAPIPromise().asResponse();
|
|
38073
|
+
return responsePromise;
|
|
38074
|
+
};
|
|
38075
|
+
return new Proxy({}, {
|
|
38076
|
+
get(target, prop, receiver) {
|
|
38077
|
+
if (prop === "withResponse") {
|
|
38078
|
+
return withResponse;
|
|
38079
|
+
}
|
|
38080
|
+
if (prop === "asResponse") {
|
|
38081
|
+
return asResponse;
|
|
38082
|
+
}
|
|
38083
|
+
if (prop === "then" || prop === "catch" || prop === "finally" || prop in Promise.prototype) {
|
|
38084
|
+
dataPromise ??= withResponse().then((result) => result.data);
|
|
38085
|
+
const value = Reflect.get(dataPromise, prop, receiver);
|
|
38086
|
+
return typeof value === "function" ? value.bind(dataPromise) : value;
|
|
38087
|
+
}
|
|
38088
|
+
return Reflect.get(target, prop, receiver);
|
|
38089
|
+
}
|
|
38090
|
+
});
|
|
38091
|
+
}
|
|
38092
|
+
|
|
38093
|
+
// src/openai-batch.ts
|
|
38094
|
+
function read2(value, key) {
|
|
38095
|
+
if (value === null || typeof value !== "object" && typeof value !== "function") {
|
|
38096
|
+
return void 0;
|
|
38097
|
+
}
|
|
38098
|
+
try {
|
|
38099
|
+
return Reflect.get(value, key);
|
|
38100
|
+
} catch {
|
|
38101
|
+
return void 0;
|
|
38102
|
+
}
|
|
38103
|
+
}
|
|
38104
|
+
function isAsyncIterable5(value) {
|
|
38105
|
+
return typeof read2(value, Symbol.asyncIterator) === "function";
|
|
38106
|
+
}
|
|
38107
|
+
function teeAsyncIterable(source) {
|
|
38108
|
+
const iterator = source[Symbol.asyncIterator]();
|
|
38109
|
+
const stream = new ReadableStream({
|
|
38110
|
+
async pull(controller) {
|
|
38111
|
+
try {
|
|
38112
|
+
const result = await iterator.next();
|
|
38113
|
+
if (result.done) {
|
|
38114
|
+
controller.close();
|
|
38115
|
+
return;
|
|
38116
|
+
}
|
|
38117
|
+
if (!(result.value instanceof Uint8Array)) {
|
|
38118
|
+
throw new TypeError(
|
|
38119
|
+
"OpenAI upload streams must yield Uint8Array chunks"
|
|
38120
|
+
);
|
|
38121
|
+
}
|
|
38122
|
+
controller.enqueue(result.value);
|
|
38123
|
+
} catch (error) {
|
|
38124
|
+
controller.error(error);
|
|
38125
|
+
}
|
|
38126
|
+
},
|
|
38127
|
+
async cancel(reason) {
|
|
38128
|
+
await iterator.return?.(reason);
|
|
38129
|
+
}
|
|
38130
|
+
});
|
|
38131
|
+
const [uploadStream, trace] = stream.tee();
|
|
38132
|
+
const upload = {
|
|
38133
|
+
async *[Symbol.asyncIterator]() {
|
|
38134
|
+
const reader = uploadStream.getReader();
|
|
38135
|
+
try {
|
|
38136
|
+
while (true) {
|
|
38137
|
+
const result = await reader.read();
|
|
38138
|
+
if (result.done) {
|
|
38139
|
+
return;
|
|
38140
|
+
}
|
|
38141
|
+
yield result.value;
|
|
38142
|
+
}
|
|
38143
|
+
} finally {
|
|
38144
|
+
reader.releaseLock();
|
|
38145
|
+
}
|
|
38146
|
+
}
|
|
38147
|
+
};
|
|
38148
|
+
const path = read2(source, "path");
|
|
38149
|
+
if (typeof path === "string") {
|
|
38150
|
+
Object.defineProperty(upload, "path", { value: path });
|
|
38151
|
+
}
|
|
38152
|
+
return { upload, trace: new Response(trace) };
|
|
38153
|
+
}
|
|
38154
|
+
function teeUpload(upload) {
|
|
38155
|
+
if (upload instanceof Blob) {
|
|
38156
|
+
return { upload, trace: new Response(upload) };
|
|
38157
|
+
}
|
|
38158
|
+
if (upload instanceof Response) {
|
|
38159
|
+
return { upload, trace: upload.clone() };
|
|
38160
|
+
}
|
|
38161
|
+
if (isAsyncIterable5(upload)) {
|
|
38162
|
+
return teeAsyncIterable(upload);
|
|
38163
|
+
}
|
|
38164
|
+
return void 0;
|
|
38165
|
+
}
|
|
38166
|
+
function openaiFilesCreateTraced(files) {
|
|
38167
|
+
return (params, options) => {
|
|
38168
|
+
const parent = getSpanParentObject();
|
|
38169
|
+
const purpose = read2(params, "purpose");
|
|
38170
|
+
const file = read2(params, "file");
|
|
38171
|
+
if (purpose !== "batch") {
|
|
38172
|
+
return files.create(params, options);
|
|
38173
|
+
}
|
|
38174
|
+
let branches;
|
|
38175
|
+
try {
|
|
38176
|
+
branches = teeUpload(file);
|
|
38177
|
+
} catch {
|
|
38178
|
+
return files.create(params, options);
|
|
38179
|
+
}
|
|
38180
|
+
if (!branches) {
|
|
38181
|
+
return files.create(params, options);
|
|
38182
|
+
}
|
|
38183
|
+
const tracedParams = {
|
|
38184
|
+
...Object(params),
|
|
38185
|
+
file: branches.upload
|
|
38186
|
+
};
|
|
38187
|
+
const apiPromise = files.create(tracedParams, options);
|
|
38188
|
+
let enhancedResponse;
|
|
38189
|
+
const tracedResponse = openAIChannels.filesCreateTraced.invoke(
|
|
38190
|
+
async () => {
|
|
38191
|
+
enhancedResponse = await apiPromise.withResponse();
|
|
38192
|
+
return enhancedResponse.data;
|
|
38193
|
+
},
|
|
38194
|
+
files,
|
|
38195
|
+
[{ params, inputFileContent: branches.trace, parent }],
|
|
38196
|
+
{}
|
|
38197
|
+
).then((data) => {
|
|
38198
|
+
if (!enhancedResponse) {
|
|
38199
|
+
throw new Error(
|
|
38200
|
+
"Expected OpenAI withResponse() to provide a response"
|
|
38201
|
+
);
|
|
38202
|
+
}
|
|
38203
|
+
return { ...enhancedResponse, data };
|
|
38204
|
+
});
|
|
38205
|
+
return createLazyAPIPromise(
|
|
38206
|
+
() => tracedResponse,
|
|
38207
|
+
() => tracedResponse.then(({ response }) => response),
|
|
38208
|
+
() => apiPromise
|
|
38209
|
+
);
|
|
38210
|
+
};
|
|
38211
|
+
}
|
|
38212
|
+
function openaiBatchesRetrieveTraced(batches) {
|
|
38213
|
+
return (batchId, options) => {
|
|
38214
|
+
const apiPromise = batches.retrieve(batchId, options);
|
|
38215
|
+
let enhancedResponse;
|
|
38216
|
+
const tracedResponse = openAIChannels.batchesRetrieveTraced.invoke(
|
|
38217
|
+
async () => {
|
|
38218
|
+
enhancedResponse = await apiPromise.withResponse();
|
|
38219
|
+
return enhancedResponse.data;
|
|
38220
|
+
},
|
|
38221
|
+
batches,
|
|
38222
|
+
[{ batchId }],
|
|
38223
|
+
{}
|
|
38224
|
+
).then((data) => {
|
|
38225
|
+
if (!enhancedResponse) {
|
|
38226
|
+
throw new Error(
|
|
38227
|
+
"Expected OpenAI withResponse() to provide a response"
|
|
38228
|
+
);
|
|
38229
|
+
}
|
|
38230
|
+
return { ...enhancedResponse, data };
|
|
38231
|
+
});
|
|
38232
|
+
return createLazyAPIPromise(
|
|
38233
|
+
() => tracedResponse,
|
|
38234
|
+
() => tracedResponse.then(({ response }) => response),
|
|
38235
|
+
() => apiPromise
|
|
38236
|
+
);
|
|
38237
|
+
};
|
|
38238
|
+
}
|
|
38239
|
+
async function completeOpenAIBatchTrace(args) {
|
|
38240
|
+
const inputFileContent = Promise.resolve(args.inputFileContent);
|
|
38241
|
+
const outputFileContent = args.outputFileContent === void 0 ? void 0 : Promise.resolve(args.outputFileContent);
|
|
38242
|
+
const errorFileContent = args.errorFileContent === void 0 ? void 0 : Promise.resolve(args.errorFileContent);
|
|
38243
|
+
void inputFileContent.catch(() => void 0);
|
|
38244
|
+
void outputFileContent?.catch(() => void 0);
|
|
38245
|
+
void errorFileContent?.catch(() => void 0);
|
|
38246
|
+
await openAIChannels.batchesCompleteTrace.invoke(
|
|
38247
|
+
async () => void 0,
|
|
38248
|
+
void 0,
|
|
38249
|
+
[
|
|
38250
|
+
{
|
|
38251
|
+
...args,
|
|
38252
|
+
inputFileContent,
|
|
38253
|
+
outputFileContent,
|
|
38254
|
+
errorFileContent
|
|
38255
|
+
}
|
|
38256
|
+
],
|
|
38257
|
+
{}
|
|
38258
|
+
);
|
|
38259
|
+
}
|
|
38260
|
+
|
|
37409
38261
|
// src/functions/invoke.ts
|
|
37410
38262
|
async function invoke(args) {
|
|
37411
38263
|
const {
|
|
@@ -37508,58 +38360,6 @@ function initFunction({
|
|
|
37508
38360
|
return f;
|
|
37509
38361
|
}
|
|
37510
38362
|
|
|
37511
|
-
// src/wrappers/openai-promise-utils.ts
|
|
37512
|
-
function splitSpanInfo(allParams) {
|
|
37513
|
-
const { span_info, ...params } = allParams;
|
|
37514
|
-
return {
|
|
37515
|
-
params,
|
|
37516
|
-
span_info
|
|
37517
|
-
};
|
|
37518
|
-
}
|
|
37519
|
-
function createChannelContext(_channel, params, span_info) {
|
|
37520
|
-
return {
|
|
37521
|
-
arguments: (
|
|
37522
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
37523
|
-
[params]
|
|
37524
|
-
),
|
|
37525
|
-
span_info
|
|
37526
|
-
};
|
|
37527
|
-
}
|
|
37528
|
-
async function tracePromiseWithResponse(channel2, traceContext, apiPromise) {
|
|
37529
|
-
let enhancedResponse;
|
|
37530
|
-
const tracePromise = (
|
|
37531
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
37532
|
-
channel2.tracePromise
|
|
37533
|
-
);
|
|
37534
|
-
const data = await tracePromise(async () => {
|
|
37535
|
-
enhancedResponse = await apiPromise.withResponse();
|
|
37536
|
-
traceContext.response = enhancedResponse.response;
|
|
37537
|
-
return enhancedResponse.data;
|
|
37538
|
-
}, traceContext);
|
|
37539
|
-
if (!enhancedResponse) {
|
|
37540
|
-
throw new Error("Expected withResponse() to provide response");
|
|
37541
|
-
}
|
|
37542
|
-
return { data, response: enhancedResponse.response };
|
|
37543
|
-
}
|
|
37544
|
-
function createLazyAPIPromise(ensureExecuted) {
|
|
37545
|
-
let dataPromise = null;
|
|
37546
|
-
return new Proxy({}, {
|
|
37547
|
-
get(target, prop, receiver) {
|
|
37548
|
-
if (prop === "withResponse") {
|
|
37549
|
-
return () => ensureExecuted();
|
|
37550
|
-
}
|
|
37551
|
-
if (prop === "then" || prop === "catch" || prop === "finally" || prop in Promise.prototype) {
|
|
37552
|
-
if (!dataPromise) {
|
|
37553
|
-
dataPromise = ensureExecuted().then((result) => result.data);
|
|
37554
|
-
}
|
|
37555
|
-
const value = Reflect.get(dataPromise, prop, receiver);
|
|
37556
|
-
return typeof value === "function" ? value.bind(dataPromise) : value;
|
|
37557
|
-
}
|
|
37558
|
-
return Reflect.get(target, prop, receiver);
|
|
37559
|
-
}
|
|
37560
|
-
});
|
|
37561
|
-
}
|
|
37562
|
-
|
|
37563
38363
|
// src/wrappers/oai_responses.ts
|
|
37564
38364
|
function responsesProxy(openai) {
|
|
37565
38365
|
if (!openai.responses) {
|
|
@@ -37596,17 +38396,33 @@ function wrapResponsesAsync(target, channel2) {
|
|
|
37596
38396
|
return (allParams, options) => {
|
|
37597
38397
|
const { span_info, params } = splitSpanInfo(allParams);
|
|
37598
38398
|
let executionPromise = null;
|
|
38399
|
+
let apiPromise = null;
|
|
38400
|
+
const getAPIPromise = () => {
|
|
38401
|
+
apiPromise ??= target(params, options);
|
|
38402
|
+
return apiPromise;
|
|
38403
|
+
};
|
|
37599
38404
|
const ensureExecuted = () => {
|
|
37600
38405
|
if (!executionPromise) {
|
|
37601
38406
|
executionPromise = (async () => {
|
|
37602
38407
|
const traceContext = createChannelContext(channel2, params, span_info);
|
|
37603
|
-
|
|
37604
|
-
|
|
38408
|
+
return tracePromiseWithResponse(
|
|
38409
|
+
channel2,
|
|
38410
|
+
traceContext,
|
|
38411
|
+
getAPIPromise()
|
|
38412
|
+
);
|
|
37605
38413
|
})();
|
|
37606
38414
|
}
|
|
37607
38415
|
return executionPromise;
|
|
37608
38416
|
};
|
|
37609
|
-
return createLazyAPIPromise(
|
|
38417
|
+
return createLazyAPIPromise(
|
|
38418
|
+
ensureExecuted,
|
|
38419
|
+
() => tracePromiseAsResponse(
|
|
38420
|
+
channel2,
|
|
38421
|
+
createChannelContext(channel2, params, span_info),
|
|
38422
|
+
getAPIPromise()
|
|
38423
|
+
),
|
|
38424
|
+
getAPIPromise
|
|
38425
|
+
);
|
|
37610
38426
|
};
|
|
37611
38427
|
}
|
|
37612
38428
|
function wrapResponsesSyncStream(target, channel2) {
|
|
@@ -37752,6 +38568,11 @@ function wrapChatCompletion(completion) {
|
|
|
37752
38568
|
allParams
|
|
37753
38569
|
);
|
|
37754
38570
|
let executionPromise = null;
|
|
38571
|
+
let apiPromise = null;
|
|
38572
|
+
const getAPIPromise = () => {
|
|
38573
|
+
apiPromise ??= completion(params, options);
|
|
38574
|
+
return apiPromise;
|
|
38575
|
+
};
|
|
37755
38576
|
const ensureExecuted = () => {
|
|
37756
38577
|
if (!executionPromise) {
|
|
37757
38578
|
executionPromise = (async () => {
|
|
@@ -37761,32 +38582,44 @@ function wrapChatCompletion(completion) {
|
|
|
37761
38582
|
span_info
|
|
37762
38583
|
);
|
|
37763
38584
|
if (params.stream) {
|
|
37764
|
-
const completionPromise =
|
|
37765
|
-
|
|
37766
|
-
|
|
38585
|
+
const completionPromise = (
|
|
38586
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38587
|
+
getAPIPromise()
|
|
37767
38588
|
);
|
|
37768
|
-
const { data: data2, response: response2 } = await tracePromiseWithResponse(
|
|
38589
|
+
const { data: data2, response: response2, request_id: request_id2 } = await tracePromiseWithResponse(
|
|
37769
38590
|
openAIChannels.chatCompletionsCreate,
|
|
37770
38591
|
traceContext,
|
|
37771
38592
|
completionPromise
|
|
37772
38593
|
);
|
|
37773
|
-
return { data: data2, response: response2 };
|
|
38594
|
+
return { data: data2, response: response2, request_id: request_id2 };
|
|
37774
38595
|
}
|
|
37775
|
-
const completionResponse =
|
|
37776
|
-
|
|
37777
|
-
|
|
38596
|
+
const completionResponse = (
|
|
38597
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38598
|
+
getAPIPromise()
|
|
37778
38599
|
);
|
|
37779
|
-
const { data, response } = await tracePromiseWithResponse(
|
|
38600
|
+
const { data, response, request_id } = await tracePromiseWithResponse(
|
|
37780
38601
|
openAIChannels.chatCompletionsCreate,
|
|
37781
38602
|
traceContext,
|
|
37782
38603
|
completionResponse
|
|
37783
38604
|
);
|
|
37784
|
-
return { data, response };
|
|
38605
|
+
return { data, response, request_id };
|
|
37785
38606
|
})();
|
|
37786
38607
|
}
|
|
37787
38608
|
return executionPromise;
|
|
37788
38609
|
};
|
|
37789
|
-
return createLazyAPIPromise(
|
|
38610
|
+
return createLazyAPIPromise(
|
|
38611
|
+
ensureExecuted,
|
|
38612
|
+
() => tracePromiseAsResponse(
|
|
38613
|
+
openAIChannels.chatCompletionsCreate,
|
|
38614
|
+
createChannelContext(
|
|
38615
|
+
openAIChannels.chatCompletionsCreate,
|
|
38616
|
+
params,
|
|
38617
|
+
span_info
|
|
38618
|
+
),
|
|
38619
|
+
getAPIPromise()
|
|
38620
|
+
),
|
|
38621
|
+
getAPIPromise
|
|
38622
|
+
);
|
|
37790
38623
|
};
|
|
37791
38624
|
}
|
|
37792
38625
|
function createEndpointProxy(target, wrapperFn) {
|
|
@@ -37804,6 +38637,11 @@ function wrapApiCreateWithChannel(create, channel2) {
|
|
|
37804
38637
|
return (allParams, options) => {
|
|
37805
38638
|
const { span_info, params } = splitSpanInfo(allParams);
|
|
37806
38639
|
let executionPromise = null;
|
|
38640
|
+
let apiPromise = null;
|
|
38641
|
+
const getAPIPromise = () => {
|
|
38642
|
+
apiPromise ??= create(params, options);
|
|
38643
|
+
return apiPromise;
|
|
38644
|
+
};
|
|
37807
38645
|
const ensureExecuted = () => {
|
|
37808
38646
|
if (!executionPromise) {
|
|
37809
38647
|
executionPromise = (async () => {
|
|
@@ -37811,13 +38649,21 @@ function wrapApiCreateWithChannel(create, channel2) {
|
|
|
37811
38649
|
return tracePromiseWithResponse(
|
|
37812
38650
|
channel2,
|
|
37813
38651
|
traceContext,
|
|
37814
|
-
|
|
38652
|
+
getAPIPromise()
|
|
37815
38653
|
);
|
|
37816
38654
|
})();
|
|
37817
38655
|
}
|
|
37818
38656
|
return executionPromise;
|
|
37819
38657
|
};
|
|
37820
|
-
return createLazyAPIPromise(
|
|
38658
|
+
return createLazyAPIPromise(
|
|
38659
|
+
ensureExecuted,
|
|
38660
|
+
() => tracePromiseAsResponse(
|
|
38661
|
+
channel2,
|
|
38662
|
+
createChannelContext(channel2, params, span_info),
|
|
38663
|
+
getAPIPromise()
|
|
38664
|
+
),
|
|
38665
|
+
getAPIPromise
|
|
38666
|
+
);
|
|
37821
38667
|
};
|
|
37822
38668
|
}
|
|
37823
38669
|
var wrapEmbeddings = (create) => wrapApiCreateWithChannel(create, openAIChannels.embeddingsCreate);
|
|
@@ -40512,7 +41358,15 @@ var MAX_EVE_PROVIDER_CACHE_ENTRIES = 1e4;
|
|
|
40512
41358
|
function createEveInstrumentationProvider(options = {}) {
|
|
40513
41359
|
const bridge = new EveProviderBridge(options.metadata);
|
|
40514
41360
|
return {
|
|
41361
|
+
// Eve versions before tracePolicy use capture to decide whether provider
|
|
41362
|
+
// events include content. Newer versions prefer tracePolicy when both are
|
|
41363
|
+
// present, so keep the deprecated field for backwards compatibility.
|
|
40515
41364
|
capture: "content",
|
|
41365
|
+
tracePolicy: () => ({
|
|
41366
|
+
emit: true,
|
|
41367
|
+
recordInputs: true,
|
|
41368
|
+
recordOutputs: true
|
|
41369
|
+
}),
|
|
40516
41370
|
events: {
|
|
40517
41371
|
"action.completed": (event, context) => bridge.handleActionTerminal(event, context),
|
|
40518
41372
|
"action.failed": (event, context) => bridge.handleActionTerminal(event, context),
|
|
@@ -44120,8 +44974,8 @@ function normalizeScores(result) {
|
|
|
44120
44974
|
(s) => s !== null && s !== void 0 && typeof s === "object" && isScore(s)
|
|
44121
44975
|
);
|
|
44122
44976
|
}
|
|
44123
|
-
if (typeof result === "object" && result !== null &&
|
|
44124
|
-
return [result];
|
|
44977
|
+
if (typeof result === "object" && result !== null && "score" in result) {
|
|
44978
|
+
return [{ ...result, name: result.name ?? "score" }];
|
|
44125
44979
|
}
|
|
44126
44980
|
return [];
|
|
44127
44981
|
}
|
|
@@ -44941,7 +45795,7 @@ function isAsync(fn) {
|
|
|
44941
45795
|
function isAsyncGenerator2(fn) {
|
|
44942
45796
|
return fn[Symbol.toStringTag] === "AsyncGenerator";
|
|
44943
45797
|
}
|
|
44944
|
-
function
|
|
45798
|
+
function isAsyncIterable6(obj) {
|
|
44945
45799
|
return typeof obj[Symbol.asyncIterator] === "function";
|
|
44946
45800
|
}
|
|
44947
45801
|
function wrapAsync(asyncFn) {
|
|
@@ -45113,7 +45967,7 @@ var eachOfLimit$2 = (limit) => {
|
|
|
45113
45967
|
if (isAsyncGenerator2(obj)) {
|
|
45114
45968
|
return asyncEachOfLimit(obj, limit, iteratee, callback);
|
|
45115
45969
|
}
|
|
45116
|
-
if (
|
|
45970
|
+
if (isAsyncIterable6(obj)) {
|
|
45117
45971
|
return asyncEachOfLimit(obj[Symbol.asyncIterator](), limit, iteratee, callback);
|
|
45118
45972
|
}
|
|
45119
45973
|
var nextElem = createIterator(obj);
|
|
@@ -46468,7 +47322,7 @@ function callEvaluatorData(data) {
|
|
|
46468
47322
|
baseExperiment
|
|
46469
47323
|
};
|
|
46470
47324
|
}
|
|
46471
|
-
function
|
|
47325
|
+
function isAsyncIterable7(value) {
|
|
46472
47326
|
return typeof value === "object" && value !== null && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
46473
47327
|
}
|
|
46474
47328
|
function isIterable(value) {
|
|
@@ -46503,7 +47357,7 @@ async function _internalResolveEvaluatorData(evaluator, experiment) {
|
|
|
46503
47357
|
}).asDataset();
|
|
46504
47358
|
}
|
|
46505
47359
|
const resolvedDataResult = dataResult instanceof Promise ? await dataResult : dataResult;
|
|
46506
|
-
if (
|
|
47360
|
+
if (isAsyncIterable7(resolvedDataResult)) {
|
|
46507
47361
|
return resolvedDataResult;
|
|
46508
47362
|
}
|
|
46509
47363
|
if (Array.isArray(resolvedDataResult) || isIterable(resolvedDataResult)) {
|
|
@@ -46704,19 +47558,29 @@ function buildSpanScores(results) {
|
|
|
46704
47558
|
function _internalPrepareEvaluatorScore(scoreValue, name) {
|
|
46705
47559
|
if (scoreValue === null) return { results: null };
|
|
46706
47560
|
if (Array.isArray(scoreValue)) {
|
|
47561
|
+
const names = /* @__PURE__ */ new Set();
|
|
46707
47562
|
for (const score of scoreValue) {
|
|
46708
47563
|
if (!(typeof score === "object" && !isEmpty2(score))) {
|
|
46709
47564
|
throw new Error(
|
|
46710
47565
|
`When returning an array of scores, each score must be a non-empty object. Got: ${JSON.stringify(score)}`
|
|
46711
47566
|
);
|
|
46712
47567
|
}
|
|
47568
|
+
if (typeof score.name !== "string") {
|
|
47569
|
+
throw new Error(
|
|
47570
|
+
`When returning an array of scores, each score must have a name. Got: ${JSON.stringify(score)}`
|
|
47571
|
+
);
|
|
47572
|
+
}
|
|
47573
|
+
if (names.has(score.name)) {
|
|
47574
|
+
throw new Error(`Duplicate score name '${score.name}' in score array`);
|
|
47575
|
+
}
|
|
47576
|
+
names.add(score.name);
|
|
46713
47577
|
}
|
|
46714
47578
|
}
|
|
46715
47579
|
let results;
|
|
46716
47580
|
if (Array.isArray(scoreValue)) {
|
|
46717
47581
|
results = scoreValue;
|
|
46718
47582
|
} else if (typeof scoreValue === "object" && !isEmpty2(scoreValue)) {
|
|
46719
|
-
results = [scoreValue];
|
|
47583
|
+
results = [{ ...scoreValue, name: scoreValue.name ?? name }];
|
|
46720
47584
|
} else {
|
|
46721
47585
|
results = [{ name, score: scoreValue }];
|
|
46722
47586
|
}
|
|
@@ -49551,6 +50415,7 @@ export {
|
|
|
49551
50415
|
braintrustStreamChunkSchema,
|
|
49552
50416
|
buildLocalSummary,
|
|
49553
50417
|
collectAnthropicSession,
|
|
50418
|
+
completeOpenAIBatchTrace,
|
|
49554
50419
|
configureInstrumentation,
|
|
49555
50420
|
constructLogs3OverflowRequest,
|
|
49556
50421
|
createFinalValuePassThroughStream,
|
|
@@ -49590,6 +50455,8 @@ export {
|
|
|
49590
50455
|
loginToState,
|
|
49591
50456
|
logs3OverflowUploadSchema,
|
|
49592
50457
|
newId,
|
|
50458
|
+
openaiBatchesRetrieveTraced,
|
|
50459
|
+
openaiFilesCreateTraced,
|
|
49593
50460
|
parseCachedHeader,
|
|
49594
50461
|
parseTemplateFormat,
|
|
49595
50462
|
permalink,
|