braintrust 3.5.0 → 3.6.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 +1353 -211
- package/dev/dist/index.mjs +1170 -28
- package/dist/auto-instrumentations/bundler/esbuild.cjs +81 -0
- package/dist/auto-instrumentations/bundler/esbuild.mjs +2 -2
- package/dist/auto-instrumentations/bundler/rollup.cjs +81 -0
- package/dist/auto-instrumentations/bundler/rollup.mjs +2 -2
- package/dist/auto-instrumentations/bundler/vite.cjs +81 -0
- package/dist/auto-instrumentations/bundler/vite.mjs +2 -2
- package/dist/auto-instrumentations/bundler/webpack.cjs +81 -0
- package/dist/auto-instrumentations/bundler/webpack.mjs +2 -2
- package/dist/auto-instrumentations/{chunk-DQTPSXJB.mjs → chunk-F7WAXFNM.mjs} +82 -1
- package/dist/auto-instrumentations/{chunk-F3TJZ3Z2.mjs → chunk-WOUC73KB.mjs} +3 -1
- package/dist/auto-instrumentations/hook.mjs +139 -49
- package/dist/auto-instrumentations/index.cjs +82 -0
- 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 +1479 -232
- package/dist/browser.mjs +1479 -232
- package/dist/cli.js +1162 -20
- package/dist/edge-light.d.mts +1 -1
- package/dist/edge-light.d.ts +1 -1
- package/dist/edge-light.js +1412 -222
- package/dist/edge-light.mjs +1412 -222
- package/dist/index.d.mts +30 -17
- package/dist/index.d.ts +30 -17
- package/dist/index.js +1763 -514
- package/dist/index.mjs +1458 -209
- package/dist/instrumentation/index.d.mts +3 -0
- package/dist/instrumentation/index.d.ts +3 -0
- package/dist/instrumentation/index.js +1102 -19
- package/dist/instrumentation/index.mjs +1102 -19
- package/dist/workerd.d.mts +1 -1
- package/dist/workerd.d.ts +1 -1
- package/dist/workerd.js +1412 -222
- package/dist/workerd.mjs +1412 -222
- package/package.json +1 -1
package/dev/dist/index.mjs
CHANGED
|
@@ -2,6 +2,64 @@
|
|
|
2
2
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
3
3
|
import * as diagnostics_channel from "node:diagnostics_channel";
|
|
4
4
|
import * as path from "node:path";
|
|
5
|
+
|
|
6
|
+
// src/auto-instrumentations/patch-tracing-channel.ts
|
|
7
|
+
function patchTracingChannel(tracingChannelFn) {
|
|
8
|
+
const dummyChannel = tracingChannelFn("__braintrust_probe__");
|
|
9
|
+
const TracingChannel = dummyChannel?.constructor;
|
|
10
|
+
if (!TracingChannel?.prototype) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
if (!Object.getOwnPropertyDescriptor(TracingChannel.prototype, "hasSubscribers")) {
|
|
14
|
+
Object.defineProperty(TracingChannel.prototype, "hasSubscribers", {
|
|
15
|
+
configurable: true,
|
|
16
|
+
enumerable: false,
|
|
17
|
+
get() {
|
|
18
|
+
return Boolean(
|
|
19
|
+
this.start?.hasSubscribers || this.end?.hasSubscribers || this.asyncStart?.hasSubscribers || this.asyncEnd?.hasSubscribers || this.error?.hasSubscribers
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
if (TracingChannel.prototype.tracePromise) {
|
|
25
|
+
TracingChannel.prototype.tracePromise = function(fn, context = {}, thisArg, ...args) {
|
|
26
|
+
const { start, end, asyncStart, asyncEnd, error } = this;
|
|
27
|
+
function reject2(err) {
|
|
28
|
+
context.error = err;
|
|
29
|
+
error?.publish(context);
|
|
30
|
+
asyncStart?.publish(context);
|
|
31
|
+
asyncEnd?.publish(context);
|
|
32
|
+
return Promise.reject(err);
|
|
33
|
+
}
|
|
34
|
+
function resolve(result) {
|
|
35
|
+
context.result = result;
|
|
36
|
+
asyncStart?.publish(context);
|
|
37
|
+
asyncEnd?.publish(context);
|
|
38
|
+
return result;
|
|
39
|
+
}
|
|
40
|
+
return start.runStores(context, () => {
|
|
41
|
+
try {
|
|
42
|
+
const result = Reflect.apply(fn, thisArg, args);
|
|
43
|
+
end?.publish(context);
|
|
44
|
+
if (result && (typeof result === "object" || typeof result === "function") && typeof result.then === "function") {
|
|
45
|
+
return result.then(resolve, reject2);
|
|
46
|
+
}
|
|
47
|
+
context.result = result;
|
|
48
|
+
asyncStart?.publish(context);
|
|
49
|
+
asyncEnd?.publish(context);
|
|
50
|
+
return result;
|
|
51
|
+
} catch (err) {
|
|
52
|
+
context.error = err;
|
|
53
|
+
error?.publish(context);
|
|
54
|
+
end?.publish(context);
|
|
55
|
+
throw err;
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// src/node/config.ts
|
|
5
63
|
import * as fs from "node:fs/promises";
|
|
6
64
|
import * as os from "node:os";
|
|
7
65
|
import * as fsSync from "node:fs";
|
|
@@ -4506,6 +4564,9 @@ var BRAINTRUST_ATTACHMENT = BraintrustAttachmentReference.shape.type.value;
|
|
|
4506
4564
|
var EXTERNAL_ATTACHMENT = ExternalAttachmentReference.shape.type.value;
|
|
4507
4565
|
var LOGS3_OVERFLOW_REFERENCE_TYPE = "logs3_overflow";
|
|
4508
4566
|
var BRAINTRUST_PARAMS = Object.keys(BraintrustModelParams.shape);
|
|
4567
|
+
var RESET_CONTEXT_MANAGER_STATE = Symbol.for(
|
|
4568
|
+
"braintrust.resetContextManagerState"
|
|
4569
|
+
);
|
|
4509
4570
|
var DEFAULT_MAX_REQUEST_SIZE = 6 * 1024 * 1024;
|
|
4510
4571
|
var parametersRowSchema = z8.object({
|
|
4511
4572
|
id: z8.string().uuid(),
|
|
@@ -4568,13 +4629,18 @@ function applyMaskingToField(maskingFunction, data, fieldName) {
|
|
|
4568
4629
|
return `ERROR: Failed to mask field '${fieldName}' - ${errorType}`;
|
|
4569
4630
|
}
|
|
4570
4631
|
}
|
|
4632
|
+
var BRAINTRUST_CURRENT_SPAN_STORE = Symbol.for(
|
|
4633
|
+
"braintrust.currentSpanStore"
|
|
4634
|
+
);
|
|
4571
4635
|
var ContextManager = class {
|
|
4572
4636
|
};
|
|
4573
4637
|
var BraintrustContextManager = class extends ContextManager {
|
|
4574
4638
|
_currentSpan;
|
|
4639
|
+
[BRAINTRUST_CURRENT_SPAN_STORE];
|
|
4575
4640
|
constructor() {
|
|
4576
4641
|
super();
|
|
4577
4642
|
this._currentSpan = isomorph_default.newAsyncLocalStorage();
|
|
4643
|
+
this[BRAINTRUST_CURRENT_SPAN_STORE] = this._currentSpan;
|
|
4578
4644
|
}
|
|
4579
4645
|
getParentSpanIds() {
|
|
4580
4646
|
const currentSpan2 = this._currentSpan.getStore();
|
|
@@ -4781,6 +4847,9 @@ var BraintrustState = class _BraintrustState {
|
|
|
4781
4847
|
resetIdGenState() {
|
|
4782
4848
|
this._idGenerator = null;
|
|
4783
4849
|
}
|
|
4850
|
+
[RESET_CONTEXT_MANAGER_STATE]() {
|
|
4851
|
+
this._contextManager = null;
|
|
4852
|
+
}
|
|
4784
4853
|
get idGenerator() {
|
|
4785
4854
|
if (this._idGenerator === null) {
|
|
4786
4855
|
this._idGenerator = getIdGenerator();
|
|
@@ -9283,6 +9352,36 @@ function startSpanForEvent(config, event, channelName) {
|
|
|
9283
9352
|
}
|
|
9284
9353
|
return { span, startTime };
|
|
9285
9354
|
}
|
|
9355
|
+
function ensureSpanStateForEvent(states, config, event, channelName) {
|
|
9356
|
+
const key = event;
|
|
9357
|
+
const existing = states.get(key);
|
|
9358
|
+
if (existing) {
|
|
9359
|
+
return existing;
|
|
9360
|
+
}
|
|
9361
|
+
const created = startSpanForEvent(config, event, channelName);
|
|
9362
|
+
states.set(key, created);
|
|
9363
|
+
return created;
|
|
9364
|
+
}
|
|
9365
|
+
function bindCurrentSpanStoreToStart(tracingChannel2, states, config, channelName) {
|
|
9366
|
+
const state = _internalGetGlobalState();
|
|
9367
|
+
const startChannel = tracingChannel2.start;
|
|
9368
|
+
const currentSpanStore = state?.contextManager ? state.contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
|
|
9369
|
+
if (!currentSpanStore || !startChannel) {
|
|
9370
|
+
return void 0;
|
|
9371
|
+
}
|
|
9372
|
+
startChannel.bindStore(
|
|
9373
|
+
currentSpanStore,
|
|
9374
|
+
(event) => ensureSpanStateForEvent(
|
|
9375
|
+
states,
|
|
9376
|
+
config,
|
|
9377
|
+
event,
|
|
9378
|
+
channelName
|
|
9379
|
+
).span
|
|
9380
|
+
);
|
|
9381
|
+
return () => {
|
|
9382
|
+
startChannel.unbindStore(currentSpanStore);
|
|
9383
|
+
};
|
|
9384
|
+
}
|
|
9286
9385
|
function logErrorAndEnd(states, event) {
|
|
9287
9386
|
const spanData = states.get(event);
|
|
9288
9387
|
if (!spanData) {
|
|
@@ -9298,15 +9397,19 @@ function traceAsyncChannel(channel2, config) {
|
|
|
9298
9397
|
const tracingChannel2 = channel2.tracingChannel();
|
|
9299
9398
|
const states = /* @__PURE__ */ new WeakMap();
|
|
9300
9399
|
const channelName = channel2.channelName;
|
|
9400
|
+
const unbindCurrentSpanStore = bindCurrentSpanStoreToStart(
|
|
9401
|
+
tracingChannel2,
|
|
9402
|
+
states,
|
|
9403
|
+
config,
|
|
9404
|
+
channelName
|
|
9405
|
+
);
|
|
9301
9406
|
const handlers = {
|
|
9302
9407
|
start: (event) => {
|
|
9303
|
-
|
|
9408
|
+
ensureSpanStateForEvent(
|
|
9409
|
+
states,
|
|
9410
|
+
config,
|
|
9304
9411
|
event,
|
|
9305
|
-
|
|
9306
|
-
config,
|
|
9307
|
-
event,
|
|
9308
|
-
channelName
|
|
9309
|
-
)
|
|
9412
|
+
channelName
|
|
9310
9413
|
);
|
|
9311
9414
|
},
|
|
9312
9415
|
asyncEnd: (event) => {
|
|
@@ -9348,6 +9451,7 @@ function traceAsyncChannel(channel2, config) {
|
|
|
9348
9451
|
};
|
|
9349
9452
|
tracingChannel2.subscribe(handlers);
|
|
9350
9453
|
return () => {
|
|
9454
|
+
unbindCurrentSpanStore?.();
|
|
9351
9455
|
tracingChannel2.unsubscribe(handlers);
|
|
9352
9456
|
};
|
|
9353
9457
|
}
|
|
@@ -9355,15 +9459,19 @@ function traceStreamingChannel(channel2, config) {
|
|
|
9355
9459
|
const tracingChannel2 = channel2.tracingChannel();
|
|
9356
9460
|
const states = /* @__PURE__ */ new WeakMap();
|
|
9357
9461
|
const channelName = channel2.channelName;
|
|
9462
|
+
const unbindCurrentSpanStore = bindCurrentSpanStoreToStart(
|
|
9463
|
+
tracingChannel2,
|
|
9464
|
+
states,
|
|
9465
|
+
config,
|
|
9466
|
+
channelName
|
|
9467
|
+
);
|
|
9358
9468
|
const handlers = {
|
|
9359
9469
|
start: (event) => {
|
|
9360
|
-
|
|
9470
|
+
ensureSpanStateForEvent(
|
|
9471
|
+
states,
|
|
9472
|
+
config,
|
|
9361
9473
|
event,
|
|
9362
|
-
|
|
9363
|
-
config,
|
|
9364
|
-
event,
|
|
9365
|
-
channelName
|
|
9366
|
-
)
|
|
9474
|
+
channelName
|
|
9367
9475
|
);
|
|
9368
9476
|
},
|
|
9369
9477
|
asyncEnd: (event) => {
|
|
@@ -9479,6 +9587,7 @@ function traceStreamingChannel(channel2, config) {
|
|
|
9479
9587
|
};
|
|
9480
9588
|
tracingChannel2.subscribe(handlers);
|
|
9481
9589
|
return () => {
|
|
9590
|
+
unbindCurrentSpanStore?.();
|
|
9482
9591
|
tracingChannel2.unsubscribe(handlers);
|
|
9483
9592
|
};
|
|
9484
9593
|
}
|
|
@@ -9486,15 +9595,19 @@ function traceSyncStreamChannel(channel2, config) {
|
|
|
9486
9595
|
const tracingChannel2 = channel2.tracingChannel();
|
|
9487
9596
|
const states = /* @__PURE__ */ new WeakMap();
|
|
9488
9597
|
const channelName = channel2.channelName;
|
|
9598
|
+
const unbindCurrentSpanStore = bindCurrentSpanStoreToStart(
|
|
9599
|
+
tracingChannel2,
|
|
9600
|
+
states,
|
|
9601
|
+
config,
|
|
9602
|
+
channelName
|
|
9603
|
+
);
|
|
9489
9604
|
const handlers = {
|
|
9490
9605
|
start: (event) => {
|
|
9491
|
-
|
|
9606
|
+
ensureSpanStateForEvent(
|
|
9607
|
+
states,
|
|
9608
|
+
config,
|
|
9492
9609
|
event,
|
|
9493
|
-
|
|
9494
|
-
config,
|
|
9495
|
-
event,
|
|
9496
|
-
channelName
|
|
9497
|
-
)
|
|
9610
|
+
channelName
|
|
9498
9611
|
);
|
|
9499
9612
|
},
|
|
9500
9613
|
end: (event) => {
|
|
@@ -9583,6 +9696,7 @@ function traceSyncStreamChannel(channel2, config) {
|
|
|
9583
9696
|
};
|
|
9584
9697
|
tracingChannel2.subscribe(handlers);
|
|
9585
9698
|
return () => {
|
|
9699
|
+
unbindCurrentSpanStore?.();
|
|
9586
9700
|
tracingChannel2.unsubscribe(handlers);
|
|
9587
9701
|
};
|
|
9588
9702
|
}
|
|
@@ -12144,6 +12258,1023 @@ function tryToDict(obj) {
|
|
|
12144
12258
|
return null;
|
|
12145
12259
|
}
|
|
12146
12260
|
|
|
12261
|
+
// src/instrumentation/plugins/openrouter-channels.ts
|
|
12262
|
+
var openRouterChannels = defineChannels("@openrouter/sdk", {
|
|
12263
|
+
chatSend: channel({
|
|
12264
|
+
channelName: "chat.send",
|
|
12265
|
+
kind: "async"
|
|
12266
|
+
}),
|
|
12267
|
+
embeddingsGenerate: channel({
|
|
12268
|
+
channelName: "embeddings.generate",
|
|
12269
|
+
kind: "async"
|
|
12270
|
+
}),
|
|
12271
|
+
betaResponsesSend: channel({
|
|
12272
|
+
channelName: "beta.responses.send",
|
|
12273
|
+
kind: "async"
|
|
12274
|
+
}),
|
|
12275
|
+
callModel: channel({
|
|
12276
|
+
channelName: "callModel",
|
|
12277
|
+
kind: "sync-stream"
|
|
12278
|
+
}),
|
|
12279
|
+
toolExecute: channel({
|
|
12280
|
+
channelName: "tool.execute",
|
|
12281
|
+
kind: "async"
|
|
12282
|
+
})
|
|
12283
|
+
});
|
|
12284
|
+
|
|
12285
|
+
// src/openrouter-utils.ts
|
|
12286
|
+
var TOKEN_NAME_MAP2 = {
|
|
12287
|
+
promptTokens: "prompt_tokens",
|
|
12288
|
+
inputTokens: "prompt_tokens",
|
|
12289
|
+
completionTokens: "completion_tokens",
|
|
12290
|
+
outputTokens: "completion_tokens",
|
|
12291
|
+
totalTokens: "tokens",
|
|
12292
|
+
prompt_tokens: "prompt_tokens",
|
|
12293
|
+
input_tokens: "prompt_tokens",
|
|
12294
|
+
completion_tokens: "completion_tokens",
|
|
12295
|
+
output_tokens: "completion_tokens",
|
|
12296
|
+
total_tokens: "tokens"
|
|
12297
|
+
};
|
|
12298
|
+
var TOKEN_DETAIL_PREFIX_MAP = {
|
|
12299
|
+
promptTokensDetails: "prompt",
|
|
12300
|
+
inputTokensDetails: "prompt",
|
|
12301
|
+
completionTokensDetails: "completion",
|
|
12302
|
+
outputTokensDetails: "completion",
|
|
12303
|
+
costDetails: "cost",
|
|
12304
|
+
prompt_tokens_details: "prompt",
|
|
12305
|
+
input_tokens_details: "prompt",
|
|
12306
|
+
completion_tokens_details: "completion",
|
|
12307
|
+
output_tokens_details: "completion",
|
|
12308
|
+
cost_details: "cost"
|
|
12309
|
+
};
|
|
12310
|
+
function camelToSnake(value) {
|
|
12311
|
+
return value.replace(/[A-Z]/g, (match) => `_${match.toLowerCase()}`);
|
|
12312
|
+
}
|
|
12313
|
+
function parseOpenRouterMetricsFromUsage(usage) {
|
|
12314
|
+
if (!isObject(usage)) {
|
|
12315
|
+
return {};
|
|
12316
|
+
}
|
|
12317
|
+
const metrics = {};
|
|
12318
|
+
for (const [name, value] of Object.entries(usage)) {
|
|
12319
|
+
if (typeof value === "number") {
|
|
12320
|
+
metrics[TOKEN_NAME_MAP2[name] || camelToSnake(name)] = value;
|
|
12321
|
+
continue;
|
|
12322
|
+
}
|
|
12323
|
+
if (!isObject(value)) {
|
|
12324
|
+
continue;
|
|
12325
|
+
}
|
|
12326
|
+
const prefix = TOKEN_DETAIL_PREFIX_MAP[name];
|
|
12327
|
+
if (!prefix) {
|
|
12328
|
+
continue;
|
|
12329
|
+
}
|
|
12330
|
+
for (const [nestedName, nestedValue] of Object.entries(value)) {
|
|
12331
|
+
if (typeof nestedValue !== "number") {
|
|
12332
|
+
continue;
|
|
12333
|
+
}
|
|
12334
|
+
metrics[`${prefix}_${camelToSnake(nestedName)}`] = nestedValue;
|
|
12335
|
+
}
|
|
12336
|
+
}
|
|
12337
|
+
return metrics;
|
|
12338
|
+
}
|
|
12339
|
+
function extractOpenRouterUsageMetadata(usage) {
|
|
12340
|
+
if (!isObject(usage)) {
|
|
12341
|
+
return void 0;
|
|
12342
|
+
}
|
|
12343
|
+
const metadata = {};
|
|
12344
|
+
if (typeof usage.isByok === "boolean") {
|
|
12345
|
+
metadata.is_byok = usage.isByok;
|
|
12346
|
+
} else if (typeof usage.is_byok === "boolean") {
|
|
12347
|
+
metadata.is_byok = usage.is_byok;
|
|
12348
|
+
}
|
|
12349
|
+
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
12350
|
+
}
|
|
12351
|
+
|
|
12352
|
+
// src/openrouter-logging.ts
|
|
12353
|
+
var OMITTED_OPENROUTER_KEYS = /* @__PURE__ */ new Set([
|
|
12354
|
+
"execute",
|
|
12355
|
+
"render",
|
|
12356
|
+
"nextTurnParams",
|
|
12357
|
+
"requireApproval"
|
|
12358
|
+
]);
|
|
12359
|
+
function parseOpenRouterModelString(model) {
|
|
12360
|
+
if (typeof model !== "string") {
|
|
12361
|
+
return { model };
|
|
12362
|
+
}
|
|
12363
|
+
const slashIndex = model.indexOf("/");
|
|
12364
|
+
if (slashIndex > 0 && slashIndex < model.length - 1) {
|
|
12365
|
+
return {
|
|
12366
|
+
provider: model.substring(0, slashIndex),
|
|
12367
|
+
model: model.substring(slashIndex + 1)
|
|
12368
|
+
};
|
|
12369
|
+
}
|
|
12370
|
+
return { model };
|
|
12371
|
+
}
|
|
12372
|
+
function isZodSchema2(value) {
|
|
12373
|
+
return value != null && typeof value === "object" && "_def" in value && typeof value._def === "object";
|
|
12374
|
+
}
|
|
12375
|
+
function serializeZodSchema2(schema) {
|
|
12376
|
+
try {
|
|
12377
|
+
return zodToJsonSchema(schema);
|
|
12378
|
+
} catch {
|
|
12379
|
+
return {
|
|
12380
|
+
type: "object",
|
|
12381
|
+
description: "Zod schema (conversion failed)"
|
|
12382
|
+
};
|
|
12383
|
+
}
|
|
12384
|
+
}
|
|
12385
|
+
function serializeOpenRouterTool(tool) {
|
|
12386
|
+
if (!isObject(tool)) {
|
|
12387
|
+
return tool;
|
|
12388
|
+
}
|
|
12389
|
+
const serialized = {};
|
|
12390
|
+
for (const [key, value] of Object.entries(tool)) {
|
|
12391
|
+
if (OMITTED_OPENROUTER_KEYS.has(key)) {
|
|
12392
|
+
continue;
|
|
12393
|
+
}
|
|
12394
|
+
if (key === "function" && isObject(value)) {
|
|
12395
|
+
serialized.function = sanitizeOpenRouterLoggedValue(value);
|
|
12396
|
+
continue;
|
|
12397
|
+
}
|
|
12398
|
+
serialized[key] = sanitizeOpenRouterLoggedValue(value);
|
|
12399
|
+
}
|
|
12400
|
+
return serialized;
|
|
12401
|
+
}
|
|
12402
|
+
function serializeOpenRouterToolsForLogging(tools) {
|
|
12403
|
+
if (!Array.isArray(tools)) {
|
|
12404
|
+
return void 0;
|
|
12405
|
+
}
|
|
12406
|
+
return tools.map((tool) => serializeOpenRouterTool(tool));
|
|
12407
|
+
}
|
|
12408
|
+
function sanitizeOpenRouterLoggedValue(value) {
|
|
12409
|
+
if (isZodSchema2(value)) {
|
|
12410
|
+
return serializeZodSchema2(value);
|
|
12411
|
+
}
|
|
12412
|
+
if (typeof value === "function") {
|
|
12413
|
+
return "[Function]";
|
|
12414
|
+
}
|
|
12415
|
+
if (Array.isArray(value)) {
|
|
12416
|
+
return value.map((entry) => sanitizeOpenRouterLoggedValue(entry));
|
|
12417
|
+
}
|
|
12418
|
+
if (!isObject(value)) {
|
|
12419
|
+
return value;
|
|
12420
|
+
}
|
|
12421
|
+
const sanitized = {};
|
|
12422
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
12423
|
+
if (OMITTED_OPENROUTER_KEYS.has(key)) {
|
|
12424
|
+
continue;
|
|
12425
|
+
}
|
|
12426
|
+
if (key === "tools" && Array.isArray(entry)) {
|
|
12427
|
+
sanitized.tools = serializeOpenRouterToolsForLogging(entry);
|
|
12428
|
+
continue;
|
|
12429
|
+
}
|
|
12430
|
+
sanitized[key] = sanitizeOpenRouterLoggedValue(entry);
|
|
12431
|
+
}
|
|
12432
|
+
return sanitized;
|
|
12433
|
+
}
|
|
12434
|
+
function buildOpenRouterMetadata(metadata, httpReferer, xTitle) {
|
|
12435
|
+
const sanitized = sanitizeOpenRouterLoggedValue(metadata);
|
|
12436
|
+
const metadataRecord = isObject(sanitized) ? sanitized : {};
|
|
12437
|
+
const { model, provider: providerRouting, ...rest } = metadataRecord;
|
|
12438
|
+
const normalizedModel = parseOpenRouterModelString(model);
|
|
12439
|
+
return {
|
|
12440
|
+
...rest,
|
|
12441
|
+
...normalizedModel.model !== void 0 ? { model: normalizedModel.model } : {},
|
|
12442
|
+
...providerRouting !== void 0 ? { providerRouting } : {},
|
|
12443
|
+
...httpReferer !== void 0 ? { httpReferer } : {},
|
|
12444
|
+
...xTitle !== void 0 ? { xTitle } : {},
|
|
12445
|
+
provider: normalizedModel.provider || "openrouter"
|
|
12446
|
+
};
|
|
12447
|
+
}
|
|
12448
|
+
function buildOpenRouterEmbeddingMetadata(metadata, httpReferer, xTitle) {
|
|
12449
|
+
const normalized = buildOpenRouterMetadata(metadata, httpReferer, xTitle);
|
|
12450
|
+
return typeof normalized.model === "string" ? {
|
|
12451
|
+
...normalized,
|
|
12452
|
+
embedding_model: normalized.model
|
|
12453
|
+
} : normalized;
|
|
12454
|
+
}
|
|
12455
|
+
function extractOpenRouterCallModelInput(request) {
|
|
12456
|
+
return isObject(request) && "input" in request ? sanitizeOpenRouterLoggedValue(request.input) : void 0;
|
|
12457
|
+
}
|
|
12458
|
+
function extractOpenRouterCallModelMetadata(request) {
|
|
12459
|
+
if (!isObject(request)) {
|
|
12460
|
+
return { provider: "openrouter" };
|
|
12461
|
+
}
|
|
12462
|
+
const { input: _input, ...metadata } = request;
|
|
12463
|
+
return buildOpenRouterMetadata(metadata, void 0, void 0);
|
|
12464
|
+
}
|
|
12465
|
+
function extractOpenRouterResponseMetadata(result) {
|
|
12466
|
+
if (!isObject(result)) {
|
|
12467
|
+
return void 0;
|
|
12468
|
+
}
|
|
12469
|
+
const { output: _output, data: _data, usage, ...metadata } = result;
|
|
12470
|
+
const sanitized = sanitizeOpenRouterLoggedValue(metadata);
|
|
12471
|
+
const metadataRecord = isObject(sanitized) ? sanitized : {};
|
|
12472
|
+
const { model, provider, ...rest } = metadataRecord;
|
|
12473
|
+
const normalizedModel = parseOpenRouterModelString(model);
|
|
12474
|
+
const normalizedProvider = (typeof provider === "string" ? provider : void 0) || normalizedModel.provider;
|
|
12475
|
+
const usageMetadata = extractOpenRouterUsageMetadata(usage);
|
|
12476
|
+
const combined = {
|
|
12477
|
+
...rest,
|
|
12478
|
+
...normalizedModel.model !== void 0 ? { model: normalizedModel.model } : {},
|
|
12479
|
+
...usageMetadata || {},
|
|
12480
|
+
...normalizedProvider !== void 0 ? { provider: normalizedProvider } : {}
|
|
12481
|
+
};
|
|
12482
|
+
return Object.keys(combined).length > 0 ? combined : void 0;
|
|
12483
|
+
}
|
|
12484
|
+
function extractOpenRouterResponseOutput(response, fallbackOutput) {
|
|
12485
|
+
if (isObject(response) && "output" in response && response.output !== void 0) {
|
|
12486
|
+
return sanitizeOpenRouterLoggedValue(response.output);
|
|
12487
|
+
}
|
|
12488
|
+
if (fallbackOutput !== void 0) {
|
|
12489
|
+
return sanitizeOpenRouterLoggedValue(fallbackOutput);
|
|
12490
|
+
}
|
|
12491
|
+
return void 0;
|
|
12492
|
+
}
|
|
12493
|
+
|
|
12494
|
+
// src/openrouter-tool-wrapping.ts
|
|
12495
|
+
var OPENROUTER_WRAPPED_TOOL = Symbol("braintrust.openrouter.wrappedTool");
|
|
12496
|
+
var OPENROUTER_WRAPPED_CALL_MODEL_RESULT = Symbol(
|
|
12497
|
+
"braintrust.openrouter.wrappedCallModelResult"
|
|
12498
|
+
);
|
|
12499
|
+
var OPENROUTER_CALL_MODEL_STREAM_METHODS = [
|
|
12500
|
+
"getFullResponsesStream",
|
|
12501
|
+
"getItemsStream",
|
|
12502
|
+
"getNewMessagesStream",
|
|
12503
|
+
"getReasoningStream",
|
|
12504
|
+
"getTextStream",
|
|
12505
|
+
"getToolCallsStream",
|
|
12506
|
+
"getToolStream"
|
|
12507
|
+
];
|
|
12508
|
+
var OPENROUTER_CALL_MODEL_CONTEXT_METHODS = [
|
|
12509
|
+
"cancel",
|
|
12510
|
+
"getPendingToolCalls",
|
|
12511
|
+
"getState",
|
|
12512
|
+
"getToolCalls",
|
|
12513
|
+
"requiresApproval"
|
|
12514
|
+
];
|
|
12515
|
+
function patchOpenRouterCallModelRequestTools(request) {
|
|
12516
|
+
if (!Array.isArray(request.tools) || request.tools.length === 0) {
|
|
12517
|
+
return void 0;
|
|
12518
|
+
}
|
|
12519
|
+
const originalTools = request.tools;
|
|
12520
|
+
const wrappedTools = originalTools.map((tool) => wrapOpenRouterTool(tool));
|
|
12521
|
+
const didPatch = wrappedTools.some(
|
|
12522
|
+
(tool, index) => tool !== originalTools[index]
|
|
12523
|
+
);
|
|
12524
|
+
if (!didPatch) {
|
|
12525
|
+
return void 0;
|
|
12526
|
+
}
|
|
12527
|
+
request.tools = wrappedTools;
|
|
12528
|
+
return () => {
|
|
12529
|
+
request.tools = originalTools;
|
|
12530
|
+
};
|
|
12531
|
+
}
|
|
12532
|
+
function patchOpenRouterCallModelResult(span, result, request) {
|
|
12533
|
+
if (!isObject(result) || isWrappedCallModelResult(result)) {
|
|
12534
|
+
return false;
|
|
12535
|
+
}
|
|
12536
|
+
const resultLike = result;
|
|
12537
|
+
const hasInstrumentableMethod = typeof resultLike.getResponse === "function" || typeof resultLike.getText === "function" || OPENROUTER_CALL_MODEL_STREAM_METHODS.some(
|
|
12538
|
+
(methodName) => typeof resultLike[methodName] === "function"
|
|
12539
|
+
);
|
|
12540
|
+
if (!hasInstrumentableMethod) {
|
|
12541
|
+
return false;
|
|
12542
|
+
}
|
|
12543
|
+
Object.defineProperty(resultLike, OPENROUTER_WRAPPED_CALL_MODEL_RESULT, {
|
|
12544
|
+
value: true,
|
|
12545
|
+
enumerable: false,
|
|
12546
|
+
configurable: false
|
|
12547
|
+
});
|
|
12548
|
+
const originalGetResponse = typeof resultLike.getResponse === "function" ? resultLike.getResponse.bind(resultLike) : void 0;
|
|
12549
|
+
const originalGetInitialResponse = typeof resultLike.getInitialResponse === "function" ? resultLike.getInitialResponse.bind(resultLike) : void 0;
|
|
12550
|
+
const originalMakeFollowupRequest = typeof resultLike.makeFollowupRequest === "function" ? resultLike.makeFollowupRequest.bind(resultLike) : void 0;
|
|
12551
|
+
let ended = false;
|
|
12552
|
+
let tracedTurnCount = 0;
|
|
12553
|
+
const endSpanWithResult = async (response, fallbackOutput) => {
|
|
12554
|
+
if (ended) {
|
|
12555
|
+
return;
|
|
12556
|
+
}
|
|
12557
|
+
ended = true;
|
|
12558
|
+
const finalResponse = getFinalOpenRouterCallModelResponse(
|
|
12559
|
+
resultLike,
|
|
12560
|
+
response
|
|
12561
|
+
);
|
|
12562
|
+
if (finalResponse) {
|
|
12563
|
+
const rounds = getOpenRouterCallModelRounds(resultLike);
|
|
12564
|
+
const metadata = extractOpenRouterCallModelResultMetadata(
|
|
12565
|
+
finalResponse,
|
|
12566
|
+
rounds.length + 1
|
|
12567
|
+
);
|
|
12568
|
+
span.log({
|
|
12569
|
+
output: extractOpenRouterResponseOutput(finalResponse, fallbackOutput),
|
|
12570
|
+
...metadata ? { metadata } : {},
|
|
12571
|
+
metrics: aggregateOpenRouterCallModelMetrics(rounds, finalResponse)
|
|
12572
|
+
});
|
|
12573
|
+
span.end();
|
|
12574
|
+
return;
|
|
12575
|
+
}
|
|
12576
|
+
if (fallbackOutput !== void 0) {
|
|
12577
|
+
span.log({
|
|
12578
|
+
output: fallbackOutput
|
|
12579
|
+
});
|
|
12580
|
+
}
|
|
12581
|
+
span.end();
|
|
12582
|
+
};
|
|
12583
|
+
const endSpanWithError = (error) => {
|
|
12584
|
+
if (ended) {
|
|
12585
|
+
return;
|
|
12586
|
+
}
|
|
12587
|
+
ended = true;
|
|
12588
|
+
span.log({
|
|
12589
|
+
error: normalizeError(error).message
|
|
12590
|
+
});
|
|
12591
|
+
span.end();
|
|
12592
|
+
};
|
|
12593
|
+
const finalizeFromResponse = async (fallbackOutput) => {
|
|
12594
|
+
if (!originalGetResponse) {
|
|
12595
|
+
await endSpanWithResult(void 0, fallbackOutput);
|
|
12596
|
+
return;
|
|
12597
|
+
}
|
|
12598
|
+
try {
|
|
12599
|
+
await endSpanWithResult(await originalGetResponse(), fallbackOutput);
|
|
12600
|
+
} catch {
|
|
12601
|
+
await endSpanWithResult(void 0, fallbackOutput);
|
|
12602
|
+
}
|
|
12603
|
+
};
|
|
12604
|
+
if (originalGetResponse) {
|
|
12605
|
+
resultLike.getResponse = async (...args) => {
|
|
12606
|
+
return await withCurrent(span, async () => {
|
|
12607
|
+
try {
|
|
12608
|
+
const response = await originalGetResponse(...args);
|
|
12609
|
+
await endSpanWithResult(response);
|
|
12610
|
+
return response;
|
|
12611
|
+
} catch (error) {
|
|
12612
|
+
endSpanWithError(error);
|
|
12613
|
+
throw error;
|
|
12614
|
+
}
|
|
12615
|
+
});
|
|
12616
|
+
};
|
|
12617
|
+
}
|
|
12618
|
+
if (typeof resultLike.getText === "function") {
|
|
12619
|
+
const originalGetText = resultLike.getText.bind(resultLike);
|
|
12620
|
+
resultLike.getText = async (...args) => {
|
|
12621
|
+
return await withCurrent(span, async () => {
|
|
12622
|
+
try {
|
|
12623
|
+
const text = await originalGetText(...args);
|
|
12624
|
+
await finalizeFromResponse(text);
|
|
12625
|
+
return text;
|
|
12626
|
+
} catch (error) {
|
|
12627
|
+
endSpanWithError(error);
|
|
12628
|
+
throw error;
|
|
12629
|
+
}
|
|
12630
|
+
});
|
|
12631
|
+
};
|
|
12632
|
+
}
|
|
12633
|
+
for (const methodName of OPENROUTER_CALL_MODEL_CONTEXT_METHODS) {
|
|
12634
|
+
if (typeof resultLike[methodName] !== "function") {
|
|
12635
|
+
continue;
|
|
12636
|
+
}
|
|
12637
|
+
const originalMethod = resultLike[methodName];
|
|
12638
|
+
resultLike[methodName] = async (...args) => {
|
|
12639
|
+
return await withCurrent(span, async () => {
|
|
12640
|
+
return await originalMethod.apply(resultLike, args);
|
|
12641
|
+
});
|
|
12642
|
+
};
|
|
12643
|
+
}
|
|
12644
|
+
for (const methodName of OPENROUTER_CALL_MODEL_STREAM_METHODS) {
|
|
12645
|
+
if (typeof resultLike[methodName] !== "function") {
|
|
12646
|
+
continue;
|
|
12647
|
+
}
|
|
12648
|
+
const originalMethod = resultLike[methodName];
|
|
12649
|
+
resultLike[methodName] = (...args) => {
|
|
12650
|
+
const stream = withCurrent(
|
|
12651
|
+
span,
|
|
12652
|
+
() => originalMethod.apply(resultLike, args)
|
|
12653
|
+
);
|
|
12654
|
+
if (!isAsyncIterable2(stream)) {
|
|
12655
|
+
return stream;
|
|
12656
|
+
}
|
|
12657
|
+
return wrapAsyncIterableWithSpan({
|
|
12658
|
+
finalize: finalizeFromResponse,
|
|
12659
|
+
iteratorFactory: () => stream[Symbol.asyncIterator](),
|
|
12660
|
+
onError: endSpanWithError,
|
|
12661
|
+
span
|
|
12662
|
+
});
|
|
12663
|
+
};
|
|
12664
|
+
}
|
|
12665
|
+
if (originalGetInitialResponse) {
|
|
12666
|
+
let initialTurnTraced = false;
|
|
12667
|
+
resultLike.getInitialResponse = async (...args) => {
|
|
12668
|
+
if (initialTurnTraced) {
|
|
12669
|
+
return await withCurrent(span, async () => {
|
|
12670
|
+
return await originalGetInitialResponse(...args);
|
|
12671
|
+
});
|
|
12672
|
+
}
|
|
12673
|
+
initialTurnTraced = true;
|
|
12674
|
+
const resolvedRequest = getOpenRouterResolvedRequest(resultLike, request);
|
|
12675
|
+
const childSpan = startOpenRouterCallModelTurnSpan({
|
|
12676
|
+
request: resolvedRequest,
|
|
12677
|
+
step: tracedTurnCount + 1,
|
|
12678
|
+
stepType: tracedTurnCount === 0 ? "initial" : "continue"
|
|
12679
|
+
});
|
|
12680
|
+
return await withCurrent(childSpan, async () => {
|
|
12681
|
+
try {
|
|
12682
|
+
const response = await originalGetInitialResponse(...args);
|
|
12683
|
+
tracedTurnCount++;
|
|
12684
|
+
finishOpenRouterCallModelTurnSpan({
|
|
12685
|
+
response,
|
|
12686
|
+
step: tracedTurnCount,
|
|
12687
|
+
stepType: tracedTurnCount === 1 ? "initial" : "continue",
|
|
12688
|
+
span: childSpan
|
|
12689
|
+
});
|
|
12690
|
+
return response;
|
|
12691
|
+
} catch (error) {
|
|
12692
|
+
childSpan.log({
|
|
12693
|
+
error: normalizeError(error).message
|
|
12694
|
+
});
|
|
12695
|
+
childSpan.end();
|
|
12696
|
+
throw error;
|
|
12697
|
+
}
|
|
12698
|
+
});
|
|
12699
|
+
};
|
|
12700
|
+
}
|
|
12701
|
+
if (originalMakeFollowupRequest) {
|
|
12702
|
+
resultLike.makeFollowupRequest = async (...args) => {
|
|
12703
|
+
const currentResponse = args[0];
|
|
12704
|
+
const toolResults = Array.isArray(args[1]) ? args[1] : [];
|
|
12705
|
+
const resolvedRequest = getOpenRouterResolvedRequest(resultLike, request);
|
|
12706
|
+
const followupRequest = buildOpenRouterFollowupRequest(
|
|
12707
|
+
resolvedRequest,
|
|
12708
|
+
currentResponse,
|
|
12709
|
+
toolResults
|
|
12710
|
+
);
|
|
12711
|
+
const childSpan = startOpenRouterCallModelTurnSpan({
|
|
12712
|
+
request: followupRequest,
|
|
12713
|
+
step: tracedTurnCount + 1,
|
|
12714
|
+
stepType: "continue"
|
|
12715
|
+
});
|
|
12716
|
+
return await withCurrent(childSpan, async () => {
|
|
12717
|
+
try {
|
|
12718
|
+
const response = await originalMakeFollowupRequest(...args);
|
|
12719
|
+
tracedTurnCount++;
|
|
12720
|
+
finishOpenRouterCallModelTurnSpan({
|
|
12721
|
+
response,
|
|
12722
|
+
step: tracedTurnCount,
|
|
12723
|
+
stepType: "continue",
|
|
12724
|
+
span: childSpan
|
|
12725
|
+
});
|
|
12726
|
+
return response;
|
|
12727
|
+
} catch (error) {
|
|
12728
|
+
childSpan.log({
|
|
12729
|
+
error: normalizeError(error).message
|
|
12730
|
+
});
|
|
12731
|
+
childSpan.end();
|
|
12732
|
+
throw error;
|
|
12733
|
+
}
|
|
12734
|
+
});
|
|
12735
|
+
};
|
|
12736
|
+
}
|
|
12737
|
+
return true;
|
|
12738
|
+
}
|
|
12739
|
+
function wrapOpenRouterTool(tool) {
|
|
12740
|
+
if (isWrappedTool(tool) || !tool.function || typeof tool.function !== "object" || typeof tool.function.execute !== "function") {
|
|
12741
|
+
return tool;
|
|
12742
|
+
}
|
|
12743
|
+
const toolName = tool.function.name || "tool";
|
|
12744
|
+
const originalExecute = tool.function.execute;
|
|
12745
|
+
const wrappedTool = {
|
|
12746
|
+
...tool,
|
|
12747
|
+
function: {
|
|
12748
|
+
...tool.function,
|
|
12749
|
+
execute(...args) {
|
|
12750
|
+
return traceToolExecution({
|
|
12751
|
+
args,
|
|
12752
|
+
execute: () => Reflect.apply(originalExecute, this, args),
|
|
12753
|
+
toolCallId: getToolCallId(args[1]),
|
|
12754
|
+
toolName
|
|
12755
|
+
});
|
|
12756
|
+
}
|
|
12757
|
+
}
|
|
12758
|
+
};
|
|
12759
|
+
Object.defineProperty(wrappedTool, OPENROUTER_WRAPPED_TOOL, {
|
|
12760
|
+
value: true,
|
|
12761
|
+
enumerable: false,
|
|
12762
|
+
configurable: false
|
|
12763
|
+
});
|
|
12764
|
+
return wrappedTool;
|
|
12765
|
+
}
|
|
12766
|
+
function isWrappedTool(tool) {
|
|
12767
|
+
return Boolean(tool[OPENROUTER_WRAPPED_TOOL]);
|
|
12768
|
+
}
|
|
12769
|
+
function isWrappedCallModelResult(value) {
|
|
12770
|
+
return Boolean(
|
|
12771
|
+
isObject(value) && value[OPENROUTER_WRAPPED_CALL_MODEL_RESULT]
|
|
12772
|
+
);
|
|
12773
|
+
}
|
|
12774
|
+
function traceToolExecution(args) {
|
|
12775
|
+
const tracingChannel2 = openRouterChannels.toolExecute.tracingChannel();
|
|
12776
|
+
const input = args.args.length > 0 ? args.args[0] : void 0;
|
|
12777
|
+
const event = {
|
|
12778
|
+
arguments: [input],
|
|
12779
|
+
span_info: {
|
|
12780
|
+
name: args.toolName
|
|
12781
|
+
},
|
|
12782
|
+
toolCallId: args.toolCallId,
|
|
12783
|
+
toolName: args.toolName
|
|
12784
|
+
};
|
|
12785
|
+
tracingChannel2.start.publish(event);
|
|
12786
|
+
try {
|
|
12787
|
+
const result = args.execute();
|
|
12788
|
+
return publishToolResult(tracingChannel2, event, result);
|
|
12789
|
+
} catch (error) {
|
|
12790
|
+
event.error = normalizeError(error);
|
|
12791
|
+
tracingChannel2.error.publish(event);
|
|
12792
|
+
throw error;
|
|
12793
|
+
}
|
|
12794
|
+
}
|
|
12795
|
+
function publishToolResult(tracingChannel2, event, result) {
|
|
12796
|
+
if (isPromiseLike(result)) {
|
|
12797
|
+
return result.then(
|
|
12798
|
+
(resolved) => {
|
|
12799
|
+
event.result = resolved;
|
|
12800
|
+
tracingChannel2.asyncEnd.publish(event);
|
|
12801
|
+
return resolved;
|
|
12802
|
+
},
|
|
12803
|
+
(error) => {
|
|
12804
|
+
event.error = normalizeError(error);
|
|
12805
|
+
tracingChannel2.error.publish(event);
|
|
12806
|
+
throw error;
|
|
12807
|
+
}
|
|
12808
|
+
);
|
|
12809
|
+
}
|
|
12810
|
+
event.result = result;
|
|
12811
|
+
tracingChannel2.asyncEnd.publish(event);
|
|
12812
|
+
return result;
|
|
12813
|
+
}
|
|
12814
|
+
function getToolCallId(context) {
|
|
12815
|
+
const toolContext = context;
|
|
12816
|
+
return typeof toolContext?.toolCall?.id === "string" ? toolContext.toolCall.id : void 0;
|
|
12817
|
+
}
|
|
12818
|
+
function extractOpenRouterCallModelResultMetadata(response, turnCount) {
|
|
12819
|
+
const combined = {
|
|
12820
|
+
...extractOpenRouterResponseMetadata(response) || {},
|
|
12821
|
+
...turnCount !== void 0 ? { turn_count: turnCount } : {}
|
|
12822
|
+
};
|
|
12823
|
+
return Object.keys(combined).length > 0 ? combined : void 0;
|
|
12824
|
+
}
|
|
12825
|
+
function getFinalOpenRouterCallModelResponse(result, response) {
|
|
12826
|
+
if (isObject(response)) {
|
|
12827
|
+
return response;
|
|
12828
|
+
}
|
|
12829
|
+
return isObject(result.finalResponse) ? result.finalResponse : void 0;
|
|
12830
|
+
}
|
|
12831
|
+
function getOpenRouterCallModelRounds(result) {
|
|
12832
|
+
if (!Array.isArray(result.allToolExecutionRounds)) {
|
|
12833
|
+
return [];
|
|
12834
|
+
}
|
|
12835
|
+
return result.allToolExecutionRounds.filter((round) => isObject(round)).map((round) => ({
|
|
12836
|
+
response: isObject(round.response) ? round.response : void 0,
|
|
12837
|
+
round: typeof round.round === "number" ? round.round : void 0,
|
|
12838
|
+
toolResults: Array.isArray(round.toolResults) ? round.toolResults : []
|
|
12839
|
+
})).filter((round) => round.response !== void 0);
|
|
12840
|
+
}
|
|
12841
|
+
function aggregateOpenRouterCallModelMetrics(rounds, finalResponse) {
|
|
12842
|
+
const metrics = {};
|
|
12843
|
+
const responses = [
|
|
12844
|
+
...rounds.map((round) => round.response).filter(isObject),
|
|
12845
|
+
finalResponse
|
|
12846
|
+
];
|
|
12847
|
+
for (const response of responses) {
|
|
12848
|
+
const responseMetrics = parseOpenRouterMetricsFromUsage(response.usage);
|
|
12849
|
+
for (const [name, value] of Object.entries(responseMetrics)) {
|
|
12850
|
+
metrics[name] = (metrics[name] || 0) + value;
|
|
12851
|
+
}
|
|
12852
|
+
}
|
|
12853
|
+
return metrics;
|
|
12854
|
+
}
|
|
12855
|
+
function buildNextOpenRouterCallModelInput(currentInput, response, toolResults) {
|
|
12856
|
+
const normalizedInput = Array.isArray(currentInput) ? [...currentInput] : currentInput === void 0 ? [] : [currentInput];
|
|
12857
|
+
const responseOutput = Array.isArray(response.output) ? response.output : response.output === void 0 ? [] : [response.output];
|
|
12858
|
+
return [...normalizedInput, ...responseOutput, ...toolResults].map(
|
|
12859
|
+
(entry) => sanitizeOpenRouterLoggedValue(entry)
|
|
12860
|
+
);
|
|
12861
|
+
}
|
|
12862
|
+
function startOpenRouterCallModelTurnSpan(args) {
|
|
12863
|
+
const requestRecord = isObject(args.request) ? args.request : void 0;
|
|
12864
|
+
const metadata = requestRecord ? extractOpenRouterCallModelMetadata(requestRecord) : { provider: "openrouter" };
|
|
12865
|
+
if (isObject(metadata) && "tools" in metadata) {
|
|
12866
|
+
delete metadata.tools;
|
|
12867
|
+
}
|
|
12868
|
+
return startSpan({
|
|
12869
|
+
name: "openrouter.beta.responses.send",
|
|
12870
|
+
spanAttributes: {
|
|
12871
|
+
type: "llm" /* LLM */
|
|
12872
|
+
},
|
|
12873
|
+
event: {
|
|
12874
|
+
input: requestRecord ? extractOpenRouterCallModelInput(requestRecord) : void 0,
|
|
12875
|
+
metadata: {
|
|
12876
|
+
...metadata,
|
|
12877
|
+
step: args.step,
|
|
12878
|
+
step_type: args.stepType
|
|
12879
|
+
}
|
|
12880
|
+
}
|
|
12881
|
+
});
|
|
12882
|
+
}
|
|
12883
|
+
function finishOpenRouterCallModelTurnSpan(args) {
|
|
12884
|
+
if (!isObject(args.response)) {
|
|
12885
|
+
args.span.end();
|
|
12886
|
+
return;
|
|
12887
|
+
}
|
|
12888
|
+
args.span.log({
|
|
12889
|
+
output: extractOpenRouterResponseOutput(args.response),
|
|
12890
|
+
...extractOpenRouterResponseMetadata(args.response) ? {
|
|
12891
|
+
metadata: {
|
|
12892
|
+
...extractOpenRouterResponseMetadata(args.response),
|
|
12893
|
+
...args.step !== void 0 ? { step: args.step } : {},
|
|
12894
|
+
...args.stepType ? { step_type: args.stepType } : {}
|
|
12895
|
+
}
|
|
12896
|
+
} : {},
|
|
12897
|
+
metrics: parseOpenRouterMetricsFromUsage(args.response.usage)
|
|
12898
|
+
});
|
|
12899
|
+
args.span.end();
|
|
12900
|
+
}
|
|
12901
|
+
function getOpenRouterResolvedRequest(result, request) {
|
|
12902
|
+
if (isObject(result.resolvedRequest)) {
|
|
12903
|
+
return result.resolvedRequest;
|
|
12904
|
+
}
|
|
12905
|
+
return request;
|
|
12906
|
+
}
|
|
12907
|
+
function buildOpenRouterFollowupRequest(request, currentResponse, toolResults) {
|
|
12908
|
+
if (!request) {
|
|
12909
|
+
return void 0;
|
|
12910
|
+
}
|
|
12911
|
+
return {
|
|
12912
|
+
...request,
|
|
12913
|
+
input: buildNextOpenRouterCallModelInput(
|
|
12914
|
+
extractOpenRouterCallModelInput(request),
|
|
12915
|
+
isObject(currentResponse) ? currentResponse : {},
|
|
12916
|
+
toolResults
|
|
12917
|
+
),
|
|
12918
|
+
stream: false
|
|
12919
|
+
};
|
|
12920
|
+
}
|
|
12921
|
+
function wrapAsyncIterableWithSpan(args) {
|
|
12922
|
+
return {
|
|
12923
|
+
[Symbol.asyncIterator]() {
|
|
12924
|
+
const iterator = args.iteratorFactory();
|
|
12925
|
+
return {
|
|
12926
|
+
next(value) {
|
|
12927
|
+
return withCurrent(
|
|
12928
|
+
args.span,
|
|
12929
|
+
() => value === void 0 ? iterator.next() : iterator.next(value)
|
|
12930
|
+
).then(
|
|
12931
|
+
async (result) => {
|
|
12932
|
+
if (result.done) {
|
|
12933
|
+
await args.finalize();
|
|
12934
|
+
}
|
|
12935
|
+
return result;
|
|
12936
|
+
},
|
|
12937
|
+
(error) => {
|
|
12938
|
+
args.onError(error);
|
|
12939
|
+
throw error;
|
|
12940
|
+
}
|
|
12941
|
+
);
|
|
12942
|
+
},
|
|
12943
|
+
return(value) {
|
|
12944
|
+
if (typeof iterator.return !== "function") {
|
|
12945
|
+
return args.finalize().then(() => ({
|
|
12946
|
+
done: true,
|
|
12947
|
+
value
|
|
12948
|
+
}));
|
|
12949
|
+
}
|
|
12950
|
+
return withCurrent(args.span, () => iterator.return(value)).then(
|
|
12951
|
+
async (result) => {
|
|
12952
|
+
await args.finalize();
|
|
12953
|
+
return result;
|
|
12954
|
+
},
|
|
12955
|
+
(error) => {
|
|
12956
|
+
args.onError(error);
|
|
12957
|
+
throw error;
|
|
12958
|
+
}
|
|
12959
|
+
);
|
|
12960
|
+
},
|
|
12961
|
+
throw(error) {
|
|
12962
|
+
args.onError(error);
|
|
12963
|
+
if (typeof iterator.throw !== "function") {
|
|
12964
|
+
return Promise.reject(error);
|
|
12965
|
+
}
|
|
12966
|
+
return withCurrent(args.span, () => iterator.throw(error));
|
|
12967
|
+
},
|
|
12968
|
+
[Symbol.asyncIterator]() {
|
|
12969
|
+
return this;
|
|
12970
|
+
}
|
|
12971
|
+
};
|
|
12972
|
+
}
|
|
12973
|
+
};
|
|
12974
|
+
}
|
|
12975
|
+
function isAsyncIterable2(value) {
|
|
12976
|
+
return !!value && (typeof value === "object" || typeof value === "function") && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
12977
|
+
}
|
|
12978
|
+
function isPromiseLike(value) {
|
|
12979
|
+
return !!value && (typeof value === "object" || typeof value === "function") && "then" in value && typeof value.then === "function";
|
|
12980
|
+
}
|
|
12981
|
+
function normalizeError(error) {
|
|
12982
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
12983
|
+
}
|
|
12984
|
+
|
|
12985
|
+
// src/instrumentation/plugins/openrouter-plugin.ts
|
|
12986
|
+
var OpenRouterPlugin = class extends BasePlugin {
|
|
12987
|
+
onEnable() {
|
|
12988
|
+
this.subscribeToOpenRouterChannels();
|
|
12989
|
+
}
|
|
12990
|
+
onDisable() {
|
|
12991
|
+
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
12992
|
+
}
|
|
12993
|
+
subscribeToOpenRouterChannels() {
|
|
12994
|
+
this.unsubscribers.push(
|
|
12995
|
+
traceStreamingChannel(openRouterChannels.chatSend, {
|
|
12996
|
+
name: "openrouter.chat.send",
|
|
12997
|
+
type: "llm" /* LLM */,
|
|
12998
|
+
extractInput: (args) => {
|
|
12999
|
+
const request = getOpenRouterRequestArg(args);
|
|
13000
|
+
const chatGenerationParams = isObject(request?.chatGenerationParams) ? request.chatGenerationParams : {};
|
|
13001
|
+
const httpReferer = request?.httpReferer;
|
|
13002
|
+
const xTitle = request?.xTitle;
|
|
13003
|
+
const { messages, ...metadata } = chatGenerationParams;
|
|
13004
|
+
return {
|
|
13005
|
+
input: messages,
|
|
13006
|
+
metadata: buildOpenRouterMetadata(metadata, httpReferer, xTitle)
|
|
13007
|
+
};
|
|
13008
|
+
},
|
|
13009
|
+
extractOutput: (result) => {
|
|
13010
|
+
return isObject(result) ? result.choices : void 0;
|
|
13011
|
+
},
|
|
13012
|
+
extractMetrics: (result, startTime) => {
|
|
13013
|
+
const metrics = parseOpenRouterMetricsFromUsage(result?.usage);
|
|
13014
|
+
if (startTime) {
|
|
13015
|
+
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
13016
|
+
}
|
|
13017
|
+
return metrics;
|
|
13018
|
+
},
|
|
13019
|
+
aggregateChunks: aggregateOpenRouterChatChunks
|
|
13020
|
+
})
|
|
13021
|
+
);
|
|
13022
|
+
this.unsubscribers.push(
|
|
13023
|
+
traceAsyncChannel(openRouterChannels.embeddingsGenerate, {
|
|
13024
|
+
name: "openrouter.embeddings.generate",
|
|
13025
|
+
type: "llm" /* LLM */,
|
|
13026
|
+
extractInput: (args) => {
|
|
13027
|
+
const request = getOpenRouterRequestArg(args);
|
|
13028
|
+
const requestBody = isObject(request?.requestBody) ? request.requestBody : {};
|
|
13029
|
+
const httpReferer = request?.httpReferer;
|
|
13030
|
+
const xTitle = request?.xTitle;
|
|
13031
|
+
const { input, ...metadata } = requestBody;
|
|
13032
|
+
return {
|
|
13033
|
+
input,
|
|
13034
|
+
metadata: buildOpenRouterEmbeddingMetadata(
|
|
13035
|
+
metadata,
|
|
13036
|
+
httpReferer,
|
|
13037
|
+
xTitle
|
|
13038
|
+
)
|
|
13039
|
+
};
|
|
13040
|
+
},
|
|
13041
|
+
extractOutput: (result) => {
|
|
13042
|
+
if (!isObject(result)) {
|
|
13043
|
+
return void 0;
|
|
13044
|
+
}
|
|
13045
|
+
const embedding = result.data?.[0]?.embedding;
|
|
13046
|
+
return Array.isArray(embedding) ? { embedding_length: embedding.length } : void 0;
|
|
13047
|
+
},
|
|
13048
|
+
extractMetadata: (result) => {
|
|
13049
|
+
if (!isObject(result)) {
|
|
13050
|
+
return void 0;
|
|
13051
|
+
}
|
|
13052
|
+
return extractOpenRouterResponseMetadata(result);
|
|
13053
|
+
},
|
|
13054
|
+
extractMetrics: (result) => {
|
|
13055
|
+
return isObject(result) ? parseOpenRouterMetricsFromUsage(result.usage) : {};
|
|
13056
|
+
}
|
|
13057
|
+
})
|
|
13058
|
+
);
|
|
13059
|
+
this.unsubscribers.push(
|
|
13060
|
+
traceStreamingChannel(openRouterChannels.betaResponsesSend, {
|
|
13061
|
+
name: "openrouter.beta.responses.send",
|
|
13062
|
+
type: "llm" /* LLM */,
|
|
13063
|
+
extractInput: (args) => {
|
|
13064
|
+
const request = getOpenRouterRequestArg(args);
|
|
13065
|
+
const openResponsesRequest = isObject(request?.openResponsesRequest) ? request.openResponsesRequest : {};
|
|
13066
|
+
const httpReferer = request?.httpReferer;
|
|
13067
|
+
const xTitle = request?.xTitle;
|
|
13068
|
+
const { input, ...metadata } = openResponsesRequest;
|
|
13069
|
+
return {
|
|
13070
|
+
input,
|
|
13071
|
+
metadata: buildOpenRouterMetadata(metadata, httpReferer, xTitle)
|
|
13072
|
+
};
|
|
13073
|
+
},
|
|
13074
|
+
extractOutput: (result) => extractOpenRouterResponseOutput(result),
|
|
13075
|
+
extractMetadata: (result) => extractOpenRouterResponseMetadata(result),
|
|
13076
|
+
extractMetrics: (result, startTime) => {
|
|
13077
|
+
const metrics = parseOpenRouterMetricsFromUsage(result?.usage);
|
|
13078
|
+
if (startTime) {
|
|
13079
|
+
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
13080
|
+
}
|
|
13081
|
+
return metrics;
|
|
13082
|
+
},
|
|
13083
|
+
aggregateChunks: aggregateOpenRouterResponseStreamEvents
|
|
13084
|
+
})
|
|
13085
|
+
);
|
|
13086
|
+
this.unsubscribers.push(
|
|
13087
|
+
traceSyncStreamChannel(openRouterChannels.callModel, {
|
|
13088
|
+
name: "openrouter.callModel",
|
|
13089
|
+
type: "llm" /* LLM */,
|
|
13090
|
+
extractInput: (args) => {
|
|
13091
|
+
const request = getOpenRouterCallModelRequestArg(args);
|
|
13092
|
+
return {
|
|
13093
|
+
input: request ? extractOpenRouterCallModelInput(request) : void 0,
|
|
13094
|
+
metadata: request ? extractOpenRouterCallModelMetadata(request) : { provider: "openrouter" }
|
|
13095
|
+
};
|
|
13096
|
+
},
|
|
13097
|
+
patchResult: ({ endEvent, result, span }) => {
|
|
13098
|
+
return patchOpenRouterCallModelResult(
|
|
13099
|
+
span,
|
|
13100
|
+
result,
|
|
13101
|
+
getOpenRouterCallModelRequestArg(endEvent.arguments)
|
|
13102
|
+
);
|
|
13103
|
+
}
|
|
13104
|
+
})
|
|
13105
|
+
);
|
|
13106
|
+
this.unsubscribers.push(
|
|
13107
|
+
traceStreamingChannel(openRouterChannels.toolExecute, {
|
|
13108
|
+
name: "openrouter.tool",
|
|
13109
|
+
type: "tool" /* TOOL */,
|
|
13110
|
+
extractInput: (args, event) => ({
|
|
13111
|
+
input: args[0],
|
|
13112
|
+
metadata: {
|
|
13113
|
+
provider: "openrouter",
|
|
13114
|
+
tool_name: event.toolName,
|
|
13115
|
+
...event.toolCallId ? { tool_call_id: event.toolCallId } : {}
|
|
13116
|
+
}
|
|
13117
|
+
}),
|
|
13118
|
+
extractOutput: (result) => result,
|
|
13119
|
+
extractMetrics: () => ({}),
|
|
13120
|
+
aggregateChunks: (chunks) => ({
|
|
13121
|
+
output: chunks.length > 0 ? chunks[chunks.length - 1] : void 0,
|
|
13122
|
+
metrics: {}
|
|
13123
|
+
})
|
|
13124
|
+
})
|
|
13125
|
+
);
|
|
13126
|
+
const callModelChannel = openRouterChannels.callModel.tracingChannel();
|
|
13127
|
+
const callModelHandlers = {
|
|
13128
|
+
start: (event) => {
|
|
13129
|
+
const request = getOpenRouterCallModelRequestArg(event.arguments);
|
|
13130
|
+
if (!request) {
|
|
13131
|
+
return;
|
|
13132
|
+
}
|
|
13133
|
+
patchOpenRouterCallModelRequestTools(request);
|
|
13134
|
+
}
|
|
13135
|
+
};
|
|
13136
|
+
callModelChannel.subscribe(callModelHandlers);
|
|
13137
|
+
this.unsubscribers.push(() => {
|
|
13138
|
+
callModelChannel.unsubscribe(callModelHandlers);
|
|
13139
|
+
});
|
|
13140
|
+
}
|
|
13141
|
+
};
|
|
13142
|
+
function normalizeArgs(args) {
|
|
13143
|
+
if (Array.isArray(args)) {
|
|
13144
|
+
return args;
|
|
13145
|
+
}
|
|
13146
|
+
if (isArrayLike(args)) {
|
|
13147
|
+
return Array.from(args);
|
|
13148
|
+
}
|
|
13149
|
+
return [args];
|
|
13150
|
+
}
|
|
13151
|
+
function isArrayLike(value) {
|
|
13152
|
+
return isObject(value) && "length" in value && typeof value.length === "number" && Number.isInteger(value.length) && value.length >= 0;
|
|
13153
|
+
}
|
|
13154
|
+
function getOpenRouterRequestArg(args) {
|
|
13155
|
+
const normalizedArgs = normalizeArgs(args);
|
|
13156
|
+
const keyedCandidate = normalizedArgs.find(
|
|
13157
|
+
(arg) => isObject(arg) && ("chatGenerationParams" in arg || "requestBody" in arg || "openResponsesRequest" in arg)
|
|
13158
|
+
);
|
|
13159
|
+
if (isObject(keyedCandidate)) {
|
|
13160
|
+
return keyedCandidate;
|
|
13161
|
+
}
|
|
13162
|
+
const firstObjectArg = normalizedArgs.find((arg) => isObject(arg));
|
|
13163
|
+
return isObject(firstObjectArg) ? firstObjectArg : void 0;
|
|
13164
|
+
}
|
|
13165
|
+
function getOpenRouterCallModelRequestArg(args) {
|
|
13166
|
+
const firstObjectArg = normalizeArgs(args).find((arg) => isObject(arg));
|
|
13167
|
+
return isObject(firstObjectArg) ? firstObjectArg : void 0;
|
|
13168
|
+
}
|
|
13169
|
+
function aggregateOpenRouterChatChunks(chunks) {
|
|
13170
|
+
let role;
|
|
13171
|
+
let content = "";
|
|
13172
|
+
let toolCalls;
|
|
13173
|
+
let finishReason;
|
|
13174
|
+
let metrics = {};
|
|
13175
|
+
for (const chunk of chunks) {
|
|
13176
|
+
metrics = {
|
|
13177
|
+
...metrics,
|
|
13178
|
+
...parseOpenRouterMetricsFromUsage(chunk?.usage)
|
|
13179
|
+
};
|
|
13180
|
+
const choice = chunk?.choices?.[0];
|
|
13181
|
+
const delta = choice?.delta;
|
|
13182
|
+
if (!delta) {
|
|
13183
|
+
if (choice?.finish_reason !== void 0) {
|
|
13184
|
+
finishReason = choice.finish_reason;
|
|
13185
|
+
}
|
|
13186
|
+
continue;
|
|
13187
|
+
}
|
|
13188
|
+
if (!role && delta.role) {
|
|
13189
|
+
role = delta.role;
|
|
13190
|
+
}
|
|
13191
|
+
if (typeof delta.content === "string") {
|
|
13192
|
+
content += delta.content;
|
|
13193
|
+
}
|
|
13194
|
+
const choiceFinishReason = choice?.finishReason ?? choice?.finish_reason ?? void 0;
|
|
13195
|
+
const deltaFinishReason = delta.finishReason ?? delta.finish_reason ?? void 0;
|
|
13196
|
+
if (choiceFinishReason !== void 0) {
|
|
13197
|
+
finishReason = choiceFinishReason;
|
|
13198
|
+
} else if (deltaFinishReason !== void 0) {
|
|
13199
|
+
finishReason = deltaFinishReason;
|
|
13200
|
+
}
|
|
13201
|
+
const toolCallDeltas = Array.isArray(delta.toolCalls) ? delta.toolCalls : Array.isArray(delta.tool_calls) ? delta.tool_calls : void 0;
|
|
13202
|
+
if (!toolCallDeltas) {
|
|
13203
|
+
continue;
|
|
13204
|
+
}
|
|
13205
|
+
for (const toolDelta of toolCallDeltas) {
|
|
13206
|
+
if (!toolDelta?.function) {
|
|
13207
|
+
continue;
|
|
13208
|
+
}
|
|
13209
|
+
const toolIndex = toolDelta.index ?? 0;
|
|
13210
|
+
const existingToolCall = toolCalls?.[toolIndex];
|
|
13211
|
+
if (!existingToolCall || toolDelta.id && existingToolCall.id !== void 0 && existingToolCall.id !== toolDelta.id) {
|
|
13212
|
+
const nextToolCalls = [...toolCalls || []];
|
|
13213
|
+
nextToolCalls[toolIndex] = {
|
|
13214
|
+
index: toolIndex,
|
|
13215
|
+
id: toolDelta.id,
|
|
13216
|
+
type: toolDelta.type,
|
|
13217
|
+
function: {
|
|
13218
|
+
name: toolDelta.function.name,
|
|
13219
|
+
arguments: toolDelta.function.arguments || ""
|
|
13220
|
+
}
|
|
13221
|
+
};
|
|
13222
|
+
toolCalls = nextToolCalls;
|
|
13223
|
+
continue;
|
|
13224
|
+
}
|
|
13225
|
+
const current = existingToolCall;
|
|
13226
|
+
if (toolDelta.id && !current.id) {
|
|
13227
|
+
current.id = toolDelta.id;
|
|
13228
|
+
}
|
|
13229
|
+
if (toolDelta.type && !current.type) {
|
|
13230
|
+
current.type = toolDelta.type;
|
|
13231
|
+
}
|
|
13232
|
+
if (toolDelta.function.name && !current.function.name) {
|
|
13233
|
+
current.function.name = toolDelta.function.name;
|
|
13234
|
+
}
|
|
13235
|
+
current.function.arguments += toolDelta.function.arguments || "";
|
|
13236
|
+
}
|
|
13237
|
+
}
|
|
13238
|
+
return {
|
|
13239
|
+
output: [
|
|
13240
|
+
{
|
|
13241
|
+
index: 0,
|
|
13242
|
+
message: {
|
|
13243
|
+
role,
|
|
13244
|
+
content: content || void 0,
|
|
13245
|
+
...toolCalls ? { tool_calls: toolCalls } : {}
|
|
13246
|
+
},
|
|
13247
|
+
logprobs: null,
|
|
13248
|
+
finish_reason: finishReason
|
|
13249
|
+
}
|
|
13250
|
+
],
|
|
13251
|
+
metrics
|
|
13252
|
+
};
|
|
13253
|
+
}
|
|
13254
|
+
function aggregateOpenRouterResponseStreamEvents(chunks) {
|
|
13255
|
+
let finalResponse;
|
|
13256
|
+
for (const chunk of chunks) {
|
|
13257
|
+
const response = chunk?.response;
|
|
13258
|
+
if (!response) {
|
|
13259
|
+
continue;
|
|
13260
|
+
}
|
|
13261
|
+
if (chunk.type === "response.completed" || chunk.type === "response.incomplete" || chunk.type === "response.failed") {
|
|
13262
|
+
finalResponse = response;
|
|
13263
|
+
}
|
|
13264
|
+
}
|
|
13265
|
+
if (!finalResponse) {
|
|
13266
|
+
return {
|
|
13267
|
+
output: void 0,
|
|
13268
|
+
metrics: {}
|
|
13269
|
+
};
|
|
13270
|
+
}
|
|
13271
|
+
return {
|
|
13272
|
+
output: extractOpenRouterResponseOutput(finalResponse),
|
|
13273
|
+
metrics: parseOpenRouterMetricsFromUsage(finalResponse.usage),
|
|
13274
|
+
...extractOpenRouterResponseMetadata(finalResponse) ? { metadata: extractOpenRouterResponseMetadata(finalResponse) } : {}
|
|
13275
|
+
};
|
|
13276
|
+
}
|
|
13277
|
+
|
|
12147
13278
|
// src/instrumentation/braintrust-plugin.ts
|
|
12148
13279
|
var BraintrustPlugin = class extends BasePlugin {
|
|
12149
13280
|
config;
|
|
@@ -12152,6 +13283,7 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
12152
13283
|
aiSDKPlugin = null;
|
|
12153
13284
|
claudeAgentSDKPlugin = null;
|
|
12154
13285
|
googleGenAIPlugin = null;
|
|
13286
|
+
openRouterPlugin = null;
|
|
12155
13287
|
constructor(config = {}) {
|
|
12156
13288
|
super();
|
|
12157
13289
|
this.config = config;
|
|
@@ -12178,6 +13310,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
12178
13310
|
this.googleGenAIPlugin = new GoogleGenAIPlugin();
|
|
12179
13311
|
this.googleGenAIPlugin.enable();
|
|
12180
13312
|
}
|
|
13313
|
+
if (integrations.openrouter !== false) {
|
|
13314
|
+
this.openRouterPlugin = new OpenRouterPlugin();
|
|
13315
|
+
this.openRouterPlugin.enable();
|
|
13316
|
+
}
|
|
12181
13317
|
}
|
|
12182
13318
|
onDisable() {
|
|
12183
13319
|
if (this.openaiPlugin) {
|
|
@@ -12200,6 +13336,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
12200
13336
|
this.googleGenAIPlugin.disable();
|
|
12201
13337
|
this.googleGenAIPlugin = null;
|
|
12202
13338
|
}
|
|
13339
|
+
if (this.openRouterPlugin) {
|
|
13340
|
+
this.openRouterPlugin.disable();
|
|
13341
|
+
this.openRouterPlugin = null;
|
|
13342
|
+
}
|
|
12203
13343
|
}
|
|
12204
13344
|
};
|
|
12205
13345
|
|
|
@@ -12271,7 +13411,8 @@ var PluginRegistry = class {
|
|
|
12271
13411
|
vercel: true,
|
|
12272
13412
|
aisdk: true,
|
|
12273
13413
|
google: true,
|
|
12274
|
-
claudeAgentSDK: true
|
|
13414
|
+
claudeAgentSDK: true,
|
|
13415
|
+
openrouter: true
|
|
12275
13416
|
};
|
|
12276
13417
|
}
|
|
12277
13418
|
/**
|
|
@@ -12301,6 +13442,7 @@ function configureNode() {
|
|
|
12301
13442
|
isomorph_default.getCallerLocation = getCallerLocation;
|
|
12302
13443
|
isomorph_default.newAsyncLocalStorage = () => new AsyncLocalStorage();
|
|
12303
13444
|
isomorph_default.newTracingChannel = (nameOrChannels) => diagnostics_channel.tracingChannel(nameOrChannels);
|
|
13445
|
+
patchTracingChannel(diagnostics_channel.tracingChannel);
|
|
12304
13446
|
isomorph_default.processOn = (event, handler) => {
|
|
12305
13447
|
process.on(event, handler);
|
|
12306
13448
|
};
|
|
@@ -12405,7 +13547,7 @@ function isAsync(fn) {
|
|
|
12405
13547
|
function isAsyncGenerator2(fn) {
|
|
12406
13548
|
return fn[Symbol.toStringTag] === "AsyncGenerator";
|
|
12407
13549
|
}
|
|
12408
|
-
function
|
|
13550
|
+
function isAsyncIterable3(obj) {
|
|
12409
13551
|
return typeof obj[Symbol.asyncIterator] === "function";
|
|
12410
13552
|
}
|
|
12411
13553
|
function wrapAsync(asyncFn) {
|
|
@@ -12455,7 +13597,7 @@ function _asyncMap(eachfn, arr, iteratee, callback) {
|
|
|
12455
13597
|
callback(err, results);
|
|
12456
13598
|
});
|
|
12457
13599
|
}
|
|
12458
|
-
function
|
|
13600
|
+
function isArrayLike2(value) {
|
|
12459
13601
|
return value && typeof value.length === "number" && value.length >= 0 && value.length % 1 === 0;
|
|
12460
13602
|
}
|
|
12461
13603
|
var breakLoop = {};
|
|
@@ -12503,7 +13645,7 @@ function createObjectIterator(obj) {
|
|
|
12503
13645
|
};
|
|
12504
13646
|
}
|
|
12505
13647
|
function createIterator(coll) {
|
|
12506
|
-
if (
|
|
13648
|
+
if (isArrayLike2(coll)) {
|
|
12507
13649
|
return createArrayIterator(coll);
|
|
12508
13650
|
}
|
|
12509
13651
|
var iterator = getIterator(coll);
|
|
@@ -12577,7 +13719,7 @@ var eachOfLimit$2 = (limit) => {
|
|
|
12577
13719
|
if (isAsyncGenerator2(obj)) {
|
|
12578
13720
|
return asyncEachOfLimit(obj, limit, iteratee, callback);
|
|
12579
13721
|
}
|
|
12580
|
-
if (
|
|
13722
|
+
if (isAsyncIterable3(obj)) {
|
|
12581
13723
|
return asyncEachOfLimit(obj[Symbol.asyncIterator](), limit, iteratee, callback);
|
|
12582
13724
|
}
|
|
12583
13725
|
var nextElem = createIterator(obj);
|
|
@@ -12649,7 +13791,7 @@ function eachOfGeneric(coll, iteratee, callback) {
|
|
|
12649
13791
|
return eachOfLimit$1(coll, Infinity, iteratee, callback);
|
|
12650
13792
|
}
|
|
12651
13793
|
function eachOf(coll, iteratee, callback) {
|
|
12652
|
-
var eachOfImplementation =
|
|
13794
|
+
var eachOfImplementation = isArrayLike2(coll) ? eachOfArrayLike : eachOfGeneric;
|
|
12653
13795
|
return eachOfImplementation(coll, wrapAsync(iteratee), callback);
|
|
12654
13796
|
}
|
|
12655
13797
|
var eachOf$1 = awaitify(eachOf, 3);
|
|
@@ -13164,7 +14306,7 @@ function filterGeneric(eachfn, coll, iteratee, callback) {
|
|
|
13164
14306
|
});
|
|
13165
14307
|
}
|
|
13166
14308
|
function _filter(eachfn, coll, iteratee, callback) {
|
|
13167
|
-
var filter2 =
|
|
14309
|
+
var filter2 = isArrayLike2(coll) ? filterArray : filterGeneric;
|
|
13168
14310
|
return filter2(eachfn, coll, wrapAsync(iteratee), callback);
|
|
13169
14311
|
}
|
|
13170
14312
|
function filter(coll, iteratee, callback) {
|
|
@@ -13239,7 +14381,7 @@ if (hasNextTick) {
|
|
|
13239
14381
|
}
|
|
13240
14382
|
var nextTick = wrap(_defer);
|
|
13241
14383
|
var _parallel = awaitify((eachfn, tasks, callback) => {
|
|
13242
|
-
var results =
|
|
14384
|
+
var results = isArrayLike2(tasks) ? [] : {};
|
|
13243
14385
|
eachfn(tasks, (task, key, taskCb) => {
|
|
13244
14386
|
wrapAsync(task)((err, ...result) => {
|
|
13245
14387
|
if (result.length < 2) {
|
|
@@ -13920,7 +15062,7 @@ function callEvaluatorData(data) {
|
|
|
13920
15062
|
baseExperiment
|
|
13921
15063
|
};
|
|
13922
15064
|
}
|
|
13923
|
-
function
|
|
15065
|
+
function isAsyncIterable4(value) {
|
|
13924
15066
|
return typeof value === "object" && value !== null && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
13925
15067
|
}
|
|
13926
15068
|
function isIterable(value) {
|
|
@@ -14125,7 +15267,7 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
|
|
|
14125
15267
|
}
|
|
14126
15268
|
const resolvedDataResult = dataResult instanceof Promise ? await dataResult : dataResult;
|
|
14127
15269
|
const dataIterable = (() => {
|
|
14128
|
-
if (
|
|
15270
|
+
if (isAsyncIterable4(resolvedDataResult)) {
|
|
14129
15271
|
return resolvedDataResult;
|
|
14130
15272
|
}
|
|
14131
15273
|
if (Array.isArray(resolvedDataResult) || isIterable(resolvedDataResult)) {
|