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.js
CHANGED
|
@@ -104,6 +104,7 @@ __export(edge_light_exports, {
|
|
|
104
104
|
braintrustStreamChunkSchema: () => braintrustStreamChunkSchema,
|
|
105
105
|
buildLocalSummary: () => buildLocalSummary,
|
|
106
106
|
collectAnthropicSession: () => collectAnthropicSession,
|
|
107
|
+
completeOpenAIBatchTrace: () => completeOpenAIBatchTrace,
|
|
107
108
|
configureInstrumentation: () => configureInstrumentation,
|
|
108
109
|
constructLogs3OverflowRequest: () => constructLogs3OverflowRequest,
|
|
109
110
|
createFinalValuePassThroughStream: () => createFinalValuePassThroughStream,
|
|
@@ -143,6 +144,8 @@ __export(edge_light_exports, {
|
|
|
143
144
|
loginToState: () => loginToState,
|
|
144
145
|
logs3OverflowUploadSchema: () => logs3OverflowUploadSchema,
|
|
145
146
|
newId: () => newId,
|
|
147
|
+
openaiBatchesRetrieveTraced: () => openaiBatchesRetrieveTraced,
|
|
148
|
+
openaiFilesCreateTraced: () => openaiFilesCreateTraced,
|
|
146
149
|
parseCachedHeader: () => parseCachedHeader,
|
|
147
150
|
parseTemplateFormat: () => parseTemplateFormat,
|
|
148
151
|
permalink: () => permalink,
|
|
@@ -869,8 +872,6 @@ function newGlobalTracingChannel(nameOrChannels) {
|
|
|
869
872
|
var DefaultAsyncLocalStorage = class {
|
|
870
873
|
constructor() {
|
|
871
874
|
}
|
|
872
|
-
enterWith(_) {
|
|
873
|
-
}
|
|
874
875
|
run(_, callback) {
|
|
875
876
|
return callback();
|
|
876
877
|
}
|
|
@@ -2687,7 +2688,9 @@ var AclObjectType = import_v36.z.union([
|
|
|
2687
2688
|
"project_log",
|
|
2688
2689
|
"org_project",
|
|
2689
2690
|
"org_audit_logs",
|
|
2690
|
-
"project_group"
|
|
2691
|
+
"project_group",
|
|
2692
|
+
"ai_secret",
|
|
2693
|
+
"org_ai_secret"
|
|
2691
2694
|
]),
|
|
2692
2695
|
import_v36.z.null()
|
|
2693
2696
|
]);
|
|
@@ -3520,7 +3523,7 @@ var PromptParserNullish = import_v36.z.union([
|
|
|
3520
3523
|
}),
|
|
3521
3524
|
import_v36.z.null()
|
|
3522
3525
|
]);
|
|
3523
|
-
var
|
|
3526
|
+
var PreprocessorId = import_v36.z.union([
|
|
3524
3527
|
import_v36.z.object({
|
|
3525
3528
|
type: import_v36.z.literal("function"),
|
|
3526
3529
|
id: import_v36.z.string(),
|
|
@@ -3531,6 +3534,7 @@ var PreprocessorSavedFunctionId = import_v36.z.union([
|
|
|
3531
3534
|
name: import_v36.z.string(),
|
|
3532
3535
|
function_type: import_v36.z.literal("preprocessor").optional().default("preprocessor")
|
|
3533
3536
|
}),
|
|
3537
|
+
import_v36.z.object({ type: import_v36.z.literal("inline"), code: import_v36.z.string().min(1) }),
|
|
3534
3538
|
import_v36.z.null()
|
|
3535
3539
|
]);
|
|
3536
3540
|
var PromptDataNullish = import_v36.z.union([
|
|
@@ -3538,7 +3542,7 @@ var PromptDataNullish = import_v36.z.union([
|
|
|
3538
3542
|
prompt: PromptBlockDataNullish,
|
|
3539
3543
|
options: PromptOptionsNullish,
|
|
3540
3544
|
parser: PromptParserNullish,
|
|
3541
|
-
preprocessor:
|
|
3545
|
+
preprocessor: PreprocessorId,
|
|
3542
3546
|
tool_functions: import_v36.z.union([import_v36.z.array(SavedFunctionId), import_v36.z.null()]),
|
|
3543
3547
|
template_format: import_v36.z.union([
|
|
3544
3548
|
import_v36.z.enum(["mustache", "nunjucks", "none"]),
|
|
@@ -3740,7 +3744,7 @@ var PromptData = import_v36.z.object({
|
|
|
3740
3744
|
prompt: PromptBlockDataNullish,
|
|
3741
3745
|
options: PromptOptionsNullish,
|
|
3742
3746
|
parser: PromptParserNullish,
|
|
3743
|
-
preprocessor:
|
|
3747
|
+
preprocessor: PreprocessorId,
|
|
3744
3748
|
tool_functions: import_v36.z.union([import_v36.z.array(SavedFunctionId), import_v36.z.null()]),
|
|
3745
3749
|
template_format: import_v36.z.union([
|
|
3746
3750
|
import_v36.z.enum(["mustache", "nunjucks", "none"]),
|
|
@@ -4684,6 +4688,7 @@ var View = import_v36.z.object({
|
|
|
4684
4688
|
]),
|
|
4685
4689
|
name: import_v36.z.string(),
|
|
4686
4690
|
description: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
|
|
4691
|
+
starred: import_v36.z.boolean().optional(),
|
|
4687
4692
|
created: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
|
|
4688
4693
|
updated_at: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
|
|
4689
4694
|
view_data: ViewData.optional(),
|
|
@@ -5385,44 +5390,72 @@ function createCacheLayers({
|
|
|
5385
5390
|
}
|
|
5386
5391
|
|
|
5387
5392
|
// src/prompt-cache/prompt-cache.ts
|
|
5388
|
-
function createCacheKey(key) {
|
|
5393
|
+
function createCacheKey(key, namespace) {
|
|
5394
|
+
let cacheKey;
|
|
5389
5395
|
if (key.id) {
|
|
5390
|
-
|
|
5391
|
-
}
|
|
5392
|
-
|
|
5393
|
-
|
|
5394
|
-
|
|
5395
|
-
|
|
5396
|
-
|
|
5397
|
-
|
|
5396
|
+
cacheKey = `id:${key.id}`;
|
|
5397
|
+
} else {
|
|
5398
|
+
const prefix = key.projectId ?? key.projectName;
|
|
5399
|
+
if (!prefix) {
|
|
5400
|
+
throw new Error("Either projectId or projectName must be provided");
|
|
5401
|
+
}
|
|
5402
|
+
if (!key.slug) {
|
|
5403
|
+
throw new Error("Slug must be provided when not using ID");
|
|
5404
|
+
}
|
|
5405
|
+
cacheKey = `${prefix}:${key.slug}:${key.version ?? "latest"}`;
|
|
5398
5406
|
}
|
|
5399
|
-
return `${
|
|
5407
|
+
return namespace === void 0 ? cacheKey : `${namespace.length}:${namespace}:${cacheKey}`;
|
|
5400
5408
|
}
|
|
5401
|
-
var PromptCache = class {
|
|
5409
|
+
var PromptCache = class _PromptCache {
|
|
5402
5410
|
memoryCache;
|
|
5403
5411
|
diskCache;
|
|
5412
|
+
namespace;
|
|
5413
|
+
expectedResolvedOrgIdentity;
|
|
5404
5414
|
constructor(options) {
|
|
5405
5415
|
this.memoryCache = options.memoryCache;
|
|
5406
5416
|
this.diskCache = options.diskCache;
|
|
5417
|
+
this.namespace = options.namespace;
|
|
5418
|
+
this.expectedResolvedOrgIdentity = options.expectedResolvedOrgIdentity;
|
|
5419
|
+
}
|
|
5420
|
+
/**
|
|
5421
|
+
* Returns a cache view that shares the same storage layers but isolates all
|
|
5422
|
+
* entries under the provided namespace.
|
|
5423
|
+
*/
|
|
5424
|
+
withNamespace(namespace, expectedResolvedOrgIdentity) {
|
|
5425
|
+
return new _PromptCache({
|
|
5426
|
+
memoryCache: this.memoryCache,
|
|
5427
|
+
diskCache: this.diskCache,
|
|
5428
|
+
namespace,
|
|
5429
|
+
expectedResolvedOrgIdentity
|
|
5430
|
+
});
|
|
5407
5431
|
}
|
|
5408
5432
|
/**
|
|
5409
5433
|
* Retrieves a prompt from the cache.
|
|
5410
5434
|
* First checks the in-memory LRU cache, then falls back to checking the disk cache if available.
|
|
5411
5435
|
*/
|
|
5412
5436
|
async get(key) {
|
|
5413
|
-
const cacheKey = createCacheKey(key);
|
|
5437
|
+
const cacheKey = createCacheKey(key, this.namespace);
|
|
5414
5438
|
if (this.memoryCache) {
|
|
5415
|
-
const
|
|
5416
|
-
if (
|
|
5417
|
-
return
|
|
5439
|
+
const memoryEntry = this.memoryCache.get(cacheKey);
|
|
5440
|
+
if (memoryEntry !== void 0 && (this.expectedResolvedOrgIdentity === void 0 || memoryEntry.resolvedOrgIdentity === this.expectedResolvedOrgIdentity)) {
|
|
5441
|
+
return memoryEntry.value;
|
|
5418
5442
|
}
|
|
5419
5443
|
}
|
|
5420
5444
|
if (this.diskCache) {
|
|
5421
|
-
const
|
|
5422
|
-
if (!
|
|
5445
|
+
const diskEntry = await this.diskCache.get(cacheKey);
|
|
5446
|
+
if (!diskEntry || this.expectedResolvedOrgIdentity !== void 0 && diskEntry.resolvedOrgIdentity !== this.expectedResolvedOrgIdentity) {
|
|
5423
5447
|
return void 0;
|
|
5424
5448
|
}
|
|
5425
|
-
|
|
5449
|
+
const serializedPrompt = diskEntry.value;
|
|
5450
|
+
const diskPrompt = new Prompt2(
|
|
5451
|
+
serializedPrompt.metadata,
|
|
5452
|
+
serializedPrompt.defaults,
|
|
5453
|
+
serializedPrompt.noTrace
|
|
5454
|
+
);
|
|
5455
|
+
this.memoryCache?.set(cacheKey, {
|
|
5456
|
+
value: diskPrompt,
|
|
5457
|
+
resolvedOrgIdentity: diskEntry.resolvedOrgIdentity
|
|
5458
|
+
});
|
|
5426
5459
|
return diskPrompt;
|
|
5427
5460
|
}
|
|
5428
5461
|
return void 0;
|
|
@@ -5436,58 +5469,91 @@ var PromptCache = class {
|
|
|
5436
5469
|
* @throws If there is an error writing to the disk cache.
|
|
5437
5470
|
*/
|
|
5438
5471
|
async set(key, value) {
|
|
5439
|
-
const cacheKey = createCacheKey(key);
|
|
5440
|
-
|
|
5472
|
+
const cacheKey = createCacheKey(key, this.namespace);
|
|
5473
|
+
const memoryEntry = {
|
|
5474
|
+
value,
|
|
5475
|
+
resolvedOrgIdentity: this.expectedResolvedOrgIdentity
|
|
5476
|
+
};
|
|
5477
|
+
this.memoryCache?.set(cacheKey, memoryEntry);
|
|
5441
5478
|
if (this.diskCache) {
|
|
5442
|
-
await this.diskCache.set(cacheKey,
|
|
5479
|
+
await this.diskCache.set(cacheKey, {
|
|
5480
|
+
value: value._internalSerializeForCache(),
|
|
5481
|
+
resolvedOrgIdentity: this.expectedResolvedOrgIdentity
|
|
5482
|
+
});
|
|
5443
5483
|
}
|
|
5444
5484
|
}
|
|
5445
5485
|
};
|
|
5446
5486
|
|
|
5447
5487
|
// src/prompt-cache/parameters-cache.ts
|
|
5448
|
-
function createCacheKey2(key) {
|
|
5488
|
+
function createCacheKey2(key, namespace) {
|
|
5489
|
+
let cacheKey;
|
|
5449
5490
|
if (key.id) {
|
|
5450
|
-
|
|
5451
|
-
}
|
|
5452
|
-
|
|
5453
|
-
|
|
5454
|
-
|
|
5455
|
-
|
|
5456
|
-
|
|
5457
|
-
|
|
5491
|
+
cacheKey = `parameters:id:${key.id}`;
|
|
5492
|
+
} else {
|
|
5493
|
+
const prefix = key.projectId ?? key.projectName;
|
|
5494
|
+
if (!prefix) {
|
|
5495
|
+
throw new Error("Either projectId or projectName must be provided");
|
|
5496
|
+
}
|
|
5497
|
+
if (!key.slug) {
|
|
5498
|
+
throw new Error("Slug must be provided when not using ID");
|
|
5499
|
+
}
|
|
5500
|
+
cacheKey = `parameters:${prefix}:${key.slug}:${key.version ?? "latest"}`;
|
|
5458
5501
|
}
|
|
5459
|
-
return
|
|
5502
|
+
return namespace === void 0 ? cacheKey : `${namespace.length}:${namespace}:${cacheKey}`;
|
|
5460
5503
|
}
|
|
5461
|
-
var ParametersCache = class {
|
|
5504
|
+
var ParametersCache = class _ParametersCache {
|
|
5462
5505
|
memoryCache;
|
|
5463
5506
|
diskCache;
|
|
5507
|
+
namespace;
|
|
5508
|
+
expectedResolvedOrgIdentity;
|
|
5464
5509
|
constructor(options) {
|
|
5465
5510
|
this.memoryCache = options.memoryCache;
|
|
5466
5511
|
this.diskCache = options.diskCache;
|
|
5512
|
+
this.namespace = options.namespace;
|
|
5513
|
+
this.expectedResolvedOrgIdentity = options.expectedResolvedOrgIdentity;
|
|
5514
|
+
}
|
|
5515
|
+
withNamespace(namespace, expectedResolvedOrgIdentity) {
|
|
5516
|
+
return new _ParametersCache({
|
|
5517
|
+
memoryCache: this.memoryCache,
|
|
5518
|
+
diskCache: this.diskCache,
|
|
5519
|
+
namespace,
|
|
5520
|
+
expectedResolvedOrgIdentity
|
|
5521
|
+
});
|
|
5467
5522
|
}
|
|
5468
5523
|
async get(key) {
|
|
5469
|
-
const cacheKey = createCacheKey2(key);
|
|
5524
|
+
const cacheKey = createCacheKey2(key, this.namespace);
|
|
5470
5525
|
if (this.memoryCache) {
|
|
5471
|
-
const
|
|
5472
|
-
if (
|
|
5473
|
-
return
|
|
5526
|
+
const memoryEntry = this.memoryCache.get(cacheKey);
|
|
5527
|
+
if (memoryEntry !== void 0 && (this.expectedResolvedOrgIdentity === void 0 || memoryEntry.resolvedOrgIdentity === this.expectedResolvedOrgIdentity)) {
|
|
5528
|
+
return memoryEntry.value;
|
|
5474
5529
|
}
|
|
5475
5530
|
}
|
|
5476
5531
|
if (this.diskCache) {
|
|
5477
|
-
const
|
|
5478
|
-
if (!
|
|
5532
|
+
const diskEntry = await this.diskCache.get(cacheKey);
|
|
5533
|
+
if (!diskEntry || this.expectedResolvedOrgIdentity !== void 0 && diskEntry.resolvedOrgIdentity !== this.expectedResolvedOrgIdentity) {
|
|
5479
5534
|
return void 0;
|
|
5480
5535
|
}
|
|
5481
|
-
|
|
5482
|
-
|
|
5536
|
+
const diskParameters = new RemoteEvalParameters(diskEntry.value.metadata);
|
|
5537
|
+
this.memoryCache?.set(cacheKey, {
|
|
5538
|
+
value: diskParameters,
|
|
5539
|
+
resolvedOrgIdentity: diskEntry.resolvedOrgIdentity
|
|
5540
|
+
});
|
|
5541
|
+
return diskParameters;
|
|
5483
5542
|
}
|
|
5484
5543
|
return void 0;
|
|
5485
5544
|
}
|
|
5486
5545
|
async set(key, value) {
|
|
5487
|
-
const cacheKey = createCacheKey2(key);
|
|
5488
|
-
|
|
5546
|
+
const cacheKey = createCacheKey2(key, this.namespace);
|
|
5547
|
+
const memoryEntry = {
|
|
5548
|
+
value,
|
|
5549
|
+
resolvedOrgIdentity: this.expectedResolvedOrgIdentity
|
|
5550
|
+
};
|
|
5551
|
+
this.memoryCache?.set(cacheKey, memoryEntry);
|
|
5489
5552
|
if (this.diskCache) {
|
|
5490
|
-
await this.diskCache.set(cacheKey,
|
|
5553
|
+
await this.diskCache.set(cacheKey, {
|
|
5554
|
+
value: value._internalSerializeForCache(),
|
|
5555
|
+
resolvedOrgIdentity: this.expectedResolvedOrgIdentity
|
|
5556
|
+
});
|
|
5491
5557
|
}
|
|
5492
5558
|
}
|
|
5493
5559
|
};
|
|
@@ -5791,6 +5857,7 @@ var INSTRUMENTATION_NAMES = {
|
|
|
5791
5857
|
CLOUDFLARE_THINK: "cloudflare-think",
|
|
5792
5858
|
COHERE: "cohere",
|
|
5793
5859
|
CURSOR_SDK: "cursor-sdk",
|
|
5860
|
+
DEEPSEEK_HARNESS: "deepseek-harness",
|
|
5794
5861
|
EVE: "eve",
|
|
5795
5862
|
FLUE: "flue",
|
|
5796
5863
|
GENKIT: "genkit",
|
|
@@ -5816,7 +5883,7 @@ var INSTRUMENTATION_NAMES = {
|
|
|
5816
5883
|
var INTERNAL_SPAN_INSTRUMENTATION_NAME = /* @__PURE__ */ Symbol.for(
|
|
5817
5884
|
"braintrust.spanInstrumentationName"
|
|
5818
5885
|
);
|
|
5819
|
-
var SDK_VERSION = true ? "3.
|
|
5886
|
+
var SDK_VERSION = true ? "3.30.0" : "0.0.0";
|
|
5820
5887
|
function withSpanInstrumentationName(args, instrumentationName) {
|
|
5821
5888
|
return {
|
|
5822
5889
|
...args,
|
|
@@ -5935,6 +6002,16 @@ var datasetSnapshotRegisterResponseSchema = import_v38.z.object({
|
|
|
5935
6002
|
dataset_snapshot: DatasetSnapshot,
|
|
5936
6003
|
found_existing: import_v38.z.boolean().optional()
|
|
5937
6004
|
});
|
|
6005
|
+
var datasetObjectInfoSchema = import_v38.z.object({
|
|
6006
|
+
object_id: import_v38.z.string(),
|
|
6007
|
+
object_name: import_v38.z.string(),
|
|
6008
|
+
parent_cols: import_v38.z.object({
|
|
6009
|
+
project: import_v38.z.object({
|
|
6010
|
+
id: import_v38.z.string(),
|
|
6011
|
+
name: import_v38.z.string()
|
|
6012
|
+
})
|
|
6013
|
+
})
|
|
6014
|
+
});
|
|
5938
6015
|
var datasetRestorePreviewResultSchema = import_v38.z.object({
|
|
5939
6016
|
rows_to_restore: import_v38.z.number(),
|
|
5940
6017
|
rows_to_delete: import_v38.z.number()
|
|
@@ -6148,12 +6225,53 @@ var loginSchema = import_v38.z.strictObject({
|
|
|
6148
6225
|
});
|
|
6149
6226
|
var stateNonce = 0;
|
|
6150
6227
|
var V1_PROXY_SUFFIX = "/v1/proxy";
|
|
6228
|
+
var LOADER_LOGIN_CACHE_MAX = 16;
|
|
6151
6229
|
function normalizeProxyConnUrl(proxyUrl) {
|
|
6152
6230
|
return proxyUrl.endsWith(V1_PROXY_SUFFIX) ? proxyUrl.slice(0, proxyUrl.length - V1_PROXY_SUFFIX.length) : proxyUrl;
|
|
6153
6231
|
}
|
|
6154
6232
|
var BraintrustState = class _BraintrustState {
|
|
6233
|
+
id;
|
|
6234
|
+
currentExperiment;
|
|
6235
|
+
// Note: the value of IsAsyncFlush doesn't really matter here, since we
|
|
6236
|
+
// (safely) dynamically cast it whenever retrieving the logger.
|
|
6237
|
+
currentLogger;
|
|
6238
|
+
currentParent;
|
|
6239
|
+
currentSpan;
|
|
6240
|
+
// Any time we re-log in, we directly update the apiConn inside the logger.
|
|
6241
|
+
// This is preferable to replacing the whole logger, which would create the
|
|
6242
|
+
// possibility of multiple loggers floating around, which may not log in a
|
|
6243
|
+
// deterministic order.
|
|
6244
|
+
_bgLogger;
|
|
6245
|
+
_overrideBgLogger = null;
|
|
6246
|
+
appUrl = null;
|
|
6247
|
+
appPublicUrl = null;
|
|
6248
|
+
loginToken = null;
|
|
6249
|
+
orgId = null;
|
|
6250
|
+
orgName = null;
|
|
6251
|
+
apiUrl = null;
|
|
6252
|
+
proxyUrl = null;
|
|
6253
|
+
loggedIn = false;
|
|
6254
|
+
gitMetadataSettings;
|
|
6255
|
+
debugLogLevel;
|
|
6256
|
+
debugLogLevelConfigured = false;
|
|
6257
|
+
fetch = globalThis.fetch;
|
|
6258
|
+
_appConn = null;
|
|
6259
|
+
_apiConn = null;
|
|
6260
|
+
_proxyConn = null;
|
|
6261
|
+
promptCache;
|
|
6262
|
+
parametersCache;
|
|
6263
|
+
spanCache;
|
|
6264
|
+
_idGenerator = null;
|
|
6265
|
+
_contextManager = null;
|
|
6266
|
+
_otelFlushCallback = null;
|
|
6267
|
+
spanOriginEnvironment;
|
|
6268
|
+
traceContextSigningSecret;
|
|
6269
|
+
loaderLoginCache = /* @__PURE__ */ new WeakMap();
|
|
6270
|
+
loginParams;
|
|
6271
|
+
activeLoginOrgNameSelector;
|
|
6155
6272
|
constructor(loginParams) {
|
|
6156
|
-
this.loginParams = loginParams;
|
|
6273
|
+
this.loginParams = { ...loginParams };
|
|
6274
|
+
this.activeLoginOrgNameSelector = loginParams.orgName ?? isomorph_default.getEnv("BRAINTRUST_ORG_NAME");
|
|
6157
6275
|
this.id = `${(/* @__PURE__ */ new Date()).toLocaleString()}-${stateNonce++}`;
|
|
6158
6276
|
this.currentExperiment = void 0;
|
|
6159
6277
|
this.currentLogger = void 0;
|
|
@@ -6190,12 +6308,14 @@ var BraintrustState = class _BraintrustState {
|
|
|
6190
6308
|
const {
|
|
6191
6309
|
memoryCache: parametersMemoryCache,
|
|
6192
6310
|
diskCache: parametersDiskCache
|
|
6193
|
-
} = createCacheLayers(
|
|
6194
|
-
|
|
6195
|
-
|
|
6196
|
-
|
|
6197
|
-
|
|
6198
|
-
|
|
6311
|
+
} = createCacheLayers(
|
|
6312
|
+
{
|
|
6313
|
+
memoryMaxEnvVar: "BRAINTRUST_PARAMETERS_CACHE_MEMORY_MAX",
|
|
6314
|
+
diskCacheDirEnvVar: "BRAINTRUST_PARAMETERS_CACHE_DIR",
|
|
6315
|
+
diskMaxEnvVar: "BRAINTRUST_PARAMETERS_CACHE_DISK_MAX",
|
|
6316
|
+
getDefaultDiskCacheDir: () => `${isomorph_default.getEnv("HOME") ?? isomorph_default.homedir()}/.braintrust/parameters_cache`
|
|
6317
|
+
}
|
|
6318
|
+
);
|
|
6199
6319
|
this.parametersCache = new ParametersCache({
|
|
6200
6320
|
memoryCache: parametersMemoryCache,
|
|
6201
6321
|
diskCache: parametersDiskCache
|
|
@@ -6204,43 +6324,6 @@ var BraintrustState = class _BraintrustState {
|
|
|
6204
6324
|
this.spanOriginEnvironment = detectSpanOriginEnvironment();
|
|
6205
6325
|
this._internalSetTraceContextSigningSecret(loginParams.apiKey);
|
|
6206
6326
|
}
|
|
6207
|
-
loginParams;
|
|
6208
|
-
id;
|
|
6209
|
-
currentExperiment;
|
|
6210
|
-
// Note: the value of IsAsyncFlush doesn't really matter here, since we
|
|
6211
|
-
// (safely) dynamically cast it whenever retrieving the logger.
|
|
6212
|
-
currentLogger;
|
|
6213
|
-
currentParent;
|
|
6214
|
-
currentSpan;
|
|
6215
|
-
// Any time we re-log in, we directly update the apiConn inside the logger.
|
|
6216
|
-
// This is preferable to replacing the whole logger, which would create the
|
|
6217
|
-
// possibility of multiple loggers floating around, which may not log in a
|
|
6218
|
-
// deterministic order.
|
|
6219
|
-
_bgLogger;
|
|
6220
|
-
_overrideBgLogger = null;
|
|
6221
|
-
appUrl = null;
|
|
6222
|
-
appPublicUrl = null;
|
|
6223
|
-
loginToken = null;
|
|
6224
|
-
orgId = null;
|
|
6225
|
-
orgName = null;
|
|
6226
|
-
apiUrl = null;
|
|
6227
|
-
proxyUrl = null;
|
|
6228
|
-
loggedIn = false;
|
|
6229
|
-
gitMetadataSettings;
|
|
6230
|
-
debugLogLevel;
|
|
6231
|
-
debugLogLevelConfigured = false;
|
|
6232
|
-
fetch = globalThis.fetch;
|
|
6233
|
-
_appConn = null;
|
|
6234
|
-
_apiConn = null;
|
|
6235
|
-
_proxyConn = null;
|
|
6236
|
-
promptCache;
|
|
6237
|
-
parametersCache;
|
|
6238
|
-
spanCache;
|
|
6239
|
-
_idGenerator = null;
|
|
6240
|
-
_contextManager = null;
|
|
6241
|
-
_otelFlushCallback = null;
|
|
6242
|
-
spanOriginEnvironment;
|
|
6243
|
-
traceContextSigningSecret;
|
|
6244
6327
|
/** @internal */
|
|
6245
6328
|
_internalSetTraceContextSigningSecret(secret) {
|
|
6246
6329
|
const normalizedSecret = secret?.trim();
|
|
@@ -6265,6 +6348,101 @@ var BraintrustState = class _BraintrustState {
|
|
|
6265
6348
|
this._appConn = null;
|
|
6266
6349
|
this._apiConn = null;
|
|
6267
6350
|
this._proxyConn = null;
|
|
6351
|
+
this.loaderLoginCache = /* @__PURE__ */ new WeakMap();
|
|
6352
|
+
}
|
|
6353
|
+
/** @internal */
|
|
6354
|
+
async _internalResolveLoaderLoginOptions({
|
|
6355
|
+
apiKey,
|
|
6356
|
+
appUrl,
|
|
6357
|
+
orgName,
|
|
6358
|
+
fetch: fetch2,
|
|
6359
|
+
forceLogin
|
|
6360
|
+
}) {
|
|
6361
|
+
const resolvedAppUrl = appUrl ?? (this.loggedIn ? this.appUrl ?? void 0 : void 0) ?? this.loginParams.appUrl ?? isomorph_default.getEnv("BRAINTRUST_APP_URL") ?? "https://www.braintrust.dev";
|
|
6362
|
+
const resolvedApiKey = apiKey ?? (this.loggedIn ? this.loginToken ?? void 0 : void 0) ?? this.loginParams.apiKey ?? await isomorph_default.getBraintrustApiKey();
|
|
6363
|
+
if (!resolvedApiKey) {
|
|
6364
|
+
throw new Error(
|
|
6365
|
+
"Please specify an api key (e.g. by setting BRAINTRUST_API_KEY)."
|
|
6366
|
+
);
|
|
6367
|
+
}
|
|
6368
|
+
const normalizedApiKey = HTTPConnection.sanitize_token(resolvedApiKey);
|
|
6369
|
+
const usesActiveCredential = this.loggedIn && normalizedApiKey === this.loginToken;
|
|
6370
|
+
const requestedOrgName = orgName ?? (usesActiveCredential ? this.activeLoginOrgNameSelector : void 0) ?? this.loginParams.orgName ?? isomorph_default.getEnv("BRAINTRUST_ORG_NAME");
|
|
6371
|
+
const resolvedOrgName = orgName ?? (usesActiveCredential ? this.orgName ?? void 0 : void 0) ?? requestedOrgName;
|
|
6372
|
+
const resolvedFetch = fetch2 ?? (this.loggedIn ? this.fetch : void 0) ?? this.loginParams.fetch ?? globalThis.fetch;
|
|
6373
|
+
const credentialCacheNamespace = JSON.stringify([
|
|
6374
|
+
"loader-credential",
|
|
6375
|
+
resolvedAppUrl,
|
|
6376
|
+
requestedOrgName,
|
|
6377
|
+
normalizedApiKey
|
|
6378
|
+
]);
|
|
6379
|
+
return {
|
|
6380
|
+
apiKey: normalizedApiKey,
|
|
6381
|
+
appUrl: resolvedAppUrl,
|
|
6382
|
+
orgName: resolvedOrgName,
|
|
6383
|
+
fetch: resolvedFetch,
|
|
6384
|
+
forceLogin,
|
|
6385
|
+
credentialCacheNamespace,
|
|
6386
|
+
existingState: !forceLogin && usesActiveCredential && resolvedAppUrl === this.appUrl && resolvedOrgName === this.orgName && resolvedFetch === this.fetch ? this : void 0
|
|
6387
|
+
};
|
|
6388
|
+
}
|
|
6389
|
+
/** @internal */
|
|
6390
|
+
_internalGetLoaderCacheViews(loginOptions, requestState) {
|
|
6391
|
+
const expectedResolvedOrgIdentity = requestState?.orgId && requestState.appUrl ? JSON.stringify([
|
|
6392
|
+
"loader-org",
|
|
6393
|
+
requestState.appUrl,
|
|
6394
|
+
requestState.orgId
|
|
6395
|
+
]) : void 0;
|
|
6396
|
+
return {
|
|
6397
|
+
promptCache: this.promptCache.withNamespace(
|
|
6398
|
+
loginOptions.credentialCacheNamespace,
|
|
6399
|
+
expectedResolvedOrgIdentity
|
|
6400
|
+
),
|
|
6401
|
+
parametersCache: this.parametersCache.withNamespace(
|
|
6402
|
+
loginOptions.credentialCacheNamespace,
|
|
6403
|
+
expectedResolvedOrgIdentity
|
|
6404
|
+
)
|
|
6405
|
+
};
|
|
6406
|
+
}
|
|
6407
|
+
/** @internal */
|
|
6408
|
+
async _internalGetLoaderState({
|
|
6409
|
+
apiKey,
|
|
6410
|
+
appUrl,
|
|
6411
|
+
orgName,
|
|
6412
|
+
fetch: fetch2,
|
|
6413
|
+
forceLogin,
|
|
6414
|
+
existingState
|
|
6415
|
+
}) {
|
|
6416
|
+
if (existingState) {
|
|
6417
|
+
return existingState;
|
|
6418
|
+
}
|
|
6419
|
+
let cache = this.loaderLoginCache.get(fetch2);
|
|
6420
|
+
if (!cache) {
|
|
6421
|
+
cache = new LRUCache({ max: LOADER_LOGIN_CACHE_MAX });
|
|
6422
|
+
this.loaderLoginCache.set(fetch2, cache);
|
|
6423
|
+
}
|
|
6424
|
+
const cacheKey = JSON.stringify([appUrl, orgName, apiKey]);
|
|
6425
|
+
if (!forceLogin) {
|
|
6426
|
+
const cachedState = cache.get(cacheKey);
|
|
6427
|
+
if (cachedState) {
|
|
6428
|
+
return cachedState;
|
|
6429
|
+
}
|
|
6430
|
+
}
|
|
6431
|
+
const statePromise = loginToLoaderRequestState({
|
|
6432
|
+
orgName,
|
|
6433
|
+
apiKey,
|
|
6434
|
+
appUrl,
|
|
6435
|
+
fetch: fetch2
|
|
6436
|
+
});
|
|
6437
|
+
cache.set(cacheKey, statePromise);
|
|
6438
|
+
try {
|
|
6439
|
+
return await statePromise;
|
|
6440
|
+
} catch (error) {
|
|
6441
|
+
if (cache.get(cacheKey) === statePromise) {
|
|
6442
|
+
cache.delete(cacheKey);
|
|
6443
|
+
}
|
|
6444
|
+
throw error;
|
|
6445
|
+
}
|
|
6268
6446
|
}
|
|
6269
6447
|
resetIdGenState() {
|
|
6270
6448
|
this._idGenerator = null;
|
|
@@ -6313,6 +6491,8 @@ var BraintrustState = class _BraintrustState {
|
|
|
6313
6491
|
this.debugLogLevel = other.debugLogLevel;
|
|
6314
6492
|
this.debugLogLevelConfigured = other.debugLogLevelConfigured;
|
|
6315
6493
|
this.traceContextSigningSecret = other.traceContextSigningSecret;
|
|
6494
|
+
this.fetch = other.fetch;
|
|
6495
|
+
this.activeLoginOrgNameSelector = other.activeLoginOrgNameSelector;
|
|
6316
6496
|
setGlobalDebugLogLevel(
|
|
6317
6497
|
this.debugLogLevelConfigured ? this.debugLogLevel ?? false : void 0
|
|
6318
6498
|
);
|
|
@@ -6552,36 +6732,85 @@ var FailedHTTPResponse = class extends Error {
|
|
|
6552
6732
|
status;
|
|
6553
6733
|
text;
|
|
6554
6734
|
data;
|
|
6555
|
-
|
|
6735
|
+
cause;
|
|
6736
|
+
constructor(status, text, data, cause) {
|
|
6556
6737
|
super(`${status}: ${text} (${data})`);
|
|
6557
6738
|
this.status = status;
|
|
6558
6739
|
this.text = text;
|
|
6559
6740
|
this.data = data;
|
|
6741
|
+
this.cause = cause;
|
|
6742
|
+
}
|
|
6743
|
+
};
|
|
6744
|
+
var HTTPTransportError = class extends Error {
|
|
6745
|
+
cause;
|
|
6746
|
+
constructor(cause) {
|
|
6747
|
+
super(cause instanceof Error ? cause.message : String(cause));
|
|
6748
|
+
this.name = "HTTPTransportError";
|
|
6749
|
+
this.cause = cause;
|
|
6560
6750
|
}
|
|
6561
6751
|
};
|
|
6752
|
+
var httpTransportErrorCauses = /* @__PURE__ */ new WeakSet();
|
|
6753
|
+
function recordHTTPTransportError(error) {
|
|
6754
|
+
if (typeof error === "object" && error !== null || typeof error === "function") {
|
|
6755
|
+
httpTransportErrorCauses.add(error);
|
|
6756
|
+
}
|
|
6757
|
+
}
|
|
6758
|
+
function rethrowHTTPTransportError(error, classifyTransportErrors) {
|
|
6759
|
+
if (classifyTransportErrors) {
|
|
6760
|
+
throw new HTTPTransportError(error);
|
|
6761
|
+
}
|
|
6762
|
+
recordHTTPTransportError(error);
|
|
6763
|
+
throw error;
|
|
6764
|
+
}
|
|
6765
|
+
function isLoaderCacheFallbackError(error) {
|
|
6766
|
+
if (error instanceof FailedHTTPResponse) {
|
|
6767
|
+
return error.status === 408 || error.status === 429 || error.status >= 500;
|
|
6768
|
+
}
|
|
6769
|
+
if (error instanceof HTTPTransportError) {
|
|
6770
|
+
return true;
|
|
6771
|
+
}
|
|
6772
|
+
return (typeof error === "object" && error !== null || typeof error === "function") && httpTransportErrorCauses.has(error);
|
|
6773
|
+
}
|
|
6774
|
+
async function readJSONResponse(response, classifyTransportErrors = false) {
|
|
6775
|
+
let data;
|
|
6776
|
+
try {
|
|
6777
|
+
data = await response.text();
|
|
6778
|
+
} catch (error) {
|
|
6779
|
+
rethrowHTTPTransportError(error, classifyTransportErrors);
|
|
6780
|
+
}
|
|
6781
|
+
return JSON.parse(data);
|
|
6782
|
+
}
|
|
6562
6783
|
async function checkResponse(resp) {
|
|
6563
6784
|
if (resp.ok) {
|
|
6564
6785
|
return resp;
|
|
6565
|
-
}
|
|
6786
|
+
}
|
|
6787
|
+
let data;
|
|
6788
|
+
try {
|
|
6789
|
+
data = await resp.text();
|
|
6790
|
+
} catch (error) {
|
|
6566
6791
|
throw new FailedHTTPResponse(
|
|
6567
6792
|
resp.status,
|
|
6568
6793
|
resp.statusText,
|
|
6569
|
-
|
|
6794
|
+
"Unable to read response body",
|
|
6795
|
+
error
|
|
6570
6796
|
);
|
|
6571
6797
|
}
|
|
6798
|
+
throw new FailedHTTPResponse(resp.status, resp.statusText, data);
|
|
6572
6799
|
}
|
|
6573
6800
|
var HTTPConnection = class _HTTPConnection {
|
|
6574
|
-
base_url
|
|
6575
|
-
|
|
6576
|
-
headers;
|
|
6577
|
-
fetch;
|
|
6578
|
-
constructor(base_url, fetch2) {
|
|
6801
|
+
constructor(base_url, fetch2, classifyTransportErrors = false) {
|
|
6802
|
+
this.classifyTransportErrors = classifyTransportErrors;
|
|
6579
6803
|
this.base_url = base_url;
|
|
6580
6804
|
this.token = null;
|
|
6581
6805
|
this.headers = {};
|
|
6582
6806
|
this._reset();
|
|
6583
6807
|
this.fetch = fetch2;
|
|
6584
6808
|
}
|
|
6809
|
+
classifyTransportErrors;
|
|
6810
|
+
base_url;
|
|
6811
|
+
token;
|
|
6812
|
+
headers;
|
|
6813
|
+
fetch;
|
|
6585
6814
|
setFetch(fetch2) {
|
|
6586
6815
|
this.fetch = fetch2;
|
|
6587
6816
|
}
|
|
@@ -6621,9 +6850,9 @@ var HTTPConnection = class _HTTPConnection {
|
|
|
6621
6850
|
).toString();
|
|
6622
6851
|
const this_fetch = this.fetch;
|
|
6623
6852
|
const this_headers = this.headers;
|
|
6624
|
-
|
|
6625
|
-
|
|
6626
|
-
await this_fetch(url.toString(), {
|
|
6853
|
+
let response;
|
|
6854
|
+
try {
|
|
6855
|
+
response = await this_fetch(url.toString(), {
|
|
6627
6856
|
headers: {
|
|
6628
6857
|
Accept: "application/json",
|
|
6629
6858
|
...this_headers,
|
|
@@ -6631,8 +6860,14 @@ var HTTPConnection = class _HTTPConnection {
|
|
|
6631
6860
|
},
|
|
6632
6861
|
keepalive: true,
|
|
6633
6862
|
...rest
|
|
6634
|
-
})
|
|
6635
|
-
)
|
|
6863
|
+
});
|
|
6864
|
+
} catch (error) {
|
|
6865
|
+
if (config?.signal?.aborted) {
|
|
6866
|
+
throw getAbortReason(config.signal);
|
|
6867
|
+
}
|
|
6868
|
+
rethrowHTTPTransportError(error, this.classifyTransportErrors);
|
|
6869
|
+
}
|
|
6870
|
+
return await checkResponse(response);
|
|
6636
6871
|
}
|
|
6637
6872
|
async post(path, params, config, retries = 0) {
|
|
6638
6873
|
const { headers, ...rest } = config || {};
|
|
@@ -6642,8 +6877,9 @@ var HTTPConnection = class _HTTPConnection {
|
|
|
6642
6877
|
const tries = retries + 1;
|
|
6643
6878
|
for (let i = 0; i < tries; i++) {
|
|
6644
6879
|
try {
|
|
6645
|
-
|
|
6646
|
-
|
|
6880
|
+
let response;
|
|
6881
|
+
try {
|
|
6882
|
+
response = await this_fetch(_urljoin(this_base_url, path), {
|
|
6647
6883
|
method: "POST",
|
|
6648
6884
|
headers: {
|
|
6649
6885
|
Accept: "application/json",
|
|
@@ -6654,8 +6890,14 @@ var HTTPConnection = class _HTTPConnection {
|
|
|
6654
6890
|
body: typeof params === "string" ? params : params ? JSON.stringify(params) : void 0,
|
|
6655
6891
|
keepalive: true,
|
|
6656
6892
|
...rest
|
|
6657
|
-
})
|
|
6658
|
-
)
|
|
6893
|
+
});
|
|
6894
|
+
} catch (error) {
|
|
6895
|
+
if (config?.signal?.aborted) {
|
|
6896
|
+
throw getAbortReason(config.signal);
|
|
6897
|
+
}
|
|
6898
|
+
rethrowHTTPTransportError(error, this.classifyTransportErrors);
|
|
6899
|
+
}
|
|
6900
|
+
return await checkResponse(response);
|
|
6659
6901
|
} catch (error) {
|
|
6660
6902
|
if (config?.signal?.aborted) {
|
|
6661
6903
|
throw getAbortReason(config.signal);
|
|
@@ -6680,7 +6922,7 @@ var HTTPConnection = class _HTTPConnection {
|
|
|
6680
6922
|
for (let i = 0; i < tries; i++) {
|
|
6681
6923
|
try {
|
|
6682
6924
|
const resp = await this.get(`${object_type}`, args);
|
|
6683
|
-
return await resp.
|
|
6925
|
+
return await readJSONResponse(resp, this.classifyTransportErrors);
|
|
6684
6926
|
} catch (e) {
|
|
6685
6927
|
if (i < tries - 1) {
|
|
6686
6928
|
debugLogger.debug(
|
|
@@ -6703,7 +6945,7 @@ var HTTPConnection = class _HTTPConnection {
|
|
|
6703
6945
|
const resp = await this.post(`${object_type}`, args, {
|
|
6704
6946
|
headers: { "Content-Type": "application/json" }
|
|
6705
6947
|
});
|
|
6706
|
-
return await resp.
|
|
6948
|
+
return await readJSONResponse(resp, this.classifyTransportErrors);
|
|
6707
6949
|
}
|
|
6708
6950
|
// Custom inspect for Node.js console.log
|
|
6709
6951
|
[/* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom")]() {
|
|
@@ -8751,6 +8993,7 @@ function initDataset(projectOrOptions, optionalOptions) {
|
|
|
8751
8993
|
const {
|
|
8752
8994
|
project,
|
|
8753
8995
|
dataset,
|
|
8996
|
+
datasetId,
|
|
8754
8997
|
description,
|
|
8755
8998
|
version,
|
|
8756
8999
|
snapshotName,
|
|
@@ -8766,6 +9009,11 @@ function initDataset(projectOrOptions, optionalOptions) {
|
|
|
8766
9009
|
state: stateArg,
|
|
8767
9010
|
_internal_btql
|
|
8768
9011
|
} = options;
|
|
9012
|
+
if (datasetId !== void 0 && (description !== void 0 || metadata !== void 0)) {
|
|
9013
|
+
throw new Error(
|
|
9014
|
+
"Cannot specify description or metadata when datasetId is provided"
|
|
9015
|
+
);
|
|
9016
|
+
}
|
|
8769
9017
|
const selection = normalizeDatasetSelection({
|
|
8770
9018
|
version,
|
|
8771
9019
|
environment,
|
|
@@ -8786,6 +9034,35 @@ function initDataset(projectOrOptions, optionalOptions) {
|
|
|
8786
9034
|
fetch: fetch2,
|
|
8787
9035
|
forceLogin
|
|
8788
9036
|
});
|
|
9037
|
+
if (datasetId !== void 0) {
|
|
9038
|
+
const objectInfo = datasetObjectInfoSchema.array().parse(
|
|
9039
|
+
await state.appConn().post_json("api/self/get_object_info", {
|
|
9040
|
+
object_type: "dataset",
|
|
9041
|
+
object_ids: [datasetId]
|
|
9042
|
+
})
|
|
9043
|
+
);
|
|
9044
|
+
if (objectInfo.length === 0) {
|
|
9045
|
+
throw new Error(`Dataset with ID ${datasetId} not found`);
|
|
9046
|
+
}
|
|
9047
|
+
if (objectInfo.length !== 1) {
|
|
9048
|
+
throw new Error(
|
|
9049
|
+
`Expected exactly one dataset with ID ${datasetId}, but found ${objectInfo.length}`
|
|
9050
|
+
);
|
|
9051
|
+
}
|
|
9052
|
+
const datasetInfo = objectInfo[0];
|
|
9053
|
+
return {
|
|
9054
|
+
project: {
|
|
9055
|
+
id: datasetInfo.parent_cols.project.id,
|
|
9056
|
+
name: datasetInfo.parent_cols.project.name,
|
|
9057
|
+
fullInfo: datasetInfo.parent_cols.project
|
|
9058
|
+
},
|
|
9059
|
+
dataset: {
|
|
9060
|
+
id: datasetInfo.object_id,
|
|
9061
|
+
name: datasetInfo.object_name,
|
|
9062
|
+
fullInfo: datasetInfo
|
|
9063
|
+
}
|
|
9064
|
+
};
|
|
9065
|
+
}
|
|
8789
9066
|
const args = {
|
|
8790
9067
|
org_id: state.orgId,
|
|
8791
9068
|
project_name: project,
|
|
@@ -8939,6 +9216,24 @@ function initLogger(options = {}) {
|
|
|
8939
9216
|
}
|
|
8940
9217
|
return ret;
|
|
8941
9218
|
}
|
|
9219
|
+
async function runCredentialScopedLoaderRequest(state, loginOptions, request) {
|
|
9220
|
+
const resolvedLoginOptions = await state._internalResolveLoaderLoginOptions(loginOptions);
|
|
9221
|
+
let cacheViews = state._internalGetLoaderCacheViews(resolvedLoginOptions);
|
|
9222
|
+
try {
|
|
9223
|
+
const requestState = await state._internalGetLoaderState(resolvedLoginOptions);
|
|
9224
|
+
cacheViews = state._internalGetLoaderCacheViews(
|
|
9225
|
+
resolvedLoginOptions,
|
|
9226
|
+
requestState
|
|
9227
|
+
);
|
|
9228
|
+
return {
|
|
9229
|
+
ok: true,
|
|
9230
|
+
response: await request(requestState),
|
|
9231
|
+
...cacheViews
|
|
9232
|
+
};
|
|
9233
|
+
} catch (error) {
|
|
9234
|
+
return { ok: false, error, ...cacheViews };
|
|
9235
|
+
}
|
|
9236
|
+
}
|
|
8942
9237
|
async function loadPrompt({
|
|
8943
9238
|
projectName,
|
|
8944
9239
|
projectId,
|
|
@@ -8963,43 +9258,47 @@ async function loadPrompt({
|
|
|
8963
9258
|
throw new Error("Must specify slug");
|
|
8964
9259
|
}
|
|
8965
9260
|
const state = stateArg ?? _globalState;
|
|
8966
|
-
|
|
8967
|
-
|
|
8968
|
-
|
|
8969
|
-
|
|
8970
|
-
|
|
8971
|
-
|
|
8972
|
-
|
|
8973
|
-
|
|
8974
|
-
|
|
8975
|
-
|
|
8976
|
-
|
|
8977
|
-
|
|
8978
|
-
|
|
9261
|
+
const result = await runCredentialScopedLoaderRequest(
|
|
9262
|
+
state,
|
|
9263
|
+
{ orgName, apiKey, appUrl, fetch: fetch2, forceLogin },
|
|
9264
|
+
async (requestState) => {
|
|
9265
|
+
let response2;
|
|
9266
|
+
if (id) {
|
|
9267
|
+
response2 = await requestState.apiConn().get_json(`v1/prompt/${id}`, versionOrEnvironment);
|
|
9268
|
+
if (response2) {
|
|
9269
|
+
response2 = { objects: [response2] };
|
|
9270
|
+
}
|
|
9271
|
+
} else {
|
|
9272
|
+
response2 = await requestState.apiConn().get_json("v1/prompt", {
|
|
9273
|
+
project_name: projectName,
|
|
9274
|
+
project_id: projectId,
|
|
9275
|
+
slug,
|
|
9276
|
+
...versionOrEnvironment
|
|
9277
|
+
});
|
|
8979
9278
|
}
|
|
8980
|
-
|
|
8981
|
-
|
|
8982
|
-
|
|
8983
|
-
|
|
8984
|
-
|
|
8985
|
-
|
|
8986
|
-
|
|
9279
|
+
return response2;
|
|
9280
|
+
}
|
|
9281
|
+
);
|
|
9282
|
+
const { promptCache } = result;
|
|
9283
|
+
if (!result.ok) {
|
|
9284
|
+
const e = result.error;
|
|
9285
|
+
if (!isLoaderCacheFallbackError(e)) {
|
|
9286
|
+
throw e;
|
|
8987
9287
|
}
|
|
8988
|
-
} catch (e) {
|
|
8989
9288
|
if (version || environment) {
|
|
8990
9289
|
throw new Error(`Prompt not found with specified parameters: ${e}`);
|
|
8991
9290
|
}
|
|
8992
9291
|
debugLogger.forState(state).warn("Failed to load prompt, attempting to fall back to cache:", e);
|
|
8993
9292
|
let prompt2;
|
|
8994
9293
|
if (id) {
|
|
8995
|
-
prompt2 = await
|
|
9294
|
+
prompt2 = await promptCache.get({ id });
|
|
8996
9295
|
if (!prompt2) {
|
|
8997
9296
|
throw new Error(
|
|
8998
9297
|
`Prompt with id ${id} not found (not found on server or in local cache): ${e}`
|
|
8999
9298
|
);
|
|
9000
9299
|
}
|
|
9001
9300
|
} else {
|
|
9002
|
-
prompt2 = await
|
|
9301
|
+
prompt2 = await promptCache.get({
|
|
9003
9302
|
slug,
|
|
9004
9303
|
projectId,
|
|
9005
9304
|
projectName,
|
|
@@ -9015,6 +9314,7 @@ async function loadPrompt({
|
|
|
9015
9314
|
}
|
|
9016
9315
|
return prompt2;
|
|
9017
9316
|
}
|
|
9317
|
+
const { response } = result;
|
|
9018
9318
|
if (!("objects" in response) || response.objects.length === 0) {
|
|
9019
9319
|
if (id) {
|
|
9020
9320
|
throw new Error(`Prompt with id ${id} not found.`);
|
|
@@ -9038,9 +9338,9 @@ async function loadPrompt({
|
|
|
9038
9338
|
const prompt = new Prompt2(metadata, defaults || {}, noTrace);
|
|
9039
9339
|
try {
|
|
9040
9340
|
if (id) {
|
|
9041
|
-
await
|
|
9341
|
+
await promptCache.set({ id }, prompt);
|
|
9042
9342
|
} else if (slug) {
|
|
9043
|
-
await
|
|
9343
|
+
await promptCache.set(
|
|
9044
9344
|
{ slug, projectId, projectName, version: version ?? "latest" },
|
|
9045
9345
|
prompt
|
|
9046
9346
|
);
|
|
@@ -9072,46 +9372,50 @@ async function loadParameters({
|
|
|
9072
9372
|
throw new Error("Must specify slug");
|
|
9073
9373
|
}
|
|
9074
9374
|
const state = stateArg ?? _globalState;
|
|
9075
|
-
|
|
9076
|
-
|
|
9077
|
-
|
|
9078
|
-
|
|
9079
|
-
|
|
9080
|
-
|
|
9081
|
-
|
|
9082
|
-
|
|
9083
|
-
|
|
9084
|
-
|
|
9085
|
-
|
|
9086
|
-
|
|
9087
|
-
}
|
|
9088
|
-
|
|
9089
|
-
|
|
9375
|
+
const result = await runCredentialScopedLoaderRequest(
|
|
9376
|
+
state,
|
|
9377
|
+
{ orgName, apiKey, appUrl, fetch: fetch2, forceLogin },
|
|
9378
|
+
async (requestState) => {
|
|
9379
|
+
let response2;
|
|
9380
|
+
if (id) {
|
|
9381
|
+
response2 = await requestState.apiConn().get_json(`v1/function/${id}`, {
|
|
9382
|
+
...versionOrEnvironment
|
|
9383
|
+
});
|
|
9384
|
+
if (response2) {
|
|
9385
|
+
response2 = { objects: [response2] };
|
|
9386
|
+
}
|
|
9387
|
+
} else {
|
|
9388
|
+
response2 = await requestState.apiConn().get_json("v1/function", {
|
|
9389
|
+
project_name: projectName,
|
|
9390
|
+
project_id: projectId,
|
|
9391
|
+
slug,
|
|
9392
|
+
function_type: "parameters",
|
|
9393
|
+
...versionOrEnvironment
|
|
9394
|
+
});
|
|
9090
9395
|
}
|
|
9091
|
-
|
|
9092
|
-
|
|
9093
|
-
|
|
9094
|
-
|
|
9095
|
-
|
|
9096
|
-
|
|
9097
|
-
|
|
9098
|
-
|
|
9396
|
+
return response2;
|
|
9397
|
+
}
|
|
9398
|
+
);
|
|
9399
|
+
const { parametersCache } = result;
|
|
9400
|
+
if (!result.ok) {
|
|
9401
|
+
const e = result.error;
|
|
9402
|
+
if (!isLoaderCacheFallbackError(e)) {
|
|
9403
|
+
throw e;
|
|
9099
9404
|
}
|
|
9100
|
-
} catch (e) {
|
|
9101
9405
|
if (version || environment) {
|
|
9102
9406
|
throw new Error(`Parameters not found with specified parameters: ${e}`);
|
|
9103
9407
|
}
|
|
9104
9408
|
debugLogger.forState(state).warn("Failed to load parameters, attempting to fall back to cache:", e);
|
|
9105
9409
|
let parameters2;
|
|
9106
9410
|
if (id) {
|
|
9107
|
-
parameters2 = await
|
|
9411
|
+
parameters2 = await parametersCache.get({ id });
|
|
9108
9412
|
if (!parameters2) {
|
|
9109
9413
|
throw new Error(
|
|
9110
9414
|
`Parameters with id ${id} not found (not found on server or in local cache): ${e}`
|
|
9111
9415
|
);
|
|
9112
9416
|
}
|
|
9113
9417
|
} else {
|
|
9114
|
-
parameters2 = await
|
|
9418
|
+
parameters2 = await parametersCache.get({
|
|
9115
9419
|
slug,
|
|
9116
9420
|
projectId,
|
|
9117
9421
|
projectName,
|
|
@@ -9127,6 +9431,7 @@ async function loadParameters({
|
|
|
9127
9431
|
}
|
|
9128
9432
|
return parameters2;
|
|
9129
9433
|
}
|
|
9434
|
+
const { response } = result;
|
|
9130
9435
|
if (!("objects" in response) || response.objects.length === 0) {
|
|
9131
9436
|
if (id) {
|
|
9132
9437
|
throw new Error(`Parameters with id ${id} not found.`);
|
|
@@ -9150,9 +9455,9 @@ async function loadParameters({
|
|
|
9150
9455
|
const parameters = new RemoteEvalParameters(metadata);
|
|
9151
9456
|
try {
|
|
9152
9457
|
if (id) {
|
|
9153
|
-
await
|
|
9458
|
+
await parametersCache.set({ id }, parameters);
|
|
9154
9459
|
} else if (slug) {
|
|
9155
|
-
await
|
|
9460
|
+
await parametersCache.set(
|
|
9156
9461
|
{ slug, projectId, projectName, version: version ?? "latest" },
|
|
9157
9462
|
parameters
|
|
9158
9463
|
);
|
|
@@ -9193,6 +9498,52 @@ async function login(options = {}) {
|
|
|
9193
9498
|
await state.login(options);
|
|
9194
9499
|
return state;
|
|
9195
9500
|
}
|
|
9501
|
+
async function loginToLoaderRequestState({
|
|
9502
|
+
appUrl,
|
|
9503
|
+
apiKey,
|
|
9504
|
+
orgName,
|
|
9505
|
+
fetch: fetch2
|
|
9506
|
+
}) {
|
|
9507
|
+
let orgId;
|
|
9508
|
+
let apiUrl;
|
|
9509
|
+
if (apiKey === TEST_API_KEY) {
|
|
9510
|
+
orgId = "test-org-id";
|
|
9511
|
+
apiUrl = "https://braintrust.dev/fake-api-url";
|
|
9512
|
+
} else {
|
|
9513
|
+
let loginResponse;
|
|
9514
|
+
try {
|
|
9515
|
+
loginResponse = await fetch2(_urljoin(appUrl, `/api/apikey/login`), {
|
|
9516
|
+
method: "POST",
|
|
9517
|
+
headers: {
|
|
9518
|
+
"Content-Type": "application/json",
|
|
9519
|
+
Authorization: `Bearer ${apiKey}`
|
|
9520
|
+
}
|
|
9521
|
+
});
|
|
9522
|
+
} catch (error) {
|
|
9523
|
+
throw new HTTPTransportError(error);
|
|
9524
|
+
}
|
|
9525
|
+
const info = await readJSONResponse(
|
|
9526
|
+
await checkResponse(loginResponse),
|
|
9527
|
+
true
|
|
9528
|
+
);
|
|
9529
|
+
const org = selectLoginOrg(info.org_info, orgName);
|
|
9530
|
+
orgId = org.id;
|
|
9531
|
+
apiUrl = isomorph_default.getEnv("BRAINTRUST_API_URL") ?? org.api_url;
|
|
9532
|
+
if (!apiUrl) {
|
|
9533
|
+
throw new Error(
|
|
9534
|
+
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."
|
|
9535
|
+
);
|
|
9536
|
+
}
|
|
9537
|
+
}
|
|
9538
|
+
const apiConnection = new HTTPConnection(apiUrl, fetch2, true);
|
|
9539
|
+
apiConnection.set_token(apiKey);
|
|
9540
|
+
apiConnection.make_long_lived();
|
|
9541
|
+
return {
|
|
9542
|
+
appUrl,
|
|
9543
|
+
orgId,
|
|
9544
|
+
apiConn: () => apiConnection
|
|
9545
|
+
};
|
|
9546
|
+
}
|
|
9196
9547
|
async function loginToState(options = {}) {
|
|
9197
9548
|
const {
|
|
9198
9549
|
appUrl = isomorph_default.getEnv("BRAINTRUST_APP_URL") || "https://www.braintrust.dev",
|
|
@@ -9224,16 +9575,18 @@ async function loginToState(options = {}) {
|
|
|
9224
9575
|
_saveOrgInfo(state, testOrgInfo, testOrgInfo[0].name);
|
|
9225
9576
|
return state;
|
|
9226
9577
|
} else {
|
|
9227
|
-
const
|
|
9228
|
-
|
|
9578
|
+
const loginResponse = await fetch2(
|
|
9579
|
+
_urljoin(state.appUrl, `/api/apikey/login`),
|
|
9580
|
+
{
|
|
9229
9581
|
method: "POST",
|
|
9230
9582
|
headers: {
|
|
9231
9583
|
"Content-Type": "application/json",
|
|
9232
9584
|
Authorization: `Bearer ${apiKey}`
|
|
9233
9585
|
}
|
|
9234
|
-
}
|
|
9586
|
+
}
|
|
9235
9587
|
);
|
|
9236
|
-
const
|
|
9588
|
+
const resp = await checkResponse(loginResponse);
|
|
9589
|
+
const info = await readJSONResponse(resp);
|
|
9237
9590
|
_saveOrgInfo(state, info.org_info, orgName);
|
|
9238
9591
|
if (!state.apiUrl) {
|
|
9239
9592
|
if (orgName) {
|
|
@@ -9736,11 +10089,11 @@ function wrapTraced(fn, args) {
|
|
|
9736
10089
|
}
|
|
9737
10090
|
if (args?.asyncFlush) {
|
|
9738
10091
|
return ((...fnArgs) => traced((span) => {
|
|
9739
|
-
if (!hasExplicitInput) {
|
|
10092
|
+
if (!args?.noTraceIO && !hasExplicitInput) {
|
|
9740
10093
|
span.log({ input: fnArgs });
|
|
9741
10094
|
}
|
|
9742
10095
|
const output = fn(...fnArgs);
|
|
9743
|
-
if (!hasExplicitOutput) {
|
|
10096
|
+
if (!args?.noTraceIO && !hasExplicitOutput) {
|
|
9744
10097
|
if (output instanceof Promise) {
|
|
9745
10098
|
return (async () => {
|
|
9746
10099
|
const result = await output;
|
|
@@ -9755,12 +10108,12 @@ function wrapTraced(fn, args) {
|
|
|
9755
10108
|
}, spanArgs));
|
|
9756
10109
|
} else {
|
|
9757
10110
|
return ((...fnArgs) => traced(async (span) => {
|
|
9758
|
-
if (!hasExplicitInput) {
|
|
10111
|
+
if (!args?.noTraceIO && !hasExplicitInput) {
|
|
9759
10112
|
span.log({ input: fnArgs });
|
|
9760
10113
|
}
|
|
9761
10114
|
const outputResult = fn(...fnArgs);
|
|
9762
10115
|
const output = await outputResult;
|
|
9763
|
-
if (!hasExplicitOutput) {
|
|
10116
|
+
if (!args?.noTraceIO && !hasExplicitOutput) {
|
|
9764
10117
|
span.log({ output });
|
|
9765
10118
|
}
|
|
9766
10119
|
return output;
|
|
@@ -9777,6 +10130,15 @@ function _internalStartSpanWithInitialMerge(args) {
|
|
|
9777
10130
|
[INITIAL_SPAN_WRITE_AS_MERGE]: true
|
|
9778
10131
|
}).span;
|
|
9779
10132
|
}
|
|
10133
|
+
function _internalStartSpanWithInitialMergeAndParentSpanIds(args) {
|
|
10134
|
+
return startSpanAndIsLogger(
|
|
10135
|
+
{
|
|
10136
|
+
...args,
|
|
10137
|
+
[INITIAL_SPAN_WRITE_AS_MERGE]: true
|
|
10138
|
+
},
|
|
10139
|
+
{ useParentSpanIdsForObjectParent: true }
|
|
10140
|
+
).span;
|
|
10141
|
+
}
|
|
9780
10142
|
function _internalStartSpanWithContext(args, context) {
|
|
9781
10143
|
return startSpanAndIsLogger({
|
|
9782
10144
|
...args,
|
|
@@ -9790,7 +10152,7 @@ async function flush(options) {
|
|
|
9790
10152
|
function setFetch(fetch2) {
|
|
9791
10153
|
_internalGetGlobalState().setFetch(fetch2);
|
|
9792
10154
|
}
|
|
9793
|
-
function startSpanAndIsLogger(args) {
|
|
10155
|
+
function startSpanAndIsLogger(args, internalOptions) {
|
|
9794
10156
|
const state = args?.state ?? _globalState;
|
|
9795
10157
|
const { parentObject, propagatedState } = getSpanParentObjectAndPropagatedState({
|
|
9796
10158
|
asyncFlush: args?.asyncFlush,
|
|
@@ -9804,7 +10166,7 @@ function startSpanAndIsLogger(args) {
|
|
|
9804
10166
|
) ? {
|
|
9805
10167
|
spanId: parentObject.data.span_id,
|
|
9806
10168
|
rootSpanId: parentObject.data.root_span_id
|
|
9807
|
-
} : void 0;
|
|
10169
|
+
} : internalOptions?.useParentSpanIdsForObjectParent ? args?.parentSpanIds : void 0;
|
|
9808
10170
|
const { parent: _ignoredParent, ...spanArgs } = args ?? {};
|
|
9809
10171
|
const span = new SpanImpl({
|
|
9810
10172
|
state,
|
|
@@ -9886,27 +10248,28 @@ async function* asyncGeneratorWithCurrent(span, gen, state = void 0) {
|
|
|
9886
10248
|
function withParent(parent, callback, state = void 0) {
|
|
9887
10249
|
return (state ?? _globalState).currentParent.run(parent, () => callback());
|
|
9888
10250
|
}
|
|
9889
|
-
function _saveOrgInfo(state,
|
|
9890
|
-
|
|
10251
|
+
function _saveOrgInfo(state, orgInfo, orgName) {
|
|
10252
|
+
const org = selectLoginOrg(orgInfo, orgName);
|
|
10253
|
+
state.orgId = org.id;
|
|
10254
|
+
state.orgName = org.name;
|
|
10255
|
+
state.apiUrl = isomorph_default.getEnv("BRAINTRUST_API_URL") ?? org.api_url;
|
|
10256
|
+
state.proxyUrl = isomorph_default.getEnv("BRAINTRUST_PROXY_URL") ?? org.proxy_url;
|
|
10257
|
+
state.gitMetadataSettings = org.git_metadata || void 0;
|
|
10258
|
+
}
|
|
10259
|
+
function selectLoginOrg(orgInfo, orgName) {
|
|
10260
|
+
if (orgInfo.length === 0) {
|
|
9891
10261
|
throw new LoginInvalidOrgError(
|
|
9892
10262
|
"This user is not part of any organizations."
|
|
9893
10263
|
);
|
|
9894
10264
|
}
|
|
9895
|
-
for (const org of
|
|
9896
|
-
if (
|
|
9897
|
-
|
|
9898
|
-
state.orgName = org.name;
|
|
9899
|
-
state.apiUrl = isomorph_default.getEnv("BRAINTRUST_API_URL") ?? org.api_url;
|
|
9900
|
-
state.proxyUrl = isomorph_default.getEnv("BRAINTRUST_PROXY_URL") ?? org.proxy_url;
|
|
9901
|
-
state.gitMetadataSettings = org.git_metadata || void 0;
|
|
9902
|
-
break;
|
|
10265
|
+
for (const org of orgInfo) {
|
|
10266
|
+
if (orgName === void 0 || org.name === orgName) {
|
|
10267
|
+
return org;
|
|
9903
10268
|
}
|
|
9904
10269
|
}
|
|
9905
|
-
|
|
9906
|
-
|
|
9907
|
-
|
|
9908
|
-
);
|
|
9909
|
-
}
|
|
10270
|
+
throw new LoginInvalidOrgError(
|
|
10271
|
+
`Organization ${orgName} not found. Must be one of ${orgInfo.map((org) => org.name).join(", ")}`
|
|
10272
|
+
);
|
|
9910
10273
|
}
|
|
9911
10274
|
function validateTags(tags) {
|
|
9912
10275
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -11812,6 +12175,14 @@ var Prompt2 = class _Prompt {
|
|
|
11812
12175
|
static isPrompt(data) {
|
|
11813
12176
|
return typeof data === "object" && data !== null && "__braintrust_prompt_marker" in data;
|
|
11814
12177
|
}
|
|
12178
|
+
/** @internal */
|
|
12179
|
+
_internalSerializeForCache() {
|
|
12180
|
+
return {
|
|
12181
|
+
metadata: this.metadata,
|
|
12182
|
+
defaults: this.defaults,
|
|
12183
|
+
noTrace: this.noTrace
|
|
12184
|
+
};
|
|
12185
|
+
}
|
|
11815
12186
|
static fromPromptData(name, promptData) {
|
|
11816
12187
|
return new _Prompt(
|
|
11817
12188
|
{
|
|
@@ -11852,6 +12223,10 @@ var RemoteEvalParameters = class {
|
|
|
11852
12223
|
get data() {
|
|
11853
12224
|
return this.metadata.function_data.data ?? {};
|
|
11854
12225
|
}
|
|
12226
|
+
/** @internal */
|
|
12227
|
+
_internalSerializeForCache() {
|
|
12228
|
+
return { metadata: this.metadata };
|
|
12229
|
+
}
|
|
11855
12230
|
validate(data) {
|
|
11856
12231
|
if (typeof data !== "object" || data === null) {
|
|
11857
12232
|
return false;
|
|
@@ -12672,56 +13047,14 @@ function suppressionStore() {
|
|
|
12672
13047
|
autoInstrumentationSuppressionStore ??= isomorph_default.newAsyncLocalStorage();
|
|
12673
13048
|
return autoInstrumentationSuppressionStore;
|
|
12674
13049
|
}
|
|
12675
|
-
function currentFrames() {
|
|
12676
|
-
return suppressionStore().getStore()?.frames ?? [];
|
|
12677
|
-
}
|
|
12678
13050
|
function isAutoInstrumentationSuppressed() {
|
|
12679
|
-
|
|
12680
|
-
return frames[frames.length - 1]?.mode === "suppress";
|
|
13051
|
+
return suppressionStore().getStore() === true;
|
|
12681
13052
|
}
|
|
12682
13053
|
function runWithAutoInstrumentationSuppressed(callback) {
|
|
12683
|
-
|
|
12684
|
-
id: /* @__PURE__ */ Symbol("braintrust.auto-instrumentation-suppress"),
|
|
12685
|
-
mode: "suppress"
|
|
12686
|
-
};
|
|
12687
|
-
return suppressionStore().run(
|
|
12688
|
-
{ frames: [...currentFrames(), frame] },
|
|
12689
|
-
callback
|
|
12690
|
-
);
|
|
12691
|
-
}
|
|
12692
|
-
function bindAutoInstrumentationSuppressionToStart(tracingChannel) {
|
|
12693
|
-
const startChannel = tracingChannel.start;
|
|
12694
|
-
if (!startChannel) {
|
|
12695
|
-
return void 0;
|
|
12696
|
-
}
|
|
12697
|
-
const store = suppressionStore();
|
|
12698
|
-
startChannel.bindStore(store, () => ({
|
|
12699
|
-
frames: [
|
|
12700
|
-
...currentFrames(),
|
|
12701
|
-
{
|
|
12702
|
-
id: /* @__PURE__ */ Symbol("braintrust.auto-instrumentation-suppress"),
|
|
12703
|
-
mode: "suppress"
|
|
12704
|
-
}
|
|
12705
|
-
]
|
|
12706
|
-
}));
|
|
12707
|
-
return () => {
|
|
12708
|
-
startChannel.unbindStore(store);
|
|
12709
|
-
};
|
|
13054
|
+
return suppressionStore().run(true, callback);
|
|
12710
13055
|
}
|
|
12711
|
-
function
|
|
12712
|
-
|
|
12713
|
-
id: /* @__PURE__ */ Symbol("braintrust.auto-instrumentation-allow"),
|
|
12714
|
-
mode: "allow"
|
|
12715
|
-
};
|
|
12716
|
-
suppressionStore().enterWith({
|
|
12717
|
-
frames: [...currentFrames(), frame]
|
|
12718
|
-
});
|
|
12719
|
-
return () => {
|
|
12720
|
-
const frames = currentFrames().filter(
|
|
12721
|
-
(candidate) => candidate.id !== frame.id
|
|
12722
|
-
);
|
|
12723
|
-
suppressionStore().enterWith(frames.length > 0 ? { frames } : void 0);
|
|
12724
|
-
};
|
|
13056
|
+
function runWithAutoInstrumentationAllowed(callback) {
|
|
13057
|
+
return suppressionStore().run(void 0, callback);
|
|
12725
13058
|
}
|
|
12726
13059
|
|
|
12727
13060
|
// src/instrumentation/core/channel-tracing.ts
|
|
@@ -13311,6 +13644,131 @@ function unsubscribeAll(unsubscribers) {
|
|
|
13311
13644
|
return [];
|
|
13312
13645
|
}
|
|
13313
13646
|
|
|
13647
|
+
// src/instrumentation/core/channel-definitions.ts
|
|
13648
|
+
function channel(spec) {
|
|
13649
|
+
return spec;
|
|
13650
|
+
}
|
|
13651
|
+
function defineChannels(pkg, channels, options) {
|
|
13652
|
+
const { instrumentationName } = options;
|
|
13653
|
+
return Object.fromEntries(
|
|
13654
|
+
Object.entries(channels).map(([key, spec]) => {
|
|
13655
|
+
const fullChannelName = `orchestrion:${pkg}:${spec.channelName}`;
|
|
13656
|
+
if (spec.kind === "async") {
|
|
13657
|
+
const asyncSpec = spec;
|
|
13658
|
+
const tracingChannel2 = () => isomorph_default.newTracingChannel(
|
|
13659
|
+
fullChannelName
|
|
13660
|
+
);
|
|
13661
|
+
const intercept2 = (interceptor) => {
|
|
13662
|
+
const hook = tracingChannel2();
|
|
13663
|
+
return typeof hook.intercept === "function" ? hook.intercept(interceptor) : () => {
|
|
13664
|
+
};
|
|
13665
|
+
};
|
|
13666
|
+
return [
|
|
13667
|
+
key,
|
|
13668
|
+
{
|
|
13669
|
+
...asyncSpec,
|
|
13670
|
+
instrumentationName,
|
|
13671
|
+
intercept: intercept2,
|
|
13672
|
+
invoke: (target, thisArg, args, additional) => {
|
|
13673
|
+
const hook = tracingChannel2();
|
|
13674
|
+
return typeof hook.invoke === "function" ? hook.invoke(target, thisArg, args, additional) : Reflect.apply(target, thisArg, args);
|
|
13675
|
+
},
|
|
13676
|
+
tracingChannel: tracingChannel2,
|
|
13677
|
+
tracePromise: (fn, context) => tracingChannel2().tracePromise(
|
|
13678
|
+
fn,
|
|
13679
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
13680
|
+
context
|
|
13681
|
+
)
|
|
13682
|
+
}
|
|
13683
|
+
];
|
|
13684
|
+
}
|
|
13685
|
+
const syncSpec = spec;
|
|
13686
|
+
const tracingChannel = () => isomorph_default.newTracingChannel(
|
|
13687
|
+
fullChannelName
|
|
13688
|
+
);
|
|
13689
|
+
const intercept = (interceptor) => {
|
|
13690
|
+
const hook = tracingChannel();
|
|
13691
|
+
return typeof hook.intercept === "function" ? hook.intercept(interceptor) : () => {
|
|
13692
|
+
};
|
|
13693
|
+
};
|
|
13694
|
+
return [
|
|
13695
|
+
key,
|
|
13696
|
+
{
|
|
13697
|
+
...syncSpec,
|
|
13698
|
+
instrumentationName,
|
|
13699
|
+
intercept,
|
|
13700
|
+
invoke: (target, thisArg, args, additional) => {
|
|
13701
|
+
const hook = tracingChannel();
|
|
13702
|
+
return typeof hook.invoke === "function" ? hook.invoke(target, thisArg, args, additional) : Reflect.apply(target, thisArg, args);
|
|
13703
|
+
},
|
|
13704
|
+
tracingChannel,
|
|
13705
|
+
traceSync: (fn, context) => tracingChannel().traceSync(
|
|
13706
|
+
fn,
|
|
13707
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
13708
|
+
context
|
|
13709
|
+
)
|
|
13710
|
+
}
|
|
13711
|
+
];
|
|
13712
|
+
})
|
|
13713
|
+
);
|
|
13714
|
+
}
|
|
13715
|
+
|
|
13716
|
+
// src/instrumentation/plugins/openai-channels.ts
|
|
13717
|
+
var openAIChannels = defineChannels(
|
|
13718
|
+
"openai",
|
|
13719
|
+
{
|
|
13720
|
+
filesCreateTraced: channel({
|
|
13721
|
+
channelName: "files.create-traced",
|
|
13722
|
+
kind: "async"
|
|
13723
|
+
}),
|
|
13724
|
+
batchesRetrieveTraced: channel({
|
|
13725
|
+
channelName: "batches.retrieve-traced",
|
|
13726
|
+
kind: "async"
|
|
13727
|
+
}),
|
|
13728
|
+
batchesCompleteTrace: channel({
|
|
13729
|
+
channelName: "batches.complete-trace",
|
|
13730
|
+
kind: "async"
|
|
13731
|
+
}),
|
|
13732
|
+
chatCompletionsCreate: channel({
|
|
13733
|
+
channelName: "chat.completions.create",
|
|
13734
|
+
kind: "async"
|
|
13735
|
+
}),
|
|
13736
|
+
embeddingsCreate: channel({
|
|
13737
|
+
channelName: "embeddings.create",
|
|
13738
|
+
kind: "async"
|
|
13739
|
+
}),
|
|
13740
|
+
betaChatCompletionsParse: channel({
|
|
13741
|
+
channelName: "beta.chat.completions.parse",
|
|
13742
|
+
kind: "async"
|
|
13743
|
+
}),
|
|
13744
|
+
betaChatCompletionsStream: channel({
|
|
13745
|
+
channelName: "beta.chat.completions.stream",
|
|
13746
|
+
kind: "sync-stream"
|
|
13747
|
+
}),
|
|
13748
|
+
moderationsCreate: channel({
|
|
13749
|
+
channelName: "moderations.create",
|
|
13750
|
+
kind: "async"
|
|
13751
|
+
}),
|
|
13752
|
+
responsesCreate: channel({
|
|
13753
|
+
channelName: "responses.create",
|
|
13754
|
+
kind: "async"
|
|
13755
|
+
}),
|
|
13756
|
+
responsesStream: channel({
|
|
13757
|
+
channelName: "responses.stream",
|
|
13758
|
+
kind: "sync-stream"
|
|
13759
|
+
}),
|
|
13760
|
+
responsesParse: channel({
|
|
13761
|
+
channelName: "responses.parse",
|
|
13762
|
+
kind: "async"
|
|
13763
|
+
}),
|
|
13764
|
+
responsesCompact: channel({
|
|
13765
|
+
channelName: "responses.compact",
|
|
13766
|
+
kind: "async"
|
|
13767
|
+
})
|
|
13768
|
+
},
|
|
13769
|
+
{ instrumentationName: INSTRUMENTATION_NAMES.OPENAI }
|
|
13770
|
+
);
|
|
13771
|
+
|
|
13314
13772
|
// src/wrappers/attachment-utils.ts
|
|
13315
13773
|
function getExtensionFromMediaType(mediaType) {
|
|
13316
13774
|
const extensionMap = {
|
|
@@ -13486,118 +13944,91 @@ function processInputAttachments(input) {
|
|
|
13486
13944
|
return processNode(input);
|
|
13487
13945
|
}
|
|
13488
13946
|
|
|
13489
|
-
// src/instrumentation/
|
|
13490
|
-
|
|
13491
|
-
|
|
13492
|
-
|
|
13493
|
-
|
|
13494
|
-
|
|
13495
|
-
|
|
13496
|
-
|
|
13497
|
-
|
|
13498
|
-
|
|
13499
|
-
|
|
13500
|
-
|
|
13501
|
-
|
|
13502
|
-
|
|
13503
|
-
|
|
13504
|
-
|
|
13505
|
-
|
|
13506
|
-
|
|
13507
|
-
|
|
13508
|
-
|
|
13509
|
-
|
|
13510
|
-
|
|
13511
|
-
...asyncSpec,
|
|
13512
|
-
instrumentationName,
|
|
13513
|
-
intercept: intercept2,
|
|
13514
|
-
invoke: (target, thisArg, args, additional) => {
|
|
13515
|
-
const hook = tracingChannel2();
|
|
13516
|
-
return typeof hook.invoke === "function" ? hook.invoke(target, thisArg, args, additional) : Reflect.apply(target, thisArg, args);
|
|
13517
|
-
},
|
|
13518
|
-
tracingChannel: tracingChannel2,
|
|
13519
|
-
tracePromise: (fn, context) => tracingChannel2().tracePromise(
|
|
13520
|
-
fn,
|
|
13521
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
13522
|
-
context
|
|
13523
|
-
)
|
|
13524
|
-
}
|
|
13525
|
-
];
|
|
13947
|
+
// src/instrumentation/plugins/openai-span-data.ts
|
|
13948
|
+
var OPENAI_METADATA_KEYS = [
|
|
13949
|
+
"model",
|
|
13950
|
+
"temperature",
|
|
13951
|
+
"top_p",
|
|
13952
|
+
"max_tokens",
|
|
13953
|
+
"frequency_penalty",
|
|
13954
|
+
"presence_penalty",
|
|
13955
|
+
"stop",
|
|
13956
|
+
"response_format",
|
|
13957
|
+
"tools",
|
|
13958
|
+
"tool_choice",
|
|
13959
|
+
"parallel_tool_calls",
|
|
13960
|
+
"max_tool_calls"
|
|
13961
|
+
];
|
|
13962
|
+
function batchMetadata(params) {
|
|
13963
|
+
const metadata = { provider: "openai" };
|
|
13964
|
+
for (const key of OPENAI_METADATA_KEYS) {
|
|
13965
|
+
try {
|
|
13966
|
+
const value = Reflect.get(params, key);
|
|
13967
|
+
if (value !== void 0) {
|
|
13968
|
+
metadata[key] = value;
|
|
13526
13969
|
}
|
|
13527
|
-
|
|
13528
|
-
|
|
13529
|
-
|
|
13530
|
-
|
|
13531
|
-
|
|
13532
|
-
|
|
13533
|
-
|
|
13534
|
-
|
|
13535
|
-
|
|
13536
|
-
|
|
13537
|
-
|
|
13538
|
-
|
|
13539
|
-
|
|
13540
|
-
|
|
13541
|
-
|
|
13542
|
-
|
|
13543
|
-
|
|
13544
|
-
|
|
13545
|
-
|
|
13546
|
-
|
|
13547
|
-
|
|
13548
|
-
|
|
13549
|
-
|
|
13550
|
-
|
|
13551
|
-
|
|
13552
|
-
|
|
13553
|
-
|
|
13554
|
-
|
|
13555
|
-
|
|
13970
|
+
} catch {
|
|
13971
|
+
}
|
|
13972
|
+
}
|
|
13973
|
+
return metadata;
|
|
13974
|
+
}
|
|
13975
|
+
function extractOpenAIBatchInput(endpoint, params) {
|
|
13976
|
+
const input = endpoint === "/v1/chat/completions" ? params.messages : params.input;
|
|
13977
|
+
return {
|
|
13978
|
+
input: processInputAttachments(input),
|
|
13979
|
+
metadata: batchMetadata(params)
|
|
13980
|
+
};
|
|
13981
|
+
}
|
|
13982
|
+
function extractOpenAIChatInput(params) {
|
|
13983
|
+
const { messages, ...metadata } = params;
|
|
13984
|
+
return {
|
|
13985
|
+
input: processInputAttachments(messages),
|
|
13986
|
+
metadata: { ...metadata, provider: "openai" }
|
|
13987
|
+
};
|
|
13988
|
+
}
|
|
13989
|
+
function extractOpenAIResponsesInput(params) {
|
|
13990
|
+
const { input, ...metadata } = params;
|
|
13991
|
+
return {
|
|
13992
|
+
input: processInputAttachments(input),
|
|
13993
|
+
metadata: { ...metadata, provider: "openai" }
|
|
13994
|
+
};
|
|
13995
|
+
}
|
|
13996
|
+
function extractOpenAIResponsesMetadata(result) {
|
|
13997
|
+
if (!result) {
|
|
13998
|
+
return void 0;
|
|
13999
|
+
}
|
|
14000
|
+
const { output: _output, usage: _usage, ...metadata } = result;
|
|
14001
|
+
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
14002
|
+
}
|
|
14003
|
+
function processImagesInOutput(output) {
|
|
14004
|
+
if (Array.isArray(output)) {
|
|
14005
|
+
return output.map(processImagesInOutput);
|
|
14006
|
+
}
|
|
14007
|
+
if (isObject(output) && output.type === "image_generation_call" && typeof output.result === "string" && output.result) {
|
|
14008
|
+
const fileExtension = output.output_format || "png";
|
|
14009
|
+
const contentType = `image/${fileExtension}`;
|
|
14010
|
+
const baseFilename = typeof output.revised_prompt === "string" ? output.revised_prompt.slice(0, 50).replace(/[^a-zA-Z0-9]/g, "_") : "generated_image";
|
|
14011
|
+
let binaryString;
|
|
14012
|
+
try {
|
|
14013
|
+
binaryString = atob(output.result);
|
|
14014
|
+
} catch {
|
|
14015
|
+
return output;
|
|
14016
|
+
}
|
|
14017
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
14018
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
14019
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
14020
|
+
}
|
|
14021
|
+
return {
|
|
14022
|
+
...output,
|
|
14023
|
+
result: new Attachment({
|
|
14024
|
+
data: new Blob([bytes], { type: contentType }),
|
|
14025
|
+
filename: `${baseFilename}.${fileExtension}`,
|
|
14026
|
+
contentType
|
|
14027
|
+
})
|
|
14028
|
+
};
|
|
14029
|
+
}
|
|
14030
|
+
return output;
|
|
13556
14031
|
}
|
|
13557
|
-
|
|
13558
|
-
// src/instrumentation/plugins/openai-channels.ts
|
|
13559
|
-
var openAIChannels = defineChannels(
|
|
13560
|
-
"openai",
|
|
13561
|
-
{
|
|
13562
|
-
chatCompletionsCreate: channel({
|
|
13563
|
-
channelName: "chat.completions.create",
|
|
13564
|
-
kind: "async"
|
|
13565
|
-
}),
|
|
13566
|
-
embeddingsCreate: channel({
|
|
13567
|
-
channelName: "embeddings.create",
|
|
13568
|
-
kind: "async"
|
|
13569
|
-
}),
|
|
13570
|
-
betaChatCompletionsParse: channel({
|
|
13571
|
-
channelName: "beta.chat.completions.parse",
|
|
13572
|
-
kind: "async"
|
|
13573
|
-
}),
|
|
13574
|
-
betaChatCompletionsStream: channel({
|
|
13575
|
-
channelName: "beta.chat.completions.stream",
|
|
13576
|
-
kind: "sync-stream"
|
|
13577
|
-
}),
|
|
13578
|
-
moderationsCreate: channel({
|
|
13579
|
-
channelName: "moderations.create",
|
|
13580
|
-
kind: "async"
|
|
13581
|
-
}),
|
|
13582
|
-
responsesCreate: channel({
|
|
13583
|
-
channelName: "responses.create",
|
|
13584
|
-
kind: "async"
|
|
13585
|
-
}),
|
|
13586
|
-
responsesStream: channel({
|
|
13587
|
-
channelName: "responses.stream",
|
|
13588
|
-
kind: "sync-stream"
|
|
13589
|
-
}),
|
|
13590
|
-
responsesParse: channel({
|
|
13591
|
-
channelName: "responses.parse",
|
|
13592
|
-
kind: "async"
|
|
13593
|
-
}),
|
|
13594
|
-
responsesCompact: channel({
|
|
13595
|
-
channelName: "responses.compact",
|
|
13596
|
-
kind: "async"
|
|
13597
|
-
})
|
|
13598
|
-
},
|
|
13599
|
-
{ instrumentationName: INSTRUMENTATION_NAMES.OPENAI }
|
|
13600
|
-
);
|
|
13601
14032
|
|
|
13602
14033
|
// src/openai-utils.ts
|
|
13603
14034
|
var BRAINTRUST_CACHED_STREAM_METRIC = "__braintrust_cached_metric";
|
|
@@ -13654,23 +14085,573 @@ function getCachedMetricFromHeaders(headers) {
|
|
|
13654
14085
|
return parseCachedHeader(headers.get(LEGACY_CACHED_HEADER));
|
|
13655
14086
|
}
|
|
13656
14087
|
|
|
14088
|
+
// src/instrumentation/plugins/openai-batch-instrumentation.ts
|
|
14089
|
+
var SUPPORTED_ENDPOINTS = /* @__PURE__ */ new Set(["/v1/chat/completions", "/v1/responses"]);
|
|
14090
|
+
var TERMINAL_STATUSES = /* @__PURE__ */ new Set([
|
|
14091
|
+
"completed",
|
|
14092
|
+
"failed",
|
|
14093
|
+
"expired",
|
|
14094
|
+
"cancelled"
|
|
14095
|
+
]);
|
|
14096
|
+
var pendingBatchTraces = /* @__PURE__ */ new Map();
|
|
14097
|
+
function read(value, key) {
|
|
14098
|
+
if (!isObject(value)) {
|
|
14099
|
+
return void 0;
|
|
14100
|
+
}
|
|
14101
|
+
try {
|
|
14102
|
+
return Reflect.get(value, key);
|
|
14103
|
+
} catch {
|
|
14104
|
+
return void 0;
|
|
14105
|
+
}
|
|
14106
|
+
}
|
|
14107
|
+
function isBatchRecordIterable(value) {
|
|
14108
|
+
if (value === null || typeof value !== "object" && typeof value !== "function") {
|
|
14109
|
+
return false;
|
|
14110
|
+
}
|
|
14111
|
+
return typeof read(value, Symbol.iterator) === "function" || typeof read(value, Symbol.asyncIterator) === "function";
|
|
14112
|
+
}
|
|
14113
|
+
function validCustomId(value) {
|
|
14114
|
+
return typeof value === "string" && value.length > 0 && value.length <= 64;
|
|
14115
|
+
}
|
|
14116
|
+
function logBatchInstrumentationError(context, error) {
|
|
14117
|
+
debugLogger.debug(`OpenAI Batch instrumentation ${context}:`, error);
|
|
14118
|
+
}
|
|
14119
|
+
async function exportParent(parent) {
|
|
14120
|
+
if ("toStr" in parent && typeof parent.toStr === "function") {
|
|
14121
|
+
return parent.toStr();
|
|
14122
|
+
}
|
|
14123
|
+
if ("export" in parent && typeof parent.export === "function") {
|
|
14124
|
+
return await parent.export();
|
|
14125
|
+
}
|
|
14126
|
+
return void 0;
|
|
14127
|
+
}
|
|
14128
|
+
async function deterministicDigest(namespace, ...parts) {
|
|
14129
|
+
const encoded = new TextEncoder().encode(
|
|
14130
|
+
[namespace, ...parts].map((part) => `${part.length}:${part}`).join("\0")
|
|
14131
|
+
);
|
|
14132
|
+
return new Uint8Array(
|
|
14133
|
+
await globalThis.crypto.subtle.digest("SHA-256", encoded)
|
|
14134
|
+
);
|
|
14135
|
+
}
|
|
14136
|
+
function digestHex(bytes, length) {
|
|
14137
|
+
return Array.from(bytes.slice(0, length)).map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
14138
|
+
}
|
|
14139
|
+
function digestUuid(bytes) {
|
|
14140
|
+
const hex = digestHex(bytes, 16);
|
|
14141
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
14142
|
+
}
|
|
14143
|
+
async function batchSpanIds(inputFileId) {
|
|
14144
|
+
const [row, span, root] = await Promise.all([
|
|
14145
|
+
deterministicDigest("openai:batch:row", inputFileId),
|
|
14146
|
+
deterministicDigest("openai:batch:span", inputFileId),
|
|
14147
|
+
deterministicDigest("openai:batch:root", inputFileId)
|
|
14148
|
+
]);
|
|
14149
|
+
return {
|
|
14150
|
+
rowId: digestUuid(row),
|
|
14151
|
+
spanId: digestHex(span, 8),
|
|
14152
|
+
rootSpanId: digestHex(root, 16)
|
|
14153
|
+
};
|
|
14154
|
+
}
|
|
14155
|
+
async function childSpanIds(inputFileId, customId) {
|
|
14156
|
+
const [row, span] = await Promise.all([
|
|
14157
|
+
deterministicDigest("openai:batch:child:row", inputFileId, customId),
|
|
14158
|
+
deterministicDigest("openai:batch:child:span", inputFileId, customId)
|
|
14159
|
+
]);
|
|
14160
|
+
return { rowId: digestUuid(row), spanId: digestHex(span, 8) };
|
|
14161
|
+
}
|
|
14162
|
+
async function startBatchSpan(context) {
|
|
14163
|
+
const ids = await batchSpanIds(context.inputFileId);
|
|
14164
|
+
const parent = SpanComponentsV4.fromStr(context.parent);
|
|
14165
|
+
const hasParentSpan = Boolean(
|
|
14166
|
+
parent.data.row_id && parent.data.span_id && parent.data.root_span_id
|
|
14167
|
+
);
|
|
14168
|
+
return withCurrent(
|
|
14169
|
+
NOOP_SPAN,
|
|
14170
|
+
() => _internalStartSpanWithInitialMergeAndParentSpanIds(
|
|
14171
|
+
withSpanInstrumentationName(
|
|
14172
|
+
{
|
|
14173
|
+
name: "openai.batch",
|
|
14174
|
+
type: "task" /* TASK */,
|
|
14175
|
+
parent: context.parent,
|
|
14176
|
+
...!hasParentSpan ? {
|
|
14177
|
+
parentSpanIds: {
|
|
14178
|
+
parentSpanIds: [],
|
|
14179
|
+
rootSpanId: ids.rootSpanId
|
|
14180
|
+
}
|
|
14181
|
+
} : {},
|
|
14182
|
+
spanId: ids.spanId,
|
|
14183
|
+
startTime: context.taskStartTime,
|
|
14184
|
+
event: {
|
|
14185
|
+
id: ids.rowId,
|
|
14186
|
+
metadata: {
|
|
14187
|
+
endpoint: context.endpoint,
|
|
14188
|
+
input_file_id: context.inputFileId,
|
|
14189
|
+
provider: "openai"
|
|
14190
|
+
}
|
|
14191
|
+
}
|
|
14192
|
+
},
|
|
14193
|
+
INSTRUMENTATION_NAMES.OPENAI
|
|
14194
|
+
)
|
|
14195
|
+
)
|
|
14196
|
+
);
|
|
14197
|
+
}
|
|
14198
|
+
async function startBatchChild(context, taskParent, input) {
|
|
14199
|
+
const ids = await childSpanIds(context.inputFileId, input.customId);
|
|
14200
|
+
return withCurrent(
|
|
14201
|
+
NOOP_SPAN,
|
|
14202
|
+
() => _internalStartSpanWithInitialMerge(
|
|
14203
|
+
withSpanInstrumentationName(
|
|
14204
|
+
{
|
|
14205
|
+
name: context.endpoint === "/v1/chat/completions" ? "Chat Completion" : "openai.responses.create",
|
|
14206
|
+
type: "llm" /* LLM */,
|
|
14207
|
+
parent: taskParent,
|
|
14208
|
+
spanId: ids.spanId,
|
|
14209
|
+
startTime: context.childStartTime,
|
|
14210
|
+
event: {
|
|
14211
|
+
id: ids.rowId,
|
|
14212
|
+
...input.spanData?.input !== void 0 ? { input: input.spanData.input } : {},
|
|
14213
|
+
metadata: {
|
|
14214
|
+
...input.spanData?.metadata,
|
|
14215
|
+
custom_id: input.customId,
|
|
14216
|
+
provider: "openai"
|
|
14217
|
+
}
|
|
14218
|
+
}
|
|
14219
|
+
},
|
|
14220
|
+
INSTRUMENTATION_NAMES.OPENAI
|
|
14221
|
+
)
|
|
14222
|
+
)
|
|
14223
|
+
);
|
|
14224
|
+
}
|
|
14225
|
+
async function* jsonlRecords(file, onIssue = () => {
|
|
14226
|
+
}) {
|
|
14227
|
+
const resolvedFile = await file;
|
|
14228
|
+
if (typeof resolvedFile === "string") {
|
|
14229
|
+
for (const line of resolvedFile.split("\n")) {
|
|
14230
|
+
if (!line.trim()) {
|
|
14231
|
+
continue;
|
|
14232
|
+
}
|
|
14233
|
+
try {
|
|
14234
|
+
yield JSON.parse(line.replace(/\r$/, ""));
|
|
14235
|
+
} catch (error) {
|
|
14236
|
+
logBatchInstrumentationError("skipped malformed JSONL", error);
|
|
14237
|
+
onIssue(new Error("OpenAI Batch file contains malformed JSONL"));
|
|
14238
|
+
}
|
|
14239
|
+
}
|
|
14240
|
+
return;
|
|
14241
|
+
}
|
|
14242
|
+
const body = read(resolvedFile, "body");
|
|
14243
|
+
const getReader = read(body, "getReader");
|
|
14244
|
+
if (isObject(body) && typeof getReader === "function") {
|
|
14245
|
+
let reader;
|
|
14246
|
+
try {
|
|
14247
|
+
reader = Reflect.apply(getReader, body, []);
|
|
14248
|
+
const decoder2 = new TextDecoder();
|
|
14249
|
+
let pending = "";
|
|
14250
|
+
while (true) {
|
|
14251
|
+
const readChunk = read(reader, "read");
|
|
14252
|
+
if (typeof readChunk !== "function") {
|
|
14253
|
+
throw new Error("Response body stream has no read method");
|
|
14254
|
+
}
|
|
14255
|
+
const chunk = await Reflect.apply(readChunk, reader, []);
|
|
14256
|
+
if (!isObject(chunk)) {
|
|
14257
|
+
throw new Error("Response body stream returned an invalid chunk");
|
|
14258
|
+
}
|
|
14259
|
+
if (chunk.done === true) {
|
|
14260
|
+
pending += decoder2.decode();
|
|
14261
|
+
break;
|
|
14262
|
+
}
|
|
14263
|
+
if (!(chunk.value instanceof Uint8Array)) {
|
|
14264
|
+
throw new Error("Response body stream returned a non-byte chunk");
|
|
14265
|
+
}
|
|
14266
|
+
pending += decoder2.decode(chunk.value, { stream: true });
|
|
14267
|
+
let newline = pending.indexOf("\n");
|
|
14268
|
+
while (newline !== -1) {
|
|
14269
|
+
const line = pending.slice(0, newline).replace(/\r$/, "");
|
|
14270
|
+
pending = pending.slice(newline + 1);
|
|
14271
|
+
if (line.trim()) {
|
|
14272
|
+
try {
|
|
14273
|
+
yield JSON.parse(line);
|
|
14274
|
+
} catch (error) {
|
|
14275
|
+
logBatchInstrumentationError("skipped malformed JSONL", error);
|
|
14276
|
+
onIssue(new Error("OpenAI Batch file contains malformed JSONL"));
|
|
14277
|
+
}
|
|
14278
|
+
}
|
|
14279
|
+
newline = pending.indexOf("\n");
|
|
14280
|
+
}
|
|
14281
|
+
}
|
|
14282
|
+
if (pending.trim()) {
|
|
14283
|
+
try {
|
|
14284
|
+
yield JSON.parse(pending.replace(/\r$/, ""));
|
|
14285
|
+
} catch (error) {
|
|
14286
|
+
logBatchInstrumentationError("skipped malformed JSONL", error);
|
|
14287
|
+
onIssue(new Error("OpenAI Batch file contains malformed JSONL"));
|
|
14288
|
+
}
|
|
14289
|
+
}
|
|
14290
|
+
} catch (error) {
|
|
14291
|
+
logBatchInstrumentationError("could not read JSONL response body", error);
|
|
14292
|
+
onIssue(new Error("OpenAI Batch response body could not be read"));
|
|
14293
|
+
} finally {
|
|
14294
|
+
const releaseLock = read(reader, "releaseLock");
|
|
14295
|
+
if (typeof releaseLock === "function") {
|
|
14296
|
+
try {
|
|
14297
|
+
Reflect.apply(releaseLock, reader, []);
|
|
14298
|
+
} catch (error) {
|
|
14299
|
+
logBatchInstrumentationError(
|
|
14300
|
+
"could not release stream reader",
|
|
14301
|
+
error
|
|
14302
|
+
);
|
|
14303
|
+
}
|
|
14304
|
+
}
|
|
14305
|
+
}
|
|
14306
|
+
return;
|
|
14307
|
+
}
|
|
14308
|
+
if (isBatchRecordIterable(resolvedFile)) {
|
|
14309
|
+
for await (const record of resolvedFile) {
|
|
14310
|
+
yield record;
|
|
14311
|
+
}
|
|
14312
|
+
return;
|
|
14313
|
+
}
|
|
14314
|
+
logBatchInstrumentationError("skipped invalid JSONL source", resolvedFile);
|
|
14315
|
+
onIssue(new Error("OpenAI Batch file source is invalid"));
|
|
14316
|
+
}
|
|
14317
|
+
async function readBatchInputs(file) {
|
|
14318
|
+
const inputs = /* @__PURE__ */ new Map();
|
|
14319
|
+
const issues = [];
|
|
14320
|
+
let endpoint;
|
|
14321
|
+
try {
|
|
14322
|
+
for await (const value of jsonlRecords(
|
|
14323
|
+
file,
|
|
14324
|
+
(issue) => issues.push(issue)
|
|
14325
|
+
)) {
|
|
14326
|
+
const customId = read(value, "custom_id");
|
|
14327
|
+
const url = read(value, "url");
|
|
14328
|
+
const body = read(value, "body");
|
|
14329
|
+
if (!validCustomId(customId) || inputs.has(customId) || read(value, "method") !== "POST" || typeof url !== "string" || !SUPPORTED_ENDPOINTS.has(url) || endpoint !== void 0 && endpoint !== url || !isObject(body)) {
|
|
14330
|
+
issues.push(new Error("OpenAI Batch input contains an invalid record"));
|
|
14331
|
+
continue;
|
|
14332
|
+
}
|
|
14333
|
+
endpoint = url;
|
|
14334
|
+
let spanData;
|
|
14335
|
+
try {
|
|
14336
|
+
spanData = extractOpenAIBatchInput(url, body);
|
|
14337
|
+
} catch (error) {
|
|
14338
|
+
logBatchInstrumentationError("could not extract batch input", error);
|
|
14339
|
+
}
|
|
14340
|
+
inputs.set(customId, { customId, spanData });
|
|
14341
|
+
}
|
|
14342
|
+
} catch (error) {
|
|
14343
|
+
logBatchInstrumentationError("could not process input file", error);
|
|
14344
|
+
issues.push(new Error("OpenAI Batch input file could not be processed"));
|
|
14345
|
+
}
|
|
14346
|
+
if (!endpoint || inputs.size === 0) {
|
|
14347
|
+
issues.push(new Error("OpenAI Batch input contains no supported records"));
|
|
14348
|
+
}
|
|
14349
|
+
return { endpoint, inputs, issues };
|
|
14350
|
+
}
|
|
14351
|
+
async function writePendingSpans(trace, endTime) {
|
|
14352
|
+
const task = await startBatchSpan(trace.context);
|
|
14353
|
+
const taskParent = await task.export();
|
|
14354
|
+
for (const input of trace.inputs.values()) {
|
|
14355
|
+
try {
|
|
14356
|
+
const child = await startBatchChild(trace.context, taskParent, input);
|
|
14357
|
+
if (endTime !== void 0) {
|
|
14358
|
+
child.end({ endTime });
|
|
14359
|
+
}
|
|
14360
|
+
} catch (error) {
|
|
14361
|
+
logBatchInstrumentationError("could not write batch request span", error);
|
|
14362
|
+
}
|
|
14363
|
+
}
|
|
14364
|
+
if (endTime !== void 0) {
|
|
14365
|
+
if (trace.status && trace.status !== "completed") {
|
|
14366
|
+
task.log({ error: new Error(`OpenAI Batch ${trace.status}`) });
|
|
14367
|
+
}
|
|
14368
|
+
task.end({ endTime });
|
|
14369
|
+
}
|
|
14370
|
+
}
|
|
14371
|
+
var interceptOpenAIFilesCreateTraced = async (target, thisArg, args) => {
|
|
14372
|
+
const startTime = getCurrentUnixTimestamp();
|
|
14373
|
+
const inputPromise = readBatchInputs(args[0].inputFileContent);
|
|
14374
|
+
const parentPromise = exportParent(args[0].parent);
|
|
14375
|
+
const file = await Reflect.apply(target, thisArg, args);
|
|
14376
|
+
try {
|
|
14377
|
+
const inputFileId = read(file, "id");
|
|
14378
|
+
const [inputData, exportedParent2] = await Promise.all([
|
|
14379
|
+
inputPromise,
|
|
14380
|
+
parentPromise
|
|
14381
|
+
]);
|
|
14382
|
+
if (typeof inputFileId !== "string" || !exportedParent2 || !inputData.endpoint || inputData.issues.length > 0) {
|
|
14383
|
+
if (inputData.issues[0]) {
|
|
14384
|
+
logBatchInstrumentationError(
|
|
14385
|
+
"skipped invalid input file",
|
|
14386
|
+
inputData.issues[0]
|
|
14387
|
+
);
|
|
14388
|
+
}
|
|
14389
|
+
return file;
|
|
14390
|
+
}
|
|
14391
|
+
const trace = {
|
|
14392
|
+
context: {
|
|
14393
|
+
inputFileId,
|
|
14394
|
+
endpoint: inputData.endpoint,
|
|
14395
|
+
parent: exportedParent2,
|
|
14396
|
+
taskStartTime: startTime,
|
|
14397
|
+
childStartTime: startTime
|
|
14398
|
+
},
|
|
14399
|
+
inputs: inputData.inputs
|
|
14400
|
+
};
|
|
14401
|
+
pendingBatchTraces.set(inputFileId, trace);
|
|
14402
|
+
await writePendingSpans(trace);
|
|
14403
|
+
} catch (error) {
|
|
14404
|
+
logBatchInstrumentationError("could not start batch spans", error);
|
|
14405
|
+
}
|
|
14406
|
+
return file;
|
|
14407
|
+
};
|
|
14408
|
+
function validTimestamp(value) {
|
|
14409
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0;
|
|
14410
|
+
}
|
|
14411
|
+
function terminalEndTime(batch, startTime) {
|
|
14412
|
+
let timestamp;
|
|
14413
|
+
switch (batch.status) {
|
|
14414
|
+
case "completed":
|
|
14415
|
+
timestamp = batch.completed_at;
|
|
14416
|
+
break;
|
|
14417
|
+
case "failed":
|
|
14418
|
+
timestamp = batch.failed_at;
|
|
14419
|
+
break;
|
|
14420
|
+
case "expired":
|
|
14421
|
+
timestamp = batch.expired_at;
|
|
14422
|
+
break;
|
|
14423
|
+
default:
|
|
14424
|
+
timestamp = batch.cancelled_at;
|
|
14425
|
+
}
|
|
14426
|
+
return validTimestamp(timestamp) ? Math.max(timestamp, startTime) : Math.max(getCurrentUnixTimestamp(), startTime);
|
|
14427
|
+
}
|
|
14428
|
+
async function updateBatchTimestamps(batch) {
|
|
14429
|
+
const trace = pendingBatchTraces.get(batch.input_file_id);
|
|
14430
|
+
if (!trace || trace.context.endpoint !== batch.endpoint) {
|
|
14431
|
+
return;
|
|
14432
|
+
}
|
|
14433
|
+
if (validTimestamp(batch.created_at)) {
|
|
14434
|
+
trace.context.taskStartTime = batch.created_at;
|
|
14435
|
+
}
|
|
14436
|
+
trace.context.childStartTime = validTimestamp(batch.in_progress_at) ? Math.max(batch.in_progress_at, trace.context.taskStartTime) : trace.context.taskStartTime;
|
|
14437
|
+
trace.status = batch.status;
|
|
14438
|
+
if (TERMINAL_STATUSES.has(batch.status)) {
|
|
14439
|
+
trace.endTime = terminalEndTime(batch, trace.context.childStartTime);
|
|
14440
|
+
}
|
|
14441
|
+
await writePendingSpans(trace, trace.endTime);
|
|
14442
|
+
}
|
|
14443
|
+
var interceptOpenAIBatchesRetrieveTraced = (target, thisArg, args) => Promise.resolve(Reflect.apply(target, thisArg, args)).then(async (batch) => {
|
|
14444
|
+
try {
|
|
14445
|
+
await updateBatchTimestamps(batch);
|
|
14446
|
+
} catch (error) {
|
|
14447
|
+
logBatchInstrumentationError("could not update batch timestamps", error);
|
|
14448
|
+
}
|
|
14449
|
+
return batch;
|
|
14450
|
+
});
|
|
14451
|
+
function errorFromResult(result) {
|
|
14452
|
+
const error = read(result.value, "error");
|
|
14453
|
+
if (isObject(error)) {
|
|
14454
|
+
const message = read(error, "message");
|
|
14455
|
+
return new Error(
|
|
14456
|
+
typeof message === "string" ? message : "OpenAI Batch request failed"
|
|
14457
|
+
);
|
|
14458
|
+
}
|
|
14459
|
+
const response = read(result.value, "response");
|
|
14460
|
+
const statusCode = read(response, "status_code");
|
|
14461
|
+
if (result.source === "error" || typeof statusCode === "number" && (statusCode < 200 || statusCode >= 300)) {
|
|
14462
|
+
const message = read(read(read(response, "body"), "error"), "message");
|
|
14463
|
+
return new Error(
|
|
14464
|
+
typeof message === "string" ? message : "OpenAI Batch request failed"
|
|
14465
|
+
);
|
|
14466
|
+
}
|
|
14467
|
+
return void 0;
|
|
14468
|
+
}
|
|
14469
|
+
async function completeBatchResult(context, taskParent, endTime, input, result) {
|
|
14470
|
+
const child = await startBatchChild(context, taskParent, input);
|
|
14471
|
+
try {
|
|
14472
|
+
const resultError = errorFromResult(result);
|
|
14473
|
+
const responseBody = read(read(result.value, "response"), "body");
|
|
14474
|
+
if (resultError) {
|
|
14475
|
+
child.log({ error: resultError });
|
|
14476
|
+
} else if (isObject(responseBody)) {
|
|
14477
|
+
const model = read(responseBody, "model");
|
|
14478
|
+
child.log({
|
|
14479
|
+
output: context.endpoint === "/v1/chat/completions" ? read(responseBody, "choices") : processImagesInOutput(read(responseBody, "output")),
|
|
14480
|
+
...typeof model === "string" ? { metadata: { model } } : {},
|
|
14481
|
+
metrics: parseMetricsFromUsage(read(responseBody, "usage"))
|
|
14482
|
+
});
|
|
14483
|
+
} else {
|
|
14484
|
+
child.log({ error: new Error("OpenAI Batch response body is missing") });
|
|
14485
|
+
}
|
|
14486
|
+
} catch (error) {
|
|
14487
|
+
child.log({ error });
|
|
14488
|
+
} finally {
|
|
14489
|
+
child.end({ endTime });
|
|
14490
|
+
}
|
|
14491
|
+
}
|
|
14492
|
+
async function completeResultFile({
|
|
14493
|
+
context,
|
|
14494
|
+
endTime,
|
|
14495
|
+
file,
|
|
14496
|
+
inputs,
|
|
14497
|
+
issues,
|
|
14498
|
+
seen,
|
|
14499
|
+
source,
|
|
14500
|
+
taskParent
|
|
14501
|
+
}) {
|
|
14502
|
+
if (file === void 0) {
|
|
14503
|
+
return;
|
|
14504
|
+
}
|
|
14505
|
+
for await (const value of jsonlRecords(file, (issue) => issues.push(issue))) {
|
|
14506
|
+
const customId = read(value, "custom_id");
|
|
14507
|
+
if (!validCustomId(customId) || !isObject(value)) {
|
|
14508
|
+
issues.push(
|
|
14509
|
+
new Error("OpenAI Batch result is missing a valid custom_id")
|
|
14510
|
+
);
|
|
14511
|
+
continue;
|
|
14512
|
+
}
|
|
14513
|
+
if (seen.has(customId)) {
|
|
14514
|
+
issues.push(new Error("OpenAI Batch result contains a duplicate"));
|
|
14515
|
+
continue;
|
|
14516
|
+
}
|
|
14517
|
+
const input = inputs.get(customId);
|
|
14518
|
+
if (!input) {
|
|
14519
|
+
issues.push(
|
|
14520
|
+
new Error("OpenAI Batch result does not match an input record")
|
|
14521
|
+
);
|
|
14522
|
+
continue;
|
|
14523
|
+
}
|
|
14524
|
+
seen.add(customId);
|
|
14525
|
+
await completeBatchResult(context, taskParent, endTime, input, {
|
|
14526
|
+
value,
|
|
14527
|
+
source
|
|
14528
|
+
});
|
|
14529
|
+
}
|
|
14530
|
+
}
|
|
14531
|
+
function sameInputs(first, second) {
|
|
14532
|
+
return first.size === second.size && [...first.keys()].every((customId) => second.has(customId));
|
|
14533
|
+
}
|
|
14534
|
+
async function contextForCompletion(inputFileId, inputData) {
|
|
14535
|
+
if (!inputData.endpoint || inputData.issues.length > 0) {
|
|
14536
|
+
return void 0;
|
|
14537
|
+
}
|
|
14538
|
+
const existing = pendingBatchTraces.get(inputFileId);
|
|
14539
|
+
if (existing) {
|
|
14540
|
+
if (existing.context.endpoint !== inputData.endpoint || !sameInputs(existing.inputs, inputData.inputs)) {
|
|
14541
|
+
return void 0;
|
|
14542
|
+
}
|
|
14543
|
+
return { ...existing, inputs: inputData.inputs };
|
|
14544
|
+
}
|
|
14545
|
+
const parent = await exportParent(getSpanParentObject());
|
|
14546
|
+
if (!parent) {
|
|
14547
|
+
return void 0;
|
|
14548
|
+
}
|
|
14549
|
+
const startTime = getCurrentUnixTimestamp();
|
|
14550
|
+
return {
|
|
14551
|
+
context: {
|
|
14552
|
+
inputFileId,
|
|
14553
|
+
endpoint: inputData.endpoint,
|
|
14554
|
+
parent,
|
|
14555
|
+
taskStartTime: startTime,
|
|
14556
|
+
childStartTime: startTime
|
|
14557
|
+
},
|
|
14558
|
+
inputs: inputData.inputs
|
|
14559
|
+
};
|
|
14560
|
+
}
|
|
14561
|
+
async function completeBatch(args) {
|
|
14562
|
+
const inputData = await readBatchInputs(args.inputFileContent);
|
|
14563
|
+
const trace = await contextForCompletion(args.inputFileId, inputData);
|
|
14564
|
+
if (!trace) {
|
|
14565
|
+
logBatchInstrumentationError(
|
|
14566
|
+
"left batch spans pending",
|
|
14567
|
+
inputData.issues[0] ?? new Error("OpenAI Batch input does not match")
|
|
14568
|
+
);
|
|
14569
|
+
return;
|
|
14570
|
+
}
|
|
14571
|
+
const endTime = trace.endTime ?? getCurrentUnixTimestamp();
|
|
14572
|
+
const task = await startBatchSpan(trace.context);
|
|
14573
|
+
const taskParent = await task.export();
|
|
14574
|
+
const issues = [];
|
|
14575
|
+
const seen = /* @__PURE__ */ new Set();
|
|
14576
|
+
await Promise.all([
|
|
14577
|
+
completeResultFile({
|
|
14578
|
+
context: trace.context,
|
|
14579
|
+
endTime,
|
|
14580
|
+
file: args.outputFileContent,
|
|
14581
|
+
inputs: trace.inputs,
|
|
14582
|
+
issues,
|
|
14583
|
+
seen,
|
|
14584
|
+
source: "output",
|
|
14585
|
+
taskParent
|
|
14586
|
+
}),
|
|
14587
|
+
completeResultFile({
|
|
14588
|
+
context: trace.context,
|
|
14589
|
+
endTime,
|
|
14590
|
+
file: args.errorFileContent,
|
|
14591
|
+
inputs: trace.inputs,
|
|
14592
|
+
issues,
|
|
14593
|
+
seen,
|
|
14594
|
+
source: "error",
|
|
14595
|
+
taskParent
|
|
14596
|
+
})
|
|
14597
|
+
]);
|
|
14598
|
+
if (issues.length > 0) {
|
|
14599
|
+
logBatchInstrumentationError("left batch spans pending", issues[0]);
|
|
14600
|
+
return;
|
|
14601
|
+
}
|
|
14602
|
+
const missing = [...trace.inputs.values()].filter(
|
|
14603
|
+
({ customId }) => !seen.has(customId)
|
|
14604
|
+
);
|
|
14605
|
+
if (!trace.status || trace.status === "completed") {
|
|
14606
|
+
if (missing.length > 0) {
|
|
14607
|
+
logBatchInstrumentationError(
|
|
14608
|
+
"left batch spans pending",
|
|
14609
|
+
new Error("OpenAI Batch result files are incomplete")
|
|
14610
|
+
);
|
|
14611
|
+
return;
|
|
14612
|
+
}
|
|
14613
|
+
} else {
|
|
14614
|
+
for (const input of missing) {
|
|
14615
|
+
const child = await startBatchChild(trace.context, taskParent, input);
|
|
14616
|
+
child.log({ error: new Error(`OpenAI Batch ${trace.status}`) });
|
|
14617
|
+
child.end({ endTime });
|
|
14618
|
+
}
|
|
14619
|
+
task.log({ error: new Error(`OpenAI Batch ${trace.status}`) });
|
|
14620
|
+
}
|
|
14621
|
+
task.end({ endTime });
|
|
14622
|
+
pendingBatchTraces.delete(args.inputFileId);
|
|
14623
|
+
}
|
|
14624
|
+
var interceptOpenAIBatchTraceComplete = (target, thisArg, args) => Promise.resolve(Reflect.apply(target, thisArg, args)).then(async (result) => {
|
|
14625
|
+
try {
|
|
14626
|
+
await completeBatch(args[0]);
|
|
14627
|
+
} catch (error) {
|
|
14628
|
+
logBatchInstrumentationError("could not complete batch", error);
|
|
14629
|
+
}
|
|
14630
|
+
return result;
|
|
14631
|
+
});
|
|
14632
|
+
|
|
13657
14633
|
// src/instrumentation/plugins/openai-plugin.ts
|
|
13658
14634
|
var OpenAIPlugin = class extends BasePlugin {
|
|
13659
14635
|
constructor() {
|
|
13660
14636
|
super();
|
|
13661
14637
|
}
|
|
13662
14638
|
onEnable() {
|
|
14639
|
+
this.unsubscribers.push(
|
|
14640
|
+
openAIChannels.filesCreateTraced.intercept(
|
|
14641
|
+
interceptOpenAIFilesCreateTraced
|
|
14642
|
+
),
|
|
14643
|
+
openAIChannels.batchesRetrieveTraced.intercept(
|
|
14644
|
+
interceptOpenAIBatchesRetrieveTraced
|
|
14645
|
+
),
|
|
14646
|
+
openAIChannels.batchesCompleteTrace.intercept(
|
|
14647
|
+
interceptOpenAIBatchTraceComplete
|
|
14648
|
+
)
|
|
14649
|
+
);
|
|
13663
14650
|
this.unsubscribers.push(
|
|
13664
14651
|
traceStreamingChannel(openAIChannels.chatCompletionsCreate, {
|
|
13665
14652
|
name: "Chat Completion",
|
|
13666
14653
|
type: "llm" /* LLM */,
|
|
13667
|
-
extractInput: ([params]) =>
|
|
13668
|
-
const { messages, ...metadata } = params;
|
|
13669
|
-
return {
|
|
13670
|
-
input: processInputAttachments(messages),
|
|
13671
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13672
|
-
};
|
|
13673
|
-
},
|
|
14654
|
+
extractInput: ([params]) => extractOpenAIChatInput(params),
|
|
13674
14655
|
extractOutput: (result) => {
|
|
13675
14656
|
return result?.choices;
|
|
13676
14657
|
},
|
|
@@ -13716,13 +14697,7 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13716
14697
|
traceStreamingChannel(openAIChannels.betaChatCompletionsParse, {
|
|
13717
14698
|
name: "Chat Completion",
|
|
13718
14699
|
type: "llm" /* LLM */,
|
|
13719
|
-
extractInput: ([params]) =>
|
|
13720
|
-
const { messages, ...metadata } = params;
|
|
13721
|
-
return {
|
|
13722
|
-
input: processInputAttachments(messages),
|
|
13723
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13724
|
-
};
|
|
13725
|
-
},
|
|
14700
|
+
extractInput: ([params]) => extractOpenAIChatInput(params),
|
|
13726
14701
|
extractOutput: (result) => {
|
|
13727
14702
|
return result?.choices;
|
|
13728
14703
|
},
|
|
@@ -13744,13 +14719,7 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13744
14719
|
traceSyncStreamChannel(openAIChannels.betaChatCompletionsStream, {
|
|
13745
14720
|
name: "Chat Completion",
|
|
13746
14721
|
type: "llm" /* LLM */,
|
|
13747
|
-
extractInput: ([params]) =>
|
|
13748
|
-
const { messages, ...metadata } = params;
|
|
13749
|
-
return {
|
|
13750
|
-
input: processInputAttachments(messages),
|
|
13751
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13752
|
-
};
|
|
13753
|
-
}
|
|
14722
|
+
extractInput: ([params]) => extractOpenAIChatInput(params)
|
|
13754
14723
|
})
|
|
13755
14724
|
);
|
|
13756
14725
|
this.unsubscribers.push(
|
|
@@ -13780,23 +14749,11 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13780
14749
|
traceStreamingChannel(openAIChannels.responsesCreate, {
|
|
13781
14750
|
name: "openai.responses.create",
|
|
13782
14751
|
type: "llm" /* LLM */,
|
|
13783
|
-
extractInput: ([params]) =>
|
|
13784
|
-
const { input, ...metadata } = params;
|
|
13785
|
-
return {
|
|
13786
|
-
input: processInputAttachments(input),
|
|
13787
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13788
|
-
};
|
|
13789
|
-
},
|
|
14752
|
+
extractInput: ([params]) => extractOpenAIResponsesInput(params),
|
|
13790
14753
|
extractOutput: (result) => {
|
|
13791
14754
|
return processImagesInOutput(result?.output);
|
|
13792
14755
|
},
|
|
13793
|
-
extractMetadata: (result) =>
|
|
13794
|
-
if (!result) {
|
|
13795
|
-
return void 0;
|
|
13796
|
-
}
|
|
13797
|
-
const { output: _output, usage: _usage, ...metadata } = result;
|
|
13798
|
-
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
13799
|
-
},
|
|
14756
|
+
extractMetadata: (result) => extractOpenAIResponsesMetadata(result),
|
|
13800
14757
|
extractMetrics: (result, startTime, endEvent) => {
|
|
13801
14758
|
const metrics = withCachedMetric(
|
|
13802
14759
|
parseMetricsFromUsage(result?.usage),
|
|
@@ -13815,13 +14772,7 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13815
14772
|
traceSyncStreamChannel(openAIChannels.responsesStream, {
|
|
13816
14773
|
name: "openai.responses.create",
|
|
13817
14774
|
type: "llm" /* LLM */,
|
|
13818
|
-
extractInput: ([params]) =>
|
|
13819
|
-
const { input, ...metadata } = params;
|
|
13820
|
-
return {
|
|
13821
|
-
input: processInputAttachments(input),
|
|
13822
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13823
|
-
};
|
|
13824
|
-
},
|
|
14775
|
+
extractInput: ([params]) => extractOpenAIResponsesInput(params),
|
|
13825
14776
|
extractFromEvent: (event) => {
|
|
13826
14777
|
if (event.type !== "response.completed" || !event.response) {
|
|
13827
14778
|
return {};
|
|
@@ -13844,23 +14795,11 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13844
14795
|
traceStreamingChannel(openAIChannels.responsesParse, {
|
|
13845
14796
|
name: "openai.responses.parse",
|
|
13846
14797
|
type: "llm" /* LLM */,
|
|
13847
|
-
extractInput: ([params]) =>
|
|
13848
|
-
const { input, ...metadata } = params;
|
|
13849
|
-
return {
|
|
13850
|
-
input: processInputAttachments(input),
|
|
13851
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13852
|
-
};
|
|
13853
|
-
},
|
|
14798
|
+
extractInput: ([params]) => extractOpenAIResponsesInput(params),
|
|
13854
14799
|
extractOutput: (result) => {
|
|
13855
14800
|
return processImagesInOutput(result?.output);
|
|
13856
14801
|
},
|
|
13857
|
-
extractMetadata: (result) =>
|
|
13858
|
-
if (!result) {
|
|
13859
|
-
return void 0;
|
|
13860
|
-
}
|
|
13861
|
-
const { output: _output, usage: _usage, ...metadata } = result;
|
|
13862
|
-
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
13863
|
-
},
|
|
14802
|
+
extractMetadata: (result) => extractOpenAIResponsesMetadata(result),
|
|
13864
14803
|
extractMetrics: (result, startTime, endEvent) => {
|
|
13865
14804
|
const metrics = withCachedMetric(
|
|
13866
14805
|
parseMetricsFromUsage(result?.usage),
|
|
@@ -13879,23 +14818,11 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13879
14818
|
traceAsyncChannel(openAIChannels.responsesCompact, {
|
|
13880
14819
|
name: "openai.responses.compact",
|
|
13881
14820
|
type: "llm" /* LLM */,
|
|
13882
|
-
extractInput: ([params]) =>
|
|
13883
|
-
const { input, ...metadata } = params;
|
|
13884
|
-
return {
|
|
13885
|
-
input: processInputAttachments(input),
|
|
13886
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13887
|
-
};
|
|
13888
|
-
},
|
|
14821
|
+
extractInput: ([params]) => extractOpenAIResponsesInput(params),
|
|
13889
14822
|
extractOutput: (result) => {
|
|
13890
14823
|
return processImagesInOutput(result?.output);
|
|
13891
14824
|
},
|
|
13892
|
-
extractMetadata: (result) =>
|
|
13893
|
-
if (!result) {
|
|
13894
|
-
return void 0;
|
|
13895
|
-
}
|
|
13896
|
-
const { output: _output, usage: _usage, ...metadata } = result;
|
|
13897
|
-
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
13898
|
-
},
|
|
14825
|
+
extractMetadata: (result) => extractOpenAIResponsesMetadata(result),
|
|
13899
14826
|
extractMetrics: (result, startTime, endEvent) => {
|
|
13900
14827
|
const metrics = withCachedMetric(
|
|
13901
14828
|
parseMetricsFromUsage(result?.usage),
|
|
@@ -13951,35 +14878,6 @@ function withCachedMetric(metrics, result, endEvent) {
|
|
|
13951
14878
|
cached
|
|
13952
14879
|
};
|
|
13953
14880
|
}
|
|
13954
|
-
function processImagesInOutput(output) {
|
|
13955
|
-
if (Array.isArray(output)) {
|
|
13956
|
-
return output.map(processImagesInOutput);
|
|
13957
|
-
}
|
|
13958
|
-
if (isObject(output)) {
|
|
13959
|
-
if (output.type === "image_generation_call" && output.result && typeof output.result === "string") {
|
|
13960
|
-
const fileExtension = output.output_format || "png";
|
|
13961
|
-
const contentType = `image/${fileExtension}`;
|
|
13962
|
-
const baseFilename = output.revised_prompt && typeof output.revised_prompt === "string" ? output.revised_prompt.slice(0, 50).replace(/[^a-zA-Z0-9]/g, "_") : "generated_image";
|
|
13963
|
-
const filename = `${baseFilename}.${fileExtension}`;
|
|
13964
|
-
const binaryString = atob(output.result);
|
|
13965
|
-
const bytes = new Uint8Array(binaryString.length);
|
|
13966
|
-
for (let i = 0; i < binaryString.length; i++) {
|
|
13967
|
-
bytes[i] = binaryString.charCodeAt(i);
|
|
13968
|
-
}
|
|
13969
|
-
const blob = new Blob([bytes], { type: contentType });
|
|
13970
|
-
const attachment = new Attachment({
|
|
13971
|
-
data: blob,
|
|
13972
|
-
filename,
|
|
13973
|
-
contentType
|
|
13974
|
-
});
|
|
13975
|
-
return {
|
|
13976
|
-
...output,
|
|
13977
|
-
result: attachment
|
|
13978
|
-
};
|
|
13979
|
-
}
|
|
13980
|
-
}
|
|
13981
|
-
return output;
|
|
13982
|
-
}
|
|
13983
14881
|
function mergeLogprobTokens(existing, incoming) {
|
|
13984
14882
|
if (incoming === void 0) {
|
|
13985
14883
|
return existing;
|
|
@@ -14010,13 +14908,33 @@ function aggregateChatLogprobs(existing, incoming) {
|
|
|
14010
14908
|
}
|
|
14011
14909
|
return aggregated;
|
|
14012
14910
|
}
|
|
14911
|
+
function createAggregatedChatChoice(index) {
|
|
14912
|
+
return {
|
|
14913
|
+
index,
|
|
14914
|
+
role: void 0,
|
|
14915
|
+
content: void 0,
|
|
14916
|
+
refusal: void 0,
|
|
14917
|
+
toolCallsByIndex: /* @__PURE__ */ new Map(),
|
|
14918
|
+
logprobs: void 0,
|
|
14919
|
+
finish_reason: void 0
|
|
14920
|
+
};
|
|
14921
|
+
}
|
|
14922
|
+
function toChatChoice(choice) {
|
|
14923
|
+
const toolCalls2 = Array.from(choice.toolCallsByIndex.entries()).sort(([left], [right]) => left - right).map(([, toolCall]) => toolCall);
|
|
14924
|
+
return {
|
|
14925
|
+
index: choice.index,
|
|
14926
|
+
message: {
|
|
14927
|
+
role: choice.role,
|
|
14928
|
+
content: choice.content,
|
|
14929
|
+
...choice.refusal !== void 0 ? { refusal: choice.refusal } : {},
|
|
14930
|
+
tool_calls: toolCalls2.length > 0 ? toolCalls2 : void 0
|
|
14931
|
+
},
|
|
14932
|
+
logprobs: choice.logprobs ?? null,
|
|
14933
|
+
finish_reason: choice.finish_reason
|
|
14934
|
+
};
|
|
14935
|
+
}
|
|
14013
14936
|
function aggregateChatCompletionChunks(chunks, streamResult, endEvent) {
|
|
14014
|
-
|
|
14015
|
-
let content = void 0;
|
|
14016
|
-
let refusal = void 0;
|
|
14017
|
-
let tool_calls = void 0;
|
|
14018
|
-
let logprobs = void 0;
|
|
14019
|
-
let finish_reason = void 0;
|
|
14937
|
+
const choicesByIndex = /* @__PURE__ */ new Map();
|
|
14020
14938
|
let metrics = {};
|
|
14021
14939
|
for (const chunk of chunks) {
|
|
14022
14940
|
if (chunk.usage) {
|
|
@@ -14025,62 +14943,75 @@ function aggregateChatCompletionChunks(chunks, streamResult, endEvent) {
|
|
|
14025
14943
|
...parseMetricsFromUsage(chunk.usage)
|
|
14026
14944
|
};
|
|
14027
14945
|
}
|
|
14028
|
-
const
|
|
14029
|
-
if (!
|
|
14946
|
+
const choices = chunk.choices;
|
|
14947
|
+
if (!choices?.length) {
|
|
14030
14948
|
continue;
|
|
14031
14949
|
}
|
|
14032
|
-
|
|
14033
|
-
|
|
14034
|
-
|
|
14035
|
-
|
|
14036
|
-
|
|
14037
|
-
|
|
14038
|
-
|
|
14039
|
-
|
|
14040
|
-
|
|
14041
|
-
|
|
14042
|
-
|
|
14043
|
-
|
|
14044
|
-
|
|
14045
|
-
|
|
14046
|
-
|
|
14047
|
-
|
|
14048
|
-
|
|
14049
|
-
|
|
14050
|
-
|
|
14051
|
-
|
|
14052
|
-
|
|
14053
|
-
|
|
14054
|
-
|
|
14055
|
-
|
|
14056
|
-
|
|
14057
|
-
|
|
14058
|
-
|
|
14059
|
-
|
|
14060
|
-
|
|
14950
|
+
for (const choice of choices) {
|
|
14951
|
+
const choiceIndex = choice.index;
|
|
14952
|
+
let aggregatedChoice = choicesByIndex.get(choiceIndex);
|
|
14953
|
+
if (!aggregatedChoice) {
|
|
14954
|
+
aggregatedChoice = createAggregatedChatChoice(choiceIndex);
|
|
14955
|
+
choicesByIndex.set(choiceIndex, aggregatedChoice);
|
|
14956
|
+
}
|
|
14957
|
+
if (choice.finish_reason) {
|
|
14958
|
+
aggregatedChoice.finish_reason = choice.finish_reason;
|
|
14959
|
+
}
|
|
14960
|
+
aggregatedChoice.logprobs = aggregateChatLogprobs(
|
|
14961
|
+
aggregatedChoice.logprobs,
|
|
14962
|
+
choice.logprobs
|
|
14963
|
+
);
|
|
14964
|
+
const delta = choice.delta;
|
|
14965
|
+
if (!delta) {
|
|
14966
|
+
continue;
|
|
14967
|
+
}
|
|
14968
|
+
if (delta.finish_reason) {
|
|
14969
|
+
aggregatedChoice.finish_reason = delta.finish_reason;
|
|
14970
|
+
}
|
|
14971
|
+
if (!aggregatedChoice.role && delta.role) {
|
|
14972
|
+
aggregatedChoice.role = delta.role;
|
|
14973
|
+
}
|
|
14974
|
+
if (delta.content) {
|
|
14975
|
+
aggregatedChoice.content = (aggregatedChoice.content || "") + delta.content;
|
|
14976
|
+
}
|
|
14977
|
+
if (delta.refusal) {
|
|
14978
|
+
aggregatedChoice.refusal = (aggregatedChoice.refusal || "") + delta.refusal;
|
|
14979
|
+
}
|
|
14980
|
+
if (delta.tool_calls) {
|
|
14981
|
+
for (const toolDelta of delta.tool_calls) {
|
|
14982
|
+
let aggregatedToolCall = aggregatedChoice.toolCallsByIndex.get(
|
|
14983
|
+
toolDelta.index
|
|
14984
|
+
);
|
|
14985
|
+
if (!aggregatedToolCall) {
|
|
14986
|
+
aggregatedToolCall = {
|
|
14987
|
+
function: { arguments: "" }
|
|
14988
|
+
};
|
|
14989
|
+
aggregatedChoice.toolCallsByIndex.set(
|
|
14990
|
+
toolDelta.index,
|
|
14991
|
+
aggregatedToolCall
|
|
14992
|
+
);
|
|
14061
14993
|
}
|
|
14062
|
-
|
|
14063
|
-
|
|
14064
|
-
|
|
14994
|
+
if (toolDelta.id !== void 0) {
|
|
14995
|
+
aggregatedToolCall.id = toolDelta.id;
|
|
14996
|
+
}
|
|
14997
|
+
if (toolDelta.type !== void 0) {
|
|
14998
|
+
aggregatedToolCall.type = toolDelta.type;
|
|
14999
|
+
}
|
|
15000
|
+
if (toolDelta.function?.name !== void 0) {
|
|
15001
|
+
aggregatedToolCall.function.name = toolDelta.function.name;
|
|
15002
|
+
}
|
|
15003
|
+
if (toolDelta.function?.arguments !== void 0) {
|
|
15004
|
+
aggregatedToolCall.function.arguments += toolDelta.function.arguments;
|
|
15005
|
+
}
|
|
15006
|
+
}
|
|
14065
15007
|
}
|
|
14066
15008
|
}
|
|
14067
15009
|
}
|
|
14068
15010
|
metrics = withCachedMetric(metrics, streamResult, endEvent);
|
|
15011
|
+
const output = Array.from(choicesByIndex.values()).sort((left, right) => left.index - right.index).map(toChatChoice);
|
|
14069
15012
|
return {
|
|
14070
15013
|
metrics,
|
|
14071
|
-
output: [
|
|
14072
|
-
{
|
|
14073
|
-
index: 0,
|
|
14074
|
-
message: {
|
|
14075
|
-
role,
|
|
14076
|
-
content,
|
|
14077
|
-
...refusal !== void 0 ? { refusal } : {},
|
|
14078
|
-
tool_calls
|
|
14079
|
-
},
|
|
14080
|
-
logprobs: logprobs ?? null,
|
|
14081
|
-
finish_reason
|
|
14082
|
-
}
|
|
14083
|
-
]
|
|
15014
|
+
output: output.length > 0 ? output : [toChatChoice(createAggregatedChatChoice(0))]
|
|
14084
15015
|
};
|
|
14085
15016
|
}
|
|
14086
15017
|
function aggregateResponseStreamEvents(chunks, _streamResult, endEvent) {
|
|
@@ -15416,6 +16347,12 @@ function parseMetricsFromUsage2(usage) {
|
|
|
15416
16347
|
}
|
|
15417
16348
|
}
|
|
15418
16349
|
}
|
|
16350
|
+
if (isObject(usage.output_tokens_details)) {
|
|
16351
|
+
const thinkingTokens = usage.output_tokens_details.thinking_tokens;
|
|
16352
|
+
if (typeof thinkingTokens === "number") {
|
|
16353
|
+
metrics.completion_reasoning_tokens = thinkingTokens;
|
|
16354
|
+
}
|
|
16355
|
+
}
|
|
15419
16356
|
if (isObject(usage.server_tool_use)) {
|
|
15420
16357
|
for (const [name, value] of Object.entries(usage.server_tool_use)) {
|
|
15421
16358
|
if (typeof value === "number") {
|
|
@@ -16372,7 +17309,6 @@ function endHarnessTurn(parent) {
|
|
|
16372
17309
|
function braintrustAISDKTelemetry() {
|
|
16373
17310
|
const operations = /* @__PURE__ */ new Map();
|
|
16374
17311
|
const operationKeysByCallId = /* @__PURE__ */ new Map();
|
|
16375
|
-
const workflowOperationKeyStore = isomorph_default.newAsyncLocalStorage();
|
|
16376
17312
|
const modelSpans = /* @__PURE__ */ new Map();
|
|
16377
17313
|
const objectSpans = /* @__PURE__ */ new Map();
|
|
16378
17314
|
const embedSpans = /* @__PURE__ */ new Map();
|
|
@@ -16415,9 +17351,6 @@ function braintrustAISDKTelemetry() {
|
|
|
16415
17351
|
return;
|
|
16416
17352
|
}
|
|
16417
17353
|
operations.delete(operationKey);
|
|
16418
|
-
if (workflowOperationKeyStore.getStore() === operationKey) {
|
|
16419
|
-
workflowOperationKeyStore.enterWith(void 0);
|
|
16420
|
-
}
|
|
16421
17354
|
const keys = operationKeysByCallId.get(state.callId);
|
|
16422
17355
|
if (!keys) {
|
|
16423
17356
|
return;
|
|
@@ -16465,14 +17398,7 @@ function braintrustAISDKTelemetry() {
|
|
|
16465
17398
|
return key;
|
|
16466
17399
|
}
|
|
16467
17400
|
}
|
|
16468
|
-
|
|
16469
|
-
if (workflowOperationKey && keys.includes(workflowOperationKey)) {
|
|
16470
|
-
return workflowOperationKey;
|
|
16471
|
-
}
|
|
16472
|
-
if (callId === "workflow-agent") {
|
|
16473
|
-
return void 0;
|
|
16474
|
-
}
|
|
16475
|
-
return mode === "finish" ? keys[0] : keys[keys.length - 1];
|
|
17401
|
+
return callId === "workflow-agent" || mode === "active" ? keys[keys.length - 1] : keys[0];
|
|
16476
17402
|
};
|
|
16477
17403
|
const operationKeyFromEvent = (event, mode = "active") => {
|
|
16478
17404
|
const explicit = explicitOperationKey(event);
|
|
@@ -16486,17 +17412,13 @@ function braintrustAISDKTelemetry() {
|
|
|
16486
17412
|
if (operationKey) {
|
|
16487
17413
|
return operationKey;
|
|
16488
17414
|
}
|
|
16489
|
-
const
|
|
16490
|
-
if (
|
|
16491
|
-
return
|
|
17415
|
+
const workflowAgentKeys2 = operationKeysByCallId.get("workflow-agent");
|
|
17416
|
+
if (workflowAgentKeys2?.length) {
|
|
17417
|
+
return workflowAgentKeys2[workflowAgentKeys2.length - 1];
|
|
16492
17418
|
}
|
|
16493
17419
|
return callId === "workflow-agent" ? void 0 : callId;
|
|
16494
17420
|
}
|
|
16495
17421
|
}
|
|
16496
|
-
const workflowOperationKey = workflowOperationKeyStore.getStore();
|
|
16497
|
-
if (workflowOperationKey && operations.has(workflowOperationKey)) {
|
|
16498
|
-
return workflowOperationKey;
|
|
16499
|
-
}
|
|
16500
17422
|
const wrapperSpan = currentWorkflowAgentWrapperSpan();
|
|
16501
17423
|
if (wrapperSpan?.spanId) {
|
|
16502
17424
|
for (const [operationKey, state] of operations) {
|
|
@@ -16506,8 +17428,8 @@ function braintrustAISDKTelemetry() {
|
|
|
16506
17428
|
}
|
|
16507
17429
|
}
|
|
16508
17430
|
const workflowAgentKeys = operationKeysByCallId.get("workflow-agent");
|
|
16509
|
-
if (workflowAgentKeys?.length
|
|
16510
|
-
return workflowAgentKeys[
|
|
17431
|
+
if (workflowAgentKeys?.length) {
|
|
17432
|
+
return workflowAgentKeys[workflowAgentKeys.length - 1];
|
|
16511
17433
|
}
|
|
16512
17434
|
if (operations.size === 1) {
|
|
16513
17435
|
return operations.keys().next().value;
|
|
@@ -16710,9 +17632,6 @@ function braintrustAISDKTelemetry() {
|
|
|
16710
17632
|
if (!ownsSpan) {
|
|
16711
17633
|
return;
|
|
16712
17634
|
}
|
|
16713
|
-
if (workflowAgent) {
|
|
16714
|
-
workflowOperationKeyStore.enterWith(operationKey);
|
|
16715
|
-
}
|
|
16716
17635
|
let metadata = metadataFromEvent(event);
|
|
16717
17636
|
const logPayload = { metadata };
|
|
16718
17637
|
const workflowAgentCallInput = workflowAgent ? operationInput(event, operationName) : void 0;
|
|
@@ -17184,6 +18103,10 @@ var aiSDKChannels = defineChannels(
|
|
|
17184
18103
|
channelName: "generateText",
|
|
17185
18104
|
kind: "async"
|
|
17186
18105
|
}),
|
|
18106
|
+
generateImage: channel({
|
|
18107
|
+
channelName: "generateImage",
|
|
18108
|
+
kind: "async"
|
|
18109
|
+
}),
|
|
17187
18110
|
streamText: channel({
|
|
17188
18111
|
channelName: "streamText",
|
|
17189
18112
|
kind: "async"
|
|
@@ -17371,7 +18294,7 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
17371
18294
|
}
|
|
17372
18295
|
subscribeToAISDK() {
|
|
17373
18296
|
const denyOutputPaths = this.config.denyOutputPaths || DEFAULT_DENY_OUTPUT_PATHS;
|
|
17374
|
-
this.unsubscribers.push(
|
|
18297
|
+
this.unsubscribers.push(interceptAISDKV7TelemetryDispatcher());
|
|
17375
18298
|
this.unsubscribers.push(subscribeToHarnessAgentCreateSession());
|
|
17376
18299
|
this.unsubscribers.push(
|
|
17377
18300
|
subscribeToHarnessContinuation(
|
|
@@ -17399,6 +18322,18 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
17399
18322
|
aggregateChunks: aggregateAISDKChunks
|
|
17400
18323
|
})
|
|
17401
18324
|
);
|
|
18325
|
+
this.unsubscribers.push(
|
|
18326
|
+
traceAsyncChannel(aiSDKChannels.generateImage, {
|
|
18327
|
+
name: "generateImage",
|
|
18328
|
+
type: "llm" /* LLM */,
|
|
18329
|
+
extractInput: ([params], event) => prepareAISDKGenerateImageInput(params, event.self),
|
|
18330
|
+
extractOutput: (result, endEvent) => processAISDKGenerateImageOutput(
|
|
18331
|
+
result,
|
|
18332
|
+
resolveDenyOutputPaths(endEvent, denyOutputPaths)
|
|
18333
|
+
),
|
|
18334
|
+
extractMetrics: (result) => extractTokenMetrics(result)
|
|
18335
|
+
})
|
|
18336
|
+
);
|
|
17402
18337
|
this.unsubscribers.push(
|
|
17403
18338
|
traceStreamingChannel(aiSDKChannels.streamText, {
|
|
17404
18339
|
name: "streamText",
|
|
@@ -17888,26 +18823,29 @@ function subscribeToHarnessContinuation(continuationChannel, defaultDenyOutputPa
|
|
|
17888
18823
|
channel2.unsubscribe(handlers);
|
|
17889
18824
|
};
|
|
17890
18825
|
}
|
|
17891
|
-
function
|
|
17892
|
-
const channel2 = aiSDKChannels.v7CreateTelemetryDispatcher.tracingChannel();
|
|
18826
|
+
function interceptAISDKV7TelemetryDispatcher() {
|
|
17893
18827
|
const telemetry = braintrustAISDKTelemetry();
|
|
17894
|
-
|
|
17895
|
-
|
|
17896
|
-
const
|
|
17897
|
-
|
|
17898
|
-
|
|
18828
|
+
return aiSDKChannels.v7CreateTelemetryDispatcher.intercept(
|
|
18829
|
+
(target, thisArg, args) => {
|
|
18830
|
+
const dispatcher = Reflect.apply(target, thisArg, args);
|
|
18831
|
+
const telemetryOptions = args[0]?.telemetry;
|
|
18832
|
+
if (telemetryOptions?.isEnabled !== false) {
|
|
18833
|
+
try {
|
|
18834
|
+
patchAISDKV7TelemetryDispatcher(
|
|
18835
|
+
dispatcher,
|
|
18836
|
+
telemetry,
|
|
18837
|
+
telemetryOptions
|
|
18838
|
+
);
|
|
18839
|
+
} catch (error) {
|
|
18840
|
+
debugLogger.error(
|
|
18841
|
+
"Error instrumenting AI SDK v7 telemetry dispatcher:",
|
|
18842
|
+
error
|
|
18843
|
+
);
|
|
18844
|
+
}
|
|
17899
18845
|
}
|
|
17900
|
-
|
|
17901
|
-
event.result,
|
|
17902
|
-
telemetry,
|
|
17903
|
-
telemetryOptions
|
|
17904
|
-
);
|
|
18846
|
+
return dispatcher;
|
|
17905
18847
|
}
|
|
17906
|
-
|
|
17907
|
-
channel2.subscribe(handlers);
|
|
17908
|
-
return () => {
|
|
17909
|
-
channel2.unsubscribe(handlers);
|
|
17910
|
-
};
|
|
18848
|
+
);
|
|
17911
18849
|
}
|
|
17912
18850
|
function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry, telemetryOptions) {
|
|
17913
18851
|
if (!isObject(dispatcher)) {
|
|
@@ -18232,16 +19170,10 @@ var convertImageToAttachment = (image, explicitMimeType) => {
|
|
|
18232
19170
|
}
|
|
18233
19171
|
}
|
|
18234
19172
|
if (explicitMimeType) {
|
|
18235
|
-
|
|
18236
|
-
|
|
18237
|
-
data: new Blob([image], { type: explicitMimeType }),
|
|
18238
|
-
filename: `image.${getExtensionFromMediaType(explicitMimeType)}`,
|
|
18239
|
-
contentType: explicitMimeType
|
|
18240
|
-
});
|
|
18241
|
-
}
|
|
18242
|
-
if (typeof Buffer !== "undefined" && Buffer.isBuffer(image)) {
|
|
19173
|
+
const blob = convertDataToBlob(image, explicitMimeType);
|
|
19174
|
+
if (blob) {
|
|
18243
19175
|
return new Attachment({
|
|
18244
|
-
data:
|
|
19176
|
+
data: blob,
|
|
18245
19177
|
filename: `image.${getExtensionFromMediaType(explicitMimeType)}`,
|
|
18246
19178
|
contentType: explicitMimeType
|
|
18247
19179
|
});
|
|
@@ -18295,6 +19227,25 @@ var convertDataToAttachment = (data, mimeType, filename) => {
|
|
|
18295
19227
|
function processAISDKCallInput(params) {
|
|
18296
19228
|
return processInputAttachmentsSync(params);
|
|
18297
19229
|
}
|
|
19230
|
+
function processAISDKGenerateImageInput(params) {
|
|
19231
|
+
const prompt = params.prompt;
|
|
19232
|
+
if (!isObject(prompt) || Array.isArray(prompt)) {
|
|
19233
|
+
return processAISDKCallInput(params);
|
|
19234
|
+
}
|
|
19235
|
+
const processedPrompt = { ...prompt };
|
|
19236
|
+
if (Array.isArray(prompt.images)) {
|
|
19237
|
+
processedPrompt.images = prompt.images.map(
|
|
19238
|
+
(image) => convertImageToAttachment(image, "image/png") ?? image
|
|
19239
|
+
);
|
|
19240
|
+
}
|
|
19241
|
+
if (prompt.mask !== void 0) {
|
|
19242
|
+
processedPrompt.mask = convertImageToAttachment(prompt.mask, "image/png") ?? prompt.mask;
|
|
19243
|
+
}
|
|
19244
|
+
return processAISDKCallInput({
|
|
19245
|
+
...params,
|
|
19246
|
+
prompt: processedPrompt
|
|
19247
|
+
});
|
|
19248
|
+
}
|
|
18298
19249
|
function processAISDKWorkflowAgentCallInput(params) {
|
|
18299
19250
|
const processed = processAISDKCallInput(params);
|
|
18300
19251
|
return {
|
|
@@ -18433,6 +19384,12 @@ function prepareAISDKEmbedInput(params, self) {
|
|
|
18433
19384
|
metadata: extractMetadataFromEmbedParams(params, self)
|
|
18434
19385
|
};
|
|
18435
19386
|
}
|
|
19387
|
+
function prepareAISDKGenerateImageInput(params, self) {
|
|
19388
|
+
return {
|
|
19389
|
+
input: processAISDKGenerateImageInput(params).input,
|
|
19390
|
+
metadata: extractMetadataFromCallParams(params, self)
|
|
19391
|
+
};
|
|
19392
|
+
}
|
|
18436
19393
|
function prepareAISDKRerankInput(params, self) {
|
|
18437
19394
|
const { documents, query } = params;
|
|
18438
19395
|
return {
|
|
@@ -19808,6 +20765,57 @@ function processAISDKOutput(output, denyOutputPaths) {
|
|
|
19808
20765
|
}
|
|
19809
20766
|
return normalizeAISDKLoggedOutput(sanitized);
|
|
19810
20767
|
}
|
|
20768
|
+
function processAISDKGenerateImageOutput(output, denyOutputPaths) {
|
|
20769
|
+
if (!output || typeof output !== "object") {
|
|
20770
|
+
return output;
|
|
20771
|
+
}
|
|
20772
|
+
const summarized = {};
|
|
20773
|
+
for (const field of [
|
|
20774
|
+
"usage",
|
|
20775
|
+
"warnings",
|
|
20776
|
+
"providerMetadata",
|
|
20777
|
+
"experimental_providerMetadata",
|
|
20778
|
+
"responses"
|
|
20779
|
+
]) {
|
|
20780
|
+
const value = safeSerializableFieldRead(output, field);
|
|
20781
|
+
if (value !== void 0 && isSerializableOutputValue(value)) {
|
|
20782
|
+
summarized[field] = value;
|
|
20783
|
+
}
|
|
20784
|
+
}
|
|
20785
|
+
const images = safeSerializableFieldRead(output, "images");
|
|
20786
|
+
const image = safeSerializableFieldRead(output, "image");
|
|
20787
|
+
const generatedFiles = Array.isArray(images) && images.length > 0 ? images : image !== void 0 ? [image] : [];
|
|
20788
|
+
const loggedOutput = normalizeAISDKLoggedOutput(
|
|
20789
|
+
omit(summarized, denyOutputPaths)
|
|
20790
|
+
);
|
|
20791
|
+
if (generatedFiles.length > 0) {
|
|
20792
|
+
loggedOutput.images = generatedFiles.map(
|
|
20793
|
+
(file, index) => convertAISDKGeneratedFileToAttachment(file, index)
|
|
20794
|
+
);
|
|
20795
|
+
}
|
|
20796
|
+
return loggedOutput;
|
|
20797
|
+
}
|
|
20798
|
+
function convertAISDKGeneratedFileToAttachment(file, index) {
|
|
20799
|
+
if (!file || typeof file !== "object") {
|
|
20800
|
+
return file;
|
|
20801
|
+
}
|
|
20802
|
+
const generatedFile = file;
|
|
20803
|
+
const generatedMediaType = safeSerializableFieldRead(
|
|
20804
|
+
generatedFile,
|
|
20805
|
+
"mediaType"
|
|
20806
|
+
);
|
|
20807
|
+
const mediaType = typeof generatedMediaType === "string" ? generatedMediaType : "application/octet-stream";
|
|
20808
|
+
const data = safeSerializableFieldRead(generatedFile, "base64") ?? safeSerializableFieldRead(generatedFile, "uint8Array");
|
|
20809
|
+
const blob = convertDataToBlob(data, mediaType);
|
|
20810
|
+
if (blob) {
|
|
20811
|
+
return new Attachment({
|
|
20812
|
+
data: blob,
|
|
20813
|
+
filename: `generated_image_${index}.${getExtensionFromMediaType(mediaType)}`,
|
|
20814
|
+
contentType: mediaType
|
|
20815
|
+
});
|
|
20816
|
+
}
|
|
20817
|
+
return file;
|
|
20818
|
+
}
|
|
19811
20819
|
function processAISDKEmbeddingOutput(output, denyOutputPaths) {
|
|
19812
20820
|
if (!output || typeof output !== "object") {
|
|
19813
20821
|
return output;
|
|
@@ -20308,118 +21316,22 @@ var claudeAgentSDKChannels = defineChannels(
|
|
|
20308
21316
|
var CLAUDE_AGENT_SDK_SKIP_LOCAL_TOOL_HOOKS_OPTION = "__braintrust_skip_local_tool_hooks";
|
|
20309
21317
|
|
|
20310
21318
|
// src/instrumentation/plugins/claude-agent-sdk-local-tool-context.ts
|
|
20311
|
-
var
|
|
20312
|
-
|
|
20313
|
-
)
|
|
20314
|
-
|
|
20315
|
-
const maybeIsoWithAsyncLocalStorage = isomorph_default;
|
|
20316
|
-
if (typeof maybeIsoWithAsyncLocalStorage.newAsyncLocalStorage === "function") {
|
|
20317
|
-
return maybeIsoWithAsyncLocalStorage.newAsyncLocalStorage();
|
|
20318
|
-
}
|
|
20319
|
-
let currentStore;
|
|
20320
|
-
return {
|
|
20321
|
-
enterWith(store) {
|
|
20322
|
-
currentStore = store;
|
|
20323
|
-
},
|
|
20324
|
-
getStore() {
|
|
20325
|
-
return currentStore;
|
|
20326
|
-
},
|
|
20327
|
-
run(store, callback) {
|
|
20328
|
-
const previousStore = currentStore;
|
|
20329
|
-
currentStore = store;
|
|
20330
|
-
try {
|
|
20331
|
-
return callback();
|
|
20332
|
-
} finally {
|
|
20333
|
-
currentStore = previousStore;
|
|
20334
|
-
}
|
|
20335
|
-
}
|
|
20336
|
-
};
|
|
20337
|
-
}
|
|
20338
|
-
var localToolContextStore = createLocalToolContextStore();
|
|
20339
|
-
var fallbackLocalToolParentResolver;
|
|
20340
|
-
function createClaudeLocalToolContext() {
|
|
20341
|
-
return {};
|
|
20342
|
-
}
|
|
20343
|
-
function runWithClaudeLocalToolContext(callback, context) {
|
|
20344
|
-
return localToolContextStore.run(
|
|
20345
|
-
context ?? createClaudeLocalToolContext(),
|
|
20346
|
-
callback
|
|
20347
|
-
);
|
|
21319
|
+
var localToolContextStore = isomorph_default.newAsyncLocalStorage();
|
|
21320
|
+
var localToolParentResolversByToolUseId = /* @__PURE__ */ new Map();
|
|
21321
|
+
function runWithClaudeLocalToolContext(callback, resolver) {
|
|
21322
|
+
return localToolContextStore.run(resolver, callback);
|
|
20348
21323
|
}
|
|
20349
|
-
function
|
|
20350
|
-
|
|
20351
|
-
if (existing) {
|
|
20352
|
-
return existing;
|
|
20353
|
-
}
|
|
20354
|
-
const created = {};
|
|
20355
|
-
localToolContextStore.enterWith(created);
|
|
20356
|
-
return created;
|
|
21324
|
+
function registerClaudeLocalToolParentResolver(toolUseId, resolver) {
|
|
21325
|
+
localToolParentResolversByToolUseId.set(toolUseId, resolver);
|
|
20357
21326
|
}
|
|
20358
|
-
function
|
|
20359
|
-
|
|
20360
|
-
|
|
20361
|
-
|
|
20362
|
-
return;
|
|
21327
|
+
function getClaudeLocalToolParentResolver(toolUseId) {
|
|
21328
|
+
const currentResolver = localToolContextStore.getStore();
|
|
21329
|
+
if (!toolUseId) {
|
|
21330
|
+
return currentResolver;
|
|
20363
21331
|
}
|
|
20364
|
-
|
|
20365
|
-
|
|
20366
|
-
|
|
20367
|
-
return localToolContextStore.getStore()?.resolveLocalToolParent ?? fallbackLocalToolParentResolver;
|
|
20368
|
-
}
|
|
20369
|
-
function isAsyncIterable3(value) {
|
|
20370
|
-
return value !== null && typeof value === "object" && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
20371
|
-
}
|
|
20372
|
-
function bindClaudeLocalToolContextToAsyncIterable(result, localToolContext) {
|
|
20373
|
-
if (!isAsyncIterable3(result) || Object.isFrozen(result) || Object.isSealed(result)) {
|
|
20374
|
-
return result;
|
|
20375
|
-
}
|
|
20376
|
-
const stream = result;
|
|
20377
|
-
const originalAsyncIterator = stream[Symbol.asyncIterator];
|
|
20378
|
-
if (originalAsyncIterator[LOCAL_TOOL_CONTEXT_ASYNC_ITERATOR_PATCHED]) {
|
|
20379
|
-
return result;
|
|
20380
|
-
}
|
|
20381
|
-
const patchedAsyncIterator = function() {
|
|
20382
|
-
return runWithClaudeLocalToolContext(() => {
|
|
20383
|
-
const iterator = Reflect.apply(originalAsyncIterator, this, []);
|
|
20384
|
-
if (!iterator || typeof iterator !== "object") {
|
|
20385
|
-
return iterator;
|
|
20386
|
-
}
|
|
20387
|
-
const patchMethod = (methodName) => {
|
|
20388
|
-
const originalMethod = Reflect.get(iterator, methodName);
|
|
20389
|
-
if (typeof originalMethod !== "function") {
|
|
20390
|
-
return;
|
|
20391
|
-
}
|
|
20392
|
-
Reflect.set(
|
|
20393
|
-
iterator,
|
|
20394
|
-
methodName,
|
|
20395
|
-
(...args) => runWithClaudeLocalToolContext(
|
|
20396
|
-
() => Reflect.apply(
|
|
20397
|
-
originalMethod,
|
|
20398
|
-
iterator,
|
|
20399
|
-
args
|
|
20400
|
-
),
|
|
20401
|
-
localToolContext
|
|
20402
|
-
)
|
|
20403
|
-
);
|
|
20404
|
-
};
|
|
20405
|
-
patchMethod("next");
|
|
20406
|
-
patchMethod("return");
|
|
20407
|
-
patchMethod("throw");
|
|
20408
|
-
return iterator;
|
|
20409
|
-
}, localToolContext);
|
|
20410
|
-
};
|
|
20411
|
-
Object.defineProperty(
|
|
20412
|
-
patchedAsyncIterator,
|
|
20413
|
-
LOCAL_TOOL_CONTEXT_ASYNC_ITERATOR_PATCHED,
|
|
20414
|
-
{
|
|
20415
|
-
configurable: false,
|
|
20416
|
-
enumerable: false,
|
|
20417
|
-
value: true,
|
|
20418
|
-
writable: false
|
|
20419
|
-
}
|
|
20420
|
-
);
|
|
20421
|
-
Reflect.set(stream, Symbol.asyncIterator, patchedAsyncIterator);
|
|
20422
|
-
return result;
|
|
21332
|
+
const registeredResolver = localToolParentResolversByToolUseId.get(toolUseId);
|
|
21333
|
+
localToolParentResolversByToolUseId.delete(toolUseId);
|
|
21334
|
+
return currentResolver ?? registeredResolver;
|
|
20423
21335
|
}
|
|
20424
21336
|
|
|
20425
21337
|
// src/instrumentation/plugins/claude-agent-sdk-local-tool-spans.ts
|
|
@@ -20445,7 +21357,7 @@ function wrapLocalClaudeToolHandler(handler, getMetadata) {
|
|
|
20445
21357
|
const metadata = getMetadata();
|
|
20446
21358
|
const rawToolName = metadata.serverName ? `mcp__${metadata.serverName}__${metadata.toolName}` : metadata.toolName;
|
|
20447
21359
|
const toolUseId = getToolUseIdFromExtra(handlerArgs[1]);
|
|
20448
|
-
const localToolParentResolver = getClaudeLocalToolParentResolver();
|
|
21360
|
+
const localToolParentResolver = getClaudeLocalToolParentResolver(toolUseId);
|
|
20449
21361
|
const spanName = metadata.serverName ? `tool: ${metadata.serverName}/${metadata.toolName}` : `tool: ${metadata.toolName}`;
|
|
20450
21362
|
const runWithResolvedParent = async () => {
|
|
20451
21363
|
const parent = toolUseId && localToolParentResolver ? await localToolParentResolver(toolUseId).catch(() => void 0) : void 0;
|
|
@@ -20972,6 +21884,7 @@ function createToolTracingHooks(resolveParentSpan, taskIdToToolUseId, toolUseToP
|
|
|
20972
21884
|
}
|
|
20973
21885
|
}
|
|
20974
21886
|
if (skipLocalToolHooks && (isLocalToolUse(input.tool_name, mcpServers) || localToolHookNames.has(input.tool_name))) {
|
|
21887
|
+
registerClaudeLocalToolParentResolver(toolUseID, resolveParentSpan);
|
|
20975
21888
|
return {};
|
|
20976
21889
|
}
|
|
20977
21890
|
const parsed = parseToolName(input.tool_name);
|
|
@@ -21682,7 +22595,7 @@ async function finalizeQuerySpan(state) {
|
|
|
21682
22595
|
}
|
|
21683
22596
|
var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
21684
22597
|
onEnable() {
|
|
21685
|
-
this.
|
|
22598
|
+
this.interceptQuery();
|
|
21686
22599
|
}
|
|
21687
22600
|
onDisable() {
|
|
21688
22601
|
for (const unsubscribe of this.unsubscribers) {
|
|
@@ -21690,211 +22603,218 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
21690
22603
|
}
|
|
21691
22604
|
this.unsubscribers = [];
|
|
21692
22605
|
}
|
|
21693
|
-
|
|
21694
|
-
const
|
|
21695
|
-
|
|
21696
|
-
|
|
21697
|
-
|
|
21698
|
-
|
|
21699
|
-
|
|
21700
|
-
|
|
21701
|
-
|
|
21702
|
-
|
|
21703
|
-
|
|
21704
|
-
|
|
21705
|
-
|
|
21706
|
-
|
|
21707
|
-
|
|
21708
|
-
|
|
21709
|
-
|
|
21710
|
-
|
|
21711
|
-
|
|
21712
|
-
|
|
21713
|
-
try {
|
|
21714
|
-
for await (const message of promptStream) {
|
|
21715
|
-
capturedPromptMessages.push(message);
|
|
21716
|
-
yield message;
|
|
21717
|
-
}
|
|
21718
|
-
} finally {
|
|
21719
|
-
resolvePromptDone?.();
|
|
22606
|
+
interceptQuery() {
|
|
22607
|
+
const startQuery = (params) => {
|
|
22608
|
+
const originalPrompt = params.prompt;
|
|
22609
|
+
const options = params.options ?? {};
|
|
22610
|
+
const promptIsAsyncIterable = isAsyncIterable(originalPrompt);
|
|
22611
|
+
let promptStarted = false;
|
|
22612
|
+
let capturedPromptMessages;
|
|
22613
|
+
let resolvePromptDone;
|
|
22614
|
+
const promptDone = new Promise((resolve) => {
|
|
22615
|
+
resolvePromptDone = resolve;
|
|
22616
|
+
});
|
|
22617
|
+
if (promptIsAsyncIterable) {
|
|
22618
|
+
capturedPromptMessages = [];
|
|
22619
|
+
const promptStream = originalPrompt;
|
|
22620
|
+
params.prompt = (async function* () {
|
|
22621
|
+
promptStarted = true;
|
|
22622
|
+
try {
|
|
22623
|
+
for await (const message of promptStream) {
|
|
22624
|
+
capturedPromptMessages.push(message);
|
|
22625
|
+
yield message;
|
|
21720
22626
|
}
|
|
21721
|
-
}
|
|
21722
|
-
|
|
21723
|
-
const span = startSpan(
|
|
21724
|
-
withSpanInstrumentationName(
|
|
21725
|
-
{
|
|
21726
|
-
name: "Claude Agent",
|
|
21727
|
-
spanAttributes: {
|
|
21728
|
-
type: "task" /* TASK */
|
|
21729
|
-
}
|
|
21730
|
-
},
|
|
21731
|
-
INSTRUMENTATION_NAMES.CLAUDE_AGENT_SDK
|
|
21732
|
-
)
|
|
21733
|
-
);
|
|
21734
|
-
const startTime = getCurrentUnixTimestamp();
|
|
21735
|
-
try {
|
|
21736
|
-
span.log({
|
|
21737
|
-
input: typeof originalPrompt === "string" ? originalPrompt : promptIsAsyncIterable ? void 0 : originalPrompt !== void 0 ? String(originalPrompt) : void 0,
|
|
21738
|
-
metadata: filterSerializableOptions(options)
|
|
21739
|
-
});
|
|
21740
|
-
} catch (error) {
|
|
21741
|
-
console.error("Error extracting input for Claude Agent SDK:", error);
|
|
21742
|
-
}
|
|
21743
|
-
const activeToolSpans = /* @__PURE__ */ new Map();
|
|
21744
|
-
const activeLlmSpansByParentToolUse = /* @__PURE__ */ new Map();
|
|
21745
|
-
const conversationHistoryByParentKey = /* @__PURE__ */ new Map();
|
|
21746
|
-
const subAgentSpans = /* @__PURE__ */ new Map();
|
|
21747
|
-
const endedSubAgentSpans = /* @__PURE__ */ new Set();
|
|
21748
|
-
const toolUseToParent = /* @__PURE__ */ new Map();
|
|
21749
|
-
const latestLlmParentBySubAgentToolUse = /* @__PURE__ */ new Map();
|
|
21750
|
-
const latestRootLlmParentRef = {
|
|
21751
|
-
value: void 0
|
|
21752
|
-
};
|
|
21753
|
-
const subAgentDetailsByToolUseId = /* @__PURE__ */ new Map();
|
|
21754
|
-
const taskIdToToolUseId = /* @__PURE__ */ new Map();
|
|
21755
|
-
const promptMessagesByParentKey = /* @__PURE__ */ new Map();
|
|
21756
|
-
const promptSourcePriorityByParentKey = /* @__PURE__ */ new Map();
|
|
21757
|
-
const localToolContext = createClaudeLocalToolContext();
|
|
21758
|
-
const { hasLocalToolHandlers, localToolHookNames } = prepareLocalToolHandlersInMcpServers(options.mcpServers);
|
|
21759
|
-
const skipLocalToolHooks = options[CLAUDE_AGENT_SDK_SKIP_LOCAL_TOOL_HOOKS_OPTION] === true || hasLocalToolHandlers;
|
|
21760
|
-
const resolveToolUseParentSpan = async (toolUseID, context) => {
|
|
21761
|
-
const trackedParentToolUseId = toolUseToParent.get(toolUseID);
|
|
21762
|
-
const parentToolUseId = trackedParentToolUseId ?? (context?.agentId ? taskIdToToolUseId.get(context.agentId) ?? null : null);
|
|
21763
|
-
const parentKey = llmParentKey(parentToolUseId);
|
|
21764
|
-
const activeLlmSpan = activeLlmSpansByParentToolUse.get(parentKey);
|
|
21765
|
-
const latestLlmParent = parentToolUseId ? latestLlmParentBySubAgentToolUse.get(parentToolUseId) : latestRootLlmParentRef.value;
|
|
21766
|
-
if (!activeLlmSpan && !latestLlmParent) {
|
|
21767
|
-
await ensureActiveLlmSpanForParentToolUse(
|
|
21768
|
-
span,
|
|
21769
|
-
activeLlmSpansByParentToolUse,
|
|
21770
|
-
subAgentDetailsByToolUseId,
|
|
21771
|
-
activeToolSpans,
|
|
21772
|
-
subAgentSpans,
|
|
21773
|
-
parentToolUseId,
|
|
21774
|
-
getCurrentUnixTimestamp()
|
|
21775
|
-
);
|
|
21776
|
-
}
|
|
21777
|
-
if (parentToolUseId) {
|
|
21778
|
-
const subAgentSpan = await ensureSubAgentSpan(
|
|
21779
|
-
subAgentDetailsByToolUseId,
|
|
21780
|
-
span,
|
|
21781
|
-
activeToolSpans,
|
|
21782
|
-
subAgentSpans,
|
|
21783
|
-
parentToolUseId
|
|
21784
|
-
);
|
|
21785
|
-
return subAgentSpan.export();
|
|
22627
|
+
} finally {
|
|
22628
|
+
resolvePromptDone?.();
|
|
21786
22629
|
}
|
|
21787
|
-
|
|
21788
|
-
|
|
21789
|
-
|
|
21790
|
-
|
|
21791
|
-
|
|
21792
|
-
|
|
21793
|
-
|
|
21794
|
-
|
|
21795
|
-
|
|
21796
|
-
|
|
21797
|
-
|
|
21798
|
-
|
|
21799
|
-
|
|
21800
|
-
|
|
21801
|
-
|
|
21802
|
-
|
|
21803
|
-
|
|
21804
|
-
|
|
21805
|
-
spans.set(event, {
|
|
21806
|
-
activeLlmSpansByParentToolUse,
|
|
21807
|
-
activePartialMessageIdByParentKey: /* @__PURE__ */ new Map(),
|
|
21808
|
-
activeToolSpans,
|
|
21809
|
-
conversationHistoryByParentKey,
|
|
21810
|
-
capturedPromptMessages,
|
|
21811
|
-
currentMessageId: void 0,
|
|
21812
|
-
currentMessageStartTime: startTime,
|
|
21813
|
-
currentMessages: [],
|
|
21814
|
-
endedSubAgentSpans,
|
|
21815
|
-
finalOutputUsageMessageIds: /* @__PURE__ */ new Set(),
|
|
21816
|
-
finalResults: [],
|
|
21817
|
-
options: optionsWithHooks,
|
|
21818
|
-
originalPrompt,
|
|
21819
|
-
processing: Promise.resolve(),
|
|
21820
|
-
promptDone,
|
|
21821
|
-
promptMessagesByParentKey,
|
|
21822
|
-
promptStarted: () => promptStarted,
|
|
21823
|
-
promptSourcePriorityByParentKey,
|
|
21824
|
-
span,
|
|
21825
|
-
subAgentDetailsByToolUseId,
|
|
21826
|
-
subAgentSpans,
|
|
21827
|
-
taskIdToToolUseId,
|
|
21828
|
-
latestLlmParentBySubAgentToolUse,
|
|
21829
|
-
latestRootLlmParentRef,
|
|
21830
|
-
toolUseToParent,
|
|
21831
|
-
usageByMessageId: /* @__PURE__ */ new Map(),
|
|
21832
|
-
localToolContext
|
|
22630
|
+
})();
|
|
22631
|
+
}
|
|
22632
|
+
const span = startSpan(
|
|
22633
|
+
withSpanInstrumentationName(
|
|
22634
|
+
{
|
|
22635
|
+
name: "Claude Agent",
|
|
22636
|
+
spanAttributes: {
|
|
22637
|
+
type: "task" /* TASK */
|
|
22638
|
+
}
|
|
22639
|
+
},
|
|
22640
|
+
INSTRUMENTATION_NAMES.CLAUDE_AGENT_SDK
|
|
22641
|
+
)
|
|
22642
|
+
);
|
|
22643
|
+
const startTime = getCurrentUnixTimestamp();
|
|
22644
|
+
try {
|
|
22645
|
+
span.log({
|
|
22646
|
+
input: typeof originalPrompt === "string" ? originalPrompt : promptIsAsyncIterable ? void 0 : originalPrompt !== void 0 ? String(originalPrompt) : void 0,
|
|
22647
|
+
metadata: filterSerializableOptions(options)
|
|
21833
22648
|
});
|
|
21834
|
-
}
|
|
21835
|
-
|
|
21836
|
-
|
|
21837
|
-
|
|
21838
|
-
|
|
21839
|
-
|
|
21840
|
-
|
|
21841
|
-
|
|
21842
|
-
|
|
21843
|
-
|
|
21844
|
-
|
|
21845
|
-
|
|
21846
|
-
|
|
21847
|
-
|
|
21848
|
-
|
|
21849
|
-
|
|
21850
|
-
|
|
21851
|
-
|
|
21852
|
-
|
|
21853
|
-
|
|
21854
|
-
|
|
21855
|
-
|
|
21856
|
-
|
|
21857
|
-
|
|
21858
|
-
|
|
21859
|
-
|
|
21860
|
-
|
|
21861
|
-
|
|
21862
|
-
|
|
21863
|
-
|
|
21864
|
-
|
|
21865
|
-
|
|
21866
|
-
|
|
21867
|
-
|
|
21868
|
-
|
|
21869
|
-
})
|
|
21870
|
-
});
|
|
21871
|
-
return;
|
|
21872
|
-
}
|
|
21873
|
-
try {
|
|
21874
|
-
state.span.log({ output: eventResult });
|
|
21875
|
-
} catch (error) {
|
|
21876
|
-
console.error("Error extracting output for Claude Agent SDK:", error);
|
|
21877
|
-
} finally {
|
|
21878
|
-
state.span.end();
|
|
21879
|
-
spans.delete(event);
|
|
22649
|
+
} catch (error) {
|
|
22650
|
+
console.error("Error extracting input for Claude Agent SDK:", error);
|
|
22651
|
+
}
|
|
22652
|
+
const activeToolSpans = /* @__PURE__ */ new Map();
|
|
22653
|
+
const activeLlmSpansByParentToolUse = /* @__PURE__ */ new Map();
|
|
22654
|
+
const conversationHistoryByParentKey = /* @__PURE__ */ new Map();
|
|
22655
|
+
const subAgentSpans = /* @__PURE__ */ new Map();
|
|
22656
|
+
const endedSubAgentSpans = /* @__PURE__ */ new Set();
|
|
22657
|
+
const toolUseToParent = /* @__PURE__ */ new Map();
|
|
22658
|
+
const latestLlmParentBySubAgentToolUse = /* @__PURE__ */ new Map();
|
|
22659
|
+
const latestRootLlmParentRef = {
|
|
22660
|
+
value: void 0
|
|
22661
|
+
};
|
|
22662
|
+
const subAgentDetailsByToolUseId = /* @__PURE__ */ new Map();
|
|
22663
|
+
const taskIdToToolUseId = /* @__PURE__ */ new Map();
|
|
22664
|
+
const promptMessagesByParentKey = /* @__PURE__ */ new Map();
|
|
22665
|
+
const promptSourcePriorityByParentKey = /* @__PURE__ */ new Map();
|
|
22666
|
+
const { hasLocalToolHandlers, localToolHookNames } = prepareLocalToolHandlersInMcpServers(options.mcpServers);
|
|
22667
|
+
const skipLocalToolHooks = options[CLAUDE_AGENT_SDK_SKIP_LOCAL_TOOL_HOOKS_OPTION] === true || hasLocalToolHandlers;
|
|
22668
|
+
const resolveToolUseParentSpan = async (toolUseID, context) => {
|
|
22669
|
+
const trackedParentToolUseId = toolUseToParent.get(toolUseID);
|
|
22670
|
+
const parentToolUseId = trackedParentToolUseId ?? (context?.agentId ? taskIdToToolUseId.get(context.agentId) ?? null : null);
|
|
22671
|
+
const parentKey = llmParentKey(parentToolUseId);
|
|
22672
|
+
const activeLlmSpan = activeLlmSpansByParentToolUse.get(parentKey);
|
|
22673
|
+
const latestLlmParent = parentToolUseId ? latestLlmParentBySubAgentToolUse.get(parentToolUseId) : latestRootLlmParentRef.value;
|
|
22674
|
+
if (!activeLlmSpan && !latestLlmParent) {
|
|
22675
|
+
await ensureActiveLlmSpanForParentToolUse(
|
|
22676
|
+
span,
|
|
22677
|
+
activeLlmSpansByParentToolUse,
|
|
22678
|
+
subAgentDetailsByToolUseId,
|
|
22679
|
+
activeToolSpans,
|
|
22680
|
+
subAgentSpans,
|
|
22681
|
+
parentToolUseId,
|
|
22682
|
+
getCurrentUnixTimestamp()
|
|
22683
|
+
);
|
|
21880
22684
|
}
|
|
21881
|
-
|
|
21882
|
-
|
|
21883
|
-
|
|
21884
|
-
|
|
21885
|
-
|
|
22685
|
+
if (parentToolUseId) {
|
|
22686
|
+
const subAgentSpan = await ensureSubAgentSpan(
|
|
22687
|
+
subAgentDetailsByToolUseId,
|
|
22688
|
+
span,
|
|
22689
|
+
activeToolSpans,
|
|
22690
|
+
subAgentSpans,
|
|
22691
|
+
parentToolUseId
|
|
22692
|
+
);
|
|
22693
|
+
return subAgentSpan.export();
|
|
21886
22694
|
}
|
|
21887
|
-
|
|
21888
|
-
|
|
22695
|
+
return span.export();
|
|
22696
|
+
};
|
|
22697
|
+
const optionsWithHooks = injectTracingHooks(
|
|
22698
|
+
options,
|
|
22699
|
+
resolveToolUseParentSpan,
|
|
22700
|
+
taskIdToToolUseId,
|
|
22701
|
+
toolUseToParent,
|
|
22702
|
+
activeToolSpans,
|
|
22703
|
+
localToolHookNames,
|
|
22704
|
+
skipLocalToolHooks,
|
|
22705
|
+
subAgentDetailsByToolUseId,
|
|
22706
|
+
subAgentSpans,
|
|
22707
|
+
endedSubAgentSpans
|
|
22708
|
+
);
|
|
22709
|
+
params.options = optionsWithHooks;
|
|
22710
|
+
return {
|
|
22711
|
+
activeLlmSpansByParentToolUse,
|
|
22712
|
+
activePartialMessageIdByParentKey: /* @__PURE__ */ new Map(),
|
|
22713
|
+
activeToolSpans,
|
|
22714
|
+
conversationHistoryByParentKey,
|
|
22715
|
+
capturedPromptMessages,
|
|
22716
|
+
currentMessageId: void 0,
|
|
22717
|
+
currentMessageStartTime: startTime,
|
|
22718
|
+
currentMessages: [],
|
|
22719
|
+
endedSubAgentSpans,
|
|
22720
|
+
finalOutputUsageMessageIds: /* @__PURE__ */ new Set(),
|
|
22721
|
+
finalResults: [],
|
|
22722
|
+
options: optionsWithHooks,
|
|
22723
|
+
originalPrompt,
|
|
22724
|
+
processing: Promise.resolve(),
|
|
22725
|
+
promptDone,
|
|
22726
|
+
promptMessagesByParentKey,
|
|
22727
|
+
promptStarted: () => promptStarted,
|
|
22728
|
+
promptSourcePriorityByParentKey,
|
|
22729
|
+
span,
|
|
22730
|
+
subAgentDetailsByToolUseId,
|
|
22731
|
+
subAgentSpans,
|
|
22732
|
+
taskIdToToolUseId,
|
|
22733
|
+
latestLlmParentBySubAgentToolUse,
|
|
22734
|
+
latestRootLlmParentRef,
|
|
22735
|
+
toolUseToParent,
|
|
22736
|
+
usageByMessageId: /* @__PURE__ */ new Map(),
|
|
22737
|
+
localToolParentResolver: resolveToolUseParentSpan
|
|
22738
|
+
};
|
|
22739
|
+
};
|
|
22740
|
+
const finishQuery = (state, result) => {
|
|
22741
|
+
if (isAsyncIterable(result)) {
|
|
22742
|
+
patchStreamIfNeeded(result, {
|
|
22743
|
+
aroundNext: (callback) => runWithClaudeLocalToolContext(
|
|
22744
|
+
callback,
|
|
22745
|
+
state.localToolParentResolver
|
|
22746
|
+
),
|
|
22747
|
+
onChunk: (message) => {
|
|
22748
|
+
maybeTrackToolUseContext(state, message);
|
|
22749
|
+
state.processing = state.processing.then(() => handleStreamMessage(state, message)).catch((error) => {
|
|
22750
|
+
console.error(
|
|
22751
|
+
"Error processing Claude Agent SDK stream chunk:",
|
|
22752
|
+
error
|
|
22753
|
+
);
|
|
22754
|
+
});
|
|
22755
|
+
},
|
|
22756
|
+
onComplete: () => state.processing.then(() => finalizeQuerySpan(state)),
|
|
22757
|
+
onError: (error) => state.processing.then(() => {
|
|
22758
|
+
state.span.log({ error: error.message });
|
|
22759
|
+
}).then(() => finalizeQuerySpan(state))
|
|
21889
22760
|
});
|
|
22761
|
+
return;
|
|
22762
|
+
}
|
|
22763
|
+
try {
|
|
22764
|
+
state.span.log({ output: result });
|
|
22765
|
+
} catch (error) {
|
|
22766
|
+
console.error("Error extracting output for Claude Agent SDK:", error);
|
|
22767
|
+
} finally {
|
|
21890
22768
|
state.span.end();
|
|
21891
|
-
spans.delete(event);
|
|
21892
22769
|
}
|
|
21893
22770
|
};
|
|
21894
|
-
|
|
21895
|
-
|
|
21896
|
-
|
|
21897
|
-
|
|
22771
|
+
this.unsubscribers.push(
|
|
22772
|
+
claudeAgentSDKChannels.query.intercept((target, thisArg, args) => {
|
|
22773
|
+
let state;
|
|
22774
|
+
try {
|
|
22775
|
+
args[0] ??= {};
|
|
22776
|
+
state = startQuery(args[0]);
|
|
22777
|
+
} catch (error) {
|
|
22778
|
+
debugLogger.error(
|
|
22779
|
+
"Error starting Claude Agent SDK instrumentation:",
|
|
22780
|
+
error
|
|
22781
|
+
);
|
|
22782
|
+
}
|
|
22783
|
+
const invokeTarget = () => Reflect.apply(target, thisArg, args);
|
|
22784
|
+
try {
|
|
22785
|
+
const result = state ? runWithClaudeLocalToolContext(
|
|
22786
|
+
invokeTarget,
|
|
22787
|
+
state.localToolParentResolver
|
|
22788
|
+
) : invokeTarget();
|
|
22789
|
+
if (state) {
|
|
22790
|
+
try {
|
|
22791
|
+
finishQuery(state, result);
|
|
22792
|
+
} catch (error) {
|
|
22793
|
+
debugLogger.error(
|
|
22794
|
+
"Error finalizing Claude Agent SDK instrumentation:",
|
|
22795
|
+
error
|
|
22796
|
+
);
|
|
22797
|
+
}
|
|
22798
|
+
}
|
|
22799
|
+
return result;
|
|
22800
|
+
} catch (error) {
|
|
22801
|
+
if (state) {
|
|
22802
|
+
try {
|
|
22803
|
+
state.span.log({
|
|
22804
|
+
error: error instanceof Error ? error.message : String(error)
|
|
22805
|
+
});
|
|
22806
|
+
state.span.end();
|
|
22807
|
+
} catch (instrumentationError) {
|
|
22808
|
+
debugLogger.error(
|
|
22809
|
+
"Error handling Claude Agent SDK instrumentation failure:",
|
|
22810
|
+
instrumentationError
|
|
22811
|
+
);
|
|
22812
|
+
}
|
|
22813
|
+
}
|
|
22814
|
+
throw error;
|
|
22815
|
+
}
|
|
22816
|
+
})
|
|
22817
|
+
);
|
|
21898
22818
|
}
|
|
21899
22819
|
};
|
|
21900
22820
|
|
|
@@ -26008,7 +26928,7 @@ function patchOpenRouterCallModelResult(args) {
|
|
|
26008
26928
|
span,
|
|
26009
26929
|
() => originalMethod.apply(resultLike, args2)
|
|
26010
26930
|
);
|
|
26011
|
-
if (!
|
|
26931
|
+
if (!isAsyncIterable3(stream)) {
|
|
26012
26932
|
return stream;
|
|
26013
26933
|
}
|
|
26014
26934
|
return wrapAsyncIterableWithSpan({
|
|
@@ -26203,7 +27123,7 @@ function wrapAsyncIterableWithSpan(args) {
|
|
|
26203
27123
|
}
|
|
26204
27124
|
};
|
|
26205
27125
|
}
|
|
26206
|
-
function
|
|
27126
|
+
function isAsyncIterable3(value) {
|
|
26207
27127
|
return !!value && (typeof value === "object" || typeof value === "function") && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
26208
27128
|
}
|
|
26209
27129
|
function normalizeError(error) {
|
|
@@ -27081,7 +28001,7 @@ function patchOpenRouterCallModelResult2(args) {
|
|
|
27081
28001
|
span,
|
|
27082
28002
|
() => originalMethod.apply(resultLike, args2)
|
|
27083
28003
|
);
|
|
27084
|
-
if (!
|
|
28004
|
+
if (!isAsyncIterable4(stream)) {
|
|
27085
28005
|
return stream;
|
|
27086
28006
|
}
|
|
27087
28007
|
return wrapAsyncIterableWithSpan2({
|
|
@@ -27276,7 +28196,7 @@ function wrapAsyncIterableWithSpan2(args) {
|
|
|
27276
28196
|
}
|
|
27277
28197
|
};
|
|
27278
28198
|
}
|
|
27279
|
-
function
|
|
28199
|
+
function isAsyncIterable4(value) {
|
|
27280
28200
|
return !!value && (typeof value === "object" || typeof value === "function") && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
27281
28201
|
}
|
|
27282
28202
|
function normalizeError2(error) {
|
|
@@ -33268,12 +34188,14 @@ function getMetricsFromResponse(response) {
|
|
|
33268
34188
|
continue;
|
|
33269
34189
|
}
|
|
33270
34190
|
const inputTokenDetails = usageMetadata.input_token_details;
|
|
34191
|
+
const outputTokenDetails = usageMetadata.output_token_details;
|
|
33271
34192
|
return normalizeTokenMetrics({
|
|
33272
34193
|
total_tokens: usageMetadata.total_tokens,
|
|
33273
34194
|
prompt_tokens: usageMetadata.input_tokens,
|
|
33274
34195
|
completion_tokens: usageMetadata.output_tokens,
|
|
33275
34196
|
prompt_cache_creation_tokens: isRecord(inputTokenDetails) ? inputTokenDetails.cache_creation : void 0,
|
|
33276
|
-
prompt_cached_tokens: isRecord(inputTokenDetails) ? inputTokenDetails.cache_read : void 0
|
|
34197
|
+
prompt_cached_tokens: isRecord(inputTokenDetails) ? inputTokenDetails.cache_read : void 0,
|
|
34198
|
+
completion_reasoning_tokens: isRecord(outputTokenDetails) ? outputTokenDetails.reasoning : void 0
|
|
33277
34199
|
});
|
|
33278
34200
|
}
|
|
33279
34201
|
const llmOutput = response.llmOutput || {};
|
|
@@ -33860,6 +34782,9 @@ var piCodingAgentChannels = defineChannels(
|
|
|
33860
34782
|
// src/instrumentation/plugins/pi-coding-agent-plugin.ts
|
|
33861
34783
|
var piAgentPatchStates = /* @__PURE__ */ new WeakMap();
|
|
33862
34784
|
var piAgentEventSubscriptions = /* @__PURE__ */ new WeakSet();
|
|
34785
|
+
var PI_TOOL_EXECUTE_WRAPPED = /* @__PURE__ */ Symbol.for(
|
|
34786
|
+
"braintrust.pi_coding_agent.tool_execute_wrapped"
|
|
34787
|
+
);
|
|
33863
34788
|
var piPromptContextStore;
|
|
33864
34789
|
var PiCodingAgentPlugin = class extends BasePlugin {
|
|
33865
34790
|
activePromptStates = /* @__PURE__ */ new Set();
|
|
@@ -33940,6 +34865,7 @@ function startPiPromptRun(event, onFinalize) {
|
|
|
33940
34865
|
return void 0;
|
|
33941
34866
|
}
|
|
33942
34867
|
installPiAgentInstrumentation(agent);
|
|
34868
|
+
wrapPiToolExecutors(agent.state?.tools);
|
|
33943
34869
|
const metadata = {
|
|
33944
34870
|
...extractSessionMetadata(session),
|
|
33945
34871
|
...extractPromptOptionsMetadata(event.arguments[1]),
|
|
@@ -33984,7 +34910,7 @@ function extractSession(event) {
|
|
|
33984
34910
|
return isObject(candidate) && typeof candidate.prompt === "function" ? candidate : void 0;
|
|
33985
34911
|
}
|
|
33986
34912
|
function isPiAgent(value) {
|
|
33987
|
-
return isObject(value) && typeof value.streamFn === "function" && typeof value.subscribe === "function";
|
|
34913
|
+
return isObject(value) && (typeof value.streamFunction === "function" || typeof value.streamFn === "function") && typeof value.subscribe === "function";
|
|
33988
34914
|
}
|
|
33989
34915
|
function promptContextStore() {
|
|
33990
34916
|
piPromptContextStore ??= isomorph_default.newAsyncLocalStorage();
|
|
@@ -33994,17 +34920,21 @@ function currentPiPromptState() {
|
|
|
33994
34920
|
return promptContextStore().getStore();
|
|
33995
34921
|
}
|
|
33996
34922
|
function installPiAgentInstrumentation(agent) {
|
|
34923
|
+
const property = typeof agent.streamFunction === "function" ? "streamFunction" : "streamFn";
|
|
34924
|
+
const streamFunction = agent[property];
|
|
33997
34925
|
const existing = piAgentPatchStates.get(agent);
|
|
33998
|
-
if (!existing ||
|
|
34926
|
+
if (streamFunction && (!existing || existing.property !== property || streamFunction !== existing.wrappedStreamFunction)) {
|
|
33999
34927
|
const patchState = {
|
|
34000
|
-
|
|
34001
|
-
|
|
34928
|
+
originalStreamFunction: streamFunction,
|
|
34929
|
+
property,
|
|
34930
|
+
wrappedStreamFunction: streamFunction
|
|
34002
34931
|
};
|
|
34003
|
-
patchState.
|
|
34932
|
+
patchState.wrappedStreamFunction = makeInstrumentedStreamFunction(
|
|
34004
34933
|
agent,
|
|
34005
|
-
patchState.
|
|
34934
|
+
patchState.originalStreamFunction,
|
|
34935
|
+
property
|
|
34006
34936
|
);
|
|
34007
|
-
agent
|
|
34937
|
+
agent[property] = patchState.wrappedStreamFunction;
|
|
34008
34938
|
piAgentPatchStates.set(agent, patchState);
|
|
34009
34939
|
}
|
|
34010
34940
|
if (piAgentEventSubscriptions.has(agent)) {
|
|
@@ -34029,14 +34959,21 @@ function installPiAgentInstrumentation(agent) {
|
|
|
34029
34959
|
logInstrumentationError4("Pi Coding Agent event subscription", error);
|
|
34030
34960
|
}
|
|
34031
34961
|
}
|
|
34032
|
-
function
|
|
34033
|
-
return async function
|
|
34034
|
-
const invokeOriginal = () => Reflect.apply(
|
|
34962
|
+
function makeInstrumentedStreamFunction(agent, originalStreamFunction, property) {
|
|
34963
|
+
return async function instrumentedPiStreamFunction(model, context, options) {
|
|
34964
|
+
const invokeOriginal = () => Reflect.apply(originalStreamFunction, this, [model, context, options]);
|
|
34035
34965
|
const state = currentPiPromptState();
|
|
34036
34966
|
if (!state || state.agent !== agent || state.finalized) {
|
|
34037
34967
|
return invokeOriginal();
|
|
34038
34968
|
}
|
|
34039
|
-
|
|
34969
|
+
wrapPiToolExecutors(context.tools);
|
|
34970
|
+
const llmState = await startPiLlmSpan(
|
|
34971
|
+
state,
|
|
34972
|
+
model,
|
|
34973
|
+
context,
|
|
34974
|
+
property,
|
|
34975
|
+
options
|
|
34976
|
+
);
|
|
34040
34977
|
try {
|
|
34041
34978
|
const stream = await runWithAutoInstrumentationSuppressed(invokeOriginal);
|
|
34042
34979
|
return patchAssistantMessageStream(stream, state, llmState);
|
|
@@ -34046,12 +34983,39 @@ function makeInstrumentedStreamFn(agent, originalStreamFn) {
|
|
|
34046
34983
|
}
|
|
34047
34984
|
};
|
|
34048
34985
|
}
|
|
34049
|
-
|
|
34986
|
+
function wrapPiToolExecutors(tools) {
|
|
34987
|
+
if (!tools) {
|
|
34988
|
+
return;
|
|
34989
|
+
}
|
|
34990
|
+
for (const tool of tools) {
|
|
34991
|
+
try {
|
|
34992
|
+
const execute = tool.execute;
|
|
34993
|
+
if (typeof execute !== "function" || execute[PI_TOOL_EXECUTE_WRAPPED]) {
|
|
34994
|
+
continue;
|
|
34995
|
+
}
|
|
34996
|
+
const wrappedExecute = function(...args) {
|
|
34997
|
+
return runWithAutoInstrumentationAllowed(
|
|
34998
|
+
() => Reflect.apply(execute, this, args)
|
|
34999
|
+
);
|
|
35000
|
+
};
|
|
35001
|
+
Object.defineProperty(wrappedExecute, PI_TOOL_EXECUTE_WRAPPED, {
|
|
35002
|
+
configurable: false,
|
|
35003
|
+
enumerable: false,
|
|
35004
|
+
value: true,
|
|
35005
|
+
writable: false
|
|
35006
|
+
});
|
|
35007
|
+
tool.execute = wrappedExecute;
|
|
35008
|
+
} catch (error) {
|
|
35009
|
+
logInstrumentationError4("Pi Coding Agent tool wrapping", error);
|
|
35010
|
+
}
|
|
35011
|
+
}
|
|
35012
|
+
}
|
|
35013
|
+
async function startPiLlmSpan(state, model, context, property, options) {
|
|
34050
35014
|
const metadata = {
|
|
34051
35015
|
...extractModelMetadata2(model),
|
|
34052
35016
|
...extractStreamOptionsMetadata(options),
|
|
34053
35017
|
...extractToolMetadata(context.tools),
|
|
34054
|
-
"pi_coding_agent.operation":
|
|
35018
|
+
"pi_coding_agent.operation": `agent.${property}`
|
|
34055
35019
|
};
|
|
34056
35020
|
const span = startSpan(
|
|
34057
35021
|
withSpanInstrumentationName(
|
|
@@ -34217,35 +35181,26 @@ async function startPiToolSpan(state, event) {
|
|
|
34217
35181
|
if (!event.toolCallId || state.activeToolSpans.has(event.toolCallId)) {
|
|
34218
35182
|
return;
|
|
34219
35183
|
}
|
|
34220
|
-
const restoreAutoInstrumentation = enterAutoInstrumentationAllowed();
|
|
34221
35184
|
const metadata = {
|
|
34222
35185
|
"gen_ai.tool.call.id": event.toolCallId,
|
|
34223
35186
|
"gen_ai.tool.name": event.toolName,
|
|
34224
35187
|
"pi_coding_agent.tool.name": event.toolName
|
|
34225
35188
|
};
|
|
34226
|
-
|
|
34227
|
-
|
|
34228
|
-
|
|
34229
|
-
{
|
|
34230
|
-
|
|
34231
|
-
|
|
34232
|
-
metadata
|
|
34233
|
-
},
|
|
34234
|
-
name: event.toolName || "tool",
|
|
34235
|
-
parent: await state.span.export(),
|
|
34236
|
-
spanAttributes: { type: "tool" /* TOOL */ }
|
|
35189
|
+
const span = startSpan(
|
|
35190
|
+
withSpanInstrumentationName(
|
|
35191
|
+
{
|
|
35192
|
+
event: {
|
|
35193
|
+
input: event.args,
|
|
35194
|
+
metadata
|
|
34237
35195
|
},
|
|
34238
|
-
|
|
34239
|
-
|
|
34240
|
-
|
|
34241
|
-
|
|
34242
|
-
|
|
34243
|
-
|
|
34244
|
-
|
|
34245
|
-
|
|
34246
|
-
restoreAutoInstrumentation();
|
|
34247
|
-
throw error;
|
|
34248
|
-
}
|
|
35196
|
+
name: event.toolName || "tool",
|
|
35197
|
+
parent: await state.span.export(),
|
|
35198
|
+
spanAttributes: { type: "tool" /* TOOL */ }
|
|
35199
|
+
},
|
|
35200
|
+
INSTRUMENTATION_NAMES.PI_CODING_AGENT
|
|
35201
|
+
)
|
|
35202
|
+
);
|
|
35203
|
+
state.activeToolSpans.set(event.toolCallId, { span });
|
|
34249
35204
|
}
|
|
34250
35205
|
function finishPiToolSpan(state, event) {
|
|
34251
35206
|
const toolState = state.activeToolSpans.get(event.toolCallId);
|
|
@@ -34266,11 +35221,7 @@ function finishPiToolSpan(state, event) {
|
|
|
34266
35221
|
output: event.result
|
|
34267
35222
|
});
|
|
34268
35223
|
} finally {
|
|
34269
|
-
|
|
34270
|
-
toolState.span.end();
|
|
34271
|
-
} finally {
|
|
34272
|
-
toolState.restoreAutoInstrumentation?.();
|
|
34273
|
-
}
|
|
35224
|
+
toolState.span.end();
|
|
34274
35225
|
}
|
|
34275
35226
|
}
|
|
34276
35227
|
function finishPiPromptRun(state, error) {
|
|
@@ -34320,10 +35271,10 @@ function finishPiLlmSpan(promptState, llmState, message, error) {
|
|
|
34320
35271
|
...cleanMetrics5(llmState.metrics),
|
|
34321
35272
|
...buildDurationMetrics3(llmState.startTime)
|
|
34322
35273
|
};
|
|
34323
|
-
const
|
|
34324
|
-
if (Object.keys(
|
|
35274
|
+
const usageMetrics2 = extractUsageMetrics2(message?.usage);
|
|
35275
|
+
if (Object.keys(usageMetrics2).length > 0) {
|
|
34325
35276
|
promptState.collectedLlmUsageMetrics = true;
|
|
34326
|
-
addMetrics(promptState.metrics,
|
|
35277
|
+
addMetrics(promptState.metrics, usageMetrics2);
|
|
34327
35278
|
}
|
|
34328
35279
|
try {
|
|
34329
35280
|
safeLog4(llmState.span, {
|
|
@@ -34341,14 +35292,10 @@ function finishPiLlmSpan(promptState, llmState, message, error) {
|
|
|
34341
35292
|
}
|
|
34342
35293
|
function finishOpenToolSpans(state, error) {
|
|
34343
35294
|
for (const [, toolState] of state.activeToolSpans) {
|
|
34344
|
-
|
|
34345
|
-
|
|
34346
|
-
|
|
34347
|
-
|
|
34348
|
-
toolState.span.end();
|
|
34349
|
-
} finally {
|
|
34350
|
-
toolState.restoreAutoInstrumentation?.();
|
|
34351
|
-
}
|
|
35295
|
+
safeLog4(toolState.span, {
|
|
35296
|
+
error: error ? toLoggedError(error) : "Pi tool did not complete"
|
|
35297
|
+
});
|
|
35298
|
+
toolState.span.end();
|
|
34352
35299
|
}
|
|
34353
35300
|
state.activeToolSpans.clear();
|
|
34354
35301
|
}
|
|
@@ -34667,12 +35614,12 @@ var MAX_STRANDS_STRING_ATTACHMENT_CACHE_ENTRIES = 32;
|
|
|
34667
35614
|
var StrandsAgentSDKPlugin = class extends BasePlugin {
|
|
34668
35615
|
activeChildParents = /* @__PURE__ */ new WeakMap();
|
|
34669
35616
|
onEnable() {
|
|
34670
|
-
this.
|
|
34671
|
-
this.
|
|
35617
|
+
this.interceptAgentStream();
|
|
35618
|
+
this.interceptMultiAgentStream(
|
|
34672
35619
|
strandsAgentSDKChannels.graphStream,
|
|
34673
35620
|
"Graph.stream"
|
|
34674
35621
|
);
|
|
34675
|
-
this.
|
|
35622
|
+
this.interceptMultiAgentStream(
|
|
34676
35623
|
strandsAgentSDKChannels.swarmStream,
|
|
34677
35624
|
"Swarm.stream"
|
|
34678
35625
|
);
|
|
@@ -34683,122 +35630,92 @@ var StrandsAgentSDKPlugin = class extends BasePlugin {
|
|
|
34683
35630
|
}
|
|
34684
35631
|
this.unsubscribers = [];
|
|
34685
35632
|
}
|
|
34686
|
-
|
|
34687
|
-
|
|
34688
|
-
|
|
34689
|
-
|
|
34690
|
-
|
|
34691
|
-
|
|
34692
|
-
|
|
34693
|
-
|
|
34694
|
-
|
|
34695
|
-
|
|
34696
|
-
|
|
34697
|
-
|
|
34698
|
-
|
|
34699
|
-
|
|
34700
|
-
|
|
34701
|
-
|
|
34702
|
-
const result = event.result;
|
|
34703
|
-
if (isAsyncIterable(result)) {
|
|
34704
|
-
patchStreamIfNeeded(result, {
|
|
34705
|
-
aroundNext: (callback) => runWithAutoInstrumentationSuppressed(callback),
|
|
34706
|
-
onChunk: (chunk) => handleAgentStreamEvent(state, chunk),
|
|
34707
|
-
onComplete: () => {
|
|
34708
|
-
finalizeAgentStream(state);
|
|
34709
|
-
states.delete(event);
|
|
34710
|
-
},
|
|
34711
|
-
onError: (error) => {
|
|
34712
|
-
finalizeAgentStream(state, error);
|
|
34713
|
-
states.delete(event);
|
|
34714
|
-
}
|
|
34715
|
-
});
|
|
34716
|
-
return;
|
|
34717
|
-
}
|
|
34718
|
-
finalizeAgentStream(state, void 0, result);
|
|
34719
|
-
states.delete(event);
|
|
34720
|
-
},
|
|
34721
|
-
error: (event) => {
|
|
34722
|
-
const state = states.get(event);
|
|
34723
|
-
if (!state || !event.error) {
|
|
34724
|
-
return;
|
|
34725
|
-
}
|
|
34726
|
-
finalizeAgentStream(state, event.error);
|
|
34727
|
-
states.delete(event);
|
|
34728
|
-
}
|
|
34729
|
-
};
|
|
34730
|
-
channel2.subscribe(handlers);
|
|
34731
|
-
this.unsubscribers.push(() => {
|
|
34732
|
-
unbindAutoInstrumentationSuppression?.();
|
|
34733
|
-
channel2.unsubscribe(handlers);
|
|
34734
|
-
});
|
|
35633
|
+
interceptAgentStream() {
|
|
35634
|
+
this.unsubscribers.push(
|
|
35635
|
+
strandsAgentSDKChannels.agentStream.intercept(
|
|
35636
|
+
(target, thisArg, args, additional) => instrumentStrandsStreamInvocation({
|
|
35637
|
+
finalize: finalizeAgentStream,
|
|
35638
|
+
handleChunk: handleAgentStreamEvent,
|
|
35639
|
+
invoke: () => Reflect.apply(target, thisArg, args),
|
|
35640
|
+
name: "Strands Agent SDK",
|
|
35641
|
+
start: () => startAgentStream(
|
|
35642
|
+
args[0],
|
|
35643
|
+
extractAgent(additional.agent, thisArg),
|
|
35644
|
+
this.activeChildParents
|
|
35645
|
+
)
|
|
35646
|
+
})
|
|
35647
|
+
)
|
|
35648
|
+
);
|
|
34735
35649
|
}
|
|
34736
|
-
|
|
34737
|
-
|
|
34738
|
-
|
|
34739
|
-
|
|
34740
|
-
|
|
34741
|
-
|
|
34742
|
-
|
|
34743
|
-
|
|
34744
|
-
|
|
34745
|
-
|
|
34746
|
-
|
|
34747
|
-
|
|
34748
|
-
|
|
34749
|
-
|
|
34750
|
-
|
|
34751
|
-
|
|
34752
|
-
|
|
34753
|
-
|
|
34754
|
-
|
|
34755
|
-
}
|
|
34756
|
-
|
|
34757
|
-
|
|
34758
|
-
|
|
34759
|
-
|
|
34760
|
-
|
|
34761
|
-
|
|
34762
|
-
|
|
34763
|
-
|
|
34764
|
-
|
|
34765
|
-
|
|
34766
|
-
|
|
34767
|
-
|
|
34768
|
-
|
|
34769
|
-
|
|
34770
|
-
|
|
34771
|
-
|
|
34772
|
-
|
|
34773
|
-
|
|
34774
|
-
|
|
34775
|
-
|
|
34776
|
-
|
|
34777
|
-
|
|
34778
|
-
this.activeChildParents,
|
|
34779
|
-
void 0,
|
|
34780
|
-
result
|
|
35650
|
+
interceptMultiAgentStream(channel2, operation) {
|
|
35651
|
+
this.unsubscribers.push(
|
|
35652
|
+
channel2.intercept(
|
|
35653
|
+
(target, thisArg, args, additional) => instrumentStrandsStreamInvocation({
|
|
35654
|
+
finalize: (state, error, output) => finalizeMultiAgentStream(
|
|
35655
|
+
state,
|
|
35656
|
+
this.activeChildParents,
|
|
35657
|
+
error,
|
|
35658
|
+
output
|
|
35659
|
+
),
|
|
35660
|
+
handleChunk: (state, chunk) => handleMultiAgentStreamEvent(state, chunk, this.activeChildParents),
|
|
35661
|
+
invoke: () => Reflect.apply(target, thisArg, args),
|
|
35662
|
+
name: "Strands multi-agent",
|
|
35663
|
+
start: () => startMultiAgentStream(
|
|
35664
|
+
args[0],
|
|
35665
|
+
extractOrchestrator(additional.orchestrator, thisArg),
|
|
35666
|
+
operation,
|
|
35667
|
+
this.activeChildParents
|
|
35668
|
+
)
|
|
35669
|
+
})
|
|
35670
|
+
)
|
|
35671
|
+
);
|
|
35672
|
+
}
|
|
35673
|
+
};
|
|
35674
|
+
function instrumentStrandsStreamInvocation(options) {
|
|
35675
|
+
let state;
|
|
35676
|
+
try {
|
|
35677
|
+
state = options.start();
|
|
35678
|
+
} catch (error) {
|
|
35679
|
+
debugLogger.error(`Error starting ${options.name} instrumentation:`, error);
|
|
35680
|
+
}
|
|
35681
|
+
let result;
|
|
35682
|
+
try {
|
|
35683
|
+
result = runWithAutoInstrumentationSuppressed(options.invoke);
|
|
35684
|
+
} catch (error) {
|
|
35685
|
+
if (state) {
|
|
35686
|
+
try {
|
|
35687
|
+
options.finalize(state, error);
|
|
35688
|
+
} catch (instrumentationError) {
|
|
35689
|
+
debugLogger.error(
|
|
35690
|
+
`Error handling ${options.name} instrumentation failure:`,
|
|
35691
|
+
instrumentationError
|
|
34781
35692
|
);
|
|
34782
|
-
states.delete(event);
|
|
34783
|
-
},
|
|
34784
|
-
error: (event) => {
|
|
34785
|
-
const state = states.get(event);
|
|
34786
|
-
if (!state || !event.error) {
|
|
34787
|
-
return;
|
|
34788
|
-
}
|
|
34789
|
-
finalizeMultiAgentStream(state, this.activeChildParents, event.error);
|
|
34790
|
-
states.delete(event);
|
|
34791
35693
|
}
|
|
34792
|
-
}
|
|
34793
|
-
|
|
34794
|
-
this.unsubscribers.push(() => {
|
|
34795
|
-
unbindAutoInstrumentationSuppression?.();
|
|
34796
|
-
tracingChannel.unsubscribe(handlers);
|
|
34797
|
-
});
|
|
35694
|
+
}
|
|
35695
|
+
throw error;
|
|
34798
35696
|
}
|
|
34799
|
-
|
|
34800
|
-
|
|
34801
|
-
|
|
35697
|
+
if (state) {
|
|
35698
|
+
try {
|
|
35699
|
+
if (isAsyncIterable(result)) {
|
|
35700
|
+
patchStreamIfNeeded(result, {
|
|
35701
|
+
aroundNext: (callback) => runWithAutoInstrumentationSuppressed(callback),
|
|
35702
|
+
onChunk: (chunk) => options.handleChunk(state, chunk),
|
|
35703
|
+
onComplete: () => options.finalize(state),
|
|
35704
|
+
onError: (error) => options.finalize(state, error)
|
|
35705
|
+
});
|
|
35706
|
+
} else {
|
|
35707
|
+
options.finalize(state, void 0, result);
|
|
35708
|
+
}
|
|
35709
|
+
} catch (error) {
|
|
35710
|
+
debugLogger.error(
|
|
35711
|
+
`Error finalizing ${options.name} instrumentation:`,
|
|
35712
|
+
error
|
|
35713
|
+
);
|
|
35714
|
+
}
|
|
35715
|
+
}
|
|
35716
|
+
return result;
|
|
35717
|
+
}
|
|
35718
|
+
function startAgentStream(input, agent, activeChildParents) {
|
|
34802
35719
|
const model = agent?.model;
|
|
34803
35720
|
const metadata = {
|
|
34804
35721
|
...extractAgentMetadata2(agent),
|
|
@@ -34808,17 +35725,14 @@ function startAgentStream(event, activeChildParents) {
|
|
|
34808
35725
|
};
|
|
34809
35726
|
const parentSpan = agent ? getOnlyChildParent(activeChildParents, agent) : void 0;
|
|
34810
35727
|
const attachmentCache = createStrandsAttachmentCache();
|
|
34811
|
-
const
|
|
34812
|
-
event.arguments[0],
|
|
34813
|
-
attachmentCache
|
|
34814
|
-
);
|
|
35728
|
+
const processedInput = processStrandsInputAttachments(input, attachmentCache);
|
|
34815
35729
|
const span = parentSpan ? withCurrent(
|
|
34816
35730
|
parentSpan,
|
|
34817
35731
|
() => startSpan(
|
|
34818
35732
|
withSpanInstrumentationName(
|
|
34819
35733
|
{
|
|
34820
35734
|
event: {
|
|
34821
|
-
input,
|
|
35735
|
+
input: processedInput,
|
|
34822
35736
|
metadata
|
|
34823
35737
|
},
|
|
34824
35738
|
name: formatAgentSpanName(agent),
|
|
@@ -34831,7 +35745,7 @@ function startAgentStream(event, activeChildParents) {
|
|
|
34831
35745
|
withSpanInstrumentationName(
|
|
34832
35746
|
{
|
|
34833
35747
|
event: {
|
|
34834
|
-
input,
|
|
35748
|
+
input: processedInput,
|
|
34835
35749
|
metadata
|
|
34836
35750
|
},
|
|
34837
35751
|
name: formatAgentSpanName(agent),
|
|
@@ -34849,22 +35763,21 @@ function startAgentStream(event, activeChildParents) {
|
|
|
34849
35763
|
startTime: getCurrentUnixTimestamp()
|
|
34850
35764
|
};
|
|
34851
35765
|
}
|
|
34852
|
-
function startMultiAgentStream(
|
|
34853
|
-
const orchestrator = extractOrchestrator(event);
|
|
35766
|
+
function startMultiAgentStream(input, orchestrator, operation, activeChildParents) {
|
|
34854
35767
|
const metadata = {
|
|
34855
35768
|
"strands.operation": operation,
|
|
34856
35769
|
provider: "strands",
|
|
34857
35770
|
...orchestrator?.id ? { "strands.orchestrator.id": orchestrator.id } : {}
|
|
34858
35771
|
};
|
|
34859
35772
|
const parentSpan = orchestrator ? getOnlyChildParent(activeChildParents, orchestrator) : void 0;
|
|
34860
|
-
const
|
|
35773
|
+
const processedInput = processStrandsInputAttachments(input);
|
|
34861
35774
|
const span = parentSpan ? withCurrent(
|
|
34862
35775
|
parentSpan,
|
|
34863
35776
|
() => startSpan(
|
|
34864
35777
|
withSpanInstrumentationName(
|
|
34865
35778
|
{
|
|
34866
35779
|
event: {
|
|
34867
|
-
input,
|
|
35780
|
+
input: processedInput,
|
|
34868
35781
|
metadata
|
|
34869
35782
|
},
|
|
34870
35783
|
name: operation === "Graph.stream" ? "Strands Graph" : "Strands Swarm",
|
|
@@ -34877,7 +35790,7 @@ function startMultiAgentStream(event, operation, activeChildParents) {
|
|
|
34877
35790
|
withSpanInstrumentationName(
|
|
34878
35791
|
{
|
|
34879
35792
|
event: {
|
|
34880
|
-
input,
|
|
35793
|
+
input: processedInput,
|
|
34881
35794
|
metadata
|
|
34882
35795
|
},
|
|
34883
35796
|
name: operation === "Graph.stream" ? "Strands Graph" : "Strands Swarm",
|
|
@@ -35248,12 +36161,12 @@ function finalizeMultiAgentStream(state, activeChildParents, error, output) {
|
|
|
35248
36161
|
});
|
|
35249
36162
|
state.span.end();
|
|
35250
36163
|
}
|
|
35251
|
-
function extractAgent(
|
|
35252
|
-
const candidate =
|
|
36164
|
+
function extractAgent(agent, self) {
|
|
36165
|
+
const candidate = agent ?? self;
|
|
35253
36166
|
return isObject(candidate) && typeof candidate.stream === "function" ? candidate : void 0;
|
|
35254
36167
|
}
|
|
35255
|
-
function extractOrchestrator(
|
|
35256
|
-
const candidate =
|
|
36168
|
+
function extractOrchestrator(orchestrator, self) {
|
|
36169
|
+
const candidate = orchestrator ?? self;
|
|
35257
36170
|
return isObject(candidate) && typeof candidate.stream === "function" ? candidate : void 0;
|
|
35258
36171
|
}
|
|
35259
36172
|
function extractAgentMetadata2(agent) {
|
|
@@ -37118,6 +38031,7 @@ __export(exports_exports, {
|
|
|
37118
38031
|
braintrustStreamChunkSchema: () => braintrustStreamChunkSchema,
|
|
37119
38032
|
buildLocalSummary: () => buildLocalSummary,
|
|
37120
38033
|
collectAnthropicSession: () => collectAnthropicSession,
|
|
38034
|
+
completeOpenAIBatchTrace: () => completeOpenAIBatchTrace,
|
|
37121
38035
|
configureInstrumentation: () => configureInstrumentation,
|
|
37122
38036
|
constructLogs3OverflowRequest: () => constructLogs3OverflowRequest,
|
|
37123
38037
|
createFinalValuePassThroughStream: () => createFinalValuePassThroughStream,
|
|
@@ -37156,6 +38070,8 @@ __export(exports_exports, {
|
|
|
37156
38070
|
loginToState: () => loginToState,
|
|
37157
38071
|
logs3OverflowUploadSchema: () => logs3OverflowUploadSchema,
|
|
37158
38072
|
newId: () => newId,
|
|
38073
|
+
openaiBatchesRetrieveTraced: () => openaiBatchesRetrieveTraced,
|
|
38074
|
+
openaiFilesCreateTraced: () => openaiFilesCreateTraced,
|
|
37159
38075
|
parseCachedHeader: () => parseCachedHeader,
|
|
37160
38076
|
parseTemplateFormat: () => parseTemplateFormat,
|
|
37161
38077
|
permalink: () => permalink,
|
|
@@ -37320,6 +38236,260 @@ async function registerSandbox(options) {
|
|
|
37320
38236
|
};
|
|
37321
38237
|
}
|
|
37322
38238
|
|
|
38239
|
+
// src/wrappers/openai-promise-utils.ts
|
|
38240
|
+
function splitSpanInfo(allParams) {
|
|
38241
|
+
const { span_info, ...params } = allParams;
|
|
38242
|
+
return {
|
|
38243
|
+
params,
|
|
38244
|
+
span_info
|
|
38245
|
+
};
|
|
38246
|
+
}
|
|
38247
|
+
function createChannelContext(_channel, params, span_info) {
|
|
38248
|
+
return {
|
|
38249
|
+
arguments: (
|
|
38250
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38251
|
+
[params]
|
|
38252
|
+
),
|
|
38253
|
+
span_info
|
|
38254
|
+
};
|
|
38255
|
+
}
|
|
38256
|
+
async function tracePromiseWithResponse(channel2, traceContext, apiPromise) {
|
|
38257
|
+
let enhancedResponse;
|
|
38258
|
+
const tracePromise = (
|
|
38259
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38260
|
+
channel2.tracePromise
|
|
38261
|
+
);
|
|
38262
|
+
const data = await tracePromise(async () => {
|
|
38263
|
+
enhancedResponse = await apiPromise.withResponse();
|
|
38264
|
+
traceContext.response = enhancedResponse.response;
|
|
38265
|
+
return enhancedResponse.data;
|
|
38266
|
+
}, traceContext);
|
|
38267
|
+
if (!enhancedResponse) {
|
|
38268
|
+
throw new Error("Expected withResponse() to provide response");
|
|
38269
|
+
}
|
|
38270
|
+
return {
|
|
38271
|
+
data,
|
|
38272
|
+
response: enhancedResponse.response,
|
|
38273
|
+
request_id: enhancedResponse.request_id
|
|
38274
|
+
};
|
|
38275
|
+
}
|
|
38276
|
+
async function tracePromiseAsResponse(channel2, traceContext, apiPromise) {
|
|
38277
|
+
const tracePromise = (
|
|
38278
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38279
|
+
channel2.tracePromise
|
|
38280
|
+
);
|
|
38281
|
+
let response;
|
|
38282
|
+
await tracePromise(async () => {
|
|
38283
|
+
response = await apiPromise.asResponse();
|
|
38284
|
+
traceContext.response = response;
|
|
38285
|
+
return void 0;
|
|
38286
|
+
}, traceContext);
|
|
38287
|
+
if (!response) {
|
|
38288
|
+
throw new Error("Expected asResponse() to provide response");
|
|
38289
|
+
}
|
|
38290
|
+
return response;
|
|
38291
|
+
}
|
|
38292
|
+
function createLazyAPIPromise(ensureExecuted, ensureResponse, getAPIPromise) {
|
|
38293
|
+
let firstConsumption;
|
|
38294
|
+
let enhancedResponsePromise;
|
|
38295
|
+
let dataPromise;
|
|
38296
|
+
let responsePromise;
|
|
38297
|
+
const withResponse = () => {
|
|
38298
|
+
firstConsumption ??= "data";
|
|
38299
|
+
enhancedResponsePromise ??= firstConsumption === "data" ? ensureExecuted() : getAPIPromise().withResponse();
|
|
38300
|
+
return enhancedResponsePromise;
|
|
38301
|
+
};
|
|
38302
|
+
const asResponse = () => {
|
|
38303
|
+
firstConsumption ??= "response";
|
|
38304
|
+
responsePromise ??= firstConsumption === "response" ? ensureResponse() : getAPIPromise().asResponse();
|
|
38305
|
+
return responsePromise;
|
|
38306
|
+
};
|
|
38307
|
+
return new Proxy({}, {
|
|
38308
|
+
get(target, prop, receiver) {
|
|
38309
|
+
if (prop === "withResponse") {
|
|
38310
|
+
return withResponse;
|
|
38311
|
+
}
|
|
38312
|
+
if (prop === "asResponse") {
|
|
38313
|
+
return asResponse;
|
|
38314
|
+
}
|
|
38315
|
+
if (prop === "then" || prop === "catch" || prop === "finally" || prop in Promise.prototype) {
|
|
38316
|
+
dataPromise ??= withResponse().then((result) => result.data);
|
|
38317
|
+
const value = Reflect.get(dataPromise, prop, receiver);
|
|
38318
|
+
return typeof value === "function" ? value.bind(dataPromise) : value;
|
|
38319
|
+
}
|
|
38320
|
+
return Reflect.get(target, prop, receiver);
|
|
38321
|
+
}
|
|
38322
|
+
});
|
|
38323
|
+
}
|
|
38324
|
+
|
|
38325
|
+
// src/openai-batch.ts
|
|
38326
|
+
function read2(value, key) {
|
|
38327
|
+
if (value === null || typeof value !== "object" && typeof value !== "function") {
|
|
38328
|
+
return void 0;
|
|
38329
|
+
}
|
|
38330
|
+
try {
|
|
38331
|
+
return Reflect.get(value, key);
|
|
38332
|
+
} catch {
|
|
38333
|
+
return void 0;
|
|
38334
|
+
}
|
|
38335
|
+
}
|
|
38336
|
+
function isAsyncIterable5(value) {
|
|
38337
|
+
return typeof read2(value, Symbol.asyncIterator) === "function";
|
|
38338
|
+
}
|
|
38339
|
+
function teeAsyncIterable(source) {
|
|
38340
|
+
const iterator = source[Symbol.asyncIterator]();
|
|
38341
|
+
const stream = new ReadableStream({
|
|
38342
|
+
async pull(controller) {
|
|
38343
|
+
try {
|
|
38344
|
+
const result = await iterator.next();
|
|
38345
|
+
if (result.done) {
|
|
38346
|
+
controller.close();
|
|
38347
|
+
return;
|
|
38348
|
+
}
|
|
38349
|
+
if (!(result.value instanceof Uint8Array)) {
|
|
38350
|
+
throw new TypeError(
|
|
38351
|
+
"OpenAI upload streams must yield Uint8Array chunks"
|
|
38352
|
+
);
|
|
38353
|
+
}
|
|
38354
|
+
controller.enqueue(result.value);
|
|
38355
|
+
} catch (error) {
|
|
38356
|
+
controller.error(error);
|
|
38357
|
+
}
|
|
38358
|
+
},
|
|
38359
|
+
async cancel(reason) {
|
|
38360
|
+
await iterator.return?.(reason);
|
|
38361
|
+
}
|
|
38362
|
+
});
|
|
38363
|
+
const [uploadStream, trace] = stream.tee();
|
|
38364
|
+
const upload = {
|
|
38365
|
+
async *[Symbol.asyncIterator]() {
|
|
38366
|
+
const reader = uploadStream.getReader();
|
|
38367
|
+
try {
|
|
38368
|
+
while (true) {
|
|
38369
|
+
const result = await reader.read();
|
|
38370
|
+
if (result.done) {
|
|
38371
|
+
return;
|
|
38372
|
+
}
|
|
38373
|
+
yield result.value;
|
|
38374
|
+
}
|
|
38375
|
+
} finally {
|
|
38376
|
+
reader.releaseLock();
|
|
38377
|
+
}
|
|
38378
|
+
}
|
|
38379
|
+
};
|
|
38380
|
+
const path = read2(source, "path");
|
|
38381
|
+
if (typeof path === "string") {
|
|
38382
|
+
Object.defineProperty(upload, "path", { value: path });
|
|
38383
|
+
}
|
|
38384
|
+
return { upload, trace: new Response(trace) };
|
|
38385
|
+
}
|
|
38386
|
+
function teeUpload(upload) {
|
|
38387
|
+
if (upload instanceof Blob) {
|
|
38388
|
+
return { upload, trace: new Response(upload) };
|
|
38389
|
+
}
|
|
38390
|
+
if (upload instanceof Response) {
|
|
38391
|
+
return { upload, trace: upload.clone() };
|
|
38392
|
+
}
|
|
38393
|
+
if (isAsyncIterable5(upload)) {
|
|
38394
|
+
return teeAsyncIterable(upload);
|
|
38395
|
+
}
|
|
38396
|
+
return void 0;
|
|
38397
|
+
}
|
|
38398
|
+
function openaiFilesCreateTraced(files) {
|
|
38399
|
+
return (params, options) => {
|
|
38400
|
+
const parent = getSpanParentObject();
|
|
38401
|
+
const purpose = read2(params, "purpose");
|
|
38402
|
+
const file = read2(params, "file");
|
|
38403
|
+
if (purpose !== "batch") {
|
|
38404
|
+
return files.create(params, options);
|
|
38405
|
+
}
|
|
38406
|
+
let branches;
|
|
38407
|
+
try {
|
|
38408
|
+
branches = teeUpload(file);
|
|
38409
|
+
} catch {
|
|
38410
|
+
return files.create(params, options);
|
|
38411
|
+
}
|
|
38412
|
+
if (!branches) {
|
|
38413
|
+
return files.create(params, options);
|
|
38414
|
+
}
|
|
38415
|
+
const tracedParams = {
|
|
38416
|
+
...Object(params),
|
|
38417
|
+
file: branches.upload
|
|
38418
|
+
};
|
|
38419
|
+
const apiPromise = files.create(tracedParams, options);
|
|
38420
|
+
let enhancedResponse;
|
|
38421
|
+
const tracedResponse = openAIChannels.filesCreateTraced.invoke(
|
|
38422
|
+
async () => {
|
|
38423
|
+
enhancedResponse = await apiPromise.withResponse();
|
|
38424
|
+
return enhancedResponse.data;
|
|
38425
|
+
},
|
|
38426
|
+
files,
|
|
38427
|
+
[{ params, inputFileContent: branches.trace, parent }],
|
|
38428
|
+
{}
|
|
38429
|
+
).then((data) => {
|
|
38430
|
+
if (!enhancedResponse) {
|
|
38431
|
+
throw new Error(
|
|
38432
|
+
"Expected OpenAI withResponse() to provide a response"
|
|
38433
|
+
);
|
|
38434
|
+
}
|
|
38435
|
+
return { ...enhancedResponse, data };
|
|
38436
|
+
});
|
|
38437
|
+
return createLazyAPIPromise(
|
|
38438
|
+
() => tracedResponse,
|
|
38439
|
+
() => tracedResponse.then(({ response }) => response),
|
|
38440
|
+
() => apiPromise
|
|
38441
|
+
);
|
|
38442
|
+
};
|
|
38443
|
+
}
|
|
38444
|
+
function openaiBatchesRetrieveTraced(batches) {
|
|
38445
|
+
return (batchId, options) => {
|
|
38446
|
+
const apiPromise = batches.retrieve(batchId, options);
|
|
38447
|
+
let enhancedResponse;
|
|
38448
|
+
const tracedResponse = openAIChannels.batchesRetrieveTraced.invoke(
|
|
38449
|
+
async () => {
|
|
38450
|
+
enhancedResponse = await apiPromise.withResponse();
|
|
38451
|
+
return enhancedResponse.data;
|
|
38452
|
+
},
|
|
38453
|
+
batches,
|
|
38454
|
+
[{ batchId }],
|
|
38455
|
+
{}
|
|
38456
|
+
).then((data) => {
|
|
38457
|
+
if (!enhancedResponse) {
|
|
38458
|
+
throw new Error(
|
|
38459
|
+
"Expected OpenAI withResponse() to provide a response"
|
|
38460
|
+
);
|
|
38461
|
+
}
|
|
38462
|
+
return { ...enhancedResponse, data };
|
|
38463
|
+
});
|
|
38464
|
+
return createLazyAPIPromise(
|
|
38465
|
+
() => tracedResponse,
|
|
38466
|
+
() => tracedResponse.then(({ response }) => response),
|
|
38467
|
+
() => apiPromise
|
|
38468
|
+
);
|
|
38469
|
+
};
|
|
38470
|
+
}
|
|
38471
|
+
async function completeOpenAIBatchTrace(args) {
|
|
38472
|
+
const inputFileContent = Promise.resolve(args.inputFileContent);
|
|
38473
|
+
const outputFileContent = args.outputFileContent === void 0 ? void 0 : Promise.resolve(args.outputFileContent);
|
|
38474
|
+
const errorFileContent = args.errorFileContent === void 0 ? void 0 : Promise.resolve(args.errorFileContent);
|
|
38475
|
+
void inputFileContent.catch(() => void 0);
|
|
38476
|
+
void outputFileContent?.catch(() => void 0);
|
|
38477
|
+
void errorFileContent?.catch(() => void 0);
|
|
38478
|
+
await openAIChannels.batchesCompleteTrace.invoke(
|
|
38479
|
+
async () => void 0,
|
|
38480
|
+
void 0,
|
|
38481
|
+
[
|
|
38482
|
+
{
|
|
38483
|
+
...args,
|
|
38484
|
+
inputFileContent,
|
|
38485
|
+
outputFileContent,
|
|
38486
|
+
errorFileContent
|
|
38487
|
+
}
|
|
38488
|
+
],
|
|
38489
|
+
{}
|
|
38490
|
+
);
|
|
38491
|
+
}
|
|
38492
|
+
|
|
37323
38493
|
// src/functions/invoke.ts
|
|
37324
38494
|
async function invoke(args) {
|
|
37325
38495
|
const {
|
|
@@ -37422,58 +38592,6 @@ function initFunction({
|
|
|
37422
38592
|
return f;
|
|
37423
38593
|
}
|
|
37424
38594
|
|
|
37425
|
-
// src/wrappers/openai-promise-utils.ts
|
|
37426
|
-
function splitSpanInfo(allParams) {
|
|
37427
|
-
const { span_info, ...params } = allParams;
|
|
37428
|
-
return {
|
|
37429
|
-
params,
|
|
37430
|
-
span_info
|
|
37431
|
-
};
|
|
37432
|
-
}
|
|
37433
|
-
function createChannelContext(_channel, params, span_info) {
|
|
37434
|
-
return {
|
|
37435
|
-
arguments: (
|
|
37436
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
37437
|
-
[params]
|
|
37438
|
-
),
|
|
37439
|
-
span_info
|
|
37440
|
-
};
|
|
37441
|
-
}
|
|
37442
|
-
async function tracePromiseWithResponse(channel2, traceContext, apiPromise) {
|
|
37443
|
-
let enhancedResponse;
|
|
37444
|
-
const tracePromise = (
|
|
37445
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
37446
|
-
channel2.tracePromise
|
|
37447
|
-
);
|
|
37448
|
-
const data = await tracePromise(async () => {
|
|
37449
|
-
enhancedResponse = await apiPromise.withResponse();
|
|
37450
|
-
traceContext.response = enhancedResponse.response;
|
|
37451
|
-
return enhancedResponse.data;
|
|
37452
|
-
}, traceContext);
|
|
37453
|
-
if (!enhancedResponse) {
|
|
37454
|
-
throw new Error("Expected withResponse() to provide response");
|
|
37455
|
-
}
|
|
37456
|
-
return { data, response: enhancedResponse.response };
|
|
37457
|
-
}
|
|
37458
|
-
function createLazyAPIPromise(ensureExecuted) {
|
|
37459
|
-
let dataPromise = null;
|
|
37460
|
-
return new Proxy({}, {
|
|
37461
|
-
get(target, prop, receiver) {
|
|
37462
|
-
if (prop === "withResponse") {
|
|
37463
|
-
return () => ensureExecuted();
|
|
37464
|
-
}
|
|
37465
|
-
if (prop === "then" || prop === "catch" || prop === "finally" || prop in Promise.prototype) {
|
|
37466
|
-
if (!dataPromise) {
|
|
37467
|
-
dataPromise = ensureExecuted().then((result) => result.data);
|
|
37468
|
-
}
|
|
37469
|
-
const value = Reflect.get(dataPromise, prop, receiver);
|
|
37470
|
-
return typeof value === "function" ? value.bind(dataPromise) : value;
|
|
37471
|
-
}
|
|
37472
|
-
return Reflect.get(target, prop, receiver);
|
|
37473
|
-
}
|
|
37474
|
-
});
|
|
37475
|
-
}
|
|
37476
|
-
|
|
37477
38595
|
// src/wrappers/oai_responses.ts
|
|
37478
38596
|
function responsesProxy(openai) {
|
|
37479
38597
|
if (!openai.responses) {
|
|
@@ -37510,17 +38628,33 @@ function wrapResponsesAsync(target, channel2) {
|
|
|
37510
38628
|
return (allParams, options) => {
|
|
37511
38629
|
const { span_info, params } = splitSpanInfo(allParams);
|
|
37512
38630
|
let executionPromise = null;
|
|
38631
|
+
let apiPromise = null;
|
|
38632
|
+
const getAPIPromise = () => {
|
|
38633
|
+
apiPromise ??= target(params, options);
|
|
38634
|
+
return apiPromise;
|
|
38635
|
+
};
|
|
37513
38636
|
const ensureExecuted = () => {
|
|
37514
38637
|
if (!executionPromise) {
|
|
37515
38638
|
executionPromise = (async () => {
|
|
37516
38639
|
const traceContext = createChannelContext(channel2, params, span_info);
|
|
37517
|
-
|
|
37518
|
-
|
|
38640
|
+
return tracePromiseWithResponse(
|
|
38641
|
+
channel2,
|
|
38642
|
+
traceContext,
|
|
38643
|
+
getAPIPromise()
|
|
38644
|
+
);
|
|
37519
38645
|
})();
|
|
37520
38646
|
}
|
|
37521
38647
|
return executionPromise;
|
|
37522
38648
|
};
|
|
37523
|
-
return createLazyAPIPromise(
|
|
38649
|
+
return createLazyAPIPromise(
|
|
38650
|
+
ensureExecuted,
|
|
38651
|
+
() => tracePromiseAsResponse(
|
|
38652
|
+
channel2,
|
|
38653
|
+
createChannelContext(channel2, params, span_info),
|
|
38654
|
+
getAPIPromise()
|
|
38655
|
+
),
|
|
38656
|
+
getAPIPromise
|
|
38657
|
+
);
|
|
37524
38658
|
};
|
|
37525
38659
|
}
|
|
37526
38660
|
function wrapResponsesSyncStream(target, channel2) {
|
|
@@ -37666,6 +38800,11 @@ function wrapChatCompletion(completion) {
|
|
|
37666
38800
|
allParams
|
|
37667
38801
|
);
|
|
37668
38802
|
let executionPromise = null;
|
|
38803
|
+
let apiPromise = null;
|
|
38804
|
+
const getAPIPromise = () => {
|
|
38805
|
+
apiPromise ??= completion(params, options);
|
|
38806
|
+
return apiPromise;
|
|
38807
|
+
};
|
|
37669
38808
|
const ensureExecuted = () => {
|
|
37670
38809
|
if (!executionPromise) {
|
|
37671
38810
|
executionPromise = (async () => {
|
|
@@ -37675,32 +38814,44 @@ function wrapChatCompletion(completion) {
|
|
|
37675
38814
|
span_info
|
|
37676
38815
|
);
|
|
37677
38816
|
if (params.stream) {
|
|
37678
|
-
const completionPromise =
|
|
37679
|
-
|
|
37680
|
-
|
|
38817
|
+
const completionPromise = (
|
|
38818
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38819
|
+
getAPIPromise()
|
|
37681
38820
|
);
|
|
37682
|
-
const { data: data2, response: response2 } = await tracePromiseWithResponse(
|
|
38821
|
+
const { data: data2, response: response2, request_id: request_id2 } = await tracePromiseWithResponse(
|
|
37683
38822
|
openAIChannels.chatCompletionsCreate,
|
|
37684
38823
|
traceContext,
|
|
37685
38824
|
completionPromise
|
|
37686
38825
|
);
|
|
37687
|
-
return { data: data2, response: response2 };
|
|
38826
|
+
return { data: data2, response: response2, request_id: request_id2 };
|
|
37688
38827
|
}
|
|
37689
|
-
const completionResponse =
|
|
37690
|
-
|
|
37691
|
-
|
|
38828
|
+
const completionResponse = (
|
|
38829
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38830
|
+
getAPIPromise()
|
|
37692
38831
|
);
|
|
37693
|
-
const { data, response } = await tracePromiseWithResponse(
|
|
38832
|
+
const { data, response, request_id } = await tracePromiseWithResponse(
|
|
37694
38833
|
openAIChannels.chatCompletionsCreate,
|
|
37695
38834
|
traceContext,
|
|
37696
38835
|
completionResponse
|
|
37697
38836
|
);
|
|
37698
|
-
return { data, response };
|
|
38837
|
+
return { data, response, request_id };
|
|
37699
38838
|
})();
|
|
37700
38839
|
}
|
|
37701
38840
|
return executionPromise;
|
|
37702
38841
|
};
|
|
37703
|
-
return createLazyAPIPromise(
|
|
38842
|
+
return createLazyAPIPromise(
|
|
38843
|
+
ensureExecuted,
|
|
38844
|
+
() => tracePromiseAsResponse(
|
|
38845
|
+
openAIChannels.chatCompletionsCreate,
|
|
38846
|
+
createChannelContext(
|
|
38847
|
+
openAIChannels.chatCompletionsCreate,
|
|
38848
|
+
params,
|
|
38849
|
+
span_info
|
|
38850
|
+
),
|
|
38851
|
+
getAPIPromise()
|
|
38852
|
+
),
|
|
38853
|
+
getAPIPromise
|
|
38854
|
+
);
|
|
37704
38855
|
};
|
|
37705
38856
|
}
|
|
37706
38857
|
function createEndpointProxy(target, wrapperFn) {
|
|
@@ -37718,6 +38869,11 @@ function wrapApiCreateWithChannel(create, channel2) {
|
|
|
37718
38869
|
return (allParams, options) => {
|
|
37719
38870
|
const { span_info, params } = splitSpanInfo(allParams);
|
|
37720
38871
|
let executionPromise = null;
|
|
38872
|
+
let apiPromise = null;
|
|
38873
|
+
const getAPIPromise = () => {
|
|
38874
|
+
apiPromise ??= create(params, options);
|
|
38875
|
+
return apiPromise;
|
|
38876
|
+
};
|
|
37721
38877
|
const ensureExecuted = () => {
|
|
37722
38878
|
if (!executionPromise) {
|
|
37723
38879
|
executionPromise = (async () => {
|
|
@@ -37725,13 +38881,21 @@ function wrapApiCreateWithChannel(create, channel2) {
|
|
|
37725
38881
|
return tracePromiseWithResponse(
|
|
37726
38882
|
channel2,
|
|
37727
38883
|
traceContext,
|
|
37728
|
-
|
|
38884
|
+
getAPIPromise()
|
|
37729
38885
|
);
|
|
37730
38886
|
})();
|
|
37731
38887
|
}
|
|
37732
38888
|
return executionPromise;
|
|
37733
38889
|
};
|
|
37734
|
-
return createLazyAPIPromise(
|
|
38890
|
+
return createLazyAPIPromise(
|
|
38891
|
+
ensureExecuted,
|
|
38892
|
+
() => tracePromiseAsResponse(
|
|
38893
|
+
channel2,
|
|
38894
|
+
createChannelContext(channel2, params, span_info),
|
|
38895
|
+
getAPIPromise()
|
|
38896
|
+
),
|
|
38897
|
+
getAPIPromise
|
|
38898
|
+
);
|
|
37735
38899
|
};
|
|
37736
38900
|
}
|
|
37737
38901
|
var wrapEmbeddings = (create) => wrapApiCreateWithChannel(create, openAIChannels.embeddingsCreate);
|
|
@@ -37767,6 +38931,13 @@ function wrapAISDK(aiSDK, options = {}) {
|
|
|
37767
38931
|
switch (prop) {
|
|
37768
38932
|
case "generateText":
|
|
37769
38933
|
return wrapGenerateText(typedAISDK.generateText, options, typedAISDK);
|
|
38934
|
+
case "generateImage":
|
|
38935
|
+
case "experimental_generateImage":
|
|
38936
|
+
return typeof original === "function" ? wrapGenerateImage(
|
|
38937
|
+
original,
|
|
38938
|
+
options,
|
|
38939
|
+
typedAISDK
|
|
38940
|
+
) : original;
|
|
37770
38941
|
case "streamText":
|
|
37771
38942
|
return wrapStreamText(typedAISDK.streamText, options, typedAISDK);
|
|
37772
38943
|
case "generateObject":
|
|
@@ -38003,6 +39174,32 @@ var wrapGenerateObject = (generateObject, options = {}, aiSDK) => {
|
|
|
38003
39174
|
options
|
|
38004
39175
|
);
|
|
38005
39176
|
};
|
|
39177
|
+
var wrapGenerateImage = (generateImage, options = {}, aiSDK) => {
|
|
39178
|
+
return makeGenerateImageWrapper(generateImage, { aiSDK }, options);
|
|
39179
|
+
};
|
|
39180
|
+
var makeGenerateImageWrapper = (generateImage, contextOptions = {}, options = {}) => {
|
|
39181
|
+
const wrapper = async function(allParams) {
|
|
39182
|
+
const { span_info, ...params } = allParams;
|
|
39183
|
+
const tracedParams = { ...params };
|
|
39184
|
+
return aiSDKChannels.generateImage.tracePromise(
|
|
39185
|
+
() => generateImage(tracedParams),
|
|
39186
|
+
createAISDKChannelContext(tracedParams, {
|
|
39187
|
+
aiSDK: contextOptions.aiSDK,
|
|
39188
|
+
denyOutputPaths: options.denyOutputPaths,
|
|
39189
|
+
self: contextOptions.self,
|
|
39190
|
+
span_info: mergeSpanInfo(span_info, {
|
|
39191
|
+
name: "generateImage",
|
|
39192
|
+
spanType: contextOptions.spanType
|
|
39193
|
+
})
|
|
39194
|
+
})
|
|
39195
|
+
);
|
|
39196
|
+
};
|
|
39197
|
+
Object.defineProperty(wrapper, "name", {
|
|
39198
|
+
value: "generateImage",
|
|
39199
|
+
writable: false
|
|
39200
|
+
});
|
|
39201
|
+
return wrapper;
|
|
39202
|
+
};
|
|
38006
39203
|
var makeEmbedWrapper = (channel2, name, embed, contextOptions = {}, options = {}) => {
|
|
38007
39204
|
const wrapper = async function(allParams) {
|
|
38008
39205
|
const { span_info, ...params } = allParams;
|
|
@@ -38753,7 +39950,7 @@ function braintrustEveHook(options) {
|
|
|
38753
39950
|
}
|
|
38754
39951
|
};
|
|
38755
39952
|
}
|
|
38756
|
-
function
|
|
39953
|
+
function createLegacyEveInstrumentation(options) {
|
|
38757
39954
|
const state = options.defineState(EVE_TRACE_STATE_KEY, emptyEveTraceState);
|
|
38758
39955
|
return {
|
|
38759
39956
|
events: {
|
|
@@ -40141,8 +41338,10 @@ function capturedModelInput(modelInput) {
|
|
|
40141
41338
|
const value = [];
|
|
40142
41339
|
if (typeof instructions === "string") {
|
|
40143
41340
|
value.push({ content: instructions, role: "system" });
|
|
40144
|
-
} else if (instructions) {
|
|
41341
|
+
} else if (Array.isArray(instructions)) {
|
|
40145
41342
|
value.push(...instructions.map(capturedEveModelMessage));
|
|
41343
|
+
} else if (instructions) {
|
|
41344
|
+
value.push(capturedEveModelMessage(instructions));
|
|
40146
41345
|
}
|
|
40147
41346
|
value.push(...messages.map(capturedEveModelMessage));
|
|
40148
41347
|
try {
|
|
@@ -40386,6 +41585,472 @@ async function deterministicEveId(...parts) {
|
|
|
40386
41585
|
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
40387
41586
|
}
|
|
40388
41587
|
|
|
41588
|
+
// src/instrumentation/plugins/eve-provider.ts
|
|
41589
|
+
var MAX_EVE_PROVIDER_CACHE_ENTRIES = 1e4;
|
|
41590
|
+
function createEveInstrumentationProvider(options = {}) {
|
|
41591
|
+
const bridge = new EveProviderBridge(options.metadata);
|
|
41592
|
+
return {
|
|
41593
|
+
// Eve versions before tracePolicy use capture to decide whether provider
|
|
41594
|
+
// events include content. Newer versions prefer tracePolicy when both are
|
|
41595
|
+
// present, so keep the deprecated field for backwards compatibility.
|
|
41596
|
+
capture: "content",
|
|
41597
|
+
tracePolicy: () => ({
|
|
41598
|
+
emit: true,
|
|
41599
|
+
recordInputs: true,
|
|
41600
|
+
recordOutputs: true
|
|
41601
|
+
}),
|
|
41602
|
+
events: {
|
|
41603
|
+
"action.completed": (event, context) => bridge.handleActionTerminal(event, context),
|
|
41604
|
+
"action.failed": (event, context) => bridge.handleActionTerminal(event, context),
|
|
41605
|
+
"action.started": (event, context) => bridge.handleActionStarted(event, context),
|
|
41606
|
+
"model.call.completed": (event, context) => bridge.handleModelTerminal(event, context),
|
|
41607
|
+
"model.call.failed": (event, context) => bridge.handleModelTerminal(event, context),
|
|
41608
|
+
"model.call.started": (event, context) => bridge.handleModelStarted(event, context),
|
|
41609
|
+
"step.attempt.completed": (event) => bridge.handleStepAttemptTerminal(event),
|
|
41610
|
+
"step.attempt.failed": (event) => bridge.handleStepAttemptTerminal(event),
|
|
41611
|
+
"turn.cancelled": (event, context) => bridge.handleTurnTerminal(event, context),
|
|
41612
|
+
"turn.completed": (event, context) => bridge.handleTurnTerminal(event, context),
|
|
41613
|
+
"turn.failed": (event, context) => bridge.handleTurnTerminal(event, context),
|
|
41614
|
+
"turn.started": (event, context) => bridge.handleTurnStarted(event, context)
|
|
41615
|
+
},
|
|
41616
|
+
flush,
|
|
41617
|
+
setup: options.setup
|
|
41618
|
+
};
|
|
41619
|
+
}
|
|
41620
|
+
var EveProviderBridge = class {
|
|
41621
|
+
constructor(metadata) {
|
|
41622
|
+
this.metadata = metadata;
|
|
41623
|
+
}
|
|
41624
|
+
metadata;
|
|
41625
|
+
activeActions = /* @__PURE__ */ new Map();
|
|
41626
|
+
activeModels = /* @__PURE__ */ new Map();
|
|
41627
|
+
modelsByAttempt = /* @__PURE__ */ new Map();
|
|
41628
|
+
settledOperations = new LRUCache({
|
|
41629
|
+
max: MAX_EVE_PROVIDER_CACHE_ENTRIES
|
|
41630
|
+
});
|
|
41631
|
+
turns = new LRUCache({
|
|
41632
|
+
max: MAX_EVE_PROVIDER_CACHE_ENTRIES
|
|
41633
|
+
});
|
|
41634
|
+
async handleTurnStarted(event, context) {
|
|
41635
|
+
await this.contain("turn start", async () => {
|
|
41636
|
+
if (this.settledOperations.has(event.idempotencyKey)) {
|
|
41637
|
+
context.state.set({ skip: true });
|
|
41638
|
+
return;
|
|
41639
|
+
}
|
|
41640
|
+
const { rowId, spanId } = await generateEveIds(
|
|
41641
|
+
"turn",
|
|
41642
|
+
event.idempotencyKey
|
|
41643
|
+
);
|
|
41644
|
+
const key = turnKey3(event.sessionId, event.turnId);
|
|
41645
|
+
const stored = storedSpan(context);
|
|
41646
|
+
if (stored && "exported" in stored && stored.rootSpanId) {
|
|
41647
|
+
this.turns.set(key, { rootSpanId: stored.rootSpanId, spanId });
|
|
41648
|
+
return;
|
|
41649
|
+
}
|
|
41650
|
+
let rootSpanId = spanId;
|
|
41651
|
+
let parentSpanId;
|
|
41652
|
+
if (event.parentLineage) {
|
|
41653
|
+
const parentTurnKey = turnKey3(
|
|
41654
|
+
event.parentLineage.sessionId,
|
|
41655
|
+
event.parentLineage.turnId
|
|
41656
|
+
);
|
|
41657
|
+
const parentTurn = this.turns.get(parentTurnKey);
|
|
41658
|
+
rootSpanId = parentTurn?.rootSpanId ?? // Eve propagates the root session through every nested subagent. Use
|
|
41659
|
+
// it instead of the immediate parent session when no ancestor ran
|
|
41660
|
+
// in-process.
|
|
41661
|
+
(await generateEveIds(
|
|
41662
|
+
"turn",
|
|
41663
|
+
turnIdempotencyKey(
|
|
41664
|
+
event.rootSessionId,
|
|
41665
|
+
event.parentLineage.turnId
|
|
41666
|
+
)
|
|
41667
|
+
)).spanId;
|
|
41668
|
+
parentSpanId = (await generateEveIds(
|
|
41669
|
+
"subagent",
|
|
41670
|
+
actionIdempotencyKey(
|
|
41671
|
+
event.parentLineage.sessionId,
|
|
41672
|
+
event.parentLineage.turnId,
|
|
41673
|
+
event.parentLineage.callId
|
|
41674
|
+
)
|
|
41675
|
+
)).spanId;
|
|
41676
|
+
}
|
|
41677
|
+
const metadata = this.spanMetadata(event.sessionId);
|
|
41678
|
+
const span = await this.startSpan(
|
|
41679
|
+
context,
|
|
41680
|
+
{
|
|
41681
|
+
event: { id: rowId, metadata },
|
|
41682
|
+
name: "eve.turn",
|
|
41683
|
+
parentSpanIds: parentSpanId ? { rootSpanId, spanId: parentSpanId } : { parentSpanIds: [], rootSpanId },
|
|
41684
|
+
spanAttributes: { type: "task" /* TASK */ },
|
|
41685
|
+
spanId
|
|
41686
|
+
},
|
|
41687
|
+
rootSpanId
|
|
41688
|
+
);
|
|
41689
|
+
span?.log({ metadata });
|
|
41690
|
+
this.turns.set(key, {
|
|
41691
|
+
rootSpanId,
|
|
41692
|
+
spanId
|
|
41693
|
+
});
|
|
41694
|
+
});
|
|
41695
|
+
}
|
|
41696
|
+
async handleTurnTerminal(event, context) {
|
|
41697
|
+
await this.contain("turn terminal", async () => {
|
|
41698
|
+
if (this.settledOperations.has(event.idempotencyKey)) {
|
|
41699
|
+
context.state.set(void 0);
|
|
41700
|
+
return;
|
|
41701
|
+
}
|
|
41702
|
+
const error = event.type === "turn.failed" ? event.error : void 0;
|
|
41703
|
+
this.drainActionsForTurn(event.sessionId, event.turnId, error);
|
|
41704
|
+
const stored = storedSpan(context);
|
|
41705
|
+
if (stored && "exported" in stored) {
|
|
41706
|
+
updateSpan({
|
|
41707
|
+
exported: stored.exported,
|
|
41708
|
+
...error !== void 0 ? { error } : {},
|
|
41709
|
+
metrics: { end: Date.now() / 1e3 }
|
|
41710
|
+
});
|
|
41711
|
+
}
|
|
41712
|
+
this.settledOperations.set(event.idempotencyKey, true);
|
|
41713
|
+
context.state.set(void 0);
|
|
41714
|
+
this.turns.delete(turnKey3(event.sessionId, event.turnId));
|
|
41715
|
+
});
|
|
41716
|
+
}
|
|
41717
|
+
async handleModelStarted(event, context) {
|
|
41718
|
+
await this.contain("model start", async () => {
|
|
41719
|
+
if (this.settledOperations.has(event.idempotencyKey)) {
|
|
41720
|
+
context.state.set({ skip: true });
|
|
41721
|
+
return;
|
|
41722
|
+
}
|
|
41723
|
+
const parent = await this.parentForScope(event.scope);
|
|
41724
|
+
const { rowId, spanId } = await generateEveIds(
|
|
41725
|
+
"step",
|
|
41726
|
+
event.idempotencyKey
|
|
41727
|
+
);
|
|
41728
|
+
const input = event.input ? capturedModelInput(event.input) : void 0;
|
|
41729
|
+
const metadata = {
|
|
41730
|
+
...this.spanMetadata(event.scope.sessionId),
|
|
41731
|
+
model: event.model.modelId,
|
|
41732
|
+
provider: event.model.provider
|
|
41733
|
+
};
|
|
41734
|
+
const span = await this.startSpan(context, {
|
|
41735
|
+
event: {
|
|
41736
|
+
id: rowId,
|
|
41737
|
+
...input !== void 0 ? { input } : {},
|
|
41738
|
+
metadata
|
|
41739
|
+
},
|
|
41740
|
+
name: "eve.step",
|
|
41741
|
+
parentSpanIds: parent,
|
|
41742
|
+
spanAttributes: { type: "llm" /* LLM */ },
|
|
41743
|
+
spanId
|
|
41744
|
+
});
|
|
41745
|
+
if (!span) return;
|
|
41746
|
+
span.log({ ...input !== void 0 ? { input } : {}, metadata });
|
|
41747
|
+
this.activeModels.set(event.idempotencyKey, {
|
|
41748
|
+
span,
|
|
41749
|
+
turnKey: turnKey3(event.scope.sessionId, event.scope.turnId)
|
|
41750
|
+
});
|
|
41751
|
+
const keys = this.modelsByAttempt.get(event.scope.attemptId) ?? /* @__PURE__ */ new Set();
|
|
41752
|
+
keys.add(event.idempotencyKey);
|
|
41753
|
+
this.modelsByAttempt.set(event.scope.attemptId, keys);
|
|
41754
|
+
});
|
|
41755
|
+
}
|
|
41756
|
+
async handleModelTerminal(event, context) {
|
|
41757
|
+
await this.contain("model terminal", async () => {
|
|
41758
|
+
if (this.settledOperations.has(event.idempotencyKey)) {
|
|
41759
|
+
context.state.set(void 0);
|
|
41760
|
+
return;
|
|
41761
|
+
}
|
|
41762
|
+
const active = this.activeModels.get(event.idempotencyKey);
|
|
41763
|
+
if (active) {
|
|
41764
|
+
const span = active.span;
|
|
41765
|
+
if (event.type === "model.call.failed") {
|
|
41766
|
+
if (event.error !== void 0) span.log({ error: event.error });
|
|
41767
|
+
} else {
|
|
41768
|
+
span.log({
|
|
41769
|
+
metrics: usageMetrics(event.usage),
|
|
41770
|
+
output: modelOutput(event)
|
|
41771
|
+
});
|
|
41772
|
+
}
|
|
41773
|
+
span.end();
|
|
41774
|
+
} else {
|
|
41775
|
+
const stored = storedSpan(context);
|
|
41776
|
+
if (stored && "exported" in stored) {
|
|
41777
|
+
updateSpan({
|
|
41778
|
+
exported: stored.exported,
|
|
41779
|
+
...event.type === "model.call.failed" ? event.error !== void 0 ? { error: event.error } : {} : { output: modelOutput(event) },
|
|
41780
|
+
metrics: {
|
|
41781
|
+
...event.type === "model.call.completed" ? usageMetrics(event.usage) : {},
|
|
41782
|
+
end: Date.now() / 1e3
|
|
41783
|
+
}
|
|
41784
|
+
});
|
|
41785
|
+
}
|
|
41786
|
+
}
|
|
41787
|
+
this.settledOperations.set(event.idempotencyKey, true);
|
|
41788
|
+
this.forgetModel(event.scope.attemptId, event.idempotencyKey);
|
|
41789
|
+
context.state.set(void 0);
|
|
41790
|
+
});
|
|
41791
|
+
}
|
|
41792
|
+
async handleActionStarted(event, context) {
|
|
41793
|
+
await this.contain("action start", async () => {
|
|
41794
|
+
if (event.kind === "load-skill" || this.settledOperations.has(event.idempotencyKey)) {
|
|
41795
|
+
context.state.set({ skip: true });
|
|
41796
|
+
return;
|
|
41797
|
+
}
|
|
41798
|
+
const parent = await this.parentForScope(event.scope);
|
|
41799
|
+
const { rowId, spanId } = await generateEveIds(
|
|
41800
|
+
event.kind === "subagent-call" ? "subagent" : "tool",
|
|
41801
|
+
event.idempotencyKey
|
|
41802
|
+
);
|
|
41803
|
+
const metadata = {
|
|
41804
|
+
...this.spanMetadata(event.scope.sessionId),
|
|
41805
|
+
"eve.action_kind": event.kind
|
|
41806
|
+
};
|
|
41807
|
+
const span = await this.startSpan(context, {
|
|
41808
|
+
event: {
|
|
41809
|
+
id: rowId,
|
|
41810
|
+
...event.input !== void 0 ? { input: event.input } : {},
|
|
41811
|
+
metadata
|
|
41812
|
+
},
|
|
41813
|
+
name: event.name,
|
|
41814
|
+
parentSpanIds: parent,
|
|
41815
|
+
spanAttributes: { type: "tool" /* TOOL */ },
|
|
41816
|
+
spanId
|
|
41817
|
+
});
|
|
41818
|
+
if (!span) return;
|
|
41819
|
+
span.log({
|
|
41820
|
+
...event.input !== void 0 ? { input: event.input } : {},
|
|
41821
|
+
metadata
|
|
41822
|
+
});
|
|
41823
|
+
this.activeActions.set(event.idempotencyKey, {
|
|
41824
|
+
span,
|
|
41825
|
+
turnKey: turnKey3(event.scope.sessionId, event.scope.turnId)
|
|
41826
|
+
});
|
|
41827
|
+
});
|
|
41828
|
+
}
|
|
41829
|
+
async handleActionTerminal(event, context) {
|
|
41830
|
+
await this.contain("action terminal", async () => {
|
|
41831
|
+
if (this.settledOperations.has(event.idempotencyKey)) {
|
|
41832
|
+
context.state.set(void 0);
|
|
41833
|
+
return;
|
|
41834
|
+
}
|
|
41835
|
+
const stored = storedSpan(context);
|
|
41836
|
+
if (stored?.skip) {
|
|
41837
|
+
context.state.set(void 0);
|
|
41838
|
+
return;
|
|
41839
|
+
}
|
|
41840
|
+
const active = this.activeActions.get(event.idempotencyKey);
|
|
41841
|
+
const end = finiteTimestamp(event.acceptedAtMs) ?? Date.now();
|
|
41842
|
+
if (active) {
|
|
41843
|
+
const span = active.span;
|
|
41844
|
+
if (event.type === "action.failed") {
|
|
41845
|
+
span.log({
|
|
41846
|
+
error: event.error ?? new Error(event.errorCode ?? `Eve action ${event.outcome}`)
|
|
41847
|
+
});
|
|
41848
|
+
} else if (event.output.type === "error") {
|
|
41849
|
+
span.log({
|
|
41850
|
+
error: event.output.error ?? new Error("Eve action returned an error")
|
|
41851
|
+
});
|
|
41852
|
+
} else {
|
|
41853
|
+
span.log({ output: event.output.output });
|
|
41854
|
+
}
|
|
41855
|
+
span.end({ endTime: end / 1e3 });
|
|
41856
|
+
} else {
|
|
41857
|
+
const stored2 = storedSpan(context);
|
|
41858
|
+
if (stored2 && "exported" in stored2) {
|
|
41859
|
+
updateSpan({
|
|
41860
|
+
exported: stored2.exported,
|
|
41861
|
+
...event.type === "action.failed" ? {
|
|
41862
|
+
error: event.error ?? new Error(event.errorCode ?? `Eve action ${event.outcome}`)
|
|
41863
|
+
} : event.output.type === "error" ? {
|
|
41864
|
+
error: event.output.error ?? new Error("Eve action returned an error")
|
|
41865
|
+
} : { output: event.output.output },
|
|
41866
|
+
metrics: { end: end / 1e3 }
|
|
41867
|
+
});
|
|
41868
|
+
}
|
|
41869
|
+
}
|
|
41870
|
+
this.settledOperations.set(event.idempotencyKey, true);
|
|
41871
|
+
this.activeActions.delete(event.idempotencyKey);
|
|
41872
|
+
context.state.set(void 0);
|
|
41873
|
+
});
|
|
41874
|
+
}
|
|
41875
|
+
handleStepAttemptTerminal(event) {
|
|
41876
|
+
void this.contain("step attempt terminal", () => {
|
|
41877
|
+
const keys = this.modelsByAttempt.get(event.scope.attemptId);
|
|
41878
|
+
if (!keys) return;
|
|
41879
|
+
for (const key of keys) {
|
|
41880
|
+
const active = this.activeModels.get(key);
|
|
41881
|
+
if (!active) continue;
|
|
41882
|
+
if (event.type === "step.attempt.failed" && event.error !== void 0) {
|
|
41883
|
+
active.span.log({ error: event.error });
|
|
41884
|
+
}
|
|
41885
|
+
active.span.end();
|
|
41886
|
+
this.activeModels.delete(key);
|
|
41887
|
+
}
|
|
41888
|
+
this.modelsByAttempt.delete(event.scope.attemptId);
|
|
41889
|
+
});
|
|
41890
|
+
}
|
|
41891
|
+
async parentForScope(scope) {
|
|
41892
|
+
const key = turnKey3(scope.sessionId, scope.turnId);
|
|
41893
|
+
const known = this.turns.get(key);
|
|
41894
|
+
if (known) {
|
|
41895
|
+
return { rootSpanId: known.rootSpanId, spanId: known.spanId };
|
|
41896
|
+
}
|
|
41897
|
+
const [{ spanId }, { spanId: rootSpanId }] = await Promise.all([
|
|
41898
|
+
generateEveIds("turn", turnIdempotencyKey(scope.sessionId, scope.turnId)),
|
|
41899
|
+
generateEveIds(
|
|
41900
|
+
"turn",
|
|
41901
|
+
turnIdempotencyKey(
|
|
41902
|
+
scope.rootSessionId ?? scope.sessionId,
|
|
41903
|
+
scope.turnId
|
|
41904
|
+
)
|
|
41905
|
+
)
|
|
41906
|
+
]);
|
|
41907
|
+
return { rootSpanId, spanId };
|
|
41908
|
+
}
|
|
41909
|
+
async startSpan(context, args, rootSpanId) {
|
|
41910
|
+
const span = withCurrent(
|
|
41911
|
+
NOOP_SPAN,
|
|
41912
|
+
() => _internalStartSpanWithInitialMerge(
|
|
41913
|
+
withSpanInstrumentationName(args ?? {}, INSTRUMENTATION_NAMES.EVE)
|
|
41914
|
+
)
|
|
41915
|
+
);
|
|
41916
|
+
try {
|
|
41917
|
+
context.state.set({
|
|
41918
|
+
exported: await span.export(),
|
|
41919
|
+
...rootSpanId ? { rootSpanId } : {}
|
|
41920
|
+
});
|
|
41921
|
+
} catch (error) {
|
|
41922
|
+
debugLogger.warn("Error exporting Eve provider span:", error);
|
|
41923
|
+
}
|
|
41924
|
+
return span;
|
|
41925
|
+
}
|
|
41926
|
+
drainActionsForTurn(sessionId, turnId, error) {
|
|
41927
|
+
const key = turnKey3(sessionId, turnId);
|
|
41928
|
+
for (const [idempotencyKey, active] of this.activeActions) {
|
|
41929
|
+
if (active.turnKey !== key) continue;
|
|
41930
|
+
if (error !== void 0) active.span.log({ error });
|
|
41931
|
+
active.span.end();
|
|
41932
|
+
this.activeActions.delete(idempotencyKey);
|
|
41933
|
+
}
|
|
41934
|
+
}
|
|
41935
|
+
forgetModel(attemptId, idempotencyKey) {
|
|
41936
|
+
this.activeModels.delete(idempotencyKey);
|
|
41937
|
+
const keys = this.modelsByAttempt.get(attemptId);
|
|
41938
|
+
keys?.delete(idempotencyKey);
|
|
41939
|
+
if (keys?.size === 0) this.modelsByAttempt.delete(attemptId);
|
|
41940
|
+
}
|
|
41941
|
+
spanMetadata(sessionId) {
|
|
41942
|
+
return {
|
|
41943
|
+
...this.metadata ?? {},
|
|
41944
|
+
"eve.session_id": sessionId
|
|
41945
|
+
};
|
|
41946
|
+
}
|
|
41947
|
+
async contain(operation, fn) {
|
|
41948
|
+
try {
|
|
41949
|
+
await fn();
|
|
41950
|
+
} catch (error) {
|
|
41951
|
+
debugLogger.warn(`Error in Eve provider ${operation}:`, error);
|
|
41952
|
+
}
|
|
41953
|
+
}
|
|
41954
|
+
};
|
|
41955
|
+
function storedSpan(context) {
|
|
41956
|
+
const value = context.state.get();
|
|
41957
|
+
if (!isObject(value)) return void 0;
|
|
41958
|
+
if (value["skip"] === true) return { skip: true };
|
|
41959
|
+
return typeof value["exported"] === "string" ? {
|
|
41960
|
+
exported: value["exported"],
|
|
41961
|
+
...typeof value["rootSpanId"] === "string" && value["rootSpanId"].length > 0 ? { rootSpanId: value["rootSpanId"] } : {}
|
|
41962
|
+
} : void 0;
|
|
41963
|
+
}
|
|
41964
|
+
function modelOutput(event) {
|
|
41965
|
+
const content = event.content ?? [];
|
|
41966
|
+
let text = "";
|
|
41967
|
+
const reasoning = [];
|
|
41968
|
+
const toolCalls2 = [];
|
|
41969
|
+
for (const part of content) {
|
|
41970
|
+
if (part.type === "text") {
|
|
41971
|
+
text += part.text;
|
|
41972
|
+
} else if (part.type === "reasoning" && part.text.trim().length > 0) {
|
|
41973
|
+
reasoning.push({ content: part.text });
|
|
41974
|
+
} else if (part.type === "tool-call") {
|
|
41975
|
+
toolCalls2.push({
|
|
41976
|
+
function: {
|
|
41977
|
+
arguments: safeJsonStringify(part.input),
|
|
41978
|
+
name: part.toolName
|
|
41979
|
+
},
|
|
41980
|
+
id: part.callId,
|
|
41981
|
+
type: "function"
|
|
41982
|
+
});
|
|
41983
|
+
}
|
|
41984
|
+
}
|
|
41985
|
+
return [
|
|
41986
|
+
{
|
|
41987
|
+
finish_reason: normalizeFinishReason3(event.finishReason),
|
|
41988
|
+
index: 0,
|
|
41989
|
+
message: {
|
|
41990
|
+
content: text || null,
|
|
41991
|
+
...reasoning.length > 0 ? { reasoning } : {},
|
|
41992
|
+
role: "assistant",
|
|
41993
|
+
...toolCalls2.length > 0 ? { tool_calls: toolCalls2 } : {}
|
|
41994
|
+
}
|
|
41995
|
+
}
|
|
41996
|
+
];
|
|
41997
|
+
}
|
|
41998
|
+
function usageMetrics(usage) {
|
|
41999
|
+
const promptTokens = nonNegativeNumber(usage.inputTokens);
|
|
42000
|
+
const completionTokens = nonNegativeNumber(usage.outputTokens);
|
|
42001
|
+
const cachedTokens = nonNegativeNumber(
|
|
42002
|
+
usage.inputTokenDetails?.cacheReadTokens
|
|
42003
|
+
);
|
|
42004
|
+
const cacheCreationTokens = nonNegativeNumber(
|
|
42005
|
+
usage.inputTokenDetails?.cacheWriteTokens
|
|
42006
|
+
);
|
|
42007
|
+
return {
|
|
42008
|
+
...promptTokens !== void 0 ? { prompt_tokens: promptTokens } : {},
|
|
42009
|
+
...completionTokens !== void 0 ? { completion_tokens: completionTokens } : {},
|
|
42010
|
+
...promptTokens !== void 0 && completionTokens !== void 0 ? { tokens: promptTokens + completionTokens } : {},
|
|
42011
|
+
...cachedTokens !== void 0 ? { prompt_cached_tokens: cachedTokens } : {},
|
|
42012
|
+
...cacheCreationTokens !== void 0 ? { prompt_cache_creation_tokens: cacheCreationTokens } : {}
|
|
42013
|
+
};
|
|
42014
|
+
}
|
|
42015
|
+
function nonNegativeNumber(value) {
|
|
42016
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : void 0;
|
|
42017
|
+
}
|
|
42018
|
+
function finiteTimestamp(value) {
|
|
42019
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
42020
|
+
}
|
|
42021
|
+
function normalizeFinishReason3(value) {
|
|
42022
|
+
if (value === "content-filter") return "content_filter";
|
|
42023
|
+
if (value === "tool-calls") return "tool_calls";
|
|
42024
|
+
return value;
|
|
42025
|
+
}
|
|
42026
|
+
function safeJsonStringify(value) {
|
|
42027
|
+
try {
|
|
42028
|
+
return JSON.stringify(value) ?? "null";
|
|
42029
|
+
} catch {
|
|
42030
|
+
return "null";
|
|
42031
|
+
}
|
|
42032
|
+
}
|
|
42033
|
+
function turnKey3(sessionId, turnId) {
|
|
42034
|
+
return `${sessionId}:${turnId}`;
|
|
42035
|
+
}
|
|
42036
|
+
function turnIdempotencyKey(sessionId, turnId) {
|
|
42037
|
+
return `turn:${sessionId}:${turnId}`;
|
|
42038
|
+
}
|
|
42039
|
+
function actionIdempotencyKey(sessionId, turnId, callId) {
|
|
42040
|
+
return `action:${sessionId}:${turnId}:${callId}`;
|
|
42041
|
+
}
|
|
42042
|
+
|
|
42043
|
+
// src/instrumentation/plugins/eve-instrumentation.ts
|
|
42044
|
+
var EVE_INSTRUMENTATION_PROVIDER = /* @__PURE__ */ Symbol.for("eve.instrumentation.provider");
|
|
42045
|
+
function braintrustEveInstrumentation(options) {
|
|
42046
|
+
const definition = "defineState" in options ? createLegacyEveInstrumentation(options) : createEveInstrumentationProvider(options);
|
|
42047
|
+
const declaration = {
|
|
42048
|
+
...definition,
|
|
42049
|
+
[EVE_INSTRUMENTATION_PROVIDER]: true
|
|
42050
|
+
};
|
|
42051
|
+
return declaration;
|
|
42052
|
+
}
|
|
42053
|
+
|
|
40389
42054
|
// src/typed-instrumentation-helpers.ts
|
|
40390
42055
|
var TypedApplyProxy = Proxy;
|
|
40391
42056
|
|
|
@@ -40787,11 +42452,11 @@ function wrapClaudeAgentQuery(queryFn, defaultThis) {
|
|
|
40787
42452
|
}
|
|
40788
42453
|
};
|
|
40789
42454
|
const invocationTarget = thisArg === proxy || thisArg === void 0 ? defaultThis ?? thisArg : thisArg;
|
|
40790
|
-
return claudeAgentSDKChannels.query.
|
|
40791
|
-
|
|
40792
|
-
|
|
40793
|
-
|
|
40794
|
-
{
|
|
42455
|
+
return claudeAgentSDKChannels.query.invoke(
|
|
42456
|
+
target,
|
|
42457
|
+
invocationTarget,
|
|
42458
|
+
[wrappedParams],
|
|
42459
|
+
{}
|
|
40795
42460
|
);
|
|
40796
42461
|
}
|
|
40797
42462
|
});
|
|
@@ -41406,13 +43071,11 @@ function wrapAgentInstance(agent) {
|
|
|
41406
43071
|
if (prop === "stream" && typeof value === "function") {
|
|
41407
43072
|
return function(args, options) {
|
|
41408
43073
|
const callArgs = [args, options];
|
|
41409
|
-
return strandsAgentSDKChannels.agentStream.
|
|
41410
|
-
|
|
41411
|
-
|
|
41412
|
-
|
|
41413
|
-
|
|
41414
|
-
self: proxy
|
|
41415
|
-
}
|
|
43074
|
+
return strandsAgentSDKChannels.agentStream.invoke(
|
|
43075
|
+
value,
|
|
43076
|
+
target,
|
|
43077
|
+
callArgs,
|
|
43078
|
+
{ agent: proxy }
|
|
41416
43079
|
);
|
|
41417
43080
|
};
|
|
41418
43081
|
}
|
|
@@ -41443,12 +43106,12 @@ function wrapMultiAgentInstance(orchestrator, kind) {
|
|
|
41443
43106
|
return function(input, options) {
|
|
41444
43107
|
const callArgs = [input, options];
|
|
41445
43108
|
const channel2 = kind === "graph" ? strandsAgentSDKChannels.graphStream : strandsAgentSDKChannels.swarmStream;
|
|
41446
|
-
return channel2.
|
|
41447
|
-
|
|
43109
|
+
return channel2.invoke(
|
|
43110
|
+
value,
|
|
43111
|
+
target,
|
|
43112
|
+
callArgs,
|
|
41448
43113
|
{
|
|
41449
|
-
|
|
41450
|
-
orchestrator: proxy,
|
|
41451
|
-
self: proxy
|
|
43114
|
+
orchestrator: proxy
|
|
41452
43115
|
}
|
|
41453
43116
|
);
|
|
41454
43117
|
};
|
|
@@ -43400,9 +45063,6 @@ var VitestContextManager = class {
|
|
|
43400
45063
|
getCurrentContext() {
|
|
43401
45064
|
return this.contextStorage.getStore();
|
|
43402
45065
|
}
|
|
43403
|
-
setContext(context) {
|
|
43404
|
-
this.contextStorage.enterWith(context);
|
|
43405
|
-
}
|
|
43406
45066
|
runInContext(context, callback) {
|
|
43407
45067
|
return this.contextStorage.run(context, callback);
|
|
43408
45068
|
}
|
|
@@ -43788,8 +45448,7 @@ function wrapDescribe(originalDescribe, config, afterAll) {
|
|
|
43788
45448
|
if (config.onProgress) {
|
|
43789
45449
|
config.onProgress({ type: "suite_start", suiteName });
|
|
43790
45450
|
}
|
|
43791
|
-
contextManager.
|
|
43792
|
-
factory();
|
|
45451
|
+
contextManager.runInContext(lazyContext, factory);
|
|
43793
45452
|
if (afterAll) {
|
|
43794
45453
|
afterAll(async () => {
|
|
43795
45454
|
await flushExperimentWithSync(context, config);
|