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/browser.js
CHANGED
|
@@ -33,8 +33,10 @@ __export(browser_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(browser_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,
|
|
@@ -1098,6 +1102,11 @@ function isPromiseLike(value) {
|
|
|
1098
1102
|
|
|
1099
1103
|
// util/object_util.ts
|
|
1100
1104
|
var SET_UNION_FIELDS = /* @__PURE__ */ new Set(["tags"]);
|
|
1105
|
+
var FORBIDDEN_MERGE_KEYS = /* @__PURE__ */ new Set([
|
|
1106
|
+
"__proto__",
|
|
1107
|
+
"constructor",
|
|
1108
|
+
"prototype"
|
|
1109
|
+
]);
|
|
1101
1110
|
function mergeDictsWithPaths({
|
|
1102
1111
|
mergeInto,
|
|
1103
1112
|
mergeFrom,
|
|
@@ -1120,6 +1129,7 @@ function mergeDictsWithPathsHelper({
|
|
|
1120
1129
|
mergePaths
|
|
1121
1130
|
}) {
|
|
1122
1131
|
Object.entries(mergeFrom).forEach(([k, mergeFromV]) => {
|
|
1132
|
+
if (FORBIDDEN_MERGE_KEYS.has(k)) return;
|
|
1123
1133
|
const fullPath = path.concat([k]);
|
|
1124
1134
|
const fullPathSerialized = JSON.stringify(fullPath);
|
|
1125
1135
|
const mergeIntoV = recordFind(mergeInto, k);
|
|
@@ -5191,6 +5201,13 @@ var HTTPConnection = class _HTTPConnection {
|
|
|
5191
5201
|
debugLogger.debug(
|
|
5192
5202
|
`Retrying API request ${object_type} ${JSON.stringify(args)} ${e.status} ${e.text}`
|
|
5193
5203
|
);
|
|
5204
|
+
const sleepTimeS = HTTP_RETRY_BASE_SLEEP_TIME_S * 2 ** i;
|
|
5205
|
+
debugLogger.info(
|
|
5206
|
+
`Sleeping for ${sleepTimeS}s before retrying API request`
|
|
5207
|
+
);
|
|
5208
|
+
await new Promise(
|
|
5209
|
+
(resolve) => setTimeout(resolve, sleepTimeS * 1e3)
|
|
5210
|
+
);
|
|
5194
5211
|
continue;
|
|
5195
5212
|
}
|
|
5196
5213
|
throw e;
|
|
@@ -5840,20 +5857,7 @@ function startSpanParentArgs(args) {
|
|
|
5840
5857
|
`Mismatch between expected span parent object type ${args.parentObjectType} and provided type ${parentComponents.data.object_type}`
|
|
5841
5858
|
);
|
|
5842
5859
|
}
|
|
5843
|
-
|
|
5844
|
-
args.state,
|
|
5845
|
-
parentComponents
|
|
5846
|
-
);
|
|
5847
|
-
const computeParentObjectId = async () => {
|
|
5848
|
-
const parentComponentsObjectId = await parentComponentsObjectIdLambda();
|
|
5849
|
-
if (await args.parentObjectId.get() !== parentComponentsObjectId) {
|
|
5850
|
-
throw new Error(
|
|
5851
|
-
`Mismatch between expected span parent object id ${await args.parentObjectId.get()} and provided id ${parentComponentsObjectId}`
|
|
5852
|
-
);
|
|
5853
|
-
}
|
|
5854
|
-
return await args.parentObjectId.get();
|
|
5855
|
-
};
|
|
5856
|
-
argParentObjectId = new LazyValue(computeParentObjectId);
|
|
5860
|
+
argParentObjectId = args.parentObjectId;
|
|
5857
5861
|
if (parentComponents.data.row_id) {
|
|
5858
5862
|
argParentSpanIds = {
|
|
5859
5863
|
spanId: parentComponents.data.span_id,
|
|
@@ -6239,6 +6243,7 @@ var TestBackgroundLogger = class {
|
|
|
6239
6243
|
}
|
|
6240
6244
|
};
|
|
6241
6245
|
var BACKGROUND_LOGGER_BASE_SLEEP_TIME_S = 1;
|
|
6246
|
+
var HTTP_RETRY_BASE_SLEEP_TIME_S = 1;
|
|
6242
6247
|
var HTTPBackgroundLogger = class _HTTPBackgroundLogger {
|
|
6243
6248
|
apiConn;
|
|
6244
6249
|
queue;
|
|
@@ -6869,17 +6874,10 @@ function init(projectOrOptions, optionalOptions) {
|
|
|
6869
6874
|
if (repoInfo) {
|
|
6870
6875
|
return repoInfo;
|
|
6871
6876
|
}
|
|
6872
|
-
|
|
6873
|
-
|
|
6874
|
-
|
|
6875
|
-
|
|
6876
|
-
};
|
|
6877
|
-
if (gitMetadataSettings) {
|
|
6878
|
-
mergedGitMetadataSettings = mergeGitMetadataSettings(
|
|
6879
|
-
mergedGitMetadataSettings,
|
|
6880
|
-
gitMetadataSettings
|
|
6881
|
-
);
|
|
6882
|
-
}
|
|
6877
|
+
const mergedGitMetadataSettings = state.gitMetadataSettings == null ? gitMetadataSettings ?? { collect: "none" } : mergeGitMetadataSettings(
|
|
6878
|
+
state.gitMetadataSettings,
|
|
6879
|
+
gitMetadataSettings ?? { collect: "all" }
|
|
6880
|
+
);
|
|
6883
6881
|
return await isomorph_default.getRepoInfo(mergedGitMetadataSettings);
|
|
6884
6882
|
})();
|
|
6885
6883
|
if (repoInfoArg) {
|
|
@@ -13575,11 +13573,11 @@ function resolveDenyOutputPaths(event, defaultDenyOutputPaths) {
|
|
|
13575
13573
|
if (Array.isArray(event?.denyOutputPaths)) {
|
|
13576
13574
|
return event.denyOutputPaths;
|
|
13577
13575
|
}
|
|
13578
|
-
const
|
|
13579
|
-
if (!
|
|
13576
|
+
const firstArgument2 = event?.arguments && event.arguments.length > 0 ? event.arguments[0] : void 0;
|
|
13577
|
+
if (!firstArgument2 || typeof firstArgument2 !== "object") {
|
|
13580
13578
|
return defaultDenyOutputPaths;
|
|
13581
13579
|
}
|
|
13582
|
-
const runtimeDenyOutputPaths =
|
|
13580
|
+
const runtimeDenyOutputPaths = firstArgument2[RUNTIME_DENY_OUTPUT_PATHS];
|
|
13583
13581
|
if (Array.isArray(runtimeDenyOutputPaths) && runtimeDenyOutputPaths.every((path) => typeof path === "string")) {
|
|
13584
13582
|
return runtimeDenyOutputPaths;
|
|
13585
13583
|
}
|
|
@@ -17238,6 +17236,467 @@ function cleanMetrics2(metrics) {
|
|
|
17238
17236
|
return cleaned;
|
|
17239
17237
|
}
|
|
17240
17238
|
|
|
17239
|
+
// src/instrumentation/plugins/openai-agents-channels.ts
|
|
17240
|
+
var openAIAgentsCoreChannels = defineChannels("@openai/agents-core", {
|
|
17241
|
+
onTraceStart: channel({
|
|
17242
|
+
channelName: "tracing.processor.onTraceStart",
|
|
17243
|
+
kind: "async"
|
|
17244
|
+
}),
|
|
17245
|
+
onTraceEnd: channel({
|
|
17246
|
+
channelName: "tracing.processor.onTraceEnd",
|
|
17247
|
+
kind: "async"
|
|
17248
|
+
}),
|
|
17249
|
+
onSpanStart: channel({
|
|
17250
|
+
channelName: "tracing.processor.onSpanStart",
|
|
17251
|
+
kind: "async"
|
|
17252
|
+
}),
|
|
17253
|
+
onSpanEnd: channel({
|
|
17254
|
+
channelName: "tracing.processor.onSpanEnd",
|
|
17255
|
+
kind: "async"
|
|
17256
|
+
})
|
|
17257
|
+
});
|
|
17258
|
+
|
|
17259
|
+
// src/instrumentation/plugins/openai-agents-trace-processor.ts
|
|
17260
|
+
function isSpanData(spanData, type) {
|
|
17261
|
+
return spanData.type === type;
|
|
17262
|
+
}
|
|
17263
|
+
function spanTypeFromAgents(span) {
|
|
17264
|
+
const spanType = span.spanData.type;
|
|
17265
|
+
if (spanType === "function" || spanType === "guardrail" || spanType === "mcp_tools") {
|
|
17266
|
+
return "tool" /* TOOL */;
|
|
17267
|
+
}
|
|
17268
|
+
if (spanType === "generation" || spanType === "response" || spanType === "transcription" || spanType === "speech") {
|
|
17269
|
+
return "llm" /* LLM */;
|
|
17270
|
+
}
|
|
17271
|
+
return "task" /* TASK */;
|
|
17272
|
+
}
|
|
17273
|
+
function spanNameFromAgents(span) {
|
|
17274
|
+
const spanData = span.spanData;
|
|
17275
|
+
if ("name" in spanData && spanData.name) {
|
|
17276
|
+
return spanData.name;
|
|
17277
|
+
}
|
|
17278
|
+
switch (spanData.type) {
|
|
17279
|
+
case "generation":
|
|
17280
|
+
return "Generation";
|
|
17281
|
+
case "response":
|
|
17282
|
+
return "Response";
|
|
17283
|
+
case "handoff":
|
|
17284
|
+
return "Handoff";
|
|
17285
|
+
case "mcp_tools":
|
|
17286
|
+
return isSpanData(spanData, "mcp_tools") && spanData.server ? `List Tools (${spanData.server})` : "MCP List Tools";
|
|
17287
|
+
case "transcription":
|
|
17288
|
+
return "Transcription";
|
|
17289
|
+
case "speech":
|
|
17290
|
+
return "Speech";
|
|
17291
|
+
case "speech_group":
|
|
17292
|
+
return "Speech Group";
|
|
17293
|
+
default:
|
|
17294
|
+
return "Unknown";
|
|
17295
|
+
}
|
|
17296
|
+
}
|
|
17297
|
+
function getTimeElapsed(end, start) {
|
|
17298
|
+
if (!start || !end) {
|
|
17299
|
+
return void 0;
|
|
17300
|
+
}
|
|
17301
|
+
const startTime = new Date(start).getTime();
|
|
17302
|
+
const endTime = new Date(end).getTime();
|
|
17303
|
+
if (Number.isNaN(startTime) || Number.isNaN(endTime)) {
|
|
17304
|
+
return void 0;
|
|
17305
|
+
}
|
|
17306
|
+
return (endTime - startTime) / 1e3;
|
|
17307
|
+
}
|
|
17308
|
+
function getNumberProperty2(obj, key) {
|
|
17309
|
+
if (!isObject(obj) || !(key in obj)) {
|
|
17310
|
+
return void 0;
|
|
17311
|
+
}
|
|
17312
|
+
const value = obj[key];
|
|
17313
|
+
return typeof value === "number" ? value : void 0;
|
|
17314
|
+
}
|
|
17315
|
+
function parseUsageMetrics(usage) {
|
|
17316
|
+
const metrics = {};
|
|
17317
|
+
if (!isObject(usage)) {
|
|
17318
|
+
return metrics;
|
|
17319
|
+
}
|
|
17320
|
+
const promptTokens = getNumberProperty2(usage, "prompt_tokens") ?? getNumberProperty2(usage, "input_tokens") ?? getNumberProperty2(usage, "promptTokens") ?? getNumberProperty2(usage, "inputTokens");
|
|
17321
|
+
const completionTokens = getNumberProperty2(usage, "completion_tokens") ?? getNumberProperty2(usage, "output_tokens") ?? getNumberProperty2(usage, "completionTokens") ?? getNumberProperty2(usage, "outputTokens");
|
|
17322
|
+
const totalTokens = getNumberProperty2(usage, "total_tokens") ?? getNumberProperty2(usage, "totalTokens");
|
|
17323
|
+
if (promptTokens !== void 0) {
|
|
17324
|
+
metrics.prompt_tokens = promptTokens;
|
|
17325
|
+
}
|
|
17326
|
+
if (completionTokens !== void 0) {
|
|
17327
|
+
metrics.completion_tokens = completionTokens;
|
|
17328
|
+
}
|
|
17329
|
+
if (totalTokens !== void 0) {
|
|
17330
|
+
metrics.tokens = totalTokens;
|
|
17331
|
+
} else if (promptTokens !== void 0 && completionTokens !== void 0) {
|
|
17332
|
+
metrics.tokens = promptTokens + completionTokens;
|
|
17333
|
+
}
|
|
17334
|
+
const inputDetails = usage.input_tokens_details;
|
|
17335
|
+
const cachedTokens = getNumberProperty2(inputDetails, "cached_tokens");
|
|
17336
|
+
const cacheWriteTokens = getNumberProperty2(
|
|
17337
|
+
inputDetails,
|
|
17338
|
+
"cache_write_tokens"
|
|
17339
|
+
);
|
|
17340
|
+
if (cachedTokens !== void 0) {
|
|
17341
|
+
metrics.prompt_cached_tokens = cachedTokens;
|
|
17342
|
+
}
|
|
17343
|
+
if (cacheWriteTokens !== void 0) {
|
|
17344
|
+
metrics.prompt_cache_creation_tokens = cacheWriteTokens;
|
|
17345
|
+
}
|
|
17346
|
+
return metrics;
|
|
17347
|
+
}
|
|
17348
|
+
var OpenAIAgentsTraceProcessor = class _OpenAIAgentsTraceProcessor {
|
|
17349
|
+
static DEFAULT_MAX_TRACES = 1e4;
|
|
17350
|
+
logger;
|
|
17351
|
+
maxTraces;
|
|
17352
|
+
traceSpans = /* @__PURE__ */ new Map();
|
|
17353
|
+
traceOrder = [];
|
|
17354
|
+
_traceSpans = this.traceSpans;
|
|
17355
|
+
constructor(options = {}) {
|
|
17356
|
+
this.logger = options.logger;
|
|
17357
|
+
this.maxTraces = options.maxTraces ?? _OpenAIAgentsTraceProcessor.DEFAULT_MAX_TRACES;
|
|
17358
|
+
}
|
|
17359
|
+
evictOldestTrace() {
|
|
17360
|
+
const oldestTraceId = this.traceOrder.shift();
|
|
17361
|
+
if (oldestTraceId) {
|
|
17362
|
+
this.traceSpans.delete(oldestTraceId);
|
|
17363
|
+
}
|
|
17364
|
+
}
|
|
17365
|
+
onTraceStart(trace) {
|
|
17366
|
+
if (!trace?.traceId) {
|
|
17367
|
+
return Promise.resolve();
|
|
17368
|
+
}
|
|
17369
|
+
if (this.traceOrder.length >= this.maxTraces) {
|
|
17370
|
+
this.evictOldestTrace();
|
|
17371
|
+
}
|
|
17372
|
+
const current = currentSpan();
|
|
17373
|
+
const span = current && current !== NOOP_SPAN ? current.startSpan({
|
|
17374
|
+
name: trace.name,
|
|
17375
|
+
type: "task" /* TASK */
|
|
17376
|
+
}) : this.logger ? this.logger.startSpan({
|
|
17377
|
+
name: trace.name,
|
|
17378
|
+
type: "task" /* TASK */
|
|
17379
|
+
}) : startSpan({
|
|
17380
|
+
name: trace.name,
|
|
17381
|
+
type: "task" /* TASK */
|
|
17382
|
+
});
|
|
17383
|
+
span.log({
|
|
17384
|
+
input: "Agent workflow started",
|
|
17385
|
+
metadata: {
|
|
17386
|
+
group_id: trace.groupId,
|
|
17387
|
+
...trace.metadata || {}
|
|
17388
|
+
}
|
|
17389
|
+
});
|
|
17390
|
+
this.traceSpans.set(trace.traceId, {
|
|
17391
|
+
rootSpan: span,
|
|
17392
|
+
childSpans: /* @__PURE__ */ new Map(),
|
|
17393
|
+
metadata: {
|
|
17394
|
+
firstInput: null,
|
|
17395
|
+
lastOutput: null
|
|
17396
|
+
}
|
|
17397
|
+
});
|
|
17398
|
+
this.traceOrder.push(trace.traceId);
|
|
17399
|
+
return Promise.resolve();
|
|
17400
|
+
}
|
|
17401
|
+
async onTraceEnd(trace) {
|
|
17402
|
+
const traceData = this.traceSpans.get(trace?.traceId);
|
|
17403
|
+
if (!traceData) {
|
|
17404
|
+
return;
|
|
17405
|
+
}
|
|
17406
|
+
try {
|
|
17407
|
+
traceData.rootSpan.log({
|
|
17408
|
+
input: traceData.metadata.firstInput,
|
|
17409
|
+
output: traceData.metadata.lastOutput
|
|
17410
|
+
});
|
|
17411
|
+
traceData.rootSpan.end();
|
|
17412
|
+
await traceData.rootSpan.flush();
|
|
17413
|
+
} finally {
|
|
17414
|
+
this.traceSpans.delete(trace.traceId);
|
|
17415
|
+
const orderIndex = this.traceOrder.indexOf(trace.traceId);
|
|
17416
|
+
if (orderIndex > -1) {
|
|
17417
|
+
this.traceOrder.splice(orderIndex, 1);
|
|
17418
|
+
}
|
|
17419
|
+
}
|
|
17420
|
+
}
|
|
17421
|
+
onSpanStart(span) {
|
|
17422
|
+
if (!span?.spanId || !span.traceId) {
|
|
17423
|
+
return Promise.resolve();
|
|
17424
|
+
}
|
|
17425
|
+
const traceData = this.traceSpans.get(span.traceId);
|
|
17426
|
+
if (!traceData) {
|
|
17427
|
+
return Promise.resolve();
|
|
17428
|
+
}
|
|
17429
|
+
const parentSpan = span.parentId ? traceData.childSpans.get(span.parentId) : traceData.rootSpan;
|
|
17430
|
+
if (!parentSpan) {
|
|
17431
|
+
return Promise.resolve();
|
|
17432
|
+
}
|
|
17433
|
+
const childSpan = parentSpan.startSpan({
|
|
17434
|
+
name: spanNameFromAgents(span),
|
|
17435
|
+
type: spanTypeFromAgents(span)
|
|
17436
|
+
});
|
|
17437
|
+
traceData.childSpans.set(span.spanId, childSpan);
|
|
17438
|
+
return Promise.resolve();
|
|
17439
|
+
}
|
|
17440
|
+
onSpanEnd(span) {
|
|
17441
|
+
if (!span?.spanId || !span.traceId) {
|
|
17442
|
+
return Promise.resolve();
|
|
17443
|
+
}
|
|
17444
|
+
const traceData = this.traceSpans.get(span.traceId);
|
|
17445
|
+
if (!traceData) {
|
|
17446
|
+
return Promise.resolve();
|
|
17447
|
+
}
|
|
17448
|
+
const braintrustSpan = traceData.childSpans.get(span.spanId);
|
|
17449
|
+
if (!braintrustSpan) {
|
|
17450
|
+
return Promise.resolve();
|
|
17451
|
+
}
|
|
17452
|
+
const logData = this.extractLogData(span);
|
|
17453
|
+
braintrustSpan.log({
|
|
17454
|
+
error: span.error,
|
|
17455
|
+
...logData
|
|
17456
|
+
});
|
|
17457
|
+
braintrustSpan.end();
|
|
17458
|
+
traceData.childSpans.delete(span.spanId);
|
|
17459
|
+
const input = logData.input;
|
|
17460
|
+
const output = logData.output;
|
|
17461
|
+
if (traceData.metadata.firstInput === null && input != null) {
|
|
17462
|
+
traceData.metadata.firstInput = input;
|
|
17463
|
+
}
|
|
17464
|
+
if (output != null) {
|
|
17465
|
+
traceData.metadata.lastOutput = output;
|
|
17466
|
+
}
|
|
17467
|
+
return Promise.resolve();
|
|
17468
|
+
}
|
|
17469
|
+
async shutdown() {
|
|
17470
|
+
if (this.logger && typeof this.logger.flush === "function") {
|
|
17471
|
+
await this.logger.flush();
|
|
17472
|
+
}
|
|
17473
|
+
}
|
|
17474
|
+
async forceFlush() {
|
|
17475
|
+
if (this.logger && typeof this.logger.flush === "function") {
|
|
17476
|
+
await this.logger.flush();
|
|
17477
|
+
}
|
|
17478
|
+
}
|
|
17479
|
+
extractLogData(span) {
|
|
17480
|
+
const spanData = span.spanData;
|
|
17481
|
+
switch (spanData.type) {
|
|
17482
|
+
case "agent":
|
|
17483
|
+
return this.extractAgentLogData(spanData);
|
|
17484
|
+
case "response":
|
|
17485
|
+
return this.extractResponseLogData(spanData, span);
|
|
17486
|
+
case "function":
|
|
17487
|
+
return this.extractFunctionLogData(spanData);
|
|
17488
|
+
case "handoff":
|
|
17489
|
+
return this.extractHandoffLogData(spanData);
|
|
17490
|
+
case "guardrail":
|
|
17491
|
+
return this.extractGuardrailLogData(spanData);
|
|
17492
|
+
case "generation":
|
|
17493
|
+
return this.extractGenerationLogData(spanData, span);
|
|
17494
|
+
case "custom":
|
|
17495
|
+
return this.extractCustomLogData(spanData);
|
|
17496
|
+
case "mcp_tools":
|
|
17497
|
+
return this.extractMCPListToolsLogData(spanData);
|
|
17498
|
+
case "transcription":
|
|
17499
|
+
return this.extractTranscriptionLogData(spanData);
|
|
17500
|
+
case "speech":
|
|
17501
|
+
return this.extractSpeechLogData(spanData);
|
|
17502
|
+
case "speech_group":
|
|
17503
|
+
return this.extractSpeechGroupLogData(spanData);
|
|
17504
|
+
default:
|
|
17505
|
+
return {};
|
|
17506
|
+
}
|
|
17507
|
+
}
|
|
17508
|
+
extractAgentLogData(spanData) {
|
|
17509
|
+
return {
|
|
17510
|
+
metadata: {
|
|
17511
|
+
tools: spanData.tools,
|
|
17512
|
+
handoffs: spanData.handoffs,
|
|
17513
|
+
output_type: spanData.output_type
|
|
17514
|
+
}
|
|
17515
|
+
};
|
|
17516
|
+
}
|
|
17517
|
+
extractResponseLogData(spanData, span) {
|
|
17518
|
+
const response = spanData._response;
|
|
17519
|
+
const output = isObject(response) ? response.output : void 0;
|
|
17520
|
+
const usage = isObject(response) ? response.usage : void 0;
|
|
17521
|
+
const metrics = {
|
|
17522
|
+
...this.extractTimingMetrics(span),
|
|
17523
|
+
...parseUsageMetrics(usage)
|
|
17524
|
+
};
|
|
17525
|
+
return {
|
|
17526
|
+
input: spanData._input,
|
|
17527
|
+
output,
|
|
17528
|
+
metadata: isObject(response) ? this.omitKeys(response, ["output", "usage"]) : {},
|
|
17529
|
+
metrics
|
|
17530
|
+
};
|
|
17531
|
+
}
|
|
17532
|
+
extractFunctionLogData(spanData) {
|
|
17533
|
+
return {
|
|
17534
|
+
input: spanData.input,
|
|
17535
|
+
output: spanData.output
|
|
17536
|
+
};
|
|
17537
|
+
}
|
|
17538
|
+
extractHandoffLogData(spanData) {
|
|
17539
|
+
return {
|
|
17540
|
+
metadata: {
|
|
17541
|
+
from_agent: spanData.from_agent,
|
|
17542
|
+
to_agent: spanData.to_agent
|
|
17543
|
+
}
|
|
17544
|
+
};
|
|
17545
|
+
}
|
|
17546
|
+
extractGuardrailLogData(spanData) {
|
|
17547
|
+
return {
|
|
17548
|
+
metadata: {
|
|
17549
|
+
triggered: spanData.triggered
|
|
17550
|
+
}
|
|
17551
|
+
};
|
|
17552
|
+
}
|
|
17553
|
+
extractGenerationLogData(spanData, span) {
|
|
17554
|
+
return {
|
|
17555
|
+
input: spanData.input,
|
|
17556
|
+
output: spanData.output,
|
|
17557
|
+
metadata: {
|
|
17558
|
+
model: spanData.model,
|
|
17559
|
+
model_config: spanData.model_config
|
|
17560
|
+
},
|
|
17561
|
+
metrics: {
|
|
17562
|
+
...this.extractTimingMetrics(span),
|
|
17563
|
+
...parseUsageMetrics(spanData.usage)
|
|
17564
|
+
}
|
|
17565
|
+
};
|
|
17566
|
+
}
|
|
17567
|
+
extractCustomLogData(spanData) {
|
|
17568
|
+
return spanData.data || {};
|
|
17569
|
+
}
|
|
17570
|
+
extractMCPListToolsLogData(spanData) {
|
|
17571
|
+
return {
|
|
17572
|
+
output: spanData.result,
|
|
17573
|
+
metadata: {
|
|
17574
|
+
server: spanData.server
|
|
17575
|
+
}
|
|
17576
|
+
};
|
|
17577
|
+
}
|
|
17578
|
+
extractTranscriptionLogData(spanData) {
|
|
17579
|
+
return {
|
|
17580
|
+
input: spanData.input,
|
|
17581
|
+
output: spanData.output,
|
|
17582
|
+
metadata: {
|
|
17583
|
+
model: spanData.model,
|
|
17584
|
+
model_config: spanData.model_config
|
|
17585
|
+
}
|
|
17586
|
+
};
|
|
17587
|
+
}
|
|
17588
|
+
extractSpeechLogData(spanData) {
|
|
17589
|
+
return {
|
|
17590
|
+
input: spanData.input,
|
|
17591
|
+
output: spanData.output,
|
|
17592
|
+
metadata: {
|
|
17593
|
+
model: spanData.model,
|
|
17594
|
+
model_config: spanData.model_config
|
|
17595
|
+
}
|
|
17596
|
+
};
|
|
17597
|
+
}
|
|
17598
|
+
extractSpeechGroupLogData(spanData) {
|
|
17599
|
+
return {
|
|
17600
|
+
input: spanData.input
|
|
17601
|
+
};
|
|
17602
|
+
}
|
|
17603
|
+
extractTimingMetrics(span) {
|
|
17604
|
+
const timeToFirstToken = getTimeElapsed(
|
|
17605
|
+
span.endedAt ?? void 0,
|
|
17606
|
+
span.startedAt ?? void 0
|
|
17607
|
+
);
|
|
17608
|
+
return timeToFirstToken === void 0 ? {} : { time_to_first_token: timeToFirstToken };
|
|
17609
|
+
}
|
|
17610
|
+
omitKeys(value, keys) {
|
|
17611
|
+
const result = {};
|
|
17612
|
+
for (const [key, fieldValue] of Object.entries(value)) {
|
|
17613
|
+
if (!keys.includes(key)) {
|
|
17614
|
+
result[key] = fieldValue;
|
|
17615
|
+
}
|
|
17616
|
+
}
|
|
17617
|
+
return result;
|
|
17618
|
+
}
|
|
17619
|
+
};
|
|
17620
|
+
|
|
17621
|
+
// src/instrumentation/plugins/openai-agents-plugin.ts
|
|
17622
|
+
function firstArgument(args) {
|
|
17623
|
+
if (Array.isArray(args)) {
|
|
17624
|
+
return args[0];
|
|
17625
|
+
}
|
|
17626
|
+
if (isObject(args) && "length" in args && typeof args.length === "number" && Number.isInteger(args.length) && args.length >= 0) {
|
|
17627
|
+
return Array.from(args)[0];
|
|
17628
|
+
}
|
|
17629
|
+
return void 0;
|
|
17630
|
+
}
|
|
17631
|
+
function isOpenAIAgentsTrace(value) {
|
|
17632
|
+
return isObject(value) && value.type === "trace" && typeof value.traceId === "string";
|
|
17633
|
+
}
|
|
17634
|
+
function isOpenAIAgentsSpan(value) {
|
|
17635
|
+
return isObject(value) && value.type === "trace.span" && typeof value.traceId === "string" && typeof value.spanId === "string";
|
|
17636
|
+
}
|
|
17637
|
+
var OpenAIAgentsPlugin = class extends BasePlugin {
|
|
17638
|
+
processor = new OpenAIAgentsTraceProcessor();
|
|
17639
|
+
onEnable() {
|
|
17640
|
+
this.subscribeToTraceLifecycle();
|
|
17641
|
+
}
|
|
17642
|
+
onDisable() {
|
|
17643
|
+
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
17644
|
+
void this.processor.shutdown();
|
|
17645
|
+
}
|
|
17646
|
+
subscribeToTraceLifecycle() {
|
|
17647
|
+
const traceStartChannel = openAIAgentsCoreChannels.onTraceStart.tracingChannel();
|
|
17648
|
+
const traceStartHandlers = {
|
|
17649
|
+
start: (event) => {
|
|
17650
|
+
const trace = firstArgument(event.arguments);
|
|
17651
|
+
if (isOpenAIAgentsTrace(trace)) {
|
|
17652
|
+
void this.processor.onTraceStart(trace);
|
|
17653
|
+
}
|
|
17654
|
+
}
|
|
17655
|
+
};
|
|
17656
|
+
traceStartChannel.subscribe(traceStartHandlers);
|
|
17657
|
+
this.unsubscribers.push(
|
|
17658
|
+
() => traceStartChannel.unsubscribe(traceStartHandlers)
|
|
17659
|
+
);
|
|
17660
|
+
const traceEndChannel = openAIAgentsCoreChannels.onTraceEnd.tracingChannel();
|
|
17661
|
+
const traceEndHandlers = {
|
|
17662
|
+
start: (event) => {
|
|
17663
|
+
const trace = firstArgument(event.arguments);
|
|
17664
|
+
if (isOpenAIAgentsTrace(trace)) {
|
|
17665
|
+
void this.processor.onTraceEnd(trace);
|
|
17666
|
+
}
|
|
17667
|
+
}
|
|
17668
|
+
};
|
|
17669
|
+
traceEndChannel.subscribe(traceEndHandlers);
|
|
17670
|
+
this.unsubscribers.push(
|
|
17671
|
+
() => traceEndChannel.unsubscribe(traceEndHandlers)
|
|
17672
|
+
);
|
|
17673
|
+
const spanStartChannel = openAIAgentsCoreChannels.onSpanStart.tracingChannel();
|
|
17674
|
+
const spanStartHandlers = {
|
|
17675
|
+
start: (event) => {
|
|
17676
|
+
const span = firstArgument(event.arguments);
|
|
17677
|
+
if (isOpenAIAgentsSpan(span)) {
|
|
17678
|
+
void this.processor.onSpanStart(span);
|
|
17679
|
+
}
|
|
17680
|
+
}
|
|
17681
|
+
};
|
|
17682
|
+
spanStartChannel.subscribe(spanStartHandlers);
|
|
17683
|
+
this.unsubscribers.push(
|
|
17684
|
+
() => spanStartChannel.unsubscribe(spanStartHandlers)
|
|
17685
|
+
);
|
|
17686
|
+
const spanEndChannel = openAIAgentsCoreChannels.onSpanEnd.tracingChannel();
|
|
17687
|
+
const spanEndHandlers = {
|
|
17688
|
+
start: (event) => {
|
|
17689
|
+
const span = firstArgument(event.arguments);
|
|
17690
|
+
if (isOpenAIAgentsSpan(span)) {
|
|
17691
|
+
void this.processor.onSpanEnd(span);
|
|
17692
|
+
}
|
|
17693
|
+
}
|
|
17694
|
+
};
|
|
17695
|
+
spanEndChannel.subscribe(spanEndHandlers);
|
|
17696
|
+
this.unsubscribers.push(() => spanEndChannel.unsubscribe(spanEndHandlers));
|
|
17697
|
+
}
|
|
17698
|
+
};
|
|
17699
|
+
|
|
17241
17700
|
// src/instrumentation/plugins/google-genai-channels.ts
|
|
17242
17701
|
var googleGenAIChannels = defineChannels("@google/genai", {
|
|
17243
17702
|
generateContent: channel({
|
|
@@ -23530,41 +23989,1773 @@ var GitHubCopilotPlugin = class extends BasePlugin {
|
|
|
23530
23989
|
}
|
|
23531
23990
|
};
|
|
23532
23991
|
|
|
23533
|
-
// src/instrumentation/
|
|
23534
|
-
|
|
23535
|
-
|
|
23992
|
+
// src/instrumentation/plugins/flue-channels.ts
|
|
23993
|
+
var flueChannels = defineChannels("@flue/runtime", {
|
|
23994
|
+
createContext: channel({
|
|
23995
|
+
channelName: "createFlueContext",
|
|
23996
|
+
kind: "sync-stream"
|
|
23997
|
+
}),
|
|
23998
|
+
openSession: channel({
|
|
23999
|
+
channelName: "Harness.openSession",
|
|
24000
|
+
kind: "async"
|
|
24001
|
+
}),
|
|
24002
|
+
contextEvent: channel({
|
|
24003
|
+
channelName: "context.event",
|
|
24004
|
+
kind: "sync-stream"
|
|
24005
|
+
}),
|
|
24006
|
+
prompt: channel({
|
|
24007
|
+
channelName: "session.prompt",
|
|
24008
|
+
kind: "async"
|
|
24009
|
+
}),
|
|
24010
|
+
skill: channel({
|
|
24011
|
+
channelName: "session.skill",
|
|
24012
|
+
kind: "async"
|
|
24013
|
+
}),
|
|
24014
|
+
task: channel({
|
|
24015
|
+
channelName: "session.task",
|
|
24016
|
+
kind: "async"
|
|
24017
|
+
}),
|
|
24018
|
+
compact: channel({
|
|
24019
|
+
channelName: "session.compact",
|
|
24020
|
+
kind: "async"
|
|
24021
|
+
})
|
|
24022
|
+
});
|
|
24023
|
+
|
|
24024
|
+
// src/wrappers/flue.ts
|
|
24025
|
+
var WRAPPED_FLUE_CONTEXT = /* @__PURE__ */ Symbol.for("braintrust.flue.wrapped-context");
|
|
24026
|
+
var WRAPPED_FLUE_HARNESS = /* @__PURE__ */ Symbol.for("braintrust.flue.wrapped-harness");
|
|
24027
|
+
var WRAPPED_FLUE_SESSION = /* @__PURE__ */ Symbol.for("braintrust.flue.wrapped-session");
|
|
24028
|
+
var SUBSCRIBED_FLUE_CONTEXT_EVENTS = /* @__PURE__ */ Symbol.for(
|
|
24029
|
+
"braintrust.flue.subscribed-context-events"
|
|
24030
|
+
);
|
|
24031
|
+
function wrapFlueContext(ctx) {
|
|
24032
|
+
if (!isPlausibleFlueContext(ctx)) {
|
|
24033
|
+
console.warn("Unsupported Flue context. Not wrapping.");
|
|
24034
|
+
return ctx;
|
|
24035
|
+
}
|
|
24036
|
+
const context = ctx;
|
|
24037
|
+
subscribeFlueContextEvents(context, { captureTurnSpans: true });
|
|
24038
|
+
return patchFlueContextInPlace(context);
|
|
23536
24039
|
}
|
|
23537
|
-
|
|
23538
|
-
|
|
23539
|
-
|
|
23540
|
-
|
|
23541
|
-
anthropicPlugin = null;
|
|
23542
|
-
aiSDKPlugin = null;
|
|
23543
|
-
claudeAgentSDKPlugin = null;
|
|
23544
|
-
cursorSDKPlugin = null;
|
|
23545
|
-
googleGenAIPlugin = null;
|
|
23546
|
-
huggingFacePlugin = null;
|
|
23547
|
-
openRouterPlugin = null;
|
|
23548
|
-
openRouterAgentPlugin = null;
|
|
23549
|
-
mistralPlugin = null;
|
|
23550
|
-
googleADKPlugin = null;
|
|
23551
|
-
coherePlugin = null;
|
|
23552
|
-
groqPlugin = null;
|
|
23553
|
-
genkitPlugin = null;
|
|
23554
|
-
gitHubCopilotPlugin = null;
|
|
23555
|
-
constructor(config = {}) {
|
|
23556
|
-
super();
|
|
23557
|
-
this.config = config;
|
|
24040
|
+
function patchFlueContextInPlace(ctx) {
|
|
24041
|
+
const context = ctx;
|
|
24042
|
+
if (context[WRAPPED_FLUE_CONTEXT]) {
|
|
24043
|
+
return ctx;
|
|
23558
24044
|
}
|
|
23559
|
-
|
|
23560
|
-
|
|
23561
|
-
|
|
23562
|
-
|
|
23563
|
-
|
|
24045
|
+
const originalInit = context.init.bind(context);
|
|
24046
|
+
try {
|
|
24047
|
+
Object.defineProperty(context, WRAPPED_FLUE_CONTEXT, {
|
|
24048
|
+
configurable: false,
|
|
24049
|
+
enumerable: false,
|
|
24050
|
+
value: true
|
|
24051
|
+
});
|
|
24052
|
+
Object.defineProperty(context, "init", {
|
|
24053
|
+
configurable: true,
|
|
24054
|
+
value: async function wrappedFlueInit(options) {
|
|
24055
|
+
const harness = await originalInit(options);
|
|
24056
|
+
return wrapFlueHarness(harness);
|
|
24057
|
+
},
|
|
24058
|
+
writable: true
|
|
24059
|
+
});
|
|
24060
|
+
} catch {
|
|
24061
|
+
}
|
|
24062
|
+
return ctx;
|
|
24063
|
+
}
|
|
24064
|
+
function wrapFlueSession(session) {
|
|
24065
|
+
if (!isPlausibleFlueSession(session)) {
|
|
24066
|
+
console.warn("Unsupported Flue session. Not wrapping.");
|
|
24067
|
+
return session;
|
|
24068
|
+
}
|
|
24069
|
+
return patchFlueSessionInPlace(session);
|
|
24070
|
+
}
|
|
24071
|
+
function subscribeFlueContextEvents(ctx, options = {}) {
|
|
24072
|
+
if (!ctx || typeof ctx !== "object" || typeof ctx.subscribeEvent !== "function") {
|
|
24073
|
+
return void 0;
|
|
24074
|
+
}
|
|
24075
|
+
const context = ctx;
|
|
24076
|
+
const captureTurnSpans = options.captureTurnSpans ?? true;
|
|
24077
|
+
const existingSubscription = context[SUBSCRIBED_FLUE_CONTEXT_EVENTS];
|
|
24078
|
+
if (existingSubscription) {
|
|
24079
|
+
if (existingSubscription.captureTurnSpans || !captureTurnSpans) {
|
|
24080
|
+
return void 0;
|
|
23564
24081
|
}
|
|
23565
|
-
|
|
23566
|
-
|
|
23567
|
-
|
|
24082
|
+
try {
|
|
24083
|
+
existingSubscription.unsubscribe();
|
|
24084
|
+
} catch {
|
|
24085
|
+
}
|
|
24086
|
+
}
|
|
24087
|
+
try {
|
|
24088
|
+
const unsubscribe = ctx.subscribeEvent((event) => {
|
|
24089
|
+
flueChannels.contextEvent.traceSync(() => void 0, {
|
|
24090
|
+
arguments: [event],
|
|
24091
|
+
captureTurnSpans,
|
|
24092
|
+
context: ctx
|
|
24093
|
+
});
|
|
24094
|
+
});
|
|
24095
|
+
if (existingSubscription) {
|
|
24096
|
+
existingSubscription.captureTurnSpans = captureTurnSpans;
|
|
24097
|
+
existingSubscription.unsubscribe = unsubscribe;
|
|
24098
|
+
} else {
|
|
24099
|
+
Object.defineProperty(context, SUBSCRIBED_FLUE_CONTEXT_EVENTS, {
|
|
24100
|
+
configurable: false,
|
|
24101
|
+
enumerable: false,
|
|
24102
|
+
value: {
|
|
24103
|
+
captureTurnSpans,
|
|
24104
|
+
unsubscribe
|
|
24105
|
+
}
|
|
24106
|
+
});
|
|
24107
|
+
}
|
|
24108
|
+
return unsubscribe;
|
|
24109
|
+
} catch {
|
|
24110
|
+
return void 0;
|
|
24111
|
+
}
|
|
24112
|
+
}
|
|
24113
|
+
function wrapFlueHarness(harness) {
|
|
24114
|
+
if (!isPlausibleFlueHarness(harness)) {
|
|
24115
|
+
return harness;
|
|
24116
|
+
}
|
|
24117
|
+
const target = harness;
|
|
24118
|
+
if (target[WRAPPED_FLUE_HARNESS]) {
|
|
24119
|
+
return harness;
|
|
24120
|
+
}
|
|
24121
|
+
const originalSession = target.session.bind(target);
|
|
24122
|
+
try {
|
|
24123
|
+
Object.defineProperty(target, WRAPPED_FLUE_HARNESS, {
|
|
24124
|
+
configurable: false,
|
|
24125
|
+
enumerable: false,
|
|
24126
|
+
value: true
|
|
24127
|
+
});
|
|
24128
|
+
Object.defineProperty(target, "session", {
|
|
24129
|
+
configurable: true,
|
|
24130
|
+
value: async function wrappedFlueHarnessSession(name, options) {
|
|
24131
|
+
const session = await originalSession(name, options);
|
|
24132
|
+
return patchFlueSessionInPlace(session);
|
|
24133
|
+
},
|
|
24134
|
+
writable: true
|
|
24135
|
+
});
|
|
24136
|
+
const sessions = target.sessions;
|
|
24137
|
+
if (sessions && typeof sessions === "object") {
|
|
24138
|
+
patchFlueSessionFactory(sessions, "get");
|
|
24139
|
+
patchFlueSessionFactory(sessions, "create");
|
|
24140
|
+
}
|
|
24141
|
+
} catch {
|
|
24142
|
+
}
|
|
24143
|
+
return harness;
|
|
24144
|
+
}
|
|
24145
|
+
function patchFlueSessionInPlace(session) {
|
|
24146
|
+
if (session[WRAPPED_FLUE_SESSION]) {
|
|
24147
|
+
return session;
|
|
24148
|
+
}
|
|
24149
|
+
try {
|
|
24150
|
+
Object.defineProperty(session, WRAPPED_FLUE_SESSION, {
|
|
24151
|
+
configurable: false,
|
|
24152
|
+
enumerable: false,
|
|
24153
|
+
value: true
|
|
24154
|
+
});
|
|
24155
|
+
patchCallHandleMethod(session, "prompt", flueChannels.prompt);
|
|
24156
|
+
patchCallHandleMethod(session, "skill", flueChannels.skill);
|
|
24157
|
+
patchCallHandleMethod(session, "task", flueChannels.task);
|
|
24158
|
+
patchCompact(session);
|
|
24159
|
+
} catch {
|
|
24160
|
+
}
|
|
24161
|
+
return session;
|
|
24162
|
+
}
|
|
24163
|
+
function patchFlueSessionFactory(sessions, method) {
|
|
24164
|
+
const original = sessions[method];
|
|
24165
|
+
if (typeof original !== "function") {
|
|
24166
|
+
return;
|
|
24167
|
+
}
|
|
24168
|
+
const bound = original.bind(sessions);
|
|
24169
|
+
Object.defineProperty(sessions, method, {
|
|
24170
|
+
configurable: true,
|
|
24171
|
+
value: async function wrappedFlueSessionFactory(name, options) {
|
|
24172
|
+
const session = await bound(name, options);
|
|
24173
|
+
return patchFlueSessionInPlace(session);
|
|
24174
|
+
},
|
|
24175
|
+
writable: true
|
|
24176
|
+
});
|
|
24177
|
+
}
|
|
24178
|
+
function patchCallHandleMethod(session, method, channel2) {
|
|
24179
|
+
const original = session[method];
|
|
24180
|
+
if (typeof original !== "function") {
|
|
24181
|
+
return;
|
|
24182
|
+
}
|
|
24183
|
+
const bound = original.bind(session);
|
|
24184
|
+
Object.defineProperty(session, method, {
|
|
24185
|
+
configurable: true,
|
|
24186
|
+
value(input, options) {
|
|
24187
|
+
const args = [input, options];
|
|
24188
|
+
const { originalResult, traced: traced2 } = traceFlueOperation(channel2, {
|
|
24189
|
+
context: {
|
|
24190
|
+
arguments: args,
|
|
24191
|
+
operation: method,
|
|
24192
|
+
session
|
|
24193
|
+
},
|
|
24194
|
+
run: () => bound(input, options)
|
|
24195
|
+
});
|
|
24196
|
+
return preserveCallHandle(originalResult, traced2);
|
|
24197
|
+
},
|
|
24198
|
+
writable: true
|
|
24199
|
+
});
|
|
24200
|
+
}
|
|
24201
|
+
function patchCompact(session) {
|
|
24202
|
+
const original = session.compact;
|
|
24203
|
+
if (typeof original !== "function") {
|
|
24204
|
+
return;
|
|
24205
|
+
}
|
|
24206
|
+
const bound = original.bind(session);
|
|
24207
|
+
Object.defineProperty(session, "compact", {
|
|
24208
|
+
configurable: true,
|
|
24209
|
+
value() {
|
|
24210
|
+
const context = {
|
|
24211
|
+
arguments: [],
|
|
24212
|
+
operation: "compact",
|
|
24213
|
+
session
|
|
24214
|
+
};
|
|
24215
|
+
return flueChannels.compact.tracePromise(() => bound(), context);
|
|
24216
|
+
},
|
|
24217
|
+
writable: true
|
|
24218
|
+
});
|
|
24219
|
+
}
|
|
24220
|
+
function traceFlueOperation(channel2, args) {
|
|
24221
|
+
const tracingChannel2 = channel2.tracingChannel();
|
|
24222
|
+
const context = args.context;
|
|
24223
|
+
let originalResult;
|
|
24224
|
+
let traced2;
|
|
24225
|
+
const run = () => {
|
|
24226
|
+
try {
|
|
24227
|
+
originalResult = args.run();
|
|
24228
|
+
tracingChannel2.end?.publish(context);
|
|
24229
|
+
} catch (error) {
|
|
24230
|
+
context.error = normalizeError3(error);
|
|
24231
|
+
tracingChannel2.error?.publish(context);
|
|
24232
|
+
tracingChannel2.end?.publish(context);
|
|
24233
|
+
throw error;
|
|
24234
|
+
}
|
|
24235
|
+
traced2 = Promise.resolve(originalResult).then(
|
|
24236
|
+
(result) => {
|
|
24237
|
+
context.result = result;
|
|
24238
|
+
tracingChannel2.asyncStart?.publish(context);
|
|
24239
|
+
tracingChannel2.asyncEnd?.publish(context);
|
|
24240
|
+
return result;
|
|
24241
|
+
},
|
|
24242
|
+
(error) => {
|
|
24243
|
+
context.error = normalizeError3(error);
|
|
24244
|
+
tracingChannel2.error?.publish(context);
|
|
24245
|
+
tracingChannel2.asyncStart?.publish(context);
|
|
24246
|
+
tracingChannel2.asyncEnd?.publish(context);
|
|
24247
|
+
throw error;
|
|
24248
|
+
}
|
|
24249
|
+
);
|
|
24250
|
+
};
|
|
24251
|
+
if (tracingChannel2.start?.runStores) {
|
|
24252
|
+
tracingChannel2.start.runStores(context, run);
|
|
24253
|
+
} else {
|
|
24254
|
+
tracingChannel2.start?.publish(context);
|
|
24255
|
+
run();
|
|
24256
|
+
}
|
|
24257
|
+
return { originalResult, traced: traced2 };
|
|
24258
|
+
}
|
|
24259
|
+
function normalizeError3(error) {
|
|
24260
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
24261
|
+
}
|
|
24262
|
+
function preserveCallHandle(originalHandle, traced2) {
|
|
24263
|
+
if (!isFlueCallHandle(originalHandle)) {
|
|
24264
|
+
return traced2;
|
|
24265
|
+
}
|
|
24266
|
+
const handle = originalHandle;
|
|
24267
|
+
const wrapped = {
|
|
24268
|
+
get signal() {
|
|
24269
|
+
return handle.signal;
|
|
24270
|
+
},
|
|
24271
|
+
abort(reason) {
|
|
24272
|
+
return handle.abort(reason);
|
|
24273
|
+
},
|
|
24274
|
+
then(onfulfilled, onrejected) {
|
|
24275
|
+
return traced2.then(onfulfilled, onrejected);
|
|
24276
|
+
}
|
|
24277
|
+
};
|
|
24278
|
+
return wrapped;
|
|
24279
|
+
}
|
|
24280
|
+
function isPlausibleFlueContext(value) {
|
|
24281
|
+
return !!value && typeof value === "object" && typeof value.init === "function";
|
|
24282
|
+
}
|
|
24283
|
+
function isPlausibleFlueHarness(value) {
|
|
24284
|
+
return !!value && typeof value === "object" && typeof value.session === "function";
|
|
24285
|
+
}
|
|
24286
|
+
function isPlausibleFlueSession(value) {
|
|
24287
|
+
return !!value && typeof value === "object" && typeof value.prompt === "function" && typeof value.skill === "function" && typeof value.task === "function" && typeof value.compact === "function";
|
|
24288
|
+
}
|
|
24289
|
+
function isFlueCallHandle(value) {
|
|
24290
|
+
return !!value && typeof value === "object" && typeof value.then === "function" && typeof value.abort === "function" && "signal" in value;
|
|
24291
|
+
}
|
|
24292
|
+
|
|
24293
|
+
// src/instrumentation/plugins/flue-plugin.ts
|
|
24294
|
+
var FluePlugin = class extends BasePlugin {
|
|
24295
|
+
activeOperationsById = /* @__PURE__ */ new Map();
|
|
24296
|
+
activeOperationsByScope = /* @__PURE__ */ new Map();
|
|
24297
|
+
compactionsByScope = /* @__PURE__ */ new Map();
|
|
24298
|
+
pendingOperationsByKey = /* @__PURE__ */ new Map();
|
|
24299
|
+
tasksById = /* @__PURE__ */ new Map();
|
|
24300
|
+
toolsById = /* @__PURE__ */ new Map();
|
|
24301
|
+
turnsByScope = /* @__PURE__ */ new Map();
|
|
24302
|
+
onEnable() {
|
|
24303
|
+
this.subscribeToContextCreation();
|
|
24304
|
+
this.subscribeToSessionCreation();
|
|
24305
|
+
this.subscribeToContextEvents();
|
|
24306
|
+
this.subscribeToSessionOperations();
|
|
24307
|
+
}
|
|
24308
|
+
onDisable() {
|
|
24309
|
+
for (const unsubscribe of this.unsubscribers) {
|
|
24310
|
+
unsubscribe();
|
|
24311
|
+
}
|
|
24312
|
+
this.unsubscribers = [];
|
|
24313
|
+
this.activeOperationsById.clear();
|
|
24314
|
+
this.activeOperationsByScope.clear();
|
|
24315
|
+
this.compactionsByScope.clear();
|
|
24316
|
+
this.pendingOperationsByKey.clear();
|
|
24317
|
+
this.tasksById.clear();
|
|
24318
|
+
this.toolsById.clear();
|
|
24319
|
+
this.turnsByScope.clear();
|
|
24320
|
+
}
|
|
24321
|
+
subscribeToContextCreation() {
|
|
24322
|
+
const channel2 = flueChannels.createContext.tracingChannel();
|
|
24323
|
+
const handlers = {
|
|
24324
|
+
end: (event) => {
|
|
24325
|
+
const ctx = event.result;
|
|
24326
|
+
if (!ctx) {
|
|
24327
|
+
return;
|
|
24328
|
+
}
|
|
24329
|
+
subscribeFlueContextEvents(ctx, { captureTurnSpans: false });
|
|
24330
|
+
patchFlueContextInPlace(ctx);
|
|
24331
|
+
},
|
|
24332
|
+
error: () => {
|
|
24333
|
+
}
|
|
24334
|
+
};
|
|
24335
|
+
channel2.subscribe(handlers);
|
|
24336
|
+
this.unsubscribers.push(() => {
|
|
24337
|
+
channel2.unsubscribe(handlers);
|
|
24338
|
+
});
|
|
24339
|
+
}
|
|
24340
|
+
subscribeToSessionCreation() {
|
|
24341
|
+
const channel2 = flueChannels.openSession.tracingChannel();
|
|
24342
|
+
const handlers = {
|
|
24343
|
+
asyncEnd: (event) => {
|
|
24344
|
+
if (event.result) {
|
|
24345
|
+
patchFlueSessionInPlace(
|
|
24346
|
+
event.result
|
|
24347
|
+
);
|
|
24348
|
+
}
|
|
24349
|
+
if (event.harness) {
|
|
24350
|
+
wrapFlueHarness(event.harness);
|
|
24351
|
+
}
|
|
24352
|
+
},
|
|
24353
|
+
error: () => {
|
|
24354
|
+
}
|
|
24355
|
+
};
|
|
24356
|
+
channel2.subscribe(handlers);
|
|
24357
|
+
this.unsubscribers.push(() => {
|
|
24358
|
+
channel2.unsubscribe(handlers);
|
|
24359
|
+
});
|
|
24360
|
+
}
|
|
24361
|
+
subscribeToSessionOperations() {
|
|
24362
|
+
this.subscribeToSessionOperation(flueChannels.prompt);
|
|
24363
|
+
this.subscribeToSessionOperation(flueChannels.skill);
|
|
24364
|
+
this.subscribeToSessionOperation(flueChannels.task);
|
|
24365
|
+
this.subscribeToCompact();
|
|
24366
|
+
}
|
|
24367
|
+
subscribeToSessionOperation(channel2) {
|
|
24368
|
+
const tracingChannel2 = channel2.tracingChannel();
|
|
24369
|
+
const states = /* @__PURE__ */ new WeakMap();
|
|
24370
|
+
const ensureState2 = (event) => {
|
|
24371
|
+
const existing = states.get(event);
|
|
24372
|
+
if (existing) {
|
|
24373
|
+
return existing;
|
|
24374
|
+
}
|
|
24375
|
+
const state = this.startOperationState({
|
|
24376
|
+
args: event.arguments,
|
|
24377
|
+
moduleVersion: typeof event.moduleVersion === "string" ? event.moduleVersion : void 0,
|
|
24378
|
+
operation: event.operation,
|
|
24379
|
+
session: event.session
|
|
24380
|
+
});
|
|
24381
|
+
states.set(event, state);
|
|
24382
|
+
return state;
|
|
24383
|
+
};
|
|
24384
|
+
const unbindCurrentSpanStore = this.bindCurrentSpanStoreToOperationStart(
|
|
24385
|
+
tracingChannel2,
|
|
24386
|
+
ensureState2
|
|
24387
|
+
);
|
|
24388
|
+
const handlers = {
|
|
24389
|
+
start: (event) => {
|
|
24390
|
+
ensureState2(event);
|
|
24391
|
+
},
|
|
24392
|
+
asyncEnd: (event) => {
|
|
24393
|
+
this.endOperationState(states.get(event), event.result);
|
|
24394
|
+
states.delete(event);
|
|
24395
|
+
},
|
|
24396
|
+
error: (event) => {
|
|
24397
|
+
const state = states.get(event);
|
|
24398
|
+
if (state && event.error) {
|
|
24399
|
+
safeLog3(state.span, { error: errorToString(event.error) });
|
|
24400
|
+
this.finishOperationState(state);
|
|
24401
|
+
}
|
|
24402
|
+
states.delete(event);
|
|
24403
|
+
}
|
|
24404
|
+
};
|
|
24405
|
+
tracingChannel2.subscribe(handlers);
|
|
24406
|
+
this.unsubscribers.push(() => {
|
|
24407
|
+
unbindCurrentSpanStore?.();
|
|
24408
|
+
tracingChannel2.unsubscribe(handlers);
|
|
24409
|
+
});
|
|
24410
|
+
}
|
|
24411
|
+
subscribeToCompact() {
|
|
24412
|
+
const tracingChannel2 = flueChannels.compact.tracingChannel();
|
|
24413
|
+
const states = /* @__PURE__ */ new WeakMap();
|
|
24414
|
+
const ensureState2 = (event) => {
|
|
24415
|
+
const existing = states.get(event);
|
|
24416
|
+
if (existing) {
|
|
24417
|
+
return existing;
|
|
24418
|
+
}
|
|
24419
|
+
const state = this.startOperationState({
|
|
24420
|
+
args: [],
|
|
24421
|
+
moduleVersion: typeof event.moduleVersion === "string" ? event.moduleVersion : void 0,
|
|
24422
|
+
operation: event.operation,
|
|
24423
|
+
session: event.session
|
|
24424
|
+
});
|
|
24425
|
+
states.set(event, state);
|
|
24426
|
+
return state;
|
|
24427
|
+
};
|
|
24428
|
+
const unbindCurrentSpanStore = this.bindCurrentSpanStoreToOperationStart(
|
|
24429
|
+
tracingChannel2,
|
|
24430
|
+
ensureState2
|
|
24431
|
+
);
|
|
24432
|
+
const handlers = {
|
|
24433
|
+
start: (event) => {
|
|
24434
|
+
ensureState2(event);
|
|
24435
|
+
},
|
|
24436
|
+
asyncEnd: (event) => {
|
|
24437
|
+
this.endOperationState(states.get(event), void 0);
|
|
24438
|
+
states.delete(event);
|
|
24439
|
+
},
|
|
24440
|
+
error: (event) => {
|
|
24441
|
+
const state = states.get(event);
|
|
24442
|
+
if (state && event.error) {
|
|
24443
|
+
safeLog3(state.span, { error: errorToString(event.error) });
|
|
24444
|
+
this.finishOperationState(state);
|
|
24445
|
+
}
|
|
24446
|
+
states.delete(event);
|
|
24447
|
+
}
|
|
24448
|
+
};
|
|
24449
|
+
tracingChannel2.subscribe(handlers);
|
|
24450
|
+
this.unsubscribers.push(() => {
|
|
24451
|
+
unbindCurrentSpanStore?.();
|
|
24452
|
+
tracingChannel2.unsubscribe(handlers);
|
|
24453
|
+
});
|
|
24454
|
+
}
|
|
24455
|
+
subscribeToContextEvents() {
|
|
24456
|
+
const channel2 = flueChannels.contextEvent.tracingChannel();
|
|
24457
|
+
const handlers = {
|
|
24458
|
+
start: (event) => {
|
|
24459
|
+
const flueEvent = event.arguments[0];
|
|
24460
|
+
if (!flueEvent) {
|
|
24461
|
+
return;
|
|
24462
|
+
}
|
|
24463
|
+
try {
|
|
24464
|
+
this.handleFlueEvent(flueEvent, {
|
|
24465
|
+
captureTurnSpans: event.captureTurnSpans !== false
|
|
24466
|
+
});
|
|
24467
|
+
} catch (error) {
|
|
24468
|
+
logInstrumentationError3("Flue event", error);
|
|
24469
|
+
}
|
|
24470
|
+
},
|
|
24471
|
+
error: () => {
|
|
24472
|
+
}
|
|
24473
|
+
};
|
|
24474
|
+
channel2.subscribe(handlers);
|
|
24475
|
+
this.unsubscribers.push(() => {
|
|
24476
|
+
channel2.unsubscribe(handlers);
|
|
24477
|
+
});
|
|
24478
|
+
}
|
|
24479
|
+
bindCurrentSpanStoreToOperationStart(tracingChannel2, ensureState2) {
|
|
24480
|
+
const state = _internalGetGlobalState();
|
|
24481
|
+
const startChannel = tracingChannel2.start;
|
|
24482
|
+
const contextManager = state?.contextManager;
|
|
24483
|
+
const currentSpanStore = contextManager ? contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
|
|
24484
|
+
if (!currentSpanStore || !startChannel) {
|
|
24485
|
+
return void 0;
|
|
24486
|
+
}
|
|
24487
|
+
startChannel.bindStore(currentSpanStore, (event) => {
|
|
24488
|
+
const operationState = ensureState2(event);
|
|
24489
|
+
return contextManager.wrapSpanForStore(operationState.span);
|
|
24490
|
+
});
|
|
24491
|
+
return () => {
|
|
24492
|
+
startChannel.unbindStore(currentSpanStore);
|
|
24493
|
+
};
|
|
24494
|
+
}
|
|
24495
|
+
startOperationState(args) {
|
|
24496
|
+
const sessionName = getSessionName(args.session);
|
|
24497
|
+
const metadata = {
|
|
24498
|
+
...extractOperationInputMetadata(args.operation, args.args),
|
|
24499
|
+
...extractSessionMetadata(args.session),
|
|
24500
|
+
"flue.operation": args.operation,
|
|
24501
|
+
provider: "flue",
|
|
24502
|
+
...args.moduleVersion ? { "flue.version": args.moduleVersion } : {}
|
|
24503
|
+
};
|
|
24504
|
+
const span = startSpan({
|
|
24505
|
+
name: `flue.session.${args.operation}`,
|
|
24506
|
+
spanAttributes: { type: "task" /* TASK */ }
|
|
24507
|
+
});
|
|
24508
|
+
const state = {
|
|
24509
|
+
metadata,
|
|
24510
|
+
operation: args.operation,
|
|
24511
|
+
sessionName,
|
|
24512
|
+
span,
|
|
24513
|
+
startTime: getCurrentUnixTimestamp()
|
|
24514
|
+
};
|
|
24515
|
+
safeLog3(span, {
|
|
24516
|
+
input: extractOperationInput(args.operation, args.args),
|
|
24517
|
+
metadata
|
|
24518
|
+
});
|
|
24519
|
+
this.pendingOperationQueue(operationKey(sessionName, args.operation)).push(
|
|
24520
|
+
state
|
|
24521
|
+
);
|
|
24522
|
+
addOperationToScope(
|
|
24523
|
+
this.activeOperationsByScope,
|
|
24524
|
+
sessionName ?? "unknown",
|
|
24525
|
+
state
|
|
24526
|
+
);
|
|
24527
|
+
return state;
|
|
24528
|
+
}
|
|
24529
|
+
endOperationState(state, result) {
|
|
24530
|
+
if (!state) {
|
|
24531
|
+
return;
|
|
24532
|
+
}
|
|
24533
|
+
const metadata = {
|
|
24534
|
+
...state.metadata,
|
|
24535
|
+
...extractPromptResponseMetadata(result)
|
|
24536
|
+
};
|
|
24537
|
+
const metrics = {
|
|
24538
|
+
...buildDurationMetrics3(state.startTime),
|
|
24539
|
+
...metricsFromUsage(result?.usage)
|
|
24540
|
+
};
|
|
24541
|
+
safeLog3(state.span, {
|
|
24542
|
+
metadata,
|
|
24543
|
+
metrics,
|
|
24544
|
+
output: extractOperationOutput(result)
|
|
24545
|
+
});
|
|
24546
|
+
this.finishCompactionsForOperation(state);
|
|
24547
|
+
this.finishOperationState(state);
|
|
24548
|
+
}
|
|
24549
|
+
finishOperationState(state) {
|
|
24550
|
+
removePendingOperation(this.pendingOperationsByKey, state);
|
|
24551
|
+
if (state.operationId) {
|
|
24552
|
+
this.activeOperationsById.delete(state.operationId);
|
|
24553
|
+
}
|
|
24554
|
+
removeScopedOperation(this.activeOperationsByScope, state);
|
|
24555
|
+
state.span.end();
|
|
24556
|
+
}
|
|
24557
|
+
handleFlueEvent(event, options) {
|
|
24558
|
+
switch (event.type) {
|
|
24559
|
+
case "operation_start":
|
|
24560
|
+
this.handleOperationStart(event);
|
|
24561
|
+
return;
|
|
24562
|
+
case "operation":
|
|
24563
|
+
this.handleOperation(event);
|
|
24564
|
+
return;
|
|
24565
|
+
case "text_delta":
|
|
24566
|
+
if (!options.captureTurnSpans) {
|
|
24567
|
+
return;
|
|
24568
|
+
}
|
|
24569
|
+
this.ensureTurnState(event).text.push(
|
|
24570
|
+
typeof event.text === "string" ? event.text : ""
|
|
24571
|
+
);
|
|
24572
|
+
return;
|
|
24573
|
+
case "thinking_start":
|
|
24574
|
+
if (!options.captureTurnSpans) {
|
|
24575
|
+
return;
|
|
24576
|
+
}
|
|
24577
|
+
this.handleThinkingStart(event);
|
|
24578
|
+
return;
|
|
24579
|
+
case "thinking_delta":
|
|
24580
|
+
if (!options.captureTurnSpans) {
|
|
24581
|
+
return;
|
|
24582
|
+
}
|
|
24583
|
+
this.handleThinkingDelta(event);
|
|
24584
|
+
return;
|
|
24585
|
+
case "thinking_end":
|
|
24586
|
+
if (!options.captureTurnSpans) {
|
|
24587
|
+
return;
|
|
24588
|
+
}
|
|
24589
|
+
this.handleThinkingEnd(event);
|
|
24590
|
+
return;
|
|
24591
|
+
case "turn":
|
|
24592
|
+
if (!options.captureTurnSpans) {
|
|
24593
|
+
return;
|
|
24594
|
+
}
|
|
24595
|
+
this.handleTurn(event);
|
|
24596
|
+
return;
|
|
24597
|
+
case "tool_start":
|
|
24598
|
+
this.handleToolStart(event, options);
|
|
24599
|
+
return;
|
|
24600
|
+
case "tool_call":
|
|
24601
|
+
this.handleToolCall(event);
|
|
24602
|
+
return;
|
|
24603
|
+
case "task_start":
|
|
24604
|
+
this.handleTaskStart(event);
|
|
24605
|
+
return;
|
|
24606
|
+
case "task":
|
|
24607
|
+
this.handleTask(event);
|
|
24608
|
+
return;
|
|
24609
|
+
case "compaction_start":
|
|
24610
|
+
this.handleCompactionStart(event);
|
|
24611
|
+
return;
|
|
24612
|
+
case "compaction":
|
|
24613
|
+
this.handleCompaction(event);
|
|
24614
|
+
return;
|
|
24615
|
+
default:
|
|
24616
|
+
return;
|
|
24617
|
+
}
|
|
24618
|
+
}
|
|
24619
|
+
handleOperationStart(event) {
|
|
24620
|
+
if (!isInstrumentedOperation(event.operationKind)) {
|
|
24621
|
+
return;
|
|
24622
|
+
}
|
|
24623
|
+
const state = this.takePendingOperationForEvent(event);
|
|
24624
|
+
if (!state) {
|
|
24625
|
+
return;
|
|
24626
|
+
}
|
|
24627
|
+
state.operationId = event.operationId;
|
|
24628
|
+
this.activeOperationsById.set(event.operationId, state);
|
|
24629
|
+
addScopedOperation(this.activeOperationsByScope, event, state);
|
|
24630
|
+
state.metadata = {
|
|
24631
|
+
...state.metadata,
|
|
24632
|
+
...extractEventMetadata(event),
|
|
24633
|
+
"flue.operation_id": event.operationId
|
|
24634
|
+
};
|
|
24635
|
+
safeLog3(state.span, { metadata: state.metadata });
|
|
24636
|
+
}
|
|
24637
|
+
handleOperation(event) {
|
|
24638
|
+
const state = event.operationId ? this.activeOperationsById.get(event.operationId) : void 0;
|
|
24639
|
+
if (!state) {
|
|
24640
|
+
return;
|
|
24641
|
+
}
|
|
24642
|
+
const metadata = {
|
|
24643
|
+
...state.metadata,
|
|
24644
|
+
...extractEventMetadata(event),
|
|
24645
|
+
...typeof event.durationMs === "number" ? { "flue.duration_ms": event.durationMs } : {},
|
|
24646
|
+
...event.isError !== void 0 ? { "flue.is_error": event.isError } : {}
|
|
24647
|
+
};
|
|
24648
|
+
const metrics = metricsFromUsage(event.usage);
|
|
24649
|
+
safeLog3(state.span, {
|
|
24650
|
+
...event.error ? { error: errorToString(event.error) } : {},
|
|
24651
|
+
metadata,
|
|
24652
|
+
...Object.keys(metrics).length ? { metrics } : {}
|
|
24653
|
+
});
|
|
24654
|
+
}
|
|
24655
|
+
ensureTurnState(event) {
|
|
24656
|
+
const scope = scopeKey(event);
|
|
24657
|
+
const existing = this.turnsByScope.get(scope);
|
|
24658
|
+
if (existing) {
|
|
24659
|
+
return existing;
|
|
24660
|
+
}
|
|
24661
|
+
const parent = this.parentSpanForEvent(event);
|
|
24662
|
+
const metadata = {
|
|
24663
|
+
...extractEventMetadata(event),
|
|
24664
|
+
provider: "flue"
|
|
24665
|
+
};
|
|
24666
|
+
const span = startFlueSpan(parent, {
|
|
24667
|
+
name: "flue.turn",
|
|
24668
|
+
spanAttributes: { type: "llm" /* LLM */ }
|
|
24669
|
+
});
|
|
24670
|
+
const state = {
|
|
24671
|
+
metadata,
|
|
24672
|
+
span,
|
|
24673
|
+
hasThinking: false,
|
|
24674
|
+
startTime: getCurrentUnixTimestamp(),
|
|
24675
|
+
text: [],
|
|
24676
|
+
thinking: [],
|
|
24677
|
+
toolCalls: []
|
|
24678
|
+
};
|
|
24679
|
+
safeLog3(span, { metadata });
|
|
24680
|
+
this.turnsByScope.set(scope, state);
|
|
24681
|
+
return state;
|
|
24682
|
+
}
|
|
24683
|
+
handleTurn(event) {
|
|
24684
|
+
const scope = scopeKey(event);
|
|
24685
|
+
const state = this.ensureTurnState(event);
|
|
24686
|
+
const text = state.text.join("");
|
|
24687
|
+
const reasoning = state.finalThinking ?? state.thinking.join("");
|
|
24688
|
+
const outputReasoning = reasoning || (state.hasThinking ? "[reasoning stream present; content unavailable]" : void 0);
|
|
24689
|
+
const metadata = {
|
|
24690
|
+
...state.metadata,
|
|
24691
|
+
...extractEventMetadata(event),
|
|
24692
|
+
...event.model ? { model: event.model, "flue.model": event.model } : {},
|
|
24693
|
+
...event.stopReason ? { "flue.stop_reason": event.stopReason } : {},
|
|
24694
|
+
...event.isError !== void 0 ? { "flue.is_error": event.isError } : {},
|
|
24695
|
+
provider: "flue"
|
|
24696
|
+
};
|
|
24697
|
+
safeLog3(state.span, {
|
|
24698
|
+
...event.error ? { error: errorToString(event.error) } : {},
|
|
24699
|
+
metadata,
|
|
24700
|
+
metrics: {
|
|
24701
|
+
...durationMsMetrics(event.durationMs),
|
|
24702
|
+
...metricsFromUsage(event.usage)
|
|
24703
|
+
},
|
|
24704
|
+
output: toAssistantOutput(
|
|
24705
|
+
text,
|
|
24706
|
+
event.stopReason,
|
|
24707
|
+
outputReasoning,
|
|
24708
|
+
state.toolCalls
|
|
24709
|
+
)
|
|
24710
|
+
});
|
|
24711
|
+
state.span.end();
|
|
24712
|
+
this.turnsByScope.delete(scope);
|
|
24713
|
+
}
|
|
24714
|
+
handleThinkingDelta(event) {
|
|
24715
|
+
const delta = event.delta;
|
|
24716
|
+
if (typeof delta !== "string" || !delta) {
|
|
24717
|
+
return;
|
|
24718
|
+
}
|
|
24719
|
+
const state = this.ensureTurnState(event);
|
|
24720
|
+
state.hasThinking = true;
|
|
24721
|
+
state.metadata["flue.thinking"] = true;
|
|
24722
|
+
state.thinking.push(delta);
|
|
24723
|
+
}
|
|
24724
|
+
handleThinkingStart(event) {
|
|
24725
|
+
const state = this.ensureTurnState(event);
|
|
24726
|
+
state.hasThinking = true;
|
|
24727
|
+
state.metadata["flue.thinking"] = true;
|
|
24728
|
+
}
|
|
24729
|
+
handleThinkingEnd(event) {
|
|
24730
|
+
const state = this.ensureTurnState(event);
|
|
24731
|
+
state.hasThinking = true;
|
|
24732
|
+
state.metadata["flue.thinking"] = true;
|
|
24733
|
+
if (typeof event.content === "string" && event.content) {
|
|
24734
|
+
state.finalThinking = event.content;
|
|
24735
|
+
}
|
|
24736
|
+
}
|
|
24737
|
+
handleToolStart(event, options) {
|
|
24738
|
+
const toolCallId = event.toolCallId;
|
|
24739
|
+
if (!toolCallId) {
|
|
24740
|
+
return;
|
|
24741
|
+
}
|
|
24742
|
+
const parent = this.parentSpanForEvent(event);
|
|
24743
|
+
const scope = scopeKey(event);
|
|
24744
|
+
let turnState = this.turnsByScope.get(scope);
|
|
24745
|
+
if (!turnState && parent && options.captureTurnSpans) {
|
|
24746
|
+
turnState = this.ensureTurnState(event);
|
|
24747
|
+
}
|
|
24748
|
+
const metadata = {
|
|
24749
|
+
...extractEventMetadata(event),
|
|
24750
|
+
...event.toolName ? { "flue.tool_name": event.toolName } : {},
|
|
24751
|
+
"flue.tool_call_id": toolCallId,
|
|
24752
|
+
provider: "flue"
|
|
24753
|
+
};
|
|
24754
|
+
const span = startFlueSpan(parent, {
|
|
24755
|
+
name: `tool: ${event.toolName ?? "unknown"}`,
|
|
24756
|
+
spanAttributes: { type: "tool" /* TOOL */ }
|
|
24757
|
+
});
|
|
24758
|
+
if (turnState) {
|
|
24759
|
+
turnState.toolCalls.push({
|
|
24760
|
+
args: event.args,
|
|
24761
|
+
toolCallId,
|
|
24762
|
+
toolName: event.toolName
|
|
24763
|
+
});
|
|
24764
|
+
}
|
|
24765
|
+
safeLog3(span, {
|
|
24766
|
+
input: event.args,
|
|
24767
|
+
metadata
|
|
24768
|
+
});
|
|
24769
|
+
this.toolsById.set(toolKey(event), {
|
|
24770
|
+
metadata,
|
|
24771
|
+
span,
|
|
24772
|
+
startTime: getCurrentUnixTimestamp()
|
|
24773
|
+
});
|
|
24774
|
+
}
|
|
24775
|
+
handleToolCall(event) {
|
|
24776
|
+
const key = toolKey(event);
|
|
24777
|
+
const state = this.toolsById.get(key) ?? this.startSyntheticToolState(event, event.toolName ?? "unknown");
|
|
24778
|
+
const metadata = {
|
|
24779
|
+
...state.metadata,
|
|
24780
|
+
...extractEventMetadata(event),
|
|
24781
|
+
...event.toolName ? { "flue.tool_name": event.toolName } : {},
|
|
24782
|
+
...event.toolCallId ? { "flue.tool_call_id": event.toolCallId } : {},
|
|
24783
|
+
...event.isError !== void 0 ? { "flue.is_error": event.isError } : {}
|
|
24784
|
+
};
|
|
24785
|
+
safeLog3(state.span, {
|
|
24786
|
+
...event.isError ? { error: errorToString(event.result) } : {},
|
|
24787
|
+
metadata,
|
|
24788
|
+
metrics: durationMsMetrics(event.durationMs),
|
|
24789
|
+
output: event.result
|
|
24790
|
+
});
|
|
24791
|
+
state.span.end();
|
|
24792
|
+
this.toolsById.delete(key);
|
|
24793
|
+
}
|
|
24794
|
+
handleTaskStart(event) {
|
|
24795
|
+
const parent = this.parentSpanForEvent(event);
|
|
24796
|
+
const metadata = {
|
|
24797
|
+
...extractEventMetadata(event),
|
|
24798
|
+
...event.role ? { "flue.role": event.role } : {},
|
|
24799
|
+
...event.cwd ? { "flue.cwd": event.cwd } : {},
|
|
24800
|
+
"flue.task_id": event.taskId,
|
|
24801
|
+
provider: "flue"
|
|
24802
|
+
};
|
|
24803
|
+
const span = startFlueSpan(parent, {
|
|
24804
|
+
name: "flue.task",
|
|
24805
|
+
spanAttributes: { type: "task" /* TASK */ }
|
|
24806
|
+
});
|
|
24807
|
+
safeLog3(span, {
|
|
24808
|
+
input: event.prompt,
|
|
24809
|
+
metadata
|
|
24810
|
+
});
|
|
24811
|
+
this.tasksById.set(event.taskId, {
|
|
24812
|
+
metadata,
|
|
24813
|
+
span,
|
|
24814
|
+
startTime: getCurrentUnixTimestamp()
|
|
24815
|
+
});
|
|
24816
|
+
}
|
|
24817
|
+
handleTask(event) {
|
|
24818
|
+
const state = this.tasksById.get(event.taskId);
|
|
24819
|
+
if (!state) {
|
|
24820
|
+
return;
|
|
24821
|
+
}
|
|
24822
|
+
safeLog3(state.span, {
|
|
24823
|
+
...event.isError ? { error: errorToString(event.result) } : {},
|
|
24824
|
+
metadata: {
|
|
24825
|
+
...state.metadata,
|
|
24826
|
+
...extractEventMetadata(event),
|
|
24827
|
+
...event.isError !== void 0 ? { "flue.is_error": event.isError } : {}
|
|
24828
|
+
},
|
|
24829
|
+
metrics: durationMsMetrics(event.durationMs),
|
|
24830
|
+
output: event.result
|
|
24831
|
+
});
|
|
24832
|
+
state.span.end();
|
|
24833
|
+
this.tasksById.delete(event.taskId);
|
|
24834
|
+
}
|
|
24835
|
+
handleCompactionStart(event) {
|
|
24836
|
+
const operationState = this.operationStateForEvent(event);
|
|
24837
|
+
const parent = operationState?.span ?? this.parentSpanForEvent(event);
|
|
24838
|
+
const metadata = {
|
|
24839
|
+
...extractEventMetadata(event),
|
|
24840
|
+
...event.reason ? { "flue.compaction_reason": event.reason } : {},
|
|
24841
|
+
provider: "flue"
|
|
24842
|
+
};
|
|
24843
|
+
const input = {
|
|
24844
|
+
...typeof event.estimatedTokens === "number" ? { estimatedTokens: event.estimatedTokens } : {},
|
|
24845
|
+
...event.reason ? { reason: event.reason } : {}
|
|
24846
|
+
};
|
|
24847
|
+
const span = startFlueSpan(parent, {
|
|
24848
|
+
name: "flue.compaction",
|
|
24849
|
+
spanAttributes: { type: "task" /* TASK */ }
|
|
24850
|
+
});
|
|
24851
|
+
safeLog3(span, {
|
|
24852
|
+
input,
|
|
24853
|
+
metadata
|
|
24854
|
+
});
|
|
24855
|
+
this.compactionsByScope.set(scopeKey(event), {
|
|
24856
|
+
input,
|
|
24857
|
+
metadata,
|
|
24858
|
+
operationState,
|
|
24859
|
+
span,
|
|
24860
|
+
startTime: getCurrentUnixTimestamp()
|
|
24861
|
+
});
|
|
24862
|
+
}
|
|
24863
|
+
handleCompaction(event) {
|
|
24864
|
+
const key = scopeKey(event);
|
|
24865
|
+
const state = this.compactionsByScope.get(key) ?? this.findCompactionState(event);
|
|
24866
|
+
if (!state) {
|
|
24867
|
+
return;
|
|
24868
|
+
}
|
|
24869
|
+
safeLog3(state.span, {
|
|
24870
|
+
metadata: {
|
|
24871
|
+
...state.metadata,
|
|
24872
|
+
...extractEventMetadata(event),
|
|
24873
|
+
...typeof event.messagesBefore === "number" ? { "flue.messages_before": event.messagesBefore } : {},
|
|
24874
|
+
...typeof event.messagesAfter === "number" ? { "flue.messages_after": event.messagesAfter } : {}
|
|
24875
|
+
},
|
|
24876
|
+
metrics: {
|
|
24877
|
+
...durationMsMetrics(event.durationMs),
|
|
24878
|
+
...metricsFromUsage(event.usage)
|
|
24879
|
+
},
|
|
24880
|
+
output: {
|
|
24881
|
+
messagesAfter: event.messagesAfter,
|
|
24882
|
+
messagesBefore: event.messagesBefore
|
|
24883
|
+
}
|
|
24884
|
+
});
|
|
24885
|
+
state.span.end();
|
|
24886
|
+
this.deleteCompactionState(state);
|
|
24887
|
+
}
|
|
24888
|
+
findCompactionState(event) {
|
|
24889
|
+
const operationState = this.operationStateForEvent(event);
|
|
24890
|
+
for (const state of this.compactionsByScope.values()) {
|
|
24891
|
+
if (operationState && state.operationState === operationState) {
|
|
24892
|
+
return state;
|
|
24893
|
+
}
|
|
24894
|
+
}
|
|
24895
|
+
return void 0;
|
|
24896
|
+
}
|
|
24897
|
+
finishCompactionsForOperation(operationState) {
|
|
24898
|
+
for (const state of [...this.compactionsByScope.values()]) {
|
|
24899
|
+
if (state.operationState !== operationState) {
|
|
24900
|
+
continue;
|
|
24901
|
+
}
|
|
24902
|
+
safeLog3(state.span, {
|
|
24903
|
+
input: state.input,
|
|
24904
|
+
metadata: state.metadata,
|
|
24905
|
+
metrics: {
|
|
24906
|
+
...buildDurationMetrics3(state.startTime)
|
|
24907
|
+
},
|
|
24908
|
+
output: { completed: true }
|
|
24909
|
+
});
|
|
24910
|
+
state.span.end();
|
|
24911
|
+
this.deleteCompactionState(state);
|
|
24912
|
+
}
|
|
24913
|
+
}
|
|
24914
|
+
deleteCompactionState(state) {
|
|
24915
|
+
for (const [key, candidate] of this.compactionsByScope) {
|
|
24916
|
+
if (candidate !== state) {
|
|
24917
|
+
continue;
|
|
24918
|
+
}
|
|
24919
|
+
this.compactionsByScope.delete(key);
|
|
24920
|
+
return;
|
|
24921
|
+
}
|
|
24922
|
+
}
|
|
24923
|
+
startSyntheticToolState(event, toolName) {
|
|
24924
|
+
const parent = this.parentSpanForEvent(event);
|
|
24925
|
+
const metadata = {
|
|
24926
|
+
...extractEventMetadata(event),
|
|
24927
|
+
...event.toolCallId ? { "flue.tool_call_id": event.toolCallId } : {},
|
|
24928
|
+
"flue.tool_name": toolName,
|
|
24929
|
+
provider: "flue"
|
|
24930
|
+
};
|
|
24931
|
+
const span = startFlueSpan(parent, {
|
|
24932
|
+
name: `tool: ${toolName}`,
|
|
24933
|
+
spanAttributes: { type: "tool" /* TOOL */ }
|
|
24934
|
+
});
|
|
24935
|
+
safeLog3(span, { metadata });
|
|
24936
|
+
return { metadata, span, startTime: getCurrentUnixTimestamp() };
|
|
24937
|
+
}
|
|
24938
|
+
operationStateForEvent(event) {
|
|
24939
|
+
if (event.operationId) {
|
|
24940
|
+
const operation = this.activeOperationsById.get(event.operationId) ?? this.promotePendingOperationForEvent(event);
|
|
24941
|
+
if (operation) {
|
|
24942
|
+
return operation;
|
|
24943
|
+
}
|
|
24944
|
+
}
|
|
24945
|
+
return this.activeOperationForEventScope(event) ?? this.pendingOperationForEventScope(event);
|
|
24946
|
+
}
|
|
24947
|
+
parentSpanForEvent(event) {
|
|
24948
|
+
if (event.operationId) {
|
|
24949
|
+
const operation = this.operationStateForEvent(event);
|
|
24950
|
+
if (operation) {
|
|
24951
|
+
return operation.span;
|
|
24952
|
+
}
|
|
24953
|
+
}
|
|
24954
|
+
if (event.taskId) {
|
|
24955
|
+
return this.tasksById.get(event.taskId)?.span;
|
|
24956
|
+
}
|
|
24957
|
+
return this.operationStateForEvent(event)?.span;
|
|
24958
|
+
}
|
|
24959
|
+
promotePendingOperationForEvent(event) {
|
|
24960
|
+
if (!event.operationId) {
|
|
24961
|
+
return void 0;
|
|
24962
|
+
}
|
|
24963
|
+
const scopePrefixes = operationScopePrefixes(event);
|
|
24964
|
+
for (const [candidateKey, candidateQueue] of this.pendingOperationsByKey) {
|
|
24965
|
+
if (!candidateQueue.length || !operationKeyMatchesScopes(candidateKey, scopePrefixes)) {
|
|
24966
|
+
continue;
|
|
24967
|
+
}
|
|
24968
|
+
const state = candidateQueue.shift();
|
|
24969
|
+
if (!state) {
|
|
24970
|
+
return void 0;
|
|
24971
|
+
}
|
|
24972
|
+
state.operationId = event.operationId;
|
|
24973
|
+
this.activeOperationsById.set(event.operationId, state);
|
|
24974
|
+
addScopedOperation(this.activeOperationsByScope, event, state);
|
|
24975
|
+
state.metadata = {
|
|
24976
|
+
...state.metadata,
|
|
24977
|
+
...extractEventMetadata(event),
|
|
24978
|
+
"flue.operation_id": event.operationId
|
|
24979
|
+
};
|
|
24980
|
+
safeLog3(state.span, { metadata: state.metadata });
|
|
24981
|
+
return state;
|
|
24982
|
+
}
|
|
24983
|
+
return void 0;
|
|
24984
|
+
}
|
|
24985
|
+
activeOperationForEventScope(event) {
|
|
24986
|
+
for (const scope of operationScopeNames(event)) {
|
|
24987
|
+
const operations = this.activeOperationsByScope.get(scope);
|
|
24988
|
+
if (operations?.length) {
|
|
24989
|
+
return operations[operations.length - 1];
|
|
24990
|
+
}
|
|
24991
|
+
}
|
|
24992
|
+
return void 0;
|
|
24993
|
+
}
|
|
24994
|
+
pendingOperationForEventScope(event) {
|
|
24995
|
+
const scopePrefixes = operationScopePrefixes(event);
|
|
24996
|
+
for (const [candidateKey, candidateQueue] of this.pendingOperationsByKey) {
|
|
24997
|
+
if (!candidateQueue.length || !operationKeyMatchesScopes(candidateKey, scopePrefixes)) {
|
|
24998
|
+
continue;
|
|
24999
|
+
}
|
|
25000
|
+
return candidateQueue[0];
|
|
25001
|
+
}
|
|
25002
|
+
return void 0;
|
|
25003
|
+
}
|
|
25004
|
+
takePendingOperationForEvent(event) {
|
|
25005
|
+
const key = operationKey(event.session, event.operationKind);
|
|
25006
|
+
const queue2 = this.pendingOperationsByKey.get(key);
|
|
25007
|
+
if (queue2?.length) {
|
|
25008
|
+
return queue2.shift();
|
|
25009
|
+
}
|
|
25010
|
+
for (const [candidateKey, candidateQueue] of this.pendingOperationsByKey) {
|
|
25011
|
+
if (candidateKey.endsWith(`::${event.operationKind}`) && candidateQueue.length) {
|
|
25012
|
+
return candidateQueue.shift();
|
|
25013
|
+
}
|
|
25014
|
+
}
|
|
25015
|
+
return void 0;
|
|
25016
|
+
}
|
|
25017
|
+
pendingOperationQueue(key) {
|
|
25018
|
+
const existing = this.pendingOperationsByKey.get(key);
|
|
25019
|
+
if (existing) {
|
|
25020
|
+
return existing;
|
|
25021
|
+
}
|
|
25022
|
+
const queue2 = [];
|
|
25023
|
+
this.pendingOperationsByKey.set(key, queue2);
|
|
25024
|
+
return queue2;
|
|
25025
|
+
}
|
|
25026
|
+
};
|
|
25027
|
+
function isInstrumentedOperation(operation) {
|
|
25028
|
+
return operation === "prompt" || operation === "skill" || operation === "task" || operation === "compact";
|
|
25029
|
+
}
|
|
25030
|
+
function getSessionName(session) {
|
|
25031
|
+
return typeof session?.name === "string" ? session.name : void 0;
|
|
25032
|
+
}
|
|
25033
|
+
function operationKey(sessionName, operation) {
|
|
25034
|
+
return `${sessionName ?? "unknown"}::${operation}`;
|
|
25035
|
+
}
|
|
25036
|
+
function operationScopePrefixes(event) {
|
|
25037
|
+
const scopes = /* @__PURE__ */ new Set();
|
|
25038
|
+
for (const scope of operationScopeNames(event)) {
|
|
25039
|
+
scopes.add(`${scope}::`);
|
|
25040
|
+
}
|
|
25041
|
+
return scopes;
|
|
25042
|
+
}
|
|
25043
|
+
function operationKeyMatchesScopes(key, scopes) {
|
|
25044
|
+
for (const scope of scopes) {
|
|
25045
|
+
if (key.startsWith(scope)) {
|
|
25046
|
+
return true;
|
|
25047
|
+
}
|
|
25048
|
+
}
|
|
25049
|
+
return false;
|
|
25050
|
+
}
|
|
25051
|
+
function operationScopeNames(event) {
|
|
25052
|
+
const scopes = /* @__PURE__ */ new Set();
|
|
25053
|
+
if (event.session) {
|
|
25054
|
+
scopes.add(event.session);
|
|
25055
|
+
}
|
|
25056
|
+
if (event.parentSession) {
|
|
25057
|
+
scopes.add(event.parentSession);
|
|
25058
|
+
}
|
|
25059
|
+
if (!scopes.size) {
|
|
25060
|
+
scopes.add("unknown");
|
|
25061
|
+
}
|
|
25062
|
+
return scopes;
|
|
25063
|
+
}
|
|
25064
|
+
function addScopedOperation(operationsByScope, event, state) {
|
|
25065
|
+
for (const scope of operationScopeNames(event)) {
|
|
25066
|
+
addOperationToScope(operationsByScope, scope, state);
|
|
25067
|
+
}
|
|
25068
|
+
}
|
|
25069
|
+
function addOperationToScope(operationsByScope, scope, state) {
|
|
25070
|
+
const operations = operationsByScope.get(scope);
|
|
25071
|
+
if (operations) {
|
|
25072
|
+
if (!operations.includes(state)) {
|
|
25073
|
+
operations.push(state);
|
|
25074
|
+
}
|
|
25075
|
+
} else {
|
|
25076
|
+
operationsByScope.set(scope, [state]);
|
|
25077
|
+
}
|
|
25078
|
+
}
|
|
25079
|
+
function removeScopedOperation(operationsByScope, state) {
|
|
25080
|
+
for (const [scope, operations] of operationsByScope) {
|
|
25081
|
+
const index = operations.indexOf(state);
|
|
25082
|
+
if (index === -1) {
|
|
25083
|
+
continue;
|
|
25084
|
+
}
|
|
25085
|
+
operations.splice(index, 1);
|
|
25086
|
+
if (operations.length === 0) {
|
|
25087
|
+
operationsByScope.delete(scope);
|
|
25088
|
+
}
|
|
25089
|
+
}
|
|
25090
|
+
}
|
|
25091
|
+
function removePendingOperation(pendingOperationsByKey, state) {
|
|
25092
|
+
for (const [key, queue2] of pendingOperationsByKey) {
|
|
25093
|
+
const index = queue2.indexOf(state);
|
|
25094
|
+
if (index === -1) {
|
|
25095
|
+
continue;
|
|
25096
|
+
}
|
|
25097
|
+
queue2.splice(index, 1);
|
|
25098
|
+
if (queue2.length === 0) {
|
|
25099
|
+
pendingOperationsByKey.delete(key);
|
|
25100
|
+
}
|
|
25101
|
+
return;
|
|
25102
|
+
}
|
|
25103
|
+
}
|
|
25104
|
+
function extractSessionMetadata(session) {
|
|
25105
|
+
const sessionName = getSessionName(session);
|
|
25106
|
+
return sessionName ? { "flue.session": sessionName } : {};
|
|
25107
|
+
}
|
|
25108
|
+
function extractEventMetadata(event) {
|
|
25109
|
+
return {
|
|
25110
|
+
...event.runId ? { "flue.run_id": event.runId } : {},
|
|
25111
|
+
...typeof event.eventIndex === "number" ? { "flue.event_index": event.eventIndex } : {},
|
|
25112
|
+
...event.session ? { "flue.session": event.session } : {},
|
|
25113
|
+
...event.parentSession ? { "flue.parent_session": event.parentSession } : {},
|
|
25114
|
+
...event.harness ? { "flue.harness": event.harness } : {},
|
|
25115
|
+
...event.taskId ? { "flue.task_id": event.taskId } : {},
|
|
25116
|
+
...event.operationId ? { "flue.operation_id": event.operationId } : {}
|
|
25117
|
+
};
|
|
25118
|
+
}
|
|
25119
|
+
function extractOperationInput(operation, args) {
|
|
25120
|
+
switch (operation) {
|
|
25121
|
+
case "prompt":
|
|
25122
|
+
case "task":
|
|
25123
|
+
return args[0];
|
|
25124
|
+
case "skill":
|
|
25125
|
+
return {
|
|
25126
|
+
args: getOptionObject(args[1])?.args,
|
|
25127
|
+
name: args[0]
|
|
25128
|
+
};
|
|
25129
|
+
case "compact":
|
|
25130
|
+
return void 0;
|
|
25131
|
+
}
|
|
25132
|
+
}
|
|
25133
|
+
function extractOperationInputMetadata(operation, args) {
|
|
25134
|
+
const options = getOptionObject(args[1]);
|
|
25135
|
+
return {
|
|
25136
|
+
...operation === "skill" && typeof args[0] === "string" ? { "flue.skill_name": args[0] } : {},
|
|
25137
|
+
...options?.model ? { model: options.model, "flue.model": options.model } : {},
|
|
25138
|
+
...options?.role ? { "flue.role": options.role } : {},
|
|
25139
|
+
...options?.thinkingLevel ? { "flue.thinking_level": options.thinkingLevel } : {},
|
|
25140
|
+
...typeof options?.cwd === "string" ? { "flue.cwd": options.cwd } : {},
|
|
25141
|
+
...Array.isArray(options?.tools) ? {
|
|
25142
|
+
"flue.tools_count": options.tools.length,
|
|
25143
|
+
tools: summarizeTools(options.tools)
|
|
25144
|
+
} : {},
|
|
25145
|
+
...Array.isArray(options?.images) ? { "flue.images_count": options.images.length } : {},
|
|
25146
|
+
...options?.result || options?.schema ? { "flue.result_schema": true } : {}
|
|
25147
|
+
};
|
|
25148
|
+
}
|
|
25149
|
+
function getOptionObject(value) {
|
|
25150
|
+
return isObject(value) ? value : void 0;
|
|
25151
|
+
}
|
|
25152
|
+
function summarizeTools(tools) {
|
|
25153
|
+
return tools.flatMap((tool) => {
|
|
25154
|
+
if (!isObject(tool)) {
|
|
25155
|
+
return [];
|
|
25156
|
+
}
|
|
25157
|
+
const name = typeof tool.name === "string" ? tool.name : void 0;
|
|
25158
|
+
if (!name) {
|
|
25159
|
+
return [];
|
|
25160
|
+
}
|
|
25161
|
+
return [
|
|
25162
|
+
{
|
|
25163
|
+
function: {
|
|
25164
|
+
description: typeof tool.description === "string" ? tool.description : void 0,
|
|
25165
|
+
name,
|
|
25166
|
+
parameters: tool.parameters
|
|
25167
|
+
},
|
|
25168
|
+
type: "function"
|
|
25169
|
+
}
|
|
25170
|
+
];
|
|
25171
|
+
});
|
|
25172
|
+
}
|
|
25173
|
+
function extractPromptResponseMetadata(result) {
|
|
25174
|
+
const modelId = result?.model && typeof result.model.id === "string" ? result.model.id : void 0;
|
|
25175
|
+
return modelId ? {
|
|
25176
|
+
model: modelId,
|
|
25177
|
+
"flue.model": modelId
|
|
25178
|
+
} : {};
|
|
25179
|
+
}
|
|
25180
|
+
function extractOperationOutput(result) {
|
|
25181
|
+
if (!result) {
|
|
25182
|
+
return void 0;
|
|
25183
|
+
}
|
|
25184
|
+
if ("data" in result) {
|
|
25185
|
+
return result.data;
|
|
25186
|
+
}
|
|
25187
|
+
if ("text" in result) {
|
|
25188
|
+
return result.text;
|
|
25189
|
+
}
|
|
25190
|
+
return result;
|
|
25191
|
+
}
|
|
25192
|
+
function metricsFromUsage(usage) {
|
|
25193
|
+
return {
|
|
25194
|
+
...typeof usage?.input === "number" ? { prompt_tokens: usage.input } : {},
|
|
25195
|
+
...typeof usage?.output === "number" ? { completion_tokens: usage.output } : {},
|
|
25196
|
+
...typeof usage?.cacheRead === "number" ? { prompt_cached_tokens: usage.cacheRead } : {},
|
|
25197
|
+
...typeof usage?.cacheWrite === "number" ? { prompt_cache_creation_tokens: usage.cacheWrite } : {},
|
|
25198
|
+
...typeof usage?.totalTokens === "number" ? { tokens: usage.totalTokens } : {},
|
|
25199
|
+
...typeof usage?.cost?.total === "number" ? { estimated_cost: usage.cost.total } : {}
|
|
25200
|
+
};
|
|
25201
|
+
}
|
|
25202
|
+
function buildDurationMetrics3(startTime) {
|
|
25203
|
+
return {
|
|
25204
|
+
duration_ms: Math.max(0, (getCurrentUnixTimestamp() - startTime) * 1e3)
|
|
25205
|
+
};
|
|
25206
|
+
}
|
|
25207
|
+
function durationMsMetrics(durationMs) {
|
|
25208
|
+
return typeof durationMs === "number" ? { duration_ms: durationMs } : {};
|
|
25209
|
+
}
|
|
25210
|
+
function scopeKey(event) {
|
|
25211
|
+
if (event.operationId) {
|
|
25212
|
+
return `operation:${event.operationId}`;
|
|
25213
|
+
}
|
|
25214
|
+
if (event.taskId) {
|
|
25215
|
+
return `task:${event.taskId}`;
|
|
25216
|
+
}
|
|
25217
|
+
if (event.session) {
|
|
25218
|
+
return `session:${event.session}`;
|
|
25219
|
+
}
|
|
25220
|
+
return "flue:unknown";
|
|
25221
|
+
}
|
|
25222
|
+
function toolKey(event) {
|
|
25223
|
+
return `${scopeKey(event)}::tool:${event.toolCallId ?? "unknown"}`;
|
|
25224
|
+
}
|
|
25225
|
+
function toAssistantOutput(text, finishReason, reasoning, toolCalls) {
|
|
25226
|
+
return [
|
|
25227
|
+
{
|
|
25228
|
+
finish_reason: finishReason ?? "stop",
|
|
25229
|
+
index: 0,
|
|
25230
|
+
message: {
|
|
25231
|
+
content: text,
|
|
25232
|
+
...reasoning ? { reasoning } : {},
|
|
25233
|
+
role: "assistant",
|
|
25234
|
+
...toolCalls?.length ? {
|
|
25235
|
+
tool_calls: toolCalls.map((toolCall) => ({
|
|
25236
|
+
function: {
|
|
25237
|
+
arguments: toolCall.args === void 0 ? "{}" : JSON.stringify(toolCall.args),
|
|
25238
|
+
name: toolCall.toolName ?? "unknown"
|
|
25239
|
+
},
|
|
25240
|
+
...toolCall.toolCallId ? { id: toolCall.toolCallId } : {},
|
|
25241
|
+
type: "function"
|
|
25242
|
+
}))
|
|
25243
|
+
} : {}
|
|
25244
|
+
}
|
|
25245
|
+
}
|
|
25246
|
+
];
|
|
25247
|
+
}
|
|
25248
|
+
function startFlueSpan(parent, args) {
|
|
25249
|
+
return parent ? withCurrent(parent, () => startSpan(args)) : startSpan(args);
|
|
25250
|
+
}
|
|
25251
|
+
function safeLog3(span, event) {
|
|
25252
|
+
try {
|
|
25253
|
+
span.log(event);
|
|
25254
|
+
} catch (error) {
|
|
25255
|
+
logInstrumentationError3("Flue span log", error);
|
|
25256
|
+
}
|
|
25257
|
+
}
|
|
25258
|
+
function errorToString(error) {
|
|
25259
|
+
if (error instanceof Error) {
|
|
25260
|
+
return error.message;
|
|
25261
|
+
}
|
|
25262
|
+
if (typeof error === "string") {
|
|
25263
|
+
return error;
|
|
25264
|
+
}
|
|
25265
|
+
try {
|
|
25266
|
+
return JSON.stringify(error);
|
|
25267
|
+
} catch {
|
|
25268
|
+
return String(error);
|
|
25269
|
+
}
|
|
25270
|
+
}
|
|
25271
|
+
function logInstrumentationError3(label, error) {
|
|
25272
|
+
console.error(`Error in ${label} instrumentation:`, error);
|
|
25273
|
+
}
|
|
25274
|
+
|
|
25275
|
+
// src/wrappers/langchain/callback-handler.ts
|
|
25276
|
+
var BRAINTRUST_LANGCHAIN_CALLBACK_HANDLER_NAME = "BraintrustCallbackHandler";
|
|
25277
|
+
var BraintrustLangChainCallbackHandler = class {
|
|
25278
|
+
name = BRAINTRUST_LANGCHAIN_CALLBACK_HANDLER_NAME;
|
|
25279
|
+
spans = /* @__PURE__ */ new Map();
|
|
25280
|
+
skippedRuns = /* @__PURE__ */ new Set();
|
|
25281
|
+
parent;
|
|
25282
|
+
rootRunId;
|
|
25283
|
+
options;
|
|
25284
|
+
startTimes = /* @__PURE__ */ new Map();
|
|
25285
|
+
firstTokenTimes = /* @__PURE__ */ new Map();
|
|
25286
|
+
ttftMs = /* @__PURE__ */ new Map();
|
|
25287
|
+
constructor(options) {
|
|
25288
|
+
this.parent = options?.parent;
|
|
25289
|
+
this.options = {
|
|
25290
|
+
debug: options?.debug ?? false,
|
|
25291
|
+
excludeMetadataProps: options?.excludeMetadataProps ?? /^(l[sc]_|langgraph_|__pregel_|checkpoint_ns)/,
|
|
25292
|
+
logger: options?.logger
|
|
25293
|
+
};
|
|
25294
|
+
}
|
|
25295
|
+
startSpan({
|
|
25296
|
+
runId,
|
|
25297
|
+
parentRunId,
|
|
25298
|
+
...args
|
|
25299
|
+
}) {
|
|
25300
|
+
if (this.spans.has(runId)) {
|
|
25301
|
+
return;
|
|
25302
|
+
}
|
|
25303
|
+
if (!parentRunId) {
|
|
25304
|
+
this.rootRunId = runId;
|
|
25305
|
+
}
|
|
25306
|
+
const tags = args.event?.tags;
|
|
25307
|
+
const spanAttributes = args.spanAttributes || {};
|
|
25308
|
+
spanAttributes.type = args.type || spanAttributes.type || "task";
|
|
25309
|
+
args.type = spanAttributes.type;
|
|
25310
|
+
const currentParent = (typeof this.parent === "function" ? this.parent() : this.parent) ?? currentSpan();
|
|
25311
|
+
let parentSpan;
|
|
25312
|
+
if (parentRunId && this.spans.has(parentRunId)) {
|
|
25313
|
+
parentSpan = this.spans.get(parentRunId);
|
|
25314
|
+
} else if (!Object.is(currentParent, NOOP_SPAN)) {
|
|
25315
|
+
parentSpan = currentParent;
|
|
25316
|
+
} else if (this.options.logger) {
|
|
25317
|
+
parentSpan = this.options.logger;
|
|
25318
|
+
} else {
|
|
25319
|
+
parentSpan = { startSpan };
|
|
25320
|
+
}
|
|
25321
|
+
args.event = {
|
|
25322
|
+
...args.event,
|
|
25323
|
+
tags: void 0,
|
|
25324
|
+
metadata: {
|
|
25325
|
+
...tags ? { tags } : {},
|
|
25326
|
+
...args.event?.metadata,
|
|
25327
|
+
braintrust: {
|
|
25328
|
+
integration_name: "langchain-js",
|
|
25329
|
+
sdk_language: "javascript"
|
|
25330
|
+
},
|
|
25331
|
+
run_id: runId,
|
|
25332
|
+
parent_run_id: parentRunId,
|
|
25333
|
+
...this.options.debug ? { runId, parentRunId } : {}
|
|
25334
|
+
}
|
|
25335
|
+
};
|
|
25336
|
+
let span = parentSpan.startSpan(args);
|
|
25337
|
+
if (!Object.is(this.options.logger, NOOP_SPAN) && Object.is(span, NOOP_SPAN)) {
|
|
25338
|
+
span = initLogger().startSpan(args);
|
|
25339
|
+
}
|
|
25340
|
+
this.spans.set(runId, span);
|
|
25341
|
+
}
|
|
25342
|
+
endSpan({
|
|
25343
|
+
runId,
|
|
25344
|
+
parentRunId,
|
|
25345
|
+
tags,
|
|
25346
|
+
metadata,
|
|
25347
|
+
...args
|
|
25348
|
+
}) {
|
|
25349
|
+
if (!this.spans.has(runId)) {
|
|
25350
|
+
return;
|
|
25351
|
+
}
|
|
25352
|
+
if (this.skippedRuns.has(runId)) {
|
|
25353
|
+
this.skippedRuns.delete(runId);
|
|
25354
|
+
return;
|
|
25355
|
+
}
|
|
25356
|
+
const span = this.spans.get(runId);
|
|
25357
|
+
this.spans.delete(runId);
|
|
25358
|
+
if (runId === this.rootRunId) {
|
|
25359
|
+
this.rootRunId = void 0;
|
|
25360
|
+
}
|
|
25361
|
+
span.log({ ...args, metadata: { tags, ...metadata } });
|
|
25362
|
+
span.end();
|
|
25363
|
+
}
|
|
25364
|
+
async handleLLMStart(llm, prompts, runId, parentRunId, extraParams, tags, metadata, runName) {
|
|
25365
|
+
this.startSpan({
|
|
25366
|
+
runId,
|
|
25367
|
+
parentRunId,
|
|
25368
|
+
name: runName ?? getSerializedName(llm) ?? "LLM",
|
|
25369
|
+
type: "llm",
|
|
25370
|
+
event: {
|
|
25371
|
+
input: prompts,
|
|
25372
|
+
tags,
|
|
25373
|
+
metadata: {
|
|
25374
|
+
serialized: llm,
|
|
25375
|
+
name: runName,
|
|
25376
|
+
metadata,
|
|
25377
|
+
...extraParams
|
|
25378
|
+
}
|
|
25379
|
+
}
|
|
25380
|
+
});
|
|
25381
|
+
}
|
|
25382
|
+
async handleLLMError(err, runId, parentRunId, tags) {
|
|
25383
|
+
this.endSpan({ runId, parentRunId, error: err, tags });
|
|
25384
|
+
}
|
|
25385
|
+
async handleLLMEnd(output, runId, parentRunId, tags) {
|
|
25386
|
+
const metrics = getMetricsFromResponse(output);
|
|
25387
|
+
const modelName2 = getModelNameFromResponse(output);
|
|
25388
|
+
const ttft = this.ttftMs.get(runId);
|
|
25389
|
+
if (ttft !== void 0) {
|
|
25390
|
+
metrics.time_to_first_token = ttft;
|
|
25391
|
+
}
|
|
25392
|
+
this.startTimes.delete(runId);
|
|
25393
|
+
this.firstTokenTimes.delete(runId);
|
|
25394
|
+
this.ttftMs.delete(runId);
|
|
25395
|
+
this.endSpan({
|
|
25396
|
+
runId,
|
|
25397
|
+
parentRunId,
|
|
25398
|
+
output,
|
|
25399
|
+
metrics,
|
|
25400
|
+
tags,
|
|
25401
|
+
metadata: {
|
|
25402
|
+
model: modelName2
|
|
25403
|
+
}
|
|
25404
|
+
});
|
|
25405
|
+
}
|
|
25406
|
+
async handleChatModelStart(llm, messages, runId, parentRunId, extraParams, tags, metadata, runName) {
|
|
25407
|
+
this.startTimes.set(runId, Date.now());
|
|
25408
|
+
this.firstTokenTimes.delete(runId);
|
|
25409
|
+
this.ttftMs.delete(runId);
|
|
25410
|
+
this.startSpan({
|
|
25411
|
+
runId,
|
|
25412
|
+
parentRunId,
|
|
25413
|
+
name: runName ?? getSerializedName(llm) ?? "Chat Model",
|
|
25414
|
+
type: "llm",
|
|
25415
|
+
event: {
|
|
25416
|
+
input: messages,
|
|
25417
|
+
tags,
|
|
25418
|
+
metadata: {
|
|
25419
|
+
serialized: llm,
|
|
25420
|
+
name: runName,
|
|
25421
|
+
metadata,
|
|
25422
|
+
...extraParams
|
|
25423
|
+
}
|
|
25424
|
+
}
|
|
25425
|
+
});
|
|
25426
|
+
}
|
|
25427
|
+
async handleChainStart(chain, inputs, runId, parentRunId, tags, metadata, runType, runName) {
|
|
25428
|
+
if (tags?.includes("langsmith:hidden")) {
|
|
25429
|
+
this.skippedRuns.add(runId);
|
|
25430
|
+
return;
|
|
25431
|
+
}
|
|
25432
|
+
this.startSpan({
|
|
25433
|
+
runId,
|
|
25434
|
+
parentRunId,
|
|
25435
|
+
name: runName ?? getSerializedName(chain) ?? "Chain",
|
|
25436
|
+
event: {
|
|
25437
|
+
input: inputs,
|
|
25438
|
+
tags,
|
|
25439
|
+
metadata: {
|
|
25440
|
+
serialized: chain,
|
|
25441
|
+
name: runName,
|
|
25442
|
+
metadata,
|
|
25443
|
+
run_type: runType
|
|
25444
|
+
}
|
|
25445
|
+
}
|
|
25446
|
+
});
|
|
25447
|
+
}
|
|
25448
|
+
async handleChainError(err, runId, parentRunId, tags, kwargs) {
|
|
25449
|
+
this.endSpan({ runId, parentRunId, error: err, tags, metadata: kwargs });
|
|
25450
|
+
}
|
|
25451
|
+
async handleChainEnd(outputs, runId, parentRunId, tags, kwargs) {
|
|
25452
|
+
this.endSpan({
|
|
25453
|
+
runId,
|
|
25454
|
+
parentRunId,
|
|
25455
|
+
tags,
|
|
25456
|
+
output: outputs,
|
|
25457
|
+
metadata: { ...kwargs }
|
|
25458
|
+
});
|
|
25459
|
+
}
|
|
25460
|
+
async handleToolStart(tool, input, runId, parentRunId, tags, metadata, runName) {
|
|
25461
|
+
this.startSpan({
|
|
25462
|
+
runId,
|
|
25463
|
+
parentRunId,
|
|
25464
|
+
name: runName ?? getSerializedName(tool) ?? "Tool",
|
|
25465
|
+
type: "llm",
|
|
25466
|
+
event: {
|
|
25467
|
+
input: safeJsonParse(input),
|
|
25468
|
+
tags,
|
|
25469
|
+
metadata: {
|
|
25470
|
+
metadata,
|
|
25471
|
+
serialized: tool,
|
|
25472
|
+
input_str: input,
|
|
25473
|
+
input: safeJsonParse(input),
|
|
25474
|
+
name: runName
|
|
25475
|
+
}
|
|
25476
|
+
}
|
|
25477
|
+
});
|
|
25478
|
+
}
|
|
25479
|
+
async handleToolError(err, runId, parentRunId, tags) {
|
|
25480
|
+
this.endSpan({ runId, parentRunId, error: err, tags });
|
|
25481
|
+
}
|
|
25482
|
+
async handleToolEnd(output, runId, parentRunId, tags) {
|
|
25483
|
+
this.endSpan({ runId, parentRunId, output, tags });
|
|
25484
|
+
}
|
|
25485
|
+
async handleAgentAction(action, runId, parentRunId, tags) {
|
|
25486
|
+
this.startSpan({
|
|
25487
|
+
runId,
|
|
25488
|
+
parentRunId,
|
|
25489
|
+
type: "llm",
|
|
25490
|
+
name: typeof action.tool === "string" ? action.tool : "Agent",
|
|
25491
|
+
event: {
|
|
25492
|
+
input: action,
|
|
25493
|
+
tags
|
|
25494
|
+
}
|
|
25495
|
+
});
|
|
25496
|
+
}
|
|
25497
|
+
async handleAgentEnd(action, runId, parentRunId, tags) {
|
|
25498
|
+
this.endSpan({ runId, parentRunId, output: action, tags });
|
|
25499
|
+
}
|
|
25500
|
+
async handleRetrieverStart(retriever, query, runId, parentRunId, tags, metadata, name) {
|
|
25501
|
+
this.startSpan({
|
|
25502
|
+
runId,
|
|
25503
|
+
parentRunId,
|
|
25504
|
+
name: name ?? getSerializedName(retriever) ?? "Retriever",
|
|
25505
|
+
type: "function",
|
|
25506
|
+
event: {
|
|
25507
|
+
input: query,
|
|
25508
|
+
tags,
|
|
25509
|
+
metadata: {
|
|
25510
|
+
serialized: retriever,
|
|
25511
|
+
metadata,
|
|
25512
|
+
name
|
|
25513
|
+
}
|
|
25514
|
+
}
|
|
25515
|
+
});
|
|
25516
|
+
}
|
|
25517
|
+
async handleRetrieverEnd(documents, runId, parentRunId, tags) {
|
|
25518
|
+
this.endSpan({ runId, parentRunId, output: documents, tags });
|
|
25519
|
+
}
|
|
25520
|
+
async handleRetrieverError(err, runId, parentRunId, tags) {
|
|
25521
|
+
this.endSpan({ runId, parentRunId, error: err, tags });
|
|
25522
|
+
}
|
|
25523
|
+
async handleLLMNewToken(_token, _idx, runId, _parentRunId, _tags) {
|
|
25524
|
+
if (!this.firstTokenTimes.has(runId)) {
|
|
25525
|
+
const now2 = Date.now();
|
|
25526
|
+
this.firstTokenTimes.set(runId, now2);
|
|
25527
|
+
const start = this.startTimes.get(runId);
|
|
25528
|
+
if (start !== void 0) {
|
|
25529
|
+
this.ttftMs.set(runId, (now2 - start) / 1e3);
|
|
25530
|
+
}
|
|
25531
|
+
}
|
|
25532
|
+
}
|
|
25533
|
+
};
|
|
25534
|
+
function getSerializedName(serialized) {
|
|
25535
|
+
if (typeof serialized.name === "string") {
|
|
25536
|
+
return serialized.name;
|
|
25537
|
+
}
|
|
25538
|
+
const lastIdPart = serialized.id?.at(-1);
|
|
25539
|
+
return typeof lastIdPart === "string" ? lastIdPart : void 0;
|
|
25540
|
+
}
|
|
25541
|
+
function cleanObject(obj) {
|
|
25542
|
+
return Object.fromEntries(
|
|
25543
|
+
Object.entries(obj).filter(([, value]) => {
|
|
25544
|
+
if (typeof value !== "number") {
|
|
25545
|
+
return false;
|
|
25546
|
+
}
|
|
25547
|
+
return Number.isFinite(value);
|
|
25548
|
+
})
|
|
25549
|
+
);
|
|
25550
|
+
}
|
|
25551
|
+
function walkGenerations(response) {
|
|
25552
|
+
const result = [];
|
|
25553
|
+
const generations = response.generations || [];
|
|
25554
|
+
for (const batch of generations) {
|
|
25555
|
+
if (Array.isArray(batch)) {
|
|
25556
|
+
for (const generation of batch) {
|
|
25557
|
+
if (isRecord(generation)) {
|
|
25558
|
+
result.push(generation);
|
|
25559
|
+
}
|
|
25560
|
+
}
|
|
25561
|
+
} else if (isRecord(batch)) {
|
|
25562
|
+
result.push(batch);
|
|
25563
|
+
}
|
|
25564
|
+
}
|
|
25565
|
+
return result;
|
|
25566
|
+
}
|
|
25567
|
+
function getModelNameFromResponse(response) {
|
|
25568
|
+
for (const generation of walkGenerations(response)) {
|
|
25569
|
+
const message = generation.message;
|
|
25570
|
+
if (!isRecord(message)) {
|
|
25571
|
+
continue;
|
|
25572
|
+
}
|
|
25573
|
+
const responseMetadata = message.response_metadata;
|
|
25574
|
+
if (!isRecord(responseMetadata)) {
|
|
25575
|
+
continue;
|
|
25576
|
+
}
|
|
25577
|
+
const modelName3 = responseMetadata.model_name ?? responseMetadata.model;
|
|
25578
|
+
if (typeof modelName3 === "string") {
|
|
25579
|
+
return modelName3;
|
|
25580
|
+
}
|
|
25581
|
+
}
|
|
25582
|
+
const llmOutput = response.llmOutput || {};
|
|
25583
|
+
const modelName2 = llmOutput.model_name ?? llmOutput.model;
|
|
25584
|
+
return typeof modelName2 === "string" ? modelName2 : void 0;
|
|
25585
|
+
}
|
|
25586
|
+
function getMetricsFromResponse(response) {
|
|
25587
|
+
for (const generation of walkGenerations(response)) {
|
|
25588
|
+
const message = generation.message;
|
|
25589
|
+
if (!isRecord(message)) {
|
|
25590
|
+
continue;
|
|
25591
|
+
}
|
|
25592
|
+
const usageMetadata = message.usage_metadata;
|
|
25593
|
+
if (!isRecord(usageMetadata)) {
|
|
25594
|
+
continue;
|
|
25595
|
+
}
|
|
25596
|
+
const inputTokenDetails = usageMetadata.input_token_details;
|
|
25597
|
+
return cleanObject({
|
|
25598
|
+
total_tokens: usageMetadata.total_tokens,
|
|
25599
|
+
prompt_tokens: usageMetadata.input_tokens,
|
|
25600
|
+
completion_tokens: usageMetadata.output_tokens,
|
|
25601
|
+
prompt_cache_creation_tokens: isRecord(inputTokenDetails) ? inputTokenDetails.cache_creation : void 0,
|
|
25602
|
+
prompt_cached_tokens: isRecord(inputTokenDetails) ? inputTokenDetails.cache_read : void 0
|
|
25603
|
+
});
|
|
25604
|
+
}
|
|
25605
|
+
const llmOutput = response.llmOutput || {};
|
|
25606
|
+
const tokenUsage = isRecord(llmOutput.tokenUsage) ? llmOutput.tokenUsage : isRecord(llmOutput.estimatedTokens) ? llmOutput.estimatedTokens : {};
|
|
25607
|
+
return cleanObject({
|
|
25608
|
+
total_tokens: tokenUsage.totalTokens,
|
|
25609
|
+
prompt_tokens: tokenUsage.promptTokens,
|
|
25610
|
+
completion_tokens: tokenUsage.completionTokens
|
|
25611
|
+
});
|
|
25612
|
+
}
|
|
25613
|
+
function safeJsonParse(input) {
|
|
25614
|
+
try {
|
|
25615
|
+
return JSON.parse(input);
|
|
25616
|
+
} catch {
|
|
25617
|
+
return input;
|
|
25618
|
+
}
|
|
25619
|
+
}
|
|
25620
|
+
function isRecord(value) {
|
|
25621
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
25622
|
+
}
|
|
25623
|
+
|
|
25624
|
+
// src/instrumentation/plugins/langchain-channels.ts
|
|
25625
|
+
var langChainChannels = defineChannels("@langchain/core", {
|
|
25626
|
+
configure: channel({
|
|
25627
|
+
channelName: "CallbackManager.configure",
|
|
25628
|
+
kind: "sync-stream"
|
|
25629
|
+
}),
|
|
25630
|
+
configureSync: channel({
|
|
25631
|
+
channelName: "CallbackManager._configureSync",
|
|
25632
|
+
kind: "sync-stream"
|
|
25633
|
+
})
|
|
25634
|
+
});
|
|
25635
|
+
|
|
25636
|
+
// src/instrumentation/plugins/langchain-plugin.ts
|
|
25637
|
+
var LangChainPlugin = class extends BasePlugin {
|
|
25638
|
+
injectedManagers = /* @__PURE__ */ new WeakSet();
|
|
25639
|
+
onEnable() {
|
|
25640
|
+
this.subscribeToConfigure(langChainChannels.configure);
|
|
25641
|
+
this.subscribeToConfigure(langChainChannels.configureSync);
|
|
25642
|
+
}
|
|
25643
|
+
onDisable() {
|
|
25644
|
+
for (const unsubscribe of this.unsubscribers) {
|
|
25645
|
+
unsubscribe();
|
|
25646
|
+
}
|
|
25647
|
+
this.unsubscribers = [];
|
|
25648
|
+
this.injectedManagers = /* @__PURE__ */ new WeakSet();
|
|
25649
|
+
}
|
|
25650
|
+
subscribeToConfigure(channel2) {
|
|
25651
|
+
const tracingChannel2 = channel2.tracingChannel();
|
|
25652
|
+
const handlers = {
|
|
25653
|
+
start: (event) => {
|
|
25654
|
+
injectHandlerIntoArguments(event.arguments);
|
|
25655
|
+
},
|
|
25656
|
+
end: (event) => {
|
|
25657
|
+
this.injectHandler(event.result);
|
|
25658
|
+
}
|
|
25659
|
+
};
|
|
25660
|
+
tracingChannel2.subscribe(handlers);
|
|
25661
|
+
this.unsubscribers.push(() => {
|
|
25662
|
+
tracingChannel2.unsubscribe(handlers);
|
|
25663
|
+
});
|
|
25664
|
+
}
|
|
25665
|
+
injectHandler(result) {
|
|
25666
|
+
if (!isCallbackManager(result)) {
|
|
25667
|
+
return;
|
|
25668
|
+
}
|
|
25669
|
+
if (this.injectedManagers.has(result) || hasBraintrustHandler(result)) {
|
|
25670
|
+
return;
|
|
25671
|
+
}
|
|
25672
|
+
try {
|
|
25673
|
+
result.addHandler(new BraintrustLangChainCallbackHandler(), true);
|
|
25674
|
+
this.injectedManagers.add(result);
|
|
25675
|
+
} catch {
|
|
25676
|
+
}
|
|
25677
|
+
}
|
|
25678
|
+
};
|
|
25679
|
+
function isCallbackManager(value) {
|
|
25680
|
+
if (typeof value !== "object" || value === null) {
|
|
25681
|
+
return false;
|
|
25682
|
+
}
|
|
25683
|
+
const maybeManager = value;
|
|
25684
|
+
return typeof maybeManager.addHandler === "function";
|
|
25685
|
+
}
|
|
25686
|
+
function hasBraintrustHandler(manager) {
|
|
25687
|
+
return manager.handlers?.some((handler) => {
|
|
25688
|
+
if (typeof handler !== "object" || handler === null) {
|
|
25689
|
+
return false;
|
|
25690
|
+
}
|
|
25691
|
+
const name = Reflect.get(handler, "name");
|
|
25692
|
+
return name === BRAINTRUST_LANGCHAIN_CALLBACK_HANDLER_NAME;
|
|
25693
|
+
}) ?? false;
|
|
25694
|
+
}
|
|
25695
|
+
function injectHandlerIntoArguments(args) {
|
|
25696
|
+
if (!isWritableArgumentsObject(args)) {
|
|
25697
|
+
return;
|
|
25698
|
+
}
|
|
25699
|
+
const inheritedHandlers = Reflect.get(args, "0");
|
|
25700
|
+
const handler = new BraintrustLangChainCallbackHandler();
|
|
25701
|
+
if (inheritedHandlers === void 0 || inheritedHandlers === null) {
|
|
25702
|
+
Reflect.set(args, "0", [handler]);
|
|
25703
|
+
return;
|
|
25704
|
+
}
|
|
25705
|
+
if (Array.isArray(inheritedHandlers)) {
|
|
25706
|
+
if (!inheritedHandlers.some(isBraintrustHandler)) {
|
|
25707
|
+
inheritedHandlers.push(handler);
|
|
25708
|
+
}
|
|
25709
|
+
}
|
|
25710
|
+
}
|
|
25711
|
+
function isWritableArgumentsObject(args) {
|
|
25712
|
+
return typeof args === "object" && args !== null;
|
|
25713
|
+
}
|
|
25714
|
+
function isBraintrustHandler(handler) {
|
|
25715
|
+
if (typeof handler !== "object" || handler === null) {
|
|
25716
|
+
return false;
|
|
25717
|
+
}
|
|
25718
|
+
return Reflect.get(handler, "name") === BRAINTRUST_LANGCHAIN_CALLBACK_HANDLER_NAME;
|
|
25719
|
+
}
|
|
25720
|
+
|
|
25721
|
+
// src/instrumentation/braintrust-plugin.ts
|
|
25722
|
+
function getIntegrationConfig(integrations, key) {
|
|
25723
|
+
return integrations[key];
|
|
25724
|
+
}
|
|
25725
|
+
var BraintrustPlugin = class extends BasePlugin {
|
|
25726
|
+
config;
|
|
25727
|
+
openaiPlugin = null;
|
|
25728
|
+
openAICodexPlugin = null;
|
|
25729
|
+
anthropicPlugin = null;
|
|
25730
|
+
aiSDKPlugin = null;
|
|
25731
|
+
claudeAgentSDKPlugin = null;
|
|
25732
|
+
cursorSDKPlugin = null;
|
|
25733
|
+
openAIAgentsPlugin = null;
|
|
25734
|
+
googleGenAIPlugin = null;
|
|
25735
|
+
huggingFacePlugin = null;
|
|
25736
|
+
openRouterPlugin = null;
|
|
25737
|
+
openRouterAgentPlugin = null;
|
|
25738
|
+
mistralPlugin = null;
|
|
25739
|
+
googleADKPlugin = null;
|
|
25740
|
+
coherePlugin = null;
|
|
25741
|
+
groqPlugin = null;
|
|
25742
|
+
genkitPlugin = null;
|
|
25743
|
+
gitHubCopilotPlugin = null;
|
|
25744
|
+
fluePlugin = null;
|
|
25745
|
+
langChainPlugin = null;
|
|
25746
|
+
constructor(config = {}) {
|
|
25747
|
+
super();
|
|
25748
|
+
this.config = config;
|
|
25749
|
+
}
|
|
25750
|
+
onEnable() {
|
|
25751
|
+
const integrations = this.config.integrations || {};
|
|
25752
|
+
if (integrations.openai !== false) {
|
|
25753
|
+
this.openaiPlugin = new OpenAIPlugin();
|
|
25754
|
+
this.openaiPlugin.enable();
|
|
25755
|
+
}
|
|
25756
|
+
if (integrations.openaiCodexSDK !== false) {
|
|
25757
|
+
this.openAICodexPlugin = new OpenAICodexPlugin();
|
|
25758
|
+
this.openAICodexPlugin.enable();
|
|
23568
25759
|
}
|
|
23569
25760
|
if (integrations.anthropic !== false) {
|
|
23570
25761
|
this.anthropicPlugin = new AnthropicPlugin();
|
|
@@ -23582,6 +25773,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
23582
25773
|
this.cursorSDKPlugin = new CursorSDKPlugin();
|
|
23583
25774
|
this.cursorSDKPlugin.enable();
|
|
23584
25775
|
}
|
|
25776
|
+
if (integrations.openAIAgents !== false) {
|
|
25777
|
+
this.openAIAgentsPlugin = new OpenAIAgentsPlugin();
|
|
25778
|
+
this.openAIAgentsPlugin.enable();
|
|
25779
|
+
}
|
|
23585
25780
|
if (integrations.googleGenAI !== false && integrations.google !== false) {
|
|
23586
25781
|
this.googleGenAIPlugin = new GoogleGenAIPlugin();
|
|
23587
25782
|
this.googleGenAIPlugin.enable();
|
|
@@ -23622,6 +25817,14 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
23622
25817
|
this.gitHubCopilotPlugin = new GitHubCopilotPlugin();
|
|
23623
25818
|
this.gitHubCopilotPlugin.enable();
|
|
23624
25819
|
}
|
|
25820
|
+
if (getIntegrationConfig(integrations, "flue") !== false) {
|
|
25821
|
+
this.fluePlugin = new FluePlugin();
|
|
25822
|
+
this.fluePlugin.enable();
|
|
25823
|
+
}
|
|
25824
|
+
if (integrations.langchain !== false && integrations.langgraph !== false) {
|
|
25825
|
+
this.langChainPlugin = new LangChainPlugin();
|
|
25826
|
+
this.langChainPlugin.enable();
|
|
25827
|
+
}
|
|
23625
25828
|
}
|
|
23626
25829
|
onDisable() {
|
|
23627
25830
|
if (this.openaiPlugin) {
|
|
@@ -23648,6 +25851,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
23648
25851
|
this.cursorSDKPlugin.disable();
|
|
23649
25852
|
this.cursorSDKPlugin = null;
|
|
23650
25853
|
}
|
|
25854
|
+
if (this.openAIAgentsPlugin) {
|
|
25855
|
+
this.openAIAgentsPlugin.disable();
|
|
25856
|
+
this.openAIAgentsPlugin = null;
|
|
25857
|
+
}
|
|
23651
25858
|
if (this.googleGenAIPlugin) {
|
|
23652
25859
|
this.googleGenAIPlugin.disable();
|
|
23653
25860
|
this.googleGenAIPlugin = null;
|
|
@@ -23688,9 +25895,104 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
23688
25895
|
this.gitHubCopilotPlugin.disable();
|
|
23689
25896
|
this.gitHubCopilotPlugin = null;
|
|
23690
25897
|
}
|
|
25898
|
+
if (this.fluePlugin) {
|
|
25899
|
+
this.fluePlugin.disable();
|
|
25900
|
+
this.fluePlugin = null;
|
|
25901
|
+
}
|
|
25902
|
+
if (this.langChainPlugin) {
|
|
25903
|
+
this.langChainPlugin.disable();
|
|
25904
|
+
this.langChainPlugin = null;
|
|
25905
|
+
}
|
|
23691
25906
|
}
|
|
23692
25907
|
};
|
|
23693
25908
|
|
|
25909
|
+
// src/instrumentation/config.ts
|
|
25910
|
+
var envIntegrationAliases = {
|
|
25911
|
+
openai: "openai",
|
|
25912
|
+
"openai-codex": "openaiCodexSDK",
|
|
25913
|
+
"openai-codex-sdk": "openaiCodexSDK",
|
|
25914
|
+
openaicodexsdk: "openaiCodexSDK",
|
|
25915
|
+
codex: "openaiCodexSDK",
|
|
25916
|
+
"codex-sdk": "openaiCodexSDK",
|
|
25917
|
+
anthropic: "anthropic",
|
|
25918
|
+
aisdk: "aisdk",
|
|
25919
|
+
"ai-sdk": "aisdk",
|
|
25920
|
+
"vercel-ai": "aisdk",
|
|
25921
|
+
vercel: "vercel",
|
|
25922
|
+
claudeagentsdk: "claudeAgentSDK",
|
|
25923
|
+
"claude-agent-sdk": "claudeAgentSDK",
|
|
25924
|
+
cursor: "cursor",
|
|
25925
|
+
"cursor-sdk": "cursorSDK",
|
|
25926
|
+
cursorsdk: "cursorSDK",
|
|
25927
|
+
flue: "flue",
|
|
25928
|
+
"flue-runtime": "flue",
|
|
25929
|
+
"openai-agents": "openAIAgents",
|
|
25930
|
+
openaiagents: "openAIAgents",
|
|
25931
|
+
"openai-agents-core": "openAIAgents",
|
|
25932
|
+
openaiagentscore: "openAIAgents",
|
|
25933
|
+
google: "google",
|
|
25934
|
+
"google-genai": "googleGenAI",
|
|
25935
|
+
googlegenai: "googleGenAI",
|
|
25936
|
+
huggingface: "huggingface",
|
|
25937
|
+
openrouter: "openrouter",
|
|
25938
|
+
openrouteragent: "openrouterAgent",
|
|
25939
|
+
"openrouter-agent": "openrouterAgent",
|
|
25940
|
+
mistral: "mistral",
|
|
25941
|
+
googleadk: "googleADK",
|
|
25942
|
+
"google-adk": "googleADK",
|
|
25943
|
+
cohere: "cohere",
|
|
25944
|
+
groq: "groq",
|
|
25945
|
+
"groq-sdk": "groq",
|
|
25946
|
+
genkit: "genkit",
|
|
25947
|
+
"firebase-genkit": "genkit",
|
|
25948
|
+
githubcopilot: "gitHubCopilot",
|
|
25949
|
+
"github-copilot": "gitHubCopilot",
|
|
25950
|
+
"copilot-sdk": "gitHubCopilot",
|
|
25951
|
+
langchain: "langchain",
|
|
25952
|
+
"langchain-js": "langchain",
|
|
25953
|
+
"@langchain": "langchain",
|
|
25954
|
+
langgraph: "langgraph"
|
|
25955
|
+
};
|
|
25956
|
+
function getDefaultInstrumentationIntegrations() {
|
|
25957
|
+
return {
|
|
25958
|
+
openai: true,
|
|
25959
|
+
openaiCodexSDK: true,
|
|
25960
|
+
anthropic: true,
|
|
25961
|
+
vercel: true,
|
|
25962
|
+
aisdk: true,
|
|
25963
|
+
google: true,
|
|
25964
|
+
googleGenAI: true,
|
|
25965
|
+
googleADK: true,
|
|
25966
|
+
huggingface: true,
|
|
25967
|
+
claudeAgentSDK: true,
|
|
25968
|
+
cursor: true,
|
|
25969
|
+
cursorSDK: true,
|
|
25970
|
+
flue: true,
|
|
25971
|
+
openAIAgents: true,
|
|
25972
|
+
openrouter: true,
|
|
25973
|
+
openrouterAgent: true,
|
|
25974
|
+
mistral: true,
|
|
25975
|
+
cohere: true,
|
|
25976
|
+
groq: true,
|
|
25977
|
+
genkit: true,
|
|
25978
|
+
gitHubCopilot: true,
|
|
25979
|
+
langchain: true,
|
|
25980
|
+
langgraph: true
|
|
25981
|
+
};
|
|
25982
|
+
}
|
|
25983
|
+
function readDisabledInstrumentationEnvConfig(disabledList) {
|
|
25984
|
+
const integrations = {};
|
|
25985
|
+
if (disabledList) {
|
|
25986
|
+
for (const value of disabledList.split(",")) {
|
|
25987
|
+
const sdk = value.trim().toLowerCase();
|
|
25988
|
+
if (sdk.length > 0) {
|
|
25989
|
+
integrations[envIntegrationAliases[sdk] ?? sdk] = false;
|
|
25990
|
+
}
|
|
25991
|
+
}
|
|
25992
|
+
}
|
|
25993
|
+
return { integrations };
|
|
25994
|
+
}
|
|
25995
|
+
|
|
23694
25996
|
// src/instrumentation/registry.ts
|
|
23695
25997
|
var REGISTRY_STATE_KEY = /* @__PURE__ */ Symbol.for("braintrust.registry");
|
|
23696
25998
|
function getSharedState() {
|
|
@@ -23769,50 +26071,16 @@ var PluginRegistry = class {
|
|
|
23769
26071
|
* Get default configuration (all integrations enabled).
|
|
23770
26072
|
*/
|
|
23771
26073
|
getDefaultConfig() {
|
|
23772
|
-
return
|
|
23773
|
-
openai: true,
|
|
23774
|
-
openaiCodexSDK: true,
|
|
23775
|
-
anthropic: true,
|
|
23776
|
-
vercel: true,
|
|
23777
|
-
aisdk: true,
|
|
23778
|
-
google: true,
|
|
23779
|
-
googleGenAI: true,
|
|
23780
|
-
googleADK: true,
|
|
23781
|
-
huggingface: true,
|
|
23782
|
-
claudeAgentSDK: true,
|
|
23783
|
-
cursor: true,
|
|
23784
|
-
cursorSDK: true,
|
|
23785
|
-
openrouter: true,
|
|
23786
|
-
openrouterAgent: true,
|
|
23787
|
-
mistral: true,
|
|
23788
|
-
cohere: true,
|
|
23789
|
-
groq: true,
|
|
23790
|
-
genkit: true,
|
|
23791
|
-
gitHubCopilot: true
|
|
23792
|
-
};
|
|
26074
|
+
return getDefaultInstrumentationIntegrations();
|
|
23793
26075
|
}
|
|
23794
26076
|
/**
|
|
23795
26077
|
* Read configuration from environment variables.
|
|
23796
26078
|
* Supports: BRAINTRUST_DISABLE_INSTRUMENTATION=openai,anthropic,...
|
|
23797
26079
|
*/
|
|
23798
26080
|
readEnvConfig() {
|
|
23799
|
-
|
|
23800
|
-
|
|
23801
|
-
|
|
23802
|
-
const disabled = disabledList.split(",").map((s) => s.trim().toLowerCase()).filter((s) => s.length > 0);
|
|
23803
|
-
for (const sdk of disabled) {
|
|
23804
|
-
if (sdk === "cursor-sdk") {
|
|
23805
|
-
integrations.cursorSDK = false;
|
|
23806
|
-
} else if (sdk === "githubcopilot" || sdk === "github-copilot" || sdk === "copilot-sdk") {
|
|
23807
|
-
integrations.gitHubCopilot = false;
|
|
23808
|
-
} else if (sdk === "openai-codex-sdk") {
|
|
23809
|
-
integrations.openaiCodexSDK = false;
|
|
23810
|
-
} else {
|
|
23811
|
-
integrations[sdk] = false;
|
|
23812
|
-
}
|
|
23813
|
-
}
|
|
23814
|
-
}
|
|
23815
|
-
return { integrations };
|
|
26081
|
+
return readDisabledInstrumentationEnvConfig(
|
|
26082
|
+
isomorph_default.getEnv("BRAINTRUST_DISABLE_INSTRUMENTATION")
|
|
26083
|
+
);
|
|
23816
26084
|
}
|
|
23817
26085
|
};
|
|
23818
26086
|
var registry = new PluginRegistry();
|
|
@@ -23948,8 +26216,10 @@ __export(exports_exports, {
|
|
|
23948
26216
|
Attachment: () => Attachment,
|
|
23949
26217
|
AttachmentReference: () => AttachmentReference,
|
|
23950
26218
|
BRAINTRUST_CURRENT_SPAN_STORE: () => BRAINTRUST_CURRENT_SPAN_STORE,
|
|
26219
|
+
BRAINTRUST_LANGCHAIN_CALLBACK_HANDLER_NAME: () => BRAINTRUST_LANGCHAIN_CALLBACK_HANDLER_NAME,
|
|
23951
26220
|
BaseAttachment: () => BaseAttachment,
|
|
23952
26221
|
BaseExperiment: () => BaseExperiment,
|
|
26222
|
+
BraintrustLangChainCallbackHandler: () => BraintrustLangChainCallbackHandler,
|
|
23953
26223
|
BraintrustMiddleware: () => BraintrustMiddleware,
|
|
23954
26224
|
BraintrustState: () => BraintrustState,
|
|
23955
26225
|
BraintrustStream: () => BraintrustStream,
|
|
@@ -24075,6 +26345,8 @@ __export(exports_exports, {
|
|
|
24075
26345
|
wrapCohere: () => wrapCohere,
|
|
24076
26346
|
wrapCopilotClient: () => wrapCopilotClient,
|
|
24077
26347
|
wrapCursorSDK: () => wrapCursorSDK,
|
|
26348
|
+
wrapFlueContext: () => wrapFlueContext,
|
|
26349
|
+
wrapFlueSession: () => wrapFlueSession,
|
|
24078
26350
|
wrapGenkit: () => wrapGenkit,
|
|
24079
26351
|
wrapGoogleADK: () => wrapGoogleADK,
|
|
24080
26352
|
wrapGoogleGenAI: () => wrapGoogleGenAI,
|
|
@@ -25174,7 +27446,7 @@ function extractModelParameters(params, excludeKeys) {
|
|
|
25174
27446
|
}
|
|
25175
27447
|
return modelParams;
|
|
25176
27448
|
}
|
|
25177
|
-
function
|
|
27449
|
+
function getNumberProperty3(obj, key) {
|
|
25178
27450
|
if (!obj || typeof obj !== "object" || !(key in obj)) {
|
|
25179
27451
|
return void 0;
|
|
25180
27452
|
}
|
|
@@ -25183,31 +27455,31 @@ function getNumberProperty2(obj, key) {
|
|
|
25183
27455
|
}
|
|
25184
27456
|
function normalizeUsageMetrics(usage, provider, providerMetadata) {
|
|
25185
27457
|
const metrics = {};
|
|
25186
|
-
const inputTokens =
|
|
27458
|
+
const inputTokens = getNumberProperty3(usage, "inputTokens");
|
|
25187
27459
|
if (inputTokens !== void 0) {
|
|
25188
27460
|
metrics.prompt_tokens = inputTokens;
|
|
25189
27461
|
}
|
|
25190
|
-
const outputTokens =
|
|
27462
|
+
const outputTokens = getNumberProperty3(usage, "outputTokens");
|
|
25191
27463
|
if (outputTokens !== void 0) {
|
|
25192
27464
|
metrics.completion_tokens = outputTokens;
|
|
25193
27465
|
}
|
|
25194
|
-
const totalTokens =
|
|
27466
|
+
const totalTokens = getNumberProperty3(usage, "totalTokens");
|
|
25195
27467
|
if (totalTokens !== void 0) {
|
|
25196
27468
|
metrics.tokens = totalTokens;
|
|
25197
27469
|
}
|
|
25198
|
-
const reasoningTokens =
|
|
27470
|
+
const reasoningTokens = getNumberProperty3(usage, "reasoningTokens");
|
|
25199
27471
|
if (reasoningTokens !== void 0) {
|
|
25200
27472
|
metrics.completion_reasoning_tokens = reasoningTokens;
|
|
25201
27473
|
}
|
|
25202
|
-
const cachedInputTokens =
|
|
27474
|
+
const cachedInputTokens = getNumberProperty3(usage, "cachedInputTokens");
|
|
25203
27475
|
if (cachedInputTokens !== void 0) {
|
|
25204
27476
|
metrics.prompt_cached_tokens = cachedInputTokens;
|
|
25205
27477
|
}
|
|
25206
27478
|
if (provider === "anthropic") {
|
|
25207
27479
|
const anthropicMetadata = providerMetadata?.anthropic;
|
|
25208
27480
|
if (anthropicMetadata) {
|
|
25209
|
-
const cacheReadTokens =
|
|
25210
|
-
const cacheCreationTokens =
|
|
27481
|
+
const cacheReadTokens = getNumberProperty3(anthropicMetadata.usage, "cache_read_input_tokens") || 0;
|
|
27482
|
+
const cacheCreationTokens = getNumberProperty3(
|
|
25211
27483
|
anthropicMetadata.usage,
|
|
25212
27484
|
"cache_creation_input_tokens"
|
|
25213
27485
|
) || 0;
|
|
@@ -26182,17 +28454,17 @@ function wrapGenkit(genkit) {
|
|
|
26182
28454
|
console.warn("Unsupported Genkit object. Not wrapping.");
|
|
26183
28455
|
return genkit;
|
|
26184
28456
|
}
|
|
26185
|
-
function
|
|
28457
|
+
function isRecord2(value) {
|
|
26186
28458
|
return typeof value === "object" && value !== null;
|
|
26187
28459
|
}
|
|
26188
28460
|
function isPropertyBag(value) {
|
|
26189
|
-
return
|
|
28461
|
+
return isRecord2(value) || typeof value === "function";
|
|
26190
28462
|
}
|
|
26191
28463
|
function hasFunction(value, methodName) {
|
|
26192
28464
|
return isPropertyBag(value) && methodName in value && typeof value[methodName] === "function";
|
|
26193
28465
|
}
|
|
26194
28466
|
function isGenkitInstance(value) {
|
|
26195
|
-
return
|
|
28467
|
+
return isRecord2(value) && (hasFunction(value, "generate") || hasFunction(value, "generateStream") || hasFunction(value, "defineFlow") || hasFunction(value, "defineTool"));
|
|
26196
28468
|
}
|
|
26197
28469
|
function isGenkitModule(value) {
|
|
26198
28470
|
return hasFunction(value, "genkit");
|
|
@@ -26246,7 +28518,7 @@ function patchGenkitRegistry(instance) {
|
|
|
26246
28518
|
patchGenkitRegistryConstructor(registry2);
|
|
26247
28519
|
}
|
|
26248
28520
|
function patchGenkitRegistryLookup(registry2) {
|
|
26249
|
-
if (!
|
|
28521
|
+
if (!isRecord2(registry2) || hasRegistryPatchedFlag(registry2) || !hasFunction(registry2, "lookupAction")) {
|
|
26250
28522
|
return;
|
|
26251
28523
|
}
|
|
26252
28524
|
const originalLookupAction = registry2.lookupAction;
|
|
@@ -26272,7 +28544,7 @@ function patchGenkitRegistryLookup(registry2) {
|
|
|
26272
28544
|
}
|
|
26273
28545
|
}
|
|
26274
28546
|
function patchGenkitRegistryConstructor(registry2) {
|
|
26275
|
-
if (!
|
|
28547
|
+
if (!isRecord2(registry2)) {
|
|
26276
28548
|
return;
|
|
26277
28549
|
}
|
|
26278
28550
|
const constructor = registry2.constructor;
|
|
@@ -26288,7 +28560,7 @@ function patchGenkitRegistryConstructor(registry2) {
|
|
|
26288
28560
|
configurable: true,
|
|
26289
28561
|
value: (...args) => {
|
|
26290
28562
|
const childRegistry = originalWithParent.apply(constructor, args);
|
|
26291
|
-
if (args.some((arg) =>
|
|
28563
|
+
if (args.some((arg) => isRecord2(arg) && hasRegistryPatchedFlag(arg))) {
|
|
26292
28564
|
patchGenkitRegistryLookup(childRegistry);
|
|
26293
28565
|
patchGenkitRegistryConstructor(childRegistry);
|
|
26294
28566
|
}
|
|
@@ -26387,7 +28659,7 @@ function hasRegistryConstructorPatchedFlag(value) {
|
|
|
26387
28659
|
);
|
|
26388
28660
|
}
|
|
26389
28661
|
function isPromiseLike2(value) {
|
|
26390
|
-
return
|
|
28662
|
+
return isRecord2(value) && "then" in value && typeof value.then === "function";
|
|
26391
28663
|
}
|
|
26392
28664
|
|
|
26393
28665
|
// src/wrappers/huggingface.ts
|
|
@@ -26750,14 +29022,14 @@ function wrapMistral(mistral) {
|
|
|
26750
29022
|
console.warn("Unsupported Mistral library. Not wrapping.");
|
|
26751
29023
|
return mistral;
|
|
26752
29024
|
}
|
|
26753
|
-
function
|
|
29025
|
+
function isRecord3(value) {
|
|
26754
29026
|
return typeof value === "object" && value !== null;
|
|
26755
29027
|
}
|
|
26756
29028
|
function hasFunction3(value, methodName) {
|
|
26757
|
-
return
|
|
29029
|
+
return isRecord3(value) && methodName in value && typeof value[methodName] === "function";
|
|
26758
29030
|
}
|
|
26759
29031
|
function isSupportedMistralClient(value) {
|
|
26760
|
-
if (!
|
|
29032
|
+
if (!isRecord3(value)) {
|
|
26761
29033
|
return false;
|
|
26762
29034
|
}
|
|
26763
29035
|
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);
|
|
@@ -26941,14 +29213,14 @@ function wrapCohere(cohere) {
|
|
|
26941
29213
|
return cohere;
|
|
26942
29214
|
}
|
|
26943
29215
|
var cohereProxyCache = /* @__PURE__ */ new WeakMap();
|
|
26944
|
-
function
|
|
29216
|
+
function isRecord4(value) {
|
|
26945
29217
|
return typeof value === "object" && value !== null;
|
|
26946
29218
|
}
|
|
26947
29219
|
function hasFunction4(value, methodName) {
|
|
26948
|
-
return
|
|
29220
|
+
return isRecord4(value) && methodName in value && typeof value[methodName] === "function";
|
|
26949
29221
|
}
|
|
26950
29222
|
function isSupportedCohereClient(value) {
|
|
26951
|
-
if (!
|
|
29223
|
+
if (!isRecord4(value)) {
|
|
26952
29224
|
return false;
|
|
26953
29225
|
}
|
|
26954
29226
|
return hasFunction4(value, "chat") || hasFunction4(value, "chatStream") || hasFunction4(value, "embed") || hasFunction4(value, "rerank");
|
|
@@ -27008,20 +29280,20 @@ function wrapGroq(groq) {
|
|
|
27008
29280
|
console.warn("Unsupported Groq library. Not wrapping.");
|
|
27009
29281
|
return groq;
|
|
27010
29282
|
}
|
|
27011
|
-
function
|
|
29283
|
+
function isRecord5(value) {
|
|
27012
29284
|
return typeof value === "object" && value !== null;
|
|
27013
29285
|
}
|
|
27014
29286
|
function hasFunction5(value, methodName) {
|
|
27015
|
-
return
|
|
29287
|
+
return isRecord5(value) && methodName in value && typeof value[methodName] === "function";
|
|
27016
29288
|
}
|
|
27017
29289
|
function hasChat2(value) {
|
|
27018
|
-
return
|
|
29290
|
+
return isRecord5(value) && isRecord5(value.completions) && hasFunction5(value.completions, "create");
|
|
27019
29291
|
}
|
|
27020
29292
|
function hasEmbeddings2(value) {
|
|
27021
29293
|
return hasFunction5(value, "create");
|
|
27022
29294
|
}
|
|
27023
29295
|
function isSupportedGroqClient(value) {
|
|
27024
|
-
return
|
|
29296
|
+
return isRecord5(value) && (value.chat !== void 0 && hasChat2(value.chat) || value.embeddings !== void 0 && hasEmbeddings2(value.embeddings));
|
|
27025
29297
|
}
|
|
27026
29298
|
function groqProxy(groq) {
|
|
27027
29299
|
const privateMethodWorkaroundCache = /* @__PURE__ */ new WeakMap();
|