braintrust 3.28.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/README.md +1 -1
- package/dev/dist/index.d.mts +356 -7
- package/dev/dist/index.d.ts +356 -7
- package/dev/dist/index.js +2679 -1828
- package/dev/dist/index.mjs +1862 -1011
- package/dist/apply-auto-instrumentation.js +298 -265
- package/dist/apply-auto-instrumentation.mjs +85 -52
- package/dist/auto-instrumentations/bundler/esbuild.cjs +56 -6
- package/dist/auto-instrumentations/bundler/esbuild.mjs +2 -2
- package/dist/auto-instrumentations/bundler/next.cjs +56 -6
- package/dist/auto-instrumentations/bundler/next.mjs +3 -3
- package/dist/auto-instrumentations/bundler/rollup.cjs +56 -6
- package/dist/auto-instrumentations/bundler/rollup.mjs +2 -2
- package/dist/auto-instrumentations/bundler/vite.cjs +56 -6
- package/dist/auto-instrumentations/bundler/vite.mjs +2 -2
- package/dist/auto-instrumentations/bundler/webpack-loader.cjs +56 -6
- package/dist/auto-instrumentations/bundler/webpack.cjs +56 -6
- package/dist/auto-instrumentations/bundler/webpack.mjs +3 -3
- package/dist/auto-instrumentations/{chunk-26PKVUKB.mjs → chunk-LW4HDHXT.mjs} +12 -4
- package/dist/auto-instrumentations/{chunk-HD35AM3M.mjs → chunk-OXINGIEZ.mjs} +1 -1
- package/dist/auto-instrumentations/{chunk-NP7V4XB2.mjs → chunk-U64OYU4Q.mjs} +45 -3
- package/dist/auto-instrumentations/hook.mjs +967 -136
- package/dist/auto-instrumentations/index.cjs +45 -3
- package/dist/auto-instrumentations/index.mjs +1 -1
- package/dist/browser.d.mts +893 -24
- package/dist/browser.d.ts +893 -24
- package/dist/browser.js +2795 -1136
- package/dist/browser.mjs +2795 -1136
- package/dist/{chunk-BBE7SNRV.js → chunk-2XDW3UCG.js} +155 -23
- package/dist/{chunk-UPFNQCGB.mjs → chunk-BU6SM54N.mjs} +1830 -1045
- package/dist/{chunk-ZHUHZWFY.mjs → chunk-N3JKQ3D3.mjs} +152 -20
- package/dist/{chunk-OBBWQW6K.js → chunk-TWCDSYJN.js} +2890 -2105
- package/dist/cli.js +5976 -1348
- package/dist/edge-light.d.mts +1 -1
- package/dist/edge-light.d.ts +1 -1
- package/dist/edge-light.js +2795 -1136
- package/dist/edge-light.mjs +2795 -1136
- package/dist/index.d.mts +893 -24
- package/dist/index.d.ts +893 -24
- package/dist/index.js +1448 -699
- package/dist/index.mjs +848 -99
- package/dist/instrumentation/index.d.mts +563 -9
- package/dist/instrumentation/index.d.ts +563 -9
- package/dist/instrumentation/index.js +2794 -989
- package/dist/instrumentation/index.mjs +2794 -989
- 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 +2795 -1136
- package/dist/workerd.mjs +2795 -1136
- package/package.json +1 -1
- package/util/dist/index.d.mts +42 -0
- package/util/dist/index.d.ts +42 -0
package/dist/edge-light.mjs
CHANGED
|
@@ -659,8 +659,6 @@ function newGlobalTracingChannel(nameOrChannels) {
|
|
|
659
659
|
var DefaultAsyncLocalStorage = class {
|
|
660
660
|
constructor() {
|
|
661
661
|
}
|
|
662
|
-
enterWith(_) {
|
|
663
|
-
}
|
|
664
662
|
run(_, callback) {
|
|
665
663
|
return callback();
|
|
666
664
|
}
|
|
@@ -2477,7 +2475,9 @@ var AclObjectType = z6.union([
|
|
|
2477
2475
|
"project_log",
|
|
2478
2476
|
"org_project",
|
|
2479
2477
|
"org_audit_logs",
|
|
2480
|
-
"project_group"
|
|
2478
|
+
"project_group",
|
|
2479
|
+
"ai_secret",
|
|
2480
|
+
"org_ai_secret"
|
|
2481
2481
|
]),
|
|
2482
2482
|
z6.null()
|
|
2483
2483
|
]);
|
|
@@ -3310,7 +3310,7 @@ var PromptParserNullish = z6.union([
|
|
|
3310
3310
|
}),
|
|
3311
3311
|
z6.null()
|
|
3312
3312
|
]);
|
|
3313
|
-
var
|
|
3313
|
+
var PreprocessorId = z6.union([
|
|
3314
3314
|
z6.object({
|
|
3315
3315
|
type: z6.literal("function"),
|
|
3316
3316
|
id: z6.string(),
|
|
@@ -3321,6 +3321,7 @@ var PreprocessorSavedFunctionId = z6.union([
|
|
|
3321
3321
|
name: z6.string(),
|
|
3322
3322
|
function_type: z6.literal("preprocessor").optional().default("preprocessor")
|
|
3323
3323
|
}),
|
|
3324
|
+
z6.object({ type: z6.literal("inline"), code: z6.string().min(1) }),
|
|
3324
3325
|
z6.null()
|
|
3325
3326
|
]);
|
|
3326
3327
|
var PromptDataNullish = z6.union([
|
|
@@ -3328,7 +3329,7 @@ var PromptDataNullish = z6.union([
|
|
|
3328
3329
|
prompt: PromptBlockDataNullish,
|
|
3329
3330
|
options: PromptOptionsNullish,
|
|
3330
3331
|
parser: PromptParserNullish,
|
|
3331
|
-
preprocessor:
|
|
3332
|
+
preprocessor: PreprocessorId,
|
|
3332
3333
|
tool_functions: z6.union([z6.array(SavedFunctionId), z6.null()]),
|
|
3333
3334
|
template_format: z6.union([
|
|
3334
3335
|
z6.enum(["mustache", "nunjucks", "none"]),
|
|
@@ -3530,7 +3531,7 @@ var PromptData = z6.object({
|
|
|
3530
3531
|
prompt: PromptBlockDataNullish,
|
|
3531
3532
|
options: PromptOptionsNullish,
|
|
3532
3533
|
parser: PromptParserNullish,
|
|
3533
|
-
preprocessor:
|
|
3534
|
+
preprocessor: PreprocessorId,
|
|
3534
3535
|
tool_functions: z6.union([z6.array(SavedFunctionId), z6.null()]),
|
|
3535
3536
|
template_format: z6.union([
|
|
3536
3537
|
z6.enum(["mustache", "nunjucks", "none"]),
|
|
@@ -4474,6 +4475,7 @@ var View = z6.object({
|
|
|
4474
4475
|
]),
|
|
4475
4476
|
name: z6.string(),
|
|
4476
4477
|
description: z6.union([z6.string(), z6.null()]).optional(),
|
|
4478
|
+
starred: z6.boolean().optional(),
|
|
4477
4479
|
created: z6.union([z6.string(), z6.null()]).optional(),
|
|
4478
4480
|
updated_at: z6.union([z6.string(), z6.null()]).optional(),
|
|
4479
4481
|
view_data: ViewData.optional(),
|
|
@@ -5177,44 +5179,72 @@ function createCacheLayers({
|
|
|
5177
5179
|
}
|
|
5178
5180
|
|
|
5179
5181
|
// src/prompt-cache/prompt-cache.ts
|
|
5180
|
-
function createCacheKey(key) {
|
|
5182
|
+
function createCacheKey(key, namespace) {
|
|
5183
|
+
let cacheKey;
|
|
5181
5184
|
if (key.id) {
|
|
5182
|
-
|
|
5183
|
-
}
|
|
5184
|
-
|
|
5185
|
-
|
|
5186
|
-
|
|
5187
|
-
|
|
5188
|
-
|
|
5189
|
-
|
|
5185
|
+
cacheKey = `id:${key.id}`;
|
|
5186
|
+
} else {
|
|
5187
|
+
const prefix = key.projectId ?? key.projectName;
|
|
5188
|
+
if (!prefix) {
|
|
5189
|
+
throw new Error("Either projectId or projectName must be provided");
|
|
5190
|
+
}
|
|
5191
|
+
if (!key.slug) {
|
|
5192
|
+
throw new Error("Slug must be provided when not using ID");
|
|
5193
|
+
}
|
|
5194
|
+
cacheKey = `${prefix}:${key.slug}:${key.version ?? "latest"}`;
|
|
5190
5195
|
}
|
|
5191
|
-
return `${
|
|
5196
|
+
return namespace === void 0 ? cacheKey : `${namespace.length}:${namespace}:${cacheKey}`;
|
|
5192
5197
|
}
|
|
5193
|
-
var PromptCache = class {
|
|
5198
|
+
var PromptCache = class _PromptCache {
|
|
5194
5199
|
memoryCache;
|
|
5195
5200
|
diskCache;
|
|
5201
|
+
namespace;
|
|
5202
|
+
expectedResolvedOrgIdentity;
|
|
5196
5203
|
constructor(options) {
|
|
5197
5204
|
this.memoryCache = options.memoryCache;
|
|
5198
5205
|
this.diskCache = options.diskCache;
|
|
5206
|
+
this.namespace = options.namespace;
|
|
5207
|
+
this.expectedResolvedOrgIdentity = options.expectedResolvedOrgIdentity;
|
|
5208
|
+
}
|
|
5209
|
+
/**
|
|
5210
|
+
* Returns a cache view that shares the same storage layers but isolates all
|
|
5211
|
+
* entries under the provided namespace.
|
|
5212
|
+
*/
|
|
5213
|
+
withNamespace(namespace, expectedResolvedOrgIdentity) {
|
|
5214
|
+
return new _PromptCache({
|
|
5215
|
+
memoryCache: this.memoryCache,
|
|
5216
|
+
diskCache: this.diskCache,
|
|
5217
|
+
namespace,
|
|
5218
|
+
expectedResolvedOrgIdentity
|
|
5219
|
+
});
|
|
5199
5220
|
}
|
|
5200
5221
|
/**
|
|
5201
5222
|
* Retrieves a prompt from the cache.
|
|
5202
5223
|
* First checks the in-memory LRU cache, then falls back to checking the disk cache if available.
|
|
5203
5224
|
*/
|
|
5204
5225
|
async get(key) {
|
|
5205
|
-
const cacheKey = createCacheKey(key);
|
|
5226
|
+
const cacheKey = createCacheKey(key, this.namespace);
|
|
5206
5227
|
if (this.memoryCache) {
|
|
5207
|
-
const
|
|
5208
|
-
if (
|
|
5209
|
-
return
|
|
5228
|
+
const memoryEntry = this.memoryCache.get(cacheKey);
|
|
5229
|
+
if (memoryEntry !== void 0 && (this.expectedResolvedOrgIdentity === void 0 || memoryEntry.resolvedOrgIdentity === this.expectedResolvedOrgIdentity)) {
|
|
5230
|
+
return memoryEntry.value;
|
|
5210
5231
|
}
|
|
5211
5232
|
}
|
|
5212
5233
|
if (this.diskCache) {
|
|
5213
|
-
const
|
|
5214
|
-
if (!
|
|
5234
|
+
const diskEntry = await this.diskCache.get(cacheKey);
|
|
5235
|
+
if (!diskEntry || this.expectedResolvedOrgIdentity !== void 0 && diskEntry.resolvedOrgIdentity !== this.expectedResolvedOrgIdentity) {
|
|
5215
5236
|
return void 0;
|
|
5216
5237
|
}
|
|
5217
|
-
|
|
5238
|
+
const serializedPrompt = diskEntry.value;
|
|
5239
|
+
const diskPrompt = new Prompt2(
|
|
5240
|
+
serializedPrompt.metadata,
|
|
5241
|
+
serializedPrompt.defaults,
|
|
5242
|
+
serializedPrompt.noTrace
|
|
5243
|
+
);
|
|
5244
|
+
this.memoryCache?.set(cacheKey, {
|
|
5245
|
+
value: diskPrompt,
|
|
5246
|
+
resolvedOrgIdentity: diskEntry.resolvedOrgIdentity
|
|
5247
|
+
});
|
|
5218
5248
|
return diskPrompt;
|
|
5219
5249
|
}
|
|
5220
5250
|
return void 0;
|
|
@@ -5228,58 +5258,91 @@ var PromptCache = class {
|
|
|
5228
5258
|
* @throws If there is an error writing to the disk cache.
|
|
5229
5259
|
*/
|
|
5230
5260
|
async set(key, value) {
|
|
5231
|
-
const cacheKey = createCacheKey(key);
|
|
5232
|
-
|
|
5261
|
+
const cacheKey = createCacheKey(key, this.namespace);
|
|
5262
|
+
const memoryEntry = {
|
|
5263
|
+
value,
|
|
5264
|
+
resolvedOrgIdentity: this.expectedResolvedOrgIdentity
|
|
5265
|
+
};
|
|
5266
|
+
this.memoryCache?.set(cacheKey, memoryEntry);
|
|
5233
5267
|
if (this.diskCache) {
|
|
5234
|
-
await this.diskCache.set(cacheKey,
|
|
5268
|
+
await this.diskCache.set(cacheKey, {
|
|
5269
|
+
value: value._internalSerializeForCache(),
|
|
5270
|
+
resolvedOrgIdentity: this.expectedResolvedOrgIdentity
|
|
5271
|
+
});
|
|
5235
5272
|
}
|
|
5236
5273
|
}
|
|
5237
5274
|
};
|
|
5238
5275
|
|
|
5239
5276
|
// src/prompt-cache/parameters-cache.ts
|
|
5240
|
-
function createCacheKey2(key) {
|
|
5277
|
+
function createCacheKey2(key, namespace) {
|
|
5278
|
+
let cacheKey;
|
|
5241
5279
|
if (key.id) {
|
|
5242
|
-
|
|
5243
|
-
}
|
|
5244
|
-
|
|
5245
|
-
|
|
5246
|
-
|
|
5247
|
-
|
|
5248
|
-
|
|
5249
|
-
|
|
5280
|
+
cacheKey = `parameters:id:${key.id}`;
|
|
5281
|
+
} else {
|
|
5282
|
+
const prefix = key.projectId ?? key.projectName;
|
|
5283
|
+
if (!prefix) {
|
|
5284
|
+
throw new Error("Either projectId or projectName must be provided");
|
|
5285
|
+
}
|
|
5286
|
+
if (!key.slug) {
|
|
5287
|
+
throw new Error("Slug must be provided when not using ID");
|
|
5288
|
+
}
|
|
5289
|
+
cacheKey = `parameters:${prefix}:${key.slug}:${key.version ?? "latest"}`;
|
|
5250
5290
|
}
|
|
5251
|
-
return
|
|
5291
|
+
return namespace === void 0 ? cacheKey : `${namespace.length}:${namespace}:${cacheKey}`;
|
|
5252
5292
|
}
|
|
5253
|
-
var ParametersCache = class {
|
|
5293
|
+
var ParametersCache = class _ParametersCache {
|
|
5254
5294
|
memoryCache;
|
|
5255
5295
|
diskCache;
|
|
5296
|
+
namespace;
|
|
5297
|
+
expectedResolvedOrgIdentity;
|
|
5256
5298
|
constructor(options) {
|
|
5257
5299
|
this.memoryCache = options.memoryCache;
|
|
5258
5300
|
this.diskCache = options.diskCache;
|
|
5301
|
+
this.namespace = options.namespace;
|
|
5302
|
+
this.expectedResolvedOrgIdentity = options.expectedResolvedOrgIdentity;
|
|
5303
|
+
}
|
|
5304
|
+
withNamespace(namespace, expectedResolvedOrgIdentity) {
|
|
5305
|
+
return new _ParametersCache({
|
|
5306
|
+
memoryCache: this.memoryCache,
|
|
5307
|
+
diskCache: this.diskCache,
|
|
5308
|
+
namespace,
|
|
5309
|
+
expectedResolvedOrgIdentity
|
|
5310
|
+
});
|
|
5259
5311
|
}
|
|
5260
5312
|
async get(key) {
|
|
5261
|
-
const cacheKey = createCacheKey2(key);
|
|
5313
|
+
const cacheKey = createCacheKey2(key, this.namespace);
|
|
5262
5314
|
if (this.memoryCache) {
|
|
5263
|
-
const
|
|
5264
|
-
if (
|
|
5265
|
-
return
|
|
5315
|
+
const memoryEntry = this.memoryCache.get(cacheKey);
|
|
5316
|
+
if (memoryEntry !== void 0 && (this.expectedResolvedOrgIdentity === void 0 || memoryEntry.resolvedOrgIdentity === this.expectedResolvedOrgIdentity)) {
|
|
5317
|
+
return memoryEntry.value;
|
|
5266
5318
|
}
|
|
5267
5319
|
}
|
|
5268
5320
|
if (this.diskCache) {
|
|
5269
|
-
const
|
|
5270
|
-
if (!
|
|
5321
|
+
const diskEntry = await this.diskCache.get(cacheKey);
|
|
5322
|
+
if (!diskEntry || this.expectedResolvedOrgIdentity !== void 0 && diskEntry.resolvedOrgIdentity !== this.expectedResolvedOrgIdentity) {
|
|
5271
5323
|
return void 0;
|
|
5272
5324
|
}
|
|
5273
|
-
|
|
5274
|
-
|
|
5325
|
+
const diskParameters = new RemoteEvalParameters(diskEntry.value.metadata);
|
|
5326
|
+
this.memoryCache?.set(cacheKey, {
|
|
5327
|
+
value: diskParameters,
|
|
5328
|
+
resolvedOrgIdentity: diskEntry.resolvedOrgIdentity
|
|
5329
|
+
});
|
|
5330
|
+
return diskParameters;
|
|
5275
5331
|
}
|
|
5276
5332
|
return void 0;
|
|
5277
5333
|
}
|
|
5278
5334
|
async set(key, value) {
|
|
5279
|
-
const cacheKey = createCacheKey2(key);
|
|
5280
|
-
|
|
5335
|
+
const cacheKey = createCacheKey2(key, this.namespace);
|
|
5336
|
+
const memoryEntry = {
|
|
5337
|
+
value,
|
|
5338
|
+
resolvedOrgIdentity: this.expectedResolvedOrgIdentity
|
|
5339
|
+
};
|
|
5340
|
+
this.memoryCache?.set(cacheKey, memoryEntry);
|
|
5281
5341
|
if (this.diskCache) {
|
|
5282
|
-
await this.diskCache.set(cacheKey,
|
|
5342
|
+
await this.diskCache.set(cacheKey, {
|
|
5343
|
+
value: value._internalSerializeForCache(),
|
|
5344
|
+
resolvedOrgIdentity: this.expectedResolvedOrgIdentity
|
|
5345
|
+
});
|
|
5283
5346
|
}
|
|
5284
5347
|
}
|
|
5285
5348
|
};
|
|
@@ -5583,6 +5646,7 @@ var INSTRUMENTATION_NAMES = {
|
|
|
5583
5646
|
CLOUDFLARE_THINK: "cloudflare-think",
|
|
5584
5647
|
COHERE: "cohere",
|
|
5585
5648
|
CURSOR_SDK: "cursor-sdk",
|
|
5649
|
+
DEEPSEEK_HARNESS: "deepseek-harness",
|
|
5586
5650
|
EVE: "eve",
|
|
5587
5651
|
FLUE: "flue",
|
|
5588
5652
|
GENKIT: "genkit",
|
|
@@ -5608,7 +5672,7 @@ var INSTRUMENTATION_NAMES = {
|
|
|
5608
5672
|
var INTERNAL_SPAN_INSTRUMENTATION_NAME = /* @__PURE__ */ Symbol.for(
|
|
5609
5673
|
"braintrust.spanInstrumentationName"
|
|
5610
5674
|
);
|
|
5611
|
-
var SDK_VERSION = true ? "3.
|
|
5675
|
+
var SDK_VERSION = true ? "3.30.0" : "0.0.0";
|
|
5612
5676
|
function withSpanInstrumentationName(args, instrumentationName) {
|
|
5613
5677
|
return {
|
|
5614
5678
|
...args,
|
|
@@ -5727,6 +5791,16 @@ var datasetSnapshotRegisterResponseSchema = z8.object({
|
|
|
5727
5791
|
dataset_snapshot: DatasetSnapshot,
|
|
5728
5792
|
found_existing: z8.boolean().optional()
|
|
5729
5793
|
});
|
|
5794
|
+
var datasetObjectInfoSchema = z8.object({
|
|
5795
|
+
object_id: z8.string(),
|
|
5796
|
+
object_name: z8.string(),
|
|
5797
|
+
parent_cols: z8.object({
|
|
5798
|
+
project: z8.object({
|
|
5799
|
+
id: z8.string(),
|
|
5800
|
+
name: z8.string()
|
|
5801
|
+
})
|
|
5802
|
+
})
|
|
5803
|
+
});
|
|
5730
5804
|
var datasetRestorePreviewResultSchema = z8.object({
|
|
5731
5805
|
rows_to_restore: z8.number(),
|
|
5732
5806
|
rows_to_delete: z8.number()
|
|
@@ -5940,12 +6014,53 @@ var loginSchema = z8.strictObject({
|
|
|
5940
6014
|
});
|
|
5941
6015
|
var stateNonce = 0;
|
|
5942
6016
|
var V1_PROXY_SUFFIX = "/v1/proxy";
|
|
6017
|
+
var LOADER_LOGIN_CACHE_MAX = 16;
|
|
5943
6018
|
function normalizeProxyConnUrl(proxyUrl) {
|
|
5944
6019
|
return proxyUrl.endsWith(V1_PROXY_SUFFIX) ? proxyUrl.slice(0, proxyUrl.length - V1_PROXY_SUFFIX.length) : proxyUrl;
|
|
5945
6020
|
}
|
|
5946
6021
|
var BraintrustState = class _BraintrustState {
|
|
6022
|
+
id;
|
|
6023
|
+
currentExperiment;
|
|
6024
|
+
// Note: the value of IsAsyncFlush doesn't really matter here, since we
|
|
6025
|
+
// (safely) dynamically cast it whenever retrieving the logger.
|
|
6026
|
+
currentLogger;
|
|
6027
|
+
currentParent;
|
|
6028
|
+
currentSpan;
|
|
6029
|
+
// Any time we re-log in, we directly update the apiConn inside the logger.
|
|
6030
|
+
// This is preferable to replacing the whole logger, which would create the
|
|
6031
|
+
// possibility of multiple loggers floating around, which may not log in a
|
|
6032
|
+
// deterministic order.
|
|
6033
|
+
_bgLogger;
|
|
6034
|
+
_overrideBgLogger = null;
|
|
6035
|
+
appUrl = null;
|
|
6036
|
+
appPublicUrl = null;
|
|
6037
|
+
loginToken = null;
|
|
6038
|
+
orgId = null;
|
|
6039
|
+
orgName = null;
|
|
6040
|
+
apiUrl = null;
|
|
6041
|
+
proxyUrl = null;
|
|
6042
|
+
loggedIn = false;
|
|
6043
|
+
gitMetadataSettings;
|
|
6044
|
+
debugLogLevel;
|
|
6045
|
+
debugLogLevelConfigured = false;
|
|
6046
|
+
fetch = globalThis.fetch;
|
|
6047
|
+
_appConn = null;
|
|
6048
|
+
_apiConn = null;
|
|
6049
|
+
_proxyConn = null;
|
|
6050
|
+
promptCache;
|
|
6051
|
+
parametersCache;
|
|
6052
|
+
spanCache;
|
|
6053
|
+
_idGenerator = null;
|
|
6054
|
+
_contextManager = null;
|
|
6055
|
+
_otelFlushCallback = null;
|
|
6056
|
+
spanOriginEnvironment;
|
|
6057
|
+
traceContextSigningSecret;
|
|
6058
|
+
loaderLoginCache = /* @__PURE__ */ new WeakMap();
|
|
6059
|
+
loginParams;
|
|
6060
|
+
activeLoginOrgNameSelector;
|
|
5947
6061
|
constructor(loginParams) {
|
|
5948
|
-
this.loginParams = loginParams;
|
|
6062
|
+
this.loginParams = { ...loginParams };
|
|
6063
|
+
this.activeLoginOrgNameSelector = loginParams.orgName ?? isomorph_default.getEnv("BRAINTRUST_ORG_NAME");
|
|
5949
6064
|
this.id = `${(/* @__PURE__ */ new Date()).toLocaleString()}-${stateNonce++}`;
|
|
5950
6065
|
this.currentExperiment = void 0;
|
|
5951
6066
|
this.currentLogger = void 0;
|
|
@@ -5982,12 +6097,14 @@ var BraintrustState = class _BraintrustState {
|
|
|
5982
6097
|
const {
|
|
5983
6098
|
memoryCache: parametersMemoryCache,
|
|
5984
6099
|
diskCache: parametersDiskCache
|
|
5985
|
-
} = createCacheLayers(
|
|
5986
|
-
|
|
5987
|
-
|
|
5988
|
-
|
|
5989
|
-
|
|
5990
|
-
|
|
6100
|
+
} = createCacheLayers(
|
|
6101
|
+
{
|
|
6102
|
+
memoryMaxEnvVar: "BRAINTRUST_PARAMETERS_CACHE_MEMORY_MAX",
|
|
6103
|
+
diskCacheDirEnvVar: "BRAINTRUST_PARAMETERS_CACHE_DIR",
|
|
6104
|
+
diskMaxEnvVar: "BRAINTRUST_PARAMETERS_CACHE_DISK_MAX",
|
|
6105
|
+
getDefaultDiskCacheDir: () => `${isomorph_default.getEnv("HOME") ?? isomorph_default.homedir()}/.braintrust/parameters_cache`
|
|
6106
|
+
}
|
|
6107
|
+
);
|
|
5991
6108
|
this.parametersCache = new ParametersCache({
|
|
5992
6109
|
memoryCache: parametersMemoryCache,
|
|
5993
6110
|
diskCache: parametersDiskCache
|
|
@@ -5996,43 +6113,6 @@ var BraintrustState = class _BraintrustState {
|
|
|
5996
6113
|
this.spanOriginEnvironment = detectSpanOriginEnvironment();
|
|
5997
6114
|
this._internalSetTraceContextSigningSecret(loginParams.apiKey);
|
|
5998
6115
|
}
|
|
5999
|
-
loginParams;
|
|
6000
|
-
id;
|
|
6001
|
-
currentExperiment;
|
|
6002
|
-
// Note: the value of IsAsyncFlush doesn't really matter here, since we
|
|
6003
|
-
// (safely) dynamically cast it whenever retrieving the logger.
|
|
6004
|
-
currentLogger;
|
|
6005
|
-
currentParent;
|
|
6006
|
-
currentSpan;
|
|
6007
|
-
// Any time we re-log in, we directly update the apiConn inside the logger.
|
|
6008
|
-
// This is preferable to replacing the whole logger, which would create the
|
|
6009
|
-
// possibility of multiple loggers floating around, which may not log in a
|
|
6010
|
-
// deterministic order.
|
|
6011
|
-
_bgLogger;
|
|
6012
|
-
_overrideBgLogger = null;
|
|
6013
|
-
appUrl = null;
|
|
6014
|
-
appPublicUrl = null;
|
|
6015
|
-
loginToken = null;
|
|
6016
|
-
orgId = null;
|
|
6017
|
-
orgName = null;
|
|
6018
|
-
apiUrl = null;
|
|
6019
|
-
proxyUrl = null;
|
|
6020
|
-
loggedIn = false;
|
|
6021
|
-
gitMetadataSettings;
|
|
6022
|
-
debugLogLevel;
|
|
6023
|
-
debugLogLevelConfigured = false;
|
|
6024
|
-
fetch = globalThis.fetch;
|
|
6025
|
-
_appConn = null;
|
|
6026
|
-
_apiConn = null;
|
|
6027
|
-
_proxyConn = null;
|
|
6028
|
-
promptCache;
|
|
6029
|
-
parametersCache;
|
|
6030
|
-
spanCache;
|
|
6031
|
-
_idGenerator = null;
|
|
6032
|
-
_contextManager = null;
|
|
6033
|
-
_otelFlushCallback = null;
|
|
6034
|
-
spanOriginEnvironment;
|
|
6035
|
-
traceContextSigningSecret;
|
|
6036
6116
|
/** @internal */
|
|
6037
6117
|
_internalSetTraceContextSigningSecret(secret) {
|
|
6038
6118
|
const normalizedSecret = secret?.trim();
|
|
@@ -6057,6 +6137,101 @@ var BraintrustState = class _BraintrustState {
|
|
|
6057
6137
|
this._appConn = null;
|
|
6058
6138
|
this._apiConn = null;
|
|
6059
6139
|
this._proxyConn = null;
|
|
6140
|
+
this.loaderLoginCache = /* @__PURE__ */ new WeakMap();
|
|
6141
|
+
}
|
|
6142
|
+
/** @internal */
|
|
6143
|
+
async _internalResolveLoaderLoginOptions({
|
|
6144
|
+
apiKey,
|
|
6145
|
+
appUrl,
|
|
6146
|
+
orgName,
|
|
6147
|
+
fetch: fetch2,
|
|
6148
|
+
forceLogin
|
|
6149
|
+
}) {
|
|
6150
|
+
const resolvedAppUrl = appUrl ?? (this.loggedIn ? this.appUrl ?? void 0 : void 0) ?? this.loginParams.appUrl ?? isomorph_default.getEnv("BRAINTRUST_APP_URL") ?? "https://www.braintrust.dev";
|
|
6151
|
+
const resolvedApiKey = apiKey ?? (this.loggedIn ? this.loginToken ?? void 0 : void 0) ?? this.loginParams.apiKey ?? await isomorph_default.getBraintrustApiKey();
|
|
6152
|
+
if (!resolvedApiKey) {
|
|
6153
|
+
throw new Error(
|
|
6154
|
+
"Please specify an api key (e.g. by setting BRAINTRUST_API_KEY)."
|
|
6155
|
+
);
|
|
6156
|
+
}
|
|
6157
|
+
const normalizedApiKey = HTTPConnection.sanitize_token(resolvedApiKey);
|
|
6158
|
+
const usesActiveCredential = this.loggedIn && normalizedApiKey === this.loginToken;
|
|
6159
|
+
const requestedOrgName = orgName ?? (usesActiveCredential ? this.activeLoginOrgNameSelector : void 0) ?? this.loginParams.orgName ?? isomorph_default.getEnv("BRAINTRUST_ORG_NAME");
|
|
6160
|
+
const resolvedOrgName = orgName ?? (usesActiveCredential ? this.orgName ?? void 0 : void 0) ?? requestedOrgName;
|
|
6161
|
+
const resolvedFetch = fetch2 ?? (this.loggedIn ? this.fetch : void 0) ?? this.loginParams.fetch ?? globalThis.fetch;
|
|
6162
|
+
const credentialCacheNamespace = JSON.stringify([
|
|
6163
|
+
"loader-credential",
|
|
6164
|
+
resolvedAppUrl,
|
|
6165
|
+
requestedOrgName,
|
|
6166
|
+
normalizedApiKey
|
|
6167
|
+
]);
|
|
6168
|
+
return {
|
|
6169
|
+
apiKey: normalizedApiKey,
|
|
6170
|
+
appUrl: resolvedAppUrl,
|
|
6171
|
+
orgName: resolvedOrgName,
|
|
6172
|
+
fetch: resolvedFetch,
|
|
6173
|
+
forceLogin,
|
|
6174
|
+
credentialCacheNamespace,
|
|
6175
|
+
existingState: !forceLogin && usesActiveCredential && resolvedAppUrl === this.appUrl && resolvedOrgName === this.orgName && resolvedFetch === this.fetch ? this : void 0
|
|
6176
|
+
};
|
|
6177
|
+
}
|
|
6178
|
+
/** @internal */
|
|
6179
|
+
_internalGetLoaderCacheViews(loginOptions, requestState) {
|
|
6180
|
+
const expectedResolvedOrgIdentity = requestState?.orgId && requestState.appUrl ? JSON.stringify([
|
|
6181
|
+
"loader-org",
|
|
6182
|
+
requestState.appUrl,
|
|
6183
|
+
requestState.orgId
|
|
6184
|
+
]) : void 0;
|
|
6185
|
+
return {
|
|
6186
|
+
promptCache: this.promptCache.withNamespace(
|
|
6187
|
+
loginOptions.credentialCacheNamespace,
|
|
6188
|
+
expectedResolvedOrgIdentity
|
|
6189
|
+
),
|
|
6190
|
+
parametersCache: this.parametersCache.withNamespace(
|
|
6191
|
+
loginOptions.credentialCacheNamespace,
|
|
6192
|
+
expectedResolvedOrgIdentity
|
|
6193
|
+
)
|
|
6194
|
+
};
|
|
6195
|
+
}
|
|
6196
|
+
/** @internal */
|
|
6197
|
+
async _internalGetLoaderState({
|
|
6198
|
+
apiKey,
|
|
6199
|
+
appUrl,
|
|
6200
|
+
orgName,
|
|
6201
|
+
fetch: fetch2,
|
|
6202
|
+
forceLogin,
|
|
6203
|
+
existingState
|
|
6204
|
+
}) {
|
|
6205
|
+
if (existingState) {
|
|
6206
|
+
return existingState;
|
|
6207
|
+
}
|
|
6208
|
+
let cache = this.loaderLoginCache.get(fetch2);
|
|
6209
|
+
if (!cache) {
|
|
6210
|
+
cache = new LRUCache({ max: LOADER_LOGIN_CACHE_MAX });
|
|
6211
|
+
this.loaderLoginCache.set(fetch2, cache);
|
|
6212
|
+
}
|
|
6213
|
+
const cacheKey = JSON.stringify([appUrl, orgName, apiKey]);
|
|
6214
|
+
if (!forceLogin) {
|
|
6215
|
+
const cachedState = cache.get(cacheKey);
|
|
6216
|
+
if (cachedState) {
|
|
6217
|
+
return cachedState;
|
|
6218
|
+
}
|
|
6219
|
+
}
|
|
6220
|
+
const statePromise = loginToLoaderRequestState({
|
|
6221
|
+
orgName,
|
|
6222
|
+
apiKey,
|
|
6223
|
+
appUrl,
|
|
6224
|
+
fetch: fetch2
|
|
6225
|
+
});
|
|
6226
|
+
cache.set(cacheKey, statePromise);
|
|
6227
|
+
try {
|
|
6228
|
+
return await statePromise;
|
|
6229
|
+
} catch (error) {
|
|
6230
|
+
if (cache.get(cacheKey) === statePromise) {
|
|
6231
|
+
cache.delete(cacheKey);
|
|
6232
|
+
}
|
|
6233
|
+
throw error;
|
|
6234
|
+
}
|
|
6060
6235
|
}
|
|
6061
6236
|
resetIdGenState() {
|
|
6062
6237
|
this._idGenerator = null;
|
|
@@ -6105,6 +6280,8 @@ var BraintrustState = class _BraintrustState {
|
|
|
6105
6280
|
this.debugLogLevel = other.debugLogLevel;
|
|
6106
6281
|
this.debugLogLevelConfigured = other.debugLogLevelConfigured;
|
|
6107
6282
|
this.traceContextSigningSecret = other.traceContextSigningSecret;
|
|
6283
|
+
this.fetch = other.fetch;
|
|
6284
|
+
this.activeLoginOrgNameSelector = other.activeLoginOrgNameSelector;
|
|
6108
6285
|
setGlobalDebugLogLevel(
|
|
6109
6286
|
this.debugLogLevelConfigured ? this.debugLogLevel ?? false : void 0
|
|
6110
6287
|
);
|
|
@@ -6344,36 +6521,85 @@ var FailedHTTPResponse = class extends Error {
|
|
|
6344
6521
|
status;
|
|
6345
6522
|
text;
|
|
6346
6523
|
data;
|
|
6347
|
-
|
|
6524
|
+
cause;
|
|
6525
|
+
constructor(status, text, data, cause) {
|
|
6348
6526
|
super(`${status}: ${text} (${data})`);
|
|
6349
6527
|
this.status = status;
|
|
6350
6528
|
this.text = text;
|
|
6351
6529
|
this.data = data;
|
|
6530
|
+
this.cause = cause;
|
|
6531
|
+
}
|
|
6532
|
+
};
|
|
6533
|
+
var HTTPTransportError = class extends Error {
|
|
6534
|
+
cause;
|
|
6535
|
+
constructor(cause) {
|
|
6536
|
+
super(cause instanceof Error ? cause.message : String(cause));
|
|
6537
|
+
this.name = "HTTPTransportError";
|
|
6538
|
+
this.cause = cause;
|
|
6352
6539
|
}
|
|
6353
6540
|
};
|
|
6541
|
+
var httpTransportErrorCauses = /* @__PURE__ */ new WeakSet();
|
|
6542
|
+
function recordHTTPTransportError(error) {
|
|
6543
|
+
if (typeof error === "object" && error !== null || typeof error === "function") {
|
|
6544
|
+
httpTransportErrorCauses.add(error);
|
|
6545
|
+
}
|
|
6546
|
+
}
|
|
6547
|
+
function rethrowHTTPTransportError(error, classifyTransportErrors) {
|
|
6548
|
+
if (classifyTransportErrors) {
|
|
6549
|
+
throw new HTTPTransportError(error);
|
|
6550
|
+
}
|
|
6551
|
+
recordHTTPTransportError(error);
|
|
6552
|
+
throw error;
|
|
6553
|
+
}
|
|
6554
|
+
function isLoaderCacheFallbackError(error) {
|
|
6555
|
+
if (error instanceof FailedHTTPResponse) {
|
|
6556
|
+
return error.status === 408 || error.status === 429 || error.status >= 500;
|
|
6557
|
+
}
|
|
6558
|
+
if (error instanceof HTTPTransportError) {
|
|
6559
|
+
return true;
|
|
6560
|
+
}
|
|
6561
|
+
return (typeof error === "object" && error !== null || typeof error === "function") && httpTransportErrorCauses.has(error);
|
|
6562
|
+
}
|
|
6563
|
+
async function readJSONResponse(response, classifyTransportErrors = false) {
|
|
6564
|
+
let data;
|
|
6565
|
+
try {
|
|
6566
|
+
data = await response.text();
|
|
6567
|
+
} catch (error) {
|
|
6568
|
+
rethrowHTTPTransportError(error, classifyTransportErrors);
|
|
6569
|
+
}
|
|
6570
|
+
return JSON.parse(data);
|
|
6571
|
+
}
|
|
6354
6572
|
async function checkResponse(resp) {
|
|
6355
6573
|
if (resp.ok) {
|
|
6356
6574
|
return resp;
|
|
6357
|
-
}
|
|
6575
|
+
}
|
|
6576
|
+
let data;
|
|
6577
|
+
try {
|
|
6578
|
+
data = await resp.text();
|
|
6579
|
+
} catch (error) {
|
|
6358
6580
|
throw new FailedHTTPResponse(
|
|
6359
6581
|
resp.status,
|
|
6360
6582
|
resp.statusText,
|
|
6361
|
-
|
|
6583
|
+
"Unable to read response body",
|
|
6584
|
+
error
|
|
6362
6585
|
);
|
|
6363
6586
|
}
|
|
6587
|
+
throw new FailedHTTPResponse(resp.status, resp.statusText, data);
|
|
6364
6588
|
}
|
|
6365
6589
|
var HTTPConnection = class _HTTPConnection {
|
|
6366
|
-
base_url
|
|
6367
|
-
|
|
6368
|
-
headers;
|
|
6369
|
-
fetch;
|
|
6370
|
-
constructor(base_url, fetch2) {
|
|
6590
|
+
constructor(base_url, fetch2, classifyTransportErrors = false) {
|
|
6591
|
+
this.classifyTransportErrors = classifyTransportErrors;
|
|
6371
6592
|
this.base_url = base_url;
|
|
6372
6593
|
this.token = null;
|
|
6373
6594
|
this.headers = {};
|
|
6374
6595
|
this._reset();
|
|
6375
6596
|
this.fetch = fetch2;
|
|
6376
6597
|
}
|
|
6598
|
+
classifyTransportErrors;
|
|
6599
|
+
base_url;
|
|
6600
|
+
token;
|
|
6601
|
+
headers;
|
|
6602
|
+
fetch;
|
|
6377
6603
|
setFetch(fetch2) {
|
|
6378
6604
|
this.fetch = fetch2;
|
|
6379
6605
|
}
|
|
@@ -6413,9 +6639,9 @@ var HTTPConnection = class _HTTPConnection {
|
|
|
6413
6639
|
).toString();
|
|
6414
6640
|
const this_fetch = this.fetch;
|
|
6415
6641
|
const this_headers = this.headers;
|
|
6416
|
-
|
|
6417
|
-
|
|
6418
|
-
await this_fetch(url.toString(), {
|
|
6642
|
+
let response;
|
|
6643
|
+
try {
|
|
6644
|
+
response = await this_fetch(url.toString(), {
|
|
6419
6645
|
headers: {
|
|
6420
6646
|
Accept: "application/json",
|
|
6421
6647
|
...this_headers,
|
|
@@ -6423,8 +6649,14 @@ var HTTPConnection = class _HTTPConnection {
|
|
|
6423
6649
|
},
|
|
6424
6650
|
keepalive: true,
|
|
6425
6651
|
...rest
|
|
6426
|
-
})
|
|
6427
|
-
)
|
|
6652
|
+
});
|
|
6653
|
+
} catch (error) {
|
|
6654
|
+
if (config?.signal?.aborted) {
|
|
6655
|
+
throw getAbortReason(config.signal);
|
|
6656
|
+
}
|
|
6657
|
+
rethrowHTTPTransportError(error, this.classifyTransportErrors);
|
|
6658
|
+
}
|
|
6659
|
+
return await checkResponse(response);
|
|
6428
6660
|
}
|
|
6429
6661
|
async post(path, params, config, retries = 0) {
|
|
6430
6662
|
const { headers, ...rest } = config || {};
|
|
@@ -6434,8 +6666,9 @@ var HTTPConnection = class _HTTPConnection {
|
|
|
6434
6666
|
const tries = retries + 1;
|
|
6435
6667
|
for (let i = 0; i < tries; i++) {
|
|
6436
6668
|
try {
|
|
6437
|
-
|
|
6438
|
-
|
|
6669
|
+
let response;
|
|
6670
|
+
try {
|
|
6671
|
+
response = await this_fetch(_urljoin(this_base_url, path), {
|
|
6439
6672
|
method: "POST",
|
|
6440
6673
|
headers: {
|
|
6441
6674
|
Accept: "application/json",
|
|
@@ -6446,8 +6679,14 @@ var HTTPConnection = class _HTTPConnection {
|
|
|
6446
6679
|
body: typeof params === "string" ? params : params ? JSON.stringify(params) : void 0,
|
|
6447
6680
|
keepalive: true,
|
|
6448
6681
|
...rest
|
|
6449
|
-
})
|
|
6450
|
-
)
|
|
6682
|
+
});
|
|
6683
|
+
} catch (error) {
|
|
6684
|
+
if (config?.signal?.aborted) {
|
|
6685
|
+
throw getAbortReason(config.signal);
|
|
6686
|
+
}
|
|
6687
|
+
rethrowHTTPTransportError(error, this.classifyTransportErrors);
|
|
6688
|
+
}
|
|
6689
|
+
return await checkResponse(response);
|
|
6451
6690
|
} catch (error) {
|
|
6452
6691
|
if (config?.signal?.aborted) {
|
|
6453
6692
|
throw getAbortReason(config.signal);
|
|
@@ -6472,7 +6711,7 @@ var HTTPConnection = class _HTTPConnection {
|
|
|
6472
6711
|
for (let i = 0; i < tries; i++) {
|
|
6473
6712
|
try {
|
|
6474
6713
|
const resp = await this.get(`${object_type}`, args);
|
|
6475
|
-
return await resp.
|
|
6714
|
+
return await readJSONResponse(resp, this.classifyTransportErrors);
|
|
6476
6715
|
} catch (e) {
|
|
6477
6716
|
if (i < tries - 1) {
|
|
6478
6717
|
debugLogger.debug(
|
|
@@ -6495,7 +6734,7 @@ var HTTPConnection = class _HTTPConnection {
|
|
|
6495
6734
|
const resp = await this.post(`${object_type}`, args, {
|
|
6496
6735
|
headers: { "Content-Type": "application/json" }
|
|
6497
6736
|
});
|
|
6498
|
-
return await resp.
|
|
6737
|
+
return await readJSONResponse(resp, this.classifyTransportErrors);
|
|
6499
6738
|
}
|
|
6500
6739
|
// Custom inspect for Node.js console.log
|
|
6501
6740
|
[/* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom")]() {
|
|
@@ -8543,6 +8782,7 @@ function initDataset(projectOrOptions, optionalOptions) {
|
|
|
8543
8782
|
const {
|
|
8544
8783
|
project,
|
|
8545
8784
|
dataset,
|
|
8785
|
+
datasetId,
|
|
8546
8786
|
description,
|
|
8547
8787
|
version,
|
|
8548
8788
|
snapshotName,
|
|
@@ -8558,6 +8798,11 @@ function initDataset(projectOrOptions, optionalOptions) {
|
|
|
8558
8798
|
state: stateArg,
|
|
8559
8799
|
_internal_btql
|
|
8560
8800
|
} = options;
|
|
8801
|
+
if (datasetId !== void 0 && (description !== void 0 || metadata !== void 0)) {
|
|
8802
|
+
throw new Error(
|
|
8803
|
+
"Cannot specify description or metadata when datasetId is provided"
|
|
8804
|
+
);
|
|
8805
|
+
}
|
|
8561
8806
|
const selection = normalizeDatasetSelection({
|
|
8562
8807
|
version,
|
|
8563
8808
|
environment,
|
|
@@ -8578,6 +8823,35 @@ function initDataset(projectOrOptions, optionalOptions) {
|
|
|
8578
8823
|
fetch: fetch2,
|
|
8579
8824
|
forceLogin
|
|
8580
8825
|
});
|
|
8826
|
+
if (datasetId !== void 0) {
|
|
8827
|
+
const objectInfo = datasetObjectInfoSchema.array().parse(
|
|
8828
|
+
await state.appConn().post_json("api/self/get_object_info", {
|
|
8829
|
+
object_type: "dataset",
|
|
8830
|
+
object_ids: [datasetId]
|
|
8831
|
+
})
|
|
8832
|
+
);
|
|
8833
|
+
if (objectInfo.length === 0) {
|
|
8834
|
+
throw new Error(`Dataset with ID ${datasetId} not found`);
|
|
8835
|
+
}
|
|
8836
|
+
if (objectInfo.length !== 1) {
|
|
8837
|
+
throw new Error(
|
|
8838
|
+
`Expected exactly one dataset with ID ${datasetId}, but found ${objectInfo.length}`
|
|
8839
|
+
);
|
|
8840
|
+
}
|
|
8841
|
+
const datasetInfo = objectInfo[0];
|
|
8842
|
+
return {
|
|
8843
|
+
project: {
|
|
8844
|
+
id: datasetInfo.parent_cols.project.id,
|
|
8845
|
+
name: datasetInfo.parent_cols.project.name,
|
|
8846
|
+
fullInfo: datasetInfo.parent_cols.project
|
|
8847
|
+
},
|
|
8848
|
+
dataset: {
|
|
8849
|
+
id: datasetInfo.object_id,
|
|
8850
|
+
name: datasetInfo.object_name,
|
|
8851
|
+
fullInfo: datasetInfo
|
|
8852
|
+
}
|
|
8853
|
+
};
|
|
8854
|
+
}
|
|
8581
8855
|
const args = {
|
|
8582
8856
|
org_id: state.orgId,
|
|
8583
8857
|
project_name: project,
|
|
@@ -8731,6 +9005,24 @@ function initLogger(options = {}) {
|
|
|
8731
9005
|
}
|
|
8732
9006
|
return ret;
|
|
8733
9007
|
}
|
|
9008
|
+
async function runCredentialScopedLoaderRequest(state, loginOptions, request) {
|
|
9009
|
+
const resolvedLoginOptions = await state._internalResolveLoaderLoginOptions(loginOptions);
|
|
9010
|
+
let cacheViews = state._internalGetLoaderCacheViews(resolvedLoginOptions);
|
|
9011
|
+
try {
|
|
9012
|
+
const requestState = await state._internalGetLoaderState(resolvedLoginOptions);
|
|
9013
|
+
cacheViews = state._internalGetLoaderCacheViews(
|
|
9014
|
+
resolvedLoginOptions,
|
|
9015
|
+
requestState
|
|
9016
|
+
);
|
|
9017
|
+
return {
|
|
9018
|
+
ok: true,
|
|
9019
|
+
response: await request(requestState),
|
|
9020
|
+
...cacheViews
|
|
9021
|
+
};
|
|
9022
|
+
} catch (error) {
|
|
9023
|
+
return { ok: false, error, ...cacheViews };
|
|
9024
|
+
}
|
|
9025
|
+
}
|
|
8734
9026
|
async function loadPrompt({
|
|
8735
9027
|
projectName,
|
|
8736
9028
|
projectId,
|
|
@@ -8755,43 +9047,47 @@ async function loadPrompt({
|
|
|
8755
9047
|
throw new Error("Must specify slug");
|
|
8756
9048
|
}
|
|
8757
9049
|
const state = stateArg ?? _globalState;
|
|
8758
|
-
|
|
8759
|
-
|
|
8760
|
-
|
|
8761
|
-
|
|
8762
|
-
|
|
8763
|
-
|
|
8764
|
-
|
|
8765
|
-
|
|
8766
|
-
|
|
8767
|
-
|
|
8768
|
-
|
|
8769
|
-
|
|
8770
|
-
|
|
9050
|
+
const result = await runCredentialScopedLoaderRequest(
|
|
9051
|
+
state,
|
|
9052
|
+
{ orgName, apiKey, appUrl, fetch: fetch2, forceLogin },
|
|
9053
|
+
async (requestState) => {
|
|
9054
|
+
let response2;
|
|
9055
|
+
if (id) {
|
|
9056
|
+
response2 = await requestState.apiConn().get_json(`v1/prompt/${id}`, versionOrEnvironment);
|
|
9057
|
+
if (response2) {
|
|
9058
|
+
response2 = { objects: [response2] };
|
|
9059
|
+
}
|
|
9060
|
+
} else {
|
|
9061
|
+
response2 = await requestState.apiConn().get_json("v1/prompt", {
|
|
9062
|
+
project_name: projectName,
|
|
9063
|
+
project_id: projectId,
|
|
9064
|
+
slug,
|
|
9065
|
+
...versionOrEnvironment
|
|
9066
|
+
});
|
|
8771
9067
|
}
|
|
8772
|
-
|
|
8773
|
-
|
|
8774
|
-
|
|
8775
|
-
|
|
8776
|
-
|
|
8777
|
-
|
|
8778
|
-
|
|
9068
|
+
return response2;
|
|
9069
|
+
}
|
|
9070
|
+
);
|
|
9071
|
+
const { promptCache } = result;
|
|
9072
|
+
if (!result.ok) {
|
|
9073
|
+
const e = result.error;
|
|
9074
|
+
if (!isLoaderCacheFallbackError(e)) {
|
|
9075
|
+
throw e;
|
|
8779
9076
|
}
|
|
8780
|
-
} catch (e) {
|
|
8781
9077
|
if (version || environment) {
|
|
8782
9078
|
throw new Error(`Prompt not found with specified parameters: ${e}`);
|
|
8783
9079
|
}
|
|
8784
9080
|
debugLogger.forState(state).warn("Failed to load prompt, attempting to fall back to cache:", e);
|
|
8785
9081
|
let prompt2;
|
|
8786
9082
|
if (id) {
|
|
8787
|
-
prompt2 = await
|
|
9083
|
+
prompt2 = await promptCache.get({ id });
|
|
8788
9084
|
if (!prompt2) {
|
|
8789
9085
|
throw new Error(
|
|
8790
9086
|
`Prompt with id ${id} not found (not found on server or in local cache): ${e}`
|
|
8791
9087
|
);
|
|
8792
9088
|
}
|
|
8793
9089
|
} else {
|
|
8794
|
-
prompt2 = await
|
|
9090
|
+
prompt2 = await promptCache.get({
|
|
8795
9091
|
slug,
|
|
8796
9092
|
projectId,
|
|
8797
9093
|
projectName,
|
|
@@ -8807,6 +9103,7 @@ async function loadPrompt({
|
|
|
8807
9103
|
}
|
|
8808
9104
|
return prompt2;
|
|
8809
9105
|
}
|
|
9106
|
+
const { response } = result;
|
|
8810
9107
|
if (!("objects" in response) || response.objects.length === 0) {
|
|
8811
9108
|
if (id) {
|
|
8812
9109
|
throw new Error(`Prompt with id ${id} not found.`);
|
|
@@ -8830,9 +9127,9 @@ async function loadPrompt({
|
|
|
8830
9127
|
const prompt = new Prompt2(metadata, defaults || {}, noTrace);
|
|
8831
9128
|
try {
|
|
8832
9129
|
if (id) {
|
|
8833
|
-
await
|
|
9130
|
+
await promptCache.set({ id }, prompt);
|
|
8834
9131
|
} else if (slug) {
|
|
8835
|
-
await
|
|
9132
|
+
await promptCache.set(
|
|
8836
9133
|
{ slug, projectId, projectName, version: version ?? "latest" },
|
|
8837
9134
|
prompt
|
|
8838
9135
|
);
|
|
@@ -8864,46 +9161,50 @@ async function loadParameters({
|
|
|
8864
9161
|
throw new Error("Must specify slug");
|
|
8865
9162
|
}
|
|
8866
9163
|
const state = stateArg ?? _globalState;
|
|
8867
|
-
|
|
8868
|
-
|
|
8869
|
-
|
|
8870
|
-
|
|
8871
|
-
|
|
8872
|
-
|
|
8873
|
-
|
|
8874
|
-
|
|
8875
|
-
|
|
8876
|
-
|
|
8877
|
-
|
|
8878
|
-
|
|
8879
|
-
}
|
|
8880
|
-
|
|
8881
|
-
|
|
9164
|
+
const result = await runCredentialScopedLoaderRequest(
|
|
9165
|
+
state,
|
|
9166
|
+
{ orgName, apiKey, appUrl, fetch: fetch2, forceLogin },
|
|
9167
|
+
async (requestState) => {
|
|
9168
|
+
let response2;
|
|
9169
|
+
if (id) {
|
|
9170
|
+
response2 = await requestState.apiConn().get_json(`v1/function/${id}`, {
|
|
9171
|
+
...versionOrEnvironment
|
|
9172
|
+
});
|
|
9173
|
+
if (response2) {
|
|
9174
|
+
response2 = { objects: [response2] };
|
|
9175
|
+
}
|
|
9176
|
+
} else {
|
|
9177
|
+
response2 = await requestState.apiConn().get_json("v1/function", {
|
|
9178
|
+
project_name: projectName,
|
|
9179
|
+
project_id: projectId,
|
|
9180
|
+
slug,
|
|
9181
|
+
function_type: "parameters",
|
|
9182
|
+
...versionOrEnvironment
|
|
9183
|
+
});
|
|
8882
9184
|
}
|
|
8883
|
-
|
|
8884
|
-
|
|
8885
|
-
|
|
8886
|
-
|
|
8887
|
-
|
|
8888
|
-
|
|
8889
|
-
|
|
8890
|
-
|
|
9185
|
+
return response2;
|
|
9186
|
+
}
|
|
9187
|
+
);
|
|
9188
|
+
const { parametersCache } = result;
|
|
9189
|
+
if (!result.ok) {
|
|
9190
|
+
const e = result.error;
|
|
9191
|
+
if (!isLoaderCacheFallbackError(e)) {
|
|
9192
|
+
throw e;
|
|
8891
9193
|
}
|
|
8892
|
-
} catch (e) {
|
|
8893
9194
|
if (version || environment) {
|
|
8894
9195
|
throw new Error(`Parameters not found with specified parameters: ${e}`);
|
|
8895
9196
|
}
|
|
8896
9197
|
debugLogger.forState(state).warn("Failed to load parameters, attempting to fall back to cache:", e);
|
|
8897
9198
|
let parameters2;
|
|
8898
9199
|
if (id) {
|
|
8899
|
-
parameters2 = await
|
|
9200
|
+
parameters2 = await parametersCache.get({ id });
|
|
8900
9201
|
if (!parameters2) {
|
|
8901
9202
|
throw new Error(
|
|
8902
9203
|
`Parameters with id ${id} not found (not found on server or in local cache): ${e}`
|
|
8903
9204
|
);
|
|
8904
9205
|
}
|
|
8905
9206
|
} else {
|
|
8906
|
-
parameters2 = await
|
|
9207
|
+
parameters2 = await parametersCache.get({
|
|
8907
9208
|
slug,
|
|
8908
9209
|
projectId,
|
|
8909
9210
|
projectName,
|
|
@@ -8919,6 +9220,7 @@ async function loadParameters({
|
|
|
8919
9220
|
}
|
|
8920
9221
|
return parameters2;
|
|
8921
9222
|
}
|
|
9223
|
+
const { response } = result;
|
|
8922
9224
|
if (!("objects" in response) || response.objects.length === 0) {
|
|
8923
9225
|
if (id) {
|
|
8924
9226
|
throw new Error(`Parameters with id ${id} not found.`);
|
|
@@ -8942,9 +9244,9 @@ async function loadParameters({
|
|
|
8942
9244
|
const parameters = new RemoteEvalParameters(metadata);
|
|
8943
9245
|
try {
|
|
8944
9246
|
if (id) {
|
|
8945
|
-
await
|
|
9247
|
+
await parametersCache.set({ id }, parameters);
|
|
8946
9248
|
} else if (slug) {
|
|
8947
|
-
await
|
|
9249
|
+
await parametersCache.set(
|
|
8948
9250
|
{ slug, projectId, projectName, version: version ?? "latest" },
|
|
8949
9251
|
parameters
|
|
8950
9252
|
);
|
|
@@ -8985,6 +9287,52 @@ async function login(options = {}) {
|
|
|
8985
9287
|
await state.login(options);
|
|
8986
9288
|
return state;
|
|
8987
9289
|
}
|
|
9290
|
+
async function loginToLoaderRequestState({
|
|
9291
|
+
appUrl,
|
|
9292
|
+
apiKey,
|
|
9293
|
+
orgName,
|
|
9294
|
+
fetch: fetch2
|
|
9295
|
+
}) {
|
|
9296
|
+
let orgId;
|
|
9297
|
+
let apiUrl;
|
|
9298
|
+
if (apiKey === TEST_API_KEY) {
|
|
9299
|
+
orgId = "test-org-id";
|
|
9300
|
+
apiUrl = "https://braintrust.dev/fake-api-url";
|
|
9301
|
+
} else {
|
|
9302
|
+
let loginResponse;
|
|
9303
|
+
try {
|
|
9304
|
+
loginResponse = await fetch2(_urljoin(appUrl, `/api/apikey/login`), {
|
|
9305
|
+
method: "POST",
|
|
9306
|
+
headers: {
|
|
9307
|
+
"Content-Type": "application/json",
|
|
9308
|
+
Authorization: `Bearer ${apiKey}`
|
|
9309
|
+
}
|
|
9310
|
+
});
|
|
9311
|
+
} catch (error) {
|
|
9312
|
+
throw new HTTPTransportError(error);
|
|
9313
|
+
}
|
|
9314
|
+
const info = await readJSONResponse(
|
|
9315
|
+
await checkResponse(loginResponse),
|
|
9316
|
+
true
|
|
9317
|
+
);
|
|
9318
|
+
const org = selectLoginOrg(info.org_info, orgName);
|
|
9319
|
+
orgId = org.id;
|
|
9320
|
+
apiUrl = isomorph_default.getEnv("BRAINTRUST_API_URL") ?? org.api_url;
|
|
9321
|
+
if (!apiUrl) {
|
|
9322
|
+
throw new Error(
|
|
9323
|
+
orgName ? `Unable to log into organization '${orgName}'. Are you sure this credential is scoped to the organization?` : "Unable to log into any organization with the provided credential."
|
|
9324
|
+
);
|
|
9325
|
+
}
|
|
9326
|
+
}
|
|
9327
|
+
const apiConnection = new HTTPConnection(apiUrl, fetch2, true);
|
|
9328
|
+
apiConnection.set_token(apiKey);
|
|
9329
|
+
apiConnection.make_long_lived();
|
|
9330
|
+
return {
|
|
9331
|
+
appUrl,
|
|
9332
|
+
orgId,
|
|
9333
|
+
apiConn: () => apiConnection
|
|
9334
|
+
};
|
|
9335
|
+
}
|
|
8988
9336
|
async function loginToState(options = {}) {
|
|
8989
9337
|
const {
|
|
8990
9338
|
appUrl = isomorph_default.getEnv("BRAINTRUST_APP_URL") || "https://www.braintrust.dev",
|
|
@@ -9016,16 +9364,18 @@ async function loginToState(options = {}) {
|
|
|
9016
9364
|
_saveOrgInfo(state, testOrgInfo, testOrgInfo[0].name);
|
|
9017
9365
|
return state;
|
|
9018
9366
|
} else {
|
|
9019
|
-
const
|
|
9020
|
-
|
|
9367
|
+
const loginResponse = await fetch2(
|
|
9368
|
+
_urljoin(state.appUrl, `/api/apikey/login`),
|
|
9369
|
+
{
|
|
9021
9370
|
method: "POST",
|
|
9022
9371
|
headers: {
|
|
9023
9372
|
"Content-Type": "application/json",
|
|
9024
9373
|
Authorization: `Bearer ${apiKey}`
|
|
9025
9374
|
}
|
|
9026
|
-
}
|
|
9375
|
+
}
|
|
9027
9376
|
);
|
|
9028
|
-
const
|
|
9377
|
+
const resp = await checkResponse(loginResponse);
|
|
9378
|
+
const info = await readJSONResponse(resp);
|
|
9029
9379
|
_saveOrgInfo(state, info.org_info, orgName);
|
|
9030
9380
|
if (!state.apiUrl) {
|
|
9031
9381
|
if (orgName) {
|
|
@@ -9528,11 +9878,11 @@ function wrapTraced(fn, args) {
|
|
|
9528
9878
|
}
|
|
9529
9879
|
if (args?.asyncFlush) {
|
|
9530
9880
|
return ((...fnArgs) => traced((span) => {
|
|
9531
|
-
if (!hasExplicitInput) {
|
|
9881
|
+
if (!args?.noTraceIO && !hasExplicitInput) {
|
|
9532
9882
|
span.log({ input: fnArgs });
|
|
9533
9883
|
}
|
|
9534
9884
|
const output = fn(...fnArgs);
|
|
9535
|
-
if (!hasExplicitOutput) {
|
|
9885
|
+
if (!args?.noTraceIO && !hasExplicitOutput) {
|
|
9536
9886
|
if (output instanceof Promise) {
|
|
9537
9887
|
return (async () => {
|
|
9538
9888
|
const result = await output;
|
|
@@ -9547,12 +9897,12 @@ function wrapTraced(fn, args) {
|
|
|
9547
9897
|
}, spanArgs));
|
|
9548
9898
|
} else {
|
|
9549
9899
|
return ((...fnArgs) => traced(async (span) => {
|
|
9550
|
-
if (!hasExplicitInput) {
|
|
9900
|
+
if (!args?.noTraceIO && !hasExplicitInput) {
|
|
9551
9901
|
span.log({ input: fnArgs });
|
|
9552
9902
|
}
|
|
9553
9903
|
const outputResult = fn(...fnArgs);
|
|
9554
9904
|
const output = await outputResult;
|
|
9555
|
-
if (!hasExplicitOutput) {
|
|
9905
|
+
if (!args?.noTraceIO && !hasExplicitOutput) {
|
|
9556
9906
|
span.log({ output });
|
|
9557
9907
|
}
|
|
9558
9908
|
return output;
|
|
@@ -9569,6 +9919,15 @@ function _internalStartSpanWithInitialMerge(args) {
|
|
|
9569
9919
|
[INITIAL_SPAN_WRITE_AS_MERGE]: true
|
|
9570
9920
|
}).span;
|
|
9571
9921
|
}
|
|
9922
|
+
function _internalStartSpanWithInitialMergeAndParentSpanIds(args) {
|
|
9923
|
+
return startSpanAndIsLogger(
|
|
9924
|
+
{
|
|
9925
|
+
...args,
|
|
9926
|
+
[INITIAL_SPAN_WRITE_AS_MERGE]: true
|
|
9927
|
+
},
|
|
9928
|
+
{ useParentSpanIdsForObjectParent: true }
|
|
9929
|
+
).span;
|
|
9930
|
+
}
|
|
9572
9931
|
function _internalStartSpanWithContext(args, context) {
|
|
9573
9932
|
return startSpanAndIsLogger({
|
|
9574
9933
|
...args,
|
|
@@ -9582,7 +9941,7 @@ async function flush(options) {
|
|
|
9582
9941
|
function setFetch(fetch2) {
|
|
9583
9942
|
_internalGetGlobalState().setFetch(fetch2);
|
|
9584
9943
|
}
|
|
9585
|
-
function startSpanAndIsLogger(args) {
|
|
9944
|
+
function startSpanAndIsLogger(args, internalOptions) {
|
|
9586
9945
|
const state = args?.state ?? _globalState;
|
|
9587
9946
|
const { parentObject, propagatedState } = getSpanParentObjectAndPropagatedState({
|
|
9588
9947
|
asyncFlush: args?.asyncFlush,
|
|
@@ -9596,7 +9955,7 @@ function startSpanAndIsLogger(args) {
|
|
|
9596
9955
|
) ? {
|
|
9597
9956
|
spanId: parentObject.data.span_id,
|
|
9598
9957
|
rootSpanId: parentObject.data.root_span_id
|
|
9599
|
-
} : void 0;
|
|
9958
|
+
} : internalOptions?.useParentSpanIdsForObjectParent ? args?.parentSpanIds : void 0;
|
|
9600
9959
|
const { parent: _ignoredParent, ...spanArgs } = args ?? {};
|
|
9601
9960
|
const span = new SpanImpl({
|
|
9602
9961
|
state,
|
|
@@ -9678,27 +10037,28 @@ async function* asyncGeneratorWithCurrent(span, gen, state = void 0) {
|
|
|
9678
10037
|
function withParent(parent, callback, state = void 0) {
|
|
9679
10038
|
return (state ?? _globalState).currentParent.run(parent, () => callback());
|
|
9680
10039
|
}
|
|
9681
|
-
function _saveOrgInfo(state,
|
|
9682
|
-
|
|
10040
|
+
function _saveOrgInfo(state, orgInfo, orgName) {
|
|
10041
|
+
const org = selectLoginOrg(orgInfo, orgName);
|
|
10042
|
+
state.orgId = org.id;
|
|
10043
|
+
state.orgName = org.name;
|
|
10044
|
+
state.apiUrl = isomorph_default.getEnv("BRAINTRUST_API_URL") ?? org.api_url;
|
|
10045
|
+
state.proxyUrl = isomorph_default.getEnv("BRAINTRUST_PROXY_URL") ?? org.proxy_url;
|
|
10046
|
+
state.gitMetadataSettings = org.git_metadata || void 0;
|
|
10047
|
+
}
|
|
10048
|
+
function selectLoginOrg(orgInfo, orgName) {
|
|
10049
|
+
if (orgInfo.length === 0) {
|
|
9683
10050
|
throw new LoginInvalidOrgError(
|
|
9684
10051
|
"This user is not part of any organizations."
|
|
9685
10052
|
);
|
|
9686
10053
|
}
|
|
9687
|
-
for (const org of
|
|
9688
|
-
if (
|
|
9689
|
-
|
|
9690
|
-
state.orgName = org.name;
|
|
9691
|
-
state.apiUrl = isomorph_default.getEnv("BRAINTRUST_API_URL") ?? org.api_url;
|
|
9692
|
-
state.proxyUrl = isomorph_default.getEnv("BRAINTRUST_PROXY_URL") ?? org.proxy_url;
|
|
9693
|
-
state.gitMetadataSettings = org.git_metadata || void 0;
|
|
9694
|
-
break;
|
|
10054
|
+
for (const org of orgInfo) {
|
|
10055
|
+
if (orgName === void 0 || org.name === orgName) {
|
|
10056
|
+
return org;
|
|
9695
10057
|
}
|
|
9696
10058
|
}
|
|
9697
|
-
|
|
9698
|
-
|
|
9699
|
-
|
|
9700
|
-
);
|
|
9701
|
-
}
|
|
10059
|
+
throw new LoginInvalidOrgError(
|
|
10060
|
+
`Organization ${orgName} not found. Must be one of ${orgInfo.map((org) => org.name).join(", ")}`
|
|
10061
|
+
);
|
|
9702
10062
|
}
|
|
9703
10063
|
function validateTags(tags) {
|
|
9704
10064
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -11604,6 +11964,14 @@ var Prompt2 = class _Prompt {
|
|
|
11604
11964
|
static isPrompt(data) {
|
|
11605
11965
|
return typeof data === "object" && data !== null && "__braintrust_prompt_marker" in data;
|
|
11606
11966
|
}
|
|
11967
|
+
/** @internal */
|
|
11968
|
+
_internalSerializeForCache() {
|
|
11969
|
+
return {
|
|
11970
|
+
metadata: this.metadata,
|
|
11971
|
+
defaults: this.defaults,
|
|
11972
|
+
noTrace: this.noTrace
|
|
11973
|
+
};
|
|
11974
|
+
}
|
|
11607
11975
|
static fromPromptData(name, promptData) {
|
|
11608
11976
|
return new _Prompt(
|
|
11609
11977
|
{
|
|
@@ -11644,6 +12012,10 @@ var RemoteEvalParameters = class {
|
|
|
11644
12012
|
get data() {
|
|
11645
12013
|
return this.metadata.function_data.data ?? {};
|
|
11646
12014
|
}
|
|
12015
|
+
/** @internal */
|
|
12016
|
+
_internalSerializeForCache() {
|
|
12017
|
+
return { metadata: this.metadata };
|
|
12018
|
+
}
|
|
11647
12019
|
validate(data) {
|
|
11648
12020
|
if (typeof data !== "object" || data === null) {
|
|
11649
12021
|
return false;
|
|
@@ -12464,56 +12836,14 @@ function suppressionStore() {
|
|
|
12464
12836
|
autoInstrumentationSuppressionStore ??= isomorph_default.newAsyncLocalStorage();
|
|
12465
12837
|
return autoInstrumentationSuppressionStore;
|
|
12466
12838
|
}
|
|
12467
|
-
function currentFrames() {
|
|
12468
|
-
return suppressionStore().getStore()?.frames ?? [];
|
|
12469
|
-
}
|
|
12470
12839
|
function isAutoInstrumentationSuppressed() {
|
|
12471
|
-
|
|
12472
|
-
return frames[frames.length - 1]?.mode === "suppress";
|
|
12840
|
+
return suppressionStore().getStore() === true;
|
|
12473
12841
|
}
|
|
12474
12842
|
function runWithAutoInstrumentationSuppressed(callback) {
|
|
12475
|
-
|
|
12476
|
-
id: /* @__PURE__ */ Symbol("braintrust.auto-instrumentation-suppress"),
|
|
12477
|
-
mode: "suppress"
|
|
12478
|
-
};
|
|
12479
|
-
return suppressionStore().run(
|
|
12480
|
-
{ frames: [...currentFrames(), frame] },
|
|
12481
|
-
callback
|
|
12482
|
-
);
|
|
12483
|
-
}
|
|
12484
|
-
function bindAutoInstrumentationSuppressionToStart(tracingChannel) {
|
|
12485
|
-
const startChannel = tracingChannel.start;
|
|
12486
|
-
if (!startChannel) {
|
|
12487
|
-
return void 0;
|
|
12488
|
-
}
|
|
12489
|
-
const store = suppressionStore();
|
|
12490
|
-
startChannel.bindStore(store, () => ({
|
|
12491
|
-
frames: [
|
|
12492
|
-
...currentFrames(),
|
|
12493
|
-
{
|
|
12494
|
-
id: /* @__PURE__ */ Symbol("braintrust.auto-instrumentation-suppress"),
|
|
12495
|
-
mode: "suppress"
|
|
12496
|
-
}
|
|
12497
|
-
]
|
|
12498
|
-
}));
|
|
12499
|
-
return () => {
|
|
12500
|
-
startChannel.unbindStore(store);
|
|
12501
|
-
};
|
|
12843
|
+
return suppressionStore().run(true, callback);
|
|
12502
12844
|
}
|
|
12503
|
-
function
|
|
12504
|
-
|
|
12505
|
-
id: /* @__PURE__ */ Symbol("braintrust.auto-instrumentation-allow"),
|
|
12506
|
-
mode: "allow"
|
|
12507
|
-
};
|
|
12508
|
-
suppressionStore().enterWith({
|
|
12509
|
-
frames: [...currentFrames(), frame]
|
|
12510
|
-
});
|
|
12511
|
-
return () => {
|
|
12512
|
-
const frames = currentFrames().filter(
|
|
12513
|
-
(candidate) => candidate.id !== frame.id
|
|
12514
|
-
);
|
|
12515
|
-
suppressionStore().enterWith(frames.length > 0 ? { frames } : void 0);
|
|
12516
|
-
};
|
|
12845
|
+
function runWithAutoInstrumentationAllowed(callback) {
|
|
12846
|
+
return suppressionStore().run(void 0, callback);
|
|
12517
12847
|
}
|
|
12518
12848
|
|
|
12519
12849
|
// src/instrumentation/core/channel-tracing.ts
|
|
@@ -13103,6 +13433,131 @@ function unsubscribeAll(unsubscribers) {
|
|
|
13103
13433
|
return [];
|
|
13104
13434
|
}
|
|
13105
13435
|
|
|
13436
|
+
// src/instrumentation/core/channel-definitions.ts
|
|
13437
|
+
function channel(spec) {
|
|
13438
|
+
return spec;
|
|
13439
|
+
}
|
|
13440
|
+
function defineChannels(pkg, channels, options) {
|
|
13441
|
+
const { instrumentationName } = options;
|
|
13442
|
+
return Object.fromEntries(
|
|
13443
|
+
Object.entries(channels).map(([key, spec]) => {
|
|
13444
|
+
const fullChannelName = `orchestrion:${pkg}:${spec.channelName}`;
|
|
13445
|
+
if (spec.kind === "async") {
|
|
13446
|
+
const asyncSpec = spec;
|
|
13447
|
+
const tracingChannel2 = () => isomorph_default.newTracingChannel(
|
|
13448
|
+
fullChannelName
|
|
13449
|
+
);
|
|
13450
|
+
const intercept2 = (interceptor) => {
|
|
13451
|
+
const hook = tracingChannel2();
|
|
13452
|
+
return typeof hook.intercept === "function" ? hook.intercept(interceptor) : () => {
|
|
13453
|
+
};
|
|
13454
|
+
};
|
|
13455
|
+
return [
|
|
13456
|
+
key,
|
|
13457
|
+
{
|
|
13458
|
+
...asyncSpec,
|
|
13459
|
+
instrumentationName,
|
|
13460
|
+
intercept: intercept2,
|
|
13461
|
+
invoke: (target, thisArg, args, additional) => {
|
|
13462
|
+
const hook = tracingChannel2();
|
|
13463
|
+
return typeof hook.invoke === "function" ? hook.invoke(target, thisArg, args, additional) : Reflect.apply(target, thisArg, args);
|
|
13464
|
+
},
|
|
13465
|
+
tracingChannel: tracingChannel2,
|
|
13466
|
+
tracePromise: (fn, context) => tracingChannel2().tracePromise(
|
|
13467
|
+
fn,
|
|
13468
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
13469
|
+
context
|
|
13470
|
+
)
|
|
13471
|
+
}
|
|
13472
|
+
];
|
|
13473
|
+
}
|
|
13474
|
+
const syncSpec = spec;
|
|
13475
|
+
const tracingChannel = () => isomorph_default.newTracingChannel(
|
|
13476
|
+
fullChannelName
|
|
13477
|
+
);
|
|
13478
|
+
const intercept = (interceptor) => {
|
|
13479
|
+
const hook = tracingChannel();
|
|
13480
|
+
return typeof hook.intercept === "function" ? hook.intercept(interceptor) : () => {
|
|
13481
|
+
};
|
|
13482
|
+
};
|
|
13483
|
+
return [
|
|
13484
|
+
key,
|
|
13485
|
+
{
|
|
13486
|
+
...syncSpec,
|
|
13487
|
+
instrumentationName,
|
|
13488
|
+
intercept,
|
|
13489
|
+
invoke: (target, thisArg, args, additional) => {
|
|
13490
|
+
const hook = tracingChannel();
|
|
13491
|
+
return typeof hook.invoke === "function" ? hook.invoke(target, thisArg, args, additional) : Reflect.apply(target, thisArg, args);
|
|
13492
|
+
},
|
|
13493
|
+
tracingChannel,
|
|
13494
|
+
traceSync: (fn, context) => tracingChannel().traceSync(
|
|
13495
|
+
fn,
|
|
13496
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
13497
|
+
context
|
|
13498
|
+
)
|
|
13499
|
+
}
|
|
13500
|
+
];
|
|
13501
|
+
})
|
|
13502
|
+
);
|
|
13503
|
+
}
|
|
13504
|
+
|
|
13505
|
+
// src/instrumentation/plugins/openai-channels.ts
|
|
13506
|
+
var openAIChannels = defineChannels(
|
|
13507
|
+
"openai",
|
|
13508
|
+
{
|
|
13509
|
+
filesCreateTraced: channel({
|
|
13510
|
+
channelName: "files.create-traced",
|
|
13511
|
+
kind: "async"
|
|
13512
|
+
}),
|
|
13513
|
+
batchesRetrieveTraced: channel({
|
|
13514
|
+
channelName: "batches.retrieve-traced",
|
|
13515
|
+
kind: "async"
|
|
13516
|
+
}),
|
|
13517
|
+
batchesCompleteTrace: channel({
|
|
13518
|
+
channelName: "batches.complete-trace",
|
|
13519
|
+
kind: "async"
|
|
13520
|
+
}),
|
|
13521
|
+
chatCompletionsCreate: channel({
|
|
13522
|
+
channelName: "chat.completions.create",
|
|
13523
|
+
kind: "async"
|
|
13524
|
+
}),
|
|
13525
|
+
embeddingsCreate: channel({
|
|
13526
|
+
channelName: "embeddings.create",
|
|
13527
|
+
kind: "async"
|
|
13528
|
+
}),
|
|
13529
|
+
betaChatCompletionsParse: channel({
|
|
13530
|
+
channelName: "beta.chat.completions.parse",
|
|
13531
|
+
kind: "async"
|
|
13532
|
+
}),
|
|
13533
|
+
betaChatCompletionsStream: channel({
|
|
13534
|
+
channelName: "beta.chat.completions.stream",
|
|
13535
|
+
kind: "sync-stream"
|
|
13536
|
+
}),
|
|
13537
|
+
moderationsCreate: channel({
|
|
13538
|
+
channelName: "moderations.create",
|
|
13539
|
+
kind: "async"
|
|
13540
|
+
}),
|
|
13541
|
+
responsesCreate: channel({
|
|
13542
|
+
channelName: "responses.create",
|
|
13543
|
+
kind: "async"
|
|
13544
|
+
}),
|
|
13545
|
+
responsesStream: channel({
|
|
13546
|
+
channelName: "responses.stream",
|
|
13547
|
+
kind: "sync-stream"
|
|
13548
|
+
}),
|
|
13549
|
+
responsesParse: channel({
|
|
13550
|
+
channelName: "responses.parse",
|
|
13551
|
+
kind: "async"
|
|
13552
|
+
}),
|
|
13553
|
+
responsesCompact: channel({
|
|
13554
|
+
channelName: "responses.compact",
|
|
13555
|
+
kind: "async"
|
|
13556
|
+
})
|
|
13557
|
+
},
|
|
13558
|
+
{ instrumentationName: INSTRUMENTATION_NAMES.OPENAI }
|
|
13559
|
+
);
|
|
13560
|
+
|
|
13106
13561
|
// src/wrappers/attachment-utils.ts
|
|
13107
13562
|
function getExtensionFromMediaType(mediaType) {
|
|
13108
13563
|
const extensionMap = {
|
|
@@ -13278,118 +13733,91 @@ function processInputAttachments(input) {
|
|
|
13278
13733
|
return processNode(input);
|
|
13279
13734
|
}
|
|
13280
13735
|
|
|
13281
|
-
// src/instrumentation/
|
|
13282
|
-
|
|
13283
|
-
|
|
13284
|
-
|
|
13285
|
-
|
|
13286
|
-
|
|
13287
|
-
|
|
13288
|
-
|
|
13289
|
-
|
|
13290
|
-
|
|
13291
|
-
|
|
13292
|
-
|
|
13293
|
-
|
|
13294
|
-
|
|
13295
|
-
|
|
13296
|
-
|
|
13297
|
-
|
|
13298
|
-
|
|
13299
|
-
|
|
13300
|
-
|
|
13301
|
-
|
|
13302
|
-
|
|
13303
|
-
...asyncSpec,
|
|
13304
|
-
instrumentationName,
|
|
13305
|
-
intercept: intercept2,
|
|
13306
|
-
invoke: (target, thisArg, args, additional) => {
|
|
13307
|
-
const hook = tracingChannel2();
|
|
13308
|
-
return typeof hook.invoke === "function" ? hook.invoke(target, thisArg, args, additional) : Reflect.apply(target, thisArg, args);
|
|
13309
|
-
},
|
|
13310
|
-
tracingChannel: tracingChannel2,
|
|
13311
|
-
tracePromise: (fn, context) => tracingChannel2().tracePromise(
|
|
13312
|
-
fn,
|
|
13313
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
13314
|
-
context
|
|
13315
|
-
)
|
|
13316
|
-
}
|
|
13317
|
-
];
|
|
13736
|
+
// src/instrumentation/plugins/openai-span-data.ts
|
|
13737
|
+
var OPENAI_METADATA_KEYS = [
|
|
13738
|
+
"model",
|
|
13739
|
+
"temperature",
|
|
13740
|
+
"top_p",
|
|
13741
|
+
"max_tokens",
|
|
13742
|
+
"frequency_penalty",
|
|
13743
|
+
"presence_penalty",
|
|
13744
|
+
"stop",
|
|
13745
|
+
"response_format",
|
|
13746
|
+
"tools",
|
|
13747
|
+
"tool_choice",
|
|
13748
|
+
"parallel_tool_calls",
|
|
13749
|
+
"max_tool_calls"
|
|
13750
|
+
];
|
|
13751
|
+
function batchMetadata(params) {
|
|
13752
|
+
const metadata = { provider: "openai" };
|
|
13753
|
+
for (const key of OPENAI_METADATA_KEYS) {
|
|
13754
|
+
try {
|
|
13755
|
+
const value = Reflect.get(params, key);
|
|
13756
|
+
if (value !== void 0) {
|
|
13757
|
+
metadata[key] = value;
|
|
13318
13758
|
}
|
|
13319
|
-
|
|
13320
|
-
|
|
13321
|
-
|
|
13322
|
-
|
|
13323
|
-
|
|
13324
|
-
|
|
13325
|
-
|
|
13326
|
-
|
|
13327
|
-
|
|
13328
|
-
|
|
13329
|
-
|
|
13330
|
-
|
|
13331
|
-
|
|
13332
|
-
|
|
13333
|
-
|
|
13334
|
-
|
|
13335
|
-
|
|
13336
|
-
|
|
13337
|
-
|
|
13338
|
-
|
|
13339
|
-
|
|
13340
|
-
|
|
13341
|
-
|
|
13342
|
-
|
|
13343
|
-
|
|
13344
|
-
|
|
13345
|
-
|
|
13346
|
-
|
|
13347
|
-
|
|
13759
|
+
} catch {
|
|
13760
|
+
}
|
|
13761
|
+
}
|
|
13762
|
+
return metadata;
|
|
13763
|
+
}
|
|
13764
|
+
function extractOpenAIBatchInput(endpoint, params) {
|
|
13765
|
+
const input = endpoint === "/v1/chat/completions" ? params.messages : params.input;
|
|
13766
|
+
return {
|
|
13767
|
+
input: processInputAttachments(input),
|
|
13768
|
+
metadata: batchMetadata(params)
|
|
13769
|
+
};
|
|
13770
|
+
}
|
|
13771
|
+
function extractOpenAIChatInput(params) {
|
|
13772
|
+
const { messages, ...metadata } = params;
|
|
13773
|
+
return {
|
|
13774
|
+
input: processInputAttachments(messages),
|
|
13775
|
+
metadata: { ...metadata, provider: "openai" }
|
|
13776
|
+
};
|
|
13777
|
+
}
|
|
13778
|
+
function extractOpenAIResponsesInput(params) {
|
|
13779
|
+
const { input, ...metadata } = params;
|
|
13780
|
+
return {
|
|
13781
|
+
input: processInputAttachments(input),
|
|
13782
|
+
metadata: { ...metadata, provider: "openai" }
|
|
13783
|
+
};
|
|
13784
|
+
}
|
|
13785
|
+
function extractOpenAIResponsesMetadata(result) {
|
|
13786
|
+
if (!result) {
|
|
13787
|
+
return void 0;
|
|
13788
|
+
}
|
|
13789
|
+
const { output: _output, usage: _usage, ...metadata } = result;
|
|
13790
|
+
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
13791
|
+
}
|
|
13792
|
+
function processImagesInOutput(output) {
|
|
13793
|
+
if (Array.isArray(output)) {
|
|
13794
|
+
return output.map(processImagesInOutput);
|
|
13795
|
+
}
|
|
13796
|
+
if (isObject(output) && output.type === "image_generation_call" && typeof output.result === "string" && output.result) {
|
|
13797
|
+
const fileExtension = output.output_format || "png";
|
|
13798
|
+
const contentType = `image/${fileExtension}`;
|
|
13799
|
+
const baseFilename = typeof output.revised_prompt === "string" ? output.revised_prompt.slice(0, 50).replace(/[^a-zA-Z0-9]/g, "_") : "generated_image";
|
|
13800
|
+
let binaryString;
|
|
13801
|
+
try {
|
|
13802
|
+
binaryString = atob(output.result);
|
|
13803
|
+
} catch {
|
|
13804
|
+
return output;
|
|
13805
|
+
}
|
|
13806
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
13807
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
13808
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
13809
|
+
}
|
|
13810
|
+
return {
|
|
13811
|
+
...output,
|
|
13812
|
+
result: new Attachment({
|
|
13813
|
+
data: new Blob([bytes], { type: contentType }),
|
|
13814
|
+
filename: `${baseFilename}.${fileExtension}`,
|
|
13815
|
+
contentType
|
|
13816
|
+
})
|
|
13817
|
+
};
|
|
13818
|
+
}
|
|
13819
|
+
return output;
|
|
13348
13820
|
}
|
|
13349
|
-
|
|
13350
|
-
// src/instrumentation/plugins/openai-channels.ts
|
|
13351
|
-
var openAIChannels = defineChannels(
|
|
13352
|
-
"openai",
|
|
13353
|
-
{
|
|
13354
|
-
chatCompletionsCreate: channel({
|
|
13355
|
-
channelName: "chat.completions.create",
|
|
13356
|
-
kind: "async"
|
|
13357
|
-
}),
|
|
13358
|
-
embeddingsCreate: channel({
|
|
13359
|
-
channelName: "embeddings.create",
|
|
13360
|
-
kind: "async"
|
|
13361
|
-
}),
|
|
13362
|
-
betaChatCompletionsParse: channel({
|
|
13363
|
-
channelName: "beta.chat.completions.parse",
|
|
13364
|
-
kind: "async"
|
|
13365
|
-
}),
|
|
13366
|
-
betaChatCompletionsStream: channel({
|
|
13367
|
-
channelName: "beta.chat.completions.stream",
|
|
13368
|
-
kind: "sync-stream"
|
|
13369
|
-
}),
|
|
13370
|
-
moderationsCreate: channel({
|
|
13371
|
-
channelName: "moderations.create",
|
|
13372
|
-
kind: "async"
|
|
13373
|
-
}),
|
|
13374
|
-
responsesCreate: channel({
|
|
13375
|
-
channelName: "responses.create",
|
|
13376
|
-
kind: "async"
|
|
13377
|
-
}),
|
|
13378
|
-
responsesStream: channel({
|
|
13379
|
-
channelName: "responses.stream",
|
|
13380
|
-
kind: "sync-stream"
|
|
13381
|
-
}),
|
|
13382
|
-
responsesParse: channel({
|
|
13383
|
-
channelName: "responses.parse",
|
|
13384
|
-
kind: "async"
|
|
13385
|
-
}),
|
|
13386
|
-
responsesCompact: channel({
|
|
13387
|
-
channelName: "responses.compact",
|
|
13388
|
-
kind: "async"
|
|
13389
|
-
})
|
|
13390
|
-
},
|
|
13391
|
-
{ instrumentationName: INSTRUMENTATION_NAMES.OPENAI }
|
|
13392
|
-
);
|
|
13393
13821
|
|
|
13394
13822
|
// src/openai-utils.ts
|
|
13395
13823
|
var BRAINTRUST_CACHED_STREAM_METRIC = "__braintrust_cached_metric";
|
|
@@ -13446,23 +13874,573 @@ function getCachedMetricFromHeaders(headers) {
|
|
|
13446
13874
|
return parseCachedHeader(headers.get(LEGACY_CACHED_HEADER));
|
|
13447
13875
|
}
|
|
13448
13876
|
|
|
13877
|
+
// src/instrumentation/plugins/openai-batch-instrumentation.ts
|
|
13878
|
+
var SUPPORTED_ENDPOINTS = /* @__PURE__ */ new Set(["/v1/chat/completions", "/v1/responses"]);
|
|
13879
|
+
var TERMINAL_STATUSES = /* @__PURE__ */ new Set([
|
|
13880
|
+
"completed",
|
|
13881
|
+
"failed",
|
|
13882
|
+
"expired",
|
|
13883
|
+
"cancelled"
|
|
13884
|
+
]);
|
|
13885
|
+
var pendingBatchTraces = /* @__PURE__ */ new Map();
|
|
13886
|
+
function read(value, key) {
|
|
13887
|
+
if (!isObject(value)) {
|
|
13888
|
+
return void 0;
|
|
13889
|
+
}
|
|
13890
|
+
try {
|
|
13891
|
+
return Reflect.get(value, key);
|
|
13892
|
+
} catch {
|
|
13893
|
+
return void 0;
|
|
13894
|
+
}
|
|
13895
|
+
}
|
|
13896
|
+
function isBatchRecordIterable(value) {
|
|
13897
|
+
if (value === null || typeof value !== "object" && typeof value !== "function") {
|
|
13898
|
+
return false;
|
|
13899
|
+
}
|
|
13900
|
+
return typeof read(value, Symbol.iterator) === "function" || typeof read(value, Symbol.asyncIterator) === "function";
|
|
13901
|
+
}
|
|
13902
|
+
function validCustomId(value) {
|
|
13903
|
+
return typeof value === "string" && value.length > 0 && value.length <= 64;
|
|
13904
|
+
}
|
|
13905
|
+
function logBatchInstrumentationError(context, error) {
|
|
13906
|
+
debugLogger.debug(`OpenAI Batch instrumentation ${context}:`, error);
|
|
13907
|
+
}
|
|
13908
|
+
async function exportParent(parent) {
|
|
13909
|
+
if ("toStr" in parent && typeof parent.toStr === "function") {
|
|
13910
|
+
return parent.toStr();
|
|
13911
|
+
}
|
|
13912
|
+
if ("export" in parent && typeof parent.export === "function") {
|
|
13913
|
+
return await parent.export();
|
|
13914
|
+
}
|
|
13915
|
+
return void 0;
|
|
13916
|
+
}
|
|
13917
|
+
async function deterministicDigest(namespace, ...parts) {
|
|
13918
|
+
const encoded = new TextEncoder().encode(
|
|
13919
|
+
[namespace, ...parts].map((part) => `${part.length}:${part}`).join("\0")
|
|
13920
|
+
);
|
|
13921
|
+
return new Uint8Array(
|
|
13922
|
+
await globalThis.crypto.subtle.digest("SHA-256", encoded)
|
|
13923
|
+
);
|
|
13924
|
+
}
|
|
13925
|
+
function digestHex(bytes, length) {
|
|
13926
|
+
return Array.from(bytes.slice(0, length)).map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
13927
|
+
}
|
|
13928
|
+
function digestUuid(bytes) {
|
|
13929
|
+
const hex = digestHex(bytes, 16);
|
|
13930
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
13931
|
+
}
|
|
13932
|
+
async function batchSpanIds(inputFileId) {
|
|
13933
|
+
const [row, span, root] = await Promise.all([
|
|
13934
|
+
deterministicDigest("openai:batch:row", inputFileId),
|
|
13935
|
+
deterministicDigest("openai:batch:span", inputFileId),
|
|
13936
|
+
deterministicDigest("openai:batch:root", inputFileId)
|
|
13937
|
+
]);
|
|
13938
|
+
return {
|
|
13939
|
+
rowId: digestUuid(row),
|
|
13940
|
+
spanId: digestHex(span, 8),
|
|
13941
|
+
rootSpanId: digestHex(root, 16)
|
|
13942
|
+
};
|
|
13943
|
+
}
|
|
13944
|
+
async function childSpanIds(inputFileId, customId) {
|
|
13945
|
+
const [row, span] = await Promise.all([
|
|
13946
|
+
deterministicDigest("openai:batch:child:row", inputFileId, customId),
|
|
13947
|
+
deterministicDigest("openai:batch:child:span", inputFileId, customId)
|
|
13948
|
+
]);
|
|
13949
|
+
return { rowId: digestUuid(row), spanId: digestHex(span, 8) };
|
|
13950
|
+
}
|
|
13951
|
+
async function startBatchSpan(context) {
|
|
13952
|
+
const ids = await batchSpanIds(context.inputFileId);
|
|
13953
|
+
const parent = SpanComponentsV4.fromStr(context.parent);
|
|
13954
|
+
const hasParentSpan = Boolean(
|
|
13955
|
+
parent.data.row_id && parent.data.span_id && parent.data.root_span_id
|
|
13956
|
+
);
|
|
13957
|
+
return withCurrent(
|
|
13958
|
+
NOOP_SPAN,
|
|
13959
|
+
() => _internalStartSpanWithInitialMergeAndParentSpanIds(
|
|
13960
|
+
withSpanInstrumentationName(
|
|
13961
|
+
{
|
|
13962
|
+
name: "openai.batch",
|
|
13963
|
+
type: "task" /* TASK */,
|
|
13964
|
+
parent: context.parent,
|
|
13965
|
+
...!hasParentSpan ? {
|
|
13966
|
+
parentSpanIds: {
|
|
13967
|
+
parentSpanIds: [],
|
|
13968
|
+
rootSpanId: ids.rootSpanId
|
|
13969
|
+
}
|
|
13970
|
+
} : {},
|
|
13971
|
+
spanId: ids.spanId,
|
|
13972
|
+
startTime: context.taskStartTime,
|
|
13973
|
+
event: {
|
|
13974
|
+
id: ids.rowId,
|
|
13975
|
+
metadata: {
|
|
13976
|
+
endpoint: context.endpoint,
|
|
13977
|
+
input_file_id: context.inputFileId,
|
|
13978
|
+
provider: "openai"
|
|
13979
|
+
}
|
|
13980
|
+
}
|
|
13981
|
+
},
|
|
13982
|
+
INSTRUMENTATION_NAMES.OPENAI
|
|
13983
|
+
)
|
|
13984
|
+
)
|
|
13985
|
+
);
|
|
13986
|
+
}
|
|
13987
|
+
async function startBatchChild(context, taskParent, input) {
|
|
13988
|
+
const ids = await childSpanIds(context.inputFileId, input.customId);
|
|
13989
|
+
return withCurrent(
|
|
13990
|
+
NOOP_SPAN,
|
|
13991
|
+
() => _internalStartSpanWithInitialMerge(
|
|
13992
|
+
withSpanInstrumentationName(
|
|
13993
|
+
{
|
|
13994
|
+
name: context.endpoint === "/v1/chat/completions" ? "Chat Completion" : "openai.responses.create",
|
|
13995
|
+
type: "llm" /* LLM */,
|
|
13996
|
+
parent: taskParent,
|
|
13997
|
+
spanId: ids.spanId,
|
|
13998
|
+
startTime: context.childStartTime,
|
|
13999
|
+
event: {
|
|
14000
|
+
id: ids.rowId,
|
|
14001
|
+
...input.spanData?.input !== void 0 ? { input: input.spanData.input } : {},
|
|
14002
|
+
metadata: {
|
|
14003
|
+
...input.spanData?.metadata,
|
|
14004
|
+
custom_id: input.customId,
|
|
14005
|
+
provider: "openai"
|
|
14006
|
+
}
|
|
14007
|
+
}
|
|
14008
|
+
},
|
|
14009
|
+
INSTRUMENTATION_NAMES.OPENAI
|
|
14010
|
+
)
|
|
14011
|
+
)
|
|
14012
|
+
);
|
|
14013
|
+
}
|
|
14014
|
+
async function* jsonlRecords(file, onIssue = () => {
|
|
14015
|
+
}) {
|
|
14016
|
+
const resolvedFile = await file;
|
|
14017
|
+
if (typeof resolvedFile === "string") {
|
|
14018
|
+
for (const line of resolvedFile.split("\n")) {
|
|
14019
|
+
if (!line.trim()) {
|
|
14020
|
+
continue;
|
|
14021
|
+
}
|
|
14022
|
+
try {
|
|
14023
|
+
yield JSON.parse(line.replace(/\r$/, ""));
|
|
14024
|
+
} catch (error) {
|
|
14025
|
+
logBatchInstrumentationError("skipped malformed JSONL", error);
|
|
14026
|
+
onIssue(new Error("OpenAI Batch file contains malformed JSONL"));
|
|
14027
|
+
}
|
|
14028
|
+
}
|
|
14029
|
+
return;
|
|
14030
|
+
}
|
|
14031
|
+
const body = read(resolvedFile, "body");
|
|
14032
|
+
const getReader = read(body, "getReader");
|
|
14033
|
+
if (isObject(body) && typeof getReader === "function") {
|
|
14034
|
+
let reader;
|
|
14035
|
+
try {
|
|
14036
|
+
reader = Reflect.apply(getReader, body, []);
|
|
14037
|
+
const decoder2 = new TextDecoder();
|
|
14038
|
+
let pending = "";
|
|
14039
|
+
while (true) {
|
|
14040
|
+
const readChunk = read(reader, "read");
|
|
14041
|
+
if (typeof readChunk !== "function") {
|
|
14042
|
+
throw new Error("Response body stream has no read method");
|
|
14043
|
+
}
|
|
14044
|
+
const chunk = await Reflect.apply(readChunk, reader, []);
|
|
14045
|
+
if (!isObject(chunk)) {
|
|
14046
|
+
throw new Error("Response body stream returned an invalid chunk");
|
|
14047
|
+
}
|
|
14048
|
+
if (chunk.done === true) {
|
|
14049
|
+
pending += decoder2.decode();
|
|
14050
|
+
break;
|
|
14051
|
+
}
|
|
14052
|
+
if (!(chunk.value instanceof Uint8Array)) {
|
|
14053
|
+
throw new Error("Response body stream returned a non-byte chunk");
|
|
14054
|
+
}
|
|
14055
|
+
pending += decoder2.decode(chunk.value, { stream: true });
|
|
14056
|
+
let newline = pending.indexOf("\n");
|
|
14057
|
+
while (newline !== -1) {
|
|
14058
|
+
const line = pending.slice(0, newline).replace(/\r$/, "");
|
|
14059
|
+
pending = pending.slice(newline + 1);
|
|
14060
|
+
if (line.trim()) {
|
|
14061
|
+
try {
|
|
14062
|
+
yield JSON.parse(line);
|
|
14063
|
+
} catch (error) {
|
|
14064
|
+
logBatchInstrumentationError("skipped malformed JSONL", error);
|
|
14065
|
+
onIssue(new Error("OpenAI Batch file contains malformed JSONL"));
|
|
14066
|
+
}
|
|
14067
|
+
}
|
|
14068
|
+
newline = pending.indexOf("\n");
|
|
14069
|
+
}
|
|
14070
|
+
}
|
|
14071
|
+
if (pending.trim()) {
|
|
14072
|
+
try {
|
|
14073
|
+
yield JSON.parse(pending.replace(/\r$/, ""));
|
|
14074
|
+
} catch (error) {
|
|
14075
|
+
logBatchInstrumentationError("skipped malformed JSONL", error);
|
|
14076
|
+
onIssue(new Error("OpenAI Batch file contains malformed JSONL"));
|
|
14077
|
+
}
|
|
14078
|
+
}
|
|
14079
|
+
} catch (error) {
|
|
14080
|
+
logBatchInstrumentationError("could not read JSONL response body", error);
|
|
14081
|
+
onIssue(new Error("OpenAI Batch response body could not be read"));
|
|
14082
|
+
} finally {
|
|
14083
|
+
const releaseLock = read(reader, "releaseLock");
|
|
14084
|
+
if (typeof releaseLock === "function") {
|
|
14085
|
+
try {
|
|
14086
|
+
Reflect.apply(releaseLock, reader, []);
|
|
14087
|
+
} catch (error) {
|
|
14088
|
+
logBatchInstrumentationError(
|
|
14089
|
+
"could not release stream reader",
|
|
14090
|
+
error
|
|
14091
|
+
);
|
|
14092
|
+
}
|
|
14093
|
+
}
|
|
14094
|
+
}
|
|
14095
|
+
return;
|
|
14096
|
+
}
|
|
14097
|
+
if (isBatchRecordIterable(resolvedFile)) {
|
|
14098
|
+
for await (const record of resolvedFile) {
|
|
14099
|
+
yield record;
|
|
14100
|
+
}
|
|
14101
|
+
return;
|
|
14102
|
+
}
|
|
14103
|
+
logBatchInstrumentationError("skipped invalid JSONL source", resolvedFile);
|
|
14104
|
+
onIssue(new Error("OpenAI Batch file source is invalid"));
|
|
14105
|
+
}
|
|
14106
|
+
async function readBatchInputs(file) {
|
|
14107
|
+
const inputs = /* @__PURE__ */ new Map();
|
|
14108
|
+
const issues = [];
|
|
14109
|
+
let endpoint;
|
|
14110
|
+
try {
|
|
14111
|
+
for await (const value of jsonlRecords(
|
|
14112
|
+
file,
|
|
14113
|
+
(issue) => issues.push(issue)
|
|
14114
|
+
)) {
|
|
14115
|
+
const customId = read(value, "custom_id");
|
|
14116
|
+
const url = read(value, "url");
|
|
14117
|
+
const body = read(value, "body");
|
|
14118
|
+
if (!validCustomId(customId) || inputs.has(customId) || read(value, "method") !== "POST" || typeof url !== "string" || !SUPPORTED_ENDPOINTS.has(url) || endpoint !== void 0 && endpoint !== url || !isObject(body)) {
|
|
14119
|
+
issues.push(new Error("OpenAI Batch input contains an invalid record"));
|
|
14120
|
+
continue;
|
|
14121
|
+
}
|
|
14122
|
+
endpoint = url;
|
|
14123
|
+
let spanData;
|
|
14124
|
+
try {
|
|
14125
|
+
spanData = extractOpenAIBatchInput(url, body);
|
|
14126
|
+
} catch (error) {
|
|
14127
|
+
logBatchInstrumentationError("could not extract batch input", error);
|
|
14128
|
+
}
|
|
14129
|
+
inputs.set(customId, { customId, spanData });
|
|
14130
|
+
}
|
|
14131
|
+
} catch (error) {
|
|
14132
|
+
logBatchInstrumentationError("could not process input file", error);
|
|
14133
|
+
issues.push(new Error("OpenAI Batch input file could not be processed"));
|
|
14134
|
+
}
|
|
14135
|
+
if (!endpoint || inputs.size === 0) {
|
|
14136
|
+
issues.push(new Error("OpenAI Batch input contains no supported records"));
|
|
14137
|
+
}
|
|
14138
|
+
return { endpoint, inputs, issues };
|
|
14139
|
+
}
|
|
14140
|
+
async function writePendingSpans(trace, endTime) {
|
|
14141
|
+
const task = await startBatchSpan(trace.context);
|
|
14142
|
+
const taskParent = await task.export();
|
|
14143
|
+
for (const input of trace.inputs.values()) {
|
|
14144
|
+
try {
|
|
14145
|
+
const child = await startBatchChild(trace.context, taskParent, input);
|
|
14146
|
+
if (endTime !== void 0) {
|
|
14147
|
+
child.end({ endTime });
|
|
14148
|
+
}
|
|
14149
|
+
} catch (error) {
|
|
14150
|
+
logBatchInstrumentationError("could not write batch request span", error);
|
|
14151
|
+
}
|
|
14152
|
+
}
|
|
14153
|
+
if (endTime !== void 0) {
|
|
14154
|
+
if (trace.status && trace.status !== "completed") {
|
|
14155
|
+
task.log({ error: new Error(`OpenAI Batch ${trace.status}`) });
|
|
14156
|
+
}
|
|
14157
|
+
task.end({ endTime });
|
|
14158
|
+
}
|
|
14159
|
+
}
|
|
14160
|
+
var interceptOpenAIFilesCreateTraced = async (target, thisArg, args) => {
|
|
14161
|
+
const startTime = getCurrentUnixTimestamp();
|
|
14162
|
+
const inputPromise = readBatchInputs(args[0].inputFileContent);
|
|
14163
|
+
const parentPromise = exportParent(args[0].parent);
|
|
14164
|
+
const file = await Reflect.apply(target, thisArg, args);
|
|
14165
|
+
try {
|
|
14166
|
+
const inputFileId = read(file, "id");
|
|
14167
|
+
const [inputData, exportedParent2] = await Promise.all([
|
|
14168
|
+
inputPromise,
|
|
14169
|
+
parentPromise
|
|
14170
|
+
]);
|
|
14171
|
+
if (typeof inputFileId !== "string" || !exportedParent2 || !inputData.endpoint || inputData.issues.length > 0) {
|
|
14172
|
+
if (inputData.issues[0]) {
|
|
14173
|
+
logBatchInstrumentationError(
|
|
14174
|
+
"skipped invalid input file",
|
|
14175
|
+
inputData.issues[0]
|
|
14176
|
+
);
|
|
14177
|
+
}
|
|
14178
|
+
return file;
|
|
14179
|
+
}
|
|
14180
|
+
const trace = {
|
|
14181
|
+
context: {
|
|
14182
|
+
inputFileId,
|
|
14183
|
+
endpoint: inputData.endpoint,
|
|
14184
|
+
parent: exportedParent2,
|
|
14185
|
+
taskStartTime: startTime,
|
|
14186
|
+
childStartTime: startTime
|
|
14187
|
+
},
|
|
14188
|
+
inputs: inputData.inputs
|
|
14189
|
+
};
|
|
14190
|
+
pendingBatchTraces.set(inputFileId, trace);
|
|
14191
|
+
await writePendingSpans(trace);
|
|
14192
|
+
} catch (error) {
|
|
14193
|
+
logBatchInstrumentationError("could not start batch spans", error);
|
|
14194
|
+
}
|
|
14195
|
+
return file;
|
|
14196
|
+
};
|
|
14197
|
+
function validTimestamp(value) {
|
|
14198
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0;
|
|
14199
|
+
}
|
|
14200
|
+
function terminalEndTime(batch, startTime) {
|
|
14201
|
+
let timestamp;
|
|
14202
|
+
switch (batch.status) {
|
|
14203
|
+
case "completed":
|
|
14204
|
+
timestamp = batch.completed_at;
|
|
14205
|
+
break;
|
|
14206
|
+
case "failed":
|
|
14207
|
+
timestamp = batch.failed_at;
|
|
14208
|
+
break;
|
|
14209
|
+
case "expired":
|
|
14210
|
+
timestamp = batch.expired_at;
|
|
14211
|
+
break;
|
|
14212
|
+
default:
|
|
14213
|
+
timestamp = batch.cancelled_at;
|
|
14214
|
+
}
|
|
14215
|
+
return validTimestamp(timestamp) ? Math.max(timestamp, startTime) : Math.max(getCurrentUnixTimestamp(), startTime);
|
|
14216
|
+
}
|
|
14217
|
+
async function updateBatchTimestamps(batch) {
|
|
14218
|
+
const trace = pendingBatchTraces.get(batch.input_file_id);
|
|
14219
|
+
if (!trace || trace.context.endpoint !== batch.endpoint) {
|
|
14220
|
+
return;
|
|
14221
|
+
}
|
|
14222
|
+
if (validTimestamp(batch.created_at)) {
|
|
14223
|
+
trace.context.taskStartTime = batch.created_at;
|
|
14224
|
+
}
|
|
14225
|
+
trace.context.childStartTime = validTimestamp(batch.in_progress_at) ? Math.max(batch.in_progress_at, trace.context.taskStartTime) : trace.context.taskStartTime;
|
|
14226
|
+
trace.status = batch.status;
|
|
14227
|
+
if (TERMINAL_STATUSES.has(batch.status)) {
|
|
14228
|
+
trace.endTime = terminalEndTime(batch, trace.context.childStartTime);
|
|
14229
|
+
}
|
|
14230
|
+
await writePendingSpans(trace, trace.endTime);
|
|
14231
|
+
}
|
|
14232
|
+
var interceptOpenAIBatchesRetrieveTraced = (target, thisArg, args) => Promise.resolve(Reflect.apply(target, thisArg, args)).then(async (batch) => {
|
|
14233
|
+
try {
|
|
14234
|
+
await updateBatchTimestamps(batch);
|
|
14235
|
+
} catch (error) {
|
|
14236
|
+
logBatchInstrumentationError("could not update batch timestamps", error);
|
|
14237
|
+
}
|
|
14238
|
+
return batch;
|
|
14239
|
+
});
|
|
14240
|
+
function errorFromResult(result) {
|
|
14241
|
+
const error = read(result.value, "error");
|
|
14242
|
+
if (isObject(error)) {
|
|
14243
|
+
const message = read(error, "message");
|
|
14244
|
+
return new Error(
|
|
14245
|
+
typeof message === "string" ? message : "OpenAI Batch request failed"
|
|
14246
|
+
);
|
|
14247
|
+
}
|
|
14248
|
+
const response = read(result.value, "response");
|
|
14249
|
+
const statusCode = read(response, "status_code");
|
|
14250
|
+
if (result.source === "error" || typeof statusCode === "number" && (statusCode < 200 || statusCode >= 300)) {
|
|
14251
|
+
const message = read(read(read(response, "body"), "error"), "message");
|
|
14252
|
+
return new Error(
|
|
14253
|
+
typeof message === "string" ? message : "OpenAI Batch request failed"
|
|
14254
|
+
);
|
|
14255
|
+
}
|
|
14256
|
+
return void 0;
|
|
14257
|
+
}
|
|
14258
|
+
async function completeBatchResult(context, taskParent, endTime, input, result) {
|
|
14259
|
+
const child = await startBatchChild(context, taskParent, input);
|
|
14260
|
+
try {
|
|
14261
|
+
const resultError = errorFromResult(result);
|
|
14262
|
+
const responseBody = read(read(result.value, "response"), "body");
|
|
14263
|
+
if (resultError) {
|
|
14264
|
+
child.log({ error: resultError });
|
|
14265
|
+
} else if (isObject(responseBody)) {
|
|
14266
|
+
const model = read(responseBody, "model");
|
|
14267
|
+
child.log({
|
|
14268
|
+
output: context.endpoint === "/v1/chat/completions" ? read(responseBody, "choices") : processImagesInOutput(read(responseBody, "output")),
|
|
14269
|
+
...typeof model === "string" ? { metadata: { model } } : {},
|
|
14270
|
+
metrics: parseMetricsFromUsage(read(responseBody, "usage"))
|
|
14271
|
+
});
|
|
14272
|
+
} else {
|
|
14273
|
+
child.log({ error: new Error("OpenAI Batch response body is missing") });
|
|
14274
|
+
}
|
|
14275
|
+
} catch (error) {
|
|
14276
|
+
child.log({ error });
|
|
14277
|
+
} finally {
|
|
14278
|
+
child.end({ endTime });
|
|
14279
|
+
}
|
|
14280
|
+
}
|
|
14281
|
+
async function completeResultFile({
|
|
14282
|
+
context,
|
|
14283
|
+
endTime,
|
|
14284
|
+
file,
|
|
14285
|
+
inputs,
|
|
14286
|
+
issues,
|
|
14287
|
+
seen,
|
|
14288
|
+
source,
|
|
14289
|
+
taskParent
|
|
14290
|
+
}) {
|
|
14291
|
+
if (file === void 0) {
|
|
14292
|
+
return;
|
|
14293
|
+
}
|
|
14294
|
+
for await (const value of jsonlRecords(file, (issue) => issues.push(issue))) {
|
|
14295
|
+
const customId = read(value, "custom_id");
|
|
14296
|
+
if (!validCustomId(customId) || !isObject(value)) {
|
|
14297
|
+
issues.push(
|
|
14298
|
+
new Error("OpenAI Batch result is missing a valid custom_id")
|
|
14299
|
+
);
|
|
14300
|
+
continue;
|
|
14301
|
+
}
|
|
14302
|
+
if (seen.has(customId)) {
|
|
14303
|
+
issues.push(new Error("OpenAI Batch result contains a duplicate"));
|
|
14304
|
+
continue;
|
|
14305
|
+
}
|
|
14306
|
+
const input = inputs.get(customId);
|
|
14307
|
+
if (!input) {
|
|
14308
|
+
issues.push(
|
|
14309
|
+
new Error("OpenAI Batch result does not match an input record")
|
|
14310
|
+
);
|
|
14311
|
+
continue;
|
|
14312
|
+
}
|
|
14313
|
+
seen.add(customId);
|
|
14314
|
+
await completeBatchResult(context, taskParent, endTime, input, {
|
|
14315
|
+
value,
|
|
14316
|
+
source
|
|
14317
|
+
});
|
|
14318
|
+
}
|
|
14319
|
+
}
|
|
14320
|
+
function sameInputs(first, second) {
|
|
14321
|
+
return first.size === second.size && [...first.keys()].every((customId) => second.has(customId));
|
|
14322
|
+
}
|
|
14323
|
+
async function contextForCompletion(inputFileId, inputData) {
|
|
14324
|
+
if (!inputData.endpoint || inputData.issues.length > 0) {
|
|
14325
|
+
return void 0;
|
|
14326
|
+
}
|
|
14327
|
+
const existing = pendingBatchTraces.get(inputFileId);
|
|
14328
|
+
if (existing) {
|
|
14329
|
+
if (existing.context.endpoint !== inputData.endpoint || !sameInputs(existing.inputs, inputData.inputs)) {
|
|
14330
|
+
return void 0;
|
|
14331
|
+
}
|
|
14332
|
+
return { ...existing, inputs: inputData.inputs };
|
|
14333
|
+
}
|
|
14334
|
+
const parent = await exportParent(getSpanParentObject());
|
|
14335
|
+
if (!parent) {
|
|
14336
|
+
return void 0;
|
|
14337
|
+
}
|
|
14338
|
+
const startTime = getCurrentUnixTimestamp();
|
|
14339
|
+
return {
|
|
14340
|
+
context: {
|
|
14341
|
+
inputFileId,
|
|
14342
|
+
endpoint: inputData.endpoint,
|
|
14343
|
+
parent,
|
|
14344
|
+
taskStartTime: startTime,
|
|
14345
|
+
childStartTime: startTime
|
|
14346
|
+
},
|
|
14347
|
+
inputs: inputData.inputs
|
|
14348
|
+
};
|
|
14349
|
+
}
|
|
14350
|
+
async function completeBatch(args) {
|
|
14351
|
+
const inputData = await readBatchInputs(args.inputFileContent);
|
|
14352
|
+
const trace = await contextForCompletion(args.inputFileId, inputData);
|
|
14353
|
+
if (!trace) {
|
|
14354
|
+
logBatchInstrumentationError(
|
|
14355
|
+
"left batch spans pending",
|
|
14356
|
+
inputData.issues[0] ?? new Error("OpenAI Batch input does not match")
|
|
14357
|
+
);
|
|
14358
|
+
return;
|
|
14359
|
+
}
|
|
14360
|
+
const endTime = trace.endTime ?? getCurrentUnixTimestamp();
|
|
14361
|
+
const task = await startBatchSpan(trace.context);
|
|
14362
|
+
const taskParent = await task.export();
|
|
14363
|
+
const issues = [];
|
|
14364
|
+
const seen = /* @__PURE__ */ new Set();
|
|
14365
|
+
await Promise.all([
|
|
14366
|
+
completeResultFile({
|
|
14367
|
+
context: trace.context,
|
|
14368
|
+
endTime,
|
|
14369
|
+
file: args.outputFileContent,
|
|
14370
|
+
inputs: trace.inputs,
|
|
14371
|
+
issues,
|
|
14372
|
+
seen,
|
|
14373
|
+
source: "output",
|
|
14374
|
+
taskParent
|
|
14375
|
+
}),
|
|
14376
|
+
completeResultFile({
|
|
14377
|
+
context: trace.context,
|
|
14378
|
+
endTime,
|
|
14379
|
+
file: args.errorFileContent,
|
|
14380
|
+
inputs: trace.inputs,
|
|
14381
|
+
issues,
|
|
14382
|
+
seen,
|
|
14383
|
+
source: "error",
|
|
14384
|
+
taskParent
|
|
14385
|
+
})
|
|
14386
|
+
]);
|
|
14387
|
+
if (issues.length > 0) {
|
|
14388
|
+
logBatchInstrumentationError("left batch spans pending", issues[0]);
|
|
14389
|
+
return;
|
|
14390
|
+
}
|
|
14391
|
+
const missing = [...trace.inputs.values()].filter(
|
|
14392
|
+
({ customId }) => !seen.has(customId)
|
|
14393
|
+
);
|
|
14394
|
+
if (!trace.status || trace.status === "completed") {
|
|
14395
|
+
if (missing.length > 0) {
|
|
14396
|
+
logBatchInstrumentationError(
|
|
14397
|
+
"left batch spans pending",
|
|
14398
|
+
new Error("OpenAI Batch result files are incomplete")
|
|
14399
|
+
);
|
|
14400
|
+
return;
|
|
14401
|
+
}
|
|
14402
|
+
} else {
|
|
14403
|
+
for (const input of missing) {
|
|
14404
|
+
const child = await startBatchChild(trace.context, taskParent, input);
|
|
14405
|
+
child.log({ error: new Error(`OpenAI Batch ${trace.status}`) });
|
|
14406
|
+
child.end({ endTime });
|
|
14407
|
+
}
|
|
14408
|
+
task.log({ error: new Error(`OpenAI Batch ${trace.status}`) });
|
|
14409
|
+
}
|
|
14410
|
+
task.end({ endTime });
|
|
14411
|
+
pendingBatchTraces.delete(args.inputFileId);
|
|
14412
|
+
}
|
|
14413
|
+
var interceptOpenAIBatchTraceComplete = (target, thisArg, args) => Promise.resolve(Reflect.apply(target, thisArg, args)).then(async (result) => {
|
|
14414
|
+
try {
|
|
14415
|
+
await completeBatch(args[0]);
|
|
14416
|
+
} catch (error) {
|
|
14417
|
+
logBatchInstrumentationError("could not complete batch", error);
|
|
14418
|
+
}
|
|
14419
|
+
return result;
|
|
14420
|
+
});
|
|
14421
|
+
|
|
13449
14422
|
// src/instrumentation/plugins/openai-plugin.ts
|
|
13450
14423
|
var OpenAIPlugin = class extends BasePlugin {
|
|
13451
14424
|
constructor() {
|
|
13452
14425
|
super();
|
|
13453
14426
|
}
|
|
13454
14427
|
onEnable() {
|
|
14428
|
+
this.unsubscribers.push(
|
|
14429
|
+
openAIChannels.filesCreateTraced.intercept(
|
|
14430
|
+
interceptOpenAIFilesCreateTraced
|
|
14431
|
+
),
|
|
14432
|
+
openAIChannels.batchesRetrieveTraced.intercept(
|
|
14433
|
+
interceptOpenAIBatchesRetrieveTraced
|
|
14434
|
+
),
|
|
14435
|
+
openAIChannels.batchesCompleteTrace.intercept(
|
|
14436
|
+
interceptOpenAIBatchTraceComplete
|
|
14437
|
+
)
|
|
14438
|
+
);
|
|
13455
14439
|
this.unsubscribers.push(
|
|
13456
14440
|
traceStreamingChannel(openAIChannels.chatCompletionsCreate, {
|
|
13457
14441
|
name: "Chat Completion",
|
|
13458
14442
|
type: "llm" /* LLM */,
|
|
13459
|
-
extractInput: ([params]) =>
|
|
13460
|
-
const { messages, ...metadata } = params;
|
|
13461
|
-
return {
|
|
13462
|
-
input: processInputAttachments(messages),
|
|
13463
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13464
|
-
};
|
|
13465
|
-
},
|
|
14443
|
+
extractInput: ([params]) => extractOpenAIChatInput(params),
|
|
13466
14444
|
extractOutput: (result) => {
|
|
13467
14445
|
return result?.choices;
|
|
13468
14446
|
},
|
|
@@ -13508,13 +14486,7 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13508
14486
|
traceStreamingChannel(openAIChannels.betaChatCompletionsParse, {
|
|
13509
14487
|
name: "Chat Completion",
|
|
13510
14488
|
type: "llm" /* LLM */,
|
|
13511
|
-
extractInput: ([params]) =>
|
|
13512
|
-
const { messages, ...metadata } = params;
|
|
13513
|
-
return {
|
|
13514
|
-
input: processInputAttachments(messages),
|
|
13515
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13516
|
-
};
|
|
13517
|
-
},
|
|
14489
|
+
extractInput: ([params]) => extractOpenAIChatInput(params),
|
|
13518
14490
|
extractOutput: (result) => {
|
|
13519
14491
|
return result?.choices;
|
|
13520
14492
|
},
|
|
@@ -13536,13 +14508,7 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13536
14508
|
traceSyncStreamChannel(openAIChannels.betaChatCompletionsStream, {
|
|
13537
14509
|
name: "Chat Completion",
|
|
13538
14510
|
type: "llm" /* LLM */,
|
|
13539
|
-
extractInput: ([params]) =>
|
|
13540
|
-
const { messages, ...metadata } = params;
|
|
13541
|
-
return {
|
|
13542
|
-
input: processInputAttachments(messages),
|
|
13543
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13544
|
-
};
|
|
13545
|
-
}
|
|
14511
|
+
extractInput: ([params]) => extractOpenAIChatInput(params)
|
|
13546
14512
|
})
|
|
13547
14513
|
);
|
|
13548
14514
|
this.unsubscribers.push(
|
|
@@ -13572,23 +14538,11 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13572
14538
|
traceStreamingChannel(openAIChannels.responsesCreate, {
|
|
13573
14539
|
name: "openai.responses.create",
|
|
13574
14540
|
type: "llm" /* LLM */,
|
|
13575
|
-
extractInput: ([params]) =>
|
|
13576
|
-
const { input, ...metadata } = params;
|
|
13577
|
-
return {
|
|
13578
|
-
input: processInputAttachments(input),
|
|
13579
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13580
|
-
};
|
|
13581
|
-
},
|
|
14541
|
+
extractInput: ([params]) => extractOpenAIResponsesInput(params),
|
|
13582
14542
|
extractOutput: (result) => {
|
|
13583
14543
|
return processImagesInOutput(result?.output);
|
|
13584
14544
|
},
|
|
13585
|
-
extractMetadata: (result) =>
|
|
13586
|
-
if (!result) {
|
|
13587
|
-
return void 0;
|
|
13588
|
-
}
|
|
13589
|
-
const { output: _output, usage: _usage, ...metadata } = result;
|
|
13590
|
-
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
13591
|
-
},
|
|
14545
|
+
extractMetadata: (result) => extractOpenAIResponsesMetadata(result),
|
|
13592
14546
|
extractMetrics: (result, startTime, endEvent) => {
|
|
13593
14547
|
const metrics = withCachedMetric(
|
|
13594
14548
|
parseMetricsFromUsage(result?.usage),
|
|
@@ -13607,13 +14561,7 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13607
14561
|
traceSyncStreamChannel(openAIChannels.responsesStream, {
|
|
13608
14562
|
name: "openai.responses.create",
|
|
13609
14563
|
type: "llm" /* LLM */,
|
|
13610
|
-
extractInput: ([params]) =>
|
|
13611
|
-
const { input, ...metadata } = params;
|
|
13612
|
-
return {
|
|
13613
|
-
input: processInputAttachments(input),
|
|
13614
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13615
|
-
};
|
|
13616
|
-
},
|
|
14564
|
+
extractInput: ([params]) => extractOpenAIResponsesInput(params),
|
|
13617
14565
|
extractFromEvent: (event) => {
|
|
13618
14566
|
if (event.type !== "response.completed" || !event.response) {
|
|
13619
14567
|
return {};
|
|
@@ -13636,23 +14584,11 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13636
14584
|
traceStreamingChannel(openAIChannels.responsesParse, {
|
|
13637
14585
|
name: "openai.responses.parse",
|
|
13638
14586
|
type: "llm" /* LLM */,
|
|
13639
|
-
extractInput: ([params]) =>
|
|
13640
|
-
const { input, ...metadata } = params;
|
|
13641
|
-
return {
|
|
13642
|
-
input: processInputAttachments(input),
|
|
13643
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13644
|
-
};
|
|
13645
|
-
},
|
|
14587
|
+
extractInput: ([params]) => extractOpenAIResponsesInput(params),
|
|
13646
14588
|
extractOutput: (result) => {
|
|
13647
14589
|
return processImagesInOutput(result?.output);
|
|
13648
14590
|
},
|
|
13649
|
-
extractMetadata: (result) =>
|
|
13650
|
-
if (!result) {
|
|
13651
|
-
return void 0;
|
|
13652
|
-
}
|
|
13653
|
-
const { output: _output, usage: _usage, ...metadata } = result;
|
|
13654
|
-
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
13655
|
-
},
|
|
14591
|
+
extractMetadata: (result) => extractOpenAIResponsesMetadata(result),
|
|
13656
14592
|
extractMetrics: (result, startTime, endEvent) => {
|
|
13657
14593
|
const metrics = withCachedMetric(
|
|
13658
14594
|
parseMetricsFromUsage(result?.usage),
|
|
@@ -13671,23 +14607,11 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13671
14607
|
traceAsyncChannel(openAIChannels.responsesCompact, {
|
|
13672
14608
|
name: "openai.responses.compact",
|
|
13673
14609
|
type: "llm" /* LLM */,
|
|
13674
|
-
extractInput: ([params]) =>
|
|
13675
|
-
const { input, ...metadata } = params;
|
|
13676
|
-
return {
|
|
13677
|
-
input: processInputAttachments(input),
|
|
13678
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13679
|
-
};
|
|
13680
|
-
},
|
|
14610
|
+
extractInput: ([params]) => extractOpenAIResponsesInput(params),
|
|
13681
14611
|
extractOutput: (result) => {
|
|
13682
14612
|
return processImagesInOutput(result?.output);
|
|
13683
14613
|
},
|
|
13684
|
-
extractMetadata: (result) =>
|
|
13685
|
-
if (!result) {
|
|
13686
|
-
return void 0;
|
|
13687
|
-
}
|
|
13688
|
-
const { output: _output, usage: _usage, ...metadata } = result;
|
|
13689
|
-
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
13690
|
-
},
|
|
14614
|
+
extractMetadata: (result) => extractOpenAIResponsesMetadata(result),
|
|
13691
14615
|
extractMetrics: (result, startTime, endEvent) => {
|
|
13692
14616
|
const metrics = withCachedMetric(
|
|
13693
14617
|
parseMetricsFromUsage(result?.usage),
|
|
@@ -13743,35 +14667,6 @@ function withCachedMetric(metrics, result, endEvent) {
|
|
|
13743
14667
|
cached
|
|
13744
14668
|
};
|
|
13745
14669
|
}
|
|
13746
|
-
function processImagesInOutput(output) {
|
|
13747
|
-
if (Array.isArray(output)) {
|
|
13748
|
-
return output.map(processImagesInOutput);
|
|
13749
|
-
}
|
|
13750
|
-
if (isObject(output)) {
|
|
13751
|
-
if (output.type === "image_generation_call" && output.result && typeof output.result === "string") {
|
|
13752
|
-
const fileExtension = output.output_format || "png";
|
|
13753
|
-
const contentType = `image/${fileExtension}`;
|
|
13754
|
-
const baseFilename = output.revised_prompt && typeof output.revised_prompt === "string" ? output.revised_prompt.slice(0, 50).replace(/[^a-zA-Z0-9]/g, "_") : "generated_image";
|
|
13755
|
-
const filename = `${baseFilename}.${fileExtension}`;
|
|
13756
|
-
const binaryString = atob(output.result);
|
|
13757
|
-
const bytes = new Uint8Array(binaryString.length);
|
|
13758
|
-
for (let i = 0; i < binaryString.length; i++) {
|
|
13759
|
-
bytes[i] = binaryString.charCodeAt(i);
|
|
13760
|
-
}
|
|
13761
|
-
const blob = new Blob([bytes], { type: contentType });
|
|
13762
|
-
const attachment = new Attachment({
|
|
13763
|
-
data: blob,
|
|
13764
|
-
filename,
|
|
13765
|
-
contentType
|
|
13766
|
-
});
|
|
13767
|
-
return {
|
|
13768
|
-
...output,
|
|
13769
|
-
result: attachment
|
|
13770
|
-
};
|
|
13771
|
-
}
|
|
13772
|
-
}
|
|
13773
|
-
return output;
|
|
13774
|
-
}
|
|
13775
14670
|
function mergeLogprobTokens(existing, incoming) {
|
|
13776
14671
|
if (incoming === void 0) {
|
|
13777
14672
|
return existing;
|
|
@@ -13802,13 +14697,33 @@ function aggregateChatLogprobs(existing, incoming) {
|
|
|
13802
14697
|
}
|
|
13803
14698
|
return aggregated;
|
|
13804
14699
|
}
|
|
14700
|
+
function createAggregatedChatChoice(index) {
|
|
14701
|
+
return {
|
|
14702
|
+
index,
|
|
14703
|
+
role: void 0,
|
|
14704
|
+
content: void 0,
|
|
14705
|
+
refusal: void 0,
|
|
14706
|
+
toolCallsByIndex: /* @__PURE__ */ new Map(),
|
|
14707
|
+
logprobs: void 0,
|
|
14708
|
+
finish_reason: void 0
|
|
14709
|
+
};
|
|
14710
|
+
}
|
|
14711
|
+
function toChatChoice(choice) {
|
|
14712
|
+
const toolCalls2 = Array.from(choice.toolCallsByIndex.entries()).sort(([left], [right]) => left - right).map(([, toolCall]) => toolCall);
|
|
14713
|
+
return {
|
|
14714
|
+
index: choice.index,
|
|
14715
|
+
message: {
|
|
14716
|
+
role: choice.role,
|
|
14717
|
+
content: choice.content,
|
|
14718
|
+
...choice.refusal !== void 0 ? { refusal: choice.refusal } : {},
|
|
14719
|
+
tool_calls: toolCalls2.length > 0 ? toolCalls2 : void 0
|
|
14720
|
+
},
|
|
14721
|
+
logprobs: choice.logprobs ?? null,
|
|
14722
|
+
finish_reason: choice.finish_reason
|
|
14723
|
+
};
|
|
14724
|
+
}
|
|
13805
14725
|
function aggregateChatCompletionChunks(chunks, streamResult, endEvent) {
|
|
13806
|
-
|
|
13807
|
-
let content = void 0;
|
|
13808
|
-
let refusal = void 0;
|
|
13809
|
-
let tool_calls = void 0;
|
|
13810
|
-
let logprobs = void 0;
|
|
13811
|
-
let finish_reason = void 0;
|
|
14726
|
+
const choicesByIndex = /* @__PURE__ */ new Map();
|
|
13812
14727
|
let metrics = {};
|
|
13813
14728
|
for (const chunk of chunks) {
|
|
13814
14729
|
if (chunk.usage) {
|
|
@@ -13817,62 +14732,75 @@ function aggregateChatCompletionChunks(chunks, streamResult, endEvent) {
|
|
|
13817
14732
|
...parseMetricsFromUsage(chunk.usage)
|
|
13818
14733
|
};
|
|
13819
14734
|
}
|
|
13820
|
-
const
|
|
13821
|
-
if (!
|
|
14735
|
+
const choices = chunk.choices;
|
|
14736
|
+
if (!choices?.length) {
|
|
13822
14737
|
continue;
|
|
13823
14738
|
}
|
|
13824
|
-
|
|
13825
|
-
|
|
13826
|
-
|
|
13827
|
-
|
|
13828
|
-
|
|
13829
|
-
|
|
13830
|
-
|
|
13831
|
-
|
|
13832
|
-
|
|
13833
|
-
|
|
13834
|
-
|
|
13835
|
-
|
|
13836
|
-
|
|
13837
|
-
|
|
13838
|
-
|
|
13839
|
-
|
|
13840
|
-
|
|
13841
|
-
|
|
13842
|
-
|
|
13843
|
-
|
|
13844
|
-
|
|
13845
|
-
|
|
13846
|
-
|
|
13847
|
-
|
|
13848
|
-
|
|
13849
|
-
|
|
13850
|
-
|
|
13851
|
-
|
|
13852
|
-
|
|
14739
|
+
for (const choice of choices) {
|
|
14740
|
+
const choiceIndex = choice.index;
|
|
14741
|
+
let aggregatedChoice = choicesByIndex.get(choiceIndex);
|
|
14742
|
+
if (!aggregatedChoice) {
|
|
14743
|
+
aggregatedChoice = createAggregatedChatChoice(choiceIndex);
|
|
14744
|
+
choicesByIndex.set(choiceIndex, aggregatedChoice);
|
|
14745
|
+
}
|
|
14746
|
+
if (choice.finish_reason) {
|
|
14747
|
+
aggregatedChoice.finish_reason = choice.finish_reason;
|
|
14748
|
+
}
|
|
14749
|
+
aggregatedChoice.logprobs = aggregateChatLogprobs(
|
|
14750
|
+
aggregatedChoice.logprobs,
|
|
14751
|
+
choice.logprobs
|
|
14752
|
+
);
|
|
14753
|
+
const delta = choice.delta;
|
|
14754
|
+
if (!delta) {
|
|
14755
|
+
continue;
|
|
14756
|
+
}
|
|
14757
|
+
if (delta.finish_reason) {
|
|
14758
|
+
aggregatedChoice.finish_reason = delta.finish_reason;
|
|
14759
|
+
}
|
|
14760
|
+
if (!aggregatedChoice.role && delta.role) {
|
|
14761
|
+
aggregatedChoice.role = delta.role;
|
|
14762
|
+
}
|
|
14763
|
+
if (delta.content) {
|
|
14764
|
+
aggregatedChoice.content = (aggregatedChoice.content || "") + delta.content;
|
|
14765
|
+
}
|
|
14766
|
+
if (delta.refusal) {
|
|
14767
|
+
aggregatedChoice.refusal = (aggregatedChoice.refusal || "") + delta.refusal;
|
|
14768
|
+
}
|
|
14769
|
+
if (delta.tool_calls) {
|
|
14770
|
+
for (const toolDelta of delta.tool_calls) {
|
|
14771
|
+
let aggregatedToolCall = aggregatedChoice.toolCallsByIndex.get(
|
|
14772
|
+
toolDelta.index
|
|
14773
|
+
);
|
|
14774
|
+
if (!aggregatedToolCall) {
|
|
14775
|
+
aggregatedToolCall = {
|
|
14776
|
+
function: { arguments: "" }
|
|
14777
|
+
};
|
|
14778
|
+
aggregatedChoice.toolCallsByIndex.set(
|
|
14779
|
+
toolDelta.index,
|
|
14780
|
+
aggregatedToolCall
|
|
14781
|
+
);
|
|
13853
14782
|
}
|
|
13854
|
-
|
|
13855
|
-
|
|
13856
|
-
|
|
14783
|
+
if (toolDelta.id !== void 0) {
|
|
14784
|
+
aggregatedToolCall.id = toolDelta.id;
|
|
14785
|
+
}
|
|
14786
|
+
if (toolDelta.type !== void 0) {
|
|
14787
|
+
aggregatedToolCall.type = toolDelta.type;
|
|
14788
|
+
}
|
|
14789
|
+
if (toolDelta.function?.name !== void 0) {
|
|
14790
|
+
aggregatedToolCall.function.name = toolDelta.function.name;
|
|
14791
|
+
}
|
|
14792
|
+
if (toolDelta.function?.arguments !== void 0) {
|
|
14793
|
+
aggregatedToolCall.function.arguments += toolDelta.function.arguments;
|
|
14794
|
+
}
|
|
14795
|
+
}
|
|
13857
14796
|
}
|
|
13858
14797
|
}
|
|
13859
14798
|
}
|
|
13860
14799
|
metrics = withCachedMetric(metrics, streamResult, endEvent);
|
|
14800
|
+
const output = Array.from(choicesByIndex.values()).sort((left, right) => left.index - right.index).map(toChatChoice);
|
|
13861
14801
|
return {
|
|
13862
14802
|
metrics,
|
|
13863
|
-
output: [
|
|
13864
|
-
{
|
|
13865
|
-
index: 0,
|
|
13866
|
-
message: {
|
|
13867
|
-
role,
|
|
13868
|
-
content,
|
|
13869
|
-
...refusal !== void 0 ? { refusal } : {},
|
|
13870
|
-
tool_calls
|
|
13871
|
-
},
|
|
13872
|
-
logprobs: logprobs ?? null,
|
|
13873
|
-
finish_reason
|
|
13874
|
-
}
|
|
13875
|
-
]
|
|
14803
|
+
output: output.length > 0 ? output : [toChatChoice(createAggregatedChatChoice(0))]
|
|
13876
14804
|
};
|
|
13877
14805
|
}
|
|
13878
14806
|
function aggregateResponseStreamEvents(chunks, _streamResult, endEvent) {
|
|
@@ -15208,6 +16136,12 @@ function parseMetricsFromUsage2(usage) {
|
|
|
15208
16136
|
}
|
|
15209
16137
|
}
|
|
15210
16138
|
}
|
|
16139
|
+
if (isObject(usage.output_tokens_details)) {
|
|
16140
|
+
const thinkingTokens = usage.output_tokens_details.thinking_tokens;
|
|
16141
|
+
if (typeof thinkingTokens === "number") {
|
|
16142
|
+
metrics.completion_reasoning_tokens = thinkingTokens;
|
|
16143
|
+
}
|
|
16144
|
+
}
|
|
15211
16145
|
if (isObject(usage.server_tool_use)) {
|
|
15212
16146
|
for (const [name, value] of Object.entries(usage.server_tool_use)) {
|
|
15213
16147
|
if (typeof value === "number") {
|
|
@@ -16164,7 +17098,6 @@ function endHarnessTurn(parent) {
|
|
|
16164
17098
|
function braintrustAISDKTelemetry() {
|
|
16165
17099
|
const operations = /* @__PURE__ */ new Map();
|
|
16166
17100
|
const operationKeysByCallId = /* @__PURE__ */ new Map();
|
|
16167
|
-
const workflowOperationKeyStore = isomorph_default.newAsyncLocalStorage();
|
|
16168
17101
|
const modelSpans = /* @__PURE__ */ new Map();
|
|
16169
17102
|
const objectSpans = /* @__PURE__ */ new Map();
|
|
16170
17103
|
const embedSpans = /* @__PURE__ */ new Map();
|
|
@@ -16207,9 +17140,6 @@ function braintrustAISDKTelemetry() {
|
|
|
16207
17140
|
return;
|
|
16208
17141
|
}
|
|
16209
17142
|
operations.delete(operationKey);
|
|
16210
|
-
if (workflowOperationKeyStore.getStore() === operationKey) {
|
|
16211
|
-
workflowOperationKeyStore.enterWith(void 0);
|
|
16212
|
-
}
|
|
16213
17143
|
const keys = operationKeysByCallId.get(state.callId);
|
|
16214
17144
|
if (!keys) {
|
|
16215
17145
|
return;
|
|
@@ -16257,14 +17187,7 @@ function braintrustAISDKTelemetry() {
|
|
|
16257
17187
|
return key;
|
|
16258
17188
|
}
|
|
16259
17189
|
}
|
|
16260
|
-
|
|
16261
|
-
if (workflowOperationKey && keys.includes(workflowOperationKey)) {
|
|
16262
|
-
return workflowOperationKey;
|
|
16263
|
-
}
|
|
16264
|
-
if (callId === "workflow-agent") {
|
|
16265
|
-
return void 0;
|
|
16266
|
-
}
|
|
16267
|
-
return mode === "finish" ? keys[0] : keys[keys.length - 1];
|
|
17190
|
+
return callId === "workflow-agent" || mode === "active" ? keys[keys.length - 1] : keys[0];
|
|
16268
17191
|
};
|
|
16269
17192
|
const operationKeyFromEvent = (event, mode = "active") => {
|
|
16270
17193
|
const explicit = explicitOperationKey(event);
|
|
@@ -16278,17 +17201,13 @@ function braintrustAISDKTelemetry() {
|
|
|
16278
17201
|
if (operationKey) {
|
|
16279
17202
|
return operationKey;
|
|
16280
17203
|
}
|
|
16281
|
-
const
|
|
16282
|
-
if (
|
|
16283
|
-
return
|
|
17204
|
+
const workflowAgentKeys2 = operationKeysByCallId.get("workflow-agent");
|
|
17205
|
+
if (workflowAgentKeys2?.length) {
|
|
17206
|
+
return workflowAgentKeys2[workflowAgentKeys2.length - 1];
|
|
16284
17207
|
}
|
|
16285
17208
|
return callId === "workflow-agent" ? void 0 : callId;
|
|
16286
17209
|
}
|
|
16287
17210
|
}
|
|
16288
|
-
const workflowOperationKey = workflowOperationKeyStore.getStore();
|
|
16289
|
-
if (workflowOperationKey && operations.has(workflowOperationKey)) {
|
|
16290
|
-
return workflowOperationKey;
|
|
16291
|
-
}
|
|
16292
17211
|
const wrapperSpan = currentWorkflowAgentWrapperSpan();
|
|
16293
17212
|
if (wrapperSpan?.spanId) {
|
|
16294
17213
|
for (const [operationKey, state] of operations) {
|
|
@@ -16298,8 +17217,8 @@ function braintrustAISDKTelemetry() {
|
|
|
16298
17217
|
}
|
|
16299
17218
|
}
|
|
16300
17219
|
const workflowAgentKeys = operationKeysByCallId.get("workflow-agent");
|
|
16301
|
-
if (workflowAgentKeys?.length
|
|
16302
|
-
return workflowAgentKeys[
|
|
17220
|
+
if (workflowAgentKeys?.length) {
|
|
17221
|
+
return workflowAgentKeys[workflowAgentKeys.length - 1];
|
|
16303
17222
|
}
|
|
16304
17223
|
if (operations.size === 1) {
|
|
16305
17224
|
return operations.keys().next().value;
|
|
@@ -16502,9 +17421,6 @@ function braintrustAISDKTelemetry() {
|
|
|
16502
17421
|
if (!ownsSpan) {
|
|
16503
17422
|
return;
|
|
16504
17423
|
}
|
|
16505
|
-
if (workflowAgent) {
|
|
16506
|
-
workflowOperationKeyStore.enterWith(operationKey);
|
|
16507
|
-
}
|
|
16508
17424
|
let metadata = metadataFromEvent(event);
|
|
16509
17425
|
const logPayload = { metadata };
|
|
16510
17426
|
const workflowAgentCallInput = workflowAgent ? operationInput(event, operationName) : void 0;
|
|
@@ -16976,6 +17892,10 @@ var aiSDKChannels = defineChannels(
|
|
|
16976
17892
|
channelName: "generateText",
|
|
16977
17893
|
kind: "async"
|
|
16978
17894
|
}),
|
|
17895
|
+
generateImage: channel({
|
|
17896
|
+
channelName: "generateImage",
|
|
17897
|
+
kind: "async"
|
|
17898
|
+
}),
|
|
16979
17899
|
streamText: channel({
|
|
16980
17900
|
channelName: "streamText",
|
|
16981
17901
|
kind: "async"
|
|
@@ -17163,7 +18083,7 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
17163
18083
|
}
|
|
17164
18084
|
subscribeToAISDK() {
|
|
17165
18085
|
const denyOutputPaths = this.config.denyOutputPaths || DEFAULT_DENY_OUTPUT_PATHS;
|
|
17166
|
-
this.unsubscribers.push(
|
|
18086
|
+
this.unsubscribers.push(interceptAISDKV7TelemetryDispatcher());
|
|
17167
18087
|
this.unsubscribers.push(subscribeToHarnessAgentCreateSession());
|
|
17168
18088
|
this.unsubscribers.push(
|
|
17169
18089
|
subscribeToHarnessContinuation(
|
|
@@ -17191,6 +18111,18 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
17191
18111
|
aggregateChunks: aggregateAISDKChunks
|
|
17192
18112
|
})
|
|
17193
18113
|
);
|
|
18114
|
+
this.unsubscribers.push(
|
|
18115
|
+
traceAsyncChannel(aiSDKChannels.generateImage, {
|
|
18116
|
+
name: "generateImage",
|
|
18117
|
+
type: "llm" /* LLM */,
|
|
18118
|
+
extractInput: ([params], event) => prepareAISDKGenerateImageInput(params, event.self),
|
|
18119
|
+
extractOutput: (result, endEvent) => processAISDKGenerateImageOutput(
|
|
18120
|
+
result,
|
|
18121
|
+
resolveDenyOutputPaths(endEvent, denyOutputPaths)
|
|
18122
|
+
),
|
|
18123
|
+
extractMetrics: (result) => extractTokenMetrics(result)
|
|
18124
|
+
})
|
|
18125
|
+
);
|
|
17194
18126
|
this.unsubscribers.push(
|
|
17195
18127
|
traceStreamingChannel(aiSDKChannels.streamText, {
|
|
17196
18128
|
name: "streamText",
|
|
@@ -17680,26 +18612,29 @@ function subscribeToHarnessContinuation(continuationChannel, defaultDenyOutputPa
|
|
|
17680
18612
|
channel2.unsubscribe(handlers);
|
|
17681
18613
|
};
|
|
17682
18614
|
}
|
|
17683
|
-
function
|
|
17684
|
-
const channel2 = aiSDKChannels.v7CreateTelemetryDispatcher.tracingChannel();
|
|
18615
|
+
function interceptAISDKV7TelemetryDispatcher() {
|
|
17685
18616
|
const telemetry = braintrustAISDKTelemetry();
|
|
17686
|
-
|
|
17687
|
-
|
|
17688
|
-
const
|
|
17689
|
-
|
|
17690
|
-
|
|
18617
|
+
return aiSDKChannels.v7CreateTelemetryDispatcher.intercept(
|
|
18618
|
+
(target, thisArg, args) => {
|
|
18619
|
+
const dispatcher = Reflect.apply(target, thisArg, args);
|
|
18620
|
+
const telemetryOptions = args[0]?.telemetry;
|
|
18621
|
+
if (telemetryOptions?.isEnabled !== false) {
|
|
18622
|
+
try {
|
|
18623
|
+
patchAISDKV7TelemetryDispatcher(
|
|
18624
|
+
dispatcher,
|
|
18625
|
+
telemetry,
|
|
18626
|
+
telemetryOptions
|
|
18627
|
+
);
|
|
18628
|
+
} catch (error) {
|
|
18629
|
+
debugLogger.error(
|
|
18630
|
+
"Error instrumenting AI SDK v7 telemetry dispatcher:",
|
|
18631
|
+
error
|
|
18632
|
+
);
|
|
18633
|
+
}
|
|
17691
18634
|
}
|
|
17692
|
-
|
|
17693
|
-
event.result,
|
|
17694
|
-
telemetry,
|
|
17695
|
-
telemetryOptions
|
|
17696
|
-
);
|
|
18635
|
+
return dispatcher;
|
|
17697
18636
|
}
|
|
17698
|
-
|
|
17699
|
-
channel2.subscribe(handlers);
|
|
17700
|
-
return () => {
|
|
17701
|
-
channel2.unsubscribe(handlers);
|
|
17702
|
-
};
|
|
18637
|
+
);
|
|
17703
18638
|
}
|
|
17704
18639
|
function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry, telemetryOptions) {
|
|
17705
18640
|
if (!isObject(dispatcher)) {
|
|
@@ -18024,16 +18959,10 @@ var convertImageToAttachment = (image, explicitMimeType) => {
|
|
|
18024
18959
|
}
|
|
18025
18960
|
}
|
|
18026
18961
|
if (explicitMimeType) {
|
|
18027
|
-
|
|
18028
|
-
|
|
18029
|
-
data: new Blob([image], { type: explicitMimeType }),
|
|
18030
|
-
filename: `image.${getExtensionFromMediaType(explicitMimeType)}`,
|
|
18031
|
-
contentType: explicitMimeType
|
|
18032
|
-
});
|
|
18033
|
-
}
|
|
18034
|
-
if (typeof Buffer !== "undefined" && Buffer.isBuffer(image)) {
|
|
18962
|
+
const blob = convertDataToBlob(image, explicitMimeType);
|
|
18963
|
+
if (blob) {
|
|
18035
18964
|
return new Attachment({
|
|
18036
|
-
data:
|
|
18965
|
+
data: blob,
|
|
18037
18966
|
filename: `image.${getExtensionFromMediaType(explicitMimeType)}`,
|
|
18038
18967
|
contentType: explicitMimeType
|
|
18039
18968
|
});
|
|
@@ -18087,6 +19016,25 @@ var convertDataToAttachment = (data, mimeType, filename) => {
|
|
|
18087
19016
|
function processAISDKCallInput(params) {
|
|
18088
19017
|
return processInputAttachmentsSync(params);
|
|
18089
19018
|
}
|
|
19019
|
+
function processAISDKGenerateImageInput(params) {
|
|
19020
|
+
const prompt = params.prompt;
|
|
19021
|
+
if (!isObject(prompt) || Array.isArray(prompt)) {
|
|
19022
|
+
return processAISDKCallInput(params);
|
|
19023
|
+
}
|
|
19024
|
+
const processedPrompt = { ...prompt };
|
|
19025
|
+
if (Array.isArray(prompt.images)) {
|
|
19026
|
+
processedPrompt.images = prompt.images.map(
|
|
19027
|
+
(image) => convertImageToAttachment(image, "image/png") ?? image
|
|
19028
|
+
);
|
|
19029
|
+
}
|
|
19030
|
+
if (prompt.mask !== void 0) {
|
|
19031
|
+
processedPrompt.mask = convertImageToAttachment(prompt.mask, "image/png") ?? prompt.mask;
|
|
19032
|
+
}
|
|
19033
|
+
return processAISDKCallInput({
|
|
19034
|
+
...params,
|
|
19035
|
+
prompt: processedPrompt
|
|
19036
|
+
});
|
|
19037
|
+
}
|
|
18090
19038
|
function processAISDKWorkflowAgentCallInput(params) {
|
|
18091
19039
|
const processed = processAISDKCallInput(params);
|
|
18092
19040
|
return {
|
|
@@ -18225,6 +19173,12 @@ function prepareAISDKEmbedInput(params, self) {
|
|
|
18225
19173
|
metadata: extractMetadataFromEmbedParams(params, self)
|
|
18226
19174
|
};
|
|
18227
19175
|
}
|
|
19176
|
+
function prepareAISDKGenerateImageInput(params, self) {
|
|
19177
|
+
return {
|
|
19178
|
+
input: processAISDKGenerateImageInput(params).input,
|
|
19179
|
+
metadata: extractMetadataFromCallParams(params, self)
|
|
19180
|
+
};
|
|
19181
|
+
}
|
|
18228
19182
|
function prepareAISDKRerankInput(params, self) {
|
|
18229
19183
|
const { documents, query } = params;
|
|
18230
19184
|
return {
|
|
@@ -19600,6 +20554,57 @@ function processAISDKOutput(output, denyOutputPaths) {
|
|
|
19600
20554
|
}
|
|
19601
20555
|
return normalizeAISDKLoggedOutput(sanitized);
|
|
19602
20556
|
}
|
|
20557
|
+
function processAISDKGenerateImageOutput(output, denyOutputPaths) {
|
|
20558
|
+
if (!output || typeof output !== "object") {
|
|
20559
|
+
return output;
|
|
20560
|
+
}
|
|
20561
|
+
const summarized = {};
|
|
20562
|
+
for (const field of [
|
|
20563
|
+
"usage",
|
|
20564
|
+
"warnings",
|
|
20565
|
+
"providerMetadata",
|
|
20566
|
+
"experimental_providerMetadata",
|
|
20567
|
+
"responses"
|
|
20568
|
+
]) {
|
|
20569
|
+
const value = safeSerializableFieldRead(output, field);
|
|
20570
|
+
if (value !== void 0 && isSerializableOutputValue(value)) {
|
|
20571
|
+
summarized[field] = value;
|
|
20572
|
+
}
|
|
20573
|
+
}
|
|
20574
|
+
const images = safeSerializableFieldRead(output, "images");
|
|
20575
|
+
const image = safeSerializableFieldRead(output, "image");
|
|
20576
|
+
const generatedFiles = Array.isArray(images) && images.length > 0 ? images : image !== void 0 ? [image] : [];
|
|
20577
|
+
const loggedOutput = normalizeAISDKLoggedOutput(
|
|
20578
|
+
omit(summarized, denyOutputPaths)
|
|
20579
|
+
);
|
|
20580
|
+
if (generatedFiles.length > 0) {
|
|
20581
|
+
loggedOutput.images = generatedFiles.map(
|
|
20582
|
+
(file, index) => convertAISDKGeneratedFileToAttachment(file, index)
|
|
20583
|
+
);
|
|
20584
|
+
}
|
|
20585
|
+
return loggedOutput;
|
|
20586
|
+
}
|
|
20587
|
+
function convertAISDKGeneratedFileToAttachment(file, index) {
|
|
20588
|
+
if (!file || typeof file !== "object") {
|
|
20589
|
+
return file;
|
|
20590
|
+
}
|
|
20591
|
+
const generatedFile = file;
|
|
20592
|
+
const generatedMediaType = safeSerializableFieldRead(
|
|
20593
|
+
generatedFile,
|
|
20594
|
+
"mediaType"
|
|
20595
|
+
);
|
|
20596
|
+
const mediaType = typeof generatedMediaType === "string" ? generatedMediaType : "application/octet-stream";
|
|
20597
|
+
const data = safeSerializableFieldRead(generatedFile, "base64") ?? safeSerializableFieldRead(generatedFile, "uint8Array");
|
|
20598
|
+
const blob = convertDataToBlob(data, mediaType);
|
|
20599
|
+
if (blob) {
|
|
20600
|
+
return new Attachment({
|
|
20601
|
+
data: blob,
|
|
20602
|
+
filename: `generated_image_${index}.${getExtensionFromMediaType(mediaType)}`,
|
|
20603
|
+
contentType: mediaType
|
|
20604
|
+
});
|
|
20605
|
+
}
|
|
20606
|
+
return file;
|
|
20607
|
+
}
|
|
19603
20608
|
function processAISDKEmbeddingOutput(output, denyOutputPaths) {
|
|
19604
20609
|
if (!output || typeof output !== "object") {
|
|
19605
20610
|
return output;
|
|
@@ -20100,118 +21105,22 @@ var claudeAgentSDKChannels = defineChannels(
|
|
|
20100
21105
|
var CLAUDE_AGENT_SDK_SKIP_LOCAL_TOOL_HOOKS_OPTION = "__braintrust_skip_local_tool_hooks";
|
|
20101
21106
|
|
|
20102
21107
|
// src/instrumentation/plugins/claude-agent-sdk-local-tool-context.ts
|
|
20103
|
-
var
|
|
20104
|
-
|
|
20105
|
-
)
|
|
20106
|
-
|
|
20107
|
-
const maybeIsoWithAsyncLocalStorage = isomorph_default;
|
|
20108
|
-
if (typeof maybeIsoWithAsyncLocalStorage.newAsyncLocalStorage === "function") {
|
|
20109
|
-
return maybeIsoWithAsyncLocalStorage.newAsyncLocalStorage();
|
|
20110
|
-
}
|
|
20111
|
-
let currentStore;
|
|
20112
|
-
return {
|
|
20113
|
-
enterWith(store) {
|
|
20114
|
-
currentStore = store;
|
|
20115
|
-
},
|
|
20116
|
-
getStore() {
|
|
20117
|
-
return currentStore;
|
|
20118
|
-
},
|
|
20119
|
-
run(store, callback) {
|
|
20120
|
-
const previousStore = currentStore;
|
|
20121
|
-
currentStore = store;
|
|
20122
|
-
try {
|
|
20123
|
-
return callback();
|
|
20124
|
-
} finally {
|
|
20125
|
-
currentStore = previousStore;
|
|
20126
|
-
}
|
|
20127
|
-
}
|
|
20128
|
-
};
|
|
20129
|
-
}
|
|
20130
|
-
var localToolContextStore = createLocalToolContextStore();
|
|
20131
|
-
var fallbackLocalToolParentResolver;
|
|
20132
|
-
function createClaudeLocalToolContext() {
|
|
20133
|
-
return {};
|
|
20134
|
-
}
|
|
20135
|
-
function runWithClaudeLocalToolContext(callback, context) {
|
|
20136
|
-
return localToolContextStore.run(
|
|
20137
|
-
context ?? createClaudeLocalToolContext(),
|
|
20138
|
-
callback
|
|
20139
|
-
);
|
|
21108
|
+
var localToolContextStore = isomorph_default.newAsyncLocalStorage();
|
|
21109
|
+
var localToolParentResolversByToolUseId = /* @__PURE__ */ new Map();
|
|
21110
|
+
function runWithClaudeLocalToolContext(callback, resolver) {
|
|
21111
|
+
return localToolContextStore.run(resolver, callback);
|
|
20140
21112
|
}
|
|
20141
|
-
function
|
|
20142
|
-
|
|
20143
|
-
if (existing) {
|
|
20144
|
-
return existing;
|
|
20145
|
-
}
|
|
20146
|
-
const created = {};
|
|
20147
|
-
localToolContextStore.enterWith(created);
|
|
20148
|
-
return created;
|
|
21113
|
+
function registerClaudeLocalToolParentResolver(toolUseId, resolver) {
|
|
21114
|
+
localToolParentResolversByToolUseId.set(toolUseId, resolver);
|
|
20149
21115
|
}
|
|
20150
|
-
function
|
|
20151
|
-
|
|
20152
|
-
|
|
20153
|
-
|
|
20154
|
-
return;
|
|
21116
|
+
function getClaudeLocalToolParentResolver(toolUseId) {
|
|
21117
|
+
const currentResolver = localToolContextStore.getStore();
|
|
21118
|
+
if (!toolUseId) {
|
|
21119
|
+
return currentResolver;
|
|
20155
21120
|
}
|
|
20156
|
-
|
|
20157
|
-
|
|
20158
|
-
|
|
20159
|
-
return localToolContextStore.getStore()?.resolveLocalToolParent ?? fallbackLocalToolParentResolver;
|
|
20160
|
-
}
|
|
20161
|
-
function isAsyncIterable3(value) {
|
|
20162
|
-
return value !== null && typeof value === "object" && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
20163
|
-
}
|
|
20164
|
-
function bindClaudeLocalToolContextToAsyncIterable(result, localToolContext) {
|
|
20165
|
-
if (!isAsyncIterable3(result) || Object.isFrozen(result) || Object.isSealed(result)) {
|
|
20166
|
-
return result;
|
|
20167
|
-
}
|
|
20168
|
-
const stream = result;
|
|
20169
|
-
const originalAsyncIterator = stream[Symbol.asyncIterator];
|
|
20170
|
-
if (originalAsyncIterator[LOCAL_TOOL_CONTEXT_ASYNC_ITERATOR_PATCHED]) {
|
|
20171
|
-
return result;
|
|
20172
|
-
}
|
|
20173
|
-
const patchedAsyncIterator = function() {
|
|
20174
|
-
return runWithClaudeLocalToolContext(() => {
|
|
20175
|
-
const iterator = Reflect.apply(originalAsyncIterator, this, []);
|
|
20176
|
-
if (!iterator || typeof iterator !== "object") {
|
|
20177
|
-
return iterator;
|
|
20178
|
-
}
|
|
20179
|
-
const patchMethod = (methodName) => {
|
|
20180
|
-
const originalMethod = Reflect.get(iterator, methodName);
|
|
20181
|
-
if (typeof originalMethod !== "function") {
|
|
20182
|
-
return;
|
|
20183
|
-
}
|
|
20184
|
-
Reflect.set(
|
|
20185
|
-
iterator,
|
|
20186
|
-
methodName,
|
|
20187
|
-
(...args) => runWithClaudeLocalToolContext(
|
|
20188
|
-
() => Reflect.apply(
|
|
20189
|
-
originalMethod,
|
|
20190
|
-
iterator,
|
|
20191
|
-
args
|
|
20192
|
-
),
|
|
20193
|
-
localToolContext
|
|
20194
|
-
)
|
|
20195
|
-
);
|
|
20196
|
-
};
|
|
20197
|
-
patchMethod("next");
|
|
20198
|
-
patchMethod("return");
|
|
20199
|
-
patchMethod("throw");
|
|
20200
|
-
return iterator;
|
|
20201
|
-
}, localToolContext);
|
|
20202
|
-
};
|
|
20203
|
-
Object.defineProperty(
|
|
20204
|
-
patchedAsyncIterator,
|
|
20205
|
-
LOCAL_TOOL_CONTEXT_ASYNC_ITERATOR_PATCHED,
|
|
20206
|
-
{
|
|
20207
|
-
configurable: false,
|
|
20208
|
-
enumerable: false,
|
|
20209
|
-
value: true,
|
|
20210
|
-
writable: false
|
|
20211
|
-
}
|
|
20212
|
-
);
|
|
20213
|
-
Reflect.set(stream, Symbol.asyncIterator, patchedAsyncIterator);
|
|
20214
|
-
return result;
|
|
21121
|
+
const registeredResolver = localToolParentResolversByToolUseId.get(toolUseId);
|
|
21122
|
+
localToolParentResolversByToolUseId.delete(toolUseId);
|
|
21123
|
+
return currentResolver ?? registeredResolver;
|
|
20215
21124
|
}
|
|
20216
21125
|
|
|
20217
21126
|
// src/instrumentation/plugins/claude-agent-sdk-local-tool-spans.ts
|
|
@@ -20237,7 +21146,7 @@ function wrapLocalClaudeToolHandler(handler, getMetadata) {
|
|
|
20237
21146
|
const metadata = getMetadata();
|
|
20238
21147
|
const rawToolName = metadata.serverName ? `mcp__${metadata.serverName}__${metadata.toolName}` : metadata.toolName;
|
|
20239
21148
|
const toolUseId = getToolUseIdFromExtra(handlerArgs[1]);
|
|
20240
|
-
const localToolParentResolver = getClaudeLocalToolParentResolver();
|
|
21149
|
+
const localToolParentResolver = getClaudeLocalToolParentResolver(toolUseId);
|
|
20241
21150
|
const spanName = metadata.serverName ? `tool: ${metadata.serverName}/${metadata.toolName}` : `tool: ${metadata.toolName}`;
|
|
20242
21151
|
const runWithResolvedParent = async () => {
|
|
20243
21152
|
const parent = toolUseId && localToolParentResolver ? await localToolParentResolver(toolUseId).catch(() => void 0) : void 0;
|
|
@@ -20764,6 +21673,7 @@ function createToolTracingHooks(resolveParentSpan, taskIdToToolUseId, toolUseToP
|
|
|
20764
21673
|
}
|
|
20765
21674
|
}
|
|
20766
21675
|
if (skipLocalToolHooks && (isLocalToolUse(input.tool_name, mcpServers) || localToolHookNames.has(input.tool_name))) {
|
|
21676
|
+
registerClaudeLocalToolParentResolver(toolUseID, resolveParentSpan);
|
|
20767
21677
|
return {};
|
|
20768
21678
|
}
|
|
20769
21679
|
const parsed = parseToolName(input.tool_name);
|
|
@@ -21474,7 +22384,7 @@ async function finalizeQuerySpan(state) {
|
|
|
21474
22384
|
}
|
|
21475
22385
|
var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
21476
22386
|
onEnable() {
|
|
21477
|
-
this.
|
|
22387
|
+
this.interceptQuery();
|
|
21478
22388
|
}
|
|
21479
22389
|
onDisable() {
|
|
21480
22390
|
for (const unsubscribe of this.unsubscribers) {
|
|
@@ -21482,211 +22392,218 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
21482
22392
|
}
|
|
21483
22393
|
this.unsubscribers = [];
|
|
21484
22394
|
}
|
|
21485
|
-
|
|
21486
|
-
const
|
|
21487
|
-
|
|
21488
|
-
|
|
21489
|
-
|
|
21490
|
-
|
|
21491
|
-
|
|
21492
|
-
|
|
21493
|
-
|
|
21494
|
-
|
|
21495
|
-
|
|
21496
|
-
|
|
21497
|
-
|
|
21498
|
-
|
|
21499
|
-
|
|
21500
|
-
|
|
21501
|
-
|
|
21502
|
-
|
|
21503
|
-
|
|
21504
|
-
|
|
21505
|
-
try {
|
|
21506
|
-
for await (const message of promptStream) {
|
|
21507
|
-
capturedPromptMessages.push(message);
|
|
21508
|
-
yield message;
|
|
21509
|
-
}
|
|
21510
|
-
} finally {
|
|
21511
|
-
resolvePromptDone?.();
|
|
22395
|
+
interceptQuery() {
|
|
22396
|
+
const startQuery = (params) => {
|
|
22397
|
+
const originalPrompt = params.prompt;
|
|
22398
|
+
const options = params.options ?? {};
|
|
22399
|
+
const promptIsAsyncIterable = isAsyncIterable(originalPrompt);
|
|
22400
|
+
let promptStarted = false;
|
|
22401
|
+
let capturedPromptMessages;
|
|
22402
|
+
let resolvePromptDone;
|
|
22403
|
+
const promptDone = new Promise((resolve) => {
|
|
22404
|
+
resolvePromptDone = resolve;
|
|
22405
|
+
});
|
|
22406
|
+
if (promptIsAsyncIterable) {
|
|
22407
|
+
capturedPromptMessages = [];
|
|
22408
|
+
const promptStream = originalPrompt;
|
|
22409
|
+
params.prompt = (async function* () {
|
|
22410
|
+
promptStarted = true;
|
|
22411
|
+
try {
|
|
22412
|
+
for await (const message of promptStream) {
|
|
22413
|
+
capturedPromptMessages.push(message);
|
|
22414
|
+
yield message;
|
|
21512
22415
|
}
|
|
21513
|
-
}
|
|
21514
|
-
|
|
21515
|
-
const span = startSpan(
|
|
21516
|
-
withSpanInstrumentationName(
|
|
21517
|
-
{
|
|
21518
|
-
name: "Claude Agent",
|
|
21519
|
-
spanAttributes: {
|
|
21520
|
-
type: "task" /* TASK */
|
|
21521
|
-
}
|
|
21522
|
-
},
|
|
21523
|
-
INSTRUMENTATION_NAMES.CLAUDE_AGENT_SDK
|
|
21524
|
-
)
|
|
21525
|
-
);
|
|
21526
|
-
const startTime = getCurrentUnixTimestamp();
|
|
21527
|
-
try {
|
|
21528
|
-
span.log({
|
|
21529
|
-
input: typeof originalPrompt === "string" ? originalPrompt : promptIsAsyncIterable ? void 0 : originalPrompt !== void 0 ? String(originalPrompt) : void 0,
|
|
21530
|
-
metadata: filterSerializableOptions(options)
|
|
21531
|
-
});
|
|
21532
|
-
} catch (error) {
|
|
21533
|
-
console.error("Error extracting input for Claude Agent SDK:", error);
|
|
21534
|
-
}
|
|
21535
|
-
const activeToolSpans = /* @__PURE__ */ new Map();
|
|
21536
|
-
const activeLlmSpansByParentToolUse = /* @__PURE__ */ new Map();
|
|
21537
|
-
const conversationHistoryByParentKey = /* @__PURE__ */ new Map();
|
|
21538
|
-
const subAgentSpans = /* @__PURE__ */ new Map();
|
|
21539
|
-
const endedSubAgentSpans = /* @__PURE__ */ new Set();
|
|
21540
|
-
const toolUseToParent = /* @__PURE__ */ new Map();
|
|
21541
|
-
const latestLlmParentBySubAgentToolUse = /* @__PURE__ */ new Map();
|
|
21542
|
-
const latestRootLlmParentRef = {
|
|
21543
|
-
value: void 0
|
|
21544
|
-
};
|
|
21545
|
-
const subAgentDetailsByToolUseId = /* @__PURE__ */ new Map();
|
|
21546
|
-
const taskIdToToolUseId = /* @__PURE__ */ new Map();
|
|
21547
|
-
const promptMessagesByParentKey = /* @__PURE__ */ new Map();
|
|
21548
|
-
const promptSourcePriorityByParentKey = /* @__PURE__ */ new Map();
|
|
21549
|
-
const localToolContext = createClaudeLocalToolContext();
|
|
21550
|
-
const { hasLocalToolHandlers, localToolHookNames } = prepareLocalToolHandlersInMcpServers(options.mcpServers);
|
|
21551
|
-
const skipLocalToolHooks = options[CLAUDE_AGENT_SDK_SKIP_LOCAL_TOOL_HOOKS_OPTION] === true || hasLocalToolHandlers;
|
|
21552
|
-
const resolveToolUseParentSpan = async (toolUseID, context) => {
|
|
21553
|
-
const trackedParentToolUseId = toolUseToParent.get(toolUseID);
|
|
21554
|
-
const parentToolUseId = trackedParentToolUseId ?? (context?.agentId ? taskIdToToolUseId.get(context.agentId) ?? null : null);
|
|
21555
|
-
const parentKey = llmParentKey(parentToolUseId);
|
|
21556
|
-
const activeLlmSpan = activeLlmSpansByParentToolUse.get(parentKey);
|
|
21557
|
-
const latestLlmParent = parentToolUseId ? latestLlmParentBySubAgentToolUse.get(parentToolUseId) : latestRootLlmParentRef.value;
|
|
21558
|
-
if (!activeLlmSpan && !latestLlmParent) {
|
|
21559
|
-
await ensureActiveLlmSpanForParentToolUse(
|
|
21560
|
-
span,
|
|
21561
|
-
activeLlmSpansByParentToolUse,
|
|
21562
|
-
subAgentDetailsByToolUseId,
|
|
21563
|
-
activeToolSpans,
|
|
21564
|
-
subAgentSpans,
|
|
21565
|
-
parentToolUseId,
|
|
21566
|
-
getCurrentUnixTimestamp()
|
|
21567
|
-
);
|
|
21568
|
-
}
|
|
21569
|
-
if (parentToolUseId) {
|
|
21570
|
-
const subAgentSpan = await ensureSubAgentSpan(
|
|
21571
|
-
subAgentDetailsByToolUseId,
|
|
21572
|
-
span,
|
|
21573
|
-
activeToolSpans,
|
|
21574
|
-
subAgentSpans,
|
|
21575
|
-
parentToolUseId
|
|
21576
|
-
);
|
|
21577
|
-
return subAgentSpan.export();
|
|
22416
|
+
} finally {
|
|
22417
|
+
resolvePromptDone?.();
|
|
21578
22418
|
}
|
|
21579
|
-
|
|
21580
|
-
|
|
21581
|
-
|
|
21582
|
-
|
|
21583
|
-
|
|
21584
|
-
|
|
21585
|
-
|
|
21586
|
-
|
|
21587
|
-
|
|
21588
|
-
|
|
21589
|
-
|
|
21590
|
-
|
|
21591
|
-
|
|
21592
|
-
|
|
21593
|
-
|
|
21594
|
-
|
|
21595
|
-
|
|
21596
|
-
|
|
21597
|
-
spans.set(event, {
|
|
21598
|
-
activeLlmSpansByParentToolUse,
|
|
21599
|
-
activePartialMessageIdByParentKey: /* @__PURE__ */ new Map(),
|
|
21600
|
-
activeToolSpans,
|
|
21601
|
-
conversationHistoryByParentKey,
|
|
21602
|
-
capturedPromptMessages,
|
|
21603
|
-
currentMessageId: void 0,
|
|
21604
|
-
currentMessageStartTime: startTime,
|
|
21605
|
-
currentMessages: [],
|
|
21606
|
-
endedSubAgentSpans,
|
|
21607
|
-
finalOutputUsageMessageIds: /* @__PURE__ */ new Set(),
|
|
21608
|
-
finalResults: [],
|
|
21609
|
-
options: optionsWithHooks,
|
|
21610
|
-
originalPrompt,
|
|
21611
|
-
processing: Promise.resolve(),
|
|
21612
|
-
promptDone,
|
|
21613
|
-
promptMessagesByParentKey,
|
|
21614
|
-
promptStarted: () => promptStarted,
|
|
21615
|
-
promptSourcePriorityByParentKey,
|
|
21616
|
-
span,
|
|
21617
|
-
subAgentDetailsByToolUseId,
|
|
21618
|
-
subAgentSpans,
|
|
21619
|
-
taskIdToToolUseId,
|
|
21620
|
-
latestLlmParentBySubAgentToolUse,
|
|
21621
|
-
latestRootLlmParentRef,
|
|
21622
|
-
toolUseToParent,
|
|
21623
|
-
usageByMessageId: /* @__PURE__ */ new Map(),
|
|
21624
|
-
localToolContext
|
|
22419
|
+
})();
|
|
22420
|
+
}
|
|
22421
|
+
const span = startSpan(
|
|
22422
|
+
withSpanInstrumentationName(
|
|
22423
|
+
{
|
|
22424
|
+
name: "Claude Agent",
|
|
22425
|
+
spanAttributes: {
|
|
22426
|
+
type: "task" /* TASK */
|
|
22427
|
+
}
|
|
22428
|
+
},
|
|
22429
|
+
INSTRUMENTATION_NAMES.CLAUDE_AGENT_SDK
|
|
22430
|
+
)
|
|
22431
|
+
);
|
|
22432
|
+
const startTime = getCurrentUnixTimestamp();
|
|
22433
|
+
try {
|
|
22434
|
+
span.log({
|
|
22435
|
+
input: typeof originalPrompt === "string" ? originalPrompt : promptIsAsyncIterable ? void 0 : originalPrompt !== void 0 ? String(originalPrompt) : void 0,
|
|
22436
|
+
metadata: filterSerializableOptions(options)
|
|
21625
22437
|
});
|
|
21626
|
-
}
|
|
21627
|
-
|
|
21628
|
-
|
|
21629
|
-
|
|
21630
|
-
|
|
21631
|
-
|
|
21632
|
-
|
|
21633
|
-
|
|
21634
|
-
|
|
21635
|
-
|
|
21636
|
-
|
|
21637
|
-
|
|
21638
|
-
|
|
21639
|
-
|
|
21640
|
-
|
|
21641
|
-
|
|
21642
|
-
|
|
21643
|
-
|
|
21644
|
-
|
|
21645
|
-
|
|
21646
|
-
|
|
21647
|
-
|
|
21648
|
-
|
|
21649
|
-
|
|
21650
|
-
|
|
21651
|
-
|
|
21652
|
-
|
|
21653
|
-
|
|
21654
|
-
|
|
21655
|
-
|
|
21656
|
-
|
|
21657
|
-
|
|
21658
|
-
|
|
21659
|
-
|
|
21660
|
-
|
|
21661
|
-
})
|
|
21662
|
-
});
|
|
21663
|
-
return;
|
|
21664
|
-
}
|
|
21665
|
-
try {
|
|
21666
|
-
state.span.log({ output: eventResult });
|
|
21667
|
-
} catch (error) {
|
|
21668
|
-
console.error("Error extracting output for Claude Agent SDK:", error);
|
|
21669
|
-
} finally {
|
|
21670
|
-
state.span.end();
|
|
21671
|
-
spans.delete(event);
|
|
22438
|
+
} catch (error) {
|
|
22439
|
+
console.error("Error extracting input for Claude Agent SDK:", error);
|
|
22440
|
+
}
|
|
22441
|
+
const activeToolSpans = /* @__PURE__ */ new Map();
|
|
22442
|
+
const activeLlmSpansByParentToolUse = /* @__PURE__ */ new Map();
|
|
22443
|
+
const conversationHistoryByParentKey = /* @__PURE__ */ new Map();
|
|
22444
|
+
const subAgentSpans = /* @__PURE__ */ new Map();
|
|
22445
|
+
const endedSubAgentSpans = /* @__PURE__ */ new Set();
|
|
22446
|
+
const toolUseToParent = /* @__PURE__ */ new Map();
|
|
22447
|
+
const latestLlmParentBySubAgentToolUse = /* @__PURE__ */ new Map();
|
|
22448
|
+
const latestRootLlmParentRef = {
|
|
22449
|
+
value: void 0
|
|
22450
|
+
};
|
|
22451
|
+
const subAgentDetailsByToolUseId = /* @__PURE__ */ new Map();
|
|
22452
|
+
const taskIdToToolUseId = /* @__PURE__ */ new Map();
|
|
22453
|
+
const promptMessagesByParentKey = /* @__PURE__ */ new Map();
|
|
22454
|
+
const promptSourcePriorityByParentKey = /* @__PURE__ */ new Map();
|
|
22455
|
+
const { hasLocalToolHandlers, localToolHookNames } = prepareLocalToolHandlersInMcpServers(options.mcpServers);
|
|
22456
|
+
const skipLocalToolHooks = options[CLAUDE_AGENT_SDK_SKIP_LOCAL_TOOL_HOOKS_OPTION] === true || hasLocalToolHandlers;
|
|
22457
|
+
const resolveToolUseParentSpan = async (toolUseID, context) => {
|
|
22458
|
+
const trackedParentToolUseId = toolUseToParent.get(toolUseID);
|
|
22459
|
+
const parentToolUseId = trackedParentToolUseId ?? (context?.agentId ? taskIdToToolUseId.get(context.agentId) ?? null : null);
|
|
22460
|
+
const parentKey = llmParentKey(parentToolUseId);
|
|
22461
|
+
const activeLlmSpan = activeLlmSpansByParentToolUse.get(parentKey);
|
|
22462
|
+
const latestLlmParent = parentToolUseId ? latestLlmParentBySubAgentToolUse.get(parentToolUseId) : latestRootLlmParentRef.value;
|
|
22463
|
+
if (!activeLlmSpan && !latestLlmParent) {
|
|
22464
|
+
await ensureActiveLlmSpanForParentToolUse(
|
|
22465
|
+
span,
|
|
22466
|
+
activeLlmSpansByParentToolUse,
|
|
22467
|
+
subAgentDetailsByToolUseId,
|
|
22468
|
+
activeToolSpans,
|
|
22469
|
+
subAgentSpans,
|
|
22470
|
+
parentToolUseId,
|
|
22471
|
+
getCurrentUnixTimestamp()
|
|
22472
|
+
);
|
|
21672
22473
|
}
|
|
21673
|
-
|
|
21674
|
-
|
|
21675
|
-
|
|
21676
|
-
|
|
21677
|
-
|
|
22474
|
+
if (parentToolUseId) {
|
|
22475
|
+
const subAgentSpan = await ensureSubAgentSpan(
|
|
22476
|
+
subAgentDetailsByToolUseId,
|
|
22477
|
+
span,
|
|
22478
|
+
activeToolSpans,
|
|
22479
|
+
subAgentSpans,
|
|
22480
|
+
parentToolUseId
|
|
22481
|
+
);
|
|
22482
|
+
return subAgentSpan.export();
|
|
21678
22483
|
}
|
|
21679
|
-
|
|
21680
|
-
|
|
22484
|
+
return span.export();
|
|
22485
|
+
};
|
|
22486
|
+
const optionsWithHooks = injectTracingHooks(
|
|
22487
|
+
options,
|
|
22488
|
+
resolveToolUseParentSpan,
|
|
22489
|
+
taskIdToToolUseId,
|
|
22490
|
+
toolUseToParent,
|
|
22491
|
+
activeToolSpans,
|
|
22492
|
+
localToolHookNames,
|
|
22493
|
+
skipLocalToolHooks,
|
|
22494
|
+
subAgentDetailsByToolUseId,
|
|
22495
|
+
subAgentSpans,
|
|
22496
|
+
endedSubAgentSpans
|
|
22497
|
+
);
|
|
22498
|
+
params.options = optionsWithHooks;
|
|
22499
|
+
return {
|
|
22500
|
+
activeLlmSpansByParentToolUse,
|
|
22501
|
+
activePartialMessageIdByParentKey: /* @__PURE__ */ new Map(),
|
|
22502
|
+
activeToolSpans,
|
|
22503
|
+
conversationHistoryByParentKey,
|
|
22504
|
+
capturedPromptMessages,
|
|
22505
|
+
currentMessageId: void 0,
|
|
22506
|
+
currentMessageStartTime: startTime,
|
|
22507
|
+
currentMessages: [],
|
|
22508
|
+
endedSubAgentSpans,
|
|
22509
|
+
finalOutputUsageMessageIds: /* @__PURE__ */ new Set(),
|
|
22510
|
+
finalResults: [],
|
|
22511
|
+
options: optionsWithHooks,
|
|
22512
|
+
originalPrompt,
|
|
22513
|
+
processing: Promise.resolve(),
|
|
22514
|
+
promptDone,
|
|
22515
|
+
promptMessagesByParentKey,
|
|
22516
|
+
promptStarted: () => promptStarted,
|
|
22517
|
+
promptSourcePriorityByParentKey,
|
|
22518
|
+
span,
|
|
22519
|
+
subAgentDetailsByToolUseId,
|
|
22520
|
+
subAgentSpans,
|
|
22521
|
+
taskIdToToolUseId,
|
|
22522
|
+
latestLlmParentBySubAgentToolUse,
|
|
22523
|
+
latestRootLlmParentRef,
|
|
22524
|
+
toolUseToParent,
|
|
22525
|
+
usageByMessageId: /* @__PURE__ */ new Map(),
|
|
22526
|
+
localToolParentResolver: resolveToolUseParentSpan
|
|
22527
|
+
};
|
|
22528
|
+
};
|
|
22529
|
+
const finishQuery = (state, result) => {
|
|
22530
|
+
if (isAsyncIterable(result)) {
|
|
22531
|
+
patchStreamIfNeeded(result, {
|
|
22532
|
+
aroundNext: (callback) => runWithClaudeLocalToolContext(
|
|
22533
|
+
callback,
|
|
22534
|
+
state.localToolParentResolver
|
|
22535
|
+
),
|
|
22536
|
+
onChunk: (message) => {
|
|
22537
|
+
maybeTrackToolUseContext(state, message);
|
|
22538
|
+
state.processing = state.processing.then(() => handleStreamMessage(state, message)).catch((error) => {
|
|
22539
|
+
console.error(
|
|
22540
|
+
"Error processing Claude Agent SDK stream chunk:",
|
|
22541
|
+
error
|
|
22542
|
+
);
|
|
22543
|
+
});
|
|
22544
|
+
},
|
|
22545
|
+
onComplete: () => state.processing.then(() => finalizeQuerySpan(state)),
|
|
22546
|
+
onError: (error) => state.processing.then(() => {
|
|
22547
|
+
state.span.log({ error: error.message });
|
|
22548
|
+
}).then(() => finalizeQuerySpan(state))
|
|
21681
22549
|
});
|
|
22550
|
+
return;
|
|
22551
|
+
}
|
|
22552
|
+
try {
|
|
22553
|
+
state.span.log({ output: result });
|
|
22554
|
+
} catch (error) {
|
|
22555
|
+
console.error("Error extracting output for Claude Agent SDK:", error);
|
|
22556
|
+
} finally {
|
|
21682
22557
|
state.span.end();
|
|
21683
|
-
spans.delete(event);
|
|
21684
22558
|
}
|
|
21685
22559
|
};
|
|
21686
|
-
|
|
21687
|
-
|
|
21688
|
-
|
|
21689
|
-
|
|
22560
|
+
this.unsubscribers.push(
|
|
22561
|
+
claudeAgentSDKChannels.query.intercept((target, thisArg, args) => {
|
|
22562
|
+
let state;
|
|
22563
|
+
try {
|
|
22564
|
+
args[0] ??= {};
|
|
22565
|
+
state = startQuery(args[0]);
|
|
22566
|
+
} catch (error) {
|
|
22567
|
+
debugLogger.error(
|
|
22568
|
+
"Error starting Claude Agent SDK instrumentation:",
|
|
22569
|
+
error
|
|
22570
|
+
);
|
|
22571
|
+
}
|
|
22572
|
+
const invokeTarget = () => Reflect.apply(target, thisArg, args);
|
|
22573
|
+
try {
|
|
22574
|
+
const result = state ? runWithClaudeLocalToolContext(
|
|
22575
|
+
invokeTarget,
|
|
22576
|
+
state.localToolParentResolver
|
|
22577
|
+
) : invokeTarget();
|
|
22578
|
+
if (state) {
|
|
22579
|
+
try {
|
|
22580
|
+
finishQuery(state, result);
|
|
22581
|
+
} catch (error) {
|
|
22582
|
+
debugLogger.error(
|
|
22583
|
+
"Error finalizing Claude Agent SDK instrumentation:",
|
|
22584
|
+
error
|
|
22585
|
+
);
|
|
22586
|
+
}
|
|
22587
|
+
}
|
|
22588
|
+
return result;
|
|
22589
|
+
} catch (error) {
|
|
22590
|
+
if (state) {
|
|
22591
|
+
try {
|
|
22592
|
+
state.span.log({
|
|
22593
|
+
error: error instanceof Error ? error.message : String(error)
|
|
22594
|
+
});
|
|
22595
|
+
state.span.end();
|
|
22596
|
+
} catch (instrumentationError) {
|
|
22597
|
+
debugLogger.error(
|
|
22598
|
+
"Error handling Claude Agent SDK instrumentation failure:",
|
|
22599
|
+
instrumentationError
|
|
22600
|
+
);
|
|
22601
|
+
}
|
|
22602
|
+
}
|
|
22603
|
+
throw error;
|
|
22604
|
+
}
|
|
22605
|
+
})
|
|
22606
|
+
);
|
|
21690
22607
|
}
|
|
21691
22608
|
};
|
|
21692
22609
|
|
|
@@ -25800,7 +26717,7 @@ function patchOpenRouterCallModelResult(args) {
|
|
|
25800
26717
|
span,
|
|
25801
26718
|
() => originalMethod.apply(resultLike, args2)
|
|
25802
26719
|
);
|
|
25803
|
-
if (!
|
|
26720
|
+
if (!isAsyncIterable3(stream)) {
|
|
25804
26721
|
return stream;
|
|
25805
26722
|
}
|
|
25806
26723
|
return wrapAsyncIterableWithSpan({
|
|
@@ -25995,7 +26912,7 @@ function wrapAsyncIterableWithSpan(args) {
|
|
|
25995
26912
|
}
|
|
25996
26913
|
};
|
|
25997
26914
|
}
|
|
25998
|
-
function
|
|
26915
|
+
function isAsyncIterable3(value) {
|
|
25999
26916
|
return !!value && (typeof value === "object" || typeof value === "function") && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
26000
26917
|
}
|
|
26001
26918
|
function normalizeError(error) {
|
|
@@ -26873,7 +27790,7 @@ function patchOpenRouterCallModelResult2(args) {
|
|
|
26873
27790
|
span,
|
|
26874
27791
|
() => originalMethod.apply(resultLike, args2)
|
|
26875
27792
|
);
|
|
26876
|
-
if (!
|
|
27793
|
+
if (!isAsyncIterable4(stream)) {
|
|
26877
27794
|
return stream;
|
|
26878
27795
|
}
|
|
26879
27796
|
return wrapAsyncIterableWithSpan2({
|
|
@@ -27068,7 +27985,7 @@ function wrapAsyncIterableWithSpan2(args) {
|
|
|
27068
27985
|
}
|
|
27069
27986
|
};
|
|
27070
27987
|
}
|
|
27071
|
-
function
|
|
27988
|
+
function isAsyncIterable4(value) {
|
|
27072
27989
|
return !!value && (typeof value === "object" || typeof value === "function") && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
27073
27990
|
}
|
|
27074
27991
|
function normalizeError2(error) {
|
|
@@ -33060,12 +33977,14 @@ function getMetricsFromResponse(response) {
|
|
|
33060
33977
|
continue;
|
|
33061
33978
|
}
|
|
33062
33979
|
const inputTokenDetails = usageMetadata.input_token_details;
|
|
33980
|
+
const outputTokenDetails = usageMetadata.output_token_details;
|
|
33063
33981
|
return normalizeTokenMetrics({
|
|
33064
33982
|
total_tokens: usageMetadata.total_tokens,
|
|
33065
33983
|
prompt_tokens: usageMetadata.input_tokens,
|
|
33066
33984
|
completion_tokens: usageMetadata.output_tokens,
|
|
33067
33985
|
prompt_cache_creation_tokens: isRecord(inputTokenDetails) ? inputTokenDetails.cache_creation : void 0,
|
|
33068
|
-
prompt_cached_tokens: isRecord(inputTokenDetails) ? inputTokenDetails.cache_read : void 0
|
|
33986
|
+
prompt_cached_tokens: isRecord(inputTokenDetails) ? inputTokenDetails.cache_read : void 0,
|
|
33987
|
+
completion_reasoning_tokens: isRecord(outputTokenDetails) ? outputTokenDetails.reasoning : void 0
|
|
33069
33988
|
});
|
|
33070
33989
|
}
|
|
33071
33990
|
const llmOutput = response.llmOutput || {};
|
|
@@ -33652,6 +34571,9 @@ var piCodingAgentChannels = defineChannels(
|
|
|
33652
34571
|
// src/instrumentation/plugins/pi-coding-agent-plugin.ts
|
|
33653
34572
|
var piAgentPatchStates = /* @__PURE__ */ new WeakMap();
|
|
33654
34573
|
var piAgentEventSubscriptions = /* @__PURE__ */ new WeakSet();
|
|
34574
|
+
var PI_TOOL_EXECUTE_WRAPPED = /* @__PURE__ */ Symbol.for(
|
|
34575
|
+
"braintrust.pi_coding_agent.tool_execute_wrapped"
|
|
34576
|
+
);
|
|
33655
34577
|
var piPromptContextStore;
|
|
33656
34578
|
var PiCodingAgentPlugin = class extends BasePlugin {
|
|
33657
34579
|
activePromptStates = /* @__PURE__ */ new Set();
|
|
@@ -33732,6 +34654,7 @@ function startPiPromptRun(event, onFinalize) {
|
|
|
33732
34654
|
return void 0;
|
|
33733
34655
|
}
|
|
33734
34656
|
installPiAgentInstrumentation(agent);
|
|
34657
|
+
wrapPiToolExecutors(agent.state?.tools);
|
|
33735
34658
|
const metadata = {
|
|
33736
34659
|
...extractSessionMetadata(session),
|
|
33737
34660
|
...extractPromptOptionsMetadata(event.arguments[1]),
|
|
@@ -33776,7 +34699,7 @@ function extractSession(event) {
|
|
|
33776
34699
|
return isObject(candidate) && typeof candidate.prompt === "function" ? candidate : void 0;
|
|
33777
34700
|
}
|
|
33778
34701
|
function isPiAgent(value) {
|
|
33779
|
-
return isObject(value) && typeof value.streamFn === "function" && typeof value.subscribe === "function";
|
|
34702
|
+
return isObject(value) && (typeof value.streamFunction === "function" || typeof value.streamFn === "function") && typeof value.subscribe === "function";
|
|
33780
34703
|
}
|
|
33781
34704
|
function promptContextStore() {
|
|
33782
34705
|
piPromptContextStore ??= isomorph_default.newAsyncLocalStorage();
|
|
@@ -33786,17 +34709,21 @@ function currentPiPromptState() {
|
|
|
33786
34709
|
return promptContextStore().getStore();
|
|
33787
34710
|
}
|
|
33788
34711
|
function installPiAgentInstrumentation(agent) {
|
|
34712
|
+
const property = typeof agent.streamFunction === "function" ? "streamFunction" : "streamFn";
|
|
34713
|
+
const streamFunction = agent[property];
|
|
33789
34714
|
const existing = piAgentPatchStates.get(agent);
|
|
33790
|
-
if (!existing ||
|
|
34715
|
+
if (streamFunction && (!existing || existing.property !== property || streamFunction !== existing.wrappedStreamFunction)) {
|
|
33791
34716
|
const patchState = {
|
|
33792
|
-
|
|
33793
|
-
|
|
34717
|
+
originalStreamFunction: streamFunction,
|
|
34718
|
+
property,
|
|
34719
|
+
wrappedStreamFunction: streamFunction
|
|
33794
34720
|
};
|
|
33795
|
-
patchState.
|
|
34721
|
+
patchState.wrappedStreamFunction = makeInstrumentedStreamFunction(
|
|
33796
34722
|
agent,
|
|
33797
|
-
patchState.
|
|
34723
|
+
patchState.originalStreamFunction,
|
|
34724
|
+
property
|
|
33798
34725
|
);
|
|
33799
|
-
agent
|
|
34726
|
+
agent[property] = patchState.wrappedStreamFunction;
|
|
33800
34727
|
piAgentPatchStates.set(agent, patchState);
|
|
33801
34728
|
}
|
|
33802
34729
|
if (piAgentEventSubscriptions.has(agent)) {
|
|
@@ -33821,14 +34748,21 @@ function installPiAgentInstrumentation(agent) {
|
|
|
33821
34748
|
logInstrumentationError4("Pi Coding Agent event subscription", error);
|
|
33822
34749
|
}
|
|
33823
34750
|
}
|
|
33824
|
-
function
|
|
33825
|
-
return async function
|
|
33826
|
-
const invokeOriginal = () => Reflect.apply(
|
|
34751
|
+
function makeInstrumentedStreamFunction(agent, originalStreamFunction, property) {
|
|
34752
|
+
return async function instrumentedPiStreamFunction(model, context, options) {
|
|
34753
|
+
const invokeOriginal = () => Reflect.apply(originalStreamFunction, this, [model, context, options]);
|
|
33827
34754
|
const state = currentPiPromptState();
|
|
33828
34755
|
if (!state || state.agent !== agent || state.finalized) {
|
|
33829
34756
|
return invokeOriginal();
|
|
33830
34757
|
}
|
|
33831
|
-
|
|
34758
|
+
wrapPiToolExecutors(context.tools);
|
|
34759
|
+
const llmState = await startPiLlmSpan(
|
|
34760
|
+
state,
|
|
34761
|
+
model,
|
|
34762
|
+
context,
|
|
34763
|
+
property,
|
|
34764
|
+
options
|
|
34765
|
+
);
|
|
33832
34766
|
try {
|
|
33833
34767
|
const stream = await runWithAutoInstrumentationSuppressed(invokeOriginal);
|
|
33834
34768
|
return patchAssistantMessageStream(stream, state, llmState);
|
|
@@ -33838,12 +34772,39 @@ function makeInstrumentedStreamFn(agent, originalStreamFn) {
|
|
|
33838
34772
|
}
|
|
33839
34773
|
};
|
|
33840
34774
|
}
|
|
33841
|
-
|
|
34775
|
+
function wrapPiToolExecutors(tools) {
|
|
34776
|
+
if (!tools) {
|
|
34777
|
+
return;
|
|
34778
|
+
}
|
|
34779
|
+
for (const tool of tools) {
|
|
34780
|
+
try {
|
|
34781
|
+
const execute = tool.execute;
|
|
34782
|
+
if (typeof execute !== "function" || execute[PI_TOOL_EXECUTE_WRAPPED]) {
|
|
34783
|
+
continue;
|
|
34784
|
+
}
|
|
34785
|
+
const wrappedExecute = function(...args) {
|
|
34786
|
+
return runWithAutoInstrumentationAllowed(
|
|
34787
|
+
() => Reflect.apply(execute, this, args)
|
|
34788
|
+
);
|
|
34789
|
+
};
|
|
34790
|
+
Object.defineProperty(wrappedExecute, PI_TOOL_EXECUTE_WRAPPED, {
|
|
34791
|
+
configurable: false,
|
|
34792
|
+
enumerable: false,
|
|
34793
|
+
value: true,
|
|
34794
|
+
writable: false
|
|
34795
|
+
});
|
|
34796
|
+
tool.execute = wrappedExecute;
|
|
34797
|
+
} catch (error) {
|
|
34798
|
+
logInstrumentationError4("Pi Coding Agent tool wrapping", error);
|
|
34799
|
+
}
|
|
34800
|
+
}
|
|
34801
|
+
}
|
|
34802
|
+
async function startPiLlmSpan(state, model, context, property, options) {
|
|
33842
34803
|
const metadata = {
|
|
33843
34804
|
...extractModelMetadata2(model),
|
|
33844
34805
|
...extractStreamOptionsMetadata(options),
|
|
33845
34806
|
...extractToolMetadata(context.tools),
|
|
33846
|
-
"pi_coding_agent.operation":
|
|
34807
|
+
"pi_coding_agent.operation": `agent.${property}`
|
|
33847
34808
|
};
|
|
33848
34809
|
const span = startSpan(
|
|
33849
34810
|
withSpanInstrumentationName(
|
|
@@ -34009,35 +34970,26 @@ async function startPiToolSpan(state, event) {
|
|
|
34009
34970
|
if (!event.toolCallId || state.activeToolSpans.has(event.toolCallId)) {
|
|
34010
34971
|
return;
|
|
34011
34972
|
}
|
|
34012
|
-
const restoreAutoInstrumentation = enterAutoInstrumentationAllowed();
|
|
34013
34973
|
const metadata = {
|
|
34014
34974
|
"gen_ai.tool.call.id": event.toolCallId,
|
|
34015
34975
|
"gen_ai.tool.name": event.toolName,
|
|
34016
34976
|
"pi_coding_agent.tool.name": event.toolName
|
|
34017
34977
|
};
|
|
34018
|
-
|
|
34019
|
-
|
|
34020
|
-
|
|
34021
|
-
{
|
|
34022
|
-
|
|
34023
|
-
|
|
34024
|
-
metadata
|
|
34025
|
-
},
|
|
34026
|
-
name: event.toolName || "tool",
|
|
34027
|
-
parent: await state.span.export(),
|
|
34028
|
-
spanAttributes: { type: "tool" /* TOOL */ }
|
|
34978
|
+
const span = startSpan(
|
|
34979
|
+
withSpanInstrumentationName(
|
|
34980
|
+
{
|
|
34981
|
+
event: {
|
|
34982
|
+
input: event.args,
|
|
34983
|
+
metadata
|
|
34029
34984
|
},
|
|
34030
|
-
|
|
34031
|
-
|
|
34032
|
-
|
|
34033
|
-
|
|
34034
|
-
|
|
34035
|
-
|
|
34036
|
-
|
|
34037
|
-
|
|
34038
|
-
restoreAutoInstrumentation();
|
|
34039
|
-
throw error;
|
|
34040
|
-
}
|
|
34985
|
+
name: event.toolName || "tool",
|
|
34986
|
+
parent: await state.span.export(),
|
|
34987
|
+
spanAttributes: { type: "tool" /* TOOL */ }
|
|
34988
|
+
},
|
|
34989
|
+
INSTRUMENTATION_NAMES.PI_CODING_AGENT
|
|
34990
|
+
)
|
|
34991
|
+
);
|
|
34992
|
+
state.activeToolSpans.set(event.toolCallId, { span });
|
|
34041
34993
|
}
|
|
34042
34994
|
function finishPiToolSpan(state, event) {
|
|
34043
34995
|
const toolState = state.activeToolSpans.get(event.toolCallId);
|
|
@@ -34058,11 +35010,7 @@ function finishPiToolSpan(state, event) {
|
|
|
34058
35010
|
output: event.result
|
|
34059
35011
|
});
|
|
34060
35012
|
} finally {
|
|
34061
|
-
|
|
34062
|
-
toolState.span.end();
|
|
34063
|
-
} finally {
|
|
34064
|
-
toolState.restoreAutoInstrumentation?.();
|
|
34065
|
-
}
|
|
35013
|
+
toolState.span.end();
|
|
34066
35014
|
}
|
|
34067
35015
|
}
|
|
34068
35016
|
function finishPiPromptRun(state, error) {
|
|
@@ -34112,10 +35060,10 @@ function finishPiLlmSpan(promptState, llmState, message, error) {
|
|
|
34112
35060
|
...cleanMetrics5(llmState.metrics),
|
|
34113
35061
|
...buildDurationMetrics3(llmState.startTime)
|
|
34114
35062
|
};
|
|
34115
|
-
const
|
|
34116
|
-
if (Object.keys(
|
|
35063
|
+
const usageMetrics2 = extractUsageMetrics2(message?.usage);
|
|
35064
|
+
if (Object.keys(usageMetrics2).length > 0) {
|
|
34117
35065
|
promptState.collectedLlmUsageMetrics = true;
|
|
34118
|
-
addMetrics(promptState.metrics,
|
|
35066
|
+
addMetrics(promptState.metrics, usageMetrics2);
|
|
34119
35067
|
}
|
|
34120
35068
|
try {
|
|
34121
35069
|
safeLog4(llmState.span, {
|
|
@@ -34133,14 +35081,10 @@ function finishPiLlmSpan(promptState, llmState, message, error) {
|
|
|
34133
35081
|
}
|
|
34134
35082
|
function finishOpenToolSpans(state, error) {
|
|
34135
35083
|
for (const [, toolState] of state.activeToolSpans) {
|
|
34136
|
-
|
|
34137
|
-
|
|
34138
|
-
|
|
34139
|
-
|
|
34140
|
-
toolState.span.end();
|
|
34141
|
-
} finally {
|
|
34142
|
-
toolState.restoreAutoInstrumentation?.();
|
|
34143
|
-
}
|
|
35084
|
+
safeLog4(toolState.span, {
|
|
35085
|
+
error: error ? toLoggedError(error) : "Pi tool did not complete"
|
|
35086
|
+
});
|
|
35087
|
+
toolState.span.end();
|
|
34144
35088
|
}
|
|
34145
35089
|
state.activeToolSpans.clear();
|
|
34146
35090
|
}
|
|
@@ -34459,12 +35403,12 @@ var MAX_STRANDS_STRING_ATTACHMENT_CACHE_ENTRIES = 32;
|
|
|
34459
35403
|
var StrandsAgentSDKPlugin = class extends BasePlugin {
|
|
34460
35404
|
activeChildParents = /* @__PURE__ */ new WeakMap();
|
|
34461
35405
|
onEnable() {
|
|
34462
|
-
this.
|
|
34463
|
-
this.
|
|
35406
|
+
this.interceptAgentStream();
|
|
35407
|
+
this.interceptMultiAgentStream(
|
|
34464
35408
|
strandsAgentSDKChannels.graphStream,
|
|
34465
35409
|
"Graph.stream"
|
|
34466
35410
|
);
|
|
34467
|
-
this.
|
|
35411
|
+
this.interceptMultiAgentStream(
|
|
34468
35412
|
strandsAgentSDKChannels.swarmStream,
|
|
34469
35413
|
"Swarm.stream"
|
|
34470
35414
|
);
|
|
@@ -34475,122 +35419,92 @@ var StrandsAgentSDKPlugin = class extends BasePlugin {
|
|
|
34475
35419
|
}
|
|
34476
35420
|
this.unsubscribers = [];
|
|
34477
35421
|
}
|
|
34478
|
-
|
|
34479
|
-
|
|
34480
|
-
|
|
34481
|
-
|
|
34482
|
-
|
|
34483
|
-
|
|
34484
|
-
|
|
34485
|
-
|
|
34486
|
-
|
|
34487
|
-
|
|
34488
|
-
|
|
34489
|
-
|
|
34490
|
-
|
|
34491
|
-
|
|
34492
|
-
|
|
34493
|
-
|
|
34494
|
-
const result = event.result;
|
|
34495
|
-
if (isAsyncIterable(result)) {
|
|
34496
|
-
patchStreamIfNeeded(result, {
|
|
34497
|
-
aroundNext: (callback) => runWithAutoInstrumentationSuppressed(callback),
|
|
34498
|
-
onChunk: (chunk) => handleAgentStreamEvent(state, chunk),
|
|
34499
|
-
onComplete: () => {
|
|
34500
|
-
finalizeAgentStream(state);
|
|
34501
|
-
states.delete(event);
|
|
34502
|
-
},
|
|
34503
|
-
onError: (error) => {
|
|
34504
|
-
finalizeAgentStream(state, error);
|
|
34505
|
-
states.delete(event);
|
|
34506
|
-
}
|
|
34507
|
-
});
|
|
34508
|
-
return;
|
|
34509
|
-
}
|
|
34510
|
-
finalizeAgentStream(state, void 0, result);
|
|
34511
|
-
states.delete(event);
|
|
34512
|
-
},
|
|
34513
|
-
error: (event) => {
|
|
34514
|
-
const state = states.get(event);
|
|
34515
|
-
if (!state || !event.error) {
|
|
34516
|
-
return;
|
|
34517
|
-
}
|
|
34518
|
-
finalizeAgentStream(state, event.error);
|
|
34519
|
-
states.delete(event);
|
|
34520
|
-
}
|
|
34521
|
-
};
|
|
34522
|
-
channel2.subscribe(handlers);
|
|
34523
|
-
this.unsubscribers.push(() => {
|
|
34524
|
-
unbindAutoInstrumentationSuppression?.();
|
|
34525
|
-
channel2.unsubscribe(handlers);
|
|
34526
|
-
});
|
|
35422
|
+
interceptAgentStream() {
|
|
35423
|
+
this.unsubscribers.push(
|
|
35424
|
+
strandsAgentSDKChannels.agentStream.intercept(
|
|
35425
|
+
(target, thisArg, args, additional) => instrumentStrandsStreamInvocation({
|
|
35426
|
+
finalize: finalizeAgentStream,
|
|
35427
|
+
handleChunk: handleAgentStreamEvent,
|
|
35428
|
+
invoke: () => Reflect.apply(target, thisArg, args),
|
|
35429
|
+
name: "Strands Agent SDK",
|
|
35430
|
+
start: () => startAgentStream(
|
|
35431
|
+
args[0],
|
|
35432
|
+
extractAgent(additional.agent, thisArg),
|
|
35433
|
+
this.activeChildParents
|
|
35434
|
+
)
|
|
35435
|
+
})
|
|
35436
|
+
)
|
|
35437
|
+
);
|
|
34527
35438
|
}
|
|
34528
|
-
|
|
34529
|
-
|
|
34530
|
-
|
|
34531
|
-
|
|
34532
|
-
|
|
34533
|
-
|
|
34534
|
-
|
|
34535
|
-
|
|
34536
|
-
|
|
34537
|
-
|
|
34538
|
-
|
|
34539
|
-
|
|
34540
|
-
|
|
34541
|
-
|
|
34542
|
-
|
|
34543
|
-
|
|
34544
|
-
|
|
34545
|
-
|
|
34546
|
-
|
|
34547
|
-
}
|
|
34548
|
-
|
|
34549
|
-
|
|
34550
|
-
|
|
34551
|
-
|
|
34552
|
-
|
|
34553
|
-
|
|
34554
|
-
|
|
34555
|
-
|
|
34556
|
-
|
|
34557
|
-
|
|
34558
|
-
|
|
34559
|
-
|
|
34560
|
-
|
|
34561
|
-
|
|
34562
|
-
|
|
34563
|
-
|
|
34564
|
-
|
|
34565
|
-
|
|
34566
|
-
|
|
34567
|
-
|
|
34568
|
-
|
|
34569
|
-
|
|
34570
|
-
this.activeChildParents,
|
|
34571
|
-
void 0,
|
|
34572
|
-
result
|
|
35439
|
+
interceptMultiAgentStream(channel2, operation) {
|
|
35440
|
+
this.unsubscribers.push(
|
|
35441
|
+
channel2.intercept(
|
|
35442
|
+
(target, thisArg, args, additional) => instrumentStrandsStreamInvocation({
|
|
35443
|
+
finalize: (state, error, output) => finalizeMultiAgentStream(
|
|
35444
|
+
state,
|
|
35445
|
+
this.activeChildParents,
|
|
35446
|
+
error,
|
|
35447
|
+
output
|
|
35448
|
+
),
|
|
35449
|
+
handleChunk: (state, chunk) => handleMultiAgentStreamEvent(state, chunk, this.activeChildParents),
|
|
35450
|
+
invoke: () => Reflect.apply(target, thisArg, args),
|
|
35451
|
+
name: "Strands multi-agent",
|
|
35452
|
+
start: () => startMultiAgentStream(
|
|
35453
|
+
args[0],
|
|
35454
|
+
extractOrchestrator(additional.orchestrator, thisArg),
|
|
35455
|
+
operation,
|
|
35456
|
+
this.activeChildParents
|
|
35457
|
+
)
|
|
35458
|
+
})
|
|
35459
|
+
)
|
|
35460
|
+
);
|
|
35461
|
+
}
|
|
35462
|
+
};
|
|
35463
|
+
function instrumentStrandsStreamInvocation(options) {
|
|
35464
|
+
let state;
|
|
35465
|
+
try {
|
|
35466
|
+
state = options.start();
|
|
35467
|
+
} catch (error) {
|
|
35468
|
+
debugLogger.error(`Error starting ${options.name} instrumentation:`, error);
|
|
35469
|
+
}
|
|
35470
|
+
let result;
|
|
35471
|
+
try {
|
|
35472
|
+
result = runWithAutoInstrumentationSuppressed(options.invoke);
|
|
35473
|
+
} catch (error) {
|
|
35474
|
+
if (state) {
|
|
35475
|
+
try {
|
|
35476
|
+
options.finalize(state, error);
|
|
35477
|
+
} catch (instrumentationError) {
|
|
35478
|
+
debugLogger.error(
|
|
35479
|
+
`Error handling ${options.name} instrumentation failure:`,
|
|
35480
|
+
instrumentationError
|
|
34573
35481
|
);
|
|
34574
|
-
states.delete(event);
|
|
34575
|
-
},
|
|
34576
|
-
error: (event) => {
|
|
34577
|
-
const state = states.get(event);
|
|
34578
|
-
if (!state || !event.error) {
|
|
34579
|
-
return;
|
|
34580
|
-
}
|
|
34581
|
-
finalizeMultiAgentStream(state, this.activeChildParents, event.error);
|
|
34582
|
-
states.delete(event);
|
|
34583
35482
|
}
|
|
34584
|
-
}
|
|
34585
|
-
|
|
34586
|
-
this.unsubscribers.push(() => {
|
|
34587
|
-
unbindAutoInstrumentationSuppression?.();
|
|
34588
|
-
tracingChannel.unsubscribe(handlers);
|
|
34589
|
-
});
|
|
35483
|
+
}
|
|
35484
|
+
throw error;
|
|
34590
35485
|
}
|
|
34591
|
-
|
|
34592
|
-
|
|
34593
|
-
|
|
35486
|
+
if (state) {
|
|
35487
|
+
try {
|
|
35488
|
+
if (isAsyncIterable(result)) {
|
|
35489
|
+
patchStreamIfNeeded(result, {
|
|
35490
|
+
aroundNext: (callback) => runWithAutoInstrumentationSuppressed(callback),
|
|
35491
|
+
onChunk: (chunk) => options.handleChunk(state, chunk),
|
|
35492
|
+
onComplete: () => options.finalize(state),
|
|
35493
|
+
onError: (error) => options.finalize(state, error)
|
|
35494
|
+
});
|
|
35495
|
+
} else {
|
|
35496
|
+
options.finalize(state, void 0, result);
|
|
35497
|
+
}
|
|
35498
|
+
} catch (error) {
|
|
35499
|
+
debugLogger.error(
|
|
35500
|
+
`Error finalizing ${options.name} instrumentation:`,
|
|
35501
|
+
error
|
|
35502
|
+
);
|
|
35503
|
+
}
|
|
35504
|
+
}
|
|
35505
|
+
return result;
|
|
35506
|
+
}
|
|
35507
|
+
function startAgentStream(input, agent, activeChildParents) {
|
|
34594
35508
|
const model = agent?.model;
|
|
34595
35509
|
const metadata = {
|
|
34596
35510
|
...extractAgentMetadata2(agent),
|
|
@@ -34600,17 +35514,14 @@ function startAgentStream(event, activeChildParents) {
|
|
|
34600
35514
|
};
|
|
34601
35515
|
const parentSpan = agent ? getOnlyChildParent(activeChildParents, agent) : void 0;
|
|
34602
35516
|
const attachmentCache = createStrandsAttachmentCache();
|
|
34603
|
-
const
|
|
34604
|
-
event.arguments[0],
|
|
34605
|
-
attachmentCache
|
|
34606
|
-
);
|
|
35517
|
+
const processedInput = processStrandsInputAttachments(input, attachmentCache);
|
|
34607
35518
|
const span = parentSpan ? withCurrent(
|
|
34608
35519
|
parentSpan,
|
|
34609
35520
|
() => startSpan(
|
|
34610
35521
|
withSpanInstrumentationName(
|
|
34611
35522
|
{
|
|
34612
35523
|
event: {
|
|
34613
|
-
input,
|
|
35524
|
+
input: processedInput,
|
|
34614
35525
|
metadata
|
|
34615
35526
|
},
|
|
34616
35527
|
name: formatAgentSpanName(agent),
|
|
@@ -34623,7 +35534,7 @@ function startAgentStream(event, activeChildParents) {
|
|
|
34623
35534
|
withSpanInstrumentationName(
|
|
34624
35535
|
{
|
|
34625
35536
|
event: {
|
|
34626
|
-
input,
|
|
35537
|
+
input: processedInput,
|
|
34627
35538
|
metadata
|
|
34628
35539
|
},
|
|
34629
35540
|
name: formatAgentSpanName(agent),
|
|
@@ -34641,22 +35552,21 @@ function startAgentStream(event, activeChildParents) {
|
|
|
34641
35552
|
startTime: getCurrentUnixTimestamp()
|
|
34642
35553
|
};
|
|
34643
35554
|
}
|
|
34644
|
-
function startMultiAgentStream(
|
|
34645
|
-
const orchestrator = extractOrchestrator(event);
|
|
35555
|
+
function startMultiAgentStream(input, orchestrator, operation, activeChildParents) {
|
|
34646
35556
|
const metadata = {
|
|
34647
35557
|
"strands.operation": operation,
|
|
34648
35558
|
provider: "strands",
|
|
34649
35559
|
...orchestrator?.id ? { "strands.orchestrator.id": orchestrator.id } : {}
|
|
34650
35560
|
};
|
|
34651
35561
|
const parentSpan = orchestrator ? getOnlyChildParent(activeChildParents, orchestrator) : void 0;
|
|
34652
|
-
const
|
|
35562
|
+
const processedInput = processStrandsInputAttachments(input);
|
|
34653
35563
|
const span = parentSpan ? withCurrent(
|
|
34654
35564
|
parentSpan,
|
|
34655
35565
|
() => startSpan(
|
|
34656
35566
|
withSpanInstrumentationName(
|
|
34657
35567
|
{
|
|
34658
35568
|
event: {
|
|
34659
|
-
input,
|
|
35569
|
+
input: processedInput,
|
|
34660
35570
|
metadata
|
|
34661
35571
|
},
|
|
34662
35572
|
name: operation === "Graph.stream" ? "Strands Graph" : "Strands Swarm",
|
|
@@ -34669,7 +35579,7 @@ function startMultiAgentStream(event, operation, activeChildParents) {
|
|
|
34669
35579
|
withSpanInstrumentationName(
|
|
34670
35580
|
{
|
|
34671
35581
|
event: {
|
|
34672
|
-
input,
|
|
35582
|
+
input: processedInput,
|
|
34673
35583
|
metadata
|
|
34674
35584
|
},
|
|
34675
35585
|
name: operation === "Graph.stream" ? "Strands Graph" : "Strands Swarm",
|
|
@@ -35040,12 +35950,12 @@ function finalizeMultiAgentStream(state, activeChildParents, error, output) {
|
|
|
35040
35950
|
});
|
|
35041
35951
|
state.span.end();
|
|
35042
35952
|
}
|
|
35043
|
-
function extractAgent(
|
|
35044
|
-
const candidate =
|
|
35953
|
+
function extractAgent(agent, self) {
|
|
35954
|
+
const candidate = agent ?? self;
|
|
35045
35955
|
return isObject(candidate) && typeof candidate.stream === "function" ? candidate : void 0;
|
|
35046
35956
|
}
|
|
35047
|
-
function extractOrchestrator(
|
|
35048
|
-
const candidate =
|
|
35957
|
+
function extractOrchestrator(orchestrator, self) {
|
|
35958
|
+
const candidate = orchestrator ?? self;
|
|
35049
35959
|
return isObject(candidate) && typeof candidate.stream === "function" ? candidate : void 0;
|
|
35050
35960
|
}
|
|
35051
35961
|
function extractAgentMetadata2(agent) {
|
|
@@ -36910,6 +37820,7 @@ __export(exports_exports, {
|
|
|
36910
37820
|
braintrustStreamChunkSchema: () => braintrustStreamChunkSchema,
|
|
36911
37821
|
buildLocalSummary: () => buildLocalSummary,
|
|
36912
37822
|
collectAnthropicSession: () => collectAnthropicSession,
|
|
37823
|
+
completeOpenAIBatchTrace: () => completeOpenAIBatchTrace,
|
|
36913
37824
|
configureInstrumentation: () => configureInstrumentation,
|
|
36914
37825
|
constructLogs3OverflowRequest: () => constructLogs3OverflowRequest,
|
|
36915
37826
|
createFinalValuePassThroughStream: () => createFinalValuePassThroughStream,
|
|
@@ -36948,6 +37859,8 @@ __export(exports_exports, {
|
|
|
36948
37859
|
loginToState: () => loginToState,
|
|
36949
37860
|
logs3OverflowUploadSchema: () => logs3OverflowUploadSchema,
|
|
36950
37861
|
newId: () => newId,
|
|
37862
|
+
openaiBatchesRetrieveTraced: () => openaiBatchesRetrieveTraced,
|
|
37863
|
+
openaiFilesCreateTraced: () => openaiFilesCreateTraced,
|
|
36951
37864
|
parseCachedHeader: () => parseCachedHeader,
|
|
36952
37865
|
parseTemplateFormat: () => parseTemplateFormat,
|
|
36953
37866
|
permalink: () => permalink,
|
|
@@ -37112,6 +38025,260 @@ async function registerSandbox(options) {
|
|
|
37112
38025
|
};
|
|
37113
38026
|
}
|
|
37114
38027
|
|
|
38028
|
+
// src/wrappers/openai-promise-utils.ts
|
|
38029
|
+
function splitSpanInfo(allParams) {
|
|
38030
|
+
const { span_info, ...params } = allParams;
|
|
38031
|
+
return {
|
|
38032
|
+
params,
|
|
38033
|
+
span_info
|
|
38034
|
+
};
|
|
38035
|
+
}
|
|
38036
|
+
function createChannelContext(_channel, params, span_info) {
|
|
38037
|
+
return {
|
|
38038
|
+
arguments: (
|
|
38039
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38040
|
+
[params]
|
|
38041
|
+
),
|
|
38042
|
+
span_info
|
|
38043
|
+
};
|
|
38044
|
+
}
|
|
38045
|
+
async function tracePromiseWithResponse(channel2, traceContext, apiPromise) {
|
|
38046
|
+
let enhancedResponse;
|
|
38047
|
+
const tracePromise = (
|
|
38048
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38049
|
+
channel2.tracePromise
|
|
38050
|
+
);
|
|
38051
|
+
const data = await tracePromise(async () => {
|
|
38052
|
+
enhancedResponse = await apiPromise.withResponse();
|
|
38053
|
+
traceContext.response = enhancedResponse.response;
|
|
38054
|
+
return enhancedResponse.data;
|
|
38055
|
+
}, traceContext);
|
|
38056
|
+
if (!enhancedResponse) {
|
|
38057
|
+
throw new Error("Expected withResponse() to provide response");
|
|
38058
|
+
}
|
|
38059
|
+
return {
|
|
38060
|
+
data,
|
|
38061
|
+
response: enhancedResponse.response,
|
|
38062
|
+
request_id: enhancedResponse.request_id
|
|
38063
|
+
};
|
|
38064
|
+
}
|
|
38065
|
+
async function tracePromiseAsResponse(channel2, traceContext, apiPromise) {
|
|
38066
|
+
const tracePromise = (
|
|
38067
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38068
|
+
channel2.tracePromise
|
|
38069
|
+
);
|
|
38070
|
+
let response;
|
|
38071
|
+
await tracePromise(async () => {
|
|
38072
|
+
response = await apiPromise.asResponse();
|
|
38073
|
+
traceContext.response = response;
|
|
38074
|
+
return void 0;
|
|
38075
|
+
}, traceContext);
|
|
38076
|
+
if (!response) {
|
|
38077
|
+
throw new Error("Expected asResponse() to provide response");
|
|
38078
|
+
}
|
|
38079
|
+
return response;
|
|
38080
|
+
}
|
|
38081
|
+
function createLazyAPIPromise(ensureExecuted, ensureResponse, getAPIPromise) {
|
|
38082
|
+
let firstConsumption;
|
|
38083
|
+
let enhancedResponsePromise;
|
|
38084
|
+
let dataPromise;
|
|
38085
|
+
let responsePromise;
|
|
38086
|
+
const withResponse = () => {
|
|
38087
|
+
firstConsumption ??= "data";
|
|
38088
|
+
enhancedResponsePromise ??= firstConsumption === "data" ? ensureExecuted() : getAPIPromise().withResponse();
|
|
38089
|
+
return enhancedResponsePromise;
|
|
38090
|
+
};
|
|
38091
|
+
const asResponse = () => {
|
|
38092
|
+
firstConsumption ??= "response";
|
|
38093
|
+
responsePromise ??= firstConsumption === "response" ? ensureResponse() : getAPIPromise().asResponse();
|
|
38094
|
+
return responsePromise;
|
|
38095
|
+
};
|
|
38096
|
+
return new Proxy({}, {
|
|
38097
|
+
get(target, prop, receiver) {
|
|
38098
|
+
if (prop === "withResponse") {
|
|
38099
|
+
return withResponse;
|
|
38100
|
+
}
|
|
38101
|
+
if (prop === "asResponse") {
|
|
38102
|
+
return asResponse;
|
|
38103
|
+
}
|
|
38104
|
+
if (prop === "then" || prop === "catch" || prop === "finally" || prop in Promise.prototype) {
|
|
38105
|
+
dataPromise ??= withResponse().then((result) => result.data);
|
|
38106
|
+
const value = Reflect.get(dataPromise, prop, receiver);
|
|
38107
|
+
return typeof value === "function" ? value.bind(dataPromise) : value;
|
|
38108
|
+
}
|
|
38109
|
+
return Reflect.get(target, prop, receiver);
|
|
38110
|
+
}
|
|
38111
|
+
});
|
|
38112
|
+
}
|
|
38113
|
+
|
|
38114
|
+
// src/openai-batch.ts
|
|
38115
|
+
function read2(value, key) {
|
|
38116
|
+
if (value === null || typeof value !== "object" && typeof value !== "function") {
|
|
38117
|
+
return void 0;
|
|
38118
|
+
}
|
|
38119
|
+
try {
|
|
38120
|
+
return Reflect.get(value, key);
|
|
38121
|
+
} catch {
|
|
38122
|
+
return void 0;
|
|
38123
|
+
}
|
|
38124
|
+
}
|
|
38125
|
+
function isAsyncIterable5(value) {
|
|
38126
|
+
return typeof read2(value, Symbol.asyncIterator) === "function";
|
|
38127
|
+
}
|
|
38128
|
+
function teeAsyncIterable(source) {
|
|
38129
|
+
const iterator = source[Symbol.asyncIterator]();
|
|
38130
|
+
const stream = new ReadableStream({
|
|
38131
|
+
async pull(controller) {
|
|
38132
|
+
try {
|
|
38133
|
+
const result = await iterator.next();
|
|
38134
|
+
if (result.done) {
|
|
38135
|
+
controller.close();
|
|
38136
|
+
return;
|
|
38137
|
+
}
|
|
38138
|
+
if (!(result.value instanceof Uint8Array)) {
|
|
38139
|
+
throw new TypeError(
|
|
38140
|
+
"OpenAI upload streams must yield Uint8Array chunks"
|
|
38141
|
+
);
|
|
38142
|
+
}
|
|
38143
|
+
controller.enqueue(result.value);
|
|
38144
|
+
} catch (error) {
|
|
38145
|
+
controller.error(error);
|
|
38146
|
+
}
|
|
38147
|
+
},
|
|
38148
|
+
async cancel(reason) {
|
|
38149
|
+
await iterator.return?.(reason);
|
|
38150
|
+
}
|
|
38151
|
+
});
|
|
38152
|
+
const [uploadStream, trace] = stream.tee();
|
|
38153
|
+
const upload = {
|
|
38154
|
+
async *[Symbol.asyncIterator]() {
|
|
38155
|
+
const reader = uploadStream.getReader();
|
|
38156
|
+
try {
|
|
38157
|
+
while (true) {
|
|
38158
|
+
const result = await reader.read();
|
|
38159
|
+
if (result.done) {
|
|
38160
|
+
return;
|
|
38161
|
+
}
|
|
38162
|
+
yield result.value;
|
|
38163
|
+
}
|
|
38164
|
+
} finally {
|
|
38165
|
+
reader.releaseLock();
|
|
38166
|
+
}
|
|
38167
|
+
}
|
|
38168
|
+
};
|
|
38169
|
+
const path = read2(source, "path");
|
|
38170
|
+
if (typeof path === "string") {
|
|
38171
|
+
Object.defineProperty(upload, "path", { value: path });
|
|
38172
|
+
}
|
|
38173
|
+
return { upload, trace: new Response(trace) };
|
|
38174
|
+
}
|
|
38175
|
+
function teeUpload(upload) {
|
|
38176
|
+
if (upload instanceof Blob) {
|
|
38177
|
+
return { upload, trace: new Response(upload) };
|
|
38178
|
+
}
|
|
38179
|
+
if (upload instanceof Response) {
|
|
38180
|
+
return { upload, trace: upload.clone() };
|
|
38181
|
+
}
|
|
38182
|
+
if (isAsyncIterable5(upload)) {
|
|
38183
|
+
return teeAsyncIterable(upload);
|
|
38184
|
+
}
|
|
38185
|
+
return void 0;
|
|
38186
|
+
}
|
|
38187
|
+
function openaiFilesCreateTraced(files) {
|
|
38188
|
+
return (params, options) => {
|
|
38189
|
+
const parent = getSpanParentObject();
|
|
38190
|
+
const purpose = read2(params, "purpose");
|
|
38191
|
+
const file = read2(params, "file");
|
|
38192
|
+
if (purpose !== "batch") {
|
|
38193
|
+
return files.create(params, options);
|
|
38194
|
+
}
|
|
38195
|
+
let branches;
|
|
38196
|
+
try {
|
|
38197
|
+
branches = teeUpload(file);
|
|
38198
|
+
} catch {
|
|
38199
|
+
return files.create(params, options);
|
|
38200
|
+
}
|
|
38201
|
+
if (!branches) {
|
|
38202
|
+
return files.create(params, options);
|
|
38203
|
+
}
|
|
38204
|
+
const tracedParams = {
|
|
38205
|
+
...Object(params),
|
|
38206
|
+
file: branches.upload
|
|
38207
|
+
};
|
|
38208
|
+
const apiPromise = files.create(tracedParams, options);
|
|
38209
|
+
let enhancedResponse;
|
|
38210
|
+
const tracedResponse = openAIChannels.filesCreateTraced.invoke(
|
|
38211
|
+
async () => {
|
|
38212
|
+
enhancedResponse = await apiPromise.withResponse();
|
|
38213
|
+
return enhancedResponse.data;
|
|
38214
|
+
},
|
|
38215
|
+
files,
|
|
38216
|
+
[{ params, inputFileContent: branches.trace, parent }],
|
|
38217
|
+
{}
|
|
38218
|
+
).then((data) => {
|
|
38219
|
+
if (!enhancedResponse) {
|
|
38220
|
+
throw new Error(
|
|
38221
|
+
"Expected OpenAI withResponse() to provide a response"
|
|
38222
|
+
);
|
|
38223
|
+
}
|
|
38224
|
+
return { ...enhancedResponse, data };
|
|
38225
|
+
});
|
|
38226
|
+
return createLazyAPIPromise(
|
|
38227
|
+
() => tracedResponse,
|
|
38228
|
+
() => tracedResponse.then(({ response }) => response),
|
|
38229
|
+
() => apiPromise
|
|
38230
|
+
);
|
|
38231
|
+
};
|
|
38232
|
+
}
|
|
38233
|
+
function openaiBatchesRetrieveTraced(batches) {
|
|
38234
|
+
return (batchId, options) => {
|
|
38235
|
+
const apiPromise = batches.retrieve(batchId, options);
|
|
38236
|
+
let enhancedResponse;
|
|
38237
|
+
const tracedResponse = openAIChannels.batchesRetrieveTraced.invoke(
|
|
38238
|
+
async () => {
|
|
38239
|
+
enhancedResponse = await apiPromise.withResponse();
|
|
38240
|
+
return enhancedResponse.data;
|
|
38241
|
+
},
|
|
38242
|
+
batches,
|
|
38243
|
+
[{ batchId }],
|
|
38244
|
+
{}
|
|
38245
|
+
).then((data) => {
|
|
38246
|
+
if (!enhancedResponse) {
|
|
38247
|
+
throw new Error(
|
|
38248
|
+
"Expected OpenAI withResponse() to provide a response"
|
|
38249
|
+
);
|
|
38250
|
+
}
|
|
38251
|
+
return { ...enhancedResponse, data };
|
|
38252
|
+
});
|
|
38253
|
+
return createLazyAPIPromise(
|
|
38254
|
+
() => tracedResponse,
|
|
38255
|
+
() => tracedResponse.then(({ response }) => response),
|
|
38256
|
+
() => apiPromise
|
|
38257
|
+
);
|
|
38258
|
+
};
|
|
38259
|
+
}
|
|
38260
|
+
async function completeOpenAIBatchTrace(args) {
|
|
38261
|
+
const inputFileContent = Promise.resolve(args.inputFileContent);
|
|
38262
|
+
const outputFileContent = args.outputFileContent === void 0 ? void 0 : Promise.resolve(args.outputFileContent);
|
|
38263
|
+
const errorFileContent = args.errorFileContent === void 0 ? void 0 : Promise.resolve(args.errorFileContent);
|
|
38264
|
+
void inputFileContent.catch(() => void 0);
|
|
38265
|
+
void outputFileContent?.catch(() => void 0);
|
|
38266
|
+
void errorFileContent?.catch(() => void 0);
|
|
38267
|
+
await openAIChannels.batchesCompleteTrace.invoke(
|
|
38268
|
+
async () => void 0,
|
|
38269
|
+
void 0,
|
|
38270
|
+
[
|
|
38271
|
+
{
|
|
38272
|
+
...args,
|
|
38273
|
+
inputFileContent,
|
|
38274
|
+
outputFileContent,
|
|
38275
|
+
errorFileContent
|
|
38276
|
+
}
|
|
38277
|
+
],
|
|
38278
|
+
{}
|
|
38279
|
+
);
|
|
38280
|
+
}
|
|
38281
|
+
|
|
37115
38282
|
// src/functions/invoke.ts
|
|
37116
38283
|
async function invoke(args) {
|
|
37117
38284
|
const {
|
|
@@ -37214,58 +38381,6 @@ function initFunction({
|
|
|
37214
38381
|
return f;
|
|
37215
38382
|
}
|
|
37216
38383
|
|
|
37217
|
-
// src/wrappers/openai-promise-utils.ts
|
|
37218
|
-
function splitSpanInfo(allParams) {
|
|
37219
|
-
const { span_info, ...params } = allParams;
|
|
37220
|
-
return {
|
|
37221
|
-
params,
|
|
37222
|
-
span_info
|
|
37223
|
-
};
|
|
37224
|
-
}
|
|
37225
|
-
function createChannelContext(_channel, params, span_info) {
|
|
37226
|
-
return {
|
|
37227
|
-
arguments: (
|
|
37228
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
37229
|
-
[params]
|
|
37230
|
-
),
|
|
37231
|
-
span_info
|
|
37232
|
-
};
|
|
37233
|
-
}
|
|
37234
|
-
async function tracePromiseWithResponse(channel2, traceContext, apiPromise) {
|
|
37235
|
-
let enhancedResponse;
|
|
37236
|
-
const tracePromise = (
|
|
37237
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
37238
|
-
channel2.tracePromise
|
|
37239
|
-
);
|
|
37240
|
-
const data = await tracePromise(async () => {
|
|
37241
|
-
enhancedResponse = await apiPromise.withResponse();
|
|
37242
|
-
traceContext.response = enhancedResponse.response;
|
|
37243
|
-
return enhancedResponse.data;
|
|
37244
|
-
}, traceContext);
|
|
37245
|
-
if (!enhancedResponse) {
|
|
37246
|
-
throw new Error("Expected withResponse() to provide response");
|
|
37247
|
-
}
|
|
37248
|
-
return { data, response: enhancedResponse.response };
|
|
37249
|
-
}
|
|
37250
|
-
function createLazyAPIPromise(ensureExecuted) {
|
|
37251
|
-
let dataPromise = null;
|
|
37252
|
-
return new Proxy({}, {
|
|
37253
|
-
get(target, prop, receiver) {
|
|
37254
|
-
if (prop === "withResponse") {
|
|
37255
|
-
return () => ensureExecuted();
|
|
37256
|
-
}
|
|
37257
|
-
if (prop === "then" || prop === "catch" || prop === "finally" || prop in Promise.prototype) {
|
|
37258
|
-
if (!dataPromise) {
|
|
37259
|
-
dataPromise = ensureExecuted().then((result) => result.data);
|
|
37260
|
-
}
|
|
37261
|
-
const value = Reflect.get(dataPromise, prop, receiver);
|
|
37262
|
-
return typeof value === "function" ? value.bind(dataPromise) : value;
|
|
37263
|
-
}
|
|
37264
|
-
return Reflect.get(target, prop, receiver);
|
|
37265
|
-
}
|
|
37266
|
-
});
|
|
37267
|
-
}
|
|
37268
|
-
|
|
37269
38384
|
// src/wrappers/oai_responses.ts
|
|
37270
38385
|
function responsesProxy(openai) {
|
|
37271
38386
|
if (!openai.responses) {
|
|
@@ -37302,17 +38417,33 @@ function wrapResponsesAsync(target, channel2) {
|
|
|
37302
38417
|
return (allParams, options) => {
|
|
37303
38418
|
const { span_info, params } = splitSpanInfo(allParams);
|
|
37304
38419
|
let executionPromise = null;
|
|
38420
|
+
let apiPromise = null;
|
|
38421
|
+
const getAPIPromise = () => {
|
|
38422
|
+
apiPromise ??= target(params, options);
|
|
38423
|
+
return apiPromise;
|
|
38424
|
+
};
|
|
37305
38425
|
const ensureExecuted = () => {
|
|
37306
38426
|
if (!executionPromise) {
|
|
37307
38427
|
executionPromise = (async () => {
|
|
37308
38428
|
const traceContext = createChannelContext(channel2, params, span_info);
|
|
37309
|
-
|
|
37310
|
-
|
|
38429
|
+
return tracePromiseWithResponse(
|
|
38430
|
+
channel2,
|
|
38431
|
+
traceContext,
|
|
38432
|
+
getAPIPromise()
|
|
38433
|
+
);
|
|
37311
38434
|
})();
|
|
37312
38435
|
}
|
|
37313
38436
|
return executionPromise;
|
|
37314
38437
|
};
|
|
37315
|
-
return createLazyAPIPromise(
|
|
38438
|
+
return createLazyAPIPromise(
|
|
38439
|
+
ensureExecuted,
|
|
38440
|
+
() => tracePromiseAsResponse(
|
|
38441
|
+
channel2,
|
|
38442
|
+
createChannelContext(channel2, params, span_info),
|
|
38443
|
+
getAPIPromise()
|
|
38444
|
+
),
|
|
38445
|
+
getAPIPromise
|
|
38446
|
+
);
|
|
37316
38447
|
};
|
|
37317
38448
|
}
|
|
37318
38449
|
function wrapResponsesSyncStream(target, channel2) {
|
|
@@ -37458,6 +38589,11 @@ function wrapChatCompletion(completion) {
|
|
|
37458
38589
|
allParams
|
|
37459
38590
|
);
|
|
37460
38591
|
let executionPromise = null;
|
|
38592
|
+
let apiPromise = null;
|
|
38593
|
+
const getAPIPromise = () => {
|
|
38594
|
+
apiPromise ??= completion(params, options);
|
|
38595
|
+
return apiPromise;
|
|
38596
|
+
};
|
|
37461
38597
|
const ensureExecuted = () => {
|
|
37462
38598
|
if (!executionPromise) {
|
|
37463
38599
|
executionPromise = (async () => {
|
|
@@ -37467,32 +38603,44 @@ function wrapChatCompletion(completion) {
|
|
|
37467
38603
|
span_info
|
|
37468
38604
|
);
|
|
37469
38605
|
if (params.stream) {
|
|
37470
|
-
const completionPromise =
|
|
37471
|
-
|
|
37472
|
-
|
|
38606
|
+
const completionPromise = (
|
|
38607
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38608
|
+
getAPIPromise()
|
|
37473
38609
|
);
|
|
37474
|
-
const { data: data2, response: response2 } = await tracePromiseWithResponse(
|
|
38610
|
+
const { data: data2, response: response2, request_id: request_id2 } = await tracePromiseWithResponse(
|
|
37475
38611
|
openAIChannels.chatCompletionsCreate,
|
|
37476
38612
|
traceContext,
|
|
37477
38613
|
completionPromise
|
|
37478
38614
|
);
|
|
37479
|
-
return { data: data2, response: response2 };
|
|
38615
|
+
return { data: data2, response: response2, request_id: request_id2 };
|
|
37480
38616
|
}
|
|
37481
|
-
const completionResponse =
|
|
37482
|
-
|
|
37483
|
-
|
|
38617
|
+
const completionResponse = (
|
|
38618
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38619
|
+
getAPIPromise()
|
|
37484
38620
|
);
|
|
37485
|
-
const { data, response } = await tracePromiseWithResponse(
|
|
38621
|
+
const { data, response, request_id } = await tracePromiseWithResponse(
|
|
37486
38622
|
openAIChannels.chatCompletionsCreate,
|
|
37487
38623
|
traceContext,
|
|
37488
38624
|
completionResponse
|
|
37489
38625
|
);
|
|
37490
|
-
return { data, response };
|
|
38626
|
+
return { data, response, request_id };
|
|
37491
38627
|
})();
|
|
37492
38628
|
}
|
|
37493
38629
|
return executionPromise;
|
|
37494
38630
|
};
|
|
37495
|
-
return createLazyAPIPromise(
|
|
38631
|
+
return createLazyAPIPromise(
|
|
38632
|
+
ensureExecuted,
|
|
38633
|
+
() => tracePromiseAsResponse(
|
|
38634
|
+
openAIChannels.chatCompletionsCreate,
|
|
38635
|
+
createChannelContext(
|
|
38636
|
+
openAIChannels.chatCompletionsCreate,
|
|
38637
|
+
params,
|
|
38638
|
+
span_info
|
|
38639
|
+
),
|
|
38640
|
+
getAPIPromise()
|
|
38641
|
+
),
|
|
38642
|
+
getAPIPromise
|
|
38643
|
+
);
|
|
37496
38644
|
};
|
|
37497
38645
|
}
|
|
37498
38646
|
function createEndpointProxy(target, wrapperFn) {
|
|
@@ -37510,6 +38658,11 @@ function wrapApiCreateWithChannel(create, channel2) {
|
|
|
37510
38658
|
return (allParams, options) => {
|
|
37511
38659
|
const { span_info, params } = splitSpanInfo(allParams);
|
|
37512
38660
|
let executionPromise = null;
|
|
38661
|
+
let apiPromise = null;
|
|
38662
|
+
const getAPIPromise = () => {
|
|
38663
|
+
apiPromise ??= create(params, options);
|
|
38664
|
+
return apiPromise;
|
|
38665
|
+
};
|
|
37513
38666
|
const ensureExecuted = () => {
|
|
37514
38667
|
if (!executionPromise) {
|
|
37515
38668
|
executionPromise = (async () => {
|
|
@@ -37517,13 +38670,21 @@ function wrapApiCreateWithChannel(create, channel2) {
|
|
|
37517
38670
|
return tracePromiseWithResponse(
|
|
37518
38671
|
channel2,
|
|
37519
38672
|
traceContext,
|
|
37520
|
-
|
|
38673
|
+
getAPIPromise()
|
|
37521
38674
|
);
|
|
37522
38675
|
})();
|
|
37523
38676
|
}
|
|
37524
38677
|
return executionPromise;
|
|
37525
38678
|
};
|
|
37526
|
-
return createLazyAPIPromise(
|
|
38679
|
+
return createLazyAPIPromise(
|
|
38680
|
+
ensureExecuted,
|
|
38681
|
+
() => tracePromiseAsResponse(
|
|
38682
|
+
channel2,
|
|
38683
|
+
createChannelContext(channel2, params, span_info),
|
|
38684
|
+
getAPIPromise()
|
|
38685
|
+
),
|
|
38686
|
+
getAPIPromise
|
|
38687
|
+
);
|
|
37527
38688
|
};
|
|
37528
38689
|
}
|
|
37529
38690
|
var wrapEmbeddings = (create) => wrapApiCreateWithChannel(create, openAIChannels.embeddingsCreate);
|
|
@@ -37559,6 +38720,13 @@ function wrapAISDK(aiSDK, options = {}) {
|
|
|
37559
38720
|
switch (prop) {
|
|
37560
38721
|
case "generateText":
|
|
37561
38722
|
return wrapGenerateText(typedAISDK.generateText, options, typedAISDK);
|
|
38723
|
+
case "generateImage":
|
|
38724
|
+
case "experimental_generateImage":
|
|
38725
|
+
return typeof original === "function" ? wrapGenerateImage(
|
|
38726
|
+
original,
|
|
38727
|
+
options,
|
|
38728
|
+
typedAISDK
|
|
38729
|
+
) : original;
|
|
37562
38730
|
case "streamText":
|
|
37563
38731
|
return wrapStreamText(typedAISDK.streamText, options, typedAISDK);
|
|
37564
38732
|
case "generateObject":
|
|
@@ -37795,6 +38963,32 @@ var wrapGenerateObject = (generateObject, options = {}, aiSDK) => {
|
|
|
37795
38963
|
options
|
|
37796
38964
|
);
|
|
37797
38965
|
};
|
|
38966
|
+
var wrapGenerateImage = (generateImage, options = {}, aiSDK) => {
|
|
38967
|
+
return makeGenerateImageWrapper(generateImage, { aiSDK }, options);
|
|
38968
|
+
};
|
|
38969
|
+
var makeGenerateImageWrapper = (generateImage, contextOptions = {}, options = {}) => {
|
|
38970
|
+
const wrapper = async function(allParams) {
|
|
38971
|
+
const { span_info, ...params } = allParams;
|
|
38972
|
+
const tracedParams = { ...params };
|
|
38973
|
+
return aiSDKChannels.generateImage.tracePromise(
|
|
38974
|
+
() => generateImage(tracedParams),
|
|
38975
|
+
createAISDKChannelContext(tracedParams, {
|
|
38976
|
+
aiSDK: contextOptions.aiSDK,
|
|
38977
|
+
denyOutputPaths: options.denyOutputPaths,
|
|
38978
|
+
self: contextOptions.self,
|
|
38979
|
+
span_info: mergeSpanInfo(span_info, {
|
|
38980
|
+
name: "generateImage",
|
|
38981
|
+
spanType: contextOptions.spanType
|
|
38982
|
+
})
|
|
38983
|
+
})
|
|
38984
|
+
);
|
|
38985
|
+
};
|
|
38986
|
+
Object.defineProperty(wrapper, "name", {
|
|
38987
|
+
value: "generateImage",
|
|
38988
|
+
writable: false
|
|
38989
|
+
});
|
|
38990
|
+
return wrapper;
|
|
38991
|
+
};
|
|
37798
38992
|
var makeEmbedWrapper = (channel2, name, embed, contextOptions = {}, options = {}) => {
|
|
37799
38993
|
const wrapper = async function(allParams) {
|
|
37800
38994
|
const { span_info, ...params } = allParams;
|
|
@@ -38545,7 +39739,7 @@ function braintrustEveHook(options) {
|
|
|
38545
39739
|
}
|
|
38546
39740
|
};
|
|
38547
39741
|
}
|
|
38548
|
-
function
|
|
39742
|
+
function createLegacyEveInstrumentation(options) {
|
|
38549
39743
|
const state = options.defineState(EVE_TRACE_STATE_KEY, emptyEveTraceState);
|
|
38550
39744
|
return {
|
|
38551
39745
|
events: {
|
|
@@ -39933,8 +41127,10 @@ function capturedModelInput(modelInput) {
|
|
|
39933
41127
|
const value = [];
|
|
39934
41128
|
if (typeof instructions === "string") {
|
|
39935
41129
|
value.push({ content: instructions, role: "system" });
|
|
39936
|
-
} else if (instructions) {
|
|
41130
|
+
} else if (Array.isArray(instructions)) {
|
|
39937
41131
|
value.push(...instructions.map(capturedEveModelMessage));
|
|
41132
|
+
} else if (instructions) {
|
|
41133
|
+
value.push(capturedEveModelMessage(instructions));
|
|
39938
41134
|
}
|
|
39939
41135
|
value.push(...messages.map(capturedEveModelMessage));
|
|
39940
41136
|
try {
|
|
@@ -40178,6 +41374,472 @@ async function deterministicEveId(...parts) {
|
|
|
40178
41374
|
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
40179
41375
|
}
|
|
40180
41376
|
|
|
41377
|
+
// src/instrumentation/plugins/eve-provider.ts
|
|
41378
|
+
var MAX_EVE_PROVIDER_CACHE_ENTRIES = 1e4;
|
|
41379
|
+
function createEveInstrumentationProvider(options = {}) {
|
|
41380
|
+
const bridge = new EveProviderBridge(options.metadata);
|
|
41381
|
+
return {
|
|
41382
|
+
// Eve versions before tracePolicy use capture to decide whether provider
|
|
41383
|
+
// events include content. Newer versions prefer tracePolicy when both are
|
|
41384
|
+
// present, so keep the deprecated field for backwards compatibility.
|
|
41385
|
+
capture: "content",
|
|
41386
|
+
tracePolicy: () => ({
|
|
41387
|
+
emit: true,
|
|
41388
|
+
recordInputs: true,
|
|
41389
|
+
recordOutputs: true
|
|
41390
|
+
}),
|
|
41391
|
+
events: {
|
|
41392
|
+
"action.completed": (event, context) => bridge.handleActionTerminal(event, context),
|
|
41393
|
+
"action.failed": (event, context) => bridge.handleActionTerminal(event, context),
|
|
41394
|
+
"action.started": (event, context) => bridge.handleActionStarted(event, context),
|
|
41395
|
+
"model.call.completed": (event, context) => bridge.handleModelTerminal(event, context),
|
|
41396
|
+
"model.call.failed": (event, context) => bridge.handleModelTerminal(event, context),
|
|
41397
|
+
"model.call.started": (event, context) => bridge.handleModelStarted(event, context),
|
|
41398
|
+
"step.attempt.completed": (event) => bridge.handleStepAttemptTerminal(event),
|
|
41399
|
+
"step.attempt.failed": (event) => bridge.handleStepAttemptTerminal(event),
|
|
41400
|
+
"turn.cancelled": (event, context) => bridge.handleTurnTerminal(event, context),
|
|
41401
|
+
"turn.completed": (event, context) => bridge.handleTurnTerminal(event, context),
|
|
41402
|
+
"turn.failed": (event, context) => bridge.handleTurnTerminal(event, context),
|
|
41403
|
+
"turn.started": (event, context) => bridge.handleTurnStarted(event, context)
|
|
41404
|
+
},
|
|
41405
|
+
flush,
|
|
41406
|
+
setup: options.setup
|
|
41407
|
+
};
|
|
41408
|
+
}
|
|
41409
|
+
var EveProviderBridge = class {
|
|
41410
|
+
constructor(metadata) {
|
|
41411
|
+
this.metadata = metadata;
|
|
41412
|
+
}
|
|
41413
|
+
metadata;
|
|
41414
|
+
activeActions = /* @__PURE__ */ new Map();
|
|
41415
|
+
activeModels = /* @__PURE__ */ new Map();
|
|
41416
|
+
modelsByAttempt = /* @__PURE__ */ new Map();
|
|
41417
|
+
settledOperations = new LRUCache({
|
|
41418
|
+
max: MAX_EVE_PROVIDER_CACHE_ENTRIES
|
|
41419
|
+
});
|
|
41420
|
+
turns = new LRUCache({
|
|
41421
|
+
max: MAX_EVE_PROVIDER_CACHE_ENTRIES
|
|
41422
|
+
});
|
|
41423
|
+
async handleTurnStarted(event, context) {
|
|
41424
|
+
await this.contain("turn start", async () => {
|
|
41425
|
+
if (this.settledOperations.has(event.idempotencyKey)) {
|
|
41426
|
+
context.state.set({ skip: true });
|
|
41427
|
+
return;
|
|
41428
|
+
}
|
|
41429
|
+
const { rowId, spanId } = await generateEveIds(
|
|
41430
|
+
"turn",
|
|
41431
|
+
event.idempotencyKey
|
|
41432
|
+
);
|
|
41433
|
+
const key = turnKey3(event.sessionId, event.turnId);
|
|
41434
|
+
const stored = storedSpan(context);
|
|
41435
|
+
if (stored && "exported" in stored && stored.rootSpanId) {
|
|
41436
|
+
this.turns.set(key, { rootSpanId: stored.rootSpanId, spanId });
|
|
41437
|
+
return;
|
|
41438
|
+
}
|
|
41439
|
+
let rootSpanId = spanId;
|
|
41440
|
+
let parentSpanId;
|
|
41441
|
+
if (event.parentLineage) {
|
|
41442
|
+
const parentTurnKey = turnKey3(
|
|
41443
|
+
event.parentLineage.sessionId,
|
|
41444
|
+
event.parentLineage.turnId
|
|
41445
|
+
);
|
|
41446
|
+
const parentTurn = this.turns.get(parentTurnKey);
|
|
41447
|
+
rootSpanId = parentTurn?.rootSpanId ?? // Eve propagates the root session through every nested subagent. Use
|
|
41448
|
+
// it instead of the immediate parent session when no ancestor ran
|
|
41449
|
+
// in-process.
|
|
41450
|
+
(await generateEveIds(
|
|
41451
|
+
"turn",
|
|
41452
|
+
turnIdempotencyKey(
|
|
41453
|
+
event.rootSessionId,
|
|
41454
|
+
event.parentLineage.turnId
|
|
41455
|
+
)
|
|
41456
|
+
)).spanId;
|
|
41457
|
+
parentSpanId = (await generateEveIds(
|
|
41458
|
+
"subagent",
|
|
41459
|
+
actionIdempotencyKey(
|
|
41460
|
+
event.parentLineage.sessionId,
|
|
41461
|
+
event.parentLineage.turnId,
|
|
41462
|
+
event.parentLineage.callId
|
|
41463
|
+
)
|
|
41464
|
+
)).spanId;
|
|
41465
|
+
}
|
|
41466
|
+
const metadata = this.spanMetadata(event.sessionId);
|
|
41467
|
+
const span = await this.startSpan(
|
|
41468
|
+
context,
|
|
41469
|
+
{
|
|
41470
|
+
event: { id: rowId, metadata },
|
|
41471
|
+
name: "eve.turn",
|
|
41472
|
+
parentSpanIds: parentSpanId ? { rootSpanId, spanId: parentSpanId } : { parentSpanIds: [], rootSpanId },
|
|
41473
|
+
spanAttributes: { type: "task" /* TASK */ },
|
|
41474
|
+
spanId
|
|
41475
|
+
},
|
|
41476
|
+
rootSpanId
|
|
41477
|
+
);
|
|
41478
|
+
span?.log({ metadata });
|
|
41479
|
+
this.turns.set(key, {
|
|
41480
|
+
rootSpanId,
|
|
41481
|
+
spanId
|
|
41482
|
+
});
|
|
41483
|
+
});
|
|
41484
|
+
}
|
|
41485
|
+
async handleTurnTerminal(event, context) {
|
|
41486
|
+
await this.contain("turn terminal", async () => {
|
|
41487
|
+
if (this.settledOperations.has(event.idempotencyKey)) {
|
|
41488
|
+
context.state.set(void 0);
|
|
41489
|
+
return;
|
|
41490
|
+
}
|
|
41491
|
+
const error = event.type === "turn.failed" ? event.error : void 0;
|
|
41492
|
+
this.drainActionsForTurn(event.sessionId, event.turnId, error);
|
|
41493
|
+
const stored = storedSpan(context);
|
|
41494
|
+
if (stored && "exported" in stored) {
|
|
41495
|
+
updateSpan({
|
|
41496
|
+
exported: stored.exported,
|
|
41497
|
+
...error !== void 0 ? { error } : {},
|
|
41498
|
+
metrics: { end: Date.now() / 1e3 }
|
|
41499
|
+
});
|
|
41500
|
+
}
|
|
41501
|
+
this.settledOperations.set(event.idempotencyKey, true);
|
|
41502
|
+
context.state.set(void 0);
|
|
41503
|
+
this.turns.delete(turnKey3(event.sessionId, event.turnId));
|
|
41504
|
+
});
|
|
41505
|
+
}
|
|
41506
|
+
async handleModelStarted(event, context) {
|
|
41507
|
+
await this.contain("model start", async () => {
|
|
41508
|
+
if (this.settledOperations.has(event.idempotencyKey)) {
|
|
41509
|
+
context.state.set({ skip: true });
|
|
41510
|
+
return;
|
|
41511
|
+
}
|
|
41512
|
+
const parent = await this.parentForScope(event.scope);
|
|
41513
|
+
const { rowId, spanId } = await generateEveIds(
|
|
41514
|
+
"step",
|
|
41515
|
+
event.idempotencyKey
|
|
41516
|
+
);
|
|
41517
|
+
const input = event.input ? capturedModelInput(event.input) : void 0;
|
|
41518
|
+
const metadata = {
|
|
41519
|
+
...this.spanMetadata(event.scope.sessionId),
|
|
41520
|
+
model: event.model.modelId,
|
|
41521
|
+
provider: event.model.provider
|
|
41522
|
+
};
|
|
41523
|
+
const span = await this.startSpan(context, {
|
|
41524
|
+
event: {
|
|
41525
|
+
id: rowId,
|
|
41526
|
+
...input !== void 0 ? { input } : {},
|
|
41527
|
+
metadata
|
|
41528
|
+
},
|
|
41529
|
+
name: "eve.step",
|
|
41530
|
+
parentSpanIds: parent,
|
|
41531
|
+
spanAttributes: { type: "llm" /* LLM */ },
|
|
41532
|
+
spanId
|
|
41533
|
+
});
|
|
41534
|
+
if (!span) return;
|
|
41535
|
+
span.log({ ...input !== void 0 ? { input } : {}, metadata });
|
|
41536
|
+
this.activeModels.set(event.idempotencyKey, {
|
|
41537
|
+
span,
|
|
41538
|
+
turnKey: turnKey3(event.scope.sessionId, event.scope.turnId)
|
|
41539
|
+
});
|
|
41540
|
+
const keys = this.modelsByAttempt.get(event.scope.attemptId) ?? /* @__PURE__ */ new Set();
|
|
41541
|
+
keys.add(event.idempotencyKey);
|
|
41542
|
+
this.modelsByAttempt.set(event.scope.attemptId, keys);
|
|
41543
|
+
});
|
|
41544
|
+
}
|
|
41545
|
+
async handleModelTerminal(event, context) {
|
|
41546
|
+
await this.contain("model terminal", async () => {
|
|
41547
|
+
if (this.settledOperations.has(event.idempotencyKey)) {
|
|
41548
|
+
context.state.set(void 0);
|
|
41549
|
+
return;
|
|
41550
|
+
}
|
|
41551
|
+
const active = this.activeModels.get(event.idempotencyKey);
|
|
41552
|
+
if (active) {
|
|
41553
|
+
const span = active.span;
|
|
41554
|
+
if (event.type === "model.call.failed") {
|
|
41555
|
+
if (event.error !== void 0) span.log({ error: event.error });
|
|
41556
|
+
} else {
|
|
41557
|
+
span.log({
|
|
41558
|
+
metrics: usageMetrics(event.usage),
|
|
41559
|
+
output: modelOutput(event)
|
|
41560
|
+
});
|
|
41561
|
+
}
|
|
41562
|
+
span.end();
|
|
41563
|
+
} else {
|
|
41564
|
+
const stored = storedSpan(context);
|
|
41565
|
+
if (stored && "exported" in stored) {
|
|
41566
|
+
updateSpan({
|
|
41567
|
+
exported: stored.exported,
|
|
41568
|
+
...event.type === "model.call.failed" ? event.error !== void 0 ? { error: event.error } : {} : { output: modelOutput(event) },
|
|
41569
|
+
metrics: {
|
|
41570
|
+
...event.type === "model.call.completed" ? usageMetrics(event.usage) : {},
|
|
41571
|
+
end: Date.now() / 1e3
|
|
41572
|
+
}
|
|
41573
|
+
});
|
|
41574
|
+
}
|
|
41575
|
+
}
|
|
41576
|
+
this.settledOperations.set(event.idempotencyKey, true);
|
|
41577
|
+
this.forgetModel(event.scope.attemptId, event.idempotencyKey);
|
|
41578
|
+
context.state.set(void 0);
|
|
41579
|
+
});
|
|
41580
|
+
}
|
|
41581
|
+
async handleActionStarted(event, context) {
|
|
41582
|
+
await this.contain("action start", async () => {
|
|
41583
|
+
if (event.kind === "load-skill" || this.settledOperations.has(event.idempotencyKey)) {
|
|
41584
|
+
context.state.set({ skip: true });
|
|
41585
|
+
return;
|
|
41586
|
+
}
|
|
41587
|
+
const parent = await this.parentForScope(event.scope);
|
|
41588
|
+
const { rowId, spanId } = await generateEveIds(
|
|
41589
|
+
event.kind === "subagent-call" ? "subagent" : "tool",
|
|
41590
|
+
event.idempotencyKey
|
|
41591
|
+
);
|
|
41592
|
+
const metadata = {
|
|
41593
|
+
...this.spanMetadata(event.scope.sessionId),
|
|
41594
|
+
"eve.action_kind": event.kind
|
|
41595
|
+
};
|
|
41596
|
+
const span = await this.startSpan(context, {
|
|
41597
|
+
event: {
|
|
41598
|
+
id: rowId,
|
|
41599
|
+
...event.input !== void 0 ? { input: event.input } : {},
|
|
41600
|
+
metadata
|
|
41601
|
+
},
|
|
41602
|
+
name: event.name,
|
|
41603
|
+
parentSpanIds: parent,
|
|
41604
|
+
spanAttributes: { type: "tool" /* TOOL */ },
|
|
41605
|
+
spanId
|
|
41606
|
+
});
|
|
41607
|
+
if (!span) return;
|
|
41608
|
+
span.log({
|
|
41609
|
+
...event.input !== void 0 ? { input: event.input } : {},
|
|
41610
|
+
metadata
|
|
41611
|
+
});
|
|
41612
|
+
this.activeActions.set(event.idempotencyKey, {
|
|
41613
|
+
span,
|
|
41614
|
+
turnKey: turnKey3(event.scope.sessionId, event.scope.turnId)
|
|
41615
|
+
});
|
|
41616
|
+
});
|
|
41617
|
+
}
|
|
41618
|
+
async handleActionTerminal(event, context) {
|
|
41619
|
+
await this.contain("action terminal", async () => {
|
|
41620
|
+
if (this.settledOperations.has(event.idempotencyKey)) {
|
|
41621
|
+
context.state.set(void 0);
|
|
41622
|
+
return;
|
|
41623
|
+
}
|
|
41624
|
+
const stored = storedSpan(context);
|
|
41625
|
+
if (stored?.skip) {
|
|
41626
|
+
context.state.set(void 0);
|
|
41627
|
+
return;
|
|
41628
|
+
}
|
|
41629
|
+
const active = this.activeActions.get(event.idempotencyKey);
|
|
41630
|
+
const end = finiteTimestamp(event.acceptedAtMs) ?? Date.now();
|
|
41631
|
+
if (active) {
|
|
41632
|
+
const span = active.span;
|
|
41633
|
+
if (event.type === "action.failed") {
|
|
41634
|
+
span.log({
|
|
41635
|
+
error: event.error ?? new Error(event.errorCode ?? `Eve action ${event.outcome}`)
|
|
41636
|
+
});
|
|
41637
|
+
} else if (event.output.type === "error") {
|
|
41638
|
+
span.log({
|
|
41639
|
+
error: event.output.error ?? new Error("Eve action returned an error")
|
|
41640
|
+
});
|
|
41641
|
+
} else {
|
|
41642
|
+
span.log({ output: event.output.output });
|
|
41643
|
+
}
|
|
41644
|
+
span.end({ endTime: end / 1e3 });
|
|
41645
|
+
} else {
|
|
41646
|
+
const stored2 = storedSpan(context);
|
|
41647
|
+
if (stored2 && "exported" in stored2) {
|
|
41648
|
+
updateSpan({
|
|
41649
|
+
exported: stored2.exported,
|
|
41650
|
+
...event.type === "action.failed" ? {
|
|
41651
|
+
error: event.error ?? new Error(event.errorCode ?? `Eve action ${event.outcome}`)
|
|
41652
|
+
} : event.output.type === "error" ? {
|
|
41653
|
+
error: event.output.error ?? new Error("Eve action returned an error")
|
|
41654
|
+
} : { output: event.output.output },
|
|
41655
|
+
metrics: { end: end / 1e3 }
|
|
41656
|
+
});
|
|
41657
|
+
}
|
|
41658
|
+
}
|
|
41659
|
+
this.settledOperations.set(event.idempotencyKey, true);
|
|
41660
|
+
this.activeActions.delete(event.idempotencyKey);
|
|
41661
|
+
context.state.set(void 0);
|
|
41662
|
+
});
|
|
41663
|
+
}
|
|
41664
|
+
handleStepAttemptTerminal(event) {
|
|
41665
|
+
void this.contain("step attempt terminal", () => {
|
|
41666
|
+
const keys = this.modelsByAttempt.get(event.scope.attemptId);
|
|
41667
|
+
if (!keys) return;
|
|
41668
|
+
for (const key of keys) {
|
|
41669
|
+
const active = this.activeModels.get(key);
|
|
41670
|
+
if (!active) continue;
|
|
41671
|
+
if (event.type === "step.attempt.failed" && event.error !== void 0) {
|
|
41672
|
+
active.span.log({ error: event.error });
|
|
41673
|
+
}
|
|
41674
|
+
active.span.end();
|
|
41675
|
+
this.activeModels.delete(key);
|
|
41676
|
+
}
|
|
41677
|
+
this.modelsByAttempt.delete(event.scope.attemptId);
|
|
41678
|
+
});
|
|
41679
|
+
}
|
|
41680
|
+
async parentForScope(scope) {
|
|
41681
|
+
const key = turnKey3(scope.sessionId, scope.turnId);
|
|
41682
|
+
const known = this.turns.get(key);
|
|
41683
|
+
if (known) {
|
|
41684
|
+
return { rootSpanId: known.rootSpanId, spanId: known.spanId };
|
|
41685
|
+
}
|
|
41686
|
+
const [{ spanId }, { spanId: rootSpanId }] = await Promise.all([
|
|
41687
|
+
generateEveIds("turn", turnIdempotencyKey(scope.sessionId, scope.turnId)),
|
|
41688
|
+
generateEveIds(
|
|
41689
|
+
"turn",
|
|
41690
|
+
turnIdempotencyKey(
|
|
41691
|
+
scope.rootSessionId ?? scope.sessionId,
|
|
41692
|
+
scope.turnId
|
|
41693
|
+
)
|
|
41694
|
+
)
|
|
41695
|
+
]);
|
|
41696
|
+
return { rootSpanId, spanId };
|
|
41697
|
+
}
|
|
41698
|
+
async startSpan(context, args, rootSpanId) {
|
|
41699
|
+
const span = withCurrent(
|
|
41700
|
+
NOOP_SPAN,
|
|
41701
|
+
() => _internalStartSpanWithInitialMerge(
|
|
41702
|
+
withSpanInstrumentationName(args ?? {}, INSTRUMENTATION_NAMES.EVE)
|
|
41703
|
+
)
|
|
41704
|
+
);
|
|
41705
|
+
try {
|
|
41706
|
+
context.state.set({
|
|
41707
|
+
exported: await span.export(),
|
|
41708
|
+
...rootSpanId ? { rootSpanId } : {}
|
|
41709
|
+
});
|
|
41710
|
+
} catch (error) {
|
|
41711
|
+
debugLogger.warn("Error exporting Eve provider span:", error);
|
|
41712
|
+
}
|
|
41713
|
+
return span;
|
|
41714
|
+
}
|
|
41715
|
+
drainActionsForTurn(sessionId, turnId, error) {
|
|
41716
|
+
const key = turnKey3(sessionId, turnId);
|
|
41717
|
+
for (const [idempotencyKey, active] of this.activeActions) {
|
|
41718
|
+
if (active.turnKey !== key) continue;
|
|
41719
|
+
if (error !== void 0) active.span.log({ error });
|
|
41720
|
+
active.span.end();
|
|
41721
|
+
this.activeActions.delete(idempotencyKey);
|
|
41722
|
+
}
|
|
41723
|
+
}
|
|
41724
|
+
forgetModel(attemptId, idempotencyKey) {
|
|
41725
|
+
this.activeModels.delete(idempotencyKey);
|
|
41726
|
+
const keys = this.modelsByAttempt.get(attemptId);
|
|
41727
|
+
keys?.delete(idempotencyKey);
|
|
41728
|
+
if (keys?.size === 0) this.modelsByAttempt.delete(attemptId);
|
|
41729
|
+
}
|
|
41730
|
+
spanMetadata(sessionId) {
|
|
41731
|
+
return {
|
|
41732
|
+
...this.metadata ?? {},
|
|
41733
|
+
"eve.session_id": sessionId
|
|
41734
|
+
};
|
|
41735
|
+
}
|
|
41736
|
+
async contain(operation, fn) {
|
|
41737
|
+
try {
|
|
41738
|
+
await fn();
|
|
41739
|
+
} catch (error) {
|
|
41740
|
+
debugLogger.warn(`Error in Eve provider ${operation}:`, error);
|
|
41741
|
+
}
|
|
41742
|
+
}
|
|
41743
|
+
};
|
|
41744
|
+
function storedSpan(context) {
|
|
41745
|
+
const value = context.state.get();
|
|
41746
|
+
if (!isObject(value)) return void 0;
|
|
41747
|
+
if (value["skip"] === true) return { skip: true };
|
|
41748
|
+
return typeof value["exported"] === "string" ? {
|
|
41749
|
+
exported: value["exported"],
|
|
41750
|
+
...typeof value["rootSpanId"] === "string" && value["rootSpanId"].length > 0 ? { rootSpanId: value["rootSpanId"] } : {}
|
|
41751
|
+
} : void 0;
|
|
41752
|
+
}
|
|
41753
|
+
function modelOutput(event) {
|
|
41754
|
+
const content = event.content ?? [];
|
|
41755
|
+
let text = "";
|
|
41756
|
+
const reasoning = [];
|
|
41757
|
+
const toolCalls2 = [];
|
|
41758
|
+
for (const part of content) {
|
|
41759
|
+
if (part.type === "text") {
|
|
41760
|
+
text += part.text;
|
|
41761
|
+
} else if (part.type === "reasoning" && part.text.trim().length > 0) {
|
|
41762
|
+
reasoning.push({ content: part.text });
|
|
41763
|
+
} else if (part.type === "tool-call") {
|
|
41764
|
+
toolCalls2.push({
|
|
41765
|
+
function: {
|
|
41766
|
+
arguments: safeJsonStringify(part.input),
|
|
41767
|
+
name: part.toolName
|
|
41768
|
+
},
|
|
41769
|
+
id: part.callId,
|
|
41770
|
+
type: "function"
|
|
41771
|
+
});
|
|
41772
|
+
}
|
|
41773
|
+
}
|
|
41774
|
+
return [
|
|
41775
|
+
{
|
|
41776
|
+
finish_reason: normalizeFinishReason3(event.finishReason),
|
|
41777
|
+
index: 0,
|
|
41778
|
+
message: {
|
|
41779
|
+
content: text || null,
|
|
41780
|
+
...reasoning.length > 0 ? { reasoning } : {},
|
|
41781
|
+
role: "assistant",
|
|
41782
|
+
...toolCalls2.length > 0 ? { tool_calls: toolCalls2 } : {}
|
|
41783
|
+
}
|
|
41784
|
+
}
|
|
41785
|
+
];
|
|
41786
|
+
}
|
|
41787
|
+
function usageMetrics(usage) {
|
|
41788
|
+
const promptTokens = nonNegativeNumber(usage.inputTokens);
|
|
41789
|
+
const completionTokens = nonNegativeNumber(usage.outputTokens);
|
|
41790
|
+
const cachedTokens = nonNegativeNumber(
|
|
41791
|
+
usage.inputTokenDetails?.cacheReadTokens
|
|
41792
|
+
);
|
|
41793
|
+
const cacheCreationTokens = nonNegativeNumber(
|
|
41794
|
+
usage.inputTokenDetails?.cacheWriteTokens
|
|
41795
|
+
);
|
|
41796
|
+
return {
|
|
41797
|
+
...promptTokens !== void 0 ? { prompt_tokens: promptTokens } : {},
|
|
41798
|
+
...completionTokens !== void 0 ? { completion_tokens: completionTokens } : {},
|
|
41799
|
+
...promptTokens !== void 0 && completionTokens !== void 0 ? { tokens: promptTokens + completionTokens } : {},
|
|
41800
|
+
...cachedTokens !== void 0 ? { prompt_cached_tokens: cachedTokens } : {},
|
|
41801
|
+
...cacheCreationTokens !== void 0 ? { prompt_cache_creation_tokens: cacheCreationTokens } : {}
|
|
41802
|
+
};
|
|
41803
|
+
}
|
|
41804
|
+
function nonNegativeNumber(value) {
|
|
41805
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : void 0;
|
|
41806
|
+
}
|
|
41807
|
+
function finiteTimestamp(value) {
|
|
41808
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
41809
|
+
}
|
|
41810
|
+
function normalizeFinishReason3(value) {
|
|
41811
|
+
if (value === "content-filter") return "content_filter";
|
|
41812
|
+
if (value === "tool-calls") return "tool_calls";
|
|
41813
|
+
return value;
|
|
41814
|
+
}
|
|
41815
|
+
function safeJsonStringify(value) {
|
|
41816
|
+
try {
|
|
41817
|
+
return JSON.stringify(value) ?? "null";
|
|
41818
|
+
} catch {
|
|
41819
|
+
return "null";
|
|
41820
|
+
}
|
|
41821
|
+
}
|
|
41822
|
+
function turnKey3(sessionId, turnId) {
|
|
41823
|
+
return `${sessionId}:${turnId}`;
|
|
41824
|
+
}
|
|
41825
|
+
function turnIdempotencyKey(sessionId, turnId) {
|
|
41826
|
+
return `turn:${sessionId}:${turnId}`;
|
|
41827
|
+
}
|
|
41828
|
+
function actionIdempotencyKey(sessionId, turnId, callId) {
|
|
41829
|
+
return `action:${sessionId}:${turnId}:${callId}`;
|
|
41830
|
+
}
|
|
41831
|
+
|
|
41832
|
+
// src/instrumentation/plugins/eve-instrumentation.ts
|
|
41833
|
+
var EVE_INSTRUMENTATION_PROVIDER = /* @__PURE__ */ Symbol.for("eve.instrumentation.provider");
|
|
41834
|
+
function braintrustEveInstrumentation(options) {
|
|
41835
|
+
const definition = "defineState" in options ? createLegacyEveInstrumentation(options) : createEveInstrumentationProvider(options);
|
|
41836
|
+
const declaration = {
|
|
41837
|
+
...definition,
|
|
41838
|
+
[EVE_INSTRUMENTATION_PROVIDER]: true
|
|
41839
|
+
};
|
|
41840
|
+
return declaration;
|
|
41841
|
+
}
|
|
41842
|
+
|
|
40181
41843
|
// src/typed-instrumentation-helpers.ts
|
|
40182
41844
|
var TypedApplyProxy = Proxy;
|
|
40183
41845
|
|
|
@@ -40579,11 +42241,11 @@ function wrapClaudeAgentQuery(queryFn, defaultThis) {
|
|
|
40579
42241
|
}
|
|
40580
42242
|
};
|
|
40581
42243
|
const invocationTarget = thisArg === proxy || thisArg === void 0 ? defaultThis ?? thisArg : thisArg;
|
|
40582
|
-
return claudeAgentSDKChannels.query.
|
|
40583
|
-
|
|
40584
|
-
|
|
40585
|
-
|
|
40586
|
-
{
|
|
42244
|
+
return claudeAgentSDKChannels.query.invoke(
|
|
42245
|
+
target,
|
|
42246
|
+
invocationTarget,
|
|
42247
|
+
[wrappedParams],
|
|
42248
|
+
{}
|
|
40587
42249
|
);
|
|
40588
42250
|
}
|
|
40589
42251
|
});
|
|
@@ -41198,13 +42860,11 @@ function wrapAgentInstance(agent) {
|
|
|
41198
42860
|
if (prop === "stream" && typeof value === "function") {
|
|
41199
42861
|
return function(args, options) {
|
|
41200
42862
|
const callArgs = [args, options];
|
|
41201
|
-
return strandsAgentSDKChannels.agentStream.
|
|
41202
|
-
|
|
41203
|
-
|
|
41204
|
-
|
|
41205
|
-
|
|
41206
|
-
self: proxy
|
|
41207
|
-
}
|
|
42863
|
+
return strandsAgentSDKChannels.agentStream.invoke(
|
|
42864
|
+
value,
|
|
42865
|
+
target,
|
|
42866
|
+
callArgs,
|
|
42867
|
+
{ agent: proxy }
|
|
41208
42868
|
);
|
|
41209
42869
|
};
|
|
41210
42870
|
}
|
|
@@ -41235,12 +42895,12 @@ function wrapMultiAgentInstance(orchestrator, kind) {
|
|
|
41235
42895
|
return function(input, options) {
|
|
41236
42896
|
const callArgs = [input, options];
|
|
41237
42897
|
const channel2 = kind === "graph" ? strandsAgentSDKChannels.graphStream : strandsAgentSDKChannels.swarmStream;
|
|
41238
|
-
return channel2.
|
|
41239
|
-
|
|
42898
|
+
return channel2.invoke(
|
|
42899
|
+
value,
|
|
42900
|
+
target,
|
|
42901
|
+
callArgs,
|
|
41240
42902
|
{
|
|
41241
|
-
|
|
41242
|
-
orchestrator: proxy,
|
|
41243
|
-
self: proxy
|
|
42903
|
+
orchestrator: proxy
|
|
41244
42904
|
}
|
|
41245
42905
|
);
|
|
41246
42906
|
};
|
|
@@ -43192,9 +44852,6 @@ var VitestContextManager = class {
|
|
|
43192
44852
|
getCurrentContext() {
|
|
43193
44853
|
return this.contextStorage.getStore();
|
|
43194
44854
|
}
|
|
43195
|
-
setContext(context) {
|
|
43196
|
-
this.contextStorage.enterWith(context);
|
|
43197
|
-
}
|
|
43198
44855
|
runInContext(context, callback) {
|
|
43199
44856
|
return this.contextStorage.run(context, callback);
|
|
43200
44857
|
}
|
|
@@ -43580,8 +45237,7 @@ function wrapDescribe(originalDescribe, config, afterAll) {
|
|
|
43580
45237
|
if (config.onProgress) {
|
|
43581
45238
|
config.onProgress({ type: "suite_start", suiteName });
|
|
43582
45239
|
}
|
|
43583
|
-
contextManager.
|
|
43584
|
-
factory();
|
|
45240
|
+
contextManager.runInContext(lazyContext, factory);
|
|
43585
45241
|
if (afterAll) {
|
|
43586
45242
|
afterAll(async () => {
|
|
43587
45243
|
await flushExperimentWithSync(context, config);
|
|
@@ -48770,6 +50426,7 @@ export {
|
|
|
48770
50426
|
braintrustStreamChunkSchema,
|
|
48771
50427
|
buildLocalSummary,
|
|
48772
50428
|
collectAnthropicSession,
|
|
50429
|
+
completeOpenAIBatchTrace,
|
|
48773
50430
|
configureInstrumentation,
|
|
48774
50431
|
constructLogs3OverflowRequest,
|
|
48775
50432
|
createFinalValuePassThroughStream,
|
|
@@ -48809,6 +50466,8 @@ export {
|
|
|
48809
50466
|
loginToState,
|
|
48810
50467
|
logs3OverflowUploadSchema,
|
|
48811
50468
|
newId,
|
|
50469
|
+
openaiBatchesRetrieveTraced,
|
|
50470
|
+
openaiFilesCreateTraced,
|
|
48812
50471
|
parseCachedHeader,
|
|
48813
50472
|
parseTemplateFormat,
|
|
48814
50473
|
permalink,
|