braintrust 3.29.0 → 3.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dev/dist/index.js +1465 -881
- package/dev/dist/index.mjs +846 -262
- package/dist/apply-auto-instrumentation.js +217 -217
- package/dist/apply-auto-instrumentation.mjs +2 -2
- package/dist/auto-instrumentations/bundler/esbuild.cjs +13 -1
- package/dist/auto-instrumentations/bundler/esbuild.mjs +2 -2
- package/dist/auto-instrumentations/bundler/next.cjs +13 -1
- package/dist/auto-instrumentations/bundler/next.mjs +3 -3
- package/dist/auto-instrumentations/bundler/rollup.cjs +13 -1
- package/dist/auto-instrumentations/bundler/rollup.mjs +2 -2
- package/dist/auto-instrumentations/bundler/vite.cjs +13 -1
- package/dist/auto-instrumentations/bundler/vite.mjs +2 -2
- package/dist/auto-instrumentations/bundler/webpack-loader.cjs +13 -1
- package/dist/auto-instrumentations/bundler/webpack.cjs +13 -1
- package/dist/auto-instrumentations/bundler/webpack.mjs +3 -3
- package/dist/auto-instrumentations/{chunk-DKTGDNA7.mjs → chunk-LW4HDHXT.mjs} +1 -1
- package/dist/auto-instrumentations/{chunk-OMCZ3MV2.mjs → chunk-OXINGIEZ.mjs} +1 -1
- package/dist/auto-instrumentations/{chunk-AOIYCVEL.mjs → chunk-U64OYU4Q.mjs} +13 -1
- package/dist/auto-instrumentations/hook.mjs +16 -4
- package/dist/auto-instrumentations/index.cjs +13 -1
- package/dist/auto-instrumentations/index.mjs +1 -1
- package/dist/browser.d.mts +133 -2
- package/dist/browser.d.ts +133 -2
- package/dist/browser.js +1143 -297
- package/dist/browser.mjs +1143 -297
- package/dist/{chunk-6Z5S7VOU.js → chunk-2XDW3UCG.js} +13 -1
- package/dist/{chunk-M6XPNJC4.mjs → chunk-BU6SM54N.mjs} +687 -115
- package/dist/{chunk-7FA6VP2S.mjs → chunk-N3JKQ3D3.mjs} +13 -1
- package/dist/{chunk-XLLGRXGR.js → chunk-TWCDSYJN.js} +1803 -1231
- package/dist/cli.js +819 -235
- package/dist/edge-light.d.mts +1 -1
- package/dist/edge-light.d.ts +1 -1
- package/dist/edge-light.js +1143 -297
- package/dist/edge-light.mjs +1143 -297
- package/dist/index.d.mts +133 -2
- package/dist/index.d.ts +133 -2
- package/dist/index.js +902 -640
- package/dist/index.mjs +336 -74
- package/dist/instrumentation/index.d.mts +15 -0
- package/dist/instrumentation/index.d.ts +15 -0
- package/dist/instrumentation/index.js +857 -262
- package/dist/instrumentation/index.mjs +857 -262
- package/dist/vitest-evals-reporter.js +16 -16
- package/dist/vitest-evals-reporter.mjs +2 -2
- package/dist/workerd.d.mts +1 -1
- package/dist/workerd.d.ts +1 -1
- package/dist/workerd.js +1143 -297
- package/dist/workerd.mjs +1143 -297
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -41,7 +41,7 @@ var require_async = __commonJS({
|
|
|
41
41
|
"use strict";
|
|
42
42
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
43
43
|
exports2.read = void 0;
|
|
44
|
-
function
|
|
44
|
+
function read2(path9, settings, callback) {
|
|
45
45
|
settings.fs.lstat(path9, (lstatError, lstat) => {
|
|
46
46
|
if (lstatError !== null) {
|
|
47
47
|
callFailureCallback(callback, lstatError);
|
|
@@ -67,7 +67,7 @@ var require_async = __commonJS({
|
|
|
67
67
|
});
|
|
68
68
|
});
|
|
69
69
|
}
|
|
70
|
-
exports2.read =
|
|
70
|
+
exports2.read = read2;
|
|
71
71
|
function callFailureCallback(callback, error2) {
|
|
72
72
|
callback(error2);
|
|
73
73
|
}
|
|
@@ -83,7 +83,7 @@ var require_sync = __commonJS({
|
|
|
83
83
|
"use strict";
|
|
84
84
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
85
85
|
exports2.read = void 0;
|
|
86
|
-
function
|
|
86
|
+
function read2(path9, settings) {
|
|
87
87
|
const lstat = settings.fs.lstatSync(path9);
|
|
88
88
|
if (!lstat.isSymbolicLink() || !settings.followSymbolicLink) {
|
|
89
89
|
return lstat;
|
|
@@ -101,7 +101,7 @@ var require_sync = __commonJS({
|
|
|
101
101
|
throw error2;
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
|
-
exports2.read =
|
|
104
|
+
exports2.read = read2;
|
|
105
105
|
}
|
|
106
106
|
});
|
|
107
107
|
|
|
@@ -327,14 +327,14 @@ var require_async2 = __commonJS({
|
|
|
327
327
|
var constants_1 = require_constants();
|
|
328
328
|
var utils = require_utils();
|
|
329
329
|
var common = require_common();
|
|
330
|
-
function
|
|
330
|
+
function read2(directory, settings, callback) {
|
|
331
331
|
if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) {
|
|
332
332
|
readdirWithFileTypes(directory, settings, callback);
|
|
333
333
|
return;
|
|
334
334
|
}
|
|
335
335
|
readdir2(directory, settings, callback);
|
|
336
336
|
}
|
|
337
|
-
exports2.read =
|
|
337
|
+
exports2.read = read2;
|
|
338
338
|
function readdirWithFileTypes(directory, settings, callback) {
|
|
339
339
|
settings.fs.readdir(directory, { withFileTypes: true }, (readdirError, dirents) => {
|
|
340
340
|
if (readdirError !== null) {
|
|
@@ -436,13 +436,13 @@ var require_sync2 = __commonJS({
|
|
|
436
436
|
var constants_1 = require_constants();
|
|
437
437
|
var utils = require_utils();
|
|
438
438
|
var common = require_common();
|
|
439
|
-
function
|
|
439
|
+
function read2(directory, settings) {
|
|
440
440
|
if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) {
|
|
441
441
|
return readdirWithFileTypes(directory, settings);
|
|
442
442
|
}
|
|
443
443
|
return readdir2(directory, settings);
|
|
444
444
|
}
|
|
445
|
-
exports2.read =
|
|
445
|
+
exports2.read = read2;
|
|
446
446
|
function readdirWithFileTypes(directory, settings) {
|
|
447
447
|
const dirents = settings.fs.readdirSync(directory, { withFileTypes: true });
|
|
448
448
|
return dirents.map((dirent) => {
|
|
@@ -1236,7 +1236,7 @@ var require_package = __commonJS({
|
|
|
1236
1236
|
"package.json"(exports2, module2) {
|
|
1237
1237
|
module2.exports = {
|
|
1238
1238
|
name: "braintrust",
|
|
1239
|
-
version: "3.
|
|
1239
|
+
version: "3.30.0",
|
|
1240
1240
|
description: "SDK for integrating Braintrust",
|
|
1241
1241
|
repository: {
|
|
1242
1242
|
type: "git",
|
|
@@ -7208,7 +7208,7 @@ var INSTRUMENTATION_NAMES = {
|
|
|
7208
7208
|
var INTERNAL_SPAN_INSTRUMENTATION_NAME = /* @__PURE__ */ Symbol.for(
|
|
7209
7209
|
"braintrust.spanInstrumentationName"
|
|
7210
7210
|
);
|
|
7211
|
-
var SDK_VERSION = true ? "3.
|
|
7211
|
+
var SDK_VERSION = true ? "3.30.0" : "0.0.0";
|
|
7212
7212
|
function withSpanInstrumentationName(args, instrumentationName) {
|
|
7213
7213
|
return {
|
|
7214
7214
|
...args,
|
|
@@ -10723,6 +10723,15 @@ function _internalStartSpanWithInitialMerge(args) {
|
|
|
10723
10723
|
[INITIAL_SPAN_WRITE_AS_MERGE]: true
|
|
10724
10724
|
}).span;
|
|
10725
10725
|
}
|
|
10726
|
+
function _internalStartSpanWithInitialMergeAndParentSpanIds(args) {
|
|
10727
|
+
return startSpanAndIsLogger(
|
|
10728
|
+
{
|
|
10729
|
+
...args,
|
|
10730
|
+
[INITIAL_SPAN_WRITE_AS_MERGE]: true
|
|
10731
|
+
},
|
|
10732
|
+
{ useParentSpanIdsForObjectParent: true }
|
|
10733
|
+
).span;
|
|
10734
|
+
}
|
|
10726
10735
|
function _internalStartSpanWithContext(args, context2) {
|
|
10727
10736
|
return startSpanAndIsLogger({
|
|
10728
10737
|
...args,
|
|
@@ -10733,7 +10742,7 @@ async function flush(options) {
|
|
|
10733
10742
|
const state = options?.state ?? _globalState;
|
|
10734
10743
|
return await state.bgLogger().flush();
|
|
10735
10744
|
}
|
|
10736
|
-
function startSpanAndIsLogger(args) {
|
|
10745
|
+
function startSpanAndIsLogger(args, internalOptions) {
|
|
10737
10746
|
const state = args?.state ?? _globalState;
|
|
10738
10747
|
const { parentObject, propagatedState } = getSpanParentObjectAndPropagatedState({
|
|
10739
10748
|
asyncFlush: args?.asyncFlush,
|
|
@@ -10747,7 +10756,7 @@ function startSpanAndIsLogger(args) {
|
|
|
10747
10756
|
) ? {
|
|
10748
10757
|
spanId: parentObject.data.span_id,
|
|
10749
10758
|
rootSpanId: parentObject.data.root_span_id
|
|
10750
|
-
} : void 0;
|
|
10759
|
+
} : internalOptions?.useParentSpanIdsForObjectParent ? args?.parentSpanIds : void 0;
|
|
10751
10760
|
const { parent: _ignoredParent, ...spanArgs } = args ?? {};
|
|
10752
10761
|
const span = new SpanImpl({
|
|
10753
10762
|
state,
|
|
@@ -17176,6 +17185,131 @@ function unsubscribeAll(unsubscribers) {
|
|
|
17176
17185
|
return [];
|
|
17177
17186
|
}
|
|
17178
17187
|
|
|
17188
|
+
// src/instrumentation/core/channel-definitions.ts
|
|
17189
|
+
function channel(spec) {
|
|
17190
|
+
return spec;
|
|
17191
|
+
}
|
|
17192
|
+
function defineChannels(pkg, channels, options) {
|
|
17193
|
+
const { instrumentationName } = options;
|
|
17194
|
+
return Object.fromEntries(
|
|
17195
|
+
Object.entries(channels).map(([key, spec]) => {
|
|
17196
|
+
const fullChannelName = `orchestrion:${pkg}:${spec.channelName}`;
|
|
17197
|
+
if (spec.kind === "async") {
|
|
17198
|
+
const asyncSpec = spec;
|
|
17199
|
+
const tracingChannel2 = () => isomorph_default.newTracingChannel(
|
|
17200
|
+
fullChannelName
|
|
17201
|
+
);
|
|
17202
|
+
const intercept2 = (interceptor) => {
|
|
17203
|
+
const hook = tracingChannel2();
|
|
17204
|
+
return typeof hook.intercept === "function" ? hook.intercept(interceptor) : () => {
|
|
17205
|
+
};
|
|
17206
|
+
};
|
|
17207
|
+
return [
|
|
17208
|
+
key,
|
|
17209
|
+
{
|
|
17210
|
+
...asyncSpec,
|
|
17211
|
+
instrumentationName,
|
|
17212
|
+
intercept: intercept2,
|
|
17213
|
+
invoke: (target, thisArg, args, additional) => {
|
|
17214
|
+
const hook = tracingChannel2();
|
|
17215
|
+
return typeof hook.invoke === "function" ? hook.invoke(target, thisArg, args, additional) : Reflect.apply(target, thisArg, args);
|
|
17216
|
+
},
|
|
17217
|
+
tracingChannel: tracingChannel2,
|
|
17218
|
+
tracePromise: (fn, context2) => tracingChannel2().tracePromise(
|
|
17219
|
+
fn,
|
|
17220
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
17221
|
+
context2
|
|
17222
|
+
)
|
|
17223
|
+
}
|
|
17224
|
+
];
|
|
17225
|
+
}
|
|
17226
|
+
const syncSpec = spec;
|
|
17227
|
+
const tracingChannel = () => isomorph_default.newTracingChannel(
|
|
17228
|
+
fullChannelName
|
|
17229
|
+
);
|
|
17230
|
+
const intercept = (interceptor) => {
|
|
17231
|
+
const hook = tracingChannel();
|
|
17232
|
+
return typeof hook.intercept === "function" ? hook.intercept(interceptor) : () => {
|
|
17233
|
+
};
|
|
17234
|
+
};
|
|
17235
|
+
return [
|
|
17236
|
+
key,
|
|
17237
|
+
{
|
|
17238
|
+
...syncSpec,
|
|
17239
|
+
instrumentationName,
|
|
17240
|
+
intercept,
|
|
17241
|
+
invoke: (target, thisArg, args, additional) => {
|
|
17242
|
+
const hook = tracingChannel();
|
|
17243
|
+
return typeof hook.invoke === "function" ? hook.invoke(target, thisArg, args, additional) : Reflect.apply(target, thisArg, args);
|
|
17244
|
+
},
|
|
17245
|
+
tracingChannel,
|
|
17246
|
+
traceSync: (fn, context2) => tracingChannel().traceSync(
|
|
17247
|
+
fn,
|
|
17248
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
17249
|
+
context2
|
|
17250
|
+
)
|
|
17251
|
+
}
|
|
17252
|
+
];
|
|
17253
|
+
})
|
|
17254
|
+
);
|
|
17255
|
+
}
|
|
17256
|
+
|
|
17257
|
+
// src/instrumentation/plugins/openai-channels.ts
|
|
17258
|
+
var openAIChannels = defineChannels(
|
|
17259
|
+
"openai",
|
|
17260
|
+
{
|
|
17261
|
+
filesCreateTraced: channel({
|
|
17262
|
+
channelName: "files.create-traced",
|
|
17263
|
+
kind: "async"
|
|
17264
|
+
}),
|
|
17265
|
+
batchesRetrieveTraced: channel({
|
|
17266
|
+
channelName: "batches.retrieve-traced",
|
|
17267
|
+
kind: "async"
|
|
17268
|
+
}),
|
|
17269
|
+
batchesCompleteTrace: channel({
|
|
17270
|
+
channelName: "batches.complete-trace",
|
|
17271
|
+
kind: "async"
|
|
17272
|
+
}),
|
|
17273
|
+
chatCompletionsCreate: channel({
|
|
17274
|
+
channelName: "chat.completions.create",
|
|
17275
|
+
kind: "async"
|
|
17276
|
+
}),
|
|
17277
|
+
embeddingsCreate: channel({
|
|
17278
|
+
channelName: "embeddings.create",
|
|
17279
|
+
kind: "async"
|
|
17280
|
+
}),
|
|
17281
|
+
betaChatCompletionsParse: channel({
|
|
17282
|
+
channelName: "beta.chat.completions.parse",
|
|
17283
|
+
kind: "async"
|
|
17284
|
+
}),
|
|
17285
|
+
betaChatCompletionsStream: channel({
|
|
17286
|
+
channelName: "beta.chat.completions.stream",
|
|
17287
|
+
kind: "sync-stream"
|
|
17288
|
+
}),
|
|
17289
|
+
moderationsCreate: channel({
|
|
17290
|
+
channelName: "moderations.create",
|
|
17291
|
+
kind: "async"
|
|
17292
|
+
}),
|
|
17293
|
+
responsesCreate: channel({
|
|
17294
|
+
channelName: "responses.create",
|
|
17295
|
+
kind: "async"
|
|
17296
|
+
}),
|
|
17297
|
+
responsesStream: channel({
|
|
17298
|
+
channelName: "responses.stream",
|
|
17299
|
+
kind: "sync-stream"
|
|
17300
|
+
}),
|
|
17301
|
+
responsesParse: channel({
|
|
17302
|
+
channelName: "responses.parse",
|
|
17303
|
+
kind: "async"
|
|
17304
|
+
}),
|
|
17305
|
+
responsesCompact: channel({
|
|
17306
|
+
channelName: "responses.compact",
|
|
17307
|
+
kind: "async"
|
|
17308
|
+
})
|
|
17309
|
+
},
|
|
17310
|
+
{ instrumentationName: INSTRUMENTATION_NAMES.OPENAI }
|
|
17311
|
+
);
|
|
17312
|
+
|
|
17179
17313
|
// src/wrappers/attachment-utils.ts
|
|
17180
17314
|
function getExtensionFromMediaType(mediaType) {
|
|
17181
17315
|
const extensionMap = {
|
|
@@ -17351,118 +17485,91 @@ function processInputAttachments(input) {
|
|
|
17351
17485
|
return processNode(input);
|
|
17352
17486
|
}
|
|
17353
17487
|
|
|
17354
|
-
// src/instrumentation/
|
|
17355
|
-
|
|
17356
|
-
|
|
17357
|
-
|
|
17358
|
-
|
|
17359
|
-
|
|
17360
|
-
|
|
17361
|
-
|
|
17362
|
-
|
|
17363
|
-
|
|
17364
|
-
|
|
17365
|
-
|
|
17366
|
-
|
|
17367
|
-
|
|
17368
|
-
|
|
17369
|
-
|
|
17370
|
-
|
|
17371
|
-
|
|
17372
|
-
|
|
17373
|
-
|
|
17374
|
-
|
|
17375
|
-
|
|
17376
|
-
...asyncSpec,
|
|
17377
|
-
instrumentationName,
|
|
17378
|
-
intercept: intercept2,
|
|
17379
|
-
invoke: (target, thisArg, args, additional) => {
|
|
17380
|
-
const hook = tracingChannel2();
|
|
17381
|
-
return typeof hook.invoke === "function" ? hook.invoke(target, thisArg, args, additional) : Reflect.apply(target, thisArg, args);
|
|
17382
|
-
},
|
|
17383
|
-
tracingChannel: tracingChannel2,
|
|
17384
|
-
tracePromise: (fn, context2) => tracingChannel2().tracePromise(
|
|
17385
|
-
fn,
|
|
17386
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
17387
|
-
context2
|
|
17388
|
-
)
|
|
17389
|
-
}
|
|
17390
|
-
];
|
|
17488
|
+
// src/instrumentation/plugins/openai-span-data.ts
|
|
17489
|
+
var OPENAI_METADATA_KEYS = [
|
|
17490
|
+
"model",
|
|
17491
|
+
"temperature",
|
|
17492
|
+
"top_p",
|
|
17493
|
+
"max_tokens",
|
|
17494
|
+
"frequency_penalty",
|
|
17495
|
+
"presence_penalty",
|
|
17496
|
+
"stop",
|
|
17497
|
+
"response_format",
|
|
17498
|
+
"tools",
|
|
17499
|
+
"tool_choice",
|
|
17500
|
+
"parallel_tool_calls",
|
|
17501
|
+
"max_tool_calls"
|
|
17502
|
+
];
|
|
17503
|
+
function batchMetadata(params) {
|
|
17504
|
+
const metadata = { provider: "openai" };
|
|
17505
|
+
for (const key of OPENAI_METADATA_KEYS) {
|
|
17506
|
+
try {
|
|
17507
|
+
const value = Reflect.get(params, key);
|
|
17508
|
+
if (value !== void 0) {
|
|
17509
|
+
metadata[key] = value;
|
|
17391
17510
|
}
|
|
17392
|
-
|
|
17393
|
-
|
|
17394
|
-
|
|
17395
|
-
|
|
17396
|
-
|
|
17397
|
-
|
|
17398
|
-
|
|
17399
|
-
|
|
17400
|
-
|
|
17401
|
-
|
|
17402
|
-
|
|
17403
|
-
|
|
17404
|
-
|
|
17405
|
-
|
|
17406
|
-
|
|
17407
|
-
|
|
17408
|
-
|
|
17409
|
-
|
|
17410
|
-
|
|
17411
|
-
|
|
17412
|
-
|
|
17413
|
-
|
|
17414
|
-
|
|
17415
|
-
|
|
17416
|
-
|
|
17417
|
-
|
|
17418
|
-
|
|
17419
|
-
|
|
17420
|
-
|
|
17511
|
+
} catch {
|
|
17512
|
+
}
|
|
17513
|
+
}
|
|
17514
|
+
return metadata;
|
|
17515
|
+
}
|
|
17516
|
+
function extractOpenAIBatchInput(endpoint, params) {
|
|
17517
|
+
const input = endpoint === "/v1/chat/completions" ? params.messages : params.input;
|
|
17518
|
+
return {
|
|
17519
|
+
input: processInputAttachments(input),
|
|
17520
|
+
metadata: batchMetadata(params)
|
|
17521
|
+
};
|
|
17522
|
+
}
|
|
17523
|
+
function extractOpenAIChatInput(params) {
|
|
17524
|
+
const { messages, ...metadata } = params;
|
|
17525
|
+
return {
|
|
17526
|
+
input: processInputAttachments(messages),
|
|
17527
|
+
metadata: { ...metadata, provider: "openai" }
|
|
17528
|
+
};
|
|
17529
|
+
}
|
|
17530
|
+
function extractOpenAIResponsesInput(params) {
|
|
17531
|
+
const { input, ...metadata } = params;
|
|
17532
|
+
return {
|
|
17533
|
+
input: processInputAttachments(input),
|
|
17534
|
+
metadata: { ...metadata, provider: "openai" }
|
|
17535
|
+
};
|
|
17536
|
+
}
|
|
17537
|
+
function extractOpenAIResponsesMetadata(result) {
|
|
17538
|
+
if (!result) {
|
|
17539
|
+
return void 0;
|
|
17540
|
+
}
|
|
17541
|
+
const { output: _output, usage: _usage, ...metadata } = result;
|
|
17542
|
+
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
17543
|
+
}
|
|
17544
|
+
function processImagesInOutput(output) {
|
|
17545
|
+
if (Array.isArray(output)) {
|
|
17546
|
+
return output.map(processImagesInOutput);
|
|
17547
|
+
}
|
|
17548
|
+
if (isObject(output) && output.type === "image_generation_call" && typeof output.result === "string" && output.result) {
|
|
17549
|
+
const fileExtension = output.output_format || "png";
|
|
17550
|
+
const contentType = `image/${fileExtension}`;
|
|
17551
|
+
const baseFilename = typeof output.revised_prompt === "string" ? output.revised_prompt.slice(0, 50).replace(/[^a-zA-Z0-9]/g, "_") : "generated_image";
|
|
17552
|
+
let binaryString;
|
|
17553
|
+
try {
|
|
17554
|
+
binaryString = atob(output.result);
|
|
17555
|
+
} catch {
|
|
17556
|
+
return output;
|
|
17557
|
+
}
|
|
17558
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
17559
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
17560
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
17561
|
+
}
|
|
17562
|
+
return {
|
|
17563
|
+
...output,
|
|
17564
|
+
result: new Attachment({
|
|
17565
|
+
data: new Blob([bytes], { type: contentType }),
|
|
17566
|
+
filename: `${baseFilename}.${fileExtension}`,
|
|
17567
|
+
contentType
|
|
17568
|
+
})
|
|
17569
|
+
};
|
|
17570
|
+
}
|
|
17571
|
+
return output;
|
|
17421
17572
|
}
|
|
17422
|
-
|
|
17423
|
-
// src/instrumentation/plugins/openai-channels.ts
|
|
17424
|
-
var openAIChannels = defineChannels(
|
|
17425
|
-
"openai",
|
|
17426
|
-
{
|
|
17427
|
-
chatCompletionsCreate: channel({
|
|
17428
|
-
channelName: "chat.completions.create",
|
|
17429
|
-
kind: "async"
|
|
17430
|
-
}),
|
|
17431
|
-
embeddingsCreate: channel({
|
|
17432
|
-
channelName: "embeddings.create",
|
|
17433
|
-
kind: "async"
|
|
17434
|
-
}),
|
|
17435
|
-
betaChatCompletionsParse: channel({
|
|
17436
|
-
channelName: "beta.chat.completions.parse",
|
|
17437
|
-
kind: "async"
|
|
17438
|
-
}),
|
|
17439
|
-
betaChatCompletionsStream: channel({
|
|
17440
|
-
channelName: "beta.chat.completions.stream",
|
|
17441
|
-
kind: "sync-stream"
|
|
17442
|
-
}),
|
|
17443
|
-
moderationsCreate: channel({
|
|
17444
|
-
channelName: "moderations.create",
|
|
17445
|
-
kind: "async"
|
|
17446
|
-
}),
|
|
17447
|
-
responsesCreate: channel({
|
|
17448
|
-
channelName: "responses.create",
|
|
17449
|
-
kind: "async"
|
|
17450
|
-
}),
|
|
17451
|
-
responsesStream: channel({
|
|
17452
|
-
channelName: "responses.stream",
|
|
17453
|
-
kind: "sync-stream"
|
|
17454
|
-
}),
|
|
17455
|
-
responsesParse: channel({
|
|
17456
|
-
channelName: "responses.parse",
|
|
17457
|
-
kind: "async"
|
|
17458
|
-
}),
|
|
17459
|
-
responsesCompact: channel({
|
|
17460
|
-
channelName: "responses.compact",
|
|
17461
|
-
kind: "async"
|
|
17462
|
-
})
|
|
17463
|
-
},
|
|
17464
|
-
{ instrumentationName: INSTRUMENTATION_NAMES.OPENAI }
|
|
17465
|
-
);
|
|
17466
17573
|
|
|
17467
17574
|
// src/openai-utils.ts
|
|
17468
17575
|
var BRAINTRUST_CACHED_STREAM_METRIC = "__braintrust_cached_metric";
|
|
@@ -17519,23 +17626,573 @@ function getCachedMetricFromHeaders(headers) {
|
|
|
17519
17626
|
return parseCachedHeader(headers.get(LEGACY_CACHED_HEADER));
|
|
17520
17627
|
}
|
|
17521
17628
|
|
|
17629
|
+
// src/instrumentation/plugins/openai-batch-instrumentation.ts
|
|
17630
|
+
var SUPPORTED_ENDPOINTS = /* @__PURE__ */ new Set(["/v1/chat/completions", "/v1/responses"]);
|
|
17631
|
+
var TERMINAL_STATUSES = /* @__PURE__ */ new Set([
|
|
17632
|
+
"completed",
|
|
17633
|
+
"failed",
|
|
17634
|
+
"expired",
|
|
17635
|
+
"cancelled"
|
|
17636
|
+
]);
|
|
17637
|
+
var pendingBatchTraces = /* @__PURE__ */ new Map();
|
|
17638
|
+
function read(value, key) {
|
|
17639
|
+
if (!isObject(value)) {
|
|
17640
|
+
return void 0;
|
|
17641
|
+
}
|
|
17642
|
+
try {
|
|
17643
|
+
return Reflect.get(value, key);
|
|
17644
|
+
} catch {
|
|
17645
|
+
return void 0;
|
|
17646
|
+
}
|
|
17647
|
+
}
|
|
17648
|
+
function isBatchRecordIterable(value) {
|
|
17649
|
+
if (value === null || typeof value !== "object" && typeof value !== "function") {
|
|
17650
|
+
return false;
|
|
17651
|
+
}
|
|
17652
|
+
return typeof read(value, Symbol.iterator) === "function" || typeof read(value, Symbol.asyncIterator) === "function";
|
|
17653
|
+
}
|
|
17654
|
+
function validCustomId(value) {
|
|
17655
|
+
return typeof value === "string" && value.length > 0 && value.length <= 64;
|
|
17656
|
+
}
|
|
17657
|
+
function logBatchInstrumentationError(context2, error2) {
|
|
17658
|
+
debugLogger.debug(`OpenAI Batch instrumentation ${context2}:`, error2);
|
|
17659
|
+
}
|
|
17660
|
+
async function exportParent(parent) {
|
|
17661
|
+
if ("toStr" in parent && typeof parent.toStr === "function") {
|
|
17662
|
+
return parent.toStr();
|
|
17663
|
+
}
|
|
17664
|
+
if ("export" in parent && typeof parent.export === "function") {
|
|
17665
|
+
return await parent.export();
|
|
17666
|
+
}
|
|
17667
|
+
return void 0;
|
|
17668
|
+
}
|
|
17669
|
+
async function deterministicDigest(namespace, ...parts) {
|
|
17670
|
+
const encoded = new TextEncoder().encode(
|
|
17671
|
+
[namespace, ...parts].map((part) => `${part.length}:${part}`).join("\0")
|
|
17672
|
+
);
|
|
17673
|
+
return new Uint8Array(
|
|
17674
|
+
await globalThis.crypto.subtle.digest("SHA-256", encoded)
|
|
17675
|
+
);
|
|
17676
|
+
}
|
|
17677
|
+
function digestHex(bytes, length) {
|
|
17678
|
+
return Array.from(bytes.slice(0, length)).map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
17679
|
+
}
|
|
17680
|
+
function digestUuid(bytes) {
|
|
17681
|
+
const hex = digestHex(bytes, 16);
|
|
17682
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
17683
|
+
}
|
|
17684
|
+
async function batchSpanIds(inputFileId) {
|
|
17685
|
+
const [row, span, root] = await Promise.all([
|
|
17686
|
+
deterministicDigest("openai:batch:row", inputFileId),
|
|
17687
|
+
deterministicDigest("openai:batch:span", inputFileId),
|
|
17688
|
+
deterministicDigest("openai:batch:root", inputFileId)
|
|
17689
|
+
]);
|
|
17690
|
+
return {
|
|
17691
|
+
rowId: digestUuid(row),
|
|
17692
|
+
spanId: digestHex(span, 8),
|
|
17693
|
+
rootSpanId: digestHex(root, 16)
|
|
17694
|
+
};
|
|
17695
|
+
}
|
|
17696
|
+
async function childSpanIds(inputFileId, customId) {
|
|
17697
|
+
const [row, span] = await Promise.all([
|
|
17698
|
+
deterministicDigest("openai:batch:child:row", inputFileId, customId),
|
|
17699
|
+
deterministicDigest("openai:batch:child:span", inputFileId, customId)
|
|
17700
|
+
]);
|
|
17701
|
+
return { rowId: digestUuid(row), spanId: digestHex(span, 8) };
|
|
17702
|
+
}
|
|
17703
|
+
async function startBatchSpan(context2) {
|
|
17704
|
+
const ids = await batchSpanIds(context2.inputFileId);
|
|
17705
|
+
const parent = SpanComponentsV4.fromStr(context2.parent);
|
|
17706
|
+
const hasParentSpan = Boolean(
|
|
17707
|
+
parent.data.row_id && parent.data.span_id && parent.data.root_span_id
|
|
17708
|
+
);
|
|
17709
|
+
return withCurrent(
|
|
17710
|
+
NOOP_SPAN,
|
|
17711
|
+
() => _internalStartSpanWithInitialMergeAndParentSpanIds(
|
|
17712
|
+
withSpanInstrumentationName(
|
|
17713
|
+
{
|
|
17714
|
+
name: "openai.batch",
|
|
17715
|
+
type: "task" /* TASK */,
|
|
17716
|
+
parent: context2.parent,
|
|
17717
|
+
...!hasParentSpan ? {
|
|
17718
|
+
parentSpanIds: {
|
|
17719
|
+
parentSpanIds: [],
|
|
17720
|
+
rootSpanId: ids.rootSpanId
|
|
17721
|
+
}
|
|
17722
|
+
} : {},
|
|
17723
|
+
spanId: ids.spanId,
|
|
17724
|
+
startTime: context2.taskStartTime,
|
|
17725
|
+
event: {
|
|
17726
|
+
id: ids.rowId,
|
|
17727
|
+
metadata: {
|
|
17728
|
+
endpoint: context2.endpoint,
|
|
17729
|
+
input_file_id: context2.inputFileId,
|
|
17730
|
+
provider: "openai"
|
|
17731
|
+
}
|
|
17732
|
+
}
|
|
17733
|
+
},
|
|
17734
|
+
INSTRUMENTATION_NAMES.OPENAI
|
|
17735
|
+
)
|
|
17736
|
+
)
|
|
17737
|
+
);
|
|
17738
|
+
}
|
|
17739
|
+
async function startBatchChild(context2, taskParent, input) {
|
|
17740
|
+
const ids = await childSpanIds(context2.inputFileId, input.customId);
|
|
17741
|
+
return withCurrent(
|
|
17742
|
+
NOOP_SPAN,
|
|
17743
|
+
() => _internalStartSpanWithInitialMerge(
|
|
17744
|
+
withSpanInstrumentationName(
|
|
17745
|
+
{
|
|
17746
|
+
name: context2.endpoint === "/v1/chat/completions" ? "Chat Completion" : "openai.responses.create",
|
|
17747
|
+
type: "llm" /* LLM */,
|
|
17748
|
+
parent: taskParent,
|
|
17749
|
+
spanId: ids.spanId,
|
|
17750
|
+
startTime: context2.childStartTime,
|
|
17751
|
+
event: {
|
|
17752
|
+
id: ids.rowId,
|
|
17753
|
+
...input.spanData?.input !== void 0 ? { input: input.spanData.input } : {},
|
|
17754
|
+
metadata: {
|
|
17755
|
+
...input.spanData?.metadata,
|
|
17756
|
+
custom_id: input.customId,
|
|
17757
|
+
provider: "openai"
|
|
17758
|
+
}
|
|
17759
|
+
}
|
|
17760
|
+
},
|
|
17761
|
+
INSTRUMENTATION_NAMES.OPENAI
|
|
17762
|
+
)
|
|
17763
|
+
)
|
|
17764
|
+
);
|
|
17765
|
+
}
|
|
17766
|
+
async function* jsonlRecords(file, onIssue = () => {
|
|
17767
|
+
}) {
|
|
17768
|
+
const resolvedFile = await file;
|
|
17769
|
+
if (typeof resolvedFile === "string") {
|
|
17770
|
+
for (const line of resolvedFile.split("\n")) {
|
|
17771
|
+
if (!line.trim()) {
|
|
17772
|
+
continue;
|
|
17773
|
+
}
|
|
17774
|
+
try {
|
|
17775
|
+
yield JSON.parse(line.replace(/\r$/, ""));
|
|
17776
|
+
} catch (error2) {
|
|
17777
|
+
logBatchInstrumentationError("skipped malformed JSONL", error2);
|
|
17778
|
+
onIssue(new Error("OpenAI Batch file contains malformed JSONL"));
|
|
17779
|
+
}
|
|
17780
|
+
}
|
|
17781
|
+
return;
|
|
17782
|
+
}
|
|
17783
|
+
const body = read(resolvedFile, "body");
|
|
17784
|
+
const getReader = read(body, "getReader");
|
|
17785
|
+
if (isObject(body) && typeof getReader === "function") {
|
|
17786
|
+
let reader;
|
|
17787
|
+
try {
|
|
17788
|
+
reader = Reflect.apply(getReader, body, []);
|
|
17789
|
+
const decoder = new TextDecoder();
|
|
17790
|
+
let pending = "";
|
|
17791
|
+
while (true) {
|
|
17792
|
+
const readChunk = read(reader, "read");
|
|
17793
|
+
if (typeof readChunk !== "function") {
|
|
17794
|
+
throw new Error("Response body stream has no read method");
|
|
17795
|
+
}
|
|
17796
|
+
const chunk = await Reflect.apply(readChunk, reader, []);
|
|
17797
|
+
if (!isObject(chunk)) {
|
|
17798
|
+
throw new Error("Response body stream returned an invalid chunk");
|
|
17799
|
+
}
|
|
17800
|
+
if (chunk.done === true) {
|
|
17801
|
+
pending += decoder.decode();
|
|
17802
|
+
break;
|
|
17803
|
+
}
|
|
17804
|
+
if (!(chunk.value instanceof Uint8Array)) {
|
|
17805
|
+
throw new Error("Response body stream returned a non-byte chunk");
|
|
17806
|
+
}
|
|
17807
|
+
pending += decoder.decode(chunk.value, { stream: true });
|
|
17808
|
+
let newline = pending.indexOf("\n");
|
|
17809
|
+
while (newline !== -1) {
|
|
17810
|
+
const line = pending.slice(0, newline).replace(/\r$/, "");
|
|
17811
|
+
pending = pending.slice(newline + 1);
|
|
17812
|
+
if (line.trim()) {
|
|
17813
|
+
try {
|
|
17814
|
+
yield JSON.parse(line);
|
|
17815
|
+
} catch (error2) {
|
|
17816
|
+
logBatchInstrumentationError("skipped malformed JSONL", error2);
|
|
17817
|
+
onIssue(new Error("OpenAI Batch file contains malformed JSONL"));
|
|
17818
|
+
}
|
|
17819
|
+
}
|
|
17820
|
+
newline = pending.indexOf("\n");
|
|
17821
|
+
}
|
|
17822
|
+
}
|
|
17823
|
+
if (pending.trim()) {
|
|
17824
|
+
try {
|
|
17825
|
+
yield JSON.parse(pending.replace(/\r$/, ""));
|
|
17826
|
+
} catch (error2) {
|
|
17827
|
+
logBatchInstrumentationError("skipped malformed JSONL", error2);
|
|
17828
|
+
onIssue(new Error("OpenAI Batch file contains malformed JSONL"));
|
|
17829
|
+
}
|
|
17830
|
+
}
|
|
17831
|
+
} catch (error2) {
|
|
17832
|
+
logBatchInstrumentationError("could not read JSONL response body", error2);
|
|
17833
|
+
onIssue(new Error("OpenAI Batch response body could not be read"));
|
|
17834
|
+
} finally {
|
|
17835
|
+
const releaseLock = read(reader, "releaseLock");
|
|
17836
|
+
if (typeof releaseLock === "function") {
|
|
17837
|
+
try {
|
|
17838
|
+
Reflect.apply(releaseLock, reader, []);
|
|
17839
|
+
} catch (error2) {
|
|
17840
|
+
logBatchInstrumentationError(
|
|
17841
|
+
"could not release stream reader",
|
|
17842
|
+
error2
|
|
17843
|
+
);
|
|
17844
|
+
}
|
|
17845
|
+
}
|
|
17846
|
+
}
|
|
17847
|
+
return;
|
|
17848
|
+
}
|
|
17849
|
+
if (isBatchRecordIterable(resolvedFile)) {
|
|
17850
|
+
for await (const record of resolvedFile) {
|
|
17851
|
+
yield record;
|
|
17852
|
+
}
|
|
17853
|
+
return;
|
|
17854
|
+
}
|
|
17855
|
+
logBatchInstrumentationError("skipped invalid JSONL source", resolvedFile);
|
|
17856
|
+
onIssue(new Error("OpenAI Batch file source is invalid"));
|
|
17857
|
+
}
|
|
17858
|
+
async function readBatchInputs(file) {
|
|
17859
|
+
const inputs = /* @__PURE__ */ new Map();
|
|
17860
|
+
const issues = [];
|
|
17861
|
+
let endpoint;
|
|
17862
|
+
try {
|
|
17863
|
+
for await (const value of jsonlRecords(
|
|
17864
|
+
file,
|
|
17865
|
+
(issue) => issues.push(issue)
|
|
17866
|
+
)) {
|
|
17867
|
+
const customId = read(value, "custom_id");
|
|
17868
|
+
const url = read(value, "url");
|
|
17869
|
+
const body = read(value, "body");
|
|
17870
|
+
if (!validCustomId(customId) || inputs.has(customId) || read(value, "method") !== "POST" || typeof url !== "string" || !SUPPORTED_ENDPOINTS.has(url) || endpoint !== void 0 && endpoint !== url || !isObject(body)) {
|
|
17871
|
+
issues.push(new Error("OpenAI Batch input contains an invalid record"));
|
|
17872
|
+
continue;
|
|
17873
|
+
}
|
|
17874
|
+
endpoint = url;
|
|
17875
|
+
let spanData;
|
|
17876
|
+
try {
|
|
17877
|
+
spanData = extractOpenAIBatchInput(url, body);
|
|
17878
|
+
} catch (error2) {
|
|
17879
|
+
logBatchInstrumentationError("could not extract batch input", error2);
|
|
17880
|
+
}
|
|
17881
|
+
inputs.set(customId, { customId, spanData });
|
|
17882
|
+
}
|
|
17883
|
+
} catch (error2) {
|
|
17884
|
+
logBatchInstrumentationError("could not process input file", error2);
|
|
17885
|
+
issues.push(new Error("OpenAI Batch input file could not be processed"));
|
|
17886
|
+
}
|
|
17887
|
+
if (!endpoint || inputs.size === 0) {
|
|
17888
|
+
issues.push(new Error("OpenAI Batch input contains no supported records"));
|
|
17889
|
+
}
|
|
17890
|
+
return { endpoint, inputs, issues };
|
|
17891
|
+
}
|
|
17892
|
+
async function writePendingSpans(trace, endTime) {
|
|
17893
|
+
const task = await startBatchSpan(trace.context);
|
|
17894
|
+
const taskParent = await task.export();
|
|
17895
|
+
for (const input of trace.inputs.values()) {
|
|
17896
|
+
try {
|
|
17897
|
+
const child = await startBatchChild(trace.context, taskParent, input);
|
|
17898
|
+
if (endTime !== void 0) {
|
|
17899
|
+
child.end({ endTime });
|
|
17900
|
+
}
|
|
17901
|
+
} catch (error2) {
|
|
17902
|
+
logBatchInstrumentationError("could not write batch request span", error2);
|
|
17903
|
+
}
|
|
17904
|
+
}
|
|
17905
|
+
if (endTime !== void 0) {
|
|
17906
|
+
if (trace.status && trace.status !== "completed") {
|
|
17907
|
+
task.log({ error: new Error(`OpenAI Batch ${trace.status}`) });
|
|
17908
|
+
}
|
|
17909
|
+
task.end({ endTime });
|
|
17910
|
+
}
|
|
17911
|
+
}
|
|
17912
|
+
var interceptOpenAIFilesCreateTraced = async (target, thisArg, args) => {
|
|
17913
|
+
const startTime = getCurrentUnixTimestamp();
|
|
17914
|
+
const inputPromise = readBatchInputs(args[0].inputFileContent);
|
|
17915
|
+
const parentPromise = exportParent(args[0].parent);
|
|
17916
|
+
const file = await Reflect.apply(target, thisArg, args);
|
|
17917
|
+
try {
|
|
17918
|
+
const inputFileId = read(file, "id");
|
|
17919
|
+
const [inputData, exportedParent2] = await Promise.all([
|
|
17920
|
+
inputPromise,
|
|
17921
|
+
parentPromise
|
|
17922
|
+
]);
|
|
17923
|
+
if (typeof inputFileId !== "string" || !exportedParent2 || !inputData.endpoint || inputData.issues.length > 0) {
|
|
17924
|
+
if (inputData.issues[0]) {
|
|
17925
|
+
logBatchInstrumentationError(
|
|
17926
|
+
"skipped invalid input file",
|
|
17927
|
+
inputData.issues[0]
|
|
17928
|
+
);
|
|
17929
|
+
}
|
|
17930
|
+
return file;
|
|
17931
|
+
}
|
|
17932
|
+
const trace = {
|
|
17933
|
+
context: {
|
|
17934
|
+
inputFileId,
|
|
17935
|
+
endpoint: inputData.endpoint,
|
|
17936
|
+
parent: exportedParent2,
|
|
17937
|
+
taskStartTime: startTime,
|
|
17938
|
+
childStartTime: startTime
|
|
17939
|
+
},
|
|
17940
|
+
inputs: inputData.inputs
|
|
17941
|
+
};
|
|
17942
|
+
pendingBatchTraces.set(inputFileId, trace);
|
|
17943
|
+
await writePendingSpans(trace);
|
|
17944
|
+
} catch (error2) {
|
|
17945
|
+
logBatchInstrumentationError("could not start batch spans", error2);
|
|
17946
|
+
}
|
|
17947
|
+
return file;
|
|
17948
|
+
};
|
|
17949
|
+
function validTimestamp(value) {
|
|
17950
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0;
|
|
17951
|
+
}
|
|
17952
|
+
function terminalEndTime(batch, startTime) {
|
|
17953
|
+
let timestamp;
|
|
17954
|
+
switch (batch.status) {
|
|
17955
|
+
case "completed":
|
|
17956
|
+
timestamp = batch.completed_at;
|
|
17957
|
+
break;
|
|
17958
|
+
case "failed":
|
|
17959
|
+
timestamp = batch.failed_at;
|
|
17960
|
+
break;
|
|
17961
|
+
case "expired":
|
|
17962
|
+
timestamp = batch.expired_at;
|
|
17963
|
+
break;
|
|
17964
|
+
default:
|
|
17965
|
+
timestamp = batch.cancelled_at;
|
|
17966
|
+
}
|
|
17967
|
+
return validTimestamp(timestamp) ? Math.max(timestamp, startTime) : Math.max(getCurrentUnixTimestamp(), startTime);
|
|
17968
|
+
}
|
|
17969
|
+
async function updateBatchTimestamps(batch) {
|
|
17970
|
+
const trace = pendingBatchTraces.get(batch.input_file_id);
|
|
17971
|
+
if (!trace || trace.context.endpoint !== batch.endpoint) {
|
|
17972
|
+
return;
|
|
17973
|
+
}
|
|
17974
|
+
if (validTimestamp(batch.created_at)) {
|
|
17975
|
+
trace.context.taskStartTime = batch.created_at;
|
|
17976
|
+
}
|
|
17977
|
+
trace.context.childStartTime = validTimestamp(batch.in_progress_at) ? Math.max(batch.in_progress_at, trace.context.taskStartTime) : trace.context.taskStartTime;
|
|
17978
|
+
trace.status = batch.status;
|
|
17979
|
+
if (TERMINAL_STATUSES.has(batch.status)) {
|
|
17980
|
+
trace.endTime = terminalEndTime(batch, trace.context.childStartTime);
|
|
17981
|
+
}
|
|
17982
|
+
await writePendingSpans(trace, trace.endTime);
|
|
17983
|
+
}
|
|
17984
|
+
var interceptOpenAIBatchesRetrieveTraced = (target, thisArg, args) => Promise.resolve(Reflect.apply(target, thisArg, args)).then(async (batch) => {
|
|
17985
|
+
try {
|
|
17986
|
+
await updateBatchTimestamps(batch);
|
|
17987
|
+
} catch (error2) {
|
|
17988
|
+
logBatchInstrumentationError("could not update batch timestamps", error2);
|
|
17989
|
+
}
|
|
17990
|
+
return batch;
|
|
17991
|
+
});
|
|
17992
|
+
function errorFromResult(result) {
|
|
17993
|
+
const error2 = read(result.value, "error");
|
|
17994
|
+
if (isObject(error2)) {
|
|
17995
|
+
const message = read(error2, "message");
|
|
17996
|
+
return new Error(
|
|
17997
|
+
typeof message === "string" ? message : "OpenAI Batch request failed"
|
|
17998
|
+
);
|
|
17999
|
+
}
|
|
18000
|
+
const response = read(result.value, "response");
|
|
18001
|
+
const statusCode = read(response, "status_code");
|
|
18002
|
+
if (result.source === "error" || typeof statusCode === "number" && (statusCode < 200 || statusCode >= 300)) {
|
|
18003
|
+
const message = read(read(read(response, "body"), "error"), "message");
|
|
18004
|
+
return new Error(
|
|
18005
|
+
typeof message === "string" ? message : "OpenAI Batch request failed"
|
|
18006
|
+
);
|
|
18007
|
+
}
|
|
18008
|
+
return void 0;
|
|
18009
|
+
}
|
|
18010
|
+
async function completeBatchResult(context2, taskParent, endTime, input, result) {
|
|
18011
|
+
const child = await startBatchChild(context2, taskParent, input);
|
|
18012
|
+
try {
|
|
18013
|
+
const resultError = errorFromResult(result);
|
|
18014
|
+
const responseBody = read(read(result.value, "response"), "body");
|
|
18015
|
+
if (resultError) {
|
|
18016
|
+
child.log({ error: resultError });
|
|
18017
|
+
} else if (isObject(responseBody)) {
|
|
18018
|
+
const model = read(responseBody, "model");
|
|
18019
|
+
child.log({
|
|
18020
|
+
output: context2.endpoint === "/v1/chat/completions" ? read(responseBody, "choices") : processImagesInOutput(read(responseBody, "output")),
|
|
18021
|
+
...typeof model === "string" ? { metadata: { model } } : {},
|
|
18022
|
+
metrics: parseMetricsFromUsage(read(responseBody, "usage"))
|
|
18023
|
+
});
|
|
18024
|
+
} else {
|
|
18025
|
+
child.log({ error: new Error("OpenAI Batch response body is missing") });
|
|
18026
|
+
}
|
|
18027
|
+
} catch (error2) {
|
|
18028
|
+
child.log({ error: error2 });
|
|
18029
|
+
} finally {
|
|
18030
|
+
child.end({ endTime });
|
|
18031
|
+
}
|
|
18032
|
+
}
|
|
18033
|
+
async function completeResultFile({
|
|
18034
|
+
context: context2,
|
|
18035
|
+
endTime,
|
|
18036
|
+
file,
|
|
18037
|
+
inputs,
|
|
18038
|
+
issues,
|
|
18039
|
+
seen,
|
|
18040
|
+
source,
|
|
18041
|
+
taskParent
|
|
18042
|
+
}) {
|
|
18043
|
+
if (file === void 0) {
|
|
18044
|
+
return;
|
|
18045
|
+
}
|
|
18046
|
+
for await (const value of jsonlRecords(file, (issue) => issues.push(issue))) {
|
|
18047
|
+
const customId = read(value, "custom_id");
|
|
18048
|
+
if (!validCustomId(customId) || !isObject(value)) {
|
|
18049
|
+
issues.push(
|
|
18050
|
+
new Error("OpenAI Batch result is missing a valid custom_id")
|
|
18051
|
+
);
|
|
18052
|
+
continue;
|
|
18053
|
+
}
|
|
18054
|
+
if (seen.has(customId)) {
|
|
18055
|
+
issues.push(new Error("OpenAI Batch result contains a duplicate"));
|
|
18056
|
+
continue;
|
|
18057
|
+
}
|
|
18058
|
+
const input = inputs.get(customId);
|
|
18059
|
+
if (!input) {
|
|
18060
|
+
issues.push(
|
|
18061
|
+
new Error("OpenAI Batch result does not match an input record")
|
|
18062
|
+
);
|
|
18063
|
+
continue;
|
|
18064
|
+
}
|
|
18065
|
+
seen.add(customId);
|
|
18066
|
+
await completeBatchResult(context2, taskParent, endTime, input, {
|
|
18067
|
+
value,
|
|
18068
|
+
source
|
|
18069
|
+
});
|
|
18070
|
+
}
|
|
18071
|
+
}
|
|
18072
|
+
function sameInputs(first, second) {
|
|
18073
|
+
return first.size === second.size && [...first.keys()].every((customId) => second.has(customId));
|
|
18074
|
+
}
|
|
18075
|
+
async function contextForCompletion(inputFileId, inputData) {
|
|
18076
|
+
if (!inputData.endpoint || inputData.issues.length > 0) {
|
|
18077
|
+
return void 0;
|
|
18078
|
+
}
|
|
18079
|
+
const existing = pendingBatchTraces.get(inputFileId);
|
|
18080
|
+
if (existing) {
|
|
18081
|
+
if (existing.context.endpoint !== inputData.endpoint || !sameInputs(existing.inputs, inputData.inputs)) {
|
|
18082
|
+
return void 0;
|
|
18083
|
+
}
|
|
18084
|
+
return { ...existing, inputs: inputData.inputs };
|
|
18085
|
+
}
|
|
18086
|
+
const parent = await exportParent(getSpanParentObject());
|
|
18087
|
+
if (!parent) {
|
|
18088
|
+
return void 0;
|
|
18089
|
+
}
|
|
18090
|
+
const startTime = getCurrentUnixTimestamp();
|
|
18091
|
+
return {
|
|
18092
|
+
context: {
|
|
18093
|
+
inputFileId,
|
|
18094
|
+
endpoint: inputData.endpoint,
|
|
18095
|
+
parent,
|
|
18096
|
+
taskStartTime: startTime,
|
|
18097
|
+
childStartTime: startTime
|
|
18098
|
+
},
|
|
18099
|
+
inputs: inputData.inputs
|
|
18100
|
+
};
|
|
18101
|
+
}
|
|
18102
|
+
async function completeBatch(args) {
|
|
18103
|
+
const inputData = await readBatchInputs(args.inputFileContent);
|
|
18104
|
+
const trace = await contextForCompletion(args.inputFileId, inputData);
|
|
18105
|
+
if (!trace) {
|
|
18106
|
+
logBatchInstrumentationError(
|
|
18107
|
+
"left batch spans pending",
|
|
18108
|
+
inputData.issues[0] ?? new Error("OpenAI Batch input does not match")
|
|
18109
|
+
);
|
|
18110
|
+
return;
|
|
18111
|
+
}
|
|
18112
|
+
const endTime = trace.endTime ?? getCurrentUnixTimestamp();
|
|
18113
|
+
const task = await startBatchSpan(trace.context);
|
|
18114
|
+
const taskParent = await task.export();
|
|
18115
|
+
const issues = [];
|
|
18116
|
+
const seen = /* @__PURE__ */ new Set();
|
|
18117
|
+
await Promise.all([
|
|
18118
|
+
completeResultFile({
|
|
18119
|
+
context: trace.context,
|
|
18120
|
+
endTime,
|
|
18121
|
+
file: args.outputFileContent,
|
|
18122
|
+
inputs: trace.inputs,
|
|
18123
|
+
issues,
|
|
18124
|
+
seen,
|
|
18125
|
+
source: "output",
|
|
18126
|
+
taskParent
|
|
18127
|
+
}),
|
|
18128
|
+
completeResultFile({
|
|
18129
|
+
context: trace.context,
|
|
18130
|
+
endTime,
|
|
18131
|
+
file: args.errorFileContent,
|
|
18132
|
+
inputs: trace.inputs,
|
|
18133
|
+
issues,
|
|
18134
|
+
seen,
|
|
18135
|
+
source: "error",
|
|
18136
|
+
taskParent
|
|
18137
|
+
})
|
|
18138
|
+
]);
|
|
18139
|
+
if (issues.length > 0) {
|
|
18140
|
+
logBatchInstrumentationError("left batch spans pending", issues[0]);
|
|
18141
|
+
return;
|
|
18142
|
+
}
|
|
18143
|
+
const missing = [...trace.inputs.values()].filter(
|
|
18144
|
+
({ customId }) => !seen.has(customId)
|
|
18145
|
+
);
|
|
18146
|
+
if (!trace.status || trace.status === "completed") {
|
|
18147
|
+
if (missing.length > 0) {
|
|
18148
|
+
logBatchInstrumentationError(
|
|
18149
|
+
"left batch spans pending",
|
|
18150
|
+
new Error("OpenAI Batch result files are incomplete")
|
|
18151
|
+
);
|
|
18152
|
+
return;
|
|
18153
|
+
}
|
|
18154
|
+
} else {
|
|
18155
|
+
for (const input of missing) {
|
|
18156
|
+
const child = await startBatchChild(trace.context, taskParent, input);
|
|
18157
|
+
child.log({ error: new Error(`OpenAI Batch ${trace.status}`) });
|
|
18158
|
+
child.end({ endTime });
|
|
18159
|
+
}
|
|
18160
|
+
task.log({ error: new Error(`OpenAI Batch ${trace.status}`) });
|
|
18161
|
+
}
|
|
18162
|
+
task.end({ endTime });
|
|
18163
|
+
pendingBatchTraces.delete(args.inputFileId);
|
|
18164
|
+
}
|
|
18165
|
+
var interceptOpenAIBatchTraceComplete = (target, thisArg, args) => Promise.resolve(Reflect.apply(target, thisArg, args)).then(async (result) => {
|
|
18166
|
+
try {
|
|
18167
|
+
await completeBatch(args[0]);
|
|
18168
|
+
} catch (error2) {
|
|
18169
|
+
logBatchInstrumentationError("could not complete batch", error2);
|
|
18170
|
+
}
|
|
18171
|
+
return result;
|
|
18172
|
+
});
|
|
18173
|
+
|
|
17522
18174
|
// src/instrumentation/plugins/openai-plugin.ts
|
|
17523
18175
|
var OpenAIPlugin = class extends BasePlugin {
|
|
17524
18176
|
constructor() {
|
|
17525
18177
|
super();
|
|
17526
18178
|
}
|
|
17527
18179
|
onEnable() {
|
|
18180
|
+
this.unsubscribers.push(
|
|
18181
|
+
openAIChannels.filesCreateTraced.intercept(
|
|
18182
|
+
interceptOpenAIFilesCreateTraced
|
|
18183
|
+
),
|
|
18184
|
+
openAIChannels.batchesRetrieveTraced.intercept(
|
|
18185
|
+
interceptOpenAIBatchesRetrieveTraced
|
|
18186
|
+
),
|
|
18187
|
+
openAIChannels.batchesCompleteTrace.intercept(
|
|
18188
|
+
interceptOpenAIBatchTraceComplete
|
|
18189
|
+
)
|
|
18190
|
+
);
|
|
17528
18191
|
this.unsubscribers.push(
|
|
17529
18192
|
traceStreamingChannel(openAIChannels.chatCompletionsCreate, {
|
|
17530
18193
|
name: "Chat Completion",
|
|
17531
18194
|
type: "llm" /* LLM */,
|
|
17532
|
-
extractInput: ([params]) =>
|
|
17533
|
-
const { messages, ...metadata } = params;
|
|
17534
|
-
return {
|
|
17535
|
-
input: processInputAttachments(messages),
|
|
17536
|
-
metadata: { ...metadata, provider: "openai" }
|
|
17537
|
-
};
|
|
17538
|
-
},
|
|
18195
|
+
extractInput: ([params]) => extractOpenAIChatInput(params),
|
|
17539
18196
|
extractOutput: (result) => {
|
|
17540
18197
|
return result?.choices;
|
|
17541
18198
|
},
|
|
@@ -17581,13 +18238,7 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
17581
18238
|
traceStreamingChannel(openAIChannels.betaChatCompletionsParse, {
|
|
17582
18239
|
name: "Chat Completion",
|
|
17583
18240
|
type: "llm" /* LLM */,
|
|
17584
|
-
extractInput: ([params]) =>
|
|
17585
|
-
const { messages, ...metadata } = params;
|
|
17586
|
-
return {
|
|
17587
|
-
input: processInputAttachments(messages),
|
|
17588
|
-
metadata: { ...metadata, provider: "openai" }
|
|
17589
|
-
};
|
|
17590
|
-
},
|
|
18241
|
+
extractInput: ([params]) => extractOpenAIChatInput(params),
|
|
17591
18242
|
extractOutput: (result) => {
|
|
17592
18243
|
return result?.choices;
|
|
17593
18244
|
},
|
|
@@ -17609,13 +18260,7 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
17609
18260
|
traceSyncStreamChannel(openAIChannels.betaChatCompletionsStream, {
|
|
17610
18261
|
name: "Chat Completion",
|
|
17611
18262
|
type: "llm" /* LLM */,
|
|
17612
|
-
extractInput: ([params]) =>
|
|
17613
|
-
const { messages, ...metadata } = params;
|
|
17614
|
-
return {
|
|
17615
|
-
input: processInputAttachments(messages),
|
|
17616
|
-
metadata: { ...metadata, provider: "openai" }
|
|
17617
|
-
};
|
|
17618
|
-
}
|
|
18263
|
+
extractInput: ([params]) => extractOpenAIChatInput(params)
|
|
17619
18264
|
})
|
|
17620
18265
|
);
|
|
17621
18266
|
this.unsubscribers.push(
|
|
@@ -17645,23 +18290,11 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
17645
18290
|
traceStreamingChannel(openAIChannels.responsesCreate, {
|
|
17646
18291
|
name: "openai.responses.create",
|
|
17647
18292
|
type: "llm" /* LLM */,
|
|
17648
|
-
extractInput: ([params]) =>
|
|
17649
|
-
const { input, ...metadata } = params;
|
|
17650
|
-
return {
|
|
17651
|
-
input: processInputAttachments(input),
|
|
17652
|
-
metadata: { ...metadata, provider: "openai" }
|
|
17653
|
-
};
|
|
17654
|
-
},
|
|
18293
|
+
extractInput: ([params]) => extractOpenAIResponsesInput(params),
|
|
17655
18294
|
extractOutput: (result) => {
|
|
17656
18295
|
return processImagesInOutput(result?.output);
|
|
17657
18296
|
},
|
|
17658
|
-
extractMetadata: (result) =>
|
|
17659
|
-
if (!result) {
|
|
17660
|
-
return void 0;
|
|
17661
|
-
}
|
|
17662
|
-
const { output: _output, usage: _usage, ...metadata } = result;
|
|
17663
|
-
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
17664
|
-
},
|
|
18297
|
+
extractMetadata: (result) => extractOpenAIResponsesMetadata(result),
|
|
17665
18298
|
extractMetrics: (result, startTime, endEvent) => {
|
|
17666
18299
|
const metrics = withCachedMetric(
|
|
17667
18300
|
parseMetricsFromUsage(result?.usage),
|
|
@@ -17680,13 +18313,7 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
17680
18313
|
traceSyncStreamChannel(openAIChannels.responsesStream, {
|
|
17681
18314
|
name: "openai.responses.create",
|
|
17682
18315
|
type: "llm" /* LLM */,
|
|
17683
|
-
extractInput: ([params]) =>
|
|
17684
|
-
const { input, ...metadata } = params;
|
|
17685
|
-
return {
|
|
17686
|
-
input: processInputAttachments(input),
|
|
17687
|
-
metadata: { ...metadata, provider: "openai" }
|
|
17688
|
-
};
|
|
17689
|
-
},
|
|
18316
|
+
extractInput: ([params]) => extractOpenAIResponsesInput(params),
|
|
17690
18317
|
extractFromEvent: (event) => {
|
|
17691
18318
|
if (event.type !== "response.completed" || !event.response) {
|
|
17692
18319
|
return {};
|
|
@@ -17709,23 +18336,11 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
17709
18336
|
traceStreamingChannel(openAIChannels.responsesParse, {
|
|
17710
18337
|
name: "openai.responses.parse",
|
|
17711
18338
|
type: "llm" /* LLM */,
|
|
17712
|
-
extractInput: ([params]) =>
|
|
17713
|
-
const { input, ...metadata } = params;
|
|
17714
|
-
return {
|
|
17715
|
-
input: processInputAttachments(input),
|
|
17716
|
-
metadata: { ...metadata, provider: "openai" }
|
|
17717
|
-
};
|
|
17718
|
-
},
|
|
18339
|
+
extractInput: ([params]) => extractOpenAIResponsesInput(params),
|
|
17719
18340
|
extractOutput: (result) => {
|
|
17720
18341
|
return processImagesInOutput(result?.output);
|
|
17721
18342
|
},
|
|
17722
|
-
extractMetadata: (result) =>
|
|
17723
|
-
if (!result) {
|
|
17724
|
-
return void 0;
|
|
17725
|
-
}
|
|
17726
|
-
const { output: _output, usage: _usage, ...metadata } = result;
|
|
17727
|
-
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
17728
|
-
},
|
|
18343
|
+
extractMetadata: (result) => extractOpenAIResponsesMetadata(result),
|
|
17729
18344
|
extractMetrics: (result, startTime, endEvent) => {
|
|
17730
18345
|
const metrics = withCachedMetric(
|
|
17731
18346
|
parseMetricsFromUsage(result?.usage),
|
|
@@ -17744,23 +18359,11 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
17744
18359
|
traceAsyncChannel(openAIChannels.responsesCompact, {
|
|
17745
18360
|
name: "openai.responses.compact",
|
|
17746
18361
|
type: "llm" /* LLM */,
|
|
17747
|
-
extractInput: ([params]) =>
|
|
17748
|
-
const { input, ...metadata } = params;
|
|
17749
|
-
return {
|
|
17750
|
-
input: processInputAttachments(input),
|
|
17751
|
-
metadata: { ...metadata, provider: "openai" }
|
|
17752
|
-
};
|
|
17753
|
-
},
|
|
18362
|
+
extractInput: ([params]) => extractOpenAIResponsesInput(params),
|
|
17754
18363
|
extractOutput: (result) => {
|
|
17755
18364
|
return processImagesInOutput(result?.output);
|
|
17756
18365
|
},
|
|
17757
|
-
extractMetadata: (result) =>
|
|
17758
|
-
if (!result) {
|
|
17759
|
-
return void 0;
|
|
17760
|
-
}
|
|
17761
|
-
const { output: _output, usage: _usage, ...metadata } = result;
|
|
17762
|
-
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
17763
|
-
},
|
|
18366
|
+
extractMetadata: (result) => extractOpenAIResponsesMetadata(result),
|
|
17764
18367
|
extractMetrics: (result, startTime, endEvent) => {
|
|
17765
18368
|
const metrics = withCachedMetric(
|
|
17766
18369
|
parseMetricsFromUsage(result?.usage),
|
|
@@ -17816,35 +18419,6 @@ function withCachedMetric(metrics, result, endEvent) {
|
|
|
17816
18419
|
cached
|
|
17817
18420
|
};
|
|
17818
18421
|
}
|
|
17819
|
-
function processImagesInOutput(output) {
|
|
17820
|
-
if (Array.isArray(output)) {
|
|
17821
|
-
return output.map(processImagesInOutput);
|
|
17822
|
-
}
|
|
17823
|
-
if (isObject(output)) {
|
|
17824
|
-
if (output.type === "image_generation_call" && output.result && typeof output.result === "string") {
|
|
17825
|
-
const fileExtension = output.output_format || "png";
|
|
17826
|
-
const contentType = `image/${fileExtension}`;
|
|
17827
|
-
const baseFilename = output.revised_prompt && typeof output.revised_prompt === "string" ? output.revised_prompt.slice(0, 50).replace(/[^a-zA-Z0-9]/g, "_") : "generated_image";
|
|
17828
|
-
const filename = `${baseFilename}.${fileExtension}`;
|
|
17829
|
-
const binaryString = atob(output.result);
|
|
17830
|
-
const bytes = new Uint8Array(binaryString.length);
|
|
17831
|
-
for (let i = 0; i < binaryString.length; i++) {
|
|
17832
|
-
bytes[i] = binaryString.charCodeAt(i);
|
|
17833
|
-
}
|
|
17834
|
-
const blob = new Blob([bytes], { type: contentType });
|
|
17835
|
-
const attachment = new Attachment({
|
|
17836
|
-
data: blob,
|
|
17837
|
-
filename,
|
|
17838
|
-
contentType
|
|
17839
|
-
});
|
|
17840
|
-
return {
|
|
17841
|
-
...output,
|
|
17842
|
-
result: attachment
|
|
17843
|
-
};
|
|
17844
|
-
}
|
|
17845
|
-
}
|
|
17846
|
-
return output;
|
|
17847
|
-
}
|
|
17848
18422
|
function mergeLogprobTokens(existing, incoming) {
|
|
17849
18423
|
if (incoming === void 0) {
|
|
17850
18424
|
return existing;
|
|
@@ -37864,7 +38438,7 @@ function extractSession(event) {
|
|
|
37864
38438
|
return isObject(candidate) && typeof candidate.prompt === "function" ? candidate : void 0;
|
|
37865
38439
|
}
|
|
37866
38440
|
function isPiAgent(value) {
|
|
37867
|
-
return isObject(value) && typeof value.streamFn === "function" && typeof value.subscribe === "function";
|
|
38441
|
+
return isObject(value) && (typeof value.streamFunction === "function" || typeof value.streamFn === "function") && typeof value.subscribe === "function";
|
|
37868
38442
|
}
|
|
37869
38443
|
function promptContextStore() {
|
|
37870
38444
|
piPromptContextStore ??= isomorph_default.newAsyncLocalStorage();
|
|
@@ -37874,17 +38448,21 @@ function currentPiPromptState() {
|
|
|
37874
38448
|
return promptContextStore().getStore();
|
|
37875
38449
|
}
|
|
37876
38450
|
function installPiAgentInstrumentation(agent) {
|
|
38451
|
+
const property = typeof agent.streamFunction === "function" ? "streamFunction" : "streamFn";
|
|
38452
|
+
const streamFunction = agent[property];
|
|
37877
38453
|
const existing = piAgentPatchStates.get(agent);
|
|
37878
|
-
if (!existing ||
|
|
38454
|
+
if (streamFunction && (!existing || existing.property !== property || streamFunction !== existing.wrappedStreamFunction)) {
|
|
37879
38455
|
const patchState = {
|
|
37880
|
-
|
|
37881
|
-
|
|
38456
|
+
originalStreamFunction: streamFunction,
|
|
38457
|
+
property,
|
|
38458
|
+
wrappedStreamFunction: streamFunction
|
|
37882
38459
|
};
|
|
37883
|
-
patchState.
|
|
38460
|
+
patchState.wrappedStreamFunction = makeInstrumentedStreamFunction(
|
|
37884
38461
|
agent,
|
|
37885
|
-
patchState.
|
|
38462
|
+
patchState.originalStreamFunction,
|
|
38463
|
+
property
|
|
37886
38464
|
);
|
|
37887
|
-
agent
|
|
38465
|
+
agent[property] = patchState.wrappedStreamFunction;
|
|
37888
38466
|
piAgentPatchStates.set(agent, patchState);
|
|
37889
38467
|
}
|
|
37890
38468
|
if (piAgentEventSubscriptions.has(agent)) {
|
|
@@ -37909,15 +38487,21 @@ function installPiAgentInstrumentation(agent) {
|
|
|
37909
38487
|
logInstrumentationError4("Pi Coding Agent event subscription", error2);
|
|
37910
38488
|
}
|
|
37911
38489
|
}
|
|
37912
|
-
function
|
|
37913
|
-
return async function
|
|
37914
|
-
const invokeOriginal = () => Reflect.apply(
|
|
38490
|
+
function makeInstrumentedStreamFunction(agent, originalStreamFunction, property) {
|
|
38491
|
+
return async function instrumentedPiStreamFunction(model, context2, options) {
|
|
38492
|
+
const invokeOriginal = () => Reflect.apply(originalStreamFunction, this, [model, context2, options]);
|
|
37915
38493
|
const state = currentPiPromptState();
|
|
37916
38494
|
if (!state || state.agent !== agent || state.finalized) {
|
|
37917
38495
|
return invokeOriginal();
|
|
37918
38496
|
}
|
|
37919
38497
|
wrapPiToolExecutors(context2.tools);
|
|
37920
|
-
const llmState = await startPiLlmSpan(
|
|
38498
|
+
const llmState = await startPiLlmSpan(
|
|
38499
|
+
state,
|
|
38500
|
+
model,
|
|
38501
|
+
context2,
|
|
38502
|
+
property,
|
|
38503
|
+
options
|
|
38504
|
+
);
|
|
37921
38505
|
try {
|
|
37922
38506
|
const stream = await runWithAutoInstrumentationSuppressed(invokeOriginal);
|
|
37923
38507
|
return patchAssistantMessageStream(stream, state, llmState);
|
|
@@ -37954,12 +38538,12 @@ function wrapPiToolExecutors(tools) {
|
|
|
37954
38538
|
}
|
|
37955
38539
|
}
|
|
37956
38540
|
}
|
|
37957
|
-
async function startPiLlmSpan(state, model, context2, options) {
|
|
38541
|
+
async function startPiLlmSpan(state, model, context2, property, options) {
|
|
37958
38542
|
const metadata = {
|
|
37959
38543
|
...extractModelMetadata2(model),
|
|
37960
38544
|
...extractStreamOptionsMetadata(options),
|
|
37961
38545
|
...extractToolMetadata(context2.tools),
|
|
37962
|
-
"pi_coding_agent.operation":
|
|
38546
|
+
"pi_coding_agent.operation": `agent.${property}`
|
|
37963
38547
|
};
|
|
37964
38548
|
const span = startSpan(
|
|
37965
38549
|
withSpanInstrumentationName(
|
|
@@ -44056,7 +44640,7 @@ var openRouterAgentConfigs = [
|
|
|
44056
44640
|
];
|
|
44057
44641
|
|
|
44058
44642
|
// src/auto-instrumentations/configs/pi-coding-agent.ts
|
|
44059
|
-
var piCodingAgentVersionRange = ">=0.79.0 <0.
|
|
44643
|
+
var piCodingAgentVersionRange = ">=0.79.0 <1.0.0";
|
|
44060
44644
|
var piCodingAgentConfigs = [
|
|
44061
44645
|
{
|
|
44062
44646
|
channelName: piCodingAgentChannels.prompt.channelName,
|