braintrust 3.4.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 +49 -7
- package/dev/dist/index.d.ts +49 -7
- package/dev/dist/index.js +2383 -494
- package/dev/dist/index.mjs +2213 -324
- package/dist/auto-instrumentations/bundler/esbuild.cjs +289 -10
- package/dist/auto-instrumentations/bundler/esbuild.d.mts +2 -2
- package/dist/auto-instrumentations/bundler/esbuild.d.ts +2 -2
- package/dist/auto-instrumentations/bundler/esbuild.mjs +2 -2
- package/dist/auto-instrumentations/bundler/rollup.cjs +289 -10
- package/dist/auto-instrumentations/bundler/rollup.mjs +2 -2
- package/dist/auto-instrumentations/bundler/vite.cjs +289 -10
- package/dist/auto-instrumentations/bundler/vite.d.mts +2 -2
- package/dist/auto-instrumentations/bundler/vite.d.ts +2 -2
- package/dist/auto-instrumentations/bundler/vite.mjs +2 -2
- package/dist/auto-instrumentations/bundler/webpack.cjs +289 -10
- package/dist/auto-instrumentations/bundler/webpack.d.mts +2 -2
- package/dist/auto-instrumentations/bundler/webpack.d.ts +2 -2
- package/dist/auto-instrumentations/bundler/webpack.mjs +2 -2
- package/dist/auto-instrumentations/chunk-EVUKFMHG.mjs +41 -0
- package/dist/auto-instrumentations/{chunk-LVWWLUMN.mjs → chunk-F7WAXFNM.mjs} +290 -11
- package/dist/auto-instrumentations/chunk-VLEJ5AEK.mjs +41 -0
- package/dist/auto-instrumentations/{chunk-D5ZPIUEL.mjs → chunk-WOUC73KB.mjs} +3 -1
- package/dist/auto-instrumentations/hook.mjs +358 -48
- package/dist/auto-instrumentations/index.cjs +290 -10
- 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/auto-instrumentations/loader/cjs-patch.cjs +32 -10
- package/dist/auto-instrumentations/loader/cjs-patch.mjs +10 -5
- package/dist/auto-instrumentations/loader/esm-hook.mjs +4 -4
- package/dist/auto-instrumentations/loader/get-package-version.cjs +28 -8
- package/dist/auto-instrumentations/loader/get-package-version.d.mts +2 -1
- package/dist/auto-instrumentations/loader/get-package-version.d.ts +2 -1
- package/dist/auto-instrumentations/loader/get-package-version.mjs +3 -1
- package/dist/browser.d.mts +357 -271
- package/dist/browser.d.ts +357 -271
- package/dist/browser.js +2345 -343
- package/dist/browser.mjs +2345 -343
- package/dist/cli.js +2296 -414
- package/dist/edge-light.d.mts +1 -1
- package/dist/edge-light.d.ts +1 -1
- package/dist/edge-light.js +2292 -315
- package/dist/edge-light.mjs +2292 -315
- package/dist/index.d.mts +370 -284
- package/dist/index.d.ts +370 -284
- package/dist/index.js +2642 -638
- package/dist/index.mjs +2385 -381
- package/dist/instrumentation/index.d.mts +3 -0
- package/dist/instrumentation/index.d.ts +3 -0
- package/dist/instrumentation/index.js +1955 -198
- package/dist/instrumentation/index.mjs +1955 -198
- package/dist/workerd.d.mts +1 -1
- package/dist/workerd.d.ts +1 -1
- package/dist/workerd.js +2292 -315
- package/dist/workerd.mjs +2292 -315
- package/package.json +22 -6
- package/dist/auto-instrumentations/chunk-XDBPUTVE.mjs +0 -22
- package/dist/auto-instrumentations/chunk-ZEC7BCL4.mjs +0 -22
package/dist/browser.js
CHANGED
|
@@ -161,6 +161,7 @@ __export(browser_exports, {
|
|
|
161
161
|
wrapMastraAgent: () => wrapMastraAgent,
|
|
162
162
|
wrapOpenAI: () => wrapOpenAI,
|
|
163
163
|
wrapOpenAIv4: () => wrapOpenAIv4,
|
|
164
|
+
wrapOpenRouter: () => wrapOpenRouter,
|
|
164
165
|
wrapTraced: () => wrapTraced,
|
|
165
166
|
wrapVitest: () => wrapVitest
|
|
166
167
|
});
|
|
@@ -182,8 +183,54 @@ var DefaultAsyncLocalStorage = class {
|
|
|
182
183
|
return void 0;
|
|
183
184
|
}
|
|
184
185
|
};
|
|
185
|
-
var
|
|
186
|
+
var DefaultChannel = class {
|
|
187
|
+
constructor(name) {
|
|
188
|
+
this.name = name;
|
|
189
|
+
}
|
|
186
190
|
hasSubscribers = false;
|
|
191
|
+
subscribe(_subscription) {
|
|
192
|
+
}
|
|
193
|
+
unsubscribe(_subscription) {
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
bindStore(_store, _transform) {
|
|
197
|
+
}
|
|
198
|
+
unbindStore(_store) {
|
|
199
|
+
return false;
|
|
200
|
+
}
|
|
201
|
+
publish(_message) {
|
|
202
|
+
}
|
|
203
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
204
|
+
runStores(_message, fn, thisArg, ...args) {
|
|
205
|
+
return fn.apply(thisArg, args);
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
var DefaultTracingChannel = class {
|
|
209
|
+
start;
|
|
210
|
+
end;
|
|
211
|
+
asyncStart;
|
|
212
|
+
asyncEnd;
|
|
213
|
+
error;
|
|
214
|
+
constructor(nameOrChannels) {
|
|
215
|
+
if (typeof nameOrChannels === "string") {
|
|
216
|
+
this.start = new DefaultChannel(`tracing:${nameOrChannels}:start`);
|
|
217
|
+
this.end = new DefaultChannel(`tracing:${nameOrChannels}:end`);
|
|
218
|
+
this.asyncStart = new DefaultChannel(
|
|
219
|
+
`tracing:${nameOrChannels}:asyncStart`
|
|
220
|
+
);
|
|
221
|
+
this.asyncEnd = new DefaultChannel(`tracing:${nameOrChannels}:asyncEnd`);
|
|
222
|
+
this.error = new DefaultChannel(`tracing:${nameOrChannels}:error`);
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
this.start = nameOrChannels.start ?? new DefaultChannel("tracing:start");
|
|
226
|
+
this.end = nameOrChannels.end ?? new DefaultChannel("tracing:end");
|
|
227
|
+
this.asyncStart = nameOrChannels.asyncStart ?? new DefaultChannel("tracing:asyncStart");
|
|
228
|
+
this.asyncEnd = nameOrChannels.asyncEnd ?? new DefaultChannel("tracing:asyncEnd");
|
|
229
|
+
this.error = nameOrChannels.error ?? new DefaultChannel("tracing:error");
|
|
230
|
+
}
|
|
231
|
+
get hasSubscribers() {
|
|
232
|
+
return this.start.hasSubscribers || this.end.hasSubscribers || this.asyncStart.hasSubscribers || this.asyncEnd.hasSubscribers || this.error.hasSubscribers;
|
|
233
|
+
}
|
|
187
234
|
subscribe(_handlers) {
|
|
188
235
|
}
|
|
189
236
|
unsubscribe(_handlers) {
|
|
@@ -211,7 +258,7 @@ var iso = {
|
|
|
211
258
|
getCallerLocation: () => void 0,
|
|
212
259
|
newAsyncLocalStorage: () => new DefaultAsyncLocalStorage(),
|
|
213
260
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
214
|
-
newTracingChannel: (
|
|
261
|
+
newTracingChannel: (nameOrChannels) => new DefaultTracingChannel(nameOrChannels),
|
|
215
262
|
processOn: (_0, _1) => {
|
|
216
263
|
},
|
|
217
264
|
basename: (filepath) => filepath.split(/[\\/]/).pop() || filepath,
|
|
@@ -2278,6 +2325,8 @@ var Experiment = import_v36.z.object({
|
|
|
2278
2325
|
deleted_at: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
|
|
2279
2326
|
dataset_id: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
|
|
2280
2327
|
dataset_version: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
|
|
2328
|
+
parameters_id: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
|
|
2329
|
+
parameters_version: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
|
|
2281
2330
|
public: import_v36.z.boolean(),
|
|
2282
2331
|
user_id: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
|
|
2283
2332
|
metadata: import_v36.z.union([import_v36.z.object({}).partial().passthrough(), import_v36.z.null()]).optional(),
|
|
@@ -2300,7 +2349,11 @@ var SpanType = import_v36.z.union([
|
|
|
2300
2349
|
import_v36.z.null()
|
|
2301
2350
|
]);
|
|
2302
2351
|
var SpanAttributes = import_v36.z.union([
|
|
2303
|
-
import_v36.z.object({
|
|
2352
|
+
import_v36.z.object({
|
|
2353
|
+
name: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]),
|
|
2354
|
+
type: SpanType,
|
|
2355
|
+
purpose: import_v36.z.union([import_v36.z.literal("scorer"), import_v36.z.null()])
|
|
2356
|
+
}).partial().passthrough(),
|
|
2304
2357
|
import_v36.z.null()
|
|
2305
2358
|
]);
|
|
2306
2359
|
var ExperimentEvent = import_v36.z.object({
|
|
@@ -2740,6 +2793,7 @@ var FunctionId = import_v36.z.union([
|
|
|
2740
2793
|
version: import_v36.z.string()
|
|
2741
2794
|
}),
|
|
2742
2795
|
code: import_v36.z.string(),
|
|
2796
|
+
function_type: FunctionTypeEnum.and(import_v36.z.unknown()).optional(),
|
|
2743
2797
|
name: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional()
|
|
2744
2798
|
}),
|
|
2745
2799
|
import_v36.z.object({
|
|
@@ -2969,7 +3023,12 @@ var TopicAutomationConfig = import_v36.z.object({
|
|
|
2969
3023
|
topic_map_functions: import_v36.z.array(TopicMapFunctionAutomation),
|
|
2970
3024
|
scope: import_v36.z.union([SpanScope, TraceScope, GroupScope, import_v36.z.null()]).optional(),
|
|
2971
3025
|
data_scope: TopicAutomationDataScope.optional(),
|
|
2972
|
-
btql_filter: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional()
|
|
3026
|
+
btql_filter: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
|
|
3027
|
+
backfill_time_range: import_v36.z.union([
|
|
3028
|
+
import_v36.z.string(),
|
|
3029
|
+
import_v36.z.object({ from: import_v36.z.string(), to: import_v36.z.string() }),
|
|
3030
|
+
import_v36.z.null()
|
|
3031
|
+
]).optional()
|
|
2973
3032
|
});
|
|
2974
3033
|
var ProjectAutomation = import_v36.z.object({
|
|
2975
3034
|
id: import_v36.z.string().uuid(),
|
|
@@ -4390,6 +4449,9 @@ var BRAINTRUST_ATTACHMENT = BraintrustAttachmentReference.shape.type.value;
|
|
|
4390
4449
|
var EXTERNAL_ATTACHMENT = ExternalAttachmentReference.shape.type.value;
|
|
4391
4450
|
var LOGS3_OVERFLOW_REFERENCE_TYPE = "logs3_overflow";
|
|
4392
4451
|
var BRAINTRUST_PARAMS = Object.keys(BraintrustModelParams.shape);
|
|
4452
|
+
var RESET_CONTEXT_MANAGER_STATE = Symbol.for(
|
|
4453
|
+
"braintrust.resetContextManagerState"
|
|
4454
|
+
);
|
|
4393
4455
|
var DEFAULT_MAX_REQUEST_SIZE = 6 * 1024 * 1024;
|
|
4394
4456
|
var parametersRowSchema = import_v38.z.object({
|
|
4395
4457
|
id: import_v38.z.string().uuid(),
|
|
@@ -4406,6 +4468,12 @@ var parametersRowSchema = import_v38.z.object({
|
|
|
4406
4468
|
}),
|
|
4407
4469
|
metadata: import_v38.z.union([import_v38.z.object({}).partial().passthrough(), import_v38.z.null()]).optional()
|
|
4408
4470
|
});
|
|
4471
|
+
var InlineAttachmentReferenceSchema = import_v38.z.object({
|
|
4472
|
+
type: import_v38.z.literal("inline_attachment"),
|
|
4473
|
+
src: import_v38.z.string().min(1),
|
|
4474
|
+
content_type: import_v38.z.string().optional(),
|
|
4475
|
+
filename: import_v38.z.string().optional()
|
|
4476
|
+
});
|
|
4409
4477
|
var LoginInvalidOrgError = class extends Error {
|
|
4410
4478
|
constructor(message) {
|
|
4411
4479
|
super(message);
|
|
@@ -4446,13 +4514,18 @@ function applyMaskingToField(maskingFunction, data, fieldName) {
|
|
|
4446
4514
|
return `ERROR: Failed to mask field '${fieldName}' - ${errorType}`;
|
|
4447
4515
|
}
|
|
4448
4516
|
}
|
|
4517
|
+
var BRAINTRUST_CURRENT_SPAN_STORE = Symbol.for(
|
|
4518
|
+
"braintrust.currentSpanStore"
|
|
4519
|
+
);
|
|
4449
4520
|
var ContextManager = class {
|
|
4450
4521
|
};
|
|
4451
4522
|
var BraintrustContextManager = class extends ContextManager {
|
|
4452
4523
|
_currentSpan;
|
|
4524
|
+
[BRAINTRUST_CURRENT_SPAN_STORE];
|
|
4453
4525
|
constructor() {
|
|
4454
4526
|
super();
|
|
4455
4527
|
this._currentSpan = isomorph_default.newAsyncLocalStorage();
|
|
4528
|
+
this[BRAINTRUST_CURRENT_SPAN_STORE] = this._currentSpan;
|
|
4456
4529
|
}
|
|
4457
4530
|
getParentSpanIds() {
|
|
4458
4531
|
const currentSpan2 = this._currentSpan.getStore();
|
|
@@ -4659,6 +4732,9 @@ var BraintrustState = class _BraintrustState {
|
|
|
4659
4732
|
resetIdGenState() {
|
|
4660
4733
|
this._idGenerator = null;
|
|
4661
4734
|
}
|
|
4735
|
+
[RESET_CONTEXT_MANAGER_STATE]() {
|
|
4736
|
+
this._contextManager = null;
|
|
4737
|
+
}
|
|
4662
4738
|
get idGenerator() {
|
|
4663
4739
|
if (this._idGenerator === null) {
|
|
4664
4740
|
this._idGenerator = getIdGenerator();
|
|
@@ -6607,6 +6683,7 @@ function init(projectOrOptions, optionalOptions) {
|
|
|
6607
6683
|
experiment,
|
|
6608
6684
|
description,
|
|
6609
6685
|
dataset,
|
|
6686
|
+
parameters,
|
|
6610
6687
|
baseExperiment,
|
|
6611
6688
|
isPublic,
|
|
6612
6689
|
open,
|
|
@@ -6724,6 +6801,17 @@ function init(projectOrOptions, optionalOptions) {
|
|
|
6724
6801
|
args["dataset_version"] = await dataset.version();
|
|
6725
6802
|
}
|
|
6726
6803
|
}
|
|
6804
|
+
if (parameters !== void 0) {
|
|
6805
|
+
if (RemoteEvalParameters.isParameters(parameters)) {
|
|
6806
|
+
args["parameters_id"] = parameters.id;
|
|
6807
|
+
args["parameters_version"] = parameters.version;
|
|
6808
|
+
} else {
|
|
6809
|
+
args["parameters_id"] = parameters.id;
|
|
6810
|
+
if (parameters.version !== void 0) {
|
|
6811
|
+
args["parameters_version"] = parameters.version;
|
|
6812
|
+
}
|
|
6813
|
+
}
|
|
6814
|
+
}
|
|
6727
6815
|
if (isPublic !== void 0) {
|
|
6728
6816
|
args["public"] = isPublic;
|
|
6729
6817
|
}
|
|
@@ -6982,11 +7070,7 @@ async function loadPrompt({
|
|
|
6982
7070
|
forceLogin,
|
|
6983
7071
|
state: stateArg
|
|
6984
7072
|
}) {
|
|
6985
|
-
|
|
6986
|
-
throw new Error(
|
|
6987
|
-
"Cannot specify both 'version' and 'environment' parameters. Please use only one (remove the other)."
|
|
6988
|
-
);
|
|
6989
|
-
}
|
|
7073
|
+
const versionOrEnvironment = version ? { version } : environment ? { environment } : {};
|
|
6990
7074
|
if (id) {
|
|
6991
7075
|
} else if (isEmpty2(projectName) && isEmpty2(projectId)) {
|
|
6992
7076
|
throw new Error("Must specify either projectName or projectId");
|
|
@@ -7004,10 +7088,7 @@ async function loadPrompt({
|
|
|
7004
7088
|
forceLogin
|
|
7005
7089
|
});
|
|
7006
7090
|
if (id) {
|
|
7007
|
-
response = await state.apiConn().get_json(`v1/prompt/${id}`,
|
|
7008
|
-
...version && { version },
|
|
7009
|
-
...environment && { environment }
|
|
7010
|
-
});
|
|
7091
|
+
response = await state.apiConn().get_json(`v1/prompt/${id}`, versionOrEnvironment);
|
|
7011
7092
|
if (response) {
|
|
7012
7093
|
response = { objects: [response] };
|
|
7013
7094
|
}
|
|
@@ -7016,12 +7097,11 @@ async function loadPrompt({
|
|
|
7016
7097
|
project_name: projectName,
|
|
7017
7098
|
project_id: projectId,
|
|
7018
7099
|
slug,
|
|
7019
|
-
|
|
7020
|
-
...environment && { environment }
|
|
7100
|
+
...versionOrEnvironment
|
|
7021
7101
|
});
|
|
7022
7102
|
}
|
|
7023
7103
|
} catch (e) {
|
|
7024
|
-
if (
|
|
7104
|
+
if (version || environment) {
|
|
7025
7105
|
throw new Error(`Prompt not found with specified parameters: ${e}`);
|
|
7026
7106
|
}
|
|
7027
7107
|
debugLogger.forState(state).warn("Failed to load prompt, attempting to fall back to cache:", e);
|
|
@@ -7099,11 +7179,7 @@ async function loadParameters({
|
|
|
7099
7179
|
forceLogin,
|
|
7100
7180
|
state: stateArg
|
|
7101
7181
|
}) {
|
|
7102
|
-
|
|
7103
|
-
throw new Error(
|
|
7104
|
-
"Cannot specify both 'version' and 'environment' parameters. Please use only one (remove the other)."
|
|
7105
|
-
);
|
|
7106
|
-
}
|
|
7182
|
+
const versionOrEnvironment = version ? { version } : environment ? { environment } : {};
|
|
7107
7183
|
if (id) {
|
|
7108
7184
|
} else if (isEmpty2(projectName) && isEmpty2(projectId)) {
|
|
7109
7185
|
throw new Error("Must specify either projectName or projectId");
|
|
@@ -7122,8 +7198,7 @@ async function loadParameters({
|
|
|
7122
7198
|
});
|
|
7123
7199
|
if (id) {
|
|
7124
7200
|
response = await state.apiConn().get_json(`v1/function/${id}`, {
|
|
7125
|
-
...
|
|
7126
|
-
...environment && { environment }
|
|
7201
|
+
...versionOrEnvironment
|
|
7127
7202
|
});
|
|
7128
7203
|
if (response) {
|
|
7129
7204
|
response = { objects: [response] };
|
|
@@ -7133,13 +7208,12 @@ async function loadParameters({
|
|
|
7133
7208
|
project_name: projectName,
|
|
7134
7209
|
project_id: projectId,
|
|
7135
7210
|
slug,
|
|
7136
|
-
version,
|
|
7137
7211
|
function_type: "parameters",
|
|
7138
|
-
...
|
|
7212
|
+
...versionOrEnvironment
|
|
7139
7213
|
});
|
|
7140
7214
|
}
|
|
7141
7215
|
} catch (e) {
|
|
7142
|
-
if (
|
|
7216
|
+
if (version || environment) {
|
|
7143
7217
|
throw new Error(`Parameters not found with specified parameters: ${e}`);
|
|
7144
7218
|
}
|
|
7145
7219
|
debugLogger.forState(state).warn("Failed to load parameters, attempting to fall back to cache:", e);
|
|
@@ -8922,40 +8996,85 @@ var Dataset2 = class extends ObjectFetcher {
|
|
|
8922
8996
|
return typeof data === "object" && data !== null && "__braintrust_dataset_marker" in data;
|
|
8923
8997
|
}
|
|
8924
8998
|
};
|
|
8999
|
+
function isAttachmentObject(value) {
|
|
9000
|
+
return BraintrustAttachmentReference.safeParse(value).success || InlineAttachmentReferenceSchema.safeParse(value).success || ExternalAttachmentReference.safeParse(value).success;
|
|
9001
|
+
}
|
|
9002
|
+
function isURL(url) {
|
|
9003
|
+
try {
|
|
9004
|
+
const parsedUrl = new URL(url.trim());
|
|
9005
|
+
return parsedUrl.protocol === "http:" || parsedUrl.protocol === "https:";
|
|
9006
|
+
} catch {
|
|
9007
|
+
return false;
|
|
9008
|
+
}
|
|
9009
|
+
}
|
|
9010
|
+
function expandAttachmentArrayPreTemplate(content, variables) {
|
|
9011
|
+
if (typeof content !== "string") return null;
|
|
9012
|
+
const match = content.match(/^\{\{\s*([\w.]+)\s*\}\}$/);
|
|
9013
|
+
if (!match) return null;
|
|
9014
|
+
const varPath = match[1];
|
|
9015
|
+
const value = varPath.includes(".") ? getObjValueByPath(variables, varPath.split(".")) : variables[varPath];
|
|
9016
|
+
if (!Array.isArray(value)) return null;
|
|
9017
|
+
const allValid = value.every(
|
|
9018
|
+
(v) => isAttachmentObject(v) || typeof v === "string" && isURL(v)
|
|
9019
|
+
);
|
|
9020
|
+
if (!allValid) return null;
|
|
9021
|
+
return value.map((item) => ({
|
|
9022
|
+
type: "image_url",
|
|
9023
|
+
image_url: { url: item }
|
|
9024
|
+
}));
|
|
9025
|
+
}
|
|
8925
9026
|
function renderMessage(render, message) {
|
|
9027
|
+
return renderMessageImpl(render, message, {});
|
|
9028
|
+
}
|
|
9029
|
+
function renderMessageImpl(render, message, variables) {
|
|
8926
9030
|
return {
|
|
8927
9031
|
...message,
|
|
8928
9032
|
..."content" in message ? {
|
|
8929
|
-
content: isEmpty2(message.content) ? void 0 : typeof message.content === "string" ? render(message.content) : message.content.
|
|
9033
|
+
content: isEmpty2(message.content) ? void 0 : typeof message.content === "string" ? render(message.content) : message.content.flatMap((c) => {
|
|
8930
9034
|
switch (c.type) {
|
|
8931
9035
|
case "text":
|
|
8932
|
-
return { ...c, text: render(c.text) };
|
|
9036
|
+
return [{ ...c, text: render(c.text) }];
|
|
8933
9037
|
case "image_url":
|
|
8934
9038
|
if (isObject(c.image_url.url)) {
|
|
8935
9039
|
throw new Error(
|
|
8936
9040
|
"Attachments must be replaced with URLs before calling `build()`"
|
|
8937
9041
|
);
|
|
8938
9042
|
}
|
|
8939
|
-
|
|
8940
|
-
|
|
8941
|
-
|
|
8942
|
-
|
|
8943
|
-
|
|
9043
|
+
if (variables) {
|
|
9044
|
+
const expanded = expandAttachmentArrayPreTemplate(
|
|
9045
|
+
c.image_url.url,
|
|
9046
|
+
variables
|
|
9047
|
+
);
|
|
9048
|
+
if (expanded) {
|
|
9049
|
+
return expanded;
|
|
8944
9050
|
}
|
|
8945
|
-
}
|
|
9051
|
+
}
|
|
9052
|
+
return [
|
|
9053
|
+
{
|
|
9054
|
+
...c,
|
|
9055
|
+
image_url: {
|
|
9056
|
+
...c.image_url,
|
|
9057
|
+
url: render(c.image_url.url)
|
|
9058
|
+
}
|
|
9059
|
+
}
|
|
9060
|
+
];
|
|
8946
9061
|
case "file":
|
|
8947
|
-
return
|
|
8948
|
-
|
|
8949
|
-
|
|
8950
|
-
|
|
8951
|
-
|
|
8952
|
-
|
|
8953
|
-
|
|
8954
|
-
|
|
8955
|
-
|
|
9062
|
+
return [
|
|
9063
|
+
{
|
|
9064
|
+
...c,
|
|
9065
|
+
file: {
|
|
9066
|
+
...c.file.file_data && {
|
|
9067
|
+
file_data: render(c.file.file_data)
|
|
9068
|
+
},
|
|
9069
|
+
...c.file.file_id && {
|
|
9070
|
+
file_id: render(c.file.file_id)
|
|
9071
|
+
},
|
|
9072
|
+
...c.file.filename && {
|
|
9073
|
+
filename: render(c.file.filename)
|
|
9074
|
+
}
|
|
8956
9075
|
}
|
|
8957
9076
|
}
|
|
8958
|
-
|
|
9077
|
+
];
|
|
8959
9078
|
default:
|
|
8960
9079
|
const _exhaustiveCheck = c;
|
|
8961
9080
|
return _exhaustiveCheck;
|
|
@@ -9112,17 +9231,19 @@ var Prompt2 = class _Prompt {
|
|
|
9112
9231
|
}
|
|
9113
9232
|
runBuild(buildArgs, options) {
|
|
9114
9233
|
const { flavor } = options;
|
|
9115
|
-
const params =
|
|
9116
|
-
|
|
9117
|
-
|
|
9118
|
-
Object.
|
|
9119
|
-
(
|
|
9120
|
-
|
|
9121
|
-
|
|
9122
|
-
|
|
9123
|
-
|
|
9124
|
-
|
|
9125
|
-
|
|
9234
|
+
const params = Object.fromEntries(
|
|
9235
|
+
Object.entries({
|
|
9236
|
+
...this.defaults,
|
|
9237
|
+
...Object.fromEntries(
|
|
9238
|
+
Object.entries(this.options.params || {}).filter(
|
|
9239
|
+
([k, _v]) => !BRAINTRUST_PARAMS.includes(k)
|
|
9240
|
+
)
|
|
9241
|
+
),
|
|
9242
|
+
...!isEmpty2(this.options.model) ? {
|
|
9243
|
+
model: this.options.model
|
|
9244
|
+
} : {}
|
|
9245
|
+
}).filter(([key, value]) => key !== "response_format" || value !== null)
|
|
9246
|
+
);
|
|
9126
9247
|
if (!("model" in params) || isEmpty2(params.model)) {
|
|
9127
9248
|
throw new Error(
|
|
9128
9249
|
"No model specified. Either specify it in the prompt or as a default"
|
|
@@ -9222,7 +9343,7 @@ var Prompt2 = class _Prompt {
|
|
|
9222
9343
|
templateFormat
|
|
9223
9344
|
});
|
|
9224
9345
|
const baseMessages = (prompt.messages || []).map(
|
|
9225
|
-
(m) =>
|
|
9346
|
+
(m) => renderMessageImpl(render, m, variables)
|
|
9226
9347
|
);
|
|
9227
9348
|
const hasSystemPrompt = baseMessages.some((m) => m.role === "system");
|
|
9228
9349
|
const messages = [
|
|
@@ -9342,6 +9463,8 @@ async function simulateLoginForTests() {
|
|
|
9342
9463
|
function simulateLogoutForTests() {
|
|
9343
9464
|
const state = _internalGetGlobalState();
|
|
9344
9465
|
state.resetLoginInfo();
|
|
9466
|
+
state.resetIdGenState();
|
|
9467
|
+
state[RESET_CONTEXT_MANAGER_STATE]();
|
|
9345
9468
|
state.appUrl = "https://www.braintrust.dev";
|
|
9346
9469
|
return state;
|
|
9347
9470
|
}
|
|
@@ -9941,7 +10064,11 @@ function startSpanForEvent(config, event, channelName) {
|
|
|
9941
10064
|
});
|
|
9942
10065
|
const startTime = getCurrentUnixTimestamp();
|
|
9943
10066
|
try {
|
|
9944
|
-
const { input, metadata } = config.extractInput(
|
|
10067
|
+
const { input, metadata } = config.extractInput(
|
|
10068
|
+
event.arguments,
|
|
10069
|
+
event,
|
|
10070
|
+
span
|
|
10071
|
+
);
|
|
9945
10072
|
span.log({
|
|
9946
10073
|
input,
|
|
9947
10074
|
metadata: mergeInputMetadata(metadata, spanInfoMetadata)
|
|
@@ -9951,6 +10078,36 @@ function startSpanForEvent(config, event, channelName) {
|
|
|
9951
10078
|
}
|
|
9952
10079
|
return { span, startTime };
|
|
9953
10080
|
}
|
|
10081
|
+
function ensureSpanStateForEvent(states, config, event, channelName) {
|
|
10082
|
+
const key = event;
|
|
10083
|
+
const existing = states.get(key);
|
|
10084
|
+
if (existing) {
|
|
10085
|
+
return existing;
|
|
10086
|
+
}
|
|
10087
|
+
const created = startSpanForEvent(config, event, channelName);
|
|
10088
|
+
states.set(key, created);
|
|
10089
|
+
return created;
|
|
10090
|
+
}
|
|
10091
|
+
function bindCurrentSpanStoreToStart(tracingChannel2, states, config, channelName) {
|
|
10092
|
+
const state = _internalGetGlobalState();
|
|
10093
|
+
const startChannel = tracingChannel2.start;
|
|
10094
|
+
const currentSpanStore = state?.contextManager ? state.contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
|
|
10095
|
+
if (!currentSpanStore || !startChannel) {
|
|
10096
|
+
return void 0;
|
|
10097
|
+
}
|
|
10098
|
+
startChannel.bindStore(
|
|
10099
|
+
currentSpanStore,
|
|
10100
|
+
(event) => ensureSpanStateForEvent(
|
|
10101
|
+
states,
|
|
10102
|
+
config,
|
|
10103
|
+
event,
|
|
10104
|
+
channelName
|
|
10105
|
+
).span
|
|
10106
|
+
);
|
|
10107
|
+
return () => {
|
|
10108
|
+
startChannel.unbindStore(currentSpanStore);
|
|
10109
|
+
};
|
|
10110
|
+
}
|
|
9954
10111
|
function logErrorAndEnd(states, event) {
|
|
9955
10112
|
const spanData = states.get(event);
|
|
9956
10113
|
if (!spanData) {
|
|
@@ -9966,15 +10123,19 @@ function traceAsyncChannel(channel2, config) {
|
|
|
9966
10123
|
const tracingChannel2 = channel2.tracingChannel();
|
|
9967
10124
|
const states = /* @__PURE__ */ new WeakMap();
|
|
9968
10125
|
const channelName = channel2.channelName;
|
|
10126
|
+
const unbindCurrentSpanStore = bindCurrentSpanStoreToStart(
|
|
10127
|
+
tracingChannel2,
|
|
10128
|
+
states,
|
|
10129
|
+
config,
|
|
10130
|
+
channelName
|
|
10131
|
+
);
|
|
9969
10132
|
const handlers = {
|
|
9970
10133
|
start: (event) => {
|
|
9971
|
-
|
|
10134
|
+
ensureSpanStateForEvent(
|
|
10135
|
+
states,
|
|
10136
|
+
config,
|
|
9972
10137
|
event,
|
|
9973
|
-
|
|
9974
|
-
config,
|
|
9975
|
-
event,
|
|
9976
|
-
channelName
|
|
9977
|
-
)
|
|
10138
|
+
channelName
|
|
9978
10139
|
);
|
|
9979
10140
|
},
|
|
9980
10141
|
asyncEnd: (event) => {
|
|
@@ -10016,6 +10177,7 @@ function traceAsyncChannel(channel2, config) {
|
|
|
10016
10177
|
};
|
|
10017
10178
|
tracingChannel2.subscribe(handlers);
|
|
10018
10179
|
return () => {
|
|
10180
|
+
unbindCurrentSpanStore?.();
|
|
10019
10181
|
tracingChannel2.unsubscribe(handlers);
|
|
10020
10182
|
};
|
|
10021
10183
|
}
|
|
@@ -10023,15 +10185,19 @@ function traceStreamingChannel(channel2, config) {
|
|
|
10023
10185
|
const tracingChannel2 = channel2.tracingChannel();
|
|
10024
10186
|
const states = /* @__PURE__ */ new WeakMap();
|
|
10025
10187
|
const channelName = channel2.channelName;
|
|
10188
|
+
const unbindCurrentSpanStore = bindCurrentSpanStoreToStart(
|
|
10189
|
+
tracingChannel2,
|
|
10190
|
+
states,
|
|
10191
|
+
config,
|
|
10192
|
+
channelName
|
|
10193
|
+
);
|
|
10026
10194
|
const handlers = {
|
|
10027
10195
|
start: (event) => {
|
|
10028
|
-
|
|
10196
|
+
ensureSpanStateForEvent(
|
|
10197
|
+
states,
|
|
10198
|
+
config,
|
|
10029
10199
|
event,
|
|
10030
|
-
|
|
10031
|
-
config,
|
|
10032
|
-
event,
|
|
10033
|
-
channelName
|
|
10034
|
-
)
|
|
10200
|
+
channelName
|
|
10035
10201
|
);
|
|
10036
10202
|
},
|
|
10037
10203
|
asyncEnd: (event) => {
|
|
@@ -10105,6 +10271,16 @@ function traceStreamingChannel(channel2, config) {
|
|
|
10105
10271
|
});
|
|
10106
10272
|
return;
|
|
10107
10273
|
}
|
|
10274
|
+
if (config.patchResult?.({
|
|
10275
|
+
channelName,
|
|
10276
|
+
endEvent: asyncEndEvent,
|
|
10277
|
+
result: asyncEndEvent.result,
|
|
10278
|
+
span,
|
|
10279
|
+
startTime
|
|
10280
|
+
})) {
|
|
10281
|
+
states.delete(event);
|
|
10282
|
+
return;
|
|
10283
|
+
}
|
|
10108
10284
|
try {
|
|
10109
10285
|
const output = config.extractOutput(
|
|
10110
10286
|
asyncEndEvent.result,
|
|
@@ -10137,6 +10313,7 @@ function traceStreamingChannel(channel2, config) {
|
|
|
10137
10313
|
};
|
|
10138
10314
|
tracingChannel2.subscribe(handlers);
|
|
10139
10315
|
return () => {
|
|
10316
|
+
unbindCurrentSpanStore?.();
|
|
10140
10317
|
tracingChannel2.unsubscribe(handlers);
|
|
10141
10318
|
};
|
|
10142
10319
|
}
|
|
@@ -10144,15 +10321,19 @@ function traceSyncStreamChannel(channel2, config) {
|
|
|
10144
10321
|
const tracingChannel2 = channel2.tracingChannel();
|
|
10145
10322
|
const states = /* @__PURE__ */ new WeakMap();
|
|
10146
10323
|
const channelName = channel2.channelName;
|
|
10324
|
+
const unbindCurrentSpanStore = bindCurrentSpanStoreToStart(
|
|
10325
|
+
tracingChannel2,
|
|
10326
|
+
states,
|
|
10327
|
+
config,
|
|
10328
|
+
channelName
|
|
10329
|
+
);
|
|
10147
10330
|
const handlers = {
|
|
10148
10331
|
start: (event) => {
|
|
10149
|
-
|
|
10332
|
+
ensureSpanStateForEvent(
|
|
10333
|
+
states,
|
|
10334
|
+
config,
|
|
10150
10335
|
event,
|
|
10151
|
-
|
|
10152
|
-
config,
|
|
10153
|
-
event,
|
|
10154
|
-
channelName
|
|
10155
|
-
)
|
|
10336
|
+
channelName
|
|
10156
10337
|
);
|
|
10157
10338
|
},
|
|
10158
10339
|
end: (event) => {
|
|
@@ -10161,8 +10342,17 @@ function traceSyncStreamChannel(channel2, config) {
|
|
|
10161
10342
|
return;
|
|
10162
10343
|
}
|
|
10163
10344
|
const { span, startTime } = spanData;
|
|
10164
|
-
const
|
|
10165
|
-
|
|
10345
|
+
const endEvent = event;
|
|
10346
|
+
if (config.patchResult?.({
|
|
10347
|
+
channelName,
|
|
10348
|
+
endEvent,
|
|
10349
|
+
result: endEvent.result,
|
|
10350
|
+
span,
|
|
10351
|
+
startTime
|
|
10352
|
+
})) {
|
|
10353
|
+
return;
|
|
10354
|
+
}
|
|
10355
|
+
const stream = endEvent.result;
|
|
10166
10356
|
if (!isSyncStreamLike(stream)) {
|
|
10167
10357
|
span.end();
|
|
10168
10358
|
states.delete(event);
|
|
@@ -10232,6 +10422,7 @@ function traceSyncStreamChannel(channel2, config) {
|
|
|
10232
10422
|
};
|
|
10233
10423
|
tracingChannel2.subscribe(handlers);
|
|
10234
10424
|
return () => {
|
|
10425
|
+
unbindCurrentSpanStore?.();
|
|
10235
10426
|
tracingChannel2.unsubscribe(handlers);
|
|
10236
10427
|
};
|
|
10237
10428
|
}
|
|
@@ -11133,6 +11324,108 @@ function filterFrom2(obj, fieldsToRemove) {
|
|
|
11133
11324
|
return result;
|
|
11134
11325
|
}
|
|
11135
11326
|
|
|
11327
|
+
// src/wrappers/ai-sdk/normalize-logged-output.ts
|
|
11328
|
+
var REMOVE_NORMALIZED_VALUE = Symbol("braintrust.ai-sdk.remove-normalized");
|
|
11329
|
+
function normalizeAISDKLoggedOutput(value) {
|
|
11330
|
+
const normalized = normalizeAISDKLoggedValue(value);
|
|
11331
|
+
return normalized === REMOVE_NORMALIZED_VALUE ? {} : normalized;
|
|
11332
|
+
}
|
|
11333
|
+
function normalizeAISDKLoggedValue(value, context = {}) {
|
|
11334
|
+
if (Array.isArray(value)) {
|
|
11335
|
+
return value.map((entry) => normalizeAISDKLoggedValue(entry, context)).filter((entry) => entry !== REMOVE_NORMALIZED_VALUE);
|
|
11336
|
+
}
|
|
11337
|
+
if (!value || typeof value !== "object") {
|
|
11338
|
+
return value;
|
|
11339
|
+
}
|
|
11340
|
+
const nextInProviderMetadata = context.inProviderMetadata || context.parentKey === "providerMetadata" || context.parentKey === "experimental_providerMetadata";
|
|
11341
|
+
const normalizedEntries = [];
|
|
11342
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
11343
|
+
if (key === "cachedPromptTokens" && entry === 0) {
|
|
11344
|
+
continue;
|
|
11345
|
+
}
|
|
11346
|
+
if (context.parentKey === "request" && key === "body" && entry === "<omitted>") {
|
|
11347
|
+
continue;
|
|
11348
|
+
}
|
|
11349
|
+
const normalizedEntry = normalizeAISDKLoggedValue(entry, {
|
|
11350
|
+
inProviderMetadata: nextInProviderMetadata,
|
|
11351
|
+
parentKey: key
|
|
11352
|
+
});
|
|
11353
|
+
if (normalizedEntry === REMOVE_NORMALIZED_VALUE) {
|
|
11354
|
+
continue;
|
|
11355
|
+
}
|
|
11356
|
+
normalizedEntries.push([key, normalizedEntry]);
|
|
11357
|
+
}
|
|
11358
|
+
if (normalizedEntries.length === 0) {
|
|
11359
|
+
if (context.parentKey === "request" || nextInProviderMetadata) {
|
|
11360
|
+
return REMOVE_NORMALIZED_VALUE;
|
|
11361
|
+
}
|
|
11362
|
+
return {};
|
|
11363
|
+
}
|
|
11364
|
+
return Object.fromEntries(normalizedEntries);
|
|
11365
|
+
}
|
|
11366
|
+
|
|
11367
|
+
// src/zod/utils.ts
|
|
11368
|
+
var import_zod_to_json_schema = require("zod-to-json-schema");
|
|
11369
|
+
var z42 = __toESM(require("zod/v4"));
|
|
11370
|
+
function isZodV4(zodObject) {
|
|
11371
|
+
return typeof zodObject === "object" && zodObject !== null && "_zod" in zodObject && zodObject._zod !== void 0;
|
|
11372
|
+
}
|
|
11373
|
+
function zodToJsonSchema(schema) {
|
|
11374
|
+
if (isZodV4(schema)) {
|
|
11375
|
+
return z42.toJSONSchema(schema, {
|
|
11376
|
+
target: "draft-7"
|
|
11377
|
+
});
|
|
11378
|
+
}
|
|
11379
|
+
return (0, import_zod_to_json_schema.zodToJsonSchema)(schema);
|
|
11380
|
+
}
|
|
11381
|
+
|
|
11382
|
+
// src/wrappers/ai-sdk/tool-serialization.ts
|
|
11383
|
+
function isZodSchema(value) {
|
|
11384
|
+
return value != null && typeof value === "object" && "_def" in value && typeof value._def === "object";
|
|
11385
|
+
}
|
|
11386
|
+
function serializeZodSchema(schema) {
|
|
11387
|
+
try {
|
|
11388
|
+
return zodToJsonSchema(schema);
|
|
11389
|
+
} catch {
|
|
11390
|
+
return {
|
|
11391
|
+
type: "object",
|
|
11392
|
+
description: "Zod schema (conversion failed)"
|
|
11393
|
+
};
|
|
11394
|
+
}
|
|
11395
|
+
}
|
|
11396
|
+
function serializeTool(tool) {
|
|
11397
|
+
if (!tool || typeof tool !== "object") {
|
|
11398
|
+
return tool;
|
|
11399
|
+
}
|
|
11400
|
+
const serialized = { ...tool };
|
|
11401
|
+
if (isZodSchema(serialized.inputSchema)) {
|
|
11402
|
+
serialized.inputSchema = serializeZodSchema(serialized.inputSchema);
|
|
11403
|
+
}
|
|
11404
|
+
if (isZodSchema(serialized.parameters)) {
|
|
11405
|
+
serialized.parameters = serializeZodSchema(serialized.parameters);
|
|
11406
|
+
}
|
|
11407
|
+
if ("execute" in serialized) {
|
|
11408
|
+
delete serialized.execute;
|
|
11409
|
+
}
|
|
11410
|
+
if ("render" in serialized) {
|
|
11411
|
+
delete serialized.render;
|
|
11412
|
+
}
|
|
11413
|
+
return serialized;
|
|
11414
|
+
}
|
|
11415
|
+
function serializeAISDKToolsForLogging(tools) {
|
|
11416
|
+
if (!tools || typeof tools !== "object") {
|
|
11417
|
+
return tools;
|
|
11418
|
+
}
|
|
11419
|
+
if (Array.isArray(tools)) {
|
|
11420
|
+
return tools.map(serializeTool);
|
|
11421
|
+
}
|
|
11422
|
+
const serialized = {};
|
|
11423
|
+
for (const [key, tool] of Object.entries(tools)) {
|
|
11424
|
+
serialized[key] = serializeTool(tool);
|
|
11425
|
+
}
|
|
11426
|
+
return serialized;
|
|
11427
|
+
}
|
|
11428
|
+
|
|
11136
11429
|
// src/instrumentation/plugins/ai-sdk-channels.ts
|
|
11137
11430
|
var aiSDKChannels = defineChannels("ai", {
|
|
11138
11431
|
generateText: channel({
|
|
@@ -11143,6 +11436,10 @@ var aiSDKChannels = defineChannels("ai", {
|
|
|
11143
11436
|
channelName: "streamText",
|
|
11144
11437
|
kind: "async"
|
|
11145
11438
|
}),
|
|
11439
|
+
streamTextSync: channel({
|
|
11440
|
+
channelName: "streamText.sync",
|
|
11441
|
+
kind: "sync-stream"
|
|
11442
|
+
}),
|
|
11146
11443
|
generateObject: channel({
|
|
11147
11444
|
channelName: "generateObject",
|
|
11148
11445
|
kind: "async"
|
|
@@ -11151,6 +11448,10 @@ var aiSDKChannels = defineChannels("ai", {
|
|
|
11151
11448
|
channelName: "streamObject",
|
|
11152
11449
|
kind: "async"
|
|
11153
11450
|
}),
|
|
11451
|
+
streamObjectSync: channel({
|
|
11452
|
+
channelName: "streamObject.sync",
|
|
11453
|
+
kind: "sync-stream"
|
|
11454
|
+
}),
|
|
11154
11455
|
agentGenerate: channel({
|
|
11155
11456
|
channelName: "Agent.generate",
|
|
11156
11457
|
kind: "async"
|
|
@@ -11158,6 +11459,14 @@ var aiSDKChannels = defineChannels("ai", {
|
|
|
11158
11459
|
agentStream: channel({
|
|
11159
11460
|
channelName: "Agent.stream",
|
|
11160
11461
|
kind: "async"
|
|
11462
|
+
}),
|
|
11463
|
+
toolLoopAgentGenerate: channel({
|
|
11464
|
+
channelName: "ToolLoopAgent.generate",
|
|
11465
|
+
kind: "async"
|
|
11466
|
+
}),
|
|
11467
|
+
toolLoopAgentStream: channel({
|
|
11468
|
+
channelName: "ToolLoopAgent.stream",
|
|
11469
|
+
kind: "async"
|
|
11161
11470
|
})
|
|
11162
11471
|
});
|
|
11163
11472
|
|
|
@@ -11176,6 +11485,8 @@ var DEFAULT_DENY_OUTPUT_PATHS = [
|
|
|
11176
11485
|
"steps[].response.body",
|
|
11177
11486
|
"steps[].response.headers"
|
|
11178
11487
|
];
|
|
11488
|
+
var AUTO_PATCHED_MODEL = Symbol.for("braintrust.ai-sdk.auto-patched-model");
|
|
11489
|
+
var AUTO_PATCHED_TOOL = Symbol.for("braintrust.ai-sdk.auto-patched-tool");
|
|
11179
11490
|
var AISDKPlugin = class extends BasePlugin {
|
|
11180
11491
|
config;
|
|
11181
11492
|
constructor(config = {}) {
|
|
@@ -11194,22 +11505,12 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
11194
11505
|
traceStreamingChannel(aiSDKChannels.generateText, {
|
|
11195
11506
|
name: "generateText",
|
|
11196
11507
|
type: "llm" /* LLM */,
|
|
11197
|
-
extractInput: ([params]) =>
|
|
11198
|
-
|
|
11199
|
-
|
|
11200
|
-
metadata: extractMetadataFromParams(params)
|
|
11201
|
-
};
|
|
11202
|
-
},
|
|
11203
|
-
extractOutput: (result) => {
|
|
11508
|
+
extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
|
|
11509
|
+
extractOutput: (result, endEvent) => {
|
|
11510
|
+
finalizeAISDKChildTracing(endEvent);
|
|
11204
11511
|
return processAISDKOutput(result, denyOutputPaths);
|
|
11205
11512
|
},
|
|
11206
|
-
extractMetrics: (result,
|
|
11207
|
-
const metrics = extractTokenMetrics(result);
|
|
11208
|
-
if (startTime) {
|
|
11209
|
-
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
11210
|
-
}
|
|
11211
|
-
return metrics;
|
|
11212
|
-
},
|
|
11513
|
+
extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
|
|
11213
11514
|
aggregateChunks: aggregateAISDKChunks
|
|
11214
11515
|
})
|
|
11215
11516
|
);
|
|
@@ -11217,45 +11518,43 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
11217
11518
|
traceStreamingChannel(aiSDKChannels.streamText, {
|
|
11218
11519
|
name: "streamText",
|
|
11219
11520
|
type: "llm" /* LLM */,
|
|
11220
|
-
extractInput: ([params]) =>
|
|
11221
|
-
|
|
11222
|
-
|
|
11223
|
-
|
|
11224
|
-
|
|
11225
|
-
|
|
11226
|
-
|
|
11227
|
-
|
|
11228
|
-
|
|
11229
|
-
|
|
11230
|
-
|
|
11231
|
-
|
|
11232
|
-
|
|
11233
|
-
|
|
11234
|
-
|
|
11235
|
-
|
|
11236
|
-
|
|
11521
|
+
extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
|
|
11522
|
+
extractOutput: (result) => processAISDKOutput(result, denyOutputPaths),
|
|
11523
|
+
extractMetrics: (result, startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent, startTime),
|
|
11524
|
+
aggregateChunks: aggregateAISDKChunks,
|
|
11525
|
+
patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
|
|
11526
|
+
denyOutputPaths,
|
|
11527
|
+
endEvent,
|
|
11528
|
+
result,
|
|
11529
|
+
span,
|
|
11530
|
+
startTime
|
|
11531
|
+
})
|
|
11532
|
+
})
|
|
11533
|
+
);
|
|
11534
|
+
this.unsubscribers.push(
|
|
11535
|
+
traceSyncStreamChannel(aiSDKChannels.streamTextSync, {
|
|
11536
|
+
name: "streamText",
|
|
11537
|
+
type: "llm" /* LLM */,
|
|
11538
|
+
extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
|
|
11539
|
+
patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
|
|
11540
|
+
denyOutputPaths,
|
|
11541
|
+
endEvent,
|
|
11542
|
+
result,
|
|
11543
|
+
span,
|
|
11544
|
+
startTime
|
|
11545
|
+
})
|
|
11237
11546
|
})
|
|
11238
11547
|
);
|
|
11239
11548
|
this.unsubscribers.push(
|
|
11240
11549
|
traceStreamingChannel(aiSDKChannels.generateObject, {
|
|
11241
11550
|
name: "generateObject",
|
|
11242
11551
|
type: "llm" /* LLM */,
|
|
11243
|
-
extractInput: ([params]) =>
|
|
11244
|
-
|
|
11245
|
-
|
|
11246
|
-
metadata: extractMetadataFromParams(params)
|
|
11247
|
-
};
|
|
11248
|
-
},
|
|
11249
|
-
extractOutput: (result) => {
|
|
11552
|
+
extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
|
|
11553
|
+
extractOutput: (result, endEvent) => {
|
|
11554
|
+
finalizeAISDKChildTracing(endEvent);
|
|
11250
11555
|
return processAISDKOutput(result, denyOutputPaths);
|
|
11251
11556
|
},
|
|
11252
|
-
extractMetrics: (result,
|
|
11253
|
-
const metrics = extractTokenMetrics(result);
|
|
11254
|
-
if (startTime) {
|
|
11255
|
-
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
11256
|
-
}
|
|
11257
|
-
return metrics;
|
|
11258
|
-
},
|
|
11557
|
+
extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
|
|
11259
11558
|
aggregateChunks: aggregateAISDKChunks
|
|
11260
11559
|
})
|
|
11261
11560
|
);
|
|
@@ -11263,45 +11562,43 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
11263
11562
|
traceStreamingChannel(aiSDKChannels.streamObject, {
|
|
11264
11563
|
name: "streamObject",
|
|
11265
11564
|
type: "llm" /* LLM */,
|
|
11266
|
-
extractInput: ([params]) =>
|
|
11267
|
-
|
|
11268
|
-
|
|
11269
|
-
|
|
11270
|
-
|
|
11271
|
-
|
|
11272
|
-
|
|
11273
|
-
|
|
11274
|
-
|
|
11275
|
-
|
|
11276
|
-
|
|
11277
|
-
|
|
11278
|
-
|
|
11279
|
-
|
|
11280
|
-
|
|
11281
|
-
|
|
11282
|
-
|
|
11565
|
+
extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
|
|
11566
|
+
extractOutput: (result) => processAISDKOutput(result, denyOutputPaths),
|
|
11567
|
+
extractMetrics: (result, startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent, startTime),
|
|
11568
|
+
aggregateChunks: aggregateAISDKChunks,
|
|
11569
|
+
patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
|
|
11570
|
+
denyOutputPaths,
|
|
11571
|
+
endEvent,
|
|
11572
|
+
result,
|
|
11573
|
+
span,
|
|
11574
|
+
startTime
|
|
11575
|
+
})
|
|
11576
|
+
})
|
|
11577
|
+
);
|
|
11578
|
+
this.unsubscribers.push(
|
|
11579
|
+
traceSyncStreamChannel(aiSDKChannels.streamObjectSync, {
|
|
11580
|
+
name: "streamObject",
|
|
11581
|
+
type: "llm" /* LLM */,
|
|
11582
|
+
extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
|
|
11583
|
+
patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
|
|
11584
|
+
denyOutputPaths,
|
|
11585
|
+
endEvent,
|
|
11586
|
+
result,
|
|
11587
|
+
span,
|
|
11588
|
+
startTime
|
|
11589
|
+
})
|
|
11283
11590
|
})
|
|
11284
11591
|
);
|
|
11285
11592
|
this.unsubscribers.push(
|
|
11286
11593
|
traceStreamingChannel(aiSDKChannels.agentGenerate, {
|
|
11287
11594
|
name: "Agent.generate",
|
|
11288
11595
|
type: "llm" /* LLM */,
|
|
11289
|
-
extractInput: ([params]) =>
|
|
11290
|
-
|
|
11291
|
-
|
|
11292
|
-
metadata: extractMetadataFromParams(params)
|
|
11293
|
-
};
|
|
11294
|
-
},
|
|
11295
|
-
extractOutput: (result) => {
|
|
11596
|
+
extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
|
|
11597
|
+
extractOutput: (result, endEvent) => {
|
|
11598
|
+
finalizeAISDKChildTracing(endEvent);
|
|
11296
11599
|
return processAISDKOutput(result, denyOutputPaths);
|
|
11297
11600
|
},
|
|
11298
|
-
extractMetrics: (result,
|
|
11299
|
-
const metrics = extractTokenMetrics(result);
|
|
11300
|
-
if (startTime) {
|
|
11301
|
-
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
11302
|
-
}
|
|
11303
|
-
return metrics;
|
|
11304
|
-
},
|
|
11601
|
+
extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
|
|
11305
11602
|
aggregateChunks: aggregateAISDKChunks
|
|
11306
11603
|
})
|
|
11307
11604
|
);
|
|
@@ -11309,52 +11606,470 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
11309
11606
|
traceStreamingChannel(aiSDKChannels.agentStream, {
|
|
11310
11607
|
name: "Agent.stream",
|
|
11311
11608
|
type: "llm" /* LLM */,
|
|
11312
|
-
extractInput: ([params]) =>
|
|
11313
|
-
|
|
11314
|
-
|
|
11315
|
-
|
|
11316
|
-
|
|
11317
|
-
|
|
11318
|
-
|
|
11319
|
-
|
|
11320
|
-
|
|
11321
|
-
|
|
11322
|
-
|
|
11323
|
-
|
|
11324
|
-
|
|
11325
|
-
|
|
11326
|
-
|
|
11609
|
+
extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
|
|
11610
|
+
extractOutput: (result) => processAISDKOutput(result, denyOutputPaths),
|
|
11611
|
+
extractMetrics: (result, startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent, startTime),
|
|
11612
|
+
aggregateChunks: aggregateAISDKChunks,
|
|
11613
|
+
patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
|
|
11614
|
+
denyOutputPaths,
|
|
11615
|
+
endEvent,
|
|
11616
|
+
result,
|
|
11617
|
+
span,
|
|
11618
|
+
startTime
|
|
11619
|
+
})
|
|
11620
|
+
})
|
|
11621
|
+
);
|
|
11622
|
+
this.unsubscribers.push(
|
|
11623
|
+
traceStreamingChannel(aiSDKChannels.toolLoopAgentGenerate, {
|
|
11624
|
+
name: "ToolLoopAgent.generate",
|
|
11625
|
+
type: "llm" /* LLM */,
|
|
11626
|
+
extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
|
|
11627
|
+
extractOutput: (result, endEvent) => {
|
|
11628
|
+
finalizeAISDKChildTracing(endEvent);
|
|
11629
|
+
return processAISDKOutput(result, denyOutputPaths);
|
|
11327
11630
|
},
|
|
11631
|
+
extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
|
|
11328
11632
|
aggregateChunks: aggregateAISDKChunks
|
|
11329
11633
|
})
|
|
11330
11634
|
);
|
|
11635
|
+
this.unsubscribers.push(
|
|
11636
|
+
traceStreamingChannel(aiSDKChannels.toolLoopAgentStream, {
|
|
11637
|
+
name: "ToolLoopAgent.stream",
|
|
11638
|
+
type: "llm" /* LLM */,
|
|
11639
|
+
extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
|
|
11640
|
+
extractOutput: (result) => processAISDKOutput(result, denyOutputPaths),
|
|
11641
|
+
extractMetrics: (result, startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent, startTime),
|
|
11642
|
+
aggregateChunks: aggregateAISDKChunks,
|
|
11643
|
+
patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
|
|
11644
|
+
denyOutputPaths,
|
|
11645
|
+
endEvent,
|
|
11646
|
+
result,
|
|
11647
|
+
span,
|
|
11648
|
+
startTime
|
|
11649
|
+
})
|
|
11650
|
+
})
|
|
11651
|
+
);
|
|
11331
11652
|
}
|
|
11332
11653
|
};
|
|
11333
11654
|
function processAISDKInput(params) {
|
|
11334
11655
|
if (!params) return params;
|
|
11335
|
-
|
|
11656
|
+
const input = processInputAttachments(params);
|
|
11657
|
+
if (!input || typeof input !== "object" || Array.isArray(input)) {
|
|
11658
|
+
return input;
|
|
11659
|
+
}
|
|
11660
|
+
const { tools: _tools, ...rest } = input;
|
|
11661
|
+
return rest;
|
|
11662
|
+
}
|
|
11663
|
+
function prepareAISDKInput(params, event, span, denyOutputPaths) {
|
|
11664
|
+
const input = processAISDKInput(params);
|
|
11665
|
+
const metadata = extractMetadataFromParams(params, event.self);
|
|
11666
|
+
const childTracing = prepareAISDKChildTracing(
|
|
11667
|
+
params,
|
|
11668
|
+
event.self,
|
|
11669
|
+
span,
|
|
11670
|
+
denyOutputPaths
|
|
11671
|
+
);
|
|
11672
|
+
event.__braintrust_ai_sdk_model_wrapped = childTracing.modelWrapped;
|
|
11673
|
+
if (childTracing.cleanup) {
|
|
11674
|
+
event.__braintrust_ai_sdk_cleanup = childTracing.cleanup;
|
|
11675
|
+
}
|
|
11676
|
+
return {
|
|
11677
|
+
input,
|
|
11678
|
+
metadata
|
|
11679
|
+
};
|
|
11680
|
+
}
|
|
11681
|
+
function extractTopLevelAISDKMetrics(result, event, startTime) {
|
|
11682
|
+
const metrics = hasModelChildTracing(event) ? {} : extractTokenMetrics(result);
|
|
11683
|
+
if (startTime) {
|
|
11684
|
+
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
11685
|
+
}
|
|
11686
|
+
return metrics;
|
|
11336
11687
|
}
|
|
11337
|
-
function
|
|
11688
|
+
function hasModelChildTracing(event) {
|
|
11689
|
+
return event?.__braintrust_ai_sdk_model_wrapped === true;
|
|
11690
|
+
}
|
|
11691
|
+
function extractMetadataFromParams(params, self) {
|
|
11338
11692
|
const metadata = {
|
|
11339
11693
|
braintrust: {
|
|
11340
11694
|
integration_name: "ai-sdk",
|
|
11341
11695
|
sdk_language: "typescript"
|
|
11342
11696
|
}
|
|
11343
11697
|
};
|
|
11344
|
-
const
|
|
11698
|
+
const agentModel = self && typeof self === "object" && "model" in self && self.model ? self.model : self && typeof self === "object" && "settings" in self && self.settings?.model ? self.settings?.model : void 0;
|
|
11699
|
+
const { model, provider } = serializeModelWithProvider(
|
|
11700
|
+
params.model ?? agentModel
|
|
11701
|
+
);
|
|
11345
11702
|
if (model) {
|
|
11346
11703
|
metadata.model = model;
|
|
11347
11704
|
}
|
|
11348
11705
|
if (provider) {
|
|
11349
11706
|
metadata.provider = provider;
|
|
11350
11707
|
}
|
|
11708
|
+
const tools = serializeAISDKToolsForLogging(params.tools);
|
|
11709
|
+
if (tools) {
|
|
11710
|
+
metadata.tools = tools;
|
|
11711
|
+
}
|
|
11351
11712
|
return metadata;
|
|
11352
11713
|
}
|
|
11714
|
+
function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths) {
|
|
11715
|
+
const cleanup = [];
|
|
11716
|
+
const patchedModels = /* @__PURE__ */ new WeakSet();
|
|
11717
|
+
const patchedTools = /* @__PURE__ */ new WeakSet();
|
|
11718
|
+
let modelWrapped = false;
|
|
11719
|
+
const patchModel = (model) => {
|
|
11720
|
+
const resolvedModel = resolveAISDKModel(model);
|
|
11721
|
+
if (!resolvedModel || typeof resolvedModel !== "object" || typeof resolvedModel.doGenerate !== "function" || patchedModels.has(resolvedModel) || resolvedModel[AUTO_PATCHED_MODEL]) {
|
|
11722
|
+
return;
|
|
11723
|
+
}
|
|
11724
|
+
patchedModels.add(resolvedModel);
|
|
11725
|
+
resolvedModel[AUTO_PATCHED_MODEL] = true;
|
|
11726
|
+
modelWrapped = true;
|
|
11727
|
+
const originalDoGenerate = resolvedModel.doGenerate;
|
|
11728
|
+
const originalDoStream = resolvedModel.doStream;
|
|
11729
|
+
const baseMetadata = buildAISDKChildMetadata(resolvedModel);
|
|
11730
|
+
resolvedModel.doGenerate = async function doGeneratePatched(options) {
|
|
11731
|
+
return parentSpan.traced(
|
|
11732
|
+
async (span) => {
|
|
11733
|
+
const result = await Reflect.apply(
|
|
11734
|
+
originalDoGenerate,
|
|
11735
|
+
resolvedModel,
|
|
11736
|
+
[options]
|
|
11737
|
+
);
|
|
11738
|
+
span.log({
|
|
11739
|
+
output: processAISDKOutput(result, denyOutputPaths),
|
|
11740
|
+
metrics: extractTokenMetrics(result),
|
|
11741
|
+
...buildResolvedMetadataPayload(result)
|
|
11742
|
+
});
|
|
11743
|
+
return result;
|
|
11744
|
+
},
|
|
11745
|
+
{
|
|
11746
|
+
name: "doGenerate",
|
|
11747
|
+
spanAttributes: {
|
|
11748
|
+
type: "llm" /* LLM */
|
|
11749
|
+
},
|
|
11750
|
+
event: {
|
|
11751
|
+
input: processAISDKInput(options),
|
|
11752
|
+
metadata: baseMetadata
|
|
11753
|
+
}
|
|
11754
|
+
}
|
|
11755
|
+
);
|
|
11756
|
+
};
|
|
11757
|
+
if (originalDoStream) {
|
|
11758
|
+
resolvedModel.doStream = async function doStreamPatched(options) {
|
|
11759
|
+
const span = parentSpan.startSpan({
|
|
11760
|
+
name: "doStream",
|
|
11761
|
+
spanAttributes: {
|
|
11762
|
+
type: "llm" /* LLM */
|
|
11763
|
+
},
|
|
11764
|
+
event: {
|
|
11765
|
+
input: processAISDKInput(options),
|
|
11766
|
+
metadata: baseMetadata
|
|
11767
|
+
}
|
|
11768
|
+
});
|
|
11769
|
+
const result = await withCurrent(
|
|
11770
|
+
span,
|
|
11771
|
+
() => Reflect.apply(originalDoStream, resolvedModel, [options])
|
|
11772
|
+
);
|
|
11773
|
+
const output = {};
|
|
11774
|
+
let text = "";
|
|
11775
|
+
let reasoning = "";
|
|
11776
|
+
const toolCalls = [];
|
|
11777
|
+
let object = void 0;
|
|
11778
|
+
const transformStream = new TransformStream({
|
|
11779
|
+
transform(chunk, controller) {
|
|
11780
|
+
switch (chunk.type) {
|
|
11781
|
+
case "text-delta":
|
|
11782
|
+
text += extractTextDelta(chunk);
|
|
11783
|
+
break;
|
|
11784
|
+
case "reasoning-delta":
|
|
11785
|
+
if (chunk.delta) {
|
|
11786
|
+
reasoning += chunk.delta;
|
|
11787
|
+
} else if (chunk.text) {
|
|
11788
|
+
reasoning += chunk.text;
|
|
11789
|
+
}
|
|
11790
|
+
break;
|
|
11791
|
+
case "tool-call":
|
|
11792
|
+
toolCalls.push(chunk);
|
|
11793
|
+
break;
|
|
11794
|
+
case "object":
|
|
11795
|
+
object = chunk.object;
|
|
11796
|
+
break;
|
|
11797
|
+
case "raw":
|
|
11798
|
+
if (chunk.rawValue) {
|
|
11799
|
+
const rawVal = chunk.rawValue;
|
|
11800
|
+
if (rawVal.delta?.content) {
|
|
11801
|
+
text += rawVal.delta.content;
|
|
11802
|
+
} else if (rawVal.choices?.[0]?.delta?.content) {
|
|
11803
|
+
text += rawVal.choices[0].delta.content;
|
|
11804
|
+
} else if (typeof rawVal.text === "string") {
|
|
11805
|
+
text += rawVal.text;
|
|
11806
|
+
} else if (typeof rawVal.content === "string") {
|
|
11807
|
+
text += rawVal.content;
|
|
11808
|
+
}
|
|
11809
|
+
}
|
|
11810
|
+
break;
|
|
11811
|
+
case "finish":
|
|
11812
|
+
output.text = text;
|
|
11813
|
+
output.reasoning = reasoning;
|
|
11814
|
+
output.toolCalls = toolCalls;
|
|
11815
|
+
output.finishReason = chunk.finishReason;
|
|
11816
|
+
output.usage = chunk.usage;
|
|
11817
|
+
if (object !== void 0) {
|
|
11818
|
+
output.object = object;
|
|
11819
|
+
}
|
|
11820
|
+
span.log({
|
|
11821
|
+
output: processAISDKOutput(
|
|
11822
|
+
output,
|
|
11823
|
+
denyOutputPaths
|
|
11824
|
+
),
|
|
11825
|
+
metrics: extractTokenMetrics(output),
|
|
11826
|
+
...buildResolvedMetadataPayload(output)
|
|
11827
|
+
});
|
|
11828
|
+
span.end();
|
|
11829
|
+
break;
|
|
11830
|
+
}
|
|
11831
|
+
controller.enqueue(chunk);
|
|
11832
|
+
}
|
|
11833
|
+
});
|
|
11834
|
+
return {
|
|
11835
|
+
...result,
|
|
11836
|
+
stream: result.stream.pipeThrough(transformStream)
|
|
11837
|
+
};
|
|
11838
|
+
};
|
|
11839
|
+
}
|
|
11840
|
+
cleanup.push(() => {
|
|
11841
|
+
resolvedModel.doGenerate = originalDoGenerate;
|
|
11842
|
+
if (originalDoStream) {
|
|
11843
|
+
resolvedModel.doStream = originalDoStream;
|
|
11844
|
+
}
|
|
11845
|
+
delete resolvedModel[AUTO_PATCHED_MODEL];
|
|
11846
|
+
});
|
|
11847
|
+
};
|
|
11848
|
+
const patchTool = (tool, name) => {
|
|
11849
|
+
if (tool == null || typeof tool !== "object" || !("execute" in tool) || typeof tool.execute !== "function" || patchedTools.has(tool) || tool[AUTO_PATCHED_TOOL]) {
|
|
11850
|
+
return;
|
|
11851
|
+
}
|
|
11852
|
+
patchedTools.add(tool);
|
|
11853
|
+
tool[AUTO_PATCHED_TOOL] = true;
|
|
11854
|
+
const originalExecute = tool.execute;
|
|
11855
|
+
tool.execute = function executePatched(...args) {
|
|
11856
|
+
const result = Reflect.apply(originalExecute, this, args);
|
|
11857
|
+
if (isAsyncGenerator(result)) {
|
|
11858
|
+
return (async function* () {
|
|
11859
|
+
const span = parentSpan.startSpan({
|
|
11860
|
+
name,
|
|
11861
|
+
spanAttributes: {
|
|
11862
|
+
type: "tool" /* TOOL */
|
|
11863
|
+
}
|
|
11864
|
+
});
|
|
11865
|
+
span.log({ input: args.length === 1 ? args[0] : args });
|
|
11866
|
+
try {
|
|
11867
|
+
let lastValue;
|
|
11868
|
+
for await (const value of result) {
|
|
11869
|
+
lastValue = value;
|
|
11870
|
+
yield value;
|
|
11871
|
+
}
|
|
11872
|
+
span.log({ output: lastValue });
|
|
11873
|
+
} catch (error) {
|
|
11874
|
+
span.log({
|
|
11875
|
+
error: error instanceof Error ? error.message : String(error)
|
|
11876
|
+
});
|
|
11877
|
+
throw error;
|
|
11878
|
+
} finally {
|
|
11879
|
+
span.end();
|
|
11880
|
+
}
|
|
11881
|
+
})();
|
|
11882
|
+
}
|
|
11883
|
+
return parentSpan.traced(
|
|
11884
|
+
async (span) => {
|
|
11885
|
+
span.log({ input: args.length === 1 ? args[0] : args });
|
|
11886
|
+
const awaitedResult = await result;
|
|
11887
|
+
span.log({ output: awaitedResult });
|
|
11888
|
+
return awaitedResult;
|
|
11889
|
+
},
|
|
11890
|
+
{
|
|
11891
|
+
name,
|
|
11892
|
+
spanAttributes: {
|
|
11893
|
+
type: "tool" /* TOOL */
|
|
11894
|
+
}
|
|
11895
|
+
}
|
|
11896
|
+
);
|
|
11897
|
+
};
|
|
11898
|
+
cleanup.push(() => {
|
|
11899
|
+
tool.execute = originalExecute;
|
|
11900
|
+
delete tool[AUTO_PATCHED_TOOL];
|
|
11901
|
+
});
|
|
11902
|
+
};
|
|
11903
|
+
const patchTools = (tools) => {
|
|
11904
|
+
if (!tools) {
|
|
11905
|
+
return;
|
|
11906
|
+
}
|
|
11907
|
+
const inferName = (tool, fallback2) => tool && (tool.name || tool.toolName || tool.id) || fallback2;
|
|
11908
|
+
if (Array.isArray(tools)) {
|
|
11909
|
+
tools.forEach(
|
|
11910
|
+
(tool, index) => patchTool(tool, inferName(tool, `tool[${index}]`))
|
|
11911
|
+
);
|
|
11912
|
+
return;
|
|
11913
|
+
}
|
|
11914
|
+
for (const [key, tool] of Object.entries(tools)) {
|
|
11915
|
+
patchTool(tool, key);
|
|
11916
|
+
}
|
|
11917
|
+
};
|
|
11918
|
+
if (params && typeof params === "object") {
|
|
11919
|
+
patchModel(params.model);
|
|
11920
|
+
patchTools(params.tools);
|
|
11921
|
+
}
|
|
11922
|
+
if (self && typeof self === "object") {
|
|
11923
|
+
const selfRecord = self;
|
|
11924
|
+
if (selfRecord.model !== void 0) {
|
|
11925
|
+
patchModel(selfRecord.model);
|
|
11926
|
+
}
|
|
11927
|
+
if (selfRecord.settings && typeof selfRecord.settings === "object") {
|
|
11928
|
+
if (selfRecord.settings.model !== void 0) {
|
|
11929
|
+
patchModel(selfRecord.settings.model);
|
|
11930
|
+
}
|
|
11931
|
+
if (selfRecord.settings.tools !== void 0) {
|
|
11932
|
+
patchTools(selfRecord.settings.tools);
|
|
11933
|
+
}
|
|
11934
|
+
}
|
|
11935
|
+
}
|
|
11936
|
+
return {
|
|
11937
|
+
cleanup: cleanup.length > 0 ? () => {
|
|
11938
|
+
while (cleanup.length > 0) {
|
|
11939
|
+
cleanup.pop()?.();
|
|
11940
|
+
}
|
|
11941
|
+
} : void 0,
|
|
11942
|
+
modelWrapped
|
|
11943
|
+
};
|
|
11944
|
+
}
|
|
11945
|
+
function finalizeAISDKChildTracing(event) {
|
|
11946
|
+
const cleanup = event?.__braintrust_ai_sdk_cleanup;
|
|
11947
|
+
if (event && typeof cleanup === "function") {
|
|
11948
|
+
cleanup();
|
|
11949
|
+
delete event.__braintrust_ai_sdk_cleanup;
|
|
11950
|
+
}
|
|
11951
|
+
}
|
|
11952
|
+
function patchAISDKStreamingResult(args) {
|
|
11953
|
+
const { denyOutputPaths, endEvent, result, span, startTime } = args;
|
|
11954
|
+
if (!result || typeof result !== "object") {
|
|
11955
|
+
return false;
|
|
11956
|
+
}
|
|
11957
|
+
const resultRecord = result;
|
|
11958
|
+
if (!isReadableStreamLike(resultRecord.baseStream)) {
|
|
11959
|
+
return false;
|
|
11960
|
+
}
|
|
11961
|
+
let firstChunkTime;
|
|
11962
|
+
const wrappedBaseStream = resultRecord.baseStream.pipeThrough(
|
|
11963
|
+
new TransformStream({
|
|
11964
|
+
transform(chunk, controller) {
|
|
11965
|
+
if (firstChunkTime === void 0) {
|
|
11966
|
+
firstChunkTime = getCurrentUnixTimestamp();
|
|
11967
|
+
}
|
|
11968
|
+
controller.enqueue(chunk);
|
|
11969
|
+
},
|
|
11970
|
+
async flush() {
|
|
11971
|
+
const metrics = extractTopLevelAISDKMetrics(result, endEvent);
|
|
11972
|
+
if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
|
|
11973
|
+
metrics.time_to_first_token = firstChunkTime - startTime;
|
|
11974
|
+
}
|
|
11975
|
+
const output = await processAISDKStreamingOutput(
|
|
11976
|
+
result,
|
|
11977
|
+
denyOutputPaths
|
|
11978
|
+
);
|
|
11979
|
+
const metadata = buildResolvedMetadataPayload(result).metadata;
|
|
11980
|
+
span.log({
|
|
11981
|
+
output,
|
|
11982
|
+
...metadata ? { metadata } : {},
|
|
11983
|
+
metrics
|
|
11984
|
+
});
|
|
11985
|
+
finalizeAISDKChildTracing(endEvent);
|
|
11986
|
+
span.end();
|
|
11987
|
+
}
|
|
11988
|
+
})
|
|
11989
|
+
);
|
|
11990
|
+
Object.defineProperty(resultRecord, "baseStream", {
|
|
11991
|
+
configurable: true,
|
|
11992
|
+
enumerable: true,
|
|
11993
|
+
value: wrappedBaseStream,
|
|
11994
|
+
writable: true
|
|
11995
|
+
});
|
|
11996
|
+
return true;
|
|
11997
|
+
}
|
|
11998
|
+
function isReadableStreamLike(value) {
|
|
11999
|
+
return value != null && typeof value === "object" && typeof value.pipeThrough === "function";
|
|
12000
|
+
}
|
|
12001
|
+
async function processAISDKStreamingOutput(result, denyOutputPaths) {
|
|
12002
|
+
const output = processAISDKOutput(result, denyOutputPaths);
|
|
12003
|
+
if (!output || typeof output !== "object") {
|
|
12004
|
+
return output;
|
|
12005
|
+
}
|
|
12006
|
+
const outputRecord = output;
|
|
12007
|
+
try {
|
|
12008
|
+
if ("text" in result && typeof result.text === "string") {
|
|
12009
|
+
outputRecord.text = result.text;
|
|
12010
|
+
}
|
|
12011
|
+
} catch {
|
|
12012
|
+
}
|
|
12013
|
+
try {
|
|
12014
|
+
if ("object" in result) {
|
|
12015
|
+
const resolvedObject = await Promise.resolve(result.object);
|
|
12016
|
+
if (resolvedObject !== void 0) {
|
|
12017
|
+
outputRecord.object = resolvedObject;
|
|
12018
|
+
}
|
|
12019
|
+
}
|
|
12020
|
+
} catch {
|
|
12021
|
+
}
|
|
12022
|
+
return outputRecord;
|
|
12023
|
+
}
|
|
12024
|
+
function buildAISDKChildMetadata(model) {
|
|
12025
|
+
const { model: modelId, provider } = serializeModelWithProvider(model);
|
|
12026
|
+
return {
|
|
12027
|
+
...modelId ? { model: modelId } : {},
|
|
12028
|
+
...provider ? { provider } : {},
|
|
12029
|
+
braintrust: {
|
|
12030
|
+
integration_name: "ai-sdk",
|
|
12031
|
+
sdk_language: "typescript"
|
|
12032
|
+
}
|
|
12033
|
+
};
|
|
12034
|
+
}
|
|
12035
|
+
function buildResolvedMetadataPayload(result) {
|
|
12036
|
+
const gatewayInfo = extractGatewayRoutingInfo(result);
|
|
12037
|
+
const metadata = {};
|
|
12038
|
+
if (gatewayInfo?.provider) {
|
|
12039
|
+
metadata.provider = gatewayInfo.provider;
|
|
12040
|
+
}
|
|
12041
|
+
if (gatewayInfo?.model) {
|
|
12042
|
+
metadata.model = gatewayInfo.model;
|
|
12043
|
+
}
|
|
12044
|
+
if (result.finishReason !== void 0) {
|
|
12045
|
+
metadata.finish_reason = result.finishReason;
|
|
12046
|
+
}
|
|
12047
|
+
return Object.keys(metadata).length > 0 ? { metadata } : {};
|
|
12048
|
+
}
|
|
12049
|
+
function resolveAISDKModel(model) {
|
|
12050
|
+
if (typeof model !== "string") {
|
|
12051
|
+
return model;
|
|
12052
|
+
}
|
|
12053
|
+
const provider = globalThis.AI_SDK_DEFAULT_PROVIDER ?? null;
|
|
12054
|
+
if (provider && typeof provider.languageModel === "function") {
|
|
12055
|
+
return provider.languageModel(model);
|
|
12056
|
+
}
|
|
12057
|
+
return model;
|
|
12058
|
+
}
|
|
12059
|
+
function extractTextDelta(chunk) {
|
|
12060
|
+
if (typeof chunk.textDelta === "string") return chunk.textDelta;
|
|
12061
|
+
if (typeof chunk.delta === "string") return chunk.delta;
|
|
12062
|
+
if (typeof chunk.text === "string") return chunk.text;
|
|
12063
|
+
if (typeof chunk.content === "string") return chunk.content;
|
|
12064
|
+
return "";
|
|
12065
|
+
}
|
|
12066
|
+
function isAsyncGenerator(value) {
|
|
12067
|
+
return value != null && typeof value === "object" && typeof value[Symbol.asyncIterator] === "function" && typeof value.next === "function" && typeof value.return === "function" && typeof value.throw === "function";
|
|
12068
|
+
}
|
|
11353
12069
|
function processAISDKOutput(output, denyOutputPaths) {
|
|
11354
12070
|
if (!output) return output;
|
|
11355
|
-
const
|
|
11356
|
-
|
|
11357
|
-
return omit(merged, denyOutputPaths);
|
|
12071
|
+
const merged = extractSerializableOutputFields(output);
|
|
12072
|
+
return normalizeAISDKLoggedOutput(omit(merged, denyOutputPaths));
|
|
11358
12073
|
}
|
|
11359
12074
|
function extractTokenMetrics(result) {
|
|
11360
12075
|
const metrics = {};
|
|
@@ -11404,12 +12119,14 @@ function extractTokenMetrics(result) {
|
|
|
11404
12119
|
}
|
|
11405
12120
|
return metrics;
|
|
11406
12121
|
}
|
|
11407
|
-
function aggregateAISDKChunks(chunks) {
|
|
12122
|
+
function aggregateAISDKChunks(chunks, _result, endEvent) {
|
|
11408
12123
|
const lastChunk = chunks[chunks.length - 1];
|
|
11409
12124
|
const output = {};
|
|
11410
12125
|
let metrics = {};
|
|
12126
|
+
let metadata;
|
|
11411
12127
|
if (lastChunk) {
|
|
11412
|
-
metrics = extractTokenMetrics(lastChunk);
|
|
12128
|
+
metrics = hasModelChildTracing(endEvent) ? {} : extractTokenMetrics(lastChunk);
|
|
12129
|
+
metadata = buildResolvedMetadataPayload(lastChunk).metadata;
|
|
11413
12130
|
if (lastChunk.text !== void 0) {
|
|
11414
12131
|
output.text = lastChunk.text;
|
|
11415
12132
|
}
|
|
@@ -11423,7 +12140,8 @@ function aggregateAISDKChunks(chunks) {
|
|
|
11423
12140
|
output.toolCalls = lastChunk.toolCalls;
|
|
11424
12141
|
}
|
|
11425
12142
|
}
|
|
11426
|
-
|
|
12143
|
+
finalizeAISDKChildTracing(endEvent);
|
|
12144
|
+
return { output, metrics, metadata };
|
|
11427
12145
|
}
|
|
11428
12146
|
function extractGetterValues(obj) {
|
|
11429
12147
|
const getterValues = {};
|
|
@@ -11443,7 +12161,7 @@ function extractGetterValues(obj) {
|
|
|
11443
12161
|
];
|
|
11444
12162
|
for (const name of getterNames) {
|
|
11445
12163
|
try {
|
|
11446
|
-
if (obj && name in obj &&
|
|
12164
|
+
if (obj && name in obj && isSerializableOutputValue(obj[name])) {
|
|
11447
12165
|
getterValues[name] = obj[name];
|
|
11448
12166
|
}
|
|
11449
12167
|
} catch {
|
|
@@ -11451,6 +12169,47 @@ function extractGetterValues(obj) {
|
|
|
11451
12169
|
}
|
|
11452
12170
|
return getterValues;
|
|
11453
12171
|
}
|
|
12172
|
+
function extractSerializableOutputFields(output) {
|
|
12173
|
+
const serialized = {};
|
|
12174
|
+
const directFieldNames = [
|
|
12175
|
+
"steps",
|
|
12176
|
+
"request",
|
|
12177
|
+
"responseMessages",
|
|
12178
|
+
"warnings",
|
|
12179
|
+
"rawResponse",
|
|
12180
|
+
"response",
|
|
12181
|
+
"providerMetadata",
|
|
12182
|
+
"experimental_providerMetadata"
|
|
12183
|
+
];
|
|
12184
|
+
for (const name of directFieldNames) {
|
|
12185
|
+
try {
|
|
12186
|
+
const value = output?.[name];
|
|
12187
|
+
if (isSerializableOutputValue(value)) {
|
|
12188
|
+
serialized[name] = value;
|
|
12189
|
+
}
|
|
12190
|
+
} catch {
|
|
12191
|
+
}
|
|
12192
|
+
}
|
|
12193
|
+
return {
|
|
12194
|
+
...serialized,
|
|
12195
|
+
...extractGetterValues(output)
|
|
12196
|
+
};
|
|
12197
|
+
}
|
|
12198
|
+
function isSerializableOutputValue(value) {
|
|
12199
|
+
if (typeof value === "function") {
|
|
12200
|
+
return false;
|
|
12201
|
+
}
|
|
12202
|
+
if (value && typeof value === "object" && typeof value.then === "function") {
|
|
12203
|
+
return false;
|
|
12204
|
+
}
|
|
12205
|
+
if (value && typeof value === "object" && typeof value.getReader === "function") {
|
|
12206
|
+
return false;
|
|
12207
|
+
}
|
|
12208
|
+
if (value && typeof value === "object" && typeof value[Symbol.asyncIterator] === "function") {
|
|
12209
|
+
return false;
|
|
12210
|
+
}
|
|
12211
|
+
return true;
|
|
12212
|
+
}
|
|
11454
12213
|
function serializeModelWithProvider(model) {
|
|
11455
12214
|
const modelId = typeof model === "string" ? model : model?.modelId;
|
|
11456
12215
|
const explicitProvider = typeof model === "object" ? model?.provider : void 0;
|
|
@@ -11476,6 +12235,25 @@ function parseGatewayModelString(modelString) {
|
|
|
11476
12235
|
}
|
|
11477
12236
|
return { model: modelString };
|
|
11478
12237
|
}
|
|
12238
|
+
function extractGatewayRoutingInfo(result) {
|
|
12239
|
+
if (result?.steps && Array.isArray(result.steps) && result.steps.length > 0) {
|
|
12240
|
+
const routing2 = result.steps[0]?.providerMetadata?.gateway?.routing;
|
|
12241
|
+
if (routing2) {
|
|
12242
|
+
return {
|
|
12243
|
+
provider: routing2.resolvedProvider || routing2.finalProvider,
|
|
12244
|
+
model: routing2.resolvedProviderApiModelId
|
|
12245
|
+
};
|
|
12246
|
+
}
|
|
12247
|
+
}
|
|
12248
|
+
const routing = result?.providerMetadata?.gateway?.routing;
|
|
12249
|
+
if (routing) {
|
|
12250
|
+
return {
|
|
12251
|
+
provider: routing.resolvedProvider || routing.finalProvider,
|
|
12252
|
+
model: routing.resolvedProviderApiModelId
|
|
12253
|
+
};
|
|
12254
|
+
}
|
|
12255
|
+
return null;
|
|
12256
|
+
}
|
|
11479
12257
|
function extractCostFromResult(result) {
|
|
11480
12258
|
if (result?.steps && Array.isArray(result.steps) && result.steps.length > 0) {
|
|
11481
12259
|
let totalCost = 0;
|
|
@@ -12153,57 +12931,1086 @@ function aggregateGenerateContentChunks(chunks, startTime) {
|
|
|
12153
12931
|
}
|
|
12154
12932
|
}
|
|
12155
12933
|
}
|
|
12156
|
-
}
|
|
12934
|
+
}
|
|
12935
|
+
}
|
|
12936
|
+
const output = {};
|
|
12937
|
+
const parts = [];
|
|
12938
|
+
if (thoughtText) {
|
|
12939
|
+
parts.push({ text: thoughtText, thought: true });
|
|
12940
|
+
}
|
|
12941
|
+
if (text) {
|
|
12942
|
+
parts.push({ text });
|
|
12943
|
+
}
|
|
12944
|
+
parts.push(...otherParts);
|
|
12945
|
+
if (parts.length > 0 && lastResponse?.candidates) {
|
|
12946
|
+
const candidates = [];
|
|
12947
|
+
for (const candidate of lastResponse.candidates) {
|
|
12948
|
+
const candidateDict = {
|
|
12949
|
+
content: {
|
|
12950
|
+
parts,
|
|
12951
|
+
role: "model"
|
|
12952
|
+
}
|
|
12953
|
+
};
|
|
12954
|
+
if (candidate.finishReason !== void 0) {
|
|
12955
|
+
candidateDict.finishReason = candidate.finishReason;
|
|
12956
|
+
}
|
|
12957
|
+
if (candidate.safetyRatings) {
|
|
12958
|
+
candidateDict.safetyRatings = candidate.safetyRatings;
|
|
12959
|
+
}
|
|
12960
|
+
candidates.push(candidateDict);
|
|
12961
|
+
}
|
|
12962
|
+
output.candidates = candidates;
|
|
12963
|
+
}
|
|
12964
|
+
if (usageMetadata) {
|
|
12965
|
+
output.usageMetadata = usageMetadata;
|
|
12966
|
+
populateUsageMetrics(metrics, usageMetadata);
|
|
12967
|
+
}
|
|
12968
|
+
if (text) {
|
|
12969
|
+
output.text = text;
|
|
12970
|
+
}
|
|
12971
|
+
return { output, metrics };
|
|
12972
|
+
}
|
|
12973
|
+
function tryToDict(obj) {
|
|
12974
|
+
if (obj === null || obj === void 0) {
|
|
12975
|
+
return null;
|
|
12976
|
+
}
|
|
12977
|
+
if (typeof obj === "object") {
|
|
12978
|
+
if ("toJSON" in obj && // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
12979
|
+
typeof obj.toJSON === "function") {
|
|
12980
|
+
return obj.toJSON();
|
|
12981
|
+
}
|
|
12982
|
+
return obj;
|
|
12983
|
+
}
|
|
12984
|
+
return null;
|
|
12985
|
+
}
|
|
12986
|
+
|
|
12987
|
+
// src/instrumentation/plugins/openrouter-channels.ts
|
|
12988
|
+
var openRouterChannels = defineChannels("@openrouter/sdk", {
|
|
12989
|
+
chatSend: channel({
|
|
12990
|
+
channelName: "chat.send",
|
|
12991
|
+
kind: "async"
|
|
12992
|
+
}),
|
|
12993
|
+
embeddingsGenerate: channel({
|
|
12994
|
+
channelName: "embeddings.generate",
|
|
12995
|
+
kind: "async"
|
|
12996
|
+
}),
|
|
12997
|
+
betaResponsesSend: channel({
|
|
12998
|
+
channelName: "beta.responses.send",
|
|
12999
|
+
kind: "async"
|
|
13000
|
+
}),
|
|
13001
|
+
callModel: channel({
|
|
13002
|
+
channelName: "callModel",
|
|
13003
|
+
kind: "sync-stream"
|
|
13004
|
+
}),
|
|
13005
|
+
toolExecute: channel({
|
|
13006
|
+
channelName: "tool.execute",
|
|
13007
|
+
kind: "async"
|
|
13008
|
+
})
|
|
13009
|
+
});
|
|
13010
|
+
|
|
13011
|
+
// src/openrouter-utils.ts
|
|
13012
|
+
var TOKEN_NAME_MAP2 = {
|
|
13013
|
+
promptTokens: "prompt_tokens",
|
|
13014
|
+
inputTokens: "prompt_tokens",
|
|
13015
|
+
completionTokens: "completion_tokens",
|
|
13016
|
+
outputTokens: "completion_tokens",
|
|
13017
|
+
totalTokens: "tokens",
|
|
13018
|
+
prompt_tokens: "prompt_tokens",
|
|
13019
|
+
input_tokens: "prompt_tokens",
|
|
13020
|
+
completion_tokens: "completion_tokens",
|
|
13021
|
+
output_tokens: "completion_tokens",
|
|
13022
|
+
total_tokens: "tokens"
|
|
13023
|
+
};
|
|
13024
|
+
var TOKEN_DETAIL_PREFIX_MAP = {
|
|
13025
|
+
promptTokensDetails: "prompt",
|
|
13026
|
+
inputTokensDetails: "prompt",
|
|
13027
|
+
completionTokensDetails: "completion",
|
|
13028
|
+
outputTokensDetails: "completion",
|
|
13029
|
+
costDetails: "cost",
|
|
13030
|
+
prompt_tokens_details: "prompt",
|
|
13031
|
+
input_tokens_details: "prompt",
|
|
13032
|
+
completion_tokens_details: "completion",
|
|
13033
|
+
output_tokens_details: "completion",
|
|
13034
|
+
cost_details: "cost"
|
|
13035
|
+
};
|
|
13036
|
+
function camelToSnake(value) {
|
|
13037
|
+
return value.replace(/[A-Z]/g, (match) => `_${match.toLowerCase()}`);
|
|
13038
|
+
}
|
|
13039
|
+
function parseOpenRouterMetricsFromUsage(usage) {
|
|
13040
|
+
if (!isObject(usage)) {
|
|
13041
|
+
return {};
|
|
13042
|
+
}
|
|
13043
|
+
const metrics = {};
|
|
13044
|
+
for (const [name, value] of Object.entries(usage)) {
|
|
13045
|
+
if (typeof value === "number") {
|
|
13046
|
+
metrics[TOKEN_NAME_MAP2[name] || camelToSnake(name)] = value;
|
|
13047
|
+
continue;
|
|
13048
|
+
}
|
|
13049
|
+
if (!isObject(value)) {
|
|
13050
|
+
continue;
|
|
13051
|
+
}
|
|
13052
|
+
const prefix = TOKEN_DETAIL_PREFIX_MAP[name];
|
|
13053
|
+
if (!prefix) {
|
|
13054
|
+
continue;
|
|
13055
|
+
}
|
|
13056
|
+
for (const [nestedName, nestedValue] of Object.entries(value)) {
|
|
13057
|
+
if (typeof nestedValue !== "number") {
|
|
13058
|
+
continue;
|
|
13059
|
+
}
|
|
13060
|
+
metrics[`${prefix}_${camelToSnake(nestedName)}`] = nestedValue;
|
|
13061
|
+
}
|
|
13062
|
+
}
|
|
13063
|
+
return metrics;
|
|
13064
|
+
}
|
|
13065
|
+
function extractOpenRouterUsageMetadata(usage) {
|
|
13066
|
+
if (!isObject(usage)) {
|
|
13067
|
+
return void 0;
|
|
13068
|
+
}
|
|
13069
|
+
const metadata = {};
|
|
13070
|
+
if (typeof usage.isByok === "boolean") {
|
|
13071
|
+
metadata.is_byok = usage.isByok;
|
|
13072
|
+
} else if (typeof usage.is_byok === "boolean") {
|
|
13073
|
+
metadata.is_byok = usage.is_byok;
|
|
13074
|
+
}
|
|
13075
|
+
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
13076
|
+
}
|
|
13077
|
+
|
|
13078
|
+
// src/openrouter-logging.ts
|
|
13079
|
+
var OMITTED_OPENROUTER_KEYS = /* @__PURE__ */ new Set([
|
|
13080
|
+
"execute",
|
|
13081
|
+
"render",
|
|
13082
|
+
"nextTurnParams",
|
|
13083
|
+
"requireApproval"
|
|
13084
|
+
]);
|
|
13085
|
+
function parseOpenRouterModelString(model) {
|
|
13086
|
+
if (typeof model !== "string") {
|
|
13087
|
+
return { model };
|
|
13088
|
+
}
|
|
13089
|
+
const slashIndex = model.indexOf("/");
|
|
13090
|
+
if (slashIndex > 0 && slashIndex < model.length - 1) {
|
|
13091
|
+
return {
|
|
13092
|
+
provider: model.substring(0, slashIndex),
|
|
13093
|
+
model: model.substring(slashIndex + 1)
|
|
13094
|
+
};
|
|
13095
|
+
}
|
|
13096
|
+
return { model };
|
|
13097
|
+
}
|
|
13098
|
+
function isZodSchema2(value) {
|
|
13099
|
+
return value != null && typeof value === "object" && "_def" in value && typeof value._def === "object";
|
|
13100
|
+
}
|
|
13101
|
+
function serializeZodSchema2(schema) {
|
|
13102
|
+
try {
|
|
13103
|
+
return zodToJsonSchema(schema);
|
|
13104
|
+
} catch {
|
|
13105
|
+
return {
|
|
13106
|
+
type: "object",
|
|
13107
|
+
description: "Zod schema (conversion failed)"
|
|
13108
|
+
};
|
|
13109
|
+
}
|
|
13110
|
+
}
|
|
13111
|
+
function serializeOpenRouterTool(tool) {
|
|
13112
|
+
if (!isObject(tool)) {
|
|
13113
|
+
return tool;
|
|
13114
|
+
}
|
|
13115
|
+
const serialized = {};
|
|
13116
|
+
for (const [key, value] of Object.entries(tool)) {
|
|
13117
|
+
if (OMITTED_OPENROUTER_KEYS.has(key)) {
|
|
13118
|
+
continue;
|
|
13119
|
+
}
|
|
13120
|
+
if (key === "function" && isObject(value)) {
|
|
13121
|
+
serialized.function = sanitizeOpenRouterLoggedValue(value);
|
|
13122
|
+
continue;
|
|
13123
|
+
}
|
|
13124
|
+
serialized[key] = sanitizeOpenRouterLoggedValue(value);
|
|
13125
|
+
}
|
|
13126
|
+
return serialized;
|
|
13127
|
+
}
|
|
13128
|
+
function serializeOpenRouterToolsForLogging(tools) {
|
|
13129
|
+
if (!Array.isArray(tools)) {
|
|
13130
|
+
return void 0;
|
|
13131
|
+
}
|
|
13132
|
+
return tools.map((tool) => serializeOpenRouterTool(tool));
|
|
13133
|
+
}
|
|
13134
|
+
function sanitizeOpenRouterLoggedValue(value) {
|
|
13135
|
+
if (isZodSchema2(value)) {
|
|
13136
|
+
return serializeZodSchema2(value);
|
|
13137
|
+
}
|
|
13138
|
+
if (typeof value === "function") {
|
|
13139
|
+
return "[Function]";
|
|
13140
|
+
}
|
|
13141
|
+
if (Array.isArray(value)) {
|
|
13142
|
+
return value.map((entry) => sanitizeOpenRouterLoggedValue(entry));
|
|
13143
|
+
}
|
|
13144
|
+
if (!isObject(value)) {
|
|
13145
|
+
return value;
|
|
13146
|
+
}
|
|
13147
|
+
const sanitized = {};
|
|
13148
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
13149
|
+
if (OMITTED_OPENROUTER_KEYS.has(key)) {
|
|
13150
|
+
continue;
|
|
13151
|
+
}
|
|
13152
|
+
if (key === "tools" && Array.isArray(entry)) {
|
|
13153
|
+
sanitized.tools = serializeOpenRouterToolsForLogging(entry);
|
|
13154
|
+
continue;
|
|
13155
|
+
}
|
|
13156
|
+
sanitized[key] = sanitizeOpenRouterLoggedValue(entry);
|
|
13157
|
+
}
|
|
13158
|
+
return sanitized;
|
|
13159
|
+
}
|
|
13160
|
+
function buildOpenRouterMetadata(metadata, httpReferer, xTitle) {
|
|
13161
|
+
const sanitized = sanitizeOpenRouterLoggedValue(metadata);
|
|
13162
|
+
const metadataRecord = isObject(sanitized) ? sanitized : {};
|
|
13163
|
+
const { model, provider: providerRouting, ...rest } = metadataRecord;
|
|
13164
|
+
const normalizedModel = parseOpenRouterModelString(model);
|
|
13165
|
+
return {
|
|
13166
|
+
...rest,
|
|
13167
|
+
...normalizedModel.model !== void 0 ? { model: normalizedModel.model } : {},
|
|
13168
|
+
...providerRouting !== void 0 ? { providerRouting } : {},
|
|
13169
|
+
...httpReferer !== void 0 ? { httpReferer } : {},
|
|
13170
|
+
...xTitle !== void 0 ? { xTitle } : {},
|
|
13171
|
+
provider: normalizedModel.provider || "openrouter"
|
|
13172
|
+
};
|
|
13173
|
+
}
|
|
13174
|
+
function buildOpenRouterEmbeddingMetadata(metadata, httpReferer, xTitle) {
|
|
13175
|
+
const normalized = buildOpenRouterMetadata(metadata, httpReferer, xTitle);
|
|
13176
|
+
return typeof normalized.model === "string" ? {
|
|
13177
|
+
...normalized,
|
|
13178
|
+
embedding_model: normalized.model
|
|
13179
|
+
} : normalized;
|
|
13180
|
+
}
|
|
13181
|
+
function extractOpenRouterCallModelInput(request) {
|
|
13182
|
+
return isObject(request) && "input" in request ? sanitizeOpenRouterLoggedValue(request.input) : void 0;
|
|
13183
|
+
}
|
|
13184
|
+
function extractOpenRouterCallModelMetadata(request) {
|
|
13185
|
+
if (!isObject(request)) {
|
|
13186
|
+
return { provider: "openrouter" };
|
|
13187
|
+
}
|
|
13188
|
+
const { input: _input, ...metadata } = request;
|
|
13189
|
+
return buildOpenRouterMetadata(metadata, void 0, void 0);
|
|
13190
|
+
}
|
|
13191
|
+
function extractOpenRouterResponseMetadata(result) {
|
|
13192
|
+
if (!isObject(result)) {
|
|
13193
|
+
return void 0;
|
|
13194
|
+
}
|
|
13195
|
+
const { output: _output, data: _data, usage, ...metadata } = result;
|
|
13196
|
+
const sanitized = sanitizeOpenRouterLoggedValue(metadata);
|
|
13197
|
+
const metadataRecord = isObject(sanitized) ? sanitized : {};
|
|
13198
|
+
const { model, provider, ...rest } = metadataRecord;
|
|
13199
|
+
const normalizedModel = parseOpenRouterModelString(model);
|
|
13200
|
+
const normalizedProvider = (typeof provider === "string" ? provider : void 0) || normalizedModel.provider;
|
|
13201
|
+
const usageMetadata = extractOpenRouterUsageMetadata(usage);
|
|
13202
|
+
const combined = {
|
|
13203
|
+
...rest,
|
|
13204
|
+
...normalizedModel.model !== void 0 ? { model: normalizedModel.model } : {},
|
|
13205
|
+
...usageMetadata || {},
|
|
13206
|
+
...normalizedProvider !== void 0 ? { provider: normalizedProvider } : {}
|
|
13207
|
+
};
|
|
13208
|
+
return Object.keys(combined).length > 0 ? combined : void 0;
|
|
13209
|
+
}
|
|
13210
|
+
function extractOpenRouterResponseOutput(response, fallbackOutput) {
|
|
13211
|
+
if (isObject(response) && "output" in response && response.output !== void 0) {
|
|
13212
|
+
return sanitizeOpenRouterLoggedValue(response.output);
|
|
13213
|
+
}
|
|
13214
|
+
if (fallbackOutput !== void 0) {
|
|
13215
|
+
return sanitizeOpenRouterLoggedValue(fallbackOutput);
|
|
13216
|
+
}
|
|
13217
|
+
return void 0;
|
|
13218
|
+
}
|
|
13219
|
+
|
|
13220
|
+
// src/openrouter-tool-wrapping.ts
|
|
13221
|
+
var OPENROUTER_WRAPPED_TOOL = Symbol("braintrust.openrouter.wrappedTool");
|
|
13222
|
+
var OPENROUTER_WRAPPED_CALL_MODEL_RESULT = Symbol(
|
|
13223
|
+
"braintrust.openrouter.wrappedCallModelResult"
|
|
13224
|
+
);
|
|
13225
|
+
var OPENROUTER_CALL_MODEL_STREAM_METHODS = [
|
|
13226
|
+
"getFullResponsesStream",
|
|
13227
|
+
"getItemsStream",
|
|
13228
|
+
"getNewMessagesStream",
|
|
13229
|
+
"getReasoningStream",
|
|
13230
|
+
"getTextStream",
|
|
13231
|
+
"getToolCallsStream",
|
|
13232
|
+
"getToolStream"
|
|
13233
|
+
];
|
|
13234
|
+
var OPENROUTER_CALL_MODEL_CONTEXT_METHODS = [
|
|
13235
|
+
"cancel",
|
|
13236
|
+
"getPendingToolCalls",
|
|
13237
|
+
"getState",
|
|
13238
|
+
"getToolCalls",
|
|
13239
|
+
"requiresApproval"
|
|
13240
|
+
];
|
|
13241
|
+
function startOpenRouterCallModelSpan(request) {
|
|
13242
|
+
return startSpan({
|
|
13243
|
+
name: "openrouter.callModel",
|
|
13244
|
+
spanAttributes: {
|
|
13245
|
+
type: "llm" /* LLM */
|
|
13246
|
+
},
|
|
13247
|
+
event: {
|
|
13248
|
+
input: extractOpenRouterCallModelInput(request),
|
|
13249
|
+
metadata: extractOpenRouterCallModelMetadata(request)
|
|
13250
|
+
}
|
|
13251
|
+
});
|
|
13252
|
+
}
|
|
13253
|
+
function patchOpenRouterCallModelRequestTools(request) {
|
|
13254
|
+
if (!Array.isArray(request.tools) || request.tools.length === 0) {
|
|
13255
|
+
return void 0;
|
|
13256
|
+
}
|
|
13257
|
+
const originalTools = request.tools;
|
|
13258
|
+
const wrappedTools = originalTools.map((tool) => wrapOpenRouterTool(tool));
|
|
13259
|
+
const didPatch = wrappedTools.some(
|
|
13260
|
+
(tool, index) => tool !== originalTools[index]
|
|
13261
|
+
);
|
|
13262
|
+
if (!didPatch) {
|
|
13263
|
+
return void 0;
|
|
13264
|
+
}
|
|
13265
|
+
request.tools = wrappedTools;
|
|
13266
|
+
return () => {
|
|
13267
|
+
request.tools = originalTools;
|
|
13268
|
+
};
|
|
13269
|
+
}
|
|
13270
|
+
function patchOpenRouterCallModelResult(span, result, request) {
|
|
13271
|
+
if (!isObject(result) || isWrappedCallModelResult(result)) {
|
|
13272
|
+
return false;
|
|
13273
|
+
}
|
|
13274
|
+
const resultLike = result;
|
|
13275
|
+
const hasInstrumentableMethod = typeof resultLike.getResponse === "function" || typeof resultLike.getText === "function" || OPENROUTER_CALL_MODEL_STREAM_METHODS.some(
|
|
13276
|
+
(methodName) => typeof resultLike[methodName] === "function"
|
|
13277
|
+
);
|
|
13278
|
+
if (!hasInstrumentableMethod) {
|
|
13279
|
+
return false;
|
|
13280
|
+
}
|
|
13281
|
+
Object.defineProperty(resultLike, OPENROUTER_WRAPPED_CALL_MODEL_RESULT, {
|
|
13282
|
+
value: true,
|
|
13283
|
+
enumerable: false,
|
|
13284
|
+
configurable: false
|
|
13285
|
+
});
|
|
13286
|
+
const originalGetResponse = typeof resultLike.getResponse === "function" ? resultLike.getResponse.bind(resultLike) : void 0;
|
|
13287
|
+
const originalGetInitialResponse = typeof resultLike.getInitialResponse === "function" ? resultLike.getInitialResponse.bind(resultLike) : void 0;
|
|
13288
|
+
const originalMakeFollowupRequest = typeof resultLike.makeFollowupRequest === "function" ? resultLike.makeFollowupRequest.bind(resultLike) : void 0;
|
|
13289
|
+
let ended = false;
|
|
13290
|
+
let tracedTurnCount = 0;
|
|
13291
|
+
const endSpanWithResult = async (response, fallbackOutput) => {
|
|
13292
|
+
if (ended) {
|
|
13293
|
+
return;
|
|
13294
|
+
}
|
|
13295
|
+
ended = true;
|
|
13296
|
+
const finalResponse = getFinalOpenRouterCallModelResponse(
|
|
13297
|
+
resultLike,
|
|
13298
|
+
response
|
|
13299
|
+
);
|
|
13300
|
+
if (finalResponse) {
|
|
13301
|
+
const rounds = getOpenRouterCallModelRounds(resultLike);
|
|
13302
|
+
const metadata = extractOpenRouterCallModelResultMetadata(
|
|
13303
|
+
finalResponse,
|
|
13304
|
+
rounds.length + 1
|
|
13305
|
+
);
|
|
13306
|
+
span.log({
|
|
13307
|
+
output: extractOpenRouterResponseOutput(finalResponse, fallbackOutput),
|
|
13308
|
+
...metadata ? { metadata } : {},
|
|
13309
|
+
metrics: aggregateOpenRouterCallModelMetrics(rounds, finalResponse)
|
|
13310
|
+
});
|
|
13311
|
+
span.end();
|
|
13312
|
+
return;
|
|
13313
|
+
}
|
|
13314
|
+
if (fallbackOutput !== void 0) {
|
|
13315
|
+
span.log({
|
|
13316
|
+
output: fallbackOutput
|
|
13317
|
+
});
|
|
13318
|
+
}
|
|
13319
|
+
span.end();
|
|
13320
|
+
};
|
|
13321
|
+
const endSpanWithError = (error) => {
|
|
13322
|
+
if (ended) {
|
|
13323
|
+
return;
|
|
13324
|
+
}
|
|
13325
|
+
ended = true;
|
|
13326
|
+
span.log({
|
|
13327
|
+
error: normalizeError(error).message
|
|
13328
|
+
});
|
|
13329
|
+
span.end();
|
|
13330
|
+
};
|
|
13331
|
+
const finalizeFromResponse = async (fallbackOutput) => {
|
|
13332
|
+
if (!originalGetResponse) {
|
|
13333
|
+
await endSpanWithResult(void 0, fallbackOutput);
|
|
13334
|
+
return;
|
|
13335
|
+
}
|
|
13336
|
+
try {
|
|
13337
|
+
await endSpanWithResult(await originalGetResponse(), fallbackOutput);
|
|
13338
|
+
} catch {
|
|
13339
|
+
await endSpanWithResult(void 0, fallbackOutput);
|
|
13340
|
+
}
|
|
13341
|
+
};
|
|
13342
|
+
if (originalGetResponse) {
|
|
13343
|
+
resultLike.getResponse = async (...args) => {
|
|
13344
|
+
return await withCurrent(span, async () => {
|
|
13345
|
+
try {
|
|
13346
|
+
const response = await originalGetResponse(...args);
|
|
13347
|
+
await endSpanWithResult(response);
|
|
13348
|
+
return response;
|
|
13349
|
+
} catch (error) {
|
|
13350
|
+
endSpanWithError(error);
|
|
13351
|
+
throw error;
|
|
13352
|
+
}
|
|
13353
|
+
});
|
|
13354
|
+
};
|
|
13355
|
+
}
|
|
13356
|
+
if (typeof resultLike.getText === "function") {
|
|
13357
|
+
const originalGetText = resultLike.getText.bind(resultLike);
|
|
13358
|
+
resultLike.getText = async (...args) => {
|
|
13359
|
+
return await withCurrent(span, async () => {
|
|
13360
|
+
try {
|
|
13361
|
+
const text = await originalGetText(...args);
|
|
13362
|
+
await finalizeFromResponse(text);
|
|
13363
|
+
return text;
|
|
13364
|
+
} catch (error) {
|
|
13365
|
+
endSpanWithError(error);
|
|
13366
|
+
throw error;
|
|
13367
|
+
}
|
|
13368
|
+
});
|
|
13369
|
+
};
|
|
13370
|
+
}
|
|
13371
|
+
for (const methodName of OPENROUTER_CALL_MODEL_CONTEXT_METHODS) {
|
|
13372
|
+
if (typeof resultLike[methodName] !== "function") {
|
|
13373
|
+
continue;
|
|
13374
|
+
}
|
|
13375
|
+
const originalMethod = resultLike[methodName];
|
|
13376
|
+
resultLike[methodName] = async (...args) => {
|
|
13377
|
+
return await withCurrent(span, async () => {
|
|
13378
|
+
return await originalMethod.apply(resultLike, args);
|
|
13379
|
+
});
|
|
13380
|
+
};
|
|
13381
|
+
}
|
|
13382
|
+
for (const methodName of OPENROUTER_CALL_MODEL_STREAM_METHODS) {
|
|
13383
|
+
if (typeof resultLike[methodName] !== "function") {
|
|
13384
|
+
continue;
|
|
13385
|
+
}
|
|
13386
|
+
const originalMethod = resultLike[methodName];
|
|
13387
|
+
resultLike[methodName] = (...args) => {
|
|
13388
|
+
const stream = withCurrent(
|
|
13389
|
+
span,
|
|
13390
|
+
() => originalMethod.apply(resultLike, args)
|
|
13391
|
+
);
|
|
13392
|
+
if (!isAsyncIterable2(stream)) {
|
|
13393
|
+
return stream;
|
|
13394
|
+
}
|
|
13395
|
+
return wrapAsyncIterableWithSpan({
|
|
13396
|
+
finalize: finalizeFromResponse,
|
|
13397
|
+
iteratorFactory: () => stream[Symbol.asyncIterator](),
|
|
13398
|
+
onError: endSpanWithError,
|
|
13399
|
+
span
|
|
13400
|
+
});
|
|
13401
|
+
};
|
|
13402
|
+
}
|
|
13403
|
+
if (originalGetInitialResponse) {
|
|
13404
|
+
let initialTurnTraced = false;
|
|
13405
|
+
resultLike.getInitialResponse = async (...args) => {
|
|
13406
|
+
if (initialTurnTraced) {
|
|
13407
|
+
return await withCurrent(span, async () => {
|
|
13408
|
+
return await originalGetInitialResponse(...args);
|
|
13409
|
+
});
|
|
13410
|
+
}
|
|
13411
|
+
initialTurnTraced = true;
|
|
13412
|
+
const resolvedRequest = getOpenRouterResolvedRequest(resultLike, request);
|
|
13413
|
+
const childSpan = startOpenRouterCallModelTurnSpan({
|
|
13414
|
+
request: resolvedRequest,
|
|
13415
|
+
step: tracedTurnCount + 1,
|
|
13416
|
+
stepType: tracedTurnCount === 0 ? "initial" : "continue"
|
|
13417
|
+
});
|
|
13418
|
+
return await withCurrent(childSpan, async () => {
|
|
13419
|
+
try {
|
|
13420
|
+
const response = await originalGetInitialResponse(...args);
|
|
13421
|
+
tracedTurnCount++;
|
|
13422
|
+
finishOpenRouterCallModelTurnSpan({
|
|
13423
|
+
response,
|
|
13424
|
+
step: tracedTurnCount,
|
|
13425
|
+
stepType: tracedTurnCount === 1 ? "initial" : "continue",
|
|
13426
|
+
span: childSpan
|
|
13427
|
+
});
|
|
13428
|
+
return response;
|
|
13429
|
+
} catch (error) {
|
|
13430
|
+
childSpan.log({
|
|
13431
|
+
error: normalizeError(error).message
|
|
13432
|
+
});
|
|
13433
|
+
childSpan.end();
|
|
13434
|
+
throw error;
|
|
13435
|
+
}
|
|
13436
|
+
});
|
|
13437
|
+
};
|
|
13438
|
+
}
|
|
13439
|
+
if (originalMakeFollowupRequest) {
|
|
13440
|
+
resultLike.makeFollowupRequest = async (...args) => {
|
|
13441
|
+
const currentResponse = args[0];
|
|
13442
|
+
const toolResults = Array.isArray(args[1]) ? args[1] : [];
|
|
13443
|
+
const resolvedRequest = getOpenRouterResolvedRequest(resultLike, request);
|
|
13444
|
+
const followupRequest = buildOpenRouterFollowupRequest(
|
|
13445
|
+
resolvedRequest,
|
|
13446
|
+
currentResponse,
|
|
13447
|
+
toolResults
|
|
13448
|
+
);
|
|
13449
|
+
const childSpan = startOpenRouterCallModelTurnSpan({
|
|
13450
|
+
request: followupRequest,
|
|
13451
|
+
step: tracedTurnCount + 1,
|
|
13452
|
+
stepType: "continue"
|
|
13453
|
+
});
|
|
13454
|
+
return await withCurrent(childSpan, async () => {
|
|
13455
|
+
try {
|
|
13456
|
+
const response = await originalMakeFollowupRequest(...args);
|
|
13457
|
+
tracedTurnCount++;
|
|
13458
|
+
finishOpenRouterCallModelTurnSpan({
|
|
13459
|
+
response,
|
|
13460
|
+
step: tracedTurnCount,
|
|
13461
|
+
stepType: "continue",
|
|
13462
|
+
span: childSpan
|
|
13463
|
+
});
|
|
13464
|
+
return response;
|
|
13465
|
+
} catch (error) {
|
|
13466
|
+
childSpan.log({
|
|
13467
|
+
error: normalizeError(error).message
|
|
13468
|
+
});
|
|
13469
|
+
childSpan.end();
|
|
13470
|
+
throw error;
|
|
13471
|
+
}
|
|
13472
|
+
});
|
|
13473
|
+
};
|
|
13474
|
+
}
|
|
13475
|
+
return true;
|
|
13476
|
+
}
|
|
13477
|
+
function wrapOpenRouterTool(tool) {
|
|
13478
|
+
if (isWrappedTool(tool) || !tool.function || typeof tool.function !== "object" || typeof tool.function.execute !== "function") {
|
|
13479
|
+
return tool;
|
|
13480
|
+
}
|
|
13481
|
+
const toolName = tool.function.name || "tool";
|
|
13482
|
+
const originalExecute = tool.function.execute;
|
|
13483
|
+
const wrappedTool = {
|
|
13484
|
+
...tool,
|
|
13485
|
+
function: {
|
|
13486
|
+
...tool.function,
|
|
13487
|
+
execute(...args) {
|
|
13488
|
+
return traceToolExecution({
|
|
13489
|
+
args,
|
|
13490
|
+
execute: () => Reflect.apply(originalExecute, this, args),
|
|
13491
|
+
toolCallId: getToolCallId(args[1]),
|
|
13492
|
+
toolName
|
|
13493
|
+
});
|
|
13494
|
+
}
|
|
13495
|
+
}
|
|
13496
|
+
};
|
|
13497
|
+
Object.defineProperty(wrappedTool, OPENROUTER_WRAPPED_TOOL, {
|
|
13498
|
+
value: true,
|
|
13499
|
+
enumerable: false,
|
|
13500
|
+
configurable: false
|
|
13501
|
+
});
|
|
13502
|
+
return wrappedTool;
|
|
13503
|
+
}
|
|
13504
|
+
function isWrappedTool(tool) {
|
|
13505
|
+
return Boolean(tool[OPENROUTER_WRAPPED_TOOL]);
|
|
13506
|
+
}
|
|
13507
|
+
function isWrappedCallModelResult(value) {
|
|
13508
|
+
return Boolean(
|
|
13509
|
+
isObject(value) && value[OPENROUTER_WRAPPED_CALL_MODEL_RESULT]
|
|
13510
|
+
);
|
|
13511
|
+
}
|
|
13512
|
+
function traceToolExecution(args) {
|
|
13513
|
+
const tracingChannel2 = openRouterChannels.toolExecute.tracingChannel();
|
|
13514
|
+
const input = args.args.length > 0 ? args.args[0] : void 0;
|
|
13515
|
+
const event = {
|
|
13516
|
+
arguments: [input],
|
|
13517
|
+
span_info: {
|
|
13518
|
+
name: args.toolName
|
|
13519
|
+
},
|
|
13520
|
+
toolCallId: args.toolCallId,
|
|
13521
|
+
toolName: args.toolName
|
|
13522
|
+
};
|
|
13523
|
+
tracingChannel2.start.publish(event);
|
|
13524
|
+
try {
|
|
13525
|
+
const result = args.execute();
|
|
13526
|
+
return publishToolResult(tracingChannel2, event, result);
|
|
13527
|
+
} catch (error) {
|
|
13528
|
+
event.error = normalizeError(error);
|
|
13529
|
+
tracingChannel2.error.publish(event);
|
|
13530
|
+
throw error;
|
|
13531
|
+
}
|
|
13532
|
+
}
|
|
13533
|
+
function publishToolResult(tracingChannel2, event, result) {
|
|
13534
|
+
if (isPromiseLike(result)) {
|
|
13535
|
+
return result.then(
|
|
13536
|
+
(resolved) => {
|
|
13537
|
+
event.result = resolved;
|
|
13538
|
+
tracingChannel2.asyncEnd.publish(event);
|
|
13539
|
+
return resolved;
|
|
13540
|
+
},
|
|
13541
|
+
(error) => {
|
|
13542
|
+
event.error = normalizeError(error);
|
|
13543
|
+
tracingChannel2.error.publish(event);
|
|
13544
|
+
throw error;
|
|
13545
|
+
}
|
|
13546
|
+
);
|
|
13547
|
+
}
|
|
13548
|
+
event.result = result;
|
|
13549
|
+
tracingChannel2.asyncEnd.publish(event);
|
|
13550
|
+
return result;
|
|
13551
|
+
}
|
|
13552
|
+
function getToolCallId(context) {
|
|
13553
|
+
const toolContext = context;
|
|
13554
|
+
return typeof toolContext?.toolCall?.id === "string" ? toolContext.toolCall.id : void 0;
|
|
13555
|
+
}
|
|
13556
|
+
function extractOpenRouterCallModelResultMetadata(response, turnCount) {
|
|
13557
|
+
const combined = {
|
|
13558
|
+
...extractOpenRouterResponseMetadata(response) || {},
|
|
13559
|
+
...turnCount !== void 0 ? { turn_count: turnCount } : {}
|
|
13560
|
+
};
|
|
13561
|
+
return Object.keys(combined).length > 0 ? combined : void 0;
|
|
13562
|
+
}
|
|
13563
|
+
function getFinalOpenRouterCallModelResponse(result, response) {
|
|
13564
|
+
if (isObject(response)) {
|
|
13565
|
+
return response;
|
|
13566
|
+
}
|
|
13567
|
+
return isObject(result.finalResponse) ? result.finalResponse : void 0;
|
|
13568
|
+
}
|
|
13569
|
+
function getOpenRouterCallModelRounds(result) {
|
|
13570
|
+
if (!Array.isArray(result.allToolExecutionRounds)) {
|
|
13571
|
+
return [];
|
|
13572
|
+
}
|
|
13573
|
+
return result.allToolExecutionRounds.filter((round) => isObject(round)).map((round) => ({
|
|
13574
|
+
response: isObject(round.response) ? round.response : void 0,
|
|
13575
|
+
round: typeof round.round === "number" ? round.round : void 0,
|
|
13576
|
+
toolResults: Array.isArray(round.toolResults) ? round.toolResults : []
|
|
13577
|
+
})).filter((round) => round.response !== void 0);
|
|
13578
|
+
}
|
|
13579
|
+
function aggregateOpenRouterCallModelMetrics(rounds, finalResponse) {
|
|
13580
|
+
const metrics = {};
|
|
13581
|
+
const responses = [
|
|
13582
|
+
...rounds.map((round) => round.response).filter(isObject),
|
|
13583
|
+
finalResponse
|
|
13584
|
+
];
|
|
13585
|
+
for (const response of responses) {
|
|
13586
|
+
const responseMetrics = parseOpenRouterMetricsFromUsage(response.usage);
|
|
13587
|
+
for (const [name, value] of Object.entries(responseMetrics)) {
|
|
13588
|
+
metrics[name] = (metrics[name] || 0) + value;
|
|
13589
|
+
}
|
|
13590
|
+
}
|
|
13591
|
+
return metrics;
|
|
13592
|
+
}
|
|
13593
|
+
function buildNextOpenRouterCallModelInput(currentInput, response, toolResults) {
|
|
13594
|
+
const normalizedInput = Array.isArray(currentInput) ? [...currentInput] : currentInput === void 0 ? [] : [currentInput];
|
|
13595
|
+
const responseOutput = Array.isArray(response.output) ? response.output : response.output === void 0 ? [] : [response.output];
|
|
13596
|
+
return [...normalizedInput, ...responseOutput, ...toolResults].map(
|
|
13597
|
+
(entry) => sanitizeOpenRouterLoggedValue(entry)
|
|
13598
|
+
);
|
|
13599
|
+
}
|
|
13600
|
+
function startOpenRouterCallModelTurnSpan(args) {
|
|
13601
|
+
const requestRecord = isObject(args.request) ? args.request : void 0;
|
|
13602
|
+
const metadata = requestRecord ? extractOpenRouterCallModelMetadata(requestRecord) : { provider: "openrouter" };
|
|
13603
|
+
if (isObject(metadata) && "tools" in metadata) {
|
|
13604
|
+
delete metadata.tools;
|
|
13605
|
+
}
|
|
13606
|
+
return startSpan({
|
|
13607
|
+
name: "openrouter.beta.responses.send",
|
|
13608
|
+
spanAttributes: {
|
|
13609
|
+
type: "llm" /* LLM */
|
|
13610
|
+
},
|
|
13611
|
+
event: {
|
|
13612
|
+
input: requestRecord ? extractOpenRouterCallModelInput(requestRecord) : void 0,
|
|
13613
|
+
metadata: {
|
|
13614
|
+
...metadata,
|
|
13615
|
+
step: args.step,
|
|
13616
|
+
step_type: args.stepType
|
|
13617
|
+
}
|
|
13618
|
+
}
|
|
13619
|
+
});
|
|
13620
|
+
}
|
|
13621
|
+
function finishOpenRouterCallModelTurnSpan(args) {
|
|
13622
|
+
if (!isObject(args.response)) {
|
|
13623
|
+
args.span.end();
|
|
13624
|
+
return;
|
|
13625
|
+
}
|
|
13626
|
+
args.span.log({
|
|
13627
|
+
output: extractOpenRouterResponseOutput(args.response),
|
|
13628
|
+
...extractOpenRouterResponseMetadata(args.response) ? {
|
|
13629
|
+
metadata: {
|
|
13630
|
+
...extractOpenRouterResponseMetadata(args.response),
|
|
13631
|
+
...args.step !== void 0 ? { step: args.step } : {},
|
|
13632
|
+
...args.stepType ? { step_type: args.stepType } : {}
|
|
13633
|
+
}
|
|
13634
|
+
} : {},
|
|
13635
|
+
metrics: parseOpenRouterMetricsFromUsage(args.response.usage)
|
|
13636
|
+
});
|
|
13637
|
+
args.span.end();
|
|
13638
|
+
}
|
|
13639
|
+
function getOpenRouterResolvedRequest(result, request) {
|
|
13640
|
+
if (isObject(result.resolvedRequest)) {
|
|
13641
|
+
return result.resolvedRequest;
|
|
13642
|
+
}
|
|
13643
|
+
return request;
|
|
13644
|
+
}
|
|
13645
|
+
function buildOpenRouterFollowupRequest(request, currentResponse, toolResults) {
|
|
13646
|
+
if (!request) {
|
|
13647
|
+
return void 0;
|
|
13648
|
+
}
|
|
13649
|
+
return {
|
|
13650
|
+
...request,
|
|
13651
|
+
input: buildNextOpenRouterCallModelInput(
|
|
13652
|
+
extractOpenRouterCallModelInput(request),
|
|
13653
|
+
isObject(currentResponse) ? currentResponse : {},
|
|
13654
|
+
toolResults
|
|
13655
|
+
),
|
|
13656
|
+
stream: false
|
|
13657
|
+
};
|
|
13658
|
+
}
|
|
13659
|
+
function wrapAsyncIterableWithSpan(args) {
|
|
13660
|
+
return {
|
|
13661
|
+
[Symbol.asyncIterator]() {
|
|
13662
|
+
const iterator = args.iteratorFactory();
|
|
13663
|
+
return {
|
|
13664
|
+
next(value) {
|
|
13665
|
+
return withCurrent(
|
|
13666
|
+
args.span,
|
|
13667
|
+
() => value === void 0 ? iterator.next() : iterator.next(value)
|
|
13668
|
+
).then(
|
|
13669
|
+
async (result) => {
|
|
13670
|
+
if (result.done) {
|
|
13671
|
+
await args.finalize();
|
|
13672
|
+
}
|
|
13673
|
+
return result;
|
|
13674
|
+
},
|
|
13675
|
+
(error) => {
|
|
13676
|
+
args.onError(error);
|
|
13677
|
+
throw error;
|
|
13678
|
+
}
|
|
13679
|
+
);
|
|
13680
|
+
},
|
|
13681
|
+
return(value) {
|
|
13682
|
+
if (typeof iterator.return !== "function") {
|
|
13683
|
+
return args.finalize().then(() => ({
|
|
13684
|
+
done: true,
|
|
13685
|
+
value
|
|
13686
|
+
}));
|
|
13687
|
+
}
|
|
13688
|
+
return withCurrent(args.span, () => iterator.return(value)).then(
|
|
13689
|
+
async (result) => {
|
|
13690
|
+
await args.finalize();
|
|
13691
|
+
return result;
|
|
13692
|
+
},
|
|
13693
|
+
(error) => {
|
|
13694
|
+
args.onError(error);
|
|
13695
|
+
throw error;
|
|
13696
|
+
}
|
|
13697
|
+
);
|
|
13698
|
+
},
|
|
13699
|
+
throw(error) {
|
|
13700
|
+
args.onError(error);
|
|
13701
|
+
if (typeof iterator.throw !== "function") {
|
|
13702
|
+
return Promise.reject(error);
|
|
13703
|
+
}
|
|
13704
|
+
return withCurrent(args.span, () => iterator.throw(error));
|
|
13705
|
+
},
|
|
13706
|
+
[Symbol.asyncIterator]() {
|
|
13707
|
+
return this;
|
|
13708
|
+
}
|
|
13709
|
+
};
|
|
13710
|
+
}
|
|
13711
|
+
};
|
|
13712
|
+
}
|
|
13713
|
+
function isAsyncIterable2(value) {
|
|
13714
|
+
return !!value && (typeof value === "object" || typeof value === "function") && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
13715
|
+
}
|
|
13716
|
+
function isPromiseLike(value) {
|
|
13717
|
+
return !!value && (typeof value === "object" || typeof value === "function") && "then" in value && typeof value.then === "function";
|
|
13718
|
+
}
|
|
13719
|
+
function normalizeError(error) {
|
|
13720
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
13721
|
+
}
|
|
13722
|
+
|
|
13723
|
+
// src/instrumentation/plugins/openrouter-plugin.ts
|
|
13724
|
+
var OpenRouterPlugin = class extends BasePlugin {
|
|
13725
|
+
onEnable() {
|
|
13726
|
+
this.subscribeToOpenRouterChannels();
|
|
13727
|
+
}
|
|
13728
|
+
onDisable() {
|
|
13729
|
+
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
13730
|
+
}
|
|
13731
|
+
subscribeToOpenRouterChannels() {
|
|
13732
|
+
this.unsubscribers.push(
|
|
13733
|
+
traceStreamingChannel(openRouterChannels.chatSend, {
|
|
13734
|
+
name: "openrouter.chat.send",
|
|
13735
|
+
type: "llm" /* LLM */,
|
|
13736
|
+
extractInput: (args) => {
|
|
13737
|
+
const request = getOpenRouterRequestArg(args);
|
|
13738
|
+
const chatGenerationParams = isObject(request?.chatGenerationParams) ? request.chatGenerationParams : {};
|
|
13739
|
+
const httpReferer = request?.httpReferer;
|
|
13740
|
+
const xTitle = request?.xTitle;
|
|
13741
|
+
const { messages, ...metadata } = chatGenerationParams;
|
|
13742
|
+
return {
|
|
13743
|
+
input: messages,
|
|
13744
|
+
metadata: buildOpenRouterMetadata(metadata, httpReferer, xTitle)
|
|
13745
|
+
};
|
|
13746
|
+
},
|
|
13747
|
+
extractOutput: (result) => {
|
|
13748
|
+
return isObject(result) ? result.choices : void 0;
|
|
13749
|
+
},
|
|
13750
|
+
extractMetrics: (result, startTime) => {
|
|
13751
|
+
const metrics = parseOpenRouterMetricsFromUsage(result?.usage);
|
|
13752
|
+
if (startTime) {
|
|
13753
|
+
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
13754
|
+
}
|
|
13755
|
+
return metrics;
|
|
13756
|
+
},
|
|
13757
|
+
aggregateChunks: aggregateOpenRouterChatChunks
|
|
13758
|
+
})
|
|
13759
|
+
);
|
|
13760
|
+
this.unsubscribers.push(
|
|
13761
|
+
traceAsyncChannel(openRouterChannels.embeddingsGenerate, {
|
|
13762
|
+
name: "openrouter.embeddings.generate",
|
|
13763
|
+
type: "llm" /* LLM */,
|
|
13764
|
+
extractInput: (args) => {
|
|
13765
|
+
const request = getOpenRouterRequestArg(args);
|
|
13766
|
+
const requestBody = isObject(request?.requestBody) ? request.requestBody : {};
|
|
13767
|
+
const httpReferer = request?.httpReferer;
|
|
13768
|
+
const xTitle = request?.xTitle;
|
|
13769
|
+
const { input, ...metadata } = requestBody;
|
|
13770
|
+
return {
|
|
13771
|
+
input,
|
|
13772
|
+
metadata: buildOpenRouterEmbeddingMetadata(
|
|
13773
|
+
metadata,
|
|
13774
|
+
httpReferer,
|
|
13775
|
+
xTitle
|
|
13776
|
+
)
|
|
13777
|
+
};
|
|
13778
|
+
},
|
|
13779
|
+
extractOutput: (result) => {
|
|
13780
|
+
if (!isObject(result)) {
|
|
13781
|
+
return void 0;
|
|
13782
|
+
}
|
|
13783
|
+
const embedding = result.data?.[0]?.embedding;
|
|
13784
|
+
return Array.isArray(embedding) ? { embedding_length: embedding.length } : void 0;
|
|
13785
|
+
},
|
|
13786
|
+
extractMetadata: (result) => {
|
|
13787
|
+
if (!isObject(result)) {
|
|
13788
|
+
return void 0;
|
|
13789
|
+
}
|
|
13790
|
+
return extractOpenRouterResponseMetadata(result);
|
|
13791
|
+
},
|
|
13792
|
+
extractMetrics: (result) => {
|
|
13793
|
+
return isObject(result) ? parseOpenRouterMetricsFromUsage(result.usage) : {};
|
|
13794
|
+
}
|
|
13795
|
+
})
|
|
13796
|
+
);
|
|
13797
|
+
this.unsubscribers.push(
|
|
13798
|
+
traceStreamingChannel(openRouterChannels.betaResponsesSend, {
|
|
13799
|
+
name: "openrouter.beta.responses.send",
|
|
13800
|
+
type: "llm" /* LLM */,
|
|
13801
|
+
extractInput: (args) => {
|
|
13802
|
+
const request = getOpenRouterRequestArg(args);
|
|
13803
|
+
const openResponsesRequest = isObject(request?.openResponsesRequest) ? request.openResponsesRequest : {};
|
|
13804
|
+
const httpReferer = request?.httpReferer;
|
|
13805
|
+
const xTitle = request?.xTitle;
|
|
13806
|
+
const { input, ...metadata } = openResponsesRequest;
|
|
13807
|
+
return {
|
|
13808
|
+
input,
|
|
13809
|
+
metadata: buildOpenRouterMetadata(metadata, httpReferer, xTitle)
|
|
13810
|
+
};
|
|
13811
|
+
},
|
|
13812
|
+
extractOutput: (result) => extractOpenRouterResponseOutput(result),
|
|
13813
|
+
extractMetadata: (result) => extractOpenRouterResponseMetadata(result),
|
|
13814
|
+
extractMetrics: (result, startTime) => {
|
|
13815
|
+
const metrics = parseOpenRouterMetricsFromUsage(result?.usage);
|
|
13816
|
+
if (startTime) {
|
|
13817
|
+
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
13818
|
+
}
|
|
13819
|
+
return metrics;
|
|
13820
|
+
},
|
|
13821
|
+
aggregateChunks: aggregateOpenRouterResponseStreamEvents
|
|
13822
|
+
})
|
|
13823
|
+
);
|
|
13824
|
+
this.unsubscribers.push(
|
|
13825
|
+
traceSyncStreamChannel(openRouterChannels.callModel, {
|
|
13826
|
+
name: "openrouter.callModel",
|
|
13827
|
+
type: "llm" /* LLM */,
|
|
13828
|
+
extractInput: (args) => {
|
|
13829
|
+
const request = getOpenRouterCallModelRequestArg(args);
|
|
13830
|
+
return {
|
|
13831
|
+
input: request ? extractOpenRouterCallModelInput(request) : void 0,
|
|
13832
|
+
metadata: request ? extractOpenRouterCallModelMetadata(request) : { provider: "openrouter" }
|
|
13833
|
+
};
|
|
13834
|
+
},
|
|
13835
|
+
patchResult: ({ endEvent, result, span }) => {
|
|
13836
|
+
return patchOpenRouterCallModelResult(
|
|
13837
|
+
span,
|
|
13838
|
+
result,
|
|
13839
|
+
getOpenRouterCallModelRequestArg(endEvent.arguments)
|
|
13840
|
+
);
|
|
13841
|
+
}
|
|
13842
|
+
})
|
|
13843
|
+
);
|
|
13844
|
+
this.unsubscribers.push(
|
|
13845
|
+
traceStreamingChannel(openRouterChannels.toolExecute, {
|
|
13846
|
+
name: "openrouter.tool",
|
|
13847
|
+
type: "tool" /* TOOL */,
|
|
13848
|
+
extractInput: (args, event) => ({
|
|
13849
|
+
input: args[0],
|
|
13850
|
+
metadata: {
|
|
13851
|
+
provider: "openrouter",
|
|
13852
|
+
tool_name: event.toolName,
|
|
13853
|
+
...event.toolCallId ? { tool_call_id: event.toolCallId } : {}
|
|
13854
|
+
}
|
|
13855
|
+
}),
|
|
13856
|
+
extractOutput: (result) => result,
|
|
13857
|
+
extractMetrics: () => ({}),
|
|
13858
|
+
aggregateChunks: (chunks) => ({
|
|
13859
|
+
output: chunks.length > 0 ? chunks[chunks.length - 1] : void 0,
|
|
13860
|
+
metrics: {}
|
|
13861
|
+
})
|
|
13862
|
+
})
|
|
13863
|
+
);
|
|
13864
|
+
const callModelChannel = openRouterChannels.callModel.tracingChannel();
|
|
13865
|
+
const callModelHandlers = {
|
|
13866
|
+
start: (event) => {
|
|
13867
|
+
const request = getOpenRouterCallModelRequestArg(event.arguments);
|
|
13868
|
+
if (!request) {
|
|
13869
|
+
return;
|
|
13870
|
+
}
|
|
13871
|
+
patchOpenRouterCallModelRequestTools(request);
|
|
13872
|
+
}
|
|
13873
|
+
};
|
|
13874
|
+
callModelChannel.subscribe(callModelHandlers);
|
|
13875
|
+
this.unsubscribers.push(() => {
|
|
13876
|
+
callModelChannel.unsubscribe(callModelHandlers);
|
|
13877
|
+
});
|
|
12157
13878
|
}
|
|
12158
|
-
|
|
12159
|
-
|
|
12160
|
-
if (
|
|
12161
|
-
|
|
13879
|
+
};
|
|
13880
|
+
function normalizeArgs(args) {
|
|
13881
|
+
if (Array.isArray(args)) {
|
|
13882
|
+
return args;
|
|
12162
13883
|
}
|
|
12163
|
-
if (
|
|
12164
|
-
|
|
13884
|
+
if (isArrayLike(args)) {
|
|
13885
|
+
return Array.from(args);
|
|
12165
13886
|
}
|
|
12166
|
-
|
|
12167
|
-
|
|
12168
|
-
|
|
12169
|
-
|
|
12170
|
-
|
|
12171
|
-
|
|
12172
|
-
|
|
12173
|
-
|
|
12174
|
-
|
|
12175
|
-
|
|
12176
|
-
|
|
12177
|
-
|
|
13887
|
+
return [args];
|
|
13888
|
+
}
|
|
13889
|
+
function isArrayLike(value) {
|
|
13890
|
+
return isObject(value) && "length" in value && typeof value.length === "number" && Number.isInteger(value.length) && value.length >= 0;
|
|
13891
|
+
}
|
|
13892
|
+
function getOpenRouterRequestArg(args) {
|
|
13893
|
+
const normalizedArgs = normalizeArgs(args);
|
|
13894
|
+
const keyedCandidate = normalizedArgs.find(
|
|
13895
|
+
(arg) => isObject(arg) && ("chatGenerationParams" in arg || "requestBody" in arg || "openResponsesRequest" in arg)
|
|
13896
|
+
);
|
|
13897
|
+
if (isObject(keyedCandidate)) {
|
|
13898
|
+
return keyedCandidate;
|
|
13899
|
+
}
|
|
13900
|
+
const firstObjectArg = normalizedArgs.find((arg) => isObject(arg));
|
|
13901
|
+
return isObject(firstObjectArg) ? firstObjectArg : void 0;
|
|
13902
|
+
}
|
|
13903
|
+
function getOpenRouterCallModelRequestArg(args) {
|
|
13904
|
+
const firstObjectArg = normalizeArgs(args).find((arg) => isObject(arg));
|
|
13905
|
+
return isObject(firstObjectArg) ? firstObjectArg : void 0;
|
|
13906
|
+
}
|
|
13907
|
+
function aggregateOpenRouterChatChunks(chunks) {
|
|
13908
|
+
let role;
|
|
13909
|
+
let content = "";
|
|
13910
|
+
let toolCalls;
|
|
13911
|
+
let finishReason;
|
|
13912
|
+
let metrics = {};
|
|
13913
|
+
for (const chunk of chunks) {
|
|
13914
|
+
metrics = {
|
|
13915
|
+
...metrics,
|
|
13916
|
+
...parseOpenRouterMetricsFromUsage(chunk?.usage)
|
|
13917
|
+
};
|
|
13918
|
+
const choice = chunk?.choices?.[0];
|
|
13919
|
+
const delta = choice?.delta;
|
|
13920
|
+
if (!delta) {
|
|
13921
|
+
if (choice?.finish_reason !== void 0) {
|
|
13922
|
+
finishReason = choice.finish_reason;
|
|
12178
13923
|
}
|
|
12179
|
-
|
|
12180
|
-
|
|
13924
|
+
continue;
|
|
13925
|
+
}
|
|
13926
|
+
if (!role && delta.role) {
|
|
13927
|
+
role = delta.role;
|
|
13928
|
+
}
|
|
13929
|
+
if (typeof delta.content === "string") {
|
|
13930
|
+
content += delta.content;
|
|
13931
|
+
}
|
|
13932
|
+
const choiceFinishReason = choice?.finishReason ?? choice?.finish_reason ?? void 0;
|
|
13933
|
+
const deltaFinishReason = delta.finishReason ?? delta.finish_reason ?? void 0;
|
|
13934
|
+
if (choiceFinishReason !== void 0) {
|
|
13935
|
+
finishReason = choiceFinishReason;
|
|
13936
|
+
} else if (deltaFinishReason !== void 0) {
|
|
13937
|
+
finishReason = deltaFinishReason;
|
|
13938
|
+
}
|
|
13939
|
+
const toolCallDeltas = Array.isArray(delta.toolCalls) ? delta.toolCalls : Array.isArray(delta.tool_calls) ? delta.tool_calls : void 0;
|
|
13940
|
+
if (!toolCallDeltas) {
|
|
13941
|
+
continue;
|
|
13942
|
+
}
|
|
13943
|
+
for (const toolDelta of toolCallDeltas) {
|
|
13944
|
+
if (!toolDelta?.function) {
|
|
13945
|
+
continue;
|
|
12181
13946
|
}
|
|
12182
|
-
|
|
13947
|
+
const toolIndex = toolDelta.index ?? 0;
|
|
13948
|
+
const existingToolCall = toolCalls?.[toolIndex];
|
|
13949
|
+
if (!existingToolCall || toolDelta.id && existingToolCall.id !== void 0 && existingToolCall.id !== toolDelta.id) {
|
|
13950
|
+
const nextToolCalls = [...toolCalls || []];
|
|
13951
|
+
nextToolCalls[toolIndex] = {
|
|
13952
|
+
index: toolIndex,
|
|
13953
|
+
id: toolDelta.id,
|
|
13954
|
+
type: toolDelta.type,
|
|
13955
|
+
function: {
|
|
13956
|
+
name: toolDelta.function.name,
|
|
13957
|
+
arguments: toolDelta.function.arguments || ""
|
|
13958
|
+
}
|
|
13959
|
+
};
|
|
13960
|
+
toolCalls = nextToolCalls;
|
|
13961
|
+
continue;
|
|
13962
|
+
}
|
|
13963
|
+
const current = existingToolCall;
|
|
13964
|
+
if (toolDelta.id && !current.id) {
|
|
13965
|
+
current.id = toolDelta.id;
|
|
13966
|
+
}
|
|
13967
|
+
if (toolDelta.type && !current.type) {
|
|
13968
|
+
current.type = toolDelta.type;
|
|
13969
|
+
}
|
|
13970
|
+
if (toolDelta.function.name && !current.function.name) {
|
|
13971
|
+
current.function.name = toolDelta.function.name;
|
|
13972
|
+
}
|
|
13973
|
+
current.function.arguments += toolDelta.function.arguments || "";
|
|
12183
13974
|
}
|
|
12184
|
-
output.candidates = candidates;
|
|
12185
|
-
}
|
|
12186
|
-
if (usageMetadata) {
|
|
12187
|
-
output.usageMetadata = usageMetadata;
|
|
12188
|
-
populateUsageMetrics(metrics, usageMetadata);
|
|
12189
|
-
}
|
|
12190
|
-
if (text) {
|
|
12191
|
-
output.text = text;
|
|
12192
13975
|
}
|
|
12193
|
-
return {
|
|
13976
|
+
return {
|
|
13977
|
+
output: [
|
|
13978
|
+
{
|
|
13979
|
+
index: 0,
|
|
13980
|
+
message: {
|
|
13981
|
+
role,
|
|
13982
|
+
content: content || void 0,
|
|
13983
|
+
...toolCalls ? { tool_calls: toolCalls } : {}
|
|
13984
|
+
},
|
|
13985
|
+
logprobs: null,
|
|
13986
|
+
finish_reason: finishReason
|
|
13987
|
+
}
|
|
13988
|
+
],
|
|
13989
|
+
metrics
|
|
13990
|
+
};
|
|
12194
13991
|
}
|
|
12195
|
-
function
|
|
12196
|
-
|
|
12197
|
-
|
|
12198
|
-
|
|
12199
|
-
|
|
12200
|
-
|
|
12201
|
-
|
|
12202
|
-
|
|
13992
|
+
function aggregateOpenRouterResponseStreamEvents(chunks) {
|
|
13993
|
+
let finalResponse;
|
|
13994
|
+
for (const chunk of chunks) {
|
|
13995
|
+
const response = chunk?.response;
|
|
13996
|
+
if (!response) {
|
|
13997
|
+
continue;
|
|
13998
|
+
}
|
|
13999
|
+
if (chunk.type === "response.completed" || chunk.type === "response.incomplete" || chunk.type === "response.failed") {
|
|
14000
|
+
finalResponse = response;
|
|
12203
14001
|
}
|
|
12204
|
-
return obj;
|
|
12205
14002
|
}
|
|
12206
|
-
|
|
14003
|
+
if (!finalResponse) {
|
|
14004
|
+
return {
|
|
14005
|
+
output: void 0,
|
|
14006
|
+
metrics: {}
|
|
14007
|
+
};
|
|
14008
|
+
}
|
|
14009
|
+
return {
|
|
14010
|
+
output: extractOpenRouterResponseOutput(finalResponse),
|
|
14011
|
+
metrics: parseOpenRouterMetricsFromUsage(finalResponse.usage),
|
|
14012
|
+
...extractOpenRouterResponseMetadata(finalResponse) ? { metadata: extractOpenRouterResponseMetadata(finalResponse) } : {}
|
|
14013
|
+
};
|
|
12207
14014
|
}
|
|
12208
14015
|
|
|
12209
14016
|
// src/instrumentation/braintrust-plugin.ts
|
|
@@ -12214,6 +14021,7 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
12214
14021
|
aiSDKPlugin = null;
|
|
12215
14022
|
claudeAgentSDKPlugin = null;
|
|
12216
14023
|
googleGenAIPlugin = null;
|
|
14024
|
+
openRouterPlugin = null;
|
|
12217
14025
|
constructor(config = {}) {
|
|
12218
14026
|
super();
|
|
12219
14027
|
this.config = config;
|
|
@@ -12240,6 +14048,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
12240
14048
|
this.googleGenAIPlugin = new GoogleGenAIPlugin();
|
|
12241
14049
|
this.googleGenAIPlugin.enable();
|
|
12242
14050
|
}
|
|
14051
|
+
if (integrations.openrouter !== false) {
|
|
14052
|
+
this.openRouterPlugin = new OpenRouterPlugin();
|
|
14053
|
+
this.openRouterPlugin.enable();
|
|
14054
|
+
}
|
|
12243
14055
|
}
|
|
12244
14056
|
onDisable() {
|
|
12245
14057
|
if (this.openaiPlugin) {
|
|
@@ -12262,6 +14074,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
12262
14074
|
this.googleGenAIPlugin.disable();
|
|
12263
14075
|
this.googleGenAIPlugin = null;
|
|
12264
14076
|
}
|
|
14077
|
+
if (this.openRouterPlugin) {
|
|
14078
|
+
this.openRouterPlugin.disable();
|
|
14079
|
+
this.openRouterPlugin = null;
|
|
14080
|
+
}
|
|
12265
14081
|
}
|
|
12266
14082
|
};
|
|
12267
14083
|
|
|
@@ -12333,7 +14149,8 @@ var PluginRegistry = class {
|
|
|
12333
14149
|
vercel: true,
|
|
12334
14150
|
aisdk: true,
|
|
12335
14151
|
google: true,
|
|
12336
|
-
claudeAgentSDK: true
|
|
14152
|
+
claudeAgentSDK: true,
|
|
14153
|
+
openrouter: true
|
|
12337
14154
|
};
|
|
12338
14155
|
}
|
|
12339
14156
|
/**
|
|
@@ -12357,6 +14174,62 @@ function configureInstrumentation(config) {
|
|
|
12357
14174
|
registry.configure(config);
|
|
12358
14175
|
}
|
|
12359
14176
|
|
|
14177
|
+
// src/auto-instrumentations/patch-tracing-channel.ts
|
|
14178
|
+
function patchTracingChannel(tracingChannelFn) {
|
|
14179
|
+
const dummyChannel = tracingChannelFn("__braintrust_probe__");
|
|
14180
|
+
const TracingChannel = dummyChannel?.constructor;
|
|
14181
|
+
if (!TracingChannel?.prototype) {
|
|
14182
|
+
return;
|
|
14183
|
+
}
|
|
14184
|
+
if (!Object.getOwnPropertyDescriptor(TracingChannel.prototype, "hasSubscribers")) {
|
|
14185
|
+
Object.defineProperty(TracingChannel.prototype, "hasSubscribers", {
|
|
14186
|
+
configurable: true,
|
|
14187
|
+
enumerable: false,
|
|
14188
|
+
get() {
|
|
14189
|
+
return Boolean(
|
|
14190
|
+
this.start?.hasSubscribers || this.end?.hasSubscribers || this.asyncStart?.hasSubscribers || this.asyncEnd?.hasSubscribers || this.error?.hasSubscribers
|
|
14191
|
+
);
|
|
14192
|
+
}
|
|
14193
|
+
});
|
|
14194
|
+
}
|
|
14195
|
+
if (TracingChannel.prototype.tracePromise) {
|
|
14196
|
+
TracingChannel.prototype.tracePromise = function(fn, context = {}, thisArg, ...args) {
|
|
14197
|
+
const { start, end, asyncStart, asyncEnd, error } = this;
|
|
14198
|
+
function reject2(err) {
|
|
14199
|
+
context.error = err;
|
|
14200
|
+
error?.publish(context);
|
|
14201
|
+
asyncStart?.publish(context);
|
|
14202
|
+
asyncEnd?.publish(context);
|
|
14203
|
+
return Promise.reject(err);
|
|
14204
|
+
}
|
|
14205
|
+
function resolve(result) {
|
|
14206
|
+
context.result = result;
|
|
14207
|
+
asyncStart?.publish(context);
|
|
14208
|
+
asyncEnd?.publish(context);
|
|
14209
|
+
return result;
|
|
14210
|
+
}
|
|
14211
|
+
return start.runStores(context, () => {
|
|
14212
|
+
try {
|
|
14213
|
+
const result = Reflect.apply(fn, thisArg, args);
|
|
14214
|
+
end?.publish(context);
|
|
14215
|
+
if (result && (typeof result === "object" || typeof result === "function") && typeof result.then === "function") {
|
|
14216
|
+
return result.then(resolve, reject2);
|
|
14217
|
+
}
|
|
14218
|
+
context.result = result;
|
|
14219
|
+
asyncStart?.publish(context);
|
|
14220
|
+
asyncEnd?.publish(context);
|
|
14221
|
+
return result;
|
|
14222
|
+
} catch (err) {
|
|
14223
|
+
context.error = err;
|
|
14224
|
+
error?.publish(context);
|
|
14225
|
+
end?.publish(context);
|
|
14226
|
+
throw err;
|
|
14227
|
+
}
|
|
14228
|
+
});
|
|
14229
|
+
};
|
|
14230
|
+
}
|
|
14231
|
+
}
|
|
14232
|
+
|
|
12360
14233
|
// src/browser/config.ts
|
|
12361
14234
|
var browserConfigured = false;
|
|
12362
14235
|
function configureBrowser() {
|
|
@@ -12371,6 +14244,7 @@ function configureBrowser() {
|
|
|
12371
14244
|
} catch {
|
|
12372
14245
|
}
|
|
12373
14246
|
isomorph_default.newTracingChannel = (nameOrChannels) => (0, import_dc_browser.tracingChannel)(nameOrChannels);
|
|
14247
|
+
patchTracingChannel(import_dc_browser.tracingChannel);
|
|
12374
14248
|
isomorph_default.getEnv = (name) => {
|
|
12375
14249
|
if (typeof process === "undefined" || typeof process.env === "undefined") {
|
|
12376
14250
|
return void 0;
|
|
@@ -12525,6 +14399,7 @@ __export(exports_exports, {
|
|
|
12525
14399
|
wrapMastraAgent: () => wrapMastraAgent,
|
|
12526
14400
|
wrapOpenAI: () => wrapOpenAI,
|
|
12527
14401
|
wrapOpenAIv4: () => wrapOpenAIv4,
|
|
14402
|
+
wrapOpenRouter: () => wrapOpenRouter,
|
|
12528
14403
|
wrapTraced: () => wrapTraced,
|
|
12529
14404
|
wrapVitest: () => wrapVitest
|
|
12530
14405
|
});
|
|
@@ -12855,7 +14730,7 @@ function wrapOpenAIv4(openai) {
|
|
|
12855
14730
|
return baseVal;
|
|
12856
14731
|
}
|
|
12857
14732
|
});
|
|
12858
|
-
const
|
|
14733
|
+
const chatProxy2 = new Proxy(typedOpenai.chat, {
|
|
12859
14734
|
get(target, name, receiver) {
|
|
12860
14735
|
if (name === "completions") {
|
|
12861
14736
|
return completionProxy;
|
|
@@ -12865,7 +14740,7 @@ function wrapOpenAIv4(openai) {
|
|
|
12865
14740
|
});
|
|
12866
14741
|
const embeddingProxy = createEndpointProxy(typedOpenai.embeddings, wrapEmbeddings);
|
|
12867
14742
|
const moderationProxy = createEndpointProxy(typedOpenai.moderations, wrapModerations);
|
|
12868
|
-
let
|
|
14743
|
+
let betaProxy3;
|
|
12869
14744
|
if (typedOpenai.beta?.chat?.completions?.stream) {
|
|
12870
14745
|
const betaChatCompletionProxy = new Proxy(
|
|
12871
14746
|
typedOpenai?.beta?.chat.completions,
|
|
@@ -12889,7 +14764,7 @@ function wrapOpenAIv4(openai) {
|
|
|
12889
14764
|
return Reflect.get(target, name, receiver);
|
|
12890
14765
|
}
|
|
12891
14766
|
});
|
|
12892
|
-
|
|
14767
|
+
betaProxy3 = new Proxy(typedOpenai.beta, {
|
|
12893
14768
|
get(target, name, receiver) {
|
|
12894
14769
|
if (name === "chat") {
|
|
12895
14770
|
return betaChatProxy;
|
|
@@ -12902,7 +14777,7 @@ function wrapOpenAIv4(openai) {
|
|
|
12902
14777
|
get(target, name, receiver) {
|
|
12903
14778
|
switch (name) {
|
|
12904
14779
|
case "chat":
|
|
12905
|
-
return
|
|
14780
|
+
return chatProxy2;
|
|
12906
14781
|
case "embeddings":
|
|
12907
14782
|
return embeddingProxy;
|
|
12908
14783
|
case "moderations":
|
|
@@ -12910,8 +14785,8 @@ function wrapOpenAIv4(openai) {
|
|
|
12910
14785
|
case "responses":
|
|
12911
14786
|
return responsesProxy(typedOpenai);
|
|
12912
14787
|
}
|
|
12913
|
-
if (name === "beta" &&
|
|
12914
|
-
return
|
|
14788
|
+
if (name === "beta" && betaProxy3) {
|
|
14789
|
+
return betaProxy3;
|
|
12915
14790
|
}
|
|
12916
14791
|
return Reflect.get(target, name, receiver);
|
|
12917
14792
|
}
|
|
@@ -12994,35 +14869,28 @@ function createEndpointProxy(target, wrapperFn) {
|
|
|
12994
14869
|
});
|
|
12995
14870
|
}
|
|
12996
14871
|
function wrapApiCreateWithChannel(create, channel2) {
|
|
12997
|
-
return
|
|
14872
|
+
return (allParams, options) => {
|
|
12998
14873
|
const { span_info, params } = splitSpanInfo(allParams);
|
|
12999
|
-
|
|
13000
|
-
const
|
|
13001
|
-
|
|
13002
|
-
|
|
13003
|
-
|
|
13004
|
-
|
|
13005
|
-
|
|
14874
|
+
let executionPromise = null;
|
|
14875
|
+
const ensureExecuted = () => {
|
|
14876
|
+
if (!executionPromise) {
|
|
14877
|
+
executionPromise = (async () => {
|
|
14878
|
+
const traceContext = createChannelContext(channel2, params, span_info);
|
|
14879
|
+
return tracePromiseWithResponse(
|
|
14880
|
+
channel2,
|
|
14881
|
+
traceContext,
|
|
14882
|
+
create(params, options)
|
|
14883
|
+
);
|
|
14884
|
+
})();
|
|
14885
|
+
}
|
|
14886
|
+
return executionPromise;
|
|
14887
|
+
};
|
|
14888
|
+
return createLazyAPIPromise(ensureExecuted);
|
|
13006
14889
|
};
|
|
13007
14890
|
}
|
|
13008
14891
|
var wrapEmbeddings = (create) => wrapApiCreateWithChannel(create, openAIChannels.embeddingsCreate);
|
|
13009
14892
|
var wrapModerations = (create) => wrapApiCreateWithChannel(create, openAIChannels.moderationsCreate);
|
|
13010
14893
|
|
|
13011
|
-
// src/zod/utils.ts
|
|
13012
|
-
var import_zod_to_json_schema = require("zod-to-json-schema");
|
|
13013
|
-
var z42 = __toESM(require("zod/v4"));
|
|
13014
|
-
function isZodV4(zodObject) {
|
|
13015
|
-
return typeof zodObject === "object" && zodObject !== null && "_zod" in zodObject && zodObject._zod !== void 0;
|
|
13016
|
-
}
|
|
13017
|
-
function zodToJsonSchema(schema) {
|
|
13018
|
-
if (isZodV4(schema)) {
|
|
13019
|
-
return z42.toJSONSchema(schema, {
|
|
13020
|
-
target: "draft-7"
|
|
13021
|
-
});
|
|
13022
|
-
}
|
|
13023
|
-
return (0, import_zod_to_json_schema.zodToJsonSchema)(schema);
|
|
13024
|
-
}
|
|
13025
|
-
|
|
13026
14894
|
// src/wrappers/ai-sdk/ai-sdk.ts
|
|
13027
14895
|
var DENY_OUTPUT_PATHS = [
|
|
13028
14896
|
// v3
|
|
@@ -13117,9 +14985,11 @@ var wrapAgentGenerate = (generate, instance, options = {}) => {
|
|
|
13117
14985
|
return async (params) => makeGenerateTextWrapper(
|
|
13118
14986
|
`${instance.constructor.name}.generate`,
|
|
13119
14987
|
options,
|
|
13120
|
-
generate.bind(instance)
|
|
14988
|
+
generate.bind(instance),
|
|
13121
14989
|
// as of v5 this is just streamText under the hood
|
|
13122
14990
|
// Follows what the AI SDK does under the hood when calling generateText
|
|
14991
|
+
void 0,
|
|
14992
|
+
"function" /* FUNCTION */
|
|
13123
14993
|
)({ ...instance.settings, ...params });
|
|
13124
14994
|
};
|
|
13125
14995
|
var wrapAgentStream = (stream, instance, options = {}) => {
|
|
@@ -13128,11 +14998,12 @@ var wrapAgentStream = (stream, instance, options = {}) => {
|
|
|
13128
14998
|
options,
|
|
13129
14999
|
stream.bind(instance),
|
|
13130
15000
|
// as of v5 this is just streamText under the hood
|
|
13131
|
-
void 0
|
|
15001
|
+
void 0,
|
|
13132
15002
|
// aiSDK not needed since model is already on instance
|
|
15003
|
+
"function" /* FUNCTION */
|
|
13133
15004
|
)({ ...instance.settings, ...params });
|
|
13134
15005
|
};
|
|
13135
|
-
var makeGenerateTextWrapper = (name, options, generateText, aiSDK) => {
|
|
15006
|
+
var makeGenerateTextWrapper = (name, options, generateText, aiSDK, spanType = "llm" /* LLM */) => {
|
|
13136
15007
|
const wrapper = async function(allParams) {
|
|
13137
15008
|
const { span_info, ...params } = allParams;
|
|
13138
15009
|
const {
|
|
@@ -13141,6 +15012,7 @@ var makeGenerateTextWrapper = (name, options, generateText, aiSDK) => {
|
|
|
13141
15012
|
spanAttributes: spanInfoAttrs
|
|
13142
15013
|
} = span_info ?? {};
|
|
13143
15014
|
const { model, provider } = serializeModelWithProvider2(params.model);
|
|
15015
|
+
const serializedTools = serializeAISDKToolsForLogging(params.tools);
|
|
13144
15016
|
const processedInput = await processInputAttachments2(params);
|
|
13145
15017
|
return traced(
|
|
13146
15018
|
async (span) => {
|
|
@@ -13153,7 +15025,7 @@ var makeGenerateTextWrapper = (name, options, generateText, aiSDK) => {
|
|
|
13153
15025
|
model: wrappedModel,
|
|
13154
15026
|
tools: wrapTools(params.tools)
|
|
13155
15027
|
});
|
|
13156
|
-
const gatewayInfo =
|
|
15028
|
+
const gatewayInfo = extractGatewayRoutingInfo2(result);
|
|
13157
15029
|
const resolvedMetadata = {};
|
|
13158
15030
|
if (gatewayInfo?.provider) {
|
|
13159
15031
|
resolvedMetadata.provider = gatewayInfo.provider;
|
|
@@ -13171,7 +15043,7 @@ var makeGenerateTextWrapper = (name, options, generateText, aiSDK) => {
|
|
|
13171
15043
|
{
|
|
13172
15044
|
name: spanName || name,
|
|
13173
15045
|
spanAttributes: {
|
|
13174
|
-
type:
|
|
15046
|
+
type: spanType,
|
|
13175
15047
|
...spanInfoAttrs
|
|
13176
15048
|
},
|
|
13177
15049
|
event: {
|
|
@@ -13180,6 +15052,7 @@ var makeGenerateTextWrapper = (name, options, generateText, aiSDK) => {
|
|
|
13180
15052
|
...spanInfoMetadata,
|
|
13181
15053
|
model,
|
|
13182
15054
|
...provider ? { provider } : {},
|
|
15055
|
+
...serializedTools ? { tools: serializedTools } : {},
|
|
13183
15056
|
braintrust: {
|
|
13184
15057
|
integration_name: "ai-sdk",
|
|
13185
15058
|
sdk_language: "typescript"
|
|
@@ -13214,11 +15087,12 @@ var wrapModel = (model, ai) => {
|
|
|
13214
15087
|
const originalDoStream = resolvedModel.doStream?.bind(resolvedModel);
|
|
13215
15088
|
const { model: modelId, provider } = serializeModelWithProvider2(resolvedModel);
|
|
13216
15089
|
const wrappedDoGenerate = async (options) => {
|
|
15090
|
+
const serializedTools = serializeAISDKToolsForLogging(options.tools);
|
|
13217
15091
|
const processedInput = await processInputAttachments2(options);
|
|
13218
15092
|
return traced(
|
|
13219
15093
|
async (span) => {
|
|
13220
15094
|
const result = await originalDoGenerate(options);
|
|
13221
|
-
const gatewayInfo =
|
|
15095
|
+
const gatewayInfo = extractGatewayRoutingInfo2(result);
|
|
13222
15096
|
const resolvedMetadata = {};
|
|
13223
15097
|
if (gatewayInfo?.provider) {
|
|
13224
15098
|
resolvedMetadata.provider = gatewayInfo.provider;
|
|
@@ -13246,6 +15120,7 @@ var wrapModel = (model, ai) => {
|
|
|
13246
15120
|
metadata: {
|
|
13247
15121
|
model: modelId,
|
|
13248
15122
|
...provider ? { provider } : {},
|
|
15123
|
+
...serializedTools ? { tools: serializedTools } : {},
|
|
13249
15124
|
braintrust: {
|
|
13250
15125
|
integration_name: "ai-sdk",
|
|
13251
15126
|
sdk_language: "typescript"
|
|
@@ -13258,6 +15133,7 @@ var wrapModel = (model, ai) => {
|
|
|
13258
15133
|
const wrappedDoStream = async (options) => {
|
|
13259
15134
|
const startTime = Date.now();
|
|
13260
15135
|
let receivedFirst = false;
|
|
15136
|
+
const serializedTools = serializeAISDKToolsForLogging(options.tools);
|
|
13261
15137
|
const processedInput = await processInputAttachments2(options);
|
|
13262
15138
|
const span = startSpan({
|
|
13263
15139
|
name: "doStream",
|
|
@@ -13269,6 +15145,7 @@ var wrapModel = (model, ai) => {
|
|
|
13269
15145
|
metadata: {
|
|
13270
15146
|
model: modelId,
|
|
13271
15147
|
...provider ? { provider } : {},
|
|
15148
|
+
...serializedTools ? { tools: serializedTools } : {},
|
|
13272
15149
|
braintrust: {
|
|
13273
15150
|
integration_name: "ai-sdk",
|
|
13274
15151
|
sdk_language: "typescript"
|
|
@@ -13282,7 +15159,7 @@ var wrapModel = (model, ai) => {
|
|
|
13282
15159
|
let reasoning = "";
|
|
13283
15160
|
const toolCalls = [];
|
|
13284
15161
|
let object = void 0;
|
|
13285
|
-
const
|
|
15162
|
+
const extractTextDelta2 = (chunk) => {
|
|
13286
15163
|
if (typeof chunk.textDelta === "string") return chunk.textDelta;
|
|
13287
15164
|
if (typeof chunk.delta === "string") return chunk.delta;
|
|
13288
15165
|
if (typeof chunk.text === "string") return chunk.text;
|
|
@@ -13301,7 +15178,7 @@ var wrapModel = (model, ai) => {
|
|
|
13301
15178
|
}
|
|
13302
15179
|
switch (chunk.type) {
|
|
13303
15180
|
case "text-delta":
|
|
13304
|
-
text +=
|
|
15181
|
+
text += extractTextDelta2(chunk);
|
|
13305
15182
|
break;
|
|
13306
15183
|
case "reasoning-delta":
|
|
13307
15184
|
if (chunk.delta) {
|
|
@@ -13339,7 +15216,7 @@ var wrapModel = (model, ai) => {
|
|
|
13339
15216
|
if (object !== void 0) {
|
|
13340
15217
|
output.object = object;
|
|
13341
15218
|
}
|
|
13342
|
-
const gatewayInfo =
|
|
15219
|
+
const gatewayInfo = extractGatewayRoutingInfo2(output);
|
|
13343
15220
|
const resolvedMetadata = {};
|
|
13344
15221
|
if (gatewayInfo?.provider) {
|
|
13345
15222
|
resolvedMetadata.provider = gatewayInfo.provider;
|
|
@@ -13401,6 +15278,7 @@ var wrapGenerateObject = (generateObject, options = {}, aiSDK) => {
|
|
|
13401
15278
|
spanAttributes: spanInfoAttrs
|
|
13402
15279
|
} = span_info ?? {};
|
|
13403
15280
|
const { model, provider } = serializeModelWithProvider2(params.model);
|
|
15281
|
+
const serializedTools = serializeAISDKToolsForLogging(params.tools);
|
|
13404
15282
|
const processedInput = await processInputAttachments2(params);
|
|
13405
15283
|
return traced(
|
|
13406
15284
|
async (span) => {
|
|
@@ -13414,7 +15292,7 @@ var wrapGenerateObject = (generateObject, options = {}, aiSDK) => {
|
|
|
13414
15292
|
tools: wrapTools(params.tools)
|
|
13415
15293
|
});
|
|
13416
15294
|
const output = await processOutput(result, options.denyOutputPaths);
|
|
13417
|
-
const gatewayInfo =
|
|
15295
|
+
const gatewayInfo = extractGatewayRoutingInfo2(result);
|
|
13418
15296
|
const resolvedMetadata = {};
|
|
13419
15297
|
if (gatewayInfo?.provider) {
|
|
13420
15298
|
resolvedMetadata.provider = gatewayInfo.provider;
|
|
@@ -13441,6 +15319,7 @@ var wrapGenerateObject = (generateObject, options = {}, aiSDK) => {
|
|
|
13441
15319
|
...spanInfoMetadata,
|
|
13442
15320
|
model,
|
|
13443
15321
|
...provider ? { provider } : {},
|
|
15322
|
+
...serializedTools ? { tools: serializedTools } : {},
|
|
13444
15323
|
braintrust: {
|
|
13445
15324
|
integration_name: "ai-sdk",
|
|
13446
15325
|
sdk_language: "typescript"
|
|
@@ -13451,7 +15330,7 @@ var wrapGenerateObject = (generateObject, options = {}, aiSDK) => {
|
|
|
13451
15330
|
);
|
|
13452
15331
|
};
|
|
13453
15332
|
};
|
|
13454
|
-
var makeStreamTextWrapper = (name, options, streamText, aiSDK) => {
|
|
15333
|
+
var makeStreamTextWrapper = (name, options, streamText, aiSDK, spanType = "llm" /* LLM */) => {
|
|
13455
15334
|
const wrapper = function(allParams) {
|
|
13456
15335
|
const { span_info, ...params } = allParams;
|
|
13457
15336
|
const {
|
|
@@ -13460,11 +15339,12 @@ var makeStreamTextWrapper = (name, options, streamText, aiSDK) => {
|
|
|
13460
15339
|
spanAttributes: spanInfoAttrs
|
|
13461
15340
|
} = span_info ?? {};
|
|
13462
15341
|
const { model, provider } = serializeModelWithProvider2(params.model);
|
|
15342
|
+
const serializedTools = serializeAISDKToolsForLogging(params.tools);
|
|
13463
15343
|
const { input: processedInput, outputPromise } = processInputAttachmentsSync(params);
|
|
13464
15344
|
const span = startSpan({
|
|
13465
15345
|
name: spanName || name,
|
|
13466
15346
|
spanAttributes: {
|
|
13467
|
-
type:
|
|
15347
|
+
type: spanType,
|
|
13468
15348
|
...spanInfoAttrs
|
|
13469
15349
|
},
|
|
13470
15350
|
event: {
|
|
@@ -13473,6 +15353,7 @@ var makeStreamTextWrapper = (name, options, streamText, aiSDK) => {
|
|
|
13473
15353
|
...spanInfoMetadata,
|
|
13474
15354
|
model,
|
|
13475
15355
|
...provider ? { provider } : {},
|
|
15356
|
+
...serializedTools ? { tools: serializedTools } : {},
|
|
13476
15357
|
braintrust: {
|
|
13477
15358
|
integration_name: "ai-sdk",
|
|
13478
15359
|
sdk_language: "typescript"
|
|
@@ -13512,7 +15393,7 @@ var makeStreamTextWrapper = (name, options, streamText, aiSDK) => {
|
|
|
13512
15393
|
},
|
|
13513
15394
|
onFinish: async (event) => {
|
|
13514
15395
|
params.onFinish?.(event);
|
|
13515
|
-
const gatewayInfo =
|
|
15396
|
+
const gatewayInfo = extractGatewayRoutingInfo2(event);
|
|
13516
15397
|
const resolvedMetadata = {};
|
|
13517
15398
|
if (gatewayInfo?.provider) {
|
|
13518
15399
|
resolvedMetadata.provider = gatewayInfo.provider;
|
|
@@ -13588,6 +15469,7 @@ var wrapStreamObject = (streamObject, options = {}, aiSDK) => {
|
|
|
13588
15469
|
spanAttributes: spanInfoAttrs
|
|
13589
15470
|
} = span_info ?? {};
|
|
13590
15471
|
const { model, provider } = serializeModelWithProvider2(params.model);
|
|
15472
|
+
const serializedTools = serializeAISDKToolsForLogging(params.tools);
|
|
13591
15473
|
const { input: processedInput, outputPromise } = processInputAttachmentsSync(params);
|
|
13592
15474
|
const span = startSpan({
|
|
13593
15475
|
name: spanName || "streamObject",
|
|
@@ -13601,6 +15483,7 @@ var wrapStreamObject = (streamObject, options = {}, aiSDK) => {
|
|
|
13601
15483
|
...spanInfoMetadata,
|
|
13602
15484
|
model,
|
|
13603
15485
|
...provider ? { provider } : {},
|
|
15486
|
+
...serializedTools ? { tools: serializedTools } : {},
|
|
13604
15487
|
braintrust: {
|
|
13605
15488
|
integration_name: "ai-sdk",
|
|
13606
15489
|
sdk_language: "typescript"
|
|
@@ -13640,7 +15523,7 @@ var wrapStreamObject = (streamObject, options = {}, aiSDK) => {
|
|
|
13640
15523
|
},
|
|
13641
15524
|
onFinish: async (event) => {
|
|
13642
15525
|
params.onFinish?.(event);
|
|
13643
|
-
const gatewayInfo =
|
|
15526
|
+
const gatewayInfo = extractGatewayRoutingInfo2(event);
|
|
13644
15527
|
const resolvedMetadata = {};
|
|
13645
15528
|
if (gatewayInfo?.provider) {
|
|
13646
15529
|
resolvedMetadata.provider = gatewayInfo.provider;
|
|
@@ -13717,7 +15600,7 @@ var wrapTools = (tools) => {
|
|
|
13717
15600
|
}
|
|
13718
15601
|
return wrappedTools;
|
|
13719
15602
|
};
|
|
13720
|
-
var
|
|
15603
|
+
var isAsyncGenerator2 = (value) => {
|
|
13721
15604
|
return value != null && typeof value === "object" && typeof value[Symbol.asyncIterator] === "function" && typeof value.next === "function" && typeof value.return === "function" && typeof value.throw === "function";
|
|
13722
15605
|
};
|
|
13723
15606
|
var wrapToolExecute = (tool, name) => {
|
|
@@ -13728,7 +15611,7 @@ var wrapToolExecute = (tool, name) => {
|
|
|
13728
15611
|
if (prop === "execute") {
|
|
13729
15612
|
const wrappedExecute = (...args) => {
|
|
13730
15613
|
const result = originalExecute.apply(target, args);
|
|
13731
|
-
if (
|
|
15614
|
+
if (isAsyncGenerator2(result)) {
|
|
13732
15615
|
return (async function* () {
|
|
13733
15616
|
const span = startSpan({
|
|
13734
15617
|
name,
|
|
@@ -13848,7 +15731,7 @@ function serializeModelWithProvider2(model) {
|
|
|
13848
15731
|
provider: explicitProvider || parsed.provider
|
|
13849
15732
|
};
|
|
13850
15733
|
}
|
|
13851
|
-
function
|
|
15734
|
+
function extractGatewayRoutingInfo2(result) {
|
|
13852
15735
|
if (result?.steps && Array.isArray(result.steps) && result.steps.length > 0) {
|
|
13853
15736
|
const routing2 = result.steps[0]?.providerMetadata?.gateway?.routing;
|
|
13854
15737
|
if (routing2) {
|
|
@@ -13867,10 +15750,10 @@ function extractGatewayRoutingInfo(result) {
|
|
|
13867
15750
|
}
|
|
13868
15751
|
return null;
|
|
13869
15752
|
}
|
|
13870
|
-
var
|
|
15753
|
+
var isZodSchema3 = (value) => {
|
|
13871
15754
|
return value != null && typeof value === "object" && "_def" in value && typeof value._def === "object";
|
|
13872
15755
|
};
|
|
13873
|
-
var
|
|
15756
|
+
var serializeZodSchema3 = (schema) => {
|
|
13874
15757
|
try {
|
|
13875
15758
|
return zodToJsonSchema(schema);
|
|
13876
15759
|
} catch {
|
|
@@ -13880,34 +15763,6 @@ var serializeZodSchema = (schema) => {
|
|
|
13880
15763
|
};
|
|
13881
15764
|
}
|
|
13882
15765
|
};
|
|
13883
|
-
var processTools = (tools) => {
|
|
13884
|
-
if (!tools || typeof tools !== "object") return tools;
|
|
13885
|
-
if (Array.isArray(tools)) {
|
|
13886
|
-
return tools.map(processTool);
|
|
13887
|
-
}
|
|
13888
|
-
const processed = {};
|
|
13889
|
-
for (const [key, tool] of Object.entries(tools)) {
|
|
13890
|
-
processed[key] = processTool(tool);
|
|
13891
|
-
}
|
|
13892
|
-
return processed;
|
|
13893
|
-
};
|
|
13894
|
-
var processTool = (tool) => {
|
|
13895
|
-
if (!tool || typeof tool !== "object") return tool;
|
|
13896
|
-
const processed = { ...tool };
|
|
13897
|
-
if (isZodSchema(processed.inputSchema)) {
|
|
13898
|
-
processed.inputSchema = serializeZodSchema(processed.inputSchema);
|
|
13899
|
-
}
|
|
13900
|
-
if (isZodSchema(processed.parameters)) {
|
|
13901
|
-
processed.parameters = serializeZodSchema(processed.parameters);
|
|
13902
|
-
}
|
|
13903
|
-
if ("execute" in processed) {
|
|
13904
|
-
processed.execute = "[Function]";
|
|
13905
|
-
}
|
|
13906
|
-
if ("render" in processed) {
|
|
13907
|
-
processed.render = "[Function]";
|
|
13908
|
-
}
|
|
13909
|
-
return processed;
|
|
13910
|
-
};
|
|
13911
15766
|
var isOutputObject = (value) => {
|
|
13912
15767
|
if (value == null || typeof value !== "object") {
|
|
13913
15768
|
return false;
|
|
@@ -13946,10 +15801,10 @@ var serializeOutputObject = (output, model) => {
|
|
|
13946
15801
|
if (typeof responseFormat.then === "function") {
|
|
13947
15802
|
result.response_format = Promise.resolve(responseFormat).then(
|
|
13948
15803
|
(resolved) => {
|
|
13949
|
-
if (resolved.schema &&
|
|
15804
|
+
if (resolved.schema && isZodSchema3(resolved.schema)) {
|
|
13950
15805
|
return {
|
|
13951
15806
|
...resolved,
|
|
13952
|
-
schema:
|
|
15807
|
+
schema: serializeZodSchema3(resolved.schema)
|
|
13953
15808
|
};
|
|
13954
15809
|
}
|
|
13955
15810
|
return resolved;
|
|
@@ -13957,10 +15812,10 @@ var serializeOutputObject = (output, model) => {
|
|
|
13957
15812
|
);
|
|
13958
15813
|
} else {
|
|
13959
15814
|
const syncResponseFormat = responseFormat;
|
|
13960
|
-
if (syncResponseFormat.schema &&
|
|
15815
|
+
if (syncResponseFormat.schema && isZodSchema3(syncResponseFormat.schema)) {
|
|
13961
15816
|
responseFormat = {
|
|
13962
15817
|
...syncResponseFormat,
|
|
13963
|
-
schema:
|
|
15818
|
+
schema: serializeZodSchema3(syncResponseFormat.schema)
|
|
13964
15819
|
};
|
|
13965
15820
|
}
|
|
13966
15821
|
result.response_format = responseFormat;
|
|
@@ -13986,14 +15841,14 @@ var processInputAttachmentsSync = (input) => {
|
|
|
13986
15841
|
processed.prompt = processPromptContent(input.prompt);
|
|
13987
15842
|
}
|
|
13988
15843
|
}
|
|
13989
|
-
if (input.
|
|
13990
|
-
processed.
|
|
15844
|
+
if (input.schema && isZodSchema3(input.schema)) {
|
|
15845
|
+
processed.schema = serializeZodSchema3(input.schema);
|
|
13991
15846
|
}
|
|
13992
|
-
if (input.
|
|
13993
|
-
processed.
|
|
15847
|
+
if (input.callOptionsSchema && isZodSchema3(input.callOptionsSchema)) {
|
|
15848
|
+
processed.callOptionsSchema = serializeZodSchema3(input.callOptionsSchema);
|
|
13994
15849
|
}
|
|
13995
|
-
if (input.
|
|
13996
|
-
processed.
|
|
15850
|
+
if (input.tools) {
|
|
15851
|
+
processed.tools = serializeAISDKToolsForLogging(input.tools);
|
|
13997
15852
|
}
|
|
13998
15853
|
let outputPromise;
|
|
13999
15854
|
if (input.output && isOutputObject(input.output)) {
|
|
@@ -14027,14 +15882,14 @@ var processInputAttachments2 = async (input) => {
|
|
|
14027
15882
|
processed.prompt = processPromptContent(input.prompt);
|
|
14028
15883
|
}
|
|
14029
15884
|
}
|
|
14030
|
-
if (input.
|
|
14031
|
-
processed.
|
|
15885
|
+
if (input.schema && isZodSchema3(input.schema)) {
|
|
15886
|
+
processed.schema = serializeZodSchema3(input.schema);
|
|
14032
15887
|
}
|
|
14033
|
-
if (input.
|
|
14034
|
-
processed.
|
|
15888
|
+
if (input.callOptionsSchema && isZodSchema3(input.callOptionsSchema)) {
|
|
15889
|
+
processed.callOptionsSchema = serializeZodSchema3(input.callOptionsSchema);
|
|
14035
15890
|
}
|
|
14036
|
-
if (input.
|
|
14037
|
-
processed.
|
|
15891
|
+
if (input.tools) {
|
|
15892
|
+
processed.tools = serializeAISDKToolsForLogging(input.tools);
|
|
14038
15893
|
}
|
|
14039
15894
|
if (input.output && isOutputObject(input.output)) {
|
|
14040
15895
|
const serialized = serializeOutputObject(input.output, input.model);
|
|
@@ -14235,7 +16090,9 @@ var processOutput = async (output, denyOutputPaths) => {
|
|
|
14235
16090
|
const getterValues = extractGetterValues2(output);
|
|
14236
16091
|
const processed = await processOutputAttachments(output);
|
|
14237
16092
|
const merged = { ...processed, ...getterValues };
|
|
14238
|
-
return
|
|
16093
|
+
return normalizeAISDKLoggedOutput(
|
|
16094
|
+
omit2(merged, denyOutputPaths ?? DENY_OUTPUT_PATHS)
|
|
16095
|
+
);
|
|
14239
16096
|
};
|
|
14240
16097
|
var processOutputAttachments = async (output) => {
|
|
14241
16098
|
try {
|
|
@@ -14798,14 +16655,14 @@ function extractModelFromResult(result) {
|
|
|
14798
16655
|
function extractModelFromWrapGenerateCallback(model) {
|
|
14799
16656
|
return model?.modelId;
|
|
14800
16657
|
}
|
|
14801
|
-
function
|
|
16658
|
+
function camelToSnake2(str) {
|
|
14802
16659
|
return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
|
|
14803
16660
|
}
|
|
14804
16661
|
function extractModelParameters(params, excludeKeys) {
|
|
14805
16662
|
const modelParams = {};
|
|
14806
16663
|
for (const [key, value] of Object.entries(params)) {
|
|
14807
16664
|
if (value !== void 0 && !excludeKeys.has(key)) {
|
|
14808
|
-
const snakeKey =
|
|
16665
|
+
const snakeKey = camelToSnake2(key);
|
|
14809
16666
|
modelParams[snakeKey] = value;
|
|
14810
16667
|
}
|
|
14811
16668
|
}
|
|
@@ -15665,7 +17522,7 @@ function filterSerializableOptions2(options) {
|
|
|
15665
17522
|
}
|
|
15666
17523
|
return filtered;
|
|
15667
17524
|
}
|
|
15668
|
-
function
|
|
17525
|
+
function isAsyncIterable3(value) {
|
|
15669
17526
|
return value !== null && typeof value === "object" && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
15670
17527
|
}
|
|
15671
17528
|
function wrapClaudeAgentQuery(queryFn, defaultThis) {
|
|
@@ -15673,7 +17530,7 @@ function wrapClaudeAgentQuery(queryFn, defaultThis) {
|
|
|
15673
17530
|
apply(target, thisArg, argArray) {
|
|
15674
17531
|
const params = argArray[0] ?? {};
|
|
15675
17532
|
const { prompt, options = {} } = params;
|
|
15676
|
-
const promptIsAsyncIterable =
|
|
17533
|
+
const promptIsAsyncIterable = isAsyncIterable3(prompt);
|
|
15677
17534
|
let capturedPromptMessages;
|
|
15678
17535
|
let promptForQuery = prompt;
|
|
15679
17536
|
let promptStarted = false;
|
|
@@ -16293,11 +18150,13 @@ function serializeInput2(params) {
|
|
|
16293
18150
|
if (params.config) {
|
|
16294
18151
|
const config = tryToDict2(params.config);
|
|
16295
18152
|
if (config) {
|
|
16296
|
-
const
|
|
16297
|
-
|
|
16298
|
-
|
|
16299
|
-
|
|
16300
|
-
|
|
18153
|
+
const filteredConfig = {};
|
|
18154
|
+
Object.keys(config).forEach((key) => {
|
|
18155
|
+
if (key !== "tools") {
|
|
18156
|
+
filteredConfig[key] = config[key];
|
|
18157
|
+
}
|
|
18158
|
+
});
|
|
18159
|
+
input.config = filteredConfig;
|
|
16301
18160
|
}
|
|
16302
18161
|
}
|
|
16303
18162
|
return input;
|
|
@@ -16378,6 +18237,10 @@ function extractMetadata2(params) {
|
|
|
16378
18237
|
});
|
|
16379
18238
|
}
|
|
16380
18239
|
}
|
|
18240
|
+
const tools = serializeTools2(params);
|
|
18241
|
+
if (tools) {
|
|
18242
|
+
metadata.tools = tools;
|
|
18243
|
+
}
|
|
16381
18244
|
return metadata;
|
|
16382
18245
|
}
|
|
16383
18246
|
function extractGenerateContentMetrics2(response, start) {
|
|
@@ -16516,6 +18379,111 @@ function tryToDict2(obj) {
|
|
|
16516
18379
|
return null;
|
|
16517
18380
|
}
|
|
16518
18381
|
|
|
18382
|
+
// src/wrappers/openrouter.ts
|
|
18383
|
+
function wrapOpenRouter(openrouter) {
|
|
18384
|
+
const or = openrouter;
|
|
18385
|
+
if (or && typeof or === "object" && ("chat" in or && typeof or.chat === "object" && or.chat && "send" in or.chat && "embeddings" in or && typeof or.embeddings === "object" && or.embeddings && "generate" in or.embeddings || "callModel" in or && typeof or.callModel === "function")) {
|
|
18386
|
+
return openRouterProxy(or);
|
|
18387
|
+
}
|
|
18388
|
+
console.warn("Unsupported OpenRouter library. Not wrapping.");
|
|
18389
|
+
return openrouter;
|
|
18390
|
+
}
|
|
18391
|
+
function openRouterProxy(openrouter) {
|
|
18392
|
+
return new Proxy(openrouter, {
|
|
18393
|
+
get(target, prop, receiver) {
|
|
18394
|
+
switch (prop) {
|
|
18395
|
+
case "chat":
|
|
18396
|
+
return target.chat ? chatProxy(target.chat) : target.chat;
|
|
18397
|
+
case "embeddings":
|
|
18398
|
+
return target.embeddings ? embeddingsProxy(target.embeddings) : target.embeddings;
|
|
18399
|
+
case "beta":
|
|
18400
|
+
return target.beta ? betaProxy2(target.beta) : target.beta;
|
|
18401
|
+
case "callModel":
|
|
18402
|
+
return typeof target.callModel === "function" ? wrapCallModel(target.callModel.bind(target)) : target.callModel;
|
|
18403
|
+
default:
|
|
18404
|
+
return Reflect.get(target, prop, receiver);
|
|
18405
|
+
}
|
|
18406
|
+
}
|
|
18407
|
+
});
|
|
18408
|
+
}
|
|
18409
|
+
function betaProxy2(beta) {
|
|
18410
|
+
return new Proxy(beta, {
|
|
18411
|
+
get(target, prop, receiver) {
|
|
18412
|
+
if (prop === "responses") {
|
|
18413
|
+
return target.responses ? responsesProxy2(target.responses) : void 0;
|
|
18414
|
+
}
|
|
18415
|
+
return Reflect.get(target, prop, receiver);
|
|
18416
|
+
}
|
|
18417
|
+
});
|
|
18418
|
+
}
|
|
18419
|
+
function chatProxy(chat) {
|
|
18420
|
+
return new Proxy(chat, {
|
|
18421
|
+
get(target, prop, receiver) {
|
|
18422
|
+
if (prop === "send") {
|
|
18423
|
+
return wrapChatSend(target.send.bind(target));
|
|
18424
|
+
}
|
|
18425
|
+
return Reflect.get(target, prop, receiver);
|
|
18426
|
+
}
|
|
18427
|
+
});
|
|
18428
|
+
}
|
|
18429
|
+
function embeddingsProxy(embeddings) {
|
|
18430
|
+
return new Proxy(embeddings, {
|
|
18431
|
+
get(target, prop, receiver) {
|
|
18432
|
+
if (prop === "generate") {
|
|
18433
|
+
return wrapEmbeddingsGenerate(target.generate.bind(target));
|
|
18434
|
+
}
|
|
18435
|
+
return Reflect.get(target, prop, receiver);
|
|
18436
|
+
}
|
|
18437
|
+
});
|
|
18438
|
+
}
|
|
18439
|
+
function responsesProxy2(responses) {
|
|
18440
|
+
return new Proxy(responses, {
|
|
18441
|
+
get(target, prop, receiver) {
|
|
18442
|
+
if (prop === "send") {
|
|
18443
|
+
return wrapResponsesSend(target.send.bind(target));
|
|
18444
|
+
}
|
|
18445
|
+
return Reflect.get(target, prop, receiver);
|
|
18446
|
+
}
|
|
18447
|
+
});
|
|
18448
|
+
}
|
|
18449
|
+
function wrapChatSend(send) {
|
|
18450
|
+
return (request, options) => openRouterChannels.chatSend.tracePromise(() => send(request, options), {
|
|
18451
|
+
arguments: [request]
|
|
18452
|
+
});
|
|
18453
|
+
}
|
|
18454
|
+
function wrapEmbeddingsGenerate(generate) {
|
|
18455
|
+
return (request, options) => openRouterChannels.embeddingsGenerate.tracePromise(
|
|
18456
|
+
() => generate(request, options),
|
|
18457
|
+
{ arguments: [request] }
|
|
18458
|
+
);
|
|
18459
|
+
}
|
|
18460
|
+
function wrapResponsesSend(send) {
|
|
18461
|
+
return (request, options) => openRouterChannels.betaResponsesSend.tracePromise(
|
|
18462
|
+
() => send(request, options),
|
|
18463
|
+
{ arguments: [request] }
|
|
18464
|
+
);
|
|
18465
|
+
}
|
|
18466
|
+
function wrapCallModel(callModel) {
|
|
18467
|
+
return (request, options) => {
|
|
18468
|
+
const patchedRequest = { ...request };
|
|
18469
|
+
patchOpenRouterCallModelRequestTools(patchedRequest);
|
|
18470
|
+
const span = startOpenRouterCallModelSpan(patchedRequest);
|
|
18471
|
+
try {
|
|
18472
|
+
const result = callModel(patchedRequest, options);
|
|
18473
|
+
if (!patchOpenRouterCallModelResult(span, result, patchedRequest)) {
|
|
18474
|
+
span.end();
|
|
18475
|
+
}
|
|
18476
|
+
return result;
|
|
18477
|
+
} catch (error) {
|
|
18478
|
+
span.log({
|
|
18479
|
+
error: error instanceof Error ? error.message : String(error)
|
|
18480
|
+
});
|
|
18481
|
+
span.end();
|
|
18482
|
+
throw error;
|
|
18483
|
+
}
|
|
18484
|
+
};
|
|
18485
|
+
}
|
|
18486
|
+
|
|
16519
18487
|
// src/wrappers/vitest/context-manager.ts
|
|
16520
18488
|
var VitestContextManager = class {
|
|
16521
18489
|
/**
|
|
@@ -17415,7 +19383,7 @@ function unescapePath(path) {
|
|
|
17415
19383
|
}
|
|
17416
19384
|
var graph_framework_default = { createGraph };
|
|
17417
19385
|
|
|
17418
|
-
// ../node_modules/async/dist/async.mjs
|
|
19386
|
+
// ../node_modules/.pnpm/async@3.2.5/node_modules/async/dist/async.mjs
|
|
17419
19387
|
function initialParams(fn) {
|
|
17420
19388
|
return function(...args) {
|
|
17421
19389
|
var callback = args.pop();
|
|
@@ -17483,10 +19451,10 @@ function invokeCallback(callback, error, value) {
|
|
|
17483
19451
|
function isAsync(fn) {
|
|
17484
19452
|
return fn[Symbol.toStringTag] === "AsyncFunction";
|
|
17485
19453
|
}
|
|
17486
|
-
function
|
|
19454
|
+
function isAsyncGenerator3(fn) {
|
|
17487
19455
|
return fn[Symbol.toStringTag] === "AsyncGenerator";
|
|
17488
19456
|
}
|
|
17489
|
-
function
|
|
19457
|
+
function isAsyncIterable4(obj) {
|
|
17490
19458
|
return typeof obj[Symbol.asyncIterator] === "function";
|
|
17491
19459
|
}
|
|
17492
19460
|
function wrapAsync(asyncFn) {
|
|
@@ -17536,10 +19504,11 @@ function _asyncMap(eachfn, arr, iteratee, callback) {
|
|
|
17536
19504
|
callback(err, results);
|
|
17537
19505
|
});
|
|
17538
19506
|
}
|
|
17539
|
-
function
|
|
19507
|
+
function isArrayLike2(value) {
|
|
17540
19508
|
return value && typeof value.length === "number" && value.length >= 0 && value.length % 1 === 0;
|
|
17541
19509
|
}
|
|
17542
19510
|
var breakLoop = {};
|
|
19511
|
+
var breakLoop$1 = breakLoop;
|
|
17543
19512
|
function once(fn) {
|
|
17544
19513
|
function wrapper(...args) {
|
|
17545
19514
|
if (fn === null) return;
|
|
@@ -17583,7 +19552,7 @@ function createObjectIterator(obj) {
|
|
|
17583
19552
|
};
|
|
17584
19553
|
}
|
|
17585
19554
|
function createIterator(coll) {
|
|
17586
|
-
if (
|
|
19555
|
+
if (isArrayLike2(coll)) {
|
|
17587
19556
|
return createArrayIterator(coll);
|
|
17588
19557
|
}
|
|
17589
19558
|
var iterator = getIterator(coll);
|
|
@@ -17631,7 +19600,7 @@ function asyncEachOfLimit(generator, limit, iteratee, callback) {
|
|
|
17631
19600
|
canceled = true;
|
|
17632
19601
|
return;
|
|
17633
19602
|
}
|
|
17634
|
-
if (result === breakLoop || done && running <= 0) {
|
|
19603
|
+
if (result === breakLoop$1 || done && running <= 0) {
|
|
17635
19604
|
done = true;
|
|
17636
19605
|
return callback(null);
|
|
17637
19606
|
}
|
|
@@ -17654,10 +19623,10 @@ var eachOfLimit$2 = (limit) => {
|
|
|
17654
19623
|
if (!obj) {
|
|
17655
19624
|
return callback(null);
|
|
17656
19625
|
}
|
|
17657
|
-
if (
|
|
19626
|
+
if (isAsyncGenerator3(obj)) {
|
|
17658
19627
|
return asyncEachOfLimit(obj, limit, iteratee, callback);
|
|
17659
19628
|
}
|
|
17660
|
-
if (
|
|
19629
|
+
if (isAsyncIterable4(obj)) {
|
|
17661
19630
|
return asyncEachOfLimit(obj[Symbol.asyncIterator](), limit, iteratee, callback);
|
|
17662
19631
|
}
|
|
17663
19632
|
var nextElem = createIterator(obj);
|
|
@@ -17674,7 +19643,7 @@ var eachOfLimit$2 = (limit) => {
|
|
|
17674
19643
|
} else if (err === false) {
|
|
17675
19644
|
done = true;
|
|
17676
19645
|
canceled = true;
|
|
17677
|
-
} else if (value === breakLoop || done && running <= 0) {
|
|
19646
|
+
} else if (value === breakLoop$1 || done && running <= 0) {
|
|
17678
19647
|
done = true;
|
|
17679
19648
|
return callback(null);
|
|
17680
19649
|
} else if (!looping) {
|
|
@@ -17717,7 +19686,7 @@ function eachOfArrayLike(coll, iteratee, callback) {
|
|
|
17717
19686
|
if (canceled === true) return;
|
|
17718
19687
|
if (err) {
|
|
17719
19688
|
callback(err);
|
|
17720
|
-
} else if (++completed === length || value === breakLoop) {
|
|
19689
|
+
} else if (++completed === length || value === breakLoop$1) {
|
|
17721
19690
|
callback(null);
|
|
17722
19691
|
}
|
|
17723
19692
|
}
|
|
@@ -17729,7 +19698,7 @@ function eachOfGeneric(coll, iteratee, callback) {
|
|
|
17729
19698
|
return eachOfLimit$1(coll, Infinity, iteratee, callback);
|
|
17730
19699
|
}
|
|
17731
19700
|
function eachOf(coll, iteratee, callback) {
|
|
17732
|
-
var eachOfImplementation =
|
|
19701
|
+
var eachOfImplementation = isArrayLike2(coll) ? eachOfArrayLike : eachOfGeneric;
|
|
17733
19702
|
return eachOfImplementation(coll, wrapAsync(iteratee), callback);
|
|
17734
19703
|
}
|
|
17735
19704
|
var eachOf$1 = awaitify(eachOf, 3);
|
|
@@ -18113,7 +20082,7 @@ function _createTester(check, getResult) {
|
|
|
18113
20082
|
if (check(result) && !testResult) {
|
|
18114
20083
|
testPassed = true;
|
|
18115
20084
|
testResult = getResult(true, value);
|
|
18116
|
-
return callback(null, breakLoop);
|
|
20085
|
+
return callback(null, breakLoop$1);
|
|
18117
20086
|
}
|
|
18118
20087
|
callback();
|
|
18119
20088
|
});
|
|
@@ -18244,7 +20213,7 @@ function filterGeneric(eachfn, coll, iteratee, callback) {
|
|
|
18244
20213
|
});
|
|
18245
20214
|
}
|
|
18246
20215
|
function _filter(eachfn, coll, iteratee, callback) {
|
|
18247
|
-
var filter2 =
|
|
20216
|
+
var filter2 = isArrayLike2(coll) ? filterArray : filterGeneric;
|
|
18248
20217
|
return filter2(eachfn, coll, wrapAsync(iteratee), callback);
|
|
18249
20218
|
}
|
|
18250
20219
|
function filter(coll, iteratee, callback) {
|
|
@@ -18319,7 +20288,7 @@ if (hasNextTick) {
|
|
|
18319
20288
|
}
|
|
18320
20289
|
var nextTick = wrap(_defer);
|
|
18321
20290
|
var _parallel = awaitify((eachfn, tasks, callback) => {
|
|
18322
|
-
var results =
|
|
20291
|
+
var results = isArrayLike2(tasks) ? [] : {};
|
|
18323
20292
|
eachfn(tasks, (task, key, taskCb) => {
|
|
18324
20293
|
wrapAsync(task)((err, ...result) => {
|
|
18325
20294
|
if (result.length < 2) {
|
|
@@ -18737,7 +20706,8 @@ var promptDefinitionSchema = promptContentsSchema.and(
|
|
|
18737
20706
|
import_v310.z.object({
|
|
18738
20707
|
model: import_v310.z.string(),
|
|
18739
20708
|
params: ModelParams.optional(),
|
|
18740
|
-
templateFormat: import_v310.z.enum(["mustache", "nunjucks", "none"]).optional()
|
|
20709
|
+
templateFormat: import_v310.z.enum(["mustache", "nunjucks", "none"]).optional(),
|
|
20710
|
+
environments: import_v310.z.array(import_v310.z.string()).optional()
|
|
18741
20711
|
})
|
|
18742
20712
|
);
|
|
18743
20713
|
var promptDefinitionWithToolsSchema = promptDefinitionSchema.and(
|
|
@@ -18896,6 +20866,22 @@ function initExperiment2(state, options = {}) {
|
|
|
18896
20866
|
setCurrent: false
|
|
18897
20867
|
});
|
|
18898
20868
|
}
|
|
20869
|
+
async function getExperimentParametersRef(parameters) {
|
|
20870
|
+
if (!parameters) {
|
|
20871
|
+
return void 0;
|
|
20872
|
+
}
|
|
20873
|
+
const resolvedParameters = parameters instanceof Promise ? await parameters : parameters;
|
|
20874
|
+
if (!RemoteEvalParameters.isParameters(resolvedParameters)) {
|
|
20875
|
+
return void 0;
|
|
20876
|
+
}
|
|
20877
|
+
if (resolvedParameters.id === void 0) {
|
|
20878
|
+
return void 0;
|
|
20879
|
+
}
|
|
20880
|
+
return {
|
|
20881
|
+
id: resolvedParameters.id,
|
|
20882
|
+
version: resolvedParameters.version
|
|
20883
|
+
};
|
|
20884
|
+
}
|
|
18899
20885
|
function callEvaluatorData(data) {
|
|
18900
20886
|
const dataResult = typeof data === "function" ? data() : data;
|
|
18901
20887
|
let baseExperiment = void 0;
|
|
@@ -18907,7 +20893,7 @@ function callEvaluatorData(data) {
|
|
|
18907
20893
|
baseExperiment
|
|
18908
20894
|
};
|
|
18909
20895
|
}
|
|
18910
|
-
function
|
|
20896
|
+
function isAsyncIterable5(value) {
|
|
18911
20897
|
return typeof value === "object" && value !== null && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
18912
20898
|
}
|
|
18913
20899
|
function isIterable(value) {
|
|
@@ -18962,6 +20948,7 @@ async function Eval(name, evaluator, reporterOrOpts) {
|
|
|
18962
20948
|
const { data, baseExperiment: defaultBaseExperiment } = callEvaluatorData(
|
|
18963
20949
|
evaluator.data
|
|
18964
20950
|
);
|
|
20951
|
+
const parameters = await getExperimentParametersRef(evaluator.parameters);
|
|
18965
20952
|
const experiment = options.parent || options.noSendLogs ? null : initExperiment2(evaluator.state, {
|
|
18966
20953
|
...evaluator.projectId ? { projectId: evaluator.projectId } : { project: name },
|
|
18967
20954
|
experiment: evaluator.experimentName,
|
|
@@ -18974,7 +20961,8 @@ async function Eval(name, evaluator, reporterOrOpts) {
|
|
|
18974
20961
|
baseExperimentId: evaluator.baseExperimentId,
|
|
18975
20962
|
gitMetadataSettings: evaluator.gitMetadataSettings,
|
|
18976
20963
|
repoInfo: evaluator.repoInfo,
|
|
18977
|
-
dataset: Dataset2.isDataset(data) ? data : void 0
|
|
20964
|
+
dataset: Dataset2.isDataset(data) ? data : void 0,
|
|
20965
|
+
parameters
|
|
18978
20966
|
});
|
|
18979
20967
|
if (experiment && typeof process !== "undefined" && globalThis.BRAINTRUST_CONTEXT_MANAGER !== void 0) {
|
|
18980
20968
|
await experiment._waitForId();
|
|
@@ -19029,7 +21017,7 @@ async function Eval(name, evaluator, reporterOrOpts) {
|
|
|
19029
21017
|
if (experiment) {
|
|
19030
21018
|
await experiment.flush().catch(console.error);
|
|
19031
21019
|
} else if (options.parent) {
|
|
19032
|
-
await flush().catch(console.error);
|
|
21020
|
+
await flush({ state: evaluator.state }).catch(console.error);
|
|
19033
21021
|
}
|
|
19034
21022
|
}
|
|
19035
21023
|
} finally {
|
|
@@ -19129,7 +21117,7 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
|
|
|
19129
21117
|
}
|
|
19130
21118
|
const resolvedDataResult = dataResult instanceof Promise ? await dataResult : dataResult;
|
|
19131
21119
|
const dataIterable = (() => {
|
|
19132
|
-
if (
|
|
21120
|
+
if (isAsyncIterable5(resolvedDataResult)) {
|
|
19133
21121
|
return resolvedDataResult;
|
|
19134
21122
|
}
|
|
19135
21123
|
if (Array.isArray(resolvedDataResult) || isIterable(resolvedDataResult)) {
|
|
@@ -19417,6 +21405,7 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
|
|
|
19417
21405
|
},
|
|
19418
21406
|
Math.max(evaluator.maxConcurrency ?? Number.MAX_SAFE_INTEGER, 1)
|
|
19419
21407
|
);
|
|
21408
|
+
const queueErrors = [];
|
|
19420
21409
|
const enqueuePromise = (async () => {
|
|
19421
21410
|
for await (const datum of dataIterable) {
|
|
19422
21411
|
if (cancelled) {
|
|
@@ -19432,7 +21421,11 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
|
|
|
19432
21421
|
}
|
|
19433
21422
|
scheduledTrials++;
|
|
19434
21423
|
progressReporter.setTotal?.(evaluator.evalName, scheduledTrials);
|
|
19435
|
-
q.
|
|
21424
|
+
q.pushAsync({ datum, trialIndex }).catch((e) => {
|
|
21425
|
+
if (queueErrors.length < 5) {
|
|
21426
|
+
queueErrors.push(e);
|
|
21427
|
+
}
|
|
21428
|
+
});
|
|
19436
21429
|
}
|
|
19437
21430
|
}
|
|
19438
21431
|
})();
|
|
@@ -19480,6 +21473,12 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
|
|
|
19480
21473
|
})();
|
|
19481
21474
|
try {
|
|
19482
21475
|
await Promise.race([waitForQueue, cancel()]);
|
|
21476
|
+
if (queueErrors.length > 0) {
|
|
21477
|
+
throw new AggregateError(
|
|
21478
|
+
queueErrors,
|
|
21479
|
+
`Encountered ${queueErrors.length} unhandled task errors`
|
|
21480
|
+
);
|
|
21481
|
+
}
|
|
19483
21482
|
} catch (e) {
|
|
19484
21483
|
q.kill();
|
|
19485
21484
|
if (e instanceof InternalAbortError) {
|
|
@@ -19883,6 +21882,7 @@ var CodePrompt = class {
|
|
|
19883
21882
|
toolFunctions;
|
|
19884
21883
|
tags;
|
|
19885
21884
|
metadata;
|
|
21885
|
+
environmentSlugs;
|
|
19886
21886
|
constructor(project, prompt, toolFunctions, opts, functionType) {
|
|
19887
21887
|
this.project = project;
|
|
19888
21888
|
this.name = opts.name;
|
|
@@ -19895,6 +21895,7 @@ var CodePrompt = class {
|
|
|
19895
21895
|
this.functionType = functionType;
|
|
19896
21896
|
this.tags = opts.tags;
|
|
19897
21897
|
this.metadata = opts.metadata;
|
|
21898
|
+
this.environmentSlugs = opts.environments;
|
|
19898
21899
|
}
|
|
19899
21900
|
async toFunctionDefinition(projectNameToId) {
|
|
19900
21901
|
const prompt_data = {
|
|
@@ -19929,7 +21930,8 @@ var CodePrompt = class {
|
|
|
19929
21930
|
prompt_data,
|
|
19930
21931
|
if_exists: this.ifExists,
|
|
19931
21932
|
tags: this.tags,
|
|
19932
|
-
metadata: this.metadata
|
|
21933
|
+
metadata: this.metadata,
|
|
21934
|
+
environments: this.environmentSlugs && this.environmentSlugs.length > 0 ? this.environmentSlugs.map((slug) => ({ slug })) : void 0
|
|
19933
21935
|
};
|
|
19934
21936
|
}
|
|
19935
21937
|
};
|