braintrust 3.11.0 → 3.12.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 +8 -8
- package/dev/dist/index.d.mts +1 -1
- package/dev/dist/index.d.ts +1 -1
- package/dev/dist/index.js +2607 -316
- package/dev/dist/index.mjs +2388 -97
- package/dist/apply-auto-instrumentation.browser.d.mts +2 -0
- package/dist/apply-auto-instrumentation.browser.d.ts +2 -0
- package/dist/apply-auto-instrumentation.browser.js +18 -0
- package/dist/apply-auto-instrumentation.browser.mjs +0 -0
- package/dist/apply-auto-instrumentation.d.mts +2 -0
- package/dist/apply-auto-instrumentation.d.ts +2 -0
- package/dist/apply-auto-instrumentation.js +2534 -0
- package/dist/apply-auto-instrumentation.mjs +2534 -0
- package/dist/auto-instrumentations/bundler/esbuild.cjs +1802 -1283
- package/dist/auto-instrumentations/bundler/esbuild.d.mts +9 -5
- package/dist/auto-instrumentations/bundler/esbuild.d.ts +9 -5
- package/dist/auto-instrumentations/bundler/esbuild.mjs +10 -2
- package/dist/auto-instrumentations/bundler/next.cjs +3268 -0
- package/dist/auto-instrumentations/bundler/next.d.mts +3 -0
- package/dist/auto-instrumentations/bundler/next.d.ts +3 -0
- package/dist/auto-instrumentations/bundler/next.mjs +189 -0
- package/dist/auto-instrumentations/bundler/rollup.cjs +1802 -1283
- package/dist/auto-instrumentations/bundler/rollup.d.mts +9 -5
- package/dist/auto-instrumentations/bundler/rollup.d.ts +9 -5
- package/dist/auto-instrumentations/bundler/rollup.mjs +10 -2
- package/dist/auto-instrumentations/bundler/vite.cjs +1802 -1283
- package/dist/auto-instrumentations/bundler/vite.d.mts +9 -5
- package/dist/auto-instrumentations/bundler/vite.d.ts +9 -5
- package/dist/auto-instrumentations/bundler/vite.mjs +10 -2
- package/dist/auto-instrumentations/bundler/webpack-loader.cjs +1860 -1308
- package/dist/auto-instrumentations/bundler/webpack-loader.d.ts +3 -3
- package/dist/auto-instrumentations/bundler/webpack.cjs +1802 -1283
- package/dist/auto-instrumentations/bundler/webpack.d.mts +9 -5
- package/dist/auto-instrumentations/bundler/webpack.d.ts +9 -5
- package/dist/auto-instrumentations/bundler/webpack.mjs +6 -6
- package/dist/auto-instrumentations/{chunk-DIV5TO4S.mjs → chunk-2DPA74KK.mjs} +337 -1
- package/dist/auto-instrumentations/chunk-73BZUKVI.mjs +300 -0
- package/dist/auto-instrumentations/chunk-AFXRW7I7.mjs +18 -0
- package/dist/auto-instrumentations/hook.mjs +1712 -1460
- package/dist/auto-instrumentations/index.cjs +93 -0
- package/dist/auto-instrumentations/index.d.mts +5 -1
- package/dist/auto-instrumentations/index.d.ts +5 -1
- package/dist/auto-instrumentations/index.mjs +6 -247
- package/dist/auto-instrumentations/loader/esm-hook.mjs +19 -2
- package/dist/auto-instrumentations/plugin-D7nDswtC.d.mts +44 -0
- package/dist/auto-instrumentations/plugin-D7nDswtC.d.ts +44 -0
- package/dist/browser.d.mts +120 -31
- package/dist/browser.d.ts +120 -31
- package/dist/browser.js +2395 -123
- package/dist/browser.mjs +2395 -123
- package/dist/chunk-BW4DF4CY.js +816 -0
- package/dist/chunk-MSLBGITU.mjs +816 -0
- package/dist/cli.js +2407 -96
- package/dist/edge-light.d.mts +1 -1
- package/dist/edge-light.d.ts +1 -1
- package/dist/edge-light.js +2395 -123
- package/dist/edge-light.mjs +2395 -123
- package/dist/index.d.mts +120 -31
- package/dist/index.d.ts +120 -31
- package/dist/index.js +3362 -1849
- package/dist/index.mjs +2505 -992
- package/dist/instrumentation/index.d.mts +7860 -48
- package/dist/instrumentation/index.d.ts +7860 -48
- package/dist/instrumentation/index.js +2395 -95
- package/dist/instrumentation/index.mjs +2394 -95
- package/dist/workerd.d.mts +1 -1
- package/dist/workerd.d.ts +1 -1
- package/dist/workerd.js +2395 -123
- package/dist/workerd.mjs +2395 -123
- package/package.json +23 -3
- package/util/dist/index.js +6 -0
- package/util/dist/index.mjs +6 -0
- package/dist/auto-instrumentations/chunk-G6ZWXGZB.mjs +0 -116
- package/dist/auto-instrumentations/plugin-Df3qKIl2.d.mts +0 -22
- package/dist/auto-instrumentations/plugin-Df3qKIl2.d.ts +0 -22
package/dist/cli.js
CHANGED
|
@@ -1232,7 +1232,7 @@ var require_package = __commonJS({
|
|
|
1232
1232
|
"package.json"(exports2, module2) {
|
|
1233
1233
|
module2.exports = {
|
|
1234
1234
|
name: "braintrust",
|
|
1235
|
-
version: "3.
|
|
1235
|
+
version: "3.12.0",
|
|
1236
1236
|
description: "SDK for integrating Braintrust",
|
|
1237
1237
|
repository: {
|
|
1238
1238
|
type: "git",
|
|
@@ -1243,6 +1243,7 @@ var require_package = __commonJS({
|
|
|
1243
1243
|
main: "./dist/index.js",
|
|
1244
1244
|
module: "./dist/index.mjs",
|
|
1245
1245
|
types: "./dist/index.d.ts",
|
|
1246
|
+
sideEffects: true,
|
|
1246
1247
|
browser: {
|
|
1247
1248
|
"./dist/index.js": "./dist/browser.js",
|
|
1248
1249
|
"./dist/index.d.ts": "./dist/browser.d.ts",
|
|
@@ -1282,6 +1283,19 @@ var require_package = __commonJS({
|
|
|
1282
1283
|
require: "./dist/browser.js",
|
|
1283
1284
|
default: "./dist/browser.mjs"
|
|
1284
1285
|
},
|
|
1286
|
+
"./apply-auto-instrumentation": {
|
|
1287
|
+
types: "./dist/apply-auto-instrumentation.d.ts",
|
|
1288
|
+
"edge-light": "./dist/apply-auto-instrumentation.browser.mjs",
|
|
1289
|
+
workerd: "./dist/apply-auto-instrumentation.browser.mjs",
|
|
1290
|
+
node: {
|
|
1291
|
+
import: "./dist/apply-auto-instrumentation.mjs",
|
|
1292
|
+
require: "./dist/apply-auto-instrumentation.js"
|
|
1293
|
+
},
|
|
1294
|
+
browser: "./dist/apply-auto-instrumentation.browser.mjs",
|
|
1295
|
+
import: "./dist/apply-auto-instrumentation.mjs",
|
|
1296
|
+
require: "./dist/apply-auto-instrumentation.js",
|
|
1297
|
+
default: "./dist/apply-auto-instrumentation.mjs"
|
|
1298
|
+
},
|
|
1285
1299
|
"./node": {
|
|
1286
1300
|
types: "./dist/index.d.ts",
|
|
1287
1301
|
import: "./dist/index.mjs",
|
|
@@ -1319,6 +1333,12 @@ var require_package = __commonJS({
|
|
|
1319
1333
|
module: "./dist/auto-instrumentations/bundler/webpack.mjs",
|
|
1320
1334
|
require: "./dist/auto-instrumentations/bundler/webpack.cjs"
|
|
1321
1335
|
},
|
|
1336
|
+
"./next": {
|
|
1337
|
+
types: "./dist/auto-instrumentations/bundler/next.d.ts",
|
|
1338
|
+
import: "./dist/auto-instrumentations/bundler/next.mjs",
|
|
1339
|
+
module: "./dist/auto-instrumentations/bundler/next.mjs",
|
|
1340
|
+
require: "./dist/auto-instrumentations/bundler/next.cjs"
|
|
1341
|
+
},
|
|
1322
1342
|
"./webpack-loader": {
|
|
1323
1343
|
types: "./dist/auto-instrumentations/bundler/webpack-loader.d.ts",
|
|
1324
1344
|
require: "./dist/auto-instrumentations/bundler/webpack-loader.cjs"
|
|
@@ -1350,7 +1370,8 @@ var require_package = __commonJS({
|
|
|
1350
1370
|
test: 'vitest run --exclude "src/wrappers/**/*.test.ts" --exclude "src/otel/**/*.test.ts" --exclude "smoke/**/*.test.ts" --exclude "src/zod/**/*.test.ts" --exclude "tests/api-compatibility/**"',
|
|
1351
1371
|
"test:core": "pnpm prune && pnpm test",
|
|
1352
1372
|
"test:checks": "pnpm run test:core && pnpm run test:vitest",
|
|
1353
|
-
"test:external": "pnpm run test:external:
|
|
1373
|
+
"test:external": "pnpm run test:external:sequential && node scripts/run-parallel.mjs test:external:ai-sdk-v5 test:external:ai-sdk-v6 test:external:claude-agent-sdk",
|
|
1374
|
+
"test:external:sequential": "pnpm run test:external:openai && pnpm run test:external:anthropic && pnpm run test:external:google-genai",
|
|
1354
1375
|
"test:external:openai": "bash scripts/test-provider.sh test:openai openai",
|
|
1355
1376
|
"test:external:anthropic": "bash scripts/test-provider.sh test:anthropic @anthropic-ai/sdk",
|
|
1356
1377
|
"test:external:google-genai": "bash scripts/test-provider.sh test:google-genai @google/genai",
|
|
@@ -1411,7 +1432,6 @@ var require_package = __commonJS({
|
|
|
1411
1432
|
"cross-env": "^7.0.3",
|
|
1412
1433
|
"eslint-plugin-node-import": "^1.0.5",
|
|
1413
1434
|
openai: "6.25.0",
|
|
1414
|
-
"openapi-zod-client": "^1.18.3",
|
|
1415
1435
|
rollup: "^4.60.3",
|
|
1416
1436
|
tar: "^7.5.2",
|
|
1417
1437
|
tinybench: "^4.0.1",
|
|
@@ -2405,6 +2425,11 @@ function isPromiseLike(value) {
|
|
|
2405
2425
|
|
|
2406
2426
|
// util/object_util.ts
|
|
2407
2427
|
var SET_UNION_FIELDS = /* @__PURE__ */ new Set(["tags"]);
|
|
2428
|
+
var FORBIDDEN_MERGE_KEYS = /* @__PURE__ */ new Set([
|
|
2429
|
+
"__proto__",
|
|
2430
|
+
"constructor",
|
|
2431
|
+
"prototype"
|
|
2432
|
+
]);
|
|
2408
2433
|
function mergeDictsWithPaths({
|
|
2409
2434
|
mergeInto,
|
|
2410
2435
|
mergeFrom,
|
|
@@ -2427,6 +2452,7 @@ function mergeDictsWithPathsHelper({
|
|
|
2427
2452
|
mergePaths
|
|
2428
2453
|
}) {
|
|
2429
2454
|
Object.entries(mergeFrom).forEach(([k, mergeFromV]) => {
|
|
2455
|
+
if (FORBIDDEN_MERGE_KEYS.has(k)) return;
|
|
2430
2456
|
const fullPath = path8.concat([k]);
|
|
2431
2457
|
const fullPathSerialized = JSON.stringify(fullPath);
|
|
2432
2458
|
const mergeIntoV = recordFind(mergeInto, k);
|
|
@@ -6490,6 +6516,13 @@ var HTTPConnection = class _HTTPConnection {
|
|
|
6490
6516
|
debugLogger.debug(
|
|
6491
6517
|
`Retrying API request ${object_type} ${JSON.stringify(args)} ${e.status} ${e.text}`
|
|
6492
6518
|
);
|
|
6519
|
+
const sleepTimeS = HTTP_RETRY_BASE_SLEEP_TIME_S * 2 ** i;
|
|
6520
|
+
debugLogger.info(
|
|
6521
|
+
`Sleeping for ${sleepTimeS}s before retrying API request`
|
|
6522
|
+
);
|
|
6523
|
+
await new Promise(
|
|
6524
|
+
(resolve2) => setTimeout(resolve2, sleepTimeS * 1e3)
|
|
6525
|
+
);
|
|
6493
6526
|
continue;
|
|
6494
6527
|
}
|
|
6495
6528
|
throw e;
|
|
@@ -7012,20 +7045,7 @@ function startSpanParentArgs(args) {
|
|
|
7012
7045
|
`Mismatch between expected span parent object type ${args.parentObjectType} and provided type ${parentComponents.data.object_type}`
|
|
7013
7046
|
);
|
|
7014
7047
|
}
|
|
7015
|
-
|
|
7016
|
-
args.state,
|
|
7017
|
-
parentComponents
|
|
7018
|
-
);
|
|
7019
|
-
const computeParentObjectId = async () => {
|
|
7020
|
-
const parentComponentsObjectId = await parentComponentsObjectIdLambda();
|
|
7021
|
-
if (await args.parentObjectId.get() !== parentComponentsObjectId) {
|
|
7022
|
-
throw new Error(
|
|
7023
|
-
`Mismatch between expected span parent object id ${await args.parentObjectId.get()} and provided id ${parentComponentsObjectId}`
|
|
7024
|
-
);
|
|
7025
|
-
}
|
|
7026
|
-
return await args.parentObjectId.get();
|
|
7027
|
-
};
|
|
7028
|
-
argParentObjectId = new LazyValue(computeParentObjectId);
|
|
7048
|
+
argParentObjectId = args.parentObjectId;
|
|
7029
7049
|
if (parentComponents.data.row_id) {
|
|
7030
7050
|
argParentSpanIds = {
|
|
7031
7051
|
spanId: parentComponents.data.span_id,
|
|
@@ -7354,6 +7374,7 @@ function now() {
|
|
|
7354
7374
|
}
|
|
7355
7375
|
var DEFAULT_FLUSH_BACKPRESSURE_BYTES = 10 * 1024 * 1024;
|
|
7356
7376
|
var BACKGROUND_LOGGER_BASE_SLEEP_TIME_S = 1;
|
|
7377
|
+
var HTTP_RETRY_BASE_SLEEP_TIME_S = 1;
|
|
7357
7378
|
var HTTPBackgroundLogger = class _HTTPBackgroundLogger {
|
|
7358
7379
|
apiConn;
|
|
7359
7380
|
queue;
|
|
@@ -7984,17 +8005,10 @@ function init(projectOrOptions, optionalOptions) {
|
|
|
7984
8005
|
if (repoInfo2) {
|
|
7985
8006
|
return repoInfo2;
|
|
7986
8007
|
}
|
|
7987
|
-
|
|
7988
|
-
|
|
7989
|
-
|
|
7990
|
-
|
|
7991
|
-
};
|
|
7992
|
-
if (gitMetadataSettings) {
|
|
7993
|
-
mergedGitMetadataSettings = mergeGitMetadataSettings(
|
|
7994
|
-
mergedGitMetadataSettings,
|
|
7995
|
-
gitMetadataSettings
|
|
7996
|
-
);
|
|
7997
|
-
}
|
|
8008
|
+
const mergedGitMetadataSettings = state.gitMetadataSettings == null ? gitMetadataSettings ?? { collect: "none" } : mergeGitMetadataSettings(
|
|
8009
|
+
state.gitMetadataSettings,
|
|
8010
|
+
gitMetadataSettings ?? { collect: "all" }
|
|
8011
|
+
);
|
|
7998
8012
|
return await isomorph_default.getRepoInfo(mergedGitMetadataSettings);
|
|
7999
8013
|
})();
|
|
8000
8014
|
if (repoInfoArg) {
|
|
@@ -8376,6 +8390,55 @@ async function computeLoggerMetadata(state, {
|
|
|
8376
8390
|
};
|
|
8377
8391
|
}
|
|
8378
8392
|
}
|
|
8393
|
+
function initLogger(options = {}) {
|
|
8394
|
+
const {
|
|
8395
|
+
projectName,
|
|
8396
|
+
projectId,
|
|
8397
|
+
asyncFlush: asyncFlushArg,
|
|
8398
|
+
appUrl,
|
|
8399
|
+
apiKey,
|
|
8400
|
+
orgName,
|
|
8401
|
+
forceLogin,
|
|
8402
|
+
debugLogLevel,
|
|
8403
|
+
fetch: fetch2,
|
|
8404
|
+
state: stateArg
|
|
8405
|
+
} = options || {};
|
|
8406
|
+
const asyncFlush = asyncFlushArg === void 0 ? true : asyncFlushArg;
|
|
8407
|
+
const computeMetadataArgs = {
|
|
8408
|
+
project_name: projectName,
|
|
8409
|
+
project_id: projectId
|
|
8410
|
+
};
|
|
8411
|
+
const linkArgs = {
|
|
8412
|
+
org_name: orgName,
|
|
8413
|
+
app_url: appUrl,
|
|
8414
|
+
project_name: projectName,
|
|
8415
|
+
project_id: projectId
|
|
8416
|
+
};
|
|
8417
|
+
const state = stateArg ?? _globalState;
|
|
8418
|
+
state.setDebugLogLevel(debugLogLevel);
|
|
8419
|
+
state.enforceQueueSizeLimit(true);
|
|
8420
|
+
const lazyMetadata = new LazyValue(
|
|
8421
|
+
async () => {
|
|
8422
|
+
await state.login({
|
|
8423
|
+
orgName,
|
|
8424
|
+
apiKey,
|
|
8425
|
+
appUrl,
|
|
8426
|
+
forceLogin,
|
|
8427
|
+
fetch: fetch2
|
|
8428
|
+
});
|
|
8429
|
+
return computeLoggerMetadata(state, computeMetadataArgs);
|
|
8430
|
+
}
|
|
8431
|
+
);
|
|
8432
|
+
const ret = new Logger(state, lazyMetadata, {
|
|
8433
|
+
asyncFlush,
|
|
8434
|
+
computeMetadataArgs,
|
|
8435
|
+
linkArgs
|
|
8436
|
+
});
|
|
8437
|
+
if (options.setCurrent ?? true) {
|
|
8438
|
+
state.currentLogger = ret;
|
|
8439
|
+
}
|
|
8440
|
+
return ret;
|
|
8441
|
+
}
|
|
8379
8442
|
async function login(options = {}) {
|
|
8380
8443
|
const { forceLogin = false } = options || {};
|
|
8381
8444
|
if (!_internalGetGlobalState()) {
|
|
@@ -13398,11 +13461,11 @@ function truncateToByteLimit(s, byteLimit = 65536) {
|
|
|
13398
13461
|
return new TextDecoder().decode(truncated);
|
|
13399
13462
|
}
|
|
13400
13463
|
async function getRepoInfo(settings) {
|
|
13401
|
-
if (settings
|
|
13464
|
+
if (!settings || settings.collect === "none") {
|
|
13402
13465
|
return void 0;
|
|
13403
13466
|
}
|
|
13404
13467
|
const repo = await repoInfo();
|
|
13405
|
-
if (!repo ||
|
|
13468
|
+
if (!repo || settings.collect === "all") {
|
|
13406
13469
|
return repo;
|
|
13407
13470
|
}
|
|
13408
13471
|
let sanitized = {};
|
|
@@ -17099,11 +17162,11 @@ function resolveDenyOutputPaths(event, defaultDenyOutputPaths) {
|
|
|
17099
17162
|
if (Array.isArray(event?.denyOutputPaths)) {
|
|
17100
17163
|
return event.denyOutputPaths;
|
|
17101
17164
|
}
|
|
17102
|
-
const
|
|
17103
|
-
if (!
|
|
17165
|
+
const firstArgument2 = event?.arguments && event.arguments.length > 0 ? event.arguments[0] : void 0;
|
|
17166
|
+
if (!firstArgument2 || typeof firstArgument2 !== "object") {
|
|
17104
17167
|
return defaultDenyOutputPaths;
|
|
17105
17168
|
}
|
|
17106
|
-
const runtimeDenyOutputPaths =
|
|
17169
|
+
const runtimeDenyOutputPaths = firstArgument2[RUNTIME_DENY_OUTPUT_PATHS];
|
|
17107
17170
|
if (Array.isArray(runtimeDenyOutputPaths) && runtimeDenyOutputPaths.every((path8) => typeof path8 === "string")) {
|
|
17108
17171
|
return runtimeDenyOutputPaths;
|
|
17109
17172
|
}
|
|
@@ -20762,6 +20825,467 @@ function cleanMetrics2(metrics) {
|
|
|
20762
20825
|
return cleaned;
|
|
20763
20826
|
}
|
|
20764
20827
|
|
|
20828
|
+
// src/instrumentation/plugins/openai-agents-channels.ts
|
|
20829
|
+
var openAIAgentsCoreChannels = defineChannels("@openai/agents-core", {
|
|
20830
|
+
onTraceStart: channel({
|
|
20831
|
+
channelName: "tracing.processor.onTraceStart",
|
|
20832
|
+
kind: "async"
|
|
20833
|
+
}),
|
|
20834
|
+
onTraceEnd: channel({
|
|
20835
|
+
channelName: "tracing.processor.onTraceEnd",
|
|
20836
|
+
kind: "async"
|
|
20837
|
+
}),
|
|
20838
|
+
onSpanStart: channel({
|
|
20839
|
+
channelName: "tracing.processor.onSpanStart",
|
|
20840
|
+
kind: "async"
|
|
20841
|
+
}),
|
|
20842
|
+
onSpanEnd: channel({
|
|
20843
|
+
channelName: "tracing.processor.onSpanEnd",
|
|
20844
|
+
kind: "async"
|
|
20845
|
+
})
|
|
20846
|
+
});
|
|
20847
|
+
|
|
20848
|
+
// src/instrumentation/plugins/openai-agents-trace-processor.ts
|
|
20849
|
+
function isSpanData(spanData, type) {
|
|
20850
|
+
return spanData.type === type;
|
|
20851
|
+
}
|
|
20852
|
+
function spanTypeFromAgents(span) {
|
|
20853
|
+
const spanType = span.spanData.type;
|
|
20854
|
+
if (spanType === "function" || spanType === "guardrail" || spanType === "mcp_tools") {
|
|
20855
|
+
return "tool" /* TOOL */;
|
|
20856
|
+
}
|
|
20857
|
+
if (spanType === "generation" || spanType === "response" || spanType === "transcription" || spanType === "speech") {
|
|
20858
|
+
return "llm" /* LLM */;
|
|
20859
|
+
}
|
|
20860
|
+
return "task" /* TASK */;
|
|
20861
|
+
}
|
|
20862
|
+
function spanNameFromAgents(span) {
|
|
20863
|
+
const spanData = span.spanData;
|
|
20864
|
+
if ("name" in spanData && spanData.name) {
|
|
20865
|
+
return spanData.name;
|
|
20866
|
+
}
|
|
20867
|
+
switch (spanData.type) {
|
|
20868
|
+
case "generation":
|
|
20869
|
+
return "Generation";
|
|
20870
|
+
case "response":
|
|
20871
|
+
return "Response";
|
|
20872
|
+
case "handoff":
|
|
20873
|
+
return "Handoff";
|
|
20874
|
+
case "mcp_tools":
|
|
20875
|
+
return isSpanData(spanData, "mcp_tools") && spanData.server ? `List Tools (${spanData.server})` : "MCP List Tools";
|
|
20876
|
+
case "transcription":
|
|
20877
|
+
return "Transcription";
|
|
20878
|
+
case "speech":
|
|
20879
|
+
return "Speech";
|
|
20880
|
+
case "speech_group":
|
|
20881
|
+
return "Speech Group";
|
|
20882
|
+
default:
|
|
20883
|
+
return "Unknown";
|
|
20884
|
+
}
|
|
20885
|
+
}
|
|
20886
|
+
function getTimeElapsed(end, start) {
|
|
20887
|
+
if (!start || !end) {
|
|
20888
|
+
return void 0;
|
|
20889
|
+
}
|
|
20890
|
+
const startTime = new Date(start).getTime();
|
|
20891
|
+
const endTime = new Date(end).getTime();
|
|
20892
|
+
if (Number.isNaN(startTime) || Number.isNaN(endTime)) {
|
|
20893
|
+
return void 0;
|
|
20894
|
+
}
|
|
20895
|
+
return (endTime - startTime) / 1e3;
|
|
20896
|
+
}
|
|
20897
|
+
function getNumberProperty2(obj, key) {
|
|
20898
|
+
if (!isObject(obj) || !(key in obj)) {
|
|
20899
|
+
return void 0;
|
|
20900
|
+
}
|
|
20901
|
+
const value = obj[key];
|
|
20902
|
+
return typeof value === "number" ? value : void 0;
|
|
20903
|
+
}
|
|
20904
|
+
function parseUsageMetrics(usage) {
|
|
20905
|
+
const metrics = {};
|
|
20906
|
+
if (!isObject(usage)) {
|
|
20907
|
+
return metrics;
|
|
20908
|
+
}
|
|
20909
|
+
const promptTokens = getNumberProperty2(usage, "prompt_tokens") ?? getNumberProperty2(usage, "input_tokens") ?? getNumberProperty2(usage, "promptTokens") ?? getNumberProperty2(usage, "inputTokens");
|
|
20910
|
+
const completionTokens = getNumberProperty2(usage, "completion_tokens") ?? getNumberProperty2(usage, "output_tokens") ?? getNumberProperty2(usage, "completionTokens") ?? getNumberProperty2(usage, "outputTokens");
|
|
20911
|
+
const totalTokens = getNumberProperty2(usage, "total_tokens") ?? getNumberProperty2(usage, "totalTokens");
|
|
20912
|
+
if (promptTokens !== void 0) {
|
|
20913
|
+
metrics.prompt_tokens = promptTokens;
|
|
20914
|
+
}
|
|
20915
|
+
if (completionTokens !== void 0) {
|
|
20916
|
+
metrics.completion_tokens = completionTokens;
|
|
20917
|
+
}
|
|
20918
|
+
if (totalTokens !== void 0) {
|
|
20919
|
+
metrics.tokens = totalTokens;
|
|
20920
|
+
} else if (promptTokens !== void 0 && completionTokens !== void 0) {
|
|
20921
|
+
metrics.tokens = promptTokens + completionTokens;
|
|
20922
|
+
}
|
|
20923
|
+
const inputDetails = usage.input_tokens_details;
|
|
20924
|
+
const cachedTokens = getNumberProperty2(inputDetails, "cached_tokens");
|
|
20925
|
+
const cacheWriteTokens = getNumberProperty2(
|
|
20926
|
+
inputDetails,
|
|
20927
|
+
"cache_write_tokens"
|
|
20928
|
+
);
|
|
20929
|
+
if (cachedTokens !== void 0) {
|
|
20930
|
+
metrics.prompt_cached_tokens = cachedTokens;
|
|
20931
|
+
}
|
|
20932
|
+
if (cacheWriteTokens !== void 0) {
|
|
20933
|
+
metrics.prompt_cache_creation_tokens = cacheWriteTokens;
|
|
20934
|
+
}
|
|
20935
|
+
return metrics;
|
|
20936
|
+
}
|
|
20937
|
+
var OpenAIAgentsTraceProcessor = class _OpenAIAgentsTraceProcessor {
|
|
20938
|
+
static DEFAULT_MAX_TRACES = 1e4;
|
|
20939
|
+
logger;
|
|
20940
|
+
maxTraces;
|
|
20941
|
+
traceSpans = /* @__PURE__ */ new Map();
|
|
20942
|
+
traceOrder = [];
|
|
20943
|
+
_traceSpans = this.traceSpans;
|
|
20944
|
+
constructor(options = {}) {
|
|
20945
|
+
this.logger = options.logger;
|
|
20946
|
+
this.maxTraces = options.maxTraces ?? _OpenAIAgentsTraceProcessor.DEFAULT_MAX_TRACES;
|
|
20947
|
+
}
|
|
20948
|
+
evictOldestTrace() {
|
|
20949
|
+
const oldestTraceId = this.traceOrder.shift();
|
|
20950
|
+
if (oldestTraceId) {
|
|
20951
|
+
this.traceSpans.delete(oldestTraceId);
|
|
20952
|
+
}
|
|
20953
|
+
}
|
|
20954
|
+
onTraceStart(trace) {
|
|
20955
|
+
if (!trace?.traceId) {
|
|
20956
|
+
return Promise.resolve();
|
|
20957
|
+
}
|
|
20958
|
+
if (this.traceOrder.length >= this.maxTraces) {
|
|
20959
|
+
this.evictOldestTrace();
|
|
20960
|
+
}
|
|
20961
|
+
const current = currentSpan();
|
|
20962
|
+
const span = current && current !== NOOP_SPAN ? current.startSpan({
|
|
20963
|
+
name: trace.name,
|
|
20964
|
+
type: "task" /* TASK */
|
|
20965
|
+
}) : this.logger ? this.logger.startSpan({
|
|
20966
|
+
name: trace.name,
|
|
20967
|
+
type: "task" /* TASK */
|
|
20968
|
+
}) : startSpan({
|
|
20969
|
+
name: trace.name,
|
|
20970
|
+
type: "task" /* TASK */
|
|
20971
|
+
});
|
|
20972
|
+
span.log({
|
|
20973
|
+
input: "Agent workflow started",
|
|
20974
|
+
metadata: {
|
|
20975
|
+
group_id: trace.groupId,
|
|
20976
|
+
...trace.metadata || {}
|
|
20977
|
+
}
|
|
20978
|
+
});
|
|
20979
|
+
this.traceSpans.set(trace.traceId, {
|
|
20980
|
+
rootSpan: span,
|
|
20981
|
+
childSpans: /* @__PURE__ */ new Map(),
|
|
20982
|
+
metadata: {
|
|
20983
|
+
firstInput: null,
|
|
20984
|
+
lastOutput: null
|
|
20985
|
+
}
|
|
20986
|
+
});
|
|
20987
|
+
this.traceOrder.push(trace.traceId);
|
|
20988
|
+
return Promise.resolve();
|
|
20989
|
+
}
|
|
20990
|
+
async onTraceEnd(trace) {
|
|
20991
|
+
const traceData = this.traceSpans.get(trace?.traceId);
|
|
20992
|
+
if (!traceData) {
|
|
20993
|
+
return;
|
|
20994
|
+
}
|
|
20995
|
+
try {
|
|
20996
|
+
traceData.rootSpan.log({
|
|
20997
|
+
input: traceData.metadata.firstInput,
|
|
20998
|
+
output: traceData.metadata.lastOutput
|
|
20999
|
+
});
|
|
21000
|
+
traceData.rootSpan.end();
|
|
21001
|
+
await traceData.rootSpan.flush();
|
|
21002
|
+
} finally {
|
|
21003
|
+
this.traceSpans.delete(trace.traceId);
|
|
21004
|
+
const orderIndex = this.traceOrder.indexOf(trace.traceId);
|
|
21005
|
+
if (orderIndex > -1) {
|
|
21006
|
+
this.traceOrder.splice(orderIndex, 1);
|
|
21007
|
+
}
|
|
21008
|
+
}
|
|
21009
|
+
}
|
|
21010
|
+
onSpanStart(span) {
|
|
21011
|
+
if (!span?.spanId || !span.traceId) {
|
|
21012
|
+
return Promise.resolve();
|
|
21013
|
+
}
|
|
21014
|
+
const traceData = this.traceSpans.get(span.traceId);
|
|
21015
|
+
if (!traceData) {
|
|
21016
|
+
return Promise.resolve();
|
|
21017
|
+
}
|
|
21018
|
+
const parentSpan = span.parentId ? traceData.childSpans.get(span.parentId) : traceData.rootSpan;
|
|
21019
|
+
if (!parentSpan) {
|
|
21020
|
+
return Promise.resolve();
|
|
21021
|
+
}
|
|
21022
|
+
const childSpan = parentSpan.startSpan({
|
|
21023
|
+
name: spanNameFromAgents(span),
|
|
21024
|
+
type: spanTypeFromAgents(span)
|
|
21025
|
+
});
|
|
21026
|
+
traceData.childSpans.set(span.spanId, childSpan);
|
|
21027
|
+
return Promise.resolve();
|
|
21028
|
+
}
|
|
21029
|
+
onSpanEnd(span) {
|
|
21030
|
+
if (!span?.spanId || !span.traceId) {
|
|
21031
|
+
return Promise.resolve();
|
|
21032
|
+
}
|
|
21033
|
+
const traceData = this.traceSpans.get(span.traceId);
|
|
21034
|
+
if (!traceData) {
|
|
21035
|
+
return Promise.resolve();
|
|
21036
|
+
}
|
|
21037
|
+
const braintrustSpan = traceData.childSpans.get(span.spanId);
|
|
21038
|
+
if (!braintrustSpan) {
|
|
21039
|
+
return Promise.resolve();
|
|
21040
|
+
}
|
|
21041
|
+
const logData = this.extractLogData(span);
|
|
21042
|
+
braintrustSpan.log({
|
|
21043
|
+
error: span.error,
|
|
21044
|
+
...logData
|
|
21045
|
+
});
|
|
21046
|
+
braintrustSpan.end();
|
|
21047
|
+
traceData.childSpans.delete(span.spanId);
|
|
21048
|
+
const input = logData.input;
|
|
21049
|
+
const output = logData.output;
|
|
21050
|
+
if (traceData.metadata.firstInput === null && input != null) {
|
|
21051
|
+
traceData.metadata.firstInput = input;
|
|
21052
|
+
}
|
|
21053
|
+
if (output != null) {
|
|
21054
|
+
traceData.metadata.lastOutput = output;
|
|
21055
|
+
}
|
|
21056
|
+
return Promise.resolve();
|
|
21057
|
+
}
|
|
21058
|
+
async shutdown() {
|
|
21059
|
+
if (this.logger && typeof this.logger.flush === "function") {
|
|
21060
|
+
await this.logger.flush();
|
|
21061
|
+
}
|
|
21062
|
+
}
|
|
21063
|
+
async forceFlush() {
|
|
21064
|
+
if (this.logger && typeof this.logger.flush === "function") {
|
|
21065
|
+
await this.logger.flush();
|
|
21066
|
+
}
|
|
21067
|
+
}
|
|
21068
|
+
extractLogData(span) {
|
|
21069
|
+
const spanData = span.spanData;
|
|
21070
|
+
switch (spanData.type) {
|
|
21071
|
+
case "agent":
|
|
21072
|
+
return this.extractAgentLogData(spanData);
|
|
21073
|
+
case "response":
|
|
21074
|
+
return this.extractResponseLogData(spanData, span);
|
|
21075
|
+
case "function":
|
|
21076
|
+
return this.extractFunctionLogData(spanData);
|
|
21077
|
+
case "handoff":
|
|
21078
|
+
return this.extractHandoffLogData(spanData);
|
|
21079
|
+
case "guardrail":
|
|
21080
|
+
return this.extractGuardrailLogData(spanData);
|
|
21081
|
+
case "generation":
|
|
21082
|
+
return this.extractGenerationLogData(spanData, span);
|
|
21083
|
+
case "custom":
|
|
21084
|
+
return this.extractCustomLogData(spanData);
|
|
21085
|
+
case "mcp_tools":
|
|
21086
|
+
return this.extractMCPListToolsLogData(spanData);
|
|
21087
|
+
case "transcription":
|
|
21088
|
+
return this.extractTranscriptionLogData(spanData);
|
|
21089
|
+
case "speech":
|
|
21090
|
+
return this.extractSpeechLogData(spanData);
|
|
21091
|
+
case "speech_group":
|
|
21092
|
+
return this.extractSpeechGroupLogData(spanData);
|
|
21093
|
+
default:
|
|
21094
|
+
return {};
|
|
21095
|
+
}
|
|
21096
|
+
}
|
|
21097
|
+
extractAgentLogData(spanData) {
|
|
21098
|
+
return {
|
|
21099
|
+
metadata: {
|
|
21100
|
+
tools: spanData.tools,
|
|
21101
|
+
handoffs: spanData.handoffs,
|
|
21102
|
+
output_type: spanData.output_type
|
|
21103
|
+
}
|
|
21104
|
+
};
|
|
21105
|
+
}
|
|
21106
|
+
extractResponseLogData(spanData, span) {
|
|
21107
|
+
const response = spanData._response;
|
|
21108
|
+
const output = isObject(response) ? response.output : void 0;
|
|
21109
|
+
const usage = isObject(response) ? response.usage : void 0;
|
|
21110
|
+
const metrics = {
|
|
21111
|
+
...this.extractTimingMetrics(span),
|
|
21112
|
+
...parseUsageMetrics(usage)
|
|
21113
|
+
};
|
|
21114
|
+
return {
|
|
21115
|
+
input: spanData._input,
|
|
21116
|
+
output,
|
|
21117
|
+
metadata: isObject(response) ? this.omitKeys(response, ["output", "usage"]) : {},
|
|
21118
|
+
metrics
|
|
21119
|
+
};
|
|
21120
|
+
}
|
|
21121
|
+
extractFunctionLogData(spanData) {
|
|
21122
|
+
return {
|
|
21123
|
+
input: spanData.input,
|
|
21124
|
+
output: spanData.output
|
|
21125
|
+
};
|
|
21126
|
+
}
|
|
21127
|
+
extractHandoffLogData(spanData) {
|
|
21128
|
+
return {
|
|
21129
|
+
metadata: {
|
|
21130
|
+
from_agent: spanData.from_agent,
|
|
21131
|
+
to_agent: spanData.to_agent
|
|
21132
|
+
}
|
|
21133
|
+
};
|
|
21134
|
+
}
|
|
21135
|
+
extractGuardrailLogData(spanData) {
|
|
21136
|
+
return {
|
|
21137
|
+
metadata: {
|
|
21138
|
+
triggered: spanData.triggered
|
|
21139
|
+
}
|
|
21140
|
+
};
|
|
21141
|
+
}
|
|
21142
|
+
extractGenerationLogData(spanData, span) {
|
|
21143
|
+
return {
|
|
21144
|
+
input: spanData.input,
|
|
21145
|
+
output: spanData.output,
|
|
21146
|
+
metadata: {
|
|
21147
|
+
model: spanData.model,
|
|
21148
|
+
model_config: spanData.model_config
|
|
21149
|
+
},
|
|
21150
|
+
metrics: {
|
|
21151
|
+
...this.extractTimingMetrics(span),
|
|
21152
|
+
...parseUsageMetrics(spanData.usage)
|
|
21153
|
+
}
|
|
21154
|
+
};
|
|
21155
|
+
}
|
|
21156
|
+
extractCustomLogData(spanData) {
|
|
21157
|
+
return spanData.data || {};
|
|
21158
|
+
}
|
|
21159
|
+
extractMCPListToolsLogData(spanData) {
|
|
21160
|
+
return {
|
|
21161
|
+
output: spanData.result,
|
|
21162
|
+
metadata: {
|
|
21163
|
+
server: spanData.server
|
|
21164
|
+
}
|
|
21165
|
+
};
|
|
21166
|
+
}
|
|
21167
|
+
extractTranscriptionLogData(spanData) {
|
|
21168
|
+
return {
|
|
21169
|
+
input: spanData.input,
|
|
21170
|
+
output: spanData.output,
|
|
21171
|
+
metadata: {
|
|
21172
|
+
model: spanData.model,
|
|
21173
|
+
model_config: spanData.model_config
|
|
21174
|
+
}
|
|
21175
|
+
};
|
|
21176
|
+
}
|
|
21177
|
+
extractSpeechLogData(spanData) {
|
|
21178
|
+
return {
|
|
21179
|
+
input: spanData.input,
|
|
21180
|
+
output: spanData.output,
|
|
21181
|
+
metadata: {
|
|
21182
|
+
model: spanData.model,
|
|
21183
|
+
model_config: spanData.model_config
|
|
21184
|
+
}
|
|
21185
|
+
};
|
|
21186
|
+
}
|
|
21187
|
+
extractSpeechGroupLogData(spanData) {
|
|
21188
|
+
return {
|
|
21189
|
+
input: spanData.input
|
|
21190
|
+
};
|
|
21191
|
+
}
|
|
21192
|
+
extractTimingMetrics(span) {
|
|
21193
|
+
const timeToFirstToken = getTimeElapsed(
|
|
21194
|
+
span.endedAt ?? void 0,
|
|
21195
|
+
span.startedAt ?? void 0
|
|
21196
|
+
);
|
|
21197
|
+
return timeToFirstToken === void 0 ? {} : { time_to_first_token: timeToFirstToken };
|
|
21198
|
+
}
|
|
21199
|
+
omitKeys(value, keys) {
|
|
21200
|
+
const result = {};
|
|
21201
|
+
for (const [key, fieldValue] of Object.entries(value)) {
|
|
21202
|
+
if (!keys.includes(key)) {
|
|
21203
|
+
result[key] = fieldValue;
|
|
21204
|
+
}
|
|
21205
|
+
}
|
|
21206
|
+
return result;
|
|
21207
|
+
}
|
|
21208
|
+
};
|
|
21209
|
+
|
|
21210
|
+
// src/instrumentation/plugins/openai-agents-plugin.ts
|
|
21211
|
+
function firstArgument(args) {
|
|
21212
|
+
if (Array.isArray(args)) {
|
|
21213
|
+
return args[0];
|
|
21214
|
+
}
|
|
21215
|
+
if (isObject(args) && "length" in args && typeof args.length === "number" && Number.isInteger(args.length) && args.length >= 0) {
|
|
21216
|
+
return Array.from(args)[0];
|
|
21217
|
+
}
|
|
21218
|
+
return void 0;
|
|
21219
|
+
}
|
|
21220
|
+
function isOpenAIAgentsTrace(value) {
|
|
21221
|
+
return isObject(value) && value.type === "trace" && typeof value.traceId === "string";
|
|
21222
|
+
}
|
|
21223
|
+
function isOpenAIAgentsSpan(value) {
|
|
21224
|
+
return isObject(value) && value.type === "trace.span" && typeof value.traceId === "string" && typeof value.spanId === "string";
|
|
21225
|
+
}
|
|
21226
|
+
var OpenAIAgentsPlugin = class extends BasePlugin {
|
|
21227
|
+
processor = new OpenAIAgentsTraceProcessor();
|
|
21228
|
+
onEnable() {
|
|
21229
|
+
this.subscribeToTraceLifecycle();
|
|
21230
|
+
}
|
|
21231
|
+
onDisable() {
|
|
21232
|
+
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
21233
|
+
void this.processor.shutdown();
|
|
21234
|
+
}
|
|
21235
|
+
subscribeToTraceLifecycle() {
|
|
21236
|
+
const traceStartChannel = openAIAgentsCoreChannels.onTraceStart.tracingChannel();
|
|
21237
|
+
const traceStartHandlers = {
|
|
21238
|
+
start: (event) => {
|
|
21239
|
+
const trace = firstArgument(event.arguments);
|
|
21240
|
+
if (isOpenAIAgentsTrace(trace)) {
|
|
21241
|
+
void this.processor.onTraceStart(trace);
|
|
21242
|
+
}
|
|
21243
|
+
}
|
|
21244
|
+
};
|
|
21245
|
+
traceStartChannel.subscribe(traceStartHandlers);
|
|
21246
|
+
this.unsubscribers.push(
|
|
21247
|
+
() => traceStartChannel.unsubscribe(traceStartHandlers)
|
|
21248
|
+
);
|
|
21249
|
+
const traceEndChannel = openAIAgentsCoreChannels.onTraceEnd.tracingChannel();
|
|
21250
|
+
const traceEndHandlers = {
|
|
21251
|
+
start: (event) => {
|
|
21252
|
+
const trace = firstArgument(event.arguments);
|
|
21253
|
+
if (isOpenAIAgentsTrace(trace)) {
|
|
21254
|
+
void this.processor.onTraceEnd(trace);
|
|
21255
|
+
}
|
|
21256
|
+
}
|
|
21257
|
+
};
|
|
21258
|
+
traceEndChannel.subscribe(traceEndHandlers);
|
|
21259
|
+
this.unsubscribers.push(
|
|
21260
|
+
() => traceEndChannel.unsubscribe(traceEndHandlers)
|
|
21261
|
+
);
|
|
21262
|
+
const spanStartChannel = openAIAgentsCoreChannels.onSpanStart.tracingChannel();
|
|
21263
|
+
const spanStartHandlers = {
|
|
21264
|
+
start: (event) => {
|
|
21265
|
+
const span = firstArgument(event.arguments);
|
|
21266
|
+
if (isOpenAIAgentsSpan(span)) {
|
|
21267
|
+
void this.processor.onSpanStart(span);
|
|
21268
|
+
}
|
|
21269
|
+
}
|
|
21270
|
+
};
|
|
21271
|
+
spanStartChannel.subscribe(spanStartHandlers);
|
|
21272
|
+
this.unsubscribers.push(
|
|
21273
|
+
() => spanStartChannel.unsubscribe(spanStartHandlers)
|
|
21274
|
+
);
|
|
21275
|
+
const spanEndChannel = openAIAgentsCoreChannels.onSpanEnd.tracingChannel();
|
|
21276
|
+
const spanEndHandlers = {
|
|
21277
|
+
start: (event) => {
|
|
21278
|
+
const span = firstArgument(event.arguments);
|
|
21279
|
+
if (isOpenAIAgentsSpan(span)) {
|
|
21280
|
+
void this.processor.onSpanEnd(span);
|
|
21281
|
+
}
|
|
21282
|
+
}
|
|
21283
|
+
};
|
|
21284
|
+
spanEndChannel.subscribe(spanEndHandlers);
|
|
21285
|
+
this.unsubscribers.push(() => spanEndChannel.unsubscribe(spanEndHandlers));
|
|
21286
|
+
}
|
|
21287
|
+
};
|
|
21288
|
+
|
|
20765
21289
|
// src/instrumentation/plugins/google-genai-channels.ts
|
|
20766
21290
|
var googleGenAIChannels = defineChannels("@google/genai", {
|
|
20767
21291
|
generateContent: channel({
|
|
@@ -27054,33 +27578,1743 @@ var GitHubCopilotPlugin = class extends BasePlugin {
|
|
|
27054
27578
|
}
|
|
27055
27579
|
};
|
|
27056
27580
|
|
|
27057
|
-
// src/instrumentation/
|
|
27058
|
-
|
|
27059
|
-
|
|
27581
|
+
// src/instrumentation/plugins/flue-channels.ts
|
|
27582
|
+
var flueChannels = defineChannels("@flue/runtime", {
|
|
27583
|
+
createContext: channel({
|
|
27584
|
+
channelName: "createFlueContext",
|
|
27585
|
+
kind: "sync-stream"
|
|
27586
|
+
}),
|
|
27587
|
+
openSession: channel({
|
|
27588
|
+
channelName: "Harness.openSession",
|
|
27589
|
+
kind: "async"
|
|
27590
|
+
}),
|
|
27591
|
+
contextEvent: channel({
|
|
27592
|
+
channelName: "context.event",
|
|
27593
|
+
kind: "sync-stream"
|
|
27594
|
+
}),
|
|
27595
|
+
prompt: channel({
|
|
27596
|
+
channelName: "session.prompt",
|
|
27597
|
+
kind: "async"
|
|
27598
|
+
}),
|
|
27599
|
+
skill: channel({
|
|
27600
|
+
channelName: "session.skill",
|
|
27601
|
+
kind: "async"
|
|
27602
|
+
}),
|
|
27603
|
+
task: channel({
|
|
27604
|
+
channelName: "session.task",
|
|
27605
|
+
kind: "async"
|
|
27606
|
+
}),
|
|
27607
|
+
compact: channel({
|
|
27608
|
+
channelName: "session.compact",
|
|
27609
|
+
kind: "async"
|
|
27610
|
+
})
|
|
27611
|
+
});
|
|
27612
|
+
|
|
27613
|
+
// src/wrappers/flue.ts
|
|
27614
|
+
var WRAPPED_FLUE_CONTEXT = /* @__PURE__ */ Symbol.for("braintrust.flue.wrapped-context");
|
|
27615
|
+
var WRAPPED_FLUE_HARNESS = /* @__PURE__ */ Symbol.for("braintrust.flue.wrapped-harness");
|
|
27616
|
+
var WRAPPED_FLUE_SESSION = /* @__PURE__ */ Symbol.for("braintrust.flue.wrapped-session");
|
|
27617
|
+
var SUBSCRIBED_FLUE_CONTEXT_EVENTS = /* @__PURE__ */ Symbol.for(
|
|
27618
|
+
"braintrust.flue.subscribed-context-events"
|
|
27619
|
+
);
|
|
27620
|
+
function patchFlueContextInPlace(ctx) {
|
|
27621
|
+
const context2 = ctx;
|
|
27622
|
+
if (context2[WRAPPED_FLUE_CONTEXT]) {
|
|
27623
|
+
return ctx;
|
|
27624
|
+
}
|
|
27625
|
+
const originalInit = context2.init.bind(context2);
|
|
27626
|
+
try {
|
|
27627
|
+
Object.defineProperty(context2, WRAPPED_FLUE_CONTEXT, {
|
|
27628
|
+
configurable: false,
|
|
27629
|
+
enumerable: false,
|
|
27630
|
+
value: true
|
|
27631
|
+
});
|
|
27632
|
+
Object.defineProperty(context2, "init", {
|
|
27633
|
+
configurable: true,
|
|
27634
|
+
value: async function wrappedFlueInit(options) {
|
|
27635
|
+
const harness = await originalInit(options);
|
|
27636
|
+
return wrapFlueHarness(harness);
|
|
27637
|
+
},
|
|
27638
|
+
writable: true
|
|
27639
|
+
});
|
|
27640
|
+
} catch {
|
|
27641
|
+
}
|
|
27642
|
+
return ctx;
|
|
27060
27643
|
}
|
|
27061
|
-
|
|
27062
|
-
|
|
27063
|
-
|
|
27064
|
-
openAICodexPlugin = null;
|
|
27065
|
-
anthropicPlugin = null;
|
|
27066
|
-
aiSDKPlugin = null;
|
|
27067
|
-
claudeAgentSDKPlugin = null;
|
|
27068
|
-
cursorSDKPlugin = null;
|
|
27069
|
-
googleGenAIPlugin = null;
|
|
27070
|
-
huggingFacePlugin = null;
|
|
27071
|
-
openRouterPlugin = null;
|
|
27072
|
-
openRouterAgentPlugin = null;
|
|
27073
|
-
mistralPlugin = null;
|
|
27074
|
-
googleADKPlugin = null;
|
|
27075
|
-
coherePlugin = null;
|
|
27076
|
-
groqPlugin = null;
|
|
27077
|
-
genkitPlugin = null;
|
|
27078
|
-
gitHubCopilotPlugin = null;
|
|
27079
|
-
constructor(config3 = {}) {
|
|
27080
|
-
super();
|
|
27081
|
-
this.config = config3;
|
|
27644
|
+
function subscribeFlueContextEvents(ctx, options = {}) {
|
|
27645
|
+
if (!ctx || typeof ctx !== "object" || typeof ctx.subscribeEvent !== "function") {
|
|
27646
|
+
return void 0;
|
|
27082
27647
|
}
|
|
27083
|
-
|
|
27648
|
+
const context2 = ctx;
|
|
27649
|
+
const captureTurnSpans = options.captureTurnSpans ?? true;
|
|
27650
|
+
const existingSubscription = context2[SUBSCRIBED_FLUE_CONTEXT_EVENTS];
|
|
27651
|
+
if (existingSubscription) {
|
|
27652
|
+
if (existingSubscription.captureTurnSpans || !captureTurnSpans) {
|
|
27653
|
+
return void 0;
|
|
27654
|
+
}
|
|
27655
|
+
try {
|
|
27656
|
+
existingSubscription.unsubscribe();
|
|
27657
|
+
} catch {
|
|
27658
|
+
}
|
|
27659
|
+
}
|
|
27660
|
+
try {
|
|
27661
|
+
const unsubscribe = ctx.subscribeEvent((event) => {
|
|
27662
|
+
flueChannels.contextEvent.traceSync(() => void 0, {
|
|
27663
|
+
arguments: [event],
|
|
27664
|
+
captureTurnSpans,
|
|
27665
|
+
context: ctx
|
|
27666
|
+
});
|
|
27667
|
+
});
|
|
27668
|
+
if (existingSubscription) {
|
|
27669
|
+
existingSubscription.captureTurnSpans = captureTurnSpans;
|
|
27670
|
+
existingSubscription.unsubscribe = unsubscribe;
|
|
27671
|
+
} else {
|
|
27672
|
+
Object.defineProperty(context2, SUBSCRIBED_FLUE_CONTEXT_EVENTS, {
|
|
27673
|
+
configurable: false,
|
|
27674
|
+
enumerable: false,
|
|
27675
|
+
value: {
|
|
27676
|
+
captureTurnSpans,
|
|
27677
|
+
unsubscribe
|
|
27678
|
+
}
|
|
27679
|
+
});
|
|
27680
|
+
}
|
|
27681
|
+
return unsubscribe;
|
|
27682
|
+
} catch {
|
|
27683
|
+
return void 0;
|
|
27684
|
+
}
|
|
27685
|
+
}
|
|
27686
|
+
function wrapFlueHarness(harness) {
|
|
27687
|
+
if (!isPlausibleFlueHarness(harness)) {
|
|
27688
|
+
return harness;
|
|
27689
|
+
}
|
|
27690
|
+
const target = harness;
|
|
27691
|
+
if (target[WRAPPED_FLUE_HARNESS]) {
|
|
27692
|
+
return harness;
|
|
27693
|
+
}
|
|
27694
|
+
const originalSession = target.session.bind(target);
|
|
27695
|
+
try {
|
|
27696
|
+
Object.defineProperty(target, WRAPPED_FLUE_HARNESS, {
|
|
27697
|
+
configurable: false,
|
|
27698
|
+
enumerable: false,
|
|
27699
|
+
value: true
|
|
27700
|
+
});
|
|
27701
|
+
Object.defineProperty(target, "session", {
|
|
27702
|
+
configurable: true,
|
|
27703
|
+
value: async function wrappedFlueHarnessSession(name, options) {
|
|
27704
|
+
const session = await originalSession(name, options);
|
|
27705
|
+
return patchFlueSessionInPlace(session);
|
|
27706
|
+
},
|
|
27707
|
+
writable: true
|
|
27708
|
+
});
|
|
27709
|
+
const sessions = target.sessions;
|
|
27710
|
+
if (sessions && typeof sessions === "object") {
|
|
27711
|
+
patchFlueSessionFactory(sessions, "get");
|
|
27712
|
+
patchFlueSessionFactory(sessions, "create");
|
|
27713
|
+
}
|
|
27714
|
+
} catch {
|
|
27715
|
+
}
|
|
27716
|
+
return harness;
|
|
27717
|
+
}
|
|
27718
|
+
function patchFlueSessionInPlace(session) {
|
|
27719
|
+
if (session[WRAPPED_FLUE_SESSION]) {
|
|
27720
|
+
return session;
|
|
27721
|
+
}
|
|
27722
|
+
try {
|
|
27723
|
+
Object.defineProperty(session, WRAPPED_FLUE_SESSION, {
|
|
27724
|
+
configurable: false,
|
|
27725
|
+
enumerable: false,
|
|
27726
|
+
value: true
|
|
27727
|
+
});
|
|
27728
|
+
patchCallHandleMethod(session, "prompt", flueChannels.prompt);
|
|
27729
|
+
patchCallHandleMethod(session, "skill", flueChannels.skill);
|
|
27730
|
+
patchCallHandleMethod(session, "task", flueChannels.task);
|
|
27731
|
+
patchCompact(session);
|
|
27732
|
+
} catch {
|
|
27733
|
+
}
|
|
27734
|
+
return session;
|
|
27735
|
+
}
|
|
27736
|
+
function patchFlueSessionFactory(sessions, method) {
|
|
27737
|
+
const original = sessions[method];
|
|
27738
|
+
if (typeof original !== "function") {
|
|
27739
|
+
return;
|
|
27740
|
+
}
|
|
27741
|
+
const bound = original.bind(sessions);
|
|
27742
|
+
Object.defineProperty(sessions, method, {
|
|
27743
|
+
configurable: true,
|
|
27744
|
+
value: async function wrappedFlueSessionFactory(name, options) {
|
|
27745
|
+
const session = await bound(name, options);
|
|
27746
|
+
return patchFlueSessionInPlace(session);
|
|
27747
|
+
},
|
|
27748
|
+
writable: true
|
|
27749
|
+
});
|
|
27750
|
+
}
|
|
27751
|
+
function patchCallHandleMethod(session, method, channel2) {
|
|
27752
|
+
const original = session[method];
|
|
27753
|
+
if (typeof original !== "function") {
|
|
27754
|
+
return;
|
|
27755
|
+
}
|
|
27756
|
+
const bound = original.bind(session);
|
|
27757
|
+
Object.defineProperty(session, method, {
|
|
27758
|
+
configurable: true,
|
|
27759
|
+
value(input, options) {
|
|
27760
|
+
const args = [input, options];
|
|
27761
|
+
const { originalResult, traced: traced2 } = traceFlueOperation(channel2, {
|
|
27762
|
+
context: {
|
|
27763
|
+
arguments: args,
|
|
27764
|
+
operation: method,
|
|
27765
|
+
session
|
|
27766
|
+
},
|
|
27767
|
+
run: () => bound(input, options)
|
|
27768
|
+
});
|
|
27769
|
+
return preserveCallHandle(originalResult, traced2);
|
|
27770
|
+
},
|
|
27771
|
+
writable: true
|
|
27772
|
+
});
|
|
27773
|
+
}
|
|
27774
|
+
function patchCompact(session) {
|
|
27775
|
+
const original = session.compact;
|
|
27776
|
+
if (typeof original !== "function") {
|
|
27777
|
+
return;
|
|
27778
|
+
}
|
|
27779
|
+
const bound = original.bind(session);
|
|
27780
|
+
Object.defineProperty(session, "compact", {
|
|
27781
|
+
configurable: true,
|
|
27782
|
+
value() {
|
|
27783
|
+
const context2 = {
|
|
27784
|
+
arguments: [],
|
|
27785
|
+
operation: "compact",
|
|
27786
|
+
session
|
|
27787
|
+
};
|
|
27788
|
+
return flueChannels.compact.tracePromise(() => bound(), context2);
|
|
27789
|
+
},
|
|
27790
|
+
writable: true
|
|
27791
|
+
});
|
|
27792
|
+
}
|
|
27793
|
+
function traceFlueOperation(channel2, args) {
|
|
27794
|
+
const tracingChannel2 = channel2.tracingChannel();
|
|
27795
|
+
const context2 = args.context;
|
|
27796
|
+
let originalResult;
|
|
27797
|
+
let traced2;
|
|
27798
|
+
const run2 = () => {
|
|
27799
|
+
try {
|
|
27800
|
+
originalResult = args.run();
|
|
27801
|
+
tracingChannel2.end?.publish(context2);
|
|
27802
|
+
} catch (error2) {
|
|
27803
|
+
context2.error = normalizeError3(error2);
|
|
27804
|
+
tracingChannel2.error?.publish(context2);
|
|
27805
|
+
tracingChannel2.end?.publish(context2);
|
|
27806
|
+
throw error2;
|
|
27807
|
+
}
|
|
27808
|
+
traced2 = Promise.resolve(originalResult).then(
|
|
27809
|
+
(result) => {
|
|
27810
|
+
context2.result = result;
|
|
27811
|
+
tracingChannel2.asyncStart?.publish(context2);
|
|
27812
|
+
tracingChannel2.asyncEnd?.publish(context2);
|
|
27813
|
+
return result;
|
|
27814
|
+
},
|
|
27815
|
+
(error2) => {
|
|
27816
|
+
context2.error = normalizeError3(error2);
|
|
27817
|
+
tracingChannel2.error?.publish(context2);
|
|
27818
|
+
tracingChannel2.asyncStart?.publish(context2);
|
|
27819
|
+
tracingChannel2.asyncEnd?.publish(context2);
|
|
27820
|
+
throw error2;
|
|
27821
|
+
}
|
|
27822
|
+
);
|
|
27823
|
+
};
|
|
27824
|
+
if (tracingChannel2.start?.runStores) {
|
|
27825
|
+
tracingChannel2.start.runStores(context2, run2);
|
|
27826
|
+
} else {
|
|
27827
|
+
tracingChannel2.start?.publish(context2);
|
|
27828
|
+
run2();
|
|
27829
|
+
}
|
|
27830
|
+
return { originalResult, traced: traced2 };
|
|
27831
|
+
}
|
|
27832
|
+
function normalizeError3(error2) {
|
|
27833
|
+
return error2 instanceof Error ? error2 : new Error(String(error2));
|
|
27834
|
+
}
|
|
27835
|
+
function preserveCallHandle(originalHandle, traced2) {
|
|
27836
|
+
if (!isFlueCallHandle(originalHandle)) {
|
|
27837
|
+
return traced2;
|
|
27838
|
+
}
|
|
27839
|
+
const handle = originalHandle;
|
|
27840
|
+
const wrapped = {
|
|
27841
|
+
get signal() {
|
|
27842
|
+
return handle.signal;
|
|
27843
|
+
},
|
|
27844
|
+
abort(reason) {
|
|
27845
|
+
return handle.abort(reason);
|
|
27846
|
+
},
|
|
27847
|
+
then(onfulfilled, onrejected) {
|
|
27848
|
+
return traced2.then(onfulfilled, onrejected);
|
|
27849
|
+
}
|
|
27850
|
+
};
|
|
27851
|
+
return wrapped;
|
|
27852
|
+
}
|
|
27853
|
+
function isPlausibleFlueHarness(value) {
|
|
27854
|
+
return !!value && typeof value === "object" && typeof value.session === "function";
|
|
27855
|
+
}
|
|
27856
|
+
function isFlueCallHandle(value) {
|
|
27857
|
+
return !!value && typeof value === "object" && typeof value.then === "function" && typeof value.abort === "function" && "signal" in value;
|
|
27858
|
+
}
|
|
27859
|
+
|
|
27860
|
+
// src/instrumentation/plugins/flue-plugin.ts
|
|
27861
|
+
var FluePlugin = class extends BasePlugin {
|
|
27862
|
+
activeOperationsById = /* @__PURE__ */ new Map();
|
|
27863
|
+
activeOperationsByScope = /* @__PURE__ */ new Map();
|
|
27864
|
+
compactionsByScope = /* @__PURE__ */ new Map();
|
|
27865
|
+
pendingOperationsByKey = /* @__PURE__ */ new Map();
|
|
27866
|
+
tasksById = /* @__PURE__ */ new Map();
|
|
27867
|
+
toolsById = /* @__PURE__ */ new Map();
|
|
27868
|
+
turnsByScope = /* @__PURE__ */ new Map();
|
|
27869
|
+
onEnable() {
|
|
27870
|
+
this.subscribeToContextCreation();
|
|
27871
|
+
this.subscribeToSessionCreation();
|
|
27872
|
+
this.subscribeToContextEvents();
|
|
27873
|
+
this.subscribeToSessionOperations();
|
|
27874
|
+
}
|
|
27875
|
+
onDisable() {
|
|
27876
|
+
for (const unsubscribe of this.unsubscribers) {
|
|
27877
|
+
unsubscribe();
|
|
27878
|
+
}
|
|
27879
|
+
this.unsubscribers = [];
|
|
27880
|
+
this.activeOperationsById.clear();
|
|
27881
|
+
this.activeOperationsByScope.clear();
|
|
27882
|
+
this.compactionsByScope.clear();
|
|
27883
|
+
this.pendingOperationsByKey.clear();
|
|
27884
|
+
this.tasksById.clear();
|
|
27885
|
+
this.toolsById.clear();
|
|
27886
|
+
this.turnsByScope.clear();
|
|
27887
|
+
}
|
|
27888
|
+
subscribeToContextCreation() {
|
|
27889
|
+
const channel2 = flueChannels.createContext.tracingChannel();
|
|
27890
|
+
const handlers = {
|
|
27891
|
+
end: (event) => {
|
|
27892
|
+
const ctx = event.result;
|
|
27893
|
+
if (!ctx) {
|
|
27894
|
+
return;
|
|
27895
|
+
}
|
|
27896
|
+
subscribeFlueContextEvents(ctx, { captureTurnSpans: false });
|
|
27897
|
+
patchFlueContextInPlace(ctx);
|
|
27898
|
+
},
|
|
27899
|
+
error: () => {
|
|
27900
|
+
}
|
|
27901
|
+
};
|
|
27902
|
+
channel2.subscribe(handlers);
|
|
27903
|
+
this.unsubscribers.push(() => {
|
|
27904
|
+
channel2.unsubscribe(handlers);
|
|
27905
|
+
});
|
|
27906
|
+
}
|
|
27907
|
+
subscribeToSessionCreation() {
|
|
27908
|
+
const channel2 = flueChannels.openSession.tracingChannel();
|
|
27909
|
+
const handlers = {
|
|
27910
|
+
asyncEnd: (event) => {
|
|
27911
|
+
if (event.result) {
|
|
27912
|
+
patchFlueSessionInPlace(
|
|
27913
|
+
event.result
|
|
27914
|
+
);
|
|
27915
|
+
}
|
|
27916
|
+
if (event.harness) {
|
|
27917
|
+
wrapFlueHarness(event.harness);
|
|
27918
|
+
}
|
|
27919
|
+
},
|
|
27920
|
+
error: () => {
|
|
27921
|
+
}
|
|
27922
|
+
};
|
|
27923
|
+
channel2.subscribe(handlers);
|
|
27924
|
+
this.unsubscribers.push(() => {
|
|
27925
|
+
channel2.unsubscribe(handlers);
|
|
27926
|
+
});
|
|
27927
|
+
}
|
|
27928
|
+
subscribeToSessionOperations() {
|
|
27929
|
+
this.subscribeToSessionOperation(flueChannels.prompt);
|
|
27930
|
+
this.subscribeToSessionOperation(flueChannels.skill);
|
|
27931
|
+
this.subscribeToSessionOperation(flueChannels.task);
|
|
27932
|
+
this.subscribeToCompact();
|
|
27933
|
+
}
|
|
27934
|
+
subscribeToSessionOperation(channel2) {
|
|
27935
|
+
const tracingChannel2 = channel2.tracingChannel();
|
|
27936
|
+
const states = /* @__PURE__ */ new WeakMap();
|
|
27937
|
+
const ensureState2 = (event) => {
|
|
27938
|
+
const existing = states.get(event);
|
|
27939
|
+
if (existing) {
|
|
27940
|
+
return existing;
|
|
27941
|
+
}
|
|
27942
|
+
const state = this.startOperationState({
|
|
27943
|
+
args: event.arguments,
|
|
27944
|
+
moduleVersion: typeof event.moduleVersion === "string" ? event.moduleVersion : void 0,
|
|
27945
|
+
operation: event.operation,
|
|
27946
|
+
session: event.session
|
|
27947
|
+
});
|
|
27948
|
+
states.set(event, state);
|
|
27949
|
+
return state;
|
|
27950
|
+
};
|
|
27951
|
+
const unbindCurrentSpanStore = this.bindCurrentSpanStoreToOperationStart(
|
|
27952
|
+
tracingChannel2,
|
|
27953
|
+
ensureState2
|
|
27954
|
+
);
|
|
27955
|
+
const handlers = {
|
|
27956
|
+
start: (event) => {
|
|
27957
|
+
ensureState2(event);
|
|
27958
|
+
},
|
|
27959
|
+
asyncEnd: (event) => {
|
|
27960
|
+
this.endOperationState(states.get(event), event.result);
|
|
27961
|
+
states.delete(event);
|
|
27962
|
+
},
|
|
27963
|
+
error: (event) => {
|
|
27964
|
+
const state = states.get(event);
|
|
27965
|
+
if (state && event.error) {
|
|
27966
|
+
safeLog3(state.span, { error: errorToString(event.error) });
|
|
27967
|
+
this.finishOperationState(state);
|
|
27968
|
+
}
|
|
27969
|
+
states.delete(event);
|
|
27970
|
+
}
|
|
27971
|
+
};
|
|
27972
|
+
tracingChannel2.subscribe(handlers);
|
|
27973
|
+
this.unsubscribers.push(() => {
|
|
27974
|
+
unbindCurrentSpanStore?.();
|
|
27975
|
+
tracingChannel2.unsubscribe(handlers);
|
|
27976
|
+
});
|
|
27977
|
+
}
|
|
27978
|
+
subscribeToCompact() {
|
|
27979
|
+
const tracingChannel2 = flueChannels.compact.tracingChannel();
|
|
27980
|
+
const states = /* @__PURE__ */ new WeakMap();
|
|
27981
|
+
const ensureState2 = (event) => {
|
|
27982
|
+
const existing = states.get(event);
|
|
27983
|
+
if (existing) {
|
|
27984
|
+
return existing;
|
|
27985
|
+
}
|
|
27986
|
+
const state = this.startOperationState({
|
|
27987
|
+
args: [],
|
|
27988
|
+
moduleVersion: typeof event.moduleVersion === "string" ? event.moduleVersion : void 0,
|
|
27989
|
+
operation: event.operation,
|
|
27990
|
+
session: event.session
|
|
27991
|
+
});
|
|
27992
|
+
states.set(event, state);
|
|
27993
|
+
return state;
|
|
27994
|
+
};
|
|
27995
|
+
const unbindCurrentSpanStore = this.bindCurrentSpanStoreToOperationStart(
|
|
27996
|
+
tracingChannel2,
|
|
27997
|
+
ensureState2
|
|
27998
|
+
);
|
|
27999
|
+
const handlers = {
|
|
28000
|
+
start: (event) => {
|
|
28001
|
+
ensureState2(event);
|
|
28002
|
+
},
|
|
28003
|
+
asyncEnd: (event) => {
|
|
28004
|
+
this.endOperationState(states.get(event), void 0);
|
|
28005
|
+
states.delete(event);
|
|
28006
|
+
},
|
|
28007
|
+
error: (event) => {
|
|
28008
|
+
const state = states.get(event);
|
|
28009
|
+
if (state && event.error) {
|
|
28010
|
+
safeLog3(state.span, { error: errorToString(event.error) });
|
|
28011
|
+
this.finishOperationState(state);
|
|
28012
|
+
}
|
|
28013
|
+
states.delete(event);
|
|
28014
|
+
}
|
|
28015
|
+
};
|
|
28016
|
+
tracingChannel2.subscribe(handlers);
|
|
28017
|
+
this.unsubscribers.push(() => {
|
|
28018
|
+
unbindCurrentSpanStore?.();
|
|
28019
|
+
tracingChannel2.unsubscribe(handlers);
|
|
28020
|
+
});
|
|
28021
|
+
}
|
|
28022
|
+
subscribeToContextEvents() {
|
|
28023
|
+
const channel2 = flueChannels.contextEvent.tracingChannel();
|
|
28024
|
+
const handlers = {
|
|
28025
|
+
start: (event) => {
|
|
28026
|
+
const flueEvent = event.arguments[0];
|
|
28027
|
+
if (!flueEvent) {
|
|
28028
|
+
return;
|
|
28029
|
+
}
|
|
28030
|
+
try {
|
|
28031
|
+
this.handleFlueEvent(flueEvent, {
|
|
28032
|
+
captureTurnSpans: event.captureTurnSpans !== false
|
|
28033
|
+
});
|
|
28034
|
+
} catch (error2) {
|
|
28035
|
+
logInstrumentationError3("Flue event", error2);
|
|
28036
|
+
}
|
|
28037
|
+
},
|
|
28038
|
+
error: () => {
|
|
28039
|
+
}
|
|
28040
|
+
};
|
|
28041
|
+
channel2.subscribe(handlers);
|
|
28042
|
+
this.unsubscribers.push(() => {
|
|
28043
|
+
channel2.unsubscribe(handlers);
|
|
28044
|
+
});
|
|
28045
|
+
}
|
|
28046
|
+
bindCurrentSpanStoreToOperationStart(tracingChannel2, ensureState2) {
|
|
28047
|
+
const state = _internalGetGlobalState();
|
|
28048
|
+
const startChannel = tracingChannel2.start;
|
|
28049
|
+
const contextManager = state?.contextManager;
|
|
28050
|
+
const currentSpanStore = contextManager ? contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
|
|
28051
|
+
if (!currentSpanStore || !startChannel) {
|
|
28052
|
+
return void 0;
|
|
28053
|
+
}
|
|
28054
|
+
startChannel.bindStore(currentSpanStore, (event) => {
|
|
28055
|
+
const operationState = ensureState2(event);
|
|
28056
|
+
return contextManager.wrapSpanForStore(operationState.span);
|
|
28057
|
+
});
|
|
28058
|
+
return () => {
|
|
28059
|
+
startChannel.unbindStore(currentSpanStore);
|
|
28060
|
+
};
|
|
28061
|
+
}
|
|
28062
|
+
startOperationState(args) {
|
|
28063
|
+
const sessionName = getSessionName(args.session);
|
|
28064
|
+
const metadata = {
|
|
28065
|
+
...extractOperationInputMetadata(args.operation, args.args),
|
|
28066
|
+
...extractSessionMetadata(args.session),
|
|
28067
|
+
"flue.operation": args.operation,
|
|
28068
|
+
provider: "flue",
|
|
28069
|
+
...args.moduleVersion ? { "flue.version": args.moduleVersion } : {}
|
|
28070
|
+
};
|
|
28071
|
+
const span = startSpan({
|
|
28072
|
+
name: `flue.session.${args.operation}`,
|
|
28073
|
+
spanAttributes: { type: "task" /* TASK */ }
|
|
28074
|
+
});
|
|
28075
|
+
const state = {
|
|
28076
|
+
metadata,
|
|
28077
|
+
operation: args.operation,
|
|
28078
|
+
sessionName,
|
|
28079
|
+
span,
|
|
28080
|
+
startTime: getCurrentUnixTimestamp()
|
|
28081
|
+
};
|
|
28082
|
+
safeLog3(span, {
|
|
28083
|
+
input: extractOperationInput(args.operation, args.args),
|
|
28084
|
+
metadata
|
|
28085
|
+
});
|
|
28086
|
+
this.pendingOperationQueue(operationKey(sessionName, args.operation)).push(
|
|
28087
|
+
state
|
|
28088
|
+
);
|
|
28089
|
+
addOperationToScope(
|
|
28090
|
+
this.activeOperationsByScope,
|
|
28091
|
+
sessionName ?? "unknown",
|
|
28092
|
+
state
|
|
28093
|
+
);
|
|
28094
|
+
return state;
|
|
28095
|
+
}
|
|
28096
|
+
endOperationState(state, result) {
|
|
28097
|
+
if (!state) {
|
|
28098
|
+
return;
|
|
28099
|
+
}
|
|
28100
|
+
const metadata = {
|
|
28101
|
+
...state.metadata,
|
|
28102
|
+
...extractPromptResponseMetadata(result)
|
|
28103
|
+
};
|
|
28104
|
+
const metrics = {
|
|
28105
|
+
...buildDurationMetrics3(state.startTime),
|
|
28106
|
+
...metricsFromUsage(result?.usage)
|
|
28107
|
+
};
|
|
28108
|
+
safeLog3(state.span, {
|
|
28109
|
+
metadata,
|
|
28110
|
+
metrics,
|
|
28111
|
+
output: extractOperationOutput(result)
|
|
28112
|
+
});
|
|
28113
|
+
this.finishCompactionsForOperation(state);
|
|
28114
|
+
this.finishOperationState(state);
|
|
28115
|
+
}
|
|
28116
|
+
finishOperationState(state) {
|
|
28117
|
+
removePendingOperation(this.pendingOperationsByKey, state);
|
|
28118
|
+
if (state.operationId) {
|
|
28119
|
+
this.activeOperationsById.delete(state.operationId);
|
|
28120
|
+
}
|
|
28121
|
+
removeScopedOperation(this.activeOperationsByScope, state);
|
|
28122
|
+
state.span.end();
|
|
28123
|
+
}
|
|
28124
|
+
handleFlueEvent(event, options) {
|
|
28125
|
+
switch (event.type) {
|
|
28126
|
+
case "operation_start":
|
|
28127
|
+
this.handleOperationStart(event);
|
|
28128
|
+
return;
|
|
28129
|
+
case "operation":
|
|
28130
|
+
this.handleOperation(event);
|
|
28131
|
+
return;
|
|
28132
|
+
case "text_delta":
|
|
28133
|
+
if (!options.captureTurnSpans) {
|
|
28134
|
+
return;
|
|
28135
|
+
}
|
|
28136
|
+
this.ensureTurnState(event).text.push(
|
|
28137
|
+
typeof event.text === "string" ? event.text : ""
|
|
28138
|
+
);
|
|
28139
|
+
return;
|
|
28140
|
+
case "thinking_start":
|
|
28141
|
+
if (!options.captureTurnSpans) {
|
|
28142
|
+
return;
|
|
28143
|
+
}
|
|
28144
|
+
this.handleThinkingStart(event);
|
|
28145
|
+
return;
|
|
28146
|
+
case "thinking_delta":
|
|
28147
|
+
if (!options.captureTurnSpans) {
|
|
28148
|
+
return;
|
|
28149
|
+
}
|
|
28150
|
+
this.handleThinkingDelta(event);
|
|
28151
|
+
return;
|
|
28152
|
+
case "thinking_end":
|
|
28153
|
+
if (!options.captureTurnSpans) {
|
|
28154
|
+
return;
|
|
28155
|
+
}
|
|
28156
|
+
this.handleThinkingEnd(event);
|
|
28157
|
+
return;
|
|
28158
|
+
case "turn":
|
|
28159
|
+
if (!options.captureTurnSpans) {
|
|
28160
|
+
return;
|
|
28161
|
+
}
|
|
28162
|
+
this.handleTurn(event);
|
|
28163
|
+
return;
|
|
28164
|
+
case "tool_start":
|
|
28165
|
+
this.handleToolStart(event, options);
|
|
28166
|
+
return;
|
|
28167
|
+
case "tool_call":
|
|
28168
|
+
this.handleToolCall(event);
|
|
28169
|
+
return;
|
|
28170
|
+
case "task_start":
|
|
28171
|
+
this.handleTaskStart(event);
|
|
28172
|
+
return;
|
|
28173
|
+
case "task":
|
|
28174
|
+
this.handleTask(event);
|
|
28175
|
+
return;
|
|
28176
|
+
case "compaction_start":
|
|
28177
|
+
this.handleCompactionStart(event);
|
|
28178
|
+
return;
|
|
28179
|
+
case "compaction":
|
|
28180
|
+
this.handleCompaction(event);
|
|
28181
|
+
return;
|
|
28182
|
+
default:
|
|
28183
|
+
return;
|
|
28184
|
+
}
|
|
28185
|
+
}
|
|
28186
|
+
handleOperationStart(event) {
|
|
28187
|
+
if (!isInstrumentedOperation(event.operationKind)) {
|
|
28188
|
+
return;
|
|
28189
|
+
}
|
|
28190
|
+
const state = this.takePendingOperationForEvent(event);
|
|
28191
|
+
if (!state) {
|
|
28192
|
+
return;
|
|
28193
|
+
}
|
|
28194
|
+
state.operationId = event.operationId;
|
|
28195
|
+
this.activeOperationsById.set(event.operationId, state);
|
|
28196
|
+
addScopedOperation(this.activeOperationsByScope, event, state);
|
|
28197
|
+
state.metadata = {
|
|
28198
|
+
...state.metadata,
|
|
28199
|
+
...extractEventMetadata(event),
|
|
28200
|
+
"flue.operation_id": event.operationId
|
|
28201
|
+
};
|
|
28202
|
+
safeLog3(state.span, { metadata: state.metadata });
|
|
28203
|
+
}
|
|
28204
|
+
handleOperation(event) {
|
|
28205
|
+
const state = event.operationId ? this.activeOperationsById.get(event.operationId) : void 0;
|
|
28206
|
+
if (!state) {
|
|
28207
|
+
return;
|
|
28208
|
+
}
|
|
28209
|
+
const metadata = {
|
|
28210
|
+
...state.metadata,
|
|
28211
|
+
...extractEventMetadata(event),
|
|
28212
|
+
...typeof event.durationMs === "number" ? { "flue.duration_ms": event.durationMs } : {},
|
|
28213
|
+
...event.isError !== void 0 ? { "flue.is_error": event.isError } : {}
|
|
28214
|
+
};
|
|
28215
|
+
const metrics = metricsFromUsage(event.usage);
|
|
28216
|
+
safeLog3(state.span, {
|
|
28217
|
+
...event.error ? { error: errorToString(event.error) } : {},
|
|
28218
|
+
metadata,
|
|
28219
|
+
...Object.keys(metrics).length ? { metrics } : {}
|
|
28220
|
+
});
|
|
28221
|
+
}
|
|
28222
|
+
ensureTurnState(event) {
|
|
28223
|
+
const scope = scopeKey(event);
|
|
28224
|
+
const existing = this.turnsByScope.get(scope);
|
|
28225
|
+
if (existing) {
|
|
28226
|
+
return existing;
|
|
28227
|
+
}
|
|
28228
|
+
const parent = this.parentSpanForEvent(event);
|
|
28229
|
+
const metadata = {
|
|
28230
|
+
...extractEventMetadata(event),
|
|
28231
|
+
provider: "flue"
|
|
28232
|
+
};
|
|
28233
|
+
const span = startFlueSpan(parent, {
|
|
28234
|
+
name: "flue.turn",
|
|
28235
|
+
spanAttributes: { type: "llm" /* LLM */ }
|
|
28236
|
+
});
|
|
28237
|
+
const state = {
|
|
28238
|
+
metadata,
|
|
28239
|
+
span,
|
|
28240
|
+
hasThinking: false,
|
|
28241
|
+
startTime: getCurrentUnixTimestamp(),
|
|
28242
|
+
text: [],
|
|
28243
|
+
thinking: [],
|
|
28244
|
+
toolCalls: []
|
|
28245
|
+
};
|
|
28246
|
+
safeLog3(span, { metadata });
|
|
28247
|
+
this.turnsByScope.set(scope, state);
|
|
28248
|
+
return state;
|
|
28249
|
+
}
|
|
28250
|
+
handleTurn(event) {
|
|
28251
|
+
const scope = scopeKey(event);
|
|
28252
|
+
const state = this.ensureTurnState(event);
|
|
28253
|
+
const text = state.text.join("");
|
|
28254
|
+
const reasoning = state.finalThinking ?? state.thinking.join("");
|
|
28255
|
+
const outputReasoning = reasoning || (state.hasThinking ? "[reasoning stream present; content unavailable]" : void 0);
|
|
28256
|
+
const metadata = {
|
|
28257
|
+
...state.metadata,
|
|
28258
|
+
...extractEventMetadata(event),
|
|
28259
|
+
...event.model ? { model: event.model, "flue.model": event.model } : {},
|
|
28260
|
+
...event.stopReason ? { "flue.stop_reason": event.stopReason } : {},
|
|
28261
|
+
...event.isError !== void 0 ? { "flue.is_error": event.isError } : {},
|
|
28262
|
+
provider: "flue"
|
|
28263
|
+
};
|
|
28264
|
+
safeLog3(state.span, {
|
|
28265
|
+
...event.error ? { error: errorToString(event.error) } : {},
|
|
28266
|
+
metadata,
|
|
28267
|
+
metrics: {
|
|
28268
|
+
...durationMsMetrics(event.durationMs),
|
|
28269
|
+
...metricsFromUsage(event.usage)
|
|
28270
|
+
},
|
|
28271
|
+
output: toAssistantOutput(
|
|
28272
|
+
text,
|
|
28273
|
+
event.stopReason,
|
|
28274
|
+
outputReasoning,
|
|
28275
|
+
state.toolCalls
|
|
28276
|
+
)
|
|
28277
|
+
});
|
|
28278
|
+
state.span.end();
|
|
28279
|
+
this.turnsByScope.delete(scope);
|
|
28280
|
+
}
|
|
28281
|
+
handleThinkingDelta(event) {
|
|
28282
|
+
const delta = event.delta;
|
|
28283
|
+
if (typeof delta !== "string" || !delta) {
|
|
28284
|
+
return;
|
|
28285
|
+
}
|
|
28286
|
+
const state = this.ensureTurnState(event);
|
|
28287
|
+
state.hasThinking = true;
|
|
28288
|
+
state.metadata["flue.thinking"] = true;
|
|
28289
|
+
state.thinking.push(delta);
|
|
28290
|
+
}
|
|
28291
|
+
handleThinkingStart(event) {
|
|
28292
|
+
const state = this.ensureTurnState(event);
|
|
28293
|
+
state.hasThinking = true;
|
|
28294
|
+
state.metadata["flue.thinking"] = true;
|
|
28295
|
+
}
|
|
28296
|
+
handleThinkingEnd(event) {
|
|
28297
|
+
const state = this.ensureTurnState(event);
|
|
28298
|
+
state.hasThinking = true;
|
|
28299
|
+
state.metadata["flue.thinking"] = true;
|
|
28300
|
+
if (typeof event.content === "string" && event.content) {
|
|
28301
|
+
state.finalThinking = event.content;
|
|
28302
|
+
}
|
|
28303
|
+
}
|
|
28304
|
+
handleToolStart(event, options) {
|
|
28305
|
+
const toolCallId = event.toolCallId;
|
|
28306
|
+
if (!toolCallId) {
|
|
28307
|
+
return;
|
|
28308
|
+
}
|
|
28309
|
+
const parent = this.parentSpanForEvent(event);
|
|
28310
|
+
const scope = scopeKey(event);
|
|
28311
|
+
let turnState = this.turnsByScope.get(scope);
|
|
28312
|
+
if (!turnState && parent && options.captureTurnSpans) {
|
|
28313
|
+
turnState = this.ensureTurnState(event);
|
|
28314
|
+
}
|
|
28315
|
+
const metadata = {
|
|
28316
|
+
...extractEventMetadata(event),
|
|
28317
|
+
...event.toolName ? { "flue.tool_name": event.toolName } : {},
|
|
28318
|
+
"flue.tool_call_id": toolCallId,
|
|
28319
|
+
provider: "flue"
|
|
28320
|
+
};
|
|
28321
|
+
const span = startFlueSpan(parent, {
|
|
28322
|
+
name: `tool: ${event.toolName ?? "unknown"}`,
|
|
28323
|
+
spanAttributes: { type: "tool" /* TOOL */ }
|
|
28324
|
+
});
|
|
28325
|
+
if (turnState) {
|
|
28326
|
+
turnState.toolCalls.push({
|
|
28327
|
+
args: event.args,
|
|
28328
|
+
toolCallId,
|
|
28329
|
+
toolName: event.toolName
|
|
28330
|
+
});
|
|
28331
|
+
}
|
|
28332
|
+
safeLog3(span, {
|
|
28333
|
+
input: event.args,
|
|
28334
|
+
metadata
|
|
28335
|
+
});
|
|
28336
|
+
this.toolsById.set(toolKey(event), {
|
|
28337
|
+
metadata,
|
|
28338
|
+
span,
|
|
28339
|
+
startTime: getCurrentUnixTimestamp()
|
|
28340
|
+
});
|
|
28341
|
+
}
|
|
28342
|
+
handleToolCall(event) {
|
|
28343
|
+
const key = toolKey(event);
|
|
28344
|
+
const state = this.toolsById.get(key) ?? this.startSyntheticToolState(event, event.toolName ?? "unknown");
|
|
28345
|
+
const metadata = {
|
|
28346
|
+
...state.metadata,
|
|
28347
|
+
...extractEventMetadata(event),
|
|
28348
|
+
...event.toolName ? { "flue.tool_name": event.toolName } : {},
|
|
28349
|
+
...event.toolCallId ? { "flue.tool_call_id": event.toolCallId } : {},
|
|
28350
|
+
...event.isError !== void 0 ? { "flue.is_error": event.isError } : {}
|
|
28351
|
+
};
|
|
28352
|
+
safeLog3(state.span, {
|
|
28353
|
+
...event.isError ? { error: errorToString(event.result) } : {},
|
|
28354
|
+
metadata,
|
|
28355
|
+
metrics: durationMsMetrics(event.durationMs),
|
|
28356
|
+
output: event.result
|
|
28357
|
+
});
|
|
28358
|
+
state.span.end();
|
|
28359
|
+
this.toolsById.delete(key);
|
|
28360
|
+
}
|
|
28361
|
+
handleTaskStart(event) {
|
|
28362
|
+
const parent = this.parentSpanForEvent(event);
|
|
28363
|
+
const metadata = {
|
|
28364
|
+
...extractEventMetadata(event),
|
|
28365
|
+
...event.role ? { "flue.role": event.role } : {},
|
|
28366
|
+
...event.cwd ? { "flue.cwd": event.cwd } : {},
|
|
28367
|
+
"flue.task_id": event.taskId,
|
|
28368
|
+
provider: "flue"
|
|
28369
|
+
};
|
|
28370
|
+
const span = startFlueSpan(parent, {
|
|
28371
|
+
name: "flue.task",
|
|
28372
|
+
spanAttributes: { type: "task" /* TASK */ }
|
|
28373
|
+
});
|
|
28374
|
+
safeLog3(span, {
|
|
28375
|
+
input: event.prompt,
|
|
28376
|
+
metadata
|
|
28377
|
+
});
|
|
28378
|
+
this.tasksById.set(event.taskId, {
|
|
28379
|
+
metadata,
|
|
28380
|
+
span,
|
|
28381
|
+
startTime: getCurrentUnixTimestamp()
|
|
28382
|
+
});
|
|
28383
|
+
}
|
|
28384
|
+
handleTask(event) {
|
|
28385
|
+
const state = this.tasksById.get(event.taskId);
|
|
28386
|
+
if (!state) {
|
|
28387
|
+
return;
|
|
28388
|
+
}
|
|
28389
|
+
safeLog3(state.span, {
|
|
28390
|
+
...event.isError ? { error: errorToString(event.result) } : {},
|
|
28391
|
+
metadata: {
|
|
28392
|
+
...state.metadata,
|
|
28393
|
+
...extractEventMetadata(event),
|
|
28394
|
+
...event.isError !== void 0 ? { "flue.is_error": event.isError } : {}
|
|
28395
|
+
},
|
|
28396
|
+
metrics: durationMsMetrics(event.durationMs),
|
|
28397
|
+
output: event.result
|
|
28398
|
+
});
|
|
28399
|
+
state.span.end();
|
|
28400
|
+
this.tasksById.delete(event.taskId);
|
|
28401
|
+
}
|
|
28402
|
+
handleCompactionStart(event) {
|
|
28403
|
+
const operationState = this.operationStateForEvent(event);
|
|
28404
|
+
const parent = operationState?.span ?? this.parentSpanForEvent(event);
|
|
28405
|
+
const metadata = {
|
|
28406
|
+
...extractEventMetadata(event),
|
|
28407
|
+
...event.reason ? { "flue.compaction_reason": event.reason } : {},
|
|
28408
|
+
provider: "flue"
|
|
28409
|
+
};
|
|
28410
|
+
const input = {
|
|
28411
|
+
...typeof event.estimatedTokens === "number" ? { estimatedTokens: event.estimatedTokens } : {},
|
|
28412
|
+
...event.reason ? { reason: event.reason } : {}
|
|
28413
|
+
};
|
|
28414
|
+
const span = startFlueSpan(parent, {
|
|
28415
|
+
name: "flue.compaction",
|
|
28416
|
+
spanAttributes: { type: "task" /* TASK */ }
|
|
28417
|
+
});
|
|
28418
|
+
safeLog3(span, {
|
|
28419
|
+
input,
|
|
28420
|
+
metadata
|
|
28421
|
+
});
|
|
28422
|
+
this.compactionsByScope.set(scopeKey(event), {
|
|
28423
|
+
input,
|
|
28424
|
+
metadata,
|
|
28425
|
+
operationState,
|
|
28426
|
+
span,
|
|
28427
|
+
startTime: getCurrentUnixTimestamp()
|
|
28428
|
+
});
|
|
28429
|
+
}
|
|
28430
|
+
handleCompaction(event) {
|
|
28431
|
+
const key = scopeKey(event);
|
|
28432
|
+
const state = this.compactionsByScope.get(key) ?? this.findCompactionState(event);
|
|
28433
|
+
if (!state) {
|
|
28434
|
+
return;
|
|
28435
|
+
}
|
|
28436
|
+
safeLog3(state.span, {
|
|
28437
|
+
metadata: {
|
|
28438
|
+
...state.metadata,
|
|
28439
|
+
...extractEventMetadata(event),
|
|
28440
|
+
...typeof event.messagesBefore === "number" ? { "flue.messages_before": event.messagesBefore } : {},
|
|
28441
|
+
...typeof event.messagesAfter === "number" ? { "flue.messages_after": event.messagesAfter } : {}
|
|
28442
|
+
},
|
|
28443
|
+
metrics: {
|
|
28444
|
+
...durationMsMetrics(event.durationMs),
|
|
28445
|
+
...metricsFromUsage(event.usage)
|
|
28446
|
+
},
|
|
28447
|
+
output: {
|
|
28448
|
+
messagesAfter: event.messagesAfter,
|
|
28449
|
+
messagesBefore: event.messagesBefore
|
|
28450
|
+
}
|
|
28451
|
+
});
|
|
28452
|
+
state.span.end();
|
|
28453
|
+
this.deleteCompactionState(state);
|
|
28454
|
+
}
|
|
28455
|
+
findCompactionState(event) {
|
|
28456
|
+
const operationState = this.operationStateForEvent(event);
|
|
28457
|
+
for (const state of this.compactionsByScope.values()) {
|
|
28458
|
+
if (operationState && state.operationState === operationState) {
|
|
28459
|
+
return state;
|
|
28460
|
+
}
|
|
28461
|
+
}
|
|
28462
|
+
return void 0;
|
|
28463
|
+
}
|
|
28464
|
+
finishCompactionsForOperation(operationState) {
|
|
28465
|
+
for (const state of [...this.compactionsByScope.values()]) {
|
|
28466
|
+
if (state.operationState !== operationState) {
|
|
28467
|
+
continue;
|
|
28468
|
+
}
|
|
28469
|
+
safeLog3(state.span, {
|
|
28470
|
+
input: state.input,
|
|
28471
|
+
metadata: state.metadata,
|
|
28472
|
+
metrics: {
|
|
28473
|
+
...buildDurationMetrics3(state.startTime)
|
|
28474
|
+
},
|
|
28475
|
+
output: { completed: true }
|
|
28476
|
+
});
|
|
28477
|
+
state.span.end();
|
|
28478
|
+
this.deleteCompactionState(state);
|
|
28479
|
+
}
|
|
28480
|
+
}
|
|
28481
|
+
deleteCompactionState(state) {
|
|
28482
|
+
for (const [key, candidate] of this.compactionsByScope) {
|
|
28483
|
+
if (candidate !== state) {
|
|
28484
|
+
continue;
|
|
28485
|
+
}
|
|
28486
|
+
this.compactionsByScope.delete(key);
|
|
28487
|
+
return;
|
|
28488
|
+
}
|
|
28489
|
+
}
|
|
28490
|
+
startSyntheticToolState(event, toolName) {
|
|
28491
|
+
const parent = this.parentSpanForEvent(event);
|
|
28492
|
+
const metadata = {
|
|
28493
|
+
...extractEventMetadata(event),
|
|
28494
|
+
...event.toolCallId ? { "flue.tool_call_id": event.toolCallId } : {},
|
|
28495
|
+
"flue.tool_name": toolName,
|
|
28496
|
+
provider: "flue"
|
|
28497
|
+
};
|
|
28498
|
+
const span = startFlueSpan(parent, {
|
|
28499
|
+
name: `tool: ${toolName}`,
|
|
28500
|
+
spanAttributes: { type: "tool" /* TOOL */ }
|
|
28501
|
+
});
|
|
28502
|
+
safeLog3(span, { metadata });
|
|
28503
|
+
return { metadata, span, startTime: getCurrentUnixTimestamp() };
|
|
28504
|
+
}
|
|
28505
|
+
operationStateForEvent(event) {
|
|
28506
|
+
if (event.operationId) {
|
|
28507
|
+
const operation = this.activeOperationsById.get(event.operationId) ?? this.promotePendingOperationForEvent(event);
|
|
28508
|
+
if (operation) {
|
|
28509
|
+
return operation;
|
|
28510
|
+
}
|
|
28511
|
+
}
|
|
28512
|
+
return this.activeOperationForEventScope(event) ?? this.pendingOperationForEventScope(event);
|
|
28513
|
+
}
|
|
28514
|
+
parentSpanForEvent(event) {
|
|
28515
|
+
if (event.operationId) {
|
|
28516
|
+
const operation = this.operationStateForEvent(event);
|
|
28517
|
+
if (operation) {
|
|
28518
|
+
return operation.span;
|
|
28519
|
+
}
|
|
28520
|
+
}
|
|
28521
|
+
if (event.taskId) {
|
|
28522
|
+
return this.tasksById.get(event.taskId)?.span;
|
|
28523
|
+
}
|
|
28524
|
+
return this.operationStateForEvent(event)?.span;
|
|
28525
|
+
}
|
|
28526
|
+
promotePendingOperationForEvent(event) {
|
|
28527
|
+
if (!event.operationId) {
|
|
28528
|
+
return void 0;
|
|
28529
|
+
}
|
|
28530
|
+
const scopePrefixes = operationScopePrefixes(event);
|
|
28531
|
+
for (const [candidateKey, candidateQueue] of this.pendingOperationsByKey) {
|
|
28532
|
+
if (!candidateQueue.length || !operationKeyMatchesScopes(candidateKey, scopePrefixes)) {
|
|
28533
|
+
continue;
|
|
28534
|
+
}
|
|
28535
|
+
const state = candidateQueue.shift();
|
|
28536
|
+
if (!state) {
|
|
28537
|
+
return void 0;
|
|
28538
|
+
}
|
|
28539
|
+
state.operationId = event.operationId;
|
|
28540
|
+
this.activeOperationsById.set(event.operationId, state);
|
|
28541
|
+
addScopedOperation(this.activeOperationsByScope, event, state);
|
|
28542
|
+
state.metadata = {
|
|
28543
|
+
...state.metadata,
|
|
28544
|
+
...extractEventMetadata(event),
|
|
28545
|
+
"flue.operation_id": event.operationId
|
|
28546
|
+
};
|
|
28547
|
+
safeLog3(state.span, { metadata: state.metadata });
|
|
28548
|
+
return state;
|
|
28549
|
+
}
|
|
28550
|
+
return void 0;
|
|
28551
|
+
}
|
|
28552
|
+
activeOperationForEventScope(event) {
|
|
28553
|
+
for (const scope of operationScopeNames(event)) {
|
|
28554
|
+
const operations = this.activeOperationsByScope.get(scope);
|
|
28555
|
+
if (operations?.length) {
|
|
28556
|
+
return operations[operations.length - 1];
|
|
28557
|
+
}
|
|
28558
|
+
}
|
|
28559
|
+
return void 0;
|
|
28560
|
+
}
|
|
28561
|
+
pendingOperationForEventScope(event) {
|
|
28562
|
+
const scopePrefixes = operationScopePrefixes(event);
|
|
28563
|
+
for (const [candidateKey, candidateQueue] of this.pendingOperationsByKey) {
|
|
28564
|
+
if (!candidateQueue.length || !operationKeyMatchesScopes(candidateKey, scopePrefixes)) {
|
|
28565
|
+
continue;
|
|
28566
|
+
}
|
|
28567
|
+
return candidateQueue[0];
|
|
28568
|
+
}
|
|
28569
|
+
return void 0;
|
|
28570
|
+
}
|
|
28571
|
+
takePendingOperationForEvent(event) {
|
|
28572
|
+
const key = operationKey(event.session, event.operationKind);
|
|
28573
|
+
const queue2 = this.pendingOperationsByKey.get(key);
|
|
28574
|
+
if (queue2?.length) {
|
|
28575
|
+
return queue2.shift();
|
|
28576
|
+
}
|
|
28577
|
+
for (const [candidateKey, candidateQueue] of this.pendingOperationsByKey) {
|
|
28578
|
+
if (candidateKey.endsWith(`::${event.operationKind}`) && candidateQueue.length) {
|
|
28579
|
+
return candidateQueue.shift();
|
|
28580
|
+
}
|
|
28581
|
+
}
|
|
28582
|
+
return void 0;
|
|
28583
|
+
}
|
|
28584
|
+
pendingOperationQueue(key) {
|
|
28585
|
+
const existing = this.pendingOperationsByKey.get(key);
|
|
28586
|
+
if (existing) {
|
|
28587
|
+
return existing;
|
|
28588
|
+
}
|
|
28589
|
+
const queue2 = [];
|
|
28590
|
+
this.pendingOperationsByKey.set(key, queue2);
|
|
28591
|
+
return queue2;
|
|
28592
|
+
}
|
|
28593
|
+
};
|
|
28594
|
+
function isInstrumentedOperation(operation) {
|
|
28595
|
+
return operation === "prompt" || operation === "skill" || operation === "task" || operation === "compact";
|
|
28596
|
+
}
|
|
28597
|
+
function getSessionName(session) {
|
|
28598
|
+
return typeof session?.name === "string" ? session.name : void 0;
|
|
28599
|
+
}
|
|
28600
|
+
function operationKey(sessionName, operation) {
|
|
28601
|
+
return `${sessionName ?? "unknown"}::${operation}`;
|
|
28602
|
+
}
|
|
28603
|
+
function operationScopePrefixes(event) {
|
|
28604
|
+
const scopes = /* @__PURE__ */ new Set();
|
|
28605
|
+
for (const scope of operationScopeNames(event)) {
|
|
28606
|
+
scopes.add(`${scope}::`);
|
|
28607
|
+
}
|
|
28608
|
+
return scopes;
|
|
28609
|
+
}
|
|
28610
|
+
function operationKeyMatchesScopes(key, scopes) {
|
|
28611
|
+
for (const scope of scopes) {
|
|
28612
|
+
if (key.startsWith(scope)) {
|
|
28613
|
+
return true;
|
|
28614
|
+
}
|
|
28615
|
+
}
|
|
28616
|
+
return false;
|
|
28617
|
+
}
|
|
28618
|
+
function operationScopeNames(event) {
|
|
28619
|
+
const scopes = /* @__PURE__ */ new Set();
|
|
28620
|
+
if (event.session) {
|
|
28621
|
+
scopes.add(event.session);
|
|
28622
|
+
}
|
|
28623
|
+
if (event.parentSession) {
|
|
28624
|
+
scopes.add(event.parentSession);
|
|
28625
|
+
}
|
|
28626
|
+
if (!scopes.size) {
|
|
28627
|
+
scopes.add("unknown");
|
|
28628
|
+
}
|
|
28629
|
+
return scopes;
|
|
28630
|
+
}
|
|
28631
|
+
function addScopedOperation(operationsByScope, event, state) {
|
|
28632
|
+
for (const scope of operationScopeNames(event)) {
|
|
28633
|
+
addOperationToScope(operationsByScope, scope, state);
|
|
28634
|
+
}
|
|
28635
|
+
}
|
|
28636
|
+
function addOperationToScope(operationsByScope, scope, state) {
|
|
28637
|
+
const operations = operationsByScope.get(scope);
|
|
28638
|
+
if (operations) {
|
|
28639
|
+
if (!operations.includes(state)) {
|
|
28640
|
+
operations.push(state);
|
|
28641
|
+
}
|
|
28642
|
+
} else {
|
|
28643
|
+
operationsByScope.set(scope, [state]);
|
|
28644
|
+
}
|
|
28645
|
+
}
|
|
28646
|
+
function removeScopedOperation(operationsByScope, state) {
|
|
28647
|
+
for (const [scope, operations] of operationsByScope) {
|
|
28648
|
+
const index = operations.indexOf(state);
|
|
28649
|
+
if (index === -1) {
|
|
28650
|
+
continue;
|
|
28651
|
+
}
|
|
28652
|
+
operations.splice(index, 1);
|
|
28653
|
+
if (operations.length === 0) {
|
|
28654
|
+
operationsByScope.delete(scope);
|
|
28655
|
+
}
|
|
28656
|
+
}
|
|
28657
|
+
}
|
|
28658
|
+
function removePendingOperation(pendingOperationsByKey, state) {
|
|
28659
|
+
for (const [key, queue2] of pendingOperationsByKey) {
|
|
28660
|
+
const index = queue2.indexOf(state);
|
|
28661
|
+
if (index === -1) {
|
|
28662
|
+
continue;
|
|
28663
|
+
}
|
|
28664
|
+
queue2.splice(index, 1);
|
|
28665
|
+
if (queue2.length === 0) {
|
|
28666
|
+
pendingOperationsByKey.delete(key);
|
|
28667
|
+
}
|
|
28668
|
+
return;
|
|
28669
|
+
}
|
|
28670
|
+
}
|
|
28671
|
+
function extractSessionMetadata(session) {
|
|
28672
|
+
const sessionName = getSessionName(session);
|
|
28673
|
+
return sessionName ? { "flue.session": sessionName } : {};
|
|
28674
|
+
}
|
|
28675
|
+
function extractEventMetadata(event) {
|
|
28676
|
+
return {
|
|
28677
|
+
...event.runId ? { "flue.run_id": event.runId } : {},
|
|
28678
|
+
...typeof event.eventIndex === "number" ? { "flue.event_index": event.eventIndex } : {},
|
|
28679
|
+
...event.session ? { "flue.session": event.session } : {},
|
|
28680
|
+
...event.parentSession ? { "flue.parent_session": event.parentSession } : {},
|
|
28681
|
+
...event.harness ? { "flue.harness": event.harness } : {},
|
|
28682
|
+
...event.taskId ? { "flue.task_id": event.taskId } : {},
|
|
28683
|
+
...event.operationId ? { "flue.operation_id": event.operationId } : {}
|
|
28684
|
+
};
|
|
28685
|
+
}
|
|
28686
|
+
function extractOperationInput(operation, args) {
|
|
28687
|
+
switch (operation) {
|
|
28688
|
+
case "prompt":
|
|
28689
|
+
case "task":
|
|
28690
|
+
return args[0];
|
|
28691
|
+
case "skill":
|
|
28692
|
+
return {
|
|
28693
|
+
args: getOptionObject(args[1])?.args,
|
|
28694
|
+
name: args[0]
|
|
28695
|
+
};
|
|
28696
|
+
case "compact":
|
|
28697
|
+
return void 0;
|
|
28698
|
+
}
|
|
28699
|
+
}
|
|
28700
|
+
function extractOperationInputMetadata(operation, args) {
|
|
28701
|
+
const options = getOptionObject(args[1]);
|
|
28702
|
+
return {
|
|
28703
|
+
...operation === "skill" && typeof args[0] === "string" ? { "flue.skill_name": args[0] } : {},
|
|
28704
|
+
...options?.model ? { model: options.model, "flue.model": options.model } : {},
|
|
28705
|
+
...options?.role ? { "flue.role": options.role } : {},
|
|
28706
|
+
...options?.thinkingLevel ? { "flue.thinking_level": options.thinkingLevel } : {},
|
|
28707
|
+
...typeof options?.cwd === "string" ? { "flue.cwd": options.cwd } : {},
|
|
28708
|
+
...Array.isArray(options?.tools) ? {
|
|
28709
|
+
"flue.tools_count": options.tools.length,
|
|
28710
|
+
tools: summarizeTools(options.tools)
|
|
28711
|
+
} : {},
|
|
28712
|
+
...Array.isArray(options?.images) ? { "flue.images_count": options.images.length } : {},
|
|
28713
|
+
...options?.result || options?.schema ? { "flue.result_schema": true } : {}
|
|
28714
|
+
};
|
|
28715
|
+
}
|
|
28716
|
+
function getOptionObject(value) {
|
|
28717
|
+
return isObject(value) ? value : void 0;
|
|
28718
|
+
}
|
|
28719
|
+
function summarizeTools(tools) {
|
|
28720
|
+
return tools.flatMap((tool) => {
|
|
28721
|
+
if (!isObject(tool)) {
|
|
28722
|
+
return [];
|
|
28723
|
+
}
|
|
28724
|
+
const name = typeof tool.name === "string" ? tool.name : void 0;
|
|
28725
|
+
if (!name) {
|
|
28726
|
+
return [];
|
|
28727
|
+
}
|
|
28728
|
+
return [
|
|
28729
|
+
{
|
|
28730
|
+
function: {
|
|
28731
|
+
description: typeof tool.description === "string" ? tool.description : void 0,
|
|
28732
|
+
name,
|
|
28733
|
+
parameters: tool.parameters
|
|
28734
|
+
},
|
|
28735
|
+
type: "function"
|
|
28736
|
+
}
|
|
28737
|
+
];
|
|
28738
|
+
});
|
|
28739
|
+
}
|
|
28740
|
+
function extractPromptResponseMetadata(result) {
|
|
28741
|
+
const modelId = result?.model && typeof result.model.id === "string" ? result.model.id : void 0;
|
|
28742
|
+
return modelId ? {
|
|
28743
|
+
model: modelId,
|
|
28744
|
+
"flue.model": modelId
|
|
28745
|
+
} : {};
|
|
28746
|
+
}
|
|
28747
|
+
function extractOperationOutput(result) {
|
|
28748
|
+
if (!result) {
|
|
28749
|
+
return void 0;
|
|
28750
|
+
}
|
|
28751
|
+
if ("data" in result) {
|
|
28752
|
+
return result.data;
|
|
28753
|
+
}
|
|
28754
|
+
if ("text" in result) {
|
|
28755
|
+
return result.text;
|
|
28756
|
+
}
|
|
28757
|
+
return result;
|
|
28758
|
+
}
|
|
28759
|
+
function metricsFromUsage(usage) {
|
|
28760
|
+
return {
|
|
28761
|
+
...typeof usage?.input === "number" ? { prompt_tokens: usage.input } : {},
|
|
28762
|
+
...typeof usage?.output === "number" ? { completion_tokens: usage.output } : {},
|
|
28763
|
+
...typeof usage?.cacheRead === "number" ? { prompt_cached_tokens: usage.cacheRead } : {},
|
|
28764
|
+
...typeof usage?.cacheWrite === "number" ? { prompt_cache_creation_tokens: usage.cacheWrite } : {},
|
|
28765
|
+
...typeof usage?.totalTokens === "number" ? { tokens: usage.totalTokens } : {},
|
|
28766
|
+
...typeof usage?.cost?.total === "number" ? { estimated_cost: usage.cost.total } : {}
|
|
28767
|
+
};
|
|
28768
|
+
}
|
|
28769
|
+
function buildDurationMetrics3(startTime) {
|
|
28770
|
+
return {
|
|
28771
|
+
duration_ms: Math.max(0, (getCurrentUnixTimestamp() - startTime) * 1e3)
|
|
28772
|
+
};
|
|
28773
|
+
}
|
|
28774
|
+
function durationMsMetrics(durationMs) {
|
|
28775
|
+
return typeof durationMs === "number" ? { duration_ms: durationMs } : {};
|
|
28776
|
+
}
|
|
28777
|
+
function scopeKey(event) {
|
|
28778
|
+
if (event.operationId) {
|
|
28779
|
+
return `operation:${event.operationId}`;
|
|
28780
|
+
}
|
|
28781
|
+
if (event.taskId) {
|
|
28782
|
+
return `task:${event.taskId}`;
|
|
28783
|
+
}
|
|
28784
|
+
if (event.session) {
|
|
28785
|
+
return `session:${event.session}`;
|
|
28786
|
+
}
|
|
28787
|
+
return "flue:unknown";
|
|
28788
|
+
}
|
|
28789
|
+
function toolKey(event) {
|
|
28790
|
+
return `${scopeKey(event)}::tool:${event.toolCallId ?? "unknown"}`;
|
|
28791
|
+
}
|
|
28792
|
+
function toAssistantOutput(text, finishReason, reasoning, toolCalls) {
|
|
28793
|
+
return [
|
|
28794
|
+
{
|
|
28795
|
+
finish_reason: finishReason ?? "stop",
|
|
28796
|
+
index: 0,
|
|
28797
|
+
message: {
|
|
28798
|
+
content: text,
|
|
28799
|
+
...reasoning ? { reasoning } : {},
|
|
28800
|
+
role: "assistant",
|
|
28801
|
+
...toolCalls?.length ? {
|
|
28802
|
+
tool_calls: toolCalls.map((toolCall) => ({
|
|
28803
|
+
function: {
|
|
28804
|
+
arguments: toolCall.args === void 0 ? "{}" : JSON.stringify(toolCall.args),
|
|
28805
|
+
name: toolCall.toolName ?? "unknown"
|
|
28806
|
+
},
|
|
28807
|
+
...toolCall.toolCallId ? { id: toolCall.toolCallId } : {},
|
|
28808
|
+
type: "function"
|
|
28809
|
+
}))
|
|
28810
|
+
} : {}
|
|
28811
|
+
}
|
|
28812
|
+
}
|
|
28813
|
+
];
|
|
28814
|
+
}
|
|
28815
|
+
function startFlueSpan(parent, args) {
|
|
28816
|
+
return parent ? withCurrent(parent, () => startSpan(args)) : startSpan(args);
|
|
28817
|
+
}
|
|
28818
|
+
function safeLog3(span, event) {
|
|
28819
|
+
try {
|
|
28820
|
+
span.log(event);
|
|
28821
|
+
} catch (error2) {
|
|
28822
|
+
logInstrumentationError3("Flue span log", error2);
|
|
28823
|
+
}
|
|
28824
|
+
}
|
|
28825
|
+
function errorToString(error2) {
|
|
28826
|
+
if (error2 instanceof Error) {
|
|
28827
|
+
return error2.message;
|
|
28828
|
+
}
|
|
28829
|
+
if (typeof error2 === "string") {
|
|
28830
|
+
return error2;
|
|
28831
|
+
}
|
|
28832
|
+
try {
|
|
28833
|
+
return JSON.stringify(error2);
|
|
28834
|
+
} catch {
|
|
28835
|
+
return String(error2);
|
|
28836
|
+
}
|
|
28837
|
+
}
|
|
28838
|
+
function logInstrumentationError3(label, error2) {
|
|
28839
|
+
console.error(`Error in ${label} instrumentation:`, error2);
|
|
28840
|
+
}
|
|
28841
|
+
|
|
28842
|
+
// src/wrappers/langchain/callback-handler.ts
|
|
28843
|
+
var BRAINTRUST_LANGCHAIN_CALLBACK_HANDLER_NAME = "BraintrustCallbackHandler";
|
|
28844
|
+
var BraintrustLangChainCallbackHandler = class {
|
|
28845
|
+
name = BRAINTRUST_LANGCHAIN_CALLBACK_HANDLER_NAME;
|
|
28846
|
+
spans = /* @__PURE__ */ new Map();
|
|
28847
|
+
skippedRuns = /* @__PURE__ */ new Set();
|
|
28848
|
+
parent;
|
|
28849
|
+
rootRunId;
|
|
28850
|
+
options;
|
|
28851
|
+
startTimes = /* @__PURE__ */ new Map();
|
|
28852
|
+
firstTokenTimes = /* @__PURE__ */ new Map();
|
|
28853
|
+
ttftMs = /* @__PURE__ */ new Map();
|
|
28854
|
+
constructor(options) {
|
|
28855
|
+
this.parent = options?.parent;
|
|
28856
|
+
this.options = {
|
|
28857
|
+
debug: options?.debug ?? false,
|
|
28858
|
+
excludeMetadataProps: options?.excludeMetadataProps ?? /^(l[sc]_|langgraph_|__pregel_|checkpoint_ns)/,
|
|
28859
|
+
logger: options?.logger
|
|
28860
|
+
};
|
|
28861
|
+
}
|
|
28862
|
+
startSpan({
|
|
28863
|
+
runId,
|
|
28864
|
+
parentRunId,
|
|
28865
|
+
...args
|
|
28866
|
+
}) {
|
|
28867
|
+
if (this.spans.has(runId)) {
|
|
28868
|
+
return;
|
|
28869
|
+
}
|
|
28870
|
+
if (!parentRunId) {
|
|
28871
|
+
this.rootRunId = runId;
|
|
28872
|
+
}
|
|
28873
|
+
const tags = args.event?.tags;
|
|
28874
|
+
const spanAttributes = args.spanAttributes || {};
|
|
28875
|
+
spanAttributes.type = args.type || spanAttributes.type || "task";
|
|
28876
|
+
args.type = spanAttributes.type;
|
|
28877
|
+
const currentParent = (typeof this.parent === "function" ? this.parent() : this.parent) ?? currentSpan();
|
|
28878
|
+
let parentSpan;
|
|
28879
|
+
if (parentRunId && this.spans.has(parentRunId)) {
|
|
28880
|
+
parentSpan = this.spans.get(parentRunId);
|
|
28881
|
+
} else if (!Object.is(currentParent, NOOP_SPAN)) {
|
|
28882
|
+
parentSpan = currentParent;
|
|
28883
|
+
} else if (this.options.logger) {
|
|
28884
|
+
parentSpan = this.options.logger;
|
|
28885
|
+
} else {
|
|
28886
|
+
parentSpan = { startSpan };
|
|
28887
|
+
}
|
|
28888
|
+
args.event = {
|
|
28889
|
+
...args.event,
|
|
28890
|
+
tags: void 0,
|
|
28891
|
+
metadata: {
|
|
28892
|
+
...tags ? { tags } : {},
|
|
28893
|
+
...args.event?.metadata,
|
|
28894
|
+
braintrust: {
|
|
28895
|
+
integration_name: "langchain-js",
|
|
28896
|
+
sdk_language: "javascript"
|
|
28897
|
+
},
|
|
28898
|
+
run_id: runId,
|
|
28899
|
+
parent_run_id: parentRunId,
|
|
28900
|
+
...this.options.debug ? { runId, parentRunId } : {}
|
|
28901
|
+
}
|
|
28902
|
+
};
|
|
28903
|
+
let span = parentSpan.startSpan(args);
|
|
28904
|
+
if (!Object.is(this.options.logger, NOOP_SPAN) && Object.is(span, NOOP_SPAN)) {
|
|
28905
|
+
span = initLogger().startSpan(args);
|
|
28906
|
+
}
|
|
28907
|
+
this.spans.set(runId, span);
|
|
28908
|
+
}
|
|
28909
|
+
endSpan({
|
|
28910
|
+
runId,
|
|
28911
|
+
parentRunId,
|
|
28912
|
+
tags,
|
|
28913
|
+
metadata,
|
|
28914
|
+
...args
|
|
28915
|
+
}) {
|
|
28916
|
+
if (!this.spans.has(runId)) {
|
|
28917
|
+
return;
|
|
28918
|
+
}
|
|
28919
|
+
if (this.skippedRuns.has(runId)) {
|
|
28920
|
+
this.skippedRuns.delete(runId);
|
|
28921
|
+
return;
|
|
28922
|
+
}
|
|
28923
|
+
const span = this.spans.get(runId);
|
|
28924
|
+
this.spans.delete(runId);
|
|
28925
|
+
if (runId === this.rootRunId) {
|
|
28926
|
+
this.rootRunId = void 0;
|
|
28927
|
+
}
|
|
28928
|
+
span.log({ ...args, metadata: { tags, ...metadata } });
|
|
28929
|
+
span.end();
|
|
28930
|
+
}
|
|
28931
|
+
async handleLLMStart(llm, prompts, runId, parentRunId, extraParams, tags, metadata, runName) {
|
|
28932
|
+
this.startSpan({
|
|
28933
|
+
runId,
|
|
28934
|
+
parentRunId,
|
|
28935
|
+
name: runName ?? getSerializedName(llm) ?? "LLM",
|
|
28936
|
+
type: "llm",
|
|
28937
|
+
event: {
|
|
28938
|
+
input: prompts,
|
|
28939
|
+
tags,
|
|
28940
|
+
metadata: {
|
|
28941
|
+
serialized: llm,
|
|
28942
|
+
name: runName,
|
|
28943
|
+
metadata,
|
|
28944
|
+
...extraParams
|
|
28945
|
+
}
|
|
28946
|
+
}
|
|
28947
|
+
});
|
|
28948
|
+
}
|
|
28949
|
+
async handleLLMError(err, runId, parentRunId, tags) {
|
|
28950
|
+
this.endSpan({ runId, parentRunId, error: err, tags });
|
|
28951
|
+
}
|
|
28952
|
+
async handleLLMEnd(output, runId, parentRunId, tags) {
|
|
28953
|
+
const metrics = getMetricsFromResponse(output);
|
|
28954
|
+
const modelName2 = getModelNameFromResponse(output);
|
|
28955
|
+
const ttft = this.ttftMs.get(runId);
|
|
28956
|
+
if (ttft !== void 0) {
|
|
28957
|
+
metrics.time_to_first_token = ttft;
|
|
28958
|
+
}
|
|
28959
|
+
this.startTimes.delete(runId);
|
|
28960
|
+
this.firstTokenTimes.delete(runId);
|
|
28961
|
+
this.ttftMs.delete(runId);
|
|
28962
|
+
this.endSpan({
|
|
28963
|
+
runId,
|
|
28964
|
+
parentRunId,
|
|
28965
|
+
output,
|
|
28966
|
+
metrics,
|
|
28967
|
+
tags,
|
|
28968
|
+
metadata: {
|
|
28969
|
+
model: modelName2
|
|
28970
|
+
}
|
|
28971
|
+
});
|
|
28972
|
+
}
|
|
28973
|
+
async handleChatModelStart(llm, messages, runId, parentRunId, extraParams, tags, metadata, runName) {
|
|
28974
|
+
this.startTimes.set(runId, Date.now());
|
|
28975
|
+
this.firstTokenTimes.delete(runId);
|
|
28976
|
+
this.ttftMs.delete(runId);
|
|
28977
|
+
this.startSpan({
|
|
28978
|
+
runId,
|
|
28979
|
+
parentRunId,
|
|
28980
|
+
name: runName ?? getSerializedName(llm) ?? "Chat Model",
|
|
28981
|
+
type: "llm",
|
|
28982
|
+
event: {
|
|
28983
|
+
input: messages,
|
|
28984
|
+
tags,
|
|
28985
|
+
metadata: {
|
|
28986
|
+
serialized: llm,
|
|
28987
|
+
name: runName,
|
|
28988
|
+
metadata,
|
|
28989
|
+
...extraParams
|
|
28990
|
+
}
|
|
28991
|
+
}
|
|
28992
|
+
});
|
|
28993
|
+
}
|
|
28994
|
+
async handleChainStart(chain, inputs, runId, parentRunId, tags, metadata, runType, runName) {
|
|
28995
|
+
if (tags?.includes("langsmith:hidden")) {
|
|
28996
|
+
this.skippedRuns.add(runId);
|
|
28997
|
+
return;
|
|
28998
|
+
}
|
|
28999
|
+
this.startSpan({
|
|
29000
|
+
runId,
|
|
29001
|
+
parentRunId,
|
|
29002
|
+
name: runName ?? getSerializedName(chain) ?? "Chain",
|
|
29003
|
+
event: {
|
|
29004
|
+
input: inputs,
|
|
29005
|
+
tags,
|
|
29006
|
+
metadata: {
|
|
29007
|
+
serialized: chain,
|
|
29008
|
+
name: runName,
|
|
29009
|
+
metadata,
|
|
29010
|
+
run_type: runType
|
|
29011
|
+
}
|
|
29012
|
+
}
|
|
29013
|
+
});
|
|
29014
|
+
}
|
|
29015
|
+
async handleChainError(err, runId, parentRunId, tags, kwargs) {
|
|
29016
|
+
this.endSpan({ runId, parentRunId, error: err, tags, metadata: kwargs });
|
|
29017
|
+
}
|
|
29018
|
+
async handleChainEnd(outputs, runId, parentRunId, tags, kwargs) {
|
|
29019
|
+
this.endSpan({
|
|
29020
|
+
runId,
|
|
29021
|
+
parentRunId,
|
|
29022
|
+
tags,
|
|
29023
|
+
output: outputs,
|
|
29024
|
+
metadata: { ...kwargs }
|
|
29025
|
+
});
|
|
29026
|
+
}
|
|
29027
|
+
async handleToolStart(tool, input, runId, parentRunId, tags, metadata, runName) {
|
|
29028
|
+
this.startSpan({
|
|
29029
|
+
runId,
|
|
29030
|
+
parentRunId,
|
|
29031
|
+
name: runName ?? getSerializedName(tool) ?? "Tool",
|
|
29032
|
+
type: "llm",
|
|
29033
|
+
event: {
|
|
29034
|
+
input: safeJsonParse(input),
|
|
29035
|
+
tags,
|
|
29036
|
+
metadata: {
|
|
29037
|
+
metadata,
|
|
29038
|
+
serialized: tool,
|
|
29039
|
+
input_str: input,
|
|
29040
|
+
input: safeJsonParse(input),
|
|
29041
|
+
name: runName
|
|
29042
|
+
}
|
|
29043
|
+
}
|
|
29044
|
+
});
|
|
29045
|
+
}
|
|
29046
|
+
async handleToolError(err, runId, parentRunId, tags) {
|
|
29047
|
+
this.endSpan({ runId, parentRunId, error: err, tags });
|
|
29048
|
+
}
|
|
29049
|
+
async handleToolEnd(output, runId, parentRunId, tags) {
|
|
29050
|
+
this.endSpan({ runId, parentRunId, output, tags });
|
|
29051
|
+
}
|
|
29052
|
+
async handleAgentAction(action, runId, parentRunId, tags) {
|
|
29053
|
+
this.startSpan({
|
|
29054
|
+
runId,
|
|
29055
|
+
parentRunId,
|
|
29056
|
+
type: "llm",
|
|
29057
|
+
name: typeof action.tool === "string" ? action.tool : "Agent",
|
|
29058
|
+
event: {
|
|
29059
|
+
input: action,
|
|
29060
|
+
tags
|
|
29061
|
+
}
|
|
29062
|
+
});
|
|
29063
|
+
}
|
|
29064
|
+
async handleAgentEnd(action, runId, parentRunId, tags) {
|
|
29065
|
+
this.endSpan({ runId, parentRunId, output: action, tags });
|
|
29066
|
+
}
|
|
29067
|
+
async handleRetrieverStart(retriever, query, runId, parentRunId, tags, metadata, name) {
|
|
29068
|
+
this.startSpan({
|
|
29069
|
+
runId,
|
|
29070
|
+
parentRunId,
|
|
29071
|
+
name: name ?? getSerializedName(retriever) ?? "Retriever",
|
|
29072
|
+
type: "function",
|
|
29073
|
+
event: {
|
|
29074
|
+
input: query,
|
|
29075
|
+
tags,
|
|
29076
|
+
metadata: {
|
|
29077
|
+
serialized: retriever,
|
|
29078
|
+
metadata,
|
|
29079
|
+
name
|
|
29080
|
+
}
|
|
29081
|
+
}
|
|
29082
|
+
});
|
|
29083
|
+
}
|
|
29084
|
+
async handleRetrieverEnd(documents, runId, parentRunId, tags) {
|
|
29085
|
+
this.endSpan({ runId, parentRunId, output: documents, tags });
|
|
29086
|
+
}
|
|
29087
|
+
async handleRetrieverError(err, runId, parentRunId, tags) {
|
|
29088
|
+
this.endSpan({ runId, parentRunId, error: err, tags });
|
|
29089
|
+
}
|
|
29090
|
+
async handleLLMNewToken(_token, _idx, runId, _parentRunId, _tags) {
|
|
29091
|
+
if (!this.firstTokenTimes.has(runId)) {
|
|
29092
|
+
const now2 = Date.now();
|
|
29093
|
+
this.firstTokenTimes.set(runId, now2);
|
|
29094
|
+
const start = this.startTimes.get(runId);
|
|
29095
|
+
if (start !== void 0) {
|
|
29096
|
+
this.ttftMs.set(runId, (now2 - start) / 1e3);
|
|
29097
|
+
}
|
|
29098
|
+
}
|
|
29099
|
+
}
|
|
29100
|
+
};
|
|
29101
|
+
function getSerializedName(serialized) {
|
|
29102
|
+
if (typeof serialized.name === "string") {
|
|
29103
|
+
return serialized.name;
|
|
29104
|
+
}
|
|
29105
|
+
const lastIdPart = serialized.id?.at(-1);
|
|
29106
|
+
return typeof lastIdPart === "string" ? lastIdPart : void 0;
|
|
29107
|
+
}
|
|
29108
|
+
function cleanObject(obj) {
|
|
29109
|
+
return Object.fromEntries(
|
|
29110
|
+
Object.entries(obj).filter(([, value]) => {
|
|
29111
|
+
if (typeof value !== "number") {
|
|
29112
|
+
return false;
|
|
29113
|
+
}
|
|
29114
|
+
return Number.isFinite(value);
|
|
29115
|
+
})
|
|
29116
|
+
);
|
|
29117
|
+
}
|
|
29118
|
+
function walkGenerations(response) {
|
|
29119
|
+
const result = [];
|
|
29120
|
+
const generations = response.generations || [];
|
|
29121
|
+
for (const batch of generations) {
|
|
29122
|
+
if (Array.isArray(batch)) {
|
|
29123
|
+
for (const generation of batch) {
|
|
29124
|
+
if (isRecord(generation)) {
|
|
29125
|
+
result.push(generation);
|
|
29126
|
+
}
|
|
29127
|
+
}
|
|
29128
|
+
} else if (isRecord(batch)) {
|
|
29129
|
+
result.push(batch);
|
|
29130
|
+
}
|
|
29131
|
+
}
|
|
29132
|
+
return result;
|
|
29133
|
+
}
|
|
29134
|
+
function getModelNameFromResponse(response) {
|
|
29135
|
+
for (const generation of walkGenerations(response)) {
|
|
29136
|
+
const message = generation.message;
|
|
29137
|
+
if (!isRecord(message)) {
|
|
29138
|
+
continue;
|
|
29139
|
+
}
|
|
29140
|
+
const responseMetadata = message.response_metadata;
|
|
29141
|
+
if (!isRecord(responseMetadata)) {
|
|
29142
|
+
continue;
|
|
29143
|
+
}
|
|
29144
|
+
const modelName3 = responseMetadata.model_name ?? responseMetadata.model;
|
|
29145
|
+
if (typeof modelName3 === "string") {
|
|
29146
|
+
return modelName3;
|
|
29147
|
+
}
|
|
29148
|
+
}
|
|
29149
|
+
const llmOutput = response.llmOutput || {};
|
|
29150
|
+
const modelName2 = llmOutput.model_name ?? llmOutput.model;
|
|
29151
|
+
return typeof modelName2 === "string" ? modelName2 : void 0;
|
|
29152
|
+
}
|
|
29153
|
+
function getMetricsFromResponse(response) {
|
|
29154
|
+
for (const generation of walkGenerations(response)) {
|
|
29155
|
+
const message = generation.message;
|
|
29156
|
+
if (!isRecord(message)) {
|
|
29157
|
+
continue;
|
|
29158
|
+
}
|
|
29159
|
+
const usageMetadata = message.usage_metadata;
|
|
29160
|
+
if (!isRecord(usageMetadata)) {
|
|
29161
|
+
continue;
|
|
29162
|
+
}
|
|
29163
|
+
const inputTokenDetails = usageMetadata.input_token_details;
|
|
29164
|
+
return cleanObject({
|
|
29165
|
+
total_tokens: usageMetadata.total_tokens,
|
|
29166
|
+
prompt_tokens: usageMetadata.input_tokens,
|
|
29167
|
+
completion_tokens: usageMetadata.output_tokens,
|
|
29168
|
+
prompt_cache_creation_tokens: isRecord(inputTokenDetails) ? inputTokenDetails.cache_creation : void 0,
|
|
29169
|
+
prompt_cached_tokens: isRecord(inputTokenDetails) ? inputTokenDetails.cache_read : void 0
|
|
29170
|
+
});
|
|
29171
|
+
}
|
|
29172
|
+
const llmOutput = response.llmOutput || {};
|
|
29173
|
+
const tokenUsage = isRecord(llmOutput.tokenUsage) ? llmOutput.tokenUsage : isRecord(llmOutput.estimatedTokens) ? llmOutput.estimatedTokens : {};
|
|
29174
|
+
return cleanObject({
|
|
29175
|
+
total_tokens: tokenUsage.totalTokens,
|
|
29176
|
+
prompt_tokens: tokenUsage.promptTokens,
|
|
29177
|
+
completion_tokens: tokenUsage.completionTokens
|
|
29178
|
+
});
|
|
29179
|
+
}
|
|
29180
|
+
function safeJsonParse(input) {
|
|
29181
|
+
try {
|
|
29182
|
+
return JSON.parse(input);
|
|
29183
|
+
} catch {
|
|
29184
|
+
return input;
|
|
29185
|
+
}
|
|
29186
|
+
}
|
|
29187
|
+
function isRecord(value) {
|
|
29188
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
29189
|
+
}
|
|
29190
|
+
|
|
29191
|
+
// src/instrumentation/plugins/langchain-channels.ts
|
|
29192
|
+
var langChainChannels = defineChannels("@langchain/core", {
|
|
29193
|
+
configure: channel({
|
|
29194
|
+
channelName: "CallbackManager.configure",
|
|
29195
|
+
kind: "sync-stream"
|
|
29196
|
+
}),
|
|
29197
|
+
configureSync: channel({
|
|
29198
|
+
channelName: "CallbackManager._configureSync",
|
|
29199
|
+
kind: "sync-stream"
|
|
29200
|
+
})
|
|
29201
|
+
});
|
|
29202
|
+
|
|
29203
|
+
// src/instrumentation/plugins/langchain-plugin.ts
|
|
29204
|
+
var LangChainPlugin = class extends BasePlugin {
|
|
29205
|
+
injectedManagers = /* @__PURE__ */ new WeakSet();
|
|
29206
|
+
onEnable() {
|
|
29207
|
+
this.subscribeToConfigure(langChainChannels.configure);
|
|
29208
|
+
this.subscribeToConfigure(langChainChannels.configureSync);
|
|
29209
|
+
}
|
|
29210
|
+
onDisable() {
|
|
29211
|
+
for (const unsubscribe of this.unsubscribers) {
|
|
29212
|
+
unsubscribe();
|
|
29213
|
+
}
|
|
29214
|
+
this.unsubscribers = [];
|
|
29215
|
+
this.injectedManagers = /* @__PURE__ */ new WeakSet();
|
|
29216
|
+
}
|
|
29217
|
+
subscribeToConfigure(channel2) {
|
|
29218
|
+
const tracingChannel2 = channel2.tracingChannel();
|
|
29219
|
+
const handlers = {
|
|
29220
|
+
start: (event) => {
|
|
29221
|
+
injectHandlerIntoArguments(event.arguments);
|
|
29222
|
+
},
|
|
29223
|
+
end: (event) => {
|
|
29224
|
+
this.injectHandler(event.result);
|
|
29225
|
+
}
|
|
29226
|
+
};
|
|
29227
|
+
tracingChannel2.subscribe(handlers);
|
|
29228
|
+
this.unsubscribers.push(() => {
|
|
29229
|
+
tracingChannel2.unsubscribe(handlers);
|
|
29230
|
+
});
|
|
29231
|
+
}
|
|
29232
|
+
injectHandler(result) {
|
|
29233
|
+
if (!isCallbackManager(result)) {
|
|
29234
|
+
return;
|
|
29235
|
+
}
|
|
29236
|
+
if (this.injectedManagers.has(result) || hasBraintrustHandler(result)) {
|
|
29237
|
+
return;
|
|
29238
|
+
}
|
|
29239
|
+
try {
|
|
29240
|
+
result.addHandler(new BraintrustLangChainCallbackHandler(), true);
|
|
29241
|
+
this.injectedManagers.add(result);
|
|
29242
|
+
} catch {
|
|
29243
|
+
}
|
|
29244
|
+
}
|
|
29245
|
+
};
|
|
29246
|
+
function isCallbackManager(value) {
|
|
29247
|
+
if (typeof value !== "object" || value === null) {
|
|
29248
|
+
return false;
|
|
29249
|
+
}
|
|
29250
|
+
const maybeManager = value;
|
|
29251
|
+
return typeof maybeManager.addHandler === "function";
|
|
29252
|
+
}
|
|
29253
|
+
function hasBraintrustHandler(manager) {
|
|
29254
|
+
return manager.handlers?.some((handler) => {
|
|
29255
|
+
if (typeof handler !== "object" || handler === null) {
|
|
29256
|
+
return false;
|
|
29257
|
+
}
|
|
29258
|
+
const name = Reflect.get(handler, "name");
|
|
29259
|
+
return name === BRAINTRUST_LANGCHAIN_CALLBACK_HANDLER_NAME;
|
|
29260
|
+
}) ?? false;
|
|
29261
|
+
}
|
|
29262
|
+
function injectHandlerIntoArguments(args) {
|
|
29263
|
+
if (!isWritableArgumentsObject(args)) {
|
|
29264
|
+
return;
|
|
29265
|
+
}
|
|
29266
|
+
const inheritedHandlers = Reflect.get(args, "0");
|
|
29267
|
+
const handler = new BraintrustLangChainCallbackHandler();
|
|
29268
|
+
if (inheritedHandlers === void 0 || inheritedHandlers === null) {
|
|
29269
|
+
Reflect.set(args, "0", [handler]);
|
|
29270
|
+
return;
|
|
29271
|
+
}
|
|
29272
|
+
if (Array.isArray(inheritedHandlers)) {
|
|
29273
|
+
if (!inheritedHandlers.some(isBraintrustHandler)) {
|
|
29274
|
+
inheritedHandlers.push(handler);
|
|
29275
|
+
}
|
|
29276
|
+
}
|
|
29277
|
+
}
|
|
29278
|
+
function isWritableArgumentsObject(args) {
|
|
29279
|
+
return typeof args === "object" && args !== null;
|
|
29280
|
+
}
|
|
29281
|
+
function isBraintrustHandler(handler) {
|
|
29282
|
+
if (typeof handler !== "object" || handler === null) {
|
|
29283
|
+
return false;
|
|
29284
|
+
}
|
|
29285
|
+
return Reflect.get(handler, "name") === BRAINTRUST_LANGCHAIN_CALLBACK_HANDLER_NAME;
|
|
29286
|
+
}
|
|
29287
|
+
|
|
29288
|
+
// src/instrumentation/braintrust-plugin.ts
|
|
29289
|
+
function getIntegrationConfig(integrations, key) {
|
|
29290
|
+
return integrations[key];
|
|
29291
|
+
}
|
|
29292
|
+
var BraintrustPlugin = class extends BasePlugin {
|
|
29293
|
+
config;
|
|
29294
|
+
openaiPlugin = null;
|
|
29295
|
+
openAICodexPlugin = null;
|
|
29296
|
+
anthropicPlugin = null;
|
|
29297
|
+
aiSDKPlugin = null;
|
|
29298
|
+
claudeAgentSDKPlugin = null;
|
|
29299
|
+
cursorSDKPlugin = null;
|
|
29300
|
+
openAIAgentsPlugin = null;
|
|
29301
|
+
googleGenAIPlugin = null;
|
|
29302
|
+
huggingFacePlugin = null;
|
|
29303
|
+
openRouterPlugin = null;
|
|
29304
|
+
openRouterAgentPlugin = null;
|
|
29305
|
+
mistralPlugin = null;
|
|
29306
|
+
googleADKPlugin = null;
|
|
29307
|
+
coherePlugin = null;
|
|
29308
|
+
groqPlugin = null;
|
|
29309
|
+
genkitPlugin = null;
|
|
29310
|
+
gitHubCopilotPlugin = null;
|
|
29311
|
+
fluePlugin = null;
|
|
29312
|
+
langChainPlugin = null;
|
|
29313
|
+
constructor(config3 = {}) {
|
|
29314
|
+
super();
|
|
29315
|
+
this.config = config3;
|
|
29316
|
+
}
|
|
29317
|
+
onEnable() {
|
|
27084
29318
|
const integrations = this.config.integrations || {};
|
|
27085
29319
|
if (integrations.openai !== false) {
|
|
27086
29320
|
this.openaiPlugin = new OpenAIPlugin();
|
|
@@ -27106,6 +29340,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
27106
29340
|
this.cursorSDKPlugin = new CursorSDKPlugin();
|
|
27107
29341
|
this.cursorSDKPlugin.enable();
|
|
27108
29342
|
}
|
|
29343
|
+
if (integrations.openAIAgents !== false) {
|
|
29344
|
+
this.openAIAgentsPlugin = new OpenAIAgentsPlugin();
|
|
29345
|
+
this.openAIAgentsPlugin.enable();
|
|
29346
|
+
}
|
|
27109
29347
|
if (integrations.googleGenAI !== false && integrations.google !== false) {
|
|
27110
29348
|
this.googleGenAIPlugin = new GoogleGenAIPlugin();
|
|
27111
29349
|
this.googleGenAIPlugin.enable();
|
|
@@ -27146,6 +29384,14 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
27146
29384
|
this.gitHubCopilotPlugin = new GitHubCopilotPlugin();
|
|
27147
29385
|
this.gitHubCopilotPlugin.enable();
|
|
27148
29386
|
}
|
|
29387
|
+
if (getIntegrationConfig(integrations, "flue") !== false) {
|
|
29388
|
+
this.fluePlugin = new FluePlugin();
|
|
29389
|
+
this.fluePlugin.enable();
|
|
29390
|
+
}
|
|
29391
|
+
if (integrations.langchain !== false && integrations.langgraph !== false) {
|
|
29392
|
+
this.langChainPlugin = new LangChainPlugin();
|
|
29393
|
+
this.langChainPlugin.enable();
|
|
29394
|
+
}
|
|
27149
29395
|
}
|
|
27150
29396
|
onDisable() {
|
|
27151
29397
|
if (this.openaiPlugin) {
|
|
@@ -27172,6 +29418,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
27172
29418
|
this.cursorSDKPlugin.disable();
|
|
27173
29419
|
this.cursorSDKPlugin = null;
|
|
27174
29420
|
}
|
|
29421
|
+
if (this.openAIAgentsPlugin) {
|
|
29422
|
+
this.openAIAgentsPlugin.disable();
|
|
29423
|
+
this.openAIAgentsPlugin = null;
|
|
29424
|
+
}
|
|
27175
29425
|
if (this.googleGenAIPlugin) {
|
|
27176
29426
|
this.googleGenAIPlugin.disable();
|
|
27177
29427
|
this.googleGenAIPlugin = null;
|
|
@@ -27212,9 +29462,104 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
27212
29462
|
this.gitHubCopilotPlugin.disable();
|
|
27213
29463
|
this.gitHubCopilotPlugin = null;
|
|
27214
29464
|
}
|
|
29465
|
+
if (this.fluePlugin) {
|
|
29466
|
+
this.fluePlugin.disable();
|
|
29467
|
+
this.fluePlugin = null;
|
|
29468
|
+
}
|
|
29469
|
+
if (this.langChainPlugin) {
|
|
29470
|
+
this.langChainPlugin.disable();
|
|
29471
|
+
this.langChainPlugin = null;
|
|
29472
|
+
}
|
|
27215
29473
|
}
|
|
27216
29474
|
};
|
|
27217
29475
|
|
|
29476
|
+
// src/instrumentation/config.ts
|
|
29477
|
+
var envIntegrationAliases = {
|
|
29478
|
+
openai: "openai",
|
|
29479
|
+
"openai-codex": "openaiCodexSDK",
|
|
29480
|
+
"openai-codex-sdk": "openaiCodexSDK",
|
|
29481
|
+
openaicodexsdk: "openaiCodexSDK",
|
|
29482
|
+
codex: "openaiCodexSDK",
|
|
29483
|
+
"codex-sdk": "openaiCodexSDK",
|
|
29484
|
+
anthropic: "anthropic",
|
|
29485
|
+
aisdk: "aisdk",
|
|
29486
|
+
"ai-sdk": "aisdk",
|
|
29487
|
+
"vercel-ai": "aisdk",
|
|
29488
|
+
vercel: "vercel",
|
|
29489
|
+
claudeagentsdk: "claudeAgentSDK",
|
|
29490
|
+
"claude-agent-sdk": "claudeAgentSDK",
|
|
29491
|
+
cursor: "cursor",
|
|
29492
|
+
"cursor-sdk": "cursorSDK",
|
|
29493
|
+
cursorsdk: "cursorSDK",
|
|
29494
|
+
flue: "flue",
|
|
29495
|
+
"flue-runtime": "flue",
|
|
29496
|
+
"openai-agents": "openAIAgents",
|
|
29497
|
+
openaiagents: "openAIAgents",
|
|
29498
|
+
"openai-agents-core": "openAIAgents",
|
|
29499
|
+
openaiagentscore: "openAIAgents",
|
|
29500
|
+
google: "google",
|
|
29501
|
+
"google-genai": "googleGenAI",
|
|
29502
|
+
googlegenai: "googleGenAI",
|
|
29503
|
+
huggingface: "huggingface",
|
|
29504
|
+
openrouter: "openrouter",
|
|
29505
|
+
openrouteragent: "openrouterAgent",
|
|
29506
|
+
"openrouter-agent": "openrouterAgent",
|
|
29507
|
+
mistral: "mistral",
|
|
29508
|
+
googleadk: "googleADK",
|
|
29509
|
+
"google-adk": "googleADK",
|
|
29510
|
+
cohere: "cohere",
|
|
29511
|
+
groq: "groq",
|
|
29512
|
+
"groq-sdk": "groq",
|
|
29513
|
+
genkit: "genkit",
|
|
29514
|
+
"firebase-genkit": "genkit",
|
|
29515
|
+
githubcopilot: "gitHubCopilot",
|
|
29516
|
+
"github-copilot": "gitHubCopilot",
|
|
29517
|
+
"copilot-sdk": "gitHubCopilot",
|
|
29518
|
+
langchain: "langchain",
|
|
29519
|
+
"langchain-js": "langchain",
|
|
29520
|
+
"@langchain": "langchain",
|
|
29521
|
+
langgraph: "langgraph"
|
|
29522
|
+
};
|
|
29523
|
+
function getDefaultInstrumentationIntegrations() {
|
|
29524
|
+
return {
|
|
29525
|
+
openai: true,
|
|
29526
|
+
openaiCodexSDK: true,
|
|
29527
|
+
anthropic: true,
|
|
29528
|
+
vercel: true,
|
|
29529
|
+
aisdk: true,
|
|
29530
|
+
google: true,
|
|
29531
|
+
googleGenAI: true,
|
|
29532
|
+
googleADK: true,
|
|
29533
|
+
huggingface: true,
|
|
29534
|
+
claudeAgentSDK: true,
|
|
29535
|
+
cursor: true,
|
|
29536
|
+
cursorSDK: true,
|
|
29537
|
+
flue: true,
|
|
29538
|
+
openAIAgents: true,
|
|
29539
|
+
openrouter: true,
|
|
29540
|
+
openrouterAgent: true,
|
|
29541
|
+
mistral: true,
|
|
29542
|
+
cohere: true,
|
|
29543
|
+
groq: true,
|
|
29544
|
+
genkit: true,
|
|
29545
|
+
gitHubCopilot: true,
|
|
29546
|
+
langchain: true,
|
|
29547
|
+
langgraph: true
|
|
29548
|
+
};
|
|
29549
|
+
}
|
|
29550
|
+
function readDisabledInstrumentationEnvConfig(disabledList) {
|
|
29551
|
+
const integrations = {};
|
|
29552
|
+
if (disabledList) {
|
|
29553
|
+
for (const value of disabledList.split(",")) {
|
|
29554
|
+
const sdk = value.trim().toLowerCase();
|
|
29555
|
+
if (sdk.length > 0) {
|
|
29556
|
+
integrations[envIntegrationAliases[sdk] ?? sdk] = false;
|
|
29557
|
+
}
|
|
29558
|
+
}
|
|
29559
|
+
}
|
|
29560
|
+
return { integrations };
|
|
29561
|
+
}
|
|
29562
|
+
|
|
27218
29563
|
// src/instrumentation/registry.ts
|
|
27219
29564
|
var REGISTRY_STATE_KEY = /* @__PURE__ */ Symbol.for("braintrust.registry");
|
|
27220
29565
|
function getSharedState() {
|
|
@@ -27293,50 +29638,16 @@ var PluginRegistry = class {
|
|
|
27293
29638
|
* Get default configuration (all integrations enabled).
|
|
27294
29639
|
*/
|
|
27295
29640
|
getDefaultConfig() {
|
|
27296
|
-
return
|
|
27297
|
-
openai: true,
|
|
27298
|
-
openaiCodexSDK: true,
|
|
27299
|
-
anthropic: true,
|
|
27300
|
-
vercel: true,
|
|
27301
|
-
aisdk: true,
|
|
27302
|
-
google: true,
|
|
27303
|
-
googleGenAI: true,
|
|
27304
|
-
googleADK: true,
|
|
27305
|
-
huggingface: true,
|
|
27306
|
-
claudeAgentSDK: true,
|
|
27307
|
-
cursor: true,
|
|
27308
|
-
cursorSDK: true,
|
|
27309
|
-
openrouter: true,
|
|
27310
|
-
openrouterAgent: true,
|
|
27311
|
-
mistral: true,
|
|
27312
|
-
cohere: true,
|
|
27313
|
-
groq: true,
|
|
27314
|
-
genkit: true,
|
|
27315
|
-
gitHubCopilot: true
|
|
27316
|
-
};
|
|
29641
|
+
return getDefaultInstrumentationIntegrations();
|
|
27317
29642
|
}
|
|
27318
29643
|
/**
|
|
27319
29644
|
* Read configuration from environment variables.
|
|
27320
29645
|
* Supports: BRAINTRUST_DISABLE_INSTRUMENTATION=openai,anthropic,...
|
|
27321
29646
|
*/
|
|
27322
29647
|
readEnvConfig() {
|
|
27323
|
-
|
|
27324
|
-
|
|
27325
|
-
|
|
27326
|
-
const disabled = disabledList.split(",").map((s) => s.trim().toLowerCase()).filter((s) => s.length > 0);
|
|
27327
|
-
for (const sdk of disabled) {
|
|
27328
|
-
if (sdk === "cursor-sdk") {
|
|
27329
|
-
integrations.cursorSDK = false;
|
|
27330
|
-
} else if (sdk === "githubcopilot" || sdk === "github-copilot" || sdk === "copilot-sdk") {
|
|
27331
|
-
integrations.gitHubCopilot = false;
|
|
27332
|
-
} else if (sdk === "openai-codex-sdk") {
|
|
27333
|
-
integrations.openaiCodexSDK = false;
|
|
27334
|
-
} else {
|
|
27335
|
-
integrations[sdk] = false;
|
|
27336
|
-
}
|
|
27337
|
-
}
|
|
27338
|
-
}
|
|
27339
|
-
return { integrations };
|
|
29648
|
+
return readDisabledInstrumentationEnvConfig(
|
|
29649
|
+
isomorph_default.getEnv("BRAINTRUST_DISABLE_INSTRUMENTATION")
|
|
29650
|
+
);
|
|
27340
29651
|
}
|
|
27341
29652
|
};
|
|
27342
29653
|
var registry = new PluginRegistry();
|