braintrust 3.5.0 → 3.7.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/dev/dist/index.d.mts +4 -2
- package/dev/dist/index.d.ts +4 -2
- package/dev/dist/index.js +2453 -612
- package/dev/dist/index.mjs +2150 -309
- package/dist/auto-instrumentations/bundler/esbuild.cjs +115 -6
- package/dist/auto-instrumentations/bundler/esbuild.mjs +2 -2
- package/dist/auto-instrumentations/bundler/rollup.cjs +115 -6
- package/dist/auto-instrumentations/bundler/rollup.mjs +2 -2
- package/dist/auto-instrumentations/bundler/vite.cjs +115 -6
- package/dist/auto-instrumentations/bundler/vite.mjs +2 -2
- package/dist/auto-instrumentations/bundler/webpack-loader.cjs +955 -0
- package/dist/auto-instrumentations/bundler/webpack-loader.d.ts +53 -0
- package/dist/auto-instrumentations/bundler/webpack.cjs +115 -6
- package/dist/auto-instrumentations/bundler/webpack.mjs +2 -2
- package/dist/auto-instrumentations/{chunk-DQTPSXJB.mjs → chunk-AKEXR4AL.mjs} +116 -7
- package/dist/auto-instrumentations/{chunk-F3TJZ3Z2.mjs → chunk-ZK2IYER2.mjs} +3 -1
- package/dist/auto-instrumentations/hook.mjs +199 -55
- package/dist/auto-instrumentations/index.cjs +116 -6
- package/dist/auto-instrumentations/index.d.mts +3 -1
- package/dist/auto-instrumentations/index.d.ts +3 -1
- package/dist/auto-instrumentations/index.mjs +3 -1
- package/dist/browser.d.mts +17 -4
- package/dist/browser.d.ts +17 -4
- package/dist/browser.js +2386 -440
- package/dist/browser.mjs +2386 -440
- package/dist/cli.js +2118 -273
- package/dist/edge-light.d.mts +1 -1
- package/dist/edge-light.d.ts +1 -1
- package/dist/edge-light.js +2348 -485
- package/dist/edge-light.mjs +2348 -485
- package/dist/index.d.mts +30 -17
- package/dist/index.d.ts +30 -17
- package/dist/index.js +2709 -761
- package/dist/index.mjs +2392 -444
- package/dist/instrumentation/index.d.mts +3 -0
- package/dist/instrumentation/index.d.ts +3 -0
- package/dist/instrumentation/index.js +2030 -274
- package/dist/instrumentation/index.mjs +2030 -274
- package/dist/workerd.d.mts +1 -1
- package/dist/workerd.d.ts +1 -1
- package/dist/workerd.js +2348 -485
- package/dist/workerd.mjs +2348 -485
- package/package.json +5 -1
package/dist/cli.js
CHANGED
|
@@ -1232,7 +1232,7 @@ var require_package = __commonJS({
|
|
|
1232
1232
|
"package.json"(exports2, module2) {
|
|
1233
1233
|
module2.exports = {
|
|
1234
1234
|
name: "braintrust",
|
|
1235
|
-
version: "3.
|
|
1235
|
+
version: "3.7.0",
|
|
1236
1236
|
description: "SDK for integrating Braintrust",
|
|
1237
1237
|
repository: {
|
|
1238
1238
|
type: "git",
|
|
@@ -1319,6 +1319,10 @@ var require_package = __commonJS({
|
|
|
1319
1319
|
module: "./dist/auto-instrumentations/bundler/webpack.mjs",
|
|
1320
1320
|
require: "./dist/auto-instrumentations/bundler/webpack.js"
|
|
1321
1321
|
},
|
|
1322
|
+
"./webpack-loader": {
|
|
1323
|
+
types: "./dist/auto-instrumentations/bundler/webpack-loader.d.ts",
|
|
1324
|
+
require: "./dist/auto-instrumentations/bundler/webpack-loader.cjs"
|
|
1325
|
+
},
|
|
1322
1326
|
"./esbuild": {
|
|
1323
1327
|
types: "./dist/auto-instrumentations/bundler/esbuild.d.ts",
|
|
1324
1328
|
import: "./dist/auto-instrumentations/bundler/esbuild.mjs",
|
|
@@ -5775,6 +5779,9 @@ var BRAINTRUST_ATTACHMENT = BraintrustAttachmentReference.shape.type.value;
|
|
|
5775
5779
|
var EXTERNAL_ATTACHMENT = ExternalAttachmentReference.shape.type.value;
|
|
5776
5780
|
var LOGS3_OVERFLOW_REFERENCE_TYPE = "logs3_overflow";
|
|
5777
5781
|
var BRAINTRUST_PARAMS = Object.keys(BraintrustModelParams.shape);
|
|
5782
|
+
var RESET_CONTEXT_MANAGER_STATE = Symbol.for(
|
|
5783
|
+
"braintrust.resetContextManagerState"
|
|
5784
|
+
);
|
|
5778
5785
|
var DEFAULT_MAX_REQUEST_SIZE = 6 * 1024 * 1024;
|
|
5779
5786
|
var parametersRowSchema = import_v38.z.object({
|
|
5780
5787
|
id: import_v38.z.string().uuid(),
|
|
@@ -5837,13 +5844,18 @@ function applyMaskingToField(maskingFunction, data, fieldName) {
|
|
|
5837
5844
|
return `ERROR: Failed to mask field '${fieldName}' - ${errorType}`;
|
|
5838
5845
|
}
|
|
5839
5846
|
}
|
|
5847
|
+
var BRAINTRUST_CURRENT_SPAN_STORE = Symbol.for(
|
|
5848
|
+
"braintrust.currentSpanStore"
|
|
5849
|
+
);
|
|
5840
5850
|
var ContextManager = class {
|
|
5841
5851
|
};
|
|
5842
5852
|
var BraintrustContextManager = class extends ContextManager {
|
|
5843
5853
|
_currentSpan;
|
|
5854
|
+
[BRAINTRUST_CURRENT_SPAN_STORE];
|
|
5844
5855
|
constructor() {
|
|
5845
5856
|
super();
|
|
5846
5857
|
this._currentSpan = isomorph_default.newAsyncLocalStorage();
|
|
5858
|
+
this[BRAINTRUST_CURRENT_SPAN_STORE] = this._currentSpan;
|
|
5847
5859
|
}
|
|
5848
5860
|
getParentSpanIds() {
|
|
5849
5861
|
const currentSpan2 = this._currentSpan.getStore();
|
|
@@ -6050,6 +6062,9 @@ var BraintrustState = class _BraintrustState {
|
|
|
6050
6062
|
resetIdGenState() {
|
|
6051
6063
|
this._idGenerator = null;
|
|
6052
6064
|
}
|
|
6065
|
+
[RESET_CONTEXT_MANAGER_STATE]() {
|
|
6066
|
+
this._contextManager = null;
|
|
6067
|
+
}
|
|
6053
6068
|
get idGenerator() {
|
|
6054
6069
|
if (this._idGenerator === null) {
|
|
6055
6070
|
this._idGenerator = getIdGenerator();
|
|
@@ -12596,6 +12611,90 @@ var fancyReporter = {
|
|
|
12596
12611
|
var import_node_async_hooks = require("node:async_hooks");
|
|
12597
12612
|
var diagnostics_channel = __toESM(require("node:diagnostics_channel"));
|
|
12598
12613
|
var path = __toESM(require("node:path"));
|
|
12614
|
+
|
|
12615
|
+
// src/auto-instrumentations/patch-tracing-channel.ts
|
|
12616
|
+
function patchTracingChannel(tracingChannelFn) {
|
|
12617
|
+
const dummyChannel = tracingChannelFn("__braintrust_probe__");
|
|
12618
|
+
const TracingChannel = dummyChannel?.constructor;
|
|
12619
|
+
if (!TracingChannel?.prototype) {
|
|
12620
|
+
return;
|
|
12621
|
+
}
|
|
12622
|
+
if (!Object.getOwnPropertyDescriptor(TracingChannel.prototype, "hasSubscribers")) {
|
|
12623
|
+
Object.defineProperty(TracingChannel.prototype, "hasSubscribers", {
|
|
12624
|
+
configurable: true,
|
|
12625
|
+
enumerable: false,
|
|
12626
|
+
get() {
|
|
12627
|
+
return Boolean(
|
|
12628
|
+
this.start?.hasSubscribers || this.end?.hasSubscribers || this.asyncStart?.hasSubscribers || this.asyncEnd?.hasSubscribers || this.error?.hasSubscribers
|
|
12629
|
+
);
|
|
12630
|
+
}
|
|
12631
|
+
});
|
|
12632
|
+
}
|
|
12633
|
+
if (TracingChannel.prototype.tracePromise) {
|
|
12634
|
+
TracingChannel.prototype.tracePromise = function(fn, context2 = {}, thisArg, ...args) {
|
|
12635
|
+
const { start, end, asyncStart, asyncEnd, error: error2 } = this;
|
|
12636
|
+
function publishRejected(err) {
|
|
12637
|
+
context2.error = err;
|
|
12638
|
+
error2?.publish(context2);
|
|
12639
|
+
asyncStart?.publish(context2);
|
|
12640
|
+
asyncEnd?.publish(context2);
|
|
12641
|
+
}
|
|
12642
|
+
function publishResolved(result) {
|
|
12643
|
+
context2.result = result;
|
|
12644
|
+
asyncStart?.publish(context2);
|
|
12645
|
+
asyncEnd?.publish(context2);
|
|
12646
|
+
}
|
|
12647
|
+
return start.runStores(context2, () => {
|
|
12648
|
+
try {
|
|
12649
|
+
const result = Reflect.apply(fn, thisArg, args);
|
|
12650
|
+
end?.publish(context2);
|
|
12651
|
+
if (result && (typeof result === "object" || typeof result === "function") && typeof result.then === "function") {
|
|
12652
|
+
if (result.constructor === Promise) {
|
|
12653
|
+
return result.then(
|
|
12654
|
+
(res) => {
|
|
12655
|
+
publishResolved(res);
|
|
12656
|
+
return res;
|
|
12657
|
+
},
|
|
12658
|
+
(err) => {
|
|
12659
|
+
publishRejected(err);
|
|
12660
|
+
return Promise.reject(err);
|
|
12661
|
+
}
|
|
12662
|
+
);
|
|
12663
|
+
}
|
|
12664
|
+
void result.then(
|
|
12665
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
12666
|
+
(resolved) => {
|
|
12667
|
+
try {
|
|
12668
|
+
publishResolved(resolved);
|
|
12669
|
+
} catch {
|
|
12670
|
+
}
|
|
12671
|
+
},
|
|
12672
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
12673
|
+
(err) => {
|
|
12674
|
+
try {
|
|
12675
|
+
publishRejected(err);
|
|
12676
|
+
} catch {
|
|
12677
|
+
}
|
|
12678
|
+
}
|
|
12679
|
+
);
|
|
12680
|
+
return result;
|
|
12681
|
+
}
|
|
12682
|
+
context2.result = result;
|
|
12683
|
+
asyncStart?.publish(context2);
|
|
12684
|
+
asyncEnd?.publish(context2);
|
|
12685
|
+
return result;
|
|
12686
|
+
} catch (err) {
|
|
12687
|
+
context2.error = err;
|
|
12688
|
+
error2?.publish(context2);
|
|
12689
|
+
end?.publish(context2);
|
|
12690
|
+
throw err;
|
|
12691
|
+
}
|
|
12692
|
+
});
|
|
12693
|
+
};
|
|
12694
|
+
}
|
|
12695
|
+
}
|
|
12696
|
+
|
|
12697
|
+
// src/node/config.ts
|
|
12599
12698
|
var fs = __toESM(require("node:fs/promises"));
|
|
12600
12699
|
var os = __toESM(require("node:os"));
|
|
12601
12700
|
var fsSync = __toESM(require("node:fs"));
|
|
@@ -13352,6 +13451,36 @@ function startSpanForEvent(config3, event, channelName) {
|
|
|
13352
13451
|
}
|
|
13353
13452
|
return { span, startTime };
|
|
13354
13453
|
}
|
|
13454
|
+
function ensureSpanStateForEvent(states, config3, event, channelName) {
|
|
13455
|
+
const key = event;
|
|
13456
|
+
const existing = states.get(key);
|
|
13457
|
+
if (existing) {
|
|
13458
|
+
return existing;
|
|
13459
|
+
}
|
|
13460
|
+
const created = startSpanForEvent(config3, event, channelName);
|
|
13461
|
+
states.set(key, created);
|
|
13462
|
+
return created;
|
|
13463
|
+
}
|
|
13464
|
+
function bindCurrentSpanStoreToStart(tracingChannel2, states, config3, channelName) {
|
|
13465
|
+
const state = _internalGetGlobalState();
|
|
13466
|
+
const startChannel = tracingChannel2.start;
|
|
13467
|
+
const currentSpanStore = state?.contextManager ? state.contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
|
|
13468
|
+
if (!currentSpanStore || !startChannel) {
|
|
13469
|
+
return void 0;
|
|
13470
|
+
}
|
|
13471
|
+
startChannel.bindStore(
|
|
13472
|
+
currentSpanStore,
|
|
13473
|
+
(event) => ensureSpanStateForEvent(
|
|
13474
|
+
states,
|
|
13475
|
+
config3,
|
|
13476
|
+
event,
|
|
13477
|
+
channelName
|
|
13478
|
+
).span
|
|
13479
|
+
);
|
|
13480
|
+
return () => {
|
|
13481
|
+
startChannel.unbindStore(currentSpanStore);
|
|
13482
|
+
};
|
|
13483
|
+
}
|
|
13355
13484
|
function logErrorAndEnd(states, event) {
|
|
13356
13485
|
const spanData = states.get(event);
|
|
13357
13486
|
if (!spanData) {
|
|
@@ -13367,15 +13496,19 @@ function traceAsyncChannel(channel2, config3) {
|
|
|
13367
13496
|
const tracingChannel2 = channel2.tracingChannel();
|
|
13368
13497
|
const states = /* @__PURE__ */ new WeakMap();
|
|
13369
13498
|
const channelName = channel2.channelName;
|
|
13499
|
+
const unbindCurrentSpanStore = bindCurrentSpanStoreToStart(
|
|
13500
|
+
tracingChannel2,
|
|
13501
|
+
states,
|
|
13502
|
+
config3,
|
|
13503
|
+
channelName
|
|
13504
|
+
);
|
|
13370
13505
|
const handlers = {
|
|
13371
13506
|
start: (event) => {
|
|
13372
|
-
|
|
13507
|
+
ensureSpanStateForEvent(
|
|
13508
|
+
states,
|
|
13509
|
+
config3,
|
|
13373
13510
|
event,
|
|
13374
|
-
|
|
13375
|
-
config3,
|
|
13376
|
-
event,
|
|
13377
|
-
channelName
|
|
13378
|
-
)
|
|
13511
|
+
channelName
|
|
13379
13512
|
);
|
|
13380
13513
|
},
|
|
13381
13514
|
asyncEnd: (event) => {
|
|
@@ -13417,6 +13550,7 @@ function traceAsyncChannel(channel2, config3) {
|
|
|
13417
13550
|
};
|
|
13418
13551
|
tracingChannel2.subscribe(handlers);
|
|
13419
13552
|
return () => {
|
|
13553
|
+
unbindCurrentSpanStore?.();
|
|
13420
13554
|
tracingChannel2.unsubscribe(handlers);
|
|
13421
13555
|
};
|
|
13422
13556
|
}
|
|
@@ -13424,15 +13558,19 @@ function traceStreamingChannel(channel2, config3) {
|
|
|
13424
13558
|
const tracingChannel2 = channel2.tracingChannel();
|
|
13425
13559
|
const states = /* @__PURE__ */ new WeakMap();
|
|
13426
13560
|
const channelName = channel2.channelName;
|
|
13561
|
+
const unbindCurrentSpanStore = bindCurrentSpanStoreToStart(
|
|
13562
|
+
tracingChannel2,
|
|
13563
|
+
states,
|
|
13564
|
+
config3,
|
|
13565
|
+
channelName
|
|
13566
|
+
);
|
|
13427
13567
|
const handlers = {
|
|
13428
13568
|
start: (event) => {
|
|
13429
|
-
|
|
13569
|
+
ensureSpanStateForEvent(
|
|
13570
|
+
states,
|
|
13571
|
+
config3,
|
|
13430
13572
|
event,
|
|
13431
|
-
|
|
13432
|
-
config3,
|
|
13433
|
-
event,
|
|
13434
|
-
channelName
|
|
13435
|
-
)
|
|
13573
|
+
channelName
|
|
13436
13574
|
);
|
|
13437
13575
|
},
|
|
13438
13576
|
asyncEnd: (event) => {
|
|
@@ -13548,6 +13686,7 @@ function traceStreamingChannel(channel2, config3) {
|
|
|
13548
13686
|
};
|
|
13549
13687
|
tracingChannel2.subscribe(handlers);
|
|
13550
13688
|
return () => {
|
|
13689
|
+
unbindCurrentSpanStore?.();
|
|
13551
13690
|
tracingChannel2.unsubscribe(handlers);
|
|
13552
13691
|
};
|
|
13553
13692
|
}
|
|
@@ -13555,15 +13694,19 @@ function traceSyncStreamChannel(channel2, config3) {
|
|
|
13555
13694
|
const tracingChannel2 = channel2.tracingChannel();
|
|
13556
13695
|
const states = /* @__PURE__ */ new WeakMap();
|
|
13557
13696
|
const channelName = channel2.channelName;
|
|
13697
|
+
const unbindCurrentSpanStore = bindCurrentSpanStoreToStart(
|
|
13698
|
+
tracingChannel2,
|
|
13699
|
+
states,
|
|
13700
|
+
config3,
|
|
13701
|
+
channelName
|
|
13702
|
+
);
|
|
13558
13703
|
const handlers = {
|
|
13559
13704
|
start: (event) => {
|
|
13560
|
-
|
|
13705
|
+
ensureSpanStateForEvent(
|
|
13706
|
+
states,
|
|
13707
|
+
config3,
|
|
13561
13708
|
event,
|
|
13562
|
-
|
|
13563
|
-
config3,
|
|
13564
|
-
event,
|
|
13565
|
-
channelName
|
|
13566
|
-
)
|
|
13709
|
+
channelName
|
|
13567
13710
|
);
|
|
13568
13711
|
},
|
|
13569
13712
|
end: (event) => {
|
|
@@ -13652,6 +13795,7 @@ function traceSyncStreamChannel(channel2, config3) {
|
|
|
13652
13795
|
};
|
|
13653
13796
|
tracingChannel2.subscribe(handlers);
|
|
13654
13797
|
return () => {
|
|
13798
|
+
unbindCurrentSpanStore?.();
|
|
13655
13799
|
tracingChannel2.unsubscribe(handlers);
|
|
13656
13800
|
};
|
|
13657
13801
|
}
|
|
@@ -14423,7 +14567,7 @@ var AnthropicPlugin = class extends BasePlugin {
|
|
|
14423
14567
|
this.unsubscribers.push(
|
|
14424
14568
|
traceStreamingChannel(anthropicChannels.betaMessagesCreate, {
|
|
14425
14569
|
...anthropicConfig,
|
|
14426
|
-
name: "anthropic.
|
|
14570
|
+
name: "anthropic.messages.create"
|
|
14427
14571
|
})
|
|
14428
14572
|
);
|
|
14429
14573
|
}
|
|
@@ -14446,9 +14590,12 @@ function parseMetricsFromUsage2(usage) {
|
|
|
14446
14590
|
return metrics;
|
|
14447
14591
|
}
|
|
14448
14592
|
function aggregateAnthropicStreamChunks(chunks) {
|
|
14449
|
-
const
|
|
14593
|
+
const fallbackTextDeltas = [];
|
|
14594
|
+
const contentBlocks = {};
|
|
14595
|
+
const contentBlockDeltas = {};
|
|
14450
14596
|
let metrics = {};
|
|
14451
14597
|
let metadata = {};
|
|
14598
|
+
let role;
|
|
14452
14599
|
for (const event of chunks) {
|
|
14453
14600
|
switch (event?.type) {
|
|
14454
14601
|
case "message_start":
|
|
@@ -14456,15 +14603,43 @@ function aggregateAnthropicStreamChunks(chunks) {
|
|
|
14456
14603
|
const initialMetrics = parseMetricsFromUsage2(event.message.usage);
|
|
14457
14604
|
metrics = { ...metrics, ...initialMetrics };
|
|
14458
14605
|
}
|
|
14606
|
+
if (typeof event.message?.role === "string") {
|
|
14607
|
+
role = event.message.role;
|
|
14608
|
+
}
|
|
14609
|
+
break;
|
|
14610
|
+
case "content_block_start":
|
|
14611
|
+
if (event.content_block) {
|
|
14612
|
+
contentBlocks[event.index] = event.content_block;
|
|
14613
|
+
contentBlockDeltas[event.index] = [];
|
|
14614
|
+
}
|
|
14459
14615
|
break;
|
|
14460
14616
|
case "content_block_delta":
|
|
14461
14617
|
if (event.delta?.type === "text_delta") {
|
|
14462
14618
|
const text = event.delta.text;
|
|
14463
14619
|
if (text) {
|
|
14464
|
-
|
|
14620
|
+
if (contentBlocks[event.index] !== void 0 || contentBlockDeltas[event.index] !== void 0) {
|
|
14621
|
+
contentBlockDeltas[event.index] ??= [];
|
|
14622
|
+
contentBlockDeltas[event.index].push(text);
|
|
14623
|
+
} else {
|
|
14624
|
+
fallbackTextDeltas.push(text);
|
|
14625
|
+
}
|
|
14626
|
+
}
|
|
14627
|
+
} else if (event.delta?.type === "input_json_delta") {
|
|
14628
|
+
const partialJson = event.delta.partial_json;
|
|
14629
|
+
if (partialJson) {
|
|
14630
|
+
contentBlockDeltas[event.index] ??= [];
|
|
14631
|
+
contentBlockDeltas[event.index].push(partialJson);
|
|
14465
14632
|
}
|
|
14466
14633
|
}
|
|
14467
14634
|
break;
|
|
14635
|
+
case "content_block_stop":
|
|
14636
|
+
finalizeContentBlock(
|
|
14637
|
+
event.index,
|
|
14638
|
+
contentBlocks,
|
|
14639
|
+
contentBlockDeltas,
|
|
14640
|
+
fallbackTextDeltas
|
|
14641
|
+
);
|
|
14642
|
+
break;
|
|
14468
14643
|
case "message_delta":
|
|
14469
14644
|
if (event.usage) {
|
|
14470
14645
|
const finalMetrics = parseMetricsFromUsage2(event.usage);
|
|
@@ -14476,7 +14651,21 @@ function aggregateAnthropicStreamChunks(chunks) {
|
|
|
14476
14651
|
break;
|
|
14477
14652
|
}
|
|
14478
14653
|
}
|
|
14479
|
-
const
|
|
14654
|
+
const orderedContent = Object.entries(contentBlocks).map(([index, block]) => ({
|
|
14655
|
+
block,
|
|
14656
|
+
index: Number(index)
|
|
14657
|
+
})).filter(({ block }) => block !== void 0).sort((left, right) => left.index - right.index).map(({ block }) => block);
|
|
14658
|
+
let output = fallbackTextDeltas.join("");
|
|
14659
|
+
if (orderedContent.length > 0) {
|
|
14660
|
+
if (orderedContent.every(isTextContentBlock)) {
|
|
14661
|
+
output = orderedContent.map((block) => block.text).join("");
|
|
14662
|
+
} else {
|
|
14663
|
+
output = {
|
|
14664
|
+
...role ? { role } : {},
|
|
14665
|
+
content: orderedContent
|
|
14666
|
+
};
|
|
14667
|
+
}
|
|
14668
|
+
}
|
|
14480
14669
|
const finalized = finalizeAnthropicTokens(metrics);
|
|
14481
14670
|
const filteredMetrics = Object.fromEntries(
|
|
14482
14671
|
Object.entries(finalized).filter(
|
|
@@ -14489,6 +14678,49 @@ function aggregateAnthropicStreamChunks(chunks) {
|
|
|
14489
14678
|
metadata
|
|
14490
14679
|
};
|
|
14491
14680
|
}
|
|
14681
|
+
function finalizeContentBlock(index, contentBlocks, contentBlockDeltas, fallbackTextDeltas) {
|
|
14682
|
+
const contentBlock = contentBlocks[index];
|
|
14683
|
+
if (!contentBlock) {
|
|
14684
|
+
return;
|
|
14685
|
+
}
|
|
14686
|
+
const text = contentBlockDeltas[index]?.join("") ?? "";
|
|
14687
|
+
if (isToolUseContentBlock(contentBlock)) {
|
|
14688
|
+
if (!text) {
|
|
14689
|
+
return;
|
|
14690
|
+
}
|
|
14691
|
+
try {
|
|
14692
|
+
contentBlocks[index] = {
|
|
14693
|
+
...contentBlock,
|
|
14694
|
+
input: JSON.parse(text)
|
|
14695
|
+
};
|
|
14696
|
+
} catch {
|
|
14697
|
+
fallbackTextDeltas.push(text);
|
|
14698
|
+
delete contentBlocks[index];
|
|
14699
|
+
}
|
|
14700
|
+
return;
|
|
14701
|
+
}
|
|
14702
|
+
if (isTextContentBlock(contentBlock)) {
|
|
14703
|
+
if (!text) {
|
|
14704
|
+
delete contentBlocks[index];
|
|
14705
|
+
return;
|
|
14706
|
+
}
|
|
14707
|
+
contentBlocks[index] = {
|
|
14708
|
+
...contentBlock,
|
|
14709
|
+
text
|
|
14710
|
+
};
|
|
14711
|
+
return;
|
|
14712
|
+
}
|
|
14713
|
+
if (text) {
|
|
14714
|
+
fallbackTextDeltas.push(text);
|
|
14715
|
+
}
|
|
14716
|
+
delete contentBlocks[index];
|
|
14717
|
+
}
|
|
14718
|
+
function isTextContentBlock(contentBlock) {
|
|
14719
|
+
return contentBlock.type === "text";
|
|
14720
|
+
}
|
|
14721
|
+
function isToolUseContentBlock(contentBlock) {
|
|
14722
|
+
return contentBlock.type === "tool_use";
|
|
14723
|
+
}
|
|
14492
14724
|
function isAnthropicBase64ContentBlock(input) {
|
|
14493
14725
|
return (input.type === "image" || input.type === "document") && isObject(input.source) && input.source.type === "base64";
|
|
14494
14726
|
}
|
|
@@ -15611,12 +15843,15 @@ var claudeAgentSDKChannels = defineChannels(
|
|
|
15611
15843
|
{
|
|
15612
15844
|
query: channel({
|
|
15613
15845
|
channelName: "query",
|
|
15614
|
-
kind: "
|
|
15846
|
+
kind: "sync-stream"
|
|
15615
15847
|
})
|
|
15616
15848
|
}
|
|
15617
15849
|
);
|
|
15618
15850
|
|
|
15619
15851
|
// src/instrumentation/plugins/claude-agent-sdk-plugin.ts
|
|
15852
|
+
function isSubAgentToolName(toolName) {
|
|
15853
|
+
return toolName === "Agent" || toolName === "Task";
|
|
15854
|
+
}
|
|
15620
15855
|
function filterSerializableOptions(options) {
|
|
15621
15856
|
const allowedKeys = [
|
|
15622
15857
|
"model",
|
|
@@ -15670,34 +15905,50 @@ function extractUsageFromMessage(message) {
|
|
|
15670
15905
|
const cacheReadTokens = getNumberProperty(usage, "cache_read_input_tokens") || 0;
|
|
15671
15906
|
const cacheCreationTokens = getNumberProperty(usage, "cache_creation_input_tokens") || 0;
|
|
15672
15907
|
if (cacheReadTokens > 0 || cacheCreationTokens > 0) {
|
|
15673
|
-
|
|
15674
|
-
|
|
15675
|
-
cacheCreationTokens
|
|
15908
|
+
Object.assign(
|
|
15909
|
+
metrics,
|
|
15910
|
+
extractAnthropicCacheTokens(cacheReadTokens, cacheCreationTokens)
|
|
15676
15911
|
);
|
|
15677
|
-
Object.assign(metrics, cacheTokens);
|
|
15678
15912
|
}
|
|
15679
15913
|
if (Object.keys(metrics).length > 0) {
|
|
15680
15914
|
Object.assign(metrics, finalizeAnthropicTokens(metrics));
|
|
15681
15915
|
}
|
|
15682
15916
|
return metrics;
|
|
15683
15917
|
}
|
|
15684
|
-
function buildLLMInput(prompt, conversationHistory) {
|
|
15685
|
-
const
|
|
15686
|
-
|
|
15687
|
-
|
|
15688
|
-
|
|
15689
|
-
|
|
15918
|
+
function buildLLMInput(prompt, conversationHistory, capturedPromptMessages) {
|
|
15919
|
+
const promptMessages = [];
|
|
15920
|
+
if (typeof prompt === "string") {
|
|
15921
|
+
promptMessages.push({ content: prompt, role: "user" });
|
|
15922
|
+
} else if (capturedPromptMessages && capturedPromptMessages.length > 0) {
|
|
15923
|
+
for (const msg of capturedPromptMessages) {
|
|
15924
|
+
const role = msg.message?.role;
|
|
15925
|
+
const content = msg.message?.content;
|
|
15926
|
+
if (role && content !== void 0) {
|
|
15927
|
+
promptMessages.push({ content, role });
|
|
15928
|
+
}
|
|
15929
|
+
}
|
|
15930
|
+
}
|
|
15931
|
+
const inputParts = [...promptMessages, ...conversationHistory];
|
|
15690
15932
|
return inputParts.length > 0 ? inputParts : void 0;
|
|
15691
15933
|
}
|
|
15692
|
-
|
|
15693
|
-
|
|
15934
|
+
function formatCapturedMessages(messages) {
|
|
15935
|
+
return messages.length > 0 ? messages : [];
|
|
15936
|
+
}
|
|
15937
|
+
async function createLLMSpanForMessages(messages, prompt, conversationHistory, options, startTime, capturedPromptMessages, parentSpan) {
|
|
15938
|
+
if (messages.length === 0) {
|
|
15939
|
+
return void 0;
|
|
15940
|
+
}
|
|
15694
15941
|
const lastMessage = messages[messages.length - 1];
|
|
15695
15942
|
if (lastMessage.type !== "assistant" || !lastMessage.message?.usage) {
|
|
15696
15943
|
return void 0;
|
|
15697
15944
|
}
|
|
15698
15945
|
const model = lastMessage.message.model || options.model;
|
|
15699
15946
|
const usage = extractUsageFromMessage(lastMessage);
|
|
15700
|
-
const input = buildLLMInput(
|
|
15947
|
+
const input = buildLLMInput(
|
|
15948
|
+
prompt,
|
|
15949
|
+
conversationHistory,
|
|
15950
|
+
capturedPromptMessages
|
|
15951
|
+
);
|
|
15701
15952
|
const outputs = messages.map(
|
|
15702
15953
|
(m) => m.message?.content && m.message?.role ? { content: m.message.content, role: m.message.role } : void 0
|
|
15703
15954
|
).filter(
|
|
@@ -15705,21 +15956,359 @@ async function createLLMSpanForMessages(messages, prompt, conversationHistory, o
|
|
|
15705
15956
|
);
|
|
15706
15957
|
const span = startSpan({
|
|
15707
15958
|
name: "anthropic.messages.create",
|
|
15959
|
+
parent: parentSpan,
|
|
15708
15960
|
spanAttributes: {
|
|
15709
15961
|
type: "llm" /* LLM */
|
|
15710
15962
|
},
|
|
15711
|
-
startTime
|
|
15712
|
-
parent: parentSpan
|
|
15963
|
+
startTime
|
|
15713
15964
|
});
|
|
15714
15965
|
span.log({
|
|
15715
15966
|
input,
|
|
15716
|
-
output: outputs,
|
|
15717
15967
|
metadata: model ? { model } : void 0,
|
|
15718
|
-
metrics: usage
|
|
15968
|
+
metrics: usage,
|
|
15969
|
+
output: outputs
|
|
15719
15970
|
});
|
|
15720
15971
|
await span.end();
|
|
15721
15972
|
return lastMessage.message?.content && lastMessage.message?.role ? { content: lastMessage.message.content, role: lastMessage.message.role } : void 0;
|
|
15722
15973
|
}
|
|
15974
|
+
function getMcpServerMetadata(serverName, mcpServers) {
|
|
15975
|
+
if (!serverName || !mcpServers) {
|
|
15976
|
+
return {};
|
|
15977
|
+
}
|
|
15978
|
+
const serverConfig = mcpServers[serverName];
|
|
15979
|
+
if (!serverConfig) {
|
|
15980
|
+
return {};
|
|
15981
|
+
}
|
|
15982
|
+
const metadata = {};
|
|
15983
|
+
if (serverConfig.type) {
|
|
15984
|
+
metadata["mcp.type"] = serverConfig.type;
|
|
15985
|
+
} else if (typeof serverConfig === "object" && "transport" in serverConfig) {
|
|
15986
|
+
metadata["mcp.type"] = "sdk";
|
|
15987
|
+
}
|
|
15988
|
+
if (serverConfig.url) {
|
|
15989
|
+
metadata["mcp.url"] = serverConfig.url;
|
|
15990
|
+
}
|
|
15991
|
+
if (serverConfig.command) {
|
|
15992
|
+
metadata["mcp.command"] = serverConfig.command;
|
|
15993
|
+
if (serverConfig.args) {
|
|
15994
|
+
metadata["mcp.args"] = serverConfig.args.join(" ");
|
|
15995
|
+
}
|
|
15996
|
+
}
|
|
15997
|
+
return metadata;
|
|
15998
|
+
}
|
|
15999
|
+
function parseToolName(rawToolName) {
|
|
16000
|
+
const mcpMatch = rawToolName.match(/^mcp__([^_]+)__(.+)$/);
|
|
16001
|
+
if (mcpMatch) {
|
|
16002
|
+
const [, mcpServer, toolName] = mcpMatch;
|
|
16003
|
+
return {
|
|
16004
|
+
displayName: `tool: ${mcpServer}/${toolName}`,
|
|
16005
|
+
mcpServer,
|
|
16006
|
+
rawToolName,
|
|
16007
|
+
toolName
|
|
16008
|
+
};
|
|
16009
|
+
}
|
|
16010
|
+
return {
|
|
16011
|
+
displayName: `tool: ${rawToolName}`,
|
|
16012
|
+
rawToolName,
|
|
16013
|
+
toolName: rawToolName
|
|
16014
|
+
};
|
|
16015
|
+
}
|
|
16016
|
+
function createToolTracingHooks(resolveParentSpan, activeToolSpans, mcpServers, subAgentSpans, endedSubAgentSpans) {
|
|
16017
|
+
const preToolUse = async (input, toolUseID) => {
|
|
16018
|
+
if (input.hook_event_name !== "PreToolUse" || !toolUseID) {
|
|
16019
|
+
return {};
|
|
16020
|
+
}
|
|
16021
|
+
if (isSubAgentToolName(input.tool_name)) {
|
|
16022
|
+
return {};
|
|
16023
|
+
}
|
|
16024
|
+
const parsed = parseToolName(input.tool_name);
|
|
16025
|
+
const toolSpan = startSpan({
|
|
16026
|
+
event: {
|
|
16027
|
+
input: input.tool_input,
|
|
16028
|
+
metadata: {
|
|
16029
|
+
"claude_agent_sdk.cwd": input.cwd,
|
|
16030
|
+
"claude_agent_sdk.raw_tool_name": parsed.rawToolName,
|
|
16031
|
+
"claude_agent_sdk.session_id": input.session_id,
|
|
16032
|
+
"gen_ai.tool.call.id": toolUseID,
|
|
16033
|
+
"gen_ai.tool.name": parsed.toolName,
|
|
16034
|
+
...parsed.mcpServer && { "mcp.server": parsed.mcpServer },
|
|
16035
|
+
...getMcpServerMetadata(parsed.mcpServer, mcpServers)
|
|
16036
|
+
}
|
|
16037
|
+
},
|
|
16038
|
+
name: parsed.displayName,
|
|
16039
|
+
parent: await resolveParentSpan(toolUseID),
|
|
16040
|
+
spanAttributes: { type: "tool" /* TOOL */ }
|
|
16041
|
+
});
|
|
16042
|
+
activeToolSpans.set(toolUseID, toolSpan);
|
|
16043
|
+
return {};
|
|
16044
|
+
};
|
|
16045
|
+
const postToolUse = async (input, toolUseID) => {
|
|
16046
|
+
if (input.hook_event_name !== "PostToolUse" || !toolUseID) {
|
|
16047
|
+
return {};
|
|
16048
|
+
}
|
|
16049
|
+
const subAgentSpan = subAgentSpans.get(toolUseID);
|
|
16050
|
+
if (subAgentSpan) {
|
|
16051
|
+
try {
|
|
16052
|
+
const response = input.tool_response;
|
|
16053
|
+
const metadata = {};
|
|
16054
|
+
if (response?.status) {
|
|
16055
|
+
metadata["claude_agent_sdk.status"] = response.status;
|
|
16056
|
+
}
|
|
16057
|
+
if (response?.totalDurationMs) {
|
|
16058
|
+
metadata["claude_agent_sdk.duration_ms"] = response.totalDurationMs;
|
|
16059
|
+
}
|
|
16060
|
+
if (response?.totalToolUseCount !== void 0) {
|
|
16061
|
+
metadata["claude_agent_sdk.tool_use_count"] = response.totalToolUseCount;
|
|
16062
|
+
}
|
|
16063
|
+
subAgentSpan.log({
|
|
16064
|
+
metadata,
|
|
16065
|
+
output: response?.content
|
|
16066
|
+
});
|
|
16067
|
+
} finally {
|
|
16068
|
+
subAgentSpan.end();
|
|
16069
|
+
endedSubAgentSpans.add(toolUseID);
|
|
16070
|
+
}
|
|
16071
|
+
return {};
|
|
16072
|
+
}
|
|
16073
|
+
const toolSpan = activeToolSpans.get(toolUseID);
|
|
16074
|
+
if (!toolSpan) {
|
|
16075
|
+
return {};
|
|
16076
|
+
}
|
|
16077
|
+
try {
|
|
16078
|
+
toolSpan.log({ output: input.tool_response });
|
|
16079
|
+
} finally {
|
|
16080
|
+
toolSpan.end();
|
|
16081
|
+
activeToolSpans.delete(toolUseID);
|
|
16082
|
+
}
|
|
16083
|
+
return {};
|
|
16084
|
+
};
|
|
16085
|
+
const postToolUseFailure = async (input, toolUseID) => {
|
|
16086
|
+
if (input.hook_event_name !== "PostToolUseFailure" || !toolUseID) {
|
|
16087
|
+
return {};
|
|
16088
|
+
}
|
|
16089
|
+
const subAgentSpan = subAgentSpans.get(toolUseID);
|
|
16090
|
+
if (subAgentSpan) {
|
|
16091
|
+
try {
|
|
16092
|
+
subAgentSpan.log({ error: input.error });
|
|
16093
|
+
} finally {
|
|
16094
|
+
subAgentSpan.end();
|
|
16095
|
+
endedSubAgentSpans.add(toolUseID);
|
|
16096
|
+
}
|
|
16097
|
+
return {};
|
|
16098
|
+
}
|
|
16099
|
+
const toolSpan = activeToolSpans.get(toolUseID);
|
|
16100
|
+
if (!toolSpan) {
|
|
16101
|
+
return {};
|
|
16102
|
+
}
|
|
16103
|
+
const parsed = parseToolName(input.tool_name);
|
|
16104
|
+
try {
|
|
16105
|
+
toolSpan.log({
|
|
16106
|
+
error: input.error,
|
|
16107
|
+
metadata: {
|
|
16108
|
+
"claude_agent_sdk.is_interrupt": input.is_interrupt,
|
|
16109
|
+
"claude_agent_sdk.session_id": input.session_id,
|
|
16110
|
+
"gen_ai.tool.call.id": toolUseID,
|
|
16111
|
+
"gen_ai.tool.name": parsed.toolName,
|
|
16112
|
+
...parsed.mcpServer && { "mcp.server": parsed.mcpServer }
|
|
16113
|
+
}
|
|
16114
|
+
});
|
|
16115
|
+
} finally {
|
|
16116
|
+
toolSpan.end();
|
|
16117
|
+
activeToolSpans.delete(toolUseID);
|
|
16118
|
+
}
|
|
16119
|
+
return {};
|
|
16120
|
+
};
|
|
16121
|
+
return { postToolUse, postToolUseFailure, preToolUse };
|
|
16122
|
+
}
|
|
16123
|
+
function injectTracingHooks(options, resolveParentSpan, activeToolSpans, subAgentSpans, endedSubAgentSpans) {
|
|
16124
|
+
const { preToolUse, postToolUse, postToolUseFailure } = createToolTracingHooks(
|
|
16125
|
+
resolveParentSpan,
|
|
16126
|
+
activeToolSpans,
|
|
16127
|
+
options.mcpServers,
|
|
16128
|
+
subAgentSpans,
|
|
16129
|
+
endedSubAgentSpans
|
|
16130
|
+
);
|
|
16131
|
+
const existingHooks = options.hooks ?? {};
|
|
16132
|
+
return {
|
|
16133
|
+
...options,
|
|
16134
|
+
hooks: {
|
|
16135
|
+
...existingHooks,
|
|
16136
|
+
PostToolUse: [
|
|
16137
|
+
...existingHooks.PostToolUse ?? [],
|
|
16138
|
+
{ hooks: [postToolUse] }
|
|
16139
|
+
],
|
|
16140
|
+
PostToolUseFailure: [
|
|
16141
|
+
...existingHooks.PostToolUseFailure ?? [],
|
|
16142
|
+
{
|
|
16143
|
+
hooks: [postToolUseFailure]
|
|
16144
|
+
}
|
|
16145
|
+
],
|
|
16146
|
+
PreToolUse: [
|
|
16147
|
+
...existingHooks.PreToolUse ?? [],
|
|
16148
|
+
{ hooks: [preToolUse] }
|
|
16149
|
+
]
|
|
16150
|
+
}
|
|
16151
|
+
};
|
|
16152
|
+
}
|
|
16153
|
+
async function finalizeCurrentMessageGroup(state) {
|
|
16154
|
+
if (state.currentMessages.length === 0) {
|
|
16155
|
+
return;
|
|
16156
|
+
}
|
|
16157
|
+
const parentToolUseId = state.currentMessages[0]?.parent_tool_use_id ?? null;
|
|
16158
|
+
let parentSpan = await state.span.export();
|
|
16159
|
+
if (parentToolUseId) {
|
|
16160
|
+
const subAgentSpan = state.subAgentSpans.get(parentToolUseId);
|
|
16161
|
+
if (subAgentSpan) {
|
|
16162
|
+
parentSpan = await subAgentSpan.export();
|
|
16163
|
+
}
|
|
16164
|
+
}
|
|
16165
|
+
const finalMessage = await createLLMSpanForMessages(
|
|
16166
|
+
state.currentMessages,
|
|
16167
|
+
state.originalPrompt,
|
|
16168
|
+
state.finalResults,
|
|
16169
|
+
state.options,
|
|
16170
|
+
state.currentMessageStartTime,
|
|
16171
|
+
state.capturedPromptMessages,
|
|
16172
|
+
parentSpan
|
|
16173
|
+
);
|
|
16174
|
+
if (finalMessage) {
|
|
16175
|
+
state.finalResults.push(finalMessage);
|
|
16176
|
+
}
|
|
16177
|
+
const lastMessage = state.currentMessages[state.currentMessages.length - 1];
|
|
16178
|
+
if (lastMessage?.message?.usage) {
|
|
16179
|
+
state.accumulatedOutputTokens += getNumberProperty(lastMessage.message.usage, "output_tokens") || 0;
|
|
16180
|
+
}
|
|
16181
|
+
state.currentMessages.length = 0;
|
|
16182
|
+
}
|
|
16183
|
+
function maybeTrackToolUseContext(state, message) {
|
|
16184
|
+
if (message.type !== "assistant" || !Array.isArray(message.message?.content)) {
|
|
16185
|
+
return;
|
|
16186
|
+
}
|
|
16187
|
+
const parentToolUseId = message.parent_tool_use_id ?? null;
|
|
16188
|
+
for (const block of message.message.content) {
|
|
16189
|
+
if (typeof block !== "object" || block === null || !("type" in block) || block.type !== "tool_use" || !("id" in block) || typeof block.id !== "string") {
|
|
16190
|
+
continue;
|
|
16191
|
+
}
|
|
16192
|
+
state.toolUseToParent.set(block.id, parentToolUseId);
|
|
16193
|
+
if (block.name === "Task" && typeof block.input === "object" && block.input !== null && "subagent_type" in block.input && typeof block.input.subagent_type === "string") {
|
|
16194
|
+
state.pendingSubAgentNames.set(block.id, block.input.subagent_type);
|
|
16195
|
+
}
|
|
16196
|
+
}
|
|
16197
|
+
}
|
|
16198
|
+
async function maybeStartSubAgentSpan(state, message) {
|
|
16199
|
+
if (!("parent_tool_use_id" in message)) {
|
|
16200
|
+
return;
|
|
16201
|
+
}
|
|
16202
|
+
const parentToolUseId = message.parent_tool_use_id;
|
|
16203
|
+
if (!parentToolUseId) {
|
|
16204
|
+
return;
|
|
16205
|
+
}
|
|
16206
|
+
await ensureSubAgentSpan(
|
|
16207
|
+
state.pendingSubAgentNames,
|
|
16208
|
+
state.span,
|
|
16209
|
+
state.subAgentSpans,
|
|
16210
|
+
parentToolUseId
|
|
16211
|
+
);
|
|
16212
|
+
}
|
|
16213
|
+
async function ensureSubAgentSpan(pendingSubAgentNames, rootSpan, subAgentSpans, parentToolUseId) {
|
|
16214
|
+
const existingSpan = subAgentSpans.get(parentToolUseId);
|
|
16215
|
+
if (existingSpan) {
|
|
16216
|
+
return existingSpan;
|
|
16217
|
+
}
|
|
16218
|
+
const agentName = pendingSubAgentNames.get(parentToolUseId);
|
|
16219
|
+
const spanName = agentName ? `Agent: ${agentName}` : "Agent: sub-agent";
|
|
16220
|
+
const subAgentSpan = startSpan({
|
|
16221
|
+
event: {
|
|
16222
|
+
metadata: {
|
|
16223
|
+
...agentName && { "claude_agent_sdk.agent_type": agentName }
|
|
16224
|
+
}
|
|
16225
|
+
},
|
|
16226
|
+
name: spanName,
|
|
16227
|
+
parent: await rootSpan.export(),
|
|
16228
|
+
spanAttributes: { type: "task" /* TASK */ }
|
|
16229
|
+
});
|
|
16230
|
+
subAgentSpans.set(parentToolUseId, subAgentSpan);
|
|
16231
|
+
return subAgentSpan;
|
|
16232
|
+
}
|
|
16233
|
+
async function handleStreamMessage(state, message) {
|
|
16234
|
+
maybeTrackToolUseContext(state, message);
|
|
16235
|
+
await maybeStartSubAgentSpan(state, message);
|
|
16236
|
+
const messageId = message.message?.id;
|
|
16237
|
+
if (messageId && messageId !== state.currentMessageId) {
|
|
16238
|
+
await finalizeCurrentMessageGroup(state);
|
|
16239
|
+
state.currentMessageId = messageId;
|
|
16240
|
+
state.currentMessageStartTime = getCurrentUnixTimestamp();
|
|
16241
|
+
}
|
|
16242
|
+
if (message.type === "assistant" && message.message?.usage) {
|
|
16243
|
+
state.currentMessages.push(message);
|
|
16244
|
+
}
|
|
16245
|
+
if (message.type !== "result" || !message.usage) {
|
|
16246
|
+
return;
|
|
16247
|
+
}
|
|
16248
|
+
const finalUsageMetrics = extractUsageFromMessage(message);
|
|
16249
|
+
if (state.currentMessages.length > 0 && finalUsageMetrics.completion_tokens !== void 0) {
|
|
16250
|
+
const lastMessage = state.currentMessages[state.currentMessages.length - 1];
|
|
16251
|
+
if (lastMessage?.message?.usage) {
|
|
16252
|
+
const adjustedTokens = finalUsageMetrics.completion_tokens - state.accumulatedOutputTokens;
|
|
16253
|
+
if (adjustedTokens >= 0) {
|
|
16254
|
+
lastMessage.message.usage.output_tokens = adjustedTokens;
|
|
16255
|
+
}
|
|
16256
|
+
const resultUsage = message.usage;
|
|
16257
|
+
if (resultUsage && typeof resultUsage === "object") {
|
|
16258
|
+
const cacheReadTokens = getNumberProperty(
|
|
16259
|
+
resultUsage,
|
|
16260
|
+
"cache_read_input_tokens"
|
|
16261
|
+
);
|
|
16262
|
+
if (cacheReadTokens !== void 0) {
|
|
16263
|
+
lastMessage.message.usage.cache_read_input_tokens = cacheReadTokens;
|
|
16264
|
+
}
|
|
16265
|
+
const cacheCreationTokens = getNumberProperty(
|
|
16266
|
+
resultUsage,
|
|
16267
|
+
"cache_creation_input_tokens"
|
|
16268
|
+
);
|
|
16269
|
+
if (cacheCreationTokens !== void 0) {
|
|
16270
|
+
lastMessage.message.usage.cache_creation_input_tokens = cacheCreationTokens;
|
|
16271
|
+
}
|
|
16272
|
+
}
|
|
16273
|
+
}
|
|
16274
|
+
}
|
|
16275
|
+
const metadata = {};
|
|
16276
|
+
if (message.num_turns !== void 0) {
|
|
16277
|
+
metadata.num_turns = message.num_turns;
|
|
16278
|
+
}
|
|
16279
|
+
if (message.session_id !== void 0) {
|
|
16280
|
+
metadata.session_id = message.session_id;
|
|
16281
|
+
}
|
|
16282
|
+
if (Object.keys(metadata).length > 0) {
|
|
16283
|
+
state.span.log({ metadata });
|
|
16284
|
+
}
|
|
16285
|
+
}
|
|
16286
|
+
async function finalizeQuerySpan(state) {
|
|
16287
|
+
try {
|
|
16288
|
+
await finalizeCurrentMessageGroup(state);
|
|
16289
|
+
state.span.log({
|
|
16290
|
+
output: state.finalResults.length > 0 ? state.finalResults[state.finalResults.length - 1] : void 0
|
|
16291
|
+
});
|
|
16292
|
+
if (state.capturedPromptMessages) {
|
|
16293
|
+
if (state.promptStarted()) {
|
|
16294
|
+
await state.promptDone;
|
|
16295
|
+
}
|
|
16296
|
+
if (state.capturedPromptMessages.length > 0) {
|
|
16297
|
+
state.span.log({
|
|
16298
|
+
input: formatCapturedMessages(state.capturedPromptMessages)
|
|
16299
|
+
});
|
|
16300
|
+
}
|
|
16301
|
+
}
|
|
16302
|
+
} finally {
|
|
16303
|
+
for (const [id, subAgentSpan] of state.subAgentSpans) {
|
|
16304
|
+
if (!state.endedSubAgentSpans.has(id)) {
|
|
16305
|
+
subAgentSpan.end();
|
|
16306
|
+
}
|
|
16307
|
+
}
|
|
16308
|
+
state.subAgentSpans.clear();
|
|
16309
|
+
state.span.end();
|
|
16310
|
+
}
|
|
16311
|
+
}
|
|
15723
16312
|
var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
15724
16313
|
onEnable() {
|
|
15725
16314
|
this.subscribeToQuery();
|
|
@@ -15730,19 +16319,36 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
15730
16319
|
}
|
|
15731
16320
|
this.unsubscribers = [];
|
|
15732
16321
|
}
|
|
15733
|
-
/**
|
|
15734
|
-
* Subscribe to the query channel for agent interactions.
|
|
15735
|
-
* Handles streaming responses and traces both the top-level agent task
|
|
15736
|
-
* and individual LLM calls.
|
|
15737
|
-
*/
|
|
15738
16322
|
subscribeToQuery() {
|
|
15739
16323
|
const channel2 = claudeAgentSDKChannels.query.tracingChannel();
|
|
15740
16324
|
const spans = /* @__PURE__ */ new WeakMap();
|
|
15741
16325
|
const handlers = {
|
|
15742
16326
|
start: (event) => {
|
|
15743
|
-
const params = event.arguments[0];
|
|
15744
|
-
const
|
|
15745
|
-
const options = params
|
|
16327
|
+
const params = event.arguments[0] ?? {};
|
|
16328
|
+
const originalPrompt = params.prompt;
|
|
16329
|
+
const options = params.options ?? {};
|
|
16330
|
+
const promptIsAsyncIterable = isAsyncIterable3(originalPrompt);
|
|
16331
|
+
let promptStarted = false;
|
|
16332
|
+
let capturedPromptMessages;
|
|
16333
|
+
let resolvePromptDone;
|
|
16334
|
+
const promptDone = new Promise((resolve2) => {
|
|
16335
|
+
resolvePromptDone = resolve2;
|
|
16336
|
+
});
|
|
16337
|
+
if (promptIsAsyncIterable) {
|
|
16338
|
+
capturedPromptMessages = [];
|
|
16339
|
+
const promptStream = originalPrompt;
|
|
16340
|
+
params.prompt = (async function* () {
|
|
16341
|
+
promptStarted = true;
|
|
16342
|
+
try {
|
|
16343
|
+
for await (const message of promptStream) {
|
|
16344
|
+
capturedPromptMessages.push(message);
|
|
16345
|
+
yield message;
|
|
16346
|
+
}
|
|
16347
|
+
} finally {
|
|
16348
|
+
resolvePromptDone?.();
|
|
16349
|
+
}
|
|
16350
|
+
})();
|
|
16351
|
+
}
|
|
15746
16352
|
const span = startSpan({
|
|
15747
16353
|
name: "Claude Agent",
|
|
15748
16354
|
spanAttributes: {
|
|
@@ -15752,163 +16358,115 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
15752
16358
|
const startTime = getCurrentUnixTimestamp();
|
|
15753
16359
|
try {
|
|
15754
16360
|
span.log({
|
|
15755
|
-
input: typeof
|
|
15756
|
-
type: "streaming",
|
|
15757
|
-
description: "AsyncIterable<ClaudeAgentSDKMessage>"
|
|
15758
|
-
},
|
|
16361
|
+
input: typeof originalPrompt === "string" ? originalPrompt : promptIsAsyncIterable ? void 0 : originalPrompt !== void 0 ? String(originalPrompt) : void 0,
|
|
15759
16362
|
metadata: filterSerializableOptions(options)
|
|
15760
16363
|
});
|
|
15761
16364
|
} catch (error2) {
|
|
15762
16365
|
console.error("Error extracting input for Claude Agent SDK:", error2);
|
|
15763
16366
|
}
|
|
16367
|
+
const activeToolSpans = /* @__PURE__ */ new Map();
|
|
16368
|
+
const subAgentSpans = /* @__PURE__ */ new Map();
|
|
16369
|
+
const endedSubAgentSpans = /* @__PURE__ */ new Set();
|
|
16370
|
+
const toolUseToParent = /* @__PURE__ */ new Map();
|
|
16371
|
+
const pendingSubAgentNames = /* @__PURE__ */ new Map();
|
|
16372
|
+
const optionsWithHooks = injectTracingHooks(
|
|
16373
|
+
options,
|
|
16374
|
+
async (toolUseID) => {
|
|
16375
|
+
const parentToolUseId = toolUseToParent.get(toolUseID);
|
|
16376
|
+
if (parentToolUseId) {
|
|
16377
|
+
const subAgentSpan = await ensureSubAgentSpan(
|
|
16378
|
+
pendingSubAgentNames,
|
|
16379
|
+
span,
|
|
16380
|
+
subAgentSpans,
|
|
16381
|
+
parentToolUseId
|
|
16382
|
+
);
|
|
16383
|
+
return subAgentSpan.export();
|
|
16384
|
+
}
|
|
16385
|
+
return span.export();
|
|
16386
|
+
},
|
|
16387
|
+
activeToolSpans,
|
|
16388
|
+
subAgentSpans,
|
|
16389
|
+
endedSubAgentSpans
|
|
16390
|
+
);
|
|
16391
|
+
params.options = optionsWithHooks;
|
|
16392
|
+
event.arguments[0] = params;
|
|
15764
16393
|
spans.set(event, {
|
|
15765
|
-
|
|
15766
|
-
|
|
15767
|
-
|
|
15768
|
-
currentMessages: [],
|
|
16394
|
+
accumulatedOutputTokens: 0,
|
|
16395
|
+
activeToolSpans,
|
|
16396
|
+
capturedPromptMessages,
|
|
15769
16397
|
currentMessageId: void 0,
|
|
15770
16398
|
currentMessageStartTime: startTime,
|
|
15771
|
-
|
|
16399
|
+
currentMessages: [],
|
|
16400
|
+
endedSubAgentSpans,
|
|
16401
|
+
finalResults: [],
|
|
16402
|
+
options: optionsWithHooks,
|
|
16403
|
+
originalPrompt,
|
|
16404
|
+
pendingSubAgentNames,
|
|
16405
|
+
processing: Promise.resolve(),
|
|
16406
|
+
promptDone,
|
|
16407
|
+
promptStarted: () => promptStarted,
|
|
16408
|
+
span,
|
|
16409
|
+
subAgentSpans,
|
|
16410
|
+
toolUseToParent
|
|
15772
16411
|
});
|
|
15773
16412
|
},
|
|
15774
|
-
|
|
15775
|
-
const
|
|
15776
|
-
if (!
|
|
16413
|
+
end: (event) => {
|
|
16414
|
+
const state = spans.get(event);
|
|
16415
|
+
if (!state) {
|
|
15777
16416
|
return;
|
|
15778
16417
|
}
|
|
15779
16418
|
const eventResult = event.result;
|
|
15780
16419
|
if (eventResult === void 0) {
|
|
15781
|
-
|
|
16420
|
+
state.span.end();
|
|
15782
16421
|
spans.delete(event);
|
|
15783
16422
|
return;
|
|
15784
16423
|
}
|
|
15785
16424
|
if (isAsyncIterable3(eventResult)) {
|
|
15786
16425
|
patchStreamIfNeeded(eventResult, {
|
|
15787
|
-
onChunk:
|
|
15788
|
-
|
|
15789
|
-
|
|
15790
|
-
const prompt = params?.prompt;
|
|
15791
|
-
const options = params?.options ?? {};
|
|
15792
|
-
const messageId = message.message?.id;
|
|
15793
|
-
if (messageId && messageId !== spanData.currentMessageId) {
|
|
15794
|
-
if (spanData.currentMessages.length > 0) {
|
|
15795
|
-
const finalMessage = await createLLMSpanForMessages(
|
|
15796
|
-
spanData.currentMessages,
|
|
15797
|
-
prompt,
|
|
15798
|
-
spanData.conversationHistory,
|
|
15799
|
-
options,
|
|
15800
|
-
spanData.currentMessageStartTime,
|
|
15801
|
-
await spanData.span.export()
|
|
15802
|
-
);
|
|
15803
|
-
if (finalMessage) {
|
|
15804
|
-
spanData.conversationHistory.push(finalMessage);
|
|
15805
|
-
}
|
|
15806
|
-
const lastMessage = spanData.currentMessages[spanData.currentMessages.length - 1];
|
|
15807
|
-
if (lastMessage?.message?.usage) {
|
|
15808
|
-
const outputTokens = getNumberProperty(
|
|
15809
|
-
lastMessage.message.usage,
|
|
15810
|
-
"output_tokens"
|
|
15811
|
-
) || 0;
|
|
15812
|
-
spanData.accumulatedOutputTokens += outputTokens;
|
|
15813
|
-
}
|
|
15814
|
-
spanData.currentMessages = [];
|
|
15815
|
-
}
|
|
15816
|
-
spanData.currentMessageId = messageId;
|
|
15817
|
-
spanData.currentMessageStartTime = currentTime;
|
|
15818
|
-
}
|
|
15819
|
-
if (message.type === "assistant" && message.message?.usage) {
|
|
15820
|
-
spanData.currentMessages.push(message);
|
|
15821
|
-
}
|
|
15822
|
-
if (message.type === "result" && message.usage) {
|
|
15823
|
-
const finalUsageMetrics = extractUsageFromMessage(message);
|
|
15824
|
-
if (spanData.currentMessages.length > 0 && finalUsageMetrics.completion_tokens !== void 0) {
|
|
15825
|
-
const lastMessage = spanData.currentMessages[spanData.currentMessages.length - 1];
|
|
15826
|
-
if (lastMessage?.message?.usage) {
|
|
15827
|
-
const adjustedTokens = finalUsageMetrics.completion_tokens - spanData.accumulatedOutputTokens;
|
|
15828
|
-
if (adjustedTokens >= 0) {
|
|
15829
|
-
lastMessage.message.usage.output_tokens = adjustedTokens;
|
|
15830
|
-
}
|
|
15831
|
-
}
|
|
15832
|
-
}
|
|
15833
|
-
const result_metadata = {};
|
|
15834
|
-
if (message.num_turns !== void 0) {
|
|
15835
|
-
result_metadata.num_turns = message.num_turns;
|
|
15836
|
-
}
|
|
15837
|
-
if (message.session_id !== void 0) {
|
|
15838
|
-
result_metadata.session_id = message.session_id;
|
|
15839
|
-
}
|
|
15840
|
-
if (Object.keys(result_metadata).length > 0) {
|
|
15841
|
-
spanData.span.log({
|
|
15842
|
-
metadata: result_metadata
|
|
15843
|
-
});
|
|
15844
|
-
}
|
|
15845
|
-
}
|
|
15846
|
-
},
|
|
15847
|
-
onComplete: async () => {
|
|
15848
|
-
try {
|
|
15849
|
-
const params = event.arguments[0];
|
|
15850
|
-
const prompt = params?.prompt;
|
|
15851
|
-
const options = params?.options ?? {};
|
|
15852
|
-
if (spanData.currentMessages.length > 0) {
|
|
15853
|
-
const finalMessage = await createLLMSpanForMessages(
|
|
15854
|
-
spanData.currentMessages,
|
|
15855
|
-
prompt,
|
|
15856
|
-
spanData.conversationHistory,
|
|
15857
|
-
options,
|
|
15858
|
-
spanData.currentMessageStartTime,
|
|
15859
|
-
await spanData.span.export()
|
|
15860
|
-
);
|
|
15861
|
-
if (finalMessage) {
|
|
15862
|
-
spanData.conversationHistory.push(finalMessage);
|
|
15863
|
-
}
|
|
15864
|
-
}
|
|
15865
|
-
spanData.span.log({
|
|
15866
|
-
output: spanData.conversationHistory.length > 0 ? spanData.conversationHistory[spanData.conversationHistory.length - 1] : void 0
|
|
15867
|
-
});
|
|
15868
|
-
} catch (error2) {
|
|
16426
|
+
onChunk: (message) => {
|
|
16427
|
+
maybeTrackToolUseContext(state, message);
|
|
16428
|
+
state.processing = state.processing.then(() => handleStreamMessage(state, message)).catch((error2) => {
|
|
15869
16429
|
console.error(
|
|
15870
|
-
"Error
|
|
16430
|
+
"Error processing Claude Agent SDK stream chunk:",
|
|
15871
16431
|
error2
|
|
15872
16432
|
);
|
|
15873
|
-
}
|
|
15874
|
-
|
|
15875
|
-
|
|
15876
|
-
|
|
16433
|
+
});
|
|
16434
|
+
},
|
|
16435
|
+
onComplete: () => {
|
|
16436
|
+
void state.processing.then(() => finalizeQuerySpan(state)).finally(() => {
|
|
16437
|
+
spans.delete(event);
|
|
16438
|
+
});
|
|
15877
16439
|
},
|
|
15878
16440
|
onError: (error2) => {
|
|
15879
|
-
|
|
15880
|
-
|
|
16441
|
+
void state.processing.then(() => {
|
|
16442
|
+
state.span.log({
|
|
16443
|
+
error: error2.message
|
|
16444
|
+
});
|
|
16445
|
+
}).then(() => finalizeQuerySpan(state)).finally(() => {
|
|
16446
|
+
spans.delete(event);
|
|
15881
16447
|
});
|
|
15882
|
-
spanData.span.end();
|
|
15883
|
-
spans.delete(event);
|
|
15884
16448
|
}
|
|
15885
16449
|
});
|
|
15886
|
-
|
|
15887
|
-
|
|
15888
|
-
|
|
15889
|
-
|
|
15890
|
-
|
|
15891
|
-
|
|
15892
|
-
|
|
15893
|
-
|
|
15894
|
-
|
|
15895
|
-
);
|
|
15896
|
-
} finally {
|
|
15897
|
-
spanData.span.end();
|
|
15898
|
-
spans.delete(event);
|
|
15899
|
-
}
|
|
16450
|
+
return;
|
|
16451
|
+
}
|
|
16452
|
+
try {
|
|
16453
|
+
state.span.log({ output: eventResult });
|
|
16454
|
+
} catch (error2) {
|
|
16455
|
+
console.error("Error extracting output for Claude Agent SDK:", error2);
|
|
16456
|
+
} finally {
|
|
16457
|
+
state.span.end();
|
|
16458
|
+
spans.delete(event);
|
|
15900
16459
|
}
|
|
15901
16460
|
},
|
|
15902
16461
|
error: (event) => {
|
|
15903
|
-
const
|
|
15904
|
-
if (!
|
|
16462
|
+
const state = spans.get(event);
|
|
16463
|
+
if (!state || !event.error) {
|
|
15905
16464
|
return;
|
|
15906
16465
|
}
|
|
15907
|
-
|
|
15908
|
-
span.log({
|
|
16466
|
+
state.span.log({
|
|
15909
16467
|
error: event.error.message
|
|
15910
16468
|
});
|
|
15911
|
-
span.end();
|
|
16469
|
+
state.span.end();
|
|
15912
16470
|
spans.delete(event);
|
|
15913
16471
|
}
|
|
15914
16472
|
};
|
|
@@ -15932,6 +16490,18 @@ var googleGenAIChannels = defineChannels("@google/genai", {
|
|
|
15932
16490
|
});
|
|
15933
16491
|
|
|
15934
16492
|
// src/instrumentation/plugins/google-genai-plugin.ts
|
|
16493
|
+
var GOOGLE_GENAI_INTERNAL_CONTEXT = {
|
|
16494
|
+
caller_filename: "<node-internal>",
|
|
16495
|
+
caller_functionname: "<node-internal>",
|
|
16496
|
+
caller_lineno: 0
|
|
16497
|
+
};
|
|
16498
|
+
function createWrapperParityEvent(args) {
|
|
16499
|
+
return {
|
|
16500
|
+
context: GOOGLE_GENAI_INTERNAL_CONTEXT,
|
|
16501
|
+
input: args.input,
|
|
16502
|
+
metadata: args.metadata
|
|
16503
|
+
};
|
|
16504
|
+
}
|
|
15935
16505
|
var GoogleGenAIPlugin = class extends BasePlugin {
|
|
15936
16506
|
onEnable() {
|
|
15937
16507
|
this.subscribeToGoogleGenAIChannels();
|
|
@@ -15940,51 +16510,282 @@ var GoogleGenAIPlugin = class extends BasePlugin {
|
|
|
15940
16510
|
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
15941
16511
|
}
|
|
15942
16512
|
subscribeToGoogleGenAIChannels() {
|
|
15943
|
-
this.
|
|
15944
|
-
|
|
15945
|
-
|
|
15946
|
-
|
|
15947
|
-
|
|
15948
|
-
|
|
15949
|
-
|
|
15950
|
-
|
|
15951
|
-
|
|
15952
|
-
|
|
15953
|
-
|
|
15954
|
-
|
|
15955
|
-
|
|
15956
|
-
|
|
15957
|
-
|
|
15958
|
-
|
|
15959
|
-
|
|
15960
|
-
|
|
15961
|
-
|
|
16513
|
+
this.subscribeToGenerateContentChannel();
|
|
16514
|
+
this.subscribeToGenerateContentStreamChannel();
|
|
16515
|
+
}
|
|
16516
|
+
subscribeToGenerateContentChannel() {
|
|
16517
|
+
const tracingChannel2 = googleGenAIChannels.generateContent.tracingChannel();
|
|
16518
|
+
const states = /* @__PURE__ */ new WeakMap();
|
|
16519
|
+
const unbindCurrentSpanStore = bindCurrentSpanStoreToStart2(
|
|
16520
|
+
tracingChannel2,
|
|
16521
|
+
states,
|
|
16522
|
+
(event) => {
|
|
16523
|
+
const params = event.arguments[0];
|
|
16524
|
+
const input = serializeInput(params);
|
|
16525
|
+
const metadata = extractMetadata(params);
|
|
16526
|
+
const span = startSpan({
|
|
16527
|
+
name: "generate_content",
|
|
16528
|
+
spanAttributes: {
|
|
16529
|
+
type: "llm" /* LLM */
|
|
16530
|
+
},
|
|
16531
|
+
event: createWrapperParityEvent({ input, metadata })
|
|
16532
|
+
});
|
|
16533
|
+
return {
|
|
16534
|
+
span,
|
|
16535
|
+
startTime: getCurrentUnixTimestamp()
|
|
16536
|
+
};
|
|
16537
|
+
}
|
|
15962
16538
|
);
|
|
15963
|
-
|
|
15964
|
-
|
|
15965
|
-
|
|
15966
|
-
|
|
15967
|
-
extractInput: ([params]) => {
|
|
16539
|
+
const handlers = {
|
|
16540
|
+
start: (event) => {
|
|
16541
|
+
ensureSpanState(states, event, () => {
|
|
16542
|
+
const params = event.arguments[0];
|
|
15968
16543
|
const input = serializeInput(params);
|
|
15969
16544
|
const metadata = extractMetadata(params);
|
|
16545
|
+
const span = startSpan({
|
|
16546
|
+
name: "generate_content",
|
|
16547
|
+
spanAttributes: {
|
|
16548
|
+
type: "llm" /* LLM */
|
|
16549
|
+
},
|
|
16550
|
+
event: createWrapperParityEvent({ input, metadata })
|
|
16551
|
+
});
|
|
15970
16552
|
return {
|
|
15971
|
-
|
|
15972
|
-
|
|
16553
|
+
span,
|
|
16554
|
+
startTime: getCurrentUnixTimestamp()
|
|
15973
16555
|
};
|
|
15974
|
-
}
|
|
15975
|
-
|
|
15976
|
-
|
|
15977
|
-
|
|
15978
|
-
|
|
15979
|
-
return
|
|
15980
|
-
},
|
|
15981
|
-
aggregateChunks: (chunks, _result, _endEvent, startTime) => {
|
|
15982
|
-
return aggregateGenerateContentChunks(chunks, startTime);
|
|
16556
|
+
});
|
|
16557
|
+
},
|
|
16558
|
+
asyncEnd: (event) => {
|
|
16559
|
+
const spanState = states.get(event);
|
|
16560
|
+
if (!spanState) {
|
|
16561
|
+
return;
|
|
15983
16562
|
}
|
|
15984
|
-
|
|
15985
|
-
|
|
16563
|
+
try {
|
|
16564
|
+
spanState.span.log({
|
|
16565
|
+
metrics: cleanMetrics(
|
|
16566
|
+
extractGenerateContentMetrics(
|
|
16567
|
+
event.result,
|
|
16568
|
+
spanState.startTime
|
|
16569
|
+
)
|
|
16570
|
+
),
|
|
16571
|
+
output: event.result
|
|
16572
|
+
});
|
|
16573
|
+
} finally {
|
|
16574
|
+
spanState.span.end();
|
|
16575
|
+
states.delete(event);
|
|
16576
|
+
}
|
|
16577
|
+
},
|
|
16578
|
+
error: (event) => {
|
|
16579
|
+
logErrorAndEndSpan(states, event);
|
|
16580
|
+
}
|
|
16581
|
+
};
|
|
16582
|
+
tracingChannel2.subscribe(handlers);
|
|
16583
|
+
this.unsubscribers.push(() => {
|
|
16584
|
+
unbindCurrentSpanStore?.();
|
|
16585
|
+
tracingChannel2.unsubscribe(handlers);
|
|
16586
|
+
});
|
|
16587
|
+
}
|
|
16588
|
+
subscribeToGenerateContentStreamChannel() {
|
|
16589
|
+
const tracingChannel2 = googleGenAIChannels.generateContentStream.tracingChannel();
|
|
16590
|
+
const handlers = {
|
|
16591
|
+
start: (event) => {
|
|
16592
|
+
const streamEvent = event;
|
|
16593
|
+
const params = event.arguments[0];
|
|
16594
|
+
streamEvent.googleGenAIInput = serializeInput(params);
|
|
16595
|
+
streamEvent.googleGenAIMetadata = extractMetadata(params);
|
|
16596
|
+
},
|
|
16597
|
+
asyncEnd: (event) => {
|
|
16598
|
+
const streamEvent = event;
|
|
16599
|
+
patchGoogleGenAIStreamingResult({
|
|
16600
|
+
input: streamEvent.googleGenAIInput,
|
|
16601
|
+
metadata: streamEvent.googleGenAIMetadata,
|
|
16602
|
+
result: streamEvent.result
|
|
16603
|
+
});
|
|
16604
|
+
},
|
|
16605
|
+
error: () => {
|
|
16606
|
+
}
|
|
16607
|
+
};
|
|
16608
|
+
tracingChannel2.subscribe(handlers);
|
|
16609
|
+
this.unsubscribers.push(() => {
|
|
16610
|
+
tracingChannel2.unsubscribe(handlers);
|
|
16611
|
+
});
|
|
15986
16612
|
}
|
|
15987
16613
|
};
|
|
16614
|
+
function ensureSpanState(states, event, create) {
|
|
16615
|
+
const existing = states.get(event);
|
|
16616
|
+
if (existing) {
|
|
16617
|
+
return existing;
|
|
16618
|
+
}
|
|
16619
|
+
const created = create();
|
|
16620
|
+
states.set(event, created);
|
|
16621
|
+
return created;
|
|
16622
|
+
}
|
|
16623
|
+
function bindCurrentSpanStoreToStart2(tracingChannel2, states, create) {
|
|
16624
|
+
const state = _internalGetGlobalState();
|
|
16625
|
+
const startChannel = tracingChannel2.start;
|
|
16626
|
+
const currentSpanStore = state?.contextManager ? state.contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
|
|
16627
|
+
if (!startChannel?.bindStore || !currentSpanStore) {
|
|
16628
|
+
return void 0;
|
|
16629
|
+
}
|
|
16630
|
+
startChannel.bindStore(
|
|
16631
|
+
currentSpanStore,
|
|
16632
|
+
(event) => ensureSpanState(
|
|
16633
|
+
states,
|
|
16634
|
+
event,
|
|
16635
|
+
() => create(event)
|
|
16636
|
+
).span
|
|
16637
|
+
);
|
|
16638
|
+
return () => {
|
|
16639
|
+
startChannel.unbindStore?.(currentSpanStore);
|
|
16640
|
+
};
|
|
16641
|
+
}
|
|
16642
|
+
function logErrorAndEndSpan(states, event) {
|
|
16643
|
+
const spanState = states.get(event);
|
|
16644
|
+
if (!spanState) {
|
|
16645
|
+
return;
|
|
16646
|
+
}
|
|
16647
|
+
spanState.span.log({
|
|
16648
|
+
error: event.error.message
|
|
16649
|
+
});
|
|
16650
|
+
spanState.span.end();
|
|
16651
|
+
states.delete(event);
|
|
16652
|
+
}
|
|
16653
|
+
function patchGoogleGenAIStreamingResult(args) {
|
|
16654
|
+
const { input, metadata, result } = args;
|
|
16655
|
+
if (!input || !metadata || !result || typeof result !== "object" || typeof result.next !== "function") {
|
|
16656
|
+
return false;
|
|
16657
|
+
}
|
|
16658
|
+
const chunks = [];
|
|
16659
|
+
let firstTokenTime = null;
|
|
16660
|
+
let finalized = false;
|
|
16661
|
+
let span = null;
|
|
16662
|
+
let startTime = null;
|
|
16663
|
+
const ensureSpan = () => {
|
|
16664
|
+
if (!span) {
|
|
16665
|
+
span = startSpan({
|
|
16666
|
+
name: "generate_content_stream",
|
|
16667
|
+
spanAttributes: {
|
|
16668
|
+
type: "llm" /* LLM */
|
|
16669
|
+
},
|
|
16670
|
+
event: {
|
|
16671
|
+
input,
|
|
16672
|
+
metadata
|
|
16673
|
+
}
|
|
16674
|
+
});
|
|
16675
|
+
startTime = getCurrentUnixTimestamp();
|
|
16676
|
+
}
|
|
16677
|
+
return span;
|
|
16678
|
+
};
|
|
16679
|
+
const finalize = (options) => {
|
|
16680
|
+
if (finalized || !span) {
|
|
16681
|
+
return;
|
|
16682
|
+
}
|
|
16683
|
+
finalized = true;
|
|
16684
|
+
if (options.result) {
|
|
16685
|
+
const { end, ...metricsWithoutEnd } = options.result.metrics;
|
|
16686
|
+
span.log({
|
|
16687
|
+
metrics: cleanMetrics(metricsWithoutEnd),
|
|
16688
|
+
output: options.result.aggregated
|
|
16689
|
+
});
|
|
16690
|
+
span.end(typeof end === "number" ? { endTime: end } : void 0);
|
|
16691
|
+
return;
|
|
16692
|
+
}
|
|
16693
|
+
if (options.error !== void 0) {
|
|
16694
|
+
span.log({
|
|
16695
|
+
error: options.error instanceof Error ? options.error.message : String(options.error)
|
|
16696
|
+
});
|
|
16697
|
+
}
|
|
16698
|
+
span.end();
|
|
16699
|
+
};
|
|
16700
|
+
const patchIterator = (iterator) => {
|
|
16701
|
+
if (typeof iterator !== "object" || iterator === null || "__braintrustGoogleGenAIPatched" in iterator) {
|
|
16702
|
+
return iterator;
|
|
16703
|
+
}
|
|
16704
|
+
const iteratorRecord = iterator;
|
|
16705
|
+
const originalNext = typeof iteratorRecord.next === "function" ? iteratorRecord.next.bind(iterator) : void 0;
|
|
16706
|
+
const originalReturn = typeof iteratorRecord.return === "function" ? iteratorRecord.return.bind(iterator) : void 0;
|
|
16707
|
+
const originalThrow = typeof iteratorRecord.throw === "function" ? iteratorRecord.throw.bind(iterator) : void 0;
|
|
16708
|
+
const asyncIteratorMethod = iteratorRecord[Symbol.asyncIterator];
|
|
16709
|
+
const originalAsyncIterator = typeof asyncIteratorMethod === "function" ? asyncIteratorMethod.bind(iterator) : void 0;
|
|
16710
|
+
Object.defineProperty(iteratorRecord, "__braintrustGoogleGenAIPatched", {
|
|
16711
|
+
configurable: true,
|
|
16712
|
+
enumerable: false,
|
|
16713
|
+
value: true,
|
|
16714
|
+
writable: false
|
|
16715
|
+
});
|
|
16716
|
+
if (originalNext) {
|
|
16717
|
+
iteratorRecord.next = async (...nextArgs) => {
|
|
16718
|
+
ensureSpan();
|
|
16719
|
+
try {
|
|
16720
|
+
const nextResult = await originalNext(
|
|
16721
|
+
...nextArgs
|
|
16722
|
+
);
|
|
16723
|
+
if (!nextResult.done && nextResult.value) {
|
|
16724
|
+
if (firstTokenTime === null) {
|
|
16725
|
+
firstTokenTime = getCurrentUnixTimestamp();
|
|
16726
|
+
}
|
|
16727
|
+
chunks.push(nextResult.value);
|
|
16728
|
+
}
|
|
16729
|
+
if (nextResult.done && startTime !== null) {
|
|
16730
|
+
finalize({
|
|
16731
|
+
result: aggregateGenerateContentChunks(
|
|
16732
|
+
chunks,
|
|
16733
|
+
startTime,
|
|
16734
|
+
firstTokenTime
|
|
16735
|
+
)
|
|
16736
|
+
});
|
|
16737
|
+
}
|
|
16738
|
+
return nextResult;
|
|
16739
|
+
} catch (error2) {
|
|
16740
|
+
finalize({ error: error2 });
|
|
16741
|
+
throw error2;
|
|
16742
|
+
}
|
|
16743
|
+
};
|
|
16744
|
+
}
|
|
16745
|
+
if (originalReturn) {
|
|
16746
|
+
iteratorRecord.return = async (...returnArgs) => {
|
|
16747
|
+
ensureSpan();
|
|
16748
|
+
try {
|
|
16749
|
+
return await originalReturn(
|
|
16750
|
+
...returnArgs
|
|
16751
|
+
);
|
|
16752
|
+
} finally {
|
|
16753
|
+
if (startTime !== null) {
|
|
16754
|
+
finalize({
|
|
16755
|
+
result: chunks.length > 0 ? aggregateGenerateContentChunks(
|
|
16756
|
+
chunks,
|
|
16757
|
+
startTime,
|
|
16758
|
+
firstTokenTime
|
|
16759
|
+
) : void 0
|
|
16760
|
+
});
|
|
16761
|
+
} else {
|
|
16762
|
+
finalize({});
|
|
16763
|
+
}
|
|
16764
|
+
}
|
|
16765
|
+
};
|
|
16766
|
+
}
|
|
16767
|
+
if (originalThrow) {
|
|
16768
|
+
iteratorRecord.throw = async (...throwArgs) => {
|
|
16769
|
+
ensureSpan();
|
|
16770
|
+
try {
|
|
16771
|
+
return await originalThrow(
|
|
16772
|
+
...throwArgs
|
|
16773
|
+
);
|
|
16774
|
+
} catch (error2) {
|
|
16775
|
+
finalize({ error: error2 });
|
|
16776
|
+
throw error2;
|
|
16777
|
+
}
|
|
16778
|
+
};
|
|
16779
|
+
}
|
|
16780
|
+
iteratorRecord[Symbol.asyncIterator] = () => {
|
|
16781
|
+
const asyncIterator = originalAsyncIterator ? originalAsyncIterator() : iterator;
|
|
16782
|
+
return patchIterator(asyncIterator);
|
|
16783
|
+
};
|
|
16784
|
+
return iterator;
|
|
16785
|
+
};
|
|
16786
|
+
patchIterator(result);
|
|
16787
|
+
return true;
|
|
16788
|
+
}
|
|
15988
16789
|
function serializeInput(params) {
|
|
15989
16790
|
const input = {
|
|
15990
16791
|
model: params.model,
|
|
@@ -15993,11 +16794,13 @@ function serializeInput(params) {
|
|
|
15993
16794
|
if (params.config) {
|
|
15994
16795
|
const config3 = tryToDict(params.config);
|
|
15995
16796
|
if (config3) {
|
|
15996
|
-
const
|
|
15997
|
-
|
|
15998
|
-
|
|
15999
|
-
|
|
16000
|
-
|
|
16797
|
+
const filteredConfig = {};
|
|
16798
|
+
Object.keys(config3).forEach((key) => {
|
|
16799
|
+
if (key !== "tools") {
|
|
16800
|
+
filteredConfig[key] = config3[key];
|
|
16801
|
+
}
|
|
16802
|
+
});
|
|
16803
|
+
input.config = filteredConfig;
|
|
16001
16804
|
}
|
|
16002
16805
|
}
|
|
16003
16806
|
return input;
|
|
@@ -16084,12 +16887,18 @@ function extractMetadata(params) {
|
|
|
16084
16887
|
});
|
|
16085
16888
|
}
|
|
16086
16889
|
}
|
|
16890
|
+
const tools = serializeTools(params);
|
|
16891
|
+
if (tools) {
|
|
16892
|
+
metadata.tools = tools;
|
|
16893
|
+
}
|
|
16087
16894
|
return metadata;
|
|
16088
16895
|
}
|
|
16089
16896
|
function extractGenerateContentMetrics(response, startTime) {
|
|
16090
16897
|
const metrics = {};
|
|
16091
|
-
if (startTime) {
|
|
16898
|
+
if (startTime !== void 0) {
|
|
16092
16899
|
const end = getCurrentUnixTimestamp();
|
|
16900
|
+
metrics.start = startTime;
|
|
16901
|
+
metrics.end = end;
|
|
16093
16902
|
metrics.duration = end - startTime;
|
|
16094
16903
|
}
|
|
16095
16904
|
if (response?.usageMetadata) {
|
|
@@ -16114,19 +16923,18 @@ function populateUsageMetrics(metrics, usage) {
|
|
|
16114
16923
|
metrics.completion_reasoning_tokens = usage.thoughtsTokenCount;
|
|
16115
16924
|
}
|
|
16116
16925
|
}
|
|
16117
|
-
function aggregateGenerateContentChunks(chunks, startTime) {
|
|
16118
|
-
const
|
|
16119
|
-
|
|
16120
|
-
|
|
16121
|
-
|
|
16122
|
-
|
|
16123
|
-
|
|
16124
|
-
if (
|
|
16125
|
-
firstTokenTime = getCurrentUnixTimestamp();
|
|
16926
|
+
function aggregateGenerateContentChunks(chunks, startTime, firstTokenTime) {
|
|
16927
|
+
const end = getCurrentUnixTimestamp();
|
|
16928
|
+
const metrics = {
|
|
16929
|
+
start: startTime,
|
|
16930
|
+
end,
|
|
16931
|
+
duration: end - startTime
|
|
16932
|
+
};
|
|
16933
|
+
if (firstTokenTime !== null) {
|
|
16126
16934
|
metrics.time_to_first_token = firstTokenTime - startTime;
|
|
16127
16935
|
}
|
|
16128
16936
|
if (chunks.length === 0) {
|
|
16129
|
-
return {
|
|
16937
|
+
return { aggregated: {}, metrics };
|
|
16130
16938
|
}
|
|
16131
16939
|
let text = "";
|
|
16132
16940
|
let thoughtText = "";
|
|
@@ -16162,7 +16970,7 @@ function aggregateGenerateContentChunks(chunks, startTime) {
|
|
|
16162
16970
|
}
|
|
16163
16971
|
}
|
|
16164
16972
|
}
|
|
16165
|
-
const
|
|
16973
|
+
const aggregated = {};
|
|
16166
16974
|
const parts = [];
|
|
16167
16975
|
if (thoughtText) {
|
|
16168
16976
|
parts.push({ text: thoughtText, thought: true });
|
|
@@ -16188,16 +16996,25 @@ function aggregateGenerateContentChunks(chunks, startTime) {
|
|
|
16188
16996
|
}
|
|
16189
16997
|
candidates.push(candidateDict);
|
|
16190
16998
|
}
|
|
16191
|
-
|
|
16999
|
+
aggregated.candidates = candidates;
|
|
16192
17000
|
}
|
|
16193
17001
|
if (usageMetadata) {
|
|
16194
|
-
|
|
17002
|
+
aggregated.usageMetadata = usageMetadata;
|
|
16195
17003
|
populateUsageMetrics(metrics, usageMetadata);
|
|
16196
17004
|
}
|
|
16197
17005
|
if (text) {
|
|
16198
|
-
|
|
17006
|
+
aggregated.text = text;
|
|
16199
17007
|
}
|
|
16200
|
-
return {
|
|
17008
|
+
return { aggregated, metrics };
|
|
17009
|
+
}
|
|
17010
|
+
function cleanMetrics(metrics) {
|
|
17011
|
+
const cleaned = {};
|
|
17012
|
+
for (const [key, value] of Object.entries(metrics)) {
|
|
17013
|
+
if (value !== null && value !== void 0) {
|
|
17014
|
+
cleaned[key] = value;
|
|
17015
|
+
}
|
|
17016
|
+
}
|
|
17017
|
+
return cleaned;
|
|
16201
17018
|
}
|
|
16202
17019
|
function tryToDict(obj) {
|
|
16203
17020
|
if (obj === null || obj === void 0) {
|
|
@@ -16213,54 +17030,1076 @@ function tryToDict(obj) {
|
|
|
16213
17030
|
return null;
|
|
16214
17031
|
}
|
|
16215
17032
|
|
|
16216
|
-
// src/instrumentation/
|
|
16217
|
-
var
|
|
16218
|
-
|
|
16219
|
-
|
|
16220
|
-
|
|
16221
|
-
|
|
16222
|
-
|
|
16223
|
-
|
|
16224
|
-
|
|
16225
|
-
|
|
16226
|
-
|
|
17033
|
+
// src/instrumentation/plugins/openrouter-channels.ts
|
|
17034
|
+
var openRouterChannels = defineChannels("@openrouter/sdk", {
|
|
17035
|
+
chatSend: channel({
|
|
17036
|
+
channelName: "chat.send",
|
|
17037
|
+
kind: "async"
|
|
17038
|
+
}),
|
|
17039
|
+
embeddingsGenerate: channel({
|
|
17040
|
+
channelName: "embeddings.generate",
|
|
17041
|
+
kind: "async"
|
|
17042
|
+
}),
|
|
17043
|
+
betaResponsesSend: channel({
|
|
17044
|
+
channelName: "beta.responses.send",
|
|
17045
|
+
kind: "async"
|
|
17046
|
+
}),
|
|
17047
|
+
callModel: channel({
|
|
17048
|
+
channelName: "callModel",
|
|
17049
|
+
kind: "sync-stream"
|
|
17050
|
+
}),
|
|
17051
|
+
toolExecute: channel({
|
|
17052
|
+
channelName: "tool.execute",
|
|
17053
|
+
kind: "async"
|
|
17054
|
+
})
|
|
17055
|
+
});
|
|
17056
|
+
|
|
17057
|
+
// src/openrouter-utils.ts
|
|
17058
|
+
var TOKEN_NAME_MAP2 = {
|
|
17059
|
+
promptTokens: "prompt_tokens",
|
|
17060
|
+
inputTokens: "prompt_tokens",
|
|
17061
|
+
completionTokens: "completion_tokens",
|
|
17062
|
+
outputTokens: "completion_tokens",
|
|
17063
|
+
totalTokens: "tokens",
|
|
17064
|
+
prompt_tokens: "prompt_tokens",
|
|
17065
|
+
input_tokens: "prompt_tokens",
|
|
17066
|
+
completion_tokens: "completion_tokens",
|
|
17067
|
+
output_tokens: "completion_tokens",
|
|
17068
|
+
total_tokens: "tokens"
|
|
17069
|
+
};
|
|
17070
|
+
var TOKEN_DETAIL_PREFIX_MAP = {
|
|
17071
|
+
promptTokensDetails: "prompt",
|
|
17072
|
+
inputTokensDetails: "prompt",
|
|
17073
|
+
completionTokensDetails: "completion",
|
|
17074
|
+
outputTokensDetails: "completion",
|
|
17075
|
+
costDetails: "cost",
|
|
17076
|
+
prompt_tokens_details: "prompt",
|
|
17077
|
+
input_tokens_details: "prompt",
|
|
17078
|
+
completion_tokens_details: "completion",
|
|
17079
|
+
output_tokens_details: "completion",
|
|
17080
|
+
cost_details: "cost"
|
|
17081
|
+
};
|
|
17082
|
+
function camelToSnake(value) {
|
|
17083
|
+
return value.replace(/[A-Z]/g, (match) => `_${match.toLowerCase()}`);
|
|
17084
|
+
}
|
|
17085
|
+
function parseOpenRouterMetricsFromUsage(usage) {
|
|
17086
|
+
if (!isObject(usage)) {
|
|
17087
|
+
return {};
|
|
16227
17088
|
}
|
|
16228
|
-
|
|
16229
|
-
|
|
16230
|
-
if (
|
|
16231
|
-
|
|
16232
|
-
|
|
16233
|
-
}
|
|
16234
|
-
if (integrations.anthropic !== false) {
|
|
16235
|
-
this.anthropicPlugin = new AnthropicPlugin();
|
|
16236
|
-
this.anthropicPlugin.enable();
|
|
17089
|
+
const metrics = {};
|
|
17090
|
+
for (const [name, value] of Object.entries(usage)) {
|
|
17091
|
+
if (typeof value === "number") {
|
|
17092
|
+
metrics[TOKEN_NAME_MAP2[name] || camelToSnake(name)] = value;
|
|
17093
|
+
continue;
|
|
16237
17094
|
}
|
|
16238
|
-
if (
|
|
16239
|
-
|
|
16240
|
-
this.aiSDKPlugin.enable();
|
|
17095
|
+
if (!isObject(value)) {
|
|
17096
|
+
continue;
|
|
16241
17097
|
}
|
|
16242
|
-
|
|
16243
|
-
|
|
16244
|
-
|
|
17098
|
+
const prefix = TOKEN_DETAIL_PREFIX_MAP[name];
|
|
17099
|
+
if (!prefix) {
|
|
17100
|
+
continue;
|
|
16245
17101
|
}
|
|
16246
|
-
|
|
16247
|
-
|
|
16248
|
-
|
|
17102
|
+
for (const [nestedName, nestedValue] of Object.entries(value)) {
|
|
17103
|
+
if (typeof nestedValue !== "number") {
|
|
17104
|
+
continue;
|
|
17105
|
+
}
|
|
17106
|
+
metrics[`${prefix}_${camelToSnake(nestedName)}`] = nestedValue;
|
|
16249
17107
|
}
|
|
16250
17108
|
}
|
|
16251
|
-
|
|
16252
|
-
|
|
16253
|
-
|
|
16254
|
-
|
|
16255
|
-
|
|
16256
|
-
|
|
16257
|
-
|
|
16258
|
-
|
|
16259
|
-
|
|
16260
|
-
|
|
16261
|
-
|
|
16262
|
-
|
|
16263
|
-
|
|
17109
|
+
return metrics;
|
|
17110
|
+
}
|
|
17111
|
+
function extractOpenRouterUsageMetadata(usage) {
|
|
17112
|
+
if (!isObject(usage)) {
|
|
17113
|
+
return void 0;
|
|
17114
|
+
}
|
|
17115
|
+
const metadata = {};
|
|
17116
|
+
if (typeof usage.isByok === "boolean") {
|
|
17117
|
+
metadata.is_byok = usage.isByok;
|
|
17118
|
+
} else if (typeof usage.is_byok === "boolean") {
|
|
17119
|
+
metadata.is_byok = usage.is_byok;
|
|
17120
|
+
}
|
|
17121
|
+
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
17122
|
+
}
|
|
17123
|
+
|
|
17124
|
+
// src/openrouter-logging.ts
|
|
17125
|
+
var OMITTED_OPENROUTER_KEYS = /* @__PURE__ */ new Set([
|
|
17126
|
+
"execute",
|
|
17127
|
+
"render",
|
|
17128
|
+
"nextTurnParams",
|
|
17129
|
+
"requireApproval"
|
|
17130
|
+
]);
|
|
17131
|
+
function parseOpenRouterModelString(model) {
|
|
17132
|
+
if (typeof model !== "string") {
|
|
17133
|
+
return { model };
|
|
17134
|
+
}
|
|
17135
|
+
const slashIndex = model.indexOf("/");
|
|
17136
|
+
if (slashIndex > 0 && slashIndex < model.length - 1) {
|
|
17137
|
+
return {
|
|
17138
|
+
provider: model.substring(0, slashIndex),
|
|
17139
|
+
model: model.substring(slashIndex + 1)
|
|
17140
|
+
};
|
|
17141
|
+
}
|
|
17142
|
+
return { model };
|
|
17143
|
+
}
|
|
17144
|
+
function isZodSchema2(value) {
|
|
17145
|
+
return value != null && typeof value === "object" && "_def" in value && typeof value._def === "object";
|
|
17146
|
+
}
|
|
17147
|
+
function serializeZodSchema2(schema) {
|
|
17148
|
+
try {
|
|
17149
|
+
return zodToJsonSchema(schema);
|
|
17150
|
+
} catch {
|
|
17151
|
+
return {
|
|
17152
|
+
type: "object",
|
|
17153
|
+
description: "Zod schema (conversion failed)"
|
|
17154
|
+
};
|
|
17155
|
+
}
|
|
17156
|
+
}
|
|
17157
|
+
function serializeOpenRouterTool(tool) {
|
|
17158
|
+
if (!isObject(tool)) {
|
|
17159
|
+
return tool;
|
|
17160
|
+
}
|
|
17161
|
+
const serialized = {};
|
|
17162
|
+
for (const [key, value] of Object.entries(tool)) {
|
|
17163
|
+
if (OMITTED_OPENROUTER_KEYS.has(key)) {
|
|
17164
|
+
continue;
|
|
17165
|
+
}
|
|
17166
|
+
if (key === "function" && isObject(value)) {
|
|
17167
|
+
serialized.function = sanitizeOpenRouterLoggedValue(value);
|
|
17168
|
+
continue;
|
|
17169
|
+
}
|
|
17170
|
+
serialized[key] = sanitizeOpenRouterLoggedValue(value);
|
|
17171
|
+
}
|
|
17172
|
+
return serialized;
|
|
17173
|
+
}
|
|
17174
|
+
function serializeOpenRouterToolsForLogging(tools) {
|
|
17175
|
+
if (!Array.isArray(tools)) {
|
|
17176
|
+
return void 0;
|
|
17177
|
+
}
|
|
17178
|
+
return tools.map((tool) => serializeOpenRouterTool(tool));
|
|
17179
|
+
}
|
|
17180
|
+
function sanitizeOpenRouterLoggedValue(value) {
|
|
17181
|
+
if (isZodSchema2(value)) {
|
|
17182
|
+
return serializeZodSchema2(value);
|
|
17183
|
+
}
|
|
17184
|
+
if (typeof value === "function") {
|
|
17185
|
+
return "[Function]";
|
|
17186
|
+
}
|
|
17187
|
+
if (Array.isArray(value)) {
|
|
17188
|
+
return value.map((entry) => sanitizeOpenRouterLoggedValue(entry));
|
|
17189
|
+
}
|
|
17190
|
+
if (!isObject(value)) {
|
|
17191
|
+
return value;
|
|
17192
|
+
}
|
|
17193
|
+
const sanitized = {};
|
|
17194
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
17195
|
+
if (OMITTED_OPENROUTER_KEYS.has(key)) {
|
|
17196
|
+
continue;
|
|
17197
|
+
}
|
|
17198
|
+
if (key === "tools" && Array.isArray(entry)) {
|
|
17199
|
+
sanitized.tools = serializeOpenRouterToolsForLogging(entry);
|
|
17200
|
+
continue;
|
|
17201
|
+
}
|
|
17202
|
+
sanitized[key] = sanitizeOpenRouterLoggedValue(entry);
|
|
17203
|
+
}
|
|
17204
|
+
return sanitized;
|
|
17205
|
+
}
|
|
17206
|
+
function buildOpenRouterMetadata(metadata, httpReferer, xTitle) {
|
|
17207
|
+
const sanitized = sanitizeOpenRouterLoggedValue(metadata);
|
|
17208
|
+
const metadataRecord = isObject(sanitized) ? sanitized : {};
|
|
17209
|
+
const { model, provider: providerRouting, ...rest } = metadataRecord;
|
|
17210
|
+
const normalizedModel = parseOpenRouterModelString(model);
|
|
17211
|
+
return {
|
|
17212
|
+
...rest,
|
|
17213
|
+
...normalizedModel.model !== void 0 ? { model: normalizedModel.model } : {},
|
|
17214
|
+
...providerRouting !== void 0 ? { providerRouting } : {},
|
|
17215
|
+
...httpReferer !== void 0 ? { httpReferer } : {},
|
|
17216
|
+
...xTitle !== void 0 ? { xTitle } : {},
|
|
17217
|
+
provider: normalizedModel.provider || "openrouter"
|
|
17218
|
+
};
|
|
17219
|
+
}
|
|
17220
|
+
function buildOpenRouterEmbeddingMetadata(metadata, httpReferer, xTitle) {
|
|
17221
|
+
const normalized = buildOpenRouterMetadata(metadata, httpReferer, xTitle);
|
|
17222
|
+
return typeof normalized.model === "string" ? {
|
|
17223
|
+
...normalized,
|
|
17224
|
+
embedding_model: normalized.model
|
|
17225
|
+
} : normalized;
|
|
17226
|
+
}
|
|
17227
|
+
function extractOpenRouterCallModelInput(request) {
|
|
17228
|
+
return isObject(request) && "input" in request ? sanitizeOpenRouterLoggedValue(request.input) : void 0;
|
|
17229
|
+
}
|
|
17230
|
+
function extractOpenRouterCallModelMetadata(request) {
|
|
17231
|
+
if (!isObject(request)) {
|
|
17232
|
+
return { provider: "openrouter" };
|
|
17233
|
+
}
|
|
17234
|
+
const { input: _input, ...metadata } = request;
|
|
17235
|
+
return buildOpenRouterMetadata(metadata, void 0, void 0);
|
|
17236
|
+
}
|
|
17237
|
+
function extractOpenRouterResponseMetadata(result) {
|
|
17238
|
+
if (!isObject(result)) {
|
|
17239
|
+
return void 0;
|
|
17240
|
+
}
|
|
17241
|
+
const { output: _output, data: _data, usage, ...metadata } = result;
|
|
17242
|
+
const sanitized = sanitizeOpenRouterLoggedValue(metadata);
|
|
17243
|
+
const metadataRecord = isObject(sanitized) ? sanitized : {};
|
|
17244
|
+
const { model, provider, ...rest } = metadataRecord;
|
|
17245
|
+
const normalizedModel = parseOpenRouterModelString(model);
|
|
17246
|
+
const normalizedProvider = (typeof provider === "string" ? provider : void 0) || normalizedModel.provider;
|
|
17247
|
+
const usageMetadata = extractOpenRouterUsageMetadata(usage);
|
|
17248
|
+
const combined = {
|
|
17249
|
+
...rest,
|
|
17250
|
+
...normalizedModel.model !== void 0 ? { model: normalizedModel.model } : {},
|
|
17251
|
+
...usageMetadata || {},
|
|
17252
|
+
...normalizedProvider !== void 0 ? { provider: normalizedProvider } : {}
|
|
17253
|
+
};
|
|
17254
|
+
return Object.keys(combined).length > 0 ? combined : void 0;
|
|
17255
|
+
}
|
|
17256
|
+
function extractOpenRouterResponseOutput(response, fallbackOutput) {
|
|
17257
|
+
if (isObject(response) && "output" in response && response.output !== void 0) {
|
|
17258
|
+
return sanitizeOpenRouterLoggedValue(response.output);
|
|
17259
|
+
}
|
|
17260
|
+
if (fallbackOutput !== void 0) {
|
|
17261
|
+
return sanitizeOpenRouterLoggedValue(fallbackOutput);
|
|
17262
|
+
}
|
|
17263
|
+
return void 0;
|
|
17264
|
+
}
|
|
17265
|
+
|
|
17266
|
+
// src/openrouter-tool-wrapping.ts
|
|
17267
|
+
var OPENROUTER_WRAPPED_TOOL = Symbol("braintrust.openrouter.wrappedTool");
|
|
17268
|
+
var OPENROUTER_WRAPPED_CALL_MODEL_RESULT = Symbol(
|
|
17269
|
+
"braintrust.openrouter.wrappedCallModelResult"
|
|
17270
|
+
);
|
|
17271
|
+
var OPENROUTER_CALL_MODEL_STREAM_METHODS = [
|
|
17272
|
+
"getFullResponsesStream",
|
|
17273
|
+
"getItemsStream",
|
|
17274
|
+
"getNewMessagesStream",
|
|
17275
|
+
"getReasoningStream",
|
|
17276
|
+
"getTextStream",
|
|
17277
|
+
"getToolCallsStream",
|
|
17278
|
+
"getToolStream"
|
|
17279
|
+
];
|
|
17280
|
+
var OPENROUTER_CALL_MODEL_CONTEXT_METHODS = [
|
|
17281
|
+
"cancel",
|
|
17282
|
+
"getPendingToolCalls",
|
|
17283
|
+
"getState",
|
|
17284
|
+
"getToolCalls",
|
|
17285
|
+
"requiresApproval"
|
|
17286
|
+
];
|
|
17287
|
+
function patchOpenRouterCallModelRequestTools(request) {
|
|
17288
|
+
if (!Array.isArray(request.tools) || request.tools.length === 0) {
|
|
17289
|
+
return void 0;
|
|
17290
|
+
}
|
|
17291
|
+
const originalTools = request.tools;
|
|
17292
|
+
const wrappedTools = originalTools.map((tool) => wrapOpenRouterTool(tool));
|
|
17293
|
+
const didPatch = wrappedTools.some(
|
|
17294
|
+
(tool, index) => tool !== originalTools[index]
|
|
17295
|
+
);
|
|
17296
|
+
if (!didPatch) {
|
|
17297
|
+
return void 0;
|
|
17298
|
+
}
|
|
17299
|
+
request.tools = wrappedTools;
|
|
17300
|
+
return () => {
|
|
17301
|
+
request.tools = originalTools;
|
|
17302
|
+
};
|
|
17303
|
+
}
|
|
17304
|
+
function patchOpenRouterCallModelResult(span, result, request) {
|
|
17305
|
+
if (!isObject(result) || isWrappedCallModelResult(result)) {
|
|
17306
|
+
return false;
|
|
17307
|
+
}
|
|
17308
|
+
const resultLike = result;
|
|
17309
|
+
const hasInstrumentableMethod = typeof resultLike.getResponse === "function" || typeof resultLike.getText === "function" || OPENROUTER_CALL_MODEL_STREAM_METHODS.some(
|
|
17310
|
+
(methodName) => typeof resultLike[methodName] === "function"
|
|
17311
|
+
);
|
|
17312
|
+
if (!hasInstrumentableMethod) {
|
|
17313
|
+
return false;
|
|
17314
|
+
}
|
|
17315
|
+
Object.defineProperty(resultLike, OPENROUTER_WRAPPED_CALL_MODEL_RESULT, {
|
|
17316
|
+
value: true,
|
|
17317
|
+
enumerable: false,
|
|
17318
|
+
configurable: false
|
|
17319
|
+
});
|
|
17320
|
+
const originalGetResponse = typeof resultLike.getResponse === "function" ? resultLike.getResponse.bind(resultLike) : void 0;
|
|
17321
|
+
const originalGetInitialResponse = typeof resultLike.getInitialResponse === "function" ? resultLike.getInitialResponse.bind(resultLike) : void 0;
|
|
17322
|
+
const originalMakeFollowupRequest = typeof resultLike.makeFollowupRequest === "function" ? resultLike.makeFollowupRequest.bind(resultLike) : void 0;
|
|
17323
|
+
let ended = false;
|
|
17324
|
+
let tracedTurnCount = 0;
|
|
17325
|
+
const endSpanWithResult = async (response, fallbackOutput) => {
|
|
17326
|
+
if (ended) {
|
|
17327
|
+
return;
|
|
17328
|
+
}
|
|
17329
|
+
ended = true;
|
|
17330
|
+
const finalResponse = getFinalOpenRouterCallModelResponse(
|
|
17331
|
+
resultLike,
|
|
17332
|
+
response
|
|
17333
|
+
);
|
|
17334
|
+
if (finalResponse) {
|
|
17335
|
+
const rounds = getOpenRouterCallModelRounds(resultLike);
|
|
17336
|
+
const metadata = extractOpenRouterCallModelResultMetadata(
|
|
17337
|
+
finalResponse,
|
|
17338
|
+
rounds.length + 1
|
|
17339
|
+
);
|
|
17340
|
+
span.log({
|
|
17341
|
+
output: extractOpenRouterResponseOutput(finalResponse, fallbackOutput),
|
|
17342
|
+
...metadata ? { metadata } : {},
|
|
17343
|
+
metrics: aggregateOpenRouterCallModelMetrics(rounds, finalResponse)
|
|
17344
|
+
});
|
|
17345
|
+
span.end();
|
|
17346
|
+
return;
|
|
17347
|
+
}
|
|
17348
|
+
if (fallbackOutput !== void 0) {
|
|
17349
|
+
span.log({
|
|
17350
|
+
output: fallbackOutput
|
|
17351
|
+
});
|
|
17352
|
+
}
|
|
17353
|
+
span.end();
|
|
17354
|
+
};
|
|
17355
|
+
const endSpanWithError = (error2) => {
|
|
17356
|
+
if (ended) {
|
|
17357
|
+
return;
|
|
17358
|
+
}
|
|
17359
|
+
ended = true;
|
|
17360
|
+
span.log({
|
|
17361
|
+
error: normalizeError(error2).message
|
|
17362
|
+
});
|
|
17363
|
+
span.end();
|
|
17364
|
+
};
|
|
17365
|
+
const finalizeFromResponse = async (fallbackOutput) => {
|
|
17366
|
+
if (!originalGetResponse) {
|
|
17367
|
+
await endSpanWithResult(void 0, fallbackOutput);
|
|
17368
|
+
return;
|
|
17369
|
+
}
|
|
17370
|
+
try {
|
|
17371
|
+
await endSpanWithResult(await originalGetResponse(), fallbackOutput);
|
|
17372
|
+
} catch {
|
|
17373
|
+
await endSpanWithResult(void 0, fallbackOutput);
|
|
17374
|
+
}
|
|
17375
|
+
};
|
|
17376
|
+
if (originalGetResponse) {
|
|
17377
|
+
resultLike.getResponse = async (...args) => {
|
|
17378
|
+
return await withCurrent(span, async () => {
|
|
17379
|
+
try {
|
|
17380
|
+
const response = await originalGetResponse(...args);
|
|
17381
|
+
await endSpanWithResult(response);
|
|
17382
|
+
return response;
|
|
17383
|
+
} catch (error2) {
|
|
17384
|
+
endSpanWithError(error2);
|
|
17385
|
+
throw error2;
|
|
17386
|
+
}
|
|
17387
|
+
});
|
|
17388
|
+
};
|
|
17389
|
+
}
|
|
17390
|
+
if (typeof resultLike.getText === "function") {
|
|
17391
|
+
const originalGetText = resultLike.getText.bind(resultLike);
|
|
17392
|
+
resultLike.getText = async (...args) => {
|
|
17393
|
+
return await withCurrent(span, async () => {
|
|
17394
|
+
try {
|
|
17395
|
+
const text = await originalGetText(...args);
|
|
17396
|
+
await finalizeFromResponse(text);
|
|
17397
|
+
return text;
|
|
17398
|
+
} catch (error2) {
|
|
17399
|
+
endSpanWithError(error2);
|
|
17400
|
+
throw error2;
|
|
17401
|
+
}
|
|
17402
|
+
});
|
|
17403
|
+
};
|
|
17404
|
+
}
|
|
17405
|
+
for (const methodName of OPENROUTER_CALL_MODEL_CONTEXT_METHODS) {
|
|
17406
|
+
if (typeof resultLike[methodName] !== "function") {
|
|
17407
|
+
continue;
|
|
17408
|
+
}
|
|
17409
|
+
const originalMethod = resultLike[methodName];
|
|
17410
|
+
resultLike[methodName] = async (...args) => {
|
|
17411
|
+
return await withCurrent(span, async () => {
|
|
17412
|
+
return await originalMethod.apply(resultLike, args);
|
|
17413
|
+
});
|
|
17414
|
+
};
|
|
17415
|
+
}
|
|
17416
|
+
for (const methodName of OPENROUTER_CALL_MODEL_STREAM_METHODS) {
|
|
17417
|
+
if (typeof resultLike[methodName] !== "function") {
|
|
17418
|
+
continue;
|
|
17419
|
+
}
|
|
17420
|
+
const originalMethod = resultLike[methodName];
|
|
17421
|
+
resultLike[methodName] = (...args) => {
|
|
17422
|
+
const stream = withCurrent(
|
|
17423
|
+
span,
|
|
17424
|
+
() => originalMethod.apply(resultLike, args)
|
|
17425
|
+
);
|
|
17426
|
+
if (!isAsyncIterable4(stream)) {
|
|
17427
|
+
return stream;
|
|
17428
|
+
}
|
|
17429
|
+
return wrapAsyncIterableWithSpan({
|
|
17430
|
+
finalize: finalizeFromResponse,
|
|
17431
|
+
iteratorFactory: () => stream[Symbol.asyncIterator](),
|
|
17432
|
+
onError: endSpanWithError,
|
|
17433
|
+
span
|
|
17434
|
+
});
|
|
17435
|
+
};
|
|
17436
|
+
}
|
|
17437
|
+
if (originalGetInitialResponse) {
|
|
17438
|
+
let initialTurnTraced = false;
|
|
17439
|
+
resultLike.getInitialResponse = async (...args) => {
|
|
17440
|
+
if (initialTurnTraced) {
|
|
17441
|
+
return await withCurrent(span, async () => {
|
|
17442
|
+
return await originalGetInitialResponse(...args);
|
|
17443
|
+
});
|
|
17444
|
+
}
|
|
17445
|
+
initialTurnTraced = true;
|
|
17446
|
+
const resolvedRequest = getOpenRouterResolvedRequest(resultLike, request);
|
|
17447
|
+
const childSpan = startOpenRouterCallModelTurnSpan({
|
|
17448
|
+
request: resolvedRequest,
|
|
17449
|
+
step: tracedTurnCount + 1,
|
|
17450
|
+
stepType: tracedTurnCount === 0 ? "initial" : "continue"
|
|
17451
|
+
});
|
|
17452
|
+
return await withCurrent(childSpan, async () => {
|
|
17453
|
+
try {
|
|
17454
|
+
const response = await originalGetInitialResponse(...args);
|
|
17455
|
+
tracedTurnCount++;
|
|
17456
|
+
finishOpenRouterCallModelTurnSpan({
|
|
17457
|
+
response,
|
|
17458
|
+
step: tracedTurnCount,
|
|
17459
|
+
stepType: tracedTurnCount === 1 ? "initial" : "continue",
|
|
17460
|
+
span: childSpan
|
|
17461
|
+
});
|
|
17462
|
+
return response;
|
|
17463
|
+
} catch (error2) {
|
|
17464
|
+
childSpan.log({
|
|
17465
|
+
error: normalizeError(error2).message
|
|
17466
|
+
});
|
|
17467
|
+
childSpan.end();
|
|
17468
|
+
throw error2;
|
|
17469
|
+
}
|
|
17470
|
+
});
|
|
17471
|
+
};
|
|
17472
|
+
}
|
|
17473
|
+
if (originalMakeFollowupRequest) {
|
|
17474
|
+
resultLike.makeFollowupRequest = async (...args) => {
|
|
17475
|
+
const currentResponse = args[0];
|
|
17476
|
+
const toolResults = Array.isArray(args[1]) ? args[1] : [];
|
|
17477
|
+
const resolvedRequest = getOpenRouterResolvedRequest(resultLike, request);
|
|
17478
|
+
const followupRequest = buildOpenRouterFollowupRequest(
|
|
17479
|
+
resolvedRequest,
|
|
17480
|
+
currentResponse,
|
|
17481
|
+
toolResults
|
|
17482
|
+
);
|
|
17483
|
+
const childSpan = startOpenRouterCallModelTurnSpan({
|
|
17484
|
+
request: followupRequest,
|
|
17485
|
+
step: tracedTurnCount + 1,
|
|
17486
|
+
stepType: "continue"
|
|
17487
|
+
});
|
|
17488
|
+
return await withCurrent(childSpan, async () => {
|
|
17489
|
+
try {
|
|
17490
|
+
const response = await originalMakeFollowupRequest(...args);
|
|
17491
|
+
tracedTurnCount++;
|
|
17492
|
+
finishOpenRouterCallModelTurnSpan({
|
|
17493
|
+
response,
|
|
17494
|
+
step: tracedTurnCount,
|
|
17495
|
+
stepType: "continue",
|
|
17496
|
+
span: childSpan
|
|
17497
|
+
});
|
|
17498
|
+
return response;
|
|
17499
|
+
} catch (error2) {
|
|
17500
|
+
childSpan.log({
|
|
17501
|
+
error: normalizeError(error2).message
|
|
17502
|
+
});
|
|
17503
|
+
childSpan.end();
|
|
17504
|
+
throw error2;
|
|
17505
|
+
}
|
|
17506
|
+
});
|
|
17507
|
+
};
|
|
17508
|
+
}
|
|
17509
|
+
return true;
|
|
17510
|
+
}
|
|
17511
|
+
function wrapOpenRouterTool(tool) {
|
|
17512
|
+
if (isWrappedTool(tool) || !tool.function || typeof tool.function !== "object" || typeof tool.function.execute !== "function") {
|
|
17513
|
+
return tool;
|
|
17514
|
+
}
|
|
17515
|
+
const toolName = tool.function.name || "tool";
|
|
17516
|
+
const originalExecute = tool.function.execute;
|
|
17517
|
+
const wrappedTool = {
|
|
17518
|
+
...tool,
|
|
17519
|
+
function: {
|
|
17520
|
+
...tool.function,
|
|
17521
|
+
execute(...args) {
|
|
17522
|
+
return traceToolExecution({
|
|
17523
|
+
args,
|
|
17524
|
+
execute: () => Reflect.apply(originalExecute, this, args),
|
|
17525
|
+
toolCallId: getToolCallId(args[1]),
|
|
17526
|
+
toolName
|
|
17527
|
+
});
|
|
17528
|
+
}
|
|
17529
|
+
}
|
|
17530
|
+
};
|
|
17531
|
+
Object.defineProperty(wrappedTool, OPENROUTER_WRAPPED_TOOL, {
|
|
17532
|
+
value: true,
|
|
17533
|
+
enumerable: false,
|
|
17534
|
+
configurable: false
|
|
17535
|
+
});
|
|
17536
|
+
return wrappedTool;
|
|
17537
|
+
}
|
|
17538
|
+
function isWrappedTool(tool) {
|
|
17539
|
+
return Boolean(tool[OPENROUTER_WRAPPED_TOOL]);
|
|
17540
|
+
}
|
|
17541
|
+
function isWrappedCallModelResult(value) {
|
|
17542
|
+
return Boolean(
|
|
17543
|
+
isObject(value) && value[OPENROUTER_WRAPPED_CALL_MODEL_RESULT]
|
|
17544
|
+
);
|
|
17545
|
+
}
|
|
17546
|
+
function traceToolExecution(args) {
|
|
17547
|
+
const tracingChannel2 = openRouterChannels.toolExecute.tracingChannel();
|
|
17548
|
+
const input = args.args.length > 0 ? args.args[0] : void 0;
|
|
17549
|
+
const event = {
|
|
17550
|
+
arguments: [input],
|
|
17551
|
+
span_info: {
|
|
17552
|
+
name: args.toolName
|
|
17553
|
+
},
|
|
17554
|
+
toolCallId: args.toolCallId,
|
|
17555
|
+
toolName: args.toolName
|
|
17556
|
+
};
|
|
17557
|
+
tracingChannel2.start.publish(event);
|
|
17558
|
+
try {
|
|
17559
|
+
const result = args.execute();
|
|
17560
|
+
return publishToolResult(tracingChannel2, event, result);
|
|
17561
|
+
} catch (error2) {
|
|
17562
|
+
event.error = normalizeError(error2);
|
|
17563
|
+
tracingChannel2.error.publish(event);
|
|
17564
|
+
throw error2;
|
|
17565
|
+
}
|
|
17566
|
+
}
|
|
17567
|
+
function publishToolResult(tracingChannel2, event, result) {
|
|
17568
|
+
if (isPromiseLike(result)) {
|
|
17569
|
+
return result.then(
|
|
17570
|
+
(resolved) => {
|
|
17571
|
+
event.result = resolved;
|
|
17572
|
+
tracingChannel2.asyncEnd.publish(event);
|
|
17573
|
+
return resolved;
|
|
17574
|
+
},
|
|
17575
|
+
(error2) => {
|
|
17576
|
+
event.error = normalizeError(error2);
|
|
17577
|
+
tracingChannel2.error.publish(event);
|
|
17578
|
+
throw error2;
|
|
17579
|
+
}
|
|
17580
|
+
);
|
|
17581
|
+
}
|
|
17582
|
+
event.result = result;
|
|
17583
|
+
tracingChannel2.asyncEnd.publish(event);
|
|
17584
|
+
return result;
|
|
17585
|
+
}
|
|
17586
|
+
function getToolCallId(context2) {
|
|
17587
|
+
const toolContext = context2;
|
|
17588
|
+
return typeof toolContext?.toolCall?.id === "string" ? toolContext.toolCall.id : void 0;
|
|
17589
|
+
}
|
|
17590
|
+
function extractOpenRouterCallModelResultMetadata(response, turnCount) {
|
|
17591
|
+
const combined = {
|
|
17592
|
+
...extractOpenRouterResponseMetadata(response) || {},
|
|
17593
|
+
...turnCount !== void 0 ? { turn_count: turnCount } : {}
|
|
17594
|
+
};
|
|
17595
|
+
return Object.keys(combined).length > 0 ? combined : void 0;
|
|
17596
|
+
}
|
|
17597
|
+
function getFinalOpenRouterCallModelResponse(result, response) {
|
|
17598
|
+
if (isObject(response)) {
|
|
17599
|
+
return response;
|
|
17600
|
+
}
|
|
17601
|
+
return isObject(result.finalResponse) ? result.finalResponse : void 0;
|
|
17602
|
+
}
|
|
17603
|
+
function getOpenRouterCallModelRounds(result) {
|
|
17604
|
+
if (!Array.isArray(result.allToolExecutionRounds)) {
|
|
17605
|
+
return [];
|
|
17606
|
+
}
|
|
17607
|
+
return result.allToolExecutionRounds.filter((round) => isObject(round)).map((round) => ({
|
|
17608
|
+
response: isObject(round.response) ? round.response : void 0,
|
|
17609
|
+
round: typeof round.round === "number" ? round.round : void 0,
|
|
17610
|
+
toolResults: Array.isArray(round.toolResults) ? round.toolResults : []
|
|
17611
|
+
})).filter((round) => round.response !== void 0);
|
|
17612
|
+
}
|
|
17613
|
+
function aggregateOpenRouterCallModelMetrics(rounds, finalResponse) {
|
|
17614
|
+
const metrics = {};
|
|
17615
|
+
const responses = [
|
|
17616
|
+
...rounds.map((round) => round.response).filter(isObject),
|
|
17617
|
+
finalResponse
|
|
17618
|
+
];
|
|
17619
|
+
for (const response of responses) {
|
|
17620
|
+
const responseMetrics = parseOpenRouterMetricsFromUsage(response.usage);
|
|
17621
|
+
for (const [name, value] of Object.entries(responseMetrics)) {
|
|
17622
|
+
metrics[name] = (metrics[name] || 0) + value;
|
|
17623
|
+
}
|
|
17624
|
+
}
|
|
17625
|
+
return metrics;
|
|
17626
|
+
}
|
|
17627
|
+
function buildNextOpenRouterCallModelInput(currentInput, response, toolResults) {
|
|
17628
|
+
const normalizedInput = Array.isArray(currentInput) ? [...currentInput] : currentInput === void 0 ? [] : [currentInput];
|
|
17629
|
+
const responseOutput = Array.isArray(response.output) ? response.output : response.output === void 0 ? [] : [response.output];
|
|
17630
|
+
return [...normalizedInput, ...responseOutput, ...toolResults].map(
|
|
17631
|
+
(entry) => sanitizeOpenRouterLoggedValue(entry)
|
|
17632
|
+
);
|
|
17633
|
+
}
|
|
17634
|
+
function startOpenRouterCallModelTurnSpan(args) {
|
|
17635
|
+
const requestRecord = isObject(args.request) ? args.request : void 0;
|
|
17636
|
+
const metadata = requestRecord ? extractOpenRouterCallModelMetadata(requestRecord) : { provider: "openrouter" };
|
|
17637
|
+
if (isObject(metadata) && "tools" in metadata) {
|
|
17638
|
+
delete metadata.tools;
|
|
17639
|
+
}
|
|
17640
|
+
return startSpan({
|
|
17641
|
+
name: "openrouter.beta.responses.send",
|
|
17642
|
+
spanAttributes: {
|
|
17643
|
+
type: "llm" /* LLM */
|
|
17644
|
+
},
|
|
17645
|
+
event: {
|
|
17646
|
+
input: requestRecord ? extractOpenRouterCallModelInput(requestRecord) : void 0,
|
|
17647
|
+
metadata: {
|
|
17648
|
+
...metadata,
|
|
17649
|
+
step: args.step,
|
|
17650
|
+
step_type: args.stepType
|
|
17651
|
+
}
|
|
17652
|
+
}
|
|
17653
|
+
});
|
|
17654
|
+
}
|
|
17655
|
+
function finishOpenRouterCallModelTurnSpan(args) {
|
|
17656
|
+
if (!isObject(args.response)) {
|
|
17657
|
+
args.span.end();
|
|
17658
|
+
return;
|
|
17659
|
+
}
|
|
17660
|
+
args.span.log({
|
|
17661
|
+
output: extractOpenRouterResponseOutput(args.response),
|
|
17662
|
+
...extractOpenRouterResponseMetadata(args.response) ? {
|
|
17663
|
+
metadata: {
|
|
17664
|
+
...extractOpenRouterResponseMetadata(args.response),
|
|
17665
|
+
...args.step !== void 0 ? { step: args.step } : {},
|
|
17666
|
+
...args.stepType ? { step_type: args.stepType } : {}
|
|
17667
|
+
}
|
|
17668
|
+
} : {},
|
|
17669
|
+
metrics: parseOpenRouterMetricsFromUsage(args.response.usage)
|
|
17670
|
+
});
|
|
17671
|
+
args.span.end();
|
|
17672
|
+
}
|
|
17673
|
+
function getOpenRouterResolvedRequest(result, request) {
|
|
17674
|
+
if (isObject(result.resolvedRequest)) {
|
|
17675
|
+
return result.resolvedRequest;
|
|
17676
|
+
}
|
|
17677
|
+
return request;
|
|
17678
|
+
}
|
|
17679
|
+
function buildOpenRouterFollowupRequest(request, currentResponse, toolResults) {
|
|
17680
|
+
if (!request) {
|
|
17681
|
+
return void 0;
|
|
17682
|
+
}
|
|
17683
|
+
return {
|
|
17684
|
+
...request,
|
|
17685
|
+
input: buildNextOpenRouterCallModelInput(
|
|
17686
|
+
extractOpenRouterCallModelInput(request),
|
|
17687
|
+
isObject(currentResponse) ? currentResponse : {},
|
|
17688
|
+
toolResults
|
|
17689
|
+
),
|
|
17690
|
+
stream: false
|
|
17691
|
+
};
|
|
17692
|
+
}
|
|
17693
|
+
function wrapAsyncIterableWithSpan(args) {
|
|
17694
|
+
return {
|
|
17695
|
+
[Symbol.asyncIterator]() {
|
|
17696
|
+
const iterator = args.iteratorFactory();
|
|
17697
|
+
return {
|
|
17698
|
+
next(value) {
|
|
17699
|
+
return withCurrent(
|
|
17700
|
+
args.span,
|
|
17701
|
+
() => value === void 0 ? iterator.next() : iterator.next(value)
|
|
17702
|
+
).then(
|
|
17703
|
+
async (result) => {
|
|
17704
|
+
if (result.done) {
|
|
17705
|
+
await args.finalize();
|
|
17706
|
+
}
|
|
17707
|
+
return result;
|
|
17708
|
+
},
|
|
17709
|
+
(error2) => {
|
|
17710
|
+
args.onError(error2);
|
|
17711
|
+
throw error2;
|
|
17712
|
+
}
|
|
17713
|
+
);
|
|
17714
|
+
},
|
|
17715
|
+
return(value) {
|
|
17716
|
+
if (typeof iterator.return !== "function") {
|
|
17717
|
+
return args.finalize().then(() => ({
|
|
17718
|
+
done: true,
|
|
17719
|
+
value
|
|
17720
|
+
}));
|
|
17721
|
+
}
|
|
17722
|
+
return withCurrent(args.span, () => iterator.return(value)).then(
|
|
17723
|
+
async (result) => {
|
|
17724
|
+
await args.finalize();
|
|
17725
|
+
return result;
|
|
17726
|
+
},
|
|
17727
|
+
(error2) => {
|
|
17728
|
+
args.onError(error2);
|
|
17729
|
+
throw error2;
|
|
17730
|
+
}
|
|
17731
|
+
);
|
|
17732
|
+
},
|
|
17733
|
+
throw(error2) {
|
|
17734
|
+
args.onError(error2);
|
|
17735
|
+
if (typeof iterator.throw !== "function") {
|
|
17736
|
+
return Promise.reject(error2);
|
|
17737
|
+
}
|
|
17738
|
+
return withCurrent(args.span, () => iterator.throw(error2));
|
|
17739
|
+
},
|
|
17740
|
+
[Symbol.asyncIterator]() {
|
|
17741
|
+
return this;
|
|
17742
|
+
}
|
|
17743
|
+
};
|
|
17744
|
+
}
|
|
17745
|
+
};
|
|
17746
|
+
}
|
|
17747
|
+
function isAsyncIterable4(value) {
|
|
17748
|
+
return !!value && (typeof value === "object" || typeof value === "function") && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
17749
|
+
}
|
|
17750
|
+
function isPromiseLike(value) {
|
|
17751
|
+
return !!value && (typeof value === "object" || typeof value === "function") && "then" in value && typeof value.then === "function";
|
|
17752
|
+
}
|
|
17753
|
+
function normalizeError(error2) {
|
|
17754
|
+
return error2 instanceof Error ? error2 : new Error(String(error2));
|
|
17755
|
+
}
|
|
17756
|
+
|
|
17757
|
+
// src/instrumentation/plugins/openrouter-plugin.ts
|
|
17758
|
+
var OpenRouterPlugin = class extends BasePlugin {
|
|
17759
|
+
onEnable() {
|
|
17760
|
+
this.subscribeToOpenRouterChannels();
|
|
17761
|
+
}
|
|
17762
|
+
onDisable() {
|
|
17763
|
+
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
17764
|
+
}
|
|
17765
|
+
subscribeToOpenRouterChannels() {
|
|
17766
|
+
this.unsubscribers.push(
|
|
17767
|
+
traceStreamingChannel(openRouterChannels.chatSend, {
|
|
17768
|
+
name: "openrouter.chat.send",
|
|
17769
|
+
type: "llm" /* LLM */,
|
|
17770
|
+
extractInput: (args) => {
|
|
17771
|
+
const request = getOpenRouterRequestArg(args);
|
|
17772
|
+
const chatGenerationParams = isObject(request?.chatGenerationParams) ? request.chatGenerationParams : {};
|
|
17773
|
+
const httpReferer = request?.httpReferer;
|
|
17774
|
+
const xTitle = request?.xTitle;
|
|
17775
|
+
const { messages, ...metadata } = chatGenerationParams;
|
|
17776
|
+
return {
|
|
17777
|
+
input: messages,
|
|
17778
|
+
metadata: buildOpenRouterMetadata(metadata, httpReferer, xTitle)
|
|
17779
|
+
};
|
|
17780
|
+
},
|
|
17781
|
+
extractOutput: (result) => {
|
|
17782
|
+
return isObject(result) ? result.choices : void 0;
|
|
17783
|
+
},
|
|
17784
|
+
extractMetrics: (result, startTime) => {
|
|
17785
|
+
const metrics = parseOpenRouterMetricsFromUsage(result?.usage);
|
|
17786
|
+
if (startTime) {
|
|
17787
|
+
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
17788
|
+
}
|
|
17789
|
+
return metrics;
|
|
17790
|
+
},
|
|
17791
|
+
aggregateChunks: aggregateOpenRouterChatChunks
|
|
17792
|
+
})
|
|
17793
|
+
);
|
|
17794
|
+
this.unsubscribers.push(
|
|
17795
|
+
traceAsyncChannel(openRouterChannels.embeddingsGenerate, {
|
|
17796
|
+
name: "openrouter.embeddings.generate",
|
|
17797
|
+
type: "llm" /* LLM */,
|
|
17798
|
+
extractInput: (args) => {
|
|
17799
|
+
const request = getOpenRouterRequestArg(args);
|
|
17800
|
+
const requestBody = isObject(request?.requestBody) ? request.requestBody : {};
|
|
17801
|
+
const httpReferer = request?.httpReferer;
|
|
17802
|
+
const xTitle = request?.xTitle;
|
|
17803
|
+
const { input, ...metadata } = requestBody;
|
|
17804
|
+
return {
|
|
17805
|
+
input,
|
|
17806
|
+
metadata: buildOpenRouterEmbeddingMetadata(
|
|
17807
|
+
metadata,
|
|
17808
|
+
httpReferer,
|
|
17809
|
+
xTitle
|
|
17810
|
+
)
|
|
17811
|
+
};
|
|
17812
|
+
},
|
|
17813
|
+
extractOutput: (result) => {
|
|
17814
|
+
if (!isObject(result)) {
|
|
17815
|
+
return void 0;
|
|
17816
|
+
}
|
|
17817
|
+
const embedding = result.data?.[0]?.embedding;
|
|
17818
|
+
return Array.isArray(embedding) ? { embedding_length: embedding.length } : void 0;
|
|
17819
|
+
},
|
|
17820
|
+
extractMetadata: (result) => {
|
|
17821
|
+
if (!isObject(result)) {
|
|
17822
|
+
return void 0;
|
|
17823
|
+
}
|
|
17824
|
+
return extractOpenRouterResponseMetadata(result);
|
|
17825
|
+
},
|
|
17826
|
+
extractMetrics: (result) => {
|
|
17827
|
+
return isObject(result) ? parseOpenRouterMetricsFromUsage(result.usage) : {};
|
|
17828
|
+
}
|
|
17829
|
+
})
|
|
17830
|
+
);
|
|
17831
|
+
this.unsubscribers.push(
|
|
17832
|
+
traceStreamingChannel(openRouterChannels.betaResponsesSend, {
|
|
17833
|
+
name: "openrouter.beta.responses.send",
|
|
17834
|
+
type: "llm" /* LLM */,
|
|
17835
|
+
extractInput: (args) => {
|
|
17836
|
+
const request = getOpenRouterRequestArg(args);
|
|
17837
|
+
const openResponsesRequest = isObject(request?.openResponsesRequest) ? request.openResponsesRequest : {};
|
|
17838
|
+
const httpReferer = request?.httpReferer;
|
|
17839
|
+
const xTitle = request?.xTitle;
|
|
17840
|
+
const { input, ...metadata } = openResponsesRequest;
|
|
17841
|
+
return {
|
|
17842
|
+
input,
|
|
17843
|
+
metadata: buildOpenRouterMetadata(metadata, httpReferer, xTitle)
|
|
17844
|
+
};
|
|
17845
|
+
},
|
|
17846
|
+
extractOutput: (result) => extractOpenRouterResponseOutput(result),
|
|
17847
|
+
extractMetadata: (result) => extractOpenRouterResponseMetadata(result),
|
|
17848
|
+
extractMetrics: (result, startTime) => {
|
|
17849
|
+
const metrics = parseOpenRouterMetricsFromUsage(result?.usage);
|
|
17850
|
+
if (startTime) {
|
|
17851
|
+
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
17852
|
+
}
|
|
17853
|
+
return metrics;
|
|
17854
|
+
},
|
|
17855
|
+
aggregateChunks: aggregateOpenRouterResponseStreamEvents
|
|
17856
|
+
})
|
|
17857
|
+
);
|
|
17858
|
+
this.unsubscribers.push(
|
|
17859
|
+
traceSyncStreamChannel(openRouterChannels.callModel, {
|
|
17860
|
+
name: "openrouter.callModel",
|
|
17861
|
+
type: "llm" /* LLM */,
|
|
17862
|
+
extractInput: (args) => {
|
|
17863
|
+
const request = getOpenRouterCallModelRequestArg(args);
|
|
17864
|
+
return {
|
|
17865
|
+
input: request ? extractOpenRouterCallModelInput(request) : void 0,
|
|
17866
|
+
metadata: request ? extractOpenRouterCallModelMetadata(request) : { provider: "openrouter" }
|
|
17867
|
+
};
|
|
17868
|
+
},
|
|
17869
|
+
patchResult: ({ endEvent, result, span }) => {
|
|
17870
|
+
return patchOpenRouterCallModelResult(
|
|
17871
|
+
span,
|
|
17872
|
+
result,
|
|
17873
|
+
getOpenRouterCallModelRequestArg(endEvent.arguments)
|
|
17874
|
+
);
|
|
17875
|
+
}
|
|
17876
|
+
})
|
|
17877
|
+
);
|
|
17878
|
+
this.unsubscribers.push(
|
|
17879
|
+
traceStreamingChannel(openRouterChannels.toolExecute, {
|
|
17880
|
+
name: "openrouter.tool",
|
|
17881
|
+
type: "tool" /* TOOL */,
|
|
17882
|
+
extractInput: (args, event) => ({
|
|
17883
|
+
input: args[0],
|
|
17884
|
+
metadata: {
|
|
17885
|
+
provider: "openrouter",
|
|
17886
|
+
tool_name: event.toolName,
|
|
17887
|
+
...event.toolCallId ? { tool_call_id: event.toolCallId } : {}
|
|
17888
|
+
}
|
|
17889
|
+
}),
|
|
17890
|
+
extractOutput: (result) => result,
|
|
17891
|
+
extractMetrics: () => ({}),
|
|
17892
|
+
aggregateChunks: (chunks) => ({
|
|
17893
|
+
output: chunks.length > 0 ? chunks[chunks.length - 1] : void 0,
|
|
17894
|
+
metrics: {}
|
|
17895
|
+
})
|
|
17896
|
+
})
|
|
17897
|
+
);
|
|
17898
|
+
const callModelChannel = openRouterChannels.callModel.tracingChannel();
|
|
17899
|
+
const callModelHandlers = {
|
|
17900
|
+
start: (event) => {
|
|
17901
|
+
const request = getOpenRouterCallModelRequestArg(event.arguments);
|
|
17902
|
+
if (!request) {
|
|
17903
|
+
return;
|
|
17904
|
+
}
|
|
17905
|
+
patchOpenRouterCallModelRequestTools(request);
|
|
17906
|
+
}
|
|
17907
|
+
};
|
|
17908
|
+
callModelChannel.subscribe(callModelHandlers);
|
|
17909
|
+
this.unsubscribers.push(() => {
|
|
17910
|
+
callModelChannel.unsubscribe(callModelHandlers);
|
|
17911
|
+
});
|
|
17912
|
+
}
|
|
17913
|
+
};
|
|
17914
|
+
function normalizeArgs(args) {
|
|
17915
|
+
if (Array.isArray(args)) {
|
|
17916
|
+
return args;
|
|
17917
|
+
}
|
|
17918
|
+
if (isArrayLike2(args)) {
|
|
17919
|
+
return Array.from(args);
|
|
17920
|
+
}
|
|
17921
|
+
return [args];
|
|
17922
|
+
}
|
|
17923
|
+
function isArrayLike2(value) {
|
|
17924
|
+
return isObject(value) && "length" in value && typeof value.length === "number" && Number.isInteger(value.length) && value.length >= 0;
|
|
17925
|
+
}
|
|
17926
|
+
function getOpenRouterRequestArg(args) {
|
|
17927
|
+
const normalizedArgs = normalizeArgs(args);
|
|
17928
|
+
const keyedCandidate = normalizedArgs.find(
|
|
17929
|
+
(arg) => isObject(arg) && ("chatGenerationParams" in arg || "requestBody" in arg || "openResponsesRequest" in arg)
|
|
17930
|
+
);
|
|
17931
|
+
if (isObject(keyedCandidate)) {
|
|
17932
|
+
return keyedCandidate;
|
|
17933
|
+
}
|
|
17934
|
+
const firstObjectArg = normalizedArgs.find((arg) => isObject(arg));
|
|
17935
|
+
return isObject(firstObjectArg) ? firstObjectArg : void 0;
|
|
17936
|
+
}
|
|
17937
|
+
function getOpenRouterCallModelRequestArg(args) {
|
|
17938
|
+
const firstObjectArg = normalizeArgs(args).find((arg) => isObject(arg));
|
|
17939
|
+
return isObject(firstObjectArg) ? firstObjectArg : void 0;
|
|
17940
|
+
}
|
|
17941
|
+
function aggregateOpenRouterChatChunks(chunks) {
|
|
17942
|
+
let role;
|
|
17943
|
+
let content = "";
|
|
17944
|
+
let toolCalls;
|
|
17945
|
+
let finishReason;
|
|
17946
|
+
let metrics = {};
|
|
17947
|
+
for (const chunk of chunks) {
|
|
17948
|
+
metrics = {
|
|
17949
|
+
...metrics,
|
|
17950
|
+
...parseOpenRouterMetricsFromUsage(chunk?.usage)
|
|
17951
|
+
};
|
|
17952
|
+
const choice = chunk?.choices?.[0];
|
|
17953
|
+
const delta = choice?.delta;
|
|
17954
|
+
if (!delta) {
|
|
17955
|
+
if (choice?.finish_reason !== void 0) {
|
|
17956
|
+
finishReason = choice.finish_reason;
|
|
17957
|
+
}
|
|
17958
|
+
continue;
|
|
17959
|
+
}
|
|
17960
|
+
if (!role && delta.role) {
|
|
17961
|
+
role = delta.role;
|
|
17962
|
+
}
|
|
17963
|
+
if (typeof delta.content === "string") {
|
|
17964
|
+
content += delta.content;
|
|
17965
|
+
}
|
|
17966
|
+
const choiceFinishReason = choice?.finishReason ?? choice?.finish_reason ?? void 0;
|
|
17967
|
+
const deltaFinishReason = delta.finishReason ?? delta.finish_reason ?? void 0;
|
|
17968
|
+
if (choiceFinishReason !== void 0) {
|
|
17969
|
+
finishReason = choiceFinishReason;
|
|
17970
|
+
} else if (deltaFinishReason !== void 0) {
|
|
17971
|
+
finishReason = deltaFinishReason;
|
|
17972
|
+
}
|
|
17973
|
+
const toolCallDeltas = Array.isArray(delta.toolCalls) ? delta.toolCalls : Array.isArray(delta.tool_calls) ? delta.tool_calls : void 0;
|
|
17974
|
+
if (!toolCallDeltas) {
|
|
17975
|
+
continue;
|
|
17976
|
+
}
|
|
17977
|
+
for (const toolDelta of toolCallDeltas) {
|
|
17978
|
+
if (!toolDelta?.function) {
|
|
17979
|
+
continue;
|
|
17980
|
+
}
|
|
17981
|
+
const toolIndex = toolDelta.index ?? 0;
|
|
17982
|
+
const existingToolCall = toolCalls?.[toolIndex];
|
|
17983
|
+
if (!existingToolCall || toolDelta.id && existingToolCall.id !== void 0 && existingToolCall.id !== toolDelta.id) {
|
|
17984
|
+
const nextToolCalls = [...toolCalls || []];
|
|
17985
|
+
nextToolCalls[toolIndex] = {
|
|
17986
|
+
index: toolIndex,
|
|
17987
|
+
id: toolDelta.id,
|
|
17988
|
+
type: toolDelta.type,
|
|
17989
|
+
function: {
|
|
17990
|
+
name: toolDelta.function.name,
|
|
17991
|
+
arguments: toolDelta.function.arguments || ""
|
|
17992
|
+
}
|
|
17993
|
+
};
|
|
17994
|
+
toolCalls = nextToolCalls;
|
|
17995
|
+
continue;
|
|
17996
|
+
}
|
|
17997
|
+
const current = existingToolCall;
|
|
17998
|
+
if (toolDelta.id && !current.id) {
|
|
17999
|
+
current.id = toolDelta.id;
|
|
18000
|
+
}
|
|
18001
|
+
if (toolDelta.type && !current.type) {
|
|
18002
|
+
current.type = toolDelta.type;
|
|
18003
|
+
}
|
|
18004
|
+
if (toolDelta.function.name && !current.function.name) {
|
|
18005
|
+
current.function.name = toolDelta.function.name;
|
|
18006
|
+
}
|
|
18007
|
+
current.function.arguments += toolDelta.function.arguments || "";
|
|
18008
|
+
}
|
|
18009
|
+
}
|
|
18010
|
+
return {
|
|
18011
|
+
output: [
|
|
18012
|
+
{
|
|
18013
|
+
index: 0,
|
|
18014
|
+
message: {
|
|
18015
|
+
role,
|
|
18016
|
+
content: content || void 0,
|
|
18017
|
+
...toolCalls ? { tool_calls: toolCalls } : {}
|
|
18018
|
+
},
|
|
18019
|
+
logprobs: null,
|
|
18020
|
+
finish_reason: finishReason
|
|
18021
|
+
}
|
|
18022
|
+
],
|
|
18023
|
+
metrics
|
|
18024
|
+
};
|
|
18025
|
+
}
|
|
18026
|
+
function aggregateOpenRouterResponseStreamEvents(chunks) {
|
|
18027
|
+
let finalResponse;
|
|
18028
|
+
for (const chunk of chunks) {
|
|
18029
|
+
const response = chunk?.response;
|
|
18030
|
+
if (!response) {
|
|
18031
|
+
continue;
|
|
18032
|
+
}
|
|
18033
|
+
if (chunk.type === "response.completed" || chunk.type === "response.incomplete" || chunk.type === "response.failed") {
|
|
18034
|
+
finalResponse = response;
|
|
18035
|
+
}
|
|
18036
|
+
}
|
|
18037
|
+
if (!finalResponse) {
|
|
18038
|
+
return {
|
|
18039
|
+
output: void 0,
|
|
18040
|
+
metrics: {}
|
|
18041
|
+
};
|
|
18042
|
+
}
|
|
18043
|
+
return {
|
|
18044
|
+
output: extractOpenRouterResponseOutput(finalResponse),
|
|
18045
|
+
metrics: parseOpenRouterMetricsFromUsage(finalResponse.usage),
|
|
18046
|
+
...extractOpenRouterResponseMetadata(finalResponse) ? { metadata: extractOpenRouterResponseMetadata(finalResponse) } : {}
|
|
18047
|
+
};
|
|
18048
|
+
}
|
|
18049
|
+
|
|
18050
|
+
// src/instrumentation/braintrust-plugin.ts
|
|
18051
|
+
var BraintrustPlugin = class extends BasePlugin {
|
|
18052
|
+
config;
|
|
18053
|
+
openaiPlugin = null;
|
|
18054
|
+
anthropicPlugin = null;
|
|
18055
|
+
aiSDKPlugin = null;
|
|
18056
|
+
claudeAgentSDKPlugin = null;
|
|
18057
|
+
googleGenAIPlugin = null;
|
|
18058
|
+
openRouterPlugin = null;
|
|
18059
|
+
constructor(config3 = {}) {
|
|
18060
|
+
super();
|
|
18061
|
+
this.config = config3;
|
|
18062
|
+
}
|
|
18063
|
+
onEnable() {
|
|
18064
|
+
const integrations = this.config.integrations || {};
|
|
18065
|
+
if (integrations.openai !== false) {
|
|
18066
|
+
this.openaiPlugin = new OpenAIPlugin();
|
|
18067
|
+
this.openaiPlugin.enable();
|
|
18068
|
+
}
|
|
18069
|
+
if (integrations.anthropic !== false) {
|
|
18070
|
+
this.anthropicPlugin = new AnthropicPlugin();
|
|
18071
|
+
this.anthropicPlugin.enable();
|
|
18072
|
+
}
|
|
18073
|
+
if (integrations.aisdk !== false && integrations.vercel !== false) {
|
|
18074
|
+
this.aiSDKPlugin = new AISDKPlugin();
|
|
18075
|
+
this.aiSDKPlugin.enable();
|
|
18076
|
+
}
|
|
18077
|
+
if (integrations.claudeAgentSDK !== false) {
|
|
18078
|
+
this.claudeAgentSDKPlugin = new ClaudeAgentSDKPlugin();
|
|
18079
|
+
this.claudeAgentSDKPlugin.enable();
|
|
18080
|
+
}
|
|
18081
|
+
if (integrations.googleGenAI !== false && integrations.google !== false) {
|
|
18082
|
+
this.googleGenAIPlugin = new GoogleGenAIPlugin();
|
|
18083
|
+
this.googleGenAIPlugin.enable();
|
|
18084
|
+
}
|
|
18085
|
+
if (integrations.openrouter !== false) {
|
|
18086
|
+
this.openRouterPlugin = new OpenRouterPlugin();
|
|
18087
|
+
this.openRouterPlugin.enable();
|
|
18088
|
+
}
|
|
18089
|
+
}
|
|
18090
|
+
onDisable() {
|
|
18091
|
+
if (this.openaiPlugin) {
|
|
18092
|
+
this.openaiPlugin.disable();
|
|
18093
|
+
this.openaiPlugin = null;
|
|
18094
|
+
}
|
|
18095
|
+
if (this.anthropicPlugin) {
|
|
18096
|
+
this.anthropicPlugin.disable();
|
|
18097
|
+
this.anthropicPlugin = null;
|
|
18098
|
+
}
|
|
18099
|
+
if (this.aiSDKPlugin) {
|
|
18100
|
+
this.aiSDKPlugin.disable();
|
|
18101
|
+
this.aiSDKPlugin = null;
|
|
18102
|
+
}
|
|
16264
18103
|
if (this.claudeAgentSDKPlugin) {
|
|
16265
18104
|
this.claudeAgentSDKPlugin.disable();
|
|
16266
18105
|
this.claudeAgentSDKPlugin = null;
|
|
@@ -16269,6 +18108,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
16269
18108
|
this.googleGenAIPlugin.disable();
|
|
16270
18109
|
this.googleGenAIPlugin = null;
|
|
16271
18110
|
}
|
|
18111
|
+
if (this.openRouterPlugin) {
|
|
18112
|
+
this.openRouterPlugin.disable();
|
|
18113
|
+
this.openRouterPlugin = null;
|
|
18114
|
+
}
|
|
16272
18115
|
}
|
|
16273
18116
|
};
|
|
16274
18117
|
|
|
@@ -16340,7 +18183,8 @@ var PluginRegistry = class {
|
|
|
16340
18183
|
vercel: true,
|
|
16341
18184
|
aisdk: true,
|
|
16342
18185
|
google: true,
|
|
16343
|
-
claudeAgentSDK: true
|
|
18186
|
+
claudeAgentSDK: true,
|
|
18187
|
+
openrouter: true
|
|
16344
18188
|
};
|
|
16345
18189
|
}
|
|
16346
18190
|
/**
|
|
@@ -16370,6 +18214,7 @@ function configureNode() {
|
|
|
16370
18214
|
isomorph_default.getCallerLocation = getCallerLocation;
|
|
16371
18215
|
isomorph_default.newAsyncLocalStorage = () => new import_node_async_hooks.AsyncLocalStorage();
|
|
16372
18216
|
isomorph_default.newTracingChannel = (nameOrChannels) => diagnostics_channel.tracingChannel(nameOrChannels);
|
|
18217
|
+
patchTracingChannel(diagnostics_channel.tracingChannel);
|
|
16373
18218
|
isomorph_default.processOn = (event, handler) => {
|
|
16374
18219
|
process.on(event, handler);
|
|
16375
18220
|
};
|