braintrust 3.4.0 → 3.5.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 +45 -5
- package/dev/dist/index.d.ts +45 -5
- package/dev/dist/index.js +992 -245
- package/dev/dist/index.mjs +914 -167
- package/dist/auto-instrumentations/bundler/esbuild.cjs +208 -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 +208 -10
- package/dist/auto-instrumentations/bundler/rollup.mjs +2 -2
- package/dist/auto-instrumentations/bundler/vite.cjs +208 -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 +208 -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-LVWWLUMN.mjs → chunk-DQTPSXJB.mjs} +208 -10
- package/dist/auto-instrumentations/chunk-EVUKFMHG.mjs +41 -0
- package/dist/auto-instrumentations/{chunk-D5ZPIUEL.mjs → chunk-F3TJZ3Z2.mjs} +1 -1
- package/dist/auto-instrumentations/chunk-VLEJ5AEK.mjs +41 -0
- package/dist/auto-instrumentations/hook.mjs +238 -18
- package/dist/auto-instrumentations/index.cjs +208 -10
- package/dist/auto-instrumentations/index.mjs +1 -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 +342 -269
- package/dist/browser.d.ts +342 -269
- package/dist/browser.js +996 -241
- package/dist/browser.mjs +996 -241
- package/dist/cli.js +1029 -289
- package/dist/edge-light.js +1007 -220
- package/dist/edge-light.mjs +1007 -220
- package/dist/index.d.mts +342 -269
- package/dist/index.d.ts +342 -269
- package/dist/index.js +1182 -427
- package/dist/index.mjs +996 -241
- package/dist/instrumentation/index.js +781 -107
- package/dist/instrumentation/index.mjs +781 -107
- package/dist/workerd.js +1007 -220
- package/dist/workerd.mjs +1007 -220
- package/package.json +22 -6
- package/dist/auto-instrumentations/chunk-XDBPUTVE.mjs +0 -22
- package/dist/auto-instrumentations/chunk-ZEC7BCL4.mjs +0 -22
|
@@ -52,8 +52,54 @@ var DefaultAsyncLocalStorage = class {
|
|
|
52
52
|
return void 0;
|
|
53
53
|
}
|
|
54
54
|
};
|
|
55
|
-
var
|
|
55
|
+
var DefaultChannel = class {
|
|
56
|
+
constructor(name) {
|
|
57
|
+
this.name = name;
|
|
58
|
+
}
|
|
56
59
|
hasSubscribers = false;
|
|
60
|
+
subscribe(_subscription) {
|
|
61
|
+
}
|
|
62
|
+
unsubscribe(_subscription) {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
bindStore(_store, _transform) {
|
|
66
|
+
}
|
|
67
|
+
unbindStore(_store) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
publish(_message) {
|
|
71
|
+
}
|
|
72
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
73
|
+
runStores(_message, fn, thisArg, ...args) {
|
|
74
|
+
return fn.apply(thisArg, args);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
var DefaultTracingChannel = class {
|
|
78
|
+
start;
|
|
79
|
+
end;
|
|
80
|
+
asyncStart;
|
|
81
|
+
asyncEnd;
|
|
82
|
+
error;
|
|
83
|
+
constructor(nameOrChannels) {
|
|
84
|
+
if (typeof nameOrChannels === "string") {
|
|
85
|
+
this.start = new DefaultChannel(`tracing:${nameOrChannels}:start`);
|
|
86
|
+
this.end = new DefaultChannel(`tracing:${nameOrChannels}:end`);
|
|
87
|
+
this.asyncStart = new DefaultChannel(
|
|
88
|
+
`tracing:${nameOrChannels}:asyncStart`
|
|
89
|
+
);
|
|
90
|
+
this.asyncEnd = new DefaultChannel(`tracing:${nameOrChannels}:asyncEnd`);
|
|
91
|
+
this.error = new DefaultChannel(`tracing:${nameOrChannels}:error`);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
this.start = nameOrChannels.start ?? new DefaultChannel("tracing:start");
|
|
95
|
+
this.end = nameOrChannels.end ?? new DefaultChannel("tracing:end");
|
|
96
|
+
this.asyncStart = nameOrChannels.asyncStart ?? new DefaultChannel("tracing:asyncStart");
|
|
97
|
+
this.asyncEnd = nameOrChannels.asyncEnd ?? new DefaultChannel("tracing:asyncEnd");
|
|
98
|
+
this.error = nameOrChannels.error ?? new DefaultChannel("tracing:error");
|
|
99
|
+
}
|
|
100
|
+
get hasSubscribers() {
|
|
101
|
+
return this.start.hasSubscribers || this.end.hasSubscribers || this.asyncStart.hasSubscribers || this.asyncEnd.hasSubscribers || this.error.hasSubscribers;
|
|
102
|
+
}
|
|
57
103
|
subscribe(_handlers) {
|
|
58
104
|
}
|
|
59
105
|
unsubscribe(_handlers) {
|
|
@@ -81,7 +127,7 @@ var iso = {
|
|
|
81
127
|
getCallerLocation: () => void 0,
|
|
82
128
|
newAsyncLocalStorage: () => new DefaultAsyncLocalStorage(),
|
|
83
129
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
84
|
-
newTracingChannel: (
|
|
130
|
+
newTracingChannel: (nameOrChannels) => new DefaultTracingChannel(nameOrChannels),
|
|
85
131
|
processOn: (_0, _1) => {
|
|
86
132
|
},
|
|
87
133
|
basename: (filepath) => filepath.split(/[\\/]/).pop() || filepath,
|
|
@@ -2115,6 +2161,8 @@ var Experiment = import_v36.z.object({
|
|
|
2115
2161
|
deleted_at: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
|
|
2116
2162
|
dataset_id: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
|
|
2117
2163
|
dataset_version: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
|
|
2164
|
+
parameters_id: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
|
|
2165
|
+
parameters_version: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
|
|
2118
2166
|
public: import_v36.z.boolean(),
|
|
2119
2167
|
user_id: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
|
|
2120
2168
|
metadata: import_v36.z.union([import_v36.z.object({}).partial().passthrough(), import_v36.z.null()]).optional(),
|
|
@@ -2137,7 +2185,11 @@ var SpanType = import_v36.z.union([
|
|
|
2137
2185
|
import_v36.z.null()
|
|
2138
2186
|
]);
|
|
2139
2187
|
var SpanAttributes = import_v36.z.union([
|
|
2140
|
-
import_v36.z.object({
|
|
2188
|
+
import_v36.z.object({
|
|
2189
|
+
name: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]),
|
|
2190
|
+
type: SpanType,
|
|
2191
|
+
purpose: import_v36.z.union([import_v36.z.literal("scorer"), import_v36.z.null()])
|
|
2192
|
+
}).partial().passthrough(),
|
|
2141
2193
|
import_v36.z.null()
|
|
2142
2194
|
]);
|
|
2143
2195
|
var ExperimentEvent = import_v36.z.object({
|
|
@@ -2577,6 +2629,7 @@ var FunctionId = import_v36.z.union([
|
|
|
2577
2629
|
version: import_v36.z.string()
|
|
2578
2630
|
}),
|
|
2579
2631
|
code: import_v36.z.string(),
|
|
2632
|
+
function_type: FunctionTypeEnum.and(import_v36.z.unknown()).optional(),
|
|
2580
2633
|
name: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional()
|
|
2581
2634
|
}),
|
|
2582
2635
|
import_v36.z.object({
|
|
@@ -2806,7 +2859,12 @@ var TopicAutomationConfig = import_v36.z.object({
|
|
|
2806
2859
|
topic_map_functions: import_v36.z.array(TopicMapFunctionAutomation),
|
|
2807
2860
|
scope: import_v36.z.union([SpanScope, TraceScope, GroupScope, import_v36.z.null()]).optional(),
|
|
2808
2861
|
data_scope: TopicAutomationDataScope.optional(),
|
|
2809
|
-
btql_filter: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional()
|
|
2862
|
+
btql_filter: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
|
|
2863
|
+
backfill_time_range: import_v36.z.union([
|
|
2864
|
+
import_v36.z.string(),
|
|
2865
|
+
import_v36.z.object({ from: import_v36.z.string(), to: import_v36.z.string() }),
|
|
2866
|
+
import_v36.z.null()
|
|
2867
|
+
]).optional()
|
|
2810
2868
|
});
|
|
2811
2869
|
var ProjectAutomation = import_v36.z.object({
|
|
2812
2870
|
id: import_v36.z.string().uuid(),
|
|
@@ -4215,6 +4273,12 @@ var parametersRowSchema = import_v38.z.object({
|
|
|
4215
4273
|
}),
|
|
4216
4274
|
metadata: import_v38.z.union([import_v38.z.object({}).partial().passthrough(), import_v38.z.null()]).optional()
|
|
4217
4275
|
});
|
|
4276
|
+
var InlineAttachmentReferenceSchema = import_v38.z.object({
|
|
4277
|
+
type: import_v38.z.literal("inline_attachment"),
|
|
4278
|
+
src: import_v38.z.string().min(1),
|
|
4279
|
+
content_type: import_v38.z.string().optional(),
|
|
4280
|
+
filename: import_v38.z.string().optional()
|
|
4281
|
+
});
|
|
4218
4282
|
var LoginInvalidOrgError = class extends Error {
|
|
4219
4283
|
constructor(message) {
|
|
4220
4284
|
super(message);
|
|
@@ -8017,7 +8081,11 @@ function startSpanForEvent(config, event, channelName) {
|
|
|
8017
8081
|
});
|
|
8018
8082
|
const startTime = getCurrentUnixTimestamp();
|
|
8019
8083
|
try {
|
|
8020
|
-
const { input, metadata } = config.extractInput(
|
|
8084
|
+
const { input, metadata } = config.extractInput(
|
|
8085
|
+
event.arguments,
|
|
8086
|
+
event,
|
|
8087
|
+
span
|
|
8088
|
+
);
|
|
8021
8089
|
span.log({
|
|
8022
8090
|
input,
|
|
8023
8091
|
metadata: mergeInputMetadata(metadata, spanInfoMetadata)
|
|
@@ -8181,6 +8249,16 @@ function traceStreamingChannel(channel2, config) {
|
|
|
8181
8249
|
});
|
|
8182
8250
|
return;
|
|
8183
8251
|
}
|
|
8252
|
+
if (config.patchResult?.({
|
|
8253
|
+
channelName,
|
|
8254
|
+
endEvent: asyncEndEvent,
|
|
8255
|
+
result: asyncEndEvent.result,
|
|
8256
|
+
span,
|
|
8257
|
+
startTime
|
|
8258
|
+
})) {
|
|
8259
|
+
states.delete(event);
|
|
8260
|
+
return;
|
|
8261
|
+
}
|
|
8184
8262
|
try {
|
|
8185
8263
|
const output = config.extractOutput(
|
|
8186
8264
|
asyncEndEvent.result,
|
|
@@ -8237,8 +8315,17 @@ function traceSyncStreamChannel(channel2, config) {
|
|
|
8237
8315
|
return;
|
|
8238
8316
|
}
|
|
8239
8317
|
const { span, startTime } = spanData;
|
|
8240
|
-
const
|
|
8241
|
-
|
|
8318
|
+
const endEvent = event;
|
|
8319
|
+
if (config.patchResult?.({
|
|
8320
|
+
channelName,
|
|
8321
|
+
endEvent,
|
|
8322
|
+
result: endEvent.result,
|
|
8323
|
+
span,
|
|
8324
|
+
startTime
|
|
8325
|
+
})) {
|
|
8326
|
+
return;
|
|
8327
|
+
}
|
|
8328
|
+
const stream = endEvent.result;
|
|
8242
8329
|
if (!isSyncStreamLike(stream)) {
|
|
8243
8330
|
span.end();
|
|
8244
8331
|
states.delete(event);
|
|
@@ -9209,6 +9296,108 @@ function filterFrom(obj, fieldsToRemove) {
|
|
|
9209
9296
|
return result;
|
|
9210
9297
|
}
|
|
9211
9298
|
|
|
9299
|
+
// src/wrappers/ai-sdk/normalize-logged-output.ts
|
|
9300
|
+
var REMOVE_NORMALIZED_VALUE = Symbol("braintrust.ai-sdk.remove-normalized");
|
|
9301
|
+
function normalizeAISDKLoggedOutput(value) {
|
|
9302
|
+
const normalized = normalizeAISDKLoggedValue(value);
|
|
9303
|
+
return normalized === REMOVE_NORMALIZED_VALUE ? {} : normalized;
|
|
9304
|
+
}
|
|
9305
|
+
function normalizeAISDKLoggedValue(value, context = {}) {
|
|
9306
|
+
if (Array.isArray(value)) {
|
|
9307
|
+
return value.map((entry) => normalizeAISDKLoggedValue(entry, context)).filter((entry) => entry !== REMOVE_NORMALIZED_VALUE);
|
|
9308
|
+
}
|
|
9309
|
+
if (!value || typeof value !== "object") {
|
|
9310
|
+
return value;
|
|
9311
|
+
}
|
|
9312
|
+
const nextInProviderMetadata = context.inProviderMetadata || context.parentKey === "providerMetadata" || context.parentKey === "experimental_providerMetadata";
|
|
9313
|
+
const normalizedEntries = [];
|
|
9314
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
9315
|
+
if (key === "cachedPromptTokens" && entry === 0) {
|
|
9316
|
+
continue;
|
|
9317
|
+
}
|
|
9318
|
+
if (context.parentKey === "request" && key === "body" && entry === "<omitted>") {
|
|
9319
|
+
continue;
|
|
9320
|
+
}
|
|
9321
|
+
const normalizedEntry = normalizeAISDKLoggedValue(entry, {
|
|
9322
|
+
inProviderMetadata: nextInProviderMetadata,
|
|
9323
|
+
parentKey: key
|
|
9324
|
+
});
|
|
9325
|
+
if (normalizedEntry === REMOVE_NORMALIZED_VALUE) {
|
|
9326
|
+
continue;
|
|
9327
|
+
}
|
|
9328
|
+
normalizedEntries.push([key, normalizedEntry]);
|
|
9329
|
+
}
|
|
9330
|
+
if (normalizedEntries.length === 0) {
|
|
9331
|
+
if (context.parentKey === "request" || nextInProviderMetadata) {
|
|
9332
|
+
return REMOVE_NORMALIZED_VALUE;
|
|
9333
|
+
}
|
|
9334
|
+
return {};
|
|
9335
|
+
}
|
|
9336
|
+
return Object.fromEntries(normalizedEntries);
|
|
9337
|
+
}
|
|
9338
|
+
|
|
9339
|
+
// src/zod/utils.ts
|
|
9340
|
+
var import_zod_to_json_schema = require("zod-to-json-schema");
|
|
9341
|
+
var z42 = __toESM(require("zod/v4"));
|
|
9342
|
+
function isZodV4(zodObject) {
|
|
9343
|
+
return typeof zodObject === "object" && zodObject !== null && "_zod" in zodObject && zodObject._zod !== void 0;
|
|
9344
|
+
}
|
|
9345
|
+
function zodToJsonSchema(schema) {
|
|
9346
|
+
if (isZodV4(schema)) {
|
|
9347
|
+
return z42.toJSONSchema(schema, {
|
|
9348
|
+
target: "draft-7"
|
|
9349
|
+
});
|
|
9350
|
+
}
|
|
9351
|
+
return (0, import_zod_to_json_schema.zodToJsonSchema)(schema);
|
|
9352
|
+
}
|
|
9353
|
+
|
|
9354
|
+
// src/wrappers/ai-sdk/tool-serialization.ts
|
|
9355
|
+
function isZodSchema(value) {
|
|
9356
|
+
return value != null && typeof value === "object" && "_def" in value && typeof value._def === "object";
|
|
9357
|
+
}
|
|
9358
|
+
function serializeZodSchema(schema) {
|
|
9359
|
+
try {
|
|
9360
|
+
return zodToJsonSchema(schema);
|
|
9361
|
+
} catch {
|
|
9362
|
+
return {
|
|
9363
|
+
type: "object",
|
|
9364
|
+
description: "Zod schema (conversion failed)"
|
|
9365
|
+
};
|
|
9366
|
+
}
|
|
9367
|
+
}
|
|
9368
|
+
function serializeTool(tool) {
|
|
9369
|
+
if (!tool || typeof tool !== "object") {
|
|
9370
|
+
return tool;
|
|
9371
|
+
}
|
|
9372
|
+
const serialized = { ...tool };
|
|
9373
|
+
if (isZodSchema(serialized.inputSchema)) {
|
|
9374
|
+
serialized.inputSchema = serializeZodSchema(serialized.inputSchema);
|
|
9375
|
+
}
|
|
9376
|
+
if (isZodSchema(serialized.parameters)) {
|
|
9377
|
+
serialized.parameters = serializeZodSchema(serialized.parameters);
|
|
9378
|
+
}
|
|
9379
|
+
if ("execute" in serialized) {
|
|
9380
|
+
delete serialized.execute;
|
|
9381
|
+
}
|
|
9382
|
+
if ("render" in serialized) {
|
|
9383
|
+
delete serialized.render;
|
|
9384
|
+
}
|
|
9385
|
+
return serialized;
|
|
9386
|
+
}
|
|
9387
|
+
function serializeAISDKToolsForLogging(tools) {
|
|
9388
|
+
if (!tools || typeof tools !== "object") {
|
|
9389
|
+
return tools;
|
|
9390
|
+
}
|
|
9391
|
+
if (Array.isArray(tools)) {
|
|
9392
|
+
return tools.map(serializeTool);
|
|
9393
|
+
}
|
|
9394
|
+
const serialized = {};
|
|
9395
|
+
for (const [key, tool] of Object.entries(tools)) {
|
|
9396
|
+
serialized[key] = serializeTool(tool);
|
|
9397
|
+
}
|
|
9398
|
+
return serialized;
|
|
9399
|
+
}
|
|
9400
|
+
|
|
9212
9401
|
// src/instrumentation/plugins/ai-sdk-channels.ts
|
|
9213
9402
|
var aiSDKChannels = defineChannels("ai", {
|
|
9214
9403
|
generateText: channel({
|
|
@@ -9219,6 +9408,10 @@ var aiSDKChannels = defineChannels("ai", {
|
|
|
9219
9408
|
channelName: "streamText",
|
|
9220
9409
|
kind: "async"
|
|
9221
9410
|
}),
|
|
9411
|
+
streamTextSync: channel({
|
|
9412
|
+
channelName: "streamText.sync",
|
|
9413
|
+
kind: "sync-stream"
|
|
9414
|
+
}),
|
|
9222
9415
|
generateObject: channel({
|
|
9223
9416
|
channelName: "generateObject",
|
|
9224
9417
|
kind: "async"
|
|
@@ -9227,6 +9420,10 @@ var aiSDKChannels = defineChannels("ai", {
|
|
|
9227
9420
|
channelName: "streamObject",
|
|
9228
9421
|
kind: "async"
|
|
9229
9422
|
}),
|
|
9423
|
+
streamObjectSync: channel({
|
|
9424
|
+
channelName: "streamObject.sync",
|
|
9425
|
+
kind: "sync-stream"
|
|
9426
|
+
}),
|
|
9230
9427
|
agentGenerate: channel({
|
|
9231
9428
|
channelName: "Agent.generate",
|
|
9232
9429
|
kind: "async"
|
|
@@ -9234,6 +9431,14 @@ var aiSDKChannels = defineChannels("ai", {
|
|
|
9234
9431
|
agentStream: channel({
|
|
9235
9432
|
channelName: "Agent.stream",
|
|
9236
9433
|
kind: "async"
|
|
9434
|
+
}),
|
|
9435
|
+
toolLoopAgentGenerate: channel({
|
|
9436
|
+
channelName: "ToolLoopAgent.generate",
|
|
9437
|
+
kind: "async"
|
|
9438
|
+
}),
|
|
9439
|
+
toolLoopAgentStream: channel({
|
|
9440
|
+
channelName: "ToolLoopAgent.stream",
|
|
9441
|
+
kind: "async"
|
|
9237
9442
|
})
|
|
9238
9443
|
});
|
|
9239
9444
|
|
|
@@ -9252,6 +9457,8 @@ var DEFAULT_DENY_OUTPUT_PATHS = [
|
|
|
9252
9457
|
"steps[].response.body",
|
|
9253
9458
|
"steps[].response.headers"
|
|
9254
9459
|
];
|
|
9460
|
+
var AUTO_PATCHED_MODEL = Symbol.for("braintrust.ai-sdk.auto-patched-model");
|
|
9461
|
+
var AUTO_PATCHED_TOOL = Symbol.for("braintrust.ai-sdk.auto-patched-tool");
|
|
9255
9462
|
var AISDKPlugin = class extends BasePlugin {
|
|
9256
9463
|
config;
|
|
9257
9464
|
constructor(config = {}) {
|
|
@@ -9270,22 +9477,12 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
9270
9477
|
traceStreamingChannel(aiSDKChannels.generateText, {
|
|
9271
9478
|
name: "generateText",
|
|
9272
9479
|
type: "llm" /* LLM */,
|
|
9273
|
-
extractInput: ([params]) =>
|
|
9274
|
-
|
|
9275
|
-
|
|
9276
|
-
metadata: extractMetadataFromParams(params)
|
|
9277
|
-
};
|
|
9278
|
-
},
|
|
9279
|
-
extractOutput: (result) => {
|
|
9480
|
+
extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
|
|
9481
|
+
extractOutput: (result, endEvent) => {
|
|
9482
|
+
finalizeAISDKChildTracing(endEvent);
|
|
9280
9483
|
return processAISDKOutput(result, denyOutputPaths);
|
|
9281
9484
|
},
|
|
9282
|
-
extractMetrics: (result,
|
|
9283
|
-
const metrics = extractTokenMetrics(result);
|
|
9284
|
-
if (startTime) {
|
|
9285
|
-
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
9286
|
-
}
|
|
9287
|
-
return metrics;
|
|
9288
|
-
},
|
|
9485
|
+
extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
|
|
9289
9486
|
aggregateChunks: aggregateAISDKChunks
|
|
9290
9487
|
})
|
|
9291
9488
|
);
|
|
@@ -9293,45 +9490,43 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
9293
9490
|
traceStreamingChannel(aiSDKChannels.streamText, {
|
|
9294
9491
|
name: "streamText",
|
|
9295
9492
|
type: "llm" /* LLM */,
|
|
9296
|
-
extractInput: ([params]) =>
|
|
9297
|
-
|
|
9298
|
-
|
|
9299
|
-
|
|
9300
|
-
|
|
9301
|
-
|
|
9302
|
-
|
|
9303
|
-
|
|
9304
|
-
|
|
9305
|
-
|
|
9306
|
-
|
|
9307
|
-
|
|
9308
|
-
|
|
9309
|
-
|
|
9310
|
-
|
|
9311
|
-
|
|
9312
|
-
|
|
9493
|
+
extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
|
|
9494
|
+
extractOutput: (result) => processAISDKOutput(result, denyOutputPaths),
|
|
9495
|
+
extractMetrics: (result, startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent, startTime),
|
|
9496
|
+
aggregateChunks: aggregateAISDKChunks,
|
|
9497
|
+
patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
|
|
9498
|
+
denyOutputPaths,
|
|
9499
|
+
endEvent,
|
|
9500
|
+
result,
|
|
9501
|
+
span,
|
|
9502
|
+
startTime
|
|
9503
|
+
})
|
|
9504
|
+
})
|
|
9505
|
+
);
|
|
9506
|
+
this.unsubscribers.push(
|
|
9507
|
+
traceSyncStreamChannel(aiSDKChannels.streamTextSync, {
|
|
9508
|
+
name: "streamText",
|
|
9509
|
+
type: "llm" /* LLM */,
|
|
9510
|
+
extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
|
|
9511
|
+
patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
|
|
9512
|
+
denyOutputPaths,
|
|
9513
|
+
endEvent,
|
|
9514
|
+
result,
|
|
9515
|
+
span,
|
|
9516
|
+
startTime
|
|
9517
|
+
})
|
|
9313
9518
|
})
|
|
9314
9519
|
);
|
|
9315
9520
|
this.unsubscribers.push(
|
|
9316
9521
|
traceStreamingChannel(aiSDKChannels.generateObject, {
|
|
9317
9522
|
name: "generateObject",
|
|
9318
9523
|
type: "llm" /* LLM */,
|
|
9319
|
-
extractInput: ([params]) =>
|
|
9320
|
-
|
|
9321
|
-
|
|
9322
|
-
metadata: extractMetadataFromParams(params)
|
|
9323
|
-
};
|
|
9324
|
-
},
|
|
9325
|
-
extractOutput: (result) => {
|
|
9524
|
+
extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
|
|
9525
|
+
extractOutput: (result, endEvent) => {
|
|
9526
|
+
finalizeAISDKChildTracing(endEvent);
|
|
9326
9527
|
return processAISDKOutput(result, denyOutputPaths);
|
|
9327
9528
|
},
|
|
9328
|
-
extractMetrics: (result,
|
|
9329
|
-
const metrics = extractTokenMetrics(result);
|
|
9330
|
-
if (startTime) {
|
|
9331
|
-
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
9332
|
-
}
|
|
9333
|
-
return metrics;
|
|
9334
|
-
},
|
|
9529
|
+
extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
|
|
9335
9530
|
aggregateChunks: aggregateAISDKChunks
|
|
9336
9531
|
})
|
|
9337
9532
|
);
|
|
@@ -9339,45 +9534,43 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
9339
9534
|
traceStreamingChannel(aiSDKChannels.streamObject, {
|
|
9340
9535
|
name: "streamObject",
|
|
9341
9536
|
type: "llm" /* LLM */,
|
|
9342
|
-
extractInput: ([params]) =>
|
|
9343
|
-
|
|
9344
|
-
|
|
9345
|
-
|
|
9346
|
-
|
|
9347
|
-
|
|
9348
|
-
|
|
9349
|
-
|
|
9350
|
-
|
|
9351
|
-
|
|
9352
|
-
|
|
9353
|
-
|
|
9354
|
-
|
|
9355
|
-
|
|
9356
|
-
|
|
9357
|
-
|
|
9358
|
-
|
|
9537
|
+
extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
|
|
9538
|
+
extractOutput: (result) => processAISDKOutput(result, denyOutputPaths),
|
|
9539
|
+
extractMetrics: (result, startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent, startTime),
|
|
9540
|
+
aggregateChunks: aggregateAISDKChunks,
|
|
9541
|
+
patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
|
|
9542
|
+
denyOutputPaths,
|
|
9543
|
+
endEvent,
|
|
9544
|
+
result,
|
|
9545
|
+
span,
|
|
9546
|
+
startTime
|
|
9547
|
+
})
|
|
9548
|
+
})
|
|
9549
|
+
);
|
|
9550
|
+
this.unsubscribers.push(
|
|
9551
|
+
traceSyncStreamChannel(aiSDKChannels.streamObjectSync, {
|
|
9552
|
+
name: "streamObject",
|
|
9553
|
+
type: "llm" /* LLM */,
|
|
9554
|
+
extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
|
|
9555
|
+
patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
|
|
9556
|
+
denyOutputPaths,
|
|
9557
|
+
endEvent,
|
|
9558
|
+
result,
|
|
9559
|
+
span,
|
|
9560
|
+
startTime
|
|
9561
|
+
})
|
|
9359
9562
|
})
|
|
9360
9563
|
);
|
|
9361
9564
|
this.unsubscribers.push(
|
|
9362
9565
|
traceStreamingChannel(aiSDKChannels.agentGenerate, {
|
|
9363
9566
|
name: "Agent.generate",
|
|
9364
9567
|
type: "llm" /* LLM */,
|
|
9365
|
-
extractInput: ([params]) =>
|
|
9366
|
-
|
|
9367
|
-
|
|
9368
|
-
metadata: extractMetadataFromParams(params)
|
|
9369
|
-
};
|
|
9370
|
-
},
|
|
9371
|
-
extractOutput: (result) => {
|
|
9568
|
+
extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
|
|
9569
|
+
extractOutput: (result, endEvent) => {
|
|
9570
|
+
finalizeAISDKChildTracing(endEvent);
|
|
9372
9571
|
return processAISDKOutput(result, denyOutputPaths);
|
|
9373
9572
|
},
|
|
9374
|
-
extractMetrics: (result,
|
|
9375
|
-
const metrics = extractTokenMetrics(result);
|
|
9376
|
-
if (startTime) {
|
|
9377
|
-
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
9378
|
-
}
|
|
9379
|
-
return metrics;
|
|
9380
|
-
},
|
|
9573
|
+
extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
|
|
9381
9574
|
aggregateChunks: aggregateAISDKChunks
|
|
9382
9575
|
})
|
|
9383
9576
|
);
|
|
@@ -9385,52 +9578,470 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
9385
9578
|
traceStreamingChannel(aiSDKChannels.agentStream, {
|
|
9386
9579
|
name: "Agent.stream",
|
|
9387
9580
|
type: "llm" /* LLM */,
|
|
9388
|
-
extractInput: ([params]) =>
|
|
9389
|
-
|
|
9390
|
-
|
|
9391
|
-
|
|
9392
|
-
|
|
9393
|
-
|
|
9394
|
-
|
|
9581
|
+
extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
|
|
9582
|
+
extractOutput: (result) => processAISDKOutput(result, denyOutputPaths),
|
|
9583
|
+
extractMetrics: (result, startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent, startTime),
|
|
9584
|
+
aggregateChunks: aggregateAISDKChunks,
|
|
9585
|
+
patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
|
|
9586
|
+
denyOutputPaths,
|
|
9587
|
+
endEvent,
|
|
9588
|
+
result,
|
|
9589
|
+
span,
|
|
9590
|
+
startTime
|
|
9591
|
+
})
|
|
9592
|
+
})
|
|
9593
|
+
);
|
|
9594
|
+
this.unsubscribers.push(
|
|
9595
|
+
traceStreamingChannel(aiSDKChannels.toolLoopAgentGenerate, {
|
|
9596
|
+
name: "ToolLoopAgent.generate",
|
|
9597
|
+
type: "llm" /* LLM */,
|
|
9598
|
+
extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
|
|
9599
|
+
extractOutput: (result, endEvent) => {
|
|
9600
|
+
finalizeAISDKChildTracing(endEvent);
|
|
9395
9601
|
return processAISDKOutput(result, denyOutputPaths);
|
|
9396
9602
|
},
|
|
9397
|
-
extractMetrics: (result,
|
|
9398
|
-
const metrics = extractTokenMetrics(result);
|
|
9399
|
-
if (startTime) {
|
|
9400
|
-
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
9401
|
-
}
|
|
9402
|
-
return metrics;
|
|
9403
|
-
},
|
|
9603
|
+
extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
|
|
9404
9604
|
aggregateChunks: aggregateAISDKChunks
|
|
9405
9605
|
})
|
|
9406
9606
|
);
|
|
9607
|
+
this.unsubscribers.push(
|
|
9608
|
+
traceStreamingChannel(aiSDKChannels.toolLoopAgentStream, {
|
|
9609
|
+
name: "ToolLoopAgent.stream",
|
|
9610
|
+
type: "llm" /* LLM */,
|
|
9611
|
+
extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
|
|
9612
|
+
extractOutput: (result) => processAISDKOutput(result, denyOutputPaths),
|
|
9613
|
+
extractMetrics: (result, startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent, startTime),
|
|
9614
|
+
aggregateChunks: aggregateAISDKChunks,
|
|
9615
|
+
patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
|
|
9616
|
+
denyOutputPaths,
|
|
9617
|
+
endEvent,
|
|
9618
|
+
result,
|
|
9619
|
+
span,
|
|
9620
|
+
startTime
|
|
9621
|
+
})
|
|
9622
|
+
})
|
|
9623
|
+
);
|
|
9407
9624
|
}
|
|
9408
9625
|
};
|
|
9409
9626
|
function processAISDKInput(params) {
|
|
9410
9627
|
if (!params) return params;
|
|
9411
|
-
|
|
9628
|
+
const input = processInputAttachments(params);
|
|
9629
|
+
if (!input || typeof input !== "object" || Array.isArray(input)) {
|
|
9630
|
+
return input;
|
|
9631
|
+
}
|
|
9632
|
+
const { tools: _tools, ...rest } = input;
|
|
9633
|
+
return rest;
|
|
9634
|
+
}
|
|
9635
|
+
function prepareAISDKInput(params, event, span, denyOutputPaths) {
|
|
9636
|
+
const input = processAISDKInput(params);
|
|
9637
|
+
const metadata = extractMetadataFromParams(params, event.self);
|
|
9638
|
+
const childTracing = prepareAISDKChildTracing(
|
|
9639
|
+
params,
|
|
9640
|
+
event.self,
|
|
9641
|
+
span,
|
|
9642
|
+
denyOutputPaths
|
|
9643
|
+
);
|
|
9644
|
+
event.__braintrust_ai_sdk_model_wrapped = childTracing.modelWrapped;
|
|
9645
|
+
if (childTracing.cleanup) {
|
|
9646
|
+
event.__braintrust_ai_sdk_cleanup = childTracing.cleanup;
|
|
9647
|
+
}
|
|
9648
|
+
return {
|
|
9649
|
+
input,
|
|
9650
|
+
metadata
|
|
9651
|
+
};
|
|
9412
9652
|
}
|
|
9413
|
-
function
|
|
9653
|
+
function extractTopLevelAISDKMetrics(result, event, startTime) {
|
|
9654
|
+
const metrics = hasModelChildTracing(event) ? {} : extractTokenMetrics(result);
|
|
9655
|
+
if (startTime) {
|
|
9656
|
+
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
9657
|
+
}
|
|
9658
|
+
return metrics;
|
|
9659
|
+
}
|
|
9660
|
+
function hasModelChildTracing(event) {
|
|
9661
|
+
return event?.__braintrust_ai_sdk_model_wrapped === true;
|
|
9662
|
+
}
|
|
9663
|
+
function extractMetadataFromParams(params, self) {
|
|
9414
9664
|
const metadata = {
|
|
9415
9665
|
braintrust: {
|
|
9416
9666
|
integration_name: "ai-sdk",
|
|
9417
9667
|
sdk_language: "typescript"
|
|
9418
9668
|
}
|
|
9419
9669
|
};
|
|
9420
|
-
const
|
|
9670
|
+
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;
|
|
9671
|
+
const { model, provider } = serializeModelWithProvider(
|
|
9672
|
+
params.model ?? agentModel
|
|
9673
|
+
);
|
|
9421
9674
|
if (model) {
|
|
9422
9675
|
metadata.model = model;
|
|
9423
9676
|
}
|
|
9424
9677
|
if (provider) {
|
|
9425
9678
|
metadata.provider = provider;
|
|
9426
9679
|
}
|
|
9680
|
+
const tools = serializeAISDKToolsForLogging(params.tools);
|
|
9681
|
+
if (tools) {
|
|
9682
|
+
metadata.tools = tools;
|
|
9683
|
+
}
|
|
9427
9684
|
return metadata;
|
|
9428
9685
|
}
|
|
9686
|
+
function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths) {
|
|
9687
|
+
const cleanup = [];
|
|
9688
|
+
const patchedModels = /* @__PURE__ */ new WeakSet();
|
|
9689
|
+
const patchedTools = /* @__PURE__ */ new WeakSet();
|
|
9690
|
+
let modelWrapped = false;
|
|
9691
|
+
const patchModel = (model) => {
|
|
9692
|
+
const resolvedModel = resolveAISDKModel(model);
|
|
9693
|
+
if (!resolvedModel || typeof resolvedModel !== "object" || typeof resolvedModel.doGenerate !== "function" || patchedModels.has(resolvedModel) || resolvedModel[AUTO_PATCHED_MODEL]) {
|
|
9694
|
+
return;
|
|
9695
|
+
}
|
|
9696
|
+
patchedModels.add(resolvedModel);
|
|
9697
|
+
resolvedModel[AUTO_PATCHED_MODEL] = true;
|
|
9698
|
+
modelWrapped = true;
|
|
9699
|
+
const originalDoGenerate = resolvedModel.doGenerate;
|
|
9700
|
+
const originalDoStream = resolvedModel.doStream;
|
|
9701
|
+
const baseMetadata = buildAISDKChildMetadata(resolvedModel);
|
|
9702
|
+
resolvedModel.doGenerate = async function doGeneratePatched(options) {
|
|
9703
|
+
return parentSpan.traced(
|
|
9704
|
+
async (span) => {
|
|
9705
|
+
const result = await Reflect.apply(
|
|
9706
|
+
originalDoGenerate,
|
|
9707
|
+
resolvedModel,
|
|
9708
|
+
[options]
|
|
9709
|
+
);
|
|
9710
|
+
span.log({
|
|
9711
|
+
output: processAISDKOutput(result, denyOutputPaths),
|
|
9712
|
+
metrics: extractTokenMetrics(result),
|
|
9713
|
+
...buildResolvedMetadataPayload(result)
|
|
9714
|
+
});
|
|
9715
|
+
return result;
|
|
9716
|
+
},
|
|
9717
|
+
{
|
|
9718
|
+
name: "doGenerate",
|
|
9719
|
+
spanAttributes: {
|
|
9720
|
+
type: "llm" /* LLM */
|
|
9721
|
+
},
|
|
9722
|
+
event: {
|
|
9723
|
+
input: processAISDKInput(options),
|
|
9724
|
+
metadata: baseMetadata
|
|
9725
|
+
}
|
|
9726
|
+
}
|
|
9727
|
+
);
|
|
9728
|
+
};
|
|
9729
|
+
if (originalDoStream) {
|
|
9730
|
+
resolvedModel.doStream = async function doStreamPatched(options) {
|
|
9731
|
+
const span = parentSpan.startSpan({
|
|
9732
|
+
name: "doStream",
|
|
9733
|
+
spanAttributes: {
|
|
9734
|
+
type: "llm" /* LLM */
|
|
9735
|
+
},
|
|
9736
|
+
event: {
|
|
9737
|
+
input: processAISDKInput(options),
|
|
9738
|
+
metadata: baseMetadata
|
|
9739
|
+
}
|
|
9740
|
+
});
|
|
9741
|
+
const result = await withCurrent(
|
|
9742
|
+
span,
|
|
9743
|
+
() => Reflect.apply(originalDoStream, resolvedModel, [options])
|
|
9744
|
+
);
|
|
9745
|
+
const output = {};
|
|
9746
|
+
let text = "";
|
|
9747
|
+
let reasoning = "";
|
|
9748
|
+
const toolCalls = [];
|
|
9749
|
+
let object = void 0;
|
|
9750
|
+
const transformStream = new TransformStream({
|
|
9751
|
+
transform(chunk, controller) {
|
|
9752
|
+
switch (chunk.type) {
|
|
9753
|
+
case "text-delta":
|
|
9754
|
+
text += extractTextDelta(chunk);
|
|
9755
|
+
break;
|
|
9756
|
+
case "reasoning-delta":
|
|
9757
|
+
if (chunk.delta) {
|
|
9758
|
+
reasoning += chunk.delta;
|
|
9759
|
+
} else if (chunk.text) {
|
|
9760
|
+
reasoning += chunk.text;
|
|
9761
|
+
}
|
|
9762
|
+
break;
|
|
9763
|
+
case "tool-call":
|
|
9764
|
+
toolCalls.push(chunk);
|
|
9765
|
+
break;
|
|
9766
|
+
case "object":
|
|
9767
|
+
object = chunk.object;
|
|
9768
|
+
break;
|
|
9769
|
+
case "raw":
|
|
9770
|
+
if (chunk.rawValue) {
|
|
9771
|
+
const rawVal = chunk.rawValue;
|
|
9772
|
+
if (rawVal.delta?.content) {
|
|
9773
|
+
text += rawVal.delta.content;
|
|
9774
|
+
} else if (rawVal.choices?.[0]?.delta?.content) {
|
|
9775
|
+
text += rawVal.choices[0].delta.content;
|
|
9776
|
+
} else if (typeof rawVal.text === "string") {
|
|
9777
|
+
text += rawVal.text;
|
|
9778
|
+
} else if (typeof rawVal.content === "string") {
|
|
9779
|
+
text += rawVal.content;
|
|
9780
|
+
}
|
|
9781
|
+
}
|
|
9782
|
+
break;
|
|
9783
|
+
case "finish":
|
|
9784
|
+
output.text = text;
|
|
9785
|
+
output.reasoning = reasoning;
|
|
9786
|
+
output.toolCalls = toolCalls;
|
|
9787
|
+
output.finishReason = chunk.finishReason;
|
|
9788
|
+
output.usage = chunk.usage;
|
|
9789
|
+
if (object !== void 0) {
|
|
9790
|
+
output.object = object;
|
|
9791
|
+
}
|
|
9792
|
+
span.log({
|
|
9793
|
+
output: processAISDKOutput(
|
|
9794
|
+
output,
|
|
9795
|
+
denyOutputPaths
|
|
9796
|
+
),
|
|
9797
|
+
metrics: extractTokenMetrics(output),
|
|
9798
|
+
...buildResolvedMetadataPayload(output)
|
|
9799
|
+
});
|
|
9800
|
+
span.end();
|
|
9801
|
+
break;
|
|
9802
|
+
}
|
|
9803
|
+
controller.enqueue(chunk);
|
|
9804
|
+
}
|
|
9805
|
+
});
|
|
9806
|
+
return {
|
|
9807
|
+
...result,
|
|
9808
|
+
stream: result.stream.pipeThrough(transformStream)
|
|
9809
|
+
};
|
|
9810
|
+
};
|
|
9811
|
+
}
|
|
9812
|
+
cleanup.push(() => {
|
|
9813
|
+
resolvedModel.doGenerate = originalDoGenerate;
|
|
9814
|
+
if (originalDoStream) {
|
|
9815
|
+
resolvedModel.doStream = originalDoStream;
|
|
9816
|
+
}
|
|
9817
|
+
delete resolvedModel[AUTO_PATCHED_MODEL];
|
|
9818
|
+
});
|
|
9819
|
+
};
|
|
9820
|
+
const patchTool = (tool, name) => {
|
|
9821
|
+
if (tool == null || typeof tool !== "object" || !("execute" in tool) || typeof tool.execute !== "function" || patchedTools.has(tool) || tool[AUTO_PATCHED_TOOL]) {
|
|
9822
|
+
return;
|
|
9823
|
+
}
|
|
9824
|
+
patchedTools.add(tool);
|
|
9825
|
+
tool[AUTO_PATCHED_TOOL] = true;
|
|
9826
|
+
const originalExecute = tool.execute;
|
|
9827
|
+
tool.execute = function executePatched(...args) {
|
|
9828
|
+
const result = Reflect.apply(originalExecute, this, args);
|
|
9829
|
+
if (isAsyncGenerator(result)) {
|
|
9830
|
+
return (async function* () {
|
|
9831
|
+
const span = parentSpan.startSpan({
|
|
9832
|
+
name,
|
|
9833
|
+
spanAttributes: {
|
|
9834
|
+
type: "tool" /* TOOL */
|
|
9835
|
+
}
|
|
9836
|
+
});
|
|
9837
|
+
span.log({ input: args.length === 1 ? args[0] : args });
|
|
9838
|
+
try {
|
|
9839
|
+
let lastValue;
|
|
9840
|
+
for await (const value of result) {
|
|
9841
|
+
lastValue = value;
|
|
9842
|
+
yield value;
|
|
9843
|
+
}
|
|
9844
|
+
span.log({ output: lastValue });
|
|
9845
|
+
} catch (error) {
|
|
9846
|
+
span.log({
|
|
9847
|
+
error: error instanceof Error ? error.message : String(error)
|
|
9848
|
+
});
|
|
9849
|
+
throw error;
|
|
9850
|
+
} finally {
|
|
9851
|
+
span.end();
|
|
9852
|
+
}
|
|
9853
|
+
})();
|
|
9854
|
+
}
|
|
9855
|
+
return parentSpan.traced(
|
|
9856
|
+
async (span) => {
|
|
9857
|
+
span.log({ input: args.length === 1 ? args[0] : args });
|
|
9858
|
+
const awaitedResult = await result;
|
|
9859
|
+
span.log({ output: awaitedResult });
|
|
9860
|
+
return awaitedResult;
|
|
9861
|
+
},
|
|
9862
|
+
{
|
|
9863
|
+
name,
|
|
9864
|
+
spanAttributes: {
|
|
9865
|
+
type: "tool" /* TOOL */
|
|
9866
|
+
}
|
|
9867
|
+
}
|
|
9868
|
+
);
|
|
9869
|
+
};
|
|
9870
|
+
cleanup.push(() => {
|
|
9871
|
+
tool.execute = originalExecute;
|
|
9872
|
+
delete tool[AUTO_PATCHED_TOOL];
|
|
9873
|
+
});
|
|
9874
|
+
};
|
|
9875
|
+
const patchTools = (tools) => {
|
|
9876
|
+
if (!tools) {
|
|
9877
|
+
return;
|
|
9878
|
+
}
|
|
9879
|
+
const inferName = (tool, fallback) => tool && (tool.name || tool.toolName || tool.id) || fallback;
|
|
9880
|
+
if (Array.isArray(tools)) {
|
|
9881
|
+
tools.forEach(
|
|
9882
|
+
(tool, index) => patchTool(tool, inferName(tool, `tool[${index}]`))
|
|
9883
|
+
);
|
|
9884
|
+
return;
|
|
9885
|
+
}
|
|
9886
|
+
for (const [key, tool] of Object.entries(tools)) {
|
|
9887
|
+
patchTool(tool, key);
|
|
9888
|
+
}
|
|
9889
|
+
};
|
|
9890
|
+
if (params && typeof params === "object") {
|
|
9891
|
+
patchModel(params.model);
|
|
9892
|
+
patchTools(params.tools);
|
|
9893
|
+
}
|
|
9894
|
+
if (self && typeof self === "object") {
|
|
9895
|
+
const selfRecord = self;
|
|
9896
|
+
if (selfRecord.model !== void 0) {
|
|
9897
|
+
patchModel(selfRecord.model);
|
|
9898
|
+
}
|
|
9899
|
+
if (selfRecord.settings && typeof selfRecord.settings === "object") {
|
|
9900
|
+
if (selfRecord.settings.model !== void 0) {
|
|
9901
|
+
patchModel(selfRecord.settings.model);
|
|
9902
|
+
}
|
|
9903
|
+
if (selfRecord.settings.tools !== void 0) {
|
|
9904
|
+
patchTools(selfRecord.settings.tools);
|
|
9905
|
+
}
|
|
9906
|
+
}
|
|
9907
|
+
}
|
|
9908
|
+
return {
|
|
9909
|
+
cleanup: cleanup.length > 0 ? () => {
|
|
9910
|
+
while (cleanup.length > 0) {
|
|
9911
|
+
cleanup.pop()?.();
|
|
9912
|
+
}
|
|
9913
|
+
} : void 0,
|
|
9914
|
+
modelWrapped
|
|
9915
|
+
};
|
|
9916
|
+
}
|
|
9917
|
+
function finalizeAISDKChildTracing(event) {
|
|
9918
|
+
const cleanup = event?.__braintrust_ai_sdk_cleanup;
|
|
9919
|
+
if (event && typeof cleanup === "function") {
|
|
9920
|
+
cleanup();
|
|
9921
|
+
delete event.__braintrust_ai_sdk_cleanup;
|
|
9922
|
+
}
|
|
9923
|
+
}
|
|
9924
|
+
function patchAISDKStreamingResult(args) {
|
|
9925
|
+
const { denyOutputPaths, endEvent, result, span, startTime } = args;
|
|
9926
|
+
if (!result || typeof result !== "object") {
|
|
9927
|
+
return false;
|
|
9928
|
+
}
|
|
9929
|
+
const resultRecord = result;
|
|
9930
|
+
if (!isReadableStreamLike(resultRecord.baseStream)) {
|
|
9931
|
+
return false;
|
|
9932
|
+
}
|
|
9933
|
+
let firstChunkTime;
|
|
9934
|
+
const wrappedBaseStream = resultRecord.baseStream.pipeThrough(
|
|
9935
|
+
new TransformStream({
|
|
9936
|
+
transform(chunk, controller) {
|
|
9937
|
+
if (firstChunkTime === void 0) {
|
|
9938
|
+
firstChunkTime = getCurrentUnixTimestamp();
|
|
9939
|
+
}
|
|
9940
|
+
controller.enqueue(chunk);
|
|
9941
|
+
},
|
|
9942
|
+
async flush() {
|
|
9943
|
+
const metrics = extractTopLevelAISDKMetrics(result, endEvent);
|
|
9944
|
+
if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
|
|
9945
|
+
metrics.time_to_first_token = firstChunkTime - startTime;
|
|
9946
|
+
}
|
|
9947
|
+
const output = await processAISDKStreamingOutput(
|
|
9948
|
+
result,
|
|
9949
|
+
denyOutputPaths
|
|
9950
|
+
);
|
|
9951
|
+
const metadata = buildResolvedMetadataPayload(result).metadata;
|
|
9952
|
+
span.log({
|
|
9953
|
+
output,
|
|
9954
|
+
...metadata ? { metadata } : {},
|
|
9955
|
+
metrics
|
|
9956
|
+
});
|
|
9957
|
+
finalizeAISDKChildTracing(endEvent);
|
|
9958
|
+
span.end();
|
|
9959
|
+
}
|
|
9960
|
+
})
|
|
9961
|
+
);
|
|
9962
|
+
Object.defineProperty(resultRecord, "baseStream", {
|
|
9963
|
+
configurable: true,
|
|
9964
|
+
enumerable: true,
|
|
9965
|
+
value: wrappedBaseStream,
|
|
9966
|
+
writable: true
|
|
9967
|
+
});
|
|
9968
|
+
return true;
|
|
9969
|
+
}
|
|
9970
|
+
function isReadableStreamLike(value) {
|
|
9971
|
+
return value != null && typeof value === "object" && typeof value.pipeThrough === "function";
|
|
9972
|
+
}
|
|
9973
|
+
async function processAISDKStreamingOutput(result, denyOutputPaths) {
|
|
9974
|
+
const output = processAISDKOutput(result, denyOutputPaths);
|
|
9975
|
+
if (!output || typeof output !== "object") {
|
|
9976
|
+
return output;
|
|
9977
|
+
}
|
|
9978
|
+
const outputRecord = output;
|
|
9979
|
+
try {
|
|
9980
|
+
if ("text" in result && typeof result.text === "string") {
|
|
9981
|
+
outputRecord.text = result.text;
|
|
9982
|
+
}
|
|
9983
|
+
} catch {
|
|
9984
|
+
}
|
|
9985
|
+
try {
|
|
9986
|
+
if ("object" in result) {
|
|
9987
|
+
const resolvedObject = await Promise.resolve(result.object);
|
|
9988
|
+
if (resolvedObject !== void 0) {
|
|
9989
|
+
outputRecord.object = resolvedObject;
|
|
9990
|
+
}
|
|
9991
|
+
}
|
|
9992
|
+
} catch {
|
|
9993
|
+
}
|
|
9994
|
+
return outputRecord;
|
|
9995
|
+
}
|
|
9996
|
+
function buildAISDKChildMetadata(model) {
|
|
9997
|
+
const { model: modelId, provider } = serializeModelWithProvider(model);
|
|
9998
|
+
return {
|
|
9999
|
+
...modelId ? { model: modelId } : {},
|
|
10000
|
+
...provider ? { provider } : {},
|
|
10001
|
+
braintrust: {
|
|
10002
|
+
integration_name: "ai-sdk",
|
|
10003
|
+
sdk_language: "typescript"
|
|
10004
|
+
}
|
|
10005
|
+
};
|
|
10006
|
+
}
|
|
10007
|
+
function buildResolvedMetadataPayload(result) {
|
|
10008
|
+
const gatewayInfo = extractGatewayRoutingInfo(result);
|
|
10009
|
+
const metadata = {};
|
|
10010
|
+
if (gatewayInfo?.provider) {
|
|
10011
|
+
metadata.provider = gatewayInfo.provider;
|
|
10012
|
+
}
|
|
10013
|
+
if (gatewayInfo?.model) {
|
|
10014
|
+
metadata.model = gatewayInfo.model;
|
|
10015
|
+
}
|
|
10016
|
+
if (result.finishReason !== void 0) {
|
|
10017
|
+
metadata.finish_reason = result.finishReason;
|
|
10018
|
+
}
|
|
10019
|
+
return Object.keys(metadata).length > 0 ? { metadata } : {};
|
|
10020
|
+
}
|
|
10021
|
+
function resolveAISDKModel(model) {
|
|
10022
|
+
if (typeof model !== "string") {
|
|
10023
|
+
return model;
|
|
10024
|
+
}
|
|
10025
|
+
const provider = globalThis.AI_SDK_DEFAULT_PROVIDER ?? null;
|
|
10026
|
+
if (provider && typeof provider.languageModel === "function") {
|
|
10027
|
+
return provider.languageModel(model);
|
|
10028
|
+
}
|
|
10029
|
+
return model;
|
|
10030
|
+
}
|
|
10031
|
+
function extractTextDelta(chunk) {
|
|
10032
|
+
if (typeof chunk.textDelta === "string") return chunk.textDelta;
|
|
10033
|
+
if (typeof chunk.delta === "string") return chunk.delta;
|
|
10034
|
+
if (typeof chunk.text === "string") return chunk.text;
|
|
10035
|
+
if (typeof chunk.content === "string") return chunk.content;
|
|
10036
|
+
return "";
|
|
10037
|
+
}
|
|
10038
|
+
function isAsyncGenerator(value) {
|
|
10039
|
+
return value != null && typeof value === "object" && typeof value[Symbol.asyncIterator] === "function" && typeof value.next === "function" && typeof value.return === "function" && typeof value.throw === "function";
|
|
10040
|
+
}
|
|
9429
10041
|
function processAISDKOutput(output, denyOutputPaths) {
|
|
9430
10042
|
if (!output) return output;
|
|
9431
|
-
const
|
|
9432
|
-
|
|
9433
|
-
return omit(merged, denyOutputPaths);
|
|
10043
|
+
const merged = extractSerializableOutputFields(output);
|
|
10044
|
+
return normalizeAISDKLoggedOutput(omit(merged, denyOutputPaths));
|
|
9434
10045
|
}
|
|
9435
10046
|
function extractTokenMetrics(result) {
|
|
9436
10047
|
const metrics = {};
|
|
@@ -9480,12 +10091,14 @@ function extractTokenMetrics(result) {
|
|
|
9480
10091
|
}
|
|
9481
10092
|
return metrics;
|
|
9482
10093
|
}
|
|
9483
|
-
function aggregateAISDKChunks(chunks) {
|
|
10094
|
+
function aggregateAISDKChunks(chunks, _result, endEvent) {
|
|
9484
10095
|
const lastChunk = chunks[chunks.length - 1];
|
|
9485
10096
|
const output = {};
|
|
9486
10097
|
let metrics = {};
|
|
10098
|
+
let metadata;
|
|
9487
10099
|
if (lastChunk) {
|
|
9488
|
-
metrics = extractTokenMetrics(lastChunk);
|
|
10100
|
+
metrics = hasModelChildTracing(endEvent) ? {} : extractTokenMetrics(lastChunk);
|
|
10101
|
+
metadata = buildResolvedMetadataPayload(lastChunk).metadata;
|
|
9489
10102
|
if (lastChunk.text !== void 0) {
|
|
9490
10103
|
output.text = lastChunk.text;
|
|
9491
10104
|
}
|
|
@@ -9499,7 +10112,8 @@ function aggregateAISDKChunks(chunks) {
|
|
|
9499
10112
|
output.toolCalls = lastChunk.toolCalls;
|
|
9500
10113
|
}
|
|
9501
10114
|
}
|
|
9502
|
-
|
|
10115
|
+
finalizeAISDKChildTracing(endEvent);
|
|
10116
|
+
return { output, metrics, metadata };
|
|
9503
10117
|
}
|
|
9504
10118
|
function extractGetterValues(obj) {
|
|
9505
10119
|
const getterValues = {};
|
|
@@ -9519,7 +10133,7 @@ function extractGetterValues(obj) {
|
|
|
9519
10133
|
];
|
|
9520
10134
|
for (const name of getterNames) {
|
|
9521
10135
|
try {
|
|
9522
|
-
if (obj && name in obj &&
|
|
10136
|
+
if (obj && name in obj && isSerializableOutputValue(obj[name])) {
|
|
9523
10137
|
getterValues[name] = obj[name];
|
|
9524
10138
|
}
|
|
9525
10139
|
} catch {
|
|
@@ -9527,6 +10141,47 @@ function extractGetterValues(obj) {
|
|
|
9527
10141
|
}
|
|
9528
10142
|
return getterValues;
|
|
9529
10143
|
}
|
|
10144
|
+
function extractSerializableOutputFields(output) {
|
|
10145
|
+
const serialized = {};
|
|
10146
|
+
const directFieldNames = [
|
|
10147
|
+
"steps",
|
|
10148
|
+
"request",
|
|
10149
|
+
"responseMessages",
|
|
10150
|
+
"warnings",
|
|
10151
|
+
"rawResponse",
|
|
10152
|
+
"response",
|
|
10153
|
+
"providerMetadata",
|
|
10154
|
+
"experimental_providerMetadata"
|
|
10155
|
+
];
|
|
10156
|
+
for (const name of directFieldNames) {
|
|
10157
|
+
try {
|
|
10158
|
+
const value = output?.[name];
|
|
10159
|
+
if (isSerializableOutputValue(value)) {
|
|
10160
|
+
serialized[name] = value;
|
|
10161
|
+
}
|
|
10162
|
+
} catch {
|
|
10163
|
+
}
|
|
10164
|
+
}
|
|
10165
|
+
return {
|
|
10166
|
+
...serialized,
|
|
10167
|
+
...extractGetterValues(output)
|
|
10168
|
+
};
|
|
10169
|
+
}
|
|
10170
|
+
function isSerializableOutputValue(value) {
|
|
10171
|
+
if (typeof value === "function") {
|
|
10172
|
+
return false;
|
|
10173
|
+
}
|
|
10174
|
+
if (value && typeof value === "object" && typeof value.then === "function") {
|
|
10175
|
+
return false;
|
|
10176
|
+
}
|
|
10177
|
+
if (value && typeof value === "object" && typeof value.getReader === "function") {
|
|
10178
|
+
return false;
|
|
10179
|
+
}
|
|
10180
|
+
if (value && typeof value === "object" && typeof value[Symbol.asyncIterator] === "function") {
|
|
10181
|
+
return false;
|
|
10182
|
+
}
|
|
10183
|
+
return true;
|
|
10184
|
+
}
|
|
9530
10185
|
function serializeModelWithProvider(model) {
|
|
9531
10186
|
const modelId = typeof model === "string" ? model : model?.modelId;
|
|
9532
10187
|
const explicitProvider = typeof model === "object" ? model?.provider : void 0;
|
|
@@ -9552,6 +10207,25 @@ function parseGatewayModelString(modelString) {
|
|
|
9552
10207
|
}
|
|
9553
10208
|
return { model: modelString };
|
|
9554
10209
|
}
|
|
10210
|
+
function extractGatewayRoutingInfo(result) {
|
|
10211
|
+
if (result?.steps && Array.isArray(result.steps) && result.steps.length > 0) {
|
|
10212
|
+
const routing2 = result.steps[0]?.providerMetadata?.gateway?.routing;
|
|
10213
|
+
if (routing2) {
|
|
10214
|
+
return {
|
|
10215
|
+
provider: routing2.resolvedProvider || routing2.finalProvider,
|
|
10216
|
+
model: routing2.resolvedProviderApiModelId
|
|
10217
|
+
};
|
|
10218
|
+
}
|
|
10219
|
+
}
|
|
10220
|
+
const routing = result?.providerMetadata?.gateway?.routing;
|
|
10221
|
+
if (routing) {
|
|
10222
|
+
return {
|
|
10223
|
+
provider: routing.resolvedProvider || routing.finalProvider,
|
|
10224
|
+
model: routing.resolvedProviderApiModelId
|
|
10225
|
+
};
|
|
10226
|
+
}
|
|
10227
|
+
return null;
|
|
10228
|
+
}
|
|
9555
10229
|
function extractCostFromResult(result) {
|
|
9556
10230
|
if (result?.steps && Array.isArray(result.steps) && result.steps.length > 0) {
|
|
9557
10231
|
let totalCost = 0;
|