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/workerd.js
CHANGED
|
@@ -33,8 +33,10 @@ __export(workerd_exports, {
|
|
|
33
33
|
Attachment: () => Attachment,
|
|
34
34
|
AttachmentReference: () => AttachmentReference,
|
|
35
35
|
BRAINTRUST_CURRENT_SPAN_STORE: () => BRAINTRUST_CURRENT_SPAN_STORE,
|
|
36
|
+
BRAINTRUST_LANGCHAIN_CALLBACK_HANDLER_NAME: () => BRAINTRUST_LANGCHAIN_CALLBACK_HANDLER_NAME,
|
|
36
37
|
BaseAttachment: () => BaseAttachment,
|
|
37
38
|
BaseExperiment: () => BaseExperiment,
|
|
39
|
+
BraintrustLangChainCallbackHandler: () => BraintrustLangChainCallbackHandler,
|
|
38
40
|
BraintrustMiddleware: () => BraintrustMiddleware,
|
|
39
41
|
BraintrustState: () => BraintrustState,
|
|
40
42
|
BraintrustStream: () => BraintrustStream,
|
|
@@ -161,6 +163,8 @@ __export(workerd_exports, {
|
|
|
161
163
|
wrapCohere: () => wrapCohere,
|
|
162
164
|
wrapCopilotClient: () => wrapCopilotClient,
|
|
163
165
|
wrapCursorSDK: () => wrapCursorSDK,
|
|
166
|
+
wrapFlueContext: () => wrapFlueContext,
|
|
167
|
+
wrapFlueSession: () => wrapFlueSession,
|
|
164
168
|
wrapGenkit: () => wrapGenkit,
|
|
165
169
|
wrapGoogleADK: () => wrapGoogleADK,
|
|
166
170
|
wrapGoogleGenAI: () => wrapGoogleGenAI,
|
|
@@ -1095,6 +1099,11 @@ function isPromiseLike(value) {
|
|
|
1095
1099
|
|
|
1096
1100
|
// util/object_util.ts
|
|
1097
1101
|
var SET_UNION_FIELDS = /* @__PURE__ */ new Set(["tags"]);
|
|
1102
|
+
var FORBIDDEN_MERGE_KEYS = /* @__PURE__ */ new Set([
|
|
1103
|
+
"__proto__",
|
|
1104
|
+
"constructor",
|
|
1105
|
+
"prototype"
|
|
1106
|
+
]);
|
|
1098
1107
|
function mergeDictsWithPaths({
|
|
1099
1108
|
mergeInto,
|
|
1100
1109
|
mergeFrom,
|
|
@@ -1117,6 +1126,7 @@ function mergeDictsWithPathsHelper({
|
|
|
1117
1126
|
mergePaths
|
|
1118
1127
|
}) {
|
|
1119
1128
|
Object.entries(mergeFrom).forEach(([k, mergeFromV]) => {
|
|
1129
|
+
if (FORBIDDEN_MERGE_KEYS.has(k)) return;
|
|
1120
1130
|
const fullPath = path.concat([k]);
|
|
1121
1131
|
const fullPathSerialized = JSON.stringify(fullPath);
|
|
1122
1132
|
const mergeIntoV = recordFind(mergeInto, k);
|
|
@@ -5188,6 +5198,13 @@ var HTTPConnection = class _HTTPConnection {
|
|
|
5188
5198
|
debugLogger.debug(
|
|
5189
5199
|
`Retrying API request ${object_type} ${JSON.stringify(args)} ${e.status} ${e.text}`
|
|
5190
5200
|
);
|
|
5201
|
+
const sleepTimeS = HTTP_RETRY_BASE_SLEEP_TIME_S * 2 ** i;
|
|
5202
|
+
debugLogger.info(
|
|
5203
|
+
`Sleeping for ${sleepTimeS}s before retrying API request`
|
|
5204
|
+
);
|
|
5205
|
+
await new Promise(
|
|
5206
|
+
(resolve) => setTimeout(resolve, sleepTimeS * 1e3)
|
|
5207
|
+
);
|
|
5191
5208
|
continue;
|
|
5192
5209
|
}
|
|
5193
5210
|
throw e;
|
|
@@ -5837,20 +5854,7 @@ function startSpanParentArgs(args) {
|
|
|
5837
5854
|
`Mismatch between expected span parent object type ${args.parentObjectType} and provided type ${parentComponents.data.object_type}`
|
|
5838
5855
|
);
|
|
5839
5856
|
}
|
|
5840
|
-
|
|
5841
|
-
args.state,
|
|
5842
|
-
parentComponents
|
|
5843
|
-
);
|
|
5844
|
-
const computeParentObjectId = async () => {
|
|
5845
|
-
const parentComponentsObjectId = await parentComponentsObjectIdLambda();
|
|
5846
|
-
if (await args.parentObjectId.get() !== parentComponentsObjectId) {
|
|
5847
|
-
throw new Error(
|
|
5848
|
-
`Mismatch between expected span parent object id ${await args.parentObjectId.get()} and provided id ${parentComponentsObjectId}`
|
|
5849
|
-
);
|
|
5850
|
-
}
|
|
5851
|
-
return await args.parentObjectId.get();
|
|
5852
|
-
};
|
|
5853
|
-
argParentObjectId = new LazyValue(computeParentObjectId);
|
|
5857
|
+
argParentObjectId = args.parentObjectId;
|
|
5854
5858
|
if (parentComponents.data.row_id) {
|
|
5855
5859
|
argParentSpanIds = {
|
|
5856
5860
|
spanId: parentComponents.data.span_id,
|
|
@@ -6236,6 +6240,7 @@ var TestBackgroundLogger = class {
|
|
|
6236
6240
|
}
|
|
6237
6241
|
};
|
|
6238
6242
|
var BACKGROUND_LOGGER_BASE_SLEEP_TIME_S = 1;
|
|
6243
|
+
var HTTP_RETRY_BASE_SLEEP_TIME_S = 1;
|
|
6239
6244
|
var HTTPBackgroundLogger = class _HTTPBackgroundLogger {
|
|
6240
6245
|
apiConn;
|
|
6241
6246
|
queue;
|
|
@@ -6866,17 +6871,10 @@ function init(projectOrOptions, optionalOptions) {
|
|
|
6866
6871
|
if (repoInfo) {
|
|
6867
6872
|
return repoInfo;
|
|
6868
6873
|
}
|
|
6869
|
-
|
|
6870
|
-
|
|
6871
|
-
|
|
6872
|
-
|
|
6873
|
-
};
|
|
6874
|
-
if (gitMetadataSettings) {
|
|
6875
|
-
mergedGitMetadataSettings = mergeGitMetadataSettings(
|
|
6876
|
-
mergedGitMetadataSettings,
|
|
6877
|
-
gitMetadataSettings
|
|
6878
|
-
);
|
|
6879
|
-
}
|
|
6874
|
+
const mergedGitMetadataSettings = state.gitMetadataSettings == null ? gitMetadataSettings ?? { collect: "none" } : mergeGitMetadataSettings(
|
|
6875
|
+
state.gitMetadataSettings,
|
|
6876
|
+
gitMetadataSettings ?? { collect: "all" }
|
|
6877
|
+
);
|
|
6880
6878
|
return await isomorph_default.getRepoInfo(mergedGitMetadataSettings);
|
|
6881
6879
|
})();
|
|
6882
6880
|
if (repoInfoArg) {
|
|
@@ -13695,11 +13693,11 @@ function resolveDenyOutputPaths(event, defaultDenyOutputPaths) {
|
|
|
13695
13693
|
if (Array.isArray(event?.denyOutputPaths)) {
|
|
13696
13694
|
return event.denyOutputPaths;
|
|
13697
13695
|
}
|
|
13698
|
-
const
|
|
13699
|
-
if (!
|
|
13696
|
+
const firstArgument2 = event?.arguments && event.arguments.length > 0 ? event.arguments[0] : void 0;
|
|
13697
|
+
if (!firstArgument2 || typeof firstArgument2 !== "object") {
|
|
13700
13698
|
return defaultDenyOutputPaths;
|
|
13701
13699
|
}
|
|
13702
|
-
const runtimeDenyOutputPaths =
|
|
13700
|
+
const runtimeDenyOutputPaths = firstArgument2[RUNTIME_DENY_OUTPUT_PATHS];
|
|
13703
13701
|
if (Array.isArray(runtimeDenyOutputPaths) && runtimeDenyOutputPaths.every((path) => typeof path === "string")) {
|
|
13704
13702
|
return runtimeDenyOutputPaths;
|
|
13705
13703
|
}
|
|
@@ -17358,6 +17356,467 @@ function cleanMetrics2(metrics) {
|
|
|
17358
17356
|
return cleaned;
|
|
17359
17357
|
}
|
|
17360
17358
|
|
|
17359
|
+
// src/instrumentation/plugins/openai-agents-channels.ts
|
|
17360
|
+
var openAIAgentsCoreChannels = defineChannels("@openai/agents-core", {
|
|
17361
|
+
onTraceStart: channel({
|
|
17362
|
+
channelName: "tracing.processor.onTraceStart",
|
|
17363
|
+
kind: "async"
|
|
17364
|
+
}),
|
|
17365
|
+
onTraceEnd: channel({
|
|
17366
|
+
channelName: "tracing.processor.onTraceEnd",
|
|
17367
|
+
kind: "async"
|
|
17368
|
+
}),
|
|
17369
|
+
onSpanStart: channel({
|
|
17370
|
+
channelName: "tracing.processor.onSpanStart",
|
|
17371
|
+
kind: "async"
|
|
17372
|
+
}),
|
|
17373
|
+
onSpanEnd: channel({
|
|
17374
|
+
channelName: "tracing.processor.onSpanEnd",
|
|
17375
|
+
kind: "async"
|
|
17376
|
+
})
|
|
17377
|
+
});
|
|
17378
|
+
|
|
17379
|
+
// src/instrumentation/plugins/openai-agents-trace-processor.ts
|
|
17380
|
+
function isSpanData(spanData, type) {
|
|
17381
|
+
return spanData.type === type;
|
|
17382
|
+
}
|
|
17383
|
+
function spanTypeFromAgents(span) {
|
|
17384
|
+
const spanType = span.spanData.type;
|
|
17385
|
+
if (spanType === "function" || spanType === "guardrail" || spanType === "mcp_tools") {
|
|
17386
|
+
return "tool" /* TOOL */;
|
|
17387
|
+
}
|
|
17388
|
+
if (spanType === "generation" || spanType === "response" || spanType === "transcription" || spanType === "speech") {
|
|
17389
|
+
return "llm" /* LLM */;
|
|
17390
|
+
}
|
|
17391
|
+
return "task" /* TASK */;
|
|
17392
|
+
}
|
|
17393
|
+
function spanNameFromAgents(span) {
|
|
17394
|
+
const spanData = span.spanData;
|
|
17395
|
+
if ("name" in spanData && spanData.name) {
|
|
17396
|
+
return spanData.name;
|
|
17397
|
+
}
|
|
17398
|
+
switch (spanData.type) {
|
|
17399
|
+
case "generation":
|
|
17400
|
+
return "Generation";
|
|
17401
|
+
case "response":
|
|
17402
|
+
return "Response";
|
|
17403
|
+
case "handoff":
|
|
17404
|
+
return "Handoff";
|
|
17405
|
+
case "mcp_tools":
|
|
17406
|
+
return isSpanData(spanData, "mcp_tools") && spanData.server ? `List Tools (${spanData.server})` : "MCP List Tools";
|
|
17407
|
+
case "transcription":
|
|
17408
|
+
return "Transcription";
|
|
17409
|
+
case "speech":
|
|
17410
|
+
return "Speech";
|
|
17411
|
+
case "speech_group":
|
|
17412
|
+
return "Speech Group";
|
|
17413
|
+
default:
|
|
17414
|
+
return "Unknown";
|
|
17415
|
+
}
|
|
17416
|
+
}
|
|
17417
|
+
function getTimeElapsed(end, start) {
|
|
17418
|
+
if (!start || !end) {
|
|
17419
|
+
return void 0;
|
|
17420
|
+
}
|
|
17421
|
+
const startTime = new Date(start).getTime();
|
|
17422
|
+
const endTime = new Date(end).getTime();
|
|
17423
|
+
if (Number.isNaN(startTime) || Number.isNaN(endTime)) {
|
|
17424
|
+
return void 0;
|
|
17425
|
+
}
|
|
17426
|
+
return (endTime - startTime) / 1e3;
|
|
17427
|
+
}
|
|
17428
|
+
function getNumberProperty2(obj, key) {
|
|
17429
|
+
if (!isObject(obj) || !(key in obj)) {
|
|
17430
|
+
return void 0;
|
|
17431
|
+
}
|
|
17432
|
+
const value = obj[key];
|
|
17433
|
+
return typeof value === "number" ? value : void 0;
|
|
17434
|
+
}
|
|
17435
|
+
function parseUsageMetrics(usage) {
|
|
17436
|
+
const metrics = {};
|
|
17437
|
+
if (!isObject(usage)) {
|
|
17438
|
+
return metrics;
|
|
17439
|
+
}
|
|
17440
|
+
const promptTokens = getNumberProperty2(usage, "prompt_tokens") ?? getNumberProperty2(usage, "input_tokens") ?? getNumberProperty2(usage, "promptTokens") ?? getNumberProperty2(usage, "inputTokens");
|
|
17441
|
+
const completionTokens = getNumberProperty2(usage, "completion_tokens") ?? getNumberProperty2(usage, "output_tokens") ?? getNumberProperty2(usage, "completionTokens") ?? getNumberProperty2(usage, "outputTokens");
|
|
17442
|
+
const totalTokens = getNumberProperty2(usage, "total_tokens") ?? getNumberProperty2(usage, "totalTokens");
|
|
17443
|
+
if (promptTokens !== void 0) {
|
|
17444
|
+
metrics.prompt_tokens = promptTokens;
|
|
17445
|
+
}
|
|
17446
|
+
if (completionTokens !== void 0) {
|
|
17447
|
+
metrics.completion_tokens = completionTokens;
|
|
17448
|
+
}
|
|
17449
|
+
if (totalTokens !== void 0) {
|
|
17450
|
+
metrics.tokens = totalTokens;
|
|
17451
|
+
} else if (promptTokens !== void 0 && completionTokens !== void 0) {
|
|
17452
|
+
metrics.tokens = promptTokens + completionTokens;
|
|
17453
|
+
}
|
|
17454
|
+
const inputDetails = usage.input_tokens_details;
|
|
17455
|
+
const cachedTokens = getNumberProperty2(inputDetails, "cached_tokens");
|
|
17456
|
+
const cacheWriteTokens = getNumberProperty2(
|
|
17457
|
+
inputDetails,
|
|
17458
|
+
"cache_write_tokens"
|
|
17459
|
+
);
|
|
17460
|
+
if (cachedTokens !== void 0) {
|
|
17461
|
+
metrics.prompt_cached_tokens = cachedTokens;
|
|
17462
|
+
}
|
|
17463
|
+
if (cacheWriteTokens !== void 0) {
|
|
17464
|
+
metrics.prompt_cache_creation_tokens = cacheWriteTokens;
|
|
17465
|
+
}
|
|
17466
|
+
return metrics;
|
|
17467
|
+
}
|
|
17468
|
+
var OpenAIAgentsTraceProcessor = class _OpenAIAgentsTraceProcessor {
|
|
17469
|
+
static DEFAULT_MAX_TRACES = 1e4;
|
|
17470
|
+
logger;
|
|
17471
|
+
maxTraces;
|
|
17472
|
+
traceSpans = /* @__PURE__ */ new Map();
|
|
17473
|
+
traceOrder = [];
|
|
17474
|
+
_traceSpans = this.traceSpans;
|
|
17475
|
+
constructor(options = {}) {
|
|
17476
|
+
this.logger = options.logger;
|
|
17477
|
+
this.maxTraces = options.maxTraces ?? _OpenAIAgentsTraceProcessor.DEFAULT_MAX_TRACES;
|
|
17478
|
+
}
|
|
17479
|
+
evictOldestTrace() {
|
|
17480
|
+
const oldestTraceId = this.traceOrder.shift();
|
|
17481
|
+
if (oldestTraceId) {
|
|
17482
|
+
this.traceSpans.delete(oldestTraceId);
|
|
17483
|
+
}
|
|
17484
|
+
}
|
|
17485
|
+
onTraceStart(trace) {
|
|
17486
|
+
if (!trace?.traceId) {
|
|
17487
|
+
return Promise.resolve();
|
|
17488
|
+
}
|
|
17489
|
+
if (this.traceOrder.length >= this.maxTraces) {
|
|
17490
|
+
this.evictOldestTrace();
|
|
17491
|
+
}
|
|
17492
|
+
const current = currentSpan();
|
|
17493
|
+
const span = current && current !== NOOP_SPAN ? current.startSpan({
|
|
17494
|
+
name: trace.name,
|
|
17495
|
+
type: "task" /* TASK */
|
|
17496
|
+
}) : this.logger ? this.logger.startSpan({
|
|
17497
|
+
name: trace.name,
|
|
17498
|
+
type: "task" /* TASK */
|
|
17499
|
+
}) : startSpan({
|
|
17500
|
+
name: trace.name,
|
|
17501
|
+
type: "task" /* TASK */
|
|
17502
|
+
});
|
|
17503
|
+
span.log({
|
|
17504
|
+
input: "Agent workflow started",
|
|
17505
|
+
metadata: {
|
|
17506
|
+
group_id: trace.groupId,
|
|
17507
|
+
...trace.metadata || {}
|
|
17508
|
+
}
|
|
17509
|
+
});
|
|
17510
|
+
this.traceSpans.set(trace.traceId, {
|
|
17511
|
+
rootSpan: span,
|
|
17512
|
+
childSpans: /* @__PURE__ */ new Map(),
|
|
17513
|
+
metadata: {
|
|
17514
|
+
firstInput: null,
|
|
17515
|
+
lastOutput: null
|
|
17516
|
+
}
|
|
17517
|
+
});
|
|
17518
|
+
this.traceOrder.push(trace.traceId);
|
|
17519
|
+
return Promise.resolve();
|
|
17520
|
+
}
|
|
17521
|
+
async onTraceEnd(trace) {
|
|
17522
|
+
const traceData = this.traceSpans.get(trace?.traceId);
|
|
17523
|
+
if (!traceData) {
|
|
17524
|
+
return;
|
|
17525
|
+
}
|
|
17526
|
+
try {
|
|
17527
|
+
traceData.rootSpan.log({
|
|
17528
|
+
input: traceData.metadata.firstInput,
|
|
17529
|
+
output: traceData.metadata.lastOutput
|
|
17530
|
+
});
|
|
17531
|
+
traceData.rootSpan.end();
|
|
17532
|
+
await traceData.rootSpan.flush();
|
|
17533
|
+
} finally {
|
|
17534
|
+
this.traceSpans.delete(trace.traceId);
|
|
17535
|
+
const orderIndex = this.traceOrder.indexOf(trace.traceId);
|
|
17536
|
+
if (orderIndex > -1) {
|
|
17537
|
+
this.traceOrder.splice(orderIndex, 1);
|
|
17538
|
+
}
|
|
17539
|
+
}
|
|
17540
|
+
}
|
|
17541
|
+
onSpanStart(span) {
|
|
17542
|
+
if (!span?.spanId || !span.traceId) {
|
|
17543
|
+
return Promise.resolve();
|
|
17544
|
+
}
|
|
17545
|
+
const traceData = this.traceSpans.get(span.traceId);
|
|
17546
|
+
if (!traceData) {
|
|
17547
|
+
return Promise.resolve();
|
|
17548
|
+
}
|
|
17549
|
+
const parentSpan = span.parentId ? traceData.childSpans.get(span.parentId) : traceData.rootSpan;
|
|
17550
|
+
if (!parentSpan) {
|
|
17551
|
+
return Promise.resolve();
|
|
17552
|
+
}
|
|
17553
|
+
const childSpan = parentSpan.startSpan({
|
|
17554
|
+
name: spanNameFromAgents(span),
|
|
17555
|
+
type: spanTypeFromAgents(span)
|
|
17556
|
+
});
|
|
17557
|
+
traceData.childSpans.set(span.spanId, childSpan);
|
|
17558
|
+
return Promise.resolve();
|
|
17559
|
+
}
|
|
17560
|
+
onSpanEnd(span) {
|
|
17561
|
+
if (!span?.spanId || !span.traceId) {
|
|
17562
|
+
return Promise.resolve();
|
|
17563
|
+
}
|
|
17564
|
+
const traceData = this.traceSpans.get(span.traceId);
|
|
17565
|
+
if (!traceData) {
|
|
17566
|
+
return Promise.resolve();
|
|
17567
|
+
}
|
|
17568
|
+
const braintrustSpan = traceData.childSpans.get(span.spanId);
|
|
17569
|
+
if (!braintrustSpan) {
|
|
17570
|
+
return Promise.resolve();
|
|
17571
|
+
}
|
|
17572
|
+
const logData = this.extractLogData(span);
|
|
17573
|
+
braintrustSpan.log({
|
|
17574
|
+
error: span.error,
|
|
17575
|
+
...logData
|
|
17576
|
+
});
|
|
17577
|
+
braintrustSpan.end();
|
|
17578
|
+
traceData.childSpans.delete(span.spanId);
|
|
17579
|
+
const input = logData.input;
|
|
17580
|
+
const output = logData.output;
|
|
17581
|
+
if (traceData.metadata.firstInput === null && input != null) {
|
|
17582
|
+
traceData.metadata.firstInput = input;
|
|
17583
|
+
}
|
|
17584
|
+
if (output != null) {
|
|
17585
|
+
traceData.metadata.lastOutput = output;
|
|
17586
|
+
}
|
|
17587
|
+
return Promise.resolve();
|
|
17588
|
+
}
|
|
17589
|
+
async shutdown() {
|
|
17590
|
+
if (this.logger && typeof this.logger.flush === "function") {
|
|
17591
|
+
await this.logger.flush();
|
|
17592
|
+
}
|
|
17593
|
+
}
|
|
17594
|
+
async forceFlush() {
|
|
17595
|
+
if (this.logger && typeof this.logger.flush === "function") {
|
|
17596
|
+
await this.logger.flush();
|
|
17597
|
+
}
|
|
17598
|
+
}
|
|
17599
|
+
extractLogData(span) {
|
|
17600
|
+
const spanData = span.spanData;
|
|
17601
|
+
switch (spanData.type) {
|
|
17602
|
+
case "agent":
|
|
17603
|
+
return this.extractAgentLogData(spanData);
|
|
17604
|
+
case "response":
|
|
17605
|
+
return this.extractResponseLogData(spanData, span);
|
|
17606
|
+
case "function":
|
|
17607
|
+
return this.extractFunctionLogData(spanData);
|
|
17608
|
+
case "handoff":
|
|
17609
|
+
return this.extractHandoffLogData(spanData);
|
|
17610
|
+
case "guardrail":
|
|
17611
|
+
return this.extractGuardrailLogData(spanData);
|
|
17612
|
+
case "generation":
|
|
17613
|
+
return this.extractGenerationLogData(spanData, span);
|
|
17614
|
+
case "custom":
|
|
17615
|
+
return this.extractCustomLogData(spanData);
|
|
17616
|
+
case "mcp_tools":
|
|
17617
|
+
return this.extractMCPListToolsLogData(spanData);
|
|
17618
|
+
case "transcription":
|
|
17619
|
+
return this.extractTranscriptionLogData(spanData);
|
|
17620
|
+
case "speech":
|
|
17621
|
+
return this.extractSpeechLogData(spanData);
|
|
17622
|
+
case "speech_group":
|
|
17623
|
+
return this.extractSpeechGroupLogData(spanData);
|
|
17624
|
+
default:
|
|
17625
|
+
return {};
|
|
17626
|
+
}
|
|
17627
|
+
}
|
|
17628
|
+
extractAgentLogData(spanData) {
|
|
17629
|
+
return {
|
|
17630
|
+
metadata: {
|
|
17631
|
+
tools: spanData.tools,
|
|
17632
|
+
handoffs: spanData.handoffs,
|
|
17633
|
+
output_type: spanData.output_type
|
|
17634
|
+
}
|
|
17635
|
+
};
|
|
17636
|
+
}
|
|
17637
|
+
extractResponseLogData(spanData, span) {
|
|
17638
|
+
const response = spanData._response;
|
|
17639
|
+
const output = isObject(response) ? response.output : void 0;
|
|
17640
|
+
const usage = isObject(response) ? response.usage : void 0;
|
|
17641
|
+
const metrics = {
|
|
17642
|
+
...this.extractTimingMetrics(span),
|
|
17643
|
+
...parseUsageMetrics(usage)
|
|
17644
|
+
};
|
|
17645
|
+
return {
|
|
17646
|
+
input: spanData._input,
|
|
17647
|
+
output,
|
|
17648
|
+
metadata: isObject(response) ? this.omitKeys(response, ["output", "usage"]) : {},
|
|
17649
|
+
metrics
|
|
17650
|
+
};
|
|
17651
|
+
}
|
|
17652
|
+
extractFunctionLogData(spanData) {
|
|
17653
|
+
return {
|
|
17654
|
+
input: spanData.input,
|
|
17655
|
+
output: spanData.output
|
|
17656
|
+
};
|
|
17657
|
+
}
|
|
17658
|
+
extractHandoffLogData(spanData) {
|
|
17659
|
+
return {
|
|
17660
|
+
metadata: {
|
|
17661
|
+
from_agent: spanData.from_agent,
|
|
17662
|
+
to_agent: spanData.to_agent
|
|
17663
|
+
}
|
|
17664
|
+
};
|
|
17665
|
+
}
|
|
17666
|
+
extractGuardrailLogData(spanData) {
|
|
17667
|
+
return {
|
|
17668
|
+
metadata: {
|
|
17669
|
+
triggered: spanData.triggered
|
|
17670
|
+
}
|
|
17671
|
+
};
|
|
17672
|
+
}
|
|
17673
|
+
extractGenerationLogData(spanData, span) {
|
|
17674
|
+
return {
|
|
17675
|
+
input: spanData.input,
|
|
17676
|
+
output: spanData.output,
|
|
17677
|
+
metadata: {
|
|
17678
|
+
model: spanData.model,
|
|
17679
|
+
model_config: spanData.model_config
|
|
17680
|
+
},
|
|
17681
|
+
metrics: {
|
|
17682
|
+
...this.extractTimingMetrics(span),
|
|
17683
|
+
...parseUsageMetrics(spanData.usage)
|
|
17684
|
+
}
|
|
17685
|
+
};
|
|
17686
|
+
}
|
|
17687
|
+
extractCustomLogData(spanData) {
|
|
17688
|
+
return spanData.data || {};
|
|
17689
|
+
}
|
|
17690
|
+
extractMCPListToolsLogData(spanData) {
|
|
17691
|
+
return {
|
|
17692
|
+
output: spanData.result,
|
|
17693
|
+
metadata: {
|
|
17694
|
+
server: spanData.server
|
|
17695
|
+
}
|
|
17696
|
+
};
|
|
17697
|
+
}
|
|
17698
|
+
extractTranscriptionLogData(spanData) {
|
|
17699
|
+
return {
|
|
17700
|
+
input: spanData.input,
|
|
17701
|
+
output: spanData.output,
|
|
17702
|
+
metadata: {
|
|
17703
|
+
model: spanData.model,
|
|
17704
|
+
model_config: spanData.model_config
|
|
17705
|
+
}
|
|
17706
|
+
};
|
|
17707
|
+
}
|
|
17708
|
+
extractSpeechLogData(spanData) {
|
|
17709
|
+
return {
|
|
17710
|
+
input: spanData.input,
|
|
17711
|
+
output: spanData.output,
|
|
17712
|
+
metadata: {
|
|
17713
|
+
model: spanData.model,
|
|
17714
|
+
model_config: spanData.model_config
|
|
17715
|
+
}
|
|
17716
|
+
};
|
|
17717
|
+
}
|
|
17718
|
+
extractSpeechGroupLogData(spanData) {
|
|
17719
|
+
return {
|
|
17720
|
+
input: spanData.input
|
|
17721
|
+
};
|
|
17722
|
+
}
|
|
17723
|
+
extractTimingMetrics(span) {
|
|
17724
|
+
const timeToFirstToken = getTimeElapsed(
|
|
17725
|
+
span.endedAt ?? void 0,
|
|
17726
|
+
span.startedAt ?? void 0
|
|
17727
|
+
);
|
|
17728
|
+
return timeToFirstToken === void 0 ? {} : { time_to_first_token: timeToFirstToken };
|
|
17729
|
+
}
|
|
17730
|
+
omitKeys(value, keys) {
|
|
17731
|
+
const result = {};
|
|
17732
|
+
for (const [key, fieldValue] of Object.entries(value)) {
|
|
17733
|
+
if (!keys.includes(key)) {
|
|
17734
|
+
result[key] = fieldValue;
|
|
17735
|
+
}
|
|
17736
|
+
}
|
|
17737
|
+
return result;
|
|
17738
|
+
}
|
|
17739
|
+
};
|
|
17740
|
+
|
|
17741
|
+
// src/instrumentation/plugins/openai-agents-plugin.ts
|
|
17742
|
+
function firstArgument(args) {
|
|
17743
|
+
if (Array.isArray(args)) {
|
|
17744
|
+
return args[0];
|
|
17745
|
+
}
|
|
17746
|
+
if (isObject(args) && "length" in args && typeof args.length === "number" && Number.isInteger(args.length) && args.length >= 0) {
|
|
17747
|
+
return Array.from(args)[0];
|
|
17748
|
+
}
|
|
17749
|
+
return void 0;
|
|
17750
|
+
}
|
|
17751
|
+
function isOpenAIAgentsTrace(value) {
|
|
17752
|
+
return isObject(value) && value.type === "trace" && typeof value.traceId === "string";
|
|
17753
|
+
}
|
|
17754
|
+
function isOpenAIAgentsSpan(value) {
|
|
17755
|
+
return isObject(value) && value.type === "trace.span" && typeof value.traceId === "string" && typeof value.spanId === "string";
|
|
17756
|
+
}
|
|
17757
|
+
var OpenAIAgentsPlugin = class extends BasePlugin {
|
|
17758
|
+
processor = new OpenAIAgentsTraceProcessor();
|
|
17759
|
+
onEnable() {
|
|
17760
|
+
this.subscribeToTraceLifecycle();
|
|
17761
|
+
}
|
|
17762
|
+
onDisable() {
|
|
17763
|
+
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
17764
|
+
void this.processor.shutdown();
|
|
17765
|
+
}
|
|
17766
|
+
subscribeToTraceLifecycle() {
|
|
17767
|
+
const traceStartChannel = openAIAgentsCoreChannels.onTraceStart.tracingChannel();
|
|
17768
|
+
const traceStartHandlers = {
|
|
17769
|
+
start: (event) => {
|
|
17770
|
+
const trace = firstArgument(event.arguments);
|
|
17771
|
+
if (isOpenAIAgentsTrace(trace)) {
|
|
17772
|
+
void this.processor.onTraceStart(trace);
|
|
17773
|
+
}
|
|
17774
|
+
}
|
|
17775
|
+
};
|
|
17776
|
+
traceStartChannel.subscribe(traceStartHandlers);
|
|
17777
|
+
this.unsubscribers.push(
|
|
17778
|
+
() => traceStartChannel.unsubscribe(traceStartHandlers)
|
|
17779
|
+
);
|
|
17780
|
+
const traceEndChannel = openAIAgentsCoreChannels.onTraceEnd.tracingChannel();
|
|
17781
|
+
const traceEndHandlers = {
|
|
17782
|
+
start: (event) => {
|
|
17783
|
+
const trace = firstArgument(event.arguments);
|
|
17784
|
+
if (isOpenAIAgentsTrace(trace)) {
|
|
17785
|
+
void this.processor.onTraceEnd(trace);
|
|
17786
|
+
}
|
|
17787
|
+
}
|
|
17788
|
+
};
|
|
17789
|
+
traceEndChannel.subscribe(traceEndHandlers);
|
|
17790
|
+
this.unsubscribers.push(
|
|
17791
|
+
() => traceEndChannel.unsubscribe(traceEndHandlers)
|
|
17792
|
+
);
|
|
17793
|
+
const spanStartChannel = openAIAgentsCoreChannels.onSpanStart.tracingChannel();
|
|
17794
|
+
const spanStartHandlers = {
|
|
17795
|
+
start: (event) => {
|
|
17796
|
+
const span = firstArgument(event.arguments);
|
|
17797
|
+
if (isOpenAIAgentsSpan(span)) {
|
|
17798
|
+
void this.processor.onSpanStart(span);
|
|
17799
|
+
}
|
|
17800
|
+
}
|
|
17801
|
+
};
|
|
17802
|
+
spanStartChannel.subscribe(spanStartHandlers);
|
|
17803
|
+
this.unsubscribers.push(
|
|
17804
|
+
() => spanStartChannel.unsubscribe(spanStartHandlers)
|
|
17805
|
+
);
|
|
17806
|
+
const spanEndChannel = openAIAgentsCoreChannels.onSpanEnd.tracingChannel();
|
|
17807
|
+
const spanEndHandlers = {
|
|
17808
|
+
start: (event) => {
|
|
17809
|
+
const span = firstArgument(event.arguments);
|
|
17810
|
+
if (isOpenAIAgentsSpan(span)) {
|
|
17811
|
+
void this.processor.onSpanEnd(span);
|
|
17812
|
+
}
|
|
17813
|
+
}
|
|
17814
|
+
};
|
|
17815
|
+
spanEndChannel.subscribe(spanEndHandlers);
|
|
17816
|
+
this.unsubscribers.push(() => spanEndChannel.unsubscribe(spanEndHandlers));
|
|
17817
|
+
}
|
|
17818
|
+
};
|
|
17819
|
+
|
|
17361
17820
|
// src/instrumentation/plugins/google-genai-channels.ts
|
|
17362
17821
|
var googleGenAIChannels = defineChannels("@google/genai", {
|
|
17363
17822
|
generateContent: channel({
|
|
@@ -23650,41 +24109,1773 @@ var GitHubCopilotPlugin = class extends BasePlugin {
|
|
|
23650
24109
|
}
|
|
23651
24110
|
};
|
|
23652
24111
|
|
|
23653
|
-
// src/instrumentation/
|
|
23654
|
-
|
|
23655
|
-
|
|
24112
|
+
// src/instrumentation/plugins/flue-channels.ts
|
|
24113
|
+
var flueChannels = defineChannels("@flue/runtime", {
|
|
24114
|
+
createContext: channel({
|
|
24115
|
+
channelName: "createFlueContext",
|
|
24116
|
+
kind: "sync-stream"
|
|
24117
|
+
}),
|
|
24118
|
+
openSession: channel({
|
|
24119
|
+
channelName: "Harness.openSession",
|
|
24120
|
+
kind: "async"
|
|
24121
|
+
}),
|
|
24122
|
+
contextEvent: channel({
|
|
24123
|
+
channelName: "context.event",
|
|
24124
|
+
kind: "sync-stream"
|
|
24125
|
+
}),
|
|
24126
|
+
prompt: channel({
|
|
24127
|
+
channelName: "session.prompt",
|
|
24128
|
+
kind: "async"
|
|
24129
|
+
}),
|
|
24130
|
+
skill: channel({
|
|
24131
|
+
channelName: "session.skill",
|
|
24132
|
+
kind: "async"
|
|
24133
|
+
}),
|
|
24134
|
+
task: channel({
|
|
24135
|
+
channelName: "session.task",
|
|
24136
|
+
kind: "async"
|
|
24137
|
+
}),
|
|
24138
|
+
compact: channel({
|
|
24139
|
+
channelName: "session.compact",
|
|
24140
|
+
kind: "async"
|
|
24141
|
+
})
|
|
24142
|
+
});
|
|
24143
|
+
|
|
24144
|
+
// src/wrappers/flue.ts
|
|
24145
|
+
var WRAPPED_FLUE_CONTEXT = /* @__PURE__ */ Symbol.for("braintrust.flue.wrapped-context");
|
|
24146
|
+
var WRAPPED_FLUE_HARNESS = /* @__PURE__ */ Symbol.for("braintrust.flue.wrapped-harness");
|
|
24147
|
+
var WRAPPED_FLUE_SESSION = /* @__PURE__ */ Symbol.for("braintrust.flue.wrapped-session");
|
|
24148
|
+
var SUBSCRIBED_FLUE_CONTEXT_EVENTS = /* @__PURE__ */ Symbol.for(
|
|
24149
|
+
"braintrust.flue.subscribed-context-events"
|
|
24150
|
+
);
|
|
24151
|
+
function wrapFlueContext(ctx) {
|
|
24152
|
+
if (!isPlausibleFlueContext(ctx)) {
|
|
24153
|
+
console.warn("Unsupported Flue context. Not wrapping.");
|
|
24154
|
+
return ctx;
|
|
24155
|
+
}
|
|
24156
|
+
const context = ctx;
|
|
24157
|
+
subscribeFlueContextEvents(context, { captureTurnSpans: true });
|
|
24158
|
+
return patchFlueContextInPlace(context);
|
|
23656
24159
|
}
|
|
23657
|
-
|
|
23658
|
-
|
|
23659
|
-
|
|
23660
|
-
|
|
23661
|
-
anthropicPlugin = null;
|
|
23662
|
-
aiSDKPlugin = null;
|
|
23663
|
-
claudeAgentSDKPlugin = null;
|
|
23664
|
-
cursorSDKPlugin = null;
|
|
23665
|
-
googleGenAIPlugin = null;
|
|
23666
|
-
huggingFacePlugin = null;
|
|
23667
|
-
openRouterPlugin = null;
|
|
23668
|
-
openRouterAgentPlugin = null;
|
|
23669
|
-
mistralPlugin = null;
|
|
23670
|
-
googleADKPlugin = null;
|
|
23671
|
-
coherePlugin = null;
|
|
23672
|
-
groqPlugin = null;
|
|
23673
|
-
genkitPlugin = null;
|
|
23674
|
-
gitHubCopilotPlugin = null;
|
|
23675
|
-
constructor(config = {}) {
|
|
23676
|
-
super();
|
|
23677
|
-
this.config = config;
|
|
24160
|
+
function patchFlueContextInPlace(ctx) {
|
|
24161
|
+
const context = ctx;
|
|
24162
|
+
if (context[WRAPPED_FLUE_CONTEXT]) {
|
|
24163
|
+
return ctx;
|
|
23678
24164
|
}
|
|
23679
|
-
|
|
23680
|
-
|
|
23681
|
-
|
|
23682
|
-
|
|
23683
|
-
|
|
24165
|
+
const originalInit = context.init.bind(context);
|
|
24166
|
+
try {
|
|
24167
|
+
Object.defineProperty(context, WRAPPED_FLUE_CONTEXT, {
|
|
24168
|
+
configurable: false,
|
|
24169
|
+
enumerable: false,
|
|
24170
|
+
value: true
|
|
24171
|
+
});
|
|
24172
|
+
Object.defineProperty(context, "init", {
|
|
24173
|
+
configurable: true,
|
|
24174
|
+
value: async function wrappedFlueInit(options) {
|
|
24175
|
+
const harness = await originalInit(options);
|
|
24176
|
+
return wrapFlueHarness(harness);
|
|
24177
|
+
},
|
|
24178
|
+
writable: true
|
|
24179
|
+
});
|
|
24180
|
+
} catch {
|
|
24181
|
+
}
|
|
24182
|
+
return ctx;
|
|
24183
|
+
}
|
|
24184
|
+
function wrapFlueSession(session) {
|
|
24185
|
+
if (!isPlausibleFlueSession(session)) {
|
|
24186
|
+
console.warn("Unsupported Flue session. Not wrapping.");
|
|
24187
|
+
return session;
|
|
24188
|
+
}
|
|
24189
|
+
return patchFlueSessionInPlace(session);
|
|
24190
|
+
}
|
|
24191
|
+
function subscribeFlueContextEvents(ctx, options = {}) {
|
|
24192
|
+
if (!ctx || typeof ctx !== "object" || typeof ctx.subscribeEvent !== "function") {
|
|
24193
|
+
return void 0;
|
|
24194
|
+
}
|
|
24195
|
+
const context = ctx;
|
|
24196
|
+
const captureTurnSpans = options.captureTurnSpans ?? true;
|
|
24197
|
+
const existingSubscription = context[SUBSCRIBED_FLUE_CONTEXT_EVENTS];
|
|
24198
|
+
if (existingSubscription) {
|
|
24199
|
+
if (existingSubscription.captureTurnSpans || !captureTurnSpans) {
|
|
24200
|
+
return void 0;
|
|
23684
24201
|
}
|
|
23685
|
-
|
|
23686
|
-
|
|
23687
|
-
|
|
24202
|
+
try {
|
|
24203
|
+
existingSubscription.unsubscribe();
|
|
24204
|
+
} catch {
|
|
24205
|
+
}
|
|
24206
|
+
}
|
|
24207
|
+
try {
|
|
24208
|
+
const unsubscribe = ctx.subscribeEvent((event) => {
|
|
24209
|
+
flueChannels.contextEvent.traceSync(() => void 0, {
|
|
24210
|
+
arguments: [event],
|
|
24211
|
+
captureTurnSpans,
|
|
24212
|
+
context: ctx
|
|
24213
|
+
});
|
|
24214
|
+
});
|
|
24215
|
+
if (existingSubscription) {
|
|
24216
|
+
existingSubscription.captureTurnSpans = captureTurnSpans;
|
|
24217
|
+
existingSubscription.unsubscribe = unsubscribe;
|
|
24218
|
+
} else {
|
|
24219
|
+
Object.defineProperty(context, SUBSCRIBED_FLUE_CONTEXT_EVENTS, {
|
|
24220
|
+
configurable: false,
|
|
24221
|
+
enumerable: false,
|
|
24222
|
+
value: {
|
|
24223
|
+
captureTurnSpans,
|
|
24224
|
+
unsubscribe
|
|
24225
|
+
}
|
|
24226
|
+
});
|
|
24227
|
+
}
|
|
24228
|
+
return unsubscribe;
|
|
24229
|
+
} catch {
|
|
24230
|
+
return void 0;
|
|
24231
|
+
}
|
|
24232
|
+
}
|
|
24233
|
+
function wrapFlueHarness(harness) {
|
|
24234
|
+
if (!isPlausibleFlueHarness(harness)) {
|
|
24235
|
+
return harness;
|
|
24236
|
+
}
|
|
24237
|
+
const target = harness;
|
|
24238
|
+
if (target[WRAPPED_FLUE_HARNESS]) {
|
|
24239
|
+
return harness;
|
|
24240
|
+
}
|
|
24241
|
+
const originalSession = target.session.bind(target);
|
|
24242
|
+
try {
|
|
24243
|
+
Object.defineProperty(target, WRAPPED_FLUE_HARNESS, {
|
|
24244
|
+
configurable: false,
|
|
24245
|
+
enumerable: false,
|
|
24246
|
+
value: true
|
|
24247
|
+
});
|
|
24248
|
+
Object.defineProperty(target, "session", {
|
|
24249
|
+
configurable: true,
|
|
24250
|
+
value: async function wrappedFlueHarnessSession(name, options) {
|
|
24251
|
+
const session = await originalSession(name, options);
|
|
24252
|
+
return patchFlueSessionInPlace(session);
|
|
24253
|
+
},
|
|
24254
|
+
writable: true
|
|
24255
|
+
});
|
|
24256
|
+
const sessions = target.sessions;
|
|
24257
|
+
if (sessions && typeof sessions === "object") {
|
|
24258
|
+
patchFlueSessionFactory(sessions, "get");
|
|
24259
|
+
patchFlueSessionFactory(sessions, "create");
|
|
24260
|
+
}
|
|
24261
|
+
} catch {
|
|
24262
|
+
}
|
|
24263
|
+
return harness;
|
|
24264
|
+
}
|
|
24265
|
+
function patchFlueSessionInPlace(session) {
|
|
24266
|
+
if (session[WRAPPED_FLUE_SESSION]) {
|
|
24267
|
+
return session;
|
|
24268
|
+
}
|
|
24269
|
+
try {
|
|
24270
|
+
Object.defineProperty(session, WRAPPED_FLUE_SESSION, {
|
|
24271
|
+
configurable: false,
|
|
24272
|
+
enumerable: false,
|
|
24273
|
+
value: true
|
|
24274
|
+
});
|
|
24275
|
+
patchCallHandleMethod(session, "prompt", flueChannels.prompt);
|
|
24276
|
+
patchCallHandleMethod(session, "skill", flueChannels.skill);
|
|
24277
|
+
patchCallHandleMethod(session, "task", flueChannels.task);
|
|
24278
|
+
patchCompact(session);
|
|
24279
|
+
} catch {
|
|
24280
|
+
}
|
|
24281
|
+
return session;
|
|
24282
|
+
}
|
|
24283
|
+
function patchFlueSessionFactory(sessions, method) {
|
|
24284
|
+
const original = sessions[method];
|
|
24285
|
+
if (typeof original !== "function") {
|
|
24286
|
+
return;
|
|
24287
|
+
}
|
|
24288
|
+
const bound = original.bind(sessions);
|
|
24289
|
+
Object.defineProperty(sessions, method, {
|
|
24290
|
+
configurable: true,
|
|
24291
|
+
value: async function wrappedFlueSessionFactory(name, options) {
|
|
24292
|
+
const session = await bound(name, options);
|
|
24293
|
+
return patchFlueSessionInPlace(session);
|
|
24294
|
+
},
|
|
24295
|
+
writable: true
|
|
24296
|
+
});
|
|
24297
|
+
}
|
|
24298
|
+
function patchCallHandleMethod(session, method, channel2) {
|
|
24299
|
+
const original = session[method];
|
|
24300
|
+
if (typeof original !== "function") {
|
|
24301
|
+
return;
|
|
24302
|
+
}
|
|
24303
|
+
const bound = original.bind(session);
|
|
24304
|
+
Object.defineProperty(session, method, {
|
|
24305
|
+
configurable: true,
|
|
24306
|
+
value(input, options) {
|
|
24307
|
+
const args = [input, options];
|
|
24308
|
+
const { originalResult, traced: traced2 } = traceFlueOperation(channel2, {
|
|
24309
|
+
context: {
|
|
24310
|
+
arguments: args,
|
|
24311
|
+
operation: method,
|
|
24312
|
+
session
|
|
24313
|
+
},
|
|
24314
|
+
run: () => bound(input, options)
|
|
24315
|
+
});
|
|
24316
|
+
return preserveCallHandle(originalResult, traced2);
|
|
24317
|
+
},
|
|
24318
|
+
writable: true
|
|
24319
|
+
});
|
|
24320
|
+
}
|
|
24321
|
+
function patchCompact(session) {
|
|
24322
|
+
const original = session.compact;
|
|
24323
|
+
if (typeof original !== "function") {
|
|
24324
|
+
return;
|
|
24325
|
+
}
|
|
24326
|
+
const bound = original.bind(session);
|
|
24327
|
+
Object.defineProperty(session, "compact", {
|
|
24328
|
+
configurable: true,
|
|
24329
|
+
value() {
|
|
24330
|
+
const context = {
|
|
24331
|
+
arguments: [],
|
|
24332
|
+
operation: "compact",
|
|
24333
|
+
session
|
|
24334
|
+
};
|
|
24335
|
+
return flueChannels.compact.tracePromise(() => bound(), context);
|
|
24336
|
+
},
|
|
24337
|
+
writable: true
|
|
24338
|
+
});
|
|
24339
|
+
}
|
|
24340
|
+
function traceFlueOperation(channel2, args) {
|
|
24341
|
+
const tracingChannel2 = channel2.tracingChannel();
|
|
24342
|
+
const context = args.context;
|
|
24343
|
+
let originalResult;
|
|
24344
|
+
let traced2;
|
|
24345
|
+
const run = () => {
|
|
24346
|
+
try {
|
|
24347
|
+
originalResult = args.run();
|
|
24348
|
+
tracingChannel2.end?.publish(context);
|
|
24349
|
+
} catch (error) {
|
|
24350
|
+
context.error = normalizeError3(error);
|
|
24351
|
+
tracingChannel2.error?.publish(context);
|
|
24352
|
+
tracingChannel2.end?.publish(context);
|
|
24353
|
+
throw error;
|
|
24354
|
+
}
|
|
24355
|
+
traced2 = Promise.resolve(originalResult).then(
|
|
24356
|
+
(result) => {
|
|
24357
|
+
context.result = result;
|
|
24358
|
+
tracingChannel2.asyncStart?.publish(context);
|
|
24359
|
+
tracingChannel2.asyncEnd?.publish(context);
|
|
24360
|
+
return result;
|
|
24361
|
+
},
|
|
24362
|
+
(error) => {
|
|
24363
|
+
context.error = normalizeError3(error);
|
|
24364
|
+
tracingChannel2.error?.publish(context);
|
|
24365
|
+
tracingChannel2.asyncStart?.publish(context);
|
|
24366
|
+
tracingChannel2.asyncEnd?.publish(context);
|
|
24367
|
+
throw error;
|
|
24368
|
+
}
|
|
24369
|
+
);
|
|
24370
|
+
};
|
|
24371
|
+
if (tracingChannel2.start?.runStores) {
|
|
24372
|
+
tracingChannel2.start.runStores(context, run);
|
|
24373
|
+
} else {
|
|
24374
|
+
tracingChannel2.start?.publish(context);
|
|
24375
|
+
run();
|
|
24376
|
+
}
|
|
24377
|
+
return { originalResult, traced: traced2 };
|
|
24378
|
+
}
|
|
24379
|
+
function normalizeError3(error) {
|
|
24380
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
24381
|
+
}
|
|
24382
|
+
function preserveCallHandle(originalHandle, traced2) {
|
|
24383
|
+
if (!isFlueCallHandle(originalHandle)) {
|
|
24384
|
+
return traced2;
|
|
24385
|
+
}
|
|
24386
|
+
const handle = originalHandle;
|
|
24387
|
+
const wrapped = {
|
|
24388
|
+
get signal() {
|
|
24389
|
+
return handle.signal;
|
|
24390
|
+
},
|
|
24391
|
+
abort(reason) {
|
|
24392
|
+
return handle.abort(reason);
|
|
24393
|
+
},
|
|
24394
|
+
then(onfulfilled, onrejected) {
|
|
24395
|
+
return traced2.then(onfulfilled, onrejected);
|
|
24396
|
+
}
|
|
24397
|
+
};
|
|
24398
|
+
return wrapped;
|
|
24399
|
+
}
|
|
24400
|
+
function isPlausibleFlueContext(value) {
|
|
24401
|
+
return !!value && typeof value === "object" && typeof value.init === "function";
|
|
24402
|
+
}
|
|
24403
|
+
function isPlausibleFlueHarness(value) {
|
|
24404
|
+
return !!value && typeof value === "object" && typeof value.session === "function";
|
|
24405
|
+
}
|
|
24406
|
+
function isPlausibleFlueSession(value) {
|
|
24407
|
+
return !!value && typeof value === "object" && typeof value.prompt === "function" && typeof value.skill === "function" && typeof value.task === "function" && typeof value.compact === "function";
|
|
24408
|
+
}
|
|
24409
|
+
function isFlueCallHandle(value) {
|
|
24410
|
+
return !!value && typeof value === "object" && typeof value.then === "function" && typeof value.abort === "function" && "signal" in value;
|
|
24411
|
+
}
|
|
24412
|
+
|
|
24413
|
+
// src/instrumentation/plugins/flue-plugin.ts
|
|
24414
|
+
var FluePlugin = class extends BasePlugin {
|
|
24415
|
+
activeOperationsById = /* @__PURE__ */ new Map();
|
|
24416
|
+
activeOperationsByScope = /* @__PURE__ */ new Map();
|
|
24417
|
+
compactionsByScope = /* @__PURE__ */ new Map();
|
|
24418
|
+
pendingOperationsByKey = /* @__PURE__ */ new Map();
|
|
24419
|
+
tasksById = /* @__PURE__ */ new Map();
|
|
24420
|
+
toolsById = /* @__PURE__ */ new Map();
|
|
24421
|
+
turnsByScope = /* @__PURE__ */ new Map();
|
|
24422
|
+
onEnable() {
|
|
24423
|
+
this.subscribeToContextCreation();
|
|
24424
|
+
this.subscribeToSessionCreation();
|
|
24425
|
+
this.subscribeToContextEvents();
|
|
24426
|
+
this.subscribeToSessionOperations();
|
|
24427
|
+
}
|
|
24428
|
+
onDisable() {
|
|
24429
|
+
for (const unsubscribe of this.unsubscribers) {
|
|
24430
|
+
unsubscribe();
|
|
24431
|
+
}
|
|
24432
|
+
this.unsubscribers = [];
|
|
24433
|
+
this.activeOperationsById.clear();
|
|
24434
|
+
this.activeOperationsByScope.clear();
|
|
24435
|
+
this.compactionsByScope.clear();
|
|
24436
|
+
this.pendingOperationsByKey.clear();
|
|
24437
|
+
this.tasksById.clear();
|
|
24438
|
+
this.toolsById.clear();
|
|
24439
|
+
this.turnsByScope.clear();
|
|
24440
|
+
}
|
|
24441
|
+
subscribeToContextCreation() {
|
|
24442
|
+
const channel2 = flueChannels.createContext.tracingChannel();
|
|
24443
|
+
const handlers = {
|
|
24444
|
+
end: (event) => {
|
|
24445
|
+
const ctx = event.result;
|
|
24446
|
+
if (!ctx) {
|
|
24447
|
+
return;
|
|
24448
|
+
}
|
|
24449
|
+
subscribeFlueContextEvents(ctx, { captureTurnSpans: false });
|
|
24450
|
+
patchFlueContextInPlace(ctx);
|
|
24451
|
+
},
|
|
24452
|
+
error: () => {
|
|
24453
|
+
}
|
|
24454
|
+
};
|
|
24455
|
+
channel2.subscribe(handlers);
|
|
24456
|
+
this.unsubscribers.push(() => {
|
|
24457
|
+
channel2.unsubscribe(handlers);
|
|
24458
|
+
});
|
|
24459
|
+
}
|
|
24460
|
+
subscribeToSessionCreation() {
|
|
24461
|
+
const channel2 = flueChannels.openSession.tracingChannel();
|
|
24462
|
+
const handlers = {
|
|
24463
|
+
asyncEnd: (event) => {
|
|
24464
|
+
if (event.result) {
|
|
24465
|
+
patchFlueSessionInPlace(
|
|
24466
|
+
event.result
|
|
24467
|
+
);
|
|
24468
|
+
}
|
|
24469
|
+
if (event.harness) {
|
|
24470
|
+
wrapFlueHarness(event.harness);
|
|
24471
|
+
}
|
|
24472
|
+
},
|
|
24473
|
+
error: () => {
|
|
24474
|
+
}
|
|
24475
|
+
};
|
|
24476
|
+
channel2.subscribe(handlers);
|
|
24477
|
+
this.unsubscribers.push(() => {
|
|
24478
|
+
channel2.unsubscribe(handlers);
|
|
24479
|
+
});
|
|
24480
|
+
}
|
|
24481
|
+
subscribeToSessionOperations() {
|
|
24482
|
+
this.subscribeToSessionOperation(flueChannels.prompt);
|
|
24483
|
+
this.subscribeToSessionOperation(flueChannels.skill);
|
|
24484
|
+
this.subscribeToSessionOperation(flueChannels.task);
|
|
24485
|
+
this.subscribeToCompact();
|
|
24486
|
+
}
|
|
24487
|
+
subscribeToSessionOperation(channel2) {
|
|
24488
|
+
const tracingChannel2 = channel2.tracingChannel();
|
|
24489
|
+
const states = /* @__PURE__ */ new WeakMap();
|
|
24490
|
+
const ensureState2 = (event) => {
|
|
24491
|
+
const existing = states.get(event);
|
|
24492
|
+
if (existing) {
|
|
24493
|
+
return existing;
|
|
24494
|
+
}
|
|
24495
|
+
const state = this.startOperationState({
|
|
24496
|
+
args: event.arguments,
|
|
24497
|
+
moduleVersion: typeof event.moduleVersion === "string" ? event.moduleVersion : void 0,
|
|
24498
|
+
operation: event.operation,
|
|
24499
|
+
session: event.session
|
|
24500
|
+
});
|
|
24501
|
+
states.set(event, state);
|
|
24502
|
+
return state;
|
|
24503
|
+
};
|
|
24504
|
+
const unbindCurrentSpanStore = this.bindCurrentSpanStoreToOperationStart(
|
|
24505
|
+
tracingChannel2,
|
|
24506
|
+
ensureState2
|
|
24507
|
+
);
|
|
24508
|
+
const handlers = {
|
|
24509
|
+
start: (event) => {
|
|
24510
|
+
ensureState2(event);
|
|
24511
|
+
},
|
|
24512
|
+
asyncEnd: (event) => {
|
|
24513
|
+
this.endOperationState(states.get(event), event.result);
|
|
24514
|
+
states.delete(event);
|
|
24515
|
+
},
|
|
24516
|
+
error: (event) => {
|
|
24517
|
+
const state = states.get(event);
|
|
24518
|
+
if (state && event.error) {
|
|
24519
|
+
safeLog3(state.span, { error: errorToString(event.error) });
|
|
24520
|
+
this.finishOperationState(state);
|
|
24521
|
+
}
|
|
24522
|
+
states.delete(event);
|
|
24523
|
+
}
|
|
24524
|
+
};
|
|
24525
|
+
tracingChannel2.subscribe(handlers);
|
|
24526
|
+
this.unsubscribers.push(() => {
|
|
24527
|
+
unbindCurrentSpanStore?.();
|
|
24528
|
+
tracingChannel2.unsubscribe(handlers);
|
|
24529
|
+
});
|
|
24530
|
+
}
|
|
24531
|
+
subscribeToCompact() {
|
|
24532
|
+
const tracingChannel2 = flueChannels.compact.tracingChannel();
|
|
24533
|
+
const states = /* @__PURE__ */ new WeakMap();
|
|
24534
|
+
const ensureState2 = (event) => {
|
|
24535
|
+
const existing = states.get(event);
|
|
24536
|
+
if (existing) {
|
|
24537
|
+
return existing;
|
|
24538
|
+
}
|
|
24539
|
+
const state = this.startOperationState({
|
|
24540
|
+
args: [],
|
|
24541
|
+
moduleVersion: typeof event.moduleVersion === "string" ? event.moduleVersion : void 0,
|
|
24542
|
+
operation: event.operation,
|
|
24543
|
+
session: event.session
|
|
24544
|
+
});
|
|
24545
|
+
states.set(event, state);
|
|
24546
|
+
return state;
|
|
24547
|
+
};
|
|
24548
|
+
const unbindCurrentSpanStore = this.bindCurrentSpanStoreToOperationStart(
|
|
24549
|
+
tracingChannel2,
|
|
24550
|
+
ensureState2
|
|
24551
|
+
);
|
|
24552
|
+
const handlers = {
|
|
24553
|
+
start: (event) => {
|
|
24554
|
+
ensureState2(event);
|
|
24555
|
+
},
|
|
24556
|
+
asyncEnd: (event) => {
|
|
24557
|
+
this.endOperationState(states.get(event), void 0);
|
|
24558
|
+
states.delete(event);
|
|
24559
|
+
},
|
|
24560
|
+
error: (event) => {
|
|
24561
|
+
const state = states.get(event);
|
|
24562
|
+
if (state && event.error) {
|
|
24563
|
+
safeLog3(state.span, { error: errorToString(event.error) });
|
|
24564
|
+
this.finishOperationState(state);
|
|
24565
|
+
}
|
|
24566
|
+
states.delete(event);
|
|
24567
|
+
}
|
|
24568
|
+
};
|
|
24569
|
+
tracingChannel2.subscribe(handlers);
|
|
24570
|
+
this.unsubscribers.push(() => {
|
|
24571
|
+
unbindCurrentSpanStore?.();
|
|
24572
|
+
tracingChannel2.unsubscribe(handlers);
|
|
24573
|
+
});
|
|
24574
|
+
}
|
|
24575
|
+
subscribeToContextEvents() {
|
|
24576
|
+
const channel2 = flueChannels.contextEvent.tracingChannel();
|
|
24577
|
+
const handlers = {
|
|
24578
|
+
start: (event) => {
|
|
24579
|
+
const flueEvent = event.arguments[0];
|
|
24580
|
+
if (!flueEvent) {
|
|
24581
|
+
return;
|
|
24582
|
+
}
|
|
24583
|
+
try {
|
|
24584
|
+
this.handleFlueEvent(flueEvent, {
|
|
24585
|
+
captureTurnSpans: event.captureTurnSpans !== false
|
|
24586
|
+
});
|
|
24587
|
+
} catch (error) {
|
|
24588
|
+
logInstrumentationError3("Flue event", error);
|
|
24589
|
+
}
|
|
24590
|
+
},
|
|
24591
|
+
error: () => {
|
|
24592
|
+
}
|
|
24593
|
+
};
|
|
24594
|
+
channel2.subscribe(handlers);
|
|
24595
|
+
this.unsubscribers.push(() => {
|
|
24596
|
+
channel2.unsubscribe(handlers);
|
|
24597
|
+
});
|
|
24598
|
+
}
|
|
24599
|
+
bindCurrentSpanStoreToOperationStart(tracingChannel2, ensureState2) {
|
|
24600
|
+
const state = _internalGetGlobalState();
|
|
24601
|
+
const startChannel = tracingChannel2.start;
|
|
24602
|
+
const contextManager = state?.contextManager;
|
|
24603
|
+
const currentSpanStore = contextManager ? contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
|
|
24604
|
+
if (!currentSpanStore || !startChannel) {
|
|
24605
|
+
return void 0;
|
|
24606
|
+
}
|
|
24607
|
+
startChannel.bindStore(currentSpanStore, (event) => {
|
|
24608
|
+
const operationState = ensureState2(event);
|
|
24609
|
+
return contextManager.wrapSpanForStore(operationState.span);
|
|
24610
|
+
});
|
|
24611
|
+
return () => {
|
|
24612
|
+
startChannel.unbindStore(currentSpanStore);
|
|
24613
|
+
};
|
|
24614
|
+
}
|
|
24615
|
+
startOperationState(args) {
|
|
24616
|
+
const sessionName = getSessionName(args.session);
|
|
24617
|
+
const metadata = {
|
|
24618
|
+
...extractOperationInputMetadata(args.operation, args.args),
|
|
24619
|
+
...extractSessionMetadata(args.session),
|
|
24620
|
+
"flue.operation": args.operation,
|
|
24621
|
+
provider: "flue",
|
|
24622
|
+
...args.moduleVersion ? { "flue.version": args.moduleVersion } : {}
|
|
24623
|
+
};
|
|
24624
|
+
const span = startSpan({
|
|
24625
|
+
name: `flue.session.${args.operation}`,
|
|
24626
|
+
spanAttributes: { type: "task" /* TASK */ }
|
|
24627
|
+
});
|
|
24628
|
+
const state = {
|
|
24629
|
+
metadata,
|
|
24630
|
+
operation: args.operation,
|
|
24631
|
+
sessionName,
|
|
24632
|
+
span,
|
|
24633
|
+
startTime: getCurrentUnixTimestamp()
|
|
24634
|
+
};
|
|
24635
|
+
safeLog3(span, {
|
|
24636
|
+
input: extractOperationInput(args.operation, args.args),
|
|
24637
|
+
metadata
|
|
24638
|
+
});
|
|
24639
|
+
this.pendingOperationQueue(operationKey(sessionName, args.operation)).push(
|
|
24640
|
+
state
|
|
24641
|
+
);
|
|
24642
|
+
addOperationToScope(
|
|
24643
|
+
this.activeOperationsByScope,
|
|
24644
|
+
sessionName ?? "unknown",
|
|
24645
|
+
state
|
|
24646
|
+
);
|
|
24647
|
+
return state;
|
|
24648
|
+
}
|
|
24649
|
+
endOperationState(state, result) {
|
|
24650
|
+
if (!state) {
|
|
24651
|
+
return;
|
|
24652
|
+
}
|
|
24653
|
+
const metadata = {
|
|
24654
|
+
...state.metadata,
|
|
24655
|
+
...extractPromptResponseMetadata(result)
|
|
24656
|
+
};
|
|
24657
|
+
const metrics = {
|
|
24658
|
+
...buildDurationMetrics3(state.startTime),
|
|
24659
|
+
...metricsFromUsage(result?.usage)
|
|
24660
|
+
};
|
|
24661
|
+
safeLog3(state.span, {
|
|
24662
|
+
metadata,
|
|
24663
|
+
metrics,
|
|
24664
|
+
output: extractOperationOutput(result)
|
|
24665
|
+
});
|
|
24666
|
+
this.finishCompactionsForOperation(state);
|
|
24667
|
+
this.finishOperationState(state);
|
|
24668
|
+
}
|
|
24669
|
+
finishOperationState(state) {
|
|
24670
|
+
removePendingOperation(this.pendingOperationsByKey, state);
|
|
24671
|
+
if (state.operationId) {
|
|
24672
|
+
this.activeOperationsById.delete(state.operationId);
|
|
24673
|
+
}
|
|
24674
|
+
removeScopedOperation(this.activeOperationsByScope, state);
|
|
24675
|
+
state.span.end();
|
|
24676
|
+
}
|
|
24677
|
+
handleFlueEvent(event, options) {
|
|
24678
|
+
switch (event.type) {
|
|
24679
|
+
case "operation_start":
|
|
24680
|
+
this.handleOperationStart(event);
|
|
24681
|
+
return;
|
|
24682
|
+
case "operation":
|
|
24683
|
+
this.handleOperation(event);
|
|
24684
|
+
return;
|
|
24685
|
+
case "text_delta":
|
|
24686
|
+
if (!options.captureTurnSpans) {
|
|
24687
|
+
return;
|
|
24688
|
+
}
|
|
24689
|
+
this.ensureTurnState(event).text.push(
|
|
24690
|
+
typeof event.text === "string" ? event.text : ""
|
|
24691
|
+
);
|
|
24692
|
+
return;
|
|
24693
|
+
case "thinking_start":
|
|
24694
|
+
if (!options.captureTurnSpans) {
|
|
24695
|
+
return;
|
|
24696
|
+
}
|
|
24697
|
+
this.handleThinkingStart(event);
|
|
24698
|
+
return;
|
|
24699
|
+
case "thinking_delta":
|
|
24700
|
+
if (!options.captureTurnSpans) {
|
|
24701
|
+
return;
|
|
24702
|
+
}
|
|
24703
|
+
this.handleThinkingDelta(event);
|
|
24704
|
+
return;
|
|
24705
|
+
case "thinking_end":
|
|
24706
|
+
if (!options.captureTurnSpans) {
|
|
24707
|
+
return;
|
|
24708
|
+
}
|
|
24709
|
+
this.handleThinkingEnd(event);
|
|
24710
|
+
return;
|
|
24711
|
+
case "turn":
|
|
24712
|
+
if (!options.captureTurnSpans) {
|
|
24713
|
+
return;
|
|
24714
|
+
}
|
|
24715
|
+
this.handleTurn(event);
|
|
24716
|
+
return;
|
|
24717
|
+
case "tool_start":
|
|
24718
|
+
this.handleToolStart(event, options);
|
|
24719
|
+
return;
|
|
24720
|
+
case "tool_call":
|
|
24721
|
+
this.handleToolCall(event);
|
|
24722
|
+
return;
|
|
24723
|
+
case "task_start":
|
|
24724
|
+
this.handleTaskStart(event);
|
|
24725
|
+
return;
|
|
24726
|
+
case "task":
|
|
24727
|
+
this.handleTask(event);
|
|
24728
|
+
return;
|
|
24729
|
+
case "compaction_start":
|
|
24730
|
+
this.handleCompactionStart(event);
|
|
24731
|
+
return;
|
|
24732
|
+
case "compaction":
|
|
24733
|
+
this.handleCompaction(event);
|
|
24734
|
+
return;
|
|
24735
|
+
default:
|
|
24736
|
+
return;
|
|
24737
|
+
}
|
|
24738
|
+
}
|
|
24739
|
+
handleOperationStart(event) {
|
|
24740
|
+
if (!isInstrumentedOperation(event.operationKind)) {
|
|
24741
|
+
return;
|
|
24742
|
+
}
|
|
24743
|
+
const state = this.takePendingOperationForEvent(event);
|
|
24744
|
+
if (!state) {
|
|
24745
|
+
return;
|
|
24746
|
+
}
|
|
24747
|
+
state.operationId = event.operationId;
|
|
24748
|
+
this.activeOperationsById.set(event.operationId, state);
|
|
24749
|
+
addScopedOperation(this.activeOperationsByScope, event, state);
|
|
24750
|
+
state.metadata = {
|
|
24751
|
+
...state.metadata,
|
|
24752
|
+
...extractEventMetadata(event),
|
|
24753
|
+
"flue.operation_id": event.operationId
|
|
24754
|
+
};
|
|
24755
|
+
safeLog3(state.span, { metadata: state.metadata });
|
|
24756
|
+
}
|
|
24757
|
+
handleOperation(event) {
|
|
24758
|
+
const state = event.operationId ? this.activeOperationsById.get(event.operationId) : void 0;
|
|
24759
|
+
if (!state) {
|
|
24760
|
+
return;
|
|
24761
|
+
}
|
|
24762
|
+
const metadata = {
|
|
24763
|
+
...state.metadata,
|
|
24764
|
+
...extractEventMetadata(event),
|
|
24765
|
+
...typeof event.durationMs === "number" ? { "flue.duration_ms": event.durationMs } : {},
|
|
24766
|
+
...event.isError !== void 0 ? { "flue.is_error": event.isError } : {}
|
|
24767
|
+
};
|
|
24768
|
+
const metrics = metricsFromUsage(event.usage);
|
|
24769
|
+
safeLog3(state.span, {
|
|
24770
|
+
...event.error ? { error: errorToString(event.error) } : {},
|
|
24771
|
+
metadata,
|
|
24772
|
+
...Object.keys(metrics).length ? { metrics } : {}
|
|
24773
|
+
});
|
|
24774
|
+
}
|
|
24775
|
+
ensureTurnState(event) {
|
|
24776
|
+
const scope = scopeKey(event);
|
|
24777
|
+
const existing = this.turnsByScope.get(scope);
|
|
24778
|
+
if (existing) {
|
|
24779
|
+
return existing;
|
|
24780
|
+
}
|
|
24781
|
+
const parent = this.parentSpanForEvent(event);
|
|
24782
|
+
const metadata = {
|
|
24783
|
+
...extractEventMetadata(event),
|
|
24784
|
+
provider: "flue"
|
|
24785
|
+
};
|
|
24786
|
+
const span = startFlueSpan(parent, {
|
|
24787
|
+
name: "flue.turn",
|
|
24788
|
+
spanAttributes: { type: "llm" /* LLM */ }
|
|
24789
|
+
});
|
|
24790
|
+
const state = {
|
|
24791
|
+
metadata,
|
|
24792
|
+
span,
|
|
24793
|
+
hasThinking: false,
|
|
24794
|
+
startTime: getCurrentUnixTimestamp(),
|
|
24795
|
+
text: [],
|
|
24796
|
+
thinking: [],
|
|
24797
|
+
toolCalls: []
|
|
24798
|
+
};
|
|
24799
|
+
safeLog3(span, { metadata });
|
|
24800
|
+
this.turnsByScope.set(scope, state);
|
|
24801
|
+
return state;
|
|
24802
|
+
}
|
|
24803
|
+
handleTurn(event) {
|
|
24804
|
+
const scope = scopeKey(event);
|
|
24805
|
+
const state = this.ensureTurnState(event);
|
|
24806
|
+
const text = state.text.join("");
|
|
24807
|
+
const reasoning = state.finalThinking ?? state.thinking.join("");
|
|
24808
|
+
const outputReasoning = reasoning || (state.hasThinking ? "[reasoning stream present; content unavailable]" : void 0);
|
|
24809
|
+
const metadata = {
|
|
24810
|
+
...state.metadata,
|
|
24811
|
+
...extractEventMetadata(event),
|
|
24812
|
+
...event.model ? { model: event.model, "flue.model": event.model } : {},
|
|
24813
|
+
...event.stopReason ? { "flue.stop_reason": event.stopReason } : {},
|
|
24814
|
+
...event.isError !== void 0 ? { "flue.is_error": event.isError } : {},
|
|
24815
|
+
provider: "flue"
|
|
24816
|
+
};
|
|
24817
|
+
safeLog3(state.span, {
|
|
24818
|
+
...event.error ? { error: errorToString(event.error) } : {},
|
|
24819
|
+
metadata,
|
|
24820
|
+
metrics: {
|
|
24821
|
+
...durationMsMetrics(event.durationMs),
|
|
24822
|
+
...metricsFromUsage(event.usage)
|
|
24823
|
+
},
|
|
24824
|
+
output: toAssistantOutput(
|
|
24825
|
+
text,
|
|
24826
|
+
event.stopReason,
|
|
24827
|
+
outputReasoning,
|
|
24828
|
+
state.toolCalls
|
|
24829
|
+
)
|
|
24830
|
+
});
|
|
24831
|
+
state.span.end();
|
|
24832
|
+
this.turnsByScope.delete(scope);
|
|
24833
|
+
}
|
|
24834
|
+
handleThinkingDelta(event) {
|
|
24835
|
+
const delta = event.delta;
|
|
24836
|
+
if (typeof delta !== "string" || !delta) {
|
|
24837
|
+
return;
|
|
24838
|
+
}
|
|
24839
|
+
const state = this.ensureTurnState(event);
|
|
24840
|
+
state.hasThinking = true;
|
|
24841
|
+
state.metadata["flue.thinking"] = true;
|
|
24842
|
+
state.thinking.push(delta);
|
|
24843
|
+
}
|
|
24844
|
+
handleThinkingStart(event) {
|
|
24845
|
+
const state = this.ensureTurnState(event);
|
|
24846
|
+
state.hasThinking = true;
|
|
24847
|
+
state.metadata["flue.thinking"] = true;
|
|
24848
|
+
}
|
|
24849
|
+
handleThinkingEnd(event) {
|
|
24850
|
+
const state = this.ensureTurnState(event);
|
|
24851
|
+
state.hasThinking = true;
|
|
24852
|
+
state.metadata["flue.thinking"] = true;
|
|
24853
|
+
if (typeof event.content === "string" && event.content) {
|
|
24854
|
+
state.finalThinking = event.content;
|
|
24855
|
+
}
|
|
24856
|
+
}
|
|
24857
|
+
handleToolStart(event, options) {
|
|
24858
|
+
const toolCallId = event.toolCallId;
|
|
24859
|
+
if (!toolCallId) {
|
|
24860
|
+
return;
|
|
24861
|
+
}
|
|
24862
|
+
const parent = this.parentSpanForEvent(event);
|
|
24863
|
+
const scope = scopeKey(event);
|
|
24864
|
+
let turnState = this.turnsByScope.get(scope);
|
|
24865
|
+
if (!turnState && parent && options.captureTurnSpans) {
|
|
24866
|
+
turnState = this.ensureTurnState(event);
|
|
24867
|
+
}
|
|
24868
|
+
const metadata = {
|
|
24869
|
+
...extractEventMetadata(event),
|
|
24870
|
+
...event.toolName ? { "flue.tool_name": event.toolName } : {},
|
|
24871
|
+
"flue.tool_call_id": toolCallId,
|
|
24872
|
+
provider: "flue"
|
|
24873
|
+
};
|
|
24874
|
+
const span = startFlueSpan(parent, {
|
|
24875
|
+
name: `tool: ${event.toolName ?? "unknown"}`,
|
|
24876
|
+
spanAttributes: { type: "tool" /* TOOL */ }
|
|
24877
|
+
});
|
|
24878
|
+
if (turnState) {
|
|
24879
|
+
turnState.toolCalls.push({
|
|
24880
|
+
args: event.args,
|
|
24881
|
+
toolCallId,
|
|
24882
|
+
toolName: event.toolName
|
|
24883
|
+
});
|
|
24884
|
+
}
|
|
24885
|
+
safeLog3(span, {
|
|
24886
|
+
input: event.args,
|
|
24887
|
+
metadata
|
|
24888
|
+
});
|
|
24889
|
+
this.toolsById.set(toolKey(event), {
|
|
24890
|
+
metadata,
|
|
24891
|
+
span,
|
|
24892
|
+
startTime: getCurrentUnixTimestamp()
|
|
24893
|
+
});
|
|
24894
|
+
}
|
|
24895
|
+
handleToolCall(event) {
|
|
24896
|
+
const key = toolKey(event);
|
|
24897
|
+
const state = this.toolsById.get(key) ?? this.startSyntheticToolState(event, event.toolName ?? "unknown");
|
|
24898
|
+
const metadata = {
|
|
24899
|
+
...state.metadata,
|
|
24900
|
+
...extractEventMetadata(event),
|
|
24901
|
+
...event.toolName ? { "flue.tool_name": event.toolName } : {},
|
|
24902
|
+
...event.toolCallId ? { "flue.tool_call_id": event.toolCallId } : {},
|
|
24903
|
+
...event.isError !== void 0 ? { "flue.is_error": event.isError } : {}
|
|
24904
|
+
};
|
|
24905
|
+
safeLog3(state.span, {
|
|
24906
|
+
...event.isError ? { error: errorToString(event.result) } : {},
|
|
24907
|
+
metadata,
|
|
24908
|
+
metrics: durationMsMetrics(event.durationMs),
|
|
24909
|
+
output: event.result
|
|
24910
|
+
});
|
|
24911
|
+
state.span.end();
|
|
24912
|
+
this.toolsById.delete(key);
|
|
24913
|
+
}
|
|
24914
|
+
handleTaskStart(event) {
|
|
24915
|
+
const parent = this.parentSpanForEvent(event);
|
|
24916
|
+
const metadata = {
|
|
24917
|
+
...extractEventMetadata(event),
|
|
24918
|
+
...event.role ? { "flue.role": event.role } : {},
|
|
24919
|
+
...event.cwd ? { "flue.cwd": event.cwd } : {},
|
|
24920
|
+
"flue.task_id": event.taskId,
|
|
24921
|
+
provider: "flue"
|
|
24922
|
+
};
|
|
24923
|
+
const span = startFlueSpan(parent, {
|
|
24924
|
+
name: "flue.task",
|
|
24925
|
+
spanAttributes: { type: "task" /* TASK */ }
|
|
24926
|
+
});
|
|
24927
|
+
safeLog3(span, {
|
|
24928
|
+
input: event.prompt,
|
|
24929
|
+
metadata
|
|
24930
|
+
});
|
|
24931
|
+
this.tasksById.set(event.taskId, {
|
|
24932
|
+
metadata,
|
|
24933
|
+
span,
|
|
24934
|
+
startTime: getCurrentUnixTimestamp()
|
|
24935
|
+
});
|
|
24936
|
+
}
|
|
24937
|
+
handleTask(event) {
|
|
24938
|
+
const state = this.tasksById.get(event.taskId);
|
|
24939
|
+
if (!state) {
|
|
24940
|
+
return;
|
|
24941
|
+
}
|
|
24942
|
+
safeLog3(state.span, {
|
|
24943
|
+
...event.isError ? { error: errorToString(event.result) } : {},
|
|
24944
|
+
metadata: {
|
|
24945
|
+
...state.metadata,
|
|
24946
|
+
...extractEventMetadata(event),
|
|
24947
|
+
...event.isError !== void 0 ? { "flue.is_error": event.isError } : {}
|
|
24948
|
+
},
|
|
24949
|
+
metrics: durationMsMetrics(event.durationMs),
|
|
24950
|
+
output: event.result
|
|
24951
|
+
});
|
|
24952
|
+
state.span.end();
|
|
24953
|
+
this.tasksById.delete(event.taskId);
|
|
24954
|
+
}
|
|
24955
|
+
handleCompactionStart(event) {
|
|
24956
|
+
const operationState = this.operationStateForEvent(event);
|
|
24957
|
+
const parent = operationState?.span ?? this.parentSpanForEvent(event);
|
|
24958
|
+
const metadata = {
|
|
24959
|
+
...extractEventMetadata(event),
|
|
24960
|
+
...event.reason ? { "flue.compaction_reason": event.reason } : {},
|
|
24961
|
+
provider: "flue"
|
|
24962
|
+
};
|
|
24963
|
+
const input = {
|
|
24964
|
+
...typeof event.estimatedTokens === "number" ? { estimatedTokens: event.estimatedTokens } : {},
|
|
24965
|
+
...event.reason ? { reason: event.reason } : {}
|
|
24966
|
+
};
|
|
24967
|
+
const span = startFlueSpan(parent, {
|
|
24968
|
+
name: "flue.compaction",
|
|
24969
|
+
spanAttributes: { type: "task" /* TASK */ }
|
|
24970
|
+
});
|
|
24971
|
+
safeLog3(span, {
|
|
24972
|
+
input,
|
|
24973
|
+
metadata
|
|
24974
|
+
});
|
|
24975
|
+
this.compactionsByScope.set(scopeKey(event), {
|
|
24976
|
+
input,
|
|
24977
|
+
metadata,
|
|
24978
|
+
operationState,
|
|
24979
|
+
span,
|
|
24980
|
+
startTime: getCurrentUnixTimestamp()
|
|
24981
|
+
});
|
|
24982
|
+
}
|
|
24983
|
+
handleCompaction(event) {
|
|
24984
|
+
const key = scopeKey(event);
|
|
24985
|
+
const state = this.compactionsByScope.get(key) ?? this.findCompactionState(event);
|
|
24986
|
+
if (!state) {
|
|
24987
|
+
return;
|
|
24988
|
+
}
|
|
24989
|
+
safeLog3(state.span, {
|
|
24990
|
+
metadata: {
|
|
24991
|
+
...state.metadata,
|
|
24992
|
+
...extractEventMetadata(event),
|
|
24993
|
+
...typeof event.messagesBefore === "number" ? { "flue.messages_before": event.messagesBefore } : {},
|
|
24994
|
+
...typeof event.messagesAfter === "number" ? { "flue.messages_after": event.messagesAfter } : {}
|
|
24995
|
+
},
|
|
24996
|
+
metrics: {
|
|
24997
|
+
...durationMsMetrics(event.durationMs),
|
|
24998
|
+
...metricsFromUsage(event.usage)
|
|
24999
|
+
},
|
|
25000
|
+
output: {
|
|
25001
|
+
messagesAfter: event.messagesAfter,
|
|
25002
|
+
messagesBefore: event.messagesBefore
|
|
25003
|
+
}
|
|
25004
|
+
});
|
|
25005
|
+
state.span.end();
|
|
25006
|
+
this.deleteCompactionState(state);
|
|
25007
|
+
}
|
|
25008
|
+
findCompactionState(event) {
|
|
25009
|
+
const operationState = this.operationStateForEvent(event);
|
|
25010
|
+
for (const state of this.compactionsByScope.values()) {
|
|
25011
|
+
if (operationState && state.operationState === operationState) {
|
|
25012
|
+
return state;
|
|
25013
|
+
}
|
|
25014
|
+
}
|
|
25015
|
+
return void 0;
|
|
25016
|
+
}
|
|
25017
|
+
finishCompactionsForOperation(operationState) {
|
|
25018
|
+
for (const state of [...this.compactionsByScope.values()]) {
|
|
25019
|
+
if (state.operationState !== operationState) {
|
|
25020
|
+
continue;
|
|
25021
|
+
}
|
|
25022
|
+
safeLog3(state.span, {
|
|
25023
|
+
input: state.input,
|
|
25024
|
+
metadata: state.metadata,
|
|
25025
|
+
metrics: {
|
|
25026
|
+
...buildDurationMetrics3(state.startTime)
|
|
25027
|
+
},
|
|
25028
|
+
output: { completed: true }
|
|
25029
|
+
});
|
|
25030
|
+
state.span.end();
|
|
25031
|
+
this.deleteCompactionState(state);
|
|
25032
|
+
}
|
|
25033
|
+
}
|
|
25034
|
+
deleteCompactionState(state) {
|
|
25035
|
+
for (const [key, candidate] of this.compactionsByScope) {
|
|
25036
|
+
if (candidate !== state) {
|
|
25037
|
+
continue;
|
|
25038
|
+
}
|
|
25039
|
+
this.compactionsByScope.delete(key);
|
|
25040
|
+
return;
|
|
25041
|
+
}
|
|
25042
|
+
}
|
|
25043
|
+
startSyntheticToolState(event, toolName) {
|
|
25044
|
+
const parent = this.parentSpanForEvent(event);
|
|
25045
|
+
const metadata = {
|
|
25046
|
+
...extractEventMetadata(event),
|
|
25047
|
+
...event.toolCallId ? { "flue.tool_call_id": event.toolCallId } : {},
|
|
25048
|
+
"flue.tool_name": toolName,
|
|
25049
|
+
provider: "flue"
|
|
25050
|
+
};
|
|
25051
|
+
const span = startFlueSpan(parent, {
|
|
25052
|
+
name: `tool: ${toolName}`,
|
|
25053
|
+
spanAttributes: { type: "tool" /* TOOL */ }
|
|
25054
|
+
});
|
|
25055
|
+
safeLog3(span, { metadata });
|
|
25056
|
+
return { metadata, span, startTime: getCurrentUnixTimestamp() };
|
|
25057
|
+
}
|
|
25058
|
+
operationStateForEvent(event) {
|
|
25059
|
+
if (event.operationId) {
|
|
25060
|
+
const operation = this.activeOperationsById.get(event.operationId) ?? this.promotePendingOperationForEvent(event);
|
|
25061
|
+
if (operation) {
|
|
25062
|
+
return operation;
|
|
25063
|
+
}
|
|
25064
|
+
}
|
|
25065
|
+
return this.activeOperationForEventScope(event) ?? this.pendingOperationForEventScope(event);
|
|
25066
|
+
}
|
|
25067
|
+
parentSpanForEvent(event) {
|
|
25068
|
+
if (event.operationId) {
|
|
25069
|
+
const operation = this.operationStateForEvent(event);
|
|
25070
|
+
if (operation) {
|
|
25071
|
+
return operation.span;
|
|
25072
|
+
}
|
|
25073
|
+
}
|
|
25074
|
+
if (event.taskId) {
|
|
25075
|
+
return this.tasksById.get(event.taskId)?.span;
|
|
25076
|
+
}
|
|
25077
|
+
return this.operationStateForEvent(event)?.span;
|
|
25078
|
+
}
|
|
25079
|
+
promotePendingOperationForEvent(event) {
|
|
25080
|
+
if (!event.operationId) {
|
|
25081
|
+
return void 0;
|
|
25082
|
+
}
|
|
25083
|
+
const scopePrefixes = operationScopePrefixes(event);
|
|
25084
|
+
for (const [candidateKey, candidateQueue] of this.pendingOperationsByKey) {
|
|
25085
|
+
if (!candidateQueue.length || !operationKeyMatchesScopes(candidateKey, scopePrefixes)) {
|
|
25086
|
+
continue;
|
|
25087
|
+
}
|
|
25088
|
+
const state = candidateQueue.shift();
|
|
25089
|
+
if (!state) {
|
|
25090
|
+
return void 0;
|
|
25091
|
+
}
|
|
25092
|
+
state.operationId = event.operationId;
|
|
25093
|
+
this.activeOperationsById.set(event.operationId, state);
|
|
25094
|
+
addScopedOperation(this.activeOperationsByScope, event, state);
|
|
25095
|
+
state.metadata = {
|
|
25096
|
+
...state.metadata,
|
|
25097
|
+
...extractEventMetadata(event),
|
|
25098
|
+
"flue.operation_id": event.operationId
|
|
25099
|
+
};
|
|
25100
|
+
safeLog3(state.span, { metadata: state.metadata });
|
|
25101
|
+
return state;
|
|
25102
|
+
}
|
|
25103
|
+
return void 0;
|
|
25104
|
+
}
|
|
25105
|
+
activeOperationForEventScope(event) {
|
|
25106
|
+
for (const scope of operationScopeNames(event)) {
|
|
25107
|
+
const operations = this.activeOperationsByScope.get(scope);
|
|
25108
|
+
if (operations?.length) {
|
|
25109
|
+
return operations[operations.length - 1];
|
|
25110
|
+
}
|
|
25111
|
+
}
|
|
25112
|
+
return void 0;
|
|
25113
|
+
}
|
|
25114
|
+
pendingOperationForEventScope(event) {
|
|
25115
|
+
const scopePrefixes = operationScopePrefixes(event);
|
|
25116
|
+
for (const [candidateKey, candidateQueue] of this.pendingOperationsByKey) {
|
|
25117
|
+
if (!candidateQueue.length || !operationKeyMatchesScopes(candidateKey, scopePrefixes)) {
|
|
25118
|
+
continue;
|
|
25119
|
+
}
|
|
25120
|
+
return candidateQueue[0];
|
|
25121
|
+
}
|
|
25122
|
+
return void 0;
|
|
25123
|
+
}
|
|
25124
|
+
takePendingOperationForEvent(event) {
|
|
25125
|
+
const key = operationKey(event.session, event.operationKind);
|
|
25126
|
+
const queue2 = this.pendingOperationsByKey.get(key);
|
|
25127
|
+
if (queue2?.length) {
|
|
25128
|
+
return queue2.shift();
|
|
25129
|
+
}
|
|
25130
|
+
for (const [candidateKey, candidateQueue] of this.pendingOperationsByKey) {
|
|
25131
|
+
if (candidateKey.endsWith(`::${event.operationKind}`) && candidateQueue.length) {
|
|
25132
|
+
return candidateQueue.shift();
|
|
25133
|
+
}
|
|
25134
|
+
}
|
|
25135
|
+
return void 0;
|
|
25136
|
+
}
|
|
25137
|
+
pendingOperationQueue(key) {
|
|
25138
|
+
const existing = this.pendingOperationsByKey.get(key);
|
|
25139
|
+
if (existing) {
|
|
25140
|
+
return existing;
|
|
25141
|
+
}
|
|
25142
|
+
const queue2 = [];
|
|
25143
|
+
this.pendingOperationsByKey.set(key, queue2);
|
|
25144
|
+
return queue2;
|
|
25145
|
+
}
|
|
25146
|
+
};
|
|
25147
|
+
function isInstrumentedOperation(operation) {
|
|
25148
|
+
return operation === "prompt" || operation === "skill" || operation === "task" || operation === "compact";
|
|
25149
|
+
}
|
|
25150
|
+
function getSessionName(session) {
|
|
25151
|
+
return typeof session?.name === "string" ? session.name : void 0;
|
|
25152
|
+
}
|
|
25153
|
+
function operationKey(sessionName, operation) {
|
|
25154
|
+
return `${sessionName ?? "unknown"}::${operation}`;
|
|
25155
|
+
}
|
|
25156
|
+
function operationScopePrefixes(event) {
|
|
25157
|
+
const scopes = /* @__PURE__ */ new Set();
|
|
25158
|
+
for (const scope of operationScopeNames(event)) {
|
|
25159
|
+
scopes.add(`${scope}::`);
|
|
25160
|
+
}
|
|
25161
|
+
return scopes;
|
|
25162
|
+
}
|
|
25163
|
+
function operationKeyMatchesScopes(key, scopes) {
|
|
25164
|
+
for (const scope of scopes) {
|
|
25165
|
+
if (key.startsWith(scope)) {
|
|
25166
|
+
return true;
|
|
25167
|
+
}
|
|
25168
|
+
}
|
|
25169
|
+
return false;
|
|
25170
|
+
}
|
|
25171
|
+
function operationScopeNames(event) {
|
|
25172
|
+
const scopes = /* @__PURE__ */ new Set();
|
|
25173
|
+
if (event.session) {
|
|
25174
|
+
scopes.add(event.session);
|
|
25175
|
+
}
|
|
25176
|
+
if (event.parentSession) {
|
|
25177
|
+
scopes.add(event.parentSession);
|
|
25178
|
+
}
|
|
25179
|
+
if (!scopes.size) {
|
|
25180
|
+
scopes.add("unknown");
|
|
25181
|
+
}
|
|
25182
|
+
return scopes;
|
|
25183
|
+
}
|
|
25184
|
+
function addScopedOperation(operationsByScope, event, state) {
|
|
25185
|
+
for (const scope of operationScopeNames(event)) {
|
|
25186
|
+
addOperationToScope(operationsByScope, scope, state);
|
|
25187
|
+
}
|
|
25188
|
+
}
|
|
25189
|
+
function addOperationToScope(operationsByScope, scope, state) {
|
|
25190
|
+
const operations = operationsByScope.get(scope);
|
|
25191
|
+
if (operations) {
|
|
25192
|
+
if (!operations.includes(state)) {
|
|
25193
|
+
operations.push(state);
|
|
25194
|
+
}
|
|
25195
|
+
} else {
|
|
25196
|
+
operationsByScope.set(scope, [state]);
|
|
25197
|
+
}
|
|
25198
|
+
}
|
|
25199
|
+
function removeScopedOperation(operationsByScope, state) {
|
|
25200
|
+
for (const [scope, operations] of operationsByScope) {
|
|
25201
|
+
const index = operations.indexOf(state);
|
|
25202
|
+
if (index === -1) {
|
|
25203
|
+
continue;
|
|
25204
|
+
}
|
|
25205
|
+
operations.splice(index, 1);
|
|
25206
|
+
if (operations.length === 0) {
|
|
25207
|
+
operationsByScope.delete(scope);
|
|
25208
|
+
}
|
|
25209
|
+
}
|
|
25210
|
+
}
|
|
25211
|
+
function removePendingOperation(pendingOperationsByKey, state) {
|
|
25212
|
+
for (const [key, queue2] of pendingOperationsByKey) {
|
|
25213
|
+
const index = queue2.indexOf(state);
|
|
25214
|
+
if (index === -1) {
|
|
25215
|
+
continue;
|
|
25216
|
+
}
|
|
25217
|
+
queue2.splice(index, 1);
|
|
25218
|
+
if (queue2.length === 0) {
|
|
25219
|
+
pendingOperationsByKey.delete(key);
|
|
25220
|
+
}
|
|
25221
|
+
return;
|
|
25222
|
+
}
|
|
25223
|
+
}
|
|
25224
|
+
function extractSessionMetadata(session) {
|
|
25225
|
+
const sessionName = getSessionName(session);
|
|
25226
|
+
return sessionName ? { "flue.session": sessionName } : {};
|
|
25227
|
+
}
|
|
25228
|
+
function extractEventMetadata(event) {
|
|
25229
|
+
return {
|
|
25230
|
+
...event.runId ? { "flue.run_id": event.runId } : {},
|
|
25231
|
+
...typeof event.eventIndex === "number" ? { "flue.event_index": event.eventIndex } : {},
|
|
25232
|
+
...event.session ? { "flue.session": event.session } : {},
|
|
25233
|
+
...event.parentSession ? { "flue.parent_session": event.parentSession } : {},
|
|
25234
|
+
...event.harness ? { "flue.harness": event.harness } : {},
|
|
25235
|
+
...event.taskId ? { "flue.task_id": event.taskId } : {},
|
|
25236
|
+
...event.operationId ? { "flue.operation_id": event.operationId } : {}
|
|
25237
|
+
};
|
|
25238
|
+
}
|
|
25239
|
+
function extractOperationInput(operation, args) {
|
|
25240
|
+
switch (operation) {
|
|
25241
|
+
case "prompt":
|
|
25242
|
+
case "task":
|
|
25243
|
+
return args[0];
|
|
25244
|
+
case "skill":
|
|
25245
|
+
return {
|
|
25246
|
+
args: getOptionObject(args[1])?.args,
|
|
25247
|
+
name: args[0]
|
|
25248
|
+
};
|
|
25249
|
+
case "compact":
|
|
25250
|
+
return void 0;
|
|
25251
|
+
}
|
|
25252
|
+
}
|
|
25253
|
+
function extractOperationInputMetadata(operation, args) {
|
|
25254
|
+
const options = getOptionObject(args[1]);
|
|
25255
|
+
return {
|
|
25256
|
+
...operation === "skill" && typeof args[0] === "string" ? { "flue.skill_name": args[0] } : {},
|
|
25257
|
+
...options?.model ? { model: options.model, "flue.model": options.model } : {},
|
|
25258
|
+
...options?.role ? { "flue.role": options.role } : {},
|
|
25259
|
+
...options?.thinkingLevel ? { "flue.thinking_level": options.thinkingLevel } : {},
|
|
25260
|
+
...typeof options?.cwd === "string" ? { "flue.cwd": options.cwd } : {},
|
|
25261
|
+
...Array.isArray(options?.tools) ? {
|
|
25262
|
+
"flue.tools_count": options.tools.length,
|
|
25263
|
+
tools: summarizeTools(options.tools)
|
|
25264
|
+
} : {},
|
|
25265
|
+
...Array.isArray(options?.images) ? { "flue.images_count": options.images.length } : {},
|
|
25266
|
+
...options?.result || options?.schema ? { "flue.result_schema": true } : {}
|
|
25267
|
+
};
|
|
25268
|
+
}
|
|
25269
|
+
function getOptionObject(value) {
|
|
25270
|
+
return isObject(value) ? value : void 0;
|
|
25271
|
+
}
|
|
25272
|
+
function summarizeTools(tools) {
|
|
25273
|
+
return tools.flatMap((tool) => {
|
|
25274
|
+
if (!isObject(tool)) {
|
|
25275
|
+
return [];
|
|
25276
|
+
}
|
|
25277
|
+
const name = typeof tool.name === "string" ? tool.name : void 0;
|
|
25278
|
+
if (!name) {
|
|
25279
|
+
return [];
|
|
25280
|
+
}
|
|
25281
|
+
return [
|
|
25282
|
+
{
|
|
25283
|
+
function: {
|
|
25284
|
+
description: typeof tool.description === "string" ? tool.description : void 0,
|
|
25285
|
+
name,
|
|
25286
|
+
parameters: tool.parameters
|
|
25287
|
+
},
|
|
25288
|
+
type: "function"
|
|
25289
|
+
}
|
|
25290
|
+
];
|
|
25291
|
+
});
|
|
25292
|
+
}
|
|
25293
|
+
function extractPromptResponseMetadata(result) {
|
|
25294
|
+
const modelId = result?.model && typeof result.model.id === "string" ? result.model.id : void 0;
|
|
25295
|
+
return modelId ? {
|
|
25296
|
+
model: modelId,
|
|
25297
|
+
"flue.model": modelId
|
|
25298
|
+
} : {};
|
|
25299
|
+
}
|
|
25300
|
+
function extractOperationOutput(result) {
|
|
25301
|
+
if (!result) {
|
|
25302
|
+
return void 0;
|
|
25303
|
+
}
|
|
25304
|
+
if ("data" in result) {
|
|
25305
|
+
return result.data;
|
|
25306
|
+
}
|
|
25307
|
+
if ("text" in result) {
|
|
25308
|
+
return result.text;
|
|
25309
|
+
}
|
|
25310
|
+
return result;
|
|
25311
|
+
}
|
|
25312
|
+
function metricsFromUsage(usage) {
|
|
25313
|
+
return {
|
|
25314
|
+
...typeof usage?.input === "number" ? { prompt_tokens: usage.input } : {},
|
|
25315
|
+
...typeof usage?.output === "number" ? { completion_tokens: usage.output } : {},
|
|
25316
|
+
...typeof usage?.cacheRead === "number" ? { prompt_cached_tokens: usage.cacheRead } : {},
|
|
25317
|
+
...typeof usage?.cacheWrite === "number" ? { prompt_cache_creation_tokens: usage.cacheWrite } : {},
|
|
25318
|
+
...typeof usage?.totalTokens === "number" ? { tokens: usage.totalTokens } : {},
|
|
25319
|
+
...typeof usage?.cost?.total === "number" ? { estimated_cost: usage.cost.total } : {}
|
|
25320
|
+
};
|
|
25321
|
+
}
|
|
25322
|
+
function buildDurationMetrics3(startTime) {
|
|
25323
|
+
return {
|
|
25324
|
+
duration_ms: Math.max(0, (getCurrentUnixTimestamp() - startTime) * 1e3)
|
|
25325
|
+
};
|
|
25326
|
+
}
|
|
25327
|
+
function durationMsMetrics(durationMs) {
|
|
25328
|
+
return typeof durationMs === "number" ? { duration_ms: durationMs } : {};
|
|
25329
|
+
}
|
|
25330
|
+
function scopeKey(event) {
|
|
25331
|
+
if (event.operationId) {
|
|
25332
|
+
return `operation:${event.operationId}`;
|
|
25333
|
+
}
|
|
25334
|
+
if (event.taskId) {
|
|
25335
|
+
return `task:${event.taskId}`;
|
|
25336
|
+
}
|
|
25337
|
+
if (event.session) {
|
|
25338
|
+
return `session:${event.session}`;
|
|
25339
|
+
}
|
|
25340
|
+
return "flue:unknown";
|
|
25341
|
+
}
|
|
25342
|
+
function toolKey(event) {
|
|
25343
|
+
return `${scopeKey(event)}::tool:${event.toolCallId ?? "unknown"}`;
|
|
25344
|
+
}
|
|
25345
|
+
function toAssistantOutput(text, finishReason, reasoning, toolCalls) {
|
|
25346
|
+
return [
|
|
25347
|
+
{
|
|
25348
|
+
finish_reason: finishReason ?? "stop",
|
|
25349
|
+
index: 0,
|
|
25350
|
+
message: {
|
|
25351
|
+
content: text,
|
|
25352
|
+
...reasoning ? { reasoning } : {},
|
|
25353
|
+
role: "assistant",
|
|
25354
|
+
...toolCalls?.length ? {
|
|
25355
|
+
tool_calls: toolCalls.map((toolCall) => ({
|
|
25356
|
+
function: {
|
|
25357
|
+
arguments: toolCall.args === void 0 ? "{}" : JSON.stringify(toolCall.args),
|
|
25358
|
+
name: toolCall.toolName ?? "unknown"
|
|
25359
|
+
},
|
|
25360
|
+
...toolCall.toolCallId ? { id: toolCall.toolCallId } : {},
|
|
25361
|
+
type: "function"
|
|
25362
|
+
}))
|
|
25363
|
+
} : {}
|
|
25364
|
+
}
|
|
25365
|
+
}
|
|
25366
|
+
];
|
|
25367
|
+
}
|
|
25368
|
+
function startFlueSpan(parent, args) {
|
|
25369
|
+
return parent ? withCurrent(parent, () => startSpan(args)) : startSpan(args);
|
|
25370
|
+
}
|
|
25371
|
+
function safeLog3(span, event) {
|
|
25372
|
+
try {
|
|
25373
|
+
span.log(event);
|
|
25374
|
+
} catch (error) {
|
|
25375
|
+
logInstrumentationError3("Flue span log", error);
|
|
25376
|
+
}
|
|
25377
|
+
}
|
|
25378
|
+
function errorToString(error) {
|
|
25379
|
+
if (error instanceof Error) {
|
|
25380
|
+
return error.message;
|
|
25381
|
+
}
|
|
25382
|
+
if (typeof error === "string") {
|
|
25383
|
+
return error;
|
|
25384
|
+
}
|
|
25385
|
+
try {
|
|
25386
|
+
return JSON.stringify(error);
|
|
25387
|
+
} catch {
|
|
25388
|
+
return String(error);
|
|
25389
|
+
}
|
|
25390
|
+
}
|
|
25391
|
+
function logInstrumentationError3(label, error) {
|
|
25392
|
+
console.error(`Error in ${label} instrumentation:`, error);
|
|
25393
|
+
}
|
|
25394
|
+
|
|
25395
|
+
// src/wrappers/langchain/callback-handler.ts
|
|
25396
|
+
var BRAINTRUST_LANGCHAIN_CALLBACK_HANDLER_NAME = "BraintrustCallbackHandler";
|
|
25397
|
+
var BraintrustLangChainCallbackHandler = class {
|
|
25398
|
+
name = BRAINTRUST_LANGCHAIN_CALLBACK_HANDLER_NAME;
|
|
25399
|
+
spans = /* @__PURE__ */ new Map();
|
|
25400
|
+
skippedRuns = /* @__PURE__ */ new Set();
|
|
25401
|
+
parent;
|
|
25402
|
+
rootRunId;
|
|
25403
|
+
options;
|
|
25404
|
+
startTimes = /* @__PURE__ */ new Map();
|
|
25405
|
+
firstTokenTimes = /* @__PURE__ */ new Map();
|
|
25406
|
+
ttftMs = /* @__PURE__ */ new Map();
|
|
25407
|
+
constructor(options) {
|
|
25408
|
+
this.parent = options?.parent;
|
|
25409
|
+
this.options = {
|
|
25410
|
+
debug: options?.debug ?? false,
|
|
25411
|
+
excludeMetadataProps: options?.excludeMetadataProps ?? /^(l[sc]_|langgraph_|__pregel_|checkpoint_ns)/,
|
|
25412
|
+
logger: options?.logger
|
|
25413
|
+
};
|
|
25414
|
+
}
|
|
25415
|
+
startSpan({
|
|
25416
|
+
runId,
|
|
25417
|
+
parentRunId,
|
|
25418
|
+
...args
|
|
25419
|
+
}) {
|
|
25420
|
+
if (this.spans.has(runId)) {
|
|
25421
|
+
return;
|
|
25422
|
+
}
|
|
25423
|
+
if (!parentRunId) {
|
|
25424
|
+
this.rootRunId = runId;
|
|
25425
|
+
}
|
|
25426
|
+
const tags = args.event?.tags;
|
|
25427
|
+
const spanAttributes = args.spanAttributes || {};
|
|
25428
|
+
spanAttributes.type = args.type || spanAttributes.type || "task";
|
|
25429
|
+
args.type = spanAttributes.type;
|
|
25430
|
+
const currentParent = (typeof this.parent === "function" ? this.parent() : this.parent) ?? currentSpan();
|
|
25431
|
+
let parentSpan;
|
|
25432
|
+
if (parentRunId && this.spans.has(parentRunId)) {
|
|
25433
|
+
parentSpan = this.spans.get(parentRunId);
|
|
25434
|
+
} else if (!Object.is(currentParent, NOOP_SPAN)) {
|
|
25435
|
+
parentSpan = currentParent;
|
|
25436
|
+
} else if (this.options.logger) {
|
|
25437
|
+
parentSpan = this.options.logger;
|
|
25438
|
+
} else {
|
|
25439
|
+
parentSpan = { startSpan };
|
|
25440
|
+
}
|
|
25441
|
+
args.event = {
|
|
25442
|
+
...args.event,
|
|
25443
|
+
tags: void 0,
|
|
25444
|
+
metadata: {
|
|
25445
|
+
...tags ? { tags } : {},
|
|
25446
|
+
...args.event?.metadata,
|
|
25447
|
+
braintrust: {
|
|
25448
|
+
integration_name: "langchain-js",
|
|
25449
|
+
sdk_language: "javascript"
|
|
25450
|
+
},
|
|
25451
|
+
run_id: runId,
|
|
25452
|
+
parent_run_id: parentRunId,
|
|
25453
|
+
...this.options.debug ? { runId, parentRunId } : {}
|
|
25454
|
+
}
|
|
25455
|
+
};
|
|
25456
|
+
let span = parentSpan.startSpan(args);
|
|
25457
|
+
if (!Object.is(this.options.logger, NOOP_SPAN) && Object.is(span, NOOP_SPAN)) {
|
|
25458
|
+
span = initLogger().startSpan(args);
|
|
25459
|
+
}
|
|
25460
|
+
this.spans.set(runId, span);
|
|
25461
|
+
}
|
|
25462
|
+
endSpan({
|
|
25463
|
+
runId,
|
|
25464
|
+
parentRunId,
|
|
25465
|
+
tags,
|
|
25466
|
+
metadata,
|
|
25467
|
+
...args
|
|
25468
|
+
}) {
|
|
25469
|
+
if (!this.spans.has(runId)) {
|
|
25470
|
+
return;
|
|
25471
|
+
}
|
|
25472
|
+
if (this.skippedRuns.has(runId)) {
|
|
25473
|
+
this.skippedRuns.delete(runId);
|
|
25474
|
+
return;
|
|
25475
|
+
}
|
|
25476
|
+
const span = this.spans.get(runId);
|
|
25477
|
+
this.spans.delete(runId);
|
|
25478
|
+
if (runId === this.rootRunId) {
|
|
25479
|
+
this.rootRunId = void 0;
|
|
25480
|
+
}
|
|
25481
|
+
span.log({ ...args, metadata: { tags, ...metadata } });
|
|
25482
|
+
span.end();
|
|
25483
|
+
}
|
|
25484
|
+
async handleLLMStart(llm, prompts, runId, parentRunId, extraParams, tags, metadata, runName) {
|
|
25485
|
+
this.startSpan({
|
|
25486
|
+
runId,
|
|
25487
|
+
parentRunId,
|
|
25488
|
+
name: runName ?? getSerializedName(llm) ?? "LLM",
|
|
25489
|
+
type: "llm",
|
|
25490
|
+
event: {
|
|
25491
|
+
input: prompts,
|
|
25492
|
+
tags,
|
|
25493
|
+
metadata: {
|
|
25494
|
+
serialized: llm,
|
|
25495
|
+
name: runName,
|
|
25496
|
+
metadata,
|
|
25497
|
+
...extraParams
|
|
25498
|
+
}
|
|
25499
|
+
}
|
|
25500
|
+
});
|
|
25501
|
+
}
|
|
25502
|
+
async handleLLMError(err, runId, parentRunId, tags) {
|
|
25503
|
+
this.endSpan({ runId, parentRunId, error: err, tags });
|
|
25504
|
+
}
|
|
25505
|
+
async handleLLMEnd(output, runId, parentRunId, tags) {
|
|
25506
|
+
const metrics = getMetricsFromResponse(output);
|
|
25507
|
+
const modelName2 = getModelNameFromResponse(output);
|
|
25508
|
+
const ttft = this.ttftMs.get(runId);
|
|
25509
|
+
if (ttft !== void 0) {
|
|
25510
|
+
metrics.time_to_first_token = ttft;
|
|
25511
|
+
}
|
|
25512
|
+
this.startTimes.delete(runId);
|
|
25513
|
+
this.firstTokenTimes.delete(runId);
|
|
25514
|
+
this.ttftMs.delete(runId);
|
|
25515
|
+
this.endSpan({
|
|
25516
|
+
runId,
|
|
25517
|
+
parentRunId,
|
|
25518
|
+
output,
|
|
25519
|
+
metrics,
|
|
25520
|
+
tags,
|
|
25521
|
+
metadata: {
|
|
25522
|
+
model: modelName2
|
|
25523
|
+
}
|
|
25524
|
+
});
|
|
25525
|
+
}
|
|
25526
|
+
async handleChatModelStart(llm, messages, runId, parentRunId, extraParams, tags, metadata, runName) {
|
|
25527
|
+
this.startTimes.set(runId, Date.now());
|
|
25528
|
+
this.firstTokenTimes.delete(runId);
|
|
25529
|
+
this.ttftMs.delete(runId);
|
|
25530
|
+
this.startSpan({
|
|
25531
|
+
runId,
|
|
25532
|
+
parentRunId,
|
|
25533
|
+
name: runName ?? getSerializedName(llm) ?? "Chat Model",
|
|
25534
|
+
type: "llm",
|
|
25535
|
+
event: {
|
|
25536
|
+
input: messages,
|
|
25537
|
+
tags,
|
|
25538
|
+
metadata: {
|
|
25539
|
+
serialized: llm,
|
|
25540
|
+
name: runName,
|
|
25541
|
+
metadata,
|
|
25542
|
+
...extraParams
|
|
25543
|
+
}
|
|
25544
|
+
}
|
|
25545
|
+
});
|
|
25546
|
+
}
|
|
25547
|
+
async handleChainStart(chain, inputs, runId, parentRunId, tags, metadata, runType, runName) {
|
|
25548
|
+
if (tags?.includes("langsmith:hidden")) {
|
|
25549
|
+
this.skippedRuns.add(runId);
|
|
25550
|
+
return;
|
|
25551
|
+
}
|
|
25552
|
+
this.startSpan({
|
|
25553
|
+
runId,
|
|
25554
|
+
parentRunId,
|
|
25555
|
+
name: runName ?? getSerializedName(chain) ?? "Chain",
|
|
25556
|
+
event: {
|
|
25557
|
+
input: inputs,
|
|
25558
|
+
tags,
|
|
25559
|
+
metadata: {
|
|
25560
|
+
serialized: chain,
|
|
25561
|
+
name: runName,
|
|
25562
|
+
metadata,
|
|
25563
|
+
run_type: runType
|
|
25564
|
+
}
|
|
25565
|
+
}
|
|
25566
|
+
});
|
|
25567
|
+
}
|
|
25568
|
+
async handleChainError(err, runId, parentRunId, tags, kwargs) {
|
|
25569
|
+
this.endSpan({ runId, parentRunId, error: err, tags, metadata: kwargs });
|
|
25570
|
+
}
|
|
25571
|
+
async handleChainEnd(outputs, runId, parentRunId, tags, kwargs) {
|
|
25572
|
+
this.endSpan({
|
|
25573
|
+
runId,
|
|
25574
|
+
parentRunId,
|
|
25575
|
+
tags,
|
|
25576
|
+
output: outputs,
|
|
25577
|
+
metadata: { ...kwargs }
|
|
25578
|
+
});
|
|
25579
|
+
}
|
|
25580
|
+
async handleToolStart(tool, input, runId, parentRunId, tags, metadata, runName) {
|
|
25581
|
+
this.startSpan({
|
|
25582
|
+
runId,
|
|
25583
|
+
parentRunId,
|
|
25584
|
+
name: runName ?? getSerializedName(tool) ?? "Tool",
|
|
25585
|
+
type: "llm",
|
|
25586
|
+
event: {
|
|
25587
|
+
input: safeJsonParse(input),
|
|
25588
|
+
tags,
|
|
25589
|
+
metadata: {
|
|
25590
|
+
metadata,
|
|
25591
|
+
serialized: tool,
|
|
25592
|
+
input_str: input,
|
|
25593
|
+
input: safeJsonParse(input),
|
|
25594
|
+
name: runName
|
|
25595
|
+
}
|
|
25596
|
+
}
|
|
25597
|
+
});
|
|
25598
|
+
}
|
|
25599
|
+
async handleToolError(err, runId, parentRunId, tags) {
|
|
25600
|
+
this.endSpan({ runId, parentRunId, error: err, tags });
|
|
25601
|
+
}
|
|
25602
|
+
async handleToolEnd(output, runId, parentRunId, tags) {
|
|
25603
|
+
this.endSpan({ runId, parentRunId, output, tags });
|
|
25604
|
+
}
|
|
25605
|
+
async handleAgentAction(action, runId, parentRunId, tags) {
|
|
25606
|
+
this.startSpan({
|
|
25607
|
+
runId,
|
|
25608
|
+
parentRunId,
|
|
25609
|
+
type: "llm",
|
|
25610
|
+
name: typeof action.tool === "string" ? action.tool : "Agent",
|
|
25611
|
+
event: {
|
|
25612
|
+
input: action,
|
|
25613
|
+
tags
|
|
25614
|
+
}
|
|
25615
|
+
});
|
|
25616
|
+
}
|
|
25617
|
+
async handleAgentEnd(action, runId, parentRunId, tags) {
|
|
25618
|
+
this.endSpan({ runId, parentRunId, output: action, tags });
|
|
25619
|
+
}
|
|
25620
|
+
async handleRetrieverStart(retriever, query, runId, parentRunId, tags, metadata, name) {
|
|
25621
|
+
this.startSpan({
|
|
25622
|
+
runId,
|
|
25623
|
+
parentRunId,
|
|
25624
|
+
name: name ?? getSerializedName(retriever) ?? "Retriever",
|
|
25625
|
+
type: "function",
|
|
25626
|
+
event: {
|
|
25627
|
+
input: query,
|
|
25628
|
+
tags,
|
|
25629
|
+
metadata: {
|
|
25630
|
+
serialized: retriever,
|
|
25631
|
+
metadata,
|
|
25632
|
+
name
|
|
25633
|
+
}
|
|
25634
|
+
}
|
|
25635
|
+
});
|
|
25636
|
+
}
|
|
25637
|
+
async handleRetrieverEnd(documents, runId, parentRunId, tags) {
|
|
25638
|
+
this.endSpan({ runId, parentRunId, output: documents, tags });
|
|
25639
|
+
}
|
|
25640
|
+
async handleRetrieverError(err, runId, parentRunId, tags) {
|
|
25641
|
+
this.endSpan({ runId, parentRunId, error: err, tags });
|
|
25642
|
+
}
|
|
25643
|
+
async handleLLMNewToken(_token, _idx, runId, _parentRunId, _tags) {
|
|
25644
|
+
if (!this.firstTokenTimes.has(runId)) {
|
|
25645
|
+
const now2 = Date.now();
|
|
25646
|
+
this.firstTokenTimes.set(runId, now2);
|
|
25647
|
+
const start = this.startTimes.get(runId);
|
|
25648
|
+
if (start !== void 0) {
|
|
25649
|
+
this.ttftMs.set(runId, (now2 - start) / 1e3);
|
|
25650
|
+
}
|
|
25651
|
+
}
|
|
25652
|
+
}
|
|
25653
|
+
};
|
|
25654
|
+
function getSerializedName(serialized) {
|
|
25655
|
+
if (typeof serialized.name === "string") {
|
|
25656
|
+
return serialized.name;
|
|
25657
|
+
}
|
|
25658
|
+
const lastIdPart = serialized.id?.at(-1);
|
|
25659
|
+
return typeof lastIdPart === "string" ? lastIdPart : void 0;
|
|
25660
|
+
}
|
|
25661
|
+
function cleanObject(obj) {
|
|
25662
|
+
return Object.fromEntries(
|
|
25663
|
+
Object.entries(obj).filter(([, value]) => {
|
|
25664
|
+
if (typeof value !== "number") {
|
|
25665
|
+
return false;
|
|
25666
|
+
}
|
|
25667
|
+
return Number.isFinite(value);
|
|
25668
|
+
})
|
|
25669
|
+
);
|
|
25670
|
+
}
|
|
25671
|
+
function walkGenerations(response) {
|
|
25672
|
+
const result = [];
|
|
25673
|
+
const generations = response.generations || [];
|
|
25674
|
+
for (const batch of generations) {
|
|
25675
|
+
if (Array.isArray(batch)) {
|
|
25676
|
+
for (const generation of batch) {
|
|
25677
|
+
if (isRecord(generation)) {
|
|
25678
|
+
result.push(generation);
|
|
25679
|
+
}
|
|
25680
|
+
}
|
|
25681
|
+
} else if (isRecord(batch)) {
|
|
25682
|
+
result.push(batch);
|
|
25683
|
+
}
|
|
25684
|
+
}
|
|
25685
|
+
return result;
|
|
25686
|
+
}
|
|
25687
|
+
function getModelNameFromResponse(response) {
|
|
25688
|
+
for (const generation of walkGenerations(response)) {
|
|
25689
|
+
const message = generation.message;
|
|
25690
|
+
if (!isRecord(message)) {
|
|
25691
|
+
continue;
|
|
25692
|
+
}
|
|
25693
|
+
const responseMetadata = message.response_metadata;
|
|
25694
|
+
if (!isRecord(responseMetadata)) {
|
|
25695
|
+
continue;
|
|
25696
|
+
}
|
|
25697
|
+
const modelName3 = responseMetadata.model_name ?? responseMetadata.model;
|
|
25698
|
+
if (typeof modelName3 === "string") {
|
|
25699
|
+
return modelName3;
|
|
25700
|
+
}
|
|
25701
|
+
}
|
|
25702
|
+
const llmOutput = response.llmOutput || {};
|
|
25703
|
+
const modelName2 = llmOutput.model_name ?? llmOutput.model;
|
|
25704
|
+
return typeof modelName2 === "string" ? modelName2 : void 0;
|
|
25705
|
+
}
|
|
25706
|
+
function getMetricsFromResponse(response) {
|
|
25707
|
+
for (const generation of walkGenerations(response)) {
|
|
25708
|
+
const message = generation.message;
|
|
25709
|
+
if (!isRecord(message)) {
|
|
25710
|
+
continue;
|
|
25711
|
+
}
|
|
25712
|
+
const usageMetadata = message.usage_metadata;
|
|
25713
|
+
if (!isRecord(usageMetadata)) {
|
|
25714
|
+
continue;
|
|
25715
|
+
}
|
|
25716
|
+
const inputTokenDetails = usageMetadata.input_token_details;
|
|
25717
|
+
return cleanObject({
|
|
25718
|
+
total_tokens: usageMetadata.total_tokens,
|
|
25719
|
+
prompt_tokens: usageMetadata.input_tokens,
|
|
25720
|
+
completion_tokens: usageMetadata.output_tokens,
|
|
25721
|
+
prompt_cache_creation_tokens: isRecord(inputTokenDetails) ? inputTokenDetails.cache_creation : void 0,
|
|
25722
|
+
prompt_cached_tokens: isRecord(inputTokenDetails) ? inputTokenDetails.cache_read : void 0
|
|
25723
|
+
});
|
|
25724
|
+
}
|
|
25725
|
+
const llmOutput = response.llmOutput || {};
|
|
25726
|
+
const tokenUsage = isRecord(llmOutput.tokenUsage) ? llmOutput.tokenUsage : isRecord(llmOutput.estimatedTokens) ? llmOutput.estimatedTokens : {};
|
|
25727
|
+
return cleanObject({
|
|
25728
|
+
total_tokens: tokenUsage.totalTokens,
|
|
25729
|
+
prompt_tokens: tokenUsage.promptTokens,
|
|
25730
|
+
completion_tokens: tokenUsage.completionTokens
|
|
25731
|
+
});
|
|
25732
|
+
}
|
|
25733
|
+
function safeJsonParse(input) {
|
|
25734
|
+
try {
|
|
25735
|
+
return JSON.parse(input);
|
|
25736
|
+
} catch {
|
|
25737
|
+
return input;
|
|
25738
|
+
}
|
|
25739
|
+
}
|
|
25740
|
+
function isRecord(value) {
|
|
25741
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
25742
|
+
}
|
|
25743
|
+
|
|
25744
|
+
// src/instrumentation/plugins/langchain-channels.ts
|
|
25745
|
+
var langChainChannels = defineChannels("@langchain/core", {
|
|
25746
|
+
configure: channel({
|
|
25747
|
+
channelName: "CallbackManager.configure",
|
|
25748
|
+
kind: "sync-stream"
|
|
25749
|
+
}),
|
|
25750
|
+
configureSync: channel({
|
|
25751
|
+
channelName: "CallbackManager._configureSync",
|
|
25752
|
+
kind: "sync-stream"
|
|
25753
|
+
})
|
|
25754
|
+
});
|
|
25755
|
+
|
|
25756
|
+
// src/instrumentation/plugins/langchain-plugin.ts
|
|
25757
|
+
var LangChainPlugin = class extends BasePlugin {
|
|
25758
|
+
injectedManagers = /* @__PURE__ */ new WeakSet();
|
|
25759
|
+
onEnable() {
|
|
25760
|
+
this.subscribeToConfigure(langChainChannels.configure);
|
|
25761
|
+
this.subscribeToConfigure(langChainChannels.configureSync);
|
|
25762
|
+
}
|
|
25763
|
+
onDisable() {
|
|
25764
|
+
for (const unsubscribe of this.unsubscribers) {
|
|
25765
|
+
unsubscribe();
|
|
25766
|
+
}
|
|
25767
|
+
this.unsubscribers = [];
|
|
25768
|
+
this.injectedManagers = /* @__PURE__ */ new WeakSet();
|
|
25769
|
+
}
|
|
25770
|
+
subscribeToConfigure(channel2) {
|
|
25771
|
+
const tracingChannel2 = channel2.tracingChannel();
|
|
25772
|
+
const handlers = {
|
|
25773
|
+
start: (event) => {
|
|
25774
|
+
injectHandlerIntoArguments(event.arguments);
|
|
25775
|
+
},
|
|
25776
|
+
end: (event) => {
|
|
25777
|
+
this.injectHandler(event.result);
|
|
25778
|
+
}
|
|
25779
|
+
};
|
|
25780
|
+
tracingChannel2.subscribe(handlers);
|
|
25781
|
+
this.unsubscribers.push(() => {
|
|
25782
|
+
tracingChannel2.unsubscribe(handlers);
|
|
25783
|
+
});
|
|
25784
|
+
}
|
|
25785
|
+
injectHandler(result) {
|
|
25786
|
+
if (!isCallbackManager(result)) {
|
|
25787
|
+
return;
|
|
25788
|
+
}
|
|
25789
|
+
if (this.injectedManagers.has(result) || hasBraintrustHandler(result)) {
|
|
25790
|
+
return;
|
|
25791
|
+
}
|
|
25792
|
+
try {
|
|
25793
|
+
result.addHandler(new BraintrustLangChainCallbackHandler(), true);
|
|
25794
|
+
this.injectedManagers.add(result);
|
|
25795
|
+
} catch {
|
|
25796
|
+
}
|
|
25797
|
+
}
|
|
25798
|
+
};
|
|
25799
|
+
function isCallbackManager(value) {
|
|
25800
|
+
if (typeof value !== "object" || value === null) {
|
|
25801
|
+
return false;
|
|
25802
|
+
}
|
|
25803
|
+
const maybeManager = value;
|
|
25804
|
+
return typeof maybeManager.addHandler === "function";
|
|
25805
|
+
}
|
|
25806
|
+
function hasBraintrustHandler(manager) {
|
|
25807
|
+
return manager.handlers?.some((handler) => {
|
|
25808
|
+
if (typeof handler !== "object" || handler === null) {
|
|
25809
|
+
return false;
|
|
25810
|
+
}
|
|
25811
|
+
const name = Reflect.get(handler, "name");
|
|
25812
|
+
return name === BRAINTRUST_LANGCHAIN_CALLBACK_HANDLER_NAME;
|
|
25813
|
+
}) ?? false;
|
|
25814
|
+
}
|
|
25815
|
+
function injectHandlerIntoArguments(args) {
|
|
25816
|
+
if (!isWritableArgumentsObject(args)) {
|
|
25817
|
+
return;
|
|
25818
|
+
}
|
|
25819
|
+
const inheritedHandlers = Reflect.get(args, "0");
|
|
25820
|
+
const handler = new BraintrustLangChainCallbackHandler();
|
|
25821
|
+
if (inheritedHandlers === void 0 || inheritedHandlers === null) {
|
|
25822
|
+
Reflect.set(args, "0", [handler]);
|
|
25823
|
+
return;
|
|
25824
|
+
}
|
|
25825
|
+
if (Array.isArray(inheritedHandlers)) {
|
|
25826
|
+
if (!inheritedHandlers.some(isBraintrustHandler)) {
|
|
25827
|
+
inheritedHandlers.push(handler);
|
|
25828
|
+
}
|
|
25829
|
+
}
|
|
25830
|
+
}
|
|
25831
|
+
function isWritableArgumentsObject(args) {
|
|
25832
|
+
return typeof args === "object" && args !== null;
|
|
25833
|
+
}
|
|
25834
|
+
function isBraintrustHandler(handler) {
|
|
25835
|
+
if (typeof handler !== "object" || handler === null) {
|
|
25836
|
+
return false;
|
|
25837
|
+
}
|
|
25838
|
+
return Reflect.get(handler, "name") === BRAINTRUST_LANGCHAIN_CALLBACK_HANDLER_NAME;
|
|
25839
|
+
}
|
|
25840
|
+
|
|
25841
|
+
// src/instrumentation/braintrust-plugin.ts
|
|
25842
|
+
function getIntegrationConfig(integrations, key) {
|
|
25843
|
+
return integrations[key];
|
|
25844
|
+
}
|
|
25845
|
+
var BraintrustPlugin = class extends BasePlugin {
|
|
25846
|
+
config;
|
|
25847
|
+
openaiPlugin = null;
|
|
25848
|
+
openAICodexPlugin = null;
|
|
25849
|
+
anthropicPlugin = null;
|
|
25850
|
+
aiSDKPlugin = null;
|
|
25851
|
+
claudeAgentSDKPlugin = null;
|
|
25852
|
+
cursorSDKPlugin = null;
|
|
25853
|
+
openAIAgentsPlugin = null;
|
|
25854
|
+
googleGenAIPlugin = null;
|
|
25855
|
+
huggingFacePlugin = null;
|
|
25856
|
+
openRouterPlugin = null;
|
|
25857
|
+
openRouterAgentPlugin = null;
|
|
25858
|
+
mistralPlugin = null;
|
|
25859
|
+
googleADKPlugin = null;
|
|
25860
|
+
coherePlugin = null;
|
|
25861
|
+
groqPlugin = null;
|
|
25862
|
+
genkitPlugin = null;
|
|
25863
|
+
gitHubCopilotPlugin = null;
|
|
25864
|
+
fluePlugin = null;
|
|
25865
|
+
langChainPlugin = null;
|
|
25866
|
+
constructor(config = {}) {
|
|
25867
|
+
super();
|
|
25868
|
+
this.config = config;
|
|
25869
|
+
}
|
|
25870
|
+
onEnable() {
|
|
25871
|
+
const integrations = this.config.integrations || {};
|
|
25872
|
+
if (integrations.openai !== false) {
|
|
25873
|
+
this.openaiPlugin = new OpenAIPlugin();
|
|
25874
|
+
this.openaiPlugin.enable();
|
|
25875
|
+
}
|
|
25876
|
+
if (integrations.openaiCodexSDK !== false) {
|
|
25877
|
+
this.openAICodexPlugin = new OpenAICodexPlugin();
|
|
25878
|
+
this.openAICodexPlugin.enable();
|
|
23688
25879
|
}
|
|
23689
25880
|
if (integrations.anthropic !== false) {
|
|
23690
25881
|
this.anthropicPlugin = new AnthropicPlugin();
|
|
@@ -23702,6 +25893,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
23702
25893
|
this.cursorSDKPlugin = new CursorSDKPlugin();
|
|
23703
25894
|
this.cursorSDKPlugin.enable();
|
|
23704
25895
|
}
|
|
25896
|
+
if (integrations.openAIAgents !== false) {
|
|
25897
|
+
this.openAIAgentsPlugin = new OpenAIAgentsPlugin();
|
|
25898
|
+
this.openAIAgentsPlugin.enable();
|
|
25899
|
+
}
|
|
23705
25900
|
if (integrations.googleGenAI !== false && integrations.google !== false) {
|
|
23706
25901
|
this.googleGenAIPlugin = new GoogleGenAIPlugin();
|
|
23707
25902
|
this.googleGenAIPlugin.enable();
|
|
@@ -23742,6 +25937,14 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
23742
25937
|
this.gitHubCopilotPlugin = new GitHubCopilotPlugin();
|
|
23743
25938
|
this.gitHubCopilotPlugin.enable();
|
|
23744
25939
|
}
|
|
25940
|
+
if (getIntegrationConfig(integrations, "flue") !== false) {
|
|
25941
|
+
this.fluePlugin = new FluePlugin();
|
|
25942
|
+
this.fluePlugin.enable();
|
|
25943
|
+
}
|
|
25944
|
+
if (integrations.langchain !== false && integrations.langgraph !== false) {
|
|
25945
|
+
this.langChainPlugin = new LangChainPlugin();
|
|
25946
|
+
this.langChainPlugin.enable();
|
|
25947
|
+
}
|
|
23745
25948
|
}
|
|
23746
25949
|
onDisable() {
|
|
23747
25950
|
if (this.openaiPlugin) {
|
|
@@ -23768,6 +25971,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
23768
25971
|
this.cursorSDKPlugin.disable();
|
|
23769
25972
|
this.cursorSDKPlugin = null;
|
|
23770
25973
|
}
|
|
25974
|
+
if (this.openAIAgentsPlugin) {
|
|
25975
|
+
this.openAIAgentsPlugin.disable();
|
|
25976
|
+
this.openAIAgentsPlugin = null;
|
|
25977
|
+
}
|
|
23771
25978
|
if (this.googleGenAIPlugin) {
|
|
23772
25979
|
this.googleGenAIPlugin.disable();
|
|
23773
25980
|
this.googleGenAIPlugin = null;
|
|
@@ -23808,9 +26015,104 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
23808
26015
|
this.gitHubCopilotPlugin.disable();
|
|
23809
26016
|
this.gitHubCopilotPlugin = null;
|
|
23810
26017
|
}
|
|
26018
|
+
if (this.fluePlugin) {
|
|
26019
|
+
this.fluePlugin.disable();
|
|
26020
|
+
this.fluePlugin = null;
|
|
26021
|
+
}
|
|
26022
|
+
if (this.langChainPlugin) {
|
|
26023
|
+
this.langChainPlugin.disable();
|
|
26024
|
+
this.langChainPlugin = null;
|
|
26025
|
+
}
|
|
23811
26026
|
}
|
|
23812
26027
|
};
|
|
23813
26028
|
|
|
26029
|
+
// src/instrumentation/config.ts
|
|
26030
|
+
var envIntegrationAliases = {
|
|
26031
|
+
openai: "openai",
|
|
26032
|
+
"openai-codex": "openaiCodexSDK",
|
|
26033
|
+
"openai-codex-sdk": "openaiCodexSDK",
|
|
26034
|
+
openaicodexsdk: "openaiCodexSDK",
|
|
26035
|
+
codex: "openaiCodexSDK",
|
|
26036
|
+
"codex-sdk": "openaiCodexSDK",
|
|
26037
|
+
anthropic: "anthropic",
|
|
26038
|
+
aisdk: "aisdk",
|
|
26039
|
+
"ai-sdk": "aisdk",
|
|
26040
|
+
"vercel-ai": "aisdk",
|
|
26041
|
+
vercel: "vercel",
|
|
26042
|
+
claudeagentsdk: "claudeAgentSDK",
|
|
26043
|
+
"claude-agent-sdk": "claudeAgentSDK",
|
|
26044
|
+
cursor: "cursor",
|
|
26045
|
+
"cursor-sdk": "cursorSDK",
|
|
26046
|
+
cursorsdk: "cursorSDK",
|
|
26047
|
+
flue: "flue",
|
|
26048
|
+
"flue-runtime": "flue",
|
|
26049
|
+
"openai-agents": "openAIAgents",
|
|
26050
|
+
openaiagents: "openAIAgents",
|
|
26051
|
+
"openai-agents-core": "openAIAgents",
|
|
26052
|
+
openaiagentscore: "openAIAgents",
|
|
26053
|
+
google: "google",
|
|
26054
|
+
"google-genai": "googleGenAI",
|
|
26055
|
+
googlegenai: "googleGenAI",
|
|
26056
|
+
huggingface: "huggingface",
|
|
26057
|
+
openrouter: "openrouter",
|
|
26058
|
+
openrouteragent: "openrouterAgent",
|
|
26059
|
+
"openrouter-agent": "openrouterAgent",
|
|
26060
|
+
mistral: "mistral",
|
|
26061
|
+
googleadk: "googleADK",
|
|
26062
|
+
"google-adk": "googleADK",
|
|
26063
|
+
cohere: "cohere",
|
|
26064
|
+
groq: "groq",
|
|
26065
|
+
"groq-sdk": "groq",
|
|
26066
|
+
genkit: "genkit",
|
|
26067
|
+
"firebase-genkit": "genkit",
|
|
26068
|
+
githubcopilot: "gitHubCopilot",
|
|
26069
|
+
"github-copilot": "gitHubCopilot",
|
|
26070
|
+
"copilot-sdk": "gitHubCopilot",
|
|
26071
|
+
langchain: "langchain",
|
|
26072
|
+
"langchain-js": "langchain",
|
|
26073
|
+
"@langchain": "langchain",
|
|
26074
|
+
langgraph: "langgraph"
|
|
26075
|
+
};
|
|
26076
|
+
function getDefaultInstrumentationIntegrations() {
|
|
26077
|
+
return {
|
|
26078
|
+
openai: true,
|
|
26079
|
+
openaiCodexSDK: true,
|
|
26080
|
+
anthropic: true,
|
|
26081
|
+
vercel: true,
|
|
26082
|
+
aisdk: true,
|
|
26083
|
+
google: true,
|
|
26084
|
+
googleGenAI: true,
|
|
26085
|
+
googleADK: true,
|
|
26086
|
+
huggingface: true,
|
|
26087
|
+
claudeAgentSDK: true,
|
|
26088
|
+
cursor: true,
|
|
26089
|
+
cursorSDK: true,
|
|
26090
|
+
flue: true,
|
|
26091
|
+
openAIAgents: true,
|
|
26092
|
+
openrouter: true,
|
|
26093
|
+
openrouterAgent: true,
|
|
26094
|
+
mistral: true,
|
|
26095
|
+
cohere: true,
|
|
26096
|
+
groq: true,
|
|
26097
|
+
genkit: true,
|
|
26098
|
+
gitHubCopilot: true,
|
|
26099
|
+
langchain: true,
|
|
26100
|
+
langgraph: true
|
|
26101
|
+
};
|
|
26102
|
+
}
|
|
26103
|
+
function readDisabledInstrumentationEnvConfig(disabledList) {
|
|
26104
|
+
const integrations = {};
|
|
26105
|
+
if (disabledList) {
|
|
26106
|
+
for (const value of disabledList.split(",")) {
|
|
26107
|
+
const sdk = value.trim().toLowerCase();
|
|
26108
|
+
if (sdk.length > 0) {
|
|
26109
|
+
integrations[envIntegrationAliases[sdk] ?? sdk] = false;
|
|
26110
|
+
}
|
|
26111
|
+
}
|
|
26112
|
+
}
|
|
26113
|
+
return { integrations };
|
|
26114
|
+
}
|
|
26115
|
+
|
|
23814
26116
|
// src/instrumentation/registry.ts
|
|
23815
26117
|
var REGISTRY_STATE_KEY = /* @__PURE__ */ Symbol.for("braintrust.registry");
|
|
23816
26118
|
function getSharedState() {
|
|
@@ -23889,50 +26191,16 @@ var PluginRegistry = class {
|
|
|
23889
26191
|
* Get default configuration (all integrations enabled).
|
|
23890
26192
|
*/
|
|
23891
26193
|
getDefaultConfig() {
|
|
23892
|
-
return
|
|
23893
|
-
openai: true,
|
|
23894
|
-
openaiCodexSDK: true,
|
|
23895
|
-
anthropic: true,
|
|
23896
|
-
vercel: true,
|
|
23897
|
-
aisdk: true,
|
|
23898
|
-
google: true,
|
|
23899
|
-
googleGenAI: true,
|
|
23900
|
-
googleADK: true,
|
|
23901
|
-
huggingface: true,
|
|
23902
|
-
claudeAgentSDK: true,
|
|
23903
|
-
cursor: true,
|
|
23904
|
-
cursorSDK: true,
|
|
23905
|
-
openrouter: true,
|
|
23906
|
-
openrouterAgent: true,
|
|
23907
|
-
mistral: true,
|
|
23908
|
-
cohere: true,
|
|
23909
|
-
groq: true,
|
|
23910
|
-
genkit: true,
|
|
23911
|
-
gitHubCopilot: true
|
|
23912
|
-
};
|
|
26194
|
+
return getDefaultInstrumentationIntegrations();
|
|
23913
26195
|
}
|
|
23914
26196
|
/**
|
|
23915
26197
|
* Read configuration from environment variables.
|
|
23916
26198
|
* Supports: BRAINTRUST_DISABLE_INSTRUMENTATION=openai,anthropic,...
|
|
23917
26199
|
*/
|
|
23918
26200
|
readEnvConfig() {
|
|
23919
|
-
|
|
23920
|
-
|
|
23921
|
-
|
|
23922
|
-
const disabled = disabledList.split(",").map((s) => s.trim().toLowerCase()).filter((s) => s.length > 0);
|
|
23923
|
-
for (const sdk of disabled) {
|
|
23924
|
-
if (sdk === "cursor-sdk") {
|
|
23925
|
-
integrations.cursorSDK = false;
|
|
23926
|
-
} else if (sdk === "githubcopilot" || sdk === "github-copilot" || sdk === "copilot-sdk") {
|
|
23927
|
-
integrations.gitHubCopilot = false;
|
|
23928
|
-
} else if (sdk === "openai-codex-sdk") {
|
|
23929
|
-
integrations.openaiCodexSDK = false;
|
|
23930
|
-
} else {
|
|
23931
|
-
integrations[sdk] = false;
|
|
23932
|
-
}
|
|
23933
|
-
}
|
|
23934
|
-
}
|
|
23935
|
-
return { integrations };
|
|
26201
|
+
return readDisabledInstrumentationEnvConfig(
|
|
26202
|
+
isomorph_default.getEnv("BRAINTRUST_DISABLE_INSTRUMENTATION")
|
|
26203
|
+
);
|
|
23936
26204
|
}
|
|
23937
26205
|
};
|
|
23938
26206
|
var registry = new PluginRegistry();
|
|
@@ -23983,8 +26251,10 @@ __export(exports_exports, {
|
|
|
23983
26251
|
Attachment: () => Attachment,
|
|
23984
26252
|
AttachmentReference: () => AttachmentReference,
|
|
23985
26253
|
BRAINTRUST_CURRENT_SPAN_STORE: () => BRAINTRUST_CURRENT_SPAN_STORE,
|
|
26254
|
+
BRAINTRUST_LANGCHAIN_CALLBACK_HANDLER_NAME: () => BRAINTRUST_LANGCHAIN_CALLBACK_HANDLER_NAME,
|
|
23986
26255
|
BaseAttachment: () => BaseAttachment,
|
|
23987
26256
|
BaseExperiment: () => BaseExperiment,
|
|
26257
|
+
BraintrustLangChainCallbackHandler: () => BraintrustLangChainCallbackHandler,
|
|
23988
26258
|
BraintrustMiddleware: () => BraintrustMiddleware,
|
|
23989
26259
|
BraintrustState: () => BraintrustState,
|
|
23990
26260
|
BraintrustStream: () => BraintrustStream,
|
|
@@ -24110,6 +26380,8 @@ __export(exports_exports, {
|
|
|
24110
26380
|
wrapCohere: () => wrapCohere,
|
|
24111
26381
|
wrapCopilotClient: () => wrapCopilotClient,
|
|
24112
26382
|
wrapCursorSDK: () => wrapCursorSDK,
|
|
26383
|
+
wrapFlueContext: () => wrapFlueContext,
|
|
26384
|
+
wrapFlueSession: () => wrapFlueSession,
|
|
24113
26385
|
wrapGenkit: () => wrapGenkit,
|
|
24114
26386
|
wrapGoogleADK: () => wrapGoogleADK,
|
|
24115
26387
|
wrapGoogleGenAI: () => wrapGoogleGenAI,
|
|
@@ -25209,7 +27481,7 @@ function extractModelParameters(params, excludeKeys) {
|
|
|
25209
27481
|
}
|
|
25210
27482
|
return modelParams;
|
|
25211
27483
|
}
|
|
25212
|
-
function
|
|
27484
|
+
function getNumberProperty3(obj, key) {
|
|
25213
27485
|
if (!obj || typeof obj !== "object" || !(key in obj)) {
|
|
25214
27486
|
return void 0;
|
|
25215
27487
|
}
|
|
@@ -25218,31 +27490,31 @@ function getNumberProperty2(obj, key) {
|
|
|
25218
27490
|
}
|
|
25219
27491
|
function normalizeUsageMetrics(usage, provider, providerMetadata) {
|
|
25220
27492
|
const metrics = {};
|
|
25221
|
-
const inputTokens =
|
|
27493
|
+
const inputTokens = getNumberProperty3(usage, "inputTokens");
|
|
25222
27494
|
if (inputTokens !== void 0) {
|
|
25223
27495
|
metrics.prompt_tokens = inputTokens;
|
|
25224
27496
|
}
|
|
25225
|
-
const outputTokens =
|
|
27497
|
+
const outputTokens = getNumberProperty3(usage, "outputTokens");
|
|
25226
27498
|
if (outputTokens !== void 0) {
|
|
25227
27499
|
metrics.completion_tokens = outputTokens;
|
|
25228
27500
|
}
|
|
25229
|
-
const totalTokens =
|
|
27501
|
+
const totalTokens = getNumberProperty3(usage, "totalTokens");
|
|
25230
27502
|
if (totalTokens !== void 0) {
|
|
25231
27503
|
metrics.tokens = totalTokens;
|
|
25232
27504
|
}
|
|
25233
|
-
const reasoningTokens =
|
|
27505
|
+
const reasoningTokens = getNumberProperty3(usage, "reasoningTokens");
|
|
25234
27506
|
if (reasoningTokens !== void 0) {
|
|
25235
27507
|
metrics.completion_reasoning_tokens = reasoningTokens;
|
|
25236
27508
|
}
|
|
25237
|
-
const cachedInputTokens =
|
|
27509
|
+
const cachedInputTokens = getNumberProperty3(usage, "cachedInputTokens");
|
|
25238
27510
|
if (cachedInputTokens !== void 0) {
|
|
25239
27511
|
metrics.prompt_cached_tokens = cachedInputTokens;
|
|
25240
27512
|
}
|
|
25241
27513
|
if (provider === "anthropic") {
|
|
25242
27514
|
const anthropicMetadata = providerMetadata?.anthropic;
|
|
25243
27515
|
if (anthropicMetadata) {
|
|
25244
|
-
const cacheReadTokens =
|
|
25245
|
-
const cacheCreationTokens =
|
|
27516
|
+
const cacheReadTokens = getNumberProperty3(anthropicMetadata.usage, "cache_read_input_tokens") || 0;
|
|
27517
|
+
const cacheCreationTokens = getNumberProperty3(
|
|
25246
27518
|
anthropicMetadata.usage,
|
|
25247
27519
|
"cache_creation_input_tokens"
|
|
25248
27520
|
) || 0;
|
|
@@ -26217,17 +28489,17 @@ function wrapGenkit(genkit) {
|
|
|
26217
28489
|
console.warn("Unsupported Genkit object. Not wrapping.");
|
|
26218
28490
|
return genkit;
|
|
26219
28491
|
}
|
|
26220
|
-
function
|
|
28492
|
+
function isRecord2(value) {
|
|
26221
28493
|
return typeof value === "object" && value !== null;
|
|
26222
28494
|
}
|
|
26223
28495
|
function isPropertyBag(value) {
|
|
26224
|
-
return
|
|
28496
|
+
return isRecord2(value) || typeof value === "function";
|
|
26225
28497
|
}
|
|
26226
28498
|
function hasFunction(value, methodName) {
|
|
26227
28499
|
return isPropertyBag(value) && methodName in value && typeof value[methodName] === "function";
|
|
26228
28500
|
}
|
|
26229
28501
|
function isGenkitInstance(value) {
|
|
26230
|
-
return
|
|
28502
|
+
return isRecord2(value) && (hasFunction(value, "generate") || hasFunction(value, "generateStream") || hasFunction(value, "defineFlow") || hasFunction(value, "defineTool"));
|
|
26231
28503
|
}
|
|
26232
28504
|
function isGenkitModule(value) {
|
|
26233
28505
|
return hasFunction(value, "genkit");
|
|
@@ -26281,7 +28553,7 @@ function patchGenkitRegistry(instance) {
|
|
|
26281
28553
|
patchGenkitRegistryConstructor(registry2);
|
|
26282
28554
|
}
|
|
26283
28555
|
function patchGenkitRegistryLookup(registry2) {
|
|
26284
|
-
if (!
|
|
28556
|
+
if (!isRecord2(registry2) || hasRegistryPatchedFlag(registry2) || !hasFunction(registry2, "lookupAction")) {
|
|
26285
28557
|
return;
|
|
26286
28558
|
}
|
|
26287
28559
|
const originalLookupAction = registry2.lookupAction;
|
|
@@ -26307,7 +28579,7 @@ function patchGenkitRegistryLookup(registry2) {
|
|
|
26307
28579
|
}
|
|
26308
28580
|
}
|
|
26309
28581
|
function patchGenkitRegistryConstructor(registry2) {
|
|
26310
|
-
if (!
|
|
28582
|
+
if (!isRecord2(registry2)) {
|
|
26311
28583
|
return;
|
|
26312
28584
|
}
|
|
26313
28585
|
const constructor = registry2.constructor;
|
|
@@ -26323,7 +28595,7 @@ function patchGenkitRegistryConstructor(registry2) {
|
|
|
26323
28595
|
configurable: true,
|
|
26324
28596
|
value: (...args) => {
|
|
26325
28597
|
const childRegistry = originalWithParent.apply(constructor, args);
|
|
26326
|
-
if (args.some((arg) =>
|
|
28598
|
+
if (args.some((arg) => isRecord2(arg) && hasRegistryPatchedFlag(arg))) {
|
|
26327
28599
|
patchGenkitRegistryLookup(childRegistry);
|
|
26328
28600
|
patchGenkitRegistryConstructor(childRegistry);
|
|
26329
28601
|
}
|
|
@@ -26422,7 +28694,7 @@ function hasRegistryConstructorPatchedFlag(value) {
|
|
|
26422
28694
|
);
|
|
26423
28695
|
}
|
|
26424
28696
|
function isPromiseLike2(value) {
|
|
26425
|
-
return
|
|
28697
|
+
return isRecord2(value) && "then" in value && typeof value.then === "function";
|
|
26426
28698
|
}
|
|
26427
28699
|
|
|
26428
28700
|
// src/wrappers/huggingface.ts
|
|
@@ -26785,14 +29057,14 @@ function wrapMistral(mistral) {
|
|
|
26785
29057
|
console.warn("Unsupported Mistral library. Not wrapping.");
|
|
26786
29058
|
return mistral;
|
|
26787
29059
|
}
|
|
26788
|
-
function
|
|
29060
|
+
function isRecord3(value) {
|
|
26789
29061
|
return typeof value === "object" && value !== null;
|
|
26790
29062
|
}
|
|
26791
29063
|
function hasFunction3(value, methodName) {
|
|
26792
|
-
return
|
|
29064
|
+
return isRecord3(value) && methodName in value && typeof value[methodName] === "function";
|
|
26793
29065
|
}
|
|
26794
29066
|
function isSupportedMistralClient(value) {
|
|
26795
|
-
if (!
|
|
29067
|
+
if (!isRecord3(value)) {
|
|
26796
29068
|
return false;
|
|
26797
29069
|
}
|
|
26798
29070
|
return value.chat !== void 0 && hasChat(value.chat) || value.embeddings !== void 0 && hasEmbeddings(value.embeddings) || value.fim !== void 0 && hasFim(value.fim) || value.agents !== void 0 && hasAgents(value.agents) || value.classifiers !== void 0 && hasClassifiers(value.classifiers);
|
|
@@ -26976,14 +29248,14 @@ function wrapCohere(cohere) {
|
|
|
26976
29248
|
return cohere;
|
|
26977
29249
|
}
|
|
26978
29250
|
var cohereProxyCache = /* @__PURE__ */ new WeakMap();
|
|
26979
|
-
function
|
|
29251
|
+
function isRecord4(value) {
|
|
26980
29252
|
return typeof value === "object" && value !== null;
|
|
26981
29253
|
}
|
|
26982
29254
|
function hasFunction4(value, methodName) {
|
|
26983
|
-
return
|
|
29255
|
+
return isRecord4(value) && methodName in value && typeof value[methodName] === "function";
|
|
26984
29256
|
}
|
|
26985
29257
|
function isSupportedCohereClient(value) {
|
|
26986
|
-
if (!
|
|
29258
|
+
if (!isRecord4(value)) {
|
|
26987
29259
|
return false;
|
|
26988
29260
|
}
|
|
26989
29261
|
return hasFunction4(value, "chat") || hasFunction4(value, "chatStream") || hasFunction4(value, "embed") || hasFunction4(value, "rerank");
|
|
@@ -27043,20 +29315,20 @@ function wrapGroq(groq) {
|
|
|
27043
29315
|
console.warn("Unsupported Groq library. Not wrapping.");
|
|
27044
29316
|
return groq;
|
|
27045
29317
|
}
|
|
27046
|
-
function
|
|
29318
|
+
function isRecord5(value) {
|
|
27047
29319
|
return typeof value === "object" && value !== null;
|
|
27048
29320
|
}
|
|
27049
29321
|
function hasFunction5(value, methodName) {
|
|
27050
|
-
return
|
|
29322
|
+
return isRecord5(value) && methodName in value && typeof value[methodName] === "function";
|
|
27051
29323
|
}
|
|
27052
29324
|
function hasChat2(value) {
|
|
27053
|
-
return
|
|
29325
|
+
return isRecord5(value) && isRecord5(value.completions) && hasFunction5(value.completions, "create");
|
|
27054
29326
|
}
|
|
27055
29327
|
function hasEmbeddings2(value) {
|
|
27056
29328
|
return hasFunction5(value, "create");
|
|
27057
29329
|
}
|
|
27058
29330
|
function isSupportedGroqClient(value) {
|
|
27059
|
-
return
|
|
29331
|
+
return isRecord5(value) && (value.chat !== void 0 && hasChat2(value.chat) || value.embeddings !== void 0 && hasEmbeddings2(value.embeddings));
|
|
27060
29332
|
}
|
|
27061
29333
|
function groqProxy(groq) {
|
|
27062
29334
|
const privateMethodWorkaroundCache = /* @__PURE__ */ new WeakMap();
|