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/browser.js
CHANGED
|
@@ -104,6 +104,7 @@ __export(browser_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(browser_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;
|
|
@@ -12638,56 +13013,14 @@ function suppressionStore() {
|
|
|
12638
13013
|
autoInstrumentationSuppressionStore ??= isomorph_default.newAsyncLocalStorage();
|
|
12639
13014
|
return autoInstrumentationSuppressionStore;
|
|
12640
13015
|
}
|
|
12641
|
-
function currentFrames() {
|
|
12642
|
-
return suppressionStore().getStore()?.frames ?? [];
|
|
12643
|
-
}
|
|
12644
13016
|
function isAutoInstrumentationSuppressed() {
|
|
12645
|
-
|
|
12646
|
-
return frames[frames.length - 1]?.mode === "suppress";
|
|
13017
|
+
return suppressionStore().getStore() === true;
|
|
12647
13018
|
}
|
|
12648
13019
|
function runWithAutoInstrumentationSuppressed(callback) {
|
|
12649
|
-
|
|
12650
|
-
id: /* @__PURE__ */ Symbol("braintrust.auto-instrumentation-suppress"),
|
|
12651
|
-
mode: "suppress"
|
|
12652
|
-
};
|
|
12653
|
-
return suppressionStore().run(
|
|
12654
|
-
{ frames: [...currentFrames(), frame] },
|
|
12655
|
-
callback
|
|
12656
|
-
);
|
|
12657
|
-
}
|
|
12658
|
-
function bindAutoInstrumentationSuppressionToStart(tracingChannel) {
|
|
12659
|
-
const startChannel = tracingChannel.start;
|
|
12660
|
-
if (!startChannel) {
|
|
12661
|
-
return void 0;
|
|
12662
|
-
}
|
|
12663
|
-
const store = suppressionStore();
|
|
12664
|
-
startChannel.bindStore(store, () => ({
|
|
12665
|
-
frames: [
|
|
12666
|
-
...currentFrames(),
|
|
12667
|
-
{
|
|
12668
|
-
id: /* @__PURE__ */ Symbol("braintrust.auto-instrumentation-suppress"),
|
|
12669
|
-
mode: "suppress"
|
|
12670
|
-
}
|
|
12671
|
-
]
|
|
12672
|
-
}));
|
|
12673
|
-
return () => {
|
|
12674
|
-
startChannel.unbindStore(store);
|
|
12675
|
-
};
|
|
13020
|
+
return suppressionStore().run(true, callback);
|
|
12676
13021
|
}
|
|
12677
|
-
function
|
|
12678
|
-
|
|
12679
|
-
id: /* @__PURE__ */ Symbol("braintrust.auto-instrumentation-allow"),
|
|
12680
|
-
mode: "allow"
|
|
12681
|
-
};
|
|
12682
|
-
suppressionStore().enterWith({
|
|
12683
|
-
frames: [...currentFrames(), frame]
|
|
12684
|
-
});
|
|
12685
|
-
return () => {
|
|
12686
|
-
const frames = currentFrames().filter(
|
|
12687
|
-
(candidate) => candidate.id !== frame.id
|
|
12688
|
-
);
|
|
12689
|
-
suppressionStore().enterWith(frames.length > 0 ? { frames } : void 0);
|
|
12690
|
-
};
|
|
13022
|
+
function runWithAutoInstrumentationAllowed(callback) {
|
|
13023
|
+
return suppressionStore().run(void 0, callback);
|
|
12691
13024
|
}
|
|
12692
13025
|
|
|
12693
13026
|
// src/instrumentation/core/channel-tracing.ts
|
|
@@ -13277,6 +13610,131 @@ function unsubscribeAll(unsubscribers) {
|
|
|
13277
13610
|
return [];
|
|
13278
13611
|
}
|
|
13279
13612
|
|
|
13613
|
+
// src/instrumentation/core/channel-definitions.ts
|
|
13614
|
+
function channel(spec) {
|
|
13615
|
+
return spec;
|
|
13616
|
+
}
|
|
13617
|
+
function defineChannels(pkg, channels, options) {
|
|
13618
|
+
const { instrumentationName } = options;
|
|
13619
|
+
return Object.fromEntries(
|
|
13620
|
+
Object.entries(channels).map(([key, spec]) => {
|
|
13621
|
+
const fullChannelName = `orchestrion:${pkg}:${spec.channelName}`;
|
|
13622
|
+
if (spec.kind === "async") {
|
|
13623
|
+
const asyncSpec = spec;
|
|
13624
|
+
const tracingChannel2 = () => isomorph_default.newTracingChannel(
|
|
13625
|
+
fullChannelName
|
|
13626
|
+
);
|
|
13627
|
+
const intercept2 = (interceptor) => {
|
|
13628
|
+
const hook = tracingChannel2();
|
|
13629
|
+
return typeof hook.intercept === "function" ? hook.intercept(interceptor) : () => {
|
|
13630
|
+
};
|
|
13631
|
+
};
|
|
13632
|
+
return [
|
|
13633
|
+
key,
|
|
13634
|
+
{
|
|
13635
|
+
...asyncSpec,
|
|
13636
|
+
instrumentationName,
|
|
13637
|
+
intercept: intercept2,
|
|
13638
|
+
invoke: (target, thisArg, args, additional) => {
|
|
13639
|
+
const hook = tracingChannel2();
|
|
13640
|
+
return typeof hook.invoke === "function" ? hook.invoke(target, thisArg, args, additional) : Reflect.apply(target, thisArg, args);
|
|
13641
|
+
},
|
|
13642
|
+
tracingChannel: tracingChannel2,
|
|
13643
|
+
tracePromise: (fn, context) => tracingChannel2().tracePromise(
|
|
13644
|
+
fn,
|
|
13645
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
13646
|
+
context
|
|
13647
|
+
)
|
|
13648
|
+
}
|
|
13649
|
+
];
|
|
13650
|
+
}
|
|
13651
|
+
const syncSpec = spec;
|
|
13652
|
+
const tracingChannel = () => isomorph_default.newTracingChannel(
|
|
13653
|
+
fullChannelName
|
|
13654
|
+
);
|
|
13655
|
+
const intercept = (interceptor) => {
|
|
13656
|
+
const hook = tracingChannel();
|
|
13657
|
+
return typeof hook.intercept === "function" ? hook.intercept(interceptor) : () => {
|
|
13658
|
+
};
|
|
13659
|
+
};
|
|
13660
|
+
return [
|
|
13661
|
+
key,
|
|
13662
|
+
{
|
|
13663
|
+
...syncSpec,
|
|
13664
|
+
instrumentationName,
|
|
13665
|
+
intercept,
|
|
13666
|
+
invoke: (target, thisArg, args, additional) => {
|
|
13667
|
+
const hook = tracingChannel();
|
|
13668
|
+
return typeof hook.invoke === "function" ? hook.invoke(target, thisArg, args, additional) : Reflect.apply(target, thisArg, args);
|
|
13669
|
+
},
|
|
13670
|
+
tracingChannel,
|
|
13671
|
+
traceSync: (fn, context) => tracingChannel().traceSync(
|
|
13672
|
+
fn,
|
|
13673
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
13674
|
+
context
|
|
13675
|
+
)
|
|
13676
|
+
}
|
|
13677
|
+
];
|
|
13678
|
+
})
|
|
13679
|
+
);
|
|
13680
|
+
}
|
|
13681
|
+
|
|
13682
|
+
// src/instrumentation/plugins/openai-channels.ts
|
|
13683
|
+
var openAIChannels = defineChannels(
|
|
13684
|
+
"openai",
|
|
13685
|
+
{
|
|
13686
|
+
filesCreateTraced: channel({
|
|
13687
|
+
channelName: "files.create-traced",
|
|
13688
|
+
kind: "async"
|
|
13689
|
+
}),
|
|
13690
|
+
batchesRetrieveTraced: channel({
|
|
13691
|
+
channelName: "batches.retrieve-traced",
|
|
13692
|
+
kind: "async"
|
|
13693
|
+
}),
|
|
13694
|
+
batchesCompleteTrace: channel({
|
|
13695
|
+
channelName: "batches.complete-trace",
|
|
13696
|
+
kind: "async"
|
|
13697
|
+
}),
|
|
13698
|
+
chatCompletionsCreate: channel({
|
|
13699
|
+
channelName: "chat.completions.create",
|
|
13700
|
+
kind: "async"
|
|
13701
|
+
}),
|
|
13702
|
+
embeddingsCreate: channel({
|
|
13703
|
+
channelName: "embeddings.create",
|
|
13704
|
+
kind: "async"
|
|
13705
|
+
}),
|
|
13706
|
+
betaChatCompletionsParse: channel({
|
|
13707
|
+
channelName: "beta.chat.completions.parse",
|
|
13708
|
+
kind: "async"
|
|
13709
|
+
}),
|
|
13710
|
+
betaChatCompletionsStream: channel({
|
|
13711
|
+
channelName: "beta.chat.completions.stream",
|
|
13712
|
+
kind: "sync-stream"
|
|
13713
|
+
}),
|
|
13714
|
+
moderationsCreate: channel({
|
|
13715
|
+
channelName: "moderations.create",
|
|
13716
|
+
kind: "async"
|
|
13717
|
+
}),
|
|
13718
|
+
responsesCreate: channel({
|
|
13719
|
+
channelName: "responses.create",
|
|
13720
|
+
kind: "async"
|
|
13721
|
+
}),
|
|
13722
|
+
responsesStream: channel({
|
|
13723
|
+
channelName: "responses.stream",
|
|
13724
|
+
kind: "sync-stream"
|
|
13725
|
+
}),
|
|
13726
|
+
responsesParse: channel({
|
|
13727
|
+
channelName: "responses.parse",
|
|
13728
|
+
kind: "async"
|
|
13729
|
+
}),
|
|
13730
|
+
responsesCompact: channel({
|
|
13731
|
+
channelName: "responses.compact",
|
|
13732
|
+
kind: "async"
|
|
13733
|
+
})
|
|
13734
|
+
},
|
|
13735
|
+
{ instrumentationName: INSTRUMENTATION_NAMES.OPENAI }
|
|
13736
|
+
);
|
|
13737
|
+
|
|
13280
13738
|
// src/wrappers/attachment-utils.ts
|
|
13281
13739
|
function getExtensionFromMediaType(mediaType) {
|
|
13282
13740
|
const extensionMap = {
|
|
@@ -13452,118 +13910,91 @@ function processInputAttachments(input) {
|
|
|
13452
13910
|
return processNode(input);
|
|
13453
13911
|
}
|
|
13454
13912
|
|
|
13455
|
-
// src/instrumentation/
|
|
13456
|
-
|
|
13457
|
-
|
|
13458
|
-
|
|
13459
|
-
|
|
13460
|
-
|
|
13461
|
-
|
|
13462
|
-
|
|
13463
|
-
|
|
13464
|
-
|
|
13465
|
-
|
|
13466
|
-
|
|
13467
|
-
|
|
13468
|
-
|
|
13469
|
-
|
|
13470
|
-
|
|
13471
|
-
|
|
13472
|
-
|
|
13473
|
-
|
|
13474
|
-
|
|
13475
|
-
|
|
13476
|
-
|
|
13477
|
-
...asyncSpec,
|
|
13478
|
-
instrumentationName,
|
|
13479
|
-
intercept: intercept2,
|
|
13480
|
-
invoke: (target, thisArg, args, additional) => {
|
|
13481
|
-
const hook = tracingChannel2();
|
|
13482
|
-
return typeof hook.invoke === "function" ? hook.invoke(target, thisArg, args, additional) : Reflect.apply(target, thisArg, args);
|
|
13483
|
-
},
|
|
13484
|
-
tracingChannel: tracingChannel2,
|
|
13485
|
-
tracePromise: (fn, context) => tracingChannel2().tracePromise(
|
|
13486
|
-
fn,
|
|
13487
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
13488
|
-
context
|
|
13489
|
-
)
|
|
13490
|
-
}
|
|
13491
|
-
];
|
|
13913
|
+
// src/instrumentation/plugins/openai-span-data.ts
|
|
13914
|
+
var OPENAI_METADATA_KEYS = [
|
|
13915
|
+
"model",
|
|
13916
|
+
"temperature",
|
|
13917
|
+
"top_p",
|
|
13918
|
+
"max_tokens",
|
|
13919
|
+
"frequency_penalty",
|
|
13920
|
+
"presence_penalty",
|
|
13921
|
+
"stop",
|
|
13922
|
+
"response_format",
|
|
13923
|
+
"tools",
|
|
13924
|
+
"tool_choice",
|
|
13925
|
+
"parallel_tool_calls",
|
|
13926
|
+
"max_tool_calls"
|
|
13927
|
+
];
|
|
13928
|
+
function batchMetadata(params) {
|
|
13929
|
+
const metadata = { provider: "openai" };
|
|
13930
|
+
for (const key of OPENAI_METADATA_KEYS) {
|
|
13931
|
+
try {
|
|
13932
|
+
const value = Reflect.get(params, key);
|
|
13933
|
+
if (value !== void 0) {
|
|
13934
|
+
metadata[key] = value;
|
|
13492
13935
|
}
|
|
13493
|
-
|
|
13494
|
-
|
|
13495
|
-
|
|
13496
|
-
|
|
13497
|
-
|
|
13498
|
-
|
|
13499
|
-
|
|
13500
|
-
|
|
13501
|
-
|
|
13502
|
-
|
|
13503
|
-
|
|
13504
|
-
|
|
13505
|
-
|
|
13506
|
-
|
|
13507
|
-
|
|
13508
|
-
|
|
13509
|
-
|
|
13510
|
-
|
|
13511
|
-
|
|
13512
|
-
|
|
13513
|
-
|
|
13514
|
-
|
|
13515
|
-
|
|
13516
|
-
|
|
13517
|
-
|
|
13518
|
-
|
|
13519
|
-
|
|
13520
|
-
|
|
13521
|
-
|
|
13936
|
+
} catch {
|
|
13937
|
+
}
|
|
13938
|
+
}
|
|
13939
|
+
return metadata;
|
|
13940
|
+
}
|
|
13941
|
+
function extractOpenAIBatchInput(endpoint, params) {
|
|
13942
|
+
const input = endpoint === "/v1/chat/completions" ? params.messages : params.input;
|
|
13943
|
+
return {
|
|
13944
|
+
input: processInputAttachments(input),
|
|
13945
|
+
metadata: batchMetadata(params)
|
|
13946
|
+
};
|
|
13947
|
+
}
|
|
13948
|
+
function extractOpenAIChatInput(params) {
|
|
13949
|
+
const { messages, ...metadata } = params;
|
|
13950
|
+
return {
|
|
13951
|
+
input: processInputAttachments(messages),
|
|
13952
|
+
metadata: { ...metadata, provider: "openai" }
|
|
13953
|
+
};
|
|
13954
|
+
}
|
|
13955
|
+
function extractOpenAIResponsesInput(params) {
|
|
13956
|
+
const { input, ...metadata } = params;
|
|
13957
|
+
return {
|
|
13958
|
+
input: processInputAttachments(input),
|
|
13959
|
+
metadata: { ...metadata, provider: "openai" }
|
|
13960
|
+
};
|
|
13961
|
+
}
|
|
13962
|
+
function extractOpenAIResponsesMetadata(result) {
|
|
13963
|
+
if (!result) {
|
|
13964
|
+
return void 0;
|
|
13965
|
+
}
|
|
13966
|
+
const { output: _output, usage: _usage, ...metadata } = result;
|
|
13967
|
+
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
13968
|
+
}
|
|
13969
|
+
function processImagesInOutput(output) {
|
|
13970
|
+
if (Array.isArray(output)) {
|
|
13971
|
+
return output.map(processImagesInOutput);
|
|
13972
|
+
}
|
|
13973
|
+
if (isObject(output) && output.type === "image_generation_call" && typeof output.result === "string" && output.result) {
|
|
13974
|
+
const fileExtension = output.output_format || "png";
|
|
13975
|
+
const contentType = `image/${fileExtension}`;
|
|
13976
|
+
const baseFilename = typeof output.revised_prompt === "string" ? output.revised_prompt.slice(0, 50).replace(/[^a-zA-Z0-9]/g, "_") : "generated_image";
|
|
13977
|
+
let binaryString;
|
|
13978
|
+
try {
|
|
13979
|
+
binaryString = atob(output.result);
|
|
13980
|
+
} catch {
|
|
13981
|
+
return output;
|
|
13982
|
+
}
|
|
13983
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
13984
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
13985
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
13986
|
+
}
|
|
13987
|
+
return {
|
|
13988
|
+
...output,
|
|
13989
|
+
result: new Attachment({
|
|
13990
|
+
data: new Blob([bytes], { type: contentType }),
|
|
13991
|
+
filename: `${baseFilename}.${fileExtension}`,
|
|
13992
|
+
contentType
|
|
13993
|
+
})
|
|
13994
|
+
};
|
|
13995
|
+
}
|
|
13996
|
+
return output;
|
|
13522
13997
|
}
|
|
13523
|
-
|
|
13524
|
-
// src/instrumentation/plugins/openai-channels.ts
|
|
13525
|
-
var openAIChannels = defineChannels(
|
|
13526
|
-
"openai",
|
|
13527
|
-
{
|
|
13528
|
-
chatCompletionsCreate: channel({
|
|
13529
|
-
channelName: "chat.completions.create",
|
|
13530
|
-
kind: "async"
|
|
13531
|
-
}),
|
|
13532
|
-
embeddingsCreate: channel({
|
|
13533
|
-
channelName: "embeddings.create",
|
|
13534
|
-
kind: "async"
|
|
13535
|
-
}),
|
|
13536
|
-
betaChatCompletionsParse: channel({
|
|
13537
|
-
channelName: "beta.chat.completions.parse",
|
|
13538
|
-
kind: "async"
|
|
13539
|
-
}),
|
|
13540
|
-
betaChatCompletionsStream: channel({
|
|
13541
|
-
channelName: "beta.chat.completions.stream",
|
|
13542
|
-
kind: "sync-stream"
|
|
13543
|
-
}),
|
|
13544
|
-
moderationsCreate: channel({
|
|
13545
|
-
channelName: "moderations.create",
|
|
13546
|
-
kind: "async"
|
|
13547
|
-
}),
|
|
13548
|
-
responsesCreate: channel({
|
|
13549
|
-
channelName: "responses.create",
|
|
13550
|
-
kind: "async"
|
|
13551
|
-
}),
|
|
13552
|
-
responsesStream: channel({
|
|
13553
|
-
channelName: "responses.stream",
|
|
13554
|
-
kind: "sync-stream"
|
|
13555
|
-
}),
|
|
13556
|
-
responsesParse: channel({
|
|
13557
|
-
channelName: "responses.parse",
|
|
13558
|
-
kind: "async"
|
|
13559
|
-
}),
|
|
13560
|
-
responsesCompact: channel({
|
|
13561
|
-
channelName: "responses.compact",
|
|
13562
|
-
kind: "async"
|
|
13563
|
-
})
|
|
13564
|
-
},
|
|
13565
|
-
{ instrumentationName: INSTRUMENTATION_NAMES.OPENAI }
|
|
13566
|
-
);
|
|
13567
13998
|
|
|
13568
13999
|
// src/openai-utils.ts
|
|
13569
14000
|
var BRAINTRUST_CACHED_STREAM_METRIC = "__braintrust_cached_metric";
|
|
@@ -13620,23 +14051,573 @@ function getCachedMetricFromHeaders(headers) {
|
|
|
13620
14051
|
return parseCachedHeader(headers.get(LEGACY_CACHED_HEADER));
|
|
13621
14052
|
}
|
|
13622
14053
|
|
|
14054
|
+
// src/instrumentation/plugins/openai-batch-instrumentation.ts
|
|
14055
|
+
var SUPPORTED_ENDPOINTS = /* @__PURE__ */ new Set(["/v1/chat/completions", "/v1/responses"]);
|
|
14056
|
+
var TERMINAL_STATUSES = /* @__PURE__ */ new Set([
|
|
14057
|
+
"completed",
|
|
14058
|
+
"failed",
|
|
14059
|
+
"expired",
|
|
14060
|
+
"cancelled"
|
|
14061
|
+
]);
|
|
14062
|
+
var pendingBatchTraces = /* @__PURE__ */ new Map();
|
|
14063
|
+
function read(value, key) {
|
|
14064
|
+
if (!isObject(value)) {
|
|
14065
|
+
return void 0;
|
|
14066
|
+
}
|
|
14067
|
+
try {
|
|
14068
|
+
return Reflect.get(value, key);
|
|
14069
|
+
} catch {
|
|
14070
|
+
return void 0;
|
|
14071
|
+
}
|
|
14072
|
+
}
|
|
14073
|
+
function isBatchRecordIterable(value) {
|
|
14074
|
+
if (value === null || typeof value !== "object" && typeof value !== "function") {
|
|
14075
|
+
return false;
|
|
14076
|
+
}
|
|
14077
|
+
return typeof read(value, Symbol.iterator) === "function" || typeof read(value, Symbol.asyncIterator) === "function";
|
|
14078
|
+
}
|
|
14079
|
+
function validCustomId(value) {
|
|
14080
|
+
return typeof value === "string" && value.length > 0 && value.length <= 64;
|
|
14081
|
+
}
|
|
14082
|
+
function logBatchInstrumentationError(context, error) {
|
|
14083
|
+
debugLogger.debug(`OpenAI Batch instrumentation ${context}:`, error);
|
|
14084
|
+
}
|
|
14085
|
+
async function exportParent(parent) {
|
|
14086
|
+
if ("toStr" in parent && typeof parent.toStr === "function") {
|
|
14087
|
+
return parent.toStr();
|
|
14088
|
+
}
|
|
14089
|
+
if ("export" in parent && typeof parent.export === "function") {
|
|
14090
|
+
return await parent.export();
|
|
14091
|
+
}
|
|
14092
|
+
return void 0;
|
|
14093
|
+
}
|
|
14094
|
+
async function deterministicDigest(namespace, ...parts) {
|
|
14095
|
+
const encoded = new TextEncoder().encode(
|
|
14096
|
+
[namespace, ...parts].map((part) => `${part.length}:${part}`).join("\0")
|
|
14097
|
+
);
|
|
14098
|
+
return new Uint8Array(
|
|
14099
|
+
await globalThis.crypto.subtle.digest("SHA-256", encoded)
|
|
14100
|
+
);
|
|
14101
|
+
}
|
|
14102
|
+
function digestHex(bytes, length) {
|
|
14103
|
+
return Array.from(bytes.slice(0, length)).map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
14104
|
+
}
|
|
14105
|
+
function digestUuid(bytes) {
|
|
14106
|
+
const hex = digestHex(bytes, 16);
|
|
14107
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
14108
|
+
}
|
|
14109
|
+
async function batchSpanIds(inputFileId) {
|
|
14110
|
+
const [row, span, root] = await Promise.all([
|
|
14111
|
+
deterministicDigest("openai:batch:row", inputFileId),
|
|
14112
|
+
deterministicDigest("openai:batch:span", inputFileId),
|
|
14113
|
+
deterministicDigest("openai:batch:root", inputFileId)
|
|
14114
|
+
]);
|
|
14115
|
+
return {
|
|
14116
|
+
rowId: digestUuid(row),
|
|
14117
|
+
spanId: digestHex(span, 8),
|
|
14118
|
+
rootSpanId: digestHex(root, 16)
|
|
14119
|
+
};
|
|
14120
|
+
}
|
|
14121
|
+
async function childSpanIds(inputFileId, customId) {
|
|
14122
|
+
const [row, span] = await Promise.all([
|
|
14123
|
+
deterministicDigest("openai:batch:child:row", inputFileId, customId),
|
|
14124
|
+
deterministicDigest("openai:batch:child:span", inputFileId, customId)
|
|
14125
|
+
]);
|
|
14126
|
+
return { rowId: digestUuid(row), spanId: digestHex(span, 8) };
|
|
14127
|
+
}
|
|
14128
|
+
async function startBatchSpan(context) {
|
|
14129
|
+
const ids = await batchSpanIds(context.inputFileId);
|
|
14130
|
+
const parent = SpanComponentsV4.fromStr(context.parent);
|
|
14131
|
+
const hasParentSpan = Boolean(
|
|
14132
|
+
parent.data.row_id && parent.data.span_id && parent.data.root_span_id
|
|
14133
|
+
);
|
|
14134
|
+
return withCurrent(
|
|
14135
|
+
NOOP_SPAN,
|
|
14136
|
+
() => _internalStartSpanWithInitialMergeAndParentSpanIds(
|
|
14137
|
+
withSpanInstrumentationName(
|
|
14138
|
+
{
|
|
14139
|
+
name: "openai.batch",
|
|
14140
|
+
type: "task" /* TASK */,
|
|
14141
|
+
parent: context.parent,
|
|
14142
|
+
...!hasParentSpan ? {
|
|
14143
|
+
parentSpanIds: {
|
|
14144
|
+
parentSpanIds: [],
|
|
14145
|
+
rootSpanId: ids.rootSpanId
|
|
14146
|
+
}
|
|
14147
|
+
} : {},
|
|
14148
|
+
spanId: ids.spanId,
|
|
14149
|
+
startTime: context.taskStartTime,
|
|
14150
|
+
event: {
|
|
14151
|
+
id: ids.rowId,
|
|
14152
|
+
metadata: {
|
|
14153
|
+
endpoint: context.endpoint,
|
|
14154
|
+
input_file_id: context.inputFileId,
|
|
14155
|
+
provider: "openai"
|
|
14156
|
+
}
|
|
14157
|
+
}
|
|
14158
|
+
},
|
|
14159
|
+
INSTRUMENTATION_NAMES.OPENAI
|
|
14160
|
+
)
|
|
14161
|
+
)
|
|
14162
|
+
);
|
|
14163
|
+
}
|
|
14164
|
+
async function startBatchChild(context, taskParent, input) {
|
|
14165
|
+
const ids = await childSpanIds(context.inputFileId, input.customId);
|
|
14166
|
+
return withCurrent(
|
|
14167
|
+
NOOP_SPAN,
|
|
14168
|
+
() => _internalStartSpanWithInitialMerge(
|
|
14169
|
+
withSpanInstrumentationName(
|
|
14170
|
+
{
|
|
14171
|
+
name: context.endpoint === "/v1/chat/completions" ? "Chat Completion" : "openai.responses.create",
|
|
14172
|
+
type: "llm" /* LLM */,
|
|
14173
|
+
parent: taskParent,
|
|
14174
|
+
spanId: ids.spanId,
|
|
14175
|
+
startTime: context.childStartTime,
|
|
14176
|
+
event: {
|
|
14177
|
+
id: ids.rowId,
|
|
14178
|
+
...input.spanData?.input !== void 0 ? { input: input.spanData.input } : {},
|
|
14179
|
+
metadata: {
|
|
14180
|
+
...input.spanData?.metadata,
|
|
14181
|
+
custom_id: input.customId,
|
|
14182
|
+
provider: "openai"
|
|
14183
|
+
}
|
|
14184
|
+
}
|
|
14185
|
+
},
|
|
14186
|
+
INSTRUMENTATION_NAMES.OPENAI
|
|
14187
|
+
)
|
|
14188
|
+
)
|
|
14189
|
+
);
|
|
14190
|
+
}
|
|
14191
|
+
async function* jsonlRecords(file, onIssue = () => {
|
|
14192
|
+
}) {
|
|
14193
|
+
const resolvedFile = await file;
|
|
14194
|
+
if (typeof resolvedFile === "string") {
|
|
14195
|
+
for (const line of resolvedFile.split("\n")) {
|
|
14196
|
+
if (!line.trim()) {
|
|
14197
|
+
continue;
|
|
14198
|
+
}
|
|
14199
|
+
try {
|
|
14200
|
+
yield JSON.parse(line.replace(/\r$/, ""));
|
|
14201
|
+
} catch (error) {
|
|
14202
|
+
logBatchInstrumentationError("skipped malformed JSONL", error);
|
|
14203
|
+
onIssue(new Error("OpenAI Batch file contains malformed JSONL"));
|
|
14204
|
+
}
|
|
14205
|
+
}
|
|
14206
|
+
return;
|
|
14207
|
+
}
|
|
14208
|
+
const body = read(resolvedFile, "body");
|
|
14209
|
+
const getReader = read(body, "getReader");
|
|
14210
|
+
if (isObject(body) && typeof getReader === "function") {
|
|
14211
|
+
let reader;
|
|
14212
|
+
try {
|
|
14213
|
+
reader = Reflect.apply(getReader, body, []);
|
|
14214
|
+
const decoder2 = new TextDecoder();
|
|
14215
|
+
let pending = "";
|
|
14216
|
+
while (true) {
|
|
14217
|
+
const readChunk = read(reader, "read");
|
|
14218
|
+
if (typeof readChunk !== "function") {
|
|
14219
|
+
throw new Error("Response body stream has no read method");
|
|
14220
|
+
}
|
|
14221
|
+
const chunk = await Reflect.apply(readChunk, reader, []);
|
|
14222
|
+
if (!isObject(chunk)) {
|
|
14223
|
+
throw new Error("Response body stream returned an invalid chunk");
|
|
14224
|
+
}
|
|
14225
|
+
if (chunk.done === true) {
|
|
14226
|
+
pending += decoder2.decode();
|
|
14227
|
+
break;
|
|
14228
|
+
}
|
|
14229
|
+
if (!(chunk.value instanceof Uint8Array)) {
|
|
14230
|
+
throw new Error("Response body stream returned a non-byte chunk");
|
|
14231
|
+
}
|
|
14232
|
+
pending += decoder2.decode(chunk.value, { stream: true });
|
|
14233
|
+
let newline = pending.indexOf("\n");
|
|
14234
|
+
while (newline !== -1) {
|
|
14235
|
+
const line = pending.slice(0, newline).replace(/\r$/, "");
|
|
14236
|
+
pending = pending.slice(newline + 1);
|
|
14237
|
+
if (line.trim()) {
|
|
14238
|
+
try {
|
|
14239
|
+
yield JSON.parse(line);
|
|
14240
|
+
} catch (error) {
|
|
14241
|
+
logBatchInstrumentationError("skipped malformed JSONL", error);
|
|
14242
|
+
onIssue(new Error("OpenAI Batch file contains malformed JSONL"));
|
|
14243
|
+
}
|
|
14244
|
+
}
|
|
14245
|
+
newline = pending.indexOf("\n");
|
|
14246
|
+
}
|
|
14247
|
+
}
|
|
14248
|
+
if (pending.trim()) {
|
|
14249
|
+
try {
|
|
14250
|
+
yield JSON.parse(pending.replace(/\r$/, ""));
|
|
14251
|
+
} catch (error) {
|
|
14252
|
+
logBatchInstrumentationError("skipped malformed JSONL", error);
|
|
14253
|
+
onIssue(new Error("OpenAI Batch file contains malformed JSONL"));
|
|
14254
|
+
}
|
|
14255
|
+
}
|
|
14256
|
+
} catch (error) {
|
|
14257
|
+
logBatchInstrumentationError("could not read JSONL response body", error);
|
|
14258
|
+
onIssue(new Error("OpenAI Batch response body could not be read"));
|
|
14259
|
+
} finally {
|
|
14260
|
+
const releaseLock = read(reader, "releaseLock");
|
|
14261
|
+
if (typeof releaseLock === "function") {
|
|
14262
|
+
try {
|
|
14263
|
+
Reflect.apply(releaseLock, reader, []);
|
|
14264
|
+
} catch (error) {
|
|
14265
|
+
logBatchInstrumentationError(
|
|
14266
|
+
"could not release stream reader",
|
|
14267
|
+
error
|
|
14268
|
+
);
|
|
14269
|
+
}
|
|
14270
|
+
}
|
|
14271
|
+
}
|
|
14272
|
+
return;
|
|
14273
|
+
}
|
|
14274
|
+
if (isBatchRecordIterable(resolvedFile)) {
|
|
14275
|
+
for await (const record of resolvedFile) {
|
|
14276
|
+
yield record;
|
|
14277
|
+
}
|
|
14278
|
+
return;
|
|
14279
|
+
}
|
|
14280
|
+
logBatchInstrumentationError("skipped invalid JSONL source", resolvedFile);
|
|
14281
|
+
onIssue(new Error("OpenAI Batch file source is invalid"));
|
|
14282
|
+
}
|
|
14283
|
+
async function readBatchInputs(file) {
|
|
14284
|
+
const inputs = /* @__PURE__ */ new Map();
|
|
14285
|
+
const issues = [];
|
|
14286
|
+
let endpoint;
|
|
14287
|
+
try {
|
|
14288
|
+
for await (const value of jsonlRecords(
|
|
14289
|
+
file,
|
|
14290
|
+
(issue) => issues.push(issue)
|
|
14291
|
+
)) {
|
|
14292
|
+
const customId = read(value, "custom_id");
|
|
14293
|
+
const url = read(value, "url");
|
|
14294
|
+
const body = read(value, "body");
|
|
14295
|
+
if (!validCustomId(customId) || inputs.has(customId) || read(value, "method") !== "POST" || typeof url !== "string" || !SUPPORTED_ENDPOINTS.has(url) || endpoint !== void 0 && endpoint !== url || !isObject(body)) {
|
|
14296
|
+
issues.push(new Error("OpenAI Batch input contains an invalid record"));
|
|
14297
|
+
continue;
|
|
14298
|
+
}
|
|
14299
|
+
endpoint = url;
|
|
14300
|
+
let spanData;
|
|
14301
|
+
try {
|
|
14302
|
+
spanData = extractOpenAIBatchInput(url, body);
|
|
14303
|
+
} catch (error) {
|
|
14304
|
+
logBatchInstrumentationError("could not extract batch input", error);
|
|
14305
|
+
}
|
|
14306
|
+
inputs.set(customId, { customId, spanData });
|
|
14307
|
+
}
|
|
14308
|
+
} catch (error) {
|
|
14309
|
+
logBatchInstrumentationError("could not process input file", error);
|
|
14310
|
+
issues.push(new Error("OpenAI Batch input file could not be processed"));
|
|
14311
|
+
}
|
|
14312
|
+
if (!endpoint || inputs.size === 0) {
|
|
14313
|
+
issues.push(new Error("OpenAI Batch input contains no supported records"));
|
|
14314
|
+
}
|
|
14315
|
+
return { endpoint, inputs, issues };
|
|
14316
|
+
}
|
|
14317
|
+
async function writePendingSpans(trace, endTime) {
|
|
14318
|
+
const task = await startBatchSpan(trace.context);
|
|
14319
|
+
const taskParent = await task.export();
|
|
14320
|
+
for (const input of trace.inputs.values()) {
|
|
14321
|
+
try {
|
|
14322
|
+
const child = await startBatchChild(trace.context, taskParent, input);
|
|
14323
|
+
if (endTime !== void 0) {
|
|
14324
|
+
child.end({ endTime });
|
|
14325
|
+
}
|
|
14326
|
+
} catch (error) {
|
|
14327
|
+
logBatchInstrumentationError("could not write batch request span", error);
|
|
14328
|
+
}
|
|
14329
|
+
}
|
|
14330
|
+
if (endTime !== void 0) {
|
|
14331
|
+
if (trace.status && trace.status !== "completed") {
|
|
14332
|
+
task.log({ error: new Error(`OpenAI Batch ${trace.status}`) });
|
|
14333
|
+
}
|
|
14334
|
+
task.end({ endTime });
|
|
14335
|
+
}
|
|
14336
|
+
}
|
|
14337
|
+
var interceptOpenAIFilesCreateTraced = async (target, thisArg, args) => {
|
|
14338
|
+
const startTime = getCurrentUnixTimestamp();
|
|
14339
|
+
const inputPromise = readBatchInputs(args[0].inputFileContent);
|
|
14340
|
+
const parentPromise = exportParent(args[0].parent);
|
|
14341
|
+
const file = await Reflect.apply(target, thisArg, args);
|
|
14342
|
+
try {
|
|
14343
|
+
const inputFileId = read(file, "id");
|
|
14344
|
+
const [inputData, exportedParent2] = await Promise.all([
|
|
14345
|
+
inputPromise,
|
|
14346
|
+
parentPromise
|
|
14347
|
+
]);
|
|
14348
|
+
if (typeof inputFileId !== "string" || !exportedParent2 || !inputData.endpoint || inputData.issues.length > 0) {
|
|
14349
|
+
if (inputData.issues[0]) {
|
|
14350
|
+
logBatchInstrumentationError(
|
|
14351
|
+
"skipped invalid input file",
|
|
14352
|
+
inputData.issues[0]
|
|
14353
|
+
);
|
|
14354
|
+
}
|
|
14355
|
+
return file;
|
|
14356
|
+
}
|
|
14357
|
+
const trace = {
|
|
14358
|
+
context: {
|
|
14359
|
+
inputFileId,
|
|
14360
|
+
endpoint: inputData.endpoint,
|
|
14361
|
+
parent: exportedParent2,
|
|
14362
|
+
taskStartTime: startTime,
|
|
14363
|
+
childStartTime: startTime
|
|
14364
|
+
},
|
|
14365
|
+
inputs: inputData.inputs
|
|
14366
|
+
};
|
|
14367
|
+
pendingBatchTraces.set(inputFileId, trace);
|
|
14368
|
+
await writePendingSpans(trace);
|
|
14369
|
+
} catch (error) {
|
|
14370
|
+
logBatchInstrumentationError("could not start batch spans", error);
|
|
14371
|
+
}
|
|
14372
|
+
return file;
|
|
14373
|
+
};
|
|
14374
|
+
function validTimestamp(value) {
|
|
14375
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0;
|
|
14376
|
+
}
|
|
14377
|
+
function terminalEndTime(batch, startTime) {
|
|
14378
|
+
let timestamp;
|
|
14379
|
+
switch (batch.status) {
|
|
14380
|
+
case "completed":
|
|
14381
|
+
timestamp = batch.completed_at;
|
|
14382
|
+
break;
|
|
14383
|
+
case "failed":
|
|
14384
|
+
timestamp = batch.failed_at;
|
|
14385
|
+
break;
|
|
14386
|
+
case "expired":
|
|
14387
|
+
timestamp = batch.expired_at;
|
|
14388
|
+
break;
|
|
14389
|
+
default:
|
|
14390
|
+
timestamp = batch.cancelled_at;
|
|
14391
|
+
}
|
|
14392
|
+
return validTimestamp(timestamp) ? Math.max(timestamp, startTime) : Math.max(getCurrentUnixTimestamp(), startTime);
|
|
14393
|
+
}
|
|
14394
|
+
async function updateBatchTimestamps(batch) {
|
|
14395
|
+
const trace = pendingBatchTraces.get(batch.input_file_id);
|
|
14396
|
+
if (!trace || trace.context.endpoint !== batch.endpoint) {
|
|
14397
|
+
return;
|
|
14398
|
+
}
|
|
14399
|
+
if (validTimestamp(batch.created_at)) {
|
|
14400
|
+
trace.context.taskStartTime = batch.created_at;
|
|
14401
|
+
}
|
|
14402
|
+
trace.context.childStartTime = validTimestamp(batch.in_progress_at) ? Math.max(batch.in_progress_at, trace.context.taskStartTime) : trace.context.taskStartTime;
|
|
14403
|
+
trace.status = batch.status;
|
|
14404
|
+
if (TERMINAL_STATUSES.has(batch.status)) {
|
|
14405
|
+
trace.endTime = terminalEndTime(batch, trace.context.childStartTime);
|
|
14406
|
+
}
|
|
14407
|
+
await writePendingSpans(trace, trace.endTime);
|
|
14408
|
+
}
|
|
14409
|
+
var interceptOpenAIBatchesRetrieveTraced = (target, thisArg, args) => Promise.resolve(Reflect.apply(target, thisArg, args)).then(async (batch) => {
|
|
14410
|
+
try {
|
|
14411
|
+
await updateBatchTimestamps(batch);
|
|
14412
|
+
} catch (error) {
|
|
14413
|
+
logBatchInstrumentationError("could not update batch timestamps", error);
|
|
14414
|
+
}
|
|
14415
|
+
return batch;
|
|
14416
|
+
});
|
|
14417
|
+
function errorFromResult(result) {
|
|
14418
|
+
const error = read(result.value, "error");
|
|
14419
|
+
if (isObject(error)) {
|
|
14420
|
+
const message = read(error, "message");
|
|
14421
|
+
return new Error(
|
|
14422
|
+
typeof message === "string" ? message : "OpenAI Batch request failed"
|
|
14423
|
+
);
|
|
14424
|
+
}
|
|
14425
|
+
const response = read(result.value, "response");
|
|
14426
|
+
const statusCode = read(response, "status_code");
|
|
14427
|
+
if (result.source === "error" || typeof statusCode === "number" && (statusCode < 200 || statusCode >= 300)) {
|
|
14428
|
+
const message = read(read(read(response, "body"), "error"), "message");
|
|
14429
|
+
return new Error(
|
|
14430
|
+
typeof message === "string" ? message : "OpenAI Batch request failed"
|
|
14431
|
+
);
|
|
14432
|
+
}
|
|
14433
|
+
return void 0;
|
|
14434
|
+
}
|
|
14435
|
+
async function completeBatchResult(context, taskParent, endTime, input, result) {
|
|
14436
|
+
const child = await startBatchChild(context, taskParent, input);
|
|
14437
|
+
try {
|
|
14438
|
+
const resultError = errorFromResult(result);
|
|
14439
|
+
const responseBody = read(read(result.value, "response"), "body");
|
|
14440
|
+
if (resultError) {
|
|
14441
|
+
child.log({ error: resultError });
|
|
14442
|
+
} else if (isObject(responseBody)) {
|
|
14443
|
+
const model = read(responseBody, "model");
|
|
14444
|
+
child.log({
|
|
14445
|
+
output: context.endpoint === "/v1/chat/completions" ? read(responseBody, "choices") : processImagesInOutput(read(responseBody, "output")),
|
|
14446
|
+
...typeof model === "string" ? { metadata: { model } } : {},
|
|
14447
|
+
metrics: parseMetricsFromUsage(read(responseBody, "usage"))
|
|
14448
|
+
});
|
|
14449
|
+
} else {
|
|
14450
|
+
child.log({ error: new Error("OpenAI Batch response body is missing") });
|
|
14451
|
+
}
|
|
14452
|
+
} catch (error) {
|
|
14453
|
+
child.log({ error });
|
|
14454
|
+
} finally {
|
|
14455
|
+
child.end({ endTime });
|
|
14456
|
+
}
|
|
14457
|
+
}
|
|
14458
|
+
async function completeResultFile({
|
|
14459
|
+
context,
|
|
14460
|
+
endTime,
|
|
14461
|
+
file,
|
|
14462
|
+
inputs,
|
|
14463
|
+
issues,
|
|
14464
|
+
seen,
|
|
14465
|
+
source,
|
|
14466
|
+
taskParent
|
|
14467
|
+
}) {
|
|
14468
|
+
if (file === void 0) {
|
|
14469
|
+
return;
|
|
14470
|
+
}
|
|
14471
|
+
for await (const value of jsonlRecords(file, (issue) => issues.push(issue))) {
|
|
14472
|
+
const customId = read(value, "custom_id");
|
|
14473
|
+
if (!validCustomId(customId) || !isObject(value)) {
|
|
14474
|
+
issues.push(
|
|
14475
|
+
new Error("OpenAI Batch result is missing a valid custom_id")
|
|
14476
|
+
);
|
|
14477
|
+
continue;
|
|
14478
|
+
}
|
|
14479
|
+
if (seen.has(customId)) {
|
|
14480
|
+
issues.push(new Error("OpenAI Batch result contains a duplicate"));
|
|
14481
|
+
continue;
|
|
14482
|
+
}
|
|
14483
|
+
const input = inputs.get(customId);
|
|
14484
|
+
if (!input) {
|
|
14485
|
+
issues.push(
|
|
14486
|
+
new Error("OpenAI Batch result does not match an input record")
|
|
14487
|
+
);
|
|
14488
|
+
continue;
|
|
14489
|
+
}
|
|
14490
|
+
seen.add(customId);
|
|
14491
|
+
await completeBatchResult(context, taskParent, endTime, input, {
|
|
14492
|
+
value,
|
|
14493
|
+
source
|
|
14494
|
+
});
|
|
14495
|
+
}
|
|
14496
|
+
}
|
|
14497
|
+
function sameInputs(first, second) {
|
|
14498
|
+
return first.size === second.size && [...first.keys()].every((customId) => second.has(customId));
|
|
14499
|
+
}
|
|
14500
|
+
async function contextForCompletion(inputFileId, inputData) {
|
|
14501
|
+
if (!inputData.endpoint || inputData.issues.length > 0) {
|
|
14502
|
+
return void 0;
|
|
14503
|
+
}
|
|
14504
|
+
const existing = pendingBatchTraces.get(inputFileId);
|
|
14505
|
+
if (existing) {
|
|
14506
|
+
if (existing.context.endpoint !== inputData.endpoint || !sameInputs(existing.inputs, inputData.inputs)) {
|
|
14507
|
+
return void 0;
|
|
14508
|
+
}
|
|
14509
|
+
return { ...existing, inputs: inputData.inputs };
|
|
14510
|
+
}
|
|
14511
|
+
const parent = await exportParent(getSpanParentObject());
|
|
14512
|
+
if (!parent) {
|
|
14513
|
+
return void 0;
|
|
14514
|
+
}
|
|
14515
|
+
const startTime = getCurrentUnixTimestamp();
|
|
14516
|
+
return {
|
|
14517
|
+
context: {
|
|
14518
|
+
inputFileId,
|
|
14519
|
+
endpoint: inputData.endpoint,
|
|
14520
|
+
parent,
|
|
14521
|
+
taskStartTime: startTime,
|
|
14522
|
+
childStartTime: startTime
|
|
14523
|
+
},
|
|
14524
|
+
inputs: inputData.inputs
|
|
14525
|
+
};
|
|
14526
|
+
}
|
|
14527
|
+
async function completeBatch(args) {
|
|
14528
|
+
const inputData = await readBatchInputs(args.inputFileContent);
|
|
14529
|
+
const trace = await contextForCompletion(args.inputFileId, inputData);
|
|
14530
|
+
if (!trace) {
|
|
14531
|
+
logBatchInstrumentationError(
|
|
14532
|
+
"left batch spans pending",
|
|
14533
|
+
inputData.issues[0] ?? new Error("OpenAI Batch input does not match")
|
|
14534
|
+
);
|
|
14535
|
+
return;
|
|
14536
|
+
}
|
|
14537
|
+
const endTime = trace.endTime ?? getCurrentUnixTimestamp();
|
|
14538
|
+
const task = await startBatchSpan(trace.context);
|
|
14539
|
+
const taskParent = await task.export();
|
|
14540
|
+
const issues = [];
|
|
14541
|
+
const seen = /* @__PURE__ */ new Set();
|
|
14542
|
+
await Promise.all([
|
|
14543
|
+
completeResultFile({
|
|
14544
|
+
context: trace.context,
|
|
14545
|
+
endTime,
|
|
14546
|
+
file: args.outputFileContent,
|
|
14547
|
+
inputs: trace.inputs,
|
|
14548
|
+
issues,
|
|
14549
|
+
seen,
|
|
14550
|
+
source: "output",
|
|
14551
|
+
taskParent
|
|
14552
|
+
}),
|
|
14553
|
+
completeResultFile({
|
|
14554
|
+
context: trace.context,
|
|
14555
|
+
endTime,
|
|
14556
|
+
file: args.errorFileContent,
|
|
14557
|
+
inputs: trace.inputs,
|
|
14558
|
+
issues,
|
|
14559
|
+
seen,
|
|
14560
|
+
source: "error",
|
|
14561
|
+
taskParent
|
|
14562
|
+
})
|
|
14563
|
+
]);
|
|
14564
|
+
if (issues.length > 0) {
|
|
14565
|
+
logBatchInstrumentationError("left batch spans pending", issues[0]);
|
|
14566
|
+
return;
|
|
14567
|
+
}
|
|
14568
|
+
const missing = [...trace.inputs.values()].filter(
|
|
14569
|
+
({ customId }) => !seen.has(customId)
|
|
14570
|
+
);
|
|
14571
|
+
if (!trace.status || trace.status === "completed") {
|
|
14572
|
+
if (missing.length > 0) {
|
|
14573
|
+
logBatchInstrumentationError(
|
|
14574
|
+
"left batch spans pending",
|
|
14575
|
+
new Error("OpenAI Batch result files are incomplete")
|
|
14576
|
+
);
|
|
14577
|
+
return;
|
|
14578
|
+
}
|
|
14579
|
+
} else {
|
|
14580
|
+
for (const input of missing) {
|
|
14581
|
+
const child = await startBatchChild(trace.context, taskParent, input);
|
|
14582
|
+
child.log({ error: new Error(`OpenAI Batch ${trace.status}`) });
|
|
14583
|
+
child.end({ endTime });
|
|
14584
|
+
}
|
|
14585
|
+
task.log({ error: new Error(`OpenAI Batch ${trace.status}`) });
|
|
14586
|
+
}
|
|
14587
|
+
task.end({ endTime });
|
|
14588
|
+
pendingBatchTraces.delete(args.inputFileId);
|
|
14589
|
+
}
|
|
14590
|
+
var interceptOpenAIBatchTraceComplete = (target, thisArg, args) => Promise.resolve(Reflect.apply(target, thisArg, args)).then(async (result) => {
|
|
14591
|
+
try {
|
|
14592
|
+
await completeBatch(args[0]);
|
|
14593
|
+
} catch (error) {
|
|
14594
|
+
logBatchInstrumentationError("could not complete batch", error);
|
|
14595
|
+
}
|
|
14596
|
+
return result;
|
|
14597
|
+
});
|
|
14598
|
+
|
|
13623
14599
|
// src/instrumentation/plugins/openai-plugin.ts
|
|
13624
14600
|
var OpenAIPlugin = class extends BasePlugin {
|
|
13625
14601
|
constructor() {
|
|
13626
14602
|
super();
|
|
13627
14603
|
}
|
|
13628
14604
|
onEnable() {
|
|
14605
|
+
this.unsubscribers.push(
|
|
14606
|
+
openAIChannels.filesCreateTraced.intercept(
|
|
14607
|
+
interceptOpenAIFilesCreateTraced
|
|
14608
|
+
),
|
|
14609
|
+
openAIChannels.batchesRetrieveTraced.intercept(
|
|
14610
|
+
interceptOpenAIBatchesRetrieveTraced
|
|
14611
|
+
),
|
|
14612
|
+
openAIChannels.batchesCompleteTrace.intercept(
|
|
14613
|
+
interceptOpenAIBatchTraceComplete
|
|
14614
|
+
)
|
|
14615
|
+
);
|
|
13629
14616
|
this.unsubscribers.push(
|
|
13630
14617
|
traceStreamingChannel(openAIChannels.chatCompletionsCreate, {
|
|
13631
14618
|
name: "Chat Completion",
|
|
13632
14619
|
type: "llm" /* LLM */,
|
|
13633
|
-
extractInput: ([params]) =>
|
|
13634
|
-
const { messages, ...metadata } = params;
|
|
13635
|
-
return {
|
|
13636
|
-
input: processInputAttachments(messages),
|
|
13637
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13638
|
-
};
|
|
13639
|
-
},
|
|
14620
|
+
extractInput: ([params]) => extractOpenAIChatInput(params),
|
|
13640
14621
|
extractOutput: (result) => {
|
|
13641
14622
|
return result?.choices;
|
|
13642
14623
|
},
|
|
@@ -13682,13 +14663,7 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13682
14663
|
traceStreamingChannel(openAIChannels.betaChatCompletionsParse, {
|
|
13683
14664
|
name: "Chat Completion",
|
|
13684
14665
|
type: "llm" /* LLM */,
|
|
13685
|
-
extractInput: ([params]) =>
|
|
13686
|
-
const { messages, ...metadata } = params;
|
|
13687
|
-
return {
|
|
13688
|
-
input: processInputAttachments(messages),
|
|
13689
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13690
|
-
};
|
|
13691
|
-
},
|
|
14666
|
+
extractInput: ([params]) => extractOpenAIChatInput(params),
|
|
13692
14667
|
extractOutput: (result) => {
|
|
13693
14668
|
return result?.choices;
|
|
13694
14669
|
},
|
|
@@ -13710,13 +14685,7 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13710
14685
|
traceSyncStreamChannel(openAIChannels.betaChatCompletionsStream, {
|
|
13711
14686
|
name: "Chat Completion",
|
|
13712
14687
|
type: "llm" /* LLM */,
|
|
13713
|
-
extractInput: ([params]) =>
|
|
13714
|
-
const { messages, ...metadata } = params;
|
|
13715
|
-
return {
|
|
13716
|
-
input: processInputAttachments(messages),
|
|
13717
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13718
|
-
};
|
|
13719
|
-
}
|
|
14688
|
+
extractInput: ([params]) => extractOpenAIChatInput(params)
|
|
13720
14689
|
})
|
|
13721
14690
|
);
|
|
13722
14691
|
this.unsubscribers.push(
|
|
@@ -13746,23 +14715,11 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13746
14715
|
traceStreamingChannel(openAIChannels.responsesCreate, {
|
|
13747
14716
|
name: "openai.responses.create",
|
|
13748
14717
|
type: "llm" /* LLM */,
|
|
13749
|
-
extractInput: ([params]) =>
|
|
13750
|
-
const { input, ...metadata } = params;
|
|
13751
|
-
return {
|
|
13752
|
-
input: processInputAttachments(input),
|
|
13753
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13754
|
-
};
|
|
13755
|
-
},
|
|
14718
|
+
extractInput: ([params]) => extractOpenAIResponsesInput(params),
|
|
13756
14719
|
extractOutput: (result) => {
|
|
13757
14720
|
return processImagesInOutput(result?.output);
|
|
13758
14721
|
},
|
|
13759
|
-
extractMetadata: (result) =>
|
|
13760
|
-
if (!result) {
|
|
13761
|
-
return void 0;
|
|
13762
|
-
}
|
|
13763
|
-
const { output: _output, usage: _usage, ...metadata } = result;
|
|
13764
|
-
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
13765
|
-
},
|
|
14722
|
+
extractMetadata: (result) => extractOpenAIResponsesMetadata(result),
|
|
13766
14723
|
extractMetrics: (result, startTime, endEvent) => {
|
|
13767
14724
|
const metrics = withCachedMetric(
|
|
13768
14725
|
parseMetricsFromUsage(result?.usage),
|
|
@@ -13781,13 +14738,7 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13781
14738
|
traceSyncStreamChannel(openAIChannels.responsesStream, {
|
|
13782
14739
|
name: "openai.responses.create",
|
|
13783
14740
|
type: "llm" /* LLM */,
|
|
13784
|
-
extractInput: ([params]) =>
|
|
13785
|
-
const { input, ...metadata } = params;
|
|
13786
|
-
return {
|
|
13787
|
-
input: processInputAttachments(input),
|
|
13788
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13789
|
-
};
|
|
13790
|
-
},
|
|
14741
|
+
extractInput: ([params]) => extractOpenAIResponsesInput(params),
|
|
13791
14742
|
extractFromEvent: (event) => {
|
|
13792
14743
|
if (event.type !== "response.completed" || !event.response) {
|
|
13793
14744
|
return {};
|
|
@@ -13810,23 +14761,11 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13810
14761
|
traceStreamingChannel(openAIChannels.responsesParse, {
|
|
13811
14762
|
name: "openai.responses.parse",
|
|
13812
14763
|
type: "llm" /* LLM */,
|
|
13813
|
-
extractInput: ([params]) =>
|
|
13814
|
-
const { input, ...metadata } = params;
|
|
13815
|
-
return {
|
|
13816
|
-
input: processInputAttachments(input),
|
|
13817
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13818
|
-
};
|
|
13819
|
-
},
|
|
14764
|
+
extractInput: ([params]) => extractOpenAIResponsesInput(params),
|
|
13820
14765
|
extractOutput: (result) => {
|
|
13821
14766
|
return processImagesInOutput(result?.output);
|
|
13822
14767
|
},
|
|
13823
|
-
extractMetadata: (result) =>
|
|
13824
|
-
if (!result) {
|
|
13825
|
-
return void 0;
|
|
13826
|
-
}
|
|
13827
|
-
const { output: _output, usage: _usage, ...metadata } = result;
|
|
13828
|
-
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
13829
|
-
},
|
|
14768
|
+
extractMetadata: (result) => extractOpenAIResponsesMetadata(result),
|
|
13830
14769
|
extractMetrics: (result, startTime, endEvent) => {
|
|
13831
14770
|
const metrics = withCachedMetric(
|
|
13832
14771
|
parseMetricsFromUsage(result?.usage),
|
|
@@ -13845,23 +14784,11 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
13845
14784
|
traceAsyncChannel(openAIChannels.responsesCompact, {
|
|
13846
14785
|
name: "openai.responses.compact",
|
|
13847
14786
|
type: "llm" /* LLM */,
|
|
13848
|
-
extractInput: ([params]) =>
|
|
13849
|
-
const { input, ...metadata } = params;
|
|
13850
|
-
return {
|
|
13851
|
-
input: processInputAttachments(input),
|
|
13852
|
-
metadata: { ...metadata, provider: "openai" }
|
|
13853
|
-
};
|
|
13854
|
-
},
|
|
14787
|
+
extractInput: ([params]) => extractOpenAIResponsesInput(params),
|
|
13855
14788
|
extractOutput: (result) => {
|
|
13856
14789
|
return processImagesInOutput(result?.output);
|
|
13857
14790
|
},
|
|
13858
|
-
extractMetadata: (result) =>
|
|
13859
|
-
if (!result) {
|
|
13860
|
-
return void 0;
|
|
13861
|
-
}
|
|
13862
|
-
const { output: _output, usage: _usage, ...metadata } = result;
|
|
13863
|
-
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
13864
|
-
},
|
|
14791
|
+
extractMetadata: (result) => extractOpenAIResponsesMetadata(result),
|
|
13865
14792
|
extractMetrics: (result, startTime, endEvent) => {
|
|
13866
14793
|
const metrics = withCachedMetric(
|
|
13867
14794
|
parseMetricsFromUsage(result?.usage),
|
|
@@ -13917,35 +14844,6 @@ function withCachedMetric(metrics, result, endEvent) {
|
|
|
13917
14844
|
cached
|
|
13918
14845
|
};
|
|
13919
14846
|
}
|
|
13920
|
-
function processImagesInOutput(output) {
|
|
13921
|
-
if (Array.isArray(output)) {
|
|
13922
|
-
return output.map(processImagesInOutput);
|
|
13923
|
-
}
|
|
13924
|
-
if (isObject(output)) {
|
|
13925
|
-
if (output.type === "image_generation_call" && output.result && typeof output.result === "string") {
|
|
13926
|
-
const fileExtension = output.output_format || "png";
|
|
13927
|
-
const contentType = `image/${fileExtension}`;
|
|
13928
|
-
const baseFilename = output.revised_prompt && typeof output.revised_prompt === "string" ? output.revised_prompt.slice(0, 50).replace(/[^a-zA-Z0-9]/g, "_") : "generated_image";
|
|
13929
|
-
const filename = `${baseFilename}.${fileExtension}`;
|
|
13930
|
-
const binaryString = atob(output.result);
|
|
13931
|
-
const bytes = new Uint8Array(binaryString.length);
|
|
13932
|
-
for (let i = 0; i < binaryString.length; i++) {
|
|
13933
|
-
bytes[i] = binaryString.charCodeAt(i);
|
|
13934
|
-
}
|
|
13935
|
-
const blob = new Blob([bytes], { type: contentType });
|
|
13936
|
-
const attachment = new Attachment({
|
|
13937
|
-
data: blob,
|
|
13938
|
-
filename,
|
|
13939
|
-
contentType
|
|
13940
|
-
});
|
|
13941
|
-
return {
|
|
13942
|
-
...output,
|
|
13943
|
-
result: attachment
|
|
13944
|
-
};
|
|
13945
|
-
}
|
|
13946
|
-
}
|
|
13947
|
-
return output;
|
|
13948
|
-
}
|
|
13949
14847
|
function mergeLogprobTokens(existing, incoming) {
|
|
13950
14848
|
if (incoming === void 0) {
|
|
13951
14849
|
return existing;
|
|
@@ -13976,13 +14874,33 @@ function aggregateChatLogprobs(existing, incoming) {
|
|
|
13976
14874
|
}
|
|
13977
14875
|
return aggregated;
|
|
13978
14876
|
}
|
|
14877
|
+
function createAggregatedChatChoice(index) {
|
|
14878
|
+
return {
|
|
14879
|
+
index,
|
|
14880
|
+
role: void 0,
|
|
14881
|
+
content: void 0,
|
|
14882
|
+
refusal: void 0,
|
|
14883
|
+
toolCallsByIndex: /* @__PURE__ */ new Map(),
|
|
14884
|
+
logprobs: void 0,
|
|
14885
|
+
finish_reason: void 0
|
|
14886
|
+
};
|
|
14887
|
+
}
|
|
14888
|
+
function toChatChoice(choice) {
|
|
14889
|
+
const toolCalls2 = Array.from(choice.toolCallsByIndex.entries()).sort(([left], [right]) => left - right).map(([, toolCall]) => toolCall);
|
|
14890
|
+
return {
|
|
14891
|
+
index: choice.index,
|
|
14892
|
+
message: {
|
|
14893
|
+
role: choice.role,
|
|
14894
|
+
content: choice.content,
|
|
14895
|
+
...choice.refusal !== void 0 ? { refusal: choice.refusal } : {},
|
|
14896
|
+
tool_calls: toolCalls2.length > 0 ? toolCalls2 : void 0
|
|
14897
|
+
},
|
|
14898
|
+
logprobs: choice.logprobs ?? null,
|
|
14899
|
+
finish_reason: choice.finish_reason
|
|
14900
|
+
};
|
|
14901
|
+
}
|
|
13979
14902
|
function aggregateChatCompletionChunks(chunks, streamResult, endEvent) {
|
|
13980
|
-
|
|
13981
|
-
let content = void 0;
|
|
13982
|
-
let refusal = void 0;
|
|
13983
|
-
let tool_calls = void 0;
|
|
13984
|
-
let logprobs = void 0;
|
|
13985
|
-
let finish_reason = void 0;
|
|
14903
|
+
const choicesByIndex = /* @__PURE__ */ new Map();
|
|
13986
14904
|
let metrics = {};
|
|
13987
14905
|
for (const chunk of chunks) {
|
|
13988
14906
|
if (chunk.usage) {
|
|
@@ -13991,62 +14909,75 @@ function aggregateChatCompletionChunks(chunks, streamResult, endEvent) {
|
|
|
13991
14909
|
...parseMetricsFromUsage(chunk.usage)
|
|
13992
14910
|
};
|
|
13993
14911
|
}
|
|
13994
|
-
const
|
|
13995
|
-
if (!
|
|
14912
|
+
const choices = chunk.choices;
|
|
14913
|
+
if (!choices?.length) {
|
|
13996
14914
|
continue;
|
|
13997
14915
|
}
|
|
13998
|
-
|
|
13999
|
-
|
|
14000
|
-
|
|
14001
|
-
|
|
14002
|
-
|
|
14003
|
-
|
|
14004
|
-
|
|
14005
|
-
|
|
14006
|
-
|
|
14007
|
-
|
|
14008
|
-
|
|
14009
|
-
|
|
14010
|
-
|
|
14011
|
-
|
|
14012
|
-
|
|
14013
|
-
|
|
14014
|
-
|
|
14015
|
-
|
|
14016
|
-
|
|
14017
|
-
|
|
14018
|
-
|
|
14019
|
-
|
|
14020
|
-
|
|
14021
|
-
|
|
14022
|
-
|
|
14023
|
-
|
|
14024
|
-
|
|
14025
|
-
|
|
14026
|
-
|
|
14916
|
+
for (const choice of choices) {
|
|
14917
|
+
const choiceIndex = choice.index;
|
|
14918
|
+
let aggregatedChoice = choicesByIndex.get(choiceIndex);
|
|
14919
|
+
if (!aggregatedChoice) {
|
|
14920
|
+
aggregatedChoice = createAggregatedChatChoice(choiceIndex);
|
|
14921
|
+
choicesByIndex.set(choiceIndex, aggregatedChoice);
|
|
14922
|
+
}
|
|
14923
|
+
if (choice.finish_reason) {
|
|
14924
|
+
aggregatedChoice.finish_reason = choice.finish_reason;
|
|
14925
|
+
}
|
|
14926
|
+
aggregatedChoice.logprobs = aggregateChatLogprobs(
|
|
14927
|
+
aggregatedChoice.logprobs,
|
|
14928
|
+
choice.logprobs
|
|
14929
|
+
);
|
|
14930
|
+
const delta = choice.delta;
|
|
14931
|
+
if (!delta) {
|
|
14932
|
+
continue;
|
|
14933
|
+
}
|
|
14934
|
+
if (delta.finish_reason) {
|
|
14935
|
+
aggregatedChoice.finish_reason = delta.finish_reason;
|
|
14936
|
+
}
|
|
14937
|
+
if (!aggregatedChoice.role && delta.role) {
|
|
14938
|
+
aggregatedChoice.role = delta.role;
|
|
14939
|
+
}
|
|
14940
|
+
if (delta.content) {
|
|
14941
|
+
aggregatedChoice.content = (aggregatedChoice.content || "") + delta.content;
|
|
14942
|
+
}
|
|
14943
|
+
if (delta.refusal) {
|
|
14944
|
+
aggregatedChoice.refusal = (aggregatedChoice.refusal || "") + delta.refusal;
|
|
14945
|
+
}
|
|
14946
|
+
if (delta.tool_calls) {
|
|
14947
|
+
for (const toolDelta of delta.tool_calls) {
|
|
14948
|
+
let aggregatedToolCall = aggregatedChoice.toolCallsByIndex.get(
|
|
14949
|
+
toolDelta.index
|
|
14950
|
+
);
|
|
14951
|
+
if (!aggregatedToolCall) {
|
|
14952
|
+
aggregatedToolCall = {
|
|
14953
|
+
function: { arguments: "" }
|
|
14954
|
+
};
|
|
14955
|
+
aggregatedChoice.toolCallsByIndex.set(
|
|
14956
|
+
toolDelta.index,
|
|
14957
|
+
aggregatedToolCall
|
|
14958
|
+
);
|
|
14027
14959
|
}
|
|
14028
|
-
|
|
14029
|
-
|
|
14030
|
-
|
|
14960
|
+
if (toolDelta.id !== void 0) {
|
|
14961
|
+
aggregatedToolCall.id = toolDelta.id;
|
|
14962
|
+
}
|
|
14963
|
+
if (toolDelta.type !== void 0) {
|
|
14964
|
+
aggregatedToolCall.type = toolDelta.type;
|
|
14965
|
+
}
|
|
14966
|
+
if (toolDelta.function?.name !== void 0) {
|
|
14967
|
+
aggregatedToolCall.function.name = toolDelta.function.name;
|
|
14968
|
+
}
|
|
14969
|
+
if (toolDelta.function?.arguments !== void 0) {
|
|
14970
|
+
aggregatedToolCall.function.arguments += toolDelta.function.arguments;
|
|
14971
|
+
}
|
|
14972
|
+
}
|
|
14031
14973
|
}
|
|
14032
14974
|
}
|
|
14033
14975
|
}
|
|
14034
14976
|
metrics = withCachedMetric(metrics, streamResult, endEvent);
|
|
14977
|
+
const output = Array.from(choicesByIndex.values()).sort((left, right) => left.index - right.index).map(toChatChoice);
|
|
14035
14978
|
return {
|
|
14036
14979
|
metrics,
|
|
14037
|
-
output: [
|
|
14038
|
-
{
|
|
14039
|
-
index: 0,
|
|
14040
|
-
message: {
|
|
14041
|
-
role,
|
|
14042
|
-
content,
|
|
14043
|
-
...refusal !== void 0 ? { refusal } : {},
|
|
14044
|
-
tool_calls
|
|
14045
|
-
},
|
|
14046
|
-
logprobs: logprobs ?? null,
|
|
14047
|
-
finish_reason
|
|
14048
|
-
}
|
|
14049
|
-
]
|
|
14980
|
+
output: output.length > 0 ? output : [toChatChoice(createAggregatedChatChoice(0))]
|
|
14050
14981
|
};
|
|
14051
14982
|
}
|
|
14052
14983
|
function aggregateResponseStreamEvents(chunks, _streamResult, endEvent) {
|
|
@@ -15382,6 +16313,12 @@ function parseMetricsFromUsage2(usage) {
|
|
|
15382
16313
|
}
|
|
15383
16314
|
}
|
|
15384
16315
|
}
|
|
16316
|
+
if (isObject(usage.output_tokens_details)) {
|
|
16317
|
+
const thinkingTokens = usage.output_tokens_details.thinking_tokens;
|
|
16318
|
+
if (typeof thinkingTokens === "number") {
|
|
16319
|
+
metrics.completion_reasoning_tokens = thinkingTokens;
|
|
16320
|
+
}
|
|
16321
|
+
}
|
|
15385
16322
|
if (isObject(usage.server_tool_use)) {
|
|
15386
16323
|
for (const [name, value] of Object.entries(usage.server_tool_use)) {
|
|
15387
16324
|
if (typeof value === "number") {
|
|
@@ -16338,7 +17275,6 @@ function endHarnessTurn(parent) {
|
|
|
16338
17275
|
function braintrustAISDKTelemetry() {
|
|
16339
17276
|
const operations = /* @__PURE__ */ new Map();
|
|
16340
17277
|
const operationKeysByCallId = /* @__PURE__ */ new Map();
|
|
16341
|
-
const workflowOperationKeyStore = isomorph_default.newAsyncLocalStorage();
|
|
16342
17278
|
const modelSpans = /* @__PURE__ */ new Map();
|
|
16343
17279
|
const objectSpans = /* @__PURE__ */ new Map();
|
|
16344
17280
|
const embedSpans = /* @__PURE__ */ new Map();
|
|
@@ -16381,9 +17317,6 @@ function braintrustAISDKTelemetry() {
|
|
|
16381
17317
|
return;
|
|
16382
17318
|
}
|
|
16383
17319
|
operations.delete(operationKey);
|
|
16384
|
-
if (workflowOperationKeyStore.getStore() === operationKey) {
|
|
16385
|
-
workflowOperationKeyStore.enterWith(void 0);
|
|
16386
|
-
}
|
|
16387
17320
|
const keys = operationKeysByCallId.get(state.callId);
|
|
16388
17321
|
if (!keys) {
|
|
16389
17322
|
return;
|
|
@@ -16431,14 +17364,7 @@ function braintrustAISDKTelemetry() {
|
|
|
16431
17364
|
return key;
|
|
16432
17365
|
}
|
|
16433
17366
|
}
|
|
16434
|
-
|
|
16435
|
-
if (workflowOperationKey && keys.includes(workflowOperationKey)) {
|
|
16436
|
-
return workflowOperationKey;
|
|
16437
|
-
}
|
|
16438
|
-
if (callId === "workflow-agent") {
|
|
16439
|
-
return void 0;
|
|
16440
|
-
}
|
|
16441
|
-
return mode === "finish" ? keys[0] : keys[keys.length - 1];
|
|
17367
|
+
return callId === "workflow-agent" || mode === "active" ? keys[keys.length - 1] : keys[0];
|
|
16442
17368
|
};
|
|
16443
17369
|
const operationKeyFromEvent = (event, mode = "active") => {
|
|
16444
17370
|
const explicit = explicitOperationKey(event);
|
|
@@ -16452,17 +17378,13 @@ function braintrustAISDKTelemetry() {
|
|
|
16452
17378
|
if (operationKey) {
|
|
16453
17379
|
return operationKey;
|
|
16454
17380
|
}
|
|
16455
|
-
const
|
|
16456
|
-
if (
|
|
16457
|
-
return
|
|
17381
|
+
const workflowAgentKeys2 = operationKeysByCallId.get("workflow-agent");
|
|
17382
|
+
if (workflowAgentKeys2?.length) {
|
|
17383
|
+
return workflowAgentKeys2[workflowAgentKeys2.length - 1];
|
|
16458
17384
|
}
|
|
16459
17385
|
return callId === "workflow-agent" ? void 0 : callId;
|
|
16460
17386
|
}
|
|
16461
17387
|
}
|
|
16462
|
-
const workflowOperationKey = workflowOperationKeyStore.getStore();
|
|
16463
|
-
if (workflowOperationKey && operations.has(workflowOperationKey)) {
|
|
16464
|
-
return workflowOperationKey;
|
|
16465
|
-
}
|
|
16466
17388
|
const wrapperSpan = currentWorkflowAgentWrapperSpan();
|
|
16467
17389
|
if (wrapperSpan?.spanId) {
|
|
16468
17390
|
for (const [operationKey, state] of operations) {
|
|
@@ -16472,8 +17394,8 @@ function braintrustAISDKTelemetry() {
|
|
|
16472
17394
|
}
|
|
16473
17395
|
}
|
|
16474
17396
|
const workflowAgentKeys = operationKeysByCallId.get("workflow-agent");
|
|
16475
|
-
if (workflowAgentKeys?.length
|
|
16476
|
-
return workflowAgentKeys[
|
|
17397
|
+
if (workflowAgentKeys?.length) {
|
|
17398
|
+
return workflowAgentKeys[workflowAgentKeys.length - 1];
|
|
16477
17399
|
}
|
|
16478
17400
|
if (operations.size === 1) {
|
|
16479
17401
|
return operations.keys().next().value;
|
|
@@ -16676,9 +17598,6 @@ function braintrustAISDKTelemetry() {
|
|
|
16676
17598
|
if (!ownsSpan) {
|
|
16677
17599
|
return;
|
|
16678
17600
|
}
|
|
16679
|
-
if (workflowAgent) {
|
|
16680
|
-
workflowOperationKeyStore.enterWith(operationKey);
|
|
16681
|
-
}
|
|
16682
17601
|
let metadata = metadataFromEvent(event);
|
|
16683
17602
|
const logPayload = { metadata };
|
|
16684
17603
|
const workflowAgentCallInput = workflowAgent ? operationInput(event, operationName) : void 0;
|
|
@@ -17150,6 +18069,10 @@ var aiSDKChannels = defineChannels(
|
|
|
17150
18069
|
channelName: "generateText",
|
|
17151
18070
|
kind: "async"
|
|
17152
18071
|
}),
|
|
18072
|
+
generateImage: channel({
|
|
18073
|
+
channelName: "generateImage",
|
|
18074
|
+
kind: "async"
|
|
18075
|
+
}),
|
|
17153
18076
|
streamText: channel({
|
|
17154
18077
|
channelName: "streamText",
|
|
17155
18078
|
kind: "async"
|
|
@@ -17337,7 +18260,7 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
17337
18260
|
}
|
|
17338
18261
|
subscribeToAISDK() {
|
|
17339
18262
|
const denyOutputPaths = this.config.denyOutputPaths || DEFAULT_DENY_OUTPUT_PATHS;
|
|
17340
|
-
this.unsubscribers.push(
|
|
18263
|
+
this.unsubscribers.push(interceptAISDKV7TelemetryDispatcher());
|
|
17341
18264
|
this.unsubscribers.push(subscribeToHarnessAgentCreateSession());
|
|
17342
18265
|
this.unsubscribers.push(
|
|
17343
18266
|
subscribeToHarnessContinuation(
|
|
@@ -17365,6 +18288,18 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
17365
18288
|
aggregateChunks: aggregateAISDKChunks
|
|
17366
18289
|
})
|
|
17367
18290
|
);
|
|
18291
|
+
this.unsubscribers.push(
|
|
18292
|
+
traceAsyncChannel(aiSDKChannels.generateImage, {
|
|
18293
|
+
name: "generateImage",
|
|
18294
|
+
type: "llm" /* LLM */,
|
|
18295
|
+
extractInput: ([params], event) => prepareAISDKGenerateImageInput(params, event.self),
|
|
18296
|
+
extractOutput: (result, endEvent) => processAISDKGenerateImageOutput(
|
|
18297
|
+
result,
|
|
18298
|
+
resolveDenyOutputPaths(endEvent, denyOutputPaths)
|
|
18299
|
+
),
|
|
18300
|
+
extractMetrics: (result) => extractTokenMetrics(result)
|
|
18301
|
+
})
|
|
18302
|
+
);
|
|
17368
18303
|
this.unsubscribers.push(
|
|
17369
18304
|
traceStreamingChannel(aiSDKChannels.streamText, {
|
|
17370
18305
|
name: "streamText",
|
|
@@ -17854,26 +18789,29 @@ function subscribeToHarnessContinuation(continuationChannel, defaultDenyOutputPa
|
|
|
17854
18789
|
channel2.unsubscribe(handlers);
|
|
17855
18790
|
};
|
|
17856
18791
|
}
|
|
17857
|
-
function
|
|
17858
|
-
const channel2 = aiSDKChannels.v7CreateTelemetryDispatcher.tracingChannel();
|
|
18792
|
+
function interceptAISDKV7TelemetryDispatcher() {
|
|
17859
18793
|
const telemetry = braintrustAISDKTelemetry();
|
|
17860
|
-
|
|
17861
|
-
|
|
17862
|
-
const
|
|
17863
|
-
|
|
17864
|
-
|
|
18794
|
+
return aiSDKChannels.v7CreateTelemetryDispatcher.intercept(
|
|
18795
|
+
(target, thisArg, args) => {
|
|
18796
|
+
const dispatcher = Reflect.apply(target, thisArg, args);
|
|
18797
|
+
const telemetryOptions = args[0]?.telemetry;
|
|
18798
|
+
if (telemetryOptions?.isEnabled !== false) {
|
|
18799
|
+
try {
|
|
18800
|
+
patchAISDKV7TelemetryDispatcher(
|
|
18801
|
+
dispatcher,
|
|
18802
|
+
telemetry,
|
|
18803
|
+
telemetryOptions
|
|
18804
|
+
);
|
|
18805
|
+
} catch (error) {
|
|
18806
|
+
debugLogger.error(
|
|
18807
|
+
"Error instrumenting AI SDK v7 telemetry dispatcher:",
|
|
18808
|
+
error
|
|
18809
|
+
);
|
|
18810
|
+
}
|
|
17865
18811
|
}
|
|
17866
|
-
|
|
17867
|
-
event.result,
|
|
17868
|
-
telemetry,
|
|
17869
|
-
telemetryOptions
|
|
17870
|
-
);
|
|
18812
|
+
return dispatcher;
|
|
17871
18813
|
}
|
|
17872
|
-
|
|
17873
|
-
channel2.subscribe(handlers);
|
|
17874
|
-
return () => {
|
|
17875
|
-
channel2.unsubscribe(handlers);
|
|
17876
|
-
};
|
|
18814
|
+
);
|
|
17877
18815
|
}
|
|
17878
18816
|
function patchAISDKV7TelemetryDispatcher(dispatcher, telemetry, telemetryOptions) {
|
|
17879
18817
|
if (!isObject(dispatcher)) {
|
|
@@ -18198,16 +19136,10 @@ var convertImageToAttachment = (image, explicitMimeType) => {
|
|
|
18198
19136
|
}
|
|
18199
19137
|
}
|
|
18200
19138
|
if (explicitMimeType) {
|
|
18201
|
-
|
|
18202
|
-
|
|
18203
|
-
data: new Blob([image], { type: explicitMimeType }),
|
|
18204
|
-
filename: `image.${getExtensionFromMediaType(explicitMimeType)}`,
|
|
18205
|
-
contentType: explicitMimeType
|
|
18206
|
-
});
|
|
18207
|
-
}
|
|
18208
|
-
if (typeof Buffer !== "undefined" && Buffer.isBuffer(image)) {
|
|
19139
|
+
const blob = convertDataToBlob(image, explicitMimeType);
|
|
19140
|
+
if (blob) {
|
|
18209
19141
|
return new Attachment({
|
|
18210
|
-
data:
|
|
19142
|
+
data: blob,
|
|
18211
19143
|
filename: `image.${getExtensionFromMediaType(explicitMimeType)}`,
|
|
18212
19144
|
contentType: explicitMimeType
|
|
18213
19145
|
});
|
|
@@ -18261,6 +19193,25 @@ var convertDataToAttachment = (data, mimeType, filename) => {
|
|
|
18261
19193
|
function processAISDKCallInput(params) {
|
|
18262
19194
|
return processInputAttachmentsSync(params);
|
|
18263
19195
|
}
|
|
19196
|
+
function processAISDKGenerateImageInput(params) {
|
|
19197
|
+
const prompt = params.prompt;
|
|
19198
|
+
if (!isObject(prompt) || Array.isArray(prompt)) {
|
|
19199
|
+
return processAISDKCallInput(params);
|
|
19200
|
+
}
|
|
19201
|
+
const processedPrompt = { ...prompt };
|
|
19202
|
+
if (Array.isArray(prompt.images)) {
|
|
19203
|
+
processedPrompt.images = prompt.images.map(
|
|
19204
|
+
(image) => convertImageToAttachment(image, "image/png") ?? image
|
|
19205
|
+
);
|
|
19206
|
+
}
|
|
19207
|
+
if (prompt.mask !== void 0) {
|
|
19208
|
+
processedPrompt.mask = convertImageToAttachment(prompt.mask, "image/png") ?? prompt.mask;
|
|
19209
|
+
}
|
|
19210
|
+
return processAISDKCallInput({
|
|
19211
|
+
...params,
|
|
19212
|
+
prompt: processedPrompt
|
|
19213
|
+
});
|
|
19214
|
+
}
|
|
18264
19215
|
function processAISDKWorkflowAgentCallInput(params) {
|
|
18265
19216
|
const processed = processAISDKCallInput(params);
|
|
18266
19217
|
return {
|
|
@@ -18399,6 +19350,12 @@ function prepareAISDKEmbedInput(params, self) {
|
|
|
18399
19350
|
metadata: extractMetadataFromEmbedParams(params, self)
|
|
18400
19351
|
};
|
|
18401
19352
|
}
|
|
19353
|
+
function prepareAISDKGenerateImageInput(params, self) {
|
|
19354
|
+
return {
|
|
19355
|
+
input: processAISDKGenerateImageInput(params).input,
|
|
19356
|
+
metadata: extractMetadataFromCallParams(params, self)
|
|
19357
|
+
};
|
|
19358
|
+
}
|
|
18402
19359
|
function prepareAISDKRerankInput(params, self) {
|
|
18403
19360
|
const { documents, query } = params;
|
|
18404
19361
|
return {
|
|
@@ -19774,6 +20731,57 @@ function processAISDKOutput(output, denyOutputPaths) {
|
|
|
19774
20731
|
}
|
|
19775
20732
|
return normalizeAISDKLoggedOutput(sanitized);
|
|
19776
20733
|
}
|
|
20734
|
+
function processAISDKGenerateImageOutput(output, denyOutputPaths) {
|
|
20735
|
+
if (!output || typeof output !== "object") {
|
|
20736
|
+
return output;
|
|
20737
|
+
}
|
|
20738
|
+
const summarized = {};
|
|
20739
|
+
for (const field of [
|
|
20740
|
+
"usage",
|
|
20741
|
+
"warnings",
|
|
20742
|
+
"providerMetadata",
|
|
20743
|
+
"experimental_providerMetadata",
|
|
20744
|
+
"responses"
|
|
20745
|
+
]) {
|
|
20746
|
+
const value = safeSerializableFieldRead(output, field);
|
|
20747
|
+
if (value !== void 0 && isSerializableOutputValue(value)) {
|
|
20748
|
+
summarized[field] = value;
|
|
20749
|
+
}
|
|
20750
|
+
}
|
|
20751
|
+
const images = safeSerializableFieldRead(output, "images");
|
|
20752
|
+
const image = safeSerializableFieldRead(output, "image");
|
|
20753
|
+
const generatedFiles = Array.isArray(images) && images.length > 0 ? images : image !== void 0 ? [image] : [];
|
|
20754
|
+
const loggedOutput = normalizeAISDKLoggedOutput(
|
|
20755
|
+
omit(summarized, denyOutputPaths)
|
|
20756
|
+
);
|
|
20757
|
+
if (generatedFiles.length > 0) {
|
|
20758
|
+
loggedOutput.images = generatedFiles.map(
|
|
20759
|
+
(file, index) => convertAISDKGeneratedFileToAttachment(file, index)
|
|
20760
|
+
);
|
|
20761
|
+
}
|
|
20762
|
+
return loggedOutput;
|
|
20763
|
+
}
|
|
20764
|
+
function convertAISDKGeneratedFileToAttachment(file, index) {
|
|
20765
|
+
if (!file || typeof file !== "object") {
|
|
20766
|
+
return file;
|
|
20767
|
+
}
|
|
20768
|
+
const generatedFile = file;
|
|
20769
|
+
const generatedMediaType = safeSerializableFieldRead(
|
|
20770
|
+
generatedFile,
|
|
20771
|
+
"mediaType"
|
|
20772
|
+
);
|
|
20773
|
+
const mediaType = typeof generatedMediaType === "string" ? generatedMediaType : "application/octet-stream";
|
|
20774
|
+
const data = safeSerializableFieldRead(generatedFile, "base64") ?? safeSerializableFieldRead(generatedFile, "uint8Array");
|
|
20775
|
+
const blob = convertDataToBlob(data, mediaType);
|
|
20776
|
+
if (blob) {
|
|
20777
|
+
return new Attachment({
|
|
20778
|
+
data: blob,
|
|
20779
|
+
filename: `generated_image_${index}.${getExtensionFromMediaType(mediaType)}`,
|
|
20780
|
+
contentType: mediaType
|
|
20781
|
+
});
|
|
20782
|
+
}
|
|
20783
|
+
return file;
|
|
20784
|
+
}
|
|
19777
20785
|
function processAISDKEmbeddingOutput(output, denyOutputPaths) {
|
|
19778
20786
|
if (!output || typeof output !== "object") {
|
|
19779
20787
|
return output;
|
|
@@ -20274,118 +21282,22 @@ var claudeAgentSDKChannels = defineChannels(
|
|
|
20274
21282
|
var CLAUDE_AGENT_SDK_SKIP_LOCAL_TOOL_HOOKS_OPTION = "__braintrust_skip_local_tool_hooks";
|
|
20275
21283
|
|
|
20276
21284
|
// src/instrumentation/plugins/claude-agent-sdk-local-tool-context.ts
|
|
20277
|
-
var
|
|
20278
|
-
|
|
20279
|
-
)
|
|
20280
|
-
|
|
20281
|
-
const maybeIsoWithAsyncLocalStorage = isomorph_default;
|
|
20282
|
-
if (typeof maybeIsoWithAsyncLocalStorage.newAsyncLocalStorage === "function") {
|
|
20283
|
-
return maybeIsoWithAsyncLocalStorage.newAsyncLocalStorage();
|
|
20284
|
-
}
|
|
20285
|
-
let currentStore;
|
|
20286
|
-
return {
|
|
20287
|
-
enterWith(store) {
|
|
20288
|
-
currentStore = store;
|
|
20289
|
-
},
|
|
20290
|
-
getStore() {
|
|
20291
|
-
return currentStore;
|
|
20292
|
-
},
|
|
20293
|
-
run(store, callback) {
|
|
20294
|
-
const previousStore = currentStore;
|
|
20295
|
-
currentStore = store;
|
|
20296
|
-
try {
|
|
20297
|
-
return callback();
|
|
20298
|
-
} finally {
|
|
20299
|
-
currentStore = previousStore;
|
|
20300
|
-
}
|
|
20301
|
-
}
|
|
20302
|
-
};
|
|
20303
|
-
}
|
|
20304
|
-
var localToolContextStore = createLocalToolContextStore();
|
|
20305
|
-
var fallbackLocalToolParentResolver;
|
|
20306
|
-
function createClaudeLocalToolContext() {
|
|
20307
|
-
return {};
|
|
20308
|
-
}
|
|
20309
|
-
function runWithClaudeLocalToolContext(callback, context) {
|
|
20310
|
-
return localToolContextStore.run(
|
|
20311
|
-
context ?? createClaudeLocalToolContext(),
|
|
20312
|
-
callback
|
|
20313
|
-
);
|
|
21285
|
+
var localToolContextStore = isomorph_default.newAsyncLocalStorage();
|
|
21286
|
+
var localToolParentResolversByToolUseId = /* @__PURE__ */ new Map();
|
|
21287
|
+
function runWithClaudeLocalToolContext(callback, resolver) {
|
|
21288
|
+
return localToolContextStore.run(resolver, callback);
|
|
20314
21289
|
}
|
|
20315
|
-
function
|
|
20316
|
-
|
|
20317
|
-
if (existing) {
|
|
20318
|
-
return existing;
|
|
20319
|
-
}
|
|
20320
|
-
const created = {};
|
|
20321
|
-
localToolContextStore.enterWith(created);
|
|
20322
|
-
return created;
|
|
21290
|
+
function registerClaudeLocalToolParentResolver(toolUseId, resolver) {
|
|
21291
|
+
localToolParentResolversByToolUseId.set(toolUseId, resolver);
|
|
20323
21292
|
}
|
|
20324
|
-
function
|
|
20325
|
-
|
|
20326
|
-
|
|
20327
|
-
|
|
20328
|
-
return;
|
|
21293
|
+
function getClaudeLocalToolParentResolver(toolUseId) {
|
|
21294
|
+
const currentResolver = localToolContextStore.getStore();
|
|
21295
|
+
if (!toolUseId) {
|
|
21296
|
+
return currentResolver;
|
|
20329
21297
|
}
|
|
20330
|
-
|
|
20331
|
-
|
|
20332
|
-
|
|
20333
|
-
return localToolContextStore.getStore()?.resolveLocalToolParent ?? fallbackLocalToolParentResolver;
|
|
20334
|
-
}
|
|
20335
|
-
function isAsyncIterable3(value) {
|
|
20336
|
-
return value !== null && typeof value === "object" && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
20337
|
-
}
|
|
20338
|
-
function bindClaudeLocalToolContextToAsyncIterable(result, localToolContext) {
|
|
20339
|
-
if (!isAsyncIterable3(result) || Object.isFrozen(result) || Object.isSealed(result)) {
|
|
20340
|
-
return result;
|
|
20341
|
-
}
|
|
20342
|
-
const stream = result;
|
|
20343
|
-
const originalAsyncIterator = stream[Symbol.asyncIterator];
|
|
20344
|
-
if (originalAsyncIterator[LOCAL_TOOL_CONTEXT_ASYNC_ITERATOR_PATCHED]) {
|
|
20345
|
-
return result;
|
|
20346
|
-
}
|
|
20347
|
-
const patchedAsyncIterator = function() {
|
|
20348
|
-
return runWithClaudeLocalToolContext(() => {
|
|
20349
|
-
const iterator = Reflect.apply(originalAsyncIterator, this, []);
|
|
20350
|
-
if (!iterator || typeof iterator !== "object") {
|
|
20351
|
-
return iterator;
|
|
20352
|
-
}
|
|
20353
|
-
const patchMethod = (methodName) => {
|
|
20354
|
-
const originalMethod = Reflect.get(iterator, methodName);
|
|
20355
|
-
if (typeof originalMethod !== "function") {
|
|
20356
|
-
return;
|
|
20357
|
-
}
|
|
20358
|
-
Reflect.set(
|
|
20359
|
-
iterator,
|
|
20360
|
-
methodName,
|
|
20361
|
-
(...args) => runWithClaudeLocalToolContext(
|
|
20362
|
-
() => Reflect.apply(
|
|
20363
|
-
originalMethod,
|
|
20364
|
-
iterator,
|
|
20365
|
-
args
|
|
20366
|
-
),
|
|
20367
|
-
localToolContext
|
|
20368
|
-
)
|
|
20369
|
-
);
|
|
20370
|
-
};
|
|
20371
|
-
patchMethod("next");
|
|
20372
|
-
patchMethod("return");
|
|
20373
|
-
patchMethod("throw");
|
|
20374
|
-
return iterator;
|
|
20375
|
-
}, localToolContext);
|
|
20376
|
-
};
|
|
20377
|
-
Object.defineProperty(
|
|
20378
|
-
patchedAsyncIterator,
|
|
20379
|
-
LOCAL_TOOL_CONTEXT_ASYNC_ITERATOR_PATCHED,
|
|
20380
|
-
{
|
|
20381
|
-
configurable: false,
|
|
20382
|
-
enumerable: false,
|
|
20383
|
-
value: true,
|
|
20384
|
-
writable: false
|
|
20385
|
-
}
|
|
20386
|
-
);
|
|
20387
|
-
Reflect.set(stream, Symbol.asyncIterator, patchedAsyncIterator);
|
|
20388
|
-
return result;
|
|
21298
|
+
const registeredResolver = localToolParentResolversByToolUseId.get(toolUseId);
|
|
21299
|
+
localToolParentResolversByToolUseId.delete(toolUseId);
|
|
21300
|
+
return currentResolver ?? registeredResolver;
|
|
20389
21301
|
}
|
|
20390
21302
|
|
|
20391
21303
|
// src/instrumentation/plugins/claude-agent-sdk-local-tool-spans.ts
|
|
@@ -20411,7 +21323,7 @@ function wrapLocalClaudeToolHandler(handler, getMetadata) {
|
|
|
20411
21323
|
const metadata = getMetadata();
|
|
20412
21324
|
const rawToolName = metadata.serverName ? `mcp__${metadata.serverName}__${metadata.toolName}` : metadata.toolName;
|
|
20413
21325
|
const toolUseId = getToolUseIdFromExtra(handlerArgs[1]);
|
|
20414
|
-
const localToolParentResolver = getClaudeLocalToolParentResolver();
|
|
21326
|
+
const localToolParentResolver = getClaudeLocalToolParentResolver(toolUseId);
|
|
20415
21327
|
const spanName = metadata.serverName ? `tool: ${metadata.serverName}/${metadata.toolName}` : `tool: ${metadata.toolName}`;
|
|
20416
21328
|
const runWithResolvedParent = async () => {
|
|
20417
21329
|
const parent = toolUseId && localToolParentResolver ? await localToolParentResolver(toolUseId).catch(() => void 0) : void 0;
|
|
@@ -20938,6 +21850,7 @@ function createToolTracingHooks(resolveParentSpan, taskIdToToolUseId, toolUseToP
|
|
|
20938
21850
|
}
|
|
20939
21851
|
}
|
|
20940
21852
|
if (skipLocalToolHooks && (isLocalToolUse(input.tool_name, mcpServers) || localToolHookNames.has(input.tool_name))) {
|
|
21853
|
+
registerClaudeLocalToolParentResolver(toolUseID, resolveParentSpan);
|
|
20941
21854
|
return {};
|
|
20942
21855
|
}
|
|
20943
21856
|
const parsed = parseToolName(input.tool_name);
|
|
@@ -21648,7 +22561,7 @@ async function finalizeQuerySpan(state) {
|
|
|
21648
22561
|
}
|
|
21649
22562
|
var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
21650
22563
|
onEnable() {
|
|
21651
|
-
this.
|
|
22564
|
+
this.interceptQuery();
|
|
21652
22565
|
}
|
|
21653
22566
|
onDisable() {
|
|
21654
22567
|
for (const unsubscribe of this.unsubscribers) {
|
|
@@ -21656,211 +22569,218 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
21656
22569
|
}
|
|
21657
22570
|
this.unsubscribers = [];
|
|
21658
22571
|
}
|
|
21659
|
-
|
|
21660
|
-
const
|
|
21661
|
-
|
|
21662
|
-
|
|
21663
|
-
|
|
21664
|
-
|
|
21665
|
-
|
|
21666
|
-
|
|
21667
|
-
|
|
21668
|
-
|
|
21669
|
-
|
|
21670
|
-
|
|
21671
|
-
|
|
21672
|
-
|
|
21673
|
-
|
|
21674
|
-
|
|
21675
|
-
|
|
21676
|
-
|
|
21677
|
-
|
|
21678
|
-
|
|
21679
|
-
try {
|
|
21680
|
-
for await (const message of promptStream) {
|
|
21681
|
-
capturedPromptMessages.push(message);
|
|
21682
|
-
yield message;
|
|
21683
|
-
}
|
|
21684
|
-
} finally {
|
|
21685
|
-
resolvePromptDone?.();
|
|
22572
|
+
interceptQuery() {
|
|
22573
|
+
const startQuery = (params) => {
|
|
22574
|
+
const originalPrompt = params.prompt;
|
|
22575
|
+
const options = params.options ?? {};
|
|
22576
|
+
const promptIsAsyncIterable = isAsyncIterable(originalPrompt);
|
|
22577
|
+
let promptStarted = false;
|
|
22578
|
+
let capturedPromptMessages;
|
|
22579
|
+
let resolvePromptDone;
|
|
22580
|
+
const promptDone = new Promise((resolve) => {
|
|
22581
|
+
resolvePromptDone = resolve;
|
|
22582
|
+
});
|
|
22583
|
+
if (promptIsAsyncIterable) {
|
|
22584
|
+
capturedPromptMessages = [];
|
|
22585
|
+
const promptStream = originalPrompt;
|
|
22586
|
+
params.prompt = (async function* () {
|
|
22587
|
+
promptStarted = true;
|
|
22588
|
+
try {
|
|
22589
|
+
for await (const message of promptStream) {
|
|
22590
|
+
capturedPromptMessages.push(message);
|
|
22591
|
+
yield message;
|
|
21686
22592
|
}
|
|
21687
|
-
}
|
|
21688
|
-
|
|
21689
|
-
const span = startSpan(
|
|
21690
|
-
withSpanInstrumentationName(
|
|
21691
|
-
{
|
|
21692
|
-
name: "Claude Agent",
|
|
21693
|
-
spanAttributes: {
|
|
21694
|
-
type: "task" /* TASK */
|
|
21695
|
-
}
|
|
21696
|
-
},
|
|
21697
|
-
INSTRUMENTATION_NAMES.CLAUDE_AGENT_SDK
|
|
21698
|
-
)
|
|
21699
|
-
);
|
|
21700
|
-
const startTime = getCurrentUnixTimestamp();
|
|
21701
|
-
try {
|
|
21702
|
-
span.log({
|
|
21703
|
-
input: typeof originalPrompt === "string" ? originalPrompt : promptIsAsyncIterable ? void 0 : originalPrompt !== void 0 ? String(originalPrompt) : void 0,
|
|
21704
|
-
metadata: filterSerializableOptions(options)
|
|
21705
|
-
});
|
|
21706
|
-
} catch (error) {
|
|
21707
|
-
console.error("Error extracting input for Claude Agent SDK:", error);
|
|
21708
|
-
}
|
|
21709
|
-
const activeToolSpans = /* @__PURE__ */ new Map();
|
|
21710
|
-
const activeLlmSpansByParentToolUse = /* @__PURE__ */ new Map();
|
|
21711
|
-
const conversationHistoryByParentKey = /* @__PURE__ */ new Map();
|
|
21712
|
-
const subAgentSpans = /* @__PURE__ */ new Map();
|
|
21713
|
-
const endedSubAgentSpans = /* @__PURE__ */ new Set();
|
|
21714
|
-
const toolUseToParent = /* @__PURE__ */ new Map();
|
|
21715
|
-
const latestLlmParentBySubAgentToolUse = /* @__PURE__ */ new Map();
|
|
21716
|
-
const latestRootLlmParentRef = {
|
|
21717
|
-
value: void 0
|
|
21718
|
-
};
|
|
21719
|
-
const subAgentDetailsByToolUseId = /* @__PURE__ */ new Map();
|
|
21720
|
-
const taskIdToToolUseId = /* @__PURE__ */ new Map();
|
|
21721
|
-
const promptMessagesByParentKey = /* @__PURE__ */ new Map();
|
|
21722
|
-
const promptSourcePriorityByParentKey = /* @__PURE__ */ new Map();
|
|
21723
|
-
const localToolContext = createClaudeLocalToolContext();
|
|
21724
|
-
const { hasLocalToolHandlers, localToolHookNames } = prepareLocalToolHandlersInMcpServers(options.mcpServers);
|
|
21725
|
-
const skipLocalToolHooks = options[CLAUDE_AGENT_SDK_SKIP_LOCAL_TOOL_HOOKS_OPTION] === true || hasLocalToolHandlers;
|
|
21726
|
-
const resolveToolUseParentSpan = async (toolUseID, context) => {
|
|
21727
|
-
const trackedParentToolUseId = toolUseToParent.get(toolUseID);
|
|
21728
|
-
const parentToolUseId = trackedParentToolUseId ?? (context?.agentId ? taskIdToToolUseId.get(context.agentId) ?? null : null);
|
|
21729
|
-
const parentKey = llmParentKey(parentToolUseId);
|
|
21730
|
-
const activeLlmSpan = activeLlmSpansByParentToolUse.get(parentKey);
|
|
21731
|
-
const latestLlmParent = parentToolUseId ? latestLlmParentBySubAgentToolUse.get(parentToolUseId) : latestRootLlmParentRef.value;
|
|
21732
|
-
if (!activeLlmSpan && !latestLlmParent) {
|
|
21733
|
-
await ensureActiveLlmSpanForParentToolUse(
|
|
21734
|
-
span,
|
|
21735
|
-
activeLlmSpansByParentToolUse,
|
|
21736
|
-
subAgentDetailsByToolUseId,
|
|
21737
|
-
activeToolSpans,
|
|
21738
|
-
subAgentSpans,
|
|
21739
|
-
parentToolUseId,
|
|
21740
|
-
getCurrentUnixTimestamp()
|
|
21741
|
-
);
|
|
21742
|
-
}
|
|
21743
|
-
if (parentToolUseId) {
|
|
21744
|
-
const subAgentSpan = await ensureSubAgentSpan(
|
|
21745
|
-
subAgentDetailsByToolUseId,
|
|
21746
|
-
span,
|
|
21747
|
-
activeToolSpans,
|
|
21748
|
-
subAgentSpans,
|
|
21749
|
-
parentToolUseId
|
|
21750
|
-
);
|
|
21751
|
-
return subAgentSpan.export();
|
|
22593
|
+
} finally {
|
|
22594
|
+
resolvePromptDone?.();
|
|
21752
22595
|
}
|
|
21753
|
-
|
|
21754
|
-
|
|
21755
|
-
|
|
21756
|
-
|
|
21757
|
-
|
|
21758
|
-
|
|
21759
|
-
|
|
21760
|
-
|
|
21761
|
-
|
|
21762
|
-
|
|
21763
|
-
|
|
21764
|
-
|
|
21765
|
-
|
|
21766
|
-
|
|
21767
|
-
|
|
21768
|
-
|
|
21769
|
-
|
|
21770
|
-
|
|
21771
|
-
spans.set(event, {
|
|
21772
|
-
activeLlmSpansByParentToolUse,
|
|
21773
|
-
activePartialMessageIdByParentKey: /* @__PURE__ */ new Map(),
|
|
21774
|
-
activeToolSpans,
|
|
21775
|
-
conversationHistoryByParentKey,
|
|
21776
|
-
capturedPromptMessages,
|
|
21777
|
-
currentMessageId: void 0,
|
|
21778
|
-
currentMessageStartTime: startTime,
|
|
21779
|
-
currentMessages: [],
|
|
21780
|
-
endedSubAgentSpans,
|
|
21781
|
-
finalOutputUsageMessageIds: /* @__PURE__ */ new Set(),
|
|
21782
|
-
finalResults: [],
|
|
21783
|
-
options: optionsWithHooks,
|
|
21784
|
-
originalPrompt,
|
|
21785
|
-
processing: Promise.resolve(),
|
|
21786
|
-
promptDone,
|
|
21787
|
-
promptMessagesByParentKey,
|
|
21788
|
-
promptStarted: () => promptStarted,
|
|
21789
|
-
promptSourcePriorityByParentKey,
|
|
21790
|
-
span,
|
|
21791
|
-
subAgentDetailsByToolUseId,
|
|
21792
|
-
subAgentSpans,
|
|
21793
|
-
taskIdToToolUseId,
|
|
21794
|
-
latestLlmParentBySubAgentToolUse,
|
|
21795
|
-
latestRootLlmParentRef,
|
|
21796
|
-
toolUseToParent,
|
|
21797
|
-
usageByMessageId: /* @__PURE__ */ new Map(),
|
|
21798
|
-
localToolContext
|
|
22596
|
+
})();
|
|
22597
|
+
}
|
|
22598
|
+
const span = startSpan(
|
|
22599
|
+
withSpanInstrumentationName(
|
|
22600
|
+
{
|
|
22601
|
+
name: "Claude Agent",
|
|
22602
|
+
spanAttributes: {
|
|
22603
|
+
type: "task" /* TASK */
|
|
22604
|
+
}
|
|
22605
|
+
},
|
|
22606
|
+
INSTRUMENTATION_NAMES.CLAUDE_AGENT_SDK
|
|
22607
|
+
)
|
|
22608
|
+
);
|
|
22609
|
+
const startTime = getCurrentUnixTimestamp();
|
|
22610
|
+
try {
|
|
22611
|
+
span.log({
|
|
22612
|
+
input: typeof originalPrompt === "string" ? originalPrompt : promptIsAsyncIterable ? void 0 : originalPrompt !== void 0 ? String(originalPrompt) : void 0,
|
|
22613
|
+
metadata: filterSerializableOptions(options)
|
|
21799
22614
|
});
|
|
21800
|
-
}
|
|
21801
|
-
|
|
21802
|
-
|
|
21803
|
-
|
|
21804
|
-
|
|
21805
|
-
|
|
21806
|
-
|
|
21807
|
-
|
|
21808
|
-
|
|
21809
|
-
|
|
21810
|
-
|
|
21811
|
-
|
|
21812
|
-
|
|
21813
|
-
|
|
21814
|
-
|
|
21815
|
-
|
|
21816
|
-
|
|
21817
|
-
|
|
21818
|
-
|
|
21819
|
-
|
|
21820
|
-
|
|
21821
|
-
|
|
21822
|
-
|
|
21823
|
-
|
|
21824
|
-
|
|
21825
|
-
|
|
21826
|
-
|
|
21827
|
-
|
|
21828
|
-
|
|
21829
|
-
|
|
21830
|
-
|
|
21831
|
-
|
|
21832
|
-
|
|
21833
|
-
|
|
21834
|
-
|
|
21835
|
-
})
|
|
21836
|
-
});
|
|
21837
|
-
return;
|
|
21838
|
-
}
|
|
21839
|
-
try {
|
|
21840
|
-
state.span.log({ output: eventResult });
|
|
21841
|
-
} catch (error) {
|
|
21842
|
-
console.error("Error extracting output for Claude Agent SDK:", error);
|
|
21843
|
-
} finally {
|
|
21844
|
-
state.span.end();
|
|
21845
|
-
spans.delete(event);
|
|
22615
|
+
} catch (error) {
|
|
22616
|
+
console.error("Error extracting input for Claude Agent SDK:", error);
|
|
22617
|
+
}
|
|
22618
|
+
const activeToolSpans = /* @__PURE__ */ new Map();
|
|
22619
|
+
const activeLlmSpansByParentToolUse = /* @__PURE__ */ new Map();
|
|
22620
|
+
const conversationHistoryByParentKey = /* @__PURE__ */ new Map();
|
|
22621
|
+
const subAgentSpans = /* @__PURE__ */ new Map();
|
|
22622
|
+
const endedSubAgentSpans = /* @__PURE__ */ new Set();
|
|
22623
|
+
const toolUseToParent = /* @__PURE__ */ new Map();
|
|
22624
|
+
const latestLlmParentBySubAgentToolUse = /* @__PURE__ */ new Map();
|
|
22625
|
+
const latestRootLlmParentRef = {
|
|
22626
|
+
value: void 0
|
|
22627
|
+
};
|
|
22628
|
+
const subAgentDetailsByToolUseId = /* @__PURE__ */ new Map();
|
|
22629
|
+
const taskIdToToolUseId = /* @__PURE__ */ new Map();
|
|
22630
|
+
const promptMessagesByParentKey = /* @__PURE__ */ new Map();
|
|
22631
|
+
const promptSourcePriorityByParentKey = /* @__PURE__ */ new Map();
|
|
22632
|
+
const { hasLocalToolHandlers, localToolHookNames } = prepareLocalToolHandlersInMcpServers(options.mcpServers);
|
|
22633
|
+
const skipLocalToolHooks = options[CLAUDE_AGENT_SDK_SKIP_LOCAL_TOOL_HOOKS_OPTION] === true || hasLocalToolHandlers;
|
|
22634
|
+
const resolveToolUseParentSpan = async (toolUseID, context) => {
|
|
22635
|
+
const trackedParentToolUseId = toolUseToParent.get(toolUseID);
|
|
22636
|
+
const parentToolUseId = trackedParentToolUseId ?? (context?.agentId ? taskIdToToolUseId.get(context.agentId) ?? null : null);
|
|
22637
|
+
const parentKey = llmParentKey(parentToolUseId);
|
|
22638
|
+
const activeLlmSpan = activeLlmSpansByParentToolUse.get(parentKey);
|
|
22639
|
+
const latestLlmParent = parentToolUseId ? latestLlmParentBySubAgentToolUse.get(parentToolUseId) : latestRootLlmParentRef.value;
|
|
22640
|
+
if (!activeLlmSpan && !latestLlmParent) {
|
|
22641
|
+
await ensureActiveLlmSpanForParentToolUse(
|
|
22642
|
+
span,
|
|
22643
|
+
activeLlmSpansByParentToolUse,
|
|
22644
|
+
subAgentDetailsByToolUseId,
|
|
22645
|
+
activeToolSpans,
|
|
22646
|
+
subAgentSpans,
|
|
22647
|
+
parentToolUseId,
|
|
22648
|
+
getCurrentUnixTimestamp()
|
|
22649
|
+
);
|
|
21846
22650
|
}
|
|
21847
|
-
|
|
21848
|
-
|
|
21849
|
-
|
|
21850
|
-
|
|
21851
|
-
|
|
22651
|
+
if (parentToolUseId) {
|
|
22652
|
+
const subAgentSpan = await ensureSubAgentSpan(
|
|
22653
|
+
subAgentDetailsByToolUseId,
|
|
22654
|
+
span,
|
|
22655
|
+
activeToolSpans,
|
|
22656
|
+
subAgentSpans,
|
|
22657
|
+
parentToolUseId
|
|
22658
|
+
);
|
|
22659
|
+
return subAgentSpan.export();
|
|
21852
22660
|
}
|
|
21853
|
-
|
|
21854
|
-
|
|
22661
|
+
return span.export();
|
|
22662
|
+
};
|
|
22663
|
+
const optionsWithHooks = injectTracingHooks(
|
|
22664
|
+
options,
|
|
22665
|
+
resolveToolUseParentSpan,
|
|
22666
|
+
taskIdToToolUseId,
|
|
22667
|
+
toolUseToParent,
|
|
22668
|
+
activeToolSpans,
|
|
22669
|
+
localToolHookNames,
|
|
22670
|
+
skipLocalToolHooks,
|
|
22671
|
+
subAgentDetailsByToolUseId,
|
|
22672
|
+
subAgentSpans,
|
|
22673
|
+
endedSubAgentSpans
|
|
22674
|
+
);
|
|
22675
|
+
params.options = optionsWithHooks;
|
|
22676
|
+
return {
|
|
22677
|
+
activeLlmSpansByParentToolUse,
|
|
22678
|
+
activePartialMessageIdByParentKey: /* @__PURE__ */ new Map(),
|
|
22679
|
+
activeToolSpans,
|
|
22680
|
+
conversationHistoryByParentKey,
|
|
22681
|
+
capturedPromptMessages,
|
|
22682
|
+
currentMessageId: void 0,
|
|
22683
|
+
currentMessageStartTime: startTime,
|
|
22684
|
+
currentMessages: [],
|
|
22685
|
+
endedSubAgentSpans,
|
|
22686
|
+
finalOutputUsageMessageIds: /* @__PURE__ */ new Set(),
|
|
22687
|
+
finalResults: [],
|
|
22688
|
+
options: optionsWithHooks,
|
|
22689
|
+
originalPrompt,
|
|
22690
|
+
processing: Promise.resolve(),
|
|
22691
|
+
promptDone,
|
|
22692
|
+
promptMessagesByParentKey,
|
|
22693
|
+
promptStarted: () => promptStarted,
|
|
22694
|
+
promptSourcePriorityByParentKey,
|
|
22695
|
+
span,
|
|
22696
|
+
subAgentDetailsByToolUseId,
|
|
22697
|
+
subAgentSpans,
|
|
22698
|
+
taskIdToToolUseId,
|
|
22699
|
+
latestLlmParentBySubAgentToolUse,
|
|
22700
|
+
latestRootLlmParentRef,
|
|
22701
|
+
toolUseToParent,
|
|
22702
|
+
usageByMessageId: /* @__PURE__ */ new Map(),
|
|
22703
|
+
localToolParentResolver: resolveToolUseParentSpan
|
|
22704
|
+
};
|
|
22705
|
+
};
|
|
22706
|
+
const finishQuery = (state, result) => {
|
|
22707
|
+
if (isAsyncIterable(result)) {
|
|
22708
|
+
patchStreamIfNeeded(result, {
|
|
22709
|
+
aroundNext: (callback) => runWithClaudeLocalToolContext(
|
|
22710
|
+
callback,
|
|
22711
|
+
state.localToolParentResolver
|
|
22712
|
+
),
|
|
22713
|
+
onChunk: (message) => {
|
|
22714
|
+
maybeTrackToolUseContext(state, message);
|
|
22715
|
+
state.processing = state.processing.then(() => handleStreamMessage(state, message)).catch((error) => {
|
|
22716
|
+
console.error(
|
|
22717
|
+
"Error processing Claude Agent SDK stream chunk:",
|
|
22718
|
+
error
|
|
22719
|
+
);
|
|
22720
|
+
});
|
|
22721
|
+
},
|
|
22722
|
+
onComplete: () => state.processing.then(() => finalizeQuerySpan(state)),
|
|
22723
|
+
onError: (error) => state.processing.then(() => {
|
|
22724
|
+
state.span.log({ error: error.message });
|
|
22725
|
+
}).then(() => finalizeQuerySpan(state))
|
|
21855
22726
|
});
|
|
22727
|
+
return;
|
|
22728
|
+
}
|
|
22729
|
+
try {
|
|
22730
|
+
state.span.log({ output: result });
|
|
22731
|
+
} catch (error) {
|
|
22732
|
+
console.error("Error extracting output for Claude Agent SDK:", error);
|
|
22733
|
+
} finally {
|
|
21856
22734
|
state.span.end();
|
|
21857
|
-
spans.delete(event);
|
|
21858
22735
|
}
|
|
21859
22736
|
};
|
|
21860
|
-
|
|
21861
|
-
|
|
21862
|
-
|
|
21863
|
-
|
|
22737
|
+
this.unsubscribers.push(
|
|
22738
|
+
claudeAgentSDKChannels.query.intercept((target, thisArg, args) => {
|
|
22739
|
+
let state;
|
|
22740
|
+
try {
|
|
22741
|
+
args[0] ??= {};
|
|
22742
|
+
state = startQuery(args[0]);
|
|
22743
|
+
} catch (error) {
|
|
22744
|
+
debugLogger.error(
|
|
22745
|
+
"Error starting Claude Agent SDK instrumentation:",
|
|
22746
|
+
error
|
|
22747
|
+
);
|
|
22748
|
+
}
|
|
22749
|
+
const invokeTarget = () => Reflect.apply(target, thisArg, args);
|
|
22750
|
+
try {
|
|
22751
|
+
const result = state ? runWithClaudeLocalToolContext(
|
|
22752
|
+
invokeTarget,
|
|
22753
|
+
state.localToolParentResolver
|
|
22754
|
+
) : invokeTarget();
|
|
22755
|
+
if (state) {
|
|
22756
|
+
try {
|
|
22757
|
+
finishQuery(state, result);
|
|
22758
|
+
} catch (error) {
|
|
22759
|
+
debugLogger.error(
|
|
22760
|
+
"Error finalizing Claude Agent SDK instrumentation:",
|
|
22761
|
+
error
|
|
22762
|
+
);
|
|
22763
|
+
}
|
|
22764
|
+
}
|
|
22765
|
+
return result;
|
|
22766
|
+
} catch (error) {
|
|
22767
|
+
if (state) {
|
|
22768
|
+
try {
|
|
22769
|
+
state.span.log({
|
|
22770
|
+
error: error instanceof Error ? error.message : String(error)
|
|
22771
|
+
});
|
|
22772
|
+
state.span.end();
|
|
22773
|
+
} catch (instrumentationError) {
|
|
22774
|
+
debugLogger.error(
|
|
22775
|
+
"Error handling Claude Agent SDK instrumentation failure:",
|
|
22776
|
+
instrumentationError
|
|
22777
|
+
);
|
|
22778
|
+
}
|
|
22779
|
+
}
|
|
22780
|
+
throw error;
|
|
22781
|
+
}
|
|
22782
|
+
})
|
|
22783
|
+
);
|
|
21864
22784
|
}
|
|
21865
22785
|
};
|
|
21866
22786
|
|
|
@@ -25974,7 +26894,7 @@ function patchOpenRouterCallModelResult(args) {
|
|
|
25974
26894
|
span,
|
|
25975
26895
|
() => originalMethod.apply(resultLike, args2)
|
|
25976
26896
|
);
|
|
25977
|
-
if (!
|
|
26897
|
+
if (!isAsyncIterable3(stream)) {
|
|
25978
26898
|
return stream;
|
|
25979
26899
|
}
|
|
25980
26900
|
return wrapAsyncIterableWithSpan({
|
|
@@ -26169,7 +27089,7 @@ function wrapAsyncIterableWithSpan(args) {
|
|
|
26169
27089
|
}
|
|
26170
27090
|
};
|
|
26171
27091
|
}
|
|
26172
|
-
function
|
|
27092
|
+
function isAsyncIterable3(value) {
|
|
26173
27093
|
return !!value && (typeof value === "object" || typeof value === "function") && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
26174
27094
|
}
|
|
26175
27095
|
function normalizeError(error) {
|
|
@@ -27047,7 +27967,7 @@ function patchOpenRouterCallModelResult2(args) {
|
|
|
27047
27967
|
span,
|
|
27048
27968
|
() => originalMethod.apply(resultLike, args2)
|
|
27049
27969
|
);
|
|
27050
|
-
if (!
|
|
27970
|
+
if (!isAsyncIterable4(stream)) {
|
|
27051
27971
|
return stream;
|
|
27052
27972
|
}
|
|
27053
27973
|
return wrapAsyncIterableWithSpan2({
|
|
@@ -27242,7 +28162,7 @@ function wrapAsyncIterableWithSpan2(args) {
|
|
|
27242
28162
|
}
|
|
27243
28163
|
};
|
|
27244
28164
|
}
|
|
27245
|
-
function
|
|
28165
|
+
function isAsyncIterable4(value) {
|
|
27246
28166
|
return !!value && (typeof value === "object" || typeof value === "function") && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
27247
28167
|
}
|
|
27248
28168
|
function normalizeError2(error) {
|
|
@@ -33234,12 +34154,14 @@ function getMetricsFromResponse(response) {
|
|
|
33234
34154
|
continue;
|
|
33235
34155
|
}
|
|
33236
34156
|
const inputTokenDetails = usageMetadata.input_token_details;
|
|
34157
|
+
const outputTokenDetails = usageMetadata.output_token_details;
|
|
33237
34158
|
return normalizeTokenMetrics({
|
|
33238
34159
|
total_tokens: usageMetadata.total_tokens,
|
|
33239
34160
|
prompt_tokens: usageMetadata.input_tokens,
|
|
33240
34161
|
completion_tokens: usageMetadata.output_tokens,
|
|
33241
34162
|
prompt_cache_creation_tokens: isRecord(inputTokenDetails) ? inputTokenDetails.cache_creation : void 0,
|
|
33242
|
-
prompt_cached_tokens: isRecord(inputTokenDetails) ? inputTokenDetails.cache_read : void 0
|
|
34163
|
+
prompt_cached_tokens: isRecord(inputTokenDetails) ? inputTokenDetails.cache_read : void 0,
|
|
34164
|
+
completion_reasoning_tokens: isRecord(outputTokenDetails) ? outputTokenDetails.reasoning : void 0
|
|
33243
34165
|
});
|
|
33244
34166
|
}
|
|
33245
34167
|
const llmOutput = response.llmOutput || {};
|
|
@@ -33826,6 +34748,9 @@ var piCodingAgentChannels = defineChannels(
|
|
|
33826
34748
|
// src/instrumentation/plugins/pi-coding-agent-plugin.ts
|
|
33827
34749
|
var piAgentPatchStates = /* @__PURE__ */ new WeakMap();
|
|
33828
34750
|
var piAgentEventSubscriptions = /* @__PURE__ */ new WeakSet();
|
|
34751
|
+
var PI_TOOL_EXECUTE_WRAPPED = /* @__PURE__ */ Symbol.for(
|
|
34752
|
+
"braintrust.pi_coding_agent.tool_execute_wrapped"
|
|
34753
|
+
);
|
|
33829
34754
|
var piPromptContextStore;
|
|
33830
34755
|
var PiCodingAgentPlugin = class extends BasePlugin {
|
|
33831
34756
|
activePromptStates = /* @__PURE__ */ new Set();
|
|
@@ -33906,6 +34831,7 @@ function startPiPromptRun(event, onFinalize) {
|
|
|
33906
34831
|
return void 0;
|
|
33907
34832
|
}
|
|
33908
34833
|
installPiAgentInstrumentation(agent);
|
|
34834
|
+
wrapPiToolExecutors(agent.state?.tools);
|
|
33909
34835
|
const metadata = {
|
|
33910
34836
|
...extractSessionMetadata(session),
|
|
33911
34837
|
...extractPromptOptionsMetadata(event.arguments[1]),
|
|
@@ -33950,7 +34876,7 @@ function extractSession(event) {
|
|
|
33950
34876
|
return isObject(candidate) && typeof candidate.prompt === "function" ? candidate : void 0;
|
|
33951
34877
|
}
|
|
33952
34878
|
function isPiAgent(value) {
|
|
33953
|
-
return isObject(value) && typeof value.streamFn === "function" && typeof value.subscribe === "function";
|
|
34879
|
+
return isObject(value) && (typeof value.streamFunction === "function" || typeof value.streamFn === "function") && typeof value.subscribe === "function";
|
|
33954
34880
|
}
|
|
33955
34881
|
function promptContextStore() {
|
|
33956
34882
|
piPromptContextStore ??= isomorph_default.newAsyncLocalStorage();
|
|
@@ -33960,17 +34886,21 @@ function currentPiPromptState() {
|
|
|
33960
34886
|
return promptContextStore().getStore();
|
|
33961
34887
|
}
|
|
33962
34888
|
function installPiAgentInstrumentation(agent) {
|
|
34889
|
+
const property = typeof agent.streamFunction === "function" ? "streamFunction" : "streamFn";
|
|
34890
|
+
const streamFunction = agent[property];
|
|
33963
34891
|
const existing = piAgentPatchStates.get(agent);
|
|
33964
|
-
if (!existing ||
|
|
34892
|
+
if (streamFunction && (!existing || existing.property !== property || streamFunction !== existing.wrappedStreamFunction)) {
|
|
33965
34893
|
const patchState = {
|
|
33966
|
-
|
|
33967
|
-
|
|
34894
|
+
originalStreamFunction: streamFunction,
|
|
34895
|
+
property,
|
|
34896
|
+
wrappedStreamFunction: streamFunction
|
|
33968
34897
|
};
|
|
33969
|
-
patchState.
|
|
34898
|
+
patchState.wrappedStreamFunction = makeInstrumentedStreamFunction(
|
|
33970
34899
|
agent,
|
|
33971
|
-
patchState.
|
|
34900
|
+
patchState.originalStreamFunction,
|
|
34901
|
+
property
|
|
33972
34902
|
);
|
|
33973
|
-
agent
|
|
34903
|
+
agent[property] = patchState.wrappedStreamFunction;
|
|
33974
34904
|
piAgentPatchStates.set(agent, patchState);
|
|
33975
34905
|
}
|
|
33976
34906
|
if (piAgentEventSubscriptions.has(agent)) {
|
|
@@ -33995,14 +34925,21 @@ function installPiAgentInstrumentation(agent) {
|
|
|
33995
34925
|
logInstrumentationError4("Pi Coding Agent event subscription", error);
|
|
33996
34926
|
}
|
|
33997
34927
|
}
|
|
33998
|
-
function
|
|
33999
|
-
return async function
|
|
34000
|
-
const invokeOriginal = () => Reflect.apply(
|
|
34928
|
+
function makeInstrumentedStreamFunction(agent, originalStreamFunction, property) {
|
|
34929
|
+
return async function instrumentedPiStreamFunction(model, context, options) {
|
|
34930
|
+
const invokeOriginal = () => Reflect.apply(originalStreamFunction, this, [model, context, options]);
|
|
34001
34931
|
const state = currentPiPromptState();
|
|
34002
34932
|
if (!state || state.agent !== agent || state.finalized) {
|
|
34003
34933
|
return invokeOriginal();
|
|
34004
34934
|
}
|
|
34005
|
-
|
|
34935
|
+
wrapPiToolExecutors(context.tools);
|
|
34936
|
+
const llmState = await startPiLlmSpan(
|
|
34937
|
+
state,
|
|
34938
|
+
model,
|
|
34939
|
+
context,
|
|
34940
|
+
property,
|
|
34941
|
+
options
|
|
34942
|
+
);
|
|
34006
34943
|
try {
|
|
34007
34944
|
const stream = await runWithAutoInstrumentationSuppressed(invokeOriginal);
|
|
34008
34945
|
return patchAssistantMessageStream(stream, state, llmState);
|
|
@@ -34012,12 +34949,39 @@ function makeInstrumentedStreamFn(agent, originalStreamFn) {
|
|
|
34012
34949
|
}
|
|
34013
34950
|
};
|
|
34014
34951
|
}
|
|
34015
|
-
|
|
34952
|
+
function wrapPiToolExecutors(tools) {
|
|
34953
|
+
if (!tools) {
|
|
34954
|
+
return;
|
|
34955
|
+
}
|
|
34956
|
+
for (const tool of tools) {
|
|
34957
|
+
try {
|
|
34958
|
+
const execute = tool.execute;
|
|
34959
|
+
if (typeof execute !== "function" || execute[PI_TOOL_EXECUTE_WRAPPED]) {
|
|
34960
|
+
continue;
|
|
34961
|
+
}
|
|
34962
|
+
const wrappedExecute = function(...args) {
|
|
34963
|
+
return runWithAutoInstrumentationAllowed(
|
|
34964
|
+
() => Reflect.apply(execute, this, args)
|
|
34965
|
+
);
|
|
34966
|
+
};
|
|
34967
|
+
Object.defineProperty(wrappedExecute, PI_TOOL_EXECUTE_WRAPPED, {
|
|
34968
|
+
configurable: false,
|
|
34969
|
+
enumerable: false,
|
|
34970
|
+
value: true,
|
|
34971
|
+
writable: false
|
|
34972
|
+
});
|
|
34973
|
+
tool.execute = wrappedExecute;
|
|
34974
|
+
} catch (error) {
|
|
34975
|
+
logInstrumentationError4("Pi Coding Agent tool wrapping", error);
|
|
34976
|
+
}
|
|
34977
|
+
}
|
|
34978
|
+
}
|
|
34979
|
+
async function startPiLlmSpan(state, model, context, property, options) {
|
|
34016
34980
|
const metadata = {
|
|
34017
34981
|
...extractModelMetadata2(model),
|
|
34018
34982
|
...extractStreamOptionsMetadata(options),
|
|
34019
34983
|
...extractToolMetadata(context.tools),
|
|
34020
|
-
"pi_coding_agent.operation":
|
|
34984
|
+
"pi_coding_agent.operation": `agent.${property}`
|
|
34021
34985
|
};
|
|
34022
34986
|
const span = startSpan(
|
|
34023
34987
|
withSpanInstrumentationName(
|
|
@@ -34183,35 +35147,26 @@ async function startPiToolSpan(state, event) {
|
|
|
34183
35147
|
if (!event.toolCallId || state.activeToolSpans.has(event.toolCallId)) {
|
|
34184
35148
|
return;
|
|
34185
35149
|
}
|
|
34186
|
-
const restoreAutoInstrumentation = enterAutoInstrumentationAllowed();
|
|
34187
35150
|
const metadata = {
|
|
34188
35151
|
"gen_ai.tool.call.id": event.toolCallId,
|
|
34189
35152
|
"gen_ai.tool.name": event.toolName,
|
|
34190
35153
|
"pi_coding_agent.tool.name": event.toolName
|
|
34191
35154
|
};
|
|
34192
|
-
|
|
34193
|
-
|
|
34194
|
-
|
|
34195
|
-
{
|
|
34196
|
-
|
|
34197
|
-
|
|
34198
|
-
metadata
|
|
34199
|
-
},
|
|
34200
|
-
name: event.toolName || "tool",
|
|
34201
|
-
parent: await state.span.export(),
|
|
34202
|
-
spanAttributes: { type: "tool" /* TOOL */ }
|
|
35155
|
+
const span = startSpan(
|
|
35156
|
+
withSpanInstrumentationName(
|
|
35157
|
+
{
|
|
35158
|
+
event: {
|
|
35159
|
+
input: event.args,
|
|
35160
|
+
metadata
|
|
34203
35161
|
},
|
|
34204
|
-
|
|
34205
|
-
|
|
34206
|
-
|
|
34207
|
-
|
|
34208
|
-
|
|
34209
|
-
|
|
34210
|
-
|
|
34211
|
-
|
|
34212
|
-
restoreAutoInstrumentation();
|
|
34213
|
-
throw error;
|
|
34214
|
-
}
|
|
35162
|
+
name: event.toolName || "tool",
|
|
35163
|
+
parent: await state.span.export(),
|
|
35164
|
+
spanAttributes: { type: "tool" /* TOOL */ }
|
|
35165
|
+
},
|
|
35166
|
+
INSTRUMENTATION_NAMES.PI_CODING_AGENT
|
|
35167
|
+
)
|
|
35168
|
+
);
|
|
35169
|
+
state.activeToolSpans.set(event.toolCallId, { span });
|
|
34215
35170
|
}
|
|
34216
35171
|
function finishPiToolSpan(state, event) {
|
|
34217
35172
|
const toolState = state.activeToolSpans.get(event.toolCallId);
|
|
@@ -34232,11 +35187,7 @@ function finishPiToolSpan(state, event) {
|
|
|
34232
35187
|
output: event.result
|
|
34233
35188
|
});
|
|
34234
35189
|
} finally {
|
|
34235
|
-
|
|
34236
|
-
toolState.span.end();
|
|
34237
|
-
} finally {
|
|
34238
|
-
toolState.restoreAutoInstrumentation?.();
|
|
34239
|
-
}
|
|
35190
|
+
toolState.span.end();
|
|
34240
35191
|
}
|
|
34241
35192
|
}
|
|
34242
35193
|
function finishPiPromptRun(state, error) {
|
|
@@ -34286,10 +35237,10 @@ function finishPiLlmSpan(promptState, llmState, message, error) {
|
|
|
34286
35237
|
...cleanMetrics5(llmState.metrics),
|
|
34287
35238
|
...buildDurationMetrics3(llmState.startTime)
|
|
34288
35239
|
};
|
|
34289
|
-
const
|
|
34290
|
-
if (Object.keys(
|
|
35240
|
+
const usageMetrics2 = extractUsageMetrics2(message?.usage);
|
|
35241
|
+
if (Object.keys(usageMetrics2).length > 0) {
|
|
34291
35242
|
promptState.collectedLlmUsageMetrics = true;
|
|
34292
|
-
addMetrics(promptState.metrics,
|
|
35243
|
+
addMetrics(promptState.metrics, usageMetrics2);
|
|
34293
35244
|
}
|
|
34294
35245
|
try {
|
|
34295
35246
|
safeLog4(llmState.span, {
|
|
@@ -34307,14 +35258,10 @@ function finishPiLlmSpan(promptState, llmState, message, error) {
|
|
|
34307
35258
|
}
|
|
34308
35259
|
function finishOpenToolSpans(state, error) {
|
|
34309
35260
|
for (const [, toolState] of state.activeToolSpans) {
|
|
34310
|
-
|
|
34311
|
-
|
|
34312
|
-
|
|
34313
|
-
|
|
34314
|
-
toolState.span.end();
|
|
34315
|
-
} finally {
|
|
34316
|
-
toolState.restoreAutoInstrumentation?.();
|
|
34317
|
-
}
|
|
35261
|
+
safeLog4(toolState.span, {
|
|
35262
|
+
error: error ? toLoggedError(error) : "Pi tool did not complete"
|
|
35263
|
+
});
|
|
35264
|
+
toolState.span.end();
|
|
34318
35265
|
}
|
|
34319
35266
|
state.activeToolSpans.clear();
|
|
34320
35267
|
}
|
|
@@ -34633,12 +35580,12 @@ var MAX_STRANDS_STRING_ATTACHMENT_CACHE_ENTRIES = 32;
|
|
|
34633
35580
|
var StrandsAgentSDKPlugin = class extends BasePlugin {
|
|
34634
35581
|
activeChildParents = /* @__PURE__ */ new WeakMap();
|
|
34635
35582
|
onEnable() {
|
|
34636
|
-
this.
|
|
34637
|
-
this.
|
|
35583
|
+
this.interceptAgentStream();
|
|
35584
|
+
this.interceptMultiAgentStream(
|
|
34638
35585
|
strandsAgentSDKChannels.graphStream,
|
|
34639
35586
|
"Graph.stream"
|
|
34640
35587
|
);
|
|
34641
|
-
this.
|
|
35588
|
+
this.interceptMultiAgentStream(
|
|
34642
35589
|
strandsAgentSDKChannels.swarmStream,
|
|
34643
35590
|
"Swarm.stream"
|
|
34644
35591
|
);
|
|
@@ -34649,122 +35596,92 @@ var StrandsAgentSDKPlugin = class extends BasePlugin {
|
|
|
34649
35596
|
}
|
|
34650
35597
|
this.unsubscribers = [];
|
|
34651
35598
|
}
|
|
34652
|
-
|
|
34653
|
-
|
|
34654
|
-
|
|
34655
|
-
|
|
34656
|
-
|
|
34657
|
-
|
|
34658
|
-
|
|
34659
|
-
|
|
34660
|
-
|
|
34661
|
-
|
|
34662
|
-
|
|
34663
|
-
|
|
34664
|
-
|
|
34665
|
-
|
|
34666
|
-
|
|
34667
|
-
|
|
34668
|
-
const result = event.result;
|
|
34669
|
-
if (isAsyncIterable(result)) {
|
|
34670
|
-
patchStreamIfNeeded(result, {
|
|
34671
|
-
aroundNext: (callback) => runWithAutoInstrumentationSuppressed(callback),
|
|
34672
|
-
onChunk: (chunk) => handleAgentStreamEvent(state, chunk),
|
|
34673
|
-
onComplete: () => {
|
|
34674
|
-
finalizeAgentStream(state);
|
|
34675
|
-
states.delete(event);
|
|
34676
|
-
},
|
|
34677
|
-
onError: (error) => {
|
|
34678
|
-
finalizeAgentStream(state, error);
|
|
34679
|
-
states.delete(event);
|
|
34680
|
-
}
|
|
34681
|
-
});
|
|
34682
|
-
return;
|
|
34683
|
-
}
|
|
34684
|
-
finalizeAgentStream(state, void 0, result);
|
|
34685
|
-
states.delete(event);
|
|
34686
|
-
},
|
|
34687
|
-
error: (event) => {
|
|
34688
|
-
const state = states.get(event);
|
|
34689
|
-
if (!state || !event.error) {
|
|
34690
|
-
return;
|
|
34691
|
-
}
|
|
34692
|
-
finalizeAgentStream(state, event.error);
|
|
34693
|
-
states.delete(event);
|
|
34694
|
-
}
|
|
34695
|
-
};
|
|
34696
|
-
channel2.subscribe(handlers);
|
|
34697
|
-
this.unsubscribers.push(() => {
|
|
34698
|
-
unbindAutoInstrumentationSuppression?.();
|
|
34699
|
-
channel2.unsubscribe(handlers);
|
|
34700
|
-
});
|
|
35599
|
+
interceptAgentStream() {
|
|
35600
|
+
this.unsubscribers.push(
|
|
35601
|
+
strandsAgentSDKChannels.agentStream.intercept(
|
|
35602
|
+
(target, thisArg, args, additional) => instrumentStrandsStreamInvocation({
|
|
35603
|
+
finalize: finalizeAgentStream,
|
|
35604
|
+
handleChunk: handleAgentStreamEvent,
|
|
35605
|
+
invoke: () => Reflect.apply(target, thisArg, args),
|
|
35606
|
+
name: "Strands Agent SDK",
|
|
35607
|
+
start: () => startAgentStream(
|
|
35608
|
+
args[0],
|
|
35609
|
+
extractAgent(additional.agent, thisArg),
|
|
35610
|
+
this.activeChildParents
|
|
35611
|
+
)
|
|
35612
|
+
})
|
|
35613
|
+
)
|
|
35614
|
+
);
|
|
34701
35615
|
}
|
|
34702
|
-
|
|
34703
|
-
|
|
34704
|
-
|
|
34705
|
-
|
|
34706
|
-
|
|
34707
|
-
|
|
34708
|
-
|
|
34709
|
-
|
|
34710
|
-
|
|
34711
|
-
|
|
34712
|
-
|
|
34713
|
-
|
|
34714
|
-
|
|
34715
|
-
|
|
34716
|
-
|
|
34717
|
-
|
|
34718
|
-
|
|
34719
|
-
|
|
34720
|
-
|
|
34721
|
-
}
|
|
34722
|
-
|
|
34723
|
-
|
|
34724
|
-
|
|
34725
|
-
|
|
34726
|
-
|
|
34727
|
-
|
|
34728
|
-
|
|
34729
|
-
|
|
34730
|
-
|
|
34731
|
-
|
|
34732
|
-
|
|
34733
|
-
|
|
34734
|
-
|
|
34735
|
-
|
|
34736
|
-
|
|
34737
|
-
|
|
34738
|
-
|
|
34739
|
-
|
|
34740
|
-
|
|
34741
|
-
|
|
34742
|
-
|
|
34743
|
-
|
|
34744
|
-
this.activeChildParents,
|
|
34745
|
-
void 0,
|
|
34746
|
-
result
|
|
35616
|
+
interceptMultiAgentStream(channel2, operation) {
|
|
35617
|
+
this.unsubscribers.push(
|
|
35618
|
+
channel2.intercept(
|
|
35619
|
+
(target, thisArg, args, additional) => instrumentStrandsStreamInvocation({
|
|
35620
|
+
finalize: (state, error, output) => finalizeMultiAgentStream(
|
|
35621
|
+
state,
|
|
35622
|
+
this.activeChildParents,
|
|
35623
|
+
error,
|
|
35624
|
+
output
|
|
35625
|
+
),
|
|
35626
|
+
handleChunk: (state, chunk) => handleMultiAgentStreamEvent(state, chunk, this.activeChildParents),
|
|
35627
|
+
invoke: () => Reflect.apply(target, thisArg, args),
|
|
35628
|
+
name: "Strands multi-agent",
|
|
35629
|
+
start: () => startMultiAgentStream(
|
|
35630
|
+
args[0],
|
|
35631
|
+
extractOrchestrator(additional.orchestrator, thisArg),
|
|
35632
|
+
operation,
|
|
35633
|
+
this.activeChildParents
|
|
35634
|
+
)
|
|
35635
|
+
})
|
|
35636
|
+
)
|
|
35637
|
+
);
|
|
35638
|
+
}
|
|
35639
|
+
};
|
|
35640
|
+
function instrumentStrandsStreamInvocation(options) {
|
|
35641
|
+
let state;
|
|
35642
|
+
try {
|
|
35643
|
+
state = options.start();
|
|
35644
|
+
} catch (error) {
|
|
35645
|
+
debugLogger.error(`Error starting ${options.name} instrumentation:`, error);
|
|
35646
|
+
}
|
|
35647
|
+
let result;
|
|
35648
|
+
try {
|
|
35649
|
+
result = runWithAutoInstrumentationSuppressed(options.invoke);
|
|
35650
|
+
} catch (error) {
|
|
35651
|
+
if (state) {
|
|
35652
|
+
try {
|
|
35653
|
+
options.finalize(state, error);
|
|
35654
|
+
} catch (instrumentationError) {
|
|
35655
|
+
debugLogger.error(
|
|
35656
|
+
`Error handling ${options.name} instrumentation failure:`,
|
|
35657
|
+
instrumentationError
|
|
34747
35658
|
);
|
|
34748
|
-
states.delete(event);
|
|
34749
|
-
},
|
|
34750
|
-
error: (event) => {
|
|
34751
|
-
const state = states.get(event);
|
|
34752
|
-
if (!state || !event.error) {
|
|
34753
|
-
return;
|
|
34754
|
-
}
|
|
34755
|
-
finalizeMultiAgentStream(state, this.activeChildParents, event.error);
|
|
34756
|
-
states.delete(event);
|
|
34757
35659
|
}
|
|
34758
|
-
}
|
|
34759
|
-
|
|
34760
|
-
this.unsubscribers.push(() => {
|
|
34761
|
-
unbindAutoInstrumentationSuppression?.();
|
|
34762
|
-
tracingChannel.unsubscribe(handlers);
|
|
34763
|
-
});
|
|
35660
|
+
}
|
|
35661
|
+
throw error;
|
|
34764
35662
|
}
|
|
34765
|
-
|
|
34766
|
-
|
|
34767
|
-
|
|
35663
|
+
if (state) {
|
|
35664
|
+
try {
|
|
35665
|
+
if (isAsyncIterable(result)) {
|
|
35666
|
+
patchStreamIfNeeded(result, {
|
|
35667
|
+
aroundNext: (callback) => runWithAutoInstrumentationSuppressed(callback),
|
|
35668
|
+
onChunk: (chunk) => options.handleChunk(state, chunk),
|
|
35669
|
+
onComplete: () => options.finalize(state),
|
|
35670
|
+
onError: (error) => options.finalize(state, error)
|
|
35671
|
+
});
|
|
35672
|
+
} else {
|
|
35673
|
+
options.finalize(state, void 0, result);
|
|
35674
|
+
}
|
|
35675
|
+
} catch (error) {
|
|
35676
|
+
debugLogger.error(
|
|
35677
|
+
`Error finalizing ${options.name} instrumentation:`,
|
|
35678
|
+
error
|
|
35679
|
+
);
|
|
35680
|
+
}
|
|
35681
|
+
}
|
|
35682
|
+
return result;
|
|
35683
|
+
}
|
|
35684
|
+
function startAgentStream(input, agent, activeChildParents) {
|
|
34768
35685
|
const model = agent?.model;
|
|
34769
35686
|
const metadata = {
|
|
34770
35687
|
...extractAgentMetadata2(agent),
|
|
@@ -34774,17 +35691,14 @@ function startAgentStream(event, activeChildParents) {
|
|
|
34774
35691
|
};
|
|
34775
35692
|
const parentSpan = agent ? getOnlyChildParent(activeChildParents, agent) : void 0;
|
|
34776
35693
|
const attachmentCache = createStrandsAttachmentCache();
|
|
34777
|
-
const
|
|
34778
|
-
event.arguments[0],
|
|
34779
|
-
attachmentCache
|
|
34780
|
-
);
|
|
35694
|
+
const processedInput = processStrandsInputAttachments(input, attachmentCache);
|
|
34781
35695
|
const span = parentSpan ? withCurrent(
|
|
34782
35696
|
parentSpan,
|
|
34783
35697
|
() => startSpan(
|
|
34784
35698
|
withSpanInstrumentationName(
|
|
34785
35699
|
{
|
|
34786
35700
|
event: {
|
|
34787
|
-
input,
|
|
35701
|
+
input: processedInput,
|
|
34788
35702
|
metadata
|
|
34789
35703
|
},
|
|
34790
35704
|
name: formatAgentSpanName(agent),
|
|
@@ -34797,7 +35711,7 @@ function startAgentStream(event, activeChildParents) {
|
|
|
34797
35711
|
withSpanInstrumentationName(
|
|
34798
35712
|
{
|
|
34799
35713
|
event: {
|
|
34800
|
-
input,
|
|
35714
|
+
input: processedInput,
|
|
34801
35715
|
metadata
|
|
34802
35716
|
},
|
|
34803
35717
|
name: formatAgentSpanName(agent),
|
|
@@ -34815,22 +35729,21 @@ function startAgentStream(event, activeChildParents) {
|
|
|
34815
35729
|
startTime: getCurrentUnixTimestamp()
|
|
34816
35730
|
};
|
|
34817
35731
|
}
|
|
34818
|
-
function startMultiAgentStream(
|
|
34819
|
-
const orchestrator = extractOrchestrator(event);
|
|
35732
|
+
function startMultiAgentStream(input, orchestrator, operation, activeChildParents) {
|
|
34820
35733
|
const metadata = {
|
|
34821
35734
|
"strands.operation": operation,
|
|
34822
35735
|
provider: "strands",
|
|
34823
35736
|
...orchestrator?.id ? { "strands.orchestrator.id": orchestrator.id } : {}
|
|
34824
35737
|
};
|
|
34825
35738
|
const parentSpan = orchestrator ? getOnlyChildParent(activeChildParents, orchestrator) : void 0;
|
|
34826
|
-
const
|
|
35739
|
+
const processedInput = processStrandsInputAttachments(input);
|
|
34827
35740
|
const span = parentSpan ? withCurrent(
|
|
34828
35741
|
parentSpan,
|
|
34829
35742
|
() => startSpan(
|
|
34830
35743
|
withSpanInstrumentationName(
|
|
34831
35744
|
{
|
|
34832
35745
|
event: {
|
|
34833
|
-
input,
|
|
35746
|
+
input: processedInput,
|
|
34834
35747
|
metadata
|
|
34835
35748
|
},
|
|
34836
35749
|
name: operation === "Graph.stream" ? "Strands Graph" : "Strands Swarm",
|
|
@@ -34843,7 +35756,7 @@ function startMultiAgentStream(event, operation, activeChildParents) {
|
|
|
34843
35756
|
withSpanInstrumentationName(
|
|
34844
35757
|
{
|
|
34845
35758
|
event: {
|
|
34846
|
-
input,
|
|
35759
|
+
input: processedInput,
|
|
34847
35760
|
metadata
|
|
34848
35761
|
},
|
|
34849
35762
|
name: operation === "Graph.stream" ? "Strands Graph" : "Strands Swarm",
|
|
@@ -35214,12 +36127,12 @@ function finalizeMultiAgentStream(state, activeChildParents, error, output) {
|
|
|
35214
36127
|
});
|
|
35215
36128
|
state.span.end();
|
|
35216
36129
|
}
|
|
35217
|
-
function extractAgent(
|
|
35218
|
-
const candidate =
|
|
36130
|
+
function extractAgent(agent, self) {
|
|
36131
|
+
const candidate = agent ?? self;
|
|
35219
36132
|
return isObject(candidate) && typeof candidate.stream === "function" ? candidate : void 0;
|
|
35220
36133
|
}
|
|
35221
|
-
function extractOrchestrator(
|
|
35222
|
-
const candidate =
|
|
36134
|
+
function extractOrchestrator(orchestrator, self) {
|
|
36135
|
+
const candidate = orchestrator ?? self;
|
|
35223
36136
|
return isObject(candidate) && typeof candidate.stream === "function" ? candidate : void 0;
|
|
35224
36137
|
}
|
|
35225
36138
|
function extractAgentMetadata2(agent) {
|
|
@@ -37086,6 +37999,7 @@ __export(exports_exports, {
|
|
|
37086
37999
|
braintrustStreamChunkSchema: () => braintrustStreamChunkSchema,
|
|
37087
38000
|
buildLocalSummary: () => buildLocalSummary,
|
|
37088
38001
|
collectAnthropicSession: () => collectAnthropicSession,
|
|
38002
|
+
completeOpenAIBatchTrace: () => completeOpenAIBatchTrace,
|
|
37089
38003
|
configureInstrumentation: () => configureInstrumentation,
|
|
37090
38004
|
constructLogs3OverflowRequest: () => constructLogs3OverflowRequest,
|
|
37091
38005
|
createFinalValuePassThroughStream: () => createFinalValuePassThroughStream,
|
|
@@ -37124,6 +38038,8 @@ __export(exports_exports, {
|
|
|
37124
38038
|
loginToState: () => loginToState,
|
|
37125
38039
|
logs3OverflowUploadSchema: () => logs3OverflowUploadSchema,
|
|
37126
38040
|
newId: () => newId,
|
|
38041
|
+
openaiBatchesRetrieveTraced: () => openaiBatchesRetrieveTraced,
|
|
38042
|
+
openaiFilesCreateTraced: () => openaiFilesCreateTraced,
|
|
37127
38043
|
parseCachedHeader: () => parseCachedHeader,
|
|
37128
38044
|
parseTemplateFormat: () => parseTemplateFormat,
|
|
37129
38045
|
permalink: () => permalink,
|
|
@@ -37288,6 +38204,260 @@ async function registerSandbox(options) {
|
|
|
37288
38204
|
};
|
|
37289
38205
|
}
|
|
37290
38206
|
|
|
38207
|
+
// src/wrappers/openai-promise-utils.ts
|
|
38208
|
+
function splitSpanInfo(allParams) {
|
|
38209
|
+
const { span_info, ...params } = allParams;
|
|
38210
|
+
return {
|
|
38211
|
+
params,
|
|
38212
|
+
span_info
|
|
38213
|
+
};
|
|
38214
|
+
}
|
|
38215
|
+
function createChannelContext(_channel, params, span_info) {
|
|
38216
|
+
return {
|
|
38217
|
+
arguments: (
|
|
38218
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38219
|
+
[params]
|
|
38220
|
+
),
|
|
38221
|
+
span_info
|
|
38222
|
+
};
|
|
38223
|
+
}
|
|
38224
|
+
async function tracePromiseWithResponse(channel2, traceContext, apiPromise) {
|
|
38225
|
+
let enhancedResponse;
|
|
38226
|
+
const tracePromise = (
|
|
38227
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38228
|
+
channel2.tracePromise
|
|
38229
|
+
);
|
|
38230
|
+
const data = await tracePromise(async () => {
|
|
38231
|
+
enhancedResponse = await apiPromise.withResponse();
|
|
38232
|
+
traceContext.response = enhancedResponse.response;
|
|
38233
|
+
return enhancedResponse.data;
|
|
38234
|
+
}, traceContext);
|
|
38235
|
+
if (!enhancedResponse) {
|
|
38236
|
+
throw new Error("Expected withResponse() to provide response");
|
|
38237
|
+
}
|
|
38238
|
+
return {
|
|
38239
|
+
data,
|
|
38240
|
+
response: enhancedResponse.response,
|
|
38241
|
+
request_id: enhancedResponse.request_id
|
|
38242
|
+
};
|
|
38243
|
+
}
|
|
38244
|
+
async function tracePromiseAsResponse(channel2, traceContext, apiPromise) {
|
|
38245
|
+
const tracePromise = (
|
|
38246
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38247
|
+
channel2.tracePromise
|
|
38248
|
+
);
|
|
38249
|
+
let response;
|
|
38250
|
+
await tracePromise(async () => {
|
|
38251
|
+
response = await apiPromise.asResponse();
|
|
38252
|
+
traceContext.response = response;
|
|
38253
|
+
return void 0;
|
|
38254
|
+
}, traceContext);
|
|
38255
|
+
if (!response) {
|
|
38256
|
+
throw new Error("Expected asResponse() to provide response");
|
|
38257
|
+
}
|
|
38258
|
+
return response;
|
|
38259
|
+
}
|
|
38260
|
+
function createLazyAPIPromise(ensureExecuted, ensureResponse, getAPIPromise) {
|
|
38261
|
+
let firstConsumption;
|
|
38262
|
+
let enhancedResponsePromise;
|
|
38263
|
+
let dataPromise;
|
|
38264
|
+
let responsePromise;
|
|
38265
|
+
const withResponse = () => {
|
|
38266
|
+
firstConsumption ??= "data";
|
|
38267
|
+
enhancedResponsePromise ??= firstConsumption === "data" ? ensureExecuted() : getAPIPromise().withResponse();
|
|
38268
|
+
return enhancedResponsePromise;
|
|
38269
|
+
};
|
|
38270
|
+
const asResponse = () => {
|
|
38271
|
+
firstConsumption ??= "response";
|
|
38272
|
+
responsePromise ??= firstConsumption === "response" ? ensureResponse() : getAPIPromise().asResponse();
|
|
38273
|
+
return responsePromise;
|
|
38274
|
+
};
|
|
38275
|
+
return new Proxy({}, {
|
|
38276
|
+
get(target, prop, receiver) {
|
|
38277
|
+
if (prop === "withResponse") {
|
|
38278
|
+
return withResponse;
|
|
38279
|
+
}
|
|
38280
|
+
if (prop === "asResponse") {
|
|
38281
|
+
return asResponse;
|
|
38282
|
+
}
|
|
38283
|
+
if (prop === "then" || prop === "catch" || prop === "finally" || prop in Promise.prototype) {
|
|
38284
|
+
dataPromise ??= withResponse().then((result) => result.data);
|
|
38285
|
+
const value = Reflect.get(dataPromise, prop, receiver);
|
|
38286
|
+
return typeof value === "function" ? value.bind(dataPromise) : value;
|
|
38287
|
+
}
|
|
38288
|
+
return Reflect.get(target, prop, receiver);
|
|
38289
|
+
}
|
|
38290
|
+
});
|
|
38291
|
+
}
|
|
38292
|
+
|
|
38293
|
+
// src/openai-batch.ts
|
|
38294
|
+
function read2(value, key) {
|
|
38295
|
+
if (value === null || typeof value !== "object" && typeof value !== "function") {
|
|
38296
|
+
return void 0;
|
|
38297
|
+
}
|
|
38298
|
+
try {
|
|
38299
|
+
return Reflect.get(value, key);
|
|
38300
|
+
} catch {
|
|
38301
|
+
return void 0;
|
|
38302
|
+
}
|
|
38303
|
+
}
|
|
38304
|
+
function isAsyncIterable5(value) {
|
|
38305
|
+
return typeof read2(value, Symbol.asyncIterator) === "function";
|
|
38306
|
+
}
|
|
38307
|
+
function teeAsyncIterable(source) {
|
|
38308
|
+
const iterator = source[Symbol.asyncIterator]();
|
|
38309
|
+
const stream = new ReadableStream({
|
|
38310
|
+
async pull(controller) {
|
|
38311
|
+
try {
|
|
38312
|
+
const result = await iterator.next();
|
|
38313
|
+
if (result.done) {
|
|
38314
|
+
controller.close();
|
|
38315
|
+
return;
|
|
38316
|
+
}
|
|
38317
|
+
if (!(result.value instanceof Uint8Array)) {
|
|
38318
|
+
throw new TypeError(
|
|
38319
|
+
"OpenAI upload streams must yield Uint8Array chunks"
|
|
38320
|
+
);
|
|
38321
|
+
}
|
|
38322
|
+
controller.enqueue(result.value);
|
|
38323
|
+
} catch (error) {
|
|
38324
|
+
controller.error(error);
|
|
38325
|
+
}
|
|
38326
|
+
},
|
|
38327
|
+
async cancel(reason) {
|
|
38328
|
+
await iterator.return?.(reason);
|
|
38329
|
+
}
|
|
38330
|
+
});
|
|
38331
|
+
const [uploadStream, trace] = stream.tee();
|
|
38332
|
+
const upload = {
|
|
38333
|
+
async *[Symbol.asyncIterator]() {
|
|
38334
|
+
const reader = uploadStream.getReader();
|
|
38335
|
+
try {
|
|
38336
|
+
while (true) {
|
|
38337
|
+
const result = await reader.read();
|
|
38338
|
+
if (result.done) {
|
|
38339
|
+
return;
|
|
38340
|
+
}
|
|
38341
|
+
yield result.value;
|
|
38342
|
+
}
|
|
38343
|
+
} finally {
|
|
38344
|
+
reader.releaseLock();
|
|
38345
|
+
}
|
|
38346
|
+
}
|
|
38347
|
+
};
|
|
38348
|
+
const path = read2(source, "path");
|
|
38349
|
+
if (typeof path === "string") {
|
|
38350
|
+
Object.defineProperty(upload, "path", { value: path });
|
|
38351
|
+
}
|
|
38352
|
+
return { upload, trace: new Response(trace) };
|
|
38353
|
+
}
|
|
38354
|
+
function teeUpload(upload) {
|
|
38355
|
+
if (upload instanceof Blob) {
|
|
38356
|
+
return { upload, trace: new Response(upload) };
|
|
38357
|
+
}
|
|
38358
|
+
if (upload instanceof Response) {
|
|
38359
|
+
return { upload, trace: upload.clone() };
|
|
38360
|
+
}
|
|
38361
|
+
if (isAsyncIterable5(upload)) {
|
|
38362
|
+
return teeAsyncIterable(upload);
|
|
38363
|
+
}
|
|
38364
|
+
return void 0;
|
|
38365
|
+
}
|
|
38366
|
+
function openaiFilesCreateTraced(files) {
|
|
38367
|
+
return (params, options) => {
|
|
38368
|
+
const parent = getSpanParentObject();
|
|
38369
|
+
const purpose = read2(params, "purpose");
|
|
38370
|
+
const file = read2(params, "file");
|
|
38371
|
+
if (purpose !== "batch") {
|
|
38372
|
+
return files.create(params, options);
|
|
38373
|
+
}
|
|
38374
|
+
let branches;
|
|
38375
|
+
try {
|
|
38376
|
+
branches = teeUpload(file);
|
|
38377
|
+
} catch {
|
|
38378
|
+
return files.create(params, options);
|
|
38379
|
+
}
|
|
38380
|
+
if (!branches) {
|
|
38381
|
+
return files.create(params, options);
|
|
38382
|
+
}
|
|
38383
|
+
const tracedParams = {
|
|
38384
|
+
...Object(params),
|
|
38385
|
+
file: branches.upload
|
|
38386
|
+
};
|
|
38387
|
+
const apiPromise = files.create(tracedParams, options);
|
|
38388
|
+
let enhancedResponse;
|
|
38389
|
+
const tracedResponse = openAIChannels.filesCreateTraced.invoke(
|
|
38390
|
+
async () => {
|
|
38391
|
+
enhancedResponse = await apiPromise.withResponse();
|
|
38392
|
+
return enhancedResponse.data;
|
|
38393
|
+
},
|
|
38394
|
+
files,
|
|
38395
|
+
[{ params, inputFileContent: branches.trace, parent }],
|
|
38396
|
+
{}
|
|
38397
|
+
).then((data) => {
|
|
38398
|
+
if (!enhancedResponse) {
|
|
38399
|
+
throw new Error(
|
|
38400
|
+
"Expected OpenAI withResponse() to provide a response"
|
|
38401
|
+
);
|
|
38402
|
+
}
|
|
38403
|
+
return { ...enhancedResponse, data };
|
|
38404
|
+
});
|
|
38405
|
+
return createLazyAPIPromise(
|
|
38406
|
+
() => tracedResponse,
|
|
38407
|
+
() => tracedResponse.then(({ response }) => response),
|
|
38408
|
+
() => apiPromise
|
|
38409
|
+
);
|
|
38410
|
+
};
|
|
38411
|
+
}
|
|
38412
|
+
function openaiBatchesRetrieveTraced(batches) {
|
|
38413
|
+
return (batchId, options) => {
|
|
38414
|
+
const apiPromise = batches.retrieve(batchId, options);
|
|
38415
|
+
let enhancedResponse;
|
|
38416
|
+
const tracedResponse = openAIChannels.batchesRetrieveTraced.invoke(
|
|
38417
|
+
async () => {
|
|
38418
|
+
enhancedResponse = await apiPromise.withResponse();
|
|
38419
|
+
return enhancedResponse.data;
|
|
38420
|
+
},
|
|
38421
|
+
batches,
|
|
38422
|
+
[{ batchId }],
|
|
38423
|
+
{}
|
|
38424
|
+
).then((data) => {
|
|
38425
|
+
if (!enhancedResponse) {
|
|
38426
|
+
throw new Error(
|
|
38427
|
+
"Expected OpenAI withResponse() to provide a response"
|
|
38428
|
+
);
|
|
38429
|
+
}
|
|
38430
|
+
return { ...enhancedResponse, data };
|
|
38431
|
+
});
|
|
38432
|
+
return createLazyAPIPromise(
|
|
38433
|
+
() => tracedResponse,
|
|
38434
|
+
() => tracedResponse.then(({ response }) => response),
|
|
38435
|
+
() => apiPromise
|
|
38436
|
+
);
|
|
38437
|
+
};
|
|
38438
|
+
}
|
|
38439
|
+
async function completeOpenAIBatchTrace(args) {
|
|
38440
|
+
const inputFileContent = Promise.resolve(args.inputFileContent);
|
|
38441
|
+
const outputFileContent = args.outputFileContent === void 0 ? void 0 : Promise.resolve(args.outputFileContent);
|
|
38442
|
+
const errorFileContent = args.errorFileContent === void 0 ? void 0 : Promise.resolve(args.errorFileContent);
|
|
38443
|
+
void inputFileContent.catch(() => void 0);
|
|
38444
|
+
void outputFileContent?.catch(() => void 0);
|
|
38445
|
+
void errorFileContent?.catch(() => void 0);
|
|
38446
|
+
await openAIChannels.batchesCompleteTrace.invoke(
|
|
38447
|
+
async () => void 0,
|
|
38448
|
+
void 0,
|
|
38449
|
+
[
|
|
38450
|
+
{
|
|
38451
|
+
...args,
|
|
38452
|
+
inputFileContent,
|
|
38453
|
+
outputFileContent,
|
|
38454
|
+
errorFileContent
|
|
38455
|
+
}
|
|
38456
|
+
],
|
|
38457
|
+
{}
|
|
38458
|
+
);
|
|
38459
|
+
}
|
|
38460
|
+
|
|
37291
38461
|
// src/functions/invoke.ts
|
|
37292
38462
|
async function invoke(args) {
|
|
37293
38463
|
const {
|
|
@@ -37390,58 +38560,6 @@ function initFunction({
|
|
|
37390
38560
|
return f;
|
|
37391
38561
|
}
|
|
37392
38562
|
|
|
37393
|
-
// src/wrappers/openai-promise-utils.ts
|
|
37394
|
-
function splitSpanInfo(allParams) {
|
|
37395
|
-
const { span_info, ...params } = allParams;
|
|
37396
|
-
return {
|
|
37397
|
-
params,
|
|
37398
|
-
span_info
|
|
37399
|
-
};
|
|
37400
|
-
}
|
|
37401
|
-
function createChannelContext(_channel, params, span_info) {
|
|
37402
|
-
return {
|
|
37403
|
-
arguments: (
|
|
37404
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
37405
|
-
[params]
|
|
37406
|
-
),
|
|
37407
|
-
span_info
|
|
37408
|
-
};
|
|
37409
|
-
}
|
|
37410
|
-
async function tracePromiseWithResponse(channel2, traceContext, apiPromise) {
|
|
37411
|
-
let enhancedResponse;
|
|
37412
|
-
const tracePromise = (
|
|
37413
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
37414
|
-
channel2.tracePromise
|
|
37415
|
-
);
|
|
37416
|
-
const data = await tracePromise(async () => {
|
|
37417
|
-
enhancedResponse = await apiPromise.withResponse();
|
|
37418
|
-
traceContext.response = enhancedResponse.response;
|
|
37419
|
-
return enhancedResponse.data;
|
|
37420
|
-
}, traceContext);
|
|
37421
|
-
if (!enhancedResponse) {
|
|
37422
|
-
throw new Error("Expected withResponse() to provide response");
|
|
37423
|
-
}
|
|
37424
|
-
return { data, response: enhancedResponse.response };
|
|
37425
|
-
}
|
|
37426
|
-
function createLazyAPIPromise(ensureExecuted) {
|
|
37427
|
-
let dataPromise = null;
|
|
37428
|
-
return new Proxy({}, {
|
|
37429
|
-
get(target, prop, receiver) {
|
|
37430
|
-
if (prop === "withResponse") {
|
|
37431
|
-
return () => ensureExecuted();
|
|
37432
|
-
}
|
|
37433
|
-
if (prop === "then" || prop === "catch" || prop === "finally" || prop in Promise.prototype) {
|
|
37434
|
-
if (!dataPromise) {
|
|
37435
|
-
dataPromise = ensureExecuted().then((result) => result.data);
|
|
37436
|
-
}
|
|
37437
|
-
const value = Reflect.get(dataPromise, prop, receiver);
|
|
37438
|
-
return typeof value === "function" ? value.bind(dataPromise) : value;
|
|
37439
|
-
}
|
|
37440
|
-
return Reflect.get(target, prop, receiver);
|
|
37441
|
-
}
|
|
37442
|
-
});
|
|
37443
|
-
}
|
|
37444
|
-
|
|
37445
38563
|
// src/wrappers/oai_responses.ts
|
|
37446
38564
|
function responsesProxy(openai) {
|
|
37447
38565
|
if (!openai.responses) {
|
|
@@ -37478,17 +38596,33 @@ function wrapResponsesAsync(target, channel2) {
|
|
|
37478
38596
|
return (allParams, options) => {
|
|
37479
38597
|
const { span_info, params } = splitSpanInfo(allParams);
|
|
37480
38598
|
let executionPromise = null;
|
|
38599
|
+
let apiPromise = null;
|
|
38600
|
+
const getAPIPromise = () => {
|
|
38601
|
+
apiPromise ??= target(params, options);
|
|
38602
|
+
return apiPromise;
|
|
38603
|
+
};
|
|
37481
38604
|
const ensureExecuted = () => {
|
|
37482
38605
|
if (!executionPromise) {
|
|
37483
38606
|
executionPromise = (async () => {
|
|
37484
38607
|
const traceContext = createChannelContext(channel2, params, span_info);
|
|
37485
|
-
|
|
37486
|
-
|
|
38608
|
+
return tracePromiseWithResponse(
|
|
38609
|
+
channel2,
|
|
38610
|
+
traceContext,
|
|
38611
|
+
getAPIPromise()
|
|
38612
|
+
);
|
|
37487
38613
|
})();
|
|
37488
38614
|
}
|
|
37489
38615
|
return executionPromise;
|
|
37490
38616
|
};
|
|
37491
|
-
return createLazyAPIPromise(
|
|
38617
|
+
return createLazyAPIPromise(
|
|
38618
|
+
ensureExecuted,
|
|
38619
|
+
() => tracePromiseAsResponse(
|
|
38620
|
+
channel2,
|
|
38621
|
+
createChannelContext(channel2, params, span_info),
|
|
38622
|
+
getAPIPromise()
|
|
38623
|
+
),
|
|
38624
|
+
getAPIPromise
|
|
38625
|
+
);
|
|
37492
38626
|
};
|
|
37493
38627
|
}
|
|
37494
38628
|
function wrapResponsesSyncStream(target, channel2) {
|
|
@@ -37634,6 +38768,11 @@ function wrapChatCompletion(completion) {
|
|
|
37634
38768
|
allParams
|
|
37635
38769
|
);
|
|
37636
38770
|
let executionPromise = null;
|
|
38771
|
+
let apiPromise = null;
|
|
38772
|
+
const getAPIPromise = () => {
|
|
38773
|
+
apiPromise ??= completion(params, options);
|
|
38774
|
+
return apiPromise;
|
|
38775
|
+
};
|
|
37637
38776
|
const ensureExecuted = () => {
|
|
37638
38777
|
if (!executionPromise) {
|
|
37639
38778
|
executionPromise = (async () => {
|
|
@@ -37643,32 +38782,44 @@ function wrapChatCompletion(completion) {
|
|
|
37643
38782
|
span_info
|
|
37644
38783
|
);
|
|
37645
38784
|
if (params.stream) {
|
|
37646
|
-
const completionPromise =
|
|
37647
|
-
|
|
37648
|
-
|
|
38785
|
+
const completionPromise = (
|
|
38786
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38787
|
+
getAPIPromise()
|
|
37649
38788
|
);
|
|
37650
|
-
const { data: data2, response: response2 } = await tracePromiseWithResponse(
|
|
38789
|
+
const { data: data2, response: response2, request_id: request_id2 } = await tracePromiseWithResponse(
|
|
37651
38790
|
openAIChannels.chatCompletionsCreate,
|
|
37652
38791
|
traceContext,
|
|
37653
38792
|
completionPromise
|
|
37654
38793
|
);
|
|
37655
|
-
return { data: data2, response: response2 };
|
|
38794
|
+
return { data: data2, response: response2, request_id: request_id2 };
|
|
37656
38795
|
}
|
|
37657
|
-
const completionResponse =
|
|
37658
|
-
|
|
37659
|
-
|
|
38796
|
+
const completionResponse = (
|
|
38797
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38798
|
+
getAPIPromise()
|
|
37660
38799
|
);
|
|
37661
|
-
const { data, response } = await tracePromiseWithResponse(
|
|
38800
|
+
const { data, response, request_id } = await tracePromiseWithResponse(
|
|
37662
38801
|
openAIChannels.chatCompletionsCreate,
|
|
37663
38802
|
traceContext,
|
|
37664
38803
|
completionResponse
|
|
37665
38804
|
);
|
|
37666
|
-
return { data, response };
|
|
38805
|
+
return { data, response, request_id };
|
|
37667
38806
|
})();
|
|
37668
38807
|
}
|
|
37669
38808
|
return executionPromise;
|
|
37670
38809
|
};
|
|
37671
|
-
return createLazyAPIPromise(
|
|
38810
|
+
return createLazyAPIPromise(
|
|
38811
|
+
ensureExecuted,
|
|
38812
|
+
() => tracePromiseAsResponse(
|
|
38813
|
+
openAIChannels.chatCompletionsCreate,
|
|
38814
|
+
createChannelContext(
|
|
38815
|
+
openAIChannels.chatCompletionsCreate,
|
|
38816
|
+
params,
|
|
38817
|
+
span_info
|
|
38818
|
+
),
|
|
38819
|
+
getAPIPromise()
|
|
38820
|
+
),
|
|
38821
|
+
getAPIPromise
|
|
38822
|
+
);
|
|
37672
38823
|
};
|
|
37673
38824
|
}
|
|
37674
38825
|
function createEndpointProxy(target, wrapperFn) {
|
|
@@ -37686,6 +38837,11 @@ function wrapApiCreateWithChannel(create, channel2) {
|
|
|
37686
38837
|
return (allParams, options) => {
|
|
37687
38838
|
const { span_info, params } = splitSpanInfo(allParams);
|
|
37688
38839
|
let executionPromise = null;
|
|
38840
|
+
let apiPromise = null;
|
|
38841
|
+
const getAPIPromise = () => {
|
|
38842
|
+
apiPromise ??= create(params, options);
|
|
38843
|
+
return apiPromise;
|
|
38844
|
+
};
|
|
37689
38845
|
const ensureExecuted = () => {
|
|
37690
38846
|
if (!executionPromise) {
|
|
37691
38847
|
executionPromise = (async () => {
|
|
@@ -37693,13 +38849,21 @@ function wrapApiCreateWithChannel(create, channel2) {
|
|
|
37693
38849
|
return tracePromiseWithResponse(
|
|
37694
38850
|
channel2,
|
|
37695
38851
|
traceContext,
|
|
37696
|
-
|
|
38852
|
+
getAPIPromise()
|
|
37697
38853
|
);
|
|
37698
38854
|
})();
|
|
37699
38855
|
}
|
|
37700
38856
|
return executionPromise;
|
|
37701
38857
|
};
|
|
37702
|
-
return createLazyAPIPromise(
|
|
38858
|
+
return createLazyAPIPromise(
|
|
38859
|
+
ensureExecuted,
|
|
38860
|
+
() => tracePromiseAsResponse(
|
|
38861
|
+
channel2,
|
|
38862
|
+
createChannelContext(channel2, params, span_info),
|
|
38863
|
+
getAPIPromise()
|
|
38864
|
+
),
|
|
38865
|
+
getAPIPromise
|
|
38866
|
+
);
|
|
37703
38867
|
};
|
|
37704
38868
|
}
|
|
37705
38869
|
var wrapEmbeddings = (create) => wrapApiCreateWithChannel(create, openAIChannels.embeddingsCreate);
|
|
@@ -37735,6 +38899,13 @@ function wrapAISDK(aiSDK, options = {}) {
|
|
|
37735
38899
|
switch (prop) {
|
|
37736
38900
|
case "generateText":
|
|
37737
38901
|
return wrapGenerateText(typedAISDK.generateText, options, typedAISDK);
|
|
38902
|
+
case "generateImage":
|
|
38903
|
+
case "experimental_generateImage":
|
|
38904
|
+
return typeof original === "function" ? wrapGenerateImage(
|
|
38905
|
+
original,
|
|
38906
|
+
options,
|
|
38907
|
+
typedAISDK
|
|
38908
|
+
) : original;
|
|
37738
38909
|
case "streamText":
|
|
37739
38910
|
return wrapStreamText(typedAISDK.streamText, options, typedAISDK);
|
|
37740
38911
|
case "generateObject":
|
|
@@ -37971,6 +39142,32 @@ var wrapGenerateObject = (generateObject, options = {}, aiSDK) => {
|
|
|
37971
39142
|
options
|
|
37972
39143
|
);
|
|
37973
39144
|
};
|
|
39145
|
+
var wrapGenerateImage = (generateImage, options = {}, aiSDK) => {
|
|
39146
|
+
return makeGenerateImageWrapper(generateImage, { aiSDK }, options);
|
|
39147
|
+
};
|
|
39148
|
+
var makeGenerateImageWrapper = (generateImage, contextOptions = {}, options = {}) => {
|
|
39149
|
+
const wrapper = async function(allParams) {
|
|
39150
|
+
const { span_info, ...params } = allParams;
|
|
39151
|
+
const tracedParams = { ...params };
|
|
39152
|
+
return aiSDKChannels.generateImage.tracePromise(
|
|
39153
|
+
() => generateImage(tracedParams),
|
|
39154
|
+
createAISDKChannelContext(tracedParams, {
|
|
39155
|
+
aiSDK: contextOptions.aiSDK,
|
|
39156
|
+
denyOutputPaths: options.denyOutputPaths,
|
|
39157
|
+
self: contextOptions.self,
|
|
39158
|
+
span_info: mergeSpanInfo(span_info, {
|
|
39159
|
+
name: "generateImage",
|
|
39160
|
+
spanType: contextOptions.spanType
|
|
39161
|
+
})
|
|
39162
|
+
})
|
|
39163
|
+
);
|
|
39164
|
+
};
|
|
39165
|
+
Object.defineProperty(wrapper, "name", {
|
|
39166
|
+
value: "generateImage",
|
|
39167
|
+
writable: false
|
|
39168
|
+
});
|
|
39169
|
+
return wrapper;
|
|
39170
|
+
};
|
|
37974
39171
|
var makeEmbedWrapper = (channel2, name, embed, contextOptions = {}, options = {}) => {
|
|
37975
39172
|
const wrapper = async function(allParams) {
|
|
37976
39173
|
const { span_info, ...params } = allParams;
|
|
@@ -38721,7 +39918,7 @@ function braintrustEveHook(options) {
|
|
|
38721
39918
|
}
|
|
38722
39919
|
};
|
|
38723
39920
|
}
|
|
38724
|
-
function
|
|
39921
|
+
function createLegacyEveInstrumentation(options) {
|
|
38725
39922
|
const state = options.defineState(EVE_TRACE_STATE_KEY, emptyEveTraceState);
|
|
38726
39923
|
return {
|
|
38727
39924
|
events: {
|
|
@@ -40109,8 +41306,10 @@ function capturedModelInput(modelInput) {
|
|
|
40109
41306
|
const value = [];
|
|
40110
41307
|
if (typeof instructions === "string") {
|
|
40111
41308
|
value.push({ content: instructions, role: "system" });
|
|
40112
|
-
} else if (instructions) {
|
|
41309
|
+
} else if (Array.isArray(instructions)) {
|
|
40113
41310
|
value.push(...instructions.map(capturedEveModelMessage));
|
|
41311
|
+
} else if (instructions) {
|
|
41312
|
+
value.push(capturedEveModelMessage(instructions));
|
|
40114
41313
|
}
|
|
40115
41314
|
value.push(...messages.map(capturedEveModelMessage));
|
|
40116
41315
|
try {
|
|
@@ -40354,6 +41553,472 @@ async function deterministicEveId(...parts) {
|
|
|
40354
41553
|
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
40355
41554
|
}
|
|
40356
41555
|
|
|
41556
|
+
// src/instrumentation/plugins/eve-provider.ts
|
|
41557
|
+
var MAX_EVE_PROVIDER_CACHE_ENTRIES = 1e4;
|
|
41558
|
+
function createEveInstrumentationProvider(options = {}) {
|
|
41559
|
+
const bridge = new EveProviderBridge(options.metadata);
|
|
41560
|
+
return {
|
|
41561
|
+
// Eve versions before tracePolicy use capture to decide whether provider
|
|
41562
|
+
// events include content. Newer versions prefer tracePolicy when both are
|
|
41563
|
+
// present, so keep the deprecated field for backwards compatibility.
|
|
41564
|
+
capture: "content",
|
|
41565
|
+
tracePolicy: () => ({
|
|
41566
|
+
emit: true,
|
|
41567
|
+
recordInputs: true,
|
|
41568
|
+
recordOutputs: true
|
|
41569
|
+
}),
|
|
41570
|
+
events: {
|
|
41571
|
+
"action.completed": (event, context) => bridge.handleActionTerminal(event, context),
|
|
41572
|
+
"action.failed": (event, context) => bridge.handleActionTerminal(event, context),
|
|
41573
|
+
"action.started": (event, context) => bridge.handleActionStarted(event, context),
|
|
41574
|
+
"model.call.completed": (event, context) => bridge.handleModelTerminal(event, context),
|
|
41575
|
+
"model.call.failed": (event, context) => bridge.handleModelTerminal(event, context),
|
|
41576
|
+
"model.call.started": (event, context) => bridge.handleModelStarted(event, context),
|
|
41577
|
+
"step.attempt.completed": (event) => bridge.handleStepAttemptTerminal(event),
|
|
41578
|
+
"step.attempt.failed": (event) => bridge.handleStepAttemptTerminal(event),
|
|
41579
|
+
"turn.cancelled": (event, context) => bridge.handleTurnTerminal(event, context),
|
|
41580
|
+
"turn.completed": (event, context) => bridge.handleTurnTerminal(event, context),
|
|
41581
|
+
"turn.failed": (event, context) => bridge.handleTurnTerminal(event, context),
|
|
41582
|
+
"turn.started": (event, context) => bridge.handleTurnStarted(event, context)
|
|
41583
|
+
},
|
|
41584
|
+
flush,
|
|
41585
|
+
setup: options.setup
|
|
41586
|
+
};
|
|
41587
|
+
}
|
|
41588
|
+
var EveProviderBridge = class {
|
|
41589
|
+
constructor(metadata) {
|
|
41590
|
+
this.metadata = metadata;
|
|
41591
|
+
}
|
|
41592
|
+
metadata;
|
|
41593
|
+
activeActions = /* @__PURE__ */ new Map();
|
|
41594
|
+
activeModels = /* @__PURE__ */ new Map();
|
|
41595
|
+
modelsByAttempt = /* @__PURE__ */ new Map();
|
|
41596
|
+
settledOperations = new LRUCache({
|
|
41597
|
+
max: MAX_EVE_PROVIDER_CACHE_ENTRIES
|
|
41598
|
+
});
|
|
41599
|
+
turns = new LRUCache({
|
|
41600
|
+
max: MAX_EVE_PROVIDER_CACHE_ENTRIES
|
|
41601
|
+
});
|
|
41602
|
+
async handleTurnStarted(event, context) {
|
|
41603
|
+
await this.contain("turn start", async () => {
|
|
41604
|
+
if (this.settledOperations.has(event.idempotencyKey)) {
|
|
41605
|
+
context.state.set({ skip: true });
|
|
41606
|
+
return;
|
|
41607
|
+
}
|
|
41608
|
+
const { rowId, spanId } = await generateEveIds(
|
|
41609
|
+
"turn",
|
|
41610
|
+
event.idempotencyKey
|
|
41611
|
+
);
|
|
41612
|
+
const key = turnKey3(event.sessionId, event.turnId);
|
|
41613
|
+
const stored = storedSpan(context);
|
|
41614
|
+
if (stored && "exported" in stored && stored.rootSpanId) {
|
|
41615
|
+
this.turns.set(key, { rootSpanId: stored.rootSpanId, spanId });
|
|
41616
|
+
return;
|
|
41617
|
+
}
|
|
41618
|
+
let rootSpanId = spanId;
|
|
41619
|
+
let parentSpanId;
|
|
41620
|
+
if (event.parentLineage) {
|
|
41621
|
+
const parentTurnKey = turnKey3(
|
|
41622
|
+
event.parentLineage.sessionId,
|
|
41623
|
+
event.parentLineage.turnId
|
|
41624
|
+
);
|
|
41625
|
+
const parentTurn = this.turns.get(parentTurnKey);
|
|
41626
|
+
rootSpanId = parentTurn?.rootSpanId ?? // Eve propagates the root session through every nested subagent. Use
|
|
41627
|
+
// it instead of the immediate parent session when no ancestor ran
|
|
41628
|
+
// in-process.
|
|
41629
|
+
(await generateEveIds(
|
|
41630
|
+
"turn",
|
|
41631
|
+
turnIdempotencyKey(
|
|
41632
|
+
event.rootSessionId,
|
|
41633
|
+
event.parentLineage.turnId
|
|
41634
|
+
)
|
|
41635
|
+
)).spanId;
|
|
41636
|
+
parentSpanId = (await generateEveIds(
|
|
41637
|
+
"subagent",
|
|
41638
|
+
actionIdempotencyKey(
|
|
41639
|
+
event.parentLineage.sessionId,
|
|
41640
|
+
event.parentLineage.turnId,
|
|
41641
|
+
event.parentLineage.callId
|
|
41642
|
+
)
|
|
41643
|
+
)).spanId;
|
|
41644
|
+
}
|
|
41645
|
+
const metadata = this.spanMetadata(event.sessionId);
|
|
41646
|
+
const span = await this.startSpan(
|
|
41647
|
+
context,
|
|
41648
|
+
{
|
|
41649
|
+
event: { id: rowId, metadata },
|
|
41650
|
+
name: "eve.turn",
|
|
41651
|
+
parentSpanIds: parentSpanId ? { rootSpanId, spanId: parentSpanId } : { parentSpanIds: [], rootSpanId },
|
|
41652
|
+
spanAttributes: { type: "task" /* TASK */ },
|
|
41653
|
+
spanId
|
|
41654
|
+
},
|
|
41655
|
+
rootSpanId
|
|
41656
|
+
);
|
|
41657
|
+
span?.log({ metadata });
|
|
41658
|
+
this.turns.set(key, {
|
|
41659
|
+
rootSpanId,
|
|
41660
|
+
spanId
|
|
41661
|
+
});
|
|
41662
|
+
});
|
|
41663
|
+
}
|
|
41664
|
+
async handleTurnTerminal(event, context) {
|
|
41665
|
+
await this.contain("turn terminal", async () => {
|
|
41666
|
+
if (this.settledOperations.has(event.idempotencyKey)) {
|
|
41667
|
+
context.state.set(void 0);
|
|
41668
|
+
return;
|
|
41669
|
+
}
|
|
41670
|
+
const error = event.type === "turn.failed" ? event.error : void 0;
|
|
41671
|
+
this.drainActionsForTurn(event.sessionId, event.turnId, error);
|
|
41672
|
+
const stored = storedSpan(context);
|
|
41673
|
+
if (stored && "exported" in stored) {
|
|
41674
|
+
updateSpan({
|
|
41675
|
+
exported: stored.exported,
|
|
41676
|
+
...error !== void 0 ? { error } : {},
|
|
41677
|
+
metrics: { end: Date.now() / 1e3 }
|
|
41678
|
+
});
|
|
41679
|
+
}
|
|
41680
|
+
this.settledOperations.set(event.idempotencyKey, true);
|
|
41681
|
+
context.state.set(void 0);
|
|
41682
|
+
this.turns.delete(turnKey3(event.sessionId, event.turnId));
|
|
41683
|
+
});
|
|
41684
|
+
}
|
|
41685
|
+
async handleModelStarted(event, context) {
|
|
41686
|
+
await this.contain("model start", async () => {
|
|
41687
|
+
if (this.settledOperations.has(event.idempotencyKey)) {
|
|
41688
|
+
context.state.set({ skip: true });
|
|
41689
|
+
return;
|
|
41690
|
+
}
|
|
41691
|
+
const parent = await this.parentForScope(event.scope);
|
|
41692
|
+
const { rowId, spanId } = await generateEveIds(
|
|
41693
|
+
"step",
|
|
41694
|
+
event.idempotencyKey
|
|
41695
|
+
);
|
|
41696
|
+
const input = event.input ? capturedModelInput(event.input) : void 0;
|
|
41697
|
+
const metadata = {
|
|
41698
|
+
...this.spanMetadata(event.scope.sessionId),
|
|
41699
|
+
model: event.model.modelId,
|
|
41700
|
+
provider: event.model.provider
|
|
41701
|
+
};
|
|
41702
|
+
const span = await this.startSpan(context, {
|
|
41703
|
+
event: {
|
|
41704
|
+
id: rowId,
|
|
41705
|
+
...input !== void 0 ? { input } : {},
|
|
41706
|
+
metadata
|
|
41707
|
+
},
|
|
41708
|
+
name: "eve.step",
|
|
41709
|
+
parentSpanIds: parent,
|
|
41710
|
+
spanAttributes: { type: "llm" /* LLM */ },
|
|
41711
|
+
spanId
|
|
41712
|
+
});
|
|
41713
|
+
if (!span) return;
|
|
41714
|
+
span.log({ ...input !== void 0 ? { input } : {}, metadata });
|
|
41715
|
+
this.activeModels.set(event.idempotencyKey, {
|
|
41716
|
+
span,
|
|
41717
|
+
turnKey: turnKey3(event.scope.sessionId, event.scope.turnId)
|
|
41718
|
+
});
|
|
41719
|
+
const keys = this.modelsByAttempt.get(event.scope.attemptId) ?? /* @__PURE__ */ new Set();
|
|
41720
|
+
keys.add(event.idempotencyKey);
|
|
41721
|
+
this.modelsByAttempt.set(event.scope.attemptId, keys);
|
|
41722
|
+
});
|
|
41723
|
+
}
|
|
41724
|
+
async handleModelTerminal(event, context) {
|
|
41725
|
+
await this.contain("model terminal", async () => {
|
|
41726
|
+
if (this.settledOperations.has(event.idempotencyKey)) {
|
|
41727
|
+
context.state.set(void 0);
|
|
41728
|
+
return;
|
|
41729
|
+
}
|
|
41730
|
+
const active = this.activeModels.get(event.idempotencyKey);
|
|
41731
|
+
if (active) {
|
|
41732
|
+
const span = active.span;
|
|
41733
|
+
if (event.type === "model.call.failed") {
|
|
41734
|
+
if (event.error !== void 0) span.log({ error: event.error });
|
|
41735
|
+
} else {
|
|
41736
|
+
span.log({
|
|
41737
|
+
metrics: usageMetrics(event.usage),
|
|
41738
|
+
output: modelOutput(event)
|
|
41739
|
+
});
|
|
41740
|
+
}
|
|
41741
|
+
span.end();
|
|
41742
|
+
} else {
|
|
41743
|
+
const stored = storedSpan(context);
|
|
41744
|
+
if (stored && "exported" in stored) {
|
|
41745
|
+
updateSpan({
|
|
41746
|
+
exported: stored.exported,
|
|
41747
|
+
...event.type === "model.call.failed" ? event.error !== void 0 ? { error: event.error } : {} : { output: modelOutput(event) },
|
|
41748
|
+
metrics: {
|
|
41749
|
+
...event.type === "model.call.completed" ? usageMetrics(event.usage) : {},
|
|
41750
|
+
end: Date.now() / 1e3
|
|
41751
|
+
}
|
|
41752
|
+
});
|
|
41753
|
+
}
|
|
41754
|
+
}
|
|
41755
|
+
this.settledOperations.set(event.idempotencyKey, true);
|
|
41756
|
+
this.forgetModel(event.scope.attemptId, event.idempotencyKey);
|
|
41757
|
+
context.state.set(void 0);
|
|
41758
|
+
});
|
|
41759
|
+
}
|
|
41760
|
+
async handleActionStarted(event, context) {
|
|
41761
|
+
await this.contain("action start", async () => {
|
|
41762
|
+
if (event.kind === "load-skill" || this.settledOperations.has(event.idempotencyKey)) {
|
|
41763
|
+
context.state.set({ skip: true });
|
|
41764
|
+
return;
|
|
41765
|
+
}
|
|
41766
|
+
const parent = await this.parentForScope(event.scope);
|
|
41767
|
+
const { rowId, spanId } = await generateEveIds(
|
|
41768
|
+
event.kind === "subagent-call" ? "subagent" : "tool",
|
|
41769
|
+
event.idempotencyKey
|
|
41770
|
+
);
|
|
41771
|
+
const metadata = {
|
|
41772
|
+
...this.spanMetadata(event.scope.sessionId),
|
|
41773
|
+
"eve.action_kind": event.kind
|
|
41774
|
+
};
|
|
41775
|
+
const span = await this.startSpan(context, {
|
|
41776
|
+
event: {
|
|
41777
|
+
id: rowId,
|
|
41778
|
+
...event.input !== void 0 ? { input: event.input } : {},
|
|
41779
|
+
metadata
|
|
41780
|
+
},
|
|
41781
|
+
name: event.name,
|
|
41782
|
+
parentSpanIds: parent,
|
|
41783
|
+
spanAttributes: { type: "tool" /* TOOL */ },
|
|
41784
|
+
spanId
|
|
41785
|
+
});
|
|
41786
|
+
if (!span) return;
|
|
41787
|
+
span.log({
|
|
41788
|
+
...event.input !== void 0 ? { input: event.input } : {},
|
|
41789
|
+
metadata
|
|
41790
|
+
});
|
|
41791
|
+
this.activeActions.set(event.idempotencyKey, {
|
|
41792
|
+
span,
|
|
41793
|
+
turnKey: turnKey3(event.scope.sessionId, event.scope.turnId)
|
|
41794
|
+
});
|
|
41795
|
+
});
|
|
41796
|
+
}
|
|
41797
|
+
async handleActionTerminal(event, context) {
|
|
41798
|
+
await this.contain("action terminal", async () => {
|
|
41799
|
+
if (this.settledOperations.has(event.idempotencyKey)) {
|
|
41800
|
+
context.state.set(void 0);
|
|
41801
|
+
return;
|
|
41802
|
+
}
|
|
41803
|
+
const stored = storedSpan(context);
|
|
41804
|
+
if (stored?.skip) {
|
|
41805
|
+
context.state.set(void 0);
|
|
41806
|
+
return;
|
|
41807
|
+
}
|
|
41808
|
+
const active = this.activeActions.get(event.idempotencyKey);
|
|
41809
|
+
const end = finiteTimestamp(event.acceptedAtMs) ?? Date.now();
|
|
41810
|
+
if (active) {
|
|
41811
|
+
const span = active.span;
|
|
41812
|
+
if (event.type === "action.failed") {
|
|
41813
|
+
span.log({
|
|
41814
|
+
error: event.error ?? new Error(event.errorCode ?? `Eve action ${event.outcome}`)
|
|
41815
|
+
});
|
|
41816
|
+
} else if (event.output.type === "error") {
|
|
41817
|
+
span.log({
|
|
41818
|
+
error: event.output.error ?? new Error("Eve action returned an error")
|
|
41819
|
+
});
|
|
41820
|
+
} else {
|
|
41821
|
+
span.log({ output: event.output.output });
|
|
41822
|
+
}
|
|
41823
|
+
span.end({ endTime: end / 1e3 });
|
|
41824
|
+
} else {
|
|
41825
|
+
const stored2 = storedSpan(context);
|
|
41826
|
+
if (stored2 && "exported" in stored2) {
|
|
41827
|
+
updateSpan({
|
|
41828
|
+
exported: stored2.exported,
|
|
41829
|
+
...event.type === "action.failed" ? {
|
|
41830
|
+
error: event.error ?? new Error(event.errorCode ?? `Eve action ${event.outcome}`)
|
|
41831
|
+
} : event.output.type === "error" ? {
|
|
41832
|
+
error: event.output.error ?? new Error("Eve action returned an error")
|
|
41833
|
+
} : { output: event.output.output },
|
|
41834
|
+
metrics: { end: end / 1e3 }
|
|
41835
|
+
});
|
|
41836
|
+
}
|
|
41837
|
+
}
|
|
41838
|
+
this.settledOperations.set(event.idempotencyKey, true);
|
|
41839
|
+
this.activeActions.delete(event.idempotencyKey);
|
|
41840
|
+
context.state.set(void 0);
|
|
41841
|
+
});
|
|
41842
|
+
}
|
|
41843
|
+
handleStepAttemptTerminal(event) {
|
|
41844
|
+
void this.contain("step attempt terminal", () => {
|
|
41845
|
+
const keys = this.modelsByAttempt.get(event.scope.attemptId);
|
|
41846
|
+
if (!keys) return;
|
|
41847
|
+
for (const key of keys) {
|
|
41848
|
+
const active = this.activeModels.get(key);
|
|
41849
|
+
if (!active) continue;
|
|
41850
|
+
if (event.type === "step.attempt.failed" && event.error !== void 0) {
|
|
41851
|
+
active.span.log({ error: event.error });
|
|
41852
|
+
}
|
|
41853
|
+
active.span.end();
|
|
41854
|
+
this.activeModels.delete(key);
|
|
41855
|
+
}
|
|
41856
|
+
this.modelsByAttempt.delete(event.scope.attemptId);
|
|
41857
|
+
});
|
|
41858
|
+
}
|
|
41859
|
+
async parentForScope(scope) {
|
|
41860
|
+
const key = turnKey3(scope.sessionId, scope.turnId);
|
|
41861
|
+
const known = this.turns.get(key);
|
|
41862
|
+
if (known) {
|
|
41863
|
+
return { rootSpanId: known.rootSpanId, spanId: known.spanId };
|
|
41864
|
+
}
|
|
41865
|
+
const [{ spanId }, { spanId: rootSpanId }] = await Promise.all([
|
|
41866
|
+
generateEveIds("turn", turnIdempotencyKey(scope.sessionId, scope.turnId)),
|
|
41867
|
+
generateEveIds(
|
|
41868
|
+
"turn",
|
|
41869
|
+
turnIdempotencyKey(
|
|
41870
|
+
scope.rootSessionId ?? scope.sessionId,
|
|
41871
|
+
scope.turnId
|
|
41872
|
+
)
|
|
41873
|
+
)
|
|
41874
|
+
]);
|
|
41875
|
+
return { rootSpanId, spanId };
|
|
41876
|
+
}
|
|
41877
|
+
async startSpan(context, args, rootSpanId) {
|
|
41878
|
+
const span = withCurrent(
|
|
41879
|
+
NOOP_SPAN,
|
|
41880
|
+
() => _internalStartSpanWithInitialMerge(
|
|
41881
|
+
withSpanInstrumentationName(args ?? {}, INSTRUMENTATION_NAMES.EVE)
|
|
41882
|
+
)
|
|
41883
|
+
);
|
|
41884
|
+
try {
|
|
41885
|
+
context.state.set({
|
|
41886
|
+
exported: await span.export(),
|
|
41887
|
+
...rootSpanId ? { rootSpanId } : {}
|
|
41888
|
+
});
|
|
41889
|
+
} catch (error) {
|
|
41890
|
+
debugLogger.warn("Error exporting Eve provider span:", error);
|
|
41891
|
+
}
|
|
41892
|
+
return span;
|
|
41893
|
+
}
|
|
41894
|
+
drainActionsForTurn(sessionId, turnId, error) {
|
|
41895
|
+
const key = turnKey3(sessionId, turnId);
|
|
41896
|
+
for (const [idempotencyKey, active] of this.activeActions) {
|
|
41897
|
+
if (active.turnKey !== key) continue;
|
|
41898
|
+
if (error !== void 0) active.span.log({ error });
|
|
41899
|
+
active.span.end();
|
|
41900
|
+
this.activeActions.delete(idempotencyKey);
|
|
41901
|
+
}
|
|
41902
|
+
}
|
|
41903
|
+
forgetModel(attemptId, idempotencyKey) {
|
|
41904
|
+
this.activeModels.delete(idempotencyKey);
|
|
41905
|
+
const keys = this.modelsByAttempt.get(attemptId);
|
|
41906
|
+
keys?.delete(idempotencyKey);
|
|
41907
|
+
if (keys?.size === 0) this.modelsByAttempt.delete(attemptId);
|
|
41908
|
+
}
|
|
41909
|
+
spanMetadata(sessionId) {
|
|
41910
|
+
return {
|
|
41911
|
+
...this.metadata ?? {},
|
|
41912
|
+
"eve.session_id": sessionId
|
|
41913
|
+
};
|
|
41914
|
+
}
|
|
41915
|
+
async contain(operation, fn) {
|
|
41916
|
+
try {
|
|
41917
|
+
await fn();
|
|
41918
|
+
} catch (error) {
|
|
41919
|
+
debugLogger.warn(`Error in Eve provider ${operation}:`, error);
|
|
41920
|
+
}
|
|
41921
|
+
}
|
|
41922
|
+
};
|
|
41923
|
+
function storedSpan(context) {
|
|
41924
|
+
const value = context.state.get();
|
|
41925
|
+
if (!isObject(value)) return void 0;
|
|
41926
|
+
if (value["skip"] === true) return { skip: true };
|
|
41927
|
+
return typeof value["exported"] === "string" ? {
|
|
41928
|
+
exported: value["exported"],
|
|
41929
|
+
...typeof value["rootSpanId"] === "string" && value["rootSpanId"].length > 0 ? { rootSpanId: value["rootSpanId"] } : {}
|
|
41930
|
+
} : void 0;
|
|
41931
|
+
}
|
|
41932
|
+
function modelOutput(event) {
|
|
41933
|
+
const content = event.content ?? [];
|
|
41934
|
+
let text = "";
|
|
41935
|
+
const reasoning = [];
|
|
41936
|
+
const toolCalls2 = [];
|
|
41937
|
+
for (const part of content) {
|
|
41938
|
+
if (part.type === "text") {
|
|
41939
|
+
text += part.text;
|
|
41940
|
+
} else if (part.type === "reasoning" && part.text.trim().length > 0) {
|
|
41941
|
+
reasoning.push({ content: part.text });
|
|
41942
|
+
} else if (part.type === "tool-call") {
|
|
41943
|
+
toolCalls2.push({
|
|
41944
|
+
function: {
|
|
41945
|
+
arguments: safeJsonStringify(part.input),
|
|
41946
|
+
name: part.toolName
|
|
41947
|
+
},
|
|
41948
|
+
id: part.callId,
|
|
41949
|
+
type: "function"
|
|
41950
|
+
});
|
|
41951
|
+
}
|
|
41952
|
+
}
|
|
41953
|
+
return [
|
|
41954
|
+
{
|
|
41955
|
+
finish_reason: normalizeFinishReason3(event.finishReason),
|
|
41956
|
+
index: 0,
|
|
41957
|
+
message: {
|
|
41958
|
+
content: text || null,
|
|
41959
|
+
...reasoning.length > 0 ? { reasoning } : {},
|
|
41960
|
+
role: "assistant",
|
|
41961
|
+
...toolCalls2.length > 0 ? { tool_calls: toolCalls2 } : {}
|
|
41962
|
+
}
|
|
41963
|
+
}
|
|
41964
|
+
];
|
|
41965
|
+
}
|
|
41966
|
+
function usageMetrics(usage) {
|
|
41967
|
+
const promptTokens = nonNegativeNumber(usage.inputTokens);
|
|
41968
|
+
const completionTokens = nonNegativeNumber(usage.outputTokens);
|
|
41969
|
+
const cachedTokens = nonNegativeNumber(
|
|
41970
|
+
usage.inputTokenDetails?.cacheReadTokens
|
|
41971
|
+
);
|
|
41972
|
+
const cacheCreationTokens = nonNegativeNumber(
|
|
41973
|
+
usage.inputTokenDetails?.cacheWriteTokens
|
|
41974
|
+
);
|
|
41975
|
+
return {
|
|
41976
|
+
...promptTokens !== void 0 ? { prompt_tokens: promptTokens } : {},
|
|
41977
|
+
...completionTokens !== void 0 ? { completion_tokens: completionTokens } : {},
|
|
41978
|
+
...promptTokens !== void 0 && completionTokens !== void 0 ? { tokens: promptTokens + completionTokens } : {},
|
|
41979
|
+
...cachedTokens !== void 0 ? { prompt_cached_tokens: cachedTokens } : {},
|
|
41980
|
+
...cacheCreationTokens !== void 0 ? { prompt_cache_creation_tokens: cacheCreationTokens } : {}
|
|
41981
|
+
};
|
|
41982
|
+
}
|
|
41983
|
+
function nonNegativeNumber(value) {
|
|
41984
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : void 0;
|
|
41985
|
+
}
|
|
41986
|
+
function finiteTimestamp(value) {
|
|
41987
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
41988
|
+
}
|
|
41989
|
+
function normalizeFinishReason3(value) {
|
|
41990
|
+
if (value === "content-filter") return "content_filter";
|
|
41991
|
+
if (value === "tool-calls") return "tool_calls";
|
|
41992
|
+
return value;
|
|
41993
|
+
}
|
|
41994
|
+
function safeJsonStringify(value) {
|
|
41995
|
+
try {
|
|
41996
|
+
return JSON.stringify(value) ?? "null";
|
|
41997
|
+
} catch {
|
|
41998
|
+
return "null";
|
|
41999
|
+
}
|
|
42000
|
+
}
|
|
42001
|
+
function turnKey3(sessionId, turnId) {
|
|
42002
|
+
return `${sessionId}:${turnId}`;
|
|
42003
|
+
}
|
|
42004
|
+
function turnIdempotencyKey(sessionId, turnId) {
|
|
42005
|
+
return `turn:${sessionId}:${turnId}`;
|
|
42006
|
+
}
|
|
42007
|
+
function actionIdempotencyKey(sessionId, turnId, callId) {
|
|
42008
|
+
return `action:${sessionId}:${turnId}:${callId}`;
|
|
42009
|
+
}
|
|
42010
|
+
|
|
42011
|
+
// src/instrumentation/plugins/eve-instrumentation.ts
|
|
42012
|
+
var EVE_INSTRUMENTATION_PROVIDER = /* @__PURE__ */ Symbol.for("eve.instrumentation.provider");
|
|
42013
|
+
function braintrustEveInstrumentation(options) {
|
|
42014
|
+
const definition = "defineState" in options ? createLegacyEveInstrumentation(options) : createEveInstrumentationProvider(options);
|
|
42015
|
+
const declaration = {
|
|
42016
|
+
...definition,
|
|
42017
|
+
[EVE_INSTRUMENTATION_PROVIDER]: true
|
|
42018
|
+
};
|
|
42019
|
+
return declaration;
|
|
42020
|
+
}
|
|
42021
|
+
|
|
40357
42022
|
// src/typed-instrumentation-helpers.ts
|
|
40358
42023
|
var TypedApplyProxy = Proxy;
|
|
40359
42024
|
|
|
@@ -40755,11 +42420,11 @@ function wrapClaudeAgentQuery(queryFn, defaultThis) {
|
|
|
40755
42420
|
}
|
|
40756
42421
|
};
|
|
40757
42422
|
const invocationTarget = thisArg === proxy || thisArg === void 0 ? defaultThis ?? thisArg : thisArg;
|
|
40758
|
-
return claudeAgentSDKChannels.query.
|
|
40759
|
-
|
|
40760
|
-
|
|
40761
|
-
|
|
40762
|
-
{
|
|
42423
|
+
return claudeAgentSDKChannels.query.invoke(
|
|
42424
|
+
target,
|
|
42425
|
+
invocationTarget,
|
|
42426
|
+
[wrappedParams],
|
|
42427
|
+
{}
|
|
40763
42428
|
);
|
|
40764
42429
|
}
|
|
40765
42430
|
});
|
|
@@ -41374,13 +43039,11 @@ function wrapAgentInstance(agent) {
|
|
|
41374
43039
|
if (prop === "stream" && typeof value === "function") {
|
|
41375
43040
|
return function(args, options) {
|
|
41376
43041
|
const callArgs = [args, options];
|
|
41377
|
-
return strandsAgentSDKChannels.agentStream.
|
|
41378
|
-
|
|
41379
|
-
|
|
41380
|
-
|
|
41381
|
-
|
|
41382
|
-
self: proxy
|
|
41383
|
-
}
|
|
43042
|
+
return strandsAgentSDKChannels.agentStream.invoke(
|
|
43043
|
+
value,
|
|
43044
|
+
target,
|
|
43045
|
+
callArgs,
|
|
43046
|
+
{ agent: proxy }
|
|
41384
43047
|
);
|
|
41385
43048
|
};
|
|
41386
43049
|
}
|
|
@@ -41411,12 +43074,12 @@ function wrapMultiAgentInstance(orchestrator, kind) {
|
|
|
41411
43074
|
return function(input, options) {
|
|
41412
43075
|
const callArgs = [input, options];
|
|
41413
43076
|
const channel2 = kind === "graph" ? strandsAgentSDKChannels.graphStream : strandsAgentSDKChannels.swarmStream;
|
|
41414
|
-
return channel2.
|
|
41415
|
-
|
|
43077
|
+
return channel2.invoke(
|
|
43078
|
+
value,
|
|
43079
|
+
target,
|
|
43080
|
+
callArgs,
|
|
41416
43081
|
{
|
|
41417
|
-
|
|
41418
|
-
orchestrator: proxy,
|
|
41419
|
-
self: proxy
|
|
43082
|
+
orchestrator: proxy
|
|
41420
43083
|
}
|
|
41421
43084
|
);
|
|
41422
43085
|
};
|
|
@@ -43368,9 +45031,6 @@ var VitestContextManager = class {
|
|
|
43368
45031
|
getCurrentContext() {
|
|
43369
45032
|
return this.contextStorage.getStore();
|
|
43370
45033
|
}
|
|
43371
|
-
setContext(context) {
|
|
43372
|
-
this.contextStorage.enterWith(context);
|
|
43373
|
-
}
|
|
43374
45034
|
runInContext(context, callback) {
|
|
43375
45035
|
return this.contextStorage.run(context, callback);
|
|
43376
45036
|
}
|
|
@@ -43756,8 +45416,7 @@ function wrapDescribe(originalDescribe, config, afterAll) {
|
|
|
43756
45416
|
if (config.onProgress) {
|
|
43757
45417
|
config.onProgress({ type: "suite_start", suiteName });
|
|
43758
45418
|
}
|
|
43759
|
-
contextManager.
|
|
43760
|
-
factory();
|
|
45419
|
+
contextManager.runInContext(lazyContext, factory);
|
|
43761
45420
|
if (afterAll) {
|
|
43762
45421
|
afterAll(async () => {
|
|
43763
45422
|
await flushExperimentWithSync(context, config);
|